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

Side by Side 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: comments Created 4 years, 9 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 unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright 2014 Google Inc. 2 * Copyright 2014 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "GrGLSLFragmentShaderBuilder.h" 8 #include "GrGLSLFragmentShaderBuilder.h"
9 #include "GrRenderTarget.h" 9 #include "GrRenderTarget.h"
10 #include "gl/GrGLGpu.h" 10 #include "gl/GrGLGpu.h"
11 #include "glsl/GrGLSL.h" 11 #include "glsl/GrGLSL.h"
12 #include "glsl/GrGLSLCaps.h" 12 #include "glsl/GrGLSLCaps.h"
13 #include "glsl/GrGLSLProgramBuilder.h" 13 #include "glsl/GrGLSLProgramBuilder.h"
14 #include "glsl/GrGLSLUniformHandler.h" 14 #include "glsl/GrGLSLUniformHandler.h"
15 #include "glsl/GrGLSLVarying.h" 15 #include "glsl/GrGLSLVarying.h"
16 16
17 const char* GrGLSLFragmentShaderBuilder::kDstTextureColorName = "_dstColor"; 17 const char* GrGLSLFragmentShaderBuilder::kDstTextureColorName = "_dstColor";
18 18
19 static const char* sample_offset_array_name(GrGLSLFPFragmentBuilder::Coordinates coords) {
20 static const char* kArrayNames[] = {
21 "deviceSpaceSampleOffsets",
22 "windowSpaceSampleOffsets"
23 };
24 return kArrayNames[coords];
25
26 GR_STATIC_ASSERT(0 == GrGLSLFPFragmentBuilder::kSkiaDevice_Coordinates);
27 GR_STATIC_ASSERT(1 == GrGLSLFPFragmentBuilder::kGLSLWindow_Coordinates);
28 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kArrayNames) == GrGLSLFPFragmentBuilder::kLa st_Coordinates + 1);
29 }
30
19 static const char* specific_layout_qualifier_name(GrBlendEquation equation) { 31 static const char* specific_layout_qualifier_name(GrBlendEquation equation) {
20 SkASSERT(GrBlendEquationIsAdvanced(equation)); 32 SkASSERT(GrBlendEquationIsAdvanced(equation));
21 33
22 static const char* kLayoutQualifierNames[] = { 34 static const char* kLayoutQualifierNames[] = {
23 "blend_support_screen", 35 "blend_support_screen",
24 "blend_support_overlay", 36 "blend_support_overlay",
25 "blend_support_darken", 37 "blend_support_darken",
26 "blend_support_lighten", 38 "blend_support_lighten",
27 "blend_support_colordodge", 39 "blend_support_colordodge",
28 "blend_support_colorburn", 40 "blend_support_colorburn",
(...skipping 21 matching lines...) Expand all
50 GR_STATIC_ASSERT(9 == kExclusion_GrBlendEquation - kFirstAdvancedGrBlendEqua tion); 62 GR_STATIC_ASSERT(9 == kExclusion_GrBlendEquation - kFirstAdvancedGrBlendEqua tion);
51 GR_STATIC_ASSERT(10 == kMultiply_GrBlendEquation - kFirstAdvancedGrBlendEqua tion); 63 GR_STATIC_ASSERT(10 == kMultiply_GrBlendEquation - kFirstAdvancedGrBlendEqua tion);
52 GR_STATIC_ASSERT(11 == kHSLHue_GrBlendEquation - kFirstAdvancedGrBlendEquati on); 64 GR_STATIC_ASSERT(11 == kHSLHue_GrBlendEquation - kFirstAdvancedGrBlendEquati on);
53 GR_STATIC_ASSERT(12 == kHSLSaturation_GrBlendEquation - kFirstAdvancedGrBlen dEquation); 65 GR_STATIC_ASSERT(12 == kHSLSaturation_GrBlendEquation - kFirstAdvancedGrBlen dEquation);
54 GR_STATIC_ASSERT(13 == kHSLColor_GrBlendEquation - kFirstAdvancedGrBlendEqua tion); 66 GR_STATIC_ASSERT(13 == kHSLColor_GrBlendEquation - kFirstAdvancedGrBlendEqua tion);
55 GR_STATIC_ASSERT(14 == kHSLLuminosity_GrBlendEquation - kFirstAdvancedGrBlen dEquation); 67 GR_STATIC_ASSERT(14 == kHSLLuminosity_GrBlendEquation - kFirstAdvancedGrBlen dEquation);
56 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kLayoutQualifierNames) == 68 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kLayoutQualifierNames) ==
57 kGrBlendEquationCnt - kFirstAdvancedGrBlendEquation); 69 kGrBlendEquationCnt - kFirstAdvancedGrBlendEquation);
58 } 70 }
59 71
60 GrGLSLFragmentShaderBuilder::FragPosKey 72 uint8_t GrGLSLFragmentShaderBuilder::KeyForSurfaceOrigin(GrSurfaceOrigin origin) {
61 GrGLSLFragmentShaderBuilder::KeyForFragmentPosition(const GrRenderTarget* dst) { 73 SkASSERT(kTopLeft_GrSurfaceOrigin == origin || kBottomLeft_GrSurfaceOrigin = = origin);
62 if (kTopLeft_GrSurfaceOrigin == dst->origin()) { 74 return origin;
63 return kTopLeftFragPosRead_FragPosKey; 75
64 } else { 76 GR_STATIC_ASSERT(1 == kTopLeft_GrSurfaceOrigin);
65 return kBottomLeftFragPosRead_FragPosKey; 77 GR_STATIC_ASSERT(2 == kBottomLeft_GrSurfaceOrigin);
66 }
67 } 78 }
68 79
69 GrGLSLFragmentShaderBuilder::GrGLSLFragmentShaderBuilder(GrGLSLProgramBuilder* p rogram, 80 GrGLSLFragmentShaderBuilder::GrGLSLFragmentShaderBuilder(GrGLSLProgramBuilder* p rogram)
70 uint8_t fragPosKey)
71 : GrGLSLFragmentBuilder(program) 81 : GrGLSLFragmentBuilder(program)
72 , fSetupFragPosition(false) 82 , fSetupFragPosition(false)
73 , fTopLeftFragPosRead(kTopLeftFragPosRead_FragPosKey == fragPosKey)
74 , fHasCustomColorOutput(false) 83 , fHasCustomColorOutput(false)
75 , fCustomColorOutputIndex(-1) 84 , fCustomColorOutputIndex(-1)
76 , fHasSecondaryOutput(false) 85 , fHasSecondaryOutput(false)
86 , fUsedSampleOffsetArrays(0)
77 , fHasInitializedSampleMask(false) { 87 , fHasInitializedSampleMask(false) {
78 fSubstageIndices.push_back(0); 88 fSubstageIndices.push_back(0);
79 #ifdef SK_DEBUG 89 #ifdef SK_DEBUG
80 fUsedProcessorFeatures = GrProcessor::kNone_RequiredFeatures; 90 fUsedProcessorFeatures = GrProcessor::kNone_RequiredFeatures;
81 fHasReadDstColor = false; 91 fHasReadDstColor = false;
82 #endif 92 #endif
83 } 93 }
84 94
85 bool GrGLSLFragmentShaderBuilder::hasFragmentPosition() const {
86 return 0 != fProgramBuilder->header().fFragPosKey;
87 }
88
89 bool GrGLSLFragmentShaderBuilder::enableFeature(GLSLFeature feature) { 95 bool GrGLSLFragmentShaderBuilder::enableFeature(GLSLFeature feature) {
90 switch (feature) { 96 switch (feature) {
91 case kStandardDerivatives_GLSLFeature: { 97 case kStandardDerivatives_GLSLFeature: {
92 if (!fProgramBuilder->glslCaps()->shaderDerivativeSupport()) { 98 if (!fProgramBuilder->glslCaps()->shaderDerivativeSupport()) {
93 return false; 99 return false;
94 } 100 }
95 const char* extension = fProgramBuilder->glslCaps()->shaderDerivativ eExtensionString(); 101 const char* extension = fProgramBuilder->glslCaps()->shaderDerivativ eExtensionString();
96 if (extension) { 102 if (extension) {
97 this->addFeature(1 << kStandardDerivatives_GLSLFeature, extensio n); 103 this->addFeature(1 << kStandardDerivatives_GLSLFeature, extensio n);
98 } 104 }
(...skipping 23 matching lines...) Expand all
122 SkString coords2D("coords2D"); 128 SkString coords2D("coords2D");
123 if (0 != index) { 129 if (0 != index) {
124 coords2D.appendf("_%i", index); 130 coords2D.appendf("_%i", index);
125 } 131 }
126 this->codeAppendf("\tvec2 %s = %s.xy / %s.z;", 132 this->codeAppendf("\tvec2 %s = %s.xy / %s.z;",
127 coords2D.c_str(), coords[index].c_str(), coords[index].c_s tr()); 133 coords2D.c_str(), coords[index].c_str(), coords[index].c_s tr());
128 return coords2D; 134 return coords2D;
129 } 135 }
130 136
131 const char* GrGLSLFragmentShaderBuilder::fragmentPosition() { 137 const char* GrGLSLFragmentShaderBuilder::fragmentPosition() {
132 SkASSERT(this->hasFragmentPosition());
133 SkDEBUGCODE(fUsedProcessorFeatures |= GrProcessor::kFragmentPosition_Require dFeature;) 138 SkDEBUGCODE(fUsedProcessorFeatures |= GrProcessor::kFragmentPosition_Require dFeature;)
134 139
135 const GrGLSLCaps* glslCaps = fProgramBuilder->glslCaps(); 140 const GrGLSLCaps* glslCaps = fProgramBuilder->glslCaps();
136 // We only declare "gl_FragCoord" when we're in the case where we want to us e layout qualifiers 141 // We only declare "gl_FragCoord" when we're in the case where we want to us e layout qualifiers
137 // to reverse y. Otherwise it isn't necessary and whether the "in" qualifier appears in the 142 // to reverse y. Otherwise it isn't necessary and whether the "in" qualifier appears in the
138 // declaration varies in earlier GLSL specs. So it is simpler to omit it. 143 // declaration varies in earlier GLSL specs. So it is simpler to omit it.
139 if (fTopLeftFragPosRead) { 144 if (kTopLeft_GrSurfaceOrigin == this->getSurfaceOrigin()) {
140 fSetupFragPosition = true; 145 fSetupFragPosition = true;
141 return "gl_FragCoord"; 146 return "gl_FragCoord";
142 } else if (const char* extension = glslCaps->fragCoordConventionsExtensionSt ring()) { 147 } else if (const char* extension = glslCaps->fragCoordConventionsExtensionSt ring()) {
143 if (!fSetupFragPosition) { 148 if (!fSetupFragPosition) {
144 if (glslCaps->generation() < k150_GrGLSLGeneration) { 149 if (glslCaps->generation() < k150_GrGLSLGeneration) {
145 this->addFeature(1 << kFragCoordConventions_GLSLPrivateFeature, 150 this->addFeature(1 << kFragCoordConventions_GLSLPrivateFeature,
146 extension); 151 extension);
147 } 152 }
148 fInputs.push_back().set(kVec4f_GrSLType, 153 fInputs.push_back().set(kVec4f_GrSLType,
149 GrGLSLShaderVar::kIn_TypeModifier, 154 GrGLSLShaderVar::kIn_TypeModifier,
(...skipping 20 matching lines...) Expand all
170 this->codePrependf("\t%svec4 %s = vec4(%s.x, %s - %s.y, 1.0, 1.0);\n ", 175 this->codePrependf("\t%svec4 %s = vec4(%s.x, %s - %s.y, 1.0, 1.0);\n ",
171 precision, kCoordName, kTempName, rtHeightName, k TempName); 176 precision, kCoordName, kTempName, rtHeightName, k TempName);
172 this->codePrependf("%svec2 %s = gl_FragCoord.xy;", precision, kTempN ame); 177 this->codePrependf("%svec2 %s = gl_FragCoord.xy;", precision, kTempN ame);
173 fSetupFragPosition = true; 178 fSetupFragPosition = true;
174 } 179 }
175 SkASSERT(fProgramBuilder->fUniformHandles.fRTHeightUni.isValid()); 180 SkASSERT(fProgramBuilder->fUniformHandles.fRTHeightUni.isValid());
176 return kCoordName; 181 return kCoordName;
177 } 182 }
178 } 183 }
179 184
185 void GrGLSLFragmentShaderBuilder::appendOffsetToSample(const char* sampleIdx, Co ordinates coords) {
186 SkASSERT(fProgramBuilder->header().fSamplePatternKey);
187 SkDEBUGCODE(fUsedProcessorFeatures |= GrProcessor::kSampleLocations_Required Feature);
188 if (kTopLeft_GrSurfaceOrigin == this->getSurfaceOrigin()) {
189 // With a top left origin, device and window space are equal, so we only use device coords.
190 coords = kSkiaDevice_Coordinates;
191 }
192 this->codeAppendf("%s[%s]", sample_offset_array_name(coords), sampleIdx);
193 fUsedSampleOffsetArrays |= (1 << coords);
194 }
195
180 void GrGLSLFragmentShaderBuilder::maskSampleCoverage(const char* mask, bool inve rt) { 196 void GrGLSLFragmentShaderBuilder::maskSampleCoverage(const char* mask, bool inve rt) {
181 const GrGLSLCaps& glslCaps = *fProgramBuilder->glslCaps(); 197 const GrGLSLCaps& glslCaps = *fProgramBuilder->glslCaps();
182 if (!glslCaps.sampleVariablesSupport()) { 198 if (!glslCaps.sampleVariablesSupport()) {
183 SkDEBUGFAIL("Attempted to mask sample coverage without support."); 199 SkDEBUGFAIL("Attempted to mask sample coverage without support.");
184 return; 200 return;
185 } 201 }
186 if (const char* extension = glslCaps.sampleVariablesExtensionString()) { 202 if (const char* extension = glslCaps.sampleVariablesExtensionString()) {
187 this->addFeature(1 << kSampleVariables_GLSLPrivateFeature, extension); 203 this->addFeature(1 << kSampleVariables_GLSLPrivateFeature, extension);
188 } 204 }
189 if (!fHasInitializedSampleMask) { 205 if (!fHasInitializedSampleMask) {
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 inputs().appendVAList(fmt, argp); 317 inputs().appendVAList(fmt, argp);
302 va_end(argp); 318 va_end(argp);
303 } 319 }
304 320
305 const char* GrGLSLFragmentShaderBuilder::getSecondaryColorOutputName() const { 321 const char* GrGLSLFragmentShaderBuilder::getSecondaryColorOutputName() const {
306 const GrGLSLCaps& caps = *fProgramBuilder->glslCaps(); 322 const GrGLSLCaps& caps = *fProgramBuilder->glslCaps();
307 return caps.mustDeclareFragmentShaderOutput() ? DeclaredSecondaryColorOutput Name() 323 return caps.mustDeclareFragmentShaderOutput() ? DeclaredSecondaryColorOutput Name()
308 : "gl_SecondaryFragColorEXT"; 324 : "gl_SecondaryFragColorEXT";
309 } 325 }
310 326
327 GrSurfaceOrigin GrGLSLFragmentShaderBuilder::getSurfaceOrigin() const {
328 SkASSERT(fProgramBuilder->header().fSurfaceOriginKey);
329 return static_cast<GrSurfaceOrigin>(fProgramBuilder->header().fSurfaceOrigin Key);
330
331 GR_STATIC_ASSERT(1 == kTopLeft_GrSurfaceOrigin);
332 GR_STATIC_ASSERT(2 == kBottomLeft_GrSurfaceOrigin);
333 }
334
311 void GrGLSLFragmentShaderBuilder::onFinalize() { 335 void GrGLSLFragmentShaderBuilder::onFinalize() {
312 fProgramBuilder->varyingHandler()->getFragDecls(&this->inputs(), &this->outp uts()); 336 fProgramBuilder->varyingHandler()->getFragDecls(&this->inputs(), &this->outp uts());
313 GrGLSLAppendDefaultFloatPrecisionDeclaration(kDefault_GrSLPrecision, 337 GrGLSLAppendDefaultFloatPrecisionDeclaration(kDefault_GrSLPrecision,
314 *fProgramBuilder->glslCaps(), 338 *fProgramBuilder->glslCaps(),
315 &this->precisionQualifier()); 339 &this->precisionQualifier());
340 if (fUsedSampleOffsetArrays & (1 << kSkiaDevice_Coordinates)) {
341 this->defineSampleOffsetArray(sample_offset_array_name(kSkiaDevice_Coord inates),
342 SkMatrix::MakeTrans(-0.5f, -0.5f));
343 }
344 if (fUsedSampleOffsetArrays & (1 << kGLSLWindow_Coordinates)) {
345 // With a top left origin, device and window space are equal, so we only use device coords.
346 SkASSERT(kBottomLeft_GrSurfaceOrigin == this->getSurfaceOrigin());
347 SkMatrix m;
348 m.setScale(1, -1);
349 m.preTranslate(-0.5f, -0.5f);
350 this->defineSampleOffsetArray(sample_offset_array_name(kGLSLWindow_Coord inates), m);
351 }
352 }
353
354 void GrGLSLFragmentShaderBuilder::defineSampleOffsetArray(const char* name, cons t SkMatrix& m) {
355 SkASSERT(fProgramBuilder->caps()->sampleLocationsSupport());
356 const GrCaps::MultisampleSpecs& specs =
357 fProgramBuilder->caps()->getMultisampleSpecs(fProgramBuilder->header().f SamplePatternKey);
358 SkSTArray<16, SkPoint, true> offsets;
359 offsets.push_back_n(specs.fEffectiveSampleCnt);
360 m.mapPoints(offsets.begin(), specs.fSampleLocations.get(), specs.fEffectiveS ampleCnt);
361 this->definitions().append("const ");
362 if (fProgramBuilder->glslCaps()->usesPrecisionModifiers()) {
363 this->definitions().append("highp ");
364 }
365 this->definitions().appendf("vec2 %s[] = vec2[](", name);
366 for (int i = 0; i < specs.fEffectiveSampleCnt; ++i) {
367 this->definitions().appendf("vec2(%f, %f)", offsets[i].x(), offsets[i].y ());
368 this->definitions().append(i + 1 != specs.fEffectiveSampleCnt ? ", " : " );\n");
369 }
316 } 370 }
317 371
318 void GrGLSLFragmentShaderBuilder::onBeforeChildProcEmitCode() { 372 void GrGLSLFragmentShaderBuilder::onBeforeChildProcEmitCode() {
319 SkASSERT(fSubstageIndices.count() >= 1); 373 SkASSERT(fSubstageIndices.count() >= 1);
320 fSubstageIndices.push_back(0); 374 fSubstageIndices.push_back(0);
321 // second-to-last value in the fSubstageIndices stack is the index of the ch ild proc 375 // second-to-last value in the fSubstageIndices stack is the index of the ch ild proc
322 // at that level which is currently emitting code. 376 // at that level which is currently emitting code.
323 fMangleString.appendf("_c%d", fSubstageIndices[fSubstageIndices.count() - 2] ); 377 fMangleString.appendf("_c%d", fSubstageIndices[fSubstageIndices.count() - 2] );
324 } 378 }
325 379
326 void GrGLSLFragmentShaderBuilder::onAfterChildProcEmitCode() { 380 void GrGLSLFragmentShaderBuilder::onAfterChildProcEmitCode() {
327 SkASSERT(fSubstageIndices.count() >= 2); 381 SkASSERT(fSubstageIndices.count() >= 2);
328 fSubstageIndices.pop_back(); 382 fSubstageIndices.pop_back();
329 fSubstageIndices.back()++; 383 fSubstageIndices.back()++;
330 int removeAt = fMangleString.findLastOf('_'); 384 int removeAt = fMangleString.findLastOf('_');
331 fMangleString.remove(removeAt, fMangleString.size() - removeAt); 385 fMangleString.remove(removeAt, fMangleString.size() - removeAt);
332 } 386 }
333 387
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698