mesa: fix transform feedback when a geometry shader is active.

When a geometry shader is active, the transform feedback primitive
type ("mode") needs to be validated against the geometry shader output
primitive type, not the primitive type passed to the glDraw*()
function.

Fixes the following piglit tests:
- glsl-1.50-geometry-primitive-types GL_LINES
- glsl-1.50-geometry-primitive-types GL_LINES_ADJACENCY
- glsl-1.50-geometry-primitive-types GL_LINE_STRIP
- glsl-1.50-geometry-primitive-types GL_LINE_STRIP_ADJACENCY
- glsl-1.50-geometry-primitive-types GL_TRIANGLES
- glsl-1.50-geometry-primitive-types GL_TRIANGLES_ADJACENCY
- glsl-1.50-geometry-primitive-types GL_TRIANGLE_FAN

Exposes previously hidden failures in the following piglit tests:
- glsl-1.50-geometry-primitive-id-restart GL_LINES other
- glsl-1.50-geometry-primitive-id-restart GL_LINES_ADJACENCY other
- glsl-1.50-geometry-primitive-id-restart GL_LINE_LOOP ffs
- glsl-1.50-geometry-primitive-id-restart GL_LINE_LOOP other
- glsl-1.50-geometry-primitive-id-restart GL_LINE_STRIP other
- glsl-1.50-geometry-primitive-id-restart GL_LINE_STRIP_ADJACENCY other
- glsl-1.50-geometry-primitive-id-restart GL_TRIANGLES other
- glsl-1.50-geometry-primitive-id-restart GL_TRIANGLES_ADJACENCY other
- glsl-1.50-geometry-primitive-id-restart GL_TRIANGLE_FAN ffs
- glsl-1.50-geometry-primitive-id-restart GL_TRIANGLE_FAN other
- glsl-1.50-geometry-primitive-id-restart GL_TRIANGLE_STRIP other
- glsl-1.50-geometry-primitive-id-restart GL_TRIANGLE_STRIP_ADJACENCY other

(These failures were previously hidden due to a flaw in the test: it
doesn't check for GL errors.  I'll fix the test shortly).

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
This commit is contained in:
Bryan Cain 2013-04-16 15:56:28 -05:00 committed by Paul Berry
parent afccf3d8e7
commit 467e3aa3de

View file

@ -330,26 +330,43 @@ _mesa_valid_prim_mode(struct gl_context *ctx, GLenum mode, const char *name)
if (_mesa_is_xfb_active_and_unpaused(ctx)) {
GLboolean pass = GL_TRUE;
switch (mode) {
case GL_POINTS:
pass = ctx->TransformFeedback.Mode == GL_POINTS;
break;
case GL_LINES:
case GL_LINE_STRIP:
case GL_LINE_LOOP:
pass = ctx->TransformFeedback.Mode == GL_LINES;
break;
default:
pass = ctx->TransformFeedback.Mode == GL_TRIANGLES;
break;
if(ctx->Shader.CurrentGeometryProgram) {
switch (ctx->Shader.CurrentGeometryProgram->Geom.OutputType) {
case GL_POINTS:
pass = ctx->TransformFeedback.Mode == GL_POINTS;
break;
case GL_LINE_STRIP:
pass = ctx->TransformFeedback.Mode == GL_LINES;
break;
case GL_TRIANGLE_STRIP:
pass = ctx->TransformFeedback.Mode == GL_TRIANGLES;
break;
default:
pass = GL_FALSE;
}
}
else {
switch (mode) {
case GL_POINTS:
pass = ctx->TransformFeedback.Mode == GL_POINTS;
break;
case GL_LINES:
case GL_LINE_STRIP:
case GL_LINE_LOOP:
pass = ctx->TransformFeedback.Mode == GL_LINES;
break;
default:
pass = ctx->TransformFeedback.Mode == GL_TRIANGLES;
break;
}
}
if (!pass) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"%s(mode=%s vs transform feedback %s)",
name,
_mesa_lookup_prim_by_nr(mode),
_mesa_lookup_prim_by_nr(ctx->TransformFeedback.Mode));
return GL_FALSE;
_mesa_error(ctx, GL_INVALID_OPERATION,
"%s(mode=%s vs transform feedback %s)",
name,
_mesa_lookup_prim_by_nr(mode),
_mesa_lookup_prim_by_nr(ctx->TransformFeedback.Mode));
return GL_FALSE;
}
}