On Mon, 2016-02-08 at 13:45 +1000, Dave Airlie wrote: > From: Dave Airlie <[email protected]> > > The state tracker never handled this properly, and it finally > annoyed me for the second time so I decided to fix it properly. > > This is inspired by the NIR sampler lowering code and I only realised > NIR seems to do its deref ordering different to GLSL at the last > minute, once I got that things got much easier. > > it fixes a bunch of tests in > tests/spec/arb_gpu_shader5/execution/sampler_array_indexing/ > > v2: fix AoA tests when forced on. > I was right I didn't need all that code, fixing the AoA code > meant cleaning up a chunk of code I didn't like in the array > handling. > > v3: start generalising the code a bit more for atomics. > v3.1: use UniformRemapTable > > v4: handle uniforms differently using the param_index, > and go back to UniformStorage > fix issues identified by Timothy with deref handling. > > Signed-off-by: Dave Airlie <[email protected]> > --- > src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 136 > +++++++++++++++++++++++++---- > 1 file changed, 118 insertions(+), 18 deletions(-) > > diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp > b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp > index 4b5f2a3..9e268bc 100644 > --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp > +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp > @@ -40,7 +40,6 @@ > #include "main/uniforms.h" > #include "main/shaderapi.h" > #include "program/prog_instruction.h" > -#include "program/sampler.h" > > #include "pipe/p_context.h" > #include "pipe/p_screen.h" > @@ -257,6 +256,7 @@ public: > GLboolean cond_update; > bool saturate; > st_src_reg sampler; /**< sampler register */ > + int sampler_base; > int sampler_array_size; /**< 1-based size of sampler array, 1 if > not array */ > int tex_target; /**< One of TEXTURE_*_INDEX */ > glsl_base_type tex_type; > @@ -502,6 +502,19 @@ public: > > void emit_arl(ir_instruction *ir, st_dst_reg dst, st_src_reg > src0); > > + void get_deref_offsets(ir_dereference *ir, > + unsigned *array_size, > + unsigned *base, > + unsigned *index, > + st_src_reg *reladdr); > + void calc_deref_offsets(ir_dereference *head, > + ir_dereference *tail, > + unsigned *array_elements, > + unsigned *base, > + unsigned *index, > + st_src_reg *indirect, > + unsigned *location); > + > bool try_emit_mad(ir_expression *ir, > int mul_operand); > bool try_emit_mad_for_and_not(ir_expression *ir, > @@ -3437,17 +3450,107 @@ glsl_to_tgsi_visitor::visit(ir_call *ir) > } > > void > +glsl_to_tgsi_visitor::calc_deref_offsets(ir_dereference *head, > + ir_dereference *tail, > + unsigned *array_elements, > + unsigned *base, > + unsigned *index, > + st_src_reg *indirect, > + unsigned *location) > +{ > + switch (tail->ir_type) { > + case ir_type_dereference_record: { > + ir_dereference_record *deref_record = tail- > >as_dereference_record(); > + const glsl_type *struct_type = deref_record->record->type; > + int field_index = deref_record->record->type- > >field_index(deref_record->field); > + > + calc_deref_offsets(head, deref_record->record- > >as_dereference(), array_elements, base, index, indirect, location); > + > + assert(field_index >= 0); > + *location += struct_type->record_location_offset(field_index); > + break; > + } > + > + case ir_type_dereference_array: { > + ir_dereference_array *deref_arr = tail- > >as_dereference_array(); > + ir_constant *array_index = deref_arr->array_index- > >constant_expression_value(); > + > + if (!array_index) { > + st_src_reg temp_reg; > + st_dst_reg temp_dst; > + > + temp_reg = get_temp(glsl_type::uint_type); > + temp_dst = st_dst_reg(temp_reg); > + temp_dst.writemask = 1; > + > + deref_arr->array_index->accept(this); > + if (*array_elements != 1) > + emit_asm(NULL, TGSI_OPCODE_MUL, temp_dst, this->result, > st_src_reg_for_int(*array_elements)); > + else > + emit_asm(NULL, TGSI_OPCODE_MOV, temp_dst, this->result); > + > + if (indirect->file == PROGRAM_UNDEFINED) > + *indirect = temp_reg; > + else { > + temp_dst = st_dst_reg(*indirect); > + temp_dst.writemask = 1; > + emit_asm(NULL, TGSI_OPCODE_ADD, temp_dst, *indirect, > temp_reg); > + } > + } else > + *index += array_index->value.u[0] * *array_elements; > + > + /* if this is just a constant 1D array deref - adjust base and > return 1 array elements */ > + if (array_index && deref_arr->array->ir_type == > ir_type_dereference_variable && head == tail) { > + *base = *index; > + } else { > + *array_elements *= deref_arr->array->type->length; > + } > + calc_deref_offsets(head, deref_arr->array->as_dereference(), > array_elements, base, index, indirect, location); > + break; > + } > + default: > + break; > + } > +} > + > +void > +glsl_to_tgsi_visitor::get_deref_offsets(ir_dereference *ir, > + unsigned *array_size, > + unsigned *base, > + unsigned *index, > + st_src_reg *reladdr) > +{ > + GLuint shader = _mesa_program_enum_to_shader_stage(this->prog- > >Target); > + unsigned location = 0; > + ir_variable *var = ir->variable_referenced(); > + > + memset(reladdr, 0, sizeof(*reladdr)); > + reladdr->file = PROGRAM_UNDEFINED; > + > + *base = 0; > + *array_size = 1; > + > + assert(var); > + location = var->data.location; > + calc_deref_offsets(ir, ir, array_size, base, index, reladdr, > &location); > + > + if (location != 0xffffffff) {
This could just be an assert right? It shouldn't ever be -1 for a sampler unless something went wrong in the linker. As I said last time I don't really understand all this tgsi specifics (which is around half the patch) but this time round the offset calculation looks correct so for what its worth this patch, 3 and 5 are Reviewed-by: Timothy Arcer <[email protected]> > + *base += this->shader_program- > >UniformStorage[location].opaque[shader].index; > + *index += this->shader_program- > >UniformStorage[location].opaque[shader].index; > + } > +} > + > +void > glsl_to_tgsi_visitor::visit(ir_texture *ir) > { > st_src_reg result_src, coord, cube_sc, lod_info, projector, dx, > dy; > st_src_reg offset[MAX_GLSL_TEXTURE_OFFSET], sample_index, > component; > - st_src_reg levels_src; > + st_src_reg levels_src, reladdr; > st_dst_reg result_dst, coord_dst, cube_sc_dst; > glsl_to_tgsi_instruction *inst = NULL; > unsigned opcode = TGSI_OPCODE_NOP; > const glsl_type *sampler_type = ir->sampler->type; > - ir_rvalue *sampler_index = > - _mesa_get_sampler_array_nonconst_index(ir->sampler); > + unsigned sampler_array_size = 1, sampler_index = 0, sampler_base > = 0; > bool is_cube_array = false; > unsigned i; > > @@ -3669,10 +3772,10 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir) > coord_dst.writemask = WRITEMASK_XYZW; > } > > - if (sampler_index) { > - sampler_index->accept(this); > - emit_arl(ir, sampler_reladdr, this->result); > - } > + get_deref_offsets(ir->sampler, &sampler_array_size, > &sampler_base, > + &sampler_index, &reladdr); > + if (reladdr.file != PROGRAM_UNDEFINED) > + emit_arl(ir, sampler_reladdr, reladdr); > > if (opcode == TGSI_OPCODE_TXD) > inst = emit_asm(ir, opcode, result_dst, coord, dx, dy); > @@ -3705,16 +3808,13 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir) > if (ir->shadow_comparitor) > inst->tex_shadow = GL_TRUE; > > - inst->sampler.index = _mesa_get_sampler_uniform_value(ir- > >sampler, > - this- > >shader_program, > - this- > >prog); > - if (sampler_index) { > + inst->sampler.index = sampler_index; > + inst->sampler_array_size = sampler_array_size; > + inst->sampler_base = sampler_base; > + > + if (reladdr.file != PROGRAM_UNDEFINED) { > inst->sampler.reladdr = ralloc(mem_ctx, st_src_reg); > - memcpy(inst->sampler.reladdr, &sampler_reladdr, > sizeof(sampler_reladdr)); > - inst->sampler_array_size = > - ir->sampler->as_dereference_array()->array->type- > >array_size(); > - } else { > - inst->sampler_array_size = 1; > + memcpy(inst->sampler.reladdr, &reladdr, sizeof(reladdr)); > } > > if (ir->offset) { > @@ -3915,7 +4015,7 @@ count_resources(glsl_to_tgsi_visitor *v, > gl_program *prog) > foreach_in_list(glsl_to_tgsi_instruction, inst, &v->instructions) > { > if (inst->info->is_tex) { > for (int i = 0; i < inst->sampler_array_size; i++) { > - unsigned idx = inst->sampler.index + i; > + unsigned idx = inst->sampler_base + i; > v->samplers_used |= 1 << idx; > > debug_assert(idx < (int)ARRAY_SIZE(v->sampler_types)); _______________________________________________ mesa-dev mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/mesa-dev
