#include "util/u_half.h"
#include "util/u_memory.h"
#include "util/u_math.h"
+#include "util/rounding.h"
#define DEBUG_EXECUTION 0
union tgsi_double_channel {
double d[TGSI_QUAD_SIZE];
unsigned u[TGSI_QUAD_SIZE][2];
+ uint64_t u64[TGSI_QUAD_SIZE];
+ int64_t i64[TGSI_QUAD_SIZE];
};
struct tgsi_double_vector {
dst->f[3] = ceilf(src->f[3]);
}
-static void
-micro_clamp(union tgsi_exec_channel *dst,
- const union tgsi_exec_channel *src0,
- const union tgsi_exec_channel *src1,
- const union tgsi_exec_channel *src2)
-{
- dst->f[0] = src0->f[0] < src1->f[0] ? src1->f[0] : src0->f[0] > src2->f[0] ? src2->f[0] : src0->f[0];
- dst->f[1] = src0->f[1] < src1->f[1] ? src1->f[1] : src0->f[1] > src2->f[1] ? src2->f[1] : src0->f[1];
- dst->f[2] = src0->f[2] < src1->f[2] ? src1->f[2] : src0->f[2] > src2->f[2] ? src2->f[2] : src0->f[2];
- dst->f[3] = src0->f[3] < src1->f[3] ? src1->f[3] : src0->f[3] > src2->f[3] ? src2->f[3] : src0->f[3];
-}
-
static void
micro_cmp(union tgsi_exec_channel *dst,
const union tgsi_exec_channel *src0,
dst->d[3] = src[0].d[3] + src[1].d[3];
}
+static void
+micro_ddiv(union tgsi_double_channel *dst,
+ const union tgsi_double_channel *src)
+{
+ dst->d[0] = src[0].d[0] / src[1].d[0];
+ dst->d[1] = src[0].d[1] / src[1].d[1];
+ dst->d[2] = src[0].d[2] / src[1].d[2];
+ dst->d[3] = src[0].d[3] / src[1].d[3];
+}
+
static void
micro_ddx(union tgsi_exec_channel *dst,
const union tgsi_exec_channel *src)
micro_rnd(union tgsi_exec_channel *dst,
const union tgsi_exec_channel *src)
{
- dst->f[0] = floorf(src->f[0] + 0.5f);
- dst->f[1] = floorf(src->f[1] + 0.5f);
- dst->f[2] = floorf(src->f[2] + 0.5f);
- dst->f[3] = floorf(src->f[3] + 0.5f);
+ dst->f[0] = _mesa_roundevenf(src->f[0]);
+ dst->f[1] = _mesa_roundevenf(src->f[1]);
+ dst->f[2] = _mesa_roundevenf(src->f[2]);
+ dst->f[3] = _mesa_roundevenf(src->f[3]);
}
static void
micro_trunc(union tgsi_exec_channel *dst,
const union tgsi_exec_channel *src)
{
- dst->f[0] = (float)(int)src->f[0];
- dst->f[1] = (float)(int)src->f[1];
- dst->f[2] = (float)(int)src->f[2];
- dst->f[3] = (float)(int)src->f[3];
+ dst->f[0] = truncf(src->f[0]);
+ dst->f[1] = truncf(src->f[1]);
+ dst->f[2] = truncf(src->f[2]);
+ dst->f[3] = truncf(src->f[3]);
}
static void
dst->d[3] = (double)src->u[3];
}
+static void
+micro_i64abs(union tgsi_double_channel *dst,
+ const union tgsi_double_channel *src)
+{
+ dst->i64[0] = src->i64[0] >= 0.0 ? src->i64[0] : -src->i64[0];
+ dst->i64[1] = src->i64[1] >= 0.0 ? src->i64[1] : -src->i64[1];
+ dst->i64[2] = src->i64[2] >= 0.0 ? src->i64[2] : -src->i64[2];
+ dst->i64[3] = src->i64[3] >= 0.0 ? src->i64[3] : -src->i64[3];
+}
+
+static void
+micro_i64sgn(union tgsi_double_channel *dst,
+ const union tgsi_double_channel *src)
+{
+ dst->i64[0] = src->i64[0] < 0 ? -1 : src->i64[0] > 0 ? 1 : 0;
+ dst->i64[1] = src->i64[1] < 0 ? -1 : src->i64[1] > 0 ? 1 : 0;
+ dst->i64[2] = src->i64[2] < 0 ? -1 : src->i64[2] > 0 ? 1 : 0;
+ dst->i64[3] = src->i64[3] < 0 ? -1 : src->i64[3] > 0 ? 1 : 0;
+}
+
+static void
+micro_i64neg(union tgsi_double_channel *dst,
+ const union tgsi_double_channel *src)
+{
+ dst->i64[0] = -src->i64[0];
+ dst->i64[1] = -src->i64[1];
+ dst->i64[2] = -src->i64[2];
+ dst->i64[3] = -src->i64[3];
+}
+
+static void
+micro_u64seq(union tgsi_double_channel *dst,
+ const union tgsi_double_channel *src)
+{
+ dst->u[0][0] = src[0].u64[0] == src[1].u64[0] ? ~0U : 0U;
+ dst->u[1][0] = src[0].u64[1] == src[1].u64[1] ? ~0U : 0U;
+ dst->u[2][0] = src[0].u64[2] == src[1].u64[2] ? ~0U : 0U;
+ dst->u[3][0] = src[0].u64[3] == src[1].u64[3] ? ~0U : 0U;
+}
+
+static void
+micro_u64sne(union tgsi_double_channel *dst,
+ const union tgsi_double_channel *src)
+{
+ dst->u[0][0] = src[0].u64[0] != src[1].u64[0] ? ~0U : 0U;
+ dst->u[1][0] = src[0].u64[1] != src[1].u64[1] ? ~0U : 0U;
+ dst->u[2][0] = src[0].u64[2] != src[1].u64[2] ? ~0U : 0U;
+ dst->u[3][0] = src[0].u64[3] != src[1].u64[3] ? ~0U : 0U;
+}
+
+static void
+micro_i64slt(union tgsi_double_channel *dst,
+ const union tgsi_double_channel *src)
+{
+ dst->u[0][0] = src[0].i64[0] < src[1].i64[0] ? ~0U : 0U;
+ dst->u[1][0] = src[0].i64[1] < src[1].i64[1] ? ~0U : 0U;
+ dst->u[2][0] = src[0].i64[2] < src[1].i64[2] ? ~0U : 0U;
+ dst->u[3][0] = src[0].i64[3] < src[1].i64[3] ? ~0U : 0U;
+}
+
+static void
+micro_u64slt(union tgsi_double_channel *dst,
+ const union tgsi_double_channel *src)
+{
+ dst->u[0][0] = src[0].u64[0] < src[1].u64[0] ? ~0U : 0U;
+ dst->u[1][0] = src[0].u64[1] < src[1].u64[1] ? ~0U : 0U;
+ dst->u[2][0] = src[0].u64[2] < src[1].u64[2] ? ~0U : 0U;
+ dst->u[3][0] = src[0].u64[3] < src[1].u64[3] ? ~0U : 0U;
+}
+
+static void
+micro_i64sge(union tgsi_double_channel *dst,
+ const union tgsi_double_channel *src)
+{
+ dst->u[0][0] = src[0].i64[0] >= src[1].i64[0] ? ~0U : 0U;
+ dst->u[1][0] = src[0].i64[1] >= src[1].i64[1] ? ~0U : 0U;
+ dst->u[2][0] = src[0].i64[2] >= src[1].i64[2] ? ~0U : 0U;
+ dst->u[3][0] = src[0].i64[3] >= src[1].i64[3] ? ~0U : 0U;
+}
+
+static void
+micro_u64sge(union tgsi_double_channel *dst,
+ const union tgsi_double_channel *src)
+{
+ dst->u[0][0] = src[0].u64[0] >= src[1].u64[0] ? ~0U : 0U;
+ dst->u[1][0] = src[0].u64[1] >= src[1].u64[1] ? ~0U : 0U;
+ dst->u[2][0] = src[0].u64[2] >= src[1].u64[2] ? ~0U : 0U;
+ dst->u[3][0] = src[0].u64[3] >= src[1].u64[3] ? ~0U : 0U;
+}
+
+static void
+micro_u64max(union tgsi_double_channel *dst,
+ const union tgsi_double_channel *src)
+{
+ dst->u64[0] = src[0].u64[0] > src[1].u64[0] ? src[0].u64[0] : src[1].u64[0];
+ dst->u64[1] = src[0].u64[1] > src[1].u64[1] ? src[0].u64[1] : src[1].u64[1];
+ dst->u64[2] = src[0].u64[2] > src[1].u64[2] ? src[0].u64[2] : src[1].u64[2];
+ dst->u64[3] = src[0].u64[3] > src[1].u64[3] ? src[0].u64[3] : src[1].u64[3];
+}
+
+static void
+micro_i64max(union tgsi_double_channel *dst,
+ const union tgsi_double_channel *src)
+{
+ dst->i64[0] = src[0].i64[0] > src[1].i64[0] ? src[0].i64[0] : src[1].i64[0];
+ dst->i64[1] = src[0].i64[1] > src[1].i64[1] ? src[0].i64[1] : src[1].i64[1];
+ dst->i64[2] = src[0].i64[2] > src[1].i64[2] ? src[0].i64[2] : src[1].i64[2];
+ dst->i64[3] = src[0].i64[3] > src[1].i64[3] ? src[0].i64[3] : src[1].i64[3];
+}
+
+static void
+micro_u64min(union tgsi_double_channel *dst,
+ const union tgsi_double_channel *src)
+{
+ dst->u64[0] = src[0].u64[0] < src[1].u64[0] ? src[0].u64[0] : src[1].u64[0];
+ dst->u64[1] = src[0].u64[1] < src[1].u64[1] ? src[0].u64[1] : src[1].u64[1];
+ dst->u64[2] = src[0].u64[2] < src[1].u64[2] ? src[0].u64[2] : src[1].u64[2];
+ dst->u64[3] = src[0].u64[3] < src[1].u64[3] ? src[0].u64[3] : src[1].u64[3];
+}
+
+static void
+micro_i64min(union tgsi_double_channel *dst,
+ const union tgsi_double_channel *src)
+{
+ dst->i64[0] = src[0].i64[0] < src[1].i64[0] ? src[0].i64[0] : src[1].i64[0];
+ dst->i64[1] = src[0].i64[1] < src[1].i64[1] ? src[0].i64[1] : src[1].i64[1];
+ dst->i64[2] = src[0].i64[2] < src[1].i64[2] ? src[0].i64[2] : src[1].i64[2];
+ dst->i64[3] = src[0].i64[3] < src[1].i64[3] ? src[0].i64[3] : src[1].i64[3];
+}
+
+static void
+micro_u64add(union tgsi_double_channel *dst,
+ const union tgsi_double_channel *src)
+{
+ dst->u64[0] = src[0].u64[0] + src[1].u64[0];
+ dst->u64[1] = src[0].u64[1] + src[1].u64[1];
+ dst->u64[2] = src[0].u64[2] + src[1].u64[2];
+ dst->u64[3] = src[0].u64[3] + src[1].u64[3];
+}
+
+static void
+micro_u64mul(union tgsi_double_channel *dst,
+ const union tgsi_double_channel *src)
+{
+ dst->u64[0] = src[0].u64[0] * src[1].u64[0];
+ dst->u64[1] = src[0].u64[1] * src[1].u64[1];
+ dst->u64[2] = src[0].u64[2] * src[1].u64[2];
+ dst->u64[3] = src[0].u64[3] * src[1].u64[3];
+}
+
+static void
+micro_u64div(union tgsi_double_channel *dst,
+ const union tgsi_double_channel *src)
+{
+ dst->u64[0] = src[1].u64[0] ? src[0].u64[0] / src[1].u64[0] : ~0ull;
+ dst->u64[1] = src[1].u64[1] ? src[0].u64[1] / src[1].u64[1] : ~0ull;
+ dst->u64[2] = src[1].u64[2] ? src[0].u64[2] / src[1].u64[2] : ~0ull;
+ dst->u64[3] = src[1].u64[3] ? src[0].u64[3] / src[1].u64[3] : ~0ull;
+}
+
+static void
+micro_i64div(union tgsi_double_channel *dst,
+ const union tgsi_double_channel *src)
+{
+ dst->i64[0] = src[1].i64[0] ? src[0].i64[0] / src[1].i64[0] : 0;
+ dst->i64[1] = src[1].i64[1] ? src[0].i64[1] / src[1].i64[1] : 0;
+ dst->i64[2] = src[1].i64[2] ? src[0].i64[2] / src[1].i64[2] : 0;
+ dst->i64[3] = src[1].i64[3] ? src[0].i64[3] / src[1].i64[3] : 0;
+}
+
+static void
+micro_u64mod(union tgsi_double_channel *dst,
+ const union tgsi_double_channel *src)
+{
+ dst->u64[0] = src[1].u64[0] ? src[0].u64[0] % src[1].u64[0] : ~0ull;
+ dst->u64[1] = src[1].u64[1] ? src[0].u64[1] % src[1].u64[1] : ~0ull;
+ dst->u64[2] = src[1].u64[2] ? src[0].u64[2] % src[1].u64[2] : ~0ull;
+ dst->u64[3] = src[1].u64[3] ? src[0].u64[3] % src[1].u64[3] : ~0ull;
+}
+
+static void
+micro_i64mod(union tgsi_double_channel *dst,
+ const union tgsi_double_channel *src)
+{
+ dst->i64[0] = src[1].i64[0] ? src[0].i64[0] % src[1].i64[0] : ~0ll;
+ dst->i64[1] = src[1].i64[1] ? src[0].i64[1] % src[1].i64[1] : ~0ll;
+ dst->i64[2] = src[1].i64[2] ? src[0].i64[2] % src[1].i64[2] : ~0ll;
+ dst->i64[3] = src[1].i64[3] ? src[0].i64[3] % src[1].i64[3] : ~0ll;
+}
+
+static void
+micro_u64shl(union tgsi_double_channel *dst,
+ const union tgsi_double_channel *src0,
+ union tgsi_exec_channel *src1)
+{
+ unsigned masked_count;
+ masked_count = src1->u[0] & 0x3f;
+ dst->u64[0] = src0->u64[0] << masked_count;
+ masked_count = src1->u[1] & 0x3f;
+ dst->u64[1] = src0->u64[1] << masked_count;
+ masked_count = src1->u[2] & 0x3f;
+ dst->u64[2] = src0->u64[2] << masked_count;
+ masked_count = src1->u[3] & 0x3f;
+ dst->u64[3] = src0->u64[3] << masked_count;
+}
+
+static void
+micro_i64shr(union tgsi_double_channel *dst,
+ const union tgsi_double_channel *src0,
+ union tgsi_exec_channel *src1)
+{
+ unsigned masked_count;
+ masked_count = src1->u[0] & 0x3f;
+ dst->i64[0] = src0->i64[0] >> masked_count;
+ masked_count = src1->u[1] & 0x3f;
+ dst->i64[1] = src0->i64[1] >> masked_count;
+ masked_count = src1->u[2] & 0x3f;
+ dst->i64[2] = src0->i64[2] >> masked_count;
+ masked_count = src1->u[3] & 0x3f;
+ dst->i64[3] = src0->i64[3] >> masked_count;
+}
+
+static void
+micro_u64shr(union tgsi_double_channel *dst,
+ const union tgsi_double_channel *src0,
+ union tgsi_exec_channel *src1)
+{
+ unsigned masked_count;
+ masked_count = src1->u[0] & 0x3f;
+ dst->u64[0] = src0->u64[0] >> masked_count;
+ masked_count = src1->u[1] & 0x3f;
+ dst->u64[1] = src0->u64[1] >> masked_count;
+ masked_count = src1->u[2] & 0x3f;
+ dst->u64[2] = src0->u64[2] >> masked_count;
+ masked_count = src1->u[3] & 0x3f;
+ dst->u64[3] = src0->u64[3] >> masked_count;
+}
+
enum tgsi_exec_datatype {
TGSI_EXEC_DATA_FLOAT,
TGSI_EXEC_DATA_INT,
TGSI_EXEC_DATA_UINT,
- TGSI_EXEC_DATA_DOUBLE
+ TGSI_EXEC_DATA_DOUBLE,
+ TGSI_EXEC_DATA_INT64,
+ TGSI_EXEC_DATA_UINT64,
};
/*
mach->ImmLimit = 0;
mach->NumOutputs = 0;
+ for (k = 0; k < TGSI_SEMANTIC_COUNT; k++)
+ mach->SysSemanticToIndex[k] = -1;
+
if (mach->ShaderType == PIPE_SHADER_GEOMETRY &&
!mach->UsedGeometryShader) {
struct tgsi_exec_vector *inputs;
{
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] =
mach->ShaderType = shader_type;
mach->Addrs = &mach->Temps[TGSI_EXEC_TEMP_ADDR];
mach->MaxGeometryShaderOutputs = TGSI_MAX_TOTAL_VERTICES;
- mach->Predicates = &mach->Temps[TGSI_EXEC_TEMP_P0];
if (shader_type != PIPE_SHADER_COMPUTE) {
mach->Inputs = align_malloc(sizeof(struct tgsi_exec_vector) * PIPE_MAX_SHADER_INPUTS, 16);
if (mach) {
FREE(mach->Instructions);
FREE(mach->Declarations);
+ FREE(mach->Imms);
align_free(mach->Inputs);
align_free(mach->Outputs);
#endif
}
+static void
+micro_ldexp(union tgsi_exec_channel *dst,
+ const union tgsi_exec_channel *src0,
+ const union tgsi_exec_channel *src1)
+{
+ dst->f[0] = ldexpf(src0->f[0], src1->i[0]);
+ dst->f[1] = ldexpf(src0->f[1], src1->i[1]);
+ dst->f[2] = ldexpf(src0->f[2], src1->i[2]);
+ dst->f[3] = ldexpf(src0->f[3], src1->i[3]);
+}
+
static void
micro_sub(union tgsi_exec_channel *dst,
const union tgsi_exec_channel *src0,
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,
}
break;
- case TGSI_FILE_PREDICATE:
- for (i = 0; i < TGSI_QUAD_SIZE; i++) {
- assert(index->i[i] >= 0 && index->i[i] < TGSI_EXEC_NUM_PREDS);
- assert(index2D->i[i] == 0);
-
- chan->u[i] = mach->Predicates[0].xyzw[swizzle].u[i];
- }
- break;
-
case TGSI_FILE_OUTPUT:
/* vertex/fragment output vars can be read too */
for (i = 0; i < TGSI_QUAD_SIZE; i++) {
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)
{
- uint i;
static union tgsi_exec_channel null;
union tgsi_exec_channel *dst;
union tgsi_exec_channel index2D;
- uint execmask = mach->ExecMask;
int offset = 0; /* indirection offset */
int index;
/* 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,
dst = &mach->Addrs[index].xyzw[chan_index];
break;
- case TGSI_FILE_PREDICATE:
- index = reg->Register.Index;
- assert(index < TGSI_EXEC_NUM_PREDS);
- dst = &mach->Predicates[index].xyzw[chan_index];
- break;
-
default:
assert( 0 );
return NULL;
}
- if (inst->Instruction.Predicate) {
- uint swizzle;
- union tgsi_exec_channel *pred;
-
- switch (chan_index) {
- case TGSI_CHAN_X:
- swizzle = inst->Predicate.SwizzleX;
- break;
- case TGSI_CHAN_Y:
- swizzle = inst->Predicate.SwizzleY;
- break;
- case TGSI_CHAN_Z:
- swizzle = inst->Predicate.SwizzleZ;
- break;
- case TGSI_CHAN_W:
- swizzle = inst->Predicate.SwizzleW;
- break;
- default:
- assert(0);
- return NULL;
- }
-
- assert(inst->Predicate.Index == 0);
-
- pred = &mach->Predicates[inst->Predicate.Index].xyzw[swizzle];
-
- if (inst->Predicate.Negate) {
- for (i = 0; i < TGSI_QUAD_SIZE; i++) {
- if (pred->u[i]) {
- execmask &= ~(1 << i);
- }
- }
- } else {
- for (i = 0; i < TGSI_QUAD_SIZE; i++) {
- if (!pred->u[i]) {
- execmask &= ~(1 << i);
- }
- }
- }
- }
-
return dst;
}
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 < Elements(args));
+ assert(shadow_ref >= dim && shadow_ref < (int)ARRAY_SIZE(args));
/* fetch modifier to the last argument */
if (modifier != TEX_MODIFIER_NONE) {
- const int last = Elements(args) - 1;
+ const int last = ARRAY_SIZE(args) - 1;
/* fetch modifier from src0.w or src1.x */
if (sampler == 1) {
control = TGSI_SAMPLER_GATHER;
}
else {
- for (i = dim; i < Elements(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[Elements(coords)];
+ 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);
- assert(dim <= Elements(coords));
+ 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++) {
FETCH(&coords[i], 0, TGSI_CHAN_X + i);
args[i] = &coords[i];
}
- for (i = dim; i < Elements(coords); 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
lod = &c1;
control = TGSI_SAMPLER_LOD_EXPLICIT;
}
+ else if (modifier == TEX_MODIFIER_GATHER) {
+ control = TGSI_SAMPLER_GATHER;
+ }
else {
assert(modifier == TEX_MODIFIER_LEVEL_ZERO);
control = TGSI_SAMPLER_LOD_ZERO;
}
}
-static void
-exec_dp2a(struct tgsi_exec_machine *mach,
- const struct tgsi_full_instruction *inst)
-{
- unsigned int chan;
- union tgsi_exec_channel arg[3];
-
- fetch_source(mach, &arg[0], &inst->Src[0], TGSI_CHAN_X, TGSI_EXEC_DATA_FLOAT);
- fetch_source(mach, &arg[1], &inst->Src[1], TGSI_CHAN_X, TGSI_EXEC_DATA_FLOAT);
- micro_mul(&arg[2], &arg[0], &arg[1]);
-
- fetch_source(mach, &arg[0], &inst->Src[0], TGSI_CHAN_Y, TGSI_EXEC_DATA_FLOAT);
- fetch_source(mach, &arg[1], &inst->Src[1], TGSI_CHAN_Y, TGSI_EXEC_DATA_FLOAT);
- micro_mad(&arg[0], &arg[0], &arg[1], &arg[2]);
-
- fetch_source(mach, &arg[1], &inst->Src[2], TGSI_CHAN_X, TGSI_EXEC_DATA_FLOAT);
- micro_add(&arg[0], &arg[0], &arg[1]);
-
- for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
- if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
- store_dest(mach, &arg[0], &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_FLOAT);
- }
- }
-}
-
-static void
-exec_dph(struct tgsi_exec_machine *mach,
- const struct tgsi_full_instruction *inst)
-{
- unsigned int chan;
- union tgsi_exec_channel arg[3];
-
- fetch_source(mach, &arg[0], &inst->Src[0], TGSI_CHAN_X, TGSI_EXEC_DATA_FLOAT);
- fetch_source(mach, &arg[1], &inst->Src[1], TGSI_CHAN_X, TGSI_EXEC_DATA_FLOAT);
- micro_mul(&arg[2], &arg[0], &arg[1]);
-
- fetch_source(mach, &arg[0], &inst->Src[0], TGSI_CHAN_Y, TGSI_EXEC_DATA_FLOAT);
- fetch_source(mach, &arg[1], &inst->Src[1], TGSI_CHAN_Y, TGSI_EXEC_DATA_FLOAT);
- micro_mad(&arg[2], &arg[0], &arg[1], &arg[2]);
-
- fetch_source(mach, &arg[0], &inst->Src[0], TGSI_CHAN_Z, TGSI_EXEC_DATA_FLOAT);
- fetch_source(mach, &arg[1], &inst->Src[1], TGSI_CHAN_Z, TGSI_EXEC_DATA_FLOAT);
- micro_mad(&arg[0], &arg[0], &arg[1], &arg[2]);
-
- fetch_source(mach, &arg[1], &inst->Src[1], TGSI_CHAN_W, TGSI_EXEC_DATA_FLOAT);
- micro_add(&arg[0], &arg[0], &arg[1]);
-
- for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
- if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
- store_dest(mach, &arg[0], &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_FLOAT);
- }
- }
-}
-
static void
exec_dp2(struct tgsi_exec_machine *mach,
const struct tgsi_full_instruction *inst)
}
static void
-exec_scs(struct tgsi_exec_machine *mach,
- const struct tgsi_full_instruction *inst)
+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->f[0] = src0->u[0] ? src1->f[0] : src2->f[0];
+ dst->f[1] = src0->u[1] ? src1->f[1] : src2->f[1];
+ dst->f[2] = src0->u[2] ? src1->f[2] : src2->f[2];
+ dst->f[3] = src0->u[3] ? src1->f[3] : src2->f[3];
+}
+
+static void
+exec_ucmp(struct tgsi_exec_machine *mach,
+ const struct tgsi_full_instruction *inst)
{
- if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_XY) {
- union tgsi_exec_channel arg;
- union tgsi_exec_channel result;
+ unsigned int chan;
+ struct tgsi_exec_vector dst;
- fetch_source(mach, &arg, &inst->Src[0], TGSI_CHAN_X, TGSI_EXEC_DATA_FLOAT);
+ for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
+ if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
+ union tgsi_exec_channel src[3];
- if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_X) {
- micro_cos(&result, &arg);
- store_dest(mach, &result, &inst->Dst[0], inst, TGSI_CHAN_X, TGSI_EXEC_DATA_FLOAT);
- }
- if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Y) {
- micro_sin(&result, &arg);
- store_dest(mach, &result, &inst->Dst[0], inst, TGSI_CHAN_Y, TGSI_EXEC_DATA_FLOAT);
+ fetch_source(mach, &src[0], &inst->Src[0], chan,
+ TGSI_EXEC_DATA_UINT);
+ fetch_source(mach, &src[1], &inst->Src[1], chan,
+ TGSI_EXEC_DATA_FLOAT);
+ fetch_source(mach, &src[2], &inst->Src[2], chan,
+ TGSI_EXEC_DATA_FLOAT);
+ micro_ucmp(&dst.xyzw[chan], &src[0], &src[1], &src[2]);
}
}
- if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Z) {
- store_dest(mach, &ZeroVec, &inst->Dst[0], inst, TGSI_CHAN_Z, TGSI_EXEC_DATA_FLOAT);
- }
- if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_W) {
- store_dest(mach, &OneVec, &inst->Dst[0], inst, TGSI_CHAN_W, TGSI_EXEC_DATA_FLOAT);
+ for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
+ if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
+ store_dest(mach, &dst.xyzw[chan], &inst->Dst[0], inst, chan,
+ TGSI_EXEC_DATA_FLOAT);
+ }
}
}
static void
-exec_xpd(struct tgsi_exec_machine *mach,
+exec_dst(struct tgsi_exec_machine *mach,
const struct tgsi_full_instruction *inst)
{
- union tgsi_exec_channel r[6];
- union tgsi_exec_channel d[3];
-
- fetch_source(mach, &r[0], &inst->Src[0], TGSI_CHAN_Y, TGSI_EXEC_DATA_FLOAT);
- fetch_source(mach, &r[1], &inst->Src[1], TGSI_CHAN_Z, TGSI_EXEC_DATA_FLOAT);
-
- micro_mul(&r[2], &r[0], &r[1]);
-
- fetch_source(mach, &r[3], &inst->Src[0], TGSI_CHAN_Z, TGSI_EXEC_DATA_FLOAT);
- fetch_source(mach, &r[4], &inst->Src[1], TGSI_CHAN_Y, TGSI_EXEC_DATA_FLOAT);
-
- micro_mul(&r[5], &r[3], &r[4] );
- micro_sub(&d[TGSI_CHAN_X], &r[2], &r[5]);
-
- fetch_source(mach, &r[2], &inst->Src[1], TGSI_CHAN_X, TGSI_EXEC_DATA_FLOAT);
-
- micro_mul(&r[3], &r[3], &r[2]);
-
- fetch_source(mach, &r[5], &inst->Src[0], TGSI_CHAN_X, TGSI_EXEC_DATA_FLOAT);
-
- micro_mul(&r[1], &r[1], &r[5]);
- micro_sub(&d[TGSI_CHAN_Y], &r[3], &r[1]);
-
- micro_mul(&r[5], &r[5], &r[4]);
- micro_mul(&r[0], &r[0], &r[2]);
- micro_sub(&d[TGSI_CHAN_Z], &r[5], &r[0]);
-
- if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_X) {
- store_dest(mach, &d[TGSI_CHAN_X], &inst->Dst[0], inst, TGSI_CHAN_X, TGSI_EXEC_DATA_FLOAT);
- }
- if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Y) {
- store_dest(mach, &d[TGSI_CHAN_Y], &inst->Dst[0], inst, TGSI_CHAN_Y, TGSI_EXEC_DATA_FLOAT);
- }
- if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Z) {
- store_dest(mach, &d[TGSI_CHAN_Z], &inst->Dst[0], inst, TGSI_CHAN_Z, TGSI_EXEC_DATA_FLOAT);
- }
- if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_W) {
- store_dest(mach, &OneVec, &inst->Dst[0], inst, TGSI_CHAN_W, TGSI_EXEC_DATA_FLOAT);
- }
-}
-
-static void
-exec_dst(struct tgsi_exec_machine *mach,
- const struct tgsi_full_instruction *inst)
-{
- union tgsi_exec_channel r[2];
- union tgsi_exec_channel d[4];
+ union tgsi_exec_channel r[2];
+ union tgsi_exec_channel d[4];
if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Y) {
fetch_source(mach, &r[0], &inst->Src[0], TGSI_CHAN_Y, TGSI_EXEC_DATA_FLOAT);
typedef void (* micro_dop)(union tgsi_double_channel *dst,
const union tgsi_double_channel *src);
+typedef void (* micro_dop_sop)(union tgsi_double_channel *dst,
+ const union tgsi_double_channel *src0,
+ union tgsi_exec_channel *src1);
+
+typedef void (* micro_dop_s)(union tgsi_double_channel *dst,
+ const union tgsi_exec_channel *src);
+
+typedef void (* micro_sop_d)(union tgsi_exec_channel *dst,
+ const union tgsi_double_channel *src);
+
static void
fetch_double_channel(struct tgsi_exec_machine *mach,
union tgsi_double_channel *chan,
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
}
static void
-exec_f2d(struct tgsi_exec_machine *mach,
- const struct tgsi_full_instruction *inst)
+exec_dldexp(struct tgsi_exec_machine *mach,
+ const struct tgsi_full_instruction *inst)
{
- union tgsi_exec_channel src;
+ union tgsi_double_channel src0;
+ union tgsi_exec_channel src1;
union tgsi_double_channel dst;
+ int wmask;
- if ((inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_XY) == TGSI_WRITEMASK_XY) {
- fetch_source(mach, &src, &inst->Src[0], TGSI_CHAN_X, TGSI_EXEC_DATA_FLOAT);
- micro_f2d(&dst, &src);
+ wmask = inst->Dst[0].Register.WriteMask;
+ if (wmask & TGSI_WRITEMASK_XY) {
+ fetch_double_channel(mach, &src0, &inst->Src[0], TGSI_CHAN_X, TGSI_CHAN_Y);
+ fetch_source(mach, &src1, &inst->Src[1], TGSI_CHAN_X, TGSI_EXEC_DATA_INT);
+ micro_dldexp(&dst, &src0, &src1);
store_double_channel(mach, &dst, &inst->Dst[0], inst, TGSI_CHAN_X, TGSI_CHAN_Y);
}
- if ((inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_ZW) == TGSI_WRITEMASK_ZW) {
- fetch_source(mach, &src, &inst->Src[0], TGSI_CHAN_Y, TGSI_EXEC_DATA_FLOAT);
- micro_f2d(&dst, &src);
- store_double_channel(mach, &dst, &inst->Dst[0], inst, TGSI_CHAN_Z, TGSI_CHAN_W);
- }
-}
-static void
-exec_d2f(struct tgsi_exec_machine *mach,
- const struct tgsi_full_instruction *inst)
-{
- union tgsi_double_channel src;
- union tgsi_exec_channel dst;
- int wm = inst->Dst[0].Register.WriteMask;
- int i;
- int bit;
- for (i = 0; i < 2; i++) {
- bit = ffs(wm);
- if (bit) {
- wm &= ~(1 << (bit - 1));
- if (i == 0)
- fetch_double_channel(mach, &src, &inst->Src[0], TGSI_CHAN_X, TGSI_CHAN_Y);
- else
- fetch_double_channel(mach, &src, &inst->Src[0], TGSI_CHAN_Z, TGSI_CHAN_W);
- micro_d2f(&dst, &src);
- store_dest(mach, &dst, &inst->Dst[0], inst, bit - 1, TGSI_EXEC_DATA_FLOAT);
- }
- }
-}
-
-static void
-exec_i2d(struct tgsi_exec_machine *mach,
- const struct tgsi_full_instruction *inst)
-{
- union tgsi_exec_channel src;
- union tgsi_double_channel dst;
-
- if ((inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_XY) == TGSI_WRITEMASK_XY) {
- fetch_source(mach, &src, &inst->Src[0], TGSI_CHAN_X, TGSI_EXEC_DATA_INT);
- micro_i2d(&dst, &src);
- store_double_channel(mach, &dst, &inst->Dst[0], inst, TGSI_CHAN_X, TGSI_CHAN_Y);
- }
- if ((inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_ZW) == TGSI_WRITEMASK_ZW) {
- fetch_source(mach, &src, &inst->Src[0], TGSI_CHAN_Y, TGSI_EXEC_DATA_INT);
- micro_i2d(&dst, &src);
+ if (wmask & TGSI_WRITEMASK_ZW) {
+ fetch_double_channel(mach, &src0, &inst->Src[0], TGSI_CHAN_Z, TGSI_CHAN_W);
+ fetch_source(mach, &src1, &inst->Src[1], TGSI_CHAN_Z, TGSI_EXEC_DATA_INT);
+ micro_dldexp(&dst, &src0, &src1);
store_double_channel(mach, &dst, &inst->Dst[0], inst, TGSI_CHAN_Z, TGSI_CHAN_W);
}
}
static void
-exec_d2i(struct tgsi_exec_machine *mach,
- const struct tgsi_full_instruction *inst)
+exec_dfracexp(struct tgsi_exec_machine *mach,
+ const struct tgsi_full_instruction *inst)
{
union tgsi_double_channel src;
- union tgsi_exec_channel dst;
- int wm = inst->Dst[0].Register.WriteMask;
- int i;
- int bit;
- for (i = 0; i < 2; i++) {
- bit = ffs(wm);
- if (bit) {
- wm &= ~(1 << (bit - 1));
- if (i == 0)
- fetch_double_channel(mach, &src, &inst->Src[0], TGSI_CHAN_X, TGSI_CHAN_Y);
- else
- fetch_double_channel(mach, &src, &inst->Src[0], TGSI_CHAN_Z, TGSI_CHAN_W);
- micro_d2i(&dst, &src);
- store_dest(mach, &dst, &inst->Dst[0], inst, bit - 1, TGSI_EXEC_DATA_INT);
- }
- }
-}
-static void
-exec_u2d(struct tgsi_exec_machine *mach,
- const struct tgsi_full_instruction *inst)
-{
- union tgsi_exec_channel src;
union tgsi_double_channel dst;
+ union tgsi_exec_channel dst_exp;
- if ((inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_XY) == TGSI_WRITEMASK_XY) {
- fetch_source(mach, &src, &inst->Src[0], TGSI_CHAN_X, TGSI_EXEC_DATA_UINT);
- micro_u2d(&dst, &src);
+ fetch_double_channel(mach, &src, &inst->Src[0], TGSI_CHAN_X, TGSI_CHAN_Y);
+ micro_dfracexp(&dst, &dst_exp, &src);
+ if ((inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_XY) == TGSI_WRITEMASK_XY)
store_double_channel(mach, &dst, &inst->Dst[0], inst, TGSI_CHAN_X, TGSI_CHAN_Y);
- }
- if ((inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_ZW) == TGSI_WRITEMASK_ZW) {
- fetch_source(mach, &src, &inst->Src[0], TGSI_CHAN_Y, TGSI_EXEC_DATA_UINT);
- micro_u2d(&dst, &src);
+ if ((inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_ZW) == TGSI_WRITEMASK_ZW)
store_double_channel(mach, &dst, &inst->Dst[0], inst, TGSI_CHAN_Z, TGSI_CHAN_W);
+ for (unsigned chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
+ if (inst->Dst[1].Register.WriteMask & (1 << chan))
+ store_dest(mach, &dst_exp, &inst->Dst[1], inst, chan, TGSI_EXEC_DATA_INT);
}
}
static void
-exec_d2u(struct tgsi_exec_machine *mach,
- const struct tgsi_full_instruction *inst)
-{
- union tgsi_double_channel src;
- union tgsi_exec_channel dst;
- int wm = inst->Dst[0].Register.WriteMask;
- int i;
- int bit;
- for (i = 0; i < 2; i++) {
- bit = ffs(wm);
- if (bit) {
- wm &= ~(1 << (bit - 1));
- if (i == 0)
- fetch_double_channel(mach, &src, &inst->Src[0], TGSI_CHAN_X, TGSI_CHAN_Y);
- else
- fetch_double_channel(mach, &src, &inst->Src[0], TGSI_CHAN_Z, TGSI_CHAN_W);
- micro_d2u(&dst, &src);
- store_dest(mach, &dst, &inst->Dst[0], inst, bit - 1, TGSI_EXEC_DATA_UINT);
- }
- }
-}
-
-static void
-exec_dldexp(struct tgsi_exec_machine *mach,
- const struct tgsi_full_instruction *inst)
+exec_arg0_64_arg1_32(struct tgsi_exec_machine *mach,
+ const struct tgsi_full_instruction *inst,
+ micro_dop_sop op)
{
union tgsi_double_channel src0;
union tgsi_exec_channel src1;
if (wmask & TGSI_WRITEMASK_XY) {
fetch_double_channel(mach, &src0, &inst->Src[0], TGSI_CHAN_X, TGSI_CHAN_Y);
fetch_source(mach, &src1, &inst->Src[1], TGSI_CHAN_X, TGSI_EXEC_DATA_INT);
- micro_dldexp(&dst, &src0, &src1);
+ op(&dst, &src0, &src1);
store_double_channel(mach, &dst, &inst->Dst[0], inst, TGSI_CHAN_X, TGSI_CHAN_Y);
}
if (wmask & TGSI_WRITEMASK_ZW) {
fetch_double_channel(mach, &src0, &inst->Src[0], TGSI_CHAN_Z, TGSI_CHAN_W);
fetch_source(mach, &src1, &inst->Src[1], TGSI_CHAN_Z, TGSI_EXEC_DATA_INT);
- micro_dldexp(&dst, &src0, &src1);
+ op(&dst, &src0, &src1);
store_double_channel(mach, &dst, &inst->Dst[0], inst, TGSI_CHAN_Z, TGSI_CHAN_W);
}
}
-static void
-exec_dfracexp(struct tgsi_exec_machine *mach,
- const struct tgsi_full_instruction *inst)
-{
- union tgsi_double_channel src;
- union tgsi_double_channel dst;
- union tgsi_exec_channel dst_exp;
-
- if (((inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_XY) == TGSI_WRITEMASK_XY)) {
- fetch_double_channel(mach, &src, &inst->Src[0], TGSI_CHAN_X, TGSI_CHAN_Y);
- micro_dfracexp(&dst, &dst_exp, &src);
- store_double_channel(mach, &dst, &inst->Dst[0], inst, TGSI_CHAN_X, TGSI_CHAN_Y);
- store_dest(mach, &dst_exp, &inst->Dst[1], inst, ffs(inst->Dst[1].Register.WriteMask) - 1, TGSI_EXEC_DATA_INT);
- }
- if (((inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_ZW) == TGSI_WRITEMASK_ZW)) {
- fetch_double_channel(mach, &src, &inst->Src[0], TGSI_CHAN_Z, TGSI_CHAN_W);
- micro_dfracexp(&dst, &dst_exp, &src);
- store_double_channel(mach, &dst, &inst->Dst[0], inst, TGSI_CHAN_Z, TGSI_CHAN_W);
- store_dest(mach, &dst_exp, &inst->Dst[1], inst, ffs(inst->Dst[1].Register.WriteMask) - 1, TGSI_EXEC_DATA_INT);
- }
-}
-
static int
get_image_coord_dim(unsigned tgsi_tex)
{
exec_load_mem(struct tgsi_exec_machine *mach,
const struct tgsi_full_instruction *inst)
{
- union tgsi_exec_channel r[3];
+ union tgsi_exec_channel r[4];
uint chan;
char *ptr = mach->LocalMem;
uint32_t offset;
exec_resq_buf(mach, inst);
}
+static void
+micro_f2u64(union tgsi_double_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->u64[0] = (uint64_t)src->f[0];
+ dst->u64[1] = (uint64_t)src->f[1];
+ dst->u64[2] = (uint64_t)src->f[2];
+ dst->u64[3] = (uint64_t)src->f[3];
+}
+
+static void
+micro_f2i64(union tgsi_double_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->i64[0] = (int64_t)src->f[0];
+ dst->i64[1] = (int64_t)src->f[1];
+ dst->i64[2] = (int64_t)src->f[2];
+ dst->i64[3] = (int64_t)src->f[3];
+}
+
+static void
+micro_u2i64(union tgsi_double_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->u64[0] = (uint64_t)src->u[0];
+ dst->u64[1] = (uint64_t)src->u[1];
+ dst->u64[2] = (uint64_t)src->u[2];
+ dst->u64[3] = (uint64_t)src->u[3];
+}
+
+static void
+micro_i2i64(union tgsi_double_channel *dst,
+ const union tgsi_exec_channel *src)
+{
+ dst->i64[0] = (int64_t)src->i[0];
+ dst->i64[1] = (int64_t)src->i[1];
+ dst->i64[2] = (int64_t)src->i[2];
+ dst->i64[3] = (int64_t)src->i[3];
+}
+
+static void
+micro_d2u64(union tgsi_double_channel *dst,
+ const union tgsi_double_channel *src)
+{
+ dst->u64[0] = (uint64_t)src->d[0];
+ dst->u64[1] = (uint64_t)src->d[1];
+ dst->u64[2] = (uint64_t)src->d[2];
+ dst->u64[3] = (uint64_t)src->d[3];
+}
+
+static void
+micro_d2i64(union tgsi_double_channel *dst,
+ const union tgsi_double_channel *src)
+{
+ dst->i64[0] = (int64_t)src->d[0];
+ dst->i64[1] = (int64_t)src->d[1];
+ dst->i64[2] = (int64_t)src->d[2];
+ dst->i64[3] = (int64_t)src->d[3];
+}
+
+static void
+micro_u642d(union tgsi_double_channel *dst,
+ const union tgsi_double_channel *src)
+{
+ dst->d[0] = (double)src->u64[0];
+ dst->d[1] = (double)src->u64[1];
+ dst->d[2] = (double)src->u64[2];
+ dst->d[3] = (double)src->u64[3];
+}
+
+static void
+micro_i642d(union tgsi_double_channel *dst,
+ const union tgsi_double_channel *src)
+{
+ dst->d[0] = (double)src->i64[0];
+ dst->d[1] = (double)src->i64[1];
+ dst->d[2] = (double)src->i64[2];
+ dst->d[3] = (double)src->i64[3];
+}
+
+static void
+micro_u642f(union tgsi_exec_channel *dst,
+ const union tgsi_double_channel *src)
+{
+ dst->f[0] = (float)src->u64[0];
+ dst->f[1] = (float)src->u64[1];
+ dst->f[2] = (float)src->u64[2];
+ dst->f[3] = (float)src->u64[3];
+}
+
+static void
+micro_i642f(union tgsi_exec_channel *dst,
+ const union tgsi_double_channel *src)
+{
+ dst->f[0] = (float)src->i64[0];
+ dst->f[1] = (float)src->i64[1];
+ dst->f[2] = (float)src->i64[2];
+ dst->f[3] = (float)src->i64[3];
+}
+
+static void
+exec_t_2_64(struct tgsi_exec_machine *mach,
+ const struct tgsi_full_instruction *inst,
+ micro_dop_s op,
+ enum tgsi_exec_datatype src_datatype)
+{
+ union tgsi_exec_channel src;
+ union tgsi_double_channel dst;
+
+ if ((inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_XY) == TGSI_WRITEMASK_XY) {
+ fetch_source(mach, &src, &inst->Src[0], TGSI_CHAN_X, src_datatype);
+ op(&dst, &src);
+ store_double_channel(mach, &dst, &inst->Dst[0], inst, TGSI_CHAN_X, TGSI_CHAN_Y);
+ }
+ if ((inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_ZW) == TGSI_WRITEMASK_ZW) {
+ fetch_source(mach, &src, &inst->Src[0], TGSI_CHAN_Y, src_datatype);
+ op(&dst, &src);
+ store_double_channel(mach, &dst, &inst->Dst[0], inst, TGSI_CHAN_Z, TGSI_CHAN_W);
+ }
+}
+
+static void
+exec_64_2_t(struct tgsi_exec_machine *mach,
+ const struct tgsi_full_instruction *inst,
+ micro_sop_d op,
+ enum tgsi_exec_datatype dst_datatype)
+{
+ union tgsi_double_channel src;
+ union tgsi_exec_channel dst;
+ int wm = inst->Dst[0].Register.WriteMask;
+ int i;
+ int bit;
+ for (i = 0; i < 2; i++) {
+ bit = ffs(wm);
+ if (bit) {
+ wm &= ~(1 << (bit - 1));
+ if (i == 0)
+ fetch_double_channel(mach, &src, &inst->Src[0], TGSI_CHAN_X, TGSI_CHAN_Y);
+ else
+ fetch_double_channel(mach, &src, &inst->Src[0], TGSI_CHAN_Z, TGSI_CHAN_W);
+ op(&dst, &src);
+ store_dest(mach, &dst, &inst->Dst[0], inst, bit - 1, dst_datatype);
+ }
+ }
+}
+
static void
micro_i2f(union tgsi_exec_channel *dst,
const union tgsi_exec_channel *src)
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];
+ dst->i[0] = src1->i[0] ? src0->i[0] % src1->i[0] : ~0;
+ dst->i[1] = src1->i[1] ? src0->i[1] % src1->i[1] : ~0;
+ dst->i[2] = src1->i[2] ? src0->i[2] % src1->i[2] : ~0;
+ dst->i[3] = src1->i[3] ? src0->i[3] % src1->i[3] : ~0;
}
static void
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];
-}
-
/**
* Signed bitfield extract (i.e. sign-extend the extracted bits)
*/
dst->i[3] = util_last_bit(src->u[3]) - 1;
}
-static void
+/**
+ * Execute a TGSI instruction.
+ * Returns TRUE if a barrier instruction is hit,
+ * otherwise FALSE.
+ */
+static boolean
exec_instruction(
struct tgsi_exec_machine *mach,
const struct tgsi_full_instruction *inst,
exec_vector_trinary(mach, inst, micro_mad, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
break;
- case TGSI_OPCODE_SUB:
- exec_vector_binary(mach, inst, micro_sub, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
- break;
-
case TGSI_OPCODE_LRP:
exec_vector_trinary(mach, inst, micro_lrp, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
break;
exec_scalar_unary(mach, inst, micro_sqrt, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
break;
- case TGSI_OPCODE_DP2A:
- exec_dp2a(mach, inst);
- break;
-
case TGSI_OPCODE_FRC:
exec_vector_unary(mach, inst, micro_frc, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
break;
- case TGSI_OPCODE_CLAMP:
- exec_vector_trinary(mach, inst, micro_clamp, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
- break;
-
case TGSI_OPCODE_FLR:
exec_vector_unary(mach, inst, micro_flr, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
break;
exec_scalar_binary(mach, inst, micro_pow, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
break;
- case TGSI_OPCODE_XPD:
- exec_xpd(mach, inst);
- break;
-
- case TGSI_OPCODE_ABS:
- exec_vector_unary(mach, inst, micro_abs, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
- break;
-
- case TGSI_OPCODE_DPH:
- exec_dph(mach, inst);
+ case TGSI_OPCODE_LDEXP:
+ 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:
/* returning from main() */
mach->CondStackTop = 0;
mach->LoopStackTop = 0;
+ mach->ContStackTop = 0;
+ mach->LoopLabelStackTop = 0;
+ mach->SwitchStackTop = 0;
+ mach->BreakStackTop = 0;
*pc = -1;
- return;
+ return FALSE;
}
assert(mach->CallStackTop > 0);
exec_vector_trinary(mach, inst, micro_cmp, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
break;
- case TGSI_OPCODE_SCS:
- exec_scs(mach, inst);
- break;
-
case TGSI_OPCODE_DIV:
exec_vector_binary(mach, inst, micro_div, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
break;
*pc = -1;
break;
- case TGSI_OPCODE_PUSHA:
- assert (0);
- break;
-
- case TGSI_OPCODE_POPA:
- assert (0);
- break;
-
case TGSI_OPCODE_CEIL:
exec_vector_unary(mach, inst, micro_ceil, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
break;
exec_vector_binary(mach, inst, micro_xor, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
break;
- case TGSI_OPCODE_SAD:
- assert (0);
- break;
-
case TGSI_OPCODE_TXF:
exec_txf(mach, inst);
break;
case TGSI_OPCODE_NOP:
break;
- case TGSI_OPCODE_BREAKC:
- IFETCH(&r[0], 0, TGSI_CHAN_X);
- /* update CondMask */
- if (r[0].u[0] && (mach->ExecMask & 0x1)) {
- mach->LoopMask &= ~0x1;
- }
- if (r[0].u[1] && (mach->ExecMask & 0x2)) {
- mach->LoopMask &= ~0x2;
- }
- if (r[0].u[2] && (mach->ExecMask & 0x4)) {
- mach->LoopMask &= ~0x4;
- }
- if (r[0].u[3] && (mach->ExecMask & 0x8)) {
- mach->LoopMask &= ~0x8;
- }
- /* Todo: if mach->LoopMask == 0, jump to end of loop */
- UPDATE_EXEC_MASK(mach);
- break;
-
case TGSI_OPCODE_F2I:
exec_vector_unary(mach, inst, micro_f2i, TGSI_EXEC_DATA_INT, TGSI_EXEC_DATA_FLOAT);
break;
break;
case TGSI_OPCODE_GATHER4:
- assert(0);
+ exec_sample(mach, inst, TEX_MODIFIER_GATHER, FALSE);
break;
case TGSI_OPCODE_SVIEWINFO:
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;
case TGSI_OPCODE_UCMP:
- exec_vector_trinary(mach, inst, micro_ucmp, TGSI_EXEC_DATA_UINT, TGSI_EXEC_DATA_UINT);
+ exec_ucmp(mach, inst);
break;
case TGSI_OPCODE_IABS:
break;
case TGSI_OPCODE_F2D:
- exec_f2d(mach, inst);
+ exec_t_2_64(mach, inst, micro_f2d, TGSI_EXEC_DATA_FLOAT);
break;
case TGSI_OPCODE_D2F:
- exec_d2f(mach, inst);
+ exec_64_2_t(mach, inst, micro_d2f, TGSI_EXEC_DATA_FLOAT);
break;
case TGSI_OPCODE_DABS:
exec_double_binary(mach, inst, micro_dadd, TGSI_EXEC_DATA_DOUBLE);
break;
+ case TGSI_OPCODE_DDIV:
+ exec_double_binary(mach, inst, micro_ddiv, TGSI_EXEC_DATA_DOUBLE);
+ break;
+
case TGSI_OPCODE_DMUL:
exec_double_binary(mach, inst, micro_dmul, TGSI_EXEC_DATA_DOUBLE);
break;
break;
case TGSI_OPCODE_I2D:
- exec_i2d(mach, inst);
+ exec_t_2_64(mach, inst, micro_i2d, TGSI_EXEC_DATA_INT);
break;
case TGSI_OPCODE_D2I:
- exec_d2i(mach, inst);
+ exec_64_2_t(mach, inst, micro_d2i, TGSI_EXEC_DATA_INT);
break;
case TGSI_OPCODE_U2D:
- exec_u2d(mach, inst);
+ exec_t_2_64(mach, inst, micro_u2d, TGSI_EXEC_DATA_UINT);
break;
case TGSI_OPCODE_D2U:
- exec_d2u(mach, inst);
+ exec_64_2_t(mach, inst, micro_d2u, TGSI_EXEC_DATA_INT);
break;
case TGSI_OPCODE_LOAD:
break;
case TGSI_OPCODE_BARRIER:
case TGSI_OPCODE_MEMBAR:
+ return TRUE;
+ break;
+
+ case TGSI_OPCODE_I64ABS:
+ exec_double_unary(mach, inst, micro_i64abs);
+ break;
+
+ case TGSI_OPCODE_I64SSG:
+ exec_double_unary(mach, inst, micro_i64sgn);
+ break;
+
+ case TGSI_OPCODE_I64NEG:
+ exec_double_unary(mach, inst, micro_i64neg);
+ break;
+
+ case TGSI_OPCODE_U64SEQ:
+ exec_double_binary(mach, inst, micro_u64seq, TGSI_EXEC_DATA_UINT);
+ break;
+
+ case TGSI_OPCODE_U64SNE:
+ exec_double_binary(mach, inst, micro_u64sne, TGSI_EXEC_DATA_UINT);
+ break;
+
+ case TGSI_OPCODE_I64SLT:
+ exec_double_binary(mach, inst, micro_i64slt, TGSI_EXEC_DATA_UINT);
+ break;
+ case TGSI_OPCODE_U64SLT:
+ exec_double_binary(mach, inst, micro_u64slt, TGSI_EXEC_DATA_UINT);
break;
+
+ case TGSI_OPCODE_I64SGE:
+ exec_double_binary(mach, inst, micro_i64sge, TGSI_EXEC_DATA_UINT);
+ break;
+ case TGSI_OPCODE_U64SGE:
+ exec_double_binary(mach, inst, micro_u64sge, TGSI_EXEC_DATA_UINT);
+ break;
+
+ case TGSI_OPCODE_I64MIN:
+ exec_double_binary(mach, inst, micro_i64min, TGSI_EXEC_DATA_INT64);
+ break;
+ case TGSI_OPCODE_U64MIN:
+ exec_double_binary(mach, inst, micro_u64min, TGSI_EXEC_DATA_UINT64);
+ break;
+ case TGSI_OPCODE_I64MAX:
+ exec_double_binary(mach, inst, micro_i64max, TGSI_EXEC_DATA_INT64);
+ break;
+ case TGSI_OPCODE_U64MAX:
+ exec_double_binary(mach, inst, micro_u64max, TGSI_EXEC_DATA_UINT64);
+ break;
+ case TGSI_OPCODE_U64ADD:
+ exec_double_binary(mach, inst, micro_u64add, TGSI_EXEC_DATA_UINT64);
+ break;
+ case TGSI_OPCODE_U64MUL:
+ exec_double_binary(mach, inst, micro_u64mul, TGSI_EXEC_DATA_UINT64);
+ break;
+ case TGSI_OPCODE_U64SHL:
+ exec_arg0_64_arg1_32(mach, inst, micro_u64shl);
+ break;
+ case TGSI_OPCODE_I64SHR:
+ exec_arg0_64_arg1_32(mach, inst, micro_i64shr);
+ break;
+ case TGSI_OPCODE_U64SHR:
+ exec_arg0_64_arg1_32(mach, inst, micro_u64shr);
+ break;
+ case TGSI_OPCODE_U64DIV:
+ exec_double_binary(mach, inst, micro_u64div, TGSI_EXEC_DATA_UINT64);
+ break;
+ case TGSI_OPCODE_I64DIV:
+ exec_double_binary(mach, inst, micro_i64div, TGSI_EXEC_DATA_INT64);
+ break;
+ case TGSI_OPCODE_U64MOD:
+ exec_double_binary(mach, inst, micro_u64mod, TGSI_EXEC_DATA_UINT64);
+ break;
+ case TGSI_OPCODE_I64MOD:
+ exec_double_binary(mach, inst, micro_i64mod, TGSI_EXEC_DATA_INT64);
+ break;
+
+ case TGSI_OPCODE_F2U64:
+ exec_t_2_64(mach, inst, micro_f2u64, TGSI_EXEC_DATA_FLOAT);
+ break;
+
+ case TGSI_OPCODE_F2I64:
+ exec_t_2_64(mach, inst, micro_f2i64, TGSI_EXEC_DATA_FLOAT);
+ break;
+
+ case TGSI_OPCODE_U2I64:
+ exec_t_2_64(mach, inst, micro_u2i64, TGSI_EXEC_DATA_INT);
+ break;
+ case TGSI_OPCODE_I2I64:
+ exec_t_2_64(mach, inst, micro_i2i64, TGSI_EXEC_DATA_INT);
+ break;
+
+ case TGSI_OPCODE_D2U64:
+ exec_double_unary(mach, inst, micro_d2u64);
+ break;
+
+ case TGSI_OPCODE_D2I64:
+ exec_double_unary(mach, inst, micro_d2i64);
+ break;
+
+ case TGSI_OPCODE_U642F:
+ exec_64_2_t(mach, inst, micro_u642f, TGSI_EXEC_DATA_FLOAT);
+ break;
+ case TGSI_OPCODE_I642F:
+ exec_64_2_t(mach, inst, micro_i642f, TGSI_EXEC_DATA_FLOAT);
+ break;
+
+ case TGSI_OPCODE_U642D:
+ exec_double_unary(mach, inst, micro_u642d);
+ break;
+ case TGSI_OPCODE_I642D:
+ exec_double_unary(mach, inst, micro_i642d);
+ break;
+
default:
assert( 0 );
}
+ return FALSE;
}
static void
tgsi_exec_machine_run( struct tgsi_exec_machine *mach, int start_pc )
{
uint i;
- int pc = 0;
- tgsi_exec_machine_setup_masks(mach);
+ mach->pc = start_pc;
- /* execute declarations (interpolants) */
- for (i = 0; i < mach->NumDeclarations; i++) {
- exec_declaration( mach, mach->Declarations+i );
+ if (!start_pc) {
+ tgsi_exec_machine_setup_masks(mach);
+
+ /* execute declarations (interpolants) */
+ for (i = 0; i < mach->NumDeclarations; i++) {
+ exec_declaration( mach, mach->Declarations+i );
+ }
}
{
struct tgsi_exec_vector outputs[PIPE_MAX_ATTRIBS];
uint inst = 1;
- memset(mach->Temps, 0, sizeof(temps));
- if (mach->Outputs)
- memset(mach->Outputs, 0, sizeof(outputs));
- memset(temps, 0, sizeof(temps));
- memset(outputs, 0, sizeof(outputs));
+ if (!start_pc) {
+ memset(mach->Temps, 0, sizeof(temps));
+ if (mach->Outputs)
+ memset(mach->Outputs, 0, sizeof(outputs));
+ memset(temps, 0, sizeof(temps));
+ memset(outputs, 0, sizeof(outputs));
+ }
#endif
/* execute instructions, until pc is set to -1 */
- while (pc != -1) {
-
+ while (mach->pc != -1) {
+ boolean barrier_hit;
#if DEBUG_EXECUTION
uint i;
- tgsi_dump_instruction(&mach->Instructions[pc], inst++);
+ tgsi_dump_instruction(&mach->Instructions[mach->pc], inst++);
#endif
- assert(pc < (int) mach->NumInstructions);
- exec_instruction(mach, mach->Instructions + pc, &pc);
+ assert(mach->pc < (int) mach->NumInstructions);
+ barrier_hit = exec_instruction(mach, mach->Instructions + mach->pc, &mach->pc);
+
+ /* for compute shaders if we hit a barrier return now for later rescheduling */
+ if (barrier_hit && mach->ShaderType == PIPE_SHADER_COMPUTE)
+ return 0;
#if DEBUG_EXECUTION
for (i = 0; i < TGSI_EXEC_NUM_TEMPS + TGSI_EXEC_NUM_TEMP_EXTRAS; i++) {