Geometry shaders that run in "DUAL_INSTANCED" mode store their inputs in vec4's. This means that when compiling gl_PointSize input swizzling (a MOV instruction which uses a geometry shader input as both source and destination), we need to do two things:
- Set force_writemask_all to ensure that the MOV happens regardless of which channels are enabled. - Set the source register region to <4;4,1> (instead of <0;4,1> to satisfy register region restrictions. --- src/mesa/drivers/dri/i965/brw_vec4_generator.cpp | 17 ++++++++++++++++- src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp | 8 +++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp b/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp index 1b597b5..700da54 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_generator.cpp @@ -858,7 +858,22 @@ vec4_generator::generate_vec4_instruction(vec4_instruction *instruction, switch (inst->opcode) { case BRW_OPCODE_MOV: - brw_MOV(p, dst, src[0]); + if (dst.width == BRW_WIDTH_4) { + /* This happens in attribute fixups for "dual instanced" geometry + * shaders, since they use attributes that are vec4's. Since the + * exec width is only 4, it's essential that the caller set + * force_writemask_all in order to make sure the MOV happens + * regardless of which channels are enabled. + */ + assert(inst->force_writemask_all); + + /* To satisfy register region restrictions, the source needs a stride + * of <4;4,1>. + */ + brw_MOV(p, dst, stride(src[0], 4, 4, 1)); + } else { + brw_MOV(p, dst, src[0]); + } break; case BRW_OPCODE_ADD: brw_ADD(p, dst, src[0], src[1]); diff --git a/src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp index 2be2666..5b823c4 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp @@ -210,7 +210,13 @@ vec4_gs_visitor::emit_prolog() src_reg src(dst); dst.writemask = WRITEMASK_X; src.swizzle = BRW_SWIZZLE_WWWW; - emit(MOV(dst, src)); + inst = emit(MOV(dst, src)); + + /* In dual instanced dispatch mode, dst has a width of 4, so we need + * to make sure the MOV happens regardless of which channels are + * enabled. + */ + inst->force_writemask_all = true; } } -- 1.8.4.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev