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
This commit is contained in:
Christoph Bumiller
2012-02-06 16:29:03 +01:00
parent 26de5273ac
commit 8b4f7b0672
19 changed files with 52 additions and 16 deletions

View File

@@ -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;
}

View File

@@ -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]);
}
}
}

View File

@@ -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); \

View File

@@ -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 */

View File

@@ -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);

View File

@@ -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); \

View File

@@ -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.

View File

@@ -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``.

View File

@@ -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). */

View File

@@ -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;
}

View File

@@ -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:

View File

@@ -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:

View File

@@ -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);

View File

@@ -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. */

View File

@@ -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. */

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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
};
/**

View File

@@ -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 =