diff options
Diffstat (limited to 'src/gpu/glsl')
-rwxr-xr-x | src/gpu/glsl/GrGLSLCaps.cpp | 6 | ||||
-rwxr-xr-x | src/gpu/glsl/GrGLSLCaps.h | 12 | ||||
-rw-r--r-- | src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp | 2 | ||||
-rw-r--r-- | src/gpu/glsl/GrGLSLFragmentShaderBuilder.h | 16 | ||||
-rw-r--r-- | src/gpu/glsl/GrGLSLGeometryProcessor.cpp | 3 | ||||
-rw-r--r-- | src/gpu/glsl/GrGLSLShaderBuilder.h | 14 | ||||
-rw-r--r-- | src/gpu/glsl/GrGLSLShaderVar.h | 36 | ||||
-rw-r--r-- | src/gpu/glsl/GrGLSLVarying.cpp | 128 | ||||
-rw-r--r-- | src/gpu/glsl/GrGLSLVarying.h | 82 |
9 files changed, 205 insertions, 94 deletions
diff --git a/src/gpu/glsl/GrGLSLCaps.cpp b/src/gpu/glsl/GrGLSLCaps.cpp index c82d8333df..ba99be57e2 100755 --- a/src/gpu/glsl/GrGLSLCaps.cpp +++ b/src/gpu/glsl/GrGLSLCaps.cpp @@ -23,11 +23,14 @@ GrGLSLCaps::GrGLSLCaps(const GrContextOptions& options) { fCanUseAnyFunctionInShader = true; fCanUseMinAndAbsTogether = true; fMustForceNegatedAtanParamToFloat = false; + fFlatInterpolationSupport = false; + fNoPerspectiveInterpolationSupport = false; fVersionDeclString = nullptr; fShaderDerivativeExtensionString = nullptr; fFragCoordConventionsExtensionString = nullptr; fSecondaryOutputExtensionString = nullptr; fExternalTextureExtensionString = nullptr; + fNoPerspectiveInterpolationExtensionString = nullptr; fFBFetchColorName = nullptr; fFBFetchExtensionString = nullptr; fAdvBlendEqInteraction = kNotSupported_AdvBlendEqInteraction; @@ -58,6 +61,9 @@ SkString GrGLSLCaps::dump() const { r.appendf("Can use min() and abs() together: %s\n", (fCanUseMinAndAbsTogether ? "YES" : "NO")); r.appendf("Must force negated atan param to float: %s\n", (fMustForceNegatedAtanParamToFloat ? "YES" : "NO")); + r.appendf("Flat interpolation support: %s\n", (fFlatInterpolationSupport ? "YES" : "NO")); + r.appendf("No perspective interpolation support: %s\n", (fNoPerspectiveInterpolationSupport ? + "YES" : "NO")); r.appendf("Advanced blend equation interaction: %s\n", kAdvBlendEqInteractionStr[fAdvBlendEqInteraction]); return r; diff --git a/src/gpu/glsl/GrGLSLCaps.h b/src/gpu/glsl/GrGLSLCaps.h index 060539645e..2f87f66850 100755 --- a/src/gpu/glsl/GrGLSLCaps.h +++ b/src/gpu/glsl/GrGLSLCaps.h @@ -54,6 +54,10 @@ public: bool dropsTileOnZeroDivide() const { return fDropsTileOnZeroDivide; } + bool flatInterpolationSupport() const { return fFlatInterpolationSupport; } + + bool noperspectiveInterpolationSupport() const { return fNoPerspectiveInterpolationSupport; } + AdvBlendEqInteraction advBlendEqInteraction() const { return fAdvBlendEqInteraction; } bool mustEnableAdvBlendEqs() const { @@ -105,6 +109,11 @@ public: return fExternalTextureExtensionString; } + const char* noperspectiveInterpolationExtensionString() const { + SkASSERT(this->noperspectiveInterpolationSupport()); + return fNoPerspectiveInterpolationExtensionString; + } + /** * Given a texture's config, this determines what swizzle must be appended to accesses to the * texture in generated shader code. Swizzling may be implemented in texture parameters or a @@ -137,6 +146,8 @@ private: bool fBindlessTextureSupport : 1; bool fUsesPrecisionModifiers : 1; bool fCanUseAnyFunctionInShader : 1; + bool fFlatInterpolationSupport : 1; + bool fNoPerspectiveInterpolationSupport : 1; // Used for specific driver bug work arounds bool fCanUseMinAndAbsTogether : 1; @@ -148,6 +159,7 @@ private: const char* fFragCoordConventionsExtensionString; const char* fSecondaryOutputExtensionString; const char* fExternalTextureExtensionString; + const char* fNoPerspectiveInterpolationExtensionString; const char* fFBFetchColorName; const char* fFBFetchExtensionString; diff --git a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp index 7ec18a23e8..8651827841 100644 --- a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp +++ b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp @@ -176,7 +176,7 @@ const char* GrGLSLFragmentShaderBuilder::dstColor() { const GrGLSLCaps* glslCaps = fProgramBuilder->glslCaps(); if (glslCaps->fbFetchSupport()) { - this->addFeature(1 << (GrGLSLFragmentShaderBuilder::kLastGLSLPrivateFeature + 1), + this->addFeature(1 << kFramebufferFetch_GLSLPrivateFeature, glslCaps->fbFetchExtensionString()); // Some versions of this extension string require declaring custom color output on ES 3.0+ diff --git a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h index e998458158..a437a194ca 100644 --- a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h +++ b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h @@ -32,9 +32,8 @@ public: * if code is added that uses one of these features without calling enableFeature() */ enum GLSLFeature { - kStandardDerivatives_GLSLFeature = 0, - kPixelLocalStorage_GLSLFeature = 1, - kLastGLSLFeature = kPixelLocalStorage_GLSLFeature + kStandardDerivatives_GLSLFeature = kLastGLSLPrivateFeature + 1, + kPixelLocalStorage_GLSLFeature }; /** @@ -168,17 +167,6 @@ private: void onFinalize() override; - /** - * Features that should only be enabled by GrGLSLFragmentShaderBuilder itself. - */ - enum GLSLPrivateFeature { - kFragCoordConventions_GLSLPrivateFeature = kLastGLSLFeature + 1, - kBlendEquationAdvanced_GLSLPrivateFeature, - kBlendFuncExtended_GLSLPrivateFeature, - kExternalTexture_GLSLPrivateFeature, - kLastGLSLPrivateFeature = kBlendFuncExtended_GLSLPrivateFeature - }; - // Interpretation of FragPosKey when generating code enum { kNoFragPosRead_FragPosKey = 0, // The fragment positition will not be needed. diff --git a/src/gpu/glsl/GrGLSLGeometryProcessor.cpp b/src/gpu/glsl/GrGLSLGeometryProcessor.cpp index b8951be551..f7dba820a0 100644 --- a/src/gpu/glsl/GrGLSLGeometryProcessor.cpp +++ b/src/gpu/glsl/GrGLSLGeometryProcessor.cpp @@ -19,6 +19,9 @@ void GrGLSLGeometryProcessor::emitCode(EmitArgs& args) { GrGPArgs gpArgs; this->onEmitCode(args, &gpArgs); vBuilder->transformToNormalizedDeviceSpace(gpArgs.fPositionVar); + if (kVec2f_GrSLType == gpArgs.fPositionVar.getType()) { + args.fVaryingHandler->setNoPerspective(); + } } void GrGLSLGeometryProcessor::emitTransforms(GrGLSLVertexBuilder* vb, diff --git a/src/gpu/glsl/GrGLSLShaderBuilder.h b/src/gpu/glsl/GrGLSLShaderBuilder.h index 5c3408e704..bc3b4ca717 100644 --- a/src/gpu/glsl/GrGLSLShaderBuilder.h +++ b/src/gpu/glsl/GrGLSLShaderBuilder.h @@ -142,6 +142,19 @@ protected: typedef GrTAllocator<GrGLSLShaderVar> VarArray; void appendDecls(const VarArray& vars, SkString* out) const; + /** + * Features that should only be enabled internally by the builders. + */ + enum GLSLPrivateFeature { + kFragCoordConventions_GLSLPrivateFeature, + kBlendEquationAdvanced_GLSLPrivateFeature, + kBlendFuncExtended_GLSLPrivateFeature, + kExternalTexture_GLSLPrivateFeature, + kFramebufferFetch_GLSLPrivateFeature, + kNoPerspectiveInterpolation_GLSLPrivateFeature, + kLastGLSLPrivateFeature = kNoPerspectiveInterpolation_GLSLPrivateFeature + }; + /* * A general function which enables an extension in a shader if the feature bit is not present */ @@ -215,6 +228,7 @@ protected: friend class GrGLSLProgramBuilder; friend class GrGLProgramBuilder; + friend class GrGLSLVaryingHandler; // to access noperspective interpolation feature. friend class GrGLPathProgramBuilder; // to access fInputs. friend class GrVkProgramBuilder; }; diff --git a/src/gpu/glsl/GrGLSLShaderVar.h b/src/gpu/glsl/GrGLSLShaderVar.h index e26a75c096..bdd36f3763 100644 --- a/src/gpu/glsl/GrGLSLShaderVar.h +++ b/src/gpu/glsl/GrGLSLShaderVar.h @@ -51,7 +51,9 @@ public: GrGLSLShaderVar(const GrGLSLShaderVar& var) : GrShaderVar(var.c_str(), var.getType(), var.getTypeModifier(), var.getArrayCount(), var.getPrecision()) - , fUseUniformFloatArrays(var.fUseUniformFloatArrays) { + , fUseUniformFloatArrays(var.fUseUniformFloatArrays) + , fLayoutQualifier(var.fLayoutQualifier) + , fExtraModifiers(var.fExtraModifiers) { SkASSERT(kVoid_GrSLType != var.getType()); } @@ -71,11 +73,15 @@ public: const SkString& name, GrSLPrecision precision = kDefault_GrSLPrecision, const char* layoutQualifier = nullptr, + const char* extraModifiers = nullptr, bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) { SkASSERT(kVoid_GrSLType != type); SkASSERT(kDefault_GrSLPrecision == precision || GrSLTypeIsNumeric(type)); INHERITED::set(type, name, typeModifier, precision); fLayoutQualifier = layoutQualifier; + if (extraModifiers) { + fExtraModifiers.printf("%s ", extraModifiers); + } fUseUniformFloatArrays = useUniformFloatArrays; } @@ -87,11 +93,15 @@ public: const char* name, GrSLPrecision precision = kDefault_GrSLPrecision, const char* layoutQualifier = nullptr, + const char* extraModifiers = nullptr, bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) { SkASSERT(kVoid_GrSLType != type); SkASSERT(kDefault_GrSLPrecision == precision || GrSLTypeIsNumeric(type)); INHERITED::set(type, name, typeModifier, precision); fLayoutQualifier = layoutQualifier; + if (extraModifiers) { + fExtraModifiers.printf("%s ", extraModifiers); + } fUseUniformFloatArrays = useUniformFloatArrays; } @@ -104,11 +114,15 @@ public: int count, GrSLPrecision precision = kDefault_GrSLPrecision, const char* layoutQualifier = nullptr, + const char* extraModifiers = nullptr, bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) { SkASSERT(kVoid_GrSLType != type); SkASSERT(kDefault_GrSLPrecision == precision || GrSLTypeIsNumeric(type)); INHERITED::set(type, name, typeModifier, precision, count); fLayoutQualifier = layoutQualifier; + if (extraModifiers) { + fExtraModifiers.printf("%s ", extraModifiers); + } fUseUniformFloatArrays = useUniformFloatArrays; } @@ -121,11 +135,15 @@ public: int count, GrSLPrecision precision = kDefault_GrSLPrecision, const char* layoutQualifier = nullptr, + const char* extraModifiers = nullptr, bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) { SkASSERT(kVoid_GrSLType != type); SkASSERT(kDefault_GrSLPrecision == precision || GrSLTypeIsNumeric(type)); INHERITED::set(type, name, typeModifier, precision, count); fLayoutQualifier = layoutQualifier; + if (extraModifiers) { + fExtraModifiers.printf("%s ", extraModifiers); + } fUseUniformFloatArrays = useUniformFloatArrays; } @@ -136,6 +154,12 @@ public: fLayoutQualifier = layoutQualifier; } + void addModifier(const char* modifier) { + if (modifier) { + fExtraModifiers.appendf("%s ", modifier); + } + } + /** * Write a declaration of this variable to out. */ @@ -144,11 +168,8 @@ public: if (!fLayoutQualifier.isEmpty()) { out->appendf("layout(%s) ", fLayoutQualifier.c_str()); } + out->append(fExtraModifiers); if (this->getTypeModifier() != kNone_TypeModifier) { - if (GrSLTypeIsIntType(fType) && (this->getTypeModifier() == kVaryingIn_TypeModifier || - this->getTypeModifier() == kVaryingOut_TypeModifier)) { - out->append("flat "); - } out->append(TypeModifierString(glslCaps, this->getTypeModifier())); out->append(" "); } @@ -234,9 +255,10 @@ private: /// Work around driver bugs on some hardware that don't correctly /// support uniform float [] - bool fUseUniformFloatArrays; + bool fUseUniformFloatArrays; - SkString fLayoutQualifier; + SkString fLayoutQualifier; + SkString fExtraModifiers; typedef GrShaderVar INHERITED; }; diff --git a/src/gpu/glsl/GrGLSLVarying.cpp b/src/gpu/glsl/GrGLSLVarying.cpp index ea52fbe7ab..99bfe7e18f 100644 --- a/src/gpu/glsl/GrGLSLVarying.cpp +++ b/src/gpu/glsl/GrGLSLVarying.cpp @@ -10,10 +10,24 @@ #include "glsl/GrGLSLProgramBuilder.h" void GrGLSLVaryingHandler::addPassThroughAttribute(const GrGeometryProcessor::Attribute* input, - const char* output) { + const char* output, GrSLPrecision precision) { GrSLType type = GrVertexAttribTypeToSLType(input->fType); GrGLSLVertToFrag v(type); - this->addVarying(input->fName, &v); + this->addVarying(input->fName, &v, precision); + this->writePassThroughAttribute(input, output, v); +} + +void GrGLSLVaryingHandler::addFlatPassThroughAttribute(const GrGeometryProcessor::Attribute* input, + const char* output, + GrSLPrecision precision) { + GrSLType type = GrVertexAttribTypeToSLType(input->fType); + GrGLSLVertToFrag v(type); + this->addFlatVarying(input->fName, &v, precision); + this->writePassThroughAttribute(input, output, v); +} + +void GrGLSLVaryingHandler::writePassThroughAttribute(const GrGeometryProcessor::Attribute* input, + const char* output, const GrGLSLVarying& v) { fProgramBuilder->fVS.codeAppendf("%s = %s;", v.vsOut(), input->fName); if (fProgramBuilder->primitiveProcessor().willUseGeoShader()) { @@ -23,62 +37,33 @@ void GrGLSLVaryingHandler::addPassThroughAttribute(const GrGeometryProcessor::At fProgramBuilder->fFS.codeAppendf("%s = %s;", output, v.fsIn()); } -void GrGLSLVaryingHandler::addVarying(const char* name, - GrGLSLVarying* varying, - GrSLPrecision precision) { +void GrGLSLVaryingHandler::internalAddVarying(const char* name, + GrGLSLVarying* varying, + GrSLPrecision precision, + bool flat) { + bool willUseGeoShader = fProgramBuilder->primitiveProcessor().willUseGeoShader(); + VaryingInfo& v = fVaryings.push_back(); + SkASSERT(varying); + v.fType = varying->fType; + v.fPrecision = precision; + v.fIsFlat = flat; + fProgramBuilder->nameVariable(&v.fVsOut, 'v', name); + v.fVisibility = kNone_GrShaderFlags; if (varying->vsVarying()) { - this->addVertexVarying(name, precision, varying); + varying->fVsOut = v.fVsOut.c_str(); + v.fVisibility |= kVertex_GrShaderFlag; } - if (fProgramBuilder->primitiveProcessor().willUseGeoShader()) { - this->addGeomVarying(name, precision, varying); + if (willUseGeoShader) { + fProgramBuilder->nameVariable(&v.fGsOut, 'g', name); + varying->fGsIn = v.fVsOut.c_str(); + varying->fGsOut = v.fGsOut.c_str(); + v.fVisibility |= kGeometry_GrShaderFlag; } if (varying->fsVarying()) { - this->addFragVarying(precision, varying); - } -} - -void GrGLSLVaryingHandler::addVertexVarying(const char* name, - GrSLPrecision precision, - GrGLSLVarying* v) { - fVertexOutputs.push_back(); - fVertexOutputs.back().setType(v->fType); - fVertexOutputs.back().setTypeModifier(GrGLSLShaderVar::kVaryingOut_TypeModifier); - fVertexOutputs.back().setPrecision(precision); - fProgramBuilder->nameVariable(fVertexOutputs.back().accessName(), 'v', name); - v->fVsOut = fVertexOutputs.back().getName().c_str(); -} -void GrGLSLVaryingHandler::addGeomVarying(const char* name, - GrSLPrecision precision, - GrGLSLVarying* v) { - // if we have a GS take each varying in as an array - // and output as non-array. - if (v->vsVarying()) { - fGeomInputs.push_back(); - fGeomInputs.back().setType(v->fType); - fGeomInputs.back().setTypeModifier(GrGLSLShaderVar::kVaryingIn_TypeModifier); - fGeomInputs.back().setPrecision(precision); - fGeomInputs.back().setUnsizedArray(); - *fGeomInputs.back().accessName() = v->fVsOut; - v->fGsIn = v->fVsOut; + varying->fFsIn = (willUseGeoShader ? v.fGsOut : v.fVsOut).c_str(); + v.fVisibility |= kFragment_GrShaderFlag; } - - if (v->fsVarying()) { - fGeomOutputs.push_back(); - fGeomOutputs.back().setType(v->fType); - fGeomOutputs.back().setTypeModifier(GrGLSLShaderVar::kVaryingOut_TypeModifier); - fGeomOutputs.back().setPrecision(precision); - fProgramBuilder->nameVariable(fGeomOutputs.back().accessName(), 'g', name); - v->fGsOut = fGeomOutputs.back().getName().c_str(); - } -} - -void GrGLSLVaryingHandler::addFragVarying(GrSLPrecision precision, GrGLSLVarying* v) { - v->fFsIn = v->fGsOut ? v->fGsOut : v->fVsOut; - fFragInputs.push_back().set(v->fType, - GrGLSLShaderVar::kVaryingIn_TypeModifier, - v->fFsIn, - precision); } void GrGLSLVaryingHandler::emitAttributes(const GrGeometryProcessor& gp) { @@ -105,7 +90,46 @@ void GrGLSLVaryingHandler::addAttribute(const GrShaderVar& var) { fVertexInputs.push_back(var); } +void GrGLSLVaryingHandler::setNoPerspective() { + const GrGLSLCaps& caps = *fProgramBuilder->glslCaps(); + if (!caps.noperspectiveInterpolationSupport()) { + return; + } + if (const char* extension = caps.noperspectiveInterpolationExtensionString()) { + int bit = 1 << GrGLSLFragmentShaderBuilder::kNoPerspectiveInterpolation_GLSLPrivateFeature; + fProgramBuilder->fVS.addFeature(bit, extension); + if (fProgramBuilder->primitiveProcessor().willUseGeoShader()) { + fProgramBuilder->fGS.addFeature(bit, extension); + } + fProgramBuilder->fFS.addFeature(bit, extension); + } + fDefaultInterpolationModifier = "noperspective"; +} + void GrGLSLVaryingHandler::finalize() { + for (int i = 0; i < fVaryings.count(); ++i) { + const VaryingInfo& v = this->fVaryings[i]; + const char* modifier = v.fIsFlat ? "flat" : fDefaultInterpolationModifier; + if (v.fVisibility & kVertex_GrShaderFlag) { + fVertexOutputs.push_back().set(v.fType, GrShaderVar::kVaryingOut_TypeModifier, v.fVsOut, + v.fPrecision, nullptr, modifier); + if (v.fVisibility & kGeometry_GrShaderFlag) { + fGeomInputs.push_back().set(v.fType, GrShaderVar::kVaryingIn_TypeModifier, v.fVsOut, + GrShaderVar::kUnsizedArray, v.fPrecision, nullptr, + modifier); + } + } + if (v.fVisibility & kFragment_GrShaderFlag) { + const char* fsIn = v.fVsOut.c_str(); + if (v.fVisibility & kGeometry_GrShaderFlag) { + fGeomOutputs.push_back().set(v.fType, GrGLSLShaderVar::kVaryingOut_TypeModifier, + v.fGsOut, v.fPrecision, nullptr, modifier); + fsIn = v.fGsOut.c_str(); + } + fFragInputs.push_back().set(v.fType, GrShaderVar::kVaryingIn_TypeModifier, fsIn, + v.fPrecision, nullptr, modifier); + } + } this->onFinalize(); } diff --git a/src/gpu/glsl/GrGLSLVarying.h b/src/gpu/glsl/GrGLSLVarying.h index 22431978c8..5867361ce4 100644 --- a/src/gpu/glsl/GrGLSLVarying.h +++ b/src/gpu/glsl/GrGLSLVarying.h @@ -71,18 +71,25 @@ static const int kVaryingsPerBlock = 8; class GrGLSLVaryingHandler { public: explicit GrGLSLVaryingHandler(GrGLSLProgramBuilder* program) - : fVertexInputs(kVaryingsPerBlock) + : fVaryings(kVaryingsPerBlock) + , fVertexInputs(kVaryingsPerBlock) , fVertexOutputs(kVaryingsPerBlock) , fGeomInputs(kVaryingsPerBlock) , fGeomOutputs(kVaryingsPerBlock) , fFragInputs(kVaryingsPerBlock) , fFragOutputs(kVaryingsPerBlock) - , fProgramBuilder(program) {} + , fProgramBuilder(program) + , fDefaultInterpolationModifier(nullptr) {} virtual ~GrGLSLVaryingHandler() {} - typedef GrTAllocator<GrGLSLShaderVar> VarArray; - typedef GrGLSLProgramDataManager::VaryingHandle VaryingHandle; + /* + * Notifies the varying handler that this shader will never emit geometry in perspective and + * therefore does not require perspective-correct interpolation. When supported, this allows + * varyings to use the "noperspective" keyword, which means the GPU can use cheaper math for + * interpolation. + */ + void setNoPerspective(); /* * addVarying allows fine grained control for setting up varyings between stages. Calling this @@ -93,18 +100,36 @@ public: * TODO convert most uses of addVarying to addPassThroughAttribute */ void addVarying(const char* name, - GrGLSLVarying*, - GrSLPrecision precision = kDefault_GrSLPrecision); + GrGLSLVarying* varying, + GrSLPrecision precision = kDefault_GrSLPrecision) { + SkASSERT(GrSLTypeIsFloatType(varying->type())); // Integers must use addFlatVarying. + this->internalAddVarying(name, varying, precision, false /*flat*/); + } + + /* + * addFlatVarying sets up a varying whose value is constant across every fragment. The graphics + * pipeline will pull its value from the final vertex of the draw primitive (provoking vertex). + * Flat interpolation is not always supported and the user must check the caps before using. + * TODO: Some platforms can change the provoking vertex. Should we be resetting this knob? + */ + void addFlatVarying(const char* name, + GrGLSLVarying* varying, + GrSLPrecision precision = kDefault_GrSLPrecision) { + this->internalAddVarying(name, varying, precision, true /*flat*/); + } /* - * This call can be used by GP to pass an attribute through all shaders directly to 'output' in - * the fragment shader. Though this call effects both the vertex shader and fragment shader, - * it expects 'output' to be defined in the fragment shader before this call is made. If there + * The GP can use these calls to pass an attribute through all shaders directly to 'output' in + * the fragment shader. Though these calls affect both the vertex shader and fragment shader, + * they expect 'output' to be defined in the fragment shader before the call is made. If there * is a geometry shader, we will simply take the value of the varying from the first vertex and * that will be set as the output varying for all emitted vertices. - * TODO it might be nicer behavior to have a flag to declare output inside this call + * TODO it might be nicer behavior to have a flag to declare output inside these calls */ - void addPassThroughAttribute(const GrGeometryProcessor::Attribute*, const char* output); + void addPassThroughAttribute(const GrGeometryProcessor::Attribute*, const char* output, + GrSLPrecision = kDefault_GrSLPrecision); + void addFlatPassThroughAttribute(const GrGeometryProcessor::Attribute*, const char* output, + GrSLPrecision = kDefault_GrSLPrecision); void emitAttributes(const GrGeometryProcessor& gp); @@ -115,21 +140,36 @@ public: void getVertexDecls(SkString* inputDecls, SkString* outputDecls) const; void getGeomDecls(SkString* inputDecls, SkString* outputDecls) const; void getFragDecls(SkString* inputDecls, SkString* outputDecls) const; + protected: - VarArray fVertexInputs; - VarArray fVertexOutputs; - VarArray fGeomInputs; - VarArray fGeomOutputs; - VarArray fFragInputs; - VarArray fFragOutputs; + struct VaryingInfo { + GrSLType fType; + GrSLPrecision fPrecision; + bool fIsFlat; + SkString fVsOut; + SkString fGsOut; + GrShaderFlags fVisibility; + }; + + typedef GrTAllocator<VaryingInfo> VaryingList; + typedef GrTAllocator<GrGLSLShaderVar> VarArray; + typedef GrGLSLProgramDataManager::VaryingHandle VaryingHandle; + + VaryingList fVaryings; + VarArray fVertexInputs; + VarArray fVertexOutputs; + VarArray fGeomInputs; + VarArray fGeomOutputs; + VarArray fFragInputs; + VarArray fFragOutputs; // This is not owned by the class GrGLSLProgramBuilder* fProgramBuilder; private: - void addVertexVarying(const char* name, GrSLPrecision precision, GrGLSLVarying* v); - void addGeomVarying(const char* name, GrSLPrecision precision, GrGLSLVarying* v); - void addFragVarying(GrSLPrecision precision, GrGLSLVarying* v); + void internalAddVarying(const char* name, GrGLSLVarying*, GrSLPrecision, bool flat); + void writePassThroughAttribute(const GrGeometryProcessor::Attribute*, const char* output, + const GrGLSLVarying&); void addAttribute(const GrShaderVar& var); @@ -138,6 +178,8 @@ private: // helper function for get*Decls void appendDecls(const VarArray& vars, SkString* out) const; + const char* fDefaultInterpolationModifier; + friend class GrGLSLProgramBuilder; }; |