[Mesa-dev] [PATCH 47/92] ac/nir: split scanning outputs from setting up output allocas
Nicolai Hähnle
nhaehnle at gmail.com
Mon Jun 26 14:10:26 UTC 2017
From: Nicolai Hähnle <nicolai.haehnle at amd.com>
The scanning phase sets the driver_location, because it is part of the
ABI: radeonsi does the assignment differently.
---
src/amd/common/ac_nir_to_llvm.c | 51 ++++++++++++++++++++++++++++++++++-------
1 file 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 2aa1903..9c17fd9 100644
--- a/src/amd/common/ac_nir_to_llvm.c
+++ b/src/amd/common/ac_nir_to_llvm.c
@@ -4902,26 +4902,27 @@ ac_build_alloca(struct ac_llvm_context *ac,
static LLVMValueRef si_build_alloca_undef(struct ac_llvm_context *ac,
LLVMTypeRef type,
const char *name)
{
LLVMValueRef ptr = ac_build_alloca(ac, type, name);
LLVMBuildStore(ac->builder, LLVMGetUndef(type), ptr);
return ptr;
}
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 */
if (ctx->stage == MESA_SHADER_TESS_CTRL)
return;
mask_attribs = ((1ull << attrib_count) - 1) << idx;
if (ctx->stage == MESA_SHADER_VERTEX ||
ctx->stage == MESA_SHADER_TESS_EVAL ||
ctx->stage == MESA_SHADER_GEOMETRY) {
@@ -4937,27 +4938,56 @@ handle_shader_output_decl(struct nir_to_llvm_context *ctx,
}
if (length > 4)
attrib_count = 2;
else
attrib_count = 1;
mask_attribs = 1ull << idx;
}
}
+ 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
setup_locals(struct ac_nir_context *ctx,
struct nir_function *func)
{
int i, j;
ctx->num_locals = 0;
nir_foreach_variable(variable, &func->impl->locals) {
unsigned attrib_count = glsl_count_attribute_slots(variable->type, false);
@@ -5883,21 +5913,21 @@ void ac_nir_translate(struct ac_llvm_context *ac, struct ac_shader_abi *abi,
ctx.ac = *ac;
ctx.abi = abi;
ctx.nctx = nctx;
if (nctx)
nctx->nir = &ctx;
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);
ctx.phis = _mesa_hash_table_create(NULL, _mesa_hash_pointer,
_mesa_key_pointer_equal);
func = (struct nir_function *)exec_list_get_head(&nir->functions);
setup_locals(&ctx, func);
@@ -5996,20 +6026,23 @@ LLVMModuleRef ac_translate_nir_to_llvm(LLVMTargetMachineRef tm,
nir_foreach_variable(variable, &nir->inputs)
handle_shader_input_decl(&ctx, variable);
if (nir->stage == MESA_SHADER_FRAGMENT)
handle_fs_inputs_pre(&ctx, nir);
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);
ac_llvm_finalize_module(&ctx);
ac_nir_eliminate_const_vs_outputs(&ctx);
if (nir->stage == MESA_SHADER_GEOMETRY) {
unsigned addclip = ctx.num_output_clips + ctx.num_output_culls > 4;
@@ -6285,22 +6318,24 @@ void ac_create_gs_copy_shader(LLVMTargetMachineRef tm,
ctx.num_output_clips = geom_shader->info.clip_distance_array_size;
ctx.num_output_culls = geom_shader->info.cull_distance_array_size;
struct ac_nir_context nir_ctx = {};
nir_ctx.ac = ctx.ac;
nir_ctx.abi = &ctx.abi;
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);
ctx.nir = NULL;
LLVMBuildRetVoid(ctx.builder);
ac_llvm_finalize_module(&ctx);
ac_compile_llvm_module(tm, ctx.module, binary, config, shader_info,
--
2.9.3
More information about the mesa-dev
mailing list