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

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

Powered by Google App Engine
This is Rietveld 408576698