Add GrD3DStencilAttachment

Bug: skia:9935
Change-Id: I249b819d3cc1387aecde200907657ffcd67d1833
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/282591
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Jim Van Verth <jvanverth@google.com>
This commit is contained in:
Jim Van Verth 2020-04-13 11:02:21 -04:00 committed by Skia Commit-Bot
parent ecd82d832f
commit 4f51f47d14
7 changed files with 199 additions and 4 deletions

View File

@ -743,6 +743,8 @@ skia_direct3d_sources = [
"$_src/gpu/d3d/GrD3DResourceProvider.cpp",
"$_src/gpu/d3d/GrD3DResourceProvider.h",
"$_src/gpu/d3d/GrD3DResourceState.h",
"$_src/gpu/d3d/GrD3DStencilAttachment.cpp",
"$_src/gpu/d3d/GrD3DStencilAttachment.h",
"$_src/gpu/d3d/GrD3DTexture.cpp",
"$_src/gpu/d3d/GrD3DTexture.h",
"$_src/gpu/d3d/GrD3DTextureRenderTarget.cpp",

View File

@ -110,7 +110,7 @@ void GrD3DCaps::init(const GrContextOptions& contextOptions, IDXGIAdapter1* adap
this->initShaderCaps(adapterDesc.VendorId, optionsDesc);
this->initFormatTable(adapterDesc, device);
// TODO: set up stencil
this->initStencilFormat(device);
if (!contextOptions.fDisableDriverCorrectnessWorkarounds) {
this->applyDriverCorrectnessWorkarounds(adapterDesc.VendorId);
@ -207,6 +207,33 @@ void GrD3DCaps::applyDriverCorrectnessWorkarounds(int vendorID) {
// Nothing yet.
}
bool stencil_format_supported(ID3D12Device* device, DXGI_FORMAT format) {
D3D12_FEATURE_DATA_FORMAT_SUPPORT formatSupportDesc;
formatSupportDesc.Format = format;
SkDEBUGCODE(HRESULT hr = ) device->CheckFeatureSupport(D3D12_FEATURE_FORMAT_SUPPORT,
&formatSupportDesc,
sizeof(formatSupportDesc));
SkASSERT(SUCCEEDED(hr));
return SkToBool(D3D12_FORMAT_SUPPORT1_DEPTH_STENCIL & formatSupportDesc.Support1);
}
void GrD3DCaps::initStencilFormat(ID3D12Device* device) {
// List of legal stencil formats (though perhaps not supported on
// the particular gpu/driver) from most preferred to least.
static const StencilFormat
// internal Format stencil bits
gD24S8 = { DXGI_FORMAT_D24_UNORM_S8_UINT, 8 },
gD32S8 = { DXGI_FORMAT_D32_FLOAT_S8X24_UINT, 8 };
if (stencil_format_supported(device, DXGI_FORMAT_D24_UNORM_S8_UINT)) {
fPreferredStencilFormat = gD24S8;
} else {
SkASSERT(stencil_format_supported(device, DXGI_FORMAT_D32_FLOAT_S8X24_UINT));
fPreferredStencilFormat = gD32S8;
}
}
// These are all the valid DXGI_FORMATs that we support in Skia. They are roughly ordered from most
// frequently used to least to improve look up times in arrays.
static constexpr DXGI_FORMAT kDxgiFormats[] = {

View File

@ -11,6 +11,7 @@
#include "src/gpu/GrCaps.h"
#include "include/gpu/d3d/GrD3DTypes.h"
#include "src/gpu/d3d/GrD3DStencilAttachment.h"
class GrShaderCaps;
@ -19,6 +20,8 @@ class GrShaderCaps;
*/
class GrD3DCaps : public GrCaps {
public:
typedef GrD3DStencilAttachment::Format StencilFormat;
/**
* Creates a GrD3DCaps that is set such that nothing is supported. The init function should
* be called to fill out the caps.
@ -53,6 +56,26 @@ public:
SurfaceReadPixelsSupport surfaceSupportsReadPixels(const GrSurface*) const override;
/**
* Returns both a supported and most preferred stencil format to use in draws.
*/
const StencilFormat& preferredStencilFormat() const {
return fPreferredStencilFormat;
}
static int GetStencilFormatTotalBitCount(DXGI_FORMAT format) {
switch (format) {
case DXGI_FORMAT_D24_UNORM_S8_UINT:
return 32;
case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
// DXGI_FORMAT_D32_FLOAT_S8X24_UINT has 24 unused bits at the end so total bits is 64.
return 64;
default:
SkASSERT(false);
return 0;
}
}
GrBackendFormat getBackendFormatFromCompressionType(SkImage::CompressionType) const override;
DXGI_FORMAT getFormatFromColorType(GrColorType colorType) const {
@ -92,6 +115,7 @@ private:
void initShaderCaps(int vendorID, const D3D12_FEATURE_DATA_D3D12_OPTIONS& optionsDesc);
void initFormatTable(const DXGI_ADAPTER_DESC&, ID3D12Device*);
void initStencilFormat(ID3D12Device*);
void applyDriverCorrectnessWorkarounds(int vendorID);
@ -165,6 +189,8 @@ private:
int fMaxPerStageShaderResourceViews;
int fMaxPerStageUnorderedAccessViews;
StencilFormat fPreferredStencilFormat;
typedef GrCaps INHERITED;
};

View File

@ -13,6 +13,7 @@
#include "src/gpu/d3d/GrD3DBuffer.h"
#include "src/gpu/d3d/GrD3DCaps.h"
#include "src/gpu/d3d/GrD3DOpsRenderPass.h"
#include "src/gpu/d3d/GrD3DStencilAttachment.h"
#include "src/gpu/d3d/GrD3DTexture.h"
#include "src/gpu/d3d/GrD3DTextureRenderTarget.h"
#include "src/gpu/d3d/GrD3DUtil.h"
@ -418,8 +419,19 @@ sk_sp<GrGpuBuffer> GrD3DGpu::onCreateBuffer(size_t sizeInBytes, GrGpuBufferType
GrStencilAttachment* GrD3DGpu::createStencilAttachmentForRenderTarget(
const GrRenderTarget* rt, int width, int height, int numStencilSamples) {
// TODO
return nullptr;
SkASSERT(numStencilSamples == rt->numSamples() || this->caps()->mixedSamplesSupport());
SkASSERT(width >= rt->width());
SkASSERT(height >= rt->height());
const GrD3DCaps::StencilFormat& sFmt = this->d3dCaps().preferredStencilFormat();
GrD3DStencilAttachment* stencil(GrD3DStencilAttachment::Make(this,
width,
height,
numStencilSamples,
sFmt));
fStats.incStencilAttachmentCreates();
return stencil;
}
bool GrD3DGpu::createTextureResourceForBackendSurface(DXGI_FORMAT dxgiFormat,

View File

@ -93,7 +93,7 @@ private:
GrD3DGpu* getD3DGpu() const;
bool completeStencilAttachment() override { /* TODO */ return false; }
bool completeStencilAttachment() override { return true; }
// In Direct3D we call the release proc after we are finished with the underlying
// GrD3DTextureResource::Resource object (which occurs after the GPU finishes all work on it).

View File

@ -0,0 +1,81 @@
/*
* Copyright 2020 Google LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "src/gpu/d3d/GrD3DStencilAttachment.h"
#include "src/gpu/d3d/GrD3DGpu.h"
GrD3DStencilAttachment::GrD3DStencilAttachment(GrD3DGpu* gpu,
const Format& format,
const D3D12_RESOURCE_DESC& desc,
const GrD3DTextureResourceInfo& info,
sk_sp<GrD3DResourceState> state)
: GrStencilAttachment(gpu, desc.Width, desc.Height, format.fStencilBits,
desc.SampleDesc.Count)
, GrD3DTextureResource(info, state) {
this->registerWithCache(SkBudgeted::kYes);
}
GrD3DStencilAttachment* GrD3DStencilAttachment::Make(GrD3DGpu* gpu,
int width,
int height,
int sampleCnt,
const Format& format) {
D3D12_RESOURCE_DESC resourceDesc;
resourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
resourceDesc.Alignment = 0; // default alignment
resourceDesc.Width = width;
resourceDesc.Height = height;
resourceDesc.DepthOrArraySize = 1;
resourceDesc.MipLevels = 1;
resourceDesc.Format = format.fInternalFormat;
resourceDesc.SampleDesc.Count = sampleCnt;
resourceDesc.SampleDesc.Quality = 0; // quality levels are only supported for tiled resources
// so ignore for now
resourceDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; // use driver-selected swizzle
resourceDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL;
GrD3DTextureResourceInfo info;
// TODO: it'd be better if we initialized the resource in DEPTH_WRITE state instead of COMMON
if (!GrD3DTextureResource::InitTextureResourceInfo(gpu, resourceDesc, GrProtected::kNo, &info)) {
return nullptr;
}
sk_sp<GrD3DResourceState> state(new GrD3DResourceState(info.fResourceState));
GrD3DStencilAttachment* stencil = new GrD3DStencilAttachment(gpu, format, resourceDesc,
info, std::move(state));
return stencil;
}
size_t GrD3DStencilAttachment::onGpuMemorySize() const {
uint64_t size = this->width();
size *= this->height();
size *= GrD3DCaps::GetStencilFormatTotalBitCount(this->dxgiFormat());
size *= this->numSamples();
return static_cast<size_t>(size / 8);
}
void GrD3DStencilAttachment::onRelease() {
GrD3DGpu* gpu = this->getD3DGpu();
this->releaseResource(gpu);
GrStencilAttachment::onRelease();
}
void GrD3DStencilAttachment::onAbandon() {
GrD3DGpu* gpu = this->getD3DGpu();
this->releaseResource(gpu);
GrStencilAttachment::onAbandon();
}
GrD3DGpu* GrD3DStencilAttachment::getD3DGpu() const {
SkASSERT(!this->wasDestroyed());
return static_cast<GrD3DGpu*>(this->getGpu());
}

View File

@ -0,0 +1,47 @@
/*
* Copyright 2020 Google LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef GrD3DStencilAttachment_DEFINED
#define GrD3DStencilAttachment_DEFINED
#include "src/gpu/GrStencilAttachment.h"
#include "include/gpu/d3d/GrD3DTypes.h"
#include "src/gpu/d3d/GrD3DTextureResource.h"
class GrD3DGpu;
class GrD3DStencilAttachment : public GrStencilAttachment, GrD3DTextureResource {
public:
struct Format {
DXGI_FORMAT fInternalFormat;
int fStencilBits;
};
static GrD3DStencilAttachment* Make(GrD3DGpu* gpu, int width, int height,
int sampleCnt, const Format& format);
~GrD3DStencilAttachment() override {}
protected:
void onRelease() override;
void onAbandon() override;
private:
size_t onGpuMemorySize() const override;
GrD3DStencilAttachment(GrD3DGpu* gpu,
const Format& format,
const D3D12_RESOURCE_DESC&,
const GrD3DTextureResourceInfo&,
sk_sp<GrD3DResourceState>);
GrD3DGpu* getD3DGpu() const;
};
#endif