From 91c13a0e9f3e1770a4e45c7b0b39612da686a323 Mon Sep 17 00:00:00 2001 From: Jasmine Hansen Date: Tue, 7 May 2024 11:33:43 -0700 Subject: [PATCH] Implemented vkGetShaderBinaryDataEXT. Added logic to return a fake UUID for shader binaries if vkGetShaderBinaryDataEXT is called. Co-authored-by: James Sumihiro --- .../driver/vulkan/wrappers/vk_get_funcs.cpp | 36 ++++++++++++++++++- .../vulkan/wrappers/vk_shader_funcs.cpp | 9 ++++- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/renderdoc/driver/vulkan/wrappers/vk_get_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_get_funcs.cpp index 2097ece6b..d005187d7 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_get_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_get_funcs.cpp @@ -875,6 +875,16 @@ void WrappedVulkan::vkGetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevi memcpy(pProperties->properties.pipelineCacheUUID, fakeRenderDocUUID, VK_UUID_SIZE); ClampPhysDevAPIVersion(&pProperties->properties, physicalDevice); + + // internal RenderDoc UUID for shader object binary + VkPhysicalDeviceShaderObjectPropertiesEXT *shadObj = + (VkPhysicalDeviceShaderObjectPropertiesEXT *)FindNextStruct( + pProperties, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_OBJECT_PROPERTIES_EXT); + + if(shadObj) + { + memcpy(shadObj->shaderBinaryUUID, fakeRenderDocUUID, VK_UUID_SIZE); + } } void WrappedVulkan::vkGetPhysicalDeviceQueueFamilyProperties2( @@ -1232,5 +1242,29 @@ void WrappedVulkan::vkGetDeviceAccelerationStructureCompatibilityKHR( VkResult WrappedVulkan::vkGetShaderBinaryDataEXT(VkDevice device, VkShaderEXT shader, size_t *pDataSize, void *pData) { - return VK_ERROR_INITIALIZATION_FAILED; + // renderdoc doesn't support shader binaries, but should comply with the spec + // so we return four NULL bytes if this function is called and would otherwise + // return a valid binary + size_t totalSize = 4; + + if(pDataSize && !pData) + *pDataSize = totalSize; + + if(pDataSize && pData) + { + if(*pDataSize < totalSize) + { + memset(pData, 0, *pDataSize); + return VK_INCOMPLETE; + } + + // empty bytes + memset(pData, 0, 4); + } + + // we don't want the application to use shader binaries at all, and especially + // don't want to return any data for future use. We thus return a technically + // valid but empty shader binary. Our UUID changes every run so in theory the + // application should never provide an old binary. + return VK_SUCCESS; } diff --git a/renderdoc/driver/vulkan/wrappers/vk_shader_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_shader_funcs.cpp index 8a148f558..048a257ae 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_shader_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_shader_funcs.cpp @@ -438,7 +438,14 @@ VkResult WrappedVulkan::vkCreateShadersEXT(VkDevice device, uint32_t createInfoC // to be extra sure just in case the driver doesn't, set shader objects to VK_NULL_HANDLE first. for(uint32_t i = 0; i < createInfoCount; i++) - pShaders[i] = VK_NULL_HANDLE; + { + // shader binaries aren't supported, and any calls to vkGetShaderBinaryData should return a + // valid but incompatible UUID + if(pCreateInfos[i].codeType == VK_SHADER_CODE_TYPE_BINARY_EXT) + return VK_ERROR_INCOMPATIBLE_SHADER_BINARY_EXT; + else + pShaders[i] = VK_NULL_HANDLE; + } VkResult ret; SERIALISE_TIME_CALL(ret = ObjDisp(device)->CreateShadersEXT(Unwrap(device), createInfoCount,