Blender V4.3
gpu_shader_create_info.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2021 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
11#include "BLI_map.hh"
12#include "BLI_set.hh"
13#include "BLI_string_ref.hh"
14#include "BLI_threads.h"
15
16#include "BKE_global.hh"
17
18#include "GPU_capabilities.hh"
19#include "GPU_context.hh"
20#include "GPU_platform.hh"
21#include "GPU_shader.hh"
22#include "GPU_texture.hh"
23
27
28#undef GPU_SHADER_INTERFACE_INFO
29#undef GPU_SHADER_CREATE_INFO
30
31namespace blender::gpu::shader {
32
36
40
41/* -------------------------------------------------------------------- */
47{
48 if (iface.instance_name.is_empty()) {
49 return true;
50 }
51
52 bool use_flat = false;
53 bool use_smooth = false;
54 bool use_noperspective = false;
55 for (const StageInterfaceInfo::InOut &attr : iface.inouts) {
56 switch (attr.interp) {
58 use_flat = true;
59 break;
61 use_smooth = true;
62 break;
64 use_noperspective = true;
65 break;
66 }
67 }
68 int num_used_interpolation_types = (use_flat ? 1 : 0) + (use_smooth ? 1 : 0) +
69 (use_noperspective ? 1 : 0);
70
71#if 0
72 if (num_used_interpolation_types > 1) {
73 std::cout << "'" << iface.name << "' uses multiple interpolation types\n";
74 }
75#endif
76
77 return num_used_interpolation_types <= 1;
78}
79
81{
82 /* Vulkan doesn't support setting an interpolation mode per attribute in a struct. */
83 for (const StageInterfaceInfo *iface : vertex_out_interfaces_) {
84 if (!is_vulkan_compatible_interface(*iface)) {
85 return false;
86 }
87 }
88 for (const StageInterfaceInfo *iface : geometry_out_interfaces_) {
89 if (!is_vulkan_compatible_interface(*iface)) {
90 return false;
91 }
92 }
93
94 return true;
95}
96
99void ShaderCreateInfo::finalize(const bool recursive)
100{
101 if (finalized_) {
102 return;
103 }
104 finalized_ = true;
105
106 Set<StringRefNull> deps_merged;
107
109
110 for (auto &info_name : additional_infos_) {
111
112 /* Fetch create info. */
113 const ShaderCreateInfo &info = *reinterpret_cast<const ShaderCreateInfo *>(
114 gpu_shader_create_info_get(info_name.c_str()));
115
116 if (recursive) {
117 const_cast<ShaderCreateInfo &>(info).finalize(recursive);
118 }
119 else {
121 }
122
124
125 /* NOTE: EEVEE Materials can result in nested includes. To avoid duplicate
126 * shader resources, we need to avoid inserting duplicates.
127 * TODO: Optimize create info preparation to include each individual "additional_info"
128 * only a single time. */
129 vertex_inputs_.extend_non_duplicates(info.vertex_inputs_);
130 fragment_outputs_.extend_non_duplicates(info.fragment_outputs_);
131 vertex_out_interfaces_.extend_non_duplicates(info.vertex_out_interfaces_);
132 geometry_out_interfaces_.extend_non_duplicates(info.geometry_out_interfaces_);
133 subpass_inputs_.extend_non_duplicates(info.subpass_inputs_);
134 specialization_constants_.extend_non_duplicates(info.specialization_constants_);
135
137
138 /* Insert with duplicate check. */
139 push_constants_.extend_non_duplicates(info.push_constants_);
140 defines_.extend_non_duplicates(info.defines_);
141 batch_resources_.extend_non_duplicates(info.batch_resources_);
142 pass_resources_.extend_non_duplicates(info.pass_resources_);
143 geometry_resources_.extend_non_duplicates(info.geometry_resources_);
144 typedef_sources_.extend_non_duplicates(info.typedef_sources_);
145
146 /* API-specific parameters.
147 * We will only copy API-specific parameters if they are otherwise unassigned. */
148#ifdef WITH_METAL_BACKEND
149 if (mtl_max_threads_per_threadgroup_ == 0) {
150 mtl_max_threads_per_threadgroup_ = info.mtl_max_threads_per_threadgroup_;
151 }
152#endif
153
154 if (info.early_fragment_test_) {
156 }
157 /* Modify depth write if has been changed from default.
158 * `UNCHANGED` implies gl_FragDepth is not used at all. */
161 }
162
163 /* Inherit builtin bits from additional info. */
164 builtins_ |= info.builtins_;
165
166 validate_merge(info);
167
168 auto assert_no_overlap = [&](const bool test, const StringRefNull error) {
169 if (!test) {
170 std::cout << name_ << ": Validation failed while merging " << info.name_ << " : ";
171 std::cout << error << std::endl;
172 BLI_assert(0);
173 }
174 };
175
176 if (!deps_merged.add(info.name_)) {
177 assert_no_overlap(false, "additional info already merged via another info");
178 }
179
180 if (info.compute_layout_.local_size_x != -1) {
181 assert_no_overlap(compute_layout_.local_size_x == -1, "Compute layout already defined");
183 }
184
185 if (!info.vertex_source_.is_empty()) {
186 assert_no_overlap(vertex_source_.is_empty(), "Vertex source already existing");
188 }
189 if (!info.geometry_source_.is_empty()) {
190 assert_no_overlap(geometry_source_.is_empty(), "Geometry source already existing");
193 }
194 if (!info.fragment_source_.is_empty()) {
195 assert_no_overlap(fragment_source_.is_empty(), "Fragment source already existing");
197 }
198 if (!info.compute_source_.is_empty()) {
199 assert_no_overlap(compute_source_.is_empty(), "Compute source already existing");
201 }
202 }
203
205 std::cout << name_
206 << ": Validation failed. BuiltinBits::LAYER shouldn't be used with geometry shaders."
207 << std::endl;
208 BLI_assert(0);
209 }
210
212 int images = 0, samplers = 0, ubos = 0, ssbos = 0;
213
214 auto set_resource_slot = [&](Resource &res) {
215 switch (res.bind_type) {
217 res.slot = ubos++;
218 break;
220 res.slot = ssbos++;
221 break;
223 res.slot = samplers++;
224 break;
226 res.slot = images++;
227 break;
228 }
229 };
230
231 for (auto &res : batch_resources_) {
232 set_resource_slot(res);
233 }
234 for (auto &res : pass_resources_) {
235 set_resource_slot(res);
236 }
237 for (auto &res : geometry_resources_) {
238 set_resource_slot(res);
239 }
240 }
241}
242
244{
245 std::string error;
246
247 /* At least a vertex shader and a fragment shader are required, or only a compute shader. */
248 if (this->compute_source_.is_empty()) {
249 if (this->vertex_source_.is_empty()) {
250 error += "Missing vertex shader in " + this->name_ + ".\n";
251 }
253 error += "Missing fragment shader in " + this->name_ + ".\n";
254 }
255 }
256 else {
257 if (!this->vertex_source_.is_empty()) {
258 error += "Compute shader has vertex_source_ shader attached in " + this->name_ + ".\n";
259 }
260 if (!this->geometry_source_.is_empty()) {
261 error += "Compute shader has geometry_source_ shader attached in " + this->name_ + ".\n";
262 }
263 if (!this->fragment_source_.is_empty()) {
264 error += "Compute shader has fragment_source_ shader attached in " + this->name_ + ".\n";
265 }
266 }
267
268 if (!this->geometry_source_.is_empty()) {
269 if (bool(this->builtins_ & BuiltinBits::BARYCENTRIC_COORD)) {
270 error += "Shader " + this->name_ +
271 " has geometry stage and uses barycentric coordinates. This is not allowed as "
272 "fallback injects a geometry stage.\n";
273 }
274 if (bool(this->builtins_ & BuiltinBits::VIEWPORT_INDEX)) {
275 error += "Shader " + this->name_ +
276 " has geometry stage and uses multi-viewport. This is not allowed as "
277 "fallback injects a geometry stage.\n";
278 }
279 if (bool(this->builtins_ & BuiltinBits::LAYER)) {
280 error += "Shader " + this->name_ +
281 " has geometry stage and uses layer output. This is not allowed as "
282 "fallback injects a geometry stage.\n";
283 }
284 }
285
286 if ((G.debug & G_DEBUG_GPU) == 0) {
287 return error;
288 }
289
290 /*
291 * The next check has been disabled. 'eevee_legacy_surface_common_iface' is known to fail.
292 * The check was added to validate if shader would be able to compile on Vulkan.
293 * TODO(jbakker): Enable the check after EEVEE is replaced by EEVEE-Next.
294 */
295#if 0
296 if (bool(this->builtins_ &
298 {
299 for (const StageInterfaceInfo *interface : this->vertex_out_interfaces_) {
300 if (interface->instance_name.is_empty()) {
301 error += "Shader " + this->name_ + " uses interface " + interface->name +
302 " that doesn't contain an instance name, but is required for the fallback "
303 "geometry shader.\n";
304 }
305 }
306 }
307#endif
308
309 if (!this->is_vulkan_compatible()) {
310 error += this->name_ +
311 " contains a stage interface using an instance name and mixed interpolation modes. "
312 "This is not compatible with Vulkan and need to be adjusted.\n";
313 }
314
315 /* Validate specialization constants. */
316 for (int i = 0; i < specialization_constants_.size(); i++) {
317 for (int j = i + 1; j < specialization_constants_.size(); j++) {
319 error += this->name_ + " contains two specialization constants with the name: " +
320 std::string(specialization_constants_[i].name);
321 }
322 }
323 }
324
325 return error;
326}
327
329{
331 /* Check same bind-points usage in OGL. */
332 Set<int> images, samplers, ubos, ssbos;
333
334 auto register_resource = [&](const Resource &res) -> bool {
335 switch (res.bind_type) {
337 return images.add(res.slot);
339 return samplers.add(res.slot);
341 return ubos.add(res.slot);
343 return ssbos.add(res.slot);
344 default:
345 return false;
346 }
347 };
348
349 auto print_error_msg = [&](const Resource &res, const Vector<Resource> &resources) {
350 auto print_resource_name = [&](const Resource &res) {
351 switch (res.bind_type) {
353 std::cout << "Uniform Buffer " << res.uniformbuf.name;
354 break;
356 std::cout << "Storage Buffer " << res.storagebuf.name;
357 break;
359 std::cout << "Sampler " << res.sampler.name;
360 break;
362 std::cout << "Image " << res.image.name;
363 break;
364 default:
365 std::cout << "Unknown Type";
366 break;
367 }
368 };
369
370 for (const Resource &_res : resources) {
371 if (&res != &_res && res.bind_type == _res.bind_type && res.slot == _res.slot) {
372 std::cout << name_ << ": Validation failed : Overlapping ";
373 print_resource_name(res);
374 std::cout << " and ";
375 print_resource_name(_res);
376 std::cout << " at (" << res.slot << ") while merging " << other_info.name_ << std::endl;
377 }
378 }
379 };
380
381 for (auto &res : batch_resources_) {
382 if (register_resource(res) == false) {
383 print_error_msg(res, resources_get_all_());
384 }
385 }
386
387 for (auto &res : pass_resources_) {
388 if (register_resource(res) == false) {
389 print_error_msg(res, resources_get_all_());
390 }
391 }
392
393 for (auto &res : geometry_resources_) {
394 if (register_resource(res) == false) {
395 print_error_msg(res, resources_get_all_());
396 }
397 }
398 }
399}
400
402{
403 uint32_t attr_bits = 0;
404 for (auto &attr : vertex_inputs_) {
405 if (attr.index >= 16 || attr.index < 0) {
406 std::cout << name_ << ": \"" << attr.name
407 << "\" : Type::MAT3 unsupported as vertex attribute." << std::endl;
408 BLI_assert(0);
409 }
410 if (attr.index >= 16 || attr.index < 0) {
411 std::cout << name_ << ": Invalid index for attribute \"" << attr.name << "\"" << std::endl;
412 BLI_assert(0);
413 }
414 uint32_t attr_new = 0;
415 if (attr.type == Type::MAT4) {
416 for (int i = 0; i < 4; i++) {
417 attr_new |= 1 << (attr.index + i);
418 }
419 }
420 else {
421 attr_new |= 1 << attr.index;
422 }
423
424 if ((attr_bits & attr_new) != 0) {
425 std::cout << name_ << ": Attribute \"" << attr.name
426 << "\" overlap one or more index from another attribute."
427 " Note that mat4 takes up 4 indices.";
428 if (other_info) {
429 std::cout << " While merging " << other_info->name_ << std::endl;
430 }
431 std::cout << std::endl;
432 BLI_assert(0);
433 }
434 attr_bits |= attr_new;
435 }
436}
437
438} // namespace blender::gpu::shader
439
440using namespace blender::gpu::shader;
441
442#ifdef _MSC_VER
443/* Disable optimization for this function with MSVC. It does not like the fact
444 * shaders info are declared in the same function (same basic block or not does
445 * not change anything).
446 * Since it is just a function called to register shaders (once),
447 * the fact it's optimized or not does not matter, it's not on any hot
448 * code path. */
449# pragma optimize("", off)
450#endif
452{
456
457#define GPU_SHADER_INTERFACE_INFO(_interface, _inst_name) \
458 StageInterfaceInfo *ptr_##_interface = new StageInterfaceInfo(#_interface, _inst_name); \
459 StageInterfaceInfo &_interface = *ptr_##_interface; \
460 g_interfaces->add_new(#_interface, ptr_##_interface); \
461 _interface
462
463#define GPU_SHADER_CREATE_INFO(_info) \
464 ShaderCreateInfo *ptr_##_info = new ShaderCreateInfo(#_info); \
465 ShaderCreateInfo &_info = *ptr_##_info; \
466 g_create_infos->add_new(#_info, ptr_##_info); \
467 _info
468
469/* Declare, register and construct the infos. */
470#include "compositor_shader_create_info_list.hh"
471#include "gpu_shader_create_info_list.hh"
472
473/* Baked shader data appended to create infos. */
474/* TODO(jbakker): should call a function with a callback. so we could switch implementations.
475 * We cannot compile bf_gpu twice. */
476#ifdef GPU_RUNTIME
477# include "gpu_shader_baked.hh"
478#endif
479
480 /* WORKAROUND: Replace draw_mesh info with the legacy one for systems that have problems with UBO
481 * indexing. */
487 {
488 draw_modelmat = draw_modelmat_legacy;
489 }
490
491 /* WORKAROUND: Replace the use of gpu_BaseInstance by an instance attribute. */
492 if (GPU_shader_draw_parameters_support() == false) {
493 draw_resource_id_new = draw_resource_id_fallback;
494 draw_resource_with_custom_id_new = draw_resource_with_custom_id_fallback;
495 }
496
498 /* WORKAROUND: Adding a dummy buffer that isn't used fixes a bug inside the Qualcom driver. */
499 eevee_deferred_tile_classify.storage_buf(
500 12, Qualifier::READ_WRITE, "uint", "dummy_workaround_buf[]");
501 }
502
503#ifdef WITH_METAL_BACKEND
504 /* Metal-specific alternatives for Geometry shaders. */
506 /* 3D polyline. */
507 gpu_shader_3D_polyline_uniform_color = gpu_shader_3D_polyline_uniform_color_no_geom;
508 gpu_shader_3D_polyline_flat_color = gpu_shader_3D_polyline_flat_color_no_geom;
509 gpu_shader_3D_polyline_smooth_color = gpu_shader_3D_polyline_smooth_color_no_geom;
510 gpu_shader_3D_polyline_uniform_color_clipped =
511 gpu_shader_3D_polyline_uniform_color_clipped_no_geom;
512
513 /* Overlay Edit Mesh. */
514 overlay_edit_mesh_edge = overlay_edit_mesh_edge_no_geom;
515 overlay_edit_mesh_edge_flat = overlay_edit_mesh_edge_flat_no_geom;
516 overlay_edit_mesh_edge_clipped = overlay_edit_mesh_edge_clipped_no_geom;
517 overlay_edit_mesh_edge_flat_clipped = overlay_edit_mesh_edge_flat_clipped_no_geom;
518 /* Overlay Edit Curve. */
519 overlay_edit_curve_handle = overlay_edit_curve_handle_no_geom;
520 overlay_edit_curve_handle_clipped = overlay_edit_curve_handle_clipped_no_geom;
521 /* Overlay Edit Curves. */
522 overlay_edit_curves_handle = overlay_edit_curves_handle_no_geom;
523 overlay_edit_curves_handle_clipped = overlay_edit_curves_handle_clipped_no_geom;
524
525 /* Overlay Armature Shape outline. */
526 overlay_armature_shape_outline = overlay_armature_shape_outline_no_geom;
527 overlay_armature_shape_outline_clipped = overlay_armature_shape_outline_clipped_no_geom;
528 overlay_armature_shape_wire = overlay_armature_shape_wire_no_geom;
529
530 /* Overlay Motion Path Line. */
531 overlay_motion_path_line = overlay_motion_path_line_no_geom;
532 overlay_motion_path_line_clipped = overlay_motion_path_line_clipped_no_geom;
533
534 /* Conservative rasterization. */
535 basic_depth_mesh_conservative = basic_depth_mesh_conservative_no_geom;
536 basic_depth_mesh_conservative_clipped = basic_depth_mesh_conservative_no_geom_clipped;
537 basic_depth_pointcloud_conservative = basic_depth_pointcloud_conservative_no_geom;
538 basic_depth_pointcloud_conservative_clipped =
539 basic_depth_pointcloud_conservative_no_geom_clipped;
540
541 /* Overlay pre-pass wire. */
542 overlay_outline_prepass_wire = overlay_outline_prepass_wire_no_geom;
543
544 /* Edit UV Edges. */
545 overlay_edit_uv_edges = overlay_edit_uv_edges_no_geom;
546
547 /* GPencil stroke. */
548 gpu_shader_gpencil_stroke = gpu_shader_gpencil_stroke_no_geom;
549
550 /* NOTE: As atomic data types can alter shader gen if native atomics are unsupported, we need
551 * to use differing create info's to handle the tile optimized check. This does prevent
552 * the shadow techniques from being dynamically switchable. */
553# if 0
554 /* Temp: Disable TILE_COPY path while efficient solution for parameter buffer overflow is
555 * identified. This path can be re-enabled in future. */
556 const bool is_tile_based_arch = (GPU_platform_architecture() == GPU_ARCHITECTURE_TBDR);
557 if (is_tile_based_arch) {
558 eevee_shadow_data = eevee_shadow_data_non_atomic;
559 }
560# endif
561 }
562#endif
563
564 for (ShaderCreateInfo *info : g_create_infos->values()) {
565 info->builtins_ |= gpu_shader_dependency_get_builtins(info->vertex_source_);
566 info->builtins_ |= gpu_shader_dependency_get_builtins(info->fragment_source_);
567 info->builtins_ |= gpu_shader_dependency_get_builtins(info->geometry_source_);
568 info->builtins_ |= gpu_shader_dependency_get_builtins(info->compute_source_);
569
570#if GPU_SHADER_PRINTF_ENABLE
571 if ((info->builtins_ & BuiltinBits::USE_PRINTF) == BuiltinBits::USE_PRINTF ||
573 {
574 info->additional_info("gpu_print");
575 }
576#endif
577
578#ifndef NDEBUG
579 /* Automatically amend the create info for ease of use of the debug feature. */
580 if ((info->builtins_ & BuiltinBits::USE_DEBUG_DRAW) == BuiltinBits::USE_DEBUG_DRAW) {
581 info->additional_info("draw_debug_draw");
582 }
583 if ((info->builtins_ & BuiltinBits::USE_DEBUG_PRINT) == BuiltinBits::USE_DEBUG_PRINT) {
584 info->additional_info("draw_debug_print");
585 }
586#endif
587 }
588
589 for (auto [key, info] : g_create_infos->items()) {
591 }
592
593 for (ShaderCreateInfo *info : g_create_infos->values()) {
594 info->finalize(true);
595 }
596
597 /* TEST */
598 // gpu_shader_create_info_compile(nullptr);
599}
600#ifdef _MSC_VER
601# pragma optimize("", on)
602#endif
603
605{
606 for (auto *value : g_create_infos->values()) {
607 delete value;
608 }
609 delete g_create_infos;
610
612
613 for (auto *value : g_interfaces->values()) {
614 delete value;
615 }
616 delete g_interfaces;
617}
618
619bool gpu_shader_create_info_compile(const char *name_starts_with_filter)
620{
621 using namespace blender::gpu;
622 int success = 0;
623 int skipped_filter = 0;
624 int skipped = 0;
625 int total = 0;
626 for (ShaderCreateInfo *info : g_create_infos->values()) {
627 info->finalize();
628 if (info->do_static_compilation_) {
629 if (name_starts_with_filter &&
630 !info->name_.startswith(blender::StringRefNull(name_starts_with_filter)))
631 {
632 skipped_filter++;
633 continue;
634 }
635 if ((info->metal_backend_only_ && GPU_backend_get_type() != GPU_BACKEND_METAL) ||
636 (GPU_geometry_shader_support() == false && info->geometry_source_ != nullptr) ||
637 (GPU_transform_feedback_support() == false && info->tf_type_ != GPU_SHADER_TFB_NONE))
638 {
639 skipped++;
640 continue;
641 }
642 total++;
644 reinterpret_cast<const GPUShaderCreateInfo *>(info));
645 if (shader == nullptr) {
646 std::cerr << "Compilation " << info->name_.c_str() << " Failed\n";
647 }
648 else {
649 success++;
650
651#if 0 /* TODO(fclem): This is too verbose for now. Make it a cmake option. */
652 /* Test if any resource is optimized out and print a warning if that's the case. */
653 /* TODO(fclem): Limit this to OpenGL backend. */
654 const ShaderInterface *interface = unwrap(shader)->interface;
655
656 blender::Vector<ShaderCreateInfo::Resource> all_resources = info->resources_get_all_();
657
658 for (ShaderCreateInfo::Resource &res : all_resources) {
659 blender::StringRefNull name = "";
660 const ShaderInput *input = nullptr;
661
662 switch (res.bind_type) {
663 case ShaderCreateInfo::Resource::BindType::UNIFORM_BUFFER:
664 input = interface->ubo_get(res.slot);
665 name = res.uniformbuf.name;
666 break;
667 case ShaderCreateInfo::Resource::BindType::STORAGE_BUFFER:
668 input = interface->ssbo_get(res.slot);
669 name = res.storagebuf.name;
670 break;
671 case ShaderCreateInfo::Resource::BindType::SAMPLER:
672 input = interface->texture_get(res.slot);
673 name = res.sampler.name;
674 break;
675 case ShaderCreateInfo::Resource::BindType::IMAGE:
676 input = interface->texture_get(res.slot);
677 name = res.image.name;
678 break;
679 }
680
681 if (input == nullptr) {
682 std::cerr << "Error: " << info->name_;
683 std::cerr << ": Resource « " << name << " » not found in the shader interface\n";
684 }
685 else if (input->location == -1) {
686 std::cerr << "Warning: " << info->name_;
687 std::cerr << ": Resource « " << name << " » is optimized out\n";
688 }
689 }
690#endif
691 }
692 GPU_shader_free(shader);
693 }
694 }
695 printf("Shader Test compilation result: %d / %d passed", success, total);
696 if (skipped_filter > 0) {
697 printf(" (skipped %d when filtering)", skipped_filter);
698 }
699 if (skipped > 0) {
700 printf(" (skipped %d for compatibility reasons)", skipped);
701 }
702 printf("\n");
703 return success == total;
704}
705
706const GPUShaderCreateInfo *gpu_shader_create_info_get(const char *info_name)
707{
708 if (g_create_infos->contains(info_name) == false) {
709 printf("Error: Cannot find shader create info named \"%s\"\n", info_name);
710 return nullptr;
711 }
712 ShaderCreateInfo *info = g_create_infos->lookup(info_name);
713 return reinterpret_cast<const GPUShaderCreateInfo *>(info);
714}
715
717 GPUShaderCreateInfo &r_info)
718{
719 if (g_create_infos_unfinalized->contains(info_name) == false) {
720 std::string msg = std::string("Error: Cannot find shader create info named \"") + info_name +
721 "\"\n";
722 BLI_assert_msg(0, msg.c_str());
723 }
724 else {
725 ShaderCreateInfo &info = reinterpret_cast<ShaderCreateInfo &>(r_info);
726 info = g_create_infos_unfinalized->lookup(info_name);
727 BLI_assert(!info.finalized_);
728 }
729}
@ G_DEBUG_GPU
#define BLI_assert(a)
Definition BLI_assert.h:50
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:57
bool GPU_transform_feedback_support()
bool GPU_crappy_amd_driver()
bool GPU_geometry_shader_support()
bool GPU_stencil_clasify_buffer_workaround()
bool GPU_shader_draw_parameters_support()
eGPUBackendType GPU_backend_get_type()
@ GPU_DRIVER_ANY
bool GPU_type_matches_ex(eGPUDeviceType device, eGPUOSType os, eGPUDriverType driver, eGPUBackendType backend)
@ GPU_ARCHITECTURE_TBDR
@ GPU_OS_ANY
@ GPU_OS_MAC
@ GPU_DEVICE_INTEL_UHD
@ GPU_DEVICE_ANY
@ GPU_DEVICE_INTEL
GPUArchitectureType GPU_platform_architecture()
@ GPU_SHADER_TFB_NONE
GPUShader * GPU_shader_create_from_info(const GPUShaderCreateInfo *_info)
void GPU_shader_free(GPUShader *shader)
struct GPUShader GPUShader
ustring name() const
const Value & lookup(const Key &key) const
Definition BLI_map.hh:506
ValueIterator values() const
Definition BLI_map.hh:846
void add_new(const Key &key, const Value &value)
Definition BLI_map.hh:241
ItemIterator items() const
Definition BLI_map.hh:864
bool contains(const Key &key) const
Definition BLI_map.hh:329
bool add(const Key &key)
Definition BLI_set.hh:248
constexpr bool is_empty() const
#define printf
gbuf_header_tx eevee_shadow_data
draw_resource_id_new
const GPUShaderCreateInfo * gpu_shader_create_info_get(const char *info_name)
void gpu_shader_create_info_exit()
bool gpu_shader_create_info_compile(const char *name_starts_with_filter)
void gpu_shader_create_info_init()
void gpu_shader_create_info_get_unfinalized_copy(const char *info_name, GPUShaderCreateInfo &r_info)
#define G(x, y, z)
static void error(const char *str)
Map< StringRef, ShaderCreateInfo * > CreateInfoDictionnary
static CreateInfoValueDictionnary * g_create_infos_unfinalized
Map< StringRef, StageInterfaceInfo * > InterfaceDictionnary
BuiltinBits gpu_shader_dependency_get_builtins(const StringRefNull source_name)
static InterfaceDictionnary * g_interfaces
bool gpu_shader_dependency_force_gpu_print_injection()
static bool is_vulkan_compatible_interface(const StageInterfaceInfo &iface)
static CreateInfoDictionnary * g_create_infos
Map< StringRef, ShaderCreateInfo > CreateInfoValueDictionnary
pos fragColor draw_modelmat
unsigned int uint32_t
Definition stdint.h:80
Describe inputs & outputs, stage interfaces, resources and sources of a shader. If all data is correc...
Vector< StageInterfaceInfo * > vertex_out_interfaces_
Vector< std::array< StringRefNull, 2 > > defines_
void validate_vertex_attributes(const ShaderCreateInfo *other_info=nullptr)
void finalize(const bool recursive=false)
Vector< StageInterfaceInfo * > geometry_out_interfaces_
void validate_merge(const ShaderCreateInfo &other_info)
Vector< SpecializationConstant > specialization_constants_