diff options
author | Dave Airlie <airlied@redhat.com> | 2011-08-26 10:59:18 +0100 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2011-09-02 10:47:45 +0100 |
commit | 2083a276eb270b748d1c2668eb9faa5aadc8e700 (patch) | |
tree | fa03d01ecdba21bab656cf5e9f274ee2b0db7f83 /src/gallium | |
parent | 49e24d3b8c0129e11fcc94b6e74dc2589d64c882 (diff) |
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>
Diffstat (limited to 'src/gallium')
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_build.c | 64 | ||||
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_dump.c | 11 | ||||
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_exec.c | 22 | ||||
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_exec.h | 3 | ||||
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_parse.c | 3 | ||||
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_parse.h | 2 | ||||
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_ureg.c | 24 | ||||
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_ureg.h | 12 | ||||
-rw-r--r-- | src/gallium/docs/source/tgsi.rst | 13 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_tex_sample.c | 17 | ||||
-rw-r--r-- | src/gallium/include/pipe/p_shader_tokens.h | 20 |
11 files changed, 173 insertions, 18 deletions
diff --git a/src/gallium/auxiliary/tgsi/tgsi_build.c b/src/gallium/auxiliary/tgsi/tgsi_build.c index 269940ec840..6ec2b0d8f21 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_build.c +++ b/src/gallium/auxiliary/tgsi/tgsi_build.c @@ -631,6 +631,7 @@ tgsi_default_instruction_texture( void ) struct tgsi_instruction_texture instruction_texture; instruction_texture.Texture = TGSI_TEXTURE_UNKNOWN; + instruction_texture.NumOffsets = 0; instruction_texture.Padding = 0; return instruction_texture; @@ -639,6 +640,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,6 +648,7 @@ tgsi_build_instruction_texture( struct tgsi_instruction_texture instruction_texture; instruction_texture.Texture = texture; + instruction_texture.NumOffsets = num_offsets; instruction_texture.Padding = 0; instruction->Texture = 1; @@ -654,6 +657,43 @@ tgsi_build_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 tgsi_default_src_register( void ) { @@ -825,6 +865,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 +951,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 c12662076b1..7e2825e9ce1 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 38dc1efa551..fd118c5bb11 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 3f6964c17fb..a7507157906 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 fb36f9de32d..e1902eb1862 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 b7a3c9bc0e6..f7b7e6edc98 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 a920741c36b..cada435aee7 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 e3a4915d03c..8f5f22e1750 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 039cb1c03d5..5cf08752e75 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 89c6536b1f4..dd33a10a1a6 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 d3a3632654c..72d3139562e 100644 --- a/src/gallium/include/pipe/p_shader_tokens.h +++ b/src/gallium/include/pipe/p_shader_tokens.h @@ -401,6 +401,8 @@ struct tgsi_instruction * If tgsi_instruction::Label is TRUE, tgsi_instruction_label 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. * @@ -437,7 +439,23 @@ struct tgsi_instruction_label struct tgsi_instruction_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; }; /* |