#include "util/u_math.h"
-#define FAST_MATH 1
+#define FAST_MATH 0
#define TILE_TOP_LEFT 0
#define TILE_TOP_RIGHT 1
if (mach->Processor == TGSI_PROCESSOR_GEOMETRY &&
!mach->UsedGeometryShader) {
- struct tgsi_exec_vector *inputs =
- align_malloc(sizeof(struct tgsi_exec_vector) *
- TGSI_MAX_PRIM_VERTICES * PIPE_MAX_ATTRIBS,
- 16);
- struct tgsi_exec_vector *outputs =
- align_malloc(sizeof(struct tgsi_exec_vector) *
- TGSI_MAX_TOTAL_VERTICES, 16);
+ struct tgsi_exec_vector *inputs;
+ struct tgsi_exec_vector *outputs;
+
+ inputs = align_malloc(sizeof(struct tgsi_exec_vector) *
+ TGSI_MAX_PRIM_VERTICES * PIPE_MAX_ATTRIBS,
+ 16);
if (!inputs)
return;
+
+ outputs = align_malloc(sizeof(struct tgsi_exec_vector) *
+ TGSI_MAX_TOTAL_VERTICES, 16);
+
if (!outputs) {
align_free(inputs);
return;
#define FETCH(VAL,INDEX,CHAN)\
fetch_source(mach, VAL, &inst->Src[INDEX], CHAN, TGSI_EXEC_DATA_FLOAT)
+#define IFETCH(VAL,INDEX,CHAN)\
+ fetch_source(mach, VAL, &inst->Src[INDEX], CHAN, TGSI_EXEC_DATA_INT)
+
/**
* Execute ARB-style KIL which is predicated by a src register.
switch (inst->Texture.Texture) {
case TGSI_TEXTURE_1D:
- case TGSI_TEXTURE_SHADOW1D:
FETCH(&r[0], 0, CHAN_X);
if (modifier == TEX_MODIFIER_PROJECTED) {
control,
&r[0], &r[1], &r[2], &r[3]); /* R, G, B, A */
break;
+ case TGSI_TEXTURE_SHADOW1D:
+ FETCH(&r[0], 0, CHAN_X);
+ FETCH(&r[2], 0, CHAN_Z);
+
+ if (modifier == TEX_MODIFIER_PROJECTED) {
+ micro_div(&r[0], &r[0], &r[3]);
+ }
+
+ fetch_texel(mach->Samplers[unit],
+ &r[0], &ZeroVec, &r[2], lod, /* S, T, P, LOD */
+ control,
+ &r[0], &r[1], &r[2], &r[3]); /* R, G, B, A */
+ break;
case TGSI_TEXTURE_2D:
case TGSI_TEXTURE_RECT:
micro_div(&r[0], &r[0], &r[3]);
}
+ fetch_texel(mach->Samplers[unit],
+ &r[0], &r[1], &ZeroVec, lod, /* S, T, P, LOD */
+ control,
+ &r[0], &r[1], &r[2], &r[3]); /* outputs */
+ break;
+ case TGSI_TEXTURE_SHADOW1D_ARRAY:
+ FETCH(&r[0], 0, CHAN_X);
+ FETCH(&r[1], 0, CHAN_Y);
+ FETCH(&r[2], 0, CHAN_Z);
+
+ if (modifier == TEX_MODIFIER_PROJECTED) {
+ micro_div(&r[0], &r[0], &r[3]);
+ }
+
fetch_texel(mach->Samplers[unit],
&r[0], &r[1], &r[2], lod, /* S, T, P, LOD */
control,
control,
&r[0], &r[1], &r[2], &r[3]); /* outputs */
break;
+ case TGSI_TEXTURE_SHADOW2D_ARRAY:
+ FETCH(&r[0], 0, CHAN_X);
+ FETCH(&r[1], 0, CHAN_Y);
+ FETCH(&r[2], 0, CHAN_Z);
+ FETCH(&r[3], 0, CHAN_W);
+ fetch_texel(mach->Samplers[unit],
+ &r[0], &r[1], &r[2], &r[3], /* S, T, P, LOD */
+ control,
+ &r[0], &r[1], &r[2], &r[3]); /* outputs */
+ break;
case TGSI_TEXTURE_3D:
case TGSI_TEXTURE_CUBE:
FETCH(&r[0], 0, CHAN_X);
&r[0], &r[1], &r[2], &r[3]); /* R, G, B, A */
break;
+ case TGSI_TEXTURE_1D_ARRAY:
case TGSI_TEXTURE_2D:
case TGSI_TEXTURE_RECT:
+ case TGSI_TEXTURE_SHADOW1D_ARRAY:
case TGSI_TEXTURE_SHADOW2D:
case TGSI_TEXTURE_SHADOWRECT:
&r[0], &r[1], &r[2], &r[3]); /* outputs */
break;
+ case TGSI_TEXTURE_2D_ARRAY:
case TGSI_TEXTURE_3D:
case TGSI_TEXTURE_CUBE:
&r[0], &r[1], &r[2], &r[3]);
break;
+ case TGSI_TEXTURE_SHADOW2D_ARRAY:
+
+ FETCH(&r[0], 0, CHAN_X);
+ FETCH(&r[1], 0, CHAN_Y);
+ FETCH(&r[2], 0, CHAN_Z);
+ FETCH(&r[3], 0, CHAN_W);
+
+ fetch_texel(mach->Samplers[unit],
+ &r[0], &r[1], &r[2], &r[3],
+ tgsi_sampler_lod_bias,
+ &r[0], &r[1], &r[2], &r[3]);
+ break;
+
default:
assert(0);
}
}
+static void
+exec_txf(struct tgsi_exec_machine *mach,
+ const struct tgsi_full_instruction *inst)
+{
+ struct tgsi_sampler *sampler;
+ 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);
+
+ switch(inst->Texture.Texture) {
+ case TGSI_TEXTURE_3D:
+ case TGSI_TEXTURE_2D_ARRAY:
+ case TGSI_TEXTURE_SHADOW2D_ARRAY:
+ IFETCH(&r[2], 0, CHAN_Z);
+ /* fallthrough */
+ case TGSI_TEXTURE_2D:
+ case TGSI_TEXTURE_RECT:
+ case TGSI_TEXTURE_SHADOW1D_ARRAY:
+ case TGSI_TEXTURE_SHADOW2D:
+ case TGSI_TEXTURE_SHADOWRECT:
+ case TGSI_TEXTURE_1D_ARRAY:
+ IFETCH(&r[1], 0, CHAN_Y);
+ /* fallthrough */
+ case TGSI_TEXTURE_1D:
+ case TGSI_TEXTURE_SHADOW1D:
+ IFETCH(&r[0], 0, CHAN_X);
+ break;
+ default:
+ assert(0);
+ break;
+ }
+
+ sampler = mach->Samplers[unit];
+ 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];
+ r[1].f[j] = rgba[1][j];
+ r[2].f[j] = rgba[2][j];
+ r[3].f[j] = rgba[3][j];
+ }
+
+ for (chan = 0; chan < NUM_CHANNELS; chan++) {
+ if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
+ store_dest(mach, &r[chan], &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_FLOAT);
+ }
+ }
+}
+
+static void
+exec_txq(struct tgsi_exec_machine *mach,
+ const struct tgsi_full_instruction *inst)
+{
+ struct tgsi_sampler *sampler;
+ const uint unit = inst->Src[1].Register.Index;
+ int result[4];
+ union tgsi_exec_channel r[4], src;
+ uint chan;
+ int i,j;
+
+ fetch_source(mach, &src, &inst->Src[0], CHAN_X, TGSI_EXEC_DATA_INT);
+ sampler = mach->Samplers[unit];
+
+ sampler->get_dims(sampler, src.i[0], result);
+
+ for (i = 0; i < QUAD_SIZE; i++) {
+ for (j = 0; j < 4; j++) {
+ r[j].i[i] = result[j];
+ }
+ }
+
+ for (chan = 0; chan < NUM_CHANNELS; chan++) {
+ if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
+ store_dest(mach, &r[chan], &inst->Dst[0], inst, chan,
+ TGSI_EXEC_DATA_INT);
+ }
+ }
+}
static void
exec_sample(struct tgsi_exec_machine *mach,
&r[0], &r[1], &r[2], &r[3]); /* R, G, B, A */
break;
+ case TGSI_TEXTURE_1D_ARRAY:
case TGSI_TEXTURE_2D:
case TGSI_TEXTURE_RECT:
+ case TGSI_TEXTURE_SHADOW1D_ARRAY:
case TGSI_TEXTURE_SHADOW2D:
case TGSI_TEXTURE_SHADOWRECT:
FETCH(&r[0], 0, CHAN_X);
&r[0], &r[1], &r[2], &r[3]); /* outputs */
break;
+ case TGSI_TEXTURE_2D_ARRAY:
case TGSI_TEXTURE_3D:
case TGSI_TEXTURE_CUBE:
FETCH(&r[0], 0, CHAN_X);
&r[0], &r[1], &r[2], &r[3]);
break;
+ case TGSI_TEXTURE_SHADOW2D_ARRAY:
+ FETCH(&r[0], 0, CHAN_X);
+ FETCH(&r[1], 0, CHAN_Y);
+ FETCH(&r[2], 0, CHAN_Z);
+ FETCH(&r[3], 0, CHAN_W);
+
+ assert(modifier != TEX_MODIFIER_PROJECTED);
+
+ fetch_texel(mach->Samplers[sampler_unit],
+ &r[0], &r[1], &r[2], &r[3],
+ control,
+ &r[0], &r[1], &r[2], &r[3]);
+ break;
+
default:
assert(0);
}
union tgsi_exec_channel r[3];
union tgsi_exec_channel d[3];
- if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_X) {
- store_dest(mach, &OneVec, &inst->Dst[0], inst, CHAN_X, TGSI_EXEC_DATA_FLOAT);
- }
if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_YZ) {
fetch_source(mach, &r[0], &inst->Src[0], CHAN_X, TGSI_EXEC_DATA_FLOAT);
- if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Y) {
- micro_max(&d[CHAN_Y], &r[0], &ZeroVec);
- store_dest(mach, &d[CHAN_Y], &inst->Dst[0], inst, CHAN_Y, TGSI_EXEC_DATA_FLOAT);
- }
-
if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Z) {
fetch_source(mach, &r[1], &inst->Src[0], CHAN_Y, TGSI_EXEC_DATA_FLOAT);
micro_max(&r[1], &r[1], &ZeroVec);
micro_lt(&d[CHAN_Z], &ZeroVec, &r[0], &r[1], &ZeroVec);
store_dest(mach, &d[CHAN_Z], &inst->Dst[0], inst, CHAN_Z, TGSI_EXEC_DATA_FLOAT);
}
+ if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Y) {
+ micro_max(&d[CHAN_Y], &r[0], &ZeroVec);
+ store_dest(mach, &d[CHAN_Y], &inst->Dst[0], inst, CHAN_Y, TGSI_EXEC_DATA_FLOAT);
+ }
+ }
+ if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_X) {
+ store_dest(mach, &OneVec, &inst->Dst[0], inst, CHAN_X, TGSI_EXEC_DATA_FLOAT);
}
+
if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_W) {
store_dest(mach, &OneVec, &inst->Dst[0], inst, CHAN_W, TGSI_EXEC_DATA_FLOAT);
}
dst->u[3] = src0->u[3] ^ src1->u[3];
}
+static void
+micro_mod(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src0,
+ const union tgsi_exec_channel *src1)
+{
+ dst->i[0] = src0->i[0] % src1->i[0];
+ dst->i[1] = src0->i[1] % src1->i[1];
+ dst->i[2] = src0->i[2] % src1->i[2];
+ dst->i[3] = src0->i[3] % src1->i[3];
+}
+
static void
micro_f2i(union tgsi_exec_channel *dst,
const union tgsi_exec_channel *src)
dst->u[3] = src0->u[3] != src1->u[3] ? ~0 : 0;
}
+static void
+micro_uarl(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->i[0] = src->u[0];
+ dst->i[1] = src->u[1];
+ dst->i[2] = src->u[2];
+ dst->i[3] = src->u[3];
+}
+
+static void
+micro_ucmp(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src0,
+ const union tgsi_exec_channel *src1,
+ const union tgsi_exec_channel *src2)
+{
+ dst->u[0] = src0->u[0] ? src1->u[0] : src2->u[0];
+ dst->u[1] = src0->u[1] ? src1->u[1] : src2->u[1];
+ dst->u[2] = src0->u[2] ? src1->u[2] : src2->u[2];
+ dst->u[3] = src0->u[3] ? src1->u[3] : src2->u[3];
+}
+
static void
exec_instruction(
struct tgsi_exec_machine *mach,
break;
case TGSI_OPCODE_MOD:
- assert (0);
+ exec_vector_binary(mach, inst, micro_mod, TGSI_EXEC_DATA_INT, TGSI_EXEC_DATA_INT);
break;
case TGSI_OPCODE_XOR:
break;
case TGSI_OPCODE_TXF:
- assert (0);
+ exec_txf(mach, inst);
break;
case TGSI_OPCODE_TXQ:
- assert (0);
+ exec_txq(mach, inst);
break;
case TGSI_OPCODE_EMIT:
assert(0);
break;
+ case TGSI_OPCODE_UARL:
+ exec_vector_unary(mach, inst, micro_uarl, TGSI_EXEC_DATA_INT, TGSI_EXEC_DATA_UINT);
+ break;
+
+ case TGSI_OPCODE_UCMP:
+ exec_vector_trinary(mach, inst, micro_ucmp, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
+ break;
+
+ case TGSI_OPCODE_IABS:
+ exec_vector_unary(mach, inst, micro_iabs, TGSI_EXEC_DATA_INT, TGSI_EXEC_DATA_INT);
+ break;
+
default:
assert( 0 );
}