Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/servers/rendering/rendering_device_commons.cpp
10277 views
1
/**************************************************************************/
2
/* rendering_device_commons.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_commons.h"
32
33
#include "thirdparty/spirv-reflect/spirv_reflect.h"
34
35
/*****************/
36
/**** GENERIC ****/
37
/*****************/
38
39
const char *const RenderingDeviceCommons::FORMAT_NAMES[DATA_FORMAT_MAX] = {
40
"R4G4_Unorm_Pack8",
41
"R4G4B4A4_Unorm_Pack16",
42
"B4G4R4A4_Unorm_Pack16",
43
"R5G6B5_Unorm_Pack16",
44
"B5G6R5_Unorm_Pack16",
45
"R5G5B5A1_Unorm_Pack16",
46
"B5G5R5A1_Unorm_Pack16",
47
"A1R5G5B5_Unorm_Pack16",
48
"R8_Unorm",
49
"R8_Snorm",
50
"R8_Uscaled",
51
"R8_Sscaled",
52
"R8_Uint",
53
"R8_Sint",
54
"R8_Srgb",
55
"R8G8_Unorm",
56
"R8G8_Snorm",
57
"R8G8_Uscaled",
58
"R8G8_Sscaled",
59
"R8G8_Uint",
60
"R8G8_Sint",
61
"R8G8_Srgb",
62
"R8G8B8_Unorm",
63
"R8G8B8_Snorm",
64
"R8G8B8_Uscaled",
65
"R8G8B8_Sscaled",
66
"R8G8B8_Uint",
67
"R8G8B8_Sint",
68
"R8G8B8_Srgb",
69
"B8G8R8_Unorm",
70
"B8G8R8_Snorm",
71
"B8G8R8_Uscaled",
72
"B8G8R8_Sscaled",
73
"B8G8R8_Uint",
74
"B8G8R8_Sint",
75
"B8G8R8_Srgb",
76
"R8G8B8A8_Unorm",
77
"R8G8B8A8_Snorm",
78
"R8G8B8A8_Uscaled",
79
"R8G8B8A8_Sscaled",
80
"R8G8B8A8_Uint",
81
"R8G8B8A8_Sint",
82
"R8G8B8A8_Srgb",
83
"B8G8R8A8_Unorm",
84
"B8G8R8A8_Snorm",
85
"B8G8R8A8_Uscaled",
86
"B8G8R8A8_Sscaled",
87
"B8G8R8A8_Uint",
88
"B8G8R8A8_Sint",
89
"B8G8R8A8_Srgb",
90
"A8B8G8R8_Unorm_Pack32",
91
"A8B8G8R8_Snorm_Pack32",
92
"A8B8G8R8_Uscaled_Pack32",
93
"A8B8G8R8_Sscaled_Pack32",
94
"A8B8G8R8_Uint_Pack32",
95
"A8B8G8R8_Sint_Pack32",
96
"A8B8G8R8_Srgb_Pack32",
97
"A2R10G10B10_Unorm_Pack32",
98
"A2R10G10B10_Snorm_Pack32",
99
"A2R10G10B10_Uscaled_Pack32",
100
"A2R10G10B10_Sscaled_Pack32",
101
"A2R10G10B10_Uint_Pack32",
102
"A2R10G10B10_Sint_Pack32",
103
"A2B10G10R10_Unorm_Pack32",
104
"A2B10G10R10_Snorm_Pack32",
105
"A2B10G10R10_Uscaled_Pack32",
106
"A2B10G10R10_Sscaled_Pack32",
107
"A2B10G10R10_Uint_Pack32",
108
"A2B10G10R10_Sint_Pack32",
109
"R16_Unorm",
110
"R16_Snorm",
111
"R16_Uscaled",
112
"R16_Sscaled",
113
"R16_Uint",
114
"R16_Sint",
115
"R16_Sfloat",
116
"R16G16_Unorm",
117
"R16G16_Snorm",
118
"R16G16_Uscaled",
119
"R16G16_Sscaled",
120
"R16G16_Uint",
121
"R16G16_Sint",
122
"R16G16_Sfloat",
123
"R16G16B16_Unorm",
124
"R16G16B16_Snorm",
125
"R16G16B16_Uscaled",
126
"R16G16B16_Sscaled",
127
"R16G16B16_Uint",
128
"R16G16B16_Sint",
129
"R16G16B16_Sfloat",
130
"R16G16B16A16_Unorm",
131
"R16G16B16A16_Snorm",
132
"R16G16B16A16_Uscaled",
133
"R16G16B16A16_Sscaled",
134
"R16G16B16A16_Uint",
135
"R16G16B16A16_Sint",
136
"R16G16B16A16_Sfloat",
137
"R32_Uint",
138
"R32_Sint",
139
"R32_Sfloat",
140
"R32G32_Uint",
141
"R32G32_Sint",
142
"R32G32_Sfloat",
143
"R32G32B32_Uint",
144
"R32G32B32_Sint",
145
"R32G32B32_Sfloat",
146
"R32G32B32A32_Uint",
147
"R32G32B32A32_Sint",
148
"R32G32B32A32_Sfloat",
149
"R64_Uint",
150
"R64_Sint",
151
"R64_Sfloat",
152
"R64G64_Uint",
153
"R64G64_Sint",
154
"R64G64_Sfloat",
155
"R64G64B64_Uint",
156
"R64G64B64_Sint",
157
"R64G64B64_Sfloat",
158
"R64G64B64A64_Uint",
159
"R64G64B64A64_Sint",
160
"R64G64B64A64_Sfloat",
161
"B10G11R11_Ufloat_Pack32",
162
"E5B9G9R9_Ufloat_Pack32",
163
"D16_Unorm",
164
"X8_D24_Unorm_Pack32",
165
"D32_Sfloat",
166
"S8_Uint",
167
"D16_Unorm_S8_Uint",
168
"D24_Unorm_S8_Uint",
169
"D32_Sfloat_S8_Uint",
170
"Bc1_Rgb_Unorm_Block",
171
"Bc1_Rgb_Srgb_Block",
172
"Bc1_Rgba_Unorm_Block",
173
"Bc1_Rgba_Srgb_Block",
174
"Bc2_Unorm_Block",
175
"Bc2_Srgb_Block",
176
"Bc3_Unorm_Block",
177
"Bc3_Srgb_Block",
178
"Bc4_Unorm_Block",
179
"Bc4_Snorm_Block",
180
"Bc5_Unorm_Block",
181
"Bc5_Snorm_Block",
182
"Bc6H_Ufloat_Block",
183
"Bc6H_Sfloat_Block",
184
"Bc7_Unorm_Block",
185
"Bc7_Srgb_Block",
186
"Etc2_R8G8B8_Unorm_Block",
187
"Etc2_R8G8B8_Srgb_Block",
188
"Etc2_R8G8B8A1_Unorm_Block",
189
"Etc2_R8G8B8A1_Srgb_Block",
190
"Etc2_R8G8B8A8_Unorm_Block",
191
"Etc2_R8G8B8A8_Srgb_Block",
192
"Eac_R11_Unorm_Block",
193
"Eac_R11_Snorm_Block",
194
"Eac_R11G11_Unorm_Block",
195
"Eac_R11G11_Snorm_Block",
196
"Astc_4X4_Unorm_Block",
197
"Astc_4X4_Srgb_Block",
198
"Astc_5X4_Unorm_Block",
199
"Astc_5X4_Srgb_Block",
200
"Astc_5X5_Unorm_Block",
201
"Astc_5X5_Srgb_Block",
202
"Astc_6X5_Unorm_Block",
203
"Astc_6X5_Srgb_Block",
204
"Astc_6X6_Unorm_Block",
205
"Astc_6X6_Srgb_Block",
206
"Astc_8X5_Unorm_Block",
207
"Astc_8X5_Srgb_Block",
208
"Astc_8X6_Unorm_Block",
209
"Astc_8X6_Srgb_Block",
210
"Astc_8X8_Unorm_Block",
211
"Astc_8X8_Srgb_Block",
212
"Astc_10X5_Unorm_Block",
213
"Astc_10X5_Srgb_Block",
214
"Astc_10X6_Unorm_Block",
215
"Astc_10X6_Srgb_Block",
216
"Astc_10X8_Unorm_Block",
217
"Astc_10X8_Srgb_Block",
218
"Astc_10X10_Unorm_Block",
219
"Astc_10X10_Srgb_Block",
220
"Astc_12X10_Unorm_Block",
221
"Astc_12X10_Srgb_Block",
222
"Astc_12X12_Unorm_Block",
223
"Astc_12X12_Srgb_Block",
224
"G8B8G8R8_422_Unorm",
225
"B8G8R8G8_422_Unorm",
226
"G8_B8_R8_3Plane_420_Unorm",
227
"G8_B8R8_2Plane_420_Unorm",
228
"G8_B8_R8_3Plane_422_Unorm",
229
"G8_B8R8_2Plane_422_Unorm",
230
"G8_B8_R8_3Plane_444_Unorm",
231
"R10X6_Unorm_Pack16",
232
"R10X6G10X6_Unorm_2Pack16",
233
"R10X6G10X6B10X6A10X6_Unorm_4Pack16",
234
"G10X6B10X6G10X6R10X6_422_Unorm_4Pack16",
235
"B10X6G10X6R10X6G10X6_422_Unorm_4Pack16",
236
"G10X6_B10X6_R10X6_3Plane_420_Unorm_3Pack16",
237
"G10X6_B10X6R10X6_2Plane_420_Unorm_3Pack16",
238
"G10X6_B10X6_R10X6_3Plane_422_Unorm_3Pack16",
239
"G10X6_B10X6R10X6_2Plane_422_Unorm_3Pack16",
240
"G10X6_B10X6_R10X6_3Plane_444_Unorm_3Pack16",
241
"R12X4_Unorm_Pack16",
242
"R12X4G12X4_Unorm_2Pack16",
243
"R12X4G12X4B12X4A12X4_Unorm_4Pack16",
244
"G12X4B12X4G12X4R12X4_422_Unorm_4Pack16",
245
"B12X4G12X4R12X4G12X4_422_Unorm_4Pack16",
246
"G12X4_B12X4_R12X4_3Plane_420_Unorm_3Pack16",
247
"G12X4_B12X4R12X4_2Plane_420_Unorm_3Pack16",
248
"G12X4_B12X4_R12X4_3Plane_422_Unorm_3Pack16",
249
"G12X4_B12X4R12X4_2Plane_422_Unorm_3Pack16",
250
"G12X4_B12X4_R12X4_3Plane_444_Unorm_3Pack16",
251
"G16B16G16R16_422_Unorm",
252
"B16G16R16G16_422_Unorm",
253
"G16_B16_R16_3Plane_420_Unorm",
254
"G16_B16R16_2Plane_420_Unorm",
255
"G16_B16_R16_3Plane_422_Unorm",
256
"G16_B16R16_2Plane_422_Unorm",
257
"G16_B16_R16_3Plane_444_Unorm",
258
"Astc_4X4_Sfloat_Block",
259
"Astc_5X4_Sfloat_Block",
260
"Astc_5X5_Sfloat_Block",
261
"Astc_6X5_Sfloat_Block",
262
"Astc_6X6_Sfloat_Block",
263
"Astc_8X5_Sfloat_Block",
264
"Astc_8X6_Sfloat_Block",
265
"Astc_8X8_Sfloat_Block",
266
"Astc_10X5_Sfloat_Block",
267
"Astc_10X6_Sfloat_Block",
268
"Astc_10X8_Sfloat_Block",
269
"Astc_10X10_Sfloat_Block",
270
"Astc_12X10_Sfloat_Block",
271
"Astc_12X12_Sfloat_Block",
272
};
273
274
/*****************/
275
/**** TEXTURE ****/
276
/*****************/
277
278
const uint32_t RenderingDeviceCommons::TEXTURE_SAMPLES_COUNT[TEXTURE_SAMPLES_MAX] = { 1, 2, 4, 8, 16, 32, 64 };
279
280
uint32_t RenderingDeviceCommons::get_image_format_pixel_size(DataFormat p_format) {
281
switch (p_format) {
282
case DATA_FORMAT_R4G4_UNORM_PACK8:
283
return 1;
284
case DATA_FORMAT_R4G4B4A4_UNORM_PACK16:
285
case DATA_FORMAT_B4G4R4A4_UNORM_PACK16:
286
case DATA_FORMAT_R5G6B5_UNORM_PACK16:
287
case DATA_FORMAT_B5G6R5_UNORM_PACK16:
288
case DATA_FORMAT_R5G5B5A1_UNORM_PACK16:
289
case DATA_FORMAT_B5G5R5A1_UNORM_PACK16:
290
case DATA_FORMAT_A1R5G5B5_UNORM_PACK16:
291
return 2;
292
case DATA_FORMAT_R8_UNORM:
293
case DATA_FORMAT_R8_SNORM:
294
case DATA_FORMAT_R8_USCALED:
295
case DATA_FORMAT_R8_SSCALED:
296
case DATA_FORMAT_R8_UINT:
297
case DATA_FORMAT_R8_SINT:
298
case DATA_FORMAT_R8_SRGB:
299
return 1;
300
case DATA_FORMAT_R8G8_UNORM:
301
case DATA_FORMAT_R8G8_SNORM:
302
case DATA_FORMAT_R8G8_USCALED:
303
case DATA_FORMAT_R8G8_SSCALED:
304
case DATA_FORMAT_R8G8_UINT:
305
case DATA_FORMAT_R8G8_SINT:
306
case DATA_FORMAT_R8G8_SRGB:
307
return 2;
308
case DATA_FORMAT_R8G8B8_UNORM:
309
case DATA_FORMAT_R8G8B8_SNORM:
310
case DATA_FORMAT_R8G8B8_USCALED:
311
case DATA_FORMAT_R8G8B8_SSCALED:
312
case DATA_FORMAT_R8G8B8_UINT:
313
case DATA_FORMAT_R8G8B8_SINT:
314
case DATA_FORMAT_R8G8B8_SRGB:
315
case DATA_FORMAT_B8G8R8_UNORM:
316
case DATA_FORMAT_B8G8R8_SNORM:
317
case DATA_FORMAT_B8G8R8_USCALED:
318
case DATA_FORMAT_B8G8R8_SSCALED:
319
case DATA_FORMAT_B8G8R8_UINT:
320
case DATA_FORMAT_B8G8R8_SINT:
321
case DATA_FORMAT_B8G8R8_SRGB:
322
return 3;
323
case DATA_FORMAT_R8G8B8A8_UNORM:
324
case DATA_FORMAT_R8G8B8A8_SNORM:
325
case DATA_FORMAT_R8G8B8A8_USCALED:
326
case DATA_FORMAT_R8G8B8A8_SSCALED:
327
case DATA_FORMAT_R8G8B8A8_UINT:
328
case DATA_FORMAT_R8G8B8A8_SINT:
329
case DATA_FORMAT_R8G8B8A8_SRGB:
330
case DATA_FORMAT_B8G8R8A8_UNORM:
331
case DATA_FORMAT_B8G8R8A8_SNORM:
332
case DATA_FORMAT_B8G8R8A8_USCALED:
333
case DATA_FORMAT_B8G8R8A8_SSCALED:
334
case DATA_FORMAT_B8G8R8A8_UINT:
335
case DATA_FORMAT_B8G8R8A8_SINT:
336
case DATA_FORMAT_B8G8R8A8_SRGB:
337
return 4;
338
case DATA_FORMAT_A8B8G8R8_UNORM_PACK32:
339
case DATA_FORMAT_A8B8G8R8_SNORM_PACK32:
340
case DATA_FORMAT_A8B8G8R8_USCALED_PACK32:
341
case DATA_FORMAT_A8B8G8R8_SSCALED_PACK32:
342
case DATA_FORMAT_A8B8G8R8_UINT_PACK32:
343
case DATA_FORMAT_A8B8G8R8_SINT_PACK32:
344
case DATA_FORMAT_A8B8G8R8_SRGB_PACK32:
345
case DATA_FORMAT_A2R10G10B10_UNORM_PACK32:
346
case DATA_FORMAT_A2R10G10B10_SNORM_PACK32:
347
case DATA_FORMAT_A2R10G10B10_USCALED_PACK32:
348
case DATA_FORMAT_A2R10G10B10_SSCALED_PACK32:
349
case DATA_FORMAT_A2R10G10B10_UINT_PACK32:
350
case DATA_FORMAT_A2R10G10B10_SINT_PACK32:
351
case DATA_FORMAT_A2B10G10R10_UNORM_PACK32:
352
case DATA_FORMAT_A2B10G10R10_SNORM_PACK32:
353
case DATA_FORMAT_A2B10G10R10_USCALED_PACK32:
354
case DATA_FORMAT_A2B10G10R10_SSCALED_PACK32:
355
case DATA_FORMAT_A2B10G10R10_UINT_PACK32:
356
case DATA_FORMAT_A2B10G10R10_SINT_PACK32:
357
return 4;
358
case DATA_FORMAT_R16_UNORM:
359
case DATA_FORMAT_R16_SNORM:
360
case DATA_FORMAT_R16_USCALED:
361
case DATA_FORMAT_R16_SSCALED:
362
case DATA_FORMAT_R16_UINT:
363
case DATA_FORMAT_R16_SINT:
364
case DATA_FORMAT_R16_SFLOAT:
365
return 2;
366
case DATA_FORMAT_R16G16_UNORM:
367
case DATA_FORMAT_R16G16_SNORM:
368
case DATA_FORMAT_R16G16_USCALED:
369
case DATA_FORMAT_R16G16_SSCALED:
370
case DATA_FORMAT_R16G16_UINT:
371
case DATA_FORMAT_R16G16_SINT:
372
case DATA_FORMAT_R16G16_SFLOAT:
373
return 4;
374
case DATA_FORMAT_R16G16B16_UNORM:
375
case DATA_FORMAT_R16G16B16_SNORM:
376
case DATA_FORMAT_R16G16B16_USCALED:
377
case DATA_FORMAT_R16G16B16_SSCALED:
378
case DATA_FORMAT_R16G16B16_UINT:
379
case DATA_FORMAT_R16G16B16_SINT:
380
case DATA_FORMAT_R16G16B16_SFLOAT:
381
return 6;
382
case DATA_FORMAT_R16G16B16A16_UNORM:
383
case DATA_FORMAT_R16G16B16A16_SNORM:
384
case DATA_FORMAT_R16G16B16A16_USCALED:
385
case DATA_FORMAT_R16G16B16A16_SSCALED:
386
case DATA_FORMAT_R16G16B16A16_UINT:
387
case DATA_FORMAT_R16G16B16A16_SINT:
388
case DATA_FORMAT_R16G16B16A16_SFLOAT:
389
return 8;
390
case DATA_FORMAT_R32_UINT:
391
case DATA_FORMAT_R32_SINT:
392
case DATA_FORMAT_R32_SFLOAT:
393
return 4;
394
case DATA_FORMAT_R32G32_UINT:
395
case DATA_FORMAT_R32G32_SINT:
396
case DATA_FORMAT_R32G32_SFLOAT:
397
return 8;
398
case DATA_FORMAT_R32G32B32_UINT:
399
case DATA_FORMAT_R32G32B32_SINT:
400
case DATA_FORMAT_R32G32B32_SFLOAT:
401
return 12;
402
case DATA_FORMAT_R32G32B32A32_UINT:
403
case DATA_FORMAT_R32G32B32A32_SINT:
404
case DATA_FORMAT_R32G32B32A32_SFLOAT:
405
return 16;
406
case DATA_FORMAT_R64_UINT:
407
case DATA_FORMAT_R64_SINT:
408
case DATA_FORMAT_R64_SFLOAT:
409
return 8;
410
case DATA_FORMAT_R64G64_UINT:
411
case DATA_FORMAT_R64G64_SINT:
412
case DATA_FORMAT_R64G64_SFLOAT:
413
return 16;
414
case DATA_FORMAT_R64G64B64_UINT:
415
case DATA_FORMAT_R64G64B64_SINT:
416
case DATA_FORMAT_R64G64B64_SFLOAT:
417
return 24;
418
case DATA_FORMAT_R64G64B64A64_UINT:
419
case DATA_FORMAT_R64G64B64A64_SINT:
420
case DATA_FORMAT_R64G64B64A64_SFLOAT:
421
return 32;
422
case DATA_FORMAT_B10G11R11_UFLOAT_PACK32:
423
case DATA_FORMAT_E5B9G9R9_UFLOAT_PACK32:
424
return 4;
425
case DATA_FORMAT_D16_UNORM:
426
return 2;
427
case DATA_FORMAT_X8_D24_UNORM_PACK32:
428
return 4;
429
case DATA_FORMAT_D32_SFLOAT:
430
return 4;
431
case DATA_FORMAT_S8_UINT:
432
return 1;
433
case DATA_FORMAT_D16_UNORM_S8_UINT:
434
return 4;
435
case DATA_FORMAT_D24_UNORM_S8_UINT:
436
return 4;
437
case DATA_FORMAT_D32_SFLOAT_S8_UINT:
438
return 5; // ?
439
case DATA_FORMAT_BC1_RGB_UNORM_BLOCK:
440
case DATA_FORMAT_BC1_RGB_SRGB_BLOCK:
441
case DATA_FORMAT_BC1_RGBA_UNORM_BLOCK:
442
case DATA_FORMAT_BC1_RGBA_SRGB_BLOCK:
443
case DATA_FORMAT_BC2_UNORM_BLOCK:
444
case DATA_FORMAT_BC2_SRGB_BLOCK:
445
case DATA_FORMAT_BC3_UNORM_BLOCK:
446
case DATA_FORMAT_BC3_SRGB_BLOCK:
447
case DATA_FORMAT_BC4_UNORM_BLOCK:
448
case DATA_FORMAT_BC4_SNORM_BLOCK:
449
case DATA_FORMAT_BC5_UNORM_BLOCK:
450
case DATA_FORMAT_BC5_SNORM_BLOCK:
451
case DATA_FORMAT_BC6H_UFLOAT_BLOCK:
452
case DATA_FORMAT_BC6H_SFLOAT_BLOCK:
453
case DATA_FORMAT_BC7_UNORM_BLOCK:
454
case DATA_FORMAT_BC7_SRGB_BLOCK:
455
return 1;
456
case DATA_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
457
case DATA_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
458
case DATA_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
459
case DATA_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
460
case DATA_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
461
case DATA_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
462
return 1;
463
case DATA_FORMAT_EAC_R11_UNORM_BLOCK:
464
case DATA_FORMAT_EAC_R11_SNORM_BLOCK:
465
case DATA_FORMAT_EAC_R11G11_UNORM_BLOCK:
466
case DATA_FORMAT_EAC_R11G11_SNORM_BLOCK:
467
return 1;
468
case DATA_FORMAT_ASTC_4x4_UNORM_BLOCK:
469
case DATA_FORMAT_ASTC_4x4_SRGB_BLOCK:
470
case DATA_FORMAT_ASTC_5x4_UNORM_BLOCK:
471
case DATA_FORMAT_ASTC_5x4_SRGB_BLOCK:
472
case DATA_FORMAT_ASTC_5x5_UNORM_BLOCK:
473
case DATA_FORMAT_ASTC_5x5_SRGB_BLOCK:
474
case DATA_FORMAT_ASTC_6x5_UNORM_BLOCK:
475
case DATA_FORMAT_ASTC_6x5_SRGB_BLOCK:
476
case DATA_FORMAT_ASTC_6x6_UNORM_BLOCK:
477
case DATA_FORMAT_ASTC_6x6_SRGB_BLOCK:
478
case DATA_FORMAT_ASTC_8x5_UNORM_BLOCK:
479
case DATA_FORMAT_ASTC_8x5_SRGB_BLOCK:
480
case DATA_FORMAT_ASTC_8x6_UNORM_BLOCK:
481
case DATA_FORMAT_ASTC_8x6_SRGB_BLOCK:
482
case DATA_FORMAT_ASTC_8x8_UNORM_BLOCK:
483
case DATA_FORMAT_ASTC_8x8_SRGB_BLOCK:
484
case DATA_FORMAT_ASTC_10x5_UNORM_BLOCK:
485
case DATA_FORMAT_ASTC_10x5_SRGB_BLOCK:
486
case DATA_FORMAT_ASTC_10x6_UNORM_BLOCK:
487
case DATA_FORMAT_ASTC_10x6_SRGB_BLOCK:
488
case DATA_FORMAT_ASTC_10x8_UNORM_BLOCK:
489
case DATA_FORMAT_ASTC_10x8_SRGB_BLOCK:
490
case DATA_FORMAT_ASTC_10x10_UNORM_BLOCK:
491
case DATA_FORMAT_ASTC_10x10_SRGB_BLOCK:
492
case DATA_FORMAT_ASTC_12x10_UNORM_BLOCK:
493
case DATA_FORMAT_ASTC_12x10_SRGB_BLOCK:
494
case DATA_FORMAT_ASTC_12x12_UNORM_BLOCK:
495
case DATA_FORMAT_ASTC_12x12_SRGB_BLOCK:
496
case DATA_FORMAT_ASTC_4x4_SFLOAT_BLOCK:
497
case DATA_FORMAT_ASTC_5x4_SFLOAT_BLOCK:
498
case DATA_FORMAT_ASTC_5x5_SFLOAT_BLOCK:
499
case DATA_FORMAT_ASTC_6x5_SFLOAT_BLOCK:
500
case DATA_FORMAT_ASTC_6x6_SFLOAT_BLOCK:
501
case DATA_FORMAT_ASTC_8x5_SFLOAT_BLOCK:
502
case DATA_FORMAT_ASTC_8x6_SFLOAT_BLOCK:
503
case DATA_FORMAT_ASTC_8x8_SFLOAT_BLOCK:
504
case DATA_FORMAT_ASTC_10x5_SFLOAT_BLOCK:
505
case DATA_FORMAT_ASTC_10x6_SFLOAT_BLOCK:
506
case DATA_FORMAT_ASTC_10x8_SFLOAT_BLOCK:
507
case DATA_FORMAT_ASTC_10x10_SFLOAT_BLOCK:
508
case DATA_FORMAT_ASTC_12x10_SFLOAT_BLOCK:
509
case DATA_FORMAT_ASTC_12x12_SFLOAT_BLOCK:
510
return 1;
511
case DATA_FORMAT_G8B8G8R8_422_UNORM:
512
case DATA_FORMAT_B8G8R8G8_422_UNORM:
513
return 4;
514
case DATA_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
515
case DATA_FORMAT_G8_B8R8_2PLANE_420_UNORM:
516
case DATA_FORMAT_G8_B8_R8_3PLANE_422_UNORM:
517
case DATA_FORMAT_G8_B8R8_2PLANE_422_UNORM:
518
case DATA_FORMAT_G8_B8_R8_3PLANE_444_UNORM:
519
return 4;
520
case DATA_FORMAT_R10X6_UNORM_PACK16:
521
case DATA_FORMAT_R10X6G10X6_UNORM_2PACK16:
522
case DATA_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16:
523
case DATA_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16:
524
case DATA_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16:
525
case DATA_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16:
526
case DATA_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
527
case DATA_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16:
528
case DATA_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16:
529
case DATA_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16:
530
case DATA_FORMAT_R12X4_UNORM_PACK16:
531
case DATA_FORMAT_R12X4G12X4_UNORM_2PACK16:
532
case DATA_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16:
533
case DATA_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16:
534
case DATA_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16:
535
case DATA_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16:
536
case DATA_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16:
537
case DATA_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16:
538
case DATA_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16:
539
case DATA_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16:
540
return 2;
541
case DATA_FORMAT_G16B16G16R16_422_UNORM:
542
case DATA_FORMAT_B16G16R16G16_422_UNORM:
543
case DATA_FORMAT_G16_B16_R16_3PLANE_420_UNORM:
544
case DATA_FORMAT_G16_B16R16_2PLANE_420_UNORM:
545
case DATA_FORMAT_G16_B16_R16_3PLANE_422_UNORM:
546
case DATA_FORMAT_G16_B16R16_2PLANE_422_UNORM:
547
case DATA_FORMAT_G16_B16_R16_3PLANE_444_UNORM:
548
return 8;
549
default: {
550
ERR_PRINT("Format not handled, bug");
551
}
552
}
553
554
return 1;
555
}
556
557
// https://www.khronos.org/registry/DataFormat/specs/1.1/dataformat.1.1.pdf
558
void RenderingDeviceCommons::get_compressed_image_format_block_dimensions(DataFormat p_format, uint32_t &r_w, uint32_t &r_h) {
559
switch (p_format) {
560
case DATA_FORMAT_BC1_RGB_UNORM_BLOCK:
561
case DATA_FORMAT_BC1_RGB_SRGB_BLOCK:
562
case DATA_FORMAT_BC1_RGBA_UNORM_BLOCK:
563
case DATA_FORMAT_BC1_RGBA_SRGB_BLOCK:
564
case DATA_FORMAT_BC2_UNORM_BLOCK:
565
case DATA_FORMAT_BC2_SRGB_BLOCK:
566
case DATA_FORMAT_BC3_UNORM_BLOCK:
567
case DATA_FORMAT_BC3_SRGB_BLOCK:
568
case DATA_FORMAT_BC4_UNORM_BLOCK:
569
case DATA_FORMAT_BC4_SNORM_BLOCK:
570
case DATA_FORMAT_BC5_UNORM_BLOCK:
571
case DATA_FORMAT_BC5_SNORM_BLOCK:
572
case DATA_FORMAT_BC6H_UFLOAT_BLOCK:
573
case DATA_FORMAT_BC6H_SFLOAT_BLOCK:
574
case DATA_FORMAT_BC7_UNORM_BLOCK:
575
case DATA_FORMAT_BC7_SRGB_BLOCK:
576
case DATA_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
577
case DATA_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
578
case DATA_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
579
case DATA_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
580
case DATA_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
581
case DATA_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
582
case DATA_FORMAT_EAC_R11_UNORM_BLOCK:
583
case DATA_FORMAT_EAC_R11_SNORM_BLOCK:
584
case DATA_FORMAT_EAC_R11G11_UNORM_BLOCK:
585
case DATA_FORMAT_EAC_R11G11_SNORM_BLOCK:
586
case DATA_FORMAT_ASTC_4x4_UNORM_BLOCK: // Again, not sure about astc.
587
case DATA_FORMAT_ASTC_4x4_SRGB_BLOCK:
588
case DATA_FORMAT_ASTC_4x4_SFLOAT_BLOCK: {
589
r_w = 4;
590
r_h = 4;
591
} break;
592
case DATA_FORMAT_ASTC_5x4_UNORM_BLOCK: // Unsupported
593
case DATA_FORMAT_ASTC_5x4_SRGB_BLOCK:
594
case DATA_FORMAT_ASTC_5x4_SFLOAT_BLOCK:
595
case DATA_FORMAT_ASTC_5x5_UNORM_BLOCK:
596
case DATA_FORMAT_ASTC_5x5_SRGB_BLOCK:
597
case DATA_FORMAT_ASTC_5x5_SFLOAT_BLOCK:
598
case DATA_FORMAT_ASTC_6x5_UNORM_BLOCK:
599
case DATA_FORMAT_ASTC_6x5_SRGB_BLOCK:
600
case DATA_FORMAT_ASTC_6x5_SFLOAT_BLOCK:
601
case DATA_FORMAT_ASTC_6x6_UNORM_BLOCK:
602
case DATA_FORMAT_ASTC_6x6_SRGB_BLOCK:
603
case DATA_FORMAT_ASTC_6x6_SFLOAT_BLOCK:
604
case DATA_FORMAT_ASTC_8x5_UNORM_BLOCK:
605
case DATA_FORMAT_ASTC_8x5_SRGB_BLOCK:
606
case DATA_FORMAT_ASTC_8x5_SFLOAT_BLOCK:
607
case DATA_FORMAT_ASTC_8x6_UNORM_BLOCK:
608
case DATA_FORMAT_ASTC_8x6_SRGB_BLOCK:
609
case DATA_FORMAT_ASTC_8x6_SFLOAT_BLOCK: {
610
r_w = 4;
611
r_h = 4;
612
} break;
613
case DATA_FORMAT_ASTC_8x8_UNORM_BLOCK:
614
case DATA_FORMAT_ASTC_8x8_SRGB_BLOCK:
615
case DATA_FORMAT_ASTC_8x8_SFLOAT_BLOCK: {
616
r_w = 8;
617
r_h = 8;
618
} break;
619
case DATA_FORMAT_ASTC_10x5_UNORM_BLOCK: // Unsupported
620
case DATA_FORMAT_ASTC_10x5_SRGB_BLOCK:
621
case DATA_FORMAT_ASTC_10x5_SFLOAT_BLOCK:
622
case DATA_FORMAT_ASTC_10x6_UNORM_BLOCK:
623
case DATA_FORMAT_ASTC_10x6_SRGB_BLOCK:
624
case DATA_FORMAT_ASTC_10x6_SFLOAT_BLOCK:
625
case DATA_FORMAT_ASTC_10x8_UNORM_BLOCK:
626
case DATA_FORMAT_ASTC_10x8_SRGB_BLOCK:
627
case DATA_FORMAT_ASTC_10x8_SFLOAT_BLOCK:
628
case DATA_FORMAT_ASTC_10x10_UNORM_BLOCK:
629
case DATA_FORMAT_ASTC_10x10_SRGB_BLOCK:
630
case DATA_FORMAT_ASTC_10x10_SFLOAT_BLOCK:
631
case DATA_FORMAT_ASTC_12x10_UNORM_BLOCK:
632
case DATA_FORMAT_ASTC_12x10_SRGB_BLOCK:
633
case DATA_FORMAT_ASTC_12x10_SFLOAT_BLOCK:
634
case DATA_FORMAT_ASTC_12x12_UNORM_BLOCK:
635
case DATA_FORMAT_ASTC_12x12_SRGB_BLOCK:
636
case DATA_FORMAT_ASTC_12x12_SFLOAT_BLOCK:
637
r_w = 4;
638
r_h = 4;
639
return;
640
default: {
641
r_w = 1;
642
r_h = 1;
643
}
644
}
645
}
646
647
uint32_t RenderingDeviceCommons::get_compressed_image_format_block_byte_size(DataFormat p_format) const {
648
switch (p_format) {
649
case DATA_FORMAT_BC1_RGB_UNORM_BLOCK:
650
case DATA_FORMAT_BC1_RGB_SRGB_BLOCK:
651
case DATA_FORMAT_BC1_RGBA_UNORM_BLOCK:
652
case DATA_FORMAT_BC1_RGBA_SRGB_BLOCK:
653
return 8;
654
case DATA_FORMAT_BC2_UNORM_BLOCK:
655
case DATA_FORMAT_BC2_SRGB_BLOCK:
656
return 16;
657
case DATA_FORMAT_BC3_UNORM_BLOCK:
658
case DATA_FORMAT_BC3_SRGB_BLOCK:
659
return 16;
660
case DATA_FORMAT_BC4_UNORM_BLOCK:
661
case DATA_FORMAT_BC4_SNORM_BLOCK:
662
return 8;
663
case DATA_FORMAT_BC5_UNORM_BLOCK:
664
case DATA_FORMAT_BC5_SNORM_BLOCK:
665
return 16;
666
case DATA_FORMAT_BC6H_UFLOAT_BLOCK:
667
case DATA_FORMAT_BC6H_SFLOAT_BLOCK:
668
return 16;
669
case DATA_FORMAT_BC7_UNORM_BLOCK:
670
case DATA_FORMAT_BC7_SRGB_BLOCK:
671
return 16;
672
case DATA_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
673
case DATA_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
674
return 8;
675
case DATA_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
676
case DATA_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
677
return 8;
678
case DATA_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
679
case DATA_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
680
return 16;
681
case DATA_FORMAT_EAC_R11_UNORM_BLOCK:
682
case DATA_FORMAT_EAC_R11_SNORM_BLOCK:
683
return 8;
684
case DATA_FORMAT_EAC_R11G11_UNORM_BLOCK:
685
case DATA_FORMAT_EAC_R11G11_SNORM_BLOCK:
686
return 16;
687
case DATA_FORMAT_ASTC_4x4_UNORM_BLOCK: // Again, not sure about astc.
688
case DATA_FORMAT_ASTC_4x4_SRGB_BLOCK:
689
case DATA_FORMAT_ASTC_4x4_SFLOAT_BLOCK:
690
case DATA_FORMAT_ASTC_5x4_UNORM_BLOCK:
691
case DATA_FORMAT_ASTC_5x4_SRGB_BLOCK:
692
case DATA_FORMAT_ASTC_5x4_SFLOAT_BLOCK:
693
case DATA_FORMAT_ASTC_5x5_UNORM_BLOCK:
694
case DATA_FORMAT_ASTC_5x5_SRGB_BLOCK:
695
case DATA_FORMAT_ASTC_5x5_SFLOAT_BLOCK:
696
case DATA_FORMAT_ASTC_6x5_UNORM_BLOCK:
697
case DATA_FORMAT_ASTC_6x5_SRGB_BLOCK:
698
case DATA_FORMAT_ASTC_6x5_SFLOAT_BLOCK:
699
case DATA_FORMAT_ASTC_6x6_UNORM_BLOCK:
700
case DATA_FORMAT_ASTC_6x6_SRGB_BLOCK:
701
case DATA_FORMAT_ASTC_6x6_SFLOAT_BLOCK:
702
case DATA_FORMAT_ASTC_8x5_UNORM_BLOCK:
703
case DATA_FORMAT_ASTC_8x5_SRGB_BLOCK:
704
case DATA_FORMAT_ASTC_8x5_SFLOAT_BLOCK:
705
case DATA_FORMAT_ASTC_8x6_UNORM_BLOCK:
706
case DATA_FORMAT_ASTC_8x6_SRGB_BLOCK:
707
case DATA_FORMAT_ASTC_8x6_SFLOAT_BLOCK:
708
case DATA_FORMAT_ASTC_8x8_UNORM_BLOCK:
709
case DATA_FORMAT_ASTC_8x8_SRGB_BLOCK:
710
case DATA_FORMAT_ASTC_8x8_SFLOAT_BLOCK:
711
case DATA_FORMAT_ASTC_10x5_UNORM_BLOCK:
712
case DATA_FORMAT_ASTC_10x5_SRGB_BLOCK:
713
case DATA_FORMAT_ASTC_10x5_SFLOAT_BLOCK:
714
case DATA_FORMAT_ASTC_10x6_UNORM_BLOCK:
715
case DATA_FORMAT_ASTC_10x6_SRGB_BLOCK:
716
case DATA_FORMAT_ASTC_10x6_SFLOAT_BLOCK:
717
case DATA_FORMAT_ASTC_10x8_UNORM_BLOCK:
718
case DATA_FORMAT_ASTC_10x8_SRGB_BLOCK:
719
case DATA_FORMAT_ASTC_10x8_SFLOAT_BLOCK:
720
case DATA_FORMAT_ASTC_10x10_UNORM_BLOCK:
721
case DATA_FORMAT_ASTC_10x10_SRGB_BLOCK:
722
case DATA_FORMAT_ASTC_10x10_SFLOAT_BLOCK:
723
case DATA_FORMAT_ASTC_12x10_UNORM_BLOCK:
724
case DATA_FORMAT_ASTC_12x10_SRGB_BLOCK:
725
case DATA_FORMAT_ASTC_12x10_SFLOAT_BLOCK:
726
case DATA_FORMAT_ASTC_12x12_UNORM_BLOCK:
727
case DATA_FORMAT_ASTC_12x12_SRGB_BLOCK:
728
case DATA_FORMAT_ASTC_12x12_SFLOAT_BLOCK:
729
return 16;
730
default: {
731
}
732
}
733
return 1;
734
}
735
736
uint32_t RenderingDeviceCommons::get_compressed_image_format_pixel_rshift(DataFormat p_format) {
737
switch (p_format) {
738
case DATA_FORMAT_BC1_RGB_UNORM_BLOCK: // These formats are half byte size, so rshift is 1.
739
case DATA_FORMAT_BC1_RGB_SRGB_BLOCK:
740
case DATA_FORMAT_BC1_RGBA_UNORM_BLOCK:
741
case DATA_FORMAT_BC1_RGBA_SRGB_BLOCK:
742
case DATA_FORMAT_BC4_UNORM_BLOCK:
743
case DATA_FORMAT_BC4_SNORM_BLOCK:
744
case DATA_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
745
case DATA_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
746
case DATA_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
747
case DATA_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
748
case DATA_FORMAT_EAC_R11_UNORM_BLOCK:
749
case DATA_FORMAT_EAC_R11_SNORM_BLOCK:
750
return 1;
751
case DATA_FORMAT_ASTC_8x8_SRGB_BLOCK:
752
case DATA_FORMAT_ASTC_8x8_UNORM_BLOCK:
753
case DATA_FORMAT_ASTC_8x8_SFLOAT_BLOCK: {
754
return 2;
755
}
756
default: {
757
}
758
}
759
760
return 0;
761
}
762
763
uint32_t RenderingDeviceCommons::get_image_format_required_size(DataFormat p_format, uint32_t p_width, uint32_t p_height, uint32_t p_depth, uint32_t p_mipmaps, uint32_t *r_blockw, uint32_t *r_blockh, uint32_t *r_depth) {
764
ERR_FAIL_COND_V(p_mipmaps == 0, 0);
765
uint32_t w = p_width;
766
uint32_t h = p_height;
767
uint32_t d = p_depth;
768
769
uint32_t size = 0;
770
771
uint32_t pixel_size = get_image_format_pixel_size(p_format);
772
uint32_t pixel_rshift = get_compressed_image_format_pixel_rshift(p_format);
773
uint32_t blockw = 0;
774
uint32_t blockh = 0;
775
get_compressed_image_format_block_dimensions(p_format, blockw, blockh);
776
777
for (uint32_t i = 0; i < p_mipmaps; i++) {
778
uint32_t bw = STEPIFY(w, blockw);
779
uint32_t bh = STEPIFY(h, blockh);
780
781
uint32_t s = bw * bh;
782
783
s *= pixel_size;
784
s >>= pixel_rshift;
785
size += s * d;
786
if (r_blockw) {
787
*r_blockw = bw;
788
}
789
if (r_blockh) {
790
*r_blockh = bh;
791
}
792
if (r_depth) {
793
*r_depth = d;
794
}
795
w = MAX(blockw, w >> 1);
796
h = MAX(blockh, h >> 1);
797
d = MAX(1u, d >> 1);
798
}
799
800
return size;
801
}
802
803
uint32_t RenderingDeviceCommons::get_image_required_mipmaps(uint32_t p_width, uint32_t p_height, uint32_t p_depth) {
804
// Formats and block size don't really matter here since they can all go down to 1px (even if block is larger).
805
uint32_t w = p_width;
806
uint32_t h = p_height;
807
uint32_t d = p_depth;
808
809
uint32_t mipmaps = 1;
810
811
while (true) {
812
if (w == 1 && h == 1 && d == 1) {
813
break;
814
}
815
816
w = MAX(1u, w >> 1);
817
h = MAX(1u, h >> 1);
818
d = MAX(1u, d >> 1);
819
820
mipmaps++;
821
}
822
823
return mipmaps;
824
}
825
826
bool RenderingDeviceCommons::format_has_stencil(DataFormat p_format) {
827
switch (p_format) {
828
case DATA_FORMAT_S8_UINT:
829
case DATA_FORMAT_D16_UNORM_S8_UINT:
830
case DATA_FORMAT_D24_UNORM_S8_UINT:
831
case DATA_FORMAT_D32_SFLOAT_S8_UINT: {
832
return true;
833
}
834
default: {
835
}
836
}
837
return false;
838
}
839
840
uint32_t RenderingDeviceCommons::format_get_plane_count(DataFormat p_format) {
841
uint32_t planes = 1;
842
switch (p_format) {
843
case DATA_FORMAT_D16_UNORM_S8_UINT:
844
case DATA_FORMAT_D24_UNORM_S8_UINT:
845
case DATA_FORMAT_D32_SFLOAT_S8_UINT: {
846
planes = 2;
847
break;
848
}
849
default: {
850
}
851
}
852
DEV_ASSERT(planes <= MAX_IMAGE_FORMAT_PLANES);
853
return planes;
854
}
855
856
/*****************/
857
/**** SAMPLER ****/
858
/*****************/
859
860
const Color RenderingDeviceCommons::SAMPLER_BORDER_COLOR_VALUE[SAMPLER_BORDER_COLOR_MAX] = {
861
Color(0, 0, 0, 0),
862
Color(0, 0, 0, 0),
863
Color(0, 0, 0, 1),
864
Color(0, 0, 0, 1),
865
Color(1, 1, 1, 1),
866
Color(1, 1, 1, 1),
867
};
868
869
/**********************/
870
/**** VERTEX ARRAY ****/
871
/**********************/
872
873
uint32_t RenderingDeviceCommons::get_format_vertex_size(DataFormat p_format) {
874
switch (p_format) {
875
case DATA_FORMAT_R8_UNORM:
876
case DATA_FORMAT_R8_SNORM:
877
case DATA_FORMAT_R8_UINT:
878
case DATA_FORMAT_R8_SINT:
879
case DATA_FORMAT_R8G8_UNORM:
880
case DATA_FORMAT_R8G8_SNORM:
881
case DATA_FORMAT_R8G8_UINT:
882
case DATA_FORMAT_R8G8_SINT:
883
case DATA_FORMAT_R8G8B8_UNORM:
884
case DATA_FORMAT_R8G8B8_SNORM:
885
case DATA_FORMAT_R8G8B8_UINT:
886
case DATA_FORMAT_R8G8B8_SINT:
887
case DATA_FORMAT_B8G8R8_UNORM:
888
case DATA_FORMAT_B8G8R8_SNORM:
889
case DATA_FORMAT_B8G8R8_UINT:
890
case DATA_FORMAT_B8G8R8_SINT:
891
case DATA_FORMAT_R8G8B8A8_UNORM:
892
case DATA_FORMAT_R8G8B8A8_SNORM:
893
case DATA_FORMAT_R8G8B8A8_UINT:
894
case DATA_FORMAT_R8G8B8A8_SINT:
895
case DATA_FORMAT_B8G8R8A8_UNORM:
896
case DATA_FORMAT_B8G8R8A8_SNORM:
897
case DATA_FORMAT_B8G8R8A8_UINT:
898
case DATA_FORMAT_B8G8R8A8_SINT:
899
case DATA_FORMAT_A2B10G10R10_UNORM_PACK32:
900
return 4;
901
case DATA_FORMAT_R16_UNORM:
902
case DATA_FORMAT_R16_SNORM:
903
case DATA_FORMAT_R16_UINT:
904
case DATA_FORMAT_R16_SINT:
905
case DATA_FORMAT_R16_SFLOAT:
906
return 4;
907
case DATA_FORMAT_R16G16_UNORM:
908
case DATA_FORMAT_R16G16_SNORM:
909
case DATA_FORMAT_R16G16_UINT:
910
case DATA_FORMAT_R16G16_SINT:
911
case DATA_FORMAT_R16G16_SFLOAT:
912
return 4;
913
case DATA_FORMAT_R16G16B16_UNORM:
914
case DATA_FORMAT_R16G16B16_SNORM:
915
case DATA_FORMAT_R16G16B16_UINT:
916
case DATA_FORMAT_R16G16B16_SINT:
917
case DATA_FORMAT_R16G16B16_SFLOAT:
918
return 8;
919
case DATA_FORMAT_R16G16B16A16_UNORM:
920
case DATA_FORMAT_R16G16B16A16_SNORM:
921
case DATA_FORMAT_R16G16B16A16_UINT:
922
case DATA_FORMAT_R16G16B16A16_SINT:
923
case DATA_FORMAT_R16G16B16A16_SFLOAT:
924
return 8;
925
case DATA_FORMAT_R32_UINT:
926
case DATA_FORMAT_R32_SINT:
927
case DATA_FORMAT_R32_SFLOAT:
928
return 4;
929
case DATA_FORMAT_R32G32_UINT:
930
case DATA_FORMAT_R32G32_SINT:
931
case DATA_FORMAT_R32G32_SFLOAT:
932
return 8;
933
case DATA_FORMAT_R32G32B32_UINT:
934
case DATA_FORMAT_R32G32B32_SINT:
935
case DATA_FORMAT_R32G32B32_SFLOAT:
936
return 12;
937
case DATA_FORMAT_R32G32B32A32_UINT:
938
case DATA_FORMAT_R32G32B32A32_SINT:
939
case DATA_FORMAT_R32G32B32A32_SFLOAT:
940
return 16;
941
case DATA_FORMAT_R64_UINT:
942
case DATA_FORMAT_R64_SINT:
943
case DATA_FORMAT_R64_SFLOAT:
944
return 8;
945
case DATA_FORMAT_R64G64_UINT:
946
case DATA_FORMAT_R64G64_SINT:
947
case DATA_FORMAT_R64G64_SFLOAT:
948
return 16;
949
case DATA_FORMAT_R64G64B64_UINT:
950
case DATA_FORMAT_R64G64B64_SINT:
951
case DATA_FORMAT_R64G64B64_SFLOAT:
952
return 24;
953
case DATA_FORMAT_R64G64B64A64_UINT:
954
case DATA_FORMAT_R64G64B64A64_SINT:
955
case DATA_FORMAT_R64G64B64A64_SFLOAT:
956
return 32;
957
default:
958
return 0;
959
}
960
}
961
962
/****************/
963
/**** SHADER ****/
964
/****************/
965
966
const char *RenderingDeviceCommons::SHADER_STAGE_NAMES[SHADER_STAGE_MAX] = {
967
"Vertex",
968
"Fragment",
969
"TesselationControl",
970
"TesselationEvaluation",
971
"Compute",
972
};
973
974
Error RenderingDeviceCommons::reflect_spirv(VectorView<ShaderStageSPIRVData> p_spirv, ShaderReflection &r_reflection) {
975
r_reflection = {};
976
977
const uint32_t spirv_size = p_spirv.size();
978
for (uint32_t i = 0; i < spirv_size; i++) {
979
ShaderStage stage = p_spirv[i].shader_stage;
980
ShaderStage stage_flag = (ShaderStage)(1 << p_spirv[i].shader_stage);
981
982
if (p_spirv[i].shader_stage == SHADER_STAGE_COMPUTE) {
983
r_reflection.is_compute = true;
984
ERR_FAIL_COND_V_MSG(spirv_size != 1, FAILED,
985
"Compute shaders can only receive one stage, dedicated to compute.");
986
}
987
ERR_FAIL_COND_V_MSG(r_reflection.stages_bits.has_flag(stage_flag), FAILED,
988
"Stage " + String(SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + " submitted more than once.");
989
990
{
991
SpvReflectShaderModule module;
992
const uint8_t *spirv = p_spirv[i].spirv.ptr();
993
SpvReflectResult result = spvReflectCreateShaderModule(p_spirv[i].spirv.size(), spirv, &module);
994
ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,
995
"Reflection of SPIR-V shader stage '" + String(SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + "' failed parsing shader.");
996
997
if (r_reflection.is_compute) {
998
r_reflection.compute_local_size[0] = module.entry_points->local_size.x;
999
r_reflection.compute_local_size[1] = module.entry_points->local_size.y;
1000
r_reflection.compute_local_size[2] = module.entry_points->local_size.z;
1001
}
1002
uint32_t binding_count = 0;
1003
result = spvReflectEnumerateDescriptorBindings(&module, &binding_count, nullptr);
1004
ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,
1005
"Reflection of SPIR-V shader stage '" + String(SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + "' failed enumerating descriptor bindings.");
1006
1007
if (binding_count > 0) {
1008
// Parse bindings.
1009
1010
Vector<SpvReflectDescriptorBinding *> bindings;
1011
bindings.resize(binding_count);
1012
result = spvReflectEnumerateDescriptorBindings(&module, &binding_count, bindings.ptrw());
1013
1014
ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,
1015
"Reflection of SPIR-V shader stage '" + String(SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + "' failed getting descriptor bindings.");
1016
1017
for (uint32_t j = 0; j < binding_count; j++) {
1018
const SpvReflectDescriptorBinding &binding = *bindings[j];
1019
1020
ShaderUniform uniform;
1021
1022
bool need_array_dimensions = false;
1023
bool need_block_size = false;
1024
bool may_be_writable = false;
1025
1026
switch (binding.descriptor_type) {
1027
case SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLER: {
1028
uniform.type = UNIFORM_TYPE_SAMPLER;
1029
need_array_dimensions = true;
1030
} break;
1031
case SPV_REFLECT_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: {
1032
uniform.type = UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;
1033
need_array_dimensions = true;
1034
} break;
1035
case SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLED_IMAGE: {
1036
uniform.type = UNIFORM_TYPE_TEXTURE;
1037
need_array_dimensions = true;
1038
} break;
1039
case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_IMAGE: {
1040
uniform.type = UNIFORM_TYPE_IMAGE;
1041
need_array_dimensions = true;
1042
may_be_writable = true;
1043
} break;
1044
case SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: {
1045
uniform.type = UNIFORM_TYPE_TEXTURE_BUFFER;
1046
need_array_dimensions = true;
1047
} break;
1048
case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: {
1049
uniform.type = UNIFORM_TYPE_IMAGE_BUFFER;
1050
need_array_dimensions = true;
1051
may_be_writable = true;
1052
} break;
1053
case SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_BUFFER: {
1054
uniform.type = UNIFORM_TYPE_UNIFORM_BUFFER;
1055
need_block_size = true;
1056
} break;
1057
case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER: {
1058
uniform.type = UNIFORM_TYPE_STORAGE_BUFFER;
1059
need_block_size = true;
1060
may_be_writable = true;
1061
} break;
1062
case SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: {
1063
ERR_PRINT("Dynamic uniform buffer not supported.");
1064
continue;
1065
} break;
1066
case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: {
1067
ERR_PRINT("Dynamic storage buffer not supported.");
1068
continue;
1069
} break;
1070
case SPV_REFLECT_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: {
1071
uniform.type = UNIFORM_TYPE_INPUT_ATTACHMENT;
1072
need_array_dimensions = true;
1073
} break;
1074
case SPV_REFLECT_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR: {
1075
ERR_PRINT("Acceleration structure not supported.");
1076
continue;
1077
} break;
1078
}
1079
1080
if (need_array_dimensions) {
1081
if (binding.array.dims_count == 0) {
1082
uniform.length = 1;
1083
} else {
1084
for (uint32_t k = 0; k < binding.array.dims_count; k++) {
1085
if (k == 0) {
1086
uniform.length = binding.array.dims[0];
1087
} else {
1088
uniform.length *= binding.array.dims[k];
1089
}
1090
}
1091
}
1092
1093
} else if (need_block_size) {
1094
uniform.length = binding.block.size;
1095
} else {
1096
uniform.length = 0;
1097
}
1098
1099
if (may_be_writable) {
1100
if (binding.descriptor_type == SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_IMAGE) {
1101
uniform.writable = !(binding.decoration_flags & SPV_REFLECT_DECORATION_NON_WRITABLE);
1102
} else {
1103
uniform.writable = !(binding.decoration_flags & SPV_REFLECT_DECORATION_NON_WRITABLE) && !(binding.block.decoration_flags & SPV_REFLECT_DECORATION_NON_WRITABLE);
1104
}
1105
} else {
1106
uniform.writable = false;
1107
}
1108
1109
uniform.binding = binding.binding;
1110
uint32_t set = binding.set;
1111
1112
ERR_FAIL_COND_V_MSG(set >= MAX_UNIFORM_SETS, FAILED,
1113
"On shader stage '" + String(SHADER_STAGE_NAMES[stage]) + "', uniform '" + binding.name + "' uses a set (" + itos(set) + ") index larger than what is supported (" + itos(MAX_UNIFORM_SETS) + ").");
1114
1115
if (set < (uint32_t)r_reflection.uniform_sets.size()) {
1116
// Check if this already exists.
1117
bool exists = false;
1118
for (int k = 0; k < r_reflection.uniform_sets[set].size(); k++) {
1119
if (r_reflection.uniform_sets[set][k].binding == uniform.binding) {
1120
// Already exists, verify that it's the same type.
1121
ERR_FAIL_COND_V_MSG(r_reflection.uniform_sets[set][k].type != uniform.type, FAILED,
1122
"On shader stage '" + String(SHADER_STAGE_NAMES[stage]) + "', uniform '" + binding.name + "' trying to reuse location for set=" + itos(set) + ", binding=" + itos(uniform.binding) + " with different uniform type.");
1123
1124
// Also, verify that it's the same size.
1125
ERR_FAIL_COND_V_MSG(r_reflection.uniform_sets[set][k].length != uniform.length, FAILED,
1126
"On shader stage '" + String(SHADER_STAGE_NAMES[stage]) + "', uniform '" + binding.name + "' trying to reuse location for set=" + itos(set) + ", binding=" + itos(uniform.binding) + " with different uniform size.");
1127
1128
// Also, verify that it has the same writability.
1129
ERR_FAIL_COND_V_MSG(r_reflection.uniform_sets[set][k].writable != uniform.writable, FAILED,
1130
"On shader stage '" + String(SHADER_STAGE_NAMES[stage]) + "', uniform '" + binding.name + "' trying to reuse location for set=" + itos(set) + ", binding=" + itos(uniform.binding) + " with different writability.");
1131
1132
// Just append stage mask and return.
1133
r_reflection.uniform_sets.write[set].write[k].stages.set_flag(stage_flag);
1134
exists = true;
1135
break;
1136
}
1137
}
1138
1139
if (exists) {
1140
continue; // Merged.
1141
}
1142
}
1143
1144
uniform.stages.set_flag(stage_flag);
1145
1146
if (set >= (uint32_t)r_reflection.uniform_sets.size()) {
1147
r_reflection.uniform_sets.resize(set + 1);
1148
}
1149
1150
r_reflection.uniform_sets.write[set].push_back(uniform);
1151
}
1152
}
1153
1154
{
1155
// Specialization constants.
1156
1157
uint32_t sc_count = 0;
1158
result = spvReflectEnumerateSpecializationConstants(&module, &sc_count, nullptr);
1159
ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,
1160
"Reflection of SPIR-V shader stage '" + String(SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + "' failed enumerating specialization constants.");
1161
1162
if (sc_count) {
1163
Vector<SpvReflectSpecializationConstant *> spec_constants;
1164
spec_constants.resize(sc_count);
1165
1166
result = spvReflectEnumerateSpecializationConstants(&module, &sc_count, spec_constants.ptrw());
1167
ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,
1168
"Reflection of SPIR-V shader stage '" + String(SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + "' failed obtaining specialization constants.");
1169
1170
for (uint32_t j = 0; j < sc_count; j++) {
1171
int32_t existing = -1;
1172
ShaderSpecializationConstant sconst;
1173
SpvReflectSpecializationConstant *spc = spec_constants[j];
1174
1175
sconst.constant_id = spc->constant_id;
1176
sconst.int_value = 0; // Clear previous value JIC.
1177
switch (spc->constant_type) {
1178
case SPV_REFLECT_SPECIALIZATION_CONSTANT_BOOL: {
1179
sconst.type = PIPELINE_SPECIALIZATION_CONSTANT_TYPE_BOOL;
1180
sconst.bool_value = spc->default_value.int_bool_value != 0;
1181
} break;
1182
case SPV_REFLECT_SPECIALIZATION_CONSTANT_INT: {
1183
sconst.type = PIPELINE_SPECIALIZATION_CONSTANT_TYPE_INT;
1184
sconst.int_value = spc->default_value.int_bool_value;
1185
} break;
1186
case SPV_REFLECT_SPECIALIZATION_CONSTANT_FLOAT: {
1187
sconst.type = PIPELINE_SPECIALIZATION_CONSTANT_TYPE_FLOAT;
1188
sconst.float_value = spc->default_value.float_value;
1189
} break;
1190
}
1191
sconst.stages.set_flag(stage_flag);
1192
1193
for (int k = 0; k < r_reflection.specialization_constants.size(); k++) {
1194
if (r_reflection.specialization_constants[k].constant_id == sconst.constant_id) {
1195
ERR_FAIL_COND_V_MSG(r_reflection.specialization_constants[k].type != sconst.type, FAILED, "More than one specialization constant used for id (" + itos(sconst.constant_id) + "), but their types differ.");
1196
ERR_FAIL_COND_V_MSG(r_reflection.specialization_constants[k].int_value != sconst.int_value, FAILED, "More than one specialization constant used for id (" + itos(sconst.constant_id) + "), but their default values differ.");
1197
existing = k;
1198
break;
1199
}
1200
}
1201
1202
if (existing >= 0) {
1203
r_reflection.specialization_constants.write[existing].stages.set_flag(stage_flag);
1204
} else {
1205
r_reflection.specialization_constants.push_back(sconst);
1206
}
1207
}
1208
1209
r_reflection.specialization_constants.sort();
1210
}
1211
}
1212
1213
if (stage == SHADER_STAGE_VERTEX || stage == SHADER_STAGE_FRAGMENT) {
1214
uint32_t iv_count = 0;
1215
result = spvReflectEnumerateInputVariables(&module, &iv_count, nullptr);
1216
ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,
1217
"Reflection of SPIR-V shader stage '" + String(SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + "' failed enumerating input variables.");
1218
1219
if (iv_count) {
1220
Vector<SpvReflectInterfaceVariable *> input_vars;
1221
input_vars.resize(iv_count);
1222
1223
result = spvReflectEnumerateInputVariables(&module, &iv_count, input_vars.ptrw());
1224
ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,
1225
"Reflection of SPIR-V shader stage '" + String(SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + "' failed obtaining input variables.");
1226
1227
for (const SpvReflectInterfaceVariable *v : input_vars) {
1228
if (!v) {
1229
continue;
1230
}
1231
if (stage == SHADER_STAGE_VERTEX) {
1232
if (v->decoration_flags == 0) { // Regular input.
1233
r_reflection.vertex_input_mask |= (((uint64_t)1) << v->location);
1234
}
1235
}
1236
if (v->built_in == SpvBuiltInViewIndex) {
1237
r_reflection.has_multiview = true;
1238
}
1239
}
1240
}
1241
}
1242
1243
if (stage == SHADER_STAGE_FRAGMENT) {
1244
uint32_t ov_count = 0;
1245
result = spvReflectEnumerateOutputVariables(&module, &ov_count, nullptr);
1246
ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,
1247
"Reflection of SPIR-V shader stage '" + String(SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + "' failed enumerating output variables.");
1248
1249
if (ov_count) {
1250
Vector<SpvReflectInterfaceVariable *> output_vars;
1251
output_vars.resize(ov_count);
1252
1253
result = spvReflectEnumerateOutputVariables(&module, &ov_count, output_vars.ptrw());
1254
ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,
1255
"Reflection of SPIR-V shader stage '" + String(SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + "' failed obtaining output variables.");
1256
1257
for (const SpvReflectInterfaceVariable *refvar : output_vars) {
1258
if (!refvar) {
1259
continue;
1260
}
1261
if (refvar->built_in != SpvBuiltInFragDepth) {
1262
r_reflection.fragment_output_mask |= 1 << refvar->location;
1263
}
1264
}
1265
}
1266
}
1267
1268
uint32_t pc_count = 0;
1269
result = spvReflectEnumeratePushConstantBlocks(&module, &pc_count, nullptr);
1270
ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,
1271
"Reflection of SPIR-V shader stage '" + String(SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + "' failed enumerating push constants.");
1272
1273
if (pc_count) {
1274
ERR_FAIL_COND_V_MSG(pc_count > 1, FAILED,
1275
"Reflection of SPIR-V shader stage '" + String(SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + "': Only one push constant is supported, which should be the same across shader stages.");
1276
1277
Vector<SpvReflectBlockVariable *> pconstants;
1278
pconstants.resize(pc_count);
1279
result = spvReflectEnumeratePushConstantBlocks(&module, &pc_count, pconstants.ptrw());
1280
ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,
1281
"Reflection of SPIR-V shader stage '" + String(SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + "' failed obtaining push constants.");
1282
#if 0
1283
if (pconstants[0] == nullptr) {
1284
Ref<FileAccess> f = FileAccess::open("res://popo.spv", FileAccess::WRITE);
1285
f->store_buffer((const uint8_t *)&SpirV[0], SpirV.size() * sizeof(uint32_t));
1286
}
1287
#endif
1288
1289
ERR_FAIL_COND_V_MSG(r_reflection.push_constant_size && r_reflection.push_constant_size != pconstants[0]->size, FAILED,
1290
"Reflection of SPIR-V shader stage '" + String(SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + "': Push constant block must be the same across shader stages.");
1291
1292
r_reflection.push_constant_size = pconstants[0]->size;
1293
r_reflection.push_constant_stages.set_flag(stage_flag);
1294
1295
//print_line("Stage: " + String(SHADER_STAGE_NAMES[stage]) + " push constant of size=" + itos(push_constant.push_constant_size));
1296
}
1297
1298
// Destroy the reflection data when no longer required.
1299
spvReflectDestroyShaderModule(&module);
1300
}
1301
1302
r_reflection.stages_bits.set_flag(stage_flag);
1303
}
1304
1305
// Sort all uniform_sets by binding.
1306
for (uint32_t i = 0; i < r_reflection.uniform_sets.size(); i++) {
1307
r_reflection.uniform_sets.write[i].sort();
1308
}
1309
1310
return OK;
1311
}
1312
1313