summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/auxiliary/draw/draw_private.h13
-rw-r--r--src/gallium/auxiliary/draw/draw_pt.c182
-rw-r--r--src/gallium/auxiliary/draw/draw_pt.h6
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch_emit.c3
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c3
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c18
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_vcache.c5
7 files changed, 75 insertions, 155 deletions
diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h
index c8cb96c8ba0..8ac061cc9f8 100644
--- a/src/gallium/auxiliary/draw/draw_private.h
+++ b/src/gallium/auxiliary/draw/draw_private.h
@@ -182,6 +182,12 @@ typedef void (*pt_fetch_func)( struct draw_context *draw,
struct vbuf_render;
+
+#define PT_SHADE 0x1
+#define PT_CLIPTEST 0x2
+#define PT_PIPELINE 0x4
+#define PT_MAX_MIDDLE 0x8
+
/**
* Private context for the drawing module.
*/
@@ -219,15 +225,10 @@ struct draw_context
unsigned hw_vertex_size; /* XXX: to be removed */
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;
+ struct draw_pt_middle_end *opt[PT_MAX_MIDDLE];
} middle;
struct {
- struct draw_pt_front_end *noop;
- struct draw_pt_front_end *split_arrays;
struct draw_pt_front_end *vcache;
} front;
diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c
index 3d2e7bf7b82..895224c9527 100644
--- a/src/gallium/auxiliary/draw/draw_pt.c
+++ b/src/gallium/auxiliary/draw/draw_pt.c
@@ -36,146 +36,58 @@
#include "draw/draw_pt.h"
-#if 0
-static boolean too_many_elts( struct draw_context *draw,
- unsigned elts )
-{
- return elts > (8 * 1024);
-}
-#endif
-
-static INLINE unsigned reduced_prim(unsigned prim)
-{
- /*FIXME*/
- return prim;
-}
-static INLINE boolean good_prim(unsigned prim)
-{
- /*FIXME*/
- return FALSE;
-}
+/* Overall we split things into:
+ * - frontend -- prepare fetch_elts, draw_elts - eg vcache
+ * - middle -- fetch, shade, cliptest, viewport
+ * - pipeline -- the prim pipeline: clipping, wide lines, etc
+ * - backend -- the vbuf_render provided by the driver.
+ */
boolean
draw_pt_arrays(struct draw_context *draw,
unsigned prim,
unsigned start,
unsigned count)
{
- const boolean pipeline = draw_need_pipeline(draw, prim);
- const boolean cliptest = !draw->rasterizer->bypass_clipping;
- const boolean shading = !draw->rasterizer->bypass_vs;
struct draw_pt_front_end *frontend = NULL;
struct draw_pt_middle_end *middle = NULL;
+ unsigned opt = 0;
if (!draw->render)
return FALSE;
/*debug_printf("XXXXXXXXXX needs_pipeline = %d\n", pipeline);*/
- /* Overall we do:
- * - frontend -- prepare fetch_elts, draw_elts - eg vcache
- * - middle -- fetch, shade, cliptest, viewport
- * - pipeline -- the prim pipeline: clipping, wide lines, etc
- * - backend -- the vbuf_render provided by the driver.
- */
-
- if (shading && !draw->use_pt_shaders)
- return FALSE;
-
- if (!cliptest && !pipeline && !shading) {
- /* This is the 'passthrough' path:
- */
- /* Fetch user verts, emit hw verts:
- */
- 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;
- }
- else if (!cliptest && !pipeline) {
- /* Fetch user verts, run vertex shader, emit hw verts:
- */
- middle = draw->pt.middle.fetch_shade_emit;
- }
- else if (!pipeline) {
- /* Even though !pipeline, we have to run it to get clipping. We
- * do know that the pipeline is just the clipping operation, but
- * that probably doesn't help much.
- *
- * This is going to be the most important path for a lot of
- * swtnl cards.
- */
- /* Fetch user verts,
- * run vertex shader,
- * cliptest and viewport trasform
- * if no clipped vertices,
- * emit hw verts
- * else
- * run pipline
- */
- middle = draw->pt.middle.fetch_shade_cliptest_pipeline_or_emit;
- }
- else {
- /* This is what we're currently always doing:
- */
- /* Fetch user verts, run vertex shader, cliptest, run pipeline
- * or
- * Fetch user verts, run vertex shader, run pipeline
- */
- middle = draw->pt.middle.fetch_shade_cliptest_pipeline_or_emit;
+ if (draw_need_pipeline(draw, prim)) {
+ opt |= PT_PIPELINE;
}
+ if (!draw->rasterizer->bypass_clipping) {
+ opt |= PT_CLIPTEST;
+ }
- /* If !pipeline, need to make sure we respect the driver's limited
- * capabilites to receive blocks of vertex data and elements.
- */
-#if 0
- if (!pipeline) {
- unsigned vertex_mode = passthrough;
- unsigned nr_verts = count_vertices( draw, start, count );
- unsigned hw_prim = prim;
-
- if (is_elts(draw)) {
- frontend = draw->pt.front.vcache;
- hw_prim = reduced_prim(prim);
- }
-#if 0
- if (too_many_verts(nr_verts)) {
- /* if (is_verts(draw) && can_split(prim)) {
- draw = draw_arrays_split;
- }
- else */ {
- frontend = draw->pt.front.vcache;
- hw_prim = reduced_prim(prim);
- }
- }
-#endif
+ if (!draw->rasterizer->bypass_vs) {
+ opt |= PT_SHADE;
- if (too_many_elts(count)) {
+ if (!draw->use_pt_shaders)
+ return FALSE;
+ }
- /* if (is_elts(draw) && can_split(prim)) {
- draw = draw_elts_split;
- }
- else */ {
- frontend = draw->pt.front.vcache;
- hw_prim = reduced_prim(prim);
- }
- }
- if (!good_prim(hw_prim)) {
- frontend = draw->pt.front.vcache;
- }
+ if (draw->pt.middle.opt[opt] == NULL) {
+ opt = PT_PIPELINE | PT_CLIPTEST | PT_SHADE;
}
-#else
+
+ middle = draw->pt.middle.opt[opt];
+ assert(middle);
+
+ /* May create a short-circuited version of this for small primitives:
+ */
frontend = draw->pt.front.vcache;
-#endif
- frontend->prepare( frontend, prim, middle );
+
+ frontend->prepare( frontend, prim, middle, opt );
frontend->run( frontend,
draw_pt_elt_func( draw ),
@@ -190,21 +102,19 @@ draw_pt_arrays(struct draw_context *draw,
boolean draw_pt_init( struct draw_context *draw )
{
- draw->pt.middle.fetch_emit = draw_pt_fetch_emit( 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)
+ draw->pt.front.vcache = draw_pt_vcache( draw );
+ if (!draw->pt.front.vcache)
return FALSE;
- draw->pt.middle.fetch_shade_cliptest_pipeline_or_emit =
+ draw->pt.middle.opt[0] = draw_pt_fetch_emit( draw );
+ draw->pt.middle.opt[PT_PIPELINE] = draw_pt_fetch_pipeline( draw );
+// draw->pt.middle.opt[PT_SHADE] = draw_pt_shade_emit( draw );
+// draw->pt.middle.opt[PT_SHADE | PT_PIPELINE] = draw_pt_shade_pipeline( draw );
+// draw->pt.middle.opt[PT_SHADE | PT_CLIPTEST] = draw_pt_shade_clip_either( draw );
+ draw->pt.middle.opt[PT_SHADE | PT_CLIPTEST | PT_PIPELINE] =
draw_pt_fetch_pipeline_or_emit( draw );
- if (!draw->pt.middle.fetch_shade_cliptest_pipeline_or_emit)
- return FALSE;
- draw->pt.front.vcache = draw_pt_vcache( draw );
- if (!draw->pt.front.vcache)
+ if (!draw->pt.middle.opt[PT_SHADE | PT_CLIPTEST | PT_PIPELINE])
return FALSE;
return TRUE;
@@ -213,21 +123,13 @@ boolean draw_pt_init( struct draw_context *draw )
void draw_pt_destroy( struct draw_context *draw )
{
- if (draw->pt.middle.fetch_emit) {
- draw->pt.middle.fetch_emit->destroy( draw->pt.middle.fetch_emit );
- draw->pt.middle.fetch_emit = NULL;
- }
+ int i;
- 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.middle.fetch_shade_cliptest_pipeline_or_emit) {
- draw->pt.middle.fetch_shade_cliptest_pipeline_or_emit->destroy(
- draw->pt.middle.fetch_shade_cliptest_pipeline_or_emit );
- draw->pt.middle.fetch_shade_cliptest_pipeline_or_emit = NULL;
- }
+ for (i = 0; i < PT_MAX_MIDDLE; i++)
+ if (draw->pt.middle.opt[i]) {
+ draw->pt.middle.opt[i]->destroy( draw->pt.middle.opt[i] );
+ draw->pt.middle.opt[i] = NULL;
+ }
if (draw->pt.front.vcache) {
draw->pt.front.vcache->destroy( draw->pt.front.vcache );
diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h
index 48413b648a6..08afb606457 100644
--- a/src/gallium/auxiliary/draw/draw_pt.h
+++ b/src/gallium/auxiliary/draw/draw_pt.h
@@ -64,7 +64,8 @@ struct draw_context;
struct draw_pt_front_end {
void (*prepare)( struct draw_pt_front_end *,
unsigned prim,
- struct draw_pt_middle_end * );
+ struct draw_pt_middle_end *,
+ unsigned opt );
void (*run)( struct draw_pt_front_end *,
pt_elt_func elt_func,
@@ -90,7 +91,8 @@ struct draw_pt_front_end {
*/
struct draw_pt_middle_end {
void (*prepare)( struct draw_pt_middle_end *,
- unsigned prim );
+ unsigned prim,
+ unsigned opt );
void (*run)( struct draw_pt_middle_end *,
const unsigned *fetch_elts,
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
index 3a26a5d7123..1a9d331a065 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
@@ -164,7 +164,8 @@ fetch_store_general( struct fetch_emit_middle_end *feme,
static void fetch_emit_prepare( struct draw_pt_middle_end *middle,
- unsigned prim )
+ unsigned prim,
+ unsigned opt )
{
struct fetch_emit_middle_end *feme = (struct fetch_emit_middle_end *)middle;
struct draw_context *draw = feme->draw;
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c
index a70d129c93c..db6d6c76ea7 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_pipeline.c
@@ -209,7 +209,8 @@ fetch_store_general( struct fetch_pipeline_middle_end *fpme,
*
*/
static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle,
- unsigned prim )
+ unsigned prim,
+ unsigned opt )
{
struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle;
struct draw_context *draw = fpme->draw;
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
index 2d83e11940f..52be4a64aa6 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
@@ -42,11 +42,13 @@ struct fetch_pipeline_middle_end {
unsigned pipeline_vertex_size;
unsigned prim;
+ unsigned opt;
};
static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle,
- unsigned prim )
+ unsigned prim,
+ unsigned opt )
{
struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle;
struct draw_context *draw = fpme->draw;
@@ -57,6 +59,7 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle,
struct translate_key hw_key;
fpme->prim = prim;
+ fpme->opt = opt;
ok = draw->render->set_primitive(draw->render, prim);
if (!ok) {
@@ -157,6 +160,7 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle,
struct draw_context *draw = fpme->draw;
struct draw_vertex_shader *shader = draw->vertex_shader;
char *pipeline_verts;
+ unsigned pipeline = PT_PIPELINE;
pipeline_verts = MALLOC(fpme->pipeline_vertex_size *
fetch_count);
@@ -170,9 +174,17 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle,
/* Shade
*/
shader->prepare(shader, draw);
+
if (shader->run(shader, draw, fetch_elts, fetch_count, pipeline_verts,
- fpme->pipeline_vertex_size)) {
- /* Run the pipeline */
+ fpme->pipeline_vertex_size))
+ {
+ pipeline |= PT_CLIPTEST;
+ }
+
+
+ /* Do we need to run the pipeline?
+ */
+ if (fpme->opt & pipeline) {
draw_pt_run_pipeline( fpme->draw,
fpme->prim,
pipeline_verts,
diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache.c b/src/gallium/auxiliary/draw/draw_pt_vcache.c
index 107dcfc269c..5561f2b6fb4 100644
--- a/src/gallium/auxiliary/draw/draw_pt_vcache.c
+++ b/src/gallium/auxiliary/draw/draw_pt_vcache.c
@@ -448,7 +448,8 @@ static unsigned reduced_prim[PIPE_PRIM_POLYGON + 1] = {
static void vcache_prepare( struct draw_pt_front_end *frontend,
unsigned prim,
- struct draw_pt_middle_end *middle )
+ struct draw_pt_middle_end *middle,
+ unsigned opt )
{
struct vcache_frontend *vcache = (struct vcache_frontend *)frontend;
@@ -464,7 +465,7 @@ static void vcache_prepare( struct draw_pt_front_end *frontend,
vcache->output_prim = reduced_prim[prim];
vcache->middle = middle;
- middle->prepare( middle, vcache->output_prim );
+ middle->prepare( middle, vcache->output_prim, opt );
}