Skip to content

Commit

Permalink
Support VK_KHR_dynamic_rendering_local_read
Browse files Browse the repository at this point in the history
Fixes #3341
  • Loading branch information
ShabbyX committed Oct 24, 2024
1 parent e6d0d57 commit 6fbacc5
Show file tree
Hide file tree
Showing 19 changed files with 701 additions and 17 deletions.
96 changes: 90 additions & 6 deletions qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ Q_DECLARE_METATYPE(CombinedSamplerData);

namespace
{
constexpr uint32_t VK_ATTACHMENT_UNUSED = ~0U;

QString getTextureRenderSamples(const TextureDescription *tex, const VKPipe::RenderPass &renderpass)
{
const uint32_t texSamples = tex ? tex->msSamp : 1;
Expand Down Expand Up @@ -2614,12 +2616,32 @@ void VulkanPipelineStateViewer::setState()
{
slotname = QFormatStr("Color %1").arg(a.localIdx);

// With dynamic rendering, the API references the framebuffer index everywhere, for
// example when specifying blend state for attachments or with vkCmdClearAttachments. As
// such, RenderDoc shows the same index in Color attachments (i.e. fbIdx == localIdx) to
// avoid confusion, even when VK_KHR_dynamic_rendering_local_read maps these attachments
// to different "locations" used by the shader. In that case, the mapped location is
// shown besides the attachment index.
uint32_t location = a.localIdx;
if(a.fbIdx < rp.colorAttachmentLocations.count())
{
location = rp.colorAttachmentLocations[a.fbIdx];
if(location == VK_ATTACHMENT_UNUSED)
{
slotname += QFormatStr(" [disabled]");
}
else
{
slotname += QFormatStr(" [location %1]").arg(location);
}
}

if(state.fragmentShader.reflection != NULL)
{
const rdcarray<SigParameter> &outSig = state.fragmentShader.reflection->outputSignature;
for(int s = 0; s < outSig.count(); s++)
{
if(outSig[s].regIndex == (uint32_t)a.localIdx &&
if(outSig[s].regIndex == location &&
(outSig[s].systemValue == ShaderBuiltin::Undefined ||
outSig[s].systemValue == ShaderBuiltin::ColorOutput))
{
Expand Down Expand Up @@ -2819,6 +2841,22 @@ void VulkanPipelineStateViewer::setState()

if(showNode(usedSlot, /*filledSlot*/ true))
{
QString writemask = QFormatStr("%1%2%3%4")
.arg((blend.writeMask & 0x1) == 0 ? lit("_") : lit("R"))
.arg((blend.writeMask & 0x2) == 0 ? lit("_") : lit("G"))
.arg((blend.writeMask & 0x4) == 0 ? lit("_") : lit("B"))
.arg((blend.writeMask & 0x8) == 0 ? lit("_") : lit("A"));

// With VK_KHR_dynamic_rendering_local_read, if a color attachment is mapped to
// VK_ATTACHMENT_UNUSED, it is implicitly disabled. The Slot name in the "Render Pass"
// pane already tags the attachment with [disabled], so the write mask is simply set to
// ____ here.
if(i < rp.colorAttachmentLocations.count() &&
rp.colorAttachmentLocations[i] == VK_ATTACHMENT_UNUSED)
{
writemask = lit("____");
}

RDTreeWidgetItem *node = new RDTreeWidgetItem(
{i, blend.enabled ? tr("True") : tr("False"),

Expand All @@ -2828,11 +2866,7 @@ void VulkanPipelineStateViewer::setState()
ToQStr(blend.alphaBlend.source), ToQStr(blend.alphaBlend.destination),
ToQStr(blend.alphaBlend.operation),

QFormatStr("%1%2%3%4")
.arg((blend.writeMask & 0x1) == 0 ? lit("_") : lit("R"))
.arg((blend.writeMask & 0x2) == 0 ? lit("_") : lit("G"))
.arg((blend.writeMask & 0x4) == 0 ? lit("_") : lit("B"))
.arg((blend.writeMask & 0x8) == 0 ? lit("_") : lit("A"))});
writemask});

if(!usedSlot)
setInactiveRow(node);
Expand Down Expand Up @@ -4188,6 +4222,40 @@ void VulkanPipelineStateViewer::exportHTML(QXmlStreamWriter &xml, const VKPipe::
xml.writeEndElement();
}

if(!pass.renderpass.colorAttachmentLocations.isEmpty())
{
QList<QVariantList> locations;

for(int i = 0; i < pass.renderpass.colorAttachmentLocations.count(); i++)
locations.push_back({pass.renderpass.colorAttachmentLocations[i]});

m_Common.exportHTMLTable(xml,
{
tr("Color Attachment Location"),
},
locations);

xml.writeStartElement(lit("p"));
xml.writeEndElement();
}

if(!pass.renderpass.colorAttachmentInputIndices.isEmpty())
{
QList<QVariantList> inputIndices;

for(int i = 0; i < pass.renderpass.colorAttachmentInputIndices.count(); i++)
inputIndices.push_back({pass.renderpass.colorAttachmentInputIndices[i]});

m_Common.exportHTMLTable(xml,
{
tr("Color Attachment Input Index"),
},
inputIndices);

xml.writeStartElement(lit("p"));
xml.writeEndElement();
}

if(!pass.renderpass.resolveAttachments.isEmpty())
{
QList<QVariantList> resolves;
Expand All @@ -4213,6 +4281,22 @@ void VulkanPipelineStateViewer::exportHTML(QXmlStreamWriter &xml, const VKPipe::
xml.writeEndElement();
}

if(!pass.renderpass.isDepthInputAttachmentIndexImplicit)
{
xml.writeStartElement(lit("p"));
xml.writeCharacters(
tr("Depth Input Attachment Index: %1").arg(pass.renderpass.depthInputAttachmentIndex));
xml.writeEndElement();
}

if(!pass.renderpass.isStencilInputAttachmentIndexImplicit)
{
xml.writeStartElement(lit("p"));
xml.writeCharacters(
tr("Stencil Input Attachment Index: %1").arg(pass.renderpass.stencilInputAttachmentIndex));
xml.writeEndElement();
}

if(pass.renderpass.depthstencilResolveAttachment >= 0)
{
xml.writeStartElement(lit("p"));
Expand Down
24 changes: 24 additions & 0 deletions renderdoc/api/replay/vk_pipestate.h
Original file line number Diff line number Diff line change
Expand Up @@ -859,6 +859,30 @@ samples used to render this subpass.
If the subpass is not internally multisampled, tileOnlyMSAASampleCount is set to 0.
)");
uint32_t tileOnlyMSAASampleCount = 0;

DOCUMENT(R"(The color index->location mapping set up by dynamic rendering local read.
:type: List[int]
)");
rdcarray<uint32_t> colorAttachmentLocations;

DOCUMENT(R"(The color index->input index mapping set up by dynamic rendering local read.
:type: List[int]
)");
rdcarray<uint32_t> colorAttachmentInputIndices;

DOCUMENT("Whether or not depth input attachment index is implicit (dynamic rendering).");
bool isDepthInputAttachmentIndexImplicit = true;

DOCUMENT("Whether or not stencil input attachment index is implicit (dynamic rendering).");
bool isStencilInputAttachmentIndexImplicit = true;

DOCUMENT("Depth input attachment index if explicit (dynamic rendering).");
uint32_t depthInputAttachmentIndex = 0x1234ABCD;

DOCUMENT("Stencil input attachment index if explicit (dynamic rendering).");
uint32_t stencilInputAttachmentIndex = 0x1234ABCD;
};

DOCUMENT("Describes a framebuffer object and its attachments.");
Expand Down
3 changes: 2 additions & 1 deletion renderdoc/driver/vulkan/extension_support.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ Maintainers can update this file by updating vk.xml in this folder and running `
* `VK_KHR_draw_indirect_count`
* `VK_KHR_driver_properties`
* `VK_KHR_dynamic_rendering`
* `VK_KHR_dynamic_rendering_local_read`
* `VK_KHR_external_fence_capabilities`
* `VK_KHR_external_fence_fd`
* `VK_KHR_external_fence_win32`
Expand Down Expand Up @@ -241,9 +242,9 @@ KHR extensions will definitely be implemented at some point, though KHR extensio
## KHR Extensions

* `VK_KHR_cooperative_matrix`
* `VK_KHR_dynamic_rendering_local_read`
* `VK_KHR_maintenance5`
* `VK_KHR_maintenance6`
* `VK_KHR_maintenance7`
* `VK_KHR_map_memory2`
* `VK_KHR_shader_expect_assume`
* `VK_KHR_shader_float_controls2`
Expand Down
8 changes: 8 additions & 0 deletions renderdoc/driver/vulkan/vk_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -1053,6 +1053,8 @@ enum class VulkanChunk : uint32_t
vkCmdSetVertexInputEXT,
vkCmdBeginRendering,
vkCmdEndRendering,
vkCmdSetRenderingAttachmentLocationsKHR,
vkCmdSetRenderingInputAttachmentIndicesKHR,
vkCmdSetFragmentShadingRateKHR,
vkSetDeviceMemoryPriorityEXT,
vkCmdSetAttachmentFeedbackLoopEnableEXT,
Expand Down Expand Up @@ -1335,6 +1337,7 @@ DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceDescriptorIndexingProperties)
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceDiscardRectanglePropertiesEXT);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceDriverProperties);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceDynamicRenderingFeatures);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceDynamicRenderingLocalReadFeaturesKHR);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceExtendedDynamicState2FeaturesEXT);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceExtendedDynamicState3FeaturesEXT);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceExtendedDynamicState3PropertiesEXT);
Expand Down Expand Up @@ -1519,8 +1522,10 @@ DECLARE_REFLECTION_STRUCT(VkRayTracingShaderGroupCreateInfoKHR);
DECLARE_REFLECTION_STRUCT(VkRefreshCycleDurationGOOGLE);
DECLARE_REFLECTION_STRUCT(VkReleaseSwapchainImagesInfoEXT);
DECLARE_REFLECTION_STRUCT(VkRenderingAttachmentInfo);
DECLARE_REFLECTION_STRUCT(VkRenderingAttachmentLocationInfoKHR);
DECLARE_REFLECTION_STRUCT(VkRenderingFragmentDensityMapAttachmentInfoEXT);
DECLARE_REFLECTION_STRUCT(VkRenderingFragmentShadingRateAttachmentInfoKHR);
DECLARE_REFLECTION_STRUCT(VkRenderingInputAttachmentIndexInfoKHR);
DECLARE_REFLECTION_STRUCT(VkRenderingInfo);
DECLARE_REFLECTION_STRUCT(VkRenderPassAttachmentBeginInfo);
DECLARE_REFLECTION_STRUCT(VkRenderPassBeginInfo);
Expand Down Expand Up @@ -1775,6 +1780,7 @@ DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceDescriptorIndexingProperties)
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceDiscardRectanglePropertiesEXT);
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceDriverProperties);
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceDynamicRenderingFeatures);
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceDynamicRenderingLocalReadFeaturesKHR);
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceExtendedDynamicState2FeaturesEXT);
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceExtendedDynamicState3FeaturesEXT);
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceExtendedDynamicState3PropertiesEXT);
Expand Down Expand Up @@ -1957,8 +1963,10 @@ DECLARE_DESERIALISE_TYPE(VkRayTracingPipelineInterfaceCreateInfoKHR);
DECLARE_DESERIALISE_TYPE(VkRayTracingShaderGroupCreateInfoKHR);
DECLARE_DESERIALISE_TYPE(VkReleaseSwapchainImagesInfoEXT);
DECLARE_DESERIALISE_TYPE(VkRenderingAttachmentInfo);
DECLARE_DESERIALISE_TYPE(VkRenderingAttachmentLocationInfoKHR);
DECLARE_DESERIALISE_TYPE(VkRenderingFragmentDensityMapAttachmentInfoEXT);
DECLARE_DESERIALISE_TYPE(VkRenderingFragmentShadingRateAttachmentInfoKHR);
DECLARE_DESERIALISE_TYPE(VkRenderingInputAttachmentIndexInfoKHR);
DECLARE_DESERIALISE_TYPE(VkRenderingInfo);
DECLARE_DESERIALISE_TYPE(VkRenderPassAttachmentBeginInfo);
DECLARE_DESERIALISE_TYPE(VkRenderPassBeginInfo);
Expand Down
8 changes: 8 additions & 0 deletions renderdoc/driver/vulkan/vk_core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1490,6 +1490,10 @@ static const VkExtensionProperties supportedExtensions[] = {
VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME,
VK_KHR_DYNAMIC_RENDERING_SPEC_VERSION,
},
{
VK_KHR_DYNAMIC_RENDERING_LOCAL_READ_EXTENSION_NAME,
VK_KHR_DYNAMIC_RENDERING_LOCAL_READ_SPEC_VERSION,
},
{
VK_KHR_EXTERNAL_FENCE_EXTENSION_NAME,
VK_KHR_EXTERNAL_FENCE_SPEC_VERSION,
Expand Down Expand Up @@ -4230,6 +4234,10 @@ bool WrappedVulkan::ProcessChunk(ReadSerialiser &ser, VulkanChunk chunk)
case VulkanChunk::vkCmdBeginRendering:
return Serialise_vkCmdBeginRendering(ser, VK_NULL_HANDLE, NULL);
case VulkanChunk::vkCmdEndRendering: return Serialise_vkCmdEndRendering(ser, VK_NULL_HANDLE);
case VulkanChunk::vkCmdSetRenderingAttachmentLocationsKHR:
return Serialise_vkCmdSetRenderingAttachmentLocationsKHR(ser, VK_NULL_HANDLE, NULL);
case VulkanChunk::vkCmdSetRenderingInputAttachmentIndicesKHR:
return Serialise_vkCmdSetRenderingInputAttachmentIndicesKHR(ser, VK_NULL_HANDLE, NULL);

case VulkanChunk::vkCmdSetFragmentShadingRateKHR:
return Serialise_vkCmdSetFragmentShadingRateKHR(ser, VK_NULL_HANDLE, NULL, NULL);
Expand Down
9 changes: 9 additions & 0 deletions renderdoc/driver/vulkan/vk_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -2787,6 +2787,15 @@ class WrappedVulkan : public IFrameCapturer

IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdEndRendering, VkCommandBuffer commandBuffer);

// VK_KHR_dynamic_rendering_local_read

IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdSetRenderingAttachmentLocationsKHR,
VkCommandBuffer commandBuffer,
const VkRenderingAttachmentLocationInfoKHR *pLocationInfo);
IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdSetRenderingInputAttachmentIndicesKHR,
VkCommandBuffer commandBuffer,
const VkRenderingInputAttachmentIndexInfoKHR *pLocationInfo);

// VK_KHR_fragment_shading_rate

IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdSetFragmentShadingRateKHR, VkCommandBuffer commandBuffer,
Expand Down
8 changes: 8 additions & 0 deletions renderdoc/driver/vulkan/vk_hookset_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,7 @@
DeclExt(EXT_multisampled_render_to_single_sampled); \
DeclExt(EXT_vertex_input_dynamic_state); \
DeclExt(KHR_dynamic_rendering); \
DeclExt(KHR_dynamic_rendering_local_read); \
DeclExt(KHR_fragment_shading_rate); \
DeclExt(EXT_attachment_feedback_loop_layout); \
DeclExt(EXT_pageable_device_local_memory); \
Expand Down Expand Up @@ -651,6 +652,7 @@
CheckExt(EXT_multisampled_render_to_single_sampled, VKXX); \
CheckExt(EXT_vertex_input_dynamic_state, VKXX); \
CheckExt(KHR_dynamic_rendering, VK13); \
CheckExt(KHR_dynamic_rendering_local_read, VKXX); \
CheckExt(KHR_fragment_shading_rate, VKXX); \
CheckExt(EXT_attachment_feedback_loop_layout, VKXX); \
CheckExt(EXT_pageable_device_local_memory, VKXX); \
Expand Down Expand Up @@ -941,6 +943,8 @@
HookInitExtension(EXT_vertex_input_dynamic_state || EXT_shader_object, CmdSetVertexInputEXT); \
HookInitPromotedExtension(KHR_dynamic_rendering, CmdBeginRendering, KHR); \
HookInitPromotedExtension(KHR_dynamic_rendering, CmdEndRendering, KHR); \
HookInitExtension(KHR_dynamic_rendering_local_read, CmdSetRenderingAttachmentLocationsKHR); \
HookInitExtension(KHR_dynamic_rendering_local_read, CmdSetRenderingInputAttachmentIndicesKHR); \
HookInitExtension(KHR_fragment_shading_rate, CmdSetFragmentShadingRateKHR); \
HookInitExtension(EXT_pageable_device_local_memory, SetDeviceMemoryPriorityEXT); \
HookInitExtension(EXT_swapchain_maintenance1, ReleaseSwapchainImagesEXT); \
Expand Down Expand Up @@ -1743,6 +1747,10 @@
HookDefine2(void, vkCmdBeginRendering, VkCommandBuffer, commandBuffer, const VkRenderingInfo *, \
pRenderingInfo); \
HookDefine1(void, vkCmdEndRendering, VkCommandBuffer, commandBuffer); \
HookDefine2(void, vkCmdSetRenderingAttachmentLocationsKHR, VkCommandBuffer, commandBuffer, \
const VkRenderingAttachmentLocationInfoKHR *, pLocationInfo); \
HookDefine2(void, vkCmdSetRenderingInputAttachmentIndicesKHR, VkCommandBuffer, commandBuffer, \
const VkRenderingInputAttachmentIndexInfoKHR *, pInputAttachmentIndexInfo); \
HookDefine3(void, vkCmdSetFragmentShadingRateKHR, VkCommandBuffer, commandBuffer, \
const VkExtent2D *, pFragmentSize, const VkFragmentShadingRateCombinerOpKHR *, \
combinerOps); \
Expand Down
Loading

0 comments on commit 6fbacc5

Please sign in to comment.