[Mesa-dev] [PATCH 2/2] st/va: Implement vaExportSurfaceHandle()

2017-10-15 Thread Mark Thompson
This is a new interface in libva 2.1 to support wider use-cases of passing
surfaces to external APIs.  In particular, this allows export of NV12 and
P010 surfaces.

v2: Convert surfaces to progressive before exporting them (Christian).

v3: Set destination rectangle to match source when converting (Leo).
Add guards to allow building with libva1.

v4: Adjust target version - this is no longer in libva 2.0.

Signed-off-by: Mark Thompson 
---
(Testing only for now, not to be applied yet.)


 src/gallium/state_trackers/va/context.c|   5 +-
 src/gallium/state_trackers/va/surface.c| 148 +
 src/gallium/state_trackers/va/va_private.h |   1 +
 3 files changed, 153 insertions(+), 1 deletion(-)

diff --git a/src/gallium/state_trackers/va/context.c 
b/src/gallium/state_trackers/va/context.c
index f2cb37aa22..8ba0af11ea 100644
--- a/src/gallium/state_trackers/va/context.c
+++ b/src/gallium/state_trackers/va/context.c
@@ -88,7 +88,10 @@ static struct VADriverVTable vtable =
,
,
,
-   
+   ,
+#if VA_CHECK_VERSION(1, 0, 1)
+   ,
+#endif
 };
 
 static struct VADriverVTableVPP vtable_vpp =
diff --git a/src/gallium/state_trackers/va/surface.c 
b/src/gallium/state_trackers/va/surface.c
index 4c2f4b5452..013914ac0e 100644
--- a/src/gallium/state_trackers/va/surface.c
+++ b/src/gallium/state_trackers/va/surface.c
@@ -44,6 +44,7 @@
 #include "va_private.h"
 
 #include 
+#include 
 
 static const enum pipe_format vpp_surface_formats[] = {
PIPE_FORMAT_B8G8R8A8_UNORM, PIPE_FORMAT_R8G8B8A8_UNORM,
@@ -901,3 +902,150 @@ vlVaQueryVideoProcPipelineCaps(VADriverContextP ctx, 
VAContextID context,
 
return VA_STATUS_SUCCESS;
 }
+
+#if VA_CHECK_VERSION(1, 0, 1)
+VAStatus
+vlVaExportSurfaceHandle(VADriverContextP ctx,
+VASurfaceID surface_id,
+uint32_t mem_type,
+uint32_t flags,
+void *descriptor)
+{
+   vlVaDriver *drv;
+   vlVaSurface *surf;
+   struct pipe_surface **surfaces;
+   struct pipe_screen *screen;
+   VAStatus ret;
+   unsigned int usage;
+   int i, p;
+
+   VADRMPRIMESurfaceDescriptor *desc = descriptor;
+
+   if (mem_type != VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2)
+  return VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE;
+   if (flags & VA_EXPORT_SURFACE_COMPOSED_LAYERS)
+  return VA_STATUS_ERROR_INVALID_SURFACE;
+
+   drv= VL_VA_DRIVER(ctx);
+   screen = VL_VA_PSCREEN(ctx);
+   mtx_lock(>mutex);
+
+   surf = handle_table_get(drv->htab, surface_id);
+   if (!surf || !surf->buffer) {
+  mtx_unlock(>mutex);
+  return VA_STATUS_ERROR_INVALID_SURFACE;
+   }
+
+   if (surf->buffer->interlaced) {
+  struct pipe_video_buffer *interlaced = surf->buffer;
+  struct u_rect src_rect, dst_rect;
+
+  surf->templat.interlaced = false;
+
+  ret = vlVaHandleSurfaceAllocate(drv, surf, >templat);
+  if (ret != VA_STATUS_SUCCESS) {
+ mtx_unlock(>mutex);
+ return VA_STATUS_ERROR_ALLOCATION_FAILED;
+  }
+
+  src_rect.x0 = dst_rect.x0 = 0;
+  src_rect.y0 = dst_rect.y0 = 0;
+  src_rect.x1 = dst_rect.x1 = surf->templat.width;
+  src_rect.y1 = dst_rect.y1 = surf->templat.height;
+
+  vl_compositor_yuv_deint_full(>cstate, >compositor,
+   interlaced, surf->buffer,
+   _rect, _rect,
+   VL_COMPOSITOR_WEAVE);
+
+  interlaced->destroy(interlaced);
+   }
+
+   surfaces = surf->buffer->get_surfaces(surf->buffer);
+
+   usage = 0;
+   if (flags & VA_EXPORT_SURFACE_READ_ONLY)
+  usage |= PIPE_HANDLE_USAGE_READ;
+   if (flags & VA_EXPORT_SURFACE_WRITE_ONLY)
+  usage |= PIPE_HANDLE_USAGE_WRITE;
+
+   desc->fourcc = PipeFormatToVaFourcc(surf->buffer->buffer_format);
+   desc->width  = surf->buffer->width;
+   desc->height = surf->buffer->height;
+
+   for (p = 0; p < VL_MAX_SURFACES; p++) {
+  struct winsys_handle whandle;
+  struct pipe_resource *resource;
+  uint32_t drm_format;
+
+  if (!surfaces[p])
+ break;
+
+  resource = surfaces[p]->texture;
+
+  switch (resource->format) {
+  case PIPE_FORMAT_R8_UNORM:
+ drm_format = DRM_FORMAT_R8;
+ break;
+  case PIPE_FORMAT_R8G8_UNORM:
+ drm_format = DRM_FORMAT_GR88;
+ break;
+  case PIPE_FORMAT_R16_UNORM:
+ drm_format = DRM_FORMAT_R16;
+ break;
+  case PIPE_FORMAT_R16G16_UNORM:
+ drm_format = DRM_FORMAT_GR1616;
+ break;
+  case PIPE_FORMAT_B8G8R8A8_UNORM:
+ drm_format = DRM_FORMAT_ARGB;
+ break;
+  case PIPE_FORMAT_R8G8B8A8_UNORM:
+ drm_format = DRM_FORMAT_ABGR;
+ break;
+  case PIPE_FORMAT_B8G8R8X8_UNORM:
+ drm_format = DRM_FORMAT_XRGB;
+ break;
+  case PIPE_FORMAT_R8G8B8X8_UNORM:
+ drm_format = DRM_FORMAT_XBGR;
+ break;
+  default:
+ ret = 

Re: [Mesa-dev] [PATCH 2/2] st/va: Implement vaExportSurfaceHandle()

2017-10-10 Thread Leo Liu



On 10/07/2017 01:22 PM, Mark Thompson wrote:

On 07/10/17 15:23, Leo Liu wrote:

On 2017-10-01 01:40 PM, Mark Thompson wrote:

This is a new interface in libva2 to support wider use-cases of passing
surfaces to external APIs.  In particular, this allows export of NV12 and
P010 surfaces.

v2: Convert surfaces to progressive before exporting them (Christian).

v3: Set destination rectangle to match source when converting (Leo).
  Add guards to allow building with libva1.

Signed-off-by: Mark Thompson 

This patch is Acked-and-Tested-by: Leo Liu< leo@amd.com>, also pushed.

Thank you!

Can you look at (or direct me to who I should be pointing at) patch 1/2 as well?




  (Needed for the H.265 10-bit interop on the EGL side.)

Right.
The patch is Acked-by: Leo Liu 

I will commit it if there is no objection in a couple of days.

Thanks,
Leo




- Mark


___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH 2/2] st/va: Implement vaExportSurfaceHandle()

2017-10-07 Thread Mark Thompson
On 07/10/17 15:23, Leo Liu wrote:
> On 2017-10-01 01:40 PM, Mark Thompson wrote:
>> This is a new interface in libva2 to support wider use-cases of passing
>> surfaces to external APIs.  In particular, this allows export of NV12 and
>> P010 surfaces.
>>
>> v2: Convert surfaces to progressive before exporting them (Christian).
>>
>> v3: Set destination rectangle to match source when converting (Leo).
>>  Add guards to allow building with libva1.
>>
>> Signed-off-by: Mark Thompson 
> This patch is Acked-and-Tested-by: Leo Liu< leo@amd.com>, also pushed.

Thank you!

Can you look at (or direct me to who I should be pointing at) patch 1/2 as 
well?  (Needed for the H.265 10-bit interop on the EGL side.)

- Mark
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH 2/2] st/va: Implement vaExportSurfaceHandle()

2017-10-07 Thread Leo Liu



On 2017-10-01 01:40 PM, Mark Thompson wrote:

This is a new interface in libva2 to support wider use-cases of passing
surfaces to external APIs.  In particular, this allows export of NV12 and
P010 surfaces.

v2: Convert surfaces to progressive before exporting them (Christian).

v3: Set destination rectangle to match source when converting (Leo).
 Add guards to allow building with libva1.

Signed-off-by: Mark Thompson 

This patch is Acked-and-Tested-by: Leo Liu< leo@amd.com>, also pushed.

Regards,
Leo



---
  src/gallium/state_trackers/va/context.c|   5 +-
  src/gallium/state_trackers/va/surface.c| 148 +
  src/gallium/state_trackers/va/va_private.h |   1 +
  3 files changed, 153 insertions(+), 1 deletion(-)

diff --git a/src/gallium/state_trackers/va/context.c 
b/src/gallium/state_trackers/va/context.c
index f2cb37aa22..1207499a78 100644
--- a/src/gallium/state_trackers/va/context.c
+++ b/src/gallium/state_trackers/va/context.c
@@ -88,7 +88,10 @@ static struct VADriverVTable vtable =
 ,
 ,
 ,
-   
+   ,
+#if VA_CHECK_VERSION(1, 0, 0)
+   ,
+#endif
  };
  
  static struct VADriverVTableVPP vtable_vpp =

diff --git a/src/gallium/state_trackers/va/surface.c 
b/src/gallium/state_trackers/va/surface.c
index 643cdcd54a..e37b17b001 100644
--- a/src/gallium/state_trackers/va/surface.c
+++ b/src/gallium/state_trackers/va/surface.c
@@ -44,6 +44,7 @@
  #include "va_private.h"
  
  #include 

+#include 
  
  static const enum pipe_format vpp_surface_formats[] = {

 PIPE_FORMAT_B8G8R8A8_UNORM, PIPE_FORMAT_R8G8B8A8_UNORM,
@@ -889,3 +890,150 @@ vlVaQueryVideoProcPipelineCaps(VADriverContextP ctx, 
VAContextID context,
  
 return VA_STATUS_SUCCESS;

  }
+
+#if VA_CHECK_VERSION(1, 0, 0)
+VAStatus
+vlVaExportSurfaceHandle(VADriverContextP ctx,
+VASurfaceID surface_id,
+uint32_t mem_type,
+uint32_t flags,
+void *descriptor)
+{
+   vlVaDriver *drv;
+   vlVaSurface *surf;
+   struct pipe_surface **surfaces;
+   struct pipe_screen *screen;
+   VAStatus ret;
+   unsigned int usage;
+   int i, p;
+
+   VADRMPRIMESurfaceDescriptor *desc = descriptor;
+
+   if (mem_type != VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2)
+  return VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE;
+   if (flags & VA_EXPORT_SURFACE_COMPOSED_LAYERS)
+  return VA_STATUS_ERROR_INVALID_SURFACE;
+
+   drv= VL_VA_DRIVER(ctx);
+   screen = VL_VA_PSCREEN(ctx);
+   mtx_lock(>mutex);
+
+   surf = handle_table_get(drv->htab, surface_id);
+   if (!surf || !surf->buffer) {
+  mtx_unlock(>mutex);
+  return VA_STATUS_ERROR_INVALID_SURFACE;
+   }
+
+   if (surf->buffer->interlaced) {
+  struct pipe_video_buffer *interlaced = surf->buffer;
+  struct u_rect src_rect, dst_rect;
+
+  surf->templat.interlaced = false;
+
+  ret = vlVaHandleSurfaceAllocate(drv, surf, >templat);
+  if (ret != VA_STATUS_SUCCESS) {
+ mtx_unlock(>mutex);
+ return VA_STATUS_ERROR_ALLOCATION_FAILED;
+  }
+
+  src_rect.x0 = dst_rect.x0 = 0;
+  src_rect.y0 = dst_rect.y0 = 0;
+  src_rect.x1 = dst_rect.x1 = surf->templat.width;
+  src_rect.y1 = dst_rect.y1 = surf->templat.height;
+
+  vl_compositor_yuv_deint_full(>cstate, >compositor,
+   interlaced, surf->buffer,
+   _rect, _rect,
+   VL_COMPOSITOR_WEAVE);
+
+  interlaced->destroy(interlaced);
+   }
+
+   surfaces = surf->buffer->get_surfaces(surf->buffer);
+
+   usage = 0;
+   if (flags & VA_EXPORT_SURFACE_READ_ONLY)
+  usage |= PIPE_HANDLE_USAGE_READ;
+   if (flags & VA_EXPORT_SURFACE_WRITE_ONLY)
+  usage |= PIPE_HANDLE_USAGE_WRITE;
+
+   desc->fourcc = PipeFormatToVaFourcc(surf->buffer->buffer_format);
+   desc->width  = surf->buffer->width;
+   desc->height = surf->buffer->height;
+
+   for (p = 0; p < VL_MAX_SURFACES; p++) {
+  struct winsys_handle whandle;
+  struct pipe_resource *resource;
+  uint32_t drm_format;
+
+  if (!surfaces[p])
+ break;
+
+  resource = surfaces[p]->texture;
+
+  switch (resource->format) {
+  case PIPE_FORMAT_R8_UNORM:
+ drm_format = DRM_FORMAT_R8;
+ break;
+  case PIPE_FORMAT_R8G8_UNORM:
+ drm_format = DRM_FORMAT_GR88;
+ break;
+  case PIPE_FORMAT_R16_UNORM:
+ drm_format = DRM_FORMAT_R16;
+ break;
+  case PIPE_FORMAT_R16G16_UNORM:
+ drm_format = DRM_FORMAT_GR1616;
+ break;
+  case PIPE_FORMAT_B8G8R8A8_UNORM:
+ drm_format = DRM_FORMAT_ARGB;
+ break;
+  case PIPE_FORMAT_R8G8B8A8_UNORM:
+ drm_format = DRM_FORMAT_ABGR;
+ break;
+  case PIPE_FORMAT_B8G8R8X8_UNORM:
+ drm_format = DRM_FORMAT_XRGB;
+ break;
+  case PIPE_FORMAT_R8G8B8X8_UNORM:
+ drm_format = DRM_FORMAT_XBGR;
+   

[Mesa-dev] [PATCH 2/2] st/va: Implement vaExportSurfaceHandle()

2017-10-01 Thread Mark Thompson
This is a new interface in libva2 to support wider use-cases of passing
surfaces to external APIs.  In particular, this allows export of NV12 and
P010 surfaces.

v2: Convert surfaces to progressive before exporting them (Christian).

v3: Set destination rectangle to match source when converting (Leo).
Add guards to allow building with libva1.

Signed-off-by: Mark Thompson 
---
 src/gallium/state_trackers/va/context.c|   5 +-
 src/gallium/state_trackers/va/surface.c| 148 +
 src/gallium/state_trackers/va/va_private.h |   1 +
 3 files changed, 153 insertions(+), 1 deletion(-)

diff --git a/src/gallium/state_trackers/va/context.c 
b/src/gallium/state_trackers/va/context.c
index f2cb37aa22..1207499a78 100644
--- a/src/gallium/state_trackers/va/context.c
+++ b/src/gallium/state_trackers/va/context.c
@@ -88,7 +88,10 @@ static struct VADriverVTable vtable =
,
,
,
-   
+   ,
+#if VA_CHECK_VERSION(1, 0, 0)
+   ,
+#endif
 };
 
 static struct VADriverVTableVPP vtable_vpp =
diff --git a/src/gallium/state_trackers/va/surface.c 
b/src/gallium/state_trackers/va/surface.c
index 643cdcd54a..e37b17b001 100644
--- a/src/gallium/state_trackers/va/surface.c
+++ b/src/gallium/state_trackers/va/surface.c
@@ -44,6 +44,7 @@
 #include "va_private.h"
 
 #include 
+#include 
 
 static const enum pipe_format vpp_surface_formats[] = {
PIPE_FORMAT_B8G8R8A8_UNORM, PIPE_FORMAT_R8G8B8A8_UNORM,
@@ -889,3 +890,150 @@ vlVaQueryVideoProcPipelineCaps(VADriverContextP ctx, 
VAContextID context,
 
return VA_STATUS_SUCCESS;
 }
+
+#if VA_CHECK_VERSION(1, 0, 0)
+VAStatus
+vlVaExportSurfaceHandle(VADriverContextP ctx,
+VASurfaceID surface_id,
+uint32_t mem_type,
+uint32_t flags,
+void *descriptor)
+{
+   vlVaDriver *drv;
+   vlVaSurface *surf;
+   struct pipe_surface **surfaces;
+   struct pipe_screen *screen;
+   VAStatus ret;
+   unsigned int usage;
+   int i, p;
+
+   VADRMPRIMESurfaceDescriptor *desc = descriptor;
+
+   if (mem_type != VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2)
+  return VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE;
+   if (flags & VA_EXPORT_SURFACE_COMPOSED_LAYERS)
+  return VA_STATUS_ERROR_INVALID_SURFACE;
+
+   drv= VL_VA_DRIVER(ctx);
+   screen = VL_VA_PSCREEN(ctx);
+   mtx_lock(>mutex);
+
+   surf = handle_table_get(drv->htab, surface_id);
+   if (!surf || !surf->buffer) {
+  mtx_unlock(>mutex);
+  return VA_STATUS_ERROR_INVALID_SURFACE;
+   }
+
+   if (surf->buffer->interlaced) {
+  struct pipe_video_buffer *interlaced = surf->buffer;
+  struct u_rect src_rect, dst_rect;
+
+  surf->templat.interlaced = false;
+
+  ret = vlVaHandleSurfaceAllocate(drv, surf, >templat);
+  if (ret != VA_STATUS_SUCCESS) {
+ mtx_unlock(>mutex);
+ return VA_STATUS_ERROR_ALLOCATION_FAILED;
+  }
+
+  src_rect.x0 = dst_rect.x0 = 0;
+  src_rect.y0 = dst_rect.y0 = 0;
+  src_rect.x1 = dst_rect.x1 = surf->templat.width;
+  src_rect.y1 = dst_rect.y1 = surf->templat.height;
+
+  vl_compositor_yuv_deint_full(>cstate, >compositor,
+   interlaced, surf->buffer,
+   _rect, _rect,
+   VL_COMPOSITOR_WEAVE);
+
+  interlaced->destroy(interlaced);
+   }
+
+   surfaces = surf->buffer->get_surfaces(surf->buffer);
+
+   usage = 0;
+   if (flags & VA_EXPORT_SURFACE_READ_ONLY)
+  usage |= PIPE_HANDLE_USAGE_READ;
+   if (flags & VA_EXPORT_SURFACE_WRITE_ONLY)
+  usage |= PIPE_HANDLE_USAGE_WRITE;
+
+   desc->fourcc = PipeFormatToVaFourcc(surf->buffer->buffer_format);
+   desc->width  = surf->buffer->width;
+   desc->height = surf->buffer->height;
+
+   for (p = 0; p < VL_MAX_SURFACES; p++) {
+  struct winsys_handle whandle;
+  struct pipe_resource *resource;
+  uint32_t drm_format;
+
+  if (!surfaces[p])
+ break;
+
+  resource = surfaces[p]->texture;
+
+  switch (resource->format) {
+  case PIPE_FORMAT_R8_UNORM:
+ drm_format = DRM_FORMAT_R8;
+ break;
+  case PIPE_FORMAT_R8G8_UNORM:
+ drm_format = DRM_FORMAT_GR88;
+ break;
+  case PIPE_FORMAT_R16_UNORM:
+ drm_format = DRM_FORMAT_R16;
+ break;
+  case PIPE_FORMAT_R16G16_UNORM:
+ drm_format = DRM_FORMAT_GR1616;
+ break;
+  case PIPE_FORMAT_B8G8R8A8_UNORM:
+ drm_format = DRM_FORMAT_ARGB;
+ break;
+  case PIPE_FORMAT_R8G8B8A8_UNORM:
+ drm_format = DRM_FORMAT_ABGR;
+ break;
+  case PIPE_FORMAT_B8G8R8X8_UNORM:
+ drm_format = DRM_FORMAT_XRGB;
+ break;
+  case PIPE_FORMAT_R8G8B8X8_UNORM:
+ drm_format = DRM_FORMAT_XBGR;
+ break;
+  default:
+ ret = VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE;
+ goto fail;
+  }
+
+  memset(, 0, sizeof(whandle));
+  

Re: [Mesa-dev] [PATCH 2/2] st/va: Implement vaExportSurfaceHandle()

2017-09-22 Thread Christian König

Am 21.09.2017 um 21:00 schrieb Mark Thompson:

On 20/09/17 09:14, Christian König wrote:

Am 20.09.2017 um 00:01 schrieb Mark Thompson:

This is a new interface in libva2 to support wider use-cases of passing
surfaces to external APIs.  In particular, this allows export of NV12 and
P010 surfaces.

First of all thanks a lot for taking care of this.


Signed-off-by: Mark Thompson 
---
Trivial update for a minor change requested on libva side (1/2 identical).

Still unsure on what to do about size and interlacing.  I'll have a look at the 
postproc code just posted soon, though I think it's pretty much entirely 
orthogonal to this.

Probably best to convert the interlaced representation into the progressive 
form before exporting.

I'd prefer not to do that, because a use-case of this is to be able to modify 
surfaces in-place.  (E.g. decode, scale, export, blend something else onto the 
surface, fence, encode.)


My suggesting is to change the backing store of the surface while it is 
exported. So in place modifications should work and if the surface is 
then reused for decoding it will directly decode to the progressive format.


But in place modification is NOT something I would recommend here 
anyway. Video surfaces can of course be read and written by the 3D 
block, but it certainly isn't in any ideal memory layout for rendering.


Just copying it into a new surface while you compose things is usually 
way faster.



Only alternative I can think of is to define new DRM 
formats/modifiers/attributes, but then the application needs to be aware of 
this as well.

I'm not really sure what form that would need to take.  The modifiers are meant 
for something else importing the surfaces, so what would support it and how?  
That would also require keeping the format part the same, I think (so an NV12 
surface would still be an R8 plane and a GR88 plane, but with some modifier 
meaning it is actually present as two fields).


That sounds similar to what I had in mind as well.


It could work with the current construction by adding a way to indicate the 
surface is interlaced with separate fields.  For NV12 it would then export four 
handles, one for each field of each plane.


Actually that won't be the case. You still have one handle for each 
plane, the format is actually that of a 2D array texture where you can 
select in the sampler if you want to sample from the top or bottom field.



   mpv at least should be able to handle this (there is already support for 
something similar for some nvidia vdpau cases),


The reason for this is that this is actually the more common format for 
(embedded) hardware decoders. It just doesn't have a fourcc assigned 
(AFAIK) and isn't used by Intel, so no support in VA-API.



  but I don't know how acceptable that would be to other users.  Certainly it 
would be quite a lot harder to modify a surface in-place in a sensible way with 
that setup.

I'm still unconvinced by the comments in the other thread about using 
interlaced surfaces by default - a lot of things would be easier if progressive 
were the default, and I have yet to find any case this actually fails in.


The reason why we use this interlaced memory layout by default is that 
it our deinterlacers only work with this format where you have separate 
top and bottom fields.


Regards,
Christian.



Thanks,

- Mark



___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH 2/2] st/va: Implement vaExportSurfaceHandle()

2017-09-21 Thread Mark Thompson
On 20/09/17 09:14, Christian König wrote:
> Am 20.09.2017 um 00:01 schrieb Mark Thompson:
>> This is a new interface in libva2 to support wider use-cases of passing
>> surfaces to external APIs.  In particular, this allows export of NV12 and
>> P010 surfaces.
> 
> First of all thanks a lot for taking care of this.
> 
>> Signed-off-by: Mark Thompson 
>> ---
>> Trivial update for a minor change requested on libva side (1/2 identical).
>>
>> Still unsure on what to do about size and interlacing.  I'll have a look at 
>> the postproc code just posted soon, though I think it's pretty much entirely 
>> orthogonal to this.
> 
> Probably best to convert the interlaced representation into the progressive 
> form before exporting.

I'd prefer not to do that, because a use-case of this is to be able to modify 
surfaces in-place.  (E.g. decode, scale, export, blend something else onto the 
surface, fence, encode.)

> Only alternative I can think of is to define new DRM 
> formats/modifiers/attributes, but then the application needs to be aware of 
> this as well.

I'm not really sure what form that would need to take.  The modifiers are meant 
for something else importing the surfaces, so what would support it and how?  
That would also require keeping the format part the same, I think (so an NV12 
surface would still be an R8 plane and a GR88 plane, but with some modifier 
meaning it is actually present as two fields).

It could work with the current construction by adding a way to indicate the 
surface is interlaced with separate fields.  For NV12 it would then export four 
handles, one for each field of each plane.  mpv at least should be able to 
handle this (there is already support for something similar for some nvidia 
vdpau cases), but I don't know how acceptable that would be to other users.  
Certainly it would be quite a lot harder to modify a surface in-place in a 
sensible way with that setup.

I'm still unconvinced by the comments in the other thread about using 
interlaced surfaces by default - a lot of things would be easier if progressive 
were the default, and I have yet to find any case this actually fails in.

Thanks,

- Mark
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH 2/2] st/va: Implement vaExportSurfaceHandle()

2017-09-20 Thread Christian König

Am 20.09.2017 um 00:01 schrieb Mark Thompson:

This is a new interface in libva2 to support wider use-cases of passing
surfaces to external APIs.  In particular, this allows export of NV12 and
P010 surfaces.


First of all thanks a lot for taking care of this.


Signed-off-by: Mark Thompson 
---
Trivial update for a minor change requested on libva side (1/2 identical).

Still unsure on what to do about size and interlacing.  I'll have a look at the 
postproc code just posted soon, though I think it's pretty much entirely 
orthogonal to this.


Probably best to convert the interlaced representation into the 
progressive form before exporting.


Only alternative I can think of is to define new DRM 
formats/modifiers/attributes, but then the application needs to be aware 
of this as well.


Anyway patch is Acked-by: Christian König  for 
now.


Regards,
Christian.



Thanks,

- Mark


  src/gallium/state_trackers/va/context.c|   3 +-
  src/gallium/state_trackers/va/surface.c| 121 +
  src/gallium/state_trackers/va/va_private.h |   1 +
  3 files changed, 124 insertions(+), 1 deletion(-)

diff --git a/src/gallium/state_trackers/va/context.c 
b/src/gallium/state_trackers/va/context.c
index f2cb37aa22..2794e5c733 100644
--- a/src/gallium/state_trackers/va/context.c
+++ b/src/gallium/state_trackers/va/context.c
@@ -88,7 +88,8 @@ static struct VADriverVTable vtable =
 ,
 ,
 ,
-   
+   ,
+   
  };
  
  static struct VADriverVTableVPP vtable_vpp =

diff --git a/src/gallium/state_trackers/va/surface.c 
b/src/gallium/state_trackers/va/surface.c
index 67773cf76a..b4ae5b3c34 100644
--- a/src/gallium/state_trackers/va/surface.c
+++ b/src/gallium/state_trackers/va/surface.c
@@ -44,6 +44,7 @@
  #include "va_private.h"
  
  #include 

+#include 
  
  static const enum pipe_format vpp_surface_formats[] = {

 PIPE_FORMAT_B8G8R8A8_UNORM, PIPE_FORMAT_R8G8B8A8_UNORM,
@@ -892,3 +893,123 @@ vlVaQueryVideoProcPipelineCaps(VADriverContextP ctx, 
VAContextID context,
  
 return VA_STATUS_SUCCESS;

  }
+
+VAStatus
+vlVaExportSurfaceHandle(VADriverContextP ctx,
+VASurfaceID surface_id,
+uint32_t mem_type,
+uint32_t flags,
+void *descriptor)
+{
+   vlVaDriver *drv;
+   vlVaSurface *surf;
+   struct pipe_surface **surfaces;
+   struct pipe_screen *screen;
+   VAStatus ret;
+   unsigned int usage;
+   int i, p;
+
+   VADRMPRIMESurfaceDescriptor *desc = descriptor;
+
+   if (mem_type != VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2)
+  return VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE;
+   if (flags & VA_EXPORT_SURFACE_COMPOSED_LAYERS)
+  return VA_STATUS_ERROR_INVALID_SURFACE;
+
+   drv= VL_VA_DRIVER(ctx);
+   screen = VL_VA_PSCREEN(ctx);
+   mtx_lock(>mutex);
+
+   surf = handle_table_get(drv->htab, surface_id);
+   if (!surf || !surf->buffer) {
+  mtx_unlock(>mutex);
+  return VA_STATUS_ERROR_INVALID_SURFACE;
+   }
+
+   surfaces = surf->buffer->get_surfaces(surf->buffer);
+
+   usage = 0;
+   if (flags & VA_EXPORT_SURFACE_READ_ONLY)
+  usage |= PIPE_HANDLE_USAGE_READ;
+   if (flags & VA_EXPORT_SURFACE_WRITE_ONLY)
+  usage |= PIPE_HANDLE_USAGE_WRITE;
+
+   desc->fourcc = PipeFormatToVaFourcc(surf->buffer->buffer_format);
+   desc->width  = surf->buffer->width;
+   desc->height = surf->buffer->height;
+
+   for (p = 0; p < VL_MAX_SURFACES; p++) {
+  struct winsys_handle whandle;
+  struct pipe_resource *resource;
+  uint32_t drm_format;
+
+  if (!surfaces[p])
+ break;
+
+  resource = surfaces[p]->texture;
+
+  switch (resource->format) {
+  case PIPE_FORMAT_R8_UNORM:
+ drm_format = DRM_FORMAT_R8;
+ break;
+  case PIPE_FORMAT_R8G8_UNORM:
+ drm_format = DRM_FORMAT_GR88;
+ break;
+  case PIPE_FORMAT_R16_UNORM:
+ drm_format = DRM_FORMAT_R16;
+ break;
+  case PIPE_FORMAT_R16G16_UNORM:
+ drm_format = DRM_FORMAT_GR1616;
+ break;
+  case PIPE_FORMAT_B8G8R8A8_UNORM:
+ drm_format = DRM_FORMAT_ARGB;
+ break;
+  case PIPE_FORMAT_R8G8B8A8_UNORM:
+ drm_format = DRM_FORMAT_ABGR;
+ break;
+  case PIPE_FORMAT_B8G8R8X8_UNORM:
+ drm_format = DRM_FORMAT_XRGB;
+ break;
+  case PIPE_FORMAT_R8G8B8X8_UNORM:
+ drm_format = DRM_FORMAT_XBGR;
+ break;
+  default:
+ ret = VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE;
+ goto fail;
+  }
+
+  memset(, 0, sizeof(whandle));
+  whandle.type = DRM_API_HANDLE_TYPE_FD;
+
+  if (!screen->resource_get_handle(screen, drv->pipe, resource,
+   , usage)) {
+ ret = VA_STATUS_ERROR_INVALID_SURFACE;
+ goto fail;
+  }
+
+  desc->objects[p].fd   = (int)whandle.handle;
+  desc->objects[p].size = 0;
+  

[Mesa-dev] [PATCH 2/2] st/va: Implement vaExportSurfaceHandle()

2017-09-19 Thread Mark Thompson
This is a new interface in libva2 to support wider use-cases of passing
surfaces to external APIs.  In particular, this allows export of NV12 and
P010 surfaces.

Signed-off-by: Mark Thompson 
---
Trivial update for a minor change requested on libva side (1/2 identical).

Still unsure on what to do about size and interlacing.  I'll have a look at the 
postproc code just posted soon, though I think it's pretty much entirely 
orthogonal to this.

Thanks,

- Mark


 src/gallium/state_trackers/va/context.c|   3 +-
 src/gallium/state_trackers/va/surface.c| 121 +
 src/gallium/state_trackers/va/va_private.h |   1 +
 3 files changed, 124 insertions(+), 1 deletion(-)

diff --git a/src/gallium/state_trackers/va/context.c 
b/src/gallium/state_trackers/va/context.c
index f2cb37aa22..2794e5c733 100644
--- a/src/gallium/state_trackers/va/context.c
+++ b/src/gallium/state_trackers/va/context.c
@@ -88,7 +88,8 @@ static struct VADriverVTable vtable =
,
,
,
-   
+   ,
+   
 };
 
 static struct VADriverVTableVPP vtable_vpp =
diff --git a/src/gallium/state_trackers/va/surface.c 
b/src/gallium/state_trackers/va/surface.c
index 67773cf76a..b4ae5b3c34 100644
--- a/src/gallium/state_trackers/va/surface.c
+++ b/src/gallium/state_trackers/va/surface.c
@@ -44,6 +44,7 @@
 #include "va_private.h"
 
 #include 
+#include 
 
 static const enum pipe_format vpp_surface_formats[] = {
PIPE_FORMAT_B8G8R8A8_UNORM, PIPE_FORMAT_R8G8B8A8_UNORM,
@@ -892,3 +893,123 @@ vlVaQueryVideoProcPipelineCaps(VADriverContextP ctx, 
VAContextID context,
 
return VA_STATUS_SUCCESS;
 }
+
+VAStatus
+vlVaExportSurfaceHandle(VADriverContextP ctx,
+VASurfaceID surface_id,
+uint32_t mem_type,
+uint32_t flags,
+void *descriptor)
+{
+   vlVaDriver *drv;
+   vlVaSurface *surf;
+   struct pipe_surface **surfaces;
+   struct pipe_screen *screen;
+   VAStatus ret;
+   unsigned int usage;
+   int i, p;
+
+   VADRMPRIMESurfaceDescriptor *desc = descriptor;
+
+   if (mem_type != VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2)
+  return VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE;
+   if (flags & VA_EXPORT_SURFACE_COMPOSED_LAYERS)
+  return VA_STATUS_ERROR_INVALID_SURFACE;
+
+   drv= VL_VA_DRIVER(ctx);
+   screen = VL_VA_PSCREEN(ctx);
+   mtx_lock(>mutex);
+
+   surf = handle_table_get(drv->htab, surface_id);
+   if (!surf || !surf->buffer) {
+  mtx_unlock(>mutex);
+  return VA_STATUS_ERROR_INVALID_SURFACE;
+   }
+
+   surfaces = surf->buffer->get_surfaces(surf->buffer);
+
+   usage = 0;
+   if (flags & VA_EXPORT_SURFACE_READ_ONLY)
+  usage |= PIPE_HANDLE_USAGE_READ;
+   if (flags & VA_EXPORT_SURFACE_WRITE_ONLY)
+  usage |= PIPE_HANDLE_USAGE_WRITE;
+
+   desc->fourcc = PipeFormatToVaFourcc(surf->buffer->buffer_format);
+   desc->width  = surf->buffer->width;
+   desc->height = surf->buffer->height;
+
+   for (p = 0; p < VL_MAX_SURFACES; p++) {
+  struct winsys_handle whandle;
+  struct pipe_resource *resource;
+  uint32_t drm_format;
+
+  if (!surfaces[p])
+ break;
+
+  resource = surfaces[p]->texture;
+
+  switch (resource->format) {
+  case PIPE_FORMAT_R8_UNORM:
+ drm_format = DRM_FORMAT_R8;
+ break;
+  case PIPE_FORMAT_R8G8_UNORM:
+ drm_format = DRM_FORMAT_GR88;
+ break;
+  case PIPE_FORMAT_R16_UNORM:
+ drm_format = DRM_FORMAT_R16;
+ break;
+  case PIPE_FORMAT_R16G16_UNORM:
+ drm_format = DRM_FORMAT_GR1616;
+ break;
+  case PIPE_FORMAT_B8G8R8A8_UNORM:
+ drm_format = DRM_FORMAT_ARGB;
+ break;
+  case PIPE_FORMAT_R8G8B8A8_UNORM:
+ drm_format = DRM_FORMAT_ABGR;
+ break;
+  case PIPE_FORMAT_B8G8R8X8_UNORM:
+ drm_format = DRM_FORMAT_XRGB;
+ break;
+  case PIPE_FORMAT_R8G8B8X8_UNORM:
+ drm_format = DRM_FORMAT_XBGR;
+ break;
+  default:
+ ret = VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE;
+ goto fail;
+  }
+
+  memset(, 0, sizeof(whandle));
+  whandle.type = DRM_API_HANDLE_TYPE_FD;
+
+  if (!screen->resource_get_handle(screen, drv->pipe, resource,
+   , usage)) {
+ ret = VA_STATUS_ERROR_INVALID_SURFACE;
+ goto fail;
+  }
+
+  desc->objects[p].fd   = (int)whandle.handle;
+  desc->objects[p].size = 0;
+  desc->objects[p].drm_format_modifier = whandle.modifier;
+
+  desc->layers[p].drm_format  = drm_format;
+  desc->layers[p].num_planes  = 1;
+  desc->layers[p].object_index[0] = p;
+  desc->layers[p].offset[0]   = whandle.offset;
+  desc->layers[p].pitch[0]= whandle.stride;
+   }
+
+   desc->num_objects  = p;
+   desc->num_layers   = p;
+
+   mtx_unlock(>mutex);
+
+   return VA_STATUS_SUCCESS;
+
+fail:
+   for (i = 0; i < p; i++)
+  

[Mesa-dev] [PATCH 2/2] st/va: Implement vaExportSurfaceHandle()

2017-09-17 Thread Mark Thompson
This is a new interface in libva2 to support wider use-cases of passing
surfaces to external APIs.  In particular, this allows export of NV12 and
P010 surfaces.

Signed-off-by: Mark Thompson 
---
This implements a new interface I am proposing for libva2, which will allow 
export to work properly with Mesa - see 
.

I have it working for GPU-only playback in mpv through EGL (previously this 
always required a download/upload step).  See 
 
for a tree containing changes to make this work.

Some outstanding things to consider:
* I've defined the API to include the size of each object.  This is because 
some import APIs require it - libva itself does, though the more obvious case 
is Beignet 
().  I'm 
not currently filling it because I don't see any way to get the actual object 
size through existing interfaces.  Thoughts?
* I haven't implemented the composite-object export form at all.  I don't 
currently know of any use case for it - the Intel use-case is for passing NV12 
scanout buffers to KMS, but this doesn't appear to be a thing in amdgpu 
(scanout is 32-bit RGB only).
* It interacts badly with the interlacing feature.  It seems to work correctly 
for 10-bit but not for 8-bit video?  I have reapplied the 
VAAPI_DISABLE_INTERLACE patch locally to make it work for me in all cases, 
though I believe there is more work in progress in this area which can 
hopefully clarify the issue.

Thanks,

- Mark


 src/gallium/state_trackers/va/context.c|   3 +-
 src/gallium/state_trackers/va/surface.c| 118 +
 src/gallium/state_trackers/va/va_private.h |   1 +
 3 files changed, 121 insertions(+), 1 deletion(-)

diff --git a/src/gallium/state_trackers/va/context.c 
b/src/gallium/state_trackers/va/context.c
index f2cb37aa22..2794e5c733 100644
--- a/src/gallium/state_trackers/va/context.c
+++ b/src/gallium/state_trackers/va/context.c
@@ -88,7 +88,8 @@ static struct VADriverVTable vtable =
,
,
,
-   
+   ,
+   
 };
 
 static struct VADriverVTableVPP vtable_vpp =
diff --git a/src/gallium/state_trackers/va/surface.c 
b/src/gallium/state_trackers/va/surface.c
index 67773cf76a..0fb0180377 100644
--- a/src/gallium/state_trackers/va/surface.c
+++ b/src/gallium/state_trackers/va/surface.c
@@ -44,6 +44,7 @@
 #include "va_private.h"
 
 #include 
+#include 
 
 static const enum pipe_format vpp_surface_formats[] = {
PIPE_FORMAT_B8G8R8A8_UNORM, PIPE_FORMAT_R8G8B8A8_UNORM,
@@ -892,3 +893,120 @@ vlVaQueryVideoProcPipelineCaps(VADriverContextP ctx, 
VAContextID context,
 
return VA_STATUS_SUCCESS;
 }
+
+VAStatus vlVaExportSurfaceHandle(VADriverContextP ctx,
+ VASurfaceID surface_id,
+ uint32_t mem_type,
+ uint32_t flags,
+ void *descriptor)
+{
+   vlVaDriver *drv;
+   vlVaSurface *surf;
+   struct pipe_surface **surfaces;
+   struct pipe_screen *screen;
+   VAStatus ret;
+   unsigned int usage;
+   int i, p;
+
+   VADRMPRIMESurfaceDescriptor *desc = descriptor;
+
+   if (mem_type != VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2)
+  return VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE;
+   if (flags & VA_EXPORT_SURFACE_COMPOSED_LAYERS)
+  return VA_STATUS_ERROR_INVALID_SURFACE;
+
+   drv= VL_VA_DRIVER(ctx);
+   screen = VL_VA_PSCREEN(ctx);
+   mtx_lock(>mutex);
+
+   surf = handle_table_get(drv->htab, surface_id);
+   if (!surf || !surf->buffer) {
+  mtx_unlock(>mutex);
+  return VA_STATUS_ERROR_INVALID_SURFACE;
+   }
+
+   surfaces = surf->buffer->get_surfaces(surf->buffer);
+
+   usage = 0;
+   if (flags & VA_EXPORT_SURFACE_READ_ONLY)
+  usage |= PIPE_HANDLE_USAGE_READ;
+   if (flags & VA_EXPORT_SURFACE_WRITE_ONLY)
+  usage |= PIPE_HANDLE_USAGE_WRITE;
+
+   desc->fourcc = PipeFormatToVaFourcc(surf->buffer->buffer_format);
+
+   for (p = 0; p < VL_MAX_SURFACES; p++) {
+  struct winsys_handle whandle;
+  struct pipe_resource *resource;
+  uint32_t drm_format;
+
+  if (!surfaces[p])
+ break;
+
+  resource = surfaces[p]->texture;
+
+  switch (resource->format) {
+  case PIPE_FORMAT_R8_UNORM:
+ drm_format = DRM_FORMAT_R8;
+ break;
+  case PIPE_FORMAT_R8G8_UNORM:
+ drm_format = DRM_FORMAT_GR88;
+ break;
+  case PIPE_FORMAT_R16_UNORM:
+ drm_format = DRM_FORMAT_R16;
+ break;
+  case PIPE_FORMAT_R16G16_UNORM:
+ drm_format = DRM_FORMAT_GR1616;
+ break;
+  case PIPE_FORMAT_B8G8R8A8_UNORM:
+ drm_format = DRM_FORMAT_ARGB;
+ break;
+  case PIPE_FORMAT_R8G8B8A8_UNORM:
+ drm_format = DRM_FORMAT_ABGR;
+ break;
+  case PIPE_FORMAT_B8G8R8X8_UNORM:
+ drm_format = DRM_FORMAT_XRGB;
+