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