<div dir="ltr">On 31 July 2013 04:07, Chris Forbes <span dir="ltr"><<a href="mailto:chrisf@ijw.co.nz" target="_blank">chrisf@ijw.co.nz</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Previously the SF only handled the builtin color varying specially.<br>
This patch generalizes that support to cover user-defined varyings,<br>
driven by the interpolation mode array set up alongside the VUE map.<br>
<br>
Based on the following patches from Olivier Galibert:<br>
- <a href="http://lists.freedesktop.org/archives/mesa-dev/2012-July/024335.html" target="_blank">http://lists.freedesktop.org/archives/mesa-dev/2012-July/024335.html</a><br>
- <a href="http://lists.freedesktop.org/archives/mesa-dev/2012-July/024339.html" target="_blank">http://lists.freedesktop.org/archives/mesa-dev/2012-July/024339.html</a><br>
<br>
With this patch, all the GLSL 1.3 interpolation tests that do not clip<br>
(spec/glsl-1.30/execution/interpolation/*-none.shader_test) pass.<br>
<br>
V5: Move key.do_flat_shading to brw_sf_compile.has_flat_shading; drop<br>
vestigial hunks.<br>
<br>
Signed-off-by: Chris Forbes <<a href="mailto:chrisf@ijw.co.nz">chrisf@ijw.co.nz</a>><br>
---<br>
 src/mesa/drivers/dri/i965/brw_fs.cpp    |   2 +-<br>
 src/mesa/drivers/dri/i965/brw_sf.c      |   2 +-<br>
 src/mesa/drivers/dri/i965/brw_sf.h      |   2 +-<br>
 src/mesa/drivers/dri/i965/brw_sf_emit.c | 149 ++++++++++++++++++--------------<br>
 4 files changed, 85 insertions(+), 70 deletions(-)<br>
<br>
diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp<br>
index afd29de..a81e97f 100644<br>
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp<br>
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp<br>
@@ -1048,7 +1048,7 @@ fs_visitor::emit_general_interpolation(ir_variable *ir)<br>
                   inst->predicate = BRW_PREDICATE_NORMAL;<br>
                   inst->predicate_inverse = true;<br>
                }<br>
-               if (brw->gen < 6) {<br>
+               if (brw->gen < 6 && interpolation_mode == INTERP_QUALIFIER_SMOOTH) {<br>
                   emit(BRW_OPCODE_MUL, attr, attr, this->pixel_w);<br>
                }<br>
               attr.reg_offset++;<br>
diff --git a/src/mesa/drivers/dri/i965/brw_sf.c b/src/mesa/drivers/dri/i965/brw_sf.c<br>
index b062c0b..1634078 100644<br>
--- a/src/mesa/drivers/dri/i965/brw_sf.c<br>
+++ b/src/mesa/drivers/dri/i965/brw_sf.c<br>
@@ -81,6 +81,7 @@ static void compile_sf_prog( struct brw_context *brw,<br>
<br>
    c.prog_data.urb_read_length = c.nr_attr_regs;<br>
    c.prog_data.urb_entry_size = c.nr_setup_regs * 2;<br>
+   c.has_flat_shading = brw_any_flat_varyings(&key->interpolation_mode);<br>
<br>
    /* Which primitive?  Or all three?<br>
     */<br>
@@ -193,7 +194,6 @@ brw_upload_sf_prog(struct brw_context *brw)<br>
    key.interpolation_mode = brw->interpolation_mode;<br>
<br>
    /* _NEW_LIGHT | _NEW_PROGRAM */<br>
-   key.do_flat_shading = (ctx->Light.ShadeModel == GL_FLAT);<br>
    key.do_twoside_color = ((ctx->Light.Enabled && ctx->Light.Model.TwoSide) ||<br>
                            ctx->VertexProgram._TwoSideEnabled);<br>
<br>
diff --git a/src/mesa/drivers/dri/i965/brw_sf.h b/src/mesa/drivers/dri/i965/brw_sf.h<br>
index d65f495..f738461 100644<br>
--- a/src/mesa/drivers/dri/i965/brw_sf.h<br>
+++ b/src/mesa/drivers/dri/i965/brw_sf.h<br>
@@ -50,7 +50,6 @@ struct brw_sf_prog_key {<br>
    uint8_t point_sprite_coord_replace;<br>
    GLuint primitive:2;<br>
    GLuint do_twoside_color:1;<br>
-   GLuint do_flat_shading:1;<br>
    GLuint frontface_ccw:1;<br>
    GLuint do_point_sprite:1;<br>
    GLuint do_point_coord:1;<br>
@@ -96,6 +95,7 @@ struct brw_sf_compile {<br>
    int urb_entry_read_offset;<br>
<br>
    struct brw_vue_map vue_map;<br>
+   GLuint has_flat_shading:1;<br></blockquote><div><br></div><div>I would just make this a bool rather than a 1-bit wide bitfield.  The only reason brw_sf_prog_key uses bitfields is that it's a hash key, so compact representation is important.  That's not an issue for brw_sf_compile.<br>
<br></div><div>Wth that fixed, this patch is:<br><br>Reviewed-by: Paul Berry <<a href="mailto:stereotype441@gmail.com">stereotype441@gmail.com</a>><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

 };<br>
<br>
<br>
diff --git a/src/mesa/drivers/dri/i965/brw_sf_emit.c b/src/mesa/drivers/dri/i965/brw_sf_emit.c<br>
index bd68f68..0131de5 100644<br>
--- a/src/mesa/drivers/dri/i965/brw_sf_emit.c<br>
+++ b/src/mesa/drivers/dri/i965/brw_sf_emit.c<br>
@@ -44,6 +44,15 @@<br>
<br>
<br>
 /**<br>
+ * Determine the vue slot corresponding to the given half of the given register.<br>
+ */<br>
+static inline int vert_reg_to_vue_slot(struct brw_sf_compile *c, GLuint reg,<br>
+                                       int half)<br>
+{<br>
+   return (reg + c->urb_entry_read_offset) * 2 + half;<br>
+}<br>
+<br>
+/**<br>
  * Determine the varying corresponding to the given half of the given<br>
  * register.  half=0 means the first half of a register, half=1 means the<br>
  * second half.<br>
@@ -51,11 +60,24 @@<br>
 static inline int vert_reg_to_varying(struct brw_sf_compile *c, GLuint reg,<br>
                                       int half)<br>
 {<br>
-   int vue_slot = (reg + c->urb_entry_read_offset) * 2 + half;<br>
+   int vue_slot = vert_reg_to_vue_slot(c, reg, half);<br>
    return c->vue_map.slot_to_varying[vue_slot];<br>
 }<br>
<br>
 /**<br>
+ * Determine the register corresponding to the given vue slot<br>
+ */<br>
+static struct brw_reg get_vue_slot(struct brw_sf_compile *c,<br>
+                                   struct brw_reg vert,<br>
+                                   int vue_slot)<br>
+{<br>
+   GLuint off = vue_slot / 2 - c->urb_entry_read_offset;<br>
+   GLuint sub = vue_slot % 2;<br>
+<br>
+   return brw_vec4_grf(<a href="http://vert.nr" target="_blank">vert.nr</a> + off, sub * 4);<br>
+}<br>
+<br>
+/**<br>
  * Determine the register corresponding to the given varying.<br>
  */<br>
 static struct brw_reg get_varying(struct brw_sf_compile *c,<br>
@@ -64,10 +86,7 @@ static struct brw_reg get_varying(struct brw_sf_compile *c,<br>
 {<br>
    int vue_slot = c->vue_map.varying_to_slot[varying];<br>
    assert (vue_slot >= c->urb_entry_read_offset);<br>
-   GLuint off = vue_slot / 2 - c->urb_entry_read_offset;<br>
-   GLuint sub = vue_slot % 2;<br>
-<br>
-   return brw_vec4_grf(<a href="http://vert.nr" target="_blank">vert.nr</a> + off, sub * 4);<br>
+   return get_vue_slot(c, vert, vue_slot);<br>
 }<br>
<br>
 static bool<br>
@@ -105,14 +124,14 @@ static void do_twoside_color( struct brw_sf_compile *c )<br>
    if (c->key.primitive == SF_UNFILLED_TRIS)<br>
       return;<br>
<br>
-   /* XXX: What happens if BFC isn't present?  This could only happen<br>
-    * for user-supplied vertex programs, as t_vp_build.c always does<br>
-    * the right thing.<br>
+   /* If the vertex shader provides backface color, do the selection. The VS<br>
+    * promises to set up the front color if the backface color is provided, but<br>
+    * it may contain junk if never written to.<br>
     */<br>
    if (!(have_attr(c, VARYING_SLOT_COL0) && have_attr(c, VARYING_SLOT_BFC0)) &&<br>
        !(have_attr(c, VARYING_SLOT_COL1) && have_attr(c, VARYING_SLOT_BFC1)))<br>
       return;<br>
-<br>
+<br>
    /* Need to use BRW_EXECUTE_4 and also do an 4-wide compare in order<br>
     * to get all channels active inside the IF.  In the clipping code<br>
     * we run with NoMask, so it's not an option and we can use<br>
@@ -138,24 +157,34 @@ static void do_twoside_color( struct brw_sf_compile *c )<br>
  * Flat shading<br>
  */<br>
<br>
-#define VARYING_SLOT_COLOR_BITS (BITFIELD64_BIT(VARYING_SLOT_COL0) | \<br>
-                                 BITFIELD64_BIT(VARYING_SLOT_COL1))<br>
-<br>
-static void copy_colors( struct brw_sf_compile *c,<br>
-                    struct brw_reg dst,<br>
-                    struct brw_reg src)<br>
+static void copy_flatshaded_attributes(struct brw_sf_compile *c,<br>
+                                       struct brw_reg dst,<br>
+                                       struct brw_reg src)<br>
 {<br>
    struct brw_compile *p = &c->func;<br>
-   GLuint i;<br>
+   int i;<br>
<br>
-   for (i = VARYING_SLOT_COL0; i <= VARYING_SLOT_COL1; i++) {<br>
-      if (have_attr(c,i))<br>
-        brw_MOV(p,<br>
-                get_varying(c, dst, i),<br>
-                get_varying(c, src, i));<br>
+   for (i = 0; i < c->vue_map.num_slots; i++) {<br>
+      if (c->key.interpolation_mode.mode[i] == INTERP_QUALIFIER_FLAT) {<br>
+         brw_MOV(p,<br>
+                 get_vue_slot(c, dst, i),<br>
+                 get_vue_slot(c, src, i));<br>
+      }<br>
    }<br>
 }<br>
<br>
+static int count_flatshaded_attributes(struct brw_sf_compile *c)<br>
+{<br>
+   int i;<br>
+   int count = 0;<br>
+<br>
+   for (i = 0; i < c->vue_map.num_slots; i++)<br>
+      if (c->key.interpolation_mode.mode[i] == INTERP_QUALIFIER_FLAT)<br>
+         count++;<br>
+<br>
+   return count;<br>
+}<br>
+<br>
<br>
<br>
 /* Need to use a computed jump to copy flatshaded attributes as the<br>
@@ -167,12 +196,9 @@ static void do_flatshade_triangle( struct brw_sf_compile *c )<br>
    struct brw_compile *p = &c->func;<br>
    struct brw_context *brw = p->brw;<br>
    struct brw_reg ip = brw_ip_reg();<br>
-   GLuint nr = _mesa_bitcount_64(c->key.attrs & VARYING_SLOT_COLOR_BITS);<br>
+   GLuint nr;<br>
    GLuint jmpi = 1;<br>
<br>
-   if (!nr)<br>
-      return;<br>
-<br>
    /* Already done in clip program:<br>
     */<br>
    if (c->key.primitive == SF_UNFILLED_TRIS)<br>
@@ -181,21 +207,23 @@ static void do_flatshade_triangle( struct brw_sf_compile *c )<br>
    if (brw->gen == 5)<br>
        jmpi = 2;<br>
<br>
+   nr = count_flatshaded_attributes(c);<br>
+<br>
    brw_push_insn_state(p);<br>
-<br>
+<br>
    brw_MUL(p, c->pv, c->pv, brw_imm_d(jmpi*(nr*2+1)));<br>
    brw_JMPI(p, ip, ip, c->pv);<br>
<br>
-   copy_colors(c, c->vert[1], c->vert[0]);<br>
-   copy_colors(c, c->vert[2], c->vert[0]);<br>
+   copy_flatshaded_attributes(c, c->vert[1], c->vert[0]);<br>
+   copy_flatshaded_attributes(c, c->vert[2], c->vert[0]);<br>
    brw_JMPI(p, ip, ip, brw_imm_d(jmpi*(nr*4+1)));<br>
<br>
-   copy_colors(c, c->vert[0], c->vert[1]);<br>
-   copy_colors(c, c->vert[2], c->vert[1]);<br>
+   copy_flatshaded_attributes(c, c->vert[0], c->vert[1]);<br>
+   copy_flatshaded_attributes(c, c->vert[2], c->vert[1]);<br>
    brw_JMPI(p, ip, ip, brw_imm_d(jmpi*nr*2));<br>
<br>
-   copy_colors(c, c->vert[0], c->vert[2]);<br>
-   copy_colors(c, c->vert[1], c->vert[2]);<br>
+   copy_flatshaded_attributes(c, c->vert[0], c->vert[2]);<br>
+   copy_flatshaded_attributes(c, c->vert[1], c->vert[2]);<br>
<br>
    brw_pop_insn_state(p);<br>
 }<br>
@@ -206,12 +234,9 @@ static void do_flatshade_line( struct brw_sf_compile *c )<br>
    struct brw_compile *p = &c->func;<br>
    struct brw_context *brw = p->brw;<br>
    struct brw_reg ip = brw_ip_reg();<br>
-   GLuint nr = _mesa_bitcount_64(c->key.attrs & VARYING_SLOT_COLOR_BITS);<br>
+   GLuint nr;<br>
    GLuint jmpi = 1;<br>
<br>
-   if (!nr)<br>
-      return;<br>
-<br>
    /* Already done in clip program:<br>
     */<br>
    if (c->key.primitive == SF_UNFILLED_TRIS)<br>
@@ -220,14 +245,16 @@ static void do_flatshade_line( struct brw_sf_compile *c )<br>
    if (brw->gen == 5)<br>
        jmpi = 2;<br>
<br>
+   nr = count_flatshaded_attributes(c);<br>
+<br>
    brw_push_insn_state(p);<br>
<br>
    brw_MUL(p, c->pv, c->pv, brw_imm_d(jmpi*(nr+1)));<br>
    brw_JMPI(p, ip, ip, c->pv);<br>
-   copy_colors(c, c->vert[1], c->vert[0]);<br>
+   copy_flatshaded_attributes(c, c->vert[1], c->vert[0]);<br>
<br>
    brw_JMPI(p, ip, ip, brw_imm_ud(jmpi*nr));<br>
-   copy_colors(c, c->vert[0], c->vert[1]);<br>
+   copy_flatshaded_attributes(c, c->vert[0], c->vert[1]);<br>
<br>
    brw_pop_insn_state(p);<br>
 }<br>
@@ -324,36 +351,23 @@ static void invert_det( struct brw_sf_compile *c)<br>
<br>
 static bool<br>
 calculate_masks(struct brw_sf_compile *c,<br>
-               GLuint reg,<br>
-               GLushort *pc,<br>
-               GLushort *pc_persp,<br>
-               GLushort *pc_linear)<br>
+                GLuint reg,<br>
+                GLushort *pc,<br>
+                GLushort *pc_persp,<br>
+                GLushort *pc_linear)<br>
 {<br>
    bool is_last_attr = (reg == c->nr_setup_regs - 1);<br>
-   GLbitfield64 persp_mask;<br>
-   GLbitfield64 linear_mask;<br>
-<br>
-   if (c->key.do_flat_shading)<br>
-      persp_mask = c->key.attrs & ~(BITFIELD64_BIT(VARYING_SLOT_POS) |<br>
-                                    BITFIELD64_BIT(VARYING_SLOT_COL0) |<br>
-                                    BITFIELD64_BIT(VARYING_SLOT_COL1));<br>
-   else<br>
-      persp_mask = c->key.attrs & ~(BITFIELD64_BIT(VARYING_SLOT_POS));<br>
-<br>
-   if (c->key.do_flat_shading)<br>
-      linear_mask = c->key.attrs & ~(BITFIELD64_BIT(VARYING_SLOT_COL0) |<br>
-                                     BITFIELD64_BIT(VARYING_SLOT_COL1));<br>
-   else<br>
-      linear_mask = c->key.attrs;<br>
+   enum glsl_interp_qualifier interp;<br>
<br>
    *pc_persp = 0;<br>
    *pc_linear = 0;<br>
    *pc = 0xf;<br>
<br>
-   if (persp_mask & BITFIELD64_BIT(vert_reg_to_varying(c, reg, 0)))<br>
+   interp = c->key.interpolation_mode.mode[vert_reg_to_vue_slot(c, reg, 0)];<br>
+   if (interp == INTERP_QUALIFIER_SMOOTH) {<br>
+      *pc_linear = 0xf;<br>
       *pc_persp = 0xf;<br>
-<br>
-   if (linear_mask & BITFIELD64_BIT(vert_reg_to_varying(c, reg, 0)))<br>
+   } else if (interp == INTERP_QUALIFIER_NOPERSPECTIVE)<br>
       *pc_linear = 0xf;<br>
<br>
    /* Maybe only processs one attribute on the final round:<br>
@@ -361,11 +375,12 @@ calculate_masks(struct brw_sf_compile *c,<br>
    if (vert_reg_to_varying(c, reg, 1) != BRW_VARYING_SLOT_COUNT) {<br>
       *pc |= 0xf0;<br>
<br>
-      if (persp_mask & BITFIELD64_BIT(vert_reg_to_varying(c, reg, 1)))<br>
-        *pc_persp |= 0xf0;<br>
-<br>
-      if (linear_mask & BITFIELD64_BIT(vert_reg_to_varying(c, reg, 1)))<br>
-        *pc_linear |= 0xf0;<br>
+      interp = c->key.interpolation_mode.mode[vert_reg_to_vue_slot(c, reg, 1)];<br>
+      if (interp == INTERP_QUALIFIER_SMOOTH) {<br>
+         *pc_linear |= 0xf0;<br>
+         *pc_persp |= 0xf0;<br>
+      } else if (interp == INTERP_QUALIFIER_NOPERSPECTIVE)<br>
+         *pc_linear |= 0xf0;<br>
    }<br>
<br>
    return is_last_attr;<br>
@@ -418,7 +433,7 @@ void brw_emit_tri_setup(struct brw_sf_compile *c, bool allocate)<br>
    if (c->key.do_twoside_color)<br>
       do_twoside_color(c);<br>
<br>
-   if (c->key.do_flat_shading)<br>
+   if (c->has_flat_shading)<br>
       do_flatshade_triangle(c);<br>
<br>
<br>
@@ -504,7 +519,7 @@ void brw_emit_line_setup(struct brw_sf_compile *c, bool allocate)<br>
    invert_det(c);<br>
    copy_z_inv_w(c);<br>
<br>
-   if (c->key.do_flat_shading)<br>
+   if (c->has_flat_shading)<br>
       do_flatshade_line(c);<br>
<br>
    for (i = 0; i < c->nr_setup_regs; i++)<br>
<span class="HOEnZb"><font color="#888888">--<br>
1.8.3.4<br>
<br>
_______________________________________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/mesa-dev" target="_blank">http://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
</font></span></blockquote></div><br></div></div>