Mesa (master): drm_api: Operate on textures instead of buffers

Jakob Bornecrantz wallbraker at kemper.freedesktop.org
Fri Aug 28 13:43:47 UTC 2009


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

Author: Jakob Bornecrantz <jakob at vmware.com>
Date:   Thu Aug 27 18:57:29 2009 +0100

drm_api: Operate on textures instead of buffers

Most use cases just got the buffer from the texture
	and then called into one of the get_handle functions.

	Also with this patch it would be easier to move to a
	generic function for getting handles from textures
	and textures from handles, that is exposed via the screen.

---

 src/gallium/drivers/identity/id_drm.c              |   90 +++++++----------
 src/gallium/drivers/trace/tr_drm.c                 |   87 ++++++-----------
 src/gallium/include/state_tracker/drm_api.h        |   29 +++---
 src/gallium/state_trackers/dri/dri_drawable.c      |   13 +--
 src/gallium/state_trackers/egl/egl_surface.c       |    9 +--
 src/gallium/state_trackers/xorg/xorg_crtc.c        |   64 ++++++++-----
 src/gallium/state_trackers/xorg/xorg_dri2.c        |    6 +-
 src/gallium/state_trackers/xorg/xorg_exa.c         |    5 +-
 src/gallium/winsys/drm/intel/gem/intel_be_api.c    |    7 +-
 src/gallium/winsys/drm/intel/gem/intel_be_device.c |  102 +++++++++++++-------
 src/gallium/winsys/drm/intel/gem/intel_be_device.h |   46 ++++-----
 11 files changed, 223 insertions(+), 235 deletions(-)

diff --git a/src/gallium/drivers/identity/id_drm.c b/src/gallium/drivers/identity/id_drm.c
index e5342ac..14f68ac 100644
--- a/src/gallium/drivers/identity/id_drm.c
+++ b/src/gallium/drivers/identity/id_drm.c
@@ -29,6 +29,7 @@
 
 #include "util/u_memory.h"
 #include "identity/id_drm.h"
+#include "identity/id_screen.h"
 #include "identity/id_public.h"
 #include "identity/id_screen.h"
 #include "identity/id_objects.h"
@@ -79,81 +80,59 @@ identity_drm_create_context(struct drm_api *_api,
    return pipe;
 }
 
-static boolean
-identity_drm_buffer_from_texture(struct drm_api *_api,
-                                 struct pipe_texture *_texture,
-                                 struct pipe_buffer **_buffer,
-                                 unsigned *stride)
-{
-   struct identity_texture *id_texture = identity_texture(_texture);
-   struct identity_drm_api *id_api = identity_drm_api(_api);
-   struct pipe_texture *texture = id_texture->texture;
-   struct drm_api *api = id_api->api;
-   struct pipe_buffer *buffer = NULL;
-   boolean result;
-
-   result = api->buffer_from_texture(api, texture, &buffer, stride);
-
-   if (result && _buffer)
-      buffer = identity_buffer_create(identity_screen(texture->screen), buffer);
-
-   if (_buffer)
-      *_buffer = buffer;
-   else
-      pipe_buffer_reference(&buffer, NULL);
-
-   return result;
-}
-
-static struct pipe_buffer *
-identity_drm_buffer_from_handle(struct drm_api *_api,
-                                struct pipe_screen *_screen,
-                                const char *name,
-                                unsigned handle)
+static struct pipe_texture *
+identity_drm_texture_from_shared_handle(struct drm_api *_api,
+                                        struct pipe_screen *_screen,
+                                        struct pipe_texture *templ,
+                                        const char *name,
+                                        unsigned stride,
+                                        unsigned handle)
 {
    struct identity_screen *id_screen = identity_screen(_screen);
    struct identity_drm_api *id_api = identity_drm_api(_api);
    struct pipe_screen *screen = id_screen->screen;
    struct drm_api *api = id_api->api;
-   struct pipe_buffer *result;
+   struct pipe_texture *result;
 
-   result = api->buffer_from_handle(api, screen, name, handle);
+   result = api->texture_from_shared_handle(api, screen, templ, name, stride, handle);
 
-   result = identity_buffer_create(identity_screen(_screen), result);
+   result = identity_texture_create(identity_screen(_screen), result);
 
    return result;
 }
 
 static boolean
-identity_drm_handle_from_buffer(struct drm_api *_api,
-                                struct pipe_screen *_screen,
-                                struct pipe_buffer *_buffer,
-                                unsigned *handle)
+identity_drm_shared_handle_from_texture(struct drm_api *_api,
+                                        struct pipe_screen *_screen,
+                                        struct pipe_texture *_texture,
+                                        unsigned *stride,
+                                        unsigned *handle)
 {
    struct identity_screen *id_screen = identity_screen(_screen);
-   struct identity_buffer *id_buffer = identity_buffer(_buffer);
+   struct identity_texture *id_texture = identity_texture(_texture);
    struct identity_drm_api *id_api = identity_drm_api(_api);
    struct pipe_screen *screen = id_screen->screen;
-   struct pipe_buffer *buffer = id_buffer->buffer;
+   struct pipe_texture *texture = id_texture->texture;
    struct drm_api *api = id_api->api;
 
-   return api->handle_from_buffer(api, screen, buffer, handle);
+   return api->shared_handle_from_texture(api, screen, texture, stride, handle);
 }
 
 static boolean
-identity_drm_global_handle_from_buffer(struct drm_api *_api,
+identity_drm_local_handle_from_texture(struct drm_api *_api,
                                        struct pipe_screen *_screen,
-                                       struct pipe_buffer *_buffer,
+                                       struct pipe_texture *_texture,
+                                       unsigned *stride,
                                        unsigned *handle)
 {
    struct identity_screen *id_screen = identity_screen(_screen);
-   struct identity_buffer *id_buffer = identity_buffer(_buffer);
+   struct identity_texture *id_texture = identity_texture(_texture);
    struct identity_drm_api *id_api = identity_drm_api(_api);
    struct pipe_screen *screen = id_screen->screen;
-   struct pipe_buffer *buffer = id_buffer->buffer;
+   struct pipe_texture *texture = id_texture->texture;
    struct drm_api *api = id_api->api;
 
-   return api->global_handle_from_buffer(api, screen, buffer, handle);
+   return api->local_handle_from_texture(api, screen, texture, stride, handle);
 }
 
 static void
@@ -169,19 +148,26 @@ identity_drm_destroy(struct drm_api *_api)
 struct drm_api *
 identity_drm_create(struct drm_api *api)
 {
-   struct identity_drm_api *id_api = CALLOC_STRUCT(identity_drm_api);
+   struct identity_drm_api *id_api;
+
+   if (!api)
+      goto error;
+
+   id_api = CALLOC_STRUCT(identity_drm_api);
 
    if (!id_api)
-      return NULL;
+      goto error;
 
    id_api->base.create_screen = identity_drm_create_screen;
    id_api->base.create_context = identity_drm_create_context;
-   id_api->base.buffer_from_texture = identity_drm_buffer_from_texture;
-   id_api->base.buffer_from_handle = identity_drm_buffer_from_handle;
-   id_api->base.handle_from_buffer = identity_drm_handle_from_buffer;
-   id_api->base.global_handle_from_buffer = identity_drm_global_handle_from_buffer;
+   id_api->base.texture_from_shared_handle = identity_drm_texture_from_shared_handle;
+   id_api->base.shared_handle_from_texture = identity_drm_shared_handle_from_texture;
+   id_api->base.local_handle_from_texture = identity_drm_local_handle_from_texture;
    id_api->base.destroy = identity_drm_destroy;
    id_api->api = api;
 
    return &id_api->base;
+
+error:
+   return api;
 }
diff --git a/src/gallium/drivers/trace/tr_drm.c b/src/gallium/drivers/trace/tr_drm.c
index 93c569c..781ca5d 100644
--- a/src/gallium/drivers/trace/tr_drm.c
+++ b/src/gallium/drivers/trace/tr_drm.c
@@ -49,7 +49,7 @@ trace_drm_api(struct drm_api *_api)
 
 static struct pipe_screen *
 trace_drm_create_screen(struct drm_api *_api, int fd,
-                           struct drm_create_screen_arg *arg)
+                        struct drm_create_screen_arg *arg)
 {
    struct trace_drm_api *tr_api = trace_drm_api(_api);
    struct drm_api *api = tr_api->api;
@@ -67,7 +67,7 @@ trace_drm_create_screen(struct drm_api *_api, int fd,
 
 static struct pipe_context *
 trace_drm_create_context(struct drm_api *_api,
-                            struct pipe_screen *_screen)
+                         struct pipe_screen *_screen)
 {
    struct trace_screen *tr_screen = trace_screen(_screen);
    struct trace_drm_api *tr_api = trace_drm_api(_api);
@@ -84,89 +84,65 @@ trace_drm_create_context(struct drm_api *_api,
    return pipe;
 }
 
-static boolean
-trace_drm_buffer_from_texture(struct drm_api *_api,
-                                 struct pipe_texture *_texture,
-                                 struct pipe_buffer **_buffer,
-                                 unsigned *stride)
-{
-   struct trace_texture *tr_texture = trace_texture(_texture);
-   struct trace_drm_api *tr_api = trace_drm_api(_api);
-   struct pipe_texture *texture = tr_texture->texture;
-   struct drm_api *api = tr_api->api;
-   struct pipe_buffer *buffer = NULL;
-   boolean result;
-
-   /* TODO trace call */
-
-   result = api->buffer_from_texture(api, texture, &buffer, stride);
-
-   if (result && _buffer)
-      buffer = trace_buffer_create(trace_screen(_texture->screen), buffer);
-
-   if (_buffer)
-      *_buffer = buffer;
-   else
-      pipe_buffer_reference(&buffer, NULL);
-
-   return result;
-}
-
-static struct pipe_buffer *
-trace_drm_buffer_from_handle(struct drm_api *_api,
-                                struct pipe_screen *_screen,
-                                const char *name,
-                                unsigned handle)
+static struct pipe_texture *
+trace_drm_texture_from_shared_handle(struct drm_api *_api,
+                                     struct pipe_screen *_screen,
+                                     struct pipe_texture *templ,
+                                     const char *name,
+                                     unsigned stride,
+                                     unsigned handle)
 {
    struct trace_screen *tr_screen = trace_screen(_screen);
    struct trace_drm_api *tr_api = trace_drm_api(_api);
    struct pipe_screen *screen = tr_screen->screen;
    struct drm_api *api = tr_api->api;
-   struct pipe_buffer *result;
+   struct pipe_texture *result;
 
    /* TODO trace call */
 
-   result = api->buffer_from_handle(api, screen, name, handle);
+   result = api->texture_from_shared_handle(api, screen, templ, name, stride, handle);
 
-   result = trace_buffer_create(trace_screen(_screen), result);
+   result = trace_texture_create(trace_screen(_screen), result);
 
    return result;
 }
 
 static boolean
-trace_drm_handle_from_buffer(struct drm_api *_api,
-                                struct pipe_screen *_screen,
-                                struct pipe_buffer *_buffer,
-                                unsigned *handle)
+trace_drm_shared_handle_from_texture(struct drm_api *_api,
+                                     struct pipe_screen *_screen,
+                                     struct pipe_texture *_texture,
+                                     unsigned *stride,
+                                     unsigned *handle)
 {
    struct trace_screen *tr_screen = trace_screen(_screen);
-   struct trace_buffer *tr_buffer = trace_buffer(_buffer);
+   struct trace_texture *tr_texture = trace_texture(_texture);
    struct trace_drm_api *tr_api = trace_drm_api(_api);
    struct pipe_screen *screen = tr_screen->screen;
-   struct pipe_buffer *buffer = tr_buffer->buffer;
+   struct pipe_texture *texture = tr_texture->texture;
    struct drm_api *api = tr_api->api;
 
    /* TODO trace call */
 
-   return api->handle_from_buffer(api, screen, buffer, handle);
+   return api->shared_handle_from_texture(api, screen, texture, stride, handle);
 }
 
 static boolean
-trace_drm_global_handle_from_buffer(struct drm_api *_api,
-                                       struct pipe_screen *_screen,
-                                       struct pipe_buffer *_buffer,
-                                       unsigned *handle)
+trace_drm_local_handle_from_texture(struct drm_api *_api,
+                                    struct pipe_screen *_screen,
+                                    struct pipe_texture *_texture,
+                                    unsigned *stride,
+                                    unsigned *handle)
 {
    struct trace_screen *tr_screen = trace_screen(_screen);
-   struct trace_buffer *tr_buffer = trace_buffer(_buffer);
+   struct trace_texture *tr_texture = trace_texture(_texture);
    struct trace_drm_api *tr_api = trace_drm_api(_api);
    struct pipe_screen *screen = tr_screen->screen;
-   struct pipe_buffer *buffer = tr_buffer->buffer;
+   struct pipe_texture *texture = tr_texture->texture;
    struct drm_api *api = tr_api->api;
 
    /* TODO trace call */
 
-   return api->global_handle_from_buffer(api, screen, buffer, handle);
+   return api->local_handle_from_texture(api, screen, texture, stride, handle);
 }
 
 static void
@@ -197,10 +173,9 @@ trace_drm_create(struct drm_api *api)
 
    tr_api->base.create_screen = trace_drm_create_screen;
    tr_api->base.create_context = trace_drm_create_context;
-   tr_api->base.buffer_from_texture = trace_drm_buffer_from_texture;
-   tr_api->base.buffer_from_handle = trace_drm_buffer_from_handle;
-   tr_api->base.handle_from_buffer = trace_drm_handle_from_buffer;
-   tr_api->base.global_handle_from_buffer = trace_drm_global_handle_from_buffer;
+   tr_api->base.texture_from_shared_handle = trace_drm_texture_from_shared_handle;
+   tr_api->base.shared_handle_from_texture = trace_drm_shared_handle_from_texture;
+   tr_api->base.local_handle_from_texture = trace_drm_local_handle_from_texture;
    tr_api->base.destroy = trace_drm_destroy;
    tr_api->api = api;
 
diff --git a/src/gallium/include/state_tracker/drm_api.h b/src/gallium/include/state_tracker/drm_api.h
index 7a38b50..4d1259e 100644
--- a/src/gallium/include/state_tracker/drm_api.h
+++ b/src/gallium/include/state_tracker/drm_api.h
@@ -42,21 +42,22 @@ struct drm_api
 	 * Special buffer functions
 	 */
 	/*@{*/
-	boolean (*buffer_from_texture)(struct drm_api *api,
-	                               struct pipe_texture *texture,
-	                               struct pipe_buffer **buffer,
-	                               unsigned *stride);
-	struct pipe_buffer* (*buffer_from_handle)(struct drm_api *api,
-	                                          struct pipe_screen *screen,
-                                                  const char *name,
-                                                  unsigned handle);
-	boolean (*handle_from_buffer)(struct drm_api *api,
-	                              struct pipe_screen *screen,
-	                              struct pipe_buffer *buffer,
-	                              unsigned *handle);
-	boolean (*global_handle_from_buffer)(struct drm_api *api,
+	struct pipe_texture*
+	    (*texture_from_shared_handle)(struct drm_api *api,
+	                                  struct pipe_screen *screen,
+	                                  struct pipe_texture *templ,
+	                                  const char *name,
+	                                  unsigned stride,
+	                                  unsigned handle);
+	boolean (*shared_handle_from_texture)(struct drm_api *api,
+	                                      struct pipe_screen *screen,
+	                                      struct pipe_texture *texture,
+	                                      unsigned *stride,
+	                                      unsigned *handle);
+	boolean (*local_handle_from_texture)(struct drm_api *api,
 	                                     struct pipe_screen *screen,
-	                                     struct pipe_buffer *buffer,
+	                                     struct pipe_texture *texture,
+	                                     unsigned *stride,
 	                                     unsigned *handle);
 	/*@}*/
 
diff --git a/src/gallium/state_trackers/dri/dri_drawable.c b/src/gallium/state_trackers/dri/dri_drawable.c
index 2265187..bcfd1c0 100644
--- a/src/gallium/state_trackers/dri/dri_drawable.c
+++ b/src/gallium/state_trackers/dri/dri_drawable.c
@@ -56,13 +56,6 @@ dri_surface_from_handle(struct drm_api *api,
    struct pipe_surface *surface = NULL;
    struct pipe_texture *texture = NULL;
    struct pipe_texture templat;
-   struct pipe_buffer *buf = NULL;
-
-   buf = api->buffer_from_handle(api, screen, "dri2 buffer", handle);
-   if (!buf) {
-      debug_printf("%s: Failed to get buffer from handle\n", __func__);
-      return NULL;
-   }
 
    memset(&templat, 0, sizeof(templat));
    templat.tex_usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET;
@@ -74,10 +67,8 @@ dri_surface_from_handle(struct drm_api *api,
    templat.height[0] = height;
    pf_get_block(templat.format, &templat.block);
 
-   texture = screen->texture_blanket(screen, &templat, &pitch, buf);
-
-   /* we don't need the buffer from this point on */
-   pipe_buffer_reference(&buf, NULL);
+   texture = api->texture_from_shared_handle(api, screen, &templat,
+                                             "dri2 buffer", pitch, handle);
 
    if (!texture) {
       debug_printf("%s: Failed to blanket the buffer with a texture\n", __func__);
diff --git a/src/gallium/state_trackers/egl/egl_surface.c b/src/gallium/state_trackers/egl/egl_surface.c
index 3ef1945..69e2d6b 100644
--- a/src/gallium/state_trackers/egl/egl_surface.c
+++ b/src/gallium/state_trackers/egl/egl_surface.c
@@ -96,10 +96,6 @@ drm_create_texture(_EGLDisplay *dpy,
 	if (!texture)
 		goto err_tex;
 
-	dev->api->buffer_from_texture(dev->api, texture, &buf, &pitch);
-	if (!buf)
-		goto err_buf;
-
 	surface = screen->get_tex_surface(screen,
 	                                  texture,
 	                                  0,
@@ -112,11 +108,11 @@ drm_create_texture(_EGLDisplay *dpy,
 
 	scrn->tex = texture;
 	scrn->surface = surface;
-	scrn->buffer = buf;
 	scrn->front.width = w;
 	scrn->front.height = h;
 	scrn->front.pitch = pitch;
-	dev->api->handle_from_buffer(dev->api, screen, scrn->buffer, &scrn->front.handle);
+	dev->api->local_handle_from_texture(dev->api, screen, texture,
+	                                    &scrn->front.pitch, &scrn->front.handle);
 	if (0)
 		goto err_handle;
 
@@ -126,7 +122,6 @@ err_handle:
 	pipe_surface_reference(&surface, NULL);
 err_surf:
 	pipe_texture_reference(&texture, NULL);
-err_buf:
 err_tex:
 	pipe_buffer_reference(&buf, NULL);
 	return;
diff --git a/src/gallium/state_trackers/xorg/xorg_crtc.c b/src/gallium/state_trackers/xorg/xorg_crtc.c
index 2110c87..fe08bde 100644
--- a/src/gallium/state_trackers/xorg/xorg_crtc.c
+++ b/src/gallium/state_trackers/xorg/xorg_crtc.c
@@ -46,13 +46,14 @@
 #include <X11/extensions/dpms.h>
 
 #include "pipe/p_inlines.h"
+#include "util/u_rect.h"
 
 struct crtc_private
 {
     drmModeCrtcPtr drm_crtc;
 
     /* hwcursor */
-    struct pipe_buffer *cursor_buf;
+    struct pipe_texture *cursor_tex;
     unsigned cursor_handle;
 };
 
@@ -173,8 +174,8 @@ crtc_destroy(xf86CrtcPtr crtc)
 {
     struct crtc_private *crtcp = crtc->driver_private;
 
-    if (crtcp->cursor_buf)
-	pipe_buffer_reference(&crtcp->cursor_buf, NULL);
+    if (crtcp->cursor_tex)
+	pipe_texture_reference(&crtcp->cursor_tex, NULL);
 
     drmModeFreeCrtc(crtcp->drm_crtc);
     xfree(crtcp);
@@ -186,25 +187,42 @@ crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 * image)
     unsigned char *ptr;
     modesettingPtr ms = modesettingPTR(crtc->scrn);
     struct crtc_private *crtcp = crtc->driver_private;
-
-    if (!crtcp->cursor_buf) {
-	crtcp->cursor_buf = pipe_buffer_create(ms->screen,
-					       0,
-					       PIPE_BUFFER_USAGE_CPU_WRITE |
-					       PIPE_BUFFER_USAGE_GPU_READ,
-					       64*64*4);
-	ms->api->handle_from_buffer(ms->api,
-				    ms->screen,
-				    crtcp->cursor_buf,
-				    &crtcp->cursor_handle);
+    struct pipe_transfer *transfer;
+
+    if (!crtcp->cursor_tex) {
+	struct pipe_texture templat;
+	unsigned pitch;
+
+	memset(&templat, 0, sizeof(templat));
+	templat.tex_usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET;
+	templat.tex_usage |= PIPE_TEXTURE_USAGE_PRIMARY;
+	templat.target = PIPE_TEXTURE_2D;
+	templat.last_level = 0;
+	templat.depth[0] = 1;
+	templat.format = PIPE_FORMAT_A8R8G8B8_UNORM;
+	templat.width[0] = 64;
+	templat.height[0] = 64;
+	pf_get_block(templat.format, &templat.block);
+
+	crtcp->cursor_tex = ms->screen->texture_create(ms->screen,
+						       &templat);
+	ms->api->local_handle_from_texture(ms->api,
+					   ms->screen,
+					   crtcp->cursor_tex,
+					   &pitch,
+					   &crtcp->cursor_handle);
     }
 
-    ptr = pipe_buffer_map(ms->screen, crtcp->cursor_buf, PIPE_BUFFER_USAGE_CPU_WRITE);
-
-    if (ptr)
-	memcpy(ptr, image, 64 * 64 * 4);
-
-    pipe_buffer_unmap(ms->screen, crtcp->cursor_buf);
+    transfer = ms->screen->get_tex_transfer(ms->screen, crtcp->cursor_tex,
+					    0, 0, 0,
+					    PIPE_TRANSFER_WRITE,
+					    0, 0, 64, 64);
+    ptr = ms->screen->transfer_map(ms->screen, transfer);
+    util_copy_rect(ptr, &crtcp->cursor_tex->block,
+		   transfer->stride, 0, 0,
+		   64, 64, (void*)image, 64 * 4, 0, 0);
+    ms->screen->transfer_unmap(ms->screen, transfer);
+    ms->screen->tex_transfer_destroy(transfer);
 }
 
 static void
@@ -222,7 +240,7 @@ crtc_show_cursor(xf86CrtcPtr crtc)
     modesettingPtr ms = modesettingPTR(crtc->scrn);
     struct crtc_private *crtcp = crtc->driver_private;
 
-    if (crtcp->cursor_buf)
+    if (crtcp->cursor_tex)
 	drmModeSetCursor(ms->fd, crtcp->drm_crtc->crtc_id,
 			 crtcp->cursor_handle, 64, 64);
 }
@@ -264,8 +282,8 @@ crtc_cursor_destroy(xf86CrtcPtr crtc)
 {
     struct crtc_private *crtcp = crtc->driver_private;
 
-    if (crtcp->cursor_buf) {
-	pipe_buffer_reference(&crtcp->cursor_buf, NULL);
+    if (crtcp->cursor_tex) {
+	pipe_texture_reference(&crtcp->cursor_tex, NULL);
     }
 }
 
diff --git a/src/gallium/state_trackers/xorg/xorg_dri2.c b/src/gallium/state_trackers/xorg/xorg_dri2.c
index c48fb30..3b90421 100644
--- a/src/gallium/state_trackers/xorg/xorg_dri2.c
+++ b/src/gallium/state_trackers/xorg/xorg_dri2.c
@@ -44,7 +44,6 @@
 typedef struct {
     PixmapPtr pPixmap;
     struct pipe_texture *tex;
-    struct pipe_buffer *buf;
     struct pipe_fence_handle *fence;
 } *BufferPrivatePtr;
 
@@ -133,8 +132,7 @@ driCreateBuffers(DrawablePtr pDraw, unsigned int *attachments, int count)
 	if (!tex)
 		FatalError("NO TEXTURE IN DRI2\n");
 
-	ms->api->buffer_from_texture(ms->api, tex, &buf, &stride);
-	ms->api->global_handle_from_buffer(ms->api, ms->screen, buf, &handle);
+	ms->api->shared_handle_from_texture(ms->api, ms->screen, tex, &stride, &handle);
 
 	buffers[i].name = handle;
 	buffers[i].attachment = attachments[i];
@@ -143,7 +141,6 @@ driCreateBuffers(DrawablePtr pDraw, unsigned int *attachments, int count)
 	buffers[i].driverPrivate = &privates[i];
 	buffers[i].flags = 0; /* not tiled */
 	privates[i].pPixmap = pPixmap;
-	privates[i].buf = buf;
 	privates[i].tex = tex;
     }
 
@@ -169,7 +166,6 @@ driDestroyBuffers(DrawablePtr pDraw, DRI2BufferPtr buffers, int count)
 	private = buffers[i].driverPrivate;
 
 	pipe_texture_reference(&private->tex, NULL);
-	pipe_buffer_reference(&private->buf, NULL);
         ms->screen->fence_reference(ms->screen, &private->fence, NULL);
 
 	if (private->pPixmap)
diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c
index 9bd28a8..acc49f4 100644
--- a/src/gallium/state_trackers/xorg/xorg_exa.c
+++ b/src/gallium/state_trackers/xorg/xorg_exa.c
@@ -396,7 +396,6 @@ xorg_exa_get_pixmap_handle(PixmapPtr pPixmap, unsigned *stride_out)
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
     modesettingPtr ms = modesettingPTR(pScrn);
     struct exa_pixmap_priv *priv;
-    struct pipe_buffer *buffer = NULL;
     unsigned handle;
     unsigned stride;
 
@@ -412,9 +411,7 @@ xorg_exa_get_pixmap_handle(PixmapPtr pPixmap, unsigned *stride_out)
 	return 0;
     }
 
-    ms->api->buffer_from_texture(ms->api, priv->tex, &buffer, &stride);
-    ms->api->handle_from_buffer(ms->api, ms->screen, buffer, &handle);
-    pipe_buffer_reference(&buffer, NULL);
+    ms->api->local_handle_from_texture(ms->api, ms->screen, priv->tex, &stride, &handle);
     if (stride_out)
 	*stride_out = stride;
 
diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_api.c b/src/gallium/winsys/drm/intel/gem/intel_be_api.c
index dd5f814..3e90088 100644
--- a/src/gallium/winsys/drm/intel/gem/intel_be_api.c
+++ b/src/gallium/winsys/drm/intel/gem/intel_be_api.c
@@ -15,10 +15,9 @@ struct drm_api intel_be_drm_api =
 	.create_context = intel_be_create_context,
 	/* intel_be_device.c */
 	.create_screen = intel_be_create_screen,
-	.buffer_from_texture = intel_be_get_texture_buffer,
-	.buffer_from_handle = intel_be_buffer_from_handle,
-	.handle_from_buffer = intel_be_handle_from_buffer,
-	.global_handle_from_buffer = intel_be_global_handle_from_buffer,
+	.texture_from_shared_handle = intel_be_texture_from_shared_handle,
+	.shared_handle_from_texture = intel_be_shared_handle_from_texture,
+	.local_handle_from_texture = intel_be_local_handle_from_texture,
 	.destroy = destroy,
 };
 
diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_device.c b/src/gallium/winsys/drm/intel/gem/intel_be_device.c
index 5312865..f58334f 100644
--- a/src/gallium/winsys/drm/intel/gem/intel_be_device.c
+++ b/src/gallium/winsys/drm/intel/gem/intel_be_device.c
@@ -209,25 +209,7 @@ intel_be_surface_buffer_create(struct pipe_winsys *winsys,
 	                              buf_size);
 }
 
-boolean
-intel_be_get_texture_buffer(struct drm_api *api,
-                            struct pipe_texture *texture,
-                            struct pipe_buffer **buffer,
-                            unsigned *stride)
-{
-	struct intel_be_device *dev;
-
-	if (!texture)
-		return FALSE;
-
-	dev = intel_be_device(texture->screen->winsys);
-	if (dev->softpipe)
-		return softpipe_get_texture_buffer(texture, buffer, stride);
-	else
-		return i915_get_texture_buffer(texture, buffer, stride);
-}
-
-struct pipe_buffer *
+static struct pipe_buffer *
 intel_be_buffer_from_handle(struct drm_api *api,
                             struct pipe_screen *screen,
                             const char* name, unsigned handle)
@@ -259,30 +241,60 @@ err:
 	return NULL;
 }
 
-boolean
-intel_be_handle_from_buffer(struct drm_api *api,
-                            struct pipe_screen *screen,
-                            struct pipe_buffer *buffer,
-                            unsigned *handle)
+struct pipe_texture *
+intel_be_texture_from_shared_handle(struct drm_api *api,
+                                    struct pipe_screen *screen,
+                                    struct pipe_texture *templ,
+                                    const char* name,
+                                    unsigned pitch,
+                                    unsigned handle)
 {
+	struct pipe_buffer *buffer;
+
+	buffer = intel_be_buffer_from_handle(api,
+	                                     screen,
+	                                     name,
+	                                     handle);
 	if (!buffer)
+		return NULL;
+
+	return screen->texture_blanket(screen, templ, &pitch, buffer);
+}
+
+static boolean
+intel_be_get_texture_buffer(struct drm_api *api,
+                            struct pipe_texture *texture,
+                            struct pipe_buffer **buffer,
+                            unsigned *stride)
+{
+	struct intel_be_device *dev;
+
+	if (!texture)
 		return FALSE;
 
-	*handle = intel_bo(buffer)->handle;
-	return TRUE;
+	dev = intel_be_device(texture->screen->winsys);
+	if (dev->softpipe)
+		return softpipe_get_texture_buffer(texture, buffer, stride);
+	else
+		return i915_get_texture_buffer(texture, buffer, stride);
 }
 
 boolean
-intel_be_global_handle_from_buffer(struct drm_api *api,
-                                   struct pipe_screen *screen,
-				   struct pipe_buffer *buffer,
-				   unsigned *handle)
+intel_be_shared_handle_from_texture(struct drm_api *api,
+                                    struct pipe_screen *screen,
+                                    struct pipe_texture *texture,
+                                    unsigned *pitch,
+                                    unsigned *handle)
 {
-	struct intel_be_buffer *buf = intel_be_buffer(buffer);
-
-	if (!buffer)
+	struct pipe_buffer *buffer;
+	struct intel_be_buffer *buf;
+	if (!intel_be_get_texture_buffer(api,
+	                                 texture,
+	                                 &buffer,
+	                                 pitch))
 		return FALSE;
 
+	buf = intel_be_buffer(buffer);
 	if (!buf->flinked) {
 		if (drm_intel_bo_flink(intel_bo(buffer), &buf->flink))
 			return FALSE;
@@ -290,6 +302,30 @@ intel_be_global_handle_from_buffer(struct drm_api *api,
 	}
 
 	*handle = buf->flink;
+
+	pipe_buffer_reference(&buffer, NULL);
+
+	return TRUE;
+}
+
+boolean
+intel_be_local_handle_from_texture(struct drm_api *api,
+                                   struct pipe_screen *screen,
+                                   struct pipe_texture *texture,
+                                   unsigned *pitch,
+                                   unsigned *handle)
+{
+	struct pipe_buffer *buffer;
+	if (!intel_be_get_texture_buffer(api,
+	                                 texture,
+	                                 &buffer,
+	                                 pitch))
+		return FALSE;
+
+	*handle = intel_bo(buffer)->handle;
+
+	pipe_buffer_reference(&buffer, NULL);
+
 	return TRUE;
 }
 
diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_device.h b/src/gallium/winsys/drm/intel/gem/intel_be_device.h
index c397048..15916b0 100644
--- a/src/gallium/winsys/drm/intel/gem/intel_be_device.h
+++ b/src/gallium/winsys/drm/intel/gem/intel_be_device.h
@@ -57,45 +57,39 @@ struct intel_be_buffer {
 	unsigned flink;
 };
 
-/*
- * Wrapper for driver get_texture_buffer functions.
- */
-boolean
-intel_be_get_texture_buffer(struct drm_api *api,
-                            struct pipe_texture *texture,
-                            struct pipe_buffer **buffer,
-                            unsigned *stride);
-
 /**
- * Create a be buffer from a drm bo handle.
- *
- * Takes a reference.
+ * Create a texture from a shared drm handle.
  */
-struct pipe_buffer *
-intel_be_buffer_from_handle(struct drm_api *api,
-                            struct pipe_screen *screen,
-                            const char* name, unsigned handle);
+struct pipe_texture *
+intel_be_texture_from_shared_handle(struct drm_api *api,
+                                    struct pipe_screen *screen,
+                                    struct pipe_texture *templ,
+                                    const char* name,
+                                    unsigned pitch,
+                                    unsigned handle);
 
 /**
- * Gets a handle from a buffer.
+ * Gets a shared handle from a texture.
  *
- * If buffer is destroyed handle may become invalid.
+ * If texture is destroyed handle may become invalid.
  */
 boolean
-intel_be_handle_from_buffer(struct drm_api *api,
-                            struct pipe_screen *screen,
-                            struct pipe_buffer *buffer,
-                            unsigned *handle);
+intel_be_shared_handle_from_texture(struct drm_api *api,
+                                    struct pipe_screen *screen,
+                                    struct pipe_texture *texture,
+                                    unsigned *pitch,
+                                    unsigned *handle);
 
 /**
- * Gets the global handle from a buffer.
+ * Gets the local handle from a texture. As used by KMS.
  *
- * If buffer is destroyed handle may become invalid.
+ * If texture is destroyed handle may become invalid.
  */
 boolean
-intel_be_global_handle_from_buffer(struct drm_api *api,
+intel_be_local_handle_from_texture(struct drm_api *api,
                                    struct pipe_screen *screen,
-                                   struct pipe_buffer *buffer,
+                                   struct pipe_texture *texture,
+                                   unsigned *pitch,
                                    unsigned *handle);
 
 static INLINE struct intel_be_buffer *




More information about the mesa-commit mailing list