draw: don't run pipeline stages when gs has no position output
authorRoland Scheidegger <sroland@vmware.com>
Tue, 5 Aug 2014 23:07:18 +0000 (01:07 +0200)
committerRoland Scheidegger <sroland@vmware.com>
Wed, 6 Aug 2014 16:01:33 +0000 (18:01 +0200)
The clip stage may crash if there's no position output, for this reason
code was added to avoid running the pipeline stages in this case
(c7c7186045ec617c53f7899280cbe12e59503e4d). However, this failed to actually
work when there was a geometry shader, since unlike the vertex shader it did
not initialize the position output to -1, hence the code trying to detect
this didn't trigger. So simply initialize the position output to -1 just like
the vs does.
This fixes piglit glsl-1.50-transform-feedback-type-and-size (segfault->pass).
clip-distance-out-values.shader_test goes from segfault to assertion failure,
suggesting more fixes are needed, no other piglit changes.

Reviewed-by: Dave Airlie <airlied@redhat.com>
Reviewed-by: Zack Rusin <zackr@vmware.com>
src/gallium/auxiliary/draw/draw_cliptest_tmp.h
src/gallium/auxiliary/draw/draw_gs.c

index fc548102f2b894628715b4daf315f894cc3ef828..779b2374e2052330c78da1caf67df995a4d4484d 100644 (file)
@@ -62,6 +62,7 @@ static boolean TAG(do_cliptest)( struct pt_post_vs *pvs,
       ucp_enable = (1 << num_written_clipdistance) - 1;
    }
 
+   assert(pos != -1);
    for (j = 0; j < info->count; j++) {
       float *position = out->data[pos];
       unsigned mask = 0x0;
@@ -84,8 +85,10 @@ static boolean TAG(do_cliptest)( struct pt_post_vs *pvs,
                    DO_CLIP_FULL_Z | DO_CLIP_HALF_Z | DO_CLIP_USER)) {
          float *clipvertex = position;
 
-         if ((flags & DO_CLIP_USER) && cv != pos)
+         if ((flags & DO_CLIP_USER) && cv != pos) {
+            assert(cv != -1);
             clipvertex = out->data[cv];
+         }
 
          for (i = 0; i < 4; i++) {
             out->clip[i] = clipvertex[i];
index fc4f69792face64f243cd500997a23a0175ef61d..f6228229b47d2af4d5250e582e11c224f39a22dd 100644 (file)
@@ -791,6 +791,7 @@ draw_create_geometry_shader(struct draw_context *draw,
     */
    gs->primitive_boundary = gs->max_output_vertices + 1;
 
+   gs->position_output = -1;
    for (i = 0; i < gs->info.num_outputs; i++) {
       if (gs->info.output_semantic_name[i] == TGSI_SEMANTIC_POSITION &&
           gs->info.output_semantic_index[i] == 0)