Am 02.06.2016 um 16:00 schrieb Julien Isorce:
In order to do zero-copy between two different devices
the memory should not be tiled.

This is currently no way to set pipe_resource template's flag
from pipe_video_buffer template. So disabled_tiling is added.

Choosed "disable" prefix so that CALLOC keeps tiling enabled
by default.

Tested with GStreamer on a laptop that has 2 GPUs:
1- gstvaapidecode:
    HW decoding and dmabuf export with nouveau driver on Nvidia GPU.
2- glimagesink:
    EGLImage imports dmabuf on Intel GPU.

Note that tiling is working if 1 and 2 are done on the same GPU.
So it is up to the application to set or not the flag:
VA_SURFACE_EXTBUF_DESC_ENABLE_TILING

Signed-off-by: Julien Isorce <j.iso...@samsung.com>

NAK, it won't be possible to use the resulting video buffer with hardware decoding on AMD hardware.

Please add a bind flag to struct pipe_video_buffer instead so that we can specify if linear layout is requested or not.

This way the hardware driver can still reject the request if this would result in a surface which can't be decoded to.

Regards,
Christian.

---
  src/gallium/state_trackers/va/surface.c | 60 ++++++++++++++++++++++++++++++++-
  1 file changed, 59 insertions(+), 1 deletion(-)

diff --git a/src/gallium/state_trackers/va/surface.c 
b/src/gallium/state_trackers/va/surface.c
index 8a6a397..b04ced4 100644
--- a/src/gallium/state_trackers/va/surface.c
+++ b/src/gallium/state_trackers/va/surface.c
@@ -507,7 +507,9 @@ vlVaCreateSurfaces2(VADriverContextP ctx, unsigned int 
format,
     int i;
     int memory_type;
     int expected_fourcc;
+   int linear_layout;
     VAStatus vaStatus;
+   const enum pipe_format *resource_formats;
if (!ctx)
        return VA_STATUS_ERROR_INVALID_CONTEXT;
@@ -529,6 +531,7 @@ vlVaCreateSurfaces2(VADriverContextP ctx, unsigned int 
format,
     memory_attibute = NULL;
     memory_type = VA_SURFACE_ATTRIB_MEM_TYPE_VA;
     expected_fourcc = 0;
+   resource_formats = NULL;
for (i = 0; i < num_attribs && attrib_list; i++) {
        if ((attrib_list[i].type == VASurfaceAttribPixelFormat) &&
@@ -569,8 +572,27 @@ vlVaCreateSurfaces2(VADriverContextP ctx, unsigned int 
format,
        return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
     }
+ /* The application will clear the TILING flag when the surface is
+    * intended to be exported as dmabuf. */
+   linear_layout = memory_attibute &&
+      !(memory_attibute->flags & VA_SURFACE_EXTBUF_DESC_ENABLE_TILING);
+
     switch (memory_type) {
     case VA_SURFACE_ATTRIB_MEM_TYPE_VA:
+      if (linear_layout) {
+         switch (expected_fourcc) {
+            case VA_FOURCC_RGBA:
+            case VA_FOURCC_RGBX:
+            case VA_FOURCC_BGRA:
+            case VA_FOURCC_BGRX:
+               if (memory_attibute->num_planes != 1)
+                  return VA_STATUS_ERROR_INVALID_PARAMETER;
+               break;
+            default:
+               return VA_STATUS_ERROR_INVALID_PARAMETER;
+         }
+      }
+
        break;
     case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME:
        if (!memory_attibute)
@@ -587,6 +609,13 @@ vlVaCreateSurfaces2(VADriverContextP ctx, unsigned int 
format,
     if (expected_fourcc) {
        templat.buffer_format = VaFourccToPipeFormat(expected_fourcc);
        templat.interlaced = 0;
+
+      if (linear_layout) {
+         resource_formats = vl_video_buffer_formats(pscreen,
+                                                    templat.buffer_format);
+         if (!resource_formats)
+            return VA_STATUS_ERROR_INVALID_PARAMETER;
+      }
     } else {
        templat.buffer_format = pscreen->get_video_param
              (
@@ -621,7 +650,36 @@ vlVaCreateSurfaces2(VADriverContextP ctx, unsigned int 
format,
switch (memory_type) {
        case VA_SURFACE_ATTRIB_MEM_TYPE_VA:
-         surf->buffer = drv->pipe->create_video_buffer(drv->pipe, &templat);
+         if (linear_layout) {
+            struct pipe_resource resource_template;
+            struct pipe_resource *resources[VL_NUM_COMPONENTS];
+            int depth = 1;
+            int array_size = 1;
+
+            memset(resources, 0, sizeof(resources));
+
+            assert(resource_formats);
+            vl_video_buffer_template(&resource_template, &templat,
+                                     resource_formats[0], depth, array_size,
+                                     PIPE_USAGE_DEFAULT, 0);
+
+            /* Shared because VASurfaceAttribExternalBuffers is used. */
+            assert(memory_attibute);
+            resource_template.bind |= PIPE_BIND_LINEAR | PIPE_BIND_SHARED;
+
+            resources[0] = pscreen->resource_create(pscreen,
+                                                    &resource_template);
+            if (!resources[0]) {
+                FREE(surf);
+                goto no_res;
+            }
+
+            surf->buffer = vl_video_buffer_create_ex2(drv->pipe, &templat,
+                                                      resources);
+         } else {
+            surf->buffer = drv->pipe->create_video_buffer(drv->pipe, &templat);
+         }
+
           if (!surf->buffer) {
              FREE(surf);
              goto no_res;

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

Reply via email to