render, render/vulkan: add primaries to wlr_buffer_pass_options

This commit is contained in:
Simon Ser 2025-06-18 00:07:35 +02:00
parent a5706e2fb9
commit f3524de980
3 changed files with 39 additions and 5 deletions

View file

@ -7,6 +7,7 @@
#include <vulkan/vulkan.h>
#include <wlr/render/wlr_renderer.h>
#include <wlr/render/wlr_texture.h>
#include <wlr/render/color.h>
#include <wlr/render/drm_format_set.h>
#include <wlr/render/interface.h>
#include <wlr/util/addon.h>
@ -390,6 +391,9 @@ struct wlr_vk_render_pass {
bool srgb_pathway; // if false, rendering via intermediate blending buffer
struct wlr_color_transform *color_transform;
bool has_primaries;
struct wlr_color_primaries primaries;
struct wlr_drm_syncobj_timeline *signal_timeline;
uint64_t signal_point;

View file

@ -33,6 +33,8 @@ struct wlr_buffer_pass_options {
/* Color transform to apply to the output of the render pass,
* leave NULL to indicate sRGB/no custom transform */
struct wlr_color_transform *color_transform;
/** Primaries describing the color volume of the destination buffer */
const struct wlr_color_primaries *primaries;
/* Signal a timeline synchronization point when the render pass completes.
*

View file

@ -78,6 +78,17 @@ static void encode_proj_matrix(const float mat3[9], float mat4[4][4]) {
memcpy(mat4, result, sizeof(result));
}
static void encode_color_matrix(const float mat3[9], float mat4[4][4]) {
float result[4][4] = {
{ mat3[0], mat3[1], mat3[2], 0 },
{ mat3[3], mat3[4], mat3[5], 0 },
{ mat3[6], mat3[7], mat3[8], 0 },
{ 0, 0, 0, 0 },
};
memcpy(mat4, result, sizeof(result));
}
static void render_pass_destroy(struct wlr_vk_render_pass *pass) {
struct wlr_vk_render_pass_texture *pass_texture;
wl_array_for_each(pass_texture, &pass->textures) {
@ -186,15 +197,28 @@ static bool render_pass_submit(struct wlr_render_pass *wlr_pass) {
}
struct wlr_vk_frag_output_pcr_data frag_pcr_data = {
.matrix = {
{1, 0, 0},
{0, 1, 0},
{0, 0, 1},
},
.lut_3d_offset = 0.5f / dim,
.lut_3d_scale = (float)(dim - 1) / dim,
};
float matrix[9];
if (pass->has_primaries) {
struct wlr_color_primaries srgb;
wlr_color_primaries_from_named(&srgb, WLR_COLOR_NAMED_PRIMARIES_SRGB);
float srgb_to_xyz[9];
wlr_color_primaries_to_xyz(&srgb, srgb_to_xyz);
float dst_primaries_to_xyz[9];
wlr_color_primaries_to_xyz(&pass->primaries, dst_primaries_to_xyz);
float xyz_to_dst_primaries[9];
matrix_invert(xyz_to_dst_primaries, dst_primaries_to_xyz);
wlr_matrix_multiply(matrix, srgb_to_xyz, xyz_to_dst_primaries);
} else {
wlr_matrix_identity(matrix);
}
encode_color_matrix(matrix, frag_pcr_data.matrix);
if (pass->color_transform && pass->color_transform->type != COLOR_TRANSFORM_SRGB) {
bind_pipeline(pass, render_buffer->plain.render_setup->output_pipe_lut3d);
} else {
@ -1106,6 +1130,10 @@ struct wlr_vk_render_pass *vulkan_begin_render_pass(struct wlr_vk_renderer *rend
pass->signal_timeline = wlr_drm_syncobj_timeline_ref(options->signal_timeline);
pass->signal_point = options->signal_point;
}
if (options != NULL && options->primaries != NULL) {
pass->has_primaries = true;
pass->primaries = *options->primaries;
}
rect_union_init(&pass->updated_region);