v3d: Upload all of UBO[0] if any indirect load occurs.

The idea was that we could skip uploading the constant-indexed uniform
data and just upload the uniforms that are variably-indexed.  However,
since the VS bin and render shaders may have a different set of uniforms
used, this meant that we had to upload the UBO for each of them.  The
first case is generally a fairly small impact (usually the uniform array
is the most space, other than a couple of FSes in shader-db), while the
second is a larger impact: 3DMMES2 was uploading 38k/frame of uniforms
instead of 18k.

Given that the optimization is of dubious value, has a big downside, and
is quite a bit of code, just drop it.  No change in shader-db.  No change
on 3DMMES2 (n=15).
This commit is contained in:
Eric Anholt
2019-03-19 09:58:14 -07:00
parent 320e96bace
commit 16f2770eb4
4 changed files with 20 additions and 167 deletions
+1 -64
View File
@@ -231,31 +231,7 @@ ntq_emit_tmu_general(struct v3d_compile *c, nir_intrinsic_instr *instr,
struct qreg offset;
if (instr->intrinsic == nir_intrinsic_load_uniform) {
/* Find what variable in the default uniform block this
* uniform load is coming from.
*/
uint32_t base = nir_intrinsic_base(instr);
int i;
struct v3d_ubo_range *range = NULL;
for (i = 0; i < c->num_ubo_ranges; i++) {
range = &c->ubo_ranges[i];
if (base >= range->src_offset &&
base < range->src_offset + range->size) {
break;
}
}
/* The driver-location-based offset always has to be within a
* declared uniform range.
*/
assert(i != c->num_ubo_ranges);
if (!c->ubo_range_used[i]) {
c->ubo_range_used[i] = true;
range->dst_offset = c->next_ubo_dst_offset;
c->next_ubo_dst_offset += range->size;
}
const_offset += base - range->src_offset + range->dst_offset;
const_offset += nir_intrinsic_base(instr);
offset = vir_uniform(c, QUNIFORM_UBO_ADDR,
v3d_unit_data_create(0, const_offset));
const_offset = 0;
@@ -668,27 +644,6 @@ add_output(struct v3d_compile *c,
v3d_slot_from_slot_and_component(slot, swizzle);
}
static void
declare_uniform_range(struct v3d_compile *c, uint32_t start, uint32_t size)
{
unsigned array_id = c->num_ubo_ranges++;
if (array_id >= c->ubo_ranges_array_size) {
c->ubo_ranges_array_size = MAX2(c->ubo_ranges_array_size * 2,
array_id + 1);
c->ubo_ranges = reralloc(c, c->ubo_ranges,
struct v3d_ubo_range,
c->ubo_ranges_array_size);
c->ubo_range_used = reralloc(c, c->ubo_range_used,
bool,
c->ubo_ranges_array_size);
}
c->ubo_ranges[array_id].dst_offset = 0;
c->ubo_ranges[array_id].src_offset = start;
c->ubo_ranges[array_id].size = size;
c->ubo_range_used[array_id] = false;
}
/**
* If compare_instr is a valid comparison instruction, emits the
* compare_instr's comparison and returns the sel_instr's return value based
@@ -1536,23 +1491,6 @@ ntq_setup_outputs(struct v3d_compile *c)
}
}
static void
ntq_setup_uniforms(struct v3d_compile *c)
{
nir_foreach_variable(var, &c->s->uniforms) {
uint32_t vec4_count = glsl_count_attribute_slots(var->type,
false);
unsigned vec4_size = 4 * sizeof(float);
if (var->data.mode != nir_var_uniform)
continue;
declare_uniform_range(c, var->data.driver_location * vec4_size,
vec4_count * vec4_size);
}
}
/**
* Sets up the mapping from nir_register to struct qreg *.
*
@@ -2361,7 +2299,6 @@ nir_to_vir(struct v3d_compile *c)
ntq_setup_vpm_inputs(c);
ntq_setup_outputs(c);
ntq_setup_uniforms(c);
ntq_setup_registers(c, &c->s->registers);
/* Find the main function and emit the body. */
-29
View File
@@ -318,25 +318,6 @@ static inline uint8_t v3d_slot_get_component(struct v3d_varying_slot slot)
return slot.slot_and_component & 3;
}
struct v3d_ubo_range {
/**
* offset in bytes from the start of the ubo where this range is
* uploaded.
*
* Only set once used is set.
*/
uint32_t dst_offset;
/**
* offset in bytes from the start of the gallium uniforms where the
* data comes from.
*/
uint32_t src_offset;
/** size in bytes of this ubo range */
uint32_t size;
};
struct v3d_key {
void *shader_state;
struct {
@@ -533,13 +514,6 @@ struct v3d_compile {
bool uses_center_w;
bool writes_z;
struct v3d_ubo_range *ubo_ranges;
bool *ubo_range_used;
uint32_t ubo_ranges_array_size;
/** Number of uniform areas tracked in ubo_ranges. */
uint32_t num_ubo_ranges;
uint32_t next_ubo_dst_offset;
/* State for whether we're executing on each channel currently. 0 if
* yes, otherwise a block number + 1 that the channel jumped to.
*/
@@ -674,9 +648,6 @@ struct v3d_uniform_list {
struct v3d_prog_data {
struct v3d_uniform_list uniforms;
struct v3d_ubo_range *ubo_ranges;
uint32_t num_ubo_ranges;
uint32_t ubo_size;
uint32_t spill_size;
uint8_t threads;
-36
View File
@@ -582,41 +582,6 @@ v3d_set_prog_data_uniforms(struct v3d_compile *c,
count * sizeof(*ulist->contents));
}
/* Copy the compiler UBO range state to the compiled shader, dropping out
* arrays that were never referenced by an indirect load.
*
* (Note that QIR dead code elimination of an array access still leaves that
* array alive, though)
*/
static void
v3d_set_prog_data_ubo(struct v3d_compile *c,
struct v3d_prog_data *prog_data)
{
if (!c->num_ubo_ranges)
return;
prog_data->num_ubo_ranges = 0;
prog_data->ubo_ranges = ralloc_array(prog_data, struct v3d_ubo_range,
c->num_ubo_ranges);
for (int i = 0; i < c->num_ubo_ranges; i++) {
if (!c->ubo_range_used[i])
continue;
struct v3d_ubo_range *range = &c->ubo_ranges[i];
prog_data->ubo_ranges[prog_data->num_ubo_ranges++] = *range;
prog_data->ubo_size += range->size;
}
if (prog_data->ubo_size) {
if (V3D_DEBUG & V3D_DEBUG_SHADERDB) {
fprintf(stderr, "SHADER-DB: %s prog %d/%d: %d UBO uniforms\n",
vir_get_stage_name(c),
c->program_id, c->variant_id,
prog_data->ubo_size / 4);
}
}
}
static void
v3d_vs_set_prog_data(struct v3d_compile *c,
struct v3d_vs_prog_data *prog_data)
@@ -713,7 +678,6 @@ v3d_set_prog_data(struct v3d_compile *c,
prog_data->spill_size = c->spill_size;
v3d_set_prog_data_uniforms(c, prog_data);
v3d_set_prog_data_ubo(c, prog_data);
if (c->s->info.stage == MESA_SHADER_VERTEX) {
v3d_vs_set_prog_data(c, (struct v3d_vs_prog_data *)prog_data);