Mesa (master): i915g: Treat primary textures as scanout buffers

Jakob Bornecrantz wallbraker at kemper.freedesktop.org
Wed Aug 5 17:34:00 UTC 2009


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

Author: Jakob Bornecrantz <jakob at vmware.com>
Date:   Wed Aug  5 19:22:34 2009 +0100

i915g: Treat primary textures as scanout buffers

---

 src/gallium/drivers/i915simple/i915_texture.c      |   25 +++++++----
 src/gallium/drivers/i915simple/i915_winsys.h       |    1 +
 src/gallium/winsys/drm/intel/gem/intel_be_device.c |   42 +++++++++++++++++--
 src/gallium/winsys/drm/intel/gem/intel_be_device.h |    4 ++
 4 files changed, 58 insertions(+), 14 deletions(-)

diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c
index ca8e87a..ac38bb5 100644
--- a/src/gallium/drivers/i915simple/i915_texture.c
+++ b/src/gallium/drivers/i915simple/i915_texture.c
@@ -160,10 +160,10 @@ i915_miptree_set_image_offset(struct i915_texture *tex,
 
 
 /**
- * Special case to deal with display targets.
+ * Special case to deal with scanout textures.
  */
 static boolean
-i915_displaytarget_layout(struct i915_texture *tex)
+i915_scanout_layout(struct i915_texture *tex)
 {
    struct pipe_texture *pt = &tex->base;
 
@@ -177,9 +177,13 @@ i915_displaytarget_layout(struct i915_texture *tex)
    i915_miptree_set_image_offset( tex, 0, 0, 0, 0 );
 
    if (tex->base.width[0] >= 128) {
+#if 0
       tex->stride = power_of_two(tex->base.nblocksx[0] * pt->block.size);
+#else
+      tex->stride = 2048 * 4; /* TODO fix when backend is smarter */
+#endif
       tex->total_nblocksy = round_up(tex->base.nblocksy[0], 8);
-#if 0 /* used for tiled display targets */
+#if 0 /* used for tiled textures */
       tex->tiled = 1;
 #endif
    } else {
@@ -209,9 +213,9 @@ i945_miptree_layout_2d( struct i915_texture *tex )
    unsigned nblocksx = pt->nblocksx[0];
    unsigned nblocksy = pt->nblocksy[0];
 
-   /* used for tiled display targets */
-   if (0)
-      if (i915_displaytarget_layout(tex))
+   /* used for scanouts that need special layouts */
+   if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_PRIMARY)
+      if (i915_scanout_layout(tex))
 	 return;
 
    tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4);
@@ -584,6 +588,7 @@ i915_texture_create(struct pipe_screen *screen,
    struct i915_screen *i915screen = i915_screen(screen);
    struct i915_texture *tex = CALLOC_STRUCT(i915_texture);
    size_t tex_size;
+   unsigned buf_usage = 0;
 
    if (!tex)
       return NULL;
@@ -605,9 +610,11 @@ i915_texture_create(struct pipe_screen *screen,
 
    tex_size = tex->stride * tex->total_nblocksy;
 
-   tex->buffer = screen->buffer_create(screen, 64,
-                                    PIPE_BUFFER_USAGE_PIXEL,
-                                    tex_size);
+   buf_usage = PIPE_BUFFER_USAGE_PIXEL;
+   if (templat->tex_usage & PIPE_TEXTURE_USAGE_PRIMARY)
+      buf_usage |= I915_BUFFER_USAGE_SCANOUT;
+
+   tex->buffer = screen->buffer_create(screen, 64, buf_usage, tex_size);
 
    if (!tex->buffer)
       goto fail;
diff --git a/src/gallium/drivers/i915simple/i915_winsys.h b/src/gallium/drivers/i915simple/i915_winsys.h
index ff5b34f..711db91 100644
--- a/src/gallium/drivers/i915simple/i915_winsys.h
+++ b/src/gallium/drivers/i915simple/i915_winsys.h
@@ -109,6 +109,7 @@ struct i915_winsys {
 #define I915_BUFFER_ACCESS_READ    0x2
 
 #define I915_BUFFER_USAGE_LIT_VERTEX  (PIPE_BUFFER_USAGE_CUSTOM << 0)
+#define I915_BUFFER_USAGE_SCANOUT     (PIPE_BUFFER_USAGE_CUSTOM << 1)
 
 
 /**
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 e3630f5..c7e8827 100644
--- a/src/gallium/winsys/drm/intel/gem/intel_be_device.c
+++ b/src/gallium/winsys/drm/intel/gem/intel_be_device.c
@@ -16,6 +16,8 @@
 #include "intel_be_api.h"
 #include <stdio.h>
 
+#define I915_TILING_X 1
+
 /*
  * Buffer
  */
@@ -25,9 +27,10 @@ intel_be_buffer_map(struct pipe_winsys *winsys,
 		    struct pipe_buffer *buf,
 		    unsigned flags)
 {
+	struct intel_be_buffer *buffer = intel_be_buffer(buf);
 	drm_intel_bo *bo = intel_bo(buf);
 	int write = 0;
-	int ret;
+	int ret = 0;
 
         if (flags & PIPE_BUFFER_USAGE_DONTBLOCK) {
            /* Remove this when drm_intel_bo_map supports DONTBLOCK 
@@ -38,19 +41,37 @@ intel_be_buffer_map(struct pipe_winsys *winsys,
 	if (flags & PIPE_BUFFER_USAGE_CPU_WRITE)
 		write = 1;
 
-	ret = drm_intel_bo_map(bo, write);
+	if (buffer->map_count)
+		goto out;
+
+	if (buffer->map_gtt)
+		ret = drm_intel_gem_bo_map_gtt(bo);
+	else
+		ret = drm_intel_bo_map(bo, write);
+
+	buffer->ptr = bo->virtual;
 
+out:
 	if (ret)
 		return NULL;
 
-	return bo->virtual;
+	buffer->map_count++;
+	return buffer->ptr;
 }
 
 static void
 intel_be_buffer_unmap(struct pipe_winsys *winsys,
 		      struct pipe_buffer *buf)
 {
-	drm_intel_bo_unmap(intel_bo(buf));
+	struct intel_be_buffer *buffer = intel_be_buffer(buf);
+
+	if (--buffer->map_count)
+		return;
+
+	if (buffer->map_gtt)
+		drm_intel_gem_bo_unmap_gtt(intel_bo(buf));
+	else
+		drm_intel_bo_unmap(intel_bo(buf));
 }
 
 static void
@@ -80,8 +101,13 @@ intel_be_buffer_create(struct pipe_winsys *winsys,
 	buffer->base.size = size;
 	buffer->flinked = FALSE;
 	buffer->flink = 0;
+	buffer->map_gtt = FALSE;
 
-	if (usage & (PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_CONSTANT)) {
+	if (usage & I915_BUFFER_USAGE_SCANOUT) {
+		/* Scanout buffer */
+		name = "gallium3d_scanout";
+		pool = dev->pools.gem;
+	} else if (usage & (PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_CONSTANT)) {
 		/* Local buffer */
 		name = "gallium3d_local";
 		pool = dev->pools.gem;
@@ -96,6 +122,12 @@ intel_be_buffer_create(struct pipe_winsys *winsys,
 	}
 
 	buffer->bo = drm_intel_bo_alloc(pool, name, size, alignment);
+	if (usage & I915_BUFFER_USAGE_SCANOUT) {
+		unsigned tiling = I915_TILING_X;
+		unsigned stride = 2048 * 4; /* TODO do something smarter here */
+		drm_intel_bo_set_tiling(buffer->bo, &tiling, stride);
+		buffer->map_gtt = TRUE;
+	}
 
 	if (!buffer->bo)
 		goto err;
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 56d95bd..3f3f2a7 100644
--- a/src/gallium/winsys/drm/intel/gem/intel_be_device.h
+++ b/src/gallium/winsys/drm/intel/gem/intel_be_device.h
@@ -47,6 +47,10 @@ intel_be_init_device(struct intel_be_device *device, int fd, unsigned id);
 
 struct intel_be_buffer {
 	struct pipe_buffer base;
+	void *ptr;
+	unsigned map_count;
+	boolean map_gtt;
+
 	drm_intel_bo *bo;
 	boolean flinked;
 	unsigned flink;




More information about the mesa-commit mailing list