summaryrefslogtreecommitdiff
path: root/src/gallium
diff options
context:
space:
mode:
authorBen Skeggs <skeggsb@gmail.com>2008-04-09 13:42:55 +1000
committerBen Skeggs <skeggsb@gmail.com>2008-04-09 13:42:55 +1000
commit2a8de8ff94e0e0e52e03f8c8427a9e92fae374f4 (patch)
treec13df91fcc114b297635eb4a254bab5578bc8239 /src/gallium
parent2655f6901289bcfe3835cf28d7b9eefa242045b8 (diff)
parent7e57a9e8bba322b2ba8a02eec4b79c90e7052738 (diff)
Merge remote branch 'upstream/gallium-0.1' into nouveau-gallium-0.1
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/auxiliary/draw/Makefile1
-rw-r--r--src/gallium/auxiliary/draw/SConscript1
-rw-r--r--src/gallium/auxiliary/draw/draw_clip.c15
-rw-r--r--src/gallium/auxiliary/draw/draw_context.c19
-rw-r--r--src/gallium/auxiliary/draw/draw_context.h3
-rw-r--r--src/gallium/auxiliary/draw/draw_private.h27
-rw-r--r--src/gallium/auxiliary/draw/draw_pt.h10
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch_emit.c2
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c163
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_pipeline.c168
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_vcache.c396
-rw-r--r--src/gallium/auxiliary/draw/draw_vertex_cache.c2
-rw-r--r--src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c154
-rw-r--r--src/gallium/auxiliary/util/p_debug.c11
-rw-r--r--src/gallium/auxiliary/util/p_debug_mem.c16
-rw-r--r--src/gallium/drivers/cell/ppu/cell_context.h2
-rw-r--r--src/gallium/drivers/cell/ppu/cell_draw_arrays.c22
-rw-r--r--src/gallium/drivers/cell/ppu/cell_state_vertex.c2
-rw-r--r--src/gallium/drivers/i915simple/i915_context.c22
-rw-r--r--src/gallium/drivers/i915simple/i915_context.h2
-rw-r--r--src/gallium/drivers/i915simple/i915_state.c3
-rw-r--r--src/gallium/drivers/softpipe/Makefile1
-rw-r--r--src/gallium/drivers/softpipe/SConscript1
-rw-r--r--src/gallium/drivers/softpipe/sp_context.c2
-rw-r--r--src/gallium/drivers/softpipe/sp_context.h5
-rw-r--r--src/gallium/drivers/softpipe/sp_draw_arrays.c22
-rw-r--r--src/gallium/drivers/softpipe/sp_fs_llvm.c16
-rw-r--r--src/gallium/drivers/softpipe/sp_headers.h4
-rw-r--r--src/gallium/drivers/softpipe/sp_quad.c9
-rw-r--r--src/gallium/drivers/softpipe/sp_quad.h1
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_alpha_test.c5
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_blend.c1192
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_bufloop.c4
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_colormask.c59
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_coverage.c15
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_fs.c60
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_output.c39
-rw-r--r--src/gallium/drivers/softpipe/sp_state_vertex.c2
-rw-r--r--src/gallium/include/pipe/p_context.h8
-rw-r--r--src/gallium/include/pipe/p_debug.h6
-rw-r--r--src/gallium/include/pipe/p_state.h2
-rw-r--r--src/gallium/include/pipe/p_util.h9
42 files changed, 1424 insertions, 1079 deletions
diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile
index b28e516396..28262a92c6 100644
--- a/src/gallium/auxiliary/draw/Makefile
+++ b/src/gallium/auxiliary/draw/Makefile
@@ -19,6 +19,7 @@ C_SOURCES = \
draw_pt_vcache.c \
draw_pt_fetch_emit.c \
draw_pt_fetch_pipeline.c \
+ draw_pt_pipeline.c \
draw_pt_elts.c \
draw_prim.c \
draw_pstipple.c \
diff --git a/src/gallium/auxiliary/draw/SConscript b/src/gallium/auxiliary/draw/SConscript
index 9ca4197441..52107912f5 100644
--- a/src/gallium/auxiliary/draw/SConscript
+++ b/src/gallium/auxiliary/draw/SConscript
@@ -18,6 +18,7 @@ draw = env.ConvenienceLibrary(
'draw_pt_vcache.c',
'draw_pt_fetch_emit.c',
'draw_pt_fetch_pipeline.c',
+ 'draw_pt_pipeline.c',
'draw_pt_elts.c',
'draw_prim.c',
'draw_pstipple.c',
diff --git a/src/gallium/auxiliary/draw/draw_clip.c b/src/gallium/auxiliary/draw/draw_clip.c
index 200152ecab..e24c5d8032 100644
--- a/src/gallium/auxiliary/draw/draw_clip.c
+++ b/src/gallium/auxiliary/draw/draw_clip.c
@@ -181,6 +181,21 @@ static void emit_poly( struct draw_stage *stage,
(header.v[1]->edgeflag << 1) |
(header.v[2]->edgeflag << 2));
+ if (0) {
+ const struct draw_vertex_shader *vs = stage->draw->vertex_shader;
+ uint j, k;
+ debug_printf("Clipped tri:\n");
+ for (j = 0; j < 3; j++) {
+ for (k = 0; k < vs->info.num_outputs; k++) {
+ debug_printf(" Vert %d: Attr %d: %f %f %f %f\n", j, k,
+ header.v[j]->data[k][0],
+ header.v[j]->data[k][1],
+ header.v[j]->data[k][2],
+ header.v[j]->data[k][3]);
+ }
+ }
+ }
+
stage->next->tri( stage->next, &header );
header.v[1]->edgeflag = tmp1;
diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c
index d0d5f66b37..b3c65c90d6 100644
--- a/src/gallium/auxiliary/draw/draw_context.c
+++ b/src/gallium/auxiliary/draw/draw_context.c
@@ -434,7 +434,8 @@ void draw_reset_vertex_ids(struct draw_context *draw)
stage = stage->next;
}
- draw_vertex_cache_reset_vertex_ids(draw);
+ draw_vertex_cache_reset_vertex_ids(draw); /* going away soon */
+ draw_pt_reset_vertex_ids(draw);
}
@@ -443,3 +444,19 @@ void draw_set_render( struct draw_context *draw,
{
draw->render = render;
}
+
+void draw_set_edgeflags( struct draw_context *draw,
+ const unsigned *edgeflag )
+{
+ draw->user.edgeflag = edgeflag;
+}
+
+
+boolean draw_get_edgeflag( struct draw_context *draw,
+ unsigned idx )
+{
+ if (draw->user.edgeflag)
+ return (draw->user.edgeflag[idx/32] & (1 << (idx%32))) != 0;
+ else
+ return 1;
+}
diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h
index 84bae3bd78..c7ac32b452 100644
--- a/src/gallium/auxiliary/draw/draw_context.h
+++ b/src/gallium/auxiliary/draw/draw_context.h
@@ -155,6 +155,9 @@ void draw_set_mapped_vertex_buffer(struct draw_context *draw,
void draw_set_mapped_constant_buffer(struct draw_context *draw,
const void *buffer);
+void draw_set_edgeflags( struct draw_context *draw,
+ const unsigned *edgeflag );
+
/***********************************************************************
* draw_prim.c
diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h
index 0c9f9c2e03..4d056f6dba 100644
--- a/src/gallium/auxiliary/draw/draw_private.h
+++ b/src/gallium/auxiliary/draw/draw_private.h
@@ -227,6 +227,12 @@ struct draw_context
struct draw_pt_front_end *vcache;
} front;
+ struct {
+ char *verts;
+ unsigned vertex_stride;
+ unsigned vertex_count;
+ } pipeline;
+
} pt;
boolean flushing;
@@ -244,6 +250,8 @@ struct draw_context
/* user-space vertex data, buffers */
struct {
+ const unsigned *edgeflag;
+
/** vertex element/index buffer (ex: glDrawElements) */
const void *elts;
/** bytes per index (0, 1, 2 or 4) */
@@ -386,15 +394,14 @@ boolean draw_pt_arrays( struct draw_context *draw,
unsigned start,
unsigned count );
-
-
-/* Prototype/hack (DEPRECATED)
- */
-boolean
-draw_passthrough_arrays(struct draw_context *draw,
- unsigned prim,
- unsigned start,
- unsigned count);
+void draw_pt_reset_vertex_ids( struct draw_context *draw );
+void draw_pt_run_pipeline( struct draw_context *draw,
+ unsigned prim,
+ char *verts,
+ unsigned vertex_stride,
+ unsigned vertex_count,
+ const ushort *elts,
+ unsigned count );
#define DRAW_FLUSH_SHADER_QUEUE 0x1 /* sized not to overflow, never raised */
@@ -406,6 +413,8 @@ draw_passthrough_arrays(struct draw_context *draw,
void draw_do_flush( struct draw_context *draw, unsigned flags );
+boolean draw_get_edgeflag( struct draw_context *draw,
+ unsigned idx );
/**
diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h
index 800072c511..590823fd33 100644
--- a/src/gallium/auxiliary/draw/draw_pt.h
+++ b/src/gallium/auxiliary/draw/draw_pt.h
@@ -40,6 +40,16 @@ typedef unsigned (*pt_elt_func)( const void *elts, unsigned idx );
struct draw_pt_middle_end;
struct draw_context;
+/* We use the top couple of bits in the vertex fetch index to convey a
+ * little API information. This limits the number of vertices we can
+ * address to only 1 billion -- if that becomes a problem, these could
+ * be moved out & passed separately.
+ */
+#define DRAW_PT_EDGEFLAG (1<<30)
+#define DRAW_PT_RESET_STIPPLE (1<<31)
+#define DRAW_PT_FLAG_MASK (3<<30)
+
+
/* The "front end" - prepare sets of fetch, draw elements for the
* middle end.
*
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
index 39f0b40838..0806076956 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
@@ -149,7 +149,7 @@ fetch_store_general( struct fetch_emit_middle_end *feme,
uint i, j;
for (i = 0; i < count; i++) {
- unsigned elt = fetch_elts[i];
+ unsigned elt = fetch_elts[i] & ~DRAW_PT_FLAG_MASK;
for (j = 0; j < feme->nr_fetch; j++) {
float attrib[4];
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c
index 94e7d01be4..4c2a281b29 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c
@@ -72,6 +72,8 @@ struct fetch_pipeline_middle_end {
struct draw_pt_middle_end base;
struct draw_context *draw;
+ void (*header)( unsigned idx, float **out);
+
struct {
const ubyte *ptr;
unsigned pitch;
@@ -85,12 +87,6 @@ struct fetch_pipeline_middle_end {
};
-static void fetch_NULL( const void *from,
- float *attrib )
-{
-}
-
-
static void emit_R32_FLOAT( const float *attrib,
float **out )
@@ -126,10 +122,16 @@ static void emit_R32G32B32A32_FLOAT( const float *attrib,
(*out) += 4;
}
-static void emit_header( const float *attrib,
- float **out )
+static void header( unsigned idx,
+ float **out )
{
- (*out)[0] = 0;
+ struct vertex_header *header = (struct vertex_header *) (*out);
+
+ header->clipmask = 0;
+ header->edgeflag = 1;
+ header->pad = 0;
+ header->vertex_id = UNDEFINED_VERTEX_ID;
+
(*out)[1] = 0;
(*out)[2] = 0;
(*out)[3] = 0;
@@ -137,6 +139,27 @@ static void emit_header( const float *attrib,
(*out) += 5;
}
+
+static void header_ef( unsigned idx,
+ float **out )
+{
+ struct vertex_header *header = (struct vertex_header *) (*out);
+
+ /* XXX: need a reset_stipple flag in the vertex header too?
+ */
+ header->clipmask = 0;
+ header->edgeflag = (idx & DRAW_PT_EDGEFLAG) != 0;
+ header->pad = 0;
+ header->vertex_id = UNDEFINED_VERTEX_ID;
+
+ (*out)[1] = 0;
+ (*out)[2] = 0;
+ (*out)[3] = 0;
+ (*out)[3] = 1;
+ (*out) += 5;
+}
+
+
/**
* General-purpose fetch from user's vertex arrays, emit to driver's
* vertex buffer.
@@ -155,6 +178,9 @@ fetch_store_general( struct fetch_pipeline_middle_end *fpme,
for (i = 0; i < count; i++) {
unsigned elt = fetch_elts[i];
+ fpme->header( elt, &out );
+ elt &= ~DRAW_PT_FLAG_MASK;
+
for (j = 0; j < fpme->nr_fetch; j++) {
float attrib[4];
const ubyte *from = (fpme->fetch[j].ptr +
@@ -194,12 +220,11 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle,
/* Emit the vertex header and empty clipspace coord field:
*/
- {
- fpme->fetch[nr].ptr = NULL;
- fpme->fetch[nr].pitch = 0;
- fpme->fetch[nr].fetch = fetch_NULL;
- fpme->fetch[nr].emit = emit_header;
- nr++;
+ if (draw->user.edgeflag) {
+ fpme->header = header_ef;
+ }
+ else {
+ fpme->header = header;
}
@@ -226,100 +251,7 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle,
}
fpme->nr_fetch = nr;
- fpme->pipeline_vertex_size = (5 + (nr-1) * 4) * sizeof(float);
-}
-
-
-
-/**
- * Add a point to the primitive queue.
- * \param i0 index into user's vertex arrays
- */
-static void do_point( struct draw_context *draw,
- const char *v0 )
-{
- struct prim_header prim;
-
- prim.reset_line_stipple = 0;
- prim.edgeflags = 1;
- prim.pad = 0;
- prim.v[0] = (struct vertex_header *)v0;
-
- draw->pipeline.first->point( draw->pipeline.first, &prim );
-}
-
-
-/**
- * Add a line to the primitive queue.
- * \param i0 index into user's vertex arrays
- * \param i1 index into user's vertex arrays
- */
-static void do_line( struct draw_context *draw,
- const char *v0,
- const char *v1 )
-{
- struct prim_header prim;
-
- prim.reset_line_stipple = 1; /* fixme */
- prim.edgeflags = 1;
- prim.pad = 0;
- prim.v[0] = (struct vertex_header *)v0;
- prim.v[1] = (struct vertex_header *)v1;
-
- draw->pipeline.first->line( draw->pipeline.first, &prim );
-}
-
-/**
- * Add a triangle to the primitive queue.
- */
-static void do_triangle( struct draw_context *draw,
- char *v0,
- char *v1,
- char *v2 )
-{
- struct prim_header prim;
-
-// _mesa_printf("tri %d %d %d\n", i0, i1, i2);
- prim.reset_line_stipple = 1;
- prim.edgeflags = ~0;
- prim.pad = 0;
- prim.v[0] = (struct vertex_header *)v0;
- prim.v[1] = (struct vertex_header *)v1;
- prim.v[2] = (struct vertex_header *)v2;
-
- draw->pipeline.first->tri( draw->pipeline.first, &prim );
-}
-
-
-static void run_pipeline( struct fetch_pipeline_middle_end *fpme,
- char *verts,
- const ushort *elts,
- unsigned count )
-{
- struct draw_context *draw = fpme->draw;
- unsigned stride = fpme->pipeline_vertex_size;
- unsigned i;
-
- switch (fpme->prim) {
- case PIPE_PRIM_POINTS:
- for (i = 0; i < count; i++)
- do_point( draw,
- verts + stride * elts[i] );
- break;
- case PIPE_PRIM_LINES:
- for (i = 0; i+1 < count; i += 2)
- do_line( draw,
- verts + stride * elts[i+0],
- verts + stride * elts[i+1]);
- break;
- case PIPE_PRIM_TRIANGLES:
- for (i = 0; i+2 < count; i += 3)
- do_triangle( draw,
- verts + stride * elts[i+0],
- verts + stride * elts[i+1],
- verts + stride * elts[i+2]);
- break;
- }
+ fpme->pipeline_vertex_size = sizeof(struct vertex_header) + nr * 4 * sizeof(float);
}
@@ -351,10 +283,15 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle,
fetch_count );
- run_pipeline( fpme,
- pipeline_verts,
- draw_elts,
- draw_count );
+ /* Run the pipeline
+ */
+ draw_pt_run_pipeline( fpme->draw,
+ fpme->prim,
+ pipeline_verts,
+ fpme->pipeline_vertex_size,
+ fetch_count,
+ draw_elts,
+ draw_count );
/* Done -- that was easy, wasn't it:
diff --git a/src/gallium/auxiliary/draw/draw_pt_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_pipeline.c
new file mode 100644
index 0000000000..e70e63d08f
--- /dev/null
+++ b/src/gallium/auxiliary/draw/draw_pt_pipeline.c
@@ -0,0 +1,168 @@
+/**************************************************************************
+ *
+ * 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>
+ */
+
+#include "pipe/p_util.h"
+#include "draw/draw_context.h"
+#include "draw/draw_private.h"
+#include "draw/draw_vertex.h"
+#include "draw/draw_pt.h"
+
+
+/**
+ * Add a point to the primitive queue.
+ * \param i0 index into user's vertex arrays
+ */
+static void do_point( struct draw_context *draw,
+ const char *v0 )
+{
+ struct prim_header prim;
+
+ prim.reset_line_stipple = 0;
+ prim.edgeflags = 1;
+ prim.pad = 0;
+ prim.v[0] = (struct vertex_header *)v0;
+
+ draw->pipeline.first->point( draw->pipeline.first, &prim );
+}
+
+
+/**
+ * Add a line to the primitive queue.
+ * \param i0 index into user's vertex arrays
+ * \param i1 index into user's vertex arrays
+ */
+static void do_line( struct draw_context *draw,
+ const char *v0,
+ const char *v1 )
+{
+ struct prim_header prim;
+
+ prim.reset_line_stipple = 1; /* fixme */
+ prim.edgeflags = 1;
+ prim.pad = 0;
+ prim.v[0] = (struct vertex_header *)v0;
+ prim.v[1] = (struct vertex_header *)v1;
+
+ draw->pipeline.first->line( draw->pipeline.first, &prim );
+}
+
+/**
+ * Add a triangle to the primitive queue.
+ */
+static void do_triangle( struct draw_context *draw,
+ char *v0,
+ char *v1,
+ char *v2 )
+{
+ struct prim_header prim;
+
+ prim.v[0] = (struct vertex_header *)v0;
+ prim.v[1] = (struct vertex_header *)v1;
+ prim.v[2] = (struct vertex_header *)v2;
+ prim.reset_line_stipple = 1;
+ prim.edgeflags = ((prim.v[0]->edgeflag) |
+ (prim.v[1]->edgeflag << 1) |
+ (prim.v[2]->edgeflag << 2));
+ prim.pad = 0;
+
+ if (0) debug_printf("tri ef: %d %d %d\n",
+ prim.v[0]->edgeflag,
+ prim.v[1]->edgeflag,
+ prim.v[2]->edgeflag);
+
+ draw->pipeline.first->tri( draw->pipeline.first, &prim );
+}
+
+
+
+void draw_pt_reset_vertex_ids( struct draw_context *draw )
+{
+ unsigned i;
+ char *verts = draw->pt.pipeline.verts;
+ unsigned stride = draw->pt.pipeline.vertex_stride;
+
+ for (i = 0; i < draw->pt.pipeline.vertex_count; i++) {
+ ((struct vertex_header *)verts)->vertex_id = UNDEFINED_VERTEX_ID;
+ verts += stride;
+ }
+}
+
+
+/* Code to run the pipeline on a fairly arbitary collection of vertices.
+ *
+ * Vertex headers must be pre-initialized with the
+ * UNDEFINED_VERTEX_ID, this code will cause that id to become
+ * overwritten, so it may have to be reset if there is the intention
+ * to reuse the vertices.
+ *
+ * This code provides a callback to reset the vertex id's which the
+ * draw_vbuf.c code uses when it has to perform a flush.
+ */
+void draw_pt_run_pipeline( struct draw_context *draw,
+ unsigned prim,
+ char *verts,
+ unsigned stride,
+ unsigned vertex_count,
+ const ushort *elts,
+ unsigned count )
+{
+ unsigned i;
+
+ draw->pt.pipeline.verts = verts;
+ draw->pt.pipeline.vertex_stride = stride;
+ draw->pt.pipeline.vertex_count = vertex_count;
+
+ switch (prim) {
+ case PIPE_PRIM_POINTS:
+ for (i = 0; i < count; i++)
+ do_point( draw,
+ verts + stride * elts[i] );
+ break;
+ case PIPE_PRIM_LINES:
+ for (i = 0; i+1 < count; i += 2)
+ do_line( draw,
+ verts + stride * elts[i+0],
+ verts + stride * elts[i+1]);
+ break;
+ case PIPE_PRIM_TRIANGLES:
+ for (i = 0; i+2 < count; i += 3)
+ do_triangle( draw,
+ verts + stride * elts[i+0],
+ verts + stride * elts[i+1],
+ verts + stride * elts[i+2]);
+ break;
+ }
+
+ draw->pt.pipeline.verts = NULL;
+ draw->pt.pipeline.vertex_count = 0;
+}
+
diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache.c b/src/gallium/auxiliary/draw/draw_pt_vcache.c
index 5a068761df..107dcfc269 100644
--- a/src/gallium/auxiliary/draw/draw_pt_vcache.c
+++ b/src/gallium/auxiliary/draw/draw_pt_vcache.c
@@ -55,9 +55,6 @@ struct vcache_frontend {
unsigned draw_count;
unsigned fetch_count;
- pt_elt_func elt_func;
- const void *elt_ptr;
-
struct draw_pt_middle_end *middle;
unsigned input_prim;
@@ -66,17 +63,6 @@ struct vcache_frontend {
static void vcache_flush( struct vcache_frontend *vcache )
{
-#if 0
- /* Should always be true if output_prim == input_prim, otherwise
- * not so much...
- */
- unsigned i;
- for (i = 0; i < vcache->draw_count; i++) {
- assert( vcache->fetch_elts[vcache->draw_elts[i]] ==
- vcache->elt_func(vcache->elt_ptr, i) );
- }
-#endif
-
if (vcache->draw_count) {
vcache->middle->run( vcache->middle,
vcache->fetch_elts,
@@ -115,26 +101,73 @@ static void vcache_elt( struct vcache_frontend *vcache,
vcache->draw_elts[vcache->draw_count++] = vcache->out[idx];
}
+
+static unsigned add_edgeflag( struct vcache_frontend *vcache,
+ unsigned idx,
+ unsigned mask )
+{
+ if (mask && draw_get_edgeflag(vcache->draw, idx))
+ return idx | DRAW_PT_EDGEFLAG;
+ else
+ return idx;
+}
+
+
+static unsigned add_reset_stipple( unsigned idx,
+ unsigned reset )
+{
+ if (reset)
+ return idx | DRAW_PT_RESET_STIPPLE;
+ else
+ return idx;
+}
+
static void vcache_triangle( struct vcache_frontend *vcache,
unsigned i0,
unsigned i1,
unsigned i2 )
{
- /* TODO: encode edgeflags in draw_elts */
+ vcache_elt(vcache, i0 | DRAW_PT_EDGEFLAG | DRAW_PT_RESET_STIPPLE);
+ vcache_elt(vcache, i1 | DRAW_PT_EDGEFLAG);
+ vcache_elt(vcache, i2 | DRAW_PT_EDGEFLAG);
+ vcache_check_flush(vcache);
+}
+
+
+static void vcache_ef_triangle( struct vcache_frontend *vcache,
+ boolean reset_stipple,
+ unsigned ef_mask,
+ unsigned i0,
+ unsigned i1,
+ unsigned i2 )
+{
+ i0 = add_edgeflag( vcache, i0, (ef_mask >> 0) & 1 );
+ i1 = add_edgeflag( vcache, i1, (ef_mask >> 1) & 1 );
+ i2 = add_edgeflag( vcache, i2, (ef_mask >> 2) & 1 );
+
+ i0 = add_reset_stipple( i0, reset_stipple );
+
vcache_elt(vcache, i0);
vcache_elt(vcache, i1);
vcache_elt(vcache, i2);
vcache_check_flush(vcache);
+
+ if (0) debug_printf("emit tri ef: %d %d %d\n",
+ !!(i0 & DRAW_PT_EDGEFLAG),
+ !!(i1 & DRAW_PT_EDGEFLAG),
+ !!(i2 & DRAW_PT_EDGEFLAG));
+
}
+
static void vcache_line( struct vcache_frontend *vcache,
- boolean reset,
+ boolean reset_stipple,
unsigned i0,
unsigned i1 )
{
- /* TODO: encode reset-line-stipple in draw_elts */
- (void) reset;
+ i0 = add_reset_stipple( i0, reset_stipple );
+
vcache_elt(vcache, i0);
vcache_elt(vcache, i1);
vcache_check_flush(vcache);
@@ -158,39 +191,43 @@ static void vcache_quad( struct vcache_frontend *vcache,
vcache_triangle( vcache, i1, i2, i3 );
}
+static void vcache_ef_quad( struct vcache_frontend *vcache,
+ unsigned i0,
+ unsigned i1,
+ unsigned i2,
+ unsigned i3 )
+{
+ const unsigned omitEdge2 = ~(1 << 1);
+ const unsigned omitEdge3 = ~(1 << 2);
+ vcache_ef_triangle( vcache, 1, omitEdge2, i0, i1, i3 );
+ vcache_ef_triangle( vcache, 0, omitEdge3, i1, i2, i3 );
+}
+
-static unsigned reduced_prim[PIPE_PRIM_POLYGON + 1] = {
- PIPE_PRIM_POINTS,
- PIPE_PRIM_LINES,
- PIPE_PRIM_LINES,
- PIPE_PRIM_LINES,
- PIPE_PRIM_TRIANGLES,
- PIPE_PRIM_TRIANGLES,
- PIPE_PRIM_TRIANGLES,
- PIPE_PRIM_TRIANGLES,
- PIPE_PRIM_TRIANGLES,
- PIPE_PRIM_TRIANGLES
-};
-static void vcache_run_pv2( struct draw_pt_front_end *frontend,
- pt_elt_func get_elt,
- const void *elts,
- unsigned count )
+static void vcache_run( struct draw_pt_front_end *frontend,
+ pt_elt_func get_elt,
+ const void *elts,
+ unsigned count )
{
struct vcache_frontend *vcache = (struct vcache_frontend *)frontend;
+ struct draw_context *draw = vcache->draw;
+
+ boolean unfilled = (draw->rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL ||
+ draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL);
+
+ boolean flatfirst = (draw->rasterizer->flatshade &&
+ draw->rasterizer->flatshade_first);
unsigned i;
-
- /* These are for validation only:
- */
- vcache->elt_func = get_elt;
- vcache->elt_ptr = elts;
+
+// debug_printf("%s (%d) %d/%d\n", __FUNCTION__, draw->prim, start, count );
switch (vcache->input_prim) {
case PIPE_PRIM_POINTS:
for (i = 0; i < count; i ++) {
- vcache_point( vcache,
- get_elt(elts, i) );
+ vcache_point( vcache,
+ get_elt(elts, i + 0) );
}
break;
@@ -205,17 +242,17 @@ static void vcache_run_pv2( struct draw_pt_front_end *frontend,
case PIPE_PRIM_LINE_LOOP:
if (count >= 2) {
- for (i = 1; i < count; i++) {
- vcache_line( vcache,
+ for (i = 1; i < count; i++) {
+ vcache_line( vcache,
i == 1, /* XXX: only if vb not split */
get_elt(elts, i - 1),
- get_elt(elts, i) );
- }
+ get_elt(elts, i ));
+ }
- vcache_line( vcache,
+ vcache_line( vcache,
0,
get_elt(elts, count - 1),
- get_elt(elts, 0) );
+ get_elt(elts, 0 ));
}
break;
@@ -224,72 +261,163 @@ static void vcache_run_pv2( struct draw_pt_front_end *frontend,
vcache_line( vcache,
i == 1,
get_elt(elts, i - 1),
- get_elt(elts, i) );
+ 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) );
+ if (unfilled) {
+ for (i = 0; i+2 < count; i += 3) {
+ vcache_ef_triangle( vcache,
+ 1,
+ ~0,
+ get_elt(elts, i + 0),
+ get_elt(elts, i + 1),
+ get_elt(elts, i + 2 ));
+ }
+ }
+ else {
+ 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 + 1),
- get_elt(elts, i + 0),
- get_elt(elts, i + 2) );
+ if (flatfirst) {
+ 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 ));
+ }
}
- else {
- vcache_triangle( vcache,
- get_elt(elts, i + 0),
- get_elt(elts, i + 1),
- get_elt(elts, i + 2) );
+ }
+ else {
+ for (i = 0; i+2 < count; i++) {
+ if (i & 1) {
+ vcache_triangle( vcache,
+ get_elt(elts, i + 1),
+ get_elt(elts, i + 0),
+ get_elt(elts, i + 2 ));
+ }
+ 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, 0),
- get_elt(elts, i + 1),
- get_elt(elts, i + 2) );
+ if (count >= 3) {
+ if (flatfirst) {
+ for (i = 0; i+2 < count; i++) {
+ vcache_triangle( vcache,
+ get_elt(elts, i + 1),
+ get_elt(elts, i + 2),
+ get_elt(elts, 0 ));
+ }
+ }
+ else {
+ for (i = 0; i+2 < count; i++) {
+ vcache_triangle( vcache,
+ get_elt(elts, 0),
+ get_elt(elts, i + 1),
+ get_elt(elts, i + 2 ));
+ }
+ }
}
break;
case PIPE_PRIM_QUADS:
- for (i = 0; i+3 < count; i += 4) {
- vcache_quad( vcache,
- get_elt(elts, i + 0),
- get_elt(elts, i + 1),
- get_elt(elts, i + 2),
- get_elt(elts, i + 3));
+ if (unfilled) {
+ for (i = 0; i+3 < count; i += 4) {
+ vcache_ef_quad( vcache,
+ get_elt(elts, i + 0),
+ get_elt(elts, i + 1),
+ get_elt(elts, i + 2),
+ get_elt(elts, i + 3));
+ }
+ }
+ else {
+ for (i = 0; i+3 < count; i += 4) {
+ vcache_quad( vcache,
+ get_elt(elts, i + 0),
+ get_elt(elts, i + 1),
+ get_elt(elts, i + 2),
+ get_elt(elts, i + 3));
+ }
}
break;
case PIPE_PRIM_QUAD_STRIP:
- for (i = 0; i+3 < count; i += 2) {
- vcache_quad( vcache,
- get_elt(elts, i + 2),
- get_elt(elts, i + 0),
- get_elt(elts, i + 1),
- get_elt(elts, i + 3));
+ if (unfilled) {
+ for (i = 0; i+3 < count; i += 2) {
+ vcache_ef_quad( vcache,
+ get_elt(elts, i + 2),
+ get_elt(elts, i + 0),
+ get_elt(elts, i + 1),
+ get_elt(elts, i + 3));
+ }
+ }
+ else {
+ for (i = 0; i+3 < count; i += 2) {
+ vcache_quad( vcache,
+ get_elt(elts, i + 2),
+ get_elt(elts, i + 0),
+ get_elt(elts, i + 1),
+ get_elt(elts, i + 3));
+ }
}
break;
case PIPE_PRIM_POLYGON:
- for (i = 0; i+2 < count; i++) {
- vcache_triangle( vcache,
- get_elt(elts, i + 1),
- get_elt(elts, i + 2),
- get_elt(elts, 0));
+ if (unfilled) {
+ /* These bitflags look a little odd because we submit the
+ * vertices as (1,2,0) to satisfy flatshade requirements.
+ */
+ const unsigned edge_first = (1<<2);
+ const unsigned edge_middle = (1<<0);
+ const unsigned edge_last = (1<<1);
+
+ for (i = 0; i+2 < count; i++) {
+ unsigned ef_mask = edge_middle;
+
+ if (i == 0)
+ ef_mask |= edge_first;
+
+ if (i + 3 == count)
+ ef_mask |= edge_last;
+
+ vcache_ef_triangle( vcache,
+ i == 0,
+ ef_mask,
+ get_elt(elts, i + 1),
+ get_elt(elts, i + 2),
+ get_elt(elts, 0));
+ }
+ }
+ else {
+ 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;
@@ -302,88 +430,21 @@ static void vcache_run_pv2( struct draw_pt_front_end *frontend,
}
-static void vcache_run_pv0( struct draw_pt_front_end *frontend,
- 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;
-
- switch (vcache->input_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;
+static unsigned reduced_prim[PIPE_PRIM_POLYGON + 1] = {
+ PIPE_PRIM_POINTS,
+ PIPE_PRIM_LINES,
+ PIPE_PRIM_LINES,
+ PIPE_PRIM_LINES,
+ PIPE_PRIM_TRIANGLES,
+ PIPE_PRIM_TRIANGLES,
+ PIPE_PRIM_TRIANGLES,
+ PIPE_PRIM_TRIANGLES,
+ PIPE_PRIM_TRIANGLES,
+ PIPE_PRIM_TRIANGLES
+};
- default:
- assert(0);
- break;
- }
-
- vcache_flush( vcache );
-}
static void vcache_prepare( struct draw_pt_front_end *frontend,
unsigned prim,
@@ -391,11 +452,14 @@ static void vcache_prepare( struct draw_pt_front_end *frontend,
{
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->base.run = vcache_run;
vcache->input_prim = prim;
vcache->output_prim = reduced_prim[prim];
diff --git a/src/gallium/auxiliary/draw/draw_vertex_cache.c b/src/gallium/auxiliary/draw/draw_vertex_cache.c
index 161b247d4e..c0248979e2 100644
--- a/src/gallium/auxiliary/draw/draw_vertex_cache.c
+++ b/src/gallium/auxiliary/draw/draw_vertex_cache.c
@@ -101,7 +101,7 @@ static struct vertex_header *get_vertex( struct draw_context *draw,
draw->vs.queue[out].elt = i;
draw->vs.queue[out].vertex->clipmask = 0;
- draw->vs.queue[out].vertex->edgeflag = 1; /*XXX use user's edge flag! */
+ draw->vs.queue[out].vertex->edgeflag = draw_get_edgeflag(draw, i);
draw->vs.queue[out].vertex->pad = 0;
draw->vs.queue[out].vertex->vertex_id = UNDEFINED_VERTEX_ID;
diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c
index 55f32e6816..b1f7d93057 100644
--- a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c
+++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c
@@ -62,7 +62,6 @@ struct fenced_buffer_list
struct pipe_winsys *winsys;
size_t numDelayed;
- size_t checkDelayed;
struct list_head delayed;
};
@@ -93,51 +92,96 @@ fenced_buffer(struct pb_buffer *buf)
}
+static INLINE void
+_fenced_buffer_add(struct fenced_buffer *fenced_buf)
+{
+ struct fenced_buffer_list *fenced_list = fenced_buf->list;
+
+ assert(fenced_buf->base.base.refcount);
+ assert(fenced_buf->fence);
+ assert(!fenced_buf->head.prev);
+ assert(!fenced_buf->head.next);
+ LIST_ADDTAIL(&fenced_buf->head, &fenced_list->delayed);
+ ++fenced_list->numDelayed;
+}
+
+
+/**
+ * Actually destroy the buffer.
+ */
+static INLINE void
+_fenced_buffer_destroy(struct fenced_buffer *fenced_buf)
+{
+ struct fenced_buffer_list *fenced_list = fenced_buf->list;
+
+ assert(!fenced_buf->base.base.refcount);
+ assert(!fenced_buf->fence);
+ pb_reference(&fenced_buf->buffer, NULL);
+ FREE(fenced_buf);
+}
+
+
+static INLINE void
+_fenced_buffer_remove(struct fenced_buffer *fenced_buf)
+{
+ struct fenced_buffer_list *fenced_list = fenced_buf->list;
+ struct pipe_winsys *winsys = fenced_list->winsys;
+
+ assert(fenced_buf->fence);
+
+ winsys->fence_reference(winsys, &fenced_buf->fence, NULL);
+
+ assert(fenced_buf->head.prev);
+ assert(fenced_buf->head.next);
+ LIST_DEL(&fenced_buf->head);
+#ifdef DEBUG
+ fenced_buf->head.prev = NULL;
+ fenced_buf->head.next = NULL;
+#endif
+
+ assert(fenced_list->numDelayed);
+ --fenced_list->numDelayed;
+
+ if(!fenced_buf->base.base.refcount)
+ _fenced_buffer_destroy(fenced_buf);
+}
+
+
+/**
+ * Free as many fenced buffers from the list head as possible.
+ */
static void
_fenced_buffer_list_check_free(struct fenced_buffer_list *fenced_list,
int wait)
{
struct pipe_winsys *winsys = fenced_list->winsys;
- struct fenced_buffer *fenced_buf;
- struct list_head *list, *prev;
- int signaled = -1;
-
- list = fenced_list->delayed.next;
- prev = list->prev;
- for (; list != &fenced_list->delayed; list = prev, prev = list->prev) {
-
- fenced_buf = LIST_ENTRY(struct fenced_buffer, list, head);
-
- if (signaled != 0) {
- if (wait) {
- signaled = winsys->fence_finish(winsys, fenced_buf->fence, 0);
- }
- else {
- signaled = winsys->fence_signalled(winsys, fenced_buf->fence, 0);
- }
+ struct list_head *curr, *next;
+ struct fenced_buffer *fenced_buf;
+ struct pipe_fence_handle *prev_fence = NULL;
+
+ curr = fenced_list->delayed.next;
+ next = curr->next;
+ while(curr != &fenced_list->delayed) {
+ fenced_buf = LIST_ENTRY(struct fenced_buffer, curr, head);
+
+ if(fenced_buf->fence != prev_fence) {
+ int signaled;
+ if (wait)
+ signaled = winsys->fence_finish(winsys, fenced_buf->fence, 0);
+ else
+ signaled = winsys->fence_signalled(winsys, fenced_buf->fence, 0);
+ if (signaled != 0)
+ break;
+ prev_fence = fenced_buf->fence;
}
-
- 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
+ else {
+ assert(winsys->fence_signalled(winsys, fenced_buf->fence, 0) == 0);
}
- winsys->fence_reference(winsys, &fenced_buf->fence, NULL);
-
- LIST_DEL(list);
- fenced_list->numDelayed--;
+ _fenced_buffer_remove(fenced_buf);
- /* Do the delayed destroy:
- */
- pb_reference(&fenced_buf->buffer, NULL);
- FREE(fenced_buf);
+ curr = next;
+ next = curr->next;
}
}
@@ -148,25 +192,30 @@ fenced_buffer_destroy(struct pb_buffer *buf)
struct fenced_buffer *fenced_buf = fenced_buffer(buf);
struct fenced_buffer_list *fenced_list = fenced_buf->list;
+ _glthread_LOCK_MUTEX(fenced_list->mutex);
+ assert(fenced_buf->base.base.refcount == 0);
if (fenced_buf->fence) {
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++;
- }
+ if(winsys->fence_signalled(winsys, fenced_buf->fence, 0) == 0) {
+ struct list_head *curr, *prev;
+ curr = &fenced_buf->head;
+ prev = curr->prev;
+ do {
+ fenced_buf = LIST_ENTRY(struct fenced_buffer, curr, head);
+ assert(winsys->fence_signalled(winsys, fenced_buf->fence, 0) == 0);
+ _fenced_buffer_remove(fenced_buf);
+ curr = prev;
+ prev = curr->prev;
+ } while (curr != &fenced_list->delayed);
+ }
else {
- winsys->fence_reference(winsys, &fenced_buf->fence, NULL);
- pb_reference(&fenced_buf->buffer, NULL);
- FREE(fenced_buf);
+ /* delay destruction */
}
}
else {
- pb_reference(&fenced_buf->buffer, NULL);
- FREE(fenced_buf);
+ _fenced_buffer_destroy(fenced_buf);
}
-
- if ((fenced_list->numDelayed % fenced_list->checkDelayed) == 0)
- _fenced_buffer_list_check_free(fenced_list, 0);
+ _glthread_UNLOCK_MUTEX(fenced_list->mutex);
}
@@ -241,7 +290,11 @@ buffer_fence(struct pb_buffer *buf,
struct pipe_winsys *winsys = fenced_list->winsys;
_glthread_LOCK_MUTEX(fenced_list->mutex);
+ if (fenced_buf->fence)
+ _fenced_buffer_remove(fenced_buf);
winsys->fence_reference(winsys, &fenced_buf->fence, fence);
+ if (fenced_buf->fence)
+ _fenced_buffer_add(fenced_buf);
_glthread_UNLOCK_MUTEX(fenced_list->mutex);
}
@@ -261,9 +314,6 @@ fenced_buffer_list_create(struct pipe_winsys *winsys)
fenced_list->numDelayed = 0;
- /* TODO: don't hard code this */
- fenced_list->checkDelayed = 5;
-
_glthread_INIT_MUTEX(fenced_list->mutex);
return fenced_list;
diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c
index 5447bbb6f5..090e3b7794 100644
--- a/src/gallium/auxiliary/util/p_debug.c
+++ b/src/gallium/auxiliary/util/p_debug.c
@@ -43,18 +43,13 @@
#ifdef WIN32
static INLINE void
-rpl_EngDebugPrint(const char *format, ...)
+_EngDebugPrint(const char *format, ...)
{
va_list ap;
va_start(ap, format);
EngDebugPrint("", (PCHAR)format, ap);
va_end(ap);
}
-
-int rpl_vsnprintf(char *, size_t, const char *, va_list);
-int rpl_snprintf(char *str, size_t size, const char *format, ...);
-#define vsnprintf rpl_vsnprintf
-#define snprintf rpl_snprintf
#endif
@@ -65,8 +60,8 @@ void _debug_vprintf(const char *format, va_list ap)
/* EngDebugPrint does not handle float point arguments, so we need to use
* our own vsnprintf implementation */
char buf[512 + 1];
- rpl_vsnprintf(buf, sizeof(buf), format, ap);
- rpl_EngDebugPrint("%s", buf);
+ vsnprintf(buf, sizeof(buf), format, ap);
+ _EngDebugPrint("%s", buf);
#else
/* TODO: Implement debug print for WINCE */
#endif
diff --git a/src/gallium/auxiliary/util/p_debug_mem.c b/src/gallium/auxiliary/util/p_debug_mem.c
index c160afe5b7..97ec9c5b39 100644
--- a/src/gallium/auxiliary/util/p_debug_mem.c
+++ b/src/gallium/auxiliary/util/p_debug_mem.c
@@ -70,8 +70,7 @@ struct debug_memory_header
static struct list_head list = { &list, &list };
-static unsigned long start_no = 0;
-static unsigned long end_no = 0;
+static unsigned long last_no = 0;
void *
@@ -84,7 +83,7 @@ debug_malloc(const char *file, unsigned line, const char *function,
if(!hdr)
return NULL;
- hdr->no = end_no++;
+ hdr->no = last_no++;
hdr->file = file;
hdr->line = line;
hdr->function = function;
@@ -147,14 +146,14 @@ debug_realloc(const char *file, unsigned line, const char *function,
return new_ptr;
}
-void
-debug_memory_reset(void)
+unsigned long
+debug_memory_begin(void)
{
- start_no = end_no;
+ return last_no;
}
void
-debug_memory_report(void)
+debug_memory_end(unsigned long start_no)
{
struct list_head *entry;
@@ -164,7 +163,8 @@ debug_memory_report(void)
void *ptr;
hdr = LIST_ENTRY(struct debug_memory_header, entry, head);
ptr = (void *)((char *)hdr + sizeof(*hdr));
- if(hdr->no >= start_no)
+ if(start_no <= hdr->no && hdr->no < last_no ||
+ last_no < start_no && (hdr->no < last_no || start_no <= hdr->no))
debug_printf("%s:%u:%s: %u bytes at %p not freed\n",
hdr->file, hdr->line, hdr->function,
hdr->size, ptr);
diff --git a/src/gallium/drivers/cell/ppu/cell_context.h b/src/gallium/drivers/cell/ppu/cell_context.h
index 7f656a9744..8df41c1d4c 100644
--- a/src/gallium/drivers/cell/ppu/cell_context.h
+++ b/src/gallium/drivers/cell/ppu/cell_context.h
@@ -104,7 +104,9 @@ struct cell_context
uint num_textures;
struct pipe_viewport_state viewport;
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
+ uint num_vertex_buffers;
struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS];
+ uint num_vertex_elements;
ubyte *cbuf_map[PIPE_MAX_COLOR_BUFS];
ubyte *zsbuf_map;
diff --git a/src/gallium/drivers/cell/ppu/cell_draw_arrays.c b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c
index b896252f81..36af5be5f0 100644
--- a/src/gallium/drivers/cell/ppu/cell_draw_arrays.c
+++ b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c
@@ -123,14 +123,12 @@ cell_draw_elements(struct pipe_context *pipe,
/*
* Map vertex buffers
*/
- for (i = 0; i < PIPE_MAX_ATTRIBS; i++) {
- if (sp->vertex_buffer[i].buffer) {
- void *buf = pipe->winsys->buffer_map(pipe->winsys,
- sp->vertex_buffer[i].buffer,
- PIPE_BUFFER_USAGE_CPU_READ);
- cell_flush_buffer_range(sp, buf, sp->vertex_buffer[i].buffer->size);
- draw_set_mapped_vertex_buffer(draw, i, buf);
- }
+ for (i = 0; i < sp->num_vertex_buffers; i++) {
+ void *buf = pipe->winsys->buffer_map(pipe->winsys,
+ sp->vertex_buffer[i].buffer,
+ PIPE_BUFFER_USAGE_CPU_READ);
+ cell_flush_buffer_range(sp, buf, sp->vertex_buffer[i].buffer->size);
+ draw_set_mapped_vertex_buffer(draw, i, buf);
}
/* Map index buffer, if present */
if (indexBuffer) {
@@ -151,11 +149,9 @@ cell_draw_elements(struct pipe_context *pipe,
/*
* unmap vertex/index buffers - will cause draw module to flush
*/
- for (i = 0; i < PIPE_MAX_ATTRIBS; i++) {
- if (sp->vertex_buffer[i].buffer) {
- draw_set_mapped_vertex_buffer(draw, i, NULL);
- pipe->winsys->buffer_unmap(pipe->winsys, sp->vertex_buffer[i].buffer);
- }
+ for (i = 0; i < sp->num_vertex_buffers; i++) {
+ draw_set_mapped_vertex_buffer(draw, i, NULL);
+ pipe->winsys->buffer_unmap(pipe->winsys, sp->vertex_buffer[i].buffer);
}
if (indexBuffer) {
draw_set_mapped_element_buffer(draw, 0, NULL);
diff --git a/src/gallium/drivers/cell/ppu/cell_state_vertex.c b/src/gallium/drivers/cell/ppu/cell_state_vertex.c
index 6c83b8dc72..114684c2a3 100644
--- a/src/gallium/drivers/cell/ppu/cell_state_vertex.c
+++ b/src/gallium/drivers/cell/ppu/cell_state_vertex.c
@@ -45,6 +45,7 @@ cell_set_vertex_elements(struct pipe_context *pipe,
assert(count <= PIPE_MAX_ATTRIBS);
memcpy(cell->vertex_element, elements, count * sizeof(elements[0]));
+ cell->num_vertex_elements = count;
cell->dirty |= CELL_NEW_VERTEX;
@@ -62,6 +63,7 @@ cell_set_vertex_buffers(struct pipe_context *pipe,
assert(count <= PIPE_MAX_ATTRIBS);
memcpy(cell->vertex_buffer, buffers, count * sizeof(buffers[0]));
+ cell->num_vertex_buffers = count;
cell->dirty |= CELL_NEW_VERTEX;
diff --git a/src/gallium/drivers/i915simple/i915_context.c b/src/gallium/drivers/i915simple/i915_context.c
index fee33d82de..58a5854f0d 100644
--- a/src/gallium/drivers/i915simple/i915_context.c
+++ b/src/gallium/drivers/i915simple/i915_context.c
@@ -65,14 +65,12 @@ i915_draw_elements( struct pipe_context *pipe,
/*
* Map vertex buffers
*/
- for (i = 0; i < PIPE_MAX_ATTRIBS; i++) {
- if (i915->vertex_buffer[i].buffer) {
- void *buf
- = pipe->winsys->buffer_map(pipe->winsys,
- i915->vertex_buffer[i].buffer,
- PIPE_BUFFER_USAGE_CPU_READ);
- draw_set_mapped_vertex_buffer(draw, i, buf);
- }
+ for (i = 0; i < i915->num_vertex_buffers; i++) {
+ void *buf
+ = pipe->winsys->buffer_map(pipe->winsys,
+ i915->vertex_buffer[i].buffer,
+ PIPE_BUFFER_USAGE_CPU_READ);
+ draw_set_mapped_vertex_buffer(draw, i, buf);
}
/* Map index buffer, if present */
if (indexBuffer) {
@@ -96,11 +94,9 @@ i915_draw_elements( struct pipe_context *pipe,
/*
* unmap vertex/index buffers
*/
- for (i = 0; i < PIPE_MAX_ATTRIBS; i++) {
- if (i915->vertex_buffer[i].buffer) {
- pipe->winsys->buffer_unmap(pipe->winsys, i915->vertex_buffer[i].buffer);
- draw_set_mapped_vertex_buffer(draw, i, NULL);
- }
+ for (i = 0; i < i915->num_vertex_buffers; i++) {
+ pipe->winsys->buffer_unmap(pipe->winsys, i915->vertex_buffer[i].buffer);
+ draw_set_mapped_vertex_buffer(draw, i, NULL);
}
if (indexBuffer) {
pipe->winsys->buffer_unmap(pipe->winsys, indexBuffer);
diff --git a/src/gallium/drivers/i915simple/i915_context.h b/src/gallium/drivers/i915simple/i915_context.h
index 8e707ea574..38e6a34884 100644
--- a/src/gallium/drivers/i915simple/i915_context.h
+++ b/src/gallium/drivers/i915simple/i915_context.h
@@ -238,6 +238,8 @@ struct i915_context
unsigned num_samplers;
unsigned num_textures;
+ unsigned num_vertex_elements;
+ unsigned num_vertex_buffers;
unsigned *batch_start;
diff --git a/src/gallium/drivers/i915simple/i915_state.c b/src/gallium/drivers/i915simple/i915_state.c
index 4404bc4590..24d31ad740 100644
--- a/src/gallium/drivers/i915simple/i915_state.c
+++ b/src/gallium/drivers/i915simple/i915_state.c
@@ -694,6 +694,8 @@ static void i915_set_vertex_buffers(struct pipe_context *pipe,
struct i915_context *i915 = i915_context(pipe);
memcpy(i915->vertex_buffer, buffers, count * sizeof(buffers[0]));
+ i915->num_vertex_buffers = count;
+
/* pass-through to draw module */
draw_set_vertex_buffers(i915->draw, count, buffers);
}
@@ -703,6 +705,7 @@ static void i915_set_vertex_elements(struct pipe_context *pipe,
const struct pipe_vertex_element *elements)
{
struct i915_context *i915 = i915_context(pipe);
+ i915->num_vertex_elements = count;
/* pass-through to draw module */
draw_set_vertex_elements(i915->draw, count, elements);
}
diff --git a/src/gallium/drivers/softpipe/Makefile b/src/gallium/drivers/softpipe/Makefile
index f32db35d58..19dfd8c1a7 100644
--- a/src/gallium/drivers/softpipe/Makefile
+++ b/src/gallium/drivers/softpipe/Makefile
@@ -17,7 +17,6 @@ C_SOURCES = \
sp_quad.c \
sp_quad_alpha_test.c \
sp_quad_blend.c \
- sp_quad_bufloop.c \
sp_quad_colormask.c \
sp_quad_coverage.c \
sp_quad_depth_test.c \
diff --git a/src/gallium/drivers/softpipe/SConscript b/src/gallium/drivers/softpipe/SConscript
index 88c21ee3b0..06931fa8d8 100644
--- a/src/gallium/drivers/softpipe/SConscript
+++ b/src/gallium/drivers/softpipe/SConscript
@@ -16,7 +16,6 @@ softpipe = env.ConvenienceLibrary(
'sp_prim_vbuf.c',
'sp_quad_alpha_test.c',
'sp_quad_blend.c',
- 'sp_quad_bufloop.c',
'sp_quad.c',
'sp_quad_colormask.c',
'sp_quad_coverage.c',
diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c
index e298ed37c3..8c84ddbe19 100644
--- a/src/gallium/drivers/softpipe/sp_context.c
+++ b/src/gallium/drivers/softpipe/sp_context.c
@@ -98,7 +98,6 @@ static void softpipe_destroy( struct pipe_context *pipe )
softpipe->quad.stencil_test->destroy( softpipe->quad.stencil_test );
softpipe->quad.occlusion->destroy( softpipe->quad.occlusion );
softpipe->quad.coverage->destroy( softpipe->quad.coverage );
- softpipe->quad.bufloop->destroy( softpipe->quad.bufloop );
softpipe->quad.blend->destroy( softpipe->quad.blend );
softpipe->quad.colormask->destroy( softpipe->quad.colormask );
softpipe->quad.output->destroy( softpipe->quad.output );
@@ -207,7 +206,6 @@ softpipe_create( struct pipe_screen *screen,
softpipe->quad.stencil_test = sp_quad_stencil_test_stage(softpipe);
softpipe->quad.occlusion = sp_quad_occlusion_stage(softpipe);
softpipe->quad.coverage = sp_quad_coverage_stage(softpipe);
- softpipe->quad.bufloop = sp_quad_bufloop_stage(softpipe);
softpipe->quad.blend = sp_quad_blend_stage(softpipe);
softpipe->quad.colormask = sp_quad_colormask_stage(softpipe);
softpipe->quad.output = sp_quad_output_stage(softpipe);
diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h
index dc9d0e6d5d..2442bd1eb0 100644
--- a/src/gallium/drivers/softpipe/sp_context.h
+++ b/src/gallium/drivers/softpipe/sp_context.h
@@ -83,6 +83,8 @@ struct softpipe_context {
unsigned num_samplers;
unsigned num_textures;
+ unsigned num_vertex_elements;
+ unsigned num_vertex_buffers;
/* Counter for occlusion queries. Note this supports overlapping
* queries.
@@ -124,7 +126,6 @@ struct softpipe_context {
struct quad_stage *depth_test;
struct quad_stage *occlusion;
struct quad_stage *coverage;
- struct quad_stage *bufloop;
struct quad_stage *blend;
struct quad_stage *colormask;
struct quad_stage *output;
@@ -138,8 +139,6 @@ struct softpipe_context {
struct draw_stage *vbuf;
struct softpipe_vbuf_render *vbuf_render;
- uint current_cbuf; /**< current color buffer being written to */
-
struct softpipe_tile_cache *cbuf_cache[PIPE_MAX_COLOR_BUFS];
struct softpipe_tile_cache *zsbuf_cache;
diff --git a/src/gallium/drivers/softpipe/sp_draw_arrays.c b/src/gallium/drivers/softpipe/sp_draw_arrays.c
index ab54050d3f..61bcf51899 100644
--- a/src/gallium/drivers/softpipe/sp_draw_arrays.c
+++ b/src/gallium/drivers/softpipe/sp_draw_arrays.c
@@ -125,14 +125,12 @@ softpipe_draw_elements(struct pipe_context *pipe,
/*
* Map vertex buffers
*/
- for (i = 0; i < PIPE_MAX_ATTRIBS; i++) {
- if (sp->vertex_buffer[i].buffer) {
- void *buf
- = pipe->winsys->buffer_map(pipe->winsys,
- sp->vertex_buffer[i].buffer,
- PIPE_BUFFER_USAGE_CPU_READ);
- draw_set_mapped_vertex_buffer(draw, i, buf);
- }
+ for (i = 0; i < sp->num_vertex_buffers; i++) {
+ void *buf
+ = pipe->winsys->buffer_map(pipe->winsys,
+ sp->vertex_buffer[i].buffer,
+ PIPE_BUFFER_USAGE_CPU_READ);
+ draw_set_mapped_vertex_buffer(draw, i, buf);
}
/* Map index buffer, if present */
if (indexBuffer) {
@@ -153,11 +151,9 @@ softpipe_draw_elements(struct pipe_context *pipe,
/*
* unmap vertex/index buffers - will cause draw module to flush
*/
- for (i = 0; i < PIPE_MAX_ATTRIBS; i++) {
- if (sp->vertex_buffer[i].buffer) {
- draw_set_mapped_vertex_buffer(draw, i, NULL);
- pipe->winsys->buffer_unmap(pipe->winsys, sp->vertex_buffer[i].buffer);
- }
+ for (i = 0; i < sp->num_vertex_buffers; i++) {
+ draw_set_mapped_vertex_buffer(draw, i, NULL);
+ pipe->winsys->buffer_unmap(pipe->winsys, sp->vertex_buffer[i].buffer);
}
if (indexBuffer) {
draw_set_mapped_element_buffer(draw, 0, NULL);
diff --git a/src/gallium/drivers/softpipe/sp_fs_llvm.c b/src/gallium/drivers/softpipe/sp_fs_llvm.c
index 07d058155f..6e1d9280bb 100644
--- a/src/gallium/drivers/softpipe/sp_fs_llvm.c
+++ b/src/gallium/drivers/softpipe/sp_fs_llvm.c
@@ -99,19 +99,19 @@ shade_quad_llvm(struct quad_stage *qs,
allvmrt(qss->stage.softpipe->fs->info.output_semantic_name[qss->colorOutSlot]
== TGSI_SEMANTIC_COLOR);
for (i = 0; i < QUAD_SIZE; ++i) {
- quad->outputs.color[0][i] = dests[i][qss->colorOutSlot][0];
- quad->outputs.color[1][i] = dests[i][qss->colorOutSlot][1];
- quad->outputs.color[2][i] = dests[i][qss->colorOutSlot][2];
- quad->outputs.color[3][i] = dests[i][qss->colorOutSlot][3];
+ quad->outputs.color[0][0][i] = dests[i][qss->colorOutSlot][0];
+ quad->outputs.color[0][1][i] = dests[i][qss->colorOutSlot][1];
+ quad->outputs.color[0][2][i] = dests[i][qss->colorOutSlot][2];
+ quad->outputs.color[0][3][i] = dests[i][qss->colorOutSlot][3];
}
}
#if DLLVM
for (int i = 0; i < QUAD_SIZE; ++i) {
debug_printf("QLLVM%d(%d) [%f, %f, %f, %f]\n", i, qss->colorOutSlot,
- quad->outputs.color[0][i],
- quad->outputs.color[1][i],
- quad->outputs.color[2][i],
- quad->outputs.color[3][i]);
+ quad->outputs.color[0][0][i],
+ quad->outputs.color[0][1][i],
+ quad->outputs.color[0][2][i],
+ quad->outputs.color[0][3][i]);
}
#endif
diff --git a/src/gallium/drivers/softpipe/sp_headers.h b/src/gallium/drivers/softpipe/sp_headers.h
index 9cf8222133..3d9ede69bb 100644
--- a/src/gallium/drivers/softpipe/sp_headers.h
+++ b/src/gallium/drivers/softpipe/sp_headers.h
@@ -31,6 +31,7 @@
#ifndef SP_HEADERS_H
#define SP_HEADERS_H
+#include "pipe/p_state.h"
#include "tgsi/exec/tgsi_exec.h"
#define PRIM_POINT 1
@@ -66,7 +67,8 @@ struct quad_header {
unsigned prim:2; /**< PRIM_POINT, LINE, TRI */
struct {
- float color[NUM_CHANNELS][QUAD_SIZE]; /* rrrr, gggg, bbbb, aaaa */
+ /** colors in SOA format (rrrr, gggg, bbbb, aaaa) */
+ float color[PIPE_MAX_COLOR_BUFS][NUM_CHANNELS][QUAD_SIZE];
float depth[QUAD_SIZE];
} outputs;
diff --git a/src/gallium/drivers/softpipe/sp_quad.c b/src/gallium/drivers/softpipe/sp_quad.c
index 8603c1a367..bc83d78ea1 100644
--- a/src/gallium/drivers/softpipe/sp_quad.c
+++ b/src/gallium/drivers/softpipe/sp_quad.c
@@ -76,15 +76,6 @@ sp_build_quad_pipeline(struct softpipe_context *sp)
sp_push_quad_first( sp, sp->quad.blend );
}
- if (sp->framebuffer.num_cbufs == 1) {
- /* the usual case: write to exactly one colorbuf */
- sp->current_cbuf = 0;
- }
- else {
- /* insert bufloop stage */
- sp_push_quad_first( sp, sp->quad.bufloop );
- }
-
if (sp->depth_stencil->depth.occlusion_count) {
sp_push_quad_first( sp, sp->quad.occlusion );
}
diff --git a/src/gallium/drivers/softpipe/sp_quad.h b/src/gallium/drivers/softpipe/sp_quad.h
index f1e0281764..08513cb95f 100644
--- a/src/gallium/drivers/softpipe/sp_quad.h
+++ b/src/gallium/drivers/softpipe/sp_quad.h
@@ -58,7 +58,6 @@ struct quad_stage *sp_quad_stencil_test_stage( struct softpipe_context *softpipe
struct quad_stage *sp_quad_depth_test_stage( struct softpipe_context *softpipe );
struct quad_stage *sp_quad_occlusion_stage( struct softpipe_context *softpipe );
struct quad_stage *sp_quad_coverage_stage( struct softpipe_context *softpipe );
-struct quad_stage *sp_quad_bufloop_stage( struct softpipe_context *softpipe );
struct quad_stage *sp_quad_blend_stage( struct softpipe_context *softpipe );
struct quad_stage *sp_quad_colormask_stage( struct softpipe_context *softpipe );
struct quad_stage *sp_quad_output_stage( struct softpipe_context *softpipe );
diff --git a/src/gallium/drivers/softpipe/sp_quad_alpha_test.c b/src/gallium/drivers/softpipe/sp_quad_alpha_test.c
index 318916fe30..7a42b08ef5 100644
--- a/src/gallium/drivers/softpipe/sp_quad_alpha_test.c
+++ b/src/gallium/drivers/softpipe/sp_quad_alpha_test.c
@@ -16,7 +16,8 @@ alpha_test_quad(struct quad_stage *qs, struct quad_header *quad)
struct softpipe_context *softpipe = qs->softpipe;
const float ref = softpipe->depth_stencil->alpha.ref;
unsigned passMask = 0x0, j;
- const float *aaaa = quad->outputs.color[3];
+ const uint cbuf = 0; /* only output[0].alpha is tested */
+ const float *aaaa = quad->outputs.color[cbuf][3];
switch (softpipe->depth_stencil->alpha.func) {
case PIPE_FUNC_NEVER:
@@ -25,7 +26,7 @@ alpha_test_quad(struct quad_stage *qs, struct quad_header *quad)
case PIPE_FUNC_LESS:
/*
* If mask were an array [4] we could do this SIMD-style:
- * passMask = (quad->outputs.color[3] <= vec4(ref));
+ * passMask = (quad->outputs.color[0][3] <= vec4(ref));
*/
for (j = 0; j < QUAD_SIZE; j++) {
if (aaaa[j] < ref) {
diff --git a/src/gallium/drivers/softpipe/sp_quad_blend.c b/src/gallium/drivers/softpipe/sp_quad_blend.c
index 0b79cfa1ed..8be8025f40 100644
--- a/src/gallium/drivers/softpipe/sp_quad_blend.c
+++ b/src/gallium/drivers/softpipe/sp_quad_blend.c
@@ -101,114 +101,119 @@ static void
logicop_quad(struct quad_stage *qs, struct quad_header *quad)
{
struct softpipe_context *softpipe = qs->softpipe;
- float dest[4][QUAD_SIZE];
- ubyte src[4][4], dst[4][4], res[4][4];
- uint *src4 = (uint *) src;
- uint *dst4 = (uint *) dst;
- uint *res4 = (uint *) res;
- struct softpipe_cached_tile *
- tile = sp_get_cached_tile(softpipe,
- softpipe->cbuf_cache[softpipe->current_cbuf],
- quad->x0, quad->y0);
- float (*quadColor)[4] = quad->outputs.color;
- uint i, j;
-
- /* get/swizzle dest colors */
- for (j = 0; j < QUAD_SIZE; j++) {
- int x = (quad->x0 & (TILE_SIZE-1)) + (j & 1);
- int y = (quad->y0 & (TILE_SIZE-1)) + (j >> 1);
- for (i = 0; i < 4; i++) {
- dest[i][j] = tile->data.color[y][x][i];
+ uint cbuf;
+
+ /* loop over colorbuffer outputs */
+ for (cbuf = 0; cbuf < softpipe->framebuffer.num_cbufs; cbuf++) {
+ float dest[4][QUAD_SIZE];
+ ubyte src[4][4], dst[4][4], res[4][4];
+ uint *src4 = (uint *) src;
+ uint *dst4 = (uint *) dst;
+ uint *res4 = (uint *) res;
+ struct softpipe_cached_tile *
+ tile = sp_get_cached_tile(softpipe,
+ softpipe->cbuf_cache[cbuf],
+ quad->x0, quad->y0);
+ float (*quadColor)[4] = quad->outputs.color[cbuf];
+ uint i, j;
+
+ /* get/swizzle dest colors */
+ for (j = 0; j < QUAD_SIZE; j++) {
+ int x = (quad->x0 & (TILE_SIZE-1)) + (j & 1);
+ int y = (quad->y0 & (TILE_SIZE-1)) + (j >> 1);
+ for (i = 0; i < 4; i++) {
+ dest[i][j] = tile->data.color[y][x][i];
+ }
}
- }
- /* convert to ubyte */
- for (j = 0; j < 4; j++) { /* loop over R,G,B,A channels */
- UNCLAMPED_FLOAT_TO_UBYTE(dst[j][0], dest[j][0]); /* P0 */
- UNCLAMPED_FLOAT_TO_UBYTE(dst[j][1], dest[j][1]); /* P1 */
- UNCLAMPED_FLOAT_TO_UBYTE(dst[j][2], dest[j][2]); /* P2 */
- UNCLAMPED_FLOAT_TO_UBYTE(dst[j][3], dest[j][3]); /* P3 */
-
- UNCLAMPED_FLOAT_TO_UBYTE(src[j][0], quadColor[j][0]); /* P0 */
- UNCLAMPED_FLOAT_TO_UBYTE(src[j][1], quadColor[j][1]); /* P1 */
- UNCLAMPED_FLOAT_TO_UBYTE(src[j][2], quadColor[j][2]); /* P2 */
- UNCLAMPED_FLOAT_TO_UBYTE(src[j][3], quadColor[j][3]); /* P3 */
- }
+ /* convert to ubyte */
+ for (j = 0; j < 4; j++) { /* loop over R,G,B,A channels */
+ UNCLAMPED_FLOAT_TO_UBYTE(dst[j][0], dest[j][0]); /* P0 */
+ UNCLAMPED_FLOAT_TO_UBYTE(dst[j][1], dest[j][1]); /* P1 */
+ UNCLAMPED_FLOAT_TO_UBYTE(dst[j][2], dest[j][2]); /* P2 */
+ UNCLAMPED_FLOAT_TO_UBYTE(dst[j][3], dest[j][3]); /* P3 */
+
+ UNCLAMPED_FLOAT_TO_UBYTE(src[j][0], quadColor[j][0]); /* P0 */
+ UNCLAMPED_FLOAT_TO_UBYTE(src[j][1], quadColor[j][1]); /* P1 */
+ UNCLAMPED_FLOAT_TO_UBYTE(src[j][2], quadColor[j][2]); /* P2 */
+ UNCLAMPED_FLOAT_TO_UBYTE(src[j][3], quadColor[j][3]); /* P3 */
+ }
- switch (softpipe->blend->logicop_func) {
- case PIPE_LOGICOP_CLEAR:
- for (j = 0; j < 4; j++)
- res4[j] = 0;
- break;
- case PIPE_LOGICOP_NOR:
- for (j = 0; j < 4; j++)
- res4[j] = ~(src4[j] | dst4[j]);
- break;
- case PIPE_LOGICOP_AND_INVERTED:
- for (j = 0; j < 4; j++)
- res4[j] = ~src4[j] & dst4[j];
- break;
- case PIPE_LOGICOP_COPY_INVERTED:
- for (j = 0; j < 4; j++)
- res4[j] = ~src4[j];
- break;
- case PIPE_LOGICOP_AND_REVERSE:
- for (j = 0; j < 4; j++)
- res4[j] = src4[j] & ~dst4[j];
- break;
- case PIPE_LOGICOP_INVERT:
- for (j = 0; j < 4; j++)
- res4[j] = ~dst4[j];
- break;
- case PIPE_LOGICOP_XOR:
- for (j = 0; j < 4; j++)
- res4[j] = dst4[j] ^ src4[j];
- break;
- case PIPE_LOGICOP_NAND:
- for (j = 0; j < 4; j++)
- res4[j] = ~(src4[j] & dst4[j]);
- break;
- case PIPE_LOGICOP_AND:
- for (j = 0; j < 4; j++)
- res4[j] = src4[j] & dst4[j];
- break;
- case PIPE_LOGICOP_EQUIV:
- for (j = 0; j < 4; j++)
- res4[j] = ~(src4[j] ^ dst4[j]);
- break;
- case PIPE_LOGICOP_NOOP:
- for (j = 0; j < 4; j++)
- res4[j] = dst4[j];
- break;
- case PIPE_LOGICOP_OR_INVERTED:
- for (j = 0; j < 4; j++)
- res4[j] = ~src4[j] | dst4[j];
- break;
- case PIPE_LOGICOP_COPY:
- for (j = 0; j < 4; j++)
- res4[j] = src4[j];
- break;
- case PIPE_LOGICOP_OR_REVERSE:
- for (j = 0; j < 4; j++)
- res4[j] = src4[j] | ~dst4[j];
- break;
- case PIPE_LOGICOP_OR:
- for (j = 0; j < 4; j++)
- res4[j] = src4[j] | dst4[j];
- break;
- case PIPE_LOGICOP_SET:
- for (j = 0; j < 4; j++)
- res4[j] = ~0;
- break;
- default:
- assert(0);
- }
+ switch (softpipe->blend->logicop_func) {
+ case PIPE_LOGICOP_CLEAR:
+ for (j = 0; j < 4; j++)
+ res4[j] = 0;
+ break;
+ case PIPE_LOGICOP_NOR:
+ for (j = 0; j < 4; j++)
+ res4[j] = ~(src4[j] | dst4[j]);
+ break;
+ case PIPE_LOGICOP_AND_INVERTED:
+ for (j = 0; j < 4; j++)
+ res4[j] = ~src4[j] & dst4[j];
+ break;
+ case PIPE_LOGICOP_COPY_INVERTED:
+ for (j = 0; j < 4; j++)
+ res4[j] = ~src4[j];
+ break;
+ case PIPE_LOGICOP_AND_REVERSE:
+ for (j = 0; j < 4; j++)
+ res4[j] = src4[j] & ~dst4[j];
+ break;
+ case PIPE_LOGICOP_INVERT:
+ for (j = 0; j < 4; j++)
+ res4[j] = ~dst4[j];
+ break;
+ case PIPE_LOGICOP_XOR:
+ for (j = 0; j < 4; j++)
+ res4[j] = dst4[j] ^ src4[j];
+ break;
+ case PIPE_LOGICOP_NAND:
+ for (j = 0; j < 4; j++)
+ res4[j] = ~(src4[j] & dst4[j]);
+ break;
+ case PIPE_LOGICOP_AND:
+ for (j = 0; j < 4; j++)
+ res4[j] = src4[j] & dst4[j];
+ break;
+ case PIPE_LOGICOP_EQUIV:
+ for (j = 0; j < 4; j++)
+ res4[j] = ~(src4[j] ^ dst4[j]);
+ break;
+ case PIPE_LOGICOP_NOOP:
+ for (j = 0; j < 4; j++)
+ res4[j] = dst4[j];
+ break;
+ case PIPE_LOGICOP_OR_INVERTED:
+ for (j = 0; j < 4; j++)
+ res4[j] = ~src4[j] | dst4[j];
+ break;
+ case PIPE_LOGICOP_COPY:
+ for (j = 0; j < 4; j++)
+ res4[j] = src4[j];
+ break;
+ case PIPE_LOGICOP_OR_REVERSE:
+ for (j = 0; j < 4; j++)
+ res4[j] = src4[j] | ~dst4[j];
+ break;
+ case PIPE_LOGICOP_OR:
+ for (j = 0; j < 4; j++)
+ res4[j] = src4[j] | dst4[j];
+ break;
+ case PIPE_LOGICOP_SET:
+ for (j = 0; j < 4; j++)
+ res4[j] = ~0;
+ break;
+ default:
+ assert(0);
+ }
- for (j = 0; j < 4; j++) {
- quadColor[j][0] = UBYTE_TO_FLOAT(res[j][0]);
- quadColor[j][1] = UBYTE_TO_FLOAT(res[j][1]);
- quadColor[j][2] = UBYTE_TO_FLOAT(res[j][2]);
- quadColor[j][3] = UBYTE_TO_FLOAT(res[j][3]);
+ for (j = 0; j < 4; j++) {
+ quadColor[j][0] = UBYTE_TO_FLOAT(res[j][0]);
+ quadColor[j][1] = UBYTE_TO_FLOAT(res[j][1]);
+ quadColor[j][2] = UBYTE_TO_FLOAT(res[j][2]);
+ quadColor[j][3] = UBYTE_TO_FLOAT(res[j][3]);
+ }
}
/* pass quad to next stage */
@@ -221,504 +226,511 @@ logicop_quad(struct quad_stage *qs, struct quad_header *quad)
static void
blend_quad(struct quad_stage *qs, struct quad_header *quad)
{
- struct softpipe_context *softpipe = qs->softpipe;
static const float zero[4] = { 0, 0, 0, 0 };
static const float one[4] = { 1, 1, 1, 1 };
- float source[4][QUAD_SIZE], dest[4][QUAD_SIZE];
- struct softpipe_cached_tile *tile
- = sp_get_cached_tile(softpipe,
- softpipe->cbuf_cache[softpipe->current_cbuf],
- quad->x0, quad->y0);
- float (*quadColor)[4] = quad->outputs.color;
- uint i, j;
-
- if (softpipe->blend->logicop_enable) {
- logicop_quad(qs, quad);
- return;
- }
- /* get/swizzle dest colors */
- for (j = 0; j < QUAD_SIZE; j++) {
- int x = (quad->x0 & (TILE_SIZE-1)) + (j & 1);
- int y = (quad->y0 & (TILE_SIZE-1)) + (j >> 1);
- for (i = 0; i < 4; i++) {
- dest[i][j] = tile->data.color[y][x][i];
+ struct softpipe_context *softpipe = qs->softpipe;
+ uint cbuf;
+
+ /* loop over colorbuffer outputs */
+ for (cbuf = 0; cbuf < softpipe->framebuffer.num_cbufs; cbuf++) {
+ float source[4][QUAD_SIZE], dest[4][QUAD_SIZE];
+ struct softpipe_cached_tile *tile
+ = sp_get_cached_tile(softpipe,
+ softpipe->cbuf_cache[cbuf],
+ quad->x0, quad->y0);
+ float (*quadColor)[4] = quad->outputs.color[cbuf];
+ uint i, j;
+
+ if (softpipe->blend->logicop_enable) {
+ logicop_quad(qs, quad);
+ return;
}
- }
- /*
- * Compute src/first term RGB
- */
- switch (softpipe->blend->rgb_src_factor) {
- case PIPE_BLENDFACTOR_ONE:
- VEC4_COPY(source[0], quadColor[0]); /* R */
- VEC4_COPY(source[1], quadColor[1]); /* G */
- VEC4_COPY(source[2], quadColor[2]); /* B */
- break;
- case PIPE_BLENDFACTOR_SRC_COLOR:
- VEC4_MUL(source[0], quadColor[0], quadColor[0]); /* R */
- VEC4_MUL(source[1], quadColor[1], quadColor[1]); /* G */
- VEC4_MUL(source[2], quadColor[2], quadColor[2]); /* B */
- break;
- case PIPE_BLENDFACTOR_SRC_ALPHA:
- {
- const float *alpha = quadColor[3];
- VEC4_MUL(source[0], quadColor[0], alpha); /* R */
- VEC4_MUL(source[1], quadColor[1], alpha); /* G */
- VEC4_MUL(source[2], quadColor[2], alpha); /* B */
- }
- break;
- case PIPE_BLENDFACTOR_DST_COLOR:
- VEC4_MUL(source[0], quadColor[0], dest[0]); /* R */
- VEC4_MUL(source[1], quadColor[1], dest[1]); /* G */
- VEC4_MUL(source[2], quadColor[2], dest[2]); /* B */
- break;
- case PIPE_BLENDFACTOR_DST_ALPHA:
- {
- const float *alpha = dest[3];
- VEC4_MUL(source[0], quadColor[0], alpha); /* R */
- VEC4_MUL(source[1], quadColor[1], alpha); /* G */
- VEC4_MUL(source[2], quadColor[2], alpha); /* B */
- }
- break;
- case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
- {
- const float *alpha = quadColor[3];
- float diff[4];
- VEC4_SUB(diff, one, dest[3]);
- VEC4_MIN(source[0], alpha, diff); /* R */
- VEC4_MIN(source[1], alpha, diff); /* G */
- VEC4_MIN(source[2], alpha, diff); /* B */
- }
- break;
- case PIPE_BLENDFACTOR_CONST_COLOR:
- {
- float comp[4];
- VEC4_SCALAR(comp, softpipe->blend_color.color[0]); /* R */
- VEC4_MUL(source[0], quadColor[0], comp); /* R */
- VEC4_SCALAR(comp, softpipe->blend_color.color[1]); /* G */
- VEC4_MUL(source[1], quadColor[1], comp); /* G */
- VEC4_SCALAR(comp, softpipe->blend_color.color[2]); /* B */
- VEC4_MUL(source[2], quadColor[2], comp); /* B */
- }
- break;
- case PIPE_BLENDFACTOR_CONST_ALPHA:
- {
- float alpha[4];
- VEC4_SCALAR(alpha, softpipe->blend_color.color[3]);
- VEC4_MUL(source[0], quadColor[0], alpha); /* R */
- VEC4_MUL(source[1], quadColor[1], alpha); /* G */
- VEC4_MUL(source[2], quadColor[2], alpha); /* B */
- }
- break;
- case PIPE_BLENDFACTOR_SRC1_COLOR:
- assert(0); /* to do */
- break;
- case PIPE_BLENDFACTOR_SRC1_ALPHA:
- assert(0); /* to do */
- break;
- case PIPE_BLENDFACTOR_ZERO:
- VEC4_COPY(source[0], zero); /* R */
- VEC4_COPY(source[1], zero); /* G */
- VEC4_COPY(source[2], zero); /* B */
- break;
- case PIPE_BLENDFACTOR_INV_SRC_COLOR:
- {
- float inv_comp[4];
- VEC4_SUB(inv_comp, one, quadColor[0]); /* R */
- VEC4_MUL(source[0], quadColor[0], inv_comp); /* R */
- VEC4_SUB(inv_comp, one, quadColor[1]); /* G */
- VEC4_MUL(source[1], quadColor[1], inv_comp); /* G */
- VEC4_SUB(inv_comp, one, quadColor[2]); /* B */
- VEC4_MUL(source[2], quadColor[2], inv_comp); /* B */
- }
- break;
- case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
- {
- float inv_alpha[4];
- VEC4_SUB(inv_alpha, one, quadColor[3]);
- VEC4_MUL(source[0], quadColor[0], inv_alpha); /* R */
- VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */
- VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */
- }
- break;
- case PIPE_BLENDFACTOR_INV_DST_ALPHA:
- {
- float inv_alpha[4];
- VEC4_SUB(inv_alpha, one, dest[3]);
- VEC4_MUL(source[0], quadColor[0], inv_alpha); /* R */
- VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */
- VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */
- }
- break;
- case PIPE_BLENDFACTOR_INV_DST_COLOR:
- {
- float inv_comp[4];
- VEC4_SUB(inv_comp, one, dest[0]); /* R */
- VEC4_MUL(source[0], quadColor[0], inv_comp); /* R */
- VEC4_SUB(inv_comp, one, dest[1]); /* G */
- VEC4_MUL(source[1], quadColor[1], inv_comp); /* G */
- VEC4_SUB(inv_comp, one, dest[2]); /* B */
- VEC4_MUL(source[2], quadColor[2], inv_comp); /* B */
- }
- break;
- case PIPE_BLENDFACTOR_INV_CONST_COLOR:
- {
- float inv_comp[4];
- /* R */
- VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[0]);
- VEC4_MUL(source[0], quadColor[0], inv_comp);
- /* G */
- VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[1]);
- VEC4_MUL(source[1], quadColor[1], inv_comp);
- /* B */
- VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[2]);
- VEC4_MUL(source[2], quadColor[2], inv_comp);
- }
- break;
- case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
- {
- float inv_alpha[4];
- VEC4_SCALAR(inv_alpha, 1.0f - softpipe->blend_color.color[3]);
- VEC4_MUL(source[0], quadColor[0], inv_alpha); /* R */
- VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */
- VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */
- }
- break;
- case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
- assert(0); /* to do */
- break;
- case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
- assert(0); /* to do */
- break;
- default:
- assert(0);
- }
-
- /*
- * Compute src/first term A
- */
- switch (softpipe->blend->alpha_src_factor) {
- case PIPE_BLENDFACTOR_ONE:
- VEC4_COPY(source[3], quadColor[3]); /* A */
- break;
- case PIPE_BLENDFACTOR_SRC_COLOR:
- /* fall-through */
- case PIPE_BLENDFACTOR_SRC_ALPHA:
- {
- const float *alpha = quadColor[3];
- VEC4_MUL(source[3], quadColor[3], alpha); /* A */
- }
- break;
- case PIPE_BLENDFACTOR_DST_COLOR:
- /* fall-through */
- case PIPE_BLENDFACTOR_DST_ALPHA:
- VEC4_MUL(source[3], quadColor[3], dest[3]); /* A */
- break;
- case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
- {
- const float *alpha = quadColor[3];
- float diff[4];
- VEC4_SUB(diff, one, dest[3]);
- VEC4_MIN(source[3], alpha, diff); /* A */
- }
- break;
- case PIPE_BLENDFACTOR_CONST_COLOR:
- /* fall-through */
- case PIPE_BLENDFACTOR_CONST_ALPHA:
- {
- float comp[4];
- VEC4_SCALAR(comp, softpipe->blend_color.color[3]); /* A */
- VEC4_MUL(source[3], quadColor[3], comp); /* A */
+ /* get/swizzle dest colors */
+ for (j = 0; j < QUAD_SIZE; j++) {
+ int x = (quad->x0 & (TILE_SIZE-1)) + (j & 1);
+ int y = (quad->y0 & (TILE_SIZE-1)) + (j >> 1);
+ for (i = 0; i < 4; i++) {
+ dest[i][j] = tile->data.color[y][x][i];
+ }
}
- break;
- case PIPE_BLENDFACTOR_ZERO:
- VEC4_COPY(source[3], zero); /* A */
- break;
- case PIPE_BLENDFACTOR_INV_SRC_COLOR:
- /* fall-through */
- case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
- {
- float inv_alpha[4];
- VEC4_SUB(inv_alpha, one, quadColor[3]);
- VEC4_MUL(source[3], quadColor[3], inv_alpha); /* A */
- }
- break;
- case PIPE_BLENDFACTOR_INV_DST_COLOR:
- /* fall-through */
- case PIPE_BLENDFACTOR_INV_DST_ALPHA:
- {
- float inv_alpha[4];
- VEC4_SUB(inv_alpha, one, dest[3]);
- VEC4_MUL(source[3], quadColor[3], inv_alpha); /* A */
- }
- break;
- case PIPE_BLENDFACTOR_INV_CONST_COLOR:
- /* fall-through */
- case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
- {
- float inv_comp[4];
- /* A */
- VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[3]);
- VEC4_MUL(source[3], quadColor[3], inv_comp);
- }
- break;
- default:
- assert(0);
- }
-
-
- /*
- * Compute dest/second term RGB
- */
- switch (softpipe->blend->rgb_dst_factor) {
- case PIPE_BLENDFACTOR_ONE:
- /* dest = dest * 1 NO-OP, leave dest as-is */
- break;
- case PIPE_BLENDFACTOR_SRC_COLOR:
- VEC4_MUL(dest[0], dest[0], quadColor[0]); /* R */
- VEC4_MUL(dest[1], dest[1], quadColor[1]); /* G */
- VEC4_MUL(dest[2], dest[2], quadColor[2]); /* B */
- break;
- case PIPE_BLENDFACTOR_SRC_ALPHA:
- VEC4_MUL(dest[0], dest[0], quadColor[3]); /* R * A */
- VEC4_MUL(dest[1], dest[1], quadColor[3]); /* G * A */
- VEC4_MUL(dest[2], dest[2], quadColor[3]); /* B * A */
- break;
- case PIPE_BLENDFACTOR_DST_ALPHA:
- VEC4_MUL(dest[0], dest[0], dest[3]); /* R * A */
- VEC4_MUL(dest[1], dest[1], dest[3]); /* G * A */
- VEC4_MUL(dest[2], dest[2], dest[3]); /* B * A */
- break;
- case PIPE_BLENDFACTOR_DST_COLOR:
- VEC4_MUL(dest[0], dest[0], dest[0]); /* R */
- VEC4_MUL(dest[1], dest[1], dest[1]); /* G */
- VEC4_MUL(dest[2], dest[2], dest[2]); /* B */
- break;
- case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
- assert(0); /* illegal */
- break;
- case PIPE_BLENDFACTOR_CONST_COLOR:
- {
- float comp[4];
- VEC4_SCALAR(comp, softpipe->blend_color.color[0]); /* R */
- VEC4_MUL(dest[0], dest[0], comp); /* R */
- VEC4_SCALAR(comp, softpipe->blend_color.color[1]); /* G */
- VEC4_MUL(dest[1], dest[1], comp); /* G */
- VEC4_SCALAR(comp, softpipe->blend_color.color[2]); /* B */
- VEC4_MUL(dest[2], dest[2], comp); /* B */
- }
- break;
- case PIPE_BLENDFACTOR_CONST_ALPHA:
- {
- float comp[4];
- VEC4_SCALAR(comp, softpipe->blend_color.color[3]); /* A */
- VEC4_MUL(dest[0], dest[0], comp); /* R */
- VEC4_MUL(dest[1], dest[1], comp); /* G */
- VEC4_MUL(dest[2], dest[2], comp); /* B */
- }
- break;
- case PIPE_BLENDFACTOR_ZERO:
- VEC4_COPY(dest[0], zero); /* R */
- VEC4_COPY(dest[1], zero); /* G */
- VEC4_COPY(dest[2], zero); /* B */
- break;
- case PIPE_BLENDFACTOR_SRC1_COLOR:
- case PIPE_BLENDFACTOR_SRC1_ALPHA:
- /* XXX what are these? */
- assert(0);
- break;
- case PIPE_BLENDFACTOR_INV_SRC_COLOR:
- {
- float inv_comp[4];
- VEC4_SUB(inv_comp, one, quadColor[0]); /* R */
- VEC4_MUL(dest[0], inv_comp, dest[0]); /* R */
- VEC4_SUB(inv_comp, one, quadColor[1]); /* G */
- VEC4_MUL(dest[1], inv_comp, dest[1]); /* G */
- VEC4_SUB(inv_comp, one, quadColor[2]); /* B */
- VEC4_MUL(dest[2], inv_comp, dest[2]); /* B */
- }
- break;
- case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
- {
- float one_minus_alpha[QUAD_SIZE];
- VEC4_SUB(one_minus_alpha, one, quadColor[3]);
- VEC4_MUL(dest[0], dest[0], one_minus_alpha); /* R */
- VEC4_MUL(dest[1], dest[1], one_minus_alpha); /* G */
- VEC4_MUL(dest[2], dest[2], one_minus_alpha); /* B */
- }
- break;
- case PIPE_BLENDFACTOR_INV_DST_ALPHA:
- {
- float inv_comp[4];
- VEC4_SUB(inv_comp, one, quadColor[3]); /* A */
- VEC4_MUL(dest[0], inv_comp, dest[0]); /* R */
- VEC4_MUL(dest[1], inv_comp, dest[1]); /* G */
- VEC4_MUL(dest[2], inv_comp, dest[2]); /* B */
- }
- break;
- case PIPE_BLENDFACTOR_INV_DST_COLOR:
- {
- float inv_comp[4];
- VEC4_SUB(inv_comp, one, dest[0]); /* R */
- VEC4_MUL(dest[0], dest[0], inv_comp); /* R */
- VEC4_SUB(inv_comp, one, dest[1]); /* G */
- VEC4_MUL(dest[1], dest[1], inv_comp); /* G */
- VEC4_SUB(inv_comp, one, dest[2]); /* B */
- VEC4_MUL(dest[2], dest[2], inv_comp); /* B */
- }
- break;
- case PIPE_BLENDFACTOR_INV_CONST_COLOR:
- {
- float inv_comp[4];
- /* R */
- VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[0]);
- VEC4_MUL(dest[0], dest[0], inv_comp);
- /* G */
- VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[1]);
- VEC4_MUL(dest[1], dest[1], inv_comp);
- /* B */
- VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[2]);
- VEC4_MUL(dest[2], dest[2], inv_comp);
+
+ /*
+ * Compute src/first term RGB
+ */
+ switch (softpipe->blend->rgb_src_factor) {
+ case PIPE_BLENDFACTOR_ONE:
+ VEC4_COPY(source[0], quadColor[0]); /* R */
+ VEC4_COPY(source[1], quadColor[1]); /* G */
+ VEC4_COPY(source[2], quadColor[2]); /* B */
+ break;
+ case PIPE_BLENDFACTOR_SRC_COLOR:
+ VEC4_MUL(source[0], quadColor[0], quadColor[0]); /* R */
+ VEC4_MUL(source[1], quadColor[1], quadColor[1]); /* G */
+ VEC4_MUL(source[2], quadColor[2], quadColor[2]); /* B */
+ break;
+ case PIPE_BLENDFACTOR_SRC_ALPHA:
+ {
+ const float *alpha = quadColor[3];
+ VEC4_MUL(source[0], quadColor[0], alpha); /* R */
+ VEC4_MUL(source[1], quadColor[1], alpha); /* G */
+ VEC4_MUL(source[2], quadColor[2], alpha); /* B */
+ }
+ break;
+ case PIPE_BLENDFACTOR_DST_COLOR:
+ VEC4_MUL(source[0], quadColor[0], dest[0]); /* R */
+ VEC4_MUL(source[1], quadColor[1], dest[1]); /* G */
+ VEC4_MUL(source[2], quadColor[2], dest[2]); /* B */
+ break;
+ case PIPE_BLENDFACTOR_DST_ALPHA:
+ {
+ const float *alpha = dest[3];
+ VEC4_MUL(source[0], quadColor[0], alpha); /* R */
+ VEC4_MUL(source[1], quadColor[1], alpha); /* G */
+ VEC4_MUL(source[2], quadColor[2], alpha); /* B */
+ }
+ break;
+ case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
+ {
+ const float *alpha = quadColor[3];
+ float diff[4];
+ VEC4_SUB(diff, one, dest[3]);
+ VEC4_MIN(source[0], alpha, diff); /* R */
+ VEC4_MIN(source[1], alpha, diff); /* G */
+ VEC4_MIN(source[2], alpha, diff); /* B */
+ }
+ break;
+ case PIPE_BLENDFACTOR_CONST_COLOR:
+ {
+ float comp[4];
+ VEC4_SCALAR(comp, softpipe->blend_color.color[0]); /* R */
+ VEC4_MUL(source[0], quadColor[0], comp); /* R */
+ VEC4_SCALAR(comp, softpipe->blend_color.color[1]); /* G */
+ VEC4_MUL(source[1], quadColor[1], comp); /* G */
+ VEC4_SCALAR(comp, softpipe->blend_color.color[2]); /* B */
+ VEC4_MUL(source[2], quadColor[2], comp); /* B */
+ }
+ break;
+ case PIPE_BLENDFACTOR_CONST_ALPHA:
+ {
+ float alpha[4];
+ VEC4_SCALAR(alpha, softpipe->blend_color.color[3]);
+ VEC4_MUL(source[0], quadColor[0], alpha); /* R */
+ VEC4_MUL(source[1], quadColor[1], alpha); /* G */
+ VEC4_MUL(source[2], quadColor[2], alpha); /* B */
+ }
+ break;
+ case PIPE_BLENDFACTOR_SRC1_COLOR:
+ assert(0); /* to do */
+ break;
+ case PIPE_BLENDFACTOR_SRC1_ALPHA:
+ assert(0); /* to do */
+ break;
+ case PIPE_BLENDFACTOR_ZERO:
+ VEC4_COPY(source[0], zero); /* R */
+ VEC4_COPY(source[1], zero); /* G */
+ VEC4_COPY(source[2], zero); /* B */
+ break;
+ case PIPE_BLENDFACTOR_INV_SRC_COLOR:
+ {
+ float inv_comp[4];
+ VEC4_SUB(inv_comp, one, quadColor[0]); /* R */
+ VEC4_MUL(source[0], quadColor[0], inv_comp); /* R */
+ VEC4_SUB(inv_comp, one, quadColor[1]); /* G */
+ VEC4_MUL(source[1], quadColor[1], inv_comp); /* G */
+ VEC4_SUB(inv_comp, one, quadColor[2]); /* B */
+ VEC4_MUL(source[2], quadColor[2], inv_comp); /* B */
+ }
+ break;
+ case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
+ {
+ float inv_alpha[4];
+ VEC4_SUB(inv_alpha, one, quadColor[3]);
+ VEC4_MUL(source[0], quadColor[0], inv_alpha); /* R */
+ VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */
+ VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */
+ }
+ break;
+ case PIPE_BLENDFACTOR_INV_DST_ALPHA:
+ {
+ float inv_alpha[4];
+ VEC4_SUB(inv_alpha, one, dest[3]);
+ VEC4_MUL(source[0], quadColor[0], inv_alpha); /* R */
+ VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */
+ VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */
+ }
+ break;
+ case PIPE_BLENDFACTOR_INV_DST_COLOR:
+ {
+ float inv_comp[4];
+ VEC4_SUB(inv_comp, one, dest[0]); /* R */
+ VEC4_MUL(source[0], quadColor[0], inv_comp); /* R */
+ VEC4_SUB(inv_comp, one, dest[1]); /* G */
+ VEC4_MUL(source[1], quadColor[1], inv_comp); /* G */
+ VEC4_SUB(inv_comp, one, dest[2]); /* B */
+ VEC4_MUL(source[2], quadColor[2], inv_comp); /* B */
+ }
+ break;
+ case PIPE_BLENDFACTOR_INV_CONST_COLOR:
+ {
+ float inv_comp[4];
+ /* R */
+ VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[0]);
+ VEC4_MUL(source[0], quadColor[0], inv_comp);
+ /* G */
+ VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[1]);
+ VEC4_MUL(source[1], quadColor[1], inv_comp);
+ /* B */
+ VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[2]);
+ VEC4_MUL(source[2], quadColor[2], inv_comp);
+ }
+ break;
+ case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
+ {
+ float inv_alpha[4];
+ VEC4_SCALAR(inv_alpha, 1.0f - softpipe->blend_color.color[3]);
+ VEC4_MUL(source[0], quadColor[0], inv_alpha); /* R */
+ VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */
+ VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */
+ }
+ break;
+ case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
+ assert(0); /* to do */
+ break;
+ case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
+ assert(0); /* to do */
+ break;
+ default:
+ assert(0);
}
- break;
- case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
- {
- float inv_comp[4];
- VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[3]);
- VEC4_MUL(dest[0], dest[0], inv_comp);
- VEC4_MUL(dest[1], dest[1], inv_comp);
- VEC4_MUL(dest[2], dest[2], inv_comp);
+
+ /*
+ * Compute src/first term A
+ */
+ switch (softpipe->blend->alpha_src_factor) {
+ case PIPE_BLENDFACTOR_ONE:
+ VEC4_COPY(source[3], quadColor[3]); /* A */
+ break;
+ case PIPE_BLENDFACTOR_SRC_COLOR:
+ /* fall-through */
+ case PIPE_BLENDFACTOR_SRC_ALPHA:
+ {
+ const float *alpha = quadColor[3];
+ VEC4_MUL(source[3], quadColor[3], alpha); /* A */
+ }
+ break;
+ case PIPE_BLENDFACTOR_DST_COLOR:
+ /* fall-through */
+ case PIPE_BLENDFACTOR_DST_ALPHA:
+ VEC4_MUL(source[3], quadColor[3], dest[3]); /* A */
+ break;
+ case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
+ {
+ const float *alpha = quadColor[3];
+ float diff[4];
+ VEC4_SUB(diff, one, dest[3]);
+ VEC4_MIN(source[3], alpha, diff); /* A */
+ }
+ break;
+ case PIPE_BLENDFACTOR_CONST_COLOR:
+ /* fall-through */
+ case PIPE_BLENDFACTOR_CONST_ALPHA:
+ {
+ float comp[4];
+ VEC4_SCALAR(comp, softpipe->blend_color.color[3]); /* A */
+ VEC4_MUL(source[3], quadColor[3], comp); /* A */
+ }
+ break;
+ case PIPE_BLENDFACTOR_ZERO:
+ VEC4_COPY(source[3], zero); /* A */
+ break;
+ case PIPE_BLENDFACTOR_INV_SRC_COLOR:
+ /* fall-through */
+ case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
+ {
+ float inv_alpha[4];
+ VEC4_SUB(inv_alpha, one, quadColor[3]);
+ VEC4_MUL(source[3], quadColor[3], inv_alpha); /* A */
+ }
+ break;
+ case PIPE_BLENDFACTOR_INV_DST_COLOR:
+ /* fall-through */
+ case PIPE_BLENDFACTOR_INV_DST_ALPHA:
+ {
+ float inv_alpha[4];
+ VEC4_SUB(inv_alpha, one, dest[3]);
+ VEC4_MUL(source[3], quadColor[3], inv_alpha); /* A */
+ }
+ break;
+ case PIPE_BLENDFACTOR_INV_CONST_COLOR:
+ /* fall-through */
+ case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
+ {
+ float inv_comp[4];
+ /* A */
+ VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[3]);
+ VEC4_MUL(source[3], quadColor[3], inv_comp);
+ }
+ break;
+ default:
+ assert(0);
}
- break;
- case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
- case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
- /* XXX what are these? */
- assert(0);
- break;
- default:
- assert(0);
- }
-
- /*
- * Compute dest/second term A
- */
- switch (softpipe->blend->alpha_dst_factor) {
- case PIPE_BLENDFACTOR_ONE:
- /* dest = dest * 1 NO-OP, leave dest as-is */
- break;
- case PIPE_BLENDFACTOR_SRC_COLOR:
- /* fall-through */
- case PIPE_BLENDFACTOR_SRC_ALPHA:
- VEC4_MUL(dest[3], dest[3], quadColor[3]); /* A * A */
- break;
- case PIPE_BLENDFACTOR_DST_COLOR:
- /* fall-through */
- case PIPE_BLENDFACTOR_DST_ALPHA:
- VEC4_MUL(dest[3], dest[3], dest[3]); /* A */
- break;
- case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
- assert(0); /* illegal */
- break;
- case PIPE_BLENDFACTOR_CONST_COLOR:
- /* fall-through */
- case PIPE_BLENDFACTOR_CONST_ALPHA:
- {
- float comp[4];
- VEC4_SCALAR(comp, softpipe->blend_color.color[3]); /* A */
- VEC4_MUL(dest[3], dest[3], comp); /* A */
+
+
+ /*
+ * Compute dest/second term RGB
+ */
+ switch (softpipe->blend->rgb_dst_factor) {
+ case PIPE_BLENDFACTOR_ONE:
+ /* dest = dest * 1 NO-OP, leave dest as-is */
+ break;
+ case PIPE_BLENDFACTOR_SRC_COLOR:
+ VEC4_MUL(dest[0], dest[0], quadColor[0]); /* R */
+ VEC4_MUL(dest[1], dest[1], quadColor[1]); /* G */
+ VEC4_MUL(dest[2], dest[2], quadColor[2]); /* B */
+ break;
+ case PIPE_BLENDFACTOR_SRC_ALPHA:
+ VEC4_MUL(dest[0], dest[0], quadColor[3]); /* R * A */
+ VEC4_MUL(dest[1], dest[1], quadColor[3]); /* G * A */
+ VEC4_MUL(dest[2], dest[2], quadColor[3]); /* B * A */
+ break;
+ case PIPE_BLENDFACTOR_DST_ALPHA:
+ VEC4_MUL(dest[0], dest[0], dest[3]); /* R * A */
+ VEC4_MUL(dest[1], dest[1], dest[3]); /* G * A */
+ VEC4_MUL(dest[2], dest[2], dest[3]); /* B * A */
+ break;
+ case PIPE_BLENDFACTOR_DST_COLOR:
+ VEC4_MUL(dest[0], dest[0], dest[0]); /* R */
+ VEC4_MUL(dest[1], dest[1], dest[1]); /* G */
+ VEC4_MUL(dest[2], dest[2], dest[2]); /* B */
+ break;
+ case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
+ assert(0); /* illegal */
+ break;
+ case PIPE_BLENDFACTOR_CONST_COLOR:
+ {
+ float comp[4];
+ VEC4_SCALAR(comp, softpipe->blend_color.color[0]); /* R */
+ VEC4_MUL(dest[0], dest[0], comp); /* R */
+ VEC4_SCALAR(comp, softpipe->blend_color.color[1]); /* G */
+ VEC4_MUL(dest[1], dest[1], comp); /* G */
+ VEC4_SCALAR(comp, softpipe->blend_color.color[2]); /* B */
+ VEC4_MUL(dest[2], dest[2], comp); /* B */
+ }
+ break;
+ case PIPE_BLENDFACTOR_CONST_ALPHA:
+ {
+ float comp[4];
+ VEC4_SCALAR(comp, softpipe->blend_color.color[3]); /* A */
+ VEC4_MUL(dest[0], dest[0], comp); /* R */
+ VEC4_MUL(dest[1], dest[1], comp); /* G */
+ VEC4_MUL(dest[2], dest[2], comp); /* B */
+ }
+ break;
+ case PIPE_BLENDFACTOR_ZERO:
+ VEC4_COPY(dest[0], zero); /* R */
+ VEC4_COPY(dest[1], zero); /* G */
+ VEC4_COPY(dest[2], zero); /* B */
+ break;
+ case PIPE_BLENDFACTOR_SRC1_COLOR:
+ case PIPE_BLENDFACTOR_SRC1_ALPHA:
+ /* XXX what are these? */
+ assert(0);
+ break;
+ case PIPE_BLENDFACTOR_INV_SRC_COLOR:
+ {
+ float inv_comp[4];
+ VEC4_SUB(inv_comp, one, quadColor[0]); /* R */
+ VEC4_MUL(dest[0], inv_comp, dest[0]); /* R */
+ VEC4_SUB(inv_comp, one, quadColor[1]); /* G */
+ VEC4_MUL(dest[1], inv_comp, dest[1]); /* G */
+ VEC4_SUB(inv_comp, one, quadColor[2]); /* B */
+ VEC4_MUL(dest[2], inv_comp, dest[2]); /* B */
+ }
+ break;
+ case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
+ {
+ float one_minus_alpha[QUAD_SIZE];
+ VEC4_SUB(one_minus_alpha, one, quadColor[3]);
+ VEC4_MUL(dest[0], dest[0], one_minus_alpha); /* R */
+ VEC4_MUL(dest[1], dest[1], one_minus_alpha); /* G */
+ VEC4_MUL(dest[2], dest[2], one_minus_alpha); /* B */
+ }
+ break;
+ case PIPE_BLENDFACTOR_INV_DST_ALPHA:
+ {
+ float inv_comp[4];
+ VEC4_SUB(inv_comp, one, quadColor[3]); /* A */
+ VEC4_MUL(dest[0], inv_comp, dest[0]); /* R */
+ VEC4_MUL(dest[1], inv_comp, dest[1]); /* G */
+ VEC4_MUL(dest[2], inv_comp, dest[2]); /* B */
+ }
+ break;
+ case PIPE_BLENDFACTOR_INV_DST_COLOR:
+ {
+ float inv_comp[4];
+ VEC4_SUB(inv_comp, one, dest[0]); /* R */
+ VEC4_MUL(dest[0], dest[0], inv_comp); /* R */
+ VEC4_SUB(inv_comp, one, dest[1]); /* G */
+ VEC4_MUL(dest[1], dest[1], inv_comp); /* G */
+ VEC4_SUB(inv_comp, one, dest[2]); /* B */
+ VEC4_MUL(dest[2], dest[2], inv_comp); /* B */
+ }
+ break;
+ case PIPE_BLENDFACTOR_INV_CONST_COLOR:
+ {
+ float inv_comp[4];
+ /* R */
+ VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[0]);
+ VEC4_MUL(dest[0], dest[0], inv_comp);
+ /* G */
+ VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[1]);
+ VEC4_MUL(dest[1], dest[1], inv_comp);
+ /* B */
+ VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[2]);
+ VEC4_MUL(dest[2], dest[2], inv_comp);
+ }
+ break;
+ case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
+ {
+ float inv_comp[4];
+ VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[3]);
+ VEC4_MUL(dest[0], dest[0], inv_comp);
+ VEC4_MUL(dest[1], dest[1], inv_comp);
+ VEC4_MUL(dest[2], dest[2], inv_comp);
+ }
+ break;
+ case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
+ case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
+ /* XXX what are these? */
+ assert(0);
+ break;
+ default:
+ assert(0);
}
- break;
- case PIPE_BLENDFACTOR_ZERO:
- VEC4_COPY(dest[3], zero); /* A */
- break;
- case PIPE_BLENDFACTOR_INV_SRC_COLOR:
- /* fall-through */
- case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
- {
- float one_minus_alpha[QUAD_SIZE];
- VEC4_SUB(one_minus_alpha, one, quadColor[3]);
- VEC4_MUL(dest[3], dest[3], one_minus_alpha); /* A */
+
+ /*
+ * Compute dest/second term A
+ */
+ switch (softpipe->blend->alpha_dst_factor) {
+ case PIPE_BLENDFACTOR_ONE:
+ /* dest = dest * 1 NO-OP, leave dest as-is */
+ break;
+ case PIPE_BLENDFACTOR_SRC_COLOR:
+ /* fall-through */
+ case PIPE_BLENDFACTOR_SRC_ALPHA:
+ VEC4_MUL(dest[3], dest[3], quadColor[3]); /* A * A */
+ break;
+ case PIPE_BLENDFACTOR_DST_COLOR:
+ /* fall-through */
+ case PIPE_BLENDFACTOR_DST_ALPHA:
+ VEC4_MUL(dest[3], dest[3], dest[3]); /* A */
+ break;
+ case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
+ assert(0); /* illegal */
+ break;
+ case PIPE_BLENDFACTOR_CONST_COLOR:
+ /* fall-through */
+ case PIPE_BLENDFACTOR_CONST_ALPHA:
+ {
+ float comp[4];
+ VEC4_SCALAR(comp, softpipe->blend_color.color[3]); /* A */
+ VEC4_MUL(dest[3], dest[3], comp); /* A */
+ }
+ break;
+ case PIPE_BLENDFACTOR_ZERO:
+ VEC4_COPY(dest[3], zero); /* A */
+ break;
+ case PIPE_BLENDFACTOR_INV_SRC_COLOR:
+ /* fall-through */
+ case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
+ {
+ float one_minus_alpha[QUAD_SIZE];
+ VEC4_SUB(one_minus_alpha, one, quadColor[3]);
+ VEC4_MUL(dest[3], dest[3], one_minus_alpha); /* A */
+ }
+ break;
+ case PIPE_BLENDFACTOR_INV_DST_COLOR:
+ /* fall-through */
+ case PIPE_BLENDFACTOR_INV_DST_ALPHA:
+ {
+ float inv_comp[4];
+ VEC4_SUB(inv_comp, one, dest[3]); /* A */
+ VEC4_MUL(dest[3], inv_comp, dest[3]); /* A */
+ }
+ break;
+ case PIPE_BLENDFACTOR_INV_CONST_COLOR:
+ /* fall-through */
+ case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
+ {
+ float inv_comp[4];
+ VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[3]);
+ VEC4_MUL(dest[3], dest[3], inv_comp);
+ }
+ break;
+ default:
+ assert(0);
}
- break;
- case PIPE_BLENDFACTOR_INV_DST_COLOR:
- /* fall-through */
- case PIPE_BLENDFACTOR_INV_DST_ALPHA:
- {
- float inv_comp[4];
- VEC4_SUB(inv_comp, one, dest[3]); /* A */
- VEC4_MUL(dest[3], inv_comp, dest[3]); /* A */
+
+ /*
+ * Combine RGB terms
+ */
+ switch (softpipe->blend->rgb_func) {
+ case PIPE_BLEND_ADD:
+ VEC4_ADD(quadColor[0], source[0], dest[0]); /* R */
+ VEC4_ADD(quadColor[1], source[1], dest[1]); /* G */
+ VEC4_ADD(quadColor[2], source[2], dest[2]); /* B */
+ break;
+ case PIPE_BLEND_SUBTRACT:
+ VEC4_SUB(quadColor[0], source[0], dest[0]); /* R */
+ VEC4_SUB(quadColor[1], source[1], dest[1]); /* G */
+ VEC4_SUB(quadColor[2], source[2], dest[2]); /* B */
+ break;
+ case PIPE_BLEND_REVERSE_SUBTRACT:
+ VEC4_SUB(quadColor[0], dest[0], source[0]); /* R */
+ VEC4_SUB(quadColor[1], dest[1], source[1]); /* G */
+ VEC4_SUB(quadColor[2], dest[2], source[2]); /* B */
+ break;
+ case PIPE_BLEND_MIN:
+ VEC4_MIN(quadColor[0], source[0], dest[0]); /* R */
+ VEC4_MIN(quadColor[1], source[1], dest[1]); /* G */
+ VEC4_MIN(quadColor[2], source[2], dest[2]); /* B */
+ break;
+ case PIPE_BLEND_MAX:
+ VEC4_MAX(quadColor[0], source[0], dest[0]); /* R */
+ VEC4_MAX(quadColor[1], source[1], dest[1]); /* G */
+ VEC4_MAX(quadColor[2], source[2], dest[2]); /* B */
+ break;
+ default:
+ assert(0);
}
- break;
- case PIPE_BLENDFACTOR_INV_CONST_COLOR:
- /* fall-through */
- case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
- {
- float inv_comp[4];
- VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[3]);
- VEC4_MUL(dest[3], dest[3], inv_comp);
+
+ /*
+ * Combine A terms
+ */
+ switch (softpipe->blend->alpha_func) {
+ case PIPE_BLEND_ADD:
+ VEC4_ADD(quadColor[3], source[3], dest[3]); /* A */
+ break;
+ case PIPE_BLEND_SUBTRACT:
+ VEC4_SUB(quadColor[3], source[3], dest[3]); /* A */
+ break;
+ case PIPE_BLEND_REVERSE_SUBTRACT:
+ VEC4_SUB(quadColor[3], dest[3], source[3]); /* A */
+ break;
+ case PIPE_BLEND_MIN:
+ VEC4_MIN(quadColor[3], source[3], dest[3]); /* A */
+ break;
+ case PIPE_BLEND_MAX:
+ VEC4_MAX(quadColor[3], source[3], dest[3]); /* A */
+ break;
+ default:
+ assert(0);
}
- break;
- default:
- assert(0);
- }
-
- /*
- * Combine RGB terms
- */
- switch (softpipe->blend->rgb_func) {
- case PIPE_BLEND_ADD:
- VEC4_ADD(quadColor[0], source[0], dest[0]); /* R */
- VEC4_ADD(quadColor[1], source[1], dest[1]); /* G */
- VEC4_ADD(quadColor[2], source[2], dest[2]); /* B */
- break;
- case PIPE_BLEND_SUBTRACT:
- VEC4_SUB(quadColor[0], source[0], dest[0]); /* R */
- VEC4_SUB(quadColor[1], source[1], dest[1]); /* G */
- VEC4_SUB(quadColor[2], source[2], dest[2]); /* B */
- break;
- case PIPE_BLEND_REVERSE_SUBTRACT:
- VEC4_SUB(quadColor[0], dest[0], source[0]); /* R */
- VEC4_SUB(quadColor[1], dest[1], source[1]); /* G */
- VEC4_SUB(quadColor[2], dest[2], source[2]); /* B */
- break;
- case PIPE_BLEND_MIN:
- VEC4_MIN(quadColor[0], source[0], dest[0]); /* R */
- VEC4_MIN(quadColor[1], source[1], dest[1]); /* G */
- VEC4_MIN(quadColor[2], source[2], dest[2]); /* B */
- break;
- case PIPE_BLEND_MAX:
- VEC4_MAX(quadColor[0], source[0], dest[0]); /* R */
- VEC4_MAX(quadColor[1], source[1], dest[1]); /* G */
- VEC4_MAX(quadColor[2], source[2], dest[2]); /* B */
- break;
- default:
- assert(0);
- }
-
- /*
- * Combine A terms
- */
- switch (softpipe->blend->alpha_func) {
- case PIPE_BLEND_ADD:
- VEC4_ADD(quadColor[3], source[3], dest[3]); /* A */
- break;
- case PIPE_BLEND_SUBTRACT:
- VEC4_SUB(quadColor[3], source[3], dest[3]); /* A */
- break;
- case PIPE_BLEND_REVERSE_SUBTRACT:
- VEC4_SUB(quadColor[3], dest[3], source[3]); /* A */
- break;
- case PIPE_BLEND_MIN:
- VEC4_MIN(quadColor[3], source[3], dest[3]); /* A */
- break;
- case PIPE_BLEND_MAX:
- VEC4_MAX(quadColor[3], source[3], dest[3]); /* A */
- break;
- default:
- assert(0);
- }
-
+
+ } /* cbuf loop */
+
/* pass blended quad to next stage */
qs->next->run(qs->next, quad);
}
diff --git a/src/gallium/drivers/softpipe/sp_quad_bufloop.c b/src/gallium/drivers/softpipe/sp_quad_bufloop.c
index 2ae4e22a7d..b3db428ef1 100644
--- a/src/gallium/drivers/softpipe/sp_quad_bufloop.c
+++ b/src/gallium/drivers/softpipe/sp_quad_bufloop.c
@@ -13,7 +13,7 @@ static void
cbuf_loop_quad(struct quad_stage *qs, struct quad_header *quad)
{
struct softpipe_context *softpipe = qs->softpipe;
- float tmp[4][QUAD_SIZE];
+ float tmp[PIPE_MAX_COLOR_BUFS][4][QUAD_SIZE];
unsigned i;
assert(sizeof(quad->outputs.color) == sizeof(tmp));
@@ -30,7 +30,9 @@ cbuf_loop_quad(struct quad_stage *qs, struct quad_header *quad)
for (i = 0; i < softpipe->framebuffer.num_cbufs; i++) {
/* set current cbuffer */
+#if 0 /* obsolete & going away */
softpipe->current_cbuf = i;
+#endif
/* pass blended quad to next stage */
qs->next->run(qs->next, quad);
diff --git a/src/gallium/drivers/softpipe/sp_quad_colormask.c b/src/gallium/drivers/softpipe/sp_quad_colormask.c
index 1f09d900ca..7fe080990b 100644
--- a/src/gallium/drivers/softpipe/sp_quad_colormask.c
+++ b/src/gallium/drivers/softpipe/sp_quad_colormask.c
@@ -47,38 +47,43 @@ static void
colormask_quad(struct quad_stage *qs, struct quad_header *quad)
{
struct softpipe_context *softpipe = qs->softpipe;
- float dest[4][QUAD_SIZE];
- struct softpipe_cached_tile *tile
- = sp_get_cached_tile(softpipe,
- softpipe->cbuf_cache[softpipe->current_cbuf],
- quad->x0, quad->y0);
- float (*quadColor)[4] = quad->outputs.color;
- uint i, j;
-
- /* get/swizzle dest colors */
- for (j = 0; j < QUAD_SIZE; j++) {
- int x = (quad->x0 & (TILE_SIZE-1)) + (j & 1);
- int y = (quad->y0 & (TILE_SIZE-1)) + (j >> 1);
- for (i = 0; i < 4; i++) {
- dest[i][j] = tile->data.color[y][x][i];
+ uint cbuf;
+
+ /* loop over colorbuffer outputs */
+ for (cbuf = 0; cbuf < softpipe->framebuffer.num_cbufs; cbuf++) {
+ float dest[4][QUAD_SIZE];
+ struct softpipe_cached_tile *tile
+ = sp_get_cached_tile(softpipe,
+ softpipe->cbuf_cache[cbuf],
+ quad->x0, quad->y0);
+ float (*quadColor)[4] = quad->outputs.color[cbuf];
+ uint i, j;
+
+ /* get/swizzle dest colors */
+ for (j = 0; j < QUAD_SIZE; j++) {
+ int x = (quad->x0 & (TILE_SIZE-1)) + (j & 1);
+ int y = (quad->y0 & (TILE_SIZE-1)) + (j >> 1);
+ for (i = 0; i < 4; i++) {
+ dest[i][j] = tile->data.color[y][x][i];
+ }
}
- }
- /* R */
- if (!(softpipe->blend->colormask & PIPE_MASK_R))
- COPY_4V(quadColor[0], dest[0]);
+ /* R */
+ if (!(softpipe->blend->colormask & PIPE_MASK_R))
+ COPY_4V(quadColor[0], dest[0]);
- /* G */
- if (!(softpipe->blend->colormask & PIPE_MASK_G))
- COPY_4V(quadColor[1], dest[1]);
+ /* G */
+ if (!(softpipe->blend->colormask & PIPE_MASK_G))
+ COPY_4V(quadColor[1], dest[1]);
- /* B */
- if (!(softpipe->blend->colormask & PIPE_MASK_B))
- COPY_4V(quadColor[2], dest[2]);
+ /* B */
+ if (!(softpipe->blend->colormask & PIPE_MASK_B))
+ COPY_4V(quadColor[2], dest[2]);
- /* A */
- if (!(softpipe->blend->colormask & PIPE_MASK_A))
- COPY_4V(quadColor[3], dest[3]);
+ /* A */
+ if (!(softpipe->blend->colormask & PIPE_MASK_A))
+ COPY_4V(quadColor[3], dest[3]);
+ }
/* pass quad to next stage */
qs->next->run(qs->next, quad);
diff --git a/src/gallium/drivers/softpipe/sp_quad_coverage.c b/src/gallium/drivers/softpipe/sp_quad_coverage.c
index b3d3fae22f..dd5ebb2296 100644
--- a/src/gallium/drivers/softpipe/sp_quad_coverage.c
+++ b/src/gallium/drivers/softpipe/sp_quad_coverage.c
@@ -50,12 +50,17 @@ coverage_quad(struct quad_stage *qs, struct quad_header *quad)
if ((softpipe->rasterizer->poly_smooth && quad->prim == PRIM_TRI) ||
(softpipe->rasterizer->line_smooth && quad->prim == PRIM_LINE) ||
(softpipe->rasterizer->point_smooth && quad->prim == PRIM_POINT)) {
- float (*quadColor)[4] = quad->outputs.color;
- unsigned j;
- for (j = 0; j < QUAD_SIZE; j++) {
- assert(quad->coverage[j] >= 0.0);
- assert(quad->coverage[j] <= 1.0);
+ uint cbuf;
+
+ /* loop over colorbuffer outputs */
+ for (cbuf = 0; cbuf < softpipe->framebuffer.num_cbufs; cbuf++) {
+ float (*quadColor)[4] = quad->outputs.color[cbuf];
+ unsigned j;
+ for (j = 0; j < QUAD_SIZE; j++) {
+ assert(quad->coverage[j] >= 0.0);
+ assert(quad->coverage[j] <= 1.0);
quadColor[3][j] *= quad->coverage[j];
+ }
}
}
diff --git a/src/gallium/drivers/softpipe/sp_quad_fs.c b/src/gallium/drivers/softpipe/sp_quad_fs.c
index a73df31383..9a20c056a2 100644
--- a/src/gallium/drivers/softpipe/sp_quad_fs.c
+++ b/src/gallium/drivers/softpipe/sp_quad_fs.c
@@ -88,22 +88,64 @@ shade_quad(
&qss->machine,
quad );
- /* store result color */
+#if 0 /* XXX multi color outputs - untested */
+ /* store outputs */
+ boolean z_written = FALSE;
+ {
+ const ubyte *sem_name = softpipe->fs->info.output_semantic_name;
+ const ubyte *sem_index = softpipe->fs->info.output_semantic_index;
+ const uint n = qss->stage.softpipe->fs->info.num_outputs;
+ uint i;
+ for (i = 0; i < n; i++) {
+ switch (sem_name[i]) {
+ case TGSI_SEMANTIC_COLOR:
+ {
+ uint cbuf = sem_index[i];
+ memcpy(quad->outputs.color[cbuf],
+ &machine->Outputs[i].xyzw[0].f[0],
+ sizeof(quad->outputs.color[0]) );
+ }
+ break;
+ case TGSI_SEMANTIC_POSITION:
+ {
+ uint j;
+ for (j = 0; j < 4; j++) {
+ quad->outputs.depth[j] = machine->Outputs[0].xyzw[2].f[j];
+ }
+ z_written = TRUE;
+ }
+ break;
+ }
+ }
+ }
+
+ if (!z_written) {
+ /* compute Z values now, as in the quad earlyz stage */
+ /* XXX we should really only do this if the earlyz stage is not used */
+ const float fx = (float) quad->x0;
+ const float fy = (float) quad->y0;
+ const float dzdx = quad->posCoef->dadx[2];
+ const float dzdy = quad->posCoef->dady[2];
+ const float z0 = quad->posCoef->a0[2] + dzdx * fx + dzdy * fy;
+
+ quad->outputs.depth[0] = z0;
+ quad->outputs.depth[1] = z0 + dzdx;
+ quad->outputs.depth[2] = z0 + dzdy;
+ quad->outputs.depth[3] = z0 + dzdx + dzdy;
+ }
+#endif
+
+ /* store result color(s) */
if (qss->colorOutSlot >= 0) {
/* XXX need to handle multiple color outputs someday */
- assert(qss->stage.softpipe->fs->info.output_semantic_name[qss->colorOutSlot]
+ assert(softpipe->fs->info.output_semantic_name[qss->colorOutSlot]
== TGSI_SEMANTIC_COLOR);
memcpy(
- quad->outputs.color,
+ quad->outputs.color[0],
&machine->Outputs[qss->colorOutSlot].xyzw[0].f[0],
- sizeof( quad->outputs.color ) );
+ sizeof( quad->outputs.color[0] ) );
}
- /*
- * XXX the following code for updating quad->outputs.depth
- * isn't really needed if we did early z testing.
- */
-
/* store result Z */
if (qss->depthOutSlot >= 0) {
/* output[slot] is new Z */
diff --git a/src/gallium/drivers/softpipe/sp_quad_output.c b/src/gallium/drivers/softpipe/sp_quad_output.c
index cfe8f11808..40083138a4 100644
--- a/src/gallium/drivers/softpipe/sp_quad_output.c
+++ b/src/gallium/drivers/softpipe/sp_quad_output.c
@@ -34,31 +34,36 @@
/**
- * Write quad to framebuffer, taking mask into account.
- *
- * Note that surfaces support only full quad reads and writes.
+ * Last step of quad processing: write quad colors to the framebuffer,
+ * taking mask into account.
*/
static void
output_quad(struct quad_stage *qs, struct quad_header *quad)
{
- struct softpipe_context *softpipe = qs->softpipe;
- struct softpipe_cached_tile *tile
- = sp_get_cached_tile(softpipe,
- softpipe->cbuf_cache[softpipe->current_cbuf],
- quad->x0, quad->y0);
/* in-tile pos: */
const int itx = quad->x0 % TILE_SIZE;
const int ity = quad->y0 % TILE_SIZE;
- float (*quadColor)[4] = quad->outputs.color;
- int i, j;
- /* get/swizzle dest colors */
- for (j = 0; j < QUAD_SIZE; j++) {
- if (quad->mask & (1 << j)) {
- int x = itx + (j & 1);
- int y = ity + (j >> 1);
- for (i = 0; i < 4; i++) { /* loop over color chans */
- tile->data.color[y][x][i] = quadColor[i][j];
+ struct softpipe_context *softpipe = qs->softpipe;
+ uint cbuf;
+
+ /* loop over colorbuffer outputs */
+ for (cbuf = 0; cbuf < softpipe->framebuffer.num_cbufs; cbuf++) {
+ struct softpipe_cached_tile *tile
+ = sp_get_cached_tile(softpipe,
+ softpipe->cbuf_cache[cbuf],
+ quad->x0, quad->y0);
+ float (*quadColor)[4] = quad->outputs.color[cbuf];
+ int i, j;
+
+ /* get/swizzle dest colors */
+ for (j = 0; j < QUAD_SIZE; j++) {
+ if (quad->mask & (1 << j)) {
+ int x = itx + (j & 1);
+ int y = ity + (j >> 1);
+ for (i = 0; i < 4; i++) { /* loop over color chans */
+ tile->data.color[y][x][i] = quadColor[i][j];
+ }
}
}
}
diff --git a/src/gallium/drivers/softpipe/sp_state_vertex.c b/src/gallium/drivers/softpipe/sp_state_vertex.c
index e0230e16a4..46b6991195 100644
--- a/src/gallium/drivers/softpipe/sp_state_vertex.c
+++ b/src/gallium/drivers/softpipe/sp_state_vertex.c
@@ -47,6 +47,7 @@ softpipe_set_vertex_elements(struct pipe_context *pipe,
memcpy(softpipe->vertex_element, attribs,
count * sizeof(struct pipe_vertex_element));
+ softpipe->num_vertex_elements = count;
softpipe->dirty |= SP_NEW_VERTEX;
@@ -64,6 +65,7 @@ softpipe_set_vertex_buffers(struct pipe_context *pipe,
assert(count <= PIPE_MAX_ATTRIBS);
memcpy(softpipe->vertex_buffer, buffers, count * sizeof(buffers[0]));
+ softpipe->num_vertex_buffers = count;
softpipe->dirty |= SP_NEW_VERTEX;
diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h
index 324f70185a..f3a9c2cd8b 100644
--- a/src/gallium/include/pipe/p_context.h
+++ b/src/gallium/include/pipe/p_context.h
@@ -57,6 +57,14 @@ struct pipe_context {
void (*destroy)( struct pipe_context * );
+
+ /* Possible interface for setting edgeflags. These aren't really
+ * vertex elements, so don't fit there.
+ */
+ void (*set_edgeflags)( struct pipe_context *,
+ const unsigned *bitfield );
+
+
/**
* VBO drawing (return false on fallbacks (temporary??))
*/
diff --git a/src/gallium/include/pipe/p_debug.h b/src/gallium/include/pipe/p_debug.h
index 9e52ad9a37..235c47abac 100644
--- a/src/gallium/include/pipe/p_debug.h
+++ b/src/gallium/include/pipe/p_debug.h
@@ -304,11 +304,11 @@ void *
debug_realloc(const char *file, unsigned line, const char *function,
void *old_ptr, size_t old_size, size_t new_size );
-void
-debug_memory_reset(void);
+unsigned long
+debug_memory_begin(void);
void
-debug_memory_report(void);
+debug_memory_end(unsigned long beginning);
#ifdef __cplusplus
diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h
index 3593446e1c..2dc9a92186 100644
--- a/src/gallium/include/pipe/p_state.h
+++ b/src/gallium/include/pipe/p_state.h
@@ -181,7 +181,7 @@ struct pipe_depth_stencil_alpha_state
unsigned occlusion_count:1; /**< do occlusion counting? */
} depth;
struct {
- unsigned enabled:1;
+ unsigned enabled:1; /**< stencil[0]: stencil enabled, stencil[1]: two-side enabled */
unsigned func:3; /**< PIPE_FUNC_x */
unsigned fail_op:3; /**< PIPE_STENCIL_OP_x */
unsigned zpass_op:3; /**< PIPE_STENCIL_OP_x */
diff --git a/src/gallium/include/pipe/p_util.h b/src/gallium/include/pipe/p_util.h
index 1e7b8181f9..8e3aaee496 100644
--- a/src/gallium/include/pipe/p_util.h
+++ b/src/gallium/include/pipe/p_util.h
@@ -32,6 +32,7 @@
#include "p_debug.h"
#include "p_pointer.h"
#include <math.h>
+#include <stdarg.h>
#ifdef __cplusplus
@@ -137,6 +138,14 @@ REALLOC( void *old_ptr, unsigned old_size, unsigned new_size )
#define GETENV( X ) debug_get_option( X, NULL )
+#ifdef WIN32
+int rpl_vsnprintf(char *, size_t, const char *, va_list);
+int rpl_snprintf(char *str, size_t size, const char *format, ...);
+#define vsnprintf rpl_vsnprintf
+#define snprintf rpl_snprintf
+#endif
+
+
/**
* Return memory on given byte alignment
*/