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
mCachedIntegerVertexAttribTypesValidation;
};
using VertexArrayMap = ResourceMap<VertexArray, VertexArrayID>;
using QueryMap = ResourceMap<Query, QueryID>;
using TransformFeedbackMap = ResourceMap<TransformFeedback, TransformFeedbackID>;
......@@ -592,6 +593,7 @@ class Context final : public egl::LabeledObject, angle::NonCopyable, public angl
angle::FrameCapture *getFrameCapture() { return mFrameCapture.get(); }
const VertexArrayMap &getVertexArraysForCapture() const { return mVertexArrayMap; }
const QueryMap &getQueriesForCapture() const { return mQueryMap; }
const TransformFeedbackMap &getTransformFeedbacksForCapture() const
{
......@@ -686,7 +688,7 @@ class Context final : public egl::LabeledObject, angle::NonCopyable, public angl
QueryMap mQueryMap;
HandleAllocator mQueryHandleAllocator;
ResourceMap<VertexArray, VertexArrayID> mVertexArrayMap;
VertexArrayMap mVertexArrayMap;
HandleAllocator mVertexArrayHandleAllocator;
TransformFeedbackMap mTransformFeedbackMap;
......
......@@ -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,
std::vector<CallCapture> *setupCalls,
const ShaderSourceMap &cachedShaderSources,
......@@ -1319,55 +1367,49 @@ void CaptureMidExecutionSetup(const gl::Context *context,
// Vertex input states. Only handles GLES 2.0 states right now.
// Must happen after buffer data initialization.
// TODO(http://anglebug.com/3662): Complete state capture.
// Capture default vertex attribs
const std::vector<gl::VertexAttribCurrentValueData> &currentValues =
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)
{
const gl::VertexAttribCurrentValueData &currentValue = currentValues[attribIndex];
if (!IsDefaultCurrentValue(currentValue))
const gl::VertexAttribCurrentValueData &defaultValue = currentValues[attribIndex];
if (!IsDefaultCurrentValue(defaultValue))
{
cap(CaptureVertexAttrib4fv(replayState, true, attribIndex,
currentValue.Values.FloatValues));
Capture(setupCalls, CaptureVertexAttrib4fv(replayState, true, attribIndex,
defaultValue.Values.FloatValues));
}
}
const gl::VertexAttribute &attrib = vertexAttribs[attribIndex];
const gl::VertexBinding &binding = vertexBindings[attrib.bindingIndex];
const gl::VertexAttribute defaultAttrib(attribIndex);
const gl::VertexBinding defaultBinding;
if (attrib.enabled != defaultAttrib.enabled)
{
cap(CaptureEnableVertexAttribArray(replayState, false, attribIndex));
}
// Capture vertex array objects
const gl::VertexArrayMap &vertexArrayMap = context->getVertexArraysForCapture();
gl::VertexArrayID boundVertexArrayID = {0};
for (const auto &vertexArrayIter : vertexArrayMap)
{
gl::VertexArrayID vertexArrayID = {vertexArrayIter.first};
cap(CaptureGenVertexArrays(replayState, true, 1, &vertexArrayID));
MaybeCaptureUpdateResourceIDs(setupCalls);
if (attrib.format != defaultAttrib.format || attrib.pointer != defaultAttrib.pointer ||
binding.getStride() != defaultBinding.getStride() ||
binding.getBuffer().get() != nullptr)
if (vertexArrayIter.second)
{
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(CaptureBindBuffer(replayState, true, gl::BufferBinding::Array, buffer->id()));
cap(CaptureBindVertexArray(replayState, true, vertexArrayID));
boundVertexArrayID = vertexArrayID;
}
cap(CaptureVertexAttribPointer(replayState, true, attribIndex,
attrib.format->channelCount,
attrib.format->vertexAttribType, attrib.format->isNorm(),
binding.getStride(), attrib.pointer));
CaptureVertexArrayData(setupCalls, context, vertexArray, &replayState);
}
}
if (binding.getDivisor() != 0)
{
cap(CaptureVertexAttribDivisor(replayState, true, attribIndex, binding.getDivisor()));
}
// Bind the current vertex array
const gl::VertexArray *currentVertexArray = apiState.getVertexArray();
if (currentVertexArray->id() != boundVertexArrayID)
{
cap(CaptureBindVertexArray(replayState, true, currentVertexArray->id()));
}
// 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