diff options
-rw-r--r-- | src/amd/common/ac_nir_to_llvm.c | 81 | ||||
-rw-r--r-- | src/amd/common/ac_nir_to_llvm.h | 7 |
2 files changed, 88 insertions, 0 deletions
diff --git a/src/amd/common/ac_nir_to_llvm.c b/src/amd/common/ac_nir_to_llvm.c index 3e1b21862c9..6e97ae3322a 100644 --- a/src/amd/common/ac_nir_to_llvm.c +++ b/src/amd/common/ac_nir_to_llvm.c @@ -4803,3 +4803,84 @@ void ac_compile_nir_shader(LLVMTargetMachineRef tm, break; } } + +static void +ac_gs_copy_shader_emit(struct nir_to_llvm_context *ctx) +{ + LLVMValueRef args[9]; + args[0] = ctx->gsvs_ring; + args[1] = LLVMBuildMul(ctx->builder, ctx->vertex_id, LLVMConstInt(ctx->i32, 4, false), ""); + args[3] = ctx->i32zero; + args[4] = ctx->i32one; /* OFFEN */ + args[5] = ctx->i32zero; /* IDXEN */ + args[6] = ctx->i32one; /* GLC */ + args[7] = ctx->i32one; /* SLC */ + args[8] = ctx->i32zero; /* TFE */ + + int idx = 0; + for (unsigned i = 0; i < RADEON_LLVM_MAX_OUTPUTS; ++i) { + if (!(ctx->output_mask & (1ull << i))) + continue; + + for (unsigned j = 0; j < 4; j++) { + LLVMValueRef value; + args[2] = LLVMConstInt(ctx->i32, + (idx * 4 + j) * + ctx->gs_max_out_vertices * 16 * 4, false); + + value = ac_emit_llvm_intrinsic(&ctx->ac, + "llvm.SI.buffer.load.dword.i32.i32", + ctx->i32, args, 9, + AC_FUNC_ATTR_READONLY); + + LLVMBuildStore(ctx->builder, + to_float(ctx, value), ctx->outputs[radeon_llvm_reg_index_soa(i, j)]); + } + idx++; + } + handle_vs_outputs_post(ctx); +} + +void ac_create_gs_copy_shader(LLVMTargetMachineRef tm, + struct nir_shader *geom_shader, + struct ac_shader_binary *binary, + struct ac_shader_config *config, + struct ac_shader_variant_info *shader_info, + const struct ac_nir_compiler_options *options, + bool dump_shader) +{ + struct nir_to_llvm_context ctx = {0}; + ctx.context = LLVMContextCreate(); + ctx.module = LLVMModuleCreateWithNameInContext("shader", ctx.context); + ctx.options = options; + ctx.shader_info = shader_info; + + ac_llvm_context_init(&ctx.ac, ctx.context); + ctx.ac.module = ctx.module; + + ctx.is_gs_copy_shader = true; + LLVMSetTarget(ctx.module, "amdgcn--"); + setup_types(&ctx); + + ctx.builder = LLVMCreateBuilderInContext(ctx.context); + ctx.ac.builder = ctx.builder; + ctx.stage = MESA_SHADER_VERTEX; + + create_function(&ctx); + + ctx.gs_max_out_vertices = geom_shader->info->gs.vertices_out; + ac_setup_rings(&ctx); + + nir_foreach_variable(variable, &geom_shader->outputs) + handle_shader_output_decl(&ctx, variable); + + ac_gs_copy_shader_emit(&ctx); + + LLVMBuildRetVoid(ctx.builder); + + ac_llvm_finalize_module(&ctx); + + ac_compile_llvm_module(tm, ctx.module, binary, config, shader_info, + MESA_SHADER_VERTEX, + dump_shader, options->supports_spill); +} diff --git a/src/amd/common/ac_nir_to_llvm.h b/src/amd/common/ac_nir_to_llvm.h index 589a9a9e08e..82c75bf6963 100644 --- a/src/amd/common/ac_nir_to_llvm.h +++ b/src/amd/common/ac_nir_to_llvm.h @@ -141,4 +141,11 @@ void ac_compile_nir_shader(LLVMTargetMachineRef tm, const struct ac_nir_compiler_options *options, bool dump_shader); +void ac_create_gs_copy_shader(LLVMTargetMachineRef tm, + struct nir_shader *geom_shader, + struct ac_shader_binary *binary, + struct ac_shader_config *config, + struct ac_shader_variant_info *shader_info, + const struct ac_nir_compiler_options *options, + bool dump_shader); |