diff --git a/src/gallium/drivers/iris/iris_batch.c b/src/gallium/drivers/iris/iris_batch.c index 4d073077df1..4119d5eb829 100644 --- a/src/gallium/drivers/iris/iris_batch.c +++ b/src/gallium/drivers/iris/iris_batch.c @@ -294,6 +294,41 @@ add_bo_to_batch(struct iris_batch *batch, struct iris_bo *bo, bool writable) MAX2(batch->max_gem_handle, iris_get_backing_bo(bo)->gem_handle); } +static void +flush_for_cross_batch_dependencies(struct iris_batch *batch, + struct iris_bo *bo, + bool writable) +{ + if (batch->measure && bo == batch->measure->bo) + return; + + /* This is the first time our batch has seen this BO. Before we use it, + * we may need to flush and synchronize with other batches. + */ + for (int b = 0; b < ARRAY_SIZE(batch->other_batches); b++) { + struct iris_batch *other_batch = batch->other_batches[b]; + int other_index = find_exec_index(other_batch, bo); + + /* If the buffer is referenced by another batch, and either batch + * intends to write it, then flush the other batch and synchronize. + * + * Consider these cases: + * + * 1. They read, we read => No synchronization required. + * 2. They read, we write => Synchronize (they need the old value) + * 3. They write, we read => Synchronize (we need their new value) + * 4. They write, we write => Synchronize (order writes) + * + * The read/read case is very common, as multiple batches usually + * share a streaming state buffer or shader assembly buffer, and + * we want to avoid synchronizing in this case. + */ + if (other_index != -1 && + (writable || BITSET_TEST(other_batch->bos_written, other_index))) + iris_batch_flush(other_batch); + } +} + /** * Add a buffer to the current batch's validation list. * @@ -332,33 +367,7 @@ iris_use_pinned_bo(struct iris_batch *batch, return; } - if (!batch->measure || bo != batch->measure->bo) { - /* This is the first time our batch has seen this BO. Before we use it, - * we may need to flush and synchronize with other batches. - */ - for (int b = 0; b < ARRAY_SIZE(batch->other_batches); b++) { - struct iris_batch *other_batch = batch->other_batches[b]; - int other_index = find_exec_index(other_batch, bo); - - /* If the buffer is referenced by another batch, and either batch - * intends to write it, then flush the other batch and synchronize. - * - * Consider these cases: - * - * 1. They read, we read => No synchronization required. - * 2. They read, we write => Synchronize (they need the old value) - * 3. They write, we read => Synchronize (we need their new value) - * 4. They write, we write => Synchronize (order writes) - * - * The read/read case is very common, as multiple batches usually - * share a streaming state buffer or shader assembly buffer, and - * we want to avoid synchronizing in this case. - */ - if (other_index != -1 && - (writable || BITSET_TEST(other_batch->bos_written, other_index))) - iris_batch_flush(other_batch); - } - } + flush_for_cross_batch_dependencies(batch, bo, writable); ensure_exec_obj_space(batch, 1); add_bo_to_batch(batch, bo, writable);