@@ -508,40 +508,104 @@ 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+ lines .append ('/* Test for user_tag availability. */' )
587+ decl = f'template <typename T>\n ' \
588+ f'concept hasLayerPtr_{ command .name } = ' \
589+ f'requires {{ layer_{ command .name } <user_tag>; }};'
590+ lines .append (decl )
591+ lines .append ('' )
592+
593+ # Define the function pointer resolution
594+ lines .append ('/* Function pointer resolution. */' )
595+ decl = f'constexpr PFN_{ command .name } getLayerPtr_{ command .name } ()\n ' \
596+ f'{{\n ' \
597+ f' return [] <typename T>\n ' \
598+ f' {{\n ' \
599+ f' if constexpr(hasLayerPtr_{ command .name } <T>)\n ' \
600+ f' {{\n ' \
601+ f' return layer_{ command .name } <T>;\n ' \
602+ f' }}\n ' \
603+ f'\n ' \
604+ f' return layer_{ command .name } <default_tag>;\n ' \
605+ f' }}.operator()<user_tag>();\n ' \
606+ f'}}'
607+ lines .append (decl )
608+ lines .append ('' )
545609
546610 if plat_define :
547611 lines .append ('#endif\n ' )
@@ -582,8 +646,9 @@ def generate_instance_defs(
582646 lines .append (f'#if defined({ plat_define } )\n ' )
583647
584648 lines .append ('/* See Vulkan API for documentation. */' )
585- decl = f'VKAPI_ATTR { command .rtype } ' \
586- f'VKAPI_CALL layer_{ command .name } _default('
649+ decl = f'template <>\n ' \
650+ f'VKAPI_ATTR { command .rtype } ' \
651+ f'VKAPI_CALL layer_{ command .name } <default_tag>('
587652 lines .append (decl )
588653
589654 for i , (ptype , pname , array ) in enumerate (command .params ):
@@ -691,7 +756,8 @@ def generate_device_decls(
691756 file .write ('// clang-format off\n ' )
692757 file .write ('\n ' )
693758
694- file .write ('#include <vulkan/vulkan.h>\n ' )
759+ file .write ('#include <vulkan/vulkan.h>\n \n ' )
760+ file .write ('#include "framework/utils.hpp"\n ' )
695761 file .write ('\n ' )
696762
697763 # Create a listing of API versions and API extensions
@@ -706,39 +772,36 @@ def generate_device_decls(
706772 if plat_define :
707773 lines .append (f'#if defined({ plat_define } )\n ' )
708774
775+ # Explicitly delete the generic primary template
709776 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('
777+ lines .append ('/* Delete the generic match-all */' )
778+ decl = f'template <typename T>\n ' \
779+ f'VKAPI_ATTR { command .rtype } ' \
780+ f'VKAPI_CALL layer_{ command .name } ('
713781 lines .append (decl )
714782
715783 for i , (ptype , pname , array ) in enumerate (command .params ):
716784 ending = ','
717785 if i == len (command .params ) - 1 :
718- ending = ');'
786+ ending = ') = delete ;'
719787 parl = f' { ptype } { pname } { array } { ending } '
720788 lines .append (parl )
721789 lines .append ('' )
722790
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 } ('
791+ # Define the default_tag template
792+ lines .append ('/* Default common code implementation. */' )
793+ decl = f 'template <> \n ' \
794+ f'VKAPI_ATTR { command . rtype } ' \
795+ f' VKAPI_CALL layer_{ command .name } <default_tag> ('
728796 lines .append (decl )
729797
730798 for i , (ptype , pname , array ) in enumerate (command .params ):
731799 ending = ','
732800 if i == len (command .params ) - 1 :
733- ending = ''
801+ ending = '); '
734802 parl = f' { ptype } { pname } { array } { ending } '
735803 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 ' )
804+ lines .append ('' )
742805
743806 if plat_define :
744807 lines .append ('#endif\n ' )
@@ -779,9 +842,9 @@ def generate_device_defs(
779842 lines .append (f'#if defined({ plat_define } )\n ' )
780843
781844 lines .append ('/* See Vulkan API for documentation. */' )
782-
783- decl = f'VKAPI_ATTR { command .rtype } ' \
784- f'VKAPI_CALL layer_{ command .name } _default ('
845+ decl = f'template <> \n ' \
846+ f'VKAPI_ATTR { command .rtype } ' \
847+ f'VKAPI_CALL layer_{ command .name } <default_tag> ('
785848 lines .append (decl )
786849
787850 for i , (ptype , pname , array ) in enumerate (command .params ):
@@ -815,6 +878,76 @@ def generate_device_defs(
815878 file .write (data )
816879
817880
881+ def generate_device_queries (
882+ file : TextIO , mapping : VersionInfo , commands : list [Command ]) -> None :
883+ '''
884+ Generate the device intercept queries header.
885+
886+ Args:
887+ file: The file to write.
888+ mapping: The version mapping information for the commands.
889+ commands: The list of commands read from the spec.
890+ '''
891+
892+ # Write the copyright header to the file
893+ write_copyright_header (file )
894+
895+ file .write ('#pragma once\n ' )
896+ file .write ('\n ' )
897+
898+ file .write ('// clang-format off\n ' )
899+ file .write ('\n ' )
900+
901+ file .write ('#include <vulkan/vulkan.h>\n \n ' )
902+ file .write ('#include "framework/utils.hpp"\n ' )
903+ file .write ('\n ' )
904+
905+ # Create a listing of API versions and API extensions
906+ for command in commands :
907+ if command .dispatch_type != 'device' :
908+ continue
909+
910+ assert command .name
911+
912+ lines = []
913+ plat_define = mapping .get_platform_define (command .name )
914+ if plat_define :
915+ lines .append (f'#if defined({ plat_define } )\n ' )
916+
917+ # Define the concept to test if user_tag specialization exists
918+ lines .append ('/* Test for user_tag availability. */' )
919+ decl = f'template <typename T>\n ' \
920+ f'concept hasLayerPtr_{ command .name } = ' \
921+ f'requires {{ layer_{ command .name } <user_tag>; }};'
922+ lines .append (decl )
923+ lines .append ('' )
924+
925+ # Define the function pointer resolution
926+ lines .append ('/* Function pointer resolution. */' )
927+ decl = f'constexpr PFN_{ command .name } getLayerPtr_{ command .name } ()\n ' \
928+ f'{{\n ' \
929+ f' return [] <typename T>\n ' \
930+ f' {{\n ' \
931+ f' if constexpr(hasLayerPtr_{ command .name } <T>)\n ' \
932+ f' {{\n ' \
933+ f' return layer_{ command .name } <T>;\n ' \
934+ f' }}\n ' \
935+ f'\n ' \
936+ f' return layer_{ command .name } <default_tag>;\n ' \
937+ f' }}.operator()<user_tag>();\n ' \
938+ f'}}'
939+ lines .append (decl )
940+ lines .append ('' )
941+
942+ if plat_define :
943+ lines .append ('#endif\n ' )
944+
945+ file .write ('\n ' .join (lines ))
946+ file .write ('\n ' )
947+
948+ file .write ('// clang-format on\n ' )
949+
950+
818951def main () -> int :
819952 '''
820953 Tool main function.
@@ -867,6 +1000,10 @@ def main() -> int:
8671000 with open (outfile , 'w' , encoding = 'utf-8' , newline = '\n ' ) as handle :
8681001 generate_instance_decls (handle , mapping , commands )
8691002
1003+ outfile = os .path .join (outdir , 'instance_functions_query.hpp' )
1004+ with open (outfile , 'w' , encoding = 'utf-8' , newline = '\n ' ) as handle :
1005+ generate_instance_queries (handle , mapping , commands )
1006+
8701007 outfile = os .path .join (outdir , 'instance_functions.cpp' )
8711008 with open (outfile , 'w' , encoding = 'utf-8' , newline = '\n ' ) as handle :
8721009 generate_instance_defs (handle , mapping , commands )
@@ -879,6 +1016,10 @@ def main() -> int:
8791016 with open (outfile , 'w' , encoding = 'utf-8' , newline = '\n ' ) as handle :
8801017 generate_device_decls (handle , mapping , commands )
8811018
1019+ outfile = os .path .join (outdir , 'device_functions_query.hpp' )
1020+ with open (outfile , 'w' , encoding = 'utf-8' , newline = '\n ' ) as handle :
1021+ generate_device_queries (handle , mapping , commands )
1022+
8821023 outfile = os .path .join (outdir , 'device_functions.cpp' )
8831024 with open (outfile , 'w' , encoding = 'utf-8' , newline = '\n ' ) as handle :
8841025 generate_device_defs (handle , mapping , commands )
0 commit comments