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