diff --git a/src/amd/common/ac_vcn_dec.h b/src/amd/common/ac_vcn_dec.h index d263c76022d..be69c14a4ba 100644 --- a/src/amd/common/ac_vcn_dec.h +++ b/src/amd/common/ac_vcn_dec.h @@ -1195,6 +1195,10 @@ struct jpeg_params { unsigned dt_luma_top_offset; unsigned dt_chroma_top_offset; unsigned dt_chromav_top_offset; + uint16_t crop_x; + uint16_t crop_y; + uint16_t crop_width; + uint16_t crop_height; }; #define RDECODE_VCN1_GPCOM_VCPU_CMD 0x2070c diff --git a/src/gallium/drivers/radeonsi/radeon_vcn_dec.c b/src/gallium/drivers/radeonsi/radeon_vcn_dec.c index b83e9567896..48a61039f19 100644 --- a/src/gallium/drivers/radeonsi/radeon_vcn_dec.c +++ b/src/gallium/drivers/radeonsi/radeon_vcn_dec.c @@ -2958,12 +2958,21 @@ static void radeon_dec_jpeg_end_frame(struct pipe_video_codec *decoder, struct p struct pipe_picture_desc *picture) { struct radeon_decoder *dec = (struct radeon_decoder *)decoder; + struct pipe_mjpeg_picture_desc *pic = (struct pipe_mjpeg_picture_desc *)picture; assert(decoder); if (!dec->bs_ptr) return; + dec->jpg.crop_x = ROUND_DOWN_TO(pic->picture_parameter.crop_x, VL_MACROBLOCK_WIDTH); + dec->jpg.crop_y = ROUND_DOWN_TO(pic->picture_parameter.crop_y, VL_MACROBLOCK_HEIGHT); + dec->jpg.crop_width = align(pic->picture_parameter.crop_width, VL_MACROBLOCK_WIDTH); + dec->jpg.crop_height = align(pic->picture_parameter.crop_height, VL_MACROBLOCK_HEIGHT); + if (dec->jpg.crop_x + dec->jpg.crop_width > pic->picture_parameter.picture_width) + dec->jpg.crop_width = 0; + if (dec->jpg.crop_y + dec->jpg.crop_height > pic->picture_parameter.picture_height) + dec->jpg.crop_height = 0; dec->send_cmd(dec, target, picture); dec->ws->cs_flush(&dec->jcs[dec->cb_idx], PIPE_FLUSH_ASYNC, NULL); next_buffer(dec); diff --git a/src/gallium/drivers/radeonsi/radeon_vcn_dec_jpeg.c b/src/gallium/drivers/radeonsi/radeon_vcn_dec_jpeg.c index 85654712b67..721aa3118b0 100644 --- a/src/gallium/drivers/radeonsi/radeon_vcn_dec_jpeg.c +++ b/src/gallium/drivers/radeonsi/radeon_vcn_dec_jpeg.c @@ -246,6 +246,7 @@ static void send_cmd_target_direct(struct radeon_decoder *dec, struct pb_buffer unsigned usage, enum radeon_bo_domain domain) { uint64_t addr; + uint32_t val; set_reg_jpeg(dec, dec->jpg_reg.jpeg_pitch, COND0, TYPE0, (dec->jpg.dt_pitch >> 4)); set_reg_jpeg(dec, dec->jpg_reg.jpeg_uv_pitch, COND0, TYPE0, ((dec->jpg.dt_uv_pitch * 2) >> 4)); @@ -276,6 +277,12 @@ static void send_cmd_target_direct(struct radeon_decoder *dec, struct pb_buffer set_reg_jpeg(dec, dec->jpg_reg.jpeg_luma_base0_0, COND0, TYPE0, dec->jpg.dt_luma_top_offset); set_reg_jpeg(dec, dec->jpg_reg.jpeg_chroma_base0_0, COND0, TYPE0, dec->jpg.dt_chroma_top_offset); set_reg_jpeg(dec, dec->jpg_reg.jpeg_chromav_base0_0, COND0, TYPE0, dec->jpg.dt_chromav_top_offset); + if (dec->jpg.crop_width && dec->jpg.crop_height) { + set_reg_jpeg(dec, vcnipUVD_JPEG_ROI_CROP_POS_START, COND0, TYPE0, + ((dec->jpg.crop_y << 16) | dec->jpg.crop_x)); + set_reg_jpeg(dec, vcnipUVD_JPEG_ROI_CROP_POS_STRIDE, COND0, TYPE0, + ((dec->jpg.crop_height << 16) | dec->jpg.crop_width)); + } } set_reg_jpeg(dec, dec->jpg_reg.jpeg_tier_cntl2, COND0, 0, 0); @@ -288,7 +295,12 @@ static void send_cmd_target_direct(struct radeon_decoder *dec, struct pb_buffer set_reg_jpeg(dec, dec->jpg_reg.jpeg_int_en, COND0, TYPE0, 0xFFFFFFFE); // start engine command - set_reg_jpeg(dec, dec->jpg_reg.jpeg_cntl, COND0, TYPE0, 0x6); + val = 0x6; + if (dec->jpg_reg.version == RDECODE_JPEG_REG_VER_V3) { + if (dec->jpg.crop_width && dec->jpg.crop_height) + val = val | (0x3 << 24); + } + set_reg_jpeg(dec, dec->jpg_reg.jpeg_cntl, COND0, TYPE0, val); // wait for job completion, wait for job JBSI fetch done set_reg_jpeg(dec, dec->jpg_reg.jrbc_ib_ref_data, COND0, TYPE0, (dec->jpg.bsd_size >> 2)); @@ -299,6 +311,14 @@ static void send_cmd_target_direct(struct radeon_decoder *dec, struct pb_buffer set_reg_jpeg(dec, dec->jpg_reg.jrbc_ib_ref_data, COND0, TYPE0, 0xFFFFFFFF); set_reg_jpeg(dec, dec->jpg_reg.jpeg_outbuf_wptr, COND3, TYPE3, 0x00000001); + if (dec->jpg_reg.version == RDECODE_JPEG_REG_VER_V3) { + val = 0; + if (dec->jpg.crop_width && dec->jpg.crop_height) + val = val | (0x1 << 19); + set_reg_jpeg(dec, dec->jpg_reg.jrbc_ib_ref_data, COND0, TYPE0, 0); + set_reg_jpeg(dec, vcnipUVD_JPEG_INT_STAT, COND3, TYPE3, val); + } + // stop engine set_reg_jpeg(dec, dec->jpg_reg.jpeg_cntl, COND0, TYPE0, 0x4); } diff --git a/src/gallium/include/pipe/p_video_state.h b/src/gallium/include/pipe/p_video_state.h index 4cc8a412801..d2038444a51 100644 --- a/src/gallium/include/pipe/p_video_state.h +++ b/src/gallium/include/pipe/p_video_state.h @@ -793,6 +793,10 @@ struct pipe_mjpeg_picture_desc } components[255]; uint8_t num_components; + uint16_t crop_x; + uint16_t crop_y; + uint16_t crop_width; + uint16_t crop_height; } picture_parameter; struct