[Mesa-dev] [PATCH] gallium/tgsi: add offset to TXF
Dave Airlie
airlied at gmail.com
Fri Aug 26 03:50:08 PDT 2011
From: Dave Airlie <airlied at redhat.com>
In order to implement the GLSL texelFetchOffset I needed to modify TXF
(which wasn't defined anyways). It now corresponds to the NV_gpu_shader4.
I've limited things to a u8, since hw can only do about 4-5 bits, since
that is what DX specifies, TGSI passes stuff in an immediate so its not a
problem there, if we need to change the tgsi_exec/driver interface later
it isn't a major problem.
Signed-off-by: Dave Airlie <airlied at redhat.com>
---
src/gallium/auxiliary/tgsi/tgsi_exec.c | 15 +++++++++++++--
src/gallium/auxiliary/tgsi/tgsi_exec.h | 3 ++-
src/gallium/auxiliary/tgsi/tgsi_info.c | 2 +-
src/gallium/docs/source/tgsi.rst | 13 ++++++++++---
src/gallium/drivers/softpipe/sp_tex_sample.c | 17 ++++++++++++-----
src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 11 +++++++++--
6 files changed, 47 insertions(+), 14 deletions(-)
diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c
index 38dc1ef..9cb13f4 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c
@@ -1929,11 +1929,21 @@ 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];
+
+ IFETCH(&offset[0], 1, CHAN_X);
+ IFETCH(&offset[1], 1, CHAN_Y);
+ IFETCH(&offset[2], 1, CHAN_Z);
+
+ offsets[0] = offset[0].i[0];
+ offsets[1] = offset[1].i[0];
+ offsets[2] = offset[2].i[0];
IFETCH(&r[3], 0, CHAN_W);
@@ -1959,7 +1969,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_info.c b/src/gallium/auxiliary/tgsi/tgsi_info.c
index 14ed56a..fa00b2d 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_info.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_info.c
@@ -125,7 +125,7 @@ static const struct tgsi_opcode_info opcode_info[TGSI_OPCODE_LAST] =
{ 1, 2, 0, 0, 0, 0, "MOD", TGSI_OPCODE_MOD },
{ 1, 2, 0, 0, 0, 0, "XOR", TGSI_OPCODE_XOR },
{ 1, 3, 0, 0, 0, 0, "SAD", TGSI_OPCODE_SAD },
- { 1, 2, 1, 0, 0, 0, "TXF", TGSI_OPCODE_TXF },
+ { 1, 3, 1, 0, 0, 0, "TXF", TGSI_OPCODE_TXF },
{ 1, 2, 1, 0, 0, 0, "TXQ", TGSI_OPCODE_TXQ },
{ 0, 0, 0, 0, 0, 0, "CONT", TGSI_OPCODE_CONT },
{ 0, 0, 0, 0, 0, 0, "EMIT", TGSI_OPCODE_EMIT },
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/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index 9cac309..6364fb1 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -2421,7 +2421,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 +2480,11 @@ 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;
+ } else
+ offset = st_src_reg_for_int(0);
break;
}
@@ -2555,7 +2560,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, offset);
+ } else
inst = emit(ir, opcode, result_dst, coord);
if (ir->shadow_comparitor)
--
1.7.6
More information about the mesa-dev
mailing list