Dawn: Implement RenderPipeline caching (optimization).
Implement RenderPipeline caching. This moves creation of all pipeline-
related objects from GrDawnGpuCommandBuffer.cpp to GrDawnProgramBuilder.
Change-Id: I42797750877b655ee19347406946302b296f3758
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/236917
Commit-Queue: Stephen White <senorblanco@chromium.org>
Reviewed-by: Greg Daniel <egdaniel@google.com>
diff --git a/src/gpu/dawn/GrDawnProgramBuilder.cpp b/src/gpu/dawn/GrDawnProgramBuilder.cpp
index db51fce..9d68b77 100644
--- a/src/gpu/dawn/GrDawnProgramBuilder.cpp
+++ b/src/gpu/dawn/GrDawnProgramBuilder.cpp
@@ -180,6 +180,51 @@
return dawn::AddressMode::ClampToEdge;
}
+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;
+ }
+}
+
+static dawn::VertexFormat to_dawn_vertex_format(GrVertexAttribType type) {
+ switch (type) {
+ case kFloat_GrVertexAttribType:
+ case kHalf_GrVertexAttribType:
+ return dawn::VertexFormat::Float;
+ case kFloat2_GrVertexAttribType:
+ case kHalf2_GrVertexAttribType:
+ return dawn::VertexFormat::Float2;
+ case kFloat3_GrVertexAttribType:
+ case kHalf3_GrVertexAttribType:
+ return dawn::VertexFormat::Float3;
+ case kFloat4_GrVertexAttribType:
+ case kHalf4_GrVertexAttribType:
+ return dawn::VertexFormat::Float4;
+ case kUShort2_GrVertexAttribType:
+ return dawn::VertexFormat::UShort2;
+ case kInt_GrVertexAttribType:
+ return dawn::VertexFormat::Int;
+ case kUByte4_norm_GrVertexAttribType:
+ return dawn::VertexFormat::UChar4Norm;
+ default:
+ SkASSERT(!"unsupported vertex format");
+ return dawn::VertexFormat::Float4;
+ }
+}
+
static dawn::ColorStateDescriptor create_color_state(const GrDawnGpu* gpu,
const GrPipeline& pipeline,
dawn::TextureFormat colorFormat) {
@@ -222,17 +267,7 @@
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 {
+ if (!stencilSettings.isDisabled()) {
const GrStencilSettings::Face& front = stencilSettings.front(origin);
state.stencilReadMask = front.fTestMask;
state.stencilWriteMask = front.fWriteMask;
@@ -294,6 +329,7 @@
const GrPipeline& pipeline,
const GrPrimitiveProcessor& primProc,
const GrTextureProxy* const primProcProxies[],
+ GrPrimitiveType primitiveType,
dawn::TextureFormat colorFormat,
bool hasDepthStencil,
dawn::TextureFormat depthStencilFormat,
@@ -317,16 +353,15 @@
uint32_t fragmentUniformSize = builder.fUniformHandler.fCurrentFragmentUBOOffset;
sk_sp<GrDawnProgram> result(
new GrDawnProgram(uniforms, geometryUniformSize, fragmentUniformSize));
- result->fVSModule = builder.createShaderModule(builder.fVS, SkSL::Program::kVertex_Kind,
- &vertInputs);
- result->fFSModule = builder.createShaderModule(builder.fFS, SkSL::Program::kFragment_Kind,
- &fragInputs);
+ auto vsModule = builder.createShaderModule(builder.fVS, SkSL::Program::kVertex_Kind,
+ &vertInputs);
+ auto fsModule = builder.createShaderModule(builder.fFS, SkSL::Program::kFragment_Kind,
+ &fragInputs);
result->fGeometryProcessor = std::move(builder.fGeometryProcessor);
result->fXferProcessor = std::move(builder.fXferProcessor);
result->fFragmentProcessors = std::move(builder.fFragmentProcessors);
result->fFragmentProcessorCnt = builder.fFragmentProcessorCnt;
std::vector<dawn::BindGroupLayoutBinding> layoutBindings;
- std::vector<dawn::BindGroupBinding> bindings;
if (0 != geometryUniformSize) {
layoutBindings.push_back({ GrDawnUniformHandler::kGeometryBinding,
dawn::ShaderStageBit::Vertex,
@@ -351,15 +386,85 @@
dawn::PipelineLayoutDescriptor pipelineLayoutDesc;
pipelineLayoutDesc.bindGroupLayoutCount = 1;
pipelineLayoutDesc.bindGroupLayouts = &result->fBindGroupLayout;
- result->fPipelineLayout = gpu->device().CreatePipelineLayout(&pipelineLayoutDesc);
+ auto pipelineLayout = gpu->device().CreatePipelineLayout(&pipelineLayoutDesc);
result->fBuiltinUniformHandles = builder.fUniformHandles;
- result->fColorState = create_color_state(gpu, pipeline, colorFormat);
+ auto colorState = create_color_state(gpu, pipeline, colorFormat);
+ dawn::DepthStencilStateDescriptor depthStencilState;
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);
+ depthStencilState = create_depth_stencil_state(stencil, depthStencilFormat, origin);
+
+ std::vector<dawn::VertexBufferDescriptor> inputs;
+
+ std::vector<dawn::VertexAttributeDescriptor> vertexAttributes;
+ if (primProc.numVertexAttributes() > 0) {
+ size_t offset = 0;
+ int i = 0;
+ for (const auto& attrib : primProc.vertexAttributes()) {
+ dawn::VertexAttributeDescriptor attribute;
+ attribute.shaderLocation = i;
+ attribute.offset = offset;
+ attribute.format = to_dawn_vertex_format(attrib.cpuType());
+ vertexAttributes.push_back(attribute);
+ offset += attrib.sizeAlign4();
+ i++;
+ }
+ dawn::VertexBufferDescriptor input;
+ input.stride = offset;
+ input.stepMode = dawn::InputStepMode::Vertex;
+ input.attributeCount = vertexAttributes.size();
+ input.attributes = &vertexAttributes.front();
+ inputs.push_back(input);
+ }
+ std::vector<dawn::VertexAttributeDescriptor> instanceAttributes;
+ if (primProc.numInstanceAttributes() > 0) {
+ size_t offset = 0;
+ int i = 0;
+ for (const auto& attrib : primProc.instanceAttributes()) {
+ dawn::VertexAttributeDescriptor attribute;
+ attribute.shaderLocation = i;
+ attribute.offset = offset;
+ attribute.format = to_dawn_vertex_format(attrib.cpuType());
+ instanceAttributes.push_back(attribute);
+ offset += attrib.sizeAlign4();
+ i++;
+ }
+ dawn::VertexBufferDescriptor input;
+ input.stride = offset;
+ input.stepMode = dawn::InputStepMode::Instance;
+ input.attributeCount = instanceAttributes.size();
+ input.attributes = &instanceAttributes.front();
+ inputs.push_back(input);
+ }
+ dawn::VertexInputDescriptor vertexInput;
+ vertexInput.indexFormat = dawn::IndexFormat::Uint16;
+ vertexInput.bufferCount = inputs.size();
+ vertexInput.buffers = &inputs.front();
+
+ dawn::PipelineStageDescriptor vsDesc;
+ vsDesc.module = vsModule;
+ vsDesc.entryPoint = "main";
+
+ dawn::PipelineStageDescriptor fsDesc;
+ fsDesc.module = fsModule;
+ fsDesc.entryPoint = "main";
+
+ dawn::RenderPipelineDescriptor rpDesc;
+ rpDesc.layout = pipelineLayout;
+ rpDesc.vertexStage = &vsDesc;
+ rpDesc.fragmentStage = &fsDesc;
+ rpDesc.vertexInput = &vertexInput;
+ rpDesc.primitiveTopology = to_dawn_primitive_topology(primitiveType);
+ if (hasDepthStencil) {
+ rpDesc.depthStencilState = &depthStencilState;
+ }
+ rpDesc.colorStateCount = 1;
+ dawn::ColorStateDescriptor* colorStatesPtr[] = { &colorState };
+ rpDesc.colorStates = colorStatesPtr;
+ result->fRenderPipeline = gpu->device().CreateRenderPipeline(&rpDesc);
return result;
}