From 533cefe5b9c7cec2592fc7ca00ee4cf69a26c094 Mon Sep 17 00:00:00 2001 From: cdalton Date: Fri, 12 Feb 2016 13:24:26 -0800 Subject: [PATCH] Add infastructure for gl_SampleMask BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1690963003 Review URL: https://codereview.chromium.org/1690963003 --- src/gpu/gl/GrGLCaps.cpp | 26 +++++++++++++++ src/gpu/gl/GrGLGLSL.cpp | 11 +++--- src/gpu/glsl/GrGLSL.cpp | 2 ++ src/gpu/glsl/GrGLSL.h | 8 +++++ src/gpu/glsl/GrGLSLCaps.cpp | 6 ++++ src/gpu/glsl/GrGLSLCaps.h | 12 +++++++ src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp | 35 ++++++++++++++++---- src/gpu/glsl/GrGLSLFragmentShaderBuilder.h | 4 ++- src/gpu/glsl/GrGLSLShaderBuilder.cpp | 10 +++--- src/gpu/glsl/GrGLSLShaderBuilder.h | 5 ++- 10 files changed, 102 insertions(+), 17 deletions(-) diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp index 6dc5ee8c4f..8d207eb00d 100644 --- a/src/gpu/gl/GrGLCaps.cpp +++ b/src/gpu/gl/GrGLCaps.cpp @@ -553,9 +553,19 @@ const char* get_glsl_version_decl_string(GrGLStandard standard, GrGLSLGeneration return "#version 330 compatibility\n"; } } + case k400_GrGLSLGeneration: + SkASSERT(kGL_GrGLStandard == standard); + if (isCoreProfile) { + return "#version 400\n"; + } else { + return "#version 400 compatibility\n"; + } case k310es_GrGLSLGeneration: SkASSERT(kGLES_GrGLStandard == standard); return "#version 310 es\n"; + case k320es_GrGLSLGeneration: + SkASSERT(kGLES_GrGLStandard == standard); + return "#version 320 es\n"; } return ""; } @@ -596,6 +606,22 @@ void GrGLCaps::initGLSL(const GrGLContextInfo& ctxInfo) { glslCaps->fBindlessTextureSupport = ctxInfo.hasExtension("GL_NV_bindless_texture"); + if (kGL_GrGLStandard == standard) { + glslCaps->fSampleVariablesSupport = ctxInfo.glslGeneration() >= k400_GrGLSLGeneration; + } else { + if (ctxInfo.glslGeneration() >= k320es_GrGLSLGeneration) { + glslCaps->fSampleVariablesSupport = true; + } else if (ctxInfo.hasExtension("GL_OES_sample_variables")) { + glslCaps->fSampleVariablesSupport = true; + glslCaps->fSampleVariablesExtensionString = "GL_OES_sample_variables"; + } + } + + if (glslCaps->fSampleVariablesSupport) { + glslCaps->fSampleMaskOverrideCoverageSupport = + ctxInfo.hasExtension("GL_NV_sample_mask_override_coverage"); + } + if (kGL_GrGLStandard == standard) { glslCaps->fFlatInterpolationSupport = ctxInfo.glslGeneration() >= k130_GrGLSLGeneration; } else { diff --git a/src/gpu/gl/GrGLGLSL.cpp b/src/gpu/gl/GrGLGLSL.cpp index 98a2386161..4aaa6f87d6 100755 --- a/src/gpu/gl/GrGLGLSL.cpp +++ b/src/gpu/gl/GrGLGLSL.cpp @@ -19,7 +19,9 @@ bool GrGLGetGLSLGeneration(const GrGLInterface* gl, GrGLSLGeneration* generation switch (gl->fStandard) { case kGL_GrGLStandard: SkASSERT(ver >= GR_GLSL_VER(1,10)); - if (ver >= GR_GLSL_VER(3,30)) { + if (ver >= GR_GLSL_VER(4,00)) { + *generation = k400_GrGLSLGeneration; + } else if (ver >= GR_GLSL_VER(3,30)) { *generation = k330_GrGLSLGeneration; } else if (ver >= GR_GLSL_VER(1,50)) { *generation = k150_GrGLSLGeneration; @@ -33,10 +35,11 @@ bool GrGLGetGLSLGeneration(const GrGLInterface* gl, GrGLSLGeneration* generation return true; case kGLES_GrGLStandard: SkASSERT(ver >= GR_GL_VER(1,00)); - if (ver >= GR_GLSL_VER(3,1)) { + if (ver >= GR_GLSL_VER(3,2)) { + *generation = k320es_GrGLSLGeneration; + } else if (ver >= GR_GLSL_VER(3,1)) { *generation = k310es_GrGLSLGeneration; - } - else if (ver >= GR_GLSL_VER(3,0)) { + } else if (ver >= GR_GLSL_VER(3,0)) { *generation = k330_GrGLSLGeneration; } else { *generation = k110_GrGLSLGeneration; diff --git a/src/gpu/glsl/GrGLSL.cpp b/src/gpu/glsl/GrGLSL.cpp index 2de81ddd60..bec4784db2 100644 --- a/src/gpu/glsl/GrGLSL.cpp +++ b/src/gpu/glsl/GrGLSL.cpp @@ -17,7 +17,9 @@ bool GrGLSLSupportsNamedFragmentShaderOutputs(GrGLSLGeneration gen) { case k140_GrGLSLGeneration: case k150_GrGLSLGeneration: case k330_GrGLSLGeneration: + case k400_GrGLSLGeneration: case k310es_GrGLSLGeneration: + case k320es_GrGLSLGeneration: return true; } return false; diff --git a/src/gpu/glsl/GrGLSL.h b/src/gpu/glsl/GrGLSL.h index 6fc8f83c7a..b13113a289 100644 --- a/src/gpu/glsl/GrGLSL.h +++ b/src/gpu/glsl/GrGLSL.h @@ -36,10 +36,18 @@ enum GrGLSLGeneration { * Desktop GLSL 3.30, and ES GLSL 3.00 */ k330_GrGLSLGeneration, + /** + * Desktop GLSL 4.00 + */ + k400_GrGLSLGeneration, /** * ES GLSL 3.10 only TODO Make GLSLCap objects to make this more granular */ k310es_GrGLSLGeneration, + /** + * ES GLSL 3.20 + */ + k320es_GrGLSLGeneration, }; bool GrGLSLSupportsNamedFragmentShaderOutputs(GrGLSLGeneration); diff --git a/src/gpu/glsl/GrGLSLCaps.cpp b/src/gpu/glsl/GrGLSLCaps.cpp index ba99be57e2..7116f5deb0 100755 --- a/src/gpu/glsl/GrGLSLCaps.cpp +++ b/src/gpu/glsl/GrGLSLCaps.cpp @@ -23,10 +23,13 @@ GrGLSLCaps::GrGLSLCaps(const GrContextOptions& options) { fCanUseAnyFunctionInShader = true; fCanUseMinAndAbsTogether = true; fMustForceNegatedAtanParamToFloat = false; + fSampleVariablesSupport = false; + fSampleMaskOverrideCoverageSupport = false; fFlatInterpolationSupport = false; fNoPerspectiveInterpolationSupport = false; fVersionDeclString = nullptr; fShaderDerivativeExtensionString = nullptr; + fSampleVariablesExtensionString = nullptr; fFragCoordConventionsExtensionString = nullptr; fSecondaryOutputExtensionString = nullptr; fExternalTextureExtensionString = nullptr; @@ -61,6 +64,9 @@ SkString GrGLSLCaps::dump() const { r.appendf("Can use min() and abs() together: %s\n", (fCanUseMinAndAbsTogether ? "YES" : "NO")); r.appendf("Must force negated atan param to float: %s\n", (fMustForceNegatedAtanParamToFloat ? "YES" : "NO")); + r.appendf("Sample variables support: %s\n", (fSampleVariablesSupport ? "YES" : "NO")); + r.appendf("Sample mask override coverage support: %s\n", (fSampleMaskOverrideCoverageSupport ? + "YES" : "NO")); r.appendf("Flat interpolation support: %s\n", (fFlatInterpolationSupport ? "YES" : "NO")); r.appendf("No perspective interpolation support: %s\n", (fNoPerspectiveInterpolationSupport ? "YES" : "NO")); diff --git a/src/gpu/glsl/GrGLSLCaps.h b/src/gpu/glsl/GrGLSLCaps.h index 2f87f66850..ee0fbff4b9 100755 --- a/src/gpu/glsl/GrGLSLCaps.h +++ b/src/gpu/glsl/GrGLSLCaps.h @@ -54,6 +54,10 @@ public: bool dropsTileOnZeroDivide() const { return fDropsTileOnZeroDivide; } + bool sampleVariablesSupport() const { return fSampleVariablesSupport; } + + bool sampleMaskOverrideCoverageSupport() const { return fSampleMaskOverrideCoverageSupport; } + bool flatInterpolationSupport() const { return fFlatInterpolationSupport; } bool noperspectiveInterpolationSupport() const { return fNoPerspectiveInterpolationSupport; } @@ -88,6 +92,11 @@ public: SkASSERT(this->shaderDerivativeSupport()); return fShaderDerivativeExtensionString; } + + const char* sampleVariablesExtensionString() const { + SkASSERT(this->sampleVariablesSupport()); + return fSampleVariablesExtensionString; + } // Returns the string of an extension that will do all necessary coord transfomations needed // when reading the fragment position. If such an extension does not exisits, this function @@ -146,6 +155,8 @@ private: bool fBindlessTextureSupport : 1; bool fUsesPrecisionModifiers : 1; bool fCanUseAnyFunctionInShader : 1; + bool fSampleVariablesSupport : 1; + bool fSampleMaskOverrideCoverageSupport : 1; bool fFlatInterpolationSupport : 1; bool fNoPerspectiveInterpolationSupport : 1; @@ -156,6 +167,7 @@ private: const char* fVersionDeclString; const char* fShaderDerivativeExtensionString; + const char* fSampleVariablesExtensionString; const char* fFragCoordConventionsExtensionString; const char* fSecondaryOutputExtensionString; const char* fExternalTextureExtensionString; diff --git a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp index 8651827841..903b03af95 100644 --- a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp +++ b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp @@ -77,25 +77,46 @@ GrGLSLFragmentShaderBuilder::GrGLSLFragmentShaderBuilder(GrGLSLProgramBuilder* p } bool GrGLSLFragmentShaderBuilder::enableFeature(GLSLFeature feature) { + const GrGLSLCaps& glslCaps = *fProgramBuilder->glslCaps(); switch (feature) { - case kStandardDerivatives_GLSLFeature: { - if (!fProgramBuilder->glslCaps()->shaderDerivativeSupport()) { + case kStandardDerivatives_GLSLFeature: + if (!glslCaps.shaderDerivativeSupport()) { return false; } - const char* extension = fProgramBuilder->glslCaps()->shaderDerivativeExtensionString(); - if (extension) { + if (const char* extension = glslCaps.shaderDerivativeExtensionString()) { this->addFeature(1 << kStandardDerivatives_GLSLFeature, extension); } return true; - } - case kPixelLocalStorage_GLSLFeature: { + case kPixelLocalStorage_GLSLFeature: if (fProgramBuilder->glslCaps()->pixelLocalStorageSize() <= 0) { return false; } this->addFeature(1 << kPixelLocalStorage_GLSLFeature, "GL_EXT_shader_pixel_local_storage"); return true; - } + case kSampleVariables_GLSLFeature: + if (!glslCaps.sampleVariablesSupport()) { + return false; + } + if (const char* extension = glslCaps.sampleVariablesExtensionString()) { + this->addFeature(1 << kSampleVariables_GLSLFeature, extension); + } + return true; + case kSampleMaskOverrideCoverage_GLSLFeature: + if (!glslCaps.sampleMaskOverrideCoverageSupport()) { + return false; + } + if (!this->enableFeature(kSampleVariables_GLSLFeature)) { + return false; + } + if (this->addFeature(1 << kSampleMaskOverrideCoverage_GLSLFeature, + "GL_NV_sample_mask_override_coverage")) { + // Redeclare gl_SampleMask with layout(override_coverage) if we haven't already. + fOutputs.push_back().set(kInt_GrSLType, GrShaderVar::kOut_TypeModifier, + "gl_SampleMask", 1, kHigh_GrSLPrecision, + "override_coverage"); + } + return true; default: SkFAIL("Unexpected GLSLFeature requested."); return false; diff --git a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h index a437a194ca..d8ff148cab 100644 --- a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h +++ b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h @@ -33,7 +33,9 @@ public: */ enum GLSLFeature { kStandardDerivatives_GLSLFeature = kLastGLSLPrivateFeature + 1, - kPixelLocalStorage_GLSLFeature + kPixelLocalStorage_GLSLFeature, + kSampleVariables_GLSLFeature, + kSampleMaskOverrideCoverage_GLSLFeature }; /** diff --git a/src/gpu/glsl/GrGLSLShaderBuilder.cpp b/src/gpu/glsl/GrGLSLShaderBuilder.cpp index c94a85534f..30bf86d210 100644 --- a/src/gpu/glsl/GrGLSLShaderBuilder.cpp +++ b/src/gpu/glsl/GrGLSLShaderBuilder.cpp @@ -112,11 +112,13 @@ void GrGLSLShaderBuilder::appendTextureLookupAndModulate(const char* modulation, this->codeAppend((GrGLSLExpr4(modulation) * GrGLSLExpr4(lookup)).c_str()); } -void GrGLSLShaderBuilder::addFeature(uint32_t featureBit, const char* extensionName) { - if (!(featureBit & fFeaturesAddedMask)) { - this->extensions().appendf("#extension %s: require\n", extensionName); - fFeaturesAddedMask |= featureBit; +bool GrGLSLShaderBuilder::addFeature(uint32_t featureBit, const char* extensionName) { + if (featureBit & fFeaturesAddedMask) { + return false; } + this->extensions().appendf("#extension %s: require\n", extensionName); + fFeaturesAddedMask |= featureBit; + return true; } void GrGLSLShaderBuilder::appendDecls(const VarArray& vars, SkString* out) const { diff --git a/src/gpu/glsl/GrGLSLShaderBuilder.h b/src/gpu/glsl/GrGLSLShaderBuilder.h index bc3b4ca717..4ec78243a9 100644 --- a/src/gpu/glsl/GrGLSLShaderBuilder.h +++ b/src/gpu/glsl/GrGLSLShaderBuilder.h @@ -151,14 +151,17 @@ protected: kBlendFuncExtended_GLSLPrivateFeature, kExternalTexture_GLSLPrivateFeature, kFramebufferFetch_GLSLPrivateFeature, + kSampleMaskOverrideCoverage_GLSLPrivateFeature, kNoPerspectiveInterpolation_GLSLPrivateFeature, kLastGLSLPrivateFeature = kNoPerspectiveInterpolation_GLSLPrivateFeature }; /* * A general function which enables an extension in a shader if the feature bit is not present + * + * @return true if the feature bit was not yet present, false otherwise. */ - void addFeature(uint32_t featureBit, const char* extensionName); + bool addFeature(uint32_t featureBit, const char* extensionName); enum InterfaceQualifier { kOut_InterfaceQualifier,