summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorStephane Marchesin <marchesin@icps.u-strasbg.fr>2008-04-02 05:10:52 +0200
committerStephane Marchesin <marchesin@icps.u-strasbg.fr>2008-04-02 05:10:52 +0200
commit901700888e5b4ec4dbec6ac924b542c780edaf52 (patch)
tree7050fa76b0b30b68a1170ed590d59011fd6d2d3c /src
parentb1a361ba7a565063200c033e4939e6b28c006b13 (diff)
parentae87909d0d261d0f4e888f6a167e6329eb129a87 (diff)
Merge branch 'gallium-0.1' of git+ssh://marcheu@git.freedesktop.org/git/nouveau/mesa into gallium-0.1
Diffstat (limited to 'src')
-rw-r--r--src/gallium/auxiliary/draw/Makefile1
-rw-r--r--src/gallium/auxiliary/draw/SConscript1
-rw-r--r--src/gallium/auxiliary/draw/draw_context.c8
-rw-r--r--src/gallium/auxiliary/draw/draw_flatshade.c55
-rw-r--r--src/gallium/auxiliary/draw/draw_passthrough.c473
-rw-r--r--src/gallium/auxiliary/draw/draw_prim.c105
-rw-r--r--src/gallium/auxiliary/draw/draw_private.h2
-rw-r--r--src/gallium/auxiliary/draw/draw_pt.c9
-rw-r--r--src/gallium/auxiliary/draw/draw_pt.h2
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_vcache.c127
-rw-r--r--src/gallium/auxiliary/draw/draw_vs_exec.c28
-rw-r--r--src/gallium/auxiliary/draw/draw_vs_llvm.c46
-rw-r--r--src/gallium/auxiliary/draw/draw_vs_sse.c34
-rw-r--r--src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c39
-rw-r--r--src/gallium/drivers/cell/common.h21
-rw-r--r--src/gallium/drivers/cell/ppu/cell_pipe_state.c1
-rw-r--r--src/gallium/drivers/cell/ppu/cell_screen.c20
-rw-r--r--src/gallium/drivers/cell/ppu/cell_state_emit.c41
-rw-r--r--src/gallium/drivers/cell/ppu/cell_state_per_fragment.c39
-rw-r--r--src/gallium/drivers/cell/ppu/cell_state_per_fragment.h5
-rw-r--r--src/gallium/drivers/cell/spu/spu_main.c54
-rw-r--r--src/gallium/drivers/cell/spu/spu_main.h18
-rw-r--r--src/gallium/drivers/cell/spu/spu_texture.c29
-rw-r--r--src/gallium/drivers/cell/spu/spu_tri.c2
-rw-r--r--src/gallium/drivers/i915simple/i915_debug.c19
-rw-r--r--src/gallium/drivers/i915simple/i915_debug.h4
-rw-r--r--src/gallium/drivers/i915simple/i915_debug_fp.c4
-rw-r--r--src/gallium/drivers/i915simple/i915_screen.c5
-rw-r--r--src/gallium/drivers/i965simple/brw_context.c5
-rw-r--r--src/gallium/drivers/i965simple/brw_context.h6
-rw-r--r--src/gallium/drivers/nv40/nv40_context.h6
-rw-r--r--src/gallium/drivers/nv40/nv40_state.c35
-rw-r--r--src/gallium/drivers/nv40/nv40_state.h1
-rw-r--r--src/gallium/drivers/nv40/nv40_state_emit.c20
-rw-r--r--src/gallium/drivers/nv40/nv40_vbo.c2
-rw-r--r--src/gallium/drivers/nv40/nv40_vertprog.c101
-rw-r--r--src/gallium/include/pipe/p_format.h13
-rw-r--r--src/gallium/include/pipe/p_state.h3
-rw-r--r--src/gallium/include/pipe/p_winsys.h4
-rw-r--r--src/gallium/winsys/SConscript2
-rw-r--r--src/gallium/winsys/dri/intel/intel_winsys_pipe.c10
-rw-r--r--src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c10
-rw-r--r--src/gallium/winsys/xlib/xm_winsys.c11
-rw-r--r--src/gallium/winsys/xlib/xm_winsys_aub.c10
-rw-r--r--src/mesa/drivers/x11/xm_winsys.c10
-rw-r--r--src/mesa/shader/arbprogram.syn6
-rw-r--r--src/mesa/shader/arbprogram_syn.h6
-rw-r--r--src/mesa/state_tracker/st_cb_bitmap.c148
-rw-r--r--src/mesa/state_tracker/st_cb_drawpixels.c14
-rw-r--r--src/mesa/state_tracker/st_cb_flush.c2
-rw-r--r--src/mesa/state_tracker/st_context.h2
51 files changed, 716 insertions, 903 deletions
diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile
index 0c7ce5da5b..a0db2e4555 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 9b3e7247c5..981225a8c2 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 10bf9f54c1..d0d5f66b37 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 ccad71d695..af2cb05c98 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 2198079a88..0000000000
--- 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 <keith@tungstengraphics.com>
- */
-
-
-/* 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 ddcde01d9a..4452376a70 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 8eb2f515cb..9a9b25297f 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 3ec31ec25f..2ea96c686d 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 439fa4c881..f878616079 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 da9a3a52ae..16ffedf580 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 487d0ea7f4..c6e503686a 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 d29cb18efe..c8268317ef 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 bc910dc2d0..f40d65df08 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 6e217eb2e0..55f32e6816 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 b0928fefd2..f430e88b9c 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 00f4be7401..52c3126050 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 124670df25..84b48bf4f1 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 4c75caa025..9cae67f091 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 f10025bd7c..53ae3aa50e 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 ab4de96c69..a8267a5133 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 d7f46f8024..7f0473d198 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 c20452931a..2bfad3535a 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 67eb08196a..4612501eb3 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 95c629a8aa..17e337bbdf 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 78102dbac2..9b9111167f 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 0bcd094233..afb63edabf 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 ebfdb3d93c..37a3508fe1 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 8d7bf0b33e..839b98c0ce 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 7c908da672..a276cc0535 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 0c96ba1732..eeccf36785 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/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h
index b50f6f8fef..525eef8d63 100644
--- a/src/gallium/drivers/nv40/nv40_context.h
+++ b/src/gallium/drivers/nv40/nv40_context.h
@@ -133,7 +133,7 @@ struct nv40_context {
unsigned fallback_swrast;
/* Context state */
- unsigned dirty;
+ unsigned dirty, draw_dirty;
struct pipe_scissor_state scissor;
unsigned stipple[32];
struct pipe_clip_state clip;
@@ -153,8 +153,10 @@ struct nv40_context {
unsigned nr_samplers;
unsigned nr_textures;
unsigned dirty_samplers;
- struct pipe_vertex_buffer vtxbuf[PIPE_ATTRIB_MAX];
+ struct pipe_vertex_buffer vtxbuf[PIPE_ATTRIB_MAX];
+ unsigned vtxbuf_nr;
struct pipe_vertex_element vtxelt[PIPE_ATTRIB_MAX];
+ unsigned vtxelt_nr;
};
static INLINE struct nv40_context *
diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c
index 1417c95e75..5dc2991212 100644
--- a/src/gallium/drivers/nv40/nv40_state.c
+++ b/src/gallium/drivers/nv40/nv40_state.c
@@ -423,10 +423,9 @@ nv40_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso)
struct nv40_context *nv40 = nv40_context(pipe);
struct nv40_rasterizer_state *rsso = hwcso;
- draw_set_rasterizer_state(nv40->draw, &rsso->pipe);
-
nv40->rasterizer = hwcso;
nv40->dirty |= NV40_NEW_RAST;
+ nv40->draw_dirty |= NV40_NEW_RAST;
}
static void
@@ -445,19 +444,20 @@ nv40_depth_stencil_alpha_state_create(struct pipe_context *pipe,
struct nv40_context *nv40 = nv40_context(pipe);
struct nv40_zsa_state *zsaso = CALLOC(1, sizeof(*zsaso));
struct nouveau_stateobj *so = so_new(32, 0);
+ struct nouveau_grobj *curie = nv40->screen->curie;
- so_method(so, nv40->screen->curie, NV40TCL_DEPTH_FUNC, 3);
+ so_method(so, curie, NV40TCL_DEPTH_FUNC, 3);
so_data (so, nvgl_comparison_op(cso->depth.func));
so_data (so, cso->depth.writemask ? 1 : 0);
so_data (so, cso->depth.enabled ? 1 : 0);
- so_method(so, nv40->screen->curie, NV40TCL_ALPHA_TEST_ENABLE, 3);
+ so_method(so, curie, NV40TCL_ALPHA_TEST_ENABLE, 3);
so_data (so, cso->alpha.enabled ? 1 : 0);
so_data (so, nvgl_comparison_op(cso->alpha.func));
so_data (so, float_to_ubyte(cso->alpha.ref));
if (cso->stencil[0].enabled) {
- so_method(so, nv40->screen->curie, NV40TCL_STENCIL_FRONT_ENABLE, 8);
+ so_method(so, curie, NV40TCL_STENCIL_FRONT_ENABLE, 8);
so_data (so, cso->stencil[0].enabled ? 1 : 0);
so_data (so, cso->stencil[0].write_mask);
so_data (so, nvgl_comparison_op(cso->stencil[0].func));
@@ -467,12 +467,12 @@ nv40_depth_stencil_alpha_state_create(struct pipe_context *pipe,
so_data (so, nvgl_stencil_op(cso->stencil[0].zfail_op));
so_data (so, nvgl_stencil_op(cso->stencil[0].zpass_op));
} else {
- so_method(so, nv40->screen->curie, NV40TCL_STENCIL_FRONT_ENABLE, 1);
+ so_method(so, curie, NV40TCL_STENCIL_FRONT_ENABLE, 1);
so_data (so, 0);
}
if (cso->stencil[1].enabled) {
- so_method(so, nv40->screen->curie, NV40TCL_STENCIL_BACK_ENABLE, 8);
+ so_method(so, curie, NV40TCL_STENCIL_BACK_ENABLE, 8);
so_data (so, cso->stencil[1].enabled ? 1 : 0);
so_data (so, cso->stencil[1].write_mask);
so_data (so, nvgl_comparison_op(cso->stencil[1].func));
@@ -482,7 +482,7 @@ nv40_depth_stencil_alpha_state_create(struct pipe_context *pipe,
so_data (so, nvgl_stencil_op(cso->stencil[1].zfail_op));
so_data (so, nvgl_stencil_op(cso->stencil[1].zpass_op));
} else {
- so_method(so, nv40->screen->curie, NV40TCL_STENCIL_BACK_ENABLE, 1);
+ so_method(so, curie, NV40TCL_STENCIL_BACK_ENABLE, 1);
so_data (so, 0);
}
@@ -529,10 +529,9 @@ nv40_vp_state_bind(struct pipe_context *pipe, void *hwcso)
struct nv40_context *nv40 = nv40_context(pipe);
struct nv40_vertex_program *vp = hwcso;
- draw_bind_vertex_shader(nv40->draw, vp ? vp->draw : NULL);
-
nv40->vertprog = hwcso;
nv40->dirty |= NV40_NEW_VERTPROG;
+ nv40->draw_dirty |= NV40_NEW_VERTPROG;
}
static void
@@ -595,10 +594,9 @@ nv40_set_clip_state(struct pipe_context *pipe,
{
struct nv40_context *nv40 = nv40_context(pipe);
- draw_set_clip_state(nv40->draw, clip);
-
nv40->clip = *clip;
nv40->dirty |= NV40_NEW_UCP;
+ nv40->draw_dirty |= NV40_NEW_UCP;
}
static void
@@ -653,10 +651,9 @@ nv40_set_viewport_state(struct pipe_context *pipe,
{
struct nv40_context *nv40 = nv40_context(pipe);
- draw_set_viewport_state(nv40->draw, vpt);
-
nv40->viewport = *vpt;
nv40->dirty |= NV40_NEW_VIEWPORT;
+ nv40->draw_dirty |= NV40_NEW_VIEWPORT;
}
static void
@@ -665,10 +662,11 @@ nv40_set_vertex_buffers(struct pipe_context *pipe, unsigned count,
{
struct nv40_context *nv40 = nv40_context(pipe);
- draw_set_vertex_buffers(nv40->draw, count, vb);
-
memcpy(nv40->vtxbuf, vb, sizeof(*vb) * count);
+ nv40->vtxbuf_nr = count;
+
nv40->dirty |= NV40_NEW_ARRAYS;
+ nv40->draw_dirty |= NV40_NEW_ARRAYS;
}
static void
@@ -677,10 +675,11 @@ nv40_set_vertex_elements(struct pipe_context *pipe, unsigned count,
{
struct nv40_context *nv40 = nv40_context(pipe);
- draw_set_vertex_elements(nv40->draw, count, ve);
-
memcpy(nv40->vtxelt, ve, sizeof(*ve) * count);
+ nv40->vtxelt_nr = count;
+
nv40->dirty |= NV40_NEW_ARRAYS;
+ nv40->draw_dirty |= NV40_NEW_ARRAYS;
}
void
diff --git a/src/gallium/drivers/nv40/nv40_state.h b/src/gallium/drivers/nv40/nv40_state.h
index ab2866eb7a..e018464c9f 100644
--- a/src/gallium/drivers/nv40/nv40_state.h
+++ b/src/gallium/drivers/nv40/nv40_state.h
@@ -42,6 +42,7 @@ struct nv40_vertex_program {
uint32_t ir;
uint32_t or;
+ uint32_t clip_ctrl;
struct nouveau_stateobj *so;
};
diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c
index 74feb6d4bf..722b9f31e6 100644
--- a/src/gallium/drivers/nv40/nv40_state_emit.c
+++ b/src/gallium/drivers/nv40/nv40_state_emit.c
@@ -144,6 +144,8 @@ nv40_state_validate(struct nv40_context *nv40)
boolean
nv40_state_validate_swtnl(struct nv40_context *nv40)
{
+ struct draw_context *draw = nv40->draw;
+
/* Setup for swtnl */
if (nv40->render_mode == HW) {
NOUVEAU_ERR("hw->swtnl 0x%08x\n", nv40->fallback_swtnl);
@@ -155,12 +157,30 @@ nv40_state_validate_swtnl(struct nv40_context *nv40)
nv40->render_mode = SWTNL;
}
+ if (nv40->draw_dirty & NV40_NEW_VERTPROG)
+ draw_bind_vertex_shader(draw, nv40->vertprog->draw);
+
+ if (nv40->draw_dirty & NV40_NEW_RAST)
+ draw_set_rasterizer_state(draw, &nv40->rasterizer->pipe);
+
+ if (nv40->draw_dirty & NV40_NEW_UCP)
+ draw_set_clip_state(draw, &nv40->clip);
+
+ if (nv40->draw_dirty & NV40_NEW_VIEWPORT)
+ draw_set_viewport_state(draw, &nv40->viewport);
+
+ if (nv40->draw_dirty & NV40_NEW_ARRAYS) {
+ draw_set_vertex_buffers(draw, nv40->vtxbuf_nr, nv40->vtxbuf);
+ draw_set_vertex_elements(draw, nv40->vtxelt_nr, nv40->vtxelt);
+ }
+
nv40_state_do_validate(nv40, swtnl_states);
if (nv40->fallback_swrast) {
NOUVEAU_ERR("swtnl->swrast 0x%08x\n", nv40->fallback_swrast);
return FALSE;
}
+ nv40->draw_dirty = 0;
return TRUE;
}
diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c
index b66bf26afb..bc53924a67 100644
--- a/src/gallium/drivers/nv40/nv40_vbo.c
+++ b/src/gallium/drivers/nv40/nv40_vbo.c
@@ -32,7 +32,7 @@ nv40_vbo_format_to_hw(enum pipe_format pipe, unsigned *fmt, unsigned *ncomp)
case PIPE_FORMAT_R16G16_SSCALED:
case PIPE_FORMAT_R16G16B16_SSCALED:
case PIPE_FORMAT_R16G16B16A16_SSCALED:
- *fmt = 5;
+ *fmt = NV40TCL_VTXFMT_TYPE_USHORT;
break;
default:
pf_sprint_name(fs, pipe);
diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c
index 40ef7174a4..08d3f387e0 100644
--- a/src/gallium/drivers/nv40/nv40_vertprog.c
+++ b/src/gallium/drivers/nv40/nv40_vertprog.c
@@ -37,6 +37,8 @@
#define neg(s) nv40_sr_neg((s))
#define abs(s) nv40_sr_abs((s))
+#define NV40_VP_INST_DEST_CLIP(n) ((~0 - 6) + (n))
+
struct nv40_vpc {
struct nv40_vertex_program *vp;
@@ -200,6 +202,36 @@ emit_dst(struct nv40_vpc *vpc, uint32_t *hw, int slot, struct nv40_sreg dst)
case NV40_VP_INST_DEST_TC(5): vp->or |= (1 << 19); break;
case NV40_VP_INST_DEST_TC(6): vp->or |= (1 << 20); break;
case NV40_VP_INST_DEST_TC(7): vp->or |= (1 << 21); break;
+ case NV40_VP_INST_DEST_CLIP(0):
+ vp->or |= (1 << 6);
+ vp->clip_ctrl |= NV40TCL_CLIP_PLANE_ENABLE_PLANE0;
+ dst.index = NV40_VP_INST_DEST_FOGC;
+ break;
+ case NV40_VP_INST_DEST_CLIP(1):
+ vp->or |= (1 << 7);
+ vp->clip_ctrl |= NV40TCL_CLIP_PLANE_ENABLE_PLANE1;
+ dst.index = NV40_VP_INST_DEST_FOGC;
+ break;
+ case NV40_VP_INST_DEST_CLIP(2):
+ vp->or |= (1 << 8);
+ vp->clip_ctrl |= NV40TCL_CLIP_PLANE_ENABLE_PLANE2;
+ dst.index = NV40_VP_INST_DEST_FOGC;
+ break;
+ case NV40_VP_INST_DEST_CLIP(3):
+ vp->or |= (1 << 9);
+ vp->clip_ctrl |= NV40TCL_CLIP_PLANE_ENABLE_PLANE3;
+ dst.index = NV40_VP_INST_DEST_PSZ;
+ break;
+ case NV40_VP_INST_DEST_CLIP(4):
+ vp->or |= (1 << 10);
+ vp->clip_ctrl |= NV40TCL_CLIP_PLANE_ENABLE_PLANE4;
+ dst.index = NV40_VP_INST_DEST_PSZ;
+ break;
+ case NV40_VP_INST_DEST_CLIP(5):
+ vp->or |= (1 << 11);
+ vp->clip_ctrl |= NV40TCL_CLIP_PLANE_ENABLE_PLANE5;
+ dst.index = NV40_VP_INST_DEST_PSZ;
+ break;
default:
break;
}
@@ -391,6 +423,11 @@ nv40_vertprog_parse_instruction(struct nv40_vpc *vpc,
int ai = -1, ci = -1, ii = -1;
int i;
+ struct {
+ struct nv40_sreg dst;
+ unsigned m;
+ } clip;
+
if (finst->Instruction.Opcode == TGSI_OPCODE_END)
return TRUE;
@@ -464,6 +501,47 @@ nv40_vertprog_parse_instruction(struct nv40_vpc *vpc,
dst = tgsi_dst(vpc, &finst->FullDstRegisters[0]);
mask = tgsi_mask(finst->FullDstRegisters[0].DstRegister.WriteMask);
+ /* If writing to clip distance regs, need to modify instruction to
+ * change which component is written to. On NV40 the clip regs
+ * are the unused components (yzw) of FOGC/PSZ.
+ */
+ clip.dst = none;
+ if (dst.type == NV40SR_OUTPUT &&
+ dst.index >= NV40_VP_INST_DEST_CLIP(0) &&
+ dst.index <= NV40_VP_INST_DEST_CLIP(5)) {
+ unsigned n = dst.index - NV40_VP_INST_DEST_CLIP(0);
+ unsigned m[] =
+ { MASK_Y, MASK_Z, MASK_W, MASK_Y, MASK_Z, MASK_W };
+
+ /* Some instructions we can get away with swizzling and/or
+ * changing the writemask. Others, we'll use a temp reg.
+ */
+ switch (finst->Instruction.Opcode) {
+ case TGSI_OPCODE_DST:
+ case TGSI_OPCODE_EXP:
+ case TGSI_OPCODE_LIT:
+ case TGSI_OPCODE_LOG:
+ case TGSI_OPCODE_XPD:
+ clip.dst = dst;
+ clip.m = m[n];
+ dst = temp(vpc);
+ break;
+ case TGSI_OPCODE_DP3:
+ case TGSI_OPCODE_DP4:
+ case TGSI_OPCODE_DPH:
+ case TGSI_OPCODE_POW:
+ case TGSI_OPCODE_RCP:
+ case TGSI_OPCODE_RSQ:
+ mask = m[n];
+ break;
+ default:
+ for (i = 0; i < finst->Instruction.NumSrcRegs; i++)
+ src[i] = swz(src[i], X, X, X, X);
+ mask = m[n];
+ break;
+ }
+ }
+
switch (finst->Instruction.Opcode) {
case TGSI_OPCODE_ABS:
arith(vpc, 0, OP_MOV, dst, mask, abs(src[0]), none, none);
@@ -561,6 +639,11 @@ nv40_vertprog_parse_instruction(struct nv40_vpc *vpc,
return FALSE;
}
+ if (clip.dst.type != NV40SR_NONE) {
+ arith(vpc, 0, OP_MOV, clip.dst, clip.m,
+ swz(dst, X, X, X, X), none, none);
+ }
+
release_temps(vpc);
return TRUE;
}
@@ -612,6 +695,15 @@ nv40_vertprog_parse_decl_output(struct nv40_vpc *vpc,
return FALSE;
}
break;
+#if 0
+ case TGSI_SEMANTIC_CLIP:
+ if (fdec->Semantic.SemanticIndex >= 6) {
+ NOUVEAU_ERR("bad clip distance index\n");
+ return FALSE;
+ }
+ hw = NV40_VP_INST_DEST_CLIP(fdec->Semantic.SemanticIndex);
+ break;
+#endif
default:
NOUVEAU_ERR("bad output semantic\n");
return FALSE;
@@ -782,6 +874,7 @@ nv40_vertprog_validate(struct nv40_context *nv40)
{
struct nouveau_winsys *nvws = nv40->nvws;
struct pipe_winsys *ws = nv40->pipe.winsys;
+ struct nouveau_grobj *curie = nv40->screen->curie;
struct nv40_vertex_program *vp;
struct pipe_buffer *constbuf;
boolean upload_code = FALSE, upload_data = FALSE;
@@ -825,12 +918,14 @@ check_gpu_resources:
assert(0);
}
- so = so_new(5, 0);
- so_method(so, nv40->screen->curie, NV40TCL_VP_START_FROM_ID, 1);
+ so = so_new(7, 0);
+ so_method(so, curie, NV40TCL_VP_START_FROM_ID, 1);
so_data (so, vp->exec->start);
- so_method(so, nv40->screen->curie, NV40TCL_VP_ATTRIB_EN, 2);
+ so_method(so, curie, NV40TCL_VP_ATTRIB_EN, 2);
so_data (so, vp->ir);
so_data (so, vp->or);
+ so_method(so, curie, NV40TCL_CLIP_PLANE_ENABLE, 1);
+ so_data (so, vp->clip_ctrl);
so_ref(so, &vp->so);
upload_code = TRUE;
diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h
index 3238b152b6..9e0f91f202 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 0eeee47a9a..a73028814e 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 1383bd0544..8569cdcf12 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 f18d3bd2f8..e8a581adb2 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 789a386500..77dec9488d 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/dri/nouveau/nouveau_winsys_pipe.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c
index 453b3623f4..b1bf9c521a 100644
--- a/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c
+++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys_pipe.c
@@ -20,15 +20,6 @@ nouveau_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface *surf,
nouveau_copy_buffer(dPriv, surf, NULL);
}
-static void
-nouveau_printf(struct pipe_winsys *pws, const char *fmt, ...)
-{
- va_list args;
- va_start(args, fmt);
- vfprintf(stderr, fmt, args);
- va_end(args);
-}
-
static const char *
nouveau_get_name(struct pipe_winsys *pws)
{
@@ -215,7 +206,6 @@ nouveau_create_pipe_winsys(struct nouveau_context *nv)
pws = &nvpws->pws;
pws->flush_frontbuffer = nouveau_flush_frontbuffer;
- pws->printf = nouveau_printf;
pws->surface_alloc = nouveau_surface_alloc;
pws->surface_alloc_storage = nouveau_surface_alloc_storage;
diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c
index 7459756279..9a20bdfb69 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 d55d8c39eb..f42f7fcc5f 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 2edc697693..eab9fd3852 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 1746a876c3..ba17d638a3 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 5f3f7d6cf4..e0c901ea8c 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 ec56b25f7c..975a55d6dc 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 43cc21d1fb..c181575f15 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 e321b401e2..1de3676bda 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 85e3d47e1a..44705bc89a 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 */