From c08f196648463d44eb85e17c5815dbf8f709a42a Mon Sep 17 00:00:00 2001 From: cdalton Date: Fri, 12 Feb 2016 12:14:06 -0800 Subject: Use noperspective interpolation for 2D draws Adds a mechanism to notify GrGLSLVaryingHandler that a shader will not emit geometry in perspective. This gives it a chance to use the noperspective keyword if it is supported. Updates the existing processors to notify the varying handler when there is no perspective. Begins using the noperspective keyword in GrGLGpu internal shaders. Web scenes with observable benefit (Pixel C, gpu config): tabl_nofolo.skp 4.62 -> 3.33 ms 28% desk_tigersvg.skp 26.5 -> 24 ms 9% desk_pokemonwiki.skp 16.1 -> 14.9 ms 7% tabl_deviantart.skp 3.97 -> 3.7 ms 7% desk_gws.skp 3.85 -> 3.65 ms 5% Also adds new methods for creating varyings with flat interpolation. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1673093002 Review URL: https://codereview.chromium.org/1673093002 --- src/gpu/glsl/GrGLSLVarying.cpp | 128 ++++++++++++++++++++++++----------------- 1 file changed, 76 insertions(+), 52 deletions(-) (limited to 'src/gpu/glsl/GrGLSLVarying.cpp') 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(); } -- cgit v1.2.3