diff options
44 files changed, 575 insertions, 869 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; diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c index 6e217eb2e06..55f32e6816f 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c @@ -29,8 +29,8 @@ * \file * Implementation of fenced buffers. * - * \author Jos� Fonseca <jrfonseca-at-tungstengraphics-dot-com> - * \author Thomas Hellstr�m <thomas-at-tungstengraphics-dot-com> + * \author José Fonseca <jrfonseca-at-tungstengraphics-dot-com> + * \author Thomas Hellström <thomas-at-tungstengraphics-dot-com> */ @@ -44,7 +44,7 @@ #include "pb_buffer.h" #include "pb_buffer_fenced.h" -#ifndef __MSC__ +#ifndef WIN32 #include <unistd.h> #endif @@ -93,8 +93,6 @@ fenced_buffer(struct pb_buffer *buf) } - - static void _fenced_buffer_list_check_free(struct fenced_buffer_list *fenced_list, int wait) @@ -105,15 +103,6 @@ _fenced_buffer_list_check_free(struct fenced_buffer_list *fenced_list, int signaled = -1; list = fenced_list->delayed.next; - - if (fenced_list->numDelayed > 3) { - unsigned i; - - for (i = 0; i < fenced_list->numDelayed; i += 3) { - list = list->next; - } - } - prev = list->prev; for (; list != &fenced_list->delayed; list = prev, prev = list->prev) { @@ -128,11 +117,17 @@ _fenced_buffer_list_check_free(struct fenced_buffer_list *fenced_list, } } - if (signaled != 0) + if (signaled != 0) { +#if 0 /* XXX: we are assuming that buffers are freed in the same order they * are fenced which may not always be true... */ break; +#else + signaled = -1; + continue; +#endif + } winsys->fence_reference(winsys, &fenced_buf->fence, NULL); @@ -154,8 +149,16 @@ fenced_buffer_destroy(struct pb_buffer *buf) struct fenced_buffer_list *fenced_list = fenced_buf->list; if (fenced_buf->fence) { - LIST_ADDTAIL(&fenced_buf->head, &fenced_list->delayed); - fenced_list->numDelayed++; + struct pipe_winsys *winsys = fenced_list->winsys; + if(winsys->fence_finish(winsys, fenced_buf->fence, 0) != 0) { + LIST_ADDTAIL(&fenced_buf->head, &fenced_list->delayed); + fenced_list->numDelayed++; + } + else { + winsys->fence_reference(winsys, &fenced_buf->fence, NULL); + pb_reference(&fenced_buf->buffer, NULL); + FREE(fenced_buf); + } } else { pb_reference(&fenced_buf->buffer, NULL); @@ -285,7 +288,7 @@ fenced_buffer_list_destroy(struct fenced_buffer_list *fenced_list) /* Wait on outstanding fences */ while (fenced_list->numDelayed) { _glthread_UNLOCK_MUTEX(fenced_list->mutex); -#ifndef __MSC__ +#ifndef WIN32 sched_yield(); #endif _fenced_buffer_list_check_free(fenced_list, 1); diff --git a/src/gallium/drivers/cell/common.h b/src/gallium/drivers/cell/common.h index b0928fefd2e..f430e88b9c1 100644 --- a/src/gallium/drivers/cell/common.h +++ b/src/gallium/drivers/cell/common.h @@ -36,6 +36,7 @@ #include "pipe/p_compiler.h" #include "pipe/p_util.h" #include "pipe/p_format.h" +#include "pipe/p_state.h" /** The standard assert macro doesn't seem to work reliably */ @@ -66,6 +67,8 @@ #define CELL_MAX_SPUS 6 +#define CELL_MAX_SAMPLERS 4 + #define TILE_SIZE 32 @@ -109,7 +112,7 @@ */ struct cell_command_depth_stencil_alpha_test { uint64_t base; /**< Effective address of code start. */ - unsigned size; /**< Size in bytes of test code. */ + unsigned size; /**< Size in bytes of SPE code. */ unsigned read_depth; /**< Flag: should depth be read? */ unsigned read_stencil; /**< Flag: should stencil be read? */ }; @@ -120,14 +123,14 @@ struct cell_command_depth_stencil_alpha_test { */ struct cell_command_blend { uint64_t base; /**< Effective address of code start. */ - unsigned size; /**< Size in bytes of test code. */ + unsigned size; /**< Size in bytes of SPE code. */ unsigned read_fb; /**< Flag: should framebuffer be read? */ }; struct cell_command_logicop { uint64_t base; /**< Effective address of code start. */ - unsigned size; /**< Size in bytes of test code. */ + unsigned size; /**< Size in bytes of SPE code. */ }; @@ -226,10 +229,20 @@ struct cell_command_release_verts }; +struct cell_command_sampler +{ + uint64_t opcode; /**< CELL_CMD_STATE_SAMPLER */ + uint unit; + struct pipe_sampler_state state; +}; + + struct cell_command_texture { + uint64_t opcode; /**< CELL_CMD_STATE_TEXTURE */ + uint unit; void *start; /**< Address in main memory */ - uint width, height; + ushort width, height; }; diff --git a/src/gallium/drivers/cell/ppu/cell_pipe_state.c b/src/gallium/drivers/cell/ppu/cell_pipe_state.c index 00f4be7401e..52c31260505 100644 --- a/src/gallium/drivers/cell/ppu/cell_pipe_state.c +++ b/src/gallium/drivers/cell/ppu/cell_pipe_state.c @@ -273,6 +273,7 @@ cell_set_sampler_textures(struct pipe_context *pipe, pipe_texture_reference((struct pipe_texture **) &cell->texture[i], tex); } + cell->num_textures = num; cell_update_texture_mapping(cell); diff --git a/src/gallium/drivers/cell/ppu/cell_screen.c b/src/gallium/drivers/cell/ppu/cell_screen.c index 124670df255..84b48bf4f1b 100644 --- a/src/gallium/drivers/cell/ppu/cell_screen.c +++ b/src/gallium/drivers/cell/ppu/cell_screen.c @@ -55,11 +55,11 @@ cell_get_param(struct pipe_screen *screen, int param) { switch (param) { case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: - return 8; + return PIPE_MAX_SAMPLERS; case PIPE_CAP_NPOT_TEXTURES: - return 1; + return 0; case PIPE_CAP_TWO_SIDED_STENCIL: - return 1; + return 0; case PIPE_CAP_GLSL: return 1; case PIPE_CAP_S3TC: @@ -67,13 +67,13 @@ cell_get_param(struct pipe_screen *screen, int param) case PIPE_CAP_ANISOTROPIC_FILTER: return 0; case PIPE_CAP_POINT_SPRITE: - return 1; + return 0; case PIPE_CAP_MAX_RENDER_TARGETS: return 1; case PIPE_CAP_OCCLUSION_QUERY: - return 1; + return 0; case PIPE_CAP_TEXTURE_SHADOW_MAP: - return 1; + return 0; case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: return 12; /* max 2Kx2K */ case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: @@ -118,8 +118,12 @@ cell_is_format_supported( struct pipe_screen *screen, { switch (type) { case PIPE_TEXTURE: - /* cell supports all texture formats, XXX for now anyway */ - return TRUE; + /* cell supports most texture formats, XXX for now anyway */ + if (format == PIPE_FORMAT_DXT5_RGBA || + format == PIPE_FORMAT_R8G8B8A8_SRGB) + return FALSE; + else + return TRUE; case PIPE_SURFACE: /* cell supports all (off-screen) surface formats, XXX for now */ return TRUE; diff --git a/src/gallium/drivers/cell/ppu/cell_state_emit.c b/src/gallium/drivers/cell/ppu/cell_state_emit.c index 4c75caa0251..9cae67f0912 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_emit.c +++ b/src/gallium/drivers/cell/ppu/cell_state_emit.c @@ -121,27 +121,36 @@ cell_emit_state(struct cell_context *cell) } if (cell->dirty & CELL_NEW_SAMPLER) { - if (cell->sampler[0]) { - emit_state_cmd(cell, CELL_CMD_STATE_SAMPLER, - cell->sampler[0], sizeof(struct pipe_sampler_state)); + uint i; + for (i = 0; i < CELL_MAX_SAMPLERS; i++) { + if (cell->sampler[i]) { + struct cell_command_sampler *sampler + = cell_batch_alloc(cell, sizeof(*sampler)); + sampler->opcode = CELL_CMD_STATE_SAMPLER; + sampler->unit = i; + sampler->state = *cell->sampler[i]; + } } } if (cell->dirty & CELL_NEW_TEXTURE) { - struct cell_command_texture texture; - if (cell->texture[0]) { - texture.start = cell->texture[0]->tiled_data; - texture.width = cell->texture[0]->base.width[0]; - texture.height = cell->texture[0]->base.height[0]; + uint i; + for (i = 0;i < CELL_MAX_SAMPLERS; i++) { + struct cell_command_texture *texture + = cell_batch_alloc(cell, sizeof(*texture)); + texture->opcode = CELL_CMD_STATE_TEXTURE; + texture->unit = i; + if (cell->texture[i]) { + texture->start = cell->texture[i]->tiled_data; + texture->width = cell->texture[i]->base.width[0]; + texture->height = cell->texture[i]->base.height[0]; + } + else { + texture->start = NULL; + texture->width = 1; + texture->height = 1; + } } - else { - texture.start = NULL; - texture.width = 0; - texture.height = 0; - } - - emit_state_cmd(cell, CELL_CMD_STATE_TEXTURE, - &texture, sizeof(struct cell_command_texture)); } if (cell->dirty & CELL_NEW_VERTEX_INFO) { diff --git a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c index f10025bd7c7..53ae3aa50e7 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c +++ b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c @@ -1164,10 +1164,11 @@ int PC_OFFSET(const struct spe_function *f, const void *d) * masking. * * \bug - * This routine is hard-coded to only work with ARGB8 data. + * Only two framebuffer formats are supported at this time. */ void -cell_generate_logic_op(struct spe_function *f, struct pipe_blend_state *blend, +cell_generate_logic_op(struct spe_function *f, + const struct pipe_blend_state *blend, struct pipe_surface *surf) { const unsigned logic_op = (blend->logicop_enable) @@ -1235,15 +1236,31 @@ cell_generate_logic_op(struct spe_function *f, struct pipe_blend_state *blend, /* Convert fragment colors to framebuffer format in AoS layout. */ - data[0] = 0x00010203; - data[1] = 0x10111213; - data[2] = 0x04050607; - data[3] = 0x14151617; - - data[4] = 0x0c000408; - data[5] = 0x80808080; - data[6] = 0x80808080; - data[7] = 0x80808080; + switch (surf->format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + data[0] = 0x00010203; + data[1] = 0x10111213; + data[2] = 0x04050607; + data[3] = 0x14151617; + data[4] = 0x0c000408; + data[5] = 0x80808080; + data[6] = 0x80808080; + data[7] = 0x80808080; + break; + case PIPE_FORMAT_B8G8R8A8_UNORM: + data[0] = 0x03020100; + data[1] = 0x13121110; + data[2] = 0x07060504; + data[3] = 0x17161514; + data[4] = 0x0804000c; + data[5] = 0x80808080; + data[6] = 0x80808080; + data[7] = 0x80808080; + break; + default: + fprintf(stderr, "CELL: Bad pixel format in cell_generate_logic_op()"); + ASSERT(0); + } spe_ilh(f, tmp[0], 0x0808); spe_lqr(f, shuf_xpose_hi, PC_OFFSET(f, data+0)); diff --git a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.h b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.h index ab4de96c69d..a8267a51331 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.h +++ b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.h @@ -32,7 +32,8 @@ extern void cell_generate_alpha_blend(struct cell_blend_state *cb); extern void -cell_generate_logic_op(struct spe_function *f, struct pipe_blend_state *blend, - struct pipe_surface *surf); +cell_generate_logic_op(struct spe_function *f, + const struct pipe_blend_state *blend, + struct pipe_surface *surf); #endif /* CELL_STATE_PER_FRAGMENT_H */ diff --git a/src/gallium/drivers/cell/spu/spu_main.c b/src/gallium/drivers/cell/spu/spu_main.c index d7f46f80246..7f0473d198c 100644 --- a/src/gallium/drivers/cell/spu/spu_main.c +++ b/src/gallium/drivers/cell/spu/spu_main.c @@ -312,13 +312,13 @@ cmd_state_depth_stencil(const struct cell_command_depth_stencil_alpha_test *stat static void -cmd_state_sampler(const struct pipe_sampler_state *state) +cmd_state_sampler(const struct cell_command_sampler *sampler) { if (Debug) - printf("SPU %u: SAMPLER\n", - spu.init.id); + printf("SPU %u: SAMPLER [%u]\n", + spu.init.id, sampler->unit); - memcpy(&spu.sampler[0], state, sizeof(*state)); + spu.sampler[sampler->unit] = sampler->state; if (spu.sampler[0].min_img_filter == PIPE_TEX_FILTER_LINEAR) spu.sample_texture = sample_texture_bilinear; else @@ -329,17 +329,25 @@ cmd_state_sampler(const struct pipe_sampler_state *state) static void cmd_state_texture(const struct cell_command_texture *texture) { - if (Debug) - printf("SPU %u: TEXTURE at %p size %u x %u\n", - spu.init.id, texture->start, texture->width, texture->height); - - memcpy(&spu.texture, texture, sizeof(*texture)); - spu.tex_size = (vector float) - { spu.texture.width, spu.texture.height, 0.0, 0.0}; - spu.tex_size_mask = (vector unsigned int) - { spu.texture.width - 1, spu.texture.height - 1, 0, 0 }; - spu.tex_size_x_mask = spu_splats(spu.texture.width - 1); - spu.tex_size_y_mask = spu_splats(spu.texture.height - 1); + const uint unit = texture->unit; + const uint width = texture->width; + const uint height = texture->height; + + if (Debug) { + printf("SPU %u: TEXTURE [%u] at %p size %u x %u\n", spu.init.id, + texture->unit, texture->start, + texture->width, texture->height); + } + + spu.texture[unit].start = texture->start; + spu.texture[unit].width = width; + spu.texture[unit].height = height; + + spu.texture[unit].tex_size = (vector float) { width, height, 0.0, 0.0}; + spu.texture[unit].tex_size_mask = (vector unsigned int) + { width - 1, height - 1, 0, 0 }; + spu.texture[unit].tex_size_x_mask = spu_splats(width - 1); + spu.texture[unit].tex_size_y_mask = spu_splats(height - 1); } @@ -471,12 +479,20 @@ cmd_batch(uint opcode) pos += (1 + ROUNDUP8(sizeof(struct cell_command_depth_stencil_alpha_test)) / 8); break; case CELL_CMD_STATE_SAMPLER: - cmd_state_sampler((struct pipe_sampler_state *) &buffer[pos+1]); - pos += (1 + ROUNDUP8(sizeof(struct pipe_sampler_state)) / 8); + { + struct cell_command_sampler *sampler + = (struct cell_command_sampler *) &buffer[pos]; + cmd_state_sampler(sampler); + pos += sizeof(*sampler) / 8; + } break; case CELL_CMD_STATE_TEXTURE: - cmd_state_texture((struct cell_command_texture *) &buffer[pos+1]); - pos += (1 + ROUNDUP8(sizeof(struct cell_command_texture)) / 8); + { + struct cell_command_texture *texture + = (struct cell_command_texture *) &buffer[pos]; + cmd_state_texture(texture); + pos += sizeof(*texture) / 8; + } break; case CELL_CMD_STATE_VERTEX_INFO: cmd_state_vertex_info((struct vertex_info *) &buffer[pos+1]); diff --git a/src/gallium/drivers/cell/spu/spu_main.h b/src/gallium/drivers/cell/spu/spu_main.h index c20452931a9..2bfad3535a1 100644 --- a/src/gallium/drivers/cell/spu/spu_main.h +++ b/src/gallium/drivers/cell/spu/spu_main.h @@ -100,6 +100,17 @@ struct spu_framebuffer { } ALIGN16_ATTRIB; +struct spu_texture +{ + void *start; + uint width, height; + vector float tex_size; + vector unsigned int tex_size_mask; /**< == int(size - 1) */ + vector unsigned int tex_size_x_mask; /**< == int(size - 1) */ + vector unsigned int tex_size_y_mask; /**< == int(size - 1) */ +} ALIGN16_ATTRIB; + + /** * All SPU global/context state will be in singleton object of this type: */ @@ -119,7 +130,7 @@ struct spu_global logicop_func logicop; struct pipe_sampler_state sampler[PIPE_MAX_SAMPLERS]; - struct cell_command_texture texture; + struct spu_texture texture[PIPE_MAX_SAMPLERS]; struct vertex_info vertex_info; @@ -141,11 +152,6 @@ struct spu_global /** for converting RGBA to PIPE_FORMAT_x colors */ vector unsigned char color_shuffle; - vector float tex_size; - vector unsigned int tex_size_mask; /**< == int(size - 1) */ - vector unsigned int tex_size_x_mask; /**< == int(size - 1) */ - vector unsigned int tex_size_y_mask; /**< == int(size - 1) */ - vector float (*sample_texture)(vector float texcoord); } ALIGN16_ATTRIB; diff --git a/src/gallium/drivers/cell/spu/spu_texture.c b/src/gallium/drivers/cell/spu/spu_texture.c index 67eb08196a4..4612501eb3b 100644 --- a/src/gallium/drivers/cell/spu/spu_texture.c +++ b/src/gallium/drivers/cell/spu/spu_texture.c @@ -40,25 +40,29 @@ void invalidate_tex_cache(void) { - spu_dcache_mark_dirty((unsigned) spu.texture.start, - 4 * spu.texture.width * spu.texture.height); + uint unit = 0; + uint bytes = 4 * spu.texture[unit].width + * spu.texture[unit].height; + + spu_dcache_mark_dirty((unsigned) spu.texture[unit].start, bytes); } static uint get_texel(vec_uint4 coordinate) { + const uint unit = 0; vec_uint4 tmp; unsigned x = spu_extract(coordinate, 0); unsigned y = spu_extract(coordinate, 1); - const unsigned tiles_per_row = spu.texture.width / TILE_SIZE; + const unsigned tiles_per_row = spu.texture[unit].width / TILE_SIZE; unsigned tile_offset = sizeof(tile_t) * ((y / TILE_SIZE * tiles_per_row) + (x / TILE_SIZE)); unsigned texel_offset = 4 * (((y % TILE_SIZE) * TILE_SIZE) + (x % TILE_SIZE)); spu_dcache_fetch_unaligned((qword *) & tmp, - spu.texture.start + tile_offset + texel_offset, + spu.texture[unit].start + tile_offset + texel_offset, 4); return spu_extract(tmp, 0); } @@ -67,13 +71,14 @@ get_texel(vec_uint4 coordinate) static void get_four_texels(vec_uint4 x, vec_uint4 y, vec_uint4 *texels) { - const unsigned texture_ea = (uintptr_t) spu.texture.start; + const uint unit = 0; + const unsigned texture_ea = (uintptr_t) spu.texture[unit].start; vec_uint4 tile_x = spu_rlmask(x, -5); vec_uint4 tile_y = spu_rlmask(y, -5); const qword offset_x = si_andi((qword) x, 0x1f); const qword offset_y = si_andi((qword) y, 0x1f); - const qword tiles_per_row = (qword) spu_splats(spu.texture.width / TILE_SIZE); + const qword tiles_per_row = (qword) spu_splats(spu.texture[unit].width / TILE_SIZE); const qword tile_size = (qword) spu_splats(sizeof(tile_t)); qword tile_offset = si_mpya((qword) tile_y, tiles_per_row, (qword) tile_x); @@ -101,9 +106,10 @@ get_four_texels(vec_uint4 x, vec_uint4 y, vec_uint4 *texels) vector float sample_texture_nearest(vector float texcoord) { - vector float tc = spu_mul(texcoord, spu.tex_size); + const uint unit = 0; + vector float tc = spu_mul(texcoord, spu.texture[unit].tex_size); vector unsigned int itc = spu_convtu(tc, 0); /* convert to int */ - itc = spu_and(itc, spu.tex_size_mask); /* mask (GL_REPEAT) */ + itc = spu_and(itc, spu.texture[unit].tex_size_mask); /* mask (GL_REPEAT) */ uint texel = get_texel(itc); return spu_unpack_A8R8G8B8(texel); } @@ -112,10 +118,11 @@ sample_texture_nearest(vector float texcoord) vector float sample_texture_bilinear(vector float texcoord) { + const uint unit = 0; static const vec_uint4 offset_x = {0, 0, 1, 1}; static const vec_uint4 offset_y = {0, 1, 0, 1}; - vector float tc = spu_mul(texcoord, spu.tex_size); + vector float tc = spu_mul(texcoord, spu.texture[unit].tex_size); tc = spu_add(tc, spu_splats(-0.5f)); /* half texel bias */ /* integer texcoords S,T: */ @@ -129,8 +136,8 @@ sample_texture_bilinear(vector float texcoord) x = spu_add(x, offset_x); y = spu_add(y, offset_y); - x = spu_and(x, spu.tex_size_x_mask); - y = spu_and(y, spu.tex_size_y_mask); + x = spu_and(x, spu.texture[unit].tex_size_x_mask); + y = spu_and(y, spu.texture[unit].tex_size_y_mask); get_four_texels(x, y, texels); diff --git a/src/gallium/drivers/cell/spu/spu_tri.c b/src/gallium/drivers/cell/spu/spu_tri.c index 95c629a8aae..17e337bbdf6 100644 --- a/src/gallium/drivers/cell/spu/spu_tri.c +++ b/src/gallium/drivers/cell/spu/spu_tri.c @@ -309,7 +309,7 @@ emit_quad( int x, int y, mask_t mask ) spu.cur_ctile_status = TILE_STATUS_DIRTY; - if (spu.texture.start) { + if (spu.texture[0].start) { /* texture mapping */ vector float texcoords[4]; eval_coeff(2, (float) x, (float) y, texcoords); diff --git a/src/gallium/drivers/i915simple/i915_debug.c b/src/gallium/drivers/i915simple/i915_debug.c index 78102dbac26..9b9111167f8 100644 --- a/src/gallium/drivers/i915simple/i915_debug.c +++ b/src/gallium/drivers/i915simple/i915_debug.c @@ -30,6 +30,7 @@ #include "i915_winsys.h" #include "i915_debug.h" #include "pipe/p_winsys.h" +#include "pipe/p_debug.h" static void @@ -39,11 +40,9 @@ PRINTF( ... ) { va_list args; - char buffer[256]; va_start( args, fmt ); - vsprintf( buffer, fmt, args ); - stream->winsys->printf( stream->winsys, buffer ); + debug_vprintf( fmt, args ); va_end( args ); } @@ -200,14 +199,12 @@ BITS( ... ) { va_list args; - char buffer[256]; unsigned himask = ~0UL >> (31 - (hi)); PRINTF(stream, "\t\t "); va_start( args, fmt ); - vsprintf( buffer, fmt, args ); - stream->winsys->printf( stream->winsys, buffer ); + debug_vprintf( fmt, args ); va_end( args ); PRINTF(stream, ": 0x%x\n", ((dw) & himask) >> (lo)); @@ -231,13 +228,11 @@ FLAG( { if (((dw) >> (bit)) & 1) { va_list args; - char buffer[256]; PRINTF(stream, "\t\t "); va_start( args, fmt ); - vsprintf( buffer, fmt, args ); - stream->winsys->printf( stream->winsys, buffer ); + debug_vprintf( fmt, args ); va_end( args ); PRINTF(stream, "\n"); @@ -877,11 +872,11 @@ i915_dump_batchbuffer( struct i915_context *i915 ) stream.winsys = i915->pipe.winsys; if (!start || !end) { - stream.winsys->printf( stream.winsys, "\n\nBATCH: ???\n"); + debug_printf( "\n\nBATCH: ???\n"); return; } - stream.winsys->printf( stream.winsys, "\n\nBATCH: (%d)\n", bytes / 4); + debug_printf( "\n\nBATCH: (%d)\n", bytes / 4); while (!done && stream.offset < bytes) @@ -893,7 +888,7 @@ i915_dump_batchbuffer( struct i915_context *i915 ) stream.offset >= 0); } - stream.winsys->printf( stream.winsys, "END-BATCH\n\n\n"); + debug_printf( "END-BATCH\n\n\n"); } diff --git a/src/gallium/drivers/i915simple/i915_debug.h b/src/gallium/drivers/i915simple/i915_debug.h index 0bcd0942334..afb63edabf7 100644 --- a/src/gallium/drivers/i915simple/i915_debug.h +++ b/src/gallium/drivers/i915simple/i915_debug.h @@ -83,11 +83,9 @@ I915_DBG( { if ((i915)->debug & FILE_DEBUG_FLAG) { va_list args; - char buffer[256]; va_start( args, fmt ); - vsprintf( buffer, fmt, args ); - i915->pipe.winsys->printf( i915->pipe.winsys, buffer ); + debug_vprintf( fmt, args ); va_end( args ); } } diff --git a/src/gallium/drivers/i915simple/i915_debug_fp.c b/src/gallium/drivers/i915simple/i915_debug_fp.c index ebfdb3d93c5..37a3508fe14 100644 --- a/src/gallium/drivers/i915simple/i915_debug_fp.c +++ b/src/gallium/drivers/i915simple/i915_debug_fp.c @@ -39,11 +39,9 @@ PRINTF( ... ) { va_list args; - char buffer[256]; va_start( args, fmt ); - vsprintf( buffer, fmt, args ); - stream->winsys->printf( stream->winsys, buffer ); + debug_vprintf( fmt, args ); va_end( args ); } diff --git a/src/gallium/drivers/i915simple/i915_screen.c b/src/gallium/drivers/i915simple/i915_screen.c index 8d7bf0b33e0..839b98c0cec 100644 --- a/src/gallium/drivers/i915simple/i915_screen.c +++ b/src/gallium/drivers/i915simple/i915_screen.c @@ -226,9 +226,8 @@ i915_create_screen(struct pipe_winsys *winsys, uint pci_id) break; default: - winsys->printf(winsys, - "%s: unknown pci id 0x%x, cannot create screen\n", - __FUNCTION__, pci_id); + debug_printf("%s: unknown pci id 0x%x, cannot create screen\n", + __FUNCTION__, pci_id); return NULL; } diff --git a/src/gallium/drivers/i965simple/brw_context.c b/src/gallium/drivers/i965simple/brw_context.c index 7c908da6726..a276cc0535d 100644 --- a/src/gallium/drivers/i965simple/brw_context.c +++ b/src/gallium/drivers/i965simple/brw_context.c @@ -77,9 +77,8 @@ struct pipe_context *brw_create(struct pipe_screen *screen, { struct brw_context *brw; - screen->winsys->printf(screen->winsys, - "%s: creating brw_context with pci id 0x%x\n", - __FUNCTION__, pci_id); + debug_printf("%s: creating brw_context with pci id 0x%x\n", + __FUNCTION__, pci_id); brw = CALLOC_STRUCT(brw_context); if (brw == NULL) diff --git a/src/gallium/drivers/i965simple/brw_context.h b/src/gallium/drivers/i965simple/brw_context.h index 0c96ba17327..eeccf367856 100644 --- a/src/gallium/drivers/i965simple/brw_context.h +++ b/src/gallium/drivers/i965simple/brw_context.h @@ -183,12 +183,12 @@ extern int BRW_DEBUG; #define DEBUG_MIPTREE 0x800000
#define DBG(...) do { \
- if (BRW_DEBUG & FILE_DEBUG_FLAG) \
- brw->pipe.winsys->printf(brw->pipe.winsys, __VA_ARGS__); \
+ if (BRW_DEBUG & FILE_DEBUG_FLAG) \
+ debug_printf(__VA_ARGS__); \
} while(0)
#define PRINT(...) do { \
- brw->pipe.winsys->printf(brw->pipe.winsys, __VA_ARGS__); \
+ debug_printf(brw->pipe.winsys, __VA_ARGS__); \
} while(0)
struct brw_state_flags {
diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h index 3238b152b65..9e0f91f202b 100644 --- a/src/gallium/include/pipe/p_format.h +++ b/src/gallium/include/pipe/p_format.h @@ -439,7 +439,8 @@ static INLINE uint pf_get_component_bits( enum pipe_format format, uint comp ) */ static INLINE uint pf_get_bits( enum pipe_format format ) { - if (pf_layout(format) == PIPE_FORMAT_LAYOUT_RGBAZS) { + switch (pf_layout(format)) { + case PIPE_FORMAT_LAYOUT_RGBAZS: return pf_get_component_bits( format, PIPE_FORMAT_COMP_R ) + pf_get_component_bits( format, PIPE_FORMAT_COMP_G ) + @@ -447,11 +448,11 @@ static INLINE uint pf_get_bits( enum pipe_format format ) pf_get_component_bits( format, PIPE_FORMAT_COMP_A ) + pf_get_component_bits( format, PIPE_FORMAT_COMP_Z ) + pf_get_component_bits( format, PIPE_FORMAT_COMP_S ); - } - else { - assert( pf_layout(format) == PIPE_FORMAT_LAYOUT_YCBCR ); - - /* TODO */ + case PIPE_FORMAT_LAYOUT_YCBCR: + assert( format == PIPE_FORMAT_YCBCR || format == PIPE_FORMAT_YCBCR_REV ); + /* return effective bits per pixel */ + return 16; + default: assert( 0 ); return 0; } diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 0eeee47a9a5..a73028814e3 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -111,7 +111,8 @@ struct pipe_rasterizer_state unsigned line_stipple_pattern:16; unsigned line_last_pixel:1; unsigned bypass_clipping:1; - unsigned bypass_vs:1; /**< vertices are already fully transformed */ + unsigned bypass_vs:1; /**< Skip the vertex shader. Note that the shader is + still needed though, to indicate inputs/outputs */ unsigned origin_lower_left:1; /**< Is (0,0) the lower-left corner? */ unsigned flatshade_first:1; /**< take color attribute from the first vertex of a primitive */ diff --git a/src/gallium/include/pipe/p_winsys.h b/src/gallium/include/pipe/p_winsys.h index 1383bd0544a..8569cdcf123 100644 --- a/src/gallium/include/pipe/p_winsys.h +++ b/src/gallium/include/pipe/p_winsys.h @@ -73,10 +73,6 @@ struct pipe_winsys struct pipe_surface *surf, void *context_private ); - /** Debug output */ - void (*printf)( struct pipe_winsys *sws, - const char *, ... ); - /** allocate a new surface (no context dependency) */ struct pipe_surface *(*surface_alloc)(struct pipe_winsys *ws); diff --git a/src/gallium/winsys/SConscript b/src/gallium/winsys/SConscript index f18d3bd2f8e..e8a581adb21 100644 --- a/src/gallium/winsys/SConscript +++ b/src/gallium/winsys/SConscript @@ -1,6 +1,6 @@ Import('*') -if dri: +if 'intel' in env['winsys'] and dri: SConscript([ 'dri/SConscript', ]) diff --git a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c index 789a386500a..77dec9488df 100644 --- a/src/gallium/winsys/dri/intel/intel_winsys_pipe.c +++ b/src/gallium/winsys/dri/intel/intel_winsys_pipe.c @@ -243,15 +243,6 @@ intel_i915_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) -static void -intel_printf( struct pipe_winsys *winsys, const char *fmtString, ... ) -{ - va_list args; - va_start( args, fmtString ); - vfprintf(stderr, fmtString, args); - va_end( args ); -} - static const char * intel_get_name( struct pipe_winsys *winsys ) { @@ -277,7 +268,6 @@ intel_create_pipe_winsys( int fd ) iws->winsys.buffer_unmap = intel_buffer_unmap; iws->winsys.buffer_destroy = intel_buffer_destroy; iws->winsys.flush_frontbuffer = intel_flush_frontbuffer; - iws->winsys.printf = intel_printf; iws->winsys.get_name = intel_get_name; iws->winsys.surface_alloc = intel_i915_surface_alloc; iws->winsys.surface_alloc_storage = intel_i915_surface_alloc_storage; diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c index 74597562798..9a20bdfb699 100644 --- a/src/gallium/winsys/xlib/xm_winsys.c +++ b/src/gallium/winsys/xlib/xm_winsys.c @@ -303,16 +303,6 @@ xm_flush_frontbuffer(struct pipe_winsys *pws, -static void -xm_printf(struct pipe_winsys *pws, const char *fmtString, ...) -{ - va_list args; - va_start( args, fmtString ); - vfprintf(stderr, fmtString, args); - va_end( args ); -} - - static const char * xm_get_name(struct pipe_winsys *pws) { @@ -635,7 +625,6 @@ xmesa_get_pipe_winsys_aub(struct xmesa_visual *xm_vis) ws->base.fence_finish = xm_fence_finish; ws->base.flush_frontbuffer = xm_flush_frontbuffer; - ws->base.printf = xm_printf; ws->base.get_name = xm_get_name; } diff --git a/src/gallium/winsys/xlib/xm_winsys_aub.c b/src/gallium/winsys/xlib/xm_winsys_aub.c index d55d8c39eb5..f42f7fcc5f1 100644 --- a/src/gallium/winsys/xlib/xm_winsys_aub.c +++ b/src/gallium/winsys/xlib/xm_winsys_aub.c @@ -311,15 +311,6 @@ aub_i915_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s) -static void -aub_printf( struct pipe_winsys *winsys, const char *fmtString, ... ) -{ - va_list args; - va_start( args, fmtString ); - vfprintf(stderr, fmtString, args); - va_end( args ); -} - static const char * aub_get_name( struct pipe_winsys *winsys ) { @@ -344,7 +335,6 @@ xmesa_create_pipe_winsys_aub( void ) iws->winsys.buffer_unmap = aub_buffer_unmap; iws->winsys.buffer_destroy = aub_buffer_destroy; iws->winsys.flush_frontbuffer = aub_flush_frontbuffer; - iws->winsys.printf = aub_printf; iws->winsys.get_name = aub_get_name; iws->winsys.surface_alloc = aub_i915_surface_alloc; diff --git a/src/mesa/drivers/x11/xm_winsys.c b/src/mesa/drivers/x11/xm_winsys.c index 2edc6976933..eab9fd38521 100644 --- a/src/mesa/drivers/x11/xm_winsys.c +++ b/src/mesa/drivers/x11/xm_winsys.c @@ -193,15 +193,6 @@ xm_wait_idle(struct pipe_winsys *pws) /* no-op */ } -static void -xm_printf(struct pipe_winsys *pws, const char *fmtString, ...) -{ - va_list args; - va_start( args, fmtString ); - vfprintf(stderr, fmtString, args); - va_end( args ); -} - static const char * xm_get_name(struct pipe_winsys *pws) { @@ -353,7 +344,6 @@ xmesa_create_pipe_winsys( XMesaContext xmesa ) xws->winsys.flush_frontbuffer = xm_flush_frontbuffer; xws->winsys.wait_idle = xm_wait_idle; - xws->winsys.printf = xm_printf; xws->winsys.get_name = xm_get_name; xws->xmesa = xmesa; diff --git a/src/mesa/shader/arbprogram.syn b/src/mesa/shader/arbprogram.syn index 1746a876c30..ba17d638a3a 100644 --- a/src/mesa/shader/arbprogram.syn +++ b/src/mesa/shader/arbprogram.syn @@ -2643,14 +2643,14 @@ white_char ' ' .or '\t' .or '\n' .or '\r'; comment_block - '#' .and .loop comment_char .and new_line; + '#' .and .loop comment_char .and optional_new_line; /* All ASCII characters except '\r', '\n' and '\0' */ comment_char '\x0E'-'\xFF' .or '\x01'-'\x09' .or '\x0B'-'\x0C'; -new_line - '\n' .or crlf .or '\0'; +optional_new_line + '\n' .or crlf .or .true; crlf '\r' .and '\n'; diff --git a/src/mesa/shader/arbprogram_syn.h b/src/mesa/shader/arbprogram_syn.h index 5f3f7d6cf46..e0c901ea8cd 100644 --- a/src/mesa/shader/arbprogram_syn.h +++ b/src/mesa/shader/arbprogram_syn.h @@ -1242,11 +1242,11 @@ "white_char\n" " ' ' .or '\\t' .or '\\n' .or '\\r';\n" "comment_block\n" -" '#' .and .loop comment_char .and new_line;\n" +" '#' .and .loop comment_char .and optional_new_line;\n" "comment_char\n" " '\\x0E'-'\\xFF' .or '\\x01'-'\\x09' .or '\\x0B'-'\\x0C';\n" -"new_line\n" -" '\\n' .or crlf .or '\\0';\n" +"optional_new_line\n" +" '\\n' .or crlf .or .true;\n" "crlf\n" " '\\r' .and '\\n';\n" "semicolon\n" diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c index ec56b25f7ce..975a55d6dc0 100644 --- a/src/mesa/state_tracker/st_cb_bitmap.c +++ b/src/mesa/state_tracker/st_cb_bitmap.c @@ -60,6 +60,19 @@ /** + * glBitmaps are drawn as textured quads. The user's bitmap pattern + * is stored in a texture image. An alpha8 texture format is used. + * The fragment shader samples a bit (texel) from the texture, then + * discards the fragment if the bit is off. + * + * Note that we actually store the inverse image of the bitmap to + * simplify the fragment program. An "on" bit gets stored as texel=0x0 + * and an "off" bit is stored as texel=0xff. Then we kill the + * fragment if the negated texel value is less than zero. + */ + + +/** * The bitmap cache attempts to accumulate multiple glBitmap calls in a * buffer which is then rendered en mass upon a flush, state change, etc. * A wide, short buffer is used to target the common case of a series @@ -102,7 +115,7 @@ make_bitmap_fragment_program(GLcontext *ctx) if (!p) return NULL; - p->NumInstructions = 5; + p->NumInstructions = 3; p->Instructions = _mesa_alloc_instructions(p->NumInstructions); if (!p->Instructions) { @@ -121,33 +134,11 @@ make_bitmap_fragment_program(GLcontext *ctx) p->Instructions[ic].TexSrcTarget = TEXTURE_2D_INDEX; ic++; - /* SWZ tmp0.x, tmp0.x, 1111; # tmp0.x = 1.0 */ - p->Instructions[ic].Opcode = OPCODE_SWZ; - p->Instructions[ic].DstReg.File = PROGRAM_TEMPORARY; - p->Instructions[ic].DstReg.Index = 0; - p->Instructions[ic].DstReg.WriteMask = WRITEMASK_X; - p->Instructions[ic].SrcReg[0].File = PROGRAM_TEMPORARY; - p->Instructions[ic].SrcReg[0].Index = 0; - p->Instructions[ic].SrcReg[0].Swizzle - = MAKE_SWIZZLE4(SWIZZLE_ONE, SWIZZLE_ONE, SWIZZLE_ONE, SWIZZLE_ONE ); - ic++; - - /* SUB tmp0, tmp0.wwww, tmp0.xxxx; # tmp0.w -= 1 */ - p->Instructions[ic].Opcode = OPCODE_SUB; - p->Instructions[ic].DstReg.File = PROGRAM_TEMPORARY; - p->Instructions[ic].DstReg.Index = 0; - p->Instructions[ic].SrcReg[0].File = PROGRAM_TEMPORARY; - p->Instructions[ic].SrcReg[0].Index = 0; - p->Instructions[ic].SrcReg[0].Swizzle = SWIZZLE_WWWW; - p->Instructions[ic].SrcReg[1].File = PROGRAM_TEMPORARY; - p->Instructions[ic].SrcReg[1].Index = 0; - p->Instructions[ic].SrcReg[1].Swizzle = SWIZZLE_XXXX; /* 1.0 */ - ic++; - - /* KIL if tmp0 < 0 */ + /* KIL if -tmp0 < 0 # texel=0 -> keep / texel=0 -> discard */ p->Instructions[ic].Opcode = OPCODE_KIL; p->Instructions[ic].SrcReg[0].File = PROGRAM_TEMPORARY; p->Instructions[ic].SrcReg[0].Index = 0; + p->Instructions[ic].SrcReg[0].NegateBase = NEGATE_XYZW; ic++; /* END; */ @@ -289,7 +280,7 @@ make_bitmap_texture(GLcontext *ctx, GLsizei width, GLsizei height, for (col = 0; col < width; col++) { /* set texel to 255 if bit is set */ - destRow[comp] = (*src & mask) ? 255 : 0; + destRow[comp] = (*src & mask) ? 0x0 : 0xff; destRow += cpp; if (mask == 128U) { @@ -311,7 +302,7 @@ make_bitmap_texture(GLcontext *ctx, GLsizei width, GLsizei height, for (col = 0; col < width; col++) { /* set texel to 255 if bit is set */ - destRow[comp] =(*src & mask) ? 255 : 0; + destRow[comp] =(*src & mask) ? 0x0 : 0xff; destRow += cpp; if (mask == 1U) { @@ -350,16 +341,21 @@ setup_bitmap_vertex_data(struct st_context *st, { struct pipe_context *pipe = st->pipe; const struct gl_framebuffer *fb = st->ctx->DrawBuffer; - const GLboolean invert = (st_fb_orientation(fb) == Y_0_TOP); + const GLfloat fb_width = fb->Width; + const GLfloat fb_height = fb->Height; const GLfloat x0 = x; const GLfloat x1 = x + width; - const GLfloat y0 = invert ? ((int) fb->Height - y - height) : y; - const GLfloat y1 = invert ? (y0 + height) : y + height; + const GLfloat y0 = y; + const GLfloat y1 = y + height; const GLfloat bias = st->bitmap_texcoord_bias; const GLfloat xBias = bias / (x1-x0); const GLfloat yBias = bias / (y1-y0); const GLfloat sLeft = 0.0 + xBias, sRight = 1.0 + xBias; - const GLfloat tTop = 1.0 - yBias, tBot = 1.0 - tTop - yBias; + const GLfloat tTop = yBias, tBot = 1.0 - tTop - yBias; + const GLfloat clip_x0 = x0 / fb_width * 2.0 - 1.0; + const GLfloat clip_y0 = y0 / fb_height * 2.0 - 1.0; + const GLfloat clip_x1 = x1 / fb_width * 2.0 - 1.0; + const GLfloat clip_y1 = y1 / fb_height * 2.0 - 1.0; GLuint i; void *buf; @@ -369,24 +365,26 @@ setup_bitmap_vertex_data(struct st_context *st, sizeof(st->bitmap.vertices)); } - /* positions, texcoords */ - st->bitmap.vertices[0][0][0] = x0; - st->bitmap.vertices[0][0][1] = y0; + /* Positions are in clip coords since we need to do clipping in case + * the bitmap quad goes beyond the window bounds. + */ + st->bitmap.vertices[0][0][0] = clip_x0; + st->bitmap.vertices[0][0][1] = clip_y0; st->bitmap.vertices[0][2][0] = sLeft; st->bitmap.vertices[0][2][1] = tTop; - st->bitmap.vertices[1][0][0] = x1; - st->bitmap.vertices[1][0][1] = y0; + st->bitmap.vertices[1][0][0] = clip_x1; + st->bitmap.vertices[1][0][1] = clip_y0; st->bitmap.vertices[1][2][0] = sRight; st->bitmap.vertices[1][2][1] = tTop; - st->bitmap.vertices[2][0][0] = x1; - st->bitmap.vertices[2][0][1] = y1; + st->bitmap.vertices[2][0][0] = clip_x1; + st->bitmap.vertices[2][0][1] = clip_y1; st->bitmap.vertices[2][2][0] = sRight; st->bitmap.vertices[2][2][1] = tBot; - st->bitmap.vertices[3][0][0] = x0; - st->bitmap.vertices[3][0][1] = y1; + st->bitmap.vertices[3][0][0] = clip_x0; + st->bitmap.vertices[3][0][1] = clip_y1; st->bitmap.vertices[3][2][0] = sLeft; st->bitmap.vertices[3][2][1] = tBot; @@ -437,17 +435,12 @@ draw_bitmap_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, cso_save_rasterizer(cso); cso_save_samplers(cso); + cso_save_sampler_textures(cso); + cso_save_viewport(cso); /* rasterizer state: just scissor */ - { - struct pipe_rasterizer_state rasterizer; - memset(&rasterizer, 0, sizeof(rasterizer)); - if (ctx->Scissor.Enabled) - rasterizer.scissor = 1; - rasterizer.bypass_clipping = 1; - - cso_set_rasterizer(cso, &rasterizer); - } + st->bitmap.rasterizer.scissor = ctx->Scissor.Enabled; + cso_set_rasterizer(cso, &st->bitmap.rasterizer); /* fragment shader state: TEX lookup program */ pipe->bind_fs_state(pipe, stfp->driver_shader); @@ -456,21 +449,26 @@ draw_bitmap_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, pipe->bind_vs_state(pipe, st->bitmap.vs); /* sampler / texture state */ + cso_single_sampler(cso, 0, &st->bitmap.sampler); + cso_single_sampler_done(cso); + pipe->set_sampler_textures(pipe, 1, &pt); + + /* viewport state: viewport matching window dims */ { - struct pipe_sampler_state sampler; - memset(&sampler, 0, sizeof(sampler)); - sampler.wrap_s = PIPE_TEX_WRAP_CLAMP; - sampler.wrap_t = PIPE_TEX_WRAP_CLAMP; - sampler.wrap_r = PIPE_TEX_WRAP_CLAMP; - sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST; - sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; - sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST; - sampler.normalized_coords = 1; - - cso_single_sampler(cso, 0, &sampler); - cso_single_sampler_done(cso); - - pipe->set_sampler_textures(pipe, 1, &pt); + const struct gl_framebuffer *fb = st->ctx->DrawBuffer; + const GLboolean invert = (st_fb_orientation(fb) == Y_0_TOP); + const float width = fb->Width; + const float height = fb->Height; + struct pipe_viewport_state vp; + vp.scale[0] = 0.5 * width; + vp.scale[1] = height * (invert ? -0.5 : 0.5); + vp.scale[2] = 1.0; + vp.scale[3] = 1.0; + vp.translate[0] = 0.5 * width; + vp.translate[1] = 0.5 * height; + vp.translate[2] = 0.0; + vp.translate[3] = 0.0; + cso_set_viewport(cso, &vp); } /* draw textured quad */ @@ -487,18 +485,18 @@ draw_bitmap_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, /* restore state */ cso_restore_rasterizer(cso); cso_restore_samplers(cso); + cso_restore_sampler_textures(cso); + cso_restore_viewport(cso); /* shaders don't go through cso yet */ pipe->bind_fs_state(pipe, st->fp->driver_shader); pipe->bind_vs_state(pipe, st->vp->driver_shader); - pipe->set_sampler_textures(pipe, ctx->st->state.num_textures, - ctx->st->state.sampler_texture); } static void reset_cache(struct st_context *st) { - memset(st->bitmap.cache->buffer, 0, sizeof(st->bitmap.cache->buffer)); + memset(st->bitmap.cache->buffer, 0xff, sizeof(st->bitmap.cache->buffer)); st->bitmap.cache->empty = GL_TRUE; st->bitmap.cache->xmin = 1000000; @@ -635,7 +633,7 @@ accum_bitmap(struct st_context *st, /* XXX try to combine this code with code in make_bitmap_texture() */ #define SET_PIXEL(COL, ROW) \ - cache->buffer[py + (ROW)][px + (COL)] = 0xff; + cache->buffer[py + (ROW)][px + (COL)] = 0x0; for (row = 0; row < height; row++) { const GLubyte *src = (const GLubyte *) _mesa_image_address2d(unpack, @@ -742,6 +740,22 @@ st_init_bitmap_functions(struct dd_function_table *functions) void st_init_bitmap(struct st_context *st) { + struct pipe_sampler_state *sampler = &st->bitmap.sampler; + + /* init sampler state once */ + memset(sampler, 0, sizeof(*sampler)); + sampler->wrap_s = PIPE_TEX_WRAP_CLAMP; + sampler->wrap_t = PIPE_TEX_WRAP_CLAMP; + sampler->wrap_r = PIPE_TEX_WRAP_CLAMP; + sampler->min_img_filter = PIPE_TEX_FILTER_NEAREST; + sampler->min_mip_filter = PIPE_TEX_MIPFILTER_NONE; + sampler->mag_img_filter = PIPE_TEX_FILTER_NEAREST; + sampler->normalized_coords = 1; + + /* init baseline rasterizer state once */ + memset(&st->bitmap.rasterizer, 0, sizeof(st->bitmap.rasterizer)); + st->bitmap.rasterizer.bypass_vs = 1; + init_bitmap_cache(st); } diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index 43cc21d1fb4..c181575f158 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -530,14 +530,13 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, cso_save_rasterizer(cso); cso_save_viewport(cso); cso_save_samplers(cso); + cso_save_sampler_textures(cso); /* rasterizer state: just scissor */ { struct pipe_rasterizer_state rasterizer; memset(&rasterizer, 0, sizeof(rasterizer)); - if (ctx->Scissor.Enabled) - rasterizer.scissor = 1; - + rasterizer.scissor = ctx->Scissor.Enabled; cso_set_rasterizer(cso, &rasterizer); } @@ -581,9 +580,7 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, } /* texture state: */ - { - pipe->set_sampler_textures(pipe, 1, &pt); - } + pipe->set_sampler_textures(pipe, 1, &pt); /* Compute window coords (y=0=bottom) with pixel zoom. * Recall that these coords are transformed by the current @@ -604,12 +601,11 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z, cso_restore_rasterizer(cso); cso_restore_viewport(cso); cso_restore_samplers(cso); + cso_restore_sampler_textures(cso); + /* shaders don't go through cso yet */ pipe->bind_fs_state(pipe, st->fp->driver_shader); pipe->bind_vs_state(pipe, st->vp->driver_shader); - - pipe->set_sampler_textures(pipe, ctx->st->state.num_textures, - ctx->st->state.sampler_texture); } diff --git a/src/mesa/state_tracker/st_cb_flush.c b/src/mesa/state_tracker/st_cb_flush.c index e321b401e2d..1de3676bda6 100644 --- a/src/mesa/state_tracker/st_cb_flush.c +++ b/src/mesa/state_tracker/st_cb_flush.c @@ -105,7 +105,7 @@ static void st_glFlush(GLcontext *ctx) void st_finish( struct st_context *st ) { - struct pipe_fence_handle *fence; + struct pipe_fence_handle *fence = NULL; st_gl_flush(st, PIPE_FLUSH_RENDER_CACHE, &fence); diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index 85e3d47e1aa..44705bc89a3 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -148,6 +148,8 @@ struct st_context struct st_fragment_program *program; /**< bitmap tex/kil program */ GLuint user_prog_sn; /**< user fragment program serial no. */ struct st_fragment_program *combined_prog; + struct pipe_rasterizer_state rasterizer; + struct pipe_sampler_state sampler; struct pipe_shader_state vert_shader; void *vs; float vertices[4][3][4]; /**< vertex pos + color + texcoord */ |