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:
@@ -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. */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user