i915g: Treat primary textures as scanout buffers
authorJakob Bornecrantz <jakob@vmware.com>
Wed, 5 Aug 2009 18:22:34 +0000 (19:22 +0100)
committerJakob Bornecrantz <jakob@vmware.com>
Wed, 5 Aug 2009 18:29:30 +0000 (19:29 +0100)
src/gallium/drivers/i915simple/i915_texture.c
src/gallium/drivers/i915simple/i915_winsys.h
src/gallium/winsys/drm/intel/gem/intel_be_device.c
src/gallium/winsys/drm/intel/gem/intel_be_device.h

index ca8e87a..ac38bb5 100644 (file)
@@ -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;
index ff5b34f..711db91 100644 (file)
@@ -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)
 
 
 /**
index e3630f5..c7e8827 100644 (file)
@@ -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;
index 56d95bd..3f3f2a7 100644 (file)
@@ -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;