Replay external memory declarations on images for compatibility

* Descriptors in descriptor buffer may be affected by this, so we need to replay
  it. We add checks that the handle types are still OK to use on replay.
This commit is contained in:
baldurk
2025-09-08 17:14:38 +01:00
parent c983b96e3d
commit 6425d71fae
2 changed files with 83 additions and 2 deletions
+1 -2
View File
@@ -179,6 +179,7 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct,
COPY_STRUCT(VK_STRUCTURE_TYPE_EVENT_CREATE_INFO, VkEventCreateInfo); \
COPY_STRUCT(VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES, VkExternalBufferProperties); \
COPY_STRUCT(VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES, VkExternalImageFormatProperties); \
COPY_STRUCT(VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO, VkExternalMemoryImageCreateInfo); \
COPY_STRUCT(VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, VkFenceCreateInfo); \
COPY_STRUCT(VK_STRUCTURE_TYPE_FILTER_CUBIC_IMAGE_VIEW_IMAGE_FORMAT_PROPERTIES_EXT, \
VkFilterCubicImageViewImageFormatPropertiesEXT); \
@@ -803,8 +804,6 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct,
COPY_STRUCT_CAPTURE_ONLY(VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES, VkExternalFenceProperties); \
COPY_STRUCT_CAPTURE_ONLY(VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO, \
VkExternalMemoryBufferCreateInfo); \
COPY_STRUCT_CAPTURE_ONLY(VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO, \
VkExternalMemoryImageCreateInfo); \
COPY_STRUCT_CAPTURE_ONLY(VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_NV, \
VkExternalMemoryImageCreateInfoNV); \
COPY_STRUCT_CAPTURE_ONLY(VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES, \
@@ -2610,6 +2610,88 @@ bool WrappedVulkan::Serialise_vkCreateImage(SerialiserType &ser, VkDevice device
}
}
VkExternalMemoryImageCreateInfo *extCreateInfo =
(VkExternalMemoryImageCreateInfo *)FindNextStruct(
&CreateInfo, VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO);
// if we've allowed an external memory image create info to stay, validate that the handle types
// are still supported
if(extCreateInfo)
{
VkExternalImageFormatProperties externalResult = {
VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES,
};
VkImageFormatProperties2 resultBase = {
VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
&externalResult,
};
VkPhysicalDeviceExternalImageFormatInfo externalQuery = {
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
};
VkPhysicalDeviceImageFormatInfo2 queryBase = {
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
&externalQuery,
};
// pass creation info
queryBase.flags = CreateInfo.flags;
queryBase.format = CreateInfo.format;
queryBase.tiling = CreateInfo.tiling;
queryBase.type = CreateInfo.imageType;
queryBase.usage = CreateInfo.usage;
// pass image format list, if the application did
VkImageFormatListCreateInfo *appFormatInfo = (VkImageFormatListCreateInfo *)FindNextStruct(
&CreateInfo, VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO);
VkImageFormatListCreateInfo formatInfo;
if(appFormatInfo)
{
formatInfo = *appFormatInfo;
formatInfo.pNext = queryBase.pNext;
queryBase.pNext = &formatInfo;
}
for(uint32_t i = 0; i < 32; i++)
{
VkExternalMemoryHandleTypeFlagBits checkBit = VkExternalMemoryHandleTypeFlagBits(1U << i);
// only check compatibility for set bits
if(extCreateInfo->handleTypes & checkBit)
{
externalQuery.handleType = checkBit;
VkResult queryResult = ObjDisp(m_PhysicalDevice)
->GetPhysicalDeviceImageFormatProperties2(
Unwrap(m_PhysicalDevice), &queryBase, &resultBase);
if(queryResult != VK_SUCCESS)
{
RDCERR("vkGetPhysicalDeviceImageFormatProperties2 returned %s",
ToStr(queryResult).c_str());
externalResult.externalMemoryProperties.externalMemoryFeatures = 0;
}
// we don't know what the application wanted to use this handle type for, but if at least
// one of import/export is supported we can replay this OK
if(externalResult.externalMemoryProperties.externalMemoryFeatures &
(VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT | VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT))
continue;
// otherwise we must fail because this handle type isn't supported at all
SET_ERROR_RESULT(
m_FailedReplayResult, ResultCode::APIHardwareUnsupported,
"Tried to create image with external handle types %s, but on replay handle type %s "
"can't "
"be imported or exported.\n"
"\n%s",
ToStr((VkExternalMemoryHandleTypeFlagBits)extCreateInfo->handleTypes).c_str(),
ToStr(checkBit).c_str(), GetPhysDeviceCompatString(false, false).c_str());
return false;
}
}
}
VkImageCreateInfo patched = CreateInfo;
byte *tempMem = GetTempMemory(GetNextPatchSize(patched.pNext));