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>
diff --git a/src/gpu/dawn/GrDawnCaps.cpp b/src/gpu/dawn/GrDawnCaps.cpp
index d645b83..201ea10 100644
--- a/src/gpu/dawn/GrDawnCaps.cpp
+++ b/src/gpu/dawn/GrDawnCaps.cpp
@@ -13,6 +13,9 @@
fMaxTextureSize = 2048; // FIXME
fMaxVertexAttributes = 16; // FIXME
fPerformPartialClearsAsDraws = true;
+
+ this->applyOptionsOverrides(contextOptions);
+ fShaderCaps->applyOptionsOverrides(contextOptions);
}
bool GrDawnCaps::isFormatSRGB(const GrBackendFormat& format) const {
diff --git a/src/gpu/dawn/GrDawnGpu.cpp b/src/gpu/dawn/GrDawnGpu.cpp
index 1a29bff..b85d134 100644
--- a/src/gpu/dawn/GrDawnGpu.cpp
+++ b/src/gpu/dawn/GrDawnGpu.cpp
@@ -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 @@
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,
diff --git a/src/gpu/dawn/GrDawnGpuCommandBuffer.cpp b/src/gpu/dawn/GrDawnGpuCommandBuffer.cpp
index 47dda8d..1f1a664 100644
--- a/src/gpu/dawn/GrDawnGpuCommandBuffer.cpp
+++ b/src/gpu/dawn/GrDawnGpuCommandBuffer.cpp
@@ -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 @@
, 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::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::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 @@
}
}
-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 @@
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 @@
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 @@
} 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,
diff --git a/src/gpu/dawn/GrDawnGpuCommandBuffer.h b/src/gpu/dawn/GrDawnGpuCommandBuffer.h
index b3a7486..afe323b 100644
--- a/src/gpu/dawn/GrDawnGpuCommandBuffer.h
+++ b/src/gpu/dawn/GrDawnGpuCommandBuffer.h
@@ -62,7 +62,7 @@
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 @@
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,
diff --git a/src/gpu/dawn/GrDawnProgramBuilder.cpp b/src/gpu/dawn/GrDawnProgramBuilder.cpp
index 850b388..9801a38 100644
--- a/src/gpu/dawn/GrDawnProgramBuilder.cpp
+++ b/src/gpu/dawn/GrDawnProgramBuilder.cpp
@@ -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_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 @@
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 @@
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 @@
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 @@
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;
}
diff --git a/src/gpu/dawn/GrDawnProgramBuilder.h b/src/gpu/dawn/GrDawnProgramBuilder.h
index 656ef51..5227e4c 100644
--- a/src/gpu/dawn/GrDawnProgramBuilder.h
+++ b/src/gpu/dawn/GrDawnProgramBuilder.h
@@ -65,6 +65,7 @@
dawn::PipelineLayout fPipelineLayout;
dawn::BindGroup fUniformBindGroup;
dawn::ColorStateDescriptor fColorState;
+ dawn::DepthStencilStateDescriptor fDepthStencilState;
GrDawnProgramDataManager fDataManager;
RenderTargetState fRenderTargetState;
BuiltinUniformHandles fBuiltinUniformHandles;
@@ -83,6 +84,8 @@
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; }
diff --git a/src/gpu/dawn/GrDawnStencilAttachment.cpp b/src/gpu/dawn/GrDawnStencilAttachment.cpp
new file mode 100644
index 0000000..f62b9a5
--- /dev/null
+++ b/src/gpu/dawn/GrDawnStencilAttachment.cpp
@@ -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());
+}
diff --git a/src/gpu/dawn/GrDawnStencilAttachment.h b/src/gpu/dawn/GrDawnStencilAttachment.h
new file mode 100644
index 0000000..b0afc23
--- /dev/null
+++ b/src/gpu/dawn/GrDawnStencilAttachment.h
@@ -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