intel: Add support for EXT_provoking_vertex.
authorEric Anholt <eric@anholt.net>
Tue, 4 Aug 2009 18:28:26 +0000 (11:28 -0700)
committerEric Anholt <eric@anholt.net>
Tue, 4 Aug 2009 22:32:18 +0000 (15:32 -0700)
src/mesa/drivers/dri/i915/i830_context.h
src/mesa/drivers/dri/i915/i830_reg.h
src/mesa/drivers/dri/i915/i830_state.c
src/mesa/drivers/dri/i915/i830_vtbl.c
src/mesa/drivers/dri/i915/i915_context.c
src/mesa/drivers/dri/i915/i915_context.h
src/mesa/drivers/dri/i915/i915_reg.h
src/mesa/drivers/dri/i915/i915_state.c
src/mesa/drivers/dri/i915/i915_vtbl.c
src/mesa/drivers/dri/i965/brw_sf_state.c
src/mesa/drivers/dri/intel/intel_extensions.c

index 1bdb32049d7fc235c968915828b2ce802763b93b..f73cbbf88bb9e7dd70f7a9a943154c8326648096 100644 (file)
@@ -40,6 +40,7 @@
 #define I830_UPLOAD_BUFFERS          0x2
 #define I830_UPLOAD_STIPPLE          0x4
 #define I830_UPLOAD_INVARIENT        0x8
+#define I830_UPLOAD_RASTER_RULES     0x10
 #define I830_UPLOAD_TEX(i)           (0x10<<(i))
 #define I830_UPLOAD_TEXBLEND(i)      (0x100<<(i))
 #define I830_UPLOAD_TEX_ALL          (0x0f0)
 
 #define I830_TEXBLEND_SIZE     12      /* (4 args + op) * 2 + COLOR_FACTOR */
 
+enum {
+   I830_RASTER_RULES,
+   I830_RASTER_RULES_SIZE
+};
+
 struct i830_texture_object
 {
    struct intel_texture_object intel;
@@ -112,6 +118,7 @@ struct i830_hw_state
    GLuint Ctx[I830_CTX_SETUP_SIZE];
    GLuint Buffer[I830_DEST_SETUP_SIZE];
    GLuint Stipple[I830_STP_SETUP_SIZE];
+   GLuint RasterRules[I830_RASTER_RULES_SIZE];
    GLuint Tex[I830_TEX_UNITS][I830_TEX_SETUP_SIZE];
    GLuint TexBlend[I830_TEX_UNITS][I830_TEXBLEND_SIZE];
    GLuint TexBlendWordsUsed[I830_TEX_UNITS];
@@ -197,6 +204,7 @@ extern void i830InitStateFuncs(struct dd_function_table *functions);
 extern void i830EmitState(struct i830_context *i830);
 
 extern void i830InitState(struct i830_context *i830);
+extern void i830_update_provoking_vertex(GLcontext *ctx);
 
 /* i830_metaops.c
  */
index db16871001d93571d416ca9b828f0c226b0c50aa..ae1317029a23c455818f82d9e84456c62bb9d3b9 100644 (file)
 #define ENABLE_LINE_STRIP_PROVOKE_VRTX (1<<8)
 #define ENABLE_TRI_FAN_PROVOKE_VRTX    (1<<5)
 #define ENABLE_TRI_STRIP_PROVOKE_VRTX  (1<<2)
+#define LINE_STRIP_PROVOKE_VRTX_MASK   (3<<6)
 #define LINE_STRIP_PROVOKE_VRTX(x)     ((x)<<6)
+#define TRI_FAN_PROVOKE_VRTX_MASK      (3<<3)
 #define TRI_FAN_PROVOKE_VRTX(x)        ((x)<<3)
+#define TRI_STRIP_PROVOKE_VRTX_MASK    (3<<0)
 #define TRI_STRIP_PROVOKE_VRTX(x)      (x)
 
 /* _3DSTATE_SCISSOR_ENABLE, p200 */
index 8ef6c9144f168fa5d0ab1bd6dd9eccf58128ab47..645ebe305774410b90153bf7a31ceca0fa9ae888 100644 (file)
@@ -1047,6 +1047,16 @@ i830_init_packets(struct i830_context *i830)
                                          TEXBIND_SET1(TEXCOORDSRC_VTXSET_1) |
                                          TEXBIND_SET0(TEXCOORDSRC_VTXSET_0));
 
+   i830->state.RasterRules[I830_RASTER_RULES] = (_3DSTATE_RASTER_RULES_CMD |
+                                                ENABLE_POINT_RASTER_RULE |
+                                                OGL_POINT_RASTER_RULE |
+                                                ENABLE_LINE_STRIP_PROVOKE_VRTX |
+                                                ENABLE_TRI_FAN_PROVOKE_VRTX |
+                                                ENABLE_TRI_STRIP_PROVOKE_VRTX |
+                                                LINE_STRIP_PROVOKE_VRTX(1) |
+                                                TRI_FAN_PROVOKE_VRTX(2) |
+                                                TRI_STRIP_PROVOKE_VRTX(2));
+
 
    i830->state.Stipple[I830_STPREG_ST0] = _3DSTATE_STIPPLE;
 
@@ -1058,6 +1068,27 @@ i830_init_packets(struct i830_context *i830)
    i830->state.Buffer[I830_DESTREG_SR2] = 0;
 }
 
+void
+i830_update_provoking_vertex(GLcontext * ctx)
+{
+   struct i830_context *i830 = i830_context(ctx);
+
+   I830_STATECHANGE(i830, I830_UPLOAD_RASTER_RULES);
+   i830->state.RasterRules[I830_RASTER_RULES] &= ~(LINE_STRIP_PROVOKE_VRTX_MASK |
+                                                  TRI_FAN_PROVOKE_VRTX_MASK |
+                                                  TRI_STRIP_PROVOKE_VRTX_MASK);
+
+   /* _NEW_LIGHT */
+   if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION) {
+      i830->state.RasterRules[I830_RASTER_RULES] |= (LINE_STRIP_PROVOKE_VRTX(1) |
+                                                    TRI_FAN_PROVOKE_VRTX(2) |
+                                                    TRI_STRIP_PROVOKE_VRTX(2));
+   } else {
+      i830->state.RasterRules[I830_RASTER_RULES] |= (LINE_STRIP_PROVOKE_VRTX(0) |
+                                                    TRI_FAN_PROVOKE_VRTX(1) |
+                                                    TRI_STRIP_PROVOKE_VRTX(0));
+    }
+}
 
 void
 i830InitStateFuncs(struct dd_function_table *functions)
@@ -1101,6 +1132,7 @@ i830InitState(struct i830_context *i830)
    i830->current = &i830->state;
    i830->state.emitted = 0;
    i830->state.active = (I830_UPLOAD_INVARIENT |
+                         I830_UPLOAD_RASTER_RULES |
                          I830_UPLOAD_TEXBLEND(0) |
                          I830_UPLOAD_STIPPLE |
                          I830_UPLOAD_CTX | I830_UPLOAD_BUFFERS);
index 9c6f891dd320f45aead1f9cf74056040696c465f..983f6724c98a0885889cc767e011fcd2920a4774 100644 (file)
@@ -299,7 +299,7 @@ i830_emit_invarient_state(struct intel_context *intel)
 {
    BATCH_LOCALS;
 
-   BEGIN_BATCH(30, IGNORE_CLIPRECTS);
+   BEGIN_BATCH(29, IGNORE_CLIPRECTS);
 
    OUT_BATCH(_3DSTATE_DFLT_DIFFUSE_CMD);
    OUT_BATCH(0);
@@ -351,15 +351,6 @@ i830_emit_invarient_state(struct intel_context *intel)
    OUT_BATCH(_3DSTATE_MAP_COORD_TRANSFORM);
    OUT_BATCH(DISABLE_TEX_TRANSFORM | TEXTURE_SET(3));
 
-   OUT_BATCH(_3DSTATE_RASTER_RULES_CMD |
-             ENABLE_POINT_RASTER_RULE |
-             OGL_POINT_RASTER_RULE |
-             ENABLE_LINE_STRIP_PROVOKE_VRTX |
-             ENABLE_TRI_FAN_PROVOKE_VRTX |
-             ENABLE_TRI_STRIP_PROVOKE_VRTX |
-             LINE_STRIP_PROVOKE_VRTX(1) |
-             TRI_FAN_PROVOKE_VRTX(2) | TRI_STRIP_PROVOKE_VRTX(2));
-
    OUT_BATCH(_3DSTATE_VERTEX_TRANSFORM);
    OUT_BATCH(DISABLE_VIEWPORT_TRANSFORM | DISABLE_PERSPECTIVE_DIVIDE);
 
@@ -394,6 +385,9 @@ get_state_size(struct i830_hw_state *state)
    if (dirty & I830_UPLOAD_INVARIENT)
       sz += 40 * sizeof(int);
 
+   if (dirty & I830_UPLOAD_RASTER_RULES)
+      sz += sizeof(state->RasterRules);
+
    if (dirty & I830_UPLOAD_CTX)
       sz += sizeof(state->Ctx);
 
@@ -486,6 +480,11 @@ i830_emit_state(struct intel_context *intel)
       i830_emit_invarient_state(intel);
    }
 
+   if (dirty & I830_UPLOAD_RASTER_RULES) {
+      DBG("I830_UPLOAD_RASTER_RULES:\n");
+      emit(intel, state->RasterRules, sizeof(state->RasterRules));
+   }
+
    if (dirty & I830_UPLOAD_CTX) {
       DBG("I830_UPLOAD_CTX:\n");
       emit(intel, state->Ctx, sizeof(state->Ctx));
@@ -737,6 +736,13 @@ i830_assert_not_dirty( struct intel_context *intel )
    assert(!get_dirty(state));
 }
 
+static void
+i830_invalidate_state(struct intel_context *intel, GLuint new_state)
+{
+   if (new_state & _NEW_LIGHT)
+      i830_update_provoking_vertex(&intel->ctx);
+}
+
 void
 i830InitVtbl(struct i830_context *i830)
 {
@@ -752,4 +758,5 @@ i830InitVtbl(struct i830_context *i830)
    i830->intel.vtbl.render_prevalidate = i830_render_prevalidate;
    i830->intel.vtbl.assert_not_dirty = i830_assert_not_dirty;
    i830->intel.vtbl.finish_batch = intel_finish_vb;
+   i830->intel.vtbl.invalidate_state = i830_invalidate_state;
 }
index 5aa41334b0b76113afd2e149d63e526b934cbc36..bb08cf8d18f24288bec14176eed3a4e0491f65e5 100644 (file)
@@ -77,6 +77,8 @@ i915InvalidateState(GLcontext * ctx, GLuint new_state)
       i915_update_fog(ctx);
    if (new_state & (_NEW_STENCIL | _NEW_BUFFERS | _NEW_POLYGON))
       i915_update_stencil(ctx);
+   if (new_state & (_NEW_LIGHT))
+       i915_update_provoking_vertex(ctx);
 }
 
 
index c6b7377da80d500dc678e5bba31bd4d0c4972527..8de4a9d0d3625c2f9cfff5f8d6c82813ea8427d4 100644 (file)
@@ -48,6 +48,7 @@
 #define I915_UPLOAD_FOG              0x20
 #define I915_UPLOAD_INVARIENT        0x40
 #define I915_UPLOAD_DEFAULTS         0x80
+#define I915_UPLOAD_RASTER_RULES     0x100
 #define I915_UPLOAD_TEX(i)           (0x00010000<<(i))
 #define I915_UPLOAD_TEX_ALL          (0x00ff0000)
 #define I915_UPLOAD_TEX_0_SHIFT      16
 #define I915_DEFREG_Z1    5
 #define I915_DEF_SETUP_SIZE    6
 
+enum {
+   I915_RASTER_RULES,
+   I915_RASTER_RULES_SETUP_SIZE,
+};
 
 #define I915_MAX_CONSTANT      32
 #define I915_CONSTANT_SIZE     (2+(4*I915_MAX_CONSTANT))
@@ -208,6 +213,7 @@ struct i915_hw_state
    GLuint Stipple[I915_STP_SETUP_SIZE];
    GLuint Fog[I915_FOG_SETUP_SIZE];
    GLuint Defaults[I915_DEF_SETUP_SIZE];
+   GLuint RasterRules[I915_RASTER_RULES_SETUP_SIZE];
    GLuint Tex[I915_TEX_UNITS][I915_TEX_SETUP_SIZE];
    GLuint Constant[I915_CONSTANT_SIZE];
    GLuint ConstantSize;
@@ -324,6 +330,7 @@ extern void i915InitStateFunctions(struct dd_function_table *functions);
 extern void i915InitState(struct i915_context *i915);
 extern void i915_update_fog(GLcontext * ctx);
 extern void i915_update_stencil(GLcontext * ctx);
+extern void i915_update_provoking_vertex(GLcontext *ctx);
 
 
 /*======================================================================
index 80ec46190d7d704fec41607cb1e02007922857be..b5fa7fddb9636f186ce715e57b45db6f4c181219 100644 (file)
 #define TEXKILL_4D                      (1<<9)
 #define ENABLE_LINE_STRIP_PROVOKE_VRTX (1<<8)
 #define ENABLE_TRI_FAN_PROVOKE_VRTX    (1<<5)
+#define LINE_STRIP_PROVOKE_VRTX_MASK   (3 << 6)
 #define LINE_STRIP_PROVOKE_VRTX(x)     ((x)<<6)
+#define TRI_FAN_PROVOKE_VRTX_MASK      (3 << 3)
 #define TRI_FAN_PROVOKE_VRTX(x)        ((x)<<3)
 
 /* _3DSTATE_SCISSOR_ENABLE, p256 */
index 670451bc838d9d0c954280511c78bcd4a165496c..b60efea75bdc32c3b749c23fbdae2e7b7a848611 100644 (file)
@@ -1033,6 +1033,13 @@ i915_init_packets(struct i915_context *i915)
       i915->state.Buffer[I915_DESTREG_SR2] = 0;
    }
 
+   i915->state.RasterRules[I915_RASTER_RULES] = _3DSTATE_RASTER_RULES_CMD |
+      ENABLE_POINT_RASTER_RULE |
+      OGL_POINT_RASTER_RULE |
+      ENABLE_LINE_STRIP_PROVOKE_VRTX |
+      ENABLE_TRI_FAN_PROVOKE_VRTX |
+      LINE_STRIP_PROVOKE_VRTX(1) |
+      TRI_FAN_PROVOKE_VRTX(2) | ENABLE_TEXKILL_3D_4D | TEXKILL_4D;
 
 #if 0
    {
@@ -1053,7 +1060,33 @@ i915_init_packets(struct i915_context *i915)
    i915->state.active = (I915_UPLOAD_PROGRAM |
                          I915_UPLOAD_STIPPLE |
                          I915_UPLOAD_CTX |
-                         I915_UPLOAD_BUFFERS | I915_UPLOAD_INVARIENT);
+                         I915_UPLOAD_BUFFERS |
+                        I915_UPLOAD_INVARIENT |
+                        I915_UPLOAD_RASTER_RULES);
+}
+
+void
+i915_update_provoking_vertex(GLcontext * ctx)
+{
+   struct i915_context *i915 = I915_CONTEXT(ctx);
+
+   I915_STATECHANGE(i915, I915_UPLOAD_CTX);
+   i915->state.Ctx[I915_CTXREG_LIS6] &= ~(S6_TRISTRIP_PV_MASK);
+
+   I915_STATECHANGE(i915, I915_UPLOAD_RASTER_RULES);
+   i915->state.RasterRules[I915_RASTER_RULES] &= ~(LINE_STRIP_PROVOKE_VRTX_MASK |
+                                                  TRI_FAN_PROVOKE_VRTX_MASK);
+
+   /* _NEW_LIGHT */
+   if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION) {
+      i915->state.RasterRules[I915_RASTER_RULES] |= (LINE_STRIP_PROVOKE_VRTX(1) |
+                                                    TRI_FAN_PROVOKE_VRTX(2));
+      i915->state.Ctx[I915_CTXREG_LIS6] |= (2 << S6_TRISTRIP_PV_SHIFT);
+   } else {
+      i915->state.RasterRules[I915_RASTER_RULES] |= (LINE_STRIP_PROVOKE_VRTX(0) |
+                                                    TRI_FAN_PROVOKE_VRTX(1));
+      i915->state.Ctx[I915_CTXREG_LIS6] |= (0 << S6_TRISTRIP_PV_SHIFT);
+    }
 }
 
 void
index 707864ebfdba6dc8628f68f15519f95e90061def..9a723d3cd739733ab3722907716394be0c4a6206 100644 (file)
@@ -176,7 +176,7 @@ i915_emit_invarient_state(struct intel_context *intel)
 {
    BATCH_LOCALS;
 
-   BEGIN_BATCH(18, IGNORE_CLIPRECTS);
+   BEGIN_BATCH(17, IGNORE_CLIPRECTS);
 
    OUT_BATCH(_3DSTATE_AA_CMD |
              AA_LINE_ECAAR_WIDTH_ENABLE |
@@ -200,14 +200,6 @@ i915_emit_invarient_state(struct intel_context *intel)
              CSB_TCB(3, 3) |
              CSB_TCB(4, 4) | CSB_TCB(5, 5) | CSB_TCB(6, 6) | CSB_TCB(7, 7));
 
-   OUT_BATCH(_3DSTATE_RASTER_RULES_CMD |
-             ENABLE_POINT_RASTER_RULE |
-             OGL_POINT_RASTER_RULE |
-             ENABLE_LINE_STRIP_PROVOKE_VRTX |
-             ENABLE_TRI_FAN_PROVOKE_VRTX |
-             LINE_STRIP_PROVOKE_VRTX(1) |
-             TRI_FAN_PROVOKE_VRTX(2) | ENABLE_TEXKILL_3D_4D | TEXKILL_4D);
-
    /* Need to initialize this to zero.
     */
    OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(3) | (0));
@@ -258,6 +250,9 @@ get_state_size(struct i915_hw_state *state)
    if (dirty & I915_UPLOAD_INVARIENT)
       sz += 30 * 4;
 
+   if (dirty & I915_UPLOAD_RASTER_RULES)
+      sz += sizeof(state->RasterRules);
+
    if (dirty & I915_UPLOAD_CTX)
       sz += sizeof(state->Ctx);
 
@@ -366,6 +361,12 @@ i915_emit_state(struct intel_context *intel)
       i915_emit_invarient_state(intel);
    }
 
+   if (dirty & I915_UPLOAD_RASTER_RULES) {
+      if (INTEL_DEBUG & DEBUG_STATE)
+         fprintf(stderr, "I915_UPLOAD_RASTER_RULES:\n");
+      emit(intel, state->RasterRules, sizeof(state->RasterRules));
+   }
+
    if (dirty & I915_UPLOAD_CTX) {
       if (INTEL_DEBUG & DEBUG_STATE)
          fprintf(stderr, "I915_UPLOAD_CTX:\n");
index b5f6371c82c2ce8a620fdfe62719563a7ed0810b..a964cb26c9a954730d1607ea8c8935eeea6e80f3 100644 (file)
@@ -113,7 +113,7 @@ struct brw_sf_unit_key {
 
    unsigned int nr_urb_entries, urb_size, sfsize;
 
-   GLenum front_face, cull_face;
+   GLenum front_face, cull_face, provoking_vertex;
    unsigned scissor:1;
    unsigned line_smooth:1;
    unsigned point_sprite:1;
@@ -153,6 +153,9 @@ sf_unit_populate_key(struct brw_context *brw, struct brw_sf_unit_key *key)
    key->point_size = CLAMP(ctx->Point.Size, ctx->Point.MinSize, ctx->Point.MaxSize);
    key->point_attenuated = ctx->Point._Attenuated;
 
+   /* _NEW_LIGHT */
+   key->provoking_vertex = ctx->Light.ProvokingVertex;
+
    key->render_to_fbo = brw->intel.ctx.DrawBuffer->Name != 0;
 }
 
@@ -284,9 +287,15 @@ sf_unit_create_from_key(struct brw_context *brw, struct brw_sf_unit_key *key,
 
    /* might be BRW_NEW_PRIMITIVE if we have to adjust pv for polygons:
     */
-   sf.sf7.trifan_pv = 2;
-   sf.sf7.linestrip_pv = 1;
-   sf.sf7.tristrip_pv = 2;
+   if (key->provoking_vertex == GL_LAST_VERTEX_CONVENTION) {
+      sf.sf7.trifan_pv = 2;
+      sf.sf7.linestrip_pv = 1;
+      sf.sf7.tristrip_pv = 2;
+   } else {
+      sf.sf7.trifan_pv = 1;
+      sf.sf7.linestrip_pv = 0;
+      sf.sf7.tristrip_pv = 0;
+   }
    sf.sf7.line_last_pixel_enable = 0;
 
    /* Set bias for OpenGL rasterization rules:
@@ -340,6 +349,7 @@ static void upload_sf_unit( struct brw_context *brw )
 const struct brw_tracked_state brw_sf_unit = {
    .dirty = {
       .mesa  = (_NEW_POLYGON | 
+               _NEW_LIGHT |
                _NEW_LINE | 
                _NEW_POINT | 
                _NEW_SCISSOR |
index 6a68021c69186591960bb6a2501c1afd6f8a14fa..aa3d704f2995e1562860efc196bbe5321aea6970 100644 (file)
@@ -48,6 +48,7 @@
 #define need_GL_EXT_framebuffer_blit
 #define need_GL_EXT_gpu_program_parameters
 #define need_GL_EXT_point_parameters
+#define need_GL_EXT_provoking_vertex
 #define need_GL_EXT_secondary_color
 #define need_GL_EXT_stencil_two_side
 #define need_GL_APPLE_vertex_array_object
@@ -93,6 +94,7 @@ static const struct dri_extension card_extensions[] = {
    { "GL_EXT_fog_coord",                  GL_EXT_fog_coord_functions },
    { "GL_EXT_gpu_program_parameters",     GL_EXT_gpu_program_parameters_functions },
    { "GL_EXT_packed_depth_stencil",       NULL },
+   { "GL_EXT_provoking_vertex",           GL_EXT_provoking_vertex_functions },
    { "GL_EXT_secondary_color",            GL_EXT_secondary_color_functions },
    { "GL_EXT_stencil_wrap",               NULL },
    { "GL_EXT_texture_edge_clamp",         NULL },