Skip to content

Commit 21f9e08

Browse files
committed
VulkanHeaders: generate sType as const with default value
Also add a script to generate all the headers we need along with function loading.
1 parent 812705e commit 21f9e08

File tree

8 files changed

+233
-2
lines changed

8 files changed

+233
-2
lines changed

libs/VulkanHeaders/GenerateAll.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
from os import system, remove
2+
3+
headers = [
4+
( "vulkan_core", "w", "" ),
5+
( "vulkan_beta", "a", "VK_ENABLE_BETA_EXTENSIONS" ),
6+
( "vulkan_win32", "a", "VK_USE_PLATFORM_WIN32_KHR" ),
7+
( "vulkan_wayland", "a", "VK_USE_PLATFORM_WAYLAND_KHR" ),
8+
( "vulkan_xlib", "a", "VK_USE_PLATFORM_XLIB_KHR" ),
9+
( "vulkan_xlib_xrandr", "a", "VK_USE_PLATFORM_XLIB_XRANDR_EXT" )
10+
]
11+
12+
with open( "FunctionDecls.h", "w" ) as f:
13+
with open( "FunctionLoaderInstance.cpp", "w" ) as f1:
14+
with open( "FunctionLoaderDevice.cpp", "w" ) as f2:
15+
print( "" )
16+
17+
vulkanLoaderPath = "../../src/engine/renderer-vulkan/VulkanLoader/"
18+
19+
for header in headers:
20+
if header[2]:
21+
define = " -define " + header[2]
22+
else:
23+
define = ""
24+
system( "python genvk.py -o " + vulkanLoaderPath + "vulkan/ -apiname vulkan -mode " + header[1] + define + " " + header[0] + ".h" )
25+
26+
with open( "FunctionDecls.h", "r" ) as inp:
27+
with open( vulkanLoaderPath + "Vulkan.h", "w" ) as out:
28+
out.write( inp.read() )
29+
out.write( '#endif // VULKAN_LOADER_H' )
30+
31+
with open( 'VulkanLoadFunctions.cpp', mode = 'r', encoding = 'utf-8', newline = '\n' ) as inp:
32+
functionLoadStart = inp.read()
33+
34+
with open( "FunctionLoaderInstance.cpp", "r" ) as inp:
35+
with open( "FunctionLoaderDevice.cpp", "r" ) as inp2:
36+
with open( vulkanLoaderPath + "VulkanLoadFunctions.cpp", "w" ) as out:
37+
out.write( functionLoadStart )
38+
out.write( '\n\nvoid VulkanLoadInstanceFunctions( VkInstance instance ) {\n' )
39+
out.write( inp.read() )
40+
out.write( '}\n\n' )
41+
out.write( 'void VulkanLoadDeviceFunctions( VkDevice device ) {\n' )
42+
out.write( inp2.read() )
43+
out.write( '}' )
44+
45+
remove( "FunctionDecls.h" )
46+
remove( "FunctionLoaderInstance.cpp" )
47+
remove( "FunctionLoaderDevice.cpp" )

libs/VulkanHeaders/Globals.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
def init():
2+
global headerText
3+
global functionDefinitionsText
4+
5+
global functionLoadInstanceText
6+
global functionLoadDeviceText
7+
8+
headerText = ''
9+
functionDefinitionsText = ''
10+
11+
functionLoadInstanceText = ''
12+
functionLoadDeviceText = ''

libs/VulkanHeaders/Vulkan.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// Auto-generated, do not modify
2+
3+
#include "Vulkan.h"
4+

libs/VulkanHeaders/Vulkan.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Auto-generated, do not modify
2+
3+
#ifndef VULKAN_LOADER_H
4+
#define VULKAN_LOADER_H
5+
6+
#ifdef _MSC_VER
7+
#define VK_USE_PLATFORM_WIN32_KHR
8+
#endif
9+
10+
#define VK_ENABLE_BETA_EXTENSIONS
11+
12+
#include "vulkan/vulkan.h"
13+
#include "vulkan/vk_enum_string_helper.h"
14+
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Auto-generated, do not modify
2+
3+
#ifdef _MSC_VER
4+
#include <windows.h>
5+
#else
6+
#include <dlfcn.h>
7+
#endif
8+
9+
#include "Vulkan.h"
10+
11+
#include "VulkanLoadFunctions.h"
12+
13+
#ifdef _MSC_VER
14+
HMODULE libVulkan;
15+
#else
16+
void* libVulkan;
17+
#endif
18+
19+
void VulkanLoaderInit() {
20+
#ifdef _MSC_VER
21+
libVulkan = LoadLibrary( "vulkan-1.dll" );
22+
vkGetInstanceProcAddr = ( PFN_vkGetInstanceProcAddr ) GetProcAddress( libVulkan, "vkGetInstanceProcAddr" );
23+
#else
24+
libVulkan = dlopen( "libvulkan.so", RTLD_NOW );
25+
vkGetInstanceProcAddr = dlsym( libVulkan, "vkGetInstanceProcAddr" );
26+
#endif
27+
28+
vkEnumerateInstanceVersion = ( PFN_vkEnumerateInstanceVersion ) vkGetInstanceProcAddr( nullptr, "vkEnumerateInstanceVersion" );
29+
30+
vkEnumerateInstanceExtensionProperties = ( PFN_vkEnumerateInstanceExtensionProperties ) vkGetInstanceProcAddr( nullptr, "vkEnumerateInstanceExtensionProperties" );
31+
32+
vkEnumerateInstanceLayerProperties = ( PFN_vkEnumerateInstanceLayerProperties ) vkGetInstanceProcAddr( nullptr, "vkEnumerateInstanceLayerProperties" );
33+
34+
vkCreateInstance = ( PFN_vkCreateInstance ) vkGetInstanceProcAddr( nullptr, "vkCreateInstance" );
35+
}
36+
37+
void VulkanLoaderFree() {
38+
#ifdef _MSC_VER
39+
FreeLibrary( libVulkan );
40+
#else
41+
dlclose( libVulkan );
42+
#endif
43+
}

libs/VulkanHeaders/generator.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
from spec_tools.util import getElemName, getElemType
2323

24+
import Globals
2425

2526
def write(*args, **kwargs):
2627
file = kwargs.pop('file', sys.stdout)
@@ -1124,6 +1125,12 @@ def makeCParamDecl(self, param, aligncol):
11241125
text = noneStr(elem.text)
11251126
tail = noneStr(elem.tail)
11261127

1128+
if text.endswith( 'sType' ):
1129+
sType = param.get( 'values' )
1130+
1131+
if sType:
1132+
text += ' = ' + sType
1133+
11271134
if self.should_insert_may_alias_macro and self.genOpts.conventions.is_voidpointer_alias(elem.tag, text, tail):
11281135
# OpenXR-specific macro insertion - but not in apiinc for the spec
11291136
tail = self.genOpts.conventions.make_voidpointer_alias(tail)
@@ -1351,14 +1358,27 @@ def makeCDecls(self, cmd):
13511358
# Leading text
13521359
pdecl += noneStr(proto.text)
13531360
tdecl += noneStr(proto.text)
1361+
13541362
# For each child element, if it is a <name> wrap in appropriate
13551363
# declaration. Otherwise append its contents and tail contents.
1364+
functionName = None
1365+
deviceFunction = True
13561366
for elem in proto:
13571367
text = noneStr(elem.text)
13581368
tail = noneStr(elem.tail)
1369+
13591370
if elem.tag == 'name':
13601371
pdecl += self.makeProtoName(text, tail)
13611372
tdecl += self.makeTypedefName(text, tail)
1373+
1374+
Globals.headerText += 'extern PFN_' + text + ' ' + text + ';\n\n'
1375+
Globals.functionDefinitionsText += 'PFN_' + text + ' ' + text + ';\n\n'
1376+
1377+
if not text.endswith( ( 'vkGetInstanceProcAddr', 'vkEnumerateInstanceVersion', 'vkEnumerateInstanceExtensionProperties', 'vkEnumerateInstanceLayerProperties', 'vkCreateInstance', 'vkDestroyInstance' ) ):
1378+
functionName = text
1379+
1380+
if text == 'vkGetDeviceProcAddr':
1381+
deviceFunction = False
13621382
else:
13631383
pdecl += text + tail
13641384
tdecl += text + tail
@@ -1376,6 +1396,22 @@ def makeCDecls(self, cmd):
13761396
# self.indentFuncPointer
13771397
# self.alignFuncParam
13781398
n = len(params)
1399+
1400+
if n > 0 and functionName:
1401+
for p in params:
1402+
for elem in p:
1403+
if deviceFunction and noneStr( elem.text ).endswith( ( 'VkInstance', 'VkPhysicalDevice', 'VkPhysicalDeviceGroup' ) ):
1404+
deviceFunction = False
1405+
break
1406+
1407+
if not deviceFunction:
1408+
break
1409+
1410+
if deviceFunction:
1411+
Globals.functionLoadDeviceText += '\t' + functionName + ' = ( PFN_' + functionName + ' ) vkGetDeviceProcAddr( device, "' + functionName + '" );\n\n'
1412+
else:
1413+
Globals.functionLoadInstanceText += '\t' + functionName + ' = ( PFN_' + functionName + ' ) vkGetInstanceProcAddr( instance, "' + functionName + '" );\n\n'
1414+
13791415
# Indented parameters
13801416
if n > 0:
13811417
indentdecl = '(\n'

libs/VulkanHeaders/genvk.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1105,6 +1105,10 @@ def genTarget(args):
11051105
help='generate MISRA C++-friendly headers')
11061106
parser.add_argument('--iscts', action='store_true', dest='isCTS',
11071107
help='Specify if this should generate CTS compatible code')
1108+
parser.add_argument('-mode', action='store',
1109+
help='w - write, a - append')
1110+
parser.add_argument('-define', action='store',
1111+
help='Pe-processor define to use')
11081112

11091113
args = parser.parse_args()
11101114

@@ -1148,12 +1152,16 @@ def genTarget(args):
11481152
logDiag('* Dumping registry to regdump.txt')
11491153
reg.dumpReg(filehandle=open('regdump.txt', 'w', encoding='utf-8'))
11501154

1155+
if not args.mode in ( 'w', 'a' ):
1156+
print( 'Unknown mode: ' + args.mode + '\nAvailable modes: w, a' )
1157+
exit( -1 )
1158+
11511159
# Finally, use the output generator to create the requested target
11521160
if args.debug:
11531161
pdb.run('reg.apiGen()')
11541162
else:
11551163
startTimer(args.time)
1156-
reg.apiGen()
1164+
reg.apiGen( args.registry.rstrip( 'vk.xml' ), args.directory, args.mode, args.define )
11571165
endTimer(args.time, f"* Time to generate {options.filename} =")
11581166

11591167
if not args.quiet:

libs/VulkanHeaders/reg.py

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
from generator import GeneratorOptions, OutputGenerator, noneStr, write
1616
from apiconventions import APIConventions
1717

18+
import Globals
19+
1820
def apiNameMatch(str, supported):
1921
"""Return whether a required api name matches a pattern specified for an
2022
XML <feature> 'api' attribute or <extension> 'supported' attribute.
@@ -1656,7 +1658,7 @@ def tagValidExtensionStructs(self):
16561658
for parent in self.validextensionstructs:
16571659
self.validextensionstructs[parent].sort()
16581660

1659-
def apiGen(self):
1661+
def apiGen(self, inputDir, outputDir, mode, define):
16601662
"""Generate interface for specified versions using the current
16611663
generator and generator options"""
16621664

@@ -1844,6 +1846,18 @@ def apiGen(self):
18441846
# generated.
18451847
self.gen.logMsg('diag', 'PASS 3: GENERATE INTERFACES FOR FEATURES')
18461848
self.gen.beginFile(self.genOpts)
1849+
1850+
headerStart = ''
1851+
functionLoadStart = ''
1852+
if mode == "w":
1853+
with open( inputDir + 'Vulkan.h', mode = 'r', encoding = 'utf-8', newline = '\n' ) as inp:
1854+
headerStart = inp.read()
1855+
1856+
with open( inputDir + 'VulkanLoadFunctions.cpp', mode = 'r', encoding = 'utf-8', newline = '\n' ) as inp:
1857+
functionLoadStart = inp.read()
1858+
1859+
Globals.init()
1860+
18471861
for f in features:
18481862
self.gen.logMsg('diag', 'PASS 3: Generating interface for',
18491863
f.name)
@@ -1870,6 +1884,59 @@ def apiGen(self):
18701884
for s in self.syncpipelinedict:
18711885
self.generateSyncPipeline(self.syncpipelinedict[s])
18721886
self.gen.endFile()
1887+
1888+
outputDir = outputDir.rstrip( '/' ).rsplit( '/', 1 )[0] + '/'
1889+
1890+
indent = "\t" if define else ""
1891+
1892+
with open( 'FunctionDecls.h', mode = mode, encoding = 'utf-8', newline = '\n' ) as out:
1893+
if define:
1894+
out.write( "#if defined( " + define + " )\n" )
1895+
1896+
out.write( headerStart + indent + Globals.headerText )
1897+
1898+
if define:
1899+
out.write( "#endif\n\n" )
1900+
1901+
with open( outputDir + 'Vulkan.cpp', mode = mode, encoding = 'utf-8', newline = '\n' ) as out:
1902+
if mode == "w":
1903+
out.write( '// Auto-generated, do not modify\n\n' )
1904+
out.write( '#include "Vulkan.h"\n\n' )
1905+
1906+
if define:
1907+
out.write( "#if defined( " + define + " )\n" )
1908+
1909+
out.write( indent + Globals.functionDefinitionsText )
1910+
1911+
if define:
1912+
out.write( "#endif\n\n" )
1913+
1914+
#with open( outputDir + 'VulkanLoadFunctions.cpp', mode = mode, encoding = 'utf-8', newline = '\n' ) as out:
1915+
# out.write( functionLoadStart )
1916+
# out.write( '\n\nvoid VulkanLoadInstanceFunctions( VkInstance instance ) {\n' )
1917+
# out.write( Globals.functionLoadInstanceText )
1918+
# out.write( '}\n\n' )
1919+
# out.write( 'void VulkanLoadDeviceFunctions( VkDevice device ) {\n' )
1920+
# out.write( Globals.functionLoadDeviceText )
1921+
# out.write( '}' )
1922+
1923+
with open( 'FunctionLoaderInstance.cpp', mode = mode, encoding = 'utf-8', newline = '\n' ) as out:
1924+
if define:
1925+
out.write( "#if defined( " + define + " )\n" )
1926+
1927+
out.write( Globals.functionLoadInstanceText )
1928+
1929+
if define:
1930+
out.write( "#endif\n\n" )
1931+
1932+
with open( 'FunctionLoaderDevice.cpp', mode = mode, encoding = 'utf-8', newline = '\n' ) as out:
1933+
if define:
1934+
out.write( "#if defined( " + define + " )\n" )
1935+
1936+
out.write( Globals.functionLoadDeviceText )
1937+
1938+
if define:
1939+
out.write( "#endif\n\n" )
18731940

18741941
def apiReset(self):
18751942
"""Reset type/enum/command dictionaries before generating another API.

0 commit comments

Comments
 (0)