radv/ac: overhaul vs output/ps input routing

In order to cleanly eliminate exports rewrite the
code first to mirror how radeonsi works for now.

Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
Dave Airlie
2017-04-21 03:17:23 +01:00
parent b858cb4df8
commit b2cedb3ea9
3 changed files with 55 additions and 37 deletions

View File

@@ -5133,8 +5133,9 @@ handle_vs_outputs_post(struct nir_to_llvm_context *ctx,
LLVMValueRef psize_value = NULL, layer_value = NULL, viewport_index_value = NULL; LLVMValueRef psize_value = NULL, layer_value = NULL, viewport_index_value = NULL;
int i; int i;
outinfo->prim_id_output = 0xffffffff; memset(outinfo->vs_output_param_offset, EXP_PARAM_UNDEFINED,
outinfo->layer_output = 0xffffffff; sizeof(outinfo->vs_output_param_offset));
if (ctx->output_mask & (1ull << VARYING_SLOT_CLIP_DIST0)) { if (ctx->output_mask & (1ull << VARYING_SLOT_CLIP_DIST0)) {
LLVMValueRef slots[8]; LLVMValueRef slots[8];
unsigned j; unsigned j;
@@ -5184,20 +5185,21 @@ handle_vs_outputs_post(struct nir_to_llvm_context *ctx,
} else if (i == VARYING_SLOT_LAYER) { } else if (i == VARYING_SLOT_LAYER) {
outinfo->writes_layer = true; outinfo->writes_layer = true;
layer_value = values[0]; layer_value = values[0];
outinfo->layer_output = param_count;
target = V_008DFC_SQ_EXP_PARAM + param_count; target = V_008DFC_SQ_EXP_PARAM + param_count;
outinfo->vs_output_param_offset[VARYING_SLOT_LAYER] = param_count;
param_count++; param_count++;
} else if (i == VARYING_SLOT_VIEWPORT) { } else if (i == VARYING_SLOT_VIEWPORT) {
outinfo->writes_viewport_index = true; outinfo->writes_viewport_index = true;
viewport_index_value = values[0]; viewport_index_value = values[0];
continue; continue;
} else if (i == VARYING_SLOT_PRIMITIVE_ID) { } else if (i == VARYING_SLOT_PRIMITIVE_ID) {
outinfo->prim_id_output = param_count;
target = V_008DFC_SQ_EXP_PARAM + param_count; target = V_008DFC_SQ_EXP_PARAM + param_count;
outinfo->vs_output_param_offset[VARYING_SLOT_PRIMITIVE_ID] = param_count;
param_count++; param_count++;
} else if (i >= VARYING_SLOT_VAR0) { } else if (i >= VARYING_SLOT_VAR0) {
outinfo->export_mask |= 1u << (i - VARYING_SLOT_VAR0); outinfo->export_mask |= 1u << (i - VARYING_SLOT_VAR0);
target = V_008DFC_SQ_EXP_PARAM + param_count; target = V_008DFC_SQ_EXP_PARAM + param_count;
outinfo->vs_output_param_offset[i] = param_count;
param_count++; param_count++;
} }

View File

@@ -120,14 +120,25 @@ struct ac_userdata_locations {
struct ac_userdata_info shader_data[AC_UD_MAX_UD]; struct ac_userdata_info shader_data[AC_UD_MAX_UD];
}; };
enum {
/* SPI_PS_INPUT_CNTL_i.OFFSET[0:4] */
EXP_PARAM_OFFSET_0 = 0,
EXP_PARAM_OFFSET_31 = 31,
/* SPI_PS_INPUT_CNTL_i.DEFAULT_VAL[0:1] */
EXP_PARAM_DEFAULT_VAL_0000 = 64,
EXP_PARAM_DEFAULT_VAL_0001,
EXP_PARAM_DEFAULT_VAL_1110,
EXP_PARAM_DEFAULT_VAL_1111,
EXP_PARAM_UNDEFINED = 255,
};
struct ac_vs_output_info { struct ac_vs_output_info {
uint8_t vs_output_param_offset[VARYING_SLOT_MAX];
uint8_t clip_dist_mask; uint8_t clip_dist_mask;
uint8_t cull_dist_mask; uint8_t cull_dist_mask;
bool writes_pointsize; bool writes_pointsize;
bool writes_layer; bool writes_layer;
bool writes_viewport_index; bool writes_viewport_index;
uint32_t prim_id_output;
uint32_t layer_output;
uint32_t export_mask; uint32_t export_mask;
unsigned param_exports; unsigned param_exports;
unsigned pos_exports; unsigned pos_exports;

View File

@@ -1870,6 +1870,25 @@ static void calculate_pa_cl_vs_out_cntl(struct radv_pipeline *pipeline)
clip_dist_mask; clip_dist_mask;
} }
static uint32_t offset_to_ps_input(uint32_t offset, bool flat_shade)
{
uint32_t ps_input_cntl;
if (offset <= EXP_PARAM_OFFSET_31)
ps_input_cntl = S_028644_OFFSET(offset);
else {
/* The input is a DEFAULT_VAL constant. */
assert(offset >= EXP_PARAM_DEFAULT_VAL_0000 &&
offset <= EXP_PARAM_DEFAULT_VAL_1111);
offset -= EXP_PARAM_DEFAULT_VAL_0000;
ps_input_cntl = S_028644_OFFSET(0x20) |
S_028644_DEFAULT_VAL(offset);
}
if (flat_shade)
ps_input_cntl |= S_028644_FLAT_SHADE(1);
return ps_input_cntl;
}
static void calculate_ps_inputs(struct radv_pipeline *pipeline) static void calculate_ps_inputs(struct radv_pipeline *pipeline)
{ {
struct radv_shader_variant *ps, *vs; struct radv_shader_variant *ps, *vs;
@@ -1882,24 +1901,20 @@ static void calculate_ps_inputs(struct radv_pipeline *pipeline)
unsigned ps_offset = 0; unsigned ps_offset = 0;
if (ps->info.fs.prim_id_input && (outinfo->prim_id_output != 0xffffffff)) { if (ps->info.fs.prim_id_input) {
unsigned vs_offset, flat_shade; unsigned vs_offset = outinfo->vs_output_param_offset[VARYING_SLOT_PRIMITIVE_ID];
unsigned val; if (vs_offset != EXP_PARAM_UNDEFINED) {
vs_offset = outinfo->prim_id_output; pipeline->graphics.ps_input_cntl[ps_offset] = offset_to_ps_input(vs_offset, true);
flat_shade = true; ++ps_offset;
val = S_028644_OFFSET(vs_offset) | S_028644_FLAT_SHADE(flat_shade); }
pipeline->graphics.ps_input_cntl[ps_offset] = val;
++ps_offset;
} }
if (ps->info.fs.layer_input && (outinfo->layer_output != 0xffffffff)) { if (ps->info.fs.layer_input) {
unsigned vs_offset, flat_shade; unsigned vs_offset = outinfo->vs_output_param_offset[VARYING_SLOT_LAYER];
unsigned val; if (vs_offset != EXP_PARAM_UNDEFINED) {
vs_offset = outinfo->layer_output; pipeline->graphics.ps_input_cntl[ps_offset] = offset_to_ps_input(vs_offset, true);
flat_shade = true; ++ps_offset;
val = S_028644_OFFSET(vs_offset) | S_028644_FLAT_SHADE(flat_shade); }
pipeline->graphics.ps_input_cntl[ps_offset] = val;
++ps_offset;
} }
if (ps->info.fs.has_pcoord) { if (ps->info.fs.has_pcoord) {
@@ -1910,31 +1925,21 @@ static void calculate_ps_inputs(struct radv_pipeline *pipeline)
} }
for (unsigned i = 0; i < 32 && (1u << i) <= ps->info.fs.input_mask; ++i) { for (unsigned i = 0; i < 32 && (1u << i) <= ps->info.fs.input_mask; ++i) {
unsigned vs_offset, flat_shade; unsigned vs_offset;
unsigned val; bool flat_shade;
if (!(ps->info.fs.input_mask & (1u << i))) if (!(ps->info.fs.input_mask & (1u << i)))
continue; continue;
if (!(outinfo->export_mask & (1u << i))) { vs_offset = outinfo->vs_output_param_offset[VARYING_SLOT_VAR0 + i];
if (vs_offset == EXP_PARAM_UNDEFINED) {
pipeline->graphics.ps_input_cntl[ps_offset] = S_028644_OFFSET(0x20); pipeline->graphics.ps_input_cntl[ps_offset] = S_028644_OFFSET(0x20);
++ps_offset; ++ps_offset;
continue; continue;
} }
vs_offset = util_bitcount(outinfo->export_mask & ((1u << i) - 1));
if (outinfo->prim_id_output != 0xffffffff) {
if (vs_offset >= outinfo->prim_id_output)
vs_offset++;
}
if (outinfo->layer_output != 0xffffffff) {
if (vs_offset >= outinfo->layer_output)
vs_offset++;
}
flat_shade = !!(ps->info.fs.flat_shaded_mask & (1u << ps_offset)); flat_shade = !!(ps->info.fs.flat_shaded_mask & (1u << ps_offset));
val = S_028644_OFFSET(vs_offset) | S_028644_FLAT_SHADE(flat_shade); pipeline->graphics.ps_input_cntl[ps_offset] = offset_to_ps_input(vs_offset, flat_shade);
pipeline->graphics.ps_input_cntl[ps_offset] = val;
++ps_offset; ++ps_offset;
} }