From: Rob Clark <robdcl...@gmail.com> For cl we can have structs with 8/16/32/64 bit scalar types (as well as, ofc, arrays/structs/etc), which are padded according to 'C' rules. So for lowering struct deref's we need to not just consider a field's size, but also it's alignment.
Signed-off-by: Karol Herbst <kher...@redhat.com> --- src/compiler/nir/nir.h | 10 +++++++ src/compiler/nir/nir_lower_io.c | 52 ++++++++++++++++++++++++--------- 2 files changed, 49 insertions(+), 13 deletions(-) diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index c469e111b2c..11e3d18320a 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -2825,10 +2825,20 @@ typedef enum { */ nir_lower_io_force_sample_interpolation = (1 << 1), } nir_lower_io_options; +typedef struct nir_memory_model { + int (*type_size)(const struct glsl_type *); + int (*type_align)(const struct glsl_type *); +} nir_memory_model; bool nir_lower_io(nir_shader *shader, nir_variable_mode modes, int (*type_size)(const struct glsl_type *), nir_lower_io_options); +// TEMP use different name to avoid fixing all the callers yet: +bool nir_lower_io2(nir_shader *shader, + nir_variable_mode modes, + const nir_memory_model *mm, + nir_lower_io_options); + nir_src *nir_get_io_offset_src(nir_intrinsic_instr *instr); nir_src *nir_get_io_vertex_index_src(nir_intrinsic_instr *instr); diff --git a/src/compiler/nir/nir_lower_io.c b/src/compiler/nir/nir_lower_io.c index 2a6c284de2b..292baf9e4fc 100644 --- a/src/compiler/nir/nir_lower_io.c +++ b/src/compiler/nir/nir_lower_io.c @@ -38,7 +38,7 @@ struct lower_io_state { void *dead_ctx; nir_builder builder; - int (*type_size)(const struct glsl_type *type); + const nir_memory_model *mm; nir_variable_mode modes; nir_lower_io_options options; }; @@ -86,12 +86,26 @@ nir_is_per_vertex_io(const nir_variable *var, gl_shader_stage stage) return false; } +static int +default_type_align(const struct glsl_type *type) +{ + return 1; +} + +static inline int +align(int value, int alignment) +{ + return (value + alignment - 1) & ~(alignment - 1); +} + static nir_ssa_def * get_io_offset(nir_deref_instr *deref, nir_ssa_def **vertex_index, struct lower_io_state *state, unsigned *component) { nir_builder *b = &state->builder; - int (*type_size)(const struct glsl_type *) = state->type_size; + int (*type_size)(const struct glsl_type *) = state->mm->type_size; + int (*type_align)(const struct glsl_type *) = state->mm->type_align ? + state->mm->type_align : default_type_align; nir_deref_path path; nir_deref_path_init(&path, deref, NULL); @@ -137,7 +151,10 @@ get_io_offset(nir_deref_instr *deref, nir_ssa_def **vertex_index, unsigned field_offset = 0; for (unsigned i = 0; i < (*p)->strct.index; i++) { - field_offset += type_size(glsl_get_struct_field(parent->type, i)); + const struct glsl_type *field_type = + glsl_get_struct_field(parent->type, i); + field_offset = align(field_offset, type_align(field_type)); + field_offset += type_size(field_type); } offset = nir_iadd(b, offset, nir_imm_int(b, field_offset)); } else { @@ -207,7 +224,7 @@ lower_load(nir_intrinsic_instr *intrin, struct lower_io_state *state, nir_intrinsic_set_component(load, component); if (load->intrinsic == nir_intrinsic_load_uniform) - nir_intrinsic_set_range(load, state->type_size(var->type)); + nir_intrinsic_set_range(load, state->mm->type_size(var->type)); if (vertex_index) { load->src[0] = nir_src_for_ssa(vertex_index); @@ -488,10 +505,8 @@ nir_lower_io_block(nir_block *block, } static bool -nir_lower_io_impl(nir_function_impl *impl, - nir_variable_mode modes, - int (*type_size)(const struct glsl_type *), - nir_lower_io_options options) +nir_lower_io_impl(nir_function_impl *impl, nir_variable_mode modes, + const nir_memory_model *mm, nir_lower_io_options options) { struct lower_io_state state; bool progress = false; @@ -499,7 +514,7 @@ nir_lower_io_impl(nir_function_impl *impl, nir_builder_init(&state.builder, impl); state.dead_ctx = ralloc_context(NULL); state.modes = modes; - state.type_size = type_size; + state.mm = mm; state.options = options; nir_foreach_block(block, impl) { @@ -514,22 +529,33 @@ nir_lower_io_impl(nir_function_impl *impl, } bool -nir_lower_io(nir_shader *shader, nir_variable_mode modes, - int (*type_size)(const struct glsl_type *), - nir_lower_io_options options) +nir_lower_io2(nir_shader *shader, nir_variable_mode modes, + const nir_memory_model *mm, nir_lower_io_options options) { bool progress = false; nir_foreach_function(function, shader) { if (function->impl) { progress |= nir_lower_io_impl(function->impl, modes, - type_size, options); + mm, options); } } return progress; } + +bool +nir_lower_io(nir_shader *shader, nir_variable_mode modes, + int (*type_size)(const struct glsl_type *), + nir_lower_io_options options) +{ + nir_memory_model mm = { + .type_size = type_size, + }; + return nir_lower_io2(shader, modes, &mm, options); +} + /** * Return the offset source for a load/store intrinsic. */ -- 2.19.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev