Skip to content

Replace instance level vk symbols with dynamic fetching #49

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/VK/UpscaleContext_FSR2_API.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,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());
Expand Down
71 changes: 45 additions & 26 deletions src/ffx-fsr2-api/vk/ffx_fsr2_vk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,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;
Expand Down Expand Up @@ -132,6 +141,7 @@ typedef struct BackendContext_VK {
PFN_vkCmdClearColorImage vkCmdClearColorImage = 0;
} VkFunctionTable;

VkInstance instance = nullptr;
VkPhysicalDevice physicalDevice = nullptr;
VkDevice device = nullptr;
VkFunctionTable vkFunctionTable = {};
Expand Down Expand Up @@ -170,7 +180,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;

Expand All @@ -184,8 +194,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,
Expand All @@ -194,7 +205,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;
Expand All @@ -214,15 +225,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");
Expand Down Expand Up @@ -444,13 +465,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++) {
Expand Down Expand Up @@ -736,7 +754,7 @@ FfxErrorCode GetDeviceCapabilitiesVK(FfxFsr2Interface* backendInterface, FfxDevi
VkPhysicalDeviceProperties2 deviceProperties2 = {};
deviceProperties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
deviceProperties2.pNext = &subgroupSizeControlProperties;
vkGetPhysicalDeviceProperties2(backendContext->physicalDevice, &deviceProperties2);
backendContext->vkFunctionTable.vkGetPhysicalDeviceProperties2(backendContext->physicalDevice, &deviceProperties2);

// NOTE: It's important to check requiredSubgroupSizeStages flags (and it's required by the spec).
// As of August 2022, AMD's Vulkan drivers do not support subgroup size selection through Vulkan API
Expand All @@ -756,8 +774,7 @@ FfxErrorCode GetDeviceCapabilitiesVK(FfxFsr2Interface* backendInterface, FfxDevi
VkPhysicalDeviceFeatures2 physicalDeviceFeatures2 = {};
physicalDeviceFeatures2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
physicalDeviceFeatures2.pNext = &shaderFloat18Int8Features;

vkGetPhysicalDeviceFeatures2(backendContext->physicalDevice, &physicalDeviceFeatures2);
backendContext->vkFunctionTable.vkGetPhysicalDeviceFeatures2(backendContext->physicalDevice, &physicalDeviceFeatures2);

deviceCapabilities->fp16Supported = (bool)shaderFloat18Int8Features.shaderFloat16;
}
Expand All @@ -770,8 +787,7 @@ FfxErrorCode GetDeviceCapabilitiesVK(FfxFsr2Interface* backendInterface, FfxDevi
VkPhysicalDeviceFeatures2 physicalDeviceFeatures2 = {};
physicalDeviceFeatures2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
physicalDeviceFeatures2.pNext = &accelerationStructureFeatures;

vkGetPhysicalDeviceFeatures2(backendContext->physicalDevice, &physicalDeviceFeatures2);
backendContext->vkFunctionTable.vkGetPhysicalDeviceFeatures2(backendContext->physicalDevice, &physicalDeviceFeatures2);

deviceCapabilities->raytracingSupported = (bool)accelerationStructureFeatures.accelerationStructure;
}
Expand All @@ -793,10 +809,6 @@ FfxErrorCode CreateBackendContextVK(FfxFsr2Interface* backendInterface, FfxDevic
// 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;
}
Expand All @@ -805,12 +817,13 @@ FfxErrorCode CreateBackendContextVK(FfxFsr2Interface* backendInterface, FfxDevic
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 = {};
Expand Down Expand Up @@ -907,14 +920,17 @@ FfxErrorCode CreateBackendContextVK(FfxFsr2Interface* backendInterface, FfxDevic

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;
Expand Down Expand Up @@ -1107,10 +1123,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;
Expand Down Expand Up @@ -1298,7 +1317,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)
Expand Down
5 changes: 3 additions & 2 deletions src/ffx-fsr2-api/vk/ffx_fsr2_vk.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,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.
///
Expand All @@ -55,8 +55,9 @@ extern "C" {
FfxFsr2Interface* outInterface,
void* scratchBuffer,
size_t scratchBufferSize,
VkInstance instance,
VkPhysicalDevice physicalDevice,
PFN_vkGetDeviceProcAddr getDeviceProcAddr);
PFN_vkGetInstanceProcAddr getInstanceProcAddr);

/// Create a <c><i>FfxFsr2Device</i></c> from a <c><i>VkDevice</i></c>.
///
Expand Down