Dawn backend: implement stencil, primitive topology, separate blends.

Remove beginDraw()/endDraw() in favour of applyState().
This allows for varying primitive topology between meshes in a single

draw: call applyState() prior to drawing each mesh in case the
primitive type changed.
Initial support for onClear() and onClearStencil() in GrNXTGpuRTCommandBuffer.
Modify beginRenderPass() to take the LoadOps for color and stencil, so we
can encode render passes for stencil operations.
Add support for reverse-subtract blend equation.
Also apply options overrides in caps initialization.
Change-Id: I8547961c414187dbc763a67d6c7ec4383d6ce6f6
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/232136
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Stephen White <senorblanco@chromium.org>
This commit is contained in:
Stephen White 2019-08-09 12:28:37 -04:00 committed by Skia Commit-Bot
parent 74c19de3be
commit f813ef7d1b
9 changed files with 316 additions and 36 deletions

View File

@ -726,6 +726,8 @@ skia_dawn_sources = [
"$_src/gpu/dawn/GrDawnProgramBuilder.h",
"$_src/gpu/dawn/GrDawnRenderTarget.cpp",
"$_src/gpu/dawn/GrDawnRenderTarget.h",
"$_src/gpu/dawn/GrDawnStencilAttachment.cpp",
"$_src/gpu/dawn/GrDawnStencilAttachment.h",
"$_src/gpu/dawn/GrDawnUniformHandler.cpp",
"$_src/gpu/dawn/GrDawnUniformHandler.h",
"$_src/gpu/dawn/GrDawnUtil.cpp",

View File

@ -13,6 +13,9 @@ GrDawnCaps::GrDawnCaps(const GrContextOptions& contextOptions) : INHERITED(conte
fMaxTextureSize = 2048; // FIXME
fMaxVertexAttributes = 16; // FIXME
fPerformPartialClearsAsDraws = true;
this->applyOptionsOverrides(contextOptions);
fShaderCaps->applyOptionsOverrides(contextOptions);
}
bool GrDawnCaps::isFormatSRGB(const GrBackendFormat& format) const {

View File

@ -21,6 +21,7 @@
#include "src/gpu/dawn/GrDawnCaps.h"
#include "src/gpu/dawn/GrDawnGpuCommandBuffer.h"
#include "src/gpu/dawn/GrDawnRenderTarget.h"
#include "src/gpu/dawn/GrDawnStencilAttachment.h"
#include "src/sksl/SkSLCompiler.h"
@ -177,8 +178,12 @@ GrStencilAttachment* GrDawnGpu::createStencilAttachmentForRenderTarget(const GrR
int width,
int height,
int numStencilSamples) {
SkASSERT(!"unimplemented");
return nullptr;
GrDawnStencilAttachment* stencil(GrDawnStencilAttachment::Create(this,
width,
height,
numStencilSamples));
fStats.incStencilAttachmentCreates();
return stencil;
}
GrBackendTexture GrDawnGpu::createBackendTexture(int width, int height,

View File

@ -17,6 +17,7 @@
#include "src/gpu/dawn/GrDawnGpu.h"
#include "src/gpu/dawn/GrDawnProgramBuilder.h"
#include "src/gpu/dawn/GrDawnRenderTarget.h"
#include "src/gpu/dawn/GrDawnStencilAttachment.h"
#include "src/gpu/dawn/GrDawnUtil.h"
#include "src/sksl/SkSLCompiler.h"
@ -60,14 +61,18 @@ GrDawnGpuRTCommandBuffer::GrDawnGpuRTCommandBuffer(GrDawnGpu* gpu,
, fGpu(gpu)
, fColorInfo(colorInfo) {
fEncoder = fGpu->device().CreateCommandEncoder();
fPassEncoder = beginRenderPass();
dawn::LoadOp colorOp = to_dawn_load_op(colorInfo.fLoadOp);
dawn::LoadOp stencilOp = to_dawn_load_op(stencilInfo.fLoadOp);
fPassEncoder = beginRenderPass(colorOp, stencilOp);
}
dawn::RenderPassEncoder GrDawnGpuRTCommandBuffer::beginRenderPass() {
dawn::RenderPassEncoder GrDawnGpuRTCommandBuffer::beginRenderPass(dawn::LoadOp colorOp,
dawn::LoadOp stencilOp) {
dawn::Texture texture = static_cast<GrDawnRenderTarget*>(fRenderTarget)->texture();
auto stencilAttachment = static_cast<GrDawnStencilAttachment*>(
fRenderTarget->renderTargetPriv().getStencilAttachment());
dawn::TextureView colorView = texture.CreateDefaultView();
const float *c = fColorInfo.fClearColor.vec();
dawn::LoadOp colorOp = to_dawn_load_op(fColorInfo.fLoadOp);
dawn::RenderPassColorAttachmentDescriptor colorAttachment;
colorAttachment.attachment = colorView;
@ -79,7 +84,19 @@ dawn::RenderPassEncoder GrDawnGpuRTCommandBuffer::beginRenderPass() {
dawn::RenderPassDescriptor renderPassDescriptor;
renderPassDescriptor.colorAttachmentCount = 1;
renderPassDescriptor.colorAttachments = &colorAttachments;
renderPassDescriptor.depthStencilAttachment = nullptr;
if (stencilAttachment) {
dawn::RenderPassDepthStencilAttachmentDescriptor depthStencilAttachment;
depthStencilAttachment.attachment = stencilAttachment->view();
depthStencilAttachment.depthLoadOp = stencilOp;
depthStencilAttachment.stencilLoadOp = stencilOp;
depthStencilAttachment.clearDepth = 1.0f;
depthStencilAttachment.clearStencil = 0;
depthStencilAttachment.depthStoreOp = dawn::StoreOp::Store;
depthStencilAttachment.stencilStoreOp = dawn::StoreOp::Store;
renderPassDescriptor.depthStencilAttachment = &depthStencilAttachment;
} else {
renderPassDescriptor.depthStencilAttachment = nullptr;
}
return fEncoder.BeginRenderPass(&renderPassDescriptor);
}
@ -112,11 +129,13 @@ void GrDawnGpuRTCommandBuffer::transferFrom(const SkIRect& srcRect, GrColorType
}
void GrDawnGpuRTCommandBuffer::onClearStencilClip(const GrFixedClip& clip, bool insideStencilMask) {
SkASSERT(!"unimplemented");
fPassEncoder.EndPass();
fPassEncoder = beginRenderPass(dawn::LoadOp::Load, dawn::LoadOp::Clear);
}
void GrDawnGpuRTCommandBuffer::onClear(const GrFixedClip& clip, const SkPMColor4f& color) {
SkASSERT(!"unimplemented");
fPassEncoder.EndPass();
fPassEncoder = beginRenderPass(dawn::LoadOp::Clear, dawn::LoadOp::Load);
}
////////////////////////////////////////////////////////////////////////////////
@ -157,17 +176,42 @@ static dawn::VertexFormat to_dawn_vertex_format(GrVertexAttribType type) {
}
}
void GrDawnGpuRTCommandBuffer::beginDraw(const GrPipeline& pipeline,
const GrPrimitiveProcessor& primProc,
const GrTextureProxy* const primProcProxies[],
bool hasPoints) {
static dawn::PrimitiveTopology to_dawn_primitive_topology(GrPrimitiveType primitiveType) {
switch (primitiveType) {
case GrPrimitiveType::kTriangles:
return dawn::PrimitiveTopology::TriangleList;
case GrPrimitiveType::kTriangleStrip:
return dawn::PrimitiveTopology::TriangleStrip;
case GrPrimitiveType::kPoints:
return dawn::PrimitiveTopology::PointList;
case GrPrimitiveType::kLines:
return dawn::PrimitiveTopology::LineList;
case GrPrimitiveType::kLineStrip:
return dawn::PrimitiveTopology::LineStrip;
case GrPrimitiveType::kLinesAdjacency:
default:
SkASSERT(!"unsupported primitive topology");
return dawn::PrimitiveTopology::TriangleList;
}
}
void GrDawnGpuRTCommandBuffer::applyState(const GrPipeline& pipeline,
const GrPrimitiveProcessor& primProc,
const GrTextureProxy* const primProcProxies[],
const GrPipeline::FixedDynamicState* fixedDynamicState,
const GrPipeline::DynamicStateArrays* dynamicStateArrays,
const GrPrimitiveType primitiveType,
bool hasPoints) {
GrProgramDesc desc;
GrProgramDesc::Build(&desc, fRenderTarget, primProc, hasPoints, pipeline, fGpu);
dawn::TextureFormat colorFormat;
SkAssertResult(GrPixelConfigToDawnFormat(fRenderTarget->config(), &colorFormat));
dawn::TextureFormat stencilFormat = dawn::TextureFormat::Depth24PlusStencil8;
bool hasDepthStencil = fRenderTarget->renderTargetPriv().getStencilAttachment() != nullptr;
sk_sp<GrDawnProgram> program = GrDawnProgramBuilder::Build(fGpu, fRenderTarget, fOrigin,
pipeline, primProc, primProcProxies,
colorFormat, &desc);
colorFormat, hasDepthStencil,
stencilFormat, &desc);
SkASSERT(program);
program->setData(primProc, fRenderTarget, fOrigin, pipeline);
@ -225,12 +269,6 @@ void GrDawnGpuRTCommandBuffer::beginDraw(const GrPipeline& pipeline,
fsDesc.module = program->fFSModule;
fsDesc.entryPoint = "main";
dawn::StencilStateFaceDescriptor stencilFace;
stencilFace.compare = dawn::CompareFunction::Always;
stencilFace.failOp = dawn::StencilOperation::Keep;
stencilFace.depthFailOp = dawn::StencilOperation::Keep;
stencilFace.passOp = dawn::StencilOperation::Replace;
dawn::RasterizationStateDescriptor rastDesc;
rastDesc.frontFace = dawn::FrontFace::CW;
@ -245,18 +283,18 @@ void GrDawnGpuRTCommandBuffer::beginDraw(const GrPipeline& pipeline,
rpDesc.fragmentStage = &fsDesc;
rpDesc.vertexInput = &vertexInput;
rpDesc.rasterizationState = &rastDesc;
rpDesc.primitiveTopology = dawn::PrimitiveTopology::TriangleList;
rpDesc.primitiveTopology = to_dawn_primitive_topology(primitiveType);
rpDesc.sampleCount = 1;
rpDesc.depthStencilState = nullptr;
rpDesc.depthStencilState = hasDepthStencil ? &program->fDepthStencilState : nullptr;
rpDesc.colorStateCount = 1;
dawn::ColorStateDescriptor* colorStates[] = { &program->fColorState };
rpDesc.colorStates = colorStates;
dawn::RenderPipeline renderPipeline = fGpu->device().CreateRenderPipeline(&rpDesc);
fPassEncoder.SetPipeline(renderPipeline);
fPassEncoder.SetBindGroup(0, program->fUniformBindGroup, 0, nullptr);
}
void GrDawnGpuRTCommandBuffer::endDraw() {
if (pipeline.isStencilEnabled()) {
fPassEncoder.SetStencilReference(pipeline.getUserStencil()->fFront.fRef);
}
}
void GrDawnGpuRTCommandBuffer::onDraw(const GrPrimitiveProcessor& primProc,
@ -281,12 +319,11 @@ void GrDawnGpuRTCommandBuffer::onDraw(const GrPrimitiveProcessor& primProc,
} else if (fixedDynamicState) {
primProcProxies = fixedDynamicState->fPrimitiveProcessorTextures;
}
beginDraw(pipeline, primProc, primProcProxies, hasPoints);
for (int i = 0; i < meshCount; ++i) {
applyState(pipeline, primProc, primProcProxies, fixedDynamicState, dynamicStateArrays,
meshes[0].primitiveType(), hasPoints);
meshes[i].sendToGpu(this);
}
endDraw();
}
void GrDawnGpuRTCommandBuffer::sendInstancedMeshToGpu(GrPrimitiveType,

View File

@ -62,7 +62,7 @@ public:
void begin() override { }
void end() override;
dawn::RenderPassEncoder beginRenderPass();
dawn::RenderPassEncoder beginRenderPass(dawn::LoadOp colorOp, dawn::LoadOp stencilOp);
void transferFrom(const SkIRect& srcRect, GrColorType surfaceColorType,
GrColorType bufferColorType, GrGpuBuffer* transferBuffer,
size_t offset) override;
@ -77,12 +77,14 @@ public:
private:
GrGpu* gpu() override;
void beginDraw(const GrPipeline& pipeline,
const GrPrimitiveProcessor& primProc,
const GrTextureProxy* const primProcProxies[],
bool hasPoints);
void applyState(const GrPipeline& pipeline,
const GrPrimitiveProcessor& primProc,
const GrTextureProxy* const primProcProxies[],
const GrPipeline::FixedDynamicState* fixedDynamicState,
const GrPipeline::DynamicStateArrays* dynamicStateArrays,
const GrPrimitiveType primitiveType,
bool hasPoints);
void endDraw();
void onDraw(const GrPrimitiveProcessor& primProc,
const GrPipeline& pipeline,
const GrPipeline::FixedDynamicState* fixedDynamicState,

View File

@ -8,11 +8,11 @@
#include "src/gpu/dawn/GrDawnProgramBuilder.h"
#include "include/gpu/GrRenderTarget.h"
#include "src/gpu/GrShaderUtils.h"
#include "src/gpu/GrStencilSettings.h"
#include "src/gpu/dawn/GrDawnGpu.h"
#include "src/sksl/SkSLCompiler.h"
#include "src/gpu/GrShaderUtils.h"
static SkSL::String sksl_to_spirv(const GrDawnGpu* gpu, const char* shaderString,
SkSL::Program::Kind kind, SkSL::Program::Inputs* inputs) {
SkSL::Program::Settings settings;
@ -71,18 +71,84 @@ static dawn::BlendFactor to_dawn_blend_factor(GrBlendCoeff coeff) {
}
}
static dawn::BlendFactor to_dawn_blend_factor_for_alpha(GrBlendCoeff coeff) {
switch (coeff) {
// Force all srcColor used in alpha slot to alpha version.
case kSC_GrBlendCoeff:
return dawn::BlendFactor::SrcAlpha;
case kISC_GrBlendCoeff:
return dawn::BlendFactor::OneMinusSrcAlpha;
case kDC_GrBlendCoeff:
return dawn::BlendFactor::DstAlpha;
case kIDC_GrBlendCoeff:
return dawn::BlendFactor::OneMinusDstAlpha;
default:
return to_dawn_blend_factor(coeff);
}
}
static dawn::BlendOperation to_dawn_blend_operation(GrBlendEquation equation) {
switch (equation) {
case kAdd_GrBlendEquation:
return dawn::BlendOperation::Add;
case kSubtract_GrBlendEquation:
return dawn::BlendOperation::Subtract;
case kReverseSubtract_GrBlendEquation:
return dawn::BlendOperation::ReverseSubtract;
default:
SkASSERT(!"unsupported blend equation");
return dawn::BlendOperation::Add;
}
}
static dawn::CompareFunction to_dawn_compare_function(GrStencilTest test) {
switch (test) {
case GrStencilTest::kAlways:
return dawn::CompareFunction::Always;
case GrStencilTest::kNever:
return dawn::CompareFunction::Never;
case GrStencilTest::kGreater:
return dawn::CompareFunction::Greater;
case GrStencilTest::kGEqual:
return dawn::CompareFunction::GreaterEqual;
case GrStencilTest::kLess:
return dawn::CompareFunction::Less;
case GrStencilTest::kLEqual:
return dawn::CompareFunction::LessEqual;
case GrStencilTest::kEqual:
return dawn::CompareFunction::Equal;
case GrStencilTest::kNotEqual:
return dawn::CompareFunction::NotEqual;
default:
SkASSERT(!"unsupported stencil test");
return dawn::CompareFunction::Always;
}
}
static dawn::StencilOperation to_dawn_stencil_operation(GrStencilOp op) {
switch (op) {
case GrStencilOp::kKeep:
return dawn::StencilOperation::Keep;
case GrStencilOp::kZero:
return dawn::StencilOperation::Zero;
case GrStencilOp::kReplace:
return dawn::StencilOperation::Replace;
case GrStencilOp::kInvert:
return dawn::StencilOperation::Invert;
case GrStencilOp::kIncClamp:
return dawn::StencilOperation::IncrementClamp;
case GrStencilOp::kDecClamp:
return dawn::StencilOperation::DecrementClamp;
case GrStencilOp::kIncWrap:
return dawn::StencilOperation::IncrementWrap;
case GrStencilOp::kDecWrap:
return dawn::StencilOperation::DecrementWrap;
default:
SkASSERT(!"unsupported stencil function");
return dawn::StencilOperation::Keep;
}
}
static dawn::ColorStateDescriptor create_color_state(const GrDawnGpu* gpu,
const GrPipeline& pipeline,
dawn::TextureFormat colorFormat) {
@ -93,11 +159,13 @@ static dawn::ColorStateDescriptor create_color_state(const GrDawnGpu* gpu,
dawn::BlendFactor srcFactor = to_dawn_blend_factor(srcCoeff);
dawn::BlendFactor dstFactor = to_dawn_blend_factor(dstCoeff);
dawn::BlendFactor srcFactorAlpha = to_dawn_blend_factor_for_alpha(srcCoeff);
dawn::BlendFactor dstFactorAlpha = to_dawn_blend_factor_for_alpha(dstCoeff);
dawn::BlendOperation operation = to_dawn_blend_operation(equation);
auto mask = blendInfo.fWriteColor ? dawn::ColorWriteMask::All : dawn::ColorWriteMask::None;
dawn::BlendDescriptor colorDesc = {operation, srcFactor, dstFactor};
dawn::BlendDescriptor alphaDesc = {operation, srcFactor, dstFactor};
dawn::BlendDescriptor alphaDesc = {operation, srcFactorAlpha, dstFactorAlpha};
dawn::ColorStateDescriptor descriptor;
descriptor.format = colorFormat;
@ -109,6 +177,44 @@ static dawn::ColorStateDescriptor create_color_state(const GrDawnGpu* gpu,
return descriptor;
}
static dawn::StencilStateFaceDescriptor to_stencil_state_face(const GrStencilSettings::Face& face) {
dawn::StencilStateFaceDescriptor desc;
desc.compare = to_dawn_compare_function(face.fTest);
desc.failOp = desc.depthFailOp = to_dawn_stencil_operation(face.fFailOp);
desc.passOp = to_dawn_stencil_operation(face.fPassOp);
return desc;
}
static dawn::DepthStencilStateDescriptor create_depth_stencil_state(
const GrStencilSettings& stencilSettings,
dawn::TextureFormat depthStencilFormat,
GrSurfaceOrigin origin) {
dawn::DepthStencilStateDescriptor state;
state.format = depthStencilFormat;
state.depthWriteEnabled = false;
state.depthCompare = dawn::CompareFunction::Always;
if (stencilSettings.isDisabled()) {
dawn::StencilStateFaceDescriptor stencilFace;
stencilFace.compare = dawn::CompareFunction::Always;
stencilFace.failOp = dawn::StencilOperation::Keep;
stencilFace.depthFailOp = dawn::StencilOperation::Keep;
stencilFace.passOp = dawn::StencilOperation::Keep;
state.stencilReadMask = state.stencilWriteMask = 0x0;
state.stencilBack = state.stencilFront = stencilFace;
} else {
const GrStencilSettings::Face& front = stencilSettings.front(origin);
state.stencilReadMask = front.fTestMask;
state.stencilWriteMask = front.fWriteMask;
state.stencilFront = to_stencil_state_face(stencilSettings.front(origin));
if (stencilSettings.isTwoSided()) {
state.stencilBack = to_stencil_state_face(stencilSettings.back(origin));
} else {
state.stencilBack = state.stencilFront;
}
}
return state;
}
static dawn::BindGroupBinding make_bind_group_binding(uint32_t binding, const dawn::Buffer& buffer,
uint32_t offset, uint32_t size, const
dawn::Sampler& sampler,
@ -135,6 +241,8 @@ sk_sp<GrDawnProgram> GrDawnProgramBuilder::Build(GrDawnGpu* gpu,
const GrPrimitiveProcessor& primProc,
const GrTextureProxy* const primProcProxies[],
dawn::TextureFormat colorFormat,
bool hasDepthStencil,
dawn::TextureFormat depthStencilFormat,
GrProgramDesc* desc) {
GrDawnProgramBuilder builder(gpu, renderTarget, origin, primProc, primProcProxies, pipeline,
desc);
@ -201,6 +309,12 @@ sk_sp<GrDawnProgram> GrDawnProgramBuilder::Build(GrDawnGpu* gpu,
result->fPipelineLayout = gpu->device().CreatePipelineLayout(&pipelineLayoutDesc);
result->fBuiltinUniformHandles = builder.fUniformHandles;
result->fColorState = create_color_state(gpu, pipeline, colorFormat);
GrStencilSettings stencil;
if (pipeline.isStencilEnabled()) {
int numStencilBits = renderTarget->renderTargetPriv().numStencilBits();
stencil.reset(*pipeline.getUserStencil(), pipeline.hasStencilClip(), numStencilBits);
}
result->fDepthStencilState = create_depth_stencil_state(stencil, depthStencilFormat, origin);
return result;
}

View File

@ -65,6 +65,7 @@ struct GrDawnProgram : public SkRefCnt {
dawn::PipelineLayout fPipelineLayout;
dawn::BindGroup fUniformBindGroup;
dawn::ColorStateDescriptor fColorState;
dawn::DepthStencilStateDescriptor fDepthStencilState;
GrDawnProgramDataManager fDataManager;
RenderTargetState fRenderTargetState;
BuiltinUniformHandles fBuiltinUniformHandles;
@ -83,6 +84,8 @@ public:
const GrPrimitiveProcessor&,
const GrTextureProxy* const primProcProxies[],
dawn::TextureFormat colorFormat,
bool hasDepthStencil,
dawn::TextureFormat depthStencilFormat,
GrProgramDesc* desc);
const GrCaps* caps() const override;
GrGLSLUniformHandler* uniformHandler() override { return &fUniformHandler; }

View File

@ -0,0 +1,71 @@
/*
* Copyright 2019 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "src/gpu/dawn/GrDawnStencilAttachment.h"
#include "src/gpu/dawn/GrDawnGpu.h"
#include "src/gpu/dawn/GrDawnUtil.h"
#define VK_CALL(GPU, X) GR_VK_CALL(GPU->vkInterface(), X)
GrDawnStencilAttachment::GrDawnStencilAttachment(GrDawnGpu* gpu,
int width,
int height,
int bits,
int samples,
dawn::Texture texture,
dawn::TextureView view)
: INHERITED(gpu, width, height, bits, samples)
, fTexture(texture)
, fView(view) {
this->registerWithCache(SkBudgeted::kYes);
}
GrDawnStencilAttachment* GrDawnStencilAttachment::Create(GrDawnGpu* gpu,
int width,
int height,
int sampleCnt) {
dawn::TextureDescriptor desc;
desc.usage = dawn::TextureUsageBit::OutputAttachment;
desc.size.width = width;
desc.size.height = height;
desc.size.depth = 1;
desc.format = dawn::TextureFormat::Depth24PlusStencil8;
dawn::Texture texture = gpu->device().CreateTexture(&desc);
if (!texture) {
return nullptr;
}
dawn::TextureView view = texture.CreateDefaultView();
if (!view) {
return nullptr;
}
return new GrDawnStencilAttachment(gpu, width, height, 8, sampleCnt, texture, view);
}
GrDawnStencilAttachment::~GrDawnStencilAttachment() {
}
size_t GrDawnStencilAttachment::onGpuMemorySize() const {
uint64_t size = this->width();
size *= this->height();
size *= 32;
size *= SkTMax(1,this->numSamples());
return static_cast<size_t>(size / 8);
}
void GrDawnStencilAttachment::onRelease() {
GrStencilAttachment::onRelease();
}
void GrDawnStencilAttachment::onAbandon() {
GrStencilAttachment::onAbandon();
}
GrDawnGpu* GrDawnStencilAttachment::getDawnGpu() const {
SkASSERT(!this->wasDestroyed());
return static_cast<GrDawnGpu*>(this->getGpu());
}

View File

@ -0,0 +1,43 @@
/*
* Copyright 2019 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef GrDawnStencil_DEFINED
#define GrDawnStencil_DEFINED
#include "src/gpu/GrStencilAttachment.h"
#include "dawn/dawncpp.h"
class GrDawnGpu;
class GrDawnStencilAttachment : public GrStencilAttachment {
public:
static GrDawnStencilAttachment* Create(GrDawnGpu* gpu, int width, int height,
int sampleCnt);
~GrDawnStencilAttachment() override;
dawn::TextureView view() const { return fView; }
protected:
void onRelease() override;
void onAbandon() override;
private:
size_t onGpuMemorySize() const override;
GrDawnStencilAttachment(GrDawnGpu* gpu, int width, int height, int bits, int samples,
dawn::Texture texture, dawn::TextureView view);
GrDawnGpu* getDawnGpu() const;
dawn::Texture fTexture;
dawn::TextureView fView;
typedef GrStencilAttachment INHERITED;
};
#endif