<div dir="ltr"><br><br><div class="gmail_quote"><div dir="ltr">On Wed, Aug 29, 2018 at 4:38 PM Gurchetan Singh <<a href="mailto:gurchetansingh@chromium.org">gurchetansingh@chromium.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Good idea, we do need a way to handle YUV buffers.  IIRC zachr@+ also<br>
ran into the limitations of DRM_IOCTL_VIRTGPU_RESOURCE_CREATE.  Maybe<br>
a DRM_IOCTL_VIRTGPU_RESOURCE_CREATE2 that handles:<br>
<br>
- YUV formats<br>
- format modifiers<br>
- stride<br>
<br>
is warranted.<br></blockquote><div>I am not sure about "format modifiers" since actually I don't know what's that. But I think it's possible to</div><div>handle multi planar format and stride in current  DRM_IOCTL_VIRTGPU_RESOURCE_CREATE ioctl.</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
On Wed, Aug 29, 2018 at 1:40 PM Lepton Wu <<a href="mailto:lepton@chromium.org" target="_blank">lepton@chromium.org</a>> wrote:<br>
><br>
> On Wed, Aug 29, 2018 at 1:23 PM Lepton Wu <<a href="mailto:lepton@chromium.org" target="_blank">lepton@chromium.org</a>> wrote:<br>
> ><br>
> > On Wed, Aug 29, 2018 at 1:15 PM Lepton Wu <<a href="mailto:lepton@chromium.org" target="_blank">lepton@chromium.org</a>> wrote:<br>
> > ><br>
> > > With this and other necessary patches to kernel, mesa etc, video player<br>
> > > under android can play videos with YV12 format under virgl + qemu.<br>
> > Patches for kerne/mesa/minigbm can be found here for your reference.<br>
> ><br>
> > kernel: <a href="https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/1194613" rel="noreferrer" target="_blank">https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/1194613</a><br>
> > mesa:  <a href="https://chromium-review.googlesource.com/c/chromiumos/third_party/mesa/+/1195011" rel="noreferrer" target="_blank">https://chromium-review.googlesource.com/c/chromiumos/third_party/mesa/+/1195011</a><br>
> > minigbm: <a href="https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/1195587" rel="noreferrer" target="_blank">https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/1195587</a><br>
> BTW,  currently drm_virtgpu_resource_create doesn't really use stride<br>
> info even it has a stride field.<br>
> This information is needed since android  has some alignment<br>
> requirement for yv12 format.<br>
> I think this could be addressed by a separate CL to kernel.<br>
> ><br>
> > My plan is to get virglrenderer change done first since I could get<br>
> > comments/suggestion  to change interface or<br>
> > even implementation detail. After virglrender side change done here ,<br>
> > then I will send patch to upstream kernel,<br>
> > then mesa, minigbm. Also perhaps libdrm since I could get suggestion<br>
> > for adding new ioctl. Now I am trying to<br>
> > reuse some old ioctl.<br>
> ><br>
> > > The basic idea is:<br>
> > > DRM_IOCTL_VIRTGPU_RESOURCE_CREATE can be used to create additional planes<br>
> > > at some offset of an existed bo. Every plane is backed by a host side texture.<br>
> > > When guest try to get res_handle for an existed bo, it will get the actual<br>
> > > res_handle for that plane by checking offset.<br>
> > > ---<br>
> > >  src/virgl_hw.h       |  1 +<br>
> > >  src/virglrenderer.h  | 12 +++++++--<br>
> > >  src/vrend_renderer.c | 64 ++++++++++++++++++++++++++++++++++++++++++++<br>
> > >  src/vrend_renderer.h | 26 ++++++++++++++++--<br>
> > >  4 files changed, 99 insertions(+), 4 deletions(-)<br>
> > ><br>
> > > diff --git a/src/virgl_hw.h b/src/virgl_hw.h<br>
> > > index 4add191..e8df498 100644<br>
> > > --- a/src/virgl_hw.h<br>
> > > +++ b/src/virgl_hw.h<br>
> > > @@ -342,4 +342,5 @@ enum virgl_ctx_errors {<br>
> > ><br>
> > ><br>
> > >  #define VIRGL_RESOURCE_Y_0_TOP (1 << 0)<br>
> > > +#define VIRGL_RESOURCE_PLANE (1 << 1)<br>
> > >  #endif<br>
> > > diff --git a/src/virglrenderer.h b/src/virglrenderer.h<br>
> > > index 5baecdd..c41523d 100644<br>
> > > --- a/src/virglrenderer.h<br>
> > > +++ b/src/virglrenderer.h<br>
> > > @@ -93,8 +93,16 @@ VIRGL_EXPORT int virgl_renderer_get_fd_for_texture2(uint32_t tex_id, int *fd, in<br>
> > ><br>
> > >  struct virgl_renderer_resource_create_args {<br>
> > >     uint32_t handle;<br>
> > > -   uint32_t target;<br>
> > > -   uint32_t format;<br>
> > > +   union {<br>
> > > +      struct {<br>
> > > +         uint32_t target;<br>
> > > +         uint32_t format;<br>
> > > +      };<br>
> > > +      struct {<br>
> > > +         uint32_t main_res;<br>
> > > +         uint32_t offset;<br>
> > > +      } plane;<br>
> > > +   };<br>
> > >     uint32_t bind;<br>
> > >     uint32_t width;<br>
> > >     uint32_t height;<br>
> > > diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c<br>
> > > index 4086abd..b38b37e 100644<br>
> > > --- a/src/vrend_renderer.c<br>
> > > +++ b/src/vrend_renderer.c<br>
> > > @@ -5144,10 +5144,50 @@ static int vrend_renderer_resource_allocate_texture(struct vrend_resource *gr,<br>
> > >     return 0;<br>
> > >  }<br>
> > ><br>
> > > +static int check_plane_valid(struct vrend_renderer_resource_create_args *args,<br>
> > > +                             struct vrend_renderer_resource_create_args<br>
> > > +                             *plane_args, struct vrend_plane_resource** pr) {<br>
> > > +   struct vrend_resource *res;<br>
> > > +   res = vrend_resource_lookup(args->plane.main_res, 0);<br>
> > > +   if (!res)<br>
> > > +      return -1;<br>
> > > +   *plane_args = *args;<br>
> > > +   /* Assume same target/format for sub planes */<br>
> > > +   plane_args->target = res->base.target;<br>
> > > +   plane_args->format = res->base.format;<br>
> > > +   plane_args->flags &= ~VIRGL_RESOURCE_PLANE;<br>
> > > +   for (int i = 0; i < VR_MAX_SUB_PLANES; ++i) {<br>
> > > +      // Only support to add planes in order to make life simple.<br>
> > > +      if (args->plane.offset <= res->planes[i].offset) {<br>
> > > +         fprintf(stderr, "Add planes in wrong order\n");<br>
> > > +         return -1;<br>
> > > +      }<br>
> > > +      if (res->planes[i].offset == 0) {<br>
> > > +         *pr = &res->planes[i];<br>
> > > +         return 0;<br>
> > > +      }<br>
> > > +   }<br>
> > > +   return -1;<br>
> > > +}<br>
> > > +<br>
> > >  int vrend_renderer_resource_create(struct vrend_renderer_resource_create_args *args, struct iovec *iov, uint32_t num_iovs, void *image_oes)<br>
> > >  {<br>
> > >     struct vrend_resource *gr;<br>
> > >     int ret;<br>
> > > +   struct vrend_renderer_resource_create_args plane_args;<br>
> > > +   struct vrend_plane_resource *pr;<br>
> > > +<br>
> > > +   if (args->flags & VIRGL_RESOURCE_PLANE) {<br>
> > > +      ret = check_plane_valid(args, &plane_args, &pr);<br>
> > > +      if (ret)<br>
> > > +         return EINVAL;<br>
> > > +      ret = vrend_renderer_resource_create(&plane_args, iov, num_iovs, image_oes);<br>
> > > +      if (ret == 0) {<br>
> > > +         pr->handle = args->handle;<br>
> > > +         pr->offset = args->plane.offset;<br>
> > > +      }<br>
> > > +      return ret;<br>
> > > +   }<br>
> > ><br>
> > >     ret = check_resource_valid(args);<br>
> > >     if (ret)<br>
> > > @@ -6067,6 +6107,22 @@ int vrend_renderer_transfer_iov(const struct vrend_transfer_info *info,<br>
> > >        return EINVAL;<br>
> > >     }<br>
> > ><br>
> > > +   /* If this is a request for sub planes, read/write sub planes.<br>
> > > +    */<br>
> > > +   struct vrend_plane_resource* plane = NULL;<br>
> > > +   for (int i = 0; i < VR_MAX_SUB_PLANES && res->planes[i].offset; i++) {<br>
> > > +      if (info->offset >= res->planes[i].offset)<br>
> > > +         plane = &res->planes[i];<br>
> > > +   }<br>
> > > +   if (plane) {<br>
> > > +      struct vrend_transfer_info tmp;<br>
> > > +      tmp = *info;<br>
> > > +      tmp.handle = plane->handle;<br>
> > > +      tmp.iovec = iov;<br>
> > > +      tmp.iovec_cnt = num_iovs;<br>
> > > +      return vrend_renderer_transfer_iov(&tmp, transfer_mode);<br>
> > > +   }<br>
> > > +<br>
> > >     if (!check_transfer_bounds(res, info))<br>
> > >        return EINVAL;<br>
> > ><br>
> > > @@ -7886,6 +7942,10 @@ void vrend_renderer_attach_res_ctx(int ctx_id, int resource_id)<br>
> > >        return;<br>
> > ><br>
> > >     vrend_object_insert_nofree(ctx->res_hash, res, sizeof(*res), resource_id, 1, false);<br>
> > > +<br>
> > > +   for (int i = 0; i < VR_MAX_SUB_PLANES && res->planes[i].offset; ++i) {<br>
> > > +      vrend_renderer_attach_res_ctx(ctx_id, res->planes[i].handle);<br>
> > > +   }<br>
> > >  }<br>
> > ><br>
> > >  static void vrend_renderer_detach_res_ctx_p(struct vrend_context *ctx, int res_handle)<br>
> > > @@ -7895,6 +7955,10 @@ static void vrend_renderer_detach_res_ctx_p(struct vrend_context *ctx, int res_h<br>
> > >     if (!res)<br>
> > >        return;<br>
> > ><br>
> > > +   for (int i = 0; i < VR_MAX_SUB_PLANES && res->planes[i].offset; ++i) {<br>
> > > +      vrend_renderer_detach_res_ctx_p(ctx, res->planes[i].handle);<br>
> > > +   }<br>
> > > +<br>
> > >     vrend_object_remove(ctx->res_hash, res_handle, 1);<br>
> > >  }<br>
> > ><br>
> > > diff --git a/src/vrend_renderer.h b/src/vrend_renderer.h<br>
> > > index bb76b44..21dceb6 100644<br>
> > > --- a/src/vrend_renderer.h<br>
> > > +++ b/src/vrend_renderer.h<br>
> > > @@ -49,6 +49,19 @@ struct vrend_context;<br>
> > >   */<br>
> > >  #define VR_MAX_TEXTURE_2D_LEVELS 15<br>
> > ><br>
> > > +/* For multi-planar formats like YV12, we just use vrend_resource for the first<br>
> > > + * plane as "main" vrend_resource and embed information for additional planes<br>
> > > + * as "sub" planes in "main" vrend_resource. So for YV12, we only need 2 "sub"<br>
> > > + * planes.<br>
> > > + */<br>
> > > +#define VR_MAX_SUB_PLANES 2<br>
> > > +<br>
> > > +struct vrend_plane_resource {<br>
> > > +  GLuint handle;<br>
> > > +  uint32_t offset;<br>
> > > +  uint32_t size;<br>
> > > +};<br>
> > > +<br>
> > >  struct vrend_resource {<br>
> > >     struct pipe_resource base;<br>
> > >     GLuint id;<br>
> > > @@ -68,6 +81,7 @@ struct vrend_resource {<br>
> > >     struct iovec *iov;<br>
> > >     uint32_t num_iovs;<br>
> > >     uint64_t mipmap_offsets[VR_MAX_TEXTURE_2D_LEVELS];<br>
> > > +   struct vrend_plane_resource planes[VR_MAX_SUB_PLANES];<br>
> > >  };<br>
> > ><br>
> > >  /* assume every format is sampler friendly */<br>
> > > @@ -160,8 +174,16 @@ void vrend_renderer_context_destroy(uint32_t handle);<br>
> > ><br>
> > >  struct vrend_renderer_resource_create_args {<br>
> > >     uint32_t handle;<br>
> > > -   enum pipe_texture_target target;<br>
> > > -   uint32_t format;<br>
> > > +   union {<br>
> > > +      struct {<br>
> > > +         enum pipe_texture_target target;<br>
> > > +         uint32_t format;<br>
> > > +      };<br>
> > > +      struct {<br>
> > > +         uint32_t main_res;<br>
> > > +         uint32_t offset;<br>
> > > +      } plane;<br>
> > > +   };<br>
> > >     uint32_t bind;<br>
> > >     uint32_t width;<br>
> > >     uint32_t height;<br>
> > > --<br>
> > > 2.19.0.rc0.228.g281dcd1b4d0-goog<br>
> > ><br>
> _______________________________________________<br>
> virglrenderer-devel mailing list<br>
> <a href="mailto:virglrenderer-devel@lists.freedesktop.org" target="_blank">virglrenderer-devel@lists.freedesktop.org</a><br>
> <a href="https://lists.freedesktop.org/mailman/listinfo/virglrenderer-devel" rel="noreferrer" target="_blank">https://lists.freedesktop.org/mailman/listinfo/virglrenderer-devel</a><br>
</blockquote></div></div>