diff --git a/renderdoc/driver/vulkan/Makefile b/renderdoc/driver/vulkan/Makefile index 0c36536cf..f6c397264 100644 --- a/renderdoc/driver/vulkan/Makefile +++ b/renderdoc/driver/vulkan/Makefile @@ -19,6 +19,7 @@ vk_resources.o \ vk_debug.o \ vk_replay.o \ vk_info.o \ +vk_state.o \ vk_linux.o \ wrappers/vk_cmd_funcs.o \ wrappers/vk_dynamic_funcs.o \ diff --git a/renderdoc/driver/vulkan/renderdoc_vulkan.vcxproj b/renderdoc/driver/vulkan/renderdoc_vulkan.vcxproj index fdf1c28e1..b63c51f2c 100644 --- a/renderdoc/driver/vulkan/renderdoc_vulkan.vcxproj +++ b/renderdoc/driver/vulkan/renderdoc_vulkan.vcxproj @@ -22,6 +22,7 @@ + @@ -67,6 +68,7 @@ + diff --git a/renderdoc/driver/vulkan/renderdoc_vulkan.vcxproj.filters b/renderdoc/driver/vulkan/renderdoc_vulkan.vcxproj.filters index a61cd932d..cbeef41e3 100644 --- a/renderdoc/driver/vulkan/renderdoc_vulkan.vcxproj.filters +++ b/renderdoc/driver/vulkan/renderdoc_vulkan.vcxproj.filters @@ -76,6 +76,9 @@ Wrappers + + Util + @@ -105,6 +108,9 @@ Core + + Util + diff --git a/renderdoc/driver/vulkan/vk_core.cpp b/renderdoc/driver/vulkan/vk_core.cpp index 7704759f4..51790a48e 100644 --- a/renderdoc/driver/vulkan/vk_core.cpp +++ b/renderdoc/driver/vulkan/vk_core.cpp @@ -241,6 +241,7 @@ void VkInitParams::Set(const VkInstanceCreateInfo* pCreateInfo, ResourceId inst) } WrappedVulkan::WrappedVulkan(const char *logFilename) + : m_RenderState(m_CreationInfo) { #if defined(RELEASE) const bool debugSerialiser = false; @@ -285,8 +286,6 @@ WrappedVulkan::WrappedVulkan(const char *logFilename) m_FirstEventID = 0; m_LastEventID = ~0U; - m_HackDrawIndices = ~0U; - m_LastCmdBufferID = ResourceId(); m_PartialReplayData.renderPassActive = false; @@ -300,6 +299,7 @@ WrappedVulkan::WrappedVulkan(const char *logFilename) m_ResourceManager = new VulkanResourceManager(m_State, m_pSerialiser, this); m_pSerialiser->SetUserData(m_ResourceManager); + m_RenderState.m_ResourceManager = GetResourceManager(); m_HeaderChunk = NULL; @@ -1736,7 +1736,8 @@ void WrappedVulkan::ReplayLog(uint32_t frameID, uint32_t startEventID, uint32_t RDCASSERT(m_PartialReplayData.resultPartialCmdBuffer == VK_NULL_HANDLE); m_PartialReplayData.partialParent = ResourceId(); m_PartialReplayData.baseEvent = 0; - m_PartialReplayData.state = PartialReplayData::StateVector(); + m_RenderState = VulkanRenderState(m_CreationInfo); + m_RenderState.m_ResourceManager = GetResourceManager(); } if(replayType == eReplay_Full) @@ -1755,124 +1756,23 @@ void WrappedVulkan::ReplayLog(uint32_t frameID, uint32_t startEventID, uint32_t VkResult vkr = ObjDisp(cmd)->BeginCommandBuffer(Unwrap(cmd), &beginInfo); RDCASSERT(vkr == VK_SUCCESS); + + bool rpWasActive = m_PartialReplayData.renderPassActive; // if a render pass was active, begin it and set up the partial replay state if(m_PartialReplayData.renderPassActive) - { - auto &s = m_PartialReplayData.state; - - RDCASSERT(s.renderPass != ResourceId()); - - // clear values don't matter as we're using the load renderpass here, that - // has all load ops set to load (as we're doing a partial replay - can't - // just clear the targets that are partially written to). - - VkClearValue empty[16] = {0}; - - RDCASSERT(ARRAY_COUNT(empty) >= m_CreationInfo.m_RenderPass[s.renderPass].attachments.size()); - - VkRenderPassBeginInfo rpbegin = { - VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, NULL, - Unwrap(m_CreationInfo.m_RenderPass[s.renderPass].loadRP), - Unwrap(GetResourceManager()->GetCurrentHandle(s.framebuffer)), - s.renderArea, - (uint32_t)m_CreationInfo.m_RenderPass[s.renderPass].attachments.size(), empty, - }; - ObjDisp(cmd)->CmdBeginRenderPass(Unwrap(cmd), &rpbegin, VK_RENDER_PASS_CONTENTS_INLINE); - - for(uint32_t i=0; i < s.subpass; i++) - ObjDisp(cmd)->CmdNextSubpass(Unwrap(cmd), VK_RENDER_PASS_CONTENTS_INLINE); - - if(s.graphics.pipeline != ResourceId()) - { - ObjDisp(cmd)->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(GetResourceManager()->GetCurrentHandle(s.graphics.pipeline))); - - ResourceId pipeLayoutId = m_CreationInfo.m_Pipeline[s.graphics.pipeline].layout; - VkPipelineLayout layout = GetResourceManager()->GetCurrentHandle(pipeLayoutId); - - const vector &pushRanges = m_CreationInfo.m_PipelineLayout[pipeLayoutId].pushRanges; - - // only set push constant ranges that the layout uses - for(size_t i=0; i < pushRanges.size(); i++) - ObjDisp(cmd)->CmdPushConstants(Unwrap(cmd), Unwrap(layout), pushRanges[i].stageFlags, pushRanges[i].start, pushRanges[i].length, s.pushconsts+pushRanges[i].start); - - const vector &descSetLayouts = m_CreationInfo.m_PipelineLayout[pipeLayoutId].descSetLayouts; - - // only iterate over the desc sets that this layout actually uses, not all that were bound - for(size_t i=0; i < descSetLayouts.size(); i++) - { - const DescSetLayout &descLayout = m_CreationInfo.m_DescSetLayout[ descSetLayouts[i] ]; - - if(i < s.graphics.descSets.size() && s.graphics.descSets[i] != ResourceId()) - { - // if there are dynamic buffers, pass along the offsets - ObjDisp(cmd)->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(layout), (uint32_t)i, - 1, UnwrapPtr(GetResourceManager()->GetCurrentHandle(s.graphics.descSets[i])), - descLayout.dynamicCount, descLayout.dynamicCount == 0 ? NULL : &s.graphics.offsets[i][0]); - } - else - { - RDCWARN("Descriptor set is not bound but pipeline layout expects one"); - } - } - } - - if(s.compute.pipeline != ResourceId()) - { - ObjDisp(cmd)->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, Unwrap(GetResourceManager()->GetCurrentHandle(s.compute.pipeline))); - - ResourceId pipeLayoutId = m_CreationInfo.m_Pipeline[s.compute.pipeline].layout; - VkPipelineLayout layout = GetResourceManager()->GetCurrentHandle(pipeLayoutId); - - const vector &descSetLayouts = m_CreationInfo.m_PipelineLayout[pipeLayoutId].descSetLayouts; - - for(size_t i=0; i < descSetLayouts.size(); i++) - { - const DescSetLayout &descLayout = m_CreationInfo.m_DescSetLayout[ descSetLayouts[i] ]; - - if(s.compute.descSets[i] != ResourceId()) - { - ObjDisp(cmd)->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(layout), (uint32_t)i, - 1, UnwrapPtr(GetResourceManager()->GetCurrentHandle(s.compute.descSets[i])), - descLayout.dynamicCount, descLayout.dynamicCount == 0 ? NULL : &s.compute.offsets[i][0]); - } - } - } - - if(!s.views.empty()) - ObjDisp(cmd)->CmdSetViewport(Unwrap(cmd), (uint32_t)s.views.size(), &s.views[0]); - if(!s.scissors.empty()) - ObjDisp(cmd)->CmdSetScissor(Unwrap(cmd), (uint32_t)s.scissors.size(), &s.scissors[0]); - - ObjDisp(cmd)->CmdSetBlendConstants(Unwrap(cmd), s.blendConst); - ObjDisp(cmd)->CmdSetDepthBounds(Unwrap(cmd), s.mindepth, s.maxdepth); - ObjDisp(cmd)->CmdSetLineWidth(Unwrap(cmd), s.lineWidth); - ObjDisp(cmd)->CmdSetDepthBias(Unwrap(cmd), s.bias.depth, s.bias.biasclamp, s.bias.slope); - - ObjDisp(cmd)->CmdSetStencilReference(Unwrap(cmd), VK_STENCIL_FACE_BACK_BIT, s.back.ref); - ObjDisp(cmd)->CmdSetStencilCompareMask(Unwrap(cmd), VK_STENCIL_FACE_BACK_BIT, s.back.compare); - ObjDisp(cmd)->CmdSetStencilWriteMask(Unwrap(cmd), VK_STENCIL_FACE_BACK_BIT, s.back.write); - - ObjDisp(cmd)->CmdSetStencilReference(Unwrap(cmd), VK_STENCIL_FACE_FRONT_BIT, s.front.ref); - ObjDisp(cmd)->CmdSetStencilCompareMask(Unwrap(cmd), VK_STENCIL_FACE_FRONT_BIT, s.front.compare); - ObjDisp(cmd)->CmdSetStencilWriteMask(Unwrap(cmd), VK_STENCIL_FACE_FRONT_BIT, s.front.write); - - if(s.ibuffer.buf != ResourceId()) - ObjDisp(cmd)->CmdBindIndexBuffer(Unwrap(cmd), Unwrap(GetResourceManager()->GetCurrentHandle(s.ibuffer.buf)), s.ibuffer.offs, s.ibuffer.bytewidth == 4 ? VK_INDEX_TYPE_UINT32 : VK_INDEX_TYPE_UINT16); - - for(size_t i=0; i < s.vbuffers.size(); i++) - ObjDisp(cmd)->CmdBindVertexBuffers(Unwrap(cmd), (uint32_t)i, 1, UnwrapPtr(GetResourceManager()->GetCurrentHandle(s.vbuffers[i].buf)), &s.vbuffers[i].offs); - } - - bool rpWasActive = m_PartialReplayData.renderPassActive; + m_RenderState.BeginRenderPassAndApplyState(cmd); ContextReplayLog(EXECUTING, endEventID, endEventID, partial); + // check if the render pass is active - it could have become active + // even if it wasn't before (if the above event was a CmdBeginRenderPass) if(m_PartialReplayData.renderPassActive) ObjDisp(cmd)->CmdEndRenderPass(Unwrap(cmd)); // we might have replayed a CmdBeginRenderPass or CmdEndRenderPass, - // but we want to keep the partial replay data state intact. + // but we want to keep the partial replay data state intact, so restore + // whether or not a render pass was active. m_PartialReplayData.renderPassActive = rpWasActive; ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd)); @@ -1912,13 +1812,13 @@ void WrappedVulkan::AddDrawcall(FetchDrawcall d, bool hasEvents) draw.depthOut = ResourceId(); - ResourceId pipe = m_PartialReplayData.state.graphics.pipeline; + ResourceId pipe = m_RenderState.graphics.pipeline; if(pipe != ResourceId()) draw.topology = MakePrimitiveTopology(m_CreationInfo.m_Pipeline[pipe].topology, m_CreationInfo.m_Pipeline[pipe].patchControlPoints); else draw.topology = eTopology_Unknown; - draw.indexByteWidth = m_PartialReplayData.state.ibuffer.bytewidth; + draw.indexByteWidth = m_RenderState.ibuffer.bytewidth; if(m_LastCmdBufferID != ResourceId()) m_BakedCmdBufferInfo[m_LastCmdBufferID].drawCount++; diff --git a/renderdoc/driver/vulkan/vk_core.h b/renderdoc/driver/vulkan/vk_core.h index fbe4d6634..e29765d64 100644 --- a/renderdoc/driver/vulkan/vk_core.h +++ b/renderdoc/driver/vulkan/vk_core.h @@ -33,6 +33,7 @@ #include "vk_common.h" #include "vk_info.h" +#include "vk_state.h" #include "vk_manager.h" #include "vk_replay.h" @@ -304,75 +305,12 @@ private: // reach the vkEndCommandBuffer that we also need to end a render // pass. bool renderPassActive; - - // There is only a state while currently partially replaying, it's - // undefined/empty otherwise. - // All IDs are original IDs, not live. - struct StateVector - { - StateVector() - { - compute.pipeline = graphics.pipeline = renderPass = framebuffer = ResourceId(); - compute.descSets.clear(); - graphics.descSets.clear(); - compute.offsets.clear(); - graphics.offsets.clear(); - - lineWidth = 1.0f; - RDCEraseEl(bias); - RDCEraseEl(blendConst); - mindepth = 0.0f; maxdepth = 1.0f; - RDCEraseEl(front); - RDCEraseEl(back); - - RDCEraseEl(renderArea); - - RDCEraseEl(ibuffer); - vbuffers.clear(); - } - - // dynamic state - vector views; - vector scissors; - float lineWidth; - struct { float depth, biasclamp, slope; } bias; - float blendConst[4]; - float mindepth, maxdepth; - struct { uint32_t compare, write, ref; } front, back; - - // this should be big enough for any implementation - byte pushconsts[1024]; - - ResourceId renderPass; - uint32_t subpass; - - ResourceId framebuffer; - VkRect2D renderArea; - - struct Pipeline - { - ResourceId pipeline; - vector descSets; - vector< vector > offsets; - } compute, graphics; - - struct IdxBuffer - { - ResourceId buf; - VkDeviceSize offs; - int bytewidth; - } ibuffer; - - struct VertBuffer - { - ResourceId buf; - VkDeviceSize offs; - }; - vector vbuffers; - } state; } m_PartialReplayData; - uint32_t m_HackDrawIndices; + // There is only a state while currently partially replaying, it's + // undefined/empty otherwise. + // All IDs are original IDs, not live. + VulkanRenderState m_RenderState; bool IsPartialCmd(ResourceId cmdid) { diff --git a/renderdoc/driver/vulkan/vk_debug.cpp b/renderdoc/driver/vulkan/vk_debug.cpp index 381294891..2b848aef0 100644 --- a/renderdoc/driver/vulkan/vk_debug.cpp +++ b/renderdoc/driver/vulkan/vk_debug.cpp @@ -2178,7 +2178,7 @@ ResourceId VulkanDebugManager::RenderOverlay(ResourceId texid, TextureDisplayOve highlightCol[3] = 1.0f; // backup state - WrappedVulkan::PartialReplayData::StateVector prevstate = m_pDriver->m_PartialReplayData.state; + VulkanRenderState prevstate = m_pDriver->m_RenderState; // make patched shader VkShaderModule mod = VK_NULL_HANDLE; @@ -2266,23 +2266,23 @@ ResourceId VulkanDebugManager::RenderOverlay(ResourceId texid, TextureDisplayOve RDCASSERT(vkr == VK_SUCCESS); // modify state - m_pDriver->m_PartialReplayData.state.renderPass = GetResID(m_OverlayNoDepthRP); - m_pDriver->m_PartialReplayData.state.subpass = 0; - m_pDriver->m_PartialReplayData.state.framebuffer = GetResID(m_OverlayNoDepthFB); + m_pDriver->m_RenderState.renderPass = GetResID(m_OverlayNoDepthRP); + m_pDriver->m_RenderState.subpass = 0; + m_pDriver->m_RenderState.framebuffer = GetResID(m_OverlayNoDepthFB); - m_pDriver->m_PartialReplayData.state.graphics.pipeline = GetResID(pipe); + m_pDriver->m_RenderState.graphics.pipeline = GetResID(pipe); // set dynamic scissors in case pipeline was using them - for(size_t i=0; i < m_pDriver->m_PartialReplayData.state.scissors.size(); i++) + for(size_t i=0; i < m_pDriver->m_RenderState.scissors.size(); i++) { - m_pDriver->m_PartialReplayData.state.scissors[i].offset.x = 0; - m_pDriver->m_PartialReplayData.state.scissors[i].offset.x = 0; - m_pDriver->m_PartialReplayData.state.scissors[i].extent.width = 4096; - m_pDriver->m_PartialReplayData.state.scissors[i].extent.height = 4096; + m_pDriver->m_RenderState.scissors[i].offset.x = 0; + m_pDriver->m_RenderState.scissors[i].offset.x = 0; + m_pDriver->m_RenderState.scissors[i].extent.width = 4096; + m_pDriver->m_RenderState.scissors[i].extent.height = 4096; } if(overlay == eTexOverlay_Wireframe) - m_pDriver->m_PartialReplayData.state.lineWidth = 1.0f; + m_pDriver->m_RenderState.lineWidth = 1.0f; m_pDriver->ReplayLog(frameID, 0, eventID, eReplay_OnlyDraw); @@ -2296,7 +2296,7 @@ ResourceId VulkanDebugManager::RenderOverlay(ResourceId texid, TextureDisplayOve RDCASSERT(vkr == VK_SUCCESS); // restore state - m_pDriver->m_PartialReplayData.state = prevstate; + m_pDriver->m_RenderState = prevstate; m_pDriver->vkDestroyPipeline(m_Device, pipe); m_pDriver->vkDestroyShaderModule(m_Device, mod); @@ -2316,26 +2316,26 @@ ResourceId VulkanDebugManager::RenderOverlay(ResourceId texid, TextureDisplayOve VkRenderPassBeginInfo rpbegin = { VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, NULL, Unwrap(m_OverlayNoDepthRP), Unwrap(m_OverlayNoDepthFB), - m_pDriver->m_PartialReplayData.state.renderArea, + m_pDriver->m_RenderState.renderArea, 1, &clearval, }; vt->CmdBeginRenderPass(Unwrap(cmd), &rpbegin, VK_RENDER_PASS_CONTENTS_INLINE); VkRect3D rect = { { - m_pDriver->m_PartialReplayData.state.renderArea.offset.x, - m_pDriver->m_PartialReplayData.state.renderArea.offset.y, + m_pDriver->m_RenderState.renderArea.offset.x, + m_pDriver->m_RenderState.renderArea.offset.y, 0, }, { - m_pDriver->m_PartialReplayData.state.renderArea.extent.width, - m_pDriver->m_PartialReplayData.state.renderArea.extent.height, + m_pDriver->m_RenderState.renderArea.extent.width, + m_pDriver->m_RenderState.renderArea.extent.height, 1, }, }; vt->CmdClearColorAttachment(Unwrap(cmd), 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, (VkClearColorValue *)black, 1, &rect); - VkViewport viewport = m_pDriver->m_PartialReplayData.state.views[0]; + VkViewport viewport = m_pDriver->m_RenderState.views[0]; vt->CmdSetViewport(Unwrap(cmd), 1, &viewport); uint32_t uboOffs = 0; @@ -2355,12 +2355,12 @@ ResourceId VulkanDebugManager::RenderOverlay(ResourceId texid, TextureDisplayOve vt->CmdDraw(Unwrap(cmd), 4, 1, 0, 0); - if(!m_pDriver->m_PartialReplayData.state.scissors.empty()) + if(!m_pDriver->m_RenderState.scissors.empty()) { - Vec4f scissor((float)m_pDriver->m_PartialReplayData.state.scissors[0].offset.x, - (float)m_pDriver->m_PartialReplayData.state.scissors[0].offset.y, - (float)m_pDriver->m_PartialReplayData.state.scissors[0].extent.width, - (float)m_pDriver->m_PartialReplayData.state.scissors[0].extent.height); + Vec4f scissor((float)m_pDriver->m_RenderState.scissors[0].offset.x, + (float)m_pDriver->m_RenderState.scissors[0].offset.y, + (float)m_pDriver->m_RenderState.scissors[0].extent.width, + (float)m_pDriver->m_RenderState.scissors[0].extent.height); outlineuniforms *ubo = (outlineuniforms *)m_OutlineUBO.Map(vt, m_Device, &uboOffs); @@ -2397,7 +2397,7 @@ ResourceId VulkanDebugManager::RenderOverlay(ResourceId texid, TextureDisplayOve highlightCol[3] = 1.0f; // backup state - WrappedVulkan::PartialReplayData::StateVector prevstate = m_pDriver->m_PartialReplayData.state; + VulkanRenderState prevstate = m_pDriver->m_RenderState; // make patched shader VkShaderModule mod[2] = {0}; @@ -2495,24 +2495,24 @@ ResourceId VulkanDebugManager::RenderOverlay(ResourceId texid, TextureDisplayOve RDCASSERT(vkr == VK_SUCCESS); // modify state - m_pDriver->m_PartialReplayData.state.renderPass = GetResID(m_OverlayNoDepthRP); - m_pDriver->m_PartialReplayData.state.subpass = 0; - m_pDriver->m_PartialReplayData.state.framebuffer = GetResID(m_OverlayNoDepthFB); + m_pDriver->m_RenderState.renderPass = GetResID(m_OverlayNoDepthRP); + m_pDriver->m_RenderState.subpass = 0; + m_pDriver->m_RenderState.framebuffer = GetResID(m_OverlayNoDepthFB); - m_pDriver->m_PartialReplayData.state.graphics.pipeline = GetResID(pipe[0]); + m_pDriver->m_RenderState.graphics.pipeline = GetResID(pipe[0]); // set dynamic scissors in case pipeline was using them - for(size_t i=0; i < m_pDriver->m_PartialReplayData.state.scissors.size(); i++) + for(size_t i=0; i < m_pDriver->m_RenderState.scissors.size(); i++) { - m_pDriver->m_PartialReplayData.state.scissors[i].offset.x = 0; - m_pDriver->m_PartialReplayData.state.scissors[i].offset.x = 0; - m_pDriver->m_PartialReplayData.state.scissors[i].extent.width = 4096; - m_pDriver->m_PartialReplayData.state.scissors[i].extent.height = 4096; + m_pDriver->m_RenderState.scissors[i].offset.x = 0; + m_pDriver->m_RenderState.scissors[i].offset.x = 0; + m_pDriver->m_RenderState.scissors[i].extent.width = 4096; + m_pDriver->m_RenderState.scissors[i].extent.height = 4096; } m_pDriver->ReplayLog(frameID, 0, eventID, eReplay_OnlyDraw); - m_pDriver->m_PartialReplayData.state.graphics.pipeline = GetResID(pipe[1]); + m_pDriver->m_RenderState.graphics.pipeline = GetResID(pipe[1]); m_pDriver->ReplayLog(frameID, 0, eventID, eReplay_OnlyDraw); @@ -2526,7 +2526,7 @@ ResourceId VulkanDebugManager::RenderOverlay(ResourceId texid, TextureDisplayOve RDCASSERT(vkr == VK_SUCCESS); // restore state - m_pDriver->m_PartialReplayData.state = prevstate; + m_pDriver->m_RenderState = prevstate; for(int i=0; i < 2; i++) { @@ -2544,7 +2544,7 @@ ResourceId VulkanDebugManager::RenderOverlay(ResourceId texid, TextureDisplayOve VkFramebuffer depthFB; VkRenderPass depthRP; - const WrappedVulkan::PartialReplayData::StateVector &state = m_pDriver->m_PartialReplayData.state; + const VulkanRenderState &state = m_pDriver->m_RenderState; VulkanCreationInfo &createinfo = m_pDriver->m_CreationInfo; RDCASSERT(state.subpass < createinfo.m_RenderPass[state.renderPass].subpasses.size()); @@ -2623,7 +2623,7 @@ ResourceId VulkanDebugManager::RenderOverlay(ResourceId texid, TextureDisplayOve highlightCol[3] = 1.0f; // backup state - WrappedVulkan::PartialReplayData::StateVector prevstate = m_pDriver->m_PartialReplayData.state; + VulkanRenderState prevstate = m_pDriver->m_RenderState; // make patched shader VkShaderModule mod[2] = {0}; @@ -2730,28 +2730,28 @@ ResourceId VulkanDebugManager::RenderOverlay(ResourceId texid, TextureDisplayOve RDCASSERT(vkr == VK_SUCCESS); // modify state - m_pDriver->m_PartialReplayData.state.renderPass = GetResID(m_OverlayNoDepthRP); - m_pDriver->m_PartialReplayData.state.subpass = 0; - m_pDriver->m_PartialReplayData.state.framebuffer = GetResID(m_OverlayNoDepthFB); + m_pDriver->m_RenderState.renderPass = GetResID(m_OverlayNoDepthRP); + m_pDriver->m_RenderState.subpass = 0; + m_pDriver->m_RenderState.framebuffer = GetResID(m_OverlayNoDepthFB); - m_pDriver->m_PartialReplayData.state.graphics.pipeline = GetResID(pipe[0]); + m_pDriver->m_RenderState.graphics.pipeline = GetResID(pipe[0]); // set dynamic scissors in case pipeline was using them - for(size_t i=0; i < m_pDriver->m_PartialReplayData.state.scissors.size(); i++) + for(size_t i=0; i < m_pDriver->m_RenderState.scissors.size(); i++) { - m_pDriver->m_PartialReplayData.state.scissors[i].offset.x = 0; - m_pDriver->m_PartialReplayData.state.scissors[i].offset.x = 0; - m_pDriver->m_PartialReplayData.state.scissors[i].extent.width = 4096; - m_pDriver->m_PartialReplayData.state.scissors[i].extent.height = 4096; + m_pDriver->m_RenderState.scissors[i].offset.x = 0; + m_pDriver->m_RenderState.scissors[i].offset.x = 0; + m_pDriver->m_RenderState.scissors[i].extent.width = 4096; + m_pDriver->m_RenderState.scissors[i].extent.height = 4096; } m_pDriver->ReplayLog(frameID, 0, eventID, eReplay_OnlyDraw); - m_pDriver->m_PartialReplayData.state.graphics.pipeline = GetResID(pipe[1]); + m_pDriver->m_RenderState.graphics.pipeline = GetResID(pipe[1]); if(depthRP != VK_NULL_HANDLE) { - m_pDriver->m_PartialReplayData.state.renderPass = GetResID(depthRP); - m_pDriver->m_PartialReplayData.state.framebuffer = GetResID(depthFB); + m_pDriver->m_RenderState.renderPass = GetResID(depthRP); + m_pDriver->m_RenderState.framebuffer = GetResID(depthFB); } m_pDriver->ReplayLog(frameID, 0, eventID, eReplay_OnlyDraw); @@ -2766,7 +2766,7 @@ ResourceId VulkanDebugManager::RenderOverlay(ResourceId texid, TextureDisplayOve RDCASSERT(vkr == VK_SUCCESS); // restore state - m_pDriver->m_PartialReplayData.state = prevstate; + m_pDriver->m_RenderState = prevstate; for(int i=0; i < 2; i++) { @@ -3806,7 +3806,7 @@ void VulkanDebugManager::InitPostVSBuffers(uint32_t frameID, uint32_t eventID) if(!m_pDriver->GetDeviceFeatures().vertexSideEffects) return; - WrappedVulkan::PartialReplayData::StateVector &state = m_pDriver->m_PartialReplayData.state; + const VulkanRenderState &state = m_pDriver->m_RenderState; VulkanCreationInfo &c = m_pDriver->m_CreationInfo; if(state.graphics.pipeline == ResourceId()) @@ -4079,14 +4079,14 @@ void VulkanDebugManager::InitPostVSBuffers(uint32_t frameID, uint32_t eventID) vkr = m_pDriver->vkCreateGraphicsPipelines(m_Device, VK_NULL_HANDLE, 1, &pipeCreateInfo, &pipe); RDCASSERT(vkr == VK_SUCCESS); - // backup state - WrappedVulkan::PartialReplayData::StateVector prevstate = state; + // make copy of state to draw from + VulkanRenderState modifiedstate = state; // bind created pipeline to partial replay state - state.graphics.pipeline = GetResID(pipe); + modifiedstate.graphics.pipeline = GetResID(pipe); // push back extra descriptor set to partial replay state - state.graphics.descSets.push_back( GetResID(m_MeshFetchDescSet) ); + modifiedstate.graphics.descSets.push_back( GetResID(m_MeshFetchDescSet) ); if((drawcall->flags & eDraw_UseIBuffer) == 0) { @@ -4151,9 +4151,6 @@ void VulkanDebugManager::InitPostVSBuffers(uint32_t frameID, uint32_t eventID) }; m_pDriver->vkUpdateDescriptorSets(dev, 1, &write, 0, NULL); - // do single draw - m_pDriver->ReplayLog(frameID, 0, eventID, eReplay_OnlyDraw); - VkCmdBuffer cmd = m_pDriver->GetNextCmd(); VkCmdBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO, NULL, VK_CMD_BUFFER_OPTIMIZE_SMALL_BATCH_BIT | VK_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT }; @@ -4161,6 +4158,11 @@ void VulkanDebugManager::InitPostVSBuffers(uint32_t frameID, uint32_t eventID) vkr = ObjDisp(dev)->BeginCommandBuffer(Unwrap(cmd), &beginInfo); RDCASSERT(vkr == VK_SUCCESS); + // do single draw + modifiedstate.BeginRenderPassAndApplyState(cmd); + ObjDisp(cmd)->CmdDraw(Unwrap(cmd), drawcall->numIndices, drawcall->numInstances, drawcall->vertexOffset, drawcall->instanceOffset); + ObjDisp(cmd)->CmdEndRenderPass(Unwrap(cmd)); + VkBufferMemoryBarrier meshbufbarrier = { VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, NULL, VK_MEMORY_OUTPUT_SHADER_WRITE_BIT, VK_MEMORY_INPUT_TRANSFER_BIT|VK_MEMORY_INPUT_VERTEX_ATTRIBUTE_FETCH_BIT, @@ -4280,9 +4282,9 @@ void VulkanDebugManager::InitPostVSBuffers(uint32_t frameID, uint32_t eventID) bufSize = numVerts*RDCMAX(1U, drawcall->numInstances)*bufStride; // bind unique'd ibuffer - state.ibuffer.bytewidth = 4; - state.ibuffer.offs = 0; - state.ibuffer.buf = GetResID(uniqIdxBuf); + modifiedstate.ibuffer.bytewidth = 4; + modifiedstate.ibuffer.offs = 0; + modifiedstate.ibuffer.buf = GetResID(uniqIdxBuf); // vkUpdateDescriptorSet desc set to point to buffer VkDescriptorInfo fetchdesc = { 0 }; @@ -4299,21 +4301,19 @@ void VulkanDebugManager::InitPostVSBuffers(uint32_t frameID, uint32_t eventID) vkr = ObjDisp(dev)->EndCommandBuffer(Unwrap(cmd)); RDCASSERT(vkr == VK_SUCCESS); - // a bit of a hack to ensure we have the right number of indices for rendering. - // we want to have a nicer 'apply current state' function so we can reuse that - // then do our own draw. - m_pDriver->m_HackDrawIndices = (uint32_t)indices.size(); - // do single draw m_pDriver->ReplayLog(frameID, 0, eventID, eReplay_OnlyDraw); - - m_pDriver->m_HackDrawIndices = ~0U; cmd = m_pDriver->GetNextCmd(); vkr = ObjDisp(dev)->BeginCommandBuffer(Unwrap(cmd), &beginInfo); RDCASSERT(vkr == VK_SUCCESS); + // do single draw + modifiedstate.BeginRenderPassAndApplyState(cmd); + ObjDisp(cmd)->CmdDrawIndexed(Unwrap(cmd), (uint32_t)indices.size(), drawcall->numInstances, 0, drawcall->vertexOffset, drawcall->instanceOffset); + ObjDisp(cmd)->CmdEndRenderPass(Unwrap(cmd)); + // rebase existing index buffer to point to the right elements in our stream-out'd // vertex buffer @@ -4447,9 +4447,6 @@ void VulkanDebugManager::InitPostVSBuffers(uint32_t frameID, uint32_t eventID) m_pDriver->vkDestroyBuffer(m_Device, uniqIdxBuf); m_pDriver->vkFreeMemory(m_Device, uniqIdxBufMem); } - - // reset pipeline state back to normal - state = prevstate; // fill out m_PostVSData m_PostVSData[idx].vsin.topo = topo; diff --git a/renderdoc/driver/vulkan/vk_replay.cpp b/renderdoc/driver/vulkan/vk_replay.cpp index 319b1a2a9..76bf319d7 100644 --- a/renderdoc/driver/vulkan/vk_replay.cpp +++ b/renderdoc/driver/vulkan/vk_replay.cpp @@ -2584,7 +2584,7 @@ void VulkanReplay::FileChanged() void VulkanReplay::SavePipelineState() { { - const WrappedVulkan::PartialReplayData::StateVector &state = m_pDriver->m_PartialReplayData.state; + const VulkanRenderState &state = m_pDriver->m_RenderState; VulkanCreationInfo &c = m_pDriver->m_CreationInfo; VulkanResourceManager *rm = m_pDriver->GetResourceManager(); @@ -3245,8 +3245,8 @@ void VulkanReplay::FillCBufferVariables(ResourceId shader, uint32_t cbufSlot, ve else { vector pushdata; - pushdata.resize(sizeof(m_pDriver->m_PartialReplayData.state.pushconsts)); - memcpy(&pushdata[0], m_pDriver->m_PartialReplayData.state.pushconsts, pushdata.size()); + pushdata.resize(sizeof(m_pDriver->m_RenderState.pushconsts)); + memcpy(&pushdata[0], m_pDriver->m_RenderState.pushconsts, pushdata.size()); FillCBufferVariables(c.variables, outvars, pushdata, zero); } diff --git a/renderdoc/driver/vulkan/vk_state.cpp b/renderdoc/driver/vulkan/vk_state.cpp new file mode 100644 index 000000000..53af1ff73 --- /dev/null +++ b/renderdoc/driver/vulkan/vk_state.cpp @@ -0,0 +1,191 @@ +/****************************************************************************** + * The MIT License (MIT) + * + * Copyright (c) 2015 Baldur Karlsson + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + ******************************************************************************/ + +#include "vk_state.h" +#include "vk_info.h" +#include "vk_resources.h" + +VulkanRenderState::VulkanRenderState(VulkanCreationInfo &createInfo) + : m_CreationInfo(createInfo) +{ + compute.pipeline = graphics.pipeline = renderPass = framebuffer = ResourceId(); + compute.descSets.clear(); + graphics.descSets.clear(); + compute.offsets.clear(); + graphics.offsets.clear(); + + views.clear(); + scissors.clear(); + lineWidth = 1.0f; + RDCEraseEl(bias); + RDCEraseEl(blendConst); + mindepth = 0.0f; maxdepth = 1.0f; + RDCEraseEl(front); + RDCEraseEl(back); + RDCEraseEl(pushconsts); + + renderPass = ResourceId(); + subpass = 0; + + RDCEraseEl(renderArea); + + RDCEraseEl(ibuffer); + vbuffers.clear(); +} + +VulkanRenderState & VulkanRenderState::operator =(const VulkanRenderState &o) +{ + views = o.views; + scissors = o.scissors; + lineWidth = o.lineWidth; + bias = o.bias; + memcpy(blendConst, o.blendConst, sizeof(blendConst)); + mindepth = o.mindepth; + maxdepth = o.maxdepth; + front = o.front; + back = o.back; + memcpy(pushconsts, o.pushconsts, sizeof(pushconsts)); + renderPass = o.renderPass; + subpass = o.subpass; + framebuffer = o.framebuffer; + renderArea = o.renderArea; + + compute.pipeline = o.compute.pipeline; + compute.descSets = o.compute.descSets; + compute.offsets = o.compute.offsets; + + graphics.pipeline = o.graphics.pipeline; + graphics.descSets = o.graphics.descSets; + graphics.offsets = o.graphics.offsets; + + ibuffer = o.ibuffer; + vbuffers = o.vbuffers; + + return *this; +} + +void VulkanRenderState::BeginRenderPassAndApplyState(VkCmdBuffer cmd) +{ + RDCASSERT(renderPass != ResourceId()); + + // clear values don't matter as we're using the load renderpass here, that + // has all load ops set to load (as we're doing a partial replay - can't + // just clear the targets that are partially written to). + + VkClearValue empty[16] = {0}; + + RDCASSERT(ARRAY_COUNT(empty) >= m_CreationInfo.m_RenderPass[renderPass].attachments.size()); + + VkRenderPassBeginInfo rpbegin = { + VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, NULL, + Unwrap(m_CreationInfo.m_RenderPass[renderPass].loadRP), + Unwrap(GetResourceManager()->GetCurrentHandle(framebuffer)), + renderArea, + (uint32_t)m_CreationInfo.m_RenderPass[renderPass].attachments.size(), empty, + }; + ObjDisp(cmd)->CmdBeginRenderPass(Unwrap(cmd), &rpbegin, VK_RENDER_PASS_CONTENTS_INLINE); + + for(uint32_t i=0; i < subpass; i++) + ObjDisp(cmd)->CmdNextSubpass(Unwrap(cmd), VK_RENDER_PASS_CONTENTS_INLINE); + + if(graphics.pipeline != ResourceId()) + { + ObjDisp(cmd)->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(GetResourceManager()->GetCurrentHandle(graphics.pipeline))); + + ResourceId pipeLayoutId = m_CreationInfo.m_Pipeline[graphics.pipeline].layout; + VkPipelineLayout layout = GetResourceManager()->GetCurrentHandle(pipeLayoutId); + + const vector &pushRanges = m_CreationInfo.m_PipelineLayout[pipeLayoutId].pushRanges; + + // only set push constant ranges that the layout uses + for(size_t i=0; i < pushRanges.size(); i++) + ObjDisp(cmd)->CmdPushConstants(Unwrap(cmd), Unwrap(layout), pushRanges[i].stageFlags, pushRanges[i].start, pushRanges[i].length, pushconsts+pushRanges[i].start); + + const vector &descSetLayouts = m_CreationInfo.m_PipelineLayout[pipeLayoutId].descSetLayouts; + + // only iterate over the desc sets that this layout actually uses, not all that were bound + for(size_t i=0; i < descSetLayouts.size(); i++) + { + const DescSetLayout &descLayout = m_CreationInfo.m_DescSetLayout[ descSetLayouts[i] ]; + + if(i < graphics.descSets.size() && graphics.descSets[i] != ResourceId()) + { + // if there are dynamic buffers, pass along the offsets + ObjDisp(cmd)->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(layout), (uint32_t)i, + 1, UnwrapPtr(GetResourceManager()->GetCurrentHandle(graphics.descSets[i])), + descLayout.dynamicCount, descLayout.dynamicCount == 0 ? NULL : &graphics.offsets[i][0]); + } + else + { + RDCWARN("Descriptor set is not bound but pipeline layout expects one"); + } + } + } + + if(compute.pipeline != ResourceId()) + { + ObjDisp(cmd)->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, Unwrap(GetResourceManager()->GetCurrentHandle(compute.pipeline))); + + ResourceId pipeLayoutId = m_CreationInfo.m_Pipeline[compute.pipeline].layout; + VkPipelineLayout layout = GetResourceManager()->GetCurrentHandle(pipeLayoutId); + + const vector &descSetLayouts = m_CreationInfo.m_PipelineLayout[pipeLayoutId].descSetLayouts; + + for(size_t i=0; i < descSetLayouts.size(); i++) + { + const DescSetLayout &descLayout = m_CreationInfo.m_DescSetLayout[ descSetLayouts[i] ]; + + if(compute.descSets[i] != ResourceId()) + { + ObjDisp(cmd)->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(layout), (uint32_t)i, + 1, UnwrapPtr(GetResourceManager()->GetCurrentHandle(compute.descSets[i])), + descLayout.dynamicCount, descLayout.dynamicCount == 0 ? NULL : &compute.offsets[i][0]); + } + } + } + + if(!views.empty()) + ObjDisp(cmd)->CmdSetViewport(Unwrap(cmd), (uint32_t)views.size(), &views[0]); + if(!scissors.empty()) + ObjDisp(cmd)->CmdSetScissor(Unwrap(cmd), (uint32_t)scissors.size(), &scissors[0]); + + ObjDisp(cmd)->CmdSetBlendConstants(Unwrap(cmd), blendConst); + ObjDisp(cmd)->CmdSetDepthBounds(Unwrap(cmd), mindepth, maxdepth); + ObjDisp(cmd)->CmdSetLineWidth(Unwrap(cmd), lineWidth); + ObjDisp(cmd)->CmdSetDepthBias(Unwrap(cmd), bias.depth, bias.biasclamp, bias.slope); + + ObjDisp(cmd)->CmdSetStencilReference(Unwrap(cmd), VK_STENCIL_FACE_BACK_BIT, back.ref); + ObjDisp(cmd)->CmdSetStencilCompareMask(Unwrap(cmd), VK_STENCIL_FACE_BACK_BIT, back.compare); + ObjDisp(cmd)->CmdSetStencilWriteMask(Unwrap(cmd), VK_STENCIL_FACE_BACK_BIT, back.write); + + ObjDisp(cmd)->CmdSetStencilReference(Unwrap(cmd), VK_STENCIL_FACE_FRONT_BIT, front.ref); + ObjDisp(cmd)->CmdSetStencilCompareMask(Unwrap(cmd), VK_STENCIL_FACE_FRONT_BIT, front.compare); + ObjDisp(cmd)->CmdSetStencilWriteMask(Unwrap(cmd), VK_STENCIL_FACE_FRONT_BIT, front.write); + + if(ibuffer.buf != ResourceId()) + ObjDisp(cmd)->CmdBindIndexBuffer(Unwrap(cmd), Unwrap(GetResourceManager()->GetCurrentHandle(ibuffer.buf)), ibuffer.offs, ibuffer.bytewidth == 4 ? VK_INDEX_TYPE_UINT32 : VK_INDEX_TYPE_UINT16); + + for(size_t i=0; i < vbuffers.size(); i++) + ObjDisp(cmd)->CmdBindVertexBuffers(Unwrap(cmd), (uint32_t)i, 1, UnwrapPtr(GetResourceManager()->GetCurrentHandle(vbuffers[i].buf)), &vbuffers[i].offs); +} diff --git a/renderdoc/driver/vulkan/vk_state.h b/renderdoc/driver/vulkan/vk_state.h new file mode 100644 index 000000000..96a77f846 --- /dev/null +++ b/renderdoc/driver/vulkan/vk_state.h @@ -0,0 +1,85 @@ +/****************************************************************************** + * The MIT License (MIT) + * + * Copyright (c) 2015 Baldur Karlsson + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + ******************************************************************************/ + +#pragma once + +#include + +#include "vk_common.h" + +struct VulkanCreationInfo; +class VulkanResourceManager; + +struct VulkanRenderState +{ + VulkanRenderState(VulkanCreationInfo &createInfo); + VulkanRenderState &operator =(const VulkanRenderState &o); + void BeginRenderPassAndApplyState(VkCmdBuffer cmd); + + // dynamic state + vector views; + vector scissors; + float lineWidth; + struct { float depth, biasclamp, slope; } bias; + float blendConst[4]; + float mindepth, maxdepth; + struct { uint32_t compare, write, ref; } front, back; + + // this should be big enough for any implementation + byte pushconsts[1024]; + + ResourceId renderPass; + uint32_t subpass; + + ResourceId framebuffer; + VkRect2D renderArea; + + struct Pipeline + { + ResourceId pipeline; + vector descSets; + vector< vector > offsets; + } compute, graphics; + + struct IdxBuffer + { + ResourceId buf; + VkDeviceSize offs; + int bytewidth; + } ibuffer; + + struct VertBuffer + { + ResourceId buf; + VkDeviceSize offs; + }; + vector vbuffers; + + VulkanResourceManager *GetResourceManager() { return m_ResourceManager; } + + VulkanResourceManager *m_ResourceManager; + VulkanCreationInfo &m_CreationInfo; +}; + + diff --git a/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp index 7c7715abd..dd0841fdc 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp @@ -28,8 +28,8 @@ string WrappedVulkan::MakeRenderPassOpString(bool store) { string opDesc = ""; - const VulkanCreationInfo::RenderPass &info = m_CreationInfo.m_RenderPass[m_PartialReplayData.state.renderPass]; - const VulkanCreationInfo::Framebuffer &fbinfo = m_CreationInfo.m_Framebuffer[m_PartialReplayData.state.framebuffer]; + const VulkanCreationInfo::RenderPass &info = m_CreationInfo.m_RenderPass[m_RenderState.renderPass]; + const VulkanCreationInfo::Framebuffer &fbinfo = m_CreationInfo.m_Framebuffer[m_RenderState.framebuffer]; const vector &atts = info.attachments; @@ -42,7 +42,7 @@ string WrappedVulkan::MakeRenderPassOpString(bool store) bool colsame = true; // find which attachment is the depth-stencil one - int32_t dsAttach = info.subpasses[m_PartialReplayData.state.subpass].depthstencilAttachment; + int32_t dsAttach = info.subpasses[m_RenderState.subpass].depthstencilAttachment; bool hasStencil = false; bool depthonly = false; @@ -51,7 +51,7 @@ string WrappedVulkan::MakeRenderPassOpString(bool store) if(dsAttach >= 0) { hasStencil = !IsDepthOnlyFormat(fbinfo.attachments[dsAttach].format); - depthonly = info.subpasses[m_PartialReplayData.state.subpass].colorAttachments.size() == 0; + depthonly = info.subpasses[m_RenderState.subpass].colorAttachments.size() == 0; } // first colour attachment, if there is one @@ -585,11 +585,11 @@ bool WrappedVulkan::Serialise_vkCmdBeginRenderPass( m_PartialReplayData.renderPassActive = true; ObjDisp(cmdBuffer)->CmdBeginRenderPass(Unwrap(cmdBuffer), &beginInfo, cont); - m_PartialReplayData.state.subpass = 0; + m_RenderState.subpass = 0; - m_PartialReplayData.state.renderPass = GetResourceManager()->GetNonDispWrapper(beginInfo.renderPass)->id; - m_PartialReplayData.state.framebuffer = GetResourceManager()->GetNonDispWrapper(beginInfo.framebuffer)->id; - m_PartialReplayData.state.renderArea = beginInfo.renderArea; + m_RenderState.renderPass = GetResourceManager()->GetNonDispWrapper(beginInfo.renderPass)->id; + m_RenderState.framebuffer = GetResourceManager()->GetNonDispWrapper(beginInfo.framebuffer)->id; + m_RenderState.renderArea = beginInfo.renderArea; } } else if(m_State == READING) @@ -599,9 +599,9 @@ bool WrappedVulkan::Serialise_vkCmdBeginRenderPass( ObjDisp(cmdBuffer)->CmdBeginRenderPass(Unwrap(cmdBuffer), &beginInfo, cont); // track during reading - m_PartialReplayData.state.subpass = 0; - m_PartialReplayData.state.renderPass = GetResourceManager()->GetNonDispWrapper(beginInfo.renderPass)->id; - m_PartialReplayData.state.framebuffer = GetResourceManager()->GetNonDispWrapper(beginInfo.framebuffer)->id; + m_RenderState.subpass = 0; + m_RenderState.renderPass = GetResourceManager()->GetNonDispWrapper(beginInfo.renderPass)->id; + m_RenderState.framebuffer = GetResourceManager()->GetNonDispWrapper(beginInfo.framebuffer)->id; const string desc = localSerialiser->GetDebugStr(); @@ -674,7 +674,7 @@ bool WrappedVulkan::Serialise_vkCmdNextSubpass( { cmdBuffer = PartialCmdBuf(); - m_PartialReplayData.state.subpass++; + m_RenderState.subpass++; ObjDisp(cmdBuffer)->CmdNextSubpass(Unwrap(cmdBuffer), cont); } @@ -686,13 +686,13 @@ bool WrappedVulkan::Serialise_vkCmdNextSubpass( ObjDisp(cmdBuffer)->CmdNextSubpass(Unwrap(cmdBuffer), cont); // track during reading - m_PartialReplayData.state.subpass++; + m_RenderState.subpass++; const string desc = localSerialiser->GetDebugStr(); AddEvent(NEXT_SUBPASS, desc); FetchDrawcall draw; - draw.name = StringFormat::Fmt("vkCmdNextSubpass() => %u", m_PartialReplayData.state.subpass); + draw.name = StringFormat::Fmt("vkCmdNextSubpass() => %u", m_RenderState.subpass); draw.flags |= eDraw_Clear; AddDrawcall(draw, true); @@ -893,51 +893,51 @@ bool WrappedVulkan::Serialise_vkCmdBindPipeline( ResourceId liveid = GetResID(pipeline); if(bind == VK_PIPELINE_BIND_POINT_GRAPHICS) - m_PartialReplayData.state.graphics.pipeline = liveid; + m_RenderState.graphics.pipeline = liveid; else - m_PartialReplayData.state.compute.pipeline = liveid; + m_RenderState.compute.pipeline = liveid; if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_VIEWPORT]) { - m_PartialReplayData.state.views = m_CreationInfo.m_Pipeline[liveid].viewports; + m_RenderState.views = m_CreationInfo.m_Pipeline[liveid].viewports; } if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_SCISSOR]) { - m_PartialReplayData.state.scissors = m_CreationInfo.m_Pipeline[liveid].scissors; + m_RenderState.scissors = m_CreationInfo.m_Pipeline[liveid].scissors; } if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_LINE_WIDTH]) { - m_PartialReplayData.state.lineWidth = m_CreationInfo.m_Pipeline[liveid].lineWidth; + m_RenderState.lineWidth = m_CreationInfo.m_Pipeline[liveid].lineWidth; } if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_DEPTH_BIAS]) { - m_PartialReplayData.state.bias.depth = m_CreationInfo.m_Pipeline[liveid].depthBias; - m_PartialReplayData.state.bias.biasclamp = m_CreationInfo.m_Pipeline[liveid].depthBiasClamp; - m_PartialReplayData.state.bias.slope = m_CreationInfo.m_Pipeline[liveid].slopeScaledDepthBias; + m_RenderState.bias.depth = m_CreationInfo.m_Pipeline[liveid].depthBias; + m_RenderState.bias.biasclamp = m_CreationInfo.m_Pipeline[liveid].depthBiasClamp; + m_RenderState.bias.slope = m_CreationInfo.m_Pipeline[liveid].slopeScaledDepthBias; } if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_BLEND_CONSTANTS]) { - memcpy(m_PartialReplayData.state.blendConst, m_CreationInfo.m_Pipeline[liveid].blendConst, sizeof(float)*4); + memcpy(m_RenderState.blendConst, m_CreationInfo.m_Pipeline[liveid].blendConst, sizeof(float)*4); } if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_DEPTH_BOUNDS]) { - m_PartialReplayData.state.mindepth = m_CreationInfo.m_Pipeline[liveid].minDepthBounds; - m_PartialReplayData.state.maxdepth = m_CreationInfo.m_Pipeline[liveid].maxDepthBounds; + m_RenderState.mindepth = m_CreationInfo.m_Pipeline[liveid].minDepthBounds; + m_RenderState.maxdepth = m_CreationInfo.m_Pipeline[liveid].maxDepthBounds; } if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK]) { - m_PartialReplayData.state.front.compare = m_CreationInfo.m_Pipeline[liveid].front.stencilCompareMask; - m_PartialReplayData.state.back.compare = m_CreationInfo.m_Pipeline[liveid].back.stencilCompareMask; + m_RenderState.front.compare = m_CreationInfo.m_Pipeline[liveid].front.stencilCompareMask; + m_RenderState.back.compare = m_CreationInfo.m_Pipeline[liveid].back.stencilCompareMask; } if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_STENCIL_WRITE_MASK]) { - m_PartialReplayData.state.front.write = m_CreationInfo.m_Pipeline[liveid].front.stencilWriteMask; - m_PartialReplayData.state.back.write = m_CreationInfo.m_Pipeline[liveid].back.stencilWriteMask; + m_RenderState.front.write = m_CreationInfo.m_Pipeline[liveid].front.stencilWriteMask; + m_RenderState.back.write = m_CreationInfo.m_Pipeline[liveid].back.stencilWriteMask; } if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_STENCIL_REFERENCE]) { - m_PartialReplayData.state.front.ref = m_CreationInfo.m_Pipeline[liveid].front.stencilReference; - m_PartialReplayData.state.back.ref = m_CreationInfo.m_Pipeline[liveid].back.stencilReference; + m_RenderState.front.ref = m_CreationInfo.m_Pipeline[liveid].front.stencilReference; + m_RenderState.back.ref = m_CreationInfo.m_Pipeline[liveid].back.stencilReference; } } } @@ -948,9 +948,9 @@ bool WrappedVulkan::Serialise_vkCmdBindPipeline( // track this while reading, as we need to bind current topology & index byte width to draws if(bind == VK_PIPELINE_BIND_POINT_GRAPHICS) - m_PartialReplayData.state.graphics.pipeline = GetResID(pipeline); + m_RenderState.graphics.pipeline = GetResID(pipeline); else - m_PartialReplayData.state.compute.pipeline = GetResID(pipeline); + m_RenderState.compute.pipeline = GetResID(pipeline); ObjDisp(cmdBuffer)->CmdBindPipeline(Unwrap(cmdBuffer), bind, Unwrap(pipeline)); } @@ -1036,13 +1036,13 @@ bool WrappedVulkan::Serialise_vkCmdBindDescriptorSets( vector &descsets = (bind == VK_PIPELINE_BIND_POINT_GRAPHICS) - ? m_PartialReplayData.state.graphics.descSets - : m_PartialReplayData.state.compute.descSets; + ? m_RenderState.graphics.descSets + : m_RenderState.compute.descSets; vector< vector > &offsets = (bind == VK_PIPELINE_BIND_POINT_GRAPHICS) - ? m_PartialReplayData.state.graphics.offsets - : m_PartialReplayData.state.compute.offsets; + ? m_RenderState.graphics.offsets + : m_RenderState.compute.offsets; // expand as necessary if(descsets.size() < first + numSets) @@ -1195,13 +1195,13 @@ bool WrappedVulkan::Serialise_vkCmdBindVertexBuffers( cmdBuffer = PartialCmdBuf(); ObjDisp(cmdBuffer)->CmdBindVertexBuffers(Unwrap(cmdBuffer), start, count, &bufs[0], &offs[0]); - if(m_PartialReplayData.state.vbuffers.size() < start + count) - m_PartialReplayData.state.vbuffers.resize(start + count); + if(m_RenderState.vbuffers.size() < start + count) + m_RenderState.vbuffers.resize(start + count); for(uint32_t i=0; i < count; i++) { - m_PartialReplayData.state.vbuffers[start + i].buf = bufids[i]; - m_PartialReplayData.state.vbuffers[start + i].offs = offs[i]; + m_RenderState.vbuffers[start + i].buf = bufids[i]; + m_RenderState.vbuffers[start + i].offs = offs[i]; } } } @@ -1272,9 +1272,9 @@ bool WrappedVulkan::Serialise_vkCmdBindIndexBuffer( cmdBuffer = PartialCmdBuf(); ObjDisp(cmdBuffer)->CmdBindIndexBuffer(Unwrap(cmdBuffer), Unwrap(buffer), offs, idxType); - m_PartialReplayData.state.ibuffer.buf = GetResID(buffer); - m_PartialReplayData.state.ibuffer.offs = offs; - m_PartialReplayData.state.ibuffer.bytewidth = idxType == VK_INDEX_TYPE_UINT32 ? 4 : 2; + m_RenderState.ibuffer.buf = GetResID(buffer); + m_RenderState.ibuffer.offs = offs; + m_RenderState.ibuffer.bytewidth = idxType == VK_INDEX_TYPE_UINT32 ? 4 : 2; } } else if(m_State == READING) @@ -1283,7 +1283,7 @@ bool WrappedVulkan::Serialise_vkCmdBindIndexBuffer( buffer = GetResourceManager()->GetLiveHandle(bufid); // track this while reading, as we need to bind current topology & index byte width to draws - m_PartialReplayData.state.ibuffer.bytewidth = idxType == VK_INDEX_TYPE_UINT32 ? 4 : 2; + m_RenderState.ibuffer.bytewidth = idxType == VK_INDEX_TYPE_UINT32 ? 4 : 2; ObjDisp(cmdBuffer)->CmdBindIndexBuffer(Unwrap(cmdBuffer), Unwrap(buffer), offs, idxType); } @@ -1486,9 +1486,9 @@ bool WrappedVulkan::Serialise_vkCmdPushConstants( layout = GetResourceManager()->GetLiveHandle(layid); ObjDisp(cmdBuffer)->CmdPushConstants(Unwrap(cmdBuffer), Unwrap(layout), flags, s, len, vals); - RDCASSERT(s+len < (uint32_t)ARRAY_COUNT(m_PartialReplayData.state.pushconsts)); + RDCASSERT(s+len < (uint32_t)ARRAY_COUNT(m_RenderState.pushconsts)); - memcpy(m_PartialReplayData.state.pushconsts + s, vals, len); + memcpy(m_RenderState.pushconsts + s, vals, len); } } else if(m_State == READING) diff --git a/renderdoc/driver/vulkan/wrappers/vk_draw_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_draw_funcs.cpp index caefeb941..5c42b6e1c 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_draw_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_draw_funcs.cpp @@ -1048,13 +1048,6 @@ bool WrappedVulkan::Serialise_vkCmdDrawIndexed( if(IsPartialCmd(cmdid) && InPartialRange()) { cmdBuffer = PartialCmdBuf(); - - if(m_HackDrawIndices != ~0U) - { - firstIdx = 0; - idxCount = m_HackDrawIndices; - } - ObjDisp(cmdBuffer)->CmdDrawIndexed(Unwrap(cmdBuffer), idxCount, instCount, firstIdx, vtxOffs, firstInst); } } diff --git a/renderdoc/driver/vulkan/wrappers/vk_dynamic_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_dynamic_funcs.cpp index bb194a169..7c269f9c1 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_dynamic_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_dynamic_funcs.cpp @@ -43,7 +43,7 @@ bool WrappedVulkan::Serialise_vkCmdSetViewport( { cmdBuffer = PartialCmdBuf(); ObjDisp(cmdBuffer)->CmdSetViewport(Unwrap(cmdBuffer), count, views); - m_PartialReplayData.state.views.assign(views, views + count); + m_RenderState.views.assign(views, views + count); } } else if(m_State == READING) @@ -97,7 +97,7 @@ bool WrappedVulkan::Serialise_vkCmdSetScissor( { cmdBuffer = PartialCmdBuf(); ObjDisp(cmdBuffer)->CmdSetScissor(Unwrap(cmdBuffer), count, scissors); - m_PartialReplayData.state.scissors.assign(scissors, scissors + count); + m_RenderState.scissors.assign(scissors, scissors + count); } } else if(m_State == READING) @@ -149,7 +149,7 @@ bool WrappedVulkan::Serialise_vkCmdSetLineWidth( { cmdBuffer = PartialCmdBuf(); ObjDisp(cmdBuffer)->CmdSetLineWidth(Unwrap(cmdBuffer), width); - m_PartialReplayData.state.lineWidth = width; + m_RenderState.lineWidth = width; } } else if(m_State == READING) @@ -202,9 +202,9 @@ bool WrappedVulkan::Serialise_vkCmdSetDepthBias( { cmdBuffer = PartialCmdBuf(); ObjDisp(cmdBuffer)->CmdSetDepthBias(Unwrap(cmdBuffer), bias, biasclamp, slope); - m_PartialReplayData.state.bias.depth = bias; - m_PartialReplayData.state.bias.biasclamp = biasclamp; - m_PartialReplayData.state.bias.slope = slope; + m_RenderState.bias.depth = bias; + m_RenderState.bias.biasclamp = biasclamp; + m_RenderState.bias.slope = slope; } } else if(m_State == READING) @@ -263,7 +263,7 @@ bool WrappedVulkan::Serialise_vkCmdSetBlendConstants( { cmdBuffer = PartialCmdBuf(); ObjDisp(cmdBuffer)->CmdSetBlendConstants(Unwrap(cmdBuffer), blendFactor); - memcpy(m_PartialReplayData.state.blendConst, blendFactor, sizeof(blendFactor)); + memcpy(m_RenderState.blendConst, blendFactor, sizeof(blendFactor)); } } else if(m_State == READING) @@ -314,8 +314,8 @@ bool WrappedVulkan::Serialise_vkCmdSetDepthBounds( { cmdBuffer = PartialCmdBuf(); ObjDisp(cmdBuffer)->CmdSetDepthBounds(Unwrap(cmdBuffer), mind, maxd); - m_PartialReplayData.state.mindepth = mind; - m_PartialReplayData.state.maxdepth = maxd; + m_RenderState.mindepth = mind; + m_RenderState.maxdepth = maxd; } } else if(m_State == READING) @@ -369,9 +369,9 @@ bool WrappedVulkan::Serialise_vkCmdSetStencilCompareMask( ObjDisp(cmdBuffer)->CmdSetStencilCompareMask(Unwrap(cmdBuffer), face, mask); if(face & VK_STENCIL_FACE_FRONT_BIT) - m_PartialReplayData.state.front.compare = mask; + m_RenderState.front.compare = mask; if(face & VK_STENCIL_FACE_BACK_BIT) - m_PartialReplayData.state.back.compare = mask; + m_RenderState.back.compare = mask; } } else if(m_State == READING) @@ -425,9 +425,9 @@ bool WrappedVulkan::Serialise_vkCmdSetStencilWriteMask( ObjDisp(cmdBuffer)->CmdSetStencilWriteMask(Unwrap(cmdBuffer), face, mask); if(face & VK_STENCIL_FACE_FRONT_BIT) - m_PartialReplayData.state.front.write = mask; + m_RenderState.front.write = mask; if(face & VK_STENCIL_FACE_BACK_BIT) - m_PartialReplayData.state.back.write = mask; + m_RenderState.back.write = mask; } } else if(m_State == READING) @@ -481,9 +481,9 @@ bool WrappedVulkan::Serialise_vkCmdSetStencilReference( ObjDisp(cmdBuffer)->CmdSetStencilReference(Unwrap(cmdBuffer), face, mask); if(face & VK_STENCIL_FACE_FRONT_BIT) - m_PartialReplayData.state.front.ref = mask; + m_RenderState.front.ref = mask; if(face & VK_STENCIL_FACE_BACK_BIT) - m_PartialReplayData.state.back.ref = mask; + m_RenderState.back.ref = mask; } } else if(m_State == READING)