Skip to content

Commit

Permalink
Add device functions to InstanceGetProcAddr()
Browse files Browse the repository at this point in the history
  • Loading branch information
solidpixel committed Dec 10, 2024
1 parent f91d88f commit 83ad75f
Show file tree
Hide file tree
Showing 5 changed files with 515 additions and 83 deletions.
40 changes: 29 additions & 11 deletions generator/generate_vulkan_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ def load_api_extensions(self, root):
continue

# Omit extensions that are from other vendors
vendor = ext_name.split("_")[1]
vendor = ext_name.split('_')[1]
if vendor in EXTENSION_VENDOR_FILTER:
continue

Expand Down Expand Up @@ -337,7 +337,7 @@ def generate_layer_instance_dispatch_table(file, mapping, commands):
data = load_template('instance_dispatch_table.txt')

# Create a listing of API versions and API extensions
itable_members = []
itable_members = ['// Instance functions']
dispatch_table_members = []
dispatch_table_inits = []

Expand Down Expand Up @@ -370,6 +370,24 @@ def generate_layer_instance_dispatch_table(file, mapping, commands):
dispatch_table_members.append('#endif')
dispatch_table_inits.append('#endif')

itable_members = ['\n// Device functions']

for command in commands:
if command.dispatch_type != 'device':
continue

plat_define = mapping.get_platform_define(command.name)
ttype = f'PFN_{command.name}'
tname = command.name

if plat_define:
itable_members.append(f'#if defined({plat_define})')

itable_members.append(f' ENTRY({tname}),')

if plat_define:
itable_members.append('#endif')

data = data.replace('{ITABLE_MEMBERS}', '\n'.join(itable_members))
data = data.replace('{DTABLE_MEMBERS}', '\n'.join(dispatch_table_members))
data = data.replace('{DTABLE_INITS}', '\n'.join(dispatch_table_inits))
Expand All @@ -389,7 +407,7 @@ def generate_layer_instance_layer_decls(file, mapping, commands):

# Create a listing of API versions and API extensions
for command in commands:
if command.dispatch_type != "instance":
if command.dispatch_type != 'instance':
continue

lines = []
Expand Down Expand Up @@ -426,7 +444,7 @@ def generate_layer_instance_layer_decls(file, mapping, commands):
parl = f' {ptype} {pname}{array}{ending}'
lines.append(parl)

parmfwd = ", ".join([x[1] for x in command.params])
parmfwd = ', '.join([x[1] for x in command.params])
retfwd = 'return ' if command.rtype != 'void' else ''
lines.append(') {')
lines.append(f' {retfwd}layer_{command.name}_default({parmfwd});')
Expand All @@ -449,7 +467,7 @@ def generate_layer_instance_layer_defs(file, mapping, commands, manual_commands)
# Create a listing of API versions and API extensions
lines = []
for command in commands:
if command.dispatch_type != "instance":
if command.dispatch_type != 'instance':
continue

plat_define = mapping.get_platform_define(command.name)
Expand All @@ -468,7 +486,7 @@ def generate_layer_instance_layer_defs(file, mapping, commands, manual_commands)
lines.append(parl)

dispatch = command.params[0][1]
parmfwd = ", ".join([x[1] for x in command.params])
parmfwd = ', '.join([x[1] for x in command.params])
retfwd = 'return ' if command.rtype != 'void' else ''

lines.append(') {')
Expand Down Expand Up @@ -506,7 +524,7 @@ def generate_layer_device_dispatch_table(file, mapping, commands):
dispatch_table_members = []
dispatch_table_inits = []
for command in commands:
if command.dispatch_type != "device":
if command.dispatch_type != 'device':
continue

plat_define = mapping.get_platform_define(command.name)
Expand Down Expand Up @@ -546,7 +564,7 @@ def generate_layer_device_layer_decls(file, mapping, commands):

# Create a listing of API versions and API extensions
for command in commands:
if command.dispatch_type != "device":
if command.dispatch_type != 'device':
continue

lines = []
Expand Down Expand Up @@ -582,7 +600,7 @@ def generate_layer_device_layer_decls(file, mapping, commands):
parl = f' {ptype} {pname}{array}{ending}'
lines.append(parl)

parmfwd = ", ".join([x[1] for x in command.params])
parmfwd = ', '.join([x[1] for x in command.params])
retfwd = 'return ' if command.rtype != 'void' else ''
lines.append(') {')
lines.append(f' {retfwd}layer_{command.name}_default({parmfwd});')
Expand All @@ -605,7 +623,7 @@ def generate_layer_device_layer_defs(file, mapping, commands, manual_commands):
# Create a listing of API versions and API extensions
lines = []
for command in commands:
if command.dispatch_type != "device":
if command.dispatch_type != 'device':
continue

plat_define = mapping.get_platform_define(command.name)
Expand All @@ -625,7 +643,7 @@ def generate_layer_device_layer_defs(file, mapping, commands, manual_commands):
lines.append(parl)

dispatch = command.params[0][1]
parmfwd = ", ".join([x[1] for x in command.params])
parmfwd = ', '.join([x[1] for x in command.params])
retfwd = 'return ' if command.rtype != 'void' else ''

lines.append(') {')
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
LAYER_TRACE(__func__);

// Hold the lock to access layer-wide global store
std::unique_lock<std::mutex> lock { g_vulkanLock };
auto* layer = Device::retrieve(device);

// Workaround Unreal Engine trying to invoke this via a function pointer
// queried from a Vulkan 1.1 instance with vkInstanceGetProcAddress() with
// device created from a later a Vulkan 1.0 context where the function is
// not available ...
if (!layer->driver.vkGetDeviceImageMemoryRequirementsKHR)
{
pMemoryRequirements->memoryRequirements.size = 0;
pMemoryRequirements->memoryRequirements.alignment = 0;
pMemoryRequirements->memoryRequirements.memoryTypeBits = 0;
return;
}

// Release the lock to call into the driver
lock.unlock();
layer->driver.vkGetDeviceImageMemoryRequirementsKHR(device, pInfo, pMemoryRequirements);
1 change: 1 addition & 0 deletions generator/vk_codegen/instance_dispatch_table.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <vulkan/vulkan.h>

#include "framework/device_functions.hpp"
#include "framework/instance_functions.hpp"
#include "framework/utils.hpp"
#include "utils/misc.hpp"
Expand Down
14 changes: 14 additions & 0 deletions source_common/framework/device_functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5955,10 +5955,24 @@ VKAPI_ATTR void VKAPI_CALL layer_vkGetDeviceImageMemoryRequirementsKHR_default(
) {
LAYER_TRACE(__func__);

LAYER_TRACE(__func__);

// Hold the lock to access layer-wide global store
std::unique_lock<std::mutex> lock { g_vulkanLock };
auto* layer = Device::retrieve(device);

// Workaround Unreal Engine trying to invoke this via a function pointer
// queried from a Vulkan 1.1 instance with vkInstanceGetProcAddress() with
// device created from a later a Vulkan 1.0 context where the function is
// not available ...
if (!layer->driver.vkGetDeviceImageMemoryRequirementsKHR)
{
pMemoryRequirements->memoryRequirements.size = 0;
pMemoryRequirements->memoryRequirements.alignment = 0;
pMemoryRequirements->memoryRequirements.memoryTypeBits = 0;
return;
}

// Release the lock to call into the driver
lock.unlock();
layer->driver.vkGetDeviceImageMemoryRequirementsKHR(device, pInfo, pMemoryRequirements);
Expand Down
Loading

0 comments on commit 83ad75f

Please sign in to comment.