amd/vpelib: Move bg color
Refactor bg gen as it check_bg_support simply calls into other version specific function. Move that function directly into check_bg_support call, and refactor unnecessary functions + format fix. Co-authored-by: Brendan <breleder@amd.com> Reviewed-by: Krunoslav Kovac <Krunoslav.Kovac@amd.com> Reviewed-by: Jesse Agate <Jesse.Agate@amd.com> Reviewed-by: Navid Assadian <Navid.Assadian@amd.com> Acked-by: Chenyu Chen <Chen-Yu.Chen@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/32646>
This commit is contained in:
committed by
Marge Bot
parent
3943ed8199
commit
4ef45d8d4e
@@ -496,11 +496,6 @@ bool vpe10_check_h_mirror_support(bool *input_mirror, bool *output_mirror)
|
||||
return true;
|
||||
}
|
||||
|
||||
enum vpe_status vpe10_check_bg_color_support(struct vpe_priv* vpe_priv, struct vpe_color* bg_color)
|
||||
{
|
||||
return vpe_is_valid_bg_color(vpe_priv, bg_color);
|
||||
}
|
||||
|
||||
void vpe10_calculate_dst_viewport_and_active(
|
||||
struct segment_ctx *segment_ctx, uint32_t max_seg_width)
|
||||
{
|
||||
@@ -917,14 +912,14 @@ int32_t vpe10_program_backend(
|
||||
if (vpe_is_fp16(surface_info->format)) {
|
||||
if (vpe_priv->output_ctx.alpha_mode == VPE_ALPHA_BGCOLOR)
|
||||
vpe_convert_from_float_to_fp16(
|
||||
(double)vpe_priv->output_ctx.bg_color.rgba.a, &alpha_16);
|
||||
(double)vpe_priv->output_ctx.mpc_bg_color.rgba.a, &alpha_16);
|
||||
else
|
||||
vpe_convert_from_float_to_fp16(1.0, &alpha_16);
|
||||
|
||||
opp_dig_bypass = true;
|
||||
} else {
|
||||
if (vpe_priv->output_ctx.alpha_mode == VPE_ALPHA_BGCOLOR)
|
||||
alpha_16 = (uint16_t)(vpe_priv->output_ctx.bg_color.rgba.a * 0xffff);
|
||||
alpha_16 = (uint16_t)(vpe_priv->output_ctx.mpc_bg_color.rgba.a * 0xffff);
|
||||
else
|
||||
alpha_16 = 0xffff;
|
||||
}
|
||||
@@ -1042,7 +1037,7 @@ void vpe10_create_stream_ops_config(struct vpe_priv *vpe_priv, uint32_t pipe_idx
|
||||
vpe_priv->output_ctx.output_tf, vpe_priv->output_ctx.surface.format,
|
||||
false); // 3DLUT should only affect input visual confirm
|
||||
} else {
|
||||
blndcfg.bg_color = vpe_priv->output_ctx.bg_color;
|
||||
blndcfg.bg_color = vpe_priv->output_ctx.mpc_bg_color;
|
||||
}
|
||||
blndcfg.global_gain = 0xff;
|
||||
blndcfg.pre_multiplied_alpha = false;
|
||||
@@ -1265,3 +1260,65 @@ enum vpe_status vpe10_update_blnd_gamma(struct vpe_priv *vpe_priv,
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
static enum vpe_status bg_color_outside_cs_gamut(
|
||||
const struct vpe_priv *vpe_priv, struct vpe_color *bg_color)
|
||||
{
|
||||
enum color_space cs;
|
||||
enum color_transfer_func tf;
|
||||
struct vpe_color bg_color_copy = *bg_color;
|
||||
const struct vpe_color_space *vcs = &vpe_priv->output_ctx.surface.cs;
|
||||
|
||||
vpe_color_get_color_space_and_tf(vcs, &cs, &tf);
|
||||
|
||||
if ((bg_color->is_ycbcr)) {
|
||||
// using the bg_color_copy instead as bg_csc will modify it
|
||||
// we should not do modification in checking stage
|
||||
// otherwise validate_cached_param() will fail
|
||||
if (vpe_bg_csc(&bg_color_copy, cs)) {
|
||||
return VPE_STATUS_BG_COLOR_OUT_OF_RANGE;
|
||||
}
|
||||
}
|
||||
return VPE_STATUS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
In order to support background color fill correctly, we need to do studio -> full range
|
||||
conversion before the blend block. However, there is also a requirement for HDR output to be
|
||||
blended in linear space. Hence, if we have PQ out and studio range, we need to make sure no
|
||||
blending will occur. Otherwise the job is invalid.
|
||||
|
||||
*/
|
||||
static enum vpe_status is_valid_blend(const struct vpe_priv *vpe_priv, struct vpe_color *bg_color)
|
||||
{
|
||||
|
||||
enum vpe_status status = VPE_STATUS_OK;
|
||||
const struct vpe_color_space *vcs = &vpe_priv->output_ctx.surface.cs;
|
||||
struct stream_ctx *stream_ctx = vpe_priv->stream_ctx; // Only need to check the first stream.
|
||||
|
||||
if ((vcs->range == VPE_COLOR_RANGE_STUDIO) && (vcs->tf == VPE_TF_PQ) &&
|
||||
((stream_ctx->stream.surface_info.cs.encoding == VPE_PIXEL_ENCODING_RGB) ||
|
||||
vpe_is_global_bg_blend_applied(stream_ctx)))
|
||||
status = VPE_STATUS_BG_COLOR_OUT_OF_RANGE;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
enum vpe_status vpe10_check_bg_color_support(struct vpe_priv *vpe_priv, struct vpe_color *bg_color)
|
||||
{
|
||||
|
||||
enum vpe_status status = VPE_STATUS_OK;
|
||||
|
||||
/* no need for background filling as for target rect equal to dest rect */
|
||||
if (vpe_rec_is_equal(vpe_priv->output_ctx.target_rect,
|
||||
vpe_priv->stream_ctx[0].stream.scaling_info.dst_rect)) {
|
||||
return VPE_STATUS_OK;
|
||||
}
|
||||
|
||||
status = is_valid_blend(vpe_priv, bg_color);
|
||||
|
||||
if (status == VPE_STATUS_OK)
|
||||
status = bg_color_outside_cs_gamut(vpe_priv, bg_color);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -208,7 +208,7 @@ static void set_gamut_remap_matrix(double* res, enum color_space src_cs, enum co
|
||||
|
||||
}
|
||||
|
||||
static bool bg_csc(struct vpe_color *bg_color, enum color_space cs)
|
||||
bool vpe_bg_csc(struct vpe_color *bg_color, enum color_space cs)
|
||||
{
|
||||
struct csc_table *entry = &bgcolor_to_rgbfull_table[cs];
|
||||
float csc_final[3] = {0};
|
||||
@@ -250,35 +250,14 @@ static bool bg_csc(struct vpe_color *bg_color, enum color_space cs)
|
||||
return output_is_clipped;
|
||||
}
|
||||
|
||||
static inline bool is_global_bg_blend_applied(struct stream_ctx *stream_ctx) {
|
||||
bool vpe_is_global_bg_blend_applied(struct stream_ctx *stream_ctx)
|
||||
{
|
||||
|
||||
return (stream_ctx->stream.blend_info.blending) &&
|
||||
(stream_ctx->stream.blend_info.global_alpha) &&
|
||||
(stream_ctx->stream.blend_info.global_alpha_value != 1.0);
|
||||
}
|
||||
|
||||
/*
|
||||
In order to support background color fill correctly, we need to do studio -> full range conversion
|
||||
before the blend block. However, there is also a requirement for HDR output to be blended in linear space.
|
||||
Hence, if we have PQ out and studio range, we need to make sure no blenidng will occur. Othewise the job
|
||||
is invalid.
|
||||
|
||||
*/
|
||||
static enum vpe_status is_valid_blend(const struct vpe_priv *vpe_priv, struct vpe_color *bg_color) {
|
||||
|
||||
enum vpe_status status = VPE_STATUS_OK;
|
||||
const struct vpe_color_space *vcs = &vpe_priv->output_ctx.surface.cs;
|
||||
struct stream_ctx *stream_ctx = vpe_priv->stream_ctx; //Only need to check the first stream.
|
||||
|
||||
if ((vcs->range == VPE_COLOR_RANGE_STUDIO) &&
|
||||
(vcs->tf == VPE_TF_PQ) &&
|
||||
((stream_ctx->stream.surface_info.cs.encoding == VPE_PIXEL_ENCODING_RGB) ||
|
||||
is_global_bg_blend_applied(stream_ctx)))
|
||||
status = VPE_STATUS_BG_COLOR_OUT_OF_RANGE;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
struct gamma_coefs {
|
||||
float a0;
|
||||
float a1;
|
||||
@@ -502,65 +481,17 @@ static void vpe_bg_inverse_gamut_remap(enum color_space output_cs,
|
||||
|
||||
// To understand the logic for background color conversion,
|
||||
// please refer to vpe_update_output_gamma_sequence in color.c
|
||||
void vpe_bg_color_convert(
|
||||
enum color_space output_cs, struct transfer_func *output_tf, enum vpe_surface_pixel_format pixel_format, struct vpe_color *bg_color, bool enable_3dlut)
|
||||
void vpe_bg_color_convert(enum color_space output_cs, struct transfer_func *output_tf,
|
||||
enum vpe_surface_pixel_format pixel_format, struct vpe_color *mpc_bg_color,
|
||||
struct vpe_color *opp_bg_color, bool enable_3dlut)
|
||||
{
|
||||
if (output_tf->type != TF_TYPE_BYPASS) {
|
||||
// inverse degam
|
||||
if (output_tf->tf == TRANSFER_FUNC_PQ2084 && !is_limited_cs(output_cs))
|
||||
vpe_bg_degam(output_tf, bg_color);
|
||||
vpe_bg_degam(output_tf, mpc_bg_color);
|
||||
// inverse gamut remap
|
||||
if (enable_3dlut)
|
||||
vpe_bg_inverse_gamut_remap(output_cs, output_tf, bg_color);
|
||||
vpe_bg_inverse_gamut_remap(output_cs, output_tf, mpc_bg_color);
|
||||
}
|
||||
// for TF_TYPE_BYPASS, bg color should be programmed to mpc as linear
|
||||
}
|
||||
|
||||
enum vpe_status vpe_bg_color_outside_cs_gamut(
|
||||
const struct vpe_priv *vpe_priv, struct vpe_color *bg_color)
|
||||
{
|
||||
enum color_space cs;
|
||||
enum color_transfer_func tf;
|
||||
struct vpe_color bg_color_copy = *bg_color;
|
||||
const struct vpe_color_space *vcs = &vpe_priv->output_ctx.surface.cs;
|
||||
|
||||
vpe_color_get_color_space_and_tf(vcs, &cs, &tf);
|
||||
|
||||
if ((bg_color->is_ycbcr)) {
|
||||
// using the bg_color_copy instead as bg_csc will modify it
|
||||
// we should not do modification in checking stage
|
||||
// otherwise validate_cached_param() will fail
|
||||
if (bg_csc(&bg_color_copy, cs)) {
|
||||
return VPE_STATUS_BG_COLOR_OUT_OF_RANGE;
|
||||
}
|
||||
}
|
||||
return VPE_STATUS_OK;
|
||||
}
|
||||
|
||||
static inline bool is_target_rect_equal_to_dest_rect(const struct vpe_priv *vpe_priv)
|
||||
{
|
||||
const struct vpe_rect *target_rect = &vpe_priv->output_ctx.target_rect;
|
||||
const struct vpe_rect *dst_rect = &vpe_priv->stream_ctx[0].stream.scaling_info.dst_rect;
|
||||
|
||||
return (target_rect->height == dst_rect ->height) && (target_rect->width == dst_rect ->width) &&
|
||||
(target_rect->x == dst_rect ->x) && (target_rect->y == dst_rect ->y);
|
||||
}
|
||||
|
||||
// These two checks are only necessary for VPE1.0 and contain a lot of quirks to work around VPE 1.0
|
||||
// limitations.
|
||||
enum vpe_status vpe_is_valid_bg_color(const struct vpe_priv *vpe_priv, struct vpe_color *bg_color) {
|
||||
|
||||
enum vpe_status status = VPE_STATUS_OK;
|
||||
|
||||
/* no need for background filling as for target rect equal to dest rect */
|
||||
if (is_target_rect_equal_to_dest_rect(vpe_priv)) {
|
||||
return VPE_STATUS_OK;
|
||||
}
|
||||
|
||||
status = is_valid_blend(vpe_priv, bg_color);
|
||||
|
||||
if (status == VPE_STATUS_OK)
|
||||
status = vpe_bg_color_outside_cs_gamut(vpe_priv, bg_color);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -26,11 +26,13 @@
|
||||
|
||||
#include "color.h"
|
||||
|
||||
void vpe_bg_color_convert(
|
||||
enum color_space cs, struct transfer_func *output_tf, enum vpe_surface_pixel_format pixel_format, struct vpe_color *bg_color, bool enable_3dlut);
|
||||
void vpe_bg_color_convert(enum color_space cs, struct transfer_func *output_tf,
|
||||
enum vpe_surface_pixel_format pixel_format, struct vpe_color *mpc_bg_color,
|
||||
struct vpe_color *opp_bg_color, bool enable_3dlut);
|
||||
|
||||
enum vpe_status vpe_bg_color_outside_cs_gamut(
|
||||
const struct vpe_priv *vpe_priv, struct vpe_color *bg_color);
|
||||
|
||||
enum vpe_status vpe_is_valid_bg_color(const struct vpe_priv *vpe_priv, struct vpe_color *bg_color);
|
||||
bool vpe_bg_csc(struct vpe_color *bg_color, enum color_space cs);
|
||||
|
||||
bool vpe_is_global_bg_blend_applied(struct stream_ctx *stream_ctx);
|
||||
|
||||
@@ -168,6 +168,8 @@ void vpe_frontend_config_callback(
|
||||
void vpe_backend_config_callback(
|
||||
void *ctx, uint64_t cfg_base_gpu, uint64_t cfg_base_cpu, uint64_t size, uint32_t pipe_idx);
|
||||
|
||||
bool vpe_rec_is_equal(struct vpe_rect rec1, struct vpe_rect rec2);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -166,7 +166,8 @@ struct stream_ctx {
|
||||
struct output_ctx {
|
||||
// stores the paramters built for generating vpep configs
|
||||
struct vpe_surface_info surface;
|
||||
struct vpe_color bg_color;
|
||||
struct vpe_color mpc_bg_color;
|
||||
struct vpe_color opp_bg_color;
|
||||
struct vpe_rect target_rect;
|
||||
enum vpe_alpha_mode alpha_mode;
|
||||
struct vpe_clamping_params clamping_params;
|
||||
|
||||
@@ -789,3 +789,10 @@ void vpe_backend_config_callback(
|
||||
vpe_priv->vpe_desc_writer.add_config_desc(
|
||||
&vpe_priv->vpe_desc_writer, cfg_base_gpu, false, (uint8_t)vpe_priv->config_writer.buf->tmz);
|
||||
}
|
||||
|
||||
bool vpe_rec_is_equal(struct vpe_rect rec1, struct vpe_rect rec2)
|
||||
{
|
||||
return (rec1.x == rec2.x && rec1.y == rec2.y && rec1.width == rec2.width &&
|
||||
rec1.height == rec2.height);
|
||||
}
|
||||
|
||||
|
||||
@@ -158,7 +158,8 @@ struct vpe_color vpe_get_visual_confirm_color(enum vpe_surface_pixel_format form
|
||||
}
|
||||
|
||||
// Due to there will be regamma (ogam), need convert the bg color for visual confirm
|
||||
vpe_bg_color_convert(output_cs, output_tf, output_format, &visual_confirm_color, enable_3dlut);
|
||||
vpe_bg_color_convert(
|
||||
output_cs, output_tf, output_format, &visual_confirm_color, NULL, enable_3dlut);
|
||||
|
||||
// Experimental: To make FP16 Linear color looks more visually ok
|
||||
if (vpe_is_fp16(output_format)) {
|
||||
|
||||
@@ -542,7 +542,8 @@ enum vpe_status vpe_check_support(
|
||||
// output resource preparation for further checking (cache the result)
|
||||
output_ctx = &vpe_priv->output_ctx;
|
||||
output_ctx->surface = param->dst_surface;
|
||||
output_ctx->bg_color = param->bg_color;
|
||||
output_ctx->mpc_bg_color = param->bg_color;
|
||||
output_ctx->opp_bg_color = param->bg_color;
|
||||
output_ctx->target_rect = param->target_rect;
|
||||
output_ctx->alpha_mode = param->alpha_mode;
|
||||
output_ctx->flags.hdr_metadata = param->flags.hdr_metadata;
|
||||
@@ -576,7 +577,7 @@ enum vpe_status vpe_check_support(
|
||||
// if the bg_color support is false, there is a flag to verify if the bg_color falls in the
|
||||
// output gamut
|
||||
if (!vpe_priv->pub.caps->bg_color_check_support) {
|
||||
status = vpe_priv->resource.check_bg_color_support(vpe_priv, &output_ctx->bg_color);
|
||||
status = vpe_priv->resource.check_bg_color_support(vpe_priv, &output_ctx->mpc_bg_color);
|
||||
if (status != VPE_STATUS_OK) {
|
||||
vpe_log(
|
||||
"failed in checking the background color versus the output color space %d\n",
|
||||
@@ -649,7 +650,10 @@ static bool validate_cached_param(struct vpe_priv *vpe_priv, const struct vpe_bu
|
||||
if (output_ctx->alpha_mode != param->alpha_mode)
|
||||
return false;
|
||||
|
||||
if (memcmp(&output_ctx->bg_color, ¶m->bg_color, sizeof(struct vpe_color)))
|
||||
if (memcmp(&output_ctx->mpc_bg_color, ¶m->bg_color, sizeof(struct vpe_color)))
|
||||
return false;
|
||||
|
||||
if (memcmp(&output_ctx->opp_bg_color, ¶m->bg_color, sizeof(struct vpe_color)))
|
||||
return false;
|
||||
|
||||
if (memcmp(&output_ctx->target_rect, ¶m->target_rect, sizeof(struct vpe_rect)))
|
||||
@@ -776,8 +780,9 @@ enum vpe_status vpe_build_commands(
|
||||
* the 3dlut enablement for the background color conversion
|
||||
* is used based on the information of the first stream.
|
||||
*/
|
||||
vpe_bg_color_convert(vpe_priv->output_ctx.cs, vpe_priv->output_ctx.output_tf, vpe_priv->output_ctx.surface.format,
|
||||
&vpe_priv->output_ctx.bg_color, vpe_priv->stream_ctx[0].enable_3dlut);
|
||||
vpe_bg_color_convert(vpe_priv->output_ctx.cs, vpe_priv->output_ctx.output_tf,
|
||||
vpe_priv->output_ctx.surface.format, &vpe_priv->output_ctx.mpc_bg_color,
|
||||
&vpe_priv->output_ctx.opp_bg_color, vpe_priv->stream_ctx[0].enable_3dlut);
|
||||
|
||||
if (vpe_priv->collaboration_mode == true) {
|
||||
status = builder->build_collaborate_sync_cmd(vpe_priv, &curr_bufs);
|
||||
|
||||
Reference in New Issue
Block a user