diff options
Diffstat (limited to 'src/gallium/auxiliary/draw')
-rw-r--r-- | src/gallium/auxiliary/draw/Makefile | 1 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/SConscript | 1 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_context.c | 8 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_flatshade.c | 55 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_passthrough.c | 473 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_prim.c | 105 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_private.h | 2 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pt.c | 9 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pt.h | 2 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pt_vcache.c | 127 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_vs_exec.c | 28 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_vs_llvm.c | 46 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_vs_sse.c | 34 |
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; |