blob: caaf8f163970d6f7f24cbbaa340b541af0ca969e [file] [log] [blame]
//
// 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.
//
#ifndef LIBANGLE_UNIFORM_H_
#define LIBANGLE_UNIFORM_H_
#include <string>
#include <vector>
#include "angle_gl.h"
#include "common/MemoryBuffer.h"
#include "common/debug.h"
#include "common/uniform_type_info_autogen.h"
#include "common/utilities.h"
#include "compiler/translator/blocklayout.h"
#include "libANGLE/angletypes.h"
namespace gl
{
class BinaryInputStream;
class BinaryOutputStream;
struct UniformTypeInfo;
struct UsedUniform;
struct LinkedUniform;
#define ACTIVE_VARIABLE_COMMON_INTERFACES \
void setActive(ShaderType shaderType, bool used, uint32_t id) \
{ \
ASSERT(shaderType != ShaderType::InvalidEnum); \
pod.activeUseBits.set(shaderType, used); \
pod.ids[shaderType] = id; \
} \
ShaderType getFirstActiveShaderType() const \
{ \
return pod.activeUseBits.first(); \
} \
bool isActive(ShaderType shaderType) const \
{ \
return pod.activeUseBits[shaderType]; \
} \
const ShaderMap<uint32_t> &getIds() const \
{ \
return pod.ids; \
} \
uint32_t getId(ShaderType shaderType) const \
{ \
return pod.ids[shaderType]; \
} \
ShaderBitSet activeShaders() const \
{ \
return pod.activeUseBits; \
} \
uint32_t activeShaderCount() const \
{ \
return static_cast<uint32_t>(pod.activeUseBits.count()); \
}
struct ActiveVariable
{
ActiveVariable() { memset(&pod, 0, sizeof(pod)); }
ACTIVE_VARIABLE_COMMON_INTERFACES
struct PODStruct
{
ShaderBitSet activeUseBits;
// The id of a linked variable in each shader stage. This id originates from
// sh::ShaderVariable::id or sh::InterfaceBlock::id
ShaderMap<uint32_t> ids;
} pod;
};
inline const UniformTypeInfo &GetUniformTypeInfoFromIndex(UniformTypeIndex index)
{
ASSERT(index.value >= 0 && index.value < kUniformInfoTable.size());
return kUniformInfoTable[index.value];
}
// Important: This struct must have basic data types only, so that we can initialize with memcpy. Do
// not put any std::vector or objects with virtual functions in it.
// Helper struct representing a single shader uniform. Most of this structure's data member and
// access functions mirrors ShaderVariable; See ShaderVars.h for more info.
ANGLE_ENABLE_STRUCT_PADDING_WARNINGS
struct LinkedUniform
{
LinkedUniform() = default;
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);
LinkedUniform(const UsedUniform &usedUniform);
const UniformTypeInfo &getUniformTypeInfo() const
{
return GetUniformTypeInfoFromIndex(pod.typeIndex);
}
bool isSampler() const { return getUniformTypeInfo().isSampler; }
bool isImage() const { return getUniformTypeInfo().isImageType; }
bool isAtomicCounter() const { return IsAtomicCounterType(getType()); }
bool isInDefaultBlock() const { return pod.bufferIndex == -1; }
size_t getElementSize() const { return getUniformTypeInfo().externalSize; }
GLint getElementComponents() const { return GetUniformElementComponents(pod.typeIndex); }
bool isTexelFetchStaticUse() const { return pod.flagBits.texelFetchStaticUse; }
bool isFragmentInOut() const { return pod.flagBits.isFragmentInOut; }
bool isArray() const { return pod.flagBits.isArray; }
uint16_t getBasicTypeElementCount() const
{
ASSERT(pod.flagBits.isArray || pod.arraySize == 1u);
return pod.arraySize;
}
GLenum getType() const { return getUniformTypeInfo().type; }
uint16_t getOuterArrayOffset() const { return pod.outerArrayOffset; }
uint16_t getOuterArraySizeProduct() const { return pod.outerArraySizeProduct; }
int16_t getBinding() const { return pod.binding; }
int16_t getOffset() const { return pod.offset; }
int getBufferIndex() const { return pod.bufferIndex; }
int getLocation() const { return pod.location; }
GLenum getImageUnitFormat() const { return pod.imageUnitFormat; }
ACTIVE_VARIABLE_COMMON_INTERFACES
struct PODStruct
{
UniformTypeIndex typeIndex;
uint16_t precision;
int32_t location;
// These are from sh::struct BlockMemberInfo struct. See locklayout.h for detail.
uint16_t blockOffset;
uint16_t blockArrayStride;
uint16_t blockMatrixStride;
uint16_t imageUnitFormat;
// maxUniformVectorsCount is 4K due to we clamp maxUniformBlockSize to 64KB. All of these
// variable should be enough to pack into 16 bits to reduce the size of mUniforms.
int16_t binding;
int16_t bufferIndex;
int16_t offset;
uint16_t arraySize;
uint16_t outerArraySizeProduct;
uint16_t outerArrayOffset;
uint16_t parentArrayIndex;
union
{
struct
{
uint8_t isFragmentInOut : 1;
uint8_t texelFetchStaticUse : 1;
uint8_t isArray : 1;
uint8_t blockIsRowMajorMatrix : 1;
uint8_t isBlock : 1;
uint8_t padding : 3;
} flagBits;
uint8_t flagBitsAsUByte;
};
ShaderBitSet activeUseBits;
uint32_t id;
// The id of a linked variable in each shader stage. This id originates from
// sh::ShaderVariable::id or sh::InterfaceBlock::id
ShaderMap<uint32_t> ids;
} pod;
};
ANGLE_DISABLE_STRUCT_PADDING_WARNINGS
struct BufferVariable
{
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);
~BufferVariable() {}
bool isArray() const { return pod.isArray; }
uint32_t getBasicTypeElementCount() const { return pod.basicTypeElementCount; }
ACTIVE_VARIABLE_COMMON_INTERFACES
std::string name;
std::string mappedName;
ANGLE_ENABLE_STRUCT_PADDING_WARNINGS
struct PODStruct
{
uint16_t type;
uint16_t precision;
// 1 byte each
ShaderBitSet activeUseBits;
bool isArray;
int16_t bufferIndex;
// The id of a linked variable in each shader stage. This id originates from
// sh::ShaderVariable::id or sh::InterfaceBlock::id
ShaderMap<uint32_t> ids;
sh::BlockMemberInfo blockInfo;
int32_t topLevelArraySize;
uint32_t basicTypeElementCount;
} pod;
ANGLE_DISABLE_STRUCT_PADDING_WARNINGS
};
// Represents a single atomic counter buffer
struct AtomicCounterBuffer
{
AtomicCounterBuffer();
~AtomicCounterBuffer() {}
ACTIVE_VARIABLE_COMMON_INTERFACES
int numActiveVariables() const { return static_cast<int>(memberIndexes.size()); }
void unionReferencesWith(const LinkedUniform &otherUniform);
std::vector<unsigned int> memberIndexes;
ANGLE_ENABLE_STRUCT_PADDING_WARNINGS
struct PODStruct
{
// The id of a linked variable in each shader stage. This id originates from
// sh::ShaderVariable::id or sh::InterfaceBlock::id
ShaderMap<uint32_t> ids;
// The binding as specified by the shader.
int inShaderBinding;
unsigned int dataSize;
ShaderBitSet activeUseBits;
uint8_t pads[3];
} pod;
ANGLE_DISABLE_STRUCT_PADDING_WARNINGS
};
// Helper struct representing a single shader interface block
struct InterfaceBlock
{
InterfaceBlock();
InterfaceBlock(const std::string &nameIn,
const std::string &mappedNameIn,
bool isArrayIn,
bool isReadOnlyIn,
unsigned int arrayElementIn,
unsigned int firstFieldArraySizeIn,
int bindingIn);
std::string nameWithArrayIndex() const;
std::string mappedNameWithArrayIndex() const;
ACTIVE_VARIABLE_COMMON_INTERFACES
int numActiveVariables() const { return static_cast<int>(memberIndexes.size()); }
std::string name;
std::string mappedName;
std::vector<unsigned int> memberIndexes;
ANGLE_ENABLE_STRUCT_PADDING_WARNINGS
struct PODStruct
{
uint32_t arrayElement;
uint32_t firstFieldArraySize;
ShaderBitSet activeUseBits;
uint8_t isArray : 1;
// Only valid for SSBOs, specifies whether it has the readonly qualifier.
uint8_t isReadOnly : 1;
uint8_t padings : 6;
// The binding as specified by the shader (0 if unspecified, per spec)
int16_t inShaderBinding;
unsigned int dataSize;
// The id of a linked variable in each shader stage. This id originates from
// sh::ShaderVariable::id or sh::InterfaceBlock::id
ShaderMap<uint32_t> ids;
} pod;
ANGLE_DISABLE_STRUCT_PADDING_WARNINGS
};
#undef ACTIVE_VARIABLE_COMMON_INTERFACES
} // namespace gl
#endif // LIBANGLE_UNIFORM_H_