Use a priori knowledge about the number of stencil bits in Dawn, Metal and Vulkan backends
The goal here is to centralize more of the program key creation w/in GrProgramInfo. For Dawn,
Metal and Vulkan, afaict, the number of stencil bits is always 8. We can use this information
to stop passing the GrStencilSettings object around. For GL, the number of stencil bits is
variable but it is never part of the key.
Bug: skia:9455
Change-Id: I8fd2bea2422c5b9df69fc184d3a82013eef5407e
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/254177
Commit-Queue: Robert Phillips <robertphillips@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
diff --git a/src/gpu/GrProgramInfo.cpp b/src/gpu/GrProgramInfo.cpp
index 3391b61..a646f56 100644
--- a/src/gpu/GrProgramInfo.cpp
+++ b/src/gpu/GrProgramInfo.cpp
@@ -7,6 +7,19 @@
#include "src/gpu/GrProgramInfo.h"
+#include "src/gpu/GrStencilSettings.h"
+
+GrStencilSettings GrProgramInfo::nonGLStencilSettings() const {
+ GrStencilSettings stencil;
+
+ if (this->pipeline().isStencilEnabled()) {
+ stencil.reset(*this->pipeline().getUserStencil(),
+ this->pipeline().hasStencilClip(),
+ 8);
+ }
+
+ return stencil;
+}
#ifdef SK_DEBUG
#include "src/gpu/GrMesh.h"
diff --git a/src/gpu/GrProgramInfo.h b/src/gpu/GrProgramInfo.h
index 72be94c..1b7b347 100644
--- a/src/gpu/GrProgramInfo.h
+++ b/src/gpu/GrProgramInfo.h
@@ -13,6 +13,7 @@
#include "src/gpu/GrPrimitiveProcessor.h"
class GrMesh;
+class GrStencilSettings;
class GrProgramInfo {
public:
@@ -93,6 +94,10 @@
GrPrimitiveType primitiveType() const { return fPrimitiveType; }
+ // For Dawn, Metal and Vulkan the number of stencil bits is known a priori so we can
+ // create the stencil settings here.
+ GrStencilSettings nonGLStencilSettings() const;
+
#ifdef SK_DEBUG
void validate() const;
void checkAllInstantiated() const;
diff --git a/src/gpu/dawn/GrDawnGpu.cpp b/src/gpu/dawn/GrDawnGpu.cpp
index ab859b2..7dd5db3 100644
--- a/src/gpu/dawn/GrDawnGpu.cpp
+++ b/src/gpu/dawn/GrDawnGpu.cpp
@@ -95,13 +95,12 @@
}
GrProcessorKeyBuilder b(&desc->key());
- GrStencilSettings stencil;
- const GrPipeline& pipeline = programInfo.pipeline();
- stencil.reset(*pipeline.getUserStencil(), pipeline.hasStencilClip(), 8);
+ GrStencilSettings stencil = programInfo.nonGLStencilSettings();
stencil.genKey(&b);
+
b.add32(rt->config());
b.add32(static_cast<int32_t>(hasDepthStencil));
- b.add32(get_blend_info_key(pipeline));
+ b.add32(get_blend_info_key(programInfo.pipeline()));
b.add32(static_cast<uint32_t>(programInfo.primitiveType()));
return true;
}
diff --git a/src/gpu/dawn/GrDawnProgramBuilder.cpp b/src/gpu/dawn/GrDawnProgramBuilder.cpp
index 6b73b1a..c493d72 100644
--- a/src/gpu/dawn/GrDawnProgramBuilder.cpp
+++ b/src/gpu/dawn/GrDawnProgramBuilder.cpp
@@ -236,9 +236,11 @@
}
static wgpu::DepthStencilStateDescriptor create_depth_stencil_state(
- const GrStencilSettings& stencilSettings,
- wgpu::TextureFormat depthStencilFormat,
- GrSurfaceOrigin origin) {
+ const GrProgramInfo& programInfo,
+ wgpu::TextureFormat depthStencilFormat) {
+ GrStencilSettings stencilSettings = programInfo.nonGLStencilSettings();
+ GrSurfaceOrigin origin = programInfo.origin();
+
wgpu::DepthStencilStateDescriptor state;
state.format = depthStencilFormat;
if (!stencilSettings.isDisabled()) {
@@ -352,13 +354,13 @@
const GrPipeline& pipeline = programInfo.pipeline();
auto colorState = create_color_state(gpu, pipeline, colorFormat);
wgpu::DepthStencilStateDescriptor depthStencilState;
- GrStencilSettings stencil;
+
+#ifdef SK_DEBUG
if (pipeline.isStencilEnabled()) {
- int numStencilBits = renderTarget->renderTargetPriv().numStencilBits();
- stencil.reset(*pipeline.getUserStencil(), pipeline.hasStencilClip(), numStencilBits);
+ SkASSERT(renderTarget->renderTargetPriv().numStencilBits() == 8);
}
- depthStencilState = create_depth_stencil_state(stencil, depthStencilFormat,
- programInfo.origin());
+#endif
+ depthStencilState = create_depth_stencil_state(programInfo, depthStencilFormat);
std::vector<wgpu::VertexBufferLayoutDescriptor> inputs;
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index 1b388c4..d2e4aa9 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -1679,7 +1679,6 @@
GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(renderTarget);
GrStencilSettings stencil;
if (programInfo.pipeline().isStencilEnabled()) {
- // TODO: attach stencil and create settings during render target flush.
SkASSERT(glRT->renderTargetPriv().getStencilAttachment());
stencil.reset(*programInfo.pipeline().getUserStencil(),
programInfo.pipeline().hasStencilClip(),
diff --git a/src/gpu/mtl/GrMtlPipelineState.mm b/src/gpu/mtl/GrMtlPipelineState.mm
index 0533610..fadaf4e 100644
--- a/src/gpu/mtl/GrMtlPipelineState.mm
+++ b/src/gpu/mtl/GrMtlPipelineState.mm
@@ -106,12 +106,14 @@
SkASSERT(fNumSamplers == fSamplerBindings.count());
fDataManager.resetDirtyBits();
+#ifdef SK_DEBUG
if (programInfo.pipeline().isStencilEnabled()) {
SkASSERT(renderTarget->renderTargetPriv().getStencilAttachment());
- fStencil.reset(*programInfo.pipeline().getUserStencil(),
- programInfo.pipeline().hasStencilClip(),
- renderTarget->renderTargetPriv().numStencilBits());
+ SkASSERT(renderTarget->renderTargetPriv().numStencilBits() == 8);
}
+#endif
+
+ fStencil = programInfo.nonGLStencilSettings();
}
void GrMtlPipelineState::setDrawState(id<MTLRenderCommandEncoder> renderCmdEncoder,
diff --git a/src/gpu/vk/GrVkPipeline.cpp b/src/gpu/vk/GrVkPipeline.cpp
index da2765c..1b0bcae 100644
--- a/src/gpu/vk/GrVkPipeline.cpp
+++ b/src/gpu/vk/GrVkPipeline.cpp
@@ -238,8 +238,11 @@
}
static void setup_depth_stencil_state(
- const GrStencilSettings& stencilSettings, GrSurfaceOrigin origin,
+ const GrProgramInfo& programInfo,
VkPipelineDepthStencilStateCreateInfo* stencilInfo) {
+ GrStencilSettings stencilSettings = programInfo.nonGLStencilSettings();
+ GrSurfaceOrigin origin = programInfo.origin();
+
memset(stencilInfo, 0, sizeof(VkPipelineDepthStencilStateCreateInfo));
stencilInfo->sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
stencilInfo->pNext = nullptr;
@@ -521,7 +524,6 @@
GrVkPipeline* GrVkPipeline::Create(
GrVkGpu* gpu,
const GrProgramInfo& programInfo,
- const GrStencilSettings& stencil,
VkPipelineShaderStageCreateInfo* shaderStageInfo, int shaderStageCount,
VkRenderPass compatibleRenderPass, VkPipelineLayout layout,
VkPipelineCache cache) {
@@ -538,7 +540,7 @@
setup_input_assembly_state(programInfo.primitiveType(), &inputAssemblyInfo);
VkPipelineDepthStencilStateCreateInfo depthStencilInfo;
- setup_depth_stencil_state(stencil, programInfo.origin(), &depthStencilInfo);
+ setup_depth_stencil_state(programInfo, &depthStencilInfo);
VkPipelineViewportStateCreateInfo viewportInfo;
setup_viewport_scissor_state(&viewportInfo);
diff --git a/src/gpu/vk/GrVkPipeline.h b/src/gpu/vk/GrVkPipeline.h
index fe0d283..34b835b 100644
--- a/src/gpu/vk/GrVkPipeline.h
+++ b/src/gpu/vk/GrVkPipeline.h
@@ -26,7 +26,6 @@
public:
static GrVkPipeline* Create(GrVkGpu*,
const GrProgramInfo&,
- const GrStencilSettings&,
VkPipelineShaderStageCreateInfo* shaderStageInfo,
int shaderStageCount,
VkRenderPass compatibleRenderPass,
diff --git a/src/gpu/vk/GrVkPipelineStateBuilder.cpp b/src/gpu/vk/GrVkPipelineStateBuilder.cpp
index e61c78e..935e7c6 100644
--- a/src/gpu/vk/GrVkPipelineStateBuilder.cpp
+++ b/src/gpu/vk/GrVkPipelineStateBuilder.cpp
@@ -24,7 +24,6 @@
GrVkGpu* gpu,
GrRenderTarget* renderTarget,
const GrProgramInfo& programInfo,
- const GrStencilSettings& stencil,
Desc* desc,
VkRenderPass compatibleRenderPass) {
// ensure that we use "." as a decimal separator when creating SkSL code
@@ -38,7 +37,7 @@
return nullptr;
}
- return builder.finalize(stencil, compatibleRenderPass, desc);
+ return builder.finalize(compatibleRenderPass, desc);
}
GrVkPipelineStateBuilder::GrVkPipelineStateBuilder(GrVkGpu* gpu,
@@ -147,8 +146,7 @@
this->gpu()->getContext()->priv().getPersistentCache()->store(*key, *data);
}
-GrVkPipelineState* GrVkPipelineStateBuilder::finalize(const GrStencilSettings& stencil,
- VkRenderPass compatibleRenderPass,
+GrVkPipelineState* GrVkPipelineStateBuilder::finalize(VkRenderPass compatibleRenderPass,
Desc* desc) {
VkDescriptorSetLayout dsLayout[2];
VkPipelineLayout pipelineLayout;
@@ -291,8 +289,10 @@
this->storeShadersInCache(shaders, inputs, isSkSL);
}
}
- GrVkPipeline* pipeline = resourceProvider.createPipeline(fProgramInfo, stencil,
- shaderStageInfo, numShaderStages, compatibleRenderPass, pipelineLayout);
+
+ GrVkPipeline* pipeline = resourceProvider.createPipeline(fProgramInfo, shaderStageInfo,
+ numShaderStages, compatibleRenderPass,
+ pipelineLayout);
for (int i = 0; i < kGrShaderTypeCount; ++i) {
// This if check should not be needed since calling destroy on a VK_NULL_HANDLE is allowed.
// However this is causing a crash in certain drivers (e.g. NVidia).
@@ -326,7 +326,6 @@
bool GrVkPipelineStateBuilder::Desc::Build(Desc* desc,
GrRenderTarget* renderTarget,
const GrProgramInfo& programInfo,
- const GrStencilSettings& stencil,
const GrCaps& caps) {
if (!GrProgramDesc::Build(desc, renderTarget, programInfo, caps)) {
return false;
@@ -344,6 +343,7 @@
SkASSERT(vkRT->getSimpleRenderPass());
vkRT->getSimpleRenderPass()->genKey(&b);
+ GrStencilSettings stencil = programInfo.nonGLStencilSettings();
stencil.genKey(&b);
programInfo.pipeline().genKey(&b, caps);
diff --git a/src/gpu/vk/GrVkPipelineStateBuilder.h b/src/gpu/vk/GrVkPipelineStateBuilder.h
index 58891a9..d3c7fbd 100644
--- a/src/gpu/vk/GrVkPipelineStateBuilder.h
+++ b/src/gpu/vk/GrVkPipelineStateBuilder.h
@@ -38,11 +38,7 @@
*/
class Desc : public GrProgramDesc {
public:
- static bool Build(Desc*,
- GrRenderTarget*,
- const GrProgramInfo&,
- const GrStencilSettings&,
- const GrCaps& caps);
+ static bool Build(Desc*, GrRenderTarget*, const GrProgramInfo&, const GrCaps&);
size_t shaderKeyLength() const { return fShaderKeyLength; }
@@ -63,7 +59,6 @@
static GrVkPipelineState* CreatePipelineState(GrVkGpu*,
GrRenderTarget*,
const GrProgramInfo&,
- const GrStencilSettings&,
Desc*,
VkRenderPass compatibleRenderPass);
@@ -77,9 +72,7 @@
private:
GrVkPipelineStateBuilder(GrVkGpu*, GrRenderTarget*, const GrProgramInfo&, GrProgramDesc*);
- GrVkPipelineState* finalize(const GrStencilSettings&,
- VkRenderPass compatibleRenderPass,
- Desc*);
+ GrVkPipelineState* finalize(VkRenderPass compatibleRenderPass, Desc*);
// returns number of shader stages
int loadShadersFromCache(SkReader32* cached, VkShaderModule outShaderModules[],
diff --git a/src/gpu/vk/GrVkPipelineStateCache.cpp b/src/gpu/vk/GrVkPipelineStateCache.cpp
index 40882af..4e7d3b16 100644
--- a/src/gpu/vk/GrVkPipelineStateCache.cpp
+++ b/src/gpu/vk/GrVkPipelineStateCache.cpp
@@ -83,20 +83,18 @@
#ifdef GR_PIPELINE_STATE_CACHE_STATS
++fTotalRequests;
#endif
- GrStencilSettings stencil;
+
+#ifdef SK_DEBUG
if (programInfo.pipeline().isStencilEnabled()) {
- // TODO: attach stencil and create settings during render target flush.
SkASSERT(renderTarget->renderTargetPriv().getStencilAttachment());
- stencil.reset(*programInfo.pipeline().getUserStencil(),
- programInfo.pipeline().hasStencilClip(),
- renderTarget->renderTargetPriv().numStencilBits());
+ SkASSERT(renderTarget->renderTargetPriv().numStencilBits() == 8);
}
+#endif
// TODO: can this be unified between GL, Vk and Mtl?
// Get GrVkProgramDesc
GrVkPipelineStateBuilder::Desc desc;
- if (!GrVkPipelineStateBuilder::Desc::Build(&desc, renderTarget, programInfo, stencil,
- *fGpu->caps())) {
+ if (!GrVkPipelineStateBuilder::Desc::Build(&desc, renderTarget, programInfo, *fGpu->caps())) {
GrCapsDebugf(fGpu->caps(), "Failed to build vk program descriptor!\n");
return nullptr;
}
@@ -107,7 +105,7 @@
++fCacheMisses;
#endif
GrVkPipelineState* pipelineState(GrVkPipelineStateBuilder::CreatePipelineState(
- fGpu, renderTarget, programInfo, stencil, &desc, compatibleRenderPass));
+ fGpu, renderTarget, programInfo, &desc, compatibleRenderPass));
if (!pipelineState) {
return nullptr;
}
diff --git a/src/gpu/vk/GrVkResourceProvider.cpp b/src/gpu/vk/GrVkResourceProvider.cpp
index 73204c5..dbb6161 100644
--- a/src/gpu/vk/GrVkResourceProvider.cpp
+++ b/src/gpu/vk/GrVkResourceProvider.cpp
@@ -92,12 +92,11 @@
}
GrVkPipeline* GrVkResourceProvider::createPipeline(const GrProgramInfo& programInfo,
- const GrStencilSettings& stencil,
VkPipelineShaderStageCreateInfo* shaderStageInfo,
int shaderStageCount,
VkRenderPass compatibleRenderPass,
VkPipelineLayout layout) {
- return GrVkPipeline::Create(fGpu, programInfo, stencil, shaderStageInfo,
+ return GrVkPipeline::Create(fGpu, programInfo, shaderStageInfo,
shaderStageCount, compatibleRenderPass, layout,
this->pipelineCache());
}
diff --git a/src/gpu/vk/GrVkResourceProvider.h b/src/gpu/vk/GrVkResourceProvider.h
index 32baa60..ea919c9 100644
--- a/src/gpu/vk/GrVkResourceProvider.h
+++ b/src/gpu/vk/GrVkResourceProvider.h
@@ -44,7 +44,6 @@
void init();
GrVkPipeline* createPipeline(const GrProgramInfo&,
- const GrStencilSettings& stencil,
VkPipelineShaderStageCreateInfo* shaderStageInfo,
int shaderStageCount,
VkRenderPass compatibleRenderPass,