From b992e95f94c30d92137bde4cc61313e9262327bf Mon Sep 17 00:00:00 2001 From: baldurk Date: Wed, 13 Sep 2017 15:50:51 +0100 Subject: [PATCH] Update replay proxy to use new serialisation mechanism --- .../D3D11PipelineStateViewer.cpp | 4 +- .../D3D12PipelineStateViewer.cpp | 4 +- .../PipelineState/PipelineStateViewer.cpp | 8 +- .../VulkanPipelineStateViewer.cpp | 4 +- qrenderdoc/Windows/ShaderViewer.cpp | 28 +- renderdoc/api/replay/data_types.h | 6 + renderdoc/api/replay/shader_types.h | 38 +- renderdoc/core/image_viewer.cpp | 11 +- renderdoc/core/replay_proxy.cpp | 4135 +++++------------ renderdoc/core/replay_proxy.h | 170 +- renderdoc/driver/d3d11/d3d11_analyse.cpp | 80 +- renderdoc/driver/d3d11/d3d11_counters.cpp | 9 +- renderdoc/driver/d3d11/d3d11_debug.h | 6 +- renderdoc/driver/d3d11/d3d11_replay.cpp | 11 +- renderdoc/driver/d3d11/d3d11_replay.h | 6 +- renderdoc/driver/d3d12/d3d12_replay.cpp | 1 + renderdoc/driver/gl/gl_replay.cpp | 1 + renderdoc/driver/shaders/dxbc/dxbc_debug.cpp | 24 +- .../driver/shaders/dxbc/dxbc_inspect.cpp | 4 +- .../driver/shaders/dxbc/dxbc_reflect.cpp | 8 +- .../shaders/spirv/spirv_disassemble.cpp | 4 +- renderdoc/driver/vulkan/vk_counters.cpp | 5 +- renderdoc/driver/vulkan/vk_replay.cpp | 34 +- renderdoc/driver/vulkan/vk_replay.h | 6 +- renderdoc/replay/renderdoc_serialise.inl | 18 + renderdoc/replay/replay_controller.cpp | 31 +- renderdoc/replay/replay_driver.cpp | 28 + renderdoc/replay/replay_driver.h | 28 +- 28 files changed, 1585 insertions(+), 3127 deletions(-) diff --git a/qrenderdoc/Windows/PipelineState/D3D11PipelineStateViewer.cpp b/qrenderdoc/Windows/PipelineState/D3D11PipelineStateViewer.cpp index 88412d6c9..382f7a4df 100644 --- a/qrenderdoc/Windows/PipelineState/D3D11PipelineStateViewer.cpp +++ b/qrenderdoc/Windows/PipelineState/D3D11PipelineStateViewer.cpp @@ -856,7 +856,7 @@ void D3D11PipelineStateViewer::setShaderState(const D3D11Pipe::Shader &stage, QL { shader->setText(QFormatStr("%1() - %2") .arg(shaderDetails->EntryPoint) - .arg(QFileInfo(shaderDetails->DebugInfo.files[0].first).fileName())); + .arg(QFileInfo(shaderDetails->DebugInfo.files[0].Filename).fileName())); } int vs = 0; @@ -2549,7 +2549,7 @@ void D3D11PipelineStateViewer::exportHTML(QXmlStreamWriter &xml, const D3D11Pipe { shadername = QFormatStr("%1() - %2") .arg(shaderDetails->EntryPoint) - .arg(QFileInfo(shaderDetails->DebugInfo.files[0].first).fileName()); + .arg(QFileInfo(shaderDetails->DebugInfo.files[0].Filename).fileName()); } xml.writeStartElement(lit("p")); diff --git a/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.cpp b/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.cpp index 6d16d62b6..69b3ef06b 100644 --- a/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.cpp +++ b/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.cpp @@ -926,7 +926,7 @@ void D3D12PipelineStateViewer::setShaderState(const D3D12Pipe::Shader &stage, QL { shader->setText(QFormatStr("%1() - %2") .arg(shaderDetails->EntryPoint) - .arg(QFileInfo(shaderDetails->DebugInfo.files[0].first).fileName())); + .arg(QFileInfo(shaderDetails->DebugInfo.files[0].Filename).fileName())); } int vs = 0; @@ -2378,7 +2378,7 @@ void D3D12PipelineStateViewer::exportHTML(QXmlStreamWriter &xml, const D3D12Pipe { shadername = QFormatStr("%1() - %2") .arg(shaderDetails->EntryPoint) - .arg(QFileInfo(shaderDetails->DebugInfo.files[0].first).fileName()); + .arg(QFileInfo(shaderDetails->DebugInfo.files[0].Filename).fileName()); } xml.writeStartElement(lit("p")); diff --git a/qrenderdoc/Windows/PipelineState/PipelineStateViewer.cpp b/qrenderdoc/Windows/PipelineState/PipelineStateViewer.cpp index 0201752ec..3e27ae616 100644 --- a/qrenderdoc/Windows/PipelineState/PipelineStateViewer.cpp +++ b/qrenderdoc/Windows/PipelineState/PipelineStateViewer.cpp @@ -550,18 +550,18 @@ bool PipelineStateViewer::PrepareShaderEditing(const ShaderReflection *shaderDet for(auto &s : shaderDetails->DebugInfo.files) { - QString filename = s.first; + QString filename = s.Filename; if(uniqueFiles.contains(filename.toLower())) { - qWarning() << lit("Duplicate full filename") << QString(s.first); + qWarning() << lit("Duplicate full filename") << filename; continue; } uniqueFiles.push_back(filename.toLower()); - files[filename] = s.second; + files[filename] = s.Contents; } - mainfile = shaderDetails->DebugInfo.files[0].first; + mainfile = shaderDetails->DebugInfo.files[0].Filename; return true; } diff --git a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp b/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp index 5926820c4..a23ae66de 100644 --- a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp +++ b/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp @@ -1278,7 +1278,7 @@ void VulkanPipelineStateViewer::setShaderState(const VKPipe::Shader &stage, if(!shaderDetails->DebugInfo.files.isEmpty()) shader->setText(entryFunc + lit("() - ") + - QFileInfo(shaderDetails->DebugInfo.files[0].first).fileName()); + QFileInfo(shaderDetails->DebugInfo.files[0].Filename).fileName()); } int vs = 0; @@ -2595,7 +2595,7 @@ void VulkanPipelineStateViewer::exportHTML(QXmlStreamWriter &xml, const VKPipe:: else if(!shaderDetails->DebugInfo.files.isEmpty()) shadername = QFormatStr("%1() - %2") .arg(entryFunc) - .arg(QFileInfo(shaderDetails->DebugInfo.files[0].first).fileName()); + .arg(QFileInfo(shaderDetails->DebugInfo.files[0].Filename).fileName()); } xml.writeStartElement(lit("p")); diff --git a/qrenderdoc/Windows/ShaderViewer.cpp b/qrenderdoc/Windows/ShaderViewer.cpp index ba301b1ac..245af6448 100644 --- a/qrenderdoc/Windows/ShaderViewer.cpp +++ b/qrenderdoc/Windows/ShaderViewer.cpp @@ -364,10 +364,10 @@ void ShaderViewer::debugShader(const ShaderBindpointMapping *bind, const ShaderR int fileIdx = 0; QWidget *sel = NULL; - for(auto &f : shader->DebugInfo.files) + for(const ShaderSourceFile &f : shader->DebugInfo.files) { - QString name = QFileInfo(f.first).fileName(); - QString text = f.second; + QString name = QFileInfo(f.Filename).fileName(); + QString text = f.Contents; ScintillaEdit *scintilla = AddFileScintilla(name, text); @@ -1135,13 +1135,13 @@ void ShaderViewer::updateDebugging() { for(int i = 0; i < m_Trace->cbuffers.count(); i++) { - for(int j = 0; j < m_Trace->cbuffers[i].count(); j++) + for(int j = 0; j < m_Trace->cbuffers[i].members.count(); j++) { - if(m_Trace->cbuffers[i][j].rows > 0 || m_Trace->cbuffers[i][j].columns > 0) + if(m_Trace->cbuffers[i].members[j].rows > 0 || m_Trace->cbuffers[i].members[j].columns > 0) { RDTreeWidgetItem *node = - new RDTreeWidgetItem({m_Trace->cbuffers[i][j].name, lit("cbuffer"), - stringRep(m_Trace->cbuffers[i][j], false)}); + new RDTreeWidgetItem({m_Trace->cbuffers[i].members[j].name, lit("cbuffer"), + stringRep(m_Trace->cbuffers[i].members[j], false)}); node->setTag(QVariant::fromValue(VariableTag(VariableCategory::Constants, j, i))); ui->constants->addTopLevelItem(node); @@ -1251,9 +1251,9 @@ void ShaderViewer::updateDebugging() { RDTreeWidgetItem *node = new RDTreeWidgetItem({QFormatStr("x%1").arg(i), lit("indexable"), QString()}); - for(int t = 0; t < state.indexableTemps[i].count(); t++) - node->addChild( - new RDTreeWidgetItem({state.indexableTemps[i][t].name, lit("indexable"), QString()})); + for(int t = 0; t < state.indexableTemps[i].members.count(); t++) + node->addChild(new RDTreeWidgetItem( + {state.indexableTemps[i].members[t].name, lit("indexable"), QString()})); ui->variables->addTopLevelItem(node); } @@ -1278,11 +1278,11 @@ void ShaderViewer::updateDebugging() { RDTreeWidgetItem *node = ui->variables->topLevelItem(v++); - for(int t = 0; t < state.indexableTemps[i].count(); t++) + for(int t = 0; t < state.indexableTemps[i].members.count(); t++) { RDTreeWidgetItem *child = node->child(t); - child->setText(2, stringRep(state.indexableTemps[i][t], false)); + child->setText(2, stringRep(state.indexableTemps[i].members[t], false)); child->setTag(QVariant::fromValue(VariableTag(VariableCategory::IndexTemporaries, t, i))); } } @@ -1928,11 +1928,11 @@ const rdcarray *ShaderViewer::GetVariableList(VariableCategory v case VariableCategory::Unknown: vars = NULL; break; case VariableCategory::Temporaries: vars = &state.registers; break; case VariableCategory::IndexTemporaries: - vars = arrayIdx < state.indexableTemps.count() ? &state.indexableTemps[arrayIdx] : NULL; + vars = arrayIdx < state.indexableTemps.count() ? &state.indexableTemps[arrayIdx].members : NULL; break; case VariableCategory::Inputs: vars = &m_Trace->inputs; break; case VariableCategory::Constants: - vars = arrayIdx < m_Trace->cbuffers.count() ? &m_Trace->cbuffers[arrayIdx] : NULL; + vars = arrayIdx < m_Trace->cbuffers.count() ? &m_Trace->cbuffers[arrayIdx].members : NULL; break; case VariableCategory::Outputs: vars = &state.outputs; break; } diff --git a/renderdoc/api/replay/data_types.h b/renderdoc/api/replay/data_types.h index 5c97cb466..9a575fe8f 100644 --- a/renderdoc/api/replay/data_types.h +++ b/renderdoc/api/replay/data_types.h @@ -882,6 +882,12 @@ different to the above, and lets the UI make decisions e.g. to flip rendering of with software rendering, or with some functionality disabled due to lack of support. )"); bool degraded; + + DOCUMENT(R"(``True`` if the driver mutates shader reflection structures from event to event. +Currently this is only true for OpenGL where the superfluous indirect in the binding model must be +worked around by re-sorting bindings. +)"); + bool shadersMutable; }; DECLARE_REFLECTION_STRUCT(APIProperties); diff --git a/renderdoc/api/replay/shader_types.h b/renderdoc/api/replay/shader_types.h index c503c99ae..3b26801d1 100644 --- a/renderdoc/api/replay/shader_types.h +++ b/renderdoc/api/replay/shader_types.h @@ -203,7 +203,7 @@ struct ShaderDebugState DOCUMENT( "Indexable temporary variables for this shader as a list of :class:`ShaderValue` lists."); - rdcarray > indexableTemps; + rdcarray indexableTemps; DOCUMENT(R"(The next instruction to be executed after this state. The initial state before any shader execution happened will have ``nextInstruction == 0``.)"); @@ -228,7 +228,7 @@ struct ShaderDebugTrace Each entry in this list corresponds to a constant block with the same index in the :data:`ShaderBindpointMapping.ConstantBlocks` list, which can be used to look up the metadata. )"); - rdcarray > cbuffers; + rdcarray cbuffers; DOCUMENT(R"(A list of :class:`ShaderDebugState` states representing the state after each instruction was executed @@ -451,16 +451,42 @@ able to be read from and written to arbitrarily. DECLARE_REFLECTION_STRUCT(ShaderResource); +DOCUMENT("Contains a single flag used at compile-time on a shader."); +struct ShaderCompileFlag +{ + DOCUMENT("The name of the compile flag."); + rdcstr Name; + + DOCUMENT("The value of the compile flag."); + rdcstr Value; +}; + +DECLARE_REFLECTION_STRUCT(ShaderCompileFlag); + DOCUMENT("Contains the information about the compilation environment of a shader"); struct ShaderCompileFlags { - DOCUMENT(R"(A list of tuples, where each tuple is a pair of flagName, flagValue. + DOCUMENT(R"(A list of :class:`ShaderCompileFlag`. Each entry is an API or compiler specific flag used to compile this shader originally. )"); - rdcarray > flags; + rdcarray flags; }; +DECLARE_REFLECTION_STRUCT(ShaderCompileFlags); + +DOCUMENT("Contains a source file available in a debug-compiled shader."); +struct ShaderSourceFile +{ + DOCUMENT("The filename of this source file."); + rdcstr Filename; + + DOCUMENT("The actual contents of the file."); + rdcstr Contents; +}; + +DECLARE_REFLECTION_STRUCT(ShaderSourceFile); + DOCUMENT(R"(Contains the information about a shader contained within API-specific debugging information attached to the shader. @@ -472,11 +498,11 @@ struct ShaderDebugChunk DOCUMENT("A :class:`ShaderCompileFlags` containing the flags used to compile this shader."); ShaderCompileFlags compileFlags; - DOCUMENT(R"(A list of tuples, where each tuple is a pair of filename, source code. + DOCUMENT(R"(A list of :class:`ShaderSourceFile`. The first entry in the list is always the file where the entry point is. )"); - rdcarray > files; + rdcarray files; }; DECLARE_REFLECTION_STRUCT(ShaderDebugChunk); diff --git a/renderdoc/core/image_viewer.cpp b/renderdoc/core/image_viewer.cpp index d39412c96..98f7e0081 100644 --- a/renderdoc/core/image_viewer.cpp +++ b/renderdoc/core/image_viewer.cpp @@ -137,10 +137,10 @@ public: } vector GetTextures() { return {m_TextureID}; } TextureDescription GetTexture(ResourceId id) { return m_Proxy->GetTexture(m_TextureID); } - byte *GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, - const GetTextureDataParams ¶ms, size_t &dataSize) + void GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, + const GetTextureDataParams ¶ms, bytebuf &data) { - return m_Proxy->GetTextureData(m_TextureID, arrayIdx, mip, params, dataSize); + m_Proxy->GetTextureData(m_TextureID, arrayIdx, mip, params, data); } // handle a couple of operations ourselves to return a simple fake log @@ -170,10 +170,11 @@ public: bool IsRenderOutput(ResourceId id) { return false; } ResourceId GetLiveID(ResourceId id) { return id; } vector EnumerateCounters() { return vector(); } - void DescribeCounter(GPUCounter counterID, CounterDescription &desc) + CounterDescription DescribeCounter(GPUCounter counterID) { - RDCEraseEl(desc); + CounterDescription desc = {}; desc.counterID = counterID; + return desc; } vector FetchCounters(const vector &counters) { diff --git a/renderdoc/core/replay_proxy.cpp b/renderdoc/core/replay_proxy.cpp index 319580355..8e363509f 100644 --- a/renderdoc/core/replay_proxy.cpp +++ b/renderdoc/core/replay_proxy.cpp @@ -24,1789 +24,50 @@ ******************************************************************************/ #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 ENABLED(RDOC_WIN32) && ENABLED(RDOC_X64) -template -class oversized -{ - int check[int(actual) - int(expected) + 1]; -}; -template -class undersized -{ - int check[int(expected) - int(actual) + 1]; -}; - -#define SIZE_CHECK(expected) \ - undersized(); \ - oversized(); -#else -#define SIZE_CHECK(expected) -#endif - -#pragma region General Shader / State - -template <> -void Serialiser::Serialise(const char *name, ResourceFormat &el) -{ - Serialise("", el.type); - Serialise("", el.compCount); - Serialise("", el.compByteWidth); - Serialise("", el.compType); - Serialise("", el.bgraOrder); - Serialise("", el.srgbCorrected); - - SIZE_CHECK(6); -} - -template <> -void Serialiser::Serialise(const char *name, BindpointMap &el) -{ - Serialise("", el.bindset); - Serialise("", el.bind); - Serialise("", el.used); - Serialise("", el.arraySize); - - SIZE_CHECK(16); -} - -template <> -void Serialiser::Serialise(const char *name, ShaderBindpointMapping &el) -{ - Serialise("", el.InputAttributes); - Serialise("", el.ConstantBlocks); - Serialise("", el.Samplers); - Serialise("", el.ReadOnlyResources); - Serialise("", el.ReadWriteResources); - - SIZE_CHECK(80); -} - -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(80); -} - -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.descriptor.arrayStride); - Serialise("", el.members); - - SIZE_CHECK(48); -} - -template <> -void Serialiser::Serialise(const char *name, ShaderConstant &el) -{ - Serialise("", el.name); - Serialise("", el.reg.vec); - Serialise("", el.reg.comp); - Serialise("", el.defaultValue); - Serialise("", el.type); - - SIZE_CHECK(80); -} - -template <> -void Serialiser::Serialise(const char *name, ConstantBlock &el) -{ - Serialise("", el.name); - Serialise("", el.variables); - Serialise("", el.bufferBacked); - Serialise("", el.bindPoint); - Serialise("", el.byteSize); - - SIZE_CHECK(48); -} - -template <> -void Serialiser::Serialise(const char *name, ShaderSampler &el) -{ - Serialise("", el.name); - Serialise("", el.bindPoint); - - SIZE_CHECK(24); -} - -template <> -void Serialiser::Serialise(const char *name, ShaderResource &el) -{ - Serialise("", el.IsTexture); - Serialise("", el.IsReadOnly); - Serialise("", el.resType); - Serialise("", el.name); - Serialise("", el.variableType); - Serialise("", el.bindPoint); - - SIZE_CHECK(80); -} - -template <> -void Serialiser::Serialise(const char *name, ShaderCompileFlags &el) -{ - Serialise("", el.flags); - - SIZE_CHECK(16); -} - -template <> -void Serialiser::Serialise(const char *name, ShaderDebugChunk &el) -{ - Serialise("", el.compileFlags); - Serialise("", el.files); - - SIZE_CHECK(32); -} - -template <> -void Serialiser::Serialise(const char *name, ShaderReflection &el) -{ - Serialise("", el.ID); - Serialise("", el.EntryPoint); - - Serialise("", el.DebugInfo); - - SerialisePODArray<3>("", el.DispatchThreadsDimension); - - Serialise("", el.RawBytes); - - Serialise("", el.InputSig); - Serialise("", el.OutputSig); - - Serialise("", el.ConstantBlocks); - - Serialise("", el.Samplers); - - Serialise("", el.ReadOnlyResources); - Serialise("", el.ReadWriteResources); - - Serialise("", el.Interfaces); - - SIZE_CHECK(200); -} - -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(184); -} - -template <> -void Serialiser::Serialise(const char *name, ShaderDebugState &el) -{ - Serialise("", el.registers); - Serialise("", el.outputs); - Serialise("", el.nextInstruction); - Serialise("", el.flags); - - std::vector > indexableTemps; - - int32_t numidxtemps = el.indexableTemps.count(); - Serialise("", numidxtemps); - - if(m_Mode == READING) - el.indexableTemps.resize(numidxtemps); - - for(int32_t i = 0; i < numidxtemps; i++) - Serialise("", el.indexableTemps[i]); - - SIZE_CHECK(56); -} - -template <> -void Serialiser::Serialise(const char *name, ShaderDebugTrace &el) -{ - Serialise("", el.inputs); - - int32_t numcbuffers = el.cbuffers.count(); - Serialise("", numcbuffers); - - if(m_Mode == READING) - el.cbuffers.resize(numcbuffers); - - for(int32_t i = 0; i < numcbuffers; i++) - Serialise("", el.cbuffers[i]); - - Serialise("", el.states); - - SIZE_CHECK(48); -} - -#pragma endregion General Shader / State - -#pragma region D3D11 pipeline state - -template <> -void Serialiser::Serialise(const char *name, D3D11Pipe::Layout &el) -{ - Serialise("", el.SemanticName); - Serialise("", el.SemanticIndex); - Serialise("", el.Format); - Serialise("", el.InputSlot); - Serialise("", el.ByteOffset); - Serialise("", el.PerInstance); - Serialise("", el.InstanceDataStepRate); - - SIZE_CHECK(48); -} - -template <> -void Serialiser::Serialise(const char *name, D3D11Pipe::IA &el) -{ - Serialise("", el.ibuffer.Buffer); - Serialise("", el.ibuffer.Offset); - - Serialise("", el.customName); - Serialise("", el.name); - - Serialise("", el.vbuffers); - Serialise("", el.layouts); - - SIZE_CHECK(88); -} - -template <> -void Serialiser::Serialise(const char *name, D3D11Pipe::View &el) -{ - Serialise("", el.Object); - Serialise("", el.Resource); - Serialise("", el.Type); - Serialise("", el.Format); - - Serialise("", el.Structured); - Serialise("", el.BufferStructCount); - Serialise("", el.FirstElement); - Serialise("", el.NumElements); - - Serialise("", el.Flags); - Serialise("", el.HighestMip); - Serialise("", el.NumMipLevels); - Serialise("", el.ArraySize); - Serialise("", el.FirstArraySlice); - - SIZE_CHECK(64); -} - -template <> -void Serialiser::Serialise(const char *name, D3D11Pipe::Sampler &el) -{ - Serialise("", el.Samp); - Serialise("", el.name); - Serialise("", el.customName); - Serialise("", el.AddressU); - Serialise("", el.AddressV); - Serialise("", el.AddressW); - SerialisePODArray<4>("", el.BorderColor); - Serialise("", el.Comparison); - Serialise("", el.Filter); - Serialise("", el.MaxAniso); - Serialise("", el.MaxLOD); - Serialise("", el.MinLOD); - Serialise("", el.MipLODBias); - - SIZE_CHECK(96); -} - -template <> -void Serialiser::Serialise(const char *name, D3D11Pipe::Shader &el) -{ - Serialise("", el.Object); - Serialise("", el.stage); - Serialise("", el.name); - 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(208); -} - -template <> -void Serialiser::Serialise(const char *name, D3D11Pipe::Rasterizer &el) -{ - Serialise("", el.m_State); - Serialise("", el.Scissors); - Serialise("", el.Viewports); - - SIZE_CHECK(80); -} - -template <> -void Serialiser::Serialise(const char *name, D3D11Pipe::Blend &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.Logic); - - Serialise("", el.Enabled); - Serialise("", el.LogicEnabled); - Serialise("", el.WriteMask); - - SIZE_CHECK(32); -} - -template <> -void Serialiser::Serialise(const char *name, D3D11Pipe::OM &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); +#include "3rdparty/lz4/lz4.h" +#include "serialise/lz4io.h" + +// utility macros for implementing proxied functions + +// begins a chunk with the given packet type, and if reading verifies that the +// read type was what was expected - otherwise sets an error flag +#define PACKET_HEADER(packet) \ + ReplayProxyPacket p = (ReplayProxyPacket)ser.BeginChunk(packet, 0); \ + if(ser.IsReading() && p != packet) \ + m_IsErrored = true; + +// begins the set of parameters. Note that we only begin a chunk when writing (sending a request to +// the remote server), since on reading the chunk has already been begun to read the type to +// dispatch to the correct function. +#define BEGIN_PARAMS() \ + ParamSerialiser &ser = paramser; \ + if(ser.IsWriting()) \ + ser.BeginChunk(packet, 0); + +// end the set of parameters, and that chunk. +#define END_PARAMS() ser.EndChunk(); + +// begin serialising a return value. We begin a chunk here in either the writing or reading case +// since this chunk is used purely to send/receive the return value and is fully handled within the +// function. +#define SERIALISE_RETURN(retval) \ + { \ + ReturnSerialiser &ser = retser; \ + PACKET_HEADER(packet); \ + SERIALISE_ELEMENT(retval); \ + ser.EndChunk(); \ } - { - 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(224); -} - -template <> -void Serialiser::Serialise(const char *name, D3D11Pipe::State &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(1656); -} - -#pragma endregion D3D11 pipeline state - -#pragma region D3D12 pipeline state - -template <> -void Serialiser::Serialise(const char *name, D3D12Pipe::Layout &el) -{ - Serialise("", el.SemanticName); - Serialise("", el.SemanticIndex); - Serialise("", el.Format); - Serialise("", el.InputSlot); - Serialise("", el.ByteOffset); - Serialise("", el.PerInstance); - Serialise("", el.InstanceDataStepRate); - - SIZE_CHECK(48); -} - -template <> -void Serialiser::Serialise(const char *name, D3D12Pipe::IA &el) -{ - Serialise("", el.ibuffer.Buffer); - Serialise("", el.ibuffer.Offset); - Serialise("", el.ibuffer.Size); - - Serialise("", el.vbuffers); - Serialise("", el.layouts); - - Serialise("", el.indexStripCutValue); - - SIZE_CHECK(64); -} - -template <> -void Serialiser::Serialise(const char *name, D3D12Pipe::CBuffer &el) -{ - Serialise("", el.Immediate); - Serialise("", el.RootElement); - Serialise("", el.TableIndex); - Serialise("", el.Buffer); - Serialise("", el.Offset); - Serialise("", el.ByteSize); - Serialise("", el.RootValues); - - SIZE_CHECK(56); -} - -template <> -void Serialiser::Serialise(const char *name, D3D12Pipe::Sampler &el) -{ - Serialise("", el.Immediate); - Serialise("", el.RootElement); - Serialise("", el.TableIndex); - Serialise("", el.AddressU); - Serialise("", el.AddressV); - Serialise("", el.AddressW); - SerialisePODArray<4>("", el.BorderColor); - Serialise("", el.Comparison); - Serialise("", el.Filter); - Serialise("", el.MaxAniso); - Serialise("", el.MaxLOD); - Serialise("", el.MinLOD); - Serialise("", el.MipLODBias); - - SIZE_CHECK(76); -} - -template <> -void Serialiser::Serialise(const char *name, D3D12Pipe::View &el) -{ - Serialise("", el.Immediate); - Serialise("", el.RootElement); - Serialise("", el.TableIndex); - Serialise("", el.Resource); - Serialise("", el.Resource); - Serialise("", el.Type); - Serialise("", el.Format); - - SerialisePODArray<4>("", el.swizzle); - Serialise("", el.BufferFlags); - Serialise("", el.BufferStructCount); - Serialise("", el.ElementSize); - Serialise("", el.FirstElement); - Serialise("", el.NumElements); - - Serialise("", el.CounterResource); - Serialise("", el.CounterByteOffset); - - Serialise("", el.HighestMip); - Serialise("", el.NumMipLevels); - Serialise("", el.ArraySize); - Serialise("", el.FirstArraySlice); - - Serialise("", el.MinLODClamp); - - SIZE_CHECK(120); -} - -template <> -void Serialiser::Serialise(const char *name, D3D12Pipe::RegisterSpace &el) -{ - Serialise("", el.ConstantBuffers); - Serialise("", el.Samplers); - Serialise("", el.SRVs); - Serialise("", el.UAVs); - - SIZE_CHECK(64); -} - -template <> -void Serialiser::Serialise(const char *name, D3D12Pipe::Shader &el) -{ - Serialise("", el.Object); - Serialise("", el.BindpointMapping); - Serialise("", el.stage); - Serialise("", el.Spaces); - - SIZE_CHECK(120); -} - -template <> -void Serialiser::Serialise(const char *name, D3D12Pipe::Rasterizer &el) -{ - Serialise("", el.SampleMask); - Serialise("", el.Scissors); - Serialise("", el.Viewports); - Serialise("", el.m_State); - - SIZE_CHECK(80); -} - -template <> -void Serialiser::Serialise(const char *name, D3D12Pipe::Blend &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.Logic); - - Serialise("", el.Enabled); - Serialise("", el.LogicEnabled); - Serialise("", el.WriteMask); - - SIZE_CHECK(32); -} - -template <> -void Serialiser::Serialise(const char *name, D3D12Pipe::OM &el) -{ - { - Serialise("", el.m_State.DepthEnable); - Serialise("", el.m_State.DepthWrites); - Serialise("", el.m_State.DepthFunc); - 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.AlphaToCoverage); - Serialise("", el.m_BlendState.IndependentBlend); - Serialise("", el.m_BlendState.Blends); - SerialisePODArray<4>("", el.m_BlendState.BlendFactor); - } - - Serialise("", el.RenderTargets); - Serialise("", el.DepthTarget); - Serialise("", el.DepthReadOnly); - Serialise("", el.StencilReadOnly); - - Serialise("", el.multiSampleCount); - Serialise("", el.multiSampleQuality); - - SIZE_CHECK(240); -} - -template <> -void Serialiser::Serialise(const char *name, D3D12Pipe::ResourceState &el) -{ - Serialise("", el.name); - - SIZE_CHECK(16); -} - -template <> -void Serialiser::Serialise(const char *name, D3D12Pipe::ResourceData &el) -{ - Serialise("", el.id); - Serialise("", el.states); - - SIZE_CHECK(24); -} - -template <> -void Serialiser::Serialise(const char *name, D3D12Pipe::State &el) -{ - Serialise("", el.pipeline); - Serialise("", el.customName); - Serialise("", el.name); - - Serialise("", el.rootSig); - - 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); - - Serialise("", el.Resources); - - SIZE_CHECK(1176); -} - -#pragma endregion D3D12 pipeline state - -#pragma region OpenGL pipeline state - -template <> -void Serialiser::Serialise(const char *name, GLPipe::VertexAttribute &el) -{ - Serialise("", el.Enabled); - Serialise("", el.Format); - SerialisePODArray<4>("", el.GenericValue.value_f); - Serialise("", el.BufferSlot); - Serialise("", el.RelativeOffset); - - SIZE_CHECK(32); -} - -template <> -void Serialiser::Serialise(const char *name, GLPipe::VertexInput &el) -{ - Serialise("", el.attributes); - Serialise("", el.vbuffers); - Serialise("", el.ibuffer); - Serialise("", el.primitiveRestart); - Serialise("", el.restartIndex); - Serialise("", el.provokingVertexLast); - - SIZE_CHECK(56); -} - -template <> -void Serialiser::Serialise(const char *name, GLPipe::Shader &el) -{ - Serialise("", el.Object); - - Serialise("", el.ShaderName); - Serialise("", el.customShaderName); - - Serialise("", el.ProgramName); - Serialise("", el.customProgramName); - - Serialise("", el.PipelineActive); - Serialise("", el.PipelineName); - Serialise("", el.customPipelineName); - - Serialise("", el.stage); - Serialise("", el.BindpointMapping); - Serialise("", el.Subroutines); - - if(m_Mode == READING) - el.ShaderDetails = NULL; - - SIZE_CHECK(192); -} - -template <> -void Serialiser::Serialise(const char *name, GLPipe::Sampler &el) -{ - Serialise("", el.Samp); - Serialise("", el.AddressS); - Serialise("", el.AddressT); - Serialise("", el.AddressR); - SerialisePODArray<4>("", el.BorderColor); - Serialise("", el.Comparison); - Serialise("", el.Filter); - Serialise("", el.SeamlessCube); - Serialise("", el.MaxAniso); - Serialise("", el.MaxLOD); - Serialise("", el.MinLOD); - Serialise("", el.MipLODBias); - - SIZE_CHECK(80); -} - -template <> -void Serialiser::Serialise(const char *name, GLPipe::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(32); -} - -template <> -void Serialiser::Serialise(const char *name, GLPipe::Rasterizer &el) -{ - Serialise("", el.Viewports); - Serialise("", el.Scissors); - Serialise("", el.m_State); - - SIZE_CHECK(104); -} - -template <> -void Serialiser::Serialise(const char *name, GLPipe::DepthState &el) -{ - Serialise("", el.DepthEnable); - Serialise("", el.DepthFunc); - Serialise("", el.DepthWrites); - Serialise("", el.DepthBounds); - Serialise("", el.NearBound); - Serialise("", el.FarBound); - - SIZE_CHECK(32); -} - -template <> -void Serialiser::Serialise(const char *name, GLPipe::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(44); -} - -template <> -void Serialiser::Serialise(const char *name, GLPipe::Blend &el) -{ - Serialise("", el.Enabled); - Serialise("", el.WriteMask); - Serialise("", el.Logic); - - 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(32); -} - -template <> -void Serialiser::Serialise(const char *name, GLPipe::BlendState &el) -{ - SerialisePODArray<4>("", el.BlendFactor); - Serialise("", el.Blends); - - SIZE_CHECK(32); -} - -template <> -void Serialiser::Serialise(const char *name, GLPipe::Attachment &el) -{ - Serialise("", el.Obj); - Serialise("", el.Layer); - Serialise("", el.Mip); - SerialisePODArray<4>("", el.Swizzle); - - SIZE_CHECK(32); -} - -template <> -void Serialiser::Serialise(const char *name, GLPipe::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(264); -} - -template <> -void Serialiser::Serialise(const char *name, GLPipe::State &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(1928); -} - -#pragma endregion OpenGL pipeline state - -#pragma region Vulkan pipeline state - -template <> -void Serialiser::Serialise(const char *name, VKPipe::BindingElement &el) -{ - Serialise("", el.view); - Serialise("", el.res); - Serialise("", el.sampler); - Serialise("", el.immutableSampler); - - Serialise("", el.name); - Serialise("", el.customName); - - Serialise("", el.viewfmt); - SerialisePODArray<4>("", el.swizzle); - Serialise("", el.baseMip); - Serialise("", el.baseLayer); - Serialise("", el.numMip); - Serialise("", el.numLayer); - - Serialise("", el.offset); - Serialise("", el.size); - - Serialise("", el.Filter); - Serialise("", el.AddressU); - Serialise("", el.AddressV); - Serialise("", el.AddressW); - Serialise("", el.mipBias); - Serialise("", el.maxAniso); - Serialise("", el.comparison); - Serialise("", el.minlod); - Serialise("", el.maxlod); - SerialisePODArray<4>("", el.BorderColor); - Serialise("", el.unnormalized); - - SIZE_CHECK(176); -}; - -template <> -void Serialiser::Serialise(const char *name, VKPipe::DescriptorBinding &el) -{ - Serialise("", el.descriptorCount); - Serialise("", el.type); - Serialise("", el.stageFlags); - - Serialise("", el.binds); - - SIZE_CHECK(32); -} - -template <> -void Serialiser::Serialise(const char *name, VKPipe::DescriptorSet &el) -{ - Serialise("", el.layout); - Serialise("", el.descset); - - Serialise("", el.bindings); - - SIZE_CHECK(32); -} - -template <> -void Serialiser::Serialise(const char *name, VKPipe::Pipeline &el) -{ - Serialise("", el.obj); - Serialise("", el.flags); - - Serialise("", el.DescSets); - - SIZE_CHECK(32); -} - -template <> -void Serialiser::Serialise(const char *name, VKPipe::VertexAttribute &el) -{ - Serialise("", el.location); - Serialise("", el.binding); - Serialise("", el.format); - Serialise("", el.byteoffset); - - SIZE_CHECK(20); -} - -template <> -void Serialiser::Serialise(const char *name, VKPipe::VertexInput &el) -{ - Serialise("", el.attrs); - Serialise("", el.binds); - Serialise("", el.vbuffers); - - SIZE_CHECK(48); -} - -template <> -void Serialiser::Serialise(const char *name, VKPipe::SpecInfo &el) -{ - Serialise("", el.specID); - Serialise("", el.data); - - SIZE_CHECK(24); -} - -template <> -void Serialiser::Serialise(const char *name, VKPipe::Shader &el) -{ - Serialise("", el.Object); - Serialise("", el.entryPoint); - - Serialise("", el.name); - Serialise("", el.customName); - Serialise("", el.BindpointMapping); - Serialise("", el.stage); - - if(m_Mode == READING) - el.ShaderDetails = NULL; - - Serialise("", el.specialization); - - SIZE_CHECK(160); -} - -template <> -void Serialiser::Serialise(const char *name, VKPipe::ViewState &el) -{ - Serialise("", el.viewportScissors); - - SIZE_CHECK(16); -} - -template <> -void Serialiser::Serialise(const char *name, VKPipe::Blend &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(32); -} - -template <> -void Serialiser::Serialise(const char *name, VKPipe::ColorBlend &el) -{ - Serialise("", el.alphaToCoverageEnable); - Serialise("", el.alphaToOneEnable); - Serialise("", el.logicOpEnable); - Serialise("", el.logic); - - Serialise("", el.attachments); - - SerialisePODArray<4>("", el.blendConst); - - SIZE_CHECK(40); -} - -template <> -void Serialiser::Serialise(const char *name, VKPipe::Attachment &el) -{ - Serialise("", el.view); - Serialise("", el.img); - - Serialise("", el.viewfmt); - SerialisePODArray<4>("", el.swizzle); - - Serialise("", el.baseMip); - Serialise("", el.baseLayer); - Serialise("", el.numMip); - Serialise("", el.numLayer); - - SIZE_CHECK(56); -} - -template <> -void Serialiser::Serialise(const char *name, VKPipe::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(76); -} - -template <> -void Serialiser::Serialise(const char *name, VKPipe::CurrentPass &el) -{ - Serialise("", el.renderpass.obj); - Serialise("", el.renderpass.inputAttachments); - Serialise("", el.renderpass.colorAttachments); - Serialise("", el.renderpass.resolveAttachments); - 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(120); -} - -template <> -void Serialiser::Serialise(const char *name, VKPipe::ImageLayout &el) -{ - Serialise("", el.baseMip); - Serialise("", el.baseLayer); - Serialise("", el.numMip); - Serialise("", el.numLayer); - Serialise("", el.name); - - SIZE_CHECK(32); -} - -template <> -void Serialiser::Serialise(const char *name, VKPipe::ImageData &el) -{ - Serialise("", el.image); - Serialise("", el.layouts); - - SIZE_CHECK(24); -} - -template <> -void Serialiser::Serialise(const char *name, VKPipe::State &el) -{ - Serialise("", el.compute); - Serialise("", el.graphics); - - Serialise("", el.IA); - Serialise("", el.VI); - - 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.Tess); - - Serialise("", el.VP); - Serialise("", el.RS); - Serialise("", el.MSAA); - Serialise("", el.CB); - Serialise("", el.DS); - Serialise("", el.Pass); - - Serialise("", el.images); - - SIZE_CHECK(1424); -} - -#pragma endregion Vulkan pipeline state - -#pragma region Data descriptors - -template <> -void Serialiser::Serialise(const char *name, TextureDescription &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.creationFlags); - Serialise("", el.msQual); - Serialise("", el.msSamp); - Serialise("", el.byteSize); - - SIZE_CHECK(88); -} - -template <> -void Serialiser::Serialise(const char *name, BufferDescription &el) -{ - Serialise("", el.ID); - Serialise("", el.name); - Serialise("", el.customName); - Serialise("", el.creationFlags); - Serialise("", el.length); - - SIZE_CHECK(40); -} - -template <> -void Serialiser::Serialise(const char *name, APIProperties &el) -{ - Serialise("", el.pipelineType); - Serialise("", el.localRenderer); - Serialise("", el.degraded); - - SIZE_CHECK(12); -} - -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(40); -} - -template <> -void Serialiser::Serialise(const char *name, APIEvent &el) -{ - Serialise("", el.eventID); - Serialise("", el.callstack); - Serialise("", el.eventDesc); - Serialise("", el.fileOffset); - - SIZE_CHECK(48); -} - -template <> -void Serialiser::Serialise(const char *name, DrawcallDescription &el) -{ - Serialise("", el.eventID); - Serialise("", el.drawcallID); - - Serialise("", el.name); - - Serialise("", el.flags); - - SerialisePODArray<4>("", el.markerColor); - - Serialise("", el.numIndices); - Serialise("", el.numInstances); - Serialise("", el.baseVertex); - 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.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(248); -} - -template <> -void Serialiser::Serialise(const char *name, ConstantBindStats &el) -{ - Serialise("", el.calls); - Serialise("", el.sets); - Serialise("", el.nulls); - Serialise("", el.bindslots); - Serialise("", el.sizes); - - SIZE_CHECK(48); -} - -template <> -void Serialiser::Serialise(const char *name, SamplerBindStats &el) -{ - Serialise("", el.calls); - Serialise("", el.sets); - Serialise("", el.nulls); - Serialise("", el.bindslots); - - SIZE_CHECK(32); -} - -template <> -void Serialiser::Serialise(const char *name, ResourceBindStats &el) -{ - Serialise("", el.calls); - Serialise("", el.sets); - Serialise("", el.nulls); - Serialise("", el.types); - Serialise("", el.bindslots); - - SIZE_CHECK(48); -} - -template <> -void Serialiser::Serialise(const char *name, ResourceUpdateStats &el) -{ - Serialise("", el.calls); - Serialise("", el.clients); - Serialise("", el.servers); - Serialise("", el.types); - Serialise("", el.sizes); - - SIZE_CHECK(48); -} - -template <> -void Serialiser::Serialise(const char *name, DrawcallStats &el) -{ - Serialise("", el.calls); - Serialise("", el.instanced); - Serialise("", el.indirect); - Serialise("", el.counts); - - SIZE_CHECK(32); -} - -template <> -void Serialiser::Serialise(const char *name, DispatchStats &el) -{ - Serialise("", el.calls); - Serialise("", el.indirect); - - SIZE_CHECK(8); -} - -template <> -void Serialiser::Serialise(const char *name, IndexBindStats &el) -{ - Serialise("", el.calls); - Serialise("", el.sets); - Serialise("", el.nulls); - - SIZE_CHECK(12); -} - -template <> -void Serialiser::Serialise(const char *name, VertexBindStats &el) -{ - Serialise("", el.calls); - Serialise("", el.sets); - Serialise("", el.nulls); - Serialise("", el.bindslots); - - SIZE_CHECK(32); -} - -template <> -void Serialiser::Serialise(const char *name, LayoutBindStats &el) -{ - Serialise("", el.calls); - Serialise("", el.sets); - Serialise("", el.nulls); - - SIZE_CHECK(12); -} - -template <> -void Serialiser::Serialise(const char *name, ShaderChangeStats &el) -{ - Serialise("", el.calls); - Serialise("", el.sets); - Serialise("", el.nulls); - Serialise("", el.redundants); - - SIZE_CHECK(16); -} - -template <> -void Serialiser::Serialise(const char *name, BlendStats &el) -{ - Serialise("", el.calls); - Serialise("", el.sets); - Serialise("", el.nulls); - Serialise("", el.redundants); - - SIZE_CHECK(16); -} - -template <> -void Serialiser::Serialise(const char *name, DepthStencilStats &el) -{ - Serialise("", el.calls); - Serialise("", el.sets); - Serialise("", el.nulls); - Serialise("", el.redundants); - - SIZE_CHECK(16); -} - -template <> -void Serialiser::Serialise(const char *name, RasterizationStats &el) -{ - Serialise("", el.calls); - Serialise("", el.sets); - Serialise("", el.nulls); - Serialise("", el.redundants); - Serialise("", el.viewports); - Serialise("", el.rects); - - SIZE_CHECK(48); -} - -template <> -void Serialiser::Serialise(const char *name, OutputTargetStats &el) -{ - Serialise("", el.calls); - Serialise("", el.sets); - Serialise("", el.nulls); - Serialise("", el.bindslots); - - SIZE_CHECK(32); -} - -template <> -void Serialiser::Serialise(const char *name, FrameStatistics &el) -{ - Serialise("", el.recorded); - // #mivance note this is technically error-prone from the perspective - // that we're passing references to pointers, but as we're really - // dealing with arrays,t hey'll never be NULL and need to be assigned - // to, so this is fine - ConstantBindStats *constants = el.constants; - SerialiseComplexArray<(uint32_t)ShaderStage::Count>("", constants); - SamplerBindStats *samplers = el.samplers; - SerialiseComplexArray<(uint32_t)ShaderStage::Count>("", samplers); - ResourceBindStats *resources = el.resources; - SerialiseComplexArray<(uint32_t)ShaderStage::Count>("", resources); - Serialise("", el.updates); - Serialise("", el.draws); - Serialise("", el.dispatches); - Serialise("", el.indices); - Serialise("", el.vertices); - Serialise("", el.layouts); - ShaderChangeStats *shaders = el.shaders; - SerialiseComplexArray<(uint32_t)ShaderStage::Count>("", shaders); - Serialise("", el.blends); - Serialise("", el.depths); - Serialise("", el.rasters); - Serialise("", el.outputs); - - SIZE_CHECK(1136); -} - -template <> -void Serialiser::Serialise(const char *name, FrameDescription &el) -{ - Serialise("", el.frameNumber); - Serialise("", el.fileOffset); - Serialise("", el.uncompressedFileSize); - Serialise("", el.compressedFileSize); - Serialise("", el.persistentSize); - Serialise("", el.initDataSize); - Serialise("", el.captureTime); - Serialise("", el.stats); - Serialise("", el.debugMessages); - - SIZE_CHECK(1208); -} - -template <> -void Serialiser::Serialise(const char *name, FrameRecord &el) -{ - Serialise("", el.frameInfo); - Serialise("", el.drawcallList); - - SIZE_CHECK(1224); -} - -template <> -void Serialiser::Serialise(const char *name, MeshFormat &el) -{ - Serialise("", el.idxbuf); - Serialise("", el.idxoffs); - Serialise("", el.idxByteWidth); - Serialise("", el.baseVertex); - Serialise("", el.buf); - Serialise("", el.offset); - Serialise("", el.stride); - Serialise("", el.fmt); - Serialise("", el.meshColor); - Serialise("", el.showAlpha); - Serialise("", el.topo); - Serialise("", el.numVerts); - Serialise("", el.unproject); - Serialise("", el.nearPlane); - Serialise("", el.farPlane); - - SIZE_CHECK(88); -} - -template <> -void Serialiser::Serialise(const char *name, Uuid &el) -{ - SerialisePODArray<4>("", el.bytes); - - SIZE_CHECK(16); -} - -template <> -void Serialiser::Serialise(const char *name, CounterDescription &el) -{ - Serialise("", el.counterID); - Serialise("", el.name); - Serialise("", el.description); - Serialise("", el.resultType); - Serialise("", el.resultByteWidth); - Serialise("", el.unit); - Serialise("", el.category); - Serialise("", el.uuid); - - SIZE_CHECK(88); -} - -template <> -void Serialiser::Serialise(const char *name, PixelModification &el) -{ - Serialise("", el.eventID); - - Serialise("", el.directShaderWrite); - Serialise("", el.unboundPS); - - 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.sampleMasked); - Serialise("", el.backfaceCulled); - Serialise("", el.depthClipped); - Serialise("", el.viewClipped); - Serialise("", el.scissorClipped); - Serialise("", el.shaderDiscarded); - Serialise("", el.depthTestFailed); - Serialise("", el.stencilTestFailed); - - SIZE_CHECK(96); -} - -#pragma endregion Data descriptors - -#pragma region Plain - old data structures - -// these structures we can just serialise as a blob, since they're POD. -template <> -std::string DoStringise(const CaptureOptions &el) -{ - return "<...>"; -} -template <> -std::string DoStringise(const D3D11Pipe::VB &el) -{ - return "<...>"; -} -template <> -std::string DoStringise(const D3D11Pipe::RasterizerState &el) -{ - return "<...>"; -} -template <> -std::string DoStringise(const D3D11Pipe::CBuffer &el) -{ - return "<...>"; -} -template <> -std::string DoStringise(const D3D11Pipe::Scissor &el) -{ - return "<...>"; -} -template <> -std::string DoStringise(const D3D11Pipe::Viewport &el) -{ - return "<...>"; -} -template <> -std::string DoStringise(const D3D11Pipe::SOBind &el) -{ - return "<...>"; -} -template <> -std::string DoStringise(const D3D12Pipe::VB &el) -{ - return "<...>"; -} -template <> -std::string DoStringise(const D3D12Pipe::SOBind &el) -{ - return "<...>"; -} -template <> -std::string DoStringise(const D3D12Pipe::Scissor &el) -{ - return "<...>"; -} -template <> -std::string DoStringise(const D3D12Pipe::Viewport &el) -{ - return "<...>"; -} -template <> -std::string DoStringise(const D3D12Pipe::RasterizerState &el) -{ - return "<...>"; -} -template <> -std::string DoStringise(const GLPipe::VB &el) -{ - return "<...>"; -} -template <> -std::string DoStringise(const GLPipe::FixedVertexProcessing &el) -{ - return "<...>"; -} -template <> -std::string DoStringise(const GLPipe::Texture &el) -{ - return "<...>"; -} -template <> -std::string DoStringise(const GLPipe::Buffer &el) -{ - return "<...>"; -} -template <> -std::string DoStringise(const GLPipe::Feedback &el) -{ - return "<...>"; -} -template <> -std::string DoStringise(const GLPipe::Viewport &el) -{ - return "<...>"; -} -template <> -std::string DoStringise(const GLPipe::Scissor &el) -{ - return "<...>"; -} -template <> -std::string DoStringise(const GLPipe::RasterizerState &el) -{ - return "<...>"; -} -template <> -std::string DoStringise(const GLPipe::Hints &el) -{ - return "<...>"; -} -template <> -std::string DoStringise(const VKPipe::RenderArea &el) -{ - return "<...>"; -} -template <> -std::string DoStringise(const VKPipe::InputAssembly &el) -{ - return "<...>"; -} -template <> -std::string DoStringise(const VKPipe::Tessellation &el) -{ - return "<...>"; -} -template <> -std::string DoStringise(const VKPipe::Raster &el) -{ - return "<...>"; -} -template <> -std::string DoStringise(const VKPipe::MultiSample &el) -{ - return "<...>"; -} -template <> -std::string DoStringise(const VKPipe::BindingElement &el) -{ - return "<...>"; -} -template <> -std::string DoStringise(const VKPipe::VertexBinding &el) -{ - return "<...>"; -} -template <> -std::string DoStringise(const VKPipe::VB &el) -{ - return "<...>"; -} -template <> -std::string DoStringise(const VKPipe::ViewportScissor &el) -{ - return "<...>"; -} -template <> -std::string DoStringise(const EventUsage &el) -{ - return "<...>"; -} -template <> -std::string DoStringise(const CounterResult &el) -{ - return "<...>"; -} -template <> -std::string DoStringise(const ReplayLogType &el) -{ - return "<...>"; -} -template <> -std::string DoStringise(const FloatVector &el) -{ - return "<...>"; -} - -#pragma endregion Plain - old data structures +// dispatches to the right implementation of the Proxied_ function, depending on whether we're on +// the remote server or not. +#define PROXY_FUNCTION(name, ...) \ + if(m_RemoteServer) \ + return CONCAT(Proxied_, name)(m_Reader, m_Writer, ##__VA_ARGS__); \ + else \ + return CONCAT(Proxied_, name)(m_Writer, m_Reader, ##__VA_ARGS__); ReplayProxy::~ReplayProxy() { - SAFE_DELETE(m_FromReplaySerialiser); - m_ToReplaySerialiser = NULL; // we don't own this - if(m_Proxy) m_Proxy->Shutdown(); m_Proxy = NULL; @@ -1815,38 +76,1187 @@ ReplayProxy::~ReplayProxy() delete it->second; } -bool ReplayProxy::SendReplayCommand(ReplayProxyPacket type) +#pragma region Proxied Functions + +template +bool ReplayProxy::Proxied_NeedRemapForFetch(ParamSerialiser ¶mser, ReturnSerialiser &retser, + const ResourceFormat &format) { - if(!m_Socket->Connected()) - return false; + const ReplayProxyPacket packet = eReplayProxy_NeedRemapForFetch; + bool ret = false; - 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; -} - -template <> -std::string DoStringise(const RemapTextureEnum &el) -{ - BEGIN_ENUM_STRINGISE(RemapTextureEnum); { - STRINGISE_ENUM(eRemap_None) - STRINGISE_ENUM(eRemap_RGBA8) - STRINGISE_ENUM(eRemap_RGBA16) - STRINGISE_ENUM(eRemap_RGBA32) - STRINGISE_ENUM(eRemap_D32S8) + BEGIN_PARAMS(); + SERIALISE_ELEMENT(format); + END_PARAMS(); } - END_ENUM_STRINGISE(); + + if(paramser.IsReading() && !paramser.IsErrored() && !m_IsErrored) + ret = m_Remote->NeedRemapForFetch(format); + + SERIALISE_RETURN(ret); + + return ret; } +bool ReplayProxy::NeedRemapForFetch(const ResourceFormat &fmt) +{ + PROXY_FUNCTION(NeedRemapForFetch, fmt); +} + +template +bool ReplayProxy::Proxied_IsRenderOutput(ParamSerialiser ¶mser, ReturnSerialiser &retser, + ResourceId id) +{ + const ReplayProxyPacket packet = eReplayProxy_IsRenderOutput; + bool ret = false; + + { + BEGIN_PARAMS(); + SERIALISE_ELEMENT(id); + END_PARAMS(); + } + + if(paramser.IsReading() && !paramser.IsErrored() && !m_IsErrored) + ret = m_Remote->IsRenderOutput(id); + + SERIALISE_RETURN(ret); + + return ret; +} + +bool ReplayProxy::IsRenderOutput(ResourceId id) +{ + PROXY_FUNCTION(IsRenderOutput, id); +} + +template +APIProperties ReplayProxy::Proxied_GetAPIProperties(ParamSerialiser ¶mser, + ReturnSerialiser &retser) +{ + const ReplayProxyPacket packet = eReplayProxy_GetAPIProperties; + APIProperties ret = {}; + + { + BEGIN_PARAMS(); + END_PARAMS(); + } + + if(paramser.IsReading() && !paramser.IsErrored() && !m_IsErrored) + ret = m_Remote->GetAPIProperties(); + + SERIALISE_RETURN(ret); + + if(!m_RemoteServer) + ret.localRenderer = m_Proxy->GetAPIProperties().localRenderer; + + m_APIProps = ret; + + return ret; +} + +APIProperties ReplayProxy::GetAPIProperties() +{ + PROXY_FUNCTION(GetAPIProperties); +} + +template +std::vector ReplayProxy::Proxied_GetDebugMessages(ParamSerialiser ¶mser, + ReturnSerialiser &retser) +{ + const ReplayProxyPacket packet = eReplayProxy_GetDebugMessages; + std::vector ret; + + { + BEGIN_PARAMS(); + END_PARAMS(); + } + + if(paramser.IsReading() && !paramser.IsErrored() && !m_IsErrored) + ret = m_Remote->GetDebugMessages(); + + SERIALISE_RETURN(ret); + + return ret; +} + +std::vector ReplayProxy::GetDebugMessages() +{ + PROXY_FUNCTION(GetDebugMessages); +} + +template +std::vector ReplayProxy::Proxied_GetTextures(ParamSerialiser ¶mser, + ReturnSerialiser &retser) +{ + const ReplayProxyPacket packet = eReplayProxy_GetTextures; + std::vector ret; + + { + BEGIN_PARAMS(); + END_PARAMS(); + } + + if(paramser.IsReading() && !paramser.IsErrored() && !m_IsErrored) + ret = m_Remote->GetTextures(); + + SERIALISE_RETURN(ret); + + return ret; +} + +std::vector ReplayProxy::GetTextures() +{ + PROXY_FUNCTION(GetTextures); +} + +template +TextureDescription ReplayProxy::Proxied_GetTexture(ParamSerialiser ¶mser, + ReturnSerialiser &retser, ResourceId id) +{ + const ReplayProxyPacket packet = eReplayProxy_GetTexture; + TextureDescription ret = {}; + + { + BEGIN_PARAMS(); + SERIALISE_ELEMENT(id); + END_PARAMS(); + } + + if(paramser.IsReading() && !paramser.IsErrored() && !m_IsErrored) + ret = m_Remote->GetTexture(id); + + SERIALISE_RETURN(ret); + + return ret; +} + +TextureDescription ReplayProxy::GetTexture(ResourceId id) +{ + PROXY_FUNCTION(GetTexture, id); +} + +template +std::vector ReplayProxy::Proxied_GetBuffers(ParamSerialiser ¶mser, + ReturnSerialiser &retser) +{ + const ReplayProxyPacket packet = eReplayProxy_GetBuffers; + std::vector ret; + + { + BEGIN_PARAMS(); + END_PARAMS(); + } + + if(paramser.IsReading() && !paramser.IsErrored() && !m_IsErrored) + ret = m_Remote->GetBuffers(); + + SERIALISE_RETURN(ret); + + return ret; +} + +std::vector ReplayProxy::GetBuffers() +{ + PROXY_FUNCTION(GetBuffers); +} + +template +BufferDescription ReplayProxy::Proxied_GetBuffer(ParamSerialiser ¶mser, + ReturnSerialiser &retser, ResourceId id) +{ + const ReplayProxyPacket packet = eReplayProxy_GetBuffer; + BufferDescription ret = {}; + + { + BEGIN_PARAMS(); + SERIALISE_ELEMENT(id); + END_PARAMS(); + } + + if(paramser.IsReading() && !paramser.IsErrored() && !m_IsErrored) + ret = m_Remote->GetBuffer(id); + + SERIALISE_RETURN(ret); + + return ret; +} + +BufferDescription ReplayProxy::GetBuffer(ResourceId id) +{ + PROXY_FUNCTION(GetBuffer, id); +} + +template +std::vector ReplayProxy::Proxied_GetPassEvents(ParamSerialiser ¶mser, + ReturnSerialiser &retser, uint32_t eventID) +{ + const ReplayProxyPacket packet = eReplayProxy_GetPassEvents; + std::vector ret; + + { + BEGIN_PARAMS(); + SERIALISE_ELEMENT(eventID); + END_PARAMS(); + } + + if(paramser.IsReading() && !paramser.IsErrored() && !m_IsErrored) + ret = m_Remote->GetPassEvents(eventID); + + SERIALISE_RETURN(ret); + + return ret; +} + +std::vector ReplayProxy::GetPassEvents(uint32_t eventID) +{ + PROXY_FUNCTION(GetPassEvents, eventID); +} + +template +std::vector ReplayProxy::Proxied_GetUsage(ParamSerialiser ¶mser, + ReturnSerialiser &retser, ResourceId id) +{ + const ReplayProxyPacket packet = eReplayProxy_GetUsage; + std::vector ret; + + { + BEGIN_PARAMS(); + SERIALISE_ELEMENT(id); + END_PARAMS(); + } + + if(paramser.IsReading() && !paramser.IsErrored() && !m_IsErrored) + ret = m_Remote->GetUsage(id); + + SERIALISE_RETURN(ret); + + return ret; +} + +std::vector ReplayProxy::GetUsage(ResourceId id) +{ + PROXY_FUNCTION(GetUsage, id); +} + +template +FrameRecord ReplayProxy::Proxied_GetFrameRecord(ParamSerialiser ¶mser, ReturnSerialiser &retser) +{ + const ReplayProxyPacket packet = eReplayProxy_GetFrameRecord; + FrameRecord ret = {}; + + { + BEGIN_PARAMS(); + END_PARAMS(); + } + + if(paramser.IsReading() && !paramser.IsErrored() && !m_IsErrored) + ret = m_Remote->GetFrameRecord(); + + SERIALISE_RETURN(ret); + + return ret; +} + +FrameRecord ReplayProxy::GetFrameRecord() +{ + PROXY_FUNCTION(GetFrameRecord); +} + +template +ResourceId ReplayProxy::Proxied_GetLiveID(ParamSerialiser ¶mser, ReturnSerialiser &retser, + ResourceId id) +{ + if(paramser.IsWriting()) + { + if(m_LiveIDs.find(id) != m_LiveIDs.end()) + return m_LiveIDs[id]; + + if(m_LocalTextures.find(id) != m_LocalTextures.end()) + return id; + } + + if(paramser.IsErrored() || retser.IsErrored() || m_IsErrored) + return ResourceId(); + + const ReplayProxyPacket packet = eReplayProxy_GetLiveID; + ResourceId ret; + + { + BEGIN_PARAMS(); + SERIALISE_ELEMENT(id); + END_PARAMS(); + } + + if(paramser.IsReading() && !paramser.IsErrored() && !m_IsErrored) + ret = m_Remote->GetLiveID(id); + + SERIALISE_RETURN(ret); + + if(paramser.IsWriting()) + m_LiveIDs[id] = ret; + + return ret; +} + +ResourceId ReplayProxy::GetLiveID(ResourceId id) +{ + PROXY_FUNCTION(GetLiveID, id); +} + +template +std::vector ReplayProxy::Proxied_FetchCounters(ParamSerialiser ¶mser, + ReturnSerialiser &retser, + const std::vector &counters) +{ + const ReplayProxyPacket packet = eReplayProxy_FetchCounters; + std::vector ret; + + { + BEGIN_PARAMS(); + SERIALISE_ELEMENT(counters); + END_PARAMS(); + } + + if(paramser.IsReading() && !paramser.IsErrored() && !m_IsErrored) + ret = m_Remote->FetchCounters(counters); + + SERIALISE_RETURN(ret); + + return ret; +} + +std::vector ReplayProxy::FetchCounters(const std::vector &counters) +{ + PROXY_FUNCTION(FetchCounters, counters); +} + +template +std::vector ReplayProxy::Proxied_EnumerateCounters(ParamSerialiser ¶mser, + ReturnSerialiser &retser) +{ + const ReplayProxyPacket packet = eReplayProxy_EnumerateCounters; + std::vector ret; + + { + BEGIN_PARAMS(); + END_PARAMS(); + } + + if(paramser.IsReading() && !paramser.IsErrored() && !m_IsErrored) + ret = m_Remote->EnumerateCounters(); + + SERIALISE_RETURN(ret); + + return ret; +} + +std::vector ReplayProxy::EnumerateCounters() +{ + PROXY_FUNCTION(EnumerateCounters); +} + +template +CounterDescription ReplayProxy::Proxied_DescribeCounter(ParamSerialiser ¶mser, + ReturnSerialiser &retser, + GPUCounter counterID) +{ + const ReplayProxyPacket packet = eReplayProxy_DescribeCounter; + CounterDescription ret = {}; + + { + BEGIN_PARAMS(); + SERIALISE_ELEMENT(counterID); + END_PARAMS(); + } + + if(paramser.IsReading() && !paramser.IsErrored() && !m_IsErrored) + ret = m_Remote->DescribeCounter(counterID); + + SERIALISE_RETURN(ret); + + return ret; +} + +CounterDescription ReplayProxy::DescribeCounter(GPUCounter counterID) +{ + PROXY_FUNCTION(DescribeCounter, counterID); +} + +template +void ReplayProxy::Proxied_FillCBufferVariables(ParamSerialiser ¶mser, ReturnSerialiser &retser, + ResourceId shader, std::string entryPoint, + uint32_t cbufSlot, + std::vector &outvars, + const std::vector &data) +{ + const ReplayProxyPacket packet = eReplayProxy_FillCBufferVariables; + + { + BEGIN_PARAMS(); + SERIALISE_ELEMENT(shader); + SERIALISE_ELEMENT(entryPoint); + SERIALISE_ELEMENT(cbufSlot); + SERIALISE_ELEMENT(data); + END_PARAMS(); + } + + if(paramser.IsReading() && !paramser.IsErrored() && !m_IsErrored) + m_Remote->FillCBufferVariables(shader, entryPoint, cbufSlot, outvars, data); + + SERIALISE_RETURN(outvars); +} + +void ReplayProxy::FillCBufferVariables(ResourceId shader, std::string entryPoint, uint32_t cbufSlot, + std::vector &outvars, + const std::vector &data) +{ + PROXY_FUNCTION(FillCBufferVariables, shader, entryPoint, cbufSlot, outvars, data); +} + +template +void ReplayProxy::Proxied_GetBufferData(ParamSerialiser ¶mser, ReturnSerialiser &retser, + ResourceId buff, uint64_t offset, uint64_t len, + std::vector &retData) +{ + const ReplayProxyPacket packet = eReplayProxy_GetBufferData; + + { + BEGIN_PARAMS(); + SERIALISE_ELEMENT(buff); + SERIALISE_ELEMENT(offset); + SERIALISE_ELEMENT(len); + END_PARAMS(); + } + + if(paramser.IsReading() && !paramser.IsErrored() && !m_IsErrored) + m_Remote->GetBufferData(buff, offset, len, retData); + + // over-estimate of total uncompressed data written. Since the decompression chain needs to know + // the exact uncompressed size, we over-estimate (to allow for length/padding/etc) and then pad + // to this amount. + uint64_t dataSize = retData.size() + 2 * retser.GetChunkAlignment(); + + { + ReturnSerialiser &ser = retser; + PACKET_HEADER(packet); + SERIALISE_ELEMENT(dataSize); + } + + char empty[128] = {}; + + // lz4 compress + if(retser.IsReading()) + { + ReadSerialiser ser(new StreamReader(new LZ4Decompressor(retser.GetReader(), Ownership::Nothing), + dataSize, Ownership::Stream), + Ownership::Stream); + + SERIALISE_ELEMENT(retData); + + uint64_t offs = ser.GetReader()->GetOffset(); + RDCASSERT(offs <= dataSize, offs, dataSize); + RDCASSERT(dataSize - offs < sizeof(empty), offs, dataSize); + + ser.GetReader()->Read(empty, dataSize - offs); + } + else + { + WriteSerialiser ser(new StreamWriter(new LZ4Compressor(retser.GetWriter(), Ownership::Nothing), + Ownership::Stream), + Ownership::Stream); + + SERIALISE_ELEMENT(retData); + + uint64_t offs = ser.GetWriter()->GetOffset(); + RDCASSERT(offs <= dataSize, offs, dataSize); + RDCASSERT(dataSize - offs < sizeof(empty), offs, dataSize); + + ser.GetWriter()->Write(empty, dataSize - offs); + } + + retser.EndChunk(); +} + +void ReplayProxy::GetBufferData(ResourceId buff, uint64_t offset, uint64_t len, + std::vector &retData) +{ + PROXY_FUNCTION(GetBufferData, buff, offset, len, retData); +} + +template +void ReplayProxy::Proxied_GetTextureData(ParamSerialiser ¶mser, ReturnSerialiser &retser, + ResourceId tex, uint32_t arrayIdx, uint32_t mip, + const GetTextureDataParams ¶ms, bytebuf &data) +{ + const ReplayProxyPacket packet = eReplayProxy_GetTextureData; + + { + BEGIN_PARAMS(); + SERIALISE_ELEMENT(tex); + SERIALISE_ELEMENT(arrayIdx); + SERIALISE_ELEMENT(mip); + SERIALISE_ELEMENT(params); + END_PARAMS(); + } + + if(paramser.IsReading() && !paramser.IsErrored() && !m_IsErrored) + m_Remote->GetTextureData(tex, arrayIdx, mip, params, data); + + // over-estimate of total uncompressed data written. Since the decompression chain needs to know + // the exact uncompressed size, we over-estimate (to allow for length/padding/etc) and then pad + // to this amount. + uint64_t dataSize = data.size() + 2 * retser.GetChunkAlignment(); + + { + ReturnSerialiser &ser = retser; + PACKET_HEADER(packet); + SERIALISE_ELEMENT(dataSize); + } + + char empty[128] = {}; + + // lz4 compress + if(retser.IsReading()) + { + ReadSerialiser ser(new StreamReader(new LZ4Decompressor(retser.GetReader(), Ownership::Nothing), + dataSize, Ownership::Stream), + Ownership::Stream); + + SERIALISE_ELEMENT(data); + + uint64_t offs = ser.GetReader()->GetOffset(); + RDCASSERT(offs <= dataSize, offs, dataSize); + RDCASSERT(dataSize - offs < sizeof(empty), offs, dataSize); + + ser.GetReader()->Read(empty, dataSize - offs); + } + else + { + WriteSerialiser ser(new StreamWriter(new LZ4Compressor(retser.GetWriter(), Ownership::Nothing), + Ownership::Stream), + Ownership::Stream); + + SERIALISE_ELEMENT(data); + + uint64_t offs = ser.GetWriter()->GetOffset(); + RDCASSERT(offs <= dataSize, offs, dataSize); + RDCASSERT(dataSize - offs < sizeof(empty), offs, dataSize); + + ser.GetWriter()->Write(empty, dataSize - offs); + } + + retser.EndChunk(); +} + +void ReplayProxy::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, + const GetTextureDataParams ¶ms, bytebuf &data) +{ + PROXY_FUNCTION(GetTextureData, tex, arrayIdx, mip, params, data); +} + +template +void ReplayProxy::Proxied_InitPostVSBuffers(ParamSerialiser ¶mser, ReturnSerialiser &retser, + uint32_t eventID) +{ + const ReplayProxyPacket packet = eReplayProxy_InitPostVS; + + { + BEGIN_PARAMS(); + SERIALISE_ELEMENT(eventID); + END_PARAMS(); + } + + if(paramser.IsReading() && !paramser.IsErrored() && !m_IsErrored) + m_Remote->InitPostVSBuffers(eventID); +} + +void ReplayProxy::InitPostVSBuffers(uint32_t eventID) +{ + PROXY_FUNCTION(InitPostVSBuffers, eventID); +} + +template +void ReplayProxy::Proxied_InitPostVSBuffers(ParamSerialiser ¶mser, ReturnSerialiser &retser, + const std::vector &events) +{ + const ReplayProxyPacket packet = eReplayProxy_InitPostVSVec; + + { + BEGIN_PARAMS(); + SERIALISE_ELEMENT(events); + END_PARAMS(); + } + + if(paramser.IsReading() && !paramser.IsErrored() && !m_IsErrored) + m_Remote->InitPostVSBuffers(events); +} + +void ReplayProxy::InitPostVSBuffers(const std::vector &events) +{ + PROXY_FUNCTION(InitPostVSBuffers, events); +} + +template +MeshFormat ReplayProxy::Proxied_GetPostVSBuffers(ParamSerialiser ¶mser, + ReturnSerialiser &retser, uint32_t eventID, + uint32_t instID, MeshDataStage stage) +{ + const ReplayProxyPacket packet = eReplayProxy_GetPostVS; + MeshFormat ret = {}; + + { + BEGIN_PARAMS(); + SERIALISE_ELEMENT(eventID); + SERIALISE_ELEMENT(instID); + SERIALISE_ELEMENT(stage); + END_PARAMS(); + } + + if(paramser.IsReading() && !paramser.IsErrored() && !m_IsErrored) + ret = m_Remote->GetPostVSBuffers(eventID, instID, stage); + + SERIALISE_RETURN(ret); + + return ret; +} + +MeshFormat ReplayProxy::GetPostVSBuffers(uint32_t eventID, uint32_t instID, MeshDataStage stage) +{ + PROXY_FUNCTION(GetPostVSBuffers, eventID, instID, stage); +} + +template +ResourceId ReplayProxy::Proxied_RenderOverlay(ParamSerialiser ¶mser, ReturnSerialiser &retser, + ResourceId texid, CompType typeHint, + DebugOverlay overlay, uint32_t eventID, + const std::vector &passEvents) +{ + const ReplayProxyPacket packet = eReplayProxy_RenderOverlay; + ResourceId ret; + + { + BEGIN_PARAMS(); + SERIALISE_ELEMENT(texid); + SERIALISE_ELEMENT(typeHint); + SERIALISE_ELEMENT(overlay); + SERIALISE_ELEMENT(eventID); + SERIALISE_ELEMENT(passEvents); + END_PARAMS(); + } + + if(paramser.IsReading() && !paramser.IsErrored() && !m_IsErrored) + ret = m_Remote->RenderOverlay(texid, typeHint, overlay, eventID, passEvents); + + SERIALISE_RETURN(ret); + + return ret; +} + +ResourceId ReplayProxy::RenderOverlay(ResourceId texid, CompType typeHint, DebugOverlay overlay, + uint32_t eventID, const std::vector &passEvents) +{ + PROXY_FUNCTION(RenderOverlay, texid, typeHint, overlay, eventID, passEvents); +} + +template +ShaderReflection *ReplayProxy::Proxied_GetShader(ParamSerialiser ¶mser, ReturnSerialiser &retser, + ResourceId id, std::string entryPoint) +{ + const ReplayProxyPacket packet = eReplayProxy_GetShader; + ShaderReflection *ret; + + ShaderReflKey key(id, entryPoint); + + if(retser.IsReading() && m_ShaderReflectionCache.find(key) != m_ShaderReflectionCache.end()) + return m_ShaderReflectionCache[key]; + + { + BEGIN_PARAMS(); + SERIALISE_ELEMENT(id); + SERIALISE_ELEMENT(entryPoint); + END_PARAMS(); + } + + if(paramser.IsReading() && !paramser.IsErrored() && !m_IsErrored) + ret = m_Remote->GetShader(id, entryPoint); + + { + ReturnSerialiser &ser = retser; + PACKET_HEADER(packet); + SERIALISE_ELEMENT_OPT(ret); + ser.EndChunk(); + + // if we're reading, we should have checked the cache above. If we didn't, we need to steal the + // serialised pointer here into our cache + if(ser.IsReading()) + { + m_ShaderReflectionCache[key] = ret; + ret = NULL; + } + } + + return m_ShaderReflectionCache[key]; +} + +ShaderReflection *ReplayProxy::GetShader(ResourceId id, std::string entryPoint) +{ + PROXY_FUNCTION(GetShader, id, entryPoint); +} + +template +std::string ReplayProxy::Proxied_DisassembleShader(ParamSerialiser ¶mser, + ReturnSerialiser &retser, ResourceId pipeline, + const ShaderReflection *refl, + const std::string &target) +{ + const ReplayProxyPacket packet = eReplayProxy_DisassembleShader; + ResourceId Shader; + std::string EntryPoint; + std::string ret; + + if(refl) + { + Shader = refl->ID; + EntryPoint = refl->EntryPoint; + } + + { + BEGIN_PARAMS(); + SERIALISE_ELEMENT(pipeline); + SERIALISE_ELEMENT(Shader); + SERIALISE_ELEMENT(EntryPoint); + SERIALISE_ELEMENT(target); + END_PARAMS(); + } + + if(paramser.IsReading() && !paramser.IsErrored() && !m_IsErrored) + { + refl = m_Remote->GetShader(m_Remote->GetLiveID(Shader), EntryPoint); + ret = m_Remote->DisassembleShader(pipeline, refl, target); + } + + SERIALISE_RETURN(ret); + + return ret; +} + +std::string ReplayProxy::DisassembleShader(ResourceId pipeline, const ShaderReflection *refl, + const std::string &target) +{ + PROXY_FUNCTION(DisassembleShader, pipeline, refl, target); +} + +template +std::vector ReplayProxy::Proxied_GetDisassemblyTargets(ParamSerialiser ¶mser, + ReturnSerialiser &retser) +{ + const ReplayProxyPacket packet = eReplayProxy_GetDisassemblyTargets; + std::vector ret; + + { + BEGIN_PARAMS(); + END_PARAMS(); + } + + if(paramser.IsReading() && !paramser.IsErrored() && !m_IsErrored) + ret = m_Remote->GetDisassemblyTargets(); + + SERIALISE_RETURN(ret); + + return ret; +} + +std::vector ReplayProxy::GetDisassemblyTargets() +{ + PROXY_FUNCTION(GetDisassemblyTargets); +} + +template +void ReplayProxy::Proxied_FreeTargetResource(ParamSerialiser ¶mser, ReturnSerialiser &retser, + ResourceId id) +{ + const ReplayProxyPacket packet = eReplayProxy_FreeTargetResource; + + { + BEGIN_PARAMS(); + SERIALISE_ELEMENT(id); + END_PARAMS(); + } + + if(paramser.IsReading() && !paramser.IsErrored() && !m_IsErrored) + m_Remote->FreeTargetResource(id); +} + +void ReplayProxy::FreeTargetResource(ResourceId id) +{ + PROXY_FUNCTION(FreeTargetResource, id); +} + +template +void ReplayProxy::Proxied_BuildTargetShader(ParamSerialiser ¶mser, ReturnSerialiser &retser, + std::string source, std::string entry, + const ShaderCompileFlags &compileFlags, + ShaderStage type, ResourceId *id, std::string *errors) +{ + const ReplayProxyPacket packet = eReplayProxy_BuildTargetShader; + ResourceId ret_id; + std::string ret_errors; + + { + BEGIN_PARAMS(); + SERIALISE_ELEMENT(source); + SERIALISE_ELEMENT(entry); + SERIALISE_ELEMENT(compileFlags); + SERIALISE_ELEMENT(type); + END_PARAMS(); + } + + if(paramser.IsReading() && !paramser.IsErrored() && !m_IsErrored) + m_Remote->BuildTargetShader(source, entry, compileFlags, type, &ret_id, &ret_errors); + + { + ReturnSerialiser &ser = retser; + PACKET_HEADER(packet); + SERIALISE_ELEMENT(ret_id); + SERIALISE_ELEMENT(ret_errors); + ser.EndChunk(); + + if(id) + *id = ret_id; + if(errors) + *errors = ret_errors; + } +} + +void ReplayProxy::BuildTargetShader(std::string source, std::string entry, + const ShaderCompileFlags &compileFlags, ShaderStage type, + ResourceId *id, std::string *errors) +{ + PROXY_FUNCTION(BuildTargetShader, source, entry, compileFlags, type, id, errors); +} + +template +void ReplayProxy::Proxied_ReplaceResource(ParamSerialiser ¶mser, ReturnSerialiser &retser, + ResourceId from, ResourceId to) +{ + const ReplayProxyPacket packet = eReplayProxy_ReplaceResource; + + { + BEGIN_PARAMS(); + SERIALISE_ELEMENT(from); + SERIALISE_ELEMENT(to); + END_PARAMS(); + } + + if(paramser.IsReading() && !paramser.IsErrored() && !m_IsErrored) + m_Remote->ReplaceResource(from, to); +} + +void ReplayProxy::ReplaceResource(ResourceId from, ResourceId to) +{ + PROXY_FUNCTION(ReplaceResource, from, to); +} + +template +void ReplayProxy::Proxied_RemoveReplacement(ParamSerialiser ¶mser, ReturnSerialiser &retser, + ResourceId id) +{ + const ReplayProxyPacket packet = eReplayProxy_RemoveReplacement; + + { + BEGIN_PARAMS(); + SERIALISE_ELEMENT(id); + END_PARAMS(); + } + + if(paramser.IsReading() && !paramser.IsErrored() && !m_IsErrored) + m_Remote->RemoveReplacement(id); +} + +void ReplayProxy::RemoveReplacement(ResourceId id) +{ + PROXY_FUNCTION(RemoveReplacement, id); +} + +template +std::vector ReplayProxy::Proxied_PixelHistory( + ParamSerialiser ¶mser, ReturnSerialiser &retser, std::vector events, + ResourceId target, uint32_t x, uint32_t y, uint32_t slice, uint32_t mip, uint32_t sampleIdx, + CompType typeHint) +{ + const ReplayProxyPacket packet = eReplayProxy_PixelHistory; + std::vector ret; + + { + BEGIN_PARAMS(); + SERIALISE_ELEMENT(events); + SERIALISE_ELEMENT(target); + SERIALISE_ELEMENT(x); + SERIALISE_ELEMENT(y); + SERIALISE_ELEMENT(slice); + SERIALISE_ELEMENT(mip); + SERIALISE_ELEMENT(sampleIdx); + SERIALISE_ELEMENT(typeHint); + END_PARAMS(); + } + + if(paramser.IsReading() && !paramser.IsErrored() && !m_IsErrored) + ret = m_Remote->PixelHistory(events, target, x, y, slice, mip, sampleIdx, typeHint); + + SERIALISE_RETURN(ret); + + return ret; +} + +std::vector ReplayProxy::PixelHistory(std::vector events, + ResourceId target, uint32_t x, uint32_t y, + uint32_t slice, uint32_t mip, + uint32_t sampleIdx, CompType typeHint) +{ + PROXY_FUNCTION(PixelHistory, events, target, x, y, slice, mip, sampleIdx, typeHint); +} + +template +ShaderDebugTrace ReplayProxy::Proxied_DebugVertex(ParamSerialiser ¶mser, + ReturnSerialiser &retser, uint32_t eventID, + uint32_t vertid, uint32_t instid, uint32_t idx, + uint32_t instOffset, uint32_t vertOffset) +{ + const ReplayProxyPacket packet = eReplayProxy_DebugVertex; + ShaderDebugTrace ret; + + { + BEGIN_PARAMS(); + SERIALISE_ELEMENT(eventID); + SERIALISE_ELEMENT(vertid); + SERIALISE_ELEMENT(instid); + SERIALISE_ELEMENT(idx); + SERIALISE_ELEMENT(instOffset); + SERIALISE_ELEMENT(vertOffset); + END_PARAMS(); + } + + if(paramser.IsReading() && !paramser.IsErrored() && !m_IsErrored) + ret = m_Remote->DebugVertex(eventID, vertid, instid, idx, instOffset, vertOffset); + + SERIALISE_RETURN(ret); + + return ret; +} + +ShaderDebugTrace ReplayProxy::DebugVertex(uint32_t eventID, uint32_t vertid, uint32_t instid, + uint32_t idx, uint32_t instOffset, uint32_t vertOffset) +{ + PROXY_FUNCTION(DebugVertex, eventID, vertid, instid, idx, instOffset, vertOffset); +} + +template +ShaderDebugTrace ReplayProxy::Proxied_DebugPixel(ParamSerialiser ¶mser, ReturnSerialiser &retser, + uint32_t eventID, uint32_t x, uint32_t y, + uint32_t sample, uint32_t primitive) +{ + const ReplayProxyPacket packet = eReplayProxy_DebugPixel; + ShaderDebugTrace ret; + + { + BEGIN_PARAMS(); + SERIALISE_ELEMENT(eventID); + SERIALISE_ELEMENT(x); + SERIALISE_ELEMENT(y); + SERIALISE_ELEMENT(sample); + SERIALISE_ELEMENT(primitive); + END_PARAMS(); + } + + if(paramser.IsReading() && !paramser.IsErrored() && !m_IsErrored) + ret = m_Remote->DebugPixel(eventID, x, y, sample, primitive); + + SERIALISE_RETURN(ret); + + return ret; +} + +ShaderDebugTrace ReplayProxy::DebugPixel(uint32_t eventID, uint32_t x, uint32_t y, uint32_t sample, + uint32_t primitive) +{ + PROXY_FUNCTION(DebugPixel, eventID, x, y, sample, primitive); +} + +template +ShaderDebugTrace ReplayProxy::Proxied_DebugThread(ParamSerialiser ¶mser, ReturnSerialiser &retser, + uint32_t eventID, const uint32_t groupid[3], + const uint32_t threadid[3]) +{ + const ReplayProxyPacket packet = eReplayProxy_DebugThread; + ShaderDebugTrace ret; + + uint32_t GroupID[3] = {groupid[0], groupid[1], groupid[2]}; + uint32_t ThreadID[3] = {threadid[0], threadid[1], threadid[2]}; + + { + BEGIN_PARAMS(); + SERIALISE_ELEMENT(eventID); + SERIALISE_ELEMENT(GroupID); + SERIALISE_ELEMENT(ThreadID); + END_PARAMS(); + } + + if(paramser.IsReading() && !paramser.IsErrored() && !m_IsErrored) + ret = m_Remote->DebugThread(eventID, GroupID, ThreadID); + + SERIALISE_RETURN(ret); + + return ret; +} + +ShaderDebugTrace ReplayProxy::DebugThread(uint32_t eventID, const uint32_t groupid[3], + const uint32_t threadid[3]) +{ + PROXY_FUNCTION(DebugThread, eventID, groupid, threadid); +} + +template +void ReplayProxy::Proxied_SavePipelineState(ParamSerialiser ¶mser, ReturnSerialiser &retser) +{ + const ReplayProxyPacket packet = eReplayProxy_SavePipelineState; + + { + BEGIN_PARAMS(); + END_PARAMS(); + } + + if(paramser.IsReading() && !paramser.IsErrored() && !m_IsErrored) + { + m_Remote->SavePipelineState(); + + if(m_APIProps.pipelineType == GraphicsAPI::D3D11) + m_D3D11PipelineState = m_Remote->GetD3D11PipelineState(); + else if(m_APIProps.pipelineType == GraphicsAPI::D3D12) + m_D3D12PipelineState = m_Remote->GetD3D12PipelineState(); + else if(m_APIProps.pipelineType == GraphicsAPI::OpenGL) + m_GLPipelineState = m_Remote->GetGLPipelineState(); + else if(m_APIProps.pipelineType == GraphicsAPI::Vulkan) + m_VulkanPipelineState = m_Remote->GetVulkanPipelineState(); + } + + { + ReturnSerialiser &ser = retser; + PACKET_HEADER(packet); + if(m_APIProps.pipelineType == GraphicsAPI::D3D11) + { + SERIALISE_ELEMENT(m_D3D11PipelineState); + } + else if(m_APIProps.pipelineType == GraphicsAPI::D3D12) + { + SERIALISE_ELEMENT(m_D3D12PipelineState); + } + else if(m_APIProps.pipelineType == GraphicsAPI::OpenGL) + { + SERIALISE_ELEMENT(m_GLPipelineState); + } + else if(m_APIProps.pipelineType == GraphicsAPI::Vulkan) + { + SERIALISE_ELEMENT(m_VulkanPipelineState); + } + ser.EndChunk(); + + if(retser.IsReading()) + { + if(m_APIProps.pipelineType == GraphicsAPI::D3D11) + { + D3D11Pipe::Shader *stages[] = { + &m_D3D11PipelineState.m_VS, &m_D3D11PipelineState.m_HS, &m_D3D11PipelineState.m_DS, + &m_D3D11PipelineState.m_GS, &m_D3D11PipelineState.m_PS, &m_D3D11PipelineState.m_CS, + }; + + for(int i = 0; i < 6; i++) + if(stages[i]->Object != ResourceId()) + stages[i]->ShaderDetails = GetShader(GetLiveID(stages[i]->Object), ""); + + if(m_D3D11PipelineState.m_IA.layout != ResourceId()) + m_D3D11PipelineState.m_IA.Bytecode = + GetShader(GetLiveID(m_D3D11PipelineState.m_IA.layout), ""); + } + else if(m_APIProps.pipelineType == GraphicsAPI::D3D12) + { + D3D12Pipe::Shader *stages[] = { + &m_D3D12PipelineState.m_VS, &m_D3D12PipelineState.m_HS, &m_D3D12PipelineState.m_DS, + &m_D3D12PipelineState.m_GS, &m_D3D12PipelineState.m_PS, &m_D3D12PipelineState.m_CS, + }; + + for(int i = 0; i < 6; i++) + if(stages[i]->Object != ResourceId()) + stages[i]->ShaderDetails = GetShader(GetLiveID(stages[i]->Object), ""); + } + else if(m_APIProps.pipelineType == GraphicsAPI::OpenGL) + { + GLPipe::Shader *stages[] = { + &m_GLPipelineState.m_VS, &m_GLPipelineState.m_TCS, &m_GLPipelineState.m_TES, + &m_GLPipelineState.m_GS, &m_GLPipelineState.m_FS, &m_GLPipelineState.m_CS, + }; + + for(int i = 0; i < 6; i++) + if(stages[i]->Object != ResourceId()) + stages[i]->ShaderDetails = GetShader(GetLiveID(stages[i]->Object), ""); + } + else if(m_APIProps.pipelineType == GraphicsAPI::Vulkan) + { + VKPipe::Shader *stages[] = { + &m_VulkanPipelineState.m_VS, &m_VulkanPipelineState.m_TCS, &m_VulkanPipelineState.m_TES, + &m_VulkanPipelineState.m_GS, &m_VulkanPipelineState.m_FS, &m_VulkanPipelineState.m_CS, + }; + + for(int i = 0; i < 6; i++) + if(stages[i]->Object != ResourceId()) + stages[i]->ShaderDetails = GetShader(GetLiveID(stages[i]->Object), stages[i]->entryPoint); + } + } + } +} + +void ReplayProxy::SavePipelineState() +{ + PROXY_FUNCTION(SavePipelineState); +} + +template +void ReplayProxy::Proxied_ReplayLog(ParamSerialiser ¶mser, ReturnSerialiser &retser, + uint32_t endEventID, ReplayLogType replayType) +{ + const ReplayProxyPacket packet = eReplayProxy_ReplayLog; + + { + BEGIN_PARAMS(); + SERIALISE_ELEMENT(endEventID); + SERIALISE_ELEMENT(replayType); + END_PARAMS(); + } + + if(paramser.IsReading() && !paramser.IsErrored() && !m_IsErrored) + m_Remote->ReplayLog(endEventID, replayType); + + if(retser.IsReading()) + { + m_TextureProxyCache.clear(); + m_BufferProxyCache.clear(); + + if(m_APIProps.shadersMutable) + { + for(auto it = m_ShaderReflectionCache.begin(); it != m_ShaderReflectionCache.end(); ++it) + delete it->second; + m_ShaderReflectionCache.clear(); + } + } +} + +void ReplayProxy::ReplayLog(uint32_t endEventID, ReplayLogType replayType) +{ + PROXY_FUNCTION(ReplayLog, endEventID, replayType); +} + +#pragma endregion Proxied Functions + // If a remap is required, modify the params that are used when getting the proxy texture data // for replay on the current driver. void ReplayProxy::RemapProxyTextureIfNeeded(TextureDescription &tex, GetTextureDataParams ¶ms) @@ -1855,7 +1265,7 @@ void ReplayProxy::RemapProxyTextureIfNeeded(TextureDescription &tex, GetTextureD { // currently only OpenGL ES need to remap all the depth formats for fetch // when depth read is not supported - params.remap = eRemap_RGBA32; + params.remap = RemapTexture::RGBA32; tex.format.compCount = 4; tex.format.compByteWidth = 4; tex.format.compType = CompType::Float; @@ -1872,15 +1282,15 @@ void ReplayProxy::RemapProxyTextureIfNeeded(TextureDescription &tex, GetTextureD switch(tex.format.type) { case ResourceFormatType::S8: - case ResourceFormatType::D16S8: params.remap = eRemap_D32S8; break; - case ResourceFormatType::ASTC: params.remap = eRemap_RGBA16; break; + case ResourceFormatType::D16S8: params.remap = RemapTexture::D32S8; break; + case ResourceFormatType::ASTC: params.remap = RemapTexture::RGBA16; break; case ResourceFormatType::EAC: case ResourceFormatType::R5G6B5: - case ResourceFormatType::ETC2: params.remap = eRemap_RGBA8; break; + case ResourceFormatType::ETC2: params.remap = RemapTexture::RGBA8; break; default: RDCERR("Don't know how to remap resource format type %u, falling back to RGBA32", tex.format.type); - params.remap = eRemap_RGBA32; + params.remap = RemapTexture::RGBA32; break; } tex.format.type = ResourceFormatType::Regular; @@ -1888,40 +1298,40 @@ void ReplayProxy::RemapProxyTextureIfNeeded(TextureDescription &tex, GetTextureD else { if(tex.format.compByteWidth == 4) - params.remap = eRemap_RGBA32; + params.remap = RemapTexture::RGBA32; else if(tex.format.compByteWidth == 2) - params.remap = eRemap_RGBA16; + params.remap = RemapTexture::RGBA16; else if(tex.format.compByteWidth == 1) - params.remap = eRemap_RGBA8; + params.remap = RemapTexture::RGBA8; } switch(params.remap) { - case eRemap_None: RDCERR("IsTextureSupported == false, but we have no remap"); break; - case eRemap_RGBA8: + case RemapTexture::NoRemap: RDCERR("IsTextureSupported == false, but we have no remap"); break; + case RemapTexture::RGBA8: tex.format.compCount = 4; tex.format.compByteWidth = 1; tex.format.compType = CompType::UNorm; // Range adaptation is only needed when remapping a higher precision format down to RGBA8. params.whitePoint = 1.0f; break; - case eRemap_RGBA16: + case RemapTexture::RGBA16: tex.format.compCount = 4; tex.format.compByteWidth = 2; tex.format.compType = CompType::Float; break; - case eRemap_RGBA32: + case RemapTexture::RGBA32: tex.format.compCount = 4; tex.format.compByteWidth = 4; tex.format.compType = CompType::Float; break; - case eRemap_D32S8: RDCERR("Remapping depth/stencil formats not implemented."); break; + case RemapTexture::D32S8: RDCERR("Remapping depth/stencil formats not implemented."); break; } } void ReplayProxy::EnsureTexCached(ResourceId texid, uint32_t arrayIdx, uint32_t mip) { - if(!m_Socket->Connected()) + if(m_Reader.IsErrored() || m_Writer.IsErrored()) return; TextureCacheEntry entry = {texid, arrayIdx, mip}; @@ -1944,13 +1354,11 @@ void ReplayProxy::EnsureTexCached(ResourceId texid, uint32_t arrayIdx, uint32_t const ProxyTextureProperties &proxy = m_ProxyTextures[texid]; - size_t size; - byte *data = GetTextureData(texid, arrayIdx, mip, proxy.params, size); + bytebuf data; + GetTextureData(texid, arrayIdx, mip, proxy.params, data); - if(data) - m_Proxy->SetProxyTextureData(proxy.id, arrayIdx, mip, data, size); - - delete[] data; + if(!data.empty()) + m_Proxy->SetProxyTextureData(proxy.id, arrayIdx, mip, data.data(), data.size()); m_TextureProxyCache.insert(entry); } @@ -1958,7 +1366,7 @@ void ReplayProxy::EnsureTexCached(ResourceId texid, uint32_t arrayIdx, uint32_t void ReplayProxy::EnsureBufCached(ResourceId bufid) { - if(!m_Socket->Connected()) + if(m_Reader.IsErrored() || m_Writer.IsErrored()) return; if(m_BufferProxyCache.find(bufid) == m_BufferProxyCache.end()) @@ -1981,103 +1389,63 @@ void ReplayProxy::EnsureBufCached(ResourceId bufid) } } -bool ReplayProxy::NeedRemapForFetch(const ResourceFormat &_format) -{ - ResourceFormat format = _format; - - m_ToReplaySerialiser->Serialise("", format); - - bool bNeedRemap; - - if(m_RemoteServer) - { - bNeedRemap = m_Remote->NeedRemapForFetch(format); - - m_FromReplaySerialiser->Serialise("", bNeedRemap); - } - else - { - if(!SendReplayCommand(eReplayProxy_NeedRemapForFetch)) - { - return false; - } - - m_FromReplaySerialiser->Serialise("", bNeedRemap); - } - - return bNeedRemap; -} - -bool ReplayProxy::Tick(int type, Serialiser *incomingPacket) +bool ReplayProxy::Tick(int type) { if(!m_RemoteServer) return true; - if(!m_Socket || !m_Socket->Connected()) + if(m_Writer.IsErrored() || m_Reader.IsErrored() || m_IsErrored) return false; - m_ToReplaySerialiser = incomingPacket; - - m_FromReplaySerialiser->Rewind(); - switch(type) { case eReplayProxy_ReplayLog: ReplayLog(0, (ReplayLogType)0); break; - case eReplayProxy_GetPassEvents: GetPassEvents(0); break; case eReplayProxy_GetAPIProperties: GetAPIProperties(); break; + case eReplayProxy_GetPassEvents: GetPassEvents(0); break; case eReplayProxy_GetTextures: GetTextures(); break; case eReplayProxy_GetTexture: GetTexture(ResourceId()); break; case eReplayProxy_GetBuffers: GetBuffers(); break; case eReplayProxy_GetBuffer: GetBuffer(ResourceId()); break; case eReplayProxy_GetShader: GetShader(ResourceId(), ""); break; case eReplayProxy_GetDebugMessages: GetDebugMessages(); break; + case eReplayProxy_GetBufferData: + { + std::vector dummy; + GetBufferData(ResourceId(), 0, 0, dummy); + break; + } + case eReplayProxy_GetTextureData: + { + bytebuf dummy; + GetTextureData(ResourceId(), 0, 0, GetTextureDataParams(), dummy); + break; + } case eReplayProxy_SavePipelineState: SavePipelineState(); break; case eReplayProxy_GetUsage: GetUsage(ResourceId()); break; case eReplayProxy_GetLiveID: GetLiveID(ResourceId()); break; case eReplayProxy_GetFrameRecord: GetFrameRecord(); break; case eReplayProxy_IsRenderOutput: IsRenderOutput(ResourceId()); break; case eReplayProxy_NeedRemapForFetch: NeedRemapForFetch(ResourceFormat()); break; - case eReplayProxy_HasResolver: HasCallstacks(); break; - case eReplayProxy_InitStackResolver: InitCallstackResolver(); break; - case eReplayProxy_HasStackResolver: GetCallstackResolver(); break; - case eReplayProxy_GetAddressDetails: GetAddr(0); break; - case eReplayProxy_FreeResource: FreeTargetResource(ResourceId()); break; + case eReplayProxy_FreeTargetResource: FreeTargetResource(ResourceId()); break; case eReplayProxy_FetchCounters: { - vector counters; + std::vector counters; FetchCounters(counters); break; } case eReplayProxy_EnumerateCounters: EnumerateCounters(); break; - case eReplayProxy_DescribeCounter: - { - CounterDescription desc; - DescribeCounter(GPUCounter::EventGPUDuration, desc); - break; - } + case eReplayProxy_DescribeCounter: DescribeCounter(GPUCounter::EventGPUDuration); break; case eReplayProxy_FillCBufferVariables: { - vector vars; - vector data; + std::vector vars; + std::vector data; FillCBufferVariables(ResourceId(), "", 0, vars, data); break; } - case eReplayProxy_GetBufferData: - { - vector dummy; - GetBufferData(ResourceId(), 0, 0, dummy); - break; - } - case eReplayProxy_GetTextureData: - { - size_t dummy; - GetTextureData(ResourceId(), 0, 0, GetTextureDataParams(), dummy); - break; - } case eReplayProxy_InitPostVS: InitPostVSBuffers(0); break; case eReplayProxy_InitPostVSVec: { - vector dummy; + std::vector dummy; InitPostVSBuffers(dummy); break; } @@ -2087,12 +1455,6 @@ bool ReplayProxy::Tick(int type, Serialiser *incomingPacket) break; case eReplayProxy_ReplaceResource: ReplaceResource(ResourceId(), ResourceId()); break; case eReplayProxy_RemoveReplacement: RemoveReplacement(ResourceId()); break; - case eReplayProxy_RenderOverlay: - RenderOverlay(ResourceId(), CompType::Typeless, DebugOverlay::NoOverlay, 0, vector()); - break; - case eReplayProxy_PixelHistory: - PixelHistory(vector(), ResourceId(), 0, 0, 0, 0, 0, CompType::Typeless); - break; case eReplayProxy_DebugVertex: DebugVertex(0, 0, 0, 0, 0, 0); break; case eReplayProxy_DebugPixel: DebugPixel(0, 0, 0, 0, 0); break; case eReplayProxy_DebugThread: @@ -2102,990 +1464,19 @@ bool ReplayProxy::Tick(int type, Serialiser *incomingPacket) DebugThread(0, dummy1, dummy2); break; } + case eReplayProxy_RenderOverlay: + RenderOverlay(ResourceId(), CompType::Typeless, DebugOverlay::NoOverlay, 0, vector()); + break; + case eReplayProxy_PixelHistory: + PixelHistory(vector(), ResourceId(), 0, 0, 0, 0, 0, CompType::Typeless); + break; case eReplayProxy_DisassembleShader: DisassembleShader(ResourceId(), NULL, ""); break; - case eReplayProxy_GetISATargets: GetDisassemblyTargets(); break; - default: RDCERR("Unexpected command"); return false; + case eReplayProxy_GetDisassemblyTargets: GetDisassemblyTargets(); break; + default: RDCERR("Unexpected command %u", type); return false; } - if(!SendPacket(m_Socket, type, *m_FromReplaySerialiser)) + if(m_Writer.IsErrored() || m_Reader.IsErrored() || m_IsErrored) return false; return true; } - -bool ReplayProxy::IsRenderOutput(ResourceId id) -{ - bool ret = false; - - m_ToReplaySerialiser->Serialise("", id); - - if(m_RemoteServer) - { - ret = m_Remote->IsRenderOutput(id); - } - else - { - if(!SendReplayCommand(eReplayProxy_IsRenderOutput)) - return ret; - } - - m_FromReplaySerialiser->Serialise("", ret); - - return ret; -} - -APIProperties ReplayProxy::GetAPIProperties() -{ - APIProperties ret; - RDCEraseEl(ret); - - if(m_RemoteServer) - { - ret = m_Remote->GetAPIProperties(); - } - else - { - if(!SendReplayCommand(eReplayProxy_GetAPIProperties)) - return ret; - } - - m_FromReplaySerialiser->Serialise("", ret); - - if(!m_RemoteServer) - ret.localRenderer = m_Proxy->GetAPIProperties().localRenderer; - - m_APIProps = ret; - - return ret; -} - -vector ReplayProxy::GetTextures() -{ - vector ret; - - if(m_RemoteServer) - { - ret = m_Remote->GetTextures(); - } - else - { - if(!SendReplayCommand(eReplayProxy_GetTextures)) - return ret; - } - - m_FromReplaySerialiser->Serialise("", ret); - - return ret; -} - -vector ReplayProxy::GetDebugMessages() -{ - vector ret; - - if(m_RemoteServer) - { - ret = m_Remote->GetDebugMessages(); - } - else - { - if(!SendReplayCommand(eReplayProxy_GetDebugMessages)) - return ret; - } - - m_FromReplaySerialiser->Serialise("", ret); - - return ret; -} - -TextureDescription ReplayProxy::GetTexture(ResourceId id) -{ - TextureDescription ret = {}; - - m_ToReplaySerialiser->Serialise("", id); - - if(m_RemoteServer) - { - ret = m_Remote->GetTexture(id); - } - else - { - if(!SendReplayCommand(eReplayProxy_GetTexture)) - return ret; - } - - m_FromReplaySerialiser->Serialise("", ret); - - return ret; -} - -vector ReplayProxy::GetBuffers() -{ - vector ret; - - if(m_RemoteServer) - { - ret = m_Remote->GetBuffers(); - } - else - { - if(!SendReplayCommand(eReplayProxy_GetBuffers)) - return ret; - } - - m_FromReplaySerialiser->Serialise("", ret); - - return ret; -} - -BufferDescription ReplayProxy::GetBuffer(ResourceId id) -{ - BufferDescription ret = {}; - - m_ToReplaySerialiser->Serialise("", id); - - if(m_RemoteServer) - { - ret = m_Remote->GetBuffer(id); - } - else - { - if(!SendReplayCommand(eReplayProxy_GetBuffer)) - return ret; - } - - m_FromReplaySerialiser->Serialise("", ret); - - return ret; -} - -void ReplayProxy::SavePipelineState() -{ - if(m_RemoteServer) - { - m_Remote->SavePipelineState(); - m_D3D11PipelineState = m_Remote->GetD3D11PipelineState(); - m_D3D12PipelineState = m_Remote->GetD3D12PipelineState(); - m_GLPipelineState = m_Remote->GetGLPipelineState(); - m_VulkanPipelineState = m_Remote->GetVulkanPipelineState(); - } - else - { - if(!SendReplayCommand(eReplayProxy_SavePipelineState)) - return; - - m_D3D11PipelineState = D3D11Pipe::State(); - m_D3D12PipelineState = D3D12Pipe::State(); - m_GLPipelineState = GLPipe::State(); - m_VulkanPipelineState = VKPipe::State(); - } - - m_FromReplaySerialiser->Serialise("", m_D3D11PipelineState); - m_FromReplaySerialiser->Serialise("", m_D3D12PipelineState); - m_FromReplaySerialiser->Serialise("", m_GLPipelineState); - m_FromReplaySerialiser->Serialise("", m_VulkanPipelineState); - - if(!m_RemoteServer) - { - { - D3D11Pipe::Shader *stages[] = { - &m_D3D11PipelineState.m_VS, &m_D3D11PipelineState.m_HS, &m_D3D11PipelineState.m_DS, - &m_D3D11PipelineState.m_GS, &m_D3D11PipelineState.m_PS, &m_D3D11PipelineState.m_CS, - }; - - for(int i = 0; i < 6; i++) - if(stages[i]->Object != ResourceId()) - stages[i]->ShaderDetails = GetShader(GetLiveID(stages[i]->Object), ""); - } - - { - D3D12Pipe::Shader *stages[] = { - &m_D3D12PipelineState.m_VS, &m_D3D12PipelineState.m_HS, &m_D3D12PipelineState.m_DS, - &m_D3D12PipelineState.m_GS, &m_D3D12PipelineState.m_PS, &m_D3D12PipelineState.m_CS, - }; - - for(int i = 0; i < 6; i++) - if(stages[i]->Object != ResourceId()) - stages[i]->ShaderDetails = GetShader(GetLiveID(stages[i]->Object), ""); - } - - { - GLPipe::Shader *stages[] = { - &m_GLPipelineState.m_VS, &m_GLPipelineState.m_TCS, &m_GLPipelineState.m_TES, - &m_GLPipelineState.m_GS, &m_GLPipelineState.m_FS, &m_GLPipelineState.m_CS, - }; - - for(int i = 0; i < 6; i++) - if(stages[i]->Object != ResourceId()) - stages[i]->ShaderDetails = GetShader(GetLiveID(stages[i]->Object), ""); - } - - { - VKPipe::Shader *stages[] = { - &m_VulkanPipelineState.m_VS, &m_VulkanPipelineState.m_TCS, &m_VulkanPipelineState.m_TES, - &m_VulkanPipelineState.m_GS, &m_VulkanPipelineState.m_FS, &m_VulkanPipelineState.m_CS, - }; - - for(int i = 0; i < 6; i++) - if(stages[i]->Object != ResourceId()) - stages[i]->ShaderDetails = GetShader(GetLiveID(stages[i]->Object), stages[i]->entryPoint); - } - } -} - -void ReplayProxy::ReplayLog(uint32_t endEventID, ReplayLogType replayType) -{ - m_ToReplaySerialiser->Serialise("", endEventID); - m_ToReplaySerialiser->Serialise("", replayType); - - if(m_RemoteServer) - { - m_Remote->ReplayLog(endEventID, replayType); - } - else - { - if(!SendReplayCommand(eReplayProxy_ReplayLog)) - return; - - m_TextureProxyCache.clear(); - m_BufferProxyCache.clear(); - } -} - -vector ReplayProxy::GetPassEvents(uint32_t eventID) -{ - vector ret; - - m_ToReplaySerialiser->Serialise("", eventID); - - if(m_RemoteServer) - { - ret = m_Remote->GetPassEvents(eventID); - } - else - { - if(!SendReplayCommand(eReplayProxy_GetPassEvents)) - return ret; - } - - m_FromReplaySerialiser->Serialise("", ret); - - return ret; -} - -vector ReplayProxy::GetUsage(ResourceId id) -{ - vector ret; - - m_ToReplaySerialiser->Serialise("", id); - - if(m_RemoteServer) - { - ret = m_Remote->GetUsage(id); - } - else - { - if(!SendReplayCommand(eReplayProxy_GetUsage)) - return ret; - } - - m_FromReplaySerialiser->Serialise("", ret); - - return ret; -} - -FrameRecord ReplayProxy::GetFrameRecord() -{ - FrameRecord ret; - - if(m_RemoteServer) - { - ret = m_Remote->GetFrameRecord(); - } - else - { - if(!SendReplayCommand(eReplayProxy_GetFrameRecord)) - return ret; - } - - m_FromReplaySerialiser->Serialise("", ret); - - return ret; -} - -bool ReplayProxy::HasCallstacks() -{ - bool ret = false; - - RDCASSERT(m_RemoteServer || m_ToReplaySerialiser->GetSize() == 0); - - if(m_RemoteServer) - { - ret = m_Remote->HasCallstacks(); - } - else - { - if(!SendReplayCommand(eReplayProxy_HasResolver)) - return ret; - } - - RDCASSERT(!m_RemoteServer || m_FromReplaySerialiser->GetSize() == 0); - - m_FromReplaySerialiser->Serialise("", ret); - - return ret; -} - -ResourceId ReplayProxy::GetLiveID(ResourceId id) -{ - if(!m_RemoteServer && m_LiveIDs.find(id) != m_LiveIDs.end()) - return m_LiveIDs[id]; - - if(!m_RemoteServer && m_LocalTextures.find(id) != m_LocalTextures.end()) - return id; - - if(!m_Socket->Connected()) - return ResourceId(); - - ResourceId ret; - - RDCASSERT(m_RemoteServer || m_ToReplaySerialiser->GetSize() == 0); - - m_ToReplaySerialiser->Serialise("", id); - - if(m_RemoteServer) - { - ret = m_Remote->GetLiveID(id); - } - else - { - if(!SendReplayCommand(eReplayProxy_GetLiveID)) - return ret; - } - - RDCASSERT(!m_RemoteServer || m_FromReplaySerialiser->GetSize() == 0); - - m_FromReplaySerialiser->Serialise("", ret); - - if(!m_RemoteServer) - m_LiveIDs[id] = ret; - - return ret; -} - -vector ReplayProxy::FetchCounters(const vector &counters) -{ - vector ret; - - m_ToReplaySerialiser->Serialise("", (vector &)counters); - - if(m_RemoteServer) - { - ret = m_Remote->FetchCounters(counters); - } - else - { - if(!SendReplayCommand(eReplayProxy_FetchCounters)) - return ret; - } - - m_FromReplaySerialiser->Serialise("", ret); - - return ret; -} - -vector ReplayProxy::EnumerateCounters() -{ - vector ret; - - if(m_RemoteServer) - { - ret = m_Remote->EnumerateCounters(); - } - else - { - if(!SendReplayCommand(eReplayProxy_EnumerateCounters)) - return ret; - } - - m_FromReplaySerialiser->Serialise("", ret); - - return ret; -} - -void ReplayProxy::DescribeCounter(GPUCounter counterID, CounterDescription &desc) -{ - m_ToReplaySerialiser->Serialise("", counterID); - - if(m_RemoteServer) - { - m_Remote->DescribeCounter(counterID, desc); - } - else - { - if(!SendReplayCommand(eReplayProxy_DescribeCounter)) - return; - } - - m_FromReplaySerialiser->Serialise("", desc); - - return; -} - -void ReplayProxy::FillCBufferVariables(ResourceId shader, string entryPoint, uint32_t cbufSlot, - vector &outvars, const vector &data) -{ - m_ToReplaySerialiser->Serialise("", shader); - m_ToReplaySerialiser->Serialise("", entryPoint); - m_ToReplaySerialiser->Serialise("", cbufSlot); - m_ToReplaySerialiser->Serialise("", outvars); - m_ToReplaySerialiser->Serialise("", (vector &)data); - - if(m_RemoteServer) - { - m_Remote->FillCBufferVariables(shader, entryPoint, cbufSlot, outvars, data); - } - else - { - if(!SendReplayCommand(eReplayProxy_FillCBufferVariables)) - return; - } - - m_FromReplaySerialiser->Serialise("", outvars); - - return; -} - -void ReplayProxy::GetBufferData(ResourceId buff, uint64_t offset, uint64_t len, vector &retData) -{ - m_ToReplaySerialiser->Serialise("", buff); - m_ToReplaySerialiser->Serialise("", offset); - m_ToReplaySerialiser->Serialise("", len); - - if(m_RemoteServer) - { - m_Remote->GetBufferData(buff, offset, len, retData); - - uint64_t sz = retData.size(); - m_FromReplaySerialiser->Serialise("", sz); - m_FromReplaySerialiser->RawWriteBytes(&retData[0], (size_t)sz); - } - else - { - if(!SendReplayCommand(eReplayProxy_GetBufferData)) - return; - - uint64_t sz = 0; - m_FromReplaySerialiser->Serialise("", sz); - retData.resize((size_t)sz); - memcpy(&retData[0], m_FromReplaySerialiser->RawReadBytes((size_t)sz), (size_t)sz); - } -} - -byte *ReplayProxy::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, - const GetTextureDataParams &_params, size_t &dataSize) -{ - GetTextureDataParams params = _params; // Serialiser is non-const - - m_ToReplaySerialiser->Serialise("", tex); - m_ToReplaySerialiser->Serialise("", arrayIdx); - m_ToReplaySerialiser->Serialise("", mip); - m_ToReplaySerialiser->Serialise("", params.forDiskSave); - m_ToReplaySerialiser->Serialise("", params.typeHint); - m_ToReplaySerialiser->Serialise("", params.resolve); - m_ToReplaySerialiser->Serialise("", params.remap); - m_ToReplaySerialiser->Serialise("", params.blackPoint); - m_ToReplaySerialiser->Serialise("", params.whitePoint); - - if(m_RemoteServer) - { - byte *data = m_Remote->GetTextureData(tex, arrayIdx, mip, params, dataSize); - - size_t destSize = LZ4_COMPRESSBOUND(dataSize); - byte *compressed = new byte[destSize]; - - uint32_t uncompressedSize = (uint32_t)dataSize; - uint32_t compressedSize = (uint32_t)LZ4_compress_default((const char *)data, (char *)compressed, - (int)uncompressedSize, (int)destSize); - - m_FromReplaySerialiser->Serialise("", uncompressedSize); - m_FromReplaySerialiser->Serialise("", compressedSize); - m_FromReplaySerialiser->RawWriteBytes(compressed, (size_t)compressedSize); - - delete[] data; - delete[] compressed; - } - else - { - if(!SendReplayCommand(eReplayProxy_GetTextureData)) - { - dataSize = 0; - return NULL; - } - - uint32_t uncompressedSize = 0; - uint32_t compressedSize = 0; - - m_FromReplaySerialiser->Serialise("", uncompressedSize); - m_FromReplaySerialiser->Serialise("", compressedSize); - - if(uncompressedSize == 0 || compressedSize == 0) - { - dataSize = 0; - return NULL; - } - - dataSize = (size_t)uncompressedSize; - - byte *ret = new byte[dataSize + 512]; - - byte *compressed = (byte *)m_FromReplaySerialiser->RawReadBytes((size_t)compressedSize); - - LZ4_decompress_fast((const char *)compressed, (char *)ret, (int)dataSize); - - return ret; - } - - return NULL; -} - -void ReplayProxy::InitPostVSBuffers(uint32_t eventID) -{ - m_ToReplaySerialiser->Serialise("", eventID); - - if(m_RemoteServer) - { - m_Remote->InitPostVSBuffers(eventID); - } - else - { - if(!SendReplayCommand(eReplayProxy_InitPostVS)) - return; - } -} - -void ReplayProxy::InitPostVSBuffers(const vector &events) -{ - m_ToReplaySerialiser->Serialise("", (vector &)events); - - if(m_RemoteServer) - { - m_Remote->InitPostVSBuffers(events); - } - else - { - if(!SendReplayCommand(eReplayProxy_InitPostVSVec)) - return; - } -} - -MeshFormat ReplayProxy::GetPostVSBuffers(uint32_t eventID, uint32_t instID, MeshDataStage stage) -{ - MeshFormat ret; - - m_ToReplaySerialiser->Serialise("", eventID); - m_ToReplaySerialiser->Serialise("", instID); - m_ToReplaySerialiser->Serialise("", stage); - - if(m_RemoteServer) - { - ret = m_Remote->GetPostVSBuffers(eventID, instID, stage); - } - else - { - if(!SendReplayCommand(eReplayProxy_GetPostVS)) - return ret; - } - - m_FromReplaySerialiser->Serialise("", ret); - - return ret; -} - -ResourceId ReplayProxy::RenderOverlay(ResourceId texid, CompType typeHint, DebugOverlay overlay, - uint32_t eventID, const vector &passEvents) -{ - ResourceId ret; - - vector events = passEvents; - - m_ToReplaySerialiser->Serialise("", texid); - m_ToReplaySerialiser->Serialise("", typeHint); - m_ToReplaySerialiser->Serialise("", overlay); - m_ToReplaySerialiser->Serialise("", eventID); - m_ToReplaySerialiser->Serialise("", events); - - if(m_RemoteServer) - { - ret = m_Remote->RenderOverlay(texid, typeHint, overlay, eventID, events); - } - else - { - if(!SendReplayCommand(eReplayProxy_RenderOverlay)) - return ret; - } - - m_FromReplaySerialiser->Serialise("", ret); - - return ret; -} - -ShaderReflection *ReplayProxy::GetShader(ResourceId id, string entryPoint) -{ - if(m_RemoteServer) - { - 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(eReplayProxy_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]; -} - -string ReplayProxy::DisassembleShader(ResourceId pipeline, const ShaderReflection *refl, - const string &target) -{ - string ret; - - ResourceId id; - std::string entryPoint; - std::string isatarget = target; - - if(refl) - { - id = refl->ID; - entryPoint = refl->EntryPoint; - } - - m_ToReplaySerialiser->Serialise("", pipeline); - m_ToReplaySerialiser->Serialise("", id); - m_ToReplaySerialiser->Serialise("", entryPoint); - m_ToReplaySerialiser->Serialise("", isatarget); - - if(m_RemoteServer) - { - refl = m_Remote->GetShader(m_Remote->GetLiveID(id), entryPoint); - if(refl) - ret = m_Remote->DisassembleShader( - pipeline, m_Remote->GetShader(m_Remote->GetLiveID(id), entryPoint), isatarget); - } - else - { - if(!SendReplayCommand(eReplayProxy_DisassembleShader)) - return ret; - } - - m_FromReplaySerialiser->Serialise("", ret); - - return ret; -} - -vector ReplayProxy::GetDisassemblyTargets() -{ - vector ret; - - if(m_RemoteServer) - { - ret = m_Remote->GetDisassemblyTargets(); - } - else - { - if(!SendReplayCommand(eReplayProxy_GetISATargets)) - return ret; - } - - m_FromReplaySerialiser->Serialise("", ret); - - return ret; -} - -void ReplayProxy::FreeTargetResource(ResourceId id) -{ - m_ToReplaySerialiser->Serialise("", id); - - if(m_RemoteServer) - { - m_Remote->FreeTargetResource(id); - } - else - { - if(!SendReplayCommand(eReplayProxy_FreeResource)) - return; - } -} - -void ReplayProxy::InitCallstackResolver() -{ - if(m_RemoteServer) - { - m_Remote->InitCallstackResolver(); - } - else - { - if(!SendReplayCommand(eReplayProxy_InitStackResolver)) - return; - } -} - -Callstack::StackResolver *ReplayProxy::GetCallstackResolver() -{ - if(m_RemoteHasResolver) - return this; - - bool remoteHasResolver = false; - - if(m_RemoteServer) - { - remoteHasResolver = m_Remote->GetCallstackResolver() != NULL; - } - else - { - if(!SendReplayCommand(eReplayProxy_HasStackResolver)) - return NULL; - } - - m_FromReplaySerialiser->Serialise("", remoteHasResolver); - - if(remoteHasResolver) - { - if(!m_RemoteServer) - m_RemoteHasResolver = true; - - return this; - } - - return NULL; -} - -Callstack::AddressDetails ReplayProxy::GetAddr(uint64_t addr) -{ - Callstack::AddressDetails ret; - - if(m_RemoteServer) - { - Callstack::StackResolver *resolv = m_Remote->GetCallstackResolver(); - if(resolv) - ret = resolv->GetAddr(addr); - } - else - { - if(!SendReplayCommand(eReplayProxy_HasStackResolver)) - return ret; - } - - m_FromReplaySerialiser->Serialise("", ret.filename); - m_FromReplaySerialiser->Serialise("", ret.function); - m_FromReplaySerialiser->Serialise("", ret.line); - - return ret; -} - -void ReplayProxy::BuildTargetShader(string source, string entry, - const ShaderCompileFlags &compileFlags, ShaderStage type, - ResourceId *id, string *errors) -{ - ShaderCompileFlags flags = compileFlags; - m_ToReplaySerialiser->Serialise("", source); - m_ToReplaySerialiser->Serialise("", entry); - m_ToReplaySerialiser->Serialise("", flags); - m_ToReplaySerialiser->Serialise("", type); - - ResourceId outId; - string outErrs; - - if(m_RemoteServer) - { - m_Remote->BuildTargetShader(source, entry, flags, type, &outId, &outErrs); - } - else - { - if(!SendReplayCommand(eReplayProxy_BuildTargetShader)) - return; - } - - m_FromReplaySerialiser->Serialise("", outId); - m_FromReplaySerialiser->Serialise("", outErrs); - - if(!m_RemoteServer) - { - if(id) - *id = outId; - if(errors) - *errors = outErrs; - } -} - -void ReplayProxy::ReplaceResource(ResourceId from, ResourceId to) -{ - m_ToReplaySerialiser->Serialise("", from); - m_ToReplaySerialiser->Serialise("", to); - - if(m_RemoteServer) - { - m_Remote->ReplaceResource(from, to); - } - else - { - if(!SendReplayCommand(eReplayProxy_ReplaceResource)) - return; - } -} - -void ReplayProxy::RemoveReplacement(ResourceId id) -{ - m_ToReplaySerialiser->Serialise("", id); - - if(m_RemoteServer) - { - m_Remote->RemoveReplacement(id); - } - else - { - if(!SendReplayCommand(eReplayProxy_RemoveReplacement)) - return; - } -} - -vector ReplayProxy::PixelHistory(vector events, ResourceId target, - uint32_t x, uint32_t y, uint32_t slice, - uint32_t mip, uint32_t sampleIdx, - CompType typeHint) -{ - vector ret; - - 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); - m_ToReplaySerialiser->Serialise("", typeHint); - - if(m_RemoteServer) - { - ret = m_Remote->PixelHistory(events, target, x, y, slice, mip, sampleIdx, typeHint); - } - else - { - if(!SendReplayCommand(eReplayProxy_PixelHistory)) - return ret; - } - - m_FromReplaySerialiser->Serialise("", ret); - - return ret; -} - -ShaderDebugTrace ReplayProxy::DebugVertex(uint32_t eventID, uint32_t vertid, uint32_t instid, - uint32_t idx, uint32_t instOffset, uint32_t vertOffset) -{ - ShaderDebugTrace ret; - - 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_RemoteServer) - { - ret = m_Remote->DebugVertex(eventID, vertid, instid, idx, instOffset, vertOffset); - } - else - { - if(!SendReplayCommand(eReplayProxy_DebugVertex)) - return ret; - } - - m_FromReplaySerialiser->Serialise("", ret); - - return ret; -} - -ShaderDebugTrace ReplayProxy::DebugPixel(uint32_t eventID, uint32_t x, uint32_t y, uint32_t sample, - uint32_t primitive) -{ - ShaderDebugTrace ret; - - m_ToReplaySerialiser->Serialise("", eventID); - m_ToReplaySerialiser->Serialise("", x); - m_ToReplaySerialiser->Serialise("", y); - m_ToReplaySerialiser->Serialise("", sample); - m_ToReplaySerialiser->Serialise("", primitive); - - if(m_RemoteServer) - { - ret = m_Remote->DebugPixel(eventID, x, y, sample, primitive); - } - else - { - if(!SendReplayCommand(eReplayProxy_DebugPixel)) - return ret; - } - - m_FromReplaySerialiser->Serialise("", ret); - - return ret; -} - -ShaderDebugTrace ReplayProxy::DebugThread(uint32_t eventID, const uint32_t groupid[3], - const uint32_t threadid[3]) -{ - ShaderDebugTrace ret; - - uint32_t g[] = {groupid[0], groupid[1], groupid[2]}; - uint32_t t[] = {threadid[0], threadid[1], threadid[2]}; - - m_ToReplaySerialiser->Serialise("", eventID); - m_ToReplaySerialiser->SerialisePODArray<3>("", g); - m_ToReplaySerialiser->SerialisePODArray<3>("", t); - - if(m_RemoteServer) - { - ret = m_Remote->DebugThread(eventID, g, t); - } - else - { - if(!SendReplayCommand(eReplayProxy_DebugThread)) - return ret; - } - - m_FromReplaySerialiser->Serialise("", ret); - - return ret; -} diff --git a/renderdoc/core/replay_proxy.h b/renderdoc/core/replay_proxy.h index 6749b8ca3..d29f5f701 100644 --- a/renderdoc/core/replay_proxy.h +++ b/renderdoc/core/replay_proxy.h @@ -37,6 +37,7 @@ enum ReplayProxyPacket eReplayProxy_ReplayLog = eReplayProxy_First, + eReplayProxy_GetAPIProperties, eReplayProxy_GetPassEvents, eReplayProxy_GetTextures, @@ -56,8 +57,7 @@ enum ReplayProxyPacket eReplayProxy_IsRenderOutput, eReplayProxy_NeedRemapForFetch, - eReplayProxy_FreeResource, - eReplayProxy_HasResolver, + eReplayProxy_FreeTargetResource, eReplayProxy_FetchCounters, eReplayProxy_EnumerateCounters, @@ -68,10 +68,6 @@ enum ReplayProxyPacket eReplayProxy_InitPostVSVec, eReplayProxy_GetPostVS, - eReplayProxy_InitStackResolver, - eReplayProxy_HasStackResolver, - eReplayProxy_GetAddressDetails, - eReplayProxy_BuildTargetShader, eReplayProxy_ReplaceResource, eReplayProxy_RemoveReplacement, @@ -82,40 +78,36 @@ enum ReplayProxyPacket eReplayProxy_RenderOverlay, - eReplayProxy_GetAPIProperties, - eReplayProxy_PixelHistory, eReplayProxy_DisassembleShader, - eReplayProxy_GetISATargets, + eReplayProxy_GetDisassemblyTargets, }; -// This class implements IReplayDriver and StackResolver. On the local machine where the UI -// is, this can then act like a full local replay by farming out over the network to a remote -// replay where necessary to implement some functions, and using a local proxy where necessary. +#define IMPLEMENT_FUNCTION_PROXIED(rettype, name, ...) \ + rettype name(__VA_ARGS__); \ + template \ + rettype CONCAT(Proxied_, name)(ParamSerialiser & paramser, ReturnSerialiser & retser, \ + ##__VA_ARGS__); + +// This class implements IReplayDriver. On the local machine where the UI is, this can then act like +// a full local replay by farming out over the network to a remote replay where necessary to +// implement some functions, and using a local proxy where necessary. // -// This class is also used on the remote replay just so we can re-use the serialisation logic -// across the network before and after implementing the IRemoteDriver parts. -class ReplayProxy : public IReplayDriver, Callstack::StackResolver +// This class is also used on the remote replay just so we can re-use the serialisation logic across +// the network before and after implementing the IRemoteDriver parts. +class ReplayProxy : public IReplayDriver { public: - ReplayProxy(Network::Socket *sock, IReplayDriver *proxy) - : m_Socket(sock), m_Proxy(proxy), m_Remote(NULL), m_RemoteServer(false) + ReplayProxy(ReadSerialiser &reader, WriteSerialiser &writer, IReplayDriver *proxy) + : m_Reader(reader), m_Writer(writer), m_Proxy(proxy), m_Remote(NULL), m_RemoteServer(false) { - m_FromReplaySerialiser = NULL; - m_ToReplaySerialiser = new Serialiser(NULL, Serialiser::WRITING, false); - m_RemoteHasResolver = false; - GetAPIProperties(); } - ReplayProxy(Network::Socket *sock, IRemoteDriver *remote) - : m_Socket(sock), m_Proxy(NULL), m_Remote(remote), m_RemoteServer(true) + ReplayProxy(ReadSerialiser &reader, WriteSerialiser &writer, IRemoteDriver *remote) + : m_Reader(reader), m_Writer(writer), m_Proxy(NULL), m_Remote(remote), m_RemoteServer(true) { - m_ToReplaySerialiser = NULL; - m_FromReplaySerialiser = new Serialiser(NULL, Serialiser::WRITING, false); - m_RemoteHasResolver = false; - RDCEraseEl(m_APIProps); } @@ -123,7 +115,7 @@ public: bool IsRemoteProxy() { return !m_RemoteServer; } void Shutdown() { delete this; } - void ReadLogInitialisation() {} + void ReadLogInitialisation(RDCFile *rdc) {} vector GetSupportedWindowSystems() { if(m_Proxy) @@ -387,79 +379,82 @@ public: return ResourceId(); } - bool Tick(int type, Serialiser *incomingPacket); + bool Tick(int type); - vector GetBuffers(); - BufferDescription GetBuffer(ResourceId id); - - vector GetTextures(); - TextureDescription GetTexture(ResourceId id); - - APIProperties GetAPIProperties(); - - vector GetDebugMessages(); - - void SavePipelineState(); const D3D11Pipe::State &GetD3D11PipelineState() { return m_D3D11PipelineState; } const D3D12Pipe::State &GetD3D12PipelineState() { return m_D3D12PipelineState; } const GLPipe::State &GetGLPipelineState() { return m_GLPipelineState; } const VKPipe::State &GetVulkanPipelineState() { return m_VulkanPipelineState; } - void ReplayLog(uint32_t endEventID, ReplayLogType replayType); + IMPLEMENT_FUNCTION_PROXIED(std::vector, GetBuffers); + IMPLEMENT_FUNCTION_PROXIED(BufferDescription, GetBuffer, ResourceId id); - vector GetPassEvents(uint32_t eventID); + IMPLEMENT_FUNCTION_PROXIED(std::vector, GetTextures); + IMPLEMENT_FUNCTION_PROXIED(TextureDescription, GetTexture, ResourceId id); - vector GetUsage(ResourceId id); - FrameRecord GetFrameRecord(); + IMPLEMENT_FUNCTION_PROXIED(APIProperties, GetAPIProperties); - bool IsRenderOutput(ResourceId id); + IMPLEMENT_FUNCTION_PROXIED(std::vector, GetDebugMessages); - ResourceId GetLiveID(ResourceId id); + IMPLEMENT_FUNCTION_PROXIED(void, SavePipelineState); + IMPLEMENT_FUNCTION_PROXIED(void, ReplayLog, uint32_t endEventID, ReplayLogType replayType); - vector EnumerateCounters(); - void DescribeCounter(GPUCounter counterID, CounterDescription &desc); - vector FetchCounters(const vector &counterID); + IMPLEMENT_FUNCTION_PROXIED(std::vector, GetPassEvents, uint32_t eventID); - void FillCBufferVariables(ResourceId shader, string entryPoint, uint32_t cbufSlot, - vector &outvars, const vector &data); + IMPLEMENT_FUNCTION_PROXIED(std::vector, GetUsage, ResourceId id); + IMPLEMENT_FUNCTION_PROXIED(FrameRecord, GetFrameRecord); - void GetBufferData(ResourceId buff, uint64_t offset, uint64_t len, vector &retData); - byte *GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, - const GetTextureDataParams ¶ms, size_t &dataSize); + IMPLEMENT_FUNCTION_PROXIED(bool, IsRenderOutput, ResourceId id); - void InitPostVSBuffers(uint32_t eventID); - void InitPostVSBuffers(const vector &passEvents); - MeshFormat GetPostVSBuffers(uint32_t eventID, uint32_t instID, MeshDataStage stage); + IMPLEMENT_FUNCTION_PROXIED(ResourceId, GetLiveID, ResourceId id); - ResourceId RenderOverlay(ResourceId texid, CompType typeHint, DebugOverlay overlay, - uint32_t eventID, const vector &passEvents); + IMPLEMENT_FUNCTION_PROXIED(std::vector, EnumerateCounters); + IMPLEMENT_FUNCTION_PROXIED(CounterDescription, DescribeCounter, GPUCounter counterID); + IMPLEMENT_FUNCTION_PROXIED(std::vector, FetchCounters, + const std::vector &counterID); - ShaderReflection *GetShader(ResourceId shader, string entryPoint); + IMPLEMENT_FUNCTION_PROXIED(void, FillCBufferVariables, ResourceId shader, std::string entryPoint, + uint32_t cbufSlot, std::vector &outvars, + const std::vector &data); - vector GetDisassemblyTargets(); - string DisassembleShader(ResourceId pipeline, const ShaderReflection *refl, const string &target); + IMPLEMENT_FUNCTION_PROXIED(void, GetBufferData, ResourceId buff, uint64_t offset, uint64_t len, + std::vector &retData); + IMPLEMENT_FUNCTION_PROXIED(void, GetTextureData, ResourceId tex, uint32_t arrayIdx, uint32_t mip, + const GetTextureDataParams ¶ms, bytebuf &data); - bool HasCallstacks(); - void InitCallstackResolver(); - Callstack::StackResolver *GetCallstackResolver(); - // implementing Callstack::StackResolver - Callstack::AddressDetails GetAddr(uint64_t addr); + IMPLEMENT_FUNCTION_PROXIED(void, InitPostVSBuffers, uint32_t eventID); + IMPLEMENT_FUNCTION_PROXIED(void, InitPostVSBuffers, const std::vector &passEvents); + IMPLEMENT_FUNCTION_PROXIED(MeshFormat, GetPostVSBuffers, uint32_t eventID, uint32_t instID, + MeshDataStage stage); - void FreeTargetResource(ResourceId id); + IMPLEMENT_FUNCTION_PROXIED(ResourceId, RenderOverlay, ResourceId texid, CompType typeHint, + DebugOverlay overlay, uint32_t eventID, + const std::vector &passEvents); - vector PixelHistory(vector events, ResourceId target, uint32_t x, - uint32_t y, uint32_t slice, uint32_t mip, - uint32_t sampleIdx, CompType typeHint); - ShaderDebugTrace DebugVertex(uint32_t eventID, uint32_t vertid, uint32_t instid, uint32_t idx, - uint32_t instOffset, uint32_t vertOffset); - ShaderDebugTrace DebugPixel(uint32_t eventID, uint32_t x, uint32_t y, uint32_t sample, - uint32_t primitive); - ShaderDebugTrace DebugThread(uint32_t eventID, const uint32_t groupid[3], - const uint32_t threadid[3]); + IMPLEMENT_FUNCTION_PROXIED(ShaderReflection *, GetShader, ResourceId shader, + std::string entryPoint); - void BuildTargetShader(string source, string entry, const ShaderCompileFlags &compileFlags, - ShaderStage type, ResourceId *id, string *errors); - void ReplaceResource(ResourceId from, ResourceId to); - void RemoveReplacement(ResourceId id); + IMPLEMENT_FUNCTION_PROXIED(std::vector, GetDisassemblyTargets); + IMPLEMENT_FUNCTION_PROXIED(std::string, DisassembleShader, ResourceId pipeline, + const ShaderReflection *refl, const std::string &target); + + IMPLEMENT_FUNCTION_PROXIED(void, FreeTargetResource, ResourceId id); + + IMPLEMENT_FUNCTION_PROXIED(std::vector, PixelHistory, + std::vector events, ResourceId target, uint32_t x, + uint32_t y, uint32_t slice, uint32_t mip, uint32_t sampleIdx, + CompType typeHint); + IMPLEMENT_FUNCTION_PROXIED(ShaderDebugTrace, DebugVertex, uint32_t eventID, uint32_t vertid, + uint32_t instid, uint32_t idx, uint32_t instOffset, uint32_t vertOffset); + IMPLEMENT_FUNCTION_PROXIED(ShaderDebugTrace, DebugPixel, uint32_t eventID, uint32_t x, uint32_t y, + uint32_t sample, uint32_t primitive); + IMPLEMENT_FUNCTION_PROXIED(ShaderDebugTrace, DebugThread, uint32_t eventID, + const uint32_t groupid[3], const uint32_t threadid[3]); + + IMPLEMENT_FUNCTION_PROXIED(void, BuildTargetShader, std::string source, std::string entry, + const ShaderCompileFlags &compileFlags, ShaderStage type, + ResourceId *id, std::string *errors); + IMPLEMENT_FUNCTION_PROXIED(void, ReplaceResource, ResourceId from, ResourceId to); + IMPLEMENT_FUNCTION_PROXIED(void, RemoveReplacement, ResourceId id); void FileChanged() {} // will never be used @@ -488,12 +483,10 @@ public: } private: - bool SendReplayCommand(ReplayProxyPacket type); - void EnsureTexCached(ResourceId texid, uint32_t arrayIdx, uint32_t mip); void RemapProxyTextureIfNeeded(TextureDescription &tex, GetTextureDataParams ¶ms); void EnsureBufCached(ResourceId bufid); - bool NeedRemapForFetch(const ResourceFormat &format); + IMPLEMENT_FUNCTION_PROXIED(bool, NeedRemapForFetch, const ResourceFormat &format); struct TextureCacheEntry { @@ -546,16 +539,15 @@ private: } }; - map m_ShaderReflectionCache; + std::map m_ShaderReflectionCache; - Network::Socket *m_Socket; - Serialiser *m_FromReplaySerialiser; - Serialiser *m_ToReplaySerialiser; + ReadSerialiser &m_Reader; + WriteSerialiser &m_Writer; IReplayDriver *m_Proxy; IRemoteDriver *m_Remote; bool m_RemoteServer; - bool m_RemoteHasResolver; + bool m_IsErrored = false; APIProperties m_APIProps; diff --git a/renderdoc/driver/d3d11/d3d11_analyse.cpp b/renderdoc/driver/d3d11/d3d11_analyse.cpp index 29b04a43d..cbdee652e 100644 --- a/renderdoc/driver/d3d11/d3d11_analyse.cpp +++ b/renderdoc/driver/d3d11/d3d11_analyse.cpp @@ -579,11 +579,12 @@ ShaderDebug::State D3D11DebugManager::CreateShaderDebugState(ShaderDebugTrace &t FillCBufferVariables(dxbc->m_CBuffers[i].variables, vars, true, cbufData[dxbc->m_CBuffers[i].reg]); - trace.cbuffers[i] = vars; + trace.cbuffers[i].members = vars; - for(size_t c = 0; c < trace.cbuffers[i].size(); c++) - trace.cbuffers[i][c].name = StringFormat::Fmt("cb%u[%u] (%s)", dxbc->m_CBuffers[i].reg, - (uint32_t)c, trace.cbuffers[i][c].name.c_str()); + for(size_t c = 0; c < trace.cbuffers[i].members.size(); c++) + trace.cbuffers[i].members[c].name = + StringFormat::Fmt("cb%u[%u] (%s)", dxbc->m_CBuffers[i].reg, (uint32_t)c, + trace.cbuffers[i].members[c].name.c_str()); } initialState.Init(); @@ -2859,8 +2860,8 @@ void D3D11DebugManager::PickPixel(ResourceId texture, uint32_t x, uint32_t y, ui m_pImmediateContext->Unmap(m_DebugRender.PickPixelStageTex, 0); } -byte *D3D11DebugManager::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, - const GetTextureDataParams ¶ms, size_t &dataSize) +void D3D11DebugManager::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, + const GetTextureDataParams ¶ms, bytebuf &data) { D3D11RenderStateTracker tracker(m_WrappedContext); @@ -2869,7 +2870,6 @@ byte *D3D11DebugManager::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint3 uint32_t subresource = 0; uint32_t mips = 0; - dataSize = 0; size_t bytesize = 0; if(WrappedID3D11Texture1D::m_TextureList.find(tex) != WrappedID3D11Texture1D::m_TextureList.end()) @@ -2890,11 +2890,11 @@ byte *D3D11DebugManager::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint3 mips = desc.MipLevels ? desc.MipLevels : CalcNumMips(desc.Width, 1, 1); if(mip >= mips || arrayIdx >= desc.ArraySize) - return NULL; + return; - if(params.remap) + if(params.remap != RemapTexture::NoRemap) { - RDCASSERT(params.remap == eRemap_RGBA8); + RDCASSERT(params.remap == RemapTexture::RGBA8); desc.Format = IsSRGBFormat(desc.Format) ? DXGI_FORMAT_R8G8B8A8_UNORM_SRGB : DXGI_FORMAT_R8G8B8A8_UNORM; @@ -2910,14 +2910,14 @@ byte *D3D11DebugManager::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint3 if(FAILED(hr)) { RDCERR("Couldn't create staging texture to retrieve data. HRESULT: %s", ToStr(hr).c_str()); - return NULL; + return; } bytesize = GetByteSize(desc.Width, 1, 1, desc.Format, mip); - if(params.remap) + if(params.remap != RemapTexture::NoRemap) { - RDCASSERT(params.remap == eRemap_RGBA8); + RDCASSERT(params.remap == RemapTexture::RGBA8); subresource = mip; @@ -2933,7 +2933,7 @@ byte *D3D11DebugManager::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint3 { RDCERR("Couldn't create target texture to downcast texture. HRESULT: %s", ToStr(hr).c_str()); SAFE_RELEASE(d); - return NULL; + return; } D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; @@ -2948,7 +2948,7 @@ byte *D3D11DebugManager::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint3 RDCERR("Couldn't create target rtv to downcast texture. HRESULT: %s", ToStr(hr).c_str()); SAFE_RELEASE(d); SAFE_RELEASE(rtTex); - return NULL; + return; } ID3D11RenderTargetView *rtv = wrappedrtv; @@ -3029,11 +3029,11 @@ byte *D3D11DebugManager::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint3 mips = desc.MipLevels ? desc.MipLevels : CalcNumMips(desc.Width, desc.Height, 1); if(mip >= mips || arrayIdx >= desc.ArraySize) - return NULL; + return; - if(params.remap) + if(params.remap != RemapTexture::NoRemap) { - RDCASSERT(params.remap == eRemap_RGBA8); + RDCASSERT(params.remap == RemapTexture::RGBA8); desc.Format = (IsSRGBFormat(desc.Format) || wrapTex->m_RealDescriptor) ? DXGI_FORMAT_R8G8B8A8_UNORM_SRGB @@ -3050,14 +3050,14 @@ byte *D3D11DebugManager::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint3 if(FAILED(hr)) { RDCERR("Couldn't create staging texture to retrieve data. HRESULT: %s", ToStr(hr).c_str()); - return NULL; + return; } bytesize = GetByteSize(desc.Width, desc.Height, 1, desc.Format, mip); - if(params.remap) + if(params.remap != RemapTexture::NoRemap) { - RDCASSERT(params.remap == eRemap_RGBA8); + RDCASSERT(params.remap == RemapTexture::RGBA8); subresource = mip; @@ -3073,7 +3073,7 @@ byte *D3D11DebugManager::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint3 { RDCERR("Couldn't create target texture to downcast texture. HRESULT: %s", ToStr(hr).c_str()); SAFE_RELEASE(d); - return NULL; + return; } D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; @@ -3088,7 +3088,7 @@ byte *D3D11DebugManager::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint3 RDCERR("Couldn't create target rtv to downcast texture. HRESULT: %s", ToStr(hr).c_str()); SAFE_RELEASE(d); SAFE_RELEASE(rtTex); - return NULL; + return; } ID3D11RenderTargetView *rtv = wrappedrtv; @@ -3148,7 +3148,7 @@ byte *D3D11DebugManager::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint3 { RDCERR("Couldn't create target texture to resolve texture. HRESULT: %s", ToStr(hr).c_str()); SAFE_RELEASE(d); - return NULL; + return; } m_pImmediateContext->ResolveSubresource(resolveTex, arrayIdx, wrapTex, arrayIdx, desc.Format); @@ -3184,11 +3184,11 @@ byte *D3D11DebugManager::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint3 mips = desc.MipLevels ? desc.MipLevels : CalcNumMips(desc.Width, desc.Height, desc.Depth); if(mip >= mips) - return NULL; + return; - if(params.remap) + if(params.remap != RemapTexture::NoRemap) { - RDCASSERT(params.remap == eRemap_RGBA8); + RDCASSERT(params.remap == RemapTexture::RGBA8); desc.Format = IsSRGBFormat(desc.Format) ? DXGI_FORMAT_R8G8B8A8_UNORM_SRGB : DXGI_FORMAT_R8G8B8A8_UNORM; @@ -3203,14 +3203,14 @@ byte *D3D11DebugManager::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint3 if(FAILED(hr)) { RDCERR("Couldn't create staging texture to retrieve data. HRESULT: %s", ToStr(hr).c_str()); - return NULL; + return; } bytesize = GetByteSize(desc.Width, desc.Height, desc.Depth, desc.Format, mip); - if(params.remap) + if(params.remap != RemapTexture::NoRemap) { - RDCASSERT(params.remap == eRemap_RGBA8); + RDCASSERT(params.remap == RemapTexture::RGBA8); subresource = mip; @@ -3226,7 +3226,7 @@ byte *D3D11DebugManager::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint3 { RDCERR("Couldn't create target texture to downcast texture. HRESULT: %s", ToStr(hr).c_str()); SAFE_RELEASE(d); - return NULL; + return; } D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; @@ -3252,7 +3252,7 @@ byte *D3D11DebugManager::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint3 RDCERR("Couldn't create target rtv to downcast texture. HRESULT: %s", ToStr(hr).c_str()); SAFE_RELEASE(d); SAFE_RELEASE(rtTex); - return NULL; + return; } rtv = wrappedrtv; @@ -3302,8 +3302,7 @@ byte *D3D11DebugManager::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint3 else { RDCERR("Trying to get texture data for unknown ID %llu!", tex); - dataSize = 0; - return new byte[0]; + return; } MapIntercept intercept; @@ -3311,13 +3310,10 @@ byte *D3D11DebugManager::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint3 D3D11_MAPPED_SUBRESOURCE mapped = {0}; HRESULT hr = m_pImmediateContext->Map(dummyTex, subresource, D3D11_MAP_READ, 0, &mapped); - byte *ret = NULL; - if(SUCCEEDED(hr)) { - ret = new byte[bytesize]; - dataSize = bytesize; - intercept.InitWrappedResource(dummyTex, subresource, ret); + data.resize(bytesize); + intercept.InitWrappedResource(dummyTex, subresource, data.data()); intercept.SetD3D(mapped); intercept.CopyFromD3D(); @@ -3325,8 +3321,8 @@ byte *D3D11DebugManager::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint3 // copy it into the beginning. if(intercept.numSlices > 1 && arrayIdx > 0 && (int)arrayIdx < intercept.numSlices) { - byte *dst = ret; - byte *src = ret + intercept.app.DepthPitch * arrayIdx; + byte *dst = data.data(); + byte *src = data.data() + intercept.app.DepthPitch * arrayIdx; for(int row = 0; row < intercept.numRows; row++) { @@ -3343,8 +3339,6 @@ byte *D3D11DebugManager::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint3 } SAFE_RELEASE(dummyTex); - - return ret; } ResourceId D3D11DebugManager::ApplyCustomShader(ResourceId shader, ResourceId texid, uint32_t mip, diff --git a/renderdoc/driver/d3d11/d3d11_counters.cpp b/renderdoc/driver/d3d11/d3d11_counters.cpp index 067f08bee..a1360aa5c 100644 --- a/renderdoc/driver/d3d11/d3d11_counters.cpp +++ b/renderdoc/driver/d3d11/d3d11_counters.cpp @@ -75,8 +75,9 @@ vector D3D11DebugManager::EnumerateCounters() return ret; } -void D3D11DebugManager::DescribeCounter(GPUCounter counterID, CounterDescription &desc) +CounterDescription D3D11DebugManager::DescribeCounter(GPUCounter counterID) { + CounterDescription desc = {}; desc.counterID = counterID; /////AMD////// @@ -84,9 +85,7 @@ void D3D11DebugManager::DescribeCounter(GPUCounter counterID, CounterDescription { if(m_pAMDCounters) { - desc = m_pAMDCounters->GetCounterDescription(counterID); - - return; + return m_pAMDCounters->GetCounterDescription(counterID); } } @@ -202,6 +201,8 @@ void D3D11DebugManager::DescribeCounter(GPUCounter counterID, CounterDescription desc.unit = CounterUnit::Absolute; break; } + + return desc; } struct GPUTimer diff --git a/renderdoc/driver/d3d11/d3d11_debug.h b/renderdoc/driver/d3d11/d3d11_debug.h index 253769a2d..9b4a100e3 100644 --- a/renderdoc/driver/d3d11/d3d11_debug.h +++ b/renderdoc/driver/d3d11/d3d11_debug.h @@ -133,8 +133,8 @@ public: void GetBufferData(ResourceId buff, uint64_t offset, uint64_t length, vector &retData); void GetBufferData(ID3D11Buffer *buff, uint64_t offset, uint64_t length, vector &retData); - byte *GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, - const GetTextureDataParams ¶ms, size_t &dataSize); + void GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, + const GetTextureDataParams ¶ms, bytebuf &data); void FillCBufferVariables(const vector &invars, vector &outvars, bool flattenVec4s, @@ -156,7 +156,7 @@ public: static void PostDeviceShutdownCounters(); vector EnumerateCounters(); - void DescribeCounter(GPUCounter counterID, CounterDescription &desc); + CounterDescription DescribeCounter(GPUCounter counterID); vector FetchCounters(const vector &counters); vector FetchCountersAMD(const vector &counters); diff --git a/renderdoc/driver/d3d11/d3d11_replay.cpp b/renderdoc/driver/d3d11/d3d11_replay.cpp index 3517c8c7d..482e599ad 100644 --- a/renderdoc/driver/d3d11/d3d11_replay.cpp +++ b/renderdoc/driver/d3d11/d3d11_replay.cpp @@ -385,6 +385,7 @@ APIProperties D3D11Replay::GetAPIProperties() ret.pipelineType = GraphicsAPI::D3D11; ret.localRenderer = GraphicsAPI::D3D11; ret.degraded = m_WARP; + ret.shadersMutable = false; return ret; } @@ -1433,10 +1434,10 @@ void D3D11Replay::GetBufferData(ResourceId buff, uint64_t offset, uint64_t len, m_pDevice->GetDebugManager()->GetBufferData(buff, offset, len, retData); } -byte *D3D11Replay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, - const GetTextureDataParams ¶ms, size_t &dataSize) +void D3D11Replay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, + const GetTextureDataParams ¶ms, bytebuf &data) { - return m_pDevice->GetDebugManager()->GetTextureData(tex, arrayIdx, mip, params, dataSize); + m_pDevice->GetDebugManager()->GetTextureData(tex, arrayIdx, mip, params, data); } void D3D11Replay::ReplaceResource(ResourceId from, ResourceId to) @@ -1454,9 +1455,9 @@ vector D3D11Replay::EnumerateCounters() return m_pDevice->GetDebugManager()->EnumerateCounters(); } -void D3D11Replay::DescribeCounter(GPUCounter counterID, CounterDescription &desc) +CounterDescription D3D11Replay::DescribeCounter(GPUCounter counterID) { - m_pDevice->GetDebugManager()->DescribeCounter(counterID, desc); + return m_pDevice->GetDebugManager()->DescribeCounter(counterID); } vector D3D11Replay::FetchCounters(const vector &counters) diff --git a/renderdoc/driver/d3d11/d3d11_replay.h b/renderdoc/driver/d3d11/d3d11_replay.h index 431e7467f..3576fddfd 100644 --- a/renderdoc/driver/d3d11/d3d11_replay.h +++ b/renderdoc/driver/d3d11/d3d11_replay.h @@ -109,8 +109,8 @@ public: MeshFormat GetPostVSBuffers(uint32_t eventID, uint32_t instID, MeshDataStage stage); void GetBufferData(ResourceId buff, uint64_t offset, uint64_t len, vector &retData); - byte *GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, - const GetTextureDataParams ¶ms, size_t &dataSize); + void GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, + const GetTextureDataParams ¶ms, bytebuf &data); void BuildTargetShader(string source, string entry, const ShaderCompileFlags &compileFlags, ShaderStage type, ResourceId *id, string *errors); @@ -118,7 +118,7 @@ public: void RemoveReplacement(ResourceId id); vector EnumerateCounters(); - void DescribeCounter(GPUCounter counterID, CounterDescription &desc); + CounterDescription DescribeCounter(GPUCounter counterID); vector FetchCounters(const vector &counters); ResourceId CreateProxyTexture(const TextureDescription &templateTex); diff --git a/renderdoc/driver/d3d12/d3d12_replay.cpp b/renderdoc/driver/d3d12/d3d12_replay.cpp index c6ce0f163..54b937c6f 100644 --- a/renderdoc/driver/d3d12/d3d12_replay.cpp +++ b/renderdoc/driver/d3d12/d3d12_replay.cpp @@ -70,6 +70,7 @@ APIProperties D3D12Replay::GetAPIProperties() ret.pipelineType = GraphicsAPI::D3D12; ret.localRenderer = GraphicsAPI::D3D12; ret.degraded = false; + ret.shadersMutable = false; return ret; } diff --git a/renderdoc/driver/gl/gl_replay.cpp b/renderdoc/driver/gl/gl_replay.cpp index 23f7103c0..025f7e924 100644 --- a/renderdoc/driver/gl/gl_replay.cpp +++ b/renderdoc/driver/gl/gl_replay.cpp @@ -136,6 +136,7 @@ APIProperties GLReplay::GetAPIProperties() ret.pipelineType = GraphicsAPI::OpenGL; ret.localRenderer = GraphicsAPI::OpenGL; ret.degraded = m_Degraded; + ret.shadersMutable = true; return ret; } diff --git a/renderdoc/driver/shaders/dxbc/dxbc_debug.cpp b/renderdoc/driver/shaders/dxbc/dxbc_debug.cpp index 9748ae063..bc950882a 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_debug.cpp +++ b/renderdoc/driver/shaders/dxbc/dxbc_debug.cpp @@ -567,14 +567,14 @@ void State::Init() { if(indexTempSizes[i] > 0) { - indexableTemps[i].resize(indexTempSizes[i]); + indexableTemps[i].members.resize(indexTempSizes[i]); for(uint32_t t = 0; t < indexTempSizes[i]; t++) { char buf[64] = {0}; StringFormat::snprintf(buf, 63, "x%u[%u]", i, t); - indexableTemps[i][t] = ShaderVariable(buf, 0l, 0l, 0l, 0l); + indexableTemps[i].members[t] = ShaderVariable(buf, 0l, 0l, 0l, 0l); } } } @@ -646,10 +646,10 @@ void State::SetDst(const ASMOperand &dstoper, const ASMOperation &op, const Shad RDCASSERT(indices[0] < (uint32_t)indexableTemps.size()); if(indices[0] < (uint32_t)indexableTemps.size()) { - RDCASSERT(indices[1] < (uint32_t)indexableTemps[indices[0]].size()); - if(indices[1] < (uint32_t)indexableTemps[indices[0]].size()) + RDCASSERT(indices[1] < (uint32_t)indexableTemps[indices[0]].members.size()); + if(indices[1] < (uint32_t)indexableTemps[indices[0]].members.size()) { - v = &indexableTemps[indices[0]][indices[1]]; + v = &indexableTemps[indices[0]].members[indices[1]]; } } } @@ -839,10 +839,10 @@ ShaderVariable State::GetSrc(const ASMOperand &oper, const ASMOperation &op) con RDCASSERT(indices[0] < (uint32_t)indexableTemps.size()); if(indices[0] < (uint32_t)indexableTemps.size()) { - RDCASSERT(indices[1] < (uint32_t)indexableTemps[indices[0]].size()); - if(indices[1] < (uint32_t)indexableTemps[indices[0]].size()) + RDCASSERT(indices[1] < (uint32_t)indexableTemps[indices[0]].members.size()); + if(indices[1] < (uint32_t)indexableTemps[indices[0]].members.size()) { - v = s = indexableTemps[indices[0]][indices[1]]; + v = s = indexableTemps[indices[0]].members[indices[1]]; } } } @@ -943,11 +943,11 @@ ShaderVariable State::GetSrc(const ASMOperand &oper, const ASMOperation &op) con if(cb >= 0 && cb < trace->cbuffers.count()) { RDCASSERTMSG("Out of bounds cbuffer lookup", - indices[1] < (uint32_t)trace->cbuffers[cb].count(), indices[1], - trace->cbuffers[cb].count()); + indices[1] < (uint32_t)trace->cbuffers[cb].members.count(), indices[1], + trace->cbuffers[cb].members.count()); - if(indices[1] < (uint32_t)trace->cbuffers[cb].size()) - v = s = trace->cbuffers[cb][indices[1]]; + if(indices[1] < (uint32_t)trace->cbuffers[cb].members.count()) + v = s = trace->cbuffers[cb].members[indices[1]]; else v = s = ShaderVariable("", 0U, 0U, 0U, 0U); } diff --git a/renderdoc/driver/shaders/dxbc/dxbc_inspect.cpp b/renderdoc/driver/shaders/dxbc/dxbc_inspect.cpp index 786ec928d..4633f088a 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_inspect.cpp +++ b/renderdoc/driver/shaders/dxbc/dxbc_inspect.cpp @@ -1427,8 +1427,8 @@ uint32_t DecodeFlags(const ShaderCompileFlags &compileFlags) { uint32_t ret = 0; - if(!compileFlags.flags.empty() && compileFlags.flags[0].first == "compileFlags") - ret = atoi(compileFlags.flags[0].second.c_str()); + if(!compileFlags.flags.empty() && compileFlags.flags[0].Name == "compileFlags") + ret = atoi(compileFlags.flags[0].Value.c_str()); return ret; } diff --git a/renderdoc/driver/shaders/dxbc/dxbc_reflect.cpp b/renderdoc/driver/shaders/dxbc/dxbc_reflect.cpp index 3592459d8..6ce2658f9 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_reflect.cpp +++ b/renderdoc/driver/shaders/dxbc/dxbc_reflect.cpp @@ -215,8 +215,8 @@ void MakeShaderReflection(DXBC::DXBCFile *dxbc, ShaderReflection *refl, refl->DebugInfo.files.resize(dxbc->m_DebugInfo->Files.size()); for(size_t i = 0; i < dxbc->m_DebugInfo->Files.size(); i++) { - refl->DebugInfo.files[i].first = dxbc->m_DebugInfo->Files[i].first; - refl->DebugInfo.files[i].second = dxbc->m_DebugInfo->Files[i].second; + refl->DebugInfo.files[i].Filename = dxbc->m_DebugInfo->Files[i].first; + refl->DebugInfo.files[i].Contents = dxbc->m_DebugInfo->Files[i].second; } string entry = dxbc->m_DebugInfo->GetEntryFunction(); @@ -235,8 +235,8 @@ void MakeShaderReflection(DXBC::DXBCFile *dxbc, ShaderReflection *refl, // positives, and so we want to bias towards leaving [0] in place. for(size_t i = 0; i < refl->DebugInfo.files.size(); i++) { - const char *c = strstr(refl->DebugInfo.files[i].first.c_str(), entry.c_str()); - const char *end = refl->DebugInfo.files[i].first.end(); + const char *c = strstr(refl->DebugInfo.files[i].Filename.c_str(), entry.c_str()); + const char *end = refl->DebugInfo.files[i].Filename.end(); // no substring match? continue if(c == NULL) diff --git a/renderdoc/driver/shaders/spirv/spirv_disassemble.cpp b/renderdoc/driver/shaders/spirv/spirv_disassemble.cpp index 68287204d..cf02aad0e 100644 --- a/renderdoc/driver/shaders/spirv/spirv_disassemble.cpp +++ b/renderdoc/driver/shaders/spirv/spirv_disassemble.cpp @@ -3918,8 +3918,8 @@ void SPVModule::MakeReflection(ShaderStage stage, const string &entryPoint, for(size_t i = 0; i < sourceFiles.size(); i++) { - reflection.DebugInfo.files[i].first = sourceFiles[i].first; - reflection.DebugInfo.files[i].second = sourceFiles[i].second; + reflection.DebugInfo.files[i].Filename = sourceFiles[i].first; + reflection.DebugInfo.files[i].Contents = sourceFiles[i].second; } } diff --git a/renderdoc/driver/vulkan/vk_counters.cpp b/renderdoc/driver/vulkan/vk_counters.cpp index aeea8da66..5cab36503 100644 --- a/renderdoc/driver/vulkan/vk_counters.cpp +++ b/renderdoc/driver/vulkan/vk_counters.cpp @@ -74,8 +74,9 @@ vector VulkanReplay::EnumerateCounters() return ret; } -void VulkanReplay::DescribeCounter(GPUCounter counterID, CounterDescription &desc) +CounterDescription VulkanReplay::DescribeCounter(GPUCounter counterID) { + CounterDescription desc = {}; desc.counterID = counterID; // 6839CB5B-FBD2-4550-B606-8C65157C684C desc.uuid.bytes[0] = 0x6839CB5B; @@ -185,6 +186,8 @@ void VulkanReplay::DescribeCounter(GPUCounter counterID, CounterDescription &des desc.unit = CounterUnit::Absolute; break; } + + return desc; } struct VulkanGPUTimerCallback : public VulkanDrawcallCallback diff --git a/renderdoc/driver/vulkan/vk_replay.cpp b/renderdoc/driver/vulkan/vk_replay.cpp index 135b904fe..c6c2f49f8 100644 --- a/renderdoc/driver/vulkan/vk_replay.cpp +++ b/renderdoc/driver/vulkan/vk_replay.cpp @@ -653,6 +653,7 @@ APIProperties VulkanReplay::GetAPIProperties() ret.pipelineType = GraphicsAPI::Vulkan; ret.localRenderer = GraphicsAPI::Vulkan; ret.degraded = false; + ret.shadersMutable = false; return ret; } @@ -4298,16 +4299,15 @@ MeshFormat VulkanReplay::GetPostVSBuffers(uint32_t eventID, uint32_t instID, Mes return GetDebugManager()->GetPostVSBuffers(eventID, instID, stage); } -byte *VulkanReplay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, - const GetTextureDataParams ¶ms, size_t &dataSize) +void VulkanReplay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, + const GetTextureDataParams ¶ms, bytebuf &data) { bool wasms = false; if(m_pDriver->m_CreationInfo.m_Image.find(tex) == m_pDriver->m_CreationInfo.m_Image.end()) { RDCERR("Trying to get texture data for unknown ID %llu!", tex); - dataSize = 0; - return new byte[0]; + return; } VulkanCreationInfo::Image &imInfo = m_pDriver->m_CreationInfo.m_Image[tex]; @@ -4366,22 +4366,22 @@ byte *VulkanReplay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t m wasms = true; } - if(params.remap) + if(params.remap != RemapTexture::NoRemap) { int renderFlags = 0; // force readback texture to RGBA8 unorm - if(params.remap == eRemap_RGBA8) + if(params.remap == RemapTexture::RGBA8) { imCreateInfo.format = IsSRGBFormat(imCreateInfo.format) ? VK_FORMAT_R8G8B8A8_SRGB : VK_FORMAT_R8G8B8A8_UNORM; } - else if(params.remap == eRemap_RGBA16) + else if(params.remap == RemapTexture::RGBA16) { imCreateInfo.format = VK_FORMAT_R16G16B16A16_SFLOAT; renderFlags = eTexDisplay_F16Render; } - else if(params.remap == eRemap_RGBA32) + else if(params.remap == RemapTexture::RGBA32) { imCreateInfo.format = VK_FORMAT_R32G32B32A32_SFLOAT; renderFlags = eTexDisplay_F32Render; @@ -4884,6 +4884,8 @@ byte *VulkanReplay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t m copyregion[i].imageExtent.depth = RDCMAX(1U, copyregion[i].imageExtent.depth >> mip); } + uint32_t dataSize = 0; + // for most combined depth-stencil images this will be large enough for both to be copied // separately, but for D24S8 we need to add extra space since they won't be copied packed dataSize = GetByteSize(imInfo.extent.width, imInfo.extent.height, imInfo.extent.depth, @@ -4891,7 +4893,7 @@ byte *VulkanReplay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t m if(imCreateInfo.format == VK_FORMAT_D24_UNORM_S8_UINT) { - dataSize = AlignUp(dataSize, (size_t)4); + dataSize = AlignUp(dataSize, 4U); dataSize += GetByteSize(imInfo.extent.width, imInfo.extent.height, imInfo.extent.depth, VK_FORMAT_S8_UINT, mip); } @@ -4935,7 +4937,7 @@ byte *VulkanReplay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t m vt->CmdCopyImageToBuffer(Unwrap(cmd), srcImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, readbackBuf, 2, copyregion); } - else if(imInfo.type == VK_IMAGE_TYPE_3D && params.remap) + else if(imInfo.type == VK_IMAGE_TYPE_3D && params.remap != RemapTexture::NoRemap) { // copy in each slice from the 2D array we created to render out the 3D texture for(uint32_t i = 0; i < imCreateInfo.arrayLayers; i++) @@ -4997,7 +4999,7 @@ byte *VulkanReplay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t m RDCASSERT(pData != NULL); - byte *ret = new byte[dataSize]; + data.resize(dataSize); if(isDepth && isStencil) { @@ -5009,7 +5011,7 @@ byte *VulkanReplay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t m uint16_t *dSrc = (uint16_t *)pData; uint8_t *sSrc = (uint8_t *)(pData + copyregion[1].bufferOffset); - uint16_t *dDst = (uint16_t *)ret; + uint16_t *dDst = (uint16_t *)data.data(); uint16_t *sDst = dDst + 1; // interleaved, next pixel for(size_t i = 0; i < pixelCount; i++) @@ -5033,7 +5035,7 @@ byte *VulkanReplay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t m uint32_t *dSrc = (uint32_t *)pData; uint8_t *sSrc = (uint8_t *)(pData + copyregion[1].bufferOffset); - uint32_t *dst = (uint32_t *)ret; + uint32_t *dst = (uint32_t *)data.data(); for(size_t i = 0; i < pixelCount; i++) { @@ -5050,7 +5052,7 @@ byte *VulkanReplay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t m uint32_t *dSrc = (uint32_t *)pData; uint8_t *sSrc = (uint8_t *)(pData + copyregion[1].bufferOffset); - uint32_t *dDst = (uint32_t *)ret; + uint32_t *dDst = (uint32_t *)data.data(); uint32_t *sDst = dDst + 1; // interleaved, next pixel for(size_t i = 0; i < pixelCount; i++) @@ -5071,7 +5073,7 @@ byte *VulkanReplay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t m } else { - memcpy(ret, pData, dataSize); + memcpy(data.data(), pData, dataSize); } vt->UnmapMemory(Unwrap(dev), readbackMem); @@ -5097,8 +5099,6 @@ byte *VulkanReplay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t m delete[] tmpView; vt->DestroyRenderPass(Unwrap(dev), tmpRP, NULL); } - - return ret; } void VulkanReplay::BuildCustomShader(string source, string entry, diff --git a/renderdoc/driver/vulkan/vk_replay.h b/renderdoc/driver/vulkan/vk_replay.h index 2414d79a8..45846cf48 100644 --- a/renderdoc/driver/vulkan/vk_replay.h +++ b/renderdoc/driver/vulkan/vk_replay.h @@ -182,7 +182,7 @@ public: ResourceId GetLiveID(ResourceId id); vector EnumerateCounters(); - void DescribeCounter(GPUCounter counterID, CounterDescription &desc); + CounterDescription DescribeCounter(GPUCounter counterID); vector FetchCounters(const vector &counters); bool GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, @@ -194,8 +194,8 @@ public: MeshFormat GetPostVSBuffers(uint32_t eventID, uint32_t instID, MeshDataStage stage); void GetBufferData(ResourceId buff, uint64_t offset, uint64_t len, vector &retData); - byte *GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, - const GetTextureDataParams ¶ms, size_t &dataSize); + void GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, + const GetTextureDataParams ¶ms, bytebuf &data); void ReplaceResource(ResourceId from, ResourceId to); void RemoveReplacement(ResourceId id); diff --git a/renderdoc/replay/renderdoc_serialise.inl b/renderdoc/replay/renderdoc_serialise.inl index c37edcdc6..26e6bab0f 100644 --- a/renderdoc/replay/renderdoc_serialise.inl +++ b/renderdoc/replay/renderdoc_serialise.inl @@ -211,6 +211,15 @@ void DoSerialise(SerialiserType &ser, ShaderResource &el) SIZE_CHECK(80); } +template +void DoSerialise(SerialiserType &ser, ShaderCompileFlag &el) +{ + SERIALISE_MEMBER(Name); + SERIALISE_MEMBER(Value); + + SIZE_CHECK(32); +} + template void DoSerialise(SerialiserType &ser, ShaderCompileFlags &el) { @@ -219,6 +228,15 @@ void DoSerialise(SerialiserType &ser, ShaderCompileFlags &el) SIZE_CHECK(16); } +template +void DoSerialise(SerialiserType &ser, ShaderSourceFile &el) +{ + SERIALISE_MEMBER(Filename); + SERIALISE_MEMBER(Contents); + + SIZE_CHECK(32); +} + template void DoSerialise(SerialiserType &ser, ShaderDebugChunk &el) { diff --git a/renderdoc/replay/replay_controller.cpp b/renderdoc/replay/replay_controller.cpp index 1884e0247..25fa288e1 100644 --- a/renderdoc/replay/replay_controller.cpp +++ b/renderdoc/replay/replay_controller.cpp @@ -285,11 +285,7 @@ rdcarray ReplayController::EnumerateCounters() CounterDescription ReplayController::DescribeCounter(GPUCounter counterID) { - CounterDescription ret; - - m_pDevice->DescribeCounter(counterID, ret); - - return ret; + return m_pDevice->DescribeCounter(counterID); } rdcarray ReplayController::GetBuffers() @@ -378,13 +374,7 @@ bytebuf ReplayController::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint return ret; } - size_t sz = 0; - byte *bytes = m_pDevice->GetTextureData(liveId, arrayIdx, mip, GetTextureDataParams(), sz); - - if(sz != 0 && bytes != NULL) - ret.assign(bytes, sz); - - SAFE_DELETE_ARRAY(bytes); + m_pDevice->GetTextureData(liveId, arrayIdx, mip, GetTextureDataParams(), ret); return ret; } @@ -641,14 +631,14 @@ bool ReplayController::SaveTexture(const TextureSave &saveData, const char *path params.forDiskSave = true; params.typeHint = sd.typeHint; params.resolve = resolveSamples; - params.remap = downcast ? eRemap_RGBA8 : eRemap_None; + params.remap = downcast ? RemapTexture::RGBA8 : RemapTexture::NoRemap; params.blackPoint = sd.comp.blackPoint; params.whitePoint = sd.comp.whitePoint; - size_t datasize = 0; - byte *bytes = m_pDevice->GetTextureData(liveid, slice, mip, params, datasize); + bytebuf data; + m_pDevice->GetTextureData(liveid, slice, mip, params, data); - if(bytes == NULL) + if(data.empty()) { RDCERR("Couldn't get bytes for mip %u, slice %u", mip, slice); @@ -660,6 +650,8 @@ bool ReplayController::SaveTexture(const TextureSave &saveData, const char *path if(td.depth == 1) { + byte *bytes = new byte[data.size()]; + memcpy(bytes, data.data(), data.size()); subdata.push_back(bytes); continue; } @@ -686,17 +678,16 @@ bool ReplayController::SaveTexture(const TextureSave &saveData, const char *path if(numSlices == 1) { byte *depthslice = new byte[mipSlicePitch]; - byte *b = bytes + mipSlicePitch * sliceOffset; + byte *b = data.data() + mipSlicePitch * sliceOffset; memcpy(depthslice, b, slicePitch); subdata.push_back(depthslice); - delete[] bytes; continue; } s += (d - 1); - byte *b = bytes; + byte *b = data.data(); // add each depth slice as a separate subdata for(uint32_t di = 0; di < d; di++) @@ -709,8 +700,6 @@ bool ReplayController::SaveTexture(const TextureSave &saveData, const char *path b += mipSlicePitch; } - - delete[] bytes; } } diff --git a/renderdoc/replay/replay_driver.cpp b/renderdoc/replay/replay_driver.cpp index 233ba6fbc..89e233687 100644 --- a/renderdoc/replay/replay_driver.cpp +++ b/renderdoc/replay/replay_driver.cpp @@ -24,6 +24,34 @@ #include "replay_driver.h" #include "maths/formatpacking.h" +#include "serialise/serialiser.h" + +template <> +std::string DoStringise(const RemapTexture &el) +{ + BEGIN_ENUM_STRINGISE(RemapTexture); + { + STRINGISE_ENUM_CLASS(NoRemap) + STRINGISE_ENUM_CLASS(RGBA8) + STRINGISE_ENUM_CLASS(RGBA16) + STRINGISE_ENUM_CLASS(RGBA32) + STRINGISE_ENUM_CLASS(D32S8) + } + END_ENUM_STRINGISE(); +} + +template +void DoSerialise(SerialiserType &ser, GetTextureDataParams &el) +{ + SERIALISE_MEMBER(forDiskSave); + SERIALISE_MEMBER(typeHint); + SERIALISE_MEMBER(resolve); + SERIALISE_MEMBER(remap); + SERIALISE_MEMBER(blackPoint); + SERIALISE_MEMBER(whitePoint); +} + +INSTANTIATE_SERIALISE_TYPE(GetTextureDataParams); DrawcallDescription *SetupDrawcallPointers(vector *drawcallTable, rdcarray &draws, diff --git a/renderdoc/replay/replay_driver.h b/renderdoc/replay/replay_driver.h index 706fdc1bb..0bc3407c5 100644 --- a/renderdoc/replay/replay_driver.h +++ b/renderdoc/replay/replay_driver.h @@ -36,21 +36,25 @@ struct FrameRecord rdcarray drawcallList; }; -enum RemapTextureEnum +DECLARE_REFLECTION_STRUCT(FrameRecord); + +enum class RemapTexture : uint32_t { - eRemap_None, - eRemap_RGBA8, - eRemap_RGBA16, - eRemap_RGBA32, - eRemap_D32S8 + NoRemap, + RGBA8, + RGBA16, + RGBA32, + D32S8 }; +DECLARE_REFLECTION_ENUM(RemapTexture); + struct GetTextureDataParams { bool forDiskSave; CompType typeHint; bool resolve; - RemapTextureEnum remap; + RemapTexture remap; float blackPoint; float whitePoint; @@ -58,13 +62,15 @@ struct GetTextureDataParams : forDiskSave(false), typeHint(CompType::Typeless), resolve(false), - remap(eRemap_None), + remap(RemapTexture::NoRemap), blackPoint(0.0f), whitePoint(1.0f) { } }; +DECLARE_REFLECTION_STRUCT(GetTextureDataParams); + class RDCFile; // these two interfaces define what an API driver implementation must provide @@ -122,8 +128,8 @@ public: virtual void GetBufferData(ResourceId buff, uint64_t offset, uint64_t len, vector &retData) = 0; - virtual byte *GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, - const GetTextureDataParams ¶ms, size_t &dataSize) = 0; + virtual void GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, + const GetTextureDataParams ¶ms, bytebuf &data) = 0; virtual void BuildTargetShader(string source, string entry, const ShaderCompileFlags &compileFlags, ShaderStage type, ResourceId *id, string *errors) = 0; @@ -132,7 +138,7 @@ public: virtual void FreeTargetResource(ResourceId id) = 0; virtual vector EnumerateCounters() = 0; - virtual void DescribeCounter(GPUCounter counterID, CounterDescription &desc) = 0; + virtual CounterDescription DescribeCounter(GPUCounter counterID) = 0; virtual vector FetchCounters(const vector &counterID) = 0; virtual void FillCBufferVariables(ResourceId shader, string entryPoint, uint32_t cbufSlot,