2 * Copyright 2017 Advanced Micro Devices, Inc.
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:
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
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.
25 #include "si_shader_internal.h"
30 * Load a dword from a constant buffer.
32 LLVMValueRef
si_buffer_load_const(struct si_shader_context
*ctx
,
33 LLVMValueRef resource
, LLVMValueRef offset
)
35 return ac_build_buffer_load(&ctx
->ac
, resource
, 1, NULL
, offset
, NULL
,
39 void si_llvm_build_ret(struct si_shader_context
*ctx
, LLVMValueRef ret
)
41 if (LLVMGetTypeKind(LLVMTypeOf(ret
)) == LLVMVoidTypeKind
)
42 LLVMBuildRetVoid(ctx
->ac
.builder
);
44 LLVMBuildRet(ctx
->ac
.builder
, ret
);
47 LLVMValueRef
si_insert_input_ret(struct si_shader_context
*ctx
, LLVMValueRef ret
,
48 struct ac_arg param
, unsigned return_index
)
50 return LLVMBuildInsertValue(ctx
->ac
.builder
, ret
,
51 ac_get_arg(&ctx
->ac
, param
),
55 LLVMValueRef
si_insert_input_ret_float(struct si_shader_context
*ctx
, LLVMValueRef ret
,
56 struct ac_arg param
, unsigned return_index
)
58 LLVMBuilderRef builder
= ctx
->ac
.builder
;
59 LLVMValueRef p
= ac_get_arg(&ctx
->ac
, param
);
61 return LLVMBuildInsertValue(builder
, ret
,
62 ac_to_float(&ctx
->ac
, p
),
66 LLVMValueRef
si_insert_input_ptr(struct si_shader_context
*ctx
, LLVMValueRef ret
,
67 struct ac_arg param
, unsigned return_index
)
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
, "");
75 LLVMValueRef
si_prolog_get_rw_buffers(struct si_shader_context
*ctx
)
77 LLVMValueRef ptr
[2], list
;
78 bool merged_shader
= si_is_merged_shader(ctx
);
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
), "");
86 LLVMValueRef
si_build_gather_64bit(struct si_shader_context
*ctx
,
87 LLVMTypeRef type
, LLVMValueRef val1
,
90 LLVMValueRef values
[2] = {
91 ac_to_integer(&ctx
->ac
, val1
),
92 ac_to_integer(&ctx
->ac
, val2
),
94 LLVMValueRef result
= ac_build_gather_values(&ctx
->ac
, values
, 2);
95 return LLVMBuildBitCast(ctx
->ac
.builder
, result
, type
, "");
98 void si_llvm_emit_barrier(struct si_shader_context
*ctx
)
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.
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
);
110 ac_build_s_barrier(&ctx
->ac
);
113 /* Ensure that the esgs ring is declared.
115 * We declare it with 64KB alignment as a hint that the
116 * pointer value will always be 0.
118 void si_llvm_declare_esgs_ring(struct si_shader_context
*ctx
)
123 assert(!LLVMGetNamedGlobal(ctx
->ac
.module
, "esgs_ring"));
125 ctx
->esgs_ring
= LLVMAddGlobalInAddressSpace(
126 ctx
->ac
.module
, LLVMArrayType(ctx
->ac
.i32
, 0),
129 LLVMSetLinkage(ctx
->esgs_ring
, LLVMExternalLinkage
);
130 LLVMSetAlignment(ctx
->esgs_ring
, 64 * 1024);