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) ...@@ -935,49 +935,66 @@ void WriteShaderVar(BinaryOutputStream *stream, const sh::ShaderVariable &var)
stream->writeIntVector(var.arraySizes); stream->writeIntVector(var.arraySizes);
stream->writeBool(var.staticUse); stream->writeBool(var.staticUse);
stream->writeBool(var.active); 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.structOrBlockName);
stream->writeString(var.mappedStructOrBlockName); 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.imageUnitFormat);
stream->writeInt(var.offset); stream->writeInt(var.offset);
stream->writeBool(var.readonly); stream->writeBool(var.readonly);
stream->writeBool(var.writeonly); stream->writeBool(var.writeonly);
stream->writeBool(var.isFragmentInOut); stream->writeBool(var.isFragmentInOut);
if (var.isFragmentInOut) stream->writeInt(var.index);
{ stream->writeBool(var.yuv);
stream->writeInt(var.location); stream->writeEnum(var.interpolation);
} stream->writeBool(var.isInvariant);
stream->writeBool(var.isShaderIOBlock);
stream->writeBool(var.isPatch);
stream->writeBool(var.texelFetchStaticUse); stream->writeBool(var.texelFetchStaticUse);
stream->writeInt(var.getFlattenedOffsetInParentArrays());
ASSERT(var.fields.empty());
} }
void LoadShaderVar(BinaryInputStream *stream, sh::ShaderVariable *var) void LoadShaderVar(gl::BinaryInputStream *stream, sh::ShaderVariable *var)
{ {
var->type = stream->readInt<GLenum>(); var->type = stream->readInt<GLenum>();
var->precision = stream->readInt<GLenum>(); var->precision = stream->readInt<GLenum>();
var->name = stream->readString(); stream->readString(&var->name);
var->mappedName = stream->readString(); stream->readString(&var->mappedName);
stream->readIntVector<unsigned int>(&var->arraySizes); stream->readIntVector<unsigned int>(&var->arraySizes);
var->staticUse = stream->readBool(); var->staticUse = stream->readBool();
var->active = stream->readBool(); var->active = stream->readBool();
var->binding = stream->readInt<int>(); size_t elementCount = stream->readInt<size_t>();
var->structOrBlockName = stream->readString(); var->fields.resize(elementCount);
var->mappedStructOrBlockName = stream->readString(); for (sh::ShaderVariable &variable : var->fields)
var->setParentArrayIndex(stream->readInt<int>()); {
LoadShaderVar(stream, &variable);
var->imageUnitFormat = stream->readInt<GLenum>(); }
var->offset = stream->readInt<int>(); stream->readString(&var->structOrBlockName);
var->readonly = stream->readBool(); stream->readString(&var->mappedStructOrBlockName);
var->writeonly = stream->readBool(); var->isRowMajorLayout = stream->readBool();
var->isFragmentInOut = stream->readBool(); var->location = stream->readInt<int>();
if (var->isFragmentInOut) var->hasImplicitLocation = stream->readBool();
{ var->binding = stream->readInt<int>();
var->location = 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->texelFetchStaticUse = stream->readBool();
var->setParentArrayIndex(stream->readInt<int>());
} }
// VariableLocation implementation. // VariableLocation implementation.
...@@ -4622,7 +4639,10 @@ angle::Result Program::serialize(const Context *context, angle::MemoryBuffer *bi ...@@ -4622,7 +4639,10 @@ angle::Result Program::serialize(const Context *context, angle::MemoryBuffer *bi
stream.writeInt(0); 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(); const auto &computeLocalSize = mState.getComputeShaderLocalSize();
...@@ -4708,7 +4728,10 @@ angle::Result Program::deserialize(const Context *context, ...@@ -4708,7 +4728,10 @@ angle::Result Program::deserialize(const Context *context,
return angle::Result::Stop; 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[0] = stream.readInt<int>();
mState.mComputeShaderLocalSize[1] = stream.readInt<int>(); mState.mComputeShaderLocalSize[1] = stream.readInt<int>();
......
...@@ -10,7 +10,6 @@ ...@@ -10,7 +10,6 @@
#include "libANGLE/Context.h" #include "libANGLE/Context.h"
#include "libANGLE/Program.h" #include "libANGLE/Program.h"
#include "libANGLE/ProgramPipeline.h"
#include "libANGLE/Shader.h" #include "libANGLE/Shader.h"
namespace gl namespace gl
...@@ -211,7 +210,7 @@ void ProgramExecutable::reset() ...@@ -211,7 +210,7 @@ void ProgramExecutable::reset()
mTessGenPointMode = GL_NONE; 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, static_assert(MAX_VERTEX_ATTRIBS * 2 <= sizeof(uint32_t) * 8,
"Too many vertex attribs for mask: All bits of mAttributesTypeMask types and " "Too many vertex attribs for mask: All bits of mAttributesTypeMask types and "
...@@ -414,9 +413,43 @@ void ProgramExecutable::load(gl::BinaryInputStream *stream) ...@@ -414,9 +413,43 @@ void ProgramExecutable::load(gl::BinaryInputStream *stream)
mGraphicsImageBindings.emplace_back(imageBinding); 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, static_assert(MAX_VERTEX_ATTRIBS * 2 <= sizeof(uint32_t) * 8,
"All bits of mAttributesTypeMask types and mask fit into 32 bits each"); "All bits of mAttributesTypeMask types and mask fit into 32 bits each");
...@@ -467,8 +500,6 @@ void ProgramExecutable::save(gl::BinaryOutputStream *stream) const ...@@ -467,8 +500,6 @@ void ProgramExecutable::save(gl::BinaryOutputStream *stream) const
{ {
WriteShaderVar(stream, uniform); WriteShaderVar(stream, uniform);
// FIXME: referenced
stream->writeInt(uniform.bufferIndex); stream->writeInt(uniform.bufferIndex);
WriteBlockMemberInfo(stream, uniform.blockInfo); WriteBlockMemberInfo(stream, uniform.blockInfo);
...@@ -563,6 +594,40 @@ void ProgramExecutable::save(gl::BinaryOutputStream *stream) const ...@@ -563,6 +594,40 @@ void ProgramExecutable::save(gl::BinaryOutputStream *stream) const
stream->writeInt(imageBinding.boundImageUnits[i]); 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 int ProgramExecutable::getInfoLogLength() const
......
...@@ -115,8 +115,8 @@ class ProgramExecutable final : public angle::Subject ...@@ -115,8 +115,8 @@ class ProgramExecutable final : public angle::Subject
void reset(); void reset();
void save(gl::BinaryOutputStream *stream) const; void save(bool isSeparable, gl::BinaryOutputStream *stream) const;
void load(gl::BinaryInputStream *stream); void load(bool isSeparable, gl::BinaryInputStream *stream);
int getInfoLogLength() const; int getInfoLogLength() const;
InfoLog &getInfoLog() { return mInfoLog; } InfoLog &getInfoLog() { return mInfoLog; }
......
...@@ -283,6 +283,7 @@ std::unique_ptr<rx::LinkEvent> ProgramExecutableVk::load(gl::BinaryInputStream * ...@@ -283,6 +283,7 @@ std::unique_ptr<rx::LinkEvent> ProgramExecutableVk::load(gl::BinaryInputStream *
info.binding = stream->readInt<uint32_t>(); info.binding = stream->readInt<uint32_t>();
info.location = stream->readInt<uint32_t>(); info.location = stream->readInt<uint32_t>();
info.component = stream->readInt<uint32_t>(); info.component = stream->readInt<uint32_t>();
info.index = stream->readInt<uint32_t>();
// PackedEnumBitSet uses uint8_t // PackedEnumBitSet uses uint8_t
info.activeStages = gl::ShaderBitSet(stream->readInt<uint8_t>()); info.activeStages = gl::ShaderBitSet(stream->readInt<uint8_t>());
LoadShaderInterfaceVariableXfbInfo(stream, &info.xfb); LoadShaderInterfaceVariableXfbInfo(stream, &info.xfb);
...@@ -317,6 +318,7 @@ void ProgramExecutableVk::save(gl::BinaryOutputStream *stream) ...@@ -317,6 +318,7 @@ void ProgramExecutableVk::save(gl::BinaryOutputStream *stream)
stream->writeInt(info.binding); stream->writeInt(info.binding);
stream->writeInt(info.location); stream->writeInt(info.location);
stream->writeInt(info.component); stream->writeInt(info.component);
stream->writeInt(info.index);
// PackedEnumBitSet uses uint8_t // PackedEnumBitSet uses uint8_t
stream->writeInt(info.activeStages.bits()); stream->writeInt(info.activeStages.bits());
SaveShaderInterfaceVariableXfbInfo(info.xfb, stream); 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