aco: Fix handling of tess factors.
authorTimur Kristóf <timur.kristof@gmail.com>
Thu, 26 Mar 2020 17:36:07 +0000 (18:36 +0100)
committerMarge Bot <eric+marge@anholt.net>
Mon, 30 Mar 2020 13:09:08 +0000 (13:09 +0000)
There is no need to check whether they are written using indirect
indices, because all tess factors should be written to VMEM only
at the end of the shader.

No pipeline db changes.

Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
Reviewed-by: Rhys Perry <pendingchaos02@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4165>

src/amd/compiler/aco_instruction_selection.cpp
src/amd/compiler/aco_instruction_selection_setup.cpp

index a0455236e4e580cf3491c4a74c9bf812025b35f3..e03dbcee9fd9161ed0f941bf18c4fa6a27f6364b 100644 (file)
@@ -3341,19 +3341,8 @@ void visit_store_ls_or_es_output(isel_context *ctx, nir_intrinsic_instr *instr)
 bool should_write_tcs_patch_output_to_vmem(isel_context *ctx, nir_intrinsic_instr *instr)
 {
    unsigned off = nir_intrinsic_base(instr) * 4u;
-   nir_src *off_src = nir_get_io_offset_src(instr);
-
-   /* Indirect offset, we can't be sure if this is a tess factor, always write to VMEM */
-   if (!nir_src_is_const(*off_src))
-      return true;
-
-   off += nir_src_as_uint(*off_src) * 16u;
-
-   const unsigned tess_index_inner = shader_io_get_unique_index(VARYING_SLOT_TESS_LEVEL_INNER);
-   const unsigned tess_index_outer = shader_io_get_unique_index(VARYING_SLOT_TESS_LEVEL_OUTER);
-
-   return (off != (tess_index_inner * 16u)) &&
-          (off != (tess_index_outer * 16u));
+   return off != ctx->tcs_tess_lvl_out_loc &&
+          off != ctx->tcs_tess_lvl_in_loc;
 }
 
 bool should_write_tcs_output_to_lds(isel_context *ctx, nir_intrinsic_instr *instr, bool per_vertex)
@@ -9374,9 +9363,6 @@ static void write_tcs_tess_factors(isel_context *ctx)
       return;
    }
 
-   const unsigned tess_index_inner = shader_io_get_unique_index(VARYING_SLOT_TESS_LEVEL_INNER);
-   const unsigned tess_index_outer = shader_io_get_unique_index(VARYING_SLOT_TESS_LEVEL_OUTER);
-
    Builder bld(ctx->program, ctx->block);
 
    bld.barrier(aco_opcode::p_memory_barrier_shared);
@@ -9405,14 +9391,14 @@ static void write_tcs_tess_factors(isel_context *ctx)
 
    if (ctx->args->options->key.tcs.primitive_mode == GL_ISOLINES) {
       // LINES reversal
-      outer[0] = out[1] = load_lds(ctx, 4, bld.tmp(v1), lds_base.first, lds_base.second + tess_index_outer * 16 + 0 * 4, 4);
-      outer[1] = out[0] = load_lds(ctx, 4, bld.tmp(v1), lds_base.first, lds_base.second + tess_index_outer * 16 + 1 * 4, 4);
+      outer[0] = out[1] = load_lds(ctx, 4, bld.tmp(v1), lds_base.first, lds_base.second + ctx->tcs_tess_lvl_out_loc + 0 * 4, 4);
+      outer[1] = out[0] = load_lds(ctx, 4, bld.tmp(v1), lds_base.first, lds_base.second + ctx->tcs_tess_lvl_out_loc + 1 * 4, 4);
    } else {
       for (unsigned i = 0; i < outer_comps; ++i)
-         outer[i] = out[i] = load_lds(ctx, 4, bld.tmp(v1), lds_base.first, lds_base.second + tess_index_outer * 16 + i * 4, 4);
+         outer[i] = out[i] = load_lds(ctx, 4, bld.tmp(v1), lds_base.first, lds_base.second + ctx->tcs_tess_lvl_out_loc + i * 4, 4);
 
       for (unsigned i = 0; i < inner_comps; ++i)
-         inner[i] = out[outer_comps + i] = load_lds(ctx, 4, bld.tmp(v1), lds_base.first, lds_base.second + tess_index_inner * 16 + i * 4, 4);
+         inner[i] = out[outer_comps + i] = load_lds(ctx, 4, bld.tmp(v1), lds_base.first, lds_base.second + ctx->tcs_tess_lvl_in_loc + i * 4, 4);
    }
 
    Temp rel_patch_id = get_tess_rel_patch_id(ctx);
@@ -9448,12 +9434,12 @@ static void write_tcs_tess_factors(isel_context *ctx)
       Temp hs_ring_tess_offchip = bld.smem(aco_opcode::s_load_dwordx4, bld.def(s4), ctx->program->private_segment_buffer, Operand(RING_HS_TESS_OFFCHIP * 16u));
       Temp oc_lds = get_arg(ctx, ctx->args->oc_lds);
 
-      std::pair<Temp, unsigned> vmem_offs_outer = get_tcs_per_patch_output_vmem_offset(ctx, nullptr, tess_index_outer * 16);
+      std::pair<Temp, unsigned> vmem_offs_outer = get_tcs_per_patch_output_vmem_offset(ctx, nullptr, ctx->tcs_tess_lvl_out_loc);
       Temp outer_vec = create_vec_from_array(ctx, outer, outer_comps, RegType::vgpr);
       store_vmem_mubuf(ctx, outer_vec, hs_ring_tess_offchip, vmem_offs_outer.first, oc_lds, vmem_offs_outer.second, 4, (1 << outer_comps) - 1, true, false);
 
       if (likely(inner_comps)) {
-         std::pair<Temp, unsigned> vmem_offs_inner = get_tcs_per_patch_output_vmem_offset(ctx, nullptr, tess_index_inner * 16);
+         std::pair<Temp, unsigned> vmem_offs_inner = get_tcs_per_patch_output_vmem_offset(ctx, nullptr, ctx->tcs_tess_lvl_in_loc);
          Temp inner_vec = create_vec_from_array(ctx, inner, inner_comps, RegType::vgpr);
          store_vmem_mubuf(ctx, inner_vec, hs_ring_tess_offchip, vmem_offs_inner.first, oc_lds, vmem_offs_inner.second, 4, (1 << inner_comps) - 1, true, false);
       }
index 2bf9ff0e09ad262d8a93f7d96d257bc2103d3d82..ff32aa3dc84d0bc7da1258a7d413cfdca85da61e 100644 (file)
@@ -96,6 +96,8 @@ struct isel_context {
    unsigned num_cull_distances;
 
    /* tessellation information */
+   unsigned tcs_tess_lvl_out_loc;
+   unsigned tcs_tess_lvl_in_loc;
    uint32_t tcs_num_inputs;
    uint32_t tcs_num_patches;
 
@@ -926,6 +928,9 @@ setup_tcs_variables(isel_context *ctx, nir_shader *nir)
    nir_foreach_variable(variable, &nir->outputs) {
       variable->data.driver_location = shader_io_get_unique_index((gl_varying_slot) variable->data.location) * 4;
    }
+
+   ctx->tcs_tess_lvl_out_loc = shader_io_get_unique_index(VARYING_SLOT_TESS_LEVEL_OUTER) * 16u;
+   ctx->tcs_tess_lvl_in_loc = shader_io_get_unique_index(VARYING_SLOT_TESS_LEVEL_INNER) * 16u;
 }
 
 void