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

Side by Side Diff: src/gpu/glsl/GrGLSLProgramBuilder.cpp

Issue 1782583002: Add support for vertex and geometry shader textures (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: better rebase 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/GrGLSLProgramBuilder.h ('k') | src/gpu/glsl/GrGLSLShaderBuilder.h » ('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 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
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
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 }
OLDNEW
« no previous file with comments | « src/gpu/glsl/GrGLSLProgramBuilder.h ('k') | src/gpu/glsl/GrGLSLShaderBuilder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698