Link atomic counters to buffers
Gather counters from each shader and group them according the
layout qualifier 'binding' into each buffer.
BUG=angleproject:1729
TEST=angle_end2end_tests:AtomicCounterBufferTest
Change-Id: I8d0cd0d2bf65be37c035b0e1540481c8bee0bae4
diff --git a/src/libANGLE/MemoryProgramCache.cpp b/src/libANGLE/MemoryProgramCache.cpp
index 8fa1c49..eccd509 100644
--- a/src/libANGLE/MemoryProgramCache.cpp
+++ b/src/libANGLE/MemoryProgramCache.cpp
@@ -49,6 +49,37 @@
var->structName = stream->readString();
}
+void WriteShaderVariableBuffer(BinaryOutputStream *stream, const ShaderVariableBuffer &var)
+{
+ stream->writeInt(var.binding);
+ stream->writeInt(var.dataSize);
+
+ stream->writeInt(var.vertexStaticUse);
+ stream->writeInt(var.fragmentStaticUse);
+ stream->writeInt(var.computeStaticUse);
+
+ stream->writeInt(var.memberIndexes.size());
+ for (unsigned int memberCounterIndex : var.memberIndexes)
+ {
+ stream->writeInt(memberCounterIndex);
+ }
+}
+
+void LoadShaderVariableBuffer(BinaryInputStream *stream, ShaderVariableBuffer *var)
+{
+ var->binding = stream->readInt<int>();
+ var->dataSize = stream->readInt<unsigned int>();
+ var->vertexStaticUse = stream->readBool();
+ var->fragmentStaticUse = stream->readBool();
+ var->computeStaticUse = stream->readBool();
+
+ unsigned int numMembers = stream->readInt<unsigned int>();
+ for (unsigned int blockMemberIndex = 0; blockMemberIndex < numMembers; blockMemberIndex++)
+ {
+ var->memberIndexes.push_back(stream->readInt<unsigned int>());
+ }
+}
+
class HashStream final : angle::NonCopyable
{
public:
@@ -158,7 +189,7 @@
LinkedUniform uniform;
LoadShaderVar(&stream, &uniform);
- uniform.blockIndex = stream.readInt<int>();
+ uniform.bufferIndex = stream.readInt<int>();
uniform.blockInfo.offset = stream.readInt<int>();
uniform.blockInfo.arrayStride = stream.readInt<int>();
uniform.blockInfo.matrixStride = stream.readInt<int>();
@@ -191,21 +222,22 @@
stream.readString(&uniformBlock.name);
stream.readBool(&uniformBlock.isArray);
stream.readInt(&uniformBlock.arrayElement);
- stream.readInt(&uniformBlock.binding);
- stream.readInt(&uniformBlock.dataSize);
- stream.readBool(&uniformBlock.vertexStaticUse);
- stream.readBool(&uniformBlock.fragmentStaticUse);
- unsigned int numMembers = stream.readInt<unsigned int>();
- for (unsigned int blockMemberIndex = 0; blockMemberIndex < numMembers; blockMemberIndex++)
- {
- uniformBlock.memberUniformIndexes.push_back(stream.readInt<unsigned int>());
- }
+ LoadShaderVariableBuffer(&stream, &uniformBlock);
state->mUniformBlocks.push_back(uniformBlock);
state->mActiveUniformBlockBindings.set(uniformBlockIndex, uniformBlock.binding != 0);
}
+ unsigned int atomicCounterBufferCount = stream.readInt<unsigned int>();
+ ASSERT(state->mAtomicCounterBuffers.empty());
+ for (unsigned int bufferIndex = 0; bufferIndex < atomicCounterBufferCount; ++bufferIndex)
+ {
+ AtomicCounterBuffer atomicCounterBuffer;
+ LoadShaderVariableBuffer(&stream, &atomicCounterBuffer);
+
+ state->mAtomicCounterBuffers.push_back(atomicCounterBuffer);
+ }
unsigned int transformFeedbackVaryingCount = stream.readInt<unsigned int>();
@@ -286,6 +318,10 @@
state->mImageBindings.emplace_back(ImageBinding(boundImageUnit, elementCount));
}
+ unsigned int atomicCounterRangeLow = stream.readInt<unsigned int>();
+ unsigned int atomicCounterRangeHigh = stream.readInt<unsigned int>();
+ state->mAtomicCounterUniformRange = RangeUI(atomicCounterRangeLow, atomicCounterRangeHigh);
+
return program->getImplementation()->load(context, infoLog, &stream);
}
@@ -335,7 +371,7 @@
// FIXME: referenced
- stream.writeInt(uniform.blockIndex);
+ stream.writeInt(uniform.bufferIndex);
stream.writeInt(uniform.blockInfo.offset);
stream.writeInt(uniform.blockInfo.arrayStride);
stream.writeInt(uniform.blockInfo.matrixStride);
@@ -358,17 +394,14 @@
stream.writeString(uniformBlock.name);
stream.writeInt(uniformBlock.isArray);
stream.writeInt(uniformBlock.arrayElement);
- stream.writeInt(uniformBlock.binding);
- stream.writeInt(uniformBlock.dataSize);
- stream.writeInt(uniformBlock.vertexStaticUse);
- stream.writeInt(uniformBlock.fragmentStaticUse);
+ WriteShaderVariableBuffer(&stream, uniformBlock);
+ }
- stream.writeInt(uniformBlock.memberUniformIndexes.size());
- for (unsigned int memberUniformIndex : uniformBlock.memberUniformIndexes)
- {
- stream.writeInt(memberUniformIndex);
- }
+ stream.writeInt(state.mAtomicCounterBuffers.size());
+ for (const auto &atomicCounterBuffer : state.mAtomicCounterBuffers)
+ {
+ WriteShaderVariableBuffer(&stream, atomicCounterBuffer);
}
// Warn the app layer if saving a binary with unsupported transform feedback.
@@ -437,6 +470,9 @@
stream.writeInt(imageBinding.elementCount);
}
+ stream.writeInt(state.getAtomicCounterUniformRange().low());
+ stream.writeInt(state.getAtomicCounterUniformRange().high());
+
program->getImplementation()->save(context, &stream);
ASSERT(binaryOut);