Shader.cpp (42625B)
1 // 2 // Copyright 2002 The ANGLE Project Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style license that can be 4 // found in the LICENSE file. 5 // 6 7 // Shader.cpp: Implements the gl::Shader class and its derived classes 8 // VertexShader and FragmentShader. Implements GL shader objects and related 9 // functionality. [OpenGL ES 2.0.24] section 2.10 page 24 and section 3.8 page 84. 10 11 #include "libANGLE/Shader.h" 12 13 #include <functional> 14 #include <sstream> 15 16 #include "GLSLANG/ShaderLang.h" 17 #include "common/utilities.h" 18 #include "libANGLE/Caps.h" 19 #include "libANGLE/Compiler.h" 20 #include "libANGLE/Constants.h" 21 #include "libANGLE/Context.h" 22 #include "libANGLE/Display.h" 23 #include "libANGLE/MemoryShaderCache.h" 24 #include "libANGLE/Program.h" 25 #include "libANGLE/ResourceManager.h" 26 #include "libANGLE/renderer/GLImplFactory.h" 27 #include "libANGLE/renderer/ShaderImpl.h" 28 #include "platform/FrontendFeatures_autogen.h" 29 30 namespace gl 31 { 32 33 namespace 34 { 35 constexpr uint32_t kShaderCacheIdentifier = 0x12345678; 36 37 template <typename VarT> 38 std::vector<VarT> GetActiveShaderVariables(const std::vector<VarT> *variableList) 39 { 40 ASSERT(variableList); 41 std::vector<VarT> result; 42 for (size_t varIndex = 0; varIndex < variableList->size(); varIndex++) 43 { 44 const VarT &var = variableList->at(varIndex); 45 if (var.active) 46 { 47 result.push_back(var); 48 } 49 } 50 return result; 51 } 52 53 template <typename VarT> 54 const std::vector<VarT> &GetShaderVariables(const std::vector<VarT> *variableList) 55 { 56 ASSERT(variableList); 57 return *variableList; 58 } 59 60 void WriteInterfaceBlock(gl::BinaryOutputStream *stream, const sh::InterfaceBlock &block) 61 { 62 stream->writeString(block.name); 63 stream->writeString(block.mappedName); 64 stream->writeString(block.instanceName); 65 stream->writeInt(block.arraySize); 66 stream->writeEnum(block.layout); 67 stream->writeBool(block.isRowMajorLayout); 68 stream->writeInt(block.binding); 69 stream->writeBool(block.staticUse); 70 stream->writeBool(block.active); 71 stream->writeEnum(block.blockType); 72 73 stream->writeInt(block.fields.size()); 74 for (const sh::ShaderVariable &shaderVariable : block.fields) 75 { 76 WriteShaderVar(stream, shaderVariable); 77 } 78 } 79 80 void LoadInterfaceBlock(gl::BinaryInputStream *stream, sh::InterfaceBlock &block) 81 { 82 stream->readString(&block.name); 83 stream->readString(&block.mappedName); 84 stream->readString(&block.instanceName); 85 stream->readInt(&block.arraySize); 86 stream->readEnum(&block.layout); 87 stream->readBool(&block.isRowMajorLayout); 88 stream->readInt(&block.binding); 89 stream->readBool(&block.staticUse); 90 stream->readBool(&block.active); 91 stream->readEnum(&block.blockType); 92 93 size_t size = stream->readInt<size_t>(); 94 block.fields.resize(size); 95 for (sh::ShaderVariable &shaderVariable : block.fields) 96 { 97 LoadShaderVar(stream, &shaderVariable); 98 } 99 } 100 } // anonymous namespace 101 102 // true if varying x has a higher priority in packing than y 103 bool CompareShaderVar(const sh::ShaderVariable &x, const sh::ShaderVariable &y) 104 { 105 if (x.type == y.type) 106 { 107 return x.getArraySizeProduct() > y.getArraySizeProduct(); 108 } 109 110 // Special case for handling structs: we sort these to the end of the list 111 if (x.type == GL_NONE) 112 { 113 return false; 114 } 115 116 if (y.type == GL_NONE) 117 { 118 return true; 119 } 120 121 return gl::VariableSortOrder(x.type) < gl::VariableSortOrder(y.type); 122 } 123 124 const char *GetShaderTypeString(ShaderType type) 125 { 126 switch (type) 127 { 128 case ShaderType::Vertex: 129 return "VERTEX"; 130 131 case ShaderType::Fragment: 132 return "FRAGMENT"; 133 134 case ShaderType::Compute: 135 return "COMPUTE"; 136 137 case ShaderType::Geometry: 138 return "GEOMETRY"; 139 140 case ShaderType::TessControl: 141 return "TESS_CONTROL"; 142 143 case ShaderType::TessEvaluation: 144 return "TESS_EVALUATION"; 145 146 default: 147 UNREACHABLE(); 148 return ""; 149 } 150 } 151 152 class [[nodiscard]] ScopedExit final : angle::NonCopyable 153 { 154 public: 155 ScopedExit(std::function<void()> exit) : mExit(exit) {} 156 ~ScopedExit() { mExit(); } 157 158 private: 159 std::function<void()> mExit; 160 }; 161 162 struct Shader::CompilingState 163 { 164 std::shared_ptr<rx::WaitableCompileEvent> compileEvent; 165 ShCompilerInstance shCompilerInstance; 166 egl::BlobCache::Key shaderHash; 167 }; 168 169 ShaderState::ShaderState(ShaderType shaderType) 170 : mLabel(), 171 mShaderType(shaderType), 172 mShaderVersion(100), 173 mNumViews(-1), 174 mGeometryShaderInvocations(1), 175 mCompileStatus(CompileStatus::NOT_COMPILED) 176 { 177 mLocalSize.fill(-1); 178 } 179 180 ShaderState::~ShaderState() {} 181 182 Shader::Shader(ShaderProgramManager *manager, 183 rx::GLImplFactory *implFactory, 184 const gl::Limitations &rendererLimitations, 185 ShaderType type, 186 ShaderProgramID handle) 187 : mState(type), 188 mImplementation(implFactory->createShader(mState)), 189 mRendererLimitations(rendererLimitations), 190 mHandle(handle), 191 mType(type), 192 mRefCount(0), 193 mDeleteStatus(false), 194 mResourceManager(manager), 195 mCurrentMaxComputeWorkGroupInvocations(0u) 196 { 197 ASSERT(mImplementation); 198 } 199 200 void Shader::onDestroy(const gl::Context *context) 201 { 202 resolveCompile(context); 203 mImplementation->destroy(); 204 mBoundCompiler.set(context, nullptr); 205 mImplementation.reset(nullptr); 206 delete this; 207 } 208 209 Shader::~Shader() 210 { 211 ASSERT(!mImplementation); 212 } 213 214 angle::Result Shader::setLabel(const Context *context, const std::string &label) 215 { 216 mState.mLabel = label; 217 218 if (mImplementation) 219 { 220 return mImplementation->onLabelUpdate(context); 221 } 222 return angle::Result::Continue; 223 } 224 225 const std::string &Shader::getLabel() const 226 { 227 return mState.mLabel; 228 } 229 230 ShaderProgramID Shader::getHandle() const 231 { 232 return mHandle; 233 } 234 235 void Shader::setSource(GLsizei count, const char *const *string, const GLint *length) 236 { 237 std::ostringstream stream; 238 239 for (int i = 0; i < count; i++) 240 { 241 if (length == nullptr || length[i] < 0) 242 { 243 stream.write(string[i], strlen(string[i])); 244 } 245 else 246 { 247 stream.write(string[i], length[i]); 248 } 249 } 250 251 mState.mSource = stream.str(); 252 } 253 254 int Shader::getInfoLogLength(const Context *context) 255 { 256 resolveCompile(context); 257 if (mInfoLog.empty()) 258 { 259 return 0; 260 } 261 262 return (static_cast<int>(mInfoLog.length()) + 1); 263 } 264 265 void Shader::getInfoLog(const Context *context, GLsizei bufSize, GLsizei *length, char *infoLog) 266 { 267 resolveCompile(context); 268 269 int index = 0; 270 271 if (bufSize > 0) 272 { 273 index = std::min(bufSize - 1, static_cast<GLsizei>(mInfoLog.length())); 274 memcpy(infoLog, mInfoLog.c_str(), index); 275 276 infoLog[index] = '\0'; 277 } 278 279 if (length) 280 { 281 *length = index; 282 } 283 } 284 285 int Shader::getSourceLength() const 286 { 287 return mState.mSource.empty() ? 0 : (static_cast<int>(mState.mSource.length()) + 1); 288 } 289 290 int Shader::getTranslatedSourceLength(const Context *context) 291 { 292 resolveCompile(context); 293 294 if (mState.mTranslatedSource.empty()) 295 { 296 return 0; 297 } 298 299 return (static_cast<int>(mState.mTranslatedSource.length()) + 1); 300 } 301 302 int Shader::getTranslatedSourceWithDebugInfoLength(const Context *context) 303 { 304 resolveCompile(context); 305 306 const std::string &debugInfo = mImplementation->getDebugInfo(); 307 if (debugInfo.empty()) 308 { 309 return 0; 310 } 311 312 return (static_cast<int>(debugInfo.length()) + 1); 313 } 314 315 // static 316 void Shader::GetSourceImpl(const std::string &source, 317 GLsizei bufSize, 318 GLsizei *length, 319 char *buffer) 320 { 321 int index = 0; 322 323 if (bufSize > 0) 324 { 325 index = std::min(bufSize - 1, static_cast<GLsizei>(source.length())); 326 memcpy(buffer, source.c_str(), index); 327 328 buffer[index] = '\0'; 329 } 330 331 if (length) 332 { 333 *length = index; 334 } 335 } 336 337 void Shader::getSource(GLsizei bufSize, GLsizei *length, char *buffer) const 338 { 339 GetSourceImpl(mState.mSource, bufSize, length, buffer); 340 } 341 342 void Shader::getTranslatedSource(const Context *context, 343 GLsizei bufSize, 344 GLsizei *length, 345 char *buffer) 346 { 347 GetSourceImpl(getTranslatedSource(context), bufSize, length, buffer); 348 } 349 350 const std::string &Shader::getTranslatedSource(const Context *context) 351 { 352 resolveCompile(context); 353 return mState.mTranslatedSource; 354 } 355 356 const sh::BinaryBlob &Shader::getCompiledBinary(const Context *context) 357 { 358 resolveCompile(context); 359 return mState.mCompiledBinary; 360 } 361 362 void Shader::getTranslatedSourceWithDebugInfo(const Context *context, 363 GLsizei bufSize, 364 GLsizei *length, 365 char *buffer) 366 { 367 resolveCompile(context); 368 const std::string &debugInfo = mImplementation->getDebugInfo(); 369 GetSourceImpl(debugInfo, bufSize, length, buffer); 370 } 371 372 void Shader::compile(const Context *context) 373 { 374 resolveCompile(context); 375 376 mState.mTranslatedSource.clear(); 377 mState.mCompiledBinary.clear(); 378 mInfoLog.clear(); 379 mState.mShaderVersion = 100; 380 mState.mInputVaryings.clear(); 381 mState.mOutputVaryings.clear(); 382 mState.mUniforms.clear(); 383 mState.mUniformBlocks.clear(); 384 mState.mShaderStorageBlocks.clear(); 385 mState.mActiveAttributes.clear(); 386 mState.mActiveOutputVariables.clear(); 387 mState.mNumViews = -1; 388 mState.mGeometryShaderInputPrimitiveType.reset(); 389 mState.mGeometryShaderOutputPrimitiveType.reset(); 390 mState.mGeometryShaderMaxVertices.reset(); 391 mState.mGeometryShaderInvocations = 1; 392 mState.mTessControlShaderVertices = 0; 393 mState.mTessGenMode = 0; 394 mState.mTessGenSpacing = 0; 395 mState.mTessGenVertexOrder = 0; 396 mState.mTessGenPointMode = 0; 397 mState.mAdvancedBlendEquations.reset(); 398 mState.mHasDiscard = false; 399 mState.mEnablesPerSampleShading = false; 400 mState.mSpecConstUsageBits.reset(); 401 402 mCurrentMaxComputeWorkGroupInvocations = 403 static_cast<GLuint>(context->getCaps().maxComputeWorkGroupInvocations); 404 mMaxComputeSharedMemory = context->getCaps().maxComputeSharedMemorySize; 405 406 ShCompileOptions options = {}; 407 options.objectCode = true; 408 options.variables = true; 409 options.emulateGLDrawID = true; 410 411 // Add default options to WebGL shaders to prevent unexpected behavior during 412 // compilation. 413 if (context->isWebGL()) 414 { 415 options.initGLPosition = true; 416 options.limitCallStackDepth = true; 417 options.limitExpressionComplexity = true; 418 options.enforcePackingRestrictions = true; 419 options.initSharedVariables = true; 420 } 421 else 422 { 423 // Per https://github.com/KhronosGroup/WebGL/pull/3278 gl_BaseVertex/gl_BaseInstance are 424 // removed from WebGL 425 options.emulateGLBaseVertexBaseInstance = true; 426 } 427 428 // Some targets (e.g. D3D11 Feature Level 9_3 and below) do not support non-constant loop 429 // indexes in fragment shaders. Shader compilation will fail. To provide a better error 430 // message we can instruct the compiler to pre-validate. 431 if (mRendererLimitations.shadersRequireIndexedLoopValidation) 432 { 433 options.validateLoopIndexing = true; 434 } 435 436 if (context->getFrontendFeatures().scalarizeVecAndMatConstructorArgs.enabled) 437 { 438 options.scalarizeVecAndMatConstructorArgs = true; 439 } 440 441 if (context->getFrontendFeatures().forceInitShaderVariables.enabled) 442 { 443 options.initOutputVariables = true; 444 options.initializeUninitializedLocals = true; 445 } 446 447 mBoundCompiler.set(context, context->getCompiler()); 448 449 ASSERT(mBoundCompiler.get()); 450 ShCompilerInstance compilerInstance = mBoundCompiler->getInstance(mState.mShaderType); 451 ShHandle compilerHandle = compilerInstance.getHandle(); 452 ASSERT(compilerHandle); 453 mCompilerResourcesString = compilerInstance.getBuiltinResourcesString(); 454 455 // Find a shader in Blob Cache 456 egl::BlobCache::Key shaderHash = {0}; 457 MemoryShaderCache *shaderCache = context->getMemoryShaderCache(); 458 if (shaderCache) 459 { 460 angle::Result cacheResult = 461 shaderCache->getShader(context, this, options, compilerInstance, &shaderHash); 462 463 if (cacheResult == angle::Result::Continue) 464 { 465 compilerInstance.destroy(); 466 return; 467 } 468 } 469 470 // Cache load failed, fall through normal compiling. 471 mState.mCompileStatus = CompileStatus::COMPILE_REQUESTED; 472 mCompilingState.reset(new CompilingState()); 473 mCompilingState->shCompilerInstance = std::move(compilerInstance); 474 mCompilingState->shaderHash = shaderHash; 475 mCompilingState->compileEvent = 476 mImplementation->compile(context, &(mCompilingState->shCompilerInstance), &options); 477 } 478 479 void Shader::resolveCompile(const Context *context) 480 { 481 if (!mState.compilePending()) 482 { 483 return; 484 } 485 486 ASSERT(mCompilingState.get()); 487 488 mCompilingState->compileEvent->wait(); 489 490 mInfoLog += mCompilingState->compileEvent->getInfoLog(); 491 492 ScopedExit exit([this]() { 493 mBoundCompiler->putInstance(std::move(mCompilingState->shCompilerInstance)); 494 mCompilingState->compileEvent.reset(); 495 mCompilingState.reset(); 496 }); 497 498 ShHandle compilerHandle = mCompilingState->shCompilerInstance.getHandle(); 499 if (!mCompilingState->compileEvent->getResult()) 500 { 501 mInfoLog += sh::GetInfoLog(compilerHandle); 502 INFO() << std::endl << mInfoLog; 503 mState.mCompileStatus = CompileStatus::NOT_COMPILED; 504 return; 505 } 506 507 const ShShaderOutput outputType = mCompilingState->shCompilerInstance.getShaderOutputType(); 508 const bool isBinaryOutput = 509 outputType == SH_SPIRV_VULKAN_OUTPUT || outputType == SH_SPIRV_METAL_OUTPUT; 510 511 if (isBinaryOutput) 512 { 513 mState.mCompiledBinary = sh::GetObjectBinaryBlob(compilerHandle); 514 } 515 else 516 { 517 mState.mTranslatedSource = sh::GetObjectCode(compilerHandle); 518 519 #if !defined(NDEBUG) 520 // Prefix translated shader with commented out un-translated shader. 521 // Useful in diagnostics tools which capture the shader source. 522 std::ostringstream shaderStream; 523 shaderStream << "// GLSL\n"; 524 shaderStream << "//\n"; 525 526 std::istringstream inputSourceStream(mState.mSource); 527 std::string line; 528 while (std::getline(inputSourceStream, line)) 529 { 530 // Remove null characters from the source line 531 line.erase(std::remove(line.begin(), line.end(), '\0'), line.end()); 532 533 shaderStream << "// " << line; 534 535 // glslang complains if a comment ends with backslash 536 if (!line.empty() && line.back() == '\\') 537 { 538 shaderStream << "\\"; 539 } 540 541 shaderStream << std::endl; 542 } 543 shaderStream << "\n\n"; 544 shaderStream << mState.mTranslatedSource; 545 mState.mTranslatedSource = shaderStream.str(); 546 #endif // !defined(NDEBUG) 547 } 548 549 // Gather the shader information 550 mState.mShaderVersion = sh::GetShaderVersion(compilerHandle); 551 552 mState.mUniforms = GetShaderVariables(sh::GetUniforms(compilerHandle)); 553 mState.mUniformBlocks = GetShaderVariables(sh::GetUniformBlocks(compilerHandle)); 554 mState.mShaderStorageBlocks = GetShaderVariables(sh::GetShaderStorageBlocks(compilerHandle)); 555 mState.mSpecConstUsageBits = 556 rx::SpecConstUsageBits(sh::GetShaderSpecConstUsageBits(compilerHandle)); 557 558 switch (mState.mShaderType) 559 { 560 case ShaderType::Compute: 561 { 562 mState.mAllAttributes = GetShaderVariables(sh::GetAttributes(compilerHandle)); 563 mState.mActiveAttributes = GetActiveShaderVariables(&mState.mAllAttributes); 564 mState.mLocalSize = sh::GetComputeShaderLocalGroupSize(compilerHandle); 565 if (mState.mLocalSize.isDeclared()) 566 { 567 angle::CheckedNumeric<uint32_t> checked_local_size_product(mState.mLocalSize[0]); 568 checked_local_size_product *= mState.mLocalSize[1]; 569 checked_local_size_product *= mState.mLocalSize[2]; 570 571 if (!checked_local_size_product.IsValid()) 572 { 573 WARN() << std::endl 574 << "Integer overflow when computing the product of local_size_x, " 575 << "local_size_y and local_size_z."; 576 mState.mCompileStatus = CompileStatus::NOT_COMPILED; 577 return; 578 } 579 if (checked_local_size_product.ValueOrDie() > 580 mCurrentMaxComputeWorkGroupInvocations) 581 { 582 WARN() << std::endl 583 << "The total number of invocations within a work group exceeds " 584 << "MAX_COMPUTE_WORK_GROUP_INVOCATIONS."; 585 mState.mCompileStatus = CompileStatus::NOT_COMPILED; 586 return; 587 } 588 } 589 590 unsigned int sharedMemSize = sh::GetShaderSharedMemorySize(compilerHandle); 591 if (sharedMemSize > mMaxComputeSharedMemory) 592 { 593 WARN() << std::endl << "Exceeded maximum shared memory size"; 594 mState.mCompileStatus = CompileStatus::NOT_COMPILED; 595 return; 596 } 597 break; 598 } 599 case ShaderType::Vertex: 600 { 601 mState.mOutputVaryings = GetShaderVariables(sh::GetOutputVaryings(compilerHandle)); 602 mState.mAllAttributes = GetShaderVariables(sh::GetAttributes(compilerHandle)); 603 mState.mActiveAttributes = GetActiveShaderVariables(&mState.mAllAttributes); 604 mState.mNumViews = sh::GetVertexShaderNumViews(compilerHandle); 605 break; 606 } 607 case ShaderType::Fragment: 608 { 609 mState.mAllAttributes = GetShaderVariables(sh::GetAttributes(compilerHandle)); 610 mState.mActiveAttributes = GetActiveShaderVariables(&mState.mAllAttributes); 611 mState.mInputVaryings = GetShaderVariables(sh::GetInputVaryings(compilerHandle)); 612 // TODO(jmadill): Figure out why we only sort in the FS, and if we need to. 613 std::sort(mState.mInputVaryings.begin(), mState.mInputVaryings.end(), CompareShaderVar); 614 mState.mActiveOutputVariables = 615 GetActiveShaderVariables(sh::GetOutputVariables(compilerHandle)); 616 mState.mHasDiscard = sh::HasDiscardInFragmentShader(compilerHandle); 617 mState.mEnablesPerSampleShading = sh::EnablesPerSampleShading(compilerHandle); 618 mState.mAdvancedBlendEquations = 619 BlendEquationBitSet(sh::GetAdvancedBlendEquations(compilerHandle)); 620 break; 621 } 622 case ShaderType::Geometry: 623 { 624 mState.mInputVaryings = GetShaderVariables(sh::GetInputVaryings(compilerHandle)); 625 mState.mOutputVaryings = GetShaderVariables(sh::GetOutputVaryings(compilerHandle)); 626 627 if (sh::HasValidGeometryShaderInputPrimitiveType(compilerHandle)) 628 { 629 mState.mGeometryShaderInputPrimitiveType = FromGLenum<PrimitiveMode>( 630 sh::GetGeometryShaderInputPrimitiveType(compilerHandle)); 631 } 632 if (sh::HasValidGeometryShaderOutputPrimitiveType(compilerHandle)) 633 { 634 mState.mGeometryShaderOutputPrimitiveType = FromGLenum<PrimitiveMode>( 635 sh::GetGeometryShaderOutputPrimitiveType(compilerHandle)); 636 } 637 if (sh::HasValidGeometryShaderMaxVertices(compilerHandle)) 638 { 639 mState.mGeometryShaderMaxVertices = 640 sh::GetGeometryShaderMaxVertices(compilerHandle); 641 } 642 mState.mGeometryShaderInvocations = sh::GetGeometryShaderInvocations(compilerHandle); 643 break; 644 } 645 case ShaderType::TessControl: 646 { 647 mState.mInputVaryings = GetShaderVariables(sh::GetInputVaryings(compilerHandle)); 648 mState.mOutputVaryings = GetShaderVariables(sh::GetOutputVaryings(compilerHandle)); 649 mState.mTessControlShaderVertices = sh::GetTessControlShaderVertices(compilerHandle); 650 break; 651 } 652 case ShaderType::TessEvaluation: 653 { 654 mState.mInputVaryings = GetShaderVariables(sh::GetInputVaryings(compilerHandle)); 655 mState.mOutputVaryings = GetShaderVariables(sh::GetOutputVaryings(compilerHandle)); 656 if (sh::HasValidTessGenMode(compilerHandle)) 657 { 658 mState.mTessGenMode = sh::GetTessGenMode(compilerHandle); 659 } 660 if (sh::HasValidTessGenSpacing(compilerHandle)) 661 { 662 mState.mTessGenSpacing = sh::GetTessGenSpacing(compilerHandle); 663 } 664 if (sh::HasValidTessGenVertexOrder(compilerHandle)) 665 { 666 mState.mTessGenVertexOrder = sh::GetTessGenVertexOrder(compilerHandle); 667 } 668 if (sh::HasValidTessGenPointMode(compilerHandle)) 669 { 670 mState.mTessGenPointMode = sh::GetTessGenPointMode(compilerHandle); 671 } 672 break; 673 } 674 675 default: 676 UNREACHABLE(); 677 } 678 679 ASSERT(!mState.mTranslatedSource.empty() || !mState.mCompiledBinary.empty()); 680 681 bool success = mCompilingState->compileEvent->postTranslate(&mInfoLog); 682 mState.mCompileStatus = success ? CompileStatus::COMPILED : CompileStatus::NOT_COMPILED; 683 684 MemoryShaderCache *shaderCache = context->getMemoryShaderCache(); 685 if (success && shaderCache) 686 { 687 // Save to the shader cache. 688 if (shaderCache->putShader(context, mCompilingState->shaderHash, this) != 689 angle::Result::Continue) 690 { 691 ANGLE_PERF_WARNING(context->getState().getDebug(), GL_DEBUG_SEVERITY_LOW, 692 "Failed to save compiled shader to memory shader cache."); 693 } 694 } 695 } 696 697 void Shader::addRef() 698 { 699 mRefCount++; 700 } 701 702 void Shader::release(const Context *context) 703 { 704 mRefCount--; 705 706 if (mRefCount == 0 && mDeleteStatus) 707 { 708 mResourceManager->deleteShader(context, mHandle); 709 } 710 } 711 712 unsigned int Shader::getRefCount() const 713 { 714 return mRefCount; 715 } 716 717 bool Shader::isFlaggedForDeletion() const 718 { 719 return mDeleteStatus; 720 } 721 722 void Shader::flagForDeletion() 723 { 724 mDeleteStatus = true; 725 } 726 727 bool Shader::isCompiled(const Context *context) 728 { 729 resolveCompile(context); 730 return mState.mCompileStatus == CompileStatus::COMPILED; 731 } 732 733 bool Shader::isCompleted() 734 { 735 return (!mState.compilePending() || mCompilingState->compileEvent->isReady()); 736 } 737 738 int Shader::getShaderVersion(const Context *context) 739 { 740 resolveCompile(context); 741 return mState.mShaderVersion; 742 } 743 744 const std::vector<sh::ShaderVariable> &Shader::getInputVaryings(const Context *context) 745 { 746 resolveCompile(context); 747 return mState.getInputVaryings(); 748 } 749 750 const std::vector<sh::ShaderVariable> &Shader::getOutputVaryings(const Context *context) 751 { 752 resolveCompile(context); 753 return mState.getOutputVaryings(); 754 } 755 756 const std::vector<sh::ShaderVariable> &Shader::getUniforms(const Context *context) 757 { 758 resolveCompile(context); 759 return mState.getUniforms(); 760 } 761 762 const std::vector<sh::InterfaceBlock> &Shader::getUniformBlocks(const Context *context) 763 { 764 resolveCompile(context); 765 return mState.getUniformBlocks(); 766 } 767 768 const std::vector<sh::InterfaceBlock> &Shader::getShaderStorageBlocks(const Context *context) 769 { 770 resolveCompile(context); 771 return mState.getShaderStorageBlocks(); 772 } 773 774 const std::vector<sh::ShaderVariable> &Shader::getActiveAttributes(const Context *context) 775 { 776 resolveCompile(context); 777 return mState.getActiveAttributes(); 778 } 779 780 const std::vector<sh::ShaderVariable> &Shader::getAllAttributes(const Context *context) 781 { 782 resolveCompile(context); 783 return mState.getAllAttributes(); 784 } 785 786 const std::vector<sh::ShaderVariable> &Shader::getActiveOutputVariables(const Context *context) 787 { 788 resolveCompile(context); 789 return mState.getActiveOutputVariables(); 790 } 791 792 std::string Shader::getTransformFeedbackVaryingMappedName(const Context *context, 793 const std::string &tfVaryingName) 794 { 795 ASSERT(mState.getShaderType() != ShaderType::Fragment && 796 mState.getShaderType() != ShaderType::Compute); 797 const auto &varyings = getOutputVaryings(context); 798 auto bracketPos = tfVaryingName.find("["); 799 if (bracketPos != std::string::npos) 800 { 801 auto tfVaryingBaseName = tfVaryingName.substr(0, bracketPos); 802 for (const auto &varying : varyings) 803 { 804 if (varying.name == tfVaryingBaseName) 805 { 806 std::string mappedNameWithArrayIndex = 807 varying.mappedName + tfVaryingName.substr(bracketPos); 808 return mappedNameWithArrayIndex; 809 } 810 } 811 } 812 else 813 { 814 for (const auto &varying : varyings) 815 { 816 if (varying.name == tfVaryingName) 817 { 818 return varying.mappedName; 819 } 820 else if (varying.isStruct()) 821 { 822 GLuint fieldIndex = 0; 823 const auto *field = varying.findField(tfVaryingName, &fieldIndex); 824 if (field == nullptr) 825 { 826 continue; 827 } 828 ASSERT(field != nullptr && !field->isStruct() && 829 (!field->isArray() || varying.isShaderIOBlock)); 830 std::string mappedName; 831 // If it's an I/O block without an instance name, don't include the block name. 832 if (!varying.isShaderIOBlock || !varying.name.empty()) 833 { 834 mappedName = varying.isShaderIOBlock ? varying.mappedStructOrBlockName 835 : varying.mappedName; 836 mappedName += '.'; 837 } 838 return mappedName + field->mappedName; 839 } 840 } 841 } 842 UNREACHABLE(); 843 return std::string(); 844 } 845 846 const sh::WorkGroupSize &Shader::getWorkGroupSize(const Context *context) 847 { 848 resolveCompile(context); 849 return mState.mLocalSize; 850 } 851 852 int Shader::getNumViews(const Context *context) 853 { 854 resolveCompile(context); 855 return mState.mNumViews; 856 } 857 858 Optional<PrimitiveMode> Shader::getGeometryShaderInputPrimitiveType(const Context *context) 859 { 860 resolveCompile(context); 861 return mState.mGeometryShaderInputPrimitiveType; 862 } 863 864 Optional<PrimitiveMode> Shader::getGeometryShaderOutputPrimitiveType(const Context *context) 865 { 866 resolveCompile(context); 867 return mState.mGeometryShaderOutputPrimitiveType; 868 } 869 870 int Shader::getGeometryShaderInvocations(const Context *context) 871 { 872 resolveCompile(context); 873 return mState.mGeometryShaderInvocations; 874 } 875 876 Optional<GLint> Shader::getGeometryShaderMaxVertices(const Context *context) 877 { 878 resolveCompile(context); 879 return mState.mGeometryShaderMaxVertices; 880 } 881 882 int Shader::getTessControlShaderVertices(const Context *context) 883 { 884 resolveCompile(context); 885 return mState.mTessControlShaderVertices; 886 } 887 888 GLenum Shader::getTessGenMode(const Context *context) 889 { 890 resolveCompile(context); 891 return mState.mTessGenMode; 892 } 893 894 GLenum Shader::getTessGenSpacing(const Context *context) 895 { 896 resolveCompile(context); 897 return mState.mTessGenSpacing; 898 } 899 900 GLenum Shader::getTessGenVertexOrder(const Context *context) 901 { 902 resolveCompile(context); 903 return mState.mTessGenVertexOrder; 904 } 905 906 GLenum Shader::getTessGenPointMode(const Context *context) 907 { 908 resolveCompile(context); 909 return mState.mTessGenPointMode; 910 } 911 912 const std::string &Shader::getCompilerResourcesString() const 913 { 914 return mCompilerResourcesString; 915 } 916 917 angle::Result Shader::serialize(const Context *context, angle::MemoryBuffer *binaryOut) const 918 { 919 BinaryOutputStream stream; 920 921 stream.writeInt(kShaderCacheIdentifier); 922 stream.writeString(mState.mLabel); 923 stream.writeInt(mState.mShaderVersion); 924 stream.writeString(mCompilerResourcesString); 925 926 stream.writeInt(mState.mUniforms.size()); 927 for (const sh::ShaderVariable &shaderVariable : mState.mUniforms) 928 { 929 WriteShaderVar(&stream, shaderVariable); 930 } 931 932 stream.writeInt(mState.mUniformBlocks.size()); 933 for (const sh::InterfaceBlock &interfaceBlock : mState.mUniformBlocks) 934 { 935 WriteInterfaceBlock(&stream, interfaceBlock); 936 } 937 938 stream.writeInt(mState.mShaderStorageBlocks.size()); 939 for (const sh::InterfaceBlock &interfaceBlock : mState.mShaderStorageBlocks) 940 { 941 WriteInterfaceBlock(&stream, interfaceBlock); 942 } 943 944 stream.writeInt(mState.mSpecConstUsageBits.bits()); 945 946 switch (mType) 947 { 948 case ShaderType::Compute: 949 { 950 stream.writeInt(mState.mAllAttributes.size()); 951 for (const sh::ShaderVariable &shaderVariable : mState.mAllAttributes) 952 { 953 WriteShaderVar(&stream, shaderVariable); 954 } 955 stream.writeInt(mState.mActiveAttributes.size()); 956 for (const sh::ShaderVariable &shaderVariable : mState.mActiveAttributes) 957 { 958 WriteShaderVar(&stream, shaderVariable); 959 } 960 stream.writeInt(mState.mLocalSize[0]); 961 stream.writeInt(mState.mLocalSize[1]); 962 stream.writeInt(mState.mLocalSize[2]); 963 break; 964 } 965 966 case ShaderType::Vertex: 967 { 968 stream.writeInt(mState.mOutputVaryings.size()); 969 for (const sh::ShaderVariable &shaderVariable : mState.mOutputVaryings) 970 { 971 WriteShaderVar(&stream, shaderVariable); 972 } 973 stream.writeInt(mState.mAllAttributes.size()); 974 for (const sh::ShaderVariable &shaderVariable : mState.mAllAttributes) 975 { 976 WriteShaderVar(&stream, shaderVariable); 977 } 978 stream.writeInt(mState.mActiveAttributes.size()); 979 for (const sh::ShaderVariable &shaderVariable : mState.mActiveAttributes) 980 { 981 WriteShaderVar(&stream, shaderVariable); 982 } 983 stream.writeInt(mState.mNumViews); 984 break; 985 } 986 case ShaderType::Fragment: 987 { 988 stream.writeInt(mState.mInputVaryings.size()); 989 for (const sh::ShaderVariable &shaderVariable : mState.mInputVaryings) 990 { 991 WriteShaderVar(&stream, shaderVariable); 992 } 993 stream.writeInt(mState.mActiveOutputVariables.size()); 994 for (const sh::ShaderVariable &shaderVariable : mState.mActiveOutputVariables) 995 { 996 WriteShaderVar(&stream, shaderVariable); 997 } 998 stream.writeBool(mState.mEnablesPerSampleShading); 999 stream.writeInt(mState.mAdvancedBlendEquations.bits()); 1000 break; 1001 } 1002 case ShaderType::Geometry: 1003 { 1004 bool valid; 1005 1006 stream.writeInt(mState.mInputVaryings.size()); 1007 for (const sh::ShaderVariable &shaderVariable : mState.mInputVaryings) 1008 { 1009 WriteShaderVar(&stream, shaderVariable); 1010 } 1011 stream.writeInt(mState.mOutputVaryings.size()); 1012 for (const sh::ShaderVariable &shaderVariable : mState.mOutputVaryings) 1013 { 1014 WriteShaderVar(&stream, shaderVariable); 1015 } 1016 1017 valid = (bool)mState.mGeometryShaderInputPrimitiveType.valid(); 1018 stream.writeBool(valid); 1019 if (valid) 1020 { 1021 unsigned char value = 1022 (unsigned char)mState.mGeometryShaderInputPrimitiveType.value(); 1023 stream.writeBytes(&value, 1); 1024 } 1025 valid = (bool)mState.mGeometryShaderOutputPrimitiveType.valid(); 1026 stream.writeBool(valid); 1027 if (valid) 1028 { 1029 unsigned char value = 1030 (unsigned char)mState.mGeometryShaderOutputPrimitiveType.value(); 1031 stream.writeBytes(&value, 1); 1032 } 1033 valid = mState.mGeometryShaderMaxVertices.valid(); 1034 stream.writeBool(valid); 1035 if (valid) 1036 { 1037 int value = (int)mState.mGeometryShaderMaxVertices.value(); 1038 stream.writeInt(value); 1039 } 1040 1041 stream.writeInt(mState.mGeometryShaderInvocations); 1042 break; 1043 } 1044 case ShaderType::TessControl: 1045 { 1046 stream.writeInt(mState.mInputVaryings.size()); 1047 for (const sh::ShaderVariable &shaderVariable : mState.mInputVaryings) 1048 { 1049 WriteShaderVar(&stream, shaderVariable); 1050 } 1051 stream.writeInt(mState.mOutputVaryings.size()); 1052 for (const sh::ShaderVariable &shaderVariable : mState.mOutputVaryings) 1053 { 1054 WriteShaderVar(&stream, shaderVariable); 1055 } 1056 stream.writeInt(mState.mTessControlShaderVertices); 1057 break; 1058 } 1059 case ShaderType::TessEvaluation: 1060 { 1061 unsigned int value; 1062 1063 stream.writeInt(mState.mInputVaryings.size()); 1064 for (const sh::ShaderVariable &shaderVariable : mState.mInputVaryings) 1065 { 1066 WriteShaderVar(&stream, shaderVariable); 1067 } 1068 stream.writeInt(mState.mOutputVaryings.size()); 1069 for (const sh::ShaderVariable &shaderVariable : mState.mOutputVaryings) 1070 { 1071 WriteShaderVar(&stream, shaderVariable); 1072 } 1073 1074 value = (unsigned int)(mState.mTessGenMode); 1075 stream.writeInt(value); 1076 1077 value = (unsigned int)mState.mTessGenSpacing; 1078 stream.writeInt(value); 1079 1080 value = (unsigned int)mState.mTessGenVertexOrder; 1081 stream.writeInt(value); 1082 1083 value = (unsigned int)mState.mTessGenPointMode; 1084 stream.writeInt(value); 1085 break; 1086 } 1087 default: 1088 UNREACHABLE(); 1089 } 1090 1091 stream.writeIntVector(mState.mCompiledBinary); 1092 stream.writeEnum(mState.mCompileStatus); 1093 1094 ASSERT(binaryOut); 1095 if (!binaryOut->resize(stream.length())) 1096 { 1097 std::stringstream sstream; 1098 sstream << "Failed to allocate enough memory to serialize a shader. (" << stream.length() 1099 << " bytes )"; 1100 ANGLE_PERF_WARNING(context->getState().getDebug(), GL_DEBUG_SEVERITY_LOW, 1101 sstream.str().c_str()); 1102 return angle::Result::Incomplete; 1103 } 1104 1105 memcpy(binaryOut->data(), stream.data(), stream.length()); 1106 1107 return angle::Result::Continue; 1108 } 1109 1110 angle::Result Shader::deserialize(const Context *context, BinaryInputStream &stream) 1111 { 1112 size_t size; 1113 1114 if (stream.readInt<uint32_t>() != kShaderCacheIdentifier) 1115 { 1116 return angle::Result::Stop; 1117 } 1118 1119 stream.readString(&mState.mLabel); 1120 stream.readInt(&mState.mShaderVersion); 1121 stream.readString(&mCompilerResourcesString); 1122 1123 size = stream.readInt<size_t>(); 1124 mState.mUniforms.resize(size); 1125 for (sh::ShaderVariable &shaderVariable : mState.mUniforms) 1126 { 1127 LoadShaderVar(&stream, &shaderVariable); 1128 } 1129 1130 size = stream.readInt<size_t>(); 1131 mState.mUniformBlocks.resize(size); 1132 for (sh::InterfaceBlock &interfaceBlock : mState.mUniformBlocks) 1133 { 1134 LoadInterfaceBlock(&stream, interfaceBlock); 1135 } 1136 1137 size = stream.readInt<size_t>(); 1138 mState.mShaderStorageBlocks.resize(size); 1139 for (sh::InterfaceBlock &interfaceBlock : mState.mShaderStorageBlocks) 1140 { 1141 LoadInterfaceBlock(&stream, interfaceBlock); 1142 } 1143 1144 mState.mSpecConstUsageBits = rx::SpecConstUsageBits(stream.readInt<uint32_t>()); 1145 1146 switch (mType) 1147 { 1148 case ShaderType::Compute: 1149 { 1150 size = stream.readInt<size_t>(); 1151 mState.mAllAttributes.resize(size); 1152 for (sh::ShaderVariable &shaderVariable : mState.mAllAttributes) 1153 { 1154 LoadShaderVar(&stream, &shaderVariable); 1155 } 1156 size = stream.readInt<size_t>(); 1157 mState.mActiveAttributes.resize(size); 1158 for (sh::ShaderVariable &shaderVariable : mState.mActiveAttributes) 1159 { 1160 LoadShaderVar(&stream, &shaderVariable); 1161 } 1162 stream.readInt(&mState.mLocalSize[0]); 1163 stream.readInt(&mState.mLocalSize[1]); 1164 stream.readInt(&mState.mLocalSize[2]); 1165 break; 1166 } 1167 case ShaderType::Vertex: 1168 { 1169 size = stream.readInt<size_t>(); 1170 mState.mOutputVaryings.resize(size); 1171 for (sh::ShaderVariable &shaderVariable : mState.mOutputVaryings) 1172 { 1173 LoadShaderVar(&stream, &shaderVariable); 1174 } 1175 size = stream.readInt<size_t>(); 1176 mState.mAllAttributes.resize(size); 1177 for (sh::ShaderVariable &shaderVariable : mState.mAllAttributes) 1178 { 1179 LoadShaderVar(&stream, &shaderVariable); 1180 } 1181 size = stream.readInt<size_t>(); 1182 mState.mActiveAttributes.resize(size); 1183 for (sh::ShaderVariable &shaderVariable : mState.mActiveAttributes) 1184 { 1185 LoadShaderVar(&stream, &shaderVariable); 1186 } 1187 stream.readInt(&mState.mNumViews); 1188 break; 1189 } 1190 case ShaderType::Fragment: 1191 { 1192 size = stream.readInt<size_t>(); 1193 mState.mInputVaryings.resize(size); 1194 for (sh::ShaderVariable &shaderVariable : mState.mInputVaryings) 1195 { 1196 LoadShaderVar(&stream, &shaderVariable); 1197 } 1198 size = stream.readInt<size_t>(); 1199 mState.mActiveOutputVariables.resize(size); 1200 for (sh::ShaderVariable &shaderVariable : mState.mActiveOutputVariables) 1201 { 1202 LoadShaderVar(&stream, &shaderVariable); 1203 } 1204 stream.readBool(&mState.mEnablesPerSampleShading); 1205 int advancedBlendEquationBits; 1206 stream.readInt(&advancedBlendEquationBits); 1207 mState.mAdvancedBlendEquations = BlendEquationBitSet(advancedBlendEquationBits); 1208 break; 1209 } 1210 case ShaderType::Geometry: 1211 { 1212 bool valid; 1213 1214 size = stream.readInt<size_t>(); 1215 mState.mInputVaryings.resize(size); 1216 for (sh::ShaderVariable &shaderVariable : mState.mInputVaryings) 1217 { 1218 LoadShaderVar(&stream, &shaderVariable); 1219 } 1220 size = stream.readInt<size_t>(); 1221 mState.mOutputVaryings.resize(size); 1222 for (sh::ShaderVariable &shaderVariable : mState.mOutputVaryings) 1223 { 1224 LoadShaderVar(&stream, &shaderVariable); 1225 } 1226 1227 stream.readBool(&valid); 1228 if (valid) 1229 { 1230 unsigned char value; 1231 stream.readBytes(&value, 1); 1232 mState.mGeometryShaderInputPrimitiveType = static_cast<PrimitiveMode>(value); 1233 } 1234 else 1235 { 1236 mState.mGeometryShaderInputPrimitiveType.reset(); 1237 } 1238 1239 stream.readBool(&valid); 1240 if (valid) 1241 { 1242 unsigned char value; 1243 stream.readBytes(&value, 1); 1244 mState.mGeometryShaderOutputPrimitiveType = static_cast<PrimitiveMode>(value); 1245 } 1246 else 1247 { 1248 mState.mGeometryShaderOutputPrimitiveType.reset(); 1249 } 1250 1251 stream.readBool(&valid); 1252 if (valid) 1253 { 1254 int value; 1255 stream.readInt(&value); 1256 mState.mGeometryShaderMaxVertices = static_cast<GLint>(value); 1257 } 1258 else 1259 { 1260 mState.mGeometryShaderMaxVertices.reset(); 1261 } 1262 1263 stream.readInt(&mState.mGeometryShaderInvocations); 1264 break; 1265 } 1266 case ShaderType::TessControl: 1267 { 1268 size = stream.readInt<size_t>(); 1269 mState.mInputVaryings.resize(size); 1270 for (sh::ShaderVariable &shaderVariable : mState.mInputVaryings) 1271 { 1272 LoadShaderVar(&stream, &shaderVariable); 1273 } 1274 size = stream.readInt<size_t>(); 1275 mState.mOutputVaryings.resize(size); 1276 for (sh::ShaderVariable &shaderVariable : mState.mOutputVaryings) 1277 { 1278 LoadShaderVar(&stream, &shaderVariable); 1279 } 1280 stream.readInt(&mState.mTessControlShaderVertices); 1281 break; 1282 } 1283 case ShaderType::TessEvaluation: 1284 { 1285 unsigned int value; 1286 1287 size = stream.readInt<size_t>(); 1288 mState.mInputVaryings.resize(size); 1289 for (sh::ShaderVariable &shaderVariable : mState.mInputVaryings) 1290 { 1291 LoadShaderVar(&stream, &shaderVariable); 1292 } 1293 size = stream.readInt<size_t>(); 1294 mState.mOutputVaryings.resize(size); 1295 for (sh::ShaderVariable &shaderVariable : mState.mOutputVaryings) 1296 { 1297 LoadShaderVar(&stream, &shaderVariable); 1298 } 1299 1300 stream.readInt(&value); 1301 mState.mTessGenMode = (GLenum)value; 1302 1303 stream.readInt(&value); 1304 mState.mTessGenSpacing = (GLenum)value; 1305 1306 stream.readInt(&value); 1307 mState.mTessGenVertexOrder = (GLenum)value; 1308 1309 stream.readInt(&value); 1310 mState.mTessGenPointMode = (GLenum)value; 1311 break; 1312 } 1313 default: 1314 UNREACHABLE(); 1315 } 1316 1317 stream.readIntVector<unsigned int>(&mState.mCompiledBinary); 1318 mState.mCompileStatus = stream.readEnum<CompileStatus>(); 1319 1320 return angle::Result::Continue; 1321 } 1322 1323 angle::Result Shader::loadBinary(const Context *context, const void *binary, GLsizei length) 1324 { 1325 BinaryInputStream stream(binary, length); 1326 ANGLE_TRY(deserialize(context, stream)); 1327 1328 return angle::Result::Continue; 1329 } 1330 1331 } // namespace gl