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: -- 1.8.5.5 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev