freedreno: replace fixed array for globabl_bindings with dynamic array
Freedreno limits set_global_binding() to 16 resource entries (MAX_GLOBAL_BUFFERS), however RustiCL can pass more global resources (e.g. OpenCL CTS test api / min_max_constant_args requires passing of 17). Follow example of other drivers and use dynamic array for global bindings. Backport-to: 25.1 Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35122>
This commit is contained in:
committed by
Marge Bot
parent
abbb0c0125
commit
5c43cf823c
@@ -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 =
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user