i915g: Rename winsys prefix to i915_ from intel_
[mesa.git] / src / gallium / winsys / i915 / drm / i915_drm_buffer.c
diff --git a/src/gallium/winsys/i915/drm/i915_drm_buffer.c b/src/gallium/winsys/i915/drm/i915_drm_buffer.c
new file mode 100644 (file)
index 0000000..3bd8502
--- /dev/null
@@ -0,0 +1,217 @@
+
+#include "state_tracker/drm_api.h"
+#include "i915_drm_winsys.h"
+#include "util/u_memory.h"
+
+#include "i915_drm.h"
+
+static struct i915_winsys_buffer *
+i915_drm_buffer_create(struct i915_winsys *iws,
+                        unsigned size, unsigned alignment,
+                        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);
+   drm_intel_bufmgr *pool;
+   char *name;
+
+   if (!buf)
+      return NULL;
+
+   buf->magic = 0xDEAD1337;
+   buf->flinked = FALSE;
+   buf->flink = 0;
+   buf->map_gtt = FALSE;
+
+   if (type == I915_NEW_TEXTURE) {
+      name = "gallium3d_texture";
+      pool = idws->pools.gem;
+   } else if (type == I915_NEW_VERTEX) {
+      name = "gallium3d_vertex";
+      pool = idws->pools.gem;
+      buf->map_gtt = TRUE;
+   } else if (type == I915_NEW_SCANOUT) {
+      name = "gallium3d_scanout";
+      pool = idws->pools.gem;
+      buf->map_gtt = TRUE;
+   } else {
+      assert(0);
+      name = "gallium3d_unknown";
+      pool = idws->pools.gem;
+   }
+
+   buf->bo = drm_intel_bo_alloc(pool, name, size, alignment);
+
+   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_from_handle(struct i915_winsys *iws,
+                             struct winsys_handle *whandle,
+                             unsigned *stride)
+{
+   struct i915_drm_winsys *idws = i915_drm_winsys(iws);
+   struct i915_drm_buffer *buf = CALLOC_STRUCT(i915_drm_buffer);
+   uint32_t tile = 0, swizzle = 0;
+
+   if (!buf)
+      return NULL;
+
+   buf->magic = 0xDEAD1337;
+   buf->bo = drm_intel_bo_gem_create_from_name(idws->pools.gem, "gallium3d_from_handle", whandle->handle);
+   buf->flinked = TRUE;
+   buf->flink = whandle->handle;
+
+   if (!buf->bo)
+      goto err;
+
+   drm_intel_bo_get_tiling(buf->bo, &tile, &swizzle);
+   if (tile != I915_TILE_NONE)
+      buf->map_gtt = TRUE;
+
+   *stride = whandle->stride;
+
+   return (struct i915_winsys_buffer *)buf;
+
+err:
+   FREE(buf);
+   return NULL;
+}
+
+static boolean
+i915_drm_buffer_get_handle(struct i915_winsys *iws,
+                            struct i915_winsys_buffer *buffer,
+                            struct winsys_handle *whandle,
+                            unsigned stride)
+{
+   struct i915_drm_buffer *buf = i915_drm_buffer(buffer);
+
+   if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
+      if (!buf->flinked) {
+         if (drm_intel_bo_flink(buf->bo, &buf->flink))
+            return FALSE;
+         buf->flinked = TRUE;
+      }
+
+      whandle->handle = buf->flink;
+   } else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) {
+      whandle->handle = buf->bo->handle;
+   } else {
+      assert(!"unknown usage");
+      return FALSE;
+   }
+
+   whandle->stride = stride;
+   return TRUE;
+}
+
+static int
+i915_drm_buffer_set_fence_reg(struct i915_winsys *iws,
+                               struct i915_winsys_buffer *buffer,
+                               unsigned stride,
+                               enum i915_winsys_buffer_tile tile)
+{
+   struct i915_drm_buffer *buf = i915_drm_buffer(buffer);
+   assert(I915_TILING_NONE == I915_TILE_NONE);
+   assert(I915_TILING_X == I915_TILE_X);
+   assert(I915_TILING_Y == I915_TILE_Y);
+
+   if (tile != I915_TILE_NONE) {
+      assert(buf->map_count == 0);
+      buf->map_gtt = TRUE;
+   }
+
+   return drm_intel_bo_set_tiling(buf->bo, &tile, stride);
+}
+
+static void *
+i915_drm_buffer_map(struct i915_winsys *iws,
+                     struct i915_winsys_buffer *buffer,
+                     boolean write)
+{
+   struct i915_drm_buffer *buf = i915_drm_buffer(buffer);
+   drm_intel_bo *bo = intel_bo(buffer);
+   int ret = 0;
+
+   assert(bo);
+
+   if (buf->map_count)
+      goto out;
+
+   if (buf->map_gtt)
+      ret = drm_intel_gem_bo_map_gtt(bo);
+   else
+      ret = drm_intel_bo_map(bo, write);
+
+   buf->ptr = bo->virtual;
+
+   assert(ret == 0);
+out:
+   if (ret)
+      return NULL;
+
+   buf->map_count++;
+   return buf->ptr;
+}
+
+static void
+i915_drm_buffer_unmap(struct i915_winsys *iws,
+                       struct i915_winsys_buffer *buffer)
+{
+   struct i915_drm_buffer *buf = i915_drm_buffer(buffer);
+
+   if (--buf->map_count)
+      return;
+
+   if (buf->map_gtt)
+      drm_intel_gem_bo_unmap_gtt(intel_bo(buffer));
+   else
+      drm_intel_bo_unmap(intel_bo(buffer));
+}
+
+static int
+i915_drm_buffer_write(struct i915_winsys *iws,
+                       struct i915_winsys_buffer *buffer,
+                       size_t offset,
+                       size_t size,
+                       const void *data)
+{
+   struct i915_drm_buffer *buf = i915_drm_buffer(buffer);
+
+   return drm_intel_bo_subdata(buf->bo, offset, size, (void*)data);
+}
+
+static void
+i915_drm_buffer_destroy(struct i915_winsys *iws,
+                         struct i915_winsys_buffer *buffer)
+{
+   drm_intel_bo_unreference(intel_bo(buffer));
+
+#ifdef DEBUG
+   i915_drm_buffer(buffer)->magic = 0;
+   i915_drm_buffer(buffer)->bo = NULL;
+#endif
+
+   FREE(buffer);
+}
+
+void
+i915_drm_winsys_init_buffer_functions(struct i915_drm_winsys *idws)
+{
+   idws->base.buffer_create = i915_drm_buffer_create;
+   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;
+   idws->base.buffer_map = i915_drm_buffer_map;
+   idws->base.buffer_unmap = i915_drm_buffer_unmap;
+   idws->base.buffer_write = i915_drm_buffer_write;
+   idws->base.buffer_destroy = i915_drm_buffer_destroy;
+}