diff --git a/renderdoc/driver/vulkan/vk_next_chains.cpp b/renderdoc/driver/vulkan/vk_next_chains.cpp index f77d7a6f1..3bdb797a5 100644 --- a/renderdoc/driver/vulkan/vk_next_chains.cpp +++ b/renderdoc/driver/vulkan/vk_next_chains.cpp @@ -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, \ diff --git a/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp index 9e2fc95b6..ff512a582 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp @@ -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));