Mesa (master): nouveau: Conversion to winsys handle

Keith Whitwell keithw at kemper.freedesktop.org
Mon Mar 8 12:04:19 UTC 2010


Module: Mesa
Branch: master
Commit: 3bd622d64ec3826d3563a5cd9790cd7accc123b4
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=3bd622d64ec3826d3563a5cd9790cd7accc123b4

Author: Jakob Bornecrantz <jakob at vmware.com>
Date:   Thu Mar  4 14:36:51 2010 +0000

nouveau: Conversion to winsys handle

Not the best conversion that could be done.

---

 src/gallium/drivers/nouveau/nouveau_screen.c       |   72 ++++++++++++++++++++
 .../winsys/drm/nouveau/drm/nouveau_drm_api.c       |   72 ++------------------
 2 files changed, 78 insertions(+), 66 deletions(-)

diff --git a/src/gallium/drivers/nouveau/nouveau_screen.c b/src/gallium/drivers/nouveau/nouveau_screen.c
index 3c2f771..2013eef 100644
--- a/src/gallium/drivers/nouveau/nouveau_screen.c
+++ b/src/gallium/drivers/nouveau/nouveau_screen.c
@@ -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;
 }
 
diff --git a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c
index 80b5a4c..af9e92e 100644
--- a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c
+++ b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c
@@ -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 *




More information about the mesa-commit mailing list