0
# Vulkan Support
1
2
Vulkan surface creation, instance management, and Vulkan function loading for modern low-level graphics programming.
3
4
## Capabilities
5
6
### Vulkan Availability
7
8
Check for Vulkan support and loader availability.
9
10
```python { .api }
11
def vulkan_supported() -> bool:
12
"""
13
Check whether the Vulkan loader has been found.
14
15
This function returns whether the Vulkan loader and any minimally
16
functional ICD have been found.
17
18
Returns:
19
bool: True if Vulkan is supported, False otherwise
20
"""
21
```
22
23
### Vulkan Extensions
24
25
Query required Vulkan instance extensions for presentation support.
26
27
```python { .api }
28
def get_required_instance_extensions() -> list[str]:
29
"""
30
Get the Vulkan instance extensions required by GLFW.
31
32
This function returns a list of names of Vulkan instance extensions
33
required by GLFW for creating Vulkan surfaces for GLFW windows.
34
35
Returns:
36
list[str]: List of required extension names
37
"""
38
```
39
40
### Vulkan Surface Creation
41
42
Create Vulkan surfaces for windows to enable Vulkan rendering.
43
44
```python { .api }
45
def create_window_surface(instance, window, allocator, surface) -> int:
46
"""
47
Create a Vulkan surface for the specified window.
48
49
This function creates a Vulkan surface for the specified window.
50
51
Parameters:
52
instance: Vulkan instance handle (VkInstance)
53
window: Window to create surface for
54
allocator: Allocator to use, or None (VkAllocationCallbacks*)
55
surface: Where to store the handle of the surface (VkSurfaceKHR*)
56
57
Returns:
58
int: VkResult - VK_SUCCESS if successful
59
"""
60
```
61
62
### Vulkan Physical Device Support
63
64
Check physical device presentation support for Vulkan queues.
65
66
```python { .api }
67
def get_physical_device_presentation_support(instance, device, queuefamily: int) -> int:
68
"""
69
Check whether the specified queue family supports presentation.
70
71
This function returns whether the specified queue family of the
72
specified physical device supports presentation to the platform GLFW was built for.
73
74
Parameters:
75
instance: Vulkan instance handle (VkInstance)
76
device: Physical device handle (VkPhysicalDevice)
77
queuefamily: Queue family index
78
79
Returns:
80
int: 1 if supported, 0 if not supported
81
"""
82
```
83
84
### Vulkan Function Loading
85
86
Load Vulkan functions for the current instance.
87
88
```python { .api }
89
def get_instance_proc_address(instance, procname: str) -> ctypes.c_void_p:
90
"""
91
Get the address of the specified Vulkan instance function.
92
93
This function returns the address of the specified Vulkan core or
94
extension function for the specified instance.
95
96
Parameters:
97
instance: Vulkan instance handle (VkInstance), or None for instance-independent functions
98
procname: ASCII encoded name of the function
99
100
Returns:
101
ctypes.c_void_p: Function address, or None if function is not available
102
"""
103
```
104
105
### Vulkan Loader Initialization
106
107
Configure the Vulkan loader before initialization (advanced usage).
108
109
```python { .api }
110
def init_vulkan_loader(loader) -> None:
111
"""
112
Set the desired Vulkan vkGetInstanceProcAddr function.
113
114
This function sets the vkGetInstanceProcAddr function that GLFW will use for all
115
Vulkan related entry point queries.
116
117
Parameters:
118
loader: vkGetInstanceProcAddr function, or None to use default
119
"""
120
```
121
122
## Window Hints for Vulkan
123
124
When creating windows for Vulkan rendering, set appropriate window hints:
125
126
```python { .api }
127
# Vulkan-specific window hints
128
CLIENT_API: int = 0x00022001
129
NO_API: int = 0 # Disable OpenGL context creation for Vulkan
130
131
# Use with window_hint:
132
# glfw.window_hint(glfw.CLIENT_API, glfw.NO_API)
133
```
134
135
## Usage Examples
136
137
### Basic Vulkan Setup
138
139
```python
140
import glfw
141
import ctypes
142
143
# Initialize GLFW
144
glfw.init()
145
146
# Check Vulkan support
147
if not glfw.vulkan_supported():
148
glfw.terminate()
149
raise Exception("Vulkan not supported")
150
151
# Get required extensions
152
extensions = glfw.get_required_instance_extensions()
153
print(f"Required Vulkan extensions: {extensions}")
154
155
# Create window without OpenGL context
156
glfw.window_hint(glfw.CLIENT_API, glfw.NO_API)
157
glfw.window_hint(glfw.RESIZABLE, glfw.FALSE)
158
159
window = glfw.create_window(800, 600, "Vulkan Window", None, None)
160
if not window:
161
glfw.terminate()
162
raise Exception("Failed to create window")
163
164
# ... Vulkan instance creation with required extensions ...
165
# instance = create_vulkan_instance_with_extensions(extensions)
166
167
# Create Vulkan surface
168
# surface = ctypes.c_void_p()
169
# result = glfw.create_window_surface(instance, window, None, ctypes.byref(surface))
170
# if result != VK_SUCCESS:
171
# raise Exception("Failed to create Vulkan surface")
172
173
glfw.terminate()
174
```
175
176
### Vulkan Function Loading
177
178
```python
179
import glfw
180
import ctypes
181
182
glfw.init()
183
184
if not glfw.vulkan_supported():
185
raise Exception("Vulkan not supported")
186
187
# Load Vulkan functions
188
vk_create_instance = glfw.get_instance_proc_address(None, "vkCreateInstance")
189
vk_enumerate_instance_extensions = glfw.get_instance_proc_address(None, "vkEnumerateInstanceExtensionProperties")
190
191
if vk_create_instance:
192
print("Successfully loaded vkCreateInstance")
193
194
# After creating instance, load instance-specific functions
195
# instance = ... # Created Vulkan instance
196
# vk_create_device = glfw.get_instance_proc_address(instance, "vkCreateDevice")
197
# vk_get_physical_devices = glfw.get_instance_proc_address(instance, "vkEnumeratePhysicalDevices")
198
199
glfw.terminate()
200
```
201
202
### Complete Vulkan Window Creation
203
204
```python
205
import glfw
206
import ctypes
207
208
def create_vulkan_window():
209
glfw.init()
210
211
# Verify Vulkan support
212
if not glfw.vulkan_supported():
213
glfw.terminate()
214
raise Exception("Vulkan is not supported")
215
216
# Get required instance extensions
217
glfw_extensions = glfw.get_required_instance_extensions()
218
print(f"GLFW requires these Vulkan extensions: {glfw_extensions}")
219
220
# Create window for Vulkan (no OpenGL context)
221
glfw.window_hint(glfw.CLIENT_API, glfw.NO_API)
222
glfw.window_hint(glfw.RESIZABLE, glfw.TRUE)
223
224
window = glfw.create_window(1024, 768, "Vulkan Application", None, None)
225
if not window:
226
glfw.terminate()
227
raise Exception("Failed to create GLFW window")
228
229
return window, glfw_extensions
230
231
def check_device_presentation_support(instance, physical_device, queue_family_index):
232
"""Check if a queue family supports presentation to GLFW windows."""
233
return glfw.get_physical_device_presentation_support(
234
instance, physical_device, queue_family_index
235
) == 1
236
237
# Usage
238
try:
239
window, required_extensions = create_vulkan_window()
240
241
# ... Create Vulkan instance with required_extensions ...
242
# ... Enumerate physical devices ...
243
# ... Check presentation support with check_device_presentation_support ...
244
# ... Create logical device with presentation-capable queue ...
245
# ... Create surface with glfw.create_window_surface ...
246
247
# Main loop
248
while not glfw.window_should_close(window):
249
glfw.poll_events()
250
251
# Vulkan rendering commands
252
# ... vkQueueSubmit, vkQueuePresentKHR, etc. ...
253
254
finally:
255
glfw.terminate()
256
```
257
258
### Vulkan Surface Management
259
260
```python
261
import glfw
262
import ctypes
263
264
class VulkanSurface:
265
def __init__(self, instance, window):
266
self.instance = instance
267
self.window = window
268
self.surface = ctypes.c_void_p()
269
270
# Create the surface
271
result = glfw.create_window_surface(
272
instance, window, None, ctypes.byref(self.surface)
273
)
274
275
if result != 0: # VK_SUCCESS = 0
276
raise Exception(f"Failed to create Vulkan surface: {result}")
277
278
def get_handle(self):
279
return self.surface.value
280
281
def cleanup(self):
282
# In a real application, you would call vkDestroySurfaceKHR here
283
# vkDestroySurfaceKHR(self.instance, self.surface, None)
284
pass
285
286
# Usage example
287
glfw.init()
288
289
if glfw.vulkan_supported():
290
glfw.window_hint(glfw.CLIENT_API, glfw.NO_API)
291
window = glfw.create_window(800, 600, "Vulkan Surface", None, None)
292
293
# ... create Vulkan instance ...
294
# instance = create_instance()
295
296
# surface = VulkanSurface(instance, window)
297
# print(f"Created surface: 0x{surface.get_handle():x}")
298
299
# ... use surface for swapchain creation ...
300
301
# surface.cleanup()
302
303
glfw.terminate()
304
```
305
306
### Vulkan Validation Layers
307
308
```python
309
import glfw
310
311
def get_vulkan_extensions_with_validation():
312
"""Get Vulkan extensions including validation layer requirements."""
313
314
# Get GLFW required extensions
315
glfw_extensions = glfw.get_required_instance_extensions()
316
317
# Add debug/validation extensions
318
validation_extensions = ["VK_EXT_debug_utils"]
319
320
# Combine extensions
321
all_extensions = glfw_extensions + validation_extensions
322
323
return all_extensions
324
325
def setup_vulkan_debug_callback():
326
"""Set up Vulkan debug callback for validation layers."""
327
328
# Load debug function
329
vk_create_debug_utils_messenger = glfw.get_instance_proc_address(
330
None, "vkCreateDebugUtilsMessengerEXT"
331
)
332
333
if vk_create_debug_utils_messenger:
334
print("Debug utils extension available")
335
# ... set up debug callback ...
336
else:
337
print("Debug utils extension not available")
338
339
# Usage
340
glfw.init()
341
342
if glfw.vulkan_supported():
343
extensions = get_vulkan_extensions_with_validation()
344
print(f"Extensions for Vulkan with validation: {extensions}")
345
346
# ... create instance with validation layers and extensions ...
347
# setup_vulkan_debug_callback()
348
349
glfw.terminate()
350
```
351
352
### Vulkan Multi-Window Support
353
354
```python
355
import glfw
356
import ctypes
357
358
def create_vulkan_windows(count=2):
359
"""Create multiple windows for Vulkan rendering."""
360
361
glfw.init()
362
363
if not glfw.vulkan_supported():
364
raise Exception("Vulkan not supported")
365
366
glfw.window_hint(glfw.CLIENT_API, glfw.NO_API)
367
368
windows = []
369
for i in range(count):
370
window = glfw.create_window(
371
800, 600, f"Vulkan Window {i+1}", None, None
372
)
373
if not window:
374
# Clean up previously created windows
375
for w in windows:
376
glfw.destroy_window(w)
377
glfw.terminate()
378
raise Exception(f"Failed to create window {i+1}")
379
380
windows.append(window)
381
382
return windows
383
384
def create_surfaces_for_windows(instance, windows):
385
"""Create Vulkan surfaces for multiple windows."""
386
387
surfaces = []
388
for i, window in enumerate(windows):
389
surface = ctypes.c_void_p()
390
result = glfw.create_window_surface(
391
instance, window, None, ctypes.byref(surface)
392
)
393
394
if result != 0:
395
print(f"Failed to create surface for window {i+1}")
396
continue
397
398
surfaces.append(surface.value)
399
400
return surfaces
401
402
# Usage
403
try:
404
windows = create_vulkan_windows(2)
405
406
# ... create Vulkan instance ...
407
# surfaces = create_surfaces_for_windows(instance, windows)
408
409
# Main loop handling multiple windows
410
while any(not glfw.window_should_close(w) for w in windows):
411
glfw.poll_events()
412
413
for i, window in enumerate(windows):
414
if not glfw.window_should_close(window):
415
# Render to window i
416
# ... Vulkan rendering for this window/surface ...
417
pass
418
419
finally:
420
glfw.terminate()
421
```