Commit 9459bae1 by Cody Northrop Committed by Commit Bot

Capture/Replay: Add Vertex Array Object support to mid-execution capture

Test: Manhattan mid-execution capture working Bug: angleproject:3662 Bug: angleproject:4091 Change-Id: I5d16e8faed759507c85b6358b65750fe5c33ddfe Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2079190Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarCourtney Goeltzenleuchter <courtneygo@google.com> Commit-Queue: Cody Northrop <cnorthrop@google.com>
parent f8ecac29
...@@ -326,6 +326,7 @@ class StateCache final : angle::NonCopyable ...@@ -326,6 +326,7 @@ class StateCache final : angle::NonCopyable
mCachedIntegerVertexAttribTypesValidation; mCachedIntegerVertexAttribTypesValidation;
}; };
using VertexArrayMap = ResourceMap<VertexArray, VertexArrayID>;
using QueryMap = ResourceMap<Query, QueryID>; using QueryMap = ResourceMap<Query, QueryID>;
using TransformFeedbackMap = ResourceMap<TransformFeedback, TransformFeedbackID>; using TransformFeedbackMap = ResourceMap<TransformFeedback, TransformFeedbackID>;
...@@ -592,6 +593,7 @@ class Context final : public egl::LabeledObject, angle::NonCopyable, public angl ...@@ -592,6 +593,7 @@ class Context final : public egl::LabeledObject, angle::NonCopyable, public angl
angle::FrameCapture *getFrameCapture() { return mFrameCapture.get(); } angle::FrameCapture *getFrameCapture() { return mFrameCapture.get(); }
const VertexArrayMap &getVertexArraysForCapture() const { return mVertexArrayMap; }
const QueryMap &getQueriesForCapture() const { return mQueryMap; } const QueryMap &getQueriesForCapture() const { return mQueryMap; }
const TransformFeedbackMap &getTransformFeedbacksForCapture() const const TransformFeedbackMap &getTransformFeedbacksForCapture() const
{ {
...@@ -686,7 +688,7 @@ class Context final : public egl::LabeledObject, angle::NonCopyable, public angl ...@@ -686,7 +688,7 @@ class Context final : public egl::LabeledObject, angle::NonCopyable, public angl
QueryMap mQueryMap; QueryMap mQueryMap;
HandleAllocator mQueryHandleAllocator; HandleAllocator mQueryHandleAllocator;
ResourceMap<VertexArray, VertexArrayID> mVertexArrayMap; VertexArrayMap mVertexArrayMap;
HandleAllocator mVertexArrayHandleAllocator; HandleAllocator mVertexArrayHandleAllocator;
TransformFeedbackMap mTransformFeedbackMap; TransformFeedbackMap mTransformFeedbackMap;
......
...@@ -1256,6 +1256,54 @@ void CaptureFramebufferAttachment(std::vector<CallCapture> *setupCalls, ...@@ -1256,6 +1256,54 @@ void CaptureFramebufferAttachment(std::vector<CallCapture> *setupCalls,
} }
} }
void CaptureVertexArrayData(std::vector<CallCapture> *setupCalls,
const gl::Context *context,
const gl::VertexArray *vertexArray,
gl::State *replayState)
{
const std::vector<gl::VertexAttribute> &vertexAttribs = vertexArray->getVertexAttributes();
const std::vector<gl::VertexBinding> &vertexBindings = vertexArray->getVertexBindings();
for (GLuint attribIndex = 0; attribIndex < gl::MAX_VERTEX_ATTRIBS; ++attribIndex)
{
const gl::VertexAttribute defaultAttrib(attribIndex);
const gl::VertexBinding defaultBinding;
const gl::VertexAttribute &attrib = vertexAttribs[attribIndex];
const gl::VertexBinding &binding = vertexBindings[attrib.bindingIndex];
if (attrib.enabled != defaultAttrib.enabled)
{
Capture(setupCalls, CaptureEnableVertexAttribArray(*replayState, false, attribIndex));
}
if (attrib.format != defaultAttrib.format || attrib.pointer != defaultAttrib.pointer ||
binding.getStride() != defaultBinding.getStride() ||
binding.getBuffer().get() != nullptr)
{
gl::Buffer *buffer = binding.getBuffer().get();
if (buffer != replayState->getArrayBuffer())
{
replayState->setBufferBinding(context, gl::BufferBinding::Array, buffer);
Capture(setupCalls, CaptureBindBuffer(*replayState, true, gl::BufferBinding::Array,
buffer->id()));
}
Capture(setupCalls, CaptureVertexAttribPointer(
*replayState, true, attribIndex, attrib.format->channelCount,
attrib.format->vertexAttribType, attrib.format->isNorm(),
binding.getStride(), attrib.pointer));
}
if (binding.getDivisor() != 0)
{
Capture(setupCalls, CaptureVertexAttribDivisor(*replayState, true, attribIndex,
binding.getDivisor()));
}
}
}
void CaptureMidExecutionSetup(const gl::Context *context, void CaptureMidExecutionSetup(const gl::Context *context,
std::vector<CallCapture> *setupCalls, std::vector<CallCapture> *setupCalls,
const ShaderSourceMap &cachedShaderSources, const ShaderSourceMap &cachedShaderSources,
...@@ -1319,55 +1367,49 @@ void CaptureMidExecutionSetup(const gl::Context *context, ...@@ -1319,55 +1367,49 @@ void CaptureMidExecutionSetup(const gl::Context *context,
// Vertex input states. Only handles GLES 2.0 states right now. // Vertex input states. Only handles GLES 2.0 states right now.
// Must happen after buffer data initialization. // Must happen after buffer data initialization.
// TODO(http://anglebug.com/3662): Complete state capture. // TODO(http://anglebug.com/3662): Complete state capture.
// Capture default vertex attribs
const std::vector<gl::VertexAttribCurrentValueData> &currentValues = const std::vector<gl::VertexAttribCurrentValueData> &currentValues =
apiState.getVertexAttribCurrentValues(); apiState.getVertexAttribCurrentValues();
const std::vector<gl::VertexAttribute> &vertexAttribs =
apiState.getVertexArray()->getVertexAttributes();
const std::vector<gl::VertexBinding> &vertexBindings =
apiState.getVertexArray()->getVertexBindings();
for (GLuint attribIndex = 0; attribIndex < gl::MAX_VERTEX_ATTRIBS; ++attribIndex) for (GLuint attribIndex = 0; attribIndex < gl::MAX_VERTEX_ATTRIBS; ++attribIndex)
{ {
const gl::VertexAttribCurrentValueData &currentValue = currentValues[attribIndex]; const gl::VertexAttribCurrentValueData &defaultValue = currentValues[attribIndex];
if (!IsDefaultCurrentValue(currentValue)) if (!IsDefaultCurrentValue(defaultValue))
{ {
cap(CaptureVertexAttrib4fv(replayState, true, attribIndex, Capture(setupCalls, CaptureVertexAttrib4fv(replayState, true, attribIndex,
currentValue.Values.FloatValues)); defaultValue.Values.FloatValues));
} }
}
const gl::VertexAttribute &attrib = vertexAttribs[attribIndex]; // Capture vertex array objects
const gl::VertexBinding &binding = vertexBindings[attrib.bindingIndex]; const gl::VertexArrayMap &vertexArrayMap = context->getVertexArraysForCapture();
gl::VertexArrayID boundVertexArrayID = {0};
const gl::VertexAttribute defaultAttrib(attribIndex); for (const auto &vertexArrayIter : vertexArrayMap)
const gl::VertexBinding defaultBinding; {
gl::VertexArrayID vertexArrayID = {vertexArrayIter.first};
if (attrib.enabled != defaultAttrib.enabled) cap(CaptureGenVertexArrays(replayState, true, 1, &vertexArrayID));
{ MaybeCaptureUpdateResourceIDs(setupCalls);
cap(CaptureEnableVertexAttribArray(replayState, false, attribIndex));
}
if (attrib.format != defaultAttrib.format || attrib.pointer != defaultAttrib.pointer || if (vertexArrayIter.second)
binding.getStride() != defaultBinding.getStride() ||
binding.getBuffer().get() != nullptr)
{ {
gl::Buffer *buffer = binding.getBuffer().get(); const gl::VertexArray *vertexArray = vertexArrayIter.second;
if (buffer != replayState.getArrayBuffer()) // Bind the vertexArray (unless default) and populate it
if (vertexArrayID.value != 0)
{ {
replayState.setBufferBinding(context, gl::BufferBinding::Array, buffer); cap(CaptureBindVertexArray(replayState, true, vertexArrayID));
cap(CaptureBindBuffer(replayState, true, gl::BufferBinding::Array, buffer->id())); boundVertexArrayID = vertexArrayID;
} }
CaptureVertexArrayData(setupCalls, context, vertexArray, &replayState);
cap(CaptureVertexAttribPointer(replayState, true, attribIndex,
attrib.format->channelCount,
attrib.format->vertexAttribType, attrib.format->isNorm(),
binding.getStride(), attrib.pointer));
} }
}
if (binding.getDivisor() != 0) // Bind the current vertex array
{ const gl::VertexArray *currentVertexArray = apiState.getVertexArray();
cap(CaptureVertexAttribDivisor(replayState, true, attribIndex, binding.getDivisor())); if (currentVertexArray->id() != boundVertexArrayID)
} {
cap(CaptureBindVertexArray(replayState, true, currentVertexArray->id()));
} }
// Capture Buffer bindings. // Capture Buffer bindings.
......
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