diff --git a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp b/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp index c3da796dd..5683d605a 100644 --- a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp +++ b/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp @@ -872,7 +872,6 @@ void VulkanPipelineStateViewer::clearState() ui->lineWidth->setText(lit("1.0")); ui->conservativeRaster->setText(tr("Disabled")); - ui->overestimationSize->setText(lit("0.0")); ui->multiview->setText(tr("Disabled")); ui->stippleFactor->setText(QString()); @@ -880,6 +879,9 @@ void VulkanPipelineStateViewer::clearState() ui->stipplePattern->setText(QString()); ui->stipplePattern->setPixmap(cross); + ui->pipelineShadingRate->setText(tr("1x1")); + ui->shadingRateCombiners->setText(tr("Keep, Keep")); + ui->sampleCount->setText(lit("1")); ui->sampleShading->setPixmap(tick); ui->minSampleShading->setText(lit("0.0")); @@ -2470,9 +2472,10 @@ void VulkanPipelineStateViewer::setState() ui->rasterizerDiscard->setPixmap(state.rasterizer.rasterizerDiscardEnable ? tick : cross); ui->lineWidth->setText(Formatter::Format(state.rasterizer.lineWidth)); - ui->conservativeRaster->setText(ToQStr(state.rasterizer.conservativeRasterization)); - ui->overestimationSize->setText( - Formatter::Format(state.rasterizer.extraPrimitiveOverestimationSize)); + QString conservRaster = ToQStr(state.rasterizer.conservativeRasterization); + if(state.rasterizer.conservativeRasterization == ConservativeRaster::Overestimate && + state.rasterizer.extraPrimitiveOverestimationSize > 0.0f) + conservRaster += QFormatStr(" (+%1)").arg(state.rasterizer.extraPrimitiveOverestimationSize); if(state.rasterizer.lineStippleFactor == 0) { @@ -2489,6 +2492,14 @@ void VulkanPipelineStateViewer::setState() ui->stipplePattern->setText(QString::number(state.rasterizer.lineStipplePattern, 2)); } + ui->pipelineShadingRate->setText(QFormatStr("%1x%2") + .arg(state.rasterizer.pipelineShadingRate.first) + .arg(state.rasterizer.pipelineShadingRate.second)); + ui->shadingRateCombiners->setText( + QFormatStr("%1, %2") + .arg(ToQStr(state.rasterizer.shadingRateCombiners.first, GraphicsAPI::Vulkan)) + .arg(ToQStr(state.rasterizer.shadingRateCombiners.second, GraphicsAPI::Vulkan))); + if(state.currentPass.renderpass.multiviews.isEmpty()) { ui->multiview->setText(tr("Disabled")); @@ -2590,6 +2601,7 @@ void VulkanPipelineStateViewer::setState() bool usedSlot = (colIdx >= 0 || resIdx >= 0 || state.currentPass.renderpass.depthstencilAttachment == i || state.currentPass.renderpass.fragmentDensityAttachment == i || + state.currentPass.renderpass.shadingRateAttachment == i || state.currentPass.renderpass.depthstencilResolveAttachment == i); if(showNode(usedSlot, filledSlot)) @@ -2631,6 +2643,7 @@ void VulkanPipelineStateViewer::setState() .arg(ToQStr(p.swizzle.alpha)); } + rdcpair shadingRateTexelSize = {0, 0}; QString slotname; if(colIdx >= 0) @@ -2649,6 +2662,11 @@ void VulkanPipelineStateViewer::setState() { slotname = lit("Fragment Density Map"); } + else if(state.currentPass.renderpass.shadingRateAttachment == i) + { + slotname = lit("Fragment Shading Rate Map"); + shadingRateTexelSize = state.currentPass.renderpass.shadingRateTexelSize; + } else { slotname = lit("Depth"); @@ -2681,8 +2699,14 @@ void VulkanPipelineStateViewer::setState() } } - RDTreeWidgetItem *node = new RDTreeWidgetItem( - {slotname, p.imageResourceId, typeName, w, h, d, a, format, QString()}); + QString resName = ToQStr(p.imageResourceId); + + if(shadingRateTexelSize.first > 0) + resName += + tr(" (%1x%2 texels)").arg(shadingRateTexelSize.first).arg(shadingRateTexelSize.second); + + RDTreeWidgetItem *node = + new RDTreeWidgetItem({slotname, resName, typeName, w, h, d, a, format, QString()}); if(tex) node->setTag( @@ -4062,6 +4086,16 @@ void VulkanPipelineStateViewer::exportHTML(QXmlStreamWriter &xml, const VKPipe:: tr("Fragment Density Attachment: %1").arg(pass.renderpass.fragmentDensityAttachment)); xml.writeEndElement(); } + + if(pass.renderpass.shadingRateAttachment >= 0) + { + xml.writeStartElement(lit("p")); + xml.writeCharacters(tr("Fragment Shading Rate Attachment: %1 (texel size %2x%3)") + .arg(pass.renderpass.shadingRateAttachment) + .arg(pass.renderpass.shadingRateTexelSize.first) + .arg(pass.renderpass.shadingRateTexelSize.second)); + xml.writeEndElement(); + } } { diff --git a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.ui b/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.ui index bd3b078b9..bde67c289 100644 --- a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.ui +++ b/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.ui @@ -2042,9 +2042,9 @@ - + - Overestimate Size: + Multiview: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -2055,14 +2055,14 @@ - + 12 - 0.00 + TextLabel Qt::AlignCenter @@ -2175,9 +2175,9 @@ - + - Multiview: + Pipeline shading rate: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -2188,14 +2188,14 @@ - + 12 - TextLabel + 1x1 Qt::AlignCenter @@ -2256,8 +2256,8 @@ 12 - - 0000000000000000 + + :/cross.png Qt::AlignCenter @@ -2296,6 +2296,37 @@ + + + + Shading rate combiners: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + + + + + + 12 + + + + Keep, Keep + + + Qt::AlignCenter + + + 4 + + + diff --git a/renderdoc/api/replay/vk_pipestate.h b/renderdoc/api/replay/vk_pipestate.h index 6bc1f1a20..59469e457 100644 --- a/renderdoc/api/replay/vk_pipestate.h +++ b/renderdoc/api/replay/vk_pipestate.h @@ -824,6 +824,29 @@ See :data:`conservativeRasterizationMode` uint32_t lineStippleFactor = 0; DOCUMENT("The line stipple bit-pattern."); uint16_t lineStipplePattern = 0; + DOCUMENT(R"(The current pipeline fragment shading rate. This will always be 1x1 when a fragment +shading rate has not been specified. + +:type: Tuple[int,int] +)"); + rdcpair pipelineShadingRate = {1, 1}; + DOCUMENT(R"(The fragment shading rate combiners. + +The combiners are applied as follows, according to the Vulkan spec: + + ``intermediateRate = combiner[0] ( pipelineShadingRate, shaderExportedShadingRate )`` + ``finalRate = combiner[1] ( intermediateRate, imageBasedShadingRate )`` + +Where the first input is from :data:`pipelineShadingRate` and the second is the exported shading +rate from the last pre-rasterization shader stage, which defaults to 1x1 if not exported. + +The intermediate result is then used as the first input to the second combiner, together with the +shading rate sampled from the fragment shading rate attachment. + +:type: Tuple[ShadingRateCombiner,ShadingRateCombiner] +)"); + rdcpair shadingRateCombiners = { + ShadingRateCombiner::Keep, ShadingRateCombiner::Keep}; }; DOCUMENT("Describes state of custom sample locations in the pipeline."); @@ -988,9 +1011,36 @@ If there is no depth-stencil resolve attachment, this index is ``-1``. DOCUMENT(R"(An index into the framebuffer attachments for the fragment density attachment. If there is no fragment density attachment, this index is ``-1``. + +.. note:: + Only one at most of :data:`fragmentDensityAttachment` and :data:`shadingRateAttachment` will be + set. )"); int32_t fragmentDensityAttachment = -1; + DOCUMENT(R"(An index into the framebuffer attachments for the fragment shading rate attachment. + +If there is no fragment shading rate attachment, this index is ``-1``. + +.. note:: + Only one at most of :data:`fragmentDensityAttachment` and :data:`shadingRateAttachment` will be + set. +)"); + int32_t shadingRateAttachment = -1; + + DOCUMENT(R"(The size of the framebuffer region represented by each texel in +:data:`shadingRateAttachment`. + +For example if this is (2,2) then every texel in the attachment gives the shading rate of a 2x2 +block in the framebuffer so the shading rate attachment is half the size of the other attachments in +each dimension. + +If no attachment is set in :data:`shadingRateAttachment` this will be (1,1). + +:type: Tuple[int,int] +)"); + rdcpair shadingRateTexelSize = {1, 1}; + DOCUMENT(R"(If multiview is enabled, contains a list of view indices to be broadcast to during rendering. diff --git a/renderdoc/driver/vulkan/extension_support.md b/renderdoc/driver/vulkan/extension_support.md index 105a3af53..0ffd3d544 100644 --- a/renderdoc/driver/vulkan/extension_support.md +++ b/renderdoc/driver/vulkan/extension_support.md @@ -133,6 +133,7 @@ Maintainers can update this file by updating vk.xml in this folder and running ` * `VK_KHR_external_semaphore_win32` * `VK_KHR_external_semaphore` * `VK_KHR_format_feature_flags2` +* `VK_KHR_fragment_shading_rate` * `VK_KHR_get_display_properties2` * `VK_KHR_get_memory_requirements2` * `VK_KHR_get_physical_device_properties2` @@ -204,7 +205,7 @@ KHR extensions will definitely be implemented at some point, though KHR extensio ## KHR Extensions -* `VK_KHR_fragment_shading_rate` +* None currently. ## KHR Portability diff --git a/renderdoc/driver/vulkan/vk_common.h b/renderdoc/driver/vulkan/vk_common.h index b4ac41553..c0584db50 100644 --- a/renderdoc/driver/vulkan/vk_common.h +++ b/renderdoc/driver/vulkan/vk_common.h @@ -727,6 +727,7 @@ enum class VulkanChunk : uint32_t vkCmdSetVertexInputEXT, vkCmdBeginRendering, vkCmdEndRendering, + vkCmdSetFragmentShadingRateKHR, Max, }; @@ -880,6 +881,7 @@ DECLARE_REFLECTION_STRUCT(VkFenceGetFdInfoKHR); DECLARE_REFLECTION_STRUCT(VkFilterCubicImageViewImageFormatPropertiesEXT); DECLARE_REFLECTION_STRUCT(VkFormatProperties2); DECLARE_REFLECTION_STRUCT(VkFormatProperties3KHR); +DECLARE_REFLECTION_STRUCT(VkFragmentShadingRateAttachmentInfoKHR); DECLARE_REFLECTION_STRUCT(VkFramebufferAttachmentImageInfo); DECLARE_REFLECTION_STRUCT(VkFramebufferAttachmentsCreateInfo); DECLARE_REFLECTION_STRUCT(VkFramebufferCreateInfo); @@ -961,6 +963,9 @@ DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT); DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceGlobalPriorityQueryFeaturesKHR); DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceGroupProperties); DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceHostQueryResetFeatures); +DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceFragmentShadingRateKHR); +DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceFragmentShadingRateFeaturesKHR); +DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceFragmentShadingRatePropertiesKHR); DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceIDProperties); DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceImageFormatInfo2); DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceImagelessFramebufferFeatures); @@ -1056,6 +1061,7 @@ DECLARE_REFLECTION_STRUCT(VkPipelineExecutableInfoKHR); DECLARE_REFLECTION_STRUCT(VkPipelineExecutableInternalRepresentationKHR); DECLARE_REFLECTION_STRUCT(VkPipelineExecutablePropertiesKHR); DECLARE_REFLECTION_STRUCT(VkPipelineExecutableStatisticKHR); +DECLARE_REFLECTION_STRUCT(VkPipelineFragmentShadingRateStateCreateInfoKHR); DECLARE_REFLECTION_STRUCT(VkPipelineInfoKHR); DECLARE_REFLECTION_STRUCT(VkPipelineInputAssemblyStateCreateInfo); DECLARE_REFLECTION_STRUCT(VkPipelineLayoutCreateInfo); @@ -1088,6 +1094,7 @@ DECLARE_REFLECTION_STRUCT(VkQueueFamilyProperties2); DECLARE_REFLECTION_STRUCT(VkRefreshCycleDurationGOOGLE); DECLARE_REFLECTION_STRUCT(VkRenderingAttachmentInfo); DECLARE_REFLECTION_STRUCT(VkRenderingFragmentDensityMapAttachmentInfoEXT); +DECLARE_REFLECTION_STRUCT(VkRenderingFragmentShadingRateAttachmentInfoKHR); DECLARE_REFLECTION_STRUCT(VkRenderingInfo); DECLARE_REFLECTION_STRUCT(VkRenderPassAttachmentBeginInfo); DECLARE_REFLECTION_STRUCT(VkRenderPassBeginInfo); @@ -1245,6 +1252,7 @@ DECLARE_DESERIALISE_TYPE(VkFenceGetFdInfoKHR); DECLARE_DESERIALISE_TYPE(VkFilterCubicImageViewImageFormatPropertiesEXT); DECLARE_DESERIALISE_TYPE(VkFormatProperties2); DECLARE_DESERIALISE_TYPE(VkFormatProperties3KHR); +DECLARE_DESERIALISE_TYPE(VkFragmentShadingRateAttachmentInfoKHR); DECLARE_DESERIALISE_TYPE(VkFramebufferAttachmentImageInfo); DECLARE_DESERIALISE_TYPE(VkFramebufferAttachmentsCreateInfo); DECLARE_DESERIALISE_TYPE(VkFramebufferCreateInfo); @@ -1322,6 +1330,9 @@ DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT); DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceGlobalPriorityQueryFeaturesKHR); DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceGroupProperties); DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceHostQueryResetFeatures); +DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceFragmentShadingRateKHR); +DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceFragmentShadingRateFeaturesKHR); +DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceFragmentShadingRatePropertiesKHR); DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceIDProperties); DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceImageFormatInfo2); DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceImagelessFramebufferFeatures); @@ -1417,6 +1428,7 @@ DECLARE_DESERIALISE_TYPE(VkPipelineExecutableInfoKHR); DECLARE_DESERIALISE_TYPE(VkPipelineExecutableInternalRepresentationKHR); DECLARE_DESERIALISE_TYPE(VkPipelineExecutablePropertiesKHR); DECLARE_DESERIALISE_TYPE(VkPipelineExecutableStatisticKHR); +DECLARE_DESERIALISE_TYPE(VkPipelineFragmentShadingRateStateCreateInfoKHR); DECLARE_DESERIALISE_TYPE(VkPipelineInfoKHR); DECLARE_DESERIALISE_TYPE(VkPipelineInputAssemblyStateCreateInfo); DECLARE_DESERIALISE_TYPE(VkPipelineLayoutCreateInfo); @@ -1446,6 +1458,7 @@ DECLARE_DESERIALISE_TYPE(VkQueryPoolPerformanceCreateInfoKHR); DECLARE_DESERIALISE_TYPE(VkQueueFamilyGlobalPriorityPropertiesKHR); DECLARE_DESERIALISE_TYPE(VkQueueFamilyProperties2); DECLARE_DESERIALISE_TYPE(VkRenderingAttachmentInfo); +DECLARE_DESERIALISE_TYPE(VkRenderingFragmentDensityMapAttachmentInfoEXT); DECLARE_DESERIALISE_TYPE(VkRenderingFragmentShadingRateAttachmentInfoKHR); DECLARE_DESERIALISE_TYPE(VkRenderingInfo); DECLARE_DESERIALISE_TYPE(VkRenderPassAttachmentBeginInfo); @@ -1729,6 +1742,7 @@ DECLARE_REFLECTION_ENUM(VkFlagWithNoBits); DECLARE_REFLECTION_ENUM(VkFormat); DECLARE_REFLECTION_ENUM(VkFormatFeatureFlagBits); DECLARE_REFLECTION_ENUM(VkFormatFeatureFlagBits2); +DECLARE_REFLECTION_ENUM(VkFragmentShadingRateCombinerOpKHR); DECLARE_REFLECTION_ENUM(VkFramebufferCreateFlagBits); DECLARE_REFLECTION_ENUM(VkFrontFace); DECLARE_REFLECTION_ENUM(VkImageAspectFlagBits); diff --git a/renderdoc/driver/vulkan/vk_core.cpp b/renderdoc/driver/vulkan/vk_core.cpp index 3c2da30f1..b15c91aec 100644 --- a/renderdoc/driver/vulkan/vk_core.cpp +++ b/renderdoc/driver/vulkan/vk_core.cpp @@ -1226,6 +1226,9 @@ static const VkExtensionProperties supportedExtensions[] = { { VK_KHR_FORMAT_FEATURE_FLAGS_2_EXTENSION_NAME, VK_KHR_FORMAT_FEATURE_FLAGS_2_SPEC_VERSION, }, + { + VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME, VK_KHR_FRAGMENT_SHADING_RATE_SPEC_VERSION, + }, { VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME, VK_KHR_GET_DISPLAY_PROPERTIES_2_SPEC_VERSION, }, @@ -3519,8 +3522,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::vkCmdEndRendering: return Serialise_vkCmdEndRendering(ser, VK_NULL_HANDLE); + + case VulkanChunk::vkCmdSetFragmentShadingRateKHR: + return Serialise_vkCmdSetFragmentShadingRateKHR(ser, VK_NULL_HANDLE, NULL, NULL); // chunks that are reserved but not yet serialised case VulkanChunk::vkResetCommandPool: diff --git a/renderdoc/driver/vulkan/vk_core.h b/renderdoc/driver/vulkan/vk_core.h index 3d7e7c92c..b3a29fc64 100644 --- a/renderdoc/driver/vulkan/vk_core.h +++ b/renderdoc/driver/vulkan/vk_core.h @@ -409,6 +409,7 @@ private: bool m_NULLDescriptorsAllowed = false; bool m_ExtendedDynState = false; bool m_ExtendedDynState2 = false; + bool m_FragmentShadingRate = false; bool m_DynColorWrite = false; bool m_DynVertexInput = false; @@ -1132,6 +1133,7 @@ public: bool NULLDescriptorsAllowed() const { return m_NULLDescriptorsAllowed; } bool ExtendedDynamicState() const { return m_ExtendedDynState; } bool ExtendedDynamicState2() const { return m_ExtendedDynState2; } + bool FragmentShadingRate() const { return m_FragmentShadingRate; } bool DynamicColorWrite() const { return m_DynColorWrite; } bool DynamicVertexInput() const { return m_DynVertexInput; } VulkanRenderState &GetRenderState() { return m_RenderState; } @@ -2517,4 +2519,13 @@ public: const VkRenderingInfo *pRenderingInfo); IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdEndRendering, VkCommandBuffer commandBuffer); + + // VK_KHR_fragment_shading_rate + + IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdSetFragmentShadingRateKHR, VkCommandBuffer commandBuffer, + const VkExtent2D *pFragmentSize, + const VkFragmentShadingRateCombinerOpKHR combinerOps[2]); + VkResult vkGetPhysicalDeviceFragmentShadingRatesKHR( + VkPhysicalDevice physicalDevice, uint32_t *pFragmentShadingRateCount, + VkPhysicalDeviceFragmentShadingRateKHR *pFragmentShadingRates); }; diff --git a/renderdoc/driver/vulkan/vk_hookset_defs.h b/renderdoc/driver/vulkan/vk_hookset_defs.h index af14c7ede..a5b46c3bc 100644 --- a/renderdoc/driver/vulkan/vk_hookset_defs.h +++ b/renderdoc/driver/vulkan/vk_hookset_defs.h @@ -536,7 +536,8 @@ DeclExt(EXT_color_write_enable); \ DeclExt(EXT_extended_dynamic_state2); \ DeclExt(EXT_vertex_input_dynamic_state); \ - DeclExt(KHR_dynamic_rendering); + DeclExt(KHR_dynamic_rendering); \ + DeclExt(KHR_fragment_shading_rate); // for simplicity and since the check itself is platform agnostic, // these aren't protected in platform defines @@ -569,7 +570,8 @@ CheckExt(EXT_headless_surface, VKXX); \ CheckExt(EXT_metal_surface, VKXX); \ CheckExt(KHR_wayland_surface, VKXX); \ - CheckExt(KHR_performance_query, VKXX); + CheckExt(KHR_performance_query, VKXX); \ + CheckExt(KHR_fragment_shading_rate, VKXX); #define CheckDeviceExts() \ CheckExt(EXT_debug_marker, VKXX); \ @@ -642,7 +644,8 @@ CheckExt(EXT_color_write_enable, VKXX); \ CheckExt(EXT_extended_dynamic_state2, VK13); \ CheckExt(EXT_vertex_input_dynamic_state, VKXX); \ - CheckExt(KHR_dynamic_rendering, VK13); + CheckExt(KHR_dynamic_rendering, VK13); \ + CheckExt(KHR_fragment_shading_rate, VKXX); #define HookInitVulkanInstanceExts_PhysDev() \ HookInitExtension(KHR_surface, GetPhysicalDeviceSurfaceSupportKHR); \ @@ -688,6 +691,7 @@ EnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR); \ HookInitExtension(KHR_performance_query, GetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR); \ HookInitPromotedExtension(EXT_tooling_info, GetPhysicalDeviceToolProperties, EXT); \ + HookInitExtension(KHR_fragment_shading_rate, GetPhysicalDeviceFragmentShadingRatesKHR); \ HookInitExtension_PhysDev_Win32(); \ HookInitExtension_PhysDev_Linux(); \ HookInitExtension_PhysDev_GGP(); \ @@ -753,6 +757,7 @@ EnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR); \ HookInitExtension(KHR_performance_query, GetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR); \ HookInitPromotedExtension(EXT_tooling_info, GetPhysicalDeviceToolProperties, EXT); \ + HookInitExtension(KHR_fragment_shading_rate, GetPhysicalDeviceFragmentShadingRatesKHR); \ HookInitExtension_Instance_Win32(); \ HookInitExtension_Instance_Linux(); \ HookInitExtension_Instance_GGP(); \ @@ -897,6 +902,7 @@ HookInitExtension(EXT_vertex_input_dynamic_state, CmdSetVertexInputEXT); \ HookInitPromotedExtension(KHR_dynamic_rendering, CmdBeginRendering, KHR); \ HookInitPromotedExtension(KHR_dynamic_rendering, CmdEndRendering, KHR); \ + HookInitExtension(KHR_fragment_shading_rate, CmdSetFragmentShadingRateKHR); \ HookInitExtension_Device_Win32(); \ HookInitExtension_Device_Linux(); \ HookInitExtension_Device_GGP(); \ @@ -1609,6 +1615,12 @@ HookDefine2(void, vkCmdBeginRendering, VkCommandBuffer, commandBuffer, const VkRenderingInfo *, \ pRenderingInfo); \ HookDefine1(void, vkCmdEndRendering, VkCommandBuffer, commandBuffer); \ + HookDefine3(void, vkCmdSetFragmentShadingRateKHR, VkCommandBuffer, commandBuffer, \ + const VkExtent2D *, pFragmentSize, const VkFragmentShadingRateCombinerOpKHR *, \ + combinerOps); \ + HookDefine3(VkResult, vkGetPhysicalDeviceFragmentShadingRatesKHR, VkPhysicalDevice, \ + physicalDevice, uint32_t *, pFragmentShadingRateCount, \ + VkPhysicalDeviceFragmentShadingRateKHR *, pFragmentShadingRates); \ HookDefine_Win32(); \ HookDefine_Linux(); \ HookDefine_GGP(); \ diff --git a/renderdoc/driver/vulkan/vk_info.cpp b/renderdoc/driver/vulkan/vk_info.cpp index deffcfe7e..a0cc915d4 100644 --- a/renderdoc/driver/vulkan/vk_info.cpp +++ b/renderdoc/driver/vulkan/vk_info.cpp @@ -515,6 +515,19 @@ void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan, scissors[i] = pCreateInfo->pViewportState->pScissors[i]; } + // VkPipelineFragmentShadingRateStateCreateInfoKHR + shadingRate = {1, 1}; + shadingRateCombiners[0] = shadingRateCombiners[1] = VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR; + const VkPipelineFragmentShadingRateStateCreateInfoKHR *shadingRateInfo = + (const VkPipelineFragmentShadingRateStateCreateInfoKHR *)FindNextStruct( + pCreateInfo, VK_STRUCTURE_TYPE_PIPELINE_FRAGMENT_SHADING_RATE_STATE_CREATE_INFO_KHR); + if(shadingRateInfo) + { + shadingRate = shadingRateInfo->fragmentSize; + shadingRateCombiners[0] = shadingRateInfo->combinerOps[0]; + shadingRateCombiners[1] = shadingRateInfo->combinerOps[1]; + } + // VkPipelineDiscardRectangleStateCreateInfoEXT discardMode = VK_DISCARD_RECTANGLE_MODE_EXCLUSIVE_EXT; @@ -1048,6 +1061,7 @@ void VulkanCreationInfo::RenderPass::Init(VulkanResourceManager *resourceMan, ? depthstencilResolve->pDepthStencilResolveAttachment->attachment : -1); + // VK_EXT_fragment_density_map dst.fragmentDensityAttachment = (fragmentDensity && fragmentDensity->fragmentDensityMapAttachment.attachment != VK_ATTACHMENT_UNUSED @@ -1060,6 +1074,25 @@ void VulkanCreationInfo::RenderPass::Init(VulkanResourceManager *resourceMan, ? fragmentDensity->fragmentDensityMapAttachment.layout : VK_IMAGE_LAYOUT_UNDEFINED); + // VK_KHR_fragment_shading_rate + const VkFragmentShadingRateAttachmentInfoKHR *shadingRate = + (const VkFragmentShadingRateAttachmentInfoKHR *)FindNextStruct( + &src, VK_STRUCTURE_TYPE_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR); + dst.shadingRateAttachment = + (shadingRate && shadingRate->pFragmentShadingRateAttachment && + shadingRate->pFragmentShadingRateAttachment->attachment != VK_ATTACHMENT_UNUSED + ? shadingRate->pFragmentShadingRateAttachment->attachment + : -1); + + dst.shadingRateLayout = + (shadingRate && shadingRate->pFragmentShadingRateAttachment && + shadingRate->pFragmentShadingRateAttachment->attachment != VK_ATTACHMENT_UNUSED + ? shadingRate->pFragmentShadingRateAttachment->layout + : VK_IMAGE_LAYOUT_UNDEFINED); + + dst.shadingRateTexelSize = + shadingRate ? shadingRate->shadingRateAttachmentTexelSize : VkExtent2D({1, 1}); + for(uint32_t i = 0; i < 32; i++) { if(src.viewMask & (1 << i)) diff --git a/renderdoc/driver/vulkan/vk_info.h b/renderdoc/driver/vulkan/vk_info.h index 0c75e3cc6..18e336d89 100644 --- a/renderdoc/driver/vulkan/vk_info.h +++ b/renderdoc/driver/vulkan/vk_info.h @@ -403,6 +403,10 @@ struct VulkanCreationInfo // VkPipelineDiscardRectangleStateCreateInfoEXT rdcarray discardRectangles; VkDiscardRectangleModeEXT discardMode; + + // VkPipelineFragmentShadingRateCreateInfoKHR + VkExtent2D shadingRate; + VkFragmentShadingRateCombinerOpKHR shadingRateCombiners[2]; }; std::unordered_map m_Pipeline; @@ -451,6 +455,7 @@ struct VulkanCreationInfo int32_t depthstencilAttachment; int32_t depthstencilResolveAttachment; int32_t fragmentDensityAttachment; + int32_t shadingRateAttachment; rdcarray inputLayouts; rdcarray inputStencilLayouts; @@ -458,6 +463,9 @@ struct VulkanCreationInfo VkImageLayout depthLayout; VkImageLayout stencilLayout; VkImageLayout fragmentDensityLayout; + VkImageLayout shadingRateLayout; + + VkExtent2D shadingRateTexelSize; rdcarray multiviews; }; diff --git a/renderdoc/driver/vulkan/vk_next_chains.cpp b/renderdoc/driver/vulkan/vk_next_chains.cpp index 799581fde..7ac4c4312 100644 --- a/renderdoc/driver/vulkan/vk_next_chains.cpp +++ b/renderdoc/driver/vulkan/vk_next_chains.cpp @@ -164,6 +164,8 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct, COPY_STRUCT(VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, VkFenceCreateInfo); \ COPY_STRUCT(VK_STRUCTURE_TYPE_FILTER_CUBIC_IMAGE_VIEW_IMAGE_FORMAT_PROPERTIES_EXT, \ VkFilterCubicImageViewImageFormatPropertiesEXT); \ + COPY_STRUCT(VK_STRUCTURE_TYPE_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR, \ + VkFragmentShadingRateAttachmentInfoKHR); \ COPY_STRUCT(VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2, VkFormatProperties2); \ COPY_STRUCT(VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3, VkFormatProperties3); \ COPY_STRUCT(VK_STRUCTURE_TYPE_HDR_METADATA_EXT, VkHdrMetadataEXT) \ @@ -265,6 +267,12 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct, VkPhysicalDeviceFragmentDensityMap2PropertiesEXT); \ 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, \ + VkPhysicalDeviceFragmentShadingRateFeaturesKHR); \ + COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_KHR, \ + VkPhysicalDeviceFragmentShadingRateKHR); \ + COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_PROPERTIES_KHR, \ + VkPhysicalDeviceFragmentShadingRatePropertiesKHR); \ COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES, \ VkPhysicalDeviceHostQueryResetFeatures); \ COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES, VkPhysicalDeviceIDProperties); \ @@ -448,6 +456,8 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct, COPY_STRUCT(VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_STATISTIC_KHR, VkPipelineExecutableStatisticKHR) \ COPY_STRUCT(VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INTERNAL_REPRESENTATION_KHR, \ VkPipelineExecutableInternalRepresentationKHR) \ + COPY_STRUCT(VK_STRUCTURE_TYPE_PIPELINE_FRAGMENT_SHADING_RATE_STATE_CREATE_INFO_KHR, \ + VkPipelineFragmentShadingRateStateCreateInfoKHR) \ COPY_STRUCT(VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, \ VkPipelineInputAssemblyStateCreateInfo); \ COPY_STRUCT(VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, \ @@ -595,6 +605,8 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct, UnwrapInPlace(out->srcSet), UnwrapInPlace(out->dstSet)); \ UNWRAP_STRUCT(VK_STRUCTURE_TYPE_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_INFO_EXT, \ VkRenderingFragmentDensityMapAttachmentInfoEXT, UnwrapInPlace(out->imageView)); \ + UNWRAP_STRUCT(VK_STRUCTURE_TYPE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR, \ + VkRenderingFragmentShadingRateAttachmentInfoKHR, UnwrapInPlace(out->imageView)); \ UNWRAP_STRUCT(VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV, \ VkDedicatedAllocationMemoryAllocateInfoNV, UnwrapInPlace(out->buffer), \ UnwrapInPlace(out->image)); \ @@ -715,7 +727,6 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct, case VK_STRUCTURE_TYPE_DEVICE_MEMORY_REPORT_CALLBACK_DATA_EXT: \ case VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_2_EXT: \ case VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT: \ - case VK_STRUCTURE_TYPE_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR: \ case VK_STRUCTURE_TYPE_FRAMEBUFFER_MIXED_SAMPLES_COMBINATION_NV: \ case VK_STRUCTURE_TYPE_GENERATED_COMMANDS_INFO_NV: \ case VK_STRUCTURE_TYPE_GENERATED_COMMANDS_MEMORY_REQUIREMENTS_INFO_NV: \ @@ -772,9 +783,6 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct, 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_FRAGMENT_SHADING_RATE_FEATURES_KHR: \ - case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_KHR: \ - case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_PROPERTIES_KHR: \ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT: \ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_MIN_LOD_FEATURES_EXT: \ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INHERITED_VIEWPORT_SCISSOR_FEATURES_NV: \ @@ -811,7 +819,6 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct, case VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_REDUCTION_STATE_CREATE_INFO_NV: \ case VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_TO_COLOR_STATE_CREATE_INFO_NV: \ case VK_STRUCTURE_TYPE_PIPELINE_FRAGMENT_SHADING_RATE_ENUM_STATE_CREATE_INFO_NV: \ - case VK_STRUCTURE_TYPE_PIPELINE_FRAGMENT_SHADING_RATE_STATE_CREATE_INFO_KHR: \ case VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR: \ case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_PROVOKING_VERTEX_STATE_CREATE_INFO_EXT: \ case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_RASTERIZATION_ORDER_AMD: \ @@ -830,7 +837,6 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct, case VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_INTERFACE_CREATE_INFO_KHR: \ case VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR: \ case VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_NV: \ - case VK_STRUCTURE_TYPE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR: \ case VK_STRUCTURE_TYPE_RENDER_PASS_TRANSFORM_BEGIN_INFO_QCOM: \ case VK_STRUCTURE_TYPE_SAMPLER_BORDER_COLOR_COMPONENT_MAPPING_CREATE_INFO_EXT: \ case VK_STRUCTURE_TYPE_SCREEN_SURFACE_CREATE_INFO_QNX: \ diff --git a/renderdoc/driver/vulkan/vk_replay.cpp b/renderdoc/driver/vulkan/vk_replay.cpp index f9f7bf9ef..db94940d8 100644 --- a/renderdoc/driver/vulkan/vk_replay.cpp +++ b/renderdoc/driver/vulkan/vk_replay.cpp @@ -1375,6 +1375,34 @@ void VulkanReplay::SavePipelineState(uint32_t eventId) default: break; } + ret.rasterizer.pipelineShadingRate = {state.pipelineShadingRate.width, + state.pipelineShadingRate.height}; + + ShadingRateCombiner combiners[2] = {}; + for(int i = 0; i < 2; i++) + { + switch(state.shadingRateCombiners[i]) + { + default: + case VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR: + combiners[i] = ShadingRateCombiner::Keep; + break; + case VK_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_KHR: + combiners[i] = ShadingRateCombiner::Replace; + break; + case VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MIN_KHR: + combiners[i] = ShadingRateCombiner::Min; + break; + case VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MAX_KHR: + combiners[i] = ShadingRateCombiner::Max; + break; + case VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MUL_KHR: + combiners[i] = ShadingRateCombiner::Multiply; + break; + } + } + ret.rasterizer.shadingRateCombiners = {combiners[0], combiners[1]}; + ret.rasterizer.lineRasterMode = LineRaster::Default; // "VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT is equivalent to @@ -1666,6 +1694,34 @@ void VulkanReplay::SavePipelineState(uint32_t eventId) rpState.fragmentDensityAttachment = -1; } + if(dyn.shadingRateView != VK_NULL_HANDLE) + { + fbState.attachments.push_back({}); + + ResourceId viewid = GetResID(dyn.shadingRateView); + + fbState.attachments.back().viewResourceId = rm->GetOriginalID(viewid); + ret.currentPass.framebuffer.attachments[attIdx].imageResourceId = + rm->GetOriginalID(c.m_ImageView[viewid].image); + + fbState.attachments.back().viewFormat = MakeResourceFormat(c.m_ImageView[viewid].format); + fbState.attachments.back().firstMip = c.m_ImageView[viewid].range.baseMipLevel; + fbState.attachments.back().firstSlice = c.m_ImageView[viewid].range.baseArrayLayer; + fbState.attachments.back().numMips = c.m_ImageView[viewid].range.levelCount; + fbState.attachments.back().numSlices = c.m_ImageView[viewid].range.layerCount; + + Convert(fbState.attachments.back().swizzle, c.m_ImageView[viewid].componentMapping); + + rpState.shadingRateAttachment = int32_t(attIdx++); + rpState.shadingRateTexelSize = {dyn.shadingRateTexelSize.width, + dyn.shadingRateTexelSize.height}; + } + else + { + rpState.shadingRateAttachment = -1; + rpState.shadingRateTexelSize = {1, 1}; + } + rpState.multiviews.clear(); for(uint32_t v = 0; v < 32; v++) { @@ -1692,6 +1748,11 @@ void VulkanReplay::SavePipelineState(uint32_t eventId) c.m_RenderPass[state.GetRenderPass()].subpasses[state.subpass].depthstencilResolveAttachment; ret.currentPass.renderpass.fragmentDensityAttachment = c.m_RenderPass[state.GetRenderPass()].subpasses[state.subpass].fragmentDensityAttachment; + ret.currentPass.renderpass.shadingRateAttachment = + c.m_RenderPass[state.GetRenderPass()].subpasses[state.subpass].shadingRateAttachment; + VkExtent2D texelSize = + c.m_RenderPass[state.GetRenderPass()].subpasses[state.subpass].shadingRateTexelSize; + ret.currentPass.renderpass.shadingRateTexelSize = {texelSize.width, texelSize.height}; ret.currentPass.renderpass.multiviews = c.m_RenderPass[state.GetRenderPass()].subpasses[state.subpass].multiviews; @@ -1764,6 +1825,8 @@ void VulkanReplay::SavePipelineState(uint32_t eventId) ret.currentPass.renderpass.depthstencilAttachment = -1; ret.currentPass.renderpass.depthstencilResolveAttachment = -1; ret.currentPass.renderpass.fragmentDensityAttachment = -1; + ret.currentPass.renderpass.shadingRateAttachment = -1; + ret.currentPass.renderpass.shadingRateTexelSize = {1, 1}; ret.currentPass.framebuffer.resourceId = ResourceId(); ret.currentPass.framebuffer.attachments.clear(); diff --git a/renderdoc/driver/vulkan/vk_serialise.cpp b/renderdoc/driver/vulkan/vk_serialise.cpp index 0ee85e5e5..09a3a96e0 100644 --- a/renderdoc/driver/vulkan/vk_serialise.cpp +++ b/renderdoc/driver/vulkan/vk_serialise.cpp @@ -954,6 +954,8 @@ SERIALISE_VK_HANDLES(); VkCommandBufferInheritanceRenderingInfo) \ PNEXT_STRUCT(VK_STRUCTURE_TYPE_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_INFO_EXT, \ VkRenderingFragmentDensityMapAttachmentInfoEXT) \ + PNEXT_STRUCT(VK_STRUCTURE_TYPE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR, \ + VkRenderingFragmentShadingRateAttachmentInfoKHR) \ \ /* VK_KHR_external_fence_capabilities */ \ PNEXT_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO, \ @@ -1055,6 +1057,18 @@ SERIALISE_VK_HANDLES(); /* VK_KHR_incremental_present */ \ PNEXT_STRUCT(VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR, VkPresentRegionsKHR) \ \ + /* VK_KHR_fragment_shading_rate */ \ + PNEXT_STRUCT(VK_STRUCTURE_TYPE_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR, \ + VkFragmentShadingRateAttachmentInfoKHR) \ + PNEXT_STRUCT(VK_STRUCTURE_TYPE_PIPELINE_FRAGMENT_SHADING_RATE_STATE_CREATE_INFO_KHR, \ + VkPipelineFragmentShadingRateStateCreateInfoKHR) \ + PNEXT_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_PROPERTIES_KHR, \ + VkPhysicalDeviceFragmentShadingRatePropertiesKHR) \ + PNEXT_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR, \ + VkPhysicalDeviceFragmentShadingRateFeaturesKHR) \ + PNEXT_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_KHR, \ + VkPhysicalDeviceFragmentShadingRateKHR) \ + \ /* VK_KHR_maintenance2 */ \ PNEXT_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES, \ VkPhysicalDevicePointClippingProperties) \ @@ -1380,15 +1394,6 @@ SERIALISE_VK_HANDLES(); PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_PROPERTIES_KHR) \ PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR) \ \ - /* VK_KHR_fragment_shading_rate */ \ - PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR) \ - PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PIPELINE_FRAGMENT_SHADING_RATE_STATE_CREATE_INFO_KHR) \ - PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_PROPERTIES_KHR) \ - PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR) \ - PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_KHR) \ - /* Interaction with VK_KHR_dynamic_rendering */ \ - PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR) \ - \ /* VK_KHR_pipeline_library */ \ PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR) \ \ @@ -4939,6 +4944,108 @@ void DoSerialise(SerialiserType &ser, VkInputAttachmentAspectReference &el) SERIALISE_MEMBER_VKFLAGS(VkImageAspectFlags, aspectMask); } +template +void DoSerialise(SerialiserType &ser, VkFragmentShadingRateAttachmentInfoKHR &el) +{ + RDCASSERT(ser.IsReading() || + el.sType == VK_STRUCTURE_TYPE_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER_OPT(pFragmentShadingRateAttachment).Important(); + SERIALISE_MEMBER(shadingRateAttachmentTexelSize); +} + +template <> +void Deserialise(const VkFragmentShadingRateAttachmentInfoKHR &el) +{ + DeserialiseNext(el.pNext); + delete el.pFragmentShadingRateAttachment; +} + +template +void DoSerialise(SerialiserType &ser, VkPipelineFragmentShadingRateStateCreateInfoKHR &el) +{ + RDCASSERT(ser.IsReading() || + el.sType == VK_STRUCTURE_TYPE_PIPELINE_FRAGMENT_SHADING_RATE_STATE_CREATE_INFO_KHR); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER(fragmentSize); + SERIALISE_MEMBER(combinerOps); +} + +template <> +void Deserialise(const VkPipelineFragmentShadingRateStateCreateInfoKHR &el) +{ + DeserialiseNext(el.pNext); +} + +template +void DoSerialise(SerialiserType &ser, VkPhysicalDeviceFragmentShadingRatePropertiesKHR &el) +{ + RDCASSERT(ser.IsReading() || + el.sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_PROPERTIES_KHR); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER(minFragmentShadingRateAttachmentTexelSize); + SERIALISE_MEMBER(maxFragmentShadingRateAttachmentTexelSize); + SERIALISE_MEMBER(maxFragmentShadingRateAttachmentTexelSizeAspectRatio); + SERIALISE_MEMBER(primitiveFragmentShadingRateWithMultipleViewports); + SERIALISE_MEMBER(layeredShadingRateAttachments); + SERIALISE_MEMBER(fragmentShadingRateNonTrivialCombinerOps); + SERIALISE_MEMBER(maxFragmentSize); + SERIALISE_MEMBER(maxFragmentSizeAspectRatio); + SERIALISE_MEMBER(maxFragmentShadingRateCoverageSamples); + SERIALISE_MEMBER(maxFragmentShadingRateRasterizationSamples); + SERIALISE_MEMBER(fragmentShadingRateWithShaderDepthStencilWrites); + SERIALISE_MEMBER(fragmentShadingRateWithSampleMask); + SERIALISE_MEMBER(fragmentShadingRateWithShaderSampleMask); + SERIALISE_MEMBER(fragmentShadingRateWithConservativeRasterization); + SERIALISE_MEMBER(fragmentShadingRateWithFragmentShaderInterlock); + SERIALISE_MEMBER(fragmentShadingRateWithCustomSampleLocations); + SERIALISE_MEMBER(fragmentShadingRateStrictMultiplyCombiner); +} + +template <> +void Deserialise(const VkPhysicalDeviceFragmentShadingRatePropertiesKHR &el) +{ + DeserialiseNext(el.pNext); +} + +template +void DoSerialise(SerialiserType &ser, VkPhysicalDeviceFragmentShadingRateFeaturesKHR &el) +{ + RDCASSERT(ser.IsReading() || + el.sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER(pipelineFragmentShadingRate); + SERIALISE_MEMBER(primitiveFragmentShadingRate); + SERIALISE_MEMBER(attachmentFragmentShadingRate); +} + +template <> +void Deserialise(const VkPhysicalDeviceFragmentShadingRateFeaturesKHR &el) +{ + DeserialiseNext(el.pNext); +} + +template +void DoSerialise(SerialiserType &ser, VkPhysicalDeviceFragmentShadingRateKHR &el) +{ + RDCASSERT(ser.IsReading() || + el.sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_KHR); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER_VKFLAGS(VkSampleCountFlags, sampleCounts); + SERIALISE_MEMBER(fragmentSize); +} + +template <> +void Deserialise(const VkPhysicalDeviceFragmentShadingRateKHR &el) +{ + DeserialiseNext(el.pNext); +} + template void DoSerialise(SerialiserType &ser, VkPhysicalDevicePointClippingProperties &el) { @@ -7606,6 +7713,24 @@ void Deserialise(const VkRenderingFragmentDensityMapAttachmentInfoEXT &el) DeserialiseNext(el.pNext); } +template +void DoSerialise(SerialiserType &ser, VkRenderingFragmentShadingRateAttachmentInfoKHR &el) +{ + RDCASSERT(ser.IsReading() || + el.sType == VK_STRUCTURE_TYPE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER(imageView); + SERIALISE_MEMBER(imageLayout); + SERIALISE_MEMBER(shadingRateAttachmentTexelSize); +} + +template <> +void Deserialise(const VkRenderingFragmentShadingRateAttachmentInfoKHR &el) +{ + DeserialiseNext(el.pNext); +} + template void DoSerialise(SerialiserType &ser, VkCommandBufferInheritanceRenderingInfo &el) { @@ -10076,6 +10201,7 @@ INSTANTIATE_SERIALISE_TYPE(VkFenceGetFdInfoKHR); INSTANTIATE_SERIALISE_TYPE(VkFilterCubicImageViewImageFormatPropertiesEXT); INSTANTIATE_SERIALISE_TYPE(VkFormatProperties2); INSTANTIATE_SERIALISE_TYPE(VkFormatProperties3KHR); +INSTANTIATE_SERIALISE_TYPE(VkFragmentShadingRateAttachmentInfoKHR); INSTANTIATE_SERIALISE_TYPE(VkFramebufferAttachmentImageInfo); INSTANTIATE_SERIALISE_TYPE(VkFramebufferAttachmentsCreateInfo); INSTANTIATE_SERIALISE_TYPE(VkFramebufferCreateInfo); @@ -10157,6 +10283,9 @@ INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT); INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceGlobalPriorityQueryFeaturesKHR); INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceGroupProperties); INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceHostQueryResetFeatures); +INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceFragmentShadingRateKHR); +INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceFragmentShadingRateFeaturesKHR); +INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceFragmentShadingRatePropertiesKHR); INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceIDProperties); INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceImageFormatInfo2); INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceImagelessFramebufferFeatures); @@ -10250,6 +10379,7 @@ INSTANTIATE_SERIALISE_TYPE(VkPipelineExecutableInfoKHR); INSTANTIATE_SERIALISE_TYPE(VkPipelineExecutableInternalRepresentationKHR); INSTANTIATE_SERIALISE_TYPE(VkPipelineExecutablePropertiesKHR); INSTANTIATE_SERIALISE_TYPE(VkPipelineExecutableStatisticKHR); +INSTANTIATE_SERIALISE_TYPE(VkPipelineFragmentShadingRateStateCreateInfoKHR); INSTANTIATE_SERIALISE_TYPE(VkPipelineInfoKHR); INSTANTIATE_SERIALISE_TYPE(VkPipelineInputAssemblyStateCreateInfo); INSTANTIATE_SERIALISE_TYPE(VkPipelineLayoutCreateInfo); @@ -10282,6 +10412,7 @@ INSTANTIATE_SERIALISE_TYPE(VkQueueFamilyProperties2); INSTANTIATE_SERIALISE_TYPE(VkRefreshCycleDurationGOOGLE); INSTANTIATE_SERIALISE_TYPE(VkRenderingAttachmentInfo); INSTANTIATE_SERIALISE_TYPE(VkRenderingFragmentDensityMapAttachmentInfoEXT); +INSTANTIATE_SERIALISE_TYPE(VkRenderingFragmentShadingRateAttachmentInfoKHR); INSTANTIATE_SERIALISE_TYPE(VkRenderingInfo); INSTANTIATE_SERIALISE_TYPE(VkRenderPassAttachmentBeginInfo); INSTANTIATE_SERIALISE_TYPE(VkRenderPassBeginInfo); diff --git a/renderdoc/driver/vulkan/vk_shader_cache.cpp b/renderdoc/driver/vulkan/vk_shader_cache.cpp index d0c4d9a2a..98e8942ea 100644 --- a/renderdoc/driver/vulkan/vk_shader_cache.cpp +++ b/renderdoc/driver/vulkan/vk_shader_cache.cpp @@ -909,6 +909,22 @@ void VulkanShaderCache::MakeGraphicsPipelineInfo(VkGraphicsPipelineCreateInfo &p ret.pNext = &discardRects; } + static VkPipelineFragmentShadingRateStateCreateInfoKHR shadingRate = { + VK_STRUCTURE_TYPE_PIPELINE_FRAGMENT_SHADING_RATE_STATE_CREATE_INFO_KHR, + }; + + if(pipeInfo.shadingRate.width != 1 || pipeInfo.shadingRate.height != 1 || + pipeInfo.shadingRateCombiners[0] != VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR || + pipeInfo.shadingRateCombiners[1] != VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR) + { + shadingRate.fragmentSize = pipeInfo.shadingRate; + shadingRate.combinerOps[0] = pipeInfo.shadingRateCombiners[0]; + shadingRate.combinerOps[1] = pipeInfo.shadingRateCombiners[1]; + + shadingRate.pNext = ret.pNext; + ret.pNext = &shadingRate; + } + // never create derivatives ret.flags &= ~VK_PIPELINE_CREATE_DERIVATIVE_BIT; diff --git a/renderdoc/driver/vulkan/vk_state.cpp b/renderdoc/driver/vulkan/vk_state.cpp index 2344e00ff..889829780 100644 --- a/renderdoc/driver/vulkan/vk_state.cpp +++ b/renderdoc/driver/vulkan/vk_state.cpp @@ -423,6 +423,13 @@ void VulkanRenderState::BindPipeline(WrappedVulkan *vk, VkCommandBuffer cmd, if(stippleFactor && dynamicStates[VkDynamicLineStippleEXT]) ObjDisp(cmd)->CmdSetLineStippleEXT(Unwrap(cmd), stippleFactor, stipplePattern); + if(vk->FragmentShadingRate()) + { + if(dynamicStates[VkDynamicShadingRateKHR]) + ObjDisp(cmd)->CmdSetFragmentShadingRateKHR(Unwrap(cmd), &pipelineShadingRate, + shadingRateCombiners); + } + if(graphics.pipeline != ResourceId()) BindDescriptorSets(vk, cmd, graphics, VK_PIPELINE_BIND_POINT_GRAPHICS); diff --git a/renderdoc/driver/vulkan/vk_state.h b/renderdoc/driver/vulkan/vk_state.h index 98659a876..870091117 100644 --- a/renderdoc/driver/vulkan/vk_state.h +++ b/renderdoc/driver/vulkan/vk_state.h @@ -228,8 +228,18 @@ struct VulkanRenderState VkImageView fragmentDensityView = VK_NULL_HANDLE; VkImageLayout fragmentDensityLayout = VK_IMAGE_LAYOUT_UNDEFINED; + + VkImageView shadingRateView = VK_NULL_HANDLE; + VkImageLayout shadingRateLayout = VK_IMAGE_LAYOUT_UNDEFINED; + VkExtent2D shadingRateTexelSize = {1, 1}; } dynamicRendering; + // shading rate + VkExtent2D pipelineShadingRate = {1, 1}; + VkFragmentShadingRateCombinerOpKHR shadingRateCombiners[2] = { + VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR, VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR, + }; + private: ResourceId renderPass; ResourceId framebuffer; diff --git a/renderdoc/driver/vulkan/vk_stringise.cpp b/renderdoc/driver/vulkan/vk_stringise.cpp index d62ad67f8..811d924e3 100644 --- a/renderdoc/driver/vulkan/vk_stringise.cpp +++ b/renderdoc/driver/vulkan/vk_stringise.cpp @@ -28,7 +28,7 @@ template <> rdcstr DoStringise(const VulkanChunk &el) { - RDCCOMPILE_ASSERT((uint32_t)VulkanChunk::Max == 1175, "Chunks changed without updating names"); + RDCCOMPILE_ASSERT((uint32_t)VulkanChunk::Max == 1176, "Chunks changed without updating names"); BEGIN_ENUM_STRINGISE(VulkanChunk) { @@ -207,6 +207,7 @@ rdcstr DoStringise(const VulkanChunk &el) STRINGISE_ENUM_CLASS(vkCmdSetVertexInputEXT) STRINGISE_ENUM_CLASS(vkCmdBeginRendering) STRINGISE_ENUM_CLASS(vkCmdEndRendering) + STRINGISE_ENUM_CLASS(vkCmdSetFragmentShadingRateKHR) 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 e5581534b..941572167 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp @@ -196,6 +196,15 @@ rdcarray WrappedVulkan::GetImplicitRenderPassBarriers(uint atts.back().attachment = (uint32_t)rpinfo.subpasses[subpass].fragmentDensityAttachment; atts.back().layout = rpinfo.subpasses[subpass].fragmentDensityLayout; } + + int32_t sr = rpinfo.subpasses[subpass].shadingRateAttachment; + + if(sr != -1) + { + atts.push_back({}); + atts.back().attachment = (uint32_t)rpinfo.subpasses[subpass].shadingRateAttachment; + atts.back().layout = rpinfo.subpasses[subpass].shadingRateLayout; + } } for(size_t i = 0; i < atts.size(); i++) @@ -303,6 +312,12 @@ rdcarray WrappedVulkan::GetImplicitRenderPassBarriers(uint barrier.oldLayout = rpinfo.subpasses[s - 1].fragmentDensityLayout; break; } + + if((uint32_t)rpinfo.subpasses[s - 1].shadingRateAttachment == idx) + { + barrier.oldLayout = rpinfo.subpasses[s - 1].shadingRateLayout; + break; + } } // if we support separate depth stencil and the format contains stencil, add barriers @@ -1386,7 +1401,24 @@ bool WrappedVulkan::Serialise_vkEndCommandBuffer(SerialiserType &ser, VkCommandB }; if(renderstate.dynamicRendering.fragmentDensityView != VK_NULL_HANDLE) + { + fragmentDensity.pNext = info.pNext; info.pNext = &fragmentDensity; + } + + VkRenderingFragmentShadingRateAttachmentInfoKHR shadingRate = { + VK_STRUCTURE_TYPE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR, + NULL, + renderstate.dynamicRendering.shadingRateView, + renderstate.dynamicRendering.shadingRateLayout, + renderstate.dynamicRendering.shadingRateTexelSize, + }; + + if(renderstate.dynamicRendering.shadingRateView != VK_NULL_HANDLE) + { + shadingRate.pNext = info.pNext; + info.pNext = &shadingRate; + } byte *tempMem = GetTempMemory(GetNextPatchSize(&info)); VkRenderingInfo *unwrappedInfo = UnwrapStructAndChain(m_State, tempMem, &info); @@ -2943,6 +2975,12 @@ bool WrappedVulkan::Serialise_vkCmdBindPipeline(SerialiserType &ser, VkCommandBu { renderstate.discardRectangles = pipeInfo.discardRectangles; } + if(!pipeInfo.dynamicStates[VkDynamicShadingRateKHR]) + { + renderstate.pipelineShadingRate = pipeInfo.shadingRate; + renderstate.shadingRateCombiners[0] = pipeInfo.shadingRateCombiners[0]; + renderstate.shadingRateCombiners[1] = pipeInfo.shadingRateCombiners[1]; + } if(!pipeInfo.dynamicStates[VkDynamicLineStippleEXT]) { renderstate.stippleFactor = pipeInfo.stippleFactor; @@ -6702,6 +6740,19 @@ bool WrappedVulkan::Serialise_vkCmdBeginRendering(SerialiserType &ser, VkCommand fragmentDensityAttachment->imageLayout; } + VkRenderingFragmentShadingRateAttachmentInfoKHR *shadingRateAttachment = + (VkRenderingFragmentShadingRateAttachmentInfoKHR *)FindNextStruct( + &RenderingInfo, + VK_STRUCTURE_TYPE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR); + + if(shadingRateAttachment) + { + renderstate.dynamicRendering.shadingRateView = shadingRateAttachment->imageView; + renderstate.dynamicRendering.shadingRateLayout = shadingRateAttachment->imageLayout; + renderstate.dynamicRendering.shadingRateTexelSize = + shadingRateAttachment->shadingRateAttachmentTexelSize; + } + rdcarray attachments; for(size_t i = 0; i < renderstate.dynamicRendering.color.size(); i++) @@ -6835,6 +6886,19 @@ bool WrappedVulkan::Serialise_vkCmdBeginRendering(SerialiserType &ser, VkCommand renderstate.dynamicRendering.fragmentDensityLayout = fragmentDensityAttachment->imageLayout; } + VkRenderingFragmentShadingRateAttachmentInfoKHR *shadingRateAttachment = + (VkRenderingFragmentShadingRateAttachmentInfoKHR *)FindNextStruct( + &RenderingInfo, + VK_STRUCTURE_TYPE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR); + + if(shadingRateAttachment) + { + renderstate.dynamicRendering.shadingRateView = shadingRateAttachment->imageView; + renderstate.dynamicRendering.shadingRateLayout = shadingRateAttachment->imageLayout; + renderstate.dynamicRendering.shadingRateTexelSize = + shadingRateAttachment->shadingRateAttachmentTexelSize; + } + rdcarray attachments; for(size_t i = 0; i < renderstate.dynamicRendering.color.size(); i++) diff --git a/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp index a40c52d6e..a00a33dcc 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp @@ -2877,6 +2877,19 @@ bool WrappedVulkan::Serialise_vkCreateDevice(SerialiserType &ser, VkPhysicalDevi CHECK_PHYS_EXT_FEATURE(textureCompressionASTC_HDR); } END_PHYS_EXT_CHECK(); + + BEGIN_PHYS_EXT_CHECK(VkPhysicalDeviceFragmentShadingRateFeaturesKHR, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR); + { + CHECK_PHYS_EXT_FEATURE(pipelineFragmentShadingRate); + CHECK_PHYS_EXT_FEATURE(primitiveFragmentShadingRate); + CHECK_PHYS_EXT_FEATURE(attachmentFragmentShadingRate); + + m_FragmentShadingRate = (ext->pipelineFragmentShadingRate != VK_FALSE) || + (ext->primitiveFragmentShadingRate != VK_FALSE) || + (ext->attachmentFragmentShadingRate != VK_FALSE); + } + END_PHYS_EXT_CHECK(); } if(availFeatures.depthClamp) diff --git a/renderdoc/driver/vulkan/wrappers/vk_dynamic_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_dynamic_funcs.cpp index 2ff7d633e..7b8bf3f21 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_dynamic_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_dynamic_funcs.cpp @@ -1878,6 +1878,73 @@ void WrappedVulkan::vkCmdSetRasterizerDiscardEnable(VkCommandBuffer commandBuffe } } +template +bool WrappedVulkan::Serialise_vkCmdSetFragmentShadingRateKHR( + SerialiserType &ser, VkCommandBuffer commandBuffer, const VkExtent2D *pFragmentSize, + const VkFragmentShadingRateCombinerOpKHR combinerOps[2]) +{ + SERIALISE_ELEMENT(commandBuffer); + SERIALISE_ELEMENT_OPT(pFragmentSize).Important(); + SERIALISE_ELEMENT_ARRAY(combinerOps, 4).Important(); + + 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); + + { + VulkanRenderState &renderstate = GetCmdRenderState(); + renderstate.pipelineShadingRate = *pFragmentSize; + renderstate.shadingRateCombiners[0] = combinerOps[0]; + renderstate.shadingRateCombiners[1] = combinerOps[1]; + } + } + else + { + commandBuffer = VK_NULL_HANDLE; + } + } + + if(commandBuffer != VK_NULL_HANDLE) + ObjDisp(commandBuffer) + ->CmdSetFragmentShadingRateKHR(Unwrap(commandBuffer), pFragmentSize, combinerOps); + } + + return true; +} + +void WrappedVulkan::vkCmdSetFragmentShadingRateKHR( + VkCommandBuffer commandBuffer, const VkExtent2D *pFragmentSize, + const VkFragmentShadingRateCombinerOpKHR combinerOps[2]) +{ + SCOPED_DBG_SINK(); + + SERIALISE_TIME_CALL( + ObjDisp(commandBuffer) + ->CmdSetFragmentShadingRateKHR(Unwrap(commandBuffer), pFragmentSize, combinerOps)); + + if(IsCaptureMode(m_State)) + { + VkResourceRecord *record = GetRecord(commandBuffer); + + CACHE_THREAD_SERIALISER(); + + SCOPED_SERIALISE_CHUNK(VulkanChunk::vkCmdSetFragmentShadingRateKHR); + Serialise_vkCmdSetFragmentShadingRateKHR(ser, commandBuffer, pFragmentSize, combinerOps); + + record->AddChunk(scope.Get(&record->cmdInfo->alloc)); + } +} + INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdSetViewport, VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, const VkViewport *pViewports); @@ -1965,3 +2032,7 @@ INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdSetPrimitiveRestartEnable, VkCommandB VkBool32 primitiveRestartEnable); INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdSetRasterizerDiscardEnable, VkCommandBuffer commandBuffer, VkBool32 rasterizerDiscardEnable); + +INSTANTIATE_FUNCTION_SERIALISED(void, vkCmdSetFragmentShadingRateKHR, VkCommandBuffer commandBuffer, + const VkExtent2D *pFragmentSize, + const VkFragmentShadingRateCombinerOpKHR combinerOps[2]); diff --git a/renderdoc/driver/vulkan/wrappers/vk_get_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_get_funcs.cpp index 7e092062e..0256f9f2a 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_get_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_get_funcs.cpp @@ -1095,3 +1095,12 @@ VkResult WrappedVulkan::vkGetPhysicalDeviceToolProperties(VkPhysicalDevice physi (*pToolCount)++; return VK_SUCCESS; } + +VkResult WrappedVulkan::vkGetPhysicalDeviceFragmentShadingRatesKHR( + VkPhysicalDevice physicalDevice, uint32_t *pFragmentShadingRateCount, + VkPhysicalDeviceFragmentShadingRateKHR *pFragmentShadingRates) +{ + return ObjDisp(physicalDevice) + ->GetPhysicalDeviceFragmentShadingRatesKHR(Unwrap(physicalDevice), pFragmentShadingRateCount, + pFragmentShadingRates); +} diff --git a/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp index e6e16d17e..e216a0aff 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp @@ -2141,6 +2141,8 @@ bool WrappedVulkan::Serialise_vkCreateImage(SerialiserType &ser, VkDevice device prefix = "2D " + depth + " Attachment"; else if(CreateInfo.usage & VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT) prefix = "2D Fragment Density Map Attachment"; + else if(CreateInfo.usage & VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR) + prefix = "2D Fragment Shading Rate Attachment"; } else if(CreateInfo.imageType == VK_IMAGE_TYPE_3D) { diff --git a/renderdoc/replay/renderdoc_serialise.inl b/renderdoc/replay/renderdoc_serialise.inl index 6f59f0154..ef51fea0b 100644 --- a/renderdoc/replay/renderdoc_serialise.inl +++ b/renderdoc/replay/renderdoc_serialise.inl @@ -2143,7 +2143,10 @@ void DoSerialise(SerialiserType &ser, VKPipe::Rasterizer &el) SERIALISE_MEMBER(lineStippleFactor); SERIALISE_MEMBER(lineStipplePattern); - SIZE_CHECK(52); + SERIALISE_MEMBER(pipelineShadingRate); + SERIALISE_MEMBER(shadingRateCombiners); + + SIZE_CHECK(68); } template @@ -2211,9 +2214,11 @@ void DoSerialise(SerialiserType &ser, VKPipe::RenderPass &el) SERIALISE_MEMBER(depthstencilAttachment); SERIALISE_MEMBER(depthstencilResolveAttachment); SERIALISE_MEMBER(fragmentDensityAttachment); + SERIALISE_MEMBER(shadingRateAttachment); + SERIALISE_MEMBER(shadingRateTexelSize); SERIALISE_MEMBER(multiviews); - SIZE_CHECK(128); + SIZE_CHECK(136); } template @@ -2263,7 +2268,7 @@ void DoSerialise(SerialiserType &ser, VKPipe::CurrentPass &el) SERIALISE_MEMBER(framebuffer); SERIALISE_MEMBER(renderArea); - SIZE_CHECK(192); + SIZE_CHECK(200); } template @@ -2331,7 +2336,7 @@ void DoSerialise(SerialiserType &ser, VKPipe::State &el) SERIALISE_MEMBER(conditionalRendering); - SIZE_CHECK(2016); + SIZE_CHECK(2040); } #pragma endregion Vulkan pipeline state