[Mesa-dev] [PATCH 2/2] i965/gen6/gs: Handle case where a GS doesn't allocate VUE
andrey simiklit
asimiklit.work at gmail.com
Thu Jun 21 13:27:52 UTC 2018
HI all,
Sorry, just ignore this patch with incorrect subject.
I will send correct one shortly.
Regards,
Andrii.
On Thu, Jun 21, 2018 at 4:12 PM, Andrii Simiklit <asimiklit.work at gmail.com>
wrote:
> 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 <andrii.simiklit at globallogic.com>
> ---
> 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 writing to the
> URB,
> - * 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"
> + * which works for both cases by setting the COMPLETE and UNUSED flags
> in
> + * the EOT message.
> */
> this->current_annotation = "gen6 thread end: EOT";
>
> @@ -504,26 +476,12 @@ 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;
> -
> - 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
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20180621/04feb606/attachment-0001.html>
More information about the mesa-dev
mailing list