From 29e38e71a930ed34b449a6297901b5097e440758 Mon Sep 17 00:00:00 2001 From: Danylo Piliaiev Date: Fri, 30 Nov 2018 18:59:47 +0200 Subject: [PATCH] Implement VK_EXT_conditional_rendering Predicate state is displayed in the raster state. "Draw Call" and "Wireframe" overlays are visible even if predicate doesn't pass. Signed-off-by: Danylo Piliaiev --- .../VulkanPipelineStateViewer.cpp | 55 +++++- .../PipelineState/VulkanPipelineStateViewer.h | 2 + .../VulkanPipelineStateViewer.ui | 79 +++++++- renderdoc/api/replay/vk_pipestate.h | 25 +++ renderdoc/driver/vulkan/vk_common.h | 8 + renderdoc/driver/vulkan/vk_core.cpp | 12 +- renderdoc/driver/vulkan/vk_core.h | 15 ++ renderdoc/driver/vulkan/vk_hookset_defs.h | 8 +- renderdoc/driver/vulkan/vk_next_chains.cpp | 9 +- renderdoc/driver/vulkan/vk_overlay.cpp | 3 + renderdoc/driver/vulkan/vk_replay.cpp | 22 +++ renderdoc/driver/vulkan/vk_serialise.cpp | 66 ++++++- renderdoc/driver/vulkan/vk_state.cpp | 28 +++ renderdoc/driver/vulkan/vk_state.h | 13 ++ renderdoc/driver/vulkan/vk_stringise.cpp | 4 +- .../driver/vulkan/wrappers/vk_cmd_funcs.cpp | 176 +++++++++++++++++- .../vulkan/wrappers/vk_device_funcs.cpp | 8 + renderdoc/replay/renderdoc_serialise.inl | 16 +- 18 files changed, 532 insertions(+), 17 deletions(-) diff --git a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp b/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp index f609c4cd0..36f772fcc 100644 --- a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp +++ b/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp @@ -276,7 +276,7 @@ VulkanPipelineStateViewer::VulkanPipelineStateViewer(ICaptureContext &ctx, ui->scissors->setInstantTooltips(true); } - for(RDLabel *rp : {ui->renderpass, ui->framebuffer}) + for(RDLabel *rp : {ui->renderpass, ui->framebuffer, ui->predicateBuffer}) { rp->setAutoFillBackground(true); rp->setBackgroundRole(QPalette::ToolTipBase); @@ -652,6 +652,8 @@ void VulkanPipelineStateViewer::clearState() ui->depthBounds->setText(lit("0.0-1.0")); ui->stencils->clear(); + + ui->conditionalRenderingGroup->setVisible(false); } QVariantList VulkanPipelineStateViewer::makeSampler(const QString &bindset, const QString &slotname, @@ -2030,6 +2032,23 @@ void VulkanPipelineStateViewer::setState() ui->alphaToOne->setPixmap(state.colorBlend.alphaToOneEnable ? tick : cross); ui->alphaToCoverage->setPixmap(state.colorBlend.alphaToCoverageEnable ? tick : cross); + //////////////////////////////////////////////// + // Conditional Rendering + + if(state.conditionalRendering.bufferId == ResourceId()) + { + ui->conditionalRenderingGroup->setVisible(false); + } + else + { + ui->conditionalRenderingGroup->setVisible(true); + ui->predicateBuffer->setText(QFormatStr("%1 (Byte Offset %2)") + .arg(ToQStr(state.conditionalRendering.bufferId)) + .arg(state.conditionalRendering.byteOffset)); + ui->predicatePassing->setPixmap(state.conditionalRendering.isPassing ? tick : cross); + ui->predicateInverted->setPixmap(state.conditionalRendering.isInverted ? tick : cross); + } + //////////////////////////////////////////////// // Output Merger @@ -3392,6 +3411,26 @@ void VulkanPipelineStateViewer::exportHTML(QXmlStreamWriter &xml, const VKPipe:: } } +void VulkanPipelineStateViewer::exportHTML(QXmlStreamWriter &xml, + const VKPipe::ConditionalRendering &cr) +{ + if(cr.bufferId == ResourceId()) + return; + + xml.writeStartElement(lit("h3")); + xml.writeCharacters(tr("Conditional Rendering")); + xml.writeEndElement(); + + QString bufferName = m_Ctx.GetResourceName(cr.bufferId); + + m_Common.exportHTMLTable( + xml, {tr("Predicate Passing"), tr("Is Inverted"), tr("Buffer"), tr("Byte Offset")}, + { + cr.isPassing ? tr("Yes") : tr("No"), cr.isInverted ? tr("Yes") : tr("No"), bufferName, + (qulonglong)cr.byteOffset, + }); +} + void VulkanPipelineStateViewer::on_exportHTML_clicked() { QXmlStreamWriter *xmlptr = m_Common.beginHTMLExport(); @@ -3440,7 +3479,10 @@ void VulkanPipelineStateViewer::on_exportHTML_clicked() exportHTML(xml, m_Ctx.CurVulkanPipelineState()->geometryShader); exportHTML(xml, m_Ctx.CurVulkanPipelineState()->transformFeedback); break; - case 5: exportHTML(xml, m_Ctx.CurVulkanPipelineState()->rasterizer); break; + case 5: + exportHTML(xml, m_Ctx.CurVulkanPipelineState()->rasterizer); + exportHTML(xml, m_Ctx.CurVulkanPipelineState()->conditionalRendering); + break; case 6: exportHTML(xml, m_Ctx.CurVulkanPipelineState()->fragmentShader); break; case 7: // FB @@ -3477,3 +3519,12 @@ void VulkanPipelineStateViewer::on_meshView_clicked() m_Ctx.ShowMeshPreview(); ToolWindowManager::raiseToolWindow(m_Ctx.GetMeshPreview()->Widget()); } + +void VulkanPipelineStateViewer::on_predicateBufferView_clicked() +{ + const VKPipe::ConditionalRendering &cr = m_Ctx.CurVulkanPipelineState()->conditionalRendering; + + IBufferViewer *viewer = m_Ctx.ViewBuffer(cr.byteOffset, sizeof(uint32_t), cr.bufferId, "uint"); + + m_Ctx.AddDockWindow(viewer->Widget(), DockReference::AddTo, this); +} \ No newline at end of file diff --git a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.h b/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.h index cef7877a8..2d23307f7 100644 --- a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.h +++ b/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.h @@ -66,6 +66,7 @@ private slots: void on_showEmpty_toggled(bool checked); void on_exportHTML_clicked(); void on_meshView_clicked(); + void on_predicateBufferView_clicked(); void on_viAttrs_itemActivated(RDTreeWidgetItem *item, int column); void on_viBuffers_itemActivated(RDTreeWidgetItem *item, int column); void on_viAttrs_mouseMove(QMouseEvent *event); @@ -122,6 +123,7 @@ private: void exportHTML(QXmlStreamWriter &xml, const VKPipe::ColorBlendState &cb); void exportHTML(QXmlStreamWriter &xml, const VKPipe::DepthStencil &ds); void exportHTML(QXmlStreamWriter &xml, const VKPipe::CurrentPass &pass); + void exportHTML(QXmlStreamWriter &xml, const VKPipe::ConditionalRendering &cr); // keep track of the VB nodes (we want to be able to highlight them easily on hover) QList m_VBNodes; diff --git a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.ui b/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.ui index 458ffd672..18d8474f0 100644 --- a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.ui +++ b/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.ui @@ -1696,7 +1696,7 @@ 0 - + @@ -1751,7 +1751,7 @@ - + @@ -1806,6 +1806,81 @@ + + + + Conditional Rendering + + + + + + Passing: + + + + + + + + + + Inverted: + + + + + + + + + + QFrame::Box + + + 4 + + + + + + + PointingHandCursor + + + Open Predicate Buffer + + + View + + + + :/action.png:/action.png + + + Qt::ToolButtonTextBesideIcon + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + diff --git a/renderdoc/api/replay/vk_pipestate.h b/renderdoc/api/replay/vk_pipestate.h index 81f096b96..d9d4297c4 100644 --- a/renderdoc/api/replay/vk_pipestate.h +++ b/renderdoc/api/replay/vk_pipestate.h @@ -909,6 +909,27 @@ struct ImageData rdcarray layouts; }; +DOCUMENT("Contains the current conditional rendering state."); +struct ConditionalRendering +{ + DOCUMENT(""); + ConditionalRendering() = default; + ConditionalRendering(const ConditionalRendering &) = default; + + DOCUMENT( + "The :class:`ResourceId` of the buffer containing the predicate for conditional rendering."); + ResourceId bufferId; + + DOCUMENT("The byte offset into buffer where the predicate is located."); + uint64_t byteOffset = 0; + + DOCUMENT("``True`` if predicate result is inverted."); + bool isInverted = false; + + DOCUMENT("``True`` if the current predicate would render."); + bool isPassing = false; +}; + DOCUMENT("The full current Vulkan pipeline state."); struct State { @@ -967,6 +988,9 @@ struct State DOCUMENT("A list of :class:`VKImageData` entries, one for each image."); rdcarray images; + + DOCUMENT("A :class:`ConditionalRendering` describing the current conditional rendering state."); + ConditionalRendering conditionalRendering; }; }; // namespace VKPipe @@ -999,4 +1023,5 @@ DECLARE_REFLECTION_STRUCT(VKPipe::RenderArea); DECLARE_REFLECTION_STRUCT(VKPipe::CurrentPass); DECLARE_REFLECTION_STRUCT(VKPipe::ImageLayout); DECLARE_REFLECTION_STRUCT(VKPipe::ImageData); +DECLARE_REFLECTION_STRUCT(VKPipe::ConditionalRendering); DECLARE_REFLECTION_STRUCT(VKPipe::State); diff --git a/renderdoc/driver/vulkan/vk_common.h b/renderdoc/driver/vulkan/vk_common.h index 0dd9bfa9a..4d218e3ee 100644 --- a/renderdoc/driver/vulkan/vk_common.h +++ b/renderdoc/driver/vulkan/vk_common.h @@ -505,6 +505,8 @@ enum class VulkanChunk : uint32_t vkCmdBeginQueryIndexedEXT, vkCmdEndQueryIndexedEXT, vkCmdDrawIndirectByteCountEXT, + vkCmdBeginConditionalRenderingEXT, + vkCmdEndConditionalRenderingEXT, Max, }; @@ -569,9 +571,11 @@ DECLARE_REFLECTION_STRUCT(VkBufferMemoryRequirementsInfo2); DECLARE_REFLECTION_STRUCT(VkBufferViewCreateInfo); DECLARE_REFLECTION_STRUCT(VkCommandBufferAllocateInfo); DECLARE_REFLECTION_STRUCT(VkCommandBufferBeginInfo); +DECLARE_REFLECTION_STRUCT(VkCommandBufferInheritanceConditionalRenderingInfoEXT); DECLARE_REFLECTION_STRUCT(VkCommandBufferInheritanceInfo); DECLARE_REFLECTION_STRUCT(VkCommandPoolCreateInfo); DECLARE_REFLECTION_STRUCT(VkComputePipelineCreateInfo); +DECLARE_REFLECTION_STRUCT(VkConditionalRenderingBeginInfoEXT); DECLARE_REFLECTION_STRUCT(VkCopyDescriptorSet); DECLARE_REFLECTION_STRUCT(VkDebugMarkerMarkerInfoEXT); DECLARE_REFLECTION_STRUCT(VkDebugMarkerObjectNameInfoEXT); @@ -657,6 +661,7 @@ DECLARE_REFLECTION_STRUCT(VkMemoryRequirements2); DECLARE_REFLECTION_STRUCT(VkPhysicalDevice16BitStorageFeatures); DECLARE_REFLECTION_STRUCT(VkPhysicalDevice8BitStorageFeaturesKHR); DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceASTCDecodeFeaturesEXT); +DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceConditionalRenderingFeaturesEXT); DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceConservativeRasterizationPropertiesEXT); DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceDriverPropertiesKHR); DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceExternalBufferInfo); @@ -762,9 +767,11 @@ DECLARE_DESERIALISE_TYPE(VkBufferMemoryRequirementsInfo2); DECLARE_DESERIALISE_TYPE(VkBufferViewCreateInfo); DECLARE_DESERIALISE_TYPE(VkCommandBufferAllocateInfo); DECLARE_DESERIALISE_TYPE(VkCommandBufferBeginInfo); +DECLARE_DESERIALISE_TYPE(VkCommandBufferInheritanceConditionalRenderingInfoEXT); DECLARE_DESERIALISE_TYPE(VkCommandBufferInheritanceInfo); DECLARE_DESERIALISE_TYPE(VkCommandPoolCreateInfo); DECLARE_DESERIALISE_TYPE(VkComputePipelineCreateInfo); +DECLARE_DESERIALISE_TYPE(VkConditionalRenderingBeginInfoEXT); DECLARE_DESERIALISE_TYPE(VkCopyDescriptorSet); DECLARE_DESERIALISE_TYPE(VkDebugMarkerMarkerInfoEXT); DECLARE_DESERIALISE_TYPE(VkDebugMarkerObjectNameInfoEXT); @@ -850,6 +857,7 @@ DECLARE_DESERIALISE_TYPE(VkMemoryRequirements2); DECLARE_DESERIALISE_TYPE(VkPhysicalDevice16BitStorageFeatures); DECLARE_DESERIALISE_TYPE(VkPhysicalDevice8BitStorageFeaturesKHR); DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceASTCDecodeFeaturesEXT); +DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceConditionalRenderingFeaturesEXT); DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceConservativeRasterizationPropertiesEXT); DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceDriverPropertiesKHR); DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceExternalBufferInfo); diff --git a/renderdoc/driver/vulkan/vk_core.cpp b/renderdoc/driver/vulkan/vk_core.cpp index 35caf3519..e04c4c67d 100644 --- a/renderdoc/driver/vulkan/vk_core.cpp +++ b/renderdoc/driver/vulkan/vk_core.cpp @@ -635,6 +635,9 @@ static const VkExtensionProperties supportedExtensions[] = { { VK_EXT_ASTC_DECODE_MODE_EXTENSION_NAME, VK_EXT_ASTC_DECODE_MODE_SPEC_VERSION, }, + { + VK_EXT_CONDITIONAL_RENDERING_EXTENSION_NAME, VK_EXT_CONDITIONAL_RENDERING_SPEC_VERSION, + }, { VK_EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME, VK_EXT_CONSERVATIVE_RASTERIZATION_SPEC_VERSION, @@ -2682,7 +2685,10 @@ bool WrappedVulkan::ProcessChunk(ReadSerialiser &ser, VulkanChunk chunk) case VulkanChunk::vkCmdDrawIndirectByteCountEXT: return Serialise_vkCmdDrawIndirectByteCountEXT(ser, VK_NULL_HANDLE, 0, 0, VK_NULL_HANDLE, 0, 0, 0); - + case VulkanChunk::vkCmdBeginConditionalRenderingEXT: + return Serialise_vkCmdBeginConditionalRenderingEXT(ser, VK_NULL_HANDLE, NULL); + case VulkanChunk::vkCmdEndConditionalRenderingEXT: + return Serialise_vkCmdEndConditionalRenderingEXT(ser, VK_NULL_HANDLE); default: { SystemChunk system = (SystemChunk)chunk; @@ -2895,6 +2901,10 @@ void WrappedVulkan::ReplayLog(uint32_t startEventID, uint32_t endEventID, Replay if(!m_RenderState.xfbcounters.empty()) m_RenderState.EndTransformFeedback(cmd); + // end any active conditional rendering + if(m_RenderState.IsConditionalRenderingEnabled()) + m_RenderState.EndConditionalRendering(cmd); + // 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 we began our own custom single-draw loadrp, and it was ended by a CmdEndRenderPass, diff --git a/renderdoc/driver/vulkan/vk_core.h b/renderdoc/driver/vulkan/vk_core.h index ec98a05c4..43685adb1 100644 --- a/renderdoc/driver/vulkan/vk_core.h +++ b/renderdoc/driver/vulkan/vk_core.h @@ -528,6 +528,8 @@ private: VkCommandBufferLevel level; VkCommandBufferUsageFlags beginFlags; + bool inheritConditionalRendering = false; + int markerCount; std::vector> resourceUsage; @@ -553,6 +555,13 @@ private: ResourceId renderPass; ResourceId framebuffer; uint32_t subpass = 0; + + struct ConditionalRendering + { + ResourceId buffer; + VkDeviceSize offset; + VkConditionalRenderingFlagsEXT flags; + } conditionalRendering; } state; std::vector> imgbarriers; @@ -1980,4 +1989,10 @@ public: uint32_t instanceCount, uint32_t firstInstance, VkBuffer counterBuffer, VkDeviceSize counterBufferOffset, uint32_t counterOffset, uint32_t vertexStride); + + // VK_EXT_conditional_rendering + IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdBeginConditionalRenderingEXT, + VkCommandBuffer commandBuffer, + const VkConditionalRenderingBeginInfoEXT *pConditionalRenderingBegin); + IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdEndConditionalRenderingEXT, VkCommandBuffer commandBuffer); }; diff --git a/renderdoc/driver/vulkan/vk_hookset_defs.h b/renderdoc/driver/vulkan/vk_hookset_defs.h index b78df2307..c53e99e7c 100644 --- a/renderdoc/driver/vulkan/vk_hookset_defs.h +++ b/renderdoc/driver/vulkan/vk_hookset_defs.h @@ -353,7 +353,8 @@ CheckExt(EXT_validation_cache, VKXX); \ CheckExt(KHR_shared_presentable_image, VKXX); \ CheckExt(KHR_create_renderpass2, VKXX); \ - CheckExt(EXT_transform_feedback, VKXX); + CheckExt(EXT_transform_feedback, VKXX); \ + CheckExt(EXT_conditional_rendering, VKXX); #define HookInitVulkanInstanceExts() \ HookInitExtension(KHR_surface, DestroySurfaceKHR); \ @@ -480,6 +481,8 @@ HookInitExtension(EXT_transform_feedback, CmdBeginQueryIndexedEXT); \ HookInitExtension(EXT_transform_feedback, CmdEndQueryIndexedEXT); \ HookInitExtension(EXT_transform_feedback, CmdDrawIndirectByteCountEXT); \ + HookInitExtension(EXT_conditional_rendering, CmdBeginConditionalRenderingEXT); \ + HookInitExtension(EXT_conditional_rendering, CmdEndConditionalRenderingEXT); \ HookInitDevice_PlatformSpecific() #define DefineHooks() \ @@ -1033,6 +1036,9 @@ HookDefine7(void, vkCmdDrawIndirectByteCountEXT, VkCommandBuffer, commandBuffer, uint32_t, \ instanceCount, uint32_t, firstInstance, VkBuffer, counterBuffer, VkDeviceSize, \ counterBufferOffset, uint32_t, counterOffset, uint32_t, vertexStride); \ + HookDefine2(void, vkCmdBeginConditionalRenderingEXT, VkCommandBuffer, commandBuffer, \ + const VkConditionalRenderingBeginInfoEXT *, pConditionalRenderingBegin); \ + HookDefine1(void, vkCmdEndConditionalRenderingEXT, VkCommandBuffer, commandBuffer); \ HookDefine_PlatformSpecific() struct VkLayerInstanceDispatchTableExtended : VkLayerInstanceDispatchTable diff --git a/renderdoc/driver/vulkan/vk_next_chains.cpp b/renderdoc/driver/vulkan/vk_next_chains.cpp index 8f27bb28e..4aa8021e3 100644 --- a/renderdoc/driver/vulkan/vk_next_chains.cpp +++ b/renderdoc/driver/vulkan/vk_next_chains.cpp @@ -82,6 +82,8 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct, COPY_STRUCT(VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO, VkBindImagePlaneMemoryInfo); \ COPY_STRUCT(VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, VkBufferCreateInfo); \ COPY_STRUCT(VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, VkCommandBufferBeginInfo); \ + COPY_STRUCT(VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_CONDITIONAL_RENDERING_INFO_EXT, \ + VkCommandBufferInheritanceConditionalRenderingInfoEXT); \ COPY_STRUCT(VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, VkCommandPoolCreateInfo); \ COPY_STRUCT(VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT, VkDebugMarkerMarkerInfoEXT); \ COPY_STRUCT(VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT, \ @@ -202,6 +204,8 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct, VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT); \ COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR, \ VkPhysicalDeviceVulkanMemoryModelFeaturesKHR); \ + COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT, \ + VkPhysicalDeviceConditionalRenderingFeaturesEXT); \ COPY_STRUCT(VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO, VkPipelineCacheCreateInfo); \ COPY_STRUCT(VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, \ VkPipelineColorBlendStateCreateInfo); \ @@ -332,6 +336,8 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct, UnwrapInPlace(out->renderPass), UnwrapInPlace(out->framebuffer)); \ UNWRAP_STRUCT(VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO, VkSamplerYcbcrConversionInfo, \ UnwrapInPlace(out->conversion)); \ + UNWRAP_STRUCT(VK_STRUCTURE_TYPE_CONDITIONAL_RENDERING_BEGIN_INFO_EXT, \ + VkConditionalRenderingBeginInfoEXT, UnwrapInPlace(out->buffer)); \ UNWRAP_STRUCT_CAPTURE_ONLY(VK_STRUCTURE_TYPE_ACQUIRE_NEXT_IMAGE_INFO_KHR, \ VkAcquireNextImageInfoKHR, UnwrapInPlace(out->swapchain), \ UnwrapInPlace(out->semaphore), UnwrapInPlace(out->fence)); \ @@ -383,8 +389,6 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct, case VK_STRUCTURE_TYPE_CHECKPOINT_DATA_NV: \ case VK_STRUCTURE_TYPE_CMD_PROCESS_COMMANDS_INFO_NVX: \ case VK_STRUCTURE_TYPE_CMD_RESERVE_SPACE_FOR_COMMANDS_INFO_NVX: \ - case VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_CONDITIONAL_RENDERING_INFO_EXT: \ - case VK_STRUCTURE_TYPE_CONDITIONAL_RENDERING_BEGIN_INFO_EXT: \ case VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO_EXT: \ case VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT: \ case VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO_EXT: \ @@ -413,7 +417,6 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct, case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT: \ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_PROPERTIES_EXT: \ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_SHADER_DERIVATIVES_FEATURES_NV: \ - case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT: \ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CORNER_SAMPLED_IMAGE_FEATURES_NV: \ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT: \ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT: \ diff --git a/renderdoc/driver/vulkan/vk_overlay.cpp b/renderdoc/driver/vulkan/vk_overlay.cpp index 5fd791c3e..1475bd365 100644 --- a/renderdoc/driver/vulkan/vk_overlay.cpp +++ b/renderdoc/driver/vulkan/vk_overlay.cpp @@ -845,6 +845,9 @@ ResourceId VulkanReplay::RenderOverlay(ResourceId texid, CompType typeHint, Debu if(overlay == DebugOverlay::Wireframe) m_pDriver->m_RenderState.lineWidth = 1.0f; + if(overlay == DebugOverlay::Drawcall || overlay == DebugOverlay::Wireframe) + m_pDriver->m_RenderState.conditionalRendering.forceDisable = true; + if(patchedIndexCount == 0) { m_pDriver->ReplayLog(0, eventId, eReplay_OnlyDraw); diff --git a/renderdoc/driver/vulkan/vk_replay.cpp b/renderdoc/driver/vulkan/vk_replay.cpp index dc92a4ad5..6634182af 100644 --- a/renderdoc/driver/vulkan/vk_replay.cpp +++ b/renderdoc/driver/vulkan/vk_replay.cpp @@ -1573,6 +1573,28 @@ void VulkanReplay::SavePipelineState() 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 = + state.conditionalRendering.flags == VK_CONDITIONAL_RENDERING_INVERTED_BIT_EXT; + + bytebuf data; + GetBufferData(state.conditionalRendering.buffer, state.conditionalRendering.offset, + sizeof(uint32_t), data); + + uint32_t value; + memcpy(&value, data.data(), sizeof(uint32_t)); + + m_VulkanPipelineState.conditionalRendering.isPassing = value != 0; + + if(m_VulkanPipelineState.conditionalRendering.isInverted) + m_VulkanPipelineState.conditionalRendering.isPassing = + !m_VulkanPipelineState.conditionalRendering.isPassing; + } } void VulkanReplay::FillCBufferVariables(ResourceId shader, string entryPoint, uint32_t cbufSlot, diff --git a/renderdoc/driver/vulkan/vk_serialise.cpp b/renderdoc/driver/vulkan/vk_serialise.cpp index c49fc4765..4174ec5c3 100644 --- a/renderdoc/driver/vulkan/vk_serialise.cpp +++ b/renderdoc/driver/vulkan/vk_serialise.cpp @@ -279,6 +279,14 @@ SERIALISE_VK_HANDLES(); PNEXT_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ASTC_DECODE_FEATURES_EXT, \ VkPhysicalDeviceASTCDecodeFeaturesEXT) \ \ + /* VK_EXT_conditional_rendering */ \ + PNEXT_STRUCT(VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_CONDITIONAL_RENDERING_INFO_EXT, \ + VkCommandBufferInheritanceConditionalRenderingInfoEXT) \ + PNEXT_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT, \ + VkPhysicalDeviceConditionalRenderingFeaturesEXT) \ + PNEXT_STRUCT(VK_STRUCTURE_TYPE_CONDITIONAL_RENDERING_BEGIN_INFO_EXT, \ + VkConditionalRenderingBeginInfoEXT) \ + \ /* VK_EXT_conservative_rasterization */ \ PNEXT_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONSERVATIVE_RASTERIZATION_PROPERTIES_EXT, \ VkPhysicalDeviceConservativeRasterizationPropertiesEXT) \ @@ -601,11 +609,6 @@ SERIALISE_VK_HANDLES(); /* VK_EXT_calibrated_timestamps */ \ PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_CALIBRATED_TIMESTAMP_INFO_EXT) \ \ - /* VK_EXT_conditional_rendering */ \ - PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_CONDITIONAL_RENDERING_INFO_EXT) \ - PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT) \ - PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_CONDITIONAL_RENDERING_BEGIN_INFO_EXT) \ - \ /* VK_EXT_descriptor_indexing */ \ PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT) \ PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT) \ @@ -5551,6 +5554,56 @@ void Deserialise(const VkPhysicalDeviceSparseImageFormatInfo2 &el) DeserialiseNext(el.pNext); } +template +void DoSerialise(SerialiserType &ser, VkCommandBufferInheritanceConditionalRenderingInfoEXT &el) +{ + RDCASSERT(ser.IsReading() || + el.sType == VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_CONDITIONAL_RENDERING_INFO_EXT); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER(conditionalRenderingEnable); +} + +template <> +void Deserialise(const VkCommandBufferInheritanceConditionalRenderingInfoEXT &el) +{ + DeserialiseNext(el.pNext); +} + +template +void DoSerialise(SerialiserType &ser, VkPhysicalDeviceConditionalRenderingFeaturesEXT &el) +{ + RDCASSERT(ser.IsReading() || + el.sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER(conditionalRendering); + SERIALISE_MEMBER(inheritedConditionalRendering); +} + +template <> +void Deserialise(const VkPhysicalDeviceConditionalRenderingFeaturesEXT &el) +{ + DeserialiseNext(el.pNext); +} + +template +void DoSerialise(SerialiserType &ser, VkConditionalRenderingBeginInfoEXT &el) +{ + RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_CONDITIONAL_RENDERING_BEGIN_INFO_EXT); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER(buffer); + SERIALISE_MEMBER(offset); + SERIALISE_MEMBER_TYPED(VkConditionalRenderingFlagsEXT, flags); +} + +template <> +void Deserialise(const VkConditionalRenderingBeginInfoEXT &el) +{ + DeserialiseNext(el.pNext); +} + // pNext structs - always have deserialise for the next chain INSTANTIATE_SERIALISE_TYPE(VkAcquireNextImageInfoKHR); INSTANTIATE_SERIALISE_TYPE(VkApplicationInfo); @@ -5570,6 +5623,7 @@ INSTANTIATE_SERIALISE_TYPE(VkBufferViewCreateInfo); INSTANTIATE_SERIALISE_TYPE(VkCommandBufferAllocateInfo); INSTANTIATE_SERIALISE_TYPE(VkCommandBufferBeginInfo); INSTANTIATE_SERIALISE_TYPE(VkCommandBufferInheritanceInfo); +INSTANTIATE_SERIALISE_TYPE(VkCommandBufferInheritanceConditionalRenderingInfoEXT); INSTANTIATE_SERIALISE_TYPE(VkCommandPoolCreateInfo); INSTANTIATE_SERIALISE_TYPE(VkComputePipelineCreateInfo); INSTANTIATE_SERIALISE_TYPE(VkCopyDescriptorSet); @@ -5691,6 +5745,7 @@ INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceVariablePointerFeatures); INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT); INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT); INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceVulkanMemoryModelFeaturesKHR); +INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceConditionalRenderingFeaturesEXT); INSTANTIATE_SERIALISE_TYPE(VkPipelineCacheCreateInfo); INSTANTIATE_SERIALISE_TYPE(VkPipelineColorBlendStateCreateInfo); INSTANTIATE_SERIALISE_TYPE(VkPipelineDepthStencilStateCreateInfo); @@ -5743,6 +5798,7 @@ INSTANTIATE_SERIALISE_TYPE(VkTextureLODGatherFormatPropertiesAMD); INSTANTIATE_SERIALISE_TYPE(VkValidationCacheCreateInfoEXT); INSTANTIATE_SERIALISE_TYPE(VkValidationFlagsEXT); INSTANTIATE_SERIALISE_TYPE(VkWriteDescriptorSet); +INSTANTIATE_SERIALISE_TYPE(VkConditionalRenderingBeginInfoEXT); // plain structs with no next chain INSTANTIATE_SERIALISE_TYPE(VkAllocationCallbacks); diff --git a/renderdoc/driver/vulkan/vk_state.cpp b/renderdoc/driver/vulkan/vk_state.cpp index 0ad42fd41..e8af4ba82 100644 --- a/renderdoc/driver/vulkan/vk_state.cpp +++ b/renderdoc/driver/vulkan/vk_state.cpp @@ -52,6 +52,8 @@ VulkanRenderState::VulkanRenderState(WrappedVulkan *driver, VulkanCreationInfo * RDCEraseEl(ibuffer); vbuffers.clear(); + + RDCEraseEl(conditionalRendering); } VulkanRenderState &VulkanRenderState::operator=(const VulkanRenderState &o) @@ -80,6 +82,8 @@ VulkanRenderState &VulkanRenderState::operator=(const VulkanRenderState &o) ibuffer = o.ibuffer; vbuffers = o.vbuffers; + conditionalRendering = o.conditionalRendering; + return *this; } @@ -151,6 +155,19 @@ void VulkanRenderState::BeginRenderPassAndApplyState(VkCommandBuffer cmd, Pipeli ObjDisp(cmd)->CmdBeginTransformFeedbackEXT( Unwrap(cmd), firstxfbcounter, (uint32_t)xfbcounters.size(), buffers.data(), offsets.data()); } + + if(IsConditionalRenderingEnabled()) + { + VkConditionalRenderingBeginInfoEXT beginInfo; + beginInfo.sType = VK_STRUCTURE_TYPE_CONDITIONAL_RENDERING_BEGIN_INFO_EXT; + beginInfo.pNext = VK_NULL_HANDLE; + beginInfo.buffer = + Unwrap(GetResourceManager()->GetCurrentHandle(conditionalRendering.buffer)); + beginInfo.offset = conditionalRendering.offset; + beginInfo.flags = conditionalRendering.flags; + + ObjDisp(cmd)->CmdBeginConditionalRenderingEXT(Unwrap(cmd), &beginInfo); + } } void VulkanRenderState::EndRenderPass(VkCommandBuffer cmd) @@ -177,6 +194,17 @@ void VulkanRenderState::EndTransformFeedback(VkCommandBuffer cmd) } } +void VulkanRenderState::EndConditionalRendering(VkCommandBuffer cmd) +{ + if(IsConditionalRenderingEnabled()) + ObjDisp(cmd)->CmdEndConditionalRenderingEXT(Unwrap(cmd)); +} + +bool VulkanRenderState::IsConditionalRenderingEnabled() +{ + return conditionalRendering.buffer != ResourceId() && !conditionalRendering.forceDisable; +} + void VulkanRenderState::BindPipeline(VkCommandBuffer cmd, PipelineBinding binding, bool subpass0) { if(graphics.pipeline != ResourceId() && binding == BindGraphics) diff --git a/renderdoc/driver/vulkan/vk_state.h b/renderdoc/driver/vulkan/vk_state.h index 000b0b556..525dc0621 100644 --- a/renderdoc/driver/vulkan/vk_state.h +++ b/renderdoc/driver/vulkan/vk_state.h @@ -51,11 +51,15 @@ struct VulkanRenderState void EndTransformFeedback(VkCommandBuffer cmd); + void EndConditionalRendering(VkCommandBuffer cmd); + void BindPipeline(VkCommandBuffer cmd, PipelineBinding binding, bool subpass0); void BindDescriptorSet(const DescSetLayout &descLayout, VkCommandBuffer cmd, VkPipelineLayout layout, VkPipelineBindPoint bindPoint, uint32_t setIndex, uint32_t *dynamicOffsets); + bool IsConditionalRenderingEnabled(); + // dynamic state vector views; vector scissors; @@ -124,6 +128,15 @@ struct VulkanRenderState uint32_t firstxfbcounter = 0; vector xfbcounters; + struct ConditionalRendering + { + ResourceId buffer; + VkDeviceSize offset; + VkConditionalRenderingFlagsEXT flags; + + bool forceDisable; + } conditionalRendering; + VulkanResourceManager *GetResourceManager(); VulkanCreationInfo *m_CreationInfo; WrappedVulkan *m_pDriver; diff --git a/renderdoc/driver/vulkan/vk_stringise.cpp b/renderdoc/driver/vulkan/vk_stringise.cpp index 44aa9a2e2..2df9c9715 100644 --- a/renderdoc/driver/vulkan/vk_stringise.cpp +++ b/renderdoc/driver/vulkan/vk_stringise.cpp @@ -28,7 +28,7 @@ template <> std::string DoStringise(const VulkanChunk &el) { - RDCCOMPILE_ASSERT((uint32_t)VulkanChunk::Max == 1128, "Chunks changed without updating names"); + RDCCOMPILE_ASSERT((uint32_t)VulkanChunk::Max == 1130, "Chunks changed without updating names"); BEGIN_ENUM_STRINGISE(VulkanChunk) { @@ -160,6 +160,8 @@ std::string DoStringise(const VulkanChunk &el) STRINGISE_ENUM_CLASS(vkCmdBeginQueryIndexedEXT) STRINGISE_ENUM_CLASS(vkCmdEndQueryIndexedEXT) STRINGISE_ENUM_CLASS(vkCmdDrawIndirectByteCountEXT) + STRINGISE_ENUM_CLASS(vkCmdBeginConditionalRenderingEXT) + STRINGISE_ENUM_CLASS(vkCmdEndConditionalRenderingEXT) STRINGISE_ENUM_CLASS_NAMED(Max, "Max Chunk"); } END_ENUM_STRINGISE() diff --git a/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp index 94e1c5c17..a8ad95f3e 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp @@ -633,6 +633,15 @@ bool WrappedVulkan::Serialise_vkBeginCommandBuffer(SerialiserType &ser, VkComman unwrappedInheritInfo.renderPass = Unwrap(unwrappedInheritInfo.renderPass); unwrappedBeginInfo.pInheritanceInfo = &unwrappedInheritInfo; + + VkCommandBufferInheritanceConditionalRenderingInfoEXT *inheritanceConditionalRenderingInfo = + (VkCommandBufferInheritanceConditionalRenderingInfoEXT *)FindNextStruct( + BeginInfo.pInheritanceInfo, + VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_CONDITIONAL_RENDERING_INFO_EXT); + + if(inheritanceConditionalRenderingInfo) + m_BakedCmdBufferInfo[BakedCommandBuffer].inheritConditionalRendering = + inheritanceConditionalRenderingInfo->conditionalRenderingEnable == VK_TRUE; } byte *tempMem = GetTempMemory(GetNextPatchSize(unwrappedBeginInfo.pNext)); @@ -667,6 +676,7 @@ bool WrappedVulkan::Serialise_vkBeginCommandBuffer(SerialiserType &ser, VkComman m_Partial[p].baseEvent = it->baseEvent; m_Partial[p].renderPassActive = false; m_RenderState.xfbcounters.clear(); + m_RenderState.conditionalRendering.buffer = ResourceId(); rerecord = true; partial = true; @@ -915,6 +925,12 @@ bool WrappedVulkan::Serialise_vkEndCommandBuffer(SerialiserType &ser, VkCommandB m_RenderState.EndTransformFeedback(commandBuffer); } + if(m_Partial[Primary].partialParent == BakedCommandBuffer && + m_RenderState.IsConditionalRenderingEnabled()) + { + m_RenderState.EndConditionalRendering(commandBuffer); + } + // finish any render pass that was still active in the primary partial parent if(m_Partial[Primary].partialParent == BakedCommandBuffer && m_Partial[Primary].renderPassActive) @@ -3083,6 +3099,19 @@ bool WrappedVulkan::Serialise_vkCmdExecuteCommands(SerialiserType &ser, VkComman m_BakedCmdBufferInfo[cmd].state.subpass = parentCmdBufInfo.state.subpass; m_BakedCmdBufferInfo[cmd].state.framebuffer = parentCmdBufInfo.state.framebuffer; + // propagate conditional rendering + if(m_BakedCmdBufferInfo[cmd].inheritConditionalRendering && + parentCmdBufInfo.state.conditionalRendering.buffer != ResourceId() && + (startEID + m_BakedCmdBufferInfo[cmd].eventCount >= m_LastEventID)) + { + m_RenderState.conditionalRendering.buffer = + parentCmdBufInfo.state.conditionalRendering.buffer; + m_RenderState.conditionalRendering.offset = + parentCmdBufInfo.state.conditionalRendering.offset; + m_RenderState.conditionalRendering.flags = + parentCmdBufInfo.state.conditionalRendering.flags; + } + // 2 extra for the virtual labels around the command buffer parentCmdBufInfo.curEventID += 2 + m_BakedCmdBufferInfo[cmd].eventCount; } @@ -4739,6 +4768,146 @@ void WrappedVulkan::vkCmdEndQueryIndexedEXT(VkCommandBuffer commandBuffer, VkQue } } +template +bool WrappedVulkan::Serialise_vkCmdBeginConditionalRenderingEXT( + SerialiserType &ser, VkCommandBuffer commandBuffer, + const VkConditionalRenderingBeginInfoEXT *pConditionalRenderingBegin) +{ + SERIALISE_ELEMENT(commandBuffer); + SERIALISE_ELEMENT_LOCAL(BeginInfo, *pConditionalRenderingBegin); + + Serialise_DebugMessages(ser); + + SERIALISE_CHECK_READ_ERRORS(); + + if(IsReplayingAndReading()) + { + m_LastCmdBufferID = GetResourceManager()->GetOriginalID(GetResID(commandBuffer)); + + if(IsActiveReplaying(m_State)) + { + if(InRerecordRange(m_LastCmdBufferID)) + { + commandBuffer = RerecordCmdBuf(m_LastCmdBufferID); + + if(ShouldUpdateRenderState(m_LastCmdBufferID)) + { + m_RenderState.conditionalRendering.buffer = GetResID(BeginInfo.buffer); + m_RenderState.conditionalRendering.offset = BeginInfo.offset; + m_RenderState.conditionalRendering.flags = BeginInfo.flags; + } + + m_BakedCmdBufferInfo[m_LastCmdBufferID].state.conditionalRendering.buffer = + GetResID(BeginInfo.buffer); + m_BakedCmdBufferInfo[m_LastCmdBufferID].state.conditionalRendering.offset = BeginInfo.offset; + m_BakedCmdBufferInfo[m_LastCmdBufferID].state.conditionalRendering.flags = BeginInfo.flags; + + BeginInfo.buffer = Unwrap(BeginInfo.buffer); + ObjDisp(commandBuffer)->CmdBeginConditionalRenderingEXT(Unwrap(commandBuffer), &BeginInfo); + } + } + else + { + m_BakedCmdBufferInfo[m_LastCmdBufferID].state.conditionalRendering.buffer = + GetResID(BeginInfo.buffer); + m_BakedCmdBufferInfo[m_LastCmdBufferID].state.conditionalRendering.offset = BeginInfo.offset; + m_BakedCmdBufferInfo[m_LastCmdBufferID].state.conditionalRendering.flags = BeginInfo.flags; + + BeginInfo.buffer = Unwrap(BeginInfo.buffer); + ObjDisp(commandBuffer)->CmdBeginConditionalRenderingEXT(Unwrap(commandBuffer), &BeginInfo); + } + } + + return true; +} + +void WrappedVulkan::vkCmdBeginConditionalRenderingEXT( + VkCommandBuffer commandBuffer, + const VkConditionalRenderingBeginInfoEXT *pConditionalRenderingBegin) +{ + SCOPED_DBG_SINK(); + + VkConditionalRenderingBeginInfoEXT unwrappedConditionalRenderingBegin = *pConditionalRenderingBegin; + unwrappedConditionalRenderingBegin.buffer = Unwrap(unwrappedConditionalRenderingBegin.buffer); + + SERIALISE_TIME_CALL(ObjDisp(commandBuffer) + ->CmdBeginConditionalRenderingEXT(Unwrap(commandBuffer), + &unwrappedConditionalRenderingBegin)); + + if(IsCaptureMode(m_State)) + { + VkResourceRecord *record = GetRecord(commandBuffer); + + CACHE_THREAD_SERIALISER(); + + SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdBeginConditionalRenderingEXT); + Serialise_vkCmdBeginConditionalRenderingEXT(ser, commandBuffer, pConditionalRenderingBegin); + + record->AddChunk(scope.Get()); + + VkResourceRecord *buf = GetRecord(pConditionalRenderingBegin->buffer); + + record->MarkResourceFrameReferenced(buf->GetResourceID(), eFrameRef_Read); + record->MarkResourceFrameReferenced(buf->baseResource, eFrameRef_Read); + } +} + +template +bool WrappedVulkan::Serialise_vkCmdEndConditionalRenderingEXT(SerialiserType &ser, + VkCommandBuffer commandBuffer) +{ + SERIALISE_ELEMENT(commandBuffer); + + Serialise_DebugMessages(ser); + + SERIALISE_CHECK_READ_ERRORS(); + + if(IsReplayingAndReading()) + { + m_LastCmdBufferID = GetResourceManager()->GetOriginalID(GetResID(commandBuffer)); + + if(IsActiveReplaying(m_State)) + { + if(InRerecordRange(m_LastCmdBufferID)) + { + commandBuffer = RerecordCmdBuf(m_LastCmdBufferID); + + if(ShouldUpdateRenderState(m_LastCmdBufferID)) + m_RenderState.conditionalRendering.buffer = ResourceId(); + + m_BakedCmdBufferInfo[m_LastCmdBufferID].state.conditionalRendering.buffer = ResourceId(); + ObjDisp(commandBuffer)->CmdEndConditionalRenderingEXT(Unwrap(commandBuffer)); + } + } + else + { + m_BakedCmdBufferInfo[m_LastCmdBufferID].state.conditionalRendering.buffer = ResourceId(); + ObjDisp(commandBuffer)->CmdEndConditionalRenderingEXT(Unwrap(commandBuffer)); + } + } + + return true; +} + +void WrappedVulkan::vkCmdEndConditionalRenderingEXT(VkCommandBuffer commandBuffer) +{ + SCOPED_DBG_SINK(); + + SERIALISE_TIME_CALL(ObjDisp(commandBuffer)->CmdEndConditionalRenderingEXT(Unwrap(commandBuffer))); + + if(IsCaptureMode(m_State)) + { + VkResourceRecord *record = GetRecord(commandBuffer); + + CACHE_THREAD_SERIALISER(); + + SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdEndConditionalRenderingEXT); + Serialise_vkCmdEndConditionalRenderingEXT(ser, commandBuffer); + + record->AddChunk(scope.Get()); + } +} + INSTANTIATE_FUNCTION_SERIALISED(VkResult, vkCreateCommandPool, VkDevice device, const VkCommandPoolCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkCommandPool *pCommandPool); @@ -4877,4 +5046,9 @@ INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdBeginQueryIndexedEXT, VkCommandBuffer VkQueryPool queryPool, uint32_t query, VkQueryControlFlags flags, uint32_t index); INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdEndQueryIndexedEXT, VkCommandBuffer commandBuffer, - VkQueryPool queryPool, uint32_t query, uint32_t index); \ No newline at end of file + VkQueryPool queryPool, uint32_t query, uint32_t index); + +INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdBeginConditionalRenderingEXT, + VkCommandBuffer commandBuffer, + const VkConditionalRenderingBeginInfoEXT *pConditionalRenderingBegin); +INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdEndConditionalRenderingEXT, VkCommandBuffer commandBuffer); \ No newline at end of file diff --git a/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp index 6904b5e39..e8e0adc10 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp @@ -1673,6 +1673,14 @@ bool WrappedVulkan::Serialise_vkCreateDevice(SerialiserType &ser, VkPhysicalDevi CHECK_PHYS_EXT_FEATURE(vulkanMemoryModelDeviceScope); } END_PHYS_EXT_CHECK(); + + BEGIN_PHYS_EXT_CHECK(VkPhysicalDeviceConditionalRenderingFeaturesEXT, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT); + { + CHECK_PHYS_EXT_FEATURE(conditionalRendering); + CHECK_PHYS_EXT_FEATURE(inheritedConditionalRendering); + } + END_PHYS_EXT_CHECK(); } if(availFeatures.depthClamp) diff --git a/renderdoc/replay/renderdoc_serialise.inl b/renderdoc/replay/renderdoc_serialise.inl index c9163cbcb..74ed03da5 100644 --- a/renderdoc/replay/renderdoc_serialise.inl +++ b/renderdoc/replay/renderdoc_serialise.inl @@ -2128,6 +2128,17 @@ void DoSerialise(SerialiserType &ser, VKPipe::ImageData &el) SIZE_CHECK(24); } +template +void DoSerialise(SerialiserType &ser, VKPipe::ConditionalRendering &el) +{ + SERIALISE_MEMBER(bufferId); + SERIALISE_MEMBER(byteOffset); + SERIALISE_MEMBER(isInverted); + SERIALISE_MEMBER(isPassing); + + SIZE_CHECK(24); +} + template void DoSerialise(SerialiserType &ser, VKPipe::State &el) { @@ -2157,7 +2168,9 @@ void DoSerialise(SerialiserType &ser, VKPipe::State &el) SERIALISE_MEMBER(images); - SIZE_CHECK(1360); + SERIALISE_MEMBER(conditionalRendering); + + SIZE_CHECK(1384); } #pragma endregion Vulkan pipeline state @@ -2264,4 +2277,5 @@ INSTANTIATE_SERIALISE_TYPE(VKPipe::DepthStencil) INSTANTIATE_SERIALISE_TYPE(VKPipe::CurrentPass) INSTANTIATE_SERIALISE_TYPE(VKPipe::ImageLayout) INSTANTIATE_SERIALISE_TYPE(VKPipe::ImageData) +INSTANTIATE_SERIALISE_TYPE(VKPipe::ConditionalRendering) INSTANTIATE_SERIALISE_TYPE(VKPipe::State) \ No newline at end of file