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:
parent
ecd82d832f
commit
4f51f47d14
@ -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",
|
||||
|
@ -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[] = {
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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).
|
||||
|
81
src/gpu/d3d/GrD3DStencilAttachment.cpp
Normal file
81
src/gpu/d3d/GrD3DStencilAttachment.cpp
Normal 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());
|
||||
}
|
47
src/gpu/d3d/GrD3DStencilAttachment.h
Normal file
47
src/gpu/d3d/GrD3DStencilAttachment.h
Normal 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
|
Loading…
Reference in New Issue
Block a user