From: Dave Airlie <[email protected]> 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 <[email protected]> --- 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 _______________________________________________ mesa-dev mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/mesa-dev
