Commit cee0bfd6 by Gert Wollny Committed by Commit Bot

Capture/Replay: serialize context to JSON

Bug: angleproject:5715 Change-Id: Ibc6897d7567fedab4a2ba7bf8d2bd5a7e496bd4b Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2760325Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarCody Northrop <cnorthrop@google.com> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent d00bd105
...@@ -1076,19 +1076,14 @@ void WriteCppReplay(bool compression, ...@@ -1076,19 +1076,14 @@ void WriteCppReplay(bool compression,
if (serializeStateEnabled) if (serializeStateEnabled)
{ {
gl::BinaryOutputStream serializedContextData{}; angle::JsonSerializer serializedContextData;
if (SerializeContext(&serializedContextData, const_cast<gl::Context *>(context)) == if (SerializeContext(&serializedContextData, const_cast<gl::Context *>(context)) ==
Result::Continue) Result::Continue)
{ {
size_t serializedContextLength = serializedContextData.length(); out << "const char *" << FmtGetSerializedContextStateFunction(context->id(), frameIndex)
size_t serializedContextOffset = rx::roundUpPow2(binaryData->size(), kBinaryAlignment); << "\n";
binaryData->resize(serializedContextOffset + serializedContextLength);
memcpy(binaryData->data() + serializedContextOffset, serializedContextData.data(),
serializedContextLength);
out << "const uint8_t *"
<< FmtGetSerializedContextStateFunction(context->id(), frameIndex) << "\n";
out << "{\n"; out << "{\n";
out << " return &gBinaryData[" << serializedContextOffset << "];\n"; out << " return R\"(" << serializedContextData.data() << ")\";\n";
out << "}\n"; out << "}\n";
out << "\n"; out << "\n";
} }
...@@ -1212,7 +1207,7 @@ void WriteCppReplayIndexFiles(bool compression, ...@@ -1212,7 +1207,7 @@ void WriteCppReplayIndexFiles(bool compression,
header << "ANGLE_REPLAY_EXPORT void ResetContext" << contextId << "Replay();\n"; header << "ANGLE_REPLAY_EXPORT void ResetContext" << contextId << "Replay();\n";
if (serializeStateEnabled) if (serializeStateEnabled)
{ {
header << "ANGLE_REPLAY_EXPORT const uint8_t *GetSerializedContext" << contextId header << "ANGLE_REPLAY_EXPORT const char * GetSerializedContext" << contextId
<< "State(uint32_t frameIndex);\n"; << "State(uint32_t frameIndex);\n";
} }
header << "\n"; header << "\n";
...@@ -1225,7 +1220,7 @@ void WriteCppReplayIndexFiles(bool compression, ...@@ -1225,7 +1220,7 @@ void WriteCppReplayIndexFiles(bool compression,
{ {
for (uint32_t frameIndex = 1; frameIndex <= frameCount; ++frameIndex) for (uint32_t frameIndex = 1; frameIndex <= frameCount; ++frameIndex)
{ {
header << "ANGLE_REPLAY_EXPORT const uint8_t *" header << "ANGLE_REPLAY_EXPORT const char *"
<< FmtGetSerializedContextStateFunction(contextId, frameIndex) << ";\n"; << FmtGetSerializedContextStateFunction(contextId, frameIndex) << ";\n";
} }
header << "\n"; header << "\n";
...@@ -1379,8 +1374,7 @@ void WriteCppReplayIndexFiles(bool compression, ...@@ -1379,8 +1374,7 @@ void WriteCppReplayIndexFiles(bool compression,
if (serializeStateEnabled) if (serializeStateEnabled)
{ {
source << "const uint8_t *GetSerializedContext" << contextId source << "const char *GetSerializedContext" << contextId << "State(uint32_t frameIndex)\n";
<< "State(uint32_t frameIndex)\n";
source << "{\n"; source << "{\n";
source << " switch (frameIndex)\n"; source << " switch (frameIndex)\n";
source << " {\n"; source << " {\n";
......
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
#include "common/Color.h" #include "common/Color.h"
#include "common/MemoryBuffer.h" #include "common/MemoryBuffer.h"
#include "common/angleutils.h" #include "common/angleutils.h"
#include "libANGLE/BinaryStream.h"
#include "libANGLE/Buffer.h" #include "libANGLE/Buffer.h"
#include "libANGLE/Caps.h" #include "libANGLE/Caps.h"
#include "libANGLE/Context.h" #include "libANGLE/Context.h"
...@@ -24,6 +23,7 @@ ...@@ -24,6 +23,7 @@
#include "libANGLE/ResourceMap.h" #include "libANGLE/ResourceMap.h"
#include "libANGLE/Sampler.h" #include "libANGLE/Sampler.h"
#include "libANGLE/State.h" #include "libANGLE/State.h"
#include "libANGLE/TransformFeedback.h" #include "libANGLE/TransformFeedback.h"
#include "libANGLE/VertexAttribute.h" #include "libANGLE/VertexAttribute.h"
#include "libANGLE/angletypes.h" #include "libANGLE/angletypes.h"
...@@ -42,46 +42,261 @@ namespace angle ...@@ -42,46 +42,261 @@ namespace angle
namespace namespace
{ {
void SerializeColorF(gl::BinaryOutputStream *bos, const ColorF &color) static const char *TextureTypeToString(gl::TextureType type)
{
switch (type)
{
case gl::TextureType::_2D:
return "TEXTURE_2D";
case gl::TextureType::_2DArray:
return "TEXTURE_2D_ARRAY";
case gl::TextureType::_2DMultisample:
return "TEXTURE_2DMS";
case gl::TextureType::_2DMultisampleArray:
return "TEXTURE_2DMS_ARRAY";
case gl::TextureType::_3D:
return "TEXTURE_3D";
case gl::TextureType::External:
return "TEXTURE_EXTERNAL";
case gl::TextureType::Rectangle:
return "TEXTURE_RECT";
case gl::TextureType::CubeMap:
return "TEXTURE_CUBE_MAP";
case gl::TextureType::CubeMapArray:
return "TEXTURE_CUBE_MAP_ARRAY";
case gl::TextureType::VideoImage:
return "TEXTURE_VIDEO_IMAGE";
case gl::TextureType::Buffer:
return "TEXTURE_BUFFER";
default:
return "invalid";
}
}
static const char *CullFaceModeToString(gl::CullFaceMode mode)
{
switch (mode)
{
case gl::CullFaceMode::Back:
return "CULL_BACK";
case gl::CullFaceMode::Front:
return "CULL_FRONT";
case gl::CullFaceMode::FrontAndBack:
return "CULL_FRONT_AND_BACK";
default:
return "invalid";
}
}
static const char *ProvokingVertexConventionToString(gl::ProvokingVertexConvention mode)
{
switch (mode)
{
case gl::ProvokingVertexConvention::FirstVertexConvention:
return "First";
case gl::ProvokingVertexConvention::LastVertexConvention:
return "Last";
default:
return "invalid";
}
}
static const char *InitStateToString(gl::InitState state)
{
return state == gl::InitState::Initialized ? "Initialized" : "MayNeedInit";
}
static const char *BlockLayoutTypeToString(sh::BlockLayoutType type)
{
switch (type)
{
case sh::BlockLayoutType::BLOCKLAYOUT_STD140:
return "std140";
case sh::BlockLayoutType::BLOCKLAYOUT_STD430:
return "std430";
case sh::BlockLayoutType::BLOCKLAYOUT_PACKED:
return "packed";
case sh::BlockLayoutType::BLOCKLAYOUT_SHARED:
return "shared";
default:
return "invalid";
}
}
static const char *BlockTypeToString(sh::BlockType type)
{
return type == sh::BlockType::BLOCK_BUFFER ? "buffer" : "uniform";
}
static const char *InterpolationTypeToString(sh::InterpolationType type)
{
switch (type)
{
case sh::InterpolationType::INTERPOLATION_SMOOTH:
return "smooth";
case sh::InterpolationType::INTERPOLATION_CENTROID:
return "centroid";
case sh::InterpolationType::INTERPOLATION_SAMPLE:
return "sample";
case sh::InterpolationType::INTERPOLATION_FLAT:
return "flat";
case sh::InterpolationType::INTERPOLATION_NOPERSPECTIVE:
return "noperspective";
default:
return "invalid";
}
}
#define ENUM_TO_STRING(C, M) \
case C ::M: \
return #M
static const char *PrimitiveModeToString(gl::PrimitiveMode mode)
{
switch (mode)
{
ENUM_TO_STRING(gl::PrimitiveMode, Points);
ENUM_TO_STRING(gl::PrimitiveMode, Lines);
ENUM_TO_STRING(gl::PrimitiveMode, LineLoop);
ENUM_TO_STRING(gl::PrimitiveMode, LineStrip);
ENUM_TO_STRING(gl::PrimitiveMode, Triangles);
ENUM_TO_STRING(gl::PrimitiveMode, TriangleStrip);
ENUM_TO_STRING(gl::PrimitiveMode, TriangleFan);
ENUM_TO_STRING(gl::PrimitiveMode, Unused1);
ENUM_TO_STRING(gl::PrimitiveMode, Unused2);
ENUM_TO_STRING(gl::PrimitiveMode, Unused3);
ENUM_TO_STRING(gl::PrimitiveMode, LinesAdjacency);
ENUM_TO_STRING(gl::PrimitiveMode, LineStripAdjacency);
ENUM_TO_STRING(gl::PrimitiveMode, TrianglesAdjacency);
ENUM_TO_STRING(gl::PrimitiveMode, TriangleStripAdjacency);
ENUM_TO_STRING(gl::PrimitiveMode, Patches);
default:
return "invalid";
}
}
static const char *BufferUsageToString(gl::BufferUsage usage)
{
switch (usage)
{
ENUM_TO_STRING(gl::BufferUsage, DynamicCopy);
ENUM_TO_STRING(gl::BufferUsage, DynamicDraw);
ENUM_TO_STRING(gl::BufferUsage, DynamicRead);
ENUM_TO_STRING(gl::BufferUsage, StaticCopy);
ENUM_TO_STRING(gl::BufferUsage, StaticDraw);
ENUM_TO_STRING(gl::BufferUsage, StaticRead);
ENUM_TO_STRING(gl::BufferUsage, StreamCopy);
ENUM_TO_STRING(gl::BufferUsage, StreamDraw);
ENUM_TO_STRING(gl::BufferUsage, StreamRead);
default:
return "invalid";
}
}
static const char *SrgbOverrideToString(gl::SrgbOverride value)
{
switch (value)
{
ENUM_TO_STRING(gl::SrgbOverride, Default);
ENUM_TO_STRING(gl::SrgbOverride, SRGB);
ENUM_TO_STRING(gl::SrgbOverride, Linear);
default:
return "invalid";
}
}
static const char *ColorGenericTypeToString(gl::ColorGeneric::Type type)
{
switch (type)
{
ENUM_TO_STRING(gl::ColorGeneric::Type, Float);
ENUM_TO_STRING(gl::ColorGeneric::Type, Int);
ENUM_TO_STRING(gl::ColorGeneric::Type, UInt);
default:
return "invalid";
}
}
static const char *CompileStatusToString(gl::CompileStatus status)
{
switch (status)
{
ENUM_TO_STRING(gl::CompileStatus, NOT_COMPILED);
ENUM_TO_STRING(gl::CompileStatus, COMPILE_REQUESTED);
ENUM_TO_STRING(gl::CompileStatus, COMPILED);
default:
return "invalid";
}
}
#undef ENUM_TO_STRING
class GroupScope
{
public:
GroupScope(JsonSerializer *json_, const std::string &name) : json(json_)
{
json->startGroup(name);
}
template <typename Int>
GroupScope(JsonSerializer *json_, const std::string &name, Int index) : json(json_)
{
std::ostringstream os;
os << name << index;
json->startGroup(os.str());
}
template <typename Int>
GroupScope(JsonSerializer *json_, Int index) : GroupScope(json_, "", index)
{}
~GroupScope() { json->endGroup(); }
private:
JsonSerializer *json;
};
void SerializeColorF(JsonSerializer *json, const ColorF &color)
{ {
bos->writeFloat(color.red); json->addScalar("red", color.red);
bos->writeFloat(color.green); json->addScalar("green", color.green);
bos->writeFloat(color.blue); json->addScalar("blue", color.blue);
bos->writeFloat(color.alpha); json->addScalar("alpha", color.alpha);
} }
void SerializeColorI(gl::BinaryOutputStream *bos, const ColorI &color) void SerializeColorI(JsonSerializer *json, const ColorI &color)
{ {
bos->writeInt(color.red); json->addScalar("Red", color.red);
bos->writeInt(color.green); json->addScalar("Green", color.green);
bos->writeInt(color.blue); json->addScalar("Blue", color.blue);
bos->writeInt(color.alpha); json->addScalar("Alpha", color.alpha);
} }
void SerializeColorUI(gl::BinaryOutputStream *bos, const ColorUI &color) void SerializeColorUI(JsonSerializer *json, const ColorUI &color)
{ {
bos->writeInt(color.red); json->addScalar("Red", color.red);
bos->writeInt(color.green); json->addScalar("Green", color.green);
bos->writeInt(color.blue); json->addScalar("Blue", color.blue);
bos->writeInt(color.alpha); json->addScalar("Alpha", color.alpha);
} }
template <class ObjectType> template <class ObjectType>
void SerializeOffsetBindingPointerVector( void SerializeOffsetBindingPointerVector(
gl::BinaryOutputStream *bos, JsonSerializer *json,
const std::vector<gl::OffsetBindingPointer<ObjectType>> &offsetBindingPointerVector) const std::vector<gl::OffsetBindingPointer<ObjectType>> &offsetBindingPointerVector)
{ {
for (size_t i = 0; i < offsetBindingPointerVector.size(); i++) for (size_t i = 0; i < offsetBindingPointerVector.size(); i++)
{ {
bos->writeInt(offsetBindingPointerVector[i].id().value); GroupScope group(json, i);
bos->writeInt(offsetBindingPointerVector[i].getOffset()); json->addScalar("Value", offsetBindingPointerVector[i].id().value);
bos->writeInt(offsetBindingPointerVector[i].getSize()); json->addScalar("Offset", offsetBindingPointerVector[i].getOffset());
json->addScalar("Size", offsetBindingPointerVector[i].getSize());
} }
} }
template <class ObjectType> template <class ObjectType>
void SerializeBindingPointerVector( void SerializeBindingPointerVector(
gl::BinaryOutputStream *bos, JsonSerializer *json,
const std::vector<gl::BindingPointer<ObjectType>> &bindingPointerVector) const std::vector<gl::BindingPointer<ObjectType>> &bindingPointerVector)
{ {
for (size_t i = 0; i < bindingPointerVector.size(); i++) for (size_t i = 0; i < bindingPointerVector.size(); i++)
...@@ -89,16 +304,19 @@ void SerializeBindingPointerVector( ...@@ -89,16 +304,19 @@ void SerializeBindingPointerVector(
// Do not serialize zero bindings, as this will create unwanted diffs // Do not serialize zero bindings, as this will create unwanted diffs
if (bindingPointerVector[i].id().value != 0) if (bindingPointerVector[i].id().value != 0)
{ {
bos->writeInt(bindingPointerVector[i].id().value); std::ostringstream s;
s << i;
json->addScalar(s.str().c_str(), bindingPointerVector[i].id().value);
} }
} }
} }
template <class T> template <class T>
void SerializeRange(gl::BinaryOutputStream *bos, const gl::Range<T> &range) void SerializeRange(JsonSerializer *json, const gl::Range<T> &range)
{ {
bos->writeInt(range.low()); GroupScope group(json, "Range");
bos->writeInt(range.high()); json->addScalar("Low", range.low());
json->addScalar("High", range.high());
} }
bool IsValidColorAttachmentBinding(GLenum binding, size_t colorAttachmentsCount) bool IsValidColorAttachmentBinding(GLenum binding, size_t colorAttachmentsCount)
...@@ -129,16 +347,17 @@ Result ReadPixelsFromAttachment(const gl::Context *context, ...@@ -129,16 +347,17 @@ Result ReadPixelsFromAttachment(const gl::Context *context,
(*pixels)->data())); (*pixels)->data()));
return Result::Continue; return Result::Continue;
} }
void SerializeImageIndex(gl::BinaryOutputStream *bos, const gl::ImageIndex &imageIndex) void SerializeImageIndex(JsonSerializer *json, const gl::ImageIndex &imageIndex)
{ {
bos->writeEnum(imageIndex.getType()); GroupScope group(json, "Image");
bos->writeInt(imageIndex.getLevelIndex()); json->addCString("ImageType", TextureTypeToString(imageIndex.getType()));
bos->writeInt(imageIndex.getLayerIndex()); json->addScalar("LevelIndex", imageIndex.getLevelIndex());
bos->writeInt(imageIndex.getLayerCount()); json->addScalar("LayerIndex", imageIndex.getLayerIndex());
json->addScalar("LayerCount", imageIndex.getLayerCount());
} }
Result SerializeFramebufferAttachment(const gl::Context *context, Result SerializeFramebufferAttachment(const gl::Context *context,
gl::BinaryOutputStream *bos, JsonSerializer *json,
ScratchBuffer *scratchBuffer, ScratchBuffer *scratchBuffer,
gl::Framebuffer *framebuffer, gl::Framebuffer *framebuffer,
const gl::FramebufferAttachment &framebufferAttachment) const gl::FramebufferAttachment &framebufferAttachment)
...@@ -146,19 +365,19 @@ Result SerializeFramebufferAttachment(const gl::Context *context, ...@@ -146,19 +365,19 @@ Result SerializeFramebufferAttachment(const gl::Context *context,
if (framebufferAttachment.type() == GL_TEXTURE || if (framebufferAttachment.type() == GL_TEXTURE ||
framebufferAttachment.type() == GL_RENDERBUFFER) framebufferAttachment.type() == GL_RENDERBUFFER)
{ {
bos->writeInt(framebufferAttachment.id()); json->addScalar("ID", framebufferAttachment.id());
} }
bos->writeInt(framebufferAttachment.type()); json->addScalar("Type", framebufferAttachment.type());
// serialize target variable // serialize target variable
bos->writeInt(framebufferAttachment.getBinding()); json->addScalar("Binding", framebufferAttachment.getBinding());
if (framebufferAttachment.type() == GL_TEXTURE) if (framebufferAttachment.type() == GL_TEXTURE)
{ {
SerializeImageIndex(bos, framebufferAttachment.getTextureImageIndex()); SerializeImageIndex(json, framebufferAttachment.getTextureImageIndex());
} }
bos->writeInt(framebufferAttachment.getNumViews()); json->addScalar("NumViews", framebufferAttachment.getNumViews());
bos->writeBool(framebufferAttachment.isMultiview()); json->addScalar("Multiview", framebufferAttachment.isMultiview());
bos->writeInt(framebufferAttachment.getBaseViewIndex()); json->addScalar("ViewIndex", framebufferAttachment.getBaseViewIndex());
bos->writeInt(framebufferAttachment.getRenderToTextureSamples()); json->addScalar("Samples", framebufferAttachment.getRenderToTextureSamples());
if (framebufferAttachment.type() != GL_TEXTURE && if (framebufferAttachment.type() != GL_TEXTURE &&
framebufferAttachment.type() != GL_RENDERBUFFER) framebufferAttachment.type() != GL_RENDERBUFFER)
...@@ -174,7 +393,7 @@ Result SerializeFramebufferAttachment(const gl::Context *context, ...@@ -174,7 +393,7 @@ Result SerializeFramebufferAttachment(const gl::Context *context,
MemoryBuffer *pixelsPtr = nullptr; MemoryBuffer *pixelsPtr = nullptr;
ANGLE_TRY(ReadPixelsFromAttachment(context, framebuffer, framebufferAttachment, ANGLE_TRY(ReadPixelsFromAttachment(context, framebuffer, framebufferAttachment,
scratchBuffer, &pixelsPtr)); scratchBuffer, &pixelsPtr));
bos->writeBytes(pixelsPtr->data(), pixelsPtr->size()); json->addBlob("Data", pixelsPtr->data(), pixelsPtr->size());
// Reset framebuffer state // Reset framebuffer state
framebuffer->setReadBuffer(prevReadBufferState); framebuffer->setReadBuffer(prevReadBufferState);
} }
...@@ -182,20 +401,22 @@ Result SerializeFramebufferAttachment(const gl::Context *context, ...@@ -182,20 +401,22 @@ Result SerializeFramebufferAttachment(const gl::Context *context,
} }
Result SerializeFramebufferState(const gl::Context *context, Result SerializeFramebufferState(const gl::Context *context,
gl::BinaryOutputStream *bos, JsonSerializer *json,
ScratchBuffer *scratchBuffer, ScratchBuffer *scratchBuffer,
gl::Framebuffer *framebuffer, gl::Framebuffer *framebuffer,
const gl::FramebufferState &framebufferState) const gl::FramebufferState &framebufferState)
{ {
bos->writeInt(framebufferState.id().value); GroupScope group(json, "Framebuffer");
bos->writeString(framebufferState.getLabel()); json->addScalar("ID", framebufferState.id().value);
bos->writeIntVector(framebufferState.getDrawBufferStates()); json->addScalar("Label", framebufferState.getLabel());
bos->writeInt(framebufferState.getReadBufferState()); json->addVector("DrawStates", framebufferState.getDrawBufferStates());
bos->writeInt(framebufferState.getDefaultWidth()); json->addScalar("ReadBufferState", framebufferState.getReadBufferState());
bos->writeInt(framebufferState.getDefaultHeight()); json->addScalar("DefaultWidth", framebufferState.getDefaultWidth());
bos->writeInt(framebufferState.getDefaultSamples()); json->addScalar("DefaultHeight", framebufferState.getDefaultHeight());
bos->writeBool(framebufferState.getDefaultFixedSampleLocations()); json->addScalar("DefaultSamples", framebufferState.getDefaultSamples());
bos->writeInt(framebufferState.getDefaultLayers()); json->addScalar("DefaultFixedSampleLocation",
framebufferState.getDefaultFixedSampleLocations());
json->addScalar("DefaultLayers", framebufferState.getDefaultLayers());
const std::vector<gl::FramebufferAttachment> &colorAttachments = const std::vector<gl::FramebufferAttachment> &colorAttachments =
framebufferState.getColorAttachments(); framebufferState.getColorAttachments();
...@@ -203,25 +424,29 @@ Result SerializeFramebufferState(const gl::Context *context, ...@@ -203,25 +424,29 @@ Result SerializeFramebufferState(const gl::Context *context,
{ {
if (colorAttachment.isAttached()) if (colorAttachment.isAttached())
{ {
ANGLE_TRY(SerializeFramebufferAttachment(context, bos, scratchBuffer, framebuffer, GroupScope colorAttachmentgroup(json, "ColorAttachment");
ANGLE_TRY(SerializeFramebufferAttachment(context, json, scratchBuffer, framebuffer,
colorAttachment)); colorAttachment));
} }
} }
if (framebuffer->getDepthStencilAttachment()) if (framebuffer->getDepthStencilAttachment())
{ {
ANGLE_TRY(SerializeFramebufferAttachment(context, bos, scratchBuffer, framebuffer, GroupScope dsAttachmentgroup(json, "DepthStencilAttachment");
ANGLE_TRY(SerializeFramebufferAttachment(context, json, scratchBuffer, framebuffer,
*framebuffer->getDepthStencilAttachment())); *framebuffer->getDepthStencilAttachment()));
} }
else else
{ {
if (framebuffer->getDepthAttachment()) if (framebuffer->getDepthAttachment())
{ {
ANGLE_TRY(SerializeFramebufferAttachment(context, bos, scratchBuffer, framebuffer, GroupScope depthAttachmentgroup(json, "DepthAttachment");
ANGLE_TRY(SerializeFramebufferAttachment(context, json, scratchBuffer, framebuffer,
*framebuffer->getDepthAttachment())); *framebuffer->getDepthAttachment()));
} }
if (framebuffer->getStencilAttachment()) if (framebuffer->getStencilAttachment())
{ {
ANGLE_TRY(SerializeFramebufferAttachment(context, bos, scratchBuffer, framebuffer, GroupScope stencilAttachmengroup(json, "StencilAttachment");
ANGLE_TRY(SerializeFramebufferAttachment(context, json, scratchBuffer, framebuffer,
*framebuffer->getStencilAttachment())); *framebuffer->getStencilAttachment()));
} }
} }
...@@ -229,72 +454,78 @@ Result SerializeFramebufferState(const gl::Context *context, ...@@ -229,72 +454,78 @@ Result SerializeFramebufferState(const gl::Context *context,
} }
Result SerializeFramebuffer(const gl::Context *context, Result SerializeFramebuffer(const gl::Context *context,
gl::BinaryOutputStream *bos, JsonSerializer *json,
ScratchBuffer *scratchBuffer, ScratchBuffer *scratchBuffer,
gl::Framebuffer *framebuffer) gl::Framebuffer *framebuffer)
{ {
return SerializeFramebufferState(context, bos, scratchBuffer, framebuffer, return SerializeFramebufferState(context, json, scratchBuffer, framebuffer,
framebuffer->getState()); framebuffer->getState());
} }
void SerializeRasterizerState(gl::BinaryOutputStream *bos, void SerializeRasterizerState(JsonSerializer *json, const gl::RasterizerState &rasterizerState)
const gl::RasterizerState &rasterizerState)
{ {
bos->writeBool(rasterizerState.cullFace); GroupScope group(json, "Rasterizer");
bos->writeEnum(rasterizerState.cullMode); json->addScalar("CullFace", rasterizerState.cullFace);
bos->writeInt(rasterizerState.frontFace); json->addCString("CullMode", CullFaceModeToString(rasterizerState.cullMode));
bos->writeBool(rasterizerState.polygonOffsetFill); json->addScalar("FrontFace", rasterizerState.frontFace);
bos->writeFloat(rasterizerState.polygonOffsetFactor); json->addScalar("PolygonOffsetFill", rasterizerState.polygonOffsetFill);
bos->writeFloat(rasterizerState.polygonOffsetUnits); json->addScalar("PolygonOffsetFactor", rasterizerState.polygonOffsetFactor);
bos->writeBool(rasterizerState.pointDrawMode); json->addScalar("PolygonOffsetUnits", rasterizerState.polygonOffsetUnits);
bos->writeBool(rasterizerState.multiSample); json->addScalar("PointDrawMode", rasterizerState.pointDrawMode);
bos->writeBool(rasterizerState.rasterizerDiscard); json->addScalar("MultiSample", rasterizerState.multiSample);
bos->writeBool(rasterizerState.dither); json->addScalar("RasterizerDiscard", rasterizerState.rasterizerDiscard);
json->addScalar("Dither", rasterizerState.dither);
} }
void SerializeRectangle(gl::BinaryOutputStream *bos, const gl::Rectangle &rectangle) void SerializeRectangle(JsonSerializer *json,
const std::string &name,
const gl::Rectangle &rectangle)
{ {
bos->writeInt(rectangle.x); GroupScope group(json, name);
bos->writeInt(rectangle.y); json->addScalar("x", rectangle.x);
bos->writeInt(rectangle.width); json->addScalar("y", rectangle.y);
bos->writeInt(rectangle.height); json->addScalar("w", rectangle.width);
json->addScalar("h", rectangle.height);
} }
void SerializeBlendStateExt(gl::BinaryOutputStream *bos, const gl::BlendStateExt &blendStateExt) void SerializeBlendStateExt(JsonSerializer *json, const gl::BlendStateExt &blendStateExt)
{ {
bos->writeInt(blendStateExt.mEnabledMask.bits()); GroupScope group(json, "BlendStateExt");
bos->writeInt(blendStateExt.mDstColor); json->addScalar("MaxDrawBuffers", blendStateExt.mMaxDrawBuffers);
bos->writeInt(blendStateExt.mDstAlpha); json->addScalar("enableMask", blendStateExt.mEnabledMask.bits());
bos->writeInt(blendStateExt.mSrcColor); json->addScalar("DstColor", blendStateExt.mDstColor);
bos->writeInt(blendStateExt.mSrcAlpha); json->addScalar("DstAlpha", blendStateExt.mDstAlpha);
bos->writeInt(blendStateExt.mEquationColor); json->addScalar("SrcColor", blendStateExt.mSrcColor);
bos->writeInt(blendStateExt.mEquationAlpha); json->addScalar("SrcAlpha", blendStateExt.mSrcAlpha);
bos->writeInt(blendStateExt.mColorMask); json->addScalar("EquationColor", blendStateExt.mEquationColor);
json->addScalar("EquationAlpha", blendStateExt.mEquationAlpha);
json->addScalar("ColorMask", blendStateExt.mColorMask);
} }
void SerializeDepthStencilState(gl::BinaryOutputStream *bos, void SerializeDepthStencilState(JsonSerializer *json,
const gl::DepthStencilState &depthStencilState) const gl::DepthStencilState &depthStencilState)
{ {
bos->writeBool(depthStencilState.depthTest); GroupScope group(json, "DepthStencilState");
bos->writeInt(depthStencilState.depthFunc); json->addScalar("DepthTest", depthStencilState.depthTest);
bos->writeBool(depthStencilState.depthMask); json->addScalar("DepthFunc", depthStencilState.depthFunc);
bos->writeBool(depthStencilState.stencilTest); json->addScalar("DepthMask", depthStencilState.depthMask);
bos->writeInt(depthStencilState.stencilFunc); json->addScalar("StencilTest", depthStencilState.stencilTest);
bos->writeInt(depthStencilState.stencilMask); json->addScalar("StencilFunc", depthStencilState.stencilFunc);
bos->writeInt(depthStencilState.stencilFail); json->addScalar("StencilMask", depthStencilState.stencilMask);
bos->writeInt(depthStencilState.stencilPassDepthFail); json->addScalar("StencilFail", depthStencilState.stencilFail);
bos->writeInt(depthStencilState.stencilPassDepthPass); json->addScalar("StencilPassDepthFail", depthStencilState.stencilPassDepthFail);
bos->writeInt(depthStencilState.stencilWritemask); json->addScalar("StencilPassDepthPass", depthStencilState.stencilPassDepthPass);
bos->writeInt(depthStencilState.stencilBackFunc); json->addScalar("StencilWritemask", depthStencilState.stencilWritemask);
bos->writeInt(depthStencilState.stencilBackMask); json->addScalar("StencilBackFunc", depthStencilState.stencilBackFunc);
bos->writeInt(depthStencilState.stencilBackFail); json->addScalar("StencilBackMask", depthStencilState.stencilBackMask);
bos->writeInt(depthStencilState.stencilBackPassDepthFail); json->addScalar("StencilBackFail", depthStencilState.stencilBackFail);
bos->writeInt(depthStencilState.stencilBackPassDepthPass); json->addScalar("StencilBackPassDepthFail", depthStencilState.stencilBackPassDepthFail);
bos->writeInt(depthStencilState.stencilBackWritemask); json->addScalar("StencilBackPassDepthPass", depthStencilState.stencilBackPassDepthPass);
json->addScalar("StencilBackWritemask", depthStencilState.stencilBackWritemask);
} }
void SerializeVertexAttribCurrentValueData( void SerializeVertexAttribCurrentValueData(
gl::BinaryOutputStream *bos, JsonSerializer *json,
const gl::VertexAttribCurrentValueData &vertexAttribCurrentValueData) const gl::VertexAttribCurrentValueData &vertexAttribCurrentValueData)
{ {
ASSERT(vertexAttribCurrentValueData.Type == gl::VertexAttribType::Float || ASSERT(vertexAttribCurrentValueData.Type == gl::VertexAttribType::Float ||
...@@ -302,282 +533,303 @@ void SerializeVertexAttribCurrentValueData( ...@@ -302,282 +533,303 @@ void SerializeVertexAttribCurrentValueData(
vertexAttribCurrentValueData.Type == gl::VertexAttribType::UnsignedInt); vertexAttribCurrentValueData.Type == gl::VertexAttribType::UnsignedInt);
if (vertexAttribCurrentValueData.Type == gl::VertexAttribType::Float) if (vertexAttribCurrentValueData.Type == gl::VertexAttribType::Float)
{ {
bos->writeFloat(vertexAttribCurrentValueData.Values.FloatValues[0]); json->addScalar("0", vertexAttribCurrentValueData.Values.FloatValues[0]);
bos->writeFloat(vertexAttribCurrentValueData.Values.FloatValues[1]); json->addScalar("1", vertexAttribCurrentValueData.Values.FloatValues[1]);
bos->writeFloat(vertexAttribCurrentValueData.Values.FloatValues[2]); json->addScalar("2", vertexAttribCurrentValueData.Values.FloatValues[2]);
bos->writeFloat(vertexAttribCurrentValueData.Values.FloatValues[3]); json->addScalar("3", vertexAttribCurrentValueData.Values.FloatValues[3]);
} }
else if (vertexAttribCurrentValueData.Type == gl::VertexAttribType::Int) else if (vertexAttribCurrentValueData.Type == gl::VertexAttribType::Int)
{ {
bos->writeInt(vertexAttribCurrentValueData.Values.IntValues[0]); json->addScalar("0", vertexAttribCurrentValueData.Values.IntValues[0]);
bos->writeInt(vertexAttribCurrentValueData.Values.IntValues[1]); json->addScalar("1", vertexAttribCurrentValueData.Values.IntValues[1]);
bos->writeInt(vertexAttribCurrentValueData.Values.IntValues[2]); json->addScalar("2", vertexAttribCurrentValueData.Values.IntValues[2]);
bos->writeInt(vertexAttribCurrentValueData.Values.IntValues[3]); json->addScalar("3", vertexAttribCurrentValueData.Values.IntValues[3]);
} }
else else
{ {
bos->writeInt(vertexAttribCurrentValueData.Values.UnsignedIntValues[0]); json->addScalar("0", vertexAttribCurrentValueData.Values.UnsignedIntValues[0]);
bos->writeInt(vertexAttribCurrentValueData.Values.UnsignedIntValues[1]); json->addScalar("1", vertexAttribCurrentValueData.Values.UnsignedIntValues[1]);
bos->writeInt(vertexAttribCurrentValueData.Values.UnsignedIntValues[2]); json->addScalar("2", vertexAttribCurrentValueData.Values.UnsignedIntValues[2]);
bos->writeInt(vertexAttribCurrentValueData.Values.UnsignedIntValues[3]); json->addScalar("3", vertexAttribCurrentValueData.Values.UnsignedIntValues[3]);
} }
} }
void SerializePixelPackState(gl::BinaryOutputStream *bos, const gl::PixelPackState &pixelPackState) void SerializePixelPackState(JsonSerializer *json, const gl::PixelPackState &pixelPackState)
{ {
bos->writeInt(pixelPackState.alignment); GroupScope group(json, "PixelPackState");
bos->writeInt(pixelPackState.rowLength); json->addScalar("Alignment", pixelPackState.alignment);
bos->writeInt(pixelPackState.skipRows); json->addScalar("RowLength", pixelPackState.rowLength);
bos->writeInt(pixelPackState.skipPixels); json->addScalar("SkipRows", pixelPackState.skipRows);
bos->writeInt(pixelPackState.imageHeight); json->addScalar("SkipPixels", pixelPackState.skipPixels);
bos->writeInt(pixelPackState.skipImages); json->addScalar("ImageHeight", pixelPackState.imageHeight);
bos->writeBool(pixelPackState.reverseRowOrder); json->addScalar("SkipImages", pixelPackState.skipImages);
json->addScalar("ReverseRowOrder", pixelPackState.reverseRowOrder);
} }
void SerializePixelUnpackState(gl::BinaryOutputStream *bos, void SerializePixelUnpackState(JsonSerializer *json, const gl::PixelUnpackState &pixelUnpackState)
const gl::PixelUnpackState &pixelUnpackState)
{ {
bos->writeInt(pixelUnpackState.alignment); GroupScope group(json, "PixelUnpackState");
bos->writeInt(pixelUnpackState.rowLength); json->addScalar("Alignment", pixelUnpackState.alignment);
bos->writeInt(pixelUnpackState.skipRows); json->addScalar("RowLength", pixelUnpackState.rowLength);
bos->writeInt(pixelUnpackState.skipPixels); json->addScalar("SkipRows", pixelUnpackState.skipRows);
bos->writeInt(pixelUnpackState.imageHeight); json->addScalar("SkipPixels", pixelUnpackState.skipPixels);
bos->writeInt(pixelUnpackState.skipImages); json->addScalar("ImageHeight", pixelUnpackState.imageHeight);
json->addScalar("SkipImages", pixelUnpackState.skipImages);
} }
void SerializeImageUnit(gl::BinaryOutputStream *bos, const gl::ImageUnit &imageUnit) void SerializeImageUnit(JsonSerializer *json, const gl::ImageUnit &imageUnit)
{ {
bos->writeInt(imageUnit.level); GroupScope group(json, "ImageUnit");
bos->writeInt(imageUnit.layered); json->addScalar("Level", imageUnit.level);
bos->writeInt(imageUnit.layer); json->addScalar("Layered", imageUnit.layered);
bos->writeInt(imageUnit.access); json->addScalar("Layer", imageUnit.layer);
bos->writeInt(imageUnit.format); json->addScalar("Access", imageUnit.access);
bos->writeInt(imageUnit.texture.id().value); json->addScalar("Format", imageUnit.format);
json->addScalar("Texid", imageUnit.texture.id().value);
} }
void SerializeGLContextStates(gl::BinaryOutputStream *bos, const gl::State &state) void SerializeGLContextStates(JsonSerializer *json, const gl::State &state)
{ {
bos->writeInt(state.getClientType()); GroupScope group(json, "ContextStates");
bos->writeInt(state.getContextPriority()); json->addScalar("ClientType", state.getClientType());
bos->writeInt(state.getClientMajorVersion()); json->addScalar("Priority", state.getContextPriority());
bos->writeInt(state.getClientMinorVersion()); json->addScalar("Major", state.getClientMajorVersion());
json->addScalar("Minor", state.getClientMinorVersion());
SerializeColorF(bos, state.getColorClearValue());
bos->writeFloat(state.getDepthClearValue()); SerializeColorF(json, state.getColorClearValue());
bos->writeInt(state.getStencilClearValue()); json->addScalar("DepthClearValue", state.getDepthClearValue());
SerializeRasterizerState(bos, state.getRasterizerState()); json->addScalar("StencilClearValue", state.getStencilClearValue());
bos->writeBool(state.isScissorTestEnabled()); SerializeRasterizerState(json, state.getRasterizerState());
SerializeRectangle(bos, state.getScissor()); json->addScalar("ScissorTestEnabled", state.isScissorTestEnabled());
SerializeBlendStateExt(bos, state.getBlendStateExt()); SerializeRectangle(json, "Scissors", state.getScissor());
SerializeColorF(bos, state.getBlendColor()); SerializeBlendStateExt(json, state.getBlendStateExt());
bos->writeBool(state.isSampleAlphaToCoverageEnabled()); SerializeColorF(json, state.getBlendColor());
bos->writeBool(state.isSampleCoverageEnabled()); json->addScalar("SampleAlphaToCoverageEnabled", state.isSampleAlphaToCoverageEnabled());
bos->writeFloat(state.getSampleCoverageValue()); json->addScalar("SampleCoverageEnabled", state.isSampleCoverageEnabled());
bos->writeBool(state.getSampleCoverageInvert()); json->addScalar("SampleCoverageValue", state.getSampleCoverageValue());
bos->writeBool(state.isSampleMaskEnabled()); json->addScalar("SampleCoverageInvert", state.getSampleCoverageInvert());
bos->writeInt(state.getMaxSampleMaskWords()); json->addScalar("SampleMaskEnabled", state.isSampleMaskEnabled());
json->addScalar("MaxSampleMaskWords", state.getMaxSampleMaskWords());
const auto &sampleMaskValues = state.getSampleMaskValues(); const auto &sampleMaskValues = state.getSampleMaskValues();
for (size_t i = 0; i < sampleMaskValues.size(); i++) for (size_t i = 0; i < sampleMaskValues.size(); i++)
{ {
bos->writeInt(sampleMaskValues[i]); std::ostringstream os;
} os << i;
SerializeDepthStencilState(bos, state.getDepthStencilState()); json->addScalar(os.str(), sampleMaskValues[i]);
bos->writeInt(state.getStencilRef()); }
bos->writeInt(state.getStencilBackRef()); SerializeDepthStencilState(json, state.getDepthStencilState());
bos->writeFloat(state.getLineWidth()); json->addScalar("StencilRef", state.getStencilRef());
bos->writeInt(state.getGenerateMipmapHint()); json->addScalar("StencilBackRef", state.getStencilBackRef());
bos->writeInt(state.getTextureFilteringHint()); json->addScalar("LineWidth", state.getLineWidth());
bos->writeInt(state.getFragmentShaderDerivativeHint()); json->addScalar("GenerateMipmapHint", state.getGenerateMipmapHint());
bos->writeBool(state.isBindGeneratesResourceEnabled()); json->addScalar("TextureFilteringHint", state.getTextureFilteringHint());
bos->writeBool(state.areClientArraysEnabled()); json->addScalar("FragmentShaderDerivativeHint", state.getFragmentShaderDerivativeHint());
SerializeRectangle(bos, state.getViewport()); json->addScalar("BindGeneratesResourceEnabled", state.isBindGeneratesResourceEnabled());
bos->writeFloat(state.getNearPlane()); json->addScalar("ClientArraysEnabled", state.areClientArraysEnabled());
bos->writeFloat(state.getFarPlane()); SerializeRectangle(json, "Viewport", state.getViewport());
json->addScalar("Near", state.getNearPlane());
json->addScalar("Far", state.getFarPlane());
if (state.getReadFramebuffer()) if (state.getReadFramebuffer())
{ {
bos->writeInt(state.getReadFramebuffer()->id().value); json->addScalar("Framebuffer ID", state.getReadFramebuffer()->id().value);
} }
if (state.getDrawFramebuffer()) if (state.getDrawFramebuffer())
{ {
bos->writeInt(state.getDrawFramebuffer()->id().value); json->addScalar("Draw Framebuffer ID", state.getDrawFramebuffer()->id().value);
} }
bos->writeInt(state.getRenderbufferId().value); json->addScalar("Renderbuffer ID", state.getRenderbufferId().value);
if (state.getProgram()) if (state.getProgram())
{ {
bos->writeInt(state.getProgram()->id().value); json->addScalar("ProgramID", state.getProgram()->id().value);
} }
if (state.getProgramPipeline()) if (state.getProgramPipeline())
{ {
bos->writeInt(state.getProgramPipeline()->id().value); json->addScalar("ProgramPipelineID", state.getProgramPipeline()->id().value);
} }
bos->writeEnum(state.getProvokingVertex()); json->addCString("ProvokingVertex",
ProvokingVertexConventionToString(state.getProvokingVertex()));
const std::vector<gl::VertexAttribCurrentValueData> &vertexAttribCurrentValues = const std::vector<gl::VertexAttribCurrentValueData> &vertexAttribCurrentValues =
state.getVertexAttribCurrentValues(); state.getVertexAttribCurrentValues();
for (size_t i = 0; i < vertexAttribCurrentValues.size(); i++) for (size_t i = 0; i < vertexAttribCurrentValues.size(); i++)
{ {
SerializeVertexAttribCurrentValueData(bos, vertexAttribCurrentValues[i]); GroupScope vagroup(json, "VertexAttribCurrentValues", i);
SerializeVertexAttribCurrentValueData(json, vertexAttribCurrentValues[i]);
} }
if (state.getVertexArray()) if (state.getVertexArray())
{ {
bos->writeInt(state.getVertexArray()->id().value); json->addScalar("VertexArrayID", state.getVertexArray()->id().value);
} }
bos->writeInt(state.getCurrentValuesTypeMask().to_ulong()); json->addScalar("CurrentValuesTypeMask", state.getCurrentValuesTypeMask().to_ulong());
bos->writeInt(state.getActiveSampler()); json->addScalar("ActiveSampler", state.getActiveSampler());
for (const auto &textures : state.getBoundTexturesForCapture()) for (const auto &textures : state.getBoundTexturesForCapture())
{ {
SerializeBindingPointerVector<gl::Texture>(bos, textures); SerializeBindingPointerVector<gl::Texture>(json, textures);
} }
bos->writeInt(state.getTexturesIncompatibleWithSamplers().to_ulong()); json->addScalar("texturesIncompatibleWithSamplers",
SerializeBindingPointerVector<gl::Sampler>(bos, state.getSamplers()); state.getTexturesIncompatibleWithSamplers().to_ulong());
SerializeBindingPointerVector<gl::Sampler>(json, state.getSamplers());
for (const gl::ImageUnit &imageUnit : state.getImageUnits()) for (const gl::ImageUnit &imageUnit : state.getImageUnits())
{ {
SerializeImageUnit(bos, imageUnit); SerializeImageUnit(json, imageUnit);
} }
for (const auto &query : state.getActiveQueriesForCapture()) for (const auto &query : state.getActiveQueriesForCapture())
{ {
bos->writeInt(query.id().value); json->addScalar("Query", query.id().value);
} }
for (const auto &boundBuffer : state.getBoundBuffersForCapture()) for (const auto &boundBuffer : state.getBoundBuffersForCapture())
{ {
bos->writeInt(boundBuffer.id().value); json->addScalar("Bound", boundBuffer.id().value);
} }
SerializeOffsetBindingPointerVector<gl::Buffer>(bos, SerializeOffsetBindingPointerVector<gl::Buffer>(json,
state.getOffsetBindingPointerUniformBuffers()); state.getOffsetBindingPointerUniformBuffers());
SerializeOffsetBindingPointerVector<gl::Buffer>( SerializeOffsetBindingPointerVector<gl::Buffer>(
bos, state.getOffsetBindingPointerAtomicCounterBuffers()); json, state.getOffsetBindingPointerAtomicCounterBuffers());
SerializeOffsetBindingPointerVector<gl::Buffer>( SerializeOffsetBindingPointerVector<gl::Buffer>(
bos, state.getOffsetBindingPointerShaderStorageBuffers()); json, state.getOffsetBindingPointerShaderStorageBuffers());
if (state.getCurrentTransformFeedback()) if (state.getCurrentTransformFeedback())
{ {
bos->writeInt(state.getCurrentTransformFeedback()->id().value); json->addScalar("CurrentTransformFeedback",
} state.getCurrentTransformFeedback()->id().value);
SerializePixelUnpackState(bos, state.getUnpackState()); }
SerializePixelPackState(bos, state.getPackState()); SerializePixelUnpackState(json, state.getUnpackState());
bos->writeBool(state.isPrimitiveRestartEnabled()); SerializePixelPackState(json, state.getPackState());
bos->writeBool(state.isMultisamplingEnabled()); json->addScalar("PrimitiveRestartEnabled", state.isPrimitiveRestartEnabled());
bos->writeBool(state.isSampleAlphaToOneEnabled()); json->addScalar("MultisamplingEnabled", state.isMultisamplingEnabled());
bos->writeInt(state.getCoverageModulation()); json->addScalar("SampleAlphaToOneEnabled", state.isSampleAlphaToOneEnabled());
bos->writeBool(state.getFramebufferSRGB()); json->addScalar("CoverageModulation", state.getCoverageModulation());
bos->writeBool(state.isRobustResourceInitEnabled()); json->addScalar("FramebufferSRGB", state.getFramebufferSRGB());
bos->writeBool(state.isProgramBinaryCacheEnabled()); json->addScalar("RobustResourceInitEnabled", state.isRobustResourceInitEnabled());
bos->writeBool(state.isTextureRectangleEnabled()); json->addScalar("ProgramBinaryCacheEnabled", state.isProgramBinaryCacheEnabled());
bos->writeInt(state.getMaxShaderCompilerThreads()); json->addScalar("TextureRectangleEnabled", state.isTextureRectangleEnabled());
bos->writeInt(state.getEnabledClipDistances().to_ulong()); json->addScalar("MaxShaderCompilerThreads", state.getMaxShaderCompilerThreads());
bos->writeInt(state.getBlendFuncConstantAlphaDrawBuffers().to_ulong()); json->addScalar("EnabledClipDistances", state.getEnabledClipDistances().to_ulong());
bos->writeInt(state.getBlendFuncConstantColorDrawBuffers().to_ulong()); json->addScalar("BlendFuncConstantAlphaDrawBuffers",
bos->writeBool(state.noSimultaneousConstantColorAndAlphaBlendFunc()); state.getBlendFuncConstantAlphaDrawBuffers().to_ulong());
} json->addScalar("BlendFuncConstantColorDrawBuffers",
state.getBlendFuncConstantColorDrawBuffers().to_ulong());
void SerializeBufferState(gl::BinaryOutputStream *bos, const gl::BufferState &bufferState) json->addScalar("SimultaneousConstantColorAndAlphaBlendFunc",
{ state.noSimultaneousConstantColorAndAlphaBlendFunc());
bos->writeString(bufferState.getLabel()); }
bos->writeEnum(bufferState.getUsage());
bos->writeInt(bufferState.getSize()); void SerializeBufferState(JsonSerializer *json, const gl::BufferState &bufferState)
bos->writeInt(bufferState.getAccessFlags()); {
bos->writeInt(bufferState.getAccess()); json->addScalar("Label", bufferState.getLabel());
bos->writeInt(bufferState.isMapped()); json->addCString("Usage", BufferUsageToString(bufferState.getUsage()));
bos->writeInt(bufferState.getMapOffset()); json->addScalar("Size", bufferState.getSize());
bos->writeInt(bufferState.getMapLength()); json->addScalar("AccessFlags", bufferState.getAccessFlags());
json->addScalar("Access", bufferState.getAccess());
json->addScalar("Mapped", bufferState.isMapped());
json->addScalar("MapOffset", bufferState.getMapOffset());
json->addScalar("MapLength", bufferState.getMapLength());
} }
Result SerializeBuffer(const gl::Context *context, Result SerializeBuffer(const gl::Context *context,
gl::BinaryOutputStream *bos, JsonSerializer *json,
ScratchBuffer *scratchBuffer, ScratchBuffer *scratchBuffer,
gl::Buffer *buffer) gl::Buffer *buffer)
{ {
SerializeBufferState(bos, buffer->getState()); GroupScope group(json, "Buffer");
SerializeBufferState(json, buffer->getState());
MemoryBuffer *dataPtr = nullptr; MemoryBuffer *dataPtr = nullptr;
ANGLE_CHECK_GL_ALLOC( ANGLE_CHECK_GL_ALLOC(
const_cast<gl::Context *>(context), const_cast<gl::Context *>(context),
scratchBuffer->getInitialized(static_cast<size_t>(buffer->getSize()), &dataPtr, 0)); scratchBuffer->getInitialized(static_cast<size_t>(buffer->getSize()), &dataPtr, 0));
ANGLE_TRY(buffer->getSubData(context, 0, dataPtr->size(), dataPtr->data())); ANGLE_TRY(buffer->getSubData(context, 0, dataPtr->size(), dataPtr->data()));
bos->writeBytes(dataPtr->data(), dataPtr->size()); json->addBlob("data", dataPtr->data(), dataPtr->size());
return Result::Continue; return Result::Continue;
} }
void SerializeColorGeneric(gl::BinaryOutputStream *bos, const ColorGeneric &colorGeneric) void SerializeColorGeneric(JsonSerializer *json,
const std::string &name,
const ColorGeneric &colorGeneric)
{ {
GroupScope group(json, name);
ASSERT(colorGeneric.type == ColorGeneric::Type::Float || ASSERT(colorGeneric.type == ColorGeneric::Type::Float ||
colorGeneric.type == ColorGeneric::Type::Int || colorGeneric.type == ColorGeneric::Type::Int ||
colorGeneric.type == ColorGeneric::Type::UInt); colorGeneric.type == ColorGeneric::Type::UInt);
bos->writeEnum(colorGeneric.type); json->addCString("Type", ColorGenericTypeToString(colorGeneric.type));
if (colorGeneric.type == ColorGeneric::Type::Float) if (colorGeneric.type == ColorGeneric::Type::Float)
{ {
SerializeColorF(bos, colorGeneric.colorF); SerializeColorF(json, colorGeneric.colorF);
} }
else if (colorGeneric.type == ColorGeneric::Type::Int) else if (colorGeneric.type == ColorGeneric::Type::Int)
{ {
SerializeColorI(bos, colorGeneric.colorI); SerializeColorI(json, colorGeneric.colorI);
} }
else else
{ {
SerializeColorUI(bos, colorGeneric.colorUI); SerializeColorUI(json, colorGeneric.colorUI);
} }
} }
void SerializeSamplerState(gl::BinaryOutputStream *bos, const gl::SamplerState &samplerState) void SerializeSamplerState(JsonSerializer *json,
const std::string &name,
const gl::SamplerState &samplerState)
{ {
bos->writeInt(samplerState.getMinFilter()); GroupScope group(json, name);
bos->writeInt(samplerState.getMagFilter()); json->addScalar("MinFilter", samplerState.getMinFilter());
bos->writeInt(samplerState.getWrapS()); json->addScalar("MagFilter", samplerState.getMagFilter());
bos->writeInt(samplerState.getWrapT()); json->addScalar("WrapS", samplerState.getWrapS());
bos->writeInt(samplerState.getWrapR()); json->addScalar("WrapT", samplerState.getWrapT());
bos->writeFloat(samplerState.getMaxAnisotropy()); json->addScalar("WrapR", samplerState.getWrapR());
bos->writeFloat(samplerState.getMinLod()); json->addScalar("MaxAnisotropy", samplerState.getMaxAnisotropy());
bos->writeFloat(samplerState.getMaxLod()); json->addScalar("MinLod", samplerState.getMinLod());
bos->writeInt(samplerState.getCompareMode()); json->addScalar("MaxLod", samplerState.getMaxLod());
bos->writeInt(samplerState.getCompareFunc()); json->addScalar("CompareMode", samplerState.getCompareMode());
bos->writeInt(samplerState.getSRGBDecode()); json->addScalar("CompareFunc", samplerState.getCompareFunc());
SerializeColorGeneric(bos, samplerState.getBorderColor()); json->addScalar("SRGBDecode", samplerState.getSRGBDecode());
SerializeColorGeneric(json, "BorderColor", samplerState.getBorderColor());
} }
void SerializeSampler(gl::BinaryOutputStream *bos, gl::Sampler *sampler) void SerializeSampler(JsonSerializer *json, gl::Sampler *sampler)
{ {
bos->writeString(sampler->getLabel()); json->addScalar("Label", sampler->getLabel());
SerializeSamplerState(bos, sampler->getSamplerState()); SerializeSamplerState(json, "Sampler", sampler->getSamplerState());
} }
void SerializeSwizzleState(gl::BinaryOutputStream *bos, const gl::SwizzleState &swizzleState) void SerializeSwizzleState(JsonSerializer *json, const gl::SwizzleState &swizzleState)
{ {
bos->writeInt(swizzleState.swizzleRed); json->addScalar("SwizzleRed", swizzleState.swizzleRed);
bos->writeInt(swizzleState.swizzleGreen); json->addScalar("SwizzleGreen", swizzleState.swizzleGreen);
bos->writeInt(swizzleState.swizzleBlue); json->addScalar("SwizzleBlue", swizzleState.swizzleBlue);
bos->writeInt(swizzleState.swizzleAlpha); json->addScalar("SwizzleAlpha", swizzleState.swizzleAlpha);
} }
void SerializeExtents(gl::BinaryOutputStream *bos, const gl::Extents &extents) void SerializeExtents(JsonSerializer *json, const gl::Extents &extents)
{ {
bos->writeInt(extents.width); json->addScalar("Width", extents.width);
bos->writeInt(extents.height); json->addScalar("Height", extents.height);
bos->writeInt(extents.depth); json->addScalar("Depth", extents.depth);
} }
void SerializeInternalFormat(gl::BinaryOutputStream *bos, const gl::InternalFormat *internalFormat) void SerializeInternalFormat(JsonSerializer *json, const gl::InternalFormat *internalFormat)
{ {
bos->writeInt(internalFormat->internalFormat); json->addScalar("InternalFormat", internalFormat->internalFormat);
} }
void SerializeFormat(gl::BinaryOutputStream *bos, const gl::Format &format) void SerializeFormat(JsonSerializer *json, const gl::Format &format)
{ {
SerializeInternalFormat(bos, format.info); SerializeInternalFormat(json, format.info);
} }
void SerializeRenderbufferState(gl::BinaryOutputStream *bos, void SerializeRenderbufferState(JsonSerializer *json,
const gl::RenderbufferState &renderbufferState) const gl::RenderbufferState &renderbufferState)
{ {
bos->writeInt(renderbufferState.getWidth()); GroupScope wg(json, "State");
bos->writeInt(renderbufferState.getHeight()); json->addScalar("Width", renderbufferState.getWidth());
SerializeFormat(bos, renderbufferState.getFormat()); json->addScalar("Height", renderbufferState.getHeight());
bos->writeInt(renderbufferState.getSamples()); SerializeFormat(json, renderbufferState.getFormat());
bos->writeEnum(renderbufferState.getInitState()); json->addScalar("Samples", renderbufferState.getSamples());
json->addCString("InitState", InitStateToString(renderbufferState.getInitState()));
} }
Result SerializeRenderbuffer(const gl::Context *context, Result SerializeRenderbuffer(const gl::Context *context,
gl::BinaryOutputStream *bos, JsonSerializer *json,
ScratchBuffer *scratchBuffer, ScratchBuffer *scratchBuffer,
gl::Renderbuffer *renderbuffer) gl::Renderbuffer *renderbuffer)
{ {
SerializeRenderbufferState(bos, renderbuffer->getState()); GroupScope wg(json, "Renderbuffer");
bos->writeString(renderbuffer->getLabel()); SerializeRenderbufferState(json, renderbuffer->getState());
json->addScalar("Label", renderbuffer->getLabel());
MemoryBuffer *pixelsPtr = nullptr; MemoryBuffer *pixelsPtr = nullptr;
ANGLE_CHECK_GL_ALLOC( ANGLE_CHECK_GL_ALLOC(
const_cast<gl::Context *>(context), const_cast<gl::Context *>(context),
...@@ -587,274 +839,297 @@ Result SerializeRenderbuffer(const gl::Context *context, ...@@ -587,274 +839,297 @@ Result SerializeRenderbuffer(const gl::Context *context,
ANGLE_TRY(renderbuffer->getImplementation()->getRenderbufferImage( ANGLE_TRY(renderbuffer->getImplementation()->getRenderbufferImage(
context, packState, nullptr, renderbuffer->getImplementationColorReadFormat(context), context, packState, nullptr, renderbuffer->getImplementationColorReadFormat(context),
renderbuffer->getImplementationColorReadType(context), pixelsPtr->data())); renderbuffer->getImplementationColorReadType(context), pixelsPtr->data()));
bos->writeBytes(pixelsPtr->data(), pixelsPtr->size()); json->addBlob("pixel", pixelsPtr->data(), pixelsPtr->size());
return Result::Continue; return Result::Continue;
} }
void SerializeWorkGroupSize(gl::BinaryOutputStream *bos, const sh::WorkGroupSize &workGroupSize) void SerializeWorkGroupSize(JsonSerializer *json, const sh::WorkGroupSize &workGroupSize)
{ {
bos->writeInt(workGroupSize[0]); GroupScope wg(json, "workGroupSize");
bos->writeInt(workGroupSize[1]); json->addScalar("x", workGroupSize[0]);
bos->writeInt(workGroupSize[2]); json->addScalar("y", workGroupSize[1]);
json->addScalar("z", workGroupSize[2]);
} }
void SerializeShaderVariable(gl::BinaryOutputStream *bos, const sh::ShaderVariable &shaderVariable) void SerializeShaderVariable(JsonSerializer *json, const sh::ShaderVariable &shaderVariable)
{ {
bos->writeInt(shaderVariable.type); GroupScope wg(json, "ShaderVariable");
bos->writeInt(shaderVariable.precision); json->addScalar("Type", shaderVariable.type);
bos->writeString(shaderVariable.name); json->addScalar("Precision", shaderVariable.precision);
bos->writeString(shaderVariable.mappedName); json->addScalar("Name", shaderVariable.name);
bos->writeIntVector(shaderVariable.arraySizes); json->addScalar("MappedName", shaderVariable.mappedName);
bos->writeBool(shaderVariable.staticUse); json->addVector("ArraySizes", shaderVariable.arraySizes);
bos->writeBool(shaderVariable.active); json->addScalar("StaticUse", shaderVariable.staticUse);
json->addScalar("Active", shaderVariable.active);
for (const sh::ShaderVariable &field : shaderVariable.fields) for (const sh::ShaderVariable &field : shaderVariable.fields)
{ {
SerializeShaderVariable(bos, field); SerializeShaderVariable(json, field);
} }
bos->writeString(shaderVariable.structOrBlockName); json->addScalar("StructOrBlockName", shaderVariable.structOrBlockName);
bos->writeString(shaderVariable.mappedStructOrBlockName); json->addScalar("MappedStructOrBlockName", shaderVariable.mappedStructOrBlockName);
bos->writeBool(shaderVariable.isRowMajorLayout); json->addScalar("RowMajorLayout", shaderVariable.isRowMajorLayout);
bos->writeInt(shaderVariable.location); json->addScalar("Location", shaderVariable.location);
bos->writeInt(shaderVariable.binding); json->addScalar("Binding", shaderVariable.binding);
bos->writeInt(shaderVariable.imageUnitFormat); json->addScalar("ImageUnitFormat", shaderVariable.imageUnitFormat);
bos->writeInt(shaderVariable.offset); json->addScalar("Offset", shaderVariable.offset);
bos->writeBool(shaderVariable.readonly); json->addScalar("Readonly", shaderVariable.readonly);
bos->writeBool(shaderVariable.writeonly); json->addScalar("Writeonly", shaderVariable.writeonly);
bos->writeInt(shaderVariable.index); json->addScalar("Index", shaderVariable.index);
bos->writeBool(shaderVariable.yuv); json->addScalar("YUV", shaderVariable.yuv);
bos->writeEnum(shaderVariable.interpolation); json->addCString("Interpolation", InterpolationTypeToString(shaderVariable.interpolation));
bos->writeBool(shaderVariable.isInvariant); json->addScalar("Invariant", shaderVariable.isInvariant);
bos->writeBool(shaderVariable.texelFetchStaticUse); json->addScalar("TexelFetchStaticUse", shaderVariable.texelFetchStaticUse);
} }
void SerializeShaderVariablesVector(gl::BinaryOutputStream *bos, void SerializeShaderVariablesVector(JsonSerializer *json,
const std::vector<sh::ShaderVariable> &shaderVariables) const std::vector<sh::ShaderVariable> &shaderVariables)
{ {
for (const sh::ShaderVariable &shaderVariable : shaderVariables) for (const sh::ShaderVariable &shaderVariable : shaderVariables)
{ {
SerializeShaderVariable(bos, shaderVariable); SerializeShaderVariable(json, shaderVariable);
} }
} }
void SerializeInterfaceBlocksVector(gl::BinaryOutputStream *bos, void SerializeInterfaceBlocksVector(JsonSerializer *json,
const std::vector<sh::InterfaceBlock> &interfaceBlocks) const std::vector<sh::InterfaceBlock> &interfaceBlocks)
{ {
for (const sh::InterfaceBlock &interfaceBlock : interfaceBlocks) for (const sh::InterfaceBlock &interfaceBlock : interfaceBlocks)
{ {
bos->writeString(interfaceBlock.name); GroupScope group(json, "Interface Block");
bos->writeString(interfaceBlock.mappedName); json->addScalar("Name", interfaceBlock.name);
bos->writeString(interfaceBlock.instanceName); json->addScalar("MappedName", interfaceBlock.mappedName);
bos->writeInt(interfaceBlock.arraySize); json->addScalar("InstanceName", interfaceBlock.instanceName);
bos->writeEnum(interfaceBlock.layout); json->addScalar("ArraySize", interfaceBlock.arraySize);
bos->writeInt(interfaceBlock.binding); json->addCString("Layout", BlockLayoutTypeToString(interfaceBlock.layout));
bos->writeBool(interfaceBlock.staticUse); json->addScalar("Binding", interfaceBlock.binding);
bos->writeBool(interfaceBlock.active); json->addScalar("StaticUse", interfaceBlock.staticUse);
bos->writeEnum(interfaceBlock.blockType); json->addScalar("Active", interfaceBlock.active);
SerializeShaderVariablesVector(bos, interfaceBlock.fields); json->addCString("BlockType", BlockTypeToString(interfaceBlock.blockType));
} SerializeShaderVariablesVector(json, interfaceBlock.fields);
} }
}
void SerializeShaderState(gl::BinaryOutputStream *bos, const gl::ShaderState &shaderState)
{ void SerializeShaderState(JsonSerializer *json, const gl::ShaderState &shaderState)
bos->writeString(shaderState.getLabel()); {
bos->writeEnum(shaderState.getShaderType()); GroupScope group(json, "ShaderState");
bos->writeInt(shaderState.getShaderVersion()); json->addScalar("Label", shaderState.getLabel());
bos->writeString(shaderState.getTranslatedSource()); json->addCString("Type", gl::ShaderTypeToString(shaderState.getShaderType()));
bos->writeIntVector(shaderState.getCompiledBinary()); json->addScalar("Version", shaderState.getShaderVersion());
bos->writeString(shaderState.getSource()); json->addScalar("TranslatedSource", shaderState.getTranslatedSource());
SerializeWorkGroupSize(bos, shaderState.getLocalSize()); json->addVector("CompiledBinary", shaderState.getCompiledBinary());
SerializeShaderVariablesVector(bos, shaderState.getInputVaryings()); json->addScalar("Source", shaderState.getSource());
SerializeShaderVariablesVector(bos, shaderState.getOutputVaryings()); SerializeWorkGroupSize(json, shaderState.getLocalSize());
SerializeShaderVariablesVector(bos, shaderState.getUniforms()); SerializeShaderVariablesVector(json, shaderState.getInputVaryings());
SerializeInterfaceBlocksVector(bos, shaderState.getUniformBlocks()); SerializeShaderVariablesVector(json, shaderState.getOutputVaryings());
SerializeInterfaceBlocksVector(bos, shaderState.getShaderStorageBlocks()); SerializeShaderVariablesVector(json, shaderState.getUniforms());
SerializeShaderVariablesVector(bos, shaderState.getAllAttributes()); SerializeInterfaceBlocksVector(json, shaderState.getUniformBlocks());
SerializeShaderVariablesVector(bos, shaderState.getActiveAttributes()); SerializeInterfaceBlocksVector(json, shaderState.getShaderStorageBlocks());
SerializeShaderVariablesVector(bos, shaderState.getActiveOutputVariables()); SerializeShaderVariablesVector(json, shaderState.getAllAttributes());
bos->writeBool(shaderState.getEarlyFragmentTestsOptimization()); SerializeShaderVariablesVector(json, shaderState.getActiveAttributes());
bos->writeInt(shaderState.getNumViews()); SerializeShaderVariablesVector(json, shaderState.getActiveOutputVariables());
bos->writeInt(shaderState.getSpecConstUsageBits().bits()); json->addScalar("EarlyFragmentTestsOptimization",
shaderState.getEarlyFragmentTestsOptimization());
json->addScalar("NumViews", shaderState.getNumViews());
json->addScalar("SpecConstUsageBits", shaderState.getSpecConstUsageBits().bits());
if (shaderState.getGeometryShaderInputPrimitiveType().valid()) if (shaderState.getGeometryShaderInputPrimitiveType().valid())
{ {
bos->writeEnum(shaderState.getGeometryShaderInputPrimitiveType().value()); json->addCString(
"GeometryShaderInputPrimitiveType",
PrimitiveModeToString(shaderState.getGeometryShaderInputPrimitiveType().value()));
} }
if (shaderState.getGeometryShaderOutputPrimitiveType().valid()) if (shaderState.getGeometryShaderOutputPrimitiveType().valid())
{ {
bos->writeEnum(shaderState.getGeometryShaderOutputPrimitiveType().value()); json->addCString(
"GeometryShaderOutputPrimitiveType",
PrimitiveModeToString(shaderState.getGeometryShaderOutputPrimitiveType().value()));
} }
if (shaderState.getGeometryShaderInvocations().valid()) if (shaderState.getGeometryShaderInvocations().valid())
{ {
bos->writeInt(shaderState.getGeometryShaderInvocations().value()); json->addScalar("GeometryShaderInvocations",
shaderState.getGeometryShaderInvocations().value());
} }
bos->writeEnum(shaderState.getCompileStatus()); json->addCString("CompileStatus", CompileStatusToString(shaderState.getCompileStatus()));
} }
void SerializeShader(gl::BinaryOutputStream *bos, gl::Shader *shader) void SerializeShader(JsonSerializer *json, gl::Shader *shader)
{ {
SerializeShaderState(bos, shader->getState()); GroupScope group(json, "Shader");
bos->writeInt(shader->getHandle().value); SerializeShaderState(json, shader->getState());
bos->writeInt(shader->getRefCount()); json->addScalar("Handle", shader->getHandle().value);
bos->writeBool(shader->isFlaggedForDeletion()); json->addScalar("RefCount", shader->getRefCount());
json->addScalar("FlaggedForDeletion", shader->isFlaggedForDeletion());
// Do not serialize mType because it is already serialized in SerializeShaderState. // Do not serialize mType because it is already serialized in SerializeShaderState.
bos->writeString(shader->getInfoLogString()); json->addScalar("InfoLogString", shader->getInfoLogString());
// Do not serialize compiler resources string because it can vary between test modes. // Do not serialize compiler resources string because it can vary between test modes.
bos->writeInt(shader->getCurrentMaxComputeWorkGroupInvocations()); json->addScalar("CurrentMaxComputeWorkGroupInvocations",
bos->writeInt(shader->getMaxComputeSharedMemory()); shader->getCurrentMaxComputeWorkGroupInvocations());
json->addScalar("MaxComputeSharedMemory", shader->getMaxComputeSharedMemory());
} }
void SerializeVariableLocationsVector(gl::BinaryOutputStream *bos, void SerializeVariableLocationsVector(JsonSerializer *json,
const std::string &group_name,
const std::vector<gl::VariableLocation> &variableLocations) const std::vector<gl::VariableLocation> &variableLocations)
{ {
GroupScope group(json, group_name);
for (const gl::VariableLocation &variableLocation : variableLocations) for (const gl::VariableLocation &variableLocation : variableLocations)
{ {
bos->writeInt(variableLocation.arrayIndex); GroupScope vargroup(json, "Variable");
bos->writeInt(variableLocation.index); json->addScalar("ArrayIndex", variableLocation.arrayIndex);
bos->writeBool(variableLocation.ignored); json->addScalar("Index", variableLocation.index);
json->addScalar("Ignored", variableLocation.ignored);
} }
} }
void SerializeBlockMemberInfo(gl::BinaryOutputStream *bos, void SerializeBlockMemberInfo(JsonSerializer *json, const sh::BlockMemberInfo &blockMemberInfo)
const sh::BlockMemberInfo &blockMemberInfo)
{ {
bos->writeInt(blockMemberInfo.offset); GroupScope(json, "BlockMemberInfo");
bos->writeInt(blockMemberInfo.arrayStride); json->addScalar("Offset", blockMemberInfo.offset);
bos->writeInt(blockMemberInfo.matrixStride); json->addScalar("Stride", blockMemberInfo.arrayStride);
bos->writeBool(blockMemberInfo.isRowMajorMatrix); json->addScalar("MatrixStride", blockMemberInfo.matrixStride);
bos->writeInt(blockMemberInfo.topLevelArrayStride); json->addScalar("IsRowMajorMatrix", blockMemberInfo.isRowMajorMatrix);
json->addScalar("TopLevelArrayStride", blockMemberInfo.topLevelArrayStride);
} }
void SerializeActiveVariable(gl::BinaryOutputStream *bos, const gl::ActiveVariable &activeVariable) void SerializeActiveVariable(JsonSerializer *json, const gl::ActiveVariable &activeVariable)
{ {
bos->writeInt(activeVariable.activeShaders().to_ulong()); json->addScalar("ActiveShaders", activeVariable.activeShaders().to_ulong());
} }
void SerializeBufferVariablesVector(gl::BinaryOutputStream *bos, void SerializeBufferVariablesVector(JsonSerializer *json,
const std::vector<gl::BufferVariable> &bufferVariables) const std::vector<gl::BufferVariable> &bufferVariables)
{ {
for (const gl::BufferVariable &bufferVariable : bufferVariables) for (const gl::BufferVariable &bufferVariable : bufferVariables)
{ {
bos->writeInt(bufferVariable.bufferIndex); GroupScope group(json, "BufferVariable");
SerializeBlockMemberInfo(bos, bufferVariable.blockInfo); json->addScalar("BufferIndex", bufferVariable.bufferIndex);
bos->writeInt(bufferVariable.topLevelArraySize); SerializeBlockMemberInfo(json, bufferVariable.blockInfo);
SerializeActiveVariable(bos, bufferVariable); json->addScalar("TopLevelArraySize", bufferVariable.topLevelArraySize);
SerializeShaderVariable(bos, bufferVariable); SerializeActiveVariable(json, bufferVariable);
SerializeShaderVariable(json, bufferVariable);
} }
} }
void SerializeProgramAliasedBindings(gl::BinaryOutputStream *bos, void SerializeProgramAliasedBindings(JsonSerializer *json,
const gl::ProgramAliasedBindings &programAliasedBindings) const gl::ProgramAliasedBindings &programAliasedBindings)
{ {
for (const auto &programAliasedBinding : programAliasedBindings) for (const auto &programAliasedBinding : programAliasedBindings)
{ {
bos->writeString(programAliasedBinding.first); GroupScope group(json, programAliasedBinding.first);
bos->writeInt(programAliasedBinding.second.location); json->addScalar("Location", programAliasedBinding.second.location);
bos->writeBool(programAliasedBinding.second.aliased); json->addScalar("Aliased", programAliasedBinding.second.aliased);
} }
} }
void SerializeProgramState(gl::BinaryOutputStream *bos, const gl::ProgramState &programState) void SerializeProgramState(JsonSerializer *json, const gl::ProgramState &programState)
{ {
bos->writeString(programState.getLabel()); json->addScalar("Label", programState.getLabel());
SerializeWorkGroupSize(bos, programState.getComputeShaderLocalSize()); SerializeWorkGroupSize(json, programState.getComputeShaderLocalSize());
for (gl::Shader *shader : programState.getAttachedShaders()) for (gl::Shader *shader : programState.getAttachedShaders())
{ {
if (shader) if (shader)
{ {
bos->writeInt(shader->getHandle().value); json->addScalar("Handle", shader->getHandle().value);
} }
else else
{ {
bos->writeInt(0); json->addScalar("Handle", 0);
} }
} }
for (bool isAttached : programState.getAttachedShadersMarkedForDetach()) const gl::ShaderMap<bool> &sm = programState.getAttachedShadersMarkedForDetach();
for (gl::ShaderType shaderType : gl::AllShaderTypes())
{ {
bos->writeBool(isAttached); if (sm[shaderType])
{
json->addCString(gl::ShaderTypeToString(shaderType), "Attached");
}
} }
bos->writeInt(programState.getLocationsUsedForXfbExtension()); json->addScalar("LocationsUsedForXfbExtension", programState.getLocationsUsedForXfbExtension());
for (const std::string &transformFeedbackVaryingName : for (const std::string &transformFeedbackVaryingName :
programState.getTransformFeedbackVaryingNames()) programState.getTransformFeedbackVaryingNames())
{ {
bos->writeString(transformFeedbackVaryingName); json->addScalar("TransformFeedbackVaryingName", transformFeedbackVaryingName);
} }
bos->writeInt(programState.getActiveUniformBlockBindingsMask().to_ulong()); json->addScalar("ActiveUniformBlockBindingsMask",
SerializeVariableLocationsVector(bos, programState.getUniformLocations()); programState.getActiveUniformBlockBindingsMask().to_ulong());
SerializeBufferVariablesVector(bos, programState.getBufferVariables()); SerializeVariableLocationsVector(json, "UniformLocations", programState.getUniformLocations());
SerializeRange(bos, programState.getAtomicCounterUniformRange()); SerializeBufferVariablesVector(json, programState.getBufferVariables());
SerializeVariableLocationsVector(bos, programState.getSecondaryOutputLocations()); SerializeRange(json, programState.getAtomicCounterUniformRange());
bos->writeInt(programState.getActiveOutputVariables().to_ulong()); SerializeVariableLocationsVector(json, "SecondaryOutputLocations",
programState.getSecondaryOutputLocations());
json->addScalar("ActiveOutputVariables", programState.getActiveOutputVariables().to_ulong());
for (GLenum outputVariableType : programState.getOutputVariableTypes()) for (GLenum outputVariableType : programState.getOutputVariableTypes())
{ {
bos->writeInt(outputVariableType); json->addScalar("OutputVariableType", outputVariableType);
} }
bos->writeInt(programState.getDrawBufferTypeMask().to_ulong()); json->addScalar("DrawBufferTypeMask", programState.getDrawBufferTypeMask().to_ulong());
bos->writeBool(programState.hasBinaryRetrieveableHint()); json->addScalar("BinaryRetrieveableHint", programState.hasBinaryRetrieveableHint());
bos->writeBool(programState.isSeparable()); json->addScalar("Separable", programState.isSeparable());
bos->writeBool(programState.hasEarlyFragmentTestsOptimization()); json->addScalar("EarlyFragmentTestsOptimization",
bos->writeInt(programState.getNumViews()); programState.hasEarlyFragmentTestsOptimization());
bos->writeInt(programState.getDrawIDLocation()); json->addScalar("NumViews", programState.getNumViews());
bos->writeInt(programState.getBaseVertexLocation()); json->addScalar("DrawIDLocation", programState.getDrawIDLocation());
bos->writeInt(programState.getBaseInstanceLocation()); json->addScalar("BaseVertexLocation", programState.getBaseVertexLocation());
SerializeProgramAliasedBindings(bos, programState.getUniformLocationBindings()); json->addScalar("BaseInstanceLocation", programState.getBaseInstanceLocation());
SerializeProgramAliasedBindings(json, programState.getUniformLocationBindings());
} }
void SerializeProgramBindings(gl::BinaryOutputStream *bos, void SerializeProgramBindings(JsonSerializer *json, const gl::ProgramBindings &programBindings)
const gl::ProgramBindings &programBindings)
{ {
for (const auto &programBinding : programBindings) for (const auto &programBinding : programBindings)
{ {
bos->writeString(programBinding.first); json->addScalar(programBinding.first, programBinding.second);
bos->writeInt(programBinding.second);
} }
} }
void SerializeProgram(gl::BinaryOutputStream *bos, gl::Program *program) void SerializeProgram(JsonSerializer *json, gl::Program *program)
{ {
SerializeProgramState(bos, program->getState()); GroupScope group(json, "Program");
bos->writeBool(program->isValidated()); SerializeProgramState(json, program->getState());
SerializeProgramBindings(bos, program->getAttributeBindings()); json->addScalar("IsValidated", program->isValidated());
SerializeProgramAliasedBindings(bos, program->getFragmentOutputLocations()); SerializeProgramBindings(json, program->getAttributeBindings());
SerializeProgramAliasedBindings(bos, program->getFragmentOutputIndexes()); SerializeProgramAliasedBindings(json, program->getFragmentOutputLocations());
bos->writeBool(program->isLinked()); SerializeProgramAliasedBindings(json, program->getFragmentOutputIndexes());
bos->writeBool(program->isFlaggedForDeletion()); json->addScalar("IsLinked", program->isLinked());
bos->writeInt(program->getRefCount()); json->addScalar("IsFlaggedForDeletion", program->isFlaggedForDeletion());
bos->writeInt(program->id().value); json->addScalar("RefCount", program->getRefCount());
json->addScalar("ID", program->id().value);
} }
void SerializeImageDesc(gl::BinaryOutputStream *bos, const gl::ImageDesc &imageDesc) void SerializeImageDesc(JsonSerializer *json, const gl::ImageDesc &imageDesc)
{ {
SerializeExtents(bos, imageDesc.size); GroupScope group(json, "ImageDesc");
SerializeFormat(bos, imageDesc.format); SerializeExtents(json, imageDesc.size);
bos->writeInt(imageDesc.samples); SerializeFormat(json, imageDesc.format);
bos->writeBool(imageDesc.fixedSampleLocations); json->addScalar("Samples", imageDesc.samples);
bos->writeEnum(imageDesc.initState); json->addScalar("FixesSampleLocations", imageDesc.fixedSampleLocations);
json->addCString("InitState", InitStateToString(imageDesc.initState));
} }
void SerializeTextureState(gl::BinaryOutputStream *bos, const gl::TextureState &textureState) void SerializeTextureState(JsonSerializer *json, const gl::TextureState &textureState)
{ {
bos->writeEnum(textureState.getType()); json->addCString("Type", TextureTypeToString(textureState.getType()));
SerializeSwizzleState(bos, textureState.getSwizzleState()); SerializeSwizzleState(json, textureState.getSwizzleState());
SerializeSamplerState(bos, textureState.getSamplerState()); SerializeSamplerState(json, "TextureState", textureState.getSamplerState());
bos->writeEnum(textureState.getSRGBOverride()); json->addCString("SRGB", SrgbOverrideToString(textureState.getSRGBOverride()));
bos->writeInt(textureState.getBaseLevel()); json->addScalar("BaseLevel", textureState.getBaseLevel());
bos->writeInt(textureState.getMaxLevel()); json->addScalar("MaxLevel", textureState.getMaxLevel());
bos->writeInt(textureState.getDepthStencilTextureMode()); json->addScalar("DepthStencilTextureMode", textureState.getDepthStencilTextureMode());
bos->writeBool(textureState.hasBeenBoundAsImage()); json->addScalar("BeenBoundAsImage", textureState.hasBeenBoundAsImage());
bos->writeBool(textureState.getImmutableFormat()); json->addScalar("ImmutableFormat", textureState.getImmutableFormat());
bos->writeInt(textureState.getImmutableLevels()); json->addScalar("ImmutableLevels", textureState.getImmutableLevels());
bos->writeInt(textureState.getUsage()); json->addScalar("Usage", textureState.getUsage());
const std::vector<gl::ImageDesc> &imageDescs = textureState.getImageDescs(); const std::vector<gl::ImageDesc> &imageDescs = textureState.getImageDescs();
for (const gl::ImageDesc &imageDesc : imageDescs) for (const gl::ImageDesc &imageDesc : imageDescs)
{ {
SerializeImageDesc(bos, imageDesc); SerializeImageDesc(json, imageDesc);
} }
SerializeRectangle(bos, textureState.getCrop()); SerializeRectangle(json, "Crop", textureState.getCrop());
bos->writeInt(textureState.getGenerateMipmapHint()); json->addScalar("GenerateMipmapHint", textureState.getGenerateMipmapHint());
bos->writeEnum(textureState.getInitState()); json->addCString("InitState", InitStateToString(textureState.getInitState()));
} }
Result SerializeTextureData(gl::BinaryOutputStream *bos, Result SerializeTextureData(JsonSerializer *json,
const gl::Context *context, const gl::Context *context,
gl::Texture *texture, gl::Texture *texture,
ScratchBuffer *scratchBuffer) ScratchBuffer *scratchBuffer)
...@@ -897,114 +1172,123 @@ Result SerializeTextureData(gl::BinaryOutputStream *bos, ...@@ -897,114 +1172,123 @@ Result SerializeTextureData(gl::BinaryOutputStream *bos,
ANGLE_TRY(texture->getTexImage(context, packState, nullptr, index.getTarget(), ANGLE_TRY(texture->getTexImage(context, packState, nullptr, index.getTarget(),
index.getLevelIndex(), getFormat, getType, index.getLevelIndex(), getFormat, getType,
texelsPtr->data())); texelsPtr->data()));
bos->writeBytes(texelsPtr->data(), texelsPtr->size()); json->addBlob("Texels", texelsPtr->data(), texelsPtr->size());
} }
return Result::Continue; return Result::Continue;
} }
Result SerializeTexture(const gl::Context *context, Result SerializeTexture(const gl::Context *context,
gl::BinaryOutputStream *bos, JsonSerializer *json,
ScratchBuffer *scratchBuffer, ScratchBuffer *scratchBuffer,
gl::Texture *texture) gl::Texture *texture)
{ {
SerializeTextureState(bos, texture->getState()); GroupScope group(json, "Texture ", texture->getId());
bos->writeString(texture->getLabel()); SerializeTextureState(json, texture->getState());
json->addScalar("Label", texture->getLabel());
// FrameCapture can not serialize mBoundSurface and mBoundStream // FrameCapture can not serialize mBoundSurface and mBoundStream
// because they are likely to change with each run // because they are likely to change with each run
ANGLE_TRY(SerializeTextureData(bos, context, texture, scratchBuffer)); ANGLE_TRY(SerializeTextureData(json, context, texture, scratchBuffer));
return Result::Continue; return Result::Continue;
} }
void SerializeFormat(gl::BinaryOutputStream *bos, const angle::Format *format) void SerializeFormat(JsonSerializer *json, const angle::Format *format)
{ {
bos->writeInt(format->glInternalFormat); json->addScalar("InternalFormat", format->glInternalFormat);
} }
void SerializeVertexAttributeVector(gl::BinaryOutputStream *bos, void SerializeVertexAttributeVector(JsonSerializer *json,
const std::vector<gl::VertexAttribute> &vertexAttributes) const std::vector<gl::VertexAttribute> &vertexAttributes)
{ {
for (const gl::VertexAttribute &vertexAttribute : vertexAttributes) for (const gl::VertexAttribute &vertexAttribute : vertexAttributes)
{ {
bos->writeBool(vertexAttribute.enabled); GroupScope group(json, "VertexAttribute@BindingIndex", vertexAttribute.bindingIndex);
json->addScalar("Enabled", vertexAttribute.enabled);
ASSERT(vertexAttribute.format); ASSERT(vertexAttribute.format);
SerializeFormat(bos, vertexAttribute.format); SerializeFormat(json, vertexAttribute.format);
bos->writeInt(vertexAttribute.relativeOffset); json->addScalar("RelativeOffset", vertexAttribute.relativeOffset);
bos->writeInt(vertexAttribute.vertexAttribArrayStride); json->addScalar("VertexAttribArrayStride", vertexAttribute.vertexAttribArrayStride);
bos->writeInt(vertexAttribute.bindingIndex);
} }
} }
void SerializeVertexBindingsVector(gl::BinaryOutputStream *bos, void SerializeVertexBindingsVector(JsonSerializer *json,
const std::vector<gl::VertexBinding> &vertexBindings) const std::vector<gl::VertexBinding> &vertexBindings)
{ {
for (const gl::VertexBinding &vertexBinding : vertexBindings) for (const gl::VertexBinding &vertexBinding : vertexBindings)
{ {
bos->writeInt(vertexBinding.getStride()); GroupScope group(json, "VertexBinding");
bos->writeInt(vertexBinding.getDivisor()); json->addScalar("Stride", vertexBinding.getStride());
bos->writeInt(vertexBinding.getOffset()); json->addScalar("Divisor", vertexBinding.getDivisor());
bos->writeInt(vertexBinding.getBuffer().id().value); json->addScalar("Offset", vertexBinding.getOffset());
bos->writeInt(vertexBinding.getBoundAttributesMask().to_ulong()); json->addScalar("BufferID", vertexBinding.getBuffer().id().value);
json->addScalar("BoundAttributesMask", vertexBinding.getBoundAttributesMask().to_ulong());
} }
} }
void SerializeVertexArrayState(gl::BinaryOutputStream *bos, void SerializeVertexArrayState(JsonSerializer *json, const gl::VertexArrayState &vertexArrayState)
const gl::VertexArrayState &vertexArrayState)
{ {
bos->writeString(vertexArrayState.getLabel()); json->addScalar("Label", vertexArrayState.getLabel());
SerializeVertexAttributeVector(bos, vertexArrayState.getVertexAttributes()); SerializeVertexAttributeVector(json, vertexArrayState.getVertexAttributes());
if (vertexArrayState.getElementArrayBuffer()) if (vertexArrayState.getElementArrayBuffer())
{ {
bos->writeInt(vertexArrayState.getElementArrayBuffer()->id().value); json->addScalar("ElementArrayBufferID",
vertexArrayState.getElementArrayBuffer()->id().value);
} }
else else
{ {
bos->writeInt(0); json->addScalar("ElementArrayBufferID", 0);
} }
SerializeVertexBindingsVector(bos, vertexArrayState.getVertexBindings()); SerializeVertexBindingsVector(json, vertexArrayState.getVertexBindings());
bos->writeInt(vertexArrayState.getEnabledAttributesMask().to_ulong()); json->addScalar("EnabledAttributesMask",
bos->writeInt(vertexArrayState.getVertexAttributesTypeMask().to_ulong()); vertexArrayState.getEnabledAttributesMask().to_ulong());
bos->writeInt(vertexArrayState.getClientMemoryAttribsMask().to_ulong()); json->addScalar("VertexAttributesTypeMask",
bos->writeInt(vertexArrayState.getNullPointerClientMemoryAttribsMask().to_ulong()); vertexArrayState.getVertexAttributesTypeMask().to_ulong());
json->addScalar("ClientMemoryAttribsMask",
vertexArrayState.getClientMemoryAttribsMask().to_ulong());
json->addScalar("NullPointerClientMemoryAttribsMask",
vertexArrayState.getNullPointerClientMemoryAttribsMask().to_ulong());
} }
void SerializeVertexArray(gl::BinaryOutputStream *bos, gl::VertexArray *vertexArray) void SerializeVertexArray(JsonSerializer *json, gl::VertexArray *vertexArray)
{ {
bos->writeInt(vertexArray->id().value); GroupScope group(json, "VertexArray", vertexArray->id().value);
SerializeVertexArrayState(bos, vertexArray->getState()); SerializeVertexArrayState(json, vertexArray->getState());
bos->writeBool(vertexArray->isBufferAccessValidationEnabled()); json->addScalar("BufferAccessValidationEnabled",
vertexArray->isBufferAccessValidationEnabled());
} }
} // namespace } // namespace
Result SerializeContext(gl::BinaryOutputStream *bos, const gl::Context *context) Result SerializeContext(JsonSerializer *json, const gl::Context *context)
{ {
SerializeGLContextStates(bos, context->getState()); json->startDocument("Context");
SerializeGLContextStates(json, context->getState());
ScratchBuffer scratchBuffer(1); ScratchBuffer scratchBuffer(1);
const gl::FramebufferManager &framebufferManager = const gl::FramebufferManager &framebufferManager =
context->getState().getFramebufferManagerForCapture(); context->getState().getFramebufferManagerForCapture();
for (const auto &framebuffer : framebufferManager) for (const auto &framebuffer : framebufferManager)
{ {
gl::Framebuffer *framebufferPtr = framebuffer.second; gl::Framebuffer *framebufferPtr = framebuffer.second;
ANGLE_TRY(SerializeFramebuffer(context, bos, &scratchBuffer, framebufferPtr)); ANGLE_TRY(SerializeFramebuffer(context, json, &scratchBuffer, framebufferPtr));
} }
const gl::BufferManager &bufferManager = context->getState().getBufferManagerForCapture(); const gl::BufferManager &bufferManager = context->getState().getBufferManagerForCapture();
for (const auto &buffer : bufferManager) for (const auto &buffer : bufferManager)
{ {
gl::Buffer *bufferPtr = buffer.second; gl::Buffer *bufferPtr = buffer.second;
ANGLE_TRY(SerializeBuffer(context, bos, &scratchBuffer, bufferPtr)); ANGLE_TRY(SerializeBuffer(context, json, &scratchBuffer, bufferPtr));
} }
const gl::SamplerManager &samplerManager = context->getState().getSamplerManagerForCapture(); const gl::SamplerManager &samplerManager = context->getState().getSamplerManagerForCapture();
for (const auto &sampler : samplerManager) for (const auto &sampler : samplerManager)
{ {
gl::Sampler *samplerPtr = sampler.second; gl::Sampler *samplerPtr = sampler.second;
SerializeSampler(bos, samplerPtr); SerializeSampler(json, samplerPtr);
} }
const gl::RenderbufferManager &renderbufferManager = const gl::RenderbufferManager &renderbufferManager =
context->getState().getRenderbufferManagerForCapture(); context->getState().getRenderbufferManagerForCapture();
for (const auto &renderbuffer : renderbufferManager) for (const auto &renderbuffer : renderbufferManager)
{ {
gl::Renderbuffer *renderbufferPtr = renderbuffer.second; gl::Renderbuffer *renderbufferPtr = renderbuffer.second;
ANGLE_TRY(SerializeRenderbuffer(context, bos, &scratchBuffer, renderbufferPtr)); ANGLE_TRY(SerializeRenderbuffer(context, json, &scratchBuffer, renderbufferPtr));
} }
const gl::ShaderProgramManager &shaderProgramManager = const gl::ShaderProgramManager &shaderProgramManager =
context->getState().getShaderProgramManagerForCapture(); context->getState().getShaderProgramManagerForCapture();
...@@ -1013,27 +1297,28 @@ Result SerializeContext(gl::BinaryOutputStream *bos, const gl::Context *context) ...@@ -1013,27 +1297,28 @@ Result SerializeContext(gl::BinaryOutputStream *bos, const gl::Context *context)
for (const auto &shader : shaderManager) for (const auto &shader : shaderManager)
{ {
gl::Shader *shaderPtr = shader.second; gl::Shader *shaderPtr = shader.second;
SerializeShader(bos, shaderPtr); SerializeShader(json, shaderPtr);
} }
const gl::ResourceMap<gl::Program, gl::ShaderProgramID> &programManager = const gl::ResourceMap<gl::Program, gl::ShaderProgramID> &programManager =
shaderProgramManager.getProgramsForCaptureAndPerf(); shaderProgramManager.getProgramsForCaptureAndPerf();
for (const auto &program : programManager) for (const auto &program : programManager)
{ {
gl::Program *programPtr = program.second; gl::Program *programPtr = program.second;
SerializeProgram(bos, programPtr); SerializeProgram(json, programPtr);
} }
const gl::TextureManager &textureManager = context->getState().getTextureManagerForCapture(); const gl::TextureManager &textureManager = context->getState().getTextureManagerForCapture();
for (const auto &texture : textureManager) for (const auto &texture : textureManager)
{ {
gl::Texture *texturePtr = texture.second; gl::Texture *texturePtr = texture.second;
ANGLE_TRY(SerializeTexture(context, bos, &scratchBuffer, texturePtr)); ANGLE_TRY(SerializeTexture(context, json, &scratchBuffer, texturePtr));
} }
const gl::VertexArrayMap &vertexArrayMap = context->getVertexArraysForCapture(); const gl::VertexArrayMap &vertexArrayMap = context->getVertexArraysForCapture();
for (auto &vertexArray : vertexArrayMap) for (auto &vertexArray : vertexArrayMap)
{ {
gl::VertexArray *vertexArrayPtr = vertexArray.second; gl::VertexArray *vertexArrayPtr = vertexArray.second;
SerializeVertexArray(bos, vertexArrayPtr); SerializeVertexArray(json, vertexArrayPtr);
} }
json->endDocument();
scratchBuffer.clear(); scratchBuffer.clear();
return Result::Continue; return Result::Continue;
......
...@@ -11,14 +11,18 @@ ...@@ -11,14 +11,18 @@
#include "libANGLE/Error.h" #include "libANGLE/Error.h"
namespace angle
{
class JsonSerializer;
} // namespace angle
namespace gl namespace gl
{ {
class BinaryOutputStream;
class Context; class Context;
} // namespace gl } // namespace gl
namespace angle namespace angle
{ {
Result SerializeContext(gl::BinaryOutputStream *bos, const gl::Context *context); Result SerializeContext(JsonSerializer *bos, const gl::Context *context);
} // namespace angle } // namespace angle
#endif // FRAME_CAPTURE_UTILS_H_ #endif // FRAME_CAPTURE_UTILS_H_
...@@ -116,7 +116,7 @@ using DecompressCallback = uint8_t *(*)(const std::vector<uint8_t> &); ...@@ -116,7 +116,7 @@ using DecompressCallback = uint8_t *(*)(const std::vector<uint8_t> &);
void SetupContextReplay(uint32_t test); void SetupContextReplay(uint32_t test);
void ReplayContextFrame(uint32_t test, uint32_t frameIndex); void ReplayContextFrame(uint32_t test, uint32_t frameIndex);
void ResetContextReplay(uint32_t test); void ResetContextReplay(uint32_t test);
const uint8_t *GetSerializedContextState(uint32_t test, uint32_t frameIndex); const char *GetSerializedContextState(uint32_t test, uint32_t frameIndex);
void SetBinaryDataDecompressCallback(uint32_t test, DecompressCallback callback); void SetBinaryDataDecompressCallback(uint32_t test, DecompressCallback callback);
void SetBinaryDataDir(uint32_t test, const char *dataDir); void SetBinaryDataDir(uint32_t test, const char *dataDir);
...@@ -164,7 +164,7 @@ void ResetContextReplay(uint32_t test) ...@@ -164,7 +164,7 @@ void ResetContextReplay(uint32_t test)
{reset_context1_replay_switch_statement} {reset_context1_replay_switch_statement}
}} }}
const uint8_t *GetSerializedContextState(uint32_t test, uint32_t frameIndex) const char *GetSerializedContextState(uint32_t test, uint32_t frameIndex)
{{ {{
{get_serialized_context1_state_data_switch_statement} {get_serialized_context1_state_data_switch_statement}
}} }}
......
...@@ -33,6 +33,7 @@ if (angle_build_capture_replay_tests) { ...@@ -33,6 +33,7 @@ if (angle_build_capture_replay_tests) {
"$angle_root:angle_common", "$angle_root:angle_common",
"$angle_root:angle_compression", "$angle_root:angle_compression",
"$angle_root:libEGL_with_capture_static", "$angle_root:libEGL_with_capture_static",
"$angle_root:libjson_serializer",
"$angle_root/util:angle_util_static", "$angle_root/util:angle_util_static",
] ]
configs += [ configs += [
......
...@@ -10,16 +10,19 @@ ...@@ -10,16 +10,19 @@
#include "common/system_utils.h" #include "common/system_utils.h"
#include "libANGLE/Context.h" #include "libANGLE/Context.h"
#include "libANGLE/capture/frame_capture_utils.h" #include "libANGLE/capture/frame_capture_utils.h"
#include "libANGLE/serializer/JsonSerializer.h"
#include "util/EGLPlatformParameters.h" #include "util/EGLPlatformParameters.h"
#include "util/EGLWindow.h" #include "util/EGLWindow.h"
#include "util/OSWindow.h" #include "util/OSWindow.h"
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include <fstream>
#include <functional> #include <functional>
#include <iostream> #include <iostream>
#include <list> #include <list>
#include <memory> #include <memory>
#include <ostream>
#include <string> #include <string>
#include <utility> #include <utility>
...@@ -128,13 +131,13 @@ class CaptureReplayTests ...@@ -128,13 +131,13 @@ class CaptureReplayTests
{ {
ReplayContextFrame(testIndex, frame); ReplayContextFrame(testIndex, frame);
gl::Context *context = static_cast<gl::Context *>(mEGLWindow->getContext()); gl::Context *context = static_cast<gl::Context *>(mEGLWindow->getContext());
gl::BinaryOutputStream bos; angle::JsonSerializer json;
if (angle::SerializeContext(&bos, context) != angle::Result::Continue) if (angle::SerializeContext(&json, context) != angle::Result::Continue)
{ {
cleanupTest(); cleanupTest();
return -1; return -1;
} }
bool isEqual = compareSerializedContexts(testIndex, frame, bos.getData()); bool isEqual = compareSerializedContexts(testIndex, frame, json.data());
// Swap always to allow RenderDoc/other tools to capture frames. // Swap always to allow RenderDoc/other tools to capture frames.
swap(); swap();
if (!isEqual) if (!isEqual)
...@@ -160,12 +163,10 @@ class CaptureReplayTests ...@@ -160,12 +163,10 @@ class CaptureReplayTests
private: private:
bool compareSerializedContexts(uint32_t testIndex, bool compareSerializedContexts(uint32_t testIndex,
uint32_t frame, uint32_t frame,
const std::vector<uint8_t> &replaySerializedContextState) const char *replaySerializedContextState)
{ {
return memcmp(replaySerializedContextState.data(), return !strcmp(replaySerializedContextState, GetSerializedContextState(testIndex, frame));
GetSerializedContextState(testIndex, frame),
replaySerializedContextState.size()) == 0;
} }
OSWindow *mOSWindow = nullptr; OSWindow *mOSWindow = nullptr;
......
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