On i965 Gen6 and above, gl_PointSize is stored in component W of the
first VUE slot (which corresponds to VERT_RESULT_PSIZ in the VUE map).
Normally we store varying floats in component X of a VUE slot, so we
need special case logic for gl_PointSize.

For Gen6, we do this with a ".wwww" swizzle in the GS.  For Gen7, we
shift the component mask by 3 to select the W component.

Fixes Piglit test "EXT_transform_feedback/builtin-varyings
gl_PointSize".
---
 src/mesa/drivers/dri/i965/brw_gs_emit.c    |    5 +++++
 src/mesa/drivers/dri/i965/gen7_sol_state.c |   11 +++++++++--
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_gs_emit.c 
b/src/mesa/drivers/dri/i965/brw_gs_emit.c
index 607ee75..4074501 100644
--- a/src/mesa/drivers/dri/i965/brw_gs_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_gs_emit.c
@@ -446,8 +446,13 @@ gen6_sol_program(struct brw_gs_compile *c, struct 
brw_gs_prog_key *key,
             struct brw_reg vertex_slot = c->reg.vertex[vertex];
             vertex_slot.nr += slot / 2;
             vertex_slot.subnr = (slot % 2) * 16;
+            /* gl_PointSize is stored in VERT_RESULT_PSIZ.w. */
+            vertex_slot.dw1.bits.swizzle = vert_result == VERT_RESULT_PSIZ
+               ? BRW_SWIZZLE_WWWW : BRW_SWIZZLE_NOOP;
+            brw_set_access_mode(p, BRW_ALIGN_16);
             brw_MOV(p, stride(c->reg.header, 4, 4, 1),
                     retype(vertex_slot, BRW_REGISTER_TYPE_UD));
+            brw_set_access_mode(p, BRW_ALIGN_1);
             brw_svb_write(p,
                           final_write ? c->reg.temp : brw_null_reg(), /* dest 
*/
                           1, /* msg_reg_nr */
diff --git a/src/mesa/drivers/dri/i965/gen7_sol_state.c 
b/src/mesa/drivers/dri/i965/gen7_sol_state.c
index 7346866..df6b9ee 100644
--- a/src/mesa/drivers/dri/i965/gen7_sol_state.c
+++ b/src/mesa/drivers/dri/i965/gen7_sol_state.c
@@ -122,14 +122,21 @@ upload_3dstate_so_decl_list(struct brw_context *brw,
       int buffer = linked_xfb_info->Outputs[i].OutputBuffer;
       uint16_t decl = 0;
       int vert_result = linked_xfb_info->Outputs[i].OutputRegister;
+      unsigned component_mask =
+         (1 << linked_xfb_info->Outputs[i].NumComponents) - 1;
+
+      /* gl_PointSize is stored in VERT_RESULT_PSIZ.w. */
+      if (vert_result == VERT_RESULT_PSIZ) {
+         assert(linked_xfb_info->Outputs[i].NumComponents == 1);
+         component_mask <<= 3;
+      }
 
       buffer_mask |= 1 << buffer;
 
       decl |= buffer << SO_DECL_OUTPUT_BUFFER_SLOT_SHIFT;
       decl |= vue_map->vert_result_to_slot[vert_result] <<
         SO_DECL_REGISTER_INDEX_SHIFT;
-      decl |= ((1 << linked_xfb_info->Outputs[i].NumComponents) - 1) <<
-        SO_DECL_COMPONENT_MASK_SHIFT;
+      decl |= component_mask << SO_DECL_COMPONENT_MASK_SHIFT;
 
       /* This assert should be true until GL_ARB_transform_feedback_instanced
        * is added and we start using the hole flag.
-- 
1.7.6.4

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to