[Mesa-dev] i965/Gen6-7: Do not replace texcoords with point coord if not drawing points

Submitted by Chris Forbes on Nov. 24, 2014, 8:44 p.m.

Details

Message ID 1416861859-314-1-git-send-email-chrisf@ijw.co.nz
State New
Headers show

Commit Message

Chris Forbes Nov. 24, 2014, 8:44 p.m.
Partially fixes broken rendering in Windows-based QtQuick2 apps run through Wine.
This library sets all texture units' GL_COORD_REPLACE, leaves point
sprite mode enabled, and then draws a triangle fan.

Will need a slightly different fix for Gen4-5, but I don't have my old
machines in a usable state currently.

Signed-off-by: Chris Forbes <chrisf@ijw.co.nz>
---
Now with 100% less bogus patch mangling!

 src/mesa/drivers/dri/i965/brw_state.h     |  2 ++
 src/mesa/drivers/dri/i965/gen6_sf_state.c | 23 ++++++++++++++++++++++-
 src/mesa/drivers/dri/i965/gen7_sf_state.c | 17 ++++++++++++++++-
 3 files changed, 40 insertions(+), 2 deletions(-)

Patch hide | download patch | download mbox

diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h
index 209fab1..77dd879 100644
--- a/src/mesa/drivers/dri/i965/brw_state.h
+++ b/src/mesa/drivers/dri/i965/brw_state.h
@@ -271,6 +271,8 @@  calculate_attr_overrides(const struct brw_context *brw,
                          uint32_t *point_sprite_enables,
                          uint32_t *flat_enables,
                          uint32_t *urb_entry_read_length);
+bool
+brw_is_drawing_points(struct brw_context *brw);
 
 /* gen6_surface_state.c */
 void gen6_init_vtable_surface_functions(struct brw_context *brw);
diff --git a/src/mesa/drivers/dri/i965/gen6_sf_state.c b/src/mesa/drivers/dri/i965/gen6_sf_state.c
index 24d2754..d4cf89d 100644
--- a/src/mesa/drivers/dri/i965/gen6_sf_state.c
+++ b/src/mesa/drivers/dri/i965/gen6_sf_state.c
@@ -222,6 +222,18 @@  calculate_attr_overrides(const struct brw_context *brw,
 }
 
 
+bool
+brw_is_drawing_points(struct brw_context *brw)
+{
+   /* Determine if the primitives *reaching the SF* are points */
+   struct gl_context *ctx = &brw->ctx;
+   if (ctx->GeometryProgram._Current)
+      return ctx->GeometryProgram._Current->OutputType == GL_POINTS;
+   else
+      return brw->primitive == _3DPRIM_POINTLIST;
+}
+
+
 static void
 upload_sf_state(struct brw_context *brw)
 {
@@ -380,6 +392,14 @@  upload_sf_state(struct brw_context *brw)
    dw1 |= (urb_entry_read_length << GEN6_SF_URB_ENTRY_READ_LENGTH_SHIFT |
            urb_entry_read_offset << GEN6_SF_URB_ENTRY_READ_OFFSET_SHIFT);
 
+   /* The SandyBridge PRM doesn't explicitly say that point sprite enables
+    * must be programmed to zero when rendering non-point primitives, but
+    * the IvyBridge PRM does, and if we don't, we get garbage:
+    */
+   /* BRW_NEW_PRIMITIVE | _NEW_PROGRAM */
+   if (!brw_is_drawing_points(brw))
+      point_sprite_enables = 0;
+
    BEGIN_BATCH(20);
    OUT_BATCH(_3DSTATE_SF << 16 | (20 - 2));
    OUT_BATCH(dw1);
@@ -411,7 +431,8 @@  const struct brw_tracked_state gen6_sf_state = {
                 _NEW_MULTISAMPLE),
       .brw   = (BRW_NEW_CONTEXT |
 		BRW_NEW_FRAGMENT_PROGRAM |
-                BRW_NEW_VUE_MAP_GEOM_OUT),
+                BRW_NEW_VUE_MAP_GEOM_OUT |
+                BRW_NEW_PRIMITIVE),
       .cache = CACHE_NEW_WM_PROG
    },
    .emit = upload_sf_state,
diff --git a/src/mesa/drivers/dri/i965/gen7_sf_state.c b/src/mesa/drivers/dri/i965/gen7_sf_state.c
index 109b825..90ac199 100644
--- a/src/mesa/drivers/dri/i965/gen7_sf_state.c
+++ b/src/mesa/drivers/dri/i965/gen7_sf_state.c
@@ -78,6 +78,20 @@  upload_sbe_state(struct brw_context *brw)
       OUT_BATCH(attr_overrides[i * 2] | attr_overrides[i * 2 + 1] << 16);
    }
 
+   /* From the Ivybridge PRM, Vol 2 Part 1, 3DSTATE_SBE,
+    * description of dw10 Point Sprite Texture Coordinate Enable:
+    *
+    * "This field must be programmed to zero when non-point primitives
+    * are rendered."
+    *
+    * FINISHME: No longer required on Haswell, so we could avoid wasting
+    * a bit of batch space on primitive changes by splitting this atom
+    * into a Haswell variant.
+    */
+   /* BRW_NEW_PRIMITIVE | _NEW_PROGRAM */
+   if (!brw_is_drawing_points(brw))
+      point_sprite_enables = 0;
+
    OUT_BATCH(point_sprite_enables); /* dw10 */
    OUT_BATCH(flat_enables);
    OUT_BATCH(0); /* wrapshortest enables 0-7 */
@@ -93,7 +107,8 @@  const struct brw_tracked_state gen7_sbe_state = {
 		_NEW_PROGRAM),
       .brw   = (BRW_NEW_CONTEXT |
 		BRW_NEW_FRAGMENT_PROGRAM |
-                BRW_NEW_VUE_MAP_GEOM_OUT),
+                BRW_NEW_VUE_MAP_GEOM_OUT |
+                BRW_NEW_PRIMITIVE),
       .cache = CACHE_NEW_WM_PROG
    },
    .emit = upload_sbe_state,