Module: Mesa
Branch: main
Commit: b557ceb75b79e0d8b3f7352d4bb6764137175ee0
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=b557ceb75b79e0d8b3f7352d4bb6764137175ee0

Author: Sil Vilerino <[email protected]>
Date:   Wed Sep  7 13:42:04 2022 -0400

frontends/va: Add windows VA frontend support via vl_winsys_win32 and 
libva-win32

Acked-by: Emil Velikov <[email protected]>
Reviewed-by: Jesse Natalie <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19063>

---

 meson.build                                 |  14 ++-
 src/gallium/frontends/va/buffer.c           |  38 +++++++-
 src/gallium/frontends/va/context.c          |   7 ++
 src/gallium/frontends/va/image.c            |  12 +--
 src/gallium/frontends/va/picture_h264_enc.c |   3 +-
 src/gallium/frontends/va/picture_hevc_enc.c |   3 +-
 src/gallium/frontends/va/surface.c          | 139 ++++++++++++++++++++++++++--
 src/gallium/frontends/va/va_private.h       |   2 +
 src/gallium/targets/va/meson.build          | 108 ++++++++++++++-------
 src/gallium/targets/va/vaon12.def.in        |   1 +
 10 files changed, 267 insertions(+), 60 deletions(-)

diff --git a/meson.build b/meson.build
index fc5a32ae9b8..3e523ee242a 100644
--- a/meson.build
+++ b/meson.build
@@ -783,13 +783,7 @@ elif _va == 'false'
   _va = 'disabled'
   warning('gallium-va option "false" deprecated, please use "disabled" 
instead.')
 endif
-if not system_has_kms_drm
-  if _va == 'enabled'
-    error('VA state tracker can only be built on unix-like OSes.')
-  else
-    _va = 'disabled'
-  endif
-elif not (with_gallium_r600 or with_gallium_radeonsi or with_gallium_nouveau 
or with_gallium_d3d12_video or with_gallium_virgl)
+if not (with_gallium_r600 or with_gallium_radeonsi or with_gallium_nouveau or 
with_gallium_d3d12_video or with_gallium_virgl)
   if _va == 'enabled'
     error('VA state tracker requires at least one of the following gallium 
drivers: r600, radeonsi, nouveau, d3d12 (with option gallium-d3d12-video), 
virgl.')
   else
@@ -799,7 +793,11 @@ endif
 with_gallium_va = false
 dep_va = null_dep
 if _va != 'disabled'
-  dep_va = dependency('libva', version : '>= 1.8.0', required : _va == 
'enabled')
+  _dep_va_name = 'libva'
+  if host_machine.system() == 'windows'
+    _dep_va_name = 'libva-win32'
+  endif
+  dep_va = dependency(_dep_va_name, version : '>= 1.8.0', required : _va == 
'enabled')
   if dep_va.found()
     dep_va_headers = dep_va.partial_dependency(compile_args : true)
     with_gallium_va = true
diff --git a/src/gallium/frontends/va/buffer.c 
b/src/gallium/frontends/va/buffer.c
index 99ab0aa1753..af035ef5f90 100644
--- a/src/gallium/frontends/va/buffer.c
+++ b/src/gallium/frontends/va/buffer.c
@@ -35,6 +35,10 @@
 
 #include "va_private.h"
 
+#ifdef _WIN32
+#include <va/va_win32.h>
+#endif
+
 VAStatus
 vlVaCreateBuffer(VADriverContextP ctx, VAContextID context, VABufferType type,
                  unsigned int size, unsigned int num_elements, void *data,
@@ -126,7 +130,7 @@ vlVaMapBuffer(VADriverContextP ctx, VABufferID buf_id, void 
**pbuff)
 
    if (buf->derived_surface.resource) {
       struct pipe_resource *resource;
-      struct pipe_box box = {};
+      struct pipe_box box;
       void *(*map_func)(struct pipe_context *,
              struct pipe_resource *resource,
              unsigned level,
@@ -134,6 +138,7 @@ vlVaMapBuffer(VADriverContextP ctx, VABufferID buf_id, void 
**pbuff)
              const struct pipe_box *,
              struct pipe_transfer **out_transfer);
 
+      memset(&box, 0, sizeof(box));
       resource = buf->derived_surface.resource;
       box.width = resource->width0;
       box.height = resource->height0;
@@ -277,7 +282,12 @@ vlVaAcquireBufferHandle(VADriverContextP ctx, VABufferID 
buf_id,
 
    /* List of supported memory types, in preferred order. */
    static const uint32_t mem_types[] = {
+#ifdef _WIN32
+      VA_SURFACE_ATTRIB_MEM_TYPE_NTHANDLE,
+      VA_SURFACE_ATTRIB_MEM_TYPE_D3D12_RESOURCE,
+#else
       VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME,
+#endif
       0
    };
 
@@ -324,7 +334,13 @@ vlVaAcquireBufferHandle(VADriverContextP ctx, VABufferID 
buf_id,
       VABufferInfo * const buf_info = &buf->export_state;
 
       switch (mem_type) {
-      case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME: {
+#ifdef _WIN32
+      case VA_SURFACE_ATTRIB_MEM_TYPE_D3D12_RESOURCE:
+      case VA_SURFACE_ATTRIB_MEM_TYPE_NTHANDLE:
+#else
+      case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME:
+#endif
+      {
          struct winsys_handle whandle;
 
          mtx_lock(&drv->mutex);
@@ -333,6 +349,10 @@ vlVaAcquireBufferHandle(VADriverContextP ctx, VABufferID 
buf_id,
          memset(&whandle, 0, sizeof(whandle));
          whandle.type = WINSYS_HANDLE_TYPE_FD;
 
+#ifdef _WIN32
+         if (mem_type == VA_SURFACE_ATTRIB_MEM_TYPE_D3D12_RESOURCE)
+            whandle.type = WINSYS_HANDLE_TYPE_D3D12_RES;
+#endif
          if (!screen->resource_get_handle(screen, drv->pipe,
                                           buf->derived_surface.resource,
                                           &whandle, 
PIPE_HANDLE_USAGE_FRAMEBUFFER_WRITE)) {
@@ -343,6 +363,11 @@ vlVaAcquireBufferHandle(VADriverContextP ctx, VABufferID 
buf_id,
          mtx_unlock(&drv->mutex);
 
          buf_info->handle = (intptr_t)whandle.handle;
+
+#ifdef _WIN32
+         if (mem_type == VA_SURFACE_ATTRIB_MEM_TYPE_D3D12_RESOURCE)
+            buf_info->handle = (intptr_t)whandle.com_obj;
+#endif
          break;
       }
       default:
@@ -385,9 +410,18 @@ vlVaReleaseBufferHandle(VADriverContextP ctx, VABufferID 
buf_id)
       VABufferInfo * const buf_info = &buf->export_state;
 
       switch (buf_info->mem_type) {
+#ifdef _WIN32
+      case VA_SURFACE_ATTRIB_MEM_TYPE_D3D12_RESOURCE:
+         // Do nothing for this case.
+         break;
+      case VA_SURFACE_ATTRIB_MEM_TYPE_NTHANDLE:
+         CloseHandle((HANDLE) buf_info->handle);
+      break;
+#else
       case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME:
          close((intptr_t)buf_info->handle);
          break;
+#endif
       default:
          return VA_STATUS_ERROR_INVALID_BUFFER;
       }
diff --git a/src/gallium/frontends/va/context.c 
b/src/gallium/frontends/va/context.c
index 3c9360921c7..0af03799d5c 100644
--- a/src/gallium/frontends/va/context.c
+++ b/src/gallium/frontends/va/context.c
@@ -128,6 +128,12 @@ VA_DRIVER_INIT_FUNC(VADriverContextP ctx)
       return VA_STATUS_ERROR_ALLOCATION_FAILED;
 
    switch (ctx->display_type) {
+#ifdef _WIN32
+   case VA_DISPLAY_WIN32: {
+      drv->vscreen = vl_win32_screen_create(ctx->native_dpy);
+      break;
+   }
+#else
    case VA_DISPLAY_ANDROID:
       FREE(drv);
       return VA_STATUS_ERROR_UNIMPLEMENTED;
@@ -160,6 +166,7 @@ VA_DRIVER_INIT_FUNC(VADriverContextP ctx)
          drv->vscreen = vl_drm_screen_create(drm_info->fd);
       break;
    }
+#endif
    default:
       FREE(drv);
       return VA_STATUS_ERROR_INVALID_DISPLAY;
diff --git a/src/gallium/frontends/va/image.c b/src/gallium/frontends/va/image.c
index 198da5d6bd6..fb5a38dc9f4 100644
--- a/src/gallium/frontends/va/image.c
+++ b/src/gallium/frontends/va/image.c
@@ -494,7 +494,7 @@ vlVaGetImage(VADriverContextP ctx, VASurfaceID surface, int 
x, int y,
    struct pipe_sampler_view **views;
    enum pipe_format format;
    bool convert = false;
-   void *data[3];
+   uint8_t *data[3];
    unsigned pitches[3], i, j;
 
    if (!ctx)
@@ -571,7 +571,7 @@ vlVaGetImage(VADriverContextP ctx, VASurfaceID surface, int 
x, int y,
    }
 
    for (i = 0; i < vaimage->num_planes; i++) {
-      data[i] = img_buf->data + vaimage->offsets[i];
+      data[i] = ((uint8_t*)img_buf->data) + vaimage->offsets[i];
       pitches[i] = vaimage->pitches[i];
    }
    if (vaimage->format.fourcc == VA_FOURCC('I','4','2','0')) {
@@ -609,11 +609,11 @@ vlVaGetImage(VADriverContextP ctx, VASurfaceID surface, 
int x, int y,
          }
 
          if (i == 1 && convert) {
-            u_copy_nv12_to_yv12(data, pitches, i, j,
+            u_copy_nv12_to_yv12((void *const *)data, pitches, i, j,
                transfer->stride, views[i]->texture->array_size,
                map, box.width, box.height);
          } else {
-            util_copy_rect(data[i] + pitches[i] * j,
+            util_copy_rect((uint8_t*)(data[i] + pitches[i] * j),
                views[i]->texture->format,
                pitches[i] * views[i]->texture->array_size, 0, 0,
                box.width, box.height, map, transfer->stride, 0, 0);
@@ -637,7 +637,7 @@ vlVaPutImage(VADriverContextP ctx, VASurfaceID surface, 
VAImageID image,
    VAImage *vaimage;
    struct pipe_sampler_view **views;
    enum pipe_format format;
-   void *data[3];
+   uint8_t *data[3];
    unsigned pitches[3], i, j;
 
    if (!ctx)
@@ -705,7 +705,7 @@ vlVaPutImage(VADriverContextP ctx, VASurfaceID surface, 
VAImageID image,
    }
 
    for (i = 0; i < vaimage->num_planes; i++) {
-      data[i] = img_buf->data + vaimage->offsets[i];
+      data[i] = ((uint8_t*)img_buf->data) + vaimage->offsets[i];
       pitches[i] = vaimage->pitches[i];
    }
    if (vaimage->format.fourcc == VA_FOURCC('I','4','2','0')) {
diff --git a/src/gallium/frontends/va/picture_h264_enc.c 
b/src/gallium/frontends/va/picture_h264_enc.c
index 493e818b088..8c8256eff50 100644
--- a/src/gallium/frontends/va/picture_h264_enc.c
+++ b/src/gallium/frontends/va/picture_h264_enc.c
@@ -129,7 +129,8 @@ vlVaHandleVAEncSliceParameterBufferTypeH264(vlVaDriver 
*drv, vlVaContext *contex
     *  Slice type.
     *  Range: 0..2, 5..7, i.e. no switching slices.
    */
-   struct h264_slice_descriptor slice_descriptor = { };
+   struct h264_slice_descriptor slice_descriptor;
+   memset(&slice_descriptor, 0, sizeof(slice_descriptor));
    slice_descriptor.macroblock_address = h264->macroblock_address;
    slice_descriptor.num_macroblocks = h264->num_macroblocks;
 
diff --git a/src/gallium/frontends/va/picture_hevc_enc.c 
b/src/gallium/frontends/va/picture_hevc_enc.c
index 6c1525727d5..44429c2df5d 100644
--- a/src/gallium/frontends/va/picture_hevc_enc.c
+++ b/src/gallium/frontends/va/picture_hevc_enc.c
@@ -135,7 +135,8 @@ vlVaHandleVAEncSliceParameterBufferTypeHEVC(vlVaDriver 
*drv, vlVaContext *contex
    context->desc.h265enc.slice.slice_loop_filter_across_slices_enabled_flag = 
h265->slice_fields.bits.slice_loop_filter_across_slices_enabled_flag;
 
    /* Handle the slice control parameters */
-   struct h265_slice_descriptor slice_descriptor = { };
+   struct h265_slice_descriptor slice_descriptor;
+   memset(&slice_descriptor, 0, sizeof(slice_descriptor));
    slice_descriptor.slice_segment_address = h265->slice_segment_address;
    slice_descriptor.num_ctu_in_slice = h265->num_ctu_in_slice;
    slice_descriptor.slice_type = h265->slice_type;
diff --git a/src/gallium/frontends/va/surface.c 
b/src/gallium/frontends/va/surface.c
index 94e0a130835..b2c745acdd2 100644
--- a/src/gallium/frontends/va/surface.c
+++ b/src/gallium/frontends/va/surface.c
@@ -29,8 +29,6 @@
 #include "pipe/p_screen.h"
 #include "pipe/p_video_codec.h"
 
-#include "frontend/drm_driver.h"
-
 #include "util/u_memory.h"
 #include "util/u_handle_table.h"
 #include "util/u_rect.h"
@@ -44,8 +42,14 @@
 
 #include "va_private.h"
 
+#ifdef _WIN32
+#include "frontend/winsys_handle.h"
+#include <va/va_win32.h>
+#else
+#include "frontend/drm_driver.h"
 #include <va/va_drmcommon.h>
 #include "drm-uapi/drm_fourcc.h"
+#endif
 
 static const enum pipe_format vpp_surface_formats[] = {
    PIPE_FORMAT_B8G8R8A8_UNORM, PIPE_FORMAT_R8G8B8A8_UNORM,
@@ -534,8 +538,13 @@ vlVaQuerySurfaceAttributes(VADriverContextP ctx, 
VAConfigID config_id,
    attribs[i].value.type = VAGenericValueTypeInteger;
    attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
    attribs[i].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_VA |
+#ifdef _WIN32
+         VA_SURFACE_ATTRIB_MEM_TYPE_NTHANDLE |
+         VA_SURFACE_ATTRIB_MEM_TYPE_D3D12_RESOURCE;
+#else
          VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME |
          VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2;
+#endif
    i++;
 
    attribs[i].type = VASurfaceAttribExternalBufferDescriptor;
@@ -604,6 +613,7 @@ vlVaQuerySurfaceAttributes(VADriverContextP ctx, VAConfigID 
config_id,
    return VA_STATUS_SUCCESS;
 }
 
+#ifndef _WIN32
 static VAStatus
 surface_from_external_memory(VADriverContextP ctx, vlVaSurface *surface,
                              VASurfaceAttribExternalBuffers *memory_attribute,
@@ -812,6 +822,48 @@ fail:
       pipe_resource_reference(&resources[i], NULL);
    return result;
 }
+#else
+static VAStatus
+surface_from_external_win32_memory(VADriverContextP ctx, vlVaSurface *surface,
+                             int memory_type, void *res_handle,
+                             struct pipe_video_buffer *templat)
+{
+   vlVaDriver *drv;
+   struct pipe_screen *pscreen;
+   struct winsys_handle whandle;
+   VAStatus result;
+
+   pscreen = VL_VA_PSCREEN(ctx);
+   drv = VL_VA_DRIVER(ctx);
+
+   templat->buffer_format = surface->templat.buffer_format;
+   templat->width = surface->templat.width;
+   templat->height = surface->templat.height;
+
+   memset(&whandle, 0, sizeof(whandle));
+   whandle.format = surface->templat.buffer_format;
+   if (memory_type == VA_SURFACE_ATTRIB_MEM_TYPE_NTHANDLE) {
+      whandle.type = WINSYS_HANDLE_TYPE_FD;
+      whandle.handle = res_handle;
+   } else if (memory_type == VA_SURFACE_ATTRIB_MEM_TYPE_D3D12_RESOURCE) {
+      whandle.type = WINSYS_HANDLE_TYPE_D3D12_RES;
+      whandle.com_obj = res_handle;
+   } else {
+      return VA_STATUS_ERROR_INVALID_PARAMETER;
+   }
+
+   surface->buffer = drv->pipe->video_buffer_from_handle(drv->pipe, templat, 
&whandle, PIPE_USAGE_DEFAULT);
+   if (!surface->buffer) {
+      result = VA_STATUS_ERROR_ALLOCATION_FAILED;
+      goto fail;
+   }
+   return VA_STATUS_SUCCESS;
+
+fail:
+   return result;
+}
+
+#endif
 
 VAStatus
 vlVaHandleSurfaceAllocate(vlVaDriver *drv, vlVaSurface *surface,
@@ -837,7 +889,8 @@ vlVaHandleSurfaceAllocate(vlVaDriver *drv, vlVaSurface 
*surface,
 
    surfaces = surface->buffer->get_surfaces(surface->buffer);
    for (i = 0; i < VL_MAX_SURFACES; ++i) {
-      union pipe_color_union c = {};
+      union pipe_color_union c;
+      memset(&c, 0, sizeof(c));
 
       if (!surfaces[i])
          continue;
@@ -862,9 +915,13 @@ vlVaCreateSurfaces2(VADriverContextP ctx, unsigned int 
format,
 {
    vlVaDriver *drv;
    VASurfaceAttribExternalBuffers *memory_attribute;
-   VADRMPRIMESurfaceDescriptor *prime_desc;
+#ifdef _WIN32
+   void **win32_handles;
+#else
+   VADRMPRIMESurfaceDescriptor *prime_desc = NULL;
 #ifdef HAVE_VA_SURFACE_ATTRIB_DRM_FORMAT_MODIFIERS
    const VADRMFormatModifierList *modifier_list;
+#endif
 #endif
    struct pipe_video_buffer templat;
    struct pipe_screen *pscreen;
@@ -895,7 +952,6 @@ vlVaCreateSurfaces2(VADriverContextP ctx, unsigned int 
format,
 
    /* Default. */
    memory_attribute = NULL;
-   prime_desc = NULL;
    memory_type = VA_SURFACE_ATTRIB_MEM_TYPE_VA;
    expected_fourcc = 0;
    modifiers = NULL;
@@ -917,8 +973,14 @@ vlVaCreateSurfaces2(VADriverContextP ctx, unsigned int 
format,
 
          switch (attrib_list[i].value.value.i) {
          case VA_SURFACE_ATTRIB_MEM_TYPE_VA:
+
+#ifdef _WIN32
+         case VA_SURFACE_ATTRIB_MEM_TYPE_NTHANDLE:
+         case VA_SURFACE_ATTRIB_MEM_TYPE_D3D12_RESOURCE:
+#else
          case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME:
          case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2:
+#endif
             memory_type = attrib_list[i].value.value.i;
             break;
          default:
@@ -928,11 +990,18 @@ vlVaCreateSurfaces2(VADriverContextP ctx, unsigned int 
format,
       case VASurfaceAttribExternalBufferDescriptor:
          if (attrib_list[i].value.type != VAGenericValueTypePointer)
             return VA_STATUS_ERROR_INVALID_PARAMETER;
+#ifndef _WIN32
          if (memory_type == VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2)
             prime_desc = (VADRMPRIMESurfaceDescriptor 
*)attrib_list[i].value.value.p;
+#else
+         else if (memory_type == VA_SURFACE_ATTRIB_MEM_TYPE_NTHANDLE ||
+                  memory_type == VA_SURFACE_ATTRIB_MEM_TYPE_D3D12_RESOURCE)
+            win32_handles = (void**) attrib_list[i].value.value.p;
+#endif
          else
             memory_attribute = (VASurfaceAttribExternalBuffers 
*)attrib_list[i].value.value.p;
          break;
+#ifndef _WIN32
 #ifdef HAVE_VA_SURFACE_ATTRIB_DRM_FORMAT_MODIFIERS
       case VASurfaceAttribDRMFormatModifiers:
          if (attrib_list[i].value.type != VAGenericValueTypePointer)
@@ -943,6 +1012,7 @@ vlVaCreateSurfaces2(VADriverContextP ctx, unsigned int 
format,
             modifiers_count = modifier_list->num_modifiers;
          }
          break;
+#endif
 #endif
       case VASurfaceAttribUsageHint:
          if (attrib_list[i].value.type != VAGenericValueTypeInteger)
@@ -968,6 +1038,13 @@ vlVaCreateSurfaces2(VADriverContextP ctx, unsigned int 
format,
    switch (memory_type) {
    case VA_SURFACE_ATTRIB_MEM_TYPE_VA:
       break;
+#ifdef _WIN32
+         case VA_SURFACE_ATTRIB_MEM_TYPE_NTHANDLE:
+         case VA_SURFACE_ATTRIB_MEM_TYPE_D3D12_RESOURCE:
+         if (!win32_handles)
+            return VA_STATUS_ERROR_INVALID_PARAMETER;
+         break;
+#else
    case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME:
       if (!memory_attribute)
          return VA_STATUS_ERROR_INVALID_PARAMETER;
@@ -982,6 +1059,7 @@ vlVaCreateSurfaces2(VADriverContextP ctx, unsigned int 
format,
 
       expected_fourcc = prime_desc->fourcc;
       break;
+#endif
    default:
       assert(0);
    }
@@ -1045,6 +1123,14 @@ vlVaCreateSurfaces2(VADriverContextP ctx, unsigned int 
format,
             goto free_surf;
          break;
 
+#ifdef _WIN32
+      case VA_SURFACE_ATTRIB_MEM_TYPE_NTHANDLE:
+      case VA_SURFACE_ATTRIB_MEM_TYPE_D3D12_RESOURCE:
+         vaStatus = surface_from_external_win32_memory(ctx, surf, memory_type, 
win32_handles[i], &templat);
+         if (vaStatus != VA_STATUS_SUCCESS)
+            goto free_surf;
+         break;
+#else
       case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME:
          vaStatus = surface_from_external_memory(ctx, surf, memory_attribute, 
i, &templat);
          if (vaStatus != VA_STATUS_SUCCESS)
@@ -1056,6 +1142,7 @@ vlVaCreateSurfaces2(VADriverContextP ctx, unsigned int 
format,
          if (vaStatus != VA_STATUS_SUCCESS)
             goto free_surf;
          break;
+#endif
       default:
          assert(0);
       }
@@ -1268,6 +1355,7 @@ vlVaQueryVideoProcPipelineCaps(VADriverContextP ctx, 
VAContextID context,
    return VA_STATUS_SUCCESS;
 }
 
+#ifndef _WIN32
 static uint32_t pipe_format_to_drm_format(enum pipe_format format)
 {
    switch (format) {
@@ -1295,6 +1383,7 @@ static uint32_t pipe_format_to_drm_format(enum 
pipe_format format)
       return DRM_FORMAT_INVALID;
    }
 }
+#endif
 
 #if VA_CHECK_VERSION(1, 1, 0)
 VAStatus
@@ -1310,12 +1399,19 @@ vlVaExportSurfaceHandle(VADriverContextP ctx,
    struct pipe_screen *screen;
    VAStatus ret;
    unsigned int usage;
-   int i, p;
 
-   VADRMPRIMESurfaceDescriptor *desc = descriptor;
+#ifdef _WIN32
+   if ((mem_type != VA_SURFACE_ATTRIB_MEM_TYPE_NTHANDLE)
+      && (mem_type != VA_SURFACE_ATTRIB_MEM_TYPE_D3D12_RESOURCE))
+      return VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE;
 
+   if ((flags & VA_EXPORT_SURFACE_COMPOSED_LAYERS) == 0)
+      return VA_STATUS_ERROR_INVALID_SURFACE;
+#else
+   int i, p;
    if (mem_type != VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2)
       return VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE;
+#endif
 
    drv    = VL_VA_DRIVER(ctx);
    screen = VL_VA_PSCREEN(ctx);
@@ -1360,6 +1456,29 @@ vlVaExportSurfaceHandle(VADriverContextP ctx,
    if (flags & VA_EXPORT_SURFACE_WRITE_ONLY)
       usage |= PIPE_HANDLE_USAGE_FRAMEBUFFER_WRITE;
 
+#ifdef _WIN32
+   struct winsys_handle whandle;
+   memset(&whandle, 0, sizeof(struct winsys_handle));
+   struct pipe_resource *resource = surfaces[0]->texture;
+
+   if (mem_type == VA_SURFACE_ATTRIB_MEM_TYPE_NTHANDLE)
+      whandle.type = WINSYS_HANDLE_TYPE_FD;
+   else if (mem_type == VA_SURFACE_ATTRIB_MEM_TYPE_D3D12_RESOURCE)
+      whandle.type = WINSYS_HANDLE_TYPE_D3D12_RES;
+
+   if (!screen->resource_get_handle(screen, drv->pipe, resource,
+                                    &whandle, usage)) {
+      ret = VA_STATUS_ERROR_INVALID_SURFACE;
+      goto fail;
+   }
+
+   if (mem_type == VA_SURFACE_ATTRIB_MEM_TYPE_NTHANDLE)
+      *(HANDLE**)descriptor = whandle.handle;
+   else if (mem_type == VA_SURFACE_ATTRIB_MEM_TYPE_D3D12_RESOURCE)
+      *(void**) descriptor = whandle.com_obj;
+
+#else
+   VADRMPRIMESurfaceDescriptor *desc = descriptor;
    desc->fourcc = PipeFormatToVaFourcc(surf->buffer->buffer_format);
    desc->width  = surf->templat.width;
    desc->height = surf->templat.height;
@@ -1424,14 +1543,20 @@ vlVaExportSurfaceHandle(VADriverContextP ctx,
    } else {
       desc->num_layers = p;
    }
+#endif
 
    mtx_unlock(&drv->mutex);
 
    return VA_STATUS_SUCCESS;
 
 fail:
+#ifndef _WIN32
    for (i = 0; i < p; i++)
       close(desc->objects[i].fd);
+#else
+   if(whandle.handle)
+      CloseHandle(whandle.handle);
+#endif
 
    mtx_unlock(&drv->mutex);
 
diff --git a/src/gallium/frontends/va/va_private.h 
b/src/gallium/frontends/va/va_private.h
index dd779269571..58089b10821 100644
--- a/src/gallium/frontends/va/va_private.h
+++ b/src/gallium/frontends/va/va_private.h
@@ -383,7 +383,9 @@ typedef struct {
 } vlVaQualityBits;
 
 // Public functions:
+#ifndef _WIN32
 VAStatus VA_DRIVER_INIT_FUNC(VADriverContextP ctx);
+#endif
 
 // vtable functions:
 VAStatus vlVaTerminate(VADriverContextP ctx);
diff --git a/src/gallium/targets/va/meson.build 
b/src/gallium/targets/va/meson.build
index 44addd45bb1..02664fef878 100644
--- a/src/gallium/targets/va/meson.build
+++ b/src/gallium/targets/va/meson.build
@@ -40,40 +40,78 @@ if with_glx == 'xlib' or with_glx == 'gallium-xlib'
   link_with_libva_gallium += [libws_xlib]
 endif
 
-libva_gallium = shared_library(
-  'gallium_drv_video',
-  'target.c',
-  gnu_symbol_visibility : 'hidden',
-  link_args : [va_link_args, ld_args_gc_sections],
-  include_directories : [
-    inc_include, inc_src, inc_mapi, inc_mesa, inc_gallium, inc_gallium_aux, 
inc_util, inc_gallium_winsys, inc_gallium_drivers,
-  ],
-  link_whole : [libva_st],
-  link_with : link_with_libva_gallium,
-  dependencies : [
-    dep_libdrm, driver_r600, driver_radeonsi, driver_nouveau, driver_d3d12, 
driver_virgl,
-    idep_mesautil,
-  ],
-  link_depends : va_link_depends,
-  # Will be deleted during installation, see install_megadrivers.py
-  install : true,
-  install_dir : va_drivers_path,
-  name_suffix : 'so',
-)
+if host_machine.system() == 'windows'
+  link_with_libva_gallium += [libwsgdi]
 
-foreach d : [[with_gallium_r600, 'r600'],
-             [with_gallium_radeonsi, 'radeonsi'],
-             [with_gallium_nouveau, 'nouveau'],
-             [with_gallium_virgl, 'virtio_gpu'],
-             [with_gallium_d3d12_video, 'd3d12']]
-  if d[0]
-    va_drivers += '@0@_drv_video.so'.format(d[1])
-  endif
-endforeach
+  libva_init_version = dep_va.version().split('.')
+  vaon12_def_input = configure_file(
+    configuration: {
+      '__vaDriverInit_X_Y': 
'__vaDriverInit_@0@_@1@'.format(libva_init_version[0], libva_init_version[1]) + 
'@4'
+    },
+    input: 'vaon12.def.in',
+    output: 'vaon12.def.in',
+  )
 
-meson.add_install_script(
-  install_megadrivers_py.path(),
-  libva_gallium.full_path(),
-  va_drivers_path,
-  va_drivers,
-)
+  vaon12_def = custom_target(
+    'vaon12.def',
+    input: vaon12_def_input,
+    output : 'vaon12.def',
+    command : [prog_python, gen_vs_module_defs_py,
+              '--in_file', '@INPUT@', '--out_file', '@OUTPUT@',
+              '--compiler_id', cc.get_argument_syntax(), '--cpu_family', 
host_machine.cpu_family()]
+  )
+
+  libva_gallium = shared_library(
+    'vaon12_drv_video',
+    'target.c',
+    link_args : [va_link_args, ld_args_gc_sections],
+    vs_module_defs : vaon12_def,
+    include_directories : [
+      inc_include, inc_src, inc_mapi, inc_mesa, inc_gallium, inc_gallium_aux, 
inc_util, inc_gallium_winsys, inc_gallium_drivers, inc_gallium_winsys_sw
+    ],
+    link_whole : [libva_st],
+    link_with : link_with_libva_gallium,
+    dependencies : [driver_d3d12, idep_mesautil],
+    link_depends : va_link_depends,
+    install : true,
+    name_suffix : 'dll',
+  )
+else
+  libva_gallium = shared_library(
+    'gallium_drv_video',
+    'target.c',
+    gnu_symbol_visibility : 'hidden',
+    link_args : [va_link_args, ld_args_gc_sections],
+    include_directories : [
+      inc_include, inc_src, inc_mapi, inc_mesa, inc_gallium, inc_gallium_aux, 
inc_util, inc_gallium_winsys, inc_gallium_drivers,
+    ],
+    link_whole : [libva_st],
+    link_with : link_with_libva_gallium,
+    dependencies : [
+      dep_libdrm, driver_r600, driver_radeonsi, driver_nouveau, driver_d3d12, 
driver_virgl,
+      idep_mesautil,
+    ],
+    link_depends : va_link_depends,
+    # Will be deleted during installation, see install_megadrivers.py
+    install : true,
+    install_dir : va_drivers_path,
+    name_suffix : 'so',
+  )
+
+  foreach d : [[with_gallium_r600, 'r600'],
+              [with_gallium_radeonsi, 'radeonsi'],
+              [with_gallium_nouveau, 'nouveau'],
+              [with_gallium_virgl, 'virtio_gpu'],
+              [with_gallium_d3d12_video, 'd3d12']]
+    if d[0]
+      va_drivers += '@0@_drv_video.so'.format(d[1])
+    endif
+  endforeach
+
+  meson.add_install_script(
+    install_megadrivers_py.path(),
+    libva_gallium.full_path(),
+    va_drivers_path,
+    va_drivers,
+  )
+endif
diff --git a/src/gallium/targets/va/vaon12.def.in 
b/src/gallium/targets/va/vaon12.def.in
new file mode 100644
index 00000000000..9f4dc013942
--- /dev/null
+++ b/src/gallium/targets/va/vaon12.def.in
@@ -0,0 +1 @@
+@__vaDriverInit_X_Y@

Reply via email to