diff --git a/backend/drm/atomic.c b/backend/drm/atomic.c index a952dc426..66569232b 100644 --- a/backend/drm/atomic.c +++ b/backend/drm/atomic.c @@ -184,6 +184,8 @@ static uint8_t convert_cta861_eotf(enum wlr_color_transfer_function tf) { abort(); // unsupported case WLR_COLOR_TRANSFER_FUNCTION_ST2084_PQ: return 2; + case WLR_COLOR_TRANSFER_FUNCTION_EXT_LINEAR: + abort(); // unsupported } abort(); // unreachable } diff --git a/include/render/vulkan.h b/include/render/vulkan.h index b6bd0c2e8..1d4b8a0ba 100644 --- a/include/render/vulkan.h +++ b/include/render/vulkan.h @@ -162,9 +162,10 @@ enum wlr_vk_shader_source { // Constants used to pick the color transform for the blend-to-output // 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_INVERSE_ST2084_PQ = 1, - WLR_VK_OUTPUT_TRANSFORM_LUT3D = 2, + WLR_VK_OUTPUT_TRANSFORM_IDENTITY = 0, + WLR_VK_OUTPUT_TRANSFORM_INVERSE_SRGB = 1, + WLR_VK_OUTPUT_TRANSFORM_INVERSE_ST2084_PQ = 2, + WLR_VK_OUTPUT_TRANSFORM_LUT3D = 3, }; struct wlr_vk_pipeline_key { @@ -193,6 +194,7 @@ struct wlr_vk_render_format_setup { bool use_blending_buffer; VkRenderPass render_pass; + VkPipeline output_pipe_identity; VkPipeline output_pipe_srgb; VkPipeline output_pipe_pq; VkPipeline output_pipe_lut3d; diff --git a/include/wlr/render/color.h b/include/wlr/render/color.h index 42ce5bc30..3341668a8 100644 --- a/include/wlr/render/color.h +++ b/include/wlr/render/color.h @@ -27,6 +27,7 @@ enum wlr_color_named_primaries { enum wlr_color_transfer_function { WLR_COLOR_TRANSFER_FUNCTION_SRGB = 1 << 0, WLR_COLOR_TRANSFER_FUNCTION_ST2084_PQ = 1 << 1, + WLR_COLOR_TRANSFER_FUNCTION_EXT_LINEAR = 1 << 2, }; /** diff --git a/render/vulkan/pass.c b/render/vulkan/pass.c index 290d8e2ca..75c454c87 100644 --- a/render/vulkan/pass.c +++ b/render/vulkan/pass.c @@ -237,6 +237,9 @@ static bool render_pass_submit(struct wlr_render_pass *wlr_pass) { } switch (tf) { + case WLR_COLOR_TRANSFER_FUNCTION_EXT_LINEAR: + pipeline = render_buffer->plain.render_setup->output_pipe_identity; + break; case WLR_COLOR_TRANSFER_FUNCTION_SRGB: pipeline = render_buffer->plain.render_setup->output_pipe_srgb; break; diff --git a/render/vulkan/renderer.c b/render/vulkan/renderer.c index 98701626f..cbfb022f7 100644 --- a/render/vulkan/renderer.c +++ b/render/vulkan/renderer.c @@ -158,6 +158,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_identity, NULL); vkDestroyPipeline(dev, setup->output_pipe_srgb, NULL); vkDestroyPipeline(dev, setup->output_pipe_pq, NULL); vkDestroyPipeline(dev, setup->output_pipe_lut3d, NULL); @@ -2294,6 +2295,11 @@ static struct wlr_vk_render_format_setup *find_or_create_render_setup( } // this is only well defined if render pass has a 2nd subpass + if (!init_blend_to_output_pipeline( + renderer, setup->render_pass, renderer->output_pipe_layout, + &setup->output_pipe_identity, WLR_VK_OUTPUT_TRANSFORM_IDENTITY)) { + goto error; + } if (!init_blend_to_output_pipeline( renderer, setup->render_pass, renderer->output_pipe_layout, &setup->output_pipe_lut3d, WLR_VK_OUTPUT_TRANSFORM_LUT3D)) { diff --git a/render/vulkan/shaders/output.frag b/render/vulkan/shaders/output.frag index f2d5d645c..3d5ac4089 100644 --- a/render/vulkan/shaders/output.frag +++ b/render/vulkan/shaders/output.frag @@ -18,9 +18,10 @@ layout(push_constant, row_major) uniform UBO { layout (constant_id = 0) const int OUTPUT_TRANSFORM = 0; // Matches enum wlr_vk_output_transform -#define OUTPUT_TRANSFORM_INVERSE_SRGB 0 -#define OUTPUT_TRANSFORM_INVERSE_ST2084_PQ 1 -#define OUTPUT_TRANSFORM_LUT_3D 2 +#define OUTPUT_TRANSFORM_IDENTITY 0 +#define OUTPUT_TRANSFORM_INVERSE_SRGB 1 +#define OUTPUT_TRANSFORM_INVERSE_ST2084_PQ 2 +#define OUTPUT_TRANSFORM_LUT_3D 3 float linear_channel_to_srgb(float x) { return max(min(x * 12.92, 0.04045), 1.055 * pow(x, 1. / 2.4) - 0.055); @@ -67,7 +68,7 @@ void main() { 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 + } else if (OUTPUT_TRANSFORM == OUTPUT_TRANSFORM_INVERSE_SRGB) { // Produce sRGB encoded values rgb = linear_color_to_srgb(rgb); }