[Mesa-dev] [PATCH 12/14] radeonsi/nir: add support for packed inputs
Nicolai Hähnle
nhaehnle at gmail.com
Wed Nov 29 11:53:23 UTC 2017
On 21.11.2017 04:37, Timothy Arceri wrote:
> 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.
> ---
> 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 5d82715f7a..ec748c9679 100644
> --- a/src/gallium/drivers/radeonsi/si_shader_nir.c
> +++ b/src/gallium/drivers/radeonsi/si_shader_nir.c
> @@ -437,46 +437,42 @@ si_lower_nir(struct si_shader_selector* sel)
>
> NIR_PASS(progress, sel->nir, nir_opt_undef);
> NIR_PASS(progress, sel->nir, nir_opt_conditional_discard);
> if (sel->nir->options->max_unroll_iterations) {
> NIR_PASS(progress, sel->nir, nir_opt_loop_unroll, 0);
> }
> } while (progress);
> }
>
> 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);
> out[2] = LLVMGetParam(ctx->main_fn, SI_PARAM_POS_Z_FLOAT);
> out[3] = ac_build_fdiv(&ctx->ac, ctx->ac.f32_1,
> LLVMGetParam(ctx->main_fn, SI_PARAM_POS_W_FLOAT));
> 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
> si_nir_load_sampler_desc(struct ac_shader_abi *abi,
> unsigned descriptor_set, unsigned base_index,
> unsigned constant_index, LLVMValueRef dynamic_index,
> enum ac_descriptor_type desc_type, bool image,
> bool write)
> {
> struct si_shader_context *ctx = si_shader_context_from_abi(abi);
> @@ -516,39 +512,47 @@ si_nir_load_sampler_desc(struct ac_shader_abi *abi,
> index = LLVMBuildAdd(ctx->gallivm.builder, index,
> LLVMConstInt(ctx->i32, SI_NUM_IMAGES / 2, 0), "");
>
> return si_load_sampler_desc(ctx, list, index, desc_type);
> }
>
> 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_outputs = 0;
s/processed_outputs/processed_inputs/
Cheers,
Nicolai
> 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_outputs & ((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_outputs |= ((uint64_t)1 << loc);
> }
>
> ctx->abi.inputs = &ctx->inputs[0];
> ctx->abi.load_sampler_desc = si_nir_load_sampler_desc;
> ctx->abi.clamp_shadow_reference = true;
>
> ctx->num_samplers = util_last_bit(info->samplers_declared);
> ctx->num_images = util_last_bit(info->images_declared);
>
> ac_nir_translate(&ctx->ac, &ctx->abi, nir, NULL);
>
--
Lerne, wie die Welt wirklich ist,
Aber vergiss niemals, wie sie sein sollte.
More information about the mesa-dev
mailing list