diff options
author | Nicolai Hähnle <nicolai.haehnle@amd.com> | 2017-05-19 18:48:13 +0200 |
---|---|---|
committer | Nicolai Hähnle <nicolai.haehnle@amd.com> | 2017-07-05 12:33:49 +0200 |
commit | 02ab9e2860438ccbcf88d3fbc38252bac1216862 (patch) | |
tree | f68278f84cb8503ad0244c767c7457283b927e84 | |
parent | f3d3e1f33f46acfa39c05b063e0bc429269a9661 (diff) |
ac/nir: split scanning outputs from setting up output allocas
The scanning phase sets the driver_location, because it is part of the
ABI: radeonsi does the assignment differently.
-rw-r--r-- | src/amd/common/ac_nir_to_llvm.c | 51 |
1 files changed, 43 insertions, 8 deletions
diff --git a/src/amd/common/ac_nir_to_llvm.c b/src/amd/common/ac_nir_to_llvm.c index d82e6824e5..5f7a938814 100644 --- a/src/amd/common/ac_nir_to_llvm.c +++ b/src/amd/common/ac_nir_to_llvm.c @@ -4982,12 +4982,13 @@ static LLVMValueRef si_build_alloca_undef(struct ac_llvm_context *ac, } static void -handle_shader_output_decl(struct nir_to_llvm_context *ctx, - struct nir_variable *variable) +scan_shader_output_decl(struct nir_to_llvm_context *ctx, + struct nir_variable *variable) { int idx = variable->data.location + variable->data.index; unsigned attrib_count = glsl_count_attribute_slots(variable->type, false); uint64_t mask_attribs; + variable->data.driver_location = idx * 4; /* tess ctrl has it's own load/store paths for outputs */ @@ -5017,13 +5018,42 @@ handle_shader_output_decl(struct nir_to_llvm_context *ctx, } } + ctx->output_mask |= mask_attribs; +} + +static void +handle_shader_output_decl(struct ac_nir_context *ctx, + struct nir_shader *nir, + struct nir_variable *variable) +{ + unsigned output_loc = variable->data.driver_location / 4; + unsigned attrib_count = glsl_count_attribute_slots(variable->type, false); + + /* tess ctrl has it's own load/store paths for outputs */ + if (ctx->stage == MESA_SHADER_TESS_CTRL) + return; + + if (ctx->stage == MESA_SHADER_VERTEX || + ctx->stage == MESA_SHADER_TESS_EVAL || + ctx->stage == MESA_SHADER_GEOMETRY) { + int idx = variable->data.location + variable->data.index; + if (idx == VARYING_SLOT_CLIP_DIST0) { + int length = nir->info.clip_distance_array_size + + nir->info.cull_distance_array_size; + + if (length > 4) + attrib_count = 2; + else + attrib_count = 1; + } + } + for (unsigned i = 0; i < attrib_count; ++i) { for (unsigned chan = 0; chan < 4; chan++) { - ctx->nir->outputs[radeon_llvm_reg_index_soa(idx + i, chan)] = - si_build_alloca_undef(&ctx->ac, ctx->f32, ""); + ctx->outputs[radeon_llvm_reg_index_soa(output_loc + i, chan)] = + si_build_alloca_undef(&ctx->ac, ctx->ac.f32, ""); } } - ctx->output_mask |= mask_attribs; } static void @@ -5981,7 +6011,7 @@ void ac_nir_translate(struct ac_llvm_context *ac, struct ac_shader_abi *abi, ctx.stage = nir->stage; nir_foreach_variable(variable, &nir->outputs) - handle_shader_output_decl(nctx, variable); + handle_shader_output_decl(&ctx, nir, variable); ctx.defs = _mesa_hash_table_create(NULL, _mesa_hash_pointer, _mesa_key_pointer_equal); @@ -6094,6 +6124,9 @@ LLVMModuleRef ac_translate_nir_to_llvm(LLVMTargetMachineRef tm, ctx.abi.inputs = &ctx.inputs[0]; ctx.abi.emit_outputs = handle_shader_outputs_post; + nir_foreach_variable(variable, &nir->outputs) + scan_shader_output_decl(&ctx, variable); + ac_nir_translate(&ctx.ac, &ctx.abi, nir, &ctx); LLVMBuildRetVoid(ctx.builder); @@ -6381,8 +6414,10 @@ void ac_create_gs_copy_shader(LLVMTargetMachineRef tm, nir_ctx.nctx = &ctx; ctx.nir = &nir_ctx; - nir_foreach_variable(variable, &geom_shader->outputs) - handle_shader_output_decl(&ctx, variable); + nir_foreach_variable(variable, &geom_shader->outputs) { + scan_shader_output_decl(&ctx, variable); + handle_shader_output_decl(&nir_ctx, geom_shader, variable); + } ac_gs_copy_shader_emit(&ctx); |