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:
parent
9cf98dcb49
commit
275f419a60
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user