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,
|
bool GrD3DCaps::canCopyAsResolve(DXGI_FORMAT dstFormat, int dstSampleCnt,
|
||||||
DXGI_FORMAT srcFormat, int srcSampleCnt) const {
|
DXGI_FORMAT srcFormat, int srcSampleCnt) const {
|
||||||
// TODO
|
// The src surface must be multisampled.
|
||||||
return false;
|
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,
|
bool GrD3DCaps::onCanCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src,
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "src/gpu/d3d/GrD3DStencilAttachment.h"
|
#include "src/gpu/d3d/GrD3DStencilAttachment.h"
|
||||||
#include "src/gpu/d3d/GrD3DTexture.h"
|
#include "src/gpu/d3d/GrD3DTexture.h"
|
||||||
#include "src/gpu/d3d/GrD3DTextureResource.h"
|
#include "src/gpu/d3d/GrD3DTextureResource.h"
|
||||||
|
#include "src/gpu/d3d/GrD3DUtil.h"
|
||||||
|
|
||||||
GrD3DCommandList::GrD3DCommandList(gr_cp<ID3D12CommandAllocator> allocator,
|
GrD3DCommandList::GrD3DCommandList(gr_cp<ID3D12CommandAllocator> allocator,
|
||||||
gr_cp<ID3D12GraphicsCommandList> commandList)
|
gr_cp<ID3D12GraphicsCommandList> commandList)
|
||||||
@ -383,6 +384,32 @@ void GrD3DDirectCommandList::setRenderTarget(const GrD3DRenderTarget* renderTarg
|
|||||||
fCommandList->OMSetRenderTargets(1, &rtvDescriptor, false, dsDescriptorPtr);
|
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(
|
void GrD3DDirectCommandList::setGraphicsRootConstantBufferView(
|
||||||
unsigned int rootParameterIndex, D3D12_GPU_VIRTUAL_ADDRESS bufferLocation) {
|
unsigned int rootParameterIndex, D3D12_GPU_VIRTUAL_ADDRESS bufferLocation) {
|
||||||
fCommandList->SetGraphicsRootConstantBufferView(rootParameterIndex, bufferLocation);
|
fCommandList->SetGraphicsRootConstantBufferView(rootParameterIndex, bufferLocation);
|
||||||
|
@ -155,6 +155,10 @@ public:
|
|||||||
void clearDepthStencilView(const GrD3DStencilAttachment*, uint8_t stencilClearValue,
|
void clearDepthStencilView(const GrD3DStencilAttachment*, uint8_t stencilClearValue,
|
||||||
const D3D12_RECT* rect);
|
const D3D12_RECT* rect);
|
||||||
void setRenderTarget(const GrD3DRenderTarget* renderTarget);
|
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,
|
void setGraphicsRootConstantBufferView(unsigned int rootParameterIndex,
|
||||||
D3D12_GPU_VIRTUAL_ADDRESS bufferLocation);
|
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,
|
void GrD3DGpu::copySurfaceAsResolve(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
|
||||||
const SkIPoint& dstPoint) {
|
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,
|
bool GrD3DGpu::onReadPixels(GrSurface* surface, int left, int top, int width, int height,
|
||||||
|
@ -180,7 +180,7 @@ private:
|
|||||||
|
|
||||||
bool onRegenerateMipMapLevels(GrTexture*) override { return true; }
|
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,
|
void addFinishedProc(GrGpuFinishedProc finishedProc,
|
||||||
GrGpuFinishedContext finishedContext) override;
|
GrGpuFinishedContext finishedContext) override;
|
||||||
@ -222,6 +222,8 @@ private:
|
|||||||
|
|
||||||
void copySurfaceAsResolve(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
|
void copySurfaceAsResolve(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
|
||||||
const SkIPoint& dstPoint);
|
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,
|
bool uploadToTexture(GrD3DTexture* tex, int left, int top, int width, int height,
|
||||||
GrColorType colorType, const GrMipLevel* texels, int mipLevelCount);
|
GrColorType colorType, const GrMipLevel* texels, int mipLevelCount);
|
||||||
|
@ -116,6 +116,8 @@ static const struct {
|
|||||||
#endif
|
#endif
|
||||||
#ifdef SK_DIRECT3D
|
#ifdef SK_DIRECT3D
|
||||||
{ "d3d", "gpu", "api=direct3d" },
|
{ "d3d", "gpu", "api=direct3d" },
|
||||||
|
{ "d3dmsaa4", "gpu", "api=direct3d,samples=4" },
|
||||||
|
{ "d3dmsaa8", "gpu", "api=direct3d,samples=8" },
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
@ -103,7 +103,7 @@ void D3D12WindowContext::initializeContext() {
|
|||||||
swapChainDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
swapChainDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||||
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
||||||
swapChainDesc.SampleDesc.Count = 1; // TODO: support MSAA
|
swapChainDesc.SampleDesc.Count = 1;
|
||||||
|
|
||||||
gr_cp<IDXGISwapChain1> swapChain;
|
gr_cp<IDXGISwapChain1> swapChain;
|
||||||
GR_D3D_CALL_ERRCHECK(factory->CreateSwapChainForHwnd(
|
GR_D3D_CALL_ERRCHECK(factory->CreateSwapChainForHwnd(
|
||||||
@ -116,6 +116,8 @@ void D3D12WindowContext::initializeContext() {
|
|||||||
|
|
||||||
fBufferIndex = fSwapChain->GetCurrentBackBufferIndex();
|
fBufferIndex = fSwapChain->GetCurrentBackBufferIndex();
|
||||||
|
|
||||||
|
fSampleCount = fDisplayParams.fMSAASampleCount;
|
||||||
|
|
||||||
this->setupSurfaces(width, height);
|
this->setupSurfaces(width, height);
|
||||||
|
|
||||||
for (int i = 0; i < kNumFrames; ++i) {
|
for (int i = 0; i < kNumFrames; ++i) {
|
||||||
@ -131,7 +133,6 @@ void D3D12WindowContext::initializeContext() {
|
|||||||
fHeight = height;
|
fHeight = height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void D3D12WindowContext::setupSurfaces(int width, int height) {
|
void D3D12WindowContext::setupSurfaces(int width, int height) {
|
||||||
// set up base resource info
|
// set up base resource info
|
||||||
GrD3DTextureResourceInfo info(nullptr,
|
GrD3DTextureResourceInfo info(nullptr,
|
||||||
@ -145,12 +146,18 @@ void D3D12WindowContext::setupSurfaces(int width, int height) {
|
|||||||
SkASSERT(fBuffers[i]->GetDesc().Width == (UINT64)width &&
|
SkASSERT(fBuffers[i]->GetDesc().Width == (UINT64)width &&
|
||||||
fBuffers[i]->GetDesc().Height == (UINT64)height);
|
fBuffers[i]->GetDesc().Height == (UINT64)height);
|
||||||
|
|
||||||
// TODO: support MSAA
|
|
||||||
info.fResource = fBuffers[i];
|
info.fResource = fBuffers[i];
|
||||||
GrBackendRenderTarget backendRT(width, height, 1, info);
|
if (fSampleCount > 1) {
|
||||||
fSurfaces[i] = SkSurface::MakeFromBackendRenderTarget(
|
GrBackendTexture backendTexture(width, height, info);
|
||||||
fContext.get(), backendRT, kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType,
|
fSurfaces[i] = SkSurface::MakeFromBackendTexture(
|
||||||
fDisplayParams.fColorSpace, &fDisplayParams.fSurfaceProps);
|
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