Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/drivers/vulkan/rendering_device_driver_vulkan.cpp
9903 views
1
/**************************************************************************/
2
/* rendering_device_driver_vulkan.cpp */
3
/**************************************************************************/
4
/* This file is part of: */
5
/* GODOT ENGINE */
6
/* https://godotengine.org */
7
/**************************************************************************/
8
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10
/* */
11
/* Permission is hereby granted, free of charge, to any person obtaining */
12
/* a copy of this software and associated documentation files (the */
13
/* "Software"), to deal in the Software without restriction, including */
14
/* without limitation the rights to use, copy, modify, merge, publish, */
15
/* distribute, sublicense, and/or sell copies of the Software, and to */
16
/* permit persons to whom the Software is furnished to do so, subject to */
17
/* the following conditions: */
18
/* */
19
/* The above copyright notice and this permission notice shall be */
20
/* included in all copies or substantial portions of the Software. */
21
/* */
22
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29
/**************************************************************************/
30
31
#include "rendering_device_driver_vulkan.h"
32
33
#include "core/config/project_settings.h"
34
#include "core/io/marshalls.h"
35
#include "vulkan_hooks.h"
36
37
#include "thirdparty/misc/smolv.h"
38
39
#if defined(ANDROID_ENABLED)
40
#include "platform/android/java_godot_wrapper.h"
41
#include "platform/android/os_android.h"
42
#include "platform/android/thread_jandroid.h"
43
#endif
44
45
#if defined(SWAPPY_FRAME_PACING_ENABLED)
46
#include "thirdparty/swappy-frame-pacing/swappyVk.h"
47
#endif
48
49
#define ARRAY_SIZE(a) std::size(a)
50
51
#define PRINT_NATIVE_COMMANDS 0
52
53
/*****************/
54
/**** GENERIC ****/
55
/*****************/
56
57
#if defined(DEBUG_ENABLED) || defined(DEV_ENABLED)
58
static const uint32_t BREADCRUMB_BUFFER_ENTRIES = 512u;
59
#endif
60
61
static const VkFormat RD_TO_VK_FORMAT[RDD::DATA_FORMAT_MAX] = {
62
VK_FORMAT_R4G4_UNORM_PACK8,
63
VK_FORMAT_R4G4B4A4_UNORM_PACK16,
64
VK_FORMAT_B4G4R4A4_UNORM_PACK16,
65
VK_FORMAT_R5G6B5_UNORM_PACK16,
66
VK_FORMAT_B5G6R5_UNORM_PACK16,
67
VK_FORMAT_R5G5B5A1_UNORM_PACK16,
68
VK_FORMAT_B5G5R5A1_UNORM_PACK16,
69
VK_FORMAT_A1R5G5B5_UNORM_PACK16,
70
VK_FORMAT_R8_UNORM,
71
VK_FORMAT_R8_SNORM,
72
VK_FORMAT_R8_USCALED,
73
VK_FORMAT_R8_SSCALED,
74
VK_FORMAT_R8_UINT,
75
VK_FORMAT_R8_SINT,
76
VK_FORMAT_R8_SRGB,
77
VK_FORMAT_R8G8_UNORM,
78
VK_FORMAT_R8G8_SNORM,
79
VK_FORMAT_R8G8_USCALED,
80
VK_FORMAT_R8G8_SSCALED,
81
VK_FORMAT_R8G8_UINT,
82
VK_FORMAT_R8G8_SINT,
83
VK_FORMAT_R8G8_SRGB,
84
VK_FORMAT_R8G8B8_UNORM,
85
VK_FORMAT_R8G8B8_SNORM,
86
VK_FORMAT_R8G8B8_USCALED,
87
VK_FORMAT_R8G8B8_SSCALED,
88
VK_FORMAT_R8G8B8_UINT,
89
VK_FORMAT_R8G8B8_SINT,
90
VK_FORMAT_R8G8B8_SRGB,
91
VK_FORMAT_B8G8R8_UNORM,
92
VK_FORMAT_B8G8R8_SNORM,
93
VK_FORMAT_B8G8R8_USCALED,
94
VK_FORMAT_B8G8R8_SSCALED,
95
VK_FORMAT_B8G8R8_UINT,
96
VK_FORMAT_B8G8R8_SINT,
97
VK_FORMAT_B8G8R8_SRGB,
98
VK_FORMAT_R8G8B8A8_UNORM,
99
VK_FORMAT_R8G8B8A8_SNORM,
100
VK_FORMAT_R8G8B8A8_USCALED,
101
VK_FORMAT_R8G8B8A8_SSCALED,
102
VK_FORMAT_R8G8B8A8_UINT,
103
VK_FORMAT_R8G8B8A8_SINT,
104
VK_FORMAT_R8G8B8A8_SRGB,
105
VK_FORMAT_B8G8R8A8_UNORM,
106
VK_FORMAT_B8G8R8A8_SNORM,
107
VK_FORMAT_B8G8R8A8_USCALED,
108
VK_FORMAT_B8G8R8A8_SSCALED,
109
VK_FORMAT_B8G8R8A8_UINT,
110
VK_FORMAT_B8G8R8A8_SINT,
111
VK_FORMAT_B8G8R8A8_SRGB,
112
VK_FORMAT_A8B8G8R8_UNORM_PACK32,
113
VK_FORMAT_A8B8G8R8_SNORM_PACK32,
114
VK_FORMAT_A8B8G8R8_USCALED_PACK32,
115
VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
116
VK_FORMAT_A8B8G8R8_UINT_PACK32,
117
VK_FORMAT_A8B8G8R8_SINT_PACK32,
118
VK_FORMAT_A8B8G8R8_SRGB_PACK32,
119
VK_FORMAT_A2R10G10B10_UNORM_PACK32,
120
VK_FORMAT_A2R10G10B10_SNORM_PACK32,
121
VK_FORMAT_A2R10G10B10_USCALED_PACK32,
122
VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
123
VK_FORMAT_A2R10G10B10_UINT_PACK32,
124
VK_FORMAT_A2R10G10B10_SINT_PACK32,
125
VK_FORMAT_A2B10G10R10_UNORM_PACK32,
126
VK_FORMAT_A2B10G10R10_SNORM_PACK32,
127
VK_FORMAT_A2B10G10R10_USCALED_PACK32,
128
VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
129
VK_FORMAT_A2B10G10R10_UINT_PACK32,
130
VK_FORMAT_A2B10G10R10_SINT_PACK32,
131
VK_FORMAT_R16_UNORM,
132
VK_FORMAT_R16_SNORM,
133
VK_FORMAT_R16_USCALED,
134
VK_FORMAT_R16_SSCALED,
135
VK_FORMAT_R16_UINT,
136
VK_FORMAT_R16_SINT,
137
VK_FORMAT_R16_SFLOAT,
138
VK_FORMAT_R16G16_UNORM,
139
VK_FORMAT_R16G16_SNORM,
140
VK_FORMAT_R16G16_USCALED,
141
VK_FORMAT_R16G16_SSCALED,
142
VK_FORMAT_R16G16_UINT,
143
VK_FORMAT_R16G16_SINT,
144
VK_FORMAT_R16G16_SFLOAT,
145
VK_FORMAT_R16G16B16_UNORM,
146
VK_FORMAT_R16G16B16_SNORM,
147
VK_FORMAT_R16G16B16_USCALED,
148
VK_FORMAT_R16G16B16_SSCALED,
149
VK_FORMAT_R16G16B16_UINT,
150
VK_FORMAT_R16G16B16_SINT,
151
VK_FORMAT_R16G16B16_SFLOAT,
152
VK_FORMAT_R16G16B16A16_UNORM,
153
VK_FORMAT_R16G16B16A16_SNORM,
154
VK_FORMAT_R16G16B16A16_USCALED,
155
VK_FORMAT_R16G16B16A16_SSCALED,
156
VK_FORMAT_R16G16B16A16_UINT,
157
VK_FORMAT_R16G16B16A16_SINT,
158
VK_FORMAT_R16G16B16A16_SFLOAT,
159
VK_FORMAT_R32_UINT,
160
VK_FORMAT_R32_SINT,
161
VK_FORMAT_R32_SFLOAT,
162
VK_FORMAT_R32G32_UINT,
163
VK_FORMAT_R32G32_SINT,
164
VK_FORMAT_R32G32_SFLOAT,
165
VK_FORMAT_R32G32B32_UINT,
166
VK_FORMAT_R32G32B32_SINT,
167
VK_FORMAT_R32G32B32_SFLOAT,
168
VK_FORMAT_R32G32B32A32_UINT,
169
VK_FORMAT_R32G32B32A32_SINT,
170
VK_FORMAT_R32G32B32A32_SFLOAT,
171
VK_FORMAT_R64_UINT,
172
VK_FORMAT_R64_SINT,
173
VK_FORMAT_R64_SFLOAT,
174
VK_FORMAT_R64G64_UINT,
175
VK_FORMAT_R64G64_SINT,
176
VK_FORMAT_R64G64_SFLOAT,
177
VK_FORMAT_R64G64B64_UINT,
178
VK_FORMAT_R64G64B64_SINT,
179
VK_FORMAT_R64G64B64_SFLOAT,
180
VK_FORMAT_R64G64B64A64_UINT,
181
VK_FORMAT_R64G64B64A64_SINT,
182
VK_FORMAT_R64G64B64A64_SFLOAT,
183
VK_FORMAT_B10G11R11_UFLOAT_PACK32,
184
VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
185
VK_FORMAT_D16_UNORM,
186
VK_FORMAT_X8_D24_UNORM_PACK32,
187
VK_FORMAT_D32_SFLOAT,
188
VK_FORMAT_S8_UINT,
189
VK_FORMAT_D16_UNORM_S8_UINT,
190
VK_FORMAT_D24_UNORM_S8_UINT,
191
VK_FORMAT_D32_SFLOAT_S8_UINT,
192
VK_FORMAT_BC1_RGB_UNORM_BLOCK,
193
VK_FORMAT_BC1_RGB_SRGB_BLOCK,
194
VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
195
VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
196
VK_FORMAT_BC2_UNORM_BLOCK,
197
VK_FORMAT_BC2_SRGB_BLOCK,
198
VK_FORMAT_BC3_UNORM_BLOCK,
199
VK_FORMAT_BC3_SRGB_BLOCK,
200
VK_FORMAT_BC4_UNORM_BLOCK,
201
VK_FORMAT_BC4_SNORM_BLOCK,
202
VK_FORMAT_BC5_UNORM_BLOCK,
203
VK_FORMAT_BC5_SNORM_BLOCK,
204
VK_FORMAT_BC6H_UFLOAT_BLOCK,
205
VK_FORMAT_BC6H_SFLOAT_BLOCK,
206
VK_FORMAT_BC7_UNORM_BLOCK,
207
VK_FORMAT_BC7_SRGB_BLOCK,
208
VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
209
VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
210
VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
211
VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
212
VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
213
VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
214
VK_FORMAT_EAC_R11_UNORM_BLOCK,
215
VK_FORMAT_EAC_R11_SNORM_BLOCK,
216
VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
217
VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
218
VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
219
VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
220
VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
221
VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
222
VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
223
VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
224
VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
225
VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
226
VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
227
VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
228
VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
229
VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
230
VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
231
VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
232
VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
233
VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
234
VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
235
VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
236
VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
237
VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
238
VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
239
VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
240
VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
241
VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
242
VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
243
VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
244
VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
245
VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
246
VK_FORMAT_G8B8G8R8_422_UNORM,
247
VK_FORMAT_B8G8R8G8_422_UNORM,
248
VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM,
249
VK_FORMAT_G8_B8R8_2PLANE_420_UNORM,
250
VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM,
251
VK_FORMAT_G8_B8R8_2PLANE_422_UNORM,
252
VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM,
253
VK_FORMAT_R10X6_UNORM_PACK16,
254
VK_FORMAT_R10X6G10X6_UNORM_2PACK16,
255
VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16,
256
VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16,
257
VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16,
258
VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16,
259
VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16,
260
VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16,
261
VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16,
262
VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16,
263
VK_FORMAT_R12X4_UNORM_PACK16,
264
VK_FORMAT_R12X4G12X4_UNORM_2PACK16,
265
VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16,
266
VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16,
267
VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16,
268
VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16,
269
VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16,
270
VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16,
271
VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16,
272
VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16,
273
VK_FORMAT_G16B16G16R16_422_UNORM,
274
VK_FORMAT_B16G16R16G16_422_UNORM,
275
VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM,
276
VK_FORMAT_G16_B16R16_2PLANE_420_UNORM,
277
VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM,
278
VK_FORMAT_G16_B16R16_2PLANE_422_UNORM,
279
VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM,
280
VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK,
281
VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK,
282
VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK,
283
VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK,
284
VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK,
285
VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK,
286
VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK,
287
VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK,
288
VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK,
289
VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK,
290
VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK,
291
VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK,
292
VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK,
293
VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK,
294
};
295
296
static VkImageLayout RD_TO_VK_LAYOUT[RDD::TEXTURE_LAYOUT_MAX] = {
297
VK_IMAGE_LAYOUT_UNDEFINED, // TEXTURE_LAYOUT_UNDEFINED
298
VK_IMAGE_LAYOUT_GENERAL, // TEXTURE_LAYOUT_GENERAL
299
VK_IMAGE_LAYOUT_GENERAL, // TEXTURE_LAYOUT_STORAGE_OPTIMAL
300
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // TEXTURE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
301
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // TEXTURE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
302
VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, // TEXTURE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
303
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // TEXTURE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
304
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // TEXTURE_LAYOUT_COPY_SRC_OPTIMAL
305
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // TEXTURE_LAYOUT_COPY_DST_OPTIMAL
306
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // TEXTURE_LAYOUT_RESOLVE_SRC_OPTIMAL
307
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // TEXTURE_LAYOUT_RESOLVE_DST_OPTIMAL
308
VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR, // TEXTURE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL
309
VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT, // TEXTURE_LAYOUT_FRAGMENT_DENSITY_MAP_ATTACHMENT_OPTIMAL
310
};
311
312
static VkPipelineStageFlags _rd_to_vk_pipeline_stages(BitField<RDD::PipelineStageBits> p_stages) {
313
VkPipelineStageFlags vk_flags = 0;
314
if (p_stages.has_flag(RDD::PIPELINE_STAGE_COPY_BIT) || p_stages.has_flag(RDD::PIPELINE_STAGE_RESOLVE_BIT)) {
315
// Transfer has been split into copy and resolve bits. Clear them and merge them into one bit.
316
vk_flags |= VK_PIPELINE_STAGE_TRANSFER_BIT;
317
p_stages.clear_flag(RDD::PIPELINE_STAGE_COPY_BIT);
318
p_stages.clear_flag(RDD::PIPELINE_STAGE_RESOLVE_BIT);
319
}
320
321
if (p_stages.has_flag(RDD::PIPELINE_STAGE_CLEAR_STORAGE_BIT)) {
322
// Vulkan should never use this as API_TRAIT_CLEAR_RESOURCES_WITH_VIEWS is not specified.
323
// Therefore, storage is never cleared with an explicit command.
324
p_stages.clear_flag(RDD::PIPELINE_STAGE_CLEAR_STORAGE_BIT);
325
}
326
327
// The rest of the flags have compatible numeric values with Vulkan.
328
return VkPipelineStageFlags(p_stages) | vk_flags;
329
}
330
331
static VkAccessFlags _rd_to_vk_access_flags(BitField<RDD::BarrierAccessBits> p_access) {
332
VkAccessFlags vk_flags = 0;
333
if (p_access.has_flag(RDD::BARRIER_ACCESS_COPY_READ_BIT) || p_access.has_flag(RDD::BARRIER_ACCESS_RESOLVE_READ_BIT)) {
334
vk_flags |= VK_ACCESS_TRANSFER_READ_BIT;
335
p_access.clear_flag(RDD::BARRIER_ACCESS_COPY_READ_BIT);
336
p_access.clear_flag(RDD::BARRIER_ACCESS_RESOLVE_READ_BIT);
337
}
338
339
if (p_access.has_flag(RDD::BARRIER_ACCESS_COPY_WRITE_BIT) || p_access.has_flag(RDD::BARRIER_ACCESS_RESOLVE_WRITE_BIT)) {
340
vk_flags |= VK_ACCESS_TRANSFER_WRITE_BIT;
341
p_access.clear_flag(RDD::BARRIER_ACCESS_COPY_WRITE_BIT);
342
p_access.clear_flag(RDD::BARRIER_ACCESS_RESOLVE_WRITE_BIT);
343
}
344
345
if (p_access.has_flag(RDD::BARRIER_ACCESS_STORAGE_CLEAR_BIT)) {
346
// Vulkan should never use this as API_TRAIT_CLEAR_RESOURCES_WITH_VIEWS is not specified.
347
// Therefore, storage is never cleared with an explicit command.
348
p_access.clear_flag(RDD::BARRIER_ACCESS_STORAGE_CLEAR_BIT);
349
}
350
351
// The rest of the flags have compatible numeric values with Vulkan.
352
return VkAccessFlags(p_access) | vk_flags;
353
}
354
355
// RDD::CompareOperator == VkCompareOp.
356
static_assert(ENUM_MEMBERS_EQUAL(RDD::COMPARE_OP_NEVER, VK_COMPARE_OP_NEVER));
357
static_assert(ENUM_MEMBERS_EQUAL(RDD::COMPARE_OP_LESS, VK_COMPARE_OP_LESS));
358
static_assert(ENUM_MEMBERS_EQUAL(RDD::COMPARE_OP_EQUAL, VK_COMPARE_OP_EQUAL));
359
static_assert(ENUM_MEMBERS_EQUAL(RDD::COMPARE_OP_LESS_OR_EQUAL, VK_COMPARE_OP_LESS_OR_EQUAL));
360
static_assert(ENUM_MEMBERS_EQUAL(RDD::COMPARE_OP_GREATER, VK_COMPARE_OP_GREATER));
361
static_assert(ENUM_MEMBERS_EQUAL(RDD::COMPARE_OP_NOT_EQUAL, VK_COMPARE_OP_NOT_EQUAL));
362
static_assert(ENUM_MEMBERS_EQUAL(RDD::COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_GREATER_OR_EQUAL));
363
static_assert(ENUM_MEMBERS_EQUAL(RDD::COMPARE_OP_ALWAYS, VK_COMPARE_OP_ALWAYS));
364
365
static_assert(ARRAYS_COMPATIBLE_FIELDWISE(Rect2i, VkRect2D));
366
367
uint32_t RenderingDeviceDriverVulkan::SubgroupCapabilities::supported_stages_flags_rd() const {
368
uint32_t flags = 0;
369
370
if (supported_stages & VK_SHADER_STAGE_VERTEX_BIT) {
371
flags += SHADER_STAGE_VERTEX_BIT;
372
}
373
if (supported_stages & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) {
374
flags += SHADER_STAGE_TESSELATION_CONTROL_BIT;
375
}
376
if (supported_stages & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) {
377
flags += SHADER_STAGE_TESSELATION_EVALUATION_BIT;
378
}
379
if (supported_stages & VK_SHADER_STAGE_GEOMETRY_BIT) {
380
// FIXME: Add shader stage geometry bit.
381
}
382
if (supported_stages & VK_SHADER_STAGE_FRAGMENT_BIT) {
383
flags += SHADER_STAGE_FRAGMENT_BIT;
384
}
385
if (supported_stages & VK_SHADER_STAGE_COMPUTE_BIT) {
386
flags += SHADER_STAGE_COMPUTE_BIT;
387
}
388
389
return flags;
390
}
391
392
String RenderingDeviceDriverVulkan::SubgroupCapabilities::supported_stages_desc() const {
393
String res;
394
395
if (supported_stages & VK_SHADER_STAGE_VERTEX_BIT) {
396
res += ", STAGE_VERTEX";
397
}
398
if (supported_stages & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) {
399
res += ", STAGE_TESSELLATION_CONTROL";
400
}
401
if (supported_stages & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) {
402
res += ", STAGE_TESSELLATION_EVALUATION";
403
}
404
if (supported_stages & VK_SHADER_STAGE_GEOMETRY_BIT) {
405
res += ", STAGE_GEOMETRY";
406
}
407
if (supported_stages & VK_SHADER_STAGE_FRAGMENT_BIT) {
408
res += ", STAGE_FRAGMENT";
409
}
410
if (supported_stages & VK_SHADER_STAGE_COMPUTE_BIT) {
411
res += ", STAGE_COMPUTE";
412
}
413
414
// These are not defined on Android GRMBL.
415
if (supported_stages & 0x00000100 /* VK_SHADER_STAGE_RAYGEN_BIT_KHR */) {
416
res += ", STAGE_RAYGEN_KHR";
417
}
418
if (supported_stages & 0x00000200 /* VK_SHADER_STAGE_ANY_HIT_BIT_KHR */) {
419
res += ", STAGE_ANY_HIT_KHR";
420
}
421
if (supported_stages & 0x00000400 /* VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR */) {
422
res += ", STAGE_CLOSEST_HIT_KHR";
423
}
424
if (supported_stages & 0x00000800 /* VK_SHADER_STAGE_MISS_BIT_KHR */) {
425
res += ", STAGE_MISS_KHR";
426
}
427
if (supported_stages & 0x00001000 /* VK_SHADER_STAGE_INTERSECTION_BIT_KHR */) {
428
res += ", STAGE_INTERSECTION_KHR";
429
}
430
if (supported_stages & 0x00002000 /* VK_SHADER_STAGE_CALLABLE_BIT_KHR */) {
431
res += ", STAGE_CALLABLE_KHR";
432
}
433
if (supported_stages & 0x00000040 /* VK_SHADER_STAGE_TASK_BIT_NV */) {
434
res += ", STAGE_TASK_NV";
435
}
436
if (supported_stages & 0x00000080 /* VK_SHADER_STAGE_MESH_BIT_NV */) {
437
res += ", STAGE_MESH_NV";
438
}
439
440
return res.substr(2); // Remove first ", ".
441
}
442
443
uint32_t RenderingDeviceDriverVulkan::SubgroupCapabilities::supported_operations_flags_rd() const {
444
uint32_t flags = 0;
445
446
if (supported_operations & VK_SUBGROUP_FEATURE_BASIC_BIT) {
447
flags += SUBGROUP_BASIC_BIT;
448
}
449
if (supported_operations & VK_SUBGROUP_FEATURE_VOTE_BIT) {
450
flags += SUBGROUP_VOTE_BIT;
451
}
452
if (supported_operations & VK_SUBGROUP_FEATURE_ARITHMETIC_BIT) {
453
flags += SUBGROUP_ARITHMETIC_BIT;
454
}
455
if (supported_operations & VK_SUBGROUP_FEATURE_BALLOT_BIT) {
456
flags += SUBGROUP_BALLOT_BIT;
457
}
458
if (supported_operations & VK_SUBGROUP_FEATURE_SHUFFLE_BIT) {
459
flags += SUBGROUP_SHUFFLE_BIT;
460
}
461
if (supported_operations & VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT) {
462
flags += SUBGROUP_SHUFFLE_RELATIVE_BIT;
463
}
464
if (supported_operations & VK_SUBGROUP_FEATURE_CLUSTERED_BIT) {
465
flags += SUBGROUP_CLUSTERED_BIT;
466
}
467
if (supported_operations & VK_SUBGROUP_FEATURE_QUAD_BIT) {
468
flags += SUBGROUP_QUAD_BIT;
469
}
470
471
return flags;
472
}
473
474
String RenderingDeviceDriverVulkan::SubgroupCapabilities::supported_operations_desc() const {
475
String res;
476
477
if (supported_operations & VK_SUBGROUP_FEATURE_BASIC_BIT) {
478
res += ", FEATURE_BASIC";
479
}
480
if (supported_operations & VK_SUBGROUP_FEATURE_VOTE_BIT) {
481
res += ", FEATURE_VOTE";
482
}
483
if (supported_operations & VK_SUBGROUP_FEATURE_ARITHMETIC_BIT) {
484
res += ", FEATURE_ARITHMETIC";
485
}
486
if (supported_operations & VK_SUBGROUP_FEATURE_BALLOT_BIT) {
487
res += ", FEATURE_BALLOT";
488
}
489
if (supported_operations & VK_SUBGROUP_FEATURE_SHUFFLE_BIT) {
490
res += ", FEATURE_SHUFFLE";
491
}
492
if (supported_operations & VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT) {
493
res += ", FEATURE_SHUFFLE_RELATIVE";
494
}
495
if (supported_operations & VK_SUBGROUP_FEATURE_CLUSTERED_BIT) {
496
res += ", FEATURE_CLUSTERED";
497
}
498
if (supported_operations & VK_SUBGROUP_FEATURE_QUAD_BIT) {
499
res += ", FEATURE_QUAD";
500
}
501
if (supported_operations & VK_SUBGROUP_FEATURE_PARTITIONED_BIT_NV) {
502
res += ", FEATURE_PARTITIONED_NV";
503
}
504
505
return res.substr(2); // Remove first ", ".
506
}
507
508
/*****************/
509
/**** GENERIC ****/
510
/*****************/
511
512
void RenderingDeviceDriverVulkan::_register_requested_device_extension(const CharString &p_extension_name, bool p_required) {
513
ERR_FAIL_COND(requested_device_extensions.has(p_extension_name));
514
requested_device_extensions[p_extension_name] = p_required;
515
}
516
517
Error RenderingDeviceDriverVulkan::_initialize_device_extensions() {
518
enabled_device_extension_names.clear();
519
520
_register_requested_device_extension(VK_KHR_SWAPCHAIN_EXTENSION_NAME, true);
521
_register_requested_device_extension(VK_KHR_MULTIVIEW_EXTENSION_NAME, false);
522
_register_requested_device_extension(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME, false);
523
_register_requested_device_extension(VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME, false);
524
_register_requested_device_extension(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME, false);
525
_register_requested_device_extension(VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME, false);
526
_register_requested_device_extension(VK_KHR_STORAGE_BUFFER_STORAGE_CLASS_EXTENSION_NAME, false);
527
_register_requested_device_extension(VK_KHR_16BIT_STORAGE_EXTENSION_NAME, false);
528
_register_requested_device_extension(VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME, false);
529
_register_requested_device_extension(VK_KHR_MAINTENANCE_2_EXTENSION_NAME, false);
530
_register_requested_device_extension(VK_EXT_PIPELINE_CREATION_CACHE_CONTROL_EXTENSION_NAME, false);
531
_register_requested_device_extension(VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME, false);
532
_register_requested_device_extension(VK_EXT_ASTC_DECODE_MODE_EXTENSION_NAME, false);
533
_register_requested_device_extension(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME, false);
534
_register_requested_device_extension(VK_KHR_VULKAN_MEMORY_MODEL_EXTENSION_NAME, false);
535
_register_requested_device_extension(VK_EXT_TEXTURE_COMPRESSION_ASTC_HDR_EXTENSION_NAME, false);
536
537
// We don't actually use this extension, but some runtime components on some platforms
538
// can and will fill the validation layers with useless info otherwise if not enabled.
539
_register_requested_device_extension(VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME, false);
540
541
if (Engine::get_singleton()->is_generate_spirv_debug_info_enabled()) {
542
_register_requested_device_extension(VK_KHR_SHADER_NON_SEMANTIC_INFO_EXTENSION_NAME, true);
543
}
544
545
#if defined(VK_TRACK_DEVICE_MEMORY)
546
if (Engine::get_singleton()->is_extra_gpu_memory_tracking_enabled()) {
547
_register_requested_device_extension(VK_EXT_DEVICE_MEMORY_REPORT_EXTENSION_NAME, false);
548
}
549
#endif
550
_register_requested_device_extension(VK_EXT_DEVICE_FAULT_EXTENSION_NAME, false);
551
552
{
553
// Debug marker extensions.
554
// Should be last element in the array.
555
#ifdef DEV_ENABLED
556
bool want_debug_markers = true;
557
#else
558
bool want_debug_markers = OS::get_singleton()->is_stdout_verbose();
559
#endif
560
if (want_debug_markers) {
561
_register_requested_device_extension(VK_EXT_DEBUG_MARKER_EXTENSION_NAME, false);
562
}
563
}
564
565
uint32_t device_extension_count = 0;
566
VkResult err = vkEnumerateDeviceExtensionProperties(physical_device, nullptr, &device_extension_count, nullptr);
567
ERR_FAIL_COND_V(err != VK_SUCCESS, ERR_CANT_CREATE);
568
ERR_FAIL_COND_V_MSG(device_extension_count == 0, ERR_CANT_CREATE, "vkEnumerateDeviceExtensionProperties failed to find any extensions\n\nDo you have a compatible Vulkan installable client driver (ICD) installed?");
569
570
TightLocalVector<VkExtensionProperties> device_extensions;
571
device_extensions.resize(device_extension_count);
572
err = vkEnumerateDeviceExtensionProperties(physical_device, nullptr, &device_extension_count, device_extensions.ptr());
573
ERR_FAIL_COND_V(err != VK_SUCCESS, ERR_CANT_CREATE);
574
575
#if defined(SWAPPY_FRAME_PACING_ENABLED)
576
if (swappy_frame_pacer_enable) {
577
char **swappy_required_extensions;
578
uint32_t swappy_required_extensions_count = 0;
579
// Determine number of extensions required by Swappy frame pacer.
580
SwappyVk_determineDeviceExtensions(physical_device, device_extension_count, device_extensions.ptr(), &swappy_required_extensions_count, nullptr);
581
582
if (swappy_required_extensions_count < device_extension_count) {
583
// Determine the actual extensions.
584
swappy_required_extensions = (char **)malloc(swappy_required_extensions_count * sizeof(char *));
585
char *pRequiredExtensionsData = (char *)malloc(swappy_required_extensions_count * (VK_MAX_EXTENSION_NAME_SIZE + 1));
586
for (uint32_t i = 0; i < swappy_required_extensions_count; i++) {
587
swappy_required_extensions[i] = &pRequiredExtensionsData[i * (VK_MAX_EXTENSION_NAME_SIZE + 1)];
588
}
589
SwappyVk_determineDeviceExtensions(physical_device, device_extension_count,
590
device_extensions.ptr(), &swappy_required_extensions_count, swappy_required_extensions);
591
592
// Enable extensions requested by Swappy.
593
for (uint32_t i = 0; i < swappy_required_extensions_count; i++) {
594
CharString extension_name(swappy_required_extensions[i]);
595
if (requested_device_extensions.has(extension_name)) {
596
enabled_device_extension_names.insert(extension_name);
597
}
598
}
599
600
free(pRequiredExtensionsData);
601
free(swappy_required_extensions);
602
}
603
}
604
#endif
605
606
#ifdef DEV_ENABLED
607
for (uint32_t i = 0; i < device_extension_count; i++) {
608
print_verbose(String("VULKAN: Found device extension ") + String::utf8(device_extensions[i].extensionName));
609
}
610
#endif
611
612
// Enable all extensions that are supported and requested.
613
for (uint32_t i = 0; i < device_extension_count; i++) {
614
CharString extension_name(device_extensions[i].extensionName);
615
if (requested_device_extensions.has(extension_name)) {
616
enabled_device_extension_names.insert(extension_name);
617
}
618
}
619
620
// Now check our requested extensions.
621
for (KeyValue<CharString, bool> &requested_extension : requested_device_extensions) {
622
if (!enabled_device_extension_names.has(requested_extension.key)) {
623
if (requested_extension.value) {
624
ERR_FAIL_V_MSG(ERR_BUG, String("Required extension ") + String::utf8(requested_extension.key) + String(" not found."));
625
} else {
626
print_verbose(String("Optional extension ") + String::utf8(requested_extension.key) + String(" not found"));
627
}
628
}
629
}
630
631
return OK;
632
}
633
634
Error RenderingDeviceDriverVulkan::_check_device_features() {
635
vkGetPhysicalDeviceFeatures(physical_device, &physical_device_features);
636
637
// Check for required features.
638
if (!physical_device_features.imageCubeArray || !physical_device_features.independentBlend) {
639
String error_string = vformat("Your GPU (%s) does not support the following features which are required to use Vulkan-based renderers in Godot:\n\n", context_device.name);
640
if (!physical_device_features.imageCubeArray) {
641
error_string += "- No support for image cube arrays.\n";
642
}
643
if (!physical_device_features.independentBlend) {
644
error_string += "- No support for independentBlend.\n";
645
}
646
error_string += "\nThis is usually a hardware limitation, so updating graphics drivers won't help in most cases.";
647
648
#if defined(ANDROID_ENABLED) || defined(IOS_ENABLED)
649
// Android/iOS platform ports currently don't exit themselves when this method returns `ERR_CANT_CREATE`.
650
OS::get_singleton()->alert(error_string + "\nClick OK to exit (black screen will be visible).");
651
#else
652
OS::get_singleton()->alert(error_string + "\nClick OK to exit.");
653
#endif
654
655
return ERR_CANT_CREATE;
656
}
657
658
// Opt-in to the features we actually need/use. These can be changed in the future.
659
// We do this for multiple reasons:
660
//
661
// 1. Certain features (like sparse* stuff) cause unnecessary internal driver allocations.
662
// 2. Others like shaderStorageImageMultisample are a huge red flag
663
// (MSAA + Storage is rarely needed).
664
// 3. Most features when turned off aren't actually off (we just promise the driver not to use them)
665
// and it is validation what will complain. This allows us to target a minimum baseline.
666
//
667
// TODO: Allow the user to override these settings (i.e. turn off more stuff) using profiles
668
// so they can target a broad range of HW. For example Mali HW does not have
669
// shaderClipDistance/shaderCullDistance; thus validation would complain if such feature is used;
670
// allowing them to fix the problem without even owning Mali HW to test on.
671
//
672
// The excluded features are:
673
// - robustBufferAccess (can hamper performance on some hardware)
674
// - occlusionQueryPrecise
675
// - pipelineStatisticsQuery
676
// - shaderStorageImageMultisample (unsupported by Intel Arc, prevents from using MSAA storage accidentally)
677
// - shaderResourceResidency
678
// - sparseBinding (we don't use sparse features and enabling them cause extra internal allocations inside the Vulkan driver we don't need)
679
// - sparseResidencyBuffer
680
// - sparseResidencyImage2D
681
// - sparseResidencyImage3D
682
// - sparseResidency2Samples
683
// - sparseResidency4Samples
684
// - sparseResidency8Samples
685
// - sparseResidency16Samples
686
// - sparseResidencyAliased
687
// - inheritedQueries
688
689
#define VK_DEVICEFEATURE_ENABLE_IF(x) \
690
if (physical_device_features.x) { \
691
requested_device_features.x = physical_device_features.x; \
692
} else \
693
((void)0)
694
695
requested_device_features = {};
696
VK_DEVICEFEATURE_ENABLE_IF(fullDrawIndexUint32);
697
VK_DEVICEFEATURE_ENABLE_IF(imageCubeArray);
698
VK_DEVICEFEATURE_ENABLE_IF(independentBlend);
699
VK_DEVICEFEATURE_ENABLE_IF(geometryShader);
700
VK_DEVICEFEATURE_ENABLE_IF(tessellationShader);
701
VK_DEVICEFEATURE_ENABLE_IF(sampleRateShading);
702
VK_DEVICEFEATURE_ENABLE_IF(dualSrcBlend);
703
VK_DEVICEFEATURE_ENABLE_IF(logicOp);
704
VK_DEVICEFEATURE_ENABLE_IF(multiDrawIndirect);
705
VK_DEVICEFEATURE_ENABLE_IF(drawIndirectFirstInstance);
706
VK_DEVICEFEATURE_ENABLE_IF(depthClamp);
707
VK_DEVICEFEATURE_ENABLE_IF(depthBiasClamp);
708
VK_DEVICEFEATURE_ENABLE_IF(fillModeNonSolid);
709
VK_DEVICEFEATURE_ENABLE_IF(depthBounds);
710
VK_DEVICEFEATURE_ENABLE_IF(wideLines);
711
VK_DEVICEFEATURE_ENABLE_IF(largePoints);
712
VK_DEVICEFEATURE_ENABLE_IF(alphaToOne);
713
VK_DEVICEFEATURE_ENABLE_IF(multiViewport);
714
VK_DEVICEFEATURE_ENABLE_IF(samplerAnisotropy);
715
VK_DEVICEFEATURE_ENABLE_IF(textureCompressionETC2);
716
VK_DEVICEFEATURE_ENABLE_IF(textureCompressionASTC_LDR);
717
VK_DEVICEFEATURE_ENABLE_IF(textureCompressionBC);
718
VK_DEVICEFEATURE_ENABLE_IF(vertexPipelineStoresAndAtomics);
719
VK_DEVICEFEATURE_ENABLE_IF(fragmentStoresAndAtomics);
720
VK_DEVICEFEATURE_ENABLE_IF(shaderTessellationAndGeometryPointSize);
721
VK_DEVICEFEATURE_ENABLE_IF(shaderImageGatherExtended);
722
VK_DEVICEFEATURE_ENABLE_IF(shaderStorageImageExtendedFormats);
723
VK_DEVICEFEATURE_ENABLE_IF(shaderStorageImageReadWithoutFormat);
724
VK_DEVICEFEATURE_ENABLE_IF(shaderStorageImageWriteWithoutFormat);
725
VK_DEVICEFEATURE_ENABLE_IF(shaderUniformBufferArrayDynamicIndexing);
726
VK_DEVICEFEATURE_ENABLE_IF(shaderSampledImageArrayDynamicIndexing);
727
VK_DEVICEFEATURE_ENABLE_IF(shaderStorageBufferArrayDynamicIndexing);
728
VK_DEVICEFEATURE_ENABLE_IF(shaderStorageImageArrayDynamicIndexing);
729
VK_DEVICEFEATURE_ENABLE_IF(shaderClipDistance);
730
VK_DEVICEFEATURE_ENABLE_IF(shaderCullDistance);
731
VK_DEVICEFEATURE_ENABLE_IF(shaderFloat64);
732
VK_DEVICEFEATURE_ENABLE_IF(shaderInt64);
733
VK_DEVICEFEATURE_ENABLE_IF(shaderInt16);
734
VK_DEVICEFEATURE_ENABLE_IF(shaderResourceMinLod);
735
VK_DEVICEFEATURE_ENABLE_IF(variableMultisampleRate);
736
737
return OK;
738
}
739
740
Error RenderingDeviceDriverVulkan::_check_device_capabilities() {
741
// Fill device family and version.
742
device_capabilities.device_family = DEVICE_VULKAN;
743
device_capabilities.version_major = VK_API_VERSION_MAJOR(physical_device_properties.apiVersion);
744
device_capabilities.version_minor = VK_API_VERSION_MINOR(physical_device_properties.apiVersion);
745
746
// References:
747
// https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VK_KHR_multiview.html
748
// https://www.khronos.org/blog/vulkan-subgroup-tutorial
749
const RenderingContextDriverVulkan::Functions &functions = context_driver->functions_get();
750
if (functions.GetPhysicalDeviceFeatures2 != nullptr) {
751
// We must check that the corresponding extension is present before assuming a feature as enabled.
752
// See also: https://github.com/godotengine/godot/issues/65409
753
754
void *next_features = nullptr;
755
VkPhysicalDeviceVulkan12Features device_features_vk_1_2 = {};
756
VkPhysicalDeviceShaderFloat16Int8FeaturesKHR shader_features = {};
757
VkPhysicalDeviceBufferDeviceAddressFeaturesKHR buffer_device_address_features = {};
758
VkPhysicalDeviceVulkanMemoryModelFeaturesKHR vulkan_memory_model_features = {};
759
VkPhysicalDeviceFragmentShadingRateFeaturesKHR fsr_features = {};
760
VkPhysicalDeviceFragmentDensityMapFeaturesEXT fdm_features = {};
761
VkPhysicalDevice16BitStorageFeaturesKHR storage_feature = {};
762
VkPhysicalDeviceMultiviewFeatures multiview_features = {};
763
VkPhysicalDevicePipelineCreationCacheControlFeatures pipeline_cache_control_features = {};
764
765
const bool use_1_2_features = physical_device_properties.apiVersion >= VK_API_VERSION_1_2;
766
if (use_1_2_features) {
767
device_features_vk_1_2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES;
768
device_features_vk_1_2.pNext = next_features;
769
next_features = &device_features_vk_1_2;
770
} else {
771
if (enabled_device_extension_names.has(VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME)) {
772
shader_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR;
773
shader_features.pNext = next_features;
774
next_features = &shader_features;
775
}
776
if (enabled_device_extension_names.has(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME)) {
777
buffer_device_address_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_KHR;
778
buffer_device_address_features.pNext = next_features;
779
next_features = &buffer_device_address_features;
780
}
781
if (enabled_device_extension_names.has(VK_KHR_VULKAN_MEMORY_MODEL_EXTENSION_NAME)) {
782
vulkan_memory_model_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR;
783
vulkan_memory_model_features.pNext = next_features;
784
next_features = &vulkan_memory_model_features;
785
}
786
}
787
788
if (enabled_device_extension_names.has(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME)) {
789
fsr_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR;
790
fsr_features.pNext = next_features;
791
next_features = &fsr_features;
792
}
793
794
if (enabled_device_extension_names.has(VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME)) {
795
fdm_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT;
796
fdm_features.pNext = next_features;
797
next_features = &fdm_features;
798
}
799
800
if (enabled_device_extension_names.has(VK_KHR_16BIT_STORAGE_EXTENSION_NAME)) {
801
storage_feature.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR;
802
storage_feature.pNext = next_features;
803
next_features = &storage_feature;
804
}
805
806
if (enabled_device_extension_names.has(VK_KHR_MULTIVIEW_EXTENSION_NAME)) {
807
multiview_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES;
808
multiview_features.pNext = next_features;
809
next_features = &multiview_features;
810
}
811
812
if (enabled_device_extension_names.has(VK_EXT_PIPELINE_CREATION_CACHE_CONTROL_EXTENSION_NAME)) {
813
pipeline_cache_control_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES;
814
pipeline_cache_control_features.pNext = next_features;
815
next_features = &pipeline_cache_control_features;
816
}
817
818
VkPhysicalDeviceFeatures2 device_features_2 = {};
819
device_features_2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
820
device_features_2.pNext = next_features;
821
functions.GetPhysicalDeviceFeatures2(physical_device, &device_features_2);
822
823
if (use_1_2_features) {
824
#ifdef MACOS_ENABLED
825
ERR_FAIL_COND_V_MSG(!device_features_vk_1_2.shaderSampledImageArrayNonUniformIndexing, ERR_CANT_CREATE, "Your GPU doesn't support shaderSampledImageArrayNonUniformIndexing which is required to use the Vulkan-based renderers in Godot.");
826
#endif
827
if (enabled_device_extension_names.has(VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME)) {
828
shader_capabilities.shader_float16_is_supported = device_features_vk_1_2.shaderFloat16;
829
shader_capabilities.shader_int8_is_supported = device_features_vk_1_2.shaderInt8;
830
}
831
if (enabled_device_extension_names.has(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME)) {
832
buffer_device_address_support = device_features_vk_1_2.bufferDeviceAddress;
833
}
834
if (enabled_device_extension_names.has(VK_KHR_VULKAN_MEMORY_MODEL_EXTENSION_NAME)) {
835
vulkan_memory_model_support = device_features_vk_1_2.vulkanMemoryModel;
836
vulkan_memory_model_device_scope_support = device_features_vk_1_2.vulkanMemoryModelDeviceScope;
837
}
838
} else {
839
if (enabled_device_extension_names.has(VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME)) {
840
shader_capabilities.shader_float16_is_supported = shader_features.shaderFloat16;
841
shader_capabilities.shader_int8_is_supported = shader_features.shaderInt8;
842
}
843
if (enabled_device_extension_names.has(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME)) {
844
buffer_device_address_support = buffer_device_address_features.bufferDeviceAddress;
845
}
846
if (enabled_device_extension_names.has(VK_KHR_VULKAN_MEMORY_MODEL_EXTENSION_NAME)) {
847
vulkan_memory_model_support = vulkan_memory_model_features.vulkanMemoryModel;
848
vulkan_memory_model_device_scope_support = vulkan_memory_model_features.vulkanMemoryModelDeviceScope;
849
}
850
}
851
852
if (enabled_device_extension_names.has(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME)) {
853
fsr_capabilities.pipeline_supported = fsr_features.pipelineFragmentShadingRate;
854
fsr_capabilities.primitive_supported = fsr_features.primitiveFragmentShadingRate;
855
fsr_capabilities.attachment_supported = fsr_features.attachmentFragmentShadingRate;
856
}
857
858
if (enabled_device_extension_names.has(VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME)) {
859
fdm_capabilities.attachment_supported = fdm_features.fragmentDensityMap;
860
fdm_capabilities.dynamic_attachment_supported = fdm_features.fragmentDensityMapDynamic;
861
fdm_capabilities.non_subsampled_images_supported = fdm_features.fragmentDensityMapNonSubsampledImages;
862
}
863
864
// Multiple VRS techniques can't co-exist during the existence of one device, so we must
865
// choose one at creation time and only report one of them as available.
866
_choose_vrs_capabilities();
867
868
if (enabled_device_extension_names.has(VK_KHR_MULTIVIEW_EXTENSION_NAME)) {
869
multiview_capabilities.is_supported = multiview_features.multiview;
870
multiview_capabilities.geometry_shader_is_supported = multiview_features.multiviewGeometryShader;
871
multiview_capabilities.tessellation_shader_is_supported = multiview_features.multiviewTessellationShader;
872
}
873
874
if (enabled_device_extension_names.has(VK_KHR_16BIT_STORAGE_EXTENSION_NAME)) {
875
storage_buffer_capabilities.storage_buffer_16_bit_access_is_supported = storage_feature.storageBuffer16BitAccess;
876
storage_buffer_capabilities.uniform_and_storage_buffer_16_bit_access_is_supported = storage_feature.uniformAndStorageBuffer16BitAccess;
877
storage_buffer_capabilities.storage_push_constant_16_is_supported = storage_feature.storagePushConstant16;
878
storage_buffer_capabilities.storage_input_output_16 = storage_feature.storageInputOutput16;
879
}
880
881
if (enabled_device_extension_names.has(VK_EXT_PIPELINE_CREATION_CACHE_CONTROL_EXTENSION_NAME)) {
882
pipeline_cache_control_support = pipeline_cache_control_features.pipelineCreationCacheControl;
883
}
884
885
if (enabled_device_extension_names.has(VK_EXT_DEVICE_FAULT_EXTENSION_NAME)) {
886
device_fault_support = true;
887
}
888
#if defined(VK_TRACK_DEVICE_MEMORY)
889
if (enabled_device_extension_names.has(VK_EXT_DEVICE_MEMORY_REPORT_EXTENSION_NAME)) {
890
device_memory_report_support = true;
891
}
892
#endif
893
}
894
895
if (functions.GetPhysicalDeviceProperties2 != nullptr) {
896
void *next_properties = nullptr;
897
VkPhysicalDeviceFragmentShadingRatePropertiesKHR fsr_properties = {};
898
VkPhysicalDeviceFragmentDensityMapPropertiesEXT fdm_properties = {};
899
VkPhysicalDeviceMultiviewProperties multiview_properties = {};
900
VkPhysicalDeviceSubgroupProperties subgroup_properties = {};
901
VkPhysicalDeviceSubgroupSizeControlProperties subgroup_size_control_properties = {};
902
VkPhysicalDeviceProperties2 physical_device_properties_2 = {};
903
904
const bool use_1_1_properties = physical_device_properties.apiVersion >= VK_API_VERSION_1_1;
905
if (use_1_1_properties) {
906
subgroup_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES;
907
subgroup_properties.pNext = next_properties;
908
next_properties = &subgroup_properties;
909
910
subgroup_capabilities.size_control_is_supported = enabled_device_extension_names.has(VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME);
911
if (subgroup_capabilities.size_control_is_supported) {
912
subgroup_size_control_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES;
913
subgroup_size_control_properties.pNext = next_properties;
914
next_properties = &subgroup_size_control_properties;
915
}
916
}
917
918
if (multiview_capabilities.is_supported) {
919
multiview_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES;
920
multiview_properties.pNext = next_properties;
921
next_properties = &multiview_properties;
922
}
923
924
if (fsr_capabilities.attachment_supported) {
925
fsr_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_PROPERTIES_KHR;
926
fsr_properties.pNext = next_properties;
927
next_properties = &fsr_properties;
928
}
929
930
if (fdm_capabilities.attachment_supported) {
931
fdm_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_PROPERTIES_EXT;
932
fdm_properties.pNext = next_properties;
933
next_properties = &fdm_properties;
934
}
935
936
physical_device_properties_2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
937
physical_device_properties_2.pNext = next_properties;
938
functions.GetPhysicalDeviceProperties2(physical_device, &physical_device_properties_2);
939
940
subgroup_capabilities.size = subgroup_properties.subgroupSize;
941
subgroup_capabilities.min_size = subgroup_properties.subgroupSize;
942
subgroup_capabilities.max_size = subgroup_properties.subgroupSize;
943
subgroup_capabilities.supported_stages = subgroup_properties.supportedStages;
944
subgroup_capabilities.supported_operations = subgroup_properties.supportedOperations;
945
946
// Note: quadOperationsInAllStages will be true if:
947
// - supportedStages has VK_SHADER_STAGE_ALL_GRAPHICS + VK_SHADER_STAGE_COMPUTE_BIT.
948
// - supportedOperations has VK_SUBGROUP_FEATURE_QUAD_BIT.
949
subgroup_capabilities.quad_operations_in_all_stages = subgroup_properties.quadOperationsInAllStages;
950
951
if (subgroup_capabilities.size_control_is_supported && (subgroup_size_control_properties.requiredSubgroupSizeStages & VK_SHADER_STAGE_COMPUTE_BIT)) {
952
subgroup_capabilities.min_size = subgroup_size_control_properties.minSubgroupSize;
953
subgroup_capabilities.max_size = subgroup_size_control_properties.maxSubgroupSize;
954
}
955
956
if (fsr_capabilities.pipeline_supported || fsr_capabilities.primitive_supported || fsr_capabilities.attachment_supported) {
957
print_verbose("- Vulkan Fragment Shading Rate supported:");
958
if (fsr_capabilities.pipeline_supported) {
959
print_verbose(" Pipeline fragment shading rate");
960
}
961
if (fsr_capabilities.primitive_supported) {
962
print_verbose(" Primitive fragment shading rate");
963
}
964
if (fsr_capabilities.attachment_supported) {
965
// TODO: Expose these somehow to the end user.
966
fsr_capabilities.min_texel_size.x = fsr_properties.minFragmentShadingRateAttachmentTexelSize.width;
967
fsr_capabilities.min_texel_size.y = fsr_properties.minFragmentShadingRateAttachmentTexelSize.height;
968
fsr_capabilities.max_texel_size.x = fsr_properties.maxFragmentShadingRateAttachmentTexelSize.width;
969
fsr_capabilities.max_texel_size.y = fsr_properties.maxFragmentShadingRateAttachmentTexelSize.height;
970
fsr_capabilities.max_fragment_size.x = fsr_properties.maxFragmentSize.width; // either 4 or 8
971
fsr_capabilities.max_fragment_size.y = fsr_properties.maxFragmentSize.height; // generally the same as width
972
973
print_verbose(String(" Attachment fragment shading rate") +
974
String(", min texel size: (") + itos(fsr_capabilities.min_texel_size.x) + String(", ") + itos(fsr_capabilities.min_texel_size.y) + String(")") +
975
String(", max texel size: (") + itos(fsr_capabilities.max_texel_size.x) + String(", ") + itos(fsr_capabilities.max_texel_size.y) + String(")") +
976
String(", max fragment size: (") + itos(fsr_capabilities.max_fragment_size.x) + String(", ") + itos(fsr_capabilities.max_fragment_size.y) + String(")"));
977
}
978
979
} else {
980
print_verbose("- Vulkan Variable Rate Shading not supported");
981
}
982
983
if (fdm_capabilities.attachment_supported || fdm_capabilities.dynamic_attachment_supported || fdm_capabilities.non_subsampled_images_supported) {
984
print_verbose("- Vulkan Fragment Density Map supported");
985
986
fdm_capabilities.min_texel_size.x = fdm_properties.minFragmentDensityTexelSize.width;
987
fdm_capabilities.min_texel_size.y = fdm_properties.minFragmentDensityTexelSize.height;
988
fdm_capabilities.max_texel_size.x = fdm_properties.maxFragmentDensityTexelSize.width;
989
fdm_capabilities.max_texel_size.y = fdm_properties.maxFragmentDensityTexelSize.height;
990
fdm_capabilities.invocations_supported = fdm_properties.fragmentDensityInvocations;
991
992
if (fdm_capabilities.dynamic_attachment_supported) {
993
print_verbose(" - dynamic fragment density map supported");
994
}
995
996
if (fdm_capabilities.non_subsampled_images_supported) {
997
print_verbose(" - non-subsampled images supported");
998
}
999
} else {
1000
print_verbose("- Vulkan Fragment Density Map not supported");
1001
}
1002
1003
if (multiview_capabilities.is_supported) {
1004
multiview_capabilities.max_view_count = multiview_properties.maxMultiviewViewCount;
1005
multiview_capabilities.max_instance_count = multiview_properties.maxMultiviewInstanceIndex;
1006
1007
print_verbose("- Vulkan multiview supported:");
1008
print_verbose(" max view count: " + itos(multiview_capabilities.max_view_count));
1009
print_verbose(" max instances: " + itos(multiview_capabilities.max_instance_count));
1010
} else {
1011
print_verbose("- Vulkan multiview not supported");
1012
}
1013
1014
print_verbose("- Vulkan subgroup:");
1015
print_verbose(" size: " + itos(subgroup_capabilities.size));
1016
print_verbose(" min size: " + itos(subgroup_capabilities.min_size));
1017
print_verbose(" max size: " + itos(subgroup_capabilities.max_size));
1018
print_verbose(" stages: " + subgroup_capabilities.supported_stages_desc());
1019
print_verbose(" supported ops: " + subgroup_capabilities.supported_operations_desc());
1020
if (subgroup_capabilities.quad_operations_in_all_stages) {
1021
print_verbose(" quad operations in all stages");
1022
}
1023
}
1024
1025
return OK;
1026
}
1027
1028
void RenderingDeviceDriverVulkan::_choose_vrs_capabilities() {
1029
bool prefer_fdm_on_qualcomm = physical_device_properties.vendorID == RenderingContextDriver::Vendor::VENDOR_QUALCOMM;
1030
if (fdm_capabilities.attachment_supported && (!fsr_capabilities.attachment_supported || prefer_fdm_on_qualcomm)) {
1031
// If available, we prefer using fragment density maps on Qualcomm as they adjust tile distribution when using
1032
// this technique. Performance as a result is higher than when using fragment shading rate.
1033
fsr_capabilities = FragmentShadingRateCapabilities();
1034
} else if (fsr_capabilities.attachment_supported) {
1035
// Disable any possibility of fragment density maps being used.
1036
fdm_capabilities = FragmentDensityMapCapabilities();
1037
} else {
1038
// Do not report or enable any VRS capabilities if attachment is not supported.
1039
fsr_capabilities = FragmentShadingRateCapabilities();
1040
fdm_capabilities = FragmentDensityMapCapabilities();
1041
}
1042
}
1043
1044
Error RenderingDeviceDriverVulkan::_add_queue_create_info(LocalVector<VkDeviceQueueCreateInfo> &r_queue_create_info) {
1045
uint32_t queue_family_count = queue_family_properties.size();
1046
queue_families.resize(queue_family_count);
1047
1048
VkQueueFlags queue_flags_mask = VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT;
1049
const uint32_t max_queue_count_per_family = 1;
1050
static const float queue_priorities[max_queue_count_per_family] = {};
1051
for (uint32_t i = 0; i < queue_family_count; i++) {
1052
if ((queue_family_properties[i].queueFlags & queue_flags_mask) == 0) {
1053
// We ignore creating queues in families that don't support any of the operations we require.
1054
continue;
1055
}
1056
1057
VkDeviceQueueCreateInfo create_info = {};
1058
create_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
1059
create_info.queueFamilyIndex = i;
1060
create_info.queueCount = MIN(queue_family_properties[i].queueCount, max_queue_count_per_family);
1061
create_info.pQueuePriorities = queue_priorities;
1062
r_queue_create_info.push_back(create_info);
1063
1064
// Prepare the vectors where the queues will be filled out.
1065
queue_families[i].resize(create_info.queueCount);
1066
}
1067
1068
return OK;
1069
}
1070
1071
Error RenderingDeviceDriverVulkan::_initialize_device(const LocalVector<VkDeviceQueueCreateInfo> &p_queue_create_info) {
1072
TightLocalVector<const char *> enabled_extension_names;
1073
enabled_extension_names.reserve(enabled_device_extension_names.size());
1074
for (const CharString &extension_name : enabled_device_extension_names) {
1075
enabled_extension_names.push_back(extension_name.ptr());
1076
}
1077
1078
void *create_info_next = nullptr;
1079
VkPhysicalDeviceShaderFloat16Int8FeaturesKHR shader_features = {};
1080
shader_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR;
1081
shader_features.pNext = create_info_next;
1082
shader_features.shaderFloat16 = shader_capabilities.shader_float16_is_supported;
1083
shader_features.shaderInt8 = shader_capabilities.shader_int8_is_supported;
1084
create_info_next = &shader_features;
1085
1086
VkPhysicalDeviceBufferDeviceAddressFeaturesKHR buffer_device_address_features = {};
1087
if (buffer_device_address_support) {
1088
buffer_device_address_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_KHR;
1089
buffer_device_address_features.pNext = create_info_next;
1090
buffer_device_address_features.bufferDeviceAddress = buffer_device_address_support;
1091
create_info_next = &buffer_device_address_features;
1092
}
1093
1094
VkPhysicalDeviceVulkanMemoryModelFeaturesKHR vulkan_memory_model_features = {};
1095
if (vulkan_memory_model_support && vulkan_memory_model_device_scope_support) {
1096
vulkan_memory_model_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR;
1097
vulkan_memory_model_features.pNext = create_info_next;
1098
vulkan_memory_model_features.vulkanMemoryModel = vulkan_memory_model_support;
1099
vulkan_memory_model_features.vulkanMemoryModelDeviceScope = vulkan_memory_model_device_scope_support;
1100
create_info_next = &vulkan_memory_model_features;
1101
}
1102
1103
VkPhysicalDeviceFragmentShadingRateFeaturesKHR fsr_features = {};
1104
if (fsr_capabilities.pipeline_supported || fsr_capabilities.primitive_supported || fsr_capabilities.attachment_supported) {
1105
fsr_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR;
1106
fsr_features.pNext = create_info_next;
1107
fsr_features.pipelineFragmentShadingRate = fsr_capabilities.pipeline_supported;
1108
fsr_features.primitiveFragmentShadingRate = fsr_capabilities.primitive_supported;
1109
fsr_features.attachmentFragmentShadingRate = fsr_capabilities.attachment_supported;
1110
create_info_next = &fsr_features;
1111
}
1112
1113
VkPhysicalDeviceFragmentDensityMapFeaturesEXT fdm_features = {};
1114
if (fdm_capabilities.attachment_supported || fdm_capabilities.dynamic_attachment_supported || fdm_capabilities.non_subsampled_images_supported) {
1115
fdm_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT;
1116
fdm_features.pNext = create_info_next;
1117
fdm_features.fragmentDensityMap = fdm_capabilities.attachment_supported;
1118
fdm_features.fragmentDensityMapDynamic = fdm_capabilities.dynamic_attachment_supported;
1119
fdm_features.fragmentDensityMapNonSubsampledImages = fdm_capabilities.non_subsampled_images_supported;
1120
create_info_next = &fdm_features;
1121
}
1122
1123
VkPhysicalDevicePipelineCreationCacheControlFeatures pipeline_cache_control_features = {};
1124
if (pipeline_cache_control_support) {
1125
pipeline_cache_control_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES;
1126
pipeline_cache_control_features.pNext = create_info_next;
1127
pipeline_cache_control_features.pipelineCreationCacheControl = pipeline_cache_control_support;
1128
create_info_next = &pipeline_cache_control_features;
1129
}
1130
1131
VkPhysicalDeviceFaultFeaturesEXT device_fault_features = {};
1132
if (device_fault_support) {
1133
device_fault_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FAULT_FEATURES_EXT;
1134
device_fault_features.pNext = create_info_next;
1135
create_info_next = &device_fault_features;
1136
}
1137
1138
#if defined(VK_TRACK_DEVICE_MEMORY)
1139
VkDeviceDeviceMemoryReportCreateInfoEXT memory_report_info = {};
1140
if (device_memory_report_support) {
1141
memory_report_info.sType = VK_STRUCTURE_TYPE_DEVICE_DEVICE_MEMORY_REPORT_CREATE_INFO_EXT;
1142
memory_report_info.pfnUserCallback = RenderingContextDriverVulkan::memory_report_callback;
1143
memory_report_info.pNext = create_info_next;
1144
memory_report_info.flags = 0;
1145
memory_report_info.pUserData = this;
1146
1147
create_info_next = &memory_report_info;
1148
}
1149
#endif
1150
1151
VkPhysicalDeviceVulkan11Features vulkan_1_1_features = {};
1152
VkPhysicalDevice16BitStorageFeaturesKHR storage_features = {};
1153
VkPhysicalDeviceMultiviewFeatures multiview_features = {};
1154
const bool enable_1_2_features = physical_device_properties.apiVersion >= VK_API_VERSION_1_2;
1155
if (enable_1_2_features) {
1156
// In Vulkan 1.2 and newer we use a newer struct to enable various features.
1157
vulkan_1_1_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES;
1158
vulkan_1_1_features.pNext = create_info_next;
1159
vulkan_1_1_features.storageBuffer16BitAccess = storage_buffer_capabilities.storage_buffer_16_bit_access_is_supported;
1160
vulkan_1_1_features.uniformAndStorageBuffer16BitAccess = storage_buffer_capabilities.uniform_and_storage_buffer_16_bit_access_is_supported;
1161
vulkan_1_1_features.storagePushConstant16 = storage_buffer_capabilities.storage_push_constant_16_is_supported;
1162
vulkan_1_1_features.storageInputOutput16 = storage_buffer_capabilities.storage_input_output_16;
1163
vulkan_1_1_features.multiview = multiview_capabilities.is_supported;
1164
vulkan_1_1_features.multiviewGeometryShader = multiview_capabilities.geometry_shader_is_supported;
1165
vulkan_1_1_features.multiviewTessellationShader = multiview_capabilities.tessellation_shader_is_supported;
1166
vulkan_1_1_features.variablePointersStorageBuffer = 0;
1167
vulkan_1_1_features.variablePointers = 0;
1168
vulkan_1_1_features.protectedMemory = 0;
1169
vulkan_1_1_features.samplerYcbcrConversion = 0;
1170
vulkan_1_1_features.shaderDrawParameters = 0;
1171
create_info_next = &vulkan_1_1_features;
1172
} else {
1173
// On Vulkan 1.0 and 1.1 we use our older structs to initialize these features.
1174
storage_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR;
1175
storage_features.pNext = create_info_next;
1176
storage_features.storageBuffer16BitAccess = storage_buffer_capabilities.storage_buffer_16_bit_access_is_supported;
1177
storage_features.uniformAndStorageBuffer16BitAccess = storage_buffer_capabilities.uniform_and_storage_buffer_16_bit_access_is_supported;
1178
storage_features.storagePushConstant16 = storage_buffer_capabilities.storage_push_constant_16_is_supported;
1179
storage_features.storageInputOutput16 = storage_buffer_capabilities.storage_input_output_16;
1180
create_info_next = &storage_features;
1181
1182
const bool enable_1_1_features = physical_device_properties.apiVersion >= VK_API_VERSION_1_1;
1183
if (enable_1_1_features) {
1184
multiview_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES;
1185
multiview_features.pNext = create_info_next;
1186
multiview_features.multiview = multiview_capabilities.is_supported;
1187
multiview_features.multiviewGeometryShader = multiview_capabilities.geometry_shader_is_supported;
1188
multiview_features.multiviewTessellationShader = multiview_capabilities.tessellation_shader_is_supported;
1189
create_info_next = &multiview_features;
1190
}
1191
}
1192
1193
VkDeviceCreateInfo create_info = {};
1194
create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
1195
create_info.pNext = create_info_next;
1196
create_info.queueCreateInfoCount = p_queue_create_info.size();
1197
create_info.pQueueCreateInfos = p_queue_create_info.ptr();
1198
create_info.enabledExtensionCount = enabled_extension_names.size();
1199
create_info.ppEnabledExtensionNames = enabled_extension_names.ptr();
1200
create_info.pEnabledFeatures = &requested_device_features;
1201
1202
if (VulkanHooks::get_singleton() != nullptr) {
1203
bool device_created = VulkanHooks::get_singleton()->create_vulkan_device(&create_info, &vk_device);
1204
ERR_FAIL_COND_V(!device_created, ERR_CANT_CREATE);
1205
} else {
1206
VkResult err = vkCreateDevice(physical_device, &create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_DEVICE), &vk_device);
1207
ERR_FAIL_COND_V(err != VK_SUCCESS, ERR_CANT_CREATE);
1208
}
1209
1210
for (uint32_t i = 0; i < queue_families.size(); i++) {
1211
for (uint32_t j = 0; j < queue_families[i].size(); j++) {
1212
vkGetDeviceQueue(vk_device, i, j, &queue_families[i][j].queue);
1213
}
1214
}
1215
1216
const RenderingContextDriverVulkan::Functions &functions = context_driver->functions_get();
1217
if (functions.GetDeviceProcAddr != nullptr) {
1218
device_functions.CreateSwapchainKHR = PFN_vkCreateSwapchainKHR(functions.GetDeviceProcAddr(vk_device, "vkCreateSwapchainKHR"));
1219
device_functions.DestroySwapchainKHR = PFN_vkDestroySwapchainKHR(functions.GetDeviceProcAddr(vk_device, "vkDestroySwapchainKHR"));
1220
device_functions.GetSwapchainImagesKHR = PFN_vkGetSwapchainImagesKHR(functions.GetDeviceProcAddr(vk_device, "vkGetSwapchainImagesKHR"));
1221
device_functions.AcquireNextImageKHR = PFN_vkAcquireNextImageKHR(functions.GetDeviceProcAddr(vk_device, "vkAcquireNextImageKHR"));
1222
device_functions.QueuePresentKHR = PFN_vkQueuePresentKHR(functions.GetDeviceProcAddr(vk_device, "vkQueuePresentKHR"));
1223
1224
if (enabled_device_extension_names.has(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME)) {
1225
device_functions.CreateRenderPass2KHR = PFN_vkCreateRenderPass2KHR(functions.GetDeviceProcAddr(vk_device, "vkCreateRenderPass2KHR"));
1226
device_functions.EndRenderPass2KHR = PFN_vkCmdEndRenderPass2KHR(functions.GetDeviceProcAddr(vk_device, "vkCmdEndRenderPass2KHR"));
1227
}
1228
1229
// Debug marker extensions.
1230
if (enabled_device_extension_names.has(VK_EXT_DEBUG_MARKER_EXTENSION_NAME)) {
1231
device_functions.CmdDebugMarkerBeginEXT = (PFN_vkCmdDebugMarkerBeginEXT)functions.GetDeviceProcAddr(vk_device, "vkCmdDebugMarkerBeginEXT");
1232
device_functions.CmdDebugMarkerEndEXT = (PFN_vkCmdDebugMarkerEndEXT)functions.GetDeviceProcAddr(vk_device, "vkCmdDebugMarkerEndEXT");
1233
device_functions.CmdDebugMarkerInsertEXT = (PFN_vkCmdDebugMarkerInsertEXT)functions.GetDeviceProcAddr(vk_device, "vkCmdDebugMarkerInsertEXT");
1234
device_functions.DebugMarkerSetObjectNameEXT = (PFN_vkDebugMarkerSetObjectNameEXT)functions.GetDeviceProcAddr(vk_device, "vkDebugMarkerSetObjectNameEXT");
1235
}
1236
1237
// Debug device fault extension.
1238
if (device_fault_support) {
1239
device_functions.GetDeviceFaultInfoEXT = (PFN_vkGetDeviceFaultInfoEXT)functions.GetDeviceProcAddr(vk_device, "vkGetDeviceFaultInfoEXT");
1240
}
1241
}
1242
1243
return OK;
1244
}
1245
1246
Error RenderingDeviceDriverVulkan::_initialize_allocator() {
1247
VmaAllocatorCreateInfo allocator_info = {};
1248
allocator_info.physicalDevice = physical_device;
1249
allocator_info.device = vk_device;
1250
allocator_info.instance = context_driver->instance_get();
1251
const bool use_1_3_features = physical_device_properties.apiVersion >= VK_API_VERSION_1_3;
1252
if (use_1_3_features) {
1253
allocator_info.flags |= VMA_ALLOCATOR_CREATE_KHR_MAINTENANCE5_BIT;
1254
}
1255
if (buffer_device_address_support) {
1256
allocator_info.flags |= VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT;
1257
}
1258
VkResult err = vmaCreateAllocator(&allocator_info, &allocator);
1259
ERR_FAIL_COND_V_MSG(err, ERR_CANT_CREATE, "vmaCreateAllocator failed with error " + itos(err) + ".");
1260
1261
return OK;
1262
}
1263
1264
Error RenderingDeviceDriverVulkan::_initialize_pipeline_cache() {
1265
pipelines_cache.buffer.resize(sizeof(PipelineCacheHeader));
1266
PipelineCacheHeader *header = (PipelineCacheHeader *)(pipelines_cache.buffer.ptrw());
1267
*header = {};
1268
header->magic = 868 + VK_PIPELINE_CACHE_HEADER_VERSION_ONE;
1269
header->device_id = physical_device_properties.deviceID;
1270
header->vendor_id = physical_device_properties.vendorID;
1271
header->driver_version = physical_device_properties.driverVersion;
1272
memcpy(header->uuid, physical_device_properties.pipelineCacheUUID, VK_UUID_SIZE);
1273
header->driver_abi = sizeof(void *);
1274
1275
pipeline_cache_id = String::hex_encode_buffer(physical_device_properties.pipelineCacheUUID, VK_UUID_SIZE);
1276
pipeline_cache_id += "-driver-" + itos(physical_device_properties.driverVersion);
1277
1278
return OK;
1279
}
1280
1281
static void _convert_subpass_attachments(const VkAttachmentReference2 *p_attachment_references_2, uint32_t p_attachment_references_count, TightLocalVector<VkAttachmentReference> &r_attachment_references) {
1282
r_attachment_references.resize(p_attachment_references_count);
1283
for (uint32_t i = 0; i < p_attachment_references_count; i++) {
1284
// Ignore sType, pNext and aspectMask (which is currently unused).
1285
r_attachment_references[i].attachment = p_attachment_references_2[i].attachment;
1286
r_attachment_references[i].layout = p_attachment_references_2[i].layout;
1287
}
1288
}
1289
1290
VkResult RenderingDeviceDriverVulkan::_create_render_pass(VkDevice p_device, const VkRenderPassCreateInfo2 *p_create_info, const VkAllocationCallbacks *p_allocator, VkRenderPass *p_render_pass) {
1291
if (device_functions.CreateRenderPass2KHR != nullptr) {
1292
return device_functions.CreateRenderPass2KHR(p_device, p_create_info, p_allocator, p_render_pass);
1293
} else {
1294
// Compatibility fallback with regular create render pass but by converting the inputs from the newer version to the older one.
1295
TightLocalVector<VkAttachmentDescription> attachments;
1296
attachments.resize(p_create_info->attachmentCount);
1297
for (uint32_t i = 0; i < p_create_info->attachmentCount; i++) {
1298
// Ignores sType and pNext from the attachment.
1299
const VkAttachmentDescription2 &src = p_create_info->pAttachments[i];
1300
VkAttachmentDescription &dst = attachments[i];
1301
dst.flags = src.flags;
1302
dst.format = src.format;
1303
dst.samples = src.samples;
1304
dst.loadOp = src.loadOp;
1305
dst.storeOp = src.storeOp;
1306
dst.stencilLoadOp = src.stencilLoadOp;
1307
dst.stencilStoreOp = src.stencilStoreOp;
1308
dst.initialLayout = src.initialLayout;
1309
dst.finalLayout = src.finalLayout;
1310
}
1311
1312
const uint32_t attachment_vectors_per_subpass = 4;
1313
TightLocalVector<TightLocalVector<VkAttachmentReference>> subpasses_attachments;
1314
TightLocalVector<VkSubpassDescription> subpasses;
1315
subpasses_attachments.resize(p_create_info->subpassCount * attachment_vectors_per_subpass);
1316
subpasses.resize(p_create_info->subpassCount);
1317
1318
for (uint32_t i = 0; i < p_create_info->subpassCount; i++) {
1319
const uint32_t vector_base_index = i * attachment_vectors_per_subpass;
1320
const uint32_t input_attachments_index = vector_base_index + 0;
1321
const uint32_t color_attachments_index = vector_base_index + 1;
1322
const uint32_t resolve_attachments_index = vector_base_index + 2;
1323
const uint32_t depth_attachment_index = vector_base_index + 3;
1324
_convert_subpass_attachments(p_create_info->pSubpasses[i].pInputAttachments, p_create_info->pSubpasses[i].inputAttachmentCount, subpasses_attachments[input_attachments_index]);
1325
_convert_subpass_attachments(p_create_info->pSubpasses[i].pColorAttachments, p_create_info->pSubpasses[i].colorAttachmentCount, subpasses_attachments[color_attachments_index]);
1326
_convert_subpass_attachments(p_create_info->pSubpasses[i].pResolveAttachments, (p_create_info->pSubpasses[i].pResolveAttachments != nullptr) ? p_create_info->pSubpasses[i].colorAttachmentCount : 0, subpasses_attachments[resolve_attachments_index]);
1327
_convert_subpass_attachments(p_create_info->pSubpasses[i].pDepthStencilAttachment, (p_create_info->pSubpasses[i].pDepthStencilAttachment != nullptr) ? 1 : 0, subpasses_attachments[depth_attachment_index]);
1328
1329
// Ignores sType and pNext from the subpass.
1330
const VkSubpassDescription2 &src_subpass = p_create_info->pSubpasses[i];
1331
VkSubpassDescription &dst_subpass = subpasses[i];
1332
dst_subpass.flags = src_subpass.flags;
1333
dst_subpass.pipelineBindPoint = src_subpass.pipelineBindPoint;
1334
dst_subpass.inputAttachmentCount = src_subpass.inputAttachmentCount;
1335
dst_subpass.pInputAttachments = subpasses_attachments[input_attachments_index].ptr();
1336
dst_subpass.colorAttachmentCount = src_subpass.colorAttachmentCount;
1337
dst_subpass.pColorAttachments = subpasses_attachments[color_attachments_index].ptr();
1338
dst_subpass.pResolveAttachments = subpasses_attachments[resolve_attachments_index].ptr();
1339
dst_subpass.pDepthStencilAttachment = subpasses_attachments[depth_attachment_index].ptr();
1340
dst_subpass.preserveAttachmentCount = src_subpass.preserveAttachmentCount;
1341
dst_subpass.pPreserveAttachments = src_subpass.pPreserveAttachments;
1342
}
1343
1344
TightLocalVector<VkSubpassDependency> dependencies;
1345
dependencies.resize(p_create_info->dependencyCount);
1346
1347
for (uint32_t i = 0; i < p_create_info->dependencyCount; i++) {
1348
// Ignores sType and pNext from the dependency, and viewMask which is currently unused.
1349
const VkSubpassDependency2 &src_dependency = p_create_info->pDependencies[i];
1350
VkSubpassDependency &dst_dependency = dependencies[i];
1351
dst_dependency.srcSubpass = src_dependency.srcSubpass;
1352
dst_dependency.dstSubpass = src_dependency.dstSubpass;
1353
dst_dependency.srcStageMask = src_dependency.srcStageMask;
1354
dst_dependency.dstStageMask = src_dependency.dstStageMask;
1355
dst_dependency.srcAccessMask = src_dependency.srcAccessMask;
1356
dst_dependency.dstAccessMask = src_dependency.dstAccessMask;
1357
dst_dependency.dependencyFlags = src_dependency.dependencyFlags;
1358
}
1359
1360
VkRenderPassCreateInfo create_info = {};
1361
create_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
1362
create_info.pNext = p_create_info->pNext;
1363
create_info.flags = p_create_info->flags;
1364
create_info.attachmentCount = attachments.size();
1365
create_info.pAttachments = attachments.ptr();
1366
create_info.subpassCount = subpasses.size();
1367
create_info.pSubpasses = subpasses.ptr();
1368
create_info.dependencyCount = dependencies.size();
1369
create_info.pDependencies = dependencies.ptr();
1370
return vkCreateRenderPass(vk_device, &create_info, p_allocator, p_render_pass);
1371
}
1372
}
1373
1374
bool RenderingDeviceDriverVulkan::_release_image_semaphore(CommandQueue *p_command_queue, uint32_t p_semaphore_index, bool p_release_on_swap_chain) {
1375
SwapChain *swap_chain = p_command_queue->image_semaphores_swap_chains[p_semaphore_index];
1376
if (swap_chain != nullptr) {
1377
// Clear the swap chain from the command queue's vector.
1378
p_command_queue->image_semaphores_swap_chains[p_semaphore_index] = nullptr;
1379
1380
if (p_release_on_swap_chain) {
1381
// Remove the acquired semaphore from the swap chain's vectors.
1382
for (uint32_t i = 0; i < swap_chain->command_queues_acquired.size(); i++) {
1383
if (swap_chain->command_queues_acquired[i] == p_command_queue && swap_chain->command_queues_acquired_semaphores[i] == p_semaphore_index) {
1384
swap_chain->command_queues_acquired.remove_at(i);
1385
swap_chain->command_queues_acquired_semaphores.remove_at(i);
1386
break;
1387
}
1388
}
1389
}
1390
1391
return true;
1392
}
1393
1394
return false;
1395
}
1396
1397
bool RenderingDeviceDriverVulkan::_recreate_image_semaphore(CommandQueue *p_command_queue, uint32_t p_semaphore_index, bool p_release_on_swap_chain) {
1398
_release_image_semaphore(p_command_queue, p_semaphore_index, p_release_on_swap_chain);
1399
1400
VkSemaphore semaphore;
1401
VkSemaphoreCreateInfo create_info = {};
1402
create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
1403
VkResult err = vkCreateSemaphore(vk_device, &create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_SEMAPHORE), &semaphore);
1404
ERR_FAIL_COND_V(err != VK_SUCCESS, false);
1405
1406
// Indicate the semaphore is free again and destroy the previous one before storing the new one.
1407
vkDestroySemaphore(vk_device, p_command_queue->image_semaphores[p_semaphore_index], VKC::get_allocation_callbacks(VK_OBJECT_TYPE_SEMAPHORE));
1408
1409
p_command_queue->image_semaphores[p_semaphore_index] = semaphore;
1410
p_command_queue->free_image_semaphores.push_back(p_semaphore_index);
1411
1412
return true;
1413
}
1414
// Debug marker extensions.
1415
VkDebugReportObjectTypeEXT RenderingDeviceDriverVulkan::_convert_to_debug_report_objectType(VkObjectType p_object_type) {
1416
switch (p_object_type) {
1417
case VK_OBJECT_TYPE_UNKNOWN:
1418
return VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT;
1419
case VK_OBJECT_TYPE_INSTANCE:
1420
return VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT;
1421
case VK_OBJECT_TYPE_PHYSICAL_DEVICE:
1422
return VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT;
1423
case VK_OBJECT_TYPE_DEVICE:
1424
return VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT;
1425
case VK_OBJECT_TYPE_QUEUE:
1426
return VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT;
1427
case VK_OBJECT_TYPE_SEMAPHORE:
1428
return VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT;
1429
case VK_OBJECT_TYPE_COMMAND_BUFFER:
1430
return VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT;
1431
case VK_OBJECT_TYPE_FENCE:
1432
return VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT;
1433
case VK_OBJECT_TYPE_DEVICE_MEMORY:
1434
return VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT;
1435
case VK_OBJECT_TYPE_BUFFER:
1436
return VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT;
1437
case VK_OBJECT_TYPE_IMAGE:
1438
return VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT;
1439
case VK_OBJECT_TYPE_EVENT:
1440
return VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT;
1441
case VK_OBJECT_TYPE_QUERY_POOL:
1442
return VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT;
1443
case VK_OBJECT_TYPE_BUFFER_VIEW:
1444
return VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT;
1445
case VK_OBJECT_TYPE_IMAGE_VIEW:
1446
return VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT;
1447
case VK_OBJECT_TYPE_SHADER_MODULE:
1448
return VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT;
1449
case VK_OBJECT_TYPE_PIPELINE_CACHE:
1450
return VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT;
1451
case VK_OBJECT_TYPE_PIPELINE_LAYOUT:
1452
return VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT;
1453
case VK_OBJECT_TYPE_RENDER_PASS:
1454
return VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT;
1455
case VK_OBJECT_TYPE_PIPELINE:
1456
return VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT;
1457
case VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT:
1458
return VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT;
1459
case VK_OBJECT_TYPE_SAMPLER:
1460
return VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT;
1461
case VK_OBJECT_TYPE_DESCRIPTOR_POOL:
1462
return VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT;
1463
case VK_OBJECT_TYPE_DESCRIPTOR_SET:
1464
return VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT;
1465
case VK_OBJECT_TYPE_FRAMEBUFFER:
1466
return VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT;
1467
case VK_OBJECT_TYPE_COMMAND_POOL:
1468
return VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT;
1469
case VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION:
1470
return VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_EXT;
1471
case VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE:
1472
return VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_EXT;
1473
case VK_OBJECT_TYPE_SURFACE_KHR:
1474
return VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT;
1475
case VK_OBJECT_TYPE_SWAPCHAIN_KHR:
1476
return VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT;
1477
case VK_OBJECT_TYPE_DISPLAY_KHR:
1478
return VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_KHR_EXT;
1479
case VK_OBJECT_TYPE_DISPLAY_MODE_KHR:
1480
return VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_MODE_KHR_EXT;
1481
case VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT:
1482
return VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT_EXT;
1483
case VK_OBJECT_TYPE_CU_MODULE_NVX:
1484
return VK_DEBUG_REPORT_OBJECT_TYPE_CU_MODULE_NVX_EXT;
1485
case VK_OBJECT_TYPE_CU_FUNCTION_NVX:
1486
return VK_DEBUG_REPORT_OBJECT_TYPE_CU_FUNCTION_NVX_EXT;
1487
case VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR:
1488
return VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR_EXT;
1489
case VK_OBJECT_TYPE_VALIDATION_CACHE_EXT:
1490
return VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT_EXT;
1491
case VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV:
1492
return VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV_EXT;
1493
default:
1494
break;
1495
}
1496
1497
return VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT;
1498
}
1499
1500
void RenderingDeviceDriverVulkan::_set_object_name(VkObjectType p_object_type, uint64_t p_object_handle, String p_object_name) {
1501
const RenderingContextDriverVulkan::Functions &functions = context_driver->functions_get();
1502
if (functions.SetDebugUtilsObjectNameEXT != nullptr) {
1503
CharString obj_data = p_object_name.utf8();
1504
VkDebugUtilsObjectNameInfoEXT name_info;
1505
name_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT;
1506
name_info.pNext = nullptr;
1507
name_info.objectType = p_object_type;
1508
name_info.objectHandle = p_object_handle;
1509
name_info.pObjectName = obj_data.get_data();
1510
functions.SetDebugUtilsObjectNameEXT(vk_device, &name_info);
1511
} else if (functions.DebugMarkerSetObjectNameEXT != nullptr) {
1512
// Debug marker extensions.
1513
CharString obj_data = p_object_name.utf8();
1514
VkDebugMarkerObjectNameInfoEXT name_info;
1515
name_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT;
1516
name_info.pNext = nullptr;
1517
name_info.objectType = _convert_to_debug_report_objectType(p_object_type);
1518
name_info.object = p_object_handle;
1519
name_info.pObjectName = obj_data.get_data();
1520
functions.DebugMarkerSetObjectNameEXT(vk_device, &name_info);
1521
}
1522
}
1523
1524
Error RenderingDeviceDriverVulkan::initialize(uint32_t p_device_index, uint32_t p_frame_count) {
1525
context_device = context_driver->device_get(p_device_index);
1526
physical_device = context_driver->physical_device_get(p_device_index);
1527
vkGetPhysicalDeviceProperties(physical_device, &physical_device_properties);
1528
1529
// Workaround a driver bug on Adreno 730 GPUs that keeps leaking memory on each call to vkResetDescriptorPool.
1530
// Which eventually run out of memory. In such case we should not be using linear allocated pools
1531
// Bug introduced in driver 512.597.0 and fixed in 512.671.0.
1532
// Confirmed by Qualcomm.
1533
if (linear_descriptor_pools_enabled) {
1534
const uint32_t reset_descriptor_pool_broken_driver_begin = VK_MAKE_VERSION(512u, 597u, 0u);
1535
const uint32_t reset_descriptor_pool_fixed_driver_begin = VK_MAKE_VERSION(512u, 671u, 0u);
1536
linear_descriptor_pools_enabled = physical_device_properties.driverVersion < reset_descriptor_pool_broken_driver_begin || physical_device_properties.driverVersion > reset_descriptor_pool_fixed_driver_begin;
1537
}
1538
frame_count = p_frame_count;
1539
1540
// Copy the queue family properties the context already retrieved.
1541
uint32_t queue_family_count = context_driver->queue_family_get_count(p_device_index);
1542
queue_family_properties.resize(queue_family_count);
1543
for (uint32_t i = 0; i < queue_family_count; i++) {
1544
queue_family_properties[i] = context_driver->queue_family_get(p_device_index, i);
1545
}
1546
1547
Error err = _initialize_device_extensions();
1548
ERR_FAIL_COND_V(err != OK, err);
1549
1550
err = _check_device_features();
1551
ERR_FAIL_COND_V(err != OK, err);
1552
1553
err = _check_device_capabilities();
1554
ERR_FAIL_COND_V(err != OK, err);
1555
1556
LocalVector<VkDeviceQueueCreateInfo> queue_create_info;
1557
err = _add_queue_create_info(queue_create_info);
1558
ERR_FAIL_COND_V(err != OK, err);
1559
1560
err = _initialize_device(queue_create_info);
1561
ERR_FAIL_COND_V(err != OK, err);
1562
1563
err = _initialize_allocator();
1564
ERR_FAIL_COND_V(err != OK, err);
1565
1566
err = _initialize_pipeline_cache();
1567
ERR_FAIL_COND_V(err != OK, err);
1568
1569
max_descriptor_sets_per_pool = GLOBAL_GET("rendering/rendering_device/vulkan/max_descriptors_per_pool");
1570
1571
#if defined(DEBUG_ENABLED) || defined(DEV_ENABLED)
1572
breadcrumb_buffer = buffer_create(2u * sizeof(uint32_t) * BREADCRUMB_BUFFER_ENTRIES, BufferUsageBits::BUFFER_USAGE_TRANSFER_TO_BIT, MemoryAllocationType::MEMORY_ALLOCATION_TYPE_CPU);
1573
#endif
1574
1575
#if defined(SWAPPY_FRAME_PACING_ENABLED)
1576
swappy_frame_pacer_enable = GLOBAL_GET("display/window/frame_pacing/android/enable_frame_pacing");
1577
swappy_mode = GLOBAL_GET("display/window/frame_pacing/android/swappy_mode");
1578
1579
if (VulkanHooks::get_singleton() != nullptr) {
1580
// Hooks control device creation & possibly presentation
1581
// (e.g. OpenXR) thus it's too risky to use Swappy.
1582
swappy_frame_pacer_enable = false;
1583
OS::get_singleton()->print("VulkanHooks detected (e.g. OpenXR): Force-disabling Swappy Frame Pacing.\n");
1584
}
1585
#endif
1586
1587
shader_container_format.set_debug_info_enabled(Engine::get_singleton()->is_generate_spirv_debug_info_enabled());
1588
1589
return OK;
1590
}
1591
1592
/****************/
1593
/**** MEMORY ****/
1594
/****************/
1595
1596
static const uint32_t SMALL_ALLOCATION_MAX_SIZE = 4096;
1597
1598
VmaPool RenderingDeviceDriverVulkan::_find_or_create_small_allocs_pool(uint32_t p_mem_type_index) {
1599
if (small_allocs_pools.has(p_mem_type_index)) {
1600
return small_allocs_pools[p_mem_type_index];
1601
}
1602
1603
print_verbose("Creating VMA small objects pool for memory type index " + itos(p_mem_type_index));
1604
1605
VmaPoolCreateInfo pci = {};
1606
pci.memoryTypeIndex = p_mem_type_index;
1607
pci.flags = 0;
1608
pci.blockSize = 0;
1609
pci.minBlockCount = 0;
1610
pci.maxBlockCount = SIZE_MAX;
1611
pci.priority = 0.5f;
1612
pci.minAllocationAlignment = 0;
1613
pci.pMemoryAllocateNext = nullptr;
1614
VmaPool pool = VK_NULL_HANDLE;
1615
VkResult res = vmaCreatePool(allocator, &pci, &pool);
1616
small_allocs_pools[p_mem_type_index] = pool; // Don't try to create it again if failed the first time.
1617
ERR_FAIL_COND_V_MSG(res, pool, "vmaCreatePool failed with error " + itos(res) + ".");
1618
1619
return pool;
1620
}
1621
1622
/*****************/
1623
/**** BUFFERS ****/
1624
/*****************/
1625
1626
// RDD::BufferUsageBits == VkBufferUsageFlagBits.
1627
static_assert(ENUM_MEMBERS_EQUAL(RDD::BUFFER_USAGE_TRANSFER_FROM_BIT, VK_BUFFER_USAGE_TRANSFER_SRC_BIT));
1628
static_assert(ENUM_MEMBERS_EQUAL(RDD::BUFFER_USAGE_TRANSFER_TO_BIT, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
1629
static_assert(ENUM_MEMBERS_EQUAL(RDD::BUFFER_USAGE_TEXEL_BIT, VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT));
1630
static_assert(ENUM_MEMBERS_EQUAL(RDD::BUFFER_USAGE_UNIFORM_BIT, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT));
1631
static_assert(ENUM_MEMBERS_EQUAL(RDD::BUFFER_USAGE_STORAGE_BIT, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT));
1632
static_assert(ENUM_MEMBERS_EQUAL(RDD::BUFFER_USAGE_INDEX_BIT, VK_BUFFER_USAGE_INDEX_BUFFER_BIT));
1633
static_assert(ENUM_MEMBERS_EQUAL(RDD::BUFFER_USAGE_VERTEX_BIT, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT));
1634
static_assert(ENUM_MEMBERS_EQUAL(RDD::BUFFER_USAGE_INDIRECT_BIT, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT));
1635
static_assert(ENUM_MEMBERS_EQUAL(RDD::BUFFER_USAGE_DEVICE_ADDRESS_BIT, VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT));
1636
1637
RDD::BufferID RenderingDeviceDriverVulkan::buffer_create(uint64_t p_size, BitField<BufferUsageBits> p_usage, MemoryAllocationType p_allocation_type) {
1638
VkBufferCreateInfo create_info = {};
1639
create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
1640
create_info.size = p_size;
1641
create_info.usage = p_usage;
1642
create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
1643
1644
VmaMemoryUsage vma_usage = VMA_MEMORY_USAGE_UNKNOWN;
1645
uint32_t vma_flags_to_remove = 0;
1646
1647
VmaAllocationCreateInfo alloc_create_info = {};
1648
switch (p_allocation_type) {
1649
case MEMORY_ALLOCATION_TYPE_CPU: {
1650
bool is_src = p_usage.has_flag(BUFFER_USAGE_TRANSFER_FROM_BIT);
1651
bool is_dst = p_usage.has_flag(BUFFER_USAGE_TRANSFER_TO_BIT);
1652
if (is_src && !is_dst) {
1653
// Looks like a staging buffer: CPU maps, writes sequentially, then GPU copies to VRAM.
1654
alloc_create_info.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT;
1655
alloc_create_info.preferredFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
1656
vma_flags_to_remove |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
1657
}
1658
if (is_dst && !is_src) {
1659
// Looks like a readback buffer: GPU copies from VRAM, then CPU maps and reads.
1660
alloc_create_info.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT;
1661
alloc_create_info.preferredFlags |= VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
1662
vma_flags_to_remove |= VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
1663
}
1664
vma_usage = VMA_MEMORY_USAGE_AUTO_PREFER_HOST;
1665
alloc_create_info.requiredFlags = (VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
1666
} break;
1667
case MEMORY_ALLOCATION_TYPE_GPU: {
1668
vma_usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE;
1669
if (!Engine::get_singleton()->is_extra_gpu_memory_tracking_enabled()) {
1670
// We must set it right now or else vmaFindMemoryTypeIndexForBufferInfo will use wrong parameters.
1671
alloc_create_info.usage = vma_usage;
1672
}
1673
alloc_create_info.preferredFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
1674
if (p_size <= SMALL_ALLOCATION_MAX_SIZE) {
1675
uint32_t mem_type_index = 0;
1676
vmaFindMemoryTypeIndexForBufferInfo(allocator, &create_info, &alloc_create_info, &mem_type_index);
1677
alloc_create_info.pool = _find_or_create_small_allocs_pool(mem_type_index);
1678
}
1679
} break;
1680
}
1681
1682
VkBuffer vk_buffer = VK_NULL_HANDLE;
1683
VmaAllocation allocation = nullptr;
1684
VmaAllocationInfo alloc_info = {};
1685
1686
if (!Engine::get_singleton()->is_extra_gpu_memory_tracking_enabled()) {
1687
alloc_create_info.preferredFlags &= ~vma_flags_to_remove;
1688
alloc_create_info.usage = vma_usage;
1689
VkResult err = vmaCreateBuffer(allocator, &create_info, &alloc_create_info, &vk_buffer, &allocation, &alloc_info);
1690
ERR_FAIL_COND_V_MSG(err, BufferID(), "Can't create buffer of size: " + itos(p_size) + ", error " + itos(err) + ".");
1691
} else {
1692
VkResult err = vkCreateBuffer(vk_device, &create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_BUFFER), &vk_buffer);
1693
ERR_FAIL_COND_V_MSG(err, BufferID(), "Can't create buffer of size: " + itos(p_size) + ", error " + itos(err) + ".");
1694
err = vmaAllocateMemoryForBuffer(allocator, vk_buffer, &alloc_create_info, &allocation, &alloc_info);
1695
ERR_FAIL_COND_V_MSG(err, BufferID(), "Can't allocate memory for buffer of size: " + itos(p_size) + ", error " + itos(err) + ".");
1696
err = vmaBindBufferMemory2(allocator, allocation, 0, vk_buffer, nullptr);
1697
ERR_FAIL_COND_V_MSG(err, BufferID(), "Can't bind memory to buffer of size: " + itos(p_size) + ", error " + itos(err) + ".");
1698
}
1699
1700
// Bookkeep.
1701
BufferInfo *buf_info = VersatileResource::allocate<BufferInfo>(resources_allocator);
1702
buf_info->vk_buffer = vk_buffer;
1703
buf_info->allocation.handle = allocation;
1704
buf_info->allocation.size = alloc_info.size;
1705
buf_info->size = p_size;
1706
1707
return BufferID(buf_info);
1708
}
1709
1710
bool RenderingDeviceDriverVulkan::buffer_set_texel_format(BufferID p_buffer, DataFormat p_format) {
1711
BufferInfo *buf_info = (BufferInfo *)p_buffer.id;
1712
1713
DEV_ASSERT(!buf_info->vk_view);
1714
1715
VkBufferViewCreateInfo view_create_info = {};
1716
view_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
1717
view_create_info.buffer = buf_info->vk_buffer;
1718
view_create_info.format = RD_TO_VK_FORMAT[p_format];
1719
view_create_info.range = buf_info->allocation.size;
1720
1721
VkResult res = vkCreateBufferView(vk_device, &view_create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_BUFFER_VIEW), &buf_info->vk_view);
1722
ERR_FAIL_COND_V_MSG(res, false, "Unable to create buffer view, error " + itos(res) + ".");
1723
1724
return true;
1725
}
1726
1727
void RenderingDeviceDriverVulkan::buffer_free(BufferID p_buffer) {
1728
BufferInfo *buf_info = (BufferInfo *)p_buffer.id;
1729
if (buf_info->vk_view) {
1730
vkDestroyBufferView(vk_device, buf_info->vk_view, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_BUFFER_VIEW));
1731
}
1732
1733
if (!Engine::get_singleton()->is_extra_gpu_memory_tracking_enabled()) {
1734
vmaDestroyBuffer(allocator, buf_info->vk_buffer, buf_info->allocation.handle);
1735
} else {
1736
vkDestroyBuffer(vk_device, buf_info->vk_buffer, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_BUFFER));
1737
vmaFreeMemory(allocator, buf_info->allocation.handle);
1738
}
1739
1740
VersatileResource::free(resources_allocator, buf_info);
1741
}
1742
1743
uint64_t RenderingDeviceDriverVulkan::buffer_get_allocation_size(BufferID p_buffer) {
1744
const BufferInfo *buf_info = (const BufferInfo *)p_buffer.id;
1745
return buf_info->allocation.size;
1746
}
1747
1748
uint8_t *RenderingDeviceDriverVulkan::buffer_map(BufferID p_buffer) {
1749
const BufferInfo *buf_info = (const BufferInfo *)p_buffer.id;
1750
void *data_ptr = nullptr;
1751
VkResult err = vmaMapMemory(allocator, buf_info->allocation.handle, &data_ptr);
1752
ERR_FAIL_COND_V_MSG(err, nullptr, "vmaMapMemory failed with error " + itos(err) + ".");
1753
return (uint8_t *)data_ptr;
1754
}
1755
1756
void RenderingDeviceDriverVulkan::buffer_unmap(BufferID p_buffer) {
1757
const BufferInfo *buf_info = (const BufferInfo *)p_buffer.id;
1758
vmaUnmapMemory(allocator, buf_info->allocation.handle);
1759
}
1760
1761
uint64_t RenderingDeviceDriverVulkan::buffer_get_device_address(BufferID p_buffer) {
1762
const BufferInfo *buf_info = (const BufferInfo *)p_buffer.id;
1763
VkBufferDeviceAddressInfo address_info = {};
1764
address_info.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO;
1765
address_info.pNext = nullptr;
1766
address_info.buffer = buf_info->vk_buffer;
1767
return vkGetBufferDeviceAddress(vk_device, &address_info);
1768
}
1769
1770
/*****************/
1771
/**** TEXTURE ****/
1772
/*****************/
1773
1774
static const VkImageType RD_TEX_TYPE_TO_VK_IMG_TYPE[RDD::TEXTURE_TYPE_MAX] = {
1775
VK_IMAGE_TYPE_1D,
1776
VK_IMAGE_TYPE_2D,
1777
VK_IMAGE_TYPE_3D,
1778
VK_IMAGE_TYPE_2D,
1779
VK_IMAGE_TYPE_1D,
1780
VK_IMAGE_TYPE_2D,
1781
VK_IMAGE_TYPE_2D,
1782
};
1783
1784
static const VkSampleCountFlagBits RD_TO_VK_SAMPLE_COUNT[RDD::TEXTURE_SAMPLES_MAX] = {
1785
VK_SAMPLE_COUNT_1_BIT,
1786
VK_SAMPLE_COUNT_2_BIT,
1787
VK_SAMPLE_COUNT_4_BIT,
1788
VK_SAMPLE_COUNT_8_BIT,
1789
VK_SAMPLE_COUNT_16_BIT,
1790
VK_SAMPLE_COUNT_32_BIT,
1791
VK_SAMPLE_COUNT_64_BIT,
1792
};
1793
1794
// RDD::TextureType == VkImageViewType.
1795
static_assert(ENUM_MEMBERS_EQUAL(RDD::TEXTURE_TYPE_1D, VK_IMAGE_VIEW_TYPE_1D));
1796
static_assert(ENUM_MEMBERS_EQUAL(RDD::TEXTURE_TYPE_2D, VK_IMAGE_VIEW_TYPE_2D));
1797
static_assert(ENUM_MEMBERS_EQUAL(RDD::TEXTURE_TYPE_3D, VK_IMAGE_VIEW_TYPE_3D));
1798
static_assert(ENUM_MEMBERS_EQUAL(RDD::TEXTURE_TYPE_CUBE, VK_IMAGE_VIEW_TYPE_CUBE));
1799
static_assert(ENUM_MEMBERS_EQUAL(RDD::TEXTURE_TYPE_1D_ARRAY, VK_IMAGE_VIEW_TYPE_1D_ARRAY));
1800
static_assert(ENUM_MEMBERS_EQUAL(RDD::TEXTURE_TYPE_2D_ARRAY, VK_IMAGE_VIEW_TYPE_2D_ARRAY));
1801
static_assert(ENUM_MEMBERS_EQUAL(RDD::TEXTURE_TYPE_CUBE_ARRAY, VK_IMAGE_VIEW_TYPE_CUBE_ARRAY));
1802
1803
// RDD::TextureSwizzle == VkComponentSwizzle.
1804
static_assert(ENUM_MEMBERS_EQUAL(RDD::TEXTURE_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY));
1805
static_assert(ENUM_MEMBERS_EQUAL(RDD::TEXTURE_SWIZZLE_ZERO, VK_COMPONENT_SWIZZLE_ZERO));
1806
static_assert(ENUM_MEMBERS_EQUAL(RDD::TEXTURE_SWIZZLE_ONE, VK_COMPONENT_SWIZZLE_ONE));
1807
static_assert(ENUM_MEMBERS_EQUAL(RDD::TEXTURE_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R));
1808
static_assert(ENUM_MEMBERS_EQUAL(RDD::TEXTURE_SWIZZLE_G, VK_COMPONENT_SWIZZLE_G));
1809
static_assert(ENUM_MEMBERS_EQUAL(RDD::TEXTURE_SWIZZLE_B, VK_COMPONENT_SWIZZLE_B));
1810
static_assert(ENUM_MEMBERS_EQUAL(RDD::TEXTURE_SWIZZLE_A, VK_COMPONENT_SWIZZLE_A));
1811
1812
// RDD::TextureAspectBits == VkImageAspectFlagBits.
1813
static_assert(ENUM_MEMBERS_EQUAL(RDD::TEXTURE_ASPECT_COLOR_BIT, VK_IMAGE_ASPECT_COLOR_BIT));
1814
static_assert(ENUM_MEMBERS_EQUAL(RDD::TEXTURE_ASPECT_DEPTH_BIT, VK_IMAGE_ASPECT_DEPTH_BIT));
1815
static_assert(ENUM_MEMBERS_EQUAL(RDD::TEXTURE_ASPECT_STENCIL_BIT, VK_IMAGE_ASPECT_STENCIL_BIT));
1816
1817
VkSampleCountFlagBits RenderingDeviceDriverVulkan::_ensure_supported_sample_count(TextureSamples p_requested_sample_count) {
1818
VkSampleCountFlags sample_count_flags = (physical_device_properties.limits.framebufferColorSampleCounts & physical_device_properties.limits.framebufferDepthSampleCounts);
1819
1820
if ((sample_count_flags & RD_TO_VK_SAMPLE_COUNT[p_requested_sample_count])) {
1821
// The requested sample count is supported.
1822
return RD_TO_VK_SAMPLE_COUNT[p_requested_sample_count];
1823
} else {
1824
// Find the closest lower supported sample count.
1825
VkSampleCountFlagBits sample_count = RD_TO_VK_SAMPLE_COUNT[p_requested_sample_count];
1826
while (sample_count > VK_SAMPLE_COUNT_1_BIT) {
1827
if (sample_count_flags & sample_count) {
1828
return sample_count;
1829
}
1830
sample_count = (VkSampleCountFlagBits)(sample_count >> 1);
1831
}
1832
}
1833
return VK_SAMPLE_COUNT_1_BIT;
1834
}
1835
1836
RDD::TextureID RenderingDeviceDriverVulkan::texture_create(const TextureFormat &p_format, const TextureView &p_view) {
1837
VkImageCreateInfo create_info = {};
1838
create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
1839
1840
if (p_format.shareable_formats.size()) {
1841
create_info.flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
1842
1843
if (enabled_device_extension_names.has(VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME)) {
1844
VkFormat *vk_allowed_formats = ALLOCA_ARRAY(VkFormat, p_format.shareable_formats.size());
1845
for (int i = 0; i < p_format.shareable_formats.size(); i++) {
1846
vk_allowed_formats[i] = RD_TO_VK_FORMAT[p_format.shareable_formats[i]];
1847
}
1848
1849
VkImageFormatListCreateInfoKHR *format_list_create_info = ALLOCA_SINGLE(VkImageFormatListCreateInfoKHR);
1850
*format_list_create_info = {};
1851
format_list_create_info->sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR;
1852
format_list_create_info->viewFormatCount = p_format.shareable_formats.size();
1853
format_list_create_info->pViewFormats = vk_allowed_formats;
1854
1855
create_info.pNext = format_list_create_info;
1856
}
1857
}
1858
1859
if (p_format.texture_type == TEXTURE_TYPE_CUBE || p_format.texture_type == TEXTURE_TYPE_CUBE_ARRAY) {
1860
create_info.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
1861
}
1862
/*if (p_format.texture_type == TEXTURE_TYPE_2D || p_format.texture_type == TEXTURE_TYPE_2D_ARRAY) {
1863
create_info.flags |= VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT;
1864
}*/
1865
1866
create_info.imageType = RD_TEX_TYPE_TO_VK_IMG_TYPE[p_format.texture_type];
1867
1868
create_info.format = RD_TO_VK_FORMAT[p_format.format];
1869
1870
create_info.extent.width = p_format.width;
1871
create_info.extent.height = p_format.height;
1872
create_info.extent.depth = p_format.depth;
1873
1874
create_info.mipLevels = p_format.mipmaps;
1875
create_info.arrayLayers = p_format.array_layers;
1876
1877
create_info.samples = _ensure_supported_sample_count(p_format.samples);
1878
create_info.tiling = (p_format.usage_bits & TEXTURE_USAGE_CPU_READ_BIT) ? VK_IMAGE_TILING_LINEAR : VK_IMAGE_TILING_OPTIMAL;
1879
1880
// Usage.
1881
if ((p_format.usage_bits & TEXTURE_USAGE_SAMPLING_BIT)) {
1882
create_info.usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
1883
}
1884
if ((p_format.usage_bits & TEXTURE_USAGE_STORAGE_BIT)) {
1885
create_info.usage |= VK_IMAGE_USAGE_STORAGE_BIT;
1886
}
1887
if ((p_format.usage_bits & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT)) {
1888
create_info.usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
1889
}
1890
if ((p_format.usage_bits & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
1891
create_info.usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
1892
}
1893
if ((p_format.usage_bits & TEXTURE_USAGE_INPUT_ATTACHMENT_BIT)) {
1894
create_info.usage |= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
1895
}
1896
if ((p_format.usage_bits & TEXTURE_USAGE_VRS_ATTACHMENT_BIT) && (p_format.usage_bits & TEXTURE_USAGE_VRS_FRAGMENT_SHADING_RATE_BIT)) {
1897
create_info.usage |= VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR;
1898
}
1899
if ((p_format.usage_bits & TEXTURE_USAGE_VRS_ATTACHMENT_BIT) && (p_format.usage_bits & TEXTURE_USAGE_VRS_FRAGMENT_DENSITY_MAP_BIT)) {
1900
create_info.usage |= VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT;
1901
}
1902
if ((p_format.usage_bits & TEXTURE_USAGE_CAN_UPDATE_BIT)) {
1903
create_info.usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1904
}
1905
if ((p_format.usage_bits & TEXTURE_USAGE_CAN_COPY_FROM_BIT)) {
1906
create_info.usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1907
}
1908
if ((p_format.usage_bits & TEXTURE_USAGE_CAN_COPY_TO_BIT)) {
1909
create_info.usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1910
}
1911
1912
create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
1913
create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1914
1915
// Allocate memory.
1916
1917
uint32_t width = 0, height = 0;
1918
uint32_t image_size = get_image_format_required_size(p_format.format, p_format.width, p_format.height, p_format.depth, p_format.mipmaps, &width, &height);
1919
1920
VmaAllocationCreateInfo alloc_create_info = {};
1921
alloc_create_info.flags = (p_format.usage_bits & TEXTURE_USAGE_CPU_READ_BIT) ? VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT : 0;
1922
1923
if (p_format.usage_bits & TEXTURE_USAGE_TRANSIENT_BIT) {
1924
uint32_t memory_type_index = 0;
1925
VmaAllocationCreateInfo lazy_memory_requirements = alloc_create_info;
1926
lazy_memory_requirements.usage = VMA_MEMORY_USAGE_GPU_LAZILY_ALLOCATED;
1927
VkResult result = vmaFindMemoryTypeIndex(allocator, UINT32_MAX, &lazy_memory_requirements, &memory_type_index);
1928
if (VK_SUCCESS == result) {
1929
alloc_create_info = lazy_memory_requirements;
1930
create_info.usage |= VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT;
1931
// VUID-VkImageCreateInfo-usage-00963 :
1932
// If usage includes VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT,
1933
// then bits other than VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
1934
// and VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT must not be set.
1935
create_info.usage &= (VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT);
1936
} else {
1937
alloc_create_info.preferredFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
1938
}
1939
} else {
1940
alloc_create_info.preferredFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
1941
}
1942
1943
if (image_size <= SMALL_ALLOCATION_MAX_SIZE) {
1944
uint32_t mem_type_index = 0;
1945
vmaFindMemoryTypeIndexForImageInfo(allocator, &create_info, &alloc_create_info, &mem_type_index);
1946
alloc_create_info.pool = _find_or_create_small_allocs_pool(mem_type_index);
1947
}
1948
1949
// Create.
1950
1951
VkImage vk_image = VK_NULL_HANDLE;
1952
VmaAllocation allocation = nullptr;
1953
VmaAllocationInfo alloc_info = {};
1954
1955
if (!Engine::get_singleton()->is_extra_gpu_memory_tracking_enabled()) {
1956
alloc_create_info.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE;
1957
VkResult err = vmaCreateImage(allocator, &create_info, &alloc_create_info, &vk_image, &allocation, &alloc_info);
1958
ERR_FAIL_COND_V_MSG(err, TextureID(), "vmaCreateImage failed with error " + itos(err) + ".");
1959
} else {
1960
VkResult err = vkCreateImage(vk_device, &create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_IMAGE), &vk_image);
1961
ERR_FAIL_COND_V_MSG(err, TextureID(), "vkCreateImage failed with error " + itos(err) + ".");
1962
err = vmaAllocateMemoryForImage(allocator, vk_image, &alloc_create_info, &allocation, &alloc_info);
1963
ERR_FAIL_COND_V_MSG(err, TextureID(), "Can't allocate memory for image, error: " + itos(err) + ".");
1964
err = vmaBindImageMemory2(allocator, allocation, 0, vk_image, nullptr);
1965
ERR_FAIL_COND_V_MSG(err, TextureID(), "Can't bind memory to image, error: " + itos(err) + ".");
1966
}
1967
1968
// Create view.
1969
1970
VkImageViewCreateInfo image_view_create_info = {};
1971
image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
1972
image_view_create_info.image = vk_image;
1973
image_view_create_info.viewType = (VkImageViewType)p_format.texture_type;
1974
image_view_create_info.format = RD_TO_VK_FORMAT[p_view.format];
1975
image_view_create_info.components.r = (VkComponentSwizzle)p_view.swizzle_r;
1976
image_view_create_info.components.g = (VkComponentSwizzle)p_view.swizzle_g;
1977
image_view_create_info.components.b = (VkComponentSwizzle)p_view.swizzle_b;
1978
image_view_create_info.components.a = (VkComponentSwizzle)p_view.swizzle_a;
1979
image_view_create_info.subresourceRange.levelCount = create_info.mipLevels;
1980
image_view_create_info.subresourceRange.layerCount = create_info.arrayLayers;
1981
if ((p_format.usage_bits & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
1982
image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
1983
} else {
1984
image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1985
}
1986
1987
VkImageViewASTCDecodeModeEXT decode_mode;
1988
if (enabled_device_extension_names.has(VK_EXT_ASTC_DECODE_MODE_EXTENSION_NAME)) {
1989
if (image_view_create_info.format >= VK_FORMAT_ASTC_4x4_UNORM_BLOCK && image_view_create_info.format <= VK_FORMAT_ASTC_12x12_SRGB_BLOCK) {
1990
decode_mode.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_ASTC_DECODE_MODE_EXT;
1991
decode_mode.pNext = nullptr;
1992
decode_mode.decodeMode = VK_FORMAT_R8G8B8A8_UNORM;
1993
image_view_create_info.pNext = &decode_mode;
1994
}
1995
}
1996
1997
VkImageView vk_image_view = VK_NULL_HANDLE;
1998
VkResult err = vkCreateImageView(vk_device, &image_view_create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_IMAGE_VIEW), &vk_image_view);
1999
if (err) {
2000
if (!Engine::get_singleton()->is_extra_gpu_memory_tracking_enabled()) {
2001
vmaDestroyImage(allocator, vk_image, allocation);
2002
} else {
2003
vkDestroyImage(vk_device, vk_image, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_IMAGE));
2004
vmaFreeMemory(allocator, allocation);
2005
}
2006
2007
ERR_FAIL_COND_V_MSG(err, TextureID(), "vkCreateImageView failed with error " + itos(err) + ".");
2008
}
2009
2010
// Bookkeep.
2011
2012
TextureInfo *tex_info = VersatileResource::allocate<TextureInfo>(resources_allocator);
2013
tex_info->vk_image = vk_image;
2014
tex_info->vk_view = vk_image_view;
2015
tex_info->rd_format = p_format.format;
2016
tex_info->vk_create_info = create_info;
2017
tex_info->vk_view_create_info = image_view_create_info;
2018
tex_info->allocation.handle = allocation;
2019
#ifdef DEBUG_ENABLED
2020
tex_info->transient = (p_format.usage_bits & TEXTURE_USAGE_TRANSIENT_BIT) != 0;
2021
#endif
2022
vmaGetAllocationInfo(allocator, tex_info->allocation.handle, &tex_info->allocation.info);
2023
2024
#if PRINT_NATIVE_COMMANDS
2025
print_line(vformat("vkCreateImageView: 0x%uX for 0x%uX", uint64_t(vk_image_view), uint64_t(vk_image)));
2026
#endif
2027
2028
return TextureID(tex_info);
2029
}
2030
2031
RDD::TextureID RenderingDeviceDriverVulkan::texture_create_from_extension(uint64_t p_native_texture, TextureType p_type, DataFormat p_format, uint32_t p_array_layers, bool p_depth_stencil, uint32_t p_mipmaps) {
2032
VkImage vk_image = (VkImage)p_native_texture;
2033
2034
// We only need to create a view into the already existing natively-provided texture.
2035
2036
VkImageViewCreateInfo image_view_create_info = {};
2037
image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
2038
image_view_create_info.image = vk_image;
2039
image_view_create_info.viewType = (VkImageViewType)p_type;
2040
image_view_create_info.format = RD_TO_VK_FORMAT[p_format];
2041
image_view_create_info.components.r = VK_COMPONENT_SWIZZLE_R;
2042
image_view_create_info.components.g = VK_COMPONENT_SWIZZLE_G;
2043
image_view_create_info.components.b = VK_COMPONENT_SWIZZLE_B;
2044
image_view_create_info.components.a = VK_COMPONENT_SWIZZLE_A;
2045
image_view_create_info.subresourceRange.baseMipLevel = 0;
2046
image_view_create_info.subresourceRange.levelCount = p_mipmaps;
2047
image_view_create_info.subresourceRange.layerCount = p_array_layers;
2048
image_view_create_info.subresourceRange.aspectMask = p_depth_stencil ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
2049
2050
VkImageView vk_image_view = VK_NULL_HANDLE;
2051
VkResult err = vkCreateImageView(vk_device, &image_view_create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_IMAGE_VIEW), &vk_image_view);
2052
if (err) {
2053
ERR_FAIL_COND_V_MSG(err, TextureID(), "vkCreateImageView failed with error " + itos(err) + ".");
2054
}
2055
2056
// Bookkeep.
2057
2058
TextureInfo *tex_info = VersatileResource::allocate<TextureInfo>(resources_allocator);
2059
tex_info->vk_view = vk_image_view;
2060
tex_info->rd_format = p_format;
2061
tex_info->vk_view_create_info = image_view_create_info;
2062
#ifdef DEBUG_ENABLED
2063
tex_info->created_from_extension = true;
2064
#endif
2065
return TextureID(tex_info);
2066
}
2067
2068
RDD::TextureID RenderingDeviceDriverVulkan::texture_create_shared(TextureID p_original_texture, const TextureView &p_view) {
2069
const TextureInfo *owner_tex_info = (const TextureInfo *)p_original_texture.id;
2070
#ifdef DEBUG_ENABLED
2071
ERR_FAIL_COND_V(!owner_tex_info->allocation.handle && !owner_tex_info->created_from_extension, TextureID());
2072
#endif
2073
VkImageViewCreateInfo image_view_create_info = owner_tex_info->vk_view_create_info;
2074
image_view_create_info.format = RD_TO_VK_FORMAT[p_view.format];
2075
image_view_create_info.components.r = (VkComponentSwizzle)p_view.swizzle_r;
2076
image_view_create_info.components.g = (VkComponentSwizzle)p_view.swizzle_g;
2077
image_view_create_info.components.b = (VkComponentSwizzle)p_view.swizzle_b;
2078
image_view_create_info.components.a = (VkComponentSwizzle)p_view.swizzle_a;
2079
2080
if (enabled_device_extension_names.has(VK_KHR_MAINTENANCE_2_EXTENSION_NAME)) {
2081
// May need to make VK_KHR_maintenance2 mandatory and thus has Vulkan 1.1 be our minimum supported version
2082
// if we require setting this information. Vulkan 1.0 may simply not care.
2083
if (image_view_create_info.format != owner_tex_info->vk_view_create_info.format) {
2084
VkImageViewUsageCreateInfo *usage_info = ALLOCA_SINGLE(VkImageViewUsageCreateInfo);
2085
*usage_info = {};
2086
usage_info->sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO;
2087
usage_info->usage = owner_tex_info->vk_create_info.usage;
2088
2089
// Certain features may not be available for the format of the view.
2090
{
2091
VkFormatProperties properties = {};
2092
vkGetPhysicalDeviceFormatProperties(physical_device, RD_TO_VK_FORMAT[p_view.format], &properties);
2093
const VkFormatFeatureFlags &supported_flags = owner_tex_info->vk_create_info.tiling == VK_IMAGE_TILING_LINEAR ? properties.linearTilingFeatures : properties.optimalTilingFeatures;
2094
if ((usage_info->usage & VK_IMAGE_USAGE_STORAGE_BIT) && !(supported_flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT)) {
2095
usage_info->usage &= ~uint32_t(VK_IMAGE_USAGE_STORAGE_BIT);
2096
}
2097
if ((usage_info->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) && !(supported_flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)) {
2098
usage_info->usage &= ~uint32_t(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
2099
}
2100
}
2101
2102
image_view_create_info.pNext = usage_info;
2103
}
2104
}
2105
2106
VkImageView new_vk_image_view = VK_NULL_HANDLE;
2107
VkResult err = vkCreateImageView(vk_device, &image_view_create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_IMAGE_VIEW), &new_vk_image_view);
2108
ERR_FAIL_COND_V_MSG(err, TextureID(), "vkCreateImageView failed with error " + itos(err) + ".");
2109
2110
// Bookkeep.
2111
2112
TextureInfo *tex_info = VersatileResource::allocate<TextureInfo>(resources_allocator);
2113
*tex_info = *owner_tex_info;
2114
tex_info->vk_view = new_vk_image_view;
2115
tex_info->vk_view_create_info = image_view_create_info;
2116
tex_info->allocation = {};
2117
2118
#if PRINT_NATIVE_COMMANDS
2119
print_line(vformat("vkCreateImageView: 0x%uX for 0x%uX", uint64_t(new_vk_image_view), uint64_t(owner_tex_info->vk_view_create_info.image)));
2120
#endif
2121
2122
return TextureID(tex_info);
2123
}
2124
2125
RDD::TextureID RenderingDeviceDriverVulkan::texture_create_shared_from_slice(TextureID p_original_texture, const TextureView &p_view, TextureSliceType p_slice_type, uint32_t p_layer, uint32_t p_layers, uint32_t p_mipmap, uint32_t p_mipmaps) {
2126
const TextureInfo *owner_tex_info = (const TextureInfo *)p_original_texture.id;
2127
#ifdef DEBUG_ENABLED
2128
ERR_FAIL_COND_V(!owner_tex_info->allocation.handle && !owner_tex_info->created_from_extension, TextureID());
2129
#endif
2130
2131
VkImageViewCreateInfo image_view_create_info = owner_tex_info->vk_view_create_info;
2132
switch (p_slice_type) {
2133
case TEXTURE_SLICE_2D: {
2134
image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
2135
} break;
2136
case TEXTURE_SLICE_3D: {
2137
image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_3D;
2138
} break;
2139
case TEXTURE_SLICE_CUBEMAP: {
2140
image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_CUBE;
2141
} break;
2142
case TEXTURE_SLICE_2D_ARRAY: {
2143
image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
2144
} break;
2145
default: {
2146
return TextureID(nullptr);
2147
}
2148
}
2149
image_view_create_info.format = RD_TO_VK_FORMAT[p_view.format];
2150
image_view_create_info.components.r = (VkComponentSwizzle)p_view.swizzle_r;
2151
image_view_create_info.components.g = (VkComponentSwizzle)p_view.swizzle_g;
2152
image_view_create_info.components.b = (VkComponentSwizzle)p_view.swizzle_b;
2153
image_view_create_info.components.a = (VkComponentSwizzle)p_view.swizzle_a;
2154
image_view_create_info.subresourceRange.baseMipLevel = p_mipmap;
2155
image_view_create_info.subresourceRange.levelCount = p_mipmaps;
2156
image_view_create_info.subresourceRange.baseArrayLayer = p_layer;
2157
image_view_create_info.subresourceRange.layerCount = p_layers;
2158
2159
VkImageView new_vk_image_view = VK_NULL_HANDLE;
2160
VkResult err = vkCreateImageView(vk_device, &image_view_create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_IMAGE_VIEW), &new_vk_image_view);
2161
ERR_FAIL_COND_V_MSG(err, TextureID(), "vkCreateImageView failed with error " + itos(err) + ".");
2162
2163
// Bookkeep.
2164
2165
TextureInfo *tex_info = VersatileResource::allocate<TextureInfo>(resources_allocator);
2166
*tex_info = *owner_tex_info;
2167
tex_info->vk_view = new_vk_image_view;
2168
tex_info->vk_view_create_info = image_view_create_info;
2169
tex_info->allocation = {};
2170
2171
#if PRINT_NATIVE_COMMANDS
2172
print_line(vformat("vkCreateImageView: 0x%uX for 0x%uX (%d %d %d %d)", uint64_t(new_vk_image_view), uint64_t(owner_tex_info->vk_view_create_info.image), p_mipmap, p_mipmaps, p_layer, p_layers));
2173
#endif
2174
2175
return TextureID(tex_info);
2176
}
2177
2178
void RenderingDeviceDriverVulkan::texture_free(TextureID p_texture) {
2179
TextureInfo *tex_info = (TextureInfo *)p_texture.id;
2180
vkDestroyImageView(vk_device, tex_info->vk_view, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_IMAGE_VIEW));
2181
if (tex_info->allocation.handle) {
2182
if (!Engine::get_singleton()->is_extra_gpu_memory_tracking_enabled()) {
2183
vmaDestroyImage(allocator, tex_info->vk_view_create_info.image, tex_info->allocation.handle);
2184
} else {
2185
vkDestroyImage(vk_device, tex_info->vk_image, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_BUFFER));
2186
vmaFreeMemory(allocator, tex_info->allocation.handle);
2187
}
2188
}
2189
VersatileResource::free(resources_allocator, tex_info);
2190
}
2191
2192
uint64_t RenderingDeviceDriverVulkan::texture_get_allocation_size(TextureID p_texture) {
2193
const TextureInfo *tex_info = (const TextureInfo *)p_texture.id;
2194
return tex_info->allocation.info.size;
2195
}
2196
2197
void RenderingDeviceDriverVulkan::texture_get_copyable_layout(TextureID p_texture, const TextureSubresource &p_subresource, TextureCopyableLayout *r_layout) {
2198
const TextureInfo *tex_info = (const TextureInfo *)p_texture.id;
2199
2200
*r_layout = {};
2201
2202
if (tex_info->vk_create_info.tiling == VK_IMAGE_TILING_LINEAR) {
2203
VkImageSubresource vk_subres = {};
2204
vk_subres.aspectMask = (VkImageAspectFlags)(1 << p_subresource.aspect);
2205
vk_subres.arrayLayer = p_subresource.layer;
2206
vk_subres.mipLevel = p_subresource.mipmap;
2207
2208
VkSubresourceLayout vk_layout = {};
2209
vkGetImageSubresourceLayout(vk_device, tex_info->vk_view_create_info.image, &vk_subres, &vk_layout);
2210
2211
r_layout->offset = vk_layout.offset;
2212
r_layout->size = vk_layout.size;
2213
r_layout->row_pitch = vk_layout.rowPitch;
2214
r_layout->depth_pitch = vk_layout.depthPitch;
2215
r_layout->layer_pitch = vk_layout.arrayPitch;
2216
} else {
2217
// Tight.
2218
uint32_t w = tex_info->vk_create_info.extent.width;
2219
uint32_t h = tex_info->vk_create_info.extent.height;
2220
uint32_t d = tex_info->vk_create_info.extent.depth;
2221
if (p_subresource.mipmap > 0) {
2222
r_layout->offset = get_image_format_required_size(tex_info->rd_format, w, h, d, p_subresource.mipmap);
2223
}
2224
for (uint32_t i = 0; i < p_subresource.mipmap; i++) {
2225
w = MAX(1u, w >> 1);
2226
h = MAX(1u, h >> 1);
2227
d = MAX(1u, d >> 1);
2228
}
2229
uint32_t bw = 0, bh = 0;
2230
get_compressed_image_format_block_dimensions(tex_info->rd_format, bw, bh);
2231
uint32_t sbw = 0, sbh = 0;
2232
r_layout->size = get_image_format_required_size(tex_info->rd_format, w, h, d, 1, &sbw, &sbh);
2233
r_layout->row_pitch = r_layout->size / ((sbh / bh) * d);
2234
r_layout->depth_pitch = r_layout->size / d;
2235
r_layout->layer_pitch = r_layout->size / tex_info->vk_create_info.arrayLayers;
2236
}
2237
}
2238
2239
uint8_t *RenderingDeviceDriverVulkan::texture_map(TextureID p_texture, const TextureSubresource &p_subresource) {
2240
const TextureInfo *tex_info = (const TextureInfo *)p_texture.id;
2241
2242
VkImageSubresource vk_subres = {};
2243
vk_subres.aspectMask = (VkImageAspectFlags)(1 << p_subresource.aspect);
2244
vk_subres.arrayLayer = p_subresource.layer;
2245
vk_subres.mipLevel = p_subresource.mipmap;
2246
2247
VkSubresourceLayout vk_layout = {};
2248
vkGetImageSubresourceLayout(vk_device, tex_info->vk_view_create_info.image, &vk_subres, &vk_layout);
2249
2250
void *data_ptr = nullptr;
2251
VkResult err = vkMapMemory(
2252
vk_device,
2253
tex_info->allocation.info.deviceMemory,
2254
tex_info->allocation.info.offset + vk_layout.offset,
2255
vk_layout.size,
2256
0,
2257
&data_ptr);
2258
2259
vmaMapMemory(allocator, tex_info->allocation.handle, &data_ptr);
2260
ERR_FAIL_COND_V_MSG(err, nullptr, "vkMapMemory failed with error " + itos(err) + ".");
2261
return (uint8_t *)data_ptr;
2262
}
2263
2264
void RenderingDeviceDriverVulkan::texture_unmap(TextureID p_texture) {
2265
const TextureInfo *tex_info = (const TextureInfo *)p_texture.id;
2266
vmaUnmapMemory(allocator, tex_info->allocation.handle);
2267
}
2268
2269
BitField<RDD::TextureUsageBits> RenderingDeviceDriverVulkan::texture_get_usages_supported_by_format(DataFormat p_format, bool p_cpu_readable) {
2270
if (p_format >= DATA_FORMAT_ASTC_4x4_SFLOAT_BLOCK && p_format <= DATA_FORMAT_ASTC_12x12_SFLOAT_BLOCK && !enabled_device_extension_names.has(VK_EXT_TEXTURE_COMPRESSION_ASTC_HDR_EXTENSION_NAME)) {
2271
// Formats that were introduced later with extensions must not reach vkGetPhysicalDeviceFormatProperties if the extension isn't available. This means it's not supported.
2272
return 0;
2273
}
2274
VkFormatProperties properties = {};
2275
vkGetPhysicalDeviceFormatProperties(physical_device, RD_TO_VK_FORMAT[p_format], &properties);
2276
2277
const VkFormatFeatureFlags &flags = p_cpu_readable ? properties.linearTilingFeatures : properties.optimalTilingFeatures;
2278
2279
// Everything supported by default makes an all-or-nothing check easier for the caller.
2280
BitField<RDD::TextureUsageBits> supported = INT64_MAX;
2281
2282
if (!(flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) {
2283
supported.clear_flag(TEXTURE_USAGE_SAMPLING_BIT);
2284
}
2285
if (!(flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)) {
2286
supported.clear_flag(TEXTURE_USAGE_COLOR_ATTACHMENT_BIT);
2287
}
2288
if (!(flags & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
2289
supported.clear_flag(TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
2290
}
2291
if (!(flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT)) {
2292
supported.clear_flag(TEXTURE_USAGE_STORAGE_BIT);
2293
}
2294
if (!(flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT)) {
2295
supported.clear_flag(TEXTURE_USAGE_STORAGE_ATOMIC_BIT);
2296
}
2297
if (p_format != DATA_FORMAT_R8_UINT && p_format != DATA_FORMAT_R8G8_UNORM) {
2298
supported.clear_flag(TEXTURE_USAGE_VRS_ATTACHMENT_BIT);
2299
}
2300
2301
return supported;
2302
}
2303
2304
bool RenderingDeviceDriverVulkan::texture_can_make_shared_with_format(TextureID p_texture, DataFormat p_format, bool &r_raw_reinterpretation) {
2305
r_raw_reinterpretation = false;
2306
return true;
2307
}
2308
2309
/*****************/
2310
/**** SAMPLER ****/
2311
/*****************/
2312
2313
// RDD::SamplerRepeatMode == VkSamplerAddressMode.
2314
static_assert(ENUM_MEMBERS_EQUAL(RDD::SAMPLER_REPEAT_MODE_REPEAT, VK_SAMPLER_ADDRESS_MODE_REPEAT));
2315
static_assert(ENUM_MEMBERS_EQUAL(RDD::SAMPLER_REPEAT_MODE_MIRRORED_REPEAT, VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT));
2316
static_assert(ENUM_MEMBERS_EQUAL(RDD::SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE));
2317
static_assert(ENUM_MEMBERS_EQUAL(RDD::SAMPLER_REPEAT_MODE_CLAMP_TO_BORDER, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER));
2318
static_assert(ENUM_MEMBERS_EQUAL(RDD::SAMPLER_REPEAT_MODE_MIRROR_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE));
2319
2320
// RDD::SamplerBorderColor == VkBorderColor.
2321
static_assert(ENUM_MEMBERS_EQUAL(RDD::SAMPLER_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK));
2322
static_assert(ENUM_MEMBERS_EQUAL(RDD::SAMPLER_BORDER_COLOR_INT_TRANSPARENT_BLACK, VK_BORDER_COLOR_INT_TRANSPARENT_BLACK));
2323
static_assert(ENUM_MEMBERS_EQUAL(RDD::SAMPLER_BORDER_COLOR_FLOAT_OPAQUE_BLACK, VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK));
2324
static_assert(ENUM_MEMBERS_EQUAL(RDD::SAMPLER_BORDER_COLOR_INT_OPAQUE_BLACK, VK_BORDER_COLOR_INT_OPAQUE_BLACK));
2325
static_assert(ENUM_MEMBERS_EQUAL(RDD::SAMPLER_BORDER_COLOR_FLOAT_OPAQUE_WHITE, VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE));
2326
static_assert(ENUM_MEMBERS_EQUAL(RDD::SAMPLER_BORDER_COLOR_INT_OPAQUE_WHITE, VK_BORDER_COLOR_INT_OPAQUE_WHITE));
2327
2328
RDD::SamplerID RenderingDeviceDriverVulkan::sampler_create(const SamplerState &p_state) {
2329
VkSamplerCreateInfo sampler_create_info = {};
2330
sampler_create_info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
2331
sampler_create_info.pNext = nullptr;
2332
sampler_create_info.flags = 0;
2333
sampler_create_info.magFilter = p_state.mag_filter == SAMPLER_FILTER_LINEAR ? VK_FILTER_LINEAR : VK_FILTER_NEAREST;
2334
sampler_create_info.minFilter = p_state.min_filter == SAMPLER_FILTER_LINEAR ? VK_FILTER_LINEAR : VK_FILTER_NEAREST;
2335
sampler_create_info.mipmapMode = p_state.mip_filter == SAMPLER_FILTER_LINEAR ? VK_SAMPLER_MIPMAP_MODE_LINEAR : VK_SAMPLER_MIPMAP_MODE_NEAREST;
2336
sampler_create_info.addressModeU = (VkSamplerAddressMode)p_state.repeat_u;
2337
sampler_create_info.addressModeV = (VkSamplerAddressMode)p_state.repeat_v;
2338
sampler_create_info.addressModeW = (VkSamplerAddressMode)p_state.repeat_w;
2339
sampler_create_info.mipLodBias = p_state.lod_bias;
2340
sampler_create_info.anisotropyEnable = p_state.use_anisotropy && (physical_device_features.samplerAnisotropy == VK_TRUE);
2341
sampler_create_info.maxAnisotropy = p_state.anisotropy_max;
2342
sampler_create_info.compareEnable = p_state.enable_compare;
2343
sampler_create_info.compareOp = (VkCompareOp)p_state.compare_op;
2344
sampler_create_info.minLod = p_state.min_lod;
2345
sampler_create_info.maxLod = p_state.max_lod;
2346
sampler_create_info.borderColor = (VkBorderColor)p_state.border_color;
2347
sampler_create_info.unnormalizedCoordinates = p_state.unnormalized_uvw;
2348
2349
VkSampler vk_sampler = VK_NULL_HANDLE;
2350
VkResult res = vkCreateSampler(vk_device, &sampler_create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_SAMPLER), &vk_sampler);
2351
ERR_FAIL_COND_V_MSG(res, SamplerID(), "vkCreateSampler failed with error " + itos(res) + ".");
2352
2353
return SamplerID(vk_sampler);
2354
}
2355
2356
void RenderingDeviceDriverVulkan::sampler_free(SamplerID p_sampler) {
2357
vkDestroySampler(vk_device, (VkSampler)p_sampler.id, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_SAMPLER));
2358
}
2359
2360
bool RenderingDeviceDriverVulkan::sampler_is_format_supported_for_filter(DataFormat p_format, SamplerFilter p_filter) {
2361
switch (p_filter) {
2362
case SAMPLER_FILTER_NEAREST: {
2363
return true;
2364
}
2365
case SAMPLER_FILTER_LINEAR: {
2366
VkFormatProperties properties = {};
2367
vkGetPhysicalDeviceFormatProperties(physical_device, RD_TO_VK_FORMAT[p_format], &properties);
2368
return (properties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT);
2369
}
2370
}
2371
return false;
2372
}
2373
2374
/**********************/
2375
/**** VERTEX ARRAY ****/
2376
/**********************/
2377
2378
RDD::VertexFormatID RenderingDeviceDriverVulkan::vertex_format_create(VectorView<VertexAttribute> p_vertex_attribs) {
2379
// Pre-bookkeep.
2380
VertexFormatInfo *vf_info = VersatileResource::allocate<VertexFormatInfo>(resources_allocator);
2381
2382
vf_info->vk_bindings.resize(p_vertex_attribs.size());
2383
vf_info->vk_attributes.resize(p_vertex_attribs.size());
2384
for (uint32_t i = 0; i < p_vertex_attribs.size(); i++) {
2385
vf_info->vk_bindings[i] = {};
2386
vf_info->vk_bindings[i].binding = i;
2387
vf_info->vk_bindings[i].stride = p_vertex_attribs[i].stride;
2388
vf_info->vk_bindings[i].inputRate = p_vertex_attribs[i].frequency == VERTEX_FREQUENCY_INSTANCE ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX;
2389
vf_info->vk_attributes[i] = {};
2390
vf_info->vk_attributes[i].binding = i;
2391
vf_info->vk_attributes[i].location = p_vertex_attribs[i].location;
2392
vf_info->vk_attributes[i].format = RD_TO_VK_FORMAT[p_vertex_attribs[i].format];
2393
vf_info->vk_attributes[i].offset = p_vertex_attribs[i].offset;
2394
}
2395
2396
vf_info->vk_create_info = {};
2397
vf_info->vk_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
2398
vf_info->vk_create_info.vertexBindingDescriptionCount = vf_info->vk_bindings.size();
2399
vf_info->vk_create_info.pVertexBindingDescriptions = vf_info->vk_bindings.ptr();
2400
vf_info->vk_create_info.vertexAttributeDescriptionCount = vf_info->vk_attributes.size();
2401
vf_info->vk_create_info.pVertexAttributeDescriptions = vf_info->vk_attributes.ptr();
2402
2403
return VertexFormatID(vf_info);
2404
}
2405
2406
void RenderingDeviceDriverVulkan::vertex_format_free(VertexFormatID p_vertex_format) {
2407
VertexFormatInfo *vf_info = (VertexFormatInfo *)p_vertex_format.id;
2408
VersatileResource::free(resources_allocator, vf_info);
2409
}
2410
2411
/******************/
2412
/**** BARRIERS ****/
2413
/******************/
2414
2415
// RDD::PipelineStageBits == VkPipelineStageFlagBits.
2416
static_assert(ENUM_MEMBERS_EQUAL(RDD::PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT));
2417
static_assert(ENUM_MEMBERS_EQUAL(RDD::PIPELINE_STAGE_DRAW_INDIRECT_BIT, VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT));
2418
static_assert(ENUM_MEMBERS_EQUAL(RDD::PIPELINE_STAGE_VERTEX_INPUT_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT));
2419
static_assert(ENUM_MEMBERS_EQUAL(RDD::PIPELINE_STAGE_VERTEX_SHADER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT));
2420
static_assert(ENUM_MEMBERS_EQUAL(RDD::PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT, VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT));
2421
static_assert(ENUM_MEMBERS_EQUAL(RDD::PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT, VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT));
2422
static_assert(ENUM_MEMBERS_EQUAL(RDD::PIPELINE_STAGE_GEOMETRY_SHADER_BIT, VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT));
2423
static_assert(ENUM_MEMBERS_EQUAL(RDD::PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT));
2424
static_assert(ENUM_MEMBERS_EQUAL(RDD::PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT));
2425
static_assert(ENUM_MEMBERS_EQUAL(RDD::PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT));
2426
static_assert(ENUM_MEMBERS_EQUAL(RDD::PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT));
2427
static_assert(ENUM_MEMBERS_EQUAL(RDD::PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT));
2428
static_assert(ENUM_MEMBERS_EQUAL(RDD::PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT));
2429
static_assert(ENUM_MEMBERS_EQUAL(RDD::PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT));
2430
static_assert(ENUM_MEMBERS_EQUAL(RDD::PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT));
2431
static_assert(ENUM_MEMBERS_EQUAL(RDD::PIPELINE_STAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR));
2432
static_assert(ENUM_MEMBERS_EQUAL(RDD::PIPELINE_STAGE_FRAGMENT_DENSITY_PROCESS_BIT, VK_PIPELINE_STAGE_FRAGMENT_DENSITY_PROCESS_BIT_EXT));
2433
2434
// RDD::BarrierAccessBits == VkAccessFlagBits.
2435
static_assert(ENUM_MEMBERS_EQUAL(RDD::BARRIER_ACCESS_INDIRECT_COMMAND_READ_BIT, VK_ACCESS_INDIRECT_COMMAND_READ_BIT));
2436
static_assert(ENUM_MEMBERS_EQUAL(RDD::BARRIER_ACCESS_INDEX_READ_BIT, VK_ACCESS_INDEX_READ_BIT));
2437
static_assert(ENUM_MEMBERS_EQUAL(RDD::BARRIER_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT));
2438
static_assert(ENUM_MEMBERS_EQUAL(RDD::BARRIER_ACCESS_UNIFORM_READ_BIT, VK_ACCESS_UNIFORM_READ_BIT));
2439
static_assert(ENUM_MEMBERS_EQUAL(RDD::BARRIER_ACCESS_INPUT_ATTACHMENT_READ_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT));
2440
static_assert(ENUM_MEMBERS_EQUAL(RDD::BARRIER_ACCESS_SHADER_READ_BIT, VK_ACCESS_SHADER_READ_BIT));
2441
static_assert(ENUM_MEMBERS_EQUAL(RDD::BARRIER_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_SHADER_WRITE_BIT));
2442
static_assert(ENUM_MEMBERS_EQUAL(RDD::BARRIER_ACCESS_COLOR_ATTACHMENT_READ_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT));
2443
static_assert(ENUM_MEMBERS_EQUAL(RDD::BARRIER_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT));
2444
static_assert(ENUM_MEMBERS_EQUAL(RDD::BARRIER_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT));
2445
static_assert(ENUM_MEMBERS_EQUAL(RDD::BARRIER_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT));
2446
static_assert(ENUM_MEMBERS_EQUAL(RDD::BARRIER_ACCESS_HOST_READ_BIT, VK_ACCESS_HOST_READ_BIT));
2447
static_assert(ENUM_MEMBERS_EQUAL(RDD::BARRIER_ACCESS_HOST_WRITE_BIT, VK_ACCESS_HOST_WRITE_BIT));
2448
static_assert(ENUM_MEMBERS_EQUAL(RDD::BARRIER_ACCESS_MEMORY_READ_BIT, VK_ACCESS_MEMORY_READ_BIT));
2449
static_assert(ENUM_MEMBERS_EQUAL(RDD::BARRIER_ACCESS_MEMORY_WRITE_BIT, VK_ACCESS_MEMORY_WRITE_BIT));
2450
static_assert(ENUM_MEMBERS_EQUAL(RDD::BARRIER_ACCESS_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT, VK_ACCESS_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR));
2451
static_assert(ENUM_MEMBERS_EQUAL(RDD::BARRIER_ACCESS_FRAGMENT_DENSITY_MAP_ATTACHMENT_READ_BIT, VK_ACCESS_FRAGMENT_DENSITY_MAP_READ_BIT_EXT));
2452
2453
void RenderingDeviceDriverVulkan::command_pipeline_barrier(
2454
CommandBufferID p_cmd_buffer,
2455
BitField<PipelineStageBits> p_src_stages,
2456
BitField<PipelineStageBits> p_dst_stages,
2457
VectorView<MemoryBarrier> p_memory_barriers,
2458
VectorView<BufferBarrier> p_buffer_barriers,
2459
VectorView<TextureBarrier> p_texture_barriers) {
2460
VkMemoryBarrier *vk_memory_barriers = ALLOCA_ARRAY(VkMemoryBarrier, p_memory_barriers.size());
2461
for (uint32_t i = 0; i < p_memory_barriers.size(); i++) {
2462
vk_memory_barriers[i] = {};
2463
vk_memory_barriers[i].sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
2464
vk_memory_barriers[i].srcAccessMask = _rd_to_vk_access_flags(p_memory_barriers[i].src_access);
2465
vk_memory_barriers[i].dstAccessMask = _rd_to_vk_access_flags(p_memory_barriers[i].dst_access);
2466
}
2467
2468
VkBufferMemoryBarrier *vk_buffer_barriers = ALLOCA_ARRAY(VkBufferMemoryBarrier, p_buffer_barriers.size());
2469
for (uint32_t i = 0; i < p_buffer_barriers.size(); i++) {
2470
vk_buffer_barriers[i] = {};
2471
vk_buffer_barriers[i].sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
2472
vk_buffer_barriers[i].srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
2473
vk_buffer_barriers[i].dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
2474
vk_buffer_barriers[i].srcAccessMask = _rd_to_vk_access_flags(p_buffer_barriers[i].src_access);
2475
vk_buffer_barriers[i].dstAccessMask = _rd_to_vk_access_flags(p_buffer_barriers[i].dst_access);
2476
vk_buffer_barriers[i].buffer = ((const BufferInfo *)p_buffer_barriers[i].buffer.id)->vk_buffer;
2477
vk_buffer_barriers[i].offset = p_buffer_barriers[i].offset;
2478
vk_buffer_barriers[i].size = p_buffer_barriers[i].size;
2479
}
2480
2481
VkImageMemoryBarrier *vk_image_barriers = ALLOCA_ARRAY(VkImageMemoryBarrier, p_texture_barriers.size());
2482
for (uint32_t i = 0; i < p_texture_barriers.size(); i++) {
2483
const TextureInfo *tex_info = (const TextureInfo *)p_texture_barriers[i].texture.id;
2484
vk_image_barriers[i] = {};
2485
vk_image_barriers[i].sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
2486
vk_image_barriers[i].srcAccessMask = _rd_to_vk_access_flags(p_texture_barriers[i].src_access);
2487
vk_image_barriers[i].dstAccessMask = _rd_to_vk_access_flags(p_texture_barriers[i].dst_access);
2488
vk_image_barriers[i].oldLayout = RD_TO_VK_LAYOUT[p_texture_barriers[i].prev_layout];
2489
vk_image_barriers[i].newLayout = RD_TO_VK_LAYOUT[p_texture_barriers[i].next_layout];
2490
vk_image_barriers[i].srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
2491
vk_image_barriers[i].dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
2492
vk_image_barriers[i].image = tex_info->vk_view_create_info.image;
2493
vk_image_barriers[i].subresourceRange.aspectMask = (VkImageAspectFlags)p_texture_barriers[i].subresources.aspect;
2494
vk_image_barriers[i].subresourceRange.baseMipLevel = p_texture_barriers[i].subresources.base_mipmap;
2495
vk_image_barriers[i].subresourceRange.levelCount = p_texture_barriers[i].subresources.mipmap_count;
2496
vk_image_barriers[i].subresourceRange.baseArrayLayer = p_texture_barriers[i].subresources.base_layer;
2497
vk_image_barriers[i].subresourceRange.layerCount = p_texture_barriers[i].subresources.layer_count;
2498
}
2499
2500
#if PRINT_NATIVE_COMMANDS
2501
print_line(vformat("vkCmdPipelineBarrier MEMORY %d BUFFER %d TEXTURE %d", p_memory_barriers.size(), p_buffer_barriers.size(), p_texture_barriers.size()));
2502
for (uint32_t i = 0; i < p_memory_barriers.size(); i++) {
2503
print_line(vformat(" VkMemoryBarrier #%d src 0x%uX dst 0x%uX", i, vk_memory_barriers[i].srcAccessMask, vk_memory_barriers[i].dstAccessMask));
2504
}
2505
2506
for (uint32_t i = 0; i < p_buffer_barriers.size(); i++) {
2507
print_line(vformat(" VkBufferMemoryBarrier #%d src 0x%uX dst 0x%uX buffer 0x%ux", i, vk_buffer_barriers[i].srcAccessMask, vk_buffer_barriers[i].dstAccessMask, uint64_t(vk_buffer_barriers[i].buffer)));
2508
}
2509
2510
for (uint32_t i = 0; i < p_texture_barriers.size(); i++) {
2511
print_line(vformat(" VkImageMemoryBarrier #%d src 0x%uX dst 0x%uX image 0x%ux old %d new %d (%d %d %d %d)", i, vk_image_barriers[i].srcAccessMask, vk_image_barriers[i].dstAccessMask,
2512
uint64_t(vk_image_barriers[i].image), vk_image_barriers[i].oldLayout, vk_image_barriers[i].newLayout, vk_image_barriers[i].subresourceRange.baseMipLevel, vk_image_barriers[i].subresourceRange.levelCount,
2513
vk_image_barriers[i].subresourceRange.baseArrayLayer, vk_image_barriers[i].subresourceRange.layerCount));
2514
}
2515
#endif
2516
2517
const CommandBufferInfo *command_buffer = (const CommandBufferInfo *)p_cmd_buffer.id;
2518
vkCmdPipelineBarrier(
2519
command_buffer->vk_command_buffer,
2520
_rd_to_vk_pipeline_stages(p_src_stages),
2521
_rd_to_vk_pipeline_stages(p_dst_stages),
2522
0,
2523
p_memory_barriers.size(), vk_memory_barriers,
2524
p_buffer_barriers.size(), vk_buffer_barriers,
2525
p_texture_barriers.size(), vk_image_barriers);
2526
}
2527
2528
/****************/
2529
/**** FENCES ****/
2530
/****************/
2531
2532
RDD::FenceID RenderingDeviceDriverVulkan::fence_create() {
2533
VkFence vk_fence = VK_NULL_HANDLE;
2534
VkFenceCreateInfo create_info = {};
2535
create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
2536
VkResult err = vkCreateFence(vk_device, &create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_FENCE), &vk_fence);
2537
ERR_FAIL_COND_V(err != VK_SUCCESS, FenceID());
2538
2539
Fence *fence = memnew(Fence);
2540
fence->vk_fence = vk_fence;
2541
fence->queue_signaled_from = nullptr;
2542
return FenceID(fence);
2543
}
2544
2545
Error RenderingDeviceDriverVulkan::fence_wait(FenceID p_fence) {
2546
Fence *fence = (Fence *)(p_fence.id);
2547
VkResult fence_status = vkGetFenceStatus(vk_device, fence->vk_fence);
2548
if (fence_status == VK_NOT_READY) {
2549
VkResult err = vkWaitForFences(vk_device, 1, &fence->vk_fence, VK_TRUE, UINT64_MAX);
2550
ERR_FAIL_COND_V(err != VK_SUCCESS, FAILED);
2551
}
2552
2553
VkResult err = vkResetFences(vk_device, 1, &fence->vk_fence);
2554
ERR_FAIL_COND_V(err != VK_SUCCESS, FAILED);
2555
2556
if (fence->queue_signaled_from != nullptr) {
2557
// Release all semaphores that the command queue associated to the fence waited on the last time it was submitted.
2558
LocalVector<Pair<Fence *, uint32_t>> &pairs = fence->queue_signaled_from->image_semaphores_for_fences;
2559
uint32_t i = 0;
2560
while (i < pairs.size()) {
2561
if (pairs[i].first == fence) {
2562
_release_image_semaphore(fence->queue_signaled_from, pairs[i].second, true);
2563
fence->queue_signaled_from->free_image_semaphores.push_back(pairs[i].second);
2564
pairs.remove_at(i);
2565
} else {
2566
i++;
2567
}
2568
}
2569
2570
fence->queue_signaled_from = nullptr;
2571
}
2572
2573
return OK;
2574
}
2575
2576
void RenderingDeviceDriverVulkan::fence_free(FenceID p_fence) {
2577
Fence *fence = (Fence *)(p_fence.id);
2578
vkDestroyFence(vk_device, fence->vk_fence, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_FENCE));
2579
memdelete(fence);
2580
}
2581
2582
/********************/
2583
/**** SEMAPHORES ****/
2584
/********************/
2585
2586
RDD::SemaphoreID RenderingDeviceDriverVulkan::semaphore_create() {
2587
VkSemaphore semaphore = VK_NULL_HANDLE;
2588
VkSemaphoreCreateInfo create_info = {};
2589
create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
2590
VkResult err = vkCreateSemaphore(vk_device, &create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_SEMAPHORE), &semaphore);
2591
ERR_FAIL_COND_V(err != VK_SUCCESS, SemaphoreID());
2592
2593
return SemaphoreID(semaphore);
2594
}
2595
2596
void RenderingDeviceDriverVulkan::semaphore_free(SemaphoreID p_semaphore) {
2597
vkDestroySemaphore(vk_device, VkSemaphore(p_semaphore.id), VKC::get_allocation_callbacks(VK_OBJECT_TYPE_SEMAPHORE));
2598
}
2599
2600
/******************/
2601
/**** COMMANDS ****/
2602
/******************/
2603
2604
// ----- QUEUE FAMILY -----
2605
2606
RDD::CommandQueueFamilyID RenderingDeviceDriverVulkan::command_queue_family_get(BitField<CommandQueueFamilyBits> p_cmd_queue_family_bits, RenderingContextDriver::SurfaceID p_surface) {
2607
// Pick the queue with the least amount of bits that can fulfill the requirements.
2608
VkQueueFlags picked_queue_flags = VK_QUEUE_FLAG_BITS_MAX_ENUM;
2609
uint32_t picked_family_index = UINT_MAX;
2610
for (uint32_t i = 0; i < queue_family_properties.size(); i++) {
2611
if (queue_families[i].is_empty()) {
2612
// Ignore empty queue families.
2613
continue;
2614
}
2615
2616
if (p_surface != 0 && !context_driver->queue_family_supports_present(physical_device, i, p_surface)) {
2617
// Present is not an actual bit but something that must be queried manually.
2618
continue;
2619
}
2620
2621
// Preferring a queue with less bits will get us closer to getting a queue that performs better for our requirements.
2622
// For example, dedicated compute and transfer queues are usually indicated as such.
2623
const VkQueueFlags option_queue_flags = queue_family_properties[i].queueFlags;
2624
const bool includes_all_bits = p_cmd_queue_family_bits.get_shared(option_queue_flags) == p_cmd_queue_family_bits;
2625
const bool prefer_less_bits = option_queue_flags < picked_queue_flags;
2626
if (includes_all_bits && prefer_less_bits) {
2627
picked_family_index = i;
2628
picked_queue_flags = option_queue_flags;
2629
}
2630
}
2631
2632
if (picked_family_index >= queue_family_properties.size()) {
2633
return CommandQueueFamilyID();
2634
}
2635
2636
// Since 0 is a valid index and we use 0 as the error case, we make the index start from 1 instead.
2637
return CommandQueueFamilyID(picked_family_index + 1);
2638
}
2639
2640
// ----- QUEUE -----
2641
2642
RDD::CommandQueueID RenderingDeviceDriverVulkan::command_queue_create(CommandQueueFamilyID p_cmd_queue_family, bool p_identify_as_main_queue) {
2643
DEV_ASSERT(p_cmd_queue_family.id != 0);
2644
2645
// Make a virtual queue on top of a real queue. Use the queue from the family with the least amount of virtual queues created.
2646
uint32_t family_index = p_cmd_queue_family.id - 1;
2647
TightLocalVector<Queue> &queue_family = queue_families[family_index];
2648
uint32_t picked_queue_index = UINT_MAX;
2649
uint32_t picked_virtual_count = UINT_MAX;
2650
for (uint32_t i = 0; i < queue_family.size(); i++) {
2651
if (queue_family[i].virtual_count < picked_virtual_count) {
2652
picked_queue_index = i;
2653
picked_virtual_count = queue_family[i].virtual_count;
2654
}
2655
}
2656
2657
ERR_FAIL_COND_V_MSG(picked_queue_index >= queue_family.size(), CommandQueueID(), "A queue in the picked family could not be found.");
2658
2659
#if defined(SWAPPY_FRAME_PACING_ENABLED)
2660
if (swappy_frame_pacer_enable) {
2661
VkQueue selected_queue;
2662
vkGetDeviceQueue(vk_device, family_index, picked_queue_index, &selected_queue);
2663
SwappyVk_setQueueFamilyIndex(vk_device, selected_queue, family_index);
2664
}
2665
#endif
2666
2667
// Create the virtual queue.
2668
CommandQueue *command_queue = memnew(CommandQueue);
2669
command_queue->queue_family = family_index;
2670
command_queue->queue_index = picked_queue_index;
2671
queue_family[picked_queue_index].virtual_count++;
2672
2673
// If is was identified as the main queue and a hook is active, indicate it as such to the hook.
2674
if (p_identify_as_main_queue && (VulkanHooks::get_singleton() != nullptr)) {
2675
VulkanHooks::get_singleton()->set_direct_queue_family_and_index(family_index, picked_queue_index);
2676
}
2677
2678
return CommandQueueID(command_queue);
2679
}
2680
2681
Error RenderingDeviceDriverVulkan::command_queue_execute_and_present(CommandQueueID p_cmd_queue, VectorView<SemaphoreID> p_wait_semaphores, VectorView<CommandBufferID> p_cmd_buffers, VectorView<SemaphoreID> p_cmd_semaphores, FenceID p_cmd_fence, VectorView<SwapChainID> p_swap_chains) {
2682
DEV_ASSERT(p_cmd_queue.id != 0);
2683
2684
VkResult err;
2685
CommandQueue *command_queue = (CommandQueue *)(p_cmd_queue.id);
2686
Queue &device_queue = queue_families[command_queue->queue_family][command_queue->queue_index];
2687
Fence *fence = (Fence *)(p_cmd_fence.id);
2688
VkFence vk_fence = (fence != nullptr) ? fence->vk_fence : VK_NULL_HANDLE;
2689
2690
thread_local LocalVector<VkSemaphore> wait_semaphores;
2691
thread_local LocalVector<VkPipelineStageFlags> wait_semaphores_stages;
2692
wait_semaphores.clear();
2693
wait_semaphores_stages.clear();
2694
2695
if (!command_queue->pending_semaphores_for_execute.is_empty()) {
2696
for (uint32_t i = 0; i < command_queue->pending_semaphores_for_execute.size(); i++) {
2697
VkSemaphore wait_semaphore = command_queue->image_semaphores[command_queue->pending_semaphores_for_execute[i]];
2698
wait_semaphores.push_back(wait_semaphore);
2699
wait_semaphores_stages.push_back(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
2700
}
2701
2702
command_queue->pending_semaphores_for_execute.clear();
2703
}
2704
2705
for (uint32_t i = 0; i < p_wait_semaphores.size(); i++) {
2706
// FIXME: Allow specifying the stage mask in more detail.
2707
wait_semaphores.push_back(VkSemaphore(p_wait_semaphores[i].id));
2708
wait_semaphores_stages.push_back(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
2709
}
2710
2711
if (p_cmd_buffers.size() > 0) {
2712
thread_local LocalVector<VkCommandBuffer> command_buffers;
2713
thread_local LocalVector<VkSemaphore> present_semaphores;
2714
thread_local LocalVector<VkSemaphore> signal_semaphores;
2715
command_buffers.clear();
2716
present_semaphores.clear();
2717
signal_semaphores.clear();
2718
2719
for (uint32_t i = 0; i < p_cmd_buffers.size(); i++) {
2720
const CommandBufferInfo *command_buffer = (const CommandBufferInfo *)(p_cmd_buffers[i].id);
2721
command_buffers.push_back(command_buffer->vk_command_buffer);
2722
}
2723
2724
for (uint32_t i = 0; i < p_cmd_semaphores.size(); i++) {
2725
signal_semaphores.push_back(VkSemaphore(p_cmd_semaphores[i].id));
2726
}
2727
2728
for (uint32_t i = 0; i < p_swap_chains.size(); i++) {
2729
const SwapChain *swap_chain = (const SwapChain *)(p_swap_chains[i].id);
2730
VkSemaphore semaphore = swap_chain->present_semaphores[swap_chain->image_index];
2731
present_semaphores.push_back(semaphore);
2732
signal_semaphores.push_back(semaphore);
2733
}
2734
2735
VkSubmitInfo submit_info = {};
2736
submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
2737
submit_info.waitSemaphoreCount = wait_semaphores.size();
2738
submit_info.pWaitSemaphores = wait_semaphores.ptr();
2739
submit_info.pWaitDstStageMask = wait_semaphores_stages.ptr();
2740
submit_info.commandBufferCount = command_buffers.size();
2741
submit_info.pCommandBuffers = command_buffers.ptr();
2742
submit_info.signalSemaphoreCount = signal_semaphores.size();
2743
submit_info.pSignalSemaphores = signal_semaphores.ptr();
2744
2745
device_queue.submit_mutex.lock();
2746
err = vkQueueSubmit(device_queue.queue, 1, &submit_info, vk_fence);
2747
device_queue.submit_mutex.unlock();
2748
2749
if (err == VK_ERROR_DEVICE_LOST) {
2750
print_lost_device_info();
2751
CRASH_NOW_MSG("Vulkan device was lost.");
2752
}
2753
ERR_FAIL_COND_V(err != VK_SUCCESS, FAILED);
2754
2755
if (fence != nullptr && !command_queue->pending_semaphores_for_fence.is_empty()) {
2756
fence->queue_signaled_from = command_queue;
2757
2758
// Indicate to the fence that it should release the semaphores that were waited on this submission the next time the fence is waited on.
2759
for (uint32_t i = 0; i < command_queue->pending_semaphores_for_fence.size(); i++) {
2760
command_queue->image_semaphores_for_fences.push_back({ fence, command_queue->pending_semaphores_for_fence[i] });
2761
}
2762
2763
command_queue->pending_semaphores_for_fence.clear();
2764
}
2765
2766
if (!present_semaphores.is_empty()) {
2767
// If command buffers were executed, swap chains must wait on the present semaphore used by the command queue.
2768
wait_semaphores = present_semaphores;
2769
}
2770
}
2771
2772
if (p_swap_chains.size() > 0) {
2773
thread_local LocalVector<VkSwapchainKHR> swapchains;
2774
thread_local LocalVector<uint32_t> image_indices;
2775
thread_local LocalVector<VkResult> results;
2776
swapchains.clear();
2777
image_indices.clear();
2778
2779
for (uint32_t i = 0; i < p_swap_chains.size(); i++) {
2780
SwapChain *swap_chain = (SwapChain *)(p_swap_chains[i].id);
2781
swapchains.push_back(swap_chain->vk_swapchain);
2782
DEV_ASSERT(swap_chain->image_index < swap_chain->images.size());
2783
image_indices.push_back(swap_chain->image_index);
2784
}
2785
2786
results.resize(swapchains.size());
2787
2788
VkPresentInfoKHR present_info = {};
2789
present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
2790
present_info.waitSemaphoreCount = wait_semaphores.size();
2791
present_info.pWaitSemaphores = wait_semaphores.ptr();
2792
present_info.swapchainCount = swapchains.size();
2793
present_info.pSwapchains = swapchains.ptr();
2794
present_info.pImageIndices = image_indices.ptr();
2795
present_info.pResults = results.ptr();
2796
2797
device_queue.submit_mutex.lock();
2798
#if defined(SWAPPY_FRAME_PACING_ENABLED)
2799
if (swappy_frame_pacer_enable) {
2800
err = SwappyVk_queuePresent(device_queue.queue, &present_info);
2801
} else {
2802
err = device_functions.QueuePresentKHR(device_queue.queue, &present_info);
2803
}
2804
#else
2805
err = device_functions.QueuePresentKHR(device_queue.queue, &present_info);
2806
#endif
2807
2808
device_queue.submit_mutex.unlock();
2809
2810
// Set the index to an invalid value. If any of the swap chains returned out of date, indicate it should be resized the next time it's acquired.
2811
bool any_result_is_out_of_date = false;
2812
for (uint32_t i = 0; i < p_swap_chains.size(); i++) {
2813
SwapChain *swap_chain = (SwapChain *)(p_swap_chains[i].id);
2814
swap_chain->image_index = UINT_MAX;
2815
if (results[i] == VK_ERROR_OUT_OF_DATE_KHR) {
2816
context_driver->surface_set_needs_resize(swap_chain->surface, true);
2817
any_result_is_out_of_date = true;
2818
}
2819
}
2820
2821
if (any_result_is_out_of_date || err == VK_ERROR_OUT_OF_DATE_KHR) {
2822
// It is possible for presentation to fail with out of date while acquire might've succeeded previously. This case
2823
// will be considered a silent failure as it can be triggered easily by resizing a window in the OS natively.
2824
return FAILED;
2825
}
2826
2827
// Handling VK_SUBOPTIMAL_KHR the same as VK_SUCCESS is completely intentional.
2828
//
2829
// Godot does not currently support native rotation in Android when creating the swap chain. It intentionally uses
2830
// VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR instead of the current transform bits available in the surface capabilities.
2831
// Choosing the transform that leads to optimal presentation leads to distortion that makes the application unusable,
2832
// as the rotation of all the content is not handled at the moment.
2833
//
2834
// VK_SUBOPTIMAL_KHR is accepted as a successful case even if it's not the most efficient solution to work around this
2835
// problem. This behavior should not be changed unless the swap chain recreation uses the current transform bits, as
2836
// it'll lead to very low performance in Android by entering an endless loop where it'll always resize the swap chain
2837
// every frame.
2838
2839
ERR_FAIL_COND_V_MSG(
2840
err != VK_SUCCESS && err != VK_SUBOPTIMAL_KHR,
2841
FAILED,
2842
"QueuePresentKHR failed with error: " + get_vulkan_result(err));
2843
}
2844
2845
return OK;
2846
}
2847
2848
void RenderingDeviceDriverVulkan::command_queue_free(CommandQueueID p_cmd_queue) {
2849
DEV_ASSERT(p_cmd_queue);
2850
2851
CommandQueue *command_queue = (CommandQueue *)(p_cmd_queue.id);
2852
2853
// Erase all the semaphores used for image acquisition.
2854
for (VkSemaphore semaphore : command_queue->image_semaphores) {
2855
vkDestroySemaphore(vk_device, semaphore, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_SEMAPHORE));
2856
}
2857
2858
// Retrieve the queue family corresponding to the virtual queue.
2859
DEV_ASSERT(command_queue->queue_family < queue_families.size());
2860
TightLocalVector<Queue> &queue_family = queue_families[command_queue->queue_family];
2861
2862
// Decrease the virtual queue count.
2863
DEV_ASSERT(command_queue->queue_index < queue_family.size());
2864
DEV_ASSERT(queue_family[command_queue->queue_index].virtual_count > 0);
2865
queue_family[command_queue->queue_index].virtual_count--;
2866
2867
// Destroy the virtual queue structure.
2868
memdelete(command_queue);
2869
}
2870
2871
// ----- POOL -----
2872
2873
RDD::CommandPoolID RenderingDeviceDriverVulkan::command_pool_create(CommandQueueFamilyID p_cmd_queue_family, CommandBufferType p_cmd_buffer_type) {
2874
DEV_ASSERT(p_cmd_queue_family.id != 0);
2875
2876
uint32_t family_index = p_cmd_queue_family.id - 1;
2877
VkCommandPoolCreateInfo cmd_pool_info = {};
2878
cmd_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
2879
cmd_pool_info.queueFamilyIndex = family_index;
2880
2881
if (!command_pool_reset_enabled) {
2882
cmd_pool_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
2883
}
2884
2885
VkCommandPool vk_command_pool = VK_NULL_HANDLE;
2886
VkResult res = vkCreateCommandPool(vk_device, &cmd_pool_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_COMMAND_POOL), &vk_command_pool);
2887
ERR_FAIL_COND_V_MSG(res, CommandPoolID(), "vkCreateCommandPool failed with error " + itos(res) + ".");
2888
2889
CommandPool *command_pool = memnew(CommandPool);
2890
command_pool->vk_command_pool = vk_command_pool;
2891
command_pool->buffer_type = p_cmd_buffer_type;
2892
return CommandPoolID(command_pool);
2893
}
2894
2895
bool RenderingDeviceDriverVulkan::command_pool_reset(CommandPoolID p_cmd_pool) {
2896
DEV_ASSERT(p_cmd_pool);
2897
2898
CommandPool *command_pool = (CommandPool *)(p_cmd_pool.id);
2899
VkResult err = vkResetCommandPool(vk_device, command_pool->vk_command_pool, 0);
2900
ERR_FAIL_COND_V_MSG(err, false, "vkResetCommandPool failed with error " + itos(err) + ".");
2901
2902
return true;
2903
}
2904
2905
void RenderingDeviceDriverVulkan::command_pool_free(CommandPoolID p_cmd_pool) {
2906
DEV_ASSERT(p_cmd_pool);
2907
2908
CommandPool *command_pool = (CommandPool *)(p_cmd_pool.id);
2909
for (CommandBufferInfo *command_buffer : command_pool->command_buffers_created) {
2910
VersatileResource::free(resources_allocator, command_buffer);
2911
}
2912
2913
vkDestroyCommandPool(vk_device, command_pool->vk_command_pool, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_COMMAND_POOL));
2914
memdelete(command_pool);
2915
}
2916
2917
// ----- BUFFER -----
2918
2919
RDD::CommandBufferID RenderingDeviceDriverVulkan::command_buffer_create(CommandPoolID p_cmd_pool) {
2920
DEV_ASSERT(p_cmd_pool);
2921
2922
CommandPool *command_pool = (CommandPool *)(p_cmd_pool.id);
2923
VkCommandBufferAllocateInfo cmd_buf_info = {};
2924
cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
2925
cmd_buf_info.commandPool = command_pool->vk_command_pool;
2926
cmd_buf_info.commandBufferCount = 1;
2927
2928
if (command_pool->buffer_type == COMMAND_BUFFER_TYPE_SECONDARY) {
2929
cmd_buf_info.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
2930
} else {
2931
cmd_buf_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
2932
}
2933
2934
VkCommandBuffer vk_command_buffer = VK_NULL_HANDLE;
2935
VkResult err = vkAllocateCommandBuffers(vk_device, &cmd_buf_info, &vk_command_buffer);
2936
ERR_FAIL_COND_V_MSG(err, CommandBufferID(), "vkAllocateCommandBuffers failed with error " + itos(err) + ".");
2937
2938
CommandBufferInfo *command_buffer = VersatileResource::allocate<CommandBufferInfo>(resources_allocator);
2939
command_buffer->vk_command_buffer = vk_command_buffer;
2940
command_pool->command_buffers_created.push_back(command_buffer);
2941
return CommandBufferID(command_buffer);
2942
}
2943
2944
bool RenderingDeviceDriverVulkan::command_buffer_begin(CommandBufferID p_cmd_buffer) {
2945
CommandBufferInfo *command_buffer = (CommandBufferInfo *)(p_cmd_buffer.id);
2946
2947
VkCommandBufferBeginInfo cmd_buf_begin_info = {};
2948
cmd_buf_begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
2949
cmd_buf_begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
2950
2951
VkResult err = vkBeginCommandBuffer(command_buffer->vk_command_buffer, &cmd_buf_begin_info);
2952
ERR_FAIL_COND_V_MSG(err, false, "vkBeginCommandBuffer failed with error " + itos(err) + ".");
2953
2954
return true;
2955
}
2956
2957
bool RenderingDeviceDriverVulkan::command_buffer_begin_secondary(CommandBufferID p_cmd_buffer, RenderPassID p_render_pass, uint32_t p_subpass, FramebufferID p_framebuffer) {
2958
Framebuffer *framebuffer = (Framebuffer *)(p_framebuffer.id);
2959
RenderPassInfo *render_pass = (RenderPassInfo *)(p_render_pass.id);
2960
CommandBufferInfo *command_buffer = (CommandBufferInfo *)(p_cmd_buffer.id);
2961
2962
VkCommandBufferInheritanceInfo inheritance_info = {};
2963
inheritance_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
2964
inheritance_info.renderPass = render_pass->vk_render_pass;
2965
inheritance_info.subpass = p_subpass;
2966
inheritance_info.framebuffer = framebuffer->vk_framebuffer;
2967
2968
VkCommandBufferBeginInfo cmd_buf_begin_info = {};
2969
cmd_buf_begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
2970
cmd_buf_begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
2971
cmd_buf_begin_info.pInheritanceInfo = &inheritance_info;
2972
2973
VkResult err = vkBeginCommandBuffer(command_buffer->vk_command_buffer, &cmd_buf_begin_info);
2974
ERR_FAIL_COND_V_MSG(err, false, "vkBeginCommandBuffer failed with error " + itos(err) + ".");
2975
2976
return true;
2977
}
2978
2979
void RenderingDeviceDriverVulkan::command_buffer_end(CommandBufferID p_cmd_buffer) {
2980
CommandBufferInfo *command_buffer = (CommandBufferInfo *)(p_cmd_buffer.id);
2981
vkEndCommandBuffer(command_buffer->vk_command_buffer);
2982
}
2983
2984
void RenderingDeviceDriverVulkan::command_buffer_execute_secondary(CommandBufferID p_cmd_buffer, VectorView<CommandBufferID> p_secondary_cmd_buffers) {
2985
thread_local LocalVector<VkCommandBuffer> secondary_command_buffers;
2986
CommandBufferInfo *command_buffer = (CommandBufferInfo *)(p_cmd_buffer.id);
2987
secondary_command_buffers.resize(p_secondary_cmd_buffers.size());
2988
for (uint32_t i = 0; i < p_secondary_cmd_buffers.size(); i++) {
2989
CommandBufferInfo *secondary_command_buffer = (CommandBufferInfo *)(p_secondary_cmd_buffers[i].id);
2990
secondary_command_buffers[i] = secondary_command_buffer->vk_command_buffer;
2991
}
2992
2993
vkCmdExecuteCommands(command_buffer->vk_command_buffer, p_secondary_cmd_buffers.size(), secondary_command_buffers.ptr());
2994
}
2995
2996
/********************/
2997
/**** SWAP CHAIN ****/
2998
/********************/
2999
3000
void RenderingDeviceDriverVulkan::_swap_chain_release(SwapChain *swap_chain) {
3001
// Destroy views and framebuffers associated to the swapchain's images.
3002
for (FramebufferID framebuffer : swap_chain->framebuffers) {
3003
framebuffer_free(framebuffer);
3004
}
3005
3006
for (VkImageView view : swap_chain->image_views) {
3007
vkDestroyImageView(vk_device, view, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_IMAGE_VIEW));
3008
}
3009
3010
swap_chain->image_index = UINT_MAX;
3011
swap_chain->images.clear();
3012
swap_chain->image_views.clear();
3013
swap_chain->framebuffers.clear();
3014
3015
if (swap_chain->vk_swapchain != VK_NULL_HANDLE) {
3016
#if defined(SWAPPY_FRAME_PACING_ENABLED)
3017
if (swappy_frame_pacer_enable) {
3018
// Swappy has a bug where the ANativeWindow will be leaked if we call
3019
// SwappyVk_destroySwapchain, so we must release it by hand.
3020
SwappyVk_setWindow(vk_device, swap_chain->vk_swapchain, nullptr);
3021
SwappyVk_destroySwapchain(vk_device, swap_chain->vk_swapchain);
3022
}
3023
#endif
3024
device_functions.DestroySwapchainKHR(vk_device, swap_chain->vk_swapchain, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_SWAPCHAIN_KHR));
3025
swap_chain->vk_swapchain = VK_NULL_HANDLE;
3026
}
3027
3028
for (uint32_t i = 0; i < swap_chain->command_queues_acquired.size(); i++) {
3029
_recreate_image_semaphore(swap_chain->command_queues_acquired[i], swap_chain->command_queues_acquired_semaphores[i], false);
3030
}
3031
3032
swap_chain->command_queues_acquired.clear();
3033
swap_chain->command_queues_acquired_semaphores.clear();
3034
3035
for (VkSemaphore semaphore : swap_chain->present_semaphores) {
3036
vkDestroySemaphore(vk_device, semaphore, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_SEMAPHORE));
3037
}
3038
3039
swap_chain->present_semaphores.clear();
3040
}
3041
3042
RenderingDeviceDriver::SwapChainID RenderingDeviceDriverVulkan::swap_chain_create(RenderingContextDriver::SurfaceID p_surface) {
3043
DEV_ASSERT(p_surface != 0);
3044
3045
RenderingContextDriverVulkan::Surface *surface = (RenderingContextDriverVulkan::Surface *)(p_surface);
3046
const RenderingContextDriverVulkan::Functions &functions = context_driver->functions_get();
3047
3048
// Retrieve the formats supported by the surface.
3049
uint32_t format_count = 0;
3050
VkResult err = functions.GetPhysicalDeviceSurfaceFormatsKHR(physical_device, surface->vk_surface, &format_count, nullptr);
3051
ERR_FAIL_COND_V(err != VK_SUCCESS, SwapChainID());
3052
3053
TightLocalVector<VkSurfaceFormatKHR> formats;
3054
formats.resize(format_count);
3055
err = functions.GetPhysicalDeviceSurfaceFormatsKHR(physical_device, surface->vk_surface, &format_count, formats.ptr());
3056
ERR_FAIL_COND_V(err != VK_SUCCESS, SwapChainID());
3057
3058
VkFormat format = VK_FORMAT_UNDEFINED;
3059
VkColorSpaceKHR color_space = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
3060
if (format_count == 1 && formats[0].format == VK_FORMAT_UNDEFINED) {
3061
// If the format list includes just one entry of VK_FORMAT_UNDEFINED, the surface has no preferred format.
3062
format = VK_FORMAT_B8G8R8A8_UNORM;
3063
color_space = formats[0].colorSpace;
3064
} else if (format_count > 0) {
3065
// Use one of the supported formats, prefer B8G8R8A8_UNORM.
3066
const VkFormat preferred_format = VK_FORMAT_B8G8R8A8_UNORM;
3067
const VkFormat second_format = VK_FORMAT_R8G8B8A8_UNORM;
3068
for (uint32_t i = 0; i < format_count; i++) {
3069
if (formats[i].format == preferred_format || formats[i].format == second_format) {
3070
format = formats[i].format;
3071
if (formats[i].format == preferred_format) {
3072
// This is the preferred format, stop searching.
3073
break;
3074
}
3075
}
3076
}
3077
}
3078
3079
// No formats are supported.
3080
ERR_FAIL_COND_V_MSG(format == VK_FORMAT_UNDEFINED, SwapChainID(), "Surface did not return any valid formats.");
3081
3082
// Create the render pass for the chosen format.
3083
VkAttachmentDescription2KHR attachment = {};
3084
attachment.sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR;
3085
attachment.format = format;
3086
attachment.samples = VK_SAMPLE_COUNT_1_BIT;
3087
attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
3088
attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
3089
attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
3090
attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
3091
attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
3092
attachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
3093
3094
VkAttachmentReference2KHR color_reference = {};
3095
color_reference.sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR;
3096
color_reference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
3097
3098
VkSubpassDescription2KHR subpass = {};
3099
subpass.sType = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR;
3100
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
3101
subpass.colorAttachmentCount = 1;
3102
subpass.pColorAttachments = &color_reference;
3103
3104
VkRenderPassCreateInfo2KHR pass_info = {};
3105
pass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR;
3106
pass_info.attachmentCount = 1;
3107
pass_info.pAttachments = &attachment;
3108
pass_info.subpassCount = 1;
3109
pass_info.pSubpasses = &subpass;
3110
3111
VkRenderPass vk_render_pass = VK_NULL_HANDLE;
3112
err = _create_render_pass(vk_device, &pass_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_RENDER_PASS), &vk_render_pass);
3113
ERR_FAIL_COND_V(err != VK_SUCCESS, SwapChainID());
3114
3115
RenderPassInfo *render_pass_info = VersatileResource::allocate<RenderPassInfo>(resources_allocator);
3116
render_pass_info->vk_render_pass = vk_render_pass;
3117
3118
SwapChain *swap_chain = memnew(SwapChain);
3119
swap_chain->surface = p_surface;
3120
swap_chain->format = format;
3121
swap_chain->color_space = color_space;
3122
swap_chain->render_pass = RenderPassID(render_pass_info);
3123
return SwapChainID(swap_chain);
3124
}
3125
3126
Error RenderingDeviceDriverVulkan::swap_chain_resize(CommandQueueID p_cmd_queue, SwapChainID p_swap_chain, uint32_t p_desired_framebuffer_count) {
3127
DEV_ASSERT(p_cmd_queue.id != 0);
3128
DEV_ASSERT(p_swap_chain.id != 0);
3129
3130
CommandQueue *command_queue = (CommandQueue *)(p_cmd_queue.id);
3131
SwapChain *swap_chain = (SwapChain *)(p_swap_chain.id);
3132
3133
// Release all current contents of the swap chain.
3134
_swap_chain_release(swap_chain);
3135
3136
// Validate if the command queue being used supports creating the swap chain for this surface.
3137
const RenderingContextDriverVulkan::Functions &functions = context_driver->functions_get();
3138
if (!context_driver->queue_family_supports_present(physical_device, command_queue->queue_family, swap_chain->surface)) {
3139
ERR_FAIL_V_MSG(ERR_CANT_CREATE, "Surface is not supported by device. Did the GPU go offline? Was the window created on another monitor? Check"
3140
"previous errors & try launching with --gpu-validation.");
3141
}
3142
3143
// Retrieve the surface's capabilities.
3144
RenderingContextDriverVulkan::Surface *surface = (RenderingContextDriverVulkan::Surface *)(swap_chain->surface);
3145
VkSurfaceCapabilitiesKHR surface_capabilities = {};
3146
VkResult err = functions.GetPhysicalDeviceSurfaceCapabilitiesKHR(physical_device, surface->vk_surface, &surface_capabilities);
3147
ERR_FAIL_COND_V(err != VK_SUCCESS, ERR_CANT_CREATE);
3148
3149
// No swapchain yet, this is the first time we're creating it.
3150
if (!swap_chain->vk_swapchain) {
3151
if (surface_capabilities.currentExtent.width == 0xFFFFFFFF) {
3152
// The current extent is currently undefined, so the current surface width and height will be clamped to the surface's capabilities.
3153
// We make sure to overwrite surface_capabilities.currentExtent.width so that the same check further below
3154
// does not set extent.width = CLAMP( surface->width, ... ) on the first run of this function, because
3155
// that'd be potentially unswapped.
3156
surface_capabilities.currentExtent.width = CLAMP(surface->width, surface_capabilities.minImageExtent.width, surface_capabilities.maxImageExtent.width);
3157
surface_capabilities.currentExtent.height = CLAMP(surface->height, surface_capabilities.minImageExtent.height, surface_capabilities.maxImageExtent.height);
3158
}
3159
3160
// We must SWAP() only once otherwise we'll keep ping-ponging between
3161
// the right and wrong resolutions after multiple calls to swap_chain_resize().
3162
if (surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR ||
3163
surface_capabilities.currentTransform & VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR) {
3164
// Swap to get identity width and height.
3165
SWAP(surface_capabilities.currentExtent.width, surface_capabilities.currentExtent.height);
3166
}
3167
}
3168
3169
VkExtent2D extent;
3170
if (surface_capabilities.currentExtent.width == 0xFFFFFFFF) {
3171
// The current extent is currently undefined, so the current surface width and height will be clamped to the surface's capabilities.
3172
// We can only be here on the second call to swap_chain_resize(), by which time surface->width & surface->height should already be swapped if needed.
3173
extent.width = CLAMP(surface->width, surface_capabilities.minImageExtent.width, surface_capabilities.maxImageExtent.width);
3174
extent.height = CLAMP(surface->height, surface_capabilities.minImageExtent.height, surface_capabilities.maxImageExtent.height);
3175
} else {
3176
// Grab the dimensions from the current extent.
3177
extent = surface_capabilities.currentExtent;
3178
surface->width = extent.width;
3179
surface->height = extent.height;
3180
}
3181
3182
if (surface->width == 0 || surface->height == 0) {
3183
// The surface doesn't have valid dimensions, so we can't create a swap chain.
3184
return ERR_SKIP;
3185
}
3186
3187
// Find what present modes are supported.
3188
TightLocalVector<VkPresentModeKHR> present_modes;
3189
uint32_t present_modes_count = 0;
3190
err = functions.GetPhysicalDeviceSurfacePresentModesKHR(physical_device, surface->vk_surface, &present_modes_count, nullptr);
3191
ERR_FAIL_COND_V(err != VK_SUCCESS, ERR_CANT_CREATE);
3192
3193
present_modes.resize(present_modes_count);
3194
err = functions.GetPhysicalDeviceSurfacePresentModesKHR(physical_device, surface->vk_surface, &present_modes_count, present_modes.ptr());
3195
ERR_FAIL_COND_V(err != VK_SUCCESS, ERR_CANT_CREATE);
3196
3197
// Choose the present mode based on the display server setting.
3198
VkPresentModeKHR present_mode = VkPresentModeKHR::VK_PRESENT_MODE_FIFO_KHR;
3199
String present_mode_name = "Enabled";
3200
switch (surface->vsync_mode) {
3201
case DisplayServer::VSYNC_MAILBOX:
3202
present_mode = VK_PRESENT_MODE_MAILBOX_KHR;
3203
present_mode_name = "Mailbox";
3204
break;
3205
case DisplayServer::VSYNC_ADAPTIVE:
3206
present_mode = VK_PRESENT_MODE_FIFO_RELAXED_KHR;
3207
present_mode_name = "Adaptive";
3208
break;
3209
case DisplayServer::VSYNC_ENABLED:
3210
present_mode = VK_PRESENT_MODE_FIFO_KHR;
3211
present_mode_name = "Enabled";
3212
break;
3213
case DisplayServer::VSYNC_DISABLED:
3214
present_mode = VK_PRESENT_MODE_IMMEDIATE_KHR;
3215
present_mode_name = "Disabled";
3216
break;
3217
}
3218
3219
bool present_mode_available = present_modes.has(present_mode);
3220
if (!present_mode_available) {
3221
// Present mode is not available, fall back to FIFO which is guaranteed to be supported.
3222
WARN_PRINT(vformat("The requested V-Sync mode %s is not available. Falling back to V-Sync mode Enabled.", present_mode_name));
3223
surface->vsync_mode = DisplayServer::VSYNC_ENABLED;
3224
present_mode = VkPresentModeKHR::VK_PRESENT_MODE_FIFO_KHR;
3225
}
3226
3227
// Clamp the desired image count to the surface's capabilities.
3228
uint32_t desired_swapchain_images = MAX(p_desired_framebuffer_count, surface_capabilities.minImageCount);
3229
if (surface_capabilities.maxImageCount > 0) {
3230
// Only clamp to the max image count if it's defined. A max image count of 0 means there's no upper limit to the amount of images.
3231
desired_swapchain_images = MIN(desired_swapchain_images, surface_capabilities.maxImageCount);
3232
}
3233
3234
// Refer to the comment in command_queue_present() for more details.
3235
VkSurfaceTransformFlagBitsKHR surface_transform_bits = surface_capabilities.currentTransform;
3236
3237
VkCompositeAlphaFlagBitsKHR composite_alpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
3238
if (OS::get_singleton()->is_layered_allowed() || !(surface_capabilities.supportedCompositeAlpha & composite_alpha)) {
3239
// Find a supported composite alpha mode - one of these is guaranteed to be set.
3240
VkCompositeAlphaFlagBitsKHR composite_alpha_flags[4] = {
3241
VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR,
3242
VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR,
3243
VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR,
3244
VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR
3245
};
3246
3247
for (uint32_t i = 0; i < ARRAY_SIZE(composite_alpha_flags); i++) {
3248
if (surface_capabilities.supportedCompositeAlpha & composite_alpha_flags[i]) {
3249
composite_alpha = composite_alpha_flags[i];
3250
break;
3251
}
3252
}
3253
has_comp_alpha[(uint64_t)p_cmd_queue.id] = (composite_alpha != VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR);
3254
}
3255
3256
VkSwapchainCreateInfoKHR swap_create_info = {};
3257
swap_create_info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
3258
swap_create_info.surface = surface->vk_surface;
3259
swap_create_info.minImageCount = desired_swapchain_images;
3260
swap_create_info.imageFormat = swap_chain->format;
3261
swap_create_info.imageColorSpace = swap_chain->color_space;
3262
swap_create_info.imageExtent = extent;
3263
swap_create_info.imageArrayLayers = 1;
3264
swap_create_info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
3265
swap_create_info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
3266
swap_create_info.preTransform = surface_transform_bits;
3267
switch (swap_create_info.preTransform) {
3268
case VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR:
3269
swap_chain->pre_transform_rotation_degrees = 0;
3270
break;
3271
case VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR:
3272
swap_chain->pre_transform_rotation_degrees = 90;
3273
break;
3274
case VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR:
3275
swap_chain->pre_transform_rotation_degrees = 180;
3276
break;
3277
case VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR:
3278
swap_chain->pre_transform_rotation_degrees = 270;
3279
break;
3280
default:
3281
WARN_PRINT("Unexpected swap_create_info.preTransform = " + itos(swap_create_info.preTransform) + ".");
3282
swap_chain->pre_transform_rotation_degrees = 0;
3283
break;
3284
}
3285
swap_create_info.compositeAlpha = composite_alpha;
3286
swap_create_info.presentMode = present_mode;
3287
swap_create_info.clipped = true;
3288
err = device_functions.CreateSwapchainKHR(vk_device, &swap_create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_SWAPCHAIN_KHR), &swap_chain->vk_swapchain);
3289
ERR_FAIL_COND_V(err != VK_SUCCESS, ERR_CANT_CREATE);
3290
3291
#if defined(SWAPPY_FRAME_PACING_ENABLED)
3292
if (swappy_frame_pacer_enable) {
3293
SwappyVk_initAndGetRefreshCycleDuration(get_jni_env(), static_cast<OS_Android *>(OS::get_singleton())->get_godot_java()->get_activity(), physical_device,
3294
vk_device, swap_chain->vk_swapchain, &swap_chain->refresh_duration);
3295
SwappyVk_setWindow(vk_device, swap_chain->vk_swapchain, static_cast<OS_Android *>(OS::get_singleton())->get_native_window());
3296
SwappyVk_setSwapIntervalNS(vk_device, swap_chain->vk_swapchain, swap_chain->refresh_duration);
3297
3298
enum SwappyModes {
3299
PIPELINE_FORCED_ON,
3300
AUTO_FPS_PIPELINE_FORCED_ON,
3301
AUTO_FPS_AUTO_PIPELINE,
3302
};
3303
3304
switch (swappy_mode) {
3305
case PIPELINE_FORCED_ON:
3306
SwappyVk_setAutoSwapInterval(true);
3307
SwappyVk_setAutoPipelineMode(true);
3308
break;
3309
case AUTO_FPS_PIPELINE_FORCED_ON:
3310
SwappyVk_setAutoSwapInterval(true);
3311
SwappyVk_setAutoPipelineMode(false);
3312
break;
3313
case AUTO_FPS_AUTO_PIPELINE:
3314
SwappyVk_setAutoSwapInterval(false);
3315
SwappyVk_setAutoPipelineMode(false);
3316
break;
3317
}
3318
}
3319
#endif
3320
3321
uint32_t image_count = 0;
3322
err = device_functions.GetSwapchainImagesKHR(vk_device, swap_chain->vk_swapchain, &image_count, nullptr);
3323
ERR_FAIL_COND_V(err != VK_SUCCESS, ERR_CANT_CREATE);
3324
3325
swap_chain->images.resize(image_count);
3326
err = device_functions.GetSwapchainImagesKHR(vk_device, swap_chain->vk_swapchain, &image_count, swap_chain->images.ptr());
3327
ERR_FAIL_COND_V(err != VK_SUCCESS, ERR_CANT_CREATE);
3328
3329
VkImageViewCreateInfo view_create_info = {};
3330
view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
3331
view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
3332
view_create_info.format = swap_chain->format;
3333
view_create_info.components.r = VK_COMPONENT_SWIZZLE_R;
3334
view_create_info.components.g = VK_COMPONENT_SWIZZLE_G;
3335
view_create_info.components.b = VK_COMPONENT_SWIZZLE_B;
3336
view_create_info.components.a = VK_COMPONENT_SWIZZLE_A;
3337
view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3338
view_create_info.subresourceRange.levelCount = 1;
3339
view_create_info.subresourceRange.layerCount = 1;
3340
3341
swap_chain->image_views.reserve(image_count);
3342
3343
VkImageView image_view;
3344
for (uint32_t i = 0; i < image_count; i++) {
3345
view_create_info.image = swap_chain->images[i];
3346
err = vkCreateImageView(vk_device, &view_create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_IMAGE_VIEW), &image_view);
3347
ERR_FAIL_COND_V(err != VK_SUCCESS, ERR_CANT_CREATE);
3348
3349
swap_chain->image_views.push_back(image_view);
3350
}
3351
3352
swap_chain->framebuffers.reserve(image_count);
3353
3354
const RenderPassInfo *render_pass = (const RenderPassInfo *)(swap_chain->render_pass.id);
3355
VkFramebufferCreateInfo fb_create_info = {};
3356
fb_create_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
3357
fb_create_info.renderPass = render_pass->vk_render_pass;
3358
fb_create_info.attachmentCount = 1;
3359
fb_create_info.width = surface->width;
3360
fb_create_info.height = surface->height;
3361
fb_create_info.layers = 1;
3362
3363
VkFramebuffer vk_framebuffer;
3364
for (uint32_t i = 0; i < image_count; i++) {
3365
fb_create_info.pAttachments = &swap_chain->image_views[i];
3366
err = vkCreateFramebuffer(vk_device, &fb_create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_FRAMEBUFFER), &vk_framebuffer);
3367
ERR_FAIL_COND_V(err != VK_SUCCESS, ERR_CANT_CREATE);
3368
3369
Framebuffer *framebuffer = memnew(Framebuffer);
3370
framebuffer->vk_framebuffer = vk_framebuffer;
3371
framebuffer->swap_chain_image = swap_chain->images[i];
3372
framebuffer->swap_chain_image_subresource_range = view_create_info.subresourceRange;
3373
swap_chain->framebuffers.push_back(RDD::FramebufferID(framebuffer));
3374
}
3375
3376
VkSemaphore vk_semaphore = VK_NULL_HANDLE;
3377
for (uint32_t i = 0; i < image_count; i++) {
3378
VkSemaphoreCreateInfo create_info = {};
3379
create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
3380
3381
err = vkCreateSemaphore(vk_device, &create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_SEMAPHORE), &vk_semaphore);
3382
ERR_FAIL_COND_V(err != VK_SUCCESS, FAILED);
3383
3384
swap_chain->present_semaphores.push_back(vk_semaphore);
3385
}
3386
3387
// Once everything's been created correctly, indicate the surface no longer needs to be resized.
3388
context_driver->surface_set_needs_resize(swap_chain->surface, false);
3389
3390
return OK;
3391
}
3392
3393
RDD::FramebufferID RenderingDeviceDriverVulkan::swap_chain_acquire_framebuffer(CommandQueueID p_cmd_queue, SwapChainID p_swap_chain, bool &r_resize_required) {
3394
DEV_ASSERT(p_cmd_queue);
3395
DEV_ASSERT(p_swap_chain);
3396
3397
CommandQueue *command_queue = (CommandQueue *)(p_cmd_queue.id);
3398
SwapChain *swap_chain = (SwapChain *)(p_swap_chain.id);
3399
if ((swap_chain->vk_swapchain == VK_NULL_HANDLE) || context_driver->surface_get_needs_resize(swap_chain->surface)) {
3400
// The surface does not have a valid swap chain or it indicates it requires a resize.
3401
r_resize_required = true;
3402
return FramebufferID();
3403
}
3404
3405
VkResult err;
3406
VkSemaphore semaphore = VK_NULL_HANDLE;
3407
uint32_t semaphore_index = 0;
3408
if (command_queue->free_image_semaphores.is_empty()) {
3409
// Add a new semaphore if none are free.
3410
VkSemaphoreCreateInfo create_info = {};
3411
create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
3412
err = vkCreateSemaphore(vk_device, &create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_SEMAPHORE), &semaphore);
3413
ERR_FAIL_COND_V(err != VK_SUCCESS, FramebufferID());
3414
3415
semaphore_index = command_queue->image_semaphores.size();
3416
command_queue->image_semaphores.push_back(semaphore);
3417
command_queue->image_semaphores_swap_chains.push_back(swap_chain);
3418
} else {
3419
// Pick a free semaphore.
3420
uint32_t free_index = command_queue->free_image_semaphores.size() - 1;
3421
semaphore_index = command_queue->free_image_semaphores[free_index];
3422
command_queue->image_semaphores_swap_chains[semaphore_index] = swap_chain;
3423
command_queue->free_image_semaphores.remove_at(free_index);
3424
semaphore = command_queue->image_semaphores[semaphore_index];
3425
}
3426
3427
// Store in the swap chain the acquired semaphore.
3428
swap_chain->command_queues_acquired.push_back(command_queue);
3429
swap_chain->command_queues_acquired_semaphores.push_back(semaphore_index);
3430
3431
err = device_functions.AcquireNextImageKHR(vk_device, swap_chain->vk_swapchain, UINT64_MAX, semaphore, VK_NULL_HANDLE, &swap_chain->image_index);
3432
if (err == VK_ERROR_OUT_OF_DATE_KHR) {
3433
// Out of date leaves the semaphore in a signaled state that will never finish, so it's necessary to recreate it.
3434
bool semaphore_recreated = _recreate_image_semaphore(command_queue, semaphore_index, true);
3435
ERR_FAIL_COND_V(!semaphore_recreated, FramebufferID());
3436
3437
// Swap chain is out of date and must be recreated.
3438
r_resize_required = true;
3439
return FramebufferID();
3440
} else if (err != VK_SUCCESS && err != VK_SUBOPTIMAL_KHR) {
3441
// Swap chain failed to present but the reason is unknown.
3442
// Refer to the comment in command_queue_present() as to why VK_SUBOPTIMAL_KHR is handled the same as VK_SUCCESS.
3443
return FramebufferID();
3444
}
3445
3446
// Indicate the command queue should wait on these semaphores on the next submission and that it should
3447
// indicate they're free again on the next fence.
3448
command_queue->pending_semaphores_for_execute.push_back(semaphore_index);
3449
command_queue->pending_semaphores_for_fence.push_back(semaphore_index);
3450
3451
// Return the corresponding framebuffer to the new current image.
3452
FramebufferID framebuffer_id = swap_chain->framebuffers[swap_chain->image_index];
3453
Framebuffer *framebuffer = (Framebuffer *)(framebuffer_id.id);
3454
framebuffer->swap_chain_acquired = true;
3455
return framebuffer_id;
3456
}
3457
3458
RDD::RenderPassID RenderingDeviceDriverVulkan::swap_chain_get_render_pass(SwapChainID p_swap_chain) {
3459
DEV_ASSERT(p_swap_chain.id != 0);
3460
3461
SwapChain *swap_chain = (SwapChain *)(p_swap_chain.id);
3462
return swap_chain->render_pass;
3463
}
3464
3465
int RenderingDeviceDriverVulkan::swap_chain_get_pre_rotation_degrees(SwapChainID p_swap_chain) {
3466
DEV_ASSERT(p_swap_chain.id != 0);
3467
3468
SwapChain *swap_chain = (SwapChain *)(p_swap_chain.id);
3469
return swap_chain->pre_transform_rotation_degrees;
3470
}
3471
3472
RDD::DataFormat RenderingDeviceDriverVulkan::swap_chain_get_format(SwapChainID p_swap_chain) {
3473
DEV_ASSERT(p_swap_chain.id != 0);
3474
3475
SwapChain *swap_chain = (SwapChain *)(p_swap_chain.id);
3476
switch (swap_chain->format) {
3477
case VK_FORMAT_B8G8R8A8_UNORM:
3478
return DATA_FORMAT_B8G8R8A8_UNORM;
3479
case VK_FORMAT_R8G8B8A8_UNORM:
3480
return DATA_FORMAT_R8G8B8A8_UNORM;
3481
default:
3482
DEV_ASSERT(false && "Unknown swap chain format.");
3483
return DATA_FORMAT_MAX;
3484
}
3485
}
3486
3487
void RenderingDeviceDriverVulkan::swap_chain_set_max_fps(SwapChainID p_swap_chain, int p_max_fps) {
3488
DEV_ASSERT(p_swap_chain.id != 0);
3489
3490
#ifdef SWAPPY_FRAME_PACING_ENABLED
3491
if (!swappy_frame_pacer_enable) {
3492
return;
3493
}
3494
3495
SwapChain *swap_chain = (SwapChain *)(p_swap_chain.id);
3496
if (swap_chain->vk_swapchain != VK_NULL_HANDLE) {
3497
const uint64_t max_time = p_max_fps > 0 ? uint64_t((1000.0 * 1000.0 * 1000.0) / p_max_fps) : 0;
3498
SwappyVk_setSwapIntervalNS(vk_device, swap_chain->vk_swapchain, MAX(swap_chain->refresh_duration, max_time));
3499
}
3500
#endif
3501
}
3502
3503
void RenderingDeviceDriverVulkan::swap_chain_free(SwapChainID p_swap_chain) {
3504
DEV_ASSERT(p_swap_chain.id != 0);
3505
3506
SwapChain *swap_chain = (SwapChain *)(p_swap_chain.id);
3507
_swap_chain_release(swap_chain);
3508
3509
if (swap_chain->render_pass) {
3510
render_pass_free(swap_chain->render_pass);
3511
}
3512
3513
memdelete(swap_chain);
3514
}
3515
3516
/*********************/
3517
/**** FRAMEBUFFER ****/
3518
/*********************/
3519
3520
RDD::FramebufferID RenderingDeviceDriverVulkan::framebuffer_create(RenderPassID p_render_pass, VectorView<TextureID> p_attachments, uint32_t p_width, uint32_t p_height) {
3521
RenderPassInfo *render_pass = (RenderPassInfo *)(p_render_pass.id);
3522
3523
uint32_t fragment_density_map_offsets_layers = 0;
3524
VkImageView *vk_img_views = ALLOCA_ARRAY(VkImageView, p_attachments.size());
3525
for (uint32_t i = 0; i < p_attachments.size(); i++) {
3526
const TextureInfo *texture = (const TextureInfo *)p_attachments[i].id;
3527
vk_img_views[i] = texture->vk_view;
3528
3529
if (render_pass->uses_fragment_density_map_offsets && (texture->vk_create_info.usage & VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT)) {
3530
// If the render pass uses the FDM and the usage fits, we store the amount of layers to use it later on the render pass's end.
3531
fragment_density_map_offsets_layers = texture->vk_create_info.arrayLayers;
3532
}
3533
}
3534
3535
VkFramebufferCreateInfo framebuffer_create_info = {};
3536
framebuffer_create_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
3537
framebuffer_create_info.renderPass = render_pass->vk_render_pass;
3538
framebuffer_create_info.attachmentCount = p_attachments.size();
3539
framebuffer_create_info.pAttachments = vk_img_views;
3540
framebuffer_create_info.width = p_width;
3541
framebuffer_create_info.height = p_height;
3542
framebuffer_create_info.layers = 1;
3543
3544
VkFramebuffer vk_framebuffer = VK_NULL_HANDLE;
3545
VkResult err = vkCreateFramebuffer(vk_device, &framebuffer_create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_FRAMEBUFFER), &vk_framebuffer);
3546
ERR_FAIL_COND_V_MSG(err, FramebufferID(), "vkCreateFramebuffer failed with error " + itos(err) + ".");
3547
3548
#if PRINT_NATIVE_COMMANDS
3549
print_line(vformat("vkCreateFramebuffer 0x%uX with %d attachments", uint64_t(vk_framebuffer), p_attachments.size()));
3550
for (uint32_t i = 0; i < p_attachments.size(); i++) {
3551
const TextureInfo *attachment_info = (const TextureInfo *)p_attachments[i].id;
3552
print_line(vformat(" Attachment #%d: IMAGE 0x%uX VIEW 0x%uX", i, uint64_t(attachment_info->vk_view_create_info.image), uint64_t(attachment_info->vk_view)));
3553
}
3554
#endif
3555
3556
Framebuffer *framebuffer = memnew(Framebuffer);
3557
framebuffer->vk_framebuffer = vk_framebuffer;
3558
framebuffer->fragment_density_map_offsets_layers = fragment_density_map_offsets_layers;
3559
return FramebufferID(framebuffer);
3560
}
3561
3562
void RenderingDeviceDriverVulkan::framebuffer_free(FramebufferID p_framebuffer) {
3563
Framebuffer *framebuffer = (Framebuffer *)(p_framebuffer.id);
3564
vkDestroyFramebuffer(vk_device, framebuffer->vk_framebuffer, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_FRAMEBUFFER));
3565
memdelete(framebuffer);
3566
}
3567
3568
/****************/
3569
/**** SHADER ****/
3570
/****************/
3571
3572
static VkShaderStageFlagBits RD_STAGE_TO_VK_SHADER_STAGE_BITS[RDD::SHADER_STAGE_MAX] = {
3573
VK_SHADER_STAGE_VERTEX_BIT,
3574
VK_SHADER_STAGE_FRAGMENT_BIT,
3575
VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
3576
VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
3577
VK_SHADER_STAGE_COMPUTE_BIT,
3578
};
3579
3580
RDD::ShaderID RenderingDeviceDriverVulkan::shader_create_from_container(const Ref<RenderingShaderContainer> &p_shader_container, const Vector<ImmutableSampler> &p_immutable_samplers) {
3581
ShaderReflection shader_refl = p_shader_container->get_shader_reflection();
3582
ShaderInfo shader_info;
3583
for (uint32_t i = 0; i < SHADER_STAGE_MAX; i++) {
3584
if (shader_refl.push_constant_stages.has_flag((ShaderStage)(1 << i))) {
3585
shader_info.vk_push_constant_stages |= RD_STAGE_TO_VK_SHADER_STAGE_BITS[i];
3586
}
3587
}
3588
3589
// Set bindings.
3590
Vector<Vector<VkDescriptorSetLayoutBinding>> vk_set_bindings;
3591
vk_set_bindings.resize(shader_refl.uniform_sets.size());
3592
for (uint32_t i = 0; i < shader_refl.uniform_sets.size(); i++) {
3593
for (uint32_t j = 0; j < shader_refl.uniform_sets[i].size(); j++) {
3594
const ShaderUniform &uniform = shader_refl.uniform_sets[i][j];
3595
VkDescriptorSetLayoutBinding layout_binding = {};
3596
layout_binding.binding = uniform.binding;
3597
layout_binding.descriptorCount = 1;
3598
for (uint32_t k = 0; k < SHADER_STAGE_MAX; k++) {
3599
if ((uniform.stages.has_flag(ShaderStage(1U << k)))) {
3600
layout_binding.stageFlags |= RD_STAGE_TO_VK_SHADER_STAGE_BITS[k];
3601
}
3602
}
3603
3604
switch (uniform.type) {
3605
case UNIFORM_TYPE_SAMPLER: {
3606
layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
3607
layout_binding.descriptorCount = uniform.length;
3608
// Immutable samplers: here they get set in the layoutbinding, given that they will not be changed later.
3609
int immutable_bind_index = -1;
3610
if (immutable_samplers_enabled && p_immutable_samplers.size() > 0) {
3611
for (int k = 0; k < p_immutable_samplers.size(); k++) {
3612
if (p_immutable_samplers[k].binding == layout_binding.binding) {
3613
immutable_bind_index = k;
3614
break;
3615
}
3616
}
3617
if (immutable_bind_index >= 0) {
3618
layout_binding.pImmutableSamplers = (VkSampler *)&p_immutable_samplers[immutable_bind_index].ids[0].id;
3619
}
3620
}
3621
} break;
3622
case UNIFORM_TYPE_SAMPLER_WITH_TEXTURE: {
3623
layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
3624
layout_binding.descriptorCount = uniform.length;
3625
} break;
3626
case UNIFORM_TYPE_TEXTURE: {
3627
layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
3628
layout_binding.descriptorCount = uniform.length;
3629
} break;
3630
case UNIFORM_TYPE_IMAGE: {
3631
layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
3632
layout_binding.descriptorCount = uniform.length;
3633
} break;
3634
case UNIFORM_TYPE_TEXTURE_BUFFER: {
3635
layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
3636
layout_binding.descriptorCount = uniform.length;
3637
} break;
3638
case UNIFORM_TYPE_IMAGE_BUFFER: {
3639
layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
3640
} break;
3641
case UNIFORM_TYPE_UNIFORM_BUFFER: {
3642
layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
3643
} break;
3644
case UNIFORM_TYPE_STORAGE_BUFFER: {
3645
layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
3646
} break;
3647
case UNIFORM_TYPE_INPUT_ATTACHMENT: {
3648
layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
3649
} break;
3650
default: {
3651
DEV_ASSERT(false);
3652
}
3653
}
3654
3655
vk_set_bindings.write[i].push_back(layout_binding);
3656
}
3657
}
3658
3659
// Modules.
3660
VkResult res;
3661
String error_text;
3662
Vector<uint8_t> decompressed_code;
3663
Vector<uint8_t> decoded_spirv;
3664
VkShaderModule vk_module;
3665
for (int i = 0; i < shader_refl.stages_vector.size(); i++) {
3666
const RenderingShaderContainer::Shader &shader = p_shader_container->shaders[i];
3667
bool requires_decompression = (shader.code_decompressed_size > 0);
3668
if (requires_decompression) {
3669
decompressed_code.resize(shader.code_decompressed_size);
3670
bool decompressed = p_shader_container->decompress_code(shader.code_compressed_bytes.ptr(), shader.code_compressed_bytes.size(), shader.code_compression_flags, decompressed_code.ptrw(), decompressed_code.size());
3671
if (!decompressed) {
3672
error_text = vformat("Failed to decompress code on shader stage %s.", String(SHADER_STAGE_NAMES[shader_refl.stages_vector[i]]));
3673
break;
3674
}
3675
}
3676
3677
const uint8_t *smolv_input = requires_decompression ? decompressed_code.ptr() : shader.code_compressed_bytes.ptr();
3678
uint32_t smolv_input_size = requires_decompression ? decompressed_code.size() : shader.code_compressed_bytes.size();
3679
if (shader.code_compression_flags & RenderingShaderContainerVulkan::COMPRESSION_FLAG_SMOLV) {
3680
decoded_spirv.resize(smolv::GetDecodedBufferSize(smolv_input, smolv_input_size));
3681
if (decoded_spirv.is_empty()) {
3682
error_text = vformat("Malformed smolv input on shader stage %s.", String(SHADER_STAGE_NAMES[shader_refl.stages_vector[i]]));
3683
break;
3684
}
3685
3686
if (!smolv::Decode(smolv_input, smolv_input_size, decoded_spirv.ptrw(), decoded_spirv.size())) {
3687
error_text = vformat("Malformed smolv input on shader stage %s.", String(SHADER_STAGE_NAMES[shader_refl.stages_vector[i]]));
3688
break;
3689
}
3690
} else {
3691
decoded_spirv.resize(smolv_input_size);
3692
memcpy(decoded_spirv.ptrw(), smolv_input, decoded_spirv.size());
3693
}
3694
3695
VkShaderModuleCreateInfo shader_module_create_info = {};
3696
shader_module_create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
3697
shader_module_create_info.codeSize = decoded_spirv.size();
3698
shader_module_create_info.pCode = (const uint32_t *)(decoded_spirv.ptr());
3699
3700
res = vkCreateShaderModule(vk_device, &shader_module_create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_SHADER_MODULE), &vk_module);
3701
if (res != VK_SUCCESS) {
3702
error_text = vformat("Error (%d) creating module for shader stage %s.", res, String(SHADER_STAGE_NAMES[shader_refl.stages_vector[i]]));
3703
break;
3704
}
3705
3706
VkPipelineShaderStageCreateInfo create_info = {};
3707
create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
3708
create_info.stage = RD_STAGE_TO_VK_SHADER_STAGE_BITS[shader_refl.stages_vector[i]];
3709
create_info.module = vk_module;
3710
create_info.pName = "main";
3711
shader_info.vk_stages_create_info.push_back(create_info);
3712
}
3713
3714
// Descriptor sets.
3715
if (error_text.is_empty()) {
3716
for (uint32_t i = 0; i < shader_refl.uniform_sets.size(); i++) {
3717
// Empty ones are fine if they were not used according to spec (binding count will be 0).
3718
VkDescriptorSetLayoutCreateInfo layout_create_info = {};
3719
layout_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
3720
layout_create_info.bindingCount = vk_set_bindings[i].size();
3721
layout_create_info.pBindings = vk_set_bindings[i].ptr();
3722
3723
VkDescriptorSetLayout layout = VK_NULL_HANDLE;
3724
res = vkCreateDescriptorSetLayout(vk_device, &layout_create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT), &layout);
3725
if (res) {
3726
error_text = vformat("Error (%d) creating descriptor set layout for set %d.", res, i);
3727
break;
3728
}
3729
3730
shader_info.vk_descriptor_set_layouts.push_back(layout);
3731
}
3732
}
3733
3734
if (error_text.is_empty()) {
3735
// Pipeline layout.
3736
VkPipelineLayoutCreateInfo pipeline_layout_create_info = {};
3737
pipeline_layout_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
3738
pipeline_layout_create_info.setLayoutCount = shader_info.vk_descriptor_set_layouts.size();
3739
pipeline_layout_create_info.pSetLayouts = shader_info.vk_descriptor_set_layouts.ptr();
3740
3741
if (shader_refl.push_constant_size > 0) {
3742
VkPushConstantRange *push_constant_range = ALLOCA_SINGLE(VkPushConstantRange);
3743
*push_constant_range = {};
3744
push_constant_range->stageFlags = shader_info.vk_push_constant_stages;
3745
push_constant_range->size = shader_refl.push_constant_size;
3746
pipeline_layout_create_info.pushConstantRangeCount = 1;
3747
pipeline_layout_create_info.pPushConstantRanges = push_constant_range;
3748
}
3749
3750
res = vkCreatePipelineLayout(vk_device, &pipeline_layout_create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_PIPELINE_LAYOUT), &shader_info.vk_pipeline_layout);
3751
if (res != VK_SUCCESS) {
3752
error_text = vformat("Error (%d) creating pipeline layout.", res);
3753
}
3754
}
3755
3756
if (!error_text.is_empty()) {
3757
// Clean up if failed.
3758
for (uint32_t i = 0; i < shader_info.vk_stages_create_info.size(); i++) {
3759
vkDestroyShaderModule(vk_device, shader_info.vk_stages_create_info[i].module, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_SHADER_MODULE));
3760
}
3761
for (uint32_t i = 0; i < shader_info.vk_descriptor_set_layouts.size(); i++) {
3762
vkDestroyDescriptorSetLayout(vk_device, shader_info.vk_descriptor_set_layouts[i], VKC::get_allocation_callbacks(VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT));
3763
}
3764
3765
ERR_FAIL_V_MSG(ShaderID(), error_text);
3766
}
3767
3768
// Bookkeep.
3769
ShaderInfo *shader_info_ptr = VersatileResource::allocate<ShaderInfo>(resources_allocator);
3770
*shader_info_ptr = shader_info;
3771
return ShaderID(shader_info_ptr);
3772
}
3773
3774
void RenderingDeviceDriverVulkan::shader_free(ShaderID p_shader) {
3775
ShaderInfo *shader_info = (ShaderInfo *)p_shader.id;
3776
3777
for (uint32_t i = 0; i < shader_info->vk_descriptor_set_layouts.size(); i++) {
3778
vkDestroyDescriptorSetLayout(vk_device, shader_info->vk_descriptor_set_layouts[i], VKC::get_allocation_callbacks(VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT));
3779
}
3780
3781
vkDestroyPipelineLayout(vk_device, shader_info->vk_pipeline_layout, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_PIPELINE_LAYOUT));
3782
3783
shader_destroy_modules(p_shader);
3784
3785
VersatileResource::free(resources_allocator, shader_info);
3786
}
3787
3788
void RenderingDeviceDriverVulkan::shader_destroy_modules(ShaderID p_shader) {
3789
ShaderInfo *si = (ShaderInfo *)p_shader.id;
3790
3791
for (uint32_t i = 0; i < si->vk_stages_create_info.size(); i++) {
3792
if (si->vk_stages_create_info[i].module) {
3793
vkDestroyShaderModule(vk_device, si->vk_stages_create_info[i].module,
3794
VKC::get_allocation_callbacks(VK_OBJECT_TYPE_SHADER_MODULE));
3795
si->vk_stages_create_info[i].module = VK_NULL_HANDLE;
3796
}
3797
}
3798
si->vk_stages_create_info.clear();
3799
}
3800
3801
/*********************/
3802
/**** UNIFORM SET ****/
3803
/*********************/
3804
VkDescriptorPool RenderingDeviceDriverVulkan::_descriptor_set_pool_find_or_create(const DescriptorSetPoolKey &p_key, DescriptorSetPools::Iterator *r_pool_sets_it, int p_linear_pool_index) {
3805
bool linear_pool = p_linear_pool_index >= 0;
3806
DescriptorSetPools::Iterator pool_sets_it = linear_pool ? linear_descriptor_set_pools[p_linear_pool_index].find(p_key) : descriptor_set_pools.find(p_key);
3807
3808
if (pool_sets_it) {
3809
for (KeyValue<VkDescriptorPool, uint32_t> &E : pool_sets_it->value) {
3810
if (E.value < max_descriptor_sets_per_pool) {
3811
*r_pool_sets_it = pool_sets_it;
3812
return E.key;
3813
}
3814
}
3815
}
3816
3817
// Create a new one.
3818
3819
// Here comes more vulkan API strangeness.
3820
VkDescriptorPoolSize *vk_sizes = ALLOCA_ARRAY(VkDescriptorPoolSize, UNIFORM_TYPE_MAX);
3821
uint32_t vk_sizes_count = 0;
3822
{
3823
VkDescriptorPoolSize *curr_vk_size = vk_sizes;
3824
if (p_key.uniform_type[UNIFORM_TYPE_SAMPLER]) {
3825
*curr_vk_size = {};
3826
curr_vk_size->type = VK_DESCRIPTOR_TYPE_SAMPLER;
3827
curr_vk_size->descriptorCount = p_key.uniform_type[UNIFORM_TYPE_SAMPLER] * max_descriptor_sets_per_pool;
3828
curr_vk_size++;
3829
vk_sizes_count++;
3830
}
3831
if (p_key.uniform_type[UNIFORM_TYPE_SAMPLER_WITH_TEXTURE]) {
3832
*curr_vk_size = {};
3833
curr_vk_size->type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
3834
curr_vk_size->descriptorCount = p_key.uniform_type[UNIFORM_TYPE_SAMPLER_WITH_TEXTURE] * max_descriptor_sets_per_pool;
3835
curr_vk_size++;
3836
vk_sizes_count++;
3837
}
3838
if (p_key.uniform_type[UNIFORM_TYPE_TEXTURE]) {
3839
*curr_vk_size = {};
3840
curr_vk_size->type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
3841
curr_vk_size->descriptorCount = p_key.uniform_type[UNIFORM_TYPE_TEXTURE] * max_descriptor_sets_per_pool;
3842
curr_vk_size++;
3843
vk_sizes_count++;
3844
}
3845
if (p_key.uniform_type[UNIFORM_TYPE_IMAGE]) {
3846
*curr_vk_size = {};
3847
curr_vk_size->type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
3848
curr_vk_size->descriptorCount = p_key.uniform_type[UNIFORM_TYPE_IMAGE] * max_descriptor_sets_per_pool;
3849
curr_vk_size++;
3850
vk_sizes_count++;
3851
}
3852
if (p_key.uniform_type[UNIFORM_TYPE_TEXTURE_BUFFER] || p_key.uniform_type[UNIFORM_TYPE_SAMPLER_WITH_TEXTURE_BUFFER]) {
3853
*curr_vk_size = {};
3854
curr_vk_size->type = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
3855
curr_vk_size->descriptorCount = (p_key.uniform_type[UNIFORM_TYPE_TEXTURE_BUFFER] + p_key.uniform_type[UNIFORM_TYPE_SAMPLER_WITH_TEXTURE_BUFFER]) * max_descriptor_sets_per_pool;
3856
curr_vk_size++;
3857
vk_sizes_count++;
3858
}
3859
if (p_key.uniform_type[UNIFORM_TYPE_IMAGE_BUFFER]) {
3860
*curr_vk_size = {};
3861
curr_vk_size->type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
3862
curr_vk_size->descriptorCount = p_key.uniform_type[UNIFORM_TYPE_IMAGE_BUFFER] * max_descriptor_sets_per_pool;
3863
curr_vk_size++;
3864
vk_sizes_count++;
3865
}
3866
if (p_key.uniform_type[UNIFORM_TYPE_UNIFORM_BUFFER]) {
3867
*curr_vk_size = {};
3868
curr_vk_size->type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
3869
curr_vk_size->descriptorCount = p_key.uniform_type[UNIFORM_TYPE_UNIFORM_BUFFER] * max_descriptor_sets_per_pool;
3870
curr_vk_size++;
3871
vk_sizes_count++;
3872
}
3873
if (p_key.uniform_type[UNIFORM_TYPE_STORAGE_BUFFER]) {
3874
*curr_vk_size = {};
3875
curr_vk_size->type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
3876
curr_vk_size->descriptorCount = p_key.uniform_type[UNIFORM_TYPE_STORAGE_BUFFER] * max_descriptor_sets_per_pool;
3877
curr_vk_size++;
3878
vk_sizes_count++;
3879
}
3880
if (p_key.uniform_type[UNIFORM_TYPE_INPUT_ATTACHMENT]) {
3881
*curr_vk_size = {};
3882
curr_vk_size->type = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
3883
curr_vk_size->descriptorCount = p_key.uniform_type[UNIFORM_TYPE_INPUT_ATTACHMENT] * max_descriptor_sets_per_pool;
3884
curr_vk_size++;
3885
vk_sizes_count++;
3886
}
3887
DEV_ASSERT(vk_sizes_count <= UNIFORM_TYPE_MAX);
3888
}
3889
3890
VkDescriptorPoolCreateInfo descriptor_set_pool_create_info = {};
3891
descriptor_set_pool_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
3892
if (linear_descriptor_pools_enabled && linear_pool) {
3893
descriptor_set_pool_create_info.flags = 0;
3894
} else {
3895
descriptor_set_pool_create_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT; // Can't think how somebody may NOT need this flag.
3896
}
3897
descriptor_set_pool_create_info.maxSets = max_descriptor_sets_per_pool;
3898
descriptor_set_pool_create_info.poolSizeCount = vk_sizes_count;
3899
descriptor_set_pool_create_info.pPoolSizes = vk_sizes;
3900
3901
VkDescriptorPool vk_pool = VK_NULL_HANDLE;
3902
VkResult res = vkCreateDescriptorPool(vk_device, &descriptor_set_pool_create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_DESCRIPTOR_POOL), &vk_pool);
3903
if (res) {
3904
ERR_FAIL_COND_V_MSG(res, VK_NULL_HANDLE, "vkCreateDescriptorPool failed with error " + itos(res) + ".");
3905
}
3906
3907
// Bookkeep.
3908
3909
if (!pool_sets_it) {
3910
if (linear_pool) {
3911
pool_sets_it = linear_descriptor_set_pools[p_linear_pool_index].insert(p_key, HashMap<VkDescriptorPool, uint32_t>());
3912
} else {
3913
pool_sets_it = descriptor_set_pools.insert(p_key, HashMap<VkDescriptorPool, uint32_t>());
3914
}
3915
}
3916
HashMap<VkDescriptorPool, uint32_t> &pool_rcs = pool_sets_it->value;
3917
pool_rcs.insert(vk_pool, 0);
3918
*r_pool_sets_it = pool_sets_it;
3919
return vk_pool;
3920
}
3921
3922
void RenderingDeviceDriverVulkan::_descriptor_set_pool_unreference(DescriptorSetPools::Iterator p_pool_sets_it, VkDescriptorPool p_vk_descriptor_pool, int p_linear_pool_index) {
3923
HashMap<VkDescriptorPool, uint32_t>::Iterator pool_rcs_it = p_pool_sets_it->value.find(p_vk_descriptor_pool);
3924
pool_rcs_it->value--;
3925
if (pool_rcs_it->value == 0) {
3926
vkDestroyDescriptorPool(vk_device, p_vk_descriptor_pool, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_DESCRIPTOR_POOL));
3927
p_pool_sets_it->value.erase(p_vk_descriptor_pool);
3928
if (p_pool_sets_it->value.is_empty()) {
3929
if (linear_descriptor_pools_enabled && p_linear_pool_index >= 0) {
3930
linear_descriptor_set_pools[p_linear_pool_index].remove(p_pool_sets_it);
3931
} else {
3932
descriptor_set_pools.remove(p_pool_sets_it);
3933
}
3934
}
3935
}
3936
}
3937
3938
RDD::UniformSetID RenderingDeviceDriverVulkan::uniform_set_create(VectorView<BoundUniform> p_uniforms, ShaderID p_shader, uint32_t p_set_index, int p_linear_pool_index) {
3939
if (!linear_descriptor_pools_enabled) {
3940
p_linear_pool_index = -1;
3941
}
3942
DescriptorSetPoolKey pool_key;
3943
// Immutable samplers will be skipped so we need to track the number of vk_writes used.
3944
VkWriteDescriptorSet *vk_writes = ALLOCA_ARRAY(VkWriteDescriptorSet, p_uniforms.size());
3945
uint32_t writes_amount = 0;
3946
for (uint32_t i = 0; i < p_uniforms.size(); i++) {
3947
const BoundUniform &uniform = p_uniforms[i];
3948
3949
vk_writes[writes_amount] = {};
3950
vk_writes[writes_amount].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
3951
3952
uint32_t num_descriptors = 1;
3953
3954
switch (uniform.type) {
3955
case UNIFORM_TYPE_SAMPLER: {
3956
if (uniform.immutable_sampler && immutable_samplers_enabled) {
3957
continue; // Skipping immutable samplers.
3958
}
3959
num_descriptors = uniform.ids.size();
3960
VkDescriptorImageInfo *vk_img_infos = ALLOCA_ARRAY(VkDescriptorImageInfo, num_descriptors);
3961
3962
for (uint32_t j = 0; j < num_descriptors; j++) {
3963
vk_img_infos[j] = {};
3964
vk_img_infos[j].sampler = (VkSampler)uniform.ids[j].id;
3965
vk_img_infos[j].imageView = VK_NULL_HANDLE;
3966
vk_img_infos[j].imageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
3967
}
3968
3969
vk_writes[writes_amount].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
3970
vk_writes[writes_amount].pImageInfo = vk_img_infos;
3971
} break;
3972
case UNIFORM_TYPE_SAMPLER_WITH_TEXTURE: {
3973
num_descriptors = uniform.ids.size() / 2;
3974
VkDescriptorImageInfo *vk_img_infos = ALLOCA_ARRAY(VkDescriptorImageInfo, num_descriptors);
3975
3976
for (uint32_t j = 0; j < num_descriptors; j++) {
3977
#ifdef DEBUG_ENABLED
3978
if (((const TextureInfo *)uniform.ids[j * 2 + 1].id)->transient) {
3979
ERR_PRINT("TEXTURE_USAGE_TRANSIENT_BIT texture must not be used for sampling in a shader.");
3980
}
3981
#endif
3982
vk_img_infos[j] = {};
3983
vk_img_infos[j].sampler = (VkSampler)uniform.ids[j * 2 + 0].id;
3984
vk_img_infos[j].imageView = ((const TextureInfo *)uniform.ids[j * 2 + 1].id)->vk_view;
3985
vk_img_infos[j].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
3986
}
3987
3988
vk_writes[writes_amount].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
3989
vk_writes[writes_amount].pImageInfo = vk_img_infos;
3990
} break;
3991
case UNIFORM_TYPE_TEXTURE: {
3992
num_descriptors = uniform.ids.size();
3993
VkDescriptorImageInfo *vk_img_infos = ALLOCA_ARRAY(VkDescriptorImageInfo, num_descriptors);
3994
3995
for (uint32_t j = 0; j < num_descriptors; j++) {
3996
#ifdef DEBUG_ENABLED
3997
if (((const TextureInfo *)uniform.ids[j].id)->transient) {
3998
ERR_PRINT("TEXTURE_USAGE_TRANSIENT_BIT texture must not be used for sampling in a shader.");
3999
}
4000
#endif
4001
vk_img_infos[j] = {};
4002
vk_img_infos[j].imageView = ((const TextureInfo *)uniform.ids[j].id)->vk_view;
4003
vk_img_infos[j].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
4004
}
4005
4006
vk_writes[writes_amount].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
4007
vk_writes[writes_amount].pImageInfo = vk_img_infos;
4008
} break;
4009
case UNIFORM_TYPE_IMAGE: {
4010
num_descriptors = uniform.ids.size();
4011
VkDescriptorImageInfo *vk_img_infos = ALLOCA_ARRAY(VkDescriptorImageInfo, num_descriptors);
4012
4013
for (uint32_t j = 0; j < num_descriptors; j++) {
4014
#ifdef DEBUG_ENABLED
4015
if (((const TextureInfo *)uniform.ids[j].id)->transient) {
4016
ERR_PRINT("TEXTURE_USAGE_TRANSIENT_BIT texture must not be used for sampling in a shader.");
4017
}
4018
#endif
4019
vk_img_infos[j] = {};
4020
vk_img_infos[j].imageView = ((const TextureInfo *)uniform.ids[j].id)->vk_view;
4021
vk_img_infos[j].imageLayout = VK_IMAGE_LAYOUT_GENERAL;
4022
}
4023
4024
vk_writes[writes_amount].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
4025
vk_writes[writes_amount].pImageInfo = vk_img_infos;
4026
} break;
4027
case UNIFORM_TYPE_TEXTURE_BUFFER: {
4028
num_descriptors = uniform.ids.size();
4029
VkDescriptorBufferInfo *vk_buf_infos = ALLOCA_ARRAY(VkDescriptorBufferInfo, num_descriptors);
4030
VkBufferView *vk_buf_views = ALLOCA_ARRAY(VkBufferView, num_descriptors);
4031
4032
for (uint32_t j = 0; j < num_descriptors; j++) {
4033
const BufferInfo *buf_info = (const BufferInfo *)uniform.ids[j].id;
4034
vk_buf_infos[j] = {};
4035
vk_buf_infos[j].buffer = buf_info->vk_buffer;
4036
vk_buf_infos[j].range = buf_info->size;
4037
4038
vk_buf_views[j] = buf_info->vk_view;
4039
}
4040
4041
vk_writes[writes_amount].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
4042
vk_writes[writes_amount].pBufferInfo = vk_buf_infos;
4043
vk_writes[writes_amount].pTexelBufferView = vk_buf_views;
4044
} break;
4045
case UNIFORM_TYPE_SAMPLER_WITH_TEXTURE_BUFFER: {
4046
num_descriptors = uniform.ids.size() / 2;
4047
VkDescriptorImageInfo *vk_img_infos = ALLOCA_ARRAY(VkDescriptorImageInfo, num_descriptors);
4048
VkDescriptorBufferInfo *vk_buf_infos = ALLOCA_ARRAY(VkDescriptorBufferInfo, num_descriptors);
4049
VkBufferView *vk_buf_views = ALLOCA_ARRAY(VkBufferView, num_descriptors);
4050
4051
for (uint32_t j = 0; j < num_descriptors; j++) {
4052
vk_img_infos[j] = {};
4053
vk_img_infos[j].sampler = (VkSampler)uniform.ids[j * 2 + 0].id;
4054
4055
const BufferInfo *buf_info = (const BufferInfo *)uniform.ids[j * 2 + 1].id;
4056
vk_buf_infos[j] = {};
4057
vk_buf_infos[j].buffer = buf_info->vk_buffer;
4058
vk_buf_infos[j].range = buf_info->size;
4059
4060
vk_buf_views[j] = buf_info->vk_view;
4061
}
4062
4063
vk_writes[writes_amount].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
4064
vk_writes[writes_amount].pImageInfo = vk_img_infos;
4065
vk_writes[writes_amount].pBufferInfo = vk_buf_infos;
4066
vk_writes[writes_amount].pTexelBufferView = vk_buf_views;
4067
} break;
4068
case UNIFORM_TYPE_IMAGE_BUFFER: {
4069
CRASH_NOW_MSG("Unimplemented!"); // TODO.
4070
} break;
4071
case UNIFORM_TYPE_UNIFORM_BUFFER: {
4072
const BufferInfo *buf_info = (const BufferInfo *)uniform.ids[0].id;
4073
VkDescriptorBufferInfo *vk_buf_info = ALLOCA_SINGLE(VkDescriptorBufferInfo);
4074
*vk_buf_info = {};
4075
vk_buf_info->buffer = buf_info->vk_buffer;
4076
vk_buf_info->range = buf_info->size;
4077
4078
vk_writes[writes_amount].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
4079
vk_writes[writes_amount].pBufferInfo = vk_buf_info;
4080
} break;
4081
case UNIFORM_TYPE_STORAGE_BUFFER: {
4082
const BufferInfo *buf_info = (const BufferInfo *)uniform.ids[0].id;
4083
VkDescriptorBufferInfo *vk_buf_info = ALLOCA_SINGLE(VkDescriptorBufferInfo);
4084
*vk_buf_info = {};
4085
vk_buf_info->buffer = buf_info->vk_buffer;
4086
vk_buf_info->range = buf_info->size;
4087
4088
vk_writes[writes_amount].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
4089
vk_writes[writes_amount].pBufferInfo = vk_buf_info;
4090
} break;
4091
case UNIFORM_TYPE_INPUT_ATTACHMENT: {
4092
num_descriptors = uniform.ids.size();
4093
VkDescriptorImageInfo *vk_img_infos = ALLOCA_ARRAY(VkDescriptorImageInfo, num_descriptors);
4094
4095
for (uint32_t j = 0; j < uniform.ids.size(); j++) {
4096
vk_img_infos[j] = {};
4097
vk_img_infos[j].imageView = ((const TextureInfo *)uniform.ids[j].id)->vk_view;
4098
vk_img_infos[j].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
4099
}
4100
4101
vk_writes[writes_amount].descriptorType = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
4102
vk_writes[writes_amount].pImageInfo = vk_img_infos;
4103
} break;
4104
default: {
4105
DEV_ASSERT(false);
4106
}
4107
}
4108
4109
vk_writes[writes_amount].dstBinding = uniform.binding;
4110
vk_writes[writes_amount].descriptorCount = num_descriptors;
4111
4112
ERR_FAIL_COND_V_MSG(pool_key.uniform_type[uniform.type] == MAX_UNIFORM_POOL_ELEMENT, UniformSetID(),
4113
"Uniform set reached the limit of bindings for the same type (" + itos(MAX_UNIFORM_POOL_ELEMENT) + ").");
4114
pool_key.uniform_type[uniform.type] += num_descriptors;
4115
writes_amount++;
4116
}
4117
4118
// Need a descriptor pool.
4119
DescriptorSetPools::Iterator pool_sets_it;
4120
VkDescriptorPool vk_pool = _descriptor_set_pool_find_or_create(pool_key, &pool_sets_it, p_linear_pool_index);
4121
DEV_ASSERT(vk_pool);
4122
pool_sets_it->value[vk_pool]++;
4123
4124
VkDescriptorSetAllocateInfo descriptor_set_allocate_info = {};
4125
descriptor_set_allocate_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
4126
descriptor_set_allocate_info.descriptorPool = vk_pool;
4127
descriptor_set_allocate_info.descriptorSetCount = 1;
4128
const ShaderInfo *shader_info = (const ShaderInfo *)p_shader.id;
4129
descriptor_set_allocate_info.pSetLayouts = &shader_info->vk_descriptor_set_layouts[p_set_index];
4130
4131
VkDescriptorSet vk_descriptor_set = VK_NULL_HANDLE;
4132
4133
VkResult res = vkAllocateDescriptorSets(vk_device, &descriptor_set_allocate_info, &vk_descriptor_set);
4134
if (res) {
4135
_descriptor_set_pool_unreference(pool_sets_it, vk_pool, p_linear_pool_index);
4136
ERR_FAIL_V_MSG(UniformSetID(), "Cannot allocate descriptor sets, error " + itos(res) + ".");
4137
}
4138
4139
for (uint32_t i = 0; i < writes_amount; i++) {
4140
vk_writes[i].dstSet = vk_descriptor_set;
4141
}
4142
vkUpdateDescriptorSets(vk_device, writes_amount, vk_writes, 0, nullptr);
4143
4144
// Bookkeep.
4145
4146
UniformSetInfo *usi = VersatileResource::allocate<UniformSetInfo>(resources_allocator);
4147
usi->vk_descriptor_set = vk_descriptor_set;
4148
if (p_linear_pool_index >= 0) {
4149
usi->vk_linear_descriptor_pool = vk_pool;
4150
} else {
4151
usi->vk_descriptor_pool = vk_pool;
4152
}
4153
usi->pool_sets_it = pool_sets_it;
4154
4155
return UniformSetID(usi);
4156
}
4157
4158
void RenderingDeviceDriverVulkan::uniform_set_free(UniformSetID p_uniform_set) {
4159
UniformSetInfo *usi = (UniformSetInfo *)p_uniform_set.id;
4160
4161
if (usi->vk_linear_descriptor_pool) {
4162
// Nothing to do. All sets are freed at once using vkResetDescriptorPool.
4163
//
4164
// We can NOT decrease the reference count (i.e. call _descriptor_set_pool_unreference())
4165
// because the pool is linear (i.e. the freed set can't be recycled) and further calls to
4166
// _descriptor_set_pool_find_or_create() need usi->pool_sets_it->value to stay so that we can
4167
// tell if the pool has ran out of space and we need to create a new pool.
4168
} else {
4169
vkFreeDescriptorSets(vk_device, usi->vk_descriptor_pool, 1, &usi->vk_descriptor_set);
4170
_descriptor_set_pool_unreference(usi->pool_sets_it, usi->vk_descriptor_pool, -1);
4171
}
4172
4173
VersatileResource::free(resources_allocator, usi);
4174
}
4175
4176
bool RenderingDeviceDriverVulkan::uniform_sets_have_linear_pools() const {
4177
return true;
4178
}
4179
4180
void RenderingDeviceDriverVulkan::linear_uniform_set_pools_reset(int p_linear_pool_index) {
4181
if (linear_descriptor_pools_enabled) {
4182
DescriptorSetPools &pools_to_reset = linear_descriptor_set_pools[p_linear_pool_index];
4183
DescriptorSetPools::Iterator curr_pool = pools_to_reset.begin();
4184
4185
while (curr_pool != pools_to_reset.end()) {
4186
HashMap<VkDescriptorPool, uint32_t>::Iterator curr_pair = curr_pool->value.begin();
4187
while (curr_pair != curr_pool->value.end()) {
4188
vkResetDescriptorPool(vk_device, curr_pair->key, 0);
4189
curr_pair->value = 0;
4190
++curr_pair;
4191
}
4192
++curr_pool;
4193
}
4194
}
4195
}
4196
4197
// ----- COMMANDS -----
4198
4199
void RenderingDeviceDriverVulkan::command_uniform_set_prepare_for_use(CommandBufferID p_cmd_buffer, UniformSetID p_uniform_set, ShaderID p_shader, uint32_t p_set_index) {
4200
}
4201
4202
/******************/
4203
/**** TRANSFER ****/
4204
/******************/
4205
4206
static_assert(ARRAYS_COMPATIBLE_FIELDWISE(RDD::BufferCopyRegion, VkBufferCopy));
4207
4208
static void _texture_subresource_range_to_vk(const RDD::TextureSubresourceRange &p_subresources, VkImageSubresourceRange *r_vk_subreources) {
4209
*r_vk_subreources = {};
4210
r_vk_subreources->aspectMask = (VkImageAspectFlags)p_subresources.aspect;
4211
r_vk_subreources->baseMipLevel = p_subresources.base_mipmap;
4212
r_vk_subreources->levelCount = p_subresources.mipmap_count;
4213
r_vk_subreources->baseArrayLayer = p_subresources.base_layer;
4214
r_vk_subreources->layerCount = p_subresources.layer_count;
4215
}
4216
4217
static void _texture_subresource_layers_to_vk(const RDD::TextureSubresourceLayers &p_subresources, VkImageSubresourceLayers *r_vk_subreources) {
4218
*r_vk_subreources = {};
4219
r_vk_subreources->aspectMask = (VkImageAspectFlags)p_subresources.aspect;
4220
r_vk_subreources->mipLevel = p_subresources.mipmap;
4221
r_vk_subreources->baseArrayLayer = p_subresources.base_layer;
4222
r_vk_subreources->layerCount = p_subresources.layer_count;
4223
}
4224
4225
static void _buffer_texture_copy_region_to_vk(const RDD::BufferTextureCopyRegion &p_copy_region, VkBufferImageCopy *r_vk_copy_region) {
4226
*r_vk_copy_region = {};
4227
r_vk_copy_region->bufferOffset = p_copy_region.buffer_offset;
4228
_texture_subresource_layers_to_vk(p_copy_region.texture_subresources, &r_vk_copy_region->imageSubresource);
4229
r_vk_copy_region->imageOffset.x = p_copy_region.texture_offset.x;
4230
r_vk_copy_region->imageOffset.y = p_copy_region.texture_offset.y;
4231
r_vk_copy_region->imageOffset.z = p_copy_region.texture_offset.z;
4232
r_vk_copy_region->imageExtent.width = p_copy_region.texture_region_size.x;
4233
r_vk_copy_region->imageExtent.height = p_copy_region.texture_region_size.y;
4234
r_vk_copy_region->imageExtent.depth = p_copy_region.texture_region_size.z;
4235
}
4236
4237
static void _texture_copy_region_to_vk(const RDD::TextureCopyRegion &p_copy_region, VkImageCopy *r_vk_copy_region) {
4238
*r_vk_copy_region = {};
4239
_texture_subresource_layers_to_vk(p_copy_region.src_subresources, &r_vk_copy_region->srcSubresource);
4240
r_vk_copy_region->srcOffset.x = p_copy_region.src_offset.x;
4241
r_vk_copy_region->srcOffset.y = p_copy_region.src_offset.y;
4242
r_vk_copy_region->srcOffset.z = p_copy_region.src_offset.z;
4243
_texture_subresource_layers_to_vk(p_copy_region.dst_subresources, &r_vk_copy_region->dstSubresource);
4244
r_vk_copy_region->dstOffset.x = p_copy_region.dst_offset.x;
4245
r_vk_copy_region->dstOffset.y = p_copy_region.dst_offset.y;
4246
r_vk_copy_region->dstOffset.z = p_copy_region.dst_offset.z;
4247
r_vk_copy_region->extent.width = p_copy_region.size.x;
4248
r_vk_copy_region->extent.height = p_copy_region.size.y;
4249
r_vk_copy_region->extent.depth = p_copy_region.size.z;
4250
}
4251
4252
void RenderingDeviceDriverVulkan::command_clear_buffer(CommandBufferID p_cmd_buffer, BufferID p_buffer, uint64_t p_offset, uint64_t p_size) {
4253
const CommandBufferInfo *command_buffer = (const CommandBufferInfo *)p_cmd_buffer.id;
4254
const BufferInfo *buf_info = (const BufferInfo *)p_buffer.id;
4255
vkCmdFillBuffer(command_buffer->vk_command_buffer, buf_info->vk_buffer, p_offset, p_size, 0);
4256
}
4257
4258
void RenderingDeviceDriverVulkan::command_copy_buffer(CommandBufferID p_cmd_buffer, BufferID p_src_buffer, BufferID p_dst_buffer, VectorView<BufferCopyRegion> p_regions) {
4259
const CommandBufferInfo *command_buffer = (const CommandBufferInfo *)p_cmd_buffer.id;
4260
const BufferInfo *src_buf_info = (const BufferInfo *)p_src_buffer.id;
4261
const BufferInfo *dst_buf_info = (const BufferInfo *)p_dst_buffer.id;
4262
vkCmdCopyBuffer(command_buffer->vk_command_buffer, src_buf_info->vk_buffer, dst_buf_info->vk_buffer, p_regions.size(), (const VkBufferCopy *)p_regions.ptr());
4263
}
4264
4265
void RenderingDeviceDriverVulkan::command_copy_texture(CommandBufferID p_cmd_buffer, TextureID p_src_texture, TextureLayout p_src_texture_layout, TextureID p_dst_texture, TextureLayout p_dst_texture_layout, VectorView<TextureCopyRegion> p_regions) {
4266
VkImageCopy *vk_copy_regions = ALLOCA_ARRAY(VkImageCopy, p_regions.size());
4267
for (uint32_t i = 0; i < p_regions.size(); i++) {
4268
_texture_copy_region_to_vk(p_regions[i], &vk_copy_regions[i]);
4269
}
4270
4271
const CommandBufferInfo *command_buffer = (const CommandBufferInfo *)p_cmd_buffer.id;
4272
const TextureInfo *src_tex_info = (const TextureInfo *)p_src_texture.id;
4273
const TextureInfo *dst_tex_info = (const TextureInfo *)p_dst_texture.id;
4274
4275
#ifdef DEBUG_ENABLED
4276
if (src_tex_info->transient) {
4277
ERR_PRINT("TEXTURE_USAGE_TRANSIENT_BIT p_src_texture must not be used in command_copy_texture.");
4278
}
4279
if (dst_tex_info->transient) {
4280
ERR_PRINT("TEXTURE_USAGE_TRANSIENT_BIT p_dst_texture must not be used in command_copy_texture.");
4281
}
4282
#endif
4283
4284
vkCmdCopyImage(command_buffer->vk_command_buffer, src_tex_info->vk_view_create_info.image, RD_TO_VK_LAYOUT[p_src_texture_layout], dst_tex_info->vk_view_create_info.image, RD_TO_VK_LAYOUT[p_dst_texture_layout], p_regions.size(), vk_copy_regions);
4285
}
4286
4287
void RenderingDeviceDriverVulkan::command_resolve_texture(CommandBufferID p_cmd_buffer, TextureID p_src_texture, TextureLayout p_src_texture_layout, uint32_t p_src_layer, uint32_t p_src_mipmap, TextureID p_dst_texture, TextureLayout p_dst_texture_layout, uint32_t p_dst_layer, uint32_t p_dst_mipmap) {
4288
const CommandBufferInfo *command_buffer = (const CommandBufferInfo *)p_cmd_buffer.id;
4289
const TextureInfo *src_tex_info = (const TextureInfo *)p_src_texture.id;
4290
const TextureInfo *dst_tex_info = (const TextureInfo *)p_dst_texture.id;
4291
4292
VkImageResolve vk_resolve = {};
4293
vk_resolve.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4294
vk_resolve.srcSubresource.mipLevel = p_src_mipmap;
4295
vk_resolve.srcSubresource.baseArrayLayer = p_src_layer;
4296
vk_resolve.srcSubresource.layerCount = 1;
4297
vk_resolve.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4298
vk_resolve.dstSubresource.mipLevel = p_dst_mipmap;
4299
vk_resolve.dstSubresource.baseArrayLayer = p_dst_layer;
4300
vk_resolve.dstSubresource.layerCount = 1;
4301
vk_resolve.extent.width = MAX(1u, src_tex_info->vk_create_info.extent.width >> p_src_mipmap);
4302
vk_resolve.extent.height = MAX(1u, src_tex_info->vk_create_info.extent.height >> p_src_mipmap);
4303
vk_resolve.extent.depth = MAX(1u, src_tex_info->vk_create_info.extent.depth >> p_src_mipmap);
4304
4305
#ifdef DEBUG_ENABLED
4306
if (src_tex_info->transient) {
4307
ERR_PRINT("TEXTURE_USAGE_TRANSIENT_BIT p_src_texture must not be used in command_resolve_texture. Use a resolve store action pass instead.");
4308
}
4309
if (dst_tex_info->transient) {
4310
ERR_PRINT("TEXTURE_USAGE_TRANSIENT_BIT p_dst_texture must not be used in command_resolve_texture.");
4311
}
4312
#endif
4313
4314
vkCmdResolveImage(command_buffer->vk_command_buffer, src_tex_info->vk_view_create_info.image, RD_TO_VK_LAYOUT[p_src_texture_layout], dst_tex_info->vk_view_create_info.image, RD_TO_VK_LAYOUT[p_dst_texture_layout], 1, &vk_resolve);
4315
}
4316
4317
void RenderingDeviceDriverVulkan::command_clear_color_texture(CommandBufferID p_cmd_buffer, TextureID p_texture, TextureLayout p_texture_layout, const Color &p_color, const TextureSubresourceRange &p_subresources) {
4318
VkClearColorValue vk_color = {};
4319
memcpy(&vk_color.float32, p_color.components, sizeof(VkClearColorValue::float32));
4320
4321
VkImageSubresourceRange vk_subresources = {};
4322
_texture_subresource_range_to_vk(p_subresources, &vk_subresources);
4323
4324
const CommandBufferInfo *command_buffer = (const CommandBufferInfo *)p_cmd_buffer.id;
4325
const TextureInfo *tex_info = (const TextureInfo *)p_texture.id;
4326
#ifdef DEBUG_ENABLED
4327
if (tex_info->transient) {
4328
ERR_PRINT("TEXTURE_USAGE_TRANSIENT_BIT p_texture must not be used in command_clear_color_texture. Use a clear store action pass instead.");
4329
}
4330
#endif
4331
vkCmdClearColorImage(command_buffer->vk_command_buffer, tex_info->vk_view_create_info.image, RD_TO_VK_LAYOUT[p_texture_layout], &vk_color, 1, &vk_subresources);
4332
}
4333
4334
void RenderingDeviceDriverVulkan::command_copy_buffer_to_texture(CommandBufferID p_cmd_buffer, BufferID p_src_buffer, TextureID p_dst_texture, TextureLayout p_dst_texture_layout, VectorView<BufferTextureCopyRegion> p_regions) {
4335
VkBufferImageCopy *vk_copy_regions = ALLOCA_ARRAY(VkBufferImageCopy, p_regions.size());
4336
for (uint32_t i = 0; i < p_regions.size(); i++) {
4337
_buffer_texture_copy_region_to_vk(p_regions[i], &vk_copy_regions[i]);
4338
}
4339
4340
const CommandBufferInfo *command_buffer = (const CommandBufferInfo *)p_cmd_buffer.id;
4341
const BufferInfo *buf_info = (const BufferInfo *)p_src_buffer.id;
4342
const TextureInfo *tex_info = (const TextureInfo *)p_dst_texture.id;
4343
#ifdef DEBUG_ENABLED
4344
if (tex_info->transient) {
4345
ERR_PRINT("TEXTURE_USAGE_TRANSIENT_BIT p_dst_texture must not be used in command_copy_buffer_to_texture.");
4346
}
4347
#endif
4348
vkCmdCopyBufferToImage(command_buffer->vk_command_buffer, buf_info->vk_buffer, tex_info->vk_view_create_info.image, RD_TO_VK_LAYOUT[p_dst_texture_layout], p_regions.size(), vk_copy_regions);
4349
}
4350
4351
void RenderingDeviceDriverVulkan::command_copy_texture_to_buffer(CommandBufferID p_cmd_buffer, TextureID p_src_texture, TextureLayout p_src_texture_layout, BufferID p_dst_buffer, VectorView<BufferTextureCopyRegion> p_regions) {
4352
VkBufferImageCopy *vk_copy_regions = ALLOCA_ARRAY(VkBufferImageCopy, p_regions.size());
4353
for (uint32_t i = 0; i < p_regions.size(); i++) {
4354
_buffer_texture_copy_region_to_vk(p_regions[i], &vk_copy_regions[i]);
4355
}
4356
4357
const CommandBufferInfo *command_buffer = (const CommandBufferInfo *)p_cmd_buffer.id;
4358
const TextureInfo *tex_info = (const TextureInfo *)p_src_texture.id;
4359
const BufferInfo *buf_info = (const BufferInfo *)p_dst_buffer.id;
4360
#ifdef DEBUG_ENABLED
4361
if (tex_info->transient) {
4362
ERR_PRINT("TEXTURE_USAGE_TRANSIENT_BIT p_src_texture must not be used in command_copy_texture_to_buffer.");
4363
}
4364
#endif
4365
vkCmdCopyImageToBuffer(command_buffer->vk_command_buffer, tex_info->vk_view_create_info.image, RD_TO_VK_LAYOUT[p_src_texture_layout], buf_info->vk_buffer, p_regions.size(), vk_copy_regions);
4366
}
4367
4368
/******************/
4369
/**** PIPELINE ****/
4370
/******************/
4371
4372
void RenderingDeviceDriverVulkan::pipeline_free(PipelineID p_pipeline) {
4373
vkDestroyPipeline(vk_device, (VkPipeline)p_pipeline.id, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_PIPELINE));
4374
}
4375
4376
// ----- BINDING -----
4377
4378
void RenderingDeviceDriverVulkan::command_bind_push_constants(CommandBufferID p_cmd_buffer, ShaderID p_shader, uint32_t p_dst_first_index, VectorView<uint32_t> p_data) {
4379
const CommandBufferInfo *command_buffer = (const CommandBufferInfo *)p_cmd_buffer.id;
4380
const ShaderInfo *shader_info = (const ShaderInfo *)p_shader.id;
4381
vkCmdPushConstants(command_buffer->vk_command_buffer, shader_info->vk_pipeline_layout, shader_info->vk_push_constant_stages, p_dst_first_index * sizeof(uint32_t), p_data.size() * sizeof(uint32_t), p_data.ptr());
4382
}
4383
4384
// ----- CACHE -----
4385
4386
int RenderingDeviceDriverVulkan::caching_instance_count = 0;
4387
4388
bool RenderingDeviceDriverVulkan::pipeline_cache_create(const Vector<uint8_t> &p_data) {
4389
if (caching_instance_count) {
4390
WARN_PRINT("There's already a RenderingDeviceDriverVulkan instance doing PSO caching. Only one can at the same time. This one won't.");
4391
return false;
4392
}
4393
caching_instance_count++;
4394
4395
pipelines_cache.current_size = 0;
4396
pipelines_cache.buffer.resize(sizeof(PipelineCacheHeader));
4397
4398
// Parse.
4399
{
4400
if (p_data.is_empty()) {
4401
// No pre-existing cache, just create it.
4402
} else if (p_data.size() <= (int)sizeof(PipelineCacheHeader)) {
4403
print_verbose("Invalid/corrupt Vulkan pipelines cache. Existing shader pipeline cache will be ignored, which may result in stuttering during gameplay.");
4404
} else {
4405
const PipelineCacheHeader *loaded_header = reinterpret_cast<const PipelineCacheHeader *>(p_data.ptr());
4406
if (loaded_header->magic != 868 + VK_PIPELINE_CACHE_HEADER_VERSION_ONE) {
4407
print_verbose("Invalid Vulkan pipelines cache magic number. Existing shader pipeline cache will be ignored, which may result in stuttering during gameplay.");
4408
} else {
4409
const uint8_t *loaded_buffer_start = p_data.ptr() + sizeof(PipelineCacheHeader);
4410
uint32_t loaded_buffer_size = p_data.size() - sizeof(PipelineCacheHeader);
4411
const PipelineCacheHeader *current_header = (PipelineCacheHeader *)pipelines_cache.buffer.ptr();
4412
if (loaded_header->data_hash != hash_murmur3_buffer(loaded_buffer_start, loaded_buffer_size) ||
4413
loaded_header->data_size != loaded_buffer_size ||
4414
loaded_header->vendor_id != current_header->vendor_id ||
4415
loaded_header->device_id != current_header->device_id ||
4416
loaded_header->driver_version != current_header->driver_version ||
4417
memcmp(loaded_header->uuid, current_header->uuid, VK_UUID_SIZE) != 0 ||
4418
loaded_header->driver_abi != current_header->driver_abi) {
4419
print_verbose("Invalid Vulkan pipelines cache header. This may be due to an engine change, GPU change or graphics driver version change. Existing shader pipeline cache will be ignored, which may result in stuttering during gameplay.");
4420
} else {
4421
pipelines_cache.current_size = loaded_buffer_size;
4422
pipelines_cache.buffer = p_data;
4423
}
4424
}
4425
}
4426
}
4427
4428
// Create.
4429
{
4430
VkPipelineCacheCreateInfo cache_info = {};
4431
cache_info.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
4432
cache_info.initialDataSize = pipelines_cache.buffer.size() - sizeof(PipelineCacheHeader);
4433
cache_info.pInitialData = pipelines_cache.buffer.ptr() + sizeof(PipelineCacheHeader);
4434
4435
VkResult err = vkCreatePipelineCache(vk_device, &cache_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_PIPELINE_CACHE), &pipelines_cache.vk_cache);
4436
if (err != VK_SUCCESS) {
4437
WARN_PRINT("vkCreatePipelinecache failed with error " + itos(err) + ".");
4438
return false;
4439
}
4440
}
4441
4442
return true;
4443
}
4444
4445
void RenderingDeviceDriverVulkan::pipeline_cache_free() {
4446
DEV_ASSERT(pipelines_cache.vk_cache);
4447
4448
vkDestroyPipelineCache(vk_device, pipelines_cache.vk_cache, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_PIPELINE_CACHE));
4449
pipelines_cache.vk_cache = VK_NULL_HANDLE;
4450
4451
DEV_ASSERT(caching_instance_count > 0);
4452
caching_instance_count--;
4453
}
4454
4455
size_t RenderingDeviceDriverVulkan::pipeline_cache_query_size() {
4456
DEV_ASSERT(pipelines_cache.vk_cache);
4457
4458
// FIXME:
4459
// We're letting the cache grow unboundedly. We may want to set at limit and see if implementations use LRU or the like.
4460
// If we do, we won't be able to assume any longer that the cache is dirty if, and only if, it has grown.
4461
VkResult err = vkGetPipelineCacheData(vk_device, pipelines_cache.vk_cache, &pipelines_cache.current_size, nullptr);
4462
ERR_FAIL_COND_V_MSG(err, 0, "vkGetPipelineCacheData failed with error " + itos(err) + ".");
4463
4464
return pipelines_cache.current_size;
4465
}
4466
4467
Vector<uint8_t> RenderingDeviceDriverVulkan::pipeline_cache_serialize() {
4468
DEV_ASSERT(pipelines_cache.vk_cache);
4469
4470
pipelines_cache.buffer.resize(pipelines_cache.current_size + sizeof(PipelineCacheHeader));
4471
4472
VkResult err = vkGetPipelineCacheData(vk_device, pipelines_cache.vk_cache, &pipelines_cache.current_size, pipelines_cache.buffer.ptrw() + sizeof(PipelineCacheHeader));
4473
ERR_FAIL_COND_V(err != VK_SUCCESS && err != VK_INCOMPLETE, Vector<uint8_t>()); // Incomplete is OK because the cache may have grown since the size was queried (unless when exiting).
4474
4475
// The real buffer size may now be bigger than the updated current_size.
4476
// We take into account the new size but keep the buffer resized in a worst-case fashion.
4477
4478
PipelineCacheHeader *header = (PipelineCacheHeader *)pipelines_cache.buffer.ptrw();
4479
header->data_size = pipelines_cache.current_size;
4480
header->data_hash = hash_murmur3_buffer(pipelines_cache.buffer.ptr() + sizeof(PipelineCacheHeader), pipelines_cache.current_size);
4481
4482
return pipelines_cache.buffer;
4483
}
4484
4485
/*******************/
4486
/**** RENDERING ****/
4487
/*******************/
4488
4489
// ----- SUBPASS -----
4490
4491
// RDD::AttachmentLoadOp == VkAttachmentLoadOp.
4492
static_assert(ENUM_MEMBERS_EQUAL(RDD::ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_LOAD));
4493
static_assert(ENUM_MEMBERS_EQUAL(RDD::ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_LOAD_OP_CLEAR));
4494
static_assert(ENUM_MEMBERS_EQUAL(RDD::ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_LOAD_OP_DONT_CARE));
4495
4496
// RDD::AttachmentStoreOp == VkAttachmentStoreOp.
4497
static_assert(ENUM_MEMBERS_EQUAL(RDD::ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_STORE_OP_STORE));
4498
static_assert(ENUM_MEMBERS_EQUAL(RDD::ATTACHMENT_STORE_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE));
4499
4500
// Assuming Vulkan and RDD's are backed by uint32_t in:
4501
// - VkSubpassDescription2::pPreserveAttachments and RDD::Subpass::preserve_attachments.
4502
// - VkRenderPassCreateInfo2KHR::pCorrelatedViewMasks and p_view_correlation_mask.
4503
4504
static void _attachment_reference_to_vk(const RDD::AttachmentReference &p_attachment_reference, VkAttachmentReference2KHR *r_vk_attachment_reference) {
4505
*r_vk_attachment_reference = {};
4506
r_vk_attachment_reference->sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR;
4507
r_vk_attachment_reference->attachment = p_attachment_reference.attachment;
4508
r_vk_attachment_reference->layout = RD_TO_VK_LAYOUT[p_attachment_reference.layout];
4509
r_vk_attachment_reference->aspectMask = (VkImageAspectFlags)p_attachment_reference.aspect;
4510
}
4511
4512
RDD::RenderPassID RenderingDeviceDriverVulkan::render_pass_create(VectorView<Attachment> p_attachments, VectorView<Subpass> p_subpasses, VectorView<SubpassDependency> p_subpass_dependencies, uint32_t p_view_count, AttachmentReference p_fragment_density_map_attachment) {
4513
// These are only used if we use multiview but we need to define them in scope.
4514
const uint32_t view_mask = (1 << p_view_count) - 1;
4515
const uint32_t correlation_mask = (1 << p_view_count) - 1;
4516
4517
VkAttachmentDescription2KHR *vk_attachments = ALLOCA_ARRAY(VkAttachmentDescription2KHR, p_attachments.size());
4518
for (uint32_t i = 0; i < p_attachments.size(); i++) {
4519
vk_attachments[i] = {};
4520
vk_attachments[i].sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR;
4521
vk_attachments[i].format = RD_TO_VK_FORMAT[p_attachments[i].format];
4522
vk_attachments[i].samples = _ensure_supported_sample_count(p_attachments[i].samples);
4523
vk_attachments[i].loadOp = (VkAttachmentLoadOp)p_attachments[i].load_op;
4524
vk_attachments[i].storeOp = (VkAttachmentStoreOp)p_attachments[i].store_op;
4525
vk_attachments[i].stencilLoadOp = (VkAttachmentLoadOp)p_attachments[i].stencil_load_op;
4526
vk_attachments[i].stencilStoreOp = (VkAttachmentStoreOp)p_attachments[i].stencil_store_op;
4527
vk_attachments[i].initialLayout = RD_TO_VK_LAYOUT[p_attachments[i].initial_layout];
4528
vk_attachments[i].finalLayout = RD_TO_VK_LAYOUT[p_attachments[i].final_layout];
4529
}
4530
4531
VkSubpassDescription2KHR *vk_subpasses = ALLOCA_ARRAY(VkSubpassDescription2KHR, p_subpasses.size());
4532
for (uint32_t i = 0; i < p_subpasses.size(); i++) {
4533
VkAttachmentReference2KHR *vk_subpass_input_attachments = ALLOCA_ARRAY(VkAttachmentReference2KHR, p_subpasses[i].input_references.size());
4534
for (uint32_t j = 0; j < p_subpasses[i].input_references.size(); j++) {
4535
_attachment_reference_to_vk(p_subpasses[i].input_references[j], &vk_subpass_input_attachments[j]);
4536
}
4537
4538
VkAttachmentReference2KHR *vk_subpass_color_attachments = ALLOCA_ARRAY(VkAttachmentReference2KHR, p_subpasses[i].color_references.size());
4539
for (uint32_t j = 0; j < p_subpasses[i].color_references.size(); j++) {
4540
_attachment_reference_to_vk(p_subpasses[i].color_references[j], &vk_subpass_color_attachments[j]);
4541
}
4542
4543
VkAttachmentReference2KHR *vk_subpass_resolve_attachments = ALLOCA_ARRAY(VkAttachmentReference2KHR, p_subpasses[i].resolve_references.size());
4544
for (uint32_t j = 0; j < p_subpasses[i].resolve_references.size(); j++) {
4545
_attachment_reference_to_vk(p_subpasses[i].resolve_references[j], &vk_subpass_resolve_attachments[j]);
4546
}
4547
4548
VkAttachmentReference2KHR *vk_subpass_depth_stencil_attachment = nullptr;
4549
if (p_subpasses[i].depth_stencil_reference.attachment != AttachmentReference::UNUSED) {
4550
vk_subpass_depth_stencil_attachment = ALLOCA_SINGLE(VkAttachmentReference2KHR);
4551
_attachment_reference_to_vk(p_subpasses[i].depth_stencil_reference, vk_subpass_depth_stencil_attachment);
4552
}
4553
4554
vk_subpasses[i] = {};
4555
vk_subpasses[i].sType = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR;
4556
vk_subpasses[i].pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
4557
vk_subpasses[i].viewMask = p_view_count == 1 ? 0 : view_mask;
4558
vk_subpasses[i].inputAttachmentCount = p_subpasses[i].input_references.size();
4559
vk_subpasses[i].pInputAttachments = vk_subpass_input_attachments;
4560
vk_subpasses[i].colorAttachmentCount = p_subpasses[i].color_references.size();
4561
vk_subpasses[i].pColorAttachments = vk_subpass_color_attachments;
4562
vk_subpasses[i].pResolveAttachments = vk_subpass_resolve_attachments;
4563
vk_subpasses[i].pDepthStencilAttachment = vk_subpass_depth_stencil_attachment;
4564
vk_subpasses[i].preserveAttachmentCount = p_subpasses[i].preserve_attachments.size();
4565
vk_subpasses[i].pPreserveAttachments = p_subpasses[i].preserve_attachments.ptr();
4566
4567
// Fragment shading rate.
4568
if (fsr_capabilities.attachment_supported && p_subpasses[i].fragment_shading_rate_reference.attachment != AttachmentReference::UNUSED) {
4569
VkAttachmentReference2KHR *vk_subpass_fsr_attachment = ALLOCA_SINGLE(VkAttachmentReference2KHR);
4570
*vk_subpass_fsr_attachment = {};
4571
vk_subpass_fsr_attachment->sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR;
4572
vk_subpass_fsr_attachment->attachment = p_subpasses[i].fragment_shading_rate_reference.attachment;
4573
vk_subpass_fsr_attachment->layout = VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR;
4574
4575
VkFragmentShadingRateAttachmentInfoKHR *vk_fsr_info = ALLOCA_SINGLE(VkFragmentShadingRateAttachmentInfoKHR);
4576
*vk_fsr_info = {};
4577
vk_fsr_info->sType = VK_STRUCTURE_TYPE_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR;
4578
vk_fsr_info->pFragmentShadingRateAttachment = vk_subpass_fsr_attachment;
4579
vk_fsr_info->shadingRateAttachmentTexelSize.width = p_subpasses[i].fragment_shading_rate_texel_size.x;
4580
vk_fsr_info->shadingRateAttachmentTexelSize.height = p_subpasses[i].fragment_shading_rate_texel_size.y;
4581
4582
vk_subpasses[i].pNext = vk_fsr_info;
4583
}
4584
}
4585
4586
VkSubpassDependency2KHR *vk_subpass_dependencies = ALLOCA_ARRAY(VkSubpassDependency2KHR, p_subpass_dependencies.size());
4587
for (uint32_t i = 0; i < p_subpass_dependencies.size(); i++) {
4588
vk_subpass_dependencies[i] = {};
4589
vk_subpass_dependencies[i].sType = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2;
4590
vk_subpass_dependencies[i].srcSubpass = p_subpass_dependencies[i].src_subpass;
4591
vk_subpass_dependencies[i].dstSubpass = p_subpass_dependencies[i].dst_subpass;
4592
vk_subpass_dependencies[i].srcStageMask = _rd_to_vk_pipeline_stages(p_subpass_dependencies[i].src_stages);
4593
vk_subpass_dependencies[i].dstStageMask = _rd_to_vk_pipeline_stages(p_subpass_dependencies[i].dst_stages);
4594
vk_subpass_dependencies[i].srcAccessMask = _rd_to_vk_access_flags(p_subpass_dependencies[i].src_access);
4595
vk_subpass_dependencies[i].dstAccessMask = _rd_to_vk_access_flags(p_subpass_dependencies[i].dst_access);
4596
}
4597
4598
VkRenderPassCreateInfo2KHR create_info = {};
4599
create_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR;
4600
create_info.attachmentCount = p_attachments.size();
4601
create_info.pAttachments = vk_attachments;
4602
create_info.subpassCount = p_subpasses.size();
4603
create_info.pSubpasses = vk_subpasses;
4604
create_info.dependencyCount = p_subpass_dependencies.size();
4605
create_info.pDependencies = vk_subpass_dependencies;
4606
create_info.correlatedViewMaskCount = p_view_count == 1 ? 0 : 1;
4607
create_info.pCorrelatedViewMasks = p_view_count == 1 ? nullptr : &correlation_mask;
4608
4609
// Multiview.
4610
if (p_view_count > 1 && device_functions.CreateRenderPass2KHR == nullptr) {
4611
// This is only required when not using vkCreateRenderPass2.
4612
// We add it if vkCreateRenderPass2KHR is not supported,
4613
// resulting this in being passed to our vkCreateRenderPass fallback.
4614
4615
uint32_t *vk_view_masks = ALLOCA_ARRAY(uint32_t, p_subpasses.size());
4616
for (uint32_t i = 0; i < p_subpasses.size(); i++) {
4617
vk_view_masks[i] = view_mask;
4618
}
4619
4620
VkRenderPassMultiviewCreateInfo *multiview_create_info = ALLOCA_SINGLE(VkRenderPassMultiviewCreateInfo);
4621
*multiview_create_info = {};
4622
multiview_create_info->sType = VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO;
4623
multiview_create_info->subpassCount = p_subpasses.size();
4624
multiview_create_info->pViewMasks = vk_view_masks;
4625
multiview_create_info->correlationMaskCount = 1;
4626
multiview_create_info->pCorrelationMasks = &correlation_mask;
4627
4628
create_info.pNext = multiview_create_info;
4629
}
4630
4631
// Fragment density map.
4632
bool uses_fragment_density_map = fdm_capabilities.attachment_supported && p_fragment_density_map_attachment.attachment != AttachmentReference::UNUSED;
4633
if (uses_fragment_density_map) {
4634
VkRenderPassFragmentDensityMapCreateInfoEXT *vk_fdm_info = ALLOCA_SINGLE(VkRenderPassFragmentDensityMapCreateInfoEXT);
4635
vk_fdm_info->sType = VK_STRUCTURE_TYPE_RENDER_PASS_FRAGMENT_DENSITY_MAP_CREATE_INFO_EXT;
4636
vk_fdm_info->fragmentDensityMapAttachment.attachment = p_fragment_density_map_attachment.attachment;
4637
vk_fdm_info->fragmentDensityMapAttachment.layout = RD_TO_VK_LAYOUT[p_fragment_density_map_attachment.layout];
4638
vk_fdm_info->pNext = create_info.pNext;
4639
create_info.pNext = vk_fdm_info;
4640
}
4641
4642
VkRenderPass vk_render_pass = VK_NULL_HANDLE;
4643
VkResult res = _create_render_pass(vk_device, &create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_RENDER_PASS), &vk_render_pass);
4644
ERR_FAIL_COND_V_MSG(res, RenderPassID(), "vkCreateRenderPass2KHR failed with error " + itos(res) + ".");
4645
4646
RenderPassInfo *render_pass = VersatileResource::allocate<RenderPassInfo>(resources_allocator);
4647
render_pass->vk_render_pass = vk_render_pass;
4648
return RenderPassID(render_pass);
4649
}
4650
4651
void RenderingDeviceDriverVulkan::render_pass_free(RenderPassID p_render_pass) {
4652
RenderPassInfo *render_pass = (RenderPassInfo *)(p_render_pass.id);
4653
vkDestroyRenderPass(vk_device, render_pass->vk_render_pass, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_RENDER_PASS));
4654
VersatileResource::free<RenderPassInfo>(resources_allocator, render_pass);
4655
}
4656
4657
// ----- COMMANDS -----
4658
4659
static_assert(ARRAYS_COMPATIBLE_FIELDWISE(RDD::RenderPassClearValue, VkClearValue));
4660
4661
void RenderingDeviceDriverVulkan::command_begin_render_pass(CommandBufferID p_cmd_buffer, RenderPassID p_render_pass, FramebufferID p_framebuffer, CommandBufferType p_cmd_buffer_type, const Rect2i &p_rect, VectorView<RenderPassClearValue> p_clear_values) {
4662
CommandBufferInfo *command_buffer = (CommandBufferInfo *)(p_cmd_buffer.id);
4663
RenderPassInfo *render_pass = (RenderPassInfo *)(p_render_pass.id);
4664
Framebuffer *framebuffer = (Framebuffer *)(p_framebuffer.id);
4665
4666
if (framebuffer->swap_chain_acquired) {
4667
// Insert a barrier to wait for the acquisition of the framebuffer before the render pass begins.
4668
VkImageMemoryBarrier image_barrier = {};
4669
image_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
4670
image_barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
4671
image_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
4672
image_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
4673
image_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
4674
image_barrier.image = framebuffer->swap_chain_image;
4675
image_barrier.subresourceRange = framebuffer->swap_chain_image_subresource_range;
4676
vkCmdPipelineBarrier(command_buffer->vk_command_buffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0, nullptr, 0, nullptr, 1, &image_barrier);
4677
framebuffer->swap_chain_acquired = false;
4678
}
4679
4680
VkRenderPassBeginInfo render_pass_begin = {};
4681
render_pass_begin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
4682
render_pass_begin.renderPass = render_pass->vk_render_pass;
4683
render_pass_begin.framebuffer = framebuffer->vk_framebuffer;
4684
4685
render_pass_begin.renderArea.offset.x = p_rect.position.x;
4686
render_pass_begin.renderArea.offset.y = p_rect.position.y;
4687
render_pass_begin.renderArea.extent.width = p_rect.size.x;
4688
render_pass_begin.renderArea.extent.height = p_rect.size.y;
4689
4690
render_pass_begin.clearValueCount = p_clear_values.size();
4691
render_pass_begin.pClearValues = (const VkClearValue *)p_clear_values.ptr();
4692
4693
VkSubpassContents vk_subpass_contents = p_cmd_buffer_type == COMMAND_BUFFER_TYPE_PRIMARY ? VK_SUBPASS_CONTENTS_INLINE : VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS;
4694
vkCmdBeginRenderPass(command_buffer->vk_command_buffer, &render_pass_begin, vk_subpass_contents);
4695
4696
command_buffer->active_framebuffer = framebuffer;
4697
command_buffer->active_render_pass = render_pass;
4698
4699
#if PRINT_NATIVE_COMMANDS
4700
print_line(vformat("vkCmdBeginRenderPass Pass 0x%uX Framebuffer 0x%uX", p_render_pass.id, p_framebuffer.id));
4701
#endif
4702
}
4703
4704
void RenderingDeviceDriverVulkan::command_end_render_pass(CommandBufferID p_cmd_buffer) {
4705
CommandBufferInfo *command_buffer = (CommandBufferInfo *)(p_cmd_buffer.id);
4706
DEV_ASSERT(command_buffer->active_framebuffer != nullptr && "A framebuffer must be active.");
4707
DEV_ASSERT(command_buffer->active_render_pass != nullptr && "A render pass must be active.");
4708
4709
vkCmdEndRenderPass(command_buffer->vk_command_buffer);
4710
4711
command_buffer->active_render_pass = nullptr;
4712
command_buffer->active_framebuffer = nullptr;
4713
4714
#if PRINT_NATIVE_COMMANDS
4715
print_line("vkCmdEndRenderPass");
4716
#endif
4717
}
4718
4719
void RenderingDeviceDriverVulkan::command_next_render_subpass(CommandBufferID p_cmd_buffer, CommandBufferType p_cmd_buffer_type) {
4720
const CommandBufferInfo *command_buffer = (const CommandBufferInfo *)p_cmd_buffer.id;
4721
VkSubpassContents vk_subpass_contents = p_cmd_buffer_type == COMMAND_BUFFER_TYPE_PRIMARY ? VK_SUBPASS_CONTENTS_INLINE : VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS;
4722
vkCmdNextSubpass(command_buffer->vk_command_buffer, vk_subpass_contents);
4723
}
4724
4725
void RenderingDeviceDriverVulkan::command_render_set_viewport(CommandBufferID p_cmd_buffer, VectorView<Rect2i> p_viewports) {
4726
const CommandBufferInfo *command_buffer = (const CommandBufferInfo *)p_cmd_buffer.id;
4727
VkViewport *vk_viewports = ALLOCA_ARRAY(VkViewport, p_viewports.size());
4728
for (uint32_t i = 0; i < p_viewports.size(); i++) {
4729
vk_viewports[i] = {};
4730
vk_viewports[i].x = p_viewports[i].position.x;
4731
vk_viewports[i].y = p_viewports[i].position.y;
4732
vk_viewports[i].width = p_viewports[i].size.x;
4733
vk_viewports[i].height = p_viewports[i].size.y;
4734
vk_viewports[i].minDepth = 0.0f;
4735
vk_viewports[i].maxDepth = 1.0f;
4736
}
4737
vkCmdSetViewport(command_buffer->vk_command_buffer, 0, p_viewports.size(), vk_viewports);
4738
}
4739
4740
void RenderingDeviceDriverVulkan::command_render_set_scissor(CommandBufferID p_cmd_buffer, VectorView<Rect2i> p_scissors) {
4741
const CommandBufferInfo *command_buffer = (const CommandBufferInfo *)p_cmd_buffer.id;
4742
vkCmdSetScissor(command_buffer->vk_command_buffer, 0, p_scissors.size(), (VkRect2D *)p_scissors.ptr());
4743
}
4744
4745
void RenderingDeviceDriverVulkan::command_render_clear_attachments(CommandBufferID p_cmd_buffer, VectorView<AttachmentClear> p_attachment_clears, VectorView<Rect2i> p_rects) {
4746
const CommandBufferInfo *command_buffer = (const CommandBufferInfo *)p_cmd_buffer.id;
4747
4748
VkClearAttachment *vk_clears = ALLOCA_ARRAY(VkClearAttachment, p_attachment_clears.size());
4749
for (uint32_t i = 0; i < p_attachment_clears.size(); i++) {
4750
vk_clears[i] = {};
4751
memcpy(&vk_clears[i].clearValue, &p_attachment_clears[i].value, sizeof(VkClearValue));
4752
vk_clears[i].colorAttachment = p_attachment_clears[i].color_attachment;
4753
vk_clears[i].aspectMask = p_attachment_clears[i].aspect;
4754
}
4755
4756
VkClearRect *vk_rects = ALLOCA_ARRAY(VkClearRect, p_rects.size());
4757
for (uint32_t i = 0; i < p_rects.size(); i++) {
4758
vk_rects[i] = {};
4759
vk_rects[i].rect.offset.x = p_rects[i].position.x;
4760
vk_rects[i].rect.offset.y = p_rects[i].position.y;
4761
vk_rects[i].rect.extent.width = p_rects[i].size.x;
4762
vk_rects[i].rect.extent.height = p_rects[i].size.y;
4763
vk_rects[i].baseArrayLayer = 0;
4764
vk_rects[i].layerCount = 1;
4765
}
4766
4767
vkCmdClearAttachments(command_buffer->vk_command_buffer, p_attachment_clears.size(), vk_clears, p_rects.size(), vk_rects);
4768
}
4769
4770
void RenderingDeviceDriverVulkan::command_bind_render_pipeline(CommandBufferID p_cmd_buffer, PipelineID p_pipeline) {
4771
const CommandBufferInfo *command_buffer = (const CommandBufferInfo *)p_cmd_buffer.id;
4772
vkCmdBindPipeline(command_buffer->vk_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, (VkPipeline)p_pipeline.id);
4773
}
4774
4775
void RenderingDeviceDriverVulkan::command_bind_render_uniform_set(CommandBufferID p_cmd_buffer, UniformSetID p_uniform_set, ShaderID p_shader, uint32_t p_set_index) {
4776
const CommandBufferInfo *command_buffer = (const CommandBufferInfo *)p_cmd_buffer.id;
4777
const ShaderInfo *shader_info = (const ShaderInfo *)p_shader.id;
4778
const UniformSetInfo *usi = (const UniformSetInfo *)p_uniform_set.id;
4779
vkCmdBindDescriptorSets(command_buffer->vk_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, shader_info->vk_pipeline_layout, p_set_index, 1, &usi->vk_descriptor_set, 0, nullptr);
4780
}
4781
4782
void RenderingDeviceDriverVulkan::command_bind_render_uniform_sets(CommandBufferID p_cmd_buffer, VectorView<UniformSetID> p_uniform_sets, ShaderID p_shader, uint32_t p_first_set_index, uint32_t p_set_count) {
4783
if (p_set_count == 0) {
4784
return;
4785
}
4786
4787
thread_local LocalVector<VkDescriptorSet> sets;
4788
sets.clear();
4789
sets.resize(p_set_count);
4790
4791
for (uint32_t i = 0; i < p_set_count; i++) {
4792
sets[i] = ((const UniformSetInfo *)p_uniform_sets[i].id)->vk_descriptor_set;
4793
}
4794
4795
const CommandBufferInfo *command_buffer = (const CommandBufferInfo *)p_cmd_buffer.id;
4796
const ShaderInfo *shader_info = (const ShaderInfo *)p_shader.id;
4797
vkCmdBindDescriptorSets(command_buffer->vk_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, shader_info->vk_pipeline_layout, p_first_set_index, p_set_count, &sets[0], 0, nullptr);
4798
}
4799
4800
void RenderingDeviceDriverVulkan::command_render_draw(CommandBufferID p_cmd_buffer, uint32_t p_vertex_count, uint32_t p_instance_count, uint32_t p_base_vertex, uint32_t p_first_instance) {
4801
const CommandBufferInfo *command_buffer = (const CommandBufferInfo *)p_cmd_buffer.id;
4802
vkCmdDraw(command_buffer->vk_command_buffer, p_vertex_count, p_instance_count, p_base_vertex, p_first_instance);
4803
}
4804
4805
void RenderingDeviceDriverVulkan::command_render_draw_indexed(CommandBufferID p_cmd_buffer, uint32_t p_index_count, uint32_t p_instance_count, uint32_t p_first_index, int32_t p_vertex_offset, uint32_t p_first_instance) {
4806
const CommandBufferInfo *command_buffer = (const CommandBufferInfo *)p_cmd_buffer.id;
4807
vkCmdDrawIndexed(command_buffer->vk_command_buffer, p_index_count, p_instance_count, p_first_index, p_vertex_offset, p_first_instance);
4808
}
4809
4810
void RenderingDeviceDriverVulkan::command_render_draw_indexed_indirect(CommandBufferID p_cmd_buffer, BufferID p_indirect_buffer, uint64_t p_offset, uint32_t p_draw_count, uint32_t p_stride) {
4811
const CommandBufferInfo *command_buffer = (const CommandBufferInfo *)p_cmd_buffer.id;
4812
const BufferInfo *buf_info = (const BufferInfo *)p_indirect_buffer.id;
4813
vkCmdDrawIndexedIndirect(command_buffer->vk_command_buffer, buf_info->vk_buffer, p_offset, p_draw_count, p_stride);
4814
}
4815
4816
void RenderingDeviceDriverVulkan::command_render_draw_indexed_indirect_count(CommandBufferID p_cmd_buffer, BufferID p_indirect_buffer, uint64_t p_offset, BufferID p_count_buffer, uint64_t p_count_buffer_offset, uint32_t p_max_draw_count, uint32_t p_stride) {
4817
const CommandBufferInfo *command_buffer = (const CommandBufferInfo *)p_cmd_buffer.id;
4818
const BufferInfo *indirect_buf_info = (const BufferInfo *)p_indirect_buffer.id;
4819
const BufferInfo *count_buf_info = (const BufferInfo *)p_count_buffer.id;
4820
vkCmdDrawIndexedIndirectCount(command_buffer->vk_command_buffer, indirect_buf_info->vk_buffer, p_offset, count_buf_info->vk_buffer, p_count_buffer_offset, p_max_draw_count, p_stride);
4821
}
4822
4823
void RenderingDeviceDriverVulkan::command_render_draw_indirect(CommandBufferID p_cmd_buffer, BufferID p_indirect_buffer, uint64_t p_offset, uint32_t p_draw_count, uint32_t p_stride) {
4824
const CommandBufferInfo *command_buffer = (const CommandBufferInfo *)p_cmd_buffer.id;
4825
const BufferInfo *buf_info = (const BufferInfo *)p_indirect_buffer.id;
4826
vkCmdDrawIndirect(command_buffer->vk_command_buffer, buf_info->vk_buffer, p_offset, p_draw_count, p_stride);
4827
}
4828
4829
void RenderingDeviceDriverVulkan::command_render_draw_indirect_count(CommandBufferID p_cmd_buffer, BufferID p_indirect_buffer, uint64_t p_offset, BufferID p_count_buffer, uint64_t p_count_buffer_offset, uint32_t p_max_draw_count, uint32_t p_stride) {
4830
const CommandBufferInfo *command_buffer = (const CommandBufferInfo *)p_cmd_buffer.id;
4831
const BufferInfo *indirect_buf_info = (const BufferInfo *)p_indirect_buffer.id;
4832
const BufferInfo *count_buf_info = (const BufferInfo *)p_count_buffer.id;
4833
vkCmdDrawIndirectCount(command_buffer->vk_command_buffer, indirect_buf_info->vk_buffer, p_offset, count_buf_info->vk_buffer, p_count_buffer_offset, p_max_draw_count, p_stride);
4834
}
4835
4836
void RenderingDeviceDriverVulkan::command_render_bind_vertex_buffers(CommandBufferID p_cmd_buffer, uint32_t p_binding_count, const BufferID *p_buffers, const uint64_t *p_offsets) {
4837
const CommandBufferInfo *command_buffer = (const CommandBufferInfo *)p_cmd_buffer.id;
4838
4839
VkBuffer *vk_buffers = ALLOCA_ARRAY(VkBuffer, p_binding_count);
4840
for (uint32_t i = 0; i < p_binding_count; i++) {
4841
vk_buffers[i] = ((const BufferInfo *)p_buffers[i].id)->vk_buffer;
4842
}
4843
vkCmdBindVertexBuffers(command_buffer->vk_command_buffer, 0, p_binding_count, vk_buffers, p_offsets);
4844
}
4845
4846
void RenderingDeviceDriverVulkan::command_render_bind_index_buffer(CommandBufferID p_cmd_buffer, BufferID p_buffer, IndexBufferFormat p_format, uint64_t p_offset) {
4847
const CommandBufferInfo *command_buffer = (const CommandBufferInfo *)p_cmd_buffer.id;
4848
const BufferInfo *buf_info = (const BufferInfo *)p_buffer.id;
4849
vkCmdBindIndexBuffer(command_buffer->vk_command_buffer, buf_info->vk_buffer, p_offset, p_format == INDEX_BUFFER_FORMAT_UINT16 ? VK_INDEX_TYPE_UINT16 : VK_INDEX_TYPE_UINT32);
4850
}
4851
4852
void RenderingDeviceDriverVulkan::command_render_set_blend_constants(CommandBufferID p_cmd_buffer, const Color &p_constants) {
4853
const CommandBufferInfo *command_buffer = (const CommandBufferInfo *)p_cmd_buffer.id;
4854
vkCmdSetBlendConstants(command_buffer->vk_command_buffer, p_constants.components);
4855
}
4856
4857
void RenderingDeviceDriverVulkan::command_render_set_line_width(CommandBufferID p_cmd_buffer, float p_width) {
4858
const CommandBufferInfo *command_buffer = (const CommandBufferInfo *)p_cmd_buffer.id;
4859
vkCmdSetLineWidth(command_buffer->vk_command_buffer, p_width);
4860
}
4861
4862
// ----- PIPELINE -----
4863
4864
static const VkPrimitiveTopology RD_TO_VK_PRIMITIVE[RDD::RENDER_PRIMITIVE_MAX] = {
4865
VK_PRIMITIVE_TOPOLOGY_POINT_LIST,
4866
VK_PRIMITIVE_TOPOLOGY_LINE_LIST,
4867
VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY,
4868
VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,
4869
VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY,
4870
VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
4871
VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY,
4872
VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
4873
VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY,
4874
VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
4875
VK_PRIMITIVE_TOPOLOGY_PATCH_LIST,
4876
};
4877
4878
// RDD::PolygonCullMode == VkCullModeFlagBits.
4879
static_assert(ENUM_MEMBERS_EQUAL(RDD::POLYGON_CULL_DISABLED, VK_CULL_MODE_NONE));
4880
static_assert(ENUM_MEMBERS_EQUAL(RDD::POLYGON_CULL_FRONT, VK_CULL_MODE_FRONT_BIT));
4881
static_assert(ENUM_MEMBERS_EQUAL(RDD::POLYGON_CULL_BACK, VK_CULL_MODE_BACK_BIT));
4882
4883
// RDD::StencilOperation == VkStencilOp.
4884
static_assert(ENUM_MEMBERS_EQUAL(RDD::STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP));
4885
static_assert(ENUM_MEMBERS_EQUAL(RDD::STENCIL_OP_ZERO, VK_STENCIL_OP_ZERO));
4886
static_assert(ENUM_MEMBERS_EQUAL(RDD::STENCIL_OP_REPLACE, VK_STENCIL_OP_REPLACE));
4887
static_assert(ENUM_MEMBERS_EQUAL(RDD::STENCIL_OP_INCREMENT_AND_CLAMP, VK_STENCIL_OP_INCREMENT_AND_CLAMP));
4888
static_assert(ENUM_MEMBERS_EQUAL(RDD::STENCIL_OP_DECREMENT_AND_CLAMP, VK_STENCIL_OP_DECREMENT_AND_CLAMP));
4889
static_assert(ENUM_MEMBERS_EQUAL(RDD::STENCIL_OP_INVERT, VK_STENCIL_OP_INVERT));
4890
static_assert(ENUM_MEMBERS_EQUAL(RDD::STENCIL_OP_INCREMENT_AND_WRAP, VK_STENCIL_OP_INCREMENT_AND_WRAP));
4891
static_assert(ENUM_MEMBERS_EQUAL(RDD::STENCIL_OP_DECREMENT_AND_WRAP, VK_STENCIL_OP_DECREMENT_AND_WRAP));
4892
4893
// RDD::LogicOperation == VkLogicOp.
4894
static_assert(ENUM_MEMBERS_EQUAL(RDD::LOGIC_OP_CLEAR, VK_LOGIC_OP_CLEAR));
4895
static_assert(ENUM_MEMBERS_EQUAL(RDD::LOGIC_OP_AND, VK_LOGIC_OP_AND));
4896
static_assert(ENUM_MEMBERS_EQUAL(RDD::LOGIC_OP_AND_REVERSE, VK_LOGIC_OP_AND_REVERSE));
4897
static_assert(ENUM_MEMBERS_EQUAL(RDD::LOGIC_OP_COPY, VK_LOGIC_OP_COPY));
4898
static_assert(ENUM_MEMBERS_EQUAL(RDD::LOGIC_OP_AND_INVERTED, VK_LOGIC_OP_AND_INVERTED));
4899
static_assert(ENUM_MEMBERS_EQUAL(RDD::LOGIC_OP_NO_OP, VK_LOGIC_OP_NO_OP));
4900
static_assert(ENUM_MEMBERS_EQUAL(RDD::LOGIC_OP_XOR, VK_LOGIC_OP_XOR));
4901
static_assert(ENUM_MEMBERS_EQUAL(RDD::LOGIC_OP_OR, VK_LOGIC_OP_OR));
4902
static_assert(ENUM_MEMBERS_EQUAL(RDD::LOGIC_OP_NOR, VK_LOGIC_OP_NOR));
4903
static_assert(ENUM_MEMBERS_EQUAL(RDD::LOGIC_OP_EQUIVALENT, VK_LOGIC_OP_EQUIVALENT));
4904
static_assert(ENUM_MEMBERS_EQUAL(RDD::LOGIC_OP_INVERT, VK_LOGIC_OP_INVERT));
4905
static_assert(ENUM_MEMBERS_EQUAL(RDD::LOGIC_OP_OR_REVERSE, VK_LOGIC_OP_OR_REVERSE));
4906
static_assert(ENUM_MEMBERS_EQUAL(RDD::LOGIC_OP_COPY_INVERTED, VK_LOGIC_OP_COPY_INVERTED));
4907
static_assert(ENUM_MEMBERS_EQUAL(RDD::LOGIC_OP_OR_INVERTED, VK_LOGIC_OP_OR_INVERTED));
4908
static_assert(ENUM_MEMBERS_EQUAL(RDD::LOGIC_OP_NAND, VK_LOGIC_OP_NAND));
4909
static_assert(ENUM_MEMBERS_EQUAL(RDD::LOGIC_OP_SET, VK_LOGIC_OP_SET));
4910
4911
// RDD::BlendFactor == VkBlendFactor.
4912
static_assert(ENUM_MEMBERS_EQUAL(RDD::BLEND_FACTOR_ZERO, VK_BLEND_FACTOR_ZERO));
4913
static_assert(ENUM_MEMBERS_EQUAL(RDD::BLEND_FACTOR_ONE, VK_BLEND_FACTOR_ONE));
4914
static_assert(ENUM_MEMBERS_EQUAL(RDD::BLEND_FACTOR_SRC_COLOR, VK_BLEND_FACTOR_SRC_COLOR));
4915
static_assert(ENUM_MEMBERS_EQUAL(RDD::BLEND_FACTOR_ONE_MINUS_SRC_COLOR, VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR));
4916
static_assert(ENUM_MEMBERS_EQUAL(RDD::BLEND_FACTOR_DST_COLOR, VK_BLEND_FACTOR_DST_COLOR));
4917
static_assert(ENUM_MEMBERS_EQUAL(RDD::BLEND_FACTOR_ONE_MINUS_DST_COLOR, VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR));
4918
static_assert(ENUM_MEMBERS_EQUAL(RDD::BLEND_FACTOR_SRC_ALPHA, VK_BLEND_FACTOR_SRC_ALPHA));
4919
static_assert(ENUM_MEMBERS_EQUAL(RDD::BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA));
4920
static_assert(ENUM_MEMBERS_EQUAL(RDD::BLEND_FACTOR_DST_ALPHA, VK_BLEND_FACTOR_DST_ALPHA));
4921
static_assert(ENUM_MEMBERS_EQUAL(RDD::BLEND_FACTOR_ONE_MINUS_DST_ALPHA, VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA));
4922
static_assert(ENUM_MEMBERS_EQUAL(RDD::BLEND_FACTOR_CONSTANT_COLOR, VK_BLEND_FACTOR_CONSTANT_COLOR));
4923
static_assert(ENUM_MEMBERS_EQUAL(RDD::BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR, VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR));
4924
static_assert(ENUM_MEMBERS_EQUAL(RDD::BLEND_FACTOR_CONSTANT_ALPHA, VK_BLEND_FACTOR_CONSTANT_ALPHA));
4925
static_assert(ENUM_MEMBERS_EQUAL(RDD::BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA, VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA));
4926
static_assert(ENUM_MEMBERS_EQUAL(RDD::BLEND_FACTOR_SRC_ALPHA_SATURATE, VK_BLEND_FACTOR_SRC_ALPHA_SATURATE));
4927
static_assert(ENUM_MEMBERS_EQUAL(RDD::BLEND_FACTOR_SRC1_COLOR, VK_BLEND_FACTOR_SRC1_COLOR));
4928
static_assert(ENUM_MEMBERS_EQUAL(RDD::BLEND_FACTOR_ONE_MINUS_SRC1_COLOR, VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR));
4929
static_assert(ENUM_MEMBERS_EQUAL(RDD::BLEND_FACTOR_SRC1_ALPHA, VK_BLEND_FACTOR_SRC1_ALPHA));
4930
static_assert(ENUM_MEMBERS_EQUAL(RDD::BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA, VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA));
4931
4932
// RDD::BlendOperation == VkBlendOp.
4933
static_assert(ENUM_MEMBERS_EQUAL(RDD::BLEND_OP_ADD, VK_BLEND_OP_ADD));
4934
static_assert(ENUM_MEMBERS_EQUAL(RDD::BLEND_OP_SUBTRACT, VK_BLEND_OP_SUBTRACT));
4935
static_assert(ENUM_MEMBERS_EQUAL(RDD::BLEND_OP_REVERSE_SUBTRACT, VK_BLEND_OP_REVERSE_SUBTRACT));
4936
static_assert(ENUM_MEMBERS_EQUAL(RDD::BLEND_OP_MINIMUM, VK_BLEND_OP_MIN));
4937
static_assert(ENUM_MEMBERS_EQUAL(RDD::BLEND_OP_MAXIMUM, VK_BLEND_OP_MAX));
4938
4939
RDD::PipelineID RenderingDeviceDriverVulkan::render_pipeline_create(
4940
ShaderID p_shader,
4941
VertexFormatID p_vertex_format,
4942
RenderPrimitive p_render_primitive,
4943
PipelineRasterizationState p_rasterization_state,
4944
PipelineMultisampleState p_multisample_state,
4945
PipelineDepthStencilState p_depth_stencil_state,
4946
PipelineColorBlendState p_blend_state,
4947
VectorView<int32_t> p_color_attachments,
4948
BitField<PipelineDynamicStateFlags> p_dynamic_state,
4949
RenderPassID p_render_pass,
4950
uint32_t p_render_subpass,
4951
VectorView<PipelineSpecializationConstant> p_specialization_constants) {
4952
// Vertex.
4953
const VkPipelineVertexInputStateCreateInfo *vertex_input_state_create_info = nullptr;
4954
if (p_vertex_format.id) {
4955
const VertexFormatInfo *vf_info = (const VertexFormatInfo *)p_vertex_format.id;
4956
vertex_input_state_create_info = &vf_info->vk_create_info;
4957
} else {
4958
VkPipelineVertexInputStateCreateInfo *null_vertex_input_state = ALLOCA_SINGLE(VkPipelineVertexInputStateCreateInfo);
4959
*null_vertex_input_state = {};
4960
null_vertex_input_state->sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
4961
vertex_input_state_create_info = null_vertex_input_state;
4962
}
4963
4964
// Input assembly.
4965
VkPipelineInputAssemblyStateCreateInfo input_assembly_create_info = {};
4966
input_assembly_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
4967
input_assembly_create_info.topology = RD_TO_VK_PRIMITIVE[p_render_primitive];
4968
input_assembly_create_info.primitiveRestartEnable = (p_render_primitive == RENDER_PRIMITIVE_TRIANGLE_STRIPS_WITH_RESTART_INDEX);
4969
4970
// Tessellation.
4971
VkPipelineTessellationStateCreateInfo tessellation_create_info = {};
4972
tessellation_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO;
4973
ERR_FAIL_COND_V(physical_device_properties.limits.maxTessellationPatchSize > 0 && (p_rasterization_state.patch_control_points < 1 || p_rasterization_state.patch_control_points > physical_device_properties.limits.maxTessellationPatchSize), PipelineID());
4974
tessellation_create_info.patchControlPoints = p_rasterization_state.patch_control_points;
4975
4976
// Viewport.
4977
VkPipelineViewportStateCreateInfo viewport_state_create_info = {};
4978
viewport_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
4979
viewport_state_create_info.viewportCount = 1; // If VR extensions are supported at some point, this will have to be customizable in the framebuffer format.
4980
viewport_state_create_info.scissorCount = 1;
4981
4982
// Rasterization.
4983
VkPipelineRasterizationStateCreateInfo rasterization_state_create_info = {};
4984
rasterization_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
4985
rasterization_state_create_info.depthClampEnable = p_rasterization_state.enable_depth_clamp;
4986
rasterization_state_create_info.rasterizerDiscardEnable = p_rasterization_state.discard_primitives;
4987
rasterization_state_create_info.polygonMode = p_rasterization_state.wireframe ? VK_POLYGON_MODE_LINE : VK_POLYGON_MODE_FILL;
4988
rasterization_state_create_info.cullMode = (PolygonCullMode)p_rasterization_state.cull_mode;
4989
rasterization_state_create_info.frontFace = (p_rasterization_state.front_face == POLYGON_FRONT_FACE_CLOCKWISE ? VK_FRONT_FACE_CLOCKWISE : VK_FRONT_FACE_COUNTER_CLOCKWISE);
4990
rasterization_state_create_info.depthBiasEnable = p_rasterization_state.depth_bias_enabled;
4991
rasterization_state_create_info.depthBiasConstantFactor = p_rasterization_state.depth_bias_constant_factor;
4992
rasterization_state_create_info.depthBiasClamp = p_rasterization_state.depth_bias_clamp;
4993
rasterization_state_create_info.depthBiasSlopeFactor = p_rasterization_state.depth_bias_slope_factor;
4994
rasterization_state_create_info.lineWidth = p_rasterization_state.line_width;
4995
4996
// Multisample.
4997
VkPipelineMultisampleStateCreateInfo multisample_state_create_info = {};
4998
multisample_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
4999
multisample_state_create_info.rasterizationSamples = _ensure_supported_sample_count(p_multisample_state.sample_count);
5000
multisample_state_create_info.sampleShadingEnable = p_multisample_state.enable_sample_shading;
5001
multisample_state_create_info.minSampleShading = p_multisample_state.min_sample_shading;
5002
if (p_multisample_state.sample_mask.size()) {
5003
static_assert(ARRAYS_COMPATIBLE(uint32_t, VkSampleMask));
5004
multisample_state_create_info.pSampleMask = p_multisample_state.sample_mask.ptr();
5005
} else {
5006
multisample_state_create_info.pSampleMask = nullptr;
5007
}
5008
multisample_state_create_info.alphaToCoverageEnable = p_multisample_state.enable_alpha_to_coverage;
5009
multisample_state_create_info.alphaToOneEnable = p_multisample_state.enable_alpha_to_one;
5010
5011
// Depth stencil.
5012
5013
VkPipelineDepthStencilStateCreateInfo depth_stencil_state_create_info = {};
5014
depth_stencil_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
5015
depth_stencil_state_create_info.depthTestEnable = p_depth_stencil_state.enable_depth_test;
5016
depth_stencil_state_create_info.depthWriteEnable = p_depth_stencil_state.enable_depth_write;
5017
depth_stencil_state_create_info.depthCompareOp = (VkCompareOp)p_depth_stencil_state.depth_compare_operator;
5018
depth_stencil_state_create_info.depthBoundsTestEnable = p_depth_stencil_state.enable_depth_range;
5019
depth_stencil_state_create_info.stencilTestEnable = p_depth_stencil_state.enable_stencil;
5020
5021
depth_stencil_state_create_info.front.failOp = (VkStencilOp)p_depth_stencil_state.front_op.fail;
5022
depth_stencil_state_create_info.front.passOp = (VkStencilOp)p_depth_stencil_state.front_op.pass;
5023
depth_stencil_state_create_info.front.depthFailOp = (VkStencilOp)p_depth_stencil_state.front_op.depth_fail;
5024
depth_stencil_state_create_info.front.compareOp = (VkCompareOp)p_depth_stencil_state.front_op.compare;
5025
depth_stencil_state_create_info.front.compareMask = p_depth_stencil_state.front_op.compare_mask;
5026
depth_stencil_state_create_info.front.writeMask = p_depth_stencil_state.front_op.write_mask;
5027
depth_stencil_state_create_info.front.reference = p_depth_stencil_state.front_op.reference;
5028
5029
depth_stencil_state_create_info.back.failOp = (VkStencilOp)p_depth_stencil_state.back_op.fail;
5030
depth_stencil_state_create_info.back.passOp = (VkStencilOp)p_depth_stencil_state.back_op.pass;
5031
depth_stencil_state_create_info.back.depthFailOp = (VkStencilOp)p_depth_stencil_state.back_op.depth_fail;
5032
depth_stencil_state_create_info.back.compareOp = (VkCompareOp)p_depth_stencil_state.back_op.compare;
5033
depth_stencil_state_create_info.back.compareMask = p_depth_stencil_state.back_op.compare_mask;
5034
depth_stencil_state_create_info.back.writeMask = p_depth_stencil_state.back_op.write_mask;
5035
depth_stencil_state_create_info.back.reference = p_depth_stencil_state.back_op.reference;
5036
5037
depth_stencil_state_create_info.minDepthBounds = p_depth_stencil_state.depth_range_min;
5038
depth_stencil_state_create_info.maxDepthBounds = p_depth_stencil_state.depth_range_max;
5039
5040
// Blend state.
5041
5042
VkPipelineColorBlendStateCreateInfo color_blend_state_create_info = {};
5043
color_blend_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
5044
color_blend_state_create_info.logicOpEnable = p_blend_state.enable_logic_op;
5045
color_blend_state_create_info.logicOp = (VkLogicOp)p_blend_state.logic_op;
5046
5047
VkPipelineColorBlendAttachmentState *vk_attachment_states = ALLOCA_ARRAY(VkPipelineColorBlendAttachmentState, p_color_attachments.size());
5048
{
5049
for (uint32_t i = 0; i < p_color_attachments.size(); i++) {
5050
vk_attachment_states[i] = {};
5051
if (p_color_attachments[i] != ATTACHMENT_UNUSED) {
5052
vk_attachment_states[i].blendEnable = p_blend_state.attachments[i].enable_blend;
5053
5054
vk_attachment_states[i].srcColorBlendFactor = (VkBlendFactor)p_blend_state.attachments[i].src_color_blend_factor;
5055
vk_attachment_states[i].dstColorBlendFactor = (VkBlendFactor)p_blend_state.attachments[i].dst_color_blend_factor;
5056
vk_attachment_states[i].colorBlendOp = (VkBlendOp)p_blend_state.attachments[i].color_blend_op;
5057
5058
vk_attachment_states[i].srcAlphaBlendFactor = (VkBlendFactor)p_blend_state.attachments[i].src_alpha_blend_factor;
5059
vk_attachment_states[i].dstAlphaBlendFactor = (VkBlendFactor)p_blend_state.attachments[i].dst_alpha_blend_factor;
5060
vk_attachment_states[i].alphaBlendOp = (VkBlendOp)p_blend_state.attachments[i].alpha_blend_op;
5061
5062
if (p_blend_state.attachments[i].write_r) {
5063
vk_attachment_states[i].colorWriteMask |= VK_COLOR_COMPONENT_R_BIT;
5064
}
5065
if (p_blend_state.attachments[i].write_g) {
5066
vk_attachment_states[i].colorWriteMask |= VK_COLOR_COMPONENT_G_BIT;
5067
}
5068
if (p_blend_state.attachments[i].write_b) {
5069
vk_attachment_states[i].colorWriteMask |= VK_COLOR_COMPONENT_B_BIT;
5070
}
5071
if (p_blend_state.attachments[i].write_a) {
5072
vk_attachment_states[i].colorWriteMask |= VK_COLOR_COMPONENT_A_BIT;
5073
}
5074
}
5075
}
5076
}
5077
color_blend_state_create_info.attachmentCount = p_color_attachments.size();
5078
color_blend_state_create_info.pAttachments = vk_attachment_states;
5079
5080
color_blend_state_create_info.blendConstants[0] = p_blend_state.blend_constant.r;
5081
color_blend_state_create_info.blendConstants[1] = p_blend_state.blend_constant.g;
5082
color_blend_state_create_info.blendConstants[2] = p_blend_state.blend_constant.b;
5083
color_blend_state_create_info.blendConstants[3] = p_blend_state.blend_constant.a;
5084
5085
// Dynamic state.
5086
5087
VkPipelineDynamicStateCreateInfo dynamic_state_create_info = {};
5088
dynamic_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
5089
5090
static const uint32_t MAX_DYN_STATE_COUNT = 9;
5091
VkDynamicState *vk_dynamic_states = ALLOCA_ARRAY(VkDynamicState, MAX_DYN_STATE_COUNT);
5092
uint32_t vk_dynamic_states_count = 0;
5093
5094
vk_dynamic_states[vk_dynamic_states_count] = VK_DYNAMIC_STATE_VIEWPORT; // Viewport and scissor are always dynamic.
5095
vk_dynamic_states_count++;
5096
vk_dynamic_states[vk_dynamic_states_count] = VK_DYNAMIC_STATE_SCISSOR;
5097
vk_dynamic_states_count++;
5098
if (p_dynamic_state.has_flag(DYNAMIC_STATE_LINE_WIDTH)) {
5099
vk_dynamic_states[vk_dynamic_states_count] = VK_DYNAMIC_STATE_LINE_WIDTH;
5100
vk_dynamic_states_count++;
5101
}
5102
if (p_dynamic_state.has_flag(DYNAMIC_STATE_DEPTH_BIAS)) {
5103
vk_dynamic_states[vk_dynamic_states_count] = VK_DYNAMIC_STATE_DEPTH_BIAS;
5104
vk_dynamic_states_count++;
5105
}
5106
if (p_dynamic_state.has_flag(DYNAMIC_STATE_BLEND_CONSTANTS)) {
5107
vk_dynamic_states[vk_dynamic_states_count] = VK_DYNAMIC_STATE_BLEND_CONSTANTS;
5108
vk_dynamic_states_count++;
5109
}
5110
if (p_dynamic_state.has_flag(DYNAMIC_STATE_DEPTH_BOUNDS)) {
5111
vk_dynamic_states[vk_dynamic_states_count] = VK_DYNAMIC_STATE_DEPTH_BOUNDS;
5112
vk_dynamic_states_count++;
5113
}
5114
if (p_dynamic_state.has_flag(DYNAMIC_STATE_STENCIL_COMPARE_MASK)) {
5115
vk_dynamic_states[vk_dynamic_states_count] = VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK;
5116
vk_dynamic_states_count++;
5117
}
5118
if (p_dynamic_state.has_flag(DYNAMIC_STATE_STENCIL_WRITE_MASK)) {
5119
vk_dynamic_states[vk_dynamic_states_count] = VK_DYNAMIC_STATE_STENCIL_WRITE_MASK;
5120
vk_dynamic_states_count++;
5121
}
5122
if (p_dynamic_state.has_flag(DYNAMIC_STATE_STENCIL_REFERENCE)) {
5123
vk_dynamic_states[vk_dynamic_states_count] = VK_DYNAMIC_STATE_STENCIL_REFERENCE;
5124
vk_dynamic_states_count++;
5125
}
5126
DEV_ASSERT(vk_dynamic_states_count <= MAX_DYN_STATE_COUNT);
5127
5128
dynamic_state_create_info.dynamicStateCount = vk_dynamic_states_count;
5129
dynamic_state_create_info.pDynamicStates = vk_dynamic_states;
5130
5131
void *graphics_pipeline_nextptr = nullptr;
5132
5133
if (fsr_capabilities.attachment_supported) {
5134
// Fragment shading rate.
5135
// If FSR is used, this defines how the different FSR types are combined.
5136
// combinerOps[0] decides how we use the output of pipeline and primitive (drawcall) FSR.
5137
// combinerOps[1] decides how we use the output of combinerOps[0] and our attachment FSR.
5138
5139
VkPipelineFragmentShadingRateStateCreateInfoKHR *fsr_create_info = ALLOCA_SINGLE(VkPipelineFragmentShadingRateStateCreateInfoKHR);
5140
*fsr_create_info = {};
5141
fsr_create_info->sType = VK_STRUCTURE_TYPE_PIPELINE_FRAGMENT_SHADING_RATE_STATE_CREATE_INFO_KHR;
5142
fsr_create_info->fragmentSize = { 4, 4 };
5143
fsr_create_info->combinerOps[0] = VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR; // We don't use pipeline/primitive FSR so this really doesn't matter.
5144
fsr_create_info->combinerOps[1] = VK_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_KHR; // Always use the outcome of attachment FSR if enabled.
5145
5146
graphics_pipeline_nextptr = fsr_create_info;
5147
}
5148
5149
// Finally, pipeline create info.
5150
5151
const ShaderInfo *shader_info = (const ShaderInfo *)p_shader.id;
5152
5153
VkGraphicsPipelineCreateInfo pipeline_create_info = {};
5154
5155
pipeline_create_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
5156
pipeline_create_info.pNext = graphics_pipeline_nextptr;
5157
pipeline_create_info.stageCount = shader_info->vk_stages_create_info.size();
5158
5159
ERR_FAIL_COND_V_MSG(pipeline_create_info.stageCount == 0, PipelineID(),
5160
"Cannot create pipeline without shader module, please make sure shader modules are destroyed only after all associated pipelines are created.");
5161
VkPipelineShaderStageCreateInfo *vk_pipeline_stages = ALLOCA_ARRAY(VkPipelineShaderStageCreateInfo, shader_info->vk_stages_create_info.size());
5162
5163
for (uint32_t i = 0; i < shader_info->vk_stages_create_info.size(); i++) {
5164
vk_pipeline_stages[i] = shader_info->vk_stages_create_info[i];
5165
5166
if (p_specialization_constants.size()) {
5167
VkSpecializationMapEntry *specialization_map_entries = ALLOCA_ARRAY(VkSpecializationMapEntry, p_specialization_constants.size());
5168
for (uint32_t j = 0; j < p_specialization_constants.size(); j++) {
5169
specialization_map_entries[j] = {};
5170
specialization_map_entries[j].constantID = p_specialization_constants[j].constant_id;
5171
specialization_map_entries[j].offset = (const char *)&p_specialization_constants[j].int_value - (const char *)p_specialization_constants.ptr();
5172
specialization_map_entries[j].size = sizeof(uint32_t);
5173
}
5174
5175
VkSpecializationInfo *specialization_info = ALLOCA_SINGLE(VkSpecializationInfo);
5176
*specialization_info = {};
5177
specialization_info->dataSize = p_specialization_constants.size() * sizeof(PipelineSpecializationConstant);
5178
specialization_info->pData = p_specialization_constants.ptr();
5179
specialization_info->mapEntryCount = p_specialization_constants.size();
5180
specialization_info->pMapEntries = specialization_map_entries;
5181
5182
vk_pipeline_stages[i].pSpecializationInfo = specialization_info;
5183
}
5184
}
5185
5186
const RenderPassInfo *render_pass = (const RenderPassInfo *)(p_render_pass.id);
5187
pipeline_create_info.pStages = vk_pipeline_stages;
5188
pipeline_create_info.pVertexInputState = vertex_input_state_create_info;
5189
pipeline_create_info.pInputAssemblyState = &input_assembly_create_info;
5190
pipeline_create_info.pTessellationState = &tessellation_create_info;
5191
pipeline_create_info.pViewportState = &viewport_state_create_info;
5192
pipeline_create_info.pRasterizationState = &rasterization_state_create_info;
5193
pipeline_create_info.pMultisampleState = &multisample_state_create_info;
5194
pipeline_create_info.pDepthStencilState = &depth_stencil_state_create_info;
5195
pipeline_create_info.pColorBlendState = &color_blend_state_create_info;
5196
pipeline_create_info.pDynamicState = &dynamic_state_create_info;
5197
pipeline_create_info.layout = shader_info->vk_pipeline_layout;
5198
pipeline_create_info.renderPass = render_pass->vk_render_pass;
5199
pipeline_create_info.subpass = p_render_subpass;
5200
5201
// ---
5202
5203
VkPipeline vk_pipeline = VK_NULL_HANDLE;
5204
VkResult err = vkCreateGraphicsPipelines(vk_device, pipelines_cache.vk_cache, 1, &pipeline_create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_PIPELINE), &vk_pipeline);
5205
ERR_FAIL_COND_V_MSG(err, PipelineID(), "vkCreateGraphicsPipelines failed with error " + itos(err) + ".");
5206
5207
return PipelineID(vk_pipeline);
5208
}
5209
5210
/*****************/
5211
/**** COMPUTE ****/
5212
/*****************/
5213
5214
// ----- COMMANDS -----
5215
5216
void RenderingDeviceDriverVulkan::command_bind_compute_pipeline(CommandBufferID p_cmd_buffer, PipelineID p_pipeline) {
5217
const CommandBufferInfo *command_buffer = (const CommandBufferInfo *)p_cmd_buffer.id;
5218
vkCmdBindPipeline(command_buffer->vk_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, (VkPipeline)p_pipeline.id);
5219
}
5220
5221
void RenderingDeviceDriverVulkan::command_bind_compute_uniform_set(CommandBufferID p_cmd_buffer, UniformSetID p_uniform_set, ShaderID p_shader, uint32_t p_set_index) {
5222
const CommandBufferInfo *command_buffer = (const CommandBufferInfo *)p_cmd_buffer.id;
5223
const ShaderInfo *shader_info = (const ShaderInfo *)p_shader.id;
5224
const UniformSetInfo *usi = (const UniformSetInfo *)p_uniform_set.id;
5225
vkCmdBindDescriptorSets(command_buffer->vk_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, shader_info->vk_pipeline_layout, p_set_index, 1, &usi->vk_descriptor_set, 0, nullptr);
5226
}
5227
5228
void RenderingDeviceDriverVulkan::command_bind_compute_uniform_sets(CommandBufferID p_cmd_buffer, VectorView<UniformSetID> p_uniform_sets, ShaderID p_shader, uint32_t p_first_set_index, uint32_t p_set_count) {
5229
if (p_set_count == 0) {
5230
return;
5231
}
5232
5233
thread_local LocalVector<VkDescriptorSet> sets;
5234
sets.clear();
5235
sets.resize(p_set_count);
5236
5237
for (uint32_t i = 0; i < p_set_count; i++) {
5238
sets[i] = ((const UniformSetInfo *)p_uniform_sets[i].id)->vk_descriptor_set;
5239
}
5240
5241
const CommandBufferInfo *command_buffer = (const CommandBufferInfo *)p_cmd_buffer.id;
5242
const ShaderInfo *shader_info = (const ShaderInfo *)p_shader.id;
5243
vkCmdBindDescriptorSets(command_buffer->vk_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, shader_info->vk_pipeline_layout, p_first_set_index, p_set_count, &sets[0], 0, nullptr);
5244
}
5245
5246
void RenderingDeviceDriverVulkan::command_compute_dispatch(CommandBufferID p_cmd_buffer, uint32_t p_x_groups, uint32_t p_y_groups, uint32_t p_z_groups) {
5247
const CommandBufferInfo *command_buffer = (const CommandBufferInfo *)p_cmd_buffer.id;
5248
vkCmdDispatch(command_buffer->vk_command_buffer, p_x_groups, p_y_groups, p_z_groups);
5249
}
5250
5251
void RenderingDeviceDriverVulkan::command_compute_dispatch_indirect(CommandBufferID p_cmd_buffer, BufferID p_indirect_buffer, uint64_t p_offset) {
5252
const CommandBufferInfo *command_buffer = (const CommandBufferInfo *)p_cmd_buffer.id;
5253
const BufferInfo *buf_info = (const BufferInfo *)p_indirect_buffer.id;
5254
vkCmdDispatchIndirect(command_buffer->vk_command_buffer, buf_info->vk_buffer, p_offset);
5255
}
5256
5257
// ----- PIPELINE -----
5258
5259
RDD::PipelineID RenderingDeviceDriverVulkan::compute_pipeline_create(ShaderID p_shader, VectorView<PipelineSpecializationConstant> p_specialization_constants) {
5260
const ShaderInfo *shader_info = (const ShaderInfo *)p_shader.id;
5261
5262
VkComputePipelineCreateInfo pipeline_create_info = {};
5263
pipeline_create_info.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
5264
pipeline_create_info.stage = shader_info->vk_stages_create_info[0];
5265
pipeline_create_info.layout = shader_info->vk_pipeline_layout;
5266
5267
if (p_specialization_constants.size()) {
5268
VkSpecializationMapEntry *specialization_map_entries = ALLOCA_ARRAY(VkSpecializationMapEntry, p_specialization_constants.size());
5269
for (uint32_t i = 0; i < p_specialization_constants.size(); i++) {
5270
specialization_map_entries[i] = {};
5271
specialization_map_entries[i].constantID = p_specialization_constants[i].constant_id;
5272
specialization_map_entries[i].offset = (const char *)&p_specialization_constants[i].int_value - (const char *)p_specialization_constants.ptr();
5273
specialization_map_entries[i].size = sizeof(uint32_t);
5274
}
5275
5276
VkSpecializationInfo *specialization_info = ALLOCA_SINGLE(VkSpecializationInfo);
5277
*specialization_info = {};
5278
specialization_info->dataSize = p_specialization_constants.size() * sizeof(PipelineSpecializationConstant);
5279
specialization_info->pData = p_specialization_constants.ptr();
5280
specialization_info->mapEntryCount = p_specialization_constants.size();
5281
specialization_info->pMapEntries = specialization_map_entries;
5282
5283
pipeline_create_info.stage.pSpecializationInfo = specialization_info;
5284
}
5285
5286
VkPipeline vk_pipeline = VK_NULL_HANDLE;
5287
VkResult err = vkCreateComputePipelines(vk_device, pipelines_cache.vk_cache, 1, &pipeline_create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_PIPELINE), &vk_pipeline);
5288
ERR_FAIL_COND_V_MSG(err, PipelineID(), "vkCreateComputePipelines failed with error " + itos(err) + ".");
5289
5290
return PipelineID(vk_pipeline);
5291
}
5292
5293
/*****************/
5294
/**** QUERIES ****/
5295
/*****************/
5296
5297
// ----- TIMESTAMP -----
5298
5299
RDD::QueryPoolID RenderingDeviceDriverVulkan::timestamp_query_pool_create(uint32_t p_query_count) {
5300
VkQueryPoolCreateInfo query_pool_create_info = {};
5301
query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
5302
query_pool_create_info.queryType = VK_QUERY_TYPE_TIMESTAMP;
5303
query_pool_create_info.queryCount = p_query_count;
5304
5305
VkQueryPool vk_query_pool = VK_NULL_HANDLE;
5306
vkCreateQueryPool(vk_device, &query_pool_create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_QUERY_POOL), &vk_query_pool);
5307
return RDD::QueryPoolID(vk_query_pool);
5308
}
5309
5310
void RenderingDeviceDriverVulkan::timestamp_query_pool_free(QueryPoolID p_pool_id) {
5311
vkDestroyQueryPool(vk_device, (VkQueryPool)p_pool_id.id, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_QUERY_POOL));
5312
}
5313
5314
void RenderingDeviceDriverVulkan::timestamp_query_pool_get_results(QueryPoolID p_pool_id, uint32_t p_query_count, uint64_t *r_results) {
5315
vkGetQueryPoolResults(vk_device, (VkQueryPool)p_pool_id.id, 0, p_query_count, sizeof(uint64_t) * p_query_count, r_results, sizeof(uint64_t), VK_QUERY_RESULT_64_BIT);
5316
}
5317
5318
uint64_t RenderingDeviceDriverVulkan::timestamp_query_result_to_time(uint64_t p_result) {
5319
// This sucks because timestampPeriod multiplier is a float, while the timestamp is 64 bits nanosecs.
5320
// So, in cases like nvidia which give you enormous numbers and 1 as multiplier, multiplying is next to impossible.
5321
// Need to do 128 bits fixed point multiplication to get the right value.
5322
5323
auto mult64to128 = [](uint64_t u, uint64_t v, uint64_t &h, uint64_t &l) {
5324
uint64_t u1 = (u & 0xffffffff);
5325
uint64_t v1 = (v & 0xffffffff);
5326
uint64_t t = (u1 * v1);
5327
uint64_t w3 = (t & 0xffffffff);
5328
uint64_t k = (t >> 32);
5329
5330
u >>= 32;
5331
t = (u * v1) + k;
5332
k = (t & 0xffffffff);
5333
uint64_t w1 = (t >> 32);
5334
5335
v >>= 32;
5336
t = (u1 * v) + k;
5337
k = (t >> 32);
5338
5339
h = (u * v) + w1 + k;
5340
l = (t << 32) + w3;
5341
};
5342
5343
uint64_t shift_bits = 16;
5344
uint64_t h = 0, l = 0;
5345
mult64to128(p_result, uint64_t(double(physical_device_properties.limits.timestampPeriod) * double(1 << shift_bits)), h, l);
5346
l >>= shift_bits;
5347
l |= h << (64 - shift_bits);
5348
5349
return l;
5350
}
5351
5352
void RenderingDeviceDriverVulkan::command_timestamp_query_pool_reset(CommandBufferID p_cmd_buffer, QueryPoolID p_pool_id, uint32_t p_query_count) {
5353
const CommandBufferInfo *command_buffer = (const CommandBufferInfo *)p_cmd_buffer.id;
5354
vkCmdResetQueryPool(command_buffer->vk_command_buffer, (VkQueryPool)p_pool_id.id, 0, p_query_count);
5355
}
5356
5357
void RenderingDeviceDriverVulkan::command_timestamp_write(CommandBufferID p_cmd_buffer, QueryPoolID p_pool_id, uint32_t p_index) {
5358
const CommandBufferInfo *command_buffer = (const CommandBufferInfo *)p_cmd_buffer.id;
5359
vkCmdWriteTimestamp(command_buffer->vk_command_buffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, (VkQueryPool)p_pool_id.id, p_index);
5360
}
5361
5362
/****************/
5363
/**** LABELS ****/
5364
/****************/
5365
5366
void RenderingDeviceDriverVulkan::command_begin_label(CommandBufferID p_cmd_buffer, const char *p_label_name, const Color &p_color) {
5367
const CommandBufferInfo *command_buffer = (const CommandBufferInfo *)p_cmd_buffer.id;
5368
const RenderingContextDriverVulkan::Functions &functions = context_driver->functions_get();
5369
if (!functions.CmdBeginDebugUtilsLabelEXT) {
5370
if (functions.CmdDebugMarkerBeginEXT) {
5371
// Debug marker extensions.
5372
VkDebugMarkerMarkerInfoEXT marker;
5373
marker.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT;
5374
marker.pNext = nullptr;
5375
marker.pMarkerName = p_label_name;
5376
marker.color[0] = p_color[0];
5377
marker.color[1] = p_color[1];
5378
marker.color[2] = p_color[2];
5379
marker.color[3] = p_color[3];
5380
functions.CmdDebugMarkerBeginEXT(command_buffer->vk_command_buffer, &marker);
5381
}
5382
return;
5383
}
5384
VkDebugUtilsLabelEXT label;
5385
label.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT;
5386
label.pNext = nullptr;
5387
label.pLabelName = p_label_name;
5388
label.color[0] = p_color[0];
5389
label.color[1] = p_color[1];
5390
label.color[2] = p_color[2];
5391
label.color[3] = p_color[3];
5392
functions.CmdBeginDebugUtilsLabelEXT(command_buffer->vk_command_buffer, &label);
5393
}
5394
5395
void RenderingDeviceDriverVulkan::command_end_label(CommandBufferID p_cmd_buffer) {
5396
const CommandBufferInfo *command_buffer = (const CommandBufferInfo *)p_cmd_buffer.id;
5397
const RenderingContextDriverVulkan::Functions &functions = context_driver->functions_get();
5398
if (!functions.CmdEndDebugUtilsLabelEXT) {
5399
if (functions.CmdDebugMarkerEndEXT) {
5400
// Debug marker extensions.
5401
functions.CmdDebugMarkerEndEXT(command_buffer->vk_command_buffer);
5402
}
5403
return;
5404
}
5405
functions.CmdEndDebugUtilsLabelEXT(command_buffer->vk_command_buffer);
5406
}
5407
5408
/****************/
5409
/**** DEBUG *****/
5410
/****************/
5411
void RenderingDeviceDriverVulkan::command_insert_breadcrumb(CommandBufferID p_cmd_buffer, uint32_t p_data) {
5412
#if defined(DEBUG_ENABLED) || defined(DEV_ENABLED)
5413
if (p_data == BreadcrumbMarker::NONE) {
5414
return;
5415
}
5416
5417
const CommandBufferInfo *command_buffer = (const CommandBufferInfo *)p_cmd_buffer.id;
5418
if (Engine::get_singleton()->is_accurate_breadcrumbs_enabled()) {
5419
// Force a full barrier so commands are not executed in parallel.
5420
// This will mean that the last breadcrumb to see was actually the
5421
// last (group of) command to be executed (hence, the one causing the crash).
5422
VkMemoryBarrier memoryBarrier;
5423
memoryBarrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
5424
memoryBarrier.pNext = nullptr;
5425
memoryBarrier.srcAccessMask = VK_ACCESS_INDIRECT_COMMAND_READ_BIT |
5426
VK_ACCESS_INDEX_READ_BIT |
5427
VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT |
5428
VK_ACCESS_UNIFORM_READ_BIT |
5429
VK_ACCESS_INPUT_ATTACHMENT_READ_BIT |
5430
VK_ACCESS_SHADER_READ_BIT |
5431
VK_ACCESS_SHADER_WRITE_BIT |
5432
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
5433
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
5434
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
5435
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
5436
VK_ACCESS_TRANSFER_READ_BIT |
5437
VK_ACCESS_TRANSFER_WRITE_BIT |
5438
VK_ACCESS_HOST_READ_BIT |
5439
VK_ACCESS_HOST_WRITE_BIT;
5440
memoryBarrier.dstAccessMask = VK_ACCESS_INDIRECT_COMMAND_READ_BIT |
5441
VK_ACCESS_INDEX_READ_BIT |
5442
VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT |
5443
VK_ACCESS_UNIFORM_READ_BIT |
5444
VK_ACCESS_INPUT_ATTACHMENT_READ_BIT |
5445
VK_ACCESS_SHADER_READ_BIT |
5446
VK_ACCESS_SHADER_WRITE_BIT |
5447
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
5448
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
5449
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
5450
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
5451
VK_ACCESS_TRANSFER_READ_BIT |
5452
VK_ACCESS_TRANSFER_WRITE_BIT |
5453
VK_ACCESS_HOST_READ_BIT |
5454
VK_ACCESS_HOST_WRITE_BIT;
5455
5456
vkCmdPipelineBarrier(
5457
command_buffer->vk_command_buffer,
5458
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
5459
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
5460
0, 1u, &memoryBarrier, 0u, nullptr, 0u, nullptr);
5461
}
5462
5463
// We write to a circular buffer. If you're getting barrier sync errors here,
5464
// increase the value of BREADCRUMB_BUFFER_ENTRIES.
5465
vkCmdFillBuffer(command_buffer->vk_command_buffer, ((BufferInfo *)breadcrumb_buffer.id)->vk_buffer, breadcrumb_offset, sizeof(uint32_t), breadcrumb_id++);
5466
vkCmdFillBuffer(command_buffer->vk_command_buffer, ((BufferInfo *)breadcrumb_buffer.id)->vk_buffer, breadcrumb_offset + sizeof(uint32_t), sizeof(uint32_t), p_data);
5467
breadcrumb_offset += sizeof(uint32_t) * 2u;
5468
if (breadcrumb_offset >= BREADCRUMB_BUFFER_ENTRIES * sizeof(uint32_t) * 2u) {
5469
breadcrumb_offset = 0u;
5470
}
5471
#endif
5472
}
5473
5474
void RenderingDeviceDriverVulkan::on_device_lost() const {
5475
if (device_functions.GetDeviceFaultInfoEXT == nullptr) {
5476
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "VK_EXT_device_fault not available.");
5477
return;
5478
}
5479
5480
VkDeviceFaultCountsEXT fault_counts = {};
5481
fault_counts.sType = VK_STRUCTURE_TYPE_DEVICE_FAULT_COUNTS_EXT;
5482
VkResult vkres = device_functions.GetDeviceFaultInfoEXT(vk_device, &fault_counts, nullptr);
5483
5484
if (vkres != VK_SUCCESS) {
5485
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "vkGetDeviceFaultInfoEXT returned " + itos(vkres) + " when getting fault count, skipping VK_EXT_device_fault report...");
5486
return;
5487
}
5488
5489
String err_msg;
5490
VkDeviceFaultInfoEXT fault_info = {};
5491
fault_info.sType = VK_STRUCTURE_TYPE_DEVICE_FAULT_INFO_EXT;
5492
fault_info.pVendorInfos = fault_counts.vendorInfoCount
5493
? (VkDeviceFaultVendorInfoEXT *)memalloc(fault_counts.vendorInfoCount * sizeof(VkDeviceFaultVendorInfoEXT))
5494
: nullptr;
5495
fault_info.pAddressInfos =
5496
fault_counts.addressInfoCount
5497
? (VkDeviceFaultAddressInfoEXT *)memalloc(fault_counts.addressInfoCount * sizeof(VkDeviceFaultAddressInfoEXT))
5498
: nullptr;
5499
fault_counts.vendorBinarySize = 0;
5500
vkres = device_functions.GetDeviceFaultInfoEXT(vk_device, &fault_counts, &fault_info);
5501
if (vkres != VK_SUCCESS) {
5502
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "vkGetDeviceFaultInfoEXT returned " + itos(vkres) + " when getting fault info, skipping VK_EXT_device_fault report...");
5503
} else {
5504
err_msg += "** Report from VK_EXT_device_fault **";
5505
err_msg += "\nDescription: " + String(fault_info.description);
5506
err_msg += "\nVendor infos:";
5507
for (uint32_t vd = 0; vd < fault_counts.vendorInfoCount; ++vd) {
5508
const VkDeviceFaultVendorInfoEXT *vendor_info = &fault_info.pVendorInfos[vd];
5509
err_msg += "\nInfo " + itos(vd);
5510
err_msg += "\n Description: " + String(vendor_info->description);
5511
err_msg += "\n Fault code : " + itos(vendor_info->vendorFaultCode);
5512
err_msg += "\n Fault data : " + itos(vendor_info->vendorFaultData);
5513
}
5514
5515
static constexpr const char *addressTypeNames[] = {
5516
"NONE",
5517
"READ_INVALID",
5518
"WRITE_INVALID",
5519
"EXECUTE_INVALID",
5520
"INSTRUCTION_POINTER_UNKNOWN",
5521
"INSTRUCTION_POINTER_INVALID",
5522
"INSTRUCTION_POINTER_FAULT",
5523
};
5524
err_msg += "\nAddresses info:";
5525
for (uint32_t ad = 0; ad < fault_counts.addressInfoCount; ++ad) {
5526
const VkDeviceFaultAddressInfoEXT *addr_info = &fault_info.pAddressInfos[ad];
5527
// From https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkDeviceFaultAddressInfoEXT.html
5528
const VkDeviceAddress lower = (addr_info->reportedAddress & ~(addr_info->addressPrecision - 1));
5529
const VkDeviceAddress upper = (addr_info->reportedAddress | (addr_info->addressPrecision - 1));
5530
err_msg += "\nInfo " + itos(ad);
5531
err_msg += "\n Type : " + String(addressTypeNames[addr_info->addressType]);
5532
err_msg += "\n Reported address: " + itos(addr_info->reportedAddress);
5533
err_msg += "\n Lower address : " + itos(lower);
5534
err_msg += "\n Upper address : " + itos(upper);
5535
err_msg += "\n Precision : " + itos(addr_info->addressPrecision);
5536
}
5537
}
5538
5539
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, err_msg);
5540
5541
if (fault_info.pVendorInfos) {
5542
memfree(fault_info.pVendorInfos);
5543
}
5544
if (fault_info.pAddressInfos) {
5545
memfree(fault_info.pAddressInfos);
5546
}
5547
5548
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, context_driver->get_driver_and_device_memory_report());
5549
}
5550
5551
void RenderingDeviceDriverVulkan::print_lost_device_info() {
5552
#if defined(DEBUG_ENABLED) || defined(DEV_ENABLED)
5553
{
5554
String error_msg = "Printing last known breadcrumbs in reverse order (last executed first).";
5555
if (!Engine::get_singleton()->is_accurate_breadcrumbs_enabled()) {
5556
error_msg += "\nSome of them might be inaccurate. Try running with --accurate-breadcrumbs for precise information.";
5557
}
5558
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, error_msg);
5559
}
5560
5561
uint8_t *breadcrumb_ptr = nullptr;
5562
VkResult map_result = VK_SUCCESS;
5563
5564
vmaFlushAllocation(allocator, ((BufferInfo *)breadcrumb_buffer.id)->allocation.handle, 0, BREADCRUMB_BUFFER_ENTRIES * sizeof(uint32_t) * 2u);
5565
vmaInvalidateAllocation(allocator, ((BufferInfo *)breadcrumb_buffer.id)->allocation.handle, 0, BREADCRUMB_BUFFER_ENTRIES * sizeof(uint32_t) * 2u);
5566
{
5567
void *ptr = nullptr;
5568
map_result = vmaMapMemory(allocator, ((BufferInfo *)breadcrumb_buffer.id)->allocation.handle, &ptr);
5569
breadcrumb_ptr = reinterpret_cast<uint8_t *>(ptr);
5570
}
5571
5572
if (breadcrumb_ptr && map_result == VK_SUCCESS) {
5573
uint32_t last_breadcrumb_offset = 0;
5574
{
5575
_err_print_error_asap("Searching last breadcrumb. We've sent up to ID: " + itos(breadcrumb_id - 1u));
5576
5577
// Scan the whole buffer to find the offset with the highest ID.
5578
// That means that was the last one to be written.
5579
//
5580
// We use "breadcrumb_id - id" to account for wraparound.
5581
// e.g. breadcrumb_id = 2 and id = 4294967294; then 2 - 4294967294 = 4.
5582
// The one with the smallest difference is the closest to breadcrumb_id, which means it's
5583
// the last written command.
5584
uint32_t biggest_id = 0u;
5585
uint32_t smallest_id_diff = std::numeric_limits<uint32_t>::max();
5586
const uint32_t *breadcrumb_ptr32 = reinterpret_cast<const uint32_t *>(breadcrumb_ptr);
5587
for (size_t i = 0u; i < BREADCRUMB_BUFFER_ENTRIES; ++i) {
5588
const uint32_t id = breadcrumb_ptr32[i * 2u];
5589
const uint32_t id_diff = breadcrumb_id - id;
5590
if (id_diff < smallest_id_diff) {
5591
biggest_id = i;
5592
smallest_id_diff = id_diff;
5593
}
5594
}
5595
5596
_err_print_error_asap("Last breadcrumb ID found: " + itos(breadcrumb_ptr32[biggest_id * 2u]));
5597
5598
last_breadcrumb_offset = biggest_id * sizeof(uint32_t) * 2u;
5599
}
5600
5601
const size_t entries_to_print = 8u; // Note: The value is arbitrary.
5602
for (size_t i = 0u; i < entries_to_print; ++i) {
5603
const uint32_t last_breadcrumb = *reinterpret_cast<uint32_t *>(breadcrumb_ptr + last_breadcrumb_offset + sizeof(uint32_t));
5604
const uint32_t phase = last_breadcrumb & uint32_t(~((1 << 16) - 1));
5605
const uint32_t user_data = last_breadcrumb & ((1 << 16) - 1);
5606
String error_msg = "Last known breadcrumb: ";
5607
5608
switch (phase) {
5609
case BreadcrumbMarker::ALPHA_PASS:
5610
error_msg += "ALPHA_PASS";
5611
break;
5612
case BreadcrumbMarker::BLIT_PASS:
5613
error_msg += "BLIT_PASS";
5614
break;
5615
case BreadcrumbMarker::DEBUG_PASS:
5616
error_msg += "DEBUG_PASS";
5617
break;
5618
case BreadcrumbMarker::LIGHTMAPPER_PASS:
5619
error_msg += "LIGHTMAPPER_PASS";
5620
break;
5621
case BreadcrumbMarker::OPAQUE_PASS:
5622
error_msg += "OPAQUE_PASS";
5623
break;
5624
case BreadcrumbMarker::POST_PROCESSING_PASS:
5625
error_msg += "POST_PROCESSING_PASS";
5626
break;
5627
case BreadcrumbMarker::REFLECTION_PROBES:
5628
error_msg += "REFLECTION_PROBES";
5629
break;
5630
case BreadcrumbMarker::SHADOW_PASS_CUBE:
5631
error_msg += "SHADOW_PASS_CUBE";
5632
break;
5633
case BreadcrumbMarker::SHADOW_PASS_DIRECTIONAL:
5634
error_msg += "SHADOW_PASS_DIRECTIONAL";
5635
break;
5636
case BreadcrumbMarker::SKY_PASS:
5637
error_msg += "SKY_PASS";
5638
break;
5639
case BreadcrumbMarker::TRANSPARENT_PASS:
5640
error_msg += "TRANSPARENT_PASS";
5641
break;
5642
case BreadcrumbMarker::UI_PASS:
5643
error_msg += "UI_PASS";
5644
break;
5645
default:
5646
error_msg += "UNKNOWN_BREADCRUMB(" + itos((uint32_t)phase) + ')';
5647
break;
5648
}
5649
5650
if (user_data != 0) {
5651
error_msg += " | User data: " + itos(user_data);
5652
}
5653
5654
_err_print_error_asap(error_msg);
5655
5656
if (last_breadcrumb_offset == 0u) {
5657
// Decrement last_breadcrumb_idx, wrapping underflow.
5658
last_breadcrumb_offset = BREADCRUMB_BUFFER_ENTRIES * sizeof(uint32_t) * 2u;
5659
}
5660
last_breadcrumb_offset -= sizeof(uint32_t) * 2u;
5661
}
5662
5663
vmaUnmapMemory(allocator, ((BufferInfo *)breadcrumb_buffer.id)->allocation.handle);
5664
breadcrumb_ptr = nullptr;
5665
} else {
5666
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Couldn't map breadcrumb buffer. VkResult = " + itos(map_result));
5667
}
5668
#endif
5669
on_device_lost();
5670
}
5671
5672
inline String RenderingDeviceDriverVulkan::get_vulkan_result(VkResult err) {
5673
#if defined(DEBUG_ENABLED) || defined(DEV_ENABLED)
5674
if (err == VK_ERROR_OUT_OF_HOST_MEMORY) {
5675
return "VK_ERROR_OUT_OF_HOST_MEMORY";
5676
} else if (err == VK_ERROR_OUT_OF_DEVICE_MEMORY) {
5677
return "VK_ERROR_OUT_OF_DEVICE_MEMORY";
5678
} else if (err == VK_ERROR_DEVICE_LOST) {
5679
return "VK_ERROR_DEVICE_LOST";
5680
} else if (err == VK_ERROR_SURFACE_LOST_KHR) {
5681
return "VK_ERROR_SURFACE_LOST_KHR";
5682
} else if (err == VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT) {
5683
return "VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT";
5684
}
5685
#endif
5686
return itos(err);
5687
}
5688
5689
/********************/
5690
/**** SUBMISSION ****/
5691
/********************/
5692
5693
void RenderingDeviceDriverVulkan::begin_segment(uint32_t p_frame_index, uint32_t p_frames_drawn) {
5694
// Per-frame segments are not required in Vulkan.
5695
}
5696
5697
void RenderingDeviceDriverVulkan::end_segment() {
5698
// Per-frame segments are not required in Vulkan.
5699
}
5700
5701
/**************/
5702
/**** MISC ****/
5703
/**************/
5704
5705
void RenderingDeviceDriverVulkan::set_object_name(ObjectType p_type, ID p_driver_id, const String &p_name) {
5706
switch (p_type) {
5707
case OBJECT_TYPE_TEXTURE: {
5708
const TextureInfo *tex_info = (const TextureInfo *)p_driver_id.id;
5709
if (tex_info->allocation.handle) {
5710
_set_object_name(VK_OBJECT_TYPE_IMAGE, (uint64_t)tex_info->vk_view_create_info.image, p_name);
5711
}
5712
_set_object_name(VK_OBJECT_TYPE_IMAGE_VIEW, (uint64_t)tex_info->vk_view, p_name + " View");
5713
} break;
5714
case OBJECT_TYPE_SAMPLER: {
5715
_set_object_name(VK_OBJECT_TYPE_SAMPLER, p_driver_id.id, p_name);
5716
} break;
5717
case OBJECT_TYPE_BUFFER: {
5718
const BufferInfo *buf_info = (const BufferInfo *)p_driver_id.id;
5719
_set_object_name(VK_OBJECT_TYPE_BUFFER, (uint64_t)buf_info->vk_buffer, p_name);
5720
if (buf_info->vk_view) {
5721
_set_object_name(VK_OBJECT_TYPE_BUFFER_VIEW, (uint64_t)buf_info->vk_view, p_name + " View");
5722
}
5723
} break;
5724
case OBJECT_TYPE_SHADER: {
5725
const ShaderInfo *shader_info = (const ShaderInfo *)p_driver_id.id;
5726
for (uint32_t i = 0; i < shader_info->vk_descriptor_set_layouts.size(); i++) {
5727
_set_object_name(VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, (uint64_t)shader_info->vk_descriptor_set_layouts[i], p_name);
5728
}
5729
_set_object_name(VK_OBJECT_TYPE_PIPELINE_LAYOUT, (uint64_t)shader_info->vk_pipeline_layout, p_name + " Pipeline Layout");
5730
} break;
5731
case OBJECT_TYPE_UNIFORM_SET: {
5732
const UniformSetInfo *usi = (const UniformSetInfo *)p_driver_id.id;
5733
_set_object_name(VK_OBJECT_TYPE_DESCRIPTOR_SET, (uint64_t)usi->vk_descriptor_set, p_name);
5734
} break;
5735
case OBJECT_TYPE_PIPELINE: {
5736
_set_object_name(VK_OBJECT_TYPE_PIPELINE, (uint64_t)p_driver_id.id, p_name);
5737
} break;
5738
default: {
5739
DEV_ASSERT(false);
5740
}
5741
}
5742
}
5743
5744
uint64_t RenderingDeviceDriverVulkan::get_resource_native_handle(DriverResource p_type, ID p_driver_id) {
5745
switch (p_type) {
5746
case DRIVER_RESOURCE_LOGICAL_DEVICE: {
5747
return (uint64_t)vk_device;
5748
}
5749
case DRIVER_RESOURCE_PHYSICAL_DEVICE: {
5750
return (uint64_t)physical_device;
5751
}
5752
case DRIVER_RESOURCE_TOPMOST_OBJECT: {
5753
return (uint64_t)context_driver->instance_get();
5754
}
5755
case DRIVER_RESOURCE_COMMAND_QUEUE: {
5756
const CommandQueue *queue_info = (const CommandQueue *)p_driver_id.id;
5757
return (uint64_t)queue_families[queue_info->queue_family][queue_info->queue_index].queue;
5758
}
5759
case DRIVER_RESOURCE_QUEUE_FAMILY: {
5760
return uint32_t(p_driver_id.id) - 1;
5761
}
5762
case DRIVER_RESOURCE_TEXTURE: {
5763
const TextureInfo *tex_info = (const TextureInfo *)p_driver_id.id;
5764
return (uint64_t)tex_info->vk_view_create_info.image;
5765
}
5766
case DRIVER_RESOURCE_TEXTURE_VIEW: {
5767
const TextureInfo *tex_info = (const TextureInfo *)p_driver_id.id;
5768
return (uint64_t)tex_info->vk_view;
5769
}
5770
case DRIVER_RESOURCE_TEXTURE_DATA_FORMAT: {
5771
const TextureInfo *tex_info = (const TextureInfo *)p_driver_id.id;
5772
return (uint64_t)tex_info->vk_view_create_info.format;
5773
}
5774
case DRIVER_RESOURCE_SAMPLER:
5775
case DRIVER_RESOURCE_UNIFORM_SET:
5776
case DRIVER_RESOURCE_BUFFER:
5777
case DRIVER_RESOURCE_COMPUTE_PIPELINE:
5778
case DRIVER_RESOURCE_RENDER_PIPELINE: {
5779
return p_driver_id.id;
5780
}
5781
default: {
5782
return 0;
5783
}
5784
}
5785
}
5786
5787
uint64_t RenderingDeviceDriverVulkan::get_total_memory_used() {
5788
VmaTotalStatistics stats = {};
5789
vmaCalculateStatistics(allocator, &stats);
5790
return stats.total.statistics.allocationBytes;
5791
}
5792
5793
uint64_t RenderingDeviceDriverVulkan::get_lazily_memory_used() {
5794
return vmaCalculateLazilyAllocatedBytes(allocator);
5795
}
5796
5797
uint64_t RenderingDeviceDriverVulkan::limit_get(Limit p_limit) {
5798
const VkPhysicalDeviceLimits &limits = physical_device_properties.limits;
5799
uint64_t safe_unbounded = ((uint64_t)1 << 30);
5800
switch (p_limit) {
5801
case LIMIT_MAX_BOUND_UNIFORM_SETS:
5802
return limits.maxBoundDescriptorSets;
5803
case LIMIT_MAX_FRAMEBUFFER_COLOR_ATTACHMENTS:
5804
return limits.maxColorAttachments;
5805
case LIMIT_MAX_TEXTURES_PER_UNIFORM_SET:
5806
return limits.maxDescriptorSetSampledImages;
5807
case LIMIT_MAX_SAMPLERS_PER_UNIFORM_SET:
5808
return limits.maxDescriptorSetSamplers;
5809
case LIMIT_MAX_STORAGE_BUFFERS_PER_UNIFORM_SET:
5810
return limits.maxDescriptorSetStorageBuffers;
5811
case LIMIT_MAX_STORAGE_IMAGES_PER_UNIFORM_SET:
5812
return limits.maxDescriptorSetStorageImages;
5813
case LIMIT_MAX_UNIFORM_BUFFERS_PER_UNIFORM_SET:
5814
return limits.maxDescriptorSetUniformBuffers;
5815
case LIMIT_MAX_DRAW_INDEXED_INDEX:
5816
return limits.maxDrawIndexedIndexValue;
5817
case LIMIT_MAX_FRAMEBUFFER_HEIGHT:
5818
return limits.maxFramebufferHeight;
5819
case LIMIT_MAX_FRAMEBUFFER_WIDTH:
5820
return limits.maxFramebufferWidth;
5821
case LIMIT_MAX_TEXTURE_ARRAY_LAYERS:
5822
return limits.maxImageArrayLayers;
5823
case LIMIT_MAX_TEXTURE_SIZE_1D:
5824
return limits.maxImageDimension1D;
5825
case LIMIT_MAX_TEXTURE_SIZE_2D:
5826
return limits.maxImageDimension2D;
5827
case LIMIT_MAX_TEXTURE_SIZE_3D:
5828
return limits.maxImageDimension3D;
5829
case LIMIT_MAX_TEXTURE_SIZE_CUBE:
5830
return limits.maxImageDimensionCube;
5831
case LIMIT_MAX_TEXTURES_PER_SHADER_STAGE:
5832
return limits.maxPerStageDescriptorSampledImages;
5833
case LIMIT_MAX_SAMPLERS_PER_SHADER_STAGE:
5834
return limits.maxPerStageDescriptorSamplers;
5835
case LIMIT_MAX_STORAGE_BUFFERS_PER_SHADER_STAGE:
5836
return limits.maxPerStageDescriptorStorageBuffers;
5837
case LIMIT_MAX_STORAGE_IMAGES_PER_SHADER_STAGE:
5838
return limits.maxPerStageDescriptorStorageImages;
5839
case LIMIT_MAX_UNIFORM_BUFFERS_PER_SHADER_STAGE:
5840
return limits.maxPerStageDescriptorUniformBuffers;
5841
case LIMIT_MAX_PUSH_CONSTANT_SIZE:
5842
return limits.maxPushConstantsSize;
5843
case LIMIT_MAX_UNIFORM_BUFFER_SIZE:
5844
return limits.maxUniformBufferRange;
5845
case LIMIT_MAX_VERTEX_INPUT_ATTRIBUTE_OFFSET:
5846
return limits.maxVertexInputAttributeOffset;
5847
case LIMIT_MAX_VERTEX_INPUT_ATTRIBUTES:
5848
return limits.maxVertexInputAttributes;
5849
case LIMIT_MAX_VERTEX_INPUT_BINDINGS:
5850
return limits.maxVertexInputBindings;
5851
case LIMIT_MAX_VERTEX_INPUT_BINDING_STRIDE:
5852
return limits.maxVertexInputBindingStride;
5853
case LIMIT_MIN_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
5854
return limits.minUniformBufferOffsetAlignment;
5855
case LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_X:
5856
return limits.maxComputeWorkGroupCount[0];
5857
case LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_Y:
5858
return limits.maxComputeWorkGroupCount[1];
5859
case LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_Z:
5860
return limits.maxComputeWorkGroupCount[2];
5861
case LIMIT_MAX_COMPUTE_WORKGROUP_INVOCATIONS:
5862
return limits.maxComputeWorkGroupInvocations;
5863
case LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_X:
5864
return limits.maxComputeWorkGroupSize[0];
5865
case LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Y:
5866
return limits.maxComputeWorkGroupSize[1];
5867
case LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Z:
5868
return limits.maxComputeWorkGroupSize[2];
5869
case LIMIT_MAX_COMPUTE_SHARED_MEMORY_SIZE:
5870
return limits.maxComputeSharedMemorySize;
5871
case LIMIT_MAX_VIEWPORT_DIMENSIONS_X:
5872
return limits.maxViewportDimensions[0];
5873
case LIMIT_MAX_VIEWPORT_DIMENSIONS_Y:
5874
return limits.maxViewportDimensions[1];
5875
case LIMIT_SUBGROUP_SIZE:
5876
return subgroup_capabilities.size;
5877
case LIMIT_SUBGROUP_MIN_SIZE:
5878
return subgroup_capabilities.min_size;
5879
case LIMIT_SUBGROUP_MAX_SIZE:
5880
return subgroup_capabilities.max_size;
5881
case LIMIT_SUBGROUP_IN_SHADERS:
5882
return subgroup_capabilities.supported_stages_flags_rd();
5883
case LIMIT_SUBGROUP_OPERATIONS:
5884
return subgroup_capabilities.supported_operations_flags_rd();
5885
case LIMIT_MAX_SHADER_VARYINGS:
5886
// The Vulkan spec states that built in varyings like gl_FragCoord should count against this, but in
5887
// practice, that doesn't seem to be the case. The validation layers don't even complain.
5888
return MIN(limits.maxVertexOutputComponents / 4, limits.maxFragmentInputComponents / 4);
5889
default: {
5890
#ifdef DEV_ENABLED
5891
WARN_PRINT("Returning maximum value for unknown limit " + itos(p_limit) + ".");
5892
#endif
5893
return safe_unbounded;
5894
}
5895
}
5896
}
5897
5898
uint64_t RenderingDeviceDriverVulkan::api_trait_get(ApiTrait p_trait) {
5899
switch (p_trait) {
5900
case API_TRAIT_TEXTURE_TRANSFER_ALIGNMENT:
5901
return (uint64_t)MAX((uint64_t)16, physical_device_properties.limits.optimalBufferCopyOffsetAlignment);
5902
case API_TRAIT_SHADER_CHANGE_INVALIDATION:
5903
return (uint64_t)SHADER_CHANGE_INVALIDATION_INCOMPATIBLE_SETS_PLUS_CASCADE;
5904
default:
5905
return RenderingDeviceDriver::api_trait_get(p_trait);
5906
}
5907
}
5908
5909
bool RenderingDeviceDriverVulkan::has_feature(Features p_feature) {
5910
switch (p_feature) {
5911
case SUPPORTS_HALF_FLOAT:
5912
return shader_capabilities.shader_float16_is_supported && physical_device_features.shaderInt16 && storage_buffer_capabilities.storage_buffer_16_bit_access_is_supported;
5913
case SUPPORTS_FRAGMENT_SHADER_WITH_ONLY_SIDE_EFFECTS:
5914
return true;
5915
case SUPPORTS_BUFFER_DEVICE_ADDRESS:
5916
return buffer_device_address_support;
5917
case SUPPORTS_IMAGE_ATOMIC_32_BIT:
5918
#if (defined(MACOS_ENABLED) || defined(APPLE_EMBEDDED_ENABLED))
5919
// MoltenVK has previously had issues with 32-bit atomics on images.
5920
return false;
5921
#else
5922
return true;
5923
#endif
5924
case SUPPORTS_VULKAN_MEMORY_MODEL:
5925
return vulkan_memory_model_support && vulkan_memory_model_device_scope_support;
5926
default:
5927
return false;
5928
}
5929
}
5930
5931
const RDD::MultiviewCapabilities &RenderingDeviceDriverVulkan::get_multiview_capabilities() {
5932
return multiview_capabilities;
5933
}
5934
5935
const RDD::FragmentShadingRateCapabilities &RenderingDeviceDriverVulkan::get_fragment_shading_rate_capabilities() {
5936
return fsr_capabilities;
5937
}
5938
5939
const RDD::FragmentDensityMapCapabilities &RenderingDeviceDriverVulkan::get_fragment_density_map_capabilities() {
5940
return fdm_capabilities;
5941
}
5942
5943
String RenderingDeviceDriverVulkan::get_api_name() const {
5944
return "Vulkan";
5945
}
5946
5947
String RenderingDeviceDriverVulkan::get_api_version() const {
5948
uint32_t api_version = physical_device_properties.apiVersion;
5949
return vformat("%d.%d.%d", VK_API_VERSION_MAJOR(api_version), VK_API_VERSION_MINOR(api_version), VK_API_VERSION_PATCH(api_version));
5950
}
5951
5952
String RenderingDeviceDriverVulkan::get_pipeline_cache_uuid() const {
5953
return pipeline_cache_id;
5954
}
5955
5956
const RDD::Capabilities &RenderingDeviceDriverVulkan::get_capabilities() const {
5957
return device_capabilities;
5958
}
5959
5960
const RenderingShaderContainerFormat &RenderingDeviceDriverVulkan::get_shader_container_format() const {
5961
return shader_container_format;
5962
}
5963
5964
bool RenderingDeviceDriverVulkan::is_composite_alpha_supported(CommandQueueID p_queue) const {
5965
if (has_comp_alpha.has((uint64_t)p_queue.id)) {
5966
return has_comp_alpha[(uint64_t)p_queue.id];
5967
}
5968
return false;
5969
}
5970
5971
/******************/
5972
5973
RenderingDeviceDriverVulkan::RenderingDeviceDriverVulkan(RenderingContextDriverVulkan *p_context_driver) {
5974
DEV_ASSERT(p_context_driver != nullptr);
5975
5976
context_driver = p_context_driver;
5977
max_descriptor_sets_per_pool = GLOBAL_GET("rendering/rendering_device/vulkan/max_descriptors_per_pool");
5978
}
5979
5980
RenderingDeviceDriverVulkan::~RenderingDeviceDriverVulkan() {
5981
#if defined(DEBUG_ENABLED) || defined(DEV_ENABLED)
5982
buffer_free(breadcrumb_buffer);
5983
#endif
5984
5985
while (small_allocs_pools.size()) {
5986
HashMap<uint32_t, VmaPool>::Iterator E = small_allocs_pools.begin();
5987
vmaDestroyPool(allocator, E->value);
5988
small_allocs_pools.remove(E);
5989
}
5990
vmaDestroyAllocator(allocator);
5991
5992
// Destroy linearly allocated descriptor pools.
5993
for (KeyValue<int, DescriptorSetPools> &pool_map : linear_descriptor_set_pools) {
5994
for (KeyValue<DescriptorSetPoolKey, HashMap<VkDescriptorPool, uint32_t>> pools : pool_map.value) {
5995
for (KeyValue<VkDescriptorPool, uint32_t> descriptor_pool : pools.value) {
5996
vkDestroyDescriptorPool(vk_device, descriptor_pool.key, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_DESCRIPTOR_POOL));
5997
}
5998
}
5999
}
6000
6001
if (vk_device != VK_NULL_HANDLE) {
6002
vkDestroyDevice(vk_device, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_DEVICE));
6003
}
6004
}
6005
6006