+ return ac_build_gather_values(&ctx->ac, result, 2);
+}
+
+static void
+visit_emit_vertex(struct nir_to_llvm_context *ctx,
+ nir_intrinsic_instr *instr)
+{
+ LLVMValueRef gs_next_vertex;
+ LLVMValueRef can_emit, kill;
+ LLVMValueRef args[2];
+ int idx;
+
+ assert(instr->const_index[0] == 0);
+ /* Write vertex attribute values to GSVS ring */
+ gs_next_vertex = LLVMBuildLoad(ctx->builder,
+ ctx->gs_next_vertex,
+ "");
+
+ /* If this thread has already emitted the declared maximum number of
+ * vertices, kill it: excessive vertex emissions are not supposed to
+ * have any effect, and GS threads have no externally observable
+ * effects other than emitting vertices.
+ */
+ can_emit = LLVMBuildICmp(ctx->builder, LLVMIntULT, gs_next_vertex,
+ LLVMConstInt(ctx->i32, ctx->gs_max_out_vertices, false), "");
+
+ kill = LLVMBuildSelect(ctx->builder, can_emit,
+ LLVMConstReal(ctx->f32, 1.0f),
+ LLVMConstReal(ctx->f32, -1.0f), "");
+ ac_emit_llvm_intrinsic(&ctx->ac, "llvm.AMDGPU.kill",
+ ctx->voidt, &kill, 1, 0);
+
+ /* loop num outputs */
+ idx = 0;
+ for (unsigned i = 0; i < RADEON_LLVM_MAX_OUTPUTS; ++i) {
+ LLVMValueRef *out_ptr = &ctx->outputs[i * 4];
+ if (!(ctx->output_mask & (1ull << i)))
+ continue;
+
+ for (unsigned j = 0; j < 4; j++) {
+ LLVMValueRef out_val = LLVMBuildLoad(ctx->builder,
+ out_ptr[j], "");
+ LLVMValueRef voffset = LLVMConstInt(ctx->i32, (idx * 4 + j) * ctx->gs_max_out_vertices, false);
+ voffset = LLVMBuildAdd(ctx->builder, voffset, gs_next_vertex, "");
+ voffset = LLVMBuildMul(ctx->builder, voffset, LLVMConstInt(ctx->i32, 4, false), "");
+
+ out_val = LLVMBuildBitCast(ctx->builder, out_val, ctx->i32, "");
+
+ build_tbuffer_store(ctx, ctx->gsvs_ring,
+ out_val, 1,
+ voffset, ctx->gs2vs_offset, 0,
+ V_008F0C_BUF_DATA_FORMAT_32,
+ V_008F0C_BUF_NUM_FORMAT_UINT,
+ 1, 0, 1, 1, 0);
+ }
+ idx++;
+ }
+
+ gs_next_vertex = LLVMBuildAdd(ctx->builder, gs_next_vertex,
+ ctx->i32one, "");
+ LLVMBuildStore(ctx->builder, gs_next_vertex, ctx->gs_next_vertex);
+ args[0] = LLVMConstInt(ctx->i32, SENDMSG_GS_OP_EMIT | SENDMSG_GS | (0 << 8), false);
+ args[1] = ctx->gs_wave_id;
+ ac_emit_llvm_intrinsic(&ctx->ac, "llvm.SI.sendmsg",
+ ctx->voidt, args, 2, 0);
+}
+
+static void
+visit_end_primitive(struct nir_to_llvm_context *ctx,
+ nir_intrinsic_instr *instr)
+{
+ LLVMValueRef args[2];
+
+ assert(instr->const_index[0] == 0);
+ args[0] = LLVMConstInt(ctx->i32, SENDMSG_GS_OP_CUT | SENDMSG_GS | (0 << 8), false);
+ args[1] = ctx->gs_wave_id;
+
+ ac_emit_llvm_intrinsic(&ctx->ac, "llvm.SI.sendmsg", ctx->voidt,
+ args, 2, 0);