broadcom/compiler: support varyings with struct types
This adds support for using structs as outputs from vertex shaders and inputs to fragment shaders. Reviewed-by: Iago Toral Quiroga <itoral@igalia.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6721>
This commit is contained in:
committed by
Marge Bot
parent
ebd5b555c1
commit
ac5f0ee19c
@@ -738,12 +738,12 @@ emit_fragment_varying(struct v3d_compile *c, nir_variable *var,
|
||||
}
|
||||
|
||||
static void
|
||||
emit_fragment_input(struct v3d_compile *c, int attr, nir_variable *var,
|
||||
int array_index)
|
||||
emit_fragment_input(struct v3d_compile *c, int base_attr, nir_variable *var,
|
||||
int array_index, unsigned nelem)
|
||||
{
|
||||
for (int i = 0; i < glsl_get_vector_elements(var->type); i++) {
|
||||
for (int i = 0; i < nelem ; i++) {
|
||||
int chan = var->data.location_frac + i;
|
||||
c->inputs[attr * 4 + chan] =
|
||||
c->inputs[(base_attr + array_index) * 4 + chan] =
|
||||
emit_fragment_varying(c, var, chan, array_index);
|
||||
}
|
||||
}
|
||||
@@ -1702,11 +1702,11 @@ ntq_setup_fs_inputs(struct v3d_compile *c)
|
||||
|
||||
for (unsigned i = 0; i < num_entries; i++) {
|
||||
nir_variable *var = vars[i];
|
||||
unsigned array_len = MAX2(glsl_get_length(var->type), 1);
|
||||
unsigned var_len = glsl_count_vec4_slots(var->type, false, false);
|
||||
unsigned loc = var->data.driver_location;
|
||||
|
||||
resize_qreg_array(c, &c->inputs, &c->inputs_array_size,
|
||||
(loc + array_len) * 4);
|
||||
(loc + var_len) * 4);
|
||||
|
||||
if (var->data.location == VARYING_SLOT_POS) {
|
||||
emit_fragcoord_input(c, loc);
|
||||
@@ -1715,11 +1715,16 @@ ntq_setup_fs_inputs(struct v3d_compile *c)
|
||||
c->inputs[loc * 4 + 0] = c->point_x;
|
||||
c->inputs[loc * 4 + 1] = c->point_y;
|
||||
} else if (var->data.compact) {
|
||||
for (int j = 0; j < array_len; j++)
|
||||
for (int j = 0; j < var_len; j++)
|
||||
emit_compact_fragment_input(c, loc, var, j);
|
||||
} else if (glsl_type_is_struct(var->type)) {
|
||||
for (int j = 0; j < var_len; j++) {
|
||||
emit_fragment_input(c, loc, var, j, 4);
|
||||
}
|
||||
} else {
|
||||
for (int j = 0; j < array_len; j++)
|
||||
emit_fragment_input(c, loc + j, var, j);
|
||||
for (int j = 0; j < var_len; j++) {
|
||||
emit_fragment_input(c, loc, var, j, glsl_get_vector_elements(var->type));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2130,12 +2135,20 @@ ntq_emit_store_output(struct v3d_compile *c, nir_intrinsic_instr *instr)
|
||||
assert(c->s->info.stage == MESA_SHADER_VERTEX);
|
||||
assert(instr->num_components == 1);
|
||||
|
||||
vir_VPM_WRITE(c,
|
||||
ntq_get_src(c, instr->src[0], 0),
|
||||
nir_intrinsic_base(instr));
|
||||
uint32_t base = nir_intrinsic_base(instr);
|
||||
if (nir_src_is_const(instr->src[1])) {
|
||||
vir_VPM_WRITE(c,
|
||||
ntq_get_src(c, instr->src[0], 0),
|
||||
base + nir_src_as_uint(instr->src[1]));
|
||||
} else {
|
||||
vir_VPM_WRITE_indirect(c,
|
||||
ntq_get_src(c, instr->src[0], 0),
|
||||
vir_ADD(c,
|
||||
ntq_get_src(c, instr->src[1], 1),
|
||||
vir_uniform_ui(c, base)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ntq_emit_intrinsic(struct v3d_compile *c, nir_intrinsic_instr *instr)
|
||||
{
|
||||
|
||||
@@ -180,9 +180,7 @@ v3d_nir_lower_vpm_output(struct v3d_compile *c, nir_builder *b,
|
||||
intr->num_components);
|
||||
nir_variable *var = NULL;
|
||||
nir_foreach_shader_out_variable(scan_var, c->s) {
|
||||
int components = scan_var->data.compact ?
|
||||
glsl_get_length(scan_var->type) :
|
||||
glsl_get_components(scan_var->type);
|
||||
int components = glsl_get_component_slots(scan_var->type);
|
||||
if (scan_var->data.driver_location != nir_intrinsic_base(intr) ||
|
||||
start_comp < scan_var->data.location_frac ||
|
||||
start_comp >= scan_var->data.location_frac + components) {
|
||||
@@ -260,7 +258,7 @@ v3d_nir_lower_vpm_output(struct v3d_compile *c, nir_builder *b,
|
||||
if (vpm_offset == -1)
|
||||
continue;
|
||||
|
||||
if (var->data.compact)
|
||||
if (var->data.compact || glsl_type_is_struct(var->type))
|
||||
vpm_offset += nir_src_as_uint(intr->src[1]) * 4;
|
||||
|
||||
BITSET_SET(state->varyings_stored, vpm_offset);
|
||||
|
||||
Reference in New Issue
Block a user