[Mesa-dev] [PATCH] intel/decoder: fix the possible out of bounds group_iter

2018-08-09 Thread Andrii Simiklit
The "gen_group_get_length" function can return a negative value
and it can lead to the out of bounds group_iter.

Signed-off-by: Andrii Simiklit 
---
 src/intel/common/gen_decoder.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/intel/common/gen_decoder.c b/src/intel/common/gen_decoder.c
index ec0a486..f09bd87 100644
--- a/src/intel/common/gen_decoder.c
+++ b/src/intel/common/gen_decoder.c
@@ -803,8 +803,10 @@ static bool
 iter_more_groups(const struct gen_field_iterator *iter)
 {
if (iter->group->variable) {
-  return iter_group_offset_bits(iter, iter->group_iter + 1) <
-  (gen_group_get_length(iter->group, iter->p) * 32);
+  const int length = gen_group_get_length(iter->group, iter->p);
+  return length > 0 &&
+ iter_group_offset_bits(iter, iter->group_iter + 1) <
+  (length * 32);
} else {
   return (iter->group_iter + 1) < iter->group->group_count ||
  iter->group->next != NULL;
-- 
2.7.4

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


[Mesa-dev] [PATCH] i965/tex: ignore the diff between GL_TEXTURE_2D and GL_TEXTURE_RECTANGLE

2018-07-10 Thread Andrii Simiklit
the difference between GL_TEXTURE_2D and GL_TEXTURE_RECTANGLE
doesn't matter as far as the miptree is concerned;
genX(update_sampler_state) only looks at the
gl_texture_object and not the miptree when determining whether or
not to use normalized coordinates.

Signed-off-by: Andrii Simiklit 

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=107117

---
 src/mesa/drivers/dri/i965/intel_mipmap_tree.c | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c 
b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
index 7d1fa96..dc45a06 100644
--- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
+++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
@@ -58,6 +58,12 @@ static void *intel_miptree_map_raw(struct brw_context *brw,
 
 static void intel_miptree_unmap_raw(struct intel_mipmap_tree *mt);
 
+static GLenum
+tex_rect_to_tex2d(GLenum val)
+{
+return (GL_TEXTURE_RECTANGLE == val) ? GL_TEXTURE_2D : val;
+}
+
 static bool
 intel_miptree_supports_mcs(struct brw_context *brw,
const struct intel_mipmap_tree *mt)
@@ -1320,13 +1326,15 @@ intel_miptree_match_image(struct intel_mipmap_tree *mt,
 {
struct intel_texture_image *intelImage = intel_texture_image(image);
GLuint level = intelImage->base.Base.Level;
+   GLenum texObjTarget = tex_rect_to_tex2d(mt->target);
+   GLenum mipmapTreeTarget = tex_rect_to_tex2d(image->TexObject->Target);
int width, height, depth;
 
/* glTexImage* choose the texture object based on the target passed in, and
 * objects can't change targets over their lifetimes, so this should be
 * true.
 */
-   assert(image->TexObject->Target == mt->target);
+   assert(texObjTarget == mipmapTreeTarget);
 
mesa_format mt_format = mt->format;
if (mt->format == MESA_FORMAT_Z24_UNORM_X8_UINT && mt->stencil_mt)
-- 
2.7.4

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


[Mesa-dev] [PATCH v3] i965/gen6/gs: Handle case where a GS doesn't allocate VUE

2018-06-22 Thread Andrii Simiklit
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 the specification
SNB Volume 2 Part 1: 1.6.5.3, 1.6.5.6
the ILK must behave itself in the similar way)

v2: Approach to fix this issue was changed.
Instead of different EOT flags in the program end
we will create VUE every time even if GS produces no output.

v3: Clean up the patch.
Signed-off-by: Andrii Simiklit 

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=105399

---
 src/intel/compiler/gen6_gs_visitor.cpp | 42 +-
 1 file changed, 21 insertions(+), 21 deletions(-)

diff --git a/src/intel/compiler/gen6_gs_visitor.cpp 
b/src/intel/compiler/gen6_gs_visitor.cpp
index 66c69fb..c9571cc 100644
--- a/src/intel/compiler/gen6_gs_visitor.cpp
+++ b/src/intel/compiler/gen6_gs_visitor.cpp
@@ -350,27 +350,27 @@ gen6_gs_visitor::emit_thread_end()
int max_usable_mrf = FIRST_SPILL_MRF(devinfo->gen);
 
/* Issue the FF_SYNC message and obtain the initial VUE handle. */
+   this->current_annotation = "gen6 thread end: ff_sync";
+
+   vec4_instruction *inst = NULL;
+   if (prog->info.has_transform_feedback_varyings) {
+  src_reg sol_temp(this, glsl_type::uvec4_type);
+  emit(GS_OPCODE_FF_SYNC_SET_PRIMITIVES,
+   dst_reg(this->svbi),
+   this->vertex_count,
+   this->prim_count,
+   sol_temp);
+  inst = emit(GS_OPCODE_FF_SYNC,
+  dst_reg(this->temp), this->prim_count, this->svbi);
+   } else {
+  inst = emit(GS_OPCODE_FF_SYNC,
+  dst_reg(this->temp), this->prim_count, brw_imm_ud(0u));
+   }
+   inst->base_mrf = base_mrf;
+
emit(CMP(dst_null_ud(), this->vertex_count, brw_imm_ud(0u), 
BRW_CONDITIONAL_G));
emit(IF(BRW_PREDICATE_NORMAL));
{
-  this->current_annotation = "gen6 thread end: ff_sync";
-
-  vec4_instruction *inst;
-  if (prog->info.has_transform_feedback_varyings) {
- src_reg sol_temp(this, glsl_type::uvec4_type);
- emit(GS_OPCODE_FF_SYNC_SET_PRIMITIVES,
-  dst_reg(this->svbi),
-  this->vertex_count,
-  this->prim_count,
-  sol_temp);
- inst = emit(GS_OPCODE_FF_SYNC,
- dst_reg(this->temp), this->prim_count, this->svbi);
-  } else {
- inst = 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 */
   this->current_annotation = "gen6 thread end: urb writes init";
   src_reg vertex(this, glsl_type::uint_type);
@@ -414,7 +414,7 @@ gen6_gs_visitor::emit_thread_end()
dst_reg reg = dst_reg(MRF, mrf);
reg.type = output_reg[varying][0].type;
data.type = reg.type;
-   vec4_instruction *inst = emit(MOV(reg, data));
+   inst = emit(MOV(reg, data));
inst->force_writemask_all = true;
 
mrf++;
@@ -460,7 +460,7 @@ gen6_gs_visitor::emit_thread_end()
 *
 * However, this would lead us to end the program with an ENDIF opcode,
 * which we want to avoid, so what we do is that we always request a new
-* VUE handle every time we do a URB WRITE, even for the last vertex we 
emit.
+* VUE handle every time, even if GS produces no output.
 * 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
@@ -476,7 +476,7 @@ gen6_gs_visitor::emit_thread_end()
   emit(GS_OPCODE_SET_DWORD_2, dst_reg(MRF, base_mrf), data);
}
 
-   vec4_instruction *inst = emit(GS_OPCODE_THREAD_END);
+   inst = emit(GS_OPCODE_THREAD_END);
inst->urb_write_flags = BRW_URB_WRITE_COMPLETE | BRW_URB_WRITE_UNUSED;
inst->base_mrf = base_mrf;
inst->mlen = 1;
-- 
2.7.4

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


[Mesa-dev] [PATCH v2] i965/gen6/gs: Handle case where a GS doesn't allocate VUE

2018-06-21 Thread Andrii Simiklit
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 the specification
SNB Volume 2 Part 1: 1.6.5.3, 1.6.5.6
the ILK must behave itself in the similar way)

v2: Approach to fix this issue was changed.
Instead of different EOT flags in the program end
we will create VUE every time even if GS produces no output.

Signed-off-by: Andrii Simiklit 
---
 src/intel/compiler/gen6_gs_visitor.cpp | 88 +-
 1 file changed, 23 insertions(+), 65 deletions(-)

diff --git a/src/intel/compiler/gen6_gs_visitor.cpp 
b/src/intel/compiler/gen6_gs_visitor.cpp
index ac3ba55..b831d33 100644
--- a/src/intel/compiler/gen6_gs_visitor.cpp
+++ b/src/intel/compiler/gen6_gs_visitor.cpp
@@ -300,11 +300,10 @@ 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 (under Pre-IL only) for the EOT 
message (one for the
+   * necessary to avoid different setups 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. 
-   * But for ILK and SNB we can not avoid the end the program with an 
IF/ELSE/ENDIF block.
+   * something we do not want.
*/
   inst = emit(GS_OPCODE_URB_WRITE_ALLOCATE);
   inst->urb_write_flags = BRW_URB_WRITE_COMPLETE;
@@ -351,27 +350,27 @@ gen6_gs_visitor::emit_thread_end()
int max_usable_mrf = FIRST_SPILL_MRF(devinfo->gen);
 
/* Issue the FF_SYNC message and obtain the initial VUE handle. */
-   emit(CMP(dst_null_ud(), this->vertex_count, brw_imm_ud(0u), 
BRW_CONDITIONAL_G));
-   emit(IF(BRW_PREDICATE_NORMAL));
-   {
-  this->current_annotation = "gen6 thread end: ff_sync";
+   this->current_annotation = "gen6 thread end: ff_sync";
 
-  vec4_instruction *inst;
-  if (prog->info.has_transform_feedback_varyings) {
+   vec4_instruction *inst = NULL;
+   if (prog->info.has_transform_feedback_varyings) {
  src_reg sol_temp(this, glsl_type::uvec4_type);
  emit(GS_OPCODE_FF_SYNC_SET_PRIMITIVES,
-  dst_reg(this->svbi),
-  this->vertex_count,
-  this->prim_count,
-  sol_temp);
+   dst_reg(this->svbi),
+   this->vertex_count,
+   this->prim_count,
+   sol_temp);
  inst = emit(GS_OPCODE_FF_SYNC,
  dst_reg(this->temp), this->prim_count, this->svbi);
-  } else {
+   } else {
  inst = emit(GS_OPCODE_FF_SYNC,
  dst_reg(this->temp), this->prim_count, brw_imm_ud(0u));
-  }
-  inst->base_mrf = base_mrf;
+   }
+   inst->base_mrf = base_mrf;
 
+   emit(CMP(dst_null_ud(), this->vertex_count, brw_imm_ud(0u), 
BRW_CONDITIONAL_G));
+   emit(IF(BRW_PREDICATE_NORMAL));
+   {
   /* Loop over all buffered vertices and emit URB write messages */
   this->current_annotation = "gen6 thread end: urb writes init";
   src_reg vertex(this, glsl_type::uint_type);
@@ -415,7 +414,7 @@ gen6_gs_visitor::emit_thread_end()
dst_reg reg = dst_reg(MRF, mrf);
reg.type = output_reg[varying][0].type;
data.type = reg.type;
-   vec4_instruction *inst = emit(MOV(reg, data));
+   inst = emit(MOV(reg, data));
inst->force_writemask_all = true;
 
mrf++;
@@ -450,11 +449,8 @@ gen6_gs_visitor::emit_thread_end()
   if (prog->info.has_transform_feedback_varyings)
  xfb_write();
}
-   const bool common_eot_approach_can_be_used = (devinfo->gen < 5);
-   if(common_eot_approach_can_be_used)
-   {
-  emit(BRW_OPCODE_ENDIF);  
-   }
+   emit(BRW_OPCODE_ENDIF);
+
/* Finally, emit EOT message.
 *
 * In gen6 we need to end the thread differently depending on whether we 
have
@@ -464,35 +460,11 @@ gen6_gs_visitor::emit_thread_end()
 *
 * However, this would lead us to end the program with an ENDIF opcode,
 * which we want to avoid, so what we do is that we always request a new
-* VUE handle every time we do a URB WRITE, even for the last vertex we 
emit.
+* VUE handle every time, even if GS produces no output.
 * 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 w

[Mesa-dev] [PATCH 2/2] i965/gen6/gs: Handle case where a GS doesn't allocate VUE

2018-06-21 Thread Andrii Simiklit
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 the specification
SNB Volume 2 Part 1: 1.6.5.3, 1.6.5.6
the ILK must behave itself in the similar way)

v2: Approach to fix this issue was changed.
Instead of different EOT flags in the program end
we will create VUE every time even if GS produces no output.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=105399

Signed-off-by: Andrii Simiklit 
---
 src/intel/compiler/gen6_gs_visitor.cpp | 88 +-
 1 file changed, 23 insertions(+), 65 deletions(-)

diff --git a/src/intel/compiler/gen6_gs_visitor.cpp 
b/src/intel/compiler/gen6_gs_visitor.cpp
index ac3ba55..b831d33 100644
--- a/src/intel/compiler/gen6_gs_visitor.cpp
+++ b/src/intel/compiler/gen6_gs_visitor.cpp
@@ -300,11 +300,10 @@ 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 (under Pre-IL only) for the EOT 
message (one for the
+   * necessary to avoid different setups 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. 
-   * But for ILK and SNB we can not avoid the end the program with an 
IF/ELSE/ENDIF block.
+   * something we do not want.
*/
   inst = emit(GS_OPCODE_URB_WRITE_ALLOCATE);
   inst->urb_write_flags = BRW_URB_WRITE_COMPLETE;
@@ -351,27 +350,27 @@ gen6_gs_visitor::emit_thread_end()
int max_usable_mrf = FIRST_SPILL_MRF(devinfo->gen);
 
/* Issue the FF_SYNC message and obtain the initial VUE handle. */
-   emit(CMP(dst_null_ud(), this->vertex_count, brw_imm_ud(0u), 
BRW_CONDITIONAL_G));
-   emit(IF(BRW_PREDICATE_NORMAL));
-   {
-  this->current_annotation = "gen6 thread end: ff_sync";
+   this->current_annotation = "gen6 thread end: ff_sync";
 
-  vec4_instruction *inst;
-  if (prog->info.has_transform_feedback_varyings) {
+   vec4_instruction *inst = NULL;
+   if (prog->info.has_transform_feedback_varyings) {
  src_reg sol_temp(this, glsl_type::uvec4_type);
  emit(GS_OPCODE_FF_SYNC_SET_PRIMITIVES,
-  dst_reg(this->svbi),
-  this->vertex_count,
-  this->prim_count,
-  sol_temp);
+   dst_reg(this->svbi),
+   this->vertex_count,
+   this->prim_count,
+   sol_temp);
  inst = emit(GS_OPCODE_FF_SYNC,
  dst_reg(this->temp), this->prim_count, this->svbi);
-  } else {
+   } else {
  inst = emit(GS_OPCODE_FF_SYNC,
  dst_reg(this->temp), this->prim_count, brw_imm_ud(0u));
-  }
-  inst->base_mrf = base_mrf;
+   }
+   inst->base_mrf = base_mrf;
 
+   emit(CMP(dst_null_ud(), this->vertex_count, brw_imm_ud(0u), 
BRW_CONDITIONAL_G));
+   emit(IF(BRW_PREDICATE_NORMAL));
+   {
   /* Loop over all buffered vertices and emit URB write messages */
   this->current_annotation = "gen6 thread end: urb writes init";
   src_reg vertex(this, glsl_type::uint_type);
@@ -415,7 +414,7 @@ gen6_gs_visitor::emit_thread_end()
dst_reg reg = dst_reg(MRF, mrf);
reg.type = output_reg[varying][0].type;
data.type = reg.type;
-   vec4_instruction *inst = emit(MOV(reg, data));
+   inst = emit(MOV(reg, data));
inst->force_writemask_all = true;
 
mrf++;
@@ -450,11 +449,8 @@ gen6_gs_visitor::emit_thread_end()
   if (prog->info.has_transform_feedback_varyings)
  xfb_write();
}
-   const bool common_eot_approach_can_be_used = (devinfo->gen < 5);
-   if(common_eot_approach_can_be_used)
-   {
-  emit(BRW_OPCODE_ENDIF);  
-   }
+   emit(BRW_OPCODE_ENDIF);
+
/* Finally, emit EOT message.
 *
 * In gen6 we need to end the thread differently depending on whether we 
have
@@ -464,35 +460,11 @@ gen6_gs_visitor::emit_thread_end()
 *
 * However, this would lead us to end the program with an ENDIF opcode,
 * which we want to avoid, so what we do is that we always request a new
-* VUE handle every time we do a URB WRITE, even for the last vertex we 
emit.
+* VUE handle every time, even if GS produces no output.
 * With this we make sure that whether we have emitted at least one vertex

[Mesa-dev] [PATCH] i965/gen6/gs: Handle case where a GS doesn't allocate VUE

2018-06-19 Thread Andrii Simiklit
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 the specification
SNB Volume 2 Part 1: 1.6.5.3, 1.6.5.6
the ILK must behave itself in the similar way)

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=105399

Signed-off-by: Andrii Simiklit 
---
 src/intel/compiler/gen6_gs_visitor.cpp | 56 +-
 1 file changed, 49 insertions(+), 7 deletions(-)

diff --git a/src/intel/compiler/gen6_gs_visitor.cpp 
b/src/intel/compiler/gen6_gs_visitor.cpp
index 66c69fb..ac3ba55 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,11 @@ gen6_gs_visitor::emit_thread_end()
   if (prog->info.has_transform_feedback_varyings)
  xfb_write();
}
-   emit(BRW_OPCODE_ENDIF);
-
+   const bool common_eot_approach_can_be_used = (devinfo->gen < 5);
+   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 +467,32 @@ 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
-* the EOT message.
+* 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 Volume 2 Part 1:
+*  "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 Volume 4 Part 2:
+*   "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 Volume 2 Part 1:
+*   "1.6.5.6 Thread Termination"
 */
this->current_annotation = "gen6 thread end: EOT";
 
@@ -480,8 +508,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


[Mesa-dev] [PATCH] Fix 105399 bug GPU hang on SNB using geometry shader. The end of thread (EOT) message with flags Complete=1 and Used=0 will leads to GPU hang on SNB and ILK when GS does not allocat

2018-06-19 Thread Andrii Simiklit
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 
---
 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

__