diff --git a/docs/python_api/renderdoc/pipelines/common.rst b/docs/python_api/renderdoc/pipelines/common.rst index 829f46a3d..a21689c3d 100644 --- a/docs/python_api/renderdoc/pipelines/common.rst +++ b/docs/python_api/renderdoc/pipelines/common.rst @@ -8,6 +8,12 @@ Common Pipeline State Abstraction .. autoclass:: PipeState :members: +General +------- + +.. autoclass:: renderdoc.Offset + :members: + Vertex Inputs ------------- diff --git a/qrenderdoc/Code/pyrenderdoc/renderdoc.i b/qrenderdoc/Code/pyrenderdoc/renderdoc.i index 78353135d..52b917593 100644 --- a/qrenderdoc/Code/pyrenderdoc/renderdoc.i +++ b/qrenderdoc/Code/pyrenderdoc/renderdoc.i @@ -388,6 +388,7 @@ TEMPLATE_ARRAY_INSTANTIATE(rdcarray, Viewport) TEMPLATE_ARRAY_INSTANTIATE(rdcarray, Scissor) TEMPLATE_ARRAY_INSTANTIATE(rdcarray, ColorBlend) TEMPLATE_ARRAY_INSTANTIATE(rdcarray, BoundVBuffer) +TEMPLATE_ARRAY_INSTANTIATE(rdcarray, Offset) TEMPLATE_ARRAY_INSTANTIATE(rdcarray, VertexInputAttribute) TEMPLATE_ARRAY_INSTANTIATE(rdcarray, BoundResource) TEMPLATE_ARRAY_INSTANTIATE(rdcarray, BoundResourceArray) diff --git a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp b/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp index 5683d605a..eebe3bf3a 100644 --- a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp +++ b/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp @@ -377,11 +377,11 @@ VulkanPipelineStateViewer::VulkanPipelineStateViewer(ICaptureContext &ctx, RDHeaderView *header = new RDHeaderView(Qt::Horizontal, this); ui->fbAttach->setHeader(header); - ui->fbAttach->setColumns({tr("Slot"), tr("Resource"), tr("Type"), tr("Width"), tr("Height"), - tr("Depth"), tr("Array Size"), tr("Format"), tr("Go")}); - header->setColumnStretchHints({2, 4, 2, 1, 1, 1, 1, 3, -1}); + ui->fbAttach->setColumns( + {tr("Slot"), tr("Resource"), tr("Type"), tr("Dimensions"), tr("Format"), tr("Go")}); + header->setColumnStretchHints({2, 4, 2, 2, 3, -1}); - ui->fbAttach->setHoverIconColumn(8, action, action_hover); + ui->fbAttach->setHoverIconColumn(5, action, action_hover); ui->fbAttach->setClearSelectionOnFocusLoss(true); ui->fbAttach->setInstantTooltips(true); @@ -593,7 +593,7 @@ template bool VulkanPipelineStateViewer::setViewDetails(RDTreeWidgetItem *node, const bindType &view, TextureDescription *tex, bool stageBitsIncluded, const QString &hiddenCombinedSampler, - bool includeSampleLocations) + bool includeSampleLocations, bool includeOffsets) { if(tex == NULL) return false; @@ -682,6 +682,21 @@ bool VulkanPipelineStateViewer::setViewDetails(RDTreeWidgetItem *node, const bin viewdetails = true; } + if(includeOffsets) + { + text += tr("Rendering with %1 offsets:\n") + .arg(state.currentPass.renderpass.fragmentDensityOffsets.size()); + for(uint32_t j = 0; j < state.currentPass.renderpass.fragmentDensityOffsets.size(); j++) + { + const Offset &o = state.currentPass.renderpass.fragmentDensityOffsets[j]; + if(j > 0) + text += tr(", "); + + text += tr(" %1x%2").arg(o.x).arg(o.y); + } + text += lit("\n"); + } + text = text.trimmed(); node->setToolTip(text); @@ -2606,10 +2621,10 @@ void VulkanPipelineStateViewer::setState() if(showNode(usedSlot, filledSlot)) { - uint32_t w = 1, h = 1, d = 1; - uint32_t a = 1; QString format; QString typeName; + QString dimensions; + bool tooltipOffsets = false; if(p.imageResourceId != ResourceId()) { @@ -2620,16 +2635,18 @@ void VulkanPipelineStateViewer::setState() { format = lit("-"); typeName = lit("-"); - w = h = d = a = 0; + dimensions = lit("-"); } TextureDescription *tex = m_Ctx.GetTexture(p.imageResourceId); if(tex) { - w = tex->width; - h = tex->height; - d = tex->depth; - a = tex->arraysize; + dimensions += tr("%1x%2").arg(tex->width).arg(tex->height); + if(tex->depth > 1) + dimensions += tr("x%1").arg(tex->depth); + if(tex->arraysize > 1) + dimensions += tr("[%1]").arg(tex->arraysize); + typeName = ToQStr(tex->type); } @@ -2661,6 +2678,22 @@ void VulkanPipelineStateViewer::setState() else if(state.currentPass.renderpass.fragmentDensityAttachment == i) { slotname = lit("Fragment Density Map"); + if(state.currentPass.renderpass.fragmentDensityOffsets.size() > 2) + { + tooltipOffsets = true; + } + else if(state.currentPass.renderpass.fragmentDensityOffsets.size() > 0) + { + dimensions += tr(" : offsets"); + for(uint32_t j = 0; j < state.currentPass.renderpass.fragmentDensityOffsets.size(); j++) + { + const Offset &o = state.currentPass.renderpass.fragmentDensityOffsets[j]; + if(j > 0) + dimensions += tr(", "); + + dimensions += tr(" %1x%2").arg(o.x).arg(o.y); + } + } } else if(state.currentPass.renderpass.shadingRateAttachment == i) { @@ -2706,7 +2739,7 @@ void VulkanPipelineStateViewer::setState() tr(" (%1x%2 texels)").arg(shadingRateTexelSize.first).arg(shadingRateTexelSize.second); RDTreeWidgetItem *node = - new RDTreeWidgetItem({slotname, resName, typeName, w, h, d, a, format, QString()}); + new RDTreeWidgetItem({slotname, resName, typeName, dimensions, format, QString()}); if(tex) node->setTag( @@ -2725,7 +2758,8 @@ void VulkanPipelineStateViewer::setState() targets[i] = true; } - bool hasViewDetails = setViewDetails(node, p, tex, true, QString(), resIdx < 0); + bool hasViewDetails = + setViewDetails(node, p, tex, true, QString(), resIdx < 0, tooltipOffsets); if(hasViewDetails) node->setText( diff --git a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.h b/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.h index 04d341226..0472797df 100644 --- a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.h +++ b/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.h @@ -125,7 +125,7 @@ private: template bool setViewDetails(RDTreeWidgetItem *node, const viewType &view, TextureDescription *tex, bool stageBitsIncluded, const QString &hiddenCombinedSampler, - bool includeSampleLocations = false); + bool includeSampleLocations = false, bool includeOffsets = false); template bool setViewDetails(RDTreeWidgetItem *node, const viewType &view, BufferDescription *buf, diff --git a/renderdoc/api/replay/common_pipestate.h b/renderdoc/api/replay/common_pipestate.h index f104a420d..3535d096e 100644 --- a/renderdoc/api/replay/common_pipestate.h +++ b/renderdoc/api/replay/common_pipestate.h @@ -420,6 +420,37 @@ typical buffer. DECLARE_REFLECTION_STRUCT(BoundCBuffer); +DOCUMENT("Describes a 2-dimensional int offset"); +struct Offset +{ + DOCUMENT(""); + Offset() = default; + Offset(const Offset &) = default; + Offset(int32_t x, int32_t y) : x(x), y(y){}; + Offset &operator=(const Offset &) = default; + + bool operator==(const Offset &o) const { return x == o.x && y == o.y; } + bool operator<(const Offset &o) const + { + if(x != o.x) + return x < o.x; + return y < o.y; + } + DOCUMENT(R"(The X offset value. + +:type: int +)"); + int32_t x = 0; + + DOCUMENT(R"(The Y offset value. + +:type: int +)"); + int32_t y = 0; +}; + +DECLARE_REFLECTION_STRUCT(Offset); + DOCUMENT("Information about a vertex input attribute feeding the vertex shader."); struct VertexInputAttribute { diff --git a/renderdoc/api/replay/vk_pipestate.h b/renderdoc/api/replay/vk_pipestate.h index 59469e457..a304d9ba3 100644 --- a/renderdoc/api/replay/vk_pipestate.h +++ b/renderdoc/api/replay/vk_pipestate.h @@ -1049,6 +1049,15 @@ If the list is empty, multiview is disabled and rendering is as normal. :type: List[int] )"); rdcarray multiviews; + + DOCUMENT(R"(If VK_QCOM_fragment_density_map_offset is enabled, contains a list of offsets applied +to the fragment density map during rendering. + +If the list is empty, fdm_offset is disabled and rendering is as normal. + +:type: List[Offset] +)"); + rdcarray fragmentDensityOffsets; }; DOCUMENT("Describes a single attachment in a framebuffer object."); diff --git a/renderdoc/driver/vulkan/vk_common.h b/renderdoc/driver/vulkan/vk_common.h index b149e7c3a..b4172cc50 100644 --- a/renderdoc/driver/vulkan/vk_common.h +++ b/renderdoc/driver/vulkan/vk_common.h @@ -957,6 +957,8 @@ DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceFragmentDensityMapFeaturesEXT); DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceFragmentDensityMapPropertiesEXT); DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceFragmentDensityMap2FeaturesEXT); DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceFragmentDensityMap2PropertiesEXT); +DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceFragmentDensityMapOffsetFeaturesQCOM); +DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceFragmentDensityMapOffsetPropertiesQCOM); DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV); DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT); DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceGlobalPriorityQueryFeaturesKHR); @@ -1129,6 +1131,7 @@ DECLARE_REFLECTION_STRUCT(VkSubpassDependency2); DECLARE_REFLECTION_STRUCT(VkSubpassDescription2); DECLARE_REFLECTION_STRUCT(VkSubpassDescriptionDepthStencilResolve); DECLARE_REFLECTION_STRUCT(VkSubpassEndInfo); +DECLARE_REFLECTION_STRUCT(VkSubpassFragmentDensityMapOffsetEndInfoQCOM); DECLARE_REFLECTION_STRUCT(VkSubpassSampleLocationsEXT); DECLARE_REFLECTION_STRUCT(VkSurfaceCapabilities2EXT); DECLARE_REFLECTION_STRUCT(VkSurfaceCapabilities2KHR); @@ -1324,6 +1327,8 @@ DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceFragmentDensityMapFeaturesEXT); DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceFragmentDensityMapPropertiesEXT); DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceFragmentDensityMap2FeaturesEXT); DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceFragmentDensityMap2PropertiesEXT); +DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceFragmentDensityMapOffsetFeaturesQCOM); +DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceFragmentDensityMapOffsetPropertiesQCOM); DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV); DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT); DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceGlobalPriorityQueryFeaturesKHR); @@ -1493,6 +1498,7 @@ DECLARE_DESERIALISE_TYPE(VkSubpassDependency2); DECLARE_DESERIALISE_TYPE(VkSubpassDescription2); DECLARE_DESERIALISE_TYPE(VkSubpassDescriptionDepthStencilResolve); DECLARE_DESERIALISE_TYPE(VkSubpassEndInfo); +DECLARE_DESERIALISE_TYPE(VkSubpassFragmentDensityMapOffsetEndInfoQCOM); DECLARE_DESERIALISE_TYPE(VkSubpassSampleLocationsEXT); DECLARE_DESERIALISE_TYPE(VkSurfaceCapabilities2EXT); DECLARE_DESERIALISE_TYPE(VkSurfaceCapabilities2KHR); diff --git a/renderdoc/driver/vulkan/vk_core.cpp b/renderdoc/driver/vulkan/vk_core.cpp index 2d50da437..2e992b0c2 100644 --- a/renderdoc/driver/vulkan/vk_core.cpp +++ b/renderdoc/driver/vulkan/vk_core.cpp @@ -1456,6 +1456,10 @@ static const VkExtensionProperties supportedExtensions[] = { VK_NV_WIN32_KEYED_MUTEX_EXTENSION_NAME, VK_NV_WIN32_KEYED_MUTEX_SPEC_VERSION, }, #endif + { + VK_QCOM_FRAGMENT_DENSITY_MAP_OFFSET_EXTENSION_NAME, + VK_QCOM_FRAGMENT_DENSITY_MAP_OFFSET_SPEC_VERSION, + }, { VK_QCOM_RENDER_PASS_SHADER_RESOLVE_EXTENSION_NAME, VK_QCOM_RENDER_PASS_SHADER_RESOLVE_SPEC_VERSION, diff --git a/renderdoc/driver/vulkan/vk_next_chains.cpp b/renderdoc/driver/vulkan/vk_next_chains.cpp index 7ac4c4312..40e07045e 100644 --- a/renderdoc/driver/vulkan/vk_next_chains.cpp +++ b/renderdoc/driver/vulkan/vk_next_chains.cpp @@ -265,6 +265,10 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct, VkPhysicalDeviceFragmentDensityMap2FeaturesEXT); \ COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_2_PROPERTIES_EXT, \ VkPhysicalDeviceFragmentDensityMap2PropertiesEXT); \ + COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_OFFSET_FEATURES_QCOM, \ + VkPhysicalDeviceFragmentDensityMapOffsetFeaturesQCOM); \ + COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_OFFSET_PROPERTIES_QCOM, \ + VkPhysicalDeviceFragmentDensityMapOffsetPropertiesQCOM); \ COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT, \ VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT); \ COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR, \ @@ -527,6 +531,8 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct, COPY_STRUCT(VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2, VkSubpassDescription2); \ COPY_STRUCT(VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE, \ VkSubpassDescriptionDepthStencilResolve); \ + COPY_STRUCT(VK_STRUCTURE_TYPE_SUBPASS_FRAGMENT_DENSITY_MAP_OFFSET_END_INFO_QCOM, \ + VkSubpassFragmentDensityMapOffsetEndInfoQCOM); \ COPY_STRUCT(VK_STRUCTURE_TYPE_SUBPASS_END_INFO, VkSubpassEndInfo); \ COPY_STRUCT(VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT, VkSurfaceCapabilities2EXT); \ COPY_STRUCT(VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR, VkSurfaceCapabilities2KHR); \ @@ -779,8 +785,6 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct, case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXCLUSIVE_SCISSOR_FEATURES_NV: \ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT: \ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_RDMA_FEATURES_NV: \ - case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_OFFSET_FEATURES_QCOM: \ - case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_OFFSET_PROPERTIES_QCOM: \ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_ENUMS_FEATURES_NV: \ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_ENUMS_PROPERTIES_NV: \ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT: \ @@ -841,7 +845,6 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct, case VK_STRUCTURE_TYPE_SAMPLER_BORDER_COLOR_COMPONENT_MAPPING_CREATE_INFO_EXT: \ case VK_STRUCTURE_TYPE_SCREEN_SURFACE_CREATE_INFO_QNX: \ case VK_STRUCTURE_TYPE_SEMAPHORE_GET_ZIRCON_HANDLE_INFO_FUCHSIA: \ - case VK_STRUCTURE_TYPE_SUBPASS_FRAGMENT_DENSITY_MAP_OFFSET_END_INFO_QCOM: \ case VK_STRUCTURE_TYPE_SUBPASS_SHADING_PIPELINE_CREATE_INFO_HUAWEI: \ case VK_STRUCTURE_TYPE_SYSMEM_COLOR_SPACE_FUCHSIA: \ case VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR: \ diff --git a/renderdoc/driver/vulkan/vk_replay.cpp b/renderdoc/driver/vulkan/vk_replay.cpp index 179b90372..8b43cc29f 100644 --- a/renderdoc/driver/vulkan/vk_replay.cpp +++ b/renderdoc/driver/vulkan/vk_replay.cpp @@ -1575,6 +1575,7 @@ void VulkanReplay::SavePipelineState(uint32_t eventId) rpState.suspended = dyn.suspended; rpState.resourceId = ResourceId(); rpState.subpass = 0; + rpState.fragmentDensityOffsets.clear(); fbState.resourceId = ResourceId(); // dynamic rendering does not provide a framebuffer dimension, it's implicit from the image @@ -1812,6 +1813,13 @@ void VulkanReplay::SavePipelineState(uint32_t eventId) ret.currentPass.framebuffer.layers = 0; } + ret.currentPass.renderpass.fragmentDensityOffsets.resize(state.fragmentDensityMapOffsets.size()); + for(size_t i = 0; i < state.fragmentDensityMapOffsets.size(); i++) + { + const VkOffset2D &o = state.fragmentDensityMapOffsets[i]; + ret.currentPass.renderpass.fragmentDensityOffsets[i] = Offset(o.x, o.y); + } + ret.currentPass.renderArea.x = state.renderArea.offset.x; ret.currentPass.renderArea.y = state.renderArea.offset.y; ret.currentPass.renderArea.width = state.renderArea.extent.width; @@ -1824,6 +1832,7 @@ void VulkanReplay::SavePipelineState(uint32_t eventId) ret.currentPass.renderpass.inputAttachments.clear(); ret.currentPass.renderpass.colorAttachments.clear(); ret.currentPass.renderpass.resolveAttachments.clear(); + ret.currentPass.renderpass.fragmentDensityOffsets.clear(); ret.currentPass.renderpass.depthstencilAttachment = -1; ret.currentPass.renderpass.depthstencilResolveAttachment = -1; ret.currentPass.renderpass.fragmentDensityAttachment = -1; diff --git a/renderdoc/driver/vulkan/vk_serialise.cpp b/renderdoc/driver/vulkan/vk_serialise.cpp index a78f622ec..fa7fe6ba6 100644 --- a/renderdoc/driver/vulkan/vk_serialise.cpp +++ b/renderdoc/driver/vulkan/vk_serialise.cpp @@ -1268,6 +1268,14 @@ SERIALISE_VK_HANDLES(); PNEXT_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_FOOTPRINT_FEATURES_NV, \ VkPhysicalDeviceShaderImageFootprintFeaturesNV) \ \ + /* VK_QCOM_fragment_density_map_offset */ \ + PNEXT_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_OFFSET_FEATURES_QCOM, \ + VkPhysicalDeviceFragmentDensityMapOffsetFeaturesQCOM) \ + PNEXT_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_OFFSET_PROPERTIES_QCOM, \ + VkPhysicalDeviceFragmentDensityMapOffsetPropertiesQCOM) \ + PNEXT_STRUCT(VK_STRUCTURE_TYPE_SUBPASS_FRAGMENT_DENSITY_MAP_OFFSET_END_INFO_QCOM, \ + VkSubpassFragmentDensityMapOffsetEndInfoQCOM) \ + \ /* Surface creation structs. These would pull in dependencies on OS-specific includes. */ \ /* So treat them as unsupported. */ \ PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR) \ @@ -1528,11 +1536,6 @@ SERIALISE_VK_HANDLES(); /* Interaction with VK_KHR_dynamic_rendering */ \ PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_MULTIVIEW_PER_VIEW_ATTRIBUTES_INFO_NVX) \ \ - /* VK_QCOM_fragment_density_map_offset */ \ - PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_OFFSET_FEATURES_QCOM) \ - PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_OFFSET_PROPERTIES_QCOM) \ - PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_SUBPASS_FRAGMENT_DENSITY_MAP_OFFSET_END_INFO_QCOM) \ - \ /* VK_QCOM_render_pass_transform */ \ PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDER_PASS_TRANSFORM_INFO_QCOM) \ PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_RENDER_PASS_TRANSFORM_BEGIN_INFO_QCOM) \ @@ -5652,6 +5655,56 @@ void Deserialise(const VkPhysicalDeviceFragmentDensityMap2PropertiesEXT &el) DeserialiseNext(el.pNext); } +template +void DoSerialise(SerialiserType &ser, VkPhysicalDeviceFragmentDensityMapOffsetFeaturesQCOM &el) +{ + RDCASSERT(ser.IsReading() || + el.sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_OFFSET_FEATURES_QCOM); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER(fragmentDensityMapOffset); +} + +template <> +void Deserialise(const VkPhysicalDeviceFragmentDensityMapOffsetFeaturesQCOM &el) +{ + DeserialiseNext(el.pNext); +} + +template +void DoSerialise(SerialiserType &ser, VkPhysicalDeviceFragmentDensityMapOffsetPropertiesQCOM &el) +{ + RDCASSERT(ser.IsReading() || + el.sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_OFFSET_PROPERTIES_QCOM); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER(fragmentDensityOffsetGranularity); +} + +template <> +void Deserialise(const VkPhysicalDeviceFragmentDensityMapOffsetPropertiesQCOM &el) +{ + DeserialiseNext(el.pNext); +} + +template +void DoSerialise(SerialiserType &ser, VkSubpassFragmentDensityMapOffsetEndInfoQCOM &el) +{ + RDCASSERT(ser.IsReading() || + el.sType == VK_STRUCTURE_TYPE_SUBPASS_FRAGMENT_DENSITY_MAP_OFFSET_END_INFO_QCOM); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER(fragmentDensityOffsetCount); + SERIALISE_MEMBER_ARRAY(pFragmentDensityOffsets, fragmentDensityOffsetCount); +} + +template <> +void Deserialise(const VkSubpassFragmentDensityMapOffsetEndInfoQCOM &el) +{ + DeserialiseNext(el.pNext); + delete[] el.pFragmentDensityOffsets; +} + template void DoSerialise(SerialiserType &ser, VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT &el) { @@ -10283,6 +10336,8 @@ INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceFragmentDensityMapFeaturesEXT); INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceFragmentDensityMapPropertiesEXT); INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceFragmentDensityMap2FeaturesEXT); INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceFragmentDensityMap2PropertiesEXT); +INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceFragmentDensityMapOffsetFeaturesQCOM); +INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceFragmentDensityMapOffsetPropertiesQCOM); INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV); INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT); INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceGlobalPriorityQueryFeaturesKHR); @@ -10452,6 +10507,7 @@ INSTANTIATE_SERIALISE_TYPE(VkSubpassBeginInfo); INSTANTIATE_SERIALISE_TYPE(VkSubpassDependency2); INSTANTIATE_SERIALISE_TYPE(VkSubpassDescription2); INSTANTIATE_SERIALISE_TYPE(VkSubpassDescriptionDepthStencilResolve); +INSTANTIATE_SERIALISE_TYPE(VkSubpassFragmentDensityMapOffsetEndInfoQCOM); INSTANTIATE_SERIALISE_TYPE(VkSubpassEndInfo); INSTANTIATE_SERIALISE_TYPE(VkSubpassSampleLocationsEXT); INSTANTIATE_SERIALISE_TYPE(VkSurfaceCapabilities2EXT); diff --git a/renderdoc/driver/vulkan/vk_state.h b/renderdoc/driver/vulkan/vk_state.h index 870091117..7385317ff 100644 --- a/renderdoc/driver/vulkan/vk_state.h +++ b/renderdoc/driver/vulkan/vk_state.h @@ -234,6 +234,9 @@ struct VulkanRenderState VkExtent2D shadingRateTexelSize = {1, 1}; } dynamicRendering; + // fdm offset + rdcarray fragmentDensityMapOffsets; + // shading rate VkExtent2D pipelineShadingRate = {1, 1}; VkFragmentShadingRateCombinerOpKHR shadingRateCombiners[2] = { diff --git a/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp index d67317e93..a12f98fd7 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp @@ -2835,6 +2835,21 @@ bool WrappedVulkan::Serialise_vkCmdEndRenderPass2(SerialiserType &ser, VkCommand m_BakedCmdBufferInfo[m_LastCmdBufferID].renderPassOpen = false; m_BakedCmdBufferInfo[m_LastCmdBufferID].endBarriers.append(GetImplicitRenderPassBarriers(~0U)); + + VkSubpassFragmentDensityMapOffsetEndInfoQCOM *fragmentDensityOffsetStruct = + (VkSubpassFragmentDensityMapOffsetEndInfoQCOM *)FindNextStruct( + &unwrappedEndInfo, + VK_STRUCTURE_TYPE_SUBPASS_FRAGMENT_DENSITY_MAP_OFFSET_END_INFO_QCOM); + + if(fragmentDensityOffsetStruct) + { + rdcarray &stateOffsets = GetCmdRenderState().fragmentDensityMapOffsets; + stateOffsets.resize(fragmentDensityOffsetStruct->fragmentDensityOffsetCount); + for(uint32_t i = 0; i < fragmentDensityOffsetStruct->fragmentDensityOffsetCount; i++) + { + stateOffsets[i] = fragmentDensityOffsetStruct->pFragmentDensityOffsets[i]; + } + } } } else diff --git a/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp index 833136faa..06ca297c8 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp @@ -2349,6 +2349,14 @@ bool WrappedVulkan::Serialise_vkCreateDevice(SerialiserType &ser, VkPhysicalDevi } END_PHYS_EXT_CHECK(); + BEGIN_PHYS_EXT_CHECK( + VkPhysicalDeviceFragmentDensityMapOffsetFeaturesQCOM, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_OFFSET_FEATURES_QCOM); + { + CHECK_PHYS_EXT_FEATURE(fragmentDensityMapOffset); + } + END_PHYS_EXT_CHECK(); + BEGIN_PHYS_EXT_CHECK(VkPhysicalDeviceProtectedMemoryFeatures, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES); { diff --git a/renderdoc/replay/renderdoc_serialise.inl b/renderdoc/replay/renderdoc_serialise.inl index ef51fea0b..bfdb1f25c 100644 --- a/renderdoc/replay/renderdoc_serialise.inl +++ b/renderdoc/replay/renderdoc_serialise.inl @@ -813,6 +813,15 @@ void DoSerialise(SerialiserType &ser, MeshFormat &el) SIZE_CHECK(128); } +template +void DoSerialise(SerialiserType &ser, Offset &el) +{ + SERIALISE_MEMBER(x); + SERIALISE_MEMBER(y); + + SIZE_CHECK(8); +} + template void DoSerialise(SerialiserType &ser, FloatVector &el) { @@ -2217,8 +2226,9 @@ void DoSerialise(SerialiserType &ser, VKPipe::RenderPass &el) SERIALISE_MEMBER(shadingRateAttachment); SERIALISE_MEMBER(shadingRateTexelSize); SERIALISE_MEMBER(multiviews); + SERIALISE_MEMBER(fragmentDensityOffsets); - SIZE_CHECK(136); + SIZE_CHECK(160); } template @@ -2268,7 +2278,7 @@ void DoSerialise(SerialiserType &ser, VKPipe::CurrentPass &el) SERIALISE_MEMBER(framebuffer); SERIALISE_MEMBER(renderArea); - SIZE_CHECK(200); + SIZE_CHECK(224); } template @@ -2336,7 +2346,7 @@ void DoSerialise(SerialiserType &ser, VKPipe::State &el) SERIALISE_MEMBER(conditionalRendering); - SIZE_CHECK(2040); + SIZE_CHECK(2064); } #pragma endregion Vulkan pipeline state @@ -2391,6 +2401,7 @@ INSTANTIATE_SERIALISE_TYPE(FrameDescription) INSTANTIATE_SERIALISE_TYPE(FrameRecord) INSTANTIATE_SERIALISE_TYPE(MeshFormat) INSTANTIATE_SERIALISE_TYPE(FloatVector) +INSTANTIATE_SERIALISE_TYPE(Offset); INSTANTIATE_SERIALISE_TYPE(Uuid) INSTANTIATE_SERIALISE_TYPE(CounterDescription) INSTANTIATE_SERIALISE_TYPE(PixelValue)