From 2b296ec77c2b95e7632b45100de5a0878ac2a294 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Balling=20S=C3=B8rensen?= Date: Thu, 28 Oct 2010 22:46:28 +0200 Subject: [PATCH] vl: initial implementation of vlVaQueryImageFormats(), vlVaCreateImage(), vlVaQuerySubpictureFormats(), vlVaCreateSurfaces(), vlVaQueryConfigEntrypoints(), vlVaQueryConfigProfiles() --- src/gallium/state_trackers/va/ftab.c | 4 +- src/gallium/state_trackers/va/htab.c | 7 ++- src/gallium/state_trackers/va/va_config.c | 36 ++++++++++- src/gallium/state_trackers/va/va_context.c | 27 +++++++-- src/gallium/state_trackers/va/va_display.c | 6 +- src/gallium/state_trackers/va/va_image.c | 60 ++++++++++++++++++- src/gallium/state_trackers/va/va_picture.c | 1 + src/gallium/state_trackers/va/va_private.h | 24 ++++++++ src/gallium/state_trackers/va/va_subpicture.c | 20 +++---- src/gallium/state_trackers/va/va_surface.c | 49 ++++++++++++++- 10 files changed, 209 insertions(+), 25 deletions(-) diff --git a/src/gallium/state_trackers/va/ftab.c b/src/gallium/state_trackers/va/ftab.c index a567eee9dd1..999287e7a7e 100644 --- a/src/gallium/state_trackers/va/ftab.c +++ b/src/gallium/state_trackers/va/ftab.c @@ -30,6 +30,8 @@ #include #include "va_private.h" +struct VADriverVTable vlVaGetVtable(); + static struct VADriverVTable vtable = { &vlVaTerminate, /* VAStatus (*vaTerminate) ( VADriverContextP ctx ); */ @@ -125,7 +127,7 @@ static struct VADriverVTable vtable = unsigned int *buffer_name, void **buffer); */ &vlVaUnlockSurface, /* VAStatus (*vaUnlockSurface) (VADriverContextP ctx,VASurfaceID surface); */ - 0x44 /* struct VADriverVTableGLX *glx; "Optional" */ + NULL /* struct VADriverVTableGLX *glx; "Optional" */ }; struct VADriverVTable vlVaGetVtable() diff --git a/src/gallium/state_trackers/va/htab.c b/src/gallium/state_trackers/va/htab.c index 069c7930927..2187507c6a4 100644 --- a/src/gallium/state_trackers/va/htab.c +++ b/src/gallium/state_trackers/va/htab.c @@ -29,9 +29,10 @@ #include #include "va_private.h" -#define VL_HANDLES - -typedef uint32_t vlHandle; +boolean vlCreateHTAB(void); +void vlDestroyHTAB(void); +vlHandle vlAddDataHTAB(void *data); +void* vlGetDataHTAB(vlHandle handle); #ifdef VL_HANDLES static struct handle_table *htab = NULL; diff --git a/src/gallium/state_trackers/va/va_config.c b/src/gallium/state_trackers/va/va_config.c index 591d113a916..1589abf7cfa 100644 --- a/src/gallium/state_trackers/va/va_config.c +++ b/src/gallium/state_trackers/va/va_config.c @@ -27,6 +27,7 @@ #include #include +#include #include "va_private.h" VAStatus vlVaQueryConfigProfiles( VADriverContextP ctx, @@ -36,19 +37,48 @@ VAStatus vlVaQueryConfigProfiles( VADriverContextP ctx, if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; - return VA_STATUS_ERROR_UNIMPLEMENTED; + int i = 0; + + profile_list[i++] = VAProfileMPEG2Simple; + *num_profiles = i; + + return VA_STATUS_SUCCESS; } VAStatus vlVaQueryConfigEntrypoints( VADriverContextP ctx, VAProfile profile, - VAEntrypoint *entypoint_list, + VAEntrypoint *entrypoint_list, int *num_entrypoints) { if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; + + VAStatus vaStatus = VA_STATUS_SUCCESS; - return VA_STATUS_ERROR_UNIMPLEMENTED; + switch (profile) { + case VAProfileMPEG2Simple: + case VAProfileMPEG2Main: + VA_INFO("Using profile %08x\n",profile); + *num_entrypoints = 1; + entrypoint_list[0] = VAEntrypointMoComp; + break; + + case VAProfileH264Baseline: + case VAProfileH264Main: + case VAProfileH264High: + vaStatus = VA_STATUS_ERROR_UNSUPPORTED_PROFILE; + *num_entrypoints = 0; + break; + + default: + VA_ERROR("Unsupported profile %08x\n",profile); + vaStatus = VA_STATUS_ERROR_UNSUPPORTED_PROFILE; + *num_entrypoints = 0; + break; + } + + return vaStatus; } diff --git a/src/gallium/state_trackers/va/va_context.c b/src/gallium/state_trackers/va/va_context.c index 1e3ab9cb22e..cdb20cc0eb2 100644 --- a/src/gallium/state_trackers/va/va_context.c +++ b/src/gallium/state_trackers/va/va_context.c @@ -27,7 +27,10 @@ #include #include +#include +#include #include +#include #include #include #include "va_private.h" @@ -37,19 +40,35 @@ PUBLIC VAStatus __vaDriverInit_0_31 (VADriverContextP ctx) { + vlVaDriverContextPriv *driver_context = NULL; + if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; - + + + /* Create private driver context */ + driver_context = CALLOC(1,sizeof(vlVaDriverContextPriv)); + if (!driver_context) + return VA_STATUS_ERROR_ALLOCATION_FAILED; + + driver_context->vscreen = vl_screen_create(ctx->native_dpy, ctx->x11_screen); + if (!driver_context->vscreen) + { + FREE(driver_context); + return VA_STATUS_ERROR_ALLOCATION_FAILED; + } + ctx->str_vendor = "mesa gallium vaapi"; ctx->vtable = vlVaGetVtable(); ctx->max_attributes = 1; ctx->max_display_attributes = 1; - ctx->max_entrypoints = 1; - ctx->max_image_formats = 1; + ctx->max_entrypoints = VA_MAX_ENTRYPOINTS; + ctx->max_image_formats = VA_MAX_IMAGE_FORMATS_SUPPORTED; ctx->max_profiles = 1; - ctx->max_subpic_formats = 1; + ctx->max_subpic_formats = VA_MAX_SUBPIC_FORMATS_SUPPORTED; ctx->version_major = 3; ctx->version_minor = 1; + ctx->pDriverData = (void *)driver_context; VA_INFO("vl_screen_pointer %p\n",ctx->native_dpy); diff --git a/src/gallium/state_trackers/va/va_display.c b/src/gallium/state_trackers/va/va_display.c index d50d712d4e0..1aaaf7ccc53 100644 --- a/src/gallium/state_trackers/va/va_display.c +++ b/src/gallium/state_trackers/va/va_display.c @@ -37,8 +37,12 @@ VAStatus vlVaQueryDisplayAttributes( VADriverContextP ctx, if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; + if (!(attr_list && num_attributes)) + return VA_STATUS_ERROR_UNKNOWN; - return VA_STATUS_ERROR_UNIMPLEMENTED; + *num_attributes = 0; + + return VA_STATUS_SUCCESS; } VAStatus vlVaGetDisplayAttributes( VADriverContextP ctx, diff --git a/src/gallium/state_trackers/va/va_image.c b/src/gallium/state_trackers/va/va_image.c index 40a96d3ea48..8d20bfa9174 100644 --- a/src/gallium/state_trackers/va/va_image.c +++ b/src/gallium/state_trackers/va/va_image.c @@ -27,10 +27,30 @@ #include #include +#include +#include #include #include #include "va_private.h" +typedef struct { + enum pipe_format pipe_format; + VAImageFormat va_format; +} va_image_formats_supported_t; + +static const va_image_formats_supported_t va_image_formats_supported[VA_MAX_IMAGE_FORMATS_SUPPORTED] = +{ + { PIPE_FORMAT_B8G8R8A8_UNORM, + { VA_FOURCC('B','G','R','A'), VA_LSB_FIRST, 32, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }}, + { PIPE_FORMAT_R8G8B8A8_UNORM, + { VA_FOURCC_RGBA, VA_LSB_FIRST, 32, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 }} +}; + +boolean vlCreateHTAB(void); +void vlDestroyHTAB(void); +vlHandle vlAddDataHTAB(void *data); +void* vlGetDataHTAB(vlHandle handle); + VAStatus vlVaQueryImageFormats ( VADriverContextP ctx, VAImageFormat *format_list, @@ -39,8 +59,20 @@ vlVaQueryImageFormats ( VADriverContextP ctx, if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; + if (!(format_list && num_formats)) + return VA_STATUS_ERROR_UNKNOWN; + + int n = 0; + + num_formats[0] = VA_MAX_IMAGE_FORMATS_SUPPORTED; + + /* Query supported formats */ + for (n = 0; n < VA_MAX_IMAGE_FORMATS_SUPPORTED; n++) + { + format_list[n] = va_image_formats_supported[n].va_format; + } - return VA_STATUS_ERROR_UNIMPLEMENTED; + return VA_STATUS_SUCCESS; } VAStatus vlVaCreateImage( VADriverContextP ctx, @@ -52,7 +84,31 @@ VAStatus vlVaCreateImage( VADriverContextP ctx, if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; - return VA_STATUS_ERROR_UNIMPLEMENTED; + if(!format) + return VA_STATUS_ERROR_UNKNOWN; + + if (!(width && height)) + return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT; + + if (!vlCreateHTAB()) + return VA_STATUS_ERROR_UNKNOWN; + + switch (format->fourcc) { + case VA_FOURCC('B','G','R','A'): + VA_INFO("Creating BGRA image of size %dx%d\n",width,height); + break; + case VA_FOURCC_RGBA: + VA_INFO("Creating RGBA image of size %dx%d\n",width,height); + break; + default: + VA_ERROR("Couldn't create image of type %0x08\n",format->fourcc); + return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT; + break; + } + + VA_INFO("Image %p created successfully\n",format); + + return VA_STATUS_SUCCESS; } VAStatus vlVaDeriveImage( VADriverContextP ctx, diff --git a/src/gallium/state_trackers/va/va_picture.c b/src/gallium/state_trackers/va/va_picture.c index cf7d844a780..3603dfb6fed 100644 --- a/src/gallium/state_trackers/va/va_picture.c +++ b/src/gallium/state_trackers/va/va_picture.c @@ -27,6 +27,7 @@ #include #include +#include #include "va_private.h" VAStatus vlVaBeginPicture( VADriverContextP ctx, diff --git a/src/gallium/state_trackers/va/va_private.h b/src/gallium/state_trackers/va/va_private.h index bd037c89606..625c6cdbe1b 100644 --- a/src/gallium/state_trackers/va/va_private.h +++ b/src/gallium/state_trackers/va/va_private.h @@ -30,17 +30,41 @@ #include #include +#include +#include + #define VA_DEBUG(_str,...) debug_printf("[Gallium VA backend]: " _str,__VA_ARGS__) #define VA_INFO(_str,...) VA_DEBUG("INFO: " _str,__VA_ARGS__) #define VA_WARNING(_str,...) VA_DEBUG("WARNING: " _str,__VA_ARGS__) #define VA_ERROR(_str,...) VA_DEBUG("ERROR: " _str,__VA_ARGS__) +#define VA_MAX_IMAGE_FORMATS_SUPPORTED 2 +#define VA_MAX_SUBPIC_FORMATS_SUPPORTED 2 +#define VA_MAX_ENTRYPOINTS 1 + +#define VL_HANDLES + +typedef unsigned int vlHandle; + +typedef struct { + struct vl_screen *vscreen; + struct pipe_surface *backbuffer; +} vlVaDriverContextPriv; + +typedef struct { + unsigned int width; + unsigned int height; + enum pipe_video_chroma_format format; + VADriverContextP ctx; +} vlVaSurfacePriv; + // Public functions: VAStatus __vaDriverInit_0_31 (VADriverContextP ctx); // Private functions: struct VADriverVTable vlVaGetVtable(); + // Vtable functions: VAStatus vlVaTerminate (VADriverContextP ctx); VAStatus vlVaQueryConfigProfiles (VADriverContextP ctx, VAProfile *profile_list,int *num_profiles); diff --git a/src/gallium/state_trackers/va/va_subpicture.c b/src/gallium/state_trackers/va/va_subpicture.c index a6d2960e7e5..910e5bd7b70 100644 --- a/src/gallium/state_trackers/va/va_subpicture.c +++ b/src/gallium/state_trackers/va/va_subpicture.c @@ -30,23 +30,20 @@ #include #include "va_private.h" -#define NUM_FORMATS_SUPPORTED 2 typedef struct { - enum pipe_format; + enum pipe_format pipe_format; VAImageFormat va_format; unsigned int va_flags; } va_subpicture_formats_supported_t; -static const va_subpicture_formats_supported_t va_subpicture_formats_supported[NUM_FORMATS_SUPPORTED] = +static const va_subpicture_formats_supported_t va_subpicture_formats_supported[VA_MAX_SUBPIC_FORMATS_SUPPORTED + 1] = { { PIPE_FORMAT_B8G8R8A8_UNORM, - { VA_FOURCC('B','G','R','A'), VA_LSB_FIRST, 32, - 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, + { VA_FOURCC('B','G','R','A'), VA_LSB_FIRST, 32, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, 0 }, { PIPE_FORMAT_R8G8B8A8_UNORM, - { VA_FOURCC('R','G','B','A'), VA_LSB_FIRST, 32, - 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 }, + { VA_FOURCC_RGBA, VA_LSB_FIRST, 32, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 }, 0 } }; @@ -62,12 +59,15 @@ vlVaQuerySubpictureFormats( VADriverContextP ctx, if (!(format_list && flags && num_formats)) return VA_STATUS_ERROR_UNKNOWN; + num_formats[0] = VA_MAX_SUBPIC_FORMATS_SUPPORTED; + int n = 0; /* Query supported formats */ - for (n = 0; n < NUM_FORMATS_SUPPORTED; n++) + for (n = 0; n < VA_MAX_SUBPIC_FORMATS_SUPPORTED ; n++) { - flags[n] = va_subpicture_formats_supported[n].va_flags; - format_list[n] = va_subpicture_formats_supported[n].va_format; + const va_subpicture_formats_supported_t * const format_map = &va_subpicture_formats_supported[n]; + flags[n] = format_map->va_flags; + format_list[n] = format_map->va_format; } return VA_STATUS_SUCCESS; diff --git a/src/gallium/state_trackers/va/va_surface.c b/src/gallium/state_trackers/va/va_surface.c index ad241adaf41..a86c806248a 100644 --- a/src/gallium/state_trackers/va/va_surface.c +++ b/src/gallium/state_trackers/va/va_surface.c @@ -27,8 +27,31 @@ #include #include +#include +#include #include "va_private.h" +boolean vlCreateHTAB(void); +void vlDestroyHTAB(void); +vlHandle vlAddDataHTAB(void *data); +void* vlGetDataHTAB(vlHandle handle); + +static enum pipe_video_chroma_format VaRTFormatToPipe(unsigned int va_type) +{ + switch (va_type) { + case VA_RT_FORMAT_YUV420: + return PIPE_VIDEO_CHROMA_FORMAT_420; + case VA_RT_FORMAT_YUV422: + return PIPE_VIDEO_CHROMA_FORMAT_422; + case VA_RT_FORMAT_YUV444: + return PIPE_VIDEO_CHROMA_FORMAT_444; + default: + assert(0); + } + + return -1; +} + VAStatus vlVaCreateSurfaces( VADriverContextP ctx, int width, int height, @@ -39,7 +62,31 @@ VAStatus vlVaCreateSurfaces( VADriverContextP ctx, if (!ctx) return VA_STATUS_ERROR_INVALID_CONTEXT; - return VA_STATUS_ERROR_UNIMPLEMENTED; + /* We only support one format */ + if (VA_RT_FORMAT_YUV420 != format) + return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT; + + if (!(width && height)) + return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT; + + if (!vlCreateHTAB()) + return VA_STATUS_ERROR_UNKNOWN; + + vlVaSurfacePriv *va_surface = (vlVaSurfacePriv *)CALLOC(num_surfaces,sizeof(vlVaSurfacePriv)); + if (!va_surface) + return VA_STATUS_ERROR_ALLOCATION_FAILED; + + int n = 0; + for (n = 0; n < num_surfaces; n++) + { + va_surface[n].width = width; + va_surface[n].height = height; + va_surface[n].format = VaRTFormatToPipe(format); + va_surface[n].ctx = ctx; + surfaces[n] = (VASurfaceID *)vlAddDataHTAB((void *)(va_surface + n)); + } + + return VA_STATUS_SUCCESS; } VAStatus vlVaDestroySurfaces( VADriverContextP ctx,