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/uniform_type_info_autogen.h" 17 #include "common/utilities.h" 18 #include "compiler/translator/blocklayout.h" 19 #include "libANGLE/angletypes.h" 20 21 namespace gl 22 { 23 class BinaryInputStream; 24 class BinaryOutputStream; 25 struct UniformTypeInfo; 26 struct UsedUniform; 27 struct LinkedUniform; 28 29 #define ACTIVE_VARIABLE_COMMON_INTERFACES \ 30 void setActive(ShaderType shaderType, bool used, uint32_t id) \ 31 { \ 32 ASSERT(shaderType != ShaderType::InvalidEnum); \ 33 pod.activeUseBits.set(shaderType, used); \ 34 pod.ids[shaderType] = id; \ 35 } \ 36 ShaderType getFirstActiveShaderType() const \ 37 { \ 38 return pod.activeUseBits.first(); \ 39 } \ 40 bool isActive(ShaderType shaderType) const \ 41 { \ 42 return pod.activeUseBits[shaderType]; \ 43 } \ 44 const ShaderMap<uint32_t> &getIds() const \ 45 { \ 46 return pod.ids; \ 47 } \ 48 uint32_t getId(ShaderType shaderType) const \ 49 { \ 50 return pod.ids[shaderType]; \ 51 } \ 52 ShaderBitSet activeShaders() const \ 53 { \ 54 return pod.activeUseBits; \ 55 } \ 56 uint32_t activeShaderCount() const \ 57 { \ 58 return static_cast<uint32_t>(pod.activeUseBits.count()); \ 59 } 60 61 struct ActiveVariable 62 { ActiveVariableActiveVariable63 ActiveVariable() { memset(&pod, 0, sizeof(pod)); } 64 65 ACTIVE_VARIABLE_COMMON_INTERFACES 66 67 struct PODStruct 68 { 69 ShaderBitSet activeUseBits; 70 // The id of a linked variable in each shader stage. This id originates from 71 // sh::ShaderVariable::id or sh::InterfaceBlock::id 72 ShaderMap<uint32_t> ids; 73 } pod; 74 }; 75 76 // Important: This struct must have basic data types only, so that we can initialize with memcpy. Do 77 // not put any std::vector or objects with virtual functions in it. 78 // Helper struct representing a single shader uniform. Most of this structure's data member and 79 // access functions mirrors ShaderVariable; See ShaderVars.h for more info. 80 ANGLE_ENABLE_STRUCT_PADDING_WARNINGS 81 struct LinkedUniform 82 { 83 LinkedUniform() = default; 84 LinkedUniform(GLenum typeIn, 85 GLenum precisionIn, 86 const std::vector<unsigned int> &arraySizesIn, 87 const int bindingIn, 88 const int offsetIn, 89 const int locationIn, 90 const int bufferIndexIn, 91 const sh::BlockMemberInfo &blockInfoIn); 92 LinkedUniform(const UsedUniform &usedUniform); 93 getUniformTypeInfoLinkedUniform94 const UniformTypeInfo &getUniformTypeInfo() const 95 { 96 return GetUniformTypeInfoFromIndex(pod.typeIndex); 97 } 98 isSamplerLinkedUniform99 bool isSampler() const { return getUniformTypeInfo().isSampler; } isImageLinkedUniform100 bool isImage() const { return getUniformTypeInfo().isImageType; } isAtomicCounterLinkedUniform101 bool isAtomicCounter() const { return IsAtomicCounterType(getType()); } isInDefaultBlockLinkedUniform102 bool isInDefaultBlock() const { return pod.bufferIndex == -1; } getElementSizeLinkedUniform103 size_t getElementSize() const { return getUniformTypeInfo().externalSize; } getElementComponentsLinkedUniform104 GLint getElementComponents() const { return GetUniformElementComponents(pod.typeIndex); } 105 isTexelFetchStaticUseLinkedUniform106 bool isTexelFetchStaticUse() const { return pod.flagBits.texelFetchStaticUse; } isFragmentInOutLinkedUniform107 bool isFragmentInOut() const { return pod.flagBits.isFragmentInOut; } 108 isArrayLinkedUniform109 bool isArray() const { return pod.flagBits.isArray; } getBasicTypeElementCountLinkedUniform110 uint16_t getBasicTypeElementCount() const 111 { 112 ASSERT(pod.flagBits.isArray || pod.arraySize == 1u); 113 return pod.arraySize; 114 } 115 getTypeLinkedUniform116 GLenum getType() const { return getUniformTypeInfo().type; } getOuterArrayOffsetLinkedUniform117 uint16_t getOuterArrayOffset() const { return pod.outerArrayOffset; } getOuterArraySizeProductLinkedUniform118 uint16_t getOuterArraySizeProduct() const { return pod.outerArraySizeProduct; } getBindingLinkedUniform119 int16_t getBinding() const { return pod.binding; } getOffsetLinkedUniform120 int16_t getOffset() const { return pod.offset; } getBufferIndexLinkedUniform121 int getBufferIndex() const { return pod.bufferIndex; } getLocationLinkedUniform122 int getLocation() const { return pod.location; } getImageUnitFormatLinkedUniform123 GLenum getImageUnitFormat() const { return pod.imageUnitFormat; } 124 125 ACTIVE_VARIABLE_COMMON_INTERFACES 126 127 struct PODStruct 128 { 129 UniformTypeIndex typeIndex; 130 uint16_t precision; 131 132 int32_t location; 133 134 // These are from sh::struct BlockMemberInfo struct. See locklayout.h for detail. 135 uint16_t blockOffset; 136 uint16_t blockArrayStride; 137 138 uint16_t blockMatrixStride; 139 uint16_t imageUnitFormat; 140 141 // maxUniformVectorsCount is 4K due to we clamp maxUniformBlockSize to 64KB. All of these 142 // variable should be enough to pack into 16 bits to reduce the size of mUniforms. 143 int16_t binding; 144 int16_t bufferIndex; 145 146 int16_t offset; 147 uint16_t arraySize; 148 149 uint16_t outerArraySizeProduct; 150 uint16_t outerArrayOffset; 151 152 uint16_t parentArrayIndex; 153 union 154 { 155 struct 156 { 157 uint8_t isFragmentInOut : 1; 158 uint8_t texelFetchStaticUse : 1; 159 uint8_t isArray : 1; 160 uint8_t blockIsRowMajorMatrix : 1; 161 uint8_t isBlock : 1; 162 uint8_t padding : 3; 163 } flagBits; 164 uint8_t flagBitsAsUByte; 165 }; 166 ShaderBitSet activeUseBits; 167 168 uint32_t id; 169 // The id of a linked variable in each shader stage. This id originates from 170 // sh::ShaderVariable::id or sh::InterfaceBlock::id 171 ShaderMap<uint32_t> ids; 172 } pod; 173 }; 174 ANGLE_DISABLE_STRUCT_PADDING_WARNINGS 175 176 struct BufferVariable 177 { 178 BufferVariable(); 179 BufferVariable(GLenum type, 180 GLenum precision, 181 const std::string &name, 182 const std::vector<unsigned int> &arraySizes, 183 const int bufferIndex, 184 int topLevelArraySize, 185 const sh::BlockMemberInfo &blockInfo); ~BufferVariableBufferVariable186 ~BufferVariable() {} 187 isArrayBufferVariable188 bool isArray() const { return pod.isArray; } getBasicTypeElementCountBufferVariable189 uint32_t getBasicTypeElementCount() const { return pod.basicTypeElementCount; } 190 191 ACTIVE_VARIABLE_COMMON_INTERFACES 192 193 std::string name; 194 std::string mappedName; 195 196 ANGLE_ENABLE_STRUCT_PADDING_WARNINGS 197 struct PODStruct 198 { 199 uint16_t type; 200 uint16_t precision; 201 202 // 1 byte each 203 ShaderBitSet activeUseBits; 204 bool isArray; 205 206 int16_t bufferIndex; 207 208 // The id of a linked variable in each shader stage. This id originates from 209 // sh::ShaderVariable::id or sh::InterfaceBlock::id 210 ShaderMap<uint32_t> ids; 211 212 sh::BlockMemberInfo blockInfo; 213 214 int32_t topLevelArraySize; 215 uint32_t basicTypeElementCount; 216 } pod; 217 ANGLE_DISABLE_STRUCT_PADDING_WARNINGS 218 }; 219 220 // Represents a single atomic counter buffer 221 struct AtomicCounterBuffer 222 { 223 AtomicCounterBuffer(); ~AtomicCounterBufferAtomicCounterBuffer224 ~AtomicCounterBuffer() {} 225 226 ACTIVE_VARIABLE_COMMON_INTERFACES numActiveVariablesAtomicCounterBuffer227 int numActiveVariables() const { return static_cast<int>(memberIndexes.size()); } 228 void unionReferencesWith(const LinkedUniform &otherUniform); 229 230 std::vector<unsigned int> memberIndexes; 231 232 ANGLE_ENABLE_STRUCT_PADDING_WARNINGS 233 struct PODStruct 234 { 235 // The id of a linked variable in each shader stage. This id originates from 236 // sh::ShaderVariable::id or sh::InterfaceBlock::id 237 ShaderMap<uint32_t> ids; 238 // The binding as specified by the shader. 239 int inShaderBinding; 240 unsigned int dataSize; 241 ShaderBitSet activeUseBits; 242 uint8_t pads[3]; 243 } pod; 244 ANGLE_DISABLE_STRUCT_PADDING_WARNINGS 245 }; 246 247 // Helper struct representing a single shader interface block 248 struct InterfaceBlock 249 { 250 InterfaceBlock(); 251 InterfaceBlock(const std::string &nameIn, 252 const std::string &mappedNameIn, 253 bool isArrayIn, 254 bool isReadOnlyIn, 255 unsigned int arrayElementIn, 256 unsigned int firstFieldArraySizeIn, 257 int bindingIn); 258 259 std::string nameWithArrayIndex() const; 260 std::string mappedNameWithArrayIndex() const; 261 262 ACTIVE_VARIABLE_COMMON_INTERFACES 263 numActiveVariablesInterfaceBlock264 int numActiveVariables() const { return static_cast<int>(memberIndexes.size()); } 265 266 std::string name; 267 std::string mappedName; 268 std::vector<unsigned int> memberIndexes; 269 270 ANGLE_ENABLE_STRUCT_PADDING_WARNINGS 271 struct PODStruct 272 { 273 uint32_t arrayElement; 274 uint32_t firstFieldArraySize; 275 276 ShaderBitSet activeUseBits; 277 uint8_t isArray : 1; 278 // Only valid for SSBOs, specifies whether it has the readonly qualifier. 279 uint8_t isReadOnly : 1; 280 uint8_t padings : 6; 281 // The binding as specified by the shader (0 if unspecified, per spec) 282 int16_t inShaderBinding; 283 284 unsigned int dataSize; 285 // The id of a linked variable in each shader stage. This id originates from 286 // sh::ShaderVariable::id or sh::InterfaceBlock::id 287 ShaderMap<uint32_t> ids; 288 } pod; 289 ANGLE_DISABLE_STRUCT_PADDING_WARNINGS 290 }; 291 292 #undef ACTIVE_VARIABLE_COMMON_INTERFACES 293 } // namespace gl 294 295 #endif // LIBANGLE_UNIFORM_H_ 296