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 <kher...@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 df91febd68..ed8e361651 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

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to