aboutsummaryrefslogtreecommitdiffstats
path: root/src/gallium/auxiliary/draw/draw_vs_aos_io.c
diff options
context:
space:
mode:
authorKeith Whitwell <[email protected]>2008-10-01 18:40:01 +0100
committerKeith Whitwell <[email protected]>2008-10-02 12:59:15 +0100
commitaf9cfea9cc80411351f9879d8eeb525bf7b4ca50 (patch)
tree40a52f583c0a8cfa3cb39c2114a1362c0358fe8e /src/gallium/auxiliary/draw/draw_vs_aos_io.c
parent102daee1b8971cf39235e220b9524bec1e4a7089 (diff)
draw: don't keep refetching constant inputs
Diffstat (limited to 'src/gallium/auxiliary/draw/draw_vs_aos_io.c')
-rw-r--r--src/gallium/auxiliary/draw/draw_vs_aos_io.c127
1 files changed, 92 insertions, 35 deletions
diff --git a/src/gallium/auxiliary/draw/draw_vs_aos_io.c b/src/gallium/auxiliary/draw/draw_vs_aos_io.c
index 8e08b9285f9..b0c51d7fa19 100644
--- a/src/gallium/auxiliary/draw/draw_vs_aos_io.c
+++ b/src/gallium/auxiliary/draw/draw_vs_aos_io.c
@@ -108,29 +108,45 @@ static void emit_swizzle( struct aos_compilation *cp,
static boolean get_buffer_ptr( struct aos_compilation *cp,
- unsigned buf_idx,
- struct x86_reg elt,
- struct x86_reg ptr)
+ boolean linear,
+ unsigned buf_idx,
+ struct x86_reg elt,
+ struct x86_reg ptr)
{
struct x86_reg buf = x86_make_disp(aos_get_x86( cp, 0, X86_BUFFERS ),
buf_idx * sizeof(struct aos_buffer));
- struct x86_reg buf_base_ptr = x86_make_disp(buf,
- Offset(struct aos_buffer, base_ptr));
-
struct x86_reg buf_stride = x86_make_disp(buf,
Offset(struct aos_buffer, stride));
+ if (linear) {
+ struct x86_reg buf_ptr = x86_make_disp(buf,
+ Offset(struct aos_buffer, ptr));
- /* Calculate pointer to current attrib:
- */
- x86_mov(cp->func, ptr, buf_stride);
- x86_imul(cp->func, ptr, elt);
- x86_add(cp->func, ptr, buf_base_ptr);
- return TRUE;
-}
+ /* Calculate pointer to current attrib:
+ */
+ x86_mov(cp->func, ptr, buf_ptr);
+ x86_mov(cp->func, elt, buf_stride);
+ x86_add(cp->func, elt, ptr);
+ sse_prefetchnta(cp->func, x86_deref(elt));
+ x86_mov(cp->func, buf_ptr, elt);
+ }
+ else {
+ struct x86_reg buf_base_ptr = x86_make_disp(buf,
+ Offset(struct aos_buffer, base_ptr));
+
+
+ /* Calculate pointer to current attrib:
+ */
+ x86_mov(cp->func, ptr, buf_stride);
+ x86_imul(cp->func, ptr, elt);
+ x86_add(cp->func, ptr, buf_base_ptr);
+ }
+ cp->insn_counter++;
+ return TRUE;
+}
static boolean load_input( struct aos_compilation *cp,
@@ -200,18 +216,57 @@ static boolean load_inputs( struct aos_compilation *cp,
boolean aos_init_inputs( struct aos_compilation *cp, boolean linear )
{
- if (linear && cp->vaos->nr_vb == 1) {
+ unsigned i;
+ for (i = 0; i < cp->vaos->nr_vb; i++) {
+ struct x86_reg buf = x86_make_disp(aos_get_x86( cp, 0, X86_BUFFERS ),
+ i * sizeof(struct aos_buffer));
- struct x86_reg elt = cp->idx_EBX;
- struct x86_reg ptr = cp->tmp_EAX;
+ struct x86_reg buf_base_ptr = x86_make_disp(buf,
+ Offset(struct aos_buffer, base_ptr));
- if (!get_buffer_ptr( cp, 0, elt, ptr ))
- return FALSE;
+ if (cp->vaos->base.key.const_vbuffers & (1<<i)) {
+ struct x86_reg ptr = cp->tmp_EAX;
- /* In the linear, single buffer case, keep the buffer pointer
- * instead of the index number.
- */
- x86_mov( cp->func, elt, ptr );
+ x86_mov(cp->func, ptr, buf_base_ptr);
+
+ /* Load all inputs for this constant vertex buffer
+ */
+ load_inputs( cp, i, x86_deref(ptr) );
+
+ /* Then just force them out to aos_machine.input[]
+ */
+ aos_spill_all( cp );
+
+ }
+ else if (linear) {
+
+ struct x86_reg elt = cp->idx_EBX;
+ struct x86_reg ptr = cp->tmp_EAX;
+
+ struct x86_reg buf_stride = x86_make_disp(buf,
+ Offset(struct aos_buffer, stride));
+
+ struct x86_reg buf_ptr = x86_make_disp(buf,
+ Offset(struct aos_buffer, ptr));
+
+
+ /* Calculate pointer to current attrib:
+ */
+ x86_mov(cp->func, ptr, buf_stride);
+ x86_imul(cp->func, ptr, elt);
+ x86_add(cp->func, ptr, buf_base_ptr);
+
+
+ /* In the linear case, keep the buffer pointer instead of the
+ * index number.
+ */
+ if (cp->vaos->nr_vb == 1)
+ x86_mov( cp->func, elt, ptr );
+ else
+ x86_mov( cp->func, buf_ptr, ptr );
+
+ cp->insn_counter++;
+ }
}
return TRUE;
@@ -219,23 +274,22 @@ boolean aos_init_inputs( struct aos_compilation *cp, boolean linear )
boolean aos_fetch_inputs( struct aos_compilation *cp, boolean linear )
{
- if (linear && cp->vaos->nr_vb == 1) {
-
- load_inputs( cp, 0, cp->idx_EBX );
+ unsigned j;
- }
- else {
- struct x86_reg elt = linear ? cp->idx_EBX : x86_deref(cp->idx_EBX);
- unsigned j;
-
- for (j = 0; j < cp->vaos->nr_vb; j++) {
+ for (j = 0; j < cp->vaos->nr_vb; j++) {
+ if (cp->vaos->base.key.const_vbuffers & (1<<j)) {
+ /* just retreive pre-transformed input */
+ }
+ else if (linear && cp->vaos->nr_vb == 1) {
+ load_inputs( cp, 0, cp->idx_EBX );
+ }
+ else {
+ struct x86_reg elt = linear ? cp->idx_EBX : x86_deref(cp->idx_EBX);
struct x86_reg ptr = cp->tmp_EAX;
- if (!get_buffer_ptr( cp, j, elt, ptr ))
+ if (!get_buffer_ptr( cp, linear, j, elt, ptr ))
return FALSE;
- cp->insn_counter++;
-
if (!load_inputs( cp, j, ptr ))
return FALSE;
}
@@ -252,13 +306,16 @@ boolean aos_incr_inputs( struct aos_compilation *cp, boolean linear )
Offset(struct aos_buffer, stride)));
x86_add(cp->func, cp->idx_EBX, stride);
+ sse_prefetchnta(cp->func, x86_deref(cp->idx_EBX));
}
else if (linear) {
- x86_inc(cp->func, cp->idx_EBX);
+ /* Nothing to do */
}
else {
x86_lea(cp->func, cp->idx_EBX, x86_make_disp(cp->idx_EBX, 4));
}
+
+ return TRUE;
}