| // |
| // 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 <cstring> |
| |
| namespace gl |
| { |
| |
| LinkedUniform::LinkedUniform(GLenum typeIn, |
| GLenum precisionIn, |
| const std::vector<unsigned int> &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<unsigned int> &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 |