aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/gl
diff options
context:
space:
mode:
authorGravatar bsalomon <bsalomon@google.com>2014-12-09 09:00:49 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2014-12-09 09:00:49 -0800
commit17168df7798d0d12684f18df0556dc19e65b32e6 (patch)
treec146317e443c68d41d03f7e5b623cf22ef2386e7 /src/gpu/gl
parent303044579913eacc177d4b28a674121725c565bb (diff)
Use texture size to determine precision of texture coord varyings.
Diffstat (limited to 'src/gpu/gl')
-rw-r--r--src/gpu/gl/GrGLCaps.cpp72
-rw-r--r--src/gpu/gl/GrGLCaps.h7
-rw-r--r--src/gpu/gl/GrGLProgramDesc.cpp53
-rw-r--r--src/gpu/gl/GrGLUtil.h9
-rw-r--r--src/gpu/gl/builders/GrGLProgramBuilder.cpp3
-rw-r--r--src/gpu/gl/builders/GrGLProgramBuilder.h12
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