From 3d68db6ec24e88a9fb6383602f85abc76e31f57c Mon Sep 17 00:00:00 2001 From: EdoardoLuciani Date: Thu, 25 Aug 2022 13:27:19 +0100 Subject: [PATCH 1/2] Dynamically fetch instance level vulkan functions --- src/VK/UpscaleContext_FSR2_API.cpp | 4 +- src/ffx-fsr2-api/vk/ffx_fsr2_vk.cpp | 67 +++++++++++++++++++---------- src/ffx-fsr2-api/vk/ffx_fsr2_vk.h | 5 ++- 3 files changed, 50 insertions(+), 26 deletions(-) diff --git a/src/VK/UpscaleContext_FSR2_API.cpp b/src/VK/UpscaleContext_FSR2_API.cpp index f98b837..a95e602 100644 --- a/src/VK/UpscaleContext_FSR2_API.cpp +++ b/src/VK/UpscaleContext_FSR2_API.cpp @@ -91,9 +91,9 @@ void UpscaleContext_FSR2_API::OnCreateWindowSizeDependentResources( UpscaleContext::OnCreateWindowSizeDependentResources(input, output, renderWidth, renderHeight, displayWidth, displayHeight, hdr); // Setup VK interface. - const size_t scratchBufferSize = ffxFsr2GetScratchMemorySizeVK(m_pDevice->GetPhysicalDevice()); + const size_t scratchBufferSize = ffxFsr2GetScratchMemorySizeVK(m_pDevice->GetPhysicalDevice(), vkEnumerateDeviceExtensionProperties); void* scratchBuffer = malloc(scratchBufferSize); - FfxErrorCode errorCode = ffxFsr2GetInterfaceVK(&initializationParameters.callbacks, scratchBuffer, scratchBufferSize, m_pDevice->GetPhysicalDevice(), vkGetDeviceProcAddr); + FfxErrorCode errorCode = ffxFsr2GetInterfaceVK(&initializationParameters.callbacks, scratchBuffer, scratchBufferSize, m_pDevice->GetInstance(), m_pDevice->GetPhysicalDevice(), vkGetInstanceProcAddr); FFX_ASSERT(errorCode == FFX_OK); initializationParameters.device = ffxGetDeviceVK(m_pDevice->GetDevice()); diff --git a/src/ffx-fsr2-api/vk/ffx_fsr2_vk.cpp b/src/ffx-fsr2-api/vk/ffx_fsr2_vk.cpp index f984d86..5b17315 100644 --- a/src/ffx-fsr2-api/vk/ffx_fsr2_vk.cpp +++ b/src/ffx-fsr2-api/vk/ffx_fsr2_vk.cpp @@ -89,7 +89,16 @@ typedef struct BackendContext_VK { } PipelineLayout; typedef struct VKFunctionTable - { + { + // instance functions + PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = 0; + PFN_vkEnumerateDeviceExtensionProperties vkEnumerateDeviceExtensionProperties = 0; + PFN_vkGetPhysicalDeviceMemoryProperties vkGetPhysicalDeviceMemoryProperties = 0; + PFN_vkGetPhysicalDeviceProperties vkGetPhysicalDeviceProperties = 0; + PFN_vkGetPhysicalDeviceProperties2 vkGetPhysicalDeviceProperties2 = 0; + PFN_vkGetPhysicalDeviceFeatures2 vkGetPhysicalDeviceFeatures2 = 0; + + // device functions PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr = 0; PFN_vkSetDebugUtilsObjectNameEXT vkSetDebugUtilsObjectNameEXT = 0; PFN_vkCreateDescriptorPool vkCreateDescriptorPool = 0; @@ -131,6 +140,7 @@ typedef struct BackendContext_VK { PFN_vkCmdClearColorImage vkCmdClearColorImage = 0; } VkFunctionTable; + VkInstance instance = nullptr; VkPhysicalDevice physicalDevice = nullptr; VkDevice device = nullptr; VkFunctionTable vkFunctionTable = {}; @@ -169,7 +179,7 @@ typedef struct BackendContext_VK { } BackendContext_VK; -FFX_API size_t ffxFsr2GetScratchMemorySizeVK(VkPhysicalDevice physicalDevice) +FFX_API size_t ffxFsr2GetScratchMemorySizeVK(VkPhysicalDevice physicalDevice, PFN_vkEnumerateDeviceExtensionProperties vkEnumerateDeviceExtensionProperties) { uint32_t numExtensions = 0; @@ -183,8 +193,9 @@ FfxErrorCode ffxFsr2GetInterfaceVK( FfxFsr2Interface* outInterface, void* scratchBuffer, size_t scratchBufferSize, + VkInstance instance, VkPhysicalDevice physicalDevice, - PFN_vkGetDeviceProcAddr getDeviceProcAddr) + PFN_vkGetInstanceProcAddr getInstanceProcAddr) { FFX_RETURN_ON_ERROR( outInterface, @@ -193,7 +204,7 @@ FfxErrorCode ffxFsr2GetInterfaceVK( scratchBuffer, FFX_ERROR_INVALID_POINTER); FFX_RETURN_ON_ERROR( - scratchBufferSize >= ffxFsr2GetScratchMemorySizeVK(physicalDevice), + scratchBufferSize >= ffxFsr2GetScratchMemorySizeVK(physicalDevice, (PFN_vkEnumerateDeviceExtensionProperties)getInstanceProcAddr(instance, "vkEnumerateDeviceExtensionProperties")), FFX_ERROR_INSUFFICIENT_MEMORY); outInterface->fpGetDeviceCapabilities = GetDeviceCapabilitiesVK; @@ -213,15 +224,25 @@ FfxErrorCode ffxFsr2GetInterfaceVK( BackendContext_VK* context = (BackendContext_VK*)scratchBuffer; + context->instance = instance; context->physicalDevice = physicalDevice; - context->vkFunctionTable.vkGetDeviceProcAddr = getDeviceProcAddr; + context->vkFunctionTable.vkGetInstanceProcAddr = getInstanceProcAddr; return FFX_OK; } -void loadVKFunctions(BackendContext_VK* backendContext, PFN_vkGetDeviceProcAddr getDeviceProcAddr) +void loadVKFunctions(BackendContext_VK* backendContext, PFN_vkGetInstanceProcAddr getInstanceProcAddr) { FFX_ASSERT(NULL != backendContext); + + backendContext->vkFunctionTable.vkGetDeviceProcAddr = (PFN_vkGetDeviceProcAddr)getInstanceProcAddr(backendContext->instance, "vkGetDeviceProcAddr"); + backendContext->vkFunctionTable.vkEnumerateDeviceExtensionProperties = (PFN_vkEnumerateDeviceExtensionProperties)getInstanceProcAddr(backendContext->instance, "vkEnumerateDeviceExtensionProperties"); + backendContext->vkFunctionTable.vkGetPhysicalDeviceMemoryProperties = (PFN_vkGetPhysicalDeviceMemoryProperties)getInstanceProcAddr(backendContext->instance, "vkGetPhysicalDeviceMemoryProperties"); + backendContext->vkFunctionTable.vkGetPhysicalDeviceProperties = (PFN_vkGetPhysicalDeviceProperties)getInstanceProcAddr(backendContext->instance, "vkGetPhysicalDeviceProperties"); + backendContext->vkFunctionTable.vkGetPhysicalDeviceProperties2 = (PFN_vkGetPhysicalDeviceProperties2)getInstanceProcAddr(backendContext->instance, "vkGetPhysicalDeviceProperties2"); + backendContext->vkFunctionTable.vkGetPhysicalDeviceFeatures2 = (PFN_vkGetPhysicalDeviceFeatures2)getInstanceProcAddr(backendContext->instance, "vkGetPhysicalDeviceFeatures2"); + + PFN_vkGetDeviceProcAddr getDeviceProcAddr = backendContext->vkFunctionTable.vkGetDeviceProcAddr; backendContext->vkFunctionTable.vkSetDebugUtilsObjectNameEXT = (PFN_vkSetDebugUtilsObjectNameEXT)getDeviceProcAddr(backendContext->device, "vkSetDebugUtilsObjectNameEXT"); backendContext->vkFunctionTable.vkFlushMappedMemoryRanges = (PFN_vkFlushMappedMemoryRanges)getDeviceProcAddr(backendContext->device, "vkFlushMappedMemoryRanges"); @@ -433,13 +454,10 @@ FfxSurfaceFormat ffxGetSurfaceFormatVK(VkFormat fmt) } } -uint32_t findMemoryTypeIndex(VkPhysicalDevice physicalDevice, VkMemoryRequirements memRequirements, VkMemoryPropertyFlags requestedProperties, VkMemoryPropertyFlags& outProperties) +uint32_t findMemoryTypeIndex(VkPhysicalDevice physicalDevice, VkMemoryRequirements memRequirements, VkMemoryPropertyFlags requestedProperties, VkMemoryPropertyFlags& outProperties, VkPhysicalDeviceMemoryProperties &memProperties) { FFX_ASSERT(NULL != physicalDevice); - VkPhysicalDeviceMemoryProperties memProperties; - vkGetPhysicalDeviceMemoryProperties(physicalDevice, &memProperties); - uint32_t bestCandidate = UINT32_MAX; for (uint32_t i = 0; i < memProperties.memoryTypeCount; i++) { @@ -711,7 +729,7 @@ FfxErrorCode GetDeviceCapabilitiesVK(FfxFsr2Interface* backendInterface, FfxDevi VkPhysicalDeviceProperties2 deviceProperties2 = {}; deviceProperties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; deviceProperties2.pNext = &subgroupSizeControlProperties; - vkGetPhysicalDeviceProperties2(context->physicalDevice, &deviceProperties2); + context->vkFunctionTable.vkGetPhysicalDeviceProperties2(context->physicalDevice, &deviceProperties2); deviceCapabilities->waveLaneCountMin = subgroupSizeControlProperties.minSubgroupSize; deviceCapabilities->waveLaneCountMax = subgroupSizeControlProperties.maxSubgroupSize; @@ -725,8 +743,7 @@ FfxErrorCode GetDeviceCapabilitiesVK(FfxFsr2Interface* backendInterface, FfxDevi VkPhysicalDeviceFeatures2 physicalDeviceFeatures2 = {}; physicalDeviceFeatures2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; physicalDeviceFeatures2.pNext = &shaderFloat18Int8Features; - - vkGetPhysicalDeviceFeatures2(context->physicalDevice, &physicalDeviceFeatures2); + context->vkFunctionTable.vkGetPhysicalDeviceFeatures2(context->physicalDevice, &physicalDeviceFeatures2); deviceCapabilities->fp16Supported = (bool)shaderFloat18Int8Features.shaderFloat16; } @@ -739,8 +756,7 @@ FfxErrorCode GetDeviceCapabilitiesVK(FfxFsr2Interface* backendInterface, FfxDevi VkPhysicalDeviceFeatures2 physicalDeviceFeatures2 = {}; physicalDeviceFeatures2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; physicalDeviceFeatures2.pNext = &accelerationStructureFeatures; - - vkGetPhysicalDeviceFeatures2(context->physicalDevice, &physicalDeviceFeatures2); + context->vkFunctionTable.vkGetPhysicalDeviceFeatures2(context->physicalDevice, &physicalDeviceFeatures2); deviceCapabilities->raytracingSupported = (bool)accelerationStructureFeatures.accelerationStructure; } @@ -774,12 +790,13 @@ FfxErrorCode CreateDeviceVK(FfxFsr2Interface* backendInterface, FfxDevice device backendContext->nextDynamicResource = FSR2_MAX_RESOURCE_COUNT - 1; // load vulkan functions - loadVKFunctions(backendContext, backendContext->vkFunctionTable.vkGetDeviceProcAddr); + loadVKFunctions(backendContext, backendContext->vkFunctionTable.vkGetInstanceProcAddr); // enumerate all the device extensions backendContext->numDeviceExtensions = 0; - vkEnumerateDeviceExtensionProperties(backendContext->physicalDevice, nullptr, &backendContext->numDeviceExtensions, nullptr); - vkEnumerateDeviceExtensionProperties(backendContext->physicalDevice, nullptr, &backendContext->numDeviceExtensions, backendContext->extensionProperties); + + backendContext->vkFunctionTable.vkEnumerateDeviceExtensionProperties(backendContext->physicalDevice, nullptr, &backendContext->numDeviceExtensions, nullptr); + backendContext->vkFunctionTable.vkEnumerateDeviceExtensionProperties(backendContext->physicalDevice, nullptr, &backendContext->numDeviceExtensions, backendContext->extensionProperties); // create descriptor pool VkDescriptorPoolCreateInfo descriptorPoolCreateInfo = {}; @@ -876,14 +893,17 @@ FfxErrorCode CreateDeviceVK(FfxFsr2Interface* backendInterface, FfxDevice device VkMemoryPropertyFlags requiredMemoryProperties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; + VkPhysicalDeviceMemoryProperties memProperties; + backendContext->vkFunctionTable.vkGetPhysicalDeviceMemoryProperties(backendContext->physicalDevice, &memProperties); + VkMemoryAllocateInfo allocInfo{}; allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; allocInfo.allocationSize = FSR2_UBO_MEMORY_BLOCK_SIZE; - allocInfo.memoryTypeIndex = findMemoryTypeIndex(backendContext->physicalDevice, memRequirements, requiredMemoryProperties, backendContext->uboMemoryProperties); + allocInfo.memoryTypeIndex = findMemoryTypeIndex(backendContext->physicalDevice, memRequirements, requiredMemoryProperties, backendContext->uboMemoryProperties, memProperties); if (allocInfo.memoryTypeIndex == UINT32_MAX) { requiredMemoryProperties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; - allocInfo.memoryTypeIndex = findMemoryTypeIndex(backendContext->physicalDevice, memRequirements, requiredMemoryProperties, backendContext->uboMemoryProperties); + allocInfo.memoryTypeIndex = findMemoryTypeIndex(backendContext->physicalDevice, memRequirements, requiredMemoryProperties, backendContext->uboMemoryProperties, memProperties); if (allocInfo.memoryTypeIndex == UINT32_MAX) { return FFX_ERROR_BACKEND_API_ERROR; @@ -1077,10 +1097,13 @@ FfxErrorCode CreateResourceVK( else requiredMemoryProperties = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; + VkPhysicalDeviceMemoryProperties memProperties; + backendContext->vkFunctionTable.vkGetPhysicalDeviceMemoryProperties(backendContext->physicalDevice, &memProperties); + VkMemoryAllocateInfo allocInfo{}; allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; allocInfo.allocationSize = memRequirements.size; - allocInfo.memoryTypeIndex = findMemoryTypeIndex(backendContext->physicalDevice, memRequirements, requiredMemoryProperties, res->memoryProperties); + allocInfo.memoryTypeIndex = findMemoryTypeIndex(backendContext->physicalDevice, memRequirements, requiredMemoryProperties, res->memoryProperties, memProperties); if (allocInfo.memoryTypeIndex == UINT32_MAX) { return FFX_ERROR_BACKEND_API_ERROR; @@ -1263,7 +1286,7 @@ FfxErrorCode CreatePipelineVK(FfxFsr2Interface* backendInterface, FfxFsr2Pass pa if (pass == FFX_FSR2_PASS_ACCUMULATE || pass == FFX_FSR2_PASS_ACCUMULATE_SHARPEN) { VkPhysicalDeviceProperties physicalDeviceProperties = {}; - vkGetPhysicalDeviceProperties(backendContext->physicalDevice, &physicalDeviceProperties); + backendContext->vkFunctionTable.vkGetPhysicalDeviceProperties(backendContext->physicalDevice, &physicalDeviceProperties); // Workaround: Disable FP16 path for the accumulate pass on NVIDIA due to reduced occupancy and high VRAM throughput. if (physicalDeviceProperties.vendorID == 0x10DE) diff --git a/src/ffx-fsr2-api/vk/ffx_fsr2_vk.h b/src/ffx-fsr2-api/vk/ffx_fsr2_vk.h index c352c98..b39591a 100644 --- a/src/ffx-fsr2-api/vk/ffx_fsr2_vk.h +++ b/src/ffx-fsr2-api/vk/ffx_fsr2_vk.h @@ -35,7 +35,7 @@ extern "C" { /// /// @returns /// The size (in bytes) of the required scratch memory buffer for the VK backend. - FFX_API size_t ffxFsr2GetScratchMemorySizeVK(VkPhysicalDevice physicalDevice); + FFX_API size_t ffxFsr2GetScratchMemorySizeVK(VkPhysicalDevice physicalDevice, PFN_vkEnumerateDeviceExtensionProperties vkEnumerateDeviceExtensionProperties); /// Populate an interface with pointers for the VK backend. /// @@ -56,8 +56,9 @@ extern "C" { FfxFsr2Interface* outInterface, void* scratchBuffer, size_t scratchBufferSize, + VkInstance instance, VkPhysicalDevice physicalDevice, - PFN_vkGetDeviceProcAddr getDeviceProcAddr); + PFN_vkGetInstanceProcAddr getInstanceProcAddr); /// Create a FfxFsr2Device from a VkDevice. /// From 8aa095e25b02ddf9354ee0f767ac010be9e7f226 Mon Sep 17 00:00:00 2001 From: EdoardoLuciani Date: Thu, 25 Aug 2022 14:10:11 +0100 Subject: [PATCH 2/2] Remove external definition of vkGetDeviceProcAddr --- src/ffx-fsr2-api/vk/ffx_fsr2_vk.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/ffx-fsr2-api/vk/ffx_fsr2_vk.cpp b/src/ffx-fsr2-api/vk/ffx_fsr2_vk.cpp index 5b17315..dc510bc 100644 --- a/src/ffx-fsr2-api/vk/ffx_fsr2_vk.cpp +++ b/src/ffx-fsr2-api/vk/ffx_fsr2_vk.cpp @@ -778,10 +778,6 @@ FfxErrorCode CreateDeviceVK(FfxFsr2Interface* backendInterface, FfxDevice device // make sure the extra parameters were already passed in FFX_ASSERT(backendContext->physicalDevice != NULL); - // if vkGetDeviceProcAddr is NULL, use the one from the vulkan header - if (backendContext->vkFunctionTable.vkGetDeviceProcAddr == NULL) - backendContext->vkFunctionTable.vkGetDeviceProcAddr = vkGetDeviceProcAddr; - if (vkDevice != NULL) { backendContext->device = vkDevice; }