{
uint size = parse.FullToken.FullImmediate.Immediate.NrTokens - 1;
assert( size <= 4 );
- assert( mach->ImmLimit + 1 <= TGSI_EXEC_NUM_IMMEDIATES );
+ if (mach->ImmLimit >= mach->ImmsReserved) {
+ unsigned newReserved = mach->ImmsReserved ? 2 * mach->ImmsReserved : 128;
+ float4 *imms = REALLOC(mach->Imms, mach->ImmsReserved, newReserved * sizeof(float4));
+ if (imms) {
+ mach->ImmsReserved = newReserved;
+ mach->Imms = imms;
+ } else {
+ debug_printf("Unable to (re)allocate space for immidiate constants\n");
+ break;
+ }
+ }
for( i = 0; i < size; i++ ) {
mach->Imms[mach->ImmLimit][i] =
if (mach) {
FREE(mach->Instructions);
FREE(mach->Declarations);
+ FREE(mach->Imms);
align_free(mach->Inputs);
align_free(mach->Outputs);
static void
fetch_src_file_channel(const struct tgsi_exec_machine *mach,
- const uint chan_index,
const uint file,
const uint swizzle,
const union tgsi_exec_channel *index,
fetch_source_d(const struct tgsi_exec_machine *mach,
union tgsi_exec_channel *chan,
const struct tgsi_full_src_register *reg,
- const uint chan_index,
- enum tgsi_exec_datatype src_datatype)
+ const uint chan_index)
{
union tgsi_exec_channel index;
union tgsi_exec_channel index2D;
/* get current value of address register[swizzle] */
swizzle = reg->Indirect.Swizzle;
fetch_src_file_channel(mach,
- chan_index,
reg->Indirect.File,
swizzle,
&index2,
swizzle = reg->DimIndirect.Swizzle;
fetch_src_file_channel(mach,
- chan_index,
reg->DimIndirect.File,
swizzle,
&index2,
swizzle = tgsi_util_get_full_src_register_swizzle( reg, chan_index );
fetch_src_file_channel(mach,
- chan_index,
reg->Register.File,
swizzle,
&index,
const uint chan_index,
enum tgsi_exec_datatype src_datatype)
{
- fetch_source_d(mach, chan, reg, chan_index, src_datatype);
+ fetch_source_d(mach, chan, reg, chan_index);
if (reg->Register.Absolute) {
if (src_datatype == TGSI_EXEC_DATA_FLOAT) {
store_dest_dstret(struct tgsi_exec_machine *mach,
const union tgsi_exec_channel *chan,
const struct tgsi_full_dst_register *reg,
- const struct tgsi_full_instruction *inst,
uint chan_index,
enum tgsi_exec_datatype dst_datatype)
{
/* fetch values from the address/indirection register */
fetch_src_file_channel(mach,
- chan_index,
reg->Indirect.File,
swizzle,
&index,
swizzle = reg->DimIndirect.Swizzle;
fetch_src_file_channel(mach,
- chan_index,
reg->DimIndirect.File,
swizzle,
&index2,
store_dest_double(struct tgsi_exec_machine *mach,
const union tgsi_exec_channel *chan,
const struct tgsi_full_dst_register *reg,
- const struct tgsi_full_instruction *inst,
uint chan_index,
enum tgsi_exec_datatype dst_datatype)
{
const uint execmask = mach->ExecMask;
int i;
- dst = store_dest_dstret(mach, chan, reg, inst, chan_index,
- dst_datatype);
+ dst = store_dest_dstret(mach, chan, reg, chan_index, dst_datatype);
if (!dst)
return;
const uint execmask = mach->ExecMask;
int i;
- dst = store_dest_dstret(mach, chan, reg, inst, chan_index,
- dst_datatype);
+ dst = store_dest_dstret(mach, chan, reg, chan_index, dst_datatype);
if (!dst)
return;
* Unconditional fragment kill/discard.
*/
static void
-exec_kill(struct tgsi_exec_machine *mach,
- const struct tgsi_full_instruction *inst)
+exec_kill(struct tgsi_exec_machine *mach)
{
uint kilmask; /* bit 0 = pixel 0, bit 1 = pixel 1, etc */
union tgsi_exec_channel index;
union tgsi_exec_channel offset[3];
index.i[0] = index.i[1] = index.i[2] = index.i[3] = inst->TexOffsets[0].Index;
- fetch_src_file_channel(mach, 0, inst->TexOffsets[0].File,
+ fetch_src_file_channel(mach, inst->TexOffsets[0].File,
inst->TexOffsets[0].SwizzleX, &index, &ZeroVec, &offset[0]);
- fetch_src_file_channel(mach, 0, inst->TexOffsets[0].File,
+ fetch_src_file_channel(mach, inst->TexOffsets[0].File,
inst->TexOffsets[0].SwizzleY, &index, &ZeroVec, &offset[1]);
- fetch_src_file_channel(mach, 0, inst->TexOffsets[0].File,
+ 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];
index2.i[3] = reg->Indirect.Index;
fetch_src_file_channel(mach,
- 0,
reg->Indirect.File,
reg->Indirect.Swizzle,
&index2,
assert(dim <= 4);
if (shadow_ref >= 0)
- assert(shadow_ref >= dim && shadow_ref < ARRAY_SIZE(args));
+ assert(shadow_ref >= dim && shadow_ref < (int)ARRAY_SIZE(args));
/* fetch modifier to the last argument */
if (modifier != TEX_MODIFIER_NONE) {
control = TGSI_SAMPLER_GATHER;
}
else {
- for (i = dim; i < ARRAY_SIZE(args); i++)
+ for (i = dim; i < (int)ARRAY_SIZE(args); i++)
args[i] = &ZeroVec;
}
exec_lodq(struct tgsi_exec_machine *mach,
const struct tgsi_full_instruction *inst)
{
- uint unit;
- int dim;
- int i;
+ uint resource_unit, sampler_unit;
+ unsigned dim;
+ unsigned i;
union tgsi_exec_channel coords[4];
const union tgsi_exec_channel *args[ARRAY_SIZE(coords)];
union tgsi_exec_channel r[2];
- unit = fetch_sampler_unit(mach, inst, 1);
- dim = tgsi_util_get_texture_coord_dim(inst->Texture.Texture);
+ resource_unit = fetch_sampler_unit(mach, inst, 1);
+ if (inst->Instruction.Opcode == TGSI_OPCODE_LOD) {
+ uint target = mach->SamplerViews[resource_unit].Resource;
+ dim = tgsi_util_get_texture_coord_dim(target);
+ sampler_unit = fetch_sampler_unit(mach, inst, 2);
+ } else {
+ dim = tgsi_util_get_texture_coord_dim(inst->Texture.Texture);
+ sampler_unit = resource_unit;
+ }
assert(dim <= ARRAY_SIZE(coords));
/* fetch coordinates */
for (i = 0; i < dim; i++) {
for (i = dim; i < ARRAY_SIZE(coords); i++) {
args[i] = &ZeroVec;
}
- mach->Sampler->query_lod(mach->Sampler, unit, unit,
+ mach->Sampler->query_lod(mach->Sampler, resource_unit, sampler_unit,
args[0]->f,
args[1]->f,
args[2]->f,
store_dest(mach, &r[1], &inst->Dst[0], inst, TGSI_CHAN_Y,
TGSI_EXEC_DATA_FLOAT);
}
+ if (inst->Instruction.Opcode == TGSI_OPCODE_LOD) {
+ unsigned char swizzles[4];
+ unsigned chan;
+ swizzles[0] = inst->Src[1].Register.SwizzleX;
+ swizzles[1] = inst->Src[1].Register.SwizzleY;
+ swizzles[2] = inst->Src[1].Register.SwizzleZ;
+ swizzles[3] = inst->Src[1].Register.SwizzleW;
+
+ for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
+ if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
+ if (swizzles[chan] >= 2) {
+ store_dest(mach, &ZeroVec,
+ &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_FLOAT);
+ } else {
+ store_dest(mach, &r[swizzles[chan]],
+ &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_FLOAT);
+ }
+ }
+ }
+ } else {
+ if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_X) {
+ store_dest(mach, &r[0], &inst->Dst[0], inst, TGSI_CHAN_X,
+ TGSI_EXEC_DATA_FLOAT);
+ }
+ if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Y) {
+ store_dest(mach, &r[1], &inst->Dst[0], inst, TGSI_CHAN_Y,
+ TGSI_EXEC_DATA_FLOAT);
+ }
+ }
}
static void
union tgsi_exec_channel src[2];
uint i;
- fetch_source_d(mach, &src[0], reg, chan_0, TGSI_EXEC_DATA_UINT);
- fetch_source_d(mach, &src[1], reg, chan_1, TGSI_EXEC_DATA_UINT);
+ fetch_source_d(mach, &src[0], reg, chan_0);
+ fetch_source_d(mach, &src[1], reg, chan_1);
for (i = 0; i < TGSI_QUAD_SIZE; i++) {
chan->u[i][0] = src[0].u[i];
}
}
- store_dest_double(mach, &dst[0], reg, inst, chan_0, TGSI_EXEC_DATA_UINT);
- if (chan_1 != -1)
- store_dest_double(mach, &dst[1], reg, inst, chan_1, TGSI_EXEC_DATA_UINT);
+ store_dest_double(mach, &dst[0], reg, chan_0, TGSI_EXEC_DATA_UINT);
+ if (chan_1 != (unsigned)-1)
+ store_dest_double(mach, &dst[1], reg, chan_1, TGSI_EXEC_DATA_UINT);
}
static void
break;
case TGSI_OPCODE_LDEXP:
- exec_scalar_binary(mach, inst, micro_ldexp, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_INT);
+ exec_vector_binary(mach, inst, micro_ldexp, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
break;
case TGSI_OPCODE_COS:
break;
case TGSI_OPCODE_KILL:
- exec_kill (mach, inst);
+ exec_kill (mach);
break;
case TGSI_OPCODE_KILL_IF:
assert(0);
break;
+ case TGSI_OPCODE_LOD:
+ exec_lodq(mach, inst);
+ break;
+
case TGSI_OPCODE_UARL:
exec_vector_unary(mach, inst, micro_uarl, TGSI_EXEC_DATA_INT, TGSI_EXEC_DATA_UINT);
break;