Blender V5.0
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
8
9#include "BLI_colorspace.hh"
10#include "BLI_math_matrix.h"
12#include "BLI_string.h"
13
14#include "GPU_capabilities.hh"
15#include "GPU_debug.hh"
16#include "GPU_matrix.hh"
17#include "GPU_platform.hh"
18
20
21#include "gpu_backend.hh"
23#include "gpu_profile_report.hh"
27#include "gpu_shader_private.hh"
28
29#include <string>
30
32
33namespace blender::gpu {
34
36{
37 std::string defines;
38 for (const auto &def : info.defines_) {
39 defines += "#define ";
40 defines += def[0];
41 defines += " ";
42 defines += def[1];
43 defines += "\n";
44 }
45 return defines;
46}
47
48} // namespace blender::gpu
49
50using namespace blender;
51using namespace blender::gpu;
52
53/* -------------------------------------------------------------------- */
56
57Shader::Shader(const char *sh_name)
58{
59 STRNCPY(this->name, sh_name);
60}
61
63{
64 BLI_assert_msg(Context::get() == nullptr || Context::get()->shader != this,
65 "Shader must be unbound from context before being freed");
66 delete interface;
67}
68
70{
71 BLI_assert(sources.is_empty());
72 /* Version and specialization constants needs to be first.
73 * Exact values will be added by implementation. */
74 sources.append("version");
75 sources.append("/* specialization_constants */");
76 /* Define to identify code usage in shading language. */
77 sources.append("#define GPU_SHADER\n");
78 /* some useful defines to detect GPU type */
80 sources.append("#define GPU_ATI\n");
81 }
83 sources.append("#define GPU_NVIDIA\n");
84 }
86 sources.append("#define GPU_INTEL\n");
87 }
89 sources.append("#define GPU_APPLE\n");
90 }
91 /* some useful defines to detect OS type */
93 sources.append("#define OS_WIN\n");
94 }
96 sources.append("#define OS_MAC\n");
97 }
99 sources.append("#define OS_UNIX\n");
100 }
101 /* API Definition */
103 switch (backend) {
105 sources.append("#define GPU_OPENGL\n");
106 break;
108 sources.append("#define GPU_METAL\n");
109 break;
111 sources.append("#define GPU_VULKAN\n");
112 break;
113 default:
114 BLI_assert_msg(false, "Invalid GPU Backend Type");
115 break;
116 }
117}
118
123
125
126/* -------------------------------------------------------------------- */
129
130const GPUShaderCreateInfo *GPU_shader_create_info_get(const char *info_name)
131{
132 return gpu_shader_create_info_get(info_name);
133}
134
135bool GPU_shader_create_info_check_error(const GPUShaderCreateInfo *_info, char r_error[128])
136{
137 using namespace blender::gpu::shader;
138 const ShaderCreateInfo &info = *reinterpret_cast<const ShaderCreateInfo *>(_info);
139 std::string error = info.check_error();
140 if (error.length() == 0) {
141 return true;
142 }
143
144 BLI_strncpy(r_error, error.c_str(), 128);
145 return false;
146}
147
149{
150 using namespace blender::gpu::shader;
151 const GPUShaderCreateInfo *_info = gpu_shader_create_info_get(info_name);
152 const ShaderCreateInfo &info = *reinterpret_cast<const ShaderCreateInfo *>(_info);
153 if (!info.do_static_compilation_) {
154 std::cerr << "Warning: Trying to compile \"" << info.name_
155 << "\" which was not marked for static compilation.\n";
156 }
157 return GPU_shader_create_from_info(_info);
158}
159
160blender::gpu::Shader *GPU_shader_create_from_info(const GPUShaderCreateInfo *_info)
161{
162 using namespace blender::gpu::shader;
163 const ShaderCreateInfo &info = *reinterpret_cast<const ShaderCreateInfo *>(_info);
164 return GPUBackend::get()->get_compiler()->compile(info, false);
165}
166
168{
169 if (original.is_empty()) {
170 return original;
171 }
173 return processor.process(original);
174};
175
177{
178 using namespace blender::gpu::shader;
179 ShaderCreateInfo &info = *const_cast<ShaderCreateInfo *>(
180 reinterpret_cast<const ShaderCreateInfo *>(_info));
181
182 std::string vertex_source_original = info.vertex_source_generated;
183 std::string fragment_source_original = info.fragment_source_generated;
184 std::string geometry_source_original = info.geometry_source_generated;
185 std::string compute_source_original = info.compute_source_generated;
186
191
193
194 info.vertex_source_generated = vertex_source_original;
195 info.fragment_source_generated = fragment_source_original;
196 info.geometry_source_generated = geometry_source_original;
197 info.compute_source_generated = compute_source_original;
198
199 return result;
200}
201
210
212{
213 return GPUBackend::get()->get_compiler()->batch_is_ready(handle);
214}
215
221
226
231
236
238{
239 printf("Compiling all static GPU shaders. This process takes a while.\n");
241}
242
247
249
250/* -------------------------------------------------------------------- */
253
255 const shader::SpecializationConstants *constants_state)
256{
257 Shader *shader = gpu_shader;
258
259 BLI_assert_msg(constants_state != nullptr || shader->constants->is_empty(),
260 "Shader requires specialization constants but none was passed");
261
262 Context *ctx = Context::get();
263
264 if (ctx->shader != shader) {
265 ctx->shader = shader;
266 shader->bind(constants_state);
267 GPU_matrix_bind(gpu_shader);
268 Shader::set_srgb_uniform(ctx, gpu_shader);
269 /* Blender working color space do not change during the drawing of the frame.
270 * So we can just set the uniform once. */
272 }
273 else {
274 if (constants_state) {
275 shader->bind(constants_state);
276 }
278 Shader::set_srgb_uniform(ctx, gpu_shader);
279 }
280 if (GPU_matrix_dirty_get()) {
281 GPU_matrix_bind(gpu_shader);
282 }
283 }
284#if GPU_SHADER_PRINTF_ENABLE
285 if (!ctx->printf_buf.is_empty()) {
287 }
288#endif
289}
290
292{
293 Context *ctx = Context::get();
294 if (ctx == nullptr) {
295 return;
296 }
297#ifndef NDEBUG
298 if (ctx->shader) {
299 ctx->shader->unbind();
300 }
301#endif
302 ctx->shader = nullptr;
303}
304
306{
307 Context *ctx = Context::get();
308 if (ctx) {
309 return ctx->shader;
310 }
311 return nullptr;
312}
313
315
316/* -------------------------------------------------------------------- */
319
321{
322 return shader->name_get().c_str();
323}
324
326
327/* -------------------------------------------------------------------- */
330
332{
333 BLI_assert(shader != nullptr);
334 BLI_assert(shader != parent);
335 if (shader != parent) {
336 Shader *shd_child = shader;
337 Shader *shd_parent = parent;
338 shd_child->parent_set(shd_parent);
339 }
340}
341
343{
344 shader->warm_cache(limit);
345}
346
348
349/* -------------------------------------------------------------------- */
352
358
360{
361 using namespace shader;
364 constants_tmp.types.append(sc.type);
365 constants_tmp.values.append(sc.value);
366 }
367 constants = std::make_unique<const shader::SpecializationConstants>(std::move(constants_tmp));
368}
369
375
380
385
387
388/* -------------------------------------------------------------------- */
391
393{
394 const ShaderInterface *interface = shader->interface;
395 const ShaderInput *uniform = interface->uniform_get(name);
396 return uniform ? uniform->location : -1;
397}
398
400{
401 const ShaderInterface *interface = shader->interface;
402 const ShaderInput *constant = interface->constant_get(name);
403 return constant ? constant->location : -1;
404}
405
407{
408 const ShaderInterface *interface = shader->interface;
409 return interface->uniform_builtin((GPUUniformBuiltin)builtin);
410}
411
413{
414 const ShaderInterface *interface = shader->interface;
415 const ShaderInput *ssbo = interface->ssbo_get(name);
416 return ssbo ? ssbo->location : -1;
417}
418
420{
421 const ShaderInterface *interface = shader->interface;
422 const ShaderInput *ubo = interface->ubo_get(name);
423 return ubo ? ubo->location : -1;
424}
425
427{
428 const ShaderInterface *interface = shader->interface;
429 const ShaderInput *ubo = interface->ubo_get(name);
430 return ubo ? ubo->binding : -1;
431}
432
434{
435 const ShaderInterface *interface = shader->interface;
436 const ShaderInput *tex = interface->uniform_get(name);
437 return tex ? tex->binding : -1;
438}
439
441{
442 const ShaderInterface *interface = shader->interface;
443 return interface->valid_bindings_get(interface->inputs_, interface->attr_len_);
444}
445
447{
448 const ShaderInterface *interface = shader->interface;
449 return interface->ssbo_len_;
450}
451
453{
454 const ShaderInterface *interface = shader->interface;
455 const ShaderInput *attr = interface->attr_get(name);
456 return attr ? attr->location : -1;
457}
458
460 int attr_location,
461 char r_name[256],
462 int *r_type)
463{
464 const ShaderInterface *interface = shader->interface;
465
466 const ShaderInput *attr = interface->attr_get(attr_location);
467 if (!attr) {
468 return false;
469 }
470
471 BLI_strncpy(r_name, interface->input_name_get(attr), 256);
472 *r_type = attr->location != -1 ? interface->attr_types_[attr->location] : -1;
473 return true;
474}
475
477 int ssbo_location,
478 char r_name[256])
479{
480 const ShaderInterface *interface = shader->interface;
481
482 const ShaderInput *ssbo_input = interface->ssbo_get(ssbo_location);
483 if (!ssbo_input) {
484 return false;
485 }
486
487 BLI_strncpy(r_name, interface->input_name_get(ssbo_input), 256);
488 return true;
489}
490
492
493/* -------------------------------------------------------------------- */
496
498 blender::gpu::Shader *shader, int loc, int len, int array_size, const float *value)
499{
500 shader->uniform_float(loc, len, array_size, value);
501}
502
504 blender::gpu::Shader *shader, int loc, int len, int array_size, const int *value)
505{
506 shader->uniform_int(loc, len, array_size, value);
507}
508
509void GPU_shader_uniform_1i(blender::gpu::Shader *sh, const char *name, int value)
510{
511 const int loc = GPU_shader_get_uniform(sh, name);
512 GPU_shader_uniform_int_ex(sh, loc, 1, 1, &value);
513}
514
515void GPU_shader_uniform_1b(blender::gpu::Shader *sh, const char *name, bool value)
516{
517 GPU_shader_uniform_1i(sh, name, value ? 1 : 0);
518}
519
520void GPU_shader_uniform_2f(blender::gpu::Shader *sh, const char *name, float x, float y)
521{
522 const float data[2] = {x, y};
524}
525
526void GPU_shader_uniform_3f(blender::gpu::Shader *sh, const char *name, float x, float y, float z)
527{
528 const float data[3] = {x, y, z};
530}
531
533 blender::gpu::Shader *sh, const char *name, float x, float y, float z, float w)
534{
535 const float data[4] = {x, y, z, w};
537}
538
539void GPU_shader_uniform_1f(blender::gpu::Shader *sh, const char *name, float value)
540{
541 const int loc = GPU_shader_get_uniform(sh, name);
542 GPU_shader_uniform_float_ex(sh, loc, 1, 1, &value);
543}
544
545void GPU_shader_uniform_2fv(blender::gpu::Shader *sh, const char *name, const float data[2])
546{
547 const int loc = GPU_shader_get_uniform(sh, name);
548 GPU_shader_uniform_float_ex(sh, loc, 2, 1, data);
549}
550
551void GPU_shader_uniform_3fv(blender::gpu::Shader *sh, const char *name, const float data[3])
552{
553 const int loc = GPU_shader_get_uniform(sh, name);
554 GPU_shader_uniform_float_ex(sh, loc, 3, 1, data);
555}
556
557void GPU_shader_uniform_4fv(blender::gpu::Shader *sh, const char *name, const float data[4])
558{
559 const int loc = GPU_shader_get_uniform(sh, name);
560 GPU_shader_uniform_float_ex(sh, loc, 4, 1, data);
561}
562
563void GPU_shader_uniform_2iv(blender::gpu::Shader *sh, const char *name, const int data[2])
564{
565 const int loc = GPU_shader_get_uniform(sh, name);
566 GPU_shader_uniform_int_ex(sh, loc, 2, 1, data);
567}
568
569void GPU_shader_uniform_3iv(blender::gpu::Shader *sh, const char *name, const int data[3])
570{
571 const int loc = GPU_shader_get_uniform(sh, name);
572 GPU_shader_uniform_int_ex(sh, loc, 3, 1, data);
573}
574
575void GPU_shader_uniform_mat4(blender::gpu::Shader *sh, const char *name, const float data[4][4])
576{
577 const int loc = GPU_shader_get_uniform(sh, name);
578 GPU_shader_uniform_float_ex(sh, loc, 16, 1, (const float *)data);
579}
580
582 const char *name,
583 const float data[3][3])
584{
585 float matrix[4][4];
586 copy_m4_m3(matrix, data);
587 GPU_shader_uniform_mat4(sh, name, matrix);
588}
589
591 const char *name,
592 int len,
593 const float *val)
594{
595 const int loc = GPU_shader_get_uniform(sh, name);
596 GPU_shader_uniform_float_ex(sh, loc, 1, len, val);
597}
598
600 const char *name,
601 int len,
602 const float (*val)[2])
603{
604 const int loc = GPU_shader_get_uniform(sh, name);
605 GPU_shader_uniform_float_ex(sh, loc, 2, len, (const float *)val);
606}
607
609 const char *name,
610 int len,
611 const float (*val)[4])
612{
613 const int loc = GPU_shader_get_uniform(sh, name);
614 GPU_shader_uniform_float_ex(sh, loc, 4, len, (const float *)val);
615}
616
618
619namespace blender::gpu {
620
621/* -------------------------------------------------------------------- */
631
640
649
650void Shader::set_framebuffer_srgb_target(int use_srgb_to_linear)
651{
652 Context *ctx = Context::get();
653 if (ctx->shader_builtin_srgb_transform != use_srgb_to_linear) {
654 ctx->shader_builtin_srgb_transform = use_srgb_to_linear;
656 }
657}
658
660
661/* -------------------------------------------------------------------- */
664
665Shader *ShaderCompiler::compile(const shader::ShaderCreateInfo &info, bool is_batch_compilation)
666{
667 using Clock = std::chrono::steady_clock;
668 using TimePoint = Clock::time_point;
669
670 using namespace blender::gpu::shader;
671 const_cast<ShaderCreateInfo &>(info).finalize();
673
674 TimePoint start_time;
675
676 if (Context::get()) {
677 /* Context can be null in Vulkan compilation threads. */
680 }
681 else if (G.profile_gpu) {
682 start_time = Clock::now();
683 }
684
685 const std::string error = info.check_error();
686 if (!error.empty()) {
687 std::cerr << error << "\n";
688 BLI_assert(false);
689 }
690
692 /* Needs to be called before init as GL uses the default specialization constants state to insert
693 * default shader inside a map. */
694 shader->specialization_constants_init(info);
695 shader->init(info, is_batch_compilation);
696
697 shader->fragment_output_bits = 0;
698 for (const shader::ShaderCreateInfo::FragOut &frag_out : info.fragment_outputs_) {
699 shader->fragment_output_bits |= 1u << frag_out.index;
700 }
701
702 std::string defines = shader->defines_declare(info);
703 std::string resources = shader->resources_declare(info);
704
705 info.resource_guard_defines(defines);
706
707 defines += "#define USE_GPU_SHADER_CREATE_INFO\n";
708
709 Vector<StringRefNull> typedefs;
710 if (!info.typedef_sources_.is_empty() || !info.typedef_source_generated.empty()) {
711 typedefs.append(gpu_shader_dependency_get_source("GPU_shader_shared_utils.hh").c_str());
712 }
713 if (!info.typedef_source_generated.empty()) {
714 typedefs.append(info.typedef_source_generated);
715 }
716 for (auto filename : info.typedef_sources_) {
717 typedefs.extend_non_duplicates(
719 }
720
721 if (!info.vertex_source_.is_empty()) {
723 info.vertex_source_, info.generated_sources, info.name_);
724 std::string interface = shader->vertex_interface_declare(info);
725
726 Vector<StringRefNull> sources;
727 standard_defines(sources);
728 sources.append("#define GPU_VERTEX_SHADER\n");
729 if (!info.geometry_source_.is_empty()) {
730 sources.append("#define USE_GEOMETRY_SHADER\n");
731 }
732 sources.append(defines);
733 sources.extend(typedefs);
734 sources.append(resources);
735 sources.append(interface);
736 sources.extend(code);
737 sources.append(info.vertex_source_generated);
738
739 if (info.vertex_entry_fn_ != "main") {
740 sources.append("void main() { ");
741 sources.append(info.vertex_entry_fn_);
742 sources.append("(); }\n");
743 }
744
745 shader->vertex_shader_from_glsl(sources);
746 }
747
748 if (!info.fragment_source_.is_empty()) {
750 info.fragment_source_, info.generated_sources, info.name_);
751 std::string interface = shader->fragment_interface_declare(info);
752
753 Vector<StringRefNull> sources;
754 standard_defines(sources);
755 sources.append("#define GPU_FRAGMENT_SHADER\n");
756 if (!info.geometry_source_.is_empty()) {
757 sources.append("#define USE_GEOMETRY_SHADER\n");
758 }
759 sources.append(defines);
760 sources.extend(typedefs);
761 sources.append(resources);
762 sources.append(interface);
763 sources.extend(code);
764 sources.append(info.fragment_source_generated);
765
766 if (info.fragment_entry_fn_ != "main") {
767 sources.append("void main() { ");
768 sources.append(info.fragment_entry_fn_);
769 sources.append("(); }\n");
770 }
771
772 shader->fragment_shader_from_glsl(sources);
773 }
774
775 if (!info.geometry_source_.is_empty()) {
777 info.geometry_source_, info.generated_sources, info.name_);
778 std::string layout = shader->geometry_layout_declare(info);
779 std::string interface = shader->geometry_interface_declare(info);
780
781 Vector<StringRefNull> sources;
782 standard_defines(sources);
783 sources.append("#define GPU_GEOMETRY_SHADER\n");
784 sources.append(defines);
785 sources.extend(typedefs);
786 sources.append(resources);
787 sources.append(layout);
788 sources.append(interface);
789 sources.append(info.geometry_source_generated);
790 sources.extend(code);
791
792 if (info.geometry_entry_fn_ != "main") {
793 sources.append("void main() { ");
794 sources.append(info.geometry_entry_fn_);
795 sources.append("(); }\n");
796 }
797
798 shader->geometry_shader_from_glsl(sources);
799 }
800
801 if (!info.compute_source_.is_empty()) {
803 info.compute_source_, info.generated_sources, info.name_);
804 std::string layout = shader->compute_layout_declare(info);
805
806 Vector<StringRefNull> sources;
807 standard_defines(sources);
808 sources.append("#define GPU_COMPUTE_SHADER\n");
809 sources.append(defines);
810 sources.extend(typedefs);
811 sources.append(resources);
812 sources.append(layout);
813 sources.extend(code);
814 sources.append(info.compute_source_generated);
815
816 if (info.compute_entry_fn_ != "main") {
817 sources.append("void main() { ");
818 sources.append(info.compute_entry_fn_);
819 sources.append("(); }\n");
820 }
821
822 shader->compute_shader_from_glsl(sources);
823 }
824
825 if (!shader->finalize(&info)) {
826 delete shader;
827 shader = nullptr;
828 }
829
830 if (Context::get()) {
831 /* Context can be null in Vulkan compilation threads. */
834 }
835 else if (G.profile_gpu) {
836 TimePoint end_time = Clock::now();
837 /* Note: Used by the vulkan backend. Use the same time_since_epoch as process_frame_timings. */
839 start_time.time_since_epoch().count(),
840 end_time.time_since_epoch().count());
842 start_time.time_since_epoch().count(),
843 end_time.time_since_epoch().count());
844 }
845
846 return shader;
847}
848
849ShaderCompiler::ShaderCompiler(uint32_t threads_count,
850 GPUWorker::ContextType context_type,
851 bool support_specializations)
852{
853 support_specializations_ = support_specializations;
854
856 compilation_worker_ = std::make_unique<GPUWorker>(
857 threads_count,
858 context_type,
859 mutex_,
860 [this]() -> void * { return this->pop_work(); },
861 [this](void *work) { this->do_work(work); });
862 }
863}
864
866{
867 compilation_worker_.reset();
868
869 /* Ensure all the requested batches have been retrieved. */
870 BLI_assert(batches_.is_empty());
871}
872
874{
875 return compile(info, false);
876}
877
879 CompilationPriority priority)
880{
881 std::unique_lock lock(mutex_);
882
883 Batch *batch = MEM_new<Batch>(__func__);
884 batch->infos = infos;
885 batch->shaders.reserve(infos.size());
886
887 BatchHandle handle = next_batch_handle_++;
888 batches_.add(handle, batch);
889
890 if (compilation_worker_) {
891 batch->shaders.resize(infos.size(), nullptr);
892 batch->pending_compilations = infos.size();
893 for (int i : infos.index_range()) {
894 compilation_queue_.push({batch, i}, priority);
895 compilation_worker_->wake_up();
896 }
897 }
898 else {
899 for (const shader::ShaderCreateInfo *info : infos) {
900 batch->shaders.append(compile(*info, false));
901 }
902 }
903
904 return handle;
905}
906
908{
909 std::unique_lock lock(mutex_);
910
911 Batch *batch = batches_.pop(handle);
912 compilation_queue_.remove_batch(batch);
913
914 /* If it was already being compiled, wait until it's ready so the calling thread can safely
915 * delete the ShaderCreateInfos. */
916 compilation_finished_notification_.wait(lock, [&]() { return batch->is_ready(); });
917 batch->free_shaders();
918 MEM_delete(batch);
919
920 handle = 0;
921}
922
924{
925 std::lock_guard lock(mutex_);
926
927 return batches_.lookup(handle)->is_ready();
928}
929
931{
932 std::unique_lock lock(mutex_);
933 /* TODO: Move to be first on the queue. */
934 compilation_finished_notification_.wait(lock,
935 [&]() { return batches_.lookup(handle)->is_ready(); });
936
937 Batch *batch = batches_.pop(handle);
938 Vector<Shader *> shaders = std::move(batch->shaders);
939 MEM_delete(batch);
940 handle = 0;
941
942 return shaders;
943}
944
946 Span<ShaderSpecialization> specializations, CompilationPriority priority)
947{
948 if (!compilation_worker_ || !support_specializations_) {
949 return 0;
950 }
951
952 std::lock_guard lock(mutex_);
953
954 Batch *batch = MEM_new<Batch>(__func__);
955 batch->specializations = specializations;
956
957 BatchHandle handle = next_batch_handle_++;
958 batches_.add(handle, batch);
959
960 batch->pending_compilations = specializations.size();
961 for (int i : specializations.index_range()) {
962 compilation_queue_.push({batch, i}, priority);
963 compilation_worker_->wake_up();
964 }
965
966 return handle;
967}
968
970{
971 if (handle != 0 && batch_is_ready(handle)) {
972 std::lock_guard lock(mutex_);
973
974 Batch *batch = batches_.pop(handle);
975 MEM_delete(batch);
976 handle = 0;
977 }
978
979 return handle == 0;
980}
981
982void *ShaderCompiler::pop_work()
983{
984 /* NOTE: Already under mutex lock when GPUWorker calls this function. */
985
986 if (compilation_queue_.is_empty()) {
987 return nullptr;
988 }
989
990 ParallelWork work = compilation_queue_.pop();
991 return MEM_new<ParallelWork>(__func__, work);
992}
993
994void ShaderCompiler::do_work(void *work_payload)
995{
996 ParallelWork *work = reinterpret_cast<ParallelWork *>(work_payload);
997 Batch *batch = work->batch;
998 int shader_index = work->shader_index;
999 MEM_delete(work);
1000
1001 /* Compile */
1002 if (!batch->is_specialization_batch()) {
1003 batch->shaders[shader_index] = compile_shader(*batch->infos[shader_index]);
1004 }
1005 else {
1006 specialize_shader(batch->specializations[shader_index]);
1007 }
1008
1009 {
1010 std::unique_lock lock(mutex_);
1011 batch->pending_compilations--;
1012 }
1013
1014 compilation_finished_notification_.notify_all();
1015}
1016
1017bool ShaderCompiler::is_compiling_impl()
1018{
1019 /* The mutex should be locked before calling this function. */
1020 BLI_assert(!mutex_.try_lock());
1021
1022 if (!compilation_queue_.is_empty()) {
1023 return true;
1024 }
1025
1026 for (Batch *batch : batches_.values()) {
1027 if (!batch->is_ready()) {
1028 return true;
1029 }
1030 }
1031
1032 return false;
1033}
1034
1036{
1037 std::unique_lock lock(mutex_);
1038 return is_compiling_impl();
1039}
1040
1042{
1043 std::unique_lock lock(mutex_);
1044 compilation_finished_notification_.wait(lock, [&]() { return !is_compiling_impl(); });
1045}
1046
1048
1049} // namespace blender::gpu
#define BLI_assert(a)
Definition BLI_assert.h:46
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:53
void copy_m4_m3(float m1[4][4], const float m2[3][3])
char * STRNCPY(char(&dst)[N], const char *src)
Definition BLI_string.h:693
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
unsigned int uint
bool GPU_use_main_context_workaround()
GPUBackendType 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:64
void GPU_matrix_bind(blender::gpu::Shader *shader)
bool GPU_matrix_dirty_get()
@ GPU_DEVICE_ATI
@ GPU_DEVICE_NVIDIA
@ GPU_DEVICE_ANY
@ GPU_DEVICE_APPLE
@ GPU_DEVICE_INTEL
bool GPU_type_matches(GPUDeviceType device, GPUOSType os, GPUDriverType driver)
@ GPU_DRIVER_ANY
@ GPU_OS_WIN
@ GPU_OS_UNIX
@ GPU_OS_ANY
@ GPU_OS_MAC
blender::gpu::Shader * GPU_shader_create_from_info_python(const GPUShaderCreateInfo *_info)
int GPU_shader_get_ubo_binding(blender::gpu::Shader *shader, const char *name)
void GPU_shader_uniform_2fv_array(blender::gpu::Shader *sh, const char *name, int len, const float(*val)[2])
int GPU_shader_get_constant(blender::gpu::Shader *shader, const char *name)
void GPU_shader_uniform_1b(blender::gpu::Shader *sh, const char *name, bool value)
const blender::gpu::shader::SpecializationConstants & GPU_shader_get_default_constant_state(blender::gpu::Shader *sh)
int GPU_shader_get_uniform_block(blender::gpu::Shader *shader, const char *name)
void GPU_shader_uniform_4fv_array(blender::gpu::Shader *sh, const char *name, int len, const float(*val)[4])
void GPU_shader_uniform_1f(blender::gpu::Shader *sh, const char *name, float value)
void GPU_shader_cache_dir_clear_old()
void GPU_shader_free(blender::gpu::Shader *shader)
bool GPU_shader_get_attribute_info(const blender::gpu::Shader *shader, int attr_location, char r_name[256], int *r_type)
bool GPU_shader_get_ssbo_input_info(const blender::gpu::Shader *shader, int ssbo_location, char r_name[256])
blender::gpu::Shader * GPU_shader_create_from_info(const GPUShaderCreateInfo *_info)
void GPU_shader_uniform_4fv(blender::gpu::Shader *sh, const char *name, const float data[4])
void GPU_shader_uniform_mat3_as_mat4(blender::gpu::Shader *sh, const char *name, const float data[3][3])
int GPU_shader_get_sampler_binding(blender::gpu::Shader *shader, const char *name)
void GPU_shader_uniform_3fv(blender::gpu::Shader *sh, const char *name, const float data[3])
bool GPU_shader_batch_is_compiling()
void GPU_shader_batch_wait_for_all()
uint GPU_shader_get_attribute_len(const blender::gpu::Shader *shader)
int64_t BatchHandle
Definition GPU_shader.hh:82
uint GPU_shader_get_ssbo_input_len(const blender::gpu::Shader *shader)
void GPU_shader_bind(blender::gpu::Shader *shader, const blender::gpu::shader::SpecializationConstants *constants_state=nullptr)
blender::Vector< blender::gpu::Shader * > GPU_shader_batch_finalize(BatchHandle &handle)
bool GPU_shader_batch_is_ready(BatchHandle handle)
int GPU_shader_get_ssbo_binding(blender::gpu::Shader *shader, const char *name)
std::string GPU_shader_preprocess_source(blender::StringRefNull original)
blender::gpu::Shader * GPU_shader_get_bound()
SpecializationBatchHandle GPU_shader_batch_specializations(blender::Span< ShaderSpecialization > specializations, CompilationPriority priority=CompilationPriority::High)
const GPUShaderCreateInfo * GPU_shader_create_info_get(const char *info_name)
void GPU_shader_uniform_int_ex(blender::gpu::Shader *shader, int location, int length, int array_size, const int *value)
void GPU_shader_uniform_1i(blender::gpu::Shader *sh, const char *name, int value)
CompilationPriority
Definition GPU_shader.hh:80
void GPU_shader_batch_specializations_cancel(SpecializationBatchHandle &handle)
GPUUniformBuiltin
@ GPU_UNIFORM_SRGB_TRANSFORM
@ GPU_UNIFORM_SCENE_LINEAR_XFORM
void GPU_shader_uniform_mat4(blender::gpu::Shader *sh, const char *name, const float data[4][4])
void GPU_shader_uniform_4f(blender::gpu::Shader *sh, const char *name, float x, float y, float z, float w)
int64_t SpecializationBatchHandle
const char * GPU_shader_get_name(blender::gpu::Shader *shader)
int GPU_shader_get_attribute(const blender::gpu::Shader *shader, const char *name)
void GPU_shader_uniform_2f(blender::gpu::Shader *sh, const char *name, float x, float y)
void GPU_shader_set_parent(blender::gpu::Shader *shader, blender::gpu::Shader *parent)
blender::gpu::Shader * GPU_shader_create_from_info_name(const char *info_name)
void GPU_shader_uniform_2fv(blender::gpu::Shader *sh, const char *name, const float data[2])
int GPU_shader_get_uniform(blender::gpu::Shader *shader, const char *name)
void GPU_shader_batch_cancel(BatchHandle &handle)
void GPU_shader_uniform_1f_array(blender::gpu::Shader *sh, const char *name, int len, const float *val)
bool GPU_shader_create_info_check_error(const GPUShaderCreateInfo *_info, char r_error[128])
void GPU_shader_unbind()
void GPU_shader_warm_cache(blender::gpu::Shader *shader, int limit)
void GPU_shader_uniform_3f(blender::gpu::Shader *sh, const char *name, float x, float y, float z)
BatchHandle GPU_shader_batch_create_from_infos(blender::Span< const GPUShaderCreateInfo * > infos, CompilationPriority priority=CompilationPriority::High)
int GPU_shader_get_builtin_uniform(blender::gpu::Shader *shader, int builtin)
void GPU_shader_uniform_float_ex(blender::gpu::Shader *shader, int location, int length, int array_size, const float *value)
bool GPU_shader_batch_specializations_is_ready(SpecializationBatchHandle &handle)
void GPU_shader_compile_static()
void GPU_shader_uniform_2iv(blender::gpu::Shader *sh, const char *name, const int data[2])
void GPU_shader_uniform_3iv(blender::gpu::Shader *sh, const char *name, const int data[3])
void GPU_storagebuf_bind(blender::gpu::StorageBuf *ssbo, int slot)
volatile int lock
BMesh const char void * data
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
void append(const T &value)
constexpr int64_t size() const
Definition BLI_span.hh:252
constexpr IndexRange index_range() const
Definition BLI_span.hh:401
constexpr bool is_empty() const
constexpr const char * c_str() const
void append(const T &value)
bool is_empty() const
void extend(Span< T > array)
void extend_non_duplicates(Span< T > array)
Vector< StorageBuf * > printf_buf
static Context * get()
static GPUBackend * get()
ShaderCompiler * get_compiler()
virtual void shader_cache_dir_clear_old()=0
virtual Shader * shader_alloc(const char *name)=0
static ProfileReport & get()
void add_group_cpu(StringRefNull name, uint64_t cpu_start, uint64_t cpu_end)
void batch_cancel(BatchHandle &handle)
BatchHandle batch_compile(Span< const shader::ShaderCreateInfo * > &infos, CompilationPriority priority)
bool specialization_batch_is_ready(SpecializationBatchHandle &handle)
Vector< Shader * > batch_finalize(BatchHandle &handle)
Shader * compile(const shader::ShaderCreateInfo &info, bool is_batch_compilation)
bool batch_is_ready(BatchHandle handle)
ShaderCompiler(uint32_t threads_count=1, GPUWorker::ContextType context_type=GPUWorker::ContextType::PerThread, bool support_specializations=false)
SpecializationBatchHandle precompile_specializations(Span< ShaderSpecialization > specializations, CompilationPriority priority)
virtual Shader * compile_shader(const shader::ShaderCreateInfo &info)
virtual void unbind()=0
std::string defines_declare(const shader::ShaderCreateInfo &info) const
Definition gpu_shader.cc:35
std::unique_ptr< const shader::SpecializationConstants > constants
ShaderInterface * interface
void specialization_constants_init(const shader::ShaderCreateInfo &info)
void parent_set(Shader *parent)
static void set_scene_linear_to_xyz_uniform(gpu::Shader *shader)
static void set_framebuffer_srgb_target(int use_srgb_to_linear)
static void set_srgb_uniform(Context *ctx, gpu::Shader *shader)
std::string process(SourceLanguage language, std::string str, const std::string &filename, bool do_parse_function, bool do_small_type_linting, report_callback report_error, metadata::Source &r_metadata)
struct @021025263243242147216143265077100330027142264337::@225245033123204053237120173316075113304004012000 batch
static void standard_defines(Vector< StringRefNull > &sources)
Definition gpu_shader.cc:69
char datatoc_gpu_shader_colorspace_lib_glsl[]
Definition gpu_shader.cc:31
#define interface
#define printf(...)
const GPUShaderCreateInfo * gpu_shader_create_info_get(const char *info_name)
bool gpu_shader_create_info_compile(const char *name_starts_with_filter)
#define GPU_SHADER_PRINTF_SLOT
#define G(x, y, z)
static void error(const char *str)
float3x3 scene_linear_to_rec709
Vector< StringRefNull > gpu_shader_dependency_get_resolved_source(const StringRefNull shader_source_name, const shader::GeneratedSourceList &generated_sources, const StringRefNull shader_name)
StringRefNull gpu_shader_dependency_get_source(const StringRefNull shader_source_name)
const char * name
Describe inputs & outputs, stage interfaces, resources and sources of a shader. If all data is correc...
std::string fragment_source_generated
std::string check_error() const
std::string geometry_source_generated
Describe inputs & outputs, stage interfaces, resources and sources of a shader. If all data is correc...
Vector< std::array< StringRefNull, 2 > > defines_
void resource_guard_defines(std::string &defines) const
Vector< SpecializationConstant > specialization_constants_
Vector< SpecializationConstant::Value, 8 > values
i
Definition text_draw.cc:230
uint len
PointerRNA * ptr
Definition wm_files.cc:4238