Am 11.08.2014 17:18, schrieb Ilia Mirkin: > Signed-off-by: Ilia Mirkin <imir...@alum.mit.edu> > --- > > This applies on top of my previous patch to allow dynamic sampler offsets. > > Roland, I believe this should address your concerns. The generated code looks > like: > > FRAG > PROPERTY FS_COLOR0_WRITES_ALL_CBUFS 1 > DCL IN[0], GENERIC[0], PERSPECTIVE > DCL OUT[0], COLOR > DCL SAMP[0] > DCL SAMP[1..3] > DCL CONST[4] > DCL TEMP[0..1], LOCAL > DCL ADDR[0..2] > IMM[0] FLT32 { 0.0000, 0.0000, 0.0000, 0.0000} > 0: MOV TEMP[0].xy, IN[0].xyyy > 1: TEX TEMP[0], TEMP[0], SAMP[0], 2D > 2: MOV TEMP[1].xy, IN[0].xyyy > 3: UARL ADDR[2].x, CONST[4].xxxx > 4: TEX TEMP[1], TEMP[1], SAMP[ADDR[2].x+1], 2D > 5: MAD TEMP[0], TEMP[0], IMM[0].xxxx, TEMP[1] > 6: MOV OUT[0], TEMP[0] > 7: END > > And for now, the +1 is definitely guaranteed to be the base of the sampler > array. If some future optimization pass materializes, it will have to update > this code since it won't work otherwise. On the bright side, it's unlikely > that it'd poke around in inst->sampler, at least not without fixing things up > first. > > src/gallium/auxiliary/tgsi/tgsi_ureg.c | 48 > +++++++++++++++++++++++------- > src/gallium/auxiliary/tgsi/tgsi_ureg.h | 5 ++++ > src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 16 ++++++---- > 3 files changed, 54 insertions(+), 15 deletions(-) > > diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.c > b/src/gallium/auxiliary/tgsi/tgsi_ureg.c > index 6d3ac91..00c671b 100644 > --- a/src/gallium/auxiliary/tgsi/tgsi_ureg.c > +++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.c > @@ -141,7 +141,10 @@ struct ureg_program > } immediate[UREG_MAX_IMMEDIATE]; > unsigned nr_immediates; > > - struct ureg_src sampler[PIPE_MAX_SAMPLERS]; > + struct { > + struct ureg_src sampler; > + unsigned size; > + } sampler[PIPE_MAX_SAMPLERS]; > unsigned nr_samplers; > > struct { > @@ -663,19 +666,43 @@ struct ureg_src ureg_DECL_sampler( struct ureg_program > *ureg, > unsigned i; > > for (i = 0; i < ureg->nr_samplers; i++) > - if (ureg->sampler[i].Index == nr) > - return ureg->sampler[i]; > - > + if (ureg->sampler[i].sampler.Index == nr) > + return ureg->sampler[i].sampler; > + > + if (i < PIPE_MAX_SAMPLERS) { > + ureg->sampler[i].sampler = ureg_src_register( TGSI_FILE_SAMPLER, nr ); > + ureg->sampler[i].size = 1; > + ureg->nr_samplers++; > + return ureg->sampler[i].sampler; > + } > + > + assert( 0 ); > + return ureg->sampler[0].sampler; > +} > + > +struct ureg_src > +ureg_DECL_sampler_array( struct ureg_program *ureg, > + unsigned nr, > + unsigned elements ) > +{ > + unsigned i; > + > + for (i = 0; i < ureg->nr_samplers; i++) > + if (ureg->sampler[i].sampler.Index == nr) > + return ureg->sampler[i].sampler; > + > if (i < PIPE_MAX_SAMPLERS) { > - ureg->sampler[i] = ureg_src_register( TGSI_FILE_SAMPLER, nr ); > + ureg->sampler[i].sampler = ureg_src_register( TGSI_FILE_SAMPLER, nr ); > + ureg->sampler[i].size = elements; > ureg->nr_samplers++; > - return ureg->sampler[i]; > + return ureg->sampler[i].sampler; > } > > assert( 0 ); > - return ureg->sampler[0]; > + return ureg->sampler[0].sampler; > } > > + > /* > * Allocate a new shader sampler view. > */ > @@ -1571,9 +1598,10 @@ static void emit_decls( struct ureg_program *ureg ) > } > > for (i = 0; i < ureg->nr_samplers; i++) { > - emit_decl_range( ureg, > - TGSI_FILE_SAMPLER, > - ureg->sampler[i].Index, 1 ); > + emit_decl_range(ureg, > + TGSI_FILE_SAMPLER, > + ureg->sampler[i].sampler.Index, > + ureg->sampler[i].size); > } > > for (i = 0; i < ureg->nr_sampler_views; i++) { > diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.h > b/src/gallium/auxiliary/tgsi/tgsi_ureg.h > index f014b53..0512efa 100644 > --- a/src/gallium/auxiliary/tgsi/tgsi_ureg.h > +++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.h > @@ -325,6 +325,11 @@ ureg_DECL_sampler( struct ureg_program *, > unsigned index ); > > struct ureg_src > +ureg_DECL_sampler_array( struct ureg_program *, > + unsigned index, > + unsigned elements ); > + > +struct ureg_src > ureg_DECL_sampler_view(struct ureg_program *, > unsigned index, > unsigned target, > diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp > b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp > index 1fc229c..29b0742 100644 > --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp > +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp > @@ -31,6 +31,7 @@ > */ > > #include <stdio.h> > +#include <map> > #include "main/compiler.h" > #include "ir.h" > #include "ir_visitor.h" > @@ -334,8 +335,10 @@ public: > unsigned array_sizes[MAX_ARRAYS]; > unsigned next_array; > > - int num_address_regs; > int samplers_used; > + std::map<int, int> sampler_array_sizes; > + > + int num_address_regs; > bool indirect_addr_consts; > > int glsl_version; > @@ -3229,9 +3232,12 @@ static void > count_resources(glsl_to_tgsi_visitor *v, gl_program *prog) > { > v->samplers_used = 0; > + v->sampler_array_sizes.clear(); > > foreach_in_list(glsl_to_tgsi_instruction, inst, &v->instructions) { > if (is_tex_instruction(inst->op)) { > + v->sampler_array_sizes.insert( > + std::make_pair(inst->sampler.index, > inst->sampler_array_size)); > for (int i = 0; i < inst->sampler_array_size; i++) { > v->samplers_used |= 1 << (inst->sampler.index + i); > > @@ -5115,10 +5121,10 @@ st_translate_program( > assert(i == program->num_immediates); > > /* texture samplers */ > - for (i = 0; i < > ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits; i++) { > - if (program->samplers_used & (1 << i)) { > - t->samplers[i] = ureg_DECL_sampler(ureg, i); > - } > + for (std::map<int, int>::const_iterator it = > program->sampler_array_sizes.begin(); > + it != program->sampler_array_sizes.end(); ++it) { > + t->samplers[it->first] = ureg_DECL_sampler_array( > + ureg, it->first, it->second); > } > > /* Emit each instruction in turn: >
The tgsi generated looks ok to me. I don't think though it can work correctly because samplers_used may be set by other places? Also, I suspect there could be a problem (though I didn't look at the glsl code) due to the way that the array ranges are derived from the instructions. Wouldn't something like uniform sampler2D tex[8]; someinttemp i; x = texture2D(tex[i]...) y = texture2D(tex[2]...) get the dcls wrong, so the result would be something like DCL SAMP[0-7] DCL SAMP[2] or worse, if the second texture instruction would address tex[0] you'd get just DCL SAMP[0] because it overwrote the first dcl? Maybe this is more complex than I thought... (OTOH you can see from the posted intel patches that some hw really could make use of the array ranges, so this is not just purely a theoretical issue.) Roland _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev