<div dir="ltr">HI all,<br><br>Sorry, just ignore this patch with incorrect subject.<br>I will send correct one shortly.<br><br>Regards,<br>Andrii.<br><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Jun 21, 2018 at 4:12 PM, Andrii Simiklit <span dir="ltr"><<a href="mailto:asimiklit.work@gmail.com" target="_blank">asimiklit.work@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">We can not use the VUE Dereference flags combination for EOT<br>
message under ILK and SNB because the threads are not initialized<br>
there with initial VUE handle unlike Pre-IL.<br>
So to avoid GPU hangs on SNB and ILK we need<br>
to avoid usage of the VUE Dereference flags combination.<br>
(Was tested only on SNB but according to the specification<br>
SNB Volume 2 Part 1: 1.6.5.3, 1.6.5.6<br>
the ILK must behave itself in the similar way)<br>
<br>
v2: Approach to fix this issue was changed.<br>
Instead of different EOT flags in the program end<br>
we will create VUE every time even if GS produces no output.<br>
<br>
Bugzilla: <a href="https://bugs.freedesktop.org/show_bug.cgi?id=105399" rel="noreferrer" target="_blank">https://bugs.freedesktop.org/s<wbr>how_bug.cgi?id=105399</a><br>
<br>
Signed-off-by: Andrii Simiklit <<a href="mailto:andrii.simiklit@globallogic.com" target="_blank">andrii.simiklit@globallogic.c<wbr>om</a>><br>
---<br>
 src/intel/compiler/gen6_gs_vi<wbr>sitor.cpp | 88 +++++++++---------------------<wbr>----<br>
 1 file changed, 23 insertions(+), 65 deletions(-)<br>
<br>
diff --git a/src/intel/compiler/gen6_gs_v<wbr>isitor.cpp b/src/intel/compiler/gen6_gs_v<wbr>isitor.cpp<br>
index ac3ba55..b831d33 100644<br>
--- a/src/intel/compiler/gen6_gs_v<wbr>isitor.cpp<br>
+++ b/src/intel/compiler/gen6_gs_v<wbr>isitor.cpp<br>
@@ -300,11 +300,10 @@ gen6_gs_visitor::emit_urb_writ<wbr>e_opcode(bool complete, int base_mrf,<br>
       /* Otherwise we always request to allocate a new VUE handle. If this is<br>
        * the last write before the EOT message and the new handle never gets<br>
        * used it will be dereferenced when we send the EOT message. This is<br>
-       * necessary to avoid different setups (under Pre-IL only) for the EOT message (one for the<br>
+       * necessary to avoid different setups for the EOT message (one for the<br>
        * case when there is no output and another for the case when there is)<br>
        * which would require to end the program with an IF/ELSE/ENDIF block,<br>
-       * something we do not want. <br>
-       * But for ILK and SNB we can not avoid the end the program with an IF/ELSE/ENDIF block.<br>
+       * something we do not want.<br>
        */<br>
       inst = emit(GS_OPCODE_URB_WRITE_ALLOC<wbr>ATE);<br>
       inst->urb_write_flags = BRW_URB_WRITE_COMPLETE;<br>
@@ -351,27 +350,27 @@ gen6_gs_visitor::emit_thread_e<wbr>nd()<br>
    int max_usable_mrf = FIRST_SPILL_MRF(devinfo->gen);<br>
<br>
    /* Issue the FF_SYNC message and obtain the initial VUE handle. */<br>
-   emit(CMP(dst_null_ud(), this->vertex_count, brw_imm_ud(0u), BRW_CONDITIONAL_G));<br>
-   emit(IF(BRW_PREDICATE_NORMAL)<wbr>);<br>
-   {<br>
-      this->current_annotation = "gen6 thread end: ff_sync";<br>
+   this->current_annotation = "gen6 thread end: ff_sync";<br>
<br>
-      vec4_instruction *inst;<br>
-      if (prog->info.has_transform_feed<wbr>back_varyings) {<br>
+   vec4_instruction *inst = NULL;<br>
+   if (prog->info.has_transform_feed<wbr>back_varyings) {<br>
          src_reg sol_temp(this, glsl_type::uvec4_type);<br>
          emit(GS_OPCODE_FF_SYNC_SET_PRI<wbr>MITIVES,<br>
-              dst_reg(this->svbi),<br>
-              this->vertex_count,<br>
-              this->prim_count,<br>
-              sol_temp);<br>
+               dst_reg(this->svbi),<br>
+               this->vertex_count,<br>
+               this->prim_count,<br>
+               sol_temp);<br>
          inst = emit(GS_OPCODE_FF_SYNC,<br>
                      dst_reg(this->temp), this->prim_count, this->svbi);<br>
-      } else {<br>
+   } else {<br>
          inst = emit(GS_OPCODE_FF_SYNC,<br>
                      dst_reg(this->temp), this->prim_count, brw_imm_ud(0u));<br>
-      }<br>
-      inst->base_mrf = base_mrf;<br>
+   }<br>
+   inst->base_mrf = base_mrf;<br>
<br>
+   emit(CMP(dst_null_ud(), this->vertex_count, brw_imm_ud(0u), BRW_CONDITIONAL_G));<br>
+   emit(IF(BRW_PREDICATE_NORMAL)<wbr>);<br>
+   {<br>
       /* Loop over all buffered vertices and emit URB write messages */<br>
       this->current_annotation = "gen6 thread end: urb writes init";<br>
       src_reg vertex(this, glsl_type::uint_type);<br>
@@ -415,7 +414,7 @@ gen6_gs_visitor::emit_thread_e<wbr>nd()<br>
                dst_reg reg = dst_reg(MRF, mrf);<br>
                reg.type = output_reg[varying][0].type;<br>
                data.type = reg.type;<br>
-               vec4_instruction *inst = emit(MOV(reg, data));<br>
+               inst = emit(MOV(reg, data));<br>
                inst->force_writemask_all = true;<br>
<br>
                mrf++;<br>
@@ -450,11 +449,8 @@ gen6_gs_visitor::emit_thread_e<wbr>nd()<br>
       if (prog->info.has_transform_feed<wbr>back_varyings)<br>
          xfb_write();<br>
    }<br>
-   const bool common_eot_approach_can_be_use<wbr>d = (devinfo->gen < 5);<br>
-   if(common_eot_approach_can_<wbr>be_used)<br>
-   {<br>
-      emit(BRW_OPCODE_ENDIF);  <br>
-   }<br>
+   emit(BRW_OPCODE_ENDIF);<br>
+<br>
    /* Finally, emit EOT message.<br>
     *<br>
     * In gen6 we need to end the thread differently depending on whether we have<br>
@@ -464,35 +460,11 @@ gen6_gs_visitor::emit_thread_e<wbr>nd()<br>
     *<br>
     * However, this would lead us to end the program with an ENDIF opcode,<br>
     * which we want to avoid, so what we do is that we always request a new<br>
-    * VUE handle every time we do a URB WRITE, even for the last vertex we emit.<br>
+    * VUE handle every time, even if GS produces no output.<br>
     * With this we make sure that whether we have emitted at least one vertex<br>
     * or none at all, we have to finish the thread without writing to the URB,<br>
-    * which works for both cases (but only under Pre-IL) by setting <br>
-    * the COMPLETE and UNUSED flags in the EOT message.<br>
-    * <br>
-    * But under ILK or SNB we must not use combination COMPLETE and UNUSED <br>
-    * because this combination could be used only for already allocated VUE. <br>
-    * But unlike Pre-IL in the ILK and SNB <br>
-    * the initial VUE is not passed to threads. <br>
-    * This behaver mentioned in specification: <br>
-    * SNB Volume 2 Part 1:<br>
-    *  "1.6.5.3 VUE Allocation (GS, CLIP) [DevIL]"<br>
-    *  "1.6.5.4 VUE Allocation (GS) [DevSNB+]"<br>
-    *     "The threads are not passed an initial handle.  <br>
-    *     Instead, they request a first handle (if any) <br>
-    *     via the URB shared function’s FF_SYNC message (see Shared Functions). <br>
-    *     If additional handles are required, <br>
-    *     the URB_WRITE allocate mechanism (mentioned above) is used."<br>
-    * <br>
-    * So for ILK and for SNB we must use only UNUSED flag.<br>
-    * This is accepteble combination according to:<br>
-    *    SNB Volume 4 Part 2:<br>
-    *       "2.4.2 Message Descriptor"<br>
-    *          "Table lists the valid and invalid combinations of <br>
-    *           the Complete, Used, Allocate and EOT bits"<br>
-    *          "Thread terminate non-write of URB"<br>
-    *    SNB Volume 2 Part 1:<br>
-    *       "1.6.5.6 Thread Termination"<br>
+    * which works for both cases by setting the COMPLETE and UNUSED flags in<br>
+    * the EOT message.<br>
     */<br>
    this->current_annotation = "gen6 thread end: EOT";<br>
<br>
@@ -504,26 +476,12 @@ gen6_gs_visitor::emit_thread_e<wbr>nd()<br>
       emit(GS_OPCODE_SET_DWORD_2, dst_reg(MRF, base_mrf), data);<br>
    }<br>
<br>
-   vec4_instruction *inst = emit(GS_OPCODE_THREAD_END);<br>
+   inst = emit(GS_OPCODE_THREAD_END);<br>
    inst->urb_write_flags = BRW_URB_WRITE_COMPLETE | BRW_URB_WRITE_UNUSED;<br>
    inst->base_mrf = base_mrf;<br>
    inst->mlen = 1;<br>
-   <br>
-   if(!common_eot_approach_can_b<wbr>e_used)<br>
-   {<br>
-      emit(BRW_OPCODE_ELSE);<br>
-      <br>
-      this->current_annotation = "gen6 thread end: EOT";<br>
-<br>
-      vec4_instruction *unused_urb_inst = emit(GS_OPCODE_THREAD_END);<br>
-      unused_urb_inst->urb_write_fla<wbr>gs = BRW_URB_WRITE_UNUSED;<br>
-      unused_urb_inst->base_mrf = base_mrf;<br>
-      unused_urb_inst->mlen = 1;<br>
-<br>
-      emit(BRW_OPCODE_ENDIF);  <br>
-   }<br>
 }<br>
-   <br>
+<br>
 void<br>
 gen6_gs_visitor::setup_payloa<wbr>d()<br>
 {<br>
<span class="gmail-m_2809284023125269520gmail-HOEnZb"><font color="#888888">-- <br>
2.7.4<br>
<br>
</font></span></blockquote></div><br></div></div>