diff options
author | Nicolai Hähnle <[email protected]> | 2017-05-19 18:48:13 +0200 |
---|---|---|
committer | Nicolai Hähnle <[email protected]> | 2017-07-31 14:55:34 +0200 |
commit | 2be774b19609f31ead5f63ee235e82853a957f9e (patch) | |
tree | b8f1b8a7eccb43e3e56b5b0d728c1fe5eceaff3f | |
parent | 1a508cf8d637532a16c428520c8644b7ab5712fa (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.
Reviewed-by: Marek Olšák <[email protected]>
-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 5cf4c03a19e..e2dd7cabc6f 100644 --- a/src/amd/common/ac_nir_to_llvm.c +++ b/src/amd/common/ac_nir_to_llvm.c @@ -5007,12 +5007,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 */ @@ -5042,13 +5043,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 LLVMTypeRef @@ -6073,7 +6103,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); @@ -6170,6 +6200,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); @@ -6457,8 +6490,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); |