Blender V5.0
fallback_gpu_shader_binder.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2025 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
6
7#include <string>
8
10
11namespace blender::ocio {
12
13namespace {
14
15static std::string generate_display_fragment_source(
16 const internal::GPUDisplayShader &display_shader)
17{
18 std::string source;
19
20 /* Generate OCIO_to_scene_linear(). */
21 if (display_shader.from_colorspace == "sRGB") {
22 /* Use Blender's default sRGB->Linear conversion.
23 * Expect that the alpha association is handled in the caller. */
24 source +=
25 "vec4 OCIO_to_scene_linear(vec4 pixel) {\n"
26 " return vec4(srgb_to_linear_rgb(pixel.rgb), pixel.a);\n"
27 "}\n";
28 }
29 else {
30 /* Linear or Non-Color: no need to perform any conversion. */
31 source += "vec4 OCIO_to_scene_linear(vec4 pixel) { return pixel; }\n";
32 }
33
34 /* Generate OCIO_to_display(). */
35 if (display_shader.display == "sRGB") {
36 source +=
37 "vec4 OCIO_to_display(vec4 pixel) {\n"
38 " return vec4(linear_rgb_to_srgb(pixel.rgb), pixel.a);\n"
39 "}\n";
40 }
41 else {
42 /* Linear or Non-Color: no need to perform any conversion. */
43 source += "vec4 OCIO_to_display(vec4 pixel) { return pixel; }\n";
44 }
45
46 return source;
47}
48
49static std::string generate_scene_linear_fragment_source(
50 const internal::GPUDisplayShader &display_shader)
51{
52 std::string source;
53
54 /* Generate OCIO_to_scene_linear(). */
55 if (display_shader.from_colorspace == "sRGB") {
56 /* Use Blender's default sRGB->Linear conversion.
57 * Expect that the alpha association is handled in the caller. */
58 source +=
59 "vec4 OCIO_to_scene_linear(vec4 pixel) {\n"
60 " return vec4(srgb_to_linear_rgb(pixel.rgb), pixel.a);\n"
61 "}\n";
62 }
63 else {
64 /* Linear or Non-Color: no need to perform any conversion. */
65 source += "vec4 OCIO_to_scene_linear(vec4 pixel) { return pixel; }\n";
66 }
67
68 /* Generate OCIO_to_display(). */
69 source += "vec4 OCIO_to_display(vec4 pixel) { return pixel; }\n";
70
71 return source;
72}
73
74} // namespace
75
77 internal::GPUDisplayShader &display_shader) const
78{
79 const std::string fragment_source = generate_display_fragment_source(display_shader);
80
81 if (!create_gpu_shader(display_shader, fragment_source, {})) {
82 display_shader.is_valid = false;
83 return;
84 }
85
86 display_shader.is_valid = true;
87}
88
90 internal::GPUDisplayShader &display_shader) const
91{
92 display_shader.is_valid = true;
93
94 const std::string fragment_source = generate_scene_linear_fragment_source(display_shader);
95
96 if (!create_gpu_shader(display_shader,
97 fragment_source,
98 {{"USE_TO_SCENE_LINEAR_ONLY", ""}, {"OUTPUT_PREMULTIPLIED", ""}}))
99 {
100 display_shader.is_valid = false;
101 }
102}
103
104} // namespace blender::ocio
void construct_scene_linear_shader(internal::GPUDisplayShader &display_shader) const override
void construct_display_shader(internal::GPUDisplayShader &display_shader) const override
static bool create_gpu_shader(internal::GPUDisplayShader &display_shader, StringRefNull fragment_source, Span< std::array< StringRefNull, 2 > > additional_defines)