@@ -508,40 +508,112 @@ def generate_instance_decls(
508508 if plat_define :
509509 lines .append (f'#if defined({ plat_define } )\n ' )
510510
511- # Declare the default implementation
511+ # Explicitly delete the generic primary template
512512 lines .append ('/* See Vulkan API for documentation. */' )
513- lines .append ('/* Default common code pass-through implementation. */' )
514- decl = f'VKAPI_ATTR { command .rtype } ' \
515- f'VKAPI_CALL layer_{ command .name } _default('
513+ lines .append ('/* Delete the generic match-all */' )
514+ decl = f'template <typename T>\n ' \
515+ f'VKAPI_ATTR { command .rtype } ' \
516+ f'VKAPI_CALL layer_{ command .name } ('
516517 lines .append (decl )
517518
518519 for i , (ptype , pname , array ) in enumerate (command .params ):
519520 ending = ','
520521 if i == len (command .params ) - 1 :
521- ending = ');'
522+ ending = ') = delete ;'
522523 parl = f' { ptype } { pname } { array } { ending } '
523524 lines .append (parl )
524525 lines .append ('' )
525526
526- # Define the default tag dispatch handler
527- lines .append ('/* Match-all template to use default implementation. */' )
528- decl = 'template <typename T>'
529- lines . append ( decl )
530- decl = f'VKAPI_ATTR { command . rtype } VKAPI_CALL layer_{ command .name } ('
527+ # Define the default_tag template
528+ lines .append ('/* Default common code implementation. */' )
529+ decl = f 'template <> \n ' \
530+ f'VKAPI_ATTR { command . rtype } ' \
531+ f' VKAPI_CALL layer_{ command .name } <default_tag> ('
531532 lines .append (decl )
532533
533534 for i , (ptype , pname , array ) in enumerate (command .params ):
534535 ending = ','
535536 if i == len (command .params ) - 1 :
536- ending = ''
537+ ending = '); '
537538 parl = f' { ptype } { pname } { array } { ending } '
538539 lines .append (parl )
540+ lines .append ('' )
539541
540- parmfwd = ', ' .join ([x [1 ] for x in command .params ])
541- retfwd = 'return ' if command .rtype != 'void' else ''
542- lines .append (') {' )
543- lines .append (f' { retfwd } layer_{ command .name } _default({ parmfwd } );' )
544- lines .append ('}\n ' )
542+ if plat_define :
543+ lines .append ('#endif\n ' )
544+
545+ file .write ('\n ' .join (lines ))
546+ file .write ('\n ' )
547+
548+ file .write ('// clang-format on\n ' )
549+
550+
551+ def generate_instance_queries (
552+ file : TextIO , mapping : VersionInfo , commands : list [Command ]) -> None :
553+ '''
554+ Generate the instance intercept declarations header.
555+
556+ Args:
557+ file: The file to write.
558+ mapping: The version mapping information for the commands.
559+ commands: The list of commands read from the spec.
560+ '''
561+ # Write the copyright header to the file
562+ write_copyright_header (file )
563+
564+ file .write ('#pragma once\n ' )
565+ file .write ('\n ' )
566+
567+ file .write ('// clang-format off\n ' )
568+ file .write ('\n ' )
569+
570+ file .write ('#include <vulkan/vulkan.h>\n ' )
571+ file .write ('\n ' )
572+
573+ # Create a listing of API versions and API extensions
574+ for command in commands :
575+ if command .dispatch_type != 'instance' :
576+ continue
577+
578+ lines = []
579+ assert command .name
580+
581+ plat_define = mapping .get_platform_define (command .name )
582+ if plat_define :
583+ lines .append (f'#if defined({ plat_define } )\n ' )
584+
585+ # Define the concept to test if user_tag specialization exists
586+ plist = []
587+ nlist = []
588+ for i , (ptype , pname , array ) in enumerate (command .params ):
589+ plist .append (f'{ ptype } { pname } { array } ' )
590+ nlist .append (pname )
591+ plistStr = ', ' .join (plist )
592+ nlistStr = ', ' .join (nlist )
593+
594+ lines .append ('/* Test for user_tag availability. */' )
595+ decl = f'template <typename T>\n ' \
596+ f'concept hasLayerPtr_{ command .name } = ' \
597+ f'requires(\n { plistStr } \n ) {{\n layer_{ command .name } <T>({ nlistStr } );\n }};'
598+ lines .append (decl )
599+ lines .append ('' )
600+
601+ # Define the function pointer resolution
602+ lines .append ('/* Function pointer resolution. */' )
603+ decl = f'constexpr PFN_{ command .name } getLayerPtr_{ command .name } ()\n ' \
604+ f'{{\n ' \
605+ f' return [] <typename T>\n ' \
606+ f' {{\n ' \
607+ f' if constexpr(hasLayerPtr_{ command .name } <T>)\n ' \
608+ f' {{\n ' \
609+ f' return layer_{ command .name } <T>;\n ' \
610+ f' }}\n ' \
611+ f'\n ' \
612+ f' return layer_{ command .name } <default_tag>;\n ' \
613+ f' }}.operator()<user_tag>();\n ' \
614+ f'}}'
615+ lines .append (decl )
616+ lines .append ('' )
545617
546618 if plat_define :
547619 lines .append ('#endif\n ' )
@@ -582,8 +654,9 @@ def generate_instance_defs(
582654 lines .append (f'#if defined({ plat_define } )\n ' )
583655
584656 lines .append ('/* See Vulkan API for documentation. */' )
585- decl = f'VKAPI_ATTR { command .rtype } ' \
586- f'VKAPI_CALL layer_{ command .name } _default('
657+ decl = f'template <>\n ' \
658+ f'VKAPI_ATTR { command .rtype } ' \
659+ f'VKAPI_CALL layer_{ command .name } <default_tag>('
587660 lines .append (decl )
588661
589662 for i , (ptype , pname , array ) in enumerate (command .params ):
@@ -691,7 +764,8 @@ def generate_device_decls(
691764 file .write ('// clang-format off\n ' )
692765 file .write ('\n ' )
693766
694- file .write ('#include <vulkan/vulkan.h>\n ' )
767+ file .write ('#include <vulkan/vulkan.h>\n \n ' )
768+ file .write ('#include "framework/utils.hpp"\n ' )
695769 file .write ('\n ' )
696770
697771 # Create a listing of API versions and API extensions
@@ -706,39 +780,36 @@ def generate_device_decls(
706780 if plat_define :
707781 lines .append (f'#if defined({ plat_define } )\n ' )
708782
783+ # Explicitly delete the generic primary template
709784 lines .append ('/* See Vulkan API for documentation. */' )
710- lines .append ('/* Default common code pass-through implementation. */' )
711- decl = f'VKAPI_ATTR { command .rtype } ' \
712- f'VKAPI_CALL layer_{ command .name } _default('
785+ lines .append ('/* Delete the generic match-all */' )
786+ decl = f'template <typename T>\n ' \
787+ f'VKAPI_ATTR { command .rtype } ' \
788+ f'VKAPI_CALL layer_{ command .name } ('
713789 lines .append (decl )
714790
715791 for i , (ptype , pname , array ) in enumerate (command .params ):
716792 ending = ','
717793 if i == len (command .params ) - 1 :
718- ending = ');'
794+ ending = ') = delete ;'
719795 parl = f' { ptype } { pname } { array } { ending } '
720796 lines .append (parl )
721797 lines .append ('' )
722798
723- # Define the default tag dispatch handler
724- lines .append ('/* Match-all template to use default implementation. */' )
725- decl = 'template <typename T>'
726- lines . append ( decl )
727- decl = f'VKAPI_ATTR { command . rtype } VKAPI_CALL layer_{ command .name } ('
799+ # Define the default_tag template
800+ lines .append ('/* Default common code implementation. */' )
801+ decl = f 'template <> \n ' \
802+ f'VKAPI_ATTR { command . rtype } ' \
803+ f' VKAPI_CALL layer_{ command .name } <default_tag> ('
728804 lines .append (decl )
729805
730806 for i , (ptype , pname , array ) in enumerate (command .params ):
731807 ending = ','
732808 if i == len (command .params ) - 1 :
733- ending = ''
809+ ending = '); '
734810 parl = f' { ptype } { pname } { array } { ending } '
735811 lines .append (parl )
736-
737- parmfwd = ', ' .join ([x [1 ] for x in command .params ])
738- retfwd = 'return ' if command .rtype != 'void' else ''
739- lines .append (') {' )
740- lines .append (f' { retfwd } layer_{ command .name } _default({ parmfwd } );' )
741- lines .append ('}\n ' )
812+ lines .append ('' )
742813
743814 if plat_define :
744815 lines .append ('#endif\n ' )
@@ -779,9 +850,9 @@ def generate_device_defs(
779850 lines .append (f'#if defined({ plat_define } )\n ' )
780851
781852 lines .append ('/* See Vulkan API for documentation. */' )
782-
783- decl = f'VKAPI_ATTR { command .rtype } ' \
784- f'VKAPI_CALL layer_{ command .name } _default ('
853+ decl = f'template <> \n ' \
854+ f'VKAPI_ATTR { command .rtype } ' \
855+ f'VKAPI_CALL layer_{ command .name } <default_tag> ('
785856 lines .append (decl )
786857
787858 for i , (ptype , pname , array ) in enumerate (command .params ):
@@ -815,6 +886,84 @@ def generate_device_defs(
815886 file .write (data )
816887
817888
889+ def generate_device_queries (
890+ file : TextIO , mapping : VersionInfo , commands : list [Command ]) -> None :
891+ '''
892+ Generate the device intercept queries header.
893+
894+ Args:
895+ file: The file to write.
896+ mapping: The version mapping information for the commands.
897+ commands: The list of commands read from the spec.
898+ '''
899+
900+ # Write the copyright header to the file
901+ write_copyright_header (file )
902+
903+ file .write ('#pragma once\n ' )
904+ file .write ('\n ' )
905+
906+ file .write ('// clang-format off\n ' )
907+ file .write ('\n ' )
908+
909+ file .write ('#include <vulkan/vulkan.h>\n \n ' )
910+ file .write ('#include "framework/utils.hpp"\n ' )
911+ file .write ('\n ' )
912+
913+ # Create a listing of API versions and API extensions
914+ for command in commands :
915+ if command .dispatch_type != 'device' :
916+ continue
917+
918+ assert command .name
919+
920+ lines = []
921+ plat_define = mapping .get_platform_define (command .name )
922+ if plat_define :
923+ lines .append (f'#if defined({ plat_define } )\n ' )
924+
925+ # Define the concept to test if user_tag specialization exists
926+ plist = []
927+ nlist = []
928+ for i , (ptype , pname , array ) in enumerate (command .params ):
929+ plist .append (f'{ ptype } { pname } { array } ' )
930+ nlist .append (pname )
931+ plistStr = ', ' .join (plist )
932+ nlistStr = ', ' .join (nlist )
933+
934+ lines .append ('/* Test for user_tag availability. */' )
935+ decl = f'template <typename T>\n ' \
936+ f'concept hasLayerPtr_{ command .name } = ' \
937+ f'requires(\n { plistStr } \n ) {{\n layer_{ command .name } <T>({ nlistStr } );\n }};'
938+ lines .append (decl )
939+ lines .append ('' )
940+
941+ # Define the function pointer resolution
942+ lines .append ('/* Function pointer resolution. */' )
943+ decl = f'constexpr PFN_{ command .name } getLayerPtr_{ command .name } ()\n ' \
944+ f'{{\n ' \
945+ f' return [] <typename T>\n ' \
946+ f' {{\n ' \
947+ f' if constexpr(hasLayerPtr_{ command .name } <T>)\n ' \
948+ f' {{\n ' \
949+ f' return layer_{ command .name } <T>;\n ' \
950+ f' }}\n ' \
951+ f'\n ' \
952+ f' return layer_{ command .name } <default_tag>;\n ' \
953+ f' }}.operator()<user_tag>();\n ' \
954+ f'}}'
955+ lines .append (decl )
956+ lines .append ('' )
957+
958+ if plat_define :
959+ lines .append ('#endif\n ' )
960+
961+ file .write ('\n ' .join (lines ))
962+ file .write ('\n ' )
963+
964+ file .write ('// clang-format on\n ' )
965+
966+
818967def main () -> int :
819968 '''
820969 Tool main function.
@@ -867,6 +1016,10 @@ def main() -> int:
8671016 with open (outfile , 'w' , encoding = 'utf-8' , newline = '\n ' ) as handle :
8681017 generate_instance_decls (handle , mapping , commands )
8691018
1019+ outfile = os .path .join (outdir , 'instance_functions_query.hpp' )
1020+ with open (outfile , 'w' , encoding = 'utf-8' , newline = '\n ' ) as handle :
1021+ generate_instance_queries (handle , mapping , commands )
1022+
8701023 outfile = os .path .join (outdir , 'instance_functions.cpp' )
8711024 with open (outfile , 'w' , encoding = 'utf-8' , newline = '\n ' ) as handle :
8721025 generate_instance_defs (handle , mapping , commands )
@@ -879,6 +1032,10 @@ def main() -> int:
8791032 with open (outfile , 'w' , encoding = 'utf-8' , newline = '\n ' ) as handle :
8801033 generate_device_decls (handle , mapping , commands )
8811034
1035+ outfile = os .path .join (outdir , 'device_functions_query.hpp' )
1036+ with open (outfile , 'w' , encoding = 'utf-8' , newline = '\n ' ) as handle :
1037+ generate_device_queries (handle , mapping , commands )
1038+
8821039 outfile = os .path .join (outdir , 'device_functions.cpp' )
8831040 with open (outfile , 'w' , encoding = 'utf-8' , newline = '\n ' ) as handle :
8841041 generate_device_defs (handle , mapping , commands )
0 commit comments