gallium: add PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION
authorChristoph Bumiller <e0425955@student.tuwien.ac.at>
Mon, 6 Feb 2012 15:29:03 +0000 (16:29 +0100)
committerChristoph Bumiller <e0425955@student.tuwien.ac.at>
Thu, 9 Feb 2012 14:01:34 +0000 (15:01 +0100)
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

19 files changed:
src/gallium/auxiliary/draw/draw_context.c
src/gallium/auxiliary/draw/draw_decompose_tmp.h
src/gallium/auxiliary/draw/draw_gs_tmp.h
src/gallium/auxiliary/draw/draw_private.h
src/gallium/auxiliary/draw/draw_pt_decompose.h
src/gallium/auxiliary/draw/draw_so_emit_tmp.h
src/gallium/docs/source/cso/rasterizer.rst
src/gallium/docs/source/screen.rst
src/gallium/drivers/i915/i915_screen.c
src/gallium/drivers/llvmpipe/lp_screen.c
src/gallium/drivers/nv50/nv50_screen.c
src/gallium/drivers/nvc0/nvc0_screen.c
src/gallium/drivers/nvfx/nvfx_screen.c
src/gallium/drivers/r300/r300_screen.c
src/gallium/drivers/r600/r600_pipe.c
src/gallium/drivers/softpipe/sp_screen.c
src/gallium/drivers/svga/svga_screen.c
src/gallium/include/pipe/p_defines.h
src/mesa/state_tracker/st_extensions.c

index 3c0b1aa39c9efde4abd7e8cfbb29d0524c211605..ad49ce733acf259fac4578e8f47b22a2d13486c3 100644 (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;
 }
 
index a142563af97155baf6056cc8e883f5f80f35be96..ee6877df99dc7d582ba837fd7d48005692385705 100644 (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]);
             }
          }
       }
index de7b02655a5101c26bddaea4ed880623f9559538..92b6fb75ea1a04d78d8f5d9116e3e66d499edf45 100644 (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);            \
index c3eca973e92fcfd6b6735c9b2dcc1a8922f81ace..9e6380341dadbaad77a461c1ffd62cb818d2481c 100644 (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 */
 
index 3127aad731024d01e6c6999aecc44d011d2cad04..8637085064a3c8bb6f219f8b2c6601c744e53988 100644 (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);
index 7fafde9d5e6605d5a2c5c78e2c11ec61a3325671..ec31c3ff32f73b0d55ae8bb9dbb36f99d027fca0 100644 (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);            \
index 482b1ea02c938d4800a7e4e05c10dd5bb9dc8b64..150e6df88ae36ed90301a1d7a0140c0bcb2cc99d 100644 (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.
index 2af9f74e902d8ab9f9952db979daff8c13818ac9..51d94649c2fe04361ff830a7a163c5670a395833 100644 (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``.
 
 
 
index aef0ed6980d0fd076ceafbc0cf5b87f6ce3adf59..a37241f5002995fa3cdaaa320cf9158c9d931b94 100644 (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). */
index fd6e439f6098b5f74c927ddd9c589486b121fd15..7f0f17ed784682638511ee9f292674e73404b797 100644 (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;
    }
index 904f39a358d850ed4502fa18884d545b25d155e4..1d5359327bc85247628999c5ba4eac386e87070f 100644 (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:
index 676af769834b72aeb7d896f51244af1703d11417..abc04ab7b8b6534618023c11229a85e7be41b8e0 100644 (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:
index ba1a2423d4bab63be9d1e4dc86008054d8b6d385..d47558e7a8633c8b77078647ce535f5f7610ca00 100644 (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);
index eb233a0b0be929f095604d3a66c34a54252da943..6b3b6c1cccfe02773fc4c0da453229371534f346 100644 (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. */
index 140ae11af9a60ea7fbf0af4cb337791e8cd2665a..bfb01f5d53288de4f0f55bc30d7f46e056318ec4 100644 (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. */
index 6d61d003975b97adae54e93ff808ac1bd696ffb6..5e50bfb292cdee4fbfccc46df118d0c98b085734 100644 (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;
    }
index 7359165621ef68138abb5ba7e9b7f8237459c20c..8d47e69006c583f03df9c984f283b0e282c8153d 100644 (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;
    }
index 88bd66c816a5ab4c43d3acd0aa4ece5cbbce3eb8..4155178dda4cf377bf6d945982d4859bc011166b 100644 (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
 };
 
 /**
index 443cb4bdfd185c3f0e87d9e77e6eff40c4733255..fb36a6809c026dd78c69ebc9bfd51081bc15fa62 100644 (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 =