nouveau: Conversion to winsys handle
authorJakob Bornecrantz <jakob@vmware.com>
Thu, 4 Mar 2010 14:36:51 +0000 (14:36 +0000)
committerJakob Bornecrantz <jakob@vmware.com>
Thu, 4 Mar 2010 14:37:29 +0000 (14:37 +0000)
Not the best conversion that could be done.

src/gallium/drivers/nouveau/nouveau_screen.c
src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c

index 3c2f771b51ef617771c64e33cc74e209cc5e0696..2013eef0c5ac61ac58f7c964f14e07c0e49e187c 100644 (file)
@@ -4,6 +4,7 @@
 
 #include "util/u_memory.h"
 #include "util/u_inlines.h"
+#include "util/u_format.h"
 
 #include <stdio.h>
 #include <errno.h>
@@ -12,6 +13,9 @@
 #include "nouveau_winsys.h"
 #include "nouveau_screen.h"
 
+/* XXX this should go away */
+#include "state_tracker/drm_api.h"
+
 static const char *
 nouveau_screen_get_name(struct pipe_screen *pscreen)
 {
@@ -231,6 +235,71 @@ nouveau_screen_fence_finish(struct pipe_screen *screen,
        return 0;
 }
 
+
+/*
+ * Both texture_{from|get}_handle use drm api defines directly which they
+ * shouldn't do. The problem is that from|get are pipe functions and as
+ * such they should be defined in the pipe level. If nouveau had a propper
+ * winsys interface we would have added from|get to that interface using
+ * the winsys_handle struct as done with other drivers. However this code
+ * calls directly into the libdrm_nouveau.so functions (nouveau_bo_*). So
+ * we need to translate the handle into something they understand.
+ */
+static struct pipe_texture *
+nouveau_screen_texture_from_handle(struct pipe_screen *pscreen,
+                                  const struct pipe_texture *templ,
+                                  struct winsys_handle *whandle)
+{
+       struct nouveau_device *dev = nouveau_screen(pscreen)->device;
+       struct pipe_texture *pt;
+       struct pipe_buffer *pb;
+       int ret;
+
+       pb = CALLOC(1, sizeof(struct pipe_buffer) + sizeof(struct nouveau_bo*));
+       if (!pb)
+               return NULL;
+
+       ret = nouveau_bo_handle_ref(dev, whandle->handle, (struct nouveau_bo**)(pb+1));
+       if (ret) {
+               debug_printf("%s: ref name 0x%08x failed with %d\n",
+                            __func__, whandle->handle, ret);
+               FREE(pb);
+               return NULL;
+       }
+
+       pipe_reference_init(&pb->reference, 1);
+       pb->screen = pscreen;
+       pb->alignment = 0;
+       pb->usage = PIPE_BUFFER_USAGE_GPU_READ_WRITE |
+                   PIPE_BUFFER_USAGE_CPU_READ_WRITE;
+       pb->size = nouveau_bo(pb)->size;
+       pt = pscreen->texture_blanket(pscreen, templ, &whandle->stride, pb);
+       pipe_buffer_reference(&pb, NULL);
+       return pt;
+}
+
+static boolean
+nouveau_screen_texture_get_handle(struct pipe_screen *pscreen,
+                                 struct pipe_texture *pt,
+                                 struct winsys_handle *whandle)
+{
+       struct nouveau_miptree *mt = nouveau_miptree(pt);
+
+       if (!mt || !mt->bo)
+               return false;
+
+       whandle->stride = util_format_get_stride(mt->base.format, mt->base.width0);
+
+       if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) { 
+               return nouveau_bo_handle_get(mt->bo, &whandle->handle) == 0;
+       } else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) {
+               whandle->handle = mt->bo->handle;
+               return TRUE;
+       } else {
+               return FALSE;
+       }
+}
+
 int
 nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev)
 {
@@ -258,6 +327,9 @@ nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev)
        pscreen->fence_signalled = nouveau_screen_fence_signalled;
        pscreen->fence_finish = nouveau_screen_fence_finish;
 
+       pscreen->texture_from_handle = nouveau_screen_texture_from_handle;
+       pscreen->texture_get_handle = nouveau_screen_texture_get_handle;
+
        return 0;
 }
 
index 80b5a4c0914944771a6cb88d8f5a07f0366344a7..af9e92edd9e003d53e13c86e153eeb86ae3f1373 100644 (file)
@@ -21,6 +21,7 @@ dri_surface_from_handle(struct drm_api *api, struct pipe_screen *pscreen,
        struct pipe_surface *ps = NULL;
        struct pipe_texture *pt = NULL;
        struct pipe_texture tmpl;
+       struct winsys_handle whandle;
 
        memset(&tmpl, 0, sizeof(tmpl));
        tmpl.tex_usage = PIPE_TEXTURE_USAGE_SCANOUT;
@@ -31,8 +32,11 @@ dri_surface_from_handle(struct drm_api *api, struct pipe_screen *pscreen,
        tmpl.width0 = width;
        tmpl.height0 = height;
 
-       pt = api->texture_from_shared_handle(api, pscreen, &tmpl,
-                                            "front buffer", pitch, handle);
+       memset(&whandle, 0, sizeof(whandle));
+       whandle.stride = pitch;
+       whandle.handle = handle;
+
+       pt = pscreen->texture_from_handle(pscreen, &tmpl, &whandle);
        if (!pt)
                return NULL;
 
@@ -142,74 +146,10 @@ nouveau_drm_create_screen(struct drm_api *api, int fd,
        return nvws->pscreen;
 }
 
-static struct pipe_texture *
-nouveau_drm_pt_from_name(struct drm_api *api, struct pipe_screen *pscreen,
-                        struct pipe_texture *templ, const char *name,
-                        unsigned stride, unsigned handle)
-{
-       struct nouveau_device *dev = nouveau_screen(pscreen)->device;
-       struct pipe_texture *pt;
-       struct pipe_buffer *pb;
-       int ret;
-
-       pb = CALLOC(1, sizeof(struct pipe_buffer) + sizeof(struct nouveau_bo*));
-       if (!pb)
-               return NULL;
-
-       ret = nouveau_bo_handle_ref(dev, handle, (struct nouveau_bo**)(pb+1));
-       if (ret) {
-               debug_printf("%s: ref name 0x%08x failed with %d\n",
-                            __func__, handle, ret);
-               FREE(pb);
-               return NULL;
-       }
-
-       pipe_reference_init(&pb->reference, 1);
-       pb->screen = pscreen;
-       pb->alignment = 0;
-       pb->usage = PIPE_BUFFER_USAGE_GPU_READ_WRITE |
-                   PIPE_BUFFER_USAGE_CPU_READ_WRITE;
-       pb->size = nouveau_bo(pb)->size;
-       pt = pscreen->texture_blanket(pscreen, templ, &stride, pb);
-       pipe_buffer_reference(&pb, NULL);
-       return pt;
-}
-
-static boolean
-nouveau_drm_name_from_pt(struct drm_api *api, struct pipe_screen *pscreen,
-                        struct pipe_texture *pt, unsigned *stride,
-                        unsigned *handle)
-{
-       struct nouveau_miptree *mt = nouveau_miptree(pt);
-
-       if (!mt || !mt->bo)
-               return false;
-
-       return nouveau_bo_handle_get(mt->bo, handle) == 0;
-}
-
-static boolean
-nouveau_drm_handle_from_pt(struct drm_api *api, struct pipe_screen *pscreen,
-                          struct pipe_texture *pt, unsigned *stride,
-                          unsigned *handle)
-{
-       struct nouveau_miptree *mt = nouveau_miptree(pt);
-
-       if (!mt || !mt->bo)
-               return false;
-
-       *handle = mt->bo->handle;
-       *stride = util_format_get_stride(mt->base.format, mt->base.width0);
-       return true;
-}
-
 struct drm_api drm_api_hooks = {
        .name = "nouveau",
        .driver_name = "nouveau",
        .create_screen = nouveau_drm_create_screen,
-       .texture_from_shared_handle = nouveau_drm_pt_from_name,
-       .shared_handle_from_texture = nouveau_drm_name_from_pt,
-       .local_handle_from_texture = nouveau_drm_handle_from_pt,
 };
 
 struct drm_api *