diff options
author | 2014-12-09 09:00:49 -0800 | |
---|---|---|
committer | 2014-12-09 09:00:49 -0800 | |
commit | 17168df7798d0d12684f18df0556dc19e65b32e6 (patch) | |
tree | c146317e443c68d41d03f7e5b623cf22ef2386e7 /src/gpu/gl | |
parent | 303044579913eacc177d4b28a674121725c565bb (diff) |
Use texture size to determine precision of texture coord varyings.
Review URL: https://codereview.chromium.org/778783002
Diffstat (limited to 'src/gpu/gl')
-rw-r--r-- | src/gpu/gl/GrGLCaps.cpp | 72 | ||||
-rw-r--r-- | src/gpu/gl/GrGLCaps.h | 7 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgramDesc.cpp | 53 | ||||
-rw-r--r-- | src/gpu/gl/GrGLUtil.h | 9 | ||||
-rw-r--r-- | src/gpu/gl/builders/GrGLProgramBuilder.cpp | 3 | ||||
-rw-r--r-- | src/gpu/gl/builders/GrGLProgramBuilder.h | 12 |
6 files changed, 122 insertions, 34 deletions
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp index cf442a0430..a510cb456b 100644 --- a/src/gpu/gl/GrGLCaps.cpp +++ b/src/gpu/gl/GrGLCaps.cpp @@ -386,6 +386,8 @@ bool GrGLCaps::init(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) { this->initConfigTexturableTable(ctxInfo, gli); this->initConfigRenderableTable(ctxInfo); + this->initShaderPrecisionTable(ctxInfo, gli); + return true; } @@ -774,6 +776,76 @@ void GrGLCaps::initStencilFormats(const GrGLContextInfo& ctxInfo) { fStencilVerifiedColorConfigs.push_back_n(fStencilFormats.count()); } +static GrGLenum precision_to_gl_float_type(GrShaderVar::Precision p) { + switch (p) { + case GrShaderVar::kLow_Precision: + return GR_GL_LOW_FLOAT; + case GrShaderVar::kMedium_Precision: + return GR_GL_MEDIUM_FLOAT; + case GrShaderVar::kHigh_Precision: + return GR_GL_HIGH_FLOAT; + } + SkFAIL("Unknown precision."); + return -1; +} + +static GrGLenum shader_type_to_gl_shader(GrShaderType type) { + switch (type) { + case kVertex_GrShaderType: + return GR_GL_VERTEX_SHADER; + case kGeometry_GrShaderType: + return GR_GL_GEOMETRY_SHADER; + case kFragment_GrShaderType: + return GR_GL_FRAGMENT_SHADER; + } + SkFAIL("Unknown shader type."); + return -1; +} + +void GrGLCaps::initShaderPrecisionTable(const GrGLContextInfo& ctxInfo, const GrGLInterface* intf) { + if (kGLES_GrGLStandard == ctxInfo.standard() || ctxInfo.version() >= GR_GL_VER(4,1) || + ctxInfo.hasExtension("GL_ARB_ES2_compatibility")) { + for (int s = 0; s < kGrShaderTypeCount; ++s) { + if (kGeometry_GrShaderType != s || fGeometryShaderSupport) { + GrShaderType shaderType = static_cast<GrShaderType>(s); + GrGLenum glShader = shader_type_to_gl_shader(shaderType); + PrecisionInfo* first = NULL; + fShaderPrecisionVaries = false; + for (int p = 0; p < GrShaderVar::kPrecisionCount; ++p) { + GrShaderVar::Precision precision = static_cast<GrShaderVar::Precision>(p); + GrGLenum glPrecision = precision_to_gl_float_type(precision); + GrGLint range[2]; + GrGLint bits; + GR_GL_GetShaderPrecisionFormat(intf, glShader, glPrecision, range, &bits); + if (bits) { + fFloatPrecisions[s][p].fLogRangeLow = range[0]; + fFloatPrecisions[s][p].fLogRangeHigh = range[1]; + fFloatPrecisions[s][p].fBits = bits; + if (!first) { + first = &fFloatPrecisions[s][p]; + } else if (!fShaderPrecisionVaries) { + fShaderPrecisionVaries = (*first != fFloatPrecisions[s][p]); + } + } + } + } + } + } else { + // We're on a desktop GL that doesn't have precision info. Assume they're all 32bit float. + fShaderPrecisionVaries = false; + for (int s = 0; s < kGrShaderTypeCount; ++s) { + if (kGeometry_GrShaderType != s || fGeometryShaderSupport) { + for (int p = 0; p < GrShaderVar::kPrecisionCount; ++p) { + fFloatPrecisions[s][p].fLogRangeLow = 127; + fFloatPrecisions[s][p].fLogRangeHigh = 127; + fFloatPrecisions[s][p].fBits = 23; + } + } + } + } +} + + void GrGLCaps::markColorConfigAndStencilFormatAsVerified( GrPixelConfig config, const GrGLStencilBuffer::Format& format) { diff --git a/src/gpu/gl/GrGLCaps.h b/src/gpu/gl/GrGLCaps.h index f84019335c..19e9b878de 100644 --- a/src/gpu/gl/GrGLCaps.h +++ b/src/gpu/gl/GrGLCaps.h @@ -325,9 +325,10 @@ private: void initConfigRenderableTable(const GrGLContextInfo&); void initConfigTexturableTable(const GrGLContextInfo&, const GrGLInterface*); - bool doReadPixelsSupported(const GrGLInterface* intf, - GrGLenum format, - GrGLenum type) const; + // Must be called after fGeometryShaderSupport is initialized. + void initShaderPrecisionTable(const GrGLContextInfo&, const GrGLInterface*); + + bool doReadPixelsSupported(const GrGLInterface* intf, GrGLenum format, GrGLenum type) const; // tracks configs that have been verified to pass the FBO completeness when // used as a color attachment diff --git a/src/gpu/gl/GrGLProgramDesc.cpp b/src/gpu/gl/GrGLProgramDesc.cpp index 6867a1329b..16de1eab22 100644 --- a/src/gpu/gl/GrGLProgramDesc.cpp +++ b/src/gpu/gl/GrGLProgramDesc.cpp @@ -14,25 +14,6 @@ #include "gl/builders/GrGLFragmentShaderBuilder.h" /** - * The key for an individual coord transform is made up of a matrix type and a bit that - * indicates the source of the input coords. - */ -enum { - kMatrixTypeKeyBits = 1, - kMatrixTypeKeyMask = (1 << kMatrixTypeKeyBits) - 1, - kPositionCoords_Flag = (1 << kMatrixTypeKeyBits), - kTransformKeyBits = kMatrixTypeKeyBits + 1, -}; - -/** - * We specialize the vertex code for each of these matrix types. - */ -enum MatrixType { - kNoPersp_MatrixType = 0, - kGeneral_MatrixType = 1, -}; - -/** * Do we need to either map r,g,b->a or a->r. configComponentMask indicates which channels are * present in the texture's config. swizzleComponentMask indicates the channels present in the * shader swizzle. @@ -72,8 +53,33 @@ static uint32_t gen_attrib_key(const GrGeometryProcessor& proc) { return key; } -static uint32_t gen_transform_key(const GrPendingFragmentStage& stage, - bool useExplicitLocalCoords) { +/** + * The key for an individual coord transform is made up of a matrix type, a precision, and a bit + * that indicates the source of the input coords. + */ +enum { + kMatrixTypeKeyBits = 1, + kMatrixTypeKeyMask = (1 << kMatrixTypeKeyBits) - 1, + + kPrecisionBits = 2, + kPrecisionShift = kMatrixTypeKeyBits, + + kPositionCoords_Flag = (1 << (kPrecisionShift + kPrecisionBits)), + + kTransformKeyBits = kMatrixTypeKeyBits + kPrecisionBits + 1, +}; + +GR_STATIC_ASSERT(GrShaderVar::kHigh_Precision < (1 << kPrecisionBits)); + +/** + * We specialize the vertex code for each of these matrix types. + */ +enum MatrixType { + kNoPersp_MatrixType = 0, + kGeneral_MatrixType = 1, +}; + +static uint32_t gen_transform_key(const GrPendingFragmentStage& stage, bool useExplicitLocalCoords) { uint32_t totalKey = 0; int numTransforms = stage.getProcessor()->numTransforms(); for (int t = 0; t < numTransforms; ++t) { @@ -88,7 +94,12 @@ static uint32_t gen_transform_key(const GrPendingFragmentStage& stage, if (kLocal_GrCoordSet != coordTransform.sourceCoords() && useExplicitLocalCoords) { key |= kPositionCoords_Flag; } + + GR_STATIC_ASSERT(GrShaderVar::kPrecisionCount <= (1 << kPrecisionBits)); + key |= (coordTransform.precision() << kPrecisionShift); + key <<= kTransformKeyBits * t; + SkASSERT(0 == (totalKey & key)); // keys for each transform ought not to overlap totalKey |= key; } diff --git a/src/gpu/gl/GrGLUtil.h b/src/gpu/gl/GrGLUtil.h index bc6fdf1757..570694af31 100644 --- a/src/gpu/gl/GrGLUtil.h +++ b/src/gpu/gl/GrGLUtil.h @@ -71,12 +71,21 @@ enum GrGLRenderer { *(p) = GR_GL_INIT_ZERO; \ GR_GL_CALL(gl, GetRenderbufferParameteriv(t, pname, p)); \ } while (0) + #define GR_GL_GetTexLevelParameteriv(gl, t, l, pname, p) \ do { \ *(p) = GR_GL_INIT_ZERO; \ GR_GL_CALL(gl, GetTexLevelParameteriv(t, l, pname, p)); \ } while (0) +#define GR_GL_GetShaderPrecisionFormat(gl, st, pt, range, precision) \ + do { \ + (range)[0] = GR_GL_INIT_ZERO; \ + (range)[1] = GR_GL_INIT_ZERO; \ + (*precision) = GR_GL_INIT_ZERO; \ + GR_GL_CALL(gl, GetShaderPrecisionFormat(st, pt, range, precision)); \ + } while (0) + //////////////////////////////////////////////////////////////////////////////// /** diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.cpp b/src/gpu/gl/builders/GrGLProgramBuilder.cpp index 4d8011cd97..5ed566fa33 100644 --- a/src/gpu/gl/builders/GrGLProgramBuilder.cpp +++ b/src/gpu/gl/builders/GrGLProgramBuilder.cpp @@ -413,7 +413,8 @@ void GrGLProgramBuilder::emitTransforms(const GrPendingFragmentStage& stage, const char* coords = useLocalCoords ? fVS.localCoords() : fVS.positionCoords(); GrGLVertToFrag v(varyingType); - this->addCoordVarying(varyingName, &v, uniName, coords); + this->addVarying(varyingName, &v, processor->coordTransform(t).precision()); + fCoordVaryings.push_back(TransformVarying(v, uniName, coords)); SkASSERT(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == varyingType); SkNEW_APPEND_TO_TARRAY(outCoords, GrGLProcessor::TransformedCoords, diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.h b/src/gpu/gl/builders/GrGLProgramBuilder.h index 973ae5e078..b7458b3e8f 100644 --- a/src/gpu/gl/builders/GrGLProgramBuilder.h +++ b/src/gpu/gl/builders/GrGLProgramBuilder.h @@ -30,9 +30,9 @@ class GrGLUniformBuilder { public: enum ShaderVisibility { - kVertex_Visibility = 0x1, - kGeometry_Visibility = 0x2, - kFragment_Visibility = 0x4, + kVertex_Visibility = 1 << kVertex_GrShaderType, + kGeometry_Visibility = 1 << kGeometry_GrShaderType, + kFragment_Visibility = 1 << kFragment_GrShaderType, }; virtual ~GrGLUniformBuilder() {} @@ -344,12 +344,6 @@ protected: SkString fSourceCoords; }; - void addCoordVarying(const char* name, GrGLVarying* v, const char* uniName, - const char* sourceCoords) { - this->addVarying(name, v); - fCoordVaryings.push_back(TransformVarying(*v, uniName, sourceCoords)); - } - const char* rtAdjustment() const { return "rtAdjustment"; } // number of each input/output type in a single allocation block, used by many builders |