tgsi: add support for texture offsets to the TGSI IR. (v2)

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.

v2: add some more comments, add back padding I removed.

Signed-off-by: Dave Airlie <airlied@redhat.com>
Reviewed-by: Brian Paul <brianp@vmware.com>
This commit is contained in:
Dave Airlie
2011-08-26 10:59:18 +01:00
parent 49e24d3b8c
commit 2083a276eb
13 changed files with 219 additions and 20 deletions

View File

@@ -631,6 +631,7 @@ tgsi_default_instruction_texture( void )
struct tgsi_instruction_texture instruction_texture; struct tgsi_instruction_texture instruction_texture;
instruction_texture.Texture = TGSI_TEXTURE_UNKNOWN; instruction_texture.Texture = TGSI_TEXTURE_UNKNOWN;
instruction_texture.NumOffsets = 0;
instruction_texture.Padding = 0; instruction_texture.Padding = 0;
return instruction_texture; return instruction_texture;
@@ -639,6 +640,7 @@ tgsi_default_instruction_texture( void )
static struct tgsi_instruction_texture static struct tgsi_instruction_texture
tgsi_build_instruction_texture( tgsi_build_instruction_texture(
unsigned texture, unsigned texture,
unsigned num_offsets,
struct tgsi_token *prev_token, struct tgsi_token *prev_token,
struct tgsi_instruction *instruction, struct tgsi_instruction *instruction,
struct tgsi_header *header ) struct tgsi_header *header )
@@ -646,6 +648,7 @@ tgsi_build_instruction_texture(
struct tgsi_instruction_texture instruction_texture; struct tgsi_instruction_texture instruction_texture;
instruction_texture.Texture = texture; instruction_texture.Texture = texture;
instruction_texture.NumOffsets = num_offsets;
instruction_texture.Padding = 0; instruction_texture.Padding = 0;
instruction->Texture = 1; instruction->Texture = 1;
@@ -654,6 +657,43 @@ tgsi_build_instruction_texture(
return instruction_texture; return instruction_texture;
} }
static struct tgsi_texture_offset
tgsi_default_texture_offset( void )
{
struct tgsi_texture_offset texture_offset;
texture_offset.Index = 0;
texture_offset.File = 0;
texture_offset.SwizzleX = 0;
texture_offset.SwizzleY = 0;
texture_offset.SwizzleZ = 0;
texture_offset.Padding = 0;
return 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;
texture_offset.Padding = 0;
instruction_grow( instruction, header );
return texture_offset;
}
static struct tgsi_src_register static struct tgsi_src_register
tgsi_default_src_register( void ) tgsi_default_src_register( void )
{ {
@@ -825,6 +865,9 @@ tgsi_default_full_instruction( void )
full_instruction.Predicate = tgsi_default_instruction_predicate(); full_instruction.Predicate = tgsi_default_instruction_predicate();
full_instruction.Label = tgsi_default_instruction_label(); full_instruction.Label = tgsi_default_instruction_label();
full_instruction.Texture = tgsi_default_instruction_texture(); 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++ ) { for( i = 0; i < TGSI_FULL_MAX_DST_REGISTERS; i++ ) {
full_instruction.Dst[i] = tgsi_default_full_dst_register(); full_instruction.Dst[i] = tgsi_default_full_dst_register();
} }
@@ -908,12 +951,31 @@ tgsi_build_full_instruction(
*instruction_texture = tgsi_build_instruction_texture( *instruction_texture = tgsi_build_instruction_texture(
full_inst->Texture.Texture, full_inst->Texture.Texture,
full_inst->Texture.NumOffsets,
prev_token, prev_token,
instruction, instruction,
header ); header );
prev_token = (struct tgsi_token *) instruction_texture; 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++ ) { for( i = 0; i < full_inst->Instruction.NumDstRegs; i++ ) {
const struct tgsi_full_dst_register *reg = &full_inst->Dst[i]; const struct tgsi_full_dst_register *reg = &full_inst->Dst[i];
struct tgsi_dst_register *dst_register; struct tgsi_dst_register *dst_register;

View File

@@ -693,6 +693,17 @@ iter_instruction(
if (inst->Instruction.Texture) { if (inst->Instruction.Texture) {
TXT( ", " ); TXT( ", " );
ENM( inst->Texture.Texture, tgsi_texture_names ); 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) { switch (inst->Instruction.Opcode) {

View File

@@ -1929,11 +1929,28 @@ exec_txf(struct tgsi_exec_machine *mach,
const struct tgsi_full_instruction *inst) const struct tgsi_full_instruction *inst)
{ {
struct tgsi_sampler *sampler; 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 r[4];
union tgsi_exec_channel offset[3];
uint chan; uint chan;
float rgba[NUM_CHANNELS][QUAD_SIZE]; float rgba[NUM_CHANNELS][QUAD_SIZE];
int j; 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); IFETCH(&r[3], 0, CHAN_W);
@@ -1959,7 +1976,8 @@ exec_txf(struct tgsi_exec_machine *mach,
} }
sampler = mach->Samplers[unit]; 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++) { for (j = 0; j < QUAD_SIZE; j++) {
r[0].f[j] = rgba[0][j]; r[0].f[j] = rgba[0][j];

View File

@@ -94,7 +94,8 @@ struct tgsi_sampler
int dims[4]); int dims[4]);
void (*get_texel)(struct tgsi_sampler *sampler, const int i[QUAD_SIZE], void (*get_texel)(struct tgsi_sampler *sampler, const int i[QUAD_SIZE],
const int j[QUAD_SIZE], const int k[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 #define TGSI_EXEC_NUM_TEMPS 128

View File

@@ -188,6 +188,9 @@ tgsi_parse_token(
if (inst->Instruction.Texture) { if (inst->Instruction.Texture) {
next_token( ctx, &inst->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 ); assert( inst->Instruction.NumDstRegs <= TGSI_FULL_MAX_DST_REGISTERS );

View File

@@ -86,6 +86,7 @@ struct tgsi_full_property
#define TGSI_FULL_MAX_DST_REGISTERS 2 #define TGSI_FULL_MAX_DST_REGISTERS 2
#define TGSI_FULL_MAX_SRC_REGISTERS 5 /* SAMPLE_D has 5 */ #define TGSI_FULL_MAX_SRC_REGISTERS 5 /* SAMPLE_D has 5 */
#define TGSI_FULL_MAX_TEX_OFFSETS 4
struct tgsi_full_instruction struct tgsi_full_instruction
{ {
@@ -95,6 +96,7 @@ struct tgsi_full_instruction
struct tgsi_instruction_texture Texture; struct tgsi_instruction_texture Texture;
struct tgsi_full_dst_register Dst[TGSI_FULL_MAX_DST_REGISTERS]; struct tgsi_full_dst_register Dst[TGSI_FULL_MAX_DST_REGISTERS];
struct tgsi_full_src_register Src[TGSI_FULL_MAX_SRC_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 union tgsi_full_token

View File

@@ -54,6 +54,7 @@ union tgsi_any_token {
struct tgsi_instruction_predicate insn_predicate; struct tgsi_instruction_predicate insn_predicate;
struct tgsi_instruction_label insn_label; struct tgsi_instruction_label insn_label;
struct tgsi_instruction_texture insn_texture; struct tgsi_instruction_texture insn_texture;
struct tgsi_texture_offset insn_texture_offset;
struct tgsi_src_register src; struct tgsi_src_register src;
struct tgsi_dimension dim; struct tgsi_dimension dim;
struct tgsi_dst_register dst; struct tgsi_dst_register dst;
@@ -997,7 +998,7 @@ ureg_fixup_label(struct ureg_program *ureg,
void void
ureg_emit_texture(struct ureg_program *ureg, ureg_emit_texture(struct ureg_program *ureg,
unsigned extended_token, unsigned extended_token,
unsigned target ) unsigned target, unsigned num_offsets)
{ {
union tgsi_any_token *out, *insn; union tgsi_any_token *out, *insn;
@@ -1008,6 +1009,20 @@ ureg_emit_texture(struct ureg_program *ureg,
out[0].value = 0; out[0].value = 0;
out[0].insn_texture.Texture = target; 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, const struct ureg_dst *dst,
unsigned nr_dst, unsigned nr_dst,
unsigned target, unsigned target,
const struct tgsi_texture_offset *texoffsets,
unsigned nr_offset,
const struct ureg_src *src, const struct ureg_src *src,
unsigned nr_src ) unsigned nr_src )
{ {
@@ -1106,7 +1123,10 @@ ureg_tex_insn(struct ureg_program *ureg,
nr_dst, nr_dst,
nr_src); 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++) for (i = 0; i < nr_dst; i++)
ureg_emit_dst( ureg, dst[i] ); ureg_emit_dst( ureg, dst[i] );

View File

@@ -451,6 +451,8 @@ ureg_tex_insn(struct ureg_program *ureg,
const struct ureg_dst *dst, const struct ureg_dst *dst,
unsigned nr_dst, unsigned nr_dst,
unsigned target, unsigned target,
const struct tgsi_texture_offset *texoffsets,
unsigned nr_offset,
const struct ureg_src *src, const struct ureg_src *src,
unsigned nr_src ); unsigned nr_src );
@@ -493,7 +495,11 @@ ureg_emit_label(struct ureg_program *ureg,
void void
ureg_emit_texture(struct ureg_program *ureg, ureg_emit_texture(struct ureg_program *ureg,
unsigned insn_token, 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 void
ureg_emit_dst( struct ureg_program *ureg, ureg_emit_dst( struct ureg_program *ureg,
@@ -677,7 +683,7 @@ static INLINE void ureg_##op( struct ureg_program *ureg, \
dst.PredSwizzleW, \ dst.PredSwizzleW, \
1, \ 1, \
2); \ 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_dst( ureg, dst ); \
ureg_emit_src( ureg, src0 ); \ ureg_emit_src( ureg, src0 ); \
ureg_emit_src( ureg, src1 ); \ ureg_emit_src( ureg, src1 ); \
@@ -732,7 +738,7 @@ static INLINE void ureg_##op( struct ureg_program *ureg, \
dst.PredSwizzleW, \ dst.PredSwizzleW, \
1, \ 1, \
4); \ 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_dst( ureg, dst ); \
ureg_emit_src( ureg, src0 ); \ ureg_emit_src( ureg, src0 ); \
ureg_emit_src( ureg, src1 ); \ ureg_emit_src( ureg, src1 ); \

View File

@@ -1026,9 +1026,16 @@ XXX so let's discuss it, yeah?
dst.w = |src0.w - src1.w| + src2.w dst.w = |src0.w - src1.w| + src2.w
.. opcode:: TXF - Texel Fetch .. opcode:: TXF - Texel Fetch (as per NV_gpu_shader4), extract a single texel
from a specified texture image. The source sampler may
TBD 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) .. opcode:: TXQ - Texture Size Query (as per NV_gpu_program4)

View File

@@ -2614,6 +2614,7 @@ sample_get_texels(struct tgsi_sampler *tgsi_sampler,
const int v_j[QUAD_SIZE], const int v_j[QUAD_SIZE],
const int v_k[QUAD_SIZE], const int v_k[QUAD_SIZE],
const int lod[QUAD_SIZE], const int lod[QUAD_SIZE],
const int8_t offset[3],
float rgba[NUM_CHANNELS][QUAD_SIZE]) float rgba[NUM_CHANNELS][QUAD_SIZE])
{ {
const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler); 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) { switch(texture->target) {
case PIPE_TEXTURE_1D: case PIPE_TEXTURE_1D:
for (j = 0; j < QUAD_SIZE; j++) { 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++) { for (c = 0; c < 4; c++) {
rgba[c][j] = tx[c]; rgba[c][j] = tx[c];
} }
@@ -2637,7 +2638,8 @@ sample_get_texels(struct tgsi_sampler *tgsi_sampler,
break; break;
case PIPE_TEXTURE_1D_ARRAY: case PIPE_TEXTURE_1D_ARRAY:
for (j = 0; j < QUAD_SIZE; j++) { 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++) { for (c = 0; c < 4; c++) {
rgba[c][j] = tx[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_2D:
case PIPE_TEXTURE_RECT: case PIPE_TEXTURE_RECT:
for (j = 0; j < QUAD_SIZE; j++) { 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++) { for (c = 0; c < 4; c++) {
rgba[c][j] = tx[c]; rgba[c][j] = tx[c];
} }
@@ -2654,7 +2657,9 @@ sample_get_texels(struct tgsi_sampler *tgsi_sampler,
break; break;
case PIPE_TEXTURE_2D_ARRAY: case PIPE_TEXTURE_2D_ARRAY:
for (j = 0; j < QUAD_SIZE; j++) { 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++) { for (c = 0; c < 4; c++) {
rgba[c][j] = tx[c]; rgba[c][j] = tx[c];
} }
@@ -2662,7 +2667,9 @@ sample_get_texels(struct tgsi_sampler *tgsi_sampler,
break; break;
case PIPE_TEXTURE_3D: case PIPE_TEXTURE_3D:
for (j = 0; j < QUAD_SIZE; j++) { 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++) { for (c = 0; c < 4; c++) {
rgba[c][j] = tx[c]; rgba[c][j] = tx[c];
} }

View File

@@ -401,6 +401,8 @@ struct tgsi_instruction
* If tgsi_instruction::Label is TRUE, tgsi_instruction_label follows. * If tgsi_instruction::Label is TRUE, tgsi_instruction_label follows.
* *
* If tgsi_instruction::Texture is TRUE, tgsi_instruction_texture follows. * If tgsi_instruction::Texture is TRUE, tgsi_instruction_texture follows.
* if texture instruction has a number of offsets,
* then tgsi_instruction::Texture::NumOffset of tgsi_texture_offset follow.
* *
* Then, tgsi_instruction::NumDstRegs of tgsi_dst_register follow. * Then, tgsi_instruction::NumDstRegs of tgsi_dst_register follow.
* *
@@ -437,7 +439,23 @@ struct tgsi_instruction_label
struct tgsi_instruction_texture struct tgsi_instruction_texture
{ {
unsigned Texture : 8; /* TGSI_TEXTURE_ */ unsigned Texture : 8; /* TGSI_TEXTURE_ */
unsigned Padding : 24; unsigned NumOffsets : 4;
unsigned Padding : 20;
};
/* for texture offsets in GLSL and DirectX.
* Generally these always come from TGSI_FILE_IMMEDIATE,
* however DX11 appears to have the capability to do
* non-constant texture offsets.
*/
struct tgsi_texture_offset
{
int Index : 16;
unsigned File : 4; /**< one of TGSI_FILE_x */
unsigned SwizzleX : 2; /* TGSI_SWIZZLE_x */
unsigned SwizzleY : 2; /* TGSI_SWIZZLE_x */
unsigned SwizzleZ : 2; /* TGSI_SWIZZLE_x */
unsigned Padding : 6;
}; };
/* /*

View File

@@ -80,6 +80,9 @@ extern "C" {
#define MAX_TEMPS 4096 #define MAX_TEMPS 4096
/* will be 4 for GLSL 4.00 */
#define MAX_GLSL_TEXTURE_OFFSET 1
class st_src_reg; class st_src_reg;
class st_dst_reg; class st_dst_reg;
@@ -211,6 +214,8 @@ public:
int sampler; /**< sampler index */ int sampler; /**< sampler index */
int tex_target; /**< One of TEXTURE_*_INDEX */ int tex_target; /**< One of TEXTURE_*_INDEX */
GLboolean tex_shadow; 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 */ int dead_mask; /**< Used in dead code elimination */
class function_entry *function; /* Set on TGSI_OPCODE_CAL or TGSI_OPCODE_BGNSUB */ 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 void
glsl_to_tgsi_visitor::visit(ir_texture *ir) 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; st_dst_reg result_dst, coord_dst;
glsl_to_tgsi_instruction *inst = NULL; glsl_to_tgsi_instruction *inst = NULL;
unsigned opcode = TGSI_OPCODE_NOP; unsigned opcode = TGSI_OPCODE_NOP;
@@ -2480,6 +2485,10 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir)
opcode = TGSI_OPCODE_TXF; opcode = TGSI_OPCODE_TXF;
ir->lod_info.lod->accept(this); ir->lod_info.lod->accept(this);
lod_info = this->result; lod_info = this->result;
if (ir->offset) {
ir->offset->accept(this);
offset = this->result;
}
break; break;
} }
@@ -2555,7 +2564,9 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir)
inst = emit(ir, opcode, result_dst, coord, dx, dy); inst = emit(ir, opcode, result_dst, coord, dx, dy);
else if (opcode == TGSI_OPCODE_TXQ) else if (opcode == TGSI_OPCODE_TXQ)
inst = emit(ir, opcode, result_dst, lod_info); 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); inst = emit(ir, opcode, result_dst, coord);
if (ir->shadow_comparitor) if (ir->shadow_comparitor)
@@ -2565,6 +2576,15 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir)
this->shader_program, this->shader_program,
this->prog); 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; const glsl_type *sampler_type = ir->sampler->type;
switch (sampler_type->sampler_dimensionality) { switch (sampler_type->sampler_dimensionality) {
@@ -4216,6 +4236,23 @@ translate_src(struct st_translate *t, const st_src_reg *src_reg)
return src; 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 static void
compile_tgsi_instruction(struct st_translate *t, compile_tgsi_instruction(struct st_translate *t,
const glsl_to_tgsi_instruction *inst) const glsl_to_tgsi_instruction *inst)
@@ -4224,6 +4261,8 @@ compile_tgsi_instruction(struct st_translate *t,
GLuint i; GLuint i;
struct ureg_dst dst[1]; struct ureg_dst dst[1];
struct ureg_src src[4]; struct ureg_src src[4];
struct tgsi_texture_offset texoffsets[MAX_GLSL_TEXTURE_OFFSET];
unsigned num_dst; unsigned num_dst;
unsigned num_src; unsigned num_src;
@@ -4260,10 +4299,14 @@ compile_tgsi_instruction(struct st_translate *t,
case TGSI_OPCODE_TXQ: case TGSI_OPCODE_TXQ:
case TGSI_OPCODE_TXF: case TGSI_OPCODE_TXF:
src[num_src++] = t->samplers[inst->sampler]; 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, ureg_tex_insn(ureg,
inst->op, inst->op,
dst, num_dst, dst, num_dst,
translate_texture_target(inst->tex_target, inst->tex_shadow), translate_texture_target(inst->tex_target, inst->tex_shadow),
texoffsets, inst->tex_offset_num_offset,
src, num_src); src, num_src);
return; return;

View File

@@ -705,6 +705,7 @@ compile_instruction(
dst, num_dst, dst, num_dst,
translate_texture_target( inst->TexSrcTarget, translate_texture_target( inst->TexSrcTarget,
inst->TexShadow ), inst->TexShadow ),
NULL, 0,
src, num_src ); src, num_src );
return; return;