summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2011-08-26 10:59:18 +0100
committerDave Airlie <airlied@redhat.com>2011-09-02 10:47:45 +0100
commit2083a276eb270b748d1c2668eb9faa5aadc8e700 (patch)
treefa03d01ecdba21bab656cf5e9f274ee2b0db7f83 /src/gallium
parent49e24d3b8c0129e11fcc94b6e74dc2589d64c882 (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.c64
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_dump.c11
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_exec.c22
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_exec.h3
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_parse.c3
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_parse.h2
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_ureg.c24
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_ureg.h12
-rw-r--r--src/gallium/docs/source/tgsi.rst13
-rw-r--r--src/gallium/drivers/softpipe/sp_tex_sample.c17
-rw-r--r--src/gallium/include/pipe/p_shader_tokens.h20
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;
};
/*