Group all ProgramExecutable basic data type members into a struct

So that we can load/save with a simple memcpy.

Bug: b/275102061
Change-Id: I178404fd72b615174a7a0412ea5482ae2bea2f80
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4785567
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-16 11:53:27 -07:00
committed by Angle LUCI CQ
parent cf2c9c5607
commit c34f83d9a3
5 changed files with 271 additions and 409 deletions

View File

@@ -787,6 +787,8 @@ class Range
typedef Range<int> RangeI;
typedef Range<unsigned int> RangeUI;
static_assert(std::is_trivially_copyable<RangeUI>(),
"RangeUI should be trivial copyable so that we can memcpy");
struct IndexRange
{

View File

@@ -997,13 +997,13 @@ Optional<GLuint> ProgramState::getSamplerIndex(UniformLocation location) const
bool ProgramState::isSamplerUniformIndex(GLuint index) const
{
return mExecutable->mSamplerUniformRange.contains(index);
return mExecutable->mPODStruct.samplerUniformRange.contains(index);
}
GLuint ProgramState::getSamplerIndexFromUniformIndex(GLuint uniformIndex) const
{
ASSERT(isSamplerUniformIndex(uniformIndex));
return uniformIndex - mExecutable->mSamplerUniformRange.low();
return uniformIndex - mExecutable->mPODStruct.samplerUniformRange.low();
}
GLuint ProgramState::getUniformIndexFromSamplerIndex(GLuint samplerIndex) const
@@ -1013,13 +1013,13 @@ GLuint ProgramState::getUniformIndexFromSamplerIndex(GLuint samplerIndex) const
bool ProgramState::isImageUniformIndex(GLuint index) const
{
return mExecutable->mImageUniformRange.contains(index);
return mExecutable->mPODStruct.imageUniformRange.contains(index);
}
GLuint ProgramState::getImageIndexFromUniformIndex(GLuint uniformIndex) const
{
ASSERT(isImageUniformIndex(uniformIndex));
return uniformIndex - mExecutable->mImageUniformRange.low();
return uniformIndex - mExecutable->mPODStruct.imageUniformRange.low();
}
GLuint ProgramState::getAttributeLocation(const std::string &name) const
@@ -1364,8 +1364,8 @@ angle::Result Program::linkImpl(const Context *context)
gl::Shader *vertexShader = mState.mAttachedShaders[ShaderType::Vertex];
if (vertexShader)
{
mState.mNumViews = vertexShader->getNumViews(context);
mState.mExecutable->mHasClipDistance = vertexShader->hasClipDistance();
mState.mNumViews = vertexShader->getNumViews(context);
mState.mExecutable->mPODStruct.hasClipDistance = vertexShader->hasClipDistance();
mState.mSpecConstUsageBits |= vertexShader->getSpecConstUsageBits();
}
@@ -1382,10 +1382,10 @@ angle::Result Program::linkImpl(const Context *context)
return angle::Result::Continue;
}
mState.mExecutable->mHasDiscard = fragmentShader->hasDiscard();
mState.mExecutable->mEnablesPerSampleShading =
mState.mExecutable->mPODStruct.hasDiscard = fragmentShader->hasDiscard();
mState.mExecutable->mPODStruct.enablesPerSampleShading =
fragmentShader->enablesPerSampleShading();
mState.mExecutable->mAdvancedBlendEquations =
mState.mExecutable->mPODStruct.advancedBlendEquations =
fragmentShader->getAdvancedBlendEquations();
mState.mSpecConstUsageBits |= fragmentShader->getSpecConstUsageBits();
}
@@ -1884,31 +1884,31 @@ GLint Program::getGeometryShaderMaxVertices() const
GLint Program::getTessControlShaderVertices() const
{
ASSERT(!mLinkingState && mState.mExecutable);
return mState.mExecutable->mTessControlShaderVertices;
return mState.mExecutable->mPODStruct.tessControlShaderVertices;
}
GLenum Program::getTessGenMode() const
{
ASSERT(!mLinkingState && mState.mExecutable);
return mState.mExecutable->mTessGenMode;
return mState.mExecutable->mPODStruct.tessGenMode;
}
GLenum Program::getTessGenPointMode() const
{
ASSERT(!mLinkingState && mState.mExecutable);
return mState.mExecutable->mTessGenPointMode;
return mState.mExecutable->mPODStruct.tessGenPointMode;
}
GLenum Program::getTessGenSpacing() const
{
ASSERT(!mLinkingState && mState.mExecutable);
return mState.mExecutable->mTessGenSpacing;
return mState.mExecutable->mPODStruct.tessGenSpacing;
}
GLenum Program::getTessGenVertexOrder() const
{
ASSERT(!mLinkingState && mState.mExecutable);
return mState.mExecutable->mTessGenVertexOrder;
return mState.mExecutable->mPODStruct.tessGenVertexOrder;
}
const ProgramInput &Program::getInputResource(size_t index) const
@@ -2769,7 +2769,7 @@ void Program::setTransformFeedbackVaryings(GLsizei count,
mState.mTransformFeedbackVaryingNames[i] = varyings[i];
}
mState.mExecutable->mTransformFeedbackBufferMode = bufferMode;
mState.mExecutable->mPODStruct.transformFeedbackBufferMode = bufferMode;
}
void Program::getTransformFeedbackVarying(GLuint index,
@@ -2968,10 +2968,12 @@ bool Program::linkValidateShaders(const Context *context, InfoLog &infoLog)
return false;
}
mState.mExecutable->mGeometryShaderInputPrimitiveType = inputPrimitive.value();
mState.mExecutable->mGeometryShaderOutputPrimitiveType = outputPrimitive.value();
mState.mExecutable->mGeometryShaderMaxVertices = maxVertices.value();
mState.mExecutable->mGeometryShaderInvocations =
mState.mExecutable->mPODStruct.geometryShaderInputPrimitiveType =
inputPrimitive.value();
mState.mExecutable->mPODStruct.geometryShaderOutputPrimitiveType =
outputPrimitive.value();
mState.mExecutable->mPODStruct.geometryShaderMaxVertices = maxVertices.value();
mState.mExecutable->mPODStruct.geometryShaderInvocations =
geometryShader->getGeometryShaderInvocations(context);
}
@@ -2994,7 +2996,7 @@ bool Program::linkValidateShaders(const Context *context, InfoLog &infoLog)
return false;
}
mState.mExecutable->mTessControlShaderVertices = tcsShaderVertices;
mState.mExecutable->mPODStruct.tessControlShaderVertices = tcsShaderVertices;
}
Shader *tessEvaluationShader = shaders[ShaderType::TessEvaluation];
@@ -3017,11 +3019,12 @@ bool Program::linkValidateShaders(const Context *context, InfoLog &infoLog)
return false;
}
mState.mExecutable->mTessGenMode = tesPrimitiveMode;
mState.mExecutable->mTessGenSpacing = tessEvaluationShader->getTessGenSpacing(context);
mState.mExecutable->mTessGenVertexOrder =
mState.mExecutable->mPODStruct.tessGenMode = tesPrimitiveMode;
mState.mExecutable->mPODStruct.tessGenSpacing =
tessEvaluationShader->getTessGenSpacing(context);
mState.mExecutable->mPODStruct.tessGenVertexOrder =
tessEvaluationShader->getTessGenVertexOrder(context);
mState.mExecutable->mTessGenPointMode =
mState.mExecutable->mPODStruct.tessGenPointMode =
tessEvaluationShader->getTessGenPointMode(context);
}
}
@@ -3295,8 +3298,8 @@ bool Program::linkAttributes(const Context *context, InfoLog &infoLog)
}
}
ASSERT(mState.mExecutable->mAttributesTypeMask.none());
ASSERT(mState.mExecutable->mAttributesMask.none());
ASSERT(mState.mExecutable->mPODStruct.attributesTypeMask.none());
ASSERT(mState.mExecutable->mPODStruct.attributesMask.none());
// Prune inactive attributes. This step is only needed on shaderVersion >= 300 since on earlier
// shader versions we're only processing active attributes to begin with.
@@ -3328,16 +3331,16 @@ bool Program::linkAttributes(const Context *context, InfoLog &infoLog)
// Built-in active program inputs don't have a bound attribute.
if (!attribute.isBuiltIn())
{
mState.mExecutable->mActiveAttribLocationsMask.set(location);
mState.mExecutable->mMaxActiveAttribLocation =
std::max(mState.mExecutable->mMaxActiveAttribLocation, location + 1);
mState.mExecutable->mPODStruct.activeAttribLocationsMask.set(location);
mState.mExecutable->mPODStruct.maxActiveAttribLocation =
std::max(mState.mExecutable->mPODStruct.maxActiveAttribLocation, location + 1);
ComponentType componentType =
GLenumToComponentType(VariableComponentType(attribute.getType()));
SetComponentTypeMask(componentType, location,
&mState.mExecutable->mAttributesTypeMask);
mState.mExecutable->mAttributesMask.set(location);
&mState.mExecutable->mPODStruct.attributesTypeMask);
mState.mExecutable->mPODStruct.attributesMask.set(location);
location++;
}

View File

@@ -273,42 +273,22 @@ void LoadUniforms(BinaryInputStream *stream,
}
} // anonymous namespace
ProgramExecutable::ProgramExecutable()
: mMaxActiveAttribLocation(0),
mAttributesTypeMask(0),
mAttributesMask(0),
mActiveSamplerRefCounts{},
mCanDrawWith(false),
mYUVOutput(false),
mTransformFeedbackBufferMode(GL_INTERLEAVED_ATTRIBS),
mDefaultUniformRange(0, 0),
mSamplerUniformRange(0, 0),
mImageUniformRange(0, 0),
mAtomicCounterUniformRange(0, 0),
mFragmentInoutRange(0, 0),
mHasClipDistance(false),
mHasDiscard(false),
mEnablesPerSampleShading(false),
// [GL_EXT_geometry_shader] Table 20.22
mGeometryShaderInputPrimitiveType(PrimitiveMode::Triangles),
mGeometryShaderOutputPrimitiveType(PrimitiveMode::TriangleStrip),
mGeometryShaderInvocations(1),
mGeometryShaderMaxVertices(0),
mTessControlShaderVertices(0),
mTessGenMode(GL_NONE),
mTessGenSpacing(GL_NONE),
mTessGenVertexOrder(GL_NONE),
mTessGenPointMode(GL_NONE)
ProgramExecutable::PODStruct::PODStruct() = default;
ProgramExecutable::PODStruct::PODStruct(const PODStruct &other) = default;
ProgramExecutable::ProgramExecutable() : mActiveSamplerRefCounts{}, mCanDrawWith(false)
{
memset(&mPODStruct, 0, sizeof(mPODStruct));
mPODStruct.geometryShaderInputPrimitiveType = PrimitiveMode::Triangles;
mPODStruct.geometryShaderOutputPrimitiveType = PrimitiveMode::TriangleStrip;
mPODStruct.geometryShaderInvocations = 1;
mPODStruct.transformFeedbackBufferMode = GL_INTERLEAVED_ATTRIBS;
reset(true);
}
ProgramExecutable::ProgramExecutable(const ProgramExecutable &other)
: mLinkedShaderStages(other.mLinkedShaderStages),
mActiveAttribLocationsMask(other.mActiveAttribLocationsMask),
mMaxActiveAttribLocation(other.mMaxActiveAttribLocation),
mAttributesTypeMask(other.mAttributesTypeMask),
mAttributesMask(other.mAttributesMask),
: mPODStruct(other.mPODStruct),
mActiveSamplersMask(other.mActiveSamplersMask),
mActiveSamplerRefCounts(other.mActiveSamplerRefCounts),
mActiveSamplerTypes(other.mActiveSamplerTypes),
@@ -321,27 +301,16 @@ ProgramExecutable::ProgramExecutable(const ProgramExecutable &other)
mOutputVariables(other.mOutputVariables),
mOutputLocations(other.mOutputLocations),
mSecondaryOutputLocations(other.mSecondaryOutputLocations),
mYUVOutput(other.mYUVOutput),
mProgramInputs(other.mProgramInputs),
mLinkedTransformFeedbackVaryings(other.mLinkedTransformFeedbackVaryings),
mTransformFeedbackStrides(other.mTransformFeedbackStrides),
mTransformFeedbackBufferMode(other.mTransformFeedbackBufferMode),
mUniforms(other.mUniforms),
mUniformNames(other.mUniformNames),
mUniformMappedNames(other.mUniformMappedNames),
mDefaultUniformRange(other.mDefaultUniformRange),
mSamplerUniformRange(other.mSamplerUniformRange),
mImageUniformRange(other.mImageUniformRange),
mAtomicCounterUniformRange(other.mAtomicCounterUniformRange),
mUniformBlocks(other.mUniformBlocks),
mActiveUniformBlockBindings(other.mActiveUniformBlockBindings),
mAtomicCounterBuffers(other.mAtomicCounterBuffers),
mShaderStorageBlocks(other.mShaderStorageBlocks),
mFragmentInoutRange(other.mFragmentInoutRange),
mHasClipDistance(other.mHasClipDistance),
mHasDiscard(other.mHasDiscard),
mEnablesPerSampleShading(other.mEnablesPerSampleShading),
mAdvancedBlendEquations(other.mAdvancedBlendEquations)
mShaderStorageBlocks(other.mShaderStorageBlocks)
{
reset(true);
}
@@ -354,10 +323,37 @@ void ProgramExecutable::reset(bool clearInfoLog)
{
resetInfoLog();
}
mActiveAttribLocationsMask.reset();
mAttributesTypeMask.reset();
mAttributesMask.reset();
mMaxActiveAttribLocation = 0;
mPODStruct.activeAttribLocationsMask.reset();
mPODStruct.attributesTypeMask.reset();
mPODStruct.attributesMask.reset();
mPODStruct.maxActiveAttribLocation = 0;
mPODStruct.activeOutputVariablesMask.reset();
mPODStruct.defaultUniformRange = RangeUI(0, 0);
mPODStruct.samplerUniformRange = RangeUI(0, 0);
mPODStruct.imageUniformRange = RangeUI(0, 0);
mPODStruct.atomicCounterUniformRange = RangeUI(0, 0);
mPODStruct.fragmentInoutRange = RangeUI(0, 0);
mPODStruct.hasClipDistance = false;
mPODStruct.hasDiscard = false;
mPODStruct.enablesPerSampleShading = false;
mPODStruct.hasYUVOutput = false;
mPODStruct.advancedBlendEquations.reset();
mPODStruct.geometryShaderInputPrimitiveType = PrimitiveMode::Triangles;
mPODStruct.geometryShaderOutputPrimitiveType = PrimitiveMode::TriangleStrip;
mPODStruct.geometryShaderInvocations = 1;
mPODStruct.geometryShaderMaxVertices = 0;
mPODStruct.tessControlShaderVertices = 0;
mPODStruct.tessGenMode = GL_NONE;
mPODStruct.tessGenSpacing = GL_NONE;
mPODStruct.tessGenVertexOrder = GL_NONE;
mPODStruct.tessGenPointMode = GL_NONE;
mPODStruct.drawBufferTypeMask.reset();
mActiveSamplersMask.reset();
mActiveSamplerRefCounts = {};
@@ -379,36 +375,11 @@ void ProgramExecutable::reset(bool clearInfoLog)
mAtomicCounterBuffers.clear();
mOutputVariables.clear();
mOutputLocations.clear();
mActiveOutputVariablesMask.reset();
mSecondaryOutputLocations.clear();
mYUVOutput = false;
mSamplerBindings.clear();
mImageBindings.clear();
mDefaultUniformRange = RangeUI(0, 0);
mSamplerUniformRange = RangeUI(0, 0);
mImageUniformRange = RangeUI(0, 0);
mAtomicCounterUniformRange = RangeUI(0, 0);
mFragmentInoutRange = RangeUI(0, 0);
mHasClipDistance = false;
mHasDiscard = false;
mEnablesPerSampleShading = false;
mAdvancedBlendEquations.reset();
mGeometryShaderInputPrimitiveType = PrimitiveMode::Triangles;
mGeometryShaderOutputPrimitiveType = PrimitiveMode::TriangleStrip;
mGeometryShaderInvocations = 1;
mGeometryShaderMaxVertices = 0;
mTessControlShaderVertices = 0;
mTessGenMode = GL_NONE;
mTessGenSpacing = GL_NONE;
mTessGenVertexOrder = GL_NONE;
mTessGenPointMode = GL_NONE;
mOutputVariableTypes.clear();
mDrawBufferTypeMask.reset();
}
void ProgramExecutable::load(bool isSeparable, gl::BinaryInputStream *stream)
@@ -416,35 +387,11 @@ void ProgramExecutable::load(bool isSeparable, gl::BinaryInputStream *stream)
static_assert(MAX_VERTEX_ATTRIBS * 2 <= sizeof(uint32_t) * 8,
"Too many vertex attribs for mask: All bits of mAttributesTypeMask types and "
"mask fit into 32 bits each");
mAttributesTypeMask = gl::ComponentTypeMask(stream->readInt<uint32_t>());
mAttributesMask = gl::AttributesMask(stream->readInt<uint32_t>());
mActiveAttribLocationsMask = gl::AttributesMask(stream->readInt<uint32_t>());
mMaxActiveAttribLocation = stream->readInt<unsigned int>();
static_assert(IMPLEMENTATION_MAX_DRAW_BUFFERS * 2 <= 8 * sizeof(uint32_t),
"All bits of mDrawBufferTypeMask and mActiveOutputVariables types and mask fit "
"into 32 bits each");
unsigned int fragmentInoutRangeLow = stream->readInt<uint32_t>();
unsigned int fragmentInoutRangeHigh = stream->readInt<uint32_t>();
mFragmentInoutRange = RangeUI(fragmentInoutRangeLow, fragmentInoutRangeHigh);
mHasClipDistance = stream->readBool();
mHasDiscard = stream->readBool();
mEnablesPerSampleShading = stream->readBool();
static_assert(sizeof(mAdvancedBlendEquations.bits()) == sizeof(uint32_t));
mAdvancedBlendEquations = BlendEquationBitSet(stream->readInt<uint32_t>());
mLinkedShaderStages = ShaderBitSet(stream->readInt<uint8_t>());
mGeometryShaderInputPrimitiveType = stream->readEnum<PrimitiveMode>();
mGeometryShaderOutputPrimitiveType = stream->readEnum<PrimitiveMode>();
mGeometryShaderInvocations = stream->readInt<int>();
mGeometryShaderMaxVertices = stream->readInt<int>();
mTessControlShaderVertices = stream->readInt<int>();
mTessGenMode = stream->readInt<GLenum>();
mTessGenSpacing = stream->readInt<GLenum>();
mTessGenVertexOrder = stream->readInt<GLenum>();
mTessGenPointMode = stream->readInt<GLenum>();
stream->readBytes(reinterpret_cast<unsigned char *>(&mPODStruct), sizeof(mPODStruct));
LoadProgramInputs(stream, &mProgramInputs);
LoadUniforms(stream, &mUniforms, &mUniformNames, &mUniformMappedNames);
@@ -494,8 +441,6 @@ void ProgramExecutable::load(bool isSeparable, gl::BinaryInputStream *stream)
varying.arrayIndex = stream->readInt<GLuint>();
}
mTransformFeedbackBufferMode = stream->readInt<GLint>();
size_t outputCount = stream->readInt<size_t>();
ASSERT(getOutputVariables().empty());
mOutputVariables.resize(outputCount);
@@ -518,9 +463,6 @@ void ProgramExecutable::load(bool isSeparable, gl::BinaryInputStream *stream)
stream->readBool(&locationData.ignored);
}
mActiveOutputVariablesMask =
gl::DrawBufferMask(stream->readInt<gl::DrawBufferMask::value_type>());
size_t outputTypeCount = stream->readInt<size_t>();
mOutputVariableTypes.resize(outputTypeCount);
for (size_t outputIndex = 0; outputIndex < outputTypeCount; ++outputIndex)
@@ -528,13 +470,6 @@ void ProgramExecutable::load(bool isSeparable, gl::BinaryInputStream *stream)
mOutputVariableTypes[outputIndex] = stream->readInt<GLenum>();
}
static_assert(IMPLEMENTATION_MAX_DRAW_BUFFERS * 2 <= 8 * sizeof(uint32_t),
"All bits of mDrawBufferTypeMask and mActiveOutputVariables types and mask fit "
"into 32 bits each");
mDrawBufferTypeMask = gl::ComponentTypeMask(stream->readInt<uint32_t>());
stream->readBool(&mYUVOutput);
size_t secondaryOutputVarCount = stream->readInt<size_t>();
ASSERT(mSecondaryOutputLocations.empty());
mSecondaryOutputLocations.resize(secondaryOutputVarCount);
@@ -546,14 +481,6 @@ void ProgramExecutable::load(bool isSeparable, gl::BinaryInputStream *stream)
stream->readBool(&locationData.ignored);
}
unsigned int defaultUniformRangeLow = stream->readInt<unsigned int>();
unsigned int defaultUniformRangeHigh = stream->readInt<unsigned int>();
mDefaultUniformRange = RangeUI(defaultUniformRangeLow, defaultUniformRangeHigh);
unsigned int samplerRangeLow = stream->readInt<unsigned int>();
unsigned int samplerRangeHigh = stream->readInt<unsigned int>();
mSamplerUniformRange = RangeUI(samplerRangeLow, samplerRangeHigh);
size_t samplerCount = stream->readInt<size_t>();
ASSERT(mSamplerBindings.empty());
mSamplerBindings.resize(samplerCount);
@@ -567,10 +494,6 @@ void ProgramExecutable::load(bool isSeparable, gl::BinaryInputStream *stream)
samplerBinding.boundTextureUnits.resize(bindingCount, 0);
}
unsigned int imageRangeLow = stream->readInt<unsigned int>();
unsigned int imageRangeHigh = stream->readInt<unsigned int>();
mImageUniformRange = RangeUI(imageRangeLow, imageRangeHigh);
size_t imageBindingCount = stream->readInt<size_t>();
ASSERT(mImageBindings.empty());
mImageBindings.resize(imageBindingCount);
@@ -586,15 +509,11 @@ void ProgramExecutable::load(bool isSeparable, gl::BinaryInputStream *stream)
}
}
unsigned int atomicCounterRangeLow = stream->readInt<unsigned int>();
unsigned int atomicCounterRangeHigh = stream->readInt<unsigned int>();
mAtomicCounterUniformRange = RangeUI(atomicCounterRangeLow, atomicCounterRangeHigh);
// These values are currently only used by PPOs, so only load them when the program is marked
// separable to save memory.
if (isSeparable)
{
for (ShaderType shaderType : mLinkedShaderStages)
for (ShaderType shaderType : getLinkedShaderStages())
{
mLinkedOutputVaryings[shaderType].resize(stream->readInt<size_t>());
for (sh::ShaderVariable &variable : mLinkedOutputVaryings[shaderType])
@@ -625,33 +544,12 @@ void ProgramExecutable::save(bool isSeparable, gl::BinaryOutputStream *stream) c
{
static_assert(MAX_VERTEX_ATTRIBS * 2 <= sizeof(uint32_t) * 8,
"All bits of mAttributesTypeMask types and mask fit into 32 bits each");
stream->writeInt(static_cast<uint32_t>(mAttributesTypeMask.to_ulong()));
stream->writeInt(static_cast<uint32_t>(mAttributesMask.to_ulong()));
stream->writeInt(static_cast<uint32_t>(mActiveAttribLocationsMask.to_ulong()));
stream->writeInt(mMaxActiveAttribLocation);
static_assert(
IMPLEMENTATION_MAX_DRAW_BUFFERS * 2 <= 8 * sizeof(uint32_t),
"All bits of mDrawBufferTypeMask and mActiveOutputVariables can be contained in 32 bits");
stream->writeInt(mFragmentInoutRange.low());
stream->writeInt(mFragmentInoutRange.high());
stream->writeBool(mHasClipDistance);
stream->writeBool(mHasDiscard);
stream->writeBool(mEnablesPerSampleShading);
stream->writeInt(mAdvancedBlendEquations.bits());
stream->writeInt(mLinkedShaderStages.bits());
ASSERT(mGeometryShaderInvocations >= 1 && mGeometryShaderMaxVertices >= 0);
stream->writeEnum(mGeometryShaderInputPrimitiveType);
stream->writeEnum(mGeometryShaderOutputPrimitiveType);
stream->writeInt(mGeometryShaderInvocations);
stream->writeInt(mGeometryShaderMaxVertices);
stream->writeInt(mTessControlShaderVertices);
stream->writeInt(mTessGenMode);
stream->writeInt(mTessGenSpacing);
stream->writeInt(mTessGenVertexOrder);
stream->writeInt(mTessGenPointMode);
ASSERT(mPODStruct.geometryShaderInvocations >= 1 && mPODStruct.geometryShaderMaxVertices >= 0);
stream->writeBytes(reinterpret_cast<const unsigned char *>(&mPODStruct), sizeof(mPODStruct));
SaveProgramInputs(stream, mProgramInputs);
SaveUniforms(stream, mUniforms, mUniformNames, mUniformMappedNames);
@@ -684,8 +582,6 @@ void ProgramExecutable::save(bool isSeparable, gl::BinaryOutputStream *stream) c
stream->writeIntOrNegOne(var.arrayIndex);
}
stream->writeInt(getTransformFeedbackBufferMode());
stream->writeInt(getOutputVariables().size());
for (const sh::ShaderVariable &output : getOutputVariables())
{
@@ -702,21 +598,12 @@ void ProgramExecutable::save(bool isSeparable, gl::BinaryOutputStream *stream) c
stream->writeBool(outputVar.ignored);
}
stream->writeInt(static_cast<int>(mActiveOutputVariablesMask.to_ulong()));
stream->writeInt(mOutputVariableTypes.size());
for (const auto &outputVariableType : mOutputVariableTypes)
{
stream->writeInt(outputVariableType);
}
static_assert(
IMPLEMENTATION_MAX_DRAW_BUFFERS * 2 <= 8 * sizeof(uint32_t),
"All bits of mDrawBufferTypeMask and mActiveOutputVariables can be contained in 32 bits");
stream->writeInt(static_cast<int>(mDrawBufferTypeMask.to_ulong()));
stream->writeBool(mYUVOutput);
stream->writeInt(getSecondaryOutputLocations().size());
for (const auto &outputVar : getSecondaryOutputLocations())
{
@@ -725,12 +612,6 @@ void ProgramExecutable::save(bool isSeparable, gl::BinaryOutputStream *stream) c
stream->writeBool(outputVar.ignored);
}
stream->writeInt(getDefaultUniformRange().low());
stream->writeInt(getDefaultUniformRange().high());
stream->writeInt(getSamplerUniformRange().low());
stream->writeInt(getSamplerUniformRange().high());
stream->writeInt(getSamplerBindings().size());
for (const auto &samplerBinding : getSamplerBindings())
{
@@ -740,9 +621,6 @@ void ProgramExecutable::save(bool isSeparable, gl::BinaryOutputStream *stream) c
stream->writeInt(samplerBinding.boundTextureUnits.size());
}
stream->writeInt(getImageUniformRange().low());
stream->writeInt(getImageUniformRange().high());
stream->writeInt(getImageBindings().size());
for (const auto &imageBinding : getImageBindings())
{
@@ -754,14 +632,11 @@ void ProgramExecutable::save(bool isSeparable, gl::BinaryOutputStream *stream) c
}
}
stream->writeInt(getAtomicCounterUniformRange().low());
stream->writeInt(getAtomicCounterUniformRange().high());
// These values are currently only used by PPOs, so only save them when the program is marked
// separable to save memory.
if (isSeparable)
{
for (ShaderType shaderType : mLinkedShaderStages)
for (ShaderType shaderType : getLinkedShaderStages())
{
stream->writeInt(mLinkedOutputVaryings[shaderType].size());
for (const sh::ShaderVariable &shaderVariable : mLinkedOutputVaryings[shaderType])
@@ -803,64 +678,6 @@ std::string ProgramExecutable::getInfoLogString() const
return mInfoLog.str();
}
bool ProgramExecutable::isAttribLocationActive(size_t attribLocation) const
{
ASSERT(attribLocation < mActiveAttribLocationsMask.size());
return mActiveAttribLocationsMask[attribLocation];
}
AttributesMask ProgramExecutable::getAttributesMask() const
{
return mAttributesMask;
}
bool ProgramExecutable::hasDefaultUniforms() const
{
return !getDefaultUniformRange().empty();
}
bool ProgramExecutable::hasTextures() const
{
return !getSamplerBindings().empty();
}
bool ProgramExecutable::hasUniformBuffers() const
{
return !mUniformBlocks.empty();
}
bool ProgramExecutable::hasStorageBuffers() const
{
return !mShaderStorageBlocks.empty();
}
bool ProgramExecutable::hasAtomicCounterBuffers() const
{
return !mAtomicCounterBuffers.empty();
}
bool ProgramExecutable::hasImages() const
{
return !mImageBindings.empty();
}
bool ProgramExecutable::usesFramebufferFetch() const
{
return (mFragmentInoutRange.length() > 0);
}
GLuint ProgramExecutable::getUniformIndexFromImageIndex(GLuint imageIndex) const
{
ASSERT(imageIndex < mImageUniformRange.length());
return imageIndex + mImageUniformRange.low();
}
GLuint ProgramExecutable::getUniformIndexFromSamplerIndex(GLuint samplerIndex) const
{
ASSERT(samplerIndex < mSamplerUniformRange.length());
return samplerIndex + mSamplerUniformRange.low();
}
void ProgramExecutable::setActive(size_t textureUnit,
const SamplerBinding &samplerBinding,
const gl::LinkedUniform &samplerUniform)
@@ -1016,16 +833,6 @@ void ProgramExecutable::saveLinkedStateInfo(const Context *context, const Progra
}
}
bool ProgramExecutable::isYUVOutput() const
{
return mYUVOutput;
}
ShaderType ProgramExecutable::getLinkedTransformFeedbackStage() const
{
return GetLastPreFragmentStage(mLinkedShaderStages);
}
bool ProgramExecutable::linkMergedVaryings(
const Context *context,
const ProgramMergedVaryings &mergedVaryings,
@@ -1190,7 +997,7 @@ bool ProgramExecutable::linkValidateTransformFeedback(
// TODO(jmadill): Investigate implementation limits on D3D11
componentCount = VariableComponentCount(var->type) * elementCount;
if (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS &&
if (mPODStruct.transformFeedbackBufferMode == GL_SEPARATE_ATTRIBS &&
componentCount > static_cast<GLuint>(caps.maxTransformFeedbackSeparateComponents))
{
mInfoLog << "Transform feedback varying " << tfVaryingName << " components ("
@@ -1200,7 +1007,7 @@ bool ProgramExecutable::linkValidateTransformFeedback(
}
totalComponents += componentCount;
if (mTransformFeedbackBufferMode == GL_INTERLEAVED_ATTRIBS &&
if (mPODStruct.transformFeedbackBufferMode == GL_INTERLEAVED_ATTRIBS &&
totalComponents > static_cast<GLuint>(caps.maxTransformFeedbackInterleavedComponents))
{
mInfoLog << "Transform feedback varying total components (" << totalComponents
@@ -1263,7 +1070,7 @@ void ProgramExecutable::updateTransformFeedbackStrides()
return;
}
if (mTransformFeedbackBufferMode == GL_INTERLEAVED_ATTRIBS)
if (mPODStruct.transformFeedbackBufferMode == GL_INTERLEAVED_ATTRIBS)
{
mTransformFeedbackStrides.resize(1);
size_t totalSize = 0;
@@ -1335,9 +1142,9 @@ bool ProgramExecutable::linkValidateOutputVariables(
const ProgramAliasedBindings &fragmentOutputIndices)
{
ASSERT(mOutputVariableTypes.empty());
ASSERT(mActiveOutputVariablesMask.none());
ASSERT(mDrawBufferTypeMask.none());
ASSERT(!mYUVOutput);
ASSERT(mPODStruct.activeOutputVariablesMask.none());
ASSERT(mPODStruct.drawBufferTypeMask.none());
ASSERT(!mPODStruct.hasYUVOutput);
// Gather output variable types
for (const sh::ShaderVariable &outputVariable : outputVariables)
@@ -1362,17 +1169,17 @@ bool ProgramExecutable::linkValidateOutputVariables(
{
mOutputVariableTypes.resize(location + 1, GL_NONE);
}
ASSERT(location < mActiveOutputVariablesMask.size());
mActiveOutputVariablesMask.set(location);
ASSERT(location < mPODStruct.activeOutputVariablesMask.size());
mPODStruct.activeOutputVariablesMask.set(location);
mOutputVariableTypes[location] = VariableComponentType(outputVariable.type);
ComponentType componentType = GLenumToComponentType(mOutputVariableTypes[location]);
SetComponentTypeMask(componentType, location, &mDrawBufferTypeMask);
SetComponentTypeMask(componentType, location, &mPODStruct.drawBufferTypeMask);
}
if (outputVariable.yuv)
{
ASSERT(outputVariables.size() == 1);
mYUVOutput = true;
mPODStruct.hasYUVOutput = true;
}
}
@@ -1384,7 +1191,7 @@ bool ProgramExecutable::linkValidateOutputVariables(
// fragment shader outputs exceeds the implementation-dependent value of
// MAX_COMBINED_SHADER_OUTPUT_RESOURCES.
if (combinedImageUniformsCount + combinedShaderStorageBlocksCount +
mActiveOutputVariablesMask.count() >
mPODStruct.activeOutputVariablesMask.count() >
static_cast<GLuint>(caps.maxCombinedShaderOutputResources))
{
mInfoLog
@@ -1590,7 +1397,7 @@ bool ProgramExecutable::linkUniforms(
std::vector<UnusedUniform> *unusedUniformsOutOrNull,
std::vector<VariableLocation> *uniformLocationsOutOrNull)
{
UniformLinker linker(mLinkedShaderStages, shaderUniforms);
UniformLinker linker(mPODStruct.linkedShaderStages, shaderUniforms);
if (!linker.link(context->getCaps(), infoLog, uniformLocationBindings))
{
return false;
@@ -1630,7 +1437,7 @@ void ProgramExecutable::linkSamplerAndImageBindings(GLuint *combinedImageUniform
--low;
}
mFragmentInoutRange = RangeUI(low, high);
mPODStruct.fragmentInoutRange = RangeUI(low, high);
highIter = lowIter;
high = low;
@@ -1640,7 +1447,7 @@ void ProgramExecutable::linkSamplerAndImageBindings(GLuint *combinedImageUniform
--low;
}
mAtomicCounterUniformRange = RangeUI(low, high);
mPODStruct.atomicCounterUniformRange = RangeUI(low, high);
highIter = lowIter;
high = low;
@@ -1650,10 +1457,10 @@ void ProgramExecutable::linkSamplerAndImageBindings(GLuint *combinedImageUniform
--low;
}
mImageUniformRange = RangeUI(low, high);
*combinedImageUniforms = 0u;
mPODStruct.imageUniformRange = RangeUI(low, high);
*combinedImageUniforms = 0u;
// If uniform is a image type, insert it into the mImageBindings array.
for (unsigned int imageIndex : mImageUniformRange)
for (unsigned int imageIndex : mPODStruct.imageUniformRange)
{
// ES3.1 (section 7.6.1) and GLSL ES3.1 (section 4.4.5), Uniform*i{v} commands
// cannot load values into a uniform defined as an image. if declare without a
@@ -1688,10 +1495,10 @@ void ProgramExecutable::linkSamplerAndImageBindings(GLuint *combinedImageUniform
--low;
}
mSamplerUniformRange = RangeUI(low, high);
mPODStruct.samplerUniformRange = RangeUI(low, high);
// If uniform is a sampler type, insert it into the mSamplerBindings array.
for (unsigned int samplerIndex : mSamplerUniformRange)
for (unsigned int samplerIndex : mPODStruct.samplerUniformRange)
{
const auto &samplerUniform = mUniforms[samplerIndex];
TextureType textureType = SamplerTypeToTextureType(samplerUniform.getType());
@@ -1702,12 +1509,12 @@ void ProgramExecutable::linkSamplerAndImageBindings(GLuint *combinedImageUniform
}
// Whatever is left constitutes the default uniforms.
mDefaultUniformRange = RangeUI(0, low);
mPODStruct.defaultUniformRange = RangeUI(0, low);
}
bool ProgramExecutable::linkAtomicCounterBuffers(const Context *context, InfoLog &infoLog)
{
for (unsigned int index : mAtomicCounterUniformRange)
for (unsigned int index : mPODStruct.atomicCounterUniformRange)
{
auto &uniform = mUniforms[index];
@@ -1816,29 +1623,33 @@ void ProgramExecutable::copyUniformsFromProgramMap(const ShaderMap<Program *> &p
{
// Merge default uniforms.
auto getDefaultRange = [](const ProgramState &state) { return state.getDefaultUniformRange(); };
mDefaultUniformRange = AddUniforms(programs, mLinkedShaderStages, &mUniforms, &mUniformNames,
&mUniformMappedNames, getDefaultRange);
mPODStruct.defaultUniformRange =
AddUniforms(programs, mPODStruct.linkedShaderStages, &mUniforms, &mUniformNames,
&mUniformMappedNames, getDefaultRange);
// Merge sampler uniforms.
auto getSamplerRange = [](const ProgramState &state) { return state.getSamplerUniformRange(); };
mSamplerUniformRange = AddUniforms(programs, mLinkedShaderStages, &mUniforms, &mUniformNames,
&mUniformMappedNames, getSamplerRange);
mPODStruct.samplerUniformRange =
AddUniforms(programs, mPODStruct.linkedShaderStages, &mUniforms, &mUniformNames,
&mUniformMappedNames, getSamplerRange);
// Merge image uniforms.
auto getImageRange = [](const ProgramState &state) { return state.getImageUniformRange(); };
mImageUniformRange = AddUniforms(programs, mLinkedShaderStages, &mUniforms, &mUniformNames,
&mUniformMappedNames, getImageRange);
mPODStruct.imageUniformRange = AddUniforms(programs, mPODStruct.linkedShaderStages, &mUniforms,
&mUniformNames, &mUniformMappedNames, getImageRange);
// Merge atomic counter uniforms.
auto getAtomicRange = [](const ProgramState &state) {
return state.getAtomicCounterUniformRange();
};
mAtomicCounterUniformRange = AddUniforms(programs, mLinkedShaderStages, &mUniforms,
&mUniformNames, &mUniformMappedNames, getAtomicRange);
mPODStruct.atomicCounterUniformRange =
AddUniforms(programs, mPODStruct.linkedShaderStages, &mUniforms, &mUniformNames,
&mUniformMappedNames, getAtomicRange);
// Merge fragment in/out uniforms.
auto getInoutRange = [](const ProgramState &state) { return state.getFragmentInoutRange(); };
mFragmentInoutRange = AddUniforms(programs, mLinkedShaderStages, &mUniforms, &mUniformNames,
&mUniformMappedNames, getInoutRange);
auto getInoutRange = [](const ProgramState &state) { return state.getFragmentInoutRange(); };
mPODStruct.fragmentInoutRange =
AddUniforms(programs, mPODStruct.linkedShaderStages, &mUniforms, &mUniformNames,
&mUniformMappedNames, getInoutRange);
}
} // namespace gl

View File

@@ -194,40 +194,48 @@ class ProgramExecutable final : public angle::Subject
std::string getInfoLogString() const;
void resetInfoLog() { mInfoLog.reset(); }
void resetLinkedShaderStages() { mLinkedShaderStages.reset(); }
const ShaderBitSet getLinkedShaderStages() const { return mLinkedShaderStages; }
void resetLinkedShaderStages() { mPODStruct.linkedShaderStages.reset(); }
const ShaderBitSet getLinkedShaderStages() const { return mPODStruct.linkedShaderStages; }
void setLinkedShaderStages(ShaderType shaderType)
{
mLinkedShaderStages.set(shaderType);
mPODStruct.linkedShaderStages.set(shaderType);
updateCanDrawWith();
}
bool hasLinkedShaderStage(ShaderType shaderType) const
{
ASSERT(shaderType != ShaderType::InvalidEnum);
return mLinkedShaderStages[shaderType];
return mPODStruct.linkedShaderStages[shaderType];
}
size_t getLinkedShaderStageCount() const { return mLinkedShaderStages.count(); }
size_t getLinkedShaderStageCount() const { return mPODStruct.linkedShaderStages.count(); }
bool hasLinkedGraphicsShader() const
{
return mLinkedShaderStages.any() &&
mLinkedShaderStages != gl::ShaderBitSet{gl::ShaderType::Compute};
return mPODStruct.linkedShaderStages.any() &&
mPODStruct.linkedShaderStages != gl::ShaderBitSet{gl::ShaderType::Compute};
}
bool hasLinkedTessellationShader() const
{
return mLinkedShaderStages[ShaderType::TessEvaluation];
return mPODStruct.linkedShaderStages[ShaderType::TessEvaluation];
}
ShaderType getLinkedTransformFeedbackStage() const;
ShaderType getLinkedTransformFeedbackStage() const
{
return GetLastPreFragmentStage(mPODStruct.linkedShaderStages);
}
const AttributesMask &getActiveAttribLocationsMask() const
{
return mActiveAttribLocationsMask;
return mPODStruct.activeAttribLocationsMask;
}
bool isAttribLocationActive(size_t attribLocation) const;
AttributesMask getNonBuiltinAttribLocationsMask() const { return mAttributesMask; }
unsigned int getMaxActiveAttribLocation() const { return mMaxActiveAttribLocation; }
ComponentTypeMask getAttributesTypeMask() const { return mAttributesTypeMask; }
AttributesMask getAttributesMask() const;
bool isAttribLocationActive(size_t attribLocation) const
{
ASSERT(attribLocation < mPODStruct.activeAttribLocationsMask.size());
return mPODStruct.activeAttribLocationsMask[attribLocation];
}
AttributesMask getNonBuiltinAttribLocationsMask() const { return mPODStruct.attributesMask; }
unsigned int getMaxActiveAttribLocation() const { return mPODStruct.maxActiveAttribLocation; }
ComponentTypeMask getAttributesTypeMask() const { return mPODStruct.attributesTypeMask; }
AttributesMask getAttributesMask() const { return mPODStruct.attributesMask; }
const ActiveTextureMask &getActiveSamplersMask() const { return mActiveSamplersMask; }
void setActiveTextureMask(ActiveTextureMask mask) { mActiveSamplersMask = mask; }
@@ -262,17 +270,17 @@ class ProgramExecutable final : public angle::Subject
void updateActiveSamplers(const ProgramState &programState);
bool hasDefaultUniforms() const;
bool hasTextures() const;
bool hasUniformBuffers() const;
bool hasStorageBuffers() const;
bool hasAtomicCounterBuffers() const;
bool hasImages() const;
bool hasDefaultUniforms() const { return !getDefaultUniformRange().empty(); }
bool hasTextures() const { return !getSamplerBindings().empty(); }
bool hasUniformBuffers() const { return !mUniformBlocks.empty(); }
bool hasStorageBuffers() const { return !mShaderStorageBlocks.empty(); }
bool hasAtomicCounterBuffers() const { return !mAtomicCounterBuffers.empty(); }
bool hasImages() const { return !mImageBindings.empty(); }
bool hasTransformFeedbackOutput() const
{
return !getLinkedTransformFeedbackVaryings().empty();
}
bool usesFramebufferFetch() const;
bool usesFramebufferFetch() const { return (mPODStruct.fragmentInoutRange.length() > 0); }
// Count the number of uniform and storage buffer declarations, counting arrays as one.
size_t getTransformFeedbackBufferCount() const { return mTransformFeedbackStrides.size(); }
@@ -298,20 +306,26 @@ class ProgramExecutable final : public angle::Subject
const std::vector<SamplerBinding> &getSamplerBindings() const { return mSamplerBindings; }
const std::vector<ImageBinding> &getImageBindings() const { return mImageBindings; }
std::vector<ImageBinding> *getImageBindings() { return &mImageBindings; }
const RangeUI &getDefaultUniformRange() const { return mDefaultUniformRange; }
const RangeUI &getSamplerUniformRange() const { return mSamplerUniformRange; }
const RangeUI &getImageUniformRange() const { return mImageUniformRange; }
const RangeUI &getAtomicCounterUniformRange() const { return mAtomicCounterUniformRange; }
const RangeUI &getFragmentInoutRange() const { return mFragmentInoutRange; }
bool hasClipDistance() const { return mHasClipDistance; }
bool hasDiscard() const { return mHasDiscard; }
bool enablesPerSampleShading() const { return mEnablesPerSampleShading; }
BlendEquationBitSet getAdvancedBlendEquations() const { return mAdvancedBlendEquations; }
const RangeUI &getDefaultUniformRange() const { return mPODStruct.defaultUniformRange; }
const RangeUI &getSamplerUniformRange() const { return mPODStruct.samplerUniformRange; }
const RangeUI &getImageUniformRange() const { return mPODStruct.imageUniformRange; }
const RangeUI &getAtomicCounterUniformRange() const
{
return mPODStruct.atomicCounterUniformRange;
}
const RangeUI &getFragmentInoutRange() const { return mPODStruct.fragmentInoutRange; }
bool hasClipDistance() const { return mPODStruct.hasClipDistance; }
bool hasDiscard() const { return mPODStruct.hasDiscard; }
bool enablesPerSampleShading() const { return mPODStruct.enablesPerSampleShading; }
BlendEquationBitSet getAdvancedBlendEquations() const
{
return mPODStruct.advancedBlendEquations;
}
const std::vector<TransformFeedbackVarying> &getLinkedTransformFeedbackVaryings() const
{
return mLinkedTransformFeedbackVaryings;
}
GLint getTransformFeedbackBufferMode() const { return mTransformFeedbackBufferMode; }
GLint getTransformFeedbackBufferMode() const { return mPODStruct.transformFeedbackBufferMode; }
GLuint getUniformBlockBinding(GLuint uniformBlockIndex) const
{
ASSERT(uniformBlockIndex < mUniformBlocks.size());
@@ -361,9 +375,17 @@ class ProgramExecutable final : public angle::Subject
return static_cast<GLuint>(shaderStorageBlocksSize);
}
GLuint getUniformIndexFromImageIndex(GLuint imageIndex) const;
GLuint getUniformIndexFromImageIndex(GLuint imageIndex) const
{
ASSERT(imageIndex < mPODStruct.imageUniformRange.length());
return imageIndex + mPODStruct.imageUniformRange.low();
}
GLuint getUniformIndexFromSamplerIndex(GLuint samplerIndex) const;
GLuint getUniformIndexFromSamplerIndex(GLuint samplerIndex) const
{
ASSERT(samplerIndex < mPODStruct.samplerUniformRange.length());
return samplerIndex + mPODStruct.samplerUniformRange.low();
}
void saveLinkedStateInfo(const Context *context, const ProgramState &state);
const std::vector<sh::ShaderVariable> &getLinkedOutputVaryings(ShaderType shaderType) const
@@ -390,23 +412,23 @@ class ProgramExecutable final : public angle::Subject
return mLinkedShaderVersions[shaderType];
}
bool isYUVOutput() const;
bool isYUVOutput() const { return mPODStruct.hasYUVOutput; }
PrimitiveMode getGeometryShaderInputPrimitiveType() const
{
return mGeometryShaderInputPrimitiveType;
return mPODStruct.geometryShaderInputPrimitiveType;
}
PrimitiveMode getGeometryShaderOutputPrimitiveType() const
{
return mGeometryShaderOutputPrimitiveType;
return mPODStruct.geometryShaderOutputPrimitiveType;
}
int getGeometryShaderInvocations() const { return mGeometryShaderInvocations; }
int getGeometryShaderInvocations() const { return mPODStruct.geometryShaderInvocations; }
int getGeometryShaderMaxVertices() const { return mGeometryShaderMaxVertices; }
int getGeometryShaderMaxVertices() const { return mPODStruct.geometryShaderMaxVertices; }
GLenum getTessGenMode() const { return mTessGenMode; }
GLenum getTessGenMode() const { return mPODStruct.tessGenMode; }
void resetCachedValidateSamplersResult() { mCachedValidateSamplersResult.reset(); }
bool validateSamplers(InfoLog *infoLog, const Caps &caps) const
@@ -422,8 +444,11 @@ class ProgramExecutable final : public angle::Subject
return validateSamplersImpl(infoLog, caps);
}
ComponentTypeMask getFragmentOutputsTypeMask() const { return mDrawBufferTypeMask; }
DrawBufferMask getActiveOutputVariablesMask() const { return mActiveOutputVariablesMask; }
ComponentTypeMask getFragmentOutputsTypeMask() const { return mPODStruct.drawBufferTypeMask; }
DrawBufferMask getActiveOutputVariablesMask() const
{
return mPODStruct.activeOutputVariablesMask;
}
bool linkUniforms(const Context *context,
const ShaderMap<std::vector<sh::ShaderVariable>> &shaderUniforms,
@@ -489,13 +514,53 @@ class ProgramExecutable final : public angle::Subject
InfoLog mInfoLog;
ShaderBitSet mLinkedShaderStages;
// This struct must only contains basic data types so that entire struct can be memcpy.
struct PODStruct
{
PODStruct();
PODStruct(const PODStruct &other);
angle::BitSet<MAX_VERTEX_ATTRIBS> mActiveAttribLocationsMask;
unsigned int mMaxActiveAttribLocation;
ComponentTypeMask mAttributesTypeMask;
// mAttributesMask is identical to mActiveAttribLocationsMask with built-in attributes removed.
AttributesMask mAttributesMask;
ShaderBitSet linkedShaderStages;
angle::BitSet<MAX_VERTEX_ATTRIBS> activeAttribLocationsMask;
unsigned int maxActiveAttribLocation;
ComponentTypeMask attributesTypeMask;
// attributesMask is identical to mActiveAttribLocationsMask with built-in attributes
// removed.
AttributesMask attributesMask;
DrawBufferMask activeOutputVariablesMask;
ComponentTypeMask drawBufferTypeMask;
RangeUI defaultUniformRange;
RangeUI samplerUniformRange;
RangeUI imageUniformRange;
RangeUI atomicCounterUniformRange;
RangeUI fragmentInoutRange;
bool hasClipDistance;
bool hasDiscard;
bool hasYUVOutput;
bool enablesPerSampleShading;
// KHR_blend_equation_advanced supported equation list
BlendEquationBitSet advancedBlendEquations;
// GL_EXT_geometry_shader.
PrimitiveMode geometryShaderInputPrimitiveType;
PrimitiveMode geometryShaderOutputPrimitiveType;
int geometryShaderInvocations;
int geometryShaderMaxVertices;
// GL_EXT_tessellation_shader
int tessControlShaderVertices;
GLenum tessGenMode;
GLenum tessGenSpacing;
GLenum tessGenVertexOrder;
GLenum tessGenPointMode;
GLenum transformFeedbackBufferMode;
} mPODStruct;
static_assert(std::is_standard_layout<PODStruct>(),
"PODStruct must be a standard layout struct so that we can memcpy");
// Cached mask of active samplers and sampler types.
ActiveTextureMask mActiveSamplersMask;
@@ -515,16 +580,13 @@ class ProgramExecutable final : public angle::Subject
// to uniforms.
std::vector<sh::ShaderVariable> mOutputVariables;
std::vector<VariableLocation> mOutputLocations;
DrawBufferMask mActiveOutputVariablesMask;
// EXT_blend_func_extended secondary outputs (ones with index 1)
std::vector<VariableLocation> mSecondaryOutputLocations;
bool mYUVOutput;
// Vertex attributes, Fragment input varyings, etc.
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;
GLenum mTransformFeedbackBufferMode;
// Uniforms are sorted in order:
// 1. Non-opaque uniforms
// 2. Sampler uniforms
@@ -541,10 +603,6 @@ class ProgramExecutable final : public angle::Subject
std::vector<std::string> mUniformNames;
// Only used by GL and D3D backend
std::vector<std::string> mUniformMappedNames;
RangeUI mDefaultUniformRange;
RangeUI mSamplerUniformRange;
RangeUI mImageUniformRange;
RangeUI mAtomicCounterUniformRange;
std::vector<InterfaceBlock> mUniformBlocks;
// For faster iteration on the blocks currently being bound.
@@ -553,14 +611,6 @@ class ProgramExecutable final : public angle::Subject
std::vector<AtomicCounterBuffer> mAtomicCounterBuffers;
std::vector<InterfaceBlock> mShaderStorageBlocks;
RangeUI mFragmentInoutRange;
bool mHasClipDistance;
bool mHasDiscard;
bool mEnablesPerSampleShading;
// KHR_blend_equation_advanced supported equation list
BlendEquationBitSet mAdvancedBlendEquations;
// An array of the samplers that are used by the program
std::vector<SamplerBinding> mSamplerBindings;
@@ -574,22 +624,8 @@ class ProgramExecutable final : public angle::Subject
ShaderMap<int> mLinkedShaderVersions;
// GL_EXT_geometry_shader.
PrimitiveMode mGeometryShaderInputPrimitiveType;
PrimitiveMode mGeometryShaderOutputPrimitiveType;
int mGeometryShaderInvocations;
int mGeometryShaderMaxVertices;
// GL_EXT_tessellation_shader
int mTessControlShaderVertices;
GLenum mTessGenMode;
GLenum mTessGenSpacing;
GLenum mTessGenVertexOrder;
GLenum mTessGenPointMode;
// Fragment output variable base types: FLOAT, INT, or UINT. Ordered by location.
std::vector<GLenum> mOutputVariableTypes;
ComponentTypeMask mDrawBufferTypeMask;
// Cache for sampler validation
mutable Optional<bool> mCachedValidateSamplersResult;

View File

@@ -270,12 +270,15 @@ void ProgramPipeline::updateExecutableAttributes()
return;
}
const ProgramExecutable &vertexExecutable = vertexProgram->getExecutable();
mState.mExecutable->mActiveAttribLocationsMask = vertexExecutable.mActiveAttribLocationsMask;
mState.mExecutable->mMaxActiveAttribLocation = vertexExecutable.mMaxActiveAttribLocation;
mState.mExecutable->mAttributesTypeMask = vertexExecutable.mAttributesTypeMask;
mState.mExecutable->mAttributesMask = vertexExecutable.mAttributesMask;
mState.mExecutable->mProgramInputs = vertexExecutable.mProgramInputs;
const ProgramExecutable &vertexExecutable = vertexProgram->getExecutable();
mState.mExecutable->mPODStruct.activeAttribLocationsMask =
vertexExecutable.mPODStruct.activeAttribLocationsMask;
mState.mExecutable->mPODStruct.maxActiveAttribLocation =
vertexExecutable.mPODStruct.maxActiveAttribLocation;
mState.mExecutable->mPODStruct.attributesTypeMask =
vertexExecutable.mPODStruct.attributesTypeMask;
mState.mExecutable->mPODStruct.attributesMask = vertexExecutable.mPODStruct.attributesMask;
mState.mExecutable->mProgramInputs = vertexExecutable.mProgramInputs;
}
void ProgramPipeline::updateTransformFeedbackMembers()
@@ -359,12 +362,14 @@ void ProgramPipeline::updateExecutableGeometryProperties()
}
const ProgramExecutable &geometryExecutable = geometryProgram->getExecutable();
mState.mExecutable->mGeometryShaderInputPrimitiveType =
geometryExecutable.mGeometryShaderInputPrimitiveType;
mState.mExecutable->mGeometryShaderOutputPrimitiveType =
geometryExecutable.mGeometryShaderOutputPrimitiveType;
mState.mExecutable->mGeometryShaderInvocations = geometryExecutable.mGeometryShaderInvocations;
mState.mExecutable->mGeometryShaderMaxVertices = geometryExecutable.mGeometryShaderMaxVertices;
mState.mExecutable->mPODStruct.geometryShaderInputPrimitiveType =
geometryExecutable.mPODStruct.geometryShaderInputPrimitiveType;
mState.mExecutable->mPODStruct.geometryShaderOutputPrimitiveType =
geometryExecutable.mPODStruct.geometryShaderOutputPrimitiveType;
mState.mExecutable->mPODStruct.geometryShaderInvocations =
geometryExecutable.mPODStruct.geometryShaderInvocations;
mState.mExecutable->mPODStruct.geometryShaderMaxVertices =
geometryExecutable.mPODStruct.geometryShaderMaxVertices;
}
void ProgramPipeline::updateExecutableTessellationProperties()
@@ -375,17 +380,20 @@ void ProgramPipeline::updateExecutableTessellationProperties()
if (tessControlProgram)
{
const ProgramExecutable &tessControlExecutable = tessControlProgram->getExecutable();
mState.mExecutable->mTessControlShaderVertices =
tessControlExecutable.mTessControlShaderVertices;
mState.mExecutable->mPODStruct.tessControlShaderVertices =
tessControlExecutable.mPODStruct.tessControlShaderVertices;
}
if (tessEvalProgram)
{
const ProgramExecutable &tessEvalExecutable = tessEvalProgram->getExecutable();
mState.mExecutable->mTessGenMode = tessEvalExecutable.mTessGenMode;
mState.mExecutable->mTessGenSpacing = tessEvalExecutable.mTessGenSpacing;
mState.mExecutable->mTessGenVertexOrder = tessEvalExecutable.mTessGenVertexOrder;
mState.mExecutable->mTessGenPointMode = tessEvalExecutable.mTessGenPointMode;
mState.mExecutable->mPODStruct.tessGenMode = tessEvalExecutable.mPODStruct.tessGenMode;
mState.mExecutable->mPODStruct.tessGenSpacing =
tessEvalExecutable.mPODStruct.tessGenSpacing;
mState.mExecutable->mPODStruct.tessGenVertexOrder =
tessEvalExecutable.mPODStruct.tessGenVertexOrder;
mState.mExecutable->mPODStruct.tessGenPointMode =
tessEvalExecutable.mPODStruct.tessGenPointMode;
}
}
@@ -398,10 +406,12 @@ void ProgramPipeline::updateFragmentInoutRangeAndEnablesPerSampleShading()
return;
}
const ProgramExecutable &fragmentExecutable = fragmentProgram->getExecutable();
mState.mExecutable->mFragmentInoutRange = fragmentExecutable.mFragmentInoutRange;
mState.mExecutable->mHasDiscard = fragmentExecutable.mHasDiscard;
mState.mExecutable->mEnablesPerSampleShading = fragmentExecutable.mEnablesPerSampleShading;
const ProgramExecutable &fragmentExecutable = fragmentProgram->getExecutable();
mState.mExecutable->mPODStruct.fragmentInoutRange =
fragmentExecutable.mPODStruct.fragmentInoutRange;
mState.mExecutable->mPODStruct.hasDiscard = fragmentExecutable.mPODStruct.hasDiscard;
mState.mExecutable->mPODStruct.enablesPerSampleShading =
fragmentExecutable.mPODStruct.enablesPerSampleShading;
}
void ProgramPipeline::updateLinkedVaryings()