From c16a0e11d394a9ad9b5d9b698130e15e1a84bf1c Mon Sep 17 00:00:00 2001 From: Timothy Arceri Date: Fri, 17 Nov 2017 17:04:22 +1100 Subject: [PATCH] radeonsi/nir: add support for packed inputs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Because NIR can create non vec4 variables when implementing component packing we need to make sure not to reprocess the same slot again. Also we can drop the fs_attr_idx counter and just use driver_location. Reviewed-by: Nicolai Hähnle --- src/gallium/drivers/radeonsi/si_shader_nir.c | 46 +++++++++++--------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/src/gallium/drivers/radeonsi/si_shader_nir.c b/src/gallium/drivers/radeonsi/si_shader_nir.c index 5d82715f7a7..12eb8763edb 100644 --- a/src/gallium/drivers/radeonsi/si_shader_nir.c +++ b/src/gallium/drivers/radeonsi/si_shader_nir.c @@ -444,21 +444,18 @@ si_lower_nir(struct si_shader_selector* sel) } static void declare_nir_input_vs(struct si_shader_context *ctx, - struct nir_variable *variable, unsigned rel, + struct nir_variable *variable, LLVMValueRef out[4]) { - si_llvm_load_input_vs(ctx, variable->data.driver_location / 4 + rel, out); + si_llvm_load_input_vs(ctx, variable->data.driver_location / 4, out); } static void declare_nir_input_fs(struct si_shader_context *ctx, - struct nir_variable *variable, unsigned rel, - unsigned *fs_attr_idx, + struct nir_variable *variable, + unsigned input_index, LLVMValueRef out[4]) { - unsigned slot = variable->data.location + rel; - - assert(variable->data.location >= VARYING_SLOT_VAR0 || rel == 0); - + unsigned slot = variable->data.location; if (slot == VARYING_SLOT_POS) { out[0] = LLVMGetParam(ctx->main_fn, SI_PARAM_POS_X_FLOAT); out[1] = LLVMGetParam(ctx->main_fn, SI_PARAM_POS_Y_FLOAT); @@ -468,8 +465,7 @@ static void declare_nir_input_fs(struct si_shader_context *ctx, return; } - si_llvm_load_input_fs(ctx, *fs_attr_idx, out); - (*fs_attr_idx)++; + si_llvm_load_input_fs(ctx, input_index, out); } static LLVMValueRef @@ -523,25 +519,33 @@ bool si_nir_build_llvm(struct si_shader_context *ctx, struct nir_shader *nir) { struct tgsi_shader_info *info = &ctx->shader->selector->info; - unsigned fs_attr_idx = 0; + uint64_t processed_inputs = 0; nir_foreach_variable(variable, &nir->inputs) { unsigned attrib_count = glsl_count_attribute_slots(variable->type, nir->info.stage == MESA_SHADER_VERTEX); unsigned input_idx = variable->data.driver_location; - for (unsigned i = 0; i < attrib_count; ++i) { - LLVMValueRef data[4]; + assert(attrib_count == 1); - if (nir->info.stage == MESA_SHADER_VERTEX) - declare_nir_input_vs(ctx, variable, i, data); - else if (nir->info.stage == MESA_SHADER_FRAGMENT) - declare_nir_input_fs(ctx, variable, i, &fs_attr_idx, data); + LLVMValueRef data[4]; + unsigned loc = variable->data.location; - for (unsigned chan = 0; chan < 4; chan++) { - ctx->inputs[input_idx + chan] = - LLVMBuildBitCast(ctx->ac.builder, data[chan], ctx->ac.i32, ""); - } + /* 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, data); + else if (nir->info.stage == MESA_SHADER_FRAGMENT) + declare_nir_input_fs(ctx, variable, input_idx / 4, data); + + for (unsigned chan = 0; chan < 4; chan++) { + ctx->inputs[input_idx + chan] = + LLVMBuildBitCast(ctx->ac.builder, data[chan], ctx->ac.i32, ""); } + processed_inputs |= ((uint64_t)1 << loc); } ctx->abi.inputs = &ctx->inputs[0];