diff options
author | Timothy Arceri <[email protected]> | 2018-01-15 11:45:37 +1100 |
---|---|---|
committer | Timothy Arceri <[email protected]> | 2018-01-31 09:14:07 +1100 |
commit | dd6d6c63a700af98a7a7d65dcdf72e8be69d4643 (patch) | |
tree | b68e36b65a0b64344e1ccbbbd00bea72de0e16e5 | |
parent | d185190222cea1def252b15c1fca3676b50d76b4 (diff) |
radeonsi/nir: add input support for arrays that have not been copied to temps and split
We need this to be able to support the interpolateAt builtins in a
sane way. It also leads to the generation of more optimal code.
Reviewed-by: Marek Olšák <[email protected]>
-rw-r--r-- | src/gallium/drivers/radeonsi/si_shader_nir.c | 146 |
1 files changed, 79 insertions, 67 deletions
diff --git a/src/gallium/drivers/radeonsi/si_shader_nir.c b/src/gallium/drivers/radeonsi/si_shader_nir.c index b6aa79857af..128be585cd1 100644 --- a/src/gallium/drivers/radeonsi/si_shader_nir.c +++ b/src/gallium/drivers/radeonsi/si_shader_nir.c @@ -266,7 +266,14 @@ void si_nir_scan_shader(const struct nir_shader *nir, unsigned num_inputs = 0; nir_foreach_variable(variable, &nir->inputs) { unsigned semantic_name, semantic_index; - unsigned attrib_count = glsl_count_attribute_slots(variable->type, + + const struct glsl_type *type = variable->type; + if (nir_is_per_vertex_io(variable, nir->info.stage)) { + assert(glsl_type_is_array(type)); + type = glsl_get_array_element(type); + } + + unsigned attrib_count = glsl_count_attribute_slots(type, nir->info.stage == MESA_SHADER_VERTEX); /* Vertex shader inputs don't have semantics. The state @@ -281,9 +288,6 @@ void si_nir_scan_shader(const struct nir_shader *nir, continue; } - assert(nir->info.stage != MESA_SHADER_FRAGMENT || - (attrib_count == 1 && "not implemented")); - /* Fragment shader position is a system value. */ if (nir->info.stage == MESA_SHADER_FRAGMENT && variable->data.location == VARYING_SLOT_POS) { @@ -296,66 +300,70 @@ void si_nir_scan_shader(const struct nir_shader *nir, } i = variable->data.driver_location; - if (processed_inputs & ((uint64_t)1 << i)) - continue; - processed_inputs |= ((uint64_t)1 << i); - num_inputs++; + for (unsigned j = 0; j < attrib_count; j++, i++) { - tgsi_get_gl_varying_semantic(variable->data.location, true, - &semantic_name, &semantic_index); + if (processed_inputs & ((uint64_t)1 << i)) + continue; - info->input_semantic_name[i] = semantic_name; - info->input_semantic_index[i] = semantic_index; + processed_inputs |= ((uint64_t)1 << i); + num_inputs++; - if (semantic_name == TGSI_SEMANTIC_PRIMID) - info->uses_primid = true; + tgsi_get_gl_varying_semantic(variable->data.location + j, true, + &semantic_name, &semantic_index); - if (variable->data.sample) - info->input_interpolate_loc[i] = TGSI_INTERPOLATE_LOC_SAMPLE; - else if (variable->data.centroid) - info->input_interpolate_loc[i] = TGSI_INTERPOLATE_LOC_CENTROID; - else - info->input_interpolate_loc[i] = TGSI_INTERPOLATE_LOC_CENTER; + info->input_semantic_name[i] = semantic_name; + info->input_semantic_index[i] = semantic_index; - enum glsl_base_type base_type = - glsl_get_base_type(glsl_without_array(variable->type)); + if (semantic_name == TGSI_SEMANTIC_PRIMID) + info->uses_primid = true; - switch (variable->data.interpolation) { - case INTERP_MODE_NONE: - if (glsl_base_type_is_integer(base_type)) { - info->input_interpolate[i] = TGSI_INTERPOLATE_CONSTANT; - break; - } + if (variable->data.sample) + info->input_interpolate_loc[i] = TGSI_INTERPOLATE_LOC_SAMPLE; + else if (variable->data.centroid) + info->input_interpolate_loc[i] = TGSI_INTERPOLATE_LOC_CENTROID; + else + info->input_interpolate_loc[i] = TGSI_INTERPOLATE_LOC_CENTER; - if (semantic_name == TGSI_SEMANTIC_COLOR) { - info->input_interpolate[i] = TGSI_INTERPOLATE_COLOR; - break; - } - /* fall-through */ + enum glsl_base_type base_type = + glsl_get_base_type(glsl_without_array(variable->type)); - case INTERP_MODE_SMOOTH: - assert(!glsl_base_type_is_integer(base_type)); + switch (variable->data.interpolation) { + case INTERP_MODE_NONE: + if (glsl_base_type_is_integer(base_type)) { + info->input_interpolate[i] = TGSI_INTERPOLATE_CONSTANT; + break; + } - info->input_interpolate[i] = TGSI_INTERPOLATE_PERSPECTIVE; - break; + if (semantic_name == TGSI_SEMANTIC_COLOR) { + info->input_interpolate[i] = TGSI_INTERPOLATE_COLOR; + break; + } + /* fall-through */ - case INTERP_MODE_NOPERSPECTIVE: - assert(!glsl_base_type_is_integer(base_type)); + case INTERP_MODE_SMOOTH: + assert(!glsl_base_type_is_integer(base_type)); - info->input_interpolate[i] = TGSI_INTERPOLATE_LINEAR; - break; + info->input_interpolate[i] = TGSI_INTERPOLATE_PERSPECTIVE; + break; - case INTERP_MODE_FLAT: - info->input_interpolate[i] = TGSI_INTERPOLATE_CONSTANT; - break; - } + case INTERP_MODE_NOPERSPECTIVE: + assert(!glsl_base_type_is_integer(base_type)); + + info->input_interpolate[i] = TGSI_INTERPOLATE_LINEAR; + break; - /* TODO make this more precise */ - if (variable->data.location == VARYING_SLOT_COL0) - info->colors_read |= 0x0f; - else if (variable->data.location == VARYING_SLOT_COL1) - info->colors_read |= 0xf0; + case INTERP_MODE_FLAT: + info->input_interpolate[i] = TGSI_INTERPOLATE_CONSTANT; + break; + } + + /* TODO make this more precise */ + if (variable->data.location == VARYING_SLOT_COL0) + info->colors_read |= 0x0f; + else if (variable->data.location == VARYING_SLOT_COL1) + info->colors_read |= 0xf0; + } } info->num_inputs = num_inputs; @@ -753,31 +761,35 @@ bool si_nir_build_llvm(struct si_shader_context *ctx, struct nir_shader *nir) nir->info.stage == MESA_SHADER_VERTEX); unsigned input_idx = variable->data.driver_location; - assert(attrib_count == 1); - LLVMValueRef data[4]; unsigned loc = variable->data.location; - /* Packed components share the same location so skip - * them if we have already processed the location. - */ - if (processed_inputs & ((uint64_t)1 << loc)) - continue; - - if (nir->info.stage == MESA_SHADER_VERTEX) { - declare_nir_input_vs(ctx, variable, input_idx / 4, data); - bitcast_inputs(ctx, data, input_idx); - if (glsl_type_is_dual_slot(variable->type)) { + for (unsigned i = 0; i < attrib_count; i++) { + /* Packed components share the same location so skip + * them if we have already processed the location. + */ + if (processed_inputs & ((uint64_t)1 << loc)) { input_idx += 4; + continue; + } + + if (nir->info.stage == MESA_SHADER_VERTEX) { declare_nir_input_vs(ctx, variable, input_idx / 4, data); bitcast_inputs(ctx, data, input_idx); + if (glsl_type_is_dual_slot(variable->type)) { + input_idx += 4; + declare_nir_input_vs(ctx, variable, input_idx / 4, data); + bitcast_inputs(ctx, data, input_idx); + } + } else if (nir->info.stage == MESA_SHADER_FRAGMENT) { + declare_nir_input_fs(ctx, variable, input_idx / 4, data); + bitcast_inputs(ctx, data, input_idx); } - } else if (nir->info.stage == MESA_SHADER_FRAGMENT) { - declare_nir_input_fs(ctx, variable, input_idx / 4, data); - bitcast_inputs(ctx, data, input_idx); - } - processed_inputs |= ((uint64_t)1 << loc); + processed_inputs |= ((uint64_t)1 << loc); + loc++; + input_idx += 4; + } } } |