From c6edcf9a3884ac11614246b058b441cabaf65b2a Mon Sep 17 00:00:00 2001 From: tuxerr Date: Sun, 24 Feb 2019 19:44:26 -0800 Subject: [PATCH] add support for VK_EXT_fragment_density_map --- .../VulkanPipelineStateViewer.cpp | 13 +++- renderdoc/api/replay/vk_pipestate.h | 6 ++ renderdoc/driver/vulkan/vk_common.h | 5 ++ renderdoc/driver/vulkan/vk_core.cpp | 42 ++++++++++++ renderdoc/driver/vulkan/vk_info.cpp | 34 ++++++++++ renderdoc/driver/vulkan/vk_info.h | 2 + renderdoc/driver/vulkan/vk_replay.cpp | 3 + renderdoc/driver/vulkan/vk_serialise.cpp | 68 +++++++++++++++++-- .../driver/vulkan/wrappers/vk_cmd_funcs.cpp | 15 ++++ .../vulkan/wrappers/vk_device_funcs.cpp | 17 +++++ .../driver/vulkan/wrappers/vk_misc_funcs.cpp | 12 ++-- .../vulkan/wrappers/vk_resource_funcs.cpp | 5 ++ renderdoc/replay/renderdoc_serialise.inl | 1 + 13 files changed, 213 insertions(+), 10 deletions(-) diff --git a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp b/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp index 285acf099..e31f2861c 100644 --- a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp +++ b/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp @@ -2174,7 +2174,8 @@ void VulkanPipelineStateViewer::setState() bool filledSlot = (p.imageResourceId != ResourceId()); bool usedSlot = - (colIdx >= 0 || resIdx >= 0 || state.currentPass.renderpass.depthstencilAttachment == i); + (colIdx >= 0 || resIdx >= 0 || state.currentPass.renderpass.depthstencilAttachment == i || + state.currentPass.renderpass.fragmentDensityAttachment == i); if(showNode(usedSlot, filledSlot)) { @@ -2216,6 +2217,8 @@ void VulkanPipelineStateViewer::setState() slotname = QFormatStr("Color %1").arg(i); else if(resIdx >= 0) slotname = QFormatStr("Resolve %1").arg(i); + else if(state.currentPass.renderpass.fragmentDensityAttachment == i) + slotname = lit("Fragment Density Map"); else slotname = lit("Depth"); @@ -3419,6 +3422,14 @@ void VulkanPipelineStateViewer::exportHTML(QXmlStreamWriter &xml, const VKPipe:: tr("Depth-stencil Attachment: %1").arg(pass.renderpass.depthstencilAttachment)); xml.writeEndElement(); } + + if(pass.renderpass.fragmentDensityAttachment >= 0) + { + xml.writeStartElement(lit("p")); + xml.writeCharacters( + tr("Fragment Density Attachment: %1").arg(pass.renderpass.fragmentDensityAttachment)); + xml.writeEndElement(); + } } { diff --git a/renderdoc/api/replay/vk_pipestate.h b/renderdoc/api/replay/vk_pipestate.h index aee57f7a0..e948d318a 100644 --- a/renderdoc/api/replay/vk_pipestate.h +++ b/renderdoc/api/replay/vk_pipestate.h @@ -805,6 +805,12 @@ If there is no depth-stencil attachment, this index is ``-1``. )"); int32_t depthstencilAttachment = -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``. +)"); + int32_t fragmentDensityAttachment = -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/vk_common.h b/renderdoc/driver/vulkan/vk_common.h index 810b6303c..ebd6764e6 100644 --- a/renderdoc/driver/vulkan/vk_common.h +++ b/renderdoc/driver/vulkan/vk_common.h @@ -699,6 +699,8 @@ DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceExternalSemaphoreInfo); DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceFeatures2); DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceFloat16Int8FeaturesKHR); DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceFloatControlsPropertiesKHR); +DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceFragmentDensityMapFeaturesEXT); +DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceFragmentDensityMapPropertiesEXT); DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceGroupProperties); DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceIDProperties); DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceImageFormatInfo2); @@ -757,6 +759,7 @@ DECLARE_REFLECTION_STRUCT(VkQueueFamilyProperties2); DECLARE_REFLECTION_STRUCT(VkRenderPassBeginInfo); DECLARE_REFLECTION_STRUCT(VkRenderPassCreateInfo); DECLARE_REFLECTION_STRUCT(VkRenderPassCreateInfo2KHR); +DECLARE_REFLECTION_STRUCT(VkRenderPassFragmentDensityMapCreateInfoEXT); DECLARE_REFLECTION_STRUCT(VkRenderPassInputAttachmentAspectCreateInfo); DECLARE_REFLECTION_STRUCT(VkRenderPassMultiviewCreateInfo); DECLARE_REFLECTION_STRUCT(VkRenderPassSampleLocationsBeginInfoEXT); @@ -913,6 +916,8 @@ DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceExternalFenceInfo); DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceExternalImageFormatInfo); DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceExternalSemaphoreInfo); DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceFeatures2); +DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceFragmentDensityMapFeaturesEXT); +DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceFragmentDensityMapPropertiesEXT); DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceGroupProperties); DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceIDProperties); DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceImageFormatInfo2); diff --git a/renderdoc/driver/vulkan/vk_core.cpp b/renderdoc/driver/vulkan/vk_core.cpp index 0e458c712..87d87127d 100644 --- a/renderdoc/driver/vulkan/vk_core.cpp +++ b/renderdoc/driver/vulkan/vk_core.cpp @@ -672,6 +672,9 @@ static const VkExtensionProperties supportedExtensions[] = { { VK_EXT_EXTERNAL_MEMORY_DMA_BUF_EXTENSION_NAME, VK_EXT_EXTERNAL_MEMORY_DMA_BUF_SPEC_VERSION, }, + { + VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME, VK_EXT_FRAGMENT_DENSITY_MAP_SPEC_VERSION, + }, { VK_EXT_GLOBAL_PRIORITY_EXTENSION_NAME, VK_EXT_GLOBAL_PRIORITY_SPEC_VERSION, }, @@ -1079,6 +1082,45 @@ VkResult WrappedVulkan::FilterDeviceExtensionProperties(VkPhysicalDevice physDev if(pLayerName == NULL) { + InstanceDeviceInfo *instDevInfo = GetRecord(m_Instance)->instDevInfo; + + // extensions with conditional support + for(auto it = filtered.begin(); it != filtered.end();) + { + if(!strcmp(it->extensionName, VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME)) + { + // require GPDP2 + if(instDevInfo->ext_KHR_get_physical_device_properties2) + { + VkPhysicalDeviceFragmentDensityMapFeaturesEXT fragmentDensityFeatures = { + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT}; + VkPhysicalDeviceFeatures2 base = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2}; + base.pNext = &fragmentDensityFeatures; + ObjDisp(physDev)->GetPhysicalDeviceFeatures2(Unwrap(physDev), &base); + + if(fragmentDensityFeatures.fragmentDensityMapNonSubsampledImages) + { + // supported + ++it; + continue; + } + else + { + RDCWARN( + "VkPhysicalDeviceFragmentDensityMapFeaturesEXT." + "fragmentDensityMapNonSubsampledImages is " + "false, can't support capture of VK_EXT_fragment_density_map"); + } + } + + // if it wasn't supported, remove the extension + it = filtered.erase(it); + continue; + } + + ++it; + } + // now we can add extensions that we provide ourselves (note this isn't sorted, but we // don't have to sort the results, the sorting was just so we could filter optimally). filtered.insert( diff --git a/renderdoc/driver/vulkan/vk_info.cpp b/renderdoc/driver/vulkan/vk_info.cpp index 1cf0bc306..d45f28e0d 100644 --- a/renderdoc/driver/vulkan/vk_info.cpp +++ b/renderdoc/driver/vulkan/vk_info.cpp @@ -635,6 +635,11 @@ void VulkanCreationInfo::RenderPass::Init(VulkanResourceManager *resourceMan, (const VkRenderPassMultiviewCreateInfo *)FindNextStruct( pCreateInfo, VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO); + // VK_EXT_fragment_density_map + const VkRenderPassFragmentDensityMapCreateInfoEXT *fragmentDensity = + (const VkRenderPassFragmentDensityMapCreateInfoEXT *)FindNextStruct( + pCreateInfo, VK_STRUCTURE_TYPE_RENDER_PASS_FRAGMENT_DENSITY_MAP_CREATE_INFO_EXT); + subpasses.resize(pCreateInfo->subpassCount); for(uint32_t subp = 0; subp < pCreateInfo->subpassCount; subp++) { @@ -670,6 +675,18 @@ void VulkanCreationInfo::RenderPass::Init(VulkanResourceManager *resourceMan, ? src.pDepthStencilAttachment->layout : VK_IMAGE_LAYOUT_UNDEFINED); + dst.fragmentDensityAttachment = + (fragmentDensity && + fragmentDensity->fragmentDensityMapAttachment.attachment != VK_ATTACHMENT_UNUSED + ? fragmentDensity->fragmentDensityMapAttachment.attachment + : -1); + + dst.fragmentDensityLayout = + (fragmentDensity && + fragmentDensity->fragmentDensityMapAttachment.attachment != VK_ATTACHMENT_UNUSED + ? fragmentDensity->fragmentDensityMapAttachment.layout + : VK_IMAGE_LAYOUT_UNDEFINED); + if(multiview && multiview->subpassCount > 0) { uint32_t mask = multiview->pViewMasks[subp]; @@ -701,6 +718,11 @@ void VulkanCreationInfo::RenderPass::Init(VulkanResourceManager *resourceMan, dst.finalLayout = pCreateInfo->pAttachments[i].finalLayout; } + // VK_EXT_fragment_density_map + const VkRenderPassFragmentDensityMapCreateInfoEXT *fragmentDensity = + (const VkRenderPassFragmentDensityMapCreateInfoEXT *)FindNextStruct( + pCreateInfo, VK_STRUCTURE_TYPE_RENDER_PASS_FRAGMENT_DENSITY_MAP_CREATE_INFO_EXT); + subpasses.resize(pCreateInfo->subpassCount); for(uint32_t subp = 0; subp < pCreateInfo->subpassCount; subp++) { @@ -736,6 +758,18 @@ void VulkanCreationInfo::RenderPass::Init(VulkanResourceManager *resourceMan, ? src.pDepthStencilAttachment->layout : VK_IMAGE_LAYOUT_UNDEFINED); + dst.fragmentDensityAttachment = + (fragmentDensity && + fragmentDensity->fragmentDensityMapAttachment.attachment != VK_ATTACHMENT_UNUSED + ? fragmentDensity->fragmentDensityMapAttachment.attachment + : -1); + + dst.fragmentDensityLayout = + (fragmentDensity && + fragmentDensity->fragmentDensityMapAttachment.attachment != VK_ATTACHMENT_UNUSED + ? fragmentDensity->fragmentDensityMapAttachment.layout + : VK_IMAGE_LAYOUT_UNDEFINED); + 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 53ab7c6fe..7efcd4c82 100644 --- a/renderdoc/driver/vulkan/vk_info.h +++ b/renderdoc/driver/vulkan/vk_info.h @@ -317,10 +317,12 @@ struct VulkanCreationInfo vector colorAttachments; vector resolveAttachments; int32_t depthstencilAttachment; + int32_t fragmentDensityAttachment; vector inputLayouts; vector colorLayouts; VkImageLayout depthstencilLayout; + VkImageLayout fragmentDensityLayout; std::vector multiviews; }; diff --git a/renderdoc/driver/vulkan/vk_replay.cpp b/renderdoc/driver/vulkan/vk_replay.cpp index d4133ecd4..f55dd5082 100644 --- a/renderdoc/driver/vulkan/vk_replay.cpp +++ b/renderdoc/driver/vulkan/vk_replay.cpp @@ -1257,6 +1257,8 @@ void VulkanReplay::SavePipelineState() c.m_RenderPass[state.renderPass].subpasses[state.subpass].resolveAttachments; m_VulkanPipelineState.currentPass.renderpass.depthstencilAttachment = c.m_RenderPass[state.renderPass].subpasses[state.subpass].depthstencilAttachment; + m_VulkanPipelineState.currentPass.renderpass.fragmentDensityAttachment = + c.m_RenderPass[state.renderPass].subpasses[state.subpass].fragmentDensityAttachment; m_VulkanPipelineState.currentPass.renderpass.multiviews = c.m_RenderPass[state.renderPass].subpasses[state.subpass].multiviews; @@ -1331,6 +1333,7 @@ void VulkanReplay::SavePipelineState() m_VulkanPipelineState.currentPass.renderpass.colorAttachments.clear(); m_VulkanPipelineState.currentPass.renderpass.resolveAttachments.clear(); m_VulkanPipelineState.currentPass.renderpass.depthstencilAttachment = -1; + m_VulkanPipelineState.currentPass.renderpass.fragmentDensityAttachment = -1; m_VulkanPipelineState.currentPass.framebuffer.resourceId = ResourceId(); m_VulkanPipelineState.currentPass.framebuffer.attachments.clear(); diff --git a/renderdoc/driver/vulkan/vk_serialise.cpp b/renderdoc/driver/vulkan/vk_serialise.cpp index 19fef90f3..28d0aca95 100644 --- a/renderdoc/driver/vulkan/vk_serialise.cpp +++ b/renderdoc/driver/vulkan/vk_serialise.cpp @@ -463,6 +463,14 @@ SERIALISE_VK_HANDLES(); /* VK_EXT_display_surface_counter */ \ PNEXT_STRUCT(VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT, VkSurfaceCapabilities2EXT) \ \ + /* VK_EXT_fragment_density_map */ \ + PNEXT_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT, \ + VkPhysicalDeviceFragmentDensityMapFeaturesEXT) \ + PNEXT_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_PROPERTIES_EXT, \ + VkPhysicalDeviceFragmentDensityMapPropertiesEXT) \ + PNEXT_STRUCT(VK_STRUCTURE_TYPE_RENDER_PASS_FRAGMENT_DENSITY_MAP_CREATE_INFO_EXT, \ + VkRenderPassFragmentDensityMapCreateInfoEXT) \ + \ /* VK_EXT_global_priority */ \ PNEXT_STRUCT(VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT, \ VkDeviceQueueGlobalPriorityCreateInfoEXT) \ @@ -810,11 +818,6 @@ SERIALISE_VK_HANDLES(); PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_MEMORY_HOST_POINTER_PROPERTIES_EXT) \ PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT) \ \ - /* VK_EXT_fragment_density_map */ \ - PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT) \ - PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_PROPERTIES_EXT) \ - PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_RENDER_PASS_FRAGMENT_DENSITY_MAP_CREATE_INFO_EXT) \ - \ /* VK_EXT_hdr_metadata */ \ PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_HDR_METADATA_EXT) \ \ @@ -3773,6 +3776,22 @@ void Deserialise(const VkRenderPassMultiviewCreateInfo &el) delete[] el.pCorrelationMasks; } +template +void DoSerialise(SerialiserType &ser, VkRenderPassFragmentDensityMapCreateInfoEXT &el) +{ + RDCASSERT(ser.IsReading() || + el.sType == VK_STRUCTURE_TYPE_RENDER_PASS_FRAGMENT_DENSITY_MAP_CREATE_INFO_EXT); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER(fragmentDensityMapAttachment); +} + +template <> +void Deserialise(const VkRenderPassFragmentDensityMapCreateInfoEXT &el) +{ + DeserialiseNext(el.pNext); +} + template void DoSerialise(SerialiserType &ser, VkSampleLocationEXT &el) { @@ -3851,6 +3870,42 @@ void Deserialise(const VkRenderPassSampleLocationsBeginInfoEXT &el) delete[] el.pPostSubpassSampleLocations; } +template +void DoSerialise(SerialiserType &ser, VkPhysicalDeviceFragmentDensityMapFeaturesEXT &el) +{ + RDCASSERT(ser.IsReading() || + el.sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER(fragmentDensityMap); + SERIALISE_MEMBER(fragmentDensityMapDynamic); + SERIALISE_MEMBER(fragmentDensityMapNonSubsampledImages); +} + +template <> +void Deserialise(const VkPhysicalDeviceFragmentDensityMapFeaturesEXT &el) +{ + DeserialiseNext(el.pNext); +} + +template +void DoSerialise(SerialiserType &ser, VkPhysicalDeviceFragmentDensityMapPropertiesEXT &el) +{ + RDCASSERT(ser.IsReading() || + el.sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_PROPERTIES_EXT); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER(minFragmentDensityTexelSize); + SERIALISE_MEMBER(maxFragmentDensityTexelSize); + SERIALISE_MEMBER(fragmentDensityInvocations); +} + +template <> +void Deserialise(const VkPhysicalDeviceFragmentDensityMapPropertiesEXT &el) +{ + DeserialiseNext(el.pNext); +} + template void DoSerialise(SerialiserType &ser, VkPhysicalDeviceMultiviewFeatures &el) { @@ -6306,6 +6361,8 @@ INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceExternalFenceInfo); INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceExternalImageFormatInfo); INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceExternalSemaphoreInfo); INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceFeatures2); +INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceFragmentDensityMapFeaturesEXT); +INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceFragmentDensityMapPropertiesEXT); INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceGroupProperties); INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceIDProperties); INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceImageFormatInfo2); @@ -6364,6 +6421,7 @@ INSTANTIATE_SERIALISE_TYPE(VkQueueFamilyProperties2); INSTANTIATE_SERIALISE_TYPE(VkRenderPassBeginInfo); INSTANTIATE_SERIALISE_TYPE(VkRenderPassCreateInfo); INSTANTIATE_SERIALISE_TYPE(VkRenderPassCreateInfo2KHR); +INSTANTIATE_SERIALISE_TYPE(VkRenderPassFragmentDensityMapCreateInfoEXT); INSTANTIATE_SERIALISE_TYPE(VkRenderPassInputAttachmentAspectCreateInfo); INSTANTIATE_SERIALISE_TYPE(VkRenderPassMultiviewCreateInfo); INSTANTIATE_SERIALISE_TYPE(VkRenderPassSampleLocationsBeginInfoEXT); diff --git a/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp index 4b443ffe8..81c16dd34 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp @@ -121,6 +121,15 @@ std::vector WrappedVulkan::GetImplicitRenderPassBarriers(u atts.back().attachment = (uint32_t)rpinfo.subpasses[subpass].depthstencilAttachment; atts.back().layout = rpinfo.subpasses[subpass].depthstencilLayout; } + + int32_t fd = rpinfo.subpasses[subpass].fragmentDensityAttachment; + + if(fd != -1) + { + atts.push_back(VkAttachmentReference()); + atts.back().attachment = (uint32_t)rpinfo.subpasses[subpass].fragmentDensityAttachment; + atts.back().layout = rpinfo.subpasses[subpass].fragmentDensityLayout; + } } for(size_t i = 0; i < atts.size(); i++) @@ -190,6 +199,12 @@ std::vector WrappedVulkan::GetImplicitRenderPassBarriers(u barrier.oldLayout = rpinfo.subpasses[s - 1].depthstencilLayout; break; } + + if((uint32_t)rpinfo.subpasses[s - 1].fragmentDensityAttachment == idx) + { + barrier.oldLayout = rpinfo.subpasses[s - 1].fragmentDensityLayout; + break; + } } ReplacePresentableImageLayout(barrier.oldLayout); diff --git a/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp index 43a51f4a2..f2e8fe64e 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp @@ -1673,6 +1673,15 @@ bool WrappedVulkan::Serialise_vkCreateDevice(SerialiserType &ser, VkPhysicalDevi } END_PHYS_EXT_CHECK(); + BEGIN_PHYS_EXT_CHECK(VkPhysicalDeviceFragmentDensityMapFeaturesEXT, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT); + { + CHECK_PHYS_EXT_FEATURE(fragmentDensityMap); + CHECK_PHYS_EXT_FEATURE(fragmentDensityMapDynamic); + CHECK_PHYS_EXT_FEATURE(fragmentDensityMapNonSubsampledImages); + } + END_PHYS_EXT_CHECK(); + BEGIN_PHYS_EXT_CHECK(VkPhysicalDeviceProtectedMemoryFeatures, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES); { @@ -2183,6 +2192,14 @@ VkResult WrappedVulkan::vkCreateDevice(VkPhysicalDevice physicalDevice, else createInfo.pEnabledFeatures = &enabledFeatures; + VkPhysicalDeviceFragmentDensityMapFeaturesEXT *fragmentDensityMapFeatures = + (VkPhysicalDeviceFragmentDensityMapFeaturesEXT *)FindNextStruct( + &createInfo, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT); + if(fragmentDensityMapFeatures && !fragmentDensityMapFeatures->fragmentDensityMapNonSubsampledImages) + { + fragmentDensityMapFeatures->fragmentDensityMapNonSubsampledImages = true; + } + VkResult ret; SERIALISE_TIME_CALL(ret = createFunc(Unwrap(physicalDevice), &createInfo, pAllocator, pDevice)); diff --git a/renderdoc/driver/vulkan/wrappers/vk_misc_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_misc_funcs.cpp index 9aa309ac2..002187a8a 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_misc_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_misc_funcs.cpp @@ -480,15 +480,19 @@ bool WrappedVulkan::Serialise_vkCreateSampler(SerialiserType &ser, VkDevice devi VkResult WrappedVulkan::vkCreateSampler(VkDevice device, const VkSamplerCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSampler *pSampler) { - VkSamplerCreateInfo info = *pCreateInfo; + VkSamplerCreateInfo info_adjusted = *pCreateInfo; - byte *tempMem = GetTempMemory(GetNextPatchSize(info.pNext)); + // like in VkCreateImage, create non-subsampled sampler since the image is now non-subsampled. + info_adjusted.flags &= ~VK_SAMPLER_CREATE_SUBSAMPLED_BIT_EXT; + info_adjusted.flags &= ~VK_SAMPLER_CREATE_SUBSAMPLED_COARSE_RECONSTRUCTION_BIT_EXT; - UnwrapNextChain(m_State, "VkSamplerCreateInfo", tempMem, (VkBaseInStructure *)&info); + byte *tempMem = GetTempMemory(GetNextPatchSize(info_adjusted.pNext)); + + UnwrapNextChain(m_State, "VkSamplerCreateInfo", tempMem, (VkBaseInStructure *)&info_adjusted); VkResult ret; SERIALISE_TIME_CALL( - ret = ObjDisp(device)->CreateSampler(Unwrap(device), &info, pAllocator, pSampler)); + ret = ObjDisp(device)->CreateSampler(Unwrap(device), &info_adjusted, pAllocator, pSampler)); if(ret == VK_SUCCESS) { diff --git a/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp index 98f65ffb9..2b744e2da 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp @@ -1450,6 +1450,8 @@ bool WrappedVulkan::Serialise_vkCreateImage(SerialiserType &ser, VkDevice device prefix = "2D Color Attachment"; else if(CreateInfo.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) 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.imageType == VK_IMAGE_TYPE_3D) { @@ -1509,6 +1511,9 @@ VkResult WrappedVulkan::vkCreateImage(VkDevice device, const VkImageCreateInfo * } } + // create non-subsampled image to be able to copy its content + createInfo_adjusted.flags &= ~VK_IMAGE_CREATE_SUBSAMPLED_BIT_EXT; + byte *tempMem = GetTempMemory(GetNextPatchSize(createInfo_adjusted.pNext)); UnwrapNextChain(m_State, "VkImageCreateInfo", tempMem, (VkBaseInStructure *)&createInfo_adjusted); diff --git a/renderdoc/replay/renderdoc_serialise.inl b/renderdoc/replay/renderdoc_serialise.inl index e7294d203..271a0d2d3 100644 --- a/renderdoc/replay/renderdoc_serialise.inl +++ b/renderdoc/replay/renderdoc_serialise.inl @@ -2057,6 +2057,7 @@ void DoSerialise(SerialiserType &ser, VKPipe::RenderPass &el) SERIALISE_MEMBER(colorAttachments); SERIALISE_MEMBER(resolveAttachments); SERIALISE_MEMBER(depthstencilAttachment); + SERIALISE_MEMBER(fragmentDensityAttachment); SERIALISE_MEMBER(multiviews); SIZE_CHECK(120);