From 65c7fb172030b8575d28970bdeb11003f47d7ee9 Mon Sep 17 00:00:00 2001 From: Julien Isorce Date: Wed, 26 Aug 2015 16:11:02 +0100 Subject: [PATCH 1/8] nouveau: extract memcpy loop from nouveau_vp3_bsp This patch add 3 functions to split nouveau_vp3_bsp: nouveau_vp3_bsp_begin nouveau_vp3_bsp_next nouveau_vp3_bsp_end https://bugs.freedesktop.org/show_bug.cgi?id=89969 Signed-off-by: Julien Isorce --- src/gallium/drivers/nouveau/nouveau_vp3_video.h | 15 +++ .../drivers/nouveau/nouveau_vp3_video_bsp.c | 105 +++++++++++++++++++++ 2 files changed, 120 insertions(+) diff --git a/src/gallium/drivers/nouveau/nouveau_vp3_video.h b/src/gallium/drivers/nouveau/nouveau_vp3_video.h index 33e3bef..16563de 100644 --- a/src/gallium/drivers/nouveau/nouveau_vp3_video.h +++ b/src/gallium/drivers/nouveau/nouveau_vp3_video.h @@ -114,6 +114,11 @@ struct nouveau_vp3_decoder { unsigned fence_seq, fw_sizes, last_frame_num, tmp_stride, ref_stride; unsigned bsp_idx, vp_idx, ppp_idx; + + // To manage chunck decoding. + char *bsp_ptr; + unsigned bsp_size; + unsigned int nb_slices; }; struct comm { @@ -215,6 +220,16 @@ nouveau_vp3_bsp(struct nouveau_vp3_decoder *dec, union pipe_desc desc, const void *const *data, const unsigned *num_bytes); void +nouveau_vp3_bsp_begin(struct nouveau_vp3_decoder *dec); + +void +nouveau_vp3_bsp_next(struct nouveau_vp3_decoder *dec, unsigned num_buffers, + const void *const *data, const unsigned *num_bytes); + +uint32_t +nouveau_vp3_bsp_end(struct nouveau_vp3_decoder *dec, union pipe_desc desc); + +void nouveau_vp3_vp_caps(struct nouveau_vp3_decoder *dec, union pipe_desc desc, struct nouveau_vp3_video_buffer *target, unsigned comm_seq, unsigned *caps, unsigned *is_ref, diff --git a/src/gallium/drivers/nouveau/nouveau_vp3_video_bsp.c b/src/gallium/drivers/nouveau/nouveau_vp3_video_bsp.c index 6d968c1..10dd23b 100644 --- a/src/gallium/drivers/nouveau/nouveau_vp3_video_bsp.c +++ b/src/gallium/drivers/nouveau/nouveau_vp3_video_bsp.c @@ -308,3 +308,108 @@ nouveau_vp3_bsp(struct nouveau_vp3_decoder *dec, union pipe_desc desc, return caps; } + +void +nouveau_vp3_bsp_begin(struct nouveau_vp3_decoder *dec) +{ + uint32_t comm_seq = dec->fence_seq; + struct nouveau_bo *bsp_bo = dec->bsp_bo[comm_seq % NOUVEAU_VP3_VIDEO_QDEPTH]; + struct strparm_bsp *str_bsp = NULL; + + dec->bsp_ptr = bsp_bo->map; + dec->bsp_size = NOUVEAU_VP3_BSP_RESERVED_SIZE; + dec->nb_slices = 0; + + dec->bsp_ptr += 0x100; + + str_bsp = (struct strparm_bsp *)dec->bsp_ptr; + memset(str_bsp, 0, 0x80); + str_bsp->w0[0] = 16; + str_bsp->w1[0] = 0x1; + dec->bsp_ptr += 0x100; + /* Reserved for picparm_vp */ + dec->bsp_ptr += 0x300; + /* Reserved for comm */ + #if !NOUVEAU_VP3_DEBUG_FENCE + memset(dec->bsp_ptr, 0, 0x200); + #endif + dec->bsp_ptr += 0x200; +} + +void +nouveau_vp3_bsp_next(struct nouveau_vp3_decoder *dec, unsigned num_buffers, + const void *const *data, const unsigned *num_bytes) +{ + uint32_t comm_seq = dec->fence_seq; + struct nouveau_bo *bsp_bo = dec->bsp_bo[comm_seq % NOUVEAU_VP3_VIDEO_QDEPTH]; + char *bsp_origin = bsp_bo->map; + struct strparm_bsp *str_bsp = NULL; + int i = 0; + + ++dec->nb_slices; + + bsp_origin += 0x100; + str_bsp = (struct strparm_bsp *)bsp_origin; + + for (i = 0; i < num_buffers; ++i) { + memcpy(dec->bsp_ptr, data[i], num_bytes[i]); + dec->bsp_ptr += num_bytes[i]; + str_bsp->w0[0] += num_bytes[i]; + } +} + +uint32_t +nouveau_vp3_bsp_end(struct nouveau_vp3_decoder *dec, union pipe_desc desc) +{ + uint32_t comm_seq = dec->fence_seq; + struct nouveau_bo *bsp_bo = dec->bsp_bo[comm_seq % NOUVEAU_VP3_VIDEO_QDEPTH]; + enum pipe_video_format codec = u_reduce_video_profile(dec->base.profile); + uint32_t caps = 0; + uint32_t endmarker = 0; + char *bsp = bsp_bo->map; + + /* + * 0x000..0x100: picparm_bsp + * 0x200..0x500: picparm_vp + * 0x500..0x700: comm + * 0x700..onward: raw bitstream + */ + + switch (codec){ + case PIPE_VIDEO_FORMAT_MPEG12: + endmarker = 0xb7010000; + caps = nouveau_vp3_fill_picparm_mpeg12_bsp(dec, desc.mpeg12, bsp); + break; + case PIPE_VIDEO_FORMAT_MPEG4: + endmarker = 0xb1010000; + caps = nouveau_vp3_fill_picparm_mpeg4_bsp(dec, desc.mpeg4, bsp); + break; + case PIPE_VIDEO_FORMAT_VC1: { + endmarker = 0x0a010000; + caps = nouveau_vp3_fill_picparm_vc1_bsp(dec, desc.vc1, bsp); + break; + } + case PIPE_VIDEO_FORMAT_MPEG4_AVC: { + endmarker = 0x0b010000; + caps = nouveau_vp3_fill_picparm_h264_bsp(dec, desc.h264, bsp); + break; + } + default: assert(0); return -1; + } + + caps |= 0 << 16; // reset struct comm if flag is set + caps |= 1 << 17; // enable watchdog + caps |= 0 << 18; // do not report error to VP, so it can continue decoding what we have + caps |= 0 << 19; // if enabled, use crypto crap? + + /* Append end sequence */ + *(uint32_t *)dec->bsp_ptr = endmarker; + dec->bsp_ptr += 4; + *(uint32_t *)dec->bsp_ptr = 0x00000000; + dec->bsp_ptr += 4; + *(uint32_t *)dec->bsp_ptr = endmarker; + dec->bsp_ptr += 4; + *(uint32_t *)dec->bsp_ptr = 0x00000000; + + return caps; +} -- 1.9.1