amd/vpelib: Update configs to be per-pipe specific

[Why]
config settings should be per pipe in concept

[How]
update the framework to store configs per pipe

Reviewed-by: Roy Chan <Roy.Chan@amd.com>
Acked-by: Chih-Wei Chien <Chih-Wei.Chien@amd.com>
Signed-off-by: Brendan <brendanSteve.leder@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/31605>
This commit is contained in:
Brendan 2024-07-31 11:18:35 -04:00 committed by Marge Bot
parent 6a68af7d21
commit af01d7a181
10 changed files with 86 additions and 67 deletions

View file

@ -65,7 +65,7 @@ enum vpe_status vpe10_build_vpe_cmd(
struct vpe_buf *emb_buf = &cur_bufs->emb_buf;
struct output_ctx *output_ctx;
struct pipe_ctx *pipe_ctx = NULL;
uint32_t i, j;
uint32_t pipe_idx, config_idx;
struct vpe_cmd_info *cmd_info = vpe_vector_get(vpe_priv->vpe_cmd_vector, cmd_idx);
VPE_ASSERT(cmd_info);
@ -83,23 +83,24 @@ enum vpe_status vpe10_build_vpe_cmd(
config_writer_init(&vpe_priv->config_writer, emb_buf);
// frontend programming
for (i = 0; i < cmd_info->num_inputs; i++) {
for (pipe_idx = 0; pipe_idx < cmd_info->num_inputs; pipe_idx++) {
bool reuse;
struct stream_ctx *stream_ctx;
enum vpe_cmd_type cmd_type = VPE_CMD_TYPE_COUNT;
// keep using the same pipe whenever possible
// this would allow reuse of the previous register configs
pipe_ctx = vpe_pipe_find_owner(vpe_priv, cmd_info->inputs[i].stream_idx, &reuse);
pipe_ctx = vpe_pipe_find_owner(vpe_priv, cmd_info->inputs[pipe_idx].stream_idx, &reuse);
VPE_ASSERT(pipe_ctx);
if (!reuse) {
vpe_priv->resource.program_frontend(vpe_priv, pipe_ctx->pipe_idx, cmd_idx, i, false);
vpe_priv->resource.program_frontend(
vpe_priv, pipe_ctx->pipe_idx, cmd_idx, pipe_idx, false);
} else {
if (vpe_priv->init.debug.disable_reuse_bit)
reuse = false;
stream_ctx = &vpe_priv->stream_ctx[cmd_info->inputs[i].stream_idx];
stream_ctx = &vpe_priv->stream_ctx[cmd_info->inputs[pipe_idx].stream_idx];
// frame specific for same type of command
if (cmd_info->ops == VPE_CMD_OPS_BG)
@ -117,21 +118,24 @@ enum vpe_status vpe10_build_vpe_cmd(
// follow the same order of config generation in "non-reuse" case
// stream sharing
VPE_ASSERT(stream_ctx->num_configs);
for (j = 0; j < stream_ctx->num_configs; j++) {
VPE_ASSERT(stream_ctx->num_configs[pipe_idx]);
for (config_idx = 0; config_idx < stream_ctx->num_configs[pipe_idx]; config_idx++) {
vpe_desc_writer->add_config_desc(vpe_desc_writer,
stream_ctx->configs[j].config_base_addr, reuse, (uint8_t)emb_buf->tmz);
}
// stream-op sharing
for (j = 0; j < stream_ctx->num_stream_op_configs[cmd_type]; j++) {
vpe_desc_writer->add_config_desc(vpe_desc_writer,
stream_ctx->stream_op_configs[cmd_type][j].config_base_addr, reuse,
stream_ctx->configs[pipe_idx][config_idx].config_base_addr, reuse,
(uint8_t)emb_buf->tmz);
}
// stream-op sharing
for (config_idx = 0; config_idx < stream_ctx->num_stream_op_configs[pipe_idx][cmd_type];
config_idx++) {
vpe_desc_writer->add_config_desc(vpe_desc_writer,
stream_ctx->stream_op_configs[pipe_idx][cmd_type][config_idx].config_base_addr,
reuse, (uint8_t)emb_buf->tmz);
}
// command specific
vpe_priv->resource.program_frontend(vpe_priv, pipe_ctx->pipe_idx, cmd_idx, i, true);
vpe_priv->resource.program_frontend(
vpe_priv, pipe_ctx->pipe_idx, cmd_idx, pipe_idx, true);
}
}
@ -144,14 +148,14 @@ enum vpe_status vpe10_build_vpe_cmd(
// backend programming
output_ctx = &vpe_priv->output_ctx;
if (!output_ctx->num_configs) {
if (!output_ctx->num_configs[0]) {
vpe_priv->resource.program_backend(vpe_priv, pipe_ctx->pipe_idx, cmd_idx, false);
} else {
bool reuse = !vpe_priv->init.debug.disable_reuse_bit;
// re-use output register configs
for (j = 0; j < output_ctx->num_configs; j++) {
for (config_idx = 0; config_idx < output_ctx->num_configs[0]; config_idx++) {
vpe_desc_writer->add_config_desc(vpe_desc_writer,
output_ctx->configs[j].config_base_addr, reuse, (uint8_t)emb_buf->tmz);
output_ctx->configs[0][config_idx].config_base_addr, reuse, (uint8_t)emb_buf->tmz);
}
vpe_priv->resource.program_backend(vpe_priv, pipe_ctx->pipe_idx, cmd_idx, true);

View file

@ -732,7 +732,7 @@ static void vpe10_mpc_set3dlut_ram12_indirect(
uint32_t data_array_size = (entries / 2 * 3); // DW size of config data array, actual size
config_writer_set_type(config_writer, CONFIG_TYPE_INDIRECT);
config_writer_set_type(config_writer, CONFIG_TYPE_INDIRECT, mpc->inst);
// Optimized by single VPEP indirect config packet
// Fill the 3dLut array pointer
@ -743,7 +743,7 @@ static void vpe10_mpc_set3dlut_ram12_indirect(
config_writer, REG_OFFSET(VPMPCC_MCM_3DLUT_INDEX), 0, REG_OFFSET(VPMPCC_MCM_3DLUT_DATA));
// restore back to direct
config_writer_set_type(config_writer, CONFIG_TYPE_DIRECT);
config_writer_set_type(config_writer, CONFIG_TYPE_DIRECT, mpc->inst);
}
static void vpe10_mpc_set3dlut_ram10(struct mpc *mpc, const struct vpe_rgb *lut, uint32_t entries)
@ -801,7 +801,7 @@ static void vpe10_mpc_set3dlut_ram10_indirect(
// DW0: R1<<22 | G1<<12 | B1 <<2
//...
config_writer_set_type(config_writer, CONFIG_TYPE_INDIRECT);
config_writer_set_type(config_writer, CONFIG_TYPE_INDIRECT, mpc->inst);
// Optimized by single VPEP indirect config packet
// Fill the 3dLut array pointer
@ -812,7 +812,7 @@ static void vpe10_mpc_set3dlut_ram10_indirect(
config_writer, REG_OFFSET(VPMPCC_MCM_3DLUT_INDEX), 0, REG_OFFSET(VPMPCC_MCM_3DLUT_DATA));
// resume back to direct
config_writer_set_type(config_writer, CONFIG_TYPE_DIRECT);
config_writer_set_type(config_writer, CONFIG_TYPE_DIRECT, mpc->inst);
}
static void vpe10_mpc_set_3dlut_mode(
@ -931,7 +931,7 @@ bool vpe10_mpc_program_3dlut_indirect(struct mpc *mpc,
struct tetrahedral_9x9x9 *tetra9 = NULL;
// make sure it is in DIRECT type
config_writer_set_type(config_writer, CONFIG_TYPE_DIRECT);
config_writer_set_type(config_writer, CONFIG_TYPE_DIRECT, mpc->inst);
if (lut0_3_buf == NULL) {
vpe10_mpc_set_3dlut_mode(mpc, LUT_BYPASS, false);

View file

@ -729,7 +729,7 @@ int32_t vpe10_program_frontend(struct vpe_priv *vpe_priv, uint32_t pipe_idx, uin
config_writer_set_callback(
&vpe_priv->config_writer, &vpe_priv->fe_cb_ctx, vpe_frontend_config_callback);
config_writer_set_type(&vpe_priv->config_writer, CONFIG_TYPE_DIRECT);
config_writer_set_type(&vpe_priv->config_writer, CONFIG_TYPE_DIRECT, pipe_idx);
if (!seg_only) {
/* start front-end programming that can be shared among segments */
@ -825,7 +825,7 @@ int32_t vpe10_program_backend(
config_writer_set_callback(
&vpe_priv->config_writer, &vpe_priv->be_cb_ctx, vpe_backend_config_callback);
config_writer_set_type(&vpe_priv->config_writer, CONFIG_TYPE_DIRECT);
config_writer_set_type(&vpe_priv->config_writer, CONFIG_TYPE_DIRECT, pipe_idx);
if (!seg_only) {
/* start back-end programming that can be shared among segments */
@ -958,7 +958,7 @@ void vpe10_create_stream_ops_config(struct vpe_priv *vpe_priv, uint32_t pipe_idx
return;
// return if already generated
if (stream_ctx->num_stream_op_configs[cmd_type])
if (stream_ctx->num_stream_op_configs[pipe_idx][cmd_type])
return;
vpe_priv->fe_cb_ctx.cmd_type = cmd_type;

View file

@ -40,6 +40,7 @@ void config_writer_init(struct config_writer *writer, struct vpe_buf *buf)
writer->callback_ctx = NULL;
writer->callback = NULL;
writer->completed = false;
writer->pipe_idx = 0;
writer->status = VPE_STATUS_OK;
}
@ -83,21 +84,23 @@ static inline void config_writer_new(struct config_writer *writer)
writer->completed = false;
}
void config_writer_set_type(struct config_writer *writer, enum config_type type)
void config_writer_set_type(struct config_writer *writer, enum config_type type, uint32_t pipe_idx)
{
VPE_ASSERT(type != CONFIG_TYPE_UNKNOWN);
if (writer->status != VPE_STATUS_OK)
return;
if (writer->type != type) {
if (writer->type != type || writer->pipe_idx != pipe_idx) {
if (writer->type == CONFIG_TYPE_UNKNOWN) {
// new header. don't need to fill it yet until completion
writer->pipe_idx = pipe_idx;
config_writer_new(writer);
} else {
// a new config type, close the previous one
config_writer_complete(writer);
writer->pipe_idx = pipe_idx;
config_writer_new(writer);
}
writer->type = type;
@ -284,6 +287,7 @@ void config_writer_complete(struct config_writer *writer)
writer->completed = true;
if (writer->callback) {
writer->callback(writer->callback_ctx, writer->base_gpu_va, writer->base_cpu_va, size);
writer->callback(
writer->callback_ctx, writer->base_gpu_va, writer->base_cpu_va, size, writer->pipe_idx);
}
}

View file

@ -109,7 +109,7 @@ struct config_cache {
\
if (!use_cache) { \
uint64_t start, end; \
uint16_t config_num = (uint16_t)(obj_cfg_array)->num_configs; \
uint16_t config_num = (uint16_t)(obj_cfg_array)->num_configs[inst]; \
\
start = config_writer->base_cpu_va; \
program_func_call; \
@ -117,7 +117,7 @@ struct config_cache {
\
if (!disable_cache && !is_bypass) { \
/* only cache when it is not crossing config packets */ \
if (config_num == (obj_cfg_array)->num_configs) { \
if (config_num == (obj_cfg_array)->num_configs[inst]) { \
if ((obj_cache)->dirty[inst]) { \
uint64_t size = end - start; \
\

View file

@ -43,7 +43,7 @@ enum config_type {
};
typedef void (*config_callback_t)(
void *ctx, uint64_t cfg_base_gpu, uint64_t cfg_base_cpu, uint64_t size);
void *ctx, uint64_t cfg_base_gpu, uint64_t cfg_base_cpu, uint64_t size, uint32_t pipe_idx);
#define MAX_CONFIG_PACKET_DATA_SIZE_DWORD 0x01000
@ -82,6 +82,7 @@ struct config_writer {
uint64_t base_gpu_va;
uint64_t base_cpu_va;
uint16_t gpu_addr_alignment;
uint32_t pipe_idx;
enum config_type type;
bool completed;
@ -120,7 +121,7 @@ void config_writer_set_callback(
* /param writer writer instance
* /param type config type
*/
void config_writer_set_type(struct config_writer *writer, enum config_type type);
void config_writer_set_type(struct config_writer *writer, enum config_type type, uint32_t pipe_idx);
/** force create new config with specific type
* if the config is empty, only type will be changed, otherwise create new one
@ -133,6 +134,7 @@ void config_writer_set_type(struct config_writer *writer, enum config_type type)
*
* /param writer writer instance
* /param type config type
* /param pipe_idx pipe instance
*/
void config_writer_force_new_with_type(struct config_writer *writer, enum config_type type);

View file

@ -160,10 +160,10 @@ void vpe_resource_build_bit_depth_reduction_params(
/** resource function call backs*/
void vpe_frontend_config_callback(
void *ctx, uint64_t cfg_base_gpu, uint64_t cfg_base_cpu, uint64_t size);
void *ctx, uint64_t cfg_base_gpu, uint64_t cfg_base_cpu, uint64_t size, uint32_t pipe_idx);
void vpe_backend_config_callback(
void *ctx, uint64_t cfg_base_gpu, uint64_t cfg_base_cpu, uint64_t size);
void *ctx, uint64_t cfg_base_gpu, uint64_t cfg_base_cpu, uint64_t size, uint32_t pipe_idx);
#ifdef __cplusplus
}

View file

@ -130,11 +130,11 @@ struct stream_ctx {
uint16_t num_segments;
struct segment_ctx *segment_ctx;
uint16_t num_configs; // shared among same stream
uint16_t num_stream_op_configs[VPE_CMD_TYPE_COUNT]; // shared among same cmd type within the
// same stream
struct config_record configs[MAX_NUM_SAVED_CONFIG];
struct config_record stream_op_configs[VPE_CMD_TYPE_COUNT][MAX_NUM_SAVED_CONFIG];
uint16_t num_configs[MAX_PIPE]; // shared among same stream
uint16_t num_stream_op_configs[MAX_PIPE][VPE_CMD_TYPE_COUNT]; // shared among same cmd type
// within the same stream
struct config_record configs[MAX_PIPE][MAX_NUM_SAVED_CONFIG];
struct config_record stream_op_configs[MAX_PIPE][VPE_CMD_TYPE_COUNT][MAX_NUM_SAVED_CONFIG];
// cached color properties
bool per_pixel_alpha;
@ -180,8 +180,8 @@ struct output_ctx {
enum color_transfer_func tf;
enum color_space cs;
uint32_t num_configs;
struct config_record configs[MAX_NUM_SAVED_CONFIG];
uint32_t num_configs[MAX_OUTPUT_PIPE];
struct config_record configs[MAX_OUTPUT_PIPE][MAX_NUM_SAVED_CONFIG];
union {
struct {

View file

@ -695,7 +695,7 @@ void vpe_resource_build_bit_depth_reduction_params(
}
void vpe_frontend_config_callback(
void *ctx, uint64_t cfg_base_gpu, uint64_t cfg_base_cpu, uint64_t size)
void *ctx, uint64_t cfg_base_gpu, uint64_t cfg_base_cpu, uint64_t size, uint32_t pipe_idx)
{
struct config_frontend_cb_ctx *cb_ctx = (struct config_frontend_cb_ctx*)ctx;
struct vpe_priv *vpe_priv = cb_ctx->vpe_priv;
@ -703,24 +703,29 @@ void vpe_frontend_config_callback(
enum vpe_cmd_type cmd_type;
if (cb_ctx->stream_sharing) {
VPE_ASSERT(stream_ctx->num_configs <
(int)(sizeof(stream_ctx->configs) / sizeof(struct config_record)));
VPE_ASSERT(stream_ctx->num_configs[pipe_idx] <
(int)(sizeof(stream_ctx->configs[pipe_idx]) / sizeof(struct config_record)));
stream_ctx->configs[stream_ctx->num_configs].config_base_addr = cfg_base_gpu;
stream_ctx->configs[stream_ctx->num_configs].config_size = size;
stream_ctx->num_configs++;
stream_ctx->configs[pipe_idx][stream_ctx->num_configs[pipe_idx]].config_base_addr =
cfg_base_gpu;
stream_ctx->configs[pipe_idx][stream_ctx->num_configs[pipe_idx]].config_size = size;
stream_ctx->num_configs[pipe_idx]++;
} else if (cb_ctx->stream_op_sharing) {
cmd_type = cb_ctx->cmd_type;
VPE_ASSERT(
stream_ctx->num_stream_op_configs[cmd_type] <
(int)(sizeof(stream_ctx->stream_op_configs[cmd_type]) / sizeof(struct config_record)));
VPE_ASSERT(stream_ctx->num_stream_op_configs[pipe_idx][cmd_type] <
(int)(sizeof(stream_ctx->stream_op_configs[pipe_idx][cmd_type]) /
sizeof(struct config_record)));
stream_ctx->stream_op_configs[cmd_type][stream_ctx->num_stream_op_configs[cmd_type]]
stream_ctx
->stream_op_configs[pipe_idx][cmd_type]
[stream_ctx->num_stream_op_configs[pipe_idx][cmd_type]]
.config_base_addr = cfg_base_gpu;
stream_ctx->stream_op_configs[cmd_type][stream_ctx->num_stream_op_configs[cmd_type]]
stream_ctx
->stream_op_configs[pipe_idx][cmd_type]
[stream_ctx->num_stream_op_configs[pipe_idx][cmd_type]]
.config_size = size;
stream_ctx->num_stream_op_configs[cmd_type]++;
stream_ctx->num_stream_op_configs[pipe_idx][cmd_type]++;
}
vpe_priv->vpe_desc_writer.add_config_desc(
@ -728,19 +733,20 @@ 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)
void *ctx, uint64_t cfg_base_gpu, uint64_t cfg_base_cpu, uint64_t size, uint32_t pipe_idx)
{
struct config_backend_cb_ctx *cb_ctx = (struct config_backend_cb_ctx*)ctx;
struct vpe_priv *vpe_priv = cb_ctx->vpe_priv;
struct output_ctx *output_ctx = &vpe_priv->output_ctx;
if (cb_ctx->share) {
VPE_ASSERT(
output_ctx->num_configs < (sizeof(output_ctx->configs) / sizeof(struct config_record)));
VPE_ASSERT(output_ctx->num_configs[pipe_idx] <
(sizeof(output_ctx->configs[pipe_idx]) / sizeof(struct config_record)));
output_ctx->configs[output_ctx->num_configs].config_base_addr = cfg_base_gpu;
output_ctx->configs[output_ctx->num_configs].config_size = size;
output_ctx->num_configs++;
output_ctx->configs[pipe_idx][output_ctx->num_configs[pipe_idx]].config_base_addr =
cfg_base_gpu;
output_ctx->configs[pipe_idx][output_ctx->num_configs[pipe_idx]].config_size = size;
output_ctx->num_configs[pipe_idx]++;
}
vpe_priv->vpe_desc_writer.add_config_desc(

View file

@ -629,14 +629,13 @@ enum vpe_status vpe_build_commands(
struct vpe_priv *vpe_priv;
struct cmd_builder *builder;
enum vpe_status status = VPE_STATUS_OK;
uint32_t cmd_idx, i, j;
uint32_t cmd_idx, i, pipe_idx, stream_idx, cmd_type_idx;
struct vpe_build_bufs curr_bufs;
int64_t cmd_buf_size;
int64_t emb_buf_size;
uint64_t cmd_buf_gpu_a, cmd_buf_cpu_a;
uint64_t emb_buf_gpu_a, emb_buf_cpu_a;
struct vpe_cmd_info *cmd_info;
if (!vpe || !param || !bufs)
return VPE_STATUS_ERROR;
@ -686,12 +685,16 @@ enum vpe_status vpe_build_commands(
curr_bufs = *bufs;
// copy the param, reset saved configs
for (i = 0; i < vpe_priv->num_streams; i++) {
vpe_priv->stream_ctx[i].num_configs = 0;
for (j = 0; j < VPE_CMD_TYPE_COUNT; j++)
vpe_priv->stream_ctx[i].num_stream_op_configs[j] = 0;
for (stream_idx = 0; stream_idx < vpe_priv->num_streams; stream_idx++) {
for (pipe_idx = 0; pipe_idx < MAX_PIPE; pipe_idx++) {
vpe_priv->stream_ctx[stream_idx].num_configs[pipe_idx] = 0;
for (cmd_type_idx = 0; cmd_type_idx < VPE_CMD_TYPE_COUNT; cmd_type_idx++)
vpe_priv->stream_ctx[stream_idx].num_stream_op_configs[pipe_idx][cmd_type_idx] = 0;
}
}
vpe_priv->output_ctx.num_configs = 0;
for (i = 0; i < MAX_OUTPUT_PIPE; i++)
vpe_priv->output_ctx.num_configs[i] = 0;
// Reset pipes
vpe_pipe_reset(vpe_priv);