Skip to content

Commit 984d775

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 8b51c4b commit 984d775

File tree

9 files changed

+303
-5
lines changed

9 files changed

+303
-5
lines changed

cmake/DaemonVulkan.cmake

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ include( DaemonEmbed )
5757
macro( GenerateVulkanShaders target )
5858
# Pre-processing for #insert/#include
5959
foreach( src IN LISTS graphicsEngineList )
60-
set( graphicsProcessedList ${graphicsProcessedList} ${src} )
60+
set( graphicsEngineProcessedList ${graphicsEngineProcessedList} ${src} )
6161
list( APPEND graphicsEngineOutputList ${GRAPHICS_ENGINE_PROCESSED_PATH}processed/${src} )
6262

6363
get_filename_component( name "${src}" NAME_WE )
@@ -104,10 +104,10 @@ macro( GenerateVulkanShaders target )
104104
endif()
105105

106106
add_custom_command(
107-
COMMAND VulkanShaderParser \"${glslangV} ${spirvOptions}\" ${spirvOut} ${graphicsProcessedList}
107+
COMMAND VulkanShaderParser \"${glslangV} ${spirvOptions}\" ${spirvOut} ${graphicsEngineProcessedList}
108108
DEPENDS ${graphicsEngineIDEList}
109109
OUTPUT ${graphicsEngineOutputList}
110-
COMMENT "Generating Vulkan Graphics Engine: ${graphicsProcessedList}"
110+
COMMENT "Generating Vulkan Graphics Engine: ${graphicsEngineProcessedList}"
111111
)
112112

113113
add_custom_target( VulkanShaderParserTarget ALL

libs/VulkanHeaders/GenerateAll.py

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# ===========================================================================
2+
#
3+
# Daemon BSD Source Code
4+
# Copyright (c) 2025 Daemon Developers
5+
# All rights reserved.
6+
#
7+
# This file is part of the Daemon BSD Source Code (Daemon Source Code).
8+
#
9+
# Redistribution and use in source and binary forms, with or without
10+
# modification, are permitted provided that the following conditions are met:
11+
# * Redistributions of source code must retain the above copyright
12+
# notice, this list of conditions and the following disclaimer.
13+
# * Redistributions in binary form must reproduce the above copyright
14+
# notice, this list of conditions and the following disclaimer in the
15+
# documentation and/or other materials provided with the distribution.
16+
# * Neither the name of the Daemon developers nor the
17+
# names of its contributors may be used to endorse or promote products
18+
# derived from this software without specific prior written permission.
19+
#
20+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21+
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22+
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23+
# DISCLAIMED. IN NO EVENT SHALL DAEMON DEVELOPERS BE LIABLE FOR ANY
24+
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25+
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26+
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27+
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28+
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29+
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30+
#
31+
# ===========================================================================
32+
33+
from os import system, remove
34+
from sys import executable
35+
from subprocess import run
36+
37+
headers = [
38+
( "vulkan_core", "w", "" ),
39+
( "vulkan_beta", "a", "VK_ENABLE_BETA_EXTENSIONS" ),
40+
( "vulkan_win32", "a", "VK_USE_PLATFORM_WIN32_KHR" ),
41+
( "vulkan_wayland", "a", "VK_USE_PLATFORM_WAYLAND_KHR" ),
42+
( "vulkan_xlib", "a", "VK_USE_PLATFORM_XLIB_KHR" ),
43+
( "vulkan_xlib_xrandr", "a", "VK_USE_PLATFORM_XLIB_XRANDR_EXT" )
44+
]
45+
46+
with open( "FunctionDecls.h", "w" ) as f:
47+
with open( "FunctionLoaderInstance.cpp", "w" ) as f1:
48+
with open( "FunctionLoaderDevice.cpp", "w" ) as f2:
49+
print( "" )
50+
51+
vulkanLoaderPath = "../../src/engine/renderer-vulkan/VulkanLoader/"
52+
53+
for header in headers:
54+
if header[2]:
55+
run( [executable, "genvk.py", "-o", vulkanLoaderPath + "vulkan/", "-apiname", "vulkan", "-mode", header[1],
56+
"-define", header[2], header[0] + ".h"], check = True )
57+
else:
58+
run( [executable, "genvk.py", "-o", vulkanLoaderPath + "vulkan/", "-apiname", "vulkan", "-mode", header[1],
59+
header[0] + ".h"], check = True )
60+
61+
with open( "FunctionDecls.h", "r" ) as inp:
62+
with open( vulkanLoaderPath + "Vulkan.h", "w" ) as out:
63+
out.write( inp.read() )
64+
out.write( '#endif // VULKAN_LOADER_H' )
65+
66+
with open( 'VulkanLoadFunctions.cpp', mode = 'r', encoding = 'utf-8', newline = '\n' ) as inp:
67+
functionLoadStart = inp.read()
68+
69+
with open( "FunctionLoaderInstance.cpp", "r" ) as inp:
70+
with open( "FunctionLoaderDevice.cpp", "r" ) as inp2:
71+
with open( vulkanLoaderPath + "VulkanLoadFunctions.cpp", "w" ) as out:
72+
out.write( functionLoadStart )
73+
out.write( '\n\nvoid VulkanLoadInstanceFunctions( VkInstance instance ) {\n' )
74+
out.write( inp.read() )
75+
out.write( '}\n\n' )
76+
out.write( 'void VulkanLoadDeviceFunctions( VkDevice device ) {\n' )
77+
out.write( inp2.read() )
78+
out.write( '}' )
79+
80+
remove( "FunctionDecls.h" )
81+
remove( "FunctionLoaderInstance.cpp" )
82+
remove( "FunctionLoaderDevice.cpp" )

libs/VulkanHeaders/Globals.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# ===========================================================================
2+
#
3+
# Daemon BSD Source Code
4+
# Copyright (c) 2025 Daemon Developers
5+
# All rights reserved.
6+
#
7+
# This file is part of the Daemon BSD Source Code (Daemon Source Code).
8+
#
9+
# Redistribution and use in source and binary forms, with or without
10+
# modification, are permitted provided that the following conditions are met:
11+
# * Redistributions of source code must retain the above copyright
12+
# notice, this list of conditions and the following disclaimer.
13+
# * Redistributions in binary form must reproduce the above copyright
14+
# notice, this list of conditions and the following disclaimer in the
15+
# documentation and/or other materials provided with the distribution.
16+
# * Neither the name of the Daemon developers nor the
17+
# names of its contributors may be used to endorse or promote products
18+
# derived from this software without specific prior written permission.
19+
#
20+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21+
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22+
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23+
# DISCLAIMED. IN NO EVENT SHALL DAEMON DEVELOPERS BE LIABLE FOR ANY
24+
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25+
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26+
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27+
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28+
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29+
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30+
#
31+
# ===========================================================================
32+
33+
def init():
34+
global headerText
35+
global functionDefinitionsText
36+
37+
global functionLoadInstanceText
38+
global functionLoadDeviceText
39+
40+
headerText = ''
41+
functionDefinitionsText = ''
42+
43+
functionLoadInstanceText = ''
44+
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.removesuffix( 'vk.xml' ), args.directory, args.mode, args.define )
11571165
endTimer(args.time, f"* Time to generate {options.filename} =")
11581166

11591167
if not args.quiet:

0 commit comments

Comments
 (0)