iris: Don't check other batches for our batch BO
This is an awkward corner case. We create batches in order, each of which creates and pins a BO. The other batches may not be set up yet, so it may not be safe to ask whether they reference a BO. Just avoid this for now. We could avoid it for other context-local BOs too, but we currently don't have a flag for that (and I'm not certain whether it's worth it).
This commit is contained in:
@@ -274,32 +274,34 @@ iris_use_pinned_bo(struct iris_batch *batch,
|
||||
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 drm_i915_gem_exec_object2 *other_entry =
|
||||
find_validation_entry(batch->other_batches[b], 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 (bo != batch->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.
|
||||
*/
|
||||
if (other_entry &&
|
||||
((other_entry->flags & EXEC_OBJECT_WRITE) || writable)) {
|
||||
iris_batch_flush(batch->other_batches[b]);
|
||||
iris_batch_add_syncpt(batch, batch->other_batches[b]->last_syncpt,
|
||||
I915_EXEC_FENCE_WAIT);
|
||||
for (int b = 0; b < ARRAY_SIZE(batch->other_batches); b++) {
|
||||
struct drm_i915_gem_exec_object2 *other_entry =
|
||||
find_validation_entry(batch->other_batches[b], 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_entry &&
|
||||
((other_entry->flags & EXEC_OBJECT_WRITE) || writable)) {
|
||||
iris_batch_flush(batch->other_batches[b]);
|
||||
iris_batch_add_syncpt(batch, batch->other_batches[b]->last_syncpt,
|
||||
I915_EXEC_FENCE_WAIT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user