SpecializationConstant.cpp (3950B)
1 // 2 // Copyright 2020 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 // SpecializationConst.cpp: Add code to generate AST node for various specialization constants. 7 // 8 9 #include "compiler/translator/tree_util/SpecializationConstant.h" 10 #include "common/PackedEnums.h" 11 #include "common/angleutils.h" 12 #include "compiler/translator/StaticType.h" 13 #include "compiler/translator/SymbolTable.h" 14 #include "compiler/translator/tree_util/IntermNode_util.h" 15 16 namespace sh 17 { 18 19 namespace 20 { 21 // Specialization constant names 22 constexpr ImmutableString kSurfaceRotationSpecConstVarName = 23 ImmutableString("ANGLESurfaceRotation"); 24 constexpr ImmutableString kDitherSpecConstVarName = ImmutableString("ANGLEDither"); 25 26 const TType *MakeSpecConst(const TType &type, vk::SpecializationConstantId id) 27 { 28 // Create a new type with the EvqSpecConst qualifier 29 TType *specConstType = new TType(type); 30 specConstType->setQualifier(EvqSpecConst); 31 32 // Set the constant_id of the spec const 33 TLayoutQualifier layoutQualifier = TLayoutQualifier::Create(); 34 layoutQualifier.location = static_cast<int>(id); 35 specConstType->setLayoutQualifier(layoutQualifier); 36 37 return specConstType; 38 } 39 } // anonymous namespace 40 41 SpecConst::SpecConst(TSymbolTable *symbolTable, 42 const ShCompileOptions &compileOptions, 43 GLenum shaderType) 44 : mSymbolTable(symbolTable), 45 mCompileOptions(compileOptions), 46 mSurfaceRotationVar(nullptr), 47 mDitherVar(nullptr) 48 { 49 if (shaderType == GL_FRAGMENT_SHADER || shaderType == GL_COMPUTE_SHADER) 50 { 51 return; 52 } 53 54 // Mark SpecConstUsage::Rotation unconditionally. gl_Position is always rotated. 55 if (mCompileOptions.useSpecializationConstant) 56 { 57 mUsageBits.set(vk::SpecConstUsage::Rotation); 58 } 59 } 60 61 SpecConst::~SpecConst() {} 62 63 void SpecConst::declareSpecConsts(TIntermBlock *root) 64 { 65 // Add specialization constant declarations. The default value of the specialization 66 // constant is irrelevant, as it will be set when creating the pipeline. 67 // Only emit specialized const declaration if it has been referenced. 68 if (mSurfaceRotationVar != nullptr) 69 { 70 TIntermDeclaration *decl = new TIntermDeclaration(); 71 decl->appendDeclarator( 72 new TIntermBinary(EOpInitialize, getRotation(), CreateBoolNode(false))); 73 74 root->insertStatement(0, decl); 75 } 76 77 if (mDitherVar != nullptr) 78 { 79 TIntermDeclaration *decl = new TIntermDeclaration(); 80 decl->appendDeclarator(new TIntermBinary(EOpInitialize, getDither(), CreateUIntNode(0))); 81 82 root->insertStatement(0, decl); 83 } 84 } 85 86 TIntermSymbol *SpecConst::getRotation() 87 { 88 if (mSurfaceRotationVar == nullptr) 89 { 90 const TType *type = MakeSpecConst(*StaticType::GetBasic<EbtBool, EbpUndefined>(), 91 vk::SpecializationConstantId::SurfaceRotation); 92 93 mSurfaceRotationVar = new TVariable(mSymbolTable, kSurfaceRotationSpecConstVarName, type, 94 SymbolType::AngleInternal); 95 } 96 return new TIntermSymbol(mSurfaceRotationVar); 97 } 98 99 TIntermTyped *SpecConst::getSwapXY() 100 { 101 if (!mCompileOptions.useSpecializationConstant) 102 { 103 return nullptr; 104 } 105 mUsageBits.set(vk::SpecConstUsage::Rotation); 106 return getRotation(); 107 } 108 109 TIntermTyped *SpecConst::getDither() 110 { 111 if (mDitherVar == nullptr) 112 { 113 const TType *type = MakeSpecConst(*StaticType::GetBasic<EbtUInt, EbpHigh>(), 114 vk::SpecializationConstantId::Dither); 115 116 mDitherVar = 117 new TVariable(mSymbolTable, kDitherSpecConstVarName, type, SymbolType::AngleInternal); 118 mUsageBits.set(vk::SpecConstUsage::Dither); 119 } 120 return new TIntermSymbol(mDitherVar); 121 } 122 } // namespace sh