<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>