[Mesa-dev] [PATCH v3 17/19] RFC nir/lower_io: lower kernel entry param load_vars to load_kernel_param

Karol Herbst kherbst at redhat.com
Fri Mar 23 19:33:54 UTC 2018


For OpenCL kernels we have an input buffer where most of the parameters are
stored. For this we have to keep track of alignment and padding rules to
correctly identify the offset of each parameter inside that buffer.

For this we can just rely on the new cl_size and cl_alignment glsl_type
functions.

Signed-off-by: Karol Herbst <kherbst at redhat.com>
---
 src/compiler/nir/nir_lower_io.c | 39 ++++++++++++++++++++++++++++++++++++---
 1 file changed, 36 insertions(+), 3 deletions(-)

diff --git a/src/compiler/nir/nir_lower_io.c b/src/compiler/nir/nir_lower_io.c
index df91febd68d..ed8e361651c 100644
--- a/src/compiler/nir/nir_lower_io.c
+++ b/src/compiler/nir/nir_lower_io.c
@@ -39,6 +39,7 @@ struct lower_io_state {
    int (*type_size)(const struct glsl_type *type);
    nir_variable_mode modes;
    nir_lower_io_options options;
+   unsigned *offsets;
 };
 
 void
@@ -159,7 +160,8 @@ lower_load(nir_intrinsic_instr *intrin, struct lower_io_state *state,
            nir_ssa_def *vertex_index, nir_ssa_def *offset,
            unsigned component)
 {
-   const nir_shader *nir = state->builder.shader;
+   nir_builder *b = &state->builder;
+   nir_shader *nir = b->shader;
    nir_variable *var = intrin->variables[0]->var;
    nir_variable_mode mode = var->data.mode;
    nir_ssa_def *barycentric = NULL;
@@ -199,6 +201,11 @@ lower_load(nir_intrinsic_instr *intrin, struct lower_io_state *state,
    case nir_var_shared:
       op = nir_intrinsic_load_shared;
       break;
+   case nir_var_param:
+      if (nir_cf_node_get_function(&intrin->instr.block->cf_node) == nir_shader_get_entrypoint(nir)) {
+         op = nir_intrinsic_load_kernel_param;
+         break;
+      }
    default:
       unreachable("Unknown variable mode");
    }
@@ -207,7 +214,9 @@ lower_load(nir_intrinsic_instr *intrin, struct lower_io_state *state,
       nir_intrinsic_instr_create(state->builder.shader, op);
    load->num_components = intrin->num_components;
 
-   nir_intrinsic_set_base(load, var->data.driver_location);
+   if (op != nir_intrinsic_load_kernel_param)
+      nir_intrinsic_set_base(load, var->data.driver_location);
+
    if (mode == nir_var_shader_in || mode == nir_var_shader_out)
       nir_intrinsic_set_component(load, component);
 
@@ -220,6 +229,8 @@ lower_load(nir_intrinsic_instr *intrin, struct lower_io_state *state,
    } else if (barycentric) {
       load->src[0] = nir_src_for_ssa(barycentric);
       load->src[1] = nir_src_for_ssa(offset);
+   } else if (op == nir_intrinsic_load_kernel_param) {
+      load->src[0] = nir_src_for_ssa(nir_imm_int(b, state->offsets[var->data.location]));
    } else {
       load->src[0] = nir_src_for_ssa(offset);
    }
@@ -407,7 +418,8 @@ nir_lower_io_block(nir_block *block,
       if (mode != nir_var_shader_in &&
           mode != nir_var_shader_out &&
           mode != nir_var_shared &&
-          mode != nir_var_uniform)
+          mode != nir_var_uniform &&
+          mode != nir_var_param)
          continue;
 
       b->cursor = nir_before_instr(instr);
@@ -481,6 +493,22 @@ nir_lower_io_block(nir_block *block,
    return progress;
 }
 
+static void
+nir_lower_io_calc_param_offsets(struct lower_io_state *state,
+                                nir_function_impl *impl)
+{
+   state->offsets = ralloc_array(state->builder.shader, unsigned,
+                                 impl->num_params);
+   state->offsets[0] = 0;
+   for (int i = 0; i < impl->num_params; ++i) {
+      nir_variable *var = impl->params[i];
+      state->offsets[i] = align(state->offsets[i], glsl_get_cl_alignment(var->type));
+      if (i + 1 < impl->num_params)
+         state->offsets[i + 1] = state->offsets[i] + glsl_get_cl_size(var->type);
+   }
+   ralloc_free(state->offsets);
+}
+
 static bool
 nir_lower_io_impl(nir_function_impl *impl,
                   nir_variable_mode modes,
@@ -495,6 +523,11 @@ nir_lower_io_impl(nir_function_impl *impl,
    state.type_size = type_size;
    state.options = options;
 
+   if (modes & nir_var_param &&
+       impl == nir_shader_get_entrypoint(state.builder.shader) &&
+       impl->num_params)
+      nir_lower_io_calc_param_offsets(&state, impl);
+
    nir_foreach_block(block, impl) {
       progress |= nir_lower_io_block(block, &state);
    }
-- 
2.14.3



More information about the mesa-dev mailing list