Add D3D support for MSAA

Change-Id: I7f9122bb99fea952a67fa47aaada789037438152
Bug: skia:10476
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/300906
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Jim Van Verth <jvanverth@google.com>
This commit is contained in:
Jim Van Verth 2020-07-07 15:36:41 -04:00 committed by Skia Commit-Bot
parent 9cf98dcb49
commit 275f419a60
7 changed files with 109 additions and 11 deletions

View File

@ -73,8 +73,22 @@ bool GrD3DCaps::canCopyTexture(DXGI_FORMAT dstFormat, int dstSampleCnt,
bool GrD3DCaps::canCopyAsResolve(DXGI_FORMAT dstFormat, int dstSampleCnt,
DXGI_FORMAT srcFormat, int srcSampleCnt) const {
// TODO
return false;
// The src surface must be multisampled.
if (srcSampleCnt <= 1) {
return false;
}
// The dst must not be multisampled.
if (dstSampleCnt > 1) {
return false;
}
// Surfaces must have the same format.
if (srcFormat != dstFormat) {
return false;
}
return true;
}
bool GrD3DCaps::onCanCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src,

View File

@ -15,6 +15,7 @@
#include "src/gpu/d3d/GrD3DStencilAttachment.h"
#include "src/gpu/d3d/GrD3DTexture.h"
#include "src/gpu/d3d/GrD3DTextureResource.h"
#include "src/gpu/d3d/GrD3DUtil.h"
GrD3DCommandList::GrD3DCommandList(gr_cp<ID3D12CommandAllocator> allocator,
gr_cp<ID3D12GraphicsCommandList> commandList)
@ -383,6 +384,32 @@ void GrD3DDirectCommandList::setRenderTarget(const GrD3DRenderTarget* renderTarg
fCommandList->OMSetRenderTargets(1, &rtvDescriptor, false, dsDescriptorPtr);
}
void GrD3DDirectCommandList::resolveSubresourceRegion(const GrD3DTextureResource* dstTexture,
UINT dstX, UINT dstY,
const GrD3DTextureResource* srcTexture,
D3D12_RECT* srcRect) {
SkASSERT(dstTexture->dxgiFormat() == srcTexture->dxgiFormat());
SkASSERT(dstTexture->currentState() == D3D12_RESOURCE_STATE_RESOLVE_DEST);
SkASSERT(srcTexture->currentState() == D3D12_RESOURCE_STATE_RESOLVE_SOURCE);
this->addingWork();
this->addResource(dstTexture->resource());
this->addResource(srcTexture->resource());
gr_cp<ID3D12GraphicsCommandList1> commandList1;
HRESULT result = fCommandList->QueryInterface(IID_PPV_ARGS(&commandList1));
if (SUCCEEDED(result)) {
commandList1->ResolveSubresourceRegion(dstTexture->d3dResource(), 0, dstX, dstY,
srcTexture->d3dResource(), 0, srcRect,
srcTexture->dxgiFormat(),
D3D12_RESOLVE_MODE_AVERAGE);
} else {
fCommandList->ResolveSubresource(dstTexture->d3dResource(), 0, srcTexture->d3dResource(), 0,
srcTexture->dxgiFormat());
}
}
void GrD3DDirectCommandList::setGraphicsRootConstantBufferView(
unsigned int rootParameterIndex, D3D12_GPU_VIRTUAL_ADDRESS bufferLocation) {
fCommandList->SetGraphicsRootConstantBufferView(rootParameterIndex, bufferLocation);

View File

@ -155,6 +155,10 @@ public:
void clearDepthStencilView(const GrD3DStencilAttachment*, uint8_t stencilClearValue,
const D3D12_RECT* rect);
void setRenderTarget(const GrD3DRenderTarget* renderTarget);
void resolveSubresourceRegion(const GrD3DTextureResource* dstTexture,
UINT dstX, UINT dstY,
const GrD3DTextureResource* srcTexture,
D3D12_RECT* srcRect);
void setGraphicsRootConstantBufferView(unsigned int rootParameterIndex,
D3D12_GPU_VIRTUAL_ADDRESS bufferLocation);

View File

@ -391,7 +391,49 @@ void GrD3DGpu::copySurfaceAsCopyTexture(GrSurface* dst, GrSurface* src,
void GrD3DGpu::copySurfaceAsResolve(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
const SkIPoint& dstPoint) {
// TODO
GrD3DRenderTarget* srcRT = static_cast<GrD3DRenderTarget*>(src->asRenderTarget());
SkASSERT(srcRT);
this->resolveTexture(dst, dstPoint.fX, dstPoint.fY, srcRT, srcRect);
}
void GrD3DGpu::resolveTexture(GrSurface* dst, int32_t dstX, int32_t dstY,
GrD3DRenderTarget* src, const SkIRect& srcIRect) {
SkASSERT(dst);
SkASSERT(src && src->numSamples() > 1 && src->msaaTextureResource());
D3D12_RECT srcRect = { srcIRect.fLeft, srcIRect.fTop, srcIRect.fRight, srcIRect.fBottom };
GrD3DTextureResource* dstTextureResource;
GrRenderTarget* dstRT = dst->asRenderTarget();
if (dstRT) {
dstTextureResource = static_cast<GrD3DRenderTarget*>(dstRT);
} else {
SkASSERT(dst->asTexture());
dstTextureResource = static_cast<GrD3DTexture*>(dst->asTexture());
}
dstTextureResource->setResourceState(this, D3D12_RESOURCE_STATE_RESOLVE_DEST);
src->msaaTextureResource()->setResourceState(this, D3D12_RESOURCE_STATE_RESOLVE_SOURCE);
fCurrentDirectCommandList->resolveSubresourceRegion(dstTextureResource, dstX, dstY,
src->msaaTextureResource(), &srcRect);
}
void GrD3DGpu::onResolveRenderTarget(GrRenderTarget* target, const SkIRect& resolveRect,
ForExternalIO forExternalIO) {
SkASSERT(target->numSamples() > 1);
GrD3DRenderTarget* rt = static_cast<GrD3DRenderTarget*>(target);
SkASSERT(rt->msaaTextureResource());
this->resolveTexture(target, resolveRect.fLeft, resolveRect.fTop, rt, resolveRect);
if (ForExternalIO::kYes == forExternalIO) {
// This resolve is called when we are preparing an msaa surface for external I/O. It is
// called after flushing, so we need to make sure we submit the command buffer after doing
// the resolve so that the resolve actually happens.
this->submitDirectCommandList(SyncQueue::kSkip);
}
}
bool GrD3DGpu::onReadPixels(GrSurface* surface, int left, int top, int width, int height,

View File

@ -180,7 +180,7 @@ private:
bool onRegenerateMipMapLevels(GrTexture*) override { return true; }
void onResolveRenderTarget(GrRenderTarget* target, const SkIRect&, ForExternalIO) override {}
void onResolveRenderTarget(GrRenderTarget* target, const SkIRect&, ForExternalIO) override;
void addFinishedProc(GrGpuFinishedProc finishedProc,
GrGpuFinishedContext finishedContext) override;
@ -222,6 +222,8 @@ private:
void copySurfaceAsResolve(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
const SkIPoint& dstPoint);
void resolveTexture(GrSurface* dst, int32_t dstX, int32_t dstY,
GrD3DRenderTarget* src, const SkIRect& srcRect);
bool uploadToTexture(GrD3DTexture* tex, int left, int top, int width, int height,
GrColorType colorType, const GrMipLevel* texels, int mipLevelCount);

View File

@ -116,6 +116,8 @@ static const struct {
#endif
#ifdef SK_DIRECT3D
{ "d3d", "gpu", "api=direct3d" },
{ "d3dmsaa4", "gpu", "api=direct3d,samples=4" },
{ "d3dmsaa8", "gpu", "api=direct3d,samples=8" },
#endif
};
// clang-format on

View File

@ -103,7 +103,7 @@ void D3D12WindowContext::initializeContext() {
swapChainDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
swapChainDesc.SampleDesc.Count = 1; // TODO: support MSAA
swapChainDesc.SampleDesc.Count = 1;
gr_cp<IDXGISwapChain1> swapChain;
GR_D3D_CALL_ERRCHECK(factory->CreateSwapChainForHwnd(
@ -116,6 +116,8 @@ void D3D12WindowContext::initializeContext() {
fBufferIndex = fSwapChain->GetCurrentBackBufferIndex();
fSampleCount = fDisplayParams.fMSAASampleCount;
this->setupSurfaces(width, height);
for (int i = 0; i < kNumFrames; ++i) {
@ -131,7 +133,6 @@ void D3D12WindowContext::initializeContext() {
fHeight = height;
}
void D3D12WindowContext::setupSurfaces(int width, int height) {
// set up base resource info
GrD3DTextureResourceInfo info(nullptr,
@ -145,12 +146,18 @@ void D3D12WindowContext::setupSurfaces(int width, int height) {
SkASSERT(fBuffers[i]->GetDesc().Width == (UINT64)width &&
fBuffers[i]->GetDesc().Height == (UINT64)height);
// TODO: support MSAA
info.fResource = fBuffers[i];
GrBackendRenderTarget backendRT(width, height, 1, info);
fSurfaces[i] = SkSurface::MakeFromBackendRenderTarget(
fContext.get(), backendRT, kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType,
fDisplayParams.fColorSpace, &fDisplayParams.fSurfaceProps);
if (fSampleCount > 1) {
GrBackendTexture backendTexture(width, height, info);
fSurfaces[i] = SkSurface::MakeFromBackendTexture(
fContext.get(), backendTexture, kTopLeft_GrSurfaceOrigin, fSampleCount,
kRGBA_8888_SkColorType, fDisplayParams.fColorSpace, &fDisplayParams.fSurfaceProps);
} else {
GrBackendRenderTarget backendRT(width, height, 1, info);
fSurfaces[i] = SkSurface::MakeFromBackendRenderTarget(
fContext.get(), backendRT, kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType,
fDisplayParams.fColorSpace, &fDisplayParams.fSurfaceProps);
}
}
}