Blender V4.3
gl_shader.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2020 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include <iomanip>
10
11#include "BKE_appdir.hh"
12#include "BKE_global.hh"
13
14#include "BLI_string.h"
15#include "BLI_time.h"
16#include "BLI_vector.hh"
17
18#include "BLI_system.h"
19#include BLI_SYSTEM_PID_H
20
21#include "GPU_capabilities.hh"
22#include "GPU_platform.hh"
25
26#include "gl_debug.hh"
27#include "gl_vertex_buffer.hh"
28
30#include "gl_shader.hh"
32
33#include <sstream>
34#include <stdio.h>
35#ifdef WIN32
36# define popen _popen
37# define pclose _pclose
38#endif
39
40using namespace blender;
41using namespace blender::gpu;
42using namespace blender::gpu::shader;
43
45
46/* -------------------------------------------------------------------- */
50GLShader::GLShader(const char *name) : Shader(name)
51{
52#if 0 /* Would be nice to have, but for now the Deferred compilation \
53 * does not have a GPUContext. */
54 BLI_assert(GLContext::get() != nullptr);
55#endif
56}
57
59{
60#if 0 /* Would be nice to have, but for now the Deferred compilation \
61 * does not have a GPUContext. */
62 BLI_assert(GLContext::get() != nullptr);
63#endif
64}
65
66void GLShader::init(const shader::ShaderCreateInfo &info, bool is_batch_compilation)
67{
68 async_compilation_ = is_batch_compilation;
69
70 /* Extract the constants names from info and store them locally. */
71 for (const SpecializationConstant &constant : info.specialization_constants_) {
72 specialization_constant_names_.append(constant.name.c_str());
73 }
74}
75
78/* -------------------------------------------------------------------- */
82static const char *to_string(const Interpolation &interp)
83{
84 switch (interp) {
85 case Interpolation::SMOOTH:
86 return "smooth";
87 case Interpolation::FLAT:
88 return "flat";
89 case Interpolation::NO_PERSPECTIVE:
90 return "noperspective";
91 default:
92 return "unknown";
93 }
94}
95
96static const char *to_string(const Type &type)
97{
98 switch (type) {
99 case Type::FLOAT:
100 return "float";
101 case Type::VEC2:
102 return "vec2";
103 case Type::VEC3:
104 return "vec3";
105 case Type::VEC4:
106 return "vec4";
107 case Type::MAT3:
108 return "mat3";
109 case Type::MAT4:
110 return "mat4";
111 case Type::UINT:
112 return "uint";
113 case Type::UVEC2:
114 return "uvec2";
115 case Type::UVEC3:
116 return "uvec3";
117 case Type::UVEC4:
118 return "uvec4";
119 case Type::INT:
120 return "int";
121 case Type::IVEC2:
122 return "ivec2";
123 case Type::IVEC3:
124 return "ivec3";
125 case Type::IVEC4:
126 return "ivec4";
127 case Type::BOOL:
128 return "bool";
129 /* Alias special types. */
130 case Type::UCHAR:
131 case Type::USHORT:
132 return "uint";
133 case Type::UCHAR2:
134 case Type::USHORT2:
135 return "uvec2";
136 case Type::UCHAR3:
137 case Type::USHORT3:
138 return "uvec3";
139 case Type::UCHAR4:
140 case Type::USHORT4:
141 return "uvec4";
142 case Type::CHAR:
143 case Type::SHORT:
144 return "int";
145 case Type::CHAR2:
146 case Type::SHORT2:
147 return "ivec2";
148 case Type::CHAR3:
149 case Type::SHORT3:
150 return "ivec3";
151 case Type::CHAR4:
152 case Type::SHORT4:
153 return "ivec4";
154 case Type::VEC3_101010I2:
155 return "vec3";
156 }
158 return "unknown";
159}
160
161static Type to_component_type(const Type &type)
162{
163 switch (type) {
164 case Type::FLOAT:
165 case Type::VEC2:
166 case Type::VEC3:
167 case Type::VEC4:
168 case Type::MAT3:
169 case Type::MAT4:
170 return Type::FLOAT;
171 case Type::UINT:
172 case Type::UVEC2:
173 case Type::UVEC3:
174 case Type::UVEC4:
175 return Type::UINT;
176 case Type::INT:
177 case Type::IVEC2:
178 case Type::IVEC3:
179 case Type::IVEC4:
180 case Type::BOOL:
181 return Type::INT;
182 /* Alias special types. */
183 case Type::UCHAR:
184 case Type::UCHAR2:
185 case Type::UCHAR3:
186 case Type::UCHAR4:
187 case Type::USHORT:
188 case Type::USHORT2:
189 case Type::USHORT3:
190 case Type::USHORT4:
191 return Type::UINT;
192 case Type::CHAR:
193 case Type::CHAR2:
194 case Type::CHAR3:
195 case Type::CHAR4:
196 case Type::SHORT:
197 case Type::SHORT2:
198 case Type::SHORT3:
199 case Type::SHORT4:
200 return Type::INT;
201 case Type::VEC3_101010I2:
202 return Type::FLOAT;
203 }
205 return Type::FLOAT;
206}
207
208static const char *to_string(const eGPUTextureFormat &type)
209{
210 switch (type) {
211 case GPU_RGBA8UI:
212 return "rgba8ui";
213 case GPU_RGBA8I:
214 return "rgba8i";
215 case GPU_RGBA8:
216 return "rgba8";
217 case GPU_RGBA32UI:
218 return "rgba32ui";
219 case GPU_RGBA32I:
220 return "rgba32i";
221 case GPU_RGBA32F:
222 return "rgba32f";
223 case GPU_RGBA16UI:
224 return "rgba16ui";
225 case GPU_RGBA16I:
226 return "rgba16i";
227 case GPU_RGBA16F:
228 return "rgba16f";
229 case GPU_RGBA16:
230 return "rgba16";
231 case GPU_RG8UI:
232 return "rg8ui";
233 case GPU_RG8I:
234 return "rg8i";
235 case GPU_RG8:
236 return "rg8";
237 case GPU_RG32UI:
238 return "rg32ui";
239 case GPU_RG32I:
240 return "rg32i";
241 case GPU_RG32F:
242 return "rg32f";
243 case GPU_RG16UI:
244 return "rg16ui";
245 case GPU_RG16I:
246 return "rg16i";
247 case GPU_RG16F:
248 return "rg16f";
249 case GPU_RG16:
250 return "rg16";
251 case GPU_R8UI:
252 return "r8ui";
253 case GPU_R8I:
254 return "r8i";
255 case GPU_R8:
256 return "r8";
257 case GPU_R32UI:
258 return "r32ui";
259 case GPU_R32I:
260 return "r32i";
261 case GPU_R32F:
262 return "r32f";
263 case GPU_R16UI:
264 return "r16ui";
265 case GPU_R16I:
266 return "r16i";
267 case GPU_R16F:
268 return "r16f";
269 case GPU_R16:
270 return "r16";
272 return "r11f_g11f_b10f";
273 case GPU_RGB10_A2:
274 return "rgb10_a2";
275 default:
276 return "unknown";
277 }
278}
279
280static const char *to_string(const PrimitiveIn &layout)
281{
282 switch (layout) {
283 case PrimitiveIn::POINTS:
284 return "points";
285 case PrimitiveIn::LINES:
286 return "lines";
287 case PrimitiveIn::LINES_ADJACENCY:
288 return "lines_adjacency";
289 case PrimitiveIn::TRIANGLES:
290 return "triangles";
291 case PrimitiveIn::TRIANGLES_ADJACENCY:
292 return "triangles_adjacency";
293 default:
294 return "unknown";
295 }
296}
297
298static const char *to_string(const PrimitiveOut &layout)
299{
300 switch (layout) {
301 case PrimitiveOut::POINTS:
302 return "points";
303 case PrimitiveOut::LINE_STRIP:
304 return "line_strip";
305 case PrimitiveOut::TRIANGLE_STRIP:
306 return "triangle_strip";
307 default:
308 return "unknown";
309 }
310}
311
312static const char *to_string(const DepthWrite &value)
313{
314 switch (value) {
315 case DepthWrite::ANY:
316 return "depth_any";
317 case DepthWrite::GREATER:
318 return "depth_greater";
319 case DepthWrite::LESS:
320 return "depth_less";
321 default:
322 return "depth_unchanged";
323 }
324}
325
326static void print_image_type(std::ostream &os,
327 const ImageType &type,
329{
330 switch (type) {
331 case ImageType::INT_BUFFER:
332 case ImageType::INT_1D:
333 case ImageType::INT_1D_ARRAY:
334 case ImageType::INT_2D:
335 case ImageType::INT_2D_ARRAY:
336 case ImageType::INT_3D:
337 case ImageType::INT_CUBE:
338 case ImageType::INT_CUBE_ARRAY:
339 case ImageType::INT_2D_ATOMIC:
340 case ImageType::INT_2D_ARRAY_ATOMIC:
341 case ImageType::INT_3D_ATOMIC:
342 os << "i";
343 break;
344 case ImageType::UINT_BUFFER:
345 case ImageType::UINT_1D:
346 case ImageType::UINT_1D_ARRAY:
347 case ImageType::UINT_2D:
348 case ImageType::UINT_2D_ARRAY:
349 case ImageType::UINT_3D:
350 case ImageType::UINT_CUBE:
351 case ImageType::UINT_CUBE_ARRAY:
352 case ImageType::UINT_2D_ATOMIC:
353 case ImageType::UINT_2D_ARRAY_ATOMIC:
354 case ImageType::UINT_3D_ATOMIC:
355 os << "u";
356 break;
357 default:
358 break;
359 }
360
361 if (bind_type == ShaderCreateInfo::Resource::BindType::IMAGE) {
362 os << "image";
363 }
364 else {
365 os << "sampler";
366 }
367
368 switch (type) {
369 case ImageType::FLOAT_BUFFER:
370 case ImageType::INT_BUFFER:
371 case ImageType::UINT_BUFFER:
372 os << "Buffer";
373 break;
374 case ImageType::FLOAT_1D:
375 case ImageType::FLOAT_1D_ARRAY:
376 case ImageType::INT_1D:
377 case ImageType::INT_1D_ARRAY:
378 case ImageType::UINT_1D:
379 case ImageType::UINT_1D_ARRAY:
380 os << "1D";
381 break;
382 case ImageType::FLOAT_2D:
383 case ImageType::FLOAT_2D_ARRAY:
384 case ImageType::INT_2D:
385 case ImageType::INT_2D_ARRAY:
386 case ImageType::INT_2D_ATOMIC:
387 case ImageType::INT_2D_ARRAY_ATOMIC:
388 case ImageType::UINT_2D:
389 case ImageType::UINT_2D_ARRAY:
390 case ImageType::UINT_2D_ATOMIC:
391 case ImageType::UINT_2D_ARRAY_ATOMIC:
392 case ImageType::SHADOW_2D:
393 case ImageType::SHADOW_2D_ARRAY:
394 case ImageType::DEPTH_2D:
395 case ImageType::DEPTH_2D_ARRAY:
396 os << "2D";
397 break;
398 case ImageType::FLOAT_3D:
399 case ImageType::INT_3D:
400 case ImageType::UINT_3D:
401 case ImageType::INT_3D_ATOMIC:
402 case ImageType::UINT_3D_ATOMIC:
403 os << "3D";
404 break;
405 case ImageType::FLOAT_CUBE:
406 case ImageType::FLOAT_CUBE_ARRAY:
407 case ImageType::INT_CUBE:
408 case ImageType::INT_CUBE_ARRAY:
409 case ImageType::UINT_CUBE:
410 case ImageType::UINT_CUBE_ARRAY:
411 case ImageType::SHADOW_CUBE:
412 case ImageType::SHADOW_CUBE_ARRAY:
413 case ImageType::DEPTH_CUBE:
414 case ImageType::DEPTH_CUBE_ARRAY:
415 os << "Cube";
416 break;
417 default:
418 break;
419 }
420
421 switch (type) {
422 case ImageType::FLOAT_1D_ARRAY:
423 case ImageType::FLOAT_2D_ARRAY:
424 case ImageType::FLOAT_CUBE_ARRAY:
425 case ImageType::INT_1D_ARRAY:
426 case ImageType::INT_2D_ARRAY:
427 case ImageType::INT_CUBE_ARRAY:
428 case ImageType::UINT_1D_ARRAY:
429 case ImageType::UINT_2D_ARRAY:
430 case ImageType::UINT_2D_ARRAY_ATOMIC:
431 case ImageType::UINT_CUBE_ARRAY:
432 case ImageType::SHADOW_2D_ARRAY:
433 case ImageType::SHADOW_CUBE_ARRAY:
434 case ImageType::DEPTH_2D_ARRAY:
435 case ImageType::DEPTH_CUBE_ARRAY:
436 os << "Array";
437 break;
438 default:
439 break;
440 }
441
442 switch (type) {
443 case ImageType::SHADOW_2D:
444 case ImageType::SHADOW_2D_ARRAY:
445 case ImageType::SHADOW_CUBE:
446 case ImageType::SHADOW_CUBE_ARRAY:
447 os << "Shadow";
448 break;
449 default:
450 break;
451 }
452 os << " ";
453}
454
455static std::ostream &print_qualifier(std::ostream &os, const Qualifier &qualifiers)
456{
457 if (bool(qualifiers & Qualifier::NO_RESTRICT) == false) {
458 os << "restrict ";
459 }
460 if (bool(qualifiers & Qualifier::READ) == false) {
461 os << "writeonly ";
462 }
463 if (bool(qualifiers & Qualifier::WRITE) == false) {
464 os << "readonly ";
465 }
466 return os;
467}
468
469static void print_resource(std::ostream &os,
471 bool auto_resource_location)
472{
473 if (auto_resource_location && res.bind_type == ShaderCreateInfo::Resource::BindType::SAMPLER) {
474 /* Skip explicit binding location for samplers when not needed, since drivers can usually
475 * handle more sampler declarations this way (as long as they're not actually used by the
476 * shader). See #105661. */
477 }
479 os << "layout(binding = " << res.slot;
480 if (res.bind_type == ShaderCreateInfo::Resource::BindType::IMAGE) {
481 os << ", " << to_string(res.image.format);
482 }
483 else if (res.bind_type == ShaderCreateInfo::Resource::BindType::UNIFORM_BUFFER) {
484 os << ", std140";
485 }
486 else if (res.bind_type == ShaderCreateInfo::Resource::BindType::STORAGE_BUFFER) {
487 os << ", std430";
488 }
489 os << ") ";
490 }
491 else if (res.bind_type == ShaderCreateInfo::Resource::BindType::UNIFORM_BUFFER) {
492 os << "layout(std140) ";
493 }
494
495 int64_t array_offset;
496 StringRef name_no_array;
497
498 switch (res.bind_type) {
499 case ShaderCreateInfo::Resource::BindType::SAMPLER:
500 os << "uniform ";
502 os << res.sampler.name << ";\n";
503 break;
504 case ShaderCreateInfo::Resource::BindType::IMAGE:
505 os << "uniform ";
507 print_image_type(os, res.image.type, res.bind_type);
508 os << res.image.name << ";\n";
509 break;
510 case ShaderCreateInfo::Resource::BindType::UNIFORM_BUFFER:
511 array_offset = res.uniformbuf.name.find_first_of("[");
512 name_no_array = (array_offset == -1) ? res.uniformbuf.name :
513 StringRef(res.uniformbuf.name.c_str(), array_offset);
514 os << "uniform " << name_no_array << " { " << res.uniformbuf.type_name << " _"
515 << res.uniformbuf.name << "; };\n";
516 break;
517 case ShaderCreateInfo::Resource::BindType::STORAGE_BUFFER:
518 array_offset = res.storagebuf.name.find_first_of("[");
519 name_no_array = (array_offset == -1) ? res.storagebuf.name :
520 StringRef(res.storagebuf.name.c_str(), array_offset);
521 print_qualifier(os, res.storagebuf.qualifiers);
522 os << "buffer ";
523 os << name_no_array << " { " << res.storagebuf.type_name << " _" << res.storagebuf.name
524 << "; };\n";
525 break;
526 }
527}
528
529static void print_resource_alias(std::ostream &os, const ShaderCreateInfo::Resource &res)
530{
531 int64_t array_offset;
532 StringRef name_no_array;
533
534 switch (res.bind_type) {
535 case ShaderCreateInfo::Resource::BindType::UNIFORM_BUFFER:
536 array_offset = res.uniformbuf.name.find_first_of("[");
537 name_no_array = (array_offset == -1) ? res.uniformbuf.name :
538 StringRef(res.uniformbuf.name.c_str(), array_offset);
539 os << "#define " << name_no_array << " (_" << name_no_array << ")\n";
540 break;
541 case ShaderCreateInfo::Resource::BindType::STORAGE_BUFFER:
542 array_offset = res.storagebuf.name.find_first_of("[");
543 name_no_array = (array_offset == -1) ? res.storagebuf.name :
544 StringRef(res.storagebuf.name.c_str(), array_offset);
545 os << "#define " << name_no_array << " (_" << name_no_array << ")\n";
546 break;
547 default:
548 break;
549 }
550}
551
552static void print_interface(std::ostream &os,
553 const StringRefNull &prefix,
554 const StageInterfaceInfo &iface,
555 const StringRefNull &suffix = "")
556{
557 /* TODO(@fclem): Move that to interface check. */
558 // if (iface.instance_name.is_empty()) {
559 // BLI_assert_msg(0, "Interfaces require an instance name for geometry shader.");
560 // std::cout << iface.name << ": Interfaces require an instance name for geometry shader.\n";
561 // continue;
562 // }
563 os << prefix << " " << iface.name << "{" << std::endl;
564 for (const StageInterfaceInfo::InOut &inout : iface.inouts) {
565 os << " " << to_string(inout.interp) << " " << to_string(inout.type) << " " << inout.name
566 << ";\n";
567 }
568 os << "}";
569 os << (iface.instance_name.is_empty() ? "" : "\n") << iface.instance_name << suffix << ";\n";
570}
571
572std::string GLShader::resources_declare(const ShaderCreateInfo &info) const
573{
574 std::stringstream ss;
575
576 /* NOTE: We define macros in GLSL to trigger compilation error if the resource names
577 * are reused for local variables. This is to match other backend behavior which needs accessors
578 * macros. */
579 ss << "\n/* Pass Resources. */\n";
580 for (const ShaderCreateInfo::Resource &res : info.pass_resources_) {
582 }
583 for (const ShaderCreateInfo::Resource &res : info.pass_resources_) {
584 print_resource_alias(ss, res);
585 }
586 ss << "\n/* Batch Resources. */\n";
587 for (const ShaderCreateInfo::Resource &res : info.batch_resources_) {
589 }
590 for (const ShaderCreateInfo::Resource &res : info.batch_resources_) {
591 print_resource_alias(ss, res);
592 }
593 ss << "\n/* Geometry Resources. */\n";
594 for (const ShaderCreateInfo::Resource &res : info.geometry_resources_) {
596 }
597 for (const ShaderCreateInfo::Resource &res : info.geometry_resources_) {
598 print_resource_alias(ss, res);
599 }
600 ss << "\n/* Push Constants. */\n";
601 for (const ShaderCreateInfo::PushConst &uniform : info.push_constants_) {
602 ss << "uniform " << to_string(uniform.type) << " " << uniform.name;
603 if (uniform.array_size > 0) {
604 ss << "[" << uniform.array_size << "]";
605 }
606 ss << ";\n";
607 }
608#if 0 /* #95278: This is not be enough to prevent some compilers think it is recursive. */
609 for (const ShaderCreateInfo::PushConst &uniform : info.push_constants_) {
610 /* #95278: Double macro to avoid some compilers think it is recursive. */
611 ss << "#define " << uniform.name << "_ " << uniform.name << "\n";
612 ss << "#define " << uniform.name << " (" << uniform.name << "_)\n";
613 }
614#endif
615 ss << "\n";
616 return ss.str();
617}
618
620{
621 std::stringstream ss;
622
623 ss << "/* Specialization Constants. */\n";
624 for (int constant_index : IndexRange(constants.types.size())) {
625 const StringRefNull name = specialization_constant_names_[constant_index];
626 gpu::shader::Type constant_type = constants.types[constant_index];
627 const SpecializationConstant::Value &value = constants.values[constant_index];
628
629 switch (constant_type) {
630 case Type::INT:
631 ss << "const int " << name << "=" << std::to_string(value.i) << ";\n";
632 break;
633 case Type::UINT:
634 ss << "const uint " << name << "=" << std::to_string(value.u) << "u;\n";
635 break;
636 case Type::BOOL:
637 ss << "const bool " << name << "=" << (value.u ? "true" : "false") << ";\n";
638 break;
639 case Type::FLOAT:
640 /* Use uint representation to allow exact same bit pattern even if NaN. */
641 ss << "const float " << name << "= uintBitsToFloat(" << std::to_string(value.u) << "u);\n";
642 break;
643 default:
645 break;
646 }
647 }
648 return ss.str();
649}
650
651static std::string main_function_wrapper(std::string &pre_main, std::string &post_main)
652{
653 std::stringstream ss;
654 /* Prototype for the original main. */
655 ss << "\n";
656 ss << "void main_function_();\n";
657 /* Wrapper to the main function in order to inject code processing on globals. */
658 ss << "void main() {\n";
659 ss << pre_main;
660 ss << " main_function_();\n";
661 ss << post_main;
662 ss << "}\n";
663 /* Rename the original main. */
664 ss << "#define main main_function_\n";
665 ss << "\n";
666 return ss.str();
667}
668
670{
671 std::stringstream ss;
672 std::string post_main;
673
674 ss << "\n/* Inputs. */\n";
675 for (const ShaderCreateInfo::VertIn &attr : info.vertex_inputs_) {
677 /* Fix issue with AMDGPU-PRO + workbench_prepass_mesh_vert.glsl being quantized. */
679 {
680 ss << "layout(location = " << attr.index << ") ";
681 }
682 ss << "in " << to_string(attr.type) << " " << attr.name << ";\n";
683 }
684 ss << "\n/* Interfaces. */\n";
685 for (const StageInterfaceInfo *iface : info.vertex_out_interfaces_) {
686 print_interface(ss, "out", *iface);
687 }
688 if (!GLContext::layered_rendering_support && bool(info.builtins_ & BuiltinBits::LAYER)) {
689 ss << "out int gpu_Layer;\n";
690 }
691 if (!GLContext::layered_rendering_support && bool(info.builtins_ & BuiltinBits::VIEWPORT_INDEX))
692 {
693 ss << "out int gpu_ViewportIndex;\n";
694 }
695 if (bool(info.builtins_ & BuiltinBits::BARYCENTRIC_COORD)) {
697 /* Disabled or unsupported. */
698 }
699 else if (epoxy_has_gl_extension("GL_AMD_shader_explicit_vertex_parameter")) {
700 /* Need this for stable barycentric. */
701 ss << "flat out vec4 gpu_pos_flat;\n";
702 ss << "out vec4 gpu_pos;\n";
703
704 post_main += " gpu_pos = gpu_pos_flat = gl_Position;\n";
705 }
706 }
707 ss << "\n";
708
709 if (post_main.empty() == false) {
710 std::string pre_main;
711 ss << main_function_wrapper(pre_main, post_main);
712 }
713 return ss.str();
714}
715
717{
718 std::stringstream ss;
719 std::string pre_main, post_main;
720
721 ss << "\n/* Interfaces. */\n";
722 const Span<StageInterfaceInfo *> in_interfaces = info.geometry_source_.is_empty() ?
725 for (const StageInterfaceInfo *iface : in_interfaces) {
726 print_interface(ss, "in", *iface);
727 }
728 if (!GLContext::layered_rendering_support && bool(info.builtins_ & BuiltinBits::LAYER)) {
729 ss << "#define gpu_Layer gl_Layer\n";
730 }
731 if (!GLContext::layered_rendering_support && bool(info.builtins_ & BuiltinBits::VIEWPORT_INDEX))
732 {
733 ss << "#define gpu_ViewportIndex gl_ViewportIndex\n";
734 }
735 if (bool(info.builtins_ & BuiltinBits::BARYCENTRIC_COORD)) {
737 ss << "flat in vec4 gpu_pos[3];\n";
738 ss << "smooth in vec3 gpu_BaryCoord;\n";
739 ss << "noperspective in vec3 gpu_BaryCoordNoPersp;\n";
740 }
741 else if (epoxy_has_gl_extension("GL_AMD_shader_explicit_vertex_parameter")) {
742 /* NOTE(fclem): This won't work with geometry shader. Hopefully, we don't need geometry
743 * shader workaround if this extension/feature is detected. */
744 ss << "\n/* Stable Barycentric Coordinates. */\n";
745 ss << "flat in vec4 gpu_pos_flat;\n";
746 ss << "__explicitInterpAMD in vec4 gpu_pos;\n";
747 /* Globals. */
748 ss << "vec3 gpu_BaryCoord;\n";
749 ss << "vec3 gpu_BaryCoordNoPersp;\n";
750 ss << "\n";
751 ss << "vec2 stable_bary_(vec2 in_bary) {\n";
752 ss << " vec3 bary = vec3(in_bary, 1.0 - in_bary.x - in_bary.y);\n";
753 ss << " if (interpolateAtVertexAMD(gpu_pos, 0) == gpu_pos_flat) { return bary.zxy; }\n";
754 ss << " if (interpolateAtVertexAMD(gpu_pos, 2) == gpu_pos_flat) { return bary.yzx; }\n";
755 ss << " return bary.xyz;\n";
756 ss << "}\n";
757 ss << "\n";
758
759 pre_main += " gpu_BaryCoord = stable_bary_(gl_BaryCoordSmoothAMD);\n";
760 pre_main += " gpu_BaryCoordNoPersp = stable_bary_(gl_BaryCoordNoPerspAMD);\n";
761 }
762 }
763 if (info.early_fragment_test_) {
764 ss << "layout(early_fragment_tests) in;\n";
765 }
766 ss << "layout(" << to_string(info.depth_write_) << ") out float gl_FragDepth;\n";
767
768 ss << "\n/* Sub-pass Inputs. */\n";
769 for (const ShaderCreateInfo::SubpassIn &input : info.subpass_inputs_) {
771 /* Declare as inout but do not write to it. */
772 ss << "layout(location = " << std::to_string(input.index) << ") inout "
773 << to_string(input.type) << " " << input.name << ";\n";
774 }
775 else {
776 std::string image_name = "gpu_subpass_img_";
777 image_name += std::to_string(input.index);
778
779 /* Declare global for input. */
780 ss << to_string(input.type) << " " << input.name << ";\n";
781
782 /* IMPORTANT: We assume that the frame-buffer will be layered or not based on the layer
783 * built-in flag. */
784 bool is_layered_fb = bool(info.builtins_ & BuiltinBits::LAYER);
785
786 /* Start with invalid value to detect failure cases. */
787 ImageType image_type = ImageType::FLOAT_BUFFER;
788 switch (to_component_type(input.type)) {
789 case Type::FLOAT:
790 image_type = is_layered_fb ? ImageType::FLOAT_2D_ARRAY : ImageType::FLOAT_2D;
791 break;
792 case Type::INT:
793 image_type = is_layered_fb ? ImageType::INT_2D_ARRAY : ImageType::INT_2D;
794 break;
795 case Type::UINT:
796 image_type = is_layered_fb ? ImageType::UINT_2D_ARRAY : ImageType::UINT_2D;
797 break;
798 default:
799 break;
800 }
801 /* Declare image. */
802 using Resource = ShaderCreateInfo::Resource;
803 /* NOTE(fclem): Using the attachment index as resource index might be problematic as it might
804 * collide with other resources. */
805 Resource res(Resource::BindType::SAMPLER, input.index);
806 res.sampler.type = image_type;
807 res.sampler.sampler = GPUSamplerState::default_sampler();
808 res.sampler.name = image_name;
809 print_resource(ss, res, false);
810
811 char swizzle[] = "xyzw";
812 swizzle[to_component_count(input.type)] = '\0';
813
814 std::string texel_co = (is_layered_fb) ? "ivec3(gl_FragCoord.xy, gpu_Layer)" :
815 "ivec2(gl_FragCoord.xy)";
816
817 std::stringstream ss_pre;
818 /* Populate the global before main using imageLoad. */
819 ss_pre << " " << input.name << " = texelFetch(" << image_name << ", " << texel_co << ", 0)."
820 << swizzle << ";\n";
821
822 pre_main += ss_pre.str();
823 }
824 }
825 ss << "\n/* Outputs. */\n";
826 for (const ShaderCreateInfo::FragOut &output : info.fragment_outputs_) {
827 ss << "layout(location = " << output.index;
828 switch (output.blend) {
829 case DualBlend::SRC_0:
830 ss << ", index = 0";
831 break;
832 case DualBlend::SRC_1:
833 ss << ", index = 1";
834 break;
835 default:
836 break;
837 }
838 ss << ") ";
839 ss << "out " << to_string(output.type) << " " << output.name << ";\n";
840 }
841 ss << "\n";
842
843 if (!pre_main.empty() || !post_main.empty()) {
844 ss << main_function_wrapper(pre_main, post_main);
845 }
846 return ss.str();
847}
848
850{
851 int max_verts = info.geometry_layout_.max_vertices;
852 int invocations = info.geometry_layout_.invocations;
853
854 std::stringstream ss;
855 ss << "\n/* Geometry Layout. */\n";
856 ss << "layout(" << to_string(info.geometry_layout_.primitive_in);
857 if (invocations != -1) {
858 ss << ", invocations = " << invocations;
859 }
860 ss << ") in;\n";
861
862 ss << "layout(" << to_string(info.geometry_layout_.primitive_out)
863 << ", max_vertices = " << max_verts << ") out;\n";
864 ss << "\n";
865 return ss.str();
866}
867
869 const StringRefNull &name)
870{
871 for (auto *iface : ifaces) {
872 if (iface->instance_name == name) {
873 return iface;
874 }
875 }
876 return nullptr;
877}
878
880{
881 std::stringstream ss;
882
883 ss << "\n/* Interfaces. */\n";
884 for (const StageInterfaceInfo *iface : info.vertex_out_interfaces_) {
885 bool has_matching_output_iface = find_interface_by_name(info.geometry_out_interfaces_,
886 iface->instance_name) != nullptr;
887 const char *suffix = (has_matching_output_iface) ? "_in[]" : "[]";
888 print_interface(ss, "in", *iface, suffix);
889 }
890 ss << "\n";
891 for (const StageInterfaceInfo *iface : info.geometry_out_interfaces_) {
892 bool has_matching_input_iface = find_interface_by_name(info.vertex_out_interfaces_,
893 iface->instance_name) != nullptr;
894 const char *suffix = (has_matching_input_iface) ? "_out" : "";
895 print_interface(ss, "out", *iface, suffix);
896 }
897 ss << "\n";
898 return ss.str();
899}
900
902{
903 std::stringstream ss;
904 ss << "\n/* Compute Layout. */\n";
905 ss << "layout(local_size_x = " << info.compute_layout_.local_size_x;
906 if (info.compute_layout_.local_size_y != -1) {
907 ss << ", local_size_y = " << info.compute_layout_.local_size_y;
908 }
909 if (info.compute_layout_.local_size_z != -1) {
910 ss << ", local_size_z = " << info.compute_layout_.local_size_z;
911 }
912 ss << ") in;\n";
913 ss << "\n";
914 return ss.str();
915}
918/* -------------------------------------------------------------------- */
923std::string GLShader::workaround_geometry_shader_source_create(
924 const shader::ShaderCreateInfo &info)
925{
926 std::stringstream ss;
927
928 const bool do_layer_workaround = !GLContext::layered_rendering_support &&
929 bool(info.builtins_ & BuiltinBits::LAYER);
930 const bool do_viewport_workaround = !GLContext::layered_rendering_support &&
931 bool(info.builtins_ & BuiltinBits::VIEWPORT_INDEX);
932 const bool do_barycentric_workaround = !GLContext::native_barycentric_support &&
933 bool(info.builtins_ & BuiltinBits::BARYCENTRIC_COORD);
934
935 shader::ShaderCreateInfo info_modified = info;
936 info_modified.geometry_out_interfaces_ = info_modified.vertex_out_interfaces_;
941 info_modified.geometry_layout(PrimitiveIn::TRIANGLES, PrimitiveOut::TRIANGLE_STRIP, 3);
942
943 ss << geometry_layout_declare(info_modified);
944 ss << geometry_interface_declare(info_modified);
945 if (do_layer_workaround) {
946 ss << "in int gpu_Layer[];\n";
947 }
948 if (do_viewport_workaround) {
949 ss << "in int gpu_ViewportIndex[];\n";
950 }
951 if (do_barycentric_workaround) {
952 ss << "flat out vec4 gpu_pos[3];\n";
953 ss << "smooth out vec3 gpu_BaryCoord;\n";
954 ss << "noperspective out vec3 gpu_BaryCoordNoPersp;\n";
955 }
956 ss << "\n";
957
958 ss << "void main()\n";
959 ss << "{\n";
960 if (do_layer_workaround) {
961 ss << " gl_Layer = gpu_Layer[0];\n";
962 }
963 if (do_viewport_workaround) {
964 ss << " gl_ViewportIndex = gpu_ViewportIndex[0];\n";
965 }
966 if (do_barycentric_workaround) {
967 ss << " gpu_pos[0] = gl_in[0].gl_Position;\n";
968 ss << " gpu_pos[1] = gl_in[1].gl_Position;\n";
969 ss << " gpu_pos[2] = gl_in[2].gl_Position;\n";
970 }
971 for (auto i : IndexRange(3)) {
972 for (const StageInterfaceInfo *iface : info_modified.vertex_out_interfaces_) {
973 for (auto &inout : iface->inouts) {
974 ss << " " << iface->instance_name << "_out." << inout.name;
975 ss << " = " << iface->instance_name << "_in[" << i << "]." << inout.name << ";\n";
976 }
977 }
978 if (do_barycentric_workaround) {
979 ss << " gpu_BaryCoordNoPersp = gpu_BaryCoord =";
980 ss << " vec3(" << int(i == 0) << ", " << int(i == 1) << ", " << int(i == 2) << ");\n";
981 }
982 ss << " gl_Position = gl_in[" << i << "].gl_Position;\n";
983 ss << " EmitVertex();\n";
984 }
985 ss << "}\n";
986 return ss.str();
987}
988
989bool GLShader::do_geometry_shader_injection(const shader::ShaderCreateInfo *info)
990{
991 BuiltinBits builtins = info->builtins_;
992 if (!GLContext::native_barycentric_support && bool(builtins & BuiltinBits::BARYCENTRIC_COORD)) {
993 return true;
994 }
995 if (!GLContext::layered_rendering_support && bool(builtins & BuiltinBits::LAYER)) {
996 return true;
997 }
998 if (!GLContext::layered_rendering_support && bool(builtins & BuiltinBits::VIEWPORT_INDEX)) {
999 return true;
1000 }
1001 return false;
1002}
1003
1006/* -------------------------------------------------------------------- */
1010static const char *glsl_patch_default_get()
1011{
1013 static std::string patch;
1014 if (!patch.empty()) {
1015 return patch.c_str();
1016 }
1017
1018 std::stringstream ss;
1019 /* Version need to go first. */
1020 if (epoxy_gl_version() >= 43) {
1021 ss << "#version 430\n";
1022 }
1023 else {
1024 ss << "#version 330\n";
1025 }
1026
1027 /* Enable extensions for features that are not part of our base GLSL version
1028 * don't use an extension for something already available! */
1030 ss << "#extension GL_ARB_shader_draw_parameters : enable\n";
1031 ss << "#define GPU_ARB_shader_draw_parameters\n";
1032 ss << "#define gpu_BaseInstance gl_BaseInstanceARB\n";
1033 }
1035 ss << "#extension GL_ARB_shader_viewport_layer_array: enable\n";
1036 ss << "#define gpu_Layer gl_Layer\n";
1037 ss << "#define gpu_ViewportIndex gl_ViewportIndex\n";
1038 }
1040 ss << "#extension GL_AMD_shader_explicit_vertex_parameter: enable\n";
1041 }
1043 ss << "#extension GL_EXT_shader_framebuffer_fetch: enable\n";
1044 }
1046 ss << "#extension GL_ARB_shader_stencil_export: enable\n";
1047 ss << "#define GPU_ARB_shader_stencil_export\n";
1048 }
1049
1050 /* Fallbacks. */
1052 ss << "uniform int gpu_BaseInstance;\n";
1053 }
1054
1055 /* Vulkan GLSL compatibility. */
1056 ss << "#define gpu_InstanceIndex (gl_InstanceID + gpu_BaseInstance)\n";
1057 ss << "#define gpu_EmitVertex EmitVertex\n";
1058
1059 /* Array compatibility. */
1060 ss << "#define gpu_Array(_type) _type[]\n";
1061
1062 /* Derivative sign can change depending on implementation. */
1063 ss << "#define DFDX_SIGN " << std::setprecision(2) << GLContext::derivative_signs[0] << "\n";
1064 ss << "#define DFDY_SIGN " << std::setprecision(2) << GLContext::derivative_signs[1] << "\n";
1065
1066 /* GLSL Backend Lib. */
1068
1069 patch = ss.str();
1070 return patch.c_str();
1071}
1072
1073static const char *glsl_patch_compute_get()
1074{
1076 static std::string patch;
1077 if (!patch.empty()) {
1078 return patch.c_str();
1079 }
1080
1081 std::stringstream ss;
1082 /* Version need to go first. */
1083 ss << "#version 430\n";
1084 ss << "#extension GL_ARB_compute_shader :enable\n";
1085
1086 /* Array compatibility. */
1087 ss << "#define gpu_Array(_type) _type[]\n";
1088
1090
1091 patch = ss.str();
1092 return patch.c_str();
1093}
1094
1095const char *GLShader::glsl_patch_get(GLenum gl_stage)
1096{
1097 if (gl_stage == GL_COMPUTE_SHADER) {
1098 return glsl_patch_compute_get();
1099 }
1100 return glsl_patch_default_get();
1101}
1102
1103GLuint GLShader::create_shader_stage(GLenum gl_stage,
1105 GLSources &gl_sources)
1106{
1107 /* Patch the shader sources to include specialization constants. */
1108 std::string constants_source;
1109 Vector<const char *> recreated_sources;
1110 const bool has_specialization_constants = !constants.types.is_empty();
1111 if (has_specialization_constants) {
1112 constants_source = constants_declare();
1113 if (sources.is_empty()) {
1114 recreated_sources = gl_sources.sources_get();
1115 sources = recreated_sources;
1116 }
1117 }
1118
1119 /* Patch the shader code using the first source slot. */
1120 sources[SOURCES_INDEX_VERSION] = glsl_patch_get(gl_stage);
1121 sources[SOURCES_INDEX_SPECIALIZATION_CONSTANTS] = constants_source.c_str();
1122
1123 if (async_compilation_) {
1124 gl_sources[SOURCES_INDEX_VERSION].source = std::string(sources[SOURCES_INDEX_VERSION]);
1125 gl_sources[SOURCES_INDEX_SPECIALIZATION_CONSTANTS].source = std::string(
1127 }
1128
1130 /* Store the generated source for printing in case the link fails. */
1131 StringRefNull source_type;
1132 switch (gl_stage) {
1133 case GL_VERTEX_SHADER:
1134 source_type = "VertShader";
1135 break;
1136 case GL_GEOMETRY_SHADER:
1137 source_type = "GeomShader";
1138 break;
1139 case GL_FRAGMENT_SHADER:
1140 source_type = "FragShader";
1141 break;
1142 case GL_COMPUTE_SHADER:
1143 source_type = "ComputeShader";
1144 break;
1145 }
1146
1147 debug_source += "\n\n----------" + source_type + "----------\n\n";
1148 for (const char *source : sources) {
1149 debug_source.append(source);
1150 }
1151 }
1152
1153 if (async_compilation_) {
1154 /* Only build the sources. */
1155 return 0;
1156 }
1157
1158 GLuint shader = glCreateShader(gl_stage);
1159 if (shader == 0) {
1160 fprintf(stderr, "GLShader: Error: Could not create shader object.\n");
1161 return 0;
1162 }
1163
1164 glShaderSource(shader, sources.size(), sources.data(), nullptr);
1165 glCompileShader(shader);
1166
1167 GLint status;
1168 glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
1169 if (!status || (G.debug & G_DEBUG_GPU)) {
1170 char log[5000] = "";
1171 glGetShaderInfoLog(shader, sizeof(log), nullptr, log);
1172 if (log[0] != '\0') {
1173 GLLogParser parser;
1174 switch (gl_stage) {
1175 case GL_VERTEX_SHADER:
1176 this->print_log(sources, log, "VertShader", !status, &parser);
1177 break;
1178 case GL_GEOMETRY_SHADER:
1179 this->print_log(sources, log, "GeomShader", !status, &parser);
1180 break;
1181 case GL_FRAGMENT_SHADER:
1182 this->print_log(sources, log, "FragShader", !status, &parser);
1183 break;
1184 case GL_COMPUTE_SHADER:
1185 this->print_log(sources, log, "ComputeShader", !status, &parser);
1186 break;
1187 }
1188 }
1189 }
1190 if (!status) {
1191 glDeleteShader(shader);
1192 compilation_failed_ = true;
1193 return 0;
1194 }
1195
1196 debug::object_label(gl_stage, shader, name);
1197 return shader;
1198}
1199
1200void GLShader::update_program_and_sources(GLSources &stage_sources,
1202{
1203 const bool store_sources = !constants.types.is_empty() || async_compilation_;
1204 if (store_sources && stage_sources.is_empty()) {
1205 stage_sources = sources;
1206 }
1207
1208 init_program();
1209}
1210
1212{
1213 update_program_and_sources(vertex_sources_, sources);
1214 program_active_->vert_shader = this->create_shader_stage(
1215 GL_VERTEX_SHADER, sources, vertex_sources_);
1216}
1217
1219{
1220 update_program_and_sources(geometry_sources_, sources);
1221 program_active_->geom_shader = this->create_shader_stage(
1222 GL_GEOMETRY_SHADER, sources, geometry_sources_);
1223}
1224
1226{
1227 update_program_and_sources(fragment_sources_, sources);
1228 program_active_->frag_shader = this->create_shader_stage(
1229 GL_FRAGMENT_SHADER, sources, fragment_sources_);
1230}
1231
1233{
1234 update_program_and_sources(compute_sources_, sources);
1235 program_active_->compute_shader = this->create_shader_stage(
1236 GL_COMPUTE_SHADER, sources, compute_sources_);
1237}
1238
1240{
1241 if (compilation_failed_) {
1242 return false;
1243 }
1244
1245 if (info && do_geometry_shader_injection(info)) {
1246 std::string source = workaround_geometry_shader_source_create(*info);
1247 Vector<const char *> sources;
1248 sources.append("version");
1249 sources.append("/* Specialization Constants. */\n");
1250 sources.append(source.c_str());
1252 }
1253
1254 if (async_compilation_) {
1255 return true;
1256 }
1257
1258 program_link();
1259 return post_finalize(info);
1260}
1261
1263{
1264 if (!check_link_status()) {
1265 return false;
1266 }
1267
1268 /* Reset for specialization constants variations. */
1269 async_compilation_ = false;
1270
1271 GLuint program_id = program_get();
1272 if (info != nullptr && info->legacy_resource_location_ == false) {
1273 interface = new GLShaderInterface(program_id, *info);
1274 }
1275 else {
1276 interface = new GLShaderInterface(program_id);
1277 }
1278
1279 return true;
1280}
1281
1284/* -------------------------------------------------------------------- */
1289{
1290 GLuint program_id = program_get();
1291 glUseProgram(program_id);
1292}
1293
1295{
1296#ifndef NDEBUG
1297 glUseProgram(0);
1298#endif
1299}
1300
1303/* -------------------------------------------------------------------- */
1310 const eGPUShaderTFBType geom_type)
1311{
1312 glTransformFeedbackVaryings(
1313 program_get(), name_list.size(), name_list.data(), GL_INTERLEAVED_ATTRIBS);
1314 transform_feedback_type_ = geom_type;
1315}
1316
1318{
1319 if (transform_feedback_type_ == GPU_SHADER_TFB_NONE) {
1320 return false;
1321 }
1322
1323 GLVertBuf *buf = static_cast<GLVertBuf *>(buf_);
1324
1325 if (buf->vbo_id_ == 0) {
1326 buf->bind();
1327 }
1328
1329 BLI_assert(buf->vbo_id_ != 0);
1330
1331 glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf->vbo_id_);
1332
1333 switch (transform_feedback_type_) {
1335 glBeginTransformFeedback(GL_POINTS);
1336 break;
1338 glBeginTransformFeedback(GL_LINES);
1339 break;
1341 glBeginTransformFeedback(GL_TRIANGLES);
1342 break;
1343 default:
1344 return false;
1345 }
1346 return true;
1347}
1348
1350{
1351 glEndTransformFeedback();
1352}
1353
1356/* -------------------------------------------------------------------- */
1360void GLShader::uniform_float(int location, int comp_len, int array_size, const float *data)
1361{
1362 switch (comp_len) {
1363 case 1:
1364 glUniform1fv(location, array_size, data);
1365 break;
1366 case 2:
1367 glUniform2fv(location, array_size, data);
1368 break;
1369 case 3:
1370 glUniform3fv(location, array_size, data);
1371 break;
1372 case 4:
1373 glUniform4fv(location, array_size, data);
1374 break;
1375 case 9:
1376 glUniformMatrix3fv(location, array_size, 0, data);
1377 break;
1378 case 16:
1379 glUniformMatrix4fv(location, array_size, 0, data);
1380 break;
1381 default:
1382 BLI_assert(0);
1383 break;
1384 }
1385}
1386
1387void GLShader::uniform_int(int location, int comp_len, int array_size, const int *data)
1388{
1389 switch (comp_len) {
1390 case 1:
1391 glUniform1iv(location, array_size, data);
1392 break;
1393 case 2:
1394 glUniform2iv(location, array_size, data);
1395 break;
1396 case 3:
1397 glUniform3iv(location, array_size, data);
1398 break;
1399 case 4:
1400 glUniform4iv(location, array_size, data);
1401 break;
1402 default:
1403 BLI_assert(0);
1404 break;
1405 }
1406}
1407
1410/* -------------------------------------------------------------------- */
1415{
1416 BLI_assert(program_active_);
1417 return program_active_->program_id;
1418}
1419
1422/* -------------------------------------------------------------------- */
1425GLSource::GLSource(const char *other)
1426{
1428 source = "";
1429 source_ref = other;
1430 }
1431 else {
1432 source = other;
1433 source_ref = nullptr;
1434 }
1435}
1436
1438{
1439 clear();
1440 reserve(other.size());
1441
1442 for (const char *other_source : other) {
1443 /* Don't store empty string as compilers can optimize these away and result in pointing to a
1444 * string that isn't c-str compliant anymore. */
1445 if (other_source[0] == '\0') {
1446 continue;
1447 }
1448 append(GLSource(other_source));
1449 }
1450
1451 return *this;
1452}
1453
1455{
1457 result.reserve(size());
1458
1459 for (const GLSource &source : *this) {
1460 if (source.source_ref) {
1461 result.append(source.source_ref);
1462 }
1463 else {
1464 result.append(source.source.c_str());
1465 }
1466 }
1467 return result;
1468}
1469
1470std::string GLSources::to_string() const
1471{
1472 std::string result;
1473 for (const GLSource &source : *this) {
1474 if (source.source_ref) {
1475 result.append(source.source_ref);
1476 }
1477 else {
1478 result.append(source.source);
1479 }
1480 }
1481 return result;
1482}
1483
1485{
1486 size_t result = 0;
1487 result += comp.empty() ? 0 : comp.size() + sizeof('\0');
1488 result += vert.empty() ? 0 : vert.size() + sizeof('\0');
1489 result += geom.empty() ? 0 : geom.size() + sizeof('\0');
1490 result += frag.empty() ? 0 : frag.size() + sizeof('\0');
1491 return result;
1492}
1493
1496/* -------------------------------------------------------------------- */
1500GLShader::GLProgram::~GLProgram()
1501{
1502 /* Invalid handles are silently ignored. */
1503 glDeleteShader(vert_shader);
1504 glDeleteShader(geom_shader);
1505 glDeleteShader(frag_shader);
1506 glDeleteShader(compute_shader);
1507 glDeleteProgram(program_id);
1508}
1509
1510void GLShader::program_link()
1511{
1512 BLI_assert(program_active_ != nullptr);
1513 if (program_active_->program_id == 0) {
1514 program_active_->program_id = glCreateProgram();
1515 debug::object_label(GL_PROGRAM, program_active_->program_id, name);
1516 }
1517
1518 if (async_compilation_) {
1519 return;
1520 }
1521
1522 GLuint program_id = program_active_->program_id;
1523
1524 if (program_active_->vert_shader) {
1525 glAttachShader(program_id, program_active_->vert_shader);
1526 }
1527 if (program_active_->geom_shader) {
1528 glAttachShader(program_id, program_active_->geom_shader);
1529 }
1530 if (program_active_->frag_shader) {
1531 glAttachShader(program_id, program_active_->frag_shader);
1532 }
1533 if (program_active_->compute_shader) {
1534 glAttachShader(program_id, program_active_->compute_shader);
1535 }
1536 glLinkProgram(program_id);
1537}
1538
1539bool GLShader::check_link_status()
1540{
1541 GLuint program_id = program_active_->program_id;
1542 GLint status;
1543 glGetProgramiv(program_id, GL_LINK_STATUS, &status);
1544 if (!status) {
1545 char log[5000];
1546 glGetProgramInfoLog(program_id, sizeof(log), nullptr, log);
1547 Span<const char *> sources = {debug_source.c_str()};
1548 GLLogParser parser;
1549 print_log(sources, log, "Linking", true, &parser);
1550 }
1551
1552 return bool(status);
1553}
1554
1555void GLShader::init_program()
1556{
1557 if (program_active_) {
1558 return;
1559 }
1560
1561 program_active_ = &program_cache_.lookup_or_add_default(constants.values);
1562 if (!program_active_->program_id) {
1563 program_active_->program_id = glCreateProgram();
1564 debug::object_label(GL_PROGRAM, program_active_->program_id, name);
1565 }
1566}
1567
1568GLuint GLShader::program_get()
1569{
1570 if (constants.types.is_empty()) {
1571 /* Early exit for shaders that doesn't use specialization constants. The active shader should
1572 * already be setup. */
1573 BLI_assert(program_active_ && program_active_->program_id);
1574 return program_active_->program_id;
1575 }
1576
1577 if (!constants.is_dirty) {
1578 /* Early exit when constants didn't change since the last call. */
1579 BLI_assert(program_active_ && program_active_->program_id);
1580 return program_active_->program_id;
1581 }
1582
1583 program_active_ = &program_cache_.lookup_or_add_default(constants.values);
1584 if (!program_active_->program_id) {
1585 MutableSpan<const char *> no_sources;
1586 if (!vertex_sources_.is_empty()) {
1587 program_active_->vert_shader = create_shader_stage(
1588 GL_VERTEX_SHADER, no_sources, vertex_sources_);
1589 }
1590 if (!geometry_sources_.is_empty()) {
1591 program_active_->geom_shader = create_shader_stage(
1592 GL_GEOMETRY_SHADER, no_sources, geometry_sources_);
1593 }
1594 if (!fragment_sources_.is_empty()) {
1595 program_active_->frag_shader = create_shader_stage(
1596 GL_FRAGMENT_SHADER, no_sources, fragment_sources_);
1597 }
1598 if (!compute_sources_.is_empty()) {
1599 program_active_->compute_shader = create_shader_stage(
1600 GL_COMPUTE_SHADER, no_sources, compute_sources_);
1601 }
1602
1603 program_link();
1604 }
1605
1606 constants.is_dirty = false;
1607 return program_active_->program_id;
1608}
1609
1611{
1613 result.comp = compute_sources_.to_string();
1614 result.vert = vertex_sources_.to_string();
1615 result.geom = geometry_sources_.to_string();
1616 result.frag = fragment_sources_.to_string();
1617 return result;
1618}
1619
1622#if BLI_SUBPROCESS_SUPPORT
1623
1624/* -------------------------------------------------------------------- */
1628GLCompilerWorker::GLCompilerWorker()
1629{
1630 static size_t pipe_id = 0;
1631 pipe_id++;
1632
1633 std::string name = "BLENDER_SHADER_COMPILER_" + std::to_string(getpid()) + "_" +
1634 std::to_string(pipe_id);
1635
1636 shared_mem_ = std::make_unique<SharedMemory>(
1637 name, compilation_subprocess_shared_memory_size, true);
1638 start_semaphore_ = std::make_unique<SharedSemaphore>(name + "_START", false);
1639 end_semaphore_ = std::make_unique<SharedSemaphore>(name + "_END", false);
1640 close_semaphore_ = std::make_unique<SharedSemaphore>(name + "_CLOSE", false);
1641
1642 subprocess_.create({"--compilation-subprocess", name.c_str()});
1643}
1644
1645GLCompilerWorker::~GLCompilerWorker()
1646{
1647 close_semaphore_->increment();
1648 /* Flag start so the subprocess can reach the close semaphore. */
1649 start_semaphore_->increment();
1650}
1651
1652void GLCompilerWorker::compile(const GLSourcesBaked &sources)
1653{
1654 BLI_assert(state_ == AVAILABLE);
1655
1656 ShaderSourceHeader *shared_src = reinterpret_cast<ShaderSourceHeader *>(shared_mem_->get_data());
1657 char *next_src = shared_src->sources;
1658
1659 auto add_src = [&](const std::string &src) {
1660 if (!src.empty()) {
1661 const size_t src_size = src.size() + 1;
1662 memcpy(next_src, src.c_str(), src_size);
1663 next_src += src_size;
1664 }
1665 };
1666
1667 add_src(sources.comp);
1668 add_src(sources.vert);
1669 add_src(sources.geom);
1670 add_src(sources.frag);
1671
1672 BLI_assert(size_t(next_src) <= size_t(shared_src) + compilation_subprocess_shared_memory_size);
1673
1674 if (!sources.comp.empty()) {
1675 BLI_assert(sources.vert.empty() && sources.geom.empty() && sources.frag.empty());
1676 shared_src->type = ShaderSourceHeader::Type::COMPUTE;
1677 }
1678 else {
1679 BLI_assert(sources.comp.empty() && !sources.vert.empty() && !sources.frag.empty());
1680 shared_src->type = sources.geom.empty() ?
1681 ShaderSourceHeader::Type::GRAPHICS :
1682 ShaderSourceHeader::Type::GRAPHICS_WITH_GEOMETRY_STAGE;
1683 }
1684
1685 start_semaphore_->increment();
1686
1687 state_ = COMPILATION_REQUESTED;
1688 compilation_start = BLI_time_now_seconds();
1689}
1690
1691bool GLCompilerWorker::is_ready()
1692{
1693 BLI_assert(ELEM(state_, COMPILATION_REQUESTED, COMPILATION_READY));
1694 if (state_ == COMPILATION_READY) {
1695 return true;
1696 }
1697
1698 if (end_semaphore_->try_decrement()) {
1699 state_ = COMPILATION_READY;
1700 }
1701
1702 return state_ == COMPILATION_READY;
1703}
1704
1705bool GLCompilerWorker::is_lost()
1706{
1707 /* Use a timeout for hanged processes. */
1708 float max_timeout_seconds = 30.0f;
1709 return !subprocess_.is_running() ||
1710 (BLI_time_now_seconds() - compilation_start) > max_timeout_seconds;
1711}
1712
1713bool GLCompilerWorker::load_program_binary(GLint program)
1714{
1715 BLI_assert(ELEM(state_, COMPILATION_REQUESTED, COMPILATION_READY));
1716 if (state_ == COMPILATION_REQUESTED) {
1717 end_semaphore_->decrement();
1718 state_ = COMPILATION_READY;
1719 }
1720
1721 ShaderBinaryHeader *binary = (ShaderBinaryHeader *)shared_mem_->get_data();
1722
1723 state_ = COMPILATION_FINISHED;
1724
1725 if (binary->size > 0) {
1726 glProgramBinary(program, binary->format, binary->data, binary->size);
1727 return true;
1728 }
1729
1730 return false;
1731}
1732
1733void GLCompilerWorker::release()
1734{
1735 state_ = AVAILABLE;
1736}
1737
1740/* -------------------------------------------------------------------- */
1744GLShaderCompiler::~GLShaderCompiler()
1745{
1746 BLI_assert(batches.is_empty());
1747
1748 for (GLCompilerWorker *worker : workers_) {
1749 delete worker;
1750 }
1751}
1752
1753GLCompilerWorker *GLShaderCompiler::get_compiler_worker(const GLSourcesBaked &sources)
1754{
1755 GLCompilerWorker *result = nullptr;
1756 for (GLCompilerWorker *compiler : workers_) {
1757 if (compiler->state_ == GLCompilerWorker::AVAILABLE) {
1758 result = compiler;
1759 break;
1760 }
1761 }
1762 if (!result && workers_.size() < GCaps.max_parallel_compilations) {
1763 result = new GLCompilerWorker();
1764 workers_.append(result);
1765 }
1766 if (result) {
1767 result->compile(sources);
1768 }
1769 return result;
1770}
1771
1772bool GLShaderCompiler::worker_is_lost(GLCompilerWorker *&worker)
1773{
1774 if (worker->is_lost()) {
1775 std::cerr << "ERROR: Compilation subprocess lost\n";
1776 workers_.remove_first_occurrence_and_reorder(worker);
1777 delete worker;
1778 worker = nullptr;
1779 }
1780
1781 return worker == nullptr;
1782}
1783
1785{
1787
1788 std::scoped_lock lock(mutex_);
1789 BatchHandle handle = next_batch_handle++;
1790 batches.add(handle, {});
1791 Batch &batch = batches.lookup(handle);
1792 batch.items.reserve(infos.size());
1793 batch.is_ready = false;
1794
1795 for (const shader::ShaderCreateInfo *info : infos) {
1796 const_cast<ShaderCreateInfo *>(info)->finalize();
1797 batch.items.append({});
1798 CompilationWork &item = batch.items.last();
1799 item.info = info;
1800 item.shader = static_cast<GLShader *>(compile(*info, true));
1801 item.sources = item.shader->get_sources();
1802
1803 size_t required_size = item.sources.size();
1804 item.do_async_compilation = required_size <= sizeof(ShaderSourceHeader::sources);
1805 if (item.do_async_compilation) {
1806 item.worker = get_compiler_worker(item.sources);
1807 }
1808 else {
1809 delete item.shader;
1810 item.sources = {};
1811 }
1812 }
1813 return handle;
1814}
1815
1817{
1818 std::scoped_lock lock(mutex_);
1819
1820 BLI_assert(batches.contains(handle));
1821 Batch &batch = batches.lookup(handle);
1822 if (batch.is_ready) {
1823 return true;
1824 }
1825
1826 batch.is_ready = true;
1827 for (CompilationWork &item : batch.items) {
1828 if (item.is_ready) {
1829 continue;
1830 }
1831
1832 if (!item.do_async_compilation) {
1833 /* Compile it locally. */
1834 item.shader = static_cast<GLShader *>(compile(*item.info, false));
1835 item.is_ready = true;
1836 continue;
1837 }
1838
1839 if (!item.worker) {
1840 /* Try to acquire an available worker. */
1841 item.worker = get_compiler_worker(item.sources);
1842 }
1843 else if (item.worker->is_ready()) {
1844 /* Retrieve the binary compiled by the worker. */
1845 if (!item.worker->load_program_binary(item.shader->program_active_->program_id) ||
1846 !item.shader->post_finalize(item.info))
1847 {
1848 /* Compilation failed, try to compile it locally. */
1849 delete item.shader;
1850 item.shader = nullptr;
1851 item.do_async_compilation = false;
1852 }
1853 else {
1854 item.is_ready = true;
1855 }
1856 item.worker->release();
1857 item.worker = nullptr;
1858 }
1859 else if (worker_is_lost(item.worker)) {
1860 /* We lost the worker, try to compile it locally. */
1861 delete item.shader;
1862 item.shader = nullptr;
1863 item.do_async_compilation = false;
1864 }
1865
1866 if (!item.is_ready) {
1867 batch.is_ready = false;
1868 }
1869 }
1870
1871 return batch.is_ready;
1872}
1873
1875{
1876 while (!batch_is_ready(handle)) {
1878 }
1879 std::scoped_lock lock(mutex_);
1880
1881 BLI_assert(batches.contains(handle));
1882 Batch batch = batches.pop(handle);
1884 for (CompilationWork &item : batch.items) {
1885 result.append(item.shader);
1886 }
1887 handle = 0;
1888 return result;
1889}
1890
1892 Span<ShaderSpecialization> specializations)
1893{
1895
1896 std::scoped_lock lock(mutex_);
1897
1898 SpecializationBatchHandle handle = next_batch_handle++;
1899
1900 specialization_queue.append({handle, specializations});
1901
1902 return handle;
1903}
1904
1905GLShader::GLProgram *GLShaderCompiler::SpecializationWork::program_get()
1906{
1907 for (const SpecializationConstant &constant : constants) {
1908 const ShaderInput *input = shader->interface->constant_get(constant.name.c_str());
1909 BLI_assert_msg(input != nullptr, "The specialization constant doesn't exists");
1910 shader->constants.values[input->location].u = constant.value.u;
1911 }
1912 shader->constants.is_dirty = true;
1913 if (shader->program_cache_.contains(shader->constants.values)) {
1914 return &shader->program_cache_.lookup(shader->constants.values);
1915 }
1916 return nullptr;
1917}
1918
1919void GLShaderCompiler::prepare_next_specialization_batch()
1920{
1921 BLI_assert(current_specialization_batch.is_ready && !specialization_queue.is_empty());
1922
1923 SpecializationRequest &next = specialization_queue.first();
1924 SpecializationBatch &batch = current_specialization_batch;
1925 batch.handle = next.handle;
1926 batch.is_ready = false;
1927 Vector<SpecializationWork> &items = batch.items;
1928 items.clear();
1929 items.reserve(next.specializations.size());
1930
1931 for (auto &specialization : next.specializations) {
1932 GLShader *sh = static_cast<GLShader *>(unwrap(specialization.shader));
1933 items.append({});
1934 SpecializationWork &item = items.last();
1935 item.shader = sh;
1936 item.constants = specialization.constants;
1937
1938 if (item.program_get()) {
1939 /* Already compiled. */
1940 items.pop_last();
1941 continue;
1942 }
1943
1945 sh->async_compilation_ = true;
1946 sh->program_get();
1947 sh->async_compilation_ = false;
1948
1949 item.sources = sh->get_sources();
1950
1951 size_t required_size = item.sources.size();
1952 item.do_async_compilation = required_size <= sizeof(ShaderSourceHeader::sources);
1953 }
1954
1955 specialization_queue.remove(0);
1956}
1957
1959{
1960 std::scoped_lock lock(mutex_);
1961
1962 SpecializationBatch &batch = current_specialization_batch;
1963
1964 if (handle < batch.handle || (handle == batch.handle && batch.is_ready)) {
1965 handle = 0;
1966 return true;
1967 }
1968
1969 if (batch.is_ready) {
1970 prepare_next_specialization_batch();
1971 }
1972
1973 bool is_ready = true;
1974 for (SpecializationWork &item : batch.items) {
1975 if (item.is_ready) {
1976 continue;
1977 }
1978
1979 if (!item.do_async_compilation) {
1980 GLShader::GLProgram *program = item.program_get();
1981 glDeleteProgram(program->program_id);
1982 program->program_id = 0;
1983 item.shader->constants.is_dirty = true;
1984 item.is_ready = true;
1985 continue;
1986 }
1987
1988 if (item.worker == nullptr) {
1989 /* Try to acquire an available worker. */
1990 item.worker = get_compiler_worker(item.sources);
1991 }
1992 else if (item.worker->is_ready()) {
1993 /* Retrieve the binary compiled by the worker. */
1994 if (item.worker->load_program_binary(item.program_get()->program_id)) {
1995 item.is_ready = true;
1996 }
1997 else {
1998 /* Compilation failed, local compilation will be tried later on shader bind. */
1999 item.do_async_compilation = false;
2000 }
2001 item.worker->release();
2002 item.worker = nullptr;
2003 }
2004 else if (worker_is_lost(item.worker)) {
2005 /* We lost the worker, local compilation will be tried later on shader bind. */
2006 item.do_async_compilation = false;
2007 }
2008
2009 if (!item.is_ready) {
2010 is_ready = false;
2011 }
2012 }
2013
2014 if (is_ready) {
2015 batch.is_ready = true;
2016 handle = 0;
2017 }
2018
2019 return is_ready;
2020}
2021
2024#endif
@ G_DEBUG_GPU
#define BLI_assert_unreachable()
Definition BLI_assert.h:97
#define BLI_assert(a)
Definition BLI_assert.h:50
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:57
Platform independent time functions.
void BLI_time_sleep_ms(int ms)
Definition time.c:85
double BLI_time_now_seconds(void)
Definition time.c:65
#define ELEM(...)
bool GPU_use_parallel_compilation()
bool GPU_stencil_export_support()
@ GPU_DRIVER_OFFICIAL
@ GPU_OS_ANY
@ GPU_DEVICE_ATI
bool GPU_type_matches(eGPUDeviceType device, eGPUOSType os, eGPUDriverType driver)
int64_t BatchHandle
Definition GPU_shader.hh:68
eGPUShaderTFBType
@ GPU_SHADER_TFB_TRIANGLES
@ GPU_SHADER_TFB_NONE
@ GPU_SHADER_TFB_LINES
@ GPU_SHADER_TFB_POINTS
int64_t SpecializationBatchHandle
eGPUTextureFormat
@ GPU_R16UI
@ GPU_R16I
@ GPU_RGB10_A2
@ GPU_R32I
@ GPU_RG8UI
@ GPU_RG8I
@ GPU_RG16I
@ GPU_RG32UI
@ GPU_RG8
@ GPU_RG32I
@ GPU_RGBA32UI
@ GPU_R8I
@ GPU_R16
@ GPU_RG16UI
@ GPU_RGBA8I
@ GPU_RGBA8UI
@ GPU_RGBA16UI
@ GPU_RGBA16I
@ GPU_R8UI
@ GPU_RGBA16
@ GPU_RG32F
@ GPU_R8
@ GPU_RGBA32I
volatile int lock
constexpr int64_t size() const
Definition BLI_span.hh:494
constexpr bool is_empty() const
Definition BLI_span.hh:510
constexpr T * data() const
Definition BLI_span.hh:540
constexpr const T * data() const
Definition BLI_span.hh:216
constexpr int64_t size() const
Definition BLI_span.hh:253
constexpr bool is_empty() const
int64_t size() const
void append(const T &value)
const T & last(const int64_t n=0) const
bool is_empty() const
void reserve(const int64_t min_capacity)
static bool layered_rendering_support
Definition gl_context.hh:55
static bool framebuffer_fetch_support
Definition gl_context.hh:54
static bool shader_draw_parameters_support
Definition gl_context.hh:60
static bool explicit_location_support
Definition gl_context.hh:53
static float derivative_signs[2]
Definition gl_context.hh:70
static GLContext * get()
static bool native_barycentric_support
Definition gl_context.hh:56
std::string geometry_layout_declare(const shader::ShaderCreateInfo &info) const override
Definition gl_shader.cc:849
std::string vertex_interface_declare(const shader::ShaderCreateInfo &info) const override
Definition gl_shader.cc:669
std::string geometry_interface_declare(const shader::ShaderCreateInfo &info) const override
Definition gl_shader.cc:879
void fragment_shader_from_glsl(MutableSpan< const char * > sources) override
void unbind() override
void uniform_float(int location, int comp_len, int array_size, const float *data) override
void transform_feedback_names_set(Span< const char * > name_list, eGPUShaderTFBType geom_type) override
bool post_finalize(const shader::ShaderCreateInfo *info=nullptr)
GLShader(const char *name)
Definition gl_shader.cc:50
void bind() override
GLSourcesBaked get_sources()
void compute_shader_from_glsl(MutableSpan< const char * > sources) override
std::string compute_layout_declare(const shader::ShaderCreateInfo &info) const override
Definition gl_shader.cc:901
std::string constants_declare() const
Definition gl_shader.cc:619
int program_handle_get() const override
void init(const shader::ShaderCreateInfo &info, bool is_batch_compilation) override
Definition gl_shader.cc:66
std::string resources_declare(const shader::ShaderCreateInfo &info) const override
Definition gl_shader.cc:572
bool transform_feedback_enable(VertBuf *buf) override
void uniform_int(int location, int comp_len, int array_size, const int *data) override
std::string fragment_interface_declare(const shader::ShaderCreateInfo &info) const override
Definition gl_shader.cc:716
bool finalize(const shader::ShaderCreateInfo *info=nullptr) override
void geometry_shader_from_glsl(MutableSpan< const char * > sources) override
void vertex_shader_from_glsl(MutableSpan< const char * > sources) override
void transform_feedback_disable() override
Vector< const char * > sources_get() const
std::string to_string() const
GLSources & operator=(Span< const char * > other)
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 >)
struct blender::gpu::Shader::Constants constants
void print_log(Span< const char * > sources, const char *log, const char *stage, bool error, GPULogParser *parser)
additional_info("compositor_sum_float_shared") .push_constant(Type additional_info("compositor_sum_float_shared") .push_constant(Type GPU_RGBA32F
append
DOF_TILES_FLATTEN_GROUP_SIZE coc_tx GPU_R11F_G11F_B10F
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
out_radiance out_gbuf_normal out_gbuf_closure2 GPU_RG16
SHADOW_TILEMAP_RES tiles_buf[] statistics_buf render_view_buf[SHADOW_VIEW_MAX] GPU_R32UI
RAYTRACE_GROUP_SIZE additional_info("eevee_shared", "eevee_gbuffer_data", "eevee_global_ubo", "eevee_sampling_data", "eevee_utility_texture", "eevee_hiz_data", "draw_view") .specialization_constant(Type RAYTRACE_GROUP_SIZE in_sh_0_tx in_sh_2_tx screen_normal_tx GPU_RGBA8
static const char * glsl_patch_compute_get()
static void print_resource_alias(std::ostream &os, const ShaderCreateInfo::Resource &res)
Definition gl_shader.cc:529
char datatoc_glsl_shader_defines_glsl[]
Definition gl_shader.cc:44
static const char * glsl_patch_default_get()
struct @620::@622 batch
#define DEBUG_LOG_SHADER_SRC_ON_ERROR
#define SOURCES_INDEX_SPECIALIZATION_CONSTANTS
#define SOURCES_INDEX_VERSION
ccl_device_inline float2 interp(const float2 a, const float2 b, float t)
ccl_device_inline float3 log(float3 v)
static ulong * next
#define G(x, y, z)
void object_label(GLenum type, GLuint object, const char *name)
Definition gl_debug.cc:344
StringRefNull gpu_shader_dependency_get_filename_from_source_string(const StringRefNull source_string)
Find the name of the file from which the given string was generated.
BLI_INLINE int to_component_count(const Type &type)
static void print_image_type(std::ostream &os, const ImageType &type, const ShaderCreateInfo::Resource::BindType bind_type)
Definition vk_shader.cc:206
const char * to_string(ShaderStage stage)
Definition mtl_shader.mm:52
static Context * unwrap(GPUContext *ctx)
static StageInterfaceInfo * find_interface_by_name(const Span< StageInterfaceInfo * > ifaces, const StringRefNull name)
static void print_interface(std::ostream &os, const std::string &prefix, const StageInterfaceInfo &iface, int &location, const StringRefNull &suffix="")
Definition vk_shader.cc:452
static std::ostream & print_qualifier(std::ostream &os, const Qualifier &qualifiers)
Definition vk_shader.cc:335
static void print_resource(std::ostream &os, const ShaderCreateInfo::Resource &res)
static Type to_component_type(const Type &type)
Definition vk_shader.cc:866
static std::string main_function_wrapper(std::string &pre_main, std::string &post_main)
Definition vk_shader.cc:467
GPUCapabilities GCaps
__int64 int64_t
Definition stdint.h:89
static constexpr GPUSamplerState default_sampler()
const char * source_ref
Definition gl_shader.hh:38
Vector< gpu::shader::Type > types
Describe inputs & outputs, stage interfaces, resources and sources of a shader. If all data is correc...
Vector< StageInterfaceInfo * > vertex_out_interfaces_
Self & geometry_layout(PrimitiveIn prim_in, PrimitiveOut prim_out, int max_vertices, int invocations=-1)
Vector< StageInterfaceInfo * > geometry_out_interfaces_
Vector< SpecializationConstant > specialization_constants_