[Mesa-dev] [PATCH] mesa/st: emit sampler declarations as arrays when indirect accesses are done
Ilia Mirkin
imirkin at alum.mit.edu
Mon Aug 11 09:56:55 PDT 2014
On Mon, Aug 11, 2014 at 12:43 PM, Roland Scheidegger <sroland at vmware.com> wrote:
> Am 11.08.2014 17:18, schrieb Ilia Mirkin:
>> Signed-off-by: Ilia Mirkin <imirkin at 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?
Pretty sure samplers_used can just be dropped entirely. All the places
that set it also generate instructions that use the samplers. There's
no way to "implicitly" use a sampler without a tex instruction of some
sort, AFAIK.
> 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?
Right, that's no good. Thanks for catching that :) I'll need to
rethink the impl... ugh.
>
> 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.)
Do you think my first patch can go in without this one being ready?
There's a release on the 15th, and I was hoping to make that with
ARB_gs5 on nvc0.
-ilia
More information about the mesa-dev
mailing list