summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristoph Bumiller <e0425955@student.tuwien.ac.at>2012-02-06 16:29:03 +0100
committerChristoph Bumiller <e0425955@student.tuwien.ac.at>2012-02-09 15:01:34 +0100
commit8b4f7b0672d663273310fffa9490ad996f5b914a (patch)
treef2ba67e7db09659b5a0062644cf46d297578a29a
parent26de5273acf1ebe6730b5e72b55b3bcceba167c6 (diff)
gallium: add PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION
Just let the hardware do it if it can and avoid drivers having to check for the special case on each draw call. v2: update the draw module
-rw-r--r--src/gallium/auxiliary/draw/draw_context.c7
-rw-r--r--src/gallium/auxiliary/draw/draw_decompose_tmp.h26
-rw-r--r--src/gallium/auxiliary/draw/draw_gs_tmp.h1
-rw-r--r--src/gallium/auxiliary/draw/draw_private.h2
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_decompose.h2
-rw-r--r--src/gallium/auxiliary/draw/draw_so_emit_tmp.h1
-rw-r--r--src/gallium/docs/source/cso/rasterizer.rst7
-rw-r--r--src/gallium/docs/source/screen.rst2
-rw-r--r--src/gallium/drivers/i915/i915_screen.c1
-rw-r--r--src/gallium/drivers/llvmpipe/lp_screen.c2
-rw-r--r--src/gallium/drivers/nv50/nv50_screen.c1
-rw-r--r--src/gallium/drivers/nvc0/nvc0_screen.c1
-rw-r--r--src/gallium/drivers/nvfx/nvfx_screen.c1
-rw-r--r--src/gallium/drivers/r300/r300_screen.c1
-rw-r--r--src/gallium/drivers/r600/r600_pipe.c1
-rw-r--r--src/gallium/drivers/softpipe/sp_screen.c2
-rw-r--r--src/gallium/drivers/svga/svga_screen.c3
-rw-r--r--src/gallium/include/pipe/p_defines.h3
-rw-r--r--src/mesa/state_tracker/st_extensions.c4
19 files changed, 52 insertions, 16 deletions
diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c
index 3c0b1aa39c9..ad49ce733ac 100644
--- a/src/gallium/auxiliary/draw/draw_context.c
+++ b/src/gallium/auxiliary/draw/draw_context.c
@@ -93,11 +93,11 @@ draw_create_context(struct pipe_context *pipe, boolean try_llvm,
}
#endif
+ draw->pipe = pipe;
+
if (!draw_init(draw))
goto err_destroy;
- draw->pipe = pipe;
-
return draw;
err_destroy:
@@ -168,6 +168,9 @@ boolean draw_init(struct draw_context *draw)
if (!draw_gs_init( draw ))
return FALSE;
+ draw->quads_always_flatshade_last = !draw->pipe->screen->get_param(
+ draw->pipe->screen, PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION);
+
return TRUE;
}
diff --git a/src/gallium/auxiliary/draw/draw_decompose_tmp.h b/src/gallium/auxiliary/draw/draw_decompose_tmp.h
index a142563af97..ee6877df99d 100644
--- a/src/gallium/auxiliary/draw/draw_decompose_tmp.h
+++ b/src/gallium/auxiliary/draw/draw_decompose_tmp.h
@@ -193,13 +193,18 @@ FUNC(FUNC_VARS)
flags = DRAW_PIPE_RESET_STIPPLE |
DRAW_PIPE_EDGE_FLAG_0 |
DRAW_PIPE_EDGE_FLAG_1;
- /* XXX should always emit idx[0] first */
- /* always emit idx[3] first */
- TRIANGLE(flags, idx[3], idx[0], idx[1]);
+ /* always emit idx[3] / idx[0] first */
+ if (quads_flatshade_last)
+ TRIANGLE(flags, idx[3], idx[0], idx[1]);
+ else
+ TRIANGLE(flags, idx[0], idx[1], idx[2]);
flags = DRAW_PIPE_EDGE_FLAG_1 |
DRAW_PIPE_EDGE_FLAG_2;
- TRIANGLE(flags, idx[3], idx[1], idx[2]);
+ if (quads_flatshade_last)
+ TRIANGLE(flags, idx[3], idx[1], idx[2]);
+ else
+ TRIANGLE(flags, idx[0], idx[2], idx[3]);
}
}
break;
@@ -237,13 +242,18 @@ FUNC(FUNC_VARS)
flags = DRAW_PIPE_RESET_STIPPLE |
DRAW_PIPE_EDGE_FLAG_0 |
DRAW_PIPE_EDGE_FLAG_1;
- /* XXX should always emit idx[0] first */
- /* always emit idx[3] first */
- TRIANGLE(flags, idx[3], idx[2], idx[0]);
+ /* always emit idx[3] / idx[0 first */
+ if (quads_flatshade_last)
+ TRIANGLE(flags, idx[3], idx[2], idx[0]);
+ else
+ TRIANGLE(flags, idx[0], idx[3], idx[2]);
flags = DRAW_PIPE_EDGE_FLAG_1 |
DRAW_PIPE_EDGE_FLAG_2;
- TRIANGLE(flags, idx[3], idx[0], idx[1]);
+ if (quads_flatshade_last)
+ TRIANGLE(flags, idx[3], idx[0], idx[1]);
+ else
+ TRIANGLE(flags, idx[0], idx[1], idx[3]);
}
}
}
diff --git a/src/gallium/auxiliary/draw/draw_gs_tmp.h b/src/gallium/auxiliary/draw/draw_gs_tmp.h
index de7b02655a5..92b6fb75ea1 100644
--- a/src/gallium/auxiliary/draw/draw_gs_tmp.h
+++ b/src/gallium/auxiliary/draw/draw_gs_tmp.h
@@ -9,6 +9,7 @@
const unsigned prim = input_prims->prim; \
const unsigned prim_flags = input_prims->flags; \
const unsigned count = input_prims->count; \
+ const boolean quads_flatshade_last = FALSE; \
const boolean last_vertex_last = TRUE; \
do { \
debug_assert(input_prims->primitive_count == 1); \
diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h
index c3eca973e92..9e6380341da 100644
--- a/src/gallium/auxiliary/draw/draw_private.h
+++ b/src/gallium/auxiliary/draw/draw_private.h
@@ -204,6 +204,8 @@ struct draw_context
boolean guard_band_xy;
} driver;
+ boolean quads_always_flatshade_last;
+
boolean flushing; /**< debugging/sanity */
boolean suspend_flushing; /**< internally set */
diff --git a/src/gallium/auxiliary/draw/draw_pt_decompose.h b/src/gallium/auxiliary/draw/draw_pt_decompose.h
index 3127aad7310..8637085064a 100644
--- a/src/gallium/auxiliary/draw/draw_pt_decompose.h
+++ b/src/gallium/auxiliary/draw/draw_pt_decompose.h
@@ -1,5 +1,7 @@
#define LOCAL_VARS \
char *verts = (char *) vertices; \
+ const boolean quads_flatshade_last = \
+ draw->quads_always_flatshade_last; \
const boolean last_vertex_last = \
!(draw->rasterizer->flatshade && \
draw->rasterizer->flatshade_first);
diff --git a/src/gallium/auxiliary/draw/draw_so_emit_tmp.h b/src/gallium/auxiliary/draw/draw_so_emit_tmp.h
index 7fafde9d5e6..ec31c3ff32f 100644
--- a/src/gallium/auxiliary/draw/draw_so_emit_tmp.h
+++ b/src/gallium/auxiliary/draw/draw_so_emit_tmp.h
@@ -9,6 +9,7 @@
/* declare more local vars */ \
const unsigned prim = input_prims->prim; \
const unsigned prim_flags = input_prims->flags; \
+ const boolean quads_flatshade_last = FALSE; \
const boolean last_vertex_last = TRUE; \
do { \
debug_assert(input_prims->primitive_count == 1); \
diff --git a/src/gallium/docs/source/cso/rasterizer.rst b/src/gallium/docs/source/cso/rasterizer.rst
index 482b1ea02c9..150e6df88ae 100644
--- a/src/gallium/docs/source/cso/rasterizer.rst
+++ b/src/gallium/docs/source/cso/rasterizer.rst
@@ -59,13 +59,14 @@ flatshade_first
Whether the first vertex should be the provoking vertex, for most primitives.
If not set, the last vertex is the provoking vertex.
-There are several important exceptions to the specification of this rule.
+There are a few important exceptions to the specification of this rule.
* ``PIPE_PRIMITIVE_POLYGON``: The provoking vertex is always the first
vertex. If the caller wishes to change the provoking vertex, they merely
need to rotate the vertices themselves.
-* ``PIPE_PRIMITIVE_QUAD``, ``PIPE_PRIMITIVE_QUAD_STRIP``: This option has no
- effect; the provoking vertex is always the last vertex.
+* ``PIPE_PRIMITIVE_QUAD``, ``PIPE_PRIMITIVE_QUAD_STRIP``: The option only has
+ an effect if ``PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION`` is true.
+ If it is not, the provoking vertex is always the last vertex.
* ``PIPE_PRIMITIVE_TRIANGLE_FAN``: When set, the provoking vertex is the
second vertex, not the first. This permits each segment of the fan to have
a different color.
diff --git a/src/gallium/docs/source/screen.rst b/src/gallium/docs/source/screen.rst
index 2af9f74e902..51d94649c2f 100644
--- a/src/gallium/docs/source/screen.rst
+++ b/src/gallium/docs/source/screen.rst
@@ -96,6 +96,8 @@ The integer capabilities:
controlled through pipe_rasterizer_state.
* ``PIPE_CAP_GLSL_FEATURE_LEVEL``: Whether the driver supports features
equivalent to a specific GLSL version. E.g. for GLSL 1.3, report 130.
+* ``PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION``: Whether quads adhere to
+ the flatshade_first setting in ``pipe_rasterizer_state``.
diff --git a/src/gallium/drivers/i915/i915_screen.c b/src/gallium/drivers/i915/i915_screen.c
index aef0ed6980d..a37241f5002 100644
--- a/src/gallium/drivers/i915/i915_screen.c
+++ b/src/gallium/drivers/i915/i915_screen.c
@@ -204,6 +204,7 @@ i915_get_param(struct pipe_screen *screen, enum pipe_cap cap)
case PIPE_CAP_TGSI_CAN_COMPACT_VARYINGS:
case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
+ case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
return 0;
/* Features we can lie about (boolean caps). */
diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c
index fd6e439f609..7f0f17ed784 100644
--- a/src/gallium/drivers/llvmpipe/lp_screen.c
+++ b/src/gallium/drivers/llvmpipe/lp_screen.c
@@ -157,6 +157,8 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
case PIPE_CAP_CONDITIONAL_RENDER:
return 1;
+ case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
+ return 0;
default:
return 0;
}
diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c
index 904f39a358d..1d5359327bc 100644
--- a/src/gallium/drivers/nv50/nv50_screen.c
+++ b/src/gallium/drivers/nv50/nv50_screen.c
@@ -146,6 +146,7 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
case PIPE_CAP_CONDITIONAL_RENDER:
case PIPE_CAP_TEXTURE_BARRIER:
+ case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
return 1;
case PIPE_CAP_TGSI_CAN_COMPACT_VARYINGS:
case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
diff --git a/src/gallium/drivers/nvc0/nvc0_screen.c b/src/gallium/drivers/nvc0/nvc0_screen.c
index 676af769834..abc04ab7b8b 100644
--- a/src/gallium/drivers/nvc0/nvc0_screen.c
+++ b/src/gallium/drivers/nvc0/nvc0_screen.c
@@ -132,6 +132,7 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
case PIPE_CAP_CONDITIONAL_RENDER:
case PIPE_CAP_TEXTURE_BARRIER:
+ case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
return 1;
case PIPE_CAP_TGSI_CAN_COMPACT_VARYINGS:
case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
diff --git a/src/gallium/drivers/nvfx/nvfx_screen.c b/src/gallium/drivers/nvfx/nvfx_screen.c
index ba1a2423d4b..d47558e7a86 100644
--- a/src/gallium/drivers/nvfx/nvfx_screen.c
+++ b/src/gallium/drivers/nvfx/nvfx_screen.c
@@ -98,6 +98,7 @@ nvfx_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
case PIPE_CAP_TGSI_CAN_COMPACT_VARYINGS:
case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
+ case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
return 0;
default:
NOUVEAU_ERR("Warning: unknown PIPE_CAP %d\n", param);
diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c
index eb233a0b0be..6b3b6c1cccf 100644
--- a/src/gallium/drivers/r300/r300_screen.c
+++ b/src/gallium/drivers/r300/r300_screen.c
@@ -140,6 +140,7 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
+ case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
return 0;
/* SWTCL-only features. */
diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c
index 140ae11af9a..bfb01f5d532 100644
--- a/src/gallium/drivers/r600/r600_pipe.c
+++ b/src/gallium/drivers/r600/r600_pipe.c
@@ -391,6 +391,7 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
case PIPE_CAP_VERTEX_COLOR_CLAMPED:
+ case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
return 0;
/* Stream output. */
diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c
index 6d61d003975..5e50bfb292c 100644
--- a/src/gallium/drivers/softpipe/sp_screen.c
+++ b/src/gallium/drivers/softpipe/sp_screen.c
@@ -134,6 +134,8 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
return 1;
case PIPE_CAP_GLSL_FEATURE_LEVEL:
return 130;
+ case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
+ return 0;
default:
return 0;
}
diff --git a/src/gallium/drivers/svga/svga_screen.c b/src/gallium/drivers/svga/svga_screen.c
index 7359165621e..8d47e69006c 100644
--- a/src/gallium/drivers/svga/svga_screen.c
+++ b/src/gallium/drivers/svga/svga_screen.c
@@ -203,6 +203,9 @@ svga_get_param(struct pipe_screen *screen, enum pipe_cap param)
case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
return 0;
+ case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
+ return 0;
+
default:
return 0;
}
diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h
index 88bd66c816a..4155178dda4 100644
--- a/src/gallium/include/pipe/p_defines.h
+++ b/src/gallium/include/pipe/p_defines.h
@@ -488,7 +488,8 @@ enum pipe_cap {
PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS = 59, /* temporary */
PIPE_CAP_VERTEX_COLOR_UNCLAMPED = 60,
PIPE_CAP_VERTEX_COLOR_CLAMPED = 61,
- PIPE_CAP_GLSL_FEATURE_LEVEL = 62
+ PIPE_CAP_GLSL_FEATURE_LEVEL = 62,
+ PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION = 63
};
/**
diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c
index 443cb4bdfd1..fb36a6809c0 100644
--- a/src/mesa/state_tracker/st_extensions.c
+++ b/src/mesa/state_tracker/st_extensions.c
@@ -146,8 +146,8 @@ void st_init_limits(struct st_context *st)
= CLAMP(screen->get_param(screen, PIPE_CAP_MAX_RENDER_TARGETS),
1, MAX_DRAW_BUFFERS);
- /* Quads always follow GL provoking rules. */
- c->QuadsFollowProvokingVertexConvention = GL_FALSE;
+ c->QuadsFollowProvokingVertexConvention = screen->get_param(
+ screen, PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION);
for (sh = 0; sh < MESA_SHADER_TYPES; ++sh) {
struct gl_shader_compiler_options *options =