Add gl_SampleMask functionality to fragment builders
Adds methods for overriding and masking a fragment's sample mask.
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1690963003
Committed: https://skia.googlesource.com/skia/+/533cefe5b9c7cec2592fc7ca00ee4cf69a26c094
Review URL: https://codereview.chromium.org/1690963003
diff --git a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp
index 4277cf4..44db57e 100644
--- a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp
+++ b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp
@@ -74,6 +74,7 @@
, fHasCustomColorOutput(false)
, fCustomColorOutputIndex(-1)
, fHasSecondaryOutput(false)
+ , fHasInitializedSampleMask(false)
, fHasReadDstColor(false)
, fHasReadFragmentPosition(false) {
fSubstageIndices.push_back(0);
@@ -169,6 +170,47 @@
}
}
+void GrGLSLFragmentShaderBuilder::maskSampleCoverage(const char* mask, bool invert) {
+ const GrGLSLCaps& glslCaps = *fProgramBuilder->glslCaps();
+ if (!glslCaps.sampleVariablesSupport()) {
+ SkDEBUGFAIL("Attempted to mask sample coverage without support.");
+ return;
+ }
+ if (const char* extension = glslCaps.sampleVariablesExtensionString()) {
+ this->addFeature(1 << kSampleVariables_GLSLPrivateFeature, extension);
+ }
+ if (!fHasInitializedSampleMask) {
+ this->codePrependf("gl_SampleMask[0] = -1;");
+ fHasInitializedSampleMask = true;
+ }
+ if (invert) {
+ this->codeAppendf("gl_SampleMask[0] &= ~(%s);", mask);
+ } else {
+ this->codeAppendf("gl_SampleMask[0] &= %s;", mask);
+ }
+}
+
+void GrGLSLFragmentShaderBuilder::overrideSampleCoverage(const char* mask) {
+ const GrGLSLCaps& glslCaps = *fProgramBuilder->glslCaps();
+ if (!glslCaps.sampleMaskOverrideCoverageSupport()) {
+ SkDEBUGFAIL("Attempted to override sample coverage without support.");
+ return;
+ }
+ SkASSERT(glslCaps.sampleVariablesSupport());
+ if (const char* extension = glslCaps.sampleVariablesExtensionString()) {
+ this->addFeature(1 << kSampleVariables_GLSLPrivateFeature, extension);
+ }
+ if (this->addFeature(1 << kSampleMaskOverrideCoverage_GLSLPrivateFeature,
+ "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");
+ }
+ this->codeAppendf("gl_SampleMask[0] = %s;", mask);
+ fHasInitializedSampleMask = true;
+}
+
const char* GrGLSLFragmentShaderBuilder::dstColor() {
fHasReadDstColor = true;