From 183ea823fd3a8a043ceb0e5d774eee459155a6f6 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Thu, 9 May 2013 14:21:25 +0800 Subject: [PATCH] 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. --- src/gallium/drivers/ilo/ilo_resource.c | 77 ++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) 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 */ +#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 * @@ -261,6 +265,73 @@ ilo_transfer_inline_write(struct pipe_context *pipe, res->bo->pwrite(res->bo, offset, size, data); } +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, @@ -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; -- 2.30.2