MythTV  master
mythopenglcomputeshaders.h
Go to the documentation of this file.
1 #ifndef MYTHOPENGLCOMPUTESHADERS_H
2 #define MYTHOPENGLCOMPUTESHADERS_H
3 
4 #include <QString>
5 
6 // This is a work in progress
7 // - assumes either NV12 or YV12
8 // - will probably break for rectangular and OES textures?
9 // - assumes HLG to Rec.709
10 // - various other hardcoded assumptions/settings
11 
12 static const QString GLSL430Tonemap =
13 "#extension GL_ARB_compute_shader : enable\n"
14 "#extension GL_ARB_shader_storage_buffer_object : enable\n"
15 "#extension GL_ARB_shader_image_load_store : enable\n"
16 "layout(std430, binding=0) buffer FrameGlobals {\n"
17 " highp vec2 m_running;\n"
18 " uint m_frameMean;\n"
19 " uint m_frameMax;\n"
20 " uint m_wgCounter;\n"
21 "};\n"
22 "layout(rgba16f) uniform highp writeonly image2D m_texture;\n"
23 "#ifdef UNSIGNED\n"
24 "#define sampler2D usampler2D\n"
25 "#endif\n"
26 "uniform highp sampler2D texture0;\n"
27 "uniform highp sampler2D texture1;\n"
28 "#ifdef YV12\n"
29 "uniform highp sampler2D texture2;\n"
30 "#endif\n"
31 "uniform highp mat4 m_colourMatrix;\n"
32 "uniform highp mat4 m_primaryMatrix;\n"
33 "layout(local_size_x = 8, local_size_y = 8) in;\n"
34 "shared uint m_workGroupMean;\n"
35 "shared uint m_workGroupMax;\n"
36 "vec3 hable(vec3 H) {\n"
37 " return (H * (0.150000 * H + vec3(0.050000)) + vec3(0.004000)) / \n"
38 " (H * (0.150000 * H + vec3(0.500000)) + vec3(0.060000)) - vec3(0.066667);\n"
39 "}\n"
40 "void main() {\n"
41 " uint numWorkGroups = gl_NumWorkGroups.x * gl_NumWorkGroups.y;\n"
42 " highp vec2 coord = (vec2(gl_GlobalInvocationID) + vec2(0.5, 0.5)) / vec2(gl_NumWorkGroups * gl_WorkGroupSize);\n"
43 " highp vec4 pixel = vec4(texture(texture0, coord).r,\n"
44 "#ifdef YV12\n"
45 " texture(texture1, coord).r,\n"
46 " texture(texture2, coord).r,\n"
47 "#else\n"
48 " texture(texture1, coord).rg,\n"
49 "#endif\n"
50 " 1.0);\n"
51 "#ifdef UNSIGNED\n"
52 " pixel /= vec4(65535.0, 65535.0, 65535.0, 1.0);\n"
53 "#endif\n"
54 " pixel *= m_colourMatrix;\n"
55 " pixel = clamp(pixel, 0.0, 1.0);\n"
56 " pixel.rgb = mix(vec3(4.0) * pixel.rgb * pixel.rgb,\n"
57 " exp((pixel.rgb - vec3(0.559911)) * vec3(1.0/0.178833)) +\n"
58 " vec3(0.284669), lessThan(vec3(0.5), pixel.rgb));\n"
59 " pixel.rgb *= vec3(0.506970 * pow(dot(vec3(0.2627, 0.6780, 0.0593), pixel.rgb), 0.200000));\n"
60 
61 " int channel = 0;\n"
62 " if (pixel.g > pixel.r) channel = 1;\n"
63 " if (pixel.b > pixel[channel]) channel = 2;\n"
64 " float channelmax = pixel[channel];\n"
65 " highp float mean = 0.25;\n"
66 " highp float peak = 10.0;\n"
67 " if (m_running.y > 0.0) {\n"
68 " mean = max(0.001, m_running.x);\n"
69 " peak = max(1.000, m_running.y);\n"
70 " }\n"
71 
72 " m_workGroupMean = 0;\n"
73 " m_workGroupMax = 0;\n"
74 " barrier();\n"
75 " atomicAdd(m_workGroupMean, uint(log(max(channelmax, 0.001)) * 400.0));\n"
76 " atomicMax(m_workGroupMax, uint(channelmax * 10000.0));\n"
77 " memoryBarrierShared();\n"
78 " barrier();\n"
79 
80 " if (gl_LocalInvocationIndex == 0) {\n"
81 " atomicAdd(m_frameMean, uint(m_workGroupMean / uint(gl_WorkGroupSize.x * gl_WorkGroupSize.y)));\n"
82 " atomicMax(m_frameMax, m_workGroupMax);\n"
83 " memoryBarrierBuffer();\n"
84 " }\n"
85 " barrier();\n"
86 
87 " if (gl_LocalInvocationIndex == 0 && atomicAdd(m_wgCounter, 1) == (numWorkGroups - 1)) {\n"
88 " highp vec2 current = vec2(exp(float(m_frameMean) / (float(numWorkGroups) * 400.0)),\n"
89 " float(m_frameMax) / 10000.0);\n"
90 " if (m_running.y == 0.0) m_running = current;\n"
91 " m_running += 0.05 * (current - m_running);\n"
92 " float weight = smoothstep(1.266422, 2.302585, abs(log(current.x / m_running.x)));\n"
93 " m_running = mix(m_running, current, weight);\n"
94 " m_wgCounter = 0;\n"
95 " m_frameMean = 0;\n"
96 " m_frameMax = 0;\n"
97 " memoryBarrierBuffer();\n"
98 " }\n"
99 
100 " vec3 colour = pixel.rgb;\n"
101 " float slope = min(1.000000, 0.25 / mean);\n"
102 " colour *= slope;\n"
103 " peak *= slope;\n"
104 " colour = hable(max(vec3(0.0), colour)) / hable(vec3(peak)).x;\n"
105 " colour = min(colour, vec3(1.0));\n"
106 " vec3 linear = pixel.rgb * (colour[channel] / channelmax);\n"
107 " float coeff = max(colour[channel] - 0.180000, 1e-6) / max(colour[channel], 1.0);\n"
108 " coeff = 0.750000 * pow(coeff, 1.500000);\n"
109 " pixel.rgb = mix(linear, colour, coeff);\n"
110 
111 // BT2020 to Rec709
112 " pixel = m_primaryMatrix * clamp(pixel, 0.0, 1.0);\n"
113 " imageStore(m_texture, ivec2(gl_GlobalInvocationID), vec4(pow(pixel.rgb, vec3(1.0 / 2.2)), 1.0));\n"
114 "}\n";
115 
116 #endif // MYTHOPENGLCOMPUTESHADERS_H
GLSL430Tonemap
static const QString GLSL430Tonemap
Definition: mythopenglcomputeshaders.h:12