mesa; add a dummy _mesa_error_no_memory() symbol to libglsl_util
[mesa.git] / src / gallium / state_trackers / xa / xa_tracker.c
index 12ee29c4647df969804cf9f0b8fcacc67c465672..f69ac8edf2774a1dfd2d824d4a2ea6fc0c55ef4f 100644 (file)
  * Thomas Hellstrom <thellstrom-at-vmware-dot-com>
  */
 
+#include <unistd.h>
 #include "xa_tracker.h"
 #include "xa_priv.h"
 #include "pipe/p_state.h"
 #include "pipe/p_format.h"
+#include "pipe-loader/pipe_loader.h"
 #include "state_tracker/drm_driver.h"
 #include "util/u_inlines.h"
 
@@ -118,10 +120,10 @@ xa_get_pipe_format(enum xa_formats xa_format)
        fdesc.format = PIPE_FORMAT_X8Z24_UNORM;
        break;
     case xa_format_s8z24:
-       fdesc.format = PIPE_FORMAT_Z24_UNORM_S8_USCALED;
+       fdesc.format = PIPE_FORMAT_Z24_UNORM_S8_UINT;
        break;
     case xa_format_z24s8:
-       fdesc.format = PIPE_FORMAT_S8_USCALED_Z24_UNORM;
+       fdesc.format = PIPE_FORMAT_S8_UINT_Z24_UNORM;
        break;
     case xa_format_yuv8:
        fdesc.format = PIPE_FORMAT_L8_UNORM;
@@ -133,17 +135,27 @@ xa_get_pipe_format(enum xa_formats xa_format)
     return fdesc;
 }
 
-struct xa_tracker *
+XA_EXPORT struct xa_tracker *
 xa_tracker_create(int drm_fd)
 {
     struct xa_tracker *xa = calloc(1, sizeof(struct xa_tracker));
     enum xa_surface_type stype;
     unsigned int num_formats;
+    int loader_fd;
 
     if (!xa)
        return NULL;
 
-    xa->screen = driver_descriptor.create_screen(drm_fd);
+#if GALLIUM_STATIC_TARGETS
+    xa->screen = dd_create_screen(drm_fd);
+    (void) loader_fd; /* silence unused var warning */
+#else
+    loader_fd = dup(drm_fd);
+    if (loader_fd == -1)
+        return NULL;
+    if (pipe_loader_drm_probe_fd(&xa->dev, loader_fd, false))
+       xa->screen = pipe_loader_create_screen(xa->dev, PIPE_SEARCH_DIR);
+#endif
     if (!xa->screen)
        goto out_no_screen;
 
@@ -190,16 +202,23 @@ xa_tracker_create(int drm_fd)
  out_no_pipe:
     xa->screen->destroy(xa->screen);
  out_no_screen:
+#if !GALLIUM_STATIC_TARGETS
+    if (xa->dev)
+       pipe_loader_release(&xa->dev, 1);
+#endif
     free(xa);
     return NULL;
 }
 
-void
+XA_EXPORT void
 xa_tracker_destroy(struct xa_tracker *xa)
 {
     free(xa->supported_formats);
     xa_context_destroy(xa->default_ctx);
     xa->screen->destroy(xa->screen);
+#if !GALLIUM_STATIC_TARGETS
+    pipe_loader_release(&xa->dev, 1);
+#endif
     free(xa);
 }
 
@@ -219,6 +238,12 @@ xa_flags_compat(unsigned int old_flags, unsigned int new_flags)
     if (flag_diff & XA_FLAG_RENDER_TARGET)
        return ((new_flags & XA_FLAG_RENDER_TARGET) == 0);
 
+    /*
+     * Don't recreate if we're dropping the scanout flag.
+     */
+    if (flag_diff & XA_FLAG_SCANOUT)
+       return ((new_flags & XA_FLAG_SCANOUT) == 0);
+
     /*
      * Always recreate for unknown / unimplemented flags.
      */
@@ -248,13 +273,39 @@ xa_get_format_stype_depth(struct xa_tracker *xa,
     return fdesc;
 }
 
-struct xa_surface *
-xa_surface_create(struct xa_tracker *xa,
+XA_EXPORT int
+xa_format_check_supported(struct xa_tracker *xa,
+                         enum xa_formats xa_format, unsigned int flags)
+{
+    struct xa_format_descriptor fdesc = xa_get_pipe_format(xa_format);
+    unsigned int bind;
+
+    if (fdesc.xa_format == xa_format_unknown)
+       return -XA_ERR_INVAL;
+
+    bind = stype_bind[xa_format_type(fdesc.xa_format)];
+    if (flags & XA_FLAG_SHARED)
+       bind |= PIPE_BIND_SHARED;
+    if (flags & XA_FLAG_RENDER_TARGET)
+       bind |= PIPE_BIND_RENDER_TARGET;
+    if (flags & XA_FLAG_SCANOUT)
+       bind |= PIPE_BIND_SCANOUT;
+
+    if (!xa->screen->is_format_supported(xa->screen, fdesc.format,
+                                        PIPE_TEXTURE_2D, 0, bind))
+       return -XA_ERR_INVAL;
+
+    return XA_ERR_NONE;
+}
+
+static struct xa_surface *
+surface_create(struct xa_tracker *xa,
                  int width,
                  int height,
                  int depth,
                  enum xa_surface_type stype,
-                 enum xa_formats xa_format, unsigned int flags)
+                 enum xa_formats xa_format, unsigned int flags,
+                 struct winsys_handle *whandle)
 {
     struct pipe_resource *template;
     struct xa_surface *srf;
@@ -286,12 +337,17 @@ xa_surface_create(struct xa_tracker *xa,
        template->bind |= PIPE_BIND_SHARED;
     if (flags & XA_FLAG_RENDER_TARGET)
        template->bind |= PIPE_BIND_RENDER_TARGET;
+    if (flags & XA_FLAG_SCANOUT)
+       template->bind |= PIPE_BIND_SCANOUT;
 
-    srf->tex = xa->screen->resource_create(xa->screen, template);
+    if (whandle)
+       srf->tex = xa->screen->resource_from_handle(xa->screen, template, whandle);
+    else
+       srf->tex = xa->screen->resource_create(xa->screen, template);
     if (!srf->tex)
        goto out_no_tex;
 
-    srf->srf = NULL;
+    srf->refcount = 1;
     srf->xa = xa;
     srf->flags = flags;
     srf->fdesc = fdesc;
@@ -302,15 +358,45 @@ xa_surface_create(struct xa_tracker *xa,
     return NULL;
 }
 
-int
+
+XA_EXPORT struct xa_surface *
+xa_surface_create(struct xa_tracker *xa,
+                 int width,
+                 int height,
+                 int depth,
+                 enum xa_surface_type stype,
+                 enum xa_formats xa_format, unsigned int flags)
+{
+    return surface_create(xa, width, height, depth, stype, xa_format, flags, NULL);
+}
+
+
+XA_EXPORT struct xa_surface *
+xa_surface_from_handle(struct xa_tracker *xa,
+                 int width,
+                 int height,
+                 int depth,
+                 enum xa_surface_type stype,
+                 enum xa_formats xa_format, unsigned int flags,
+                 uint32_t handle, uint32_t stride)
+{
+    struct winsys_handle whandle;
+    memset(&whandle, 0, sizeof(whandle));
+    whandle.type = DRM_API_HANDLE_TYPE_SHARED;
+    whandle.handle = handle;
+    whandle.stride = stride;
+    return surface_create(xa, width, height, depth, stype, xa_format, flags, &whandle);
+}
+
+XA_EXPORT int
 xa_surface_redefine(struct xa_surface *srf,
                    int width,
                    int height,
                    int depth,
                    enum xa_surface_type stype,
                    enum xa_formats xa_format,
-                   unsigned int add_flags,
-                   unsigned int remove_flags, int copy_contents)
+                   unsigned int new_flags,
+                   int copy_contents)
 {
     struct pipe_resource *template = &srf->template;
     struct pipe_resource *texture;
@@ -318,9 +404,10 @@ xa_surface_redefine(struct xa_surface *srf,
     struct xa_tracker *xa = srf->xa;
     int save_width;
     int save_height;
-    unsigned int new_flags = (srf->flags | add_flags) & ~(remove_flags);
+    unsigned int save_format;
     struct xa_format_descriptor fdesc;
 
+
     if (xa_format == xa_format_unknown)
        fdesc = xa_get_format_stype_depth(xa, stype, depth);
     else
@@ -336,6 +423,8 @@ xa_surface_redefine(struct xa_surface *srf,
        template->bind |= PIPE_BIND_SHARED;
     if (new_flags & XA_FLAG_RENDER_TARGET)
        template->bind |= PIPE_BIND_RENDER_TARGET;
+    if (new_flags & XA_FLAG_SCANOUT)
+       template->bind |= PIPE_BIND_SCANOUT;
 
     if (copy_contents) {
        if (!xa_format_type_is_color(fdesc.xa_format) ||
@@ -351,19 +440,20 @@ xa_surface_redefine(struct xa_surface *srf,
 
     save_width = template->width0;
     save_height = template->height0;
+    save_format = template->format;
 
     template->width0 = width;
     template->height0 = height;
+    template->format = fdesc.format;
 
     texture = xa->screen->resource_create(xa->screen, template);
     if (!texture) {
        template->width0 = save_width;
        template->height0 = save_height;
+       template->format = save_format;
        return -XA_ERR_NORES;
     }
 
-    pipe_surface_reference(&srf->srf, NULL);
-
     if (copy_contents) {
        struct pipe_context *pipe = xa->default_ctx->pipe;
 
@@ -371,7 +461,7 @@ xa_surface_redefine(struct xa_surface *srf,
                        xa_min(save_height, template->height0), &src_box);
        pipe->resource_copy_region(pipe, texture,
                                   0, 0, 0, 0, srf->tex, 0, &src_box);
-       pipe->flush(pipe, &xa->default_ctx->last_fence);
+       pipe->flush(pipe, &xa->default_ctx->last_fence, 0);
     }
 
     pipe_resource_reference(&srf->tex, texture);
@@ -382,15 +472,27 @@ xa_surface_redefine(struct xa_surface *srf,
     return XA_ERR_NONE;
 }
 
-void
-xa_surface_destroy(struct xa_surface *srf)
+XA_EXPORT struct xa_surface*
+xa_surface_ref(struct xa_surface *srf)
 {
-    pipe_surface_reference(&srf->srf, NULL);
+    if (srf == NULL) {
+       return NULL;
+    }
+    srf->refcount++;
+    return srf;
+}
+
+XA_EXPORT void
+xa_surface_unref(struct xa_surface *srf)
+{
+    if (srf == NULL || --srf->refcount) {
+       return;
+    }
     pipe_resource_reference(&srf->tex, NULL);
     free(srf);
 }
 
-extern void
+XA_EXPORT void
 xa_tracker_version(int *major, int *minor, int *patch)
 {
     *major = XA_TRACKER_VERSION_MAJOR;
@@ -398,8 +500,9 @@ xa_tracker_version(int *major, int *minor, int *patch)
     *patch = XA_TRACKER_VERSION_PATCH;
 }
 
-extern int
+XA_EXPORT int
 xa_surface_handle(struct xa_surface *srf,
+                 enum xa_handle_type type,
                  uint32_t * handle, unsigned int *stride)
 {
     struct winsys_handle whandle;
@@ -408,7 +511,15 @@ xa_surface_handle(struct xa_surface *srf,
     boolean res;
 
     memset(&whandle, 0, sizeof(whandle));
-    whandle.type = DRM_API_HANDLE_TYPE_SHARED;
+    switch (type) {
+    case xa_handle_type_kms:
+       whandle.type = DRM_API_HANDLE_TYPE_KMS;
+       break;
+    case xa_handle_type_shared:
+    default:
+       whandle.type = DRM_API_HANDLE_TYPE_SHARED;
+       break;
+    }
     res = screen->resource_get_handle(screen, srf->tex, &whandle);
     if (!res)
        return -XA_ERR_INVAL;
@@ -418,3 +529,9 @@ xa_surface_handle(struct xa_surface *srf,
 
     return XA_ERR_NONE;
 }
+
+XA_EXPORT enum xa_formats
+xa_surface_format(const struct xa_surface *srf)
+{
+    return srf->fdesc.xa_format;
+}