summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gallium/drivers/ilo/ilo_transfer.c215
1 files changed, 100 insertions, 115 deletions
diff --git a/src/gallium/drivers/ilo/ilo_transfer.c b/src/gallium/drivers/ilo/ilo_transfer.c
index 059c383f05d..161534363eb 100644
--- a/src/gallium/drivers/ilo/ilo_transfer.c
+++ b/src/gallium/drivers/ilo/ilo_transfer.c
@@ -212,20 +212,6 @@ xfer_alloc_staging_sys(struct ilo_transfer *xfer)
return (xfer->staging_sys != NULL);
}
-static bool
-is_bo_busy(struct ilo_context *ilo, struct intel_bo *bo, bool *need_flush)
-{
- const bool referenced = intel_bo_has_reloc(ilo->cp->bo, bo);
-
- if (need_flush)
- *need_flush = referenced;
-
- if (referenced)
- return true;
-
- return intel_bo_is_busy(bo);
-}
-
/**
* Map a transfer and set the pointer according to the method. The staging
* system buffer should have been allocated if the method requires it.
@@ -275,39 +261,6 @@ xfer_unmap(struct ilo_transfer *xfer)
}
}
-/**
- * Choose the best mapping method, depending on the transfer usage and whether
- * the bo is busy.
- */
-static bool
-choose_transfer_method(struct ilo_context *ilo, struct ilo_transfer *xfer)
-{
- struct pipe_resource *res = xfer->base.resource;
- bool need_flush;
-
- if (!resource_get_transfer_method(res, xfer->base.usage, &xfer->method))
- return false;
-
- /* see if we can avoid blocking */
- if (is_bo_busy(ilo, resource_get_bo(res), &need_flush)) {
- bool resource_renamed;
-
- if (!xfer_unblock(xfer, &resource_renamed)) {
- if (xfer->base.usage & PIPE_TRANSFER_DONTBLOCK)
- return false;
-
- /* flush to make bo really busy so that map() correctly blocks */
- if (need_flush)
- ilo_cp_flush(ilo->cp, "syncing for transfers");
- }
-
- if (resource_renamed)
- ilo_mark_states_with_resource_dirty(ilo, res);
- }
-
- return true;
-}
-
static void
tex_get_box_origin(const struct ilo_texture *tex,
unsigned level, unsigned slice,
@@ -534,11 +487,12 @@ tex_tile_choose_offset_func(const struct ilo_texture *tex,
}
static void *
-tex_staging_sys_map_bo(const struct ilo_context *ilo,
- struct ilo_texture *tex,
- bool for_read_back, bool linear_view)
+tex_staging_sys_map_bo(struct ilo_texture *tex,
+ bool for_read_back,
+ bool linear_view)
{
- const bool prefer_cpu = (ilo->dev->has_llc || for_read_back);
+ const struct ilo_screen *is = ilo_screen(tex->base.screen);
+ const bool prefer_cpu = (is->dev.has_llc || for_read_back);
void *ptr;
if (prefer_cpu && (tex->tiling == INTEL_TILING_NONE || !linear_view))
@@ -550,25 +504,24 @@ tex_staging_sys_map_bo(const struct ilo_context *ilo,
}
static void
-tex_staging_sys_unmap_bo(const struct ilo_context *ilo,
- const struct ilo_texture *tex)
+tex_staging_sys_unmap_bo(struct ilo_texture *tex)
{
intel_bo_unmap(tex->bo);
}
static bool
-tex_staging_sys_zs_read(struct ilo_context *ilo,
- struct ilo_texture *tex,
+tex_staging_sys_zs_read(struct ilo_texture *tex,
const struct ilo_transfer *xfer)
{
- const bool swizzle = ilo->dev->has_address_swizzling;
+ const struct ilo_screen *is = ilo_screen(tex->base.screen);
+ const bool swizzle = is->dev.has_address_swizzling;
const struct pipe_box *box = &xfer->base.box;
const uint8_t *src;
tex_tile_offset_func tile_offset;
unsigned tiles_per_row;
int slice;
- src = tex_staging_sys_map_bo(ilo, tex, true, false);
+ src = tex_staging_sys_map_bo(tex, true, false);
if (!src)
return false;
@@ -583,9 +536,9 @@ tex_staging_sys_zs_read(struct ilo_context *ilo,
unsigned s8_tiles_per_row;
int dst_cpp, dst_s8_pos, src_cpp_used;
- s8_src = tex_staging_sys_map_bo(ilo, s8_tex, true, false);
+ s8_src = tex_staging_sys_map_bo(s8_tex, true, false);
if (!s8_src) {
- tex_staging_sys_unmap_bo(ilo, tex);
+ tex_staging_sys_unmap_bo(tex);
return false;
}
@@ -643,7 +596,7 @@ tex_staging_sys_zs_read(struct ilo_context *ilo,
}
}
- tex_staging_sys_unmap_bo(ilo, s8_tex);
+ tex_staging_sys_unmap_bo(s8_tex);
}
else {
assert(tex->bo_format == PIPE_FORMAT_S8_UINT);
@@ -678,24 +631,24 @@ tex_staging_sys_zs_read(struct ilo_context *ilo,
}
}
- tex_staging_sys_unmap_bo(ilo, tex);
+ tex_staging_sys_unmap_bo(tex);
return true;
}
static bool
-tex_staging_sys_zs_write(struct ilo_context *ilo,
- struct ilo_texture *tex,
+tex_staging_sys_zs_write(struct ilo_texture *tex,
const struct ilo_transfer *xfer)
{
- const bool swizzle = ilo->dev->has_address_swizzling;
+ const struct ilo_screen *is = ilo_screen(tex->base.screen);
+ const bool swizzle = is->dev.has_address_swizzling;
const struct pipe_box *box = &xfer->base.box;
uint8_t *dst;
tex_tile_offset_func tile_offset;
unsigned tiles_per_row;
int slice;
- dst = tex_staging_sys_map_bo(ilo, tex, false, false);
+ dst = tex_staging_sys_map_bo(tex, false, false);
if (!dst)
return false;
@@ -710,9 +663,9 @@ tex_staging_sys_zs_write(struct ilo_context *ilo,
unsigned s8_tiles_per_row;
int src_cpp, src_s8_pos, dst_cpp_used;
- s8_dst = tex_staging_sys_map_bo(ilo, s8_tex, false, false);
+ s8_dst = tex_staging_sys_map_bo(s8_tex, false, false);
if (!s8_dst) {
- tex_staging_sys_unmap_bo(ilo, s8_tex);
+ tex_staging_sys_unmap_bo(s8_tex);
return false;
}
@@ -770,7 +723,7 @@ tex_staging_sys_zs_write(struct ilo_context *ilo,
}
}
- tex_staging_sys_unmap_bo(ilo, s8_tex);
+ tex_staging_sys_unmap_bo(s8_tex);
}
else {
assert(tex->bo_format == PIPE_FORMAT_S8_UINT);
@@ -805,14 +758,13 @@ tex_staging_sys_zs_write(struct ilo_context *ilo,
}
}
- tex_staging_sys_unmap_bo(ilo, tex);
+ tex_staging_sys_unmap_bo(tex);
return true;
}
static bool
-tex_staging_sys_convert_write(struct ilo_context *ilo,
- struct ilo_texture *tex,
+tex_staging_sys_convert_write(struct ilo_texture *tex,
const struct ilo_transfer *xfer)
{
const struct pipe_box *box = &xfer->base.box;
@@ -820,7 +772,7 @@ tex_staging_sys_convert_write(struct ilo_context *ilo,
void *dst;
int slice;
- dst = tex_staging_sys_map_bo(ilo, tex, false, true);
+ dst = tex_staging_sys_map_bo(tex, false, true);
if (!dst)
return false;
@@ -838,7 +790,7 @@ tex_staging_sys_convert_write(struct ilo_context *ilo,
xfer->staging_sys, xfer->base.stride, xfer->base.layer_stride,
0, 0, 0);
- tex_staging_sys_unmap_bo(ilo, tex);
+ tex_staging_sys_unmap_bo(tex);
return true;
}
@@ -863,14 +815,13 @@ tex_staging_sys_convert_write(struct ilo_context *ilo,
break;
}
- tex_staging_sys_unmap_bo(ilo, tex);
+ tex_staging_sys_unmap_bo(tex);
return true;
}
static void
-tex_staging_sys_writeback(struct ilo_context *ilo,
- struct ilo_transfer *xfer)
+tex_staging_sys_writeback(struct ilo_transfer *xfer)
{
struct ilo_texture *tex = ilo_texture(xfer->base.resource);
bool success;
@@ -880,10 +831,10 @@ tex_staging_sys_writeback(struct ilo_context *ilo,
switch (xfer->method) {
case ILO_TRANSFER_MAP_SW_CONVERT:
- success = tex_staging_sys_convert_write(ilo, tex, xfer);
+ success = tex_staging_sys_convert_write(tex, xfer);
break;
case ILO_TRANSFER_MAP_SW_ZS:
- success = tex_staging_sys_zs_write(ilo, tex, xfer);
+ success = tex_staging_sys_zs_write(tex, xfer);
break;
default:
assert(!"unknown mapping method");
@@ -896,8 +847,7 @@ tex_staging_sys_writeback(struct ilo_context *ilo,
}
static bool
-tex_staging_sys_readback(struct ilo_context *ilo,
- struct ilo_transfer *xfer)
+tex_staging_sys_readback(struct ilo_transfer *xfer)
{
struct ilo_texture *tex = ilo_texture(xfer->base.resource);
bool read_back = false, success;
@@ -923,7 +873,7 @@ tex_staging_sys_readback(struct ilo_context *ilo,
success = false;
break;
case ILO_TRANSFER_MAP_SW_ZS:
- success = tex_staging_sys_zs_read(ilo, tex, xfer);
+ success = tex_staging_sys_zs_read(tex, xfer);
break;
default:
assert(!"unknown mapping method");
@@ -935,13 +885,10 @@ tex_staging_sys_readback(struct ilo_context *ilo,
}
static bool
-tex_map(struct ilo_context *ilo, struct ilo_transfer *xfer)
+tex_map(struct ilo_transfer *xfer)
{
bool success;
- if (!choose_transfer_method(ilo, xfer))
- return false;
-
switch (xfer->method) {
case ILO_TRANSFER_MAP_CPU:
case ILO_TRANSFER_MAP_GTT:
@@ -964,7 +911,7 @@ tex_map(struct ilo_context *ilo, struct ilo_transfer *xfer)
case ILO_TRANSFER_MAP_SW_CONVERT:
case ILO_TRANSFER_MAP_SW_ZS:
success = (xfer_alloc_staging_sys(xfer) &&
- tex_staging_sys_readback(ilo, xfer) &&
+ tex_staging_sys_readback(xfer) &&
xfer_map(xfer));
break;
default:
@@ -976,26 +923,10 @@ tex_map(struct ilo_context *ilo, struct ilo_transfer *xfer)
return success;
}
-static void
-tex_unmap(struct ilo_context *ilo, struct ilo_transfer *xfer)
-{
- xfer_unmap(xfer);
-
- switch (xfer->method) {
- case ILO_TRANSFER_MAP_SW_CONVERT:
- case ILO_TRANSFER_MAP_SW_ZS:
- tex_staging_sys_writeback(ilo, xfer);
- align_free(xfer->staging_sys);
- break;
- default:
- break;
- }
-}
-
static bool
-buf_map(struct ilo_context *ilo, struct ilo_transfer *xfer)
+buf_map(struct ilo_transfer *xfer)
{
- if (!choose_transfer_method(ilo, xfer) || !xfer_map(xfer))
+ if (!xfer_map(xfer))
return false;
xfer->ptr += xfer->base.box.x;
@@ -1011,10 +942,51 @@ buf_map(struct ilo_context *ilo, struct ilo_transfer *xfer)
return true;
}
-static void
-buf_unmap(struct ilo_context *ilo, struct ilo_transfer *xfer)
+static bool
+is_bo_busy(struct ilo_context *ilo, struct intel_bo *bo, bool *need_flush)
{
- xfer_unmap(xfer);
+ const bool referenced = intel_bo_has_reloc(ilo->cp->bo, bo);
+
+ if (need_flush)
+ *need_flush = referenced;
+
+ if (referenced)
+ return true;
+
+ return intel_bo_is_busy(bo);
+}
+
+/**
+ * Choose the best mapping method, depending on the transfer usage and whether
+ * the bo is busy.
+ */
+static bool
+choose_transfer_method(struct ilo_context *ilo, struct ilo_transfer *xfer)
+{
+ struct pipe_resource *res = xfer->base.resource;
+ bool need_flush;
+
+ if (!resource_get_transfer_method(res, xfer->base.usage, &xfer->method))
+ return false;
+
+ /* see if we can avoid blocking */
+ if (is_bo_busy(ilo, resource_get_bo(res), &need_flush)) {
+ bool resource_renamed;
+
+ if (!xfer_unblock(xfer, &resource_renamed)) {
+ if (xfer->base.usage & PIPE_TRANSFER_DONTBLOCK)
+ return false;
+
+ /* flush to make bo really busy so that map() correctly blocks */
+ if (need_flush)
+ ilo_cp_flush(ilo->cp, "syncing for transfers");
+ }
+
+ if (resource_renamed)
+ ilo_mark_states_with_resource_dirty(ilo, res);
+ }
+
+ return true;
}
static void
@@ -1064,10 +1036,17 @@ ilo_transfer_unmap(struct pipe_context *pipe,
struct ilo_context *ilo = ilo_context(pipe);
struct ilo_transfer *xfer = ilo_transfer(transfer);
- if (xfer->base.resource->target == PIPE_BUFFER)
- buf_unmap(ilo, xfer);
- else
- tex_unmap(ilo, xfer);
+ xfer_unmap(xfer);
+
+ switch (xfer->method) {
+ case ILO_TRANSFER_MAP_SW_CONVERT:
+ case ILO_TRANSFER_MAP_SW_ZS:
+ tex_staging_sys_writeback(xfer);
+ align_free(xfer->staging_sys);
+ break;
+ default:
+ break;
+ }
pipe_resource_reference(&xfer->base.resource, NULL);
@@ -1086,6 +1065,7 @@ ilo_transfer_map(struct pipe_context *pipe,
struct ilo_transfer *xfer;
bool success;
+ /* note that xfer is not zero'd */
xfer = util_slab_alloc(&ilo->transfer_mempool);
if (!xfer) {
*transfer = NULL;
@@ -1100,10 +1080,15 @@ ilo_transfer_map(struct pipe_context *pipe,
ilo_blit_resolve_transfer(ilo, &xfer->base);
- if (res->target == PIPE_BUFFER)
- success = buf_map(ilo, xfer);
- else
- success = tex_map(ilo, xfer);
+ if (choose_transfer_method(ilo, xfer)) {
+ if (res->target == PIPE_BUFFER)
+ success = buf_map(xfer);
+ else
+ success = tex_map(xfer);
+ }
+ else {
+ success = false;
+ }
if (!success) {
pipe_resource_reference(&xfer->base.resource, NULL);