// // Copyright 2010 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // #include "libANGLE/Uniform.h" #include "common/BinaryStream.h" #include "libANGLE/ProgramLinkedResources.h" #include namespace gl { LinkedUniform::LinkedUniform(GLenum typeIn, GLenum precisionIn, const std::vector &arraySizesIn, const int bindingIn, const int offsetIn, const int locationIn, const int bufferIndexIn, const sh::BlockMemberInfo &blockInfoIn) { // arrays are always flattened, which means at most 1D array ASSERT(arraySizesIn.size() <= 1); memset(this, 0, sizeof(*this)); pod.typeIndex = GetUniformTypeIndex(typeIn); SetBitField(pod.precision, precisionIn); pod.location = locationIn; SetBitField(pod.binding, bindingIn); SetBitField(pod.offset, offsetIn); SetBitField(pod.bufferIndex, bufferIndexIn); pod.outerArraySizeProduct = 1; SetBitField(pod.arraySize, arraySizesIn.empty() ? 1u : arraySizesIn[0]); SetBitField(pod.flagBits.isArray, !arraySizesIn.empty()); if (!(blockInfoIn == sh::kDefaultBlockMemberInfo)) { pod.flagBits.isBlock = 1; pod.flagBits.blockIsRowMajorMatrix = blockInfoIn.isRowMajorMatrix; SetBitField(pod.blockOffset, blockInfoIn.offset); SetBitField(pod.blockArrayStride, blockInfoIn.arrayStride); SetBitField(pod.blockMatrixStride, blockInfoIn.matrixStride); } } LinkedUniform::LinkedUniform(const UsedUniform &usedUniform) { ASSERT(!usedUniform.isArrayOfArrays()); ASSERT(!usedUniform.isStruct()); ASSERT(usedUniform.active); ASSERT(usedUniform.blockInfo == sh::kDefaultBlockMemberInfo); // Note: Ensure every data member is initialized. pod.flagBitsAsUByte = 0; pod.typeIndex = GetUniformTypeIndex(usedUniform.type); SetBitField(pod.precision, usedUniform.precision); SetBitField(pod.imageUnitFormat, usedUniform.imageUnitFormat); pod.location = usedUniform.location; pod.blockOffset = 0; pod.blockArrayStride = 0; pod.blockMatrixStride = 0; SetBitField(pod.binding, usedUniform.binding); SetBitField(pod.offset, usedUniform.offset); SetBitField(pod.bufferIndex, usedUniform.bufferIndex); SetBitField(pod.parentArrayIndex, usedUniform.parentArrayIndex()); SetBitField(pod.outerArraySizeProduct, ArraySizeProduct(usedUniform.outerArraySizes)); SetBitField(pod.outerArrayOffset, usedUniform.outerArrayOffset); SetBitField(pod.arraySize, usedUniform.isArray() ? usedUniform.getArraySizeProduct() : 1u); SetBitField(pod.flagBits.isArray, usedUniform.isArray()); pod.id = usedUniform.id; pod.activeUseBits = usedUniform.activeVariable.activeShaders(); pod.ids = usedUniform.activeVariable.getIds(); SetBitField(pod.flagBits.isFragmentInOut, usedUniform.isFragmentInOut); SetBitField(pod.flagBits.texelFetchStaticUse, usedUniform.texelFetchStaticUse); ASSERT(!usedUniform.isArray() || pod.arraySize == usedUniform.getArraySizeProduct()); } BufferVariable::BufferVariable() { memset(&pod, 0, sizeof(pod)); pod.bufferIndex = -1; pod.blockInfo = sh::kDefaultBlockMemberInfo; pod.topLevelArraySize = -1; } BufferVariable::BufferVariable(GLenum type, GLenum precision, const std::string &name, const std::vector &arraySizes, const int bufferIndex, int topLevelArraySize, const sh::BlockMemberInfo &blockInfo) : name(name) { memset(&pod, 0, sizeof(pod)); SetBitField(pod.type, type); SetBitField(pod.precision, precision); SetBitField(pod.bufferIndex, bufferIndex); pod.blockInfo = blockInfo; SetBitField(pod.topLevelArraySize, topLevelArraySize); pod.isArray = !arraySizes.empty(); SetBitField(pod.basicTypeElementCount, arraySizes.empty() ? 1u : arraySizes.back()); } AtomicCounterBuffer::AtomicCounterBuffer() { memset(&pod, 0, sizeof(pod)); } void AtomicCounterBuffer::unionReferencesWith(const LinkedUniform &other) { pod.activeUseBits |= other.pod.activeUseBits; for (const ShaderType shaderType : AllShaderTypes()) { ASSERT(pod.ids[shaderType] == 0 || other.getId(shaderType) == 0 || pod.ids[shaderType] == other.getId(shaderType)); if (pod.ids[shaderType] == 0) { pod.ids[shaderType] = other.getId(shaderType); } } } InterfaceBlock::InterfaceBlock() { memset(&pod, 0, sizeof(pod)); } InterfaceBlock::InterfaceBlock(const std::string &name, const std::string &mappedName, bool isArray, bool isReadOnly, unsigned int arrayElementIn, unsigned int firstFieldArraySizeIn, int binding) : name(name), mappedName(mappedName) { memset(&pod, 0, sizeof(pod)); SetBitField(pod.isArray, isArray); SetBitField(pod.isReadOnly, isReadOnly); SetBitField(pod.inShaderBinding, binding); pod.arrayElement = arrayElementIn; pod.firstFieldArraySize = firstFieldArraySizeIn; } std::string InterfaceBlock::nameWithArrayIndex() const { std::stringstream fullNameStr; fullNameStr << name; if (pod.isArray) { fullNameStr << "[" << pod.arrayElement << "]"; } return fullNameStr.str(); } std::string InterfaceBlock::mappedNameWithArrayIndex() const { std::stringstream fullNameStr; fullNameStr << mappedName; if (pod.isArray) { fullNameStr << "[" << pod.arrayElement << "]"; } return fullNameStr.str(); } } // namespace gl