OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 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 "glsl/GrGLSLProgramBuilder.h" | 8 #include "glsl/GrGLSLProgramBuilder.h" |
9 | 9 |
10 #include "GrPipeline.h" | 10 #include "GrPipeline.h" |
11 #include "glsl/GrGLSLFragmentProcessor.h" | 11 #include "glsl/GrGLSLFragmentProcessor.h" |
12 #include "glsl/GrGLSLGeometryProcessor.h" | 12 #include "glsl/GrGLSLGeometryProcessor.h" |
13 #include "glsl/GrGLSLVarying.h" | 13 #include "glsl/GrGLSLVarying.h" |
14 #include "glsl/GrGLSLXferProcessor.h" | 14 #include "glsl/GrGLSLXferProcessor.h" |
15 | 15 |
16 const int GrGLSLProgramBuilder::kVarsPerBlock = 8; | 16 const int GrGLSLProgramBuilder::kVarsPerBlock = 8; |
17 | 17 |
18 GrGLSLProgramBuilder::GrGLSLProgramBuilder(const DrawArgs& args) | 18 GrGLSLProgramBuilder::GrGLSLProgramBuilder(const DrawArgs& args) |
19 : fVS(this) | 19 : fVS(this) |
20 , fGS(this) | 20 , fGS(this) |
21 , fFS(this) | 21 , fFS(this) |
22 , fStageIndex(-1) | 22 , fStageIndex(-1) |
23 , fArgs(args) | 23 , fArgs(args) |
24 , fGeometryProcessor(nullptr) | 24 , fGeometryProcessor(nullptr) |
25 , fXferProcessor(nullptr) { | 25 , fXferProcessor(nullptr) |
| 26 , fSamplerUniforms(4) |
| 27 , fNumVertexSamplers(0) |
| 28 , fNumGeometrySamplers(0) |
| 29 , fNumFragmentSamplers(0) { |
| 30 } |
| 31 |
| 32 void GrGLSLProgramBuilder::addFeature(GrShaderFlags shaders, |
| 33 uint32_t featureBit, |
| 34 const char* extensionName) { |
| 35 if (shaders & kVertex_GrShaderFlag) { |
| 36 fVS.addFeature(featureBit, extensionName); |
| 37 } |
| 38 if (shaders & kGeometry_GrShaderFlag) { |
| 39 SkASSERT(this->glslCaps()->geometryShaderSupport()); |
| 40 fGS.addFeature(featureBit, extensionName); |
| 41 } |
| 42 if (shaders & kFragment_GrShaderFlag) { |
| 43 fFS.addFeature(featureBit, extensionName); |
| 44 } |
26 } | 45 } |
27 | 46 |
28 bool GrGLSLProgramBuilder::emitAndInstallProcs(GrGLSLExpr4* inputColor, | 47 bool GrGLSLProgramBuilder::emitAndInstallProcs(GrGLSLExpr4* inputColor, |
29 GrGLSLExpr4* inputCoverage, | 48 GrGLSLExpr4* inputCoverage) { |
30 int maxTextures) { | |
31 // First we loop over all of the installed processors and collect coord tran
sforms. These will | 49 // First we loop over all of the installed processors and collect coord tran
sforms. These will |
32 // be sent to the GrGLSLPrimitiveProcessor in its emitCode function | 50 // be sent to the GrGLSLPrimitiveProcessor in its emitCode function |
33 const GrPrimitiveProcessor& primProc = this->primitiveProcessor(); | 51 const GrPrimitiveProcessor& primProc = this->primitiveProcessor(); |
34 int totalTextures = primProc.numTextures(); | |
35 | 52 |
36 for (int i = 0; i < this->pipeline().numFragmentProcessors(); i++) { | 53 for (int i = 0; i < this->pipeline().numFragmentProcessors(); i++) { |
37 const GrFragmentProcessor& processor = this->pipeline().getFragmentProce
ssor(i); | 54 const GrFragmentProcessor& processor = this->pipeline().getFragmentProce
ssor(i); |
38 | 55 |
39 if (!primProc.hasTransformedLocalCoords()) { | 56 if (!primProc.hasTransformedLocalCoords()) { |
40 SkTArray<const GrCoordTransform*, true>& procCoords = fCoordTransfor
ms.push_back(); | 57 SkTArray<const GrCoordTransform*, true>& procCoords = fCoordTransfor
ms.push_back(); |
41 processor.gatherCoordTransforms(&procCoords); | 58 processor.gatherCoordTransforms(&procCoords); |
42 } | 59 } |
43 | |
44 totalTextures += processor.numTextures(); | |
45 if (totalTextures >= maxTextures) { | |
46 GrCapsDebugf(this->caps(), "Program would use too many texture units
\n"); | |
47 return false; | |
48 } | |
49 } | 60 } |
50 | 61 |
51 this->emitAndInstallPrimProc(primProc, inputColor, inputCoverage); | 62 this->emitAndInstallPrimProc(primProc, inputColor, inputCoverage); |
52 | 63 |
53 int numProcs = this->pipeline().numFragmentProcessors(); | 64 int numProcs = this->pipeline().numFragmentProcessors(); |
54 this->emitAndInstallFragProcs(0, this->pipeline().numColorFragmentProcessors
(), inputColor); | 65 this->emitAndInstallFragProcs(0, this->pipeline().numColorFragmentProcessors
(), inputColor); |
55 this->emitAndInstallFragProcs(this->pipeline().numColorFragmentProcessors(),
numProcs, | 66 this->emitAndInstallFragProcs(this->pipeline().numColorFragmentProcessors(),
numProcs, |
56 inputCoverage); | 67 inputCoverage); |
57 if (primProc.getPixelLocalStorageState() != | 68 if (primProc.getPixelLocalStorageState() != |
58 GrPixelLocalStorageState::kDraw_GrPixelLocalStorageState) { | 69 GrPixelLocalStorageState::kDraw_GrPixelLocalStorageState) { |
59 this->emitAndInstallXferProc(this->pipeline().getXferProcessor(), *input
Color, | 70 this->emitAndInstallXferProc(this->pipeline().getXferProcessor(), *input
Color, |
60 *inputCoverage, this->pipeline().ignoresCov
erage(), | 71 *inputCoverage, this->pipeline().ignoresCov
erage(), |
61 primProc.getPixelLocalStorageState()); | 72 primProc.getPixelLocalStorageState()); |
62 this->emitFSOutputSwizzle(this->pipeline().getXferProcessor().hasSeconda
ryOutput()); | 73 this->emitFSOutputSwizzle(this->pipeline().getXferProcessor().hasSeconda
ryOutput()); |
63 } | 74 } |
64 return true; | 75 |
| 76 return this->checkSamplerCounts(); |
65 } | 77 } |
66 | 78 |
67 void GrGLSLProgramBuilder::emitAndInstallPrimProc(const GrPrimitiveProcessor& pr
oc, | 79 void GrGLSLProgramBuilder::emitAndInstallPrimProc(const GrPrimitiveProcessor& pr
oc, |
68 GrGLSLExpr4* outputColor, | 80 GrGLSLExpr4* outputColor, |
69 GrGLSLExpr4* outputCoverage) { | 81 GrGLSLExpr4* outputCoverage) { |
70 // Program builders have a bit of state we need to clear with each effect | 82 // Program builders have a bit of state we need to clear with each effect |
71 AutoStageAdvance adv(this); | 83 AutoStageAdvance adv(this); |
72 this->nameExpression(outputColor, "outputColor"); | 84 this->nameExpression(outputColor, "outputColor"); |
73 this->nameExpression(outputCoverage, "outputCoverage"); | 85 this->nameExpression(outputCoverage, "outputCoverage"); |
74 | 86 |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
191 samplers, | 203 samplers, |
192 usePLSDstRead); | 204 usePLSDstRead); |
193 fXferProcessor->emitCode(args); | 205 fXferProcessor->emitCode(args); |
194 | 206 |
195 // We have to check that effects and the code they emit are consistent, ie i
f an effect | 207 // We have to check that effects and the code they emit are consistent, ie i
f an effect |
196 // asks for dst color, then the emit code needs to follow suit | 208 // asks for dst color, then the emit code needs to follow suit |
197 SkDEBUGCODE(verify(xp);) | 209 SkDEBUGCODE(verify(xp);) |
198 fFS.codeAppend("}"); | 210 fFS.codeAppend("}"); |
199 } | 211 } |
200 | 212 |
| 213 void GrGLSLProgramBuilder::emitSamplers(const GrProcessor& processor, |
| 214 GrGLSLTextureSampler::TextureSamplerArra
y* outSamplers) { |
| 215 int numTextures = processor.numTextures(); |
| 216 UniformHandle* localSamplerUniforms = fSamplerUniforms.push_back_n(numTextur
es); |
| 217 SkString name; |
| 218 for (int t = 0; t < numTextures; ++t) { |
| 219 const GrTextureAccess& access = processor.textureAccess(t); |
| 220 GrShaderFlags visibility = access.getVisibility(); |
| 221 if (visibility & kVertex_GrShaderFlag) { |
| 222 ++fNumVertexSamplers; |
| 223 } |
| 224 if (visibility & kGeometry_GrShaderFlag) { |
| 225 SkASSERT(this->primitiveProcessor().willUseGeoShader()); |
| 226 ++fNumGeometrySamplers; |
| 227 } |
| 228 if (visibility & kFragment_GrShaderFlag) { |
| 229 ++fNumFragmentSamplers; |
| 230 } |
| 231 GrSLType samplerType = access.getTexture()->samplerType(); |
| 232 if (kSamplerExternal_GrSLType == samplerType) { |
| 233 const char* externalFeatureString = this->glslCaps()->externalTextur
eExtensionString(); |
| 234 // We shouldn't ever create a GrGLTexture that requires external sam
pler type |
| 235 SkASSERT(externalFeatureString); |
| 236 this->addFeature(visibility, |
| 237 1 << GrGLSLShaderBuilder::kExternalTexture_GLSLPriv
ateFeature, |
| 238 externalFeatureString); |
| 239 } |
| 240 name.printf("Sampler%d", t); |
| 241 localSamplerUniforms[t] = this->uniformHandler()->addUniform(access.getV
isibility(), |
| 242 samplerType
, |
| 243 kDefault_Gr
SLPrecision, |
| 244 name.c_str(
)); |
| 245 outSamplers->emplace_back(localSamplerUniforms[t], access); |
| 246 } |
| 247 } |
| 248 |
201 void GrGLSLProgramBuilder::emitFSOutputSwizzle(bool hasSecondaryOutput) { | 249 void GrGLSLProgramBuilder::emitFSOutputSwizzle(bool hasSecondaryOutput) { |
202 // Swizzle the fragment shader outputs if necessary. | 250 // Swizzle the fragment shader outputs if necessary. |
203 GrSwizzle swizzle; | 251 GrSwizzle swizzle; |
204 swizzle.setFromKey(this->desc().header().fOutputSwizzle); | 252 swizzle.setFromKey(this->desc().header().fOutputSwizzle); |
205 if (swizzle != GrSwizzle::RGBA()) { | 253 if (swizzle != GrSwizzle::RGBA()) { |
206 fFS.codeAppendf("%s = %s.%s;", fFS.getPrimaryColorOutputName(), | 254 fFS.codeAppendf("%s = %s.%s;", fFS.getPrimaryColorOutputName(), |
207 fFS.getPrimaryColorOutputName(), | 255 fFS.getPrimaryColorOutputName(), |
208 swizzle.c_str()); | 256 swizzle.c_str()); |
209 if (hasSecondaryOutput) { | 257 if (hasSecondaryOutput) { |
210 fFS.codeAppendf("%s = %s.%s;", fFS.getSecondaryColorOutputName(), | 258 fFS.codeAppendf("%s = %s.%s;", fFS.getSecondaryColorOutputName(), |
211 fFS.getSecondaryColorOutputName(), | 259 fFS.getSecondaryColorOutputName(), |
212 swizzle.c_str()); | 260 swizzle.c_str()); |
213 } | 261 } |
214 } | 262 } |
215 } | 263 } |
216 | 264 |
| 265 bool GrGLSLProgramBuilder::checkSamplerCounts() { |
| 266 const GrGLSLCaps& glslCaps = *this->glslCaps(); |
| 267 if (fNumVertexSamplers > glslCaps.maxVertexSamplers()) { |
| 268 GrCapsDebugf(this->caps(), "Program would use too many vertex samplers\n
"); |
| 269 return false; |
| 270 } |
| 271 if (fNumGeometrySamplers > glslCaps.maxGeometrySamplers()) { |
| 272 GrCapsDebugf(this->caps(), "Program would use too many geometry samplers
\n"); |
| 273 return false; |
| 274 } |
| 275 if (fNumFragmentSamplers > glslCaps.maxFragmentSamplers()) { |
| 276 GrCapsDebugf(this->caps(), "Program would use too many fragment samplers
\n"); |
| 277 return false; |
| 278 } |
| 279 // If the same sampler is used in two different shaders, it counts as two co
mbined samplers. |
| 280 int numCombinedSamplers = fNumVertexSamplers + fNumGeometrySamplers + fNumFr
agmentSamplers; |
| 281 if (numCombinedSamplers > glslCaps.maxCombinedSamplers()) { |
| 282 GrCapsDebugf(this->caps(), "Program would use too many combined samplers
\n"); |
| 283 return false; |
| 284 } |
| 285 return true; |
| 286 } |
| 287 |
217 #ifdef SK_DEBUG | 288 #ifdef SK_DEBUG |
218 void GrGLSLProgramBuilder::verify(const GrPrimitiveProcessor& gp) { | 289 void GrGLSLProgramBuilder::verify(const GrPrimitiveProcessor& gp) { |
219 SkASSERT(fFS.usedProcessorFeatures() == gp.requiredFeatures()); | 290 SkASSERT(fFS.usedProcessorFeatures() == gp.requiredFeatures()); |
220 } | 291 } |
221 | 292 |
222 void GrGLSLProgramBuilder::verify(const GrXferProcessor& xp) { | 293 void GrGLSLProgramBuilder::verify(const GrXferProcessor& xp) { |
223 SkASSERT(fFS.usedProcessorFeatures() == xp.requiredFeatures()); | 294 SkASSERT(fFS.usedProcessorFeatures() == xp.requiredFeatures()); |
224 SkASSERT(fFS.hasReadDstColor() == xp.willReadDstColor()); | 295 SkASSERT(fFS.hasReadDstColor() == xp.willReadDstColor()); |
225 } | 296 } |
226 | 297 |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
288 delete fFragmentProcessors[i]; | 359 delete fFragmentProcessors[i]; |
289 } | 360 } |
290 } | 361 } |
291 | 362 |
292 void GrGLSLProgramBuilder::finalizeShaders() { | 363 void GrGLSLProgramBuilder::finalizeShaders() { |
293 this->varyingHandler()->finalize(); | 364 this->varyingHandler()->finalize(); |
294 fVS.finalize(kVertex_GrShaderFlag); | 365 fVS.finalize(kVertex_GrShaderFlag); |
295 fFS.finalize(kFragment_GrShaderFlag); | 366 fFS.finalize(kFragment_GrShaderFlag); |
296 | 367 |
297 } | 368 } |
OLD | NEW |