diff options
author | csmartdalton <csmartdalton@google.com> | 2016-11-21 11:55:00 -0700 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2016-11-21 19:29:40 +0000 |
commit | 276cc4113a6440b842c0dacb6d668ee3b45a3b7d (patch) | |
tree | 0bc4552177f1180abc734095d9a23d1f17c2d475 /src/gpu | |
parent | 99938a8ef24e2dd5b39f78638742e9b50ab6d9bf (diff) |
Revive geometry shaders
Fixes the bit rot that has set in for geometry shaders. They're to a
point now that we can use them again for GL experiments. Since SkSL
does not support geometry shaders yet, we pass the shader string
directly to the GL compiler for now.
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=5080
Change-Id: Ie3864e5559c810c682cf5f1709bdab87f033c43b
Reviewed-on: https://skia-review.googlesource.com/5080
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Chris Dalton <csmartdalton@google.com>
Diffstat (limited to 'src/gpu')
-rw-r--r-- | src/gpu/gl/builders/GrGLProgramBuilder.cpp | 11 | ||||
-rw-r--r-- | src/gpu/gl/builders/GrGLShaderStringBuilder.cpp | 38 | ||||
-rw-r--r-- | src/gpu/glsl/GrGLSLGeometryShaderBuilder.cpp | 39 | ||||
-rw-r--r-- | src/gpu/glsl/GrGLSLGeometryShaderBuilder.h | 18 | ||||
-rw-r--r-- | src/gpu/glsl/GrGLSLPrimitiveProcessor.h | 4 | ||||
-rw-r--r-- | src/gpu/glsl/GrGLSLProgramBuilder.cpp | 7 | ||||
-rw-r--r-- | src/gpu/glsl/GrGLSLShaderBuilder.cpp | 4 | ||||
-rw-r--r-- | src/gpu/glsl/GrGLSLShaderBuilder.h | 1 | ||||
-rw-r--r-- | src/gpu/glsl/GrGLSLVarying.cpp | 6 | ||||
-rw-r--r-- | src/gpu/vk/GrVkPipelineStateBuilder.cpp | 3 |
10 files changed, 107 insertions, 24 deletions
diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.cpp b/src/gpu/gl/builders/GrGLProgramBuilder.cpp index e951c6bcf9..a1ad572a86 100644 --- a/src/gpu/gl/builders/GrGLProgramBuilder.cpp +++ b/src/gpu/gl/builders/GrGLProgramBuilder.cpp @@ -111,16 +111,21 @@ GrGLProgram* GrGLProgramBuilder::finalize() { } // NVPR actually requires a vertex shader to compile - bool useNvpr = primitiveProcessor().isPathRendering(); + const GrPrimitiveProcessor& primProc = this->primitiveProcessor(); + bool useNvpr = primProc.isPathRendering(); if (!useNvpr) { - const GrPrimitiveProcessor& primProc = this->primitiveProcessor(); - int vaCount = primProc.numAttribs(); for (int i = 0; i < vaCount; i++) { GL_CALL(BindAttribLocation(programID, i, primProc.getAttrib(i).fName)); } } + if (primProc.willUseGeoShader() && + !this->compileAndAttachShaders(fGS, programID, GR_GL_GEOMETRY_SHADER, &shadersToDelete)) { + this->cleanupProgram(programID, shadersToDelete); + return nullptr; + } + if (!this->compileAndAttachShaders(fFS, programID, GR_GL_FRAGMENT_SHADER, &shadersToDelete)) { this->cleanupProgram(programID, shadersToDelete); return nullptr; diff --git a/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp b/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp index 86df089d82..81115c5522 100644 --- a/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp +++ b/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp @@ -63,23 +63,28 @@ GrGLuint GrGLCompileAndAttachShader(const GrGLContext& glCtx, #endif SkString glsl; - SkSL::Compiler& compiler = *glCtx.compiler(); - SkASSERT(type == GR_GL_VERTEX_SHADER || type == GR_GL_FRAGMENT_SHADER); - SkDEBUGCODE(bool result = )compiler.toGLSL(type == GR_GL_VERTEX_SHADER + if (type == GR_GL_VERTEX_SHADER || type == GR_GL_FRAGMENT_SHADER) { + SkSL::Compiler& compiler = *glCtx.compiler(); + SkDEBUGCODE(bool result = )compiler.toGLSL(type == GR_GL_VERTEX_SHADER ? SkSL::Program::kVertex_Kind : SkSL::Program::kFragment_Kind, - sksl, - *glCtx.caps()->glslCaps(), - &glsl); + sksl, + *glCtx.caps()->glslCaps(), + &glsl); #ifdef SK_DEBUG - if (!result) { - SkDebugf("SKSL compilation error\n----------------------\n"); - SkDebugf("SKSL:\n"); - dump_string(sksl); - SkDebugf("\nErrors:\n%s\n", compiler.errorText().c_str()); - SkDEBUGFAIL("SKSL compilation failed!\n"); - } + if (!result) { + SkDebugf("SKSL compilation error\n----------------------\n"); + SkDebugf("SKSL:\n"); + dump_string(sksl); + SkDebugf("\nErrors:\n%s\n", compiler.errorText().c_str()); + SkDEBUGFAIL("SKSL compilation failed!\n"); + } #endif + } else { + // TODO: geometry shader support in sksl. + SkASSERT(type == GR_GL_GEOMETRY_SHADER); + glsl = sksl; + } const char* glslChars = glsl.c_str(); GrGLint glslLength = (GrGLint) glsl.size(); @@ -129,6 +134,13 @@ GrGLuint GrGLCompileAndAttachShader(const GrGLContext& glCtx, } if (c_PrintShaders) { + const char* typeName = "Unknown"; + switch (type) { + case GR_GL_VERTEX_SHADER: typeName = "Vertex"; break; + case GR_GL_GEOMETRY_SHADER: typeName = "Geometry"; break; + case GR_GL_FRAGMENT_SHADER: typeName = "Fragment"; break; + } + SkDebugf("---- %s shader ----------------------------------------------------\n", typeName); print_shader_source(strings, lengths, count); } diff --git a/src/gpu/glsl/GrGLSLGeometryShaderBuilder.cpp b/src/gpu/glsl/GrGLSLGeometryShaderBuilder.cpp index eddd69f7cd..a8e746cf0a 100644 --- a/src/gpu/glsl/GrGLSLGeometryShaderBuilder.cpp +++ b/src/gpu/glsl/GrGLSLGeometryShaderBuilder.cpp @@ -9,11 +9,48 @@ #include "GrGLSLProgramBuilder.h" #include "GrGLSLVarying.h" +static const char* input_type_name(GrGLSLGeometryBuilder::InputType in) { + using InputType = GrGLSLGeometryBuilder::InputType; + switch (in) { + case InputType::kPoints: return "points"; + case InputType::kLines: return "lines"; + case InputType::kLinesAdjacency: return "lines_adjacency"; + case InputType::kTriangles: return "triangles"; + case InputType::kTrianglesAdjacency: return "triangles_adjacency"; + } + SkFAIL("invalid input type"); + return "unknown_input"; +} + +static const char* output_type_name(GrGLSLGeometryBuilder::OutputType out) { + using OutputType = GrGLSLGeometryBuilder::OutputType; + switch (out) { + case OutputType::kPoints: return "points"; + case OutputType::kLineStrip: return "line_strip"; + case OutputType::kTriangleStrip: return "triangle_strip"; + } + SkFAIL("invalid output type"); + return "unknown_output"; +} + GrGLSLGeometryBuilder::GrGLSLGeometryBuilder(GrGLSLProgramBuilder* program) - : INHERITED(program) { + : INHERITED(program) + , fIsConfigured(false) { +} +void GrGLSLGeometryBuilder::configure(InputType inputType, OutputType outputType, int maxVertices, + int numInvocations) { + SkASSERT(!fIsConfigured); + this->addLayoutQualifier(input_type_name(inputType), kIn_InterfaceQualifier); + this->addLayoutQualifier(SkStringPrintf("invocations = %i", numInvocations).c_str(), + kIn_InterfaceQualifier); + this->addLayoutQualifier(output_type_name(outputType), kOut_InterfaceQualifier); + this->addLayoutQualifier(SkStringPrintf("max_vertices = %i", maxVertices).c_str(), + kOut_InterfaceQualifier); + fIsConfigured = true; } void GrGLSLGeometryBuilder::onFinalize() { + SkASSERT(fIsConfigured); fProgramBuilder->varyingHandler()->getGeomDecls(&this->inputs(), &this->outputs()); } diff --git a/src/gpu/glsl/GrGLSLGeometryShaderBuilder.h b/src/gpu/glsl/GrGLSLGeometryShaderBuilder.h index f5e09f11a2..feedcf2930 100644 --- a/src/gpu/glsl/GrGLSLGeometryShaderBuilder.h +++ b/src/gpu/glsl/GrGLSLGeometryShaderBuilder.h @@ -16,9 +16,27 @@ class GrGLSLGeometryBuilder : public GrGLSLShaderBuilder { public: GrGLSLGeometryBuilder(GrGLSLProgramBuilder* program); + enum class InputType { + kPoints, + kLines, + kLinesAdjacency, + kTriangles, + kTrianglesAdjacency + }; + + enum class OutputType { + kPoints, + kLineStrip, + kTriangleStrip + }; + + void configure(InputType, OutputType, int maxVertices, int numInvocations = 1); + private: void onFinalize() override; + bool fIsConfigured; + friend class GrGLProgramBuilder; typedef GrGLSLShaderBuilder INHERITED; diff --git a/src/gpu/glsl/GrGLSLPrimitiveProcessor.h b/src/gpu/glsl/GrGLSLPrimitiveProcessor.h index fd77bdd42a..199163939f 100644 --- a/src/gpu/glsl/GrGLSLPrimitiveProcessor.h +++ b/src/gpu/glsl/GrGLSLPrimitiveProcessor.h @@ -16,6 +16,7 @@ class GrBatchTracker; class GrPrimitiveProcessor; class GrGLSLCaps; class GrGLSLPPFragmentBuilder; +class GrGLSLGeometryBuilder; class GrGLSLGPBuilder; class GrGLSLUniformHandler; class GrGLSLVaryingHandler; @@ -65,6 +66,7 @@ public: struct EmitArgs { EmitArgs(GrGLSLVertexBuilder* vertBuilder, + GrGLSLGeometryBuilder* geomBuilder, GrGLSLPPFragmentBuilder* fragBuilder, GrGLSLVaryingHandler* varyingHandler, GrGLSLUniformHandler* uniformHandler, @@ -77,6 +79,7 @@ public: const SamplerHandle* bufferSamplers, FPCoordTransformHandler* transformHandler) : fVertBuilder(vertBuilder) + , fGeomBuilder(geomBuilder) , fFragBuilder(fragBuilder) , fVaryingHandler(varyingHandler) , fUniformHandler(uniformHandler) @@ -89,6 +92,7 @@ public: , fBufferSamplers(bufferSamplers) , fFPCoordTransformHandler(transformHandler) {} GrGLSLVertexBuilder* fVertBuilder; + GrGLSLGeometryBuilder* fGeomBuilder; GrGLSLPPFragmentBuilder* fFragBuilder; GrGLSLVaryingHandler* fVaryingHandler; GrGLSLUniformHandler* fUniformHandler; diff --git a/src/gpu/glsl/GrGLSLProgramBuilder.cpp b/src/gpu/glsl/GrGLSLProgramBuilder.cpp index 9da88ded18..e8097c783f 100644 --- a/src/gpu/glsl/GrGLSLProgramBuilder.cpp +++ b/src/gpu/glsl/GrGLSLProgramBuilder.cpp @@ -41,7 +41,7 @@ void GrGLSLProgramBuilder::addFeature(GrShaderFlags shaders, fVS.addFeature(featureBit, extensionName); } if (shaders & kGeometry_GrShaderFlag) { - SkASSERT(this->glslCaps()->geometryShaderSupport()); + SkASSERT(this->primitiveProcessor().willUseGeoShader()); fGS.addFeature(featureBit, extensionName); } if (shaders & kFragment_GrShaderFlag) { @@ -104,6 +104,7 @@ void GrGLSLProgramBuilder::emitAndInstallPrimProc(const GrPrimitiveProcessor& pr GrGLSLPrimitiveProcessor::FPCoordTransformHandler transformHandler(fPipeline, &fTransformedCoordVars); GrGLSLGeometryProcessor::EmitArgs args(&fVS, + proc.willUseGeoShader() ? &fGS : nullptr, &fFS, this->varyingHandler(), this->uniformHandler(), @@ -423,5 +424,9 @@ void GrGLSLProgramBuilder::cleanupFragmentProcessors() { void GrGLSLProgramBuilder::finalizeShaders() { this->varyingHandler()->finalize(); fVS.finalize(kVertex_GrShaderFlag); + if (this->primitiveProcessor().willUseGeoShader()) { + SkASSERT(this->glslCaps()->geometryShaderSupport()); + fGS.finalize(kGeometry_GrShaderFlag); + } fFS.finalize(kFragment_GrShaderFlag); } diff --git a/src/gpu/glsl/GrGLSLShaderBuilder.cpp b/src/gpu/glsl/GrGLSLShaderBuilder.cpp index 3836d6dbe4..eb4c7d4a22 100644 --- a/src/gpu/glsl/GrGLSLShaderBuilder.cpp +++ b/src/gpu/glsl/GrGLSLShaderBuilder.cpp @@ -199,6 +199,7 @@ void GrGLSLShaderBuilder::addLayoutQualifier(const char* param, InterfaceQualifi void GrGLSLShaderBuilder::compileAndAppendLayoutQualifiers() { static const char* interfaceQualifierNames[] = { + "in", "out" }; @@ -214,7 +215,8 @@ void GrGLSLShaderBuilder::compileAndAppendLayoutQualifiers() { this->layoutQualifiers().appendf(") %s;\n", interfaceQualifierNames[interface]); } - GR_STATIC_ASSERT(0 == GrGLSLShaderBuilder::kOut_InterfaceQualifier); + GR_STATIC_ASSERT(0 == GrGLSLShaderBuilder::kIn_InterfaceQualifier); + GR_STATIC_ASSERT(1 == GrGLSLShaderBuilder::kOut_InterfaceQualifier); GR_STATIC_ASSERT(SK_ARRAY_COUNT(interfaceQualifierNames) == kLastInterfaceQualifier + 1); } diff --git a/src/gpu/glsl/GrGLSLShaderBuilder.h b/src/gpu/glsl/GrGLSLShaderBuilder.h index 17eb5a63cf..6be69d4a2b 100644 --- a/src/gpu/glsl/GrGLSLShaderBuilder.h +++ b/src/gpu/glsl/GrGLSLShaderBuilder.h @@ -188,6 +188,7 @@ protected: bool addFeature(uint32_t featureBit, const char* extensionName); enum InterfaceQualifier { + kIn_InterfaceQualifier, kOut_InterfaceQualifier, kLastInterfaceQualifier = kOut_InterfaceQualifier }; diff --git a/src/gpu/glsl/GrGLSLVarying.cpp b/src/gpu/glsl/GrGLSLVarying.cpp index a3d50533cc..f264fc0921 100644 --- a/src/gpu/glsl/GrGLSLVarying.cpp +++ b/src/gpu/glsl/GrGLSLVarying.cpp @@ -28,12 +28,8 @@ void GrGLSLVaryingHandler::addFlatPassThroughAttribute(const GrGeometryProcessor void GrGLSLVaryingHandler::writePassThroughAttribute(const GrGeometryProcessor::Attribute* input, const char* output, const GrGLSLVarying& v) { + SkASSERT(!fProgramBuilder->primitiveProcessor().willUseGeoShader()); fProgramBuilder->fVS.codeAppendf("%s = %s;", v.vsOut(), input->fName); - - if (fProgramBuilder->primitiveProcessor().willUseGeoShader()) { - fProgramBuilder->fGS.codeAppendf("%s = %s[0];", v.gsOut(), v.gsIn()); - } - fProgramBuilder->fFS.codeAppendf("%s = %s;", output, v.fsIn()); } diff --git a/src/gpu/vk/GrVkPipelineStateBuilder.cpp b/src/gpu/vk/GrVkPipelineStateBuilder.cpp index e68159ddf0..725bc24641 100644 --- a/src/gpu/vk/GrVkPipelineStateBuilder.cpp +++ b/src/gpu/vk/GrVkPipelineStateBuilder.cpp @@ -126,6 +126,9 @@ GrVkPipelineState* GrVkPipelineStateBuilder::finalize(const GrStencilSettings& s &vertShaderModule, &shaderStageInfo[0])); + // TODO: geometry shader support. + SkASSERT(!this->primitiveProcessor().willUseGeoShader()); + SkAssertResult(CreateVkShaderModule(fGpu, VK_SHADER_STAGE_FRAGMENT_BIT, fFS, |