summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/iris/iris_binder.c
diff options
context:
space:
mode:
authorKenneth Graunke <[email protected]>2019-01-18 12:26:41 -0800
committerKenneth Graunke <[email protected]>2019-02-21 10:26:11 -0800
commit4801af2f26ced530b6a8c86a79a16857e670959a (patch)
tree1a3981a5fc951128c7c7bc19c1f40bd986267ab1 /src/gallium/drivers/iris/iris_binder.c
parent0f33204f0524390b7428ea68fcc024063e4ef358 (diff)
iris: Do binder address allocations per-context, not globally.
iris_bufmgr allocates addresses across the entire screen, since buffers may be shared between multiple contexts. There used to be a single special address, IRIS_BINDER_ADDRESS, that was per-context - and all contexts used the same address. When I moved to the multi-binder system, I made a separate memory zone for them. I wanted there to be 2-3 binders per context, so we could cycle them to avoid the stalls inherent in pinning two buffers to the same address in back-to-back batches. But I figured I'd allow 100 binders just to be wildly excessive/cautious. What I didn't realize was that we need 2-3 binders per *context*, and what I did was allocate 100 binders per *screen*. Web browsers, for example, might have 1-2 contexts per tab, leading to hundreds of contexts, and thus binders. To fix this, we stop allocating VMA for binders in bufmgr, and let the binder handle it itself. Binders are per-context, and they can assign context-local addresses for the buffers by simply doing a ringbuffer style approach. We only hold on to one binder BO at a time, so we won't ever have a conflicting address. This fixes dEQP-EGL.functional.multicontext.non_shared_clear. Huge thanks to Tapani Pälli for debugging this whole mess and figuring out what was going wrong. Reviewed-by: Tapani Pälli <[email protected]>
Diffstat (limited to 'src/gallium/drivers/iris/iris_binder.c')
-rw-r--r--src/gallium/drivers/iris/iris_binder.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/src/gallium/drivers/iris/iris_binder.c b/src/gallium/drivers/iris/iris_binder.c
index ca60287df3f..6d23de229bf 100644
--- a/src/gallium/drivers/iris/iris_binder.c
+++ b/src/gallium/drivers/iris/iris_binder.c
@@ -71,10 +71,23 @@ binder_realloc(struct iris_context *ice)
struct iris_bufmgr *bufmgr = screen->bufmgr;
struct iris_binder *binder = &ice->state.binder;
- iris_bo_unreference(binder->bo);
+ uint64_t next_address = IRIS_MEMZONE_BINDER_START;
+
+ if (binder->bo) {
+ /* Place the new binder just after the old binder, unless we've hit the
+ * end of the memory zone...then wrap around to the start again.
+ */
+ next_address = binder->bo->gtt_offset + IRIS_BINDER_SIZE;
+ if (next_address >= IRIS_MEMZONE_SURFACE_START)
+ next_address = IRIS_MEMZONE_BINDER_START;
+
+ iris_bo_unreference(binder->bo);
+ }
+
binder->bo =
iris_bo_alloc(bufmgr, "binder", IRIS_BINDER_SIZE, IRIS_MEMZONE_BINDER);
+ binder->bo->gtt_offset = next_address;
binder->map = iris_bo_map(NULL, binder->bo, MAP_WRITE);
binder->insert_point = INIT_INSERT_POINT;