From 9feb637cd0ea77f1ef232153daf9d9fd30bccd3d Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Thu, 30 Oct 2014 14:35:00 +0800 Subject: [PATCH] ilo: use a dynamic array for global bindings Use util_dynarray in ilo_set_global_binding() to allow for unlimited number of global bindings. Add a comment for global bindings. Signed-off-by: Chia-I Wu --- src/gallium/drivers/ilo/ilo_state.c | 63 ++++++++++++++++++++++------- src/gallium/drivers/ilo/ilo_state.h | 39 +++++++++--------- 2 files changed, 70 insertions(+), 32 deletions(-) diff --git a/src/gallium/drivers/ilo/ilo_state.c b/src/gallium/drivers/ilo/ilo_state.c index 18c1566d93a..217d22c614b 100644 --- a/src/gallium/drivers/ilo/ilo_state.c +++ b/src/gallium/drivers/ilo/ilo_state.c @@ -25,6 +25,7 @@ * Chia-I Wu */ +#include "util/u_dynarray.h" #include "util/u_helpers.h" #include "util/u_upload_mgr.h" @@ -1138,30 +1139,52 @@ ilo_set_global_binding(struct pipe_context *pipe, uint32_t **handles) { struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector; - struct ilo_global_binding *dst = &vec->global_binding; + struct ilo_global_binding_cso *dst; unsigned i; - assert(start + count <= Elements(dst->resources)); + /* make room */ + if (vec->global_binding.count < start + count) { + if (resources) { + const unsigned old_size = vec->global_binding.bindings.size; + const unsigned new_size = sizeof(*dst) * (start + count); - if (resources) { - for (i = 0; i < count; i++) - pipe_resource_reference(&dst->resources[start + i], resources[i]); + if (old_size < new_size) { + util_dynarray_resize(&vec->global_binding.bindings, new_size); + memset(vec->global_binding.bindings.data + old_size, 0, + new_size - old_size); + } + } else { + count = vec->global_binding.count - start; + } } - else { - for (i = 0; i < count; i++) - pipe_resource_reference(&dst->resources[start + i], NULL); + + dst = util_dynarray_element(&vec->global_binding.bindings, + struct ilo_global_binding_cso, start); + + if (resources) { + for (i = 0; i < count; i++) { + pipe_resource_reference(&dst[i].resource, resources[i]); + dst[i].handle = handles[i]; + } + } else { + for (i = 0; i < count; i++) { + pipe_resource_reference(&dst[i].resource, NULL); + dst[i].handle = NULL; + } } - if (dst->count <= start + count) { + if (vec->global_binding.count <= start + count) { + dst = util_dynarray_begin(&vec->global_binding.bindings); + if (resources) count += start; else count = start; - while (count > 0 && !dst->resources[count - 1]) + while (count > 0 && !dst[count - 1].resource) count--; - dst->count = count; + vec->global_binding.count = count; } vec->dirty |= ILO_DIRTY_GLOBAL_BINDING; @@ -1240,6 +1263,8 @@ ilo_state_vector_init(const struct ilo_dev_info *dev, ilo_gpe_init_zs_surface(dev, NULL, PIPE_FORMAT_NONE, 0, 0, 1, &vec->fb.null_zs); + util_dynarray_init(&vec->global_binding.bindings); + vec->dirty = ILO_DIRTY_ALL; } @@ -1283,8 +1308,14 @@ ilo_state_vector_cleanup(struct ilo_state_vector *vec) for (i = 0; i < vec->cs_resource.count; i++) pipe_surface_reference(&vec->cs_resource.states[i], NULL); - for (i = 0; i < vec->global_binding.count; i++) - pipe_resource_reference(&vec->global_binding.resources[i], NULL); + for (i = 0; i < vec->global_binding.count; i++) { + struct ilo_global_binding_cso *cso = + util_dynarray_element(&vec->global_binding.bindings, + struct ilo_global_binding_cso, i); + pipe_resource_reference(&cso->resource, NULL); + } + + util_dynarray_fini(&vec->global_binding.bindings); } /** @@ -1405,7 +1436,11 @@ ilo_state_vector_resource_renamed(struct ilo_state_vector *vec, } for (i = 0; i < vec->global_binding.count; i++) { - if (vec->global_binding.resources[i] == res) { + struct ilo_global_binding_cso *cso = + util_dynarray_element(&vec->global_binding.bindings, + struct ilo_global_binding_cso, i); + + if (cso->resource == res) { states |= ILO_DIRTY_GLOBAL_BINDING; break; } diff --git a/src/gallium/drivers/ilo/ilo_state.h b/src/gallium/drivers/ilo/ilo_state.h index a1d4b7bffcb..7343b20e357 100644 --- a/src/gallium/drivers/ilo/ilo_state.h +++ b/src/gallium/drivers/ilo/ilo_state.h @@ -29,6 +29,7 @@ #define ILO_STATE_H #include "pipe/p_state.h" +#include "util/u_dynarray.h" #include "ilo_common.h" @@ -349,25 +350,27 @@ struct ilo_fb_state { unsigned num_samples; }; +struct ilo_global_binding_cso { + struct pipe_resource *resource; + uint32_t *handle; +}; + +/* + * In theory, we would like a "virtual" bo that serves as the global memory + * region. The virtual bo would reserve a region in the GTT aperture, but the + * pages of it would come from those of the global bindings. + * + * The virtual bo would be created in launch_grid(). The global bindings + * would be added to the virtual bo. A SURFACE_STATE for the virtual bo would + * be created. The handles returned by set_global_binding() would be offsets + * into the virtual bo. + * + * But for now, we will create a SURFACE_STATE for each of the bindings. The + * handle of a global binding consists of the offset and the binding table + * index. + */ struct ilo_global_binding { - /* - * XXX These should not be treated as real resources (and there could be - * thousands of them). They should be treated as regions in GLOBAL - * resource, which is the only real resource. - * - * That is, a resource here should instead be - * - * struct ilo_global_region { - * struct pipe_resource base; - * int offset; - * int size; - * }; - * - * and it describes the region [offset, offset + size) in GLOBAL - * resource. - */ - struct pipe_resource *resources[PIPE_MAX_SHADER_RESOURCES]; - uint32_t *handles[PIPE_MAX_SHADER_RESOURCES]; + struct util_dynarray bindings; unsigned count; }; -- 2.30.2