<div dir="ltr">This patch is missing "memset(&templat, 0, sizeof(templat));" so I am going to submit a v3 for this one.<br></div><div class="gmail_extra"><br><div class="gmail_quote">On 20 October 2015 at 17:34, Julien Isorce <span dir="ltr"><<a href="mailto:j.isorce@samsung.com" target="_blank">j.isorce@samsung.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Inspired from <a href="http://cgit.freedesktop.org/vaapi/intel-driver/" rel="noreferrer" target="_blank">http://cgit.freedesktop.org/vaapi/intel-driver/</a><br>
especially src/i965_drv_video.c::i965_CreateSurfaces2.<br>
<br>
This patch is mainly to support gstreamer-vaapi and tools that uses<br>
this newer libva API. The first advantage of using VaCreateSurfaces2<br>
over existing VaCreateSurfaces, is that it is possible to select which<br>
the pixel format for the surface. Indeed with the simple VaCreateSurfaces<br>
function it is only possible to create a NV12 surface. It can be useful<br>
to create a RGBA surface to use with video post processing.<br>
<br>
The avaible pixel formats can be query with VaQuerySurfaceAttributes.<br>
<br>
Signed-off-by: Julien Isorce <<a href="mailto:j.isorce@samsung.com">j.isorce@samsung.com</a>><br>
---<br>
 src/gallium/state_trackers/va/context.c    |   5 +-<br>
 src/gallium/state_trackers/va/surface.c    | 294 ++++++++++++++++++++++++-----<br>
 src/gallium/state_trackers/va/va_private.h |   6 +-<br>
 3 files changed, 253 insertions(+), 52 deletions(-)<br>
<br>
diff --git a/src/gallium/state_trackers/va/context.c b/src/gallium/state_trackers/va/context.c<br>
index 8b003ae..9be9085 100644<br>
--- a/src/gallium/state_trackers/va/context.c<br>
+++ b/src/gallium/state_trackers/va/context.c<br>
@@ -81,7 +81,10 @@ static struct VADriverVTable vtable =<br>
    &vlVaSetDisplayAttributes,<br>
    &vlVaBufferInfo,<br>
    &vlVaLockSurface,<br>
-   &vlVaUnlockSurface<br>
+   &vlVaUnlockSurface,<br>
+   NULL, /* DEPRECATED VaGetSurfaceAttributes */<br>
+   &vlVaCreateSurfaces2,<br>
+   &vlVaQuerySurfaceAttributes<br>
 };<br>
<br>
 PUBLIC VAStatus<br>
diff --git a/src/gallium/state_trackers/va/surface.c b/src/gallium/state_trackers/va/surface.c<br>
index 8d4487b..62fdf3c 100644<br>
--- a/src/gallium/state_trackers/va/surface.c<br>
+++ b/src/gallium/state_trackers/va/surface.c<br>
@@ -36,6 +36,7 @@<br>
 #include "util/u_surface.h"<br>
<br>
 #include "vl/vl_compositor.h"<br>
+#include "vl/vl_video_buffer.h"<br>
 #include "vl/vl_winsys.h"<br>
<br>
 #include "va_private.h"<br>
@@ -44,56 +45,8 @@ VAStatus<br>
 vlVaCreateSurfaces(VADriverContextP ctx, int width, int height, int format,<br>
                    int num_surfaces, VASurfaceID *surfaces)<br>
 {<br>
-   struct pipe_video_buffer templat = {};<br>
-   struct pipe_screen *pscreen;<br>
-   vlVaDriver *drv;<br>
-   int i;<br>
-<br>
-   if (!ctx)<br>
-      return VA_STATUS_ERROR_INVALID_CONTEXT;<br>
-<br>
-   if (!(width && height))<br>
-      return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT;<br>
-<br>
-   drv = VL_VA_DRIVER(ctx);<br>
-   pscreen = VL_VA_PSCREEN(ctx);<br>
-<br>
-   templat.buffer_format = pscreen->get_video_param<br>
-   (<br>
-      pscreen,<br>
-      PIPE_VIDEO_PROFILE_UNKNOWN,<br>
-      PIPE_VIDEO_ENTRYPOINT_BITSTREAM,<br>
-      PIPE_VIDEO_CAP_PREFERED_FORMAT<br>
-   );<br>
-   templat.chroma_format = ChromaToPipe(format);<br>
-   templat.width = width;<br>
-   templat.height = height;<br>
-   templat.interlaced = pscreen->get_video_param<br>
-   (<br>
-      pscreen,<br>
-      PIPE_VIDEO_PROFILE_UNKNOWN,<br>
-      PIPE_VIDEO_ENTRYPOINT_BITSTREAM,<br>
-      PIPE_VIDEO_CAP_PREFERS_INTERLACED<br>
-   );<br>
-<br>
-   for (i = 0; i < num_surfaces; ++i) {<br>
-      vlVaSurface *surf = CALLOC(1, sizeof(vlVaSurface));<br>
-      if (!surf)<br>
-         goto no_res;<br>
-<br>
-      surf->templat = templat;<br>
-      surf->buffer = drv->pipe->create_video_buffer(drv->pipe, &templat);<br>
-      util_dynarray_init(&surf->subpics);<br>
-      surfaces[i] = handle_table_add(drv->htab, surf);<br>
-   }<br>
-<br>
-   return VA_STATUS_SUCCESS;<br>
-<br>
-no_res:<br>
-   if (i)<br>
-      vlVaDestroySurfaces(ctx, surfaces, i);<br>
-<br>
-   return VA_STATUS_ERROR_ALLOCATION_FAILED;<br>
+   return vlVaCreateSurfaces2(ctx, format, width, height, surfaces, num_surfaces,<br>
+                              NULL, 0);<br>
 }<br>
<br>
 VAStatus<br>
@@ -349,3 +302,244 @@ vlVaUnlockSurface(VADriverContextP ctx, VASurfaceID surface)<br>
<br>
    return VA_STATUS_ERROR_UNIMPLEMENTED;<br>
 }<br>
+<br>
+VAStatus<br>
+vlVaQuerySurfaceAttributes(VADriverContextP ctx, VAConfigID config,<br>
+                           VASurfaceAttrib *attrib_list, unsigned int *num_attribs)<br>
+{<br>
+    vlVaDriver *drv;<br>
+    VASurfaceAttrib *attribs;<br>
+    struct pipe_screen *pscreen;<br>
+    int i;<br>
+<br>
+    if (config == VA_INVALID_ID)<br>
+        return VA_STATUS_ERROR_INVALID_CONFIG;<br>
+<br>
+    if (!attrib_list && !num_attribs)<br>
+        return VA_STATUS_ERROR_INVALID_PARAMETER;<br>
+<br>
+    if (!attrib_list) {<br>
+        *num_attribs = VASurfaceAttribCount;<br>
+        return VA_STATUS_SUCCESS;<br>
+    }<br>
+<br>
+    if (!ctx)<br>
+       return VA_STATUS_ERROR_INVALID_CONTEXT;<br>
+<br>
+    drv = VL_VA_DRIVER(ctx);<br>
+<br>
+    if (!drv)<br>
+        return VA_STATUS_ERROR_INVALID_CONTEXT;<br>
+<br>
+    pscreen = VL_VA_PSCREEN(ctx);<br>
+<br>
+    if (!pscreen)<br>
+       return VA_STATUS_ERROR_INVALID_CONTEXT;<br>
+<br>
+    attribs = CALLOC(VASurfaceAttribCount, sizeof(VASurfaceAttrib));<br>
+<br>
+    if (!attribs)<br>
+        return VA_STATUS_ERROR_ALLOCATION_FAILED;<br>
+<br>
+    i = 0;<br>
+<br>
+    if (config == PIPE_VIDEO_PROFILE_UNKNOWN) {<br>
+       /* Assume VAEntrypointVideoProc for now. */<br>
+       attribs[i].type = VASurfaceAttribPixelFormat;<br>
+       attribs[i].value.type = VAGenericValueTypeInteger;<br>
+       attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;<br>
+       attribs[i].value.value.i = VA_FOURCC_BGRA;<br>
+       i++;<br>
+<br>
+       attribs[i].type = VASurfaceAttribPixelFormat;<br>
+       attribs[i].value.type = VAGenericValueTypeInteger;<br>
+       attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;<br>
+       attribs[i].value.value.i = VA_FOURCC_RGBA;<br>
+       i++;<br>
+    } else {<br>
+       /* Assume VAEntrypointVLD for now. */<br>
+       attribs[i].type = VASurfaceAttribPixelFormat;<br>
+       attribs[i].value.type = VAGenericValueTypeInteger;<br>
+       attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;<br>
+       attribs[i].value.value.i = VA_FOURCC_NV12;<br>
+       i++;<br>
+    }<br>
+<br>
+    attribs[i].type = VASurfaceAttribMemoryType;<br>
+    attribs[i].value.type = VAGenericValueTypeInteger;<br>
+    attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;<br>
+    attribs[i].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_VA;<br>
+    i++;<br>
+<br>
+    attribs[i].type = VASurfaceAttribExternalBufferDescriptor;<br>
+    attribs[i].value.type = VAGenericValueTypePointer;<br>
+    attribs[i].flags = VA_SURFACE_ATTRIB_SETTABLE;<br>
+    attribs[i].value.value.p = NULL; /* ignore */<br>
+    i++;<br>
+<br>
+    attribs[i].type = VASurfaceAttribMaxWidth;<br>
+    attribs[i].value.type = VAGenericValueTypeInteger;<br>
+    attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE;<br>
+    attribs[i].value.value.i = vl_video_buffer_max_size(pscreen);<br>
+    i++;<br>
+<br>
+    attribs[i].type = VASurfaceAttribMaxHeight;<br>
+    attribs[i].value.type = VAGenericValueTypeInteger;<br>
+    attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE;<br>
+    attribs[i].value.value.i = vl_video_buffer_max_size(pscreen);<br>
+    i++;<br>
+<br>
+    if (i > *num_attribs) {<br>
+        *num_attribs = i;<br>
+        FREE(attribs);<br>
+        return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;<br>
+    }<br>
+<br>
+    *num_attribs = i;<br>
+    memcpy(attrib_list, attribs, i * sizeof(VASurfaceAttrib));<br>
+    FREE(attribs);<br>
+<br>
+    return VA_STATUS_SUCCESS;<br>
+}<br>
+<br>
+VAStatus<br>
+vlVaCreateSurfaces2(VADriverContextP ctx, unsigned int format,<br>
+                    unsigned int width, unsigned int height,<br>
+                    VASurfaceID *surfaces, unsigned int num_surfaces,<br>
+                    VASurfaceAttrib *attrib_list, unsigned int num_attribs)<br>
+{<br>
+    vlVaDriver *drv;<br>
+    VASurfaceAttribExternalBuffers *memory_attibute;<br>
+    struct pipe_video_buffer templat;<br>
+    struct pipe_screen *pscreen;<br>
+    int i;<br>
+    int memory_type;<br>
+    int expected_fourcc;<br>
+<br>
+    if (!ctx)<br>
+       return VA_STATUS_ERROR_INVALID_CONTEXT;<br>
+<br>
+    if (!(width && height))<br>
+       return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT;<br>
+<br>
+    drv = VL_VA_DRIVER(ctx);<br>
+<br>
+    if (!drv)<br>
+        return VA_STATUS_ERROR_INVALID_CONTEXT;<br>
+<br>
+    pscreen = VL_VA_PSCREEN(ctx);<br>
+<br>
+    if (!pscreen)<br>
+        return VA_STATUS_ERROR_INVALID_CONTEXT;<br>
+<br>
+    /* Default. */<br>
+    memory_attibute = NULL;<br>
+    memory_type = VA_SURFACE_ATTRIB_MEM_TYPE_VA;<br>
+    expected_fourcc = 0;<br>
+<br>
+    for (i = 0; i < num_attribs && attrib_list; i++) {<br>
+        if ((attrib_list[i].type == VASurfaceAttribPixelFormat) &&<br>
+            (attrib_list[i].flags & VA_SURFACE_ATTRIB_SETTABLE)) {<br>
+            if (attrib_list[i].value.type != VAGenericValueTypeInteger)<br>
+                return VA_STATUS_ERROR_INVALID_PARAMETER;<br>
+            expected_fourcc = attrib_list[i].value.value.i;<br>
+        }<br>
+<br>
+        if ((attrib_list[i].type == VASurfaceAttribMemoryType) &&<br>
+            (attrib_list[i].flags & VA_SURFACE_ATTRIB_SETTABLE)) {<br>
+<br>
+            if (attrib_list[i].value.type != VAGenericValueTypeInteger)<br>
+                return VA_STATUS_ERROR_INVALID_PARAMETER;<br>
+<br>
+            switch (attrib_list[i].value.value.i) {<br>
+                case VA_SURFACE_ATTRIB_MEM_TYPE_VA:<br>
+                   memory_type = attrib_list[i].value.value.i;<br>
+                   break;<br>
+                default:<br>
+                   return VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE;<br>
+            }<br>
+        }<br>
+<br>
+        if ((attrib_list[i].type == VASurfaceAttribExternalBufferDescriptor) &&<br>
+            (attrib_list[i].flags == VA_SURFACE_ATTRIB_SETTABLE)) {<br>
+            if (attrib_list[i].value.type != VAGenericValueTypePointer)<br>
+                return VA_STATUS_ERROR_INVALID_PARAMETER;<br>
+            memory_attibute = (VASurfaceAttribExternalBuffers *)attrib_list[i].value.value.p;<br>
+        }<br>
+    }<br>
+<br>
+    if (VA_RT_FORMAT_YUV400 != format &&<br>
+        VA_RT_FORMAT_YUV420 != format &&<br>
+        VA_RT_FORMAT_YUV422 != format &&<br>
+        VA_RT_FORMAT_YUV444 != format &&<br>
+        VA_RT_FORMAT_RGB32  != format) {<br>
+        return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;<br>
+    }<br>
+<br>
+    switch (memory_type) {<br>
+        case VA_SURFACE_ATTRIB_MEM_TYPE_VA:<br>
+            if (memory_attibute)<br>
+               return VA_STATUS_ERROR_UNIMPLEMENTED;<br>
+            break;<br>
+        default:<br>
+            assert(0);<br>
+    }<br>
+<br>
+    if (expected_fourcc) {<br>
+       templat.buffer_format = YCbCrToPipe(expected_fourcc);<br>
+       templat.interlaced = 0;<br>
+    } else {<br>
+        templat.buffer_format = pscreen->get_video_param<br>
+        (<br>
+           pscreen,<br>
+           PIPE_VIDEO_PROFILE_UNKNOWN,<br>
+           PIPE_VIDEO_ENTRYPOINT_BITSTREAM,<br>
+           PIPE_VIDEO_CAP_PREFERED_FORMAT<br>
+        );<br>
+        templat.interlaced = pscreen->get_video_param<br>
+        (<br>
+           pscreen,<br>
+           PIPE_VIDEO_PROFILE_UNKNOWN,<br>
+           PIPE_VIDEO_ENTRYPOINT_BITSTREAM,<br>
+           PIPE_VIDEO_CAP_PREFERS_INTERLACED<br>
+        );<br>
+    }<br>
+<br>
+    if (format != VA_RT_FORMAT_RGB32)<br>
+       templat.chroma_format = ChromaToPipe(format);<br>
+<br>
+    templat.width = width;<br>
+    templat.height = height;<br>
+<br>
+    memset(surfaces, VA_INVALID_ID, num_surfaces * sizeof(VASurfaceID));<br>
+<br>
+    for (i = 0; i < num_surfaces; i++) {<br>
+        vlVaSurface *surf = CALLOC(1, sizeof(vlVaSurface));<br>
+        if (!surf)<br>
+            goto no_res;<br>
+<br>
+        surf->templat = templat;<br>
+<br>
+        switch (memory_type) {<br>
+            case VA_SURFACE_ATTRIB_MEM_TYPE_VA:<br>
+                surf->buffer = drv->pipe->create_video_buffer(drv->pipe, &templat);<br>
+                if (!surf->buffer)<br>
+                    goto no_res;<br>
+                util_dynarray_init(&surf->subpics);<br>
+                surfaces[i] = handle_table_add(drv->htab, surf);<br>
+                break;<br>
+            default:<br>
+                assert(0);<br>
+        }<br>
+    }<br>
+<br>
+    return VA_STATUS_SUCCESS;<br>
+<br>
+no_res:<br>
+   for (i = 0; i < num_surfaces; i++) {<br>
+      if (surfaces[i] != VA_INVALID_ID)<br>
+         vlVaDestroySurfaces(ctx, surfaces, i);<br>
+   }<br>
+<br>
+   return VA_STATUS_ERROR_ALLOCATION_FAILED;<br>
+}<br>
diff --git a/src/gallium/state_trackers/va/va_private.h b/src/gallium/state_trackers/va/va_private.h<br>
index 303b0c6..c0287e7 100644<br>
--- a/src/gallium/state_trackers/va/va_private.h<br>
+++ b/src/gallium/state_trackers/va/va_private.h<br>
@@ -311,5 +311,9 @@ VAStatus vlVaLockSurface(VADriverContextP ctx, VASurfaceID surface, unsigned int<br>
                          unsigned int *luma_offset, unsigned int *chroma_u_offset, unsigned int *chroma_v_offset,<br>
                          unsigned int *buffer_name, void **buffer);<br>
 VAStatus vlVaUnlockSurface(VADriverContextP ctx, VASurfaceID surface);<br>
-<br>
+VAStatus vlVaCreateSurfaces2(VADriverContextP ctx, unsigned int format, unsigned int width, unsigned int height,<br>
+                             VASurfaceID *surfaces, unsigned int num_surfaces, VASurfaceAttrib *attrib_list,<br>
+                             unsigned int num_attribs);<br>
+VAStatus vlVaQuerySurfaceAttributes(VADriverContextP ctx, VAConfigID config, VASurfaceAttrib *attrib_list,<br>
+                                    unsigned int *num_attribs);<br>
 #endif //VA_PRIVATE_H<br>
<span class="HOEnZb"><font color="#888888">--<br>
1.9.1<br>
<br>
_______________________________________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">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>
</font></span></blockquote></div><br></div>