Skip to content

Commit 543afec

Browse files
authored
Move shared object exported entry points to tag dispatch (#28)
1 parent 4e477fe commit 543afec

22 files changed

+931
-658
lines changed

generator/generate_vulkan_common.py

Lines changed: 74 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -32,30 +32,48 @@
3232
import sys
3333
import xml.etree.ElementTree as ET
3434

35-
# These functions are manually created as fully exported entry points in the
36-
# layer library, and are not part of the dynamic dispatch behavior
37-
MANUAL_FUNCTIONS = {
38-
# Exposed by loader so not handled by the layer
35+
# These functions are not part of the layer implementation
36+
EXCLUDED_FUNCTIONS = {
37+
# Functions exposed by loader not the implementation
3938
'vkEnumerateInstanceVersion',
40-
# Exposed as symbols managed by the loader so not handled by the layer
41-
'vkGetInstanceProcAddr',
39+
}
40+
41+
# These functions are excluded from generated intercept and dispatch tables
42+
NO_INTERCEPT_OR_DISPATCH_FUNCTIONS = {
43+
# Functions resolved by the loaded not the implementation
4244
'vkGetDeviceProcAddr',
43-
# Exposed by layer as explicit entry points
45+
'vkGetInstanceProcAddr',
46+
}
47+
48+
# These functions are excluded from generated intercept tables
49+
NO_INTERCEPT_FUNCTIONS = {
50+
# Functions exported as shared object exports and resolved by loader
51+
'vkEnumerateDeviceExtensionProperties',
4452
'vkEnumerateDeviceLayerProperties',
4553
'vkEnumerateInstanceExtensionProperties',
4654
'vkEnumerateInstanceLayerProperties',
4755
}
4856

49-
# These functions are manually exported, but we can use driver forwarding
50-
FORWARD_WITHOUT_INTERCEPT = {
51-
'vkEnumerateDeviceExtensionProperties',
52-
'vkEnumerateInstanceExtensionProperties',
57+
# These functions are excluded from generated dispatch tables
58+
NO_DISPATCH_FUNCTIONS = {
59+
# Functions resolved by the loaded not the implementation
60+
'vkCreateDevice',
61+
'vkCreateInstance',
5362
}
5463

55-
# These functions are found via the loader-injected chain info
56-
INTERCEPT_WITHOUT_FORWARD = {
64+
# These functions are excluded from generated declarations
65+
CUSTOM_FUNCTIONS = {
5766
'vkCreateDevice',
5867
'vkCreateInstance',
68+
'vkDestroyDevice',
69+
'vkDestroyInstance',
70+
'vkGetDeviceProcAddr',
71+
'vkGetInstanceProcAddr',
72+
'vkEnumerateDeviceExtensionProperties',
73+
'vkEnumerateDeviceLayerProperties',
74+
'vkEnumerateInstanceExtensionProperties',
75+
'vkEnumerateInstanceLayerProperties',
76+
'vkGetDeviceImageMemoryRequirementsKHR',
5977
}
6078

6179
# Filter out extensions from these vendors by default
@@ -284,7 +302,7 @@ def __init__(self, mapping, root):
284302
self.params.append((ptype, text, tail))
285303

286304
# Filter out functions that are not dynamically dispatched
287-
if self.name in MANUAL_FUNCTIONS:
305+
if self.name in EXCLUDED_FUNCTIONS:
288306
raise NotImplementedError
289307

290308
# Filter out functions that are not in our supported mapping
@@ -299,7 +317,10 @@ def __init__(self, mapping, root):
299317
elif dispatch_type in DEVICE_FUNCTION_PARAM_TYPE:
300318
self.dispatch_type = 'device'
301319
else:
302-
assert False, f'Unknown dispatch: {dispatch_type} {self.name}'
320+
if self.name.startswith('vkEnumerateInstance'):
321+
self.dispatch_type = 'instance'
322+
else:
323+
assert False, f'Unknown dispatch: {dispatch_type} {self.name}'
303324

304325

305326
def load_template(path):
@@ -346,19 +367,23 @@ def generate_layer_instance_dispatch_table(file, mapping, commands):
346367
if command.dispatch_type != 'instance':
347368
continue
348369

370+
tname = command.name
371+
if tname in NO_INTERCEPT_OR_DISPATCH_FUNCTIONS:
372+
continue
373+
349374
plat_define = mapping.get_platform_define(command.name)
350375

351376
ttype = f'PFN_{command.name}'
352-
tname = command.name
353-
if tname not in FORWARD_WITHOUT_INTERCEPT:
377+
378+
if tname not in NO_INTERCEPT_FUNCTIONS:
354379
if plat_define:
355380
itable_members.append(f'#if defined({plat_define})')
356381

357382
itable_members.append(f' ENTRY({tname}),')
358383
if plat_define:
359384
itable_members.append('#endif')
360385

361-
if tname not in INTERCEPT_WITHOUT_FORWARD:
386+
if tname not in NO_DISPATCH_FUNCTIONS:
362387
if plat_define:
363388
dispatch_table_members.append(f'#if defined({plat_define})')
364389
dispatch_table_inits.append(f'#if defined({plat_define})')
@@ -457,7 +482,7 @@ def generate_layer_instance_layer_decls(file, mapping, commands):
457482
file.write('\n')
458483

459484

460-
def generate_layer_instance_layer_defs(file, mapping, commands, manual_commands):
485+
def generate_layer_instance_layer_defs(file, mapping, commands):
461486

462487
# Write the copyright header to the file
463488
write_copyright_header(file)
@@ -470,6 +495,13 @@ def generate_layer_instance_layer_defs(file, mapping, commands, manual_commands)
470495
if command.dispatch_type != 'instance':
471496
continue
472497

498+
tname = command.name
499+
if tname in NO_INTERCEPT_FUNCTIONS:
500+
continue
501+
502+
if tname in CUSTOM_FUNCTIONS:
503+
continue
504+
473505
plat_define = mapping.get_platform_define(command.name)
474506
if plat_define:
475507
lines.append(f'#if defined({plat_define})\n')
@@ -492,16 +524,13 @@ def generate_layer_instance_layer_defs(file, mapping, commands, manual_commands)
492524
lines.append(') {')
493525
lines.append(' LAYER_TRACE(__func__);\n')
494526

495-
if command.name in manual_commands:
496-
lines.append(manual_commands[command.name])
497-
else:
498-
lines.append(' // Hold the lock to access layer-wide global store')
499-
lines.append(' std::unique_lock<std::mutex> lock { g_vulkanLock };')
500-
lines.append(f' auto* layer = Instance::retrieve({dispatch});\n')
527+
lines.append(' // Hold the lock to access layer-wide global store')
528+
lines.append(' std::unique_lock<std::mutex> lock { g_vulkanLock };')
529+
lines.append(f' auto* layer = Instance::retrieve({dispatch});\n')
501530

502-
lines.append(' // Release the lock to call into the driver')
503-
lines.append(' lock.unlock();')
504-
lines.append(f' {retfwd}layer->driver.{command.name}({parmfwd});')
531+
lines.append(' // Release the lock to call into the driver')
532+
lines.append(' lock.unlock();')
533+
lines.append(f' {retfwd}layer->driver.{command.name}({parmfwd});')
505534

506535
lines.append('}\n')
507536

@@ -527,9 +556,12 @@ def generate_layer_device_dispatch_table(file, mapping, commands):
527556
if command.dispatch_type != 'device':
528557
continue
529558

559+
tname = command.name
560+
if tname in NO_INTERCEPT_OR_DISPATCH_FUNCTIONS:
561+
continue
562+
530563
plat_define = mapping.get_platform_define(command.name)
531564
ttype = f'PFN_{command.name}'
532-
tname = command.name
533565

534566
if plat_define:
535567
itable_members.append(f'#if defined({plat_define})')
@@ -613,7 +645,7 @@ def generate_layer_device_layer_decls(file, mapping, commands):
613645
file.write('\n')
614646

615647

616-
def generate_layer_device_layer_defs(file, mapping, commands, manual_commands):
648+
def generate_layer_device_layer_defs(file, mapping, commands):
617649

618650
# Write the copyright header to the file
619651
write_copyright_header(file)
@@ -626,6 +658,10 @@ def generate_layer_device_layer_defs(file, mapping, commands, manual_commands):
626658
if command.dispatch_type != 'device':
627659
continue
628660

661+
tname = command.name
662+
if tname in CUSTOM_FUNCTIONS:
663+
continue
664+
629665
plat_define = mapping.get_platform_define(command.name)
630666
if plat_define:
631667
lines.append(f'#if defined({plat_define})\n')
@@ -649,16 +685,13 @@ def generate_layer_device_layer_defs(file, mapping, commands, manual_commands):
649685
lines.append(') {')
650686
lines.append(' LAYER_TRACE(__func__);\n')
651687

652-
if command.name in manual_commands:
653-
lines.append(manual_commands[command.name])
654-
else:
655-
lines.append(' // Hold the lock to access layer-wide global store')
656-
lines.append(' std::unique_lock<std::mutex> lock { g_vulkanLock };')
657-
lines.append(f' auto* layer = Device::retrieve({dispatch});\n')
688+
lines.append(' // Hold the lock to access layer-wide global store')
689+
lines.append(' std::unique_lock<std::mutex> lock { g_vulkanLock };')
690+
lines.append(f' auto* layer = Device::retrieve({dispatch});\n')
658691

659-
lines.append(' // Release the lock to call into the driver')
660-
lines.append(' lock.unlock();')
661-
lines.append(f' {retfwd}layer->driver.{command.name}({parmfwd});')
692+
lines.append(' // Release the lock to call into the driver')
693+
lines.append(' lock.unlock();')
694+
lines.append(f' {retfwd}layer->driver.{command.name}({parmfwd});')
662695

663696
lines.append('}\n')
664697

@@ -669,23 +702,6 @@ def generate_layer_device_layer_defs(file, mapping, commands, manual_commands):
669702
file.write(data)
670703

671704

672-
def load_handwritten_commands():
673-
'''
674-
Load the small number of hand-written functions from template files.
675-
'''
676-
script_dir = os.path.dirname(__file__)
677-
template_dir = os.path.join(script_dir, 'vk_codegen')
678-
pattern = re.compile(r'^function_(.*)\.txt$')
679-
680-
commands = {}
681-
for path in os.listdir(template_dir):
682-
match = pattern.match(path)
683-
if match:
684-
commands[match.group(1)] = load_template(path)
685-
686-
return commands
687-
688-
689705
def copy_resource(src_dir, out_dir):
690706
out_dir = os.path.abspath(out_dir)
691707
os.makedirs(out_dir, exist_ok=True)
@@ -738,9 +754,6 @@ def main():
738754
# Sort functions into alphabetical order
739755
commands.sort(key=lambda x: x.name)
740756

741-
# Load hand written function bodies
742-
manual_commands = load_handwritten_commands()
743-
744757
# Generate dynamic resources
745758
outfile = os.path.join(outdir, 'instance_dispatch_table.hpp')
746759
with open(outfile, 'w', encoding='utf-8', newline='\n') as handle:
@@ -756,15 +769,15 @@ def main():
756769

757770
outfile = os.path.join(outdir, 'instance_functions.cpp')
758771
with open(outfile, 'w', encoding='utf-8', newline='\n') as handle:
759-
generate_layer_instance_layer_defs(handle, mapping, commands, manual_commands)
772+
generate_layer_instance_layer_defs(handle, mapping, commands)
760773

761774
outfile = os.path.join(outdir, 'device_functions.hpp')
762775
with open(outfile, 'w', encoding='utf-8', newline='\n') as handle:
763776
generate_layer_device_layer_decls(handle, mapping, commands)
764777

765778
outfile = os.path.join(outdir, 'device_functions.cpp')
766779
with open(outfile, 'w', encoding='utf-8', newline='\n') as handle:
767-
generate_layer_device_layer_defs(handle, mapping, commands, manual_commands)
780+
generate_layer_device_layer_defs(handle, mapping, commands)
768781

769782
return 0
770783

generator/vk_codegen/function_vkCreateDevice.txt

Lines changed: 0 additions & 30 deletions
This file was deleted.

generator/vk_codegen/function_vkCreateInstance.txt

Lines changed: 0 additions & 56 deletions
This file was deleted.

generator/vk_codegen/function_vkDestroyDevice.txt

Lines changed: 0 additions & 11 deletions
This file was deleted.

generator/vk_codegen/function_vkDestroyInstance.txt

Lines changed: 0 additions & 11 deletions
This file was deleted.

0 commit comments

Comments
 (0)