summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChia-I Wu <[email protected]>2013-05-09 14:21:25 +0800
committerChia-I Wu <[email protected]>2013-05-09 16:05:47 +0800
commit183ea823fd3a8a043ceb0e5d774eee459155a6f6 (patch)
tree11a4a0b1975bc93f1dfa4381459eb8f2ad89237c
parentbaa44db06586f8f844046a6397ea609f55cd3b97 (diff)
ilo: support mapping with a staging system buffer
It can be used for unpacking compressed texture on-the-fly or to support explicit transfer flushing.
-rw-r--r--src/gallium/drivers/ilo/ilo_resource.c77
1 files changed, 77 insertions, 0 deletions
diff --git a/src/gallium/drivers/ilo/ilo_resource.c b/src/gallium/drivers/ilo/ilo_resource.c
index 984a47a22ad..082d9170fd0 100644
--- a/src/gallium/drivers/ilo/ilo_resource.c
+++ b/src/gallium/drivers/ilo/ilo_resource.c
@@ -25,6 +25,7 @@
* Chia-I Wu <[email protected]>
*/
+#include "util/u_surface.h"
#include "util/u_transfer.h"
#include "ilo_cp.h"
@@ -37,6 +38,7 @@
enum ilo_transfer_map_method {
ILO_TRANSFER_MAP_DIRECT,
+ ILO_TRANSFER_MAP_STAGING_SYS,
};
struct ilo_transfer {
@@ -44,6 +46,8 @@ struct ilo_transfer {
enum ilo_transfer_map_method method;
void *ptr;
+
+ void *staging_sys;
};
static inline struct ilo_transfer *
@@ -262,6 +266,73 @@ ilo_transfer_inline_write(struct pipe_context *pipe,
}
static void
+transfer_unmap_sys(struct ilo_context *ilo,
+ struct ilo_resource *res,
+ struct ilo_transfer *xfer)
+{
+ const void *src = xfer->ptr;
+ struct pipe_transfer *dst_xfer;
+ void *dst;
+
+ dst = ilo->base.transfer_map(&ilo->base,
+ xfer->base.resource, xfer->base.level,
+ PIPE_TRANSFER_WRITE |
+ PIPE_TRANSFER_MAP_DIRECTLY |
+ PIPE_TRANSFER_DISCARD_RANGE,
+ &xfer->base.box, &dst_xfer);
+ if (!dst_xfer) {
+ ilo_err("failed to map resource for moving staging data\n");
+ FREE(xfer->staging_sys);
+ return;
+ }
+
+ util_copy_box(dst, res->bo_format,
+ dst_xfer->stride, dst_xfer->layer_stride, 0, 0, 0,
+ dst_xfer->box.width, dst_xfer->box.height, dst_xfer->box.depth,
+ src, xfer->base.stride, xfer->base.layer_stride, 0, 0, 0);
+
+ ilo->base.transfer_unmap(&ilo->base, dst_xfer);
+ FREE(xfer->staging_sys);
+}
+
+static bool
+transfer_map_sys(struct ilo_context *ilo,
+ struct ilo_resource *res,
+ struct ilo_transfer *xfer)
+{
+ const struct pipe_box *box = &xfer->base.box;
+ const size_t stride = util_format_get_stride(res->base.format, box->width);
+ const size_t size =
+ util_format_get_2d_size(res->base.format, stride, box->height);
+ bool read_back;
+
+ if (xfer->base.usage & PIPE_TRANSFER_READ) {
+ read_back = true;
+ }
+ else if (xfer->base.usage & PIPE_TRANSFER_WRITE) {
+ const unsigned discard_flags =
+ (PIPE_TRANSFER_DISCARD_RANGE | PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE);
+
+ if (!(xfer->base.usage & discard_flags))
+ read_back = true;
+ }
+
+ /* TODO */
+ if (read_back)
+ return false;
+
+ 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;
+
+ return true;
+}
+
+static void
transfer_unmap_direct(struct ilo_context *ilo,
struct ilo_resource *res,
struct ilo_transfer *xfer)
@@ -415,6 +486,9 @@ ilo_transfer_unmap(struct pipe_context *pipe,
case ILO_TRANSFER_MAP_DIRECT:
transfer_unmap_direct(ilo, res, xfer);
break;
+ case ILO_TRANSFER_MAP_STAGING_SYS:
+ transfer_unmap_sys(ilo, res, xfer);
+ break;
default:
assert(!"unknown mapping method");
break;
@@ -455,6 +529,9 @@ ilo_transfer_map(struct pipe_context *pipe,
case ILO_TRANSFER_MAP_DIRECT:
ok = transfer_map_direct(ilo, res, xfer);
break;
+ case ILO_TRANSFER_MAP_STAGING_SYS:
+ ok = transfer_map_sys(ilo, res, xfer);
+ break;
default:
assert(!"unknown mapping method");
ok = false;