21#include BLI_SYSTEM_PID_H
40# define pclose _pclose
71 async_compilation_ = is_batch_compilation;
75 specialization_constant_names_.append(constant.
name.
c_str());
80 main_program_ = program_cache_
82 []() { return std::make_unique<GLProgram>(); })
84 if (!main_program_->program_id) {
85 main_program_->program_id = glCreateProgram();
92 main_program_ = program_cache_
94 []() { return std::make_unique<GLProgram>(); })
96 if (!main_program_->program_id) {
97 main_program_->program_id = glCreateProgram();
116 return "noperspective";
298 return "r11f_g11f_b10f";
314 return "lines_adjacency";
318 return "triangles_adjacency";
332 return "triangle_strip";
344 return "depth_greater";
348 return "depth_unchanged";
357 case ImageType::IntBuffer:
358 case ImageType::Int1D:
359 case ImageType::Int1DArray:
360 case ImageType::Int2D:
361 case ImageType::Int2DArray:
362 case ImageType::Int3D:
363 case ImageType::IntCube:
364 case ImageType::IntCubeArray:
365 case ImageType::AtomicInt2D:
366 case ImageType::AtomicInt2DArray:
367 case ImageType::AtomicInt3D:
370 case ImageType::UintBuffer:
371 case ImageType::Uint1D:
372 case ImageType::Uint1DArray:
373 case ImageType::Uint2D:
374 case ImageType::Uint2DArray:
375 case ImageType::Uint3D:
376 case ImageType::UintCube:
377 case ImageType::UintCubeArray:
378 case ImageType::AtomicUint2D:
379 case ImageType::AtomicUint2DArray:
380 case ImageType::AtomicUint3D:
395 case ImageType::FloatBuffer:
396 case ImageType::IntBuffer:
397 case ImageType::UintBuffer:
400 case ImageType::Float1D:
401 case ImageType::Float1DArray:
402 case ImageType::Int1D:
403 case ImageType::Int1DArray:
404 case ImageType::Uint1D:
405 case ImageType::Uint1DArray:
408 case ImageType::Float2D:
409 case ImageType::Float2DArray:
410 case ImageType::Int2D:
411 case ImageType::Int2DArray:
412 case ImageType::AtomicInt2D:
413 case ImageType::AtomicInt2DArray:
414 case ImageType::Uint2D:
415 case ImageType::Uint2DArray:
416 case ImageType::AtomicUint2D:
417 case ImageType::AtomicUint2DArray:
418 case ImageType::Shadow2D:
419 case ImageType::Shadow2DArray:
420 case ImageType::Depth2D:
421 case ImageType::Depth2DArray:
424 case ImageType::Float3D:
425 case ImageType::Int3D:
426 case ImageType::Uint3D:
427 case ImageType::AtomicInt3D:
428 case ImageType::AtomicUint3D:
431 case ImageType::FloatCube:
432 case ImageType::FloatCubeArray:
433 case ImageType::IntCube:
434 case ImageType::IntCubeArray:
435 case ImageType::UintCube:
436 case ImageType::UintCubeArray:
437 case ImageType::ShadowCube:
438 case ImageType::ShadowCubeArray:
439 case ImageType::DepthCube:
440 case ImageType::DepthCubeArray:
448 case ImageType::Float1DArray:
449 case ImageType::Float2DArray:
450 case ImageType::FloatCubeArray:
451 case ImageType::Int1DArray:
452 case ImageType::Int2DArray:
453 case ImageType::IntCubeArray:
454 case ImageType::Uint1DArray:
455 case ImageType::Uint2DArray:
456 case ImageType::AtomicUint2DArray:
457 case ImageType::UintCubeArray:
458 case ImageType::Shadow2DArray:
459 case ImageType::ShadowCubeArray:
460 case ImageType::Depth2DArray:
461 case ImageType::DepthCubeArray:
469 case ImageType::Shadow2D:
470 case ImageType::Shadow2DArray:
471 case ImageType::ShadowCube:
472 case ImageType::ShadowCubeArray:
497 bool auto_resource_location)
505 os <<
"layout(binding = " << res.
slot;
518 os <<
"layout(std140) ";
537 array_offset = res.
uniformbuf.name.find_first_of(
"[");
538 name_no_array = (array_offset == -1) ? res.
uniformbuf.name :
540 os <<
"uniform " << name_no_array <<
" { " << res.
uniformbuf.type_name <<
" _"
544 array_offset = res.
storagebuf.name.find_first_of(
"[");
545 name_no_array = (array_offset == -1) ? res.
storagebuf.name :
562 array_offset = res.
uniformbuf.name.find_first_of(
"[");
563 name_no_array = (array_offset == -1) ? res.
uniformbuf.name :
565 os <<
"#define " << name_no_array <<
" (_" << name_no_array <<
")\n";
568 array_offset = res.
storagebuf.name.find_first_of(
"[");
569 name_no_array = (array_offset == -1) ? res.
storagebuf.name :
571 os <<
"#define " << name_no_array <<
" (_" << name_no_array <<
")\n";
589 os << prefix <<
" " << iface.
name <<
"{" << std::endl;
600 std::stringstream ss;
602 ss <<
"\n/* Compilation Constants (pass-through). */\n";
607 ss <<
"int " << sc.
name <<
"=" << std::to_string(sc.
value.
i) <<
";\n";
610 ss <<
"uint " << sc.
name <<
"=" << std::to_string(sc.
value.
u) <<
"u;\n";
613 ss <<
"bool " << sc.
name <<
"=" << (sc.
value.
u ?
"true" :
"false") <<
";\n";
623 ss <<
"\n/* Pass Resources. */\n";
630 ss <<
"\n/* Batch Resources. */\n";
637 ss <<
"\n/* Geometry Resources. */\n";
644 ss <<
"\n/* Push Constants. */\n";
649 ss <<
"layout(location = " << location <<
") ";
661 ss <<
"#define " << uniform.
name <<
"_ " << uniform.
name <<
"\n";
662 ss <<
"#define " << uniform.
name <<
" (" << uniform.
name <<
"_)\n";
672 std::stringstream ss;
674 ss <<
"/* Specialization Constants. */\n";
680 switch (constant_type) {
682 ss <<
"const int " <<
name <<
"=" << std::to_string(value.
i) <<
";\n";
685 ss <<
"const uint " <<
name <<
"=" << std::to_string(value.
u) <<
"u;\n";
688 ss <<
"const bool " <<
name <<
"=" << (value.
u ?
"true" :
"false") <<
";\n";
692 ss <<
"const float " <<
name <<
"= uintBitsToFloat(" << std::to_string(value.
u) <<
"u);\n";
704 std::stringstream ss;
707 ss <<
"void main_function_();\n";
709 ss <<
"void main() {\n";
711 ss <<
" main_function_();\n";
715 ss <<
"#define main main_function_\n";
722 std::stringstream ss;
723 std::string post_main;
725 ss <<
"\n/* Inputs. */\n";
731 ss <<
"layout(location = " << attr.
index <<
") ";
735 ss <<
"\n/* Interfaces. */\n";
739 const bool has_geometry_stage = do_geometry_shader_injection(&info) ||
743 if (has_geometry_stage) {
744 if (do_layer_output) {
745 ss <<
"out int gpu_Layer;\n";
747 if (do_viewport_output) {
748 ss <<
"out int gpu_ViewportIndex;\n";
752 if (do_layer_output) {
753 ss <<
"#define gpu_Layer gl_Layer\n";
755 if (do_viewport_output) {
756 ss <<
"#define gpu_ViewportIndex gl_ViewportIndex\n";
763 post_main +=
"gl_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n";
770 else if (epoxy_has_gl_extension(
"GL_AMD_shader_explicit_vertex_parameter")) {
772 ss <<
"flat out vec4 gpu_pos_flat;\n";
773 ss <<
"out vec4 gpu_pos;\n";
775 post_main +=
" gpu_pos = gpu_pos_flat = gl_Position;\n";
780 if (post_main.empty() ==
false) {
781 std::string pre_main;
789 std::stringstream ss;
790 std::string pre_main, post_main;
792 ss <<
"\n/* Interfaces. */\n";
800 ss <<
"#define gpu_Layer gl_Layer\n";
803 ss <<
"#define gpu_ViewportIndex gl_ViewportIndex\n";
807 ss <<
"flat in vec4 gpu_pos[3];\n";
808 ss <<
"smooth in vec3 gpu_BaryCoord;\n";
809 ss <<
"noperspective in vec3 gpu_BaryCoordNoPersp;\n";
811 else if (epoxy_has_gl_extension(
"GL_AMD_shader_explicit_vertex_parameter")) {
814 ss <<
"\n/* Stable Barycentric Coordinates. */\n";
815 ss <<
"flat in vec4 gpu_pos_flat;\n";
816 ss <<
"__explicitInterpAMD in vec4 gpu_pos;\n";
818 ss <<
"vec3 gpu_BaryCoord;\n";
819 ss <<
"vec3 gpu_BaryCoordNoPersp;\n";
821 ss <<
"vec2 stable_bary_(vec2 in_bary) {\n";
822 ss <<
" vec3 bary = vec3(in_bary, 1.0 - in_bary.x - in_bary.y);\n";
823 ss <<
" if (interpolateAtVertexAMD(gpu_pos, 0) == gpu_pos_flat) { return bary.zxy; }\n";
824 ss <<
" if (interpolateAtVertexAMD(gpu_pos, 2) == gpu_pos_flat) { return bary.yzx; }\n";
825 ss <<
" return bary.xyz;\n";
829 pre_main +=
" gpu_BaryCoord = stable_bary_(gl_BaryCoordSmoothAMD);\n";
830 pre_main +=
" gpu_BaryCoordNoPersp = stable_bary_(gl_BaryCoordNoPerspAMD);\n";
834 ss <<
"layout(early_fragment_tests) in;\n";
838 ss <<
"\n/* Sub-pass Inputs. */\n";
842 ss <<
"layout(location = " << std::to_string(
input.index) <<
") inout "
846 std::string image_name =
"gpu_subpass_img_";
847 image_name += std::to_string(
input.index);
855 bool is_layered_input =
ELEM(
856 input.img_type, ImageType::Uint2DArray, ImageType::Int2DArray, ImageType::Float2DArray);
862 Resource res(Resource::BindType::SAMPLER,
input.index);
863 res.sampler.type =
input.img_type;
865 res.sampler.name = image_name;
868 char swizzle[] =
"xyzw";
871 std::string texel_co = (is_layered_input) ?
872 ((is_layered_fb) ?
"ivec3(gl_FragCoord.xy, gpu_Layer)" :
876 "ivec3(gl_FragCoord.xy, 0)") :
877 "ivec2(gl_FragCoord.xy)";
879 std::stringstream ss_pre;
881 ss_pre <<
" " <<
input.name <<
" = texelFetch(" << image_name <<
", " << texel_co <<
", 0)."
884 pre_main += ss_pre.str();
887 ss <<
"\n/* Outputs. */\n";
889 ss <<
"layout(location = " <<
output.index;
905 if (!pre_main.empty() || !post_main.empty()) {
916 std::stringstream ss;
917 ss <<
"\n/* Geometry Layout. */\n";
919 if (invocations != -1) {
920 ss <<
", invocations = " << invocations;
925 <<
", max_vertices = " << max_verts <<
") out;\n";
933 for (
auto *iface : ifaces) {
934 if (iface->instance_name == name) {
943 std::stringstream ss;
945 ss <<
"\n/* Interfaces. */\n";
949 const char *suffix = (has_matching_output_iface) ?
"_in[]" :
"[]";
956 const char *suffix = (has_matching_input_iface) ?
"_out" :
"";
965 std::stringstream ss;
966 ss <<
"\n/* Compute Layout. */\n";
982std::string GLShader::workaround_geometry_shader_source_create(
985 std::stringstream ss;
1002 if (do_layer_output) {
1003 ss <<
"in int gpu_Layer[];\n";
1005 if (do_viewport_output) {
1006 ss <<
"in int gpu_ViewportIndex[];\n";
1009 if (do_barycentric_workaround) {
1010 ss <<
"flat out vec4 gpu_pos[3];\n";
1011 ss <<
"smooth out vec3 gpu_BaryCoord;\n";
1012 ss <<
"noperspective out vec3 gpu_BaryCoordNoPersp;\n";
1016 ss <<
"void main()\n";
1018 if (do_barycentric_workaround) {
1019 ss <<
" gpu_pos[0] = gl_in[0].gl_Position;\n";
1020 ss <<
" gpu_pos[1] = gl_in[1].gl_Position;\n";
1021 ss <<
" gpu_pos[2] = gl_in[2].gl_Position;\n";
1023 for (
auto i : IndexRange(3)) {
1030 if (do_barycentric_workaround) {
1031 ss <<
" gpu_BaryCoordNoPersp = gpu_BaryCoord =";
1032 ss <<
" vec3(" << int(
i == 0) <<
", " << int(
i == 1) <<
", " << int(
i == 2) <<
");\n";
1034 ss <<
" gl_Position = gl_in[" <<
i <<
"].gl_Position;\n";
1035 if (
bool(info.
builtins_ & BuiltinBits::CLIP_CONTROL)) {
1038 ss <<
"gl_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n";
1041 if (do_layer_output) {
1042 ss <<
" gl_Layer = gpu_Layer[" <<
i <<
"];\n";
1044 if (do_viewport_output) {
1045 ss <<
" gl_ViewportIndex = gpu_ViewportIndex[" <<
i <<
"];\n";
1047 ss <<
" EmitVertex();\n";
1077 static std::string patch = []() {
1078 std::stringstream ss;
1080 ss <<
"#version 430\n";
1085 ss <<
"#extension GL_ARB_shader_draw_parameters : enable\n";
1086 ss <<
"#define GPU_ARB_shader_draw_parameters\n";
1087 ss <<
"#define gpu_BaseInstance gl_BaseInstanceARB\n";
1090 ss <<
"#extension GL_ARB_shader_viewport_layer_array: enable\n";
1093 ss <<
"#extension GL_AMD_shader_explicit_vertex_parameter: enable\n";
1096 ss <<
"#define GPU_ARB_clip_control\n";
1101 ss <<
"uniform int gpu_BaseInstance;\n";
1105 ss <<
"#define gpu_InstanceIndex (gl_InstanceID + gpu_BaseInstance)\n";
1108 ss <<
"#define gpu_Array(_type) _type[]\n";
1111 ss <<
"#define GPU_VERTEX_SHADER\n";
1123 static std::string patch = []() {
1124 std::stringstream ss;
1126 ss <<
"#version 430\n";
1129 ss <<
"#extension GL_ARB_shader_viewport_layer_array: enable\n";
1132 ss <<
"#extension GL_AMD_shader_explicit_vertex_parameter: enable\n";
1135 ss <<
"#define GPU_ARB_clip_control\n";
1139 ss <<
"#define gpu_Array(_type) _type[]\n";
1142 ss <<
"#define GPU_GEOMETRY_SHADER\n";
1154 static std::string patch = []() {
1155 std::stringstream ss;
1157 ss <<
"#version 430\n";
1160 ss <<
"#extension GL_ARB_shader_viewport_layer_array: enable\n";
1163 ss <<
"#extension GL_AMD_shader_explicit_vertex_parameter: enable\n";
1166 ss <<
"#extension GL_EXT_shader_framebuffer_fetch: enable\n";
1169 ss <<
"#extension GL_ARB_shader_stencil_export: enable\n";
1170 ss <<
"#define GPU_ARB_shader_stencil_export\n";
1173 ss <<
"#define GPU_ARB_clip_control\n";
1177 ss <<
"#define gpu_Array(_type) _type[]\n";
1180 ss <<
"#define GPU_FRAGMENT_SHADER\n";
1192 static std::string patch = []() {
1193 std::stringstream ss;
1195 ss <<
"#version 430\n";
1198 ss <<
"#define gpu_Array(_type) _type[]\n";
1201 ss <<
"#define GPU_COMPUTE_SHADER\n";
1204 ss <<
"#define GPU_ARB_clip_control\n";
1214StringRefNull GLShader::glsl_patch_get(GLenum gl_stage)
1216 if (gl_stage == GL_VERTEX_SHADER) {
1219 if (gl_stage == GL_GEOMETRY_SHADER) {
1222 if (gl_stage == GL_FRAGMENT_SHADER) {
1225 if (gl_stage == GL_COMPUTE_SHADER) {
1232GLuint GLShader::create_shader_stage(GLenum gl_stage,
1233 MutableSpan<StringRefNull> sources,
1238 std::string constants_source;
1240 if (has_specialization_constants()) {
1244 sources = recreated_sources;
1252 if (async_compilation_) {
1260 StringRefNull source_type;
1262 case GL_VERTEX_SHADER:
1263 source_type =
"VertShader";
1265 case GL_GEOMETRY_SHADER:
1266 source_type =
"GeomShader";
1268 case GL_FRAGMENT_SHADER:
1269 source_type =
"FragShader";
1271 case GL_COMPUTE_SHADER:
1272 source_type =
"ComputeShader";
1276 debug_source +=
"\n\n----------" + source_type +
"----------\n\n";
1277 for (StringRefNull source : sources) {
1278 debug_source.append(source);
1282 if (async_compilation_) {
1287 GLuint shader = glCreateShader(gl_stage);
1289 fprintf(stderr,
"GLShader: Error: Could not create shader object.\n");
1293 Array<const char *, 16> c_str_sources(sources.size());
1294 for (
const int i : sources.index_range()) {
1295 c_str_sources[
i] = sources[
i].c_str();
1297 glShaderSource(shader, c_str_sources.size(), c_str_sources.data(),
nullptr);
1298 glCompileShader(shader);
1301 glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
1303 char log[5000] =
"";
1304 glGetShaderInfoLog(shader,
sizeof(
log),
nullptr,
log);
1305 if (
log[0] !=
'\0') {
1308 case GL_VERTEX_SHADER:
1309 this->
print_log(sources,
log,
"VertShader", !status, &parser);
1311 case GL_GEOMETRY_SHADER:
1312 this->
print_log(sources,
log,
"GeomShader", !status, &parser);
1314 case GL_FRAGMENT_SHADER:
1315 this->
print_log(sources,
log,
"FragShader", !status, &parser);
1317 case GL_COMPUTE_SHADER:
1318 this->
print_log(sources,
log,
"ComputeShader", !status, &parser);
1324 glDeleteShader(shader);
1325 compilation_failed_ =
true;
1333void GLShader::update_program_and_sources(
GLSources &stage_sources,
1334 MutableSpan<StringRefNull> sources)
1336 const bool store_sources = has_specialization_constants() || async_compilation_;
1337 if (store_sources && stage_sources.
is_empty()) {
1338 stage_sources = sources;
1344 update_program_and_sources(vertex_sources_, sources);
1345 main_program_->vert_shader = create_shader_stage(
1346 GL_VERTEX_SHADER, sources, vertex_sources_, *
constants);
1351 update_program_and_sources(geometry_sources_, sources);
1352 main_program_->geom_shader = create_shader_stage(
1353 GL_GEOMETRY_SHADER, sources, geometry_sources_, *
constants);
1358 update_program_and_sources(fragment_sources_, sources);
1359 main_program_->frag_shader = create_shader_stage(
1360 GL_FRAGMENT_SHADER, sources, fragment_sources_, *
constants);
1365 update_program_and_sources(compute_sources_, sources);
1366 main_program_->compute_shader = create_shader_stage(
1367 GL_COMPUTE_SHADER, sources, compute_sources_, *
constants);
1372 if (compilation_failed_) {
1376 if (info && do_geometry_shader_injection(info)) {
1377 std::string source = workaround_geometry_shader_source_create(*info);
1379 sources.
append(
"version");
1380 sources.
append(
"/* Specialization Constants. */\n");
1385 if (async_compilation_) {
1389 main_program_->program_link(
name);
1395 GLuint program_id = main_program_->program_id;
1397 glGetProgramiv(program_id, GL_LINK_STATUS, &status);
1400 glGetProgramInfoLog(program_id,
sizeof(
log),
nullptr,
log);
1402 print_log({debug_source},
log,
"Linking",
true, &parser);
1407 async_compilation_ =
false;
1409 if (info !=
nullptr) {
1427 GLProgram &program = program_get(constants_state);
1428 glUseProgram(program.program_id);
1448 glUniform1fv(location, array_size,
data);
1451 glUniform2fv(location, array_size,
data);
1454 glUniform3fv(location, array_size,
data);
1457 glUniform4fv(location, array_size,
data);
1460 glUniformMatrix3fv(location, array_size, 0,
data);
1463 glUniformMatrix4fv(location, array_size, 0,
data);
1475 glUniform1iv(location, array_size,
data);
1478 glUniform2iv(location, array_size,
data);
1481 glUniform3iv(location, array_size,
data);
1484 glUniform4iv(location, array_size,
data);
1517 if (other_source.is_empty()) {
1531 for (
const GLSource &source : *
this) {
1545 for (
const GLSource &source : *
this) {
1572GLShader::GLProgram::~GLProgram()
1575 glDeleteShader(vert_shader);
1576 glDeleteShader(geom_shader);
1577 glDeleteShader(frag_shader);
1578 glDeleteShader(compute_shader);
1579 glDeleteProgram(program_id);
1582void GLShader::GLProgram::program_link(
StringRefNull shader_name)
1584 if (this->program_id == 0) {
1585 this->program_id = glCreateProgram();
1589 GLuint program_id = this->program_id;
1591 if (this->vert_shader) {
1592 glAttachShader(program_id, this->vert_shader);
1594 if (this->geom_shader) {
1595 glAttachShader(program_id, this->geom_shader);
1597 if (this->frag_shader) {
1598 glAttachShader(program_id, this->frag_shader);
1600 if (this->compute_shader) {
1601 glAttachShader(program_id, this->compute_shader);
1603 glLinkProgram(program_id);
1606GLShader::GLProgram &GLShader::program_get(
const shader::SpecializationConstants *constants_state)
1608 BLI_assert(constants_state ==
nullptr || this->has_specialization_constants() ==
true);
1610 if (constants_state ==
nullptr) {
1613 return *main_program_;
1616 program_cache_mutex_.lock();
1618 GLProgram &program = *program_cache_.lookup_or_add_cb(
1619 constants_state->
values, []() { return std::make_unique<GLProgram>(); });
1621 program_cache_mutex_.unlock();
1624 std::scoped_lock
lock(program.compilation_mutex);
1626 if (program.program_id != 0) {
1631 if (!vertex_sources_.is_empty()) {
1632 program.vert_shader = create_shader_stage(
1633 GL_VERTEX_SHADER, {}, vertex_sources_, *constants_state);
1635 if (!geometry_sources_.is_empty()) {
1636 program.geom_shader = create_shader_stage(
1637 GL_GEOMETRY_SHADER, {}, geometry_sources_, *constants_state);
1639 if (!fragment_sources_.is_empty()) {
1640 program.frag_shader = create_shader_stage(
1641 GL_FRAGMENT_SHADER, {}, fragment_sources_, *constants_state);
1643 if (!compute_sources_.is_empty()) {
1644 program.compute_shader = create_shader_stage(
1645 GL_COMPUTE_SHADER, {}, compute_sources_, *constants_state);
1648 if (async_compilation_) {
1649 program.program_id = glCreateProgram();
1657 program.program_link(
name);
1663 glGetProgramiv(program.program_id, GL_LINK_STATUS, &status);
1675 result.comp = compute_sources_.to_string();
1676 result.vert = vertex_sources_.to_string();
1677 result.geom = geometry_sources_.to_string();
1678 result.frag = fragment_sources_.to_string();
1695#if BLI_SUBPROCESS_SUPPORT
1701GLCompilerWorker::GLCompilerWorker()
1703 static size_t pipe_id = 0;
1706 std::string
name =
"BLENDER_SHADER_COMPILER_" + std::to_string(getpid()) +
"_" +
1707 std::to_string(pipe_id);
1709 shared_mem_ = std::make_unique<SharedMemory>(
1710 name, compilation_subprocess_shared_memory_size,
true);
1711 start_semaphore_ = std::make_unique<SharedSemaphore>(
name +
"_START",
false);
1712 end_semaphore_ = std::make_unique<SharedSemaphore>(
name +
"_END",
false);
1713 close_semaphore_ = std::make_unique<SharedSemaphore>(
name +
"_CLOSE",
false);
1715 subprocess_.create({
"--compilation-subprocess",
name.c_str()});
1718GLCompilerWorker::~GLCompilerWorker()
1720 close_semaphore_->increment();
1722 start_semaphore_->increment();
1725void GLCompilerWorker::compile(
const GLSourcesBaked &sources)
1729 ShaderSourceHeader *shared_src =
reinterpret_cast<ShaderSourceHeader *
>(shared_mem_->get_data());
1730 char *next_src = shared_src->sources;
1732 auto add_src = [&](
const std::string &src) {
1734 const size_t src_size = src.size() + 1;
1735 memcpy(next_src, src.c_str(), src_size);
1736 next_src += src_size;
1740 add_src(sources.
comp);
1741 add_src(sources.
vert);
1742 add_src(sources.
geom);
1743 add_src(sources.
frag);
1745 BLI_assert(
size_t(next_src) <=
size_t(shared_src) + compilation_subprocess_shared_memory_size);
1747 if (!sources.
comp.empty()) {
1749 shared_src->type = ShaderSourceHeader::Type::COMPUTE;
1753 shared_src->type = sources.
geom.empty() ?
1754 ShaderSourceHeader::Type::GRAPHICS :
1755 ShaderSourceHeader::Type::GRAPHICS_WITH_GEOMETRY_STAGE;
1758 start_semaphore_->increment();
1760 state_ = COMPILATION_REQUESTED;
1764bool GLCompilerWorker::block_until_ready()
1766 BLI_assert(
ELEM(state_, COMPILATION_REQUESTED, COMPILATION_READY));
1767 if (state_ == COMPILATION_READY) {
1771 auto delete_cached_binary = [&]() {
1775 char str_start[] =
"SOURCE_HASH:";
1776 char *shared_mem =
reinterpret_cast<char *
>(shared_mem_->get_data());
1778 std::string path = GL_shader_cache_dir_get() +
SEP_STR +
1779 std::string(shared_mem +
sizeof(str_start) - 1);
1786 while (!end_semaphore_->try_decrement(1000)) {
1788 delete_cached_binary();
1793 state_ = COMPILATION_READY;
1797bool GLCompilerWorker::is_lost()
1800 float max_timeout_seconds = 30.0f;
1801 return !subprocess_.is_running() ||
1802 (state_ == COMPILATION_REQUESTED &&
1806bool GLCompilerWorker::load_program_binary(GLint program)
1808 if (!block_until_ready()) {
1812 ShaderBinaryHeader *binary = (ShaderBinaryHeader *)shared_mem_->get_data();
1814 state_ = COMPILATION_FINISHED;
1816 if (binary->size > 0) {
1818 glProgramBinary(program, binary->format, binary->data, binary->size);
1826void GLCompilerWorker::release()
1837GLSubprocessShaderCompiler::~GLSubprocessShaderCompiler()
1840 destruct_compilation_worker();
1842 for (GLCompilerWorker *worker : workers_) {
1847GLCompilerWorker *GLSubprocessShaderCompiler::get_compiler_worker()
1849 auto new_worker = [&]() {
1850 GLCompilerWorker *
result =
new GLCompilerWorker();
1851 std::lock_guard
lock(workers_mutex_);
1856 static thread_local GLCompilerWorker *worker = new_worker();
1858 if (worker->is_lost()) {
1859 std::cerr <<
"ERROR: Compilation subprocess lost\n";
1861 std::lock_guard
lock(workers_mutex_);
1862 workers_.remove_first_occurrence_and_reorder(worker);
1865 worker = new_worker();
1873 const_cast<ShaderCreateInfo *
>(&info)->
finalize();
1877 size_t required_size = sources.
size();
1878 bool do_async_compilation = required_size <=
sizeof(ShaderSourceHeader::sources);
1879 if (!do_async_compilation) {
1882 return compile(info,
false);
1885 GLCompilerWorker *worker = get_compiler_worker();
1886 worker->compile(sources);
1895 if (!worker->load_program_binary(shader->program_cache_.lookup(
constants.values)->program_id) ||
1908 return compile(info,
false);
1916 static std::mutex
mutex;
1920 auto program_get = [&]() -> GLShader::GLProgram * {
1921 if (shader->program_cache_.contains(specialization.
constants.
values)) {
1922 return shader->program_cache_.lookup(specialization.
constants.
values).get();
1927 auto program_release = [&]() {
1929 GLShader::GLProgram *program = program_get();
1930 glDeleteProgram(program->program_id);
1931 program->program_id = 0;
1934 GLSourcesBaked sources;
1938 if (program_get()) {
1944 shader->async_compilation_ =
true;
1945 shader->program_get(&specialization.
constants);
1946 shader->async_compilation_ =
false;
1949 size_t required_size = sources.
size();
1950 bool do_async_compilation = required_size <=
sizeof(ShaderSourceHeader::sources);
1951 if (!do_async_compilation) {
1959 GLCompilerWorker *worker = get_compiler_worker();
1960 worker->compile(sources);
1961 worker->block_until_ready();
1965 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