<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On 17 December 2015 at 04:13, Ilia Mirkin <span dir="ltr"><<a href="mailto:imirkin@alum.mit.edu" target="_blank">imirkin@alum.mit.edu</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><div>On Wed, Dec 16, 2015 at 9:39 AM, Julien Isorce <<a href="mailto:j.isorce@samsung.com" target="_blank">j.isorce@samsung.com</a>> wrote:<br>
> - split nvc0_decoder_bsp in begin/next/end<br>
> - preserve content buffer when calling nvc0_decoder_bsp_next<br>
> - implement pipe_video_codec::begin_frame/end_frame<br>
><br>
> <a href="https://bugs.freedesktop.org/show_bug.cgi?id=89969" rel="noreferrer" target="_blank">https://bugs.freedesktop.org/show_bug.cgi?id=89969</a><br>
><br>
> Signed-off-by: Julien Isorce <<a href="mailto:j.isorce@samsung.com" target="_blank">j.isorce@samsung.com</a>><br>
> ---<br>
> src/gallium/drivers/nouveau/nouveau_vp3_video.h | 3 +<br>
> .../drivers/nouveau/nouveau_vp3_video_bsp.c | 2 +<br>
> src/gallium/drivers/nouveau/nvc0/nvc0_video.c | 44 ++++++-<br>
> src/gallium/drivers/nouveau/nvc0/nvc0_video.h | 18 ++-<br>
> src/gallium/drivers/nouveau/nvc0/nvc0_video_bsp.c | 138 ++++++++++++++-------<br>
> 5 files changed, 150 insertions(+), 55 deletions(-)<br>
><br>
> diff --git a/src/gallium/drivers/nouveau/nouveau_vp3_video.h b/src/gallium/drivers/nouveau/nouveau_vp3_video.h<br>
> index 9db8c63..1e10693 100644<br>
> --- a/src/gallium/drivers/nouveau/nouveau_vp3_video.h<br>
> +++ b/src/gallium/drivers/nouveau/nouveau_vp3_video.h<br>
> @@ -118,6 +118,9 @@ struct nouveau_vp3_decoder {<br>
> /* End of the bsp bo where new data should be appended between one begin/end<br>
> * frame. */<br>
> char *bsp_ptr;<br>
> +<br>
> + /* Total data appended so far after last begin frame. */<br>
> + unsigned bsp_size;<br>
> };<br>
><br>
> struct comm {<br>
> diff --git a/src/gallium/drivers/nouveau/nouveau_vp3_video_bsp.c b/src/gallium/drivers/nouveau/nouveau_vp3_video_bsp.c<br>
> index 2c15955..aab8e25 100644<br>
> --- a/src/gallium/drivers/nouveau/nouveau_vp3_video_bsp.c<br>
> +++ b/src/gallium/drivers/nouveau/nouveau_vp3_video_bsp.c<br>
> @@ -238,6 +238,7 @@ nouveau_vp3_bsp_begin(struct nouveau_vp3_decoder *dec)<br>
> struct strparm_bsp *str_bsp = NULL;<br>
><br>
> dec->bsp_ptr = bsp_bo->map;<br>
> + dec->bsp_size = NOUVEAU_VP3_BSP_RESERVED_SIZE;<br>
><br>
> dec->bsp_ptr += 0x100;<br>
><br>
> @@ -329,6 +330,7 @@ nouveau_vp3_bsp_end(struct nouveau_vp3_decoder *dec, union pipe_desc desc)<br>
> *(uint32_t *)dec->bsp_ptr = 0x00000000;<br>
><br>
> dec->bsp_ptr = NULL;<br>
> + dec->bsp_size = 0;<br>
><br>
> return caps;<br>
> }<br>
> diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_video.c b/src/gallium/drivers/nouveau/nvc0/nvc0_video.c<br>
> index 48ffac1..e28016a 100644<br>
> --- a/src/gallium/drivers/nouveau/nvc0/nvc0_video.c<br>
> +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_video.c<br>
> @@ -26,6 +26,24 @@<br>
> #include "util/u_format.h"<br>
><br>
> static void<br>
> +nvc0_decoder_begin_frame(struct pipe_video_codec *decoder,<br>
> + struct pipe_video_buffer *target,<br>
> + struct pipe_picture_desc *picture)<br>
> +{<br>
> + struct nouveau_vp3_decoder *dec = (struct nouveau_vp3_decoder *)decoder;<br>
> + uint32_t comm_seq = ++dec->fence_seq;<br>
> + unsigned ret = 0;<br>
> +<br>
> + assert(dec);<br>
> + assert(target);<br>
> + assert(target->buffer_format == PIPE_FORMAT_NV12);<br>
> +<br>
> + ret = nvc0_decoder_bsp_begin(dec, comm_seq);<br>
> +<br>
> + assert(ret == 2);<br>
> +}<br>
> +<br>
> +static void<br>
> nvc0_decoder_decode_bitstream(struct pipe_video_codec *decoder,<br>
> struct pipe_video_buffer *video_target,<br>
> struct pipe_picture_desc *picture,<br>
> @@ -34,8 +52,24 @@ nvc0_decoder_decode_bitstream(struct pipe_video_codec *decoder,<br>
> const unsigned *num_bytes)<br>
> {<br>
> struct nouveau_vp3_decoder *dec = (struct nouveau_vp3_decoder *)decoder;<br>
> + uint32_t comm_seq = dec->fence_seq;<br>
> + unsigned ret = 0;<br>
> +<br>
> + assert(decoder);<br>
> +<br>
> + ret = nvc0_decoder_bsp_next(dec, comm_seq, num_buffers, data, num_bytes);<br>
> +<br>
> + assert(ret == 2);<br>
> +}<br>
> +<br>
> +static void<br>
> +nvc0_decoder_end_frame(struct pipe_video_codec *decoder,<br>
> + struct pipe_video_buffer *video_target,<br>
> + struct pipe_picture_desc *picture)<br>
> +{<br>
> + struct nouveau_vp3_decoder *dec = (struct nouveau_vp3_decoder *)decoder;<br>
> struct nouveau_vp3_video_buffer *target = (struct nouveau_vp3_video_buffer *)video_target;<br>
> - uint32_t comm_seq = ++dec->fence_seq;<br>
> + uint32_t comm_seq = dec->fence_seq;<br>
> union pipe_desc desc;<br>
><br>
> unsigned vp_caps, is_ref, ret;<br>
> @@ -43,11 +77,7 @@ nvc0_decoder_decode_bitstream(struct pipe_video_codec *decoder,<br>
><br>
> desc.base = picture;<br>
><br>
> - assert(target->base.buffer_format == PIPE_FORMAT_NV12);<br>
> -<br>
> - ret = nvc0_decoder_bsp(dec, desc, target, comm_seq,<br>
> - num_buffers, data, num_bytes,<br>
> - &vp_caps, &is_ref, refs);<br>
> + ret = nvc0_decoder_bsp_end(dec, desc, target, comm_seq, &vp_caps, &is_ref, refs);<br>
><br>
> /* did we decode bitstream correctly? */<br>
> assert(ret == 2);<br>
> @@ -164,7 +194,9 @@ nvc0_create_decoder(struct pipe_context *context,<br>
> PUSH_DATA (push[2], dec->ppp->handle);<br>
><br>
> dec->base.context = context;<br>
> + dec->base.begin_frame = nvc0_decoder_begin_frame;<br>
> dec->base.decode_bitstream = nvc0_decoder_decode_bitstream;<br>
> + dec->base.end_frame = nvc0_decoder_end_frame;<br>
><br>
> for (i = 0; i < NOUVEAU_VP3_VIDEO_QDEPTH && !ret; ++i)<br>
> ret = nouveau_bo_new(screen->device, NOUVEAU_BO_VRAM,<br>
> diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_video.h b/src/gallium/drivers/nouveau/nvc0/nvc0_video.h<br>
> index 9ee0280..cf3c942 100644<br>
> --- a/src/gallium/drivers/nouveau/nvc0/nvc0_video.h<br>
> +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_video.h<br>
> @@ -30,12 +30,18 @@<br>
> #include "util/u_video.h"<br>
><br>
> extern unsigned<br>
> -nvc0_decoder_bsp(struct nouveau_vp3_decoder *dec, union pipe_desc desc,<br>
> - struct nouveau_vp3_video_buffer *target,<br>
> - unsigned comm_seq, unsigned num_buffers,<br>
> - const void *const *data, const unsigned *num_bytes,<br>
> - unsigned *vp_caps, unsigned *is_ref,<br>
> - struct nouveau_vp3_video_buffer *refs[16]);<br>
> +nvc0_decoder_bsp_begin(struct nouveau_vp3_decoder *dec, unsigned comm_seq);<br>
> +<br>
> +extern unsigned<br>
> +nvc0_decoder_bsp_next(struct nouveau_vp3_decoder *dec,<br>
> + unsigned comm_seq, unsigned num_buffers,<br>
> + const void *const *data, const unsigned *num_bytes);<br>
> +<br>
> +extern unsigned<br>
> +nvc0_decoder_bsp_end(struct nouveau_vp3_decoder *dec, union pipe_desc desc,<br>
> + struct nouveau_vp3_video_buffer *target,<br>
> + unsigned comm_seq, unsigned *vp_caps, unsigned *is_ref,<br>
> + struct nouveau_vp3_video_buffer *refs[16]);<br>
><br>
> extern void<br>
> nvc0_decoder_vp(struct nouveau_vp3_decoder *dec, union pipe_desc desc,<br>
> diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_video_bsp.c b/src/gallium/drivers/nouveau/nvc0/nvc0_video_bsp.c<br>
> index b0ee4a4..04528d8 100644<br>
> --- a/src/gallium/drivers/nouveau/nvc0/nvc0_video_bsp.c<br>
> +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_video_bsp.c<br>
> @@ -32,40 +32,34 @@ static void dump_comm_bsp(struct comm *comm)<br>
> #endif<br>
><br>
> unsigned<br>
> -nvc0_decoder_bsp(struct nouveau_vp3_decoder *dec, union pipe_desc desc,<br>
> - struct nouveau_vp3_video_buffer *target,<br>
> - unsigned comm_seq, unsigned num_buffers,<br>
> - const void *const *data, const unsigned *num_bytes,<br>
> - unsigned *vp_caps, unsigned *is_ref,<br>
> - struct nouveau_vp3_video_buffer *refs[16])<br>
> +nvc0_decoder_bsp_begin(struct nouveau_vp3_decoder *dec, unsigned comm_seq)<br>
> {<br>
> - struct nouveau_pushbuf *push = dec->pushbuf[0];<br>
> - enum pipe_video_format codec = u_reduce_video_profile(dec->base.profile);<br>
> - uint32_t bsp_addr, comm_addr, inter_addr;<br>
> - uint32_t slice_size, bucket_size, ring_size, bsp_size;<br>
> - uint32_t caps, i;<br>
> - int ret;<br>
> struct nouveau_bo *bsp_bo = dec->bsp_bo[comm_seq % NOUVEAU_VP3_VIDEO_QDEPTH];<br>
> - struct nouveau_bo *inter_bo = dec->inter_bo[comm_seq & 1];<br>
> - unsigned fence_extra = 0;<br>
> - struct nouveau_pushbuf_refn bo_refs[] = {<br>
> - { bsp_bo, NOUVEAU_BO_RD | NOUVEAU_BO_VRAM },<br>
> - { inter_bo, NOUVEAU_BO_WR | NOUVEAU_BO_VRAM },<br>
> -#if NOUVEAU_VP3_DEBUG_FENCE<br>
> - { dec->fence_bo, NOUVEAU_BO_WR | NOUVEAU_BO_GART },<br>
> -#endif<br>
> - { dec->bitplane_bo, NOUVEAU_BO_RDWR | NOUVEAU_BO_VRAM },<br>
> - };<br>
> - int num_refs = ARRAY_SIZE(bo_refs);<br>
> + unsigned ret = 0;<br>
><br>
> - if (!dec->bitplane_bo)<br>
> - num_refs--;<br>
> + ret = nouveau_bo_map(bsp_bo, NOUVEAU_BO_WR, dec->client);<br>
> + if (ret) {<br>
> + debug_printf("map failed: %i %s\n", ret, strerror(-ret));<br>
> + return -1;<br>
> + }<br>
><br>
> -#if NOUVEAU_VP3_DEBUG_FENCE<br>
> - fence_extra = 4;<br>
> -#endif<br>
> + nouveau_vp3_bsp_begin(dec);<br>
> +<br>
> + return 2;<br>
> +}<br>
> +<br>
> +unsigned<br>
> +nvc0_decoder_bsp_next(struct nouveau_vp3_decoder *dec,<br>
> + unsigned comm_seq, unsigned num_buffers,<br>
> + const void *const *data, const unsigned *num_bytes)<br>
> +{<br>
> + struct nouveau_bo *bsp_bo = dec->bsp_bo[comm_seq % NOUVEAU_VP3_VIDEO_QDEPTH];<br>
> + struct nouveau_bo *inter_bo = dec->inter_bo[comm_seq & 1];<br>
> + uint32_t bsp_size = 0;<br>
> + uint32_t i = 0;<br>
> + unsigned ret = 0;<br>
><br>
> - bsp_size = NOUVEAU_VP3_BSP_RESERVED_SIZE;<br>
> + bsp_size = dec->bsp_size;<br>
> for (i = 0; i < num_buffers; i++)<br>
> bsp_size += num_bytes[i];<br>
> bsp_size += 256; /* the 4 end markers */<br>
> @@ -73,22 +67,36 @@ nvc0_decoder_bsp(struct nouveau_vp3_decoder *dec, union pipe_desc desc,<br>
> if (!bsp_bo || bsp_size > bsp_bo->size) {<br>
> union nouveau_bo_config cfg;<br>
> struct nouveau_bo *tmp_bo = NULL;<br>
> + uint32_t bsp_new_size = bsp_size;<br>
<br>
</div></div>Err, why not just use bsp_size as before. And not move it around the<br>
cfg.* setting, to reduce churn?<br></blockquote><div><br></div><div>Ack I'll apply similar solution as you suggested below.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<span><br>
> +<br>
> + /* round up to the nearest mb */<br>
> + bsp_new_size += (1 << 20) - 1;<br>
> + bsp_new_size &= ~((1 << 20) - 1);<br>
><br>
> cfg.nvc0.tile_mode = 0x10;<br>
> cfg.nvc0.memtype = 0xfe;<br>
><br>
> - /* round up to the nearest mb */<br>
> - bsp_size += (1 << 20) - 1;<br>
> - bsp_size &= ~((1 << 20) - 1);<br>
> + ret = nouveau_bo_new(dec->bitplane_bo->device, NOUVEAU_BO_VRAM, 0, bsp_new_size, &cfg, &tmp_bo);<br>
> + if (ret) {<br>
> + debug_printf("resizing bsp %u -> %u failed with %i\n",<br>
<br>
</span>There's no resizing... the previous message was more accurate ("reallocating").<br></blockquote><div> </div><div>Ack.<br> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<span><br>
> + bsp_bo ? (unsigned)bsp_bo->size : 0, bsp_new_size, ret);<br>
> + return -1;<br>
> + }<br>
><br>
> - ret = nouveau_bo_new(dec->bitplane_bo->device, NOUVEAU_BO_VRAM, 0, bsp_size, &cfg, &tmp_bo);<br>
> + ret = nouveau_bo_map(tmp_bo, NOUVEAU_BO_WR, dec->client);<br>
> if (ret) {<br>
> - debug_printf("reallocating bsp %u -> %u failed with %i\n",<br>
> - bsp_bo ? (unsigned)bsp_bo->size : 0, bsp_size, ret);<br>
> + debug_printf("map failed: %i %s\n", ret, strerror(-ret));<br>
> return -1;<br>
> }<br>
> +<br>
> + /* Preserve previous buffer. */<br>
> + memcpy(tmp_bo->map, bsp_bo->map, bsp_bo->size);<br>
> +<br>
> nouveau_bo_ref(NULL, &bsp_bo);<br>
> - bo_refs[0].bo = dec->bsp_bo[comm_seq % NOUVEAU_VP3_VIDEO_QDEPTH] = bsp_bo = tmp_bo;<br>
> + dec->bsp_bo[comm_seq % NOUVEAU_VP3_VIDEO_QDEPTH] = bsp_bo = tmp_bo;<br>
> +<br>
> + /* update position to current chunk */<br>
> + dec->bsp_ptr = bsp_bo->map + dec->bsp_size;<br>
<br>
</span>Instead of keeping the bsp_size around (which I'm moderately sure<br>
you're not doing *quite* right), you can just do (before freeing the<br>
old bsp bo):<br>
<br>
dec->bsp_ptr = tmp_bo->map + (dec->bsp_ptr - bsp_bo->map);<br>
<br>
That will avoid the double bookkeeping between dec->bsp_ptr and dec->bsp_size.<br></blockquote><div><br></div><div>Good idea thx.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<span><br>
> }<br>
><br>
> if (!inter_bo || bsp_bo->size * 4 > inter_bo->size) {<br>
> @@ -104,18 +112,62 @@ nvc0_decoder_bsp(struct nouveau_vp3_decoder *dec, union pipe_desc desc,<br>
> inter_bo ? (unsigned)inter_bo->size : 0, (unsigned)bsp_bo->size * 4, ret);<br>
> return -1;<br>
> }<br>
> +<br>
> + ret = nouveau_bo_map(tmp_bo, NOUVEAU_BO_WR, dec->client);<br>
> + if (ret) {<br>
> + debug_printf("map failed: %i %s\n", ret, strerror(-ret));<br>
> + return -1;<br>
> + }<br>
> +<br>
> + /* Preserve previous buffer. */<br>
> + memcpy(tmp_bo->map, inter_bo->map, bsp_bo->size * 4);<br>
<br>
</span>Isn't bsp_bo->size * 4 the new size? You want to copy over the old<br>
size's worth of data. But AFAIK, the contents can be uninitialized for<br>
the inter_bo... I don't think this is necessary in the first place.<br></blockquote><div><br></div><div>Yes you are right it is the new size. But as you said I'll skip this, I did not know at the time I did it. Then I left it over.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div><div><br>
> +<br>
> nouveau_bo_ref(NULL, &inter_bo);<br>
> - bo_refs[1].bo = dec->inter_bo[comm_seq & 1] = inter_bo = tmp_bo;<br>
> + dec->inter_bo[comm_seq & 1] = inter_bo = tmp_bo;<br>
> }<br>
><br>
> - ret = nouveau_bo_map(bsp_bo, NOUVEAU_BO_WR, dec->client);<br>
> - if (ret) {<br>
> - debug_printf("map failed: %i %s\n", ret, strerror(-ret));<br>
> - return -1;<br>
> - }<br>
> + dec->bsp_size = bsp_size - 256;<br>
><br>
> - nouveau_vp3_bsp_begin(dec);<br>
> nouveau_vp3_bsp_next(dec, num_buffers, data, num_bytes);<br>
> +<br>
> + return 2;<br>
> +}<br>
> +<br>
> +<br>
> +unsigned<br>
> +nvc0_decoder_bsp_end(struct nouveau_vp3_decoder *dec, union pipe_desc desc,<br>
> + struct nouveau_vp3_video_buffer *target, unsigned comm_seq,<br>
> + unsigned *vp_caps, unsigned *is_ref,<br>
> + struct nouveau_vp3_video_buffer *refs[16])<br>
> +{<br>
> + struct nouveau_pushbuf *push = dec->pushbuf[0];<br>
> + enum pipe_video_format codec = u_reduce_video_profile(dec->base.profile);<br>
> + uint32_t bsp_addr, comm_addr, inter_addr;<br>
> + uint32_t slice_size, bucket_size, ring_size;<br>
> + uint32_t caps = 0;<br>
> + struct nouveau_bo *bsp_bo = dec->bsp_bo[comm_seq % NOUVEAU_VP3_VIDEO_QDEPTH];<br>
> + struct nouveau_bo *inter_bo = dec->inter_bo[comm_seq & 1];<br>
> + unsigned fence_extra = 0;<br>
> + struct nouveau_pushbuf_refn bo_refs[] = {<br>
> + { bsp_bo, NOUVEAU_BO_RD | NOUVEAU_BO_VRAM },<br>
> + { inter_bo, NOUVEAU_BO_WR | NOUVEAU_BO_VRAM },<br>
> +#if NOUVEAU_VP3_DEBUG_FENCE<br>
> + { dec->fence_bo, NOUVEAU_BO_WR | NOUVEAU_BO_GART },<br>
> +#endif<br>
> + { dec->bitplane_bo, NOUVEAU_BO_RDWR | NOUVEAU_BO_VRAM },<br>
> + };<br>
> + int num_refs = ARRAY_SIZE(bo_refs);<br>
> +<br>
> + if (!dec->bitplane_bo)<br>
> + num_refs--;<br>
> +<br>
> +#if NOUVEAU_VP3_DEBUG_FENCE<br>
> + fence_extra = 4;<br>
> +#endif<br>
> +<br>
> + bo_refs[0].bo = dec->bsp_bo[comm_seq % NOUVEAU_VP3_VIDEO_QDEPTH];<br>
> + bo_refs[1].bo = dec->inter_bo[comm_seq & 1];<br>
<br>
</div></div>I don't get it... what's the point of these?<br></blockquote><div><br></div><div>Me too ! I see now this is unnecessarry since they aere initialized with the right pointers, which was not the case before in the case of reallocation.<br></div><div>I'll just remove these 2 lines.<br></div><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div><div><br>
> +<br>
> caps = nouveau_vp3_bsp_end(dec, desc);<br>
><br>
> nouveau_vp3_vp_caps(dec, desc, target, comm_seq, vp_caps, is_ref, refs);<br>
> --<br>
> 1.9.1<br>
><br>
_______________________________________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org" target="_blank">mesa-dev@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">http://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
</div></div></blockquote></div><br></div></div>