xref: /aosp_15_r20/external/angle/src/compiler/translator/tree_util/SpecializationConstant.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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 
MakeSpecConst(const TType & type,vk::SpecializationConstantId id)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 
SpecConst(TSymbolTable * symbolTable,const ShCompileOptions & compileOptions,GLenum shaderType)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 
~SpecConst()61 SpecConst::~SpecConst() {}
62 
declareSpecConsts(TIntermBlock * root)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 
getRotation()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 
getSwapXY()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 
getDither()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
123