mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-30 05:00:32 +01:00
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.
This commit is contained in:
parent
baa44db065
commit
183ea823fd
1 changed files with 77 additions and 0 deletions
|
|
@ -25,6 +25,7 @@
|
|||
* Chia-I Wu <olv@lunarg.com>
|
||||
*/
|
||||
|
||||
#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;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue