freedreno/ir3: split out ubo info from range
Split out the description of the ubo from the ubo-range.
Signed-off-by: Rob Clark <robdclark@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5526>
diff --git a/src/freedreno/ir3/ir3_nir_analyze_ubo_ranges.c b/src/freedreno/ir3/ir3_nir_analyze_ubo_ranges.c
index d14e549..ec78ff7 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 @@
return r;
}
+static bool
+get_ubo_info(nir_intrinsic_instr *instr, struct ir3_ubo_info *ubo)
+{
+ if (nir_src_is_const(instr->src[0])) {
+ 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])) {
+ 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)
{
- unsigned block, base = 0;
- bool bindless;
- if (nir_src_is_const(instr->src[0])) {
- block = nir_src_as_uint(instr->src[0]);
- bindless = false;
- } 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;
- }
- }
+ 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 @@
/* 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 @@
/* 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 fc2a924..e7e6f38 100644
--- a/src/freedreno/ir3/ir3_shader.h
+++ b/src/freedreno/ir3/ir3_shader.h
@@ -72,15 +72,27 @@
#define IR3_MAX_SO_OUTPUTS 64
#define IR3_MAX_UBO_PUSH_RANGES 32
-
-struct ir3_ubo_range {
- uint32_t offset; /* start offset to push in the const register file */
+/**
+ * Description of a lowered UBO.
+ */
+struct ir3_ubo_info {
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;
};
+/**
+ * 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 start, end; /* range of block that's actually used */
+};
+
struct ir3_ubo_analysis_state {
struct ir3_ubo_range range[IR3_MAX_UBO_PUSH_RANGES];
uint32_t num_enabled;
diff --git a/src/freedreno/vulkan/tu_cmd_buffer.c b/src/freedreno/vulkan/tu_cmd_buffer.c
index 975a0d9..731d361 100644
--- a/src/freedreno/vulkan/tu_cmd_buffer.c
+++ b/src/freedreno/vulkan/tu_cmd_buffer.c
@@ -2869,11 +2869,11 @@
/* 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 ee73bc5..1bcd53b 100644
--- a/src/gallium/drivers/freedreno/ir3/ir3_const.h
+++ b/src/gallium/drivers/freedreno/ir3/ir3_const.h
@@ -97,8 +97,8 @@
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];