1 /* 2 * Copyright 2015 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "glsl/GrGLSLProgramBuilder.h" 9 10 #include "GrCaps.h" 11 #include "GrPipeline.h" 12 #include "GrShaderCaps.h" 13 #include "GrTexturePriv.h" 14 #include "glsl/GrGLSLFragmentProcessor.h" 15 #include "glsl/GrGLSLGeometryProcessor.h" 16 #include "glsl/GrGLSLVarying.h" 17 #include "glsl/GrGLSLXferProcessor.h" 18 19 const int GrGLSLProgramBuilder::kVarsPerBlock = 8; 20 21 GrGLSLProgramBuilder::GrGLSLProgramBuilder(const GrPipeline& pipeline, 22 const GrPrimitiveProcessor& primProc, 23 GrProgramDesc* desc) 24 : fVS(this) 25 , fGS(this) 26 , fFS(this) 27 , fStageIndex(-1) 28 , fPipeline(pipeline) 29 , fPrimProc(primProc) 30 , fDesc(desc) 31 , fGeometryProcessor(nullptr) 32 , fXferProcessor(nullptr) 33 , fNumVertexSamplers(0) 34 , fNumGeometrySamplers(0) 35 , fNumFragmentSamplers(0) 36 , fNumVertexImageStorages(0) 37 , fNumGeometryImageStorages(0) 38 , fNumFragmentImageStorages(0) { 39 } 40 41 void GrGLSLProgramBuilder::addFeature(GrShaderFlags shaders, 42 uint32_t featureBit, 43 const char* extensionName) { 44 if (shaders & kVertex_GrShaderFlag) { 45 fVS.addFeature(featureBit, extensionName); 46 } 47 if (shaders & kGeometry_GrShaderFlag) { 48 SkASSERT(this->primitiveProcessor().willUseGeoShader()); 49 fGS.addFeature(featureBit, extensionName); 50 } 51 if (shaders & kFragment_GrShaderFlag) { 52 fFS.addFeature(featureBit, extensionName); 53 } 54 } 55 56 bool GrGLSLProgramBuilder::emitAndInstallProcs() { 57 // First we loop over all of the installed processors and collect coord transforms. These will 58 // be sent to the GrGLSLPrimitiveProcessor in its emitCode function 59 const GrPrimitiveProcessor& primProc = this->primitiveProcessor(); 60 61 SkString inputColor; 62 SkString inputCoverage; 63 this->emitAndInstallPrimProc(primProc, &inputColor, &inputCoverage); 64 this->emitAndInstallFragProcs(&inputColor, &inputCoverage); 65 this->emitAndInstallXferProc(inputColor, inputCoverage); 66 this->emitFSOutputSwizzle(this->pipeline().getXferProcessor().hasSecondaryOutput()); 67 68 return this->checkSamplerCounts() && this->checkImageStorageCounts(); 69 } 70 71 void GrGLSLProgramBuilder::emitAndInstallPrimProc(const GrPrimitiveProcessor& proc, 72 SkString* outputColor, 73 SkString* outputCoverage) { 74 // Program builders have a bit of state we need to clear with each effect 75 AutoStageAdvance adv(this); 76 this->nameExpression(outputColor, "outputColor"); 77 this->nameExpression(outputCoverage, "outputCoverage"); 78 79 SkASSERT(!fUniformHandles.fRTAdjustmentUni.isValid()); 80 GrShaderFlags rtAdjustVisibility = kVertex_GrShaderFlag; 81 if (proc.willUseGeoShader()) { 82 rtAdjustVisibility |= kGeometry_GrShaderFlag; 83 } 84 fUniformHandles.fRTAdjustmentUni = this->uniformHandler()->addUniform(rtAdjustVisibility, 85 kVec4f_GrSLType, 86 kHigh_GrSLPrecision, 87 "rtAdjustment"); 88 const char* rtAdjustName = 89 this->uniformHandler()->getUniformCStr(fUniformHandles.fRTAdjustmentUni); 90 91 // Enclose custom code in a block to avoid namespace conflicts 92 SkString openBrace; 93 openBrace.printf("{ // Stage %d, %s\n", fStageIndex, proc.name()); 94 fFS.codeAppend(openBrace.c_str()); 95 fVS.codeAppendf("// Primitive Processor %s\n", proc.name()); 96 97 SkASSERT(!fGeometryProcessor); 98 fGeometryProcessor = proc.createGLSLInstance(*this->shaderCaps()); 99 100 SkSTArray<4, SamplerHandle> texSamplers(proc.numTextureSamplers()); 101 SkSTArray<2, TexelBufferHandle> texelBuffers(proc.numBuffers()); 102 SkSTArray<2, ImageStorageHandle> imageStorages(proc.numImageStorages()); 103 this->emitSamplersAndImageStorages(proc, &texSamplers, &texelBuffers, &imageStorages); 104 105 GrGLSLPrimitiveProcessor::FPCoordTransformHandler transformHandler(fPipeline, 106 &fTransformedCoordVars); 107 GrGLSLGeometryProcessor::EmitArgs args(&fVS, 108 proc.willUseGeoShader() ? &fGS : nullptr, 109 &fFS, 110 this->varyingHandler(), 111 this->uniformHandler(), 112 this->shaderCaps(), 113 proc, 114 outputColor->c_str(), 115 outputCoverage->c_str(), 116 rtAdjustName, 117 texSamplers.begin(), 118 texelBuffers.begin(), 119 imageStorages.begin(), 120 &transformHandler); 121 fGeometryProcessor->emitCode(args); 122 123 // We have to check that effects and the code they emit are consistent, ie if an effect 124 // asks for dst color, then the emit code needs to follow suit 125 SkDEBUGCODE(verify(proc);) 126 127 fFS.codeAppend("}"); 128 } 129 130 void GrGLSLProgramBuilder::emitAndInstallFragProcs(SkString* color, SkString* coverage) { 131 int transformedCoordVarsIdx = 0; 132 SkString** inOut = &color; 133 for (int i = 0; i < this->pipeline().numFragmentProcessors(); ++i) { 134 if (i == this->pipeline().numColorFragmentProcessors()) { 135 inOut = &coverage; 136 } 137 SkString output; 138 const GrFragmentProcessor& fp = this->pipeline().getFragmentProcessor(i); 139 output = this->emitAndInstallFragProc(fp, i, transformedCoordVarsIdx, **inOut, output); 140 GrFragmentProcessor::Iter iter(&fp); 141 while (const GrFragmentProcessor* fp = iter.next()) { 142 transformedCoordVarsIdx += fp->numCoordTransforms(); 143 } 144 **inOut = output; 145 } 146 } 147 148 // TODO Processors cannot output zeros because an empty string is all 1s 149 // the fix is to allow effects to take the SkString directly 150 SkString GrGLSLProgramBuilder::emitAndInstallFragProc(const GrFragmentProcessor& fp, 151 int index, 152 int transformedCoordVarsIdx, 153 const SkString& input, 154 SkString output) { 155 SkASSERT(input.size()); 156 // Program builders have a bit of state we need to clear with each effect 157 AutoStageAdvance adv(this); 158 this->nameExpression(&output, "output"); 159 160 // Enclose custom code in a block to avoid namespace conflicts 161 SkString openBrace; 162 openBrace.printf("{ // Stage %d, %s\n", fStageIndex, fp.name()); 163 fFS.codeAppend(openBrace.c_str()); 164 165 GrGLSLFragmentProcessor* fragProc = fp.createGLSLInstance(); 166 167 SkSTArray<4, SamplerHandle> textureSamplerArray(fp.numTextureSamplers()); 168 SkSTArray<2, TexelBufferHandle> texelBufferArray(fp.numBuffers()); 169 SkSTArray<2, ImageStorageHandle> imageStorageArray(fp.numImageStorages()); 170 GrFragmentProcessor::Iter iter(&fp); 171 while (const GrFragmentProcessor* subFP = iter.next()) { 172 this->emitSamplersAndImageStorages(*subFP, &textureSamplerArray, &texelBufferArray, 173 &imageStorageArray); 174 } 175 176 const GrShaderVar* coordVars = fTransformedCoordVars.begin() + transformedCoordVarsIdx; 177 GrGLSLFragmentProcessor::TransformedCoordVars coords(&fp, coordVars); 178 GrGLSLFragmentProcessor::TextureSamplers textureSamplers(&fp, textureSamplerArray.begin()); 179 GrGLSLFragmentProcessor::TexelBuffers texelBuffers(&fp, texelBufferArray.begin()); 180 GrGLSLFragmentProcessor::ImageStorages imageStorages(&fp, imageStorageArray.begin()); 181 GrGLSLFragmentProcessor::EmitArgs args(&fFS, 182 this->uniformHandler(), 183 this->shaderCaps(), 184 fp, 185 output.c_str(), 186 input.c_str(), 187 coords, 188 textureSamplers, 189 texelBuffers, 190 imageStorages); 191 192 fragProc->emitCode(args); 193 194 // We have to check that effects and the code they emit are consistent, ie if an effect 195 // asks for dst color, then the emit code needs to follow suit 196 SkDEBUGCODE(verify(fp);) 197 fFragmentProcessors.push_back(fragProc); 198 199 fFS.codeAppend("}"); 200 return output; 201 } 202 203 void GrGLSLProgramBuilder::emitAndInstallXferProc(const SkString& colorIn, 204 const SkString& coverageIn) { 205 // Program builders have a bit of state we need to clear with each effect 206 AutoStageAdvance adv(this); 207 208 SkASSERT(!fXferProcessor); 209 const GrXferProcessor& xp = fPipeline.getXferProcessor(); 210 fXferProcessor = xp.createGLSLInstance(); 211 212 // Enable dual source secondary output if we have one 213 if (xp.hasSecondaryOutput()) { 214 fFS.enableSecondaryOutput(); 215 } 216 217 if (this->shaderCaps()->mustDeclareFragmentShaderOutput()) { 218 fFS.enableCustomOutput(); 219 } 220 221 SkString openBrace; 222 openBrace.printf("{ // Xfer Processor: %s\n", xp.name()); 223 fFS.codeAppend(openBrace.c_str()); 224 225 SamplerHandle dstTextureSamplerHandle; 226 GrSurfaceOrigin dstTextureOrigin = kTopLeft_GrSurfaceOrigin; 227 228 if (GrTexture* dstTexture = fPipeline.peekDstTexture()) { 229 // GrProcessor::TextureSampler sampler(dstTexture); 230 SkString name("DstTextureSampler"); 231 dstTextureSamplerHandle = 232 this->emitSampler(dstTexture->texturePriv().samplerType(), dstTexture->config(), 233 "DstTextureSampler", kFragment_GrShaderFlag); 234 dstTextureOrigin = dstTexture->origin(); 235 SkASSERT(kTextureExternalSampler_GrSLType != dstTexture->texturePriv().samplerType()); 236 } 237 238 GrGLSLXferProcessor::EmitArgs args(&fFS, 239 this->uniformHandler(), 240 this->shaderCaps(), 241 xp, 242 colorIn.size() ? colorIn.c_str() : "vec4(1)", 243 coverageIn.size() ? coverageIn.c_str() : "vec4(1)", 244 fFS.getPrimaryColorOutputName(), 245 fFS.getSecondaryColorOutputName(), 246 dstTextureSamplerHandle, 247 dstTextureOrigin); 248 fXferProcessor->emitCode(args); 249 250 // We have to check that effects and the code they emit are consistent, ie if an effect 251 // asks for dst color, then the emit code needs to follow suit 252 SkDEBUGCODE(verify(xp);) 253 fFS.codeAppend("}"); 254 } 255 256 void GrGLSLProgramBuilder::emitSamplersAndImageStorages( 257 const GrResourceIOProcessor& processor, 258 SkTArray<SamplerHandle>* outTexSamplerHandles, 259 SkTArray<TexelBufferHandle>* outTexelBufferHandles, 260 SkTArray<ImageStorageHandle>* outImageStorageHandles) { 261 SkString name; 262 int numTextureSamplers = processor.numTextureSamplers(); 263 for (int t = 0; t < numTextureSamplers; ++t) { 264 const GrResourceIOProcessor::TextureSampler& sampler = processor.textureSampler(t); 265 name.printf("TextureSampler_%d", outTexSamplerHandles->count()); 266 GrSLType samplerType = sampler.peekTexture()->texturePriv().samplerType(); 267 if (kTextureExternalSampler_GrSLType == samplerType) { 268 const char* externalFeatureString = 269 this->shaderCaps()->externalTextureExtensionString(); 270 // We shouldn't ever create a GrGLTexture that requires external sampler type 271 SkASSERT(externalFeatureString); 272 this->addFeature(sampler.visibility(), 273 1 << GrGLSLShaderBuilder::kExternalTexture_GLSLPrivateFeature, 274 externalFeatureString); 275 } 276 outTexSamplerHandles->emplace_back(this->emitSampler( 277 samplerType, sampler.peekTexture()->config(), name.c_str(), sampler.visibility())); 278 } 279 if (int numBuffers = processor.numBuffers()) { 280 SkASSERT(this->shaderCaps()->texelBufferSupport()); 281 GrShaderFlags texelBufferVisibility = kNone_GrShaderFlags; 282 283 for (int b = 0; b < numBuffers; ++b) { 284 const GrResourceIOProcessor::BufferAccess& access = processor.bufferAccess(b); 285 name.printf("TexelBuffer_%d", outTexelBufferHandles->count()); 286 outTexelBufferHandles->emplace_back( 287 this->emitTexelBuffer(access.texelConfig(), name.c_str(), access.visibility())); 288 texelBufferVisibility |= access.visibility(); 289 } 290 291 if (const char* extension = this->shaderCaps()->texelBufferExtensionString()) { 292 this->addFeature(texelBufferVisibility, 293 1 << GrGLSLShaderBuilder::kTexelBuffer_GLSLPrivateFeature, 294 extension); 295 } 296 } 297 int numImageStorages = processor.numImageStorages(); 298 for (int i = 0; i < numImageStorages; ++i) { 299 const GrResourceIOProcessor::ImageStorageAccess& imageStorageAccess = 300 processor.imageStorageAccess(i); 301 name.printf("Image_%d", outImageStorageHandles->count()); 302 outImageStorageHandles->emplace_back( 303 this->emitImageStorage(imageStorageAccess, name.c_str())); 304 } 305 } 306 307 void GrGLSLProgramBuilder::updateSamplerCounts(GrShaderFlags visibility) { 308 if (visibility & kVertex_GrShaderFlag) { 309 ++fNumVertexSamplers; 310 } 311 if (visibility & kGeometry_GrShaderFlag) { 312 SkASSERT(this->primitiveProcessor().willUseGeoShader()); 313 ++fNumGeometrySamplers; 314 } 315 if (visibility & kFragment_GrShaderFlag) { 316 ++fNumFragmentSamplers; 317 } 318 } 319 320 GrGLSLProgramBuilder::SamplerHandle GrGLSLProgramBuilder::emitSampler(GrSLType samplerType, 321 GrPixelConfig config, 322 const char* name, 323 GrShaderFlags visibility) { 324 this->updateSamplerCounts(visibility); 325 GrSLPrecision precision = this->shaderCaps()->samplerPrecision(config, visibility); 326 GrSwizzle swizzle = this->shaderCaps()->configTextureSwizzle(config); 327 return this->uniformHandler()->addSampler(visibility, swizzle, samplerType, precision, name); 328 } 329 330 GrGLSLProgramBuilder::TexelBufferHandle GrGLSLProgramBuilder::emitTexelBuffer( 331 GrPixelConfig config, const char* name, GrShaderFlags visibility) { 332 this->updateSamplerCounts(visibility); 333 GrSLPrecision precision = this->shaderCaps()->samplerPrecision(config, visibility); 334 return this->uniformHandler()->addTexelBuffer(visibility, precision, name); 335 } 336 337 GrGLSLProgramBuilder::ImageStorageHandle GrGLSLProgramBuilder::emitImageStorage( 338 const GrResourceIOProcessor::ImageStorageAccess& access, const char* name) { 339 if (access.visibility() & kVertex_GrShaderFlag) { 340 ++fNumVertexImageStorages; 341 } 342 if (access.visibility() & kGeometry_GrShaderFlag) { 343 SkASSERT(this->primitiveProcessor().willUseGeoShader()); 344 ++fNumGeometryImageStorages; 345 } 346 if (access.visibility() & kFragment_GrShaderFlag) { 347 ++fNumFragmentImageStorages; 348 } 349 GrSLType uniformType = access.proxy()->imageStorageType(); 350 return this->uniformHandler()->addImageStorage(access.visibility(), uniformType, 351 access.format(), access.memoryModel(), 352 access.restrict(), access.ioType(), name); 353 } 354 355 void GrGLSLProgramBuilder::emitFSOutputSwizzle(bool hasSecondaryOutput) { 356 // Swizzle the fragment shader outputs if necessary. 357 GrSwizzle swizzle; 358 swizzle.setFromKey(this->desc()->header().fOutputSwizzle); 359 if (swizzle != GrSwizzle::RGBA()) { 360 fFS.codeAppendf("%s = %s.%s;", fFS.getPrimaryColorOutputName(), 361 fFS.getPrimaryColorOutputName(), 362 swizzle.c_str()); 363 if (hasSecondaryOutput) { 364 fFS.codeAppendf("%s = %s.%s;", fFS.getSecondaryColorOutputName(), 365 fFS.getSecondaryColorOutputName(), 366 swizzle.c_str()); 367 } 368 } 369 } 370 371 bool GrGLSLProgramBuilder::checkSamplerCounts() { 372 const GrShaderCaps& shaderCaps = *this->shaderCaps(); 373 if (fNumVertexSamplers > shaderCaps.maxVertexSamplers()) { 374 GrCapsDebugf(this->caps(), "Program would use too many vertex samplers\n"); 375 return false; 376 } 377 if (fNumGeometrySamplers > shaderCaps.maxGeometrySamplers()) { 378 GrCapsDebugf(this->caps(), "Program would use too many geometry samplers\n"); 379 return false; 380 } 381 if (fNumFragmentSamplers > shaderCaps.maxFragmentSamplers()) { 382 GrCapsDebugf(this->caps(), "Program would use too many fragment samplers\n"); 383 return false; 384 } 385 // If the same sampler is used in two different shaders, it counts as two combined samplers. 386 int numCombinedSamplers = fNumVertexSamplers + fNumGeometrySamplers + fNumFragmentSamplers; 387 if (numCombinedSamplers > shaderCaps.maxCombinedSamplers()) { 388 GrCapsDebugf(this->caps(), "Program would use too many combined samplers\n"); 389 return false; 390 } 391 return true; 392 } 393 394 bool GrGLSLProgramBuilder::checkImageStorageCounts() { 395 const GrShaderCaps& shaderCaps = *this->shaderCaps(); 396 if (fNumVertexImageStorages > shaderCaps.maxVertexImageStorages()) { 397 GrCapsDebugf(this->caps(), "Program would use too many vertex images\n"); 398 return false; 399 } 400 if (fNumGeometryImageStorages > shaderCaps.maxGeometryImageStorages()) { 401 GrCapsDebugf(this->caps(), "Program would use too many geometry images\n"); 402 return false; 403 } 404 if (fNumFragmentImageStorages > shaderCaps.maxFragmentImageStorages()) { 405 GrCapsDebugf(this->caps(), "Program would use too many fragment images\n"); 406 return false; 407 } 408 // If the same image is used in two different shaders, it counts as two combined images. 409 int numCombinedImages = fNumVertexImageStorages + fNumGeometryImageStorages + 410 fNumFragmentImageStorages; 411 if (numCombinedImages > shaderCaps.maxCombinedImageStorages()) { 412 GrCapsDebugf(this->caps(), "Program would use too many combined images\n"); 413 return false; 414 } 415 return true; 416 } 417 418 #ifdef SK_DEBUG 419 void GrGLSLProgramBuilder::verify(const GrPrimitiveProcessor& gp) { 420 SkASSERT(fFS.usedProcessorFeatures() == gp.requiredFeatures()); 421 } 422 423 void GrGLSLProgramBuilder::verify(const GrXferProcessor& xp) { 424 SkASSERT(fFS.usedProcessorFeatures() == xp.requiredFeatures()); 425 SkASSERT(fFS.hasReadDstColor() == xp.willReadDstColor()); 426 } 427 428 void GrGLSLProgramBuilder::verify(const GrFragmentProcessor& fp) { 429 SkASSERT(fFS.usedProcessorFeatures() == fp.requiredFeatures()); 430 } 431 #endif 432 433 void GrGLSLProgramBuilder::nameVariable(SkString* out, char prefix, const char* name, bool mangle) { 434 if ('\0' == prefix) { 435 *out = name; 436 } else { 437 out->printf("%c%s", prefix, name); 438 } 439 if (mangle) { 440 if (out->endsWith('_')) { 441 // Names containing "__" are reserved. 442 out->append("x"); 443 } 444 out->appendf("_Stage%d%s", fStageIndex, fFS.getMangleString().c_str()); 445 } 446 } 447 448 void GrGLSLProgramBuilder::nameExpression(SkString* output, const char* baseName) { 449 // create var to hold stage result. If we already have a valid output name, just use that 450 // otherwise create a new mangled one. This name is only valid if we are reordering stages 451 // and have to tell stage exactly where to put its output. 452 SkString outName; 453 if (output->size()) { 454 outName = output->c_str(); 455 } else { 456 this->nameVariable(&outName, '\0', baseName); 457 } 458 fFS.codeAppendf("vec4 %s;", outName.c_str()); 459 *output = outName; 460 } 461 462 void GrGLSLProgramBuilder::appendUniformDecls(GrShaderFlags visibility, SkString* out) const { 463 this->uniformHandler()->appendUniformDecls(visibility, out); 464 } 465 466 void GrGLSLProgramBuilder::addRTHeightUniform(const char* name) { 467 SkASSERT(!fUniformHandles.fRTHeightUni.isValid()); 468 GrGLSLUniformHandler* uniformHandler = this->uniformHandler(); 469 fUniformHandles.fRTHeightUni = 470 uniformHandler->internalAddUniformArray(kFragment_GrShaderFlag, 471 kFloat_GrSLType, kDefault_GrSLPrecision, 472 name, false, 0, nullptr); 473 } 474 475 void GrGLSLProgramBuilder::cleanupFragmentProcessors() { 476 for (int i = 0; i < fFragmentProcessors.count(); ++i) { 477 delete fFragmentProcessors[i]; 478 } 479 } 480 481 void GrGLSLProgramBuilder::finalizeShaders() { 482 this->varyingHandler()->finalize(); 483 fVS.finalize(kVertex_GrShaderFlag); 484 if (this->primitiveProcessor().willUseGeoShader()) { 485 SkASSERT(this->shaderCaps()->geometryShaderSupport()); 486 fGS.finalize(kGeometry_GrShaderFlag); 487 } 488 fFS.finalize(kFragment_GrShaderFlag); 489 } 490