mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-07-09 09:10:49 +00:00
2297 lines
57 KiB
C++
2297 lines
57 KiB
C++
/******************************************************************************
|
|
* The MIT License (MIT)
|
|
*
|
|
* Copyright (c) 2014 Crytek
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
* in the Software without restriction, including without limitation the rights
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in
|
|
* all copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
* THE SOFTWARE.
|
|
******************************************************************************/
|
|
|
|
|
|
#include "replay_proxy.h"
|
|
#include "lz4/lz4.h"
|
|
|
|
// these functions do compile time asserts on the size of the structure, to
|
|
// help prevent the structure changing without these functions being updated.
|
|
// This isn't perfect as a new variable could be added in padding space, or
|
|
// one removed and leaves padding. Most variables are 4 bytes in size though
|
|
// so it should be fairly reliable and it's better than nothing!
|
|
// Since structures contain pointers and vary in size, we do this only on
|
|
// Win32 to try and hide less padding with the larger alignment requirement
|
|
// of 8-byte pointers.
|
|
|
|
#if defined(WIN32) && defined(_M_IX86)
|
|
template<size_t a, size_t e> class oversized { int check[int(a)-int(e)+1]; };
|
|
template<size_t a, size_t e> class undersized { int check[int(e)-int(a)+1]; };
|
|
|
|
#define SIZE_CHECK(T, expected) undersized<sizeof(T), expected>(); oversized<sizeof(T), expected>();
|
|
#else
|
|
#define SIZE_CHECK(T, expected)
|
|
#endif
|
|
|
|
#pragma region General Shader/State
|
|
|
|
template<>
|
|
string ToStrHelper<false, SystemAttribute>::Get(const SystemAttribute &el)
|
|
{
|
|
switch(el)
|
|
{
|
|
TOSTR_CASE_STRINGIZE(eAttr_None)
|
|
TOSTR_CASE_STRINGIZE(eAttr_Position)
|
|
TOSTR_CASE_STRINGIZE(eAttr_PointSize)
|
|
TOSTR_CASE_STRINGIZE(eAttr_ClipDistance)
|
|
TOSTR_CASE_STRINGIZE(eAttr_CullDistance)
|
|
TOSTR_CASE_STRINGIZE(eAttr_RTIndex)
|
|
TOSTR_CASE_STRINGIZE(eAttr_ViewportIndex)
|
|
TOSTR_CASE_STRINGIZE(eAttr_VertexIndex)
|
|
TOSTR_CASE_STRINGIZE(eAttr_PrimitiveIndex)
|
|
TOSTR_CASE_STRINGIZE(eAttr_InstanceIndex)
|
|
TOSTR_CASE_STRINGIZE(eAttr_InvocationIndex)
|
|
TOSTR_CASE_STRINGIZE(eAttr_DispatchSize)
|
|
TOSTR_CASE_STRINGIZE(eAttr_DispatchThreadIndex)
|
|
TOSTR_CASE_STRINGIZE(eAttr_GroupIndex)
|
|
TOSTR_CASE_STRINGIZE(eAttr_GroupFlatIndex)
|
|
TOSTR_CASE_STRINGIZE(eAttr_GroupThreadIndex)
|
|
TOSTR_CASE_STRINGIZE(eAttr_GSInstanceIndex)
|
|
TOSTR_CASE_STRINGIZE(eAttr_OutputControlPointIndex)
|
|
TOSTR_CASE_STRINGIZE(eAttr_DomainLocation)
|
|
TOSTR_CASE_STRINGIZE(eAttr_IsFrontFace)
|
|
TOSTR_CASE_STRINGIZE(eAttr_MSAACoverage)
|
|
TOSTR_CASE_STRINGIZE(eAttr_MSAASamplePosition)
|
|
TOSTR_CASE_STRINGIZE(eAttr_MSAASampleIndex)
|
|
TOSTR_CASE_STRINGIZE(eAttr_PatchNumVertices)
|
|
TOSTR_CASE_STRINGIZE(eAttr_OuterTessFactor)
|
|
TOSTR_CASE_STRINGIZE(eAttr_InsideTessFactor)
|
|
TOSTR_CASE_STRINGIZE(eAttr_ColourOutput)
|
|
TOSTR_CASE_STRINGIZE(eAttr_DepthOutput)
|
|
TOSTR_CASE_STRINGIZE(eAttr_DepthOutputGreaterEqual)
|
|
TOSTR_CASE_STRINGIZE(eAttr_DepthOutputLessEqual)
|
|
default: break;
|
|
}
|
|
|
|
char tostrBuf[256] = {0};
|
|
StringFormat::snprintf(tostrBuf, 255, "SystemAttribute<%d>", el);
|
|
|
|
return tostrBuf;
|
|
}
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, ResourceFormat &el)
|
|
{
|
|
Serialise("", el.rawType);
|
|
Serialise("", el.special);
|
|
Serialise("", el.specialFormat);
|
|
Serialise("", el.strname);
|
|
Serialise("", el.compCount);
|
|
Serialise("", el.compByteWidth);
|
|
Serialise("", el.compType);
|
|
Serialise("", el.bgraOrder);
|
|
Serialise("", el.srgbCorrected);
|
|
|
|
SIZE_CHECK(ResourceFormat, 40);
|
|
}
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, BindpointMap &el)
|
|
{
|
|
Serialise("", el.bindset);
|
|
Serialise("", el.bind);
|
|
Serialise("", el.used);
|
|
Serialise("", el.arraySize);
|
|
|
|
SIZE_CHECK(BindpointMap, 16);
|
|
}
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, ShaderBindpointMapping &el)
|
|
{
|
|
Serialise("", el.InputAttributes);
|
|
Serialise("", el.ConstantBlocks);
|
|
Serialise("", el.ReadOnlyResources);
|
|
Serialise("", el.ReadWriteResources);
|
|
|
|
SIZE_CHECK(ShaderBindpointMapping, 32);
|
|
}
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, SigParameter &el)
|
|
{
|
|
Serialise("", el.varName);
|
|
Serialise("", el.semanticName);
|
|
Serialise("", el.semanticIndex);
|
|
Serialise("", el.semanticIdxName);
|
|
Serialise("", el.needSemanticIndex);
|
|
Serialise("", el.regIndex);
|
|
Serialise("", el.systemValue);
|
|
Serialise("", el.compType);
|
|
Serialise("", el.regChannelMask);
|
|
Serialise("", el.channelUsedMask);
|
|
Serialise("", el.compCount);
|
|
Serialise("", el.stream);
|
|
Serialise("", el.arrayIndex);
|
|
|
|
SIZE_CHECK(SigParameter, 60);
|
|
}
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, ShaderVariableType &el)
|
|
{
|
|
Serialise("", el.descriptor.name);
|
|
Serialise("", el.descriptor.type);
|
|
Serialise("", el.descriptor.rows);
|
|
Serialise("", el.descriptor.cols);
|
|
Serialise("", el.descriptor.elements);
|
|
Serialise("", el.descriptor.rowMajorStorage);
|
|
Serialise("", el.members);
|
|
|
|
SIZE_CHECK(ShaderVariableType, 36);
|
|
}
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, ShaderConstant &el)
|
|
{
|
|
Serialise("", el.name);
|
|
Serialise("", el.reg.vec);
|
|
Serialise("", el.reg.comp);
|
|
Serialise("", el.type);
|
|
|
|
SIZE_CHECK(ShaderConstant, 52);
|
|
}
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, ConstantBlock &el)
|
|
{
|
|
Serialise("", el.name);
|
|
Serialise("", el.variables);
|
|
Serialise("", el.bufferBacked);
|
|
Serialise("", el.bindPoint);
|
|
|
|
SIZE_CHECK(ConstantBlock, 24);
|
|
}
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, ShaderResource &el)
|
|
{
|
|
Serialise("", el.IsSampler);
|
|
Serialise("", el.IsTexture);
|
|
Serialise("", el.IsSRV);
|
|
Serialise("", el.resType);
|
|
Serialise("", el.name);
|
|
Serialise("", el.variableType);
|
|
Serialise("", el.bindPoint);
|
|
|
|
SIZE_CHECK(ShaderResource, 64);
|
|
}
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, ShaderReflection &el)
|
|
{
|
|
Serialise("", el.DebugInfo.compileFlags);
|
|
Serialise("", el.DebugInfo.entryFunc);
|
|
Serialise("", el.DebugInfo.files);
|
|
|
|
SerialisePODArray<3>("", el.DispatchThreadsDimension);
|
|
|
|
Serialise("", el.Disassembly);
|
|
|
|
Serialise("", el.InputSig);
|
|
Serialise("", el.OutputSig);
|
|
|
|
Serialise("", el.ConstantBlocks);
|
|
|
|
Serialise("", el.ReadOnlyResources);
|
|
Serialise("", el.ReadWriteResources);
|
|
|
|
Serialise("", el.Interfaces);
|
|
|
|
SIZE_CHECK(ShaderReflection, 92);
|
|
}
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, ShaderVariable &el)
|
|
{
|
|
Serialise("", el.rows);
|
|
Serialise("", el.columns);
|
|
Serialise("", el.name);
|
|
Serialise("", el.type);
|
|
|
|
SerialisePODArray<16>("", el.value.dv);
|
|
|
|
Serialise("", el.isStruct);
|
|
|
|
Serialise("", el.members);
|
|
|
|
SIZE_CHECK(ShaderVariable, 168);
|
|
}
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, ShaderDebugState &el)
|
|
{
|
|
Serialise("", el.registers);
|
|
Serialise("", el.outputs);
|
|
Serialise("", el.nextInstruction);
|
|
|
|
vector< vector<ShaderVariable> > indexableTemps;
|
|
|
|
int32_t numidxtemps = el.indexableTemps.count;
|
|
Serialise("", numidxtemps);
|
|
|
|
if(m_Mode == READING) create_array_uninit(el.indexableTemps, numidxtemps);
|
|
|
|
for(int32_t i=0; i < numidxtemps; i++)
|
|
Serialise("", el.indexableTemps[i]);
|
|
|
|
SIZE_CHECK(ShaderDebugState, 28);
|
|
}
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, ShaderDebugTrace &el)
|
|
{
|
|
Serialise("", el.inputs);
|
|
|
|
int32_t numcbuffers = el.cbuffers.count;
|
|
Serialise("", numcbuffers);
|
|
|
|
if(m_Mode == READING) create_array_uninit(el.cbuffers, numcbuffers);
|
|
|
|
for(int32_t i=0; i < numcbuffers; i++)
|
|
Serialise("", el.cbuffers[i]);
|
|
|
|
Serialise("", el.states);
|
|
|
|
SIZE_CHECK(ShaderDebugTrace, 24);
|
|
}
|
|
|
|
#pragma endregion General Shader/State
|
|
|
|
#pragma region D3D11 pipeline state
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, D3D11PipelineState::InputAssembler::LayoutInput &el)
|
|
{
|
|
Serialise("", el.SemanticName);
|
|
Serialise("", el.SemanticIndex);
|
|
Serialise("", el.Format);
|
|
Serialise("", el.InputSlot);
|
|
Serialise("", el.ByteOffset);
|
|
Serialise("", el.PerInstance);
|
|
Serialise("", el.InstanceDataStepRate);
|
|
|
|
SIZE_CHECK(D3D11PipelineState::InputAssembler::LayoutInput, 68);
|
|
}
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, D3D11PipelineState::InputAssembler &el)
|
|
{
|
|
Serialise("", el.ibuffer.Buffer);
|
|
Serialise("", el.ibuffer.Offset);
|
|
|
|
Serialise("", el.vbuffers);
|
|
Serialise("", el.layouts);
|
|
|
|
SIZE_CHECK(D3D11PipelineState::InputAssembler, 48);
|
|
}
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, D3D11PipelineState::ShaderStage::ResourceView &el)
|
|
{
|
|
Serialise("", el.View);
|
|
Serialise("", el.Resource);
|
|
Serialise("", el.Type);
|
|
Serialise("", el.Format);
|
|
|
|
Serialise("", el.Structured);
|
|
Serialise("", el.BufferStructCount);
|
|
Serialise("", el.ElementOffset);
|
|
Serialise("", el.ElementWidth);
|
|
Serialise("", el.FirstElement);
|
|
Serialise("", el.NumElements);
|
|
|
|
Serialise("", el.Flags);
|
|
Serialise("", el.HighestMip);
|
|
Serialise("", el.NumMipLevels);
|
|
Serialise("", el.ArraySize);
|
|
Serialise("", el.FirstArraySlice);
|
|
|
|
SIZE_CHECK(D3D11PipelineState::ShaderStage::ResourceView, 112);
|
|
}
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, D3D11PipelineState::ShaderStage::Sampler &el)
|
|
{
|
|
Serialise("", el.Samp);
|
|
Serialise("", el.AddressU);
|
|
Serialise("", el.AddressV);
|
|
Serialise("", el.AddressW);
|
|
SerialisePODArray<4>("", el.BorderColor);
|
|
Serialise("", el.Comparison);
|
|
Serialise("", el.Filter);
|
|
Serialise("", el.UseBorder);
|
|
Serialise("", el.UseComparison);
|
|
Serialise("", el.MaxAniso);
|
|
Serialise("", el.MaxLOD);
|
|
Serialise("", el.MinLOD);
|
|
Serialise("", el.MipLODBias);
|
|
|
|
SIZE_CHECK(D3D11PipelineState::ShaderStage::Sampler, 88);
|
|
}
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, D3D11PipelineState::ShaderStage &el)
|
|
{
|
|
Serialise("", el.Shader);
|
|
Serialise("", el.stage);
|
|
Serialise("", el.ShaderName);
|
|
Serialise("", el.customName);
|
|
|
|
if(m_Mode == READING)
|
|
el.ShaderDetails = NULL;
|
|
|
|
Serialise("", el.BindpointMapping);
|
|
|
|
Serialise("", el.SRVs);
|
|
Serialise("", el.UAVs);
|
|
Serialise("", el.Samplers);
|
|
Serialise("", el.ConstantBuffers);
|
|
Serialise("", el.ClassInstances);
|
|
|
|
SIZE_CHECK(D3D11PipelineState::ShaderStage, 104);
|
|
}
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, D3D11PipelineState::Rasterizer &el)
|
|
{
|
|
Serialise("", el.m_State);
|
|
Serialise("", el.Scissors);
|
|
Serialise("", el.Viewports);
|
|
|
|
SIZE_CHECK(D3D11PipelineState::Rasterizer, 72);
|
|
}
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, D3D11PipelineState::OutputMerger::BlendState::RTBlend &el)
|
|
{
|
|
Serialise("", el.m_Blend.Source);
|
|
Serialise("", el.m_Blend.Destination);
|
|
Serialise("", el.m_Blend.Operation);
|
|
|
|
Serialise("", el.m_AlphaBlend.Source);
|
|
Serialise("", el.m_AlphaBlend.Destination);
|
|
Serialise("", el.m_AlphaBlend.Operation);
|
|
|
|
Serialise("", el.LogicOp);
|
|
|
|
Serialise("", el.Enabled);
|
|
Serialise("", el.LogicEnabled);
|
|
Serialise("", el.WriteMask);
|
|
|
|
SIZE_CHECK(D3D11PipelineState::OutputMerger::BlendState::RTBlend, 68);
|
|
}
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, D3D11PipelineState::OutputMerger &el)
|
|
{
|
|
{
|
|
Serialise("", el.m_State.State);
|
|
Serialise("", el.m_State.DepthEnable);
|
|
Serialise("", el.m_State.DepthFunc);
|
|
Serialise("", el.m_State.DepthWrites);
|
|
Serialise("", el.m_State.StencilEnable);
|
|
Serialise("", el.m_State.StencilReadMask);
|
|
Serialise("", el.m_State.StencilWriteMask);
|
|
|
|
Serialise("", el.m_State.m_FrontFace.FailOp);
|
|
Serialise("", el.m_State.m_FrontFace.DepthFailOp);
|
|
Serialise("", el.m_State.m_FrontFace.PassOp);
|
|
Serialise("", el.m_State.m_FrontFace.Func);
|
|
|
|
Serialise("", el.m_State.m_BackFace.FailOp);
|
|
Serialise("", el.m_State.m_BackFace.DepthFailOp);
|
|
Serialise("", el.m_State.m_BackFace.PassOp);
|
|
Serialise("", el.m_State.m_BackFace.Func);
|
|
|
|
Serialise("", el.m_State.StencilRef);
|
|
}
|
|
|
|
{
|
|
Serialise("", el.m_BlendState.State);
|
|
Serialise("", el.m_BlendState.AlphaToCoverage);
|
|
Serialise("", el.m_BlendState.IndependentBlend);
|
|
Serialise("", el.m_BlendState.Blends);
|
|
SerialisePODArray<4>("", el.m_BlendState.BlendFactor);
|
|
|
|
Serialise("", el.m_BlendState.SampleMask);
|
|
}
|
|
|
|
Serialise("", el.RenderTargets);
|
|
Serialise("", el.UAVStartSlot);
|
|
Serialise("", el.UAVs);
|
|
Serialise("", el.DepthTarget);
|
|
Serialise("", el.DepthReadOnly);
|
|
Serialise("", el.StencilReadOnly);
|
|
|
|
SIZE_CHECK(D3D11PipelineState::OutputMerger, 296);
|
|
}
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, D3D11PipelineState &el)
|
|
{
|
|
Serialise("", el.m_IA);
|
|
|
|
Serialise("", el.m_VS);
|
|
Serialise("", el.m_HS);
|
|
Serialise("", el.m_DS);
|
|
Serialise("", el.m_GS);
|
|
Serialise("", el.m_PS);
|
|
Serialise("", el.m_CS);
|
|
|
|
Serialise("", el.m_SO.Outputs);
|
|
|
|
Serialise("", el.m_RS);
|
|
Serialise("", el.m_OM);
|
|
|
|
SIZE_CHECK(D3D11PipelineState, 1040);
|
|
}
|
|
|
|
#pragma endregion D3D11 pipeline state
|
|
|
|
#pragma region OpenGL pipeline state
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, GLPipelineState::VertexInput::VertexAttribute &el)
|
|
{
|
|
Serialise("", el.Enabled);
|
|
Serialise("", el.Format);
|
|
SerialisePODArray<4>("", el.GenericValue.f);
|
|
Serialise("", el.BufferSlot);
|
|
Serialise("", el.RelativeOffset);
|
|
|
|
SIZE_CHECK(GLPipelineState::VertexInput::VertexAttribute, 68);
|
|
}
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, GLPipelineState::VertexInput &el)
|
|
{
|
|
Serialise("", el.attributes);
|
|
Serialise("", el.vbuffers);
|
|
Serialise("", el.ibuffer);
|
|
Serialise("", el.primitiveRestart);
|
|
Serialise("", el.restartIndex);
|
|
Serialise("", el.provokingVertexLast);
|
|
|
|
SIZE_CHECK(GLPipelineState::VertexInput, 40);
|
|
}
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, GLPipelineState::ShaderStage &el)
|
|
{
|
|
Serialise("", el.Shader);
|
|
Serialise("", el.stage);
|
|
Serialise("", el.BindpointMapping);
|
|
Serialise("", el.Subroutines);
|
|
|
|
if(m_Mode == READING)
|
|
el.ShaderDetails = NULL;
|
|
|
|
SIZE_CHECK(GLPipelineState::ShaderStage, 56);
|
|
}
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, GLPipelineState::Sampler &el)
|
|
{
|
|
Serialise("", el.Samp);
|
|
Serialise("", el.AddressS);
|
|
Serialise("", el.AddressT);
|
|
Serialise("", el.AddressR);
|
|
SerialisePODArray<4>("", el.BorderColor);
|
|
Serialise("", el.Comparison);
|
|
Serialise("", el.MinFilter);
|
|
Serialise("", el.MagFilter);
|
|
Serialise("", el.UseBorder);
|
|
Serialise("", el.UseComparison);
|
|
Serialise("", el.SeamlessCube);
|
|
Serialise("", el.MaxAniso);
|
|
Serialise("", el.MaxLOD);
|
|
Serialise("", el.MinLOD);
|
|
Serialise("", el.MipLODBias);
|
|
|
|
SIZE_CHECK(GLPipelineState::Sampler, 104);
|
|
}
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, GLPipelineState::ImageLoadStore &el)
|
|
{
|
|
Serialise("", el.Resource);
|
|
Serialise("", el.Level);
|
|
Serialise("", el.Layered);
|
|
Serialise("", el.Layer);
|
|
Serialise("", el.ResType);
|
|
Serialise("", el.readAllowed);
|
|
Serialise("", el.writeAllowed);
|
|
Serialise("", el.Format);
|
|
|
|
SIZE_CHECK(GLPipelineState::ImageLoadStore, 72);
|
|
}
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, GLPipelineState::Rasterizer &el)
|
|
{
|
|
Serialise("", el.Viewports);
|
|
Serialise("", el.Scissors);
|
|
Serialise("", el.m_State);
|
|
|
|
SIZE_CHECK(GLPipelineState::Rasterizer, 104);
|
|
}
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, GLPipelineState::DepthState &el)
|
|
{
|
|
Serialise("", el.DepthEnable);
|
|
Serialise("", el.DepthFunc);
|
|
Serialise("", el.DepthWrites);
|
|
Serialise("", el.DepthBounds);
|
|
Serialise("", el.NearBound);
|
|
Serialise("", el.FarBound);
|
|
|
|
SIZE_CHECK(GLPipelineState::DepthState, 40);
|
|
}
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, GLPipelineState::StencilState &el)
|
|
{
|
|
Serialise("", el.StencilEnable);
|
|
|
|
Serialise("", el.m_FrontFace.FailOp);
|
|
Serialise("", el.m_FrontFace.DepthFailOp);
|
|
Serialise("", el.m_FrontFace.PassOp);
|
|
Serialise("", el.m_FrontFace.Func);
|
|
Serialise("", el.m_FrontFace.Ref);
|
|
Serialise("", el.m_FrontFace.ValueMask);
|
|
Serialise("", el.m_FrontFace.WriteMask);
|
|
|
|
Serialise("", el.m_BackFace.FailOp);
|
|
Serialise("", el.m_BackFace.DepthFailOp);
|
|
Serialise("", el.m_BackFace.PassOp);
|
|
Serialise("", el.m_BackFace.Func);
|
|
Serialise("", el.m_BackFace.Ref);
|
|
Serialise("", el.m_BackFace.ValueMask);
|
|
Serialise("", el.m_BackFace.WriteMask);
|
|
|
|
SIZE_CHECK(GLPipelineState::StencilState, 92);
|
|
}
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, GLPipelineState::FrameBuffer::BlendState::RTBlend &el)
|
|
{
|
|
Serialise("", el.Enabled);
|
|
Serialise("", el.WriteMask);
|
|
Serialise("", el.LogicOp);
|
|
|
|
Serialise("", el.m_Blend.Source);
|
|
Serialise("", el.m_Blend.Destination);
|
|
Serialise("", el.m_Blend.Operation);
|
|
|
|
Serialise("", el.m_AlphaBlend.Source);
|
|
Serialise("", el.m_AlphaBlend.Destination);
|
|
Serialise("", el.m_AlphaBlend.Operation);
|
|
|
|
SIZE_CHECK(GLPipelineState::FrameBuffer::BlendState::RTBlend, 64);
|
|
}
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, GLPipelineState::FrameBuffer::BlendState &el)
|
|
{
|
|
SerialisePODArray<4>("", el.BlendFactor);
|
|
Serialise("", el.Blends);
|
|
|
|
SIZE_CHECK(GLPipelineState::FrameBuffer::BlendState, 24);
|
|
}
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, GLPipelineState::FrameBuffer::Attachment &el)
|
|
{
|
|
Serialise("", el.Obj);
|
|
Serialise("", el.Layer);
|
|
Serialise("", el.Mip);
|
|
|
|
SIZE_CHECK(GLPipelineState::FrameBuffer::Attachment, 16);
|
|
}
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, GLPipelineState::FrameBuffer &el)
|
|
{
|
|
Serialise("", el.FramebufferSRGB);
|
|
Serialise("", el.Dither);
|
|
|
|
Serialise("", el.m_DrawFBO.Obj);
|
|
Serialise("", el.m_DrawFBO.Color);
|
|
Serialise("", el.m_DrawFBO.Depth);
|
|
Serialise("", el.m_DrawFBO.Stencil);
|
|
Serialise("", el.m_DrawFBO.DrawBuffers);
|
|
Serialise("", el.m_DrawFBO.ReadBuffer);
|
|
|
|
Serialise("", el.m_ReadFBO.Obj);
|
|
Serialise("", el.m_ReadFBO.Color);
|
|
Serialise("", el.m_ReadFBO.Depth);
|
|
Serialise("", el.m_ReadFBO.Stencil);
|
|
Serialise("", el.m_ReadFBO.DrawBuffers);
|
|
Serialise("", el.m_ReadFBO.ReadBuffer);
|
|
|
|
Serialise("", el.m_Blending);
|
|
|
|
SIZE_CHECK(GLPipelineState::FrameBuffer, 160);
|
|
}
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, GLPipelineState &el)
|
|
{
|
|
Serialise("", el.m_VtxIn);
|
|
|
|
Serialise("", el.m_VS);
|
|
Serialise("", el.m_TCS);
|
|
Serialise("", el.m_TES);
|
|
Serialise("", el.m_GS);
|
|
Serialise("", el.m_FS);
|
|
Serialise("", el.m_CS);
|
|
|
|
Serialise("", el.m_VtxProcess);
|
|
|
|
Serialise("", el.Textures);
|
|
Serialise("", el.Samplers);
|
|
Serialise("", el.AtomicBuffers);
|
|
Serialise("", el.UniformBuffers);
|
|
Serialise("", el.ShaderStorageBuffers);
|
|
Serialise("", el.Images);
|
|
|
|
Serialise("", el.m_Feedback);
|
|
|
|
Serialise("", el.m_Rasterizer);
|
|
Serialise("", el.m_DepthState);
|
|
Serialise("", el.m_StencilState);
|
|
|
|
Serialise("", el.m_FB);
|
|
|
|
Serialise("", el.m_Hints);
|
|
|
|
SIZE_CHECK(GLPipelineState, 1032);
|
|
}
|
|
|
|
#pragma endregion OpenGL pipeline state
|
|
|
|
#pragma region Vulkan pipeline state
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, VulkanPipelineState::Pipeline::DescriptorSet::DescriptorBinding &el)
|
|
{
|
|
Serialise("", el.descriptorCount);
|
|
Serialise("", el.type);
|
|
Serialise("", el.stageFlags);
|
|
|
|
Serialise("", el.binds);
|
|
|
|
SIZE_CHECK(VulkanPipelineState::Pipeline::DescriptorSet::DescriptorBinding, 20);
|
|
}
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, VulkanPipelineState::Pipeline::DescriptorSet &el)
|
|
{
|
|
Serialise("", el.layout);
|
|
Serialise("", el.descset);
|
|
|
|
Serialise("", el.bindings);
|
|
|
|
SIZE_CHECK(VulkanPipelineState::Pipeline::DescriptorSet, 24);
|
|
}
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, VulkanPipelineState::Pipeline &el)
|
|
{
|
|
Serialise("", el.obj);
|
|
Serialise("", el.flags);
|
|
|
|
Serialise("", el.DescSets);
|
|
|
|
SIZE_CHECK(VulkanPipelineState::Pipeline, 24);
|
|
}
|
|
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, VulkanPipelineState::VertexInput::Attribute &el)
|
|
{
|
|
Serialise("", el.location);
|
|
Serialise("", el.binding);
|
|
Serialise("", el.format);
|
|
Serialise("", el.byteoffset);
|
|
|
|
SIZE_CHECK(VulkanPipelineState::VertexInput::Attribute, 52);
|
|
}
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, VulkanPipelineState::VertexInput &el)
|
|
{
|
|
Serialise("", el.attrs);
|
|
Serialise("", el.binds);
|
|
Serialise("", el.vbuffers);
|
|
|
|
SIZE_CHECK(VulkanPipelineState::VertexInput, 24);
|
|
}
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, VulkanPipelineState::ShaderStage::SpecInfo &el)
|
|
{
|
|
Serialise("", el.specID);
|
|
Serialise("", el.data);
|
|
|
|
SIZE_CHECK(VulkanPipelineState::ShaderStage::SpecInfo, 12);
|
|
}
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, VulkanPipelineState::ShaderStage &el)
|
|
{
|
|
Serialise("", el.Shader);
|
|
Serialise("", el.entryPoint);
|
|
|
|
Serialise("", el.ShaderName);
|
|
Serialise("", el.customName);
|
|
Serialise("", el.BindpointMapping);
|
|
Serialise("", el.stage);
|
|
|
|
if(m_Mode == READING)
|
|
el.ShaderDetails = NULL;
|
|
|
|
Serialise("", el.specialization);
|
|
|
|
SIZE_CHECK(VulkanPipelineState::ShaderStage, 80);
|
|
}
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, VulkanPipelineState::ViewState &el)
|
|
{
|
|
Serialise("", el.viewportScissors);
|
|
|
|
SIZE_CHECK(VulkanPipelineState::ViewState, 8);
|
|
}
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, VulkanPipelineState::ColorBlend::Attachment &el)
|
|
{
|
|
Serialise("", el.blendEnable);
|
|
|
|
Serialise("", el.blend.Source);
|
|
Serialise("", el.blend.Destination);
|
|
Serialise("", el.blend.Operation);
|
|
|
|
Serialise("", el.alphaBlend.Source);
|
|
Serialise("", el.alphaBlend.Destination);
|
|
Serialise("", el.alphaBlend.Operation);
|
|
|
|
Serialise("", el.writeMask);
|
|
|
|
SIZE_CHECK(VulkanPipelineState::ColorBlend::Attachment, 56);
|
|
}
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, VulkanPipelineState::ColorBlend &el)
|
|
{
|
|
Serialise("", el.alphaToCoverageEnable);
|
|
Serialise("", el.alphaToOneEnable);
|
|
Serialise("", el.logicOpEnable);
|
|
Serialise("", el.logicOp);
|
|
|
|
Serialise("", el.attachments);
|
|
|
|
SerialisePODArray<4>("", el.blendConst);
|
|
|
|
SIZE_CHECK(VulkanPipelineState::ColorBlend, 44);
|
|
}
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, VulkanPipelineState::DepthStencil &el)
|
|
{
|
|
Serialise("", el.depthTestEnable);
|
|
Serialise("", el.depthWriteEnable);
|
|
Serialise("", el.depthBoundsEnable);
|
|
Serialise("", el.depthCompareOp);
|
|
|
|
Serialise("", el.stencilTestEnable);
|
|
|
|
Serialise("", el.front.failOp);
|
|
Serialise("", el.front.depthFailOp);
|
|
Serialise("", el.front.passOp);
|
|
Serialise("", el.front.func);
|
|
Serialise("", el.front.ref);
|
|
Serialise("", el.front.compareMask);
|
|
Serialise("", el.front.writeMask);
|
|
|
|
Serialise("", el.back.failOp);
|
|
Serialise("", el.back.depthFailOp);
|
|
Serialise("", el.back.passOp);
|
|
Serialise("", el.back.func);
|
|
Serialise("", el.back.ref);
|
|
Serialise("", el.back.compareMask);
|
|
Serialise("", el.back.writeMask);
|
|
|
|
Serialise("", el.minDepthBounds);
|
|
Serialise("", el.maxDepthBounds);
|
|
|
|
SIZE_CHECK(VulkanPipelineState::DepthStencil, 120);
|
|
}
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, VulkanPipelineState::CurrentPass &el)
|
|
{
|
|
Serialise("", el.renderpass.obj);
|
|
Serialise("", el.renderpass.inputAttachments);
|
|
Serialise("", el.renderpass.colorAttachments);
|
|
Serialise("", el.renderpass.depthstencilAttachment);
|
|
|
|
Serialise("", el.framebuffer.obj);
|
|
Serialise("", el.framebuffer.attachments);
|
|
Serialise("", el.framebuffer.width);
|
|
Serialise("", el.framebuffer.height);
|
|
Serialise("", el.framebuffer.layers);
|
|
|
|
Serialise("", el.renderArea);
|
|
|
|
SIZE_CHECK(VulkanPipelineState::CurrentPass, 80);
|
|
}
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, VulkanPipelineState &el)
|
|
{
|
|
Serialise("", el.compute);
|
|
Serialise("", el.graphics);
|
|
|
|
Serialise("", el.IA);
|
|
Serialise("", el.VI);
|
|
|
|
Serialise("", el.VS);
|
|
Serialise("", el.TCS);
|
|
Serialise("", el.TES);
|
|
Serialise("", el.GS);
|
|
Serialise("", el.FS);
|
|
Serialise("", el.CS);
|
|
|
|
Serialise("", el.Tess);
|
|
|
|
Serialise("", el.VP);
|
|
Serialise("", el.RS);
|
|
Serialise("", el.MSAA);
|
|
Serialise("", el.CB);
|
|
Serialise("", el.DS);
|
|
Serialise("", el.Pass);
|
|
|
|
SIZE_CHECK(VulkanPipelineState, 888);
|
|
}
|
|
|
|
#pragma endregion Vulkan pipeline state
|
|
|
|
#pragma region Data descriptors
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, FetchTexture &el)
|
|
{
|
|
Serialise("", el.name);
|
|
Serialise("", el.customName);
|
|
Serialise("", el.format);
|
|
Serialise("", el.dimension);
|
|
Serialise("", el.resType);
|
|
Serialise("", el.width);
|
|
Serialise("", el.height);
|
|
Serialise("", el.depth);
|
|
Serialise("", el.ID);
|
|
Serialise("", el.cubemap);
|
|
Serialise("", el.mips);
|
|
Serialise("", el.arraysize);
|
|
Serialise("", el.numSubresources);
|
|
Serialise("", el.creationFlags);
|
|
Serialise("", el.msQual);
|
|
Serialise("", el.msSamp);
|
|
|
|
SIZE_CHECK(FetchTexture, 120);
|
|
}
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, FetchBuffer &el)
|
|
{
|
|
Serialise("", el.ID);
|
|
Serialise("", el.name);
|
|
Serialise("", el.customName);
|
|
Serialise("", el.length);
|
|
Serialise("", el.structureSize);
|
|
Serialise("", el.creationFlags);
|
|
Serialise("", el.byteSize);
|
|
|
|
SIZE_CHECK(FetchBuffer, 40);
|
|
}
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, APIProperties &el)
|
|
{
|
|
Serialise("", el.pipelineType);
|
|
Serialise("", el.degraded);
|
|
|
|
SIZE_CHECK(APIProperties, 8);
|
|
}
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, DebugMessage &el)
|
|
{
|
|
Serialise("", el.eventID);
|
|
Serialise("", el.category);
|
|
Serialise("", el.severity);
|
|
Serialise("", el.source);
|
|
Serialise("", el.messageID);
|
|
Serialise("", el.description);
|
|
|
|
SIZE_CHECK(DebugMessage, 28);
|
|
}
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, FetchAPIEvent &el)
|
|
{
|
|
Serialise("", el.eventID);
|
|
Serialise("", el.context);
|
|
Serialise("", el.callstack);
|
|
Serialise("", el.eventDesc);
|
|
Serialise("", el.fileOffset);
|
|
|
|
SIZE_CHECK(FetchAPIEvent, 40);
|
|
}
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, FetchDrawcall &el)
|
|
{
|
|
Serialise("", el.eventID);
|
|
Serialise("", el.drawcallID);
|
|
|
|
Serialise("", el.name);
|
|
|
|
Serialise("", el.flags);
|
|
|
|
Serialise("", el.numIndices);
|
|
Serialise("", el.numInstances);
|
|
Serialise("", el.indexOffset);
|
|
Serialise("", el.vertexOffset);
|
|
Serialise("", el.instanceOffset);
|
|
|
|
SerialisePODArray<3>("", el.dispatchDimension);
|
|
SerialisePODArray<3>("", el.dispatchThreadsDimension);
|
|
|
|
Serialise("", el.indexByteWidth);
|
|
Serialise("", el.topology);
|
|
|
|
Serialise("", el.context);
|
|
|
|
Serialise("", el.copySource);
|
|
Serialise("", el.copyDestination);
|
|
|
|
Serialise("", el.parent);
|
|
Serialise("", el.previous);
|
|
Serialise("", el.next);
|
|
|
|
SerialisePODArray<8>("", el.outputs);
|
|
Serialise("", el.depthOut);
|
|
|
|
Serialise("", el.events);
|
|
Serialise("", el.children);
|
|
|
|
SIZE_CHECK(FetchDrawcall, 208);
|
|
}
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, FetchFrameInfo &el)
|
|
{
|
|
Serialise("", el.frameNumber);
|
|
Serialise("", el.firstEvent);
|
|
Serialise("", el.fileOffset);
|
|
Serialise("", el.captureTime);
|
|
Serialise("", el.immContextId);
|
|
Serialise("", el.debugMessages);
|
|
|
|
SIZE_CHECK(FetchFrameInfo, 40);
|
|
}
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, FetchFrameRecord &el)
|
|
{
|
|
Serialise("", el.frameInfo);
|
|
Serialise("", el.drawcallList);
|
|
|
|
SIZE_CHECK(FetchFrameRecord, 56);
|
|
}
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, MeshFormat &el)
|
|
{
|
|
Serialise("", el.idxbuf);
|
|
Serialise("", el.idxoffs);
|
|
Serialise("", el.idxByteWidth);
|
|
Serialise("", el.buf);
|
|
Serialise("", el.offset);
|
|
Serialise("", el.stride);
|
|
Serialise("", el.compCount);
|
|
Serialise("", el.compByteWidth);
|
|
Serialise("", el.compType);
|
|
Serialise("", el.bgraOrder);
|
|
Serialise("", el.specialFormat);
|
|
Serialise("", el.showAlpha);
|
|
Serialise("", el.topo);
|
|
Serialise("", el.numVerts);
|
|
Serialise("", el.unproject);
|
|
Serialise("", el.nearPlane);
|
|
Serialise("", el.farPlane);
|
|
|
|
SIZE_CHECK(MeshFormat, 88);
|
|
}
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, CounterDescription &el)
|
|
{
|
|
Serialise("", el.counterID);
|
|
Serialise("", el.name);
|
|
Serialise("", el.description);
|
|
Serialise("", el.resultCompType);
|
|
Serialise("", el.resultByteWidth);
|
|
Serialise("", el.units);
|
|
|
|
SIZE_CHECK(CounterDescription, 32);
|
|
}
|
|
|
|
template<>
|
|
void Serialiser::Serialise(const char *name, PixelModification &el)
|
|
{
|
|
Serialise("", el.eventID);
|
|
|
|
Serialise("", el.uavWrite);
|
|
Serialise("", el.fragIndex);
|
|
Serialise("", el.primitiveID);
|
|
|
|
SerialisePODArray<4>("", el.preMod.col.value_u);
|
|
Serialise("", el.preMod.depth);
|
|
Serialise("", el.preMod.stencil);
|
|
SerialisePODArray<4>("", el.shaderOut.col.value_u);
|
|
Serialise("", el.shaderOut.depth);
|
|
Serialise("", el.shaderOut.stencil);
|
|
SerialisePODArray<4>("", el.postMod.col.value_u);
|
|
Serialise("", el.postMod.depth);
|
|
Serialise("", el.postMod.stencil);
|
|
|
|
Serialise("", el.backfaceCulled);
|
|
Serialise("", el.depthClipped);
|
|
Serialise("", el.viewClipped);
|
|
Serialise("", el.scissorClipped);
|
|
Serialise("", el.shaderDiscarded);
|
|
Serialise("", el.depthTestFailed);
|
|
Serialise("", el.stencilTestFailed);
|
|
|
|
SIZE_CHECK(PixelModification, 116);
|
|
}
|
|
|
|
#pragma endregion Data descriptors
|
|
|
|
#pragma region Ignored Enums
|
|
|
|
// don't need string representation of these enums
|
|
template<>
|
|
string ToStrHelper<false, SpecialFormat>::Get(const SpecialFormat &el) { return "<...>"; }
|
|
template<>
|
|
string ToStrHelper<false, FormatComponentType>::Get(const FormatComponentType &el) { return "<...>"; }
|
|
template<>
|
|
string ToStrHelper<false, CounterUnits>::Get(const CounterUnits &el) { return "<...>"; }
|
|
template<>
|
|
string ToStrHelper<false, PrimitiveTopology>::Get(const PrimitiveTopology &el) { return "<...>"; }
|
|
template<>
|
|
string ToStrHelper<false, ShaderStageType>::Get(const ShaderStageType &el) { return "<...>"; }
|
|
template<>
|
|
string ToStrHelper<false, ShaderStageBits>::Get(const ShaderStageBits &el) { return "<...>"; }
|
|
template<>
|
|
string ToStrHelper<false, ShaderBindType>::Get(const ShaderBindType &el) { return "<...>"; }
|
|
template<>
|
|
string ToStrHelper<false, ShaderResourceType>::Get(const ShaderResourceType &el) { return "<...>"; }
|
|
template<>
|
|
string ToStrHelper<false, DebugMessageCategory>::Get(const DebugMessageCategory &el) { return "<...>"; }
|
|
template<>
|
|
string ToStrHelper<false, DebugMessageSeverity>::Get(const DebugMessageSeverity &el) { return "<...>"; }
|
|
template<>
|
|
string ToStrHelper<false, DebugMessageSource>::Get(const DebugMessageSource &el) { return "<...>"; }
|
|
template<>
|
|
string ToStrHelper<false, VarType>::Get(const VarType &el) { return "<...>"; }
|
|
template<>
|
|
string ToStrHelper<false, MeshDataStage>::Get(const MeshDataStage &el) { return "<...>"; }
|
|
template<>
|
|
string ToStrHelper<false, TextureDisplayOverlay>::Get(const TextureDisplayOverlay &el) { return "<...>"; }
|
|
template<>
|
|
string ToStrHelper<false, APIPipelineStateType>::Get(const APIPipelineStateType &el) { return "<...>"; }
|
|
|
|
#pragma endregion Ignored Enums
|
|
|
|
#pragma region Plain-old data structures
|
|
|
|
// these structures we can just serialise as a blob, since they're POD.
|
|
template<>
|
|
string ToStrHelper<false, D3D11PipelineState::InputAssembler::VertexBuffer>::Get(const D3D11PipelineState::InputAssembler::VertexBuffer &el) { return "<...>"; }
|
|
template<>
|
|
string ToStrHelper<false, D3D11PipelineState::Rasterizer::RasterizerState>::Get(const D3D11PipelineState::Rasterizer::RasterizerState &el) { return "<...>"; }
|
|
template<>
|
|
string ToStrHelper<false, D3D11PipelineState::ShaderStage::CBuffer>::Get(const D3D11PipelineState::ShaderStage::CBuffer &el) { return "<...>"; }
|
|
template<>
|
|
string ToStrHelper<false, D3D11PipelineState::Rasterizer::Scissor>::Get(const D3D11PipelineState::Rasterizer::Scissor &el) { return "<...>"; }
|
|
template<>
|
|
string ToStrHelper<false, D3D11PipelineState::Rasterizer::Viewport>::Get(const D3D11PipelineState::Rasterizer::Viewport &el) { return "<...>"; }
|
|
template<>
|
|
string ToStrHelper<false, D3D11PipelineState::Streamout::Output>::Get(const D3D11PipelineState::Streamout::Output &el) { return "<...>"; }
|
|
template<>
|
|
string ToStrHelper<false, GLPipelineState::VertexInput::VertexBuffer>::Get(const GLPipelineState::VertexInput::VertexBuffer &el) { return "<...>"; }
|
|
template<>
|
|
string ToStrHelper<false, GLPipelineState::FixedVertexProcessing>::Get(const GLPipelineState::FixedVertexProcessing &el) { return "<...>"; }
|
|
template<>
|
|
string ToStrHelper<false, GLPipelineState::Texture>::Get(const GLPipelineState::Texture &el) { return "<...>"; }
|
|
template<>
|
|
string ToStrHelper<false, GLPipelineState::Buffer>::Get(const GLPipelineState::Buffer &el) { return "<...>"; }
|
|
template<>
|
|
string ToStrHelper<false, GLPipelineState::Feedback>::Get(const GLPipelineState::Feedback &el) { return "<...>"; }
|
|
template<>
|
|
string ToStrHelper<false, GLPipelineState::Rasterizer::Viewport>::Get(const GLPipelineState::Rasterizer::Viewport &el) { return "<...>"; }
|
|
template<>
|
|
string ToStrHelper<false, GLPipelineState::Rasterizer::Scissor>::Get(const GLPipelineState::Rasterizer::Scissor &el) { return "<...>"; }
|
|
template<>
|
|
string ToStrHelper<false, GLPipelineState::Rasterizer::RasterizerState>::Get(const GLPipelineState::Rasterizer::RasterizerState &el) { return "<...>"; }
|
|
template<>
|
|
string ToStrHelper<false, GLPipelineState::Hints>::Get(const GLPipelineState::Hints &el) { return "<...>"; }
|
|
template<>
|
|
string ToStrHelper<false, VulkanPipelineState::CurrentPass::RenderArea>::Get(const VulkanPipelineState::CurrentPass::RenderArea &el) { return "<...>"; }
|
|
template<>
|
|
string ToStrHelper<false, VulkanPipelineState::InputAssembly>::Get(const VulkanPipelineState::InputAssembly &el) { return "<...>"; }
|
|
template<>
|
|
string ToStrHelper<false, VulkanPipelineState::Tessellation>::Get(const VulkanPipelineState::Tessellation &el) { return "<...>"; }
|
|
template<>
|
|
string ToStrHelper<false, VulkanPipelineState::Raster>::Get(const VulkanPipelineState::Raster &el) { return "<...>"; }
|
|
template<>
|
|
string ToStrHelper<false, VulkanPipelineState::MultiSample>::Get(const VulkanPipelineState::MultiSample &el) { return "<...>"; }
|
|
template<>
|
|
string ToStrHelper<false, VulkanPipelineState::Pipeline::DescriptorSet::DescriptorBinding::BindingElement>::Get(const VulkanPipelineState::Pipeline::DescriptorSet::DescriptorBinding::BindingElement &el) { return "<...>"; }
|
|
template<>
|
|
string ToStrHelper<false, VulkanPipelineState::VertexInput::Binding>::Get(const VulkanPipelineState::VertexInput::Binding &el) { return "<...>"; }
|
|
template<>
|
|
string ToStrHelper<false, VulkanPipelineState::VertexInput::VertexBuffer>::Get(const VulkanPipelineState::VertexInput::VertexBuffer &el) { return "<...>"; }
|
|
template<>
|
|
string ToStrHelper<false, VulkanPipelineState::ViewState::ViewportScissor>::Get(const VulkanPipelineState::ViewState::ViewportScissor &el) { return "<...>"; }
|
|
template<>
|
|
string ToStrHelper<false, VulkanPipelineState::CurrentPass::Framebuffer::Attachment>::Get(const VulkanPipelineState::CurrentPass::Framebuffer::Attachment &el) { return "<...>"; }
|
|
template<>
|
|
string ToStrHelper<false, EventUsage>::Get(const EventUsage &el) { return "<...>"; }
|
|
template<>
|
|
string ToStrHelper<false, CounterResult>::Get(const CounterResult &el) { return "<...>"; }
|
|
template<>
|
|
string ToStrHelper<false, ReplayLogType>::Get(const ReplayLogType &el) { return "<...>"; }
|
|
|
|
#pragma endregion Plain-old data structures
|
|
|
|
ProxySerialiser::~ProxySerialiser()
|
|
{
|
|
SAFE_DELETE(m_FromReplaySerialiser);
|
|
SAFE_DELETE(m_ToReplaySerialiser);
|
|
|
|
if(m_Proxy) m_Proxy->Shutdown();
|
|
m_Proxy = NULL;
|
|
|
|
for(auto it=m_ShaderReflectionCache.begin(); it != m_ShaderReflectionCache.end(); ++it)
|
|
delete it->second;
|
|
}
|
|
|
|
bool ProxySerialiser::SendReplayCommand(CommandPacketType type)
|
|
{
|
|
if(!SendPacket(m_Socket, type, *m_ToReplaySerialiser))
|
|
return false;
|
|
|
|
m_ToReplaySerialiser->Rewind();
|
|
|
|
SAFE_DELETE(m_FromReplaySerialiser);
|
|
|
|
if(!RecvPacket(m_Socket, type, &m_FromReplaySerialiser))
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
void ProxySerialiser::EnsureTexCached(ResourceId texid, uint32_t arrayIdx, uint32_t mip)
|
|
{
|
|
TextureCacheEntry entry = { texid, arrayIdx, mip };
|
|
|
|
if(m_LocalTextures.find(texid) != m_LocalTextures.end())
|
|
return;
|
|
|
|
if(m_TextureProxyCache.find(entry) == m_TextureProxyCache.end())
|
|
{
|
|
if(m_ProxyTextureIds.find(texid) == m_ProxyTextureIds.end())
|
|
{
|
|
FetchTexture tex = GetTexture(texid);
|
|
m_ProxyTextureIds[texid] = m_Proxy->CreateProxyTexture(tex);
|
|
}
|
|
|
|
ResourceId proxyid = m_ProxyTextureIds[texid];
|
|
|
|
size_t size;
|
|
byte *data = GetTextureData(texid, arrayIdx, mip, false, false, 0.0f, 0.0f, size);
|
|
|
|
if(data)
|
|
m_Proxy->SetProxyTextureData(proxyid, arrayIdx, mip, data, size);
|
|
|
|
delete[] data;
|
|
|
|
m_TextureProxyCache.insert(entry);
|
|
}
|
|
}
|
|
|
|
void ProxySerialiser::EnsureBufCached(ResourceId bufid)
|
|
{
|
|
if(m_BufferProxyCache.find(bufid) == m_BufferProxyCache.end())
|
|
{
|
|
if(m_ProxyBufferIds.find(bufid) == m_ProxyBufferIds.end())
|
|
{
|
|
FetchBuffer buf = GetBuffer(bufid);
|
|
m_ProxyBufferIds[bufid] = m_Proxy->CreateProxyBuffer(buf);
|
|
}
|
|
|
|
ResourceId proxyid = m_ProxyBufferIds[bufid];
|
|
|
|
vector<byte> data;
|
|
GetBufferData(bufid, 0, 0, data);
|
|
|
|
if(!data.empty())
|
|
m_Proxy->SetProxyBufferData(proxyid, &data[0], data.size());
|
|
|
|
m_BufferProxyCache.insert(bufid);
|
|
}
|
|
}
|
|
|
|
bool ProxySerialiser::Tick()
|
|
{
|
|
if(!m_ReplayHost) return true;
|
|
|
|
if(!m_Socket) return false;
|
|
|
|
CommandPacketType type;
|
|
|
|
if(!RecvPacket(m_Socket, type, &m_ToReplaySerialiser))
|
|
return false;
|
|
|
|
m_FromReplaySerialiser->Rewind();
|
|
|
|
switch(type)
|
|
{
|
|
case eCommand_SetCtxFilter:
|
|
SetContextFilter(ResourceId(), 0, 0);
|
|
break;
|
|
case eCommand_ReplayLog:
|
|
ReplayLog(0, 0, (ReplayLogType)0);
|
|
break;
|
|
case eCommand_GetPassEvents:
|
|
GetPassEvents(0, 0);
|
|
break;
|
|
case eCommand_GetAPIProperties:
|
|
GetAPIProperties();
|
|
break;
|
|
case eCommand_GetTextures:
|
|
GetTextures();
|
|
break;
|
|
case eCommand_GetTexture:
|
|
GetTexture(ResourceId());
|
|
break;
|
|
case eCommand_GetBuffers:
|
|
GetBuffers();
|
|
break;
|
|
case eCommand_GetBuffer:
|
|
GetBuffer(ResourceId());
|
|
break;
|
|
case eCommand_GetShader:
|
|
GetShader(ResourceId(), "");
|
|
break;
|
|
case eCommand_GetDebugMessages:
|
|
GetDebugMessages();
|
|
break;
|
|
case eCommand_SavePipelineState:
|
|
SavePipelineState();
|
|
break;
|
|
case eCommand_GetUsage:
|
|
GetUsage(ResourceId());
|
|
break;
|
|
case eCommand_GetLiveID:
|
|
GetLiveID(ResourceId());
|
|
break;
|
|
case eCommand_GetFrameRecord:
|
|
GetFrameRecord();
|
|
break;
|
|
case eCommand_HasResolver:
|
|
HasCallstacks();
|
|
break;
|
|
case eCommand_InitStackResolver:
|
|
InitCallstackResolver();
|
|
break;
|
|
case eCommand_HasStackResolver:
|
|
GetCallstackResolver();
|
|
break;
|
|
case eCommand_GetAddressDetails:
|
|
GetAddr(0);
|
|
break;
|
|
case eCommand_FreeResource:
|
|
FreeTargetResource(ResourceId());
|
|
break;
|
|
case eCommand_FetchCounters:
|
|
{
|
|
vector<uint32_t> counters;
|
|
FetchCounters(0, counters);
|
|
break;
|
|
}
|
|
case eCommand_EnumerateCounters:
|
|
EnumerateCounters();
|
|
break;
|
|
case eCommand_DescribeCounter:
|
|
{
|
|
CounterDescription desc;
|
|
DescribeCounter(0, desc);
|
|
break;
|
|
}
|
|
case eCommand_FillCBufferVariables:
|
|
{
|
|
vector<ShaderVariable> vars;
|
|
vector<byte> data;
|
|
FillCBufferVariables(ResourceId(), "", 0, vars, data);
|
|
break;
|
|
}
|
|
case eCommand_GetBufferData:
|
|
{
|
|
vector<byte> dummy;
|
|
GetBufferData(ResourceId(), 0, 0, dummy);
|
|
break;
|
|
}
|
|
case eCommand_GetTextureData:
|
|
{
|
|
size_t dummy;
|
|
GetTextureData(ResourceId(), 0, 0, false, false, 0.0f, 0.0f, dummy);
|
|
break;
|
|
}
|
|
case eCommand_InitPostVS:
|
|
InitPostVSBuffers(0, 0);
|
|
break;
|
|
case eCommand_InitPostVSVec:
|
|
{
|
|
vector<uint32_t> dummy;
|
|
InitPostVSBuffers(0, dummy);
|
|
break;
|
|
}
|
|
case eCommand_GetPostVS:
|
|
GetPostVSBuffers(0, 0, 0, eMeshDataStage_Unknown);
|
|
break;
|
|
case eCommand_BuildTargetShader:
|
|
BuildTargetShader("", "", 0, eShaderStage_Vertex, NULL, NULL);
|
|
break;
|
|
case eCommand_ReplaceResource:
|
|
ReplaceResource(ResourceId(), ResourceId());
|
|
break;
|
|
case eCommand_RemoveReplacement:
|
|
RemoveReplacement(ResourceId());
|
|
break;
|
|
case eCommand_RenderOverlay:
|
|
RenderOverlay(ResourceId(), eTexOverlay_None, 0, 0, vector<uint32_t>());
|
|
break;
|
|
case eCommand_PixelHistory:
|
|
PixelHistory(0, vector<EventUsage>(), ResourceId(), 0, 0, 0, 0, 0);
|
|
break;
|
|
case eCommand_DebugVertex:
|
|
DebugVertex(0, 0, 0, 0, 0, 0, 0);
|
|
break;
|
|
case eCommand_DebugPixel:
|
|
DebugPixel(0, 0, 0, 0, 0, 0);
|
|
break;
|
|
case eCommand_DebugThread:
|
|
{
|
|
uint32_t dummy1[3] = {0};
|
|
uint32_t dummy2[3] = {0};
|
|
DebugThread(0, 0, dummy1, dummy2);
|
|
break;
|
|
}
|
|
default:
|
|
RDCERR("Unexpected command");
|
|
break;
|
|
}
|
|
|
|
SAFE_DELETE(m_ToReplaySerialiser);
|
|
|
|
if(!SendPacket(m_Socket, type, *m_FromReplaySerialiser))
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ProxySerialiser::IsRenderOutput(ResourceId id)
|
|
{
|
|
// TODO this should go remote
|
|
|
|
for(int32_t i=0; i < m_D3D11PipelineState.m_OM.RenderTargets.count; i++)
|
|
{
|
|
if(m_D3D11PipelineState.m_OM.RenderTargets[i].View == id ||
|
|
m_D3D11PipelineState.m_OM.RenderTargets[i].Resource == id)
|
|
return true;
|
|
}
|
|
|
|
if(m_D3D11PipelineState.m_OM.DepthTarget.View == id ||
|
|
m_D3D11PipelineState.m_OM.DepthTarget.Resource == id)
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
APIProperties ProxySerialiser::GetAPIProperties()
|
|
{
|
|
APIProperties ret;
|
|
RDCEraseEl(ret);
|
|
|
|
if(m_ReplayHost)
|
|
{
|
|
ret = m_Remote->GetAPIProperties();
|
|
}
|
|
else
|
|
{
|
|
if(!SendReplayCommand(eCommand_GetAPIProperties))
|
|
return ret;
|
|
}
|
|
|
|
m_FromReplaySerialiser->Serialise("", ret);
|
|
|
|
if(!m_ReplayHost)
|
|
{
|
|
m_APIProperties = ret;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
vector<ResourceId> ProxySerialiser::GetTextures()
|
|
{
|
|
vector<ResourceId> ret;
|
|
|
|
if(m_ReplayHost)
|
|
{
|
|
ret = m_Remote->GetTextures();
|
|
}
|
|
else
|
|
{
|
|
if(!SendReplayCommand(eCommand_GetTextures))
|
|
return ret;
|
|
}
|
|
|
|
m_FromReplaySerialiser->Serialise("", ret);
|
|
|
|
return ret;
|
|
}
|
|
|
|
vector<DebugMessage> ProxySerialiser::GetDebugMessages()
|
|
{
|
|
vector<DebugMessage> ret;
|
|
|
|
if(m_ReplayHost)
|
|
{
|
|
ret = m_Remote->GetDebugMessages();
|
|
}
|
|
else
|
|
{
|
|
if(!SendReplayCommand(eCommand_GetDebugMessages))
|
|
return ret;
|
|
}
|
|
|
|
m_FromReplaySerialiser->Serialise("", ret);
|
|
|
|
return ret;
|
|
}
|
|
|
|
FetchTexture ProxySerialiser::GetTexture(ResourceId id)
|
|
{
|
|
FetchTexture ret;
|
|
|
|
m_ToReplaySerialiser->Serialise("", id);
|
|
|
|
if(m_ReplayHost)
|
|
{
|
|
ret = m_Remote->GetTexture(id);
|
|
}
|
|
else
|
|
{
|
|
if(!SendReplayCommand(eCommand_GetTexture))
|
|
return ret;
|
|
}
|
|
|
|
m_FromReplaySerialiser->Serialise("", ret);
|
|
|
|
return ret;
|
|
}
|
|
|
|
vector<ResourceId> ProxySerialiser::GetBuffers()
|
|
{
|
|
vector<ResourceId> ret;
|
|
|
|
if(m_ReplayHost)
|
|
{
|
|
ret = m_Remote->GetBuffers();
|
|
}
|
|
else
|
|
{
|
|
if(!SendReplayCommand(eCommand_GetBuffers))
|
|
return ret;
|
|
}
|
|
|
|
m_FromReplaySerialiser->Serialise("", ret);
|
|
|
|
return ret;
|
|
}
|
|
|
|
FetchBuffer ProxySerialiser::GetBuffer(ResourceId id)
|
|
{
|
|
FetchBuffer ret;
|
|
|
|
m_ToReplaySerialiser->Serialise("", id);
|
|
|
|
if(m_ReplayHost)
|
|
{
|
|
ret = m_Remote->GetBuffer(id);
|
|
}
|
|
else
|
|
{
|
|
if(!SendReplayCommand(eCommand_GetBuffer))
|
|
return ret;
|
|
}
|
|
|
|
m_FromReplaySerialiser->Serialise("", ret);
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
void ProxySerialiser::SavePipelineState()
|
|
{
|
|
if(m_ReplayHost)
|
|
{
|
|
m_Remote->SavePipelineState();
|
|
m_D3D11PipelineState = m_Remote->GetD3D11PipelineState();
|
|
m_GLPipelineState = m_Remote->GetGLPipelineState();
|
|
m_VulkanPipelineState = m_Remote->GetVulkanPipelineState();
|
|
}
|
|
else
|
|
{
|
|
if(!SendReplayCommand(eCommand_SavePipelineState))
|
|
return;
|
|
|
|
m_D3D11PipelineState = D3D11PipelineState();
|
|
m_GLPipelineState = GLPipelineState();
|
|
m_VulkanPipelineState = VulkanPipelineState();
|
|
}
|
|
|
|
m_FromReplaySerialiser->Serialise("", m_D3D11PipelineState);
|
|
m_FromReplaySerialiser->Serialise("", m_GLPipelineState);
|
|
m_FromReplaySerialiser->Serialise("", m_VulkanPipelineState);
|
|
}
|
|
|
|
void ProxySerialiser::SetContextFilter(ResourceId id, uint32_t firstDefEv, uint32_t lastDefEv)
|
|
{
|
|
m_ToReplaySerialiser->Serialise("", id);
|
|
m_ToReplaySerialiser->Serialise("", firstDefEv);
|
|
m_ToReplaySerialiser->Serialise("", lastDefEv);
|
|
|
|
if(m_ReplayHost)
|
|
{
|
|
m_Remote->SetContextFilter(id, firstDefEv, lastDefEv);
|
|
}
|
|
else
|
|
{
|
|
if(!SendReplayCommand(eCommand_SetCtxFilter))
|
|
return;
|
|
}
|
|
}
|
|
|
|
void ProxySerialiser::ReplayLog(uint32_t frameID, uint32_t endEventID, ReplayLogType replayType)
|
|
{
|
|
m_ToReplaySerialiser->Serialise("", frameID);
|
|
m_ToReplaySerialiser->Serialise("", endEventID);
|
|
m_ToReplaySerialiser->Serialise("", replayType);
|
|
|
|
if(m_ReplayHost)
|
|
{
|
|
m_Remote->ReplayLog(frameID, endEventID, replayType);
|
|
}
|
|
else
|
|
{
|
|
if(!SendReplayCommand(eCommand_ReplayLog))
|
|
return;
|
|
|
|
m_TextureProxyCache.clear();
|
|
m_BufferProxyCache.clear();
|
|
}
|
|
}
|
|
|
|
vector<uint32_t> ProxySerialiser::GetPassEvents(uint32_t frameID, uint32_t eventID)
|
|
{
|
|
vector<uint32_t> ret;
|
|
|
|
m_ToReplaySerialiser->Serialise("", frameID);
|
|
m_ToReplaySerialiser->Serialise("", eventID);
|
|
|
|
if(m_ReplayHost)
|
|
{
|
|
ret = m_Remote->GetPassEvents(frameID, eventID);
|
|
}
|
|
else
|
|
{
|
|
if(!SendReplayCommand(eCommand_GetPassEvents))
|
|
return ret;
|
|
}
|
|
|
|
m_FromReplaySerialiser->Serialise("", ret);
|
|
|
|
return ret;
|
|
}
|
|
|
|
vector<EventUsage> ProxySerialiser::GetUsage(ResourceId id)
|
|
{
|
|
vector<EventUsage> ret;
|
|
|
|
m_ToReplaySerialiser->Serialise("", id);
|
|
|
|
if(m_ReplayHost)
|
|
{
|
|
ret = m_Remote->GetUsage(id);
|
|
}
|
|
else
|
|
{
|
|
if(!SendReplayCommand(eCommand_GetUsage))
|
|
return ret;
|
|
}
|
|
|
|
m_FromReplaySerialiser->Serialise("", ret);
|
|
|
|
return ret;
|
|
}
|
|
|
|
vector<FetchFrameRecord> ProxySerialiser::GetFrameRecord()
|
|
{
|
|
vector<FetchFrameRecord> ret;
|
|
|
|
if(m_ReplayHost)
|
|
{
|
|
ret = m_Remote->GetFrameRecord();
|
|
}
|
|
else
|
|
{
|
|
if(!SendReplayCommand(eCommand_GetFrameRecord))
|
|
return ret;
|
|
}
|
|
|
|
m_FromReplaySerialiser->Serialise("", ret);
|
|
|
|
return ret;
|
|
}
|
|
|
|
bool ProxySerialiser::HasCallstacks()
|
|
{
|
|
bool ret = false;
|
|
|
|
RDCASSERT(m_ReplayHost || m_ToReplaySerialiser->GetSize() == 0);
|
|
|
|
if(m_ReplayHost)
|
|
{
|
|
ret = m_Remote->HasCallstacks();
|
|
}
|
|
else
|
|
{
|
|
if(!SendReplayCommand(eCommand_HasResolver))
|
|
return ret;
|
|
}
|
|
|
|
RDCASSERT(!m_ReplayHost || m_FromReplaySerialiser->GetSize() == 0);
|
|
|
|
m_FromReplaySerialiser->Serialise("", ret);
|
|
|
|
return ret;
|
|
}
|
|
|
|
ResourceId ProxySerialiser::GetLiveID(ResourceId id)
|
|
{
|
|
if(!m_ReplayHost && m_LiveIDs.find(id) != m_LiveIDs.end())
|
|
return m_LiveIDs[id];
|
|
|
|
if(!m_ReplayHost && m_LocalTextures.find(id) != m_LocalTextures.end())
|
|
return id;
|
|
|
|
ResourceId ret;
|
|
|
|
RDCASSERT(m_ReplayHost || m_ToReplaySerialiser->GetSize() == 0);
|
|
|
|
m_ToReplaySerialiser->Serialise("", id);
|
|
|
|
if(m_ReplayHost)
|
|
{
|
|
ret = m_Remote->GetLiveID(id);
|
|
}
|
|
else
|
|
{
|
|
if(!SendReplayCommand(eCommand_GetLiveID))
|
|
return ret;
|
|
}
|
|
|
|
RDCASSERT(!m_ReplayHost || m_FromReplaySerialiser->GetSize() == 0);
|
|
|
|
m_FromReplaySerialiser->Serialise("", ret);
|
|
|
|
if(!m_ReplayHost)
|
|
m_LiveIDs[id] = ret;
|
|
|
|
return ret;
|
|
}
|
|
|
|
vector<CounterResult> ProxySerialiser::FetchCounters(uint32_t frameID, const vector<uint32_t> &counters)
|
|
{
|
|
vector<CounterResult> ret;
|
|
|
|
m_ToReplaySerialiser->Serialise("", frameID);
|
|
m_ToReplaySerialiser->Serialise("", (vector<uint32_t> &)counters);
|
|
|
|
if(m_ReplayHost)
|
|
{
|
|
ret = m_Remote->FetchCounters(frameID, counters);
|
|
}
|
|
else
|
|
{
|
|
if(!SendReplayCommand(eCommand_FetchCounters))
|
|
return ret;
|
|
}
|
|
|
|
m_FromReplaySerialiser->Serialise("", ret);
|
|
|
|
return ret;
|
|
}
|
|
|
|
vector<uint32_t> ProxySerialiser::EnumerateCounters()
|
|
{
|
|
vector<uint32_t> ret;
|
|
|
|
if(m_ReplayHost)
|
|
{
|
|
ret = m_Remote->EnumerateCounters();
|
|
}
|
|
else
|
|
{
|
|
if(!SendReplayCommand(eCommand_EnumerateCounters))
|
|
return ret;
|
|
}
|
|
|
|
m_FromReplaySerialiser->Serialise("", ret);
|
|
|
|
return ret;
|
|
}
|
|
|
|
void ProxySerialiser::DescribeCounter(uint32_t counterID, CounterDescription &desc)
|
|
{
|
|
m_ToReplaySerialiser->Serialise("", counterID);
|
|
|
|
if(m_ReplayHost)
|
|
{
|
|
m_Remote->DescribeCounter(counterID, desc);
|
|
}
|
|
else
|
|
{
|
|
if(!SendReplayCommand(eCommand_DescribeCounter))
|
|
return;
|
|
}
|
|
|
|
m_FromReplaySerialiser->Serialise("", desc);
|
|
|
|
return;
|
|
}
|
|
|
|
void ProxySerialiser::FillCBufferVariables(ResourceId shader, string entryPoint, uint32_t cbufSlot, vector<ShaderVariable> &outvars, const vector<byte> &data)
|
|
{
|
|
m_ToReplaySerialiser->Serialise("", shader);
|
|
m_ToReplaySerialiser->Serialise("", entryPoint);
|
|
m_ToReplaySerialiser->Serialise("", cbufSlot);
|
|
m_ToReplaySerialiser->Serialise("", outvars);
|
|
m_ToReplaySerialiser->Serialise("", (vector<byte> &)data);
|
|
|
|
if(m_ReplayHost)
|
|
{
|
|
m_Remote->FillCBufferVariables(shader, entryPoint, cbufSlot, outvars, data);
|
|
}
|
|
else
|
|
{
|
|
if(!SendReplayCommand(eCommand_FillCBufferVariables))
|
|
return;
|
|
}
|
|
|
|
m_FromReplaySerialiser->Serialise("", outvars);
|
|
|
|
return;
|
|
}
|
|
|
|
void ProxySerialiser::GetBufferData(ResourceId buff, uint64_t offset, uint64_t len, vector<byte> &retData)
|
|
{
|
|
m_ToReplaySerialiser->Serialise("", buff);
|
|
m_ToReplaySerialiser->Serialise("", offset);
|
|
m_ToReplaySerialiser->Serialise("", len);
|
|
|
|
if(m_ReplayHost)
|
|
{
|
|
m_Remote->GetBufferData(buff, offset, len, retData);
|
|
|
|
size_t sz = retData.size();
|
|
m_FromReplaySerialiser->Serialise("", sz);
|
|
m_FromReplaySerialiser->RawWriteBytes(&retData[0], sz);
|
|
}
|
|
else
|
|
{
|
|
if(!SendReplayCommand(eCommand_GetBufferData))
|
|
return;
|
|
|
|
size_t sz = 0;
|
|
m_FromReplaySerialiser->Serialise("", sz);
|
|
retData.resize(sz);
|
|
memcpy(&retData[0], m_FromReplaySerialiser->RawReadBytes(sz), sz);
|
|
}
|
|
}
|
|
|
|
byte *ProxySerialiser::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, bool resolve, bool forceRGBA8unorm,
|
|
float blackPoint, float whitePoint, size_t &dataSize)
|
|
{
|
|
m_ToReplaySerialiser->Serialise("", tex);
|
|
m_ToReplaySerialiser->Serialise("", arrayIdx);
|
|
m_ToReplaySerialiser->Serialise("", mip);
|
|
m_ToReplaySerialiser->Serialise("", resolve);
|
|
m_ToReplaySerialiser->Serialise("", forceRGBA8unorm);
|
|
m_ToReplaySerialiser->Serialise("", blackPoint);
|
|
m_ToReplaySerialiser->Serialise("", whitePoint);
|
|
|
|
if(m_ReplayHost)
|
|
{
|
|
byte *data = m_Remote->GetTextureData(tex, arrayIdx, mip, resolve, forceRGBA8unorm, blackPoint, whitePoint, dataSize);
|
|
|
|
byte *compressed = new byte[dataSize+512];
|
|
|
|
size_t compressedSize = (size_t)LZ4_compress((const char *)data, (char *)compressed, (int)dataSize);
|
|
|
|
m_FromReplaySerialiser->Serialise("", dataSize);
|
|
m_FromReplaySerialiser->Serialise("", compressedSize);
|
|
m_FromReplaySerialiser->RawWriteBytes(compressed, compressedSize);
|
|
|
|
delete[] data;
|
|
delete[] compressed;
|
|
}
|
|
else
|
|
{
|
|
if(!SendReplayCommand(eCommand_GetTextureData))
|
|
return NULL;
|
|
|
|
size_t compressedSize;
|
|
|
|
m_FromReplaySerialiser->Serialise("", dataSize);
|
|
m_FromReplaySerialiser->Serialise("", compressedSize);
|
|
|
|
byte *ret = new byte[dataSize+512];
|
|
|
|
byte *compressed = (byte *)m_FromReplaySerialiser->RawReadBytes(compressedSize);
|
|
|
|
size_t uncompSize = (size_t)LZ4_decompress_fast((const char *)compressed, (char *)ret, (int)dataSize);
|
|
|
|
return ret;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
void ProxySerialiser::InitPostVSBuffers(uint32_t frameID, uint32_t eventID)
|
|
{
|
|
m_ToReplaySerialiser->Serialise("", frameID);
|
|
m_ToReplaySerialiser->Serialise("", eventID);
|
|
|
|
if(m_ReplayHost)
|
|
{
|
|
m_Remote->InitPostVSBuffers(frameID, eventID);
|
|
}
|
|
else
|
|
{
|
|
if(!SendReplayCommand(eCommand_InitPostVS))
|
|
return;
|
|
}
|
|
}
|
|
|
|
void ProxySerialiser::InitPostVSBuffers(uint32_t frameID, const vector<uint32_t> &events)
|
|
{
|
|
m_ToReplaySerialiser->Serialise("", frameID);
|
|
m_ToReplaySerialiser->Serialise("", (vector<uint32_t> &)events);
|
|
|
|
if(m_ReplayHost)
|
|
{
|
|
m_Remote->InitPostVSBuffers(frameID, events);
|
|
}
|
|
else
|
|
{
|
|
if(!SendReplayCommand(eCommand_InitPostVSVec))
|
|
return;
|
|
}
|
|
}
|
|
|
|
MeshFormat ProxySerialiser::GetPostVSBuffers(uint32_t frameID, uint32_t eventID, uint32_t instID, MeshDataStage stage)
|
|
{
|
|
MeshFormat ret;
|
|
|
|
m_ToReplaySerialiser->Serialise("", frameID);
|
|
m_ToReplaySerialiser->Serialise("", eventID);
|
|
m_ToReplaySerialiser->Serialise("", instID);
|
|
m_ToReplaySerialiser->Serialise("", stage);
|
|
|
|
if(m_ReplayHost)
|
|
{
|
|
ret = m_Remote->GetPostVSBuffers(frameID, eventID, instID, stage);
|
|
}
|
|
else
|
|
{
|
|
if(!SendReplayCommand(eCommand_GetPostVS))
|
|
return ret;
|
|
}
|
|
|
|
m_FromReplaySerialiser->Serialise("", ret);
|
|
|
|
return ret;
|
|
}
|
|
|
|
ResourceId ProxySerialiser::RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, uint32_t frameID, uint32_t eventID, const vector<uint32_t> &passEvents)
|
|
{
|
|
ResourceId ret;
|
|
|
|
vector<uint32_t> events = passEvents;
|
|
|
|
m_ToReplaySerialiser->Serialise("", texid);
|
|
m_ToReplaySerialiser->Serialise("", overlay);
|
|
m_ToReplaySerialiser->Serialise("", frameID);
|
|
m_ToReplaySerialiser->Serialise("", eventID);
|
|
m_ToReplaySerialiser->Serialise("", events);
|
|
|
|
if(m_ReplayHost)
|
|
{
|
|
ret = m_Remote->RenderOverlay(texid, overlay, frameID, eventID, events);
|
|
}
|
|
else
|
|
{
|
|
if(!SendReplayCommand(eCommand_RenderOverlay))
|
|
return ret;
|
|
}
|
|
|
|
m_FromReplaySerialiser->Serialise("", ret);
|
|
|
|
return ret;
|
|
}
|
|
|
|
ShaderReflection *ProxySerialiser::GetShader(ResourceId id, string entryPoint)
|
|
{
|
|
if(m_ReplayHost)
|
|
{
|
|
m_ToReplaySerialiser->Serialise("", id);
|
|
m_ToReplaySerialiser->Serialise("", entryPoint);
|
|
|
|
ShaderReflection *refl = m_Remote->GetShader(id, entryPoint);
|
|
|
|
bool hasrefl = (refl != NULL);
|
|
m_FromReplaySerialiser->Serialise("", hasrefl);
|
|
|
|
if(hasrefl)
|
|
m_FromReplaySerialiser->Serialise("", *refl);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
ShaderReflKey key(id, entryPoint);
|
|
|
|
if(m_ShaderReflectionCache.find(key) == m_ShaderReflectionCache.end())
|
|
{
|
|
m_ToReplaySerialiser->Serialise("", id);
|
|
m_ToReplaySerialiser->Serialise("", entryPoint);
|
|
|
|
if(!SendReplayCommand(eCommand_GetShader))
|
|
return NULL;
|
|
|
|
bool hasrefl = false;
|
|
m_FromReplaySerialiser->Serialise("", hasrefl);
|
|
|
|
if(hasrefl)
|
|
{
|
|
m_ShaderReflectionCache[key] = new ShaderReflection();
|
|
|
|
m_FromReplaySerialiser->Serialise("", *m_ShaderReflectionCache[key]);
|
|
}
|
|
else
|
|
{
|
|
m_ShaderReflectionCache[key] = NULL;
|
|
}
|
|
}
|
|
|
|
return m_ShaderReflectionCache[key];
|
|
}
|
|
|
|
void ProxySerialiser::FreeTargetResource(ResourceId id)
|
|
{
|
|
m_ToReplaySerialiser->Serialise("", id);
|
|
|
|
if(m_ReplayHost)
|
|
{
|
|
m_Remote->FreeTargetResource(id);
|
|
}
|
|
else
|
|
{
|
|
if(!SendReplayCommand(eCommand_FreeResource))
|
|
return;
|
|
}
|
|
}
|
|
|
|
void ProxySerialiser::InitCallstackResolver()
|
|
{
|
|
if(m_ReplayHost)
|
|
{
|
|
m_Remote->InitCallstackResolver();
|
|
}
|
|
else
|
|
{
|
|
if(!SendReplayCommand(eCommand_InitStackResolver))
|
|
return;
|
|
}
|
|
}
|
|
|
|
Callstack::StackResolver *ProxySerialiser::GetCallstackResolver()
|
|
{
|
|
if(m_RemoteHasResolver) return this;
|
|
|
|
bool remoteHasResolver = false;
|
|
|
|
if(m_ReplayHost)
|
|
{
|
|
remoteHasResolver = m_Remote->GetCallstackResolver() != NULL;
|
|
}
|
|
else
|
|
{
|
|
if(!SendReplayCommand(eCommand_HasStackResolver))
|
|
return NULL;
|
|
}
|
|
|
|
m_FromReplaySerialiser->Serialise("", remoteHasResolver);
|
|
|
|
if(remoteHasResolver)
|
|
{
|
|
if(!m_ReplayHost)
|
|
m_RemoteHasResolver = true;
|
|
|
|
return this;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
Callstack::AddressDetails ProxySerialiser::GetAddr(uint64_t addr)
|
|
{
|
|
Callstack::AddressDetails ret;
|
|
|
|
if(m_ReplayHost)
|
|
{
|
|
Callstack::StackResolver *resolv = m_Remote->GetCallstackResolver();
|
|
if(resolv) ret = resolv->GetAddr(addr);
|
|
}
|
|
else
|
|
{
|
|
if(!SendReplayCommand(eCommand_HasStackResolver))
|
|
return ret;
|
|
}
|
|
|
|
m_FromReplaySerialiser->Serialise("", ret.filename);
|
|
m_FromReplaySerialiser->Serialise("", ret.function);
|
|
m_FromReplaySerialiser->Serialise("", ret.line);
|
|
|
|
return ret;
|
|
}
|
|
|
|
void ProxySerialiser::BuildTargetShader(string source, string entry, const uint32_t compileFlags, ShaderStageType type, ResourceId *id, string *errors)
|
|
{
|
|
uint32_t flags = compileFlags;
|
|
m_ToReplaySerialiser->Serialise("", source);
|
|
m_ToReplaySerialiser->Serialise("", entry);
|
|
m_ToReplaySerialiser->Serialise("", flags);
|
|
m_ToReplaySerialiser->Serialise("", type);
|
|
|
|
ResourceId outId;
|
|
string outErrs;
|
|
|
|
if(m_ReplayHost)
|
|
{
|
|
m_Remote->BuildTargetShader(source, entry, flags, type, &outId, &outErrs);
|
|
}
|
|
else
|
|
{
|
|
if(!SendReplayCommand(eCommand_BuildTargetShader))
|
|
return;
|
|
}
|
|
|
|
m_FromReplaySerialiser->Serialise("", outId);
|
|
m_FromReplaySerialiser->Serialise("", outErrs);
|
|
|
|
if(!m_ReplayHost)
|
|
{
|
|
if(id) *id = outId;
|
|
if(errors) *errors = outErrs;
|
|
}
|
|
}
|
|
|
|
void ProxySerialiser::ReplaceResource(ResourceId from, ResourceId to)
|
|
{
|
|
m_ToReplaySerialiser->Serialise("", from);
|
|
m_ToReplaySerialiser->Serialise("", to);
|
|
|
|
if(m_ReplayHost)
|
|
{
|
|
m_Remote->ReplaceResource(from, to);
|
|
}
|
|
else
|
|
{
|
|
if(!SendReplayCommand(eCommand_ReplaceResource))
|
|
return;
|
|
}
|
|
}
|
|
|
|
void ProxySerialiser::RemoveReplacement(ResourceId id)
|
|
{
|
|
m_ToReplaySerialiser->Serialise("", id);
|
|
|
|
if(m_ReplayHost)
|
|
{
|
|
m_Remote->RemoveReplacement(id);
|
|
}
|
|
else
|
|
{
|
|
if(!SendReplayCommand(eCommand_RemoveReplacement))
|
|
return;
|
|
}
|
|
}
|
|
|
|
vector<PixelModification> ProxySerialiser::PixelHistory(uint32_t frameID, vector<EventUsage> events, ResourceId target, uint32_t x, uint32_t y, uint32_t slice, uint32_t mip, uint32_t sampleIdx)
|
|
{
|
|
vector<PixelModification> ret;
|
|
|
|
m_ToReplaySerialiser->Serialise("", frameID);
|
|
m_ToReplaySerialiser->Serialise("", events);
|
|
m_ToReplaySerialiser->Serialise("", target);
|
|
m_ToReplaySerialiser->Serialise("", x);
|
|
m_ToReplaySerialiser->Serialise("", y);
|
|
m_ToReplaySerialiser->Serialise("", slice);
|
|
m_ToReplaySerialiser->Serialise("", mip);
|
|
m_ToReplaySerialiser->Serialise("", sampleIdx);
|
|
|
|
if(m_ReplayHost)
|
|
{
|
|
ret = m_Remote->PixelHistory(frameID, events, target, x, y, slice, mip, sampleIdx);
|
|
}
|
|
else
|
|
{
|
|
if(!SendReplayCommand(eCommand_PixelHistory))
|
|
return ret;
|
|
}
|
|
|
|
m_FromReplaySerialiser->Serialise("", ret);
|
|
|
|
return ret;
|
|
}
|
|
|
|
ShaderDebugTrace ProxySerialiser::DebugVertex(uint32_t frameID, uint32_t eventID, uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset, uint32_t vertOffset)
|
|
{
|
|
ShaderDebugTrace ret;
|
|
|
|
m_ToReplaySerialiser->Serialise("", frameID);
|
|
m_ToReplaySerialiser->Serialise("", eventID);
|
|
m_ToReplaySerialiser->Serialise("", vertid);
|
|
m_ToReplaySerialiser->Serialise("", instid);
|
|
m_ToReplaySerialiser->Serialise("", idx);
|
|
m_ToReplaySerialiser->Serialise("", instOffset);
|
|
m_ToReplaySerialiser->Serialise("", vertOffset);
|
|
|
|
if(m_ReplayHost)
|
|
{
|
|
ret = m_Remote->DebugVertex(frameID, eventID, vertid, instid, idx, instOffset, vertOffset);
|
|
}
|
|
else
|
|
{
|
|
if(!SendReplayCommand(eCommand_DebugVertex))
|
|
return ret;
|
|
}
|
|
|
|
m_FromReplaySerialiser->Serialise("", ret);
|
|
|
|
return ret;
|
|
}
|
|
|
|
ShaderDebugTrace ProxySerialiser::DebugPixel(uint32_t frameID, uint32_t eventID, uint32_t x, uint32_t y, uint32_t sample, uint32_t primitive)
|
|
{
|
|
ShaderDebugTrace ret;
|
|
|
|
m_ToReplaySerialiser->Serialise("", frameID);
|
|
m_ToReplaySerialiser->Serialise("", eventID);
|
|
m_ToReplaySerialiser->Serialise("", x);
|
|
m_ToReplaySerialiser->Serialise("", y);
|
|
m_ToReplaySerialiser->Serialise("", sample);
|
|
m_ToReplaySerialiser->Serialise("", primitive);
|
|
|
|
if(m_ReplayHost)
|
|
{
|
|
ret = m_Remote->DebugPixel(frameID, eventID, x, y, sample, primitive);
|
|
}
|
|
else
|
|
{
|
|
if(!SendReplayCommand(eCommand_DebugPixel))
|
|
return ret;
|
|
}
|
|
|
|
m_FromReplaySerialiser->Serialise("", ret);
|
|
|
|
return ret;
|
|
}
|
|
|
|
ShaderDebugTrace ProxySerialiser::DebugThread(uint32_t frameID, uint32_t eventID, uint32_t groupid[3], uint32_t threadid[3])
|
|
{
|
|
ShaderDebugTrace ret;
|
|
|
|
m_ToReplaySerialiser->Serialise("", frameID);
|
|
m_ToReplaySerialiser->Serialise("", eventID);
|
|
m_ToReplaySerialiser->SerialisePODArray<3>("", groupid);
|
|
m_ToReplaySerialiser->SerialisePODArray<3>("", threadid);
|
|
|
|
if(m_ReplayHost)
|
|
{
|
|
ret = m_Remote->DebugThread(frameID, eventID, groupid, threadid);
|
|
}
|
|
else
|
|
{
|
|
if(!SendReplayCommand(eCommand_DebugThread))
|
|
return ret;
|
|
}
|
|
|
|
m_FromReplaySerialiser->Serialise("", ret);
|
|
|
|
return ret;
|
|
}
|