ec7629514a7f18fc23a351045cdb1ff4c9592077
[mesa.git] / src / gallium / drivers / radeonsi / si_shader_llvm_build.c
1 /*
2 * Copyright 2017 Advanced Micro Devices, Inc.
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * on the rights to use, copy, modify, merge, publish, distribute, sub
9 * license, and/or sell copies of the Software, and to permit persons to whom
10 * the Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22 * USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 #include "si_shader_internal.h"
26 #include "si_pipe.h"
27 #include "sid.h"
28
29 /**
30 * Load a dword from a constant buffer.
31 */
32 LLVMValueRef si_buffer_load_const(struct si_shader_context *ctx,
33 LLVMValueRef resource, LLVMValueRef offset)
34 {
35 return ac_build_buffer_load(&ctx->ac, resource, 1, NULL, offset, NULL,
36 0, 0, true, true);
37 }
38
39 void si_llvm_build_ret(struct si_shader_context *ctx, LLVMValueRef ret)
40 {
41 if (LLVMGetTypeKind(LLVMTypeOf(ret)) == LLVMVoidTypeKind)
42 LLVMBuildRetVoid(ctx->ac.builder);
43 else
44 LLVMBuildRet(ctx->ac.builder, ret);
45 }
46
47 LLVMValueRef si_insert_input_ret(struct si_shader_context *ctx, LLVMValueRef ret,
48 struct ac_arg param, unsigned return_index)
49 {
50 return LLVMBuildInsertValue(ctx->ac.builder, ret,
51 ac_get_arg(&ctx->ac, param),
52 return_index, "");
53 }
54
55 LLVMValueRef si_insert_input_ret_float(struct si_shader_context *ctx, LLVMValueRef ret,
56 struct ac_arg param, unsigned return_index)
57 {
58 LLVMBuilderRef builder = ctx->ac.builder;
59 LLVMValueRef p = ac_get_arg(&ctx->ac, param);
60
61 return LLVMBuildInsertValue(builder, ret,
62 ac_to_float(&ctx->ac, p),
63 return_index, "");
64 }
65
66 LLVMValueRef si_insert_input_ptr(struct si_shader_context *ctx, LLVMValueRef ret,
67 struct ac_arg param, unsigned return_index)
68 {
69 LLVMBuilderRef builder = ctx->ac.builder;
70 LLVMValueRef ptr = ac_get_arg(&ctx->ac, param);
71 ptr = LLVMBuildPtrToInt(builder, ptr, ctx->ac.i32, "");
72 return LLVMBuildInsertValue(builder, ret, ptr, return_index, "");
73 }
74
75 LLVMValueRef si_prolog_get_rw_buffers(struct si_shader_context *ctx)
76 {
77 LLVMValueRef ptr[2], list;
78 bool merged_shader = si_is_merged_shader(ctx);
79
80 ptr[0] = LLVMGetParam(ctx->main_fn, (merged_shader ? 8 : 0) + SI_SGPR_RW_BUFFERS);
81 list = LLVMBuildIntToPtr(ctx->ac.builder, ptr[0],
82 ac_array_in_const32_addr_space(ctx->ac.v4i32), "");
83 return list;
84 }
85
86 LLVMValueRef si_build_gather_64bit(struct si_shader_context *ctx,
87 LLVMTypeRef type, LLVMValueRef val1,
88 LLVMValueRef val2)
89 {
90 LLVMValueRef values[2] = {
91 ac_to_integer(&ctx->ac, val1),
92 ac_to_integer(&ctx->ac, val2),
93 };
94 LLVMValueRef result = ac_build_gather_values(&ctx->ac, values, 2);
95 return LLVMBuildBitCast(ctx->ac.builder, result, type, "");
96 }
97
98 void si_llvm_emit_barrier(struct si_shader_context *ctx)
99 {
100 /* GFX6 only (thanks to a hw bug workaround):
101 * The real barrier instruction isn’t needed, because an entire patch
102 * always fits into a single wave.
103 */
104 if (ctx->screen->info.chip_class == GFX6 &&
105 ctx->type == PIPE_SHADER_TESS_CTRL) {
106 ac_build_waitcnt(&ctx->ac, AC_WAIT_LGKM | AC_WAIT_VLOAD | AC_WAIT_VSTORE);
107 return;
108 }
109
110 ac_build_s_barrier(&ctx->ac);
111 }
112
113 /* Ensure that the esgs ring is declared.
114 *
115 * We declare it with 64KB alignment as a hint that the
116 * pointer value will always be 0.
117 */
118 void si_llvm_declare_esgs_ring(struct si_shader_context *ctx)
119 {
120 if (ctx->esgs_ring)
121 return;
122
123 assert(!LLVMGetNamedGlobal(ctx->ac.module, "esgs_ring"));
124
125 ctx->esgs_ring = LLVMAddGlobalInAddressSpace(
126 ctx->ac.module, LLVMArrayType(ctx->ac.i32, 0),
127 "esgs_ring",
128 AC_ADDR_SPACE_LDS);
129 LLVMSetLinkage(ctx->esgs_ring, LLVMExternalLinkage);
130 LLVMSetAlignment(ctx->esgs_ring, 64 * 1024);
131 }