21#include BLI_SYSTEM_PID_H
39#include <fmt/format.h>
49# define pclose _pclose
78 async_compilation_ = is_batch_compilation;
82 specialization_constant_names_.append(constant.
name.
c_str());
87 main_program_ = program_cache_
89 []() { return std::make_unique<GLProgram>(); })
91 if (!main_program_->program_id) {
92 main_program_->program_id = glCreateProgram();
111 return "noperspective";
232 case TextureFormat::UINT_8_8_8_8:
234 case TextureFormat::SINT_8_8_8_8:
236 case TextureFormat::UNORM_8_8_8_8:
238 case TextureFormat::UINT_32_32_32_32:
240 case TextureFormat::SINT_32_32_32_32:
242 case TextureFormat::SFLOAT_32_32_32_32:
244 case TextureFormat::UINT_16_16_16_16:
246 case TextureFormat::SINT_16_16_16_16:
248 case TextureFormat::SFLOAT_16_16_16_16:
250 case TextureFormat::UNORM_16_16_16_16:
252 case TextureFormat::UINT_8_8:
254 case TextureFormat::SINT_8_8:
256 case TextureFormat::UNORM_8_8:
258 case TextureFormat::UINT_32_32:
260 case TextureFormat::SINT_32_32:
262 case TextureFormat::SFLOAT_32_32:
264 case TextureFormat::UINT_16_16:
266 case TextureFormat::SINT_16_16:
268 case TextureFormat::SFLOAT_16_16:
270 case TextureFormat::UNORM_16_16:
272 case TextureFormat::UINT_8:
274 case TextureFormat::SINT_8:
276 case TextureFormat::UNORM_8:
278 case TextureFormat::UINT_32:
280 case TextureFormat::SINT_32:
282 case TextureFormat::SFLOAT_32:
284 case TextureFormat::UINT_16:
286 case TextureFormat::SINT_16:
288 case TextureFormat::SFLOAT_16:
290 case TextureFormat::UNORM_16:
292 case TextureFormat::UFLOAT_11_11_10:
293 return "r11f_g11f_b10f";
294 case TextureFormat::UNORM_10_10_10_2:
309 return "lines_adjacency";
313 return "triangles_adjacency";
327 return "triangle_strip";
339 return "depth_greater";
343 return "depth_unchanged";
352 case ImageType::IntBuffer:
353 case ImageType::Int1D:
354 case ImageType::Int1DArray:
355 case ImageType::Int2D:
356 case ImageType::Int2DArray:
357 case ImageType::Int3D:
358 case ImageType::IntCube:
359 case ImageType::IntCubeArray:
360 case ImageType::AtomicInt2D:
361 case ImageType::AtomicInt2DArray:
362 case ImageType::AtomicInt3D:
365 case ImageType::UintBuffer:
366 case ImageType::Uint1D:
367 case ImageType::Uint1DArray:
368 case ImageType::Uint2D:
369 case ImageType::Uint2DArray:
370 case ImageType::Uint3D:
371 case ImageType::UintCube:
372 case ImageType::UintCubeArray:
373 case ImageType::AtomicUint2D:
374 case ImageType::AtomicUint2DArray:
375 case ImageType::AtomicUint3D:
390 case ImageType::FloatBuffer:
391 case ImageType::IntBuffer:
392 case ImageType::UintBuffer:
395 case ImageType::Float1D:
396 case ImageType::Float1DArray:
397 case ImageType::Int1D:
398 case ImageType::Int1DArray:
399 case ImageType::Uint1D:
400 case ImageType::Uint1DArray:
403 case ImageType::Float2D:
404 case ImageType::Float2DArray:
405 case ImageType::Int2D:
406 case ImageType::Int2DArray:
407 case ImageType::AtomicInt2D:
408 case ImageType::AtomicInt2DArray:
409 case ImageType::Uint2D:
410 case ImageType::Uint2DArray:
411 case ImageType::AtomicUint2D:
412 case ImageType::AtomicUint2DArray:
413 case ImageType::Shadow2D:
414 case ImageType::Shadow2DArray:
415 case ImageType::Depth2D:
416 case ImageType::Depth2DArray:
419 case ImageType::Float3D:
420 case ImageType::Int3D:
421 case ImageType::Uint3D:
422 case ImageType::AtomicInt3D:
423 case ImageType::AtomicUint3D:
426 case ImageType::FloatCube:
427 case ImageType::FloatCubeArray:
428 case ImageType::IntCube:
429 case ImageType::IntCubeArray:
430 case ImageType::UintCube:
431 case ImageType::UintCubeArray:
432 case ImageType::ShadowCube:
433 case ImageType::ShadowCubeArray:
434 case ImageType::DepthCube:
435 case ImageType::DepthCubeArray:
443 case ImageType::Float1DArray:
444 case ImageType::Float2DArray:
445 case ImageType::FloatCubeArray:
446 case ImageType::Int1DArray:
447 case ImageType::Int2DArray:
448 case ImageType::IntCubeArray:
449 case ImageType::Uint1DArray:
450 case ImageType::Uint2DArray:
451 case ImageType::AtomicUint2DArray:
452 case ImageType::UintCubeArray:
453 case ImageType::Shadow2DArray:
454 case ImageType::ShadowCubeArray:
455 case ImageType::Depth2DArray:
456 case ImageType::DepthCubeArray:
464 case ImageType::Shadow2D:
465 case ImageType::Shadow2DArray:
466 case ImageType::ShadowCube:
467 case ImageType::ShadowCubeArray:
492 bool auto_resource_location)
500 os <<
"layout(binding = " << res.
slot;
513 os <<
"layout(std140) ";
532 array_offset = res.
uniformbuf.name.find_first_of(
"[");
533 name_no_array = (array_offset == -1) ? res.
uniformbuf.name :
535 os <<
"uniform " << name_no_array <<
" { " << res.
uniformbuf.type_name <<
" _"
539 array_offset = res.
storagebuf.name.find_first_of(
"[");
540 name_no_array = (array_offset == -1) ? res.
storagebuf.name :
557 array_offset = res.
uniformbuf.name.find_first_of(
"[");
558 name_no_array = (array_offset == -1) ? res.
uniformbuf.name :
560 os <<
"#define " << name_no_array <<
" (_" << name_no_array <<
")\n";
563 array_offset = res.
storagebuf.name.find_first_of(
"[");
564 name_no_array = (array_offset == -1) ? res.
storagebuf.name :
566 os <<
"#define " << name_no_array <<
" (_" << name_no_array <<
")\n";
584 os << prefix <<
" " << iface.
name <<
"{" << std::endl;
595 std::stringstream ss;
597 ss <<
"\n/* Compilation Constants (pass-through). */\n";
602 ss <<
"int " << sc.
name <<
"=" << std::to_string(sc.
value.
i) <<
";\n";
605 ss <<
"uint " << sc.
name <<
"=" << std::to_string(sc.
value.
u) <<
"u;\n";
608 ss <<
"bool " << sc.
name <<
"=" << (sc.
value.
u ?
"true" :
"false") <<
";\n";
615 ss <<
"\n/* Shared Variables. */\n";
622 ss <<
"\n/* Pass Resources. */\n";
629 ss <<
"\n/* Batch Resources. */\n";
636 ss <<
"\n/* Geometry Resources. */\n";
643 ss <<
"\n/* Push Constants. */\n";
648 ss <<
"layout(location = " << location <<
") ";
660 ss <<
"#define " << uniform.
name <<
"_ " << uniform.
name <<
"\n";
661 ss <<
"#define " << uniform.
name <<
" (" << uniform.
name <<
"_)\n";
671 std::stringstream ss;
673 ss <<
"/* Specialization Constants. */\n";
679 switch (constant_type) {
681 ss <<
"const int " <<
name <<
"=" << std::to_string(value.
i) <<
";\n";
684 ss <<
"const uint " <<
name <<
"=" << std::to_string(value.
u) <<
"u;\n";
687 ss <<
"const bool " <<
name <<
"=" << (value.
u ?
"true" :
"false") <<
";\n";
691 ss <<
"const float " <<
name <<
"= uintBitsToFloat(" << std::to_string(value.
u) <<
"u);\n";
703 std::stringstream ss;
706 ss <<
"void main_function_();\n";
708 ss <<
"void main() {\n";
710 ss <<
" main_function_();\n";
714 ss <<
"#define main main_function_\n";
721 std::stringstream ss;
722 std::string post_main;
724 ss <<
"\n/* Inputs. */\n";
730 ss <<
"layout(location = " << attr.
index <<
") ";
734 ss <<
"\n/* Interfaces. */\n";
738 const bool has_geometry_stage = do_geometry_shader_injection(&info) ||
742 if (has_geometry_stage) {
743 if (do_layer_output) {
744 ss <<
"out int gpu_Layer;\n";
746 if (do_viewport_output) {
747 ss <<
"out int gpu_ViewportIndex;\n";
751 if (do_layer_output) {
752 ss <<
"#define gpu_Layer gl_Layer\n";
754 if (do_viewport_output) {
755 ss <<
"#define gpu_ViewportIndex gl_ViewportIndex\n";
759 if (!has_geometry_stage) {
762 post_main +=
"gl_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n";
769 else if (epoxy_has_gl_extension(
"GL_AMD_shader_explicit_vertex_parameter")) {
771 ss <<
"flat out vec4 gpu_pos_flat;\n";
772 ss <<
"out vec4 gpu_pos;\n";
774 post_main +=
" gpu_pos = gpu_pos_flat = gl_Position;\n";
779 if (post_main.empty() ==
false) {
780 std::string pre_main;
788 std::stringstream ss;
789 std::string pre_main, post_main;
791 ss <<
"\n/* Interfaces. */\n";
799 ss <<
"#define gpu_Layer gl_Layer\n";
802 ss <<
"#define gpu_ViewportIndex gl_ViewportIndex\n";
806 ss <<
"flat in vec4 gpu_pos[3];\n";
807 ss <<
"smooth in vec3 gpu_BaryCoord;\n";
808 ss <<
"noperspective in vec3 gpu_BaryCoordNoPersp;\n";
810 else if (epoxy_has_gl_extension(
"GL_AMD_shader_explicit_vertex_parameter")) {
813 ss <<
"\n/* Stable Barycentric Coordinates. */\n";
814 ss <<
"flat in vec4 gpu_pos_flat;\n";
815 ss <<
"__explicitInterpAMD in vec4 gpu_pos;\n";
817 ss <<
"vec3 gpu_BaryCoord;\n";
818 ss <<
"vec3 gpu_BaryCoordNoPersp;\n";
820 ss <<
"vec2 stable_bary_(vec2 in_bary) {\n";
821 ss <<
" vec3 bary = vec3(in_bary, 1.0 - in_bary.x - in_bary.y);\n";
822 ss <<
" if (interpolateAtVertexAMD(gpu_pos, 0) == gpu_pos_flat) { return bary.zxy; }\n";
823 ss <<
" if (interpolateAtVertexAMD(gpu_pos, 2) == gpu_pos_flat) { return bary.yzx; }\n";
824 ss <<
" return bary.xyz;\n";
828 pre_main +=
" gpu_BaryCoord = stable_bary_(gl_BaryCoordSmoothAMD);\n";
829 pre_main +=
" gpu_BaryCoordNoPersp = stable_bary_(gl_BaryCoordNoPerspAMD);\n";
833 ss <<
"layout(early_fragment_tests) in;\n";
837 ss <<
"\n/* Sub-pass Inputs. */\n";
841 ss <<
"layout(location = " << std::to_string(
input.index) <<
") inout "
845 std::string image_name =
"gpu_subpass_img_";
846 image_name += std::to_string(
input.index);
854 bool is_layered_input =
ELEM(
855 input.img_type, ImageType::Uint2DArray, ImageType::Int2DArray, ImageType::Float2DArray);
861 Resource res(Resource::BindType::SAMPLER,
input.index);
862 res.sampler.type =
input.img_type;
864 res.sampler.name = image_name;
867 char swizzle[] =
"xyzw";
870 std::string texel_co = (is_layered_input) ?
871 ((is_layered_fb) ?
"ivec3(gl_FragCoord.xy, gpu_Layer)" :
875 "ivec3(gl_FragCoord.xy, 0)") :
876 "ivec2(gl_FragCoord.xy)";
878 std::stringstream ss_pre;
880 ss_pre <<
" " <<
input.name <<
" = texelFetch(" << image_name <<
", " << texel_co <<
", 0)."
883 pre_main += ss_pre.str();
886 ss <<
"\n/* Outputs. */\n";
888 ss <<
"layout(location = " <<
output.index;
904 if (!pre_main.empty() || !post_main.empty()) {
915 std::stringstream ss;
916 ss <<
"\n/* Geometry Layout. */\n";
918 if (invocations != -1) {
919 ss <<
", invocations = " << invocations;
924 <<
", max_vertices = " << max_verts <<
") out;\n";
932 for (
auto *iface : ifaces) {
933 if (iface->instance_name ==
name) {
942 std::stringstream ss;
944 ss <<
"\n/* Interfaces. */\n";
948 const char *suffix = (has_matching_output_iface) ?
"_in[]" :
"[]";
955 const char *suffix = (has_matching_input_iface) ?
"_out" :
"";
964 std::stringstream ss;
965 ss <<
"\n/* Compute Layout. */\n";
981std::string GLShader::workaround_geometry_shader_source_create(
984 std::stringstream ss;
1001 if (do_layer_output) {
1002 ss <<
"in int gpu_Layer[];\n";
1004 if (do_viewport_output) {
1005 ss <<
"in int gpu_ViewportIndex[];\n";
1008 if (do_barycentric_workaround) {
1009 ss <<
"flat out vec4 gpu_pos[3];\n";
1010 ss <<
"smooth out vec3 gpu_BaryCoord;\n";
1011 ss <<
"noperspective out vec3 gpu_BaryCoordNoPersp;\n";
1015 ss <<
"void main()\n";
1017 if (do_barycentric_workaround) {
1018 ss <<
" gpu_pos[0] = gl_in[0].gl_Position;\n";
1019 ss <<
" gpu_pos[1] = gl_in[1].gl_Position;\n";
1020 ss <<
" gpu_pos[2] = gl_in[2].gl_Position;\n";
1022 for (
auto i : IndexRange(3)) {
1029 if (do_barycentric_workaround) {
1030 ss <<
" gpu_BaryCoordNoPersp = gpu_BaryCoord =";
1031 ss <<
" vec3(" << int(
i == 0) <<
", " << int(
i == 1) <<
", " << int(
i == 2) <<
");\n";
1033 ss <<
" gl_Position = gl_in[" <<
i <<
"].gl_Position;\n";
1034 if (
bool(info.
builtins_ & BuiltinBits::CLIP_CONTROL)) {
1036 ss <<
"gl_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n";
1038 if (do_layer_output) {
1039 ss <<
" gl_Layer = gpu_Layer[" <<
i <<
"];\n";
1041 if (do_viewport_output) {
1042 ss <<
" gl_ViewportIndex = gpu_ViewportIndex[" <<
i <<
"];\n";
1044 ss <<
" EmitVertex();\n";
1074 static std::string patch = []() {
1075 std::stringstream ss;
1077 ss <<
"#version 430\n";
1083 ss <<
"#extension GL_ARB_shader_draw_parameters : enable\n";
1084 ss <<
"#define GPU_ARB_shader_draw_parameters\n";
1085 ss <<
"#define gpu_BaseInstance gl_BaseInstanceARB\n";
1086 ss <<
"#define GPU_ARB_clip_control\n";
1089 ss <<
"#extension GL_ARB_shader_viewport_layer_array: enable\n";
1092 ss <<
"#extension GL_AMD_shader_explicit_vertex_parameter: enable\n";
1096 ss <<
"#define gpu_InstanceIndex (gl_InstanceID + gpu_BaseInstance)\n";
1099 ss <<
"#define gpu_Array(_type) _type[]\n";
1102 ss <<
"#define GPU_VERTEX_SHADER\n";
1106 return fmt::to_string(fmt::join(
1115 static std::string patch = []() {
1116 std::stringstream ss;
1118 ss <<
"#version 430\n";
1121 ss <<
"#extension GL_ARB_shader_viewport_layer_array: enable\n";
1124 ss <<
"#extension GL_AMD_shader_explicit_vertex_parameter: enable\n";
1126 ss <<
"#define GPU_ARB_clip_control\n";
1129 ss <<
"#define gpu_Array(_type) _type[]\n";
1132 ss <<
"#define GPU_GEOMETRY_SHADER\n";
1136 return fmt::to_string(fmt::join(
1145 static std::string patch = []() {
1146 std::stringstream ss;
1148 ss <<
"#version 430\n";
1151 ss <<
"#extension GL_ARB_shader_viewport_layer_array: enable\n";
1154 ss <<
"#extension GL_AMD_shader_explicit_vertex_parameter: enable\n";
1157 ss <<
"#extension GL_EXT_shader_framebuffer_fetch: enable\n";
1160 ss <<
"#extension GL_ARB_shader_stencil_export: enable\n";
1161 ss <<
"#define GPU_ARB_shader_stencil_export\n";
1163 ss <<
"#define GPU_ARB_clip_control\n";
1166 ss <<
"#define gpu_Array(_type) _type[]\n";
1169 ss <<
"#define GPU_FRAGMENT_SHADER\n";
1173 return fmt::to_string(fmt::join(
1182 static std::string patch = []() {
1183 std::stringstream ss;
1185 ss <<
"#version 430\n";
1188 ss <<
"#define gpu_Array(_type) _type[]\n";
1191 ss <<
"#define GPU_COMPUTE_SHADER\n";
1193 ss <<
"#define GPU_ARB_clip_control\n";
1197 return fmt::to_string(fmt::join(
1203StringRefNull GLShader::glsl_patch_get(GLenum gl_stage)
1205 if (gl_stage == GL_VERTEX_SHADER) {
1208 if (gl_stage == GL_GEOMETRY_SHADER) {
1211 if (gl_stage == GL_FRAGMENT_SHADER) {
1214 if (gl_stage == GL_COMPUTE_SHADER) {
1221GLuint GLShader::create_shader_stage(GLenum gl_stage,
1222 MutableSpan<StringRefNull> sources,
1227 std::string constants_source;
1228 Vector<StringRefNull> recreated_sources;
1229 if (has_specialization_constants()) {
1233 sources = recreated_sources;
1241 if (async_compilation_) {
1249 StringRefNull source_type;
1251 case GL_VERTEX_SHADER:
1252 source_type =
"VertShader";
1254 case GL_GEOMETRY_SHADER:
1255 source_type =
"GeomShader";
1257 case GL_FRAGMENT_SHADER:
1258 source_type =
"FragShader";
1260 case GL_COMPUTE_SHADER:
1261 source_type =
"ComputeShader";
1265 debug_source +=
"\n\n----------" + source_type +
"----------\n\n";
1266 for (StringRefNull source : sources) {
1267 debug_source.append(source);
1271 if (async_compilation_) {
1276 GLuint shader = glCreateShader(gl_stage);
1278 fprintf(stderr,
"GLShader: Error: Could not create shader object.\n");
1282 std::string concat_source = fmt::to_string(fmt::join(sources,
""));
1285 size_t start_pos = 0;
1286 while ((start_pos = concat_source.find(
"#line ", start_pos)) != std::string::npos) {
1287 concat_source[start_pos] =
'/';
1288 concat_source[start_pos + 1] =
'/';
1291 const char *str_ptr = concat_source.c_str();
1292 glShaderSource(shader, 1, &str_ptr,
nullptr);
1293 glCompileShader(shader);
1296 glGetShaderiv(shader, GL_COMPILE_STATUS, &
status);
1298 char log[5000] =
"";
1299 glGetShaderInfoLog(shader,
sizeof(
log),
nullptr,
log);
1300 if (
log[0] !=
'\0') {
1303 case GL_VERTEX_SHADER:
1306 case GL_GEOMETRY_SHADER:
1309 case GL_FRAGMENT_SHADER:
1312 case GL_COMPUTE_SHADER:
1319 glDeleteShader(shader);
1320 compilation_failed_ =
true;
1328void GLShader::update_program_and_sources(
GLSources &stage_sources,
1329 MutableSpan<StringRefNull> sources)
1331 const bool store_sources = has_specialization_constants() || async_compilation_;
1332 if (store_sources && stage_sources.
is_empty()) {
1333 stage_sources = sources;
1339 update_program_and_sources(vertex_sources_, sources);
1340 main_program_->vert_shader = create_shader_stage(
1341 GL_VERTEX_SHADER, sources, vertex_sources_, *
constants);
1346 update_program_and_sources(geometry_sources_, sources);
1347 main_program_->geom_shader = create_shader_stage(
1348 GL_GEOMETRY_SHADER, sources, geometry_sources_, *
constants);
1353 update_program_and_sources(fragment_sources_, sources);
1354 main_program_->frag_shader = create_shader_stage(
1355 GL_FRAGMENT_SHADER, sources, fragment_sources_, *
constants);
1360 update_program_and_sources(compute_sources_, sources);
1361 main_program_->compute_shader = create_shader_stage(
1362 GL_COMPUTE_SHADER, sources, compute_sources_, *
constants);
1367 if (compilation_failed_) {
1371 if (info && do_geometry_shader_injection(info)) {
1372 std::string source = workaround_geometry_shader_source_create(*info);
1374 sources.
append(
"version");
1375 sources.
append(
"/* Specialization Constants. */\n");
1380 if (async_compilation_) {
1384 main_program_->program_link(
name);
1390 GLuint program_id = main_program_->program_id;
1392 glGetProgramiv(program_id, GL_LINK_STATUS, &
status);
1395 glGetProgramInfoLog(program_id,
sizeof(
log),
nullptr,
log);
1402 async_compilation_ =
false;
1404 if (info !=
nullptr) {
1422 GLProgram &program = program_get(constants_state);
1423 glUseProgram(program.program_id);
1443 glUniform1fv(location, array_size,
data);
1446 glUniform2fv(location, array_size,
data);
1449 glUniform3fv(location, array_size,
data);
1452 glUniform4fv(location, array_size,
data);
1455 glUniformMatrix3fv(location, array_size, 0,
data);
1458 glUniformMatrix4fv(location, array_size, 0,
data);
1470 glUniform1iv(location, array_size,
data);
1473 glUniform2iv(location, array_size,
data);
1476 glUniform3iv(location, array_size,
data);
1479 glUniform4iv(location, array_size,
data);
1512 if (other_source.is_empty()) {
1526 for (
const GLSource &source : *
this) {
1540 for (
const GLSource &source : *
this) {
1567GLShader::GLProgram::~GLProgram()
1578void GLShader::GLProgram::program_link(
StringRefNull shader_name)
1580 if (this->program_id == 0) {
1581 this->program_id = glCreateProgram();
1585 GLuint program_id = this->program_id;
1587 if (this->vert_shader) {
1588 glAttachShader(program_id, this->vert_shader);
1590 if (this->geom_shader) {
1591 glAttachShader(program_id, this->geom_shader);
1593 if (this->frag_shader) {
1594 glAttachShader(program_id, this->frag_shader);
1596 if (this->compute_shader) {
1597 glAttachShader(program_id, this->compute_shader);
1599 glLinkProgram(program_id);
1602GLShader::GLProgram &GLShader::program_get(
const shader::SpecializationConstants *constants_state)
1604 BLI_assert(constants_state ==
nullptr || this->has_specialization_constants() ==
true);
1606 if (constants_state ==
nullptr) {
1609 return *main_program_;
1612 program_cache_mutex_.lock();
1614 GLProgram &program = *program_cache_.lookup_or_add_cb(
1615 constants_state->
values, []() { return std::make_unique<GLProgram>(); });
1617 program_cache_mutex_.unlock();
1620 std::scoped_lock
lock(program.compilation_mutex);
1622 if (program.program_id != 0) {
1627 if (!vertex_sources_.is_empty()) {
1628 program.vert_shader = create_shader_stage(
1629 GL_VERTEX_SHADER, {}, vertex_sources_, *constants_state);
1631 if (!geometry_sources_.is_empty()) {
1632 program.geom_shader = create_shader_stage(
1633 GL_GEOMETRY_SHADER, {}, geometry_sources_, *constants_state);
1635 if (!fragment_sources_.is_empty()) {
1636 program.frag_shader = create_shader_stage(
1637 GL_FRAGMENT_SHADER, {}, fragment_sources_, *constants_state);
1639 if (!compute_sources_.is_empty()) {
1640 program.compute_shader = create_shader_stage(
1641 GL_COMPUTE_SHADER, {}, compute_sources_, *constants_state);
1644 if (async_compilation_) {
1645 program.program_id = glCreateProgram();
1653 program.program_link(
name);
1659 glGetProgramiv(program.program_id, GL_LINK_STATUS, &
status);
1671 result.comp = compute_sources_.to_string();
1672 result.vert = vertex_sources_.to_string();
1673 result.geom = geometry_sources_.to_string();
1674 result.frag = fragment_sources_.to_string();
1691#if BLI_SUBPROCESS_SUPPORT
1697GLCompilerWorker::GLCompilerWorker()
1699 static size_t pipe_id = 0;
1702 std::string
name =
"BLENDER_SHADER_COMPILER_" + std::to_string(getpid()) +
"_" +
1703 std::to_string(pipe_id);
1705 shared_mem_ = std::make_unique<SharedMemory>(
1706 name, compilation_subprocess_shared_memory_size,
true);
1707 start_semaphore_ = std::make_unique<SharedSemaphore>(
name +
"_START",
false);
1708 end_semaphore_ = std::make_unique<SharedSemaphore>(
name +
"_END",
false);
1709 close_semaphore_ = std::make_unique<SharedSemaphore>(
name +
"_CLOSE",
false);
1711 subprocess_.create({
"--compilation-subprocess",
name.c_str()});
1714GLCompilerWorker::~GLCompilerWorker()
1716 close_semaphore_->increment();
1718 start_semaphore_->increment();
1721void GLCompilerWorker::compile(
const GLSourcesBaked &sources)
1725 ShaderSourceHeader *shared_src =
reinterpret_cast<ShaderSourceHeader *
>(shared_mem_->get_data());
1726 char *next_src = shared_src->sources;
1728 auto add_src = [&](
const std::string &src) {
1730 const size_t src_size = src.size() + 1;
1731 memcpy(next_src, src.c_str(), src_size);
1732 next_src += src_size;
1736 add_src(sources.
comp);
1737 add_src(sources.
vert);
1738 add_src(sources.
geom);
1739 add_src(sources.
frag);
1741 BLI_assert(
size_t(next_src) <=
size_t(shared_src) + compilation_subprocess_shared_memory_size);
1743 if (!sources.
comp.empty()) {
1745 shared_src->type = ShaderSourceHeader::Type::COMPUTE;
1749 shared_src->type = sources.
geom.empty() ?
1750 ShaderSourceHeader::Type::GRAPHICS :
1751 ShaderSourceHeader::Type::GRAPHICS_WITH_GEOMETRY_STAGE;
1754 start_semaphore_->increment();
1756 state_ = COMPILATION_REQUESTED;
1760bool GLCompilerWorker::block_until_ready()
1762 BLI_assert(
ELEM(state_, COMPILATION_REQUESTED, COMPILATION_READY));
1763 if (state_ == COMPILATION_READY) {
1767 auto delete_cached_binary = [&]() {
1771 char str_start[] =
"SOURCE_HASH:";
1772 char *shared_mem =
reinterpret_cast<char *
>(shared_mem_->get_data());
1774 std::string path = GL_shader_cache_dir_get() +
SEP_STR +
1775 std::string(shared_mem +
sizeof(str_start) - 1);
1782 while (!end_semaphore_->try_decrement(1000)) {
1784 delete_cached_binary();
1789 state_ = COMPILATION_READY;
1793bool GLCompilerWorker::is_lost()
1796 float max_timeout_seconds = 30.0f;
1797 return !subprocess_.is_running() ||
1798 (state_ == COMPILATION_REQUESTED &&
1802bool GLCompilerWorker::load_program_binary(GLint program)
1804 if (!block_until_ready()) {
1808 ShaderBinaryHeader *binary = (ShaderBinaryHeader *)shared_mem_->get_data();
1810 state_ = COMPILATION_FINISHED;
1812 if (binary->size > 0) {
1814 glProgramBinary(program, binary->format, binary->data, binary->size);
1822void GLCompilerWorker::release()
1833GLSubprocessShaderCompiler::~GLSubprocessShaderCompiler()
1836 destruct_compilation_worker();
1838 for (GLCompilerWorker *worker : workers_) {
1843GLCompilerWorker *GLSubprocessShaderCompiler::get_compiler_worker()
1845 auto new_worker = [&]() {
1846 GLCompilerWorker *
result =
new GLCompilerWorker();
1847 std::lock_guard
lock(workers_mutex_);
1852 static thread_local GLCompilerWorker *worker = new_worker();
1854 if (worker->is_lost()) {
1855 std::cerr <<
"ERROR: Compilation subprocess lost\n";
1857 std::lock_guard
lock(workers_mutex_);
1858 workers_.remove_first_occurrence_and_reorder(worker);
1861 worker = new_worker();
1869 const_cast<ShaderCreateInfo *
>(&info)->
finalize();
1873 size_t required_size = sources.
size();
1874 bool do_async_compilation = required_size <=
sizeof(ShaderSourceHeader::sources);
1875 if (!do_async_compilation) {
1878 return compile(info,
false);
1881 GLCompilerWorker *worker = get_compiler_worker();
1882 worker->compile(sources);
1890 if (!worker->load_program_binary(shader->program_cache_.lookup(
constants.values)->program_id) ||
1903 return compile(info,
false);
1911 static std::mutex
mutex;
1915 auto program_get = [&]() -> GLShader::GLProgram * {
1916 if (shader->program_cache_.contains(specialization.
constants.
values)) {
1917 return shader->program_cache_.lookup(specialization.
constants.
values).get();
1922 auto program_release = [&]() {
1924 GLShader::GLProgram *program = program_get();
1925 glDeleteProgram(program->program_id);
1926 program->program_id = 0;
1929 GLSourcesBaked sources;
1933 if (program_get()) {
1939 shader->async_compilation_ =
true;
1940 shader->program_get(&specialization.
constants);
1941 shader->async_compilation_ =
false;
1944 size_t required_size = sources.
size();
1945 bool do_async_compilation = required_size <=
sizeof(ShaderSourceHeader::sources);
1946 if (!do_async_compilation) {
1954 GLCompilerWorker *worker = get_compiler_worker();
1955 worker->compile(sources);
1956 worker->block_until_ready();
1960 if (!worker->load_program_binary(program_get()->program_id)) {
#define BLI_assert_unreachable()
File and directory operations.
int BLI_exists(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
int BLI_delete(const char *path, bool dir, bool recursive) ATTR_NONNULL()
KDTree *BLI_kdtree_nd_ new(unsigned int nodes_len_capacity)
int bool BLI_str_startswith(const char *__restrict str, const char *__restrict start) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1
Platform independent time functions.
double BLI_time_now_seconds(void)
#define UNUSED_FUNCTION(x)
bool GPU_stencil_export_support()
void GPU_debug_group_end()
void GPU_debug_group_begin(const char *name)
#define GPU_DEBUG_SHADER_SPECIALIZATION_GROUP
const blender::gpu::shader::SpecializationConstants & GPU_shader_get_default_constant_state(blender::gpu::Shader *sh)
BMesh const char void * data
void append(const GLSource &value)
void reserve(const int64_t min_capacity)
constexpr bool is_empty() const
constexpr int64_t size() const
constexpr bool is_empty() const
constexpr const char * c_str() const
void append(const T &value)
static bool layered_rendering_support
static bool framebuffer_fetch_support
static bool explicit_location_support
static void shader_free(GLuint shader_id)
static bool native_barycentric_support
static void program_free(GLuint program_id)
virtual void specialize_shader(ShaderSpecialization &specialization) override
std::string geometry_layout_declare(const shader::ShaderCreateInfo &info) const override
std::string vertex_interface_declare(const shader::ShaderCreateInfo &info) const override
void fragment_shader_from_glsl(MutableSpan< StringRefNull > sources) override
std::string geometry_interface_declare(const shader::ShaderCreateInfo &info) const override
void geometry_shader_from_glsl(MutableSpan< StringRefNull > sources) override
void compute_shader_from_glsl(MutableSpan< StringRefNull > sources) override
void uniform_float(int location, int comp_len, int array_size, const float *data) override
bool post_finalize(const shader::ShaderCreateInfo *info=nullptr)
GLShader(const char *name)
GLSourcesBaked get_sources()
std::string compute_layout_declare(const shader::ShaderCreateInfo &info) const override
std::string constants_declare(const shader::SpecializationConstants &constants_state) const
void init(const shader::ShaderCreateInfo &info, bool is_batch_compilation) override
std::string resources_declare(const shader::ShaderCreateInfo &info) const 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
bool finalize(const shader::ShaderCreateInfo *info=nullptr) override
void bind(const shader::SpecializationConstants *constants_state) override
void vertex_shader_from_glsl(MutableSpan< StringRefNull > sources) override
GLSources & operator=(Span< StringRefNull > other)
std::string to_string() const
Vector< StringRefNull > sources_get() const
virtual void specialize_shader(ShaderSpecialization &)
virtual Shader * compile_shader(const shader::ShaderCreateInfo &info)
std::unique_ptr< const shader::SpecializationConstants > constants
void print_log(Span< StringRefNull > sources, const char *log, const char *stage, bool error, GPULogParser *parser)
static StringRefNull glsl_patch_geometry_get()
static void print_resource_alias(std::ostream &os, const ShaderCreateInfo::Resource &res)
static StringRefNull glsl_patch_compute_get()
static StringRefNull glsl_patch_vertex_get()
static StringRefNull glsl_patch_fragment_get()
static Type UNUSED_FUNCTION to_component_type(const Type &type)
#define DEBUG_LOG_SHADER_SRC_ON_ERROR
#define SOURCES_INDEX_SPECIALIZATION_CONSTANTS
#define SOURCES_INDEX_VERSION
ccl_device_inline float interp(const float a, const float b, const float t)
void object_label(GLenum type, GLuint object, const char *name)
Vector< shader::GeneratedSource, 0 > GeneratedSourceList
Vector< StringRefNull > gpu_shader_dependency_get_resolved_source(const StringRefNull shader_source_name, const shader::GeneratedSourceList &generated_sources, const StringRefNull shader_name)
BLI_INLINE int to_component_count(const Type &type)
StringRefNull gpu_shader_dependency_get_filename_from_source_string(const StringRef source_string)
Find the name of the file from which the given string was generated.
static void print_image_type(std::ostream &os, const ImageType &type, const ShaderCreateInfo::Resource::BindType bind_type)
const char * to_string(ShaderStage stage)
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="")
static std::ostream & print_qualifier(std::ostream &os, const Qualifier &qualifiers)
static void print_resource(std::ostream &os, const ShaderCreateInfo::Resource &res)
static std::string main_function_wrapper(std::string &pre_main, std::string &post_main)
static constexpr GPUSamplerState default_sampler()
blender::gpu::shader::SpecializationConstants constants
blender::gpu::Shader * shader
std::optional< StringRefNull > source_ref
SpecializationConstant::Value value
PrimitiveOut primitive_out
Describe inputs & outputs, stage interfaces, resources and sources of a shader. If all data is correc...
Vector< StageInterfaceInfo * > vertex_out_interfaces_
Vector< SubpassIn > subpass_inputs_
Vector< Resource > geometry_resources_
Self & geometry_layout(PrimitiveIn prim_in, PrimitiveOut prim_out, int max_vertices, int invocations=-1)
Vector< CompilationConstant, 0 > compilation_constants_
Vector< VertIn > vertex_inputs_
bool early_fragment_test_
bool auto_resource_location_
Vector< Resource > batch_resources_
StringRefNull geometry_source_
Vector< StageInterfaceInfo * > geometry_out_interfaces_
Vector< Resource > pass_resources_
GeometryStageLayout geometry_layout_
Vector< SharedVariable, 0 > shared_variables_
ComputeStageLayout compute_layout_
Vector< SpecializationConstant > specialization_constants_
Vector< PushConst > push_constants_
Vector< FragOut > fragment_outputs_
Vector< SpecializationConstant::Value, 8 > values
Vector< gpu::shader::Type, 8 > types
StringRefNull instance_name