mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-24 13:10:10 +01:00
amd/vpelib: Create virtual stream concept
[Why] Need to create streams that don't come from input params (ex. for bg gen) to prepare for future concepts. [How] Add enum for stream type, create helper functions to populate virtual streams, and add custom functions where virtual stream function varies from input stream function. Reviewed-by: Roy Chan <roy.chan@amd.com> Acked-by: Alan Liu <haoping.liu@amd.com> Signed-off-by: Brendan Leder <brendansteve.leder@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30715>
This commit is contained in:
parent
b670701b65
commit
fcad791d07
6 changed files with 222 additions and 163 deletions
|
|
@ -537,7 +537,7 @@ enum vpe_status vpe10_calculate_segments(
|
|||
struct dpp *dpp = vpe_priv->resource.dpp[0];
|
||||
const uint32_t max_lb_size = dpp->funcs->get_line_buffer_size();
|
||||
|
||||
for (stream_idx = 0; stream_idx < params->num_streams; stream_idx++) {
|
||||
for (stream_idx = 0; stream_idx < vpe_priv->num_streams; stream_idx++) {
|
||||
stream_ctx = &vpe_priv->stream_ctx[stream_idx];
|
||||
src_rect = &stream_ctx->stream.scaling_info.src_rect;
|
||||
dst_rect = &stream_ctx->stream.scaling_info.dst_rect;
|
||||
|
|
|
|||
|
|
@ -229,7 +229,7 @@ static enum vpe_status vpe_allocate_cm_memory(struct vpe_priv *vpe_priv, const s
|
|||
struct output_ctx *output_ctx;
|
||||
enum vpe_status status = VPE_STATUS_OK;
|
||||
|
||||
for (uint32_t stream_idx = 0; stream_idx < param->num_streams; stream_idx++) {
|
||||
for (uint32_t stream_idx = 0; stream_idx < vpe_priv->num_streams; stream_idx++) {
|
||||
stream_ctx = &vpe_priv->stream_ctx[stream_idx];
|
||||
|
||||
if (!stream_ctx->input_cs) {
|
||||
|
|
@ -640,7 +640,7 @@ enum vpe_status vpe_color_update_color_space_and_tf(
|
|||
vpe_update_geometric_scaling(vpe_priv, param, &geometric_update, &geometric_scaling);
|
||||
color_check_output_cm_update(vpe_priv, &vpe_priv->output_ctx.surface.cs, geometric_update);
|
||||
|
||||
for (stream_idx = 0; stream_idx < param->num_streams; stream_idx++) {
|
||||
for (stream_idx = 0; stream_idx < vpe_priv->num_streams; stream_idx++) {
|
||||
|
||||
new_matrix_scaling_factor = vpe_fixpt_one;
|
||||
stream_ctx = &vpe_priv->stream_ctx[stream_idx];
|
||||
|
|
@ -757,7 +757,7 @@ enum vpe_status vpe_color_update_movable_cm(
|
|||
struct stream_ctx *stream_ctx;
|
||||
struct output_ctx *output_ctx = &vpe_priv->output_ctx;
|
||||
|
||||
for (stream_idx = 0; stream_idx < param->num_streams; stream_idx++) {
|
||||
for (stream_idx = 0; stream_idx < vpe_priv->num_streams; stream_idx++) {
|
||||
stream_ctx = &vpe_priv->stream_ctx[stream_idx];
|
||||
|
||||
bool enable_3dlut = stream_ctx->stream.tm_params.UID != 0 || stream_ctx->stream.tm_params.enable_3dlut;
|
||||
|
|
|
|||
|
|
@ -72,6 +72,11 @@ enum vpe_cmd_type {
|
|||
VPE_CMD_TYPE_COUNT
|
||||
};
|
||||
|
||||
enum vpe_stream_type {
|
||||
VPE_STREAM_TYPE_INPUT,
|
||||
VPE_STREAM_TYPE_BG_GEN,
|
||||
};
|
||||
|
||||
/** this represents a segement context.
|
||||
* each segment has its own version of data */
|
||||
struct segment_ctx {
|
||||
|
|
@ -124,8 +129,9 @@ struct vpe_3dlut_cache {
|
|||
struct stream_ctx {
|
||||
struct vpe_priv *vpe_priv;
|
||||
|
||||
int32_t stream_idx;
|
||||
struct vpe_stream stream; /**< stores all the input data */
|
||||
enum vpe_stream_type stream_type;
|
||||
int32_t stream_idx;
|
||||
struct vpe_stream stream; /**< stores all the input data */
|
||||
|
||||
uint16_t num_segments;
|
||||
struct segment_ctx *segment_ctx;
|
||||
|
|
@ -255,8 +261,10 @@ struct vpe_priv {
|
|||
struct config_backend_cb_ctx be_cb_ctx;
|
||||
|
||||
// input ctx
|
||||
uint32_t num_streams;
|
||||
struct stream_ctx *stream_ctx;
|
||||
uint32_t num_virtual_streams; // streams created by VPE
|
||||
uint32_t num_input_streams; // streams inputed from build params
|
||||
uint32_t num_streams; // input streams + virtual streams
|
||||
struct stream_ctx *stream_ctx; // input streams allocated first, then virtual streams
|
||||
|
||||
// output ctx
|
||||
struct output_ctx output_ctx;
|
||||
|
|
|
|||
|
|
@ -246,6 +246,7 @@ void vpe_free_stream_ctx(struct vpe_priv *vpe_priv)
|
|||
vpe_free(vpe_priv->stream_ctx);
|
||||
vpe_priv->stream_ctx = NULL;
|
||||
vpe_priv->num_streams = 0;
|
||||
vpe_priv->num_virtual_streams = 0;
|
||||
}
|
||||
|
||||
void vpe_free_output_ctx(struct vpe_priv *vpe_priv)
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ static uint16_t vpe_get_visual_confirm_total_seg_count(
|
|||
struct stream_ctx *stream_ctx;
|
||||
|
||||
if (vpe_priv->init.debug.visual_confirm_params.input_format) {
|
||||
for (stream_idx = 0; stream_idx < params->num_streams; stream_idx++) {
|
||||
for (stream_idx = 0; stream_idx < vpe_priv->num_streams; stream_idx++) {
|
||||
stream_ctx = &vpe_priv->stream_ctx[stream_idx];
|
||||
total_visual_confirm_segs += get_visual_confirm_segs_count(
|
||||
max_seg_width, stream_ctx->stream.scaling_info.dst_rect.width);
|
||||
|
|
|
|||
|
|
@ -215,132 +215,190 @@ void vpe_destroy(struct vpe **vpe)
|
|||
|
||||
|
||||
/*****************************************************************************************
|
||||
* handle_zero_input
|
||||
* handle any zero input stream but background output only
|
||||
* populate_bg_stream
|
||||
* populate virtual stream for background output only
|
||||
* struct vpe* vpe
|
||||
* [input] vpe context
|
||||
* const struct vpe_build_param* org_param
|
||||
* [input] original parameter from caller
|
||||
* struct vpe_build_param* dummy_input_param
|
||||
* [output] caller provided param struct for filling with dummy input
|
||||
* struct struct vpe_stream* dummy_stream
|
||||
* [output] caller provided vpe_stream struct for use in dummy_input_param->streams
|
||||
* struct struct vpe_stream_ctx* stream_ctx
|
||||
* [input/output] caller provided vpe_stream_ctx struct to populate
|
||||
*****************************************************************************************/
|
||||
static enum vpe_status handle_zero_input(struct vpe *vpe, const struct vpe_build_param *in_param,
|
||||
const struct vpe_build_param **out_param)
|
||||
static enum vpe_status populate_bg_stream(struct vpe_priv *vpe_priv, const struct vpe_build_param *param, struct stream_ctx *stream_ctx)
|
||||
{
|
||||
struct vpe_priv *vpe_priv;
|
||||
struct vpe_surface_info *surface_info;
|
||||
struct vpe_scaling_info *scaling_info;
|
||||
struct vpe_scaling_filter_coeffs *polyphaseCoeffs;
|
||||
struct vpe_stream *stream;
|
||||
|
||||
vpe_priv = container_of(vpe, struct vpe_priv, pub);
|
||||
|
||||
if (!in_param || !out_param)
|
||||
if (!param || !stream_ctx)
|
||||
return VPE_STATUS_ERROR;
|
||||
|
||||
*out_param = NULL;
|
||||
stream = &stream_ctx->stream;
|
||||
stream_ctx->stream_type = VPE_STREAM_TYPE_BG_GEN;
|
||||
|
||||
if (in_param->num_streams == 0 || vpe_priv->init.debug.bg_color_fill_only) {
|
||||
// if output surface is too small, don't use it as dummy input
|
||||
// request 2x2 instead of 1x1 for bpc safety
|
||||
// as we are to treat output as input for RGB 1x1, need 4bytes at least
|
||||
// but if output is YUV, bpc will be smaller and need larger dimension
|
||||
|
||||
// if output surface is too small, don't use it as dummy input
|
||||
// request 2x2 instead of 1x1 for bpc safety
|
||||
// as we are to treat output as input for RGB 1x1, need 4bytes at least
|
||||
// but if output is YUV, bpc will be smaller and need larger dimension
|
||||
|
||||
if (in_param->dst_surface.plane_size.surface_size.width < VPE_MIN_VIEWPORT_SIZE ||
|
||||
in_param->dst_surface.plane_size.surface_size.height < VPE_MIN_VIEWPORT_SIZE ||
|
||||
in_param->dst_surface.plane_size.surface_pitch < 256 / 4 || // 256bytes, 4bpp
|
||||
in_param->target_rect.width < VPE_MIN_VIEWPORT_SIZE ||
|
||||
in_param->target_rect.height < VPE_MIN_VIEWPORT_SIZE) {
|
||||
return VPE_STATUS_ERROR;
|
||||
}
|
||||
|
||||
if (!vpe_priv->dummy_input_param) {
|
||||
vpe_priv->dummy_input_param = vpe_zalloc(sizeof(struct vpe_build_param));
|
||||
if (!vpe_priv->dummy_input_param)
|
||||
return VPE_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
if (!vpe_priv->dummy_stream) {
|
||||
vpe_priv->dummy_stream = vpe_zalloc(sizeof(struct vpe_stream));
|
||||
if (!vpe_priv->dummy_stream)
|
||||
return VPE_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
*vpe_priv->dummy_input_param = *in_param;
|
||||
|
||||
vpe_priv->dummy_input_param->num_streams = 1;
|
||||
vpe_priv->dummy_input_param->streams = vpe_priv->dummy_stream;
|
||||
|
||||
// set output surface as our dummy input
|
||||
stream = vpe_priv->dummy_stream;
|
||||
surface_info = &stream->surface_info;
|
||||
scaling_info = &stream->scaling_info;
|
||||
polyphaseCoeffs = &stream->polyphase_scaling_coeffs;
|
||||
surface_info->address.type = VPE_PLN_ADDR_TYPE_GRAPHICS;
|
||||
surface_info->address.tmz_surface = in_param->dst_surface.address.tmz_surface;
|
||||
surface_info->address.grph.addr.quad_part =
|
||||
in_param->dst_surface.address.grph.addr.quad_part;
|
||||
|
||||
surface_info->swizzle = VPE_SW_LINEAR; // treat it as linear for simple
|
||||
surface_info->plane_size.surface_size.x = 0;
|
||||
surface_info->plane_size.surface_size.y = 0;
|
||||
surface_info->plane_size.surface_size.width = VPE_MIN_VIEWPORT_SIZE; // min width in pixels
|
||||
surface_info->plane_size.surface_size.height =
|
||||
VPE_MIN_VIEWPORT_SIZE; // min height in pixels
|
||||
surface_info->plane_size.surface_pitch = 256 / 4; // pitch in pixels
|
||||
surface_info->plane_size.surface_aligned_height = VPE_MIN_VIEWPORT_SIZE;
|
||||
surface_info->dcc.enable = false;
|
||||
surface_info->format = VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA8888;
|
||||
surface_info->cs.encoding = VPE_PIXEL_ENCODING_RGB;
|
||||
surface_info->cs.range = VPE_COLOR_RANGE_FULL;
|
||||
surface_info->cs.tf = VPE_TF_G22;
|
||||
surface_info->cs.cositing = VPE_CHROMA_COSITING_NONE;
|
||||
surface_info->cs.primaries = VPE_PRIMARIES_BT709;
|
||||
scaling_info->src_rect.x = 0;
|
||||
scaling_info->src_rect.y = 0;
|
||||
scaling_info->src_rect.width = VPE_MIN_VIEWPORT_SIZE;
|
||||
scaling_info->src_rect.height = VPE_MIN_VIEWPORT_SIZE;
|
||||
scaling_info->dst_rect.x = in_param->target_rect.x;
|
||||
scaling_info->dst_rect.y = in_param->target_rect.y;
|
||||
scaling_info->dst_rect.width = VPE_MIN_VIEWPORT_SIZE;
|
||||
scaling_info->dst_rect.height = VPE_MIN_VIEWPORT_SIZE;
|
||||
scaling_info->taps.v_taps = 4;
|
||||
scaling_info->taps.h_taps = 4;
|
||||
scaling_info->taps.v_taps_c = 2;
|
||||
scaling_info->taps.h_taps_c = 2;
|
||||
|
||||
polyphaseCoeffs->taps = scaling_info->taps;
|
||||
polyphaseCoeffs->nb_phases = 64;
|
||||
|
||||
stream->blend_info.blending = true;
|
||||
stream->blend_info.pre_multiplied_alpha = false;
|
||||
stream->blend_info.global_alpha = true; // hardcoded upon DAL request
|
||||
stream->blend_info.global_alpha_value = 0; // transparent as we are dummy input
|
||||
|
||||
stream->color_adj.brightness = 0.0f;
|
||||
stream->color_adj.contrast = 1.0f;
|
||||
stream->color_adj.hue = 0.0f;
|
||||
stream->color_adj.saturation = 1.0f;
|
||||
stream->rotation = VPE_ROTATION_ANGLE_0;
|
||||
stream->horizontal_mirror = false;
|
||||
stream->vertical_mirror = false;
|
||||
stream->enable_luma_key = false;
|
||||
stream->lower_luma_bound = 0;
|
||||
stream->upper_luma_bound = 0;
|
||||
stream->flags.hdr_metadata = 0;
|
||||
stream->flags.geometric_scaling = 0;
|
||||
stream->use_external_scaling_coeffs = false;
|
||||
*out_param = vpe_priv->dummy_input_param;
|
||||
} else {
|
||||
*out_param = in_param;
|
||||
if (param->dst_surface.plane_size.surface_size.width < VPE_MIN_VIEWPORT_SIZE ||
|
||||
param->dst_surface.plane_size.surface_size.height < VPE_MIN_VIEWPORT_SIZE ||
|
||||
param->dst_surface.plane_size.surface_pitch < 256 / 4 || // 256bytes, 4bpp
|
||||
param->target_rect.width < VPE_MIN_VIEWPORT_SIZE ||
|
||||
param->target_rect.height < VPE_MIN_VIEWPORT_SIZE) {
|
||||
return VPE_STATUS_ERROR;
|
||||
}
|
||||
|
||||
// set output surface as our dummy input
|
||||
surface_info = &stream->surface_info;
|
||||
scaling_info = &stream->scaling_info;
|
||||
polyphaseCoeffs = &stream->polyphase_scaling_coeffs;
|
||||
surface_info->address.type = VPE_PLN_ADDR_TYPE_GRAPHICS;
|
||||
surface_info->address.tmz_surface = param->dst_surface.address.tmz_surface;
|
||||
surface_info->address.grph.addr.quad_part =
|
||||
param->dst_surface.address.grph.addr.quad_part;
|
||||
|
||||
surface_info->swizzle = VPE_SW_LINEAR; // treat it as linear for simple
|
||||
surface_info->plane_size.surface_size.x = 0;
|
||||
surface_info->plane_size.surface_size.y = 0;
|
||||
surface_info->plane_size.surface_size.width = VPE_MIN_VIEWPORT_SIZE; // min width in pixels
|
||||
surface_info->plane_size.surface_size.height =
|
||||
VPE_MIN_VIEWPORT_SIZE; // min height in pixels
|
||||
surface_info->plane_size.surface_pitch = 256 / 4; // pitch in pixels
|
||||
surface_info->plane_size.surface_aligned_height = VPE_MIN_VIEWPORT_SIZE;
|
||||
surface_info->dcc.enable = false;
|
||||
surface_info->format = VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA8888;
|
||||
surface_info->cs.encoding = VPE_PIXEL_ENCODING_RGB;
|
||||
surface_info->cs.range = VPE_COLOR_RANGE_FULL;
|
||||
surface_info->cs.tf = VPE_TF_G22;
|
||||
surface_info->cs.cositing = VPE_CHROMA_COSITING_NONE;
|
||||
surface_info->cs.primaries = VPE_PRIMARIES_BT709;
|
||||
scaling_info->src_rect.x = 0;
|
||||
scaling_info->src_rect.y = 0;
|
||||
scaling_info->src_rect.width = VPE_MIN_VIEWPORT_SIZE;
|
||||
scaling_info->src_rect.height = VPE_MIN_VIEWPORT_SIZE;
|
||||
scaling_info->dst_rect.x = param->target_rect.x;
|
||||
scaling_info->dst_rect.y = param->target_rect.y;
|
||||
scaling_info->dst_rect.width = VPE_MIN_VIEWPORT_SIZE;
|
||||
scaling_info->dst_rect.height = VPE_MIN_VIEWPORT_SIZE;
|
||||
scaling_info->taps.v_taps = 4;
|
||||
scaling_info->taps.h_taps = 4;
|
||||
scaling_info->taps.v_taps_c = 2;
|
||||
scaling_info->taps.h_taps_c = 2;
|
||||
|
||||
polyphaseCoeffs->taps = scaling_info->taps;
|
||||
polyphaseCoeffs->nb_phases = 64;
|
||||
|
||||
stream->blend_info.blending = true;
|
||||
stream->blend_info.pre_multiplied_alpha = false;
|
||||
stream->blend_info.global_alpha = true; // hardcoded upon DAL request
|
||||
stream->blend_info.global_alpha_value = 0; // transparent as we are dummy input
|
||||
|
||||
stream->color_adj.brightness = 0.0f;
|
||||
stream->color_adj.contrast = 1.0f;
|
||||
stream->color_adj.hue = 0.0f;
|
||||
stream->color_adj.saturation = 1.0f;
|
||||
stream->rotation = VPE_ROTATION_ANGLE_0;
|
||||
stream->horizontal_mirror = false;
|
||||
stream->vertical_mirror = false;
|
||||
stream->enable_luma_key = false;
|
||||
stream->lower_luma_bound = 0;
|
||||
stream->upper_luma_bound = 0;
|
||||
stream->flags.hdr_metadata = 0;
|
||||
stream->flags.geometric_scaling = 0;
|
||||
stream->use_external_scaling_coeffs = false;
|
||||
|
||||
return VPE_STATUS_OK;
|
||||
}
|
||||
|
||||
static uint32_t get_required_virtual_stream_count(struct vpe_priv *vpe_priv, const struct vpe_build_param *param)
|
||||
{
|
||||
uint32_t result = 0;
|
||||
|
||||
// Check for zero-input background stream
|
||||
// Normally we result++ instead of returning, but bg_color_fill_only removes other streams (and therefore other features)
|
||||
if (param->num_streams == 0 || vpe_priv->init.debug.bg_color_fill_only)
|
||||
return 1;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static enum vpe_status populate_input_streams(struct vpe_priv *vpe_priv, const struct vpe_build_param *param, struct stream_ctx *stream_ctx_base)
|
||||
{
|
||||
enum vpe_status result = VPE_STATUS_OK;
|
||||
uint32_t i;
|
||||
struct stream_ctx* stream_ctx;
|
||||
bool input_h_mirror, output_h_mirror;
|
||||
|
||||
vpe_priv->resource.check_h_mirror_support(&input_h_mirror, &output_h_mirror);
|
||||
|
||||
for (i = 0; i < vpe_priv->num_input_streams; i++) {
|
||||
stream_ctx = &stream_ctx_base[i];
|
||||
stream_ctx->stream_type = VPE_STREAM_TYPE_INPUT;
|
||||
stream_ctx->stream_idx = (int32_t)i;
|
||||
stream_ctx->per_pixel_alpha =
|
||||
vpe_has_per_pixel_alpha(param->streams[i].surface_info.format);
|
||||
if (vpe_priv->init.debug.bypass_per_pixel_alpha) {
|
||||
stream_ctx->per_pixel_alpha = false;
|
||||
}
|
||||
if (param->streams[i].horizontal_mirror && !input_h_mirror && output_h_mirror)
|
||||
stream_ctx->flip_horizonal_output = true;
|
||||
else
|
||||
stream_ctx->flip_horizonal_output = false;
|
||||
|
||||
memcpy(&stream_ctx->stream, ¶m->streams[i], sizeof(struct vpe_stream));
|
||||
|
||||
/* if top-bottom blending is not supported,
|
||||
* the 1st stream still can support blending with background,
|
||||
* however, the 2nd stream and onward can't enable blending.
|
||||
*/
|
||||
if (i && param->streams[i].blend_info.blending &&
|
||||
!vpe_priv->pub.caps->color_caps.mpc.top_bottom_blending) {
|
||||
result = VPE_STATUS_ALPHA_BLENDING_NOT_SUPPORTED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static enum vpe_status populate_virtual_streams(struct vpe_priv* vpe_priv, const struct vpe_build_param* param, struct stream_ctx* stream_ctx_base, uint32_t num_virtual_streams)
|
||||
{
|
||||
enum vpe_status result = VPE_STATUS_OK;
|
||||
uint32_t virtual_stream_idx = 0;
|
||||
struct stream_ctx *stream_ctx;
|
||||
bool input_h_mirror, output_h_mirror;
|
||||
|
||||
vpe_priv->resource.check_h_mirror_support(&input_h_mirror, &output_h_mirror);
|
||||
|
||||
if (param->num_streams == 0 || vpe_priv->init.debug.bg_color_fill_only) {
|
||||
if (num_virtual_streams != 1)
|
||||
result = VPE_STATUS_ERROR;
|
||||
else
|
||||
result = populate_bg_stream(vpe_priv, param, &vpe_priv->stream_ctx[virtual_stream_idx++]);
|
||||
}
|
||||
|
||||
if (result != VPE_STATUS_OK)
|
||||
return result;
|
||||
|
||||
for (virtual_stream_idx = 0; virtual_stream_idx < num_virtual_streams; virtual_stream_idx++) {
|
||||
stream_ctx = &stream_ctx_base[virtual_stream_idx];
|
||||
stream_ctx->stream_idx = virtual_stream_idx + vpe_priv->num_input_streams;
|
||||
stream_ctx->per_pixel_alpha =
|
||||
vpe_has_per_pixel_alpha(stream_ctx->stream.surface_info.format);
|
||||
if (vpe_priv->init.debug.bypass_per_pixel_alpha) {
|
||||
stream_ctx->per_pixel_alpha = false;
|
||||
}
|
||||
if (stream_ctx->stream.horizontal_mirror && !input_h_mirror && output_h_mirror)
|
||||
stream_ctx->flip_horizonal_output = true;
|
||||
else
|
||||
stream_ctx->flip_horizonal_output = false;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
enum vpe_status vpe_check_support(
|
||||
struct vpe *vpe, const struct vpe_build_param *param, struct vpe_bufs_req *req)
|
||||
{
|
||||
|
|
@ -348,18 +406,13 @@ enum vpe_status vpe_check_support(
|
|||
struct vpec *vpec;
|
||||
struct dpp *dpp;
|
||||
enum vpe_status status;
|
||||
struct stream_ctx *stream_ctx;
|
||||
struct output_ctx *output_ctx = NULL;
|
||||
uint32_t i;
|
||||
bool input_h_mirror, output_h_mirror;
|
||||
uint32_t i, required_virtual_streams;
|
||||
|
||||
vpe_priv = container_of(vpe, struct vpe_priv, pub);
|
||||
vpec = &vpe_priv->resource.vpec;
|
||||
dpp = vpe_priv->resource.dpp[0];
|
||||
|
||||
status = handle_zero_input(vpe, param, ¶m);
|
||||
if (status != VPE_STATUS_OK)
|
||||
status = VPE_STATUS_NUM_STREAM_NOT_SUPPORTED;
|
||||
vpe_priv = container_of(vpe, struct vpe_priv, pub);
|
||||
vpec = &vpe_priv->resource.vpec;
|
||||
dpp = vpe_priv->resource.dpp[0];
|
||||
status = VPE_STATUS_OK;
|
||||
|
||||
#ifdef VPE_BUILD_1_1
|
||||
vpe_priv->collaboration_mode = param->collaboration_mode;
|
||||
|
|
@ -367,15 +420,36 @@ enum vpe_status vpe_check_support(
|
|||
verify_collaboration_mode(vpe_priv);
|
||||
#endif
|
||||
|
||||
if (!vpe_priv->stream_ctx || vpe_priv->num_streams != param->num_streams) {
|
||||
required_virtual_streams = get_required_virtual_stream_count(vpe_priv, param);
|
||||
|
||||
if (!vpe_priv->stream_ctx ||
|
||||
vpe_priv->num_streams != (param->num_streams + vpe_priv->num_virtual_streams) ||
|
||||
vpe_priv->num_virtual_streams != required_virtual_streams) {
|
||||
if (vpe_priv->stream_ctx)
|
||||
vpe_free_stream_ctx(vpe_priv);
|
||||
|
||||
vpe_priv->stream_ctx = vpe_alloc_stream_ctx(vpe_priv, param->num_streams);
|
||||
vpe_priv->stream_ctx = vpe_alloc_stream_ctx(vpe_priv, param->num_streams + required_virtual_streams);
|
||||
}
|
||||
|
||||
if (!vpe_priv->stream_ctx)
|
||||
status = VPE_STATUS_NO_MEMORY;
|
||||
else {
|
||||
vpe_priv->num_streams = param->num_streams + required_virtual_streams;
|
||||
vpe_priv->num_virtual_streams = required_virtual_streams;
|
||||
vpe_priv->num_input_streams = param->num_streams;
|
||||
}
|
||||
|
||||
if (param->num_streams == 0 || vpe_priv->init.debug.bg_color_fill_only) {
|
||||
vpe_free_stream_ctx(vpe_priv);
|
||||
vpe_priv->stream_ctx = vpe_alloc_stream_ctx(vpe_priv, 1);
|
||||
vpe_priv->num_streams = required_virtual_streams;
|
||||
vpe_priv->num_virtual_streams = required_virtual_streams;
|
||||
vpe_priv->num_input_streams = 0;
|
||||
|
||||
if (!vpe_priv->stream_ctx)
|
||||
status = VPE_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
|
||||
if (status == VPE_STATUS_OK) {
|
||||
// output checking - check per asic support
|
||||
|
|
@ -419,39 +493,20 @@ enum vpe_status vpe_check_support(
|
|||
|
||||
vpe_priv->num_vpe_cmds = 0;
|
||||
output_ctx->clamping_params = vpe_priv->init.debug.clamping_params;
|
||||
|
||||
vpe_priv->num_streams = param->num_streams;
|
||||
}
|
||||
|
||||
|
||||
if (status == VPE_STATUS_OK) {
|
||||
// blending support check
|
||||
vpe_priv->resource.check_h_mirror_support(&input_h_mirror, &output_h_mirror);
|
||||
status = populate_input_streams(vpe_priv, param, vpe_priv->stream_ctx);
|
||||
if (status != VPE_STATUS_OK)
|
||||
vpe_log("fail input stream population. status %d\n", (int)status);
|
||||
}
|
||||
|
||||
for (i = 0; i < param->num_streams; i++) {
|
||||
stream_ctx = &vpe_priv->stream_ctx[i];
|
||||
stream_ctx->stream_idx = (int32_t)i;
|
||||
stream_ctx->per_pixel_alpha =
|
||||
vpe_has_per_pixel_alpha(param->streams[i].surface_info.format);
|
||||
if (vpe_priv->init.debug.bypass_per_pixel_alpha) {
|
||||
stream_ctx->per_pixel_alpha = false;
|
||||
}
|
||||
if (param->streams[i].horizontal_mirror && !input_h_mirror && output_h_mirror)
|
||||
stream_ctx->flip_horizonal_output = true;
|
||||
else
|
||||
stream_ctx->flip_horizonal_output = false;
|
||||
|
||||
memcpy(&stream_ctx->stream, ¶m->streams[i], sizeof(struct vpe_stream));
|
||||
|
||||
/* if top-bottom blending is not supported,
|
||||
* the 1st stream still can support blending with background,
|
||||
* however, the 2nd stream and onward can't enable blending.
|
||||
*/
|
||||
if (i && param->streams[i].blend_info.blending &&
|
||||
!vpe_priv->pub.caps->color_caps.mpc.top_bottom_blending) {
|
||||
status = VPE_STATUS_ALPHA_BLENDING_NOT_SUPPORTED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (status == VPE_STATUS_OK) {
|
||||
status = populate_virtual_streams(vpe_priv, param, vpe_priv->stream_ctx + vpe_priv->num_input_streams, vpe_priv->num_virtual_streams);
|
||||
if (status != VPE_STATUS_OK)
|
||||
vpe_log("fail virtual stream population. status %d\n", (int)status);
|
||||
}
|
||||
|
||||
if (status == VPE_STATUS_OK) {
|
||||
|
|
@ -513,7 +568,8 @@ static bool validate_cached_param(struct vpe_priv *vpe_priv, const struct vpe_bu
|
|||
uint32_t i;
|
||||
struct output_ctx *output_ctx;
|
||||
|
||||
if (vpe_priv->num_streams != param->num_streams)
|
||||
if (vpe_priv->num_input_streams != param->num_streams &&
|
||||
!(vpe_priv->init.debug.bg_color_fill_only == true && vpe_priv->num_streams == 1))
|
||||
return false;
|
||||
|
||||
#ifdef VPE_BUILD_1_1
|
||||
|
|
@ -524,7 +580,7 @@ static bool validate_cached_param(struct vpe_priv *vpe_priv, const struct vpe_bu
|
|||
return false;
|
||||
#endif
|
||||
|
||||
for (i = 0; i < param->num_streams; i++) {
|
||||
for (i = 0; i < vpe_priv->num_input_streams; i++) {
|
||||
struct vpe_stream stream = param->streams[i];
|
||||
|
||||
vpe_clip_stream(
|
||||
|
|
@ -573,12 +629,6 @@ enum vpe_status vpe_build_commands(
|
|||
status = VPE_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (status == VPE_STATUS_OK) {
|
||||
status = handle_zero_input(vpe, param, ¶m);
|
||||
if (status != VPE_STATUS_OK)
|
||||
status = VPE_STATUS_NUM_STREAM_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (status == VPE_STATUS_OK) {
|
||||
if (!validate_cached_param(vpe_priv, param)) {
|
||||
status = VPE_STATUS_PARAM_CHECK_ERROR;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue