i915g: add winsys function to create tiled buffers
authorDaniel Vetter <daniel.vetter@ffwll.ch>
Sun, 21 Nov 2010 19:34:44 +0000 (20:34 +0100)
committerJakob Bornecrantz <wallbraker@gmail.com>
Thu, 2 Dec 2010 00:34:12 +0000 (01:34 +0100)
Different kernels have different restrictions for tiled buffers.
Hence use the libdrm abstraction to calculate the necessary
stride and height alignment requirements.

Not yet used.

v2: Incorporate review comments from Jakob Bornecrantz

Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Reviewed-by: Jakob Bornecrantz <wallbraker@gmail.com>
Signed-off-by: Jakob Bornecrantz <wallbraker@gmail.com>
src/gallium/drivers/i915/i915_winsys.h
src/gallium/winsys/i915/drm/i915_drm_buffer.c
src/gallium/winsys/i915/sw/i915_sw_buffer.c
src/gallium/winsys/i915/sw/i915_sw_winsys.h

index 3d5627045bcf323f5e6ca51866eb5a62a65eb905..59b7220e5923e94481cf0178819a0b73e7555af7 100644 (file)
@@ -133,6 +133,20 @@ struct i915_winsys {
                        unsigned size,
                        enum i915_winsys_buffer_type type);
 
+   /**
+    * Create a tiled buffer.
+    *
+    * *stride, height are in bytes. The winsys tries to allocate the buffer with
+    * the tiling mode provide in *tiling. If tiling is no possible, *tiling will
+    * be set to I915_TILE_NONE. The calculated stride (incorporateing hw/kernel
+    * requirements) is always returned in *stride.
+    */
+   struct i915_winsys_buffer *
+      (*buffer_create_tiled)(struct i915_winsys *iws,
+                             unsigned *stride, unsigned height,
+                             enum i915_winsys_buffer_tile *tiling,
+                             enum i915_winsys_buffer_type type);
+
    /**
     * Creates a buffer from a handle.
     * Used to implement pipe_screen::resource_from_handle.
index ab1e12529e48153431f7fef036aa1246c895277f..537bd737c53606963ec74bdadf368677475576fb 100644 (file)
@@ -5,6 +5,24 @@
 
 #include "i915_drm.h"
 
+static char *i915_drm_type_to_name(enum i915_winsys_buffer_type type)
+{
+   char *name;
+
+   if (type == I915_NEW_TEXTURE) {
+      name = "gallium3d_texture";
+   } else if (type == I915_NEW_VERTEX) {
+      name = "gallium3d_vertex";
+   } else if (type == I915_NEW_SCANOUT) {
+      name = "gallium3d_scanout";
+   } else {
+      assert(0);
+      name = "gallium3d_unknown";
+   }
+
+   return name;
+}
+
 static struct i915_winsys_buffer *
 i915_drm_buffer_create(struct i915_winsys *iws,
                         unsigned size,
@@ -12,7 +30,6 @@ i915_drm_buffer_create(struct i915_winsys *iws,
 {
    struct i915_drm_buffer *buf = CALLOC_STRUCT(i915_drm_buffer);
    struct i915_drm_winsys *idws = i915_drm_winsys(iws);
-   char *name;
 
    if (!buf)
       return NULL;
@@ -21,22 +38,48 @@ i915_drm_buffer_create(struct i915_winsys *iws,
    buf->flinked = FALSE;
    buf->flink = 0;
 
-   if (type == I915_NEW_TEXTURE) {
-      name = "gallium3d_texture";
-   } else if (type == I915_NEW_VERTEX) {
-      name = "gallium3d_vertex";
-   } else if (type == I915_NEW_SCANOUT) {
-      name = "gallium3d_scanout";
-   } else {
-      assert(0);
-      name = "gallium3d_unknown";
-   }
+   buf->bo = drm_intel_bo_alloc(idws->gem_manager,
+                                i915_drm_type_to_name(type), size, 0);
+
+   if (!buf->bo)
+      goto err;
+
+   return (struct i915_winsys_buffer *)buf;
+
+err:
+   assert(0);
+   FREE(buf);
+   return NULL;
+}
+
+static struct i915_winsys_buffer *
+i915_drm_buffer_create_tiled(struct i915_winsys *iws,
+                             unsigned *stride, unsigned height, 
+                             enum i915_winsys_buffer_tile *tiling,
+                             enum i915_winsys_buffer_type type)
+{
+   struct i915_drm_buffer *buf = CALLOC_STRUCT(i915_drm_buffer);
+   struct i915_drm_winsys *idws = i915_drm_winsys(iws);
+   unsigned long pitch = 0;
+   uint32_t tiling_mode = *tiling;
+
+   if (!buf)
+      return NULL;
+
+   buf->magic = 0xDEAD1337;
+   buf->flinked = FALSE;
+   buf->flink = 0;
 
-   buf->bo = drm_intel_bo_alloc(idws->gem_manager, name, size, 0);
+   buf->bo = drm_intel_bo_alloc_tiled(idws->gem_manager,
+                                      i915_drm_type_to_name(type),
+                                     *stride, height, 1,
+                                      &tiling_mode, &pitch, 0);
 
    if (!buf->bo)
       goto err;
 
+   *stride = pitch;
+   *tiling = tiling_mode;
    return (struct i915_winsys_buffer *)buf;
 
 err:
@@ -190,6 +233,7 @@ void
 i915_drm_winsys_init_buffer_functions(struct i915_drm_winsys *idws)
 {
    idws->base.buffer_create = i915_drm_buffer_create;
+   idws->base.buffer_create_tiled = i915_drm_buffer_create_tiled;
    idws->base.buffer_from_handle = i915_drm_buffer_from_handle;
    idws->base.buffer_get_handle = i915_drm_buffer_get_handle;
    idws->base.buffer_set_fence_reg = i915_drm_buffer_set_fence_reg;
index 321ef90d265a55f7ba41d44f6b3b70c4570a21f2..44466d1c661238c3e262b97d0b22de9cabc7b18c 100644 (file)
@@ -27,6 +27,34 @@ err:
    return NULL;
 }
 
+static struct i915_winsys_buffer *
+i915_sw_buffer_create_tiled(struct i915_winsys *iws,
+                      unsigned *stride, unsigned height, 
+                      enum i915_winsys_buffer_tile *tiling,
+                      enum i915_winsys_buffer_type type)
+{
+   struct i915_sw_buffer *buf = CALLOC_STRUCT(i915_sw_buffer);
+
+   if (!buf)
+      return NULL;
+
+   buf->magic = 0xDEAD1337;
+   buf->type = type;
+   buf->ptr = CALLOC(*stride * height, 1);
+   buf->tiling = *tiling;
+   buf->stride = *stride;
+
+   if (!buf->ptr)
+      goto err;
+
+   return (struct i915_winsys_buffer *)buf;
+
+err:
+   assert(0);
+   FREE(buf);
+   return NULL;
+}
+
 static int
 i915_sw_buffer_set_fence_reg(struct i915_winsys *iws,
                                struct i915_winsys_buffer *buffer,
@@ -39,7 +67,7 @@ i915_sw_buffer_set_fence_reg(struct i915_winsys *iws,
       assert(buf->map_count == 0);
    }
 
-   buf->tile = tile;
+   buf->tiling = tile;
 
    return 0;
 }
@@ -95,6 +123,7 @@ void
 i915_sw_winsys_init_buffer_functions(struct i915_sw_winsys *isws)
 {
    isws->base.buffer_create = i915_sw_buffer_create;
+   isws->base.buffer_create_tiled = i915_sw_buffer_create_tiled;
    isws->base.buffer_set_fence_reg = i915_sw_buffer_set_fence_reg;
    isws->base.buffer_map = i915_sw_buffer_map;
    isws->base.buffer_unmap = i915_sw_buffer_unmap;
index cd2eebd17995b4bb35c8139879db81065ce1e299..3af2548419e4343ccc85f7b3b114f2b0391349c5 100644 (file)
@@ -43,7 +43,8 @@ struct i915_sw_buffer {
    void *ptr;
    unsigned map_count;
    enum i915_winsys_buffer_type type;
-   enum i915_winsys_buffer_tile tile;
+   enum i915_winsys_buffer_tile tiling;
+   unsigned stride;
 };
 
 static INLINE struct i915_sw_buffer *