void vec4_gs_visitor::emit_thread_end() { if (c->control_data_header_size_bits > 0) { /* During shader execution, we only ever call emit_control_data_bits() * just prior to outputting a vertex. Therefore, the control data bits * corresponding to the most recently output vertex still need to be * emitted. */ current_annotation = "thread end: emit control data bits"; emit_control_data_bits(); } /* MRF 0 is reserved for the debugger, so start with message header * in MRF 1. */ int base_mrf = 1; current_annotation = "thread end"; dst_reg mrf_reg(MRF, base_mrf); src_reg r0(retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UD)); vec4_instruction *inst = emit(MOV(mrf_reg, r0)); inst->force_writemask_all = true; emit(GS_OPCODE_SET_VERTEX_COUNT, mrf_reg, this->vertex_count); if (INTEL_DEBUG & DEBUG_SHADER_TIME) emit_shader_time_end(); inst = emit(GS_OPCODE_THREAD_END); inst->base_mrf = base_mrf; inst->mlen = 1; }
void vec4_tcs_visitor::emit_thread_end() { vec4_instruction *inst; current_annotation = "thread end"; if (nir->info->tcs.vertices_out % 2) { emit(BRW_OPCODE_ENDIF); } if (devinfo->gen == 7) { struct brw_tcs_prog_data *tcs_prog_data = (struct brw_tcs_prog_data *) prog_data; current_annotation = "release input vertices"; /* Synchronize all threads, so we know that no one is still * using the input URB handles. */ if (tcs_prog_data->instances > 1) { dst_reg header = dst_reg(this, glsl_type::uvec4_type); emit(TCS_OPCODE_CREATE_BARRIER_HEADER, header); emit(SHADER_OPCODE_BARRIER, dst_null_ud(), src_reg(header)); } /* Make thread 0 (invocations <1, 0>) release pairs of ICP handles. * We want to compare the bottom half of invocation_id with 0, but * use that truth value for the top half as well. Unfortunately, * we don't have stride in the vec4 world, nor UV immediates in * align16, so we need an opcode to get invocation_id<0,4,0>. */ set_condmod(BRW_CONDITIONAL_Z, emit(TCS_OPCODE_SRC0_010_IS_ZERO, dst_null_d(), invocation_id)); emit(IF(BRW_PREDICATE_NORMAL)); for (unsigned i = 0; i < key->input_vertices; i += 2) { /* If we have an odd number of input vertices, the last will be * unpaired. We don't want to use an interleaved URB write in * that case. */ const bool is_unpaired = i == key->input_vertices - 1; dst_reg header(this, glsl_type::uvec4_type); emit(TCS_OPCODE_RELEASE_INPUT, header, brw_imm_ud(i), brw_imm_ud(is_unpaired)); } emit(BRW_OPCODE_ENDIF); } if (unlikely(INTEL_DEBUG & DEBUG_SHADER_TIME)) emit_shader_time_end(); inst = emit(TCS_OPCODE_THREAD_END); inst->base_mrf = 14; inst->mlen = 2; }
vec4_instruction * vec4_vs_visitor::emit_urb_write_opcode(bool complete) { /* For VS, the URB writes end the thread. */ if (complete) { if (INTEL_DEBUG & DEBUG_SHADER_TIME) emit_shader_time_end(); } vec4_instruction *inst = emit(VS_OPCODE_URB_WRITE); inst->urb_write_flags = complete ? BRW_URB_WRITE_EOT_COMPLETE : BRW_URB_WRITE_NO_FLAGS; return inst; }
void vec4_gs_visitor::emit_thread_end() { if (c->control_data_header_size_bits > 0) { /* During shader execution, we only ever call emit_control_data_bits() * just prior to outputting a vertex. Therefore, the control data bits * corresponding to the most recently output vertex still need to be * emitted. */ current_annotation = "thread end: emit control data bits"; emit_control_data_bits(); } /* MRF 0 is reserved for the debugger, so start with message header * in MRF 1. */ int base_mrf = 1; bool static_vertex_count = gs_prog_data->static_vertex_count != -1; /* If the previous instruction was a URB write, we don't need to issue * a second one - we can just set the EOT bit on the previous write. * * Skip this on Gen8+ unless there's a static vertex count, as we also * need to write the vertex count out, and combining the two may not be * possible (or at least not straightforward). */ vec4_instruction *last = (vec4_instruction *) instructions.get_tail(); if (last && last->opcode == GS_OPCODE_URB_WRITE && !(INTEL_DEBUG & DEBUG_SHADER_TIME) && devinfo->gen >= 8 && static_vertex_count) { last->urb_write_flags = BRW_URB_WRITE_EOT | last->urb_write_flags; return; } current_annotation = "thread end"; dst_reg mrf_reg(MRF, base_mrf); src_reg r0(retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UD)); vec4_instruction *inst = emit(MOV(mrf_reg, r0)); inst->force_writemask_all = true; if (devinfo->gen < 8 || !static_vertex_count) emit(GS_OPCODE_SET_VERTEX_COUNT, mrf_reg, this->vertex_count); if (INTEL_DEBUG & DEBUG_SHADER_TIME) emit_shader_time_end(); inst = emit(GS_OPCODE_THREAD_END); inst->base_mrf = base_mrf; inst->mlen = devinfo->gen >= 8 && !static_vertex_count ? 2 : 1; }