mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-04 22:49:13 +02:00
radeonsi/vcn: enable roi feature for vcn5
Compared to vcn4, qp map unit is a 32bit number, vcn5 uses 16bit integer number, in addition to that it has 2 unit alignment requirement(32 bit alignment) and each qp value needs left shift 7 bits. Acked-by: Leo Liu <leo.liu@amd.com> Signed-off-by: Ruijing Dong <ruijing.dong@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29423>
This commit is contained in:
parent
83d0189288
commit
c1e52baf30
3 changed files with 57 additions and 26 deletions
|
|
@ -751,6 +751,7 @@ typedef struct rvcn_enc_av1_recon_slot_s
|
|||
#define RENCODE_QP_MAP_TYPE_DELTA 1
|
||||
#define RENCODE_QP_MAP_TYPE_MAP_PA 4
|
||||
#define RENCODE_QP_MAP_MAX_REGIONS 32
|
||||
#define RENCODE_QP_MAP_UNIFIED_QP_BITS_SHIFT 7
|
||||
|
||||
struct rvcn_enc_qp_map_region
|
||||
{
|
||||
|
|
@ -767,7 +768,17 @@ typedef struct rvcn_enc_qp_map_s
|
|||
uint32_t qp_map_type;
|
||||
uint32_t qp_map_buffer_address_hi;
|
||||
uint32_t qp_map_buffer_address_lo;
|
||||
uint32_t qp_map_pitch;
|
||||
uint32_t qp_map_pitch; /* number of units in width */
|
||||
/* format difference between these two versions
|
||||
* legacy is using a 32 bit for 1 unit
|
||||
* vcn5 is using a 32 bit for 2 units, and use 2 units as the alignment
|
||||
*/
|
||||
enum {
|
||||
RENCODE_QP_MAP_LEGACY = 0,
|
||||
RENCODE_QP_MAP_VCN5
|
||||
} version;
|
||||
uint32_t width_in_block;
|
||||
uint32_t height_in_block;
|
||||
struct rvcn_enc_qp_map_region map[RENCODE_QP_MAP_MAX_REGIONS];
|
||||
}rvcn_enc_qp_map_t;
|
||||
|
||||
|
|
|
|||
|
|
@ -131,8 +131,11 @@ static void radeon_vcn_enc_get_intra_refresh_param(struct radeon_encoder *enc,
|
|||
static void radeon_vcn_enc_get_roi_param(struct radeon_encoder *enc,
|
||||
struct pipe_enc_roi *roi)
|
||||
{
|
||||
struct si_screen *sscreen = (struct si_screen *)enc->screen;
|
||||
bool is_av1 = u_reduce_video_profile(enc->base.profile)
|
||||
== PIPE_VIDEO_FORMAT_AV1;
|
||||
rvcn_enc_qp_map_t *qp_map = &enc->enc_pic.enc_qp_map;
|
||||
|
||||
if (!roi->num)
|
||||
enc->enc_pic.enc_qp_map.qp_map_type = RENCODE_QP_MAP_TYPE_NONE;
|
||||
else {
|
||||
|
|
@ -140,8 +143,13 @@ static void radeon_vcn_enc_get_roi_param(struct radeon_encoder *enc,
|
|||
uint32_t block_length;
|
||||
int32_t i, j, pa_format = 0;
|
||||
|
||||
/* rate control is using a different qp map type */
|
||||
if (enc->enc_pic.rc_session_init.rate_control_method) {
|
||||
qp_map->version = sscreen->info.vcn_ip_version >= VCN_5_0_0
|
||||
? RENCODE_QP_MAP_VCN5 : RENCODE_QP_MAP_LEGACY;
|
||||
|
||||
/* rate control is using a different qp map type, in case of below
|
||||
* vcn_5_0_0 */
|
||||
if (enc->enc_pic.rc_session_init.rate_control_method &&
|
||||
(qp_map->version == RENCODE_QP_MAP_LEGACY)) {
|
||||
enc->enc_pic.enc_qp_map.qp_map_type = RENCODE_QP_MAP_TYPE_MAP_PA;
|
||||
pa_format = 1;
|
||||
}
|
||||
|
|
@ -150,6 +158,9 @@ static void radeon_vcn_enc_get_roi_param(struct radeon_encoder *enc,
|
|||
|
||||
block_length = radeon_vcn_enc_blocks_in_frame(enc, &width_in_block, &height_in_block);
|
||||
|
||||
qp_map->width_in_block = width_in_block;
|
||||
qp_map->height_in_block = height_in_block;
|
||||
|
||||
for (i = RENCODE_QP_MAP_MAX_REGIONS; i >= roi->num; i--)
|
||||
enc->enc_pic.enc_qp_map.map[i].is_valid = false;
|
||||
|
||||
|
|
@ -164,7 +175,7 @@ static void radeon_vcn_enc_get_roi_param(struct radeon_encoder *enc,
|
|||
/* mapped av1 qi into the legacy qp range by dividing by 5 and
|
||||
* rounding up in any rate control mode.
|
||||
*/
|
||||
if (is_av1 && pa_format) {
|
||||
if (is_av1 && (pa_format || (qp_map->version == RENCODE_QP_MAP_VCN5))) {
|
||||
if (region->qp_value > 0)
|
||||
av1_qi_value = (region->qp_value + 2) / 5;
|
||||
else if (region->qp_value < 0)
|
||||
|
|
@ -1179,29 +1190,40 @@ static int setup_dpb(struct radeon_encoder *enc)
|
|||
/* each block (MB/CTB/SB) has one QP/QI value */
|
||||
static uint32_t roi_buffer_size(struct radeon_encoder *enc)
|
||||
{
|
||||
uint32_t width_in_block, height_in_block;
|
||||
uint32_t pitch_size_in_dword = 0;
|
||||
rvcn_enc_qp_map_t *qp_map = &enc->enc_pic.enc_qp_map;
|
||||
|
||||
radeon_vcn_enc_blocks_in_frame(enc, &width_in_block, &height_in_block);
|
||||
if ( qp_map->version == RENCODE_QP_MAP_LEGACY){
|
||||
pitch_size_in_dword = qp_map->width_in_block;
|
||||
qp_map->qp_map_pitch = qp_map->width_in_block;
|
||||
} else {
|
||||
/* two units merge into 1 dword */
|
||||
pitch_size_in_dword = DIV_ROUND_UP(qp_map->width_in_block, 2);
|
||||
qp_map->qp_map_pitch = pitch_size_in_dword * 2;
|
||||
}
|
||||
|
||||
return width_in_block * height_in_block * sizeof(uint32_t);
|
||||
return pitch_size_in_dword * qp_map->height_in_block * sizeof(uint32_t);
|
||||
}
|
||||
|
||||
static void arrange_qp_map(uint32_t *start,
|
||||
struct rvcn_enc_qp_map_region *map,
|
||||
uint32_t width_in_block,
|
||||
uint32_t height_in_block)
|
||||
static void arrange_qp_map(void *start,
|
||||
struct rvcn_enc_qp_map_region *regin,
|
||||
rvcn_enc_qp_map_t *map)
|
||||
{
|
||||
uint32_t i, j;
|
||||
uint32_t offset;
|
||||
uint32_t num_in_x = MIN2(map->x_in_unit + map->width_in_unit, width_in_block)
|
||||
- map->x_in_unit;
|
||||
uint32_t num_in_y = MIN2(map->y_in_unit + map->height_in_unit, height_in_block)
|
||||
- map->y_in_unit;;
|
||||
uint32_t num_in_x = MIN2(regin->x_in_unit + regin->width_in_unit, map->width_in_block)
|
||||
- regin->x_in_unit;
|
||||
uint32_t num_in_y = MIN2(regin->y_in_unit + regin->height_in_unit, map->height_in_block)
|
||||
- regin->y_in_unit;;
|
||||
|
||||
for (j = 0; j < num_in_y; j++) {
|
||||
for (i = 0; i < num_in_x; i++) {
|
||||
offset = map->x_in_unit + i + (map->y_in_unit + j) * width_in_block;
|
||||
*(start + offset) = (int32_t)map->qp_delta;
|
||||
offset = regin->x_in_unit + i + (regin->y_in_unit + j) * map->qp_map_pitch;
|
||||
if (map->version == RENCODE_QP_MAP_LEGACY)
|
||||
*((uint32_t *)start + offset) = (int32_t)regin->qp_delta;
|
||||
else
|
||||
*((int16_t *)start + offset) =
|
||||
(int16_t)(regin->qp_delta << RENCODE_QP_MAP_UNIFIED_QP_BITS_SHIFT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1214,24 +1236,23 @@ static int generate_roi_map(struct radeon_encoder *enc)
|
|||
{
|
||||
uint32_t width_in_block, height_in_block;
|
||||
uint32_t i;
|
||||
uint32_t *p_roi = NULL;
|
||||
void *p_roi = NULL;
|
||||
|
||||
radeon_vcn_enc_blocks_in_frame(enc, &width_in_block, &height_in_block);
|
||||
|
||||
assert (enc->roi_size >= width_in_block * height_in_block);
|
||||
p_roi = (uint32_t *)enc->ws->buffer_map(enc->ws,
|
||||
p_roi = enc->ws->buffer_map(enc->ws,
|
||||
enc->roi->res->buf,
|
||||
&enc->cs,
|
||||
PIPE_MAP_READ_WRITE | RADEON_MAP_TEMPORARY);
|
||||
if (!p_roi)
|
||||
goto error;
|
||||
|
||||
memset(p_roi, 0, width_in_block * height_in_block * sizeof(uint32_t));
|
||||
memset(p_roi, 0, enc->roi_size);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(enc->enc_pic.enc_qp_map.map); i++) {
|
||||
struct rvcn_enc_qp_map_region *map = &enc->enc_pic.enc_qp_map.map[i];
|
||||
if (map->is_valid)
|
||||
arrange_qp_map(p_roi, map, width_in_block, height_in_block);
|
||||
struct rvcn_enc_qp_map_region *region = &enc->enc_pic.enc_qp_map.map[i];
|
||||
if (region->is_valid)
|
||||
arrange_qp_map(p_roi, region, &enc->enc_pic.enc_qp_map);
|
||||
}
|
||||
|
||||
enc->ws->buffer_unmap(enc->ws, enc->roi->res->buf);
|
||||
|
|
|
|||
|
|
@ -1310,12 +1310,11 @@ static void radeon_enc_qp_map(struct radeon_encoder *enc)
|
|||
{
|
||||
if (enc->enc_pic.enc_qp_map.qp_map_type == RENCODE_QP_MAP_TYPE_NONE)
|
||||
return;
|
||||
enc->enc_pic.enc_qp_map.qp_map_pitch = 0;
|
||||
|
||||
RADEON_ENC_BEGIN(enc->cmd.enc_qp_map);
|
||||
RADEON_ENC_CS(enc->enc_pic.enc_qp_map.qp_map_type);
|
||||
RADEON_ENC_READWRITE(enc->roi->res->buf, enc->roi->res->domains, 0);
|
||||
RADEON_ENC_CS(enc->enc_pic.enc_qp_map.qp_map_pitch);
|
||||
RADEON_ENC_CS(0); /* qp_map pitch set to 0 for the ib */
|
||||
RADEON_ENC_END();
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue