diff --git a/qrenderdoc/Windows/ResourceInspector.cpp b/qrenderdoc/Windows/ResourceInspector.cpp index f452f1da7..120ed87e5 100644 --- a/qrenderdoc/Windows/ResourceInspector.cpp +++ b/qrenderdoc/Windows/ResourceInspector.cpp @@ -553,7 +553,7 @@ void ResourceInspector::on_viewContents_clicked() ResourceId id = m_Resource; ICaptureContext *ctx = &m_Ctx; m_Ctx.Replay().AsyncInvoke([this, ctx, pipeid, id, entry](IReplayController *r) { - ShaderReflection *refl = r->GetShader(pipeid, id, entry); + const ShaderReflection *refl = r->GetShader(pipeid, id, entry); if(!refl) return; diff --git a/renderdoc/api/replay/pipestate.h b/renderdoc/api/replay/pipestate.h index 92f752e5c..91a7a8257 100644 --- a/renderdoc/api/replay/pipestate.h +++ b/renderdoc/api/replay/pipestate.h @@ -45,13 +45,36 @@ public: #if defined(RENDERDOC_EXPORTS) // we initialise this internally only - void SetStates(APIProperties props, const D3D11Pipe::State *d3d11, const D3D12Pipe::State *d3d12, - const GLPipe::State *gl, const VKPipe::State *vk) + void SetState(const D3D11Pipe::State *d3d11) { - m_PipelineType = props.pipelineType; + m_PipelineType = GraphicsAPI::D3D11; m_D3D11 = d3d11; + m_D3D12 = NULL; + m_GL = NULL; + m_Vulkan = NULL; + } + void SetState(const D3D12Pipe::State *d3d12) + { + m_PipelineType = GraphicsAPI::D3D12; + m_D3D11 = NULL; m_D3D12 = d3d12; + m_GL = NULL; + m_Vulkan = NULL; + } + void SetState(const GLPipe::State *gl) + { + m_PipelineType = GraphicsAPI::OpenGL; + m_D3D11 = NULL; + m_D3D12 = NULL; m_GL = gl; + m_Vulkan = NULL; + } + void SetState(const VKPipe::State *vk) + { + m_PipelineType = GraphicsAPI::Vulkan; + m_D3D11 = NULL; + m_D3D12 = NULL; + m_GL = NULL; m_Vulkan = vk; } #endif diff --git a/renderdoc/api/replay/renderdoc_replay.h b/renderdoc/api/replay/renderdoc_replay.h index 917815141..1ee6fe299 100644 --- a/renderdoc/api/replay/renderdoc_replay.h +++ b/renderdoc/api/replay/renderdoc_replay.h @@ -782,8 +782,8 @@ only ever have one result (only one entry point per shader). :return: The frame information. :rtype: ShaderReflection )"); - virtual ShaderReflection *GetShader(ResourceId pipeline, ResourceId shader, - ShaderEntryPoint entry) = 0; + virtual const ShaderReflection *GetShader(ResourceId pipeline, ResourceId shader, + ShaderEntryPoint entry) = 0; DOCUMENT(R"(Retrieve the contents of a particular pixel in a texture. diff --git a/renderdoc/core/image_viewer.cpp b/renderdoc/core/image_viewer.cpp index 9c8c7029f..19c5b3ec1 100644 --- a/renderdoc/core/image_viewer.cpp +++ b/renderdoc/core/image_viewer.cpp @@ -66,10 +66,6 @@ public: m_Resources[0].resourceId = m_TextureID; m_Resources[0].autogeneratedName = false; m_Resources[0].name = get_basename(m_Filename); - - m_PipelineState.outputMerger.renderTargets.resize(1); - m_PipelineState.outputMerger.renderTargets[0].resourceResourceId = m_TextureID; - m_PipelineState.outputMerger.renderTargets[0].viewFormat = m_TexDetails.format; } virtual ~ImageViewer() @@ -211,7 +207,14 @@ public: // handle a couple of operations ourselves to return a simple fake log APIProperties GetAPIProperties() { return m_Props; } FrameRecord GetFrameRecord() { return m_FrameRecord; } - const D3D11Pipe::State *GetD3D11PipelineState() { return &m_PipelineState; } + void SetPipelineStates(D3D11Pipe::State *d3d11, D3D12Pipe::State *d3d12, GLPipe::State *gl, + VKPipe::State *vk) + { + d3d11->outputMerger.renderTargets.resize(1); + d3d11->outputMerger.renderTargets[0].resourceResourceId = m_TextureID; + d3d11->outputMerger.renderTargets[0].viewFormat = m_TexDetails.format; + } + // other operations are dropped/ignored, to avoid confusion ReplayStatus ReadLogInitialisation(RDCFile *rdc, bool storeStructuredBuffers) { @@ -236,9 +239,6 @@ public: return ret; } rdcarray GetAvailableGPUs() { return {}; } - const D3D12Pipe::State *GetD3D12PipelineState() { return NULL; } - const GLPipe::State *GetGLPipelineState() { return NULL; } - const VKPipe::State *GetVulkanPipelineState() { return NULL; } void ReplayLog(uint32_t endEventID, ReplayLogType replayType) {} rdcarray GetPassEvents(uint32_t eventId) { return rdcarray(); } rdcarray GetUsage(ResourceId id) { return rdcarray(); } diff --git a/renderdoc/core/replay_proxy.cpp b/renderdoc/core/replay_proxy.cpp index 2a0655168..299a0642e 100644 --- a/renderdoc/core/replay_proxy.cpp +++ b/renderdoc/core/replay_proxy.cpp @@ -189,8 +189,58 @@ struct RemoteExecution else \ return CONCAT(Proxied_, name)(m_Writer, m_Reader, ##__VA_ARGS__); +ReplayProxy::ReplayProxy(ReadSerialiser &reader, WriteSerialiser &writer, IRemoteDriver *remoteDriver, + IReplayDriver *replayDriver, RENDERDOC_PreviewWindowCallback previewWindow) + : m_Reader(reader), + m_Writer(writer), + m_Proxy(NULL), + m_Remote(remoteDriver), + m_Replay(replayDriver), + m_PreviewWindow(previewWindow), + m_RemoteServer(true) +{ + m_APIProps = m_Remote->GetAPIProperties(); + + InitRemoteExecutionThread(); + + if(m_Replay) + InitPreviewWindow(); + + if(m_APIProps.pipelineType == GraphicsAPI::D3D11) + m_D3D11PipelineState = new D3D11Pipe::State; + else if(m_APIProps.pipelineType == GraphicsAPI::D3D12) + m_D3D12PipelineState = new D3D12Pipe::State; + else if(m_APIProps.pipelineType == GraphicsAPI::OpenGL) + m_GLPipelineState = new GLPipe::State; + else if(m_APIProps.pipelineType == GraphicsAPI::Vulkan) + m_VulkanPipelineState = new VKPipe::State; + + m_Remote->SetPipelineStates(m_D3D11PipelineState, m_D3D12PipelineState, m_GLPipelineState, + m_VulkanPipelineState); +} + +ReplayProxy::ReplayProxy(ReadSerialiser &reader, WriteSerialiser &writer, IReplayDriver *proxy) + : m_Reader(reader), + m_Writer(writer), + m_Proxy(proxy), + m_Remote(NULL), + m_Replay(NULL), + m_RemoteServer(false) +{ + ReplayProxy::GetAPIProperties(); + ReplayProxy::FetchStructuredFile(); +} + ReplayProxy::~ReplayProxy() { + if(m_Remote) + { + SAFE_DELETE(m_D3D11PipelineState); + SAFE_DELETE(m_D3D12PipelineState); + SAFE_DELETE(m_GLPipelineState); + SAFE_DELETE(m_VulkanPipelineState); + } + ShutdownRemoteExecutionThread(); ShutdownPreviewWindow(); @@ -1651,15 +1701,6 @@ void ReplayProxy::Proxied_SavePipelineState(ParamSerialiser ¶mser, ReturnSer if(paramser.IsReading() && !paramser.IsErrored() && !m_IsErrored) { m_Remote->SavePipelineState(eventId); - - 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(); } } @@ -1668,31 +1709,31 @@ void ReplayProxy::Proxied_SavePipelineState(ParamSerialiser ¶mser, ReturnSer PACKET_HEADER(packet); if(m_APIProps.pipelineType == GraphicsAPI::D3D11) { - SERIALISE_ELEMENT(m_D3D11PipelineState); + SERIALISE_ELEMENT(*m_D3D11PipelineState); } else if(m_APIProps.pipelineType == GraphicsAPI::D3D12) { - SERIALISE_ELEMENT(m_D3D12PipelineState); + SERIALISE_ELEMENT(*m_D3D12PipelineState); } else if(m_APIProps.pipelineType == GraphicsAPI::OpenGL) { - SERIALISE_ELEMENT(m_GLPipelineState); + SERIALISE_ELEMENT(*m_GLPipelineState); } else if(m_APIProps.pipelineType == GraphicsAPI::Vulkan) { - SERIALISE_ELEMENT(m_VulkanPipelineState); + SERIALISE_ELEMENT(*m_VulkanPipelineState); } SERIALISE_ELEMENT(packet); ser.EndChunk(); if(retser.IsReading()) { - if(m_APIProps.pipelineType == GraphicsAPI::D3D11) + if(m_APIProps.pipelineType == GraphicsAPI::D3D11 && m_D3D11PipelineState) { D3D11Pipe::Shader *stages[] = { - &m_D3D11PipelineState.vertexShader, &m_D3D11PipelineState.hullShader, - &m_D3D11PipelineState.domainShader, &m_D3D11PipelineState.geometryShader, - &m_D3D11PipelineState.pixelShader, &m_D3D11PipelineState.computeShader, + &m_D3D11PipelineState->vertexShader, &m_D3D11PipelineState->hullShader, + &m_D3D11PipelineState->domainShader, &m_D3D11PipelineState->geometryShader, + &m_D3D11PipelineState->pixelShader, &m_D3D11PipelineState->computeShader, }; for(int i = 0; i < 6; i++) @@ -1700,32 +1741,32 @@ void ReplayProxy::Proxied_SavePipelineState(ParamSerialiser ¶mser, ReturnSer stages[i]->reflection = GetShader(ResourceId(), GetLiveID(stages[i]->resourceId), ShaderEntryPoint()); - if(m_D3D11PipelineState.inputAssembly.resourceId != ResourceId()) - m_D3D11PipelineState.inputAssembly.bytecode = - GetShader(ResourceId(), GetLiveID(m_D3D11PipelineState.inputAssembly.resourceId), + if(m_D3D11PipelineState->inputAssembly.resourceId != ResourceId()) + m_D3D11PipelineState->inputAssembly.bytecode = + GetShader(ResourceId(), GetLiveID(m_D3D11PipelineState->inputAssembly.resourceId), ShaderEntryPoint()); } - else if(m_APIProps.pipelineType == GraphicsAPI::D3D12) + else if(m_APIProps.pipelineType == GraphicsAPI::D3D12 && m_D3D12PipelineState) { D3D12Pipe::Shader *stages[] = { - &m_D3D12PipelineState.vertexShader, &m_D3D12PipelineState.hullShader, - &m_D3D12PipelineState.domainShader, &m_D3D12PipelineState.geometryShader, - &m_D3D12PipelineState.pixelShader, &m_D3D12PipelineState.computeShader, + &m_D3D12PipelineState->vertexShader, &m_D3D12PipelineState->hullShader, + &m_D3D12PipelineState->domainShader, &m_D3D12PipelineState->geometryShader, + &m_D3D12PipelineState->pixelShader, &m_D3D12PipelineState->computeShader, }; - ResourceId pipe = GetLiveID(m_D3D12PipelineState.pipelineResourceId); + ResourceId pipe = GetLiveID(m_D3D12PipelineState->pipelineResourceId); for(int i = 0; i < 6; i++) if(stages[i]->resourceId != ResourceId()) stages[i]->reflection = GetShader(pipe, GetLiveID(stages[i]->resourceId), ShaderEntryPoint()); } - else if(m_APIProps.pipelineType == GraphicsAPI::OpenGL) + else if(m_APIProps.pipelineType == GraphicsAPI::OpenGL && m_GLPipelineState) { GLPipe::Shader *stages[] = { - &m_GLPipelineState.vertexShader, &m_GLPipelineState.tessControlShader, - &m_GLPipelineState.tessEvalShader, &m_GLPipelineState.geometryShader, - &m_GLPipelineState.fragmentShader, &m_GLPipelineState.computeShader, + &m_GLPipelineState->vertexShader, &m_GLPipelineState->tessControlShader, + &m_GLPipelineState->tessEvalShader, &m_GLPipelineState->geometryShader, + &m_GLPipelineState->fragmentShader, &m_GLPipelineState->computeShader, }; for(int i = 0; i < 6; i++) @@ -1733,20 +1774,20 @@ void ReplayProxy::Proxied_SavePipelineState(ParamSerialiser ¶mser, ReturnSer stages[i]->reflection = GetShader(ResourceId(), GetLiveID(stages[i]->shaderResourceId), ShaderEntryPoint()); } - else if(m_APIProps.pipelineType == GraphicsAPI::Vulkan) + else if(m_APIProps.pipelineType == GraphicsAPI::Vulkan && m_VulkanPipelineState) { VKPipe::Shader *stages[] = { - &m_VulkanPipelineState.vertexShader, &m_VulkanPipelineState.tessControlShader, - &m_VulkanPipelineState.tessEvalShader, &m_VulkanPipelineState.geometryShader, - &m_VulkanPipelineState.fragmentShader, &m_VulkanPipelineState.computeShader, + &m_VulkanPipelineState->vertexShader, &m_VulkanPipelineState->tessControlShader, + &m_VulkanPipelineState->tessEvalShader, &m_VulkanPipelineState->geometryShader, + &m_VulkanPipelineState->fragmentShader, &m_VulkanPipelineState->computeShader, }; - ResourceId pipe = GetLiveID(m_VulkanPipelineState.graphics.pipelineResourceId); + ResourceId pipe = GetLiveID(m_VulkanPipelineState->graphics.pipelineResourceId); for(int i = 0; i < 6; i++) { if(i == 5) - pipe = GetLiveID(m_VulkanPipelineState.compute.pipelineResourceId); + pipe = GetLiveID(m_VulkanPipelineState->compute.pipelineResourceId); if(stages[i]->resourceId != ResourceId()) stages[i]->reflection = diff --git a/renderdoc/core/replay_proxy.h b/renderdoc/core/replay_proxy.h index fe49975b0..17260a692 100644 --- a/renderdoc/core/replay_proxy.h +++ b/renderdoc/core/replay_proxy.h @@ -122,35 +122,10 @@ DECLARE_REFLECTION_ENUM(ReplayProxyPacket); class ReplayProxy : public IReplayDriver { public: - ReplayProxy(ReadSerialiser &reader, WriteSerialiser &writer, IReplayDriver *proxy) - : m_Reader(reader), - m_Writer(writer), - m_Proxy(proxy), - m_Remote(NULL), - m_Replay(NULL), - m_RemoteServer(false) - { - ReplayProxy::GetAPIProperties(); - ReplayProxy::FetchStructuredFile(); - } + ReplayProxy(ReadSerialiser &reader, WriteSerialiser &writer, IReplayDriver *proxy); ReplayProxy(ReadSerialiser &reader, WriteSerialiser &writer, IRemoteDriver *remoteDriver, - IReplayDriver *replayDriver, RENDERDOC_PreviewWindowCallback previewWindow) - : m_Reader(reader), - m_Writer(writer), - m_Proxy(NULL), - m_Remote(remoteDriver), - m_Replay(replayDriver), - m_PreviewWindow(previewWindow), - m_RemoteServer(true) - { - RDCEraseEl(m_APIProps); - - InitRemoteExecutionThread(); - - if(m_Replay) - InitPreviewWindow(); - } + IReplayDriver *replayDriver, RENDERDOC_PreviewWindowCallback previewWindow); virtual ~ReplayProxy(); @@ -460,11 +435,15 @@ public: bool Tick(int type); - 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; } const SDFile &GetStructuredFile() { return m_StructuredFile; } + void SetPipelineStates(D3D11Pipe::State *d3d11, D3D12Pipe::State *d3d12, GLPipe::State *gl, + VKPipe::State *vk) + { + m_D3D11PipelineState = d3d11; + m_D3D12PipelineState = d3d12; + m_GLPipelineState = gl; + m_VulkanPipelineState = vk; + } IMPLEMENT_FUNCTION_PROXIED(void, FetchStructuredFile); IMPLEMENT_FUNCTION_PROXIED(rdcarray, GetResources); @@ -724,8 +703,8 @@ private: SDFile m_StructuredFile; - D3D11Pipe::State m_D3D11PipelineState; - D3D12Pipe::State m_D3D12PipelineState; - GLPipe::State m_GLPipelineState; - VKPipe::State m_VulkanPipelineState; + D3D11Pipe::State *m_D3D11PipelineState = NULL; + D3D12Pipe::State *m_D3D12PipelineState = NULL; + GLPipe::State *m_GLPipelineState = NULL; + VKPipe::State *m_VulkanPipelineState = NULL; }; diff --git a/renderdoc/driver/d3d11/d3d11_overlay.cpp b/renderdoc/driver/d3d11/d3d11_overlay.cpp index e93704aa4..b40d77614 100644 --- a/renderdoc/driver/d3d11/d3d11_overlay.cpp +++ b/renderdoc/driver/d3d11/d3d11_overlay.cpp @@ -69,19 +69,46 @@ static void SetRTVDesc(D3D11_RENDER_TARGET_VIEW_DESC &rtDesc, const D3D11_TEXTUR RenderOutputSubresource D3D11Replay::GetRenderOutputSubresource(ResourceId id) { - id = m_pDevice->GetResourceManager()->GetOriginalID(id); + D3D11RenderState *rs = m_pDevice->GetImmediateContext()->GetCurrentPipelineState(); for(size_t i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) { - const D3D11Pipe::View &rt = m_CurPipelineState.outputMerger.renderTargets[i]; + ID3D11RenderTargetView *rtv = rs->OM.RenderTargets[i]; + ID3D11Resource *res = NULL; + if(rtv) + { + rtv->GetResource(&res); + if(res) + res->Release(); - if(rt.viewResourceId == id || rt.resourceResourceId == id) - return RenderOutputSubresource(rt.firstMip, rt.firstSlice, rt.numSlices); + if(GetIDForDeviceChild(rtv) == id || GetIDForDeviceChild(res) == id) + { + D3D11_RENDER_TARGET_VIEW_DESC desc = {}; + rtv->GetDesc(&desc); + return RenderOutputSubresource(GetMipForRtv(desc), GetSliceForRtv(desc), + GetSliceCountForRtv(desc)); + } + } } - const D3D11Pipe::View &dsv = m_CurPipelineState.outputMerger.depthTarget; - if(dsv.viewResourceId == id || dsv.resourceResourceId == id) - return RenderOutputSubresource(dsv.firstMip, dsv.firstSlice, dsv.numSlices); + { + ID3D11DepthStencilView *dsv = rs->OM.DepthView; + ID3D11Resource *res = NULL; + if(dsv) + { + dsv->GetResource(&res); + if(res) + res->Release(); + + if(GetIDForDeviceChild(dsv) == id || GetIDForDeviceChild(res) == id) + { + D3D11_DEPTH_STENCIL_VIEW_DESC desc = {}; + dsv->GetDesc(&desc); + return RenderOutputSubresource(GetMipForDsv(desc), GetSliceForDsv(desc), + GetSliceCountForDsv(desc)); + } + } + } return RenderOutputSubresource(~0U, ~0U, 0); } diff --git a/renderdoc/driver/d3d11/d3d11_replay.cpp b/renderdoc/driver/d3d11/d3d11_replay.cpp index d055c2dc8..0571225d3 100644 --- a/renderdoc/driver/d3d11/d3d11_replay.cpp +++ b/renderdoc/driver/d3d11/d3d11_replay.cpp @@ -691,9 +691,12 @@ rdcarray D3D11Replay::GetTextures() void D3D11Replay::SavePipelineState(uint32_t eventId) { + if(!m_D3D11PipelineState) + return; + D3D11RenderState *rs = m_pDevice->GetImmediateContext()->GetCurrentPipelineState(); - D3D11Pipe::State &ret = m_CurPipelineState; + D3D11Pipe::State &ret = *m_D3D11PipelineState; ///////////////////////////////////////////////// // Input Assembler diff --git a/renderdoc/driver/d3d11/d3d11_replay.h b/renderdoc/driver/d3d11/d3d11_replay.h index b62d91dfb..ea598d324 100644 --- a/renderdoc/driver/d3d11/d3d11_replay.h +++ b/renderdoc/driver/d3d11/d3d11_replay.h @@ -137,11 +137,12 @@ public: FrameRecord &WriteFrameRecord() { return m_FrameRecord; } FrameRecord GetFrameRecord() { return m_FrameRecord; } + void SetPipelineStates(D3D11Pipe::State *d3d11, D3D12Pipe::State *d3d12, GLPipe::State *gl, + VKPipe::State *vk) + { + m_D3D11PipelineState = d3d11; + } void SavePipelineState(uint32_t eventId); - const D3D11Pipe::State *GetD3D11PipelineState() { return &m_CurPipelineState; } - const D3D12Pipe::State *GetD3D12PipelineState() { return NULL; } - const GLPipe::State *GetGLPipelineState() { return NULL; } - const VKPipe::State *GetVulkanPipelineState() { return NULL; } void FreeTargetResource(ResourceId id); void FreeCustomShader(ResourceId id); @@ -489,5 +490,5 @@ private: FrameRecord m_FrameRecord; - D3D11Pipe::State m_CurPipelineState; + D3D11Pipe::State *m_D3D11PipelineState = NULL; }; diff --git a/renderdoc/driver/d3d11/d3d11_resources.cpp b/renderdoc/driver/d3d11/d3d11_resources.cpp index 2227fe645..3be02edbc 100644 --- a/renderdoc/driver/d3d11/d3d11_resources.cpp +++ b/renderdoc/driver/d3d11/d3d11_resources.cpp @@ -274,6 +274,17 @@ UINT GetSliceForDsv(const D3D11_DEPTH_STENCIL_VIEW_DESC &view) } } +UINT GetSliceCountForDsv(const D3D11_DEPTH_STENCIL_VIEW_DESC &view) +{ + switch(view.ViewDimension) + { + case D3D11_DSV_DIMENSION_TEXTURE1DARRAY: return view.Texture1DArray.ArraySize; + case D3D11_DSV_DIMENSION_TEXTURE2DARRAY: return view.Texture2DArray.ArraySize; + case D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY: return view.Texture2DMSArray.ArraySize; + default: return 0; + } +} + UINT GetMipForRtv(const D3D11_RENDER_TARGET_VIEW_DESC &view) { switch(view.ViewDimension) @@ -286,6 +297,7 @@ UINT GetMipForRtv(const D3D11_RENDER_TARGET_VIEW_DESC &view) default: return 0; } } + UINT GetSliceForRtv(const D3D11_RENDER_TARGET_VIEW_DESC &view) { switch(view.ViewDimension) @@ -297,6 +309,17 @@ UINT GetSliceForRtv(const D3D11_RENDER_TARGET_VIEW_DESC &view) } } +UINT GetSliceCountForRtv(const D3D11_RENDER_TARGET_VIEW_DESC &view) +{ + switch(view.ViewDimension) + { + case D3D11_RTV_DIMENSION_TEXTURE1DARRAY: return view.Texture1DArray.ArraySize; + case D3D11_RTV_DIMENSION_TEXTURE2DARRAY: return view.Texture2DArray.ArraySize; + case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY: return view.Texture2DMSArray.ArraySize; + default: return 0; + } +} + UINT GetMipForSrv(const D3D11_SHADER_RESOURCE_VIEW_DESC &view) { switch(view.ViewDimension) @@ -322,6 +345,19 @@ UINT GetSliceForSrv(const D3D11_SHADER_RESOURCE_VIEW_DESC &view) default: return 0; } } + +UINT GetSliceCountForSrv(const D3D11_SHADER_RESOURCE_VIEW_DESC &view) +{ + switch(view.ViewDimension) + { + case D3D11_SRV_DIMENSION_TEXTURE1DARRAY: return view.Texture1DArray.ArraySize; + case D3D11_SRV_DIMENSION_TEXTURE2DARRAY: return view.Texture2DArray.ArraySize; + case D3D11_SRV_DIMENSION_TEXTURECUBEARRAY: return view.TextureCubeArray.NumCubes * 6; + case D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY: return view.Texture2DMSArray.ArraySize; + default: return 0; + } +} + UINT GetMipForUav(const D3D11_UNORDERED_ACCESS_VIEW_DESC &view) { switch(view.ViewDimension) @@ -345,6 +381,17 @@ UINT GetSliceForUav(const D3D11_UNORDERED_ACCESS_VIEW_DESC &view) } } +UINT GetSliceCountForUav(const D3D11_UNORDERED_ACCESS_VIEW_DESC &view) +{ + switch(view.ViewDimension) + { + case D3D11_UAV_DIMENSION_TEXTURE1DARRAY: return view.Texture1DArray.ArraySize; + case D3D11_UAV_DIMENSION_TEXTURE2DARRAY: return view.Texture2DArray.ArraySize; + case D3D11_UAV_DIMENSION_TEXTURE3D: return view.Texture3D.WSize; + default: return 0; + } +} + ResourcePitch GetResourcePitchForSubresource(ID3D11DeviceContext *ctx, ID3D11Resource *res, int Subresource) { diff --git a/renderdoc/driver/d3d11/d3d11_resources.h b/renderdoc/driver/d3d11/d3d11_resources.h index fb75fce88..bb35330e0 100644 --- a/renderdoc/driver/d3d11/d3d11_resources.h +++ b/renderdoc/driver/d3d11/d3d11_resources.h @@ -43,12 +43,16 @@ UINT GetMipForSubresource(ID3D11Resource *res, int Subresource); UINT GetSliceForSubresource(ID3D11Resource *res, int Subresource); UINT GetMipForDsv(const D3D11_DEPTH_STENCIL_VIEW_DESC &dsv); UINT GetSliceForDsv(const D3D11_DEPTH_STENCIL_VIEW_DESC &dsv); +UINT GetSliceCountForDsv(const D3D11_DEPTH_STENCIL_VIEW_DESC &dsv); UINT GetMipForRtv(const D3D11_RENDER_TARGET_VIEW_DESC &rtv); UINT GetSliceForRtv(const D3D11_RENDER_TARGET_VIEW_DESC &rtv); +UINT GetSliceCountForRtv(const D3D11_RENDER_TARGET_VIEW_DESC &rtv); UINT GetMipForSrv(const D3D11_SHADER_RESOURCE_VIEW_DESC &srv); UINT GetSliceForSrv(const D3D11_SHADER_RESOURCE_VIEW_DESC &srv); +UINT GetSliceCountForSrv(const D3D11_SHADER_RESOURCE_VIEW_DESC &srv); UINT GetMipForUav(const D3D11_UNORDERED_ACCESS_VIEW_DESC &uav); UINT GetSliceForUav(const D3D11_UNORDERED_ACCESS_VIEW_DESC &uav); +UINT GetSliceCountForUav(const D3D11_UNORDERED_ACCESS_VIEW_DESC &uav); struct ResourcePitch { diff --git a/renderdoc/driver/d3d12/d3d12_replay.cpp b/renderdoc/driver/d3d12/d3d12_replay.cpp index 6dae02236..064316171 100644 --- a/renderdoc/driver/d3d12/d3d12_replay.cpp +++ b/renderdoc/driver/d3d12/d3d12_replay.cpp @@ -1402,6 +1402,9 @@ void D3D12Replay::FillRootElements(uint32_t eventId, const D3D12RenderState::Roo void D3D12Replay::SavePipelineState(uint32_t eventId) { + if(!m_D3D12PipelineState) + return; + const D3D12RenderState &rs = m_pDevice->GetQueue()->GetCommandData()->m_RenderState; D3D12MarkerRegion::Begin(m_pDevice->GetQueue(), @@ -1411,7 +1414,7 @@ void D3D12Replay::SavePipelineState(uint32_t eventId) D3D12MarkerRegion::End(m_pDevice->GetQueue()); - D3D12Pipe::State &state = m_PipelineState; + D3D12Pipe::State &state = *m_D3D12PipelineState; ///////////////////////////////////////////////// // Input Assembler diff --git a/renderdoc/driver/d3d12/d3d12_replay.h b/renderdoc/driver/d3d12/d3d12_replay.h index af1f68b35..831891615 100644 --- a/renderdoc/driver/d3d12/d3d12_replay.h +++ b/renderdoc/driver/d3d12/d3d12_replay.h @@ -111,11 +111,12 @@ public: FrameRecord &WriteFrameRecord() { return m_FrameRecord; } FrameRecord GetFrameRecord() { return m_FrameRecord; } + void SetPipelineStates(D3D11Pipe::State *d3d11, D3D12Pipe::State *d3d12, GLPipe::State *gl, + VKPipe::State *vk) + { + m_D3D12PipelineState = d3d12; + } void SavePipelineState(uint32_t eventId); - const D3D11Pipe::State *GetD3D11PipelineState() { return NULL; } - const D3D12Pipe::State *GetD3D12PipelineState() { return &m_PipelineState; } - const GLPipe::State *GetGLPipelineState() { return NULL; } - const VKPipe::State *GetVulkanPipelineState() { return NULL; } void FreeTargetResource(ResourceId id); void FreeCustomShader(ResourceId id); @@ -457,7 +458,7 @@ private: bool m_ISAChecked = false; bool m_ISAAvailable = false; - D3D12Pipe::State m_PipelineState; + D3D12Pipe::State *m_D3D12PipelineState = NULL; FrameRecord m_FrameRecord; diff --git a/renderdoc/driver/d3d12/d3d12_shaderdebug.cpp b/renderdoc/driver/d3d12/d3d12_shaderdebug.cpp index 8280d2e01..1ca0cb9a3 100644 --- a/renderdoc/driver/d3d12/d3d12_shaderdebug.cpp +++ b/renderdoc/driver/d3d12/d3d12_shaderdebug.cpp @@ -1817,10 +1817,18 @@ ShaderDebugTrace *D3D12Replay::DebugVertex(uint32_t eventId, uint32_t vertid, ui m_pDevice->GetQueue()->GetReal(), StringFormat::Fmt("DebugVertex @ %u of (%u,%u,%u)", eventId, vertid, instid, idx)); - const D3D12Pipe::State *pipelineState = GetD3D12PipelineState(); - const D3D12Pipe::Shader &vertexShader = pipelineState->vertexShader; - WrappedID3D12Shader *vs = - m_pDevice->GetResourceManager()->GetCurrentAs(vertexShader.resourceId); + D3D12RenderState &rs = m_pDevice->GetQueue()->GetCommandData()->m_RenderState; + + WrappedID3D12PipelineState *pso = + m_pDevice->GetResourceManager()->GetCurrentAs(rs.pipe); + + if(!pso || !pso->IsGraphics()) + { + RDCERR("Can't debug with no current graphics pipeline"); + return new ShaderDebugTrace; + } + + WrappedID3D12Shader *vs = (WrappedID3D12Shader *)pso->graphics->VS.pShaderBytecode; if(!vs) { RDCERR("Can't debug with no current vertex shader"); @@ -1844,11 +1852,6 @@ ShaderDebugTrace *D3D12Replay::DebugVertex(uint32_t eventId, uint32_t vertid, ui dxbc->GetDisassembly(); - const D3D12RenderState &rs = m_pDevice->GetQueue()->GetCommandData()->m_RenderState; - - WrappedID3D12PipelineState *pso = - m_pDevice->GetResourceManager()->GetCurrentAs(rs.pipe); - const ActionDescription *action = m_pDevice->GetAction(eventId); rdcarray inputlayout; @@ -2193,12 +2196,18 @@ ShaderDebugTrace *D3D12Replay::DebugPixel(uint32_t eventId, uint32_t x, uint32_t m_pDevice->GetQueue()->GetReal(), StringFormat::Fmt("DebugPixel @ %u of (%u,%u) %u / %u", eventId, x, y, sample, primitive)); - const D3D12Pipe::State *pipelineState = GetD3D12PipelineState(); + D3D12RenderState &rs = m_pDevice->GetQueue()->GetCommandData()->m_RenderState; - // Fetch the disassembly info from the pixel shader - const D3D12Pipe::Shader &pixelShader = pipelineState->pixelShader; - WrappedID3D12Shader *ps = - m_pDevice->GetResourceManager()->GetCurrentAs(pixelShader.resourceId); + WrappedID3D12PipelineState *pso = + m_pDevice->GetResourceManager()->GetCurrentAs(rs.pipe); + + if(!pso || !pso->IsGraphics()) + { + RDCERR("Can't debug with no current graphics pipeline"); + return new ShaderDebugTrace; + } + + WrappedID3D12Shader *ps = (WrappedID3D12Shader *)pso->graphics->PS.pShaderBytecode; if(!ps) { RDCERR("Can't debug with no current pixel shader"); @@ -2226,27 +2235,21 @@ ShaderDebugTrace *D3D12Replay::DebugPixel(uint32_t eventId, uint32_t x, uint32_t DXBCContainer *prevDxbc = NULL; // Check for geometry shader first { - const D3D12Pipe::Shader &geometryShader = pipelineState->geometryShader; - WrappedID3D12Shader *gs = - m_pDevice->GetResourceManager()->GetCurrentAs(geometryShader.resourceId); + WrappedID3D12Shader *gs = (WrappedID3D12Shader *)pso->graphics->GS.pShaderBytecode; if(gs) prevDxbc = gs->GetDXBC(); } // Check for domain shader next if(prevDxbc == NULL) { - const D3D12Pipe::Shader &domainShader = pipelineState->domainShader; - WrappedID3D12Shader *ds = - m_pDevice->GetResourceManager()->GetCurrentAs(domainShader.resourceId); + WrappedID3D12Shader *ds = (WrappedID3D12Shader *)pso->graphics->DS.pShaderBytecode; if(ds) prevDxbc = ds->GetDXBC(); } // Check for vertex shader last if(prevDxbc == NULL) { - const D3D12Pipe::Shader &vertexShader = pipelineState->vertexShader; - WrappedID3D12Shader *vs = - m_pDevice->GetResourceManager()->GetCurrentAs(vertexShader.resourceId); + WrappedID3D12Shader *vs = (WrappedID3D12Shader *)pso->graphics->VS.pShaderBytecode; if(vs) prevDxbc = vs->GetDXBC(); } @@ -2277,7 +2280,6 @@ ShaderDebugTrace *D3D12Replay::DebugPixel(uint32_t eventId, uint32_t x, uint32_t } // Store a copy of the event's render state to restore later - D3D12RenderState &rs = m_pDevice->GetQueue()->GetCommandData()->m_RenderState; D3D12RenderState prevState = rs; // Fetch the multisample count from the PSO @@ -2989,10 +2991,14 @@ ShaderDebugTrace *D3D12Replay::DebugThread(uint32_t eventId, StringFormat::Fmt("DebugThread @ %u: [%u, %u, %u] (%u, %u, %u)", eventId, groupid[0], groupid[1], groupid[2], threadid[0], threadid[1], threadid[2])); - const D3D12Pipe::State *pipelineState = GetD3D12PipelineState(); - const D3D12Pipe::Shader &computeShader = pipelineState->computeShader; + const D3D12RenderState &rs = m_pDevice->GetQueue()->GetCommandData()->m_RenderState; + + WrappedID3D12PipelineState *pso = + m_pDevice->GetResourceManager()->GetCurrentAs(rs.pipe); + WrappedID3D12Shader *cs = - m_pDevice->GetResourceManager()->GetCurrentAs(computeShader.resourceId); + pso && pso->IsCompute() ? (WrappedID3D12Shader *)pso->compute->CS.pShaderBytecode : NULL; + if(!cs) { RDCERR("Can't debug with no current compute shader"); @@ -3016,11 +3022,6 @@ ShaderDebugTrace *D3D12Replay::DebugThread(uint32_t eventId, dxbc->GetDisassembly(); - const D3D12RenderState &rs = m_pDevice->GetQueue()->GetCommandData()->m_RenderState; - - WrappedID3D12PipelineState *pso = - m_pDevice->GetResourceManager()->GetCurrentAs(rs.pipe); - InterpretDebugger *interpreter = new InterpretDebugger; interpreter->eventId = eventId; ShaderDebugTrace *ret = interpreter->BeginDebug(dxbc, refl, pso->CS()->GetMapping(), 0); diff --git a/renderdoc/driver/gl/gl_replay.cpp b/renderdoc/driver/gl/gl_replay.cpp index 3b9aabcee..9895d8559 100644 --- a/renderdoc/driver/gl/gl_replay.cpp +++ b/renderdoc/driver/gl/gl_replay.cpp @@ -783,7 +783,10 @@ rdcstr GLReplay::DisassembleShader(ResourceId pipeline, const ShaderReflection * void GLReplay::SavePipelineState(uint32_t eventId) { - GLPipe::State &pipe = m_CurPipelineState; + if(!m_GLPipelineState) + return; + + GLPipe::State &pipe = *m_GLPipelineState; WrappedOpenGL &drv = *m_pDriver; GLResourceManager *rm = m_pDriver->GetResourceManager(); diff --git a/renderdoc/driver/gl/gl_replay.h b/renderdoc/driver/gl/gl_replay.h index e3b7ec3ac..364676fa2 100644 --- a/renderdoc/driver/gl/gl_replay.h +++ b/renderdoc/driver/gl/gl_replay.h @@ -140,11 +140,12 @@ public: FrameRecord &WriteFrameRecord() { return m_FrameRecord; } FrameRecord GetFrameRecord() { return m_FrameRecord; } + void SetPipelineStates(D3D11Pipe::State *d3d11, D3D12Pipe::State *d3d12, GLPipe::State *gl, + VKPipe::State *vk) + { + m_GLPipelineState = gl; + } void SavePipelineState(uint32_t eventId); - const D3D11Pipe::State *GetD3D11PipelineState() { return NULL; } - const D3D12Pipe::State *GetD3D12PipelineState() { return NULL; } - const GLPipe::State *GetGLPipelineState() { return &m_CurPipelineState; } - const VKPipe::State *GetVulkanPipelineState() { return NULL; } void FreeTargetResource(ResourceId id); ReplayStatus ReadLogInitialisation(RDCFile *rdc, bool storeStructuredBuffers); @@ -463,7 +464,7 @@ private: rdcarray m_Resources; std::map m_ResourceIdx; - GLPipe::State m_CurPipelineState; + GLPipe::State *m_GLPipelineState = NULL; FrameRecord m_FrameRecord; diff --git a/renderdoc/driver/vulkan/vk_overlay.cpp b/renderdoc/driver/vulkan/vk_overlay.cpp index 2b0be09ce..633d635d6 100644 --- a/renderdoc/driver/vulkan/vk_overlay.cpp +++ b/renderdoc/driver/vulkan/vk_overlay.cpp @@ -468,13 +468,18 @@ void VulkanDebugManager::PatchLineStripIndexBuffer(const ActionDescription *acti RenderOutputSubresource VulkanReplay::GetRenderOutputSubresource(ResourceId id) { - id = GetResourceManager()->GetOriginalID(id); + const VulkanRenderState &state = m_pDriver->m_RenderState; + VulkanCreationInfo &c = m_pDriver->m_CreationInfo; - for(const VKPipe::Attachment &att : m_VulkanPipelineState.currentPass.framebuffer.attachments) + for(ResourceId viewid : state.GetFramebufferAttachments()) { - if(att.viewResourceId == id || att.imageResourceId == id) + const VulkanCreationInfo::ImageView &viewInfo = c.m_ImageView[viewid]; + + if(viewid == id || viewInfo.image == id) { - return RenderOutputSubresource(att.firstMip, att.firstSlice, att.numSlices); + return RenderOutputSubresource(viewInfo.range.baseMipLevel, + c.m_ImageView[viewid].range.baseArrayLayer, + c.m_ImageView[viewid].range.layerCount); } } diff --git a/renderdoc/driver/vulkan/vk_replay.cpp b/renderdoc/driver/vulkan/vk_replay.cpp index 13437b1f4..ecab9eac6 100644 --- a/renderdoc/driver/vulkan/vk_replay.cpp +++ b/renderdoc/driver/vulkan/vk_replay.cpp @@ -1018,9 +1018,14 @@ static void Convert(TextureSwizzle4 &dst, VkComponentMapping src) void VulkanReplay::SavePipelineState(uint32_t eventId) { + if(!m_VulkanPipelineState) + return; + const VulkanRenderState &state = m_pDriver->m_RenderState; VulkanCreationInfo &c = m_pDriver->m_CreationInfo; + VKPipe::State &ret = *m_VulkanPipelineState; + VulkanResourceManager *rm = m_pDriver->GetResourceManager(); VkMarkerRegion::Begin(StringFormat::Fmt("FetchShaderFeedback for %u", eventId)); @@ -1035,35 +1040,33 @@ void VulkanReplay::SavePipelineState(uint32_t eventId) rdcarray graphicsDescriptors; rdcarray computeDescriptors; - m_VulkanPipelineState.graphics.descriptorSets.swap(graphicsDescriptors); - m_VulkanPipelineState.compute.descriptorSets.swap(computeDescriptors); + ret.graphics.descriptorSets.swap(graphicsDescriptors); + ret.compute.descriptorSets.swap(computeDescriptors); - m_VulkanPipelineState = VKPipe::State(); + ret = VKPipe::State(); - m_VulkanPipelineState.graphics.descriptorSets.swap(graphicsDescriptors); - m_VulkanPipelineState.compute.descriptorSets.swap(computeDescriptors); + ret.graphics.descriptorSets.swap(graphicsDescriptors); + ret.compute.descriptorSets.swap(computeDescriptors); } - m_VulkanPipelineState.pushconsts.resize(state.pushConstSize); - memcpy(m_VulkanPipelineState.pushconsts.data(), state.pushconsts, state.pushConstSize); + ret.pushconsts.resize(state.pushConstSize); + memcpy(ret.pushconsts.data(), state.pushconsts, state.pushConstSize); // General pipeline properties - m_VulkanPipelineState.compute.pipelineResourceId = - rm->GetUnreplacedOriginalID(state.compute.pipeline); - m_VulkanPipelineState.graphics.pipelineResourceId = - rm->GetUnreplacedOriginalID(state.graphics.pipeline); + ret.compute.pipelineResourceId = rm->GetUnreplacedOriginalID(state.compute.pipeline); + ret.graphics.pipelineResourceId = rm->GetUnreplacedOriginalID(state.graphics.pipeline); if(state.compute.pipeline != ResourceId()) { const VulkanCreationInfo::Pipeline &p = c.m_Pipeline[state.compute.pipeline]; - m_VulkanPipelineState.compute.pipelineLayoutResourceId = rm->GetOriginalID(p.layout); + ret.compute.pipelineLayoutResourceId = rm->GetOriginalID(p.layout); const VulkanCreationInfo::PipelineLayout &pl = c.m_PipelineLayout[p.layout]; - m_VulkanPipelineState.compute.flags = p.flags; + ret.compute.flags = p.flags; - VKPipe::Shader &stage = m_VulkanPipelineState.computeShader; + VKPipe::Shader &stage = ret.computeShader; int i = 5; // 5 is the CS idx (VS, TCS, TES, GS, FS, CS) { @@ -1118,66 +1121,59 @@ void VulkanReplay::SavePipelineState(uint32_t eventId) } else { - m_VulkanPipelineState.compute.pipelineLayoutResourceId = ResourceId(); - m_VulkanPipelineState.compute.flags = 0; - m_VulkanPipelineState.computeShader = VKPipe::Shader(); + ret.compute.pipelineLayoutResourceId = ResourceId(); + ret.compute.flags = 0; + ret.computeShader = VKPipe::Shader(); } if(state.graphics.pipeline != ResourceId()) { const VulkanCreationInfo::Pipeline &p = c.m_Pipeline[state.graphics.pipeline]; - m_VulkanPipelineState.graphics.pipelineLayoutResourceId = rm->GetOriginalID(p.layout); + ret.graphics.pipelineLayoutResourceId = rm->GetOriginalID(p.layout); const VulkanCreationInfo::PipelineLayout &pl = c.m_PipelineLayout[p.layout]; - m_VulkanPipelineState.graphics.flags = p.flags; + ret.graphics.flags = p.flags; // Input Assembly - m_VulkanPipelineState.inputAssembly.indexBuffer.resourceId = rm->GetOriginalID(state.ibuffer.buf); - m_VulkanPipelineState.inputAssembly.indexBuffer.byteOffset = state.ibuffer.offs; - m_VulkanPipelineState.inputAssembly.indexBuffer.byteStride = state.ibuffer.bytewidth; - m_VulkanPipelineState.inputAssembly.primitiveRestartEnable = p.primitiveRestartEnable; - m_VulkanPipelineState.inputAssembly.topology = - MakePrimitiveTopology(state.primitiveTopology, p.patchControlPoints); + ret.inputAssembly.indexBuffer.resourceId = rm->GetOriginalID(state.ibuffer.buf); + ret.inputAssembly.indexBuffer.byteOffset = state.ibuffer.offs; + ret.inputAssembly.indexBuffer.byteStride = state.ibuffer.bytewidth; + ret.inputAssembly.primitiveRestartEnable = p.primitiveRestartEnable; + ret.inputAssembly.topology = MakePrimitiveTopology(state.primitiveTopology, p.patchControlPoints); // Vertex Input - m_VulkanPipelineState.vertexInput.attributes.resize(p.vertexAttrs.size()); + ret.vertexInput.attributes.resize(p.vertexAttrs.size()); for(size_t i = 0; i < p.vertexAttrs.size(); i++) { - m_VulkanPipelineState.vertexInput.attributes[i].location = p.vertexAttrs[i].location; - m_VulkanPipelineState.vertexInput.attributes[i].binding = p.vertexAttrs[i].binding; - m_VulkanPipelineState.vertexInput.attributes[i].byteOffset = p.vertexAttrs[i].byteoffset; - m_VulkanPipelineState.vertexInput.attributes[i].format = - MakeResourceFormat(p.vertexAttrs[i].format); + ret.vertexInput.attributes[i].location = p.vertexAttrs[i].location; + ret.vertexInput.attributes[i].binding = p.vertexAttrs[i].binding; + ret.vertexInput.attributes[i].byteOffset = p.vertexAttrs[i].byteoffset; + ret.vertexInput.attributes[i].format = MakeResourceFormat(p.vertexAttrs[i].format); } - m_VulkanPipelineState.vertexInput.bindings.resize(p.vertexBindings.size()); + ret.vertexInput.bindings.resize(p.vertexBindings.size()); for(size_t i = 0; i < p.vertexBindings.size(); i++) { - m_VulkanPipelineState.vertexInput.bindings[i].vertexBufferBinding = - p.vertexBindings[i].vbufferBinding; - m_VulkanPipelineState.vertexInput.bindings[i].perInstance = p.vertexBindings[i].perInstance; - m_VulkanPipelineState.vertexInput.bindings[i].instanceDivisor = - p.vertexBindings[i].instanceDivisor; + ret.vertexInput.bindings[i].vertexBufferBinding = p.vertexBindings[i].vbufferBinding; + ret.vertexInput.bindings[i].perInstance = p.vertexBindings[i].perInstance; + ret.vertexInput.bindings[i].instanceDivisor = p.vertexBindings[i].instanceDivisor; } - m_VulkanPipelineState.vertexInput.vertexBuffers.resize(state.vbuffers.size()); + ret.vertexInput.vertexBuffers.resize(state.vbuffers.size()); for(size_t i = 0; i < state.vbuffers.size(); i++) { - m_VulkanPipelineState.vertexInput.vertexBuffers[i].resourceId = - rm->GetOriginalID(state.vbuffers[i].buf); - m_VulkanPipelineState.vertexInput.vertexBuffers[i].byteOffset = state.vbuffers[i].offs; - m_VulkanPipelineState.vertexInput.vertexBuffers[i].byteStride = - (uint32_t)state.vbuffers[i].stride; - m_VulkanPipelineState.vertexInput.vertexBuffers[i].byteSize = (uint32_t)state.vbuffers[i].size; + ret.vertexInput.vertexBuffers[i].resourceId = rm->GetOriginalID(state.vbuffers[i].buf); + ret.vertexInput.vertexBuffers[i].byteOffset = state.vbuffers[i].offs; + ret.vertexInput.vertexBuffers[i].byteStride = (uint32_t)state.vbuffers[i].stride; + ret.vertexInput.vertexBuffers[i].byteSize = (uint32_t)state.vbuffers[i].size; } // Shader Stages VKPipe::Shader *stages[] = { - &m_VulkanPipelineState.vertexShader, &m_VulkanPipelineState.tessControlShader, - &m_VulkanPipelineState.tessEvalShader, &m_VulkanPipelineState.geometryShader, - &m_VulkanPipelineState.fragmentShader, + &ret.vertexShader, &ret.tessControlShader, &ret.tessEvalShader, + &ret.geometryShader, &ret.fragmentShader, }; for(size_t i = 0; i < ARRAY_COUNT(stages); i++) @@ -1232,391 +1228,357 @@ void VulkanReplay::SavePipelineState(uint32_t eventId) } // Tessellation - m_VulkanPipelineState.tessellation.numControlPoints = p.patchControlPoints; + ret.tessellation.numControlPoints = p.patchControlPoints; - m_VulkanPipelineState.tessellation.domainOriginUpperLeft = + ret.tessellation.domainOriginUpperLeft = p.tessellationDomainOrigin == VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT; // Transform feedback - m_VulkanPipelineState.transformFeedback.buffers.resize(state.xfbbuffers.size()); + ret.transformFeedback.buffers.resize(state.xfbbuffers.size()); for(size_t i = 0; i < state.xfbbuffers.size(); i++) { - m_VulkanPipelineState.transformFeedback.buffers[i].bufferResourceId = - rm->GetOriginalID(state.xfbbuffers[i].buf); - m_VulkanPipelineState.transformFeedback.buffers[i].byteOffset = state.xfbbuffers[i].offs; - m_VulkanPipelineState.transformFeedback.buffers[i].byteSize = state.xfbbuffers[i].size; + ret.transformFeedback.buffers[i].bufferResourceId = rm->GetOriginalID(state.xfbbuffers[i].buf); + ret.transformFeedback.buffers[i].byteOffset = state.xfbbuffers[i].offs; + ret.transformFeedback.buffers[i].byteSize = state.xfbbuffers[i].size; - m_VulkanPipelineState.transformFeedback.buffers[i].active = false; - m_VulkanPipelineState.transformFeedback.buffers[i].counterBufferResourceId = ResourceId(); - m_VulkanPipelineState.transformFeedback.buffers[i].counterBufferOffset = 0; + ret.transformFeedback.buffers[i].active = false; + ret.transformFeedback.buffers[i].counterBufferResourceId = ResourceId(); + ret.transformFeedback.buffers[i].counterBufferOffset = 0; if(i >= state.firstxfbcounter) { size_t xfb = i - state.firstxfbcounter; if(xfb < state.xfbcounters.size()) { - m_VulkanPipelineState.transformFeedback.buffers[i].active = true; - m_VulkanPipelineState.transformFeedback.buffers[i].counterBufferResourceId = + ret.transformFeedback.buffers[i].active = true; + ret.transformFeedback.buffers[i].counterBufferResourceId = rm->GetOriginalID(state.xfbcounters[xfb].buf); - m_VulkanPipelineState.transformFeedback.buffers[i].counterBufferOffset = - state.xfbcounters[xfb].offs; + ret.transformFeedback.buffers[i].counterBufferOffset = state.xfbcounters[xfb].offs; } } } // Viewport/Scissors size_t numViewScissors = state.views.size(); - m_VulkanPipelineState.viewportScissor.viewportScissors.resize(numViewScissors); + ret.viewportScissor.viewportScissors.resize(numViewScissors); for(size_t i = 0; i < numViewScissors; i++) { if(i < state.views.size()) { - m_VulkanPipelineState.viewportScissor.viewportScissors[i].vp.x = state.views[i].x; - m_VulkanPipelineState.viewportScissor.viewportScissors[i].vp.y = state.views[i].y; - m_VulkanPipelineState.viewportScissor.viewportScissors[i].vp.width = state.views[i].width; - m_VulkanPipelineState.viewportScissor.viewportScissors[i].vp.height = state.views[i].height; - m_VulkanPipelineState.viewportScissor.viewportScissors[i].vp.minDepth = - state.views[i].minDepth; - m_VulkanPipelineState.viewportScissor.viewportScissors[i].vp.maxDepth = - state.views[i].maxDepth; + ret.viewportScissor.viewportScissors[i].vp.x = state.views[i].x; + ret.viewportScissor.viewportScissors[i].vp.y = state.views[i].y; + ret.viewportScissor.viewportScissors[i].vp.width = state.views[i].width; + ret.viewportScissor.viewportScissors[i].vp.height = state.views[i].height; + ret.viewportScissor.viewportScissors[i].vp.minDepth = state.views[i].minDepth; + ret.viewportScissor.viewportScissors[i].vp.maxDepth = state.views[i].maxDepth; } else { - RDCEraseEl(m_VulkanPipelineState.viewportScissor.viewportScissors[i].vp); + RDCEraseEl(ret.viewportScissor.viewportScissors[i].vp); } if(i < state.scissors.size()) { - m_VulkanPipelineState.viewportScissor.viewportScissors[i].scissor.x = - state.scissors[i].offset.x; - m_VulkanPipelineState.viewportScissor.viewportScissors[i].scissor.y = - state.scissors[i].offset.y; - m_VulkanPipelineState.viewportScissor.viewportScissors[i].scissor.width = - state.scissors[i].extent.width; - m_VulkanPipelineState.viewportScissor.viewportScissors[i].scissor.height = - state.scissors[i].extent.height; + ret.viewportScissor.viewportScissors[i].scissor.x = state.scissors[i].offset.x; + ret.viewportScissor.viewportScissors[i].scissor.y = state.scissors[i].offset.y; + ret.viewportScissor.viewportScissors[i].scissor.width = state.scissors[i].extent.width; + ret.viewportScissor.viewportScissors[i].scissor.height = state.scissors[i].extent.height; } else { - RDCEraseEl(m_VulkanPipelineState.viewportScissor.viewportScissors[i].scissor); + RDCEraseEl(ret.viewportScissor.viewportScissors[i].scissor); } } { - m_VulkanPipelineState.viewportScissor.discardRectangles.resize(p.discardRectangles.size()); + ret.viewportScissor.discardRectangles.resize(p.discardRectangles.size()); for(size_t i = 0; i < p.discardRectangles.size() && i < state.discardRectangles.size(); i++) { - m_VulkanPipelineState.viewportScissor.discardRectangles[i].x = - state.discardRectangles[i].offset.x; - m_VulkanPipelineState.viewportScissor.discardRectangles[i].y = - state.discardRectangles[i].offset.y; - m_VulkanPipelineState.viewportScissor.discardRectangles[i].width = - state.discardRectangles[i].extent.width; - m_VulkanPipelineState.viewportScissor.discardRectangles[i].height = - state.discardRectangles[i].extent.height; + ret.viewportScissor.discardRectangles[i].x = state.discardRectangles[i].offset.x; + ret.viewportScissor.discardRectangles[i].y = state.discardRectangles[i].offset.y; + ret.viewportScissor.discardRectangles[i].width = state.discardRectangles[i].extent.width; + ret.viewportScissor.discardRectangles[i].height = state.discardRectangles[i].extent.height; } - m_VulkanPipelineState.viewportScissor.discardRectanglesExclusive = + ret.viewportScissor.discardRectanglesExclusive = (p.discardMode == VK_DISCARD_RECTANGLE_MODE_EXCLUSIVE_EXT); } // Rasterizer - m_VulkanPipelineState.rasterizer.depthClampEnable = p.depthClampEnable; - m_VulkanPipelineState.rasterizer.depthClipEnable = p.depthClipEnable; - m_VulkanPipelineState.rasterizer.rasterizerDiscardEnable = p.rasterizerDiscardEnable; - m_VulkanPipelineState.rasterizer.frontCCW = state.frontFace == VK_FRONT_FACE_COUNTER_CLOCKWISE; + ret.rasterizer.depthClampEnable = p.depthClampEnable; + ret.rasterizer.depthClipEnable = p.depthClipEnable; + ret.rasterizer.rasterizerDiscardEnable = p.rasterizerDiscardEnable; + ret.rasterizer.frontCCW = state.frontFace == VK_FRONT_FACE_COUNTER_CLOCKWISE; - m_VulkanPipelineState.rasterizer.conservativeRasterization = ConservativeRaster::Disabled; + ret.rasterizer.conservativeRasterization = ConservativeRaster::Disabled; switch(p.conservativeRasterizationMode) { case VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT: - m_VulkanPipelineState.rasterizer.conservativeRasterization = - ConservativeRaster::Underestimate; + ret.rasterizer.conservativeRasterization = ConservativeRaster::Underestimate; break; case VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT: - m_VulkanPipelineState.rasterizer.conservativeRasterization = ConservativeRaster::Overestimate; + ret.rasterizer.conservativeRasterization = ConservativeRaster::Overestimate; break; default: break; } - m_VulkanPipelineState.rasterizer.lineRasterMode = LineRaster::Default; + ret.rasterizer.lineRasterMode = LineRaster::Default; // "VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT is equivalent to // VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT if VkPhysicalDeviceLimits::strictLines is VK_TRUE" if(m_pDriver->GetDeviceProps().limits.strictLines) - m_VulkanPipelineState.rasterizer.lineRasterMode = LineRaster::Rectangular; + ret.rasterizer.lineRasterMode = LineRaster::Rectangular; switch(p.lineRasterMode) { case VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT: - m_VulkanPipelineState.rasterizer.lineRasterMode = LineRaster::Rectangular; + ret.rasterizer.lineRasterMode = LineRaster::Rectangular; break; case VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT: - m_VulkanPipelineState.rasterizer.lineRasterMode = LineRaster::Bresenham; + ret.rasterizer.lineRasterMode = LineRaster::Bresenham; break; case VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT: - m_VulkanPipelineState.rasterizer.lineRasterMode = LineRaster::RectangularSmooth; + ret.rasterizer.lineRasterMode = LineRaster::RectangularSmooth; break; default: break; } - m_VulkanPipelineState.rasterizer.lineStippleFactor = state.stippleFactor; - m_VulkanPipelineState.rasterizer.lineStipplePattern = state.stipplePattern; + ret.rasterizer.lineStippleFactor = state.stippleFactor; + ret.rasterizer.lineStipplePattern = state.stipplePattern; - m_VulkanPipelineState.rasterizer.extraPrimitiveOverestimationSize = - p.extraPrimitiveOverestimationSize; + ret.rasterizer.extraPrimitiveOverestimationSize = p.extraPrimitiveOverestimationSize; switch(p.polygonMode) { - case VK_POLYGON_MODE_POINT: - m_VulkanPipelineState.rasterizer.fillMode = FillMode::Point; - break; - case VK_POLYGON_MODE_LINE: - m_VulkanPipelineState.rasterizer.fillMode = FillMode::Wireframe; - break; - case VK_POLYGON_MODE_FILL: m_VulkanPipelineState.rasterizer.fillMode = FillMode::Solid; break; + case VK_POLYGON_MODE_POINT: ret.rasterizer.fillMode = FillMode::Point; break; + case VK_POLYGON_MODE_LINE: ret.rasterizer.fillMode = FillMode::Wireframe; break; + case VK_POLYGON_MODE_FILL: ret.rasterizer.fillMode = FillMode::Solid; break; default: - m_VulkanPipelineState.rasterizer.fillMode = FillMode::Solid; + ret.rasterizer.fillMode = FillMode::Solid; RDCERR("Unexpected value for FillMode %x", p.polygonMode); break; } switch(state.cullMode) { - case VK_CULL_MODE_NONE: m_VulkanPipelineState.rasterizer.cullMode = CullMode::NoCull; break; - case VK_CULL_MODE_FRONT_BIT: - m_VulkanPipelineState.rasterizer.cullMode = CullMode::Front; - break; - case VK_CULL_MODE_BACK_BIT: m_VulkanPipelineState.rasterizer.cullMode = CullMode::Back; break; - case VK_CULL_MODE_FRONT_AND_BACK: - m_VulkanPipelineState.rasterizer.cullMode = CullMode::FrontAndBack; - break; + case VK_CULL_MODE_NONE: ret.rasterizer.cullMode = CullMode::NoCull; break; + case VK_CULL_MODE_FRONT_BIT: ret.rasterizer.cullMode = CullMode::Front; break; + case VK_CULL_MODE_BACK_BIT: ret.rasterizer.cullMode = CullMode::Back; break; + case VK_CULL_MODE_FRONT_AND_BACK: ret.rasterizer.cullMode = CullMode::FrontAndBack; break; default: - m_VulkanPipelineState.rasterizer.cullMode = CullMode::NoCull; + ret.rasterizer.cullMode = CullMode::NoCull; RDCERR("Unexpected value for CullMode %x", state.cullMode); break; } - m_VulkanPipelineState.rasterizer.depthBias = state.bias.depth; - m_VulkanPipelineState.rasterizer.depthBiasClamp = state.bias.biasclamp; - m_VulkanPipelineState.rasterizer.slopeScaledDepthBias = state.bias.slope; - m_VulkanPipelineState.rasterizer.lineWidth = state.lineWidth; + ret.rasterizer.depthBias = state.bias.depth; + ret.rasterizer.depthBiasClamp = state.bias.biasclamp; + ret.rasterizer.slopeScaledDepthBias = state.bias.slope; + ret.rasterizer.lineWidth = state.lineWidth; // MSAA - m_VulkanPipelineState.multisample.rasterSamples = p.rasterizationSamples; - m_VulkanPipelineState.multisample.sampleShadingEnable = p.sampleShadingEnable; - m_VulkanPipelineState.multisample.minSampleShading = p.minSampleShading; - m_VulkanPipelineState.multisample.sampleMask = p.sampleMask; + ret.multisample.rasterSamples = p.rasterizationSamples; + ret.multisample.sampleShadingEnable = p.sampleShadingEnable; + ret.multisample.minSampleShading = p.minSampleShading; + ret.multisample.sampleMask = p.sampleMask; - m_VulkanPipelineState.multisample.sampleLocations.customLocations.clear(); + ret.multisample.sampleLocations.customLocations.clear(); if(p.sampleLocations.enabled) { - m_VulkanPipelineState.multisample.sampleLocations.gridWidth = - state.sampleLocations.gridSize.width; - m_VulkanPipelineState.multisample.sampleLocations.gridHeight = - state.sampleLocations.gridSize.height; - m_VulkanPipelineState.multisample.sampleLocations.customLocations.reserve( - state.sampleLocations.locations.size()); + ret.multisample.sampleLocations.gridWidth = state.sampleLocations.gridSize.width; + ret.multisample.sampleLocations.gridHeight = state.sampleLocations.gridSize.height; + ret.multisample.sampleLocations.customLocations.reserve(state.sampleLocations.locations.size()); for(const VkSampleLocationEXT &loc : state.sampleLocations.locations) { - m_VulkanPipelineState.multisample.sampleLocations.customLocations.push_back( - {loc.x, loc.y, 0.0f, 0.0f}); + ret.multisample.sampleLocations.customLocations.push_back({loc.x, loc.y, 0.0f, 0.0f}); } } // Color Blend - m_VulkanPipelineState.colorBlend.alphaToCoverageEnable = p.alphaToCoverageEnable; - m_VulkanPipelineState.colorBlend.alphaToOneEnable = p.alphaToOneEnable; + ret.colorBlend.alphaToCoverageEnable = p.alphaToCoverageEnable; + ret.colorBlend.alphaToOneEnable = p.alphaToOneEnable; - m_VulkanPipelineState.colorBlend.blends.resize(p.attachments.size()); + ret.colorBlend.blends.resize(p.attachments.size()); for(size_t i = 0; i < p.attachments.size(); i++) { - m_VulkanPipelineState.colorBlend.blends[i].enabled = p.attachments[i].blendEnable; + ret.colorBlend.blends[i].enabled = p.attachments[i].blendEnable; // due to shared structs, this is slightly duplicated - Vulkan doesn't have separate states // for logic operations - m_VulkanPipelineState.colorBlend.blends[i].logicOperationEnabled = p.logicOpEnable; - m_VulkanPipelineState.colorBlend.blends[i].logicOperation = MakeLogicOp(p.logicOp); + ret.colorBlend.blends[i].logicOperationEnabled = p.logicOpEnable; + ret.colorBlend.blends[i].logicOperation = MakeLogicOp(p.logicOp); - m_VulkanPipelineState.colorBlend.blends[i].colorBlend.source = - MakeBlendMultiplier(p.attachments[i].blend.Source); - m_VulkanPipelineState.colorBlend.blends[i].colorBlend.destination = + ret.colorBlend.blends[i].colorBlend.source = MakeBlendMultiplier(p.attachments[i].blend.Source); + ret.colorBlend.blends[i].colorBlend.destination = MakeBlendMultiplier(p.attachments[i].blend.Destination); - m_VulkanPipelineState.colorBlend.blends[i].colorBlend.operation = - MakeBlendOp(p.attachments[i].blend.Operation); + ret.colorBlend.blends[i].colorBlend.operation = MakeBlendOp(p.attachments[i].blend.Operation); - m_VulkanPipelineState.colorBlend.blends[i].alphaBlend.source = + ret.colorBlend.blends[i].alphaBlend.source = MakeBlendMultiplier(p.attachments[i].alphaBlend.Source); - m_VulkanPipelineState.colorBlend.blends[i].alphaBlend.destination = + ret.colorBlend.blends[i].alphaBlend.destination = MakeBlendMultiplier(p.attachments[i].alphaBlend.Destination); - m_VulkanPipelineState.colorBlend.blends[i].alphaBlend.operation = + ret.colorBlend.blends[i].alphaBlend.operation = MakeBlendOp(p.attachments[i].alphaBlend.Operation); - m_VulkanPipelineState.colorBlend.blends[i].writeMask = p.attachments[i].channelWriteMask; + ret.colorBlend.blends[i].writeMask = p.attachments[i].channelWriteMask; } - m_VulkanPipelineState.colorBlend.blendFactor = state.blendConst; + ret.colorBlend.blendFactor = state.blendConst; // Depth Stencil - m_VulkanPipelineState.depthStencil.depthTestEnable = state.depthTestEnable != VK_FALSE; - m_VulkanPipelineState.depthStencil.depthWriteEnable = state.depthWriteEnable != VK_FALSE; - m_VulkanPipelineState.depthStencil.depthBoundsEnable = state.depthBoundsTestEnable != VK_FALSE; - m_VulkanPipelineState.depthStencil.depthFunction = MakeCompareFunc(state.depthCompareOp); - m_VulkanPipelineState.depthStencil.stencilTestEnable = state.stencilTestEnable != VK_FALSE; + ret.depthStencil.depthTestEnable = state.depthTestEnable != VK_FALSE; + ret.depthStencil.depthWriteEnable = state.depthWriteEnable != VK_FALSE; + ret.depthStencil.depthBoundsEnable = state.depthBoundsTestEnable != VK_FALSE; + ret.depthStencil.depthFunction = MakeCompareFunc(state.depthCompareOp); + ret.depthStencil.stencilTestEnable = state.stencilTestEnable != VK_FALSE; - m_VulkanPipelineState.depthStencil.frontFace.passOperation = MakeStencilOp(state.front.passOp); - m_VulkanPipelineState.depthStencil.frontFace.failOperation = MakeStencilOp(state.front.failOp); - m_VulkanPipelineState.depthStencil.frontFace.depthFailOperation = - MakeStencilOp(state.front.depthFailOp); - m_VulkanPipelineState.depthStencil.frontFace.function = MakeCompareFunc(state.front.compareOp); + ret.depthStencil.frontFace.passOperation = MakeStencilOp(state.front.passOp); + ret.depthStencil.frontFace.failOperation = MakeStencilOp(state.front.failOp); + ret.depthStencil.frontFace.depthFailOperation = MakeStencilOp(state.front.depthFailOp); + ret.depthStencil.frontFace.function = MakeCompareFunc(state.front.compareOp); - m_VulkanPipelineState.depthStencil.backFace.passOperation = MakeStencilOp(state.back.passOp); - m_VulkanPipelineState.depthStencil.backFace.failOperation = MakeStencilOp(state.back.failOp); - m_VulkanPipelineState.depthStencil.backFace.depthFailOperation = - MakeStencilOp(state.back.depthFailOp); - m_VulkanPipelineState.depthStencil.backFace.function = MakeCompareFunc(state.back.compareOp); + ret.depthStencil.backFace.passOperation = MakeStencilOp(state.back.passOp); + ret.depthStencil.backFace.failOperation = MakeStencilOp(state.back.failOp); + ret.depthStencil.backFace.depthFailOperation = MakeStencilOp(state.back.depthFailOp); + ret.depthStencil.backFace.function = MakeCompareFunc(state.back.compareOp); - m_VulkanPipelineState.depthStencil.minDepthBounds = state.mindepth; - m_VulkanPipelineState.depthStencil.maxDepthBounds = state.maxdepth; + ret.depthStencil.minDepthBounds = state.mindepth; + ret.depthStencil.maxDepthBounds = state.maxdepth; - m_VulkanPipelineState.depthStencil.frontFace.reference = state.front.ref; - m_VulkanPipelineState.depthStencil.frontFace.compareMask = state.front.compare; - m_VulkanPipelineState.depthStencil.frontFace.writeMask = state.front.write; + ret.depthStencil.frontFace.reference = state.front.ref; + ret.depthStencil.frontFace.compareMask = state.front.compare; + ret.depthStencil.frontFace.writeMask = state.front.write; - m_VulkanPipelineState.depthStencil.backFace.reference = state.back.ref; - m_VulkanPipelineState.depthStencil.backFace.compareMask = state.back.compare; - m_VulkanPipelineState.depthStencil.backFace.writeMask = state.back.write; + ret.depthStencil.backFace.reference = state.back.ref; + ret.depthStencil.backFace.compareMask = state.back.compare; + ret.depthStencil.backFace.writeMask = state.back.write; } else { - m_VulkanPipelineState.graphics.pipelineLayoutResourceId = ResourceId(); + ret.graphics.pipelineLayoutResourceId = ResourceId(); - m_VulkanPipelineState.graphics.flags = 0; + ret.graphics.flags = 0; - m_VulkanPipelineState.vertexInput.attributes.clear(); - m_VulkanPipelineState.vertexInput.bindings.clear(); - m_VulkanPipelineState.vertexInput.vertexBuffers.clear(); + ret.vertexInput.attributes.clear(); + ret.vertexInput.bindings.clear(); + ret.vertexInput.vertexBuffers.clear(); VKPipe::Shader *stages[] = { - &m_VulkanPipelineState.vertexShader, &m_VulkanPipelineState.tessControlShader, - &m_VulkanPipelineState.tessEvalShader, &m_VulkanPipelineState.geometryShader, - &m_VulkanPipelineState.fragmentShader, + &ret.vertexShader, &ret.tessControlShader, &ret.tessEvalShader, + &ret.geometryShader, &ret.fragmentShader, }; for(size_t i = 0; i < ARRAY_COUNT(stages); i++) *stages[i] = VKPipe::Shader(); - m_VulkanPipelineState.viewportScissor.viewportScissors.clear(); - m_VulkanPipelineState.viewportScissor.discardRectangles.clear(); - m_VulkanPipelineState.viewportScissor.discardRectanglesExclusive = true; + ret.viewportScissor.viewportScissors.clear(); + ret.viewportScissor.discardRectangles.clear(); + ret.viewportScissor.discardRectanglesExclusive = true; - m_VulkanPipelineState.colorBlend.blends.clear(); + ret.colorBlend.blends.clear(); } if(state.renderPass != ResourceId()) { // Renderpass - m_VulkanPipelineState.currentPass.renderpass.resourceId = rm->GetOriginalID(state.renderPass); - m_VulkanPipelineState.currentPass.renderpass.subpass = state.subpass; + ret.currentPass.renderpass.resourceId = rm->GetOriginalID(state.renderPass); + ret.currentPass.renderpass.subpass = state.subpass; if(state.renderPass != ResourceId()) { - m_VulkanPipelineState.currentPass.renderpass.inputAttachments = + ret.currentPass.renderpass.inputAttachments = c.m_RenderPass[state.renderPass].subpasses[state.subpass].inputAttachments; - m_VulkanPipelineState.currentPass.renderpass.colorAttachments = + ret.currentPass.renderpass.colorAttachments = c.m_RenderPass[state.renderPass].subpasses[state.subpass].colorAttachments; - m_VulkanPipelineState.currentPass.renderpass.resolveAttachments = + ret.currentPass.renderpass.resolveAttachments = c.m_RenderPass[state.renderPass].subpasses[state.subpass].resolveAttachments; - m_VulkanPipelineState.currentPass.renderpass.depthstencilAttachment = + ret.currentPass.renderpass.depthstencilAttachment = c.m_RenderPass[state.renderPass].subpasses[state.subpass].depthstencilAttachment; - m_VulkanPipelineState.currentPass.renderpass.fragmentDensityAttachment = + ret.currentPass.renderpass.fragmentDensityAttachment = c.m_RenderPass[state.renderPass].subpasses[state.subpass].fragmentDensityAttachment; - m_VulkanPipelineState.currentPass.renderpass.multiviews = + ret.currentPass.renderpass.multiviews = c.m_RenderPass[state.renderPass].subpasses[state.subpass].multiviews; } ResourceId fb = state.GetFramebuffer(); - m_VulkanPipelineState.currentPass.framebuffer.resourceId = rm->GetOriginalID(fb); + ret.currentPass.framebuffer.resourceId = rm->GetOriginalID(fb); if(fb != ResourceId()) { - m_VulkanPipelineState.currentPass.framebuffer.width = c.m_Framebuffer[fb].width; - m_VulkanPipelineState.currentPass.framebuffer.height = c.m_Framebuffer[fb].height; - m_VulkanPipelineState.currentPass.framebuffer.layers = c.m_Framebuffer[fb].layers; + ret.currentPass.framebuffer.width = c.m_Framebuffer[fb].width; + ret.currentPass.framebuffer.height = c.m_Framebuffer[fb].height; + ret.currentPass.framebuffer.layers = c.m_Framebuffer[fb].layers; - m_VulkanPipelineState.currentPass.framebuffer.attachments.resize( - c.m_Framebuffer[fb].attachments.size()); + ret.currentPass.framebuffer.attachments.resize(c.m_Framebuffer[fb].attachments.size()); for(size_t i = 0; i < c.m_Framebuffer[fb].attachments.size(); i++) { ResourceId viewid = state.GetFramebufferAttachments()[i]; if(viewid != ResourceId()) { - m_VulkanPipelineState.currentPass.framebuffer.attachments[i].viewResourceId = - rm->GetOriginalID(viewid); - m_VulkanPipelineState.currentPass.framebuffer.attachments[i].imageResourceId = + ret.currentPass.framebuffer.attachments[i].viewResourceId = rm->GetOriginalID(viewid); + ret.currentPass.framebuffer.attachments[i].imageResourceId = rm->GetOriginalID(c.m_ImageView[viewid].image); - m_VulkanPipelineState.currentPass.framebuffer.attachments[i].viewFormat = + ret.currentPass.framebuffer.attachments[i].viewFormat = MakeResourceFormat(c.m_ImageView[viewid].format); - m_VulkanPipelineState.currentPass.framebuffer.attachments[i].firstMip = + ret.currentPass.framebuffer.attachments[i].firstMip = c.m_ImageView[viewid].range.baseMipLevel; - m_VulkanPipelineState.currentPass.framebuffer.attachments[i].firstSlice = + ret.currentPass.framebuffer.attachments[i].firstSlice = c.m_ImageView[viewid].range.baseArrayLayer; - m_VulkanPipelineState.currentPass.framebuffer.attachments[i].numMips = - c.m_ImageView[viewid].range.levelCount; - m_VulkanPipelineState.currentPass.framebuffer.attachments[i].numSlices = + ret.currentPass.framebuffer.attachments[i].numMips = c.m_ImageView[viewid].range.levelCount; + ret.currentPass.framebuffer.attachments[i].numSlices = c.m_ImageView[viewid].range.layerCount; - Convert(m_VulkanPipelineState.currentPass.framebuffer.attachments[i].swizzle, + Convert(ret.currentPass.framebuffer.attachments[i].swizzle, c.m_ImageView[viewid].componentMapping); } else { - m_VulkanPipelineState.currentPass.framebuffer.attachments[i].viewResourceId = ResourceId(); - m_VulkanPipelineState.currentPass.framebuffer.attachments[i].imageResourceId = ResourceId(); + ret.currentPass.framebuffer.attachments[i].viewResourceId = ResourceId(); + ret.currentPass.framebuffer.attachments[i].imageResourceId = ResourceId(); - m_VulkanPipelineState.currentPass.framebuffer.attachments[i].firstMip = 0; - m_VulkanPipelineState.currentPass.framebuffer.attachments[i].firstSlice = 0; - m_VulkanPipelineState.currentPass.framebuffer.attachments[i].numMips = 1; - m_VulkanPipelineState.currentPass.framebuffer.attachments[i].numSlices = 1; + ret.currentPass.framebuffer.attachments[i].firstMip = 0; + ret.currentPass.framebuffer.attachments[i].firstSlice = 0; + ret.currentPass.framebuffer.attachments[i].numMips = 1; + ret.currentPass.framebuffer.attachments[i].numSlices = 1; } } } else { - m_VulkanPipelineState.currentPass.framebuffer.width = 0; - m_VulkanPipelineState.currentPass.framebuffer.height = 0; - m_VulkanPipelineState.currentPass.framebuffer.layers = 0; + ret.currentPass.framebuffer.width = 0; + ret.currentPass.framebuffer.height = 0; + ret.currentPass.framebuffer.layers = 0; } - m_VulkanPipelineState.currentPass.renderArea.x = state.renderArea.offset.x; - m_VulkanPipelineState.currentPass.renderArea.y = state.renderArea.offset.y; - m_VulkanPipelineState.currentPass.renderArea.width = state.renderArea.extent.width; - m_VulkanPipelineState.currentPass.renderArea.height = state.renderArea.extent.height; + ret.currentPass.renderArea.x = state.renderArea.offset.x; + ret.currentPass.renderArea.y = state.renderArea.offset.y; + ret.currentPass.renderArea.width = state.renderArea.extent.width; + ret.currentPass.renderArea.height = state.renderArea.extent.height; } else { - m_VulkanPipelineState.currentPass.renderpass.resourceId = ResourceId(); - m_VulkanPipelineState.currentPass.renderpass.subpass = 0; - m_VulkanPipelineState.currentPass.renderpass.inputAttachments.clear(); - m_VulkanPipelineState.currentPass.renderpass.colorAttachments.clear(); - m_VulkanPipelineState.currentPass.renderpass.resolveAttachments.clear(); - m_VulkanPipelineState.currentPass.renderpass.depthstencilAttachment = -1; - m_VulkanPipelineState.currentPass.renderpass.fragmentDensityAttachment = -1; + ret.currentPass.renderpass.resourceId = ResourceId(); + ret.currentPass.renderpass.subpass = 0; + ret.currentPass.renderpass.inputAttachments.clear(); + ret.currentPass.renderpass.colorAttachments.clear(); + ret.currentPass.renderpass.resolveAttachments.clear(); + ret.currentPass.renderpass.depthstencilAttachment = -1; + ret.currentPass.renderpass.fragmentDensityAttachment = -1; - m_VulkanPipelineState.currentPass.framebuffer.resourceId = ResourceId(); - m_VulkanPipelineState.currentPass.framebuffer.attachments.clear(); + ret.currentPass.framebuffer.resourceId = ResourceId(); + ret.currentPass.framebuffer.attachments.clear(); } // Descriptor sets - m_VulkanPipelineState.graphics.descriptorSets.resize(state.graphics.descSets.size()); - m_VulkanPipelineState.compute.descriptorSets.resize(state.compute.descSets.size()); + ret.graphics.descriptorSets.resize(state.graphics.descSets.size()); + ret.compute.descriptorSets.resize(state.compute.descSets.size()); { rdcarray *dsts[] = { - &m_VulkanPipelineState.graphics.descriptorSets, &m_VulkanPipelineState.compute.descriptorSets, + &ret.graphics.descriptorSets, &ret.compute.descriptorSets, }; const rdcarray *srcs[] = { @@ -1625,7 +1587,7 @@ void VulkanReplay::SavePipelineState(uint32_t eventId) const VKDynamicShaderFeedback &usage = m_BindlessFeedback.Usage[eventId]; - m_VulkanPipelineState.shaderMessages = usage.messages; + ret.shaderMessages = usage.messages; for(size_t p = 0; p < ARRAY_COUNT(srcs); p++) { @@ -1978,10 +1940,10 @@ void VulkanReplay::SavePipelineState(uint32_t eventId) // image layouts { size_t i = 0; - m_VulkanPipelineState.images.resize(m_pDriver->m_ImageStates.size()); + ret.images.resize(m_pDriver->m_ImageStates.size()); for(auto it = m_pDriver->m_ImageStates.begin(); it != m_pDriver->m_ImageStates.end(); ++it) { - VKPipe::ImageData &img = m_VulkanPipelineState.images[i]; + VKPipe::ImageData &img = ret.images[i]; if(rm->GetOriginalID(it->first) == it->first) continue; @@ -2009,15 +1971,14 @@ void VulkanReplay::SavePipelineState(uint32_t eventId) i++; } - m_VulkanPipelineState.images.resize(i); + ret.images.resize(i); } if(state.conditionalRendering.buffer != ResourceId()) { - m_VulkanPipelineState.conditionalRendering.bufferId = - rm->GetOriginalID(state.conditionalRendering.buffer); - m_VulkanPipelineState.conditionalRendering.byteOffset = state.conditionalRendering.offset; - m_VulkanPipelineState.conditionalRendering.isInverted = + ret.conditionalRendering.bufferId = rm->GetOriginalID(state.conditionalRendering.buffer); + ret.conditionalRendering.byteOffset = state.conditionalRendering.offset; + ret.conditionalRendering.isInverted = state.conditionalRendering.flags == VK_CONDITIONAL_RENDERING_INVERTED_BIT_EXT; bytebuf data; @@ -2027,11 +1988,10 @@ void VulkanReplay::SavePipelineState(uint32_t eventId) uint32_t value; memcpy(&value, data.data(), sizeof(uint32_t)); - m_VulkanPipelineState.conditionalRendering.isPassing = value != 0; + ret.conditionalRendering.isPassing = value != 0; - if(m_VulkanPipelineState.conditionalRendering.isInverted) - m_VulkanPipelineState.conditionalRendering.isPassing = - !m_VulkanPipelineState.conditionalRendering.isPassing; + if(ret.conditionalRendering.isInverted) + ret.conditionalRendering.isPassing = !ret.conditionalRendering.isPassing; } } diff --git a/renderdoc/driver/vulkan/vk_replay.h b/renderdoc/driver/vulkan/vk_replay.h index 337d940f4..1c8ffb583 100644 --- a/renderdoc/driver/vulkan/vk_replay.h +++ b/renderdoc/driver/vulkan/vk_replay.h @@ -296,11 +296,12 @@ public: FrameRecord GetFrameRecord() { return m_FrameRecord; } rdcarray GetDebugMessages(); + void SetPipelineStates(D3D11Pipe::State *d3d11, D3D12Pipe::State *d3d12, GLPipe::State *gl, + VKPipe::State *vk) + { + m_VulkanPipelineState = vk; + } void SavePipelineState(uint32_t eventId); - const D3D11Pipe::State *GetD3D11PipelineState() { return NULL; } - const D3D12Pipe::State *GetD3D12PipelineState() { return NULL; } - const GLPipe::State *GetGLPipelineState() { return NULL; } - const VKPipe::State *GetVulkanPipelineState() { return &m_VulkanPipelineState; } void FreeTargetResource(ResourceId id); ReplayStatus ReadLogInitialisation(RDCFile *rdc, bool storeStructuredBuffers); @@ -752,7 +753,7 @@ private: rdcarray m_Resources; std::map m_ResourceIdx; - VKPipe::State m_VulkanPipelineState; + VKPipe::State *m_VulkanPipelineState = NULL; DriverInformation m_DriverInfo; diff --git a/renderdoc/replay/replay_controller.cpp b/renderdoc/replay/replay_controller.cpp index f8ad0e31f..969138562 100644 --- a/renderdoc/replay/replay_controller.cpp +++ b/renderdoc/replay/replay_controller.cpp @@ -53,11 +53,6 @@ ReplayController::ReplayController() m_EventID = 100000; - m_D3D11PipelineState = NULL; - m_D3D12PipelineState = NULL; - m_GLPipelineState = NULL; - m_VulkanPipelineState = NULL; - if(RenderDoc::Inst().GetCrashHandler()) RenderDoc::Inst().GetCrashHandler()->RegisterMemoryRegion(this, sizeof(ReplayController)); } @@ -96,28 +91,28 @@ const D3D11Pipe::State *ReplayController::GetD3D11PipelineState() { CHECK_REPLAY_THREAD(); - return m_D3D11PipelineState; + return m_APIProps.pipelineType == GraphicsAPI::D3D11 ? &m_D3D11PipelineState : NULL; } const D3D12Pipe::State *ReplayController::GetD3D12PipelineState() { CHECK_REPLAY_THREAD(); - return m_D3D12PipelineState; + return m_APIProps.pipelineType == GraphicsAPI::D3D12 ? &m_D3D12PipelineState : NULL; } const GLPipe::State *ReplayController::GetGLPipelineState() { CHECK_REPLAY_THREAD(); - return m_GLPipelineState; + return m_APIProps.pipelineType == GraphicsAPI::OpenGL ? &m_GLPipelineState : NULL; } const VKPipe::State *ReplayController::GetVulkanPipelineState() { CHECK_REPLAY_THREAD(); - return m_VulkanPipelineState; + return m_APIProps.pipelineType == GraphicsAPI::Vulkan ? &m_VulkanPipelineState : NULL; } const PipeState &ReplayController::GetPipelineState() @@ -471,8 +466,8 @@ rdcarray ReplayController::GetShaderEntryPoints(ResourceId sha return m_pDevice->GetShaderEntryPoints(m_pDevice->GetLiveID(shader)); } -ShaderReflection *ReplayController::GetShader(ResourceId pipeline, ResourceId shader, - ShaderEntryPoint entry) +const ShaderReflection *ReplayController::GetShader(ResourceId pipeline, ResourceId shader, + ShaderEntryPoint entry) { CHECK_REPLAY_THREAD(); @@ -2060,6 +2055,9 @@ ReplayStatus ReplayController::PostCreateInit(IReplayDriver *device, RDCFile *rd ReplayStatus status = m_pDevice->ReadLogInitialisation(rdc, false); + m_pDevice->SetPipelineStates(&m_D3D11PipelineState, &m_D3D12PipelineState, &m_GLPipelineState, + &m_VulkanPipelineState); + GCNISA::GetTargets(m_APIProps.pipelineType, m_GCNTargets); if(status != ReplayStatus::Succeeded) @@ -2104,11 +2102,12 @@ void ReplayController::FetchPipelineState(uint32_t eventId) m_pDevice->SavePipelineState(eventId); - m_D3D11PipelineState = m_pDevice->GetD3D11PipelineState(); - m_D3D12PipelineState = m_pDevice->GetD3D12PipelineState(); - m_GLPipelineState = m_pDevice->GetGLPipelineState(); - m_VulkanPipelineState = m_pDevice->GetVulkanPipelineState(); - - m_PipeState.SetStates(m_APIProps, m_D3D11PipelineState, m_D3D12PipelineState, m_GLPipelineState, - m_VulkanPipelineState); + if(m_APIProps.pipelineType == GraphicsAPI::D3D11) + m_PipeState.SetState(&m_D3D11PipelineState); + else if(m_APIProps.pipelineType == GraphicsAPI::D3D12) + m_PipeState.SetState(&m_D3D12PipelineState); + else if(m_APIProps.pipelineType == GraphicsAPI::OpenGL) + m_PipeState.SetState(&m_GLPipelineState); + else if(m_APIProps.pipelineType == GraphicsAPI::Vulkan) + m_PipeState.SetState(&m_VulkanPipelineState); } diff --git a/renderdoc/replay/replay_controller.h b/renderdoc/replay/replay_controller.h index b49119ac5..43f07cb34 100644 --- a/renderdoc/replay/replay_controller.h +++ b/renderdoc/replay/replay_controller.h @@ -175,7 +175,7 @@ public: rdcarray GetDebugMessages(); rdcarray GetShaderEntryPoints(ResourceId shader); - ShaderReflection *GetShader(ResourceId pipeline, ResourceId shader, ShaderEntryPoint entry); + const ShaderReflection *GetShader(ResourceId pipeline, ResourceId shader, ShaderEntryPoint entry); PixelValue PickPixel(ResourceId textureId, uint32_t x, uint32_t y, const Subresource &sub, CompType typeCast); @@ -244,10 +244,10 @@ private: std::map m_EventRemap; - const D3D11Pipe::State *m_D3D11PipelineState; - const D3D12Pipe::State *m_D3D12PipelineState; - const GLPipe::State *m_GLPipelineState; - const VKPipe::State *m_VulkanPipelineState; + D3D11Pipe::State m_D3D11PipelineState; + D3D12Pipe::State m_D3D12PipelineState; + GLPipe::State m_GLPipelineState; + VKPipe::State m_VulkanPipelineState; PipeState m_PipeState; rdcarray m_Outputs; diff --git a/renderdoc/replay/replay_driver.h b/renderdoc/replay/replay_driver.h index b8e8181f1..bc14b2edd 100644 --- a/renderdoc/replay/replay_driver.h +++ b/renderdoc/replay/replay_driver.h @@ -154,11 +154,9 @@ public: virtual rdcarray GetUsage(ResourceId id) = 0; + virtual void SetPipelineStates(D3D11Pipe::State *d3d11, D3D12Pipe::State *d3d12, + GLPipe::State *gl, VKPipe::State *vk) = 0; virtual void SavePipelineState(uint32_t eventId) = 0; - virtual const D3D11Pipe::State *GetD3D11PipelineState() = 0; - virtual const D3D12Pipe::State *GetD3D12PipelineState() = 0; - virtual const GLPipe::State *GetGLPipelineState() = 0; - virtual const VKPipe::State *GetVulkanPipelineState() = 0; virtual FrameRecord GetFrameRecord() = 0;