summaryrefslogtreecommitdiffstats
path: root/src/gallium/auxiliary/draw
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/auxiliary/draw')
-rw-r--r--src/gallium/auxiliary/draw/Makefile1
-rw-r--r--src/gallium/auxiliary/draw/SConscript1
-rw-r--r--src/gallium/auxiliary/draw/draw_context.c8
-rw-r--r--src/gallium/auxiliary/draw/draw_flatshade.c55
-rw-r--r--src/gallium/auxiliary/draw/draw_passthrough.c473
-rw-r--r--src/gallium/auxiliary/draw/draw_prim.c105
-rw-r--r--src/gallium/auxiliary/draw/draw_private.h2
-rw-r--r--src/gallium/auxiliary/draw/draw_pt.c9
-rw-r--r--src/gallium/auxiliary/draw/draw_pt.h2
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_vcache.c127
-rw-r--r--src/gallium/auxiliary/draw/draw_vs_exec.c28
-rw-r--r--src/gallium/auxiliary/draw/draw_vs_llvm.c46
-rw-r--r--src/gallium/auxiliary/draw/draw_vs_sse.c34
13 files changed, 281 insertions, 610 deletions
diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile
index 0c7ce5da5ba..a0db2e4555e 100644
--- a/src/gallium/auxiliary/draw/Makefile
+++ b/src/gallium/auxiliary/draw/Makefile
@@ -15,7 +15,6 @@ C_SOURCES = \
draw_debug.c \
draw_flatshade.c \
draw_offset.c \
- draw_passthrough.c \
draw_pt.c \
draw_pt_vcache.c \
draw_pt_fetch_emit.c \
diff --git a/src/gallium/auxiliary/draw/SConscript b/src/gallium/auxiliary/draw/SConscript
index 9b3e7247c54..981225a8c2c 100644
--- a/src/gallium/auxiliary/draw/SConscript
+++ b/src/gallium/auxiliary/draw/SConscript
@@ -14,7 +14,6 @@ draw = env.ConvenienceLibrary(
'draw_debug.c',
'draw_flatshade.c',
'draw_offset.c',
- 'draw_passthrough.c', # going away soon
'draw_pt.c',
'draw_pt_vcache.c',
'draw_pt_fetch_emit.c',
diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c
index 10bf9f54c10..d0d5f66b376 100644
--- a/src/gallium/auxiliary/draw/draw_context.c
+++ b/src/gallium/auxiliary/draw/draw_context.c
@@ -228,6 +228,14 @@ void draw_set_viewport_state( struct draw_context *draw,
{
draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
draw->viewport = *viewport; /* struct copy */
+ draw->identity_viewport = (viewport->scale[0] == 1.0f &&
+ viewport->scale[1] == 1.0f &&
+ viewport->scale[2] == 1.0f &&
+ viewport->scale[3] == 1.0f &&
+ viewport->translate[0] == 0.0f &&
+ viewport->translate[1] == 0.0f &&
+ viewport->translate[2] == 0.0f &&
+ viewport->translate[3] == 0.0f);
}
diff --git a/src/gallium/auxiliary/draw/draw_flatshade.c b/src/gallium/auxiliary/draw/draw_flatshade.c
index ccad71d6957..af2cb05c989 100644
--- a/src/gallium/auxiliary/draw/draw_flatshade.c
+++ b/src/gallium/auxiliary/draw/draw_flatshade.c
@@ -84,8 +84,25 @@ static INLINE void copy_colors2( struct draw_stage *stage,
* Flatshade tri. Required for clipping and when unfilled tris are
* active, otherwise handled by hardware.
*/
-static void flatshade_tri( struct draw_stage *stage,
- struct prim_header *header )
+static void flatshade_tri_0( struct draw_stage *stage,
+ struct prim_header *header )
+{
+ struct prim_header tmp;
+
+ tmp.det = header->det;
+ tmp.edgeflags = header->edgeflags;
+ tmp.v[0] = header->v[0];
+ tmp.v[1] = dup_vert(stage, header->v[1], 0);
+ tmp.v[2] = dup_vert(stage, header->v[2], 1);
+
+ copy_colors2(stage, tmp.v[1], tmp.v[2], tmp.v[0]);
+
+ stage->next->tri( stage->next, &tmp );
+}
+
+
+static void flatshade_tri_2( struct draw_stage *stage,
+ struct prim_header *header )
{
struct prim_header tmp;
@@ -101,11 +118,27 @@ static void flatshade_tri( struct draw_stage *stage,
}
+
+
+
/**
* Flatshade line. Required for clipping.
*/
-static void flatshade_line( struct draw_stage *stage,
- struct prim_header *header )
+static void flatshade_line_0( struct draw_stage *stage,
+ struct prim_header *header )
+{
+ struct prim_header tmp;
+
+ tmp.v[0] = header->v[0];
+ tmp.v[1] = dup_vert(stage, header->v[1], 0);
+
+ copy_colors(stage, tmp.v[1], tmp.v[0]);
+
+ stage->next->line( stage->next, &tmp );
+}
+
+static void flatshade_line_1( struct draw_stage *stage,
+ struct prim_header *header )
{
struct prim_header tmp;
@@ -118,6 +151,8 @@ static void flatshade_line( struct draw_stage *stage,
}
+/* Flatshade point -- passthrough.
+ */
static void flatshade_point( struct draw_stage *stage,
struct prim_header *header )
{
@@ -140,8 +175,16 @@ static void flatshade_init_state( struct draw_stage *stage )
}
}
- stage->line = flatshade_line;
- stage->tri = flatshade_tri;
+ /* Choose flatshade routine according to provoking vertex:
+ */
+ if (stage->draw->rasterizer->flatshade_first) {
+ stage->line = flatshade_line_0;
+ stage->tri = flatshade_tri_0;
+ }
+ else {
+ stage->line = flatshade_line_1;
+ stage->tri = flatshade_tri_2;
+ }
}
static void flatshade_first_tri( struct draw_stage *stage,
diff --git a/src/gallium/auxiliary/draw/draw_passthrough.c b/src/gallium/auxiliary/draw/draw_passthrough.c
deleted file mode 100644
index 2198079a880..00000000000
--- a/src/gallium/auxiliary/draw/draw_passthrough.c
+++ /dev/null
@@ -1,473 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
- /*
- * Authors:
- * Keith Whitwell <[email protected]>
- */
-
-
-/* This code is a prototype of what a passhthrough vertex shader might
- * look like.
- *
- * Probably the best approach for us is to do:
- * - vertex fetch
- * - vertex shader
- * - cliptest / viewport transform
- *
- * in one step, then examine the clipOrMask & choose between two paths:
- *
- * Either:
- * - build primitive headers
- * - clip and the primitive path
- * - build clipped vertex buffers,
- * - vertex-emit to vbuf buffers
- *
- * Or, if no clipping:
- * - vertex-emit directly to vbuf buffers
- *
- * But when bypass clipping is enabled, we just take the latter
- * choice. If (some new) passthrough-vertex-shader flag is also set,
- * the pipeline degenerates to:
- *
- * - vertex fetch
- * - vertex emit to vbuf buffers
- *
- * Which is what is prototyped here.
- */
-#include "pipe/p_util.h"
-#include "draw/draw_context.h"
-#include "draw/draw_private.h"
-#include "draw/draw_vbuf.h"
-#include "draw/draw_vertex.h"
-
-
-/**
- * General-purpose fetch from user's vertex arrays, emit to driver's
- * vertex buffer.
- *
- * XXX this is totally temporary.
- */
-static void
-fetch_store_general( struct draw_context *draw,
- float *out,
- unsigned start,
- unsigned count )
-{
- const struct vertex_info *vinfo = draw->render->get_vertex_info(draw->render);
- const unsigned nr_attrs = vinfo->num_attribs;
- uint i, j;
-
- const unsigned *pitch = draw->vertex_fetch.pitch;
- const ubyte **src = draw->vertex_fetch.src_ptr;
-
- for (i = start; i < start + count; i++) {
- for (j = 0; j < nr_attrs; j++) {
- /* vinfo->src_index is the output of the vertex shader
- * matching this hw-vertex component.
- *
- * In passthrough, we require a 1:1 mapping between vertex
- * shader outputs and inputs, which in turn correspond to
- * vertex elements in the state. So, this is the vertex
- * element we're interested in...
- */
- const uint jj = vinfo->src_index[j];
- const enum pipe_format srcFormat = draw->vertex_element[jj].src_format;
- const ubyte *from = src[jj] + i * pitch[jj];
- float attrib[4];
-
- /* Except... When we're not. Two cases EMIT_HEADER &
- * EMIT_1F_PSIZE don't consume an input. Should have some
- * method for indicating this, or change the logic here
- * somewhat so it doesn't matter.
- *
- * Just hack this up now, do something better about it later.
- */
- if (vinfo->emit[j] == EMIT_HEADER) {
- memset(out, 0, sizeof(struct vertex_header));
- out += sizeof(struct vertex_header) / 4;
- continue;
- }
- else if (vinfo->emit[j] == EMIT_1F_PSIZE) {
- out[0] = 1.0; /* xxx */
- out += 1;
- continue;
- }
-
-
- /* The normal fetch/emit code:
- */
- switch (srcFormat) {
- case PIPE_FORMAT_B8G8R8A8_UNORM:
- {
- ubyte *ub = (ubyte *) from;
- attrib[2] = UBYTE_TO_FLOAT(ub[0]);
- attrib[1] = UBYTE_TO_FLOAT(ub[1]);
- attrib[0] = UBYTE_TO_FLOAT(ub[2]);
- attrib[3] = UBYTE_TO_FLOAT(ub[3]);
- }
- break;
- case PIPE_FORMAT_R32G32B32A32_FLOAT:
- {
- float *f = (float *) from;
- attrib[0] = f[0];
- attrib[1] = f[1];
- attrib[2] = f[2];
- attrib[3] = f[3];
- }
- break;
- case PIPE_FORMAT_R32G32B32_FLOAT:
- {
- float *f = (float *) from;
- attrib[0] = f[0];
- attrib[1] = f[1];
- attrib[2] = f[2];
- attrib[3] = 1.0;
- }
- break;
- case PIPE_FORMAT_R32G32_FLOAT:
- {
- float *f = (float *) from;
- attrib[0] = f[0];
- attrib[1] = f[1];
- attrib[2] = 0.0;
- attrib[3] = 1.0;
- }
- break;
- case PIPE_FORMAT_R32_FLOAT:
- {
- float *f = (float *) from;
- attrib[0] = f[0];
- attrib[1] = 0.0;
- attrib[2] = 0.0;
- attrib[3] = 1.0;
- }
- break;
- default:
- assert(0);
- }
-
- debug_printf("attrib %d: %f %f %f %f\n", j,
- attrib[0], attrib[1], attrib[2], attrib[3]);
-
- switch (vinfo->emit[j]) {
- case EMIT_1F:
- out[0] = attrib[0];
- out += 1;
- break;
- case EMIT_2F:
- out[0] = attrib[0];
- out[1] = attrib[1];
- out += 2;
- break;
- case EMIT_4F:
- out[0] = attrib[0];
- out[1] = attrib[1];
- out[2] = attrib[2];
- out[3] = attrib[3];
- out += 4;
- break;
- default:
- assert(0);
- }
- }
- debug_printf("\n");
- }
-}
-
-
-
-static boolean update_shader( struct draw_context *draw )
-{
- const struct vertex_info *vinfo = draw->render->get_vertex_info(draw->render);
-
- unsigned nr_attrs = vinfo->num_attribs;
- unsigned i;
-
- for (i = 0; i < nr_attrs; i++) {
- unsigned buf = draw->vertex_element[i].vertex_buffer_index;
-
- draw->vertex_fetch.src_ptr[i] = (const ubyte *) draw->user.vbuffer[buf] +
- draw->vertex_buffer[buf].buffer_offset +
- draw->vertex_element[i].src_offset;
-
- draw->vertex_fetch.pitch[i] = draw->vertex_buffer[buf].pitch;
- draw->vertex_fetch.fetch[i] = NULL;
- }
-
- draw->vertex_fetch.nr_attrs = nr_attrs;
- draw->vertex_fetch.fetch_func = NULL;
- draw->vertex_fetch.pt_fetch = NULL;
-
- draw->pt.hw_vertex_size = vinfo->size * 4;
-
- draw->vertex_fetch.pt_fetch = fetch_store_general;
- return TRUE;
-}
-
-
-
-
-static boolean split_prim_inplace(unsigned prim, unsigned *first, unsigned *incr)
-{
- switch (prim) {
- case PIPE_PRIM_POINTS:
- *first = 1;
- *incr = 1;
- return TRUE;
- case PIPE_PRIM_LINES:
- *first = 2;
- *incr = 2;
- return TRUE;
- case PIPE_PRIM_LINE_STRIP:
- *first = 2;
- *incr = 1;
- return TRUE;
- case PIPE_PRIM_TRIANGLES:
- *first = 3;
- *incr = 3;
- return TRUE;
- case PIPE_PRIM_TRIANGLE_STRIP:
- *first = 3;
- *incr = 1;
- return TRUE;
- case PIPE_PRIM_QUADS:
- *first = 4;
- *incr = 4;
- return TRUE;
- case PIPE_PRIM_QUAD_STRIP:
- *first = 4;
- *incr = 2;
- return TRUE;
- default:
- *first = 0;
- *incr = 1; /* set to one so that count % incr works */
- return FALSE;
- }
-}
-
-
-
-static boolean set_prim( struct draw_context *draw,
- unsigned prim,
- unsigned count )
-{
- assert(!draw->user.elts);
-
- switch (prim) {
- case PIPE_PRIM_LINE_LOOP:
- if (count > 1024)
- return FALSE;
- return draw->render->set_primitive( draw->render, PIPE_PRIM_LINE_STRIP );
-
- case PIPE_PRIM_TRIANGLE_FAN:
- case PIPE_PRIM_POLYGON:
- if (count > 1024)
- return FALSE;
- return draw->render->set_primitive( draw->render, prim );
-
- case PIPE_PRIM_QUADS:
- case PIPE_PRIM_QUAD_STRIP:
- return draw->render->set_primitive( draw->render, PIPE_PRIM_TRIANGLES );
-
- default:
- return draw->render->set_primitive( draw->render, prim );
- break;
- }
-
- return TRUE;
-}
-
-
-
-#define INDEX(i) (start + (i))
-static void pt_draw_arrays( struct draw_context *draw,
- unsigned start,
- unsigned length )
-{
- ushort *tmp = NULL;
- unsigned i, j;
-
- switch (draw->pt.prim) {
- case PIPE_PRIM_LINE_LOOP:
- tmp = MALLOC( sizeof(ushort) * (length + 1) );
-
- for (i = 0; i < length; i++)
- tmp[i] = INDEX(i);
- tmp[length] = 0;
-
- draw->render->draw( draw->render,
- tmp,
- length+1 );
- break;
-
-
- case PIPE_PRIM_QUAD_STRIP:
- tmp = MALLOC( sizeof(ushort) * (length / 2 * 6) );
-
- for (j = i = 0; i + 3 < length; i += 2, j += 6) {
- tmp[j+0] = INDEX(i+0);
- tmp[j+1] = INDEX(i+1);
- tmp[j+2] = INDEX(i+3);
-
- tmp[j+3] = INDEX(i+2);
- tmp[j+4] = INDEX(i+0);
- tmp[j+5] = INDEX(i+3);
- }
-
- if (j)
- draw->render->draw( draw->render, tmp, j );
- break;
-
- case PIPE_PRIM_QUADS:
- tmp = MALLOC( sizeof(int) * (length / 4 * 6) );
-
- for (j = i = 0; i + 3 < length; i += 4, j += 6) {
- tmp[j+0] = INDEX(i+0);
- tmp[j+1] = INDEX(i+1);
- tmp[j+2] = INDEX(i+3);
-
- tmp[j+3] = INDEX(i+1);
- tmp[j+4] = INDEX(i+2);
- tmp[j+5] = INDEX(i+3);
- }
-
- if (j)
- draw->render->draw( draw->render, tmp, j );
- break;
-
- default:
- draw->render->draw_arrays( draw->render,
- start,
- length );
- break;
- }
-
- if (tmp)
- FREE(tmp);
-}
-
-
-
-static boolean do_draw( struct draw_context *draw,
- unsigned start, unsigned count )
-{
- float *hw_verts =
- draw->render->allocate_vertices( draw->render,
- (ushort)draw->pt.hw_vertex_size,
- (ushort)count );
-
- if (!hw_verts)
- return FALSE;
-
- /* Single routine to fetch vertices and emit HW verts.
- */
- draw->vertex_fetch.pt_fetch( draw,
- hw_verts,
- start, count );
-
- /* Draw arrays path to avoid re-emitting index list again and
- * again.
- */
- pt_draw_arrays( draw,
- 0,
- count );
-
-
- draw->render->release_vertices( draw->render,
- hw_verts,
- draw->pt.hw_vertex_size,
- count );
-
- return TRUE;
-}
-
-
-boolean
-draw_passthrough_arrays(struct draw_context *draw,
- unsigned prim,
- unsigned start,
- unsigned count)
-{
- unsigned i = 0;
- unsigned first, incr;
-
- //debug_printf("%s prim %d start %d count %d\n", __FUNCTION__, prim, start, count);
-
- split_prim_inplace(prim, &first, &incr);
-
- count -= (count - first) % incr;
-
- debug_printf("%s %d %d %d\n", __FUNCTION__, prim, start, count);
-
- if (draw_need_pipeline(draw, prim))
- return FALSE;
-
- debug_printf("%s AAA\n", __FUNCTION__);
-
- if (!set_prim(draw, prim, count))
- return FALSE;
-
- /* XXX: need a single value that reflects the most recent call to
- * driver->set_primitive:
- */
- draw->pt.prim = prim;
-
- debug_printf("%s BBB\n", __FUNCTION__);
-
- if (!update_shader(draw))
- return FALSE;
-
- debug_printf("%s CCC\n", __FUNCTION__);
-
- /* Chop this up into bite-sized pieces that a driver should be able
- * to devour -- problem is we don't have a quick way to query the
- * driver on the maximum size for this chunk in the current state.
- */
- while (i + first <= count) {
- int nr = MIN2( count - i, 1024 );
-
- /* snap to prim boundary
- */
- nr -= (nr - first) % incr;
-
- if (!do_draw( draw, start + i, nr )) {
- assert(0);
- return FALSE;
- }
-
- /* increment allowing for repeated vertices
- */
- i += nr - (first - incr);
- }
-
-
- debug_printf("%s DONE\n", __FUNCTION__);
- return TRUE;
-}
-
-
diff --git a/src/gallium/auxiliary/draw/draw_prim.c b/src/gallium/auxiliary/draw/draw_prim.c
index ddcde01d9a2..4452376a70e 100644
--- a/src/gallium/auxiliary/draw/draw_prim.c
+++ b/src/gallium/auxiliary/draw/draw_prim.c
@@ -343,21 +343,11 @@ draw_prim( struct draw_context *draw,
break;
case PIPE_PRIM_LINES:
- if (flatfirst) {
- for (i = 0; i+1 < count; i += 2) {
- do_line( draw,
- TRUE,
- start + i + 1,
- start + i + 0);
- }
- }
- else {
- for (i = 0; i+1 < count; i += 2) {
- do_line( draw,
- TRUE,
- start + i + 0,
- start + i + 1);
- }
+ for (i = 0; i+1 < count; i += 2) {
+ do_line( draw,
+ TRUE,
+ start + i + 0,
+ start + i + 1);
}
break;
@@ -378,63 +368,31 @@ draw_prim( struct draw_context *draw,
break;
case PIPE_PRIM_LINE_STRIP:
- if (flatfirst) {
- for (i = 1; i < count; i++) {
- do_line( draw,
- i == 1,
- start + i,
- start + i - 1 );
- }
- }
- else {
- for (i = 1; i < count; i++) {
- do_line( draw,
- i == 1,
- start + i - 1,
- start + i );
- }
+ for (i = 1; i < count; i++) {
+ do_line( draw,
+ i == 1,
+ start + i - 1,
+ start + i );
}
break;
case PIPE_PRIM_TRIANGLES:
- if (flatfirst) {
- if (unfilled) {
- for (i = 0; i+2 < count; i += 3) {
- do_ef_triangle( draw,
- 1,
- ~0,
- start + i + 1,
- start + i + 2,
- start + i + 0 );
- }
- }
- else {
- for (i = 0; i+2 < count; i += 3) {
- do_triangle( draw,
- start + i + 1,
- start + i + 2,
- start + i + 0 );
- }
+ if (unfilled) {
+ for (i = 0; i+2 < count; i += 3) {
+ do_ef_triangle( draw,
+ 1,
+ ~0,
+ start + i + 0,
+ start + i + 1,
+ start + i + 2 );
}
- }
+ }
else {
- if (unfilled) {
- for (i = 0; i+2 < count; i += 3) {
- do_ef_triangle( draw,
- 1,
- ~0,
- start + i + 0,
- start + i + 1,
- start + i + 2 );
- }
- }
- else {
- for (i = 0; i+2 < count; i += 3) {
- do_triangle( draw,
- start + i + 0,
- start + i + 1,
- start + i + 2 );
- }
+ for (i = 0; i+2 < count; i += 3) {
+ do_triangle( draw,
+ start + i + 0,
+ start + i + 1,
+ start + i + 2 );
}
}
break;
@@ -444,15 +402,15 @@ draw_prim( struct draw_context *draw,
for (i = 0; i+2 < count; i++) {
if (i & 1) {
do_triangle( draw,
+ start + i + 0,
start + i + 2,
- start + i + 1,
- start + i + 0 );
+ start + i + 1 );
}
else {
do_triangle( draw,
+ start + i + 0,
start + i + 1,
- start + i + 2,
- start + i + 0 );
+ start + i + 2 );
}
}
}
@@ -479,9 +437,9 @@ draw_prim( struct draw_context *draw,
if (flatfirst) {
for (i = 0; i+2 < count; i++) {
do_triangle( draw,
+ start + i + 1,
start + i + 2,
- start + 0,
- start + i + 1 );
+ start + 0 );
}
}
else {
@@ -593,8 +551,7 @@ draw_arrays(struct draw_context *draw, unsigned prim,
}
/* drawing done here: */
- if (!draw->rasterizer->bypass_vs ||
- !draw_pt_arrays(draw, prim, start, count)) {
+ if (!draw_pt_arrays(draw, prim, start, count)) {
/* we have to run the whole pipeline */
draw_prim(draw, prim, start, count);
}
diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h
index 8eb2f515cbc..9a9b25297f1 100644
--- a/src/gallium/auxiliary/draw/draw_private.h
+++ b/src/gallium/auxiliary/draw/draw_private.h
@@ -232,6 +232,8 @@ struct draw_context
struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS];
struct draw_vertex_shader *vertex_shader;
+ boolean identity_viewport;
+
uint num_vs_outputs; /**< convenience, from vertex_shader */
/* user-space vertex data, buffers */
diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c
index 3ec31ec25f3..2ea96c686da 100644
--- a/src/gallium/auxiliary/draw/draw_pt.c
+++ b/src/gallium/auxiliary/draw/draw_pt.c
@@ -36,6 +36,9 @@
#include "draw/draw_pt.h"
+/* XXX: Shouldn't those two functions below use the '>' operator???
+ */
+
static boolean too_many_verts( struct draw_context *draw,
unsigned verts )
{
@@ -164,6 +167,10 @@ draw_pt_arrays(struct draw_context *draw,
frontend = draw->pt.front.vcache;
#endif
+ /* XXX: need to flush to get prim_vbuf.c to release its allocation??
+ */
+ draw_do_flush( draw, DRAW_FLUSH_BACKEND );
+
frontend->prepare( frontend, middle );
frontend->run( frontend,
@@ -184,7 +191,7 @@ boolean draw_pt_init( struct draw_context *draw )
if (!draw->pt.middle.fetch_emit)
return FALSE;
- draw->pt.front.vcache = draw_pt_vcache();
+ draw->pt.front.vcache = draw_pt_vcache( draw );
if (!draw->pt.front.vcache)
return FALSE;
diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h
index 439fa4c8813..f8786160799 100644
--- a/src/gallium/auxiliary/draw/draw_pt.h
+++ b/src/gallium/auxiliary/draw/draw_pt.h
@@ -110,7 +110,7 @@ const void *draw_pt_elt_ptr( struct draw_context *draw,
/* Implementations:
*/
-struct draw_pt_front_end *draw_pt_vcache( void );
+struct draw_pt_front_end *draw_pt_vcache( struct draw_context *draw );
struct draw_pt_middle_end *draw_pt_fetch_emit( struct draw_context *draw );
diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache.c b/src/gallium/auxiliary/draw/draw_pt_vcache.c
index da9a3a52aed..16ffedf580c 100644
--- a/src/gallium/auxiliary/draw/draw_pt_vcache.c
+++ b/src/gallium/auxiliary/draw/draw_pt_vcache.c
@@ -44,6 +44,7 @@
struct vcache_frontend {
struct draw_pt_front_end base;
+ struct draw_context *draw;
unsigned in[CACHE_MAX];
ushort out[CACHE_MAX];
@@ -157,14 +158,6 @@ static void vcache_quad( struct vcache_frontend *vcache,
}
-static void vcache_prepare( struct draw_pt_front_end *frontend,
- struct draw_pt_middle_end *middle )
-{
- struct vcache_frontend *vcache = (struct vcache_frontend *)frontend;
- vcache->middle = middle;
- middle->prepare( middle );
-}
-
static unsigned reduced_prim[PIPE_PRIM_POLYGON + 1] = {
PIPE_PRIM_POINTS,
PIPE_PRIM_LINES,
@@ -179,11 +172,11 @@ static unsigned reduced_prim[PIPE_PRIM_POLYGON + 1] = {
};
-static void vcache_run( struct draw_pt_front_end *frontend,
- unsigned prim,
- pt_elt_func get_elt,
- const void *elts,
- unsigned count )
+static void vcache_run_pv2( struct draw_pt_front_end *frontend,
+ unsigned prim,
+ pt_elt_func get_elt,
+ const void *elts,
+ unsigned count )
{
struct vcache_frontend *vcache = (struct vcache_frontend *)frontend;
unsigned i;
@@ -309,6 +302,109 @@ static void vcache_run( struct draw_pt_front_end *frontend,
vcache_flush( vcache );
}
+
+static void vcache_run_pv0( struct draw_pt_front_end *frontend,
+ unsigned prim,
+ pt_elt_func get_elt,
+ const void *elts,
+ unsigned count )
+{
+ struct vcache_frontend *vcache = (struct vcache_frontend *)frontend;
+ unsigned i;
+
+ /* These are for validation only:
+ */
+ vcache->elt_func = get_elt;
+ vcache->elt_ptr = elts;
+ vcache->output_prim = reduced_prim[prim];
+
+ switch (prim) {
+ case PIPE_PRIM_POINTS:
+ for (i = 0; i < count; i ++) {
+ vcache_point( vcache,
+ get_elt(elts, i) );
+ }
+ break;
+
+ case PIPE_PRIM_LINES:
+ for (i = 0; i+1 < count; i += 2) {
+ vcache_line( vcache,
+ TRUE,
+ get_elt(elts, i + 0),
+ get_elt(elts, i + 1));
+ }
+ break;
+
+ case PIPE_PRIM_LINE_STRIP:
+ for (i = 1; i < count; i++) {
+ vcache_line( vcache,
+ i == 1,
+ get_elt(elts, i - 1),
+ get_elt(elts, i) );
+ }
+ break;
+
+ case PIPE_PRIM_TRIANGLES:
+ for (i = 0; i+2 < count; i += 3) {
+ vcache_triangle( vcache,
+ get_elt(elts, i + 0),
+ get_elt(elts, i + 1),
+ get_elt(elts, i + 2) );
+ }
+ break;
+
+ case PIPE_PRIM_TRIANGLE_STRIP:
+ for (i = 0; i+2 < count; i++) {
+ if (i & 1) {
+ vcache_triangle( vcache,
+ get_elt(elts, i + 0),
+ get_elt(elts, i + 2),
+ get_elt(elts, i + 1) );
+ }
+ else {
+ vcache_triangle( vcache,
+ get_elt(elts, i + 0),
+ get_elt(elts, i + 1),
+ get_elt(elts, i + 2) );
+ }
+ }
+ break;
+
+ case PIPE_PRIM_TRIANGLE_FAN:
+ for (i = 0; i+2 < count; i++) {
+ vcache_triangle( vcache,
+ get_elt(elts, i + 1),
+ get_elt(elts, i + 2),
+ get_elt(elts, 0) );
+ }
+ break;
+
+
+ default:
+ assert(0);
+ break;
+ }
+
+ vcache_flush( vcache );
+}
+
+static void vcache_prepare( struct draw_pt_front_end *frontend,
+ struct draw_pt_middle_end *middle )
+{
+ struct vcache_frontend *vcache = (struct vcache_frontend *)frontend;
+
+ if (vcache->draw->rasterizer->flatshade_first)
+ vcache->base.run = vcache_run_pv0;
+ else
+ vcache->base.run = vcache_run_pv2;
+
+ vcache->middle = middle;
+ middle->prepare( middle );
+}
+
+
+
+
static void vcache_finish( struct draw_pt_front_end *frontend )
{
struct vcache_frontend *vcache = (struct vcache_frontend *)frontend;
@@ -322,14 +418,15 @@ static void vcache_destroy( struct draw_pt_front_end *frontend )
}
-struct draw_pt_front_end *draw_pt_vcache( void )
+struct draw_pt_front_end *draw_pt_vcache( struct draw_context *draw )
{
struct vcache_frontend *vcache = CALLOC_STRUCT( vcache_frontend );
vcache->base.prepare = vcache_prepare;
- vcache->base.run = vcache_run;
+ vcache->base.run = NULL;
vcache->base.finish = vcache_finish;
vcache->base.destroy = vcache_destroy;
+ vcache->draw = draw;
memset(vcache->in, ~0, sizeof(vcache->in));
diff --git a/src/gallium/auxiliary/draw/draw_vs_exec.c b/src/gallium/auxiliary/draw/draw_vs_exec.c
index 487d0ea7f4f..c6e503686a6 100644
--- a/src/gallium/auxiliary/draw/draw_vs_exec.c
+++ b/src/gallium/auxiliary/draw/draw_vs_exec.c
@@ -110,13 +110,20 @@ vs_exec_run( struct draw_vertex_shader *shader,
machine->Consts = (float (*)[4]) draw->user.constants;
machine->Inputs = ALIGN16_ASSIGN(inputs);
- machine->Outputs = ALIGN16_ASSIGN(outputs);
+ if (draw->rasterizer->bypass_vs) {
+ /* outputs are just the inputs */
+ machine->Outputs = machine->Inputs;
+ }
+ else {
+ machine->Outputs = ALIGN16_ASSIGN(outputs);
+ }
draw->vertex_fetch.fetch_func( draw, machine, elts, count );
- /* run interpreter */
- tgsi_exec_machine_run( machine );
-
+ if (!draw->rasterizer->bypass_vs) {
+ /* run interpreter */
+ tgsi_exec_machine_run( machine );
+ }
/* store machine results */
for (j = 0; j < count; j++) {
@@ -136,14 +143,19 @@ vs_exec_run( struct draw_vertex_shader *shader,
if (!draw->rasterizer->bypass_clipping) {
vOut[j]->clipmask = compute_clipmask(vOut[j]->clip, draw->plane, draw->nr_planes);
- vOut[j]->edgeflag = 1;
/* divide by w */
w = 1.0f / w;
x *= w;
y *= w;
- z *= w;
-
+ z *= w;
+ }
+ else {
+ vOut[j]->clipmask = 0;
+ }
+ vOut[j]->edgeflag = 1;
+
+ if (!draw->identity_viewport) {
/* Viewport mapping */
vOut[j]->data[0][0] = x * scale[0] + trans[0];
vOut[j]->data[0][1] = y * scale[1] + trans[1];
@@ -151,8 +163,6 @@ vs_exec_run( struct draw_vertex_shader *shader,
vOut[j]->data[0][3] = w;
}
else {
- vOut[j]->clipmask = 0;
- vOut[j]->edgeflag = 1;
vOut[j]->data[0][0] = x;
vOut[j]->data[0][1] = y;
vOut[j]->data[0][2] = z;
diff --git a/src/gallium/auxiliary/draw/draw_vs_llvm.c b/src/gallium/auxiliary/draw/draw_vs_llvm.c
index d29cb18efe4..c8268317efa 100644
--- a/src/gallium/auxiliary/draw/draw_vs_llvm.c
+++ b/src/gallium/auxiliary/draw/draw_vs_llvm.c
@@ -121,37 +121,51 @@ vs_llvm_run( struct draw_vertex_shader *base,
machine->Consts = (float (*)[4]) draw->user.constants;
machine->Inputs = ALIGN16_ASSIGN(inputs);
- machine->Outputs = ALIGN16_ASSIGN(outputs);
+ if (draw->rasterizer->bypass_vs) {
+ /* outputs are just the inputs */
+ machine->Outputs = machine->Inputs;
+ }
+ else {
+ machine->Outputs = ALIGN16_ASSIGN(outputs);
+ }
+
draw->vertex_fetch.fetch_func( draw, machine, elts, count );
- /* run shader */
- gallivm_cpu_vs_exec(shader->llvm_prog,
- machine->Inputs,
- machine->Outputs,
- machine->Consts,
- machine->Temps);
+ if (!draw->rasterizer->bypass_vs) {
+ /* run shader */
+ gallivm_cpu_vs_exec(shader->llvm_prog,
+ machine->Inputs,
+ machine->Outputs,
+ machine->Consts,
+ machine->Temps);
+ }
/* store machine results */
for (j = 0; j < count; j++) {
unsigned slot;
float x, y, z, w;
- if (!draw->rasterizer->bypass_clipping) {
- x = vOut[j]->clip[0] = machine->Outputs[0].xyzw[0].f[j];
- y = vOut[j]->clip[1] = machine->Outputs[0].xyzw[1].f[j];
- z = vOut[j]->clip[2] = machine->Outputs[0].xyzw[2].f[j];
- w = vOut[j]->clip[3] = machine->Outputs[0].xyzw[3].f[j];
+ x = vOut[j]->clip[0] = machine->Outputs[0].xyzw[0].f[j];
+ y = vOut[j]->clip[1] = machine->Outputs[0].xyzw[1].f[j];
+ z = vOut[j]->clip[2] = machine->Outputs[0].xyzw[2].f[j];
+ w = vOut[j]->clip[3] = machine->Outputs[0].xyzw[3].f[j];
+ if (!draw->rasterizer->bypass_clipping) {
vOut[j]->clipmask = compute_clipmask(vOut[j]->clip, draw->plane, draw->nr_planes);
- vOut[j]->edgeflag = 1;
-
+
/* divide by w */
w = 1.0f / w;
x *= w;
y *= w;
- z *= w;
+ z *= w;
+ }
+ else {
+ vOut[j]->clipmask = 0;
+ }
+ vOut[j]->edgeflag = 1;
+ if (!draw->identity_viewport) {
/* Viewport mapping */
vOut[j]->data[0][0] = x * scale[0] + trans[0];
vOut[j]->data[0][1] = y * scale[1] + trans[1];
@@ -159,8 +173,6 @@ vs_llvm_run( struct draw_vertex_shader *base,
vOut[j]->data[0][3] = w;
}
else {
- vOut[j]->clipmask = 0;
- vOut[j]->edgeflag = 1;
vOut[j]->data[0][0] = x;
vOut[j]->data[0][1] = y;
vOut[j]->data[0][2] = z;
diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c
index bc910dc2d04..f40d65df08f 100644
--- a/src/gallium/auxiliary/draw/draw_vs_sse.c
+++ b/src/gallium/auxiliary/draw/draw_vs_sse.c
@@ -126,7 +126,13 @@ vs_sse_run( struct draw_vertex_shader *base,
/* Consts does not require 16 byte alignment. */
machine->Consts = (float (*)[4]) draw->user.constants;
machine->Inputs = ALIGN16_ASSIGN(inputs);
- machine->Outputs = ALIGN16_ASSIGN(outputs);
+ if (draw->rasterizer->bypass_vs) {
+ /* outputs are just the inputs */
+ machine->Outputs = machine->Inputs;
+ }
+ else {
+ machine->Outputs = ALIGN16_ASSIGN(outputs);
+ }
/* Fetch vertices. This may at some point be integrated into the
@@ -137,13 +143,14 @@ vs_sse_run( struct draw_vertex_shader *base,
draw->vertex_fetch.fetch_func( draw, machine, elts, count );
- /* run compiled shader
- */
- shader->func(
- machine->Inputs,
- machine->Outputs,
- machine->Consts,
- machine->Temps );
+ if (!draw->rasterizer->bypass_vs) {
+ /* run compiled shader
+ */
+ shader->func(machine->Inputs,
+ machine->Outputs,
+ machine->Consts,
+ machine->Temps );
+ }
/* XXX: Computing the clipmask and emitting results should be done
@@ -161,14 +168,19 @@ vs_sse_run( struct draw_vertex_shader *base,
if (!draw->rasterizer->bypass_clipping) {
vOut[j]->clipmask = compute_clipmask(vOut[j]->clip, draw->plane, draw->nr_planes);
- vOut[j]->edgeflag = 1;
/* divide by w */
w = 1.0f / w;
x *= w;
y *= w;
z *= w;
-
+ }
+ else {
+ vOut[j]->clipmask = 0;
+ }
+ vOut[j]->edgeflag = 1;
+
+ if (!draw->identity_viewport) {
/* Viewport mapping */
vOut[j]->data[0][0] = x * scale[0] + trans[0];
vOut[j]->data[0][1] = y * scale[1] + trans[1];
@@ -176,8 +188,6 @@ vs_sse_run( struct draw_vertex_shader *base,
vOut[j]->data[0][3] = w;
}
else {
- vOut[j]->clipmask = 0;
- vOut[j]->edgeflag = 1;
vOut[j]->data[0][0] = x;
vOut[j]->data[0][1] = y;
vOut[j]->data[0][2] = z;