ilo: tidy up transfer mapping/unmapping
authorChia-I Wu <olvaffe@gmail.com>
Mon, 28 Jul 2014 03:00:52 +0000 (11:00 +0800)
committerChia-I Wu <olvaffe@gmail.com>
Mon, 28 Jul 2014 14:57:22 +0000 (22:57 +0800)
Add xfer_map() to replace map_bo_for_transfer().  Add xfer_unmap() and
xfer_alloc_staging_sys() to simplify texture and buffer mapping/unmapping, and
enable more code sharing between them.

src/gallium/drivers/ilo/ilo_transfer.c

index 7645a250173d841d4b6ee2b5d15a7cd7bdafdb2f..059c383f05d17bbf380d983953c878c30419b4b2 100644 (file)
@@ -189,6 +189,29 @@ xfer_unblock(struct ilo_transfer *xfer, bool *resource_renamed)
    return unblocked;
 }
 
+/**
+ * Allocate the staging system buffer based on the resource format and the
+ * transfer box.
+ */
+static bool
+xfer_alloc_staging_sys(struct ilo_transfer *xfer)
+{
+   const enum pipe_format format = xfer->base.resource->format;
+   const struct pipe_box *box = &xfer->base.box;
+   const unsigned alignment = 64;
+
+   /* need to tell the world the layout */
+   xfer->base.stride =
+      align(util_format_get_stride(format, box->width), alignment);
+   xfer->base.layer_stride =
+      util_format_get_2d_size(format, xfer->base.stride, box->height);
+
+   xfer->staging_sys =
+      align_malloc(xfer->base.layer_stride * box->depth, alignment);
+
+   return (xfer->staging_sys != NULL);
+}
+
 static bool
 is_bo_busy(struct ilo_context *ilo, struct intel_bo *bo, bool *need_flush)
 {
@@ -203,29 +226,53 @@ is_bo_busy(struct ilo_context *ilo, struct intel_bo *bo, bool *need_flush)
    return intel_bo_is_busy(bo);
 }
 
-static void *
-map_bo_for_transfer(struct ilo_context *ilo, struct intel_bo *bo,
-                    const struct ilo_transfer *xfer)
+/**
+ * Map a transfer and set the pointer according to the method.  The staging
+ * system buffer should have been allocated if the method requires it.
+ */
+static bool
+xfer_map(struct ilo_transfer *xfer)
 {
-   void *ptr;
-
    switch (xfer->method) {
    case ILO_TRANSFER_MAP_CPU:
-      ptr = intel_bo_map(bo, (xfer->base.usage & PIPE_TRANSFER_WRITE));
+      xfer->ptr = intel_bo_map(resource_get_bo(xfer->base.resource),
+            xfer->base.usage & PIPE_TRANSFER_WRITE);
       break;
    case ILO_TRANSFER_MAP_GTT:
-      ptr = intel_bo_map_gtt(bo);
+      xfer->ptr = intel_bo_map_gtt(resource_get_bo(xfer->base.resource));
       break;
    case ILO_TRANSFER_MAP_UNSYNC:
-      ptr = intel_bo_map_unsynchronized(bo);
+      xfer->ptr =
+         intel_bo_map_unsynchronized(resource_get_bo(xfer->base.resource));
+      break;
+   case ILO_TRANSFER_MAP_SW_CONVERT:
+   case ILO_TRANSFER_MAP_SW_ZS:
+      xfer->ptr = xfer->staging_sys;
       break;
    default:
       assert(!"unknown mapping method");
-      ptr = NULL;
+      xfer->ptr = NULL;
       break;
    }
 
-   return ptr;
+   return (xfer->ptr != NULL);
+}
+
+/**
+ * Unmap a transfer.
+ */
+static void
+xfer_unmap(struct ilo_transfer *xfer)
+{
+   switch (xfer->method) {
+   case ILO_TRANSFER_MAP_CPU:
+   case ILO_TRANSFER_MAP_GTT:
+   case ILO_TRANSFER_MAP_UNSYNC:
+      intel_bo_unmap(resource_get_bo(xfer->base.resource));
+      break;
+   default:
+      break;
+   }
 }
 
 /**
@@ -822,16 +869,14 @@ tex_staging_sys_convert_write(struct ilo_context *ilo,
 }
 
 static void
-tex_staging_sys_unmap(struct ilo_context *ilo,
-                      struct ilo_texture *tex,
-                      struct ilo_transfer *xfer)
+tex_staging_sys_writeback(struct ilo_context *ilo,
+                          struct ilo_transfer *xfer)
 {
+   struct ilo_texture *tex = ilo_texture(xfer->base.resource);
    bool success;
 
-   if (!(xfer->base.usage & PIPE_TRANSFER_WRITE)) {
-      FREE(xfer->staging_sys);
+   if (!(xfer->base.usage & PIPE_TRANSFER_WRITE))
       return;
-   }
 
    switch (xfer->method) {
    case ILO_TRANSFER_MAP_SW_CONVERT:
@@ -848,29 +893,15 @@ tex_staging_sys_unmap(struct ilo_context *ilo,
 
    if (!success)
       ilo_err("failed to map resource for moving staging data\n");
-
-   FREE(xfer->staging_sys);
 }
 
 static bool
-tex_staging_sys_map(struct ilo_context *ilo,
-                    struct ilo_texture *tex,
-                    struct ilo_transfer *xfer)
+tex_staging_sys_readback(struct ilo_context *ilo,
+                         struct ilo_transfer *xfer)
 {
-   const struct pipe_box *box = &xfer->base.box;
-   const size_t stride = util_format_get_stride(tex->base.format, box->width);
-   const size_t size =
-      util_format_get_2d_size(tex->base.format, stride, box->height);
+   struct ilo_texture *tex = ilo_texture(xfer->base.resource);
    bool read_back = false, success;
 
-   xfer->staging_sys = MALLOC(size * box->depth);
-   if (!xfer->staging_sys)
-      return false;
-
-   xfer->base.stride = stride;
-   xfer->base.layer_stride = size;
-   xfer->ptr = xfer->staging_sys;
-
    /* see if we need to read the resource back */
    if (xfer->base.usage & PIPE_TRANSFER_READ) {
       read_back = true;
@@ -903,41 +934,9 @@ tex_staging_sys_map(struct ilo_context *ilo,
    return success;
 }
 
-static void
-tex_direct_unmap(struct ilo_context *ilo,
-                 struct ilo_texture *tex,
-                 struct ilo_transfer *xfer)
-{
-   intel_bo_unmap(tex->bo);
-}
-
-static bool
-tex_direct_map(struct ilo_context *ilo,
-               struct ilo_texture *tex,
-               struct ilo_transfer *xfer)
-{
-   xfer->ptr = map_bo_for_transfer(ilo, tex->bo, xfer);
-   if (!xfer->ptr)
-      return false;
-
-   xfer->ptr += tex_get_box_offset(tex, xfer->base.level, &xfer->base.box);
-
-   /* note that stride is for a block row, not a texel row */
-   xfer->base.stride = tex->bo_stride;
-
-   /* slice stride is not always available */
-   if (xfer->base.box.depth > 1)
-      xfer->base.layer_stride = tex_get_slice_stride(tex, xfer->base.level);
-   else
-      xfer->base.layer_stride = 0;
-
-   return true;
-}
-
 static bool
 tex_map(struct ilo_context *ilo, struct ilo_transfer *xfer)
 {
-   struct ilo_texture *tex = ilo_texture(xfer->base.resource);
    bool success;
 
    if (!choose_transfer_method(ilo, xfer))
@@ -947,11 +946,26 @@ tex_map(struct ilo_context *ilo, struct ilo_transfer *xfer)
    case ILO_TRANSFER_MAP_CPU:
    case ILO_TRANSFER_MAP_GTT:
    case ILO_TRANSFER_MAP_UNSYNC:
-      success = tex_direct_map(ilo, tex, xfer);
+      success = xfer_map(xfer);
+      if (success) {
+         const struct ilo_texture *tex = ilo_texture(xfer->base.resource);
+
+         xfer->ptr += tex_get_box_offset(tex,
+               xfer->base.level, &xfer->base.box);
+
+         /* stride is for a block row, not a texel row */
+         xfer->base.stride = tex->bo_stride;
+
+         /* note that slice stride is not always available */
+         xfer->base.layer_stride = (xfer->base.box.depth > 1) ?
+            tex_get_slice_stride(tex, xfer->base.level) : 0;
+      }
       break;
    case ILO_TRANSFER_MAP_SW_CONVERT:
    case ILO_TRANSFER_MAP_SW_ZS:
-      success = tex_staging_sys_map(ilo, tex, xfer);
+      success = (xfer_alloc_staging_sys(xfer) &&
+                 tex_staging_sys_readback(ilo, xfer) &&
+                 xfer_map(xfer));
       break;
    default:
       assert(!"unknown mapping method");
@@ -965,20 +979,15 @@ tex_map(struct ilo_context *ilo, struct ilo_transfer *xfer)
 static void
 tex_unmap(struct ilo_context *ilo, struct ilo_transfer *xfer)
 {
-   struct ilo_texture *tex = ilo_texture(xfer->base.resource);
+   xfer_unmap(xfer);
 
    switch (xfer->method) {
-   case ILO_TRANSFER_MAP_CPU:
-   case ILO_TRANSFER_MAP_GTT:
-   case ILO_TRANSFER_MAP_UNSYNC:
-      tex_direct_unmap(ilo, tex, xfer);
-      break;
    case ILO_TRANSFER_MAP_SW_CONVERT:
    case ILO_TRANSFER_MAP_SW_ZS:
-      tex_staging_sys_unmap(ilo, tex, xfer);
+      tex_staging_sys_writeback(ilo, xfer);
+      align_free(xfer->staging_sys);
       break;
    default:
-      assert(!"unknown mapping method");
       break;
    }
 }
@@ -986,14 +995,12 @@ tex_unmap(struct ilo_context *ilo, struct ilo_transfer *xfer)
 static bool
 buf_map(struct ilo_context *ilo, struct ilo_transfer *xfer)
 {
-   struct ilo_buffer *buf = ilo_buffer(xfer->base.resource);
-
-   if (!choose_transfer_method(ilo, xfer))
+   if (!choose_transfer_method(ilo, xfer) || !xfer_map(xfer))
       return false;
 
-   xfer->ptr = map_bo_for_transfer(ilo, buf->bo, xfer);
-   if (!xfer->ptr)
-      return false;
+   xfer->ptr += xfer->base.box.x;
+   xfer->base.stride = 0;
+   xfer->base.layer_stride = 0;
 
    assert(xfer->base.level == 0);
    assert(xfer->base.box.y == 0);
@@ -1001,19 +1008,13 @@ buf_map(struct ilo_context *ilo, struct ilo_transfer *xfer)
    assert(xfer->base.box.height == 1);
    assert(xfer->base.box.depth == 1);
 
-   xfer->ptr += xfer->base.box.x;
-   xfer->base.stride = 0;
-   xfer->base.layer_stride = 0;
-
    return true;
 }
 
 static void
 buf_unmap(struct ilo_context *ilo, struct ilo_transfer *xfer)
 {
-   struct ilo_buffer *buf = ilo_buffer(xfer->base.resource);
-
-   intel_bo_unmap(buf->bo);
+   xfer_unmap(xfer);
 }
 
 static void