Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(222)

Unified Diff: src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp

Issue 1717393002: Add "sample locations" feature to GrProcessor (Closed) Base URL: https://skia.googlesource.com/skia.git@upload_getmultisamp
Patch Set: move into GrProcessor Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp
diff --git a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp
index bd0108407f076d5fce9ee45e2dcba8c80939107a..6835466ccfedc8e605c9d5e01ebfbbafd1b972c5 100644
--- a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp
+++ b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp
@@ -66,6 +66,16 @@ GrGLSLFragmentShaderBuilder::KeyForFragmentPosition(const GrRenderTarget* dst) {
}
}
+static const char* sampleOffsetArrays[] = {
+ "deviceSpaceSampleOffsets",
+ "windowSpaceSampleOffsets"
+};
+
+GR_STATIC_ASSERT(0 == GrGLSLFPFragmentBuilder::kSkiaDevice_Coordinates);
+GR_STATIC_ASSERT(1 == GrGLSLFPFragmentBuilder::kGLSLWindow_Coordinates);
+GR_STATIC_ASSERT(SK_ARRAY_COUNT(sampleOffsetArrays) ==
+ GrGLSLFPFragmentBuilder::kLast_Coordinates + 1);
+
GrGLSLFragmentShaderBuilder::GrGLSLFragmentShaderBuilder(GrGLSLProgramBuilder* program,
uint8_t fragPosKey)
: GrGLSLFragmentBuilder(program)
@@ -74,6 +84,7 @@ GrGLSLFragmentShaderBuilder::GrGLSLFragmentShaderBuilder(GrGLSLProgramBuilder* p
, fHasCustomColorOutput(false)
, fCustomColorOutputIndex(-1)
, fHasSecondaryOutput(false)
+ , fUsedSampleOffsetArrays(0)
, fHasInitializedSampleMask(false) {
fSubstageIndices.push_back(0);
#ifdef SK_DEBUG
@@ -82,10 +93,6 @@ GrGLSLFragmentShaderBuilder::GrGLSLFragmentShaderBuilder(GrGLSLProgramBuilder* p
#endif
}
-bool GrGLSLFragmentShaderBuilder::hasFragmentPosition() const {
- return 0 != fProgramBuilder->header().fFragPosKey;
-}
-
bool GrGLSLFragmentShaderBuilder::enableFeature(GLSLFeature feature) {
switch (feature) {
case kStandardDerivatives_GLSLFeature: {
@@ -129,7 +136,7 @@ SkString GrGLSLFragmentShaderBuilder::ensureFSCoords2D(const GrGLSLTransformedCo
}
const char* GrGLSLFragmentShaderBuilder::fragmentPosition() {
- SkASSERT(this->hasFragmentPosition());
+ SkASSERT(fProgramBuilder->canReadFragmentPosition());
SkDEBUGCODE(fUsedProcessorFeatures |= GrProcessor::kFragmentPosition_RequiredFeature;)
const GrGLSLCaps* glslCaps = fProgramBuilder->glslCaps();
@@ -177,6 +184,13 @@ const char* GrGLSLFragmentShaderBuilder::fragmentPosition() {
}
}
+void GrGLSLFragmentShaderBuilder::appendOffsetToSample(const char* sampleIdx, Coordinates coords) {
+ SkASSERT(fProgramBuilder->canUseSampleLocations());
Chris Dalton 2016/02/29 20:52:50 Is an assert here good enough? Or do we prefer an
bsalomon 2016/03/01 14:28:55 An assert seems fine.
+ SkDEBUGCODE(fUsedProcessorFeatures |= GrProcessor::kSampleLocations_RequiredFeature);
+ this->codeAppendf("%s[%s]", sampleOffsetArrays[coords], sampleIdx);
+ fUsedSampleOffsetArrays |= (1 << coords);
+}
+
void GrGLSLFragmentShaderBuilder::maskSampleCoverage(const char* mask, bool invert) {
const GrGLSLCaps& glslCaps = *fProgramBuilder->glslCaps();
if (!glslCaps.sampleVariablesSupport()) {
@@ -313,6 +327,34 @@ void GrGLSLFragmentShaderBuilder::onFinalize() {
GrGLSLAppendDefaultFloatPrecisionDeclaration(kDefault_GrSLPrecision,
*fProgramBuilder->glslCaps(),
&this->precisionQualifier());
+ if (fUsedSampleOffsetArrays & (1 << kSkiaDevice_Coordinates)) {
+ this->defineSampleOffsetArray(sampleOffsetArrays[kSkiaDevice_Coordinates],
+ SkMatrix::MakeTrans(-0.5f, -0.5f));
+ }
+ if (fUsedSampleOffsetArrays & (1 << kGLSLWindow_Coordinates)) {
+ SkMatrix m;
+ m.setScale(1, -1);
+ m.preTranslate(-0.5f, -0.5f);
+ this->defineSampleOffsetArray(sampleOffsetArrays[kGLSLWindow_Coordinates], m);
+ }
+}
+
+void GrGLSLFragmentShaderBuilder::defineSampleOffsetArray(const char* name, const SkMatrix& m) {
+ const GrPipeline& pipeline = fProgramBuilder->pipeline();
+ const GrRenderTargetPriv& rtp = pipeline.getRenderTarget()->renderTargetPriv();
+ int effectiveSampleCnt = rtp.getEffectiveSampleCount(pipeline.getStencil());
+ SkSTArray<16, SkPoint, true> offsets;
+ offsets.push_back_n(effectiveSampleCnt);
+ m.mapPoints(offsets.begin(), rtp.getSampleLocations(pipeline.getStencil()), effectiveSampleCnt);
+ this->definitions().append("const ");
+ if (fProgramBuilder->glslCaps()->usesPrecisionModifiers()) {
+ this->definitions().append("highp ");
+ }
+ this->definitions().appendf("vec2 %s[] = vec2[](", name);
+ for (int i = 0; i < effectiveSampleCnt; ++i) {
+ this->definitions().appendf("vec2(%f, %f)", offsets[i].x(), offsets[i].y());
+ this->definitions().append(i + 1 != effectiveSampleCnt ? ", " : ");\n");
+ }
}
void GrGLSLFragmentShaderBuilder::onBeforeChildProcEmitCode() {

Powered by Google App Engine
This is Rietveld 408576698