diff --git a/renderdoc/driver/vulkan/extension_support.md b/renderdoc/driver/vulkan/extension_support.md index 64a74d144..8e08907b3 100644 --- a/renderdoc/driver/vulkan/extension_support.md +++ b/renderdoc/driver/vulkan/extension_support.md @@ -140,6 +140,7 @@ Maintainers can update this file by updating vk.xml in this folder and running ` * `VK_EXT_vertex_input_dynamic_state` * `VK_EXT_ycbcr_2plane_444_formats` * `VK_EXT_ycbcr_image_arrays` +* `VK_EXT_zero_initialize_device_memory` * `VK_GOOGLE_decorate_string` * `VK_GOOGLE_display_timing` * `VK_GOOGLE_hlsl_functionality1` @@ -347,7 +348,6 @@ The portability subset is only relevant on mac, which is not a supported platfor * `VK_EXT_shader_uniform_buffer_unsized_array` * `VK_EXT_subpass_merge_feedback` * `VK_EXT_texture_compression_astc_3d` -* `VK_EXT_zero_initialize_device_memory` ## Platform/IHV Extensions diff --git a/renderdoc/driver/vulkan/vk_common.cpp b/renderdoc/driver/vulkan/vk_common.cpp index 7c6fa98d5..0155b8d3d 100644 --- a/renderdoc/driver/vulkan/vk_common.cpp +++ b/renderdoc/driver/vulkan/vk_common.cpp @@ -526,11 +526,15 @@ void SanitiseOldImageLayout(VkImageLayout &layout) // we can't transition to PREINITIALIZED, so instead use GENERAL. This allows host access so we // can still replay maps of the image's memory. In theory we can still transition from // PREINITIALIZED on replay, but consider that we need to be able to reset layouts and suddenly we - // have a problem transitioning from PREINITIALIZED more than once - so for that reason we - // instantly promote any images that are PREINITIALIZED to GENERAL at the start of the frame - // capture, and from then on treat it as the same + // have a problem transitioning from PREINITIALIZED more than once. + // We lose the PREINITIALIZED layout when initial contents are first applied, and from then on + // play pretend and leave it in GENERAL. if(layout == VK_IMAGE_LAYOUT_PREINITIALIZED) layout = VK_IMAGE_LAYOUT_GENERAL; + + // same applies to ZERO_INITIALIZED + if(layout == VK_IMAGE_LAYOUT_ZERO_INITIALIZED_EXT) + layout = VK_IMAGE_LAYOUT_GENERAL; } void SanitiseNewImageLayout(VkImageLayout &layout) diff --git a/renderdoc/driver/vulkan/vk_common.h b/renderdoc/driver/vulkan/vk_common.h index ba6c084b8..ed4905d2e 100644 --- a/renderdoc/driver/vulkan/vk_common.h +++ b/renderdoc/driver/vulkan/vk_common.h @@ -1896,6 +1896,7 @@ DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceVulkanMemoryModelFeatures); DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR); DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceYcbcr2Plane444FormatsFeaturesEXT); DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceYcbcrImageArraysFeaturesEXT); +DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceZeroInitializeDeviceMemoryFeaturesEXT); DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures); DECLARE_REFLECTION_STRUCT(VkPipelineCacheCreateInfo); DECLARE_REFLECTION_STRUCT(VkPipelineColorBlendStateCreateInfo); @@ -2470,6 +2471,7 @@ DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceVulkanMemoryModelFeatures); DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR); DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceYcbcr2Plane444FormatsFeaturesEXT); DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceYcbcrImageArraysFeaturesEXT); +DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceZeroInitializeDeviceMemoryFeaturesEXT); DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures); DECLARE_DESERIALISE_TYPE(VkPipelineCacheCreateInfo); DECLARE_DESERIALISE_TYPE(VkPipelineColorBlendStateCreateInfo); diff --git a/renderdoc/driver/vulkan/vk_core.cpp b/renderdoc/driver/vulkan/vk_core.cpp index 9c77b90bd..38bbaf24c 100644 --- a/renderdoc/driver/vulkan/vk_core.cpp +++ b/renderdoc/driver/vulkan/vk_core.cpp @@ -1548,6 +1548,10 @@ static const VkExtensionProperties supportedExtensions[] = { VK_EXT_YCBCR_IMAGE_ARRAYS_EXTENSION_NAME, VK_EXT_YCBCR_IMAGE_ARRAYS_SPEC_VERSION, }, + { + VK_EXT_ZERO_INITIALIZE_DEVICE_MEMORY_EXTENSION_NAME, + VK_EXT_ZERO_INITIALIZE_DEVICE_MEMORY_SPEC_VERSION, + }, { VK_GOOGLE_DECORATE_STRING_EXTENSION_NAME, VK_GOOGLE_DECORATE_STRING_SPEC_VERSION, diff --git a/renderdoc/driver/vulkan/vk_image_states.cpp b/renderdoc/driver/vulkan/vk_image_states.cpp index 9aa912f59..f298caa00 100644 --- a/renderdoc/driver/vulkan/vk_image_states.cpp +++ b/renderdoc/driver/vulkan/vk_image_states.cpp @@ -1147,6 +1147,11 @@ void ImageState::ResetToOldState(ImageBarrierSequence &barriers, ImageTransition // Transitioning back to PREINITIALIZED; this is impossible, so transition to GENERAL instead. newLayout = VK_IMAGE_LAYOUT_GENERAL; } + if(oldLayout != VK_IMAGE_LAYOUT_ZERO_INITIALIZED_EXT && + newLayout == VK_IMAGE_LAYOUT_ZERO_INITIALIZED_EXT) + { + newLayout = VK_IMAGE_LAYOUT_GENERAL; + } uint32_t srcQueueFamilyIndex = subIt->state().newQueueFamilyIndex; uint32_t dstQueueFamilyIndex = subIt->state().oldQueueFamilyIndex; @@ -1309,6 +1314,13 @@ void ImageState::Transition(const ImageState &dstState, VkAccessFlags srcAccessM dstQueueFamilyIndex = srcSub.oldQueueFamilyIndex; RDCASSERT(dstQueueFamilyIndex != VK_QUEUE_FAMILY_IGNORED); } + if(newLayout == VK_IMAGE_LAYOUT_ZERO_INITIALIZED_EXT && + oldLayout != VK_IMAGE_LAYOUT_ZERO_INITIALIZED_EXT) + { + newLayout = VK_IMAGE_LAYOUT_GENERAL; + dstQueueFamilyIndex = srcSub.oldQueueFamilyIndex; + RDCASSERT(dstQueueFamilyIndex != VK_QUEUE_FAMILY_IGNORED); + } if(IsReplayMode(info.capState)) { diff --git a/renderdoc/driver/vulkan/vk_initstate.cpp b/renderdoc/driver/vulkan/vk_initstate.cpp index bc6b7a426..b6ec3be83 100644 --- a/renderdoc/driver/vulkan/vk_initstate.cpp +++ b/renderdoc/driver/vulkan/vk_initstate.cpp @@ -1810,6 +1810,9 @@ void WrappedVulkan::Create_InitialState(ResourceId id, WrappedVkRes *res, bool) tag = VkInitialContents::PreInit; } + // zero-initialised images here will just go through the discard+clear path - which works out + // for their expected contents + GetResourceManager()->SetInitialContents(id, VkInitialContents(type, tag)); } else if(type == eResDeviceMemory) diff --git a/renderdoc/driver/vulkan/vk_next_chains.cpp b/renderdoc/driver/vulkan/vk_next_chains.cpp index b9c26ac5e..6be44d00c 100644 --- a/renderdoc/driver/vulkan/vk_next_chains.cpp +++ b/renderdoc/driver/vulkan/vk_next_chains.cpp @@ -688,6 +688,8 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct, VkPhysicalDeviceYcbcr2Plane444FormatsFeaturesEXT); \ COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_IMAGE_ARRAYS_FEATURES_EXT, \ VkPhysicalDeviceYcbcrImageArraysFeaturesEXT); \ + COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_DEVICE_MEMORY_FEATURES_EXT, \ + VkPhysicalDeviceZeroInitializeDeviceMemoryFeaturesEXT); \ COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_WORKGROUP_MEMORY_FEATURES, \ VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures); \ COPY_STRUCT(VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO, VkPipelineCacheCreateInfo); \ @@ -1471,7 +1473,6 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct, case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_MAINTENANCE_1_FEATURES_KHR: \ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_MAINTENANCE_2_FEATURES_KHR: \ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_DEGAMMA_FEATURES_QCOM: \ - case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_DEVICE_MEMORY_FEATURES_EXT: \ case VK_STRUCTURE_TYPE_PIPELINE_BINARY_CREATE_INFO_KHR: \ case VK_STRUCTURE_TYPE_PIPELINE_BINARY_DATA_INFO_KHR: \ case VK_STRUCTURE_TYPE_PIPELINE_BINARY_HANDLES_INFO_KHR: \ diff --git a/renderdoc/driver/vulkan/vk_serialise.cpp b/renderdoc/driver/vulkan/vk_serialise.cpp index d234da3d1..30cebc7c9 100644 --- a/renderdoc/driver/vulkan/vk_serialise.cpp +++ b/renderdoc/driver/vulkan/vk_serialise.cpp @@ -1086,6 +1086,10 @@ SERIALISE_VK_HANDLES(); PNEXT_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_IMAGE_ARRAYS_FEATURES_EXT, \ VkPhysicalDeviceYcbcrImageArraysFeaturesEXT) \ \ + /* VK_KHR_zero_initialize_workgroup_memory */ \ + PNEXT_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_WORKGROUP_MEMORY_FEATURES, \ + VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures) \ + \ /* VK_GOOGLE_display_timing */ \ PNEXT_STRUCT(VK_STRUCTURE_TYPE_PRESENT_TIMES_INFO_GOOGLE, VkPresentTimesInfoGOOGLE) \ \ @@ -1719,10 +1723,6 @@ SERIALISE_VK_HANDLES(); PNEXT_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES, \ VkPhysicalDeviceVulkanMemoryModelFeatures) \ \ - /* VK_KHR_zero_initialize_workgroup_memory */ \ - PNEXT_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_WORKGROUP_MEMORY_FEATURES, \ - VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures) \ - \ /* VK_KHR_compute_shader_derivatives promoted from VK_NV_compute_shader_derivatives */ \ PNEXT_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_SHADER_DERIVATIVES_FEATURES_KHR, \ VkPhysicalDeviceComputeShaderDerivativesFeaturesKHR) \ @@ -5415,6 +5415,22 @@ void Deserialise(const VkPhysicalDeviceVulkanMemoryModelFeatures &el) DeserialiseNext(el.pNext); } +template +void DoSerialise(SerialiserType &ser, VkPhysicalDeviceZeroInitializeDeviceMemoryFeaturesEXT &el) +{ + RDCASSERT(ser.IsReading() || + el.sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_WORKGROUP_MEMORY_FEATURES); + SerialiseNext(ser, el.sType, el.pNext); + + SERIALISE_MEMBER(zeroInitializeDeviceMemory); +} + +template <> +void Deserialise(const VkPhysicalDeviceZeroInitializeDeviceMemoryFeaturesEXT &el) +{ + DeserialiseNext(el.pNext); +} + template void DoSerialise(SerialiserType &ser, VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures &el) { @@ -16086,6 +16102,7 @@ INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceVulkanMemoryModelFeatures); INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR); INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceYcbcr2Plane444FormatsFeaturesEXT); INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceYcbcrImageArraysFeaturesEXT); +INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceZeroInitializeDeviceMemoryFeaturesEXT); INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures); INSTANTIATE_SERIALISE_TYPE(VkPipelineCacheCreateInfo); INSTANTIATE_SERIALISE_TYPE(VkPipelineColorBlendStateCreateInfo); diff --git a/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp index 4af4d0594..c8fcd74fc 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp @@ -3772,6 +3772,14 @@ bool WrappedVulkan::Serialise_vkCreateDevice(SerialiserType &ser, VkPhysicalDevi CHECK_PHYS_EXT_FEATURE(shaderTileImageStencilReadAccess); } END_PHYS_EXT_CHECK(); + + BEGIN_PHYS_EXT_CHECK( + VkPhysicalDeviceZeroInitializeDeviceMemoryFeaturesEXT, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_DEVICE_MEMORY_FEATURES_EXT); + { + CHECK_PHYS_EXT_FEATURE(zeroInitializeDeviceMemory); + } + END_PHYS_EXT_CHECK(); } if(availFeatures.depthClamp) diff --git a/renderdoc/driver/vulkan/wrappers/vk_sync_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_sync_funcs.cpp index b4693a04c..91f23f207 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_sync_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_sync_funcs.cpp @@ -1378,7 +1378,8 @@ bool WrappedVulkan::Serialise_vkCmdWaitEvents2(SerialiserType &ser, VkCommandBuf continue; } - if(!IsLoading(m_State) && barrier.oldLayout == VK_IMAGE_LAYOUT_PREINITIALIZED) + if(!IsLoading(m_State) && (barrier.oldLayout == VK_IMAGE_LAYOUT_PREINITIALIZED || + barrier.oldLayout == VK_IMAGE_LAYOUT_ZERO_INITIALIZED_EXT)) { // This is a transition from PRENITIALIZED, but we've already done this barrier once // (when loading); Since we couldn't transition back to PREINITIALIZED, we instead left