From f2226acd74485905506f0efa545d91582dfe9afb Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Wed, 17 Jun 2020 09:22:42 -0700 Subject: [PATCH] freedreno/ir3: split out ubo info from range Split out the description of the ubo from the ubo-range. Signed-off-by: Rob Clark Part-of: --- .../ir3/ir3_nir_analyze_ubo_ranges.c | 51 +++++++++++-------- src/freedreno/ir3/ir3_shader.h | 18 +++++-- src/freedreno/vulkan/tu_cmd_buffer.c | 8 +-- src/gallium/drivers/freedreno/ir3/ir3_const.h | 4 +- 4 files changed, 50 insertions(+), 31 deletions(-) diff --git a/src/freedreno/ir3/ir3_nir_analyze_ubo_ranges.c b/src/freedreno/ir3/ir3_nir_analyze_ubo_ranges.c index d14e5499445..ec78ff79fc9 100644 --- a/src/freedreno/ir3/ir3_nir_analyze_ubo_ranges.c +++ b/src/freedreno/ir3/ir3_nir_analyze_ubo_ranges.c @@ -28,9 +28,9 @@ #include "util/u_math.h" static bool -range_is_gl_uniforms(struct ir3_ubo_range *r) +ubo_is_gl_uniforms(const struct ir3_ubo_info *ubo) { - return !r->bindless && r->block == 0; + return !ubo->bindless && ubo->block == 0; } static inline struct ir3_ubo_range @@ -54,41 +54,48 @@ get_ubo_load_range(nir_shader *nir, nir_intrinsic_instr *instr, uint32_t alignme return r; } -static struct ir3_ubo_range * -get_existing_range(nir_intrinsic_instr *instr, - struct ir3_ubo_analysis_state *state, - bool create_new) +static bool +get_ubo_info(nir_intrinsic_instr *instr, struct ir3_ubo_info *ubo) { - unsigned block, base = 0; - bool bindless; if (nir_src_is_const(instr->src[0])) { - block = nir_src_as_uint(instr->src[0]); - bindless = false; + ubo->block = nir_src_as_uint(instr->src[0]); + ubo->bindless_base = 0; + ubo->bindless = false; + return true; } else { nir_intrinsic_instr *rsrc = ir3_bindless_resource(instr->src[0]); if (rsrc && nir_src_is_const(rsrc->src[0])) { - block = nir_src_as_uint(rsrc->src[0]); - base = nir_intrinsic_desc_set(rsrc); - bindless = true; - } else { - return NULL; + ubo->block = nir_src_as_uint(rsrc->src[0]); + ubo->bindless_base = nir_intrinsic_desc_set(rsrc); + ubo->bindless = true; + return true; } } + return false; +} + +static struct ir3_ubo_range * +get_existing_range(nir_intrinsic_instr *instr, + struct ir3_ubo_analysis_state *state, + bool create_new) +{ + struct ir3_ubo_info ubo = {}; + + if (!get_ubo_info(instr, &ubo)) + return NULL; + for (int i = 0; i < IR3_MAX_UBO_PUSH_RANGES; i++) { struct ir3_ubo_range *range = &state->range[i]; if (range->end < range->start) { /* We don't have a matching range, but there are more available. */ if (create_new) { - range->block = block; - range->bindless_base = base; - range->bindless = bindless; + range->ubo = ubo; return range; } else { return NULL; } - } else if (range->block == block && range->bindless_base == base && - range->bindless == bindless) { + } else if (!memcmp(&range->ubo, &ubo, sizeof(ubo))) { return range; } } @@ -110,7 +117,7 @@ gather_ubo_ranges(nir_shader *nir, nir_intrinsic_instr *instr, /* We don't know how to get the size of UBOs being indirected on, other * than on the GL uniforms where we have some other shader_info data. */ - if (!nir_src_is_const(instr->src[1]) && !range_is_gl_uniforms(old_r)) + if (!nir_src_is_const(instr->src[1]) && !ubo_is_gl_uniforms(&old_r->ubo)) return; const struct ir3_ubo_range r = get_ubo_load_range(nir, instr, alignment); @@ -219,7 +226,7 @@ lower_ubo_load_to_uniform(nir_intrinsic_instr *instr, nir_builder *b, /* We don't have a good way of determining the range of the dynamic * access in general, so for now just fall back to pulling. */ - if (!nir_src_is_const(instr->src[1]) && !range_is_gl_uniforms(range)) + if (!nir_src_is_const(instr->src[1]) && !ubo_is_gl_uniforms(&range->ubo)) return; /* After gathering the UBO access ranges, we limit the total diff --git a/src/freedreno/ir3/ir3_shader.h b/src/freedreno/ir3/ir3_shader.h index fc2a924b58a..e7e6f381293 100644 --- a/src/freedreno/ir3/ir3_shader.h +++ b/src/freedreno/ir3/ir3_shader.h @@ -72,13 +72,25 @@ enum ir3_driver_param { #define IR3_MAX_SO_OUTPUTS 64 #define IR3_MAX_UBO_PUSH_RANGES 32 +/** + * Description of a lowered UBO. + */ +struct ir3_ubo_info { + uint32_t block; /* Which constant block */ + uint16_t bindless_base; /* For bindless, which base register is used */ + bool bindless; +}; +/** + * Description of a range of a lowered UBO access. + * + * Drivers should not assume that there are not multiple disjoint + * lowered ranges of a single UBO. + */ struct ir3_ubo_range { + struct ir3_ubo_info ubo; uint32_t offset; /* start offset to push in the const register file */ - uint32_t block; /* Which constant block */ uint32_t start, end; /* range of block that's actually used */ - uint16_t bindless_base; /* For bindless, which base register is used */ - bool bindless; }; struct ir3_ubo_analysis_state { diff --git a/src/freedreno/vulkan/tu_cmd_buffer.c b/src/freedreno/vulkan/tu_cmd_buffer.c index 975a0d905ad..731d361712e 100644 --- a/src/freedreno/vulkan/tu_cmd_buffer.c +++ b/src/freedreno/vulkan/tu_cmd_buffer.c @@ -2869,11 +2869,11 @@ tu6_emit_user_consts(struct tu_cs *cs, const struct tu_pipeline *pipeline, /* Dig out the descriptor from the descriptor state and read the VA from * it. */ - assert(state->range[i].bindless); - uint32_t *base = state->range[i].bindless_base == MAX_SETS ? + assert(state->range[i].ubo.bindless); + uint32_t *base = state->range[i].ubo.bindless_base == MAX_SETS ? descriptors_state->dynamic_descriptors : - descriptors_state->sets[state->range[i].bindless_base]->mapped_ptr; - unsigned block = state->range[i].block; + descriptors_state->sets[state->range[i].ubo.bindless_base]->mapped_ptr; + unsigned block = state->range[i].ubo.block; uint32_t *desc = base + block * A6XX_TEX_CONST_DWORDS; uint64_t va = desc[0] | ((uint64_t)(desc[1] & A6XX_UBO_1_BASE_HI__MASK) << 32); assert(va); diff --git a/src/gallium/drivers/freedreno/ir3/ir3_const.h b/src/gallium/drivers/freedreno/ir3/ir3_const.h index ee73bc501d9..1bcd53b66b0 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_const.h +++ b/src/gallium/drivers/freedreno/ir3/ir3_const.h @@ -97,8 +97,8 @@ ir3_emit_user_consts(struct fd_screen *screen, const struct ir3_shader_variant * const struct ir3_ubo_analysis_state *state = &const_state->ubo_state; for (unsigned i = 0; i < state->num_enabled; i++) { - assert(!state->range[i].bindless); - unsigned ubo = state->range[i].block; + assert(!state->range[i].ubo.bindless); + unsigned ubo = state->range[i].ubo.block; if (!(constbuf->enabled_mask & (1 << ubo))) continue; struct pipe_constant_buffer *cb = &constbuf->cb[ubo]; -- 2.30.2