Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/servers/rendering/rendering_shader_container.cpp
20872 views
1
/**************************************************************************/
2
/* rendering_shader_container.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_shader_container.h"
32
33
#include "core/io/compression.h"
34
35
#include "servers/rendering/renderer_rd/shader_rd.h"
36
#include "thirdparty/spirv-reflect/spirv_reflect.h"
37
38
static inline uint32_t aligned_to(uint32_t p_size, uint32_t p_alignment) {
39
if (p_size % p_alignment) {
40
return p_size + (p_alignment - (p_size % p_alignment));
41
} else {
42
return p_size;
43
}
44
}
45
46
template <class T>
47
const T &RenderingShaderContainer::ReflectSymbol<T>::get_spv_reflect(RDC::ShaderStage p_stage) const {
48
const T *info = _spv_reflect[get_index_for_stage(p_stage)];
49
DEV_ASSERT(info != nullptr); // Caller is expected to specify valid shader stages
50
return *info;
51
}
52
53
template <class T>
54
void RenderingShaderContainer::ReflectSymbol<T>::set_spv_reflect(RDC::ShaderStage p_stage, const T *p_spv) {
55
stages.set_flag(1 << p_stage);
56
_spv_reflect[get_index_for_stage(p_stage)] = p_spv;
57
}
58
59
RenderingShaderContainer::ReflectShaderStage::ReflectShaderStage() {
60
_module = memnew(SpvReflectShaderModule);
61
memset(_module, 0, sizeof(SpvReflectShaderModule));
62
}
63
64
RenderingShaderContainer::ReflectShaderStage::~ReflectShaderStage() {
65
spvReflectDestroyShaderModule(_module);
66
memdelete(_module);
67
_module = nullptr;
68
}
69
70
const SpvReflectShaderModule &RenderingShaderContainer::ReflectShaderStage::module() const {
71
return *_module;
72
}
73
74
const Span<uint32_t> RenderingShaderContainer::ReflectShaderStage::spirv() const {
75
return _spirv_data.span().reinterpret<uint32_t>();
76
}
77
78
uint32_t RenderingShaderContainer::_from_bytes_header_extra_data(const uint8_t *p_bytes) {
79
return 0;
80
}
81
82
uint32_t RenderingShaderContainer::_from_bytes_reflection_extra_data(const uint8_t *p_bytes) {
83
return 0;
84
}
85
86
uint32_t RenderingShaderContainer::_from_bytes_reflection_binding_uniform_extra_data_start(const uint8_t *p_bytes) {
87
return 0;
88
}
89
90
uint32_t RenderingShaderContainer::_from_bytes_reflection_binding_uniform_extra_data(const uint8_t *p_bytes, uint32_t p_index) {
91
return 0;
92
}
93
94
uint32_t RenderingShaderContainer::_from_bytes_reflection_specialization_extra_data_start(const uint8_t *p_bytes) {
95
return 0;
96
}
97
98
uint32_t RenderingShaderContainer::_from_bytes_reflection_specialization_extra_data(const uint8_t *p_bytes, uint32_t p_index) {
99
return 0;
100
}
101
102
uint32_t RenderingShaderContainer::_from_bytes_shader_extra_data_start(const uint8_t *p_bytes) {
103
return 0;
104
}
105
106
uint32_t RenderingShaderContainer::_from_bytes_shader_extra_data(const uint8_t *p_bytes, uint32_t p_index) {
107
return 0;
108
}
109
110
uint32_t RenderingShaderContainer::_from_bytes_footer_extra_data(const uint8_t *p_bytes) {
111
return 0;
112
}
113
114
uint32_t RenderingShaderContainer::_to_bytes_header_extra_data(uint8_t *) const {
115
return 0;
116
}
117
118
uint32_t RenderingShaderContainer::_to_bytes_reflection_extra_data(uint8_t *) const {
119
return 0;
120
}
121
122
uint32_t RenderingShaderContainer::_to_bytes_reflection_binding_uniform_extra_data(uint8_t *, uint32_t) const {
123
return 0;
124
}
125
126
uint32_t RenderingShaderContainer::_to_bytes_reflection_specialization_extra_data(uint8_t *, uint32_t) const {
127
return 0;
128
}
129
130
uint32_t RenderingShaderContainer::_to_bytes_shader_extra_data(uint8_t *, uint32_t) const {
131
return 0;
132
}
133
134
uint32_t RenderingShaderContainer::_to_bytes_footer_extra_data(uint8_t *) const {
135
return 0;
136
}
137
138
void RenderingShaderContainer::_set_from_shader_reflection_post(const ReflectShader &p_shader) {
139
// Do nothing.
140
}
141
142
static RenderingDeviceCommons::DataFormat spv_image_format_to_data_format(const SpvImageFormat p_format) {
143
using RDC = RenderingDeviceCommons;
144
switch (p_format) {
145
case SpvImageFormatUnknown:
146
return RDC::DATA_FORMAT_MAX;
147
case SpvImageFormatRgba32f:
148
return RDC::DATA_FORMAT_R32G32B32A32_SFLOAT;
149
case SpvImageFormatRgba16f:
150
return RDC::DATA_FORMAT_R16G16B16A16_SFLOAT;
151
case SpvImageFormatR32f:
152
return RDC::DATA_FORMAT_R32_SFLOAT;
153
case SpvImageFormatRgba8:
154
return RDC::DATA_FORMAT_R8G8B8A8_UNORM;
155
case SpvImageFormatRgba8Snorm:
156
return RDC::DATA_FORMAT_R8G8B8A8_SNORM;
157
case SpvImageFormatRg32f:
158
return RDC::DATA_FORMAT_R32G32_SFLOAT;
159
case SpvImageFormatRg16f:
160
return RDC::DATA_FORMAT_R16G16_SFLOAT;
161
case SpvImageFormatR11fG11fB10f:
162
return RDC::DATA_FORMAT_B10G11R11_UFLOAT_PACK32;
163
case SpvImageFormatR16f:
164
return RDC::DATA_FORMAT_R16_SFLOAT;
165
case SpvImageFormatRgba16:
166
return RDC::DATA_FORMAT_R16G16B16A16_UNORM;
167
case SpvImageFormatRgb10A2:
168
return RDC::DATA_FORMAT_A2B10G10R10_UNORM_PACK32;
169
case SpvImageFormatRg16:
170
return RDC::DATA_FORMAT_R16G16_UNORM;
171
case SpvImageFormatRg8:
172
return RDC::DATA_FORMAT_R8G8_UNORM;
173
case SpvImageFormatR16:
174
return RDC::DATA_FORMAT_R16_UNORM;
175
case SpvImageFormatR8:
176
return RDC::DATA_FORMAT_R8_UNORM;
177
case SpvImageFormatRgba16Snorm:
178
return RDC::DATA_FORMAT_R16G16B16A16_SNORM;
179
case SpvImageFormatRg16Snorm:
180
return RDC::DATA_FORMAT_R16G16_SNORM;
181
case SpvImageFormatRg8Snorm:
182
return RDC::DATA_FORMAT_R8G8_SNORM;
183
case SpvImageFormatR16Snorm:
184
return RDC::DATA_FORMAT_R16_SNORM;
185
case SpvImageFormatR8Snorm:
186
return RDC::DATA_FORMAT_R8_SNORM;
187
case SpvImageFormatRgba32i:
188
return RDC::DATA_FORMAT_R32G32B32A32_SINT;
189
case SpvImageFormatRgba16i:
190
return RDC::DATA_FORMAT_R16G16B16A16_SINT;
191
case SpvImageFormatRgba8i:
192
return RDC::DATA_FORMAT_R8G8B8A8_SINT;
193
case SpvImageFormatR32i:
194
return RDC::DATA_FORMAT_R32_SINT;
195
case SpvImageFormatRg32i:
196
return RDC::DATA_FORMAT_R32G32_SINT;
197
case SpvImageFormatRg16i:
198
return RDC::DATA_FORMAT_R16G16_SINT;
199
case SpvImageFormatRg8i:
200
return RDC::DATA_FORMAT_R8G8_SINT;
201
case SpvImageFormatR16i:
202
return RDC::DATA_FORMAT_R16_SINT;
203
case SpvImageFormatR8i:
204
return RDC::DATA_FORMAT_R8_SINT;
205
case SpvImageFormatRgba32ui:
206
return RDC::DATA_FORMAT_R32G32B32A32_UINT;
207
case SpvImageFormatRgba16ui:
208
return RDC::DATA_FORMAT_R16G16B16A16_UINT;
209
case SpvImageFormatRgba8ui:
210
return RDC::DATA_FORMAT_R8G8B8A8_UINT;
211
case SpvImageFormatR32ui:
212
return RDC::DATA_FORMAT_R32_UINT;
213
case SpvImageFormatRgb10a2ui:
214
return RDC::DATA_FORMAT_A2B10G10R10_UINT_PACK32;
215
case SpvImageFormatRg32ui:
216
return RDC::DATA_FORMAT_R32G32_UINT;
217
case SpvImageFormatRg16ui:
218
return RDC::DATA_FORMAT_R16G16_UINT;
219
case SpvImageFormatRg8ui:
220
return RDC::DATA_FORMAT_R8G8_UINT;
221
case SpvImageFormatR16ui:
222
return RDC::DATA_FORMAT_R16_UINT;
223
case SpvImageFormatR8ui:
224
return RDC::DATA_FORMAT_R8_UINT;
225
case SpvImageFormatR64ui:
226
return RDC::DATA_FORMAT_R64_UINT;
227
case SpvImageFormatR64i:
228
return RDC::DATA_FORMAT_R64_SINT;
229
case SpvImageFormatMax:
230
return RDC::DATA_FORMAT_MAX;
231
}
232
return RDC::DATA_FORMAT_MAX;
233
}
234
235
Error RenderingShaderContainer::reflect_spirv(const String &p_shader_name, Span<RDC::ShaderStageSPIRVData> p_spirv, ReflectShader &r_shader) {
236
ReflectShader &reflection = r_shader;
237
238
shader_name = p_shader_name.utf8();
239
240
const uint32_t spirv_size = p_spirv.size() + 0;
241
242
LocalVector<ReflectShaderStage> &r_refl = r_shader.shader_stages;
243
r_refl.resize(spirv_size);
244
245
bool pipeline_type_detected = false;
246
for (uint32_t i = 0; i < spirv_size; i++) {
247
RDC::ShaderStage stage = p_spirv[i].shader_stage;
248
RDC::ShaderStage stage_flag = (RDC::ShaderStage)(1 << stage);
249
r_refl[i].shader_stage = stage;
250
r_refl[i]._spirv_data = p_spirv[i].spirv;
251
252
if (!pipeline_type_detected) {
253
switch (stage) {
254
case RDC::SHADER_STAGE_VERTEX:
255
case RDC::SHADER_STAGE_FRAGMENT:
256
case RDC::SHADER_STAGE_TESSELATION_CONTROL:
257
case RDC::SHADER_STAGE_TESSELATION_EVALUATION:
258
r_shader.pipeline_type = RDC::PIPELINE_TYPE_RASTERIZATION;
259
break;
260
case RDC::SHADER_STAGE_COMPUTE:
261
r_shader.pipeline_type = RDC::PIPELINE_TYPE_COMPUTE;
262
break;
263
case RDC::SHADER_STAGE_RAYGEN:
264
case RDC::SHADER_STAGE_ANY_HIT:
265
case RDC::SHADER_STAGE_CLOSEST_HIT:
266
case RDC::SHADER_STAGE_MISS:
267
case RDC::SHADER_STAGE_INTERSECTION:
268
r_shader.pipeline_type = RDC::PIPELINE_TYPE_RAYTRACING;
269
break;
270
default:
271
DEV_ASSERT(false && "Unknown shader stage.");
272
}
273
274
pipeline_type_detected = true;
275
}
276
277
const Vector<uint64_t> &dynamic_buffers = p_spirv[i].dynamic_buffers;
278
279
if (stage == RDC::SHADER_STAGE_COMPUTE) {
280
ERR_FAIL_COND_V_MSG(spirv_size != 1, FAILED,
281
"Compute shaders can only receive one stage, dedicated to compute.");
282
}
283
ERR_FAIL_COND_V_MSG(reflection.stages_bits.has_flag(stage_flag), FAILED,
284
"Stage " + String(RDC::SHADER_STAGE_NAMES[stage]) + " submitted more than once.");
285
reflection.stages_bits.set_flag(stage_flag);
286
287
{
288
SpvReflectShaderModule &module = *r_refl.ptr()[i]._module;
289
const uint8_t *spirv = p_spirv[i].spirv.ptr();
290
SpvReflectResult result = spvReflectCreateShaderModule2(SPV_REFLECT_MODULE_FLAG_NO_COPY, p_spirv[i].spirv.size(), spirv, &module);
291
ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,
292
"Reflection of SPIR-V shader stage '" + String(RDC::SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + "' failed parsing shader.");
293
294
for (uint32_t j = 0; j < module.capability_count; j++) {
295
if (module.capabilities[j].value == SpvCapabilityMultiView) {
296
reflection.has_multiview = true;
297
break;
298
}
299
}
300
301
if (reflection.is_compute()) {
302
reflection.compute_local_size[0] = module.entry_points->local_size.x;
303
reflection.compute_local_size[1] = module.entry_points->local_size.y;
304
reflection.compute_local_size[2] = module.entry_points->local_size.z;
305
}
306
uint32_t binding_count = 0;
307
result = spvReflectEnumerateDescriptorBindings(&module, &binding_count, nullptr);
308
ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,
309
"Reflection of SPIR-V shader stage '" + String(RDC::SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + "' failed enumerating descriptor bindings.");
310
311
if (binding_count > 0) {
312
// Parse bindings.
313
314
Vector<SpvReflectDescriptorBinding *> bindings;
315
bindings.resize(binding_count);
316
result = spvReflectEnumerateDescriptorBindings(&module, &binding_count, bindings.ptrw());
317
318
ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,
319
"Reflection of SPIR-V shader stage '" + String(RDC::SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + "' failed getting descriptor bindings.");
320
321
for (uint32_t j = 0; j < binding_count; j++) {
322
const SpvReflectDescriptorBinding &binding = *bindings[j];
323
324
ReflectUniform uniform;
325
uniform.set_spv_reflect(stage, &binding);
326
327
bool need_array_dimensions = false;
328
bool need_block_size = false;
329
bool may_be_writable = false;
330
bool is_image = false;
331
332
switch (binding.descriptor_type) {
333
case SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLER: {
334
uniform.type = RDC::UNIFORM_TYPE_SAMPLER;
335
need_array_dimensions = true;
336
} break;
337
case SPV_REFLECT_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: {
338
uniform.type = RDC::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;
339
need_array_dimensions = true;
340
is_image = true;
341
} break;
342
case SPV_REFLECT_DESCRIPTOR_TYPE_SAMPLED_IMAGE: {
343
uniform.type = RDC::UNIFORM_TYPE_TEXTURE;
344
need_array_dimensions = true;
345
is_image = true;
346
} break;
347
case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_IMAGE: {
348
uniform.type = RDC::UNIFORM_TYPE_IMAGE;
349
need_array_dimensions = true;
350
may_be_writable = true;
351
is_image = true;
352
} break;
353
case SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: {
354
uniform.type = RDC::UNIFORM_TYPE_TEXTURE_BUFFER;
355
need_array_dimensions = true;
356
is_image = true;
357
} break;
358
case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: {
359
uniform.type = RDC::UNIFORM_TYPE_IMAGE_BUFFER;
360
need_array_dimensions = true;
361
may_be_writable = true;
362
is_image = true;
363
} break;
364
case SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_BUFFER: {
365
const uint64_t key = ShaderRD::DynamicBuffer::encode(binding.set, binding.binding);
366
if (dynamic_buffers.has(key)) {
367
uniform.type = RDC::UNIFORM_TYPE_UNIFORM_BUFFER_DYNAMIC;
368
reflection.has_dynamic_buffers = true;
369
} else {
370
uniform.type = RDC::UNIFORM_TYPE_UNIFORM_BUFFER;
371
}
372
need_block_size = true;
373
} break;
374
case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER: {
375
const uint64_t key = ShaderRD::DynamicBuffer::encode(binding.set, binding.binding);
376
if (dynamic_buffers.has(key)) {
377
uniform.type = RDC::UNIFORM_TYPE_STORAGE_BUFFER_DYNAMIC;
378
reflection.has_dynamic_buffers = true;
379
} else {
380
uniform.type = RDC::UNIFORM_TYPE_STORAGE_BUFFER;
381
}
382
need_block_size = true;
383
may_be_writable = true;
384
} break;
385
case SPV_REFLECT_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: {
386
ERR_PRINT("Dynamic uniform buffer not supported.");
387
continue;
388
} break;
389
case SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: {
390
ERR_PRINT("Dynamic storage buffer not supported.");
391
continue;
392
} break;
393
case SPV_REFLECT_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: {
394
uniform.type = RDC::UNIFORM_TYPE_INPUT_ATTACHMENT;
395
need_array_dimensions = true;
396
is_image = true;
397
} break;
398
case SPV_REFLECT_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR: {
399
uniform.type = RDC::UNIFORM_TYPE_ACCELERATION_STRUCTURE;
400
} break;
401
}
402
403
if (need_array_dimensions) {
404
uniform.length = 1;
405
for (uint32_t k = 0; k < binding.array.dims_count; k++) {
406
uniform.length *= binding.array.dims[k];
407
}
408
} else if (need_block_size) {
409
uniform.length = binding.block.size;
410
} else {
411
uniform.length = 0;
412
}
413
414
if (may_be_writable) {
415
if (binding.descriptor_type == SPV_REFLECT_DESCRIPTOR_TYPE_STORAGE_IMAGE) {
416
uniform.writable = !(binding.decoration_flags & SPV_REFLECT_DECORATION_NON_WRITABLE);
417
} else {
418
uniform.writable = !(binding.decoration_flags & SPV_REFLECT_DECORATION_NON_WRITABLE) && !(binding.block.decoration_flags & SPV_REFLECT_DECORATION_NON_WRITABLE);
419
}
420
} else {
421
uniform.writable = false;
422
}
423
424
if (is_image) {
425
uniform.image.format = spv_image_format_to_data_format(binding.image.image_format);
426
}
427
428
uniform.binding = binding.binding;
429
uint32_t set = binding.set;
430
431
ERR_FAIL_COND_V_MSG(set >= RDC::MAX_UNIFORM_SETS, FAILED,
432
"On shader stage '" + String(RDC::SHADER_STAGE_NAMES[stage]) + "', uniform '" + binding.name + "' uses a set (" + itos(set) + ") index larger than what is supported (" + itos(RDC::MAX_UNIFORM_SETS) + ").");
433
434
if (set < (uint32_t)reflection.uniform_sets.size()) {
435
// Check if this already exists.
436
bool exists = false;
437
for (uint32_t k = 0; k < reflection.uniform_sets[set].size(); k++) {
438
if (reflection.uniform_sets[set][k].binding == uniform.binding) {
439
// Already exists, verify that it's the same type.
440
ERR_FAIL_COND_V_MSG(reflection.uniform_sets[set][k].type != uniform.type, FAILED,
441
"On shader stage '" + String(RDC::SHADER_STAGE_NAMES[stage]) + "', uniform '" + binding.name + "' trying to reuse location for set=" + itos(set) + ", binding=" + itos(uniform.binding) + " with different uniform type.");
442
443
// Also, verify that it's the same size.
444
ERR_FAIL_COND_V_MSG(reflection.uniform_sets[set][k].length != uniform.length, FAILED,
445
"On shader stage '" + String(RDC::SHADER_STAGE_NAMES[stage]) + "', uniform '" + binding.name + "' trying to reuse location for set=" + itos(set) + ", binding=" + itos(uniform.binding) + " with different uniform size.");
446
447
// Also, verify that it has the same writability.
448
ERR_FAIL_COND_V_MSG(reflection.uniform_sets[set][k].writable != uniform.writable, FAILED,
449
"On shader stage '" + String(RDC::SHADER_STAGE_NAMES[stage]) + "', uniform '" + binding.name + "' trying to reuse location for set=" + itos(set) + ", binding=" + itos(uniform.binding) + " with different writability.");
450
451
// Just append stage mask and return.
452
reflection.uniform_sets[set][k].stages.set_flag(stage_flag);
453
exists = true;
454
break;
455
}
456
}
457
458
if (exists) {
459
continue; // Merged.
460
}
461
}
462
463
uniform.stages.set_flag(stage_flag);
464
465
if (set >= (uint32_t)reflection.uniform_sets.size()) {
466
reflection.uniform_sets.resize(set + 1);
467
}
468
469
reflection.uniform_sets[set].push_back(uniform);
470
}
471
}
472
473
{
474
// Specialization constants.
475
476
uint32_t sc_count = 0;
477
result = spvReflectEnumerateSpecializationConstants(&module, &sc_count, nullptr);
478
ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,
479
"Reflection of SPIR-V shader stage '" + String(RDC::SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + "' failed enumerating specialization constants.");
480
481
if (sc_count) {
482
Vector<SpvReflectSpecializationConstant *> spec_constants;
483
spec_constants.resize(sc_count);
484
485
result = spvReflectEnumerateSpecializationConstants(&module, &sc_count, spec_constants.ptrw());
486
ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,
487
"Reflection of SPIR-V shader stage '" + String(RDC::SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + "' failed obtaining specialization constants.");
488
489
for (uint32_t j = 0; j < sc_count; j++) {
490
int32_t existing = -1;
491
ReflectSpecializationConstant sconst;
492
SpvReflectSpecializationConstant *spc = spec_constants[j];
493
sconst.set_spv_reflect(stage, spc);
494
495
if (spc->default_value_size != 4) {
496
ERR_FAIL_V_MSG(FAILED, vformat("Reflection of SPIR-V shader stage '%s' failed because the specialization constant #%d's default value is not 4 bytes long (%d) and is currently not supported.", RDC::SHADER_STAGE_NAMES[p_spirv[i].shader_stage], spc->constant_id, spc->default_value_size));
497
}
498
499
sconst.constant_id = spc->constant_id;
500
sconst.int_value = 0; // Clear previous value JIC.
501
502
switch (spc->type_description->op) {
503
case SpvOpTypeBool:
504
sconst.type = RDC::PIPELINE_SPECIALIZATION_CONSTANT_TYPE_BOOL;
505
sconst.bool_value = *(uint32_t *)(spc->default_value);
506
break;
507
case SpvOpTypeInt:
508
sconst.type = RDC::PIPELINE_SPECIALIZATION_CONSTANT_TYPE_INT;
509
sconst.int_value = *(uint32_t *)(spc->default_value);
510
break;
511
case SpvOpTypeFloat:
512
sconst.type = RDC::PIPELINE_SPECIALIZATION_CONSTANT_TYPE_FLOAT;
513
sconst.float_value = *(float *)(spc->default_value);
514
break;
515
default:
516
ERR_FAIL_V_MSG(FAILED, vformat("Reflection of SPIR-V shader stage '%s' failed because the specialization constant #%d does not use a known operation (%d).", RDC::SHADER_STAGE_NAMES[p_spirv[i].shader_stage], spc->constant_id, spc->type_description->op));
517
break;
518
}
519
520
sconst.stages.set_flag(stage_flag);
521
522
for (uint32_t k = 0; k < reflection.specialization_constants.size(); k++) {
523
if (reflection.specialization_constants[k].constant_id == sconst.constant_id) {
524
ERR_FAIL_COND_V_MSG(reflection.specialization_constants[k].type != sconst.type, FAILED, "More than one specialization constant used for id (" + itos(sconst.constant_id) + "), but their types differ.");
525
ERR_FAIL_COND_V_MSG(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.");
526
existing = k;
527
break;
528
}
529
}
530
531
if (existing >= 0) {
532
reflection.specialization_constants[existing].stages.set_flag(stage_flag);
533
} else {
534
reflection.specialization_constants.push_back(sconst);
535
}
536
}
537
538
reflection.specialization_constants.sort();
539
}
540
}
541
542
if (stage == RDC::SHADER_STAGE_VERTEX || stage == RDC::SHADER_STAGE_FRAGMENT) {
543
uint32_t iv_count = 0;
544
result = spvReflectEnumerateInputVariables(&module, &iv_count, nullptr);
545
ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,
546
"Reflection of SPIR-V shader stage '" + String(RDC::SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + "' failed enumerating input variables.");
547
548
if (iv_count) {
549
Vector<SpvReflectInterfaceVariable *> input_vars;
550
input_vars.resize(iv_count);
551
552
result = spvReflectEnumerateInputVariables(&module, &iv_count, input_vars.ptrw());
553
ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,
554
"Reflection of SPIR-V shader stage '" + String(RDC::SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + "' failed obtaining input variables.");
555
556
for (const SpvReflectInterfaceVariable *v : input_vars) {
557
if (!v) {
558
continue;
559
}
560
if (stage == RDC::SHADER_STAGE_VERTEX) {
561
if (v->decoration_flags == 0) { // Regular input.
562
reflection.vertex_input_mask |= (((uint64_t)1) << v->location);
563
}
564
}
565
if (v->built_in == SpvBuiltInViewIndex) {
566
reflection.has_multiview = true;
567
}
568
}
569
}
570
}
571
572
if (stage == RDC::SHADER_STAGE_FRAGMENT) {
573
uint32_t ov_count = 0;
574
result = spvReflectEnumerateOutputVariables(&module, &ov_count, nullptr);
575
ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,
576
"Reflection of SPIR-V shader stage '" + String(RDC::SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + "' failed enumerating output variables.");
577
578
if (ov_count) {
579
Vector<SpvReflectInterfaceVariable *> output_vars;
580
output_vars.resize(ov_count);
581
582
result = spvReflectEnumerateOutputVariables(&module, &ov_count, output_vars.ptrw());
583
ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,
584
"Reflection of SPIR-V shader stage '" + String(RDC::SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + "' failed obtaining output variables.");
585
586
for (const SpvReflectInterfaceVariable *refvar : output_vars) {
587
if (!refvar) {
588
continue;
589
}
590
if (refvar->built_in != SpvBuiltInFragDepth) {
591
reflection.fragment_output_mask |= 1 << refvar->location;
592
}
593
}
594
}
595
}
596
597
uint32_t pc_count = 0;
598
result = spvReflectEnumeratePushConstantBlocks(&module, &pc_count, nullptr);
599
ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,
600
"Reflection of SPIR-V shader stage '" + String(RDC::SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + "' failed enumerating push constants.");
601
602
if (pc_count) {
603
ERR_FAIL_COND_V_MSG(pc_count > 1, FAILED,
604
"Reflection of SPIR-V shader stage '" + String(RDC::SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + "': Only one push constant is supported, which should be the same across shader stages.");
605
606
Vector<SpvReflectBlockVariable *> pconstants;
607
pconstants.resize(pc_count);
608
result = spvReflectEnumeratePushConstantBlocks(&module, &pc_count, pconstants.ptrw());
609
ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, FAILED,
610
"Reflection of SPIR-V shader stage '" + String(RDC::SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + "' failed obtaining push constants.");
611
#if 0
612
if (pconstants[0] == nullptr) {
613
Ref<FileAccess> f = FileAccess::open("res://popo.spv", FileAccess::WRITE);
614
f->store_buffer((const uint8_t *)&SpirV[0], SpirV.size() * sizeof(uint32_t));
615
}
616
#endif
617
618
ERR_FAIL_COND_V_MSG(reflection.push_constant_size && reflection.push_constant_size != pconstants[0]->size, FAILED,
619
"Reflection of SPIR-V shader stage '" + String(RDC::SHADER_STAGE_NAMES[p_spirv[i].shader_stage]) + "': Push constant block must be the same across shader stages.");
620
621
reflection.push_constant_size = pconstants[0]->size;
622
reflection.push_constant_stages.set_flag(stage_flag);
623
624
//print_line("Stage: " + String(RDC::SHADER_STAGE_NAMES[stage]) + " push constant of size=" + itos(push_constant.push_constant_size));
625
}
626
}
627
}
628
629
// Sort all uniform_sets by binding.
630
for (uint32_t i = 0; i < reflection.uniform_sets.size(); i++) {
631
reflection.uniform_sets[i].sort();
632
}
633
634
set_from_shader_reflection(reflection);
635
636
return OK;
637
}
638
639
void RenderingShaderContainer::set_from_shader_reflection(const ReflectShader &p_reflection) {
640
reflection_binding_set_uniforms_count.clear();
641
reflection_binding_set_uniforms_data.clear();
642
reflection_specialization_data.clear();
643
reflection_shader_stages.clear();
644
645
reflection_data.vertex_input_mask = p_reflection.vertex_input_mask;
646
reflection_data.fragment_output_mask = p_reflection.fragment_output_mask;
647
reflection_data.specialization_constants_count = p_reflection.specialization_constants.size();
648
reflection_data.pipeline_type = p_reflection.pipeline_type;
649
reflection_data.has_multiview = p_reflection.has_multiview;
650
reflection_data.has_dynamic_buffers = p_reflection.has_dynamic_buffers;
651
reflection_data.compute_local_size[0] = p_reflection.compute_local_size[0];
652
reflection_data.compute_local_size[1] = p_reflection.compute_local_size[1];
653
reflection_data.compute_local_size[2] = p_reflection.compute_local_size[2];
654
reflection_data.set_count = p_reflection.uniform_sets.size();
655
reflection_data.push_constant_size = p_reflection.push_constant_size;
656
reflection_data.push_constant_stages_mask = uint32_t(p_reflection.push_constant_stages);
657
reflection_data.shader_name_len = shader_name.length();
658
659
ReflectionBindingData binding_data;
660
for (const ReflectDescriptorSet &uniform_set : p_reflection.uniform_sets) {
661
for (const ReflectUniform &uniform : uniform_set) {
662
binding_data.type = uint32_t(uniform.type);
663
binding_data.binding = uniform.binding;
664
binding_data.stages = uint32_t(uniform.stages);
665
binding_data.length = uniform.length;
666
binding_data.writable = uint32_t(uniform.writable);
667
reflection_binding_set_uniforms_data.push_back(binding_data);
668
}
669
670
reflection_binding_set_uniforms_count.push_back(uniform_set.size());
671
}
672
673
ReflectionSpecializationData specialization_data;
674
for (const ReflectSpecializationConstant &spec : p_reflection.specialization_constants) {
675
specialization_data.type = uint32_t(spec.type);
676
specialization_data.constant_id = spec.constant_id;
677
specialization_data.int_value = spec.int_value;
678
specialization_data.stage_flags = uint32_t(spec.stages);
679
reflection_specialization_data.push_back(specialization_data);
680
}
681
682
for (uint32_t i = 0; i < RDC::SHADER_STAGE_MAX; i++) {
683
if (p_reflection.stages_bits.has_flag(RDC::ShaderStage(1U << i))) {
684
reflection_shader_stages.push_back(RDC::ShaderStage(i));
685
}
686
}
687
688
reflection_data.stage_count = reflection_shader_stages.size();
689
690
_set_from_shader_reflection_post(p_reflection);
691
}
692
693
bool RenderingShaderContainer::set_code_from_spirv(const String &p_shader_name, Span<RDC::ShaderStageSPIRVData> p_spirv) {
694
ReflectShader shader;
695
ERR_FAIL_COND_V(reflect_spirv(p_shader_name, p_spirv, shader) != OK, false);
696
return _set_code_from_spirv(shader);
697
}
698
699
RenderingDeviceCommons::ShaderReflection RenderingShaderContainer::get_shader_reflection() const {
700
RDC::ShaderReflection shader_refl;
701
shader_refl.push_constant_size = reflection_data.push_constant_size;
702
shader_refl.push_constant_stages = reflection_data.push_constant_stages_mask;
703
shader_refl.vertex_input_mask = reflection_data.vertex_input_mask;
704
shader_refl.fragment_output_mask = reflection_data.fragment_output_mask;
705
shader_refl.pipeline_type = reflection_data.pipeline_type;
706
shader_refl.has_multiview = reflection_data.has_multiview;
707
shader_refl.has_dynamic_buffers = reflection_data.has_dynamic_buffers;
708
shader_refl.compute_local_size[0] = reflection_data.compute_local_size[0];
709
shader_refl.compute_local_size[1] = reflection_data.compute_local_size[1];
710
shader_refl.compute_local_size[2] = reflection_data.compute_local_size[2];
711
shader_refl.uniform_sets.resize(reflection_data.set_count);
712
shader_refl.specialization_constants.resize(reflection_data.specialization_constants_count);
713
shader_refl.stages_vector.resize(reflection_data.stage_count);
714
715
DEV_ASSERT(reflection_binding_set_uniforms_count.size() == reflection_data.set_count && "The amount of elements in the reflection and the shader container can't be different.");
716
uint32_t uniform_index = 0;
717
for (uint32_t i = 0; i < reflection_data.set_count; i++) {
718
Vector<RDC::ShaderUniform> &uniform_set = shader_refl.uniform_sets.ptrw()[i];
719
uint32_t uniforms_count = reflection_binding_set_uniforms_count[i];
720
uniform_set.resize(uniforms_count);
721
for (uint32_t j = 0; j < uniforms_count; j++) {
722
const ReflectionBindingData &binding = reflection_binding_set_uniforms_data[uniform_index++];
723
RDC::ShaderUniform &uniform = uniform_set.ptrw()[j];
724
uniform.type = RDC::UniformType(binding.type);
725
uniform.writable = binding.writable;
726
uniform.length = binding.length;
727
uniform.binding = binding.binding;
728
uniform.stages = binding.stages;
729
}
730
}
731
732
shader_refl.specialization_constants.resize(reflection_data.specialization_constants_count);
733
for (uint32_t i = 0; i < reflection_data.specialization_constants_count; i++) {
734
const ReflectionSpecializationData &spec = reflection_specialization_data[i];
735
RDC::ShaderSpecializationConstant &sc = shader_refl.specialization_constants.ptrw()[i];
736
sc.type = RDC::PipelineSpecializationConstantType(spec.type);
737
sc.constant_id = spec.constant_id;
738
sc.int_value = spec.int_value;
739
sc.stages = spec.stage_flags;
740
}
741
742
shader_refl.stages_vector.resize(reflection_data.stage_count);
743
for (uint32_t i = 0; i < reflection_data.stage_count; i++) {
744
shader_refl.stages_vector.set(i, reflection_shader_stages[i]);
745
shader_refl.stages_bits.set_flag(RDC::ShaderStage(1U << reflection_shader_stages[i]));
746
}
747
748
return shader_refl;
749
}
750
751
bool RenderingShaderContainer::from_bytes(const PackedByteArray &p_bytes) {
752
const uint64_t alignment = sizeof(uint32_t);
753
const uint8_t *bytes_ptr = p_bytes.ptr();
754
uint64_t bytes_offset = 0;
755
756
// Read container header.
757
ERR_FAIL_COND_V_MSG(int64_t(bytes_offset + sizeof(ContainerHeader)) > p_bytes.size(), false, "Not enough bytes for a container header in shader container.");
758
const ContainerHeader &container_header = *(const ContainerHeader *)(&bytes_ptr[bytes_offset]);
759
bytes_offset += sizeof(ContainerHeader);
760
bytes_offset += _from_bytes_header_extra_data(&bytes_ptr[bytes_offset]);
761
762
ERR_FAIL_COND_V_MSG(container_header.magic_number != CONTAINER_MAGIC_NUMBER, false, "Incorrect magic number in shader container.");
763
ERR_FAIL_COND_V_MSG(container_header.version > CONTAINER_VERSION, false, "Unsupported version in shader container.");
764
ERR_FAIL_COND_V_MSG(container_header.format != _format(), false, "Incorrect format in shader container.");
765
ERR_FAIL_COND_V_MSG(container_header.format_version > _format_version(), false, "Unsupported format version in shader container.");
766
767
// Adjust shaders to the size indicated by the container header.
768
shaders.resize(container_header.shader_count);
769
770
// Read reflection data.
771
ERR_FAIL_COND_V_MSG(int64_t(bytes_offset + sizeof(ReflectionData)) > p_bytes.size(), false, "Not enough bytes for reflection data in shader container.");
772
reflection_data = *(const ReflectionData *)(&bytes_ptr[bytes_offset]);
773
bytes_offset += sizeof(ReflectionData);
774
bytes_offset += _from_bytes_reflection_extra_data(&bytes_ptr[bytes_offset]);
775
776
// Read shader name.
777
ERR_FAIL_COND_V_MSG(int64_t(bytes_offset + reflection_data.shader_name_len) > p_bytes.size(), false, "Not enough bytes for shader name in shader container.");
778
if (reflection_data.shader_name_len > 0) {
779
String shader_name_str;
780
shader_name_str.append_utf8((const char *)(&bytes_ptr[bytes_offset]), reflection_data.shader_name_len);
781
shader_name = shader_name_str.utf8();
782
bytes_offset = aligned_to(bytes_offset + reflection_data.shader_name_len, alignment);
783
} else {
784
shader_name = CharString();
785
}
786
787
reflection_binding_set_uniforms_count.resize(reflection_data.set_count);
788
reflection_binding_set_uniforms_data.clear();
789
790
uint32_t uniform_index = 0;
791
for (uint32_t i = 0; i < reflection_data.set_count; i++) {
792
ERR_FAIL_COND_V_MSG(int64_t(bytes_offset + sizeof(uint32_t)) > p_bytes.size(), false, "Not enough bytes for uniform set count in shader container.");
793
uint32_t uniforms_count = *(uint32_t *)(&bytes_ptr[bytes_offset]);
794
reflection_binding_set_uniforms_count.ptrw()[i] = uniforms_count;
795
bytes_offset += sizeof(uint32_t);
796
797
reflection_binding_set_uniforms_data.resize(reflection_binding_set_uniforms_data.size() + uniforms_count);
798
bytes_offset += _from_bytes_reflection_binding_uniform_extra_data_start(&bytes_ptr[bytes_offset]);
799
800
for (uint32_t j = 0; j < uniforms_count; j++) {
801
ERR_FAIL_COND_V_MSG(int64_t(bytes_offset + sizeof(ReflectionBindingData)) > p_bytes.size(), false, "Not enough bytes for uniform in shader container.");
802
memcpy(&reflection_binding_set_uniforms_data.ptrw()[uniform_index], &bytes_ptr[bytes_offset], sizeof(ReflectionBindingData));
803
bytes_offset += sizeof(ReflectionBindingData);
804
bytes_offset += _from_bytes_reflection_binding_uniform_extra_data(&bytes_ptr[bytes_offset], uniform_index);
805
uniform_index++;
806
}
807
}
808
809
reflection_specialization_data.resize(reflection_data.specialization_constants_count);
810
bytes_offset += _from_bytes_reflection_specialization_extra_data_start(&bytes_ptr[bytes_offset]);
811
812
for (uint32_t i = 0; i < reflection_data.specialization_constants_count; i++) {
813
ERR_FAIL_COND_V_MSG(int64_t(bytes_offset + sizeof(ReflectionSpecializationData)) > p_bytes.size(), false, "Not enough bytes for specialization in shader container.");
814
memcpy(&reflection_specialization_data.ptrw()[i], &bytes_ptr[bytes_offset], sizeof(ReflectionSpecializationData));
815
bytes_offset += sizeof(ReflectionSpecializationData);
816
bytes_offset += _from_bytes_reflection_specialization_extra_data(&bytes_ptr[bytes_offset], i);
817
}
818
819
const uint32_t stage_count = reflection_data.stage_count;
820
if (stage_count > 0) {
821
ERR_FAIL_COND_V_MSG(int64_t(bytes_offset + stage_count * sizeof(RDC::ShaderStage)) > p_bytes.size(), false, "Not enough bytes for stages in shader container.");
822
reflection_shader_stages.resize(stage_count);
823
bytes_offset += _from_bytes_shader_extra_data_start(&bytes_ptr[bytes_offset]);
824
memcpy(reflection_shader_stages.ptrw(), &bytes_ptr[bytes_offset], stage_count * sizeof(RDC::ShaderStage));
825
bytes_offset += stage_count * sizeof(RDC::ShaderStage);
826
}
827
828
// Read shaders.
829
for (int64_t i = 0; i < shaders.size(); i++) {
830
ERR_FAIL_COND_V_MSG(int64_t(bytes_offset + sizeof(ShaderHeader)) > p_bytes.size(), false, "Not enough bytes for shader header in shader container.");
831
const ShaderHeader &header = *(const ShaderHeader *)(&bytes_ptr[bytes_offset]);
832
bytes_offset += sizeof(ShaderHeader);
833
834
ERR_FAIL_COND_V_MSG(int64_t(bytes_offset + header.code_compressed_size) > p_bytes.size(), false, "Not enough bytes for a shader in shader container.");
835
Shader &shader = shaders.ptrw()[i];
836
shader.shader_stage = RDC::ShaderStage(header.shader_stage);
837
shader.code_compression_flags = header.code_compression_flags;
838
shader.code_decompressed_size = header.code_decompressed_size;
839
shader.code_compressed_bytes.resize(header.code_compressed_size);
840
memcpy(shader.code_compressed_bytes.ptrw(), &bytes_ptr[bytes_offset], header.code_compressed_size);
841
bytes_offset = aligned_to(bytes_offset + header.code_compressed_size, alignment);
842
bytes_offset += _from_bytes_shader_extra_data(&bytes_ptr[bytes_offset], i);
843
}
844
845
bytes_offset += _from_bytes_footer_extra_data(&bytes_ptr[bytes_offset]);
846
847
ERR_FAIL_COND_V_MSG(bytes_offset != (uint64_t)p_bytes.size(), false, "Amount of bytes in the container does not match the amount of bytes read.");
848
return true;
849
}
850
851
PackedByteArray RenderingShaderContainer::to_bytes() const {
852
// Compute the exact size the container will require for writing everything out.
853
const uint64_t alignment = sizeof(uint32_t);
854
uint64_t total_size = 0;
855
total_size += sizeof(ContainerHeader) + _to_bytes_header_extra_data(nullptr);
856
total_size += sizeof(ReflectionData) + _to_bytes_reflection_extra_data(nullptr);
857
total_size += aligned_to(reflection_data.shader_name_len, alignment);
858
total_size += reflection_binding_set_uniforms_count.size() * sizeof(uint32_t);
859
total_size += reflection_binding_set_uniforms_data.size() * sizeof(ReflectionBindingData);
860
total_size += reflection_specialization_data.size() * sizeof(ReflectionSpecializationData);
861
total_size += reflection_shader_stages.size() * sizeof(RDC::ShaderStage);
862
863
for (uint32_t i = 0; i < reflection_binding_set_uniforms_data.size(); i++) {
864
total_size += _to_bytes_reflection_binding_uniform_extra_data(nullptr, i);
865
}
866
867
for (uint32_t i = 0; i < reflection_specialization_data.size(); i++) {
868
total_size += _to_bytes_reflection_specialization_extra_data(nullptr, i);
869
}
870
871
for (uint32_t i = 0; i < shaders.size(); i++) {
872
total_size += sizeof(ShaderHeader);
873
total_size += shaders[i].code_compressed_bytes.size();
874
total_size = aligned_to(total_size, alignment);
875
total_size += _to_bytes_shader_extra_data(nullptr, i);
876
}
877
878
total_size += _to_bytes_footer_extra_data(nullptr);
879
880
// Create the array that will hold all of the data.
881
PackedByteArray bytes;
882
bytes.resize_initialized(total_size);
883
884
// Write out the data to the array.
885
uint64_t bytes_offset = 0;
886
uint8_t *bytes_ptr = bytes.ptrw();
887
ContainerHeader &container_header = *(ContainerHeader *)(&bytes_ptr[bytes_offset]);
888
container_header.magic_number = CONTAINER_MAGIC_NUMBER;
889
container_header.version = CONTAINER_VERSION;
890
container_header.format = _format();
891
container_header.format_version = _format_version();
892
container_header.shader_count = shaders.size();
893
bytes_offset += sizeof(ContainerHeader);
894
bytes_offset += _to_bytes_header_extra_data(&bytes_ptr[bytes_offset]);
895
896
memcpy(&bytes_ptr[bytes_offset], &reflection_data, sizeof(ReflectionData));
897
bytes_offset += sizeof(ReflectionData);
898
bytes_offset += _to_bytes_reflection_extra_data(&bytes_ptr[bytes_offset]);
899
900
if (shader_name.size() > 0) {
901
memcpy(&bytes_ptr[bytes_offset], shader_name.ptr(), reflection_data.shader_name_len);
902
bytes_offset = aligned_to(bytes_offset + reflection_data.shader_name_len, alignment);
903
}
904
905
uint32_t uniform_index = 0;
906
for (uint32_t uniform_count : reflection_binding_set_uniforms_count) {
907
memcpy(&bytes_ptr[bytes_offset], &uniform_count, sizeof(uniform_count));
908
bytes_offset += sizeof(uint32_t);
909
910
for (uint32_t i = 0; i < uniform_count; i++) {
911
memcpy(&bytes_ptr[bytes_offset], &reflection_binding_set_uniforms_data[uniform_index], sizeof(ReflectionBindingData));
912
bytes_offset += sizeof(ReflectionBindingData);
913
bytes_offset += _to_bytes_reflection_binding_uniform_extra_data(&bytes_ptr[bytes_offset], uniform_index);
914
uniform_index++;
915
}
916
}
917
918
for (uint32_t i = 0; i < reflection_specialization_data.size(); i++) {
919
memcpy(&bytes_ptr[bytes_offset], &reflection_specialization_data.ptr()[i], sizeof(ReflectionSpecializationData));
920
bytes_offset += sizeof(ReflectionSpecializationData);
921
bytes_offset += _to_bytes_reflection_specialization_extra_data(&bytes_ptr[bytes_offset], i);
922
}
923
924
if (!reflection_shader_stages.is_empty()) {
925
uint32_t stage_count = reflection_shader_stages.size();
926
memcpy(&bytes_ptr[bytes_offset], reflection_shader_stages.ptr(), stage_count * sizeof(RDC::ShaderStage));
927
bytes_offset += stage_count * sizeof(RDC::ShaderStage);
928
}
929
930
for (uint32_t i = 0; i < shaders.size(); i++) {
931
const Shader &shader = shaders[i];
932
ShaderHeader &header = *(ShaderHeader *)(&bytes.ptr()[bytes_offset]);
933
header.shader_stage = shader.shader_stage;
934
header.code_compressed_size = uint32_t(shader.code_compressed_bytes.size());
935
header.code_compression_flags = shader.code_compression_flags;
936
header.code_decompressed_size = shader.code_decompressed_size;
937
bytes_offset += sizeof(ShaderHeader);
938
memcpy(&bytes.ptrw()[bytes_offset], shader.code_compressed_bytes.ptr(), shader.code_compressed_bytes.size());
939
bytes_offset = aligned_to(bytes_offset + shader.code_compressed_bytes.size(), alignment);
940
bytes_offset += _to_bytes_shader_extra_data(&bytes_ptr[bytes_offset], i);
941
}
942
943
bytes_offset += _to_bytes_footer_extra_data(&bytes_ptr[bytes_offset]);
944
945
ERR_FAIL_COND_V_MSG(bytes_offset != total_size, PackedByteArray(), "Amount of bytes written does not match the amount of bytes reserved for the container.");
946
return bytes;
947
}
948
949
bool RenderingShaderContainer::compress_code(const uint8_t *p_decompressed_bytes, uint32_t p_decompressed_size, uint8_t *p_compressed_bytes, uint32_t *r_compressed_size, uint32_t *r_compressed_flags) const {
950
DEV_ASSERT(p_decompressed_bytes != nullptr);
951
DEV_ASSERT(p_decompressed_size > 0);
952
DEV_ASSERT(p_compressed_bytes != nullptr);
953
DEV_ASSERT(r_compressed_size != nullptr);
954
DEV_ASSERT(r_compressed_flags != nullptr);
955
956
*r_compressed_flags = 0;
957
958
PackedByteArray zstd_bytes;
959
const int64_t zstd_max_bytes = Compression::get_max_compressed_buffer_size(p_decompressed_size, Compression::MODE_ZSTD);
960
zstd_bytes.resize(zstd_max_bytes);
961
962
const int64_t zstd_size = Compression::compress(zstd_bytes.ptrw(), p_decompressed_bytes, p_decompressed_size, Compression::MODE_ZSTD);
963
if (zstd_size > 0 && (uint32_t)(zstd_size) < p_decompressed_size) {
964
// Only choose Zstd if it results in actual compression.
965
memcpy(p_compressed_bytes, zstd_bytes.ptr(), zstd_size);
966
*r_compressed_size = zstd_size;
967
*r_compressed_flags |= COMPRESSION_FLAG_ZSTD;
968
} else {
969
// Just copy the input to the output directly.
970
memcpy(p_compressed_bytes, p_decompressed_bytes, p_decompressed_size);
971
*r_compressed_size = p_decompressed_size;
972
}
973
974
return true;
975
}
976
977
bool RenderingShaderContainer::decompress_code(const uint8_t *p_compressed_bytes, uint32_t p_compressed_size, uint32_t p_compressed_flags, uint8_t *p_decompressed_bytes, uint32_t p_decompressed_size) const {
978
DEV_ASSERT(p_compressed_bytes != nullptr);
979
DEV_ASSERT(p_compressed_size > 0);
980
DEV_ASSERT(p_decompressed_bytes != nullptr);
981
DEV_ASSERT(p_decompressed_size > 0);
982
983
bool uses_zstd = p_compressed_flags & COMPRESSION_FLAG_ZSTD;
984
if (uses_zstd) {
985
if (!Compression::decompress(p_decompressed_bytes, p_decompressed_size, p_compressed_bytes, p_compressed_size, Compression::MODE_ZSTD)) {
986
ERR_FAIL_V_MSG(false, "Malformed zstd input for decompressing shader code.");
987
}
988
} else {
989
memcpy(p_decompressed_bytes, p_compressed_bytes, MIN(p_compressed_size, p_decompressed_size));
990
}
991
992
return true;
993
}
994
995
RenderingShaderContainer::RenderingShaderContainer() {}
996
997
RenderingShaderContainer::~RenderingShaderContainer() {}
998
999