From 71c1f6b7a0fcd89c9626b7abe5f41a71963cacfe Mon Sep 17 00:00:00 2001 From: baldurk Date: Thu, 21 Oct 2021 16:47:11 +0100 Subject: [PATCH] Add support for VK_KHR_maintenance4 --- renderdoc/driver/vulkan/extension_support.md | 2 +- renderdoc/driver/vulkan/vk_common.h | 8 + renderdoc/driver/vulkan/vk_core.cpp | 3 + renderdoc/driver/vulkan/vk_core.h | 14 ++ renderdoc/driver/vulkan/vk_hookset_defs.h | 16 +- renderdoc/driver/vulkan/vk_next_chains.cpp | 67 ++++- renderdoc/driver/vulkan/vk_serialise.cpp | 88 ++++++- .../vulkan/wrappers/vk_device_funcs.cpp | 7 + .../driver/vulkan/wrappers/vk_get_funcs.cpp | 230 ++++++++++++++++++ .../vulkan/wrappers/vk_resource_funcs.cpp | 6 + 10 files changed, 428 insertions(+), 13 deletions(-) diff --git a/renderdoc/driver/vulkan/extension_support.md b/renderdoc/driver/vulkan/extension_support.md index 8e0a39147..b7c85a658 100644 --- a/renderdoc/driver/vulkan/extension_support.md +++ b/renderdoc/driver/vulkan/extension_support.md @@ -132,6 +132,7 @@ Maintainers can update this file by updating vk.xml in this folder and running ` * `VK_KHR_maintenance1` * `VK_KHR_maintenance2` * `VK_KHR_maintenance3` +* `VK_KHR_maintenance4` * `VK_KHR_multiview` * `VK_KHR_performance_query` * `VK_KHR_pipeline_executable_properties` @@ -190,7 +191,6 @@ KHR extensions will definitely be implemented at some point, though KHR extensio ## KHR Extensions * `VK_KHR_fragment_shading_rate` -* `VK_KHR_maintenance4` * `VK_KHR_shader_integer_dot_product` * `VK_KHR_shader_subgroup_uniform_control_flow` diff --git a/renderdoc/driver/vulkan/vk_common.h b/renderdoc/driver/vulkan/vk_common.h index 59bfb1807..7bfda3b00 100644 --- a/renderdoc/driver/vulkan/vk_common.h +++ b/renderdoc/driver/vulkan/vk_common.h @@ -824,6 +824,7 @@ DECLARE_REFLECTION_STRUCT(VkDescriptorSetLayoutSupport); DECLARE_REFLECTION_STRUCT(VkDescriptorSetVariableDescriptorCountAllocateInfo) DECLARE_REFLECTION_STRUCT(VkDescriptorSetVariableDescriptorCountLayoutSupport) DECLARE_REFLECTION_STRUCT(VkDescriptorUpdateTemplateCreateInfo); +DECLARE_REFLECTION_STRUCT(VkDeviceBufferMemoryRequirementsKHR); DECLARE_REFLECTION_STRUCT(VkDeviceCreateInfo); DECLARE_REFLECTION_STRUCT(VkDeviceEventInfoEXT); DECLARE_REFLECTION_STRUCT(VkDeviceGroupBindSparseInfo); @@ -834,6 +835,7 @@ DECLARE_REFLECTION_STRUCT(VkDeviceGroupPresentInfoKHR); DECLARE_REFLECTION_STRUCT(VkDeviceGroupRenderPassBeginInfo); DECLARE_REFLECTION_STRUCT(VkDeviceGroupSubmitInfo); DECLARE_REFLECTION_STRUCT(VkDeviceGroupSwapchainCreateInfoKHR); +DECLARE_REFLECTION_STRUCT(VkDeviceImageMemoryRequirementsKHR); DECLARE_REFLECTION_STRUCT(VkDeviceMemoryOpaqueCaptureAddressInfo); DECLARE_REFLECTION_STRUCT(VkDevicePrivateDataCreateInfoEXT); DECLARE_REFLECTION_STRUCT(VkDeviceQueueCreateInfo); @@ -952,6 +954,8 @@ DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceInlineUniformBlockPropertiesEXT); DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceLineRasterizationFeaturesEXT); DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceLineRasterizationPropertiesEXT); DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceMaintenance3Properties); +DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceMaintenance4FeaturesKHR); +DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceMaintenance4PropertiesKHR); DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceMemoryBudgetPropertiesEXT); DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceMemoryPriorityFeaturesEXT); DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceMemoryProperties2); @@ -1161,6 +1165,7 @@ DECLARE_DESERIALISE_TYPE(VkDescriptorSetLayoutSupport); DECLARE_DESERIALISE_TYPE(VkDescriptorSetVariableDescriptorCountAllocateInfo) DECLARE_DESERIALISE_TYPE(VkDescriptorSetVariableDescriptorCountLayoutSupport) DECLARE_DESERIALISE_TYPE(VkDescriptorUpdateTemplateCreateInfo); +DECLARE_DESERIALISE_TYPE(VkDeviceBufferMemoryRequirementsKHR); DECLARE_DESERIALISE_TYPE(VkDeviceCreateInfo); DECLARE_DESERIALISE_TYPE(VkDeviceEventInfoEXT); DECLARE_DESERIALISE_TYPE(VkDeviceGroupBindSparseInfo); @@ -1171,6 +1176,7 @@ DECLARE_DESERIALISE_TYPE(VkDeviceGroupPresentInfoKHR); DECLARE_DESERIALISE_TYPE(VkDeviceGroupRenderPassBeginInfo); DECLARE_DESERIALISE_TYPE(VkDeviceGroupSubmitInfo); DECLARE_DESERIALISE_TYPE(VkDeviceGroupSwapchainCreateInfoKHR); +DECLARE_DESERIALISE_TYPE(VkDeviceImageMemoryRequirementsKHR); DECLARE_DESERIALISE_TYPE(VkDeviceMemoryOpaqueCaptureAddressInfo); DECLARE_DESERIALISE_TYPE(VkDevicePrivateDataCreateInfoEXT); DECLARE_DESERIALISE_TYPE(VkDeviceQueueCreateInfo); @@ -1285,6 +1291,8 @@ DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceInlineUniformBlockPropertiesEXT); DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceLineRasterizationFeaturesEXT); DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceLineRasterizationPropertiesEXT); DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceMaintenance3Properties); +DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceMaintenance4FeaturesKHR); +DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceMaintenance4PropertiesKHR); DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceMemoryBudgetPropertiesEXT); DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceMemoryPriorityFeaturesEXT); DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceMemoryProperties2); diff --git a/renderdoc/driver/vulkan/vk_core.cpp b/renderdoc/driver/vulkan/vk_core.cpp index 42b77a69e..40b098f28 100644 --- a/renderdoc/driver/vulkan/vk_core.cpp +++ b/renderdoc/driver/vulkan/vk_core.cpp @@ -1227,6 +1227,9 @@ static const VkExtensionProperties supportedExtensions[] = { { VK_KHR_MAINTENANCE_3_EXTENSION_NAME, VK_KHR_MAINTENANCE_3_SPEC_VERSION, }, + { + VK_KHR_MAINTENANCE_4_EXTENSION_NAME, VK_KHR_MAINTENANCE_4_SPEC_VERSION, + }, { VK_KHR_MULTIVIEW_EXTENSION_NAME, VK_KHR_MULTIVIEW_SPEC_VERSION, }, diff --git a/renderdoc/driver/vulkan/vk_core.h b/renderdoc/driver/vulkan/vk_core.h index df46cbc80..5de08e8ab 100644 --- a/renderdoc/driver/vulkan/vk_core.h +++ b/renderdoc/driver/vulkan/vk_core.h @@ -2459,4 +2459,18 @@ public: IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkWaitForPresentKHR, VkDevice device, VkSwapchainKHR swapchain, uint64_t presentId, uint64_t timeout); + + // VK_KHR_maintenance4 + IMPLEMENT_FUNCTION_SERIALISED(void, vkGetDeviceBufferMemoryRequirementsKHR, VkDevice device, + const VkDeviceBufferMemoryRequirementsKHR *pInfo, + VkMemoryRequirements2 *pMemoryRequirements); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkGetDeviceImageMemoryRequirementsKHR, VkDevice device, + const VkDeviceImageMemoryRequirementsKHR *pInfo, + VkMemoryRequirements2 *pMemoryRequirements); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkGetDeviceImageSparseMemoryRequirementsKHR, VkDevice device, + const VkDeviceImageMemoryRequirementsKHR *pInfo, + uint32_t *pSparseMemoryRequirementCount, + VkSparseImageMemoryRequirements2 *pSparseMemoryRequirements); }; diff --git a/renderdoc/driver/vulkan/vk_hookset_defs.h b/renderdoc/driver/vulkan/vk_hookset_defs.h index 21a84dfb1..fb77f1d95 100644 --- a/renderdoc/driver/vulkan/vk_hookset_defs.h +++ b/renderdoc/driver/vulkan/vk_hookset_defs.h @@ -528,7 +528,8 @@ DeclExt(EXT_extended_dynamic_state); \ DeclExt(KHR_copy_commands2); \ DeclExt(KHR_synchronization2); \ - DeclExt(KHR_present_wait); + DeclExt(KHR_present_wait); \ + DeclExt(KHR_maintenance4); // for simplicity and since the check itself is platform agnostic, // these aren't protected in platform defines @@ -870,6 +871,9 @@ HookInitExtension(KHR_synchronization2, QueueSubmit2KHR); \ HookInitExtension(KHR_synchronization2 &&AMD_buffer_marker, CmdWriteBufferMarker2AMD); \ HookInitExtension(KHR_present_wait, WaitForPresentKHR); \ + HookInitExtension(KHR_maintenance4, GetDeviceBufferMemoryRequirementsKHR); \ + HookInitExtension(KHR_maintenance4, GetDeviceImageMemoryRequirementsKHR); \ + HookInitExtension(KHR_maintenance4, GetDeviceImageSparseMemoryRequirementsKHR); \ /* No GetQueueCheckpointData2NV without VK_NV_device_diagnostic_checkpoints */ \ HookInitExtension_Device_Win32(); \ HookInitExtension_Device_Linux(); \ @@ -1556,6 +1560,16 @@ uint32_t, marker); \ HookDefine4(VkResult, vkWaitForPresentKHR, VkDevice, device, VkSwapchainKHR, swapchain, \ uint64_t, presentId, uint64_t, timeout); \ + HookDefine3(void, vkGetDeviceBufferMemoryRequirementsKHR, VkDevice, device, \ + const VkDeviceBufferMemoryRequirementsKHR *, pInfo, VkMemoryRequirements2 *, \ + pMemoryRequirements); \ + HookDefine3(void, vkGetDeviceImageMemoryRequirementsKHR, VkDevice, device, \ + const VkDeviceImageMemoryRequirementsKHR *, pInfo, VkMemoryRequirements2 *, \ + pMemoryRequirements); \ + HookDefine4(void, vkGetDeviceImageSparseMemoryRequirementsKHR, VkDevice, device, \ + const VkDeviceImageMemoryRequirementsKHR *, pInfo, uint32_t *, \ + pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements2 *, \ + pSparseMemoryRequirements); \ HookDefine_Win32(); \ HookDefine_Linux(); \ HookDefine_GGP(); \ diff --git a/renderdoc/driver/vulkan/vk_next_chains.cpp b/renderdoc/driver/vulkan/vk_next_chains.cpp index 391f3687c..2586569b8 100644 --- a/renderdoc/driver/vulkan/vk_next_chains.cpp +++ b/renderdoc/driver/vulkan/vk_next_chains.cpp @@ -272,6 +272,10 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct, VkPhysicalDeviceInlineUniformBlockPropertiesEXT); \ COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES, \ VkPhysicalDeviceMaintenance3Properties); \ + COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES_KHR, \ + VkPhysicalDeviceMaintenance4FeaturesKHR); \ + COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_PROPERTIES_KHR, \ + VkPhysicalDeviceMaintenance4PropertiesKHR); \ COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT, \ VkPhysicalDeviceMemoryBudgetPropertiesEXT); \ COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2, \ @@ -661,10 +665,8 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct, case VK_STRUCTURE_TYPE_CU_FUNCTION_CREATE_INFO_NVX: \ case VK_STRUCTURE_TYPE_CU_LAUNCH_INFO_NVX: \ case VK_STRUCTURE_TYPE_CU_MODULE_CREATE_INFO_NVX: \ - case VK_STRUCTURE_TYPE_DEVICE_BUFFER_MEMORY_REQUIREMENTS_KHR: \ case VK_STRUCTURE_TYPE_DEVICE_DEVICE_MEMORY_REPORT_CREATE_INFO_EXT: \ case VK_STRUCTURE_TYPE_DEVICE_DIAGNOSTICS_CONFIG_CREATE_INFO_NV: \ - case VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS_KHR: \ case VK_STRUCTURE_TYPE_DEVICE_MEMORY_OVERALLOCATION_CREATE_INFO_AMD: \ case VK_STRUCTURE_TYPE_DEVICE_MEMORY_REPORT_CALLBACK_DATA_EXT: \ case VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_2_EXT: \ @@ -731,8 +733,6 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct, case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT: \ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INHERITED_VIEWPORT_SCISSOR_FEATURES_NV: \ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INVOCATION_MASK_FEATURES_HUAWEI: \ - case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES_KHR: \ - case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_PROPERTIES_KHR: \ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_NV: \ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_PROPERTIES_NV: \ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_FEATURES_EXT: \ @@ -944,6 +944,14 @@ size_t GetNextPatchSize(const void *pNext) memSize += info->pBindings[i].descriptorCount * sizeof(VkSampler); break; } + case VK_STRUCTURE_TYPE_DEVICE_BUFFER_MEMORY_REQUIREMENTS_KHR: + { + memSize += sizeof(VkDeviceBufferMemoryRequirementsKHR); + + VkDeviceBufferMemoryRequirementsKHR *info = (VkDeviceBufferMemoryRequirementsKHR *)next; + memSize += GetNextPatchSize(info->pCreateInfo); + break; + } case VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO: { memSize += sizeof(VkDeviceGroupDeviceCreateInfo); @@ -952,6 +960,14 @@ size_t GetNextPatchSize(const void *pNext) memSize += info->physicalDeviceCount * sizeof(VkPhysicalDevice); break; } + case VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS_KHR: + { + memSize += sizeof(VkDeviceImageMemoryRequirementsKHR); + + VkDeviceImageMemoryRequirementsKHR *info = (VkDeviceImageMemoryRequirementsKHR *)next; + memSize += GetNextPatchSize(info->pCreateInfo); + break; + } case VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO: { memSize += sizeof(VkFramebufferCreateInfo); @@ -1669,6 +1685,23 @@ void UnwrapNextChain(CaptureState state, const char *structName, byte *&tempMem, break; } + case VK_STRUCTURE_TYPE_DEVICE_BUFFER_MEMORY_REQUIREMENTS_KHR: + { + const VkDeviceBufferMemoryRequirementsKHR *in = + (const VkDeviceBufferMemoryRequirementsKHR *)nextInput; + VkDeviceBufferMemoryRequirementsKHR *out = (VkDeviceBufferMemoryRequirementsKHR *)tempMem; + + // append immediately so tempMem is incremented + AppendModifiedChainedStruct(tempMem, out, nextChainTail); + + out->sType = VK_STRUCTURE_TYPE_DEVICE_BUFFER_MEMORY_REQUIREMENTS_KHR; + out->pNext = in->pNext; + + out->pCreateInfo = AllocStructCopy(tempMem, in->pCreateInfo); + UnwrapNextChain(state, "VkBufferCreateInfo", tempMem, (VkBaseInStructure *)out->pCreateInfo); + + break; + } case VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO: { const VkDeviceGroupDeviceCreateInfo *in = (const VkDeviceGroupDeviceCreateInfo *)nextInput; @@ -1689,6 +1722,24 @@ void UnwrapNextChain(CaptureState state, const char *structName, byte *&tempMem, break; } + case VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS_KHR: + { + const VkDeviceImageMemoryRequirementsKHR *in = + (const VkDeviceImageMemoryRequirementsKHR *)nextInput; + VkDeviceImageMemoryRequirementsKHR *out = (VkDeviceImageMemoryRequirementsKHR *)tempMem; + + // append immediately so tempMem is incremented + AppendModifiedChainedStruct(tempMem, out, nextChainTail); + + out->sType = VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS_KHR; + out->pNext = in->pNext; + out->planeAspect = in->planeAspect; + + out->pCreateInfo = AllocStructCopy(tempMem, in->pCreateInfo); + UnwrapNextChain(state, "VkImageCreateInfo", tempMem, (VkBaseInStructure *)out->pCreateInfo); + + break; + } case VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO: { const VkFramebufferCreateInfo *in = (const VkFramebufferCreateInfo *)nextInput; @@ -2324,10 +2375,18 @@ void CopyNextChainForPatching(const char *structName, byte *&tempMem, VkBaseInSt CopyNextChainedStruct(sizeof(VkDescriptorSetLayoutCreateInfo), tempMem, nextInput, nextChainTail); break; + case VK_STRUCTURE_TYPE_DEVICE_BUFFER_MEMORY_REQUIREMENTS_KHR: + CopyNextChainedStruct(sizeof(VkDeviceBufferMemoryRequirementsKHR), tempMem, nextInput, + nextChainTail); + break; case VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO: CopyNextChainedStruct(sizeof(VkDeviceGroupDeviceCreateInfo), tempMem, nextInput, nextChainTail); break; + case VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS_KHR: + CopyNextChainedStruct(sizeof(VkDeviceImageMemoryRequirementsKHR), tempMem, nextInput, + nextChainTail); + break; case VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO: CopyNextChainedStruct(sizeof(VkFramebufferCreateInfo), tempMem, nextInput, nextChainTail); break; diff --git a/renderdoc/driver/vulkan/vk_serialise.cpp b/renderdoc/driver/vulkan/vk_serialise.cpp index 03c049c05..7ec89017d 100644 --- a/renderdoc/driver/vulkan/vk_serialise.cpp +++ b/renderdoc/driver/vulkan/vk_serialise.cpp @@ -1009,6 +1009,16 @@ SERIALISE_VK_HANDLES(); VkPhysicalDeviceMaintenance3Properties) \ PNEXT_STRUCT(VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT, VkDescriptorSetLayoutSupport) \ \ + /* VK_KHR_maintenance4 */ \ + PNEXT_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES_KHR, \ + VkPhysicalDeviceMaintenance4FeaturesKHR) \ + PNEXT_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_PROPERTIES_KHR, \ + VkPhysicalDeviceMaintenance4PropertiesKHR) \ + PNEXT_STRUCT(VK_STRUCTURE_TYPE_DEVICE_BUFFER_MEMORY_REQUIREMENTS_KHR, \ + VkDeviceBufferMemoryRequirementsKHR) \ + PNEXT_STRUCT(VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS_KHR, \ + VkDeviceImageMemoryRequirementsKHR) \ + \ /* VK_KHR_multiview */ \ PNEXT_STRUCT(VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO, VkRenderPassMultiviewCreateInfo) \ PNEXT_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES, \ @@ -1328,12 +1338,6 @@ SERIALISE_VK_HANDLES(); PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR) \ PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_KHR) \ \ - /* VK_KHR_maintenance4 */ \ - PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES_KHR) \ - PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_PROPERTIES_KHR) \ - PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_DEVICE_BUFFER_MEMORY_REQUIREMENTS_KHR) \ - PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS_KHR) \ - \ /* VK_KHR_pipeline_library */ \ PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR) \ \ @@ -4660,6 +4664,7 @@ template <> void Deserialise(const VkSubpassDescriptionDepthStencilResolve &el) { DeserialiseNext(el.pNext); + delete el.pDepthStencilResolveAttachment; } template @@ -4982,6 +4987,71 @@ void Deserialise(const VkDescriptorSetLayoutSupport &el) DeserialiseNext(el.pNext); } +template +void DoSerialise(SerialiserType &ser, VkPhysicalDeviceMaintenance4PropertiesKHR &el) +{ + RDCASSERT(ser.IsReading() || + el.sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_PROPERTIES_KHR); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER(maxBufferSize); +} + +template <> +void Deserialise(const VkPhysicalDeviceMaintenance4PropertiesKHR &el) +{ + DeserialiseNext(el.pNext); +} + +template +void DoSerialise(SerialiserType &ser, VkPhysicalDeviceMaintenance4FeaturesKHR &el) +{ + RDCASSERT(ser.IsReading() || + el.sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES_KHR); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER(maintenance4); +} + +template <> +void Deserialise(const VkPhysicalDeviceMaintenance4FeaturesKHR &el) +{ + DeserialiseNext(el.pNext); +} + +template +void DoSerialise(SerialiserType &ser, VkDeviceBufferMemoryRequirementsKHR &el) +{ + RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_DEVICE_BUFFER_MEMORY_REQUIREMENTS_KHR); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER_OPT(pCreateInfo); +} + +template <> +void Deserialise(const VkDeviceBufferMemoryRequirementsKHR &el) +{ + DeserialiseNext(el.pNext); + delete el.pCreateInfo; +} + +template +void DoSerialise(SerialiserType &ser, VkDeviceImageMemoryRequirementsKHR &el) +{ + RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS_KHR); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER_OPT(pCreateInfo); + SERIALISE_MEMBER(planeAspect); +} + +template <> +void Deserialise(const VkDeviceImageMemoryRequirementsKHR &el) +{ + DeserialiseNext(el.pNext); + delete el.pCreateInfo; +} + template void DoSerialise(SerialiserType &ser, VkRenderPassMultiviewCreateInfo &el) { @@ -5430,7 +5500,7 @@ void DoSerialise(SerialiserType &ser, VkPresentIdKHR &el) SerialiseNext(ser, el.sType, el.pNext); SERIALISE_MEMBER(swapchainCount); - SERIALISE_MEMBER_ARRAY(pPresentIds); + SERIALISE_MEMBER_ARRAY(pPresentIds, swapchainCount); } template <> @@ -9391,6 +9461,7 @@ INSTANTIATE_SERIALISE_TYPE(VkDescriptorSetLayoutSupport); INSTANTIATE_SERIALISE_TYPE(VkDescriptorSetVariableDescriptorCountAllocateInfo) INSTANTIATE_SERIALISE_TYPE(VkDescriptorSetVariableDescriptorCountLayoutSupport) INSTANTIATE_SERIALISE_TYPE(VkDescriptorUpdateTemplateCreateInfo); +INSTANTIATE_SERIALISE_TYPE(VkDeviceBufferMemoryRequirementsKHR); INSTANTIATE_SERIALISE_TYPE(VkDeviceCreateInfo); INSTANTIATE_SERIALISE_TYPE(VkDeviceEventInfoEXT); INSTANTIATE_SERIALISE_TYPE(VkDeviceGroupBindSparseInfo); @@ -9401,6 +9472,7 @@ INSTANTIATE_SERIALISE_TYPE(VkDeviceGroupPresentInfoKHR); INSTANTIATE_SERIALISE_TYPE(VkDeviceGroupRenderPassBeginInfo); INSTANTIATE_SERIALISE_TYPE(VkDeviceGroupSubmitInfo); INSTANTIATE_SERIALISE_TYPE(VkDeviceGroupSwapchainCreateInfoKHR); +INSTANTIATE_SERIALISE_TYPE(VkDeviceImageMemoryRequirementsKHR); INSTANTIATE_SERIALISE_TYPE(VkDeviceMemoryOpaqueCaptureAddressInfo); INSTANTIATE_SERIALISE_TYPE(VkDevicePrivateDataCreateInfoEXT); INSTANTIATE_SERIALISE_TYPE(VkDeviceQueueCreateInfo); @@ -9517,6 +9589,8 @@ INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceIndexTypeUint8FeaturesEXT); INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceLineRasterizationFeaturesEXT); INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceLineRasterizationPropertiesEXT); INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceMaintenance3Properties); +INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceMaintenance4FeaturesKHR); +INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceMaintenance4PropertiesKHR); INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceMemoryBudgetPropertiesEXT); INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceMemoryPriorityFeaturesEXT); INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceMemoryProperties2); diff --git a/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp index 32b38bb5f..319eadd52 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp @@ -2738,6 +2738,13 @@ bool WrappedVulkan::Serialise_vkCreateDevice(SerialiserType &ser, VkPhysicalDevi CHECK_PHYS_EXT_FEATURE(synchronization2); } END_PHYS_EXT_CHECK(); + + BEGIN_PHYS_EXT_CHECK(VkPhysicalDeviceMaintenance4FeaturesKHR, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES_KHR); + { + CHECK_PHYS_EXT_FEATURE(maintenance4); + } + END_PHYS_EXT_CHECK(); } if(availFeatures.depthClamp) diff --git a/renderdoc/driver/vulkan/wrappers/vk_get_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_get_funcs.cpp index 868d91af4..207385484 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_get_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_get_funcs.cpp @@ -23,6 +23,7 @@ ******************************************************************************/ #include "../vk_core.h" +#include "../vk_debug.h" #include "api/replay/version.h" static char fakeRenderDocUUID[VK_UUID_SIZE] = {}; @@ -280,6 +281,235 @@ void WrappedVulkan::vkGetImageSparseMemoryRequirements( pSparseMemoryRequirements); } +void WrappedVulkan::vkGetDeviceBufferMemoryRequirementsKHR( + VkDevice device, const VkDeviceBufferMemoryRequirementsKHR *pInfo, + VkMemoryRequirements2 *pMemoryRequirements) +{ + byte *tempMem = GetTempMemory(GetNextPatchSize(pInfo)); + VkDeviceBufferMemoryRequirementsKHR *unwrappedInfo = UnwrapStructAndChain(m_State, tempMem, pInfo); + + VkBufferCreateInfo *info = (VkBufferCreateInfo *)unwrappedInfo->pCreateInfo; + + // patch the create info the same as we would for vkCreateBuffer + info->usage |= VK_BUFFER_USAGE_TRANSFER_SRC_BIT; + info->usage |= VK_BUFFER_USAGE_TRANSFER_DST_BIT; + + if(IsCaptureMode(m_State) && (info->usage & VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT)) + info->flags |= VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT; + + ObjDisp(device)->GetDeviceBufferMemoryRequirementsKHR(Unwrap(device), unwrappedInfo, + pMemoryRequirements); + + // if the buffer is external, create a non-external and return the worst case memory requirements + // so that the memory allocated is sufficient for us on replay when the buffer is non-external + bool isExternal = FindNextStruct(unwrappedInfo->pCreateInfo, + VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO) != NULL; + + if(isExternal) + { + bool removed = + RemoveNextStruct(unwrappedInfo, VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO); + + RDCASSERTMSG("Couldn't find next struct indicating external memory", removed); + + VkMemoryRequirements2 nonExternalReq = {}; + nonExternalReq.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2; + + ObjDisp(device)->GetDeviceBufferMemoryRequirementsKHR(Unwrap(device), unwrappedInfo, + &nonExternalReq); + + pMemoryRequirements->memoryRequirements.size = + RDCMAX(pMemoryRequirements->memoryRequirements.size, nonExternalReq.memoryRequirements.size); + pMemoryRequirements->memoryRequirements.alignment = + RDCMAX(pMemoryRequirements->memoryRequirements.alignment, + nonExternalReq.memoryRequirements.alignment); + + if((pMemoryRequirements->memoryRequirements.memoryTypeBits & + nonExternalReq.memoryRequirements.memoryTypeBits) == 0) + { + RDCWARN( + "External buffer shares no memory types with non-external buffer. This buffer " + "will not be replayable."); + } + else + { + pMemoryRequirements->memoryRequirements.memoryTypeBits &= + nonExternalReq.memoryRequirements.memoryTypeBits; + } + } +} + +void WrappedVulkan::vkGetDeviceImageMemoryRequirementsKHR( + VkDevice device, const VkDeviceImageMemoryRequirementsKHR *pInfo, + VkMemoryRequirements2 *pMemoryRequirements) +{ + size_t tempMemSize = GetNextPatchSize(pInfo); + + // reserve space for a patched view format list if necessary + if(pInfo->pCreateInfo->samples != VK_SAMPLE_COUNT_1_BIT) + { + const VkImageFormatListCreateInfo *formatListInfo = + (const VkImageFormatListCreateInfo *)FindNextStruct( + pInfo->pCreateInfo, VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO); + + if(formatListInfo) + tempMemSize += sizeof(VkFormat) * (formatListInfo->viewFormatCount + 1); + } + + byte *tempMem = GetTempMemory(tempMemSize); + VkDeviceImageMemoryRequirementsKHR *unwrappedInfo = UnwrapStructAndChain(m_State, tempMem, pInfo); + + VkImageCreateInfo *info = (VkImageCreateInfo *)unwrappedInfo->pCreateInfo; + + info->usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT; + + if(IsCaptureMode(m_State)) + { + info->usage |= VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; + info->usage &= ~VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT; + } + + if(IsYUVFormat(info->format)) + info->flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT; + + if(info->samples != VK_SAMPLE_COUNT_1_BIT) + { + info->usage |= VK_IMAGE_USAGE_SAMPLED_BIT; + info->flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT; + + if(IsCaptureMode(m_State)) + { + if(!IsDepthOrStencilFormat(info->format)) + { + if(GetDebugManager() && GetShaderCache()->IsArray2MSSupported()) + info->usage |= VK_IMAGE_USAGE_STORAGE_BIT; + } + else + { + info->usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; + } + } + } + + info->flags &= ~VK_IMAGE_CREATE_SUBSAMPLED_BIT_EXT; + + VkImageStencilUsageCreateInfo *separateStencilUsage = + (VkImageStencilUsageCreateInfo *)FindNextStruct( + info, VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO); + if(separateStencilUsage) + { + separateStencilUsage->stencilUsage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT; + + if(IsCaptureMode(m_State)) + { + info->usage |= VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; + info->usage &= ~VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT; + } + + if(info->samples != VK_SAMPLE_COUNT_1_BIT) + { + separateStencilUsage->stencilUsage |= + VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; + } + } + + // similarly for the image format list for MSAA textures, add the UINT cast format we will need + if(info->samples != VK_SAMPLE_COUNT_1_BIT) + { + VkImageFormatListCreateInfo *formatListInfo = (VkImageFormatListCreateInfo *)FindNextStruct( + info, VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO); + + if(formatListInfo) + { + uint32_t bs = GetByteSize(1, 1, 1, info->format, 0); + + VkFormat msaaCopyFormat = VK_FORMAT_UNDEFINED; + if(bs == 1) + msaaCopyFormat = VK_FORMAT_R8_UINT; + else if(bs == 2) + msaaCopyFormat = VK_FORMAT_R16_UINT; + else if(bs == 4) + msaaCopyFormat = VK_FORMAT_R32_UINT; + else if(bs == 8) + msaaCopyFormat = VK_FORMAT_R32G32_UINT; + else if(bs == 16) + msaaCopyFormat = VK_FORMAT_R32G32B32A32_UINT; + + const VkFormat *oldFmts = formatListInfo->pViewFormats; + VkFormat *newFmts = (VkFormat *)tempMem; + formatListInfo->pViewFormats = newFmts; + + bool needAdded = true; + uint32_t i = 0; + for(; i < formatListInfo->viewFormatCount; i++) + { + newFmts[i] = oldFmts[i]; + if(newFmts[i] == msaaCopyFormat) + needAdded = false; + } + + if(needAdded) + { + newFmts[i] = msaaCopyFormat; + formatListInfo->viewFormatCount++; + } + } + } + + ObjDisp(device)->GetDeviceImageMemoryRequirementsKHR(Unwrap(device), unwrappedInfo, + pMemoryRequirements); + + // if the image is external, create a non-external and return the worst case memory requirements + // so that the memory allocated is sufficient for us on replay when the image is non-external + bool isExternal = FindNextStruct(unwrappedInfo->pCreateInfo, + VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO) != NULL; + + if(isExternal) + { + bool removed = + RemoveNextStruct(unwrappedInfo, VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO); + + RDCASSERTMSG("Couldn't find next struct indicating external memory", removed); + + VkMemoryRequirements2 nonExternalReq = {}; + nonExternalReq.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2; + + ObjDisp(device)->GetDeviceImageMemoryRequirementsKHR(Unwrap(device), unwrappedInfo, + &nonExternalReq); + + pMemoryRequirements->memoryRequirements.size = + RDCMAX(pMemoryRequirements->memoryRequirements.size, nonExternalReq.memoryRequirements.size); + pMemoryRequirements->memoryRequirements.alignment = + RDCMAX(pMemoryRequirements->memoryRequirements.alignment, + nonExternalReq.memoryRequirements.alignment); + + if((pMemoryRequirements->memoryRequirements.memoryTypeBits & + nonExternalReq.memoryRequirements.memoryTypeBits) == 0) + { + RDCWARN( + "External image shares no memory types with non-external image. This image " + "will not be replayable."); + } + else + { + pMemoryRequirements->memoryRequirements.memoryTypeBits &= + nonExternalReq.memoryRequirements.memoryTypeBits; + } + } +} + +void WrappedVulkan::vkGetDeviceImageSparseMemoryRequirementsKHR( + VkDevice device, const VkDeviceImageMemoryRequirementsKHR *pInfo, + uint32_t *pSparseMemoryRequirementCount, + VkSparseImageMemoryRequirements2 *pSparseMemoryRequirements) +{ + byte *tempMem = GetTempMemory(GetNextPatchSize(pInfo)); + VkDeviceImageMemoryRequirementsKHR *unwrappedInfo = UnwrapStructAndChain(m_State, tempMem, pInfo); + + ObjDisp(device)->GetDeviceImageSparseMemoryRequirementsKHR( + Unwrap(device), unwrappedInfo, pSparseMemoryRequirementCount, pSparseMemoryRequirements); +} + void WrappedVulkan::vkGetBufferMemoryRequirements2(VkDevice device, const VkBufferMemoryRequirementsInfo2 *pInfo, VkMemoryRequirements2 *pMemoryRequirements) diff --git a/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp index 9e081e493..23a67138b 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp @@ -1603,6 +1603,9 @@ VkResult WrappedVulkan::vkCreateBuffer(VkDevice device, const VkBufferCreateInfo { VkBufferCreateInfo adjusted_info = *pCreateInfo; + // if you change any properties here, ensure you also update + // vkGetDeviceBufferMemoryRequirementsKHR + // TEMP HACK: Until we define a portable fake hardware, need to match the requirements for usage // on replay, so that the memory requirements are the same adjusted_info.usage |= VK_BUFFER_USAGE_TRANSFER_SRC_BIT; @@ -2136,6 +2139,9 @@ VkResult WrappedVulkan::vkCreateImage(VkDevice device, const VkImageCreateInfo * { VkImageCreateInfo createInfo_adjusted = *pCreateInfo; + // if you change any properties here, ensure you also update + // vkGetDeviceImageMemoryRequirementsKHR + createInfo_adjusted.usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT; // TEMP HACK: Until we define a portable fake hardware, need to match the requirements for usage