diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_compute.c b/src/gallium/drivers/freedreno/a4xx/fd4_compute.c index e9b3e8b1001..42e94d1c8d8 100644 --- a/src/gallium/drivers/freedreno/a4xx/fd4_compute.c +++ b/src/gallium/drivers/freedreno/a4xx/fd4_compute.c @@ -127,7 +127,7 @@ fd4_launch_grid(struct fd_context *ctx, fd4_emit_cs_state(ctx, ring, v); fd4_emit_cs_consts(v, ring, ctx, info); - u_foreach_bit (i, ctx->global_bindings.enabled_mask) + util_dynarray_foreach (&ctx->global_bindings, struct pipe_resource *, res) nglobal++; if (nglobal > 0) { @@ -138,10 +138,8 @@ fd4_launch_grid(struct fd_context *ctx, * payload: */ OUT_PKT3(ring, CP_NOP, 2 * nglobal); - u_foreach_bit (i, ctx->global_bindings.enabled_mask) { - struct pipe_resource *prsc = ctx->global_bindings.buf[i]; - OUT_RELOC(ring, fd_resource(prsc)->bo, 0, 0, 0); - } + util_dynarray_foreach (&ctx->global_bindings, struct pipe_resource *, res) + OUT_RELOC(ring, fd_resource(*res)->bo, 0, 0, 0); } const unsigned *local_size = diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_compute.c b/src/gallium/drivers/freedreno/a5xx/fd5_compute.c index 003e71428d0..443bc364853 100644 --- a/src/gallium/drivers/freedreno/a5xx/fd5_compute.c +++ b/src/gallium/drivers/freedreno/a5xx/fd5_compute.c @@ -106,7 +106,7 @@ fd5_launch_grid(struct fd_context *ctx, fd5_emit_cs_state(ctx, ring, v); fd5_emit_cs_consts(v, ring, ctx, info); - u_foreach_bit (i, ctx->global_bindings.enabled_mask) + util_dynarray_foreach (&ctx->global_bindings, struct pipe_resource *, res) nglobal++; if (nglobal > 0) { @@ -117,10 +117,8 @@ fd5_launch_grid(struct fd_context *ctx, * payload: */ OUT_PKT7(ring, CP_NOP, 2 * nglobal); - u_foreach_bit (i, ctx->global_bindings.enabled_mask) { - struct pipe_resource *prsc = ctx->global_bindings.buf[i]; - OUT_RELOC(ring, fd_resource(prsc)->bo, 0, 0, 0); - } + util_dynarray_foreach (&ctx->global_bindings, struct pipe_resource *, res) + OUT_RELOC(ring, fd_resource(*res)->bo, 0, 0, 0); } const unsigned *local_size = diff --git a/src/gallium/drivers/freedreno/freedreno_context.c b/src/gallium/drivers/freedreno/freedreno_context.c index f218994271b..9c0fc810395 100644 --- a/src/gallium/drivers/freedreno/freedreno_context.c +++ b/src/gallium/drivers/freedreno/freedreno_context.c @@ -401,6 +401,8 @@ fd_context_destroy(struct pipe_context *pctx) if (ctx->clear_rs_state[i]) pctx->delete_rasterizer_state(pctx, ctx->clear_rs_state[i]); + util_dynarray_fini(&ctx->global_bindings); + slab_destroy_child(&ctx->transfer_pool); slab_destroy_child(&ctx->transfer_pool_unsync); @@ -678,6 +680,8 @@ fd_context_init(struct fd_context *ctx, struct pipe_screen *pscreen, slab_create_child(&ctx->transfer_pool, &screen->transfer_pool); slab_create_child(&ctx->transfer_pool_unsync, &screen->transfer_pool); + util_dynarray_init(&ctx->global_bindings, NULL); + fd_draw_init(pctx); fd_resource_context_init(pctx); fd_query_context_init(pctx); diff --git a/src/gallium/drivers/freedreno/freedreno_context.h b/src/gallium/drivers/freedreno/freedreno_context.h index d7b53280f87..114b7d7e0a3 100644 --- a/src/gallium/drivers/freedreno/freedreno_context.h +++ b/src/gallium/drivers/freedreno/freedreno_context.h @@ -14,6 +14,7 @@ #include "util/list.h" #include "util/slab.h" #include "util/u_blitter.h" +#include "util/u_dynarray.h" #include "util/u_string.h" #include "util/u_threaded_context.h" #include "util/perf/u_trace.h" @@ -110,12 +111,6 @@ struct fd_streamout_stateobj { unsigned verts_written; }; -#define MAX_GLOBAL_BUFFERS 16 -struct fd_global_bindings_stateobj { - struct pipe_resource *buf[MAX_GLOBAL_BUFFERS]; - uint32_t enabled_mask; -}; - /* group together the vertex and vertexbuf state.. for ease of passing * around, and because various internal operations (gmem<->mem, etc) * need their own vertex state: @@ -507,7 +502,7 @@ struct fd_context { struct fd_shaderbuf_stateobj shaderbuf[PIPE_SHADER_TYPES] dt; struct fd_shaderimg_stateobj shaderimg[PIPE_SHADER_TYPES] dt; struct fd_streamout_stateobj streamout dt; - struct fd_global_bindings_stateobj global_bindings dt; + struct util_dynarray global_bindings dt; struct pipe_clip_state ucp dt; struct pipe_query *cond_query dt; diff --git a/src/gallium/drivers/freedreno/freedreno_draw.c b/src/gallium/drivers/freedreno/freedreno_draw.c index b352d120220..02583f67ae3 100644 --- a/src/gallium/drivers/freedreno/freedreno_draw.c +++ b/src/gallium/drivers/freedreno/freedreno_draw.c @@ -596,8 +596,9 @@ fd_launch_grid(struct pipe_context *pctx, /* For global buffers, we don't really know if read or written, so assume * the worst: */ - u_foreach_bit (i, ctx->global_bindings.enabled_mask) - resource_written(batch, ctx->global_bindings.buf[i]); + util_dynarray_foreach (&ctx->global_bindings, struct pipe_resource *, res) { + resource_written(batch, *res); + } if (info->indirect) resource_read(batch, info->indirect); diff --git a/src/gallium/drivers/freedreno/freedreno_state.c b/src/gallium/drivers/freedreno/freedreno_state.c index a8487c3be49..ac0f29fce62 100644 --- a/src/gallium/drivers/freedreno/freedreno_state.c +++ b/src/gallium/drivers/freedreno/freedreno_state.c @@ -725,40 +725,35 @@ fd_set_global_binding(struct pipe_context *pctx, unsigned first, unsigned count, struct pipe_resource **prscs, uint32_t **handles) in_dt { struct fd_context *ctx = fd_context(pctx); - struct fd_global_bindings_stateobj *so = &ctx->global_bindings; - unsigned mask = 0; + unsigned old_size = util_dynarray_num_elements(&ctx->global_bindings, *prscs); - if (prscs) { - for (unsigned i = 0; i < count; i++) { - unsigned n = i + first; + if (old_size < first + count) { + /* we are screwed no matter what */ + if (!util_dynarray_grow(&ctx->global_bindings, *prscs, + (first + count) - old_size)) + unreachable("out of memory"); - mask |= BIT(n); + for (unsigned i = old_size; i < first + count; i++) + *util_dynarray_element(&ctx->global_bindings, + struct pipe_resource *, i) = NULL; + } - pipe_resource_reference(&so->buf[n], prscs[i]); + for (unsigned i = first; i < first + count; ++i) { + struct pipe_resource **res = util_dynarray_element(&ctx->global_bindings, + struct pipe_resource *, + first + i); + if (prscs && prscs[i]) { + pipe_resource_reference(res, prscs[i]); - if (so->buf[n]) { - struct fd_resource *rsc = fd_resource(so->buf[n]); - uint32_t offset = *handles[i]; - uint64_t iova = fd_bo_get_iova(rsc->bo) + offset; + struct fd_resource *rsc = fd_resource(prscs[i]); + uint32_t offset = *handles[i]; + uint64_t iova = fd_bo_get_iova(rsc->bo) + offset; - /* Yes, really, despite what the type implies: */ - memcpy(handles[i], &iova, sizeof(iova)); - } - - if (prscs[i]) - so->enabled_mask |= BIT(n); - else - so->enabled_mask &= ~BIT(n); + /* Yes, really, despite what the type implies: */ + memcpy(handles[i], &iova, sizeof(iova)); + } else { + pipe_resource_reference(res, NULL); } - } else { - mask = (BIT(count) - 1) << first; - - for (unsigned i = 0; i < count; i++) { - unsigned n = i + first; - pipe_resource_reference(&so->buf[n], NULL); - } - - so->enabled_mask &= ~mask; } }