Commit 0af8cfa7 by Tim Van Patten Committed by Commit Bot

Reland "Save/Load missing members"

This is a reland of b2e76cf5 Always call saveLinkedStateInfo() so we fill in the necessary values with valid data for monolithic programs also. Original change's description: > Save/Load missing members > > There are several class/struct members that are missing when a program > is serialized/deserialized. This leads to errors when attempting to link > programs that have been deserialized. For example, when drawing with a > PPO that contains programs which were created with glProgramBinary(). > > This CL adds saving/loading the missing members. > > Bug: b/182409935 > Change-Id: I637c6cd8c174acd6da8d51433893323a32e5d7c0 > Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2770683 > Commit-Queue: Tim Van Patten <timvp@google.com> > Reviewed-by: Jamie Madill <jmadill@chromium.org> > Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> > Reviewed-by: Cody Northrop <cnorthrop@google.com> Bug: b/182409935 Bug: angleproject:5793 Change-Id: I07ca8f5dfed8c0a9eac3a0defb1602d2ba021c5f Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2782189 Commit-Queue: Tim Van Patten <timvp@google.com> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarCody Northrop <cnorthrop@google.com>
parent 3e887665
......@@ -935,49 +935,66 @@ void WriteShaderVar(BinaryOutputStream *stream, const sh::ShaderVariable &var)
stream->writeIntVector(var.arraySizes);
stream->writeBool(var.staticUse);
stream->writeBool(var.active);
stream->writeInt(var.binding);
stream->writeInt<size_t>(var.fields.size());
for (const sh::ShaderVariable &shaderVariable : var.fields)
{
WriteShaderVar(stream, shaderVariable);
}
stream->writeString(var.structOrBlockName);
stream->writeString(var.mappedStructOrBlockName);
stream->writeInt(var.hasParentArrayIndex() ? var.parentArrayIndex() : -1);
stream->writeBool(var.isRowMajorLayout);
stream->writeInt(var.location);
stream->writeBool(var.hasImplicitLocation);
stream->writeInt(var.binding);
stream->writeInt(var.imageUnitFormat);
stream->writeInt(var.offset);
stream->writeBool(var.readonly);
stream->writeBool(var.writeonly);
stream->writeBool(var.isFragmentInOut);
if (var.isFragmentInOut)
{
stream->writeInt(var.location);
}
stream->writeInt(var.index);
stream->writeBool(var.yuv);
stream->writeEnum(var.interpolation);
stream->writeBool(var.isInvariant);
stream->writeBool(var.isShaderIOBlock);
stream->writeBool(var.isPatch);
stream->writeBool(var.texelFetchStaticUse);
ASSERT(var.fields.empty());
stream->writeInt(var.getFlattenedOffsetInParentArrays());
}
void LoadShaderVar(BinaryInputStream *stream, sh::ShaderVariable *var)
void LoadShaderVar(gl::BinaryInputStream *stream, sh::ShaderVariable *var)
{
var->type = stream->readInt<GLenum>();
var->precision = stream->readInt<GLenum>();
var->name = stream->readString();
var->mappedName = stream->readString();
var->type = stream->readInt<GLenum>();
var->precision = stream->readInt<GLenum>();
stream->readString(&var->name);
stream->readString(&var->mappedName);
stream->readIntVector<unsigned int>(&var->arraySizes);
var->staticUse = stream->readBool();
var->active = stream->readBool();
var->binding = stream->readInt<int>();
var->structOrBlockName = stream->readString();
var->mappedStructOrBlockName = stream->readString();
var->setParentArrayIndex(stream->readInt<int>());
var->imageUnitFormat = stream->readInt<GLenum>();
var->offset = stream->readInt<int>();
var->readonly = stream->readBool();
var->writeonly = stream->readBool();
var->isFragmentInOut = stream->readBool();
if (var->isFragmentInOut)
{
var->location = stream->readInt<int>();
}
var->staticUse = stream->readBool();
var->active = stream->readBool();
size_t elementCount = stream->readInt<size_t>();
var->fields.resize(elementCount);
for (sh::ShaderVariable &variable : var->fields)
{
LoadShaderVar(stream, &variable);
}
stream->readString(&var->structOrBlockName);
stream->readString(&var->mappedStructOrBlockName);
var->isRowMajorLayout = stream->readBool();
var->location = stream->readInt<int>();
var->hasImplicitLocation = stream->readBool();
var->binding = stream->readInt<int>();
var->imageUnitFormat = stream->readInt<GLenum>();
var->offset = stream->readInt<int>();
var->readonly = stream->readBool();
var->writeonly = stream->readBool();
var->isFragmentInOut = stream->readBool();
var->index = stream->readInt<int>();
var->yuv = stream->readBool();
var->interpolation = stream->readEnum<sh::InterpolationType>();
var->isInvariant = stream->readBool();
var->isShaderIOBlock = stream->readBool();
var->isPatch = stream->readBool();
var->texelFetchStaticUse = stream->readBool();
var->setParentArrayIndex(stream->readInt<int>());
}
// VariableLocation implementation.
......@@ -4622,7 +4639,10 @@ angle::Result Program::serialize(const Context *context, angle::MemoryBuffer *bi
stream.writeInt(0);
}
mState.mExecutable->save(&stream);
// Must be before mExecutable->save(), since it uses the value.
stream.writeBool(mState.mSeparable);
mState.mExecutable->save(mState.mSeparable, &stream);
const auto &computeLocalSize = mState.getComputeShaderLocalSize();
......@@ -4708,7 +4728,10 @@ angle::Result Program::deserialize(const Context *context,
return angle::Result::Stop;
}
mState.mExecutable->load(&stream);
// Must be before mExecutable->load(), since it uses the value.
mState.mSeparable = stream.readBool();
mState.mExecutable->load(mState.mSeparable, &stream);
mState.mComputeShaderLocalSize[0] = stream.readInt<int>();
mState.mComputeShaderLocalSize[1] = stream.readInt<int>();
......
......@@ -10,7 +10,6 @@
#include "libANGLE/Context.h"
#include "libANGLE/Program.h"
#include "libANGLE/ProgramPipeline.h"
#include "libANGLE/Shader.h"
namespace gl
......@@ -211,7 +210,7 @@ void ProgramExecutable::reset()
mTessGenPointMode = GL_NONE;
}
void ProgramExecutable::load(gl::BinaryInputStream *stream)
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 "
......@@ -414,9 +413,43 @@ void ProgramExecutable::load(gl::BinaryInputStream *stream)
mGraphicsImageBindings.emplace_back(imageBinding);
}
}
// 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 : mLinkedGraphicsShaderStages)
{
mLinkedOutputVaryings[shaderType].resize(stream->readInt<size_t>());
for (sh::ShaderVariable &variable : mLinkedOutputVaryings[shaderType])
{
LoadShaderVar(stream, &variable);
}
mLinkedInputVaryings[shaderType].resize(stream->readInt<size_t>());
for (sh::ShaderVariable &variable : mLinkedInputVaryings[shaderType])
{
LoadShaderVar(stream, &variable);
}
mLinkedShaderVersions[shaderType] = stream->readInt<int>();
}
for (ShaderType shaderType : mLinkedComputeShaderStages)
{
mLinkedOutputVaryings[shaderType].resize(stream->readInt<size_t>());
for (sh::ShaderVariable &variable : mLinkedOutputVaryings[shaderType])
{
LoadShaderVar(stream, &variable);
}
mLinkedInputVaryings[shaderType].resize(stream->readInt<size_t>());
for (sh::ShaderVariable &variable : mLinkedInputVaryings[shaderType])
{
LoadShaderVar(stream, &variable);
}
mLinkedShaderVersions[shaderType] = stream->readInt<int>();
}
}
}
void ProgramExecutable::save(gl::BinaryOutputStream *stream) const
void ProgramExecutable::save(bool isSeparable, gl::BinaryOutputStream *stream) const
{
static_assert(MAX_VERTEX_ATTRIBS * 2 <= sizeof(uint32_t) * 8,
"All bits of mAttributesTypeMask types and mask fit into 32 bits each");
......@@ -467,8 +500,6 @@ void ProgramExecutable::save(gl::BinaryOutputStream *stream) const
{
WriteShaderVar(stream, uniform);
// FIXME: referenced
stream->writeInt(uniform.bufferIndex);
WriteBlockMemberInfo(stream, uniform.blockInfo);
......@@ -563,6 +594,40 @@ void ProgramExecutable::save(gl::BinaryOutputStream *stream) const
stream->writeInt(imageBinding.boundImageUnits[i]);
}
}
// 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 : mLinkedGraphicsShaderStages)
{
stream->writeInt(mLinkedOutputVaryings[shaderType].size());
for (const sh::ShaderVariable &shaderVariable : mLinkedOutputVaryings[shaderType])
{
WriteShaderVar(stream, shaderVariable);
}
stream->writeInt(mLinkedInputVaryings[shaderType].size());
for (const sh::ShaderVariable &shaderVariable : mLinkedInputVaryings[shaderType])
{
WriteShaderVar(stream, shaderVariable);
}
stream->writeInt(mLinkedShaderVersions[shaderType]);
}
for (ShaderType shaderType : mLinkedComputeShaderStages)
{
stream->writeInt(mLinkedOutputVaryings[shaderType].size());
for (const sh::ShaderVariable &shaderVariable : mLinkedOutputVaryings[shaderType])
{
WriteShaderVar(stream, shaderVariable);
}
stream->writeInt(mLinkedInputVaryings[shaderType].size());
for (const sh::ShaderVariable &shaderVariable : mLinkedInputVaryings[shaderType])
{
WriteShaderVar(stream, shaderVariable);
}
stream->writeInt(mLinkedShaderVersions[shaderType]);
}
}
}
int ProgramExecutable::getInfoLogLength() const
......
......@@ -115,8 +115,8 @@ class ProgramExecutable final : public angle::Subject
void reset();
void save(gl::BinaryOutputStream *stream) const;
void load(gl::BinaryInputStream *stream);
void save(bool isSeparable, gl::BinaryOutputStream *stream) const;
void load(bool isSeparable, gl::BinaryInputStream *stream);
int getInfoLogLength() const;
InfoLog &getInfoLog() { return mInfoLog; }
......
......@@ -283,6 +283,7 @@ std::unique_ptr<rx::LinkEvent> ProgramExecutableVk::load(gl::BinaryInputStream *
info.binding = stream->readInt<uint32_t>();
info.location = stream->readInt<uint32_t>();
info.component = stream->readInt<uint32_t>();
info.index = stream->readInt<uint32_t>();
// PackedEnumBitSet uses uint8_t
info.activeStages = gl::ShaderBitSet(stream->readInt<uint8_t>());
LoadShaderInterfaceVariableXfbInfo(stream, &info.xfb);
......@@ -317,6 +318,7 @@ void ProgramExecutableVk::save(gl::BinaryOutputStream *stream)
stream->writeInt(info.binding);
stream->writeInt(info.location);
stream->writeInt(info.component);
stream->writeInt(info.index);
// PackedEnumBitSet uses uint8_t
stream->writeInt(info.activeStages.bits());
SaveShaderInterfaceVariableXfbInfo(info.xfb, stream);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment