diff options
author | Dave Airlie <[email protected]> | 2017-04-21 03:17:23 +0100 |
---|---|---|
committer | Dave Airlie <[email protected]> | 2017-04-25 23:24:39 +0100 |
commit | b2cedb3ea9482d3099506069204a2d226ccd54fc (patch) | |
tree | a45aea68146b8fee4706d38c67fb44a2bec76afd | |
parent | b858cb4df8f7be9baa33d7e20347d2fe77822872 (diff) |
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 <[email protected]>
Signed-off-by: Dave Airlie <[email protected]>
-rw-r--r-- | src/amd/common/ac_nir_to_llvm.c | 10 | ||||
-rw-r--r-- | src/amd/common/ac_nir_to_llvm.h | 15 | ||||
-rw-r--r-- | src/amd/vulkan/radv_pipeline.c | 67 |
3 files changed, 55 insertions, 37 deletions
diff --git a/src/amd/common/ac_nir_to_llvm.c b/src/amd/common/ac_nir_to_llvm.c index 514c9e9ca35..ab929bc81fe 100644 --- a/src/amd/common/ac_nir_to_llvm.c +++ b/src/amd/common/ac_nir_to_llvm.c @@ -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; int i; - outinfo->prim_id_output = 0xffffffff; - outinfo->layer_output = 0xffffffff; + memset(outinfo->vs_output_param_offset, EXP_PARAM_UNDEFINED, + sizeof(outinfo->vs_output_param_offset)); + if (ctx->output_mask & (1ull << VARYING_SLOT_CLIP_DIST0)) { LLVMValueRef slots[8]; unsigned j; @@ -5184,20 +5185,21 @@ handle_vs_outputs_post(struct nir_to_llvm_context *ctx, } else if (i == VARYING_SLOT_LAYER) { outinfo->writes_layer = true; layer_value = values[0]; - outinfo->layer_output = param_count; target = V_008DFC_SQ_EXP_PARAM + param_count; + outinfo->vs_output_param_offset[VARYING_SLOT_LAYER] = param_count; param_count++; } else if (i == VARYING_SLOT_VIEWPORT) { outinfo->writes_viewport_index = true; viewport_index_value = values[0]; continue; } else if (i == VARYING_SLOT_PRIMITIVE_ID) { - outinfo->prim_id_output = param_count; target = V_008DFC_SQ_EXP_PARAM + param_count; + outinfo->vs_output_param_offset[VARYING_SLOT_PRIMITIVE_ID] = param_count; param_count++; } else if (i >= VARYING_SLOT_VAR0) { outinfo->export_mask |= 1u << (i - VARYING_SLOT_VAR0); target = V_008DFC_SQ_EXP_PARAM + param_count; + outinfo->vs_output_param_offset[i] = param_count; param_count++; } diff --git a/src/amd/common/ac_nir_to_llvm.h b/src/amd/common/ac_nir_to_llvm.h index 401d284a7c4..f77a9b8d2bb 100644 --- a/src/amd/common/ac_nir_to_llvm.h +++ b/src/amd/common/ac_nir_to_llvm.h @@ -120,14 +120,25 @@ struct ac_userdata_locations { 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 { + uint8_t vs_output_param_offset[VARYING_SLOT_MAX]; uint8_t clip_dist_mask; uint8_t cull_dist_mask; bool writes_pointsize; bool writes_layer; bool writes_viewport_index; - uint32_t prim_id_output; - uint32_t layer_output; uint32_t export_mask; unsigned param_exports; unsigned pos_exports; diff --git a/src/amd/vulkan/radv_pipeline.c b/src/amd/vulkan/radv_pipeline.c index aada4d2f30d..d6989137a55 100644 --- a/src/amd/vulkan/radv_pipeline.c +++ b/src/amd/vulkan/radv_pipeline.c @@ -1870,6 +1870,25 @@ static void calculate_pa_cl_vs_out_cntl(struct radv_pipeline *pipeline) 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) { struct radv_shader_variant *ps, *vs; @@ -1882,24 +1901,20 @@ static void calculate_ps_inputs(struct radv_pipeline *pipeline) unsigned ps_offset = 0; - if (ps->info.fs.prim_id_input && (outinfo->prim_id_output != 0xffffffff)) { - unsigned vs_offset, flat_shade; - unsigned val; - vs_offset = outinfo->prim_id_output; - flat_shade = true; - 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.prim_id_input) { + unsigned vs_offset = outinfo->vs_output_param_offset[VARYING_SLOT_PRIMITIVE_ID]; + if (vs_offset != EXP_PARAM_UNDEFINED) { + pipeline->graphics.ps_input_cntl[ps_offset] = offset_to_ps_input(vs_offset, true); + ++ps_offset; + } } - if (ps->info.fs.layer_input && (outinfo->layer_output != 0xffffffff)) { - unsigned vs_offset, flat_shade; - unsigned val; - vs_offset = outinfo->layer_output; - flat_shade = true; - 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) { + unsigned vs_offset = outinfo->vs_output_param_offset[VARYING_SLOT_LAYER]; + if (vs_offset != EXP_PARAM_UNDEFINED) { + pipeline->graphics.ps_input_cntl[ps_offset] = offset_to_ps_input(vs_offset, true); + ++ps_offset; + } } 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) { - unsigned vs_offset, flat_shade; - unsigned val; - + unsigned vs_offset; + bool flat_shade; if (!(ps->info.fs.input_mask & (1u << i))) 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); ++ps_offset; 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)); - val = S_028644_OFFSET(vs_offset) | S_028644_FLAT_SHADE(flat_shade); - pipeline->graphics.ps_input_cntl[ps_offset] = val; + pipeline->graphics.ps_input_cntl[ps_offset] = offset_to_ps_input(vs_offset, flat_shade); ++ps_offset; } |