mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2025-10-29 05:40:12 -04:00
render/vulkan: add PQ inverse EOTF to output shader
This commit is contained in:
parent
f024d1b8c8
commit
8430a1922d
3 changed files with 26 additions and 4 deletions
|
|
@ -163,7 +163,8 @@ enum wlr_vk_shader_source {
|
|||
// fragment shader. Must match those in shaders/output.frag
|
||||
enum wlr_vk_output_transform {
|
||||
WLR_VK_OUTPUT_TRANSFORM_INVERSE_SRGB = 0,
|
||||
WLR_VK_OUTPUT_TRANSFORM_LUT3D = 1,
|
||||
WLR_VK_OUTPUT_TRANSFORM_INVERSE_ST2084_PQ = 1,
|
||||
WLR_VK_OUTPUT_TRANSFORM_LUT3D = 2,
|
||||
};
|
||||
|
||||
struct wlr_vk_pipeline_key {
|
||||
|
|
@ -193,6 +194,7 @@ struct wlr_vk_render_format_setup {
|
|||
VkRenderPass render_pass;
|
||||
|
||||
VkPipeline output_pipe_srgb;
|
||||
VkPipeline output_pipe_pq;
|
||||
VkPipeline output_pipe_lut3d;
|
||||
|
||||
struct wlr_vk_renderer *renderer;
|
||||
|
|
|
|||
|
|
@ -159,6 +159,7 @@ static void destroy_render_format_setup(struct wlr_vk_renderer *renderer,
|
|||
VkDevice dev = renderer->dev->dev;
|
||||
vkDestroyRenderPass(dev, setup->render_pass, NULL);
|
||||
vkDestroyPipeline(dev, setup->output_pipe_srgb, NULL);
|
||||
vkDestroyPipeline(dev, setup->output_pipe_pq, NULL);
|
||||
vkDestroyPipeline(dev, setup->output_pipe_lut3d, NULL);
|
||||
|
||||
struct wlr_vk_pipeline *pipeline, *tmp_pipeline;
|
||||
|
|
@ -2299,8 +2300,13 @@ static struct wlr_vk_render_format_setup *find_or_create_render_setup(
|
|||
goto error;
|
||||
}
|
||||
if (!init_blend_to_output_pipeline(
|
||||
renderer, setup->render_pass, renderer->output_pipe_layout,
|
||||
&setup->output_pipe_srgb, WLR_VK_OUTPUT_TRANSFORM_INVERSE_SRGB)) {
|
||||
renderer, setup->render_pass, renderer->output_pipe_layout,
|
||||
&setup->output_pipe_srgb, WLR_VK_OUTPUT_TRANSFORM_INVERSE_SRGB)) {
|
||||
goto error;
|
||||
}
|
||||
if (!init_blend_to_output_pipeline(
|
||||
renderer, setup->render_pass, renderer->output_pipe_layout,
|
||||
&setup->output_pipe_pq, WLR_VK_OUTPUT_TRANSFORM_INVERSE_ST2084_PQ)) {
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -18,7 +18,8 @@ layout (constant_id = 0) const int OUTPUT_TRANSFORM = 0;
|
|||
|
||||
// Matches enum wlr_vk_output_transform
|
||||
#define OUTPUT_TRANSFORM_INVERSE_SRGB 0
|
||||
#define OUTPUT_TRANSFORM_LUT_3D 1
|
||||
#define OUTPUT_TRANSFORM_INVERSE_ST2084_PQ 1
|
||||
#define OUTPUT_TRANSFORM_LUT_3D 2
|
||||
|
||||
float linear_channel_to_srgb(float x) {
|
||||
return max(min(x * 12.92, 0.04045), 1.055 * pow(x, 1. / 2.4) - 0.055);
|
||||
|
|
@ -32,6 +33,17 @@ vec3 linear_color_to_srgb(vec3 color) {
|
|||
);
|
||||
}
|
||||
|
||||
vec3 linear_color_to_pq(vec3 color) {
|
||||
// H.273 TransferCharacteristics code point 16
|
||||
float c1 = 0.8359375;
|
||||
float c2 = 18.8515625;
|
||||
float c3 = 18.6875;
|
||||
float m = 78.84375;
|
||||
float n = 0.1593017578125;
|
||||
vec3 pow_n = pow(clamp(color, vec3(0), vec3(1)), vec3(n));
|
||||
return pow((vec3(c1) + c2 * pow_n) / (vec3(1) + c3 * pow_n), vec3(m));
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec4 in_color = subpassLoad(in_color).rgba;
|
||||
|
||||
|
|
@ -50,6 +62,8 @@ void main() {
|
|||
// Apply 3D LUT
|
||||
vec3 pos = data.lut_3d_offset + rgb * data.lut_3d_scale;
|
||||
rgb = texture(lut_3d, pos).rgb;
|
||||
} else if (OUTPUT_TRANSFORM == OUTPUT_TRANSFORM_INVERSE_ST2084_PQ) {
|
||||
rgb = linear_color_to_pq(rgb);
|
||||
} else { // OUTPUT_TRANSFORM_INVERSE_SRGB
|
||||
// Produce sRGB encoded values
|
||||
rgb = linear_color_to_srgb(rgb);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue