Mesa (main): iris: Make an iris_foreach_batch macro that skips unsupported batches
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Fri Feb 4 08:36:33 UTC 2022
Module: Mesa
Branch: main
Commit: fd0e4aedeb276b64bb58bc0ecfa68db228c3857d
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=fd0e4aedeb276b64bb58bc0ecfa68db228c3857d
Author: Kenneth Graunke <kenneth at whitecape.org>
Date: Fri Jan 28 03:23:34 2022 -0800
iris: Make an iris_foreach_batch macro that skips unsupported batches
IRIS_BATCH_BLITTER isn't supported prior to Tigerlake; in general,
batches may not be supported on all hardware. In most cases, querying
them is harmless (if useless): they reference nothing, have no commands
to flush, and so on. However, the fence code does need to know that
certain batches don't exist, so it can avoid adding inter-batch fences
involving them.
This patch introduces a new iris_foreach_batch() iterator macro that
walks over all batches that are actually supported on the platform,
while skipping the others. It provides a central place to update should
we add or reorder more batches in the future.
Fixes various tests in the piglit.spec.ext_external_objects.* category.
Thanks to Tapani Pälli for catching this.
Fixes: a90a1f15 ("iris: Create an IRIS_BATCH_BLITTER for using the BLT command streamer")
Reviewed-by: Caio Oliveira <caio.oliveira at intel.com>
Reviewed-by: Paulo Zanoni <paulo.r.zanoni at intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14834>
---
src/gallium/drivers/iris/iris_batch.c | 47 ++++++++++++++++------------
src/gallium/drivers/iris/iris_batch.h | 6 ++++
src/gallium/drivers/iris/iris_border_color.c | 6 ++--
src/gallium/drivers/iris/iris_context.c | 4 +--
src/gallium/drivers/iris/iris_fence.c | 27 +++++++---------
src/gallium/drivers/iris/iris_pipe_control.c | 9 +++---
src/gallium/drivers/iris/iris_resource.c | 25 +++++++--------
7 files changed, 66 insertions(+), 58 deletions(-)
diff --git a/src/gallium/drivers/iris/iris_batch.c b/src/gallium/drivers/iris/iris_batch.c
index 83397812d58..1364f5fdb07 100644
--- a/src/gallium/drivers/iris/iris_batch.c
+++ b/src/gallium/drivers/iris/iris_batch.c
@@ -181,13 +181,13 @@ iris_init_batch(struct iris_context *ice,
struct iris_batch *batch = &ice->batches[name];
struct iris_screen *screen = (void *) ice->ctx.screen;
- /* Note: ctx_id, exec_flags and has_engines_context fields are initialized
- * at an earlier phase when contexts are created.
+ /* Note: screen, ctx_id, exec_flags and has_engines_context fields are
+ * initialized at an earlier phase when contexts are created.
*
- * Ref: iris_init_engines_context(), iris_init_non_engine_contexts()
+ * See iris_init_batches(), which calls either iris_init_engines_context()
+ * or iris_init_non_engine_contexts().
*/
- batch->screen = screen;
batch->dbg = &ice->dbg;
batch->reset = &ice->reset;
batch->state_sizes = ice->state.sizes;
@@ -214,11 +214,12 @@ iris_init_batch(struct iris_context *ice,
batch->cache.render = _mesa_hash_table_create(NULL, _mesa_hash_pointer,
_mesa_key_pointer_equal);
+ batch->num_other_batches = 0;
memset(batch->other_batches, 0, sizeof(batch->other_batches));
- for (int i = 0, j = 0; i < IRIS_BATCH_COUNT; i++) {
- if (i != name)
- batch->other_batches[j++] = &ice->batches[i];
+ iris_foreach_batch(ice, other_batch) {
+ if (batch != other_batch)
+ batch->other_batches[batch->num_other_batches++] = other_batch;
}
if (INTEL_DEBUG(DEBUG_ANY)) {
@@ -250,8 +251,7 @@ iris_init_non_engine_contexts(struct iris_context *ice, int priority)
{
struct iris_screen *screen = (void *) ice->ctx.screen;
- for (int i = 0; i < IRIS_BATCH_COUNT; i++) {
- struct iris_batch *batch = &ice->batches[i];
+ iris_foreach_batch(ice, batch) {
batch->ctx_id = iris_create_hw_context(screen->bufmgr);
batch->exec_flags = I915_EXEC_RENDER;
batch->has_engines_context = false;
@@ -315,8 +315,8 @@ iris_init_engines_context(struct iris_context *ice, int priority)
struct iris_screen *screen = (void *) ice->ctx.screen;
iris_hw_context_set_priority(screen->bufmgr, engines_ctx, priority);
- for (int i = 0; i < IRIS_BATCH_COUNT; i++) {
- struct iris_batch *batch = &ice->batches[i];
+ iris_foreach_batch(ice, batch) {
+ unsigned i = batch - &ice->batches[0];
batch->ctx_id = engines_ctx;
batch->exec_flags = i;
batch->has_engines_context = true;
@@ -328,10 +328,14 @@ iris_init_engines_context(struct iris_context *ice, int priority)
void
iris_init_batches(struct iris_context *ice, int priority)
{
+ /* We have to do this early for iris_foreach_batch() to work */
+ for (int i = 0; i < IRIS_BATCH_COUNT; i++)
+ ice->batches[i].screen = (void *) ice->ctx.screen;
+
if (!iris_init_engines_context(ice, priority))
iris_init_non_engine_contexts(ice, priority);
- for (int i = 0; i < IRIS_BATCH_COUNT; i++)
- iris_init_batch(ice, (enum iris_batch_name) i);
+ iris_foreach_batch(ice, batch)
+ iris_init_batch(ice, batch - &ice->batches[0]);
}
static int
@@ -400,7 +404,7 @@ flush_for_cross_batch_dependencies(struct iris_batch *batch,
* it had already referenced, we may need to flush other batches in order
* to correctly synchronize them.
*/
- for (int b = 0; b < ARRAY_SIZE(batch->other_batches); b++) {
+ for (int b = 0; b < batch->num_other_batches; b++) {
struct iris_batch *other_batch = batch->other_batches[b];
int other_index = find_exec_index(other_batch, bo);
@@ -598,8 +602,8 @@ iris_destroy_batches(struct iris_context *ice)
ice->batches[0].ctx_id);
}
- for (int i = 0; i < IRIS_BATCH_COUNT; i++)
- iris_batch_free(&ice->batches[i]);
+ iris_foreach_batch(ice, batch)
+ iris_batch_free(batch);
}
/**
@@ -726,10 +730,10 @@ replace_kernel_ctx(struct iris_batch *batch)
int new_ctx = iris_create_engines_context(ice, priority);
if (new_ctx < 0)
return false;
- for (int i = 0; i < IRIS_BATCH_COUNT; i++) {
- ice->batches[i].ctx_id = new_ctx;
+ iris_foreach_batch(ice, bat) {
+ bat->ctx_id = new_ctx;
/* Notify the context that state must be re-initialized. */
- iris_lost_context_state(&ice->batches[i]);
+ iris_lost_context_state(bat);
}
iris_destroy_kernel_context(bufmgr, old_ctx);
} else {
@@ -810,6 +814,7 @@ update_bo_syncobjs(struct iris_batch *batch, struct iris_bo *bo, bool write)
{
struct iris_screen *screen = batch->screen;
struct iris_bufmgr *bufmgr = screen->bufmgr;
+ struct iris_context *ice = batch->ice;
/* Make sure bo->deps is big enough */
if (screen->id >= bo->deps_size) {
@@ -838,7 +843,9 @@ update_bo_syncobjs(struct iris_batch *batch, struct iris_bo *bo, bool write)
* have come from a different context, and apps don't like it when we don't
* do inter-context tracking.
*/
- for (unsigned i = 0; i < IRIS_BATCH_COUNT; i++) {
+ iris_foreach_batch(ice, batch_i) {
+ unsigned i = batch_i->name;
+
/* If the bo is being written to by others, wait for them. */
if (bo_deps->write_syncobjs[i])
move_syncobj_to_batch(batch, &bo_deps->write_syncobjs[i],
diff --git a/src/gallium/drivers/iris/iris_batch.h b/src/gallium/drivers/iris/iris_batch.h
index 1b5b4638753..82f576d47a4 100644
--- a/src/gallium/drivers/iris/iris_batch.h
+++ b/src/gallium/drivers/iris/iris_batch.h
@@ -136,6 +136,7 @@ struct iris_batch {
/** List of other batches which we might need to flush to use a BO */
struct iris_batch *other_batches[IRIS_BATCH_COUNT - 1];
+ unsigned num_other_batches;
struct {
/**
@@ -382,4 +383,9 @@ iris_batch_mark_reset_sync(struct iris_batch *batch)
const char *
iris_batch_name_to_string(enum iris_batch_name name);
+#define iris_foreach_batch(ice, batch) \
+ for (struct iris_batch *batch = &ice->batches[0]; \
+ batch <= &ice->batches[((struct iris_screen *)ice->ctx.screen)->devinfo.ver >= 12 ? IRIS_BATCH_BLITTER : IRIS_BATCH_COMPUTE]; \
+ ++batch)
+
#endif
diff --git a/src/gallium/drivers/iris/iris_border_color.c b/src/gallium/drivers/iris/iris_border_color.c
index 6c794752bd5..17097a6b0f6 100644
--- a/src/gallium/drivers/iris/iris_border_color.c
+++ b/src/gallium/drivers/iris/iris_border_color.c
@@ -114,9 +114,9 @@ iris_border_color_pool_reserve(struct iris_context *ice, unsigned count)
if (remaining_entries < count) {
/* It's safe to flush because we're called outside of state upload. */
- for (int i = 0; i < IRIS_BATCH_COUNT; i++) {
- if (iris_batch_references(&ice->batches[i], pool->bo))
- iris_batch_flush(&ice->batches[i]);
+ iris_foreach_batch(ice, batch) {
+ if (iris_batch_references(batch, pool->bo))
+ iris_batch_flush(batch);
}
iris_reset_border_color_pool(pool, pool->bo->bufmgr);
diff --git a/src/gallium/drivers/iris/iris_context.c b/src/gallium/drivers/iris/iris_context.c
index 1a92df1a5e6..b91f6f8ef8b 100644
--- a/src/gallium/drivers/iris/iris_context.c
+++ b/src/gallium/drivers/iris/iris_context.c
@@ -98,12 +98,12 @@ iris_get_device_reset_status(struct pipe_context *ctx)
/* Check the reset status of each batch's hardware context, and take the
* worst status (if one was guilty, proclaim guilt).
*/
- for (int i = 0; i < IRIS_BATCH_COUNT; i++) {
+ iris_foreach_batch(ice, batch) {
/* This will also recreate the hardware contexts as necessary, so any
* future queries will show no resets. We only want to report once.
*/
enum pipe_reset_status batch_reset =
- iris_batch_check_for_reset(&ice->batches[i]);
+ iris_batch_check_for_reset(batch);
if (batch_reset == PIPE_NO_RESET)
continue;
diff --git a/src/gallium/drivers/iris/iris_fence.c b/src/gallium/drivers/iris/iris_fence.c
index bcaeb5d6757..387adb12122 100644
--- a/src/gallium/drivers/iris/iris_fence.c
+++ b/src/gallium/drivers/iris/iris_fence.c
@@ -263,8 +263,8 @@ iris_fence_flush(struct pipe_context *ctx,
iris_flush_dirty_dmabufs(ice);
if (!deferred) {
- for (unsigned i = 0; i < IRIS_BATCH_COUNT; i++)
- iris_batch_flush(&ice->batches[i]);
+ iris_foreach_batch(ice, batch)
+ iris_batch_flush(batch);
}
if (flags & PIPE_FLUSH_END_OF_FRAME) {
@@ -286,8 +286,8 @@ iris_fence_flush(struct pipe_context *ctx,
if (deferred)
fence->unflushed_ctx = ctx;
- for (unsigned b = 0; b < IRIS_BATCH_COUNT; b++) {
- struct iris_batch *batch = &ice->batches[b];
+ iris_foreach_batch(ice, batch) {
+ unsigned b = batch->name;
if (deferred && iris_batch_bytes_used(batch) > 0) {
struct iris_fine_fence *fine =
@@ -339,9 +339,7 @@ iris_fence_await(struct pipe_context *ctx,
if (iris_fine_fence_signaled(fine))
continue;
- for (unsigned b = 0; b < IRIS_BATCH_COUNT; b++) {
- struct iris_batch *batch = &ice->batches[b];
-
+ iris_foreach_batch(ice, batch) {
/* We're going to make any future work in this batch wait for our
* fence to have gone by. But any currently queued work doesn't
* need to wait. Flush the batch now, so it can happen sooner.
@@ -402,14 +400,14 @@ iris_fence_finish(struct pipe_screen *p_screen,
* that it matches first.
*/
if (ctx && ctx == fence->unflushed_ctx) {
- for (unsigned i = 0; i < IRIS_BATCH_COUNT; i++) {
- struct iris_fine_fence *fine = fence->fine[i];
+ iris_foreach_batch(ice, batch) {
+ struct iris_fine_fence *fine = fence->fine[batch->name];
if (iris_fine_fence_signaled(fine))
continue;
- if (fine->syncobj == iris_batch_get_signal_syncobj(&ice->batches[i]))
- iris_batch_flush(&ice->batches[i]);
+ if (fine->syncobj == iris_batch_get_signal_syncobj(batch))
+ iris_batch_flush(batch);
}
/* The fence is no longer deferred. */
@@ -595,7 +593,7 @@ iris_fence_signal(struct pipe_context *ctx,
if (ctx == fence->unflushed_ctx)
return;
- for (unsigned b = 0; b < IRIS_BATCH_COUNT; b++) {
+ iris_foreach_batch(ice, batch) {
for (unsigned i = 0; i < ARRAY_SIZE(fence->fine); i++) {
struct iris_fine_fence *fine = fence->fine[i];
@@ -603,9 +601,8 @@ iris_fence_signal(struct pipe_context *ctx,
if (iris_fine_fence_signaled(fine))
continue;
- ice->batches[b].contains_fence_signal = true;
- iris_batch_add_syncobj(&ice->batches[b], fine->syncobj,
- I915_EXEC_FENCE_SIGNAL);
+ batch->contains_fence_signal = true;
+ iris_batch_add_syncobj(batch, fine->syncobj, I915_EXEC_FENCE_SIGNAL);
}
}
}
diff --git a/src/gallium/drivers/iris/iris_pipe_control.c b/src/gallium/drivers/iris/iris_pipe_control.c
index df6814fd32c..5ef0acba396 100644
--- a/src/gallium/drivers/iris/iris_pipe_control.c
+++ b/src/gallium/drivers/iris/iris_pipe_control.c
@@ -357,11 +357,10 @@ iris_memory_barrier(struct pipe_context *ctx, unsigned flags)
PIPE_CONTROL_TILE_CACHE_FLUSH;
}
- for (int i = 0; i < IRIS_BATCH_COUNT; i++) {
- if (ice->batches[i].contains_draw) {
- iris_batch_maybe_flush(&ice->batches[i], 24);
- iris_emit_pipe_control_flush(&ice->batches[i], "API: memory barrier",
- bits);
+ iris_foreach_batch(ice, batch) {
+ if (batch->contains_draw) {
+ iris_batch_maybe_flush(batch, 24);
+ iris_emit_pipe_control_flush(batch, "API: memory barrier", bits);
}
}
}
diff --git a/src/gallium/drivers/iris/iris_resource.c b/src/gallium/drivers/iris/iris_resource.c
index 109c6de59ff..04d64b41670 100644
--- a/src/gallium/drivers/iris/iris_resource.c
+++ b/src/gallium/drivers/iris/iris_resource.c
@@ -1404,9 +1404,9 @@ iris_flush_resource(struct pipe_context *ctx, struct pipe_resource *resource)
* sure to get rid of any compression that a consumer wouldn't know how
* to handle.
*/
- for (int i = 0; i < IRIS_BATCH_COUNT; i++) {
- if (iris_batch_references(&ice->batches[i], res->bo))
- iris_batch_flush(&ice->batches[i]);
+ iris_foreach_batch(ice, batch) {
+ if (iris_batch_references(batch, res->bo))
+ iris_batch_flush(batch);
}
iris_resource_disable_aux(res);
@@ -1741,8 +1741,8 @@ resource_is_busy(struct iris_context *ice,
{
bool busy = iris_bo_busy(res->bo);
- for (int i = 0; i < IRIS_BATCH_COUNT; i++)
- busy |= iris_batch_references(&ice->batches[i], res->bo);
+ iris_foreach_batch(ice, batch)
+ busy |= iris_batch_references(batch, res->bo);
return busy;
}
@@ -2339,9 +2339,9 @@ iris_transfer_map(struct pipe_context *ctx,
}
if (!(usage & PIPE_MAP_UNSYNCHRONIZED)) {
- for (int i = 0; i < IRIS_BATCH_COUNT; i++) {
- if (iris_batch_references(&ice->batches[i], res->bo))
- iris_batch_flush(&ice->batches[i]);
+ iris_foreach_batch(ice, batch) {
+ if (iris_batch_references(batch, res->bo))
+ iris_batch_flush(batch);
}
}
@@ -2384,8 +2384,7 @@ iris_transfer_flush_region(struct pipe_context *ctx,
}
if (history_flush & ~PIPE_CONTROL_CS_STALL) {
- for (int i = 0; i < IRIS_BATCH_COUNT; i++) {
- struct iris_batch *batch = &ice->batches[i];
+ iris_foreach_batch(ice, batch) {
if (batch->contains_draw || batch->cache.render->entries) {
iris_batch_maybe_flush(batch, 24);
iris_emit_pipe_control_flush(batch,
@@ -2474,9 +2473,9 @@ iris_texture_subdata(struct pipe_context *ctx,
iris_resource_access_raw(ice, res, level, box->z, box->depth, true);
- for (int i = 0; i < IRIS_BATCH_COUNT; i++) {
- if (iris_batch_references(&ice->batches[i], res->bo))
- iris_batch_flush(&ice->batches[i]);
+ iris_foreach_batch(ice, batch) {
+ if (iris_batch_references(batch, res->bo))
+ iris_batch_flush(batch);
}
uint8_t *dst = iris_bo_map(&ice->dbg, res->bo, MAP_WRITE | MAP_RAW);
More information about the mesa-commit
mailing list