diff options
-rw-r--r-- | include/gpu/GrShaderCaps.h | 4 | ||||
-rw-r--r-- | src/gpu/GrShaderCaps.cpp | 2 | ||||
-rw-r--r-- | src/gpu/ccpr/GrCCCubicShader.cpp | 34 | ||||
-rw-r--r-- | src/gpu/gl/GrGLCaps.cpp | 6 | ||||
-rw-r--r-- | src/gpu/vk/GrVkCaps.cpp | 1 |
5 files changed, 42 insertions, 5 deletions
diff --git a/include/gpu/GrShaderCaps.h b/include/gpu/GrShaderCaps.h index f86e87c461..b6afe3934f 100644 --- a/include/gpu/GrShaderCaps.h +++ b/include/gpu/GrShaderCaps.h @@ -76,6 +76,9 @@ public: bool vertexIDSupport() const { return fVertexIDSupport; } + // frexp, ldexp, etc. + bool fpManipulationSupport() const { return fFPManipulationSupport; } + bool floatIs32Bits() const { return fFloatIs32Bits; } bool halfIs32Bits() const { return fHalfIs32Bits; } @@ -250,6 +253,7 @@ private: bool fExternalTextureSupport : 1; bool fTexelFetchSupport : 1; bool fVertexIDSupport : 1; + bool fFPManipulationSupport : 1; bool fFloatIs32Bits : 1; bool fHalfIs32Bits : 1; diff --git a/src/gpu/GrShaderCaps.cpp b/src/gpu/GrShaderCaps.cpp index 5c6d0b9ce7..c0b34ab746 100644 --- a/src/gpu/GrShaderCaps.cpp +++ b/src/gpu/GrShaderCaps.cpp @@ -46,6 +46,7 @@ GrShaderCaps::GrShaderCaps(const GrContextOptions& options) { fExternalTextureSupport = false; fTexelFetchSupport = false; fVertexIDSupport = false; + fFPManipulationSupport = false; fFloatIs32Bits = true; fHalfIs32Bits = false; @@ -118,6 +119,7 @@ void GrShaderCaps::dumpJSON(SkJSONWriter* writer) const { writer->appendBool("External texture support", fExternalTextureSupport); writer->appendBool("texelFetch support", fTexelFetchSupport); writer->appendBool("sk_VertexID support", fVertexIDSupport); + writer->appendBool("Floating point manipulation support", fFPManipulationSupport); writer->appendBool("float == fp32", fFloatIs32Bits); writer->appendBool("half == fp32", fHalfIs32Bits); diff --git a/src/gpu/ccpr/GrCCCubicShader.cpp b/src/gpu/ccpr/GrCCCubicShader.cpp index d0228d59ad..c5fefdd78e 100644 --- a/src/gpu/ccpr/GrCCCubicShader.cpp +++ b/src/gpu/ccpr/GrCCCubicShader.cpp @@ -8,12 +8,35 @@ #include "GrCCCubicShader.h" #include "glsl/GrGLSLFragmentShaderBuilder.h" +#include "glsl/GrGLSLProgramBuilder.h" #include "glsl/GrGLSLVertexGeoBuilder.h" using Shader = GrCCCoverageProcessor::Shader; void GrCCCubicShader::emitSetupCode(GrGLSLVertexGeoBuilder* s, const char* pts, const char* wind, const char** /*tighterHull*/) const { + // Define a function that normalizes the homogeneous coordinates T=t/s in order to avoid + // exponent overflow. + SkString normalizeHomogCoordFn; + GrShaderVar coord("coord", kFloat2_GrSLType); + s->emitFunction(kFloat2_GrSLType, "normalize_homogeneous_coord", 1, &coord, + s->getProgramBuilder()->shaderCaps()->fpManipulationSupport() + // Exponent manipulation version: Scale the exponents so the larger + // component has a magnitude in 1..2. + // (Neither component should be infinity because ccpr crops big paths.) + ? "int exp;" + "frexp(max(abs(coord.t), abs(coord.s)), exp);" + "return coord * ldexp(1, 1 - exp);" + + // Division version: Divide by the component with the larger magnitude. + // (Both should not be 0 because ccpr catches degenerate cubics.) + : "bool swap = abs(coord.t) > abs(coord.s);" + "coord = swap ? coord.ts : coord;" + "coord = float2(1, coord.t/coord.s);" + "return swap ? coord.ts : coord;", + + &normalizeHomogCoordFn); + // Find the cubic's power basis coefficients. s->codeAppendf("float2x4 C = float4x4(-1, 3, -3, 1, " " 3, -6, 3, 0, " @@ -33,9 +56,10 @@ void GrCCCubicShader::emitSetupCode(GrGLSLVertexGeoBuilder* s, const char* pts, s->codeAppend ("q = x*D2 + (D2 >= 0 ? q : -q);"); s->codeAppend ("float2 l, m;"); - s->codeAppend ("l.ts = normalize(float2(q, 2*x * D1));"); - s->codeAppend ("m.ts = normalize(float2(2, q) * (discr >= 0 ? float2(D3, 1) " - ": float2(D2*D2 - D3*D1, D1)));"); + s->codeAppendf("l.ts = %s(float2(q, 2*x * D1));", normalizeHomogCoordFn.c_str()); + s->codeAppendf("m.ts = %s(float2(2, q) * (discr >= 0 ? float2(D3, 1) " + ": float2(D2*D2 - D3*D1, D1)));", + normalizeHomogCoordFn.c_str()); s->codeAppend ("float4 K;"); s->codeAppend ("float4 lm = l.sstt * m.stst;"); @@ -46,7 +70,7 @@ void GrCCCubicShader::emitSetupCode(GrGLSLVertexGeoBuilder* s, const char* pts, s->codeAppend ("L = float4(-1,x,-x,1) * l.sstt * (discr >= 0 ? l.ssst * l.sttt : lm);"); s->codeAppend ("M = float4(-1,x,-x,1) * m.sstt * (discr >= 0 ? m.ssst * m.sttt : lm.xzyw);"); - s->codeAppend ("short middlerow = abs(D2) > abs(D1) ? 2 : 1;"); + s->codeAppend ("int middlerow = abs(D2) > abs(D1) ? 2 : 1;"); s->codeAppend ("float3x3 CI = inverse(float3x3(C[0][0], C[0][middlerow], C[0][3], " "C[1][0], C[1][middlerow], C[1][3], " " 0, 0, 1));"); @@ -66,7 +90,7 @@ void GrCCCubicShader::emitSetupCode(GrGLSLVertexGeoBuilder* s, const char* pts, // Determine the amount of additional coverage to subtract out for the flat edge (P3 -> P0). s->declareGlobal(fEdgeDistanceEquation); - s->codeAppendf("short edgeidx0 = %s > 0 ? 3 : 0;", wind); + s->codeAppendf("int edgeidx0 = %s > 0 ? 3 : 0;", wind); s->codeAppendf("float2 edgept0 = %s[edgeidx0];", pts); s->codeAppendf("float2 edgept1 = %s[3 - edgeidx0];", pts); Shader::EmitEdgeDistanceEquation(s, "edgept0", "edgept1", fEdgeDistanceEquation.c_str()); diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp index e22133cff4..e7e2ae9001 100644 --- a/src/gpu/gl/GrGLCaps.cpp +++ b/src/gpu/gl/GrGLCaps.cpp @@ -805,6 +805,12 @@ void GrGLCaps::initGLSL(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli shaderCaps->fVertexIDSupport = ctxInfo.glslGeneration() >= k330_GrGLSLGeneration; } + if (kGL_GrGLStandard == standard) { + shaderCaps->fFPManipulationSupport = ctxInfo.glslGeneration() >= k400_GrGLSLGeneration; + } else { + shaderCaps->fFPManipulationSupport = ctxInfo.glslGeneration() >= k310es_GrGLSLGeneration; + } + shaderCaps->fFloatIs32Bits = is_float_fp32(ctxInfo, gli, GR_GL_HIGH_FLOAT); shaderCaps->fHalfIs32Bits = is_float_fp32(ctxInfo, gli, GR_GL_MEDIUM_FLOAT); } diff --git a/src/gpu/vk/GrVkCaps.cpp b/src/gpu/vk/GrVkCaps.cpp index 83546da5c4..e4ff3ef09a 100644 --- a/src/gpu/vk/GrVkCaps.cpp +++ b/src/gpu/vk/GrVkCaps.cpp @@ -261,6 +261,7 @@ void GrVkCaps::initShaderCaps(const VkPhysicalDeviceProperties& properties, uint shaderCaps->fTexelBufferSupport = true; shaderCaps->fTexelFetchSupport = true; shaderCaps->fVertexIDSupport = true; + shaderCaps->fFPManipulationSupport = true; // Assume the minimum precisions mandated by the SPIR-V spec. shaderCaps->fFloatIs32Bits = true; |