Blender V4.3
gpu_shader.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2005 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include "MEM_guardedalloc.h"
10
11#include "BLI_math_matrix.h"
12#include "BLI_string.h"
13#include "BLI_string_utils.hh"
14
15#include "GPU_capabilities.hh"
16#include "GPU_debug.hh"
17#include "GPU_matrix.hh"
18#include "GPU_platform.hh"
19
20#include "gpu_backend.hh"
25#include "gpu_shader_private.hh"
26
27#include <string>
28
30
31namespace blender::gpu {
32
34{
35 std::string defines;
36 for (const auto &def : info.defines_) {
37 defines += "#define ";
38 defines += def[0];
39 defines += " ";
40 defines += def[1];
41 defines += "\n";
42 }
43 return defines;
44}
45
46} // namespace blender::gpu
47
48using namespace blender;
49using namespace blender::gpu;
50
51/* -------------------------------------------------------------------- */
55Shader::Shader(const char *sh_name)
56{
57 STRNCPY(this->name, sh_name);
58}
59
61{
62 delete interface;
63}
64
66{
67 BLI_assert(sources.is_empty());
68 /* Version and specialization constants needs to be first.
69 * Exact values will be added by implementation. */
70 sources.append("version");
71 sources.append("/* specialization_constants */");
72 /* Define to identify code usage in shading language. */
73 sources.append("#define GPU_SHADER\n");
74 /* some useful defines to detect GPU type */
76 sources.append("#define GPU_ATI\n");
77 }
79 sources.append("#define GPU_NVIDIA\n");
80 }
82 sources.append("#define GPU_INTEL\n");
83 }
85 sources.append("#define GPU_APPLE\n");
86 }
87 /* some useful defines to detect OS type */
89 sources.append("#define OS_WIN\n");
90 }
92 sources.append("#define OS_MAC\n");
93 }
95 sources.append("#define OS_UNIX\n");
96 }
97 /* API Definition */
99 switch (backend) {
101 sources.append("#define GPU_OPENGL\n");
102 break;
104 sources.append("#define GPU_METAL\n");
105 break;
107 sources.append("#define GPU_VULKAN\n");
108 break;
109 default:
110 BLI_assert_msg(false, "Invalid GPU Backend Type");
111 break;
112 }
113
114 if (GPU_crappy_amd_driver()) {
115 sources.append("#define GPU_DEPRECATED_AMD_DRIVER\n");
116 }
117}
118
119GPUShader *GPU_shader_create_ex(const char *vertcode,
120 const char *fragcode,
121 const char *geomcode,
122 const char *computecode,
123 const char *libcode,
124 const char *defines,
125 const eGPUShaderTFBType tf_type,
126 const char **tf_names,
127 const int tf_count,
128 const char *shname)
129{
130 /* At least a vertex shader and a fragment shader are required, or only a compute shader. */
131 BLI_assert(((fragcode != nullptr) && (vertcode != nullptr) && (computecode == nullptr)) ||
132 ((fragcode == nullptr) && (vertcode == nullptr) && (geomcode == nullptr) &&
133 (computecode != nullptr)));
134
135 Shader *shader = GPUBackend::get()->shader_alloc(shname);
136
137 if (vertcode) {
138 Vector<const char *> sources;
139 standard_defines(sources);
140 sources.append("#define GPU_VERTEX_SHADER\n");
141 sources.append("#define IN_OUT out\n");
142 if (geomcode) {
143 sources.append("#define USE_GEOMETRY_SHADER\n");
144 }
145 if (defines) {
146 sources.append(defines);
147 }
148 sources.append(vertcode);
149
150 shader->vertex_shader_from_glsl(sources);
151 }
152
153 if (fragcode) {
154 Vector<const char *> sources;
155 standard_defines(sources);
156 sources.append("#define GPU_FRAGMENT_SHADER\n");
157 sources.append("#define IN_OUT in\n");
158 if (geomcode) {
159 sources.append("#define USE_GEOMETRY_SHADER\n");
160 }
161 if (defines) {
162 sources.append(defines);
163 }
164 if (libcode) {
165 sources.append(libcode);
166 }
167 sources.append(fragcode);
168
169 shader->fragment_shader_from_glsl(sources);
170 }
171
172 if (geomcode) {
173 Vector<const char *> sources;
174 standard_defines(sources);
175 sources.append("#define GPU_GEOMETRY_SHADER\n");
176 if (defines) {
177 sources.append(defines);
178 }
179 sources.append(geomcode);
180
181 shader->geometry_shader_from_glsl(sources);
182 }
183
184 if (computecode) {
185 Vector<const char *> sources;
186 standard_defines(sources);
187 sources.append("#define GPU_COMPUTE_SHADER\n");
188 if (defines) {
189 sources.append(defines);
190 }
191 if (libcode) {
192 sources.append(libcode);
193 }
194 sources.append(computecode);
195
196 shader->compute_shader_from_glsl(sources);
197 }
198
199 if (tf_names != nullptr && tf_count > 0) {
201 shader->transform_feedback_names_set(Span<const char *>(tf_names, tf_count), tf_type);
202 }
203
204 if (!shader->finalize()) {
205 delete shader;
206 return nullptr;
207 };
208
209 return wrap(shader);
210}
211
213{
214 delete unwrap(shader);
215}
216
219/* -------------------------------------------------------------------- */
223GPUShader *GPU_shader_create(const char *vertcode,
224 const char *fragcode,
225 const char *geomcode,
226 const char *libcode,
227 const char *defines,
228 const char *shname)
229{
230 return GPU_shader_create_ex(vertcode,
231 fragcode,
232 geomcode,
233 nullptr,
234 libcode,
235 defines,
237 nullptr,
238 0,
239 shname);
240}
241
242GPUShader *GPU_shader_create_compute(const char *computecode,
243 const char *libcode,
244 const char *defines,
245 const char *shname)
246{
247 return GPU_shader_create_ex(nullptr,
248 nullptr,
249 nullptr,
250 computecode,
251 libcode,
252 defines,
254 nullptr,
255 0,
256 shname);
257}
258
259const GPUShaderCreateInfo *GPU_shader_create_info_get(const char *info_name)
260{
261 return gpu_shader_create_info_get(info_name);
262}
263
265 GPUShaderCreateInfo &r_info)
266{
268}
269
270bool GPU_shader_create_info_check_error(const GPUShaderCreateInfo *_info, char r_error[128])
271{
272 using namespace blender::gpu::shader;
273 const ShaderCreateInfo &info = *reinterpret_cast<const ShaderCreateInfo *>(_info);
274 std::string error = info.check_error();
275 if (error.length() == 0) {
276 return true;
277 }
278
279 BLI_strncpy(r_error, error.c_str(), 128);
280 return false;
281}
282
284{
285 using namespace blender::gpu::shader;
286 const GPUShaderCreateInfo *_info = gpu_shader_create_info_get(info_name);
287 const ShaderCreateInfo &info = *reinterpret_cast<const ShaderCreateInfo *>(_info);
288 if (!info.do_static_compilation_) {
289 std::cerr << "Warning: Trying to compile \"" << info.name_.c_str()
290 << "\" which was not marked for static compilation.\n";
291 }
292 return GPU_shader_create_from_info(_info);
293}
294
295GPUShader *GPU_shader_create_from_info(const GPUShaderCreateInfo *_info)
296{
297 using namespace blender::gpu::shader;
298 const ShaderCreateInfo &info = *reinterpret_cast<const ShaderCreateInfo *>(_info);
299 return wrap(Context::get()->compiler->compile(info, false));
300}
301
303 const char *fragcode,
304 const char *geomcode,
305 const char *libcode,
306 const char *defines,
307 const char *name)
308{
309 char *libcodecat = nullptr;
310
311 if (libcode == nullptr) {
313 }
314 else {
315 libcode = libcodecat = BLI_strdupcat(libcode, datatoc_gpu_shader_colorspace_lib_glsl);
316 }
317
318 /* Use pyGPUShader as default name for shader. */
319 const char *shname = name != nullptr ? name : "pyGPUShader";
320
321 GPUShader *sh = GPU_shader_create_ex(vertcode,
322 fragcode,
323 geomcode,
324 nullptr,
325 libcode,
326 defines,
328 nullptr,
329 0,
330 shname);
331
332 MEM_SAFE_FREE(libcodecat);
333 return sh;
334}
335
343
345{
346 return Context::get()->compiler->batch_is_ready(handle);
347}
348
354
356{
357 printf("Compiling all static GPU shaders. This process takes a while.\n");
359}
360
365
368/* -------------------------------------------------------------------- */
372void GPU_shader_bind(GPUShader *gpu_shader)
373{
374 Shader *shader = unwrap(gpu_shader);
375
376 Context *ctx = Context::get();
377
378 if (ctx->shader != shader) {
379 ctx->shader = shader;
380 shader->bind();
381 GPU_matrix_bind(gpu_shader);
382 Shader::set_srgb_uniform(gpu_shader);
383 shader->constants.is_dirty = false;
384 }
385 else {
386 if (shader->constants.is_dirty) {
387 shader->bind();
388 shader->constants.is_dirty = false;
389 }
390 if (Shader::srgb_uniform_dirty_get()) {
391 Shader::set_srgb_uniform(gpu_shader);
392 }
393 if (GPU_matrix_dirty_get()) {
394 GPU_matrix_bind(gpu_shader);
395 }
396 }
397#if GPU_SHADER_PRINTF_ENABLE
398 if (ctx->printf_buf) {
400 }
401#endif
402}
403
405{
406#ifndef NDEBUG
407 Context *ctx = Context::get();
408 if (ctx->shader) {
409 ctx->shader->unbind();
410 }
411 ctx->shader = nullptr;
412#endif
413}
414
416{
417 Context *ctx = Context::get();
418 if (ctx) {
419 return wrap(ctx->shader);
420 }
421 return nullptr;
422}
423
426/* -------------------------------------------------------------------- */
430const char *GPU_shader_get_name(GPUShader *shader)
431{
432 return unwrap(shader)->name_get();
433}
434
437/* -------------------------------------------------------------------- */
442{
443 BLI_assert(shader != nullptr);
444 BLI_assert(shader != parent);
445 if (shader != parent) {
446 Shader *shd_child = unwrap(shader);
447 Shader *shd_parent = unwrap(parent);
448 shd_child->parent_set(shd_parent);
449 }
450}
451
452void GPU_shader_warm_cache(GPUShader *shader, int limit)
453{
454 unwrap(shader)->warm_cache(limit);
455}
456
459/* -------------------------------------------------------------------- */
466{
467 return unwrap(shader)->transform_feedback_enable(vertbuf);
468}
469
471{
472 unwrap(shader)->transform_feedback_disable();
473}
474
477/* -------------------------------------------------------------------- */
481void Shader::specialization_constants_init(const shader::ShaderCreateInfo &info)
482{
483 using namespace shader;
485 constants.types.append(sc.type);
486 constants.values.append(sc.value);
487 }
488 constants.is_dirty = true;
489}
490
491void GPU_shader_constant_int_ex(GPUShader *sh, int location, int value)
492{
493 Shader &shader = *unwrap(sh);
494 BLI_assert(shader.constants.types[location] == gpu::shader::Type::INT);
495 shader.constants.is_dirty |= assign_if_different(shader.constants.values[location].i, value);
496}
497void GPU_shader_constant_uint_ex(GPUShader *sh, int location, uint value)
498{
499 Shader &shader = *unwrap(sh);
500 BLI_assert(shader.constants.types[location] == gpu::shader::Type::UINT);
501 shader.constants.is_dirty |= assign_if_different(shader.constants.values[location].u, value);
502}
503void GPU_shader_constant_float_ex(GPUShader *sh, int location, float value)
504{
505 Shader &shader = *unwrap(sh);
506 BLI_assert(shader.constants.types[location] == gpu::shader::Type::FLOAT);
507 shader.constants.is_dirty |= assign_if_different(shader.constants.values[location].f, value);
508}
509void GPU_shader_constant_bool_ex(GPUShader *sh, int location, bool value)
510{
511 Shader &shader = *unwrap(sh);
512 BLI_assert(shader.constants.types[location] == gpu::shader::Type::BOOL);
513 shader.constants.is_dirty |= assign_if_different(shader.constants.values[location].u,
514 uint32_t(value));
515}
516
517void GPU_shader_constant_int(GPUShader *sh, const char *name, int value)
518{
519 GPU_shader_constant_int_ex(sh, unwrap(sh)->interface->constant_get(name)->location, value);
520}
521void GPU_shader_constant_uint(GPUShader *sh, const char *name, uint value)
522{
523 GPU_shader_constant_uint_ex(sh, unwrap(sh)->interface->constant_get(name)->location, value);
524}
525void GPU_shader_constant_float(GPUShader *sh, const char *name, float value)
526{
527 GPU_shader_constant_float_ex(sh, unwrap(sh)->interface->constant_get(name)->location, value);
528}
529void GPU_shader_constant_bool(GPUShader *sh, const char *name, bool value)
530{
531 GPU_shader_constant_bool_ex(sh, unwrap(sh)->interface->constant_get(name)->location, value);
532}
533
539
544
547/* -------------------------------------------------------------------- */
551int GPU_shader_get_uniform(GPUShader *shader, const char *name)
552{
553 const ShaderInterface *interface = unwrap(shader)->interface;
554 const ShaderInput *uniform = interface->uniform_get(name);
555 return uniform ? uniform->location : -1;
556}
557
558int GPU_shader_get_constant(GPUShader *shader, const char *name)
559{
560 const ShaderInterface *interface = unwrap(shader)->interface;
561 const ShaderInput *constant = interface->constant_get(name);
562 return constant ? constant->location : -1;
563}
564
566{
567 const ShaderInterface *interface = unwrap(shader)->interface;
568 return interface->uniform_builtin((GPUUniformBuiltin)builtin);
569}
570
572{
573 const ShaderInterface *interface = unwrap(shader)->interface;
574 return interface->ubo_builtin((GPUUniformBlockBuiltin)builtin);
575}
576
577int GPU_shader_get_ssbo_binding(GPUShader *shader, const char *name)
578{
579 const ShaderInterface *interface = unwrap(shader)->interface;
580 const ShaderInput *ssbo = interface->ssbo_get(name);
581 return ssbo ? ssbo->location : -1;
582}
583
584int GPU_shader_get_uniform_block(GPUShader *shader, const char *name)
585{
586 const ShaderInterface *interface = unwrap(shader)->interface;
587 const ShaderInput *ubo = interface->ubo_get(name);
588 return ubo ? ubo->location : -1;
589}
590
591int GPU_shader_get_ubo_binding(GPUShader *shader, const char *name)
592{
593 const ShaderInterface *interface = unwrap(shader)->interface;
594 const ShaderInput *ubo = interface->ubo_get(name);
595 return ubo ? ubo->binding : -1;
596}
597
598int GPU_shader_get_sampler_binding(GPUShader *shader, const char *name)
599{
600 const ShaderInterface *interface = unwrap(shader)->interface;
601 const ShaderInput *tex = interface->uniform_get(name);
602 return tex ? tex->binding : -1;
603}
604
606{
607 const ShaderInterface *interface = unwrap(shader)->interface;
608 return interface->attr_len_;
609}
610
611int GPU_shader_get_attribute(const GPUShader *shader, const char *name)
612{
613 const ShaderInterface *interface = unwrap(shader)->interface;
614 const ShaderInput *attr = interface->attr_get(name);
615 return attr ? attr->location : -1;
616}
617
619 int attr_location,
620 char r_name[256],
621 int *r_type)
622{
623 const ShaderInterface *interface = unwrap(shader)->interface;
624
625 const ShaderInput *attr = interface->attr_get(attr_location);
626 if (!attr) {
627 return false;
628 }
629
630 BLI_strncpy(r_name, interface->input_name_get(attr), 256);
631 *r_type = attr->location != -1 ? interface->attr_types_[attr->location] : -1;
632 return true;
633}
634
637/* -------------------------------------------------------------------- */
642{
643 return unwrap(shader)->program_handle_get();
644}
645
647{
648 return unwrap(shader)->get_ssbo_vertex_fetch_output_num_verts();
649}
650
652{
653 return unwrap(shader)->get_uses_ssbo_vertex_fetch();
654}
655
658/* -------------------------------------------------------------------- */
663 GPUShader *shader, int loc, int len, int array_size, const float *value)
664{
665 unwrap(shader)->uniform_float(loc, len, array_size, value);
666}
667
669 GPUShader *shader, int loc, int len, int array_size, const int *value)
670{
671 unwrap(shader)->uniform_int(loc, len, array_size, value);
672}
673
674void GPU_shader_uniform_1i(GPUShader *sh, const char *name, int value)
675{
676 const int loc = GPU_shader_get_uniform(sh, name);
677 GPU_shader_uniform_int_ex(sh, loc, 1, 1, &value);
678}
679
680void GPU_shader_uniform_1b(GPUShader *sh, const char *name, bool value)
681{
682 GPU_shader_uniform_1i(sh, name, value ? 1 : 0);
683}
684
685void GPU_shader_uniform_2f(GPUShader *sh, const char *name, float x, float y)
686{
687 const float data[2] = {x, y};
688 GPU_shader_uniform_2fv(sh, name, data);
689}
690
691void GPU_shader_uniform_3f(GPUShader *sh, const char *name, float x, float y, float z)
692{
693 const float data[3] = {x, y, z};
694 GPU_shader_uniform_3fv(sh, name, data);
695}
696
697void GPU_shader_uniform_4f(GPUShader *sh, const char *name, float x, float y, float z, float w)
698{
699 const float data[4] = {x, y, z, w};
700 GPU_shader_uniform_4fv(sh, name, data);
701}
702
703void GPU_shader_uniform_1f(GPUShader *sh, const char *name, float value)
704{
705 const int loc = GPU_shader_get_uniform(sh, name);
706 GPU_shader_uniform_float_ex(sh, loc, 1, 1, &value);
707}
708
709void GPU_shader_uniform_2fv(GPUShader *sh, const char *name, const float data[2])
710{
711 const int loc = GPU_shader_get_uniform(sh, name);
712 GPU_shader_uniform_float_ex(sh, loc, 2, 1, data);
713}
714
715void GPU_shader_uniform_3fv(GPUShader *sh, const char *name, const float data[3])
716{
717 const int loc = GPU_shader_get_uniform(sh, name);
718 GPU_shader_uniform_float_ex(sh, loc, 3, 1, data);
719}
720
721void GPU_shader_uniform_4fv(GPUShader *sh, const char *name, const float data[4])
722{
723 const int loc = GPU_shader_get_uniform(sh, name);
724 GPU_shader_uniform_float_ex(sh, loc, 4, 1, data);
725}
726
727void GPU_shader_uniform_2iv(GPUShader *sh, const char *name, const int data[2])
728{
729 const int loc = GPU_shader_get_uniform(sh, name);
730 GPU_shader_uniform_int_ex(sh, loc, 2, 1, data);
731}
732
733void GPU_shader_uniform_mat4(GPUShader *sh, const char *name, const float data[4][4])
734{
735 const int loc = GPU_shader_get_uniform(sh, name);
736 GPU_shader_uniform_float_ex(sh, loc, 16, 1, (const float *)data);
737}
738
739void GPU_shader_uniform_mat3_as_mat4(GPUShader *sh, const char *name, const float data[3][3])
740{
741 float matrix[4][4];
742 copy_m4_m3(matrix, data);
743 GPU_shader_uniform_mat4(sh, name, matrix);
744}
745
746void GPU_shader_uniform_1f_array(GPUShader *sh, const char *name, int len, const float *val)
747{
748 const int loc = GPU_shader_get_uniform(sh, name);
749 GPU_shader_uniform_float_ex(sh, loc, 1, len, val);
750}
751
752void GPU_shader_uniform_2fv_array(GPUShader *sh, const char *name, int len, const float (*val)[2])
753{
754 const int loc = GPU_shader_get_uniform(sh, name);
755 GPU_shader_uniform_float_ex(sh, loc, 2, len, (const float *)val);
756}
757
758void GPU_shader_uniform_4fv_array(GPUShader *sh, const char *name, int len, const float (*val)[4])
759{
760 const int loc = GPU_shader_get_uniform(sh, name);
761 GPU_shader_uniform_float_ex(sh, loc, 4, len, (const float *)val);
762}
763
766namespace blender::gpu {
767
768/* -------------------------------------------------------------------- */
781
782bool Shader::srgb_uniform_dirty_get()
783{
785}
786
787void Shader::set_srgb_uniform(GPUShader *shader)
788{
790 if (loc != -1) {
792 }
794}
795
796void Shader::set_framebuffer_srgb_target(int use_srgb_to_linear)
797{
798 if (g_shader_builtin_srgb_transform != use_srgb_to_linear) {
799 g_shader_builtin_srgb_transform = use_srgb_to_linear;
801 }
802}
803
806/* -------------------------------------------------------------------- */
810Shader *ShaderCompiler::compile(const shader::ShaderCreateInfo &info, bool is_batch_compilation)
811{
812 using namespace blender::gpu::shader;
813 const_cast<ShaderCreateInfo &>(info).finalize();
814
816
817 const std::string error = info.check_error();
818 if (!error.empty()) {
819 std::cerr << error.c_str() << "\n";
820 BLI_assert(false);
821 }
822
823 Shader *shader = GPUBackend::get()->shader_alloc(info.name_.c_str());
824 shader->init(info, is_batch_compilation);
825 shader->specialization_constants_init(info);
826
827 std::string defines = shader->defines_declare(info);
828 std::string resources = shader->resources_declare(info);
829
830 if (info.legacy_resource_location_ == false) {
831 defines += "#define USE_GPU_SHADER_CREATE_INFO\n";
832 }
833
834 Vector<const char *> typedefs;
835 if (!info.typedef_sources_.is_empty() || !info.typedef_source_generated.empty()) {
836 typedefs.append(gpu_shader_dependency_get_source("GPU_shader_shared_utils.hh").c_str());
837 }
838 if (!info.typedef_source_generated.empty()) {
839 typedefs.append(info.typedef_source_generated.c_str());
840 }
841 for (auto filename : info.typedef_sources_) {
842 typedefs.append(gpu_shader_dependency_get_source(filename).c_str());
843 }
844
845 if (!info.vertex_source_.is_empty()) {
846 auto code = gpu_shader_dependency_get_resolved_source(info.vertex_source_);
847 std::string interface = shader->vertex_interface_declare(info);
848
849 Vector<const char *> sources;
850 standard_defines(sources);
851 sources.append("#define GPU_VERTEX_SHADER\n");
852 if (!info.geometry_source_.is_empty()) {
853 sources.append("#define USE_GEOMETRY_SHADER\n");
854 }
855 sources.append(defines.c_str());
856 sources.extend(typedefs);
857 sources.append(resources.c_str());
858 sources.append(interface.c_str());
859 sources.extend(code);
860 sources.extend(info.dependencies_generated);
861 sources.append(info.vertex_source_generated.c_str());
862
863 shader->vertex_shader_from_glsl(sources);
864 }
865
866 if (!info.fragment_source_.is_empty()) {
867 auto code = gpu_shader_dependency_get_resolved_source(info.fragment_source_);
868 std::string interface = shader->fragment_interface_declare(info);
869
870 Vector<const char *> sources;
871 standard_defines(sources);
872 sources.append("#define GPU_FRAGMENT_SHADER\n");
873 if (!info.geometry_source_.is_empty()) {
874 sources.append("#define USE_GEOMETRY_SHADER\n");
875 }
876 sources.append(defines.c_str());
877 sources.extend(typedefs);
878 sources.append(resources.c_str());
879 sources.append(interface.c_str());
880 sources.extend(code);
881 sources.extend(info.dependencies_generated);
882 sources.append(info.fragment_source_generated.c_str());
883
884 shader->fragment_shader_from_glsl(sources);
885 }
886
887 if (!info.geometry_source_.is_empty()) {
888 auto code = gpu_shader_dependency_get_resolved_source(info.geometry_source_);
889 std::string layout = shader->geometry_layout_declare(info);
890 std::string interface = shader->geometry_interface_declare(info);
891
892 Vector<const char *> sources;
893 standard_defines(sources);
894 sources.append("#define GPU_GEOMETRY_SHADER\n");
895 sources.append(defines.c_str());
896 sources.extend(typedefs);
897 sources.append(resources.c_str());
898 sources.append(layout.c_str());
899 sources.append(interface.c_str());
900 sources.append(info.geometry_source_generated.c_str());
901 sources.extend(code);
902
903 shader->geometry_shader_from_glsl(sources);
904 }
905
906 if (!info.compute_source_.is_empty()) {
907 auto code = gpu_shader_dependency_get_resolved_source(info.compute_source_);
908 std::string layout = shader->compute_layout_declare(info);
909
910 Vector<const char *> sources;
911 standard_defines(sources);
912 sources.append("#define GPU_COMPUTE_SHADER\n");
913 sources.append(defines.c_str());
914 sources.extend(typedefs);
915 sources.append(resources.c_str());
916 sources.append(layout.c_str());
917 sources.extend(code);
918 sources.extend(info.dependencies_generated);
919 sources.append(info.compute_source_generated.c_str());
920
921 shader->compute_shader_from_glsl(sources);
922 }
923
924 if (info.tf_type_ != GPU_SHADER_TFB_NONE && info.tf_names_.size() > 0) {
925 shader->transform_feedback_names_set(info.tf_names_.as_span(), info.tf_type_);
926 }
927
928 if (!shader->finalize(&info)) {
929 delete shader;
931 return nullptr;
932 }
933
935 return shader;
936}
937
940/* -------------------------------------------------------------------- */
945{
946 /* Ensure all the requested batches have been retrieved. */
947 BLI_assert(batches.is_empty());
948}
949
951{
952 BatchHandle handle = next_batch_handle++;
953 batches.add(handle, {{}, infos, true});
954 Batch &batch = batches.lookup(handle);
955 batch.shaders.reserve(infos.size());
956 for (const shader::ShaderCreateInfo *info : infos) {
957 batch.shaders.append(compile(*info, true));
958 }
959 return handle;
960}
961
963{
964 bool is_ready = batches.lookup(handle).is_ready;
965 return is_ready;
966}
967
969{
970 Vector<Shader *> shaders = batches.pop(handle).shaders;
971 handle = 0;
972 return shaders;
973}
974
977} // namespace blender::gpu
#define BLI_assert(a)
Definition BLI_assert.h:50
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:57
void copy_m4_m3(float m1[4][4], const float m2[3][3])
char * BLI_strdupcat(const char *__restrict str1, const char *__restrict str2) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1
#define STRNCPY(dst, src)
Definition BLI_string.h:593
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
unsigned int uint
bool GPU_crappy_amd_driver()
eGPUBackendType GPU_backend_get_type()
void GPU_debug_group_end()
Definition gpu_debug.cc:33
void GPU_debug_group_begin(const char *name)
Definition gpu_debug.cc:22
#define GPU_DEBUG_SHADER_COMPILATION_GROUP
Definition GPU_debug.hh:66
void GPU_matrix_bind(GPUShader *shader)
bool GPU_matrix_dirty_get()
@ GPU_DRIVER_ANY
@ GPU_OS_WIN
@ GPU_OS_UNIX
@ GPU_OS_ANY
@ GPU_OS_MAC
@ GPU_DEVICE_ATI
@ GPU_DEVICE_NVIDIA
@ GPU_DEVICE_ANY
@ GPU_DEVICE_APPLE
@ GPU_DEVICE_INTEL
bool GPU_type_matches(eGPUDeviceType device, eGPUOSType os, eGPUDriverType driver)
int GPU_shader_get_sampler_binding(GPUShader *shader, const char *name)
int GPU_shader_get_uniform(GPUShader *shader, const char *name)
void GPU_shader_constant_int(GPUShader *sh, const char *name, int value)
GPUShader * GPU_shader_create(const char *vertcode, const char *fragcode, const char *geomcode, const char *libcode, const char *defines, const char *shname)
void GPU_shader_uniform_2fv(GPUShader *sh, const char *name, const float data[2])
bool GPU_shader_get_attribute_info(const GPUShader *shader, int attr_location, char r_name[256], int *r_type)
const char * GPU_shader_get_name(GPUShader *shader)
void GPU_shader_uniform_1i(GPUShader *sh, const char *name, int value)
int GPU_shader_get_ubo_binding(GPUShader *shader, const char *name)
void GPU_shader_uniform_3f(GPUShader *sh, const char *name, float x, float y, float z)
blender::Vector< GPUShader * > GPU_shader_batch_finalize(BatchHandle &handle)
void GPU_shader_uniform_2f(GPUShader *sh, const char *name, float x, float y)
void GPU_shader_uniform_2fv_array(GPUShader *sh, const char *name, int len, const float(*val)[2])
void GPU_shader_uniform_int_ex(GPUShader *shader, int location, int length, int array_size, const int *value)
SpecializationBatchHandle GPU_shader_batch_specializations(blender::Span< ShaderSpecialization > specializations)
GPUShader * GPU_shader_create_from_info_name(const char *info_name)
int GPU_shader_get_ssbo_vertex_fetch_num_verts_per_prim(GPUShader *shader)
bool GPU_shader_uses_ssbo_vertex_fetch(GPUShader *shader)
void GPU_shader_cache_dir_clear_old()
void GPU_shader_uniform_1f(GPUShader *sh, const char *name, float value)
GPUShader * GPU_shader_create_from_python(const char *vertcode, const char *fragcode, const char *geomcode, const char *libcode, const char *defines, const char *name)
void GPU_shader_uniform_mat3_as_mat4(GPUShader *sh, const char *name, const float data[3][3])
void GPU_shader_uniform_3fv(GPUShader *sh, const char *name, const float data[3])
void GPU_shader_constant_uint(GPUShader *sh, const char *name, unsigned int value)
void GPU_shader_uniform_1f_array(GPUShader *sh, const char *name, int len, const float *val)
int GPU_shader_get_ssbo_binding(GPUShader *shader, const char *name)
unsigned int GPU_shader_get_attribute_len(const GPUShader *shader)
int GPU_shader_get_attribute(const GPUShader *shader, const char *name)
bool GPU_shader_transform_feedback_enable(GPUShader *shader, blender::gpu::VertBuf *vertbuf)
void GPU_shader_uniform_2iv(GPUShader *sh, const char *name, const int data[2])
void GPU_shader_uniform_4fv_array(GPUShader *sh, const char *name, int len, const float(*val)[4])
void GPU_shader_constant_bool_ex(GPUShader *sh, int location, bool value)
int64_t BatchHandle
Definition GPU_shader.hh:68
void GPU_shader_constant_int_ex(GPUShader *sh, int location, int value)
void GPU_shader_set_parent(GPUShader *shader, GPUShader *parent)
bool GPU_shader_batch_is_ready(BatchHandle handle)
int GPU_shader_get_builtin_block(GPUShader *shader, int builtin)
void GPU_shader_uniform_float_ex(GPUShader *shader, int location, int length, int array_size, const float *value)
eGPUShaderTFBType
@ GPU_SHADER_TFB_NONE
const GPUShaderCreateInfo * GPU_shader_create_info_get(const char *info_name)
void GPU_shader_transform_feedback_disable(GPUShader *shader)
int GPU_shader_get_program(GPUShader *shader)
void GPU_shader_bind(GPUShader *shader)
void GPU_shader_constant_float_ex(GPUShader *sh, int location, float value)
void GPU_shader_uniform_1b(GPUShader *sh, const char *name, bool value)
GPUUniformBuiltin
@ GPU_UNIFORM_SRGB_TRANSFORM
GPUShader * GPU_shader_create_from_info(const GPUShaderCreateInfo *_info)
void GPU_shader_uniform_4fv(GPUShader *sh, const char *name, const float data[4])
void GPU_shader_uniform_4f(GPUShader *sh, const char *name, float x, float y, float z, float w)
void GPU_shader_constant_uint_ex(GPUShader *sh, int location, unsigned int value)
int GPU_shader_get_uniform_block(GPUShader *shader, const char *name)
int64_t SpecializationBatchHandle
BatchHandle GPU_shader_batch_create_from_infos(blender::Span< const GPUShaderCreateInfo * > infos)
void GPU_shader_uniform_mat4(GPUShader *sh, const char *name, const float data[4][4])
int GPU_shader_get_constant(GPUShader *shader, const char *name)
void GPU_shader_constant_bool(GPUShader *sh, const char *name, bool value)
int GPU_shader_get_builtin_uniform(GPUShader *shader, int builtin)
void GPU_shader_free(GPUShader *shader)
GPUShader * GPU_shader_create_compute(const char *computecode, const char *libcode, const char *defines, const char *shname)
bool GPU_shader_create_info_check_error(const GPUShaderCreateInfo *_info, char r_error[128])
void GPU_shader_unbind()
void GPU_shader_create_info_get_unfinalized_copy(const char *info_name, GPUShaderCreateInfo &r_info)
GPUShader * GPU_shader_create_ex(const char *vertcode, const char *fragcode, const char *geomcode, const char *computecode, const char *libcode, const char *defines, eGPUShaderTFBType tf_type, const char **tf_names, int tf_count, const char *shname)
GPUShader * GPU_shader_get_bound()
void GPU_shader_warm_cache(GPUShader *shader, int limit)
GPUUniformBlockBuiltin
bool GPU_shader_batch_specializations_is_ready(SpecializationBatchHandle &handle)
void GPU_shader_constant_float(GPUShader *sh, const char *name, float value)
void GPU_shader_compile_static()
void GPU_storagebuf_bind(GPUStorageBuf *ssbo, int slot)
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
struct GPUShader GPUShader
SIMD_FORCE_INLINE const btScalar & z() const
Return the z value.
Definition btQuadWord.h:117
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition btQuadWord.h:119
constexpr int64_t size() const
Definition BLI_span.hh:253
constexpr bool is_empty() const
constexpr const char * c_str() const
int64_t size() const
void append(const T &value)
bool is_empty() const
void extend(Span< T > array)
Span< T > as_span() const
static Context * get()
static GPUBackend * get()
virtual void shader_cache_dir_clear_old()=0
virtual Shader * shader_alloc(const char *name)=0
virtual bool batch_is_ready(BatchHandle handle) override
virtual BatchHandle batch_compile(Span< const shader::ShaderCreateInfo * > &infos) override
virtual ~ShaderCompilerGeneric() override
virtual Vector< Shader * > batch_finalize(BatchHandle &handle) override
Shader * compile(const shader::ShaderCreateInfo &info, bool is_batch_compilation)
virtual Vector< Shader * > batch_finalize(BatchHandle &handle)=0
virtual bool specialization_batch_is_ready(SpecializationBatchHandle &handle)
virtual bool batch_is_ready(BatchHandle handle)=0
virtual BatchHandle batch_compile(Span< const shader::ShaderCreateInfo * > &infos)=0
virtual SpecializationBatchHandle precompile_specializations(Span< ShaderSpecialization >)
int32_t uniform_builtin(const GPUUniformBuiltin builtin) const
int32_t ubo_builtin(const GPUUniformBlockBuiltin builtin) const
virtual void unbind()=0
std::string defines_declare(const shader::ShaderCreateInfo &info) const
Definition gpu_shader.cc:33
virtual void init(const shader::ShaderCreateInfo &info, bool is_batch_compilation)=0
void parent_set(Shader *parent)
virtual void bind()=0
#define printf
int len
struct @620::@622 batch
static void standard_defines(Vector< const char * > &sources)
Definition gpu_shader.cc:65
char datatoc_gpu_shader_colorspace_lib_glsl[]
Definition gpu_shader.cc:29
const GPUShaderCreateInfo * gpu_shader_create_info_get(const char *info_name)
bool gpu_shader_create_info_compile(const char *name_starts_with_filter)
void gpu_shader_create_info_get_unfinalized_copy(const char *info_name, GPUShaderCreateInfo &r_info)
#define GPU_SHADER_PRINTF_SLOT
static void error(const char *str)
static Context * unwrap(GPUContext *ctx)
static int g_shader_builtin_srgb_transform
static GPUContext * wrap(Context *ctx)
static bool g_shader_builtin_srgb_is_dirty
bool assign_if_different(T &old_value, T new_value)
unsigned int uint32_t
Definition stdint.h:80
signed int int32_t
Definition stdint.h:77
Describe inputs & outputs, stage interfaces, resources and sources of a shader. If all data is correc...
Vector< std::array< StringRefNull, 2 > > defines_
Vector< SpecializationConstant > specialization_constants_