summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Skeggs <[email protected]>2008-04-04 20:30:29 +1000
committerBen Skeggs <[email protected]>2008-04-04 20:30:29 +1000
commite902d9091c048531cf76b1d9d034fb865b1a0f6e (patch)
tree6594c42173c215b9b17ac904a7d05a1568d53d31
parentbc67533f29abe578e2306be2a24db392a0c62fc4 (diff)
parent7a7bce7b24ea4f63faa1d5bfe3f71d09b412c838 (diff)
Merge remote branch 'upstream/gallium-0.1' into nouveau-gallium-0.1
-rw-r--r--src/gallium/auxiliary/draw/Makefile1
-rw-r--r--src/gallium/auxiliary/draw/SConscript1
-rw-r--r--src/gallium/auxiliary/draw/draw_private.h6
-rw-r--r--src/gallium/auxiliary/draw/draw_pt.c26
-rw-r--r--src/gallium/auxiliary/draw/draw_pt.h7
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch_emit.c98
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c391
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_vcache.c17
-rw-r--r--src/gallium/auxiliary/draw/draw_vertex_fetch.c4
-rw-r--r--src/gallium/auxiliary/draw/draw_wide_point.c33
-rw-r--r--src/gallium/auxiliary/util/p_tile.c72
-rw-r--r--src/gallium/drivers/cell/spu/spu_main.c2
-rw-r--r--src/gallium/drivers/cell/spu/spu_main.h3
-rw-r--r--src/gallium/drivers/cell/spu/spu_texture.c50
-rw-r--r--src/gallium/include/pipe/p_state.h3
-rw-r--r--src/gallium/winsys/xlib/SConscript2
-rw-r--r--src/mesa/state_tracker/st_atom_constbuf.c13
-rw-r--r--src/mesa/state_tracker/st_atom_rasterizer.c6
-rw-r--r--src/mesa/state_tracker/st_cb_bitmap.c1
-rw-r--r--src/mesa/state_tracker/st_cb_clear.c86
-rw-r--r--src/mesa/state_tracker/st_cb_clear.h4
-rw-r--r--src/mesa/state_tracker/st_cb_drawpixels.c1
-rw-r--r--src/mesa/state_tracker/st_cb_readpixels.c3
-rw-r--r--src/mesa/state_tracker/st_context.c1
-rw-r--r--src/mesa/state_tracker/st_context.h2
-rw-r--r--src/mesa/state_tracker/st_extensions.c5
-rw-r--r--src/mesa/state_tracker/st_format.c25
27 files changed, 683 insertions, 180 deletions
diff --git a/src/gallium/auxiliary/draw/Makefile b/src/gallium/auxiliary/draw/Makefile
index a0db2e4555e..b28e516396e 100644
--- a/src/gallium/auxiliary/draw/Makefile
+++ b/src/gallium/auxiliary/draw/Makefile
@@ -18,6 +18,7 @@ C_SOURCES = \
draw_pt.c \
draw_pt_vcache.c \
draw_pt_fetch_emit.c \
+ draw_pt_fetch_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 981225a8c2c..9ca41974412 100644
--- a/src/gallium/auxiliary/draw/SConscript
+++ b/src/gallium/auxiliary/draw/SConscript
@@ -17,6 +17,7 @@ draw = env.ConvenienceLibrary(
'draw_pt.c',
'draw_pt_vcache.c',
'draw_pt_fetch_emit.c',
+ 'draw_pt_fetch_pipeline.c',
'draw_pt_elts.c',
'draw_prim.c',
'draw_pstipple.c',
diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h
index 9a9b25297f1..0c9f9c2e036 100644
--- a/src/gallium/auxiliary/draw/draw_private.h
+++ b/src/gallium/auxiliary/draw/draw_private.h
@@ -160,6 +160,11 @@ struct draw_vertex_shader {
/* Internal function for vertex fetch.
*/
typedef void (*fetch_func)(const void *ptr, float *attrib);
+
+fetch_func draw_get_fetch_func( enum pipe_format format );
+
+
+
typedef void (*full_fetch_func)( struct draw_context *draw,
struct tgsi_exec_machine *machine,
const unsigned *elts,
@@ -211,6 +216,7 @@ struct draw_context
struct {
struct draw_pt_middle_end *fetch_emit;
+ struct draw_pt_middle_end *fetch_pipeline;
struct draw_pt_middle_end *fetch_shade_emit;
struct draw_pt_middle_end *fetch_shade_cliptest_pipeline_or_emit;
} middle;
diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c
index 2ea96c686da..f59fb86f781 100644
--- a/src/gallium/auxiliary/draw/draw_pt.c
+++ b/src/gallium/auxiliary/draw/draw_pt.c
@@ -73,7 +73,6 @@ draw_pt_arrays(struct draw_context *draw,
*/
-#if 0
if (!cliptest && !pipeline && !shading) {
/* This is the 'passthrough' path:
*/
@@ -81,6 +80,14 @@ draw_pt_arrays(struct draw_context *draw,
*/
middle = draw->pt.middle.fetch_emit;
}
+ else if (!cliptest && !shading) {
+ /* This is the 'passthrough' path targetting the pipeline backend.
+ */
+ /* Fetch user verts, emit pipeline verts, run pipeline:
+ */
+ middle = draw->pt.middle.fetch_pipeline;
+ }
+#if 0
else if (!cliptest && !pipeline) {
/* Fetch user verts, run vertex shader, emit hw verts:
*/
@@ -117,10 +124,9 @@ draw_pt_arrays(struct draw_context *draw,
middle = draw->pt.middle.fetch_shade_cliptest_pipeline;
}
#else
- if (cliptest || pipeline || shading)
+ else {
return FALSE;
-
- middle = draw->pt.middle.fetch_emit;
+ }
#endif
@@ -171,10 +177,9 @@ draw_pt_arrays(struct draw_context *draw,
*/
draw_do_flush( draw, DRAW_FLUSH_BACKEND );
- frontend->prepare( frontend, middle );
+ frontend->prepare( frontend, prim, middle );
frontend->run( frontend,
- prim,
draw_pt_elt_func( draw ),
draw_pt_elt_ptr( draw, start ),
count );
@@ -191,6 +196,10 @@ boolean draw_pt_init( struct draw_context *draw )
if (!draw->pt.middle.fetch_emit)
return FALSE;
+ draw->pt.middle.fetch_pipeline = draw_pt_fetch_pipeline( draw );
+ if (!draw->pt.middle.fetch_pipeline)
+ return FALSE;
+
draw->pt.front.vcache = draw_pt_vcache( draw );
if (!draw->pt.front.vcache)
return FALSE;
@@ -206,6 +215,11 @@ void draw_pt_destroy( struct draw_context *draw )
draw->pt.middle.fetch_emit = NULL;
}
+ if (draw->pt.middle.fetch_pipeline) {
+ draw->pt.middle.fetch_pipeline->destroy( draw->pt.middle.fetch_pipeline );
+ draw->pt.middle.fetch_pipeline = NULL;
+ }
+
if (draw->pt.front.vcache) {
draw->pt.front.vcache->destroy( draw->pt.front.vcache );
draw->pt.front.vcache = NULL;
diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h
index f8786160799..800072c5115 100644
--- a/src/gallium/auxiliary/draw/draw_pt.h
+++ b/src/gallium/auxiliary/draw/draw_pt.h
@@ -53,10 +53,10 @@ struct draw_context;
*/
struct draw_pt_front_end {
void (*prepare)( struct draw_pt_front_end *,
+ unsigned prim,
struct draw_pt_middle_end * );
void (*run)( struct draw_pt_front_end *,
- unsigned prim,
pt_elt_func elt_func,
const void *elt_ptr,
unsigned count );
@@ -79,10 +79,10 @@ struct draw_pt_front_end {
* Currenly only using the passthrough version.
*/
struct draw_pt_middle_end {
- void (*prepare)( struct draw_pt_middle_end * );
+ void (*prepare)( struct draw_pt_middle_end *,
+ unsigned prim );
void (*run)( struct draw_pt_middle_end *,
- unsigned prim,
const unsigned *fetch_elts,
unsigned fetch_count,
const ushort *draw_elts,
@@ -112,6 +112,7 @@ const void *draw_pt_elt_ptr( struct draw_context *draw,
*/
struct draw_pt_front_end *draw_pt_vcache( struct draw_context *draw );
struct draw_pt_middle_end *draw_pt_fetch_emit( struct draw_context *draw );
+struct draw_pt_middle_end *draw_pt_fetch_pipeline( struct draw_context *draw );
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
index 9b098bc173f..39f0b40838f 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
@@ -85,45 +85,6 @@ struct fetch_emit_middle_end {
};
-static void fetch_B8G8R8A8_UNORM( const void *from,
- float *attrib )
-{
- ubyte *ub = (ubyte *) from;
- attrib[2] = UBYTE_TO_FLOAT(ub[0]);
- attrib[1] = UBYTE_TO_FLOAT(ub[1]);
- attrib[0] = UBYTE_TO_FLOAT(ub[2]);
- attrib[3] = UBYTE_TO_FLOAT(ub[3]);
-}
-
-static void fetch_R32G32B32A32_FLOAT( const void *from,
- float *attrib )
-{
- float *f = (float *) from;
- attrib[0] = f[0];
- attrib[1] = f[1];
- attrib[2] = f[2];
- attrib[3] = f[3];
-}
-
-static void fetch_R32G32B32_FLOAT( const void *from,
- float *attrib )
-{
- float *f = (float *) from;
- attrib[0] = f[0];
- attrib[1] = f[1];
- attrib[2] = f[2];
- attrib[3] = 1.0;
-}
-
-static void fetch_R32G32_FLOAT( const void *from,
- float *attrib )
-{
- float *f = (float *) from;
- attrib[0] = f[0];
- attrib[1] = f[1];
- attrib[2] = 0.0;
- attrib[3] = 1.0;
-}
static void fetch_R32_FLOAT( const void *from,
float *attrib )
@@ -203,16 +164,29 @@ fetch_store_general( struct fetch_emit_middle_end *feme,
-static void fetch_emit_prepare( struct draw_pt_middle_end *middle )
+static void fetch_emit_prepare( struct draw_pt_middle_end *middle,
+ unsigned prim )
{
static const float zero = 0;
struct fetch_emit_middle_end *feme = (struct fetch_emit_middle_end *)middle;
struct draw_context *draw = feme->draw;
- const struct vertex_info *vinfo = draw->render->get_vertex_info(draw->render);
- unsigned nr_attrs = vinfo->num_attribs;
+ const struct vertex_info *vinfo;
unsigned i;
+ boolean ok;
+
+
+ ok = draw->render->set_primitive( draw->render,
+ prim );
+ if (!ok) {
+ assert(0);
+ return;
+ }
+
+ /* Must do this after set_primitive() above:
+ */
+ vinfo = draw->render->get_vertex_info(draw->render);
- for (i = 0; i < nr_attrs; i++) {
+ for (i = 0; i < vinfo->num_attribs; i++) {
unsigned src_element = vinfo->src_index[i];
unsigned src_buffer = draw->vertex_element[src_element].vertex_buffer_index;
@@ -222,28 +196,9 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle )
feme->fetch[i].pitch = draw->vertex_buffer[src_buffer].pitch;
- switch (draw->vertex_element[src_element].src_format) {
- case PIPE_FORMAT_B8G8R8A8_UNORM:
- feme->fetch[i].fetch = fetch_B8G8R8A8_UNORM;
- break;
- case PIPE_FORMAT_R32G32B32A32_FLOAT:
- feme->fetch[i].fetch = fetch_R32G32B32A32_FLOAT;
- break;
- case PIPE_FORMAT_R32G32B32_FLOAT:
- feme->fetch[i].fetch = fetch_R32G32B32_FLOAT;
- break;
- case PIPE_FORMAT_R32G32_FLOAT:
- feme->fetch[i].fetch = fetch_R32G32_FLOAT;
- break;
- case PIPE_FORMAT_R32_FLOAT:
- feme->fetch[i].fetch = fetch_R32_FLOAT;
- break;
- default:
- assert(0);
- feme->fetch[i].fetch = NULL;
- break;
- }
-
+ feme->fetch[i].fetch = draw_get_fetch_func(draw->vertex_element[src_element].src_format);
+
+
switch (vinfo->emit[i]) {
case EMIT_4F:
feme->fetch[i].emit = emit_R32G32B32A32_FLOAT;
@@ -268,6 +223,7 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle )
feme->fetch[i].pitch = 0;
feme->fetch[i].fetch = fetch_R32_FLOAT;
feme->fetch[i].emit = emit_R32_FLOAT;
+ break;
default:
assert(0);
feme->fetch[i].emit = NULL;
@@ -275,7 +231,7 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle )
}
}
- feme->nr_fetch = nr_attrs;
+ feme->nr_fetch = vinfo->num_attribs;
feme->hw_vertex_size = vinfo->size * 4;
}
@@ -284,7 +240,6 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle )
static void fetch_emit_run( struct draw_pt_middle_end *middle,
- unsigned prim,
const unsigned *fetch_elts,
unsigned fetch_count,
const ushort *draw_elts,
@@ -293,16 +248,7 @@ static void fetch_emit_run( struct draw_pt_middle_end *middle,
struct fetch_emit_middle_end *feme = (struct fetch_emit_middle_end *)middle;
struct draw_context *draw = feme->draw;
void *hw_verts;
- boolean ok;
- ok = draw->render->set_primitive( draw->render,
- prim );
- if (!ok) {
- assert(0);
- return;
- }
-
-
hw_verts = draw->render->allocate_vertices( draw->render,
(ushort)feme->hw_vertex_size,
(ushort)fetch_count );
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c
new file mode 100644
index 00000000000..94e7d01be4b
--- /dev/null
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c
@@ -0,0 +1,391 @@
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+ /*
+ * Authors:
+ * Keith Whitwell <[email protected]>
+ */
+
+#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"
+
+/* The simplest 'middle end' in the new vertex code.
+ *
+ * The responsibilities of a middle end are to:
+ * - perform vertex fetch using
+ * - draw vertex element/buffer state
+ * - a list of fetch indices we received as an input
+ * - run the vertex shader
+ * - cliptest,
+ * - clip coord calculation
+ * - viewport transformation
+ * - if necessary, run the primitive pipeline, passing it:
+ * - a linear array of vertex_header vertices constructed here
+ * - a set of draw indices we received as an input
+ * - otherwise, drive the hw backend,
+ * - allocate space for hardware format vertices
+ * - translate the vertex-shader output vertices to hw format
+ * - calling the backend draw functions.
+ *
+ * For convenience, we provide a helper function to drive the hardware
+ * backend given similar inputs to those required to run the pipeline.
+ *
+ * In the case of passthrough mode, many of these actions are disabled
+ * or noops, so we end up doing:
+ *
+ * - perform vertex fetch
+ * - drive the hw backend
+ *
+ * IE, basically just vertex fetch to post-vs-format vertices,
+ * followed by a call to the backend helper function.
+ */
+
+
+struct fetch_pipeline_middle_end {
+ struct draw_pt_middle_end base;
+ struct draw_context *draw;
+
+ struct {
+ const ubyte *ptr;
+ unsigned pitch;
+ void (*fetch)( const void *from, float *attrib);
+ void (*emit)( const float *attrib, float **out );
+ } fetch[PIPE_MAX_ATTRIBS];
+
+ unsigned nr_fetch;
+ unsigned pipeline_vertex_size;
+ unsigned prim;
+};
+
+
+static void fetch_NULL( const void *from,
+ float *attrib )
+{
+}
+
+
+
+static void emit_R32_FLOAT( const float *attrib,
+ float **out )
+{
+ (*out)[0] = attrib[0];
+ (*out) += 1;
+}
+
+static void emit_R32G32_FLOAT( const float *attrib,
+ float **out )
+{
+ (*out)[0] = attrib[0];
+ (*out)[1] = attrib[1];
+ (*out) += 2;
+}
+
+static void emit_R32G32B32_FLOAT( const float *attrib,
+ float **out )
+{
+ (*out)[0] = attrib[0];
+ (*out)[1] = attrib[1];
+ (*out)[2] = attrib[2];
+ (*out) += 3;
+}
+
+static void emit_R32G32B32A32_FLOAT( const float *attrib,
+ float **out )
+{
+ (*out)[0] = attrib[0];
+ (*out)[1] = attrib[1];
+ (*out)[2] = attrib[2];
+ (*out)[3] = attrib[3];
+ (*out) += 4;
+}
+
+static void emit_header( const float *attrib,
+ float **out )
+{
+ (*out)[0] = 0;
+ (*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.
+ *
+ * XXX this is totally temporary.
+ */
+static void
+fetch_store_general( struct fetch_pipeline_middle_end *fpme,
+ void *out_ptr,
+ const unsigned *fetch_elts,
+ unsigned count )
+{
+ float *out = (float *)out_ptr;
+ uint i, j;
+
+ for (i = 0; i < count; i++) {
+ unsigned elt = fetch_elts[i];
+
+ for (j = 0; j < fpme->nr_fetch; j++) {
+ float attrib[4];
+ const ubyte *from = (fpme->fetch[j].ptr +
+ fpme->fetch[j].pitch * elt);
+
+ fpme->fetch[j].fetch( from, attrib );
+ fpme->fetch[j].emit( attrib, &out );
+ }
+ }
+}
+
+
+/* We aren't running a vertex shader, but are running the pipeline.
+ * That means the vertices we need to build look like:
+ *
+ * dw0: vertex header (zero?)
+ * dw1: clip coord 0
+ * dw2: clip coord 1
+ * dw3: clip coord 2
+ * dw4: clip coord 4
+ * dw5: screen coord 0
+ * dw6: screen coord 0
+ * dw7: screen coord 0
+ * dw8: screen coord 0
+ * dw9: other attribs...
+ *
+ */
+static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle,
+ unsigned prim )
+{
+ static const float zero = 0;
+ struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle;
+ struct draw_context *draw = fpme->draw;
+ unsigned i, nr = 0;
+
+ fpme->prim = prim;
+
+ /* 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++;
+ }
+
+
+ /* Need to look at vertex shader inputs (we know it is a
+ * passthrough shader, so these define the outputs too). If we
+ * were running a shader, we'd still be looking at the inputs at
+ * this point.
+ */
+ for (i = 0; i < draw->vertex_shader->info.num_inputs; i++) {
+ unsigned buf = draw->vertex_element[i].vertex_buffer_index;
+ enum pipe_format format = draw->vertex_element[i].src_format;
+
+ fpme->fetch[nr].ptr = ((const ubyte *) draw->user.vbuffer[buf] +
+ draw->vertex_buffer[buf].buffer_offset +
+ draw->vertex_element[i].src_offset);
+
+ fpme->fetch[nr].pitch = draw->vertex_buffer[buf].pitch;
+ fpme->fetch[nr].fetch = draw_get_fetch_func( format );
+
+ /* Always do this -- somewhat redundant...
+ */
+ fpme->fetch[nr].emit = emit_R32G32B32A32_FLOAT;
+ nr++;
+ }
+
+ 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;
+ }
+}
+
+
+
+
+static void fetch_pipeline_run( struct draw_pt_middle_end *middle,
+ const unsigned *fetch_elts,
+ unsigned fetch_count,
+ const ushort *draw_elts,
+ unsigned draw_count )
+{
+ struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle;
+ struct draw_context *draw = fpme->draw;
+ char *pipeline_verts;
+
+ pipeline_verts = MALLOC( fpme->pipeline_vertex_size *
+ fetch_count );
+ if (!pipeline_verts) {
+ assert(0);
+ return;
+ }
+
+
+ /* Single routine to fetch vertices and emit pipeline verts.
+ */
+ fetch_store_general( fpme,
+ pipeline_verts,
+ fetch_elts,
+ fetch_count );
+
+
+ run_pipeline( fpme,
+ pipeline_verts,
+ draw_elts,
+ draw_count );
+
+
+ /* Done -- that was easy, wasn't it:
+ */
+ FREE( pipeline_verts );
+}
+
+
+
+static void fetch_pipeline_finish( struct draw_pt_middle_end *middle )
+{
+ /* nothing to do */
+}
+
+static void fetch_pipeline_destroy( struct draw_pt_middle_end *middle )
+{
+ FREE(middle);
+}
+
+
+struct draw_pt_middle_end *draw_pt_fetch_pipeline( struct draw_context *draw )
+{
+ struct fetch_pipeline_middle_end *fetch_pipeline = CALLOC_STRUCT( fetch_pipeline_middle_end );
+
+ fetch_pipeline->base.prepare = fetch_pipeline_prepare;
+ fetch_pipeline->base.run = fetch_pipeline_run;
+ fetch_pipeline->base.finish = fetch_pipeline_finish;
+ fetch_pipeline->base.destroy = fetch_pipeline_destroy;
+
+ fetch_pipeline->draw = draw;
+
+ return &fetch_pipeline->base;
+}
+
diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache.c b/src/gallium/auxiliary/draw/draw_pt_vcache.c
index 16ffedf580c..5a068761df9 100644
--- a/src/gallium/auxiliary/draw/draw_pt_vcache.c
+++ b/src/gallium/auxiliary/draw/draw_pt_vcache.c
@@ -59,6 +59,8 @@ struct vcache_frontend {
const void *elt_ptr;
struct draw_pt_middle_end *middle;
+
+ unsigned input_prim;
unsigned output_prim;
};
@@ -77,7 +79,6 @@ static void vcache_flush( struct vcache_frontend *vcache )
if (vcache->draw_count) {
vcache->middle->run( vcache->middle,
- vcache->output_prim,
vcache->fetch_elts,
vcache->fetch_count,
vcache->draw_elts,
@@ -173,7 +174,6 @@ static unsigned reduced_prim[PIPE_PRIM_POLYGON + 1] = {
static void vcache_run_pv2( struct draw_pt_front_end *frontend,
- unsigned prim,
pt_elt_func get_elt,
const void *elts,
unsigned count )
@@ -185,9 +185,8 @@ static void vcache_run_pv2( struct draw_pt_front_end *frontend,
*/
vcache->elt_func = get_elt;
vcache->elt_ptr = elts;
- vcache->output_prim = reduced_prim[prim];
- switch (prim) {
+ switch (vcache->input_prim) {
case PIPE_PRIM_POINTS:
for (i = 0; i < count; i ++) {
vcache_point( vcache,
@@ -304,7 +303,6 @@ static void vcache_run_pv2( struct draw_pt_front_end *frontend,
static void vcache_run_pv0( struct draw_pt_front_end *frontend,
- unsigned prim,
pt_elt_func get_elt,
const void *elts,
unsigned count )
@@ -316,9 +314,8 @@ static void vcache_run_pv0( struct draw_pt_front_end *frontend,
*/
vcache->elt_func = get_elt;
vcache->elt_ptr = elts;
- vcache->output_prim = reduced_prim[prim];
- switch (prim) {
+ switch (vcache->input_prim) {
case PIPE_PRIM_POINTS:
for (i = 0; i < count; i ++) {
vcache_point( vcache,
@@ -389,6 +386,7 @@ static void vcache_run_pv0( struct draw_pt_front_end *frontend,
}
static void vcache_prepare( struct draw_pt_front_end *frontend,
+ unsigned prim,
struct draw_pt_middle_end *middle )
{
struct vcache_frontend *vcache = (struct vcache_frontend *)frontend;
@@ -398,8 +396,11 @@ static void vcache_prepare( struct draw_pt_front_end *frontend,
else
vcache->base.run = vcache_run_pv2;
+ vcache->input_prim = prim;
+ vcache->output_prim = reduced_prim[prim];
+
vcache->middle = middle;
- middle->prepare( middle );
+ middle->prepare( middle, vcache->output_prim );
}
diff --git a/src/gallium/auxiliary/draw/draw_vertex_fetch.c b/src/gallium/auxiliary/draw/draw_vertex_fetch.c
index 11f99babf65..9041041006e 100644
--- a/src/gallium/auxiliary/draw/draw_vertex_fetch.c
+++ b/src/gallium/auxiliary/draw/draw_vertex_fetch.c
@@ -166,7 +166,7 @@ fetch_B8G8R8A8_UNORM(const void *ptr, float *attrib)
}
-static fetch_func get_fetch_func( enum pipe_format format )
+fetch_func draw_get_fetch_func( enum pipe_format format )
{
#if 0
{
@@ -502,7 +502,7 @@ void draw_update_vertex_fetch( struct draw_context *draw )
draw->vertex_element[i].src_offset;
draw->vertex_fetch.pitch[i] = draw->vertex_buffer[buf].pitch;
- draw->vertex_fetch.fetch[i] = get_fetch_func( format );
+ draw->vertex_fetch.fetch[i] = draw_get_fetch_func( format );
}
draw->vertex_fetch.nr_attrs = nr_attrs;
diff --git a/src/gallium/auxiliary/draw/draw_wide_point.c b/src/gallium/auxiliary/draw/draw_wide_point.c
index c53f7e6cb37..6fc7c9fcd7a 100644
--- a/src/gallium/auxiliary/draw/draw_wide_point.c
+++ b/src/gallium/auxiliary/draw/draw_wide_point.c
@@ -38,6 +38,11 @@ struct widepoint_stage {
struct draw_stage stage;
float half_point_size;
+ float point_size_min;
+ float point_size_max;
+
+ float xbias;
+ float ybias;
uint texcoord_slot[PIPE_MAX_SHADER_OUTPUTS];
uint texcoord_mode[PIPE_MAX_SHADER_OUTPUTS];
@@ -124,20 +129,26 @@ static void widepoint_point( struct draw_stage *stage,
float *pos2 = v2->data[0];
float *pos3 = v3->data[0];
- const float xbias = 0.0, ybias = -0.125;
-
/* point size is either per-vertex or fixed size */
if (wide->psize_slot >= 0) {
- half_size = 0.5f * header->v[0]->data[wide->psize_slot][0];
+ half_size = header->v[0]->data[wide->psize_slot][0];
+
+ /* XXX: temporary -- do this in the vertex shader??
+ */
+ half_size = CLAMP(half_size,
+ wide->point_size_min,
+ wide->point_size_max);
+
+ half_size *= 0.5f;
}
else {
half_size = wide->half_point_size;
}
- left_adj = -half_size + xbias;
- right_adj = half_size + xbias;
- bot_adj = half_size + ybias;
- top_adj = -half_size + ybias;
+ left_adj = -half_size + wide->xbias;
+ right_adj = half_size + wide->xbias;
+ bot_adj = half_size + wide->ybias;
+ top_adj = -half_size + wide->ybias;
pos0[0] += left_adj;
pos0[1] += top_adj;
@@ -182,6 +193,14 @@ static void widepoint_first_point( struct draw_stage *stage,
struct draw_context *draw = stage->draw;
wide->half_point_size = 0.5f * draw->rasterizer->point_size;
+ wide->point_size_min = draw->rasterizer->point_size_min;
+ wide->point_size_max = draw->rasterizer->point_size_max;
+ wide->xbias = 0.0;
+ wide->ybias = 0.0;
+
+ if (draw->rasterizer->gl_rasterization_rules) {
+ wide->ybias = -0.125;
+ }
/* XXX we won't know the real size if it's computed by the vertex shader! */
if ((draw->rasterizer->point_size > draw->wide_point_threshold) ||
diff --git a/src/gallium/auxiliary/util/p_tile.c b/src/gallium/auxiliary/util/p_tile.c
index 287d7839812..520da5cecd5 100644
--- a/src/gallium/auxiliary/util/p_tile.c
+++ b/src/gallium/auxiliary/util/p_tile.c
@@ -560,6 +560,70 @@ z24s8_get_tile_rgba(unsigned *src,
}
+/*** PIPE_FORMAT_YCBCR / PIPE_FORMAT_YCBCR_REV ***/
+
+/**
+ * Convert YCbCr (or YCrCb) to RGBA.
+ */
+static void
+ycbcr_get_tile_rgba(ushort *src,
+ unsigned w, unsigned h,
+ float *p,
+ unsigned dst_stride,
+ boolean rev)
+{
+ const float scale = 1.0f / 255.0f;
+ unsigned i, j;
+
+ /* we're assuming we're being asked for an even number of texels */
+ assert((w & 1) == 0);
+
+ for (i = 0; i < h; i++) {
+ float *pRow = p;
+ /* do two texels at a time */
+ for (j = 0; j < w; j += 2, src += 2) {
+ const ushort t0 = src[0];
+ const ushort t1 = src[1];
+ const ubyte y0 = (t0 >> 8) & 0xff; /* luminance */
+ const ubyte y1 = (t1 >> 8) & 0xff; /* luminance */
+ ubyte cb, cr;
+ float r, g, b;
+
+ if (rev) {
+ cb = t1 & 0xff; /* chroma U */
+ cr = t0 & 0xff; /* chroma V */
+ }
+ else {
+ cb = t0 & 0xff; /* chroma U */
+ cr = t1 & 0xff; /* chroma V */
+ }
+
+ /* even pixel: y0,cr,cb */
+ r = 1.164f * (y0-16) + 1.596f * (cr-128);
+ g = 1.164f * (y0-16) - 0.813f * (cr-128) - 0.391f * (cb-128);
+ b = 1.164f * (y0-16) + 2.018f * (cb-128);
+ pRow[0] = r * scale;
+ pRow[1] = g * scale;
+ pRow[2] = b * scale;
+ pRow[3] = 1.0f;
+ pRow += 4;
+
+ /* odd pixel: use y1,cr,cb */
+ r = 1.164f * (y1-16) + 1.596f * (cr-128);
+ g = 1.164f * (y1-16) - 0.813f * (cr-128) - 0.391f * (cb-128);
+ b = 1.164f * (y1-16) + 2.018f * (cb-128);
+ pRow[0] = r * scale;
+ pRow[1] = g * scale;
+ pRow[2] = b * scale;
+ pRow[3] = 1.0f;
+ pRow += 4;
+
+ }
+ p += dst_stride;
+ }
+}
+
+
void
pipe_get_tile_rgba(struct pipe_context *pipe,
struct pipe_surface *ps,
@@ -622,6 +686,14 @@ pipe_get_tile_rgba(struct pipe_context *pipe,
case PIPE_FORMAT_Z24S8_UNORM:
z24s8_get_tile_rgba((unsigned *) packed, w, h, p, dst_stride);
break;
+ case PIPE_FORMAT_YCBCR:
+ assert((x & 1) == 0);
+ ycbcr_get_tile_rgba((ushort *) packed, w, h, p, dst_stride, FALSE);
+ break;
+ case PIPE_FORMAT_YCBCR_REV:
+ assert((x & 1) == 0);
+ ycbcr_get_tile_rgba((ushort *) packed, w, h, p, dst_stride, TRUE);
+ break;
default:
assert(0);
}
diff --git a/src/gallium/drivers/cell/spu/spu_main.c b/src/gallium/drivers/cell/spu/spu_main.c
index 1ab1c40379a..e04ffeb9b16 100644
--- a/src/gallium/drivers/cell/spu/spu_main.c
+++ b/src/gallium/drivers/cell/spu/spu_main.c
@@ -343,6 +343,8 @@ cmd_state_texture(const struct cell_command_texture *texture)
spu.texture[unit].width = width;
spu.texture[unit].height = height;
+ spu.texture[unit].tiles_per_row = width / TILE_SIZE;
+
spu.texture[unit].tex_size = (vector float) { width, height, 0.0, 0.0};
spu.texture[unit].tex_size_mask = (vector unsigned int)
{ width - 1, height - 1, 0, 0 };
diff --git a/src/gallium/drivers/cell/spu/spu_main.h b/src/gallium/drivers/cell/spu/spu_main.h
index e9e39cbeab3..e962e1426c6 100644
--- a/src/gallium/drivers/cell/spu/spu_main.h
+++ b/src/gallium/drivers/cell/spu/spu_main.h
@@ -105,7 +105,8 @@ struct spu_framebuffer {
struct spu_texture
{
void *start;
- uint width, height;
+ ushort width, height;
+ ushort tiles_per_row;
vector float tex_size;
vector unsigned int tex_size_mask; /**< == int(size - 1) */
vector unsigned int tex_size_x_mask; /**< == int(size - 1) */
diff --git a/src/gallium/drivers/cell/spu/spu_texture.c b/src/gallium/drivers/cell/spu/spu_texture.c
index ceab2469803..5051774f00c 100644
--- a/src/gallium/drivers/cell/spu/spu_texture.c
+++ b/src/gallium/drivers/cell/spu/spu_texture.c
@@ -48,25 +48,45 @@ invalidate_tex_cache(void)
}
+/**
+ * XXX look into getting texels for all four pixels in a quad at once.
+ */
static uint
get_texel(uint unit, vec_uint4 coordinate)
{
+ /*
+ * XXX we could do the "/ TILE_SIZE" and "% TILE_SIZE" operations as
+ * SIMD since X and Y are already in a SIMD register.
+ */
+ const unsigned texture_ea = (uintptr_t) spu.texture[unit].start;
+ ushort x = spu_extract(coordinate, 0);
+ ushort y = spu_extract(coordinate, 1);
+ unsigned tile_offset = sizeof(tile_t)
+ * ((y / TILE_SIZE * spu.texture[unit].tiles_per_row) + (x / TILE_SIZE));
+ ushort texel_offset = (ushort) 4
+ * (ushort) (((ushort) (y % TILE_SIZE) * (ushort) TILE_SIZE) + (x % TILE_SIZE));
vec_uint4 tmp;
- unsigned x = spu_extract(coordinate, 0);
- unsigned y = spu_extract(coordinate, 1);
- const unsigned tiles_per_row = spu.texture[unit].width / TILE_SIZE;
- unsigned tile_offset = sizeof(tile_t) * ((y / TILE_SIZE * tiles_per_row)
- + (x / TILE_SIZE));
- unsigned texel_offset = 4 * (((y % TILE_SIZE) * TILE_SIZE)
- + (x % TILE_SIZE));
spu_dcache_fetch_unaligned((qword *) & tmp,
- spu.texture[unit].start + tile_offset + texel_offset,
+ texture_ea + tile_offset + texel_offset,
4);
return spu_extract(tmp, 0);
}
+/**
+ * Get four texels from locations (x[0], y[0]), (x[1], y[1]) ...
+ *
+ * NOTE: in the typical case of bilinear filtering, the four texels
+ * are in a 2x2 group so we could get by with just two dcache fetches
+ * (two side-by-side texels per fetch). But when bilinear filtering
+ * wraps around a texture edge, we'll probably need code like we have
+ * now.
+ * FURTHERMORE: since we're rasterizing a quad of 2x2 pixels at a time,
+ * it's quite likely that the four pixels in a quad will need some of the
+ * same texels. So look into doing texture fetches for four pixels at
+ * a time.
+ */
static void
get_four_texels(uint unit, vec_uint4 x, vec_uint4 y, vec_uint4 *texels)
{
@@ -76,7 +96,7 @@ get_four_texels(uint unit, vec_uint4 x, vec_uint4 y, vec_uint4 *texels)
const qword offset_x = si_andi((qword) x, 0x1f);
const qword offset_y = si_andi((qword) y, 0x1f);
- const qword tiles_per_row = (qword) spu_splats(spu.texture[unit].width / TILE_SIZE);
+ const qword tiles_per_row = (qword) spu_splats(spu.texture[unit].tiles_per_row);
const qword tile_size = (qword) spu_splats(sizeof(tile_t));
qword tile_offset = si_mpya((qword) tile_y, tiles_per_row, (qword) tile_x);
@@ -97,9 +117,9 @@ get_four_texels(uint unit, vec_uint4 x, vec_uint4 y, vec_uint4 *texels)
texture_ea + spu_extract(offset, 3), 4);
}
+
/**
* Get texture sample at texcoord.
- * XXX this is extremely primitive for now.
*/
vector float
sample_texture_nearest(uint unit, vector float texcoord)
@@ -126,17 +146,25 @@ sample_texture_bilinear(uint unit, vector float texcoord)
vec_uint4 texels[4];
+ /* setup texcoords for quad:
+ * +-----+-----+
+ * |x0,y0|x1,y1|
+ * +-----+-----+
+ * |x2,y2|x3,y3|
+ * +-----+-----+
+ */
vec_uint4 x = spu_splats(spu_extract(itc, 0));
vec_uint4 y = spu_splats(spu_extract(itc, 1));
-
x = spu_add(x, offset_x);
y = spu_add(y, offset_y);
+ /* GL_REPEAT wrap mode: */
x = spu_and(x, spu.texture[unit].tex_size_x_mask);
y = spu_and(y, spu.texture[unit].tex_size_y_mask);
get_four_texels(unit, x, y, texels);
+ /* integer A8R8G8B8 to float texel conversion */
vector float texel00 = spu_unpack_A8R8G8B8(spu_extract(texels[0], 0));
vector float texel01 = spu_unpack_A8R8G8B8(spu_extract(texels[1], 0));
vector float texel10 = spu_unpack_A8R8G8B8(spu_extract(texels[2], 0));
diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h
index a73028814e3..3593446e1c4 100644
--- a/src/gallium/include/pipe/p_state.h
+++ b/src/gallium/include/pipe/p_state.h
@@ -115,9 +115,12 @@ struct pipe_rasterizer_state
still needed though, to indicate inputs/outputs */
unsigned origin_lower_left:1; /**< Is (0,0) the lower-left corner? */
unsigned flatshade_first:1; /**< take color attribute from the first vertex of a primitive */
+ unsigned gl_rasterization_rules:1; /**< enable tweaks for GL rasterization? */
float line_width;
float point_size; /**< used when no per-vertex size */
+ float point_size_min; /* XXX - temporary, will go away */
+ float point_size_max; /* XXX - temporary, will go away */
float offset_units;
float offset_scale;
ubyte sprite_coord_mode[PIPE_MAX_SHADER_OUTPUTS]; /**< PIPE_SPRITE_COORD_ */
diff --git a/src/gallium/winsys/xlib/SConscript b/src/gallium/winsys/xlib/SConscript
index c38b5be52c8..218b89285f7 100644
--- a/src/gallium/winsys/xlib/SConscript
+++ b/src/gallium/winsys/xlib/SConscript
@@ -22,8 +22,6 @@ sources = [
drivers = [
softpipe,
- i915simple,
- i965simple,
]
# TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions
diff --git a/src/mesa/state_tracker/st_atom_constbuf.c b/src/mesa/state_tracker/st_atom_constbuf.c
index cd7372902b8..03093579e15 100644
--- a/src/mesa/state_tracker/st_atom_constbuf.c
+++ b/src/mesa/state_tracker/st_atom_constbuf.c
@@ -71,13 +71,12 @@ void st_upload_constants( struct st_context *st,
_mesa_load_state_parameters(st->ctx, params);
- if (cbuf->buffer && cbuf->size != paramBytes)
- pipe_buffer_reference( ws, &cbuf->buffer, NULL );
-
- if (!cbuf->buffer) {
- cbuf->buffer = ws->buffer_create(ws, 1, PIPE_BUFFER_USAGE_CONSTANT,
- paramBytes);
- }
+ /* We always need to get a new buffer, to keep the drivers simple and
+ * avoid gratuitous rendering synchronization.
+ */
+ pipe_buffer_reference( ws, &cbuf->buffer, NULL );
+ cbuf->buffer = ws->buffer_create( ws, 1, PIPE_BUFFER_USAGE_CONSTANT,
+ paramBytes );
if (0)
{
diff --git a/src/mesa/state_tracker/st_atom_rasterizer.c b/src/mesa/state_tracker/st_atom_rasterizer.c
index 17d77f90aec..bb14cf9045a 100644
--- a/src/mesa/state_tracker/st_atom_rasterizer.c
+++ b/src/mesa/state_tracker/st_atom_rasterizer.c
@@ -198,6 +198,10 @@ static void update_raster_state( struct st_context *st )
/* _NEW_POINT
*/
raster->point_size = ctx->Point.Size;
+
+ raster->point_size_min = 0; /* temporary, will go away */
+ raster->point_size_max = 1000; /* temporary, will go away */
+
raster->point_smooth = ctx->Point.SmoothFlag;
raster->point_sprite = ctx->Point.PointSprite;
for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) {
@@ -257,6 +261,8 @@ static void update_raster_state( struct st_context *st )
if (ctx->Scissor.Enabled)
raster->scissor = 1;
+ raster->gl_rasterization_rules = 1;
+
cso_set_rasterizer(st->cso_context, raster);
}
diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c
index 975a55d6dc0..0872f2bd28a 100644
--- a/src/mesa/state_tracker/st_cb_bitmap.c
+++ b/src/mesa/state_tracker/st_cb_bitmap.c
@@ -754,6 +754,7 @@ st_init_bitmap(struct st_context *st)
/* init baseline rasterizer state once */
memset(&st->bitmap.rasterizer, 0, sizeof(st->bitmap.rasterizer));
+ st->bitmap.rasterizer.gl_rasterization_rules = 1;
st->bitmap.rasterizer.bypass_vs = 1;
init_bitmap_cache(st);
diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c
index ec8d3e10221..fa9f986f116 100644
--- a/src/mesa/state_tracker/st_cb_clear.c
+++ b/src/mesa/state_tracker/st_cb_clear.c
@@ -55,9 +55,41 @@
#include "cso_cache/cso_context.h"
-/* XXX for testing draw module vertex passthrough: */
-/* XXX this hack is broken now */
-#define TEST_DRAW_PASSTHROUGH 0
+void
+st_init_clear(struct st_context *st)
+{
+ struct pipe_context *pipe = st->pipe;
+
+ /* rasterizer state: bypass clipping */
+ memset(&st->clear.raster, 0, sizeof(st->clear.raster));
+ st->clear.raster.gl_rasterization_rules = 1;
+ st->clear.raster.bypass_clipping = 1;
+
+ /* viewport state: identity since we're drawing in window coords */
+ st->clear.viewport.scale[0] = 1.0;
+ st->clear.viewport.scale[1] = 1.0;
+ st->clear.viewport.scale[2] = 1.0;
+ st->clear.viewport.scale[3] = 1.0;
+ st->clear.viewport.translate[0] = 0.0;
+ st->clear.viewport.translate[1] = 0.0;
+ st->clear.viewport.translate[2] = 0.0;
+ st->clear.viewport.translate[3] = 0.0;
+
+ /* fragment shader state: color pass-through program */
+ st->clear.fs =
+ util_make_fragment_passthrough_shader(pipe, &st->clear.frag_shader);
+
+ /* vertex shader state: color/position pass-through */
+ {
+ const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
+ TGSI_SEMANTIC_COLOR };
+ const uint semantic_indexes[] = { 0, 0 };
+ st->clear.vs = util_make_vertex_passthrough_shader(pipe, 2,
+ semantic_names,
+ semantic_indexes,
+ &st->clear.vert_shader);
+ }
+}
void
@@ -238,55 +270,11 @@ clear_with_quad(GLcontext *ctx,
cso_set_depth_stencil_alpha(st->cso_context, &depth_stencil);
}
- /* rasterizer state: bypass clipping */
- {
- struct pipe_rasterizer_state raster;
- memset(&raster, 0, sizeof(raster));
- raster.bypass_clipping = 1;
-#if TEST_DRAW_PASSTHROUGH
- raster.bypass_vs = 1;
-#endif
- cso_set_rasterizer(st->cso_context, &raster);
- }
+ cso_set_rasterizer(st->cso_context, &st->clear.raster);
+ cso_set_viewport(st->cso_context, &st->clear.viewport);
- /* fragment shader state: color pass-through program */
- if (!st->clear.fs) {
- st->clear.fs = util_make_fragment_passthrough_shader(pipe, &st->clear.frag_shader);
- }
pipe->bind_fs_state(pipe, st->clear.fs);
-
-
-#if !TEST_DRAW_PASSTHROUGH
- /* vertex shader state: color/position pass-through */
- if (!st->clear.vs) {
- const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
- TGSI_SEMANTIC_COLOR };
- const uint semantic_indexes[] = { 0, 0 };
- st->clear.vs = util_make_vertex_passthrough_shader(pipe, 2,
- semantic_names,
- semantic_indexes,
- &st->clear.vert_shader);
- }
pipe->bind_vs_state(pipe, st->clear.vs);
-#endif
-
-#if !TEST_DRAW_PASSTHROUGH
- /* viewport state: viewport matching window dims */
- {
- const float width = ctx->DrawBuffer->Width;
- const float height = ctx->DrawBuffer->Height;
- struct pipe_viewport_state vp;
- vp.scale[0] = 0.5 * width;
- vp.scale[1] = -0.5 * height;
- vp.scale[2] = 1.0;
- vp.scale[3] = 1.0;
- vp.translate[0] = 0.5 * width;
- vp.translate[1] = 0.5 * height;
- vp.translate[2] = 0.0;
- vp.translate[3] = 0.0;
- cso_set_viewport(st->cso_context, &vp);
- }
-#endif
/* draw quad matching scissor rect (XXX verify coord round-off) */
draw_quad(ctx, x0, y0, x1, y1, ctx->Depth.Clear, ctx->Color.ClearColor);
diff --git a/src/mesa/state_tracker/st_cb_clear.h b/src/mesa/state_tracker/st_cb_clear.h
index dfa4033faa6..f49387747d6 100644
--- a/src/mesa/state_tracker/st_cb_clear.h
+++ b/src/mesa/state_tracker/st_cb_clear.h
@@ -31,6 +31,10 @@
extern void
+st_init_clear(struct st_context *st);
+
+
+extern void
st_destroy_clear(struct st_context *st);
diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c
index c181575f158..c7796cfb6aa 100644
--- a/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -536,6 +536,7 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
{
struct pipe_rasterizer_state rasterizer;
memset(&rasterizer, 0, sizeof(rasterizer));
+ rasterizer.gl_rasterization_rules = 1;
rasterizer.scissor = ctx->Scissor.Enabled;
cso_set_rasterizer(cso, &rasterizer);
}
diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c
index e9fcdf69a14..2bcc8c99fb7 100644
--- a/src/mesa/state_tracker/st_cb_readpixels.c
+++ b/src/mesa/state_tracker/st_cb_readpixels.c
@@ -43,6 +43,7 @@
#include "pipe/p_inlines.h"
#include "util/p_tile.h"
#include "st_context.h"
+#include "st_cb_bitmap.h"
#include "st_cb_readpixels.h"
#include "st_cb_fbo.h"
#include "st_format.h"
@@ -159,6 +160,8 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
if (!dest)
return;
+ st_flush_bitmap_cache(ctx->st);
+
/* make sure rendering has completed */
pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c
index a20195f2dea..7511c280740 100644
--- a/src/mesa/state_tracker/st_context.c
+++ b/src/mesa/state_tracker/st_context.c
@@ -110,6 +110,7 @@ st_create_context_priv( GLcontext *ctx, struct pipe_context *pipe )
st_init_atoms( st );
st_init_bitmap(st);
+ st_init_clear(st);
st_init_draw( st );
st_init_generate_mipmap(st);
st_init_blit(st);
diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h
index 44705bc89a3..bcebbd49436 100644
--- a/src/mesa/state_tracker/st_context.h
+++ b/src/mesa/state_tracker/st_context.h
@@ -161,6 +161,8 @@ struct st_context
struct {
struct pipe_shader_state vert_shader;
struct pipe_shader_state frag_shader;
+ struct pipe_rasterizer_state raster;
+ struct pipe_viewport_state viewport;
void *vs;
void *fs;
float vertices[4][2][4]; /**< vertex pos + color */
diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c
index 20f4652413d..47a50d40ca1 100644
--- a/src/mesa/state_tracker/st_extensions.c
+++ b/src/mesa/state_tracker/st_extensions.c
@@ -220,4 +220,9 @@ void st_init_extensions(struct st_context *st)
ctx->Extensions.EXT_texture_compression_s3tc = GL_TRUE;
}
+ if (screen->is_format_supported(screen, PIPE_FORMAT_YCBCR, PIPE_TEXTURE) ||
+ screen->is_format_supported(screen, PIPE_FORMAT_YCBCR_REV, PIPE_TEXTURE)) {
+ ctx->Extensions.MESA_ycbcr_texture = GL_TRUE;
+ }
+
}
diff --git a/src/mesa/state_tracker/st_format.c b/src/mesa/state_tracker/st_format.c
index cb6fa9a573d..761645c1057 100644
--- a/src/mesa/state_tracker/st_format.c
+++ b/src/mesa/state_tracker/st_format.c
@@ -189,15 +189,14 @@ st_get_format_info(enum pipe_format format, struct pipe_format_info *pinfo)
pinfo->base_format = GL_RGBA;
}
}
+ else if (pf_layout(format) == PIPE_FORMAT_LAYOUT_YCBCR) {
+ pinfo->base_format = GL_YCBCR_MESA;
+ pinfo->datatype = GL_UNSIGNED_SHORT;
+ pinfo->size = 2; /* two bytes per "texel" */
+ }
else {
- pipe_format_ycbcr_t info;
-
- assert( pf_layout(format) == PIPE_FORMAT_LAYOUT_YCBCR );
-
- info = format;
-
- /* TODO */
- assert( 0 );
+ /* compressed format? */
+ assert(0);
}
#if 0
@@ -275,6 +274,8 @@ st_mesa_format_to_pipe_format(GLuint mesaFormat)
return PIPE_FORMAT_Z32_UNORM;
case MESA_FORMAT_Z24_S8:
return PIPE_FORMAT_Z24S8_UNORM;
+ case MESA_FORMAT_YCBCR:
+ return PIPE_FORMAT_YCBCR;
default:
assert(0);
return 0;
@@ -435,6 +436,14 @@ choose_format(struct pipe_context *pipe, GLint internalFormat, uint surfType)
return default_rgba_format( screen, surfType );
case GL_YCBCR_MESA:
+ if (screen->is_format_supported(screen, PIPE_FORMAT_YCBCR,
+ PIPE_TEXTURE)) {
+ return PIPE_FORMAT_YCBCR;
+ }
+ if (screen->is_format_supported(screen, PIPE_FORMAT_YCBCR_REV,
+ PIPE_TEXTURE)) {
+ return PIPE_FORMAT_YCBCR_REV;
+ }
return PIPE_FORMAT_NONE;
case GL_RGB_S3TC: