From 7ba27f60f71accaf59f267ff20580444e912ab2b Mon Sep 17 00:00:00 2001 From: Julien Isorce Date: Wed, 23 Dec 2015 09:25:52 +0000 Subject: [PATCH] nouveau: split nouveau_vp3_bsp in begin/next/end It allows to call nouveau_vp3_bsp_next multiple times between one begin/end. It is required to support st/va. https://bugs.freedesktop.org/show_bug.cgi?id=89969 Signed-off-by: Julien Isorce [imirkin: create strparm_bsp function, simplified w0 calculation] Signed-off-by: Ilia Mirkin --- src/gallium/drivers/nouveau/nouveau_vp3_video.h | 17 +++- .../drivers/nouveau/nouveau_vp3_video_bsp.c | 91 ++++++++++++++-------- src/gallium/drivers/nouveau/nv50/nv98_video_bsp.c | 5 +- src/gallium/drivers/nouveau/nvc0/nvc0_video_bsp.c | 5 +- 4 files changed, 77 insertions(+), 41 deletions(-) diff --git a/src/gallium/drivers/nouveau/nouveau_vp3_video.h b/src/gallium/drivers/nouveau/nouveau_vp3_video.h index 58df5ee847f..809e971a678 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; + + /* End of the bsp bo where new data should be appended between one begin/end + * frame. + */ + char *bsp_ptr; }; struct comm { @@ -208,11 +213,15 @@ nouveau_vp3_load_firmware(struct nouveau_vp3_decoder *dec, enum pipe_video_profile profile, unsigned chipset); +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(struct nouveau_vp3_decoder *dec, union pipe_desc desc, - struct nouveau_vp3_video_buffer *target, - unsigned comm_seq, unsigned num_buffers, - const void *const *data, const unsigned *num_bytes); +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, diff --git a/src/gallium/drivers/nouveau/nouveau_vp3_video_bsp.c b/src/gallium/drivers/nouveau/nouveau_vp3_video_bsp.c index 692772e49d1..a3d07deeb18 100644 --- a/src/gallium/drivers/nouveau/nouveau_vp3_video_bsp.c +++ b/src/gallium/drivers/nouveau/nouveau_vp3_video_bsp.c @@ -230,20 +230,58 @@ nouveau_vp3_fill_picparm_h264_bsp(struct nouveau_vp3_decoder *dec, return caps | 3; } +static inline struct strparm_bsp *strparm_bsp(struct nouveau_vp3_decoder *dec) +{ + unsigned comm_seq = dec->fence_seq; + struct nouveau_bo *bsp_bo = dec->bsp_bo[comm_seq % NOUVEAU_VP3_VIDEO_QDEPTH]; + return (struct strparm_bsp *)(bsp_bo->map + 0x100); +} + +void +nouveau_vp3_bsp_begin(struct nouveau_vp3_decoder *dec) +{ + struct strparm_bsp *str_bsp = strparm_bsp(dec); + + dec->bsp_ptr = (void *)str_bsp; + memset(str_bsp, 0, 0x80); + 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) +{ +#ifndef NDEBUG + unsigned comm_seq = dec->fence_seq; + struct nouveau_bo *bsp_bo = dec->bsp_bo[comm_seq % NOUVEAU_VP3_VIDEO_QDEPTH]; +#endif + struct strparm_bsp *str_bsp = strparm_bsp(dec); + int i; + + for (i = 0; i < num_buffers; ++i) { + assert(bsp_bo->size >= str_bsp->w0[0] + num_bytes[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(struct nouveau_vp3_decoder *dec, union pipe_desc desc, - struct nouveau_vp3_video_buffer *target, - unsigned comm_seq, unsigned num_buffers, - const void *const *data, const unsigned *num_bytes) +nouveau_vp3_bsp_end(struct nouveau_vp3_decoder *dec, union pipe_desc desc) { enum pipe_video_format codec = u_reduce_video_profile(dec->base.profile); + unsigned comm_seq = dec->fence_seq; struct nouveau_bo *bsp_bo = dec->bsp_bo[comm_seq % NOUVEAU_VP3_VIDEO_QDEPTH]; - char *bsp; uint32_t endmarker, caps; - struct strparm_bsp *str_bsp; - int i; - - bsp = bsp_bo->map; + struct strparm_bsp *str_bsp = strparm_bsp(dec); + char *bsp = bsp_bo->map; /* * 0x000..0x100: picparm_bsp * 0x200..0x500: picparm_vp @@ -277,34 +315,21 @@ nouveau_vp3_bsp(struct nouveau_vp3_decoder *dec, union pipe_desc desc, 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? - bsp += 0x100; - str_bsp = (struct strparm_bsp *)bsp; - memset(str_bsp, 0, 0x80); - str_bsp->w0[0] = 16; + str_bsp = strparm_bsp(dec); str_bsp->w1[0] = 0x1; - bsp += 0x100; - /* Reserved for picparm_vp */ - bsp += 0x300; - /* Reserved for comm */ -#if !NOUVEAU_VP3_DEBUG_FENCE - memset(bsp, 0, 0x200); -#endif - bsp += 0x200; - for (i = 0; i < num_buffers; ++i) { - memcpy(bsp, data[i], num_bytes[i]); - bsp += num_bytes[i]; - str_bsp->w0[0] += num_bytes[i]; - } /* Append end sequence */ - *(uint32_t *)bsp = endmarker; - bsp += 4; - *(uint32_t *)bsp = 0x00000000; - bsp += 4; - *(uint32_t *)bsp = endmarker; - bsp += 4; - *(uint32_t *)bsp = 0x00000000; + *(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; + str_bsp->w0[0] += 16; + + dec->bsp_ptr = NULL; return caps; } diff --git a/src/gallium/drivers/nouveau/nv50/nv98_video_bsp.c b/src/gallium/drivers/nouveau/nv50/nv98_video_bsp.c index 0f689cb2d6c..4fe0e05c96b 100644 --- a/src/gallium/drivers/nouveau/nv50/nv98_video_bsp.c +++ b/src/gallium/drivers/nouveau/nv50/nv98_video_bsp.c @@ -106,8 +106,9 @@ nv98_decoder_bsp(struct nouveau_vp3_decoder *dec, union pipe_desc desc, return -1; } - caps = nouveau_vp3_bsp(dec, desc, target, comm_seq, - num_buffers, data, num_bytes); + nouveau_vp3_bsp_begin(dec); + nouveau_vp3_bsp_next(dec, num_buffers, data, num_bytes); + caps = nouveau_vp3_bsp_end(dec, desc); nouveau_vp3_vp_caps(dec, desc, target, comm_seq, vp_caps, is_ref, refs); diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_video_bsp.c b/src/gallium/drivers/nouveau/nvc0/nvc0_video_bsp.c index 5e8cda0768d..6cedeaf9f27 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_video_bsp.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_video_bsp.c @@ -114,8 +114,9 @@ nvc0_decoder_bsp(struct nouveau_vp3_decoder *dec, union pipe_desc desc, return -1; } - caps = nouveau_vp3_bsp(dec, desc, target, comm_seq, - num_buffers, data, num_bytes); + nouveau_vp3_bsp_begin(dec); + nouveau_vp3_bsp_next(dec, num_buffers, data, num_bytes); + caps = nouveau_vp3_bsp_end(dec, desc); nouveau_vp3_vp_caps(dec, desc, target, comm_seq, vp_caps, is_ref, refs); -- 2.11.0