We can not use the VUE Dereference flags combination for EOT
message under ILK and SNB because the threads are not initialized
there with initial VUE handle unlike Pre-IL.
So to avoid GPU hangs on SNB and ILK we need
to avoid usage of the VUE Dereference flags combination.
(Was tested only on SNB but according to specification
https://01.org/sites/default/files/documentation/snb_ihd_os_vol2_part1_0.pdf
sections: 1.6.5.3, 1.6.5.6
the ILK must behave itself in the similar way)

Signed-off-by: Andrii Simiklit <andrii.simik...@globallogic.com>
---
 src/intel/compiler/gen6_gs_visitor.cpp | 53 ++++++++++++++++++++++++++++++----
 1 file changed, 47 insertions(+), 6 deletions(-)

diff --git a/src/intel/compiler/gen6_gs_visitor.cpp 
b/src/intel/compiler/gen6_gs_visitor.cpp
index 66c69fb..2143fd2 100644
--- a/src/intel/compiler/gen6_gs_visitor.cpp
+++ b/src/intel/compiler/gen6_gs_visitor.cpp
@@ -300,10 +300,11 @@ gen6_gs_visitor::emit_urb_write_opcode(bool complete, int 
base_mrf,
       /* Otherwise we always request to allocate a new VUE handle. If this is
        * the last write before the EOT message and the new handle never gets
        * used it will be dereferenced when we send the EOT message. This is
-       * necessary to avoid different setups for the EOT message (one for the
+       * necessary to avoid different setups (under Pre-IL only) for the EOT 
message (one for the
        * case when there is no output and another for the case when there is)
        * which would require to end the program with an IF/ELSE/ENDIF block,
-       * something we do not want.
+       * something we do not want. 
+       * But for ILK and SNB we can not avoid the end the program with an 
IF/ELSE/ENDIF block.
        */
       inst = emit(GS_OPCODE_URB_WRITE_ALLOCATE);
       inst->urb_write_flags = BRW_URB_WRITE_COMPLETE;
@@ -449,8 +450,12 @@ gen6_gs_visitor::emit_thread_end()
       if (prog->info.has_transform_feedback_varyings)
          xfb_write();
    }
-   emit(BRW_OPCODE_ENDIF);
-
+   enum { GEN5_ILK = 5 };
+   const bool common_eot_approach_can_be_used = (devinfo->gen < GEN5_ILK);
+   if(common_eot_approach_can_be_used)
+   {
+      emit(BRW_OPCODE_ENDIF);  
+   }
    /* Finally, emit EOT message.
     *
     * In gen6 we need to end the thread differently depending on whether we 
have
@@ -463,8 +468,30 @@ gen6_gs_visitor::emit_thread_end()
     * VUE handle every time we do a URB WRITE, even for the last vertex we 
emit.
     * With this we make sure that whether we have emitted at least one vertex
     * or none at all, we have to finish the thread without writing to the URB,
-    * which works for both cases by setting the COMPLETE and UNUSED flags in
+    * which works for both cases (but only under Pre-IL) by setting the 
COMPLETE and UNUSED flags in
     * the EOT message.
+    * 
+    * But under ILK or SNB we must not use combination COMPLETE and UNUSED 
+    * because this combination could be used only for already allocated VUE. 
+    * But unlike Pre-IL in the ILK and SNB the initial VUE is not passed to 
threads. 
+    * This behaver mentioned in specification: 
+    * SNB (gen6) Spec: 
https://01.org/sites/default/files/documentation/snb_ihd_os_vol2_part1_0.pdf
+    *    1.6.5.3 VUE Allocation (GS, CLIP) [DevIL]
+    *    1.6.5.4 VUE Allocation (GS) [DevSNB+]
+    *       The threads are not passed an initial handle.  
+    *       Instead, they request a first handle (if any) 
+    *       via the URB shared function’s FF_SYNC message (see Shared 
Functions). 
+    *       If additional handles are required, 
+    *       the URB_WRITE allocate mechanism (mentioned above) is used. 
+    * 
+    * So for ILK and for SNB we must use only UNUSED flag.
+    * This is accepteble combination according to:
+    *    SNB (gen6) Spec: 
https://01.org/sites/default/files/documentation/snb_ihd_os_vol4_part2_0.pdf
+    *       2.4.2 Message Descriptor
+    *          "Table lists the valid and invalid combinations of the 
Complete, Used, Allocate and EOT bits"
+    *          "Thread terminate non-write of URB"
+    *    SNB (gen6) Spec: 
https://01.org/sites/default/files/documentation/snb_ihd_os_vol2_part1_0.pdf
+    *       1.6.5.6 Thread Termination
     */
    this->current_annotation = "gen6 thread end: EOT";
 
@@ -480,8 +507,22 @@ gen6_gs_visitor::emit_thread_end()
    inst->urb_write_flags = BRW_URB_WRITE_COMPLETE | BRW_URB_WRITE_UNUSED;
    inst->base_mrf = base_mrf;
    inst->mlen = 1;
-}
+   
+   if(!common_eot_approach_can_be_used)
+   {
+      emit(BRW_OPCODE_ELSE);
+      
+      this->current_annotation = "gen6 thread end: EOT";
+
+      vec4_instruction *unused_urb_inst = emit(GS_OPCODE_THREAD_END);
+      unused_urb_inst->urb_write_flags = BRW_URB_WRITE_UNUSED;
+      unused_urb_inst->base_mrf = base_mrf;
+      unused_urb_inst->mlen = 1;
 
+      emit(BRW_OPCODE_ENDIF);  
+   }
+}
+   
 void
 gen6_gs_visitor::setup_payload()
 {
-- 
2.7.4

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

Reply via email to