diff options
author | Chris Dalton <csmartdalton@google.com> | 2018-02-02 11:06:30 -0700 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-02-02 18:43:29 +0000 |
commit | 7b046312edd9219ba8e66c255f5347c000b69ee1 (patch) | |
tree | 1119465d75682b9d5952e30695033d1105a24c93 | |
parent | 7a9263906c677c0fa5636521e3cc58ba60837720 (diff) |
ccpr: Don't use flat interpolation when it is slow
Bug: skia:
Change-Id: I1bc087187541183fdbaa5f2b93e8b8d287ac8ef8
Reviewed-on: https://skia-review.googlesource.com/102100
Commit-Queue: Chris Dalton <csmartdalton@google.com>
Reviewed-by: Jim Van Verth <jvanverth@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
-rw-r--r-- | src/gpu/ccpr/GrCCCubicShader.cpp | 6 | ||||
-rw-r--r-- | src/gpu/ccpr/GrCCPathProcessor.cpp | 6 | ||||
-rw-r--r-- | src/gpu/ccpr/GrCCQuadraticShader.cpp | 6 | ||||
-rw-r--r-- | src/gpu/ccpr/GrCCTriangleShader.cpp | 8 | ||||
-rw-r--r-- | src/gpu/effects/GrAtlasedShaderHelpers.h | 10 | ||||
-rw-r--r-- | src/gpu/glsl/GrGLSLVarying.cpp | 44 | ||||
-rw-r--r-- | src/gpu/glsl/GrGLSLVarying.h | 30 | ||||
-rw-r--r-- | src/gpu/ops/GrTextureOp.cpp | 22 |
8 files changed, 66 insertions, 66 deletions
diff --git a/src/gpu/ccpr/GrCCCubicShader.cpp b/src/gpu/ccpr/GrCCCubicShader.cpp index fbaf7d9da8..3bf8479536 100644 --- a/src/gpu/ccpr/GrCCCubicShader.cpp +++ b/src/gpu/ccpr/GrCCCubicShader.cpp @@ -133,14 +133,16 @@ void GrCCCubicCornerShader::onEmitSetupCode(GrGLSLVertexGeoBuilder* s, const cha void GrCCCubicCornerShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandler, GrGLSLVarying::Scope scope, SkString* code) { + using Interpolation = GrGLSLVaryingHandler::Interpolation; + fdKLMDdx.reset(kFloat4_GrSLType, scope); - varyingHandler->addFlatVarying("dklmddx", &fdKLMDdx); + varyingHandler->addVarying("dklmddx", &fdKLMDdx, Interpolation::kCanBeFlat); code->appendf("%s = float4(%s[0].x, %s[1].x, %s[2].x, %s.x);", OutName(fdKLMDdx), fKLMMatrix.c_str(), fKLMMatrix.c_str(), fKLMMatrix.c_str(), fEdgeDistanceEquation.c_str()); fdKLMDdy.reset(kFloat4_GrSLType, scope); - varyingHandler->addFlatVarying("dklmddy", &fdKLMDdy); + varyingHandler->addVarying("dklmddy", &fdKLMDdy, Interpolation::kCanBeFlat); code->appendf("%s = float4(%s[0].y, %s[1].y, %s[2].y, %s.y);", OutName(fdKLMDdy), fKLMMatrix.c_str(), fKLMMatrix.c_str(), fKLMMatrix.c_str(), fEdgeDistanceEquation.c_str()); diff --git a/src/gpu/ccpr/GrCCPathProcessor.cpp b/src/gpu/ccpr/GrCCPathProcessor.cpp index f93a0bd631..986b5870d7 100644 --- a/src/gpu/ccpr/GrCCPathProcessor.cpp +++ b/src/gpu/ccpr/GrCCPathProcessor.cpp @@ -146,6 +146,8 @@ GrGLSLPrimitiveProcessor* GrCCPathProcessor::createGLSLInstance(const GrShaderCa void GLSLPathProcessor::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { using InstanceAttribs = GrCCPathProcessor::InstanceAttribs; + using Interpolation = GrGLSLVaryingHandler::Interpolation; + const GrCCPathProcessor& proc = args.fGP.cast<GrCCPathProcessor>(); GrGLSLUniformHandler* uniHandler = args.fUniformHandler; GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler; @@ -160,8 +162,8 @@ void GLSLPathProcessor::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { GrGLSLVarying texcoord(kFloat2_GrSLType); GrGLSLVarying color(kHalf4_GrSLType); varyingHandler->addVarying("texcoord", &texcoord); - varyingHandler->addFlatPassThroughAttribute(&proc.getInstanceAttrib(InstanceAttribs::kColor), - args.fOutputColor); + varyingHandler->addPassThroughAttribute(&proc.getInstanceAttrib(InstanceAttribs::kColor), + args.fOutputColor, Interpolation::kCanBeFlat); // The vertex shader bloats and intersects the devBounds and devBounds45 rectangles, in order to // find an octagon that circumscribes the (bloated) path. diff --git a/src/gpu/ccpr/GrCCQuadraticShader.cpp b/src/gpu/ccpr/GrCCQuadraticShader.cpp index 002fcfd340..1122eafc98 100644 --- a/src/gpu/ccpr/GrCCQuadraticShader.cpp +++ b/src/gpu/ccpr/GrCCQuadraticShader.cpp @@ -101,14 +101,16 @@ void GrCCQuadraticCornerShader::onEmitSetupCode(GrGLSLVertexGeoBuilder* s, const void GrCCQuadraticCornerShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandler, GrGLSLVarying::Scope scope, SkString* code) { + using Interpolation = GrGLSLVaryingHandler::Interpolation; + fdXYDdx.reset(kFloat3_GrSLType, scope); - varyingHandler->addFlatVarying("dXYDdx", &fdXYDdx); + varyingHandler->addVarying("dXYDdx", &fdXYDdx, Interpolation::kCanBeFlat); code->appendf("%s = float3(%s[0].x, %s[0].y, %s.x);", OutName(fdXYDdx), fCanonicalMatrix.c_str(), fCanonicalMatrix.c_str(), fEdgeDistanceEquation.c_str()); fdXYDdy.reset(kFloat3_GrSLType, scope); - varyingHandler->addFlatVarying("dXYDdy", &fdXYDdy); + varyingHandler->addVarying("dXYDdy", &fdXYDdy, Interpolation::kCanBeFlat); code->appendf("%s = float3(%s[1].x, %s[1].y, %s.y);", OutName(fdXYDdy), fCanonicalMatrix.c_str(), fCanonicalMatrix.c_str(), fEdgeDistanceEquation.c_str()); diff --git a/src/gpu/ccpr/GrCCTriangleShader.cpp b/src/gpu/ccpr/GrCCTriangleShader.cpp index 6e9b13ef69..6ed875822e 100644 --- a/src/gpu/ccpr/GrCCTriangleShader.cpp +++ b/src/gpu/ccpr/GrCCTriangleShader.cpp @@ -18,7 +18,8 @@ void GrCCTriangleShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandler, const char* wind) { fCoverageTimesWind.reset(kHalf_GrSLType, scope); if (!inputCoverage) { - varyingHandler->addFlatVarying("wind", &fCoverageTimesWind); + varyingHandler->addVarying("wind", &fCoverageTimesWind, + GrGLSLVaryingHandler::Interpolation::kCanBeFlat); code->appendf("%s = %s;", OutName(fCoverageTimesWind), wind); } else { varyingHandler->addVarying("coverage_times_wind", &fCoverageTimesWind); @@ -89,13 +90,14 @@ void GrCCTriangleCornerShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandl GrGLSLVarying::Scope scope, SkString* code, const char* position, const char* inputCoverage, const char* wind) { + using Interpolation = GrGLSLVaryingHandler::Interpolation; SkASSERT(!inputCoverage); fCornerLocationInAABoxes.reset(kFloat2x2_GrSLType, scope); varyingHandler->addVarying("corner_location_in_aa_boxes", &fCornerLocationInAABoxes); fBisectInAABoxes.reset(kFloat2x2_GrSLType, scope); - varyingHandler->addFlatVarying("bisect_in_aa_boxes", &fBisectInAABoxes); + varyingHandler->addVarying("bisect_in_aa_boxes", &fBisectInAABoxes, Interpolation::kCanBeFlat); code->appendf("for (int i = 0; i < 2; ++i) {"); code->appendf( "%s[i] = %s * %s[i] + %s[i];", @@ -105,7 +107,7 @@ void GrCCTriangleCornerShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandl code->appendf("}"); fWindTimesHalf.reset(kHalf_GrSLType, scope); - varyingHandler->addFlatVarying("wind_times_half", &fWindTimesHalf); + varyingHandler->addVarying("wind_times_half", &fWindTimesHalf, Interpolation::kCanBeFlat); code->appendf("%s = %s * .5;", OutName(fWindTimesHalf), wind); } diff --git a/src/gpu/effects/GrAtlasedShaderHelpers.h b/src/gpu/effects/GrAtlasedShaderHelpers.h index 8c09291d6a..a7d445ac86 100644 --- a/src/gpu/effects/GrAtlasedShaderHelpers.h +++ b/src/gpu/effects/GrAtlasedShaderHelpers.h @@ -20,6 +20,8 @@ static void append_index_uv_varyings(GrGLSLPrimitiveProcessor::EmitArgs& args, GrGLSLVarying *uv, GrGLSLVarying *texIdx, GrGLSLVarying *st) { + using Interpolation = GrGLSLVaryingHandler::Interpolation; + // This extracts the texture index and texel coordinates from the same variable // Packing structure: texel coordinates are multiplied by 2 (or shifted left 1) // texture index is stored as lower bits of both x and y @@ -40,11 +42,9 @@ static void append_index_uv_varyings(GrGLSLPrimitiveProcessor::EmitArgs& args, args.fVaryingHandler->addVarying("TextureCoords", uv); args.fVertBuilder->codeAppendf("%s = unormTexCoords * %s;", uv->vsOut(), atlasSizeInvName); - if (args.fShaderCaps->integerSupport()) { - args.fVaryingHandler->addFlatVarying("TexIndex", texIdx); - } else { - args.fVaryingHandler->addVarying("TexIndex", texIdx); - } + args.fVaryingHandler->addVarying("TexIndex", texIdx, args.fShaderCaps->integerSupport() + ? Interpolation::kMustBeFlat + : Interpolation::kCanBeFlat); args.fVertBuilder->codeAppendf("%s = texIdx;", texIdx->vsOut()); if (st) { diff --git a/src/gpu/glsl/GrGLSLVarying.cpp b/src/gpu/glsl/GrGLSLVarying.cpp index 5a57613b3a..c5cef3492a 100644 --- a/src/gpu/glsl/GrGLSLVarying.cpp +++ b/src/gpu/glsl/GrGLSLVarying.cpp @@ -10,36 +10,44 @@ #include "glsl/GrGLSLProgramBuilder.h" void GrGLSLVaryingHandler::addPassThroughAttribute(const GrGeometryProcessor::Attribute* input, - const char* output) { - GrSLType type = GrVertexAttribTypeToSLType(input->fType); - GrGLSLVarying v(type); - this->addVarying(input->fName, &v); - this->writePassThroughAttribute(input, output, v); -} - -void GrGLSLVaryingHandler::addFlatPassThroughAttribute(const GrGeometryProcessor::Attribute* input, - const char* output) { + const char* output, + Interpolation interpolation) { + SkASSERT(!fProgramBuilder->primitiveProcessor().willUseGeoShader()); GrSLType type = GrVertexAttribTypeToSLType(input->fType); GrGLSLVarying v(type); - this->addFlatVarying(input->fName, &v); - this->writePassThroughAttribute(input, output, v); -} - -void GrGLSLVaryingHandler::writePassThroughAttribute(const GrGeometryProcessor::Attribute* input, - const char* output, const GrGLSLVarying& v) { - SkASSERT(!fProgramBuilder->primitiveProcessor().willUseGeoShader()); + this->addVarying(input->fName, &v, interpolation); fProgramBuilder->fVS.codeAppendf("%s = %s;", v.vsOut(), input->fName); fProgramBuilder->fFS.codeAppendf("%s = %s;", output, v.fsIn()); } -void GrGLSLVaryingHandler::internalAddVarying(const char* name, GrGLSLVarying* varying, bool flat) { +static bool use_flat_interpolation(GrGLSLVaryingHandler::Interpolation interpolation, + const GrShaderCaps& shaderCaps) { + switch (interpolation) { + using Interpolation = GrGLSLVaryingHandler::Interpolation; + case Interpolation::kInterpolated: + return false; + case Interpolation::kCanBeFlat: + SkASSERT(!shaderCaps.preferFlatInterpolation() || + shaderCaps.flatInterpolationSupport()); + return shaderCaps.preferFlatInterpolation(); + case Interpolation::kMustBeFlat: + SkASSERT(shaderCaps.flatInterpolationSupport()); + return true; + } + SK_ABORT("Invalid interpolation"); + return false; +} + +void GrGLSLVaryingHandler::addVarying(const char* name, GrGLSLVarying* varying, + Interpolation interpolation) { + SkASSERT(GrSLTypeIsFloatType(varying->type()) || Interpolation::kMustBeFlat == interpolation); bool willUseGeoShader = fProgramBuilder->primitiveProcessor().willUseGeoShader(); VaryingInfo& v = fVaryings.push_back(); SkASSERT(varying); SkASSERT(kVoid_GrSLType != varying->fType); v.fType = varying->fType; - v.fIsFlat = flat; + v.fIsFlat = use_flat_interpolation(interpolation, *fProgramBuilder->shaderCaps()); fProgramBuilder->nameVariable(&v.fVsOut, 'v', name); v.fVisibility = kNone_GrShaderFlags; if (varying->isInVertexShader()) { diff --git a/src/gpu/glsl/GrGLSLVarying.h b/src/gpu/glsl/GrGLSLVarying.h index dac9bb771f..57704ad075 100644 --- a/src/gpu/glsl/GrGLSLVarying.h +++ b/src/gpu/glsl/GrGLSLVarying.h @@ -79,6 +79,12 @@ public: */ void setNoPerspective(); + enum class Interpolation { + kInterpolated, + kCanBeFlat, // Use "flat" if it will be faster. + kMustBeFlat // Use "flat" even if it is known to be slow. + }; + /* * addVarying allows fine grained control for setting up varyings between stages. Calling this * function will make sure all necessary decls are setup for the client. The client however is @@ -87,20 +93,8 @@ public: * addPassThroughAttribute. * TODO convert most uses of addVarying to addPassThroughAttribute */ - void addVarying(const char* name, GrGLSLVarying* varying) { - SkASSERT(GrSLTypeIsFloatType(varying->type())); // Integers must use addFlatVarying. - this->internalAddVarying(name, varying, 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) { - this->internalAddVarying(name, varying, true /*flat*/); - } + void addVarying(const char* name, GrGLSLVarying* varying, + Interpolation = Interpolation::kInterpolated); /* * The GP can use these calls to pass an attribute through all shaders directly to 'output' in @@ -110,8 +104,8 @@ public: * 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 these calls */ - void addPassThroughAttribute(const GrGeometryProcessor::Attribute*, const char* output); - void addFlatPassThroughAttribute(const GrGeometryProcessor::Attribute*, const char* output); + void addPassThroughAttribute(const GrGeometryProcessor::Attribute*, const char* output, + Interpolation = Interpolation::kInterpolated); void emitAttributes(const GrGeometryProcessor& gp); @@ -148,10 +142,6 @@ protected: GrGLSLProgramBuilder* fProgramBuilder; private: - void internalAddVarying(const char* name, GrGLSLVarying*, bool flat); - void writePassThroughAttribute(const GrGeometryProcessor::Attribute*, const char* output, - const GrGLSLVarying&); - void addAttribute(const GrShaderVar& var); virtual void onFinalize() = 0; diff --git a/src/gpu/ops/GrTextureOp.cpp b/src/gpu/ops/GrTextureOp.cpp index 46d2630270..565a65883d 100644 --- a/src/gpu/ops/GrTextureOp.cpp +++ b/src/gpu/ops/GrTextureOp.cpp @@ -116,6 +116,7 @@ public: private: void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override { + using Interpolation = GrGLSLVaryingHandler::Interpolation; const auto& textureGP = args.fGP.cast<TextureGeometryProcessor>(); fColorSpaceXformHelper.emitCode( args.fUniformHandler, textureGP.fColorSpaceXform.get()); @@ -127,26 +128,19 @@ public: args.fUniformHandler, textureGP.fTextureCoords.asShaderVar(), args.fFPCoordTransformHandler); - if (args.fShaderCaps->preferFlatInterpolation()) { - args.fVaryingHandler->addFlatPassThroughAttribute(&textureGP.fColors, - args.fOutputColor); - } else { - args.fVaryingHandler->addPassThroughAttribute(&textureGP.fColors, - args.fOutputColor); - } + args.fVaryingHandler->addPassThroughAttribute(&textureGP.fColors, + args.fOutputColor, + Interpolation::kCanBeFlat); args.fFragBuilder->codeAppend("float2 texCoord;"); args.fVaryingHandler->addPassThroughAttribute(&textureGP.fTextureCoords, "texCoord"); if (textureGP.numTextureSamplers() > 1) { + // If this changes to float, reconsider Interpolation::kMustBeFlat. + SkASSERT(kInt_GrVertexAttribType == textureGP.fTextureIdx.fType); SkASSERT(args.fShaderCaps->integerSupport()); args.fFragBuilder->codeAppend("int texIdx;"); - if (args.fShaderCaps->flatInterpolationSupport()) { - args.fVaryingHandler->addFlatPassThroughAttribute(&textureGP.fTextureIdx, - "texIdx"); - } else { - args.fVaryingHandler->addPassThroughAttribute(&textureGP.fTextureIdx, - "texIdx"); - } + args.fVaryingHandler->addPassThroughAttribute(&textureGP.fTextureIdx, "texIdx", + Interpolation::kMustBeFlat); args.fFragBuilder->codeAppend("switch (texIdx) {"); for (int i = 0; i < textureGP.numTextureSamplers(); ++i) { args.fFragBuilder->codeAppendf("case %d: %s = ", i, args.fOutputColor); |