Add support for VK_EXT_zero_initialize_device_memory

This commit is contained in:
baldurk
2026-07-24 17:52:48 +01:00
parent c6c8f807c9
commit 70caae7418
10 changed files with 62 additions and 10 deletions
+1 -1
View File
@@ -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
+7 -3
View File
@@ -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)
+2
View File
@@ -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);
+4
View File
@@ -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,
@@ -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))
{
+3
View File
@@ -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)
+2 -1
View File
@@ -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: \
+21 -4
View File
@@ -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 <typename SerialiserType>
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 <typename SerialiserType>
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);
@@ -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)
@@ -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