Merge remote-tracking branch 'origin/master' into pipe-video
[mesa.git] / src / mesa / drivers / dri / i965 / gen6_sf_state.c
index 50a5ad38c6fcb1d936a4030ff7e2a6fa62dc275c..5bb731dc8fd1088f991a03bf4a02e9646d1607d1 100644 (file)
@@ -32,7 +32,7 @@
 #include "main/macros.h"
 #include "intel_batchbuffer.h"
 
-static uint32_t
+uint32_t
 get_attr_override(struct brw_context *brw, int fs_attr, int two_side_color)
 {
    int attr_index = 0, i, vs_attr;
@@ -100,9 +100,11 @@ upload_sf_state(struct brw_context *brw)
    int i;
    /* _NEW_BUFFER */
    GLboolean render_to_fbo = brw->intel.ctx.DrawBuffer->Name != 0;
-   int attr = 0;
+   int attr = 0, input_index = 0;
    int urb_start;
    int two_side_color = (ctx->Light.Enabled && ctx->Light.Model.TwoSide);
+   float point_size;
+   uint16_t attr_overrides[FRAG_ATTRIB_MAX];
 
    /* _NEW_TRANSFORM */
    if (ctx->Transform.ClipPlanesEnabled)
@@ -209,8 +211,12 @@ upload_sf_state(struct brw_context *brw)
         ctx->Point._Attenuated))
       dw4 |= GEN6_SF_USE_STATE_POINT_WIDTH;
 
-   dw4 |= U_FIXED(CLAMP(ctx->Point.Size, 0.125, 255.875), 3) <<
-      GEN6_SF_POINT_WIDTH_SHIFT;
+   /* Clamp to ARB_point_parameters user limits */
+   point_size = CLAMP(ctx->Point.Size, ctx->Point.MinSize, ctx->Point.MaxSize);
+
+   /* Clamp to the hardware limits and convert to fixed point */
+   dw4 |= U_FIXED(CLAMP(point_size, 0.125, 255.875), 3);
+
    if (ctx->Point.SpriteOrigin == GL_LOWER_LEFT)
       dw1 |= GEN6_SF_POINT_SPRITE_LOWERLEFT;
 
@@ -225,19 +231,43 @@ upload_sf_state(struct brw_context *brw)
         (1 << GEN6_SF_TRIFAN_PROVOKE_SHIFT);
    }
 
-   if (ctx->Point.PointSprite) {
-       for (i = 0; i < 8; i++) { 
-          if (ctx->Point.CoordReplace[i])
-              dw16 |= (1 << i);
-       }
-   }
-
    /* flat shading */
    if (ctx->Light.ShadeModel == GL_FLAT) {
        dw17 |= ((brw->fragment_program->Base.InputsRead & (FRAG_BIT_COL0 | FRAG_BIT_COL1)) >>
                 ((brw->fragment_program->Base.InputsRead & FRAG_BIT_WPOS) ? 0 : 1));
    }
 
+   /* Create the mapping from the FS inputs we produce to the VS outputs
+    * they source from.
+    */
+   for (; attr < FRAG_ATTRIB_MAX; attr++) {
+      if (!(brw->fragment_program->Base.InputsRead & BITFIELD64_BIT(attr)))
+        continue;
+
+      /* _NEW_POINT */
+      if (ctx->Point.PointSprite &&
+         (attr >= FRAG_ATTRIB_TEX0 && attr <= FRAG_ATTRIB_TEX7) &&
+         ctx->Point.CoordReplace[attr - FRAG_ATTRIB_TEX0]) {
+        dw16 |= (1 << input_index);
+      }
+
+      if (attr == FRAG_ATTRIB_PNTC)
+        dw16 |= (1 << input_index);
+
+      /* The hardware can only do the overrides on 16 overrides at a
+       * time, and the other up to 16 have to be lined up so that the
+       * input index = the output index.  We'll need to do some
+       * tweaking to make sure that's the case.
+       */
+      assert(input_index < 16 || attr == input_index);
+
+      attr_overrides[input_index++] = get_attr_override(brw, attr,
+                                                       two_side_color);
+   }
+
+   for (; input_index < FRAG_ATTRIB_MAX; input_index++)
+      attr_overrides[input_index] = 0;
+
    BEGIN_BATCH(20);
    OUT_BATCH(_3DSTATE_SF << 16 | (20 - 2));
    OUT_BATCH(dw1);
@@ -248,24 +278,7 @@ upload_sf_state(struct brw_context *brw)
    OUT_BATCH_F(ctx->Polygon.OffsetFactor); /* scale */
    OUT_BATCH_F(0.0); /* XXX: global depth offset clamp */
    for (i = 0; i < 8; i++) {
-      uint32_t attr_overrides = 0;
-
-      for (; attr < 64; attr++) {
-        if (brw->fragment_program->Base.InputsRead & BITFIELD64_BIT(attr)) {
-           attr_overrides |= get_attr_override(brw, attr, two_side_color);
-           attr++;
-           break;
-        }
-      }
-
-      for (; attr < 64; attr++) {
-        if (brw->fragment_program->Base.InputsRead & BITFIELD64_BIT(attr)) {
-           attr_overrides |= get_attr_override(brw, attr, two_side_color) << 16;
-           attr++;
-           break;
-        }
-      }
-      OUT_BATCH(attr_overrides);
+      OUT_BATCH(attr_overrides[i * 2] | attr_overrides[i * 2 + 1] << 16);
    }
    OUT_BATCH(dw16); /* point sprite texcoord bitmask */
    OUT_BATCH(dw17); /* constant interp bitmask */