+ brw_gs_alloc_regs(c, num_verts);
+ brw_gs_initialize_header(c);
+
+ brw_gs_ff_sync(c, 1);
+
+ brw_gs_overwrite_header_dw2_from_r0(c);
+ switch (num_verts) {
+ case 1:
+ brw_gs_offset_header_dw2(c, URB_WRITE_PRIM_START | URB_WRITE_PRIM_END);
+ brw_gs_emit_vue(c, c->reg.vertex[0], true);
+ break;
+ case 2:
+ brw_gs_offset_header_dw2(c, URB_WRITE_PRIM_START);
+ brw_gs_emit_vue(c, c->reg.vertex[0], false);
+ brw_gs_offset_header_dw2(c, URB_WRITE_PRIM_END - URB_WRITE_PRIM_START);
+ brw_gs_emit_vue(c, c->reg.vertex[1], true);
+ break;
+ case 3:
+ if (check_edge_flags) {
+ /* Only emit vertices 0 and 1 if this is the first triangle of the
+ * polygon. Otherwise they are redundant.
+ */
+ brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
+ brw_AND(p, retype(brw_null_reg(), BRW_REGISTER_TYPE_UD),
+ get_element_ud(c->reg.R0, 2),
+ brw_imm_ud(BRW_GS_EDGE_INDICATOR_0));
+ brw_IF(p, BRW_EXECUTE_1);
+ }
+ brw_gs_offset_header_dw2(c, URB_WRITE_PRIM_START);
+ brw_gs_emit_vue(c, c->reg.vertex[0], false);
+ brw_gs_offset_header_dw2(c, -URB_WRITE_PRIM_START);
+ brw_gs_emit_vue(c, c->reg.vertex[1], false);
+ if (check_edge_flags) {
+ brw_ENDIF(p);
+ /* Only emit vertex 2 in PRIM_END mode if this is the last triangle
+ * of the polygon. Otherwise leave the primitive incomplete because
+ * there are more polygon vertices coming.
+ */
+ brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
+ brw_AND(p, retype(brw_null_reg(), BRW_REGISTER_TYPE_UD),
+ get_element_ud(c->reg.R0, 2),
+ brw_imm_ud(BRW_GS_EDGE_INDICATOR_1));
+ brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
+ }
+ brw_gs_offset_header_dw2(c, URB_WRITE_PRIM_END);
+ brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+ brw_gs_emit_vue(c, c->reg.vertex[2], true);
+ break;
+ }