aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu
diff options
context:
space:
mode:
authorGravatar csmartdalton <csmartdalton@google.com>2016-11-21 11:55:00 -0700
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2016-11-21 19:29:40 +0000
commit276cc4113a6440b842c0dacb6d668ee3b45a3b7d (patch)
tree0bc4552177f1180abc734095d9a23d1f17c2d475 /src/gpu
parent99938a8ef24e2dd5b39f78638742e9b50ab6d9bf (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.cpp11
-rw-r--r--src/gpu/gl/builders/GrGLShaderStringBuilder.cpp38
-rw-r--r--src/gpu/glsl/GrGLSLGeometryShaderBuilder.cpp39
-rw-r--r--src/gpu/glsl/GrGLSLGeometryShaderBuilder.h18
-rw-r--r--src/gpu/glsl/GrGLSLPrimitiveProcessor.h4
-rw-r--r--src/gpu/glsl/GrGLSLProgramBuilder.cpp7
-rw-r--r--src/gpu/glsl/GrGLSLShaderBuilder.cpp4
-rw-r--r--src/gpu/glsl/GrGLSLShaderBuilder.h1
-rw-r--r--src/gpu/glsl/GrGLSLVarying.cpp6
-rw-r--r--src/gpu/vk/GrVkPipelineStateBuilder.cpp3
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,