Pack and reduce Program::mProgramInput size

Right now mProgramInput is std::vector<sh::ShaderVariable>. It really
only need a subset of ShaderVariable struct. This CL adds a ProgramInput
struct so that we can add data members that actually required. This CL
also makes bools into bitfield and some variables to uint16_t to further
compact the size. This CL also groups the data memebers other than
string to basicDataTypeStruct which only contains basic data types and
the entire struct is memcpied during program binary load and save. This
not just reduces number of memcpy calls, but also improves reliability
so that when someone adds a new member into the struct, it will
automatically load/save correctly.

Bug: b/275102061
Change-Id: Ic055c986453ed46e56057a0122c9926245fef4d1
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4776267
Reviewed-by: Roman Lavrov <romanl@google.com>
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
Commit-Queue: Charlie Lao <cclao@google.com>
This commit is contained in:
Charlie Lao
2023-08-11 15:16:26 -07:00
committed by Angle LUCI CQ
parent 124e90af14
commit 1e1c9d9de8
15 changed files with 297 additions and 173 deletions

View File

@@ -327,6 +327,54 @@ void InitShaderStorageBlockLinker(const Context *context,
}
}
}
template <typename T>
GLuint GetResourceMaxNameSize(const T &resource, GLint max)
{
if (resource.isArray())
{
return std::max(max, clampCast<GLint>((resource.name + "[0]").size()));
}
else
{
return std::max(max, clampCast<GLint>((resource.name).size()));
}
}
template <typename T>
GLuint GetResourceLocation(const GLchar *name, const T &variable, GLint location)
{
if (variable.isBuiltIn())
{
return GL_INVALID_INDEX;
}
if (variable.isArray())
{
size_t nameLengthWithoutArrayIndexOut;
size_t arrayIndex = ParseArrayIndex(name, &nameLengthWithoutArrayIndexOut);
// The 'name' string may not contain the array notation "[0]"
if (arrayIndex != GL_INVALID_INDEX)
{
location += arrayIndex;
}
}
return location;
}
template <typename T>
const std::string GetResourceName(const T &resource)
{
std::string resourceName = resource.name;
if (resource.isArray())
{
resourceName += "[0]";
}
return resourceName;
}
} // anonymous namespace
const char *GetLinkMismatchErrorString(LinkMismatchError linkError)
@@ -379,7 +427,8 @@ const char *GetLinkMismatchErrorString(LinkMismatchError linkError)
}
}
void UpdateInterfaceVariable(std::vector<sh::ShaderVariable> *block, const sh::ShaderVariable &var)
template <typename T>
void UpdateInterfaceVariable(std::vector<T> *block, const sh::ShaderVariable &var)
{
if (!var.isStruct())
{
@@ -471,7 +520,7 @@ void LoadShaderVariableBuffer(BinaryInputStream *stream, ShaderVariableBuffer *v
{
var->memberIndexes.resize(numMembers);
stream->readBytes(reinterpret_cast<unsigned char *>(var->memberIndexes.data()),
sizeof(unsigned int) * var->memberIndexes.size());
sizeof(*var->memberIndexes.data()) * var->memberIndexes.size());
}
}
@@ -660,6 +709,46 @@ void LoadBlockMemberInfo(BinaryInputStream *stream, sh::BlockMemberInfo *var)
var->topLevelArrayStride = stream->readInt<int>();
}
// ProgramInput implementation.
ProgramInput::ProgramInput() {}
ProgramInput::ProgramInput(const sh::ShaderVariable &var)
{
ASSERT(!var.isStruct());
name = var.name;
mappedName = var.mappedName;
SetBitField(basicDataTypeStruct.type, var.type);
basicDataTypeStruct.location = var.hasImplicitLocation ? -1 : var.location;
SetBitField(basicDataTypeStruct.interpolation, var.interpolation);
basicDataTypeStruct.flagBitsAsUByte = 0;
basicDataTypeStruct.flagBits.active = var.active;
basicDataTypeStruct.flagBits.isPatch = var.isPatch;
basicDataTypeStruct.flagBits.hasImplicitLocation = var.hasImplicitLocation;
basicDataTypeStruct.flagBits.isArray = var.isArray();
basicDataTypeStruct.flagBits.isBuiltIn = IsBuiltInName(var.name);
SetBitField(basicDataTypeStruct.basicTypeElementCount, var.getBasicTypeElementCount());
basicDataTypeStruct.id = var.id;
SetBitField(basicDataTypeStruct.arraySizeProduct, var.getArraySizeProduct());
}
ProgramInput::ProgramInput(const ProgramInput &other)
{
*this = other;
}
ProgramInput &ProgramInput::operator=(const ProgramInput &rhs)
{
if (this != &rhs)
{
name = rhs.name;
mappedName = rhs.mappedName;
basicDataTypeStruct = rhs.basicDataTypeStruct;
}
return *this;
}
// VariableLocation implementation.
VariableLocation::VariableLocation() : arrayIndex(0), index(kUnused), ignored(false) {}
@@ -935,11 +1024,11 @@ GLuint ProgramState::getImageIndexFromUniformIndex(GLuint uniformIndex) const
GLuint ProgramState::getAttributeLocation(const std::string &name) const
{
for (const sh::ShaderVariable &attribute : mExecutable->mProgramInputs)
for (const ProgramInput &attribute : mExecutable->mProgramInputs)
{
if (attribute.name == name)
{
return attribute.location;
return attribute.getLocation();
}
}
@@ -1718,7 +1807,7 @@ void Program::getActiveAttribute(GLuint index,
}
ASSERT(index < mState.mExecutable->getProgramInputs().size());
const sh::ShaderVariable &attrib = mState.mExecutable->getProgramInputs()[index];
const ProgramInput &attrib = mState.mExecutable->getProgramInputs()[index];
if (bufsize > 0)
{
@@ -1727,7 +1816,7 @@ void Program::getActiveAttribute(GLuint index,
// Always a single 'type' instance
*size = 1;
*type = attrib.type;
*type = attrib.getType();
}
GLint Program::getActiveAttributeCount() const
@@ -1751,7 +1840,7 @@ GLint Program::getActiveAttributeMaxLength() const
size_t maxLength = 0;
for (const sh::ShaderVariable &attrib : mState.mExecutable->getProgramInputs())
for (const ProgramInput &attrib : mState.mExecutable->getProgramInputs())
{
maxLength = std::max(attrib.name.length() + 1, maxLength);
}
@@ -1759,7 +1848,7 @@ GLint Program::getActiveAttributeMaxLength() const
return static_cast<GLint>(maxLength);
}
const std::vector<sh::ShaderVariable> &Program::getAttributes() const
const std::vector<ProgramInput> &Program::getAttributes() const
{
ASSERT(!mLinkingState);
return mState.mExecutable->getProgramInputs();
@@ -1822,7 +1911,7 @@ GLenum Program::getTessGenVertexOrder() const
return mState.mExecutable->mTessGenVertexOrder;
}
const sh::ShaderVariable &Program::getInputResource(size_t index) const
const ProgramInput &Program::getInputResource(size_t index) const
{
ASSERT(!mLinkingState);
ASSERT(index < mState.mExecutable->getProgramInputs().size());
@@ -1836,7 +1925,7 @@ GLuint Program::getInputResourceIndex(const GLchar *name) const
for (size_t index = 0; index < mState.mExecutable->getProgramInputs().size(); index++)
{
sh::ShaderVariable resource = getInputResource(index);
ProgramInput resource = getInputResource(index);
if (resource.name == nameString)
{
return static_cast<GLuint>(index);
@@ -1846,25 +1935,13 @@ GLuint Program::getInputResourceIndex(const GLchar *name) const
return GL_INVALID_INDEX;
}
GLuint Program::getResourceMaxNameSize(const sh::ShaderVariable &resource, GLint max) const
{
if (resource.isArray())
{
return std::max(max, clampCast<GLint>((resource.name + "[0]").size()));
}
else
{
return std::max(max, clampCast<GLint>((resource.name).size()));
}
}
GLuint Program::getInputResourceMaxNameSize() const
{
GLint max = 0;
for (const sh::ShaderVariable &resource : mState.mExecutable->getProgramInputs())
for (const ProgramInput &resource : mState.mExecutable->getProgramInputs())
{
max = getResourceMaxNameSize(resource, max);
max = GetResourceMaxNameSize(resource, max);
}
return max;
@@ -1876,34 +1953,12 @@ GLuint Program::getOutputResourceMaxNameSize() const
for (const sh::ShaderVariable &resource : mState.mExecutable->getOutputVariables())
{
max = getResourceMaxNameSize(resource, max);
max = GetResourceMaxNameSize(resource, max);
}
return max;
}
GLuint Program::getResourceLocation(const GLchar *name, const sh::ShaderVariable &variable) const
{
if (variable.isBuiltIn())
{
return GL_INVALID_INDEX;
}
GLint location = variable.location;
if (variable.isArray())
{
size_t nameLengthWithoutArrayIndexOut;
size_t arrayIndex = ParseArrayIndex(name, &nameLengthWithoutArrayIndexOut);
// The 'name' string may not contain the array notation "[0]"
if (arrayIndex != GL_INVALID_INDEX)
{
location += arrayIndex;
}
}
return location;
}
GLuint Program::getInputResourceLocation(const GLchar *name) const
{
const GLuint index = getInputResourceIndex(name);
@@ -1912,9 +1967,9 @@ GLuint Program::getInputResourceLocation(const GLchar *name) const
return index;
}
const sh::ShaderVariable &variable = getInputResource(index);
const ProgramInput &variable = getInputResource(index);
return getResourceLocation(name, variable);
return GetResourceLocation(name, variable, variable.getLocation());
}
GLuint Program::getOutputResourceLocation(const GLchar *name) const
@@ -1927,7 +1982,7 @@ GLuint Program::getOutputResourceLocation(const GLchar *name) const
const sh::ShaderVariable &variable = getOutputResource(index);
return getResourceLocation(name, variable);
return GetResourceLocation(name, variable, variable.location);
}
GLuint Program::getOutputResourceIndex(const GLchar *name) const
@@ -2016,24 +2071,12 @@ void Program::getBufferVariableResourceName(GLuint index,
getResourceName(mState.mBufferVariables[index].name, bufSize, length, name);
}
const std::string Program::getResourceName(const sh::ShaderVariable &resource) const
{
std::string resourceName = resource.name;
if (resource.isArray())
{
resourceName += "[0]";
}
return resourceName;
}
const std::string Program::getInputResourceName(GLuint index) const
{
ASSERT(!mLinkingState);
const sh::ShaderVariable &resource = getInputResource(index);
const ProgramInput &resource = getInputResource(index);
return getResourceName(resource);
return GetResourceName(resource);
}
const std::string Program::getOutputResourceName(GLuint index) const
@@ -2041,7 +2084,7 @@ const std::string Program::getOutputResourceName(GLuint index) const
ASSERT(!mLinkingState);
const sh::ShaderVariable &resource = getOutputResource(index);
return getResourceName(resource);
return GetResourceName(resource);
}
const sh::ShaderVariable &Program::getOutputResource(size_t index) const
@@ -3158,54 +3201,56 @@ bool Program::linkAttributes(const Context *context, InfoLog &infoLog)
return true;
}
// In GLSL ES 3.00.6, aliasing checks should be done with all declared attributes -
// see GLSL ES 3.00.6 section 12.46. Inactive attributes will be pruned after
// aliasing checks.
// In GLSL ES 1.00.17 we only do aliasing checks for active attributes.
shaderVersion = vertexShader->getShaderVersion(context);
if (shaderVersion >= 300)
{
// In GLSL ES 3.00.6, aliasing checks should be done with all declared attributes -
// see GLSL ES 3.00.6 section 12.46. Inactive attributes will be pruned after
// aliasing checks.
mState.mExecutable->mProgramInputs = vertexShader->getAllAttributes(context);
}
else
{
// In GLSL ES 1.00.17 we only do aliasing checks for active attributes.
mState.mExecutable->mProgramInputs = vertexShader->getActiveAttributes(context);
}
const std::vector<sh::ShaderVariable> &shaderAttributes =
shaderVersion >= 300 ? vertexShader->getAllAttributes(context)
: vertexShader->getActiveAttributes(context);
ASSERT(mState.mExecutable->mProgramInputs.empty());
mState.mExecutable->mProgramInputs.reserve(shaderAttributes.size());
GLuint maxAttribs = static_cast<GLuint>(caps.maxVertexAttributes);
std::vector<sh::ShaderVariable *> usedAttribMap(maxAttribs, nullptr);
std::vector<ProgramInput *> usedAttribMap(maxAttribs, nullptr);
// Assign locations to attributes that have a binding location and check for attribute aliasing.
for (sh::ShaderVariable &attribute : mState.mExecutable->mProgramInputs)
for (const sh::ShaderVariable &shaderAttribute : shaderAttributes)
{
// GLSL ES 3.10 January 2016 section 4.3.4: Vertex shader inputs can't be arrays or
// structures, so we don't need to worry about adjusting their names or generating entries
// for each member/element (unlike uniforms for example).
ASSERT(!attribute.isArray() && !attribute.isStruct());
ASSERT(!shaderAttribute.isArray() && !shaderAttribute.isStruct());
int bindingLocation = mAttributeBindings.getBinding(attribute);
if (attribute.location == -1 && bindingLocation != -1)
mState.mExecutable->mProgramInputs.emplace_back(shaderAttribute);
// Assign locations to attributes that have a binding location and check for attribute
// aliasing.
ProgramInput &attribute = mState.mExecutable->mProgramInputs.back();
int bindingLocation = mAttributeBindings.getBinding(attribute);
if (attribute.getLocation() == -1 && bindingLocation != -1)
{
attribute.location = bindingLocation;
attribute.setLocation(bindingLocation);
}
if (attribute.location != -1)
if (attribute.getLocation() != -1)
{
// Location is set by glBindAttribLocation or by location layout qualifier
const int regs = VariableRegisterCount(attribute.type);
const int regs = VariableRegisterCount(attribute.getType());
if (static_cast<GLuint>(regs + attribute.location) > maxAttribs)
if (static_cast<GLuint>(regs + attribute.getLocation()) > maxAttribs)
{
infoLog << "Attribute (" << attribute.name << ") at location " << attribute.location
<< " is too big to fit";
infoLog << "Attribute (" << attribute.name << ") at location "
<< attribute.getLocation() << " is too big to fit";
return false;
}
for (int reg = 0; reg < regs; reg++)
{
const int regLocation = attribute.location + reg;
sh::ShaderVariable *linkedAttribute = usedAttribMap[regLocation];
const int regLocation = attribute.getLocation() + reg;
ProgramInput *linkedAttribute = usedAttribMap[regLocation];
// In GLSL ES 3.00.6 and in WebGL, attribute aliasing produces a link error.
// In non-WebGL GLSL ES 1.00.17, attribute aliasing is allowed with some
@@ -3232,12 +3277,12 @@ bool Program::linkAttributes(const Context *context, InfoLog &infoLog)
}
// Assign locations to attributes that don't have a binding location.
for (sh::ShaderVariable &attribute : mState.mExecutable->mProgramInputs)
for (ProgramInput &attribute : mState.mExecutable->mProgramInputs)
{
// Not set by glBindAttribLocation or by location layout qualifier
if (attribute.location == -1)
if (attribute.getLocation() == -1)
{
int regs = VariableRegisterCount(attribute.type);
int regs = VariableRegisterCount(attribute.getType());
int availableIndex = AllocateFirstFreeBits(&usedLocations, regs, maxAttribs);
if (availableIndex == -1 || static_cast<GLuint>(availableIndex + regs) > maxAttribs)
@@ -3246,7 +3291,7 @@ bool Program::linkAttributes(const Context *context, InfoLog &infoLog)
return false;
}
attribute.location = availableIndex;
attribute.setLocation(availableIndex);
}
}
@@ -3260,7 +3305,7 @@ bool Program::linkAttributes(const Context *context, InfoLog &infoLog)
for (auto attributeIter = mState.mExecutable->getProgramInputs().begin();
attributeIter != mState.mExecutable->getProgramInputs().end();)
{
if (attributeIter->active)
if (attributeIter->isActive())
{
++attributeIter;
}
@@ -3271,13 +3316,13 @@ bool Program::linkAttributes(const Context *context, InfoLog &infoLog)
}
}
for (const sh::ShaderVariable &attribute : mState.mExecutable->getProgramInputs())
for (const ProgramInput &attribute : mState.mExecutable->getProgramInputs())
{
ASSERT(attribute.active);
ASSERT(attribute.location != -1);
unsigned int regs = static_cast<unsigned int>(VariableRegisterCount(attribute.type));
ASSERT(attribute.isActive());
ASSERT(attribute.getLocation() != -1);
unsigned int regs = static_cast<unsigned int>(VariableRegisterCount(attribute.getType()));
unsigned int location = static_cast<unsigned int>(attribute.location);
unsigned int location = static_cast<unsigned int>(attribute.getLocation());
for (unsigned int r = 0; r < regs; r++)
{
// Built-in active program inputs don't have a bound attribute.
@@ -3288,7 +3333,7 @@ bool Program::linkAttributes(const Context *context, InfoLog &infoLog)
std::max(mState.mExecutable->mMaxActiveAttribLocation, location + 1);
ComponentType componentType =
GLenumToComponentType(VariableComponentType(attribute.type));
GLenumToComponentType(VariableComponentType(attribute.getType()));
SetComponentTypeMask(componentType, location,
&mState.mExecutable->mAttributesTypeMask);

View File

@@ -244,7 +244,7 @@ class ProgramState final : angle::NonCopyable
{
return mExecutable->getActiveUniformBlockBindings();
}
const std::vector<sh::ShaderVariable> &getProgramInputs() const
const std::vector<ProgramInput> &getProgramInputs() const
{
return mExecutable->getProgramInputs();
}
@@ -508,7 +508,7 @@ class Program final : public LabeledObject, public angle::Subject
GLchar *name) const;
GLint getActiveAttributeCount() const;
GLint getActiveAttributeMaxLength() const;
const std::vector<sh::ShaderVariable> &getAttributes() const;
const std::vector<ProgramInput> &getAttributes() const;
GLint getFragDataLocation(const std::string &name) const;
size_t getOutputResourceCount() const;
@@ -734,14 +734,11 @@ class Program final : public LabeledObject, public angle::Subject
GLsizei bufSize,
GLsizei *length,
GLchar *name) const;
const sh::ShaderVariable &getInputResource(size_t index) const;
GLuint getResourceMaxNameSize(const sh::ShaderVariable &resource, GLint max) const;
const ProgramInput &getInputResource(size_t index) const;
GLuint getInputResourceMaxNameSize() const;
GLuint getOutputResourceMaxNameSize() const;
GLuint getResourceLocation(const GLchar *name, const sh::ShaderVariable &variable) const;
GLuint getInputResourceLocation(const GLchar *name) const;
GLuint getOutputResourceLocation(const GLchar *name) const;
const std::string getResourceName(const sh::ShaderVariable &resource) const;
const std::string getInputResourceName(GLuint index) const;
const std::string getOutputResourceName(GLuint index) const;
const sh::ShaderVariable &getOutputResource(size_t index) const;

View File

@@ -194,6 +194,35 @@ void AppendActiveBlocks(ShaderType shaderType,
}
}
void SaveProgramInputs(BinaryOutputStream *stream, const std::vector<ProgramInput> &programInputs)
{
stream->writeInt(programInputs.size());
for (const ProgramInput &attrib : programInputs)
{
stream->writeString(attrib.name);
stream->writeString(attrib.mappedName);
stream->writeBytes(reinterpret_cast<const unsigned char *>(&attrib.basicDataTypeStruct),
sizeof(attrib.basicDataTypeStruct));
}
}
void LoadProgramInputs(BinaryInputStream *stream, std::vector<ProgramInput> *programInputs)
{
size_t attribCount = stream->readInt<size_t>();
ASSERT(programInputs->empty());
if (attribCount > 0)
{
programInputs->resize(attribCount);
for (size_t attribIndex = 0; attribIndex < attribCount; ++attribIndex)
{
ProgramInput &attrib = (*programInputs)[attribIndex];
stream->readString(&attrib.name);
stream->readString(&attrib.mappedName);
stream->readBytes(reinterpret_cast<unsigned char *>(&attrib.basicDataTypeStruct),
sizeof(attrib.basicDataTypeStruct));
}
}
}
void SaveUniforms(BinaryOutputStream *stream,
const std::vector<LinkedUniform> &uniforms,
const std::vector<std::string> &uniformNames,
@@ -417,16 +446,7 @@ void ProgramExecutable::load(bool isSeparable, gl::BinaryInputStream *stream)
mTessGenVertexOrder = stream->readInt<GLenum>();
mTessGenPointMode = stream->readInt<GLenum>();
size_t attribCount = stream->readInt<size_t>();
ASSERT(mProgramInputs.empty());
mProgramInputs.resize(attribCount);
for (size_t attribIndex = 0; attribIndex < attribCount; ++attribIndex)
{
sh::ShaderVariable &attrib = mProgramInputs[attribIndex];
LoadShaderVar(stream, &attrib);
attrib.location = stream->readInt<int>();
}
LoadProgramInputs(stream, &mProgramInputs);
LoadUniforms(stream, &mUniforms, &mUniformNames, &mUniformMappedNames);
size_t uniformBlockCount = stream->readInt<size_t>();
@@ -633,13 +653,7 @@ void ProgramExecutable::save(bool isSeparable, gl::BinaryOutputStream *stream) c
stream->writeInt(mTessGenVertexOrder);
stream->writeInt(mTessGenPointMode);
stream->writeInt(getProgramInputs().size());
for (const sh::ShaderVariable &attrib : getProgramInputs())
{
WriteShaderVar(stream, attrib);
stream->writeInt(attrib.location);
}
SaveProgramInputs(stream, mProgramInputs);
SaveUniforms(stream, mUniforms, mUniformNames, mUniformMappedNames);
stream->writeInt(getUniformBlocks().size());

View File

@@ -60,6 +60,72 @@ struct ImageBinding
std::vector<GLuint> boundImageUnits;
};
ANGLE_ENABLE_STRUCT_PADDING_WARNINGS
struct ProgramInput
{
ProgramInput();
ProgramInput(const sh::ShaderVariable &var);
ProgramInput(const ProgramInput &other);
ProgramInput &operator=(const ProgramInput &rhs);
GLenum getType() const { return basicDataTypeStruct.type; }
bool isBuiltIn() const { return basicDataTypeStruct.flagBits.isBuiltIn; }
bool isArray() const { return basicDataTypeStruct.flagBits.isArray; }
bool isActive() const { return basicDataTypeStruct.flagBits.active; }
bool isPatch() const { return basicDataTypeStruct.flagBits.isPatch; }
int getLocation() const { return basicDataTypeStruct.location; }
unsigned int getBasicTypeElementCount() const
{
return basicDataTypeStruct.basicTypeElementCount;
}
unsigned int getArraySizeProduct() const { return basicDataTypeStruct.arraySizeProduct; }
uint32_t getId() const { return basicDataTypeStruct.id; }
sh::InterpolationType getInterpolation() const
{
return static_cast<sh::InterpolationType>(basicDataTypeStruct.interpolation);
}
void setLocation(int location) { basicDataTypeStruct.location = location; }
void resetEffectiveLocation()
{
if (basicDataTypeStruct.flagBits.hasImplicitLocation)
{
basicDataTypeStruct.location = -1;
}
}
std::string name;
std::string mappedName;
// The struct bellow must only contain data of basic type so that entire struct can memcpy-able.
struct
{
uint16_t type; // GLenum
uint16_t arraySizeProduct;
int location;
uint8_t interpolation; // sh::InterpolationType
union
{
struct
{
uint8_t active : 1;
uint8_t isPatch : 1;
uint8_t hasImplicitLocation : 1;
uint8_t isArray : 1;
uint8_t isBuiltIn : 1;
uint8_t padding : 3;
} flagBits;
uint8_t flagBitsAsUByte;
};
int16_t basicTypeElementCount;
uint32_t id;
} basicDataTypeStruct;
};
ANGLE_DISABLE_STRUCT_PADDING_WARNINGS
// A varying with transform feedback enabled. If it's an array, either the whole array or one of its
// elements specified by 'arrayIndex' can set to be enabled.
struct TransformFeedbackVarying : public sh::ShaderVariable
@@ -214,7 +280,7 @@ class ProgramExecutable final : public angle::Subject
void updateCanDrawWith();
bool hasVertexShader() const { return mCanDrawWith; }
const std::vector<sh::ShaderVariable> &getProgramInputs() const { return mProgramInputs; }
const std::vector<ProgramInput> &getProgramInputs() const { return mProgramInputs; }
const std::vector<sh::ShaderVariable> &getOutputVariables() const { return mOutputVariables; }
const std::vector<VariableLocation> &getOutputLocations() const { return mOutputLocations; }
const std::vector<VariableLocation> &getSecondaryOutputLocations() const
@@ -454,7 +520,7 @@ class ProgramExecutable final : public angle::Subject
std::vector<VariableLocation> mSecondaryOutputLocations;
bool mYUVOutput;
// Vertex attributes, Fragment input varyings, etc.
std::vector<sh::ShaderVariable> mProgramInputs;
std::vector<ProgramInput> mProgramInputs;
std::vector<TransformFeedbackVarying> mLinkedTransformFeedbackVaryings;
// The size of the data written to each transform feedback buffer per vertex.
std::vector<GLsizei> mTransformFeedbackStrides;

View File

@@ -3407,7 +3407,7 @@ void GenerateLinkedProgram(const gl::Context *context,
// Force the attributes to be bound the same way as in the existing program.
// This can affect attributes that are optimized out in some implementations.
for (const sh::ShaderVariable &attrib : program->getState().getProgramInputs())
for (const gl::ProgramInput &attrib : program->getState().getProgramInputs())
{
if (gl::IsBuiltInName(attrib.name))
{
@@ -3418,9 +3418,9 @@ void GenerateLinkedProgram(const gl::Context *context,
// Separable programs may not have a VS, meaning it may not have attributes.
if (program->getExecutable().hasLinkedShaderStage(gl::ShaderType::Vertex))
{
ASSERT(attrib.location != -1);
ASSERT(attrib.getLocation() != -1);
Capture(setupCalls, CaptureBindAttribLocation(replayState, true, id,
static_cast<GLuint>(attrib.location),
static_cast<GLuint>(attrib.getLocation()),
attrib.name.c_str()));
}
}

View File

@@ -719,19 +719,20 @@ GLint GetCommonVariableProperty(const T &var, GLenum prop)
GLint GetInputResourceProperty(const Program *program, GLuint index, GLenum prop)
{
const sh::ShaderVariable &variable = program->getInputResource(index);
const ProgramInput &variable = program->getInputResource(index);
switch (prop)
{
case GL_TYPE:
return clampCast<GLint>(variable.getType());
case GL_ARRAY_SIZE:
return GetCommonVariableProperty(variable, prop);
return clampCast<GLint>(variable.getBasicTypeElementCount());
case GL_NAME_LENGTH:
return clampCast<GLint>(program->getInputResourceName(index).size() + 1u);
case GL_LOCATION:
return variable.isBuiltIn() ? GL_INVALID_INDEX : variable.location;
return variable.isBuiltIn() ? GL_INVALID_INDEX : variable.getLocation();
// The query is targeted at the set of active input variables used by the first shader stage
// of program. If program contains multiple shader stages then input variables from any
@@ -751,7 +752,7 @@ GLint GetInputResourceProperty(const Program *program, GLuint index, GLenum prop
return program->getState().getFirstAttachedShaderStageType() ==
ShaderType::TessEvaluation;
case GL_IS_PER_PATCH_EXT:
return variable.isPatch;
return variable.isPatch();
default:
UNREACHABLE();

View File

@@ -181,7 +181,7 @@ DynamicHLSL::DynamicHLSL(RendererD3D *const renderer) : mRenderer(renderer) {}
std::string DynamicHLSL::generateVertexShaderForInputLayout(
const std::string &sourceShader,
const InputLayout &inputLayout,
const std::vector<sh::ShaderVariable> &shaderAttributes,
const std::vector<gl::ProgramInput> &shaderAttributes,
const std::vector<rx::ShaderStorageBlock> &shaderStorageBlocks,
size_t baseUAVRegister) const
{
@@ -217,7 +217,7 @@ std::string DynamicHLSL::generateVertexShaderForInputLayout(
for (size_t attributeIndex = 0; attributeIndex < shaderAttributes.size(); ++attributeIndex)
{
const sh::ShaderVariable &shaderAttribute = shaderAttributes[attributeIndex];
const gl::ProgramInput &shaderAttribute = shaderAttributes[attributeIndex];
if (!shaderAttribute.name.empty())
{
ASSERT(inputIndex < MAX_VERTEX_ATTRIBS);
@@ -225,11 +225,12 @@ std::string DynamicHLSL::generateVertexShaderForInputLayout(
inputIndex < inputLayout.size() ? inputLayout[inputIndex] : angle::FormatID::NONE;
// HLSL code for input structure
if (IsMatrixType(shaderAttribute.type))
if (IsMatrixType(shaderAttribute.getType()))
{
// Matrix types are always transposed
structStream << " "
<< HLSLMatrixTypeString(TransposeMatrixType(shaderAttribute.type));
<< HLSLMatrixTypeString(
TransposeMatrixType(shaderAttribute.getType()));
}
else
{
@@ -246,7 +247,7 @@ std::string DynamicHLSL::generateVertexShaderForInputLayout(
structStream << " ";
HLSLComponentTypeString(structStream, componentType,
VariableComponentCount(shaderAttribute.type));
VariableComponentCount(shaderAttribute.getType()));
}
}
@@ -263,7 +264,7 @@ std::string DynamicHLSL::generateVertexShaderForInputLayout(
else
{
structStream << "TEXCOORD" << semanticIndex;
semanticIndex += VariableRegisterCount(shaderAttribute.type);
semanticIndex += VariableRegisterCount(shaderAttribute.getType());
}
structStream << ";\n";
@@ -274,7 +275,7 @@ std::string DynamicHLSL::generateVertexShaderForInputLayout(
// Mismatched vertex attribute to vertex input may result in an undefined
// data reinterpretation (eg for pure integer->float, float->pure integer)
// TODO: issue warning with gl debug info extension, when supported
if (IsMatrixType(shaderAttribute.type) ||
if (IsMatrixType(shaderAttribute.getType()) ||
(mRenderer->getVertexConversionType(vertexFormatID) & VERTEX_CONVERT_GPU) != 0)
{
GenerateAttributeConversionHLSL(vertexFormatID, shaderAttribute, initStream);
@@ -292,7 +293,7 @@ std::string DynamicHLSL::generateVertexShaderForInputLayout(
initStream << ";\n";
inputIndex += VariableRowCount(TransposeMatrixType(shaderAttribute.type));
inputIndex += VariableRowCount(TransposeMatrixType(shaderAttribute.getType()));
}
}
@@ -1464,18 +1465,18 @@ std::string DynamicHLSL::generateGeometryShaderHLSL(const gl::Caps &caps,
// static
void DynamicHLSL::GenerateAttributeConversionHLSL(angle::FormatID vertexFormatID,
const sh::ShaderVariable &shaderAttrib,
const gl::ProgramInput &shaderAttrib,
std::ostringstream &outStream)
{
// Matrix
if (IsMatrixType(shaderAttrib.type))
if (IsMatrixType(shaderAttrib.getType()))
{
outStream << "transpose(input." << DecorateVariable(shaderAttrib.name) << ")";
return;
}
GLenum shaderComponentType = VariableComponentType(shaderAttrib.type);
int shaderComponentCount = VariableComponentCount(shaderAttrib.type);
GLenum shaderComponentType = VariableComponentType(shaderAttrib.getType());
int shaderComponentCount = VariableComponentCount(shaderAttrib.getType());
const gl::VertexFormat &vertexFormat = gl::GetVertexFormatFromID(vertexFormatID);
// Perform integer to float conversion (if necessary)

View File

@@ -152,7 +152,7 @@ class DynamicHLSL : angle::NonCopyable
std::string generateVertexShaderForInputLayout(
const std::string &sourceShader,
const gl::InputLayout &inputLayout,
const std::vector<sh::ShaderVariable> &shaderAttributes,
const std::vector<gl::ProgramInput> &shaderAttributes,
const std::vector<rx::ShaderStorageBlock> &shaderStorageBlocks,
size_t baseUAVRegister) const;
std::string generatePixelShaderForOutputSignature(
@@ -207,7 +207,7 @@ class DynamicHLSL : angle::NonCopyable
std::ostringstream &hlslStream) const;
static void GenerateAttributeConversionHLSL(angle::FormatID vertexFormatID,
const sh::ShaderVariable &shaderAttrib,
const gl::ProgramInput &shaderAttrib,
std::ostringstream &outStream);
};

View File

@@ -30,21 +30,21 @@ namespace rx
namespace
{
GLenum GetGLSLAttributeType(const std::vector<sh::ShaderVariable> &shaderAttributes, size_t index)
GLenum GetGLSLAttributeType(const std::vector<gl::ProgramInput> &shaderAttributes, size_t index)
{
// Count matrices differently
for (const sh::ShaderVariable &attrib : shaderAttributes)
for (const gl::ProgramInput &attrib : shaderAttributes)
{
if (attrib.location == -1)
if (attrib.getLocation() == -1)
{
continue;
}
GLenum transposedType = gl::TransposeMatrixType(attrib.type);
GLenum transposedType = gl::TransposeMatrixType(attrib.getType());
int rows = gl::VariableRowCount(transposedType);
int intIndex = static_cast<int>(index);
if (intIndex >= attrib.location && intIndex < attrib.location + rows)
if (intIndex >= attrib.getLocation() && intIndex < attrib.getLocation() + rows)
{
return transposedType;
}

View File

@@ -290,14 +290,14 @@ std::unique_ptr<LinkEvent> ProgramGL::link(const gl::Context *context,
}
// Bind attribute locations to match the GL layer.
for (const sh::ShaderVariable &attribute : mState.getProgramInputs())
for (const gl::ProgramInput &attribute : mState.getProgramInputs())
{
if (!attribute.active || attribute.isBuiltIn())
if (!attribute.isActive() || attribute.isBuiltIn())
{
continue;
}
mFunctions->bindAttribLocation(mProgramID, attribute.location,
mFunctions->bindAttribLocation(mProgramID, attribute.getLocation(),
attribute.mappedName.c_str());
}

View File

@@ -676,7 +676,7 @@ void ProgramMtl::linkUpdateHasFlatAttributes(const gl::Context *context)
const auto &programInputs = mState.getProgramInputs();
for (auto &attribute : programInputs)
{
if (attribute.interpolation == sh::INTERPOLATION_FLAT)
if (attribute.getInterpolation() == sh::INTERPOLATION_FLAT)
{
mProgramHasFlatAttributes = true;
return;

View File

@@ -71,7 +71,7 @@ class VertexArrayMtl : public VertexArrayImpl
private:
void reset(ContextMtl *context);
void getVertexAttribFormatAndArraySize(const sh::ShaderVariable &var,
void getVertexAttribFormatAndArraySize(const gl::ProgramInput &var,
MTLVertexFormat *formatOut,
uint32_t *arraySizeOut);

View File

@@ -328,14 +328,14 @@ angle::Result VertexArrayMtl::syncState(const gl::Context *context,
return angle::Result::Continue;
}
ANGLE_INLINE void VertexArrayMtl::getVertexAttribFormatAndArraySize(const sh::ShaderVariable &var,
ANGLE_INLINE void VertexArrayMtl::getVertexAttribFormatAndArraySize(const gl::ProgramInput &var,
MTLVertexFormat *formatOut,
uint32_t *arraySizeOut)
{
uint32_t arraySize = var.getArraySizeProduct();
MTLVertexFormat format;
switch (var.type)
switch (var.getType())
{
case GL_INT:
case GL_INT_VEC2:
@@ -437,11 +437,11 @@ angle::Result VertexArrayMtl::setupDraw(const gl::Context *glContext,
// Use default attribute
// Need to find the attribute having the exact binding location = v in the program
// inputs list to retrieve its coresponding data type:
const std::vector<sh::ShaderVariable> &programInputs =
const std::vector<gl::ProgramInput> &programInputs =
programState.getProgramInputs();
std::vector<sh::ShaderVariable>::const_iterator attribInfoIte = std::find_if(
begin(programInputs), end(programInputs), [v](const sh::ShaderVariable &sv) {
return static_cast<uint32_t>(sv.location) == v;
std::vector<gl::ProgramInput>::const_iterator attribInfoIte = std::find_if(
begin(programInputs), end(programInputs), [v](const gl::ProgramInput &sv) {
return static_cast<uint32_t>(sv.getLocation()) == v;
});
if (attribInfoIte == end(programInputs))

View File

@@ -173,7 +173,7 @@ std::string updateShaderAttributes(std::string shaderSourceIn, const gl::Program
std::unordered_map<std::string, uint32_t> attributeBindings;
for (auto &attribute : programAttributes)
{
const int regs = gl::VariableRegisterCount(attribute.type);
const int regs = gl::VariableRegisterCount(attribute.getType());
if (regs > 1)
{
for (int i = 0; i < regs; i++)
@@ -181,7 +181,7 @@ std::string updateShaderAttributes(std::string shaderSourceIn, const gl::Program
stream.str("");
stream << " " << kUserDefinedNamePrefix << attribute.name << "_"
<< std::to_string(i) << sh::kUnassignedAttributeString;
attributeBindings.insert({std::string(stream.str()), i + attribute.location});
attributeBindings.insert({std::string(stream.str()), i + attribute.getLocation()});
}
}
else
@@ -189,7 +189,7 @@ std::string updateShaderAttributes(std::string shaderSourceIn, const gl::Program
stream.str("");
stream << " " << kUserDefinedNamePrefix << attribute.name
<< sh::kUnassignedAttributeString;
attributeBindings.insert({std::string(stream.str()), attribute.location});
attributeBindings.insert({std::string(stream.str()), attribute.getLocation()});
stream.str("");
}
}

View File

@@ -283,9 +283,9 @@ void AssignAttributeLocations(const gl::ProgramExecutable &programExecutable,
bool hasAliasingAttributes = false;
// Assign attribute locations for the vertex shader.
for (const sh::ShaderVariable &attribute : programExecutable.getProgramInputs())
for (const gl::ProgramInput &attribute : programExecutable.getProgramInputs())
{
ASSERT(attribute.active);
ASSERT(attribute.isActive());
if (std::find(implicitInputs.begin(), implicitInputs.end(), attribute.name) !=
implicitInputs.end())
@@ -293,14 +293,14 @@ void AssignAttributeLocations(const gl::ProgramExecutable &programExecutable,
continue;
}
const uint8_t colCount = static_cast<uint8_t>(gl::VariableColumnCount(attribute.type));
const uint8_t rowCount = static_cast<uint8_t>(gl::VariableRowCount(attribute.type));
const uint8_t colCount = static_cast<uint8_t>(gl::VariableColumnCount(attribute.getType()));
const uint8_t rowCount = static_cast<uint8_t>(gl::VariableRowCount(attribute.getType()));
const bool isMatrix = colCount > 1 && rowCount > 1;
const uint8_t componentCount = isMatrix ? rowCount : colCount;
const uint8_t locationCount = isMatrix ? colCount : rowCount;
AddLocationInfo(variableInfoMapOut, shaderType, attribute.id, attribute.location,
AddLocationInfo(variableInfoMapOut, shaderType, attribute.getId(), attribute.getLocation(),
ShaderInterfaceVariableInfo::kInvalid, componentCount, locationCount);
// Detect if there are aliasing attributes.
@@ -309,7 +309,7 @@ void AssignAttributeLocations(const gl::ProgramExecutable &programExecutable,
{
for (uint8_t offset = 0; offset < locationCount; ++offset)
{
uint32_t location = attribute.location + offset;
uint32_t location = attribute.getLocation() + offset;
// If there's aliasing, no need for futher processing.
if (isLocationAssigned.test(location))