[Mesa-dev] [PATCH 1/2] tgsi: add support for texture offsets to the TGSI IR.
Christoph Bumiller
e0425955 at student.tuwien.ac.at
Tue Aug 30 07:56:52 PDT 2011
On 08/30/2011 04:43 PM, Brian Paul wrote:
> On Mon, Aug 29, 2011 at 7:38 AM, Dave Airlie <airlied at gmail.com> wrote:
>> From: Dave Airlie <airlied at redhat.com>
>>
>> This adds tokens for texture offsets, to store 4 * swizzled vec 3
>> for use in TXF and other opcodes.
>>
>> It also contains TGSI exec changes for softpipe to use this code,
>> along with GLSL->TGSI support for TXF.
>>
>> Signed-off-by: Dave Airlie <airlied at redhat.com>
>> ---
>> src/gallium/auxiliary/tgsi/tgsi_build.c | 64 ++++++++++++++++++++++++-
>> src/gallium/auxiliary/tgsi/tgsi_dump.c | 11 ++++
>> src/gallium/auxiliary/tgsi/tgsi_exec.c | 22 ++++++++-
>> src/gallium/auxiliary/tgsi/tgsi_exec.h | 3 +-
>> src/gallium/auxiliary/tgsi/tgsi_parse.c | 3 +
>> src/gallium/auxiliary/tgsi/tgsi_parse.h | 2 +
>> src/gallium/auxiliary/tgsi/tgsi_ureg.c | 24 +++++++++-
>> src/gallium/auxiliary/tgsi/tgsi_ureg.h | 12 ++++-
>> src/gallium/docs/source/tgsi.rst | 13 ++++-
>> src/gallium/drivers/softpipe/sp_tex_sample.c | 17 +++++--
>> src/gallium/include/pipe/p_shader_tokens.h | 11 ++++-
>> src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 47 ++++++++++++++++++-
>> src/mesa/state_tracker/st_mesa_to_tgsi.c | 1 +
>> 13 files changed, 208 insertions(+), 22 deletions(-)
>>
>> diff --git a/src/gallium/auxiliary/tgsi/tgsi_build.c b/src/gallium/auxiliary/tgsi/tgsi_build.c
>> index 269940e..56491c9 100644
>> --- a/src/gallium/auxiliary/tgsi/tgsi_build.c
>> +++ b/src/gallium/auxiliary/tgsi/tgsi_build.c
>> @@ -631,7 +631,7 @@ tgsi_default_instruction_texture( void )
>> struct tgsi_instruction_texture instruction_texture;
>>
>> instruction_texture.Texture = TGSI_TEXTURE_UNKNOWN;
>> - instruction_texture.Padding = 0;
>> + instruction_texture.NumOffsets = 0;
>>
>> return instruction_texture;
>> }
>> @@ -639,6 +639,7 @@ tgsi_default_instruction_texture( void )
>> static struct tgsi_instruction_texture
>> tgsi_build_instruction_texture(
>> unsigned texture,
>> + unsigned num_offsets,
>> struct tgsi_token *prev_token,
>> struct tgsi_instruction *instruction,
>> struct tgsi_header *header )
>> @@ -646,7 +647,7 @@ tgsi_build_instruction_texture(
>> struct tgsi_instruction_texture instruction_texture;
>>
>> instruction_texture.Texture = texture;
>> - instruction_texture.Padding = 0;
>> + instruction_texture.NumOffsets = num_offsets;
>> instruction->Texture = 1;
>>
>> instruction_grow( instruction, header );
>> @@ -654,6 +655,41 @@ tgsi_build_instruction_texture(
>> return instruction_texture;
>> }
>>
>> +
>> +static struct tgsi_texture_offset
>> +tgsi_default_texture_offset( void )
>> +{
>> + struct tgsi_texture_offset instruction_texture_offset;
>> +
>> + instruction_texture_offset.Index = 0;
>> + instruction_texture_offset.File = 0;
>> + instruction_texture_offset.SwizzleX = 0;
>> + instruction_texture_offset.SwizzleY = 0;
>> + instruction_texture_offset.SwizzleZ = 0;
>> +
>> + return instruction_texture_offset;
>> +}
>> +
>> +static struct tgsi_texture_offset
>> +tgsi_build_texture_offset(
>> + int index, int file, int swizzle_x, int swizzle_y, int swizzle_z,
>> + struct tgsi_token *prev_token,
>> + struct tgsi_instruction *instruction,
>> + struct tgsi_header *header )
>> +{
>> + struct tgsi_texture_offset texture_offset;
>> +
>> + texture_offset.Index = index;
>> + texture_offset.File = file;
>> + texture_offset.SwizzleX = swizzle_x;
>> + texture_offset.SwizzleY = swizzle_y;
>> + texture_offset.SwizzleZ = swizzle_z;
>> +
>> + instruction_grow( instruction, header );
>> +
>> + return texture_offset;
>> +}
>> +
>> static struct tgsi_src_register
>> tgsi_default_src_register( void )
>> {
>> @@ -825,6 +861,9 @@ tgsi_default_full_instruction( void )
>> full_instruction.Predicate = tgsi_default_instruction_predicate();
>> full_instruction.Label = tgsi_default_instruction_label();
>> full_instruction.Texture = tgsi_default_instruction_texture();
>> + for( i = 0; i < TGSI_FULL_MAX_TEX_OFFSETS; i++ ) {
>> + full_instruction.TexOffsets[i] = tgsi_default_texture_offset();
>> + }
>> for( i = 0; i < TGSI_FULL_MAX_DST_REGISTERS; i++ ) {
>> full_instruction.Dst[i] = tgsi_default_full_dst_register();
>> }
>> @@ -908,12 +947,31 @@ tgsi_build_full_instruction(
>>
>> *instruction_texture = tgsi_build_instruction_texture(
>> full_inst->Texture.Texture,
>> + full_inst->Texture.NumOffsets,
>> prev_token,
>> instruction,
>> header );
>> prev_token = (struct tgsi_token *) instruction_texture;
>> - }
>>
>> + for (i = 0; i < full_inst->Texture.NumOffsets; i++) {
>> + struct tgsi_texture_offset *texture_offset;
>> +
>> + if ( maxsize <= size )
>> + return 0;
>> + texture_offset = (struct tgsi_texture_offset *)&tokens[size];
>> + size++;
>> + *texture_offset = tgsi_build_texture_offset(
>> + full_inst->TexOffsets[i].Index,
>> + full_inst->TexOffsets[i].File,
>> + full_inst->TexOffsets[i].SwizzleX,
>> + full_inst->TexOffsets[i].SwizzleY,
>> + full_inst->TexOffsets[i].SwizzleZ,
>> + prev_token,
>> + instruction,
>> + header);
>> + prev_token = (struct tgsi_token *) texture_offset;
>> + }
>> + }
>> for( i = 0; i < full_inst->Instruction.NumDstRegs; i++ ) {
>> const struct tgsi_full_dst_register *reg = &full_inst->Dst[i];
>> struct tgsi_dst_register *dst_register;
>> diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump.c b/src/gallium/auxiliary/tgsi/tgsi_dump.c
>> index c126620..7e2825e 100644
>> --- a/src/gallium/auxiliary/tgsi/tgsi_dump.c
>> +++ b/src/gallium/auxiliary/tgsi/tgsi_dump.c
>> @@ -693,6 +693,17 @@ iter_instruction(
>> if (inst->Instruction.Texture) {
>> TXT( ", " );
>> ENM( inst->Texture.Texture, tgsi_texture_names );
>> + for (i = 0; i < inst->Texture.NumOffsets; i++) {
>> + TXT( ", " );
>> + ENM( inst->TexOffsets[i].File, tgsi_file_names);
>> + CHR( '[' );
>> + SID( inst->TexOffsets[i].Index );
>> + CHR( ']' );
>> + CHR( '.' );
>> + ENM( inst->TexOffsets[i].SwizzleX, tgsi_swizzle_names);
>> + ENM( inst->TexOffsets[i].SwizzleY, tgsi_swizzle_names);
>> + ENM( inst->TexOffsets[i].SwizzleZ, tgsi_swizzle_names);
>> + }
>> }
>>
>> switch (inst->Instruction.Opcode) {
>> diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c
>> index 38dc1ef..fd118c5 100644
>> --- a/src/gallium/auxiliary/tgsi/tgsi_exec.c
>> +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c
>> @@ -1929,11 +1929,28 @@ exec_txf(struct tgsi_exec_machine *mach,
>> const struct tgsi_full_instruction *inst)
>> {
>> struct tgsi_sampler *sampler;
>> - const uint unit = inst->Src[1].Register.Index;
>> + const uint unit = inst->Src[2].Register.Index;
>> union tgsi_exec_channel r[4];
>> + union tgsi_exec_channel offset[3];
>> uint chan;
>> float rgba[NUM_CHANNELS][QUAD_SIZE];
>> int j;
>> + int8_t offsets[3];
>> +
>> + if (inst->Texture.NumOffsets == 1) {
>> + union tgsi_exec_channel index;
>> + index.i[0] = index.i[1] = index.i[2] = index.i[3] = inst->TexOffsets[0].Index;
>> + fetch_src_file_channel(mach, inst->TexOffsets[0].File,
>> + inst->TexOffsets[0].SwizzleX, &index, &ZeroVec, &offset[0]);
>> + fetch_src_file_channel(mach, inst->TexOffsets[0].File,
>> + inst->TexOffsets[0].SwizzleY, &index, &ZeroVec, &offset[1]);
>> + fetch_src_file_channel(mach, inst->TexOffsets[0].File,
>> + inst->TexOffsets[0].SwizzleZ, &index, &ZeroVec, &offset[2]);
>> + offsets[0] = offset[0].i[0];
>> + offsets[1] = offset[1].i[0];
>> + offsets[2] = offset[2].i[0];
>> + } else
>> + offsets[0] = offsets[1] = offsets[2] = 0;
>>
>> IFETCH(&r[3], 0, CHAN_W);
>>
>> @@ -1959,7 +1976,8 @@ exec_txf(struct tgsi_exec_machine *mach,
>> }
>>
>> sampler = mach->Samplers[unit];
>> - sampler->get_texel(sampler, r[0].i, r[1].i, r[2].i, r[3].i, rgba);
>> + sampler->get_texel(sampler, r[0].i, r[1].i, r[2].i, r[3].i,
>> + offsets, rgba);
>>
>> for (j = 0; j < QUAD_SIZE; j++) {
>> r[0].f[j] = rgba[0][j];
>> diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.h b/src/gallium/auxiliary/tgsi/tgsi_exec.h
>> index 3f6964c..a750715 100644
>> --- a/src/gallium/auxiliary/tgsi/tgsi_exec.h
>> +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.h
>> @@ -94,7 +94,8 @@ struct tgsi_sampler
>> int dims[4]);
>> void (*get_texel)(struct tgsi_sampler *sampler, const int i[QUAD_SIZE],
>> const int j[QUAD_SIZE], const int k[QUAD_SIZE],
>> - const int lod[QUAD_SIZE], float rgba[NUM_CHANNELS][QUAD_SIZE]);
>> + const int lod[QUAD_SIZE], const int8_t offset[3],
>> + float rgba[NUM_CHANNELS][QUAD_SIZE]);
>> };
>>
>> #define TGSI_EXEC_NUM_TEMPS 128
>> diff --git a/src/gallium/auxiliary/tgsi/tgsi_parse.c b/src/gallium/auxiliary/tgsi/tgsi_parse.c
>> index fb36f9d..e1902eb 100644
>> --- a/src/gallium/auxiliary/tgsi/tgsi_parse.c
>> +++ b/src/gallium/auxiliary/tgsi/tgsi_parse.c
>> @@ -188,6 +188,9 @@ tgsi_parse_token(
>>
>> if (inst->Instruction.Texture) {
>> next_token( ctx, &inst->Texture);
>> + for( i = 0; i < inst->Texture.NumOffsets; i++ ) {
>> + next_token( ctx, &inst->TexOffsets[i] );
>> + }
>> }
>>
>> assert( inst->Instruction.NumDstRegs <= TGSI_FULL_MAX_DST_REGISTERS );
>> diff --git a/src/gallium/auxiliary/tgsi/tgsi_parse.h b/src/gallium/auxiliary/tgsi/tgsi_parse.h
>> index b7a3c9b..f7b7e6e 100644
>> --- a/src/gallium/auxiliary/tgsi/tgsi_parse.h
>> +++ b/src/gallium/auxiliary/tgsi/tgsi_parse.h
>> @@ -86,6 +86,7 @@ struct tgsi_full_property
>>
>> #define TGSI_FULL_MAX_DST_REGISTERS 2
>> #define TGSI_FULL_MAX_SRC_REGISTERS 5 /* SAMPLE_D has 5 */
>> +#define TGSI_FULL_MAX_TEX_OFFSETS 4
>>
>> struct tgsi_full_instruction
>> {
>> @@ -95,6 +96,7 @@ struct tgsi_full_instruction
>> struct tgsi_instruction_texture Texture;
>> struct tgsi_full_dst_register Dst[TGSI_FULL_MAX_DST_REGISTERS];
>> struct tgsi_full_src_register Src[TGSI_FULL_MAX_SRC_REGISTERS];
>> + struct tgsi_texture_offset TexOffsets[TGSI_FULL_MAX_TEX_OFFSETS];
>> };
>>
>> union tgsi_full_token
>> diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.c b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
>> index a920741..cada435 100644
>> --- a/src/gallium/auxiliary/tgsi/tgsi_ureg.c
>> +++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
>> @@ -54,6 +54,7 @@ union tgsi_any_token {
>> struct tgsi_instruction_predicate insn_predicate;
>> struct tgsi_instruction_label insn_label;
>> struct tgsi_instruction_texture insn_texture;
>> + struct tgsi_texture_offset insn_texture_offset;
>> struct tgsi_src_register src;
>> struct tgsi_dimension dim;
>> struct tgsi_dst_register dst;
>> @@ -997,7 +998,7 @@ ureg_fixup_label(struct ureg_program *ureg,
>> void
>> ureg_emit_texture(struct ureg_program *ureg,
>> unsigned extended_token,
>> - unsigned target )
>> + unsigned target, unsigned num_offsets)
>> {
>> union tgsi_any_token *out, *insn;
>>
>> @@ -1008,6 +1009,20 @@ ureg_emit_texture(struct ureg_program *ureg,
>>
>> out[0].value = 0;
>> out[0].insn_texture.Texture = target;
>> + out[0].insn_texture.NumOffsets = num_offsets;
>> +}
>> +
>> +void
>> +ureg_emit_texture_offset(struct ureg_program *ureg,
>> + const struct tgsi_texture_offset *offset)
>> +{
>> + union tgsi_any_token *out;
>> +
>> + out = get_tokens( ureg, DOMAIN_INSN, 1);
>> +
>> + out[0].value = 0;
>> + out[0].insn_texture_offset = *offset;
>> +
>> }
>>
>>
>> @@ -1074,6 +1089,8 @@ ureg_tex_insn(struct ureg_program *ureg,
>> const struct ureg_dst *dst,
>> unsigned nr_dst,
>> unsigned target,
>> + const struct tgsi_texture_offset *texoffsets,
>> + unsigned nr_offset,
>> const struct ureg_src *src,
>> unsigned nr_src )
>> {
>> @@ -1106,7 +1123,10 @@ ureg_tex_insn(struct ureg_program *ureg,
>> nr_dst,
>> nr_src);
>>
>> - ureg_emit_texture( ureg, insn.extended_token, target );
>> + ureg_emit_texture( ureg, insn.extended_token, target, nr_offset );
>> +
>> + for (i = 0; i < nr_offset; i++)
>> + ureg_emit_texture_offset( ureg, &texoffsets[i]);
>>
>> for (i = 0; i < nr_dst; i++)
>> ureg_emit_dst( ureg, dst[i] );
>> diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.h b/src/gallium/auxiliary/tgsi/tgsi_ureg.h
>> index e3a4915..8f5f22e 100644
>> --- a/src/gallium/auxiliary/tgsi/tgsi_ureg.h
>> +++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.h
>> @@ -451,6 +451,8 @@ ureg_tex_insn(struct ureg_program *ureg,
>> const struct ureg_dst *dst,
>> unsigned nr_dst,
>> unsigned target,
>> + const struct tgsi_texture_offset *texoffsets,
>> + unsigned nr_offset,
>> const struct ureg_src *src,
>> unsigned nr_src );
>>
>> @@ -493,7 +495,11 @@ ureg_emit_label(struct ureg_program *ureg,
>> void
>> ureg_emit_texture(struct ureg_program *ureg,
>> unsigned insn_token,
>> - unsigned target );
>> + unsigned target, unsigned num_offsets);
>> +
>> +void
>> +ureg_emit_texture_offset(struct ureg_program *ureg,
>> + const struct tgsi_texture_offset *offset);
>>
>> void
>> ureg_emit_dst( struct ureg_program *ureg,
>> @@ -677,7 +683,7 @@ static INLINE void ureg_##op( struct ureg_program *ureg, \
>> dst.PredSwizzleW, \
>> 1, \
>> 2); \
>> - ureg_emit_texture( ureg, insn.extended_token, target ); \
>> + ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
>> ureg_emit_dst( ureg, dst ); \
>> ureg_emit_src( ureg, src0 ); \
>> ureg_emit_src( ureg, src1 ); \
>> @@ -732,7 +738,7 @@ static INLINE void ureg_##op( struct ureg_program *ureg, \
>> dst.PredSwizzleW, \
>> 1, \
>> 4); \
>> - ureg_emit_texture( ureg, insn.extended_token, target ); \
>> + ureg_emit_texture( ureg, insn.extended_token, target, 0 ); \
>> ureg_emit_dst( ureg, dst ); \
>> ureg_emit_src( ureg, src0 ); \
>> ureg_emit_src( ureg, src1 ); \
>> diff --git a/src/gallium/docs/source/tgsi.rst b/src/gallium/docs/source/tgsi.rst
>> index 039cb1c..5cf0875 100644
>> --- a/src/gallium/docs/source/tgsi.rst
>> +++ b/src/gallium/docs/source/tgsi.rst
>> @@ -1026,9 +1026,16 @@ XXX so let's discuss it, yeah?
>> dst.w = |src0.w - src1.w| + src2.w
>>
>>
>> -.. opcode:: TXF - Texel Fetch
>> -
>> - TBD
>> +.. opcode:: TXF - Texel Fetch (as per NV_gpu_shader4), extract a single texel
>> + from a specified texture image. The source sampler may
>> + not be a CUBE or SHADOW.
>> + src 0 is a four-component signed integer vector used to
>> + identify the single texel accessed. 3 components + level.
>> + src 1 is a 3 component constant signed integer vector,
>> + with each component only have a range of
>> + -8..+8 (hw only seems to deal with this range, interface
>> + allows for up to unsigned int).
>> + TXF(uint_vec coord, int_vec offset).
>>
>>
>> .. opcode:: TXQ - Texture Size Query (as per NV_gpu_program4)
>> diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c
>> index 89c6536..dd33a10 100644
>> --- a/src/gallium/drivers/softpipe/sp_tex_sample.c
>> +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c
>> @@ -2614,6 +2614,7 @@ sample_get_texels(struct tgsi_sampler *tgsi_sampler,
>> const int v_j[QUAD_SIZE],
>> const int v_k[QUAD_SIZE],
>> const int lod[QUAD_SIZE],
>> + const int8_t offset[3],
>> float rgba[NUM_CHANNELS][QUAD_SIZE])
>> {
>> const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
>> @@ -2629,7 +2630,7 @@ sample_get_texels(struct tgsi_sampler *tgsi_sampler,
>> switch(texture->target) {
>> case PIPE_TEXTURE_1D:
>> for (j = 0; j < QUAD_SIZE; j++) {
>> - tx = get_texel_2d(samp, addr, v_i[j], 0);
>> + tx = get_texel_2d(samp, addr, v_i[j] + offset[0], 0);
>> for (c = 0; c < 4; c++) {
>> rgba[c][j] = tx[c];
>> }
>> @@ -2637,7 +2638,8 @@ sample_get_texels(struct tgsi_sampler *tgsi_sampler,
>> break;
>> case PIPE_TEXTURE_1D_ARRAY:
>> for (j = 0; j < QUAD_SIZE; j++) {
>> - tx = get_texel_1d_array(samp, addr, v_i[j], v_j[j]);
>> + tx = get_texel_1d_array(samp, addr, v_i[j] + offset[0],
>> + v_j[j] + offset[1]);
>> for (c = 0; c < 4; c++) {
>> rgba[c][j] = tx[c];
>> }
>> @@ -2646,7 +2648,8 @@ sample_get_texels(struct tgsi_sampler *tgsi_sampler,
>> case PIPE_TEXTURE_2D:
>> case PIPE_TEXTURE_RECT:
>> for (j = 0; j < QUAD_SIZE; j++) {
>> - tx = get_texel_2d(samp, addr, v_i[j], v_j[j]);
>> + tx = get_texel_2d(samp, addr, v_i[j] + offset[0],
>> + v_j[j] + offset[1]);
>> for (c = 0; c < 4; c++) {
>> rgba[c][j] = tx[c];
>> }
>> @@ -2654,7 +2657,9 @@ sample_get_texels(struct tgsi_sampler *tgsi_sampler,
>> break;
>> case PIPE_TEXTURE_2D_ARRAY:
>> for (j = 0; j < QUAD_SIZE; j++) {
>> - tx = get_texel_2d_array(samp, addr, v_i[j], v_j[j], v_k[j]);
>> + tx = get_texel_2d_array(samp, addr, v_i[j] + offset[0],
>> + v_j[j] + offset[1],
>> + v_k[j] + offset[2]);
>> for (c = 0; c < 4; c++) {
>> rgba[c][j] = tx[c];
>> }
>> @@ -2662,7 +2667,9 @@ sample_get_texels(struct tgsi_sampler *tgsi_sampler,
>> break;
>> case PIPE_TEXTURE_3D:
>> for (j = 0; j < QUAD_SIZE; j++) {
>> - tx = get_texel_3d(samp, addr, v_i[j], v_j[j], v_k[j]);
>> + tx = get_texel_3d(samp, addr, v_i[j] + offset[0],
>> + v_j[j] + offset[1],
>> + v_k[j] + offset[2]);
>> for (c = 0; c < 4; c++) {
>> rgba[c][j] = tx[c];
>> }
>> diff --git a/src/gallium/include/pipe/p_shader_tokens.h b/src/gallium/include/pipe/p_shader_tokens.h
>> index d3a3632..e5e7c0b 100644
>> --- a/src/gallium/include/pipe/p_shader_tokens.h
>> +++ b/src/gallium/include/pipe/p_shader_tokens.h
>> @@ -437,7 +437,16 @@ struct tgsi_instruction_label
>> struct tgsi_instruction_texture
>> {
>> unsigned Texture : 8; /* TGSI_TEXTURE_ */
>> - unsigned Padding : 24;
>> + unsigned NumOffsets : 4;
>> +};
>> +
>> +struct tgsi_texture_offset
>> +{
>> + int Index:16;
>> + unsigned File : 4;
>> + unsigned SwizzleX : 2; /* TGSI_SWIZZLE_x */
>> + unsigned SwizzleY : 2; /* TGSI_SWIZZLE_x */
>> + unsigned SwizzleZ : 2; /* TGSI_SWIZZLE_x */
>> };
>>
>> /*
>> diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
>> index 9cac309..c2a94f4 100644
>> --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
>> +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
>> @@ -80,6 +80,9 @@ extern "C" {
>>
>> #define MAX_TEMPS 4096
>>
>> +/* will be 4 for GLSL 4.00 */
>> +#define MAX_GLSL_TEXTURE_OFFSET 1
>> +
>> class st_src_reg;
>> class st_dst_reg;
>>
>> @@ -211,6 +214,8 @@ public:
>> int sampler; /**< sampler index */
>> int tex_target; /**< One of TEXTURE_*_INDEX */
>> GLboolean tex_shadow;
>> + struct tgsi_texture_offset tex_offsets[MAX_GLSL_TEXTURE_OFFSET];
>> + unsigned tex_offset_num_offset;
>> int dead_mask; /**< Used in dead code elimination */
>>
>> class function_entry *function; /* Set on TGSI_OPCODE_CAL or TGSI_OPCODE_BGNSUB */
>> @@ -2421,7 +2426,7 @@ glsl_to_tgsi_visitor::visit(ir_call *ir)
>> void
>> glsl_to_tgsi_visitor::visit(ir_texture *ir)
>> {
>> - st_src_reg result_src, coord, lod_info, projector, dx, dy;
>> + st_src_reg result_src, coord, lod_info, projector, dx, dy, offset;
>> st_dst_reg result_dst, coord_dst;
>> glsl_to_tgsi_instruction *inst = NULL;
>> unsigned opcode = TGSI_OPCODE_NOP;
>> @@ -2480,6 +2485,10 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir)
>> opcode = TGSI_OPCODE_TXF;
>> ir->lod_info.lod->accept(this);
>> lod_info = this->result;
>> + if (ir->offset) {
>> + ir->offset->accept(this);
>> + offset = this->result;
>> + }
>> break;
>> }
>>
>> @@ -2555,7 +2564,9 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir)
>> inst = emit(ir, opcode, result_dst, coord, dx, dy);
>> else if (opcode == TGSI_OPCODE_TXQ)
>> inst = emit(ir, opcode, result_dst, lod_info);
>> - else
>> + else if (opcode == TGSI_OPCODE_TXF) {
>> + inst = emit(ir, opcode, result_dst, coord);
>> + } else
>> inst = emit(ir, opcode, result_dst, coord);
>>
>> if (ir->shadow_comparitor)
>> @@ -2565,6 +2576,15 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir)
>> this->shader_program,
>> this->prog);
>>
>> + if (ir->offset) {
>> + inst->tex_offset_num_offset = 1;
>> + inst->tex_offsets[0].Index = offset.index;
>> + inst->tex_offsets[0].File = offset.file;
>> + inst->tex_offsets[0].SwizzleX = GET_SWZ(offset.swizzle, 0);
>> + inst->tex_offsets[0].SwizzleY = GET_SWZ(offset.swizzle, 1);
>> + inst->tex_offsets[0].SwizzleZ = GET_SWZ(offset.swizzle, 2);
>> + }
>> +
>> const glsl_type *sampler_type = ir->sampler->type;
>>
>> switch (sampler_type->sampler_dimensionality) {
>> @@ -4246,6 +4266,23 @@ translate_src(struct st_translate *t, const st_src_reg *src_reg)
>> return src;
>> }
>>
>> +static struct tgsi_texture_offset
>> +translate_tex_offset(struct st_translate *t,
>> + const struct tgsi_texture_offset *in_offset)
>> +{
>> + struct tgsi_texture_offset offset;
>> +
>> + assert(in_offset->File == PROGRAM_IMMEDIATE);
>> +
>> + offset.File = TGSI_FILE_IMMEDIATE;
>> + offset.Index = in_offset->Index;
>> + offset.SwizzleX = in_offset->SwizzleX;
>> + offset.SwizzleY = in_offset->SwizzleY;
>> + offset.SwizzleZ = in_offset->SwizzleZ;
>> +
>> + return offset;
>> +}
>> +
>> static void
>> compile_tgsi_instruction(struct st_translate *t,
>> const glsl_to_tgsi_instruction *inst)
>> @@ -4254,6 +4291,8 @@ compile_tgsi_instruction(struct st_translate *t,
>> GLuint i;
>> struct ureg_dst dst[1];
>> struct ureg_src src[4];
>> + struct tgsi_texture_offset texoffsets[MAX_GLSL_TEXTURE_OFFSET];
>> +
>> unsigned num_dst;
>> unsigned num_src;
>>
>> @@ -4290,10 +4329,14 @@ compile_tgsi_instruction(struct st_translate *t,
>> case TGSI_OPCODE_TXQ:
>> case TGSI_OPCODE_TXF:
>> src[num_src++] = t->samplers[inst->sampler];
>> + for (i = 0; i < inst->tex_offset_num_offset; i++) {
>> + texoffsets[i] = translate_tex_offset(t, &inst->tex_offsets[i]);
>> + }
>> ureg_tex_insn(ureg,
>> inst->op,
>> dst, num_dst,
>> translate_texture_target(inst->tex_target, inst->tex_shadow),
>> + texoffsets, inst->tex_offset_num_offset,
>> src, num_src);
>> return;
>>
>> diff --git a/src/mesa/state_tracker/st_mesa_to_tgsi.c b/src/mesa/state_tracker/st_mesa_to_tgsi.c
>> index 656c985..f4263c6 100644
>> --- a/src/mesa/state_tracker/st_mesa_to_tgsi.c
>> +++ b/src/mesa/state_tracker/st_mesa_to_tgsi.c
>> @@ -705,6 +705,7 @@ compile_instruction(
>> dst, num_dst,
>> translate_texture_target( inst->TexSrcTarget,
>> inst->TexShadow ),
>> + NULL, 0,
>> src, num_src );
>> return;
>>
>> --
>> 1.7.6
>
> Extending TSGI is a bit of a black art but you seem to have figured it out.
>
> I'm looking at the swizzle fields in tgsi_texture_offset. Why do
> those exist? I'm guessing it's just for the case that a bunch of
> offsets get tightly packed in a constant slot. 0, 1, -1 would seem to
> be very common offsets so a whole bunch of offsets might be encoded in
> a single constant vector. If that's the intention, some comments
> explaining this would be good.
>
> Also, I thought that the offsets had to be compile-time constants so
> tgsi_texture_offset::File would always be PROGRAM_IMMEDIATE. If
> that's true, why have the File field?
>
More information about the mesa-dev
mailing list