21#include BLI_SYSTEM_PID_H
41# define pclose _pclose
72 async_compilation_ = is_batch_compilation;
76 specialization_constant_names_.append(constant.
name.
c_str());
81 main_program_ = program_cache_
83 []() { return std::make_unique<GLProgram>(); })
85 if (!main_program_->program_id) {
86 main_program_->program_id = glCreateProgram();
93 main_program_ = program_cache_
95 []() { return std::make_unique<GLProgram>(); })
97 if (!main_program_->program_id) {
98 main_program_->program_id = glCreateProgram();
117 return "noperspective";
299 return "r11f_g11f_b10f";
315 return "lines_adjacency";
319 return "triangles_adjacency";
333 return "triangle_strip";
345 return "depth_greater";
349 return "depth_unchanged";
358 case ImageType::IntBuffer:
359 case ImageType::Int1D:
360 case ImageType::Int1DArray:
361 case ImageType::Int2D:
362 case ImageType::Int2DArray:
363 case ImageType::Int3D:
364 case ImageType::IntCube:
365 case ImageType::IntCubeArray:
366 case ImageType::AtomicInt2D:
367 case ImageType::AtomicInt2DArray:
368 case ImageType::AtomicInt3D:
371 case ImageType::UintBuffer:
372 case ImageType::Uint1D:
373 case ImageType::Uint1DArray:
374 case ImageType::Uint2D:
375 case ImageType::Uint2DArray:
376 case ImageType::Uint3D:
377 case ImageType::UintCube:
378 case ImageType::UintCubeArray:
379 case ImageType::AtomicUint2D:
380 case ImageType::AtomicUint2DArray:
381 case ImageType::AtomicUint3D:
396 case ImageType::FloatBuffer:
397 case ImageType::IntBuffer:
398 case ImageType::UintBuffer:
401 case ImageType::Float1D:
402 case ImageType::Float1DArray:
403 case ImageType::Int1D:
404 case ImageType::Int1DArray:
405 case ImageType::Uint1D:
406 case ImageType::Uint1DArray:
409 case ImageType::Float2D:
410 case ImageType::Float2DArray:
411 case ImageType::Int2D:
412 case ImageType::Int2DArray:
413 case ImageType::AtomicInt2D:
414 case ImageType::AtomicInt2DArray:
415 case ImageType::Uint2D:
416 case ImageType::Uint2DArray:
417 case ImageType::AtomicUint2D:
418 case ImageType::AtomicUint2DArray:
419 case ImageType::Shadow2D:
420 case ImageType::Shadow2DArray:
421 case ImageType::Depth2D:
422 case ImageType::Depth2DArray:
425 case ImageType::Float3D:
426 case ImageType::Int3D:
427 case ImageType::Uint3D:
428 case ImageType::AtomicInt3D:
429 case ImageType::AtomicUint3D:
432 case ImageType::FloatCube:
433 case ImageType::FloatCubeArray:
434 case ImageType::IntCube:
435 case ImageType::IntCubeArray:
436 case ImageType::UintCube:
437 case ImageType::UintCubeArray:
438 case ImageType::ShadowCube:
439 case ImageType::ShadowCubeArray:
440 case ImageType::DepthCube:
441 case ImageType::DepthCubeArray:
449 case ImageType::Float1DArray:
450 case ImageType::Float2DArray:
451 case ImageType::FloatCubeArray:
452 case ImageType::Int1DArray:
453 case ImageType::Int2DArray:
454 case ImageType::IntCubeArray:
455 case ImageType::Uint1DArray:
456 case ImageType::Uint2DArray:
457 case ImageType::AtomicUint2DArray:
458 case ImageType::UintCubeArray:
459 case ImageType::Shadow2DArray:
460 case ImageType::ShadowCubeArray:
461 case ImageType::Depth2DArray:
462 case ImageType::DepthCubeArray:
470 case ImageType::Shadow2D:
471 case ImageType::Shadow2DArray:
472 case ImageType::ShadowCube:
473 case ImageType::ShadowCubeArray:
498 bool auto_resource_location)
506 os <<
"layout(binding = " << res.
slot;
519 os <<
"layout(std140) ";
538 array_offset = res.
uniformbuf.name.find_first_of(
"[");
539 name_no_array = (array_offset == -1) ? res.
uniformbuf.name :
541 os <<
"uniform " << name_no_array <<
" { " << res.
uniformbuf.type_name <<
" _"
545 array_offset = res.
storagebuf.name.find_first_of(
"[");
546 name_no_array = (array_offset == -1) ? res.
storagebuf.name :
563 array_offset = res.
uniformbuf.name.find_first_of(
"[");
564 name_no_array = (array_offset == -1) ? res.
uniformbuf.name :
566 os <<
"#define " << name_no_array <<
" (_" << name_no_array <<
")\n";
569 array_offset = res.
storagebuf.name.find_first_of(
"[");
570 name_no_array = (array_offset == -1) ? res.
storagebuf.name :
572 os <<
"#define " << name_no_array <<
" (_" << name_no_array <<
")\n";
590 os << prefix <<
" " << iface.
name <<
"{" << std::endl;
601 std::stringstream ss;
603 ss <<
"\n/* Compilation Constants (pass-through). */\n";
608 ss <<
"int " << sc.
name <<
"=" << std::to_string(sc.
value.
i) <<
";\n";
611 ss <<
"uint " << sc.
name <<
"=" << std::to_string(sc.
value.
u) <<
"u;\n";
614 ss <<
"bool " << sc.
name <<
"=" << (sc.
value.
u ?
"true" :
"false") <<
";\n";
624 ss <<
"\n/* Pass Resources. */\n";
631 ss <<
"\n/* Batch Resources. */\n";
638 ss <<
"\n/* Geometry Resources. */\n";
645 ss <<
"\n/* Push Constants. */\n";
650 ss <<
"layout(location = " << location <<
") ";
662 ss <<
"#define " << uniform.
name <<
"_ " << uniform.
name <<
"\n";
663 ss <<
"#define " << uniform.
name <<
" (" << uniform.
name <<
"_)\n";
673 std::stringstream ss;
675 ss <<
"/* Specialization Constants. */\n";
681 switch (constant_type) {
683 ss <<
"const int " <<
name <<
"=" << std::to_string(value.
i) <<
";\n";
686 ss <<
"const uint " <<
name <<
"=" << std::to_string(value.
u) <<
"u;\n";
689 ss <<
"const bool " <<
name <<
"=" << (value.
u ?
"true" :
"false") <<
";\n";
693 ss <<
"const float " <<
name <<
"= uintBitsToFloat(" << std::to_string(value.
u) <<
"u);\n";
705 std::stringstream ss;
708 ss <<
"void main_function_();\n";
710 ss <<
"void main() {\n";
712 ss <<
" main_function_();\n";
716 ss <<
"#define main main_function_\n";
723 std::stringstream ss;
724 std::string post_main;
726 ss <<
"\n/* Inputs. */\n";
732 ss <<
"layout(location = " << attr.
index <<
") ";
736 ss <<
"\n/* Interfaces. */\n";
740 const bool has_geometry_stage = do_geometry_shader_injection(&info) ||
744 if (has_geometry_stage) {
745 if (do_layer_output) {
746 ss <<
"out int gpu_Layer;\n";
748 if (do_viewport_output) {
749 ss <<
"out int gpu_ViewportIndex;\n";
753 if (do_layer_output) {
754 ss <<
"#define gpu_Layer gl_Layer\n";
756 if (do_viewport_output) {
757 ss <<
"#define gpu_ViewportIndex gl_ViewportIndex\n";
764 post_main +=
"gl_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n";
771 else if (epoxy_has_gl_extension(
"GL_AMD_shader_explicit_vertex_parameter")) {
773 ss <<
"flat out vec4 gpu_pos_flat;\n";
774 ss <<
"out vec4 gpu_pos;\n";
776 post_main +=
" gpu_pos = gpu_pos_flat = gl_Position;\n";
781 if (post_main.empty() ==
false) {
782 std::string pre_main;
790 std::stringstream ss;
791 std::string pre_main, post_main;
793 ss <<
"\n/* Interfaces. */\n";
801 ss <<
"#define gpu_Layer gl_Layer\n";
804 ss <<
"#define gpu_ViewportIndex gl_ViewportIndex\n";
808 ss <<
"flat in vec4 gpu_pos[3];\n";
809 ss <<
"smooth in vec3 gpu_BaryCoord;\n";
810 ss <<
"noperspective in vec3 gpu_BaryCoordNoPersp;\n";
812 else if (epoxy_has_gl_extension(
"GL_AMD_shader_explicit_vertex_parameter")) {
815 ss <<
"\n/* Stable Barycentric Coordinates. */\n";
816 ss <<
"flat in vec4 gpu_pos_flat;\n";
817 ss <<
"__explicitInterpAMD in vec4 gpu_pos;\n";
819 ss <<
"vec3 gpu_BaryCoord;\n";
820 ss <<
"vec3 gpu_BaryCoordNoPersp;\n";
822 ss <<
"vec2 stable_bary_(vec2 in_bary) {\n";
823 ss <<
" vec3 bary = vec3(in_bary, 1.0 - in_bary.x - in_bary.y);\n";
824 ss <<
" if (interpolateAtVertexAMD(gpu_pos, 0) == gpu_pos_flat) { return bary.zxy; }\n";
825 ss <<
" if (interpolateAtVertexAMD(gpu_pos, 2) == gpu_pos_flat) { return bary.yzx; }\n";
826 ss <<
" return bary.xyz;\n";
830 pre_main +=
" gpu_BaryCoord = stable_bary_(gl_BaryCoordSmoothAMD);\n";
831 pre_main +=
" gpu_BaryCoordNoPersp = stable_bary_(gl_BaryCoordNoPerspAMD);\n";
835 ss <<
"layout(early_fragment_tests) in;\n";
839 ss <<
"\n/* Sub-pass Inputs. */\n";
843 ss <<
"layout(location = " << std::to_string(
input.index) <<
") inout "
847 std::string image_name =
"gpu_subpass_img_";
848 image_name += std::to_string(
input.index);
856 bool is_layered_input =
ELEM(
857 input.img_type, ImageType::Uint2DArray, ImageType::Int2DArray, ImageType::Float2DArray);
863 Resource res(Resource::BindType::SAMPLER,
input.index);
864 res.sampler.type =
input.img_type;
866 res.sampler.name = image_name;
869 char swizzle[] =
"xyzw";
872 std::string texel_co = (is_layered_input) ?
873 ((is_layered_fb) ?
"ivec3(gl_FragCoord.xy, gpu_Layer)" :
877 "ivec3(gl_FragCoord.xy, 0)") :
878 "ivec2(gl_FragCoord.xy)";
880 std::stringstream ss_pre;
882 ss_pre <<
" " <<
input.name <<
" = texelFetch(" << image_name <<
", " << texel_co <<
", 0)."
885 pre_main += ss_pre.str();
888 ss <<
"\n/* Outputs. */\n";
890 ss <<
"layout(location = " <<
output.index;
906 if (!pre_main.empty() || !post_main.empty()) {
917 std::stringstream ss;
918 ss <<
"\n/* Geometry Layout. */\n";
920 if (invocations != -1) {
921 ss <<
", invocations = " << invocations;
926 <<
", max_vertices = " << max_verts <<
") out;\n";
934 for (
auto *iface : ifaces) {
935 if (iface->instance_name == name) {
944 std::stringstream ss;
946 ss <<
"\n/* Interfaces. */\n";
950 const char *suffix = (has_matching_output_iface) ?
"_in[]" :
"[]";
957 const char *suffix = (has_matching_input_iface) ?
"_out" :
"";
966 std::stringstream ss;
967 ss <<
"\n/* Compute Layout. */\n";
983std::string GLShader::workaround_geometry_shader_source_create(
986 std::stringstream ss;
1003 if (do_layer_output) {
1004 ss <<
"in int gpu_Layer[];\n";
1006 if (do_viewport_output) {
1007 ss <<
"in int gpu_ViewportIndex[];\n";
1010 if (do_barycentric_workaround) {
1011 ss <<
"flat out vec4 gpu_pos[3];\n";
1012 ss <<
"smooth out vec3 gpu_BaryCoord;\n";
1013 ss <<
"noperspective out vec3 gpu_BaryCoordNoPersp;\n";
1017 ss <<
"void main()\n";
1019 if (do_barycentric_workaround) {
1020 ss <<
" gpu_pos[0] = gl_in[0].gl_Position;\n";
1021 ss <<
" gpu_pos[1] = gl_in[1].gl_Position;\n";
1022 ss <<
" gpu_pos[2] = gl_in[2].gl_Position;\n";
1024 for (
auto i : IndexRange(3)) {
1031 if (do_barycentric_workaround) {
1032 ss <<
" gpu_BaryCoordNoPersp = gpu_BaryCoord =";
1033 ss <<
" vec3(" << int(
i == 0) <<
", " << int(
i == 1) <<
", " << int(
i == 2) <<
");\n";
1035 ss <<
" gl_Position = gl_in[" <<
i <<
"].gl_Position;\n";
1036 if (
bool(info.
builtins_ & BuiltinBits::CLIP_CONTROL)) {
1039 ss <<
"gl_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n";
1042 if (do_layer_output) {
1043 ss <<
" gl_Layer = gpu_Layer[" <<
i <<
"];\n";
1045 if (do_viewport_output) {
1046 ss <<
" gl_ViewportIndex = gpu_ViewportIndex[" <<
i <<
"];\n";
1048 ss <<
" EmitVertex();\n";
1078 static std::string patch = []() {
1079 std::stringstream ss;
1081 ss <<
"#version 430\n";
1086 ss <<
"#extension GL_ARB_shader_draw_parameters : enable\n";
1087 ss <<
"#define GPU_ARB_shader_draw_parameters\n";
1088 ss <<
"#define gpu_BaseInstance gl_BaseInstanceARB\n";
1091 ss <<
"#extension GL_ARB_shader_viewport_layer_array: enable\n";
1094 ss <<
"#extension GL_AMD_shader_explicit_vertex_parameter: enable\n";
1097 ss <<
"#define GPU_ARB_clip_control\n";
1102 ss <<
"uniform int gpu_BaseInstance;\n";
1106 ss <<
"#define gpu_InstanceIndex (gl_InstanceID + gpu_BaseInstance)\n";
1109 ss <<
"#define gpu_Array(_type) _type[]\n";
1112 ss <<
"#define GPU_VERTEX_SHADER\n";
1124 static std::string patch = []() {
1125 std::stringstream ss;
1127 ss <<
"#version 430\n";
1130 ss <<
"#extension GL_ARB_shader_viewport_layer_array: enable\n";
1133 ss <<
"#extension GL_AMD_shader_explicit_vertex_parameter: enable\n";
1136 ss <<
"#define GPU_ARB_clip_control\n";
1140 ss <<
"#define gpu_Array(_type) _type[]\n";
1143 ss <<
"#define GPU_GEOMETRY_SHADER\n";
1155 static std::string patch = []() {
1156 std::stringstream ss;
1158 ss <<
"#version 430\n";
1161 ss <<
"#extension GL_ARB_shader_viewport_layer_array: enable\n";
1164 ss <<
"#extension GL_AMD_shader_explicit_vertex_parameter: enable\n";
1167 ss <<
"#extension GL_EXT_shader_framebuffer_fetch: enable\n";
1170 ss <<
"#extension GL_ARB_shader_stencil_export: enable\n";
1171 ss <<
"#define GPU_ARB_shader_stencil_export\n";
1174 ss <<
"#define GPU_ARB_clip_control\n";
1178 ss <<
"#define gpu_Array(_type) _type[]\n";
1181 ss <<
"#define GPU_FRAGMENT_SHADER\n";
1193 static std::string patch = []() {
1194 std::stringstream ss;
1196 ss <<
"#version 430\n";
1199 ss <<
"#define gpu_Array(_type) _type[]\n";
1202 ss <<
"#define GPU_COMPUTE_SHADER\n";
1205 ss <<
"#define GPU_ARB_clip_control\n";
1215StringRefNull GLShader::glsl_patch_get(GLenum gl_stage)
1217 if (gl_stage == GL_VERTEX_SHADER) {
1220 if (gl_stage == GL_GEOMETRY_SHADER) {
1223 if (gl_stage == GL_FRAGMENT_SHADER) {
1226 if (gl_stage == GL_COMPUTE_SHADER) {
1233GLuint GLShader::create_shader_stage(GLenum gl_stage,
1234 MutableSpan<StringRefNull> sources,
1239 std::string constants_source;
1241 if (has_specialization_constants()) {
1245 sources = recreated_sources;
1253 if (async_compilation_) {
1261 StringRefNull source_type;
1263 case GL_VERTEX_SHADER:
1264 source_type =
"VertShader";
1266 case GL_GEOMETRY_SHADER:
1267 source_type =
"GeomShader";
1269 case GL_FRAGMENT_SHADER:
1270 source_type =
"FragShader";
1272 case GL_COMPUTE_SHADER:
1273 source_type =
"ComputeShader";
1277 debug_source +=
"\n\n----------" + source_type +
"----------\n\n";
1278 for (StringRefNull source : sources) {
1279 debug_source.append(source);
1283 if (async_compilation_) {
1288 GLuint shader = glCreateShader(gl_stage);
1290 fprintf(stderr,
"GLShader: Error: Could not create shader object.\n");
1294 Array<const char *, 16> c_str_sources(sources.size());
1295 for (
const int i : sources.index_range()) {
1296 c_str_sources[
i] = sources[
i].c_str();
1298 glShaderSource(shader, c_str_sources.size(), c_str_sources.data(),
nullptr);
1299 glCompileShader(shader);
1302 glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
1304 char log[5000] =
"";
1305 glGetShaderInfoLog(shader,
sizeof(
log),
nullptr,
log);
1306 if (
log[0] !=
'\0') {
1309 case GL_VERTEX_SHADER:
1310 this->
print_log(sources,
log,
"VertShader", !status, &parser);
1312 case GL_GEOMETRY_SHADER:
1313 this->
print_log(sources,
log,
"GeomShader", !status, &parser);
1315 case GL_FRAGMENT_SHADER:
1316 this->
print_log(sources,
log,
"FragShader", !status, &parser);
1318 case GL_COMPUTE_SHADER:
1319 this->
print_log(sources,
log,
"ComputeShader", !status, &parser);
1325 glDeleteShader(shader);
1326 compilation_failed_ =
true;
1334void GLShader::update_program_and_sources(
GLSources &stage_sources,
1335 MutableSpan<StringRefNull> sources)
1337 const bool store_sources = has_specialization_constants() || async_compilation_;
1338 if (store_sources && stage_sources.
is_empty()) {
1339 stage_sources = sources;
1345 update_program_and_sources(vertex_sources_, sources);
1346 main_program_->vert_shader = create_shader_stage(
1347 GL_VERTEX_SHADER, sources, vertex_sources_, *
constants);
1352 update_program_and_sources(geometry_sources_, sources);
1353 main_program_->geom_shader = create_shader_stage(
1354 GL_GEOMETRY_SHADER, sources, geometry_sources_, *
constants);
1359 update_program_and_sources(fragment_sources_, sources);
1360 main_program_->frag_shader = create_shader_stage(
1361 GL_FRAGMENT_SHADER, sources, fragment_sources_, *
constants);
1366 update_program_and_sources(compute_sources_, sources);
1367 main_program_->compute_shader = create_shader_stage(
1368 GL_COMPUTE_SHADER, sources, compute_sources_, *
constants);
1373 if (compilation_failed_) {
1377 if (info && do_geometry_shader_injection(info)) {
1378 std::string source = workaround_geometry_shader_source_create(*info);
1380 sources.
append(
"version");
1381 sources.
append(
"/* Specialization Constants. */\n");
1386 if (async_compilation_) {
1390 main_program_->program_link(
name);
1396 GLuint program_id = main_program_->program_id;
1398 glGetProgramiv(program_id, GL_LINK_STATUS, &status);
1401 glGetProgramInfoLog(program_id,
sizeof(
log),
nullptr,
log);
1403 print_log({debug_source},
log,
"Linking",
true, &parser);
1408 async_compilation_ =
false;
1410 if (info !=
nullptr) {
1428 GLProgram &program = program_get(constants_state);
1429 glUseProgram(program.program_id);
1449 glUniform1fv(location, array_size,
data);
1452 glUniform2fv(location, array_size,
data);
1455 glUniform3fv(location, array_size,
data);
1458 glUniform4fv(location, array_size,
data);
1461 glUniformMatrix3fv(location, array_size, 0,
data);
1464 glUniformMatrix4fv(location, array_size, 0,
data);
1476 glUniform1iv(location, array_size,
data);
1479 glUniform2iv(location, array_size,
data);
1482 glUniform3iv(location, array_size,
data);
1485 glUniform4iv(location, array_size,
data);
1518 if (other_source.is_empty()) {
1532 for (
const GLSource &source : *
this) {
1546 for (
const GLSource &source : *
this) {
1573GLShader::GLProgram::~GLProgram()
1576 glDeleteShader(vert_shader);
1577 glDeleteShader(geom_shader);
1578 glDeleteShader(frag_shader);
1579 glDeleteShader(compute_shader);
1580 glDeleteProgram(program_id);
1583void GLShader::GLProgram::program_link(
StringRefNull shader_name)
1585 if (this->program_id == 0) {
1586 this->program_id = glCreateProgram();
1590 GLuint program_id = this->program_id;
1592 if (this->vert_shader) {
1593 glAttachShader(program_id, this->vert_shader);
1595 if (this->geom_shader) {
1596 glAttachShader(program_id, this->geom_shader);
1598 if (this->frag_shader) {
1599 glAttachShader(program_id, this->frag_shader);
1601 if (this->compute_shader) {
1602 glAttachShader(program_id, this->compute_shader);
1604 glLinkProgram(program_id);
1607GLShader::GLProgram &GLShader::program_get(
const shader::SpecializationConstants *constants_state)
1609 BLI_assert(constants_state ==
nullptr || this->has_specialization_constants() ==
true);
1611 if (constants_state ==
nullptr) {
1614 return *main_program_;
1617 program_cache_mutex_.lock();
1619 GLProgram &program = *program_cache_.lookup_or_add_cb(
1620 constants_state->
values, []() { return std::make_unique<GLProgram>(); });
1622 program_cache_mutex_.unlock();
1625 std::scoped_lock
lock(program.compilation_mutex);
1627 if (program.program_id != 0) {
1632 if (!vertex_sources_.is_empty()) {
1633 program.vert_shader = create_shader_stage(
1634 GL_VERTEX_SHADER, {}, vertex_sources_, *constants_state);
1636 if (!geometry_sources_.is_empty()) {
1637 program.geom_shader = create_shader_stage(
1638 GL_GEOMETRY_SHADER, {}, geometry_sources_, *constants_state);
1640 if (!fragment_sources_.is_empty()) {
1641 program.frag_shader = create_shader_stage(
1642 GL_FRAGMENT_SHADER, {}, fragment_sources_, *constants_state);
1644 if (!compute_sources_.is_empty()) {
1645 program.compute_shader = create_shader_stage(
1646 GL_COMPUTE_SHADER, {}, compute_sources_, *constants_state);
1649 if (async_compilation_) {
1650 program.program_id = glCreateProgram();
1658 program.program_link(
name);
1664 glGetProgramiv(program.program_id, GL_LINK_STATUS, &status);
1676 result.comp = compute_sources_.to_string();
1677 result.vert = vertex_sources_.to_string();
1678 result.geom = geometry_sources_.to_string();
1679 result.frag = fragment_sources_.to_string();
1696#if BLI_SUBPROCESS_SUPPORT
1702GLCompilerWorker::GLCompilerWorker()
1704 using namespace std::chrono;
1706 static std::atomic<size_t> g_pipe_id = 0;
1707 size_t pipe_id = g_pipe_id++;
1712 static size_t time_id =
1713 duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
1715 std::string
name =
"BLENDER_SHADER_COMPILER_" + std::to_string(getpid()) +
"_" +
1716 std::to_string(time_id) +
"_" + std::to_string(pipe_id);
1718 shared_mem_ = std::make_unique<SharedMemory>(
1719 name, compilation_subprocess_shared_memory_size,
true);
1720 start_semaphore_ = std::make_unique<SharedSemaphore>(
name +
"_START",
false);
1721 end_semaphore_ = std::make_unique<SharedSemaphore>(
name +
"_END",
false);
1722 close_semaphore_ = std::make_unique<SharedSemaphore>(
name +
"_CLOSE",
false);
1724 subprocess_.create({
"--compilation-subprocess",
name.c_str()});
1727GLCompilerWorker::~GLCompilerWorker()
1729 close_semaphore_->increment();
1731 start_semaphore_->increment();
1734void GLCompilerWorker::compile(
const GLSourcesBaked &sources)
1738 ShaderSourceHeader *shared_src =
reinterpret_cast<ShaderSourceHeader *
>(shared_mem_->get_data());
1739 char *next_src = shared_src->sources;
1741 auto add_src = [&](
const std::string &src) {
1743 const size_t src_size = src.size() + 1;
1744 memcpy(next_src, src.c_str(), src_size);
1745 next_src += src_size;
1749 add_src(sources.
comp);
1750 add_src(sources.
vert);
1751 add_src(sources.
geom);
1752 add_src(sources.
frag);
1754 BLI_assert(
size_t(next_src) <=
size_t(shared_src) + compilation_subprocess_shared_memory_size);
1756 if (!sources.
comp.empty()) {
1758 shared_src->type = ShaderSourceHeader::Type::COMPUTE;
1762 shared_src->type = sources.
geom.empty() ?
1763 ShaderSourceHeader::Type::GRAPHICS :
1764 ShaderSourceHeader::Type::GRAPHICS_WITH_GEOMETRY_STAGE;
1767 start_semaphore_->increment();
1769 state_ = COMPILATION_REQUESTED;
1773bool GLCompilerWorker::block_until_ready()
1775 BLI_assert(
ELEM(state_, COMPILATION_REQUESTED, COMPILATION_READY));
1776 if (state_ == COMPILATION_READY) {
1780 auto delete_cached_binary = [&]() {
1784 char str_start[] =
"SOURCE_HASH:";
1785 char *shared_mem =
reinterpret_cast<char *
>(shared_mem_->get_data());
1787 std::string path = GL_shader_cache_dir_get() +
SEP_STR +
1788 std::string(shared_mem +
sizeof(str_start) - 1);
1795 while (!end_semaphore_->try_decrement(1000)) {
1797 delete_cached_binary();
1802 state_ = COMPILATION_READY;
1806bool GLCompilerWorker::is_lost()
1809 float max_timeout_seconds = 30.0f;
1810 return !subprocess_.is_running() ||
1811 (state_ == COMPILATION_REQUESTED &&
1815bool GLCompilerWorker::load_program_binary(GLint program)
1817 if (!block_until_ready()) {
1821 ShaderBinaryHeader *binary = (ShaderBinaryHeader *)shared_mem_->get_data();
1823 state_ = COMPILATION_FINISHED;
1825 if (binary->size > 0) {
1827 glProgramBinary(program, binary->format, binary->data, binary->size);
1835void GLCompilerWorker::release()
1846GLSubprocessShaderCompiler::~GLSubprocessShaderCompiler()
1849 destruct_compilation_worker();
1851 for (GLCompilerWorker *worker : workers_) {
1856GLCompilerWorker *GLSubprocessShaderCompiler::get_compiler_worker()
1858 auto new_worker = [&]() {
1859 GLCompilerWorker *
result =
new GLCompilerWorker();
1860 std::lock_guard
lock(workers_mutex_);
1865 static thread_local GLCompilerWorker *worker = new_worker();
1867 if (worker->is_lost()) {
1868 std::cerr <<
"ERROR: Compilation subprocess lost\n";
1870 std::lock_guard
lock(workers_mutex_);
1871 workers_.remove_first_occurrence_and_reorder(worker);
1874 worker = new_worker();
1882 const_cast<ShaderCreateInfo *
>(&info)->
finalize();
1886 size_t required_size = sources.
size();
1887 bool do_async_compilation = required_size <=
sizeof(ShaderSourceHeader::sources);
1888 if (!do_async_compilation) {
1891 return compile(info,
false);
1894 GLCompilerWorker *worker = get_compiler_worker();
1895 worker->compile(sources);
1904 if (!worker->load_program_binary(shader->program_cache_.lookup(
constants.values)->program_id) ||
1917 return compile(info,
false);
1925 static std::mutex
mutex;
1929 auto program_get = [&]() -> GLShader::GLProgram * {
1930 if (shader->program_cache_.contains(specialization.
constants.
values)) {
1931 return shader->program_cache_.lookup(specialization.
constants.
values).get();
1936 auto program_release = [&]() {
1938 GLShader::GLProgram *program = program_get();
1939 glDeleteProgram(program->program_id);
1940 program->program_id = 0;
1943 GLSourcesBaked sources;
1947 if (program_get()) {
1953 shader->async_compilation_ =
true;
1954 shader->program_get(&specialization.
constants);
1955 shader->async_compilation_ =
false;
1958 size_t required_size = sources.
size();
1959 bool do_async_compilation = required_size <=
sizeof(ShaderSourceHeader::sources);
1960 if (!do_async_compilation) {
1968 GLCompilerWorker *worker = get_compiler_worker();
1969 worker->compile(sources);
1970 worker->block_until_ready();
1974 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(GPUShader *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 shader_draw_parameters_support
static bool explicit_location_support
static bool clip_control_support
static bool native_barycentric_support
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
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()
char datatoc_glsl_shader_defines_glsl[]
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)
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 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="")
static GPUContext * wrap(Context *ctx)
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
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_
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