i965/gen6/gs: Add an additional parameter to the FF_SYNC opcode.
authorSamuel Iglesias Gonsalvez <siglesias@igalia.com>
Wed, 23 Jul 2014 08:51:35 +0000 (10:51 +0200)
committerIago Toral Quiroga <itoral@igalia.com>
Fri, 19 Sep 2014 13:01:16 +0000 (15:01 +0200)
We will use this parameter in later patches to provide information relevant
to transform feedback that needs to be set as part of the FF_SYNC message.

Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
Acked-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
src/mesa/drivers/dri/i965/brw_defines.h
src/mesa/drivers/dri/i965/brw_vec4.h
src/mesa/drivers/dri/i965/brw_vec4_generator.cpp
src/mesa/drivers/dri/i965/gen6_gs_visitor.cpp

index e4868d1c29219b140fe5e42d727187f2590a3d51..b2216fe9559ccee019fab45f5eb241e0443d7095 100644 (file)
@@ -1028,6 +1028,10 @@ enum opcode {
     *
     * - src0 is the number of primitives written.
     *
+    * - src1 is the value to hold in M0.0: number of SO vertices to write
+    *   and number of SO primitives needed. Its value will be overwritten
+    *   with the SVBI values if transform feedback is enabled.
+    *
     * Note: This opcode uses an implicit MRF register for the ff_sync message
     * header, so the caller is expected to set inst->base_mrf and initialize
     * that MRF register to r0. This opcode will also write to this MRF register
index d3d374d14c2dd6cb5d55a8900a4cae6decf701dc..1909cbd75d69c31c415e08e73dc18b95a57ca0b4 100644 (file)
@@ -675,7 +675,8 @@ private:
                                            struct brw_reg src2);
    void generate_gs_ff_sync(vec4_instruction *inst,
                             struct brw_reg dst,
-                            struct brw_reg src0);
+                            struct brw_reg src0,
+                            struct brw_reg src1);
    void generate_gs_set_primitive_id(struct brw_reg dst);
    void generate_oword_dual_block_offsets(struct brw_reg m1,
                                          struct brw_reg index);
index d1aeeadd102fd1515d4926ebd07d52655b8d984e..88695381045a73814218bf88a98a96dba9ab22ff 100644 (file)
@@ -756,7 +756,8 @@ vec4_generator::generate_gs_ff_sync_set_primitives(struct brw_reg dst,
 void
 vec4_generator::generate_gs_ff_sync(vec4_instruction *inst,
                                     struct brw_reg dst,
-                                    struct brw_reg src0)
+                                    struct brw_reg src0,
+                                    struct brw_reg src1)
 {
    /* This opcode uses an implied MRF register for:
     *  - the header of the ff_sync message. And as such it is expected to be
@@ -766,14 +767,13 @@ vec4_generator::generate_gs_ff_sync(vec4_instruction *inst,
    struct brw_reg header =
       retype(brw_message_reg(inst->base_mrf), BRW_REGISTER_TYPE_UD);
 
-   /* Overwrite dword 0 of the header (cleared for now since we are not doing
-    * transform feedback) and dword 1 (to hold the number of primitives
-    * written).
+   /* Overwrite dword 0 of the header (SO vertices to write) and
+    * dword 1 (number of primitives written).
     */
    brw_push_insn_state(p);
    brw_set_default_mask_control(p, BRW_MASK_DISABLE);
    brw_set_default_access_mode(p, BRW_ALIGN_1);
-   brw_MOV(p, get_element_ud(header, 0), brw_imm_ud(0));
+   brw_MOV(p, get_element_ud(header, 0), get_element_ud(src1, 0));
    brw_MOV(p, get_element_ud(header, 1), get_element_ud(src0, 0));
    brw_pop_insn_state(p);
 
@@ -791,6 +791,11 @@ vec4_generator::generate_gs_ff_sync(vec4_instruction *inst,
    brw_set_default_access_mode(p, BRW_ALIGN_1);
    brw_set_default_mask_control(p, BRW_MASK_DISABLE);
    brw_MOV(p, get_element_ud(header, 0), get_element_ud(dst, 0));
+
+   /* src1 is not an immediate when we use transform feedback */
+   if (src1.file != BRW_IMMEDIATE_VALUE)
+      brw_MOV(p, brw_vec4_grf(src1.nr, 0), brw_vec4_grf(dst.nr, 1));
+
    brw_pop_insn_state(p);
 }
 
@@ -1441,7 +1446,7 @@ vec4_generator::generate_code(const cfg_t *cfg)
          break;
 
       case GS_OPCODE_FF_SYNC:
-         generate_gs_ff_sync(inst, dst, src[0]);
+         generate_gs_ff_sync(inst, dst, src[0], src[1]);
          break;
 
       case GS_OPCODE_FF_SYNC_SET_PRIMITIVES:
index 0da95e5601188638bcc909d331dfb4049aeb2ec0..7a832cac39b9318a5ba0ab7679946a492a9033df 100644 (file)
@@ -331,7 +331,8 @@ gen6_gs_visitor::emit_thread_end()
    {
       this->current_annotation = "gen6 thread end: ff_sync";
       vec4_instruction *inst =
-         emit(GS_OPCODE_FF_SYNC, dst_reg(this->temp), this->prim_count);
+         emit(GS_OPCODE_FF_SYNC, dst_reg(this->temp), this->prim_count,
+              brw_imm_ud(0u));
       inst->base_mrf = base_mrf;
 
       /* Loop over all buffered vertices and emit URB write messages */