1 // 2 // Copyright 2010 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 #ifndef LIBANGLE_UNIFORM_H_ 8 #define LIBANGLE_UNIFORM_H_ 9 10 #include <string> 11 #include <vector> 12 13 #include "angle_gl.h" 14 #include "common/MemoryBuffer.h" 15 #include "common/debug.h" 16 #include "common/utilities.h" 17 #include "compiler/translator/blocklayout.h" 18 #include "libANGLE/angletypes.h" 19 20 namespace gl 21 { 22 class BinaryInputStream; 23 class BinaryOutputStream; 24 struct UniformTypeInfo; 25 struct UsedUniform; 26 27 // Note: keep this struct memcpy-able: i.e, a simple struct with basic types only and no virtual 28 // functions. LinkedUniform relies on this so that it can use memcpy to initialize uniform for 29 // performance. 30 struct ActiveVariable 31 { 32 ActiveVariable(); 33 ActiveVariable(const ActiveVariable &rhs); 34 ~ActiveVariable(); 35 36 ActiveVariable &operator=(const ActiveVariable &rhs); 37 getFirstActiveShaderTypeActiveVariable38 ShaderType getFirstActiveShaderType() const 39 { 40 return static_cast<ShaderType>(ScanForward(mActiveUseBits.bits())); 41 } 42 void setActive(ShaderType shaderType, bool used, uint32_t id); 43 void unionReferencesWith(const ActiveVariable &other); isActiveActiveVariable44 bool isActive(ShaderType shaderType) const 45 { 46 ASSERT(shaderType != ShaderType::InvalidEnum); 47 return mActiveUseBits[shaderType]; 48 } getIdsActiveVariable49 const ShaderMap<uint32_t> &getIds() const { return mIds; } getIdActiveVariable50 uint32_t getId(ShaderType shaderType) const { return mIds[shaderType]; } activeShadersActiveVariable51 ShaderBitSet activeShaders() const { return mActiveUseBits; } activeShaderCountActiveVariable52 GLuint activeShaderCount() const { return static_cast<GLuint>(mActiveUseBits.count()); } 53 54 private: 55 ShaderBitSet mActiveUseBits; 56 // The id of a linked variable in each shader stage. This id originates from 57 // sh::ShaderVariable::id or sh::InterfaceBlock::id 58 ShaderMap<uint32_t> mIds; 59 }; 60 61 // Helper struct representing a single shader uniform. Most of this structure's data member and 62 // access functions mirrors ShaderVariable; See ShaderVars.h for more info. 63 struct LinkedUniform 64 { 65 LinkedUniform(); 66 LinkedUniform(GLenum typeIn, 67 GLenum precisionIn, 68 const std::string &nameIn, 69 const std::vector<unsigned int> &arraySizesIn, 70 const int bindingIn, 71 const int offsetIn, 72 const int locationIn, 73 const int bufferIndexIn, 74 const sh::BlockMemberInfo &blockInfoIn); 75 LinkedUniform(const LinkedUniform &other); 76 LinkedUniform(const UsedUniform &usedUniform); 77 LinkedUniform &operator=(const LinkedUniform &other); 78 ~LinkedUniform(); 79 setBlockInfoLinkedUniform80 void setBlockInfo(int offset, int arrayStride, int matrixStride, bool isRowMajorMatrix) 81 { 82 mFixedSizeData.blockInfo.offset = offset; 83 mFixedSizeData.blockInfo.arrayStride = arrayStride; 84 mFixedSizeData.blockInfo.matrixStride = matrixStride; 85 mFixedSizeData.blockInfo.isRowMajorMatrix = isRowMajorMatrix; 86 } setBufferIndexLinkedUniform87 void setBufferIndex(int bufferIndex) { mFixedSizeData.bufferIndex = bufferIndex; } 88 isSamplerLinkedUniform89 bool isSampler() const { return typeInfo->isSampler; } isImageLinkedUniform90 bool isImage() const { return typeInfo->isImageType; } isAtomicCounterLinkedUniform91 bool isAtomicCounter() const { return IsAtomicCounterType(mFixedSizeData.type); } isInDefaultBlockLinkedUniform92 bool isInDefaultBlock() const { return mFixedSizeData.bufferIndex == -1; } getElementSizeLinkedUniform93 size_t getElementSize() const { return typeInfo->externalSize; } getElementComponentsLinkedUniform94 size_t getElementComponents() const { return typeInfo->componentCount; } 95 isStructLinkedUniform96 bool isStruct() const { return mFixedSizeData.flagBits.isStruct; } isTexelFetchStaticUseLinkedUniform97 bool isTexelFetchStaticUse() const { return mFixedSizeData.flagBits.texelFetchStaticUse; } isFragmentInOutLinkedUniform98 bool isFragmentInOut() const { return mFixedSizeData.flagBits.isFragmentInOut; } 99 isArrayOfArraysLinkedUniform100 bool isArrayOfArrays() const { return arraySizes.size() >= 2u; } isArrayLinkedUniform101 bool isArray() const { return !arraySizes.empty(); } getArraySizeProductLinkedUniform102 unsigned int getArraySizeProduct() const { return gl::ArraySizeProduct(arraySizes); } getOutermostArraySizeLinkedUniform103 unsigned int getOutermostArraySize() const { return isArray() ? arraySizes.back() : 0; } getBasicTypeElementCountLinkedUniform104 unsigned int getBasicTypeElementCount() const 105 { 106 ASSERT(!isArrayOfArrays()); 107 ASSERT(!isStruct() || !isArray()); 108 109 if (isArray()) 110 { 111 return getOutermostArraySize(); 112 } 113 return 1u; 114 } 115 getTypeLinkedUniform116 GLenum getType() const { return mFixedSizeData.type; } 117 unsigned int getExternalSize() const; getOuterArrayOffsetLinkedUniform118 unsigned int getOuterArrayOffset() const { return mFixedSizeData.outerArrayOffset; } getOuterArraySizeProductLinkedUniform119 unsigned int getOuterArraySizeProduct() const { return mFixedSizeData.outerArraySizeProduct; } getBindingLinkedUniform120 int getBinding() const { return mFixedSizeData.binding; } getOffsetLinkedUniform121 int getOffset() const { return mFixedSizeData.offset; } getBlockInfoLinkedUniform122 const sh::BlockMemberInfo &getBlockInfo() const { return mFixedSizeData.blockInfo; } getBufferIndexLinkedUniform123 int getBufferIndex() const { return mFixedSizeData.bufferIndex; } getLocationLinkedUniform124 int getLocation() const { return mFixedSizeData.location; } getImageUnitFormatLinkedUniform125 GLenum getImageUnitFormat() const { return mFixedSizeData.imageUnitFormat; } 126 127 bool findInfoByMappedName(const std::string &mappedFullName, 128 const sh::ShaderVariable **leafVar, 129 std::string *originalFullName) const; isBuiltInLinkedUniform130 bool isBuiltIn() const { return gl::IsBuiltInName(name); } 131 parentArrayIndexLinkedUniform132 int parentArrayIndex() const 133 { 134 return hasParentArrayIndex() ? mFixedSizeData.flattenedOffsetInParentArrays : 0; 135 } 136 hasParentArrayIndexLinkedUniform137 bool hasParentArrayIndex() const { return mFixedSizeData.flattenedOffsetInParentArrays != -1; } 138 bool isSameInterfaceBlockFieldAtLinkTime(const sh::ShaderVariable &other) const; 139 140 bool isSameVariableAtLinkTime(const sh::ShaderVariable &other, 141 bool matchPrecision, 142 bool matchName) const; 143 getFirstActiveShaderTypeLinkedUniform144 ShaderType getFirstActiveShaderType() const 145 { 146 return mFixedSizeData.activeVariable.getFirstActiveShaderType(); 147 } setActiveLinkedUniform148 void setActive(ShaderType shaderType, bool used, uint32_t _id) 149 { 150 mFixedSizeData.activeVariable.setActive(shaderType, used, _id); 151 } isActiveLinkedUniform152 bool isActive(ShaderType shaderType) const 153 { 154 return mFixedSizeData.activeVariable.isActive(shaderType); 155 } getIdsLinkedUniform156 const ShaderMap<uint32_t> &getIds() const { return mFixedSizeData.activeVariable.getIds(); } getIdLinkedUniform157 uint32_t getId(ShaderType shaderType) const 158 { 159 return mFixedSizeData.activeVariable.getId(shaderType); 160 } activeShadersLinkedUniform161 ShaderBitSet activeShaders() const { return mFixedSizeData.activeVariable.activeShaders(); } activeShaderCountLinkedUniform162 GLuint activeShaderCount() const { return mFixedSizeData.activeVariable.activeShaderCount(); } getActiveVariableLinkedUniform163 const ActiveVariable &getActiveVariable() const { return mFixedSizeData.activeVariable; } 164 165 void save(BinaryOutputStream *stream) const; 166 void load(BinaryInputStream *stream); 167 168 std::string name; 169 // Only used by GL backend 170 std::string mappedName; 171 172 std::vector<unsigned int> arraySizes; 173 174 const UniformTypeInfo *typeInfo; 175 176 private: 177 // Important: The fixed size data structure with fundamental data types only, so that we can 178 // initialize with memcpy. Do not put any std::vector or objects with virtual functions in it. 179 struct 180 { 181 GLenum type; 182 GLenum precision; 183 int location; 184 int binding; 185 GLenum imageUnitFormat; 186 int offset; 187 uint32_t id; 188 int flattenedOffsetInParentArrays; 189 int bufferIndex; 190 sh::BlockMemberInfo blockInfo; 191 unsigned int outerArraySizeProduct; 192 unsigned int outerArrayOffset; 193 ActiveVariable activeVariable; 194 195 union 196 { 197 struct 198 { 199 uint32_t staticUse : 1; 200 uint32_t active : 1; 201 uint32_t isStruct : 1; 202 uint32_t rasterOrdered : 1; 203 uint32_t readonly : 1; 204 uint32_t writeonly : 1; 205 uint32_t isFragmentInOut : 1; 206 uint32_t texelFetchStaticUse : 1; 207 uint32_t padding : 24; 208 } flagBits; 209 210 uint32_t flagBitsAsUInt; 211 }; 212 } mFixedSizeData; 213 }; 214 215 struct BufferVariable : public sh::ShaderVariable 216 { 217 BufferVariable(); 218 BufferVariable(GLenum type, 219 GLenum precision, 220 const std::string &name, 221 const std::vector<unsigned int> &arraySizes, 222 const int bufferIndex, 223 const sh::BlockMemberInfo &blockInfo); 224 ~BufferVariable(); 225 setActiveBufferVariable226 void setActive(ShaderType shaderType, bool used, uint32_t _id) 227 { 228 activeVariable.setActive(shaderType, used, _id); 229 } isActiveBufferVariable230 bool isActive(ShaderType shaderType) const { return activeVariable.isActive(shaderType); } getIdBufferVariable231 uint32_t getId(ShaderType shaderType) const { return activeVariable.getId(shaderType); } activeShadersBufferVariable232 ShaderBitSet activeShaders() const { return activeVariable.activeShaders(); } 233 234 ActiveVariable activeVariable; 235 int bufferIndex; 236 sh::BlockMemberInfo blockInfo; 237 238 int topLevelArraySize; 239 }; 240 241 // Parent struct for atomic counter, uniform block, and shader storage block buffer, which all 242 // contain a group of shader variables, and have a GL buffer backed. 243 struct ShaderVariableBuffer 244 { 245 ShaderVariableBuffer(); 246 ShaderVariableBuffer(const ShaderVariableBuffer &other); 247 ~ShaderVariableBuffer(); 248 getFirstActiveShaderTypeShaderVariableBuffer249 ShaderType getFirstActiveShaderType() const 250 { 251 return activeVariable.getFirstActiveShaderType(); 252 } setActiveShaderVariableBuffer253 void setActive(ShaderType shaderType, bool used, uint32_t _id) 254 { 255 activeVariable.setActive(shaderType, used, _id); 256 } unionReferencesWithShaderVariableBuffer257 void unionReferencesWith(const ActiveVariable &other) 258 { 259 activeVariable.unionReferencesWith(other); 260 } isActiveShaderVariableBuffer261 bool isActive(ShaderType shaderType) const { return activeVariable.isActive(shaderType); } getIdsShaderVariableBuffer262 const ShaderMap<uint32_t> &getIds() const { return activeVariable.getIds(); } getIdShaderVariableBuffer263 uint32_t getId(ShaderType shaderType) const { return activeVariable.getId(shaderType); } activeShadersShaderVariableBuffer264 ShaderBitSet activeShaders() const { return activeVariable.activeShaders(); } 265 int numActiveVariables() const; 266 267 ActiveVariable activeVariable; 268 int binding; 269 unsigned int dataSize; 270 std::vector<unsigned int> memberIndexes; 271 }; 272 273 using AtomicCounterBuffer = ShaderVariableBuffer; 274 275 // Helper struct representing a single shader interface block 276 struct InterfaceBlock : public ShaderVariableBuffer 277 { 278 InterfaceBlock(); 279 InterfaceBlock(const std::string &nameIn, 280 const std::string &mappedNameIn, 281 bool isArrayIn, 282 bool isReadOnlyIn, 283 unsigned int arrayElementIn, 284 unsigned int firstFieldArraySizeIn, 285 int bindingIn); 286 InterfaceBlock(const InterfaceBlock &other); 287 288 std::string nameWithArrayIndex() const; 289 std::string mappedNameWithArrayIndex() const; 290 291 std::string name; 292 std::string mappedName; 293 bool isArray; 294 // Only valid for SSBOs, specifies whether it has the readonly qualifier. 295 bool isReadOnly; 296 unsigned int arrayElement; 297 unsigned int firstFieldArraySize; 298 }; 299 300 } // namespace gl 301 302 #endif // LIBANGLE_UNIFORM_H_ 303