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
This commit is contained in:
cdalton 2016-02-12 13:24:26 -08:00 committed by Commit bot
parent c7578b6cdd
commit 533cefe5b9
10 changed files with 102 additions and 17 deletions

View File

@ -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 "<no version>";
}
@ -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 {

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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"));

View File

@ -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;

View File

@ -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;

View File

@ -33,7 +33,9 @@ public:
*/
enum GLSLFeature {
kStandardDerivatives_GLSLFeature = kLastGLSLPrivateFeature + 1,
kPixelLocalStorage_GLSLFeature
kPixelLocalStorage_GLSLFeature,
kSampleVariables_GLSLFeature,
kSampleMaskOverrideCoverage_GLSLFeature
};
/**

View File

@ -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 {

View File

@ -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,