diff --git a/ReleaseNotes.md b/ReleaseNotes.md index c197e11e0..5ce8d394a 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -33,7 +33,6 @@ On capture: * Unsupported or untested features: * Subpasses * Nested command buffer execution - * Push constants * GPU-GPU synchronisation with events. * Sparse resources diff --git a/renderdoc/driver/vulkan/vk_core.cpp b/renderdoc/driver/vulkan/vk_core.cpp index e4b61549d..b6ac80ca5 100644 --- a/renderdoc/driver/vulkan/vk_core.cpp +++ b/renderdoc/driver/vulkan/vk_core.cpp @@ -1770,6 +1770,12 @@ void WrappedVulkan::ReplayLog(uint32_t frameID, uint32_t startEventID, uint32_t 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].stages, 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 diff --git a/renderdoc/driver/vulkan/vk_core.h b/renderdoc/driver/vulkan/vk_core.h index f589143fa..ac438538b 100644 --- a/renderdoc/driver/vulkan/vk_core.h +++ b/renderdoc/driver/vulkan/vk_core.h @@ -334,6 +334,9 @@ private: float mindepth, maxdepth; struct { uint32_t compare, write, ref; } front, back; + // this should be big enough for any implementation + byte pushconsts[1024]; + ResourceId renderPass; ResourceId framebuffer; VkRect2D renderArea; diff --git a/renderdoc/driver/vulkan/vk_info.cpp b/renderdoc/driver/vulkan/vk_info.cpp index 1c4e77c86..f63a73751 100644 --- a/renderdoc/driver/vulkan/vk_info.cpp +++ b/renderdoc/driver/vulkan/vk_info.cpp @@ -229,6 +229,15 @@ void VulkanCreationInfo::PipelineLayout::Init(VulkanResourceManager *resourceMan descSetLayouts.resize(pCreateInfo->descriptorSetCount); for(uint32_t i=0; i < pCreateInfo->descriptorSetCount; i++) descSetLayouts[i] = resourceMan->GetNonDispWrapper(pCreateInfo->pSetLayouts[i])->id; + + pushRanges.resize(pCreateInfo->pushConstantRangeCount); + for(uint32_t i=0; i < pCreateInfo->pushConstantRangeCount; i++) + { + PushConstantRange &range = pushRanges[i]; + range.start = pCreateInfo->pPushConstantRanges[i].start; + range.length = pCreateInfo->pPushConstantRanges[i].length; + range.stages = pCreateInfo->pPushConstantRanges[i].stageFlags; + } } void VulkanCreationInfo::RenderPass::Init(VulkanResourceManager *resourceMan, const VkRenderPassCreateInfo* pCreateInfo) diff --git a/renderdoc/driver/vulkan/vk_info.h b/renderdoc/driver/vulkan/vk_info.h index 59c0769ae..69420c3b6 100644 --- a/renderdoc/driver/vulkan/vk_info.h +++ b/renderdoc/driver/vulkan/vk_info.h @@ -156,6 +156,14 @@ struct VulkanCreationInfo { void Init(VulkanResourceManager *resourceMan, const VkPipelineLayoutCreateInfo* pCreateInfo); + struct PushConstantRange + { + uint32_t start; + uint32_t length; + VkShaderStageFlags stages; + }; + vector pushRanges; + vector descSetLayouts; }; map m_PipelineLayout; diff --git a/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp index a2e788c05..043f73b91 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp @@ -1500,7 +1500,9 @@ bool WrappedVulkan::Serialise_vkCmdPushConstants( cmdBuffer = PartialCmdBuf(); ObjDisp(cmdBuffer)->CmdPushConstants(Unwrap(cmdBuffer), Unwrap(layout), flags, s, len, vals); - // VKTODOMED update pipeline state + RDCASSERT(s+len < (uint32_t)ARRAY_COUNT(m_PartialReplayData.state.pushconsts)); + + memcpy(m_PartialReplayData.state.pushconsts + s, vals, len); } } else if(m_State == READING) @@ -1510,7 +1512,8 @@ bool WrappedVulkan::Serialise_vkCmdPushConstants( ObjDisp(cmdBuffer)->CmdPushConstants(Unwrap(cmdBuffer), Unwrap(layout), flags, s, len, vals); } - SAFE_DELETE_ARRAY(vals); + if(m_State < WRITING) + SAFE_DELETE_ARRAY(vals); return true; }