ac: rework load_tcs_{inputs,outputs}
authorTimothy Arceri <tarceri@itsqueeze.com>
Tue, 9 Jan 2018 02:50:08 +0000 (13:50 +1100)
committerTimothy Arceri <tarceri@itsqueeze.com>
Wed, 17 Jan 2018 13:03:33 +0000 (00:03 +1100)
This shares more code and calls the new shared load_tess_varyings()
abi so that the radeonsi nir path now supports tcs output loads.

Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
src/amd/common/ac_nir_to_llvm.c

index d94a010ca380901eb59f4c37da210bd145833333..25ce06138baa1a220fa5bc645e353be32393c0d2 100644 (file)
@@ -2841,73 +2841,45 @@ get_dw_address(struct nir_to_llvm_context *ctx,
 }
 
 static LLVMValueRef
-load_tcs_input(struct ac_shader_abi *abi,
-              LLVMValueRef vertex_index,
-              LLVMValueRef indir_index,
-              unsigned const_index,
-              unsigned location,
-              unsigned driver_location,
-              unsigned component,
-              unsigned num_components,
-              bool is_patch,
-              bool is_compact,
-              bool load_input)
+load_tcs_varyings(struct ac_shader_abi *abi,
+                 LLVMValueRef vertex_index,
+                 LLVMValueRef indir_index,
+                 unsigned const_index,
+                 unsigned location,
+                 unsigned driver_location,
+                 unsigned component,
+                 unsigned num_components,
+                 bool is_patch,
+                 bool is_compact,
+                 bool load_input)
 {
        struct nir_to_llvm_context *ctx = nir_to_llvm_context_from_abi(abi);
        LLVMValueRef dw_addr, stride;
        LLVMValueRef value[4], result;
        unsigned param = shader_io_get_unique_index(location);
 
-       stride = unpack_param(&ctx->ac, ctx->tcs_in_layout, 13, 8);
-       dw_addr = get_tcs_in_current_patch_offset(ctx);
-       dw_addr = get_dw_address(ctx, dw_addr, param, const_index, is_compact, vertex_index, stride,
-                                indir_index);
-
-       for (unsigned i = 0; i < num_components + component; i++) {
-               value[i] = ac_lds_load(&ctx->ac, dw_addr);
-               dw_addr = LLVMBuildAdd(ctx->builder, dw_addr,
-                                      ctx->ac.i32_1, "");
-       }
-       result = ac_build_varying_gather_values(&ctx->ac, value, num_components, component);
-       return result;
-}
-
-static LLVMValueRef
-load_tcs_output(struct nir_to_llvm_context *ctx,
-              nir_intrinsic_instr *instr)
-{
-       LLVMValueRef dw_addr;
-       LLVMValueRef stride = NULL;
-       LLVMValueRef value[4], result;
-       LLVMValueRef vertex_index = NULL;
-       LLVMValueRef indir_index = NULL;
-       unsigned const_index = 0;
-       unsigned param;
-       const bool per_vertex = nir_is_per_vertex_io(instr->variables[0]->var, ctx->stage);
-       const bool is_compact = instr->variables[0]->var->data.compact;
-       param = shader_io_get_unique_index(instr->variables[0]->var->data.location);
-       get_deref_offset(ctx->nir, instr->variables[0],
-                        false, NULL, per_vertex ? &vertex_index : NULL,
-                        &const_index, &indir_index);
-
-       if (!instr->variables[0]->var->data.patch) {
-               stride = unpack_param(&ctx->ac, ctx->tcs_out_layout, 13, 8);
-               dw_addr = get_tcs_out_current_patch_offset(ctx);
+       if (load_input) {
+               stride = unpack_param(&ctx->ac, ctx->tcs_in_layout, 13, 8);
+               dw_addr = get_tcs_in_current_patch_offset(ctx);
        } else {
-               dw_addr = get_tcs_out_current_patch_data_offset(ctx);
+               if (!is_patch) {
+                       stride = unpack_param(&ctx->ac, ctx->tcs_out_layout, 13, 8);
+                       dw_addr = get_tcs_out_current_patch_offset(ctx);
+               } else {
+                       dw_addr = get_tcs_out_current_patch_data_offset(ctx);
+                       stride = NULL;
+               }
        }
 
        dw_addr = get_dw_address(ctx, dw_addr, param, const_index, is_compact, vertex_index, stride,
                                 indir_index);
 
-       unsigned comp = instr->variables[0]->var->data.location_frac;
-       for (unsigned i = comp; i < instr->num_components + comp; i++) {
+       for (unsigned i = 0; i < num_components + component; i++) {
                value[i] = ac_lds_load(&ctx->ac, dw_addr);
                dw_addr = LLVMBuildAdd(ctx->builder, dw_addr,
                                       ctx->ac.i32_1, "");
        }
-       result = ac_build_varying_gather_values(&ctx->ac, value, instr->num_components, comp);
-       result = LLVMBuildBitCast(ctx->builder, result, get_def_type(ctx->nir, &instr->dest.ssa), "");
+       result = ac_build_varying_gather_values(&ctx->ac, value, num_components, component);
        return result;
 }
 
@@ -3115,6 +3087,31 @@ build_gep_for_deref(struct ac_nir_context *ctx,
        return val;
 }
 
+static LLVMValueRef load_tess_varyings(struct ac_nir_context *ctx,
+                                      nir_intrinsic_instr *instr,
+                                      bool load_inputs)
+{
+       LLVMValueRef result;
+       LLVMValueRef vertex_index = NULL;
+       LLVMValueRef indir_index = NULL;
+       unsigned const_index = 0;
+       unsigned location = instr->variables[0]->var->data.location;
+       unsigned driver_location = instr->variables[0]->var->data.driver_location;
+       const bool is_patch =  instr->variables[0]->var->data.patch;
+       const bool is_compact = instr->variables[0]->var->data.compact;
+
+       get_deref_offset(ctx, instr->variables[0],
+                        false, NULL, is_patch ? NULL : &vertex_index,
+                        &const_index, &indir_index);
+
+       result = ctx->abi->load_tess_varyings(ctx->abi, vertex_index, indir_index,
+                                             const_index, location, driver_location,
+                                             instr->variables[0]->var->data.location_frac,
+                                             instr->num_components,
+                                             is_patch, is_compact, load_inputs);
+       return LLVMBuildBitCast(ctx->ac.builder, result, get_def_type(ctx, &instr->dest.ssa), "");
+}
+
 static LLVMValueRef visit_load_var(struct ac_nir_context *ctx,
                                   nir_intrinsic_instr *instr)
 {
@@ -3138,25 +3135,7 @@ static LLVMValueRef visit_load_var(struct ac_nir_context *ctx,
        case nir_var_shader_in:
                if (ctx->stage == MESA_SHADER_TESS_CTRL ||
                    ctx->stage == MESA_SHADER_TESS_EVAL) {
-                       LLVMValueRef result;
-                       LLVMValueRef vertex_index = NULL;
-                       LLVMValueRef indir_index = NULL;
-                       unsigned const_index = 0;
-                       unsigned location = instr->variables[0]->var->data.location;
-                       unsigned driver_location = instr->variables[0]->var->data.driver_location;
-                       const bool is_patch =  instr->variables[0]->var->data.patch;
-                       const bool is_compact = instr->variables[0]->var->data.compact;
-
-                       get_deref_offset(ctx, instr->variables[0],
-                                        false, NULL, is_patch ? NULL : &vertex_index,
-                                        &const_index, &indir_index);
-
-                       result = ctx->abi->load_tess_varyings(ctx->abi, vertex_index, indir_index,
-                                                             const_index, location, driver_location,
-                                                             instr->variables[0]->var->data.location_frac,
-                                                             instr->num_components,
-                                                             is_patch, is_compact, true);
-                       return LLVMBuildBitCast(ctx->ac.builder, result, get_def_type(ctx, &instr->dest.ssa), "");
+                       return load_tess_varyings(ctx, instr, true);
                }
 
                if (ctx->stage == MESA_SHADER_GEOMETRY) {
@@ -3216,8 +3195,9 @@ static LLVMValueRef visit_load_var(struct ac_nir_context *ctx,
                                        "");
        }
        case nir_var_shader_out:
-               if (ctx->stage == MESA_SHADER_TESS_CTRL)
-                       return load_tcs_output(ctx->nctx, instr);
+               if (ctx->stage == MESA_SHADER_TESS_CTRL) {
+                       return load_tess_varyings(ctx, instr, false);
+               }
 
                for (unsigned chan = comp; chan < ve + comp; chan++) {
                        if (indir_index) {
@@ -6744,7 +6724,7 @@ LLVMModuleRef ac_translate_nir_to_llvm(LLVMTargetMachineRef tm,
                } else if (shaders[i]->info.stage == MESA_SHADER_TESS_CTRL) {
                        ctx.tcs_outputs_read = shaders[i]->info.outputs_read;
                        ctx.tcs_patch_outputs_read = shaders[i]->info.patch_outputs_read;
-                       ctx.abi.load_tess_varyings = load_tcs_input;
+                       ctx.abi.load_tess_varyings = load_tcs_varyings;
                        ctx.abi.load_patch_vertices_in = load_patch_vertices_in;
                        ctx.abi.store_tcs_outputs = store_tcs_output;
                } else if (shaders[i]->info.stage == MESA_SHADER_TESS_EVAL) {