#include "util/u_memory.h"
#include "util/u_math.h"
#include "pipe/p_shader_tokens.h"
-#include "pipe/p_debug.h"
+#include "util/u_debug.h"
#include "tgsi/tgsi_parse.h"
#include "tgsi/tgsi_util.h"
#include "tgsi/tgsi_exec.h"
assert(which_reg == 1);
offset = Offset(struct aos_machine, constants);
break;
- case X86_ATTRIBS:
+ case X86_BUFFERS:
assert(which_reg == 0);
- offset = Offset(struct aos_machine, attrib);
+ offset = Offset(struct aos_machine, buffer);
break;
default:
assert(0);
return x86_make_disp(aos_get_x86(cp, 1, X86_CONSTANTS), idx * 4 * sizeof(float));
default:
- ERROR(cp, "unknown reg file");
+ AOS_ERROR(cp, "unknown reg file");
return x86_make_reg(0,0);
}
}
(cp->xmm[idx].file != TGSI_FILE_INPUT && /* inputs are fetched into xmm & set dirty */
cp->xmm[idx].file != TGSI_FILE_OUTPUT &&
cp->xmm[idx].file != TGSI_FILE_TEMPORARY)) {
- ERROR(cp, "invalid spill");
+ AOS_ERROR(cp, "invalid spill");
return;
}
else {
}
+void aos_spill_all( struct aos_compilation *cp )
+{
+ unsigned i;
+
+ for (i = 0; i < 8; i++) {
+ if (cp->xmm[i].dirty)
+ spill(cp, i);
+ aos_release_xmm_reg(cp, i);
+ }
+}
+
+
static struct x86_reg get_xmm_writable( struct aos_compilation *cp,
struct x86_reg reg )
{
}
+static void aos_soft_release_xmm( struct aos_compilation *cp,
+ struct x86_reg reg )
+{
+ if (reg.file == file_XMM) {
+ assert(cp->xmm[reg.idx].last_used == cp->insn_counter);
+ cp->xmm[reg.idx].last_used = cp->insn_counter - 1;
+ }
+}
+
/* Mark an xmm reg as holding the current copy of a shader reg.
switch (swizzle) {
case TGSI_EXTSWIZZLE_ZERO:
case TGSI_EXTSWIZZLE_ONE:
- ERROR(cp, "not supporting full swizzles yet in tgsi_aos_sse2");
+ AOS_ERROR(cp, "not supporting full swizzles yet in tgsi_aos_sse2");
break;
default:
break;
default:
- ERROR(cp, "unsupported sign-mode");
+ AOS_ERROR(cp, "unsupported sign-mode");
break;
}
}
sse_mulps(cp->func, dst, tmp);
aos_release_xmm_reg(cp, tmp.idx);
+ aos_soft_release_xmm(cp, imm_swz);
}
else if (negs) {
struct x86_reg imm_negs = aos_get_internal_xmm(cp, IMM_NEGS);
sse_mulps(cp->func, dst, imm_negs);
+ aos_soft_release_xmm(cp, imm_negs);
}
if (abs && abs != 0xf) {
- ERROR(cp, "unsupported partial abs");
+ AOS_ERROR(cp, "unsupported partial abs");
}
else if (abs) {
struct x86_reg neg = aos_get_internal(cp, IMM_NEGS);
sse_maxps(cp->func, dst, tmp);
aos_release_xmm_reg(cp, tmp.idx);
+ aos_soft_release_xmm(cp, neg);
}
+ aos_soft_release_xmm(cp, arg0);
return dst;
}
break;
default:
- ERROR(cp, "unsupported sign-mode");
+ AOS_ERROR(cp, "unsupported sign-mode");
break;
}
}
}
}
-
+#if 0
static void x87_emit_ex2( struct aos_compilation *cp )
{
struct x86_reg st0 = x86_make_reg(file_x87, 0);
assert( stack == cp->func->x87_stack);
}
+#endif
+#if 0
static void PIPE_CDECL print_reg( const char *msg,
const float *reg )
{
debug_printf("%s: %f %f %f %f\n", msg, reg[0], reg[1], reg[2], reg[3]);
}
+#endif
+#if 0
static void emit_print( struct aos_compilation *cp,
const char *message, /* must point to a static string! */
unsigned file,
/* Done...
*/
}
+#endif
/**
* The traditional instructions. All operate on internal registers
return TRUE;
}
-
+#if 0
static boolean emit_EX2( struct aos_compilation *cp, const struct tgsi_full_instruction *op )
{
x87_fld_src(cp, &op->FullSrcRegisters[0], 0);
x87_fstp_dest4(cp, &op->FullDstRegisters[0]);
return TRUE;
}
+#endif
static boolean emit_FLR( struct aos_compilation *cp, const struct tgsi_full_instruction *op )
*/
static boolean emit_RSQ( struct aos_compilation *cp, const struct tgsi_full_instruction *op )
{
-
if (0) {
struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]);
struct x86_reg r = aos_get_xmm_reg(cp);
return TRUE;
}
else {
- struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]);
- struct x86_reg r = aos_get_xmm_reg(cp);
+ struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]);
+ struct x86_reg r = aos_get_xmm_reg(cp);
struct x86_reg neg_half = get_reg_ptr( cp, AOS_FILE_INTERNAL, IMM_RSQ );
struct x86_reg one_point_five = x86_make_disp( neg_half, 4 );
struct x86_reg src = get_xmm_writable( cp, arg0 );
-
- sse_rsqrtss( cp->func, r, src ); /* rsqrtss(a) */
- sse_mulss( cp->func, src, neg_half ); /* -.5 * a */
- sse_mulss( cp->func, src, r ); /* -.5 * a * r */
- sse_mulss( cp->func, src, r ); /* -.5 * a * r * r */
- sse_addss( cp->func, src, one_point_five ); /* 1.5 - .5 * a * r * r */
- sse_mulss( cp->func, r, src ); /* r * (1.5 - .5 * a * r * r) */
+ struct x86_reg neg = aos_get_internal(cp, IMM_NEGS);
+ struct x86_reg tmp = aos_get_xmm_reg(cp);
+
+ sse_movaps(cp->func, tmp, src);
+ sse_mulps(cp->func, tmp, neg);
+ sse_maxps(cp->func, tmp, src);
+
+ sse_rsqrtss( cp->func, r, tmp ); /* rsqrtss(a) */
+ sse_mulss( cp->func, tmp, neg_half ); /* -.5 * a */
+ sse_mulss( cp->func, tmp, r ); /* -.5 * a * r */
+ sse_mulss( cp->func, tmp, r ); /* -.5 * a * r * r */
+ sse_addss( cp->func, tmp, one_point_five ); /* 1.5 - .5 * a * r * r */
+ sse_mulss( cp->func, r, tmp ); /* r * (1.5 - .5 * a * r * r) */
store_scalar_dest(cp, &op->FullDstRegisters[0], r);
+
+ aos_release_xmm_reg(cp, tmp.idx);
+
return TRUE;
}
}
return TRUE;
}
+static boolean emit_TRUNC( struct aos_compilation *cp, const struct tgsi_full_instruction *op )
+{
+ struct x86_reg arg0 = fetch_src(cp, &op->FullSrcRegisters[0]);
+ struct x86_reg tmp0 = aos_get_xmm_reg(cp);
+
+ sse2_cvttps2dq(cp->func, tmp0, arg0);
+ sse2_cvtdq2ps(cp->func, tmp0, tmp0);
+
+ store_dest(cp, &op->FullDstRegisters[0], tmp0);
+ return TRUE;
+}
static boolean emit_XPD( struct aos_compilation *cp, const struct tgsi_full_instruction *op )
{
case TGSI_OPCODE_SIN:
return emit_SIN(cp, inst);
+ case TGSI_OPCODE_TRUNC:
+ return emit_TRUNC(cp, inst);
+
case TGSI_OPCODE_END:
return TRUE;
unsigned pos = cp->num_immediates++;
unsigned j;
- for (j = 0; j < imm->Immediate.Size; j++) {
+ for (j = 0; j < imm->Immediate.NrTokens - 1; j++) {
cp->vaos->machine->immediate[pos][j] = imm->u.ImmediateFloat32[j].Float;
}
save_fpu_state( &cp );
set_fpu_round_nearest( &cp );
+ aos_init_inputs( &cp, linear );
+
+ cp.x86_reg[0] = 0;
+ cp.x86_reg[1] = 0;
+
/* Note address for loop jump
*/
label = x86_get_label(cp.func);
/* Incr index
*/
- if (linear) {
- x86_inc(cp.func, cp.idx_EBX);
- }
- else {
- x86_lea(cp.func, cp.idx_EBX, x86_make_disp(cp.idx_EBX, 4));
- }
-
+ aos_incr_inputs( &cp, linear );
}
/* decr count, loop if not zero
*/
unsigned stride )
{
struct draw_vs_varient_aos_sse *vaos = (struct draw_vs_varient_aos_sse *)varient;
- unsigned i;
- for (i = 0; i < vaos->base.key.nr_inputs; i++) {
- if (vaos->base.key.element[i].in.buffer == buf) {
- vaos->attrib[i].input_ptr = ((char *)ptr +
- vaos->base.key.element[i].in.offset);
- vaos->attrib[i].input_stride = stride;
- }
+ if (buf < vaos->nr_vb) {
+ vaos->buffer[buf].base_ptr = (char *)ptr;
+ vaos->buffer[buf].stride = stride;
}
+
+ if (0) debug_printf("%s %d/%d: %p %d\n", __FUNCTION__, buf, vaos->nr_vb, ptr, stride);
}
struct draw_vs_varient_aos_sse *vaos = (struct draw_vs_varient_aos_sse *)varient;
struct aos_machine *machine = vaos->draw->vs.aos_machine;
+ if (0) debug_printf("%s %d\n", __FUNCTION__, count);
+
machine->internal[IMM_PSIZE][0] = vaos->draw->rasterizer->point_size;
machine->constants = vaos->draw->vs.aligned_constants;
machine->immediates = vaos->base.vs->immediates;
- machine->attrib = vaos->attrib;
+ machine->buffer = vaos->buffer;
vaos->gen_run_elts( machine,
elts,
struct draw_vs_varient_aos_sse *vaos = (struct draw_vs_varient_aos_sse *)varient;
struct aos_machine *machine = vaos->draw->vs.aos_machine;
+ if (0) debug_printf("%s %d %d const: %x\n", __FUNCTION__, start, count,
+ vaos->base.key.const_vbuffers);
+
machine->internal[IMM_PSIZE][0] = vaos->draw->rasterizer->point_size;
machine->constants = vaos->draw->vs.aligned_constants;
machine->immediates = vaos->base.vs->immediates;
- machine->attrib = vaos->attrib;
+ machine->buffer = vaos->buffer;
vaos->gen_run_linear( machine,
start,
{
struct draw_vs_varient_aos_sse *vaos = (struct draw_vs_varient_aos_sse *)varient;
- FREE( vaos->attrib );
+ FREE( vaos->buffer );
x86_release_func( &vaos->func[0] );
x86_release_func( &vaos->func[1] );
static struct draw_vs_varient *varient_aos_sse( struct draw_vertex_shader *vs,
const struct draw_vs_varient_key *key )
{
+ unsigned i;
struct draw_vs_varient_aos_sse *vaos = CALLOC_STRUCT(draw_vs_varient_aos_sse);
if (!vaos)
vaos->base.key = *key;
vaos->base.vs = vs;
- vaos->base.set_input = vaos_set_buffer;
+ vaos->base.set_buffer = vaos_set_buffer;
vaos->base.destroy = vaos_destroy;
vaos->base.run_linear = vaos_run_linear;
vaos->base.run_elts = vaos_run_elts;
vaos->draw = vs->draw;
- vaos->attrib = MALLOC( key->nr_inputs * sizeof(vaos->attrib[0]) );
- if (!vaos->attrib)
+ for (i = 0; i < key->nr_inputs; i++)
+ vaos->nr_vb = MAX2( vaos->nr_vb, key->element[i].in.buffer + 1 );
+
+ vaos->buffer = MALLOC( vaos->nr_vb * sizeof(vaos->buffer[0]) );
+ if (!vaos->buffer)
goto fail;
+ if (0)
+ debug_printf("nr_vb: %d const: %x\n", vaos->nr_vb, vaos->base.key.const_vbuffers);
+
#if 0
tgsi_dump(vs->state.tokens, 0);
#endif
return &vaos->base;
fail:
- if (vaos && vaos->attrib)
- FREE(vaos->attrib);
+ if (vaos && vaos->buffer)
+ FREE(vaos->buffer);
if (vaos)
x86_release_func( &vaos->func[0] );