On 08/30/2011 04:43 PM, Brian Paul wrote: > On Mon, Aug 29, 2011 at 7:38 AM, Dave Airlie <airl...@gmail.com> wrote: >> From: Dave Airlie <airl...@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 <airl...@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? >
>From NV_gpu_program5: extending texel offset support to allow loading texel offsets from regular integer operands computed at run-time, instead of requiring that the offsets be constants encoded in texture instructions; > -Brian > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/mesa-dev > _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev