1 /**************************************************************************
3 * Copyright 2019 Red Hat.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 **************************************************************************/
26 #include "lp_bld_nir.h"
27 #include "lp_bld_init.h"
28 #include "lp_bld_flow.h"
29 #include "lp_bld_logic.h"
30 #include "lp_bld_gather.h"
31 #include "lp_bld_const.h"
32 #include "lp_bld_struct.h"
33 #include "lp_bld_arit.h"
34 #include "lp_bld_bitarit.h"
35 #include "lp_bld_coro.h"
36 #include "lp_bld_printf.h"
37 #include "util/u_math.h"
39 * combine the execution mask if there is one with the current mask.
42 mask_vec(struct lp_build_nir_context
*bld_base
)
44 struct lp_build_nir_soa_context
* bld
= (struct lp_build_nir_soa_context
*)bld_base
;
45 LLVMBuilderRef builder
= bld
->bld_base
.base
.gallivm
->builder
;
46 struct lp_exec_mask
*exec_mask
= &bld
->exec_mask
;
47 LLVMValueRef bld_mask
= bld
->mask
? lp_build_mask_value(bld
->mask
) : NULL
;
48 if (!exec_mask
->has_mask
) {
52 return exec_mask
->exec_mask
;
53 return LLVMBuildAnd(builder
, lp_build_mask_value(bld
->mask
),
54 exec_mask
->exec_mask
, "");
59 struct lp_build_nir_context
* bld_base
,
63 struct gallivm_state
*gallivm
= bld_base
->base
.gallivm
;
64 LLVMBuilderRef builder
= gallivm
->builder
;
67 LLVMValueRef shuffles
[2 * (LP_MAX_VECTOR_WIDTH
/32)];
68 int len
= bld_base
->base
.type
.length
* 2;
69 assert(len
<= (2 * (LP_MAX_VECTOR_WIDTH
/32)));
71 for (i
= 0; i
< bld_base
->base
.type
.length
* 2; i
+=2) {
72 shuffles
[i
] = lp_build_const_int32(gallivm
, i
/ 2);
73 shuffles
[i
+ 1] = lp_build_const_int32(gallivm
, i
/ 2 + bld_base
->base
.type
.length
);
75 res
= LLVMBuildShuffleVector(builder
, input
, input2
, LLVMConstVector(shuffles
, len
), "");
77 return LLVMBuildBitCast(builder
, res
, bld_base
->dbl_bld
.vec_type
, "");
81 emit_store_64bit_chan(struct lp_build_nir_context
*bld_base
,
82 LLVMValueRef chan_ptr
,
83 LLVMValueRef chan_ptr2
,
86 struct lp_build_nir_soa_context
*bld
= (struct lp_build_nir_soa_context
*)bld_base
;
87 struct gallivm_state
*gallivm
= bld_base
->base
.gallivm
;
88 LLVMBuilderRef builder
= gallivm
->builder
;
89 struct lp_build_context
*float_bld
= &bld_base
->base
;
91 LLVMValueRef temp
, temp2
;
92 LLVMValueRef shuffles
[LP_MAX_VECTOR_WIDTH
/32];
93 LLVMValueRef shuffles2
[LP_MAX_VECTOR_WIDTH
/32];
94 int len
= bld_base
->base
.type
.length
* 2;
96 value
= LLVMBuildBitCast(gallivm
->builder
, value
, LLVMVectorType(LLVMFloatTypeInContext(gallivm
->context
), len
), "");
97 for (i
= 0; i
< bld_base
->base
.type
.length
; i
++) {
98 shuffles
[i
] = lp_build_const_int32(gallivm
, i
* 2);
99 shuffles2
[i
] = lp_build_const_int32(gallivm
, (i
* 2) + 1);
102 temp
= LLVMBuildShuffleVector(builder
, value
,
103 LLVMGetUndef(LLVMTypeOf(value
)),
104 LLVMConstVector(shuffles
,
105 bld_base
->base
.type
.length
),
107 temp2
= LLVMBuildShuffleVector(builder
, value
,
108 LLVMGetUndef(LLVMTypeOf(value
)),
109 LLVMConstVector(shuffles2
,
110 bld_base
->base
.type
.length
),
113 lp_exec_mask_store(&bld
->exec_mask
, float_bld
, temp
, chan_ptr
);
114 lp_exec_mask_store(&bld
->exec_mask
, float_bld
, temp2
, chan_ptr2
);
118 get_soa_array_offsets(struct lp_build_context
*uint_bld
,
119 LLVMValueRef indirect_index
,
122 bool need_perelement_offset
)
124 struct gallivm_state
*gallivm
= uint_bld
->gallivm
;
125 LLVMValueRef chan_vec
=
126 lp_build_const_int_vec(uint_bld
->gallivm
, uint_bld
->type
, chan_index
);
127 LLVMValueRef length_vec
=
128 lp_build_const_int_vec(gallivm
, uint_bld
->type
, uint_bld
->type
.length
);
129 LLVMValueRef index_vec
;
131 /* index_vec = (indirect_index * 4 + chan_index) * length + offsets */
132 index_vec
= lp_build_mul(uint_bld
, indirect_index
, lp_build_const_int_vec(uint_bld
->gallivm
, uint_bld
->type
, num_components
));
133 index_vec
= lp_build_add(uint_bld
, index_vec
, chan_vec
);
134 index_vec
= lp_build_mul(uint_bld
, index_vec
, length_vec
);
136 if (need_perelement_offset
) {
137 LLVMValueRef pixel_offsets
;
139 /* build pixel offset vector: {0, 1, 2, 3, ...} */
140 pixel_offsets
= uint_bld
->undef
;
141 for (i
= 0; i
< uint_bld
->type
.length
; i
++) {
142 LLVMValueRef ii
= lp_build_const_int32(gallivm
, i
);
143 pixel_offsets
= LLVMBuildInsertElement(gallivm
->builder
, pixel_offsets
,
146 index_vec
= lp_build_add(uint_bld
, index_vec
, pixel_offsets
);
152 build_gather(struct lp_build_nir_context
*bld_base
,
153 struct lp_build_context
*bld
,
154 LLVMValueRef base_ptr
,
155 LLVMValueRef indexes
,
156 LLVMValueRef overflow_mask
,
157 LLVMValueRef indexes2
)
159 struct gallivm_state
*gallivm
= bld_base
->base
.gallivm
;
160 LLVMBuilderRef builder
= gallivm
->builder
;
161 struct lp_build_context
*uint_bld
= &bld_base
->uint_bld
;
166 res
= LLVMGetUndef(LLVMVectorType(LLVMFloatTypeInContext(gallivm
->context
), bld_base
->base
.type
.length
* 2));
170 * overflow_mask is a vector telling us which channels
171 * in the vector overflowed. We use the overflow behavior for
172 * constant buffers which is defined as:
173 * Out of bounds access to constant buffer returns 0 in all
174 * components. Out of bounds behavior is always with respect
175 * to the size of the buffer bound at that slot.
180 * We avoid per-element control flow here (also due to llvm going crazy,
181 * though I suspect it's better anyway since overflow is likely rare).
182 * Note that since we still fetch from buffers even if num_elements was
183 * zero (in this case we'll fetch from index zero) the jit func callers
184 * MUST provide valid fake constant buffers of size 4x32 (the values do
185 * not matter), otherwise we'd still need (not per element though)
188 indexes
= lp_build_select(uint_bld
, overflow_mask
, uint_bld
->zero
, indexes
);
190 indexes2
= lp_build_select(uint_bld
, overflow_mask
, uint_bld
->zero
, indexes2
);
194 * Loop over elements of index_vec, load scalar value, insert it into 'res'.
196 for (i
= 0; i
< bld
->type
.length
* (indexes2
? 2 : 1); i
++) {
199 LLVMValueRef scalar_ptr
, scalar
;
201 di
= lp_build_const_int32(gallivm
, i
);
203 si
= lp_build_const_int32(gallivm
, i
>> 1);
207 if (indexes2
&& (i
& 1)) {
208 index
= LLVMBuildExtractElement(builder
,
211 index
= LLVMBuildExtractElement(builder
,
214 scalar_ptr
= LLVMBuildGEP(builder
, base_ptr
,
215 &index
, 1, "gather_ptr");
216 scalar
= LLVMBuildLoad(builder
, scalar_ptr
, "");
218 res
= LLVMBuildInsertElement(builder
, res
, scalar
, di
, "");
223 res
= LLVMBuildBitCast(builder
, res
, bld_base
->dbl_bld
.vec_type
, "");
224 overflow_mask
= LLVMBuildSExt(builder
, overflow_mask
,
225 bld_base
->dbl_bld
.int_vec_type
, "");
226 res
= lp_build_select(&bld_base
->dbl_bld
, overflow_mask
,
227 bld_base
->dbl_bld
.zero
, res
);
229 res
= lp_build_select(bld
, overflow_mask
, bld
->zero
, res
);
236 * Scatter/store vector.
239 emit_mask_scatter(struct lp_build_nir_soa_context
*bld
,
240 LLVMValueRef base_ptr
,
241 LLVMValueRef indexes
,
243 struct lp_exec_mask
*mask
)
245 struct gallivm_state
*gallivm
= bld
->bld_base
.base
.gallivm
;
246 LLVMBuilderRef builder
= gallivm
->builder
;
248 LLVMValueRef pred
= mask
->has_mask
? mask
->exec_mask
: NULL
;
251 * Loop over elements of index_vec, store scalar value.
253 for (i
= 0; i
< bld
->bld_base
.base
.type
.length
; i
++) {
254 LLVMValueRef ii
= lp_build_const_int32(gallivm
, i
);
255 LLVMValueRef index
= LLVMBuildExtractElement(builder
, indexes
, ii
, "");
256 LLVMValueRef scalar_ptr
= LLVMBuildGEP(builder
, base_ptr
, &index
, 1, "scatter_ptr");
257 LLVMValueRef val
= LLVMBuildExtractElement(builder
, values
, ii
, "scatter_val");
258 LLVMValueRef scalar_pred
= pred
?
259 LLVMBuildExtractElement(builder
, pred
, ii
, "scatter_pred") : NULL
;
262 lp_build_printf(gallivm
, "scatter %d: val %f at %d %p\n",
263 ii
, val
, index
, scalar_ptr
);
266 LLVMValueRef real_val
, dst_val
;
267 dst_val
= LLVMBuildLoad(builder
, scalar_ptr
, "");
268 real_val
= lp_build_select(&bld
->uint_elem_bld
, scalar_pred
, val
, dst_val
);
269 LLVMBuildStore(builder
, real_val
, scalar_ptr
);
272 LLVMBuildStore(builder
, val
, scalar_ptr
);
277 static void emit_load_var(struct lp_build_nir_context
*bld_base
,
278 nir_variable_mode deref_mode
,
279 unsigned num_components
,
282 unsigned vertex_index
,
283 unsigned const_index
,
284 LLVMValueRef indir_index
,
285 LLVMValueRef result
[NIR_MAX_VEC_COMPONENTS
])
287 struct lp_build_nir_soa_context
*bld
= (struct lp_build_nir_soa_context
*)bld_base
;
288 struct gallivm_state
*gallivm
= bld_base
->base
.gallivm
;
289 int dmul
= bit_size
== 64 ? 2 : 1;
290 switch (deref_mode
) {
291 case nir_var_shader_in
: {
292 for (unsigned i
= 0; i
< num_components
; i
++) {
293 int idx
= (i
* dmul
) + var
->data
.location_frac
;
295 LLVMValueRef vertex_index_val
= lp_build_const_int32(gallivm
, vertex_index
);
296 LLVMValueRef attrib_index_val
= lp_build_const_int32(gallivm
, const_index
+ var
->data
.driver_location
);
297 LLVMValueRef swizzle_index_val
= lp_build_const_int32(gallivm
, idx
);
298 LLVMValueRef result2
;
299 result
[i
] = bld
->gs_iface
->fetch_input(bld
->gs_iface
, &bld_base
->base
,
300 false, vertex_index_val
, 0, attrib_index_val
, swizzle_index_val
);
301 if (bit_size
== 64) {
302 LLVMValueRef swizzle_index_val
= lp_build_const_int32(gallivm
, idx
+ 1);
303 result2
= bld
->gs_iface
->fetch_input(bld
->gs_iface
, &bld_base
->base
,
304 false, vertex_index_val
, 0, attrib_index_val
, swizzle_index_val
);
305 result
[i
] = emit_fetch_64bit(bld_base
, result
[i
], result2
);
309 LLVMValueRef attrib_index_val
= lp_build_add(&bld_base
->uint_bld
, indir_index
, lp_build_const_int_vec(gallivm
, bld_base
->uint_bld
.type
, var
->data
.driver_location
));
310 LLVMValueRef index_vec
= get_soa_array_offsets(&bld_base
->uint_bld
,
311 attrib_index_val
, 4, idx
,
313 LLVMValueRef index_vec2
= NULL
;
314 LLVMTypeRef fptr_type
;
315 LLVMValueRef inputs_array
;
316 fptr_type
= LLVMPointerType(LLVMFloatTypeInContext(gallivm
->context
), 0);
317 inputs_array
= LLVMBuildBitCast(gallivm
->builder
, bld
->inputs_array
, fptr_type
, "");
320 index_vec2
= get_soa_array_offsets(&bld_base
->uint_bld
,
321 indir_index
, 4, idx
+ 1, TRUE
);
323 /* Gather values from the input register array */
324 result
[i
] = build_gather(bld_base
, &bld_base
->base
, inputs_array
, index_vec
, NULL
, index_vec2
);
326 if (bld
->indirects
& nir_var_shader_in
) {
327 LLVMValueRef lindex
= lp_build_const_int32(gallivm
,
328 var
->data
.driver_location
* 4 + idx
);
329 LLVMValueRef input_ptr
= lp_build_pointer_get(gallivm
->builder
,
330 bld
->inputs_array
, lindex
);
331 if (bit_size
== 64) {
332 LLVMValueRef lindex2
= lp_build_const_int32(gallivm
,
333 var
->data
.driver_location
* 4 + (idx
+ 1));
334 LLVMValueRef input_ptr2
= lp_build_pointer_get(gallivm
->builder
,
335 bld
->inputs_array
, lindex2
);
336 result
[i
] = emit_fetch_64bit(bld_base
, input_ptr
, input_ptr2
);
338 result
[i
] = input_ptr
;
341 if (bit_size
== 64) {
343 tmp
[0] = bld
->inputs
[var
->data
.driver_location
+ const_index
][idx
];
344 tmp
[1] = bld
->inputs
[var
->data
.driver_location
+ const_index
][idx
+ 1];
345 result
[i
] = emit_fetch_64bit(bld_base
, tmp
[0], tmp
[1]);
347 result
[i
] = bld
->inputs
[var
->data
.driver_location
+ const_index
][idx
];
359 static void emit_store_chan(struct lp_build_nir_context
*bld_base
,
360 nir_variable_mode deref_mode
,
362 unsigned location
, unsigned comp
,
366 struct lp_build_nir_soa_context
*bld
= (struct lp_build_nir_soa_context
*)bld_base
;
367 LLVMBuilderRef builder
= bld
->bld_base
.base
.gallivm
->builder
;
368 struct lp_build_context
*float_bld
= &bld_base
->base
;
370 if (bit_size
== 64) {
377 emit_store_64bit_chan(bld_base
, bld
->outputs
[location
][chan
],
378 bld
->outputs
[location
][chan
+ 1], dst
);
380 dst
= LLVMBuildBitCast(builder
, dst
, float_bld
->vec_type
, "");
381 lp_exec_mask_store(&bld
->exec_mask
, float_bld
, dst
,
382 bld
->outputs
[location
][chan
+ comp
]);
386 static void emit_store_var(struct lp_build_nir_context
*bld_base
,
387 nir_variable_mode deref_mode
,
389 unsigned num_components
,
391 unsigned const_index
,
392 nir_variable
*var
, LLVMValueRef dst
)
394 struct lp_build_nir_soa_context
*bld
= (struct lp_build_nir_soa_context
*)bld_base
;
395 LLVMBuilderRef builder
= bld
->bld_base
.base
.gallivm
->builder
;
396 switch (deref_mode
) {
397 case nir_var_shader_out
: {
398 unsigned location
= var
->data
.driver_location
+ const_index
;
399 unsigned comp
= var
->data
.location_frac
;
400 if (bld_base
->shader
->info
.stage
== MESA_SHADER_FRAGMENT
) {
401 if (var
->data
.location
== FRAG_RESULT_STENCIL
)
403 else if (var
->data
.location
== FRAG_RESULT_DEPTH
)
406 for (unsigned chan
= 0; chan
< num_components
; chan
++) {
407 if (writemask
& (1u << chan
)) {
408 LLVMValueRef chan_val
= (num_components
== 1) ? dst
: LLVMBuildExtractValue(builder
, dst
, chan
, "");
409 emit_store_chan(bld_base
, deref_mode
, bit_size
, location
, comp
, chan
, chan_val
);
419 static LLVMValueRef
emit_load_reg(struct lp_build_nir_context
*bld_base
,
420 struct lp_build_context
*reg_bld
,
421 const nir_reg_src
*reg
,
422 LLVMValueRef indir_src
,
423 LLVMValueRef reg_storage
)
425 struct gallivm_state
*gallivm
= bld_base
->base
.gallivm
;
426 LLVMBuilderRef builder
= gallivm
->builder
;
427 int nc
= reg
->reg
->num_components
;
428 LLVMValueRef vals
[NIR_MAX_VEC_COMPONENTS
] = { NULL
};
429 struct lp_build_context
*uint_bld
= &bld_base
->uint_bld
;
430 if (reg
->reg
->num_array_elems
) {
431 LLVMValueRef indirect_val
= lp_build_const_int_vec(gallivm
, uint_bld
->type
, reg
->base_offset
);
433 LLVMValueRef max_index
= lp_build_const_int_vec(gallivm
, uint_bld
->type
, reg
->reg
->num_array_elems
- 1);
434 indirect_val
= LLVMBuildAdd(builder
, indirect_val
, indir_src
, "");
435 indirect_val
= lp_build_min(uint_bld
, indirect_val
, max_index
);
437 reg_storage
= LLVMBuildBitCast(builder
, reg_storage
, LLVMPointerType(reg_bld
->elem_type
, 0), "");
438 for (unsigned i
= 0; i
< nc
; i
++) {
439 LLVMValueRef indirect_offset
= get_soa_array_offsets(uint_bld
, indirect_val
, nc
, i
, TRUE
);
440 vals
[i
] = build_gather(bld_base
, reg_bld
, reg_storage
, indirect_offset
, NULL
, NULL
);
443 for (unsigned i
= 0; i
< nc
; i
++) {
444 LLVMValueRef this_storage
= nc
== 1 ? reg_storage
: lp_build_array_get_ptr(gallivm
, reg_storage
,
445 lp_build_const_int32(gallivm
, i
));
446 vals
[i
] = LLVMBuildLoad(builder
, this_storage
, "");
449 return nc
== 1 ? vals
[0] : lp_nir_array_build_gather_values(builder
, vals
, nc
);
452 static void emit_store_reg(struct lp_build_nir_context
*bld_base
,
453 struct lp_build_context
*reg_bld
,
454 const nir_reg_dest
*reg
,
456 LLVMValueRef indir_src
,
457 LLVMValueRef reg_storage
,
458 LLVMValueRef dst
[NIR_MAX_VEC_COMPONENTS
])
460 struct lp_build_nir_soa_context
*bld
= (struct lp_build_nir_soa_context
*)bld_base
;
461 struct gallivm_state
*gallivm
= bld_base
->base
.gallivm
;
462 LLVMBuilderRef builder
= gallivm
->builder
;
463 struct lp_build_context
*uint_bld
= &bld_base
->uint_bld
;
464 int nc
= reg
->reg
->num_components
;
465 if (reg
->reg
->num_array_elems
> 0) {
466 LLVMValueRef indirect_val
= lp_build_const_int_vec(gallivm
, uint_bld
->type
, reg
->base_offset
);
468 LLVMValueRef max_index
= lp_build_const_int_vec(gallivm
, uint_bld
->type
, reg
->reg
->num_array_elems
- 1);
469 indirect_val
= LLVMBuildAdd(builder
, indirect_val
, indir_src
, "");
470 indirect_val
= lp_build_min(uint_bld
, indirect_val
, max_index
);
472 reg_storage
= LLVMBuildBitCast(builder
, reg_storage
, LLVMPointerType(reg_bld
->elem_type
, 0), "");
473 for (unsigned i
= 0; i
< nc
; i
++) {
474 if (!(writemask
& (1 << i
)))
476 LLVMValueRef indirect_offset
= get_soa_array_offsets(uint_bld
, indirect_val
, nc
, i
, TRUE
);
477 dst
[i
] = LLVMBuildBitCast(builder
, dst
[i
], reg_bld
->vec_type
, "");
478 emit_mask_scatter(bld
, reg_storage
, indirect_offset
, dst
[i
], &bld
->exec_mask
);
483 for (unsigned i
= 0; i
< nc
; i
++) {
484 LLVMValueRef this_storage
= nc
== 1 ? reg_storage
: lp_build_array_get_ptr(gallivm
, reg_storage
,
485 lp_build_const_int32(gallivm
, i
));
486 dst
[i
] = LLVMBuildBitCast(builder
, dst
[i
], reg_bld
->vec_type
, "");
487 lp_exec_mask_store(&bld
->exec_mask
, reg_bld
, dst
[i
], this_storage
);
491 static void emit_load_kernel_arg(struct lp_build_nir_context
*bld_base
,
494 unsigned offset_bit_size
,
495 bool offset_is_uniform
,
497 LLVMValueRef result
[NIR_MAX_VEC_COMPONENTS
])
499 struct lp_build_nir_soa_context
*bld
= (struct lp_build_nir_soa_context
*)bld_base
;
500 struct gallivm_state
*gallivm
= bld_base
->base
.gallivm
;
501 LLVMBuilderRef builder
= gallivm
->builder
;
502 struct lp_build_context
*bld_broad
= get_int_bld(bld_base
, true, bit_size
);
503 LLVMValueRef kernel_args_ptr
= bld
->kernel_args_ptr
;
504 unsigned size_shift
= 0;
505 struct lp_build_context
*bld_offset
= get_int_bld(bld_base
, true, offset_bit_size
);
508 else if (bit_size
== 32)
510 else if (bit_size
== 64)
513 offset
= lp_build_shr(bld_offset
, offset
, lp_build_const_int_vec(gallivm
, bld_offset
->type
, size_shift
));
515 LLVMTypeRef ptr_type
= LLVMPointerType(bld_broad
->elem_type
, 0);
516 kernel_args_ptr
= LLVMBuildBitCast(builder
, kernel_args_ptr
, ptr_type
, "");
518 if (offset_is_uniform
) {
519 offset
= LLVMBuildExtractElement(builder
, offset
, lp_build_const_int32(gallivm
, 0), "");
521 for (unsigned c
= 0; c
< nc
; c
++) {
522 LLVMValueRef this_offset
= LLVMBuildAdd(builder
, offset
, offset_bit_size
== 64 ? lp_build_const_int64(gallivm
, c
) : lp_build_const_int32(gallivm
, c
), "");
524 LLVMValueRef scalar
= lp_build_pointer_get(builder
, kernel_args_ptr
, this_offset
);
525 result
[c
] = lp_build_broadcast_scalar(bld_broad
, scalar
);
530 static LLVMValueRef
global_addr_to_ptr(struct gallivm_state
*gallivm
, LLVMValueRef addr_ptr
, unsigned bit_size
)
532 LLVMBuilderRef builder
= gallivm
->builder
;
535 addr_ptr
= LLVMBuildIntToPtr(builder
, addr_ptr
, LLVMPointerType(LLVMInt8TypeInContext(gallivm
->context
), 0), "");
538 addr_ptr
= LLVMBuildIntToPtr(builder
, addr_ptr
, LLVMPointerType(LLVMInt16TypeInContext(gallivm
->context
), 0), "");
542 addr_ptr
= LLVMBuildIntToPtr(builder
, addr_ptr
, LLVMPointerType(LLVMInt32TypeInContext(gallivm
->context
), 0), "");
545 addr_ptr
= LLVMBuildIntToPtr(builder
, addr_ptr
, LLVMPointerType(LLVMInt64TypeInContext(gallivm
->context
), 0), "");
551 static void emit_load_global(struct lp_build_nir_context
*bld_base
,
554 unsigned addr_bit_size
,
556 LLVMValueRef outval
[NIR_MAX_VEC_COMPONENTS
])
558 struct gallivm_state
*gallivm
= bld_base
->base
.gallivm
;
559 LLVMBuilderRef builder
= gallivm
->builder
;
560 struct lp_build_context
*uint_bld
= &bld_base
->uint_bld
;
561 struct lp_build_context
*res_bld
;
563 res_bld
= get_int_bld(bld_base
, true, bit_size
);
565 for (unsigned c
= 0; c
< nc
; c
++) {
566 LLVMValueRef result
= lp_build_alloca(gallivm
, res_bld
->vec_type
, "");
568 struct lp_build_loop_state loop_state
;
569 lp_build_loop_begin(&loop_state
, gallivm
, lp_build_const_int32(gallivm
, 0));
571 LLVMValueRef addr_ptr
= LLVMBuildExtractElement(gallivm
->builder
, addr
,
572 loop_state
.counter
, "");
573 addr_ptr
= global_addr_to_ptr(gallivm
, addr_ptr
, bit_size
);
575 LLVMValueRef value_ptr
= lp_build_pointer_get(builder
, addr_ptr
, lp_build_const_int32(gallivm
, c
));
577 LLVMValueRef temp_res
;
578 temp_res
= LLVMBuildLoad(builder
, result
, "");
579 temp_res
= LLVMBuildInsertElement(builder
, temp_res
, value_ptr
, loop_state
.counter
, "");
580 LLVMBuildStore(builder
, temp_res
, result
);
581 lp_build_loop_end_cond(&loop_state
, lp_build_const_int32(gallivm
, uint_bld
->type
.length
),
583 outval
[c
] = LLVMBuildLoad(builder
, result
, "");
587 static void emit_store_global(struct lp_build_nir_context
*bld_base
,
589 unsigned nc
, unsigned bit_size
,
590 unsigned addr_bit_size
,
594 struct gallivm_state
*gallivm
= bld_base
->base
.gallivm
;
595 LLVMBuilderRef builder
= gallivm
->builder
;
596 struct lp_build_context
*uint_bld
= &bld_base
->uint_bld
;
598 for (unsigned c
= 0; c
< nc
; c
++) {
599 if (!(writemask
& (1u << c
)))
601 LLVMValueRef val
= (nc
== 1) ? dst
: LLVMBuildExtractValue(builder
, dst
, c
, "");
603 LLVMValueRef exec_mask
= mask_vec(bld_base
);
604 struct lp_build_loop_state loop_state
;
605 lp_build_loop_begin(&loop_state
, gallivm
, lp_build_const_int32(gallivm
, 0));
606 LLVMValueRef value_ptr
= LLVMBuildExtractElement(gallivm
->builder
, val
,
607 loop_state
.counter
, "");
609 LLVMValueRef addr_ptr
= LLVMBuildExtractElement(gallivm
->builder
, addr
,
610 loop_state
.counter
, "");
611 addr_ptr
= global_addr_to_ptr(gallivm
, addr_ptr
, bit_size
);
614 value_ptr
= LLVMBuildBitCast(builder
, value_ptr
, LLVMInt32TypeInContext(gallivm
->context
), "");
617 value_ptr
= LLVMBuildBitCast(builder
, value_ptr
, LLVMInt64TypeInContext(gallivm
->context
), "");
622 struct lp_build_if_state ifthen
;
624 LLVMValueRef cond
= LLVMBuildICmp(gallivm
->builder
, LLVMIntNE
, exec_mask
, uint_bld
->zero
, "");
625 cond
= LLVMBuildExtractElement(gallivm
->builder
, cond
, loop_state
.counter
, "");
626 lp_build_if(&ifthen
, gallivm
, cond
);
627 lp_build_pointer_set(builder
, addr_ptr
, lp_build_const_int32(gallivm
, c
), value_ptr
);
628 lp_build_endif(&ifthen
);
629 lp_build_loop_end_cond(&loop_state
, lp_build_const_int32(gallivm
, uint_bld
->type
.length
),
634 static void emit_atomic_global(struct lp_build_nir_context
*bld_base
,
635 nir_intrinsic_op nir_op
,
636 unsigned addr_bit_size
,
638 LLVMValueRef val
, LLVMValueRef val2
,
639 LLVMValueRef
*result
)
641 struct gallivm_state
*gallivm
= bld_base
->base
.gallivm
;
642 LLVMBuilderRef builder
= gallivm
->builder
;
643 struct lp_build_context
*uint_bld
= &bld_base
->uint_bld
;
645 LLVMValueRef atom_res
= lp_build_alloca(gallivm
,
646 uint_bld
->vec_type
, "");
647 LLVMValueRef exec_mask
= mask_vec(bld_base
);
648 struct lp_build_loop_state loop_state
;
649 lp_build_loop_begin(&loop_state
, gallivm
, lp_build_const_int32(gallivm
, 0));
651 LLVMValueRef value_ptr
= LLVMBuildExtractElement(gallivm
->builder
, val
,
652 loop_state
.counter
, "");
654 LLVMValueRef addr_ptr
= LLVMBuildExtractElement(gallivm
->builder
, addr
,
655 loop_state
.counter
, "");
656 addr_ptr
= global_addr_to_ptr(gallivm
, addr_ptr
, 32);
657 struct lp_build_if_state ifthen
;
658 LLVMValueRef cond
, temp_res
;
660 cond
= LLVMBuildICmp(gallivm
->builder
, LLVMIntNE
, exec_mask
, uint_bld
->zero
, "");
661 cond
= LLVMBuildExtractElement(gallivm
->builder
, cond
, loop_state
.counter
, "");
662 lp_build_if(&ifthen
, gallivm
, cond
);
664 if (nir_op
== nir_intrinsic_global_atomic_comp_swap
) {
665 LLVMValueRef cas_src_ptr
= LLVMBuildExtractElement(gallivm
->builder
, val2
,
666 loop_state
.counter
, "");
667 cas_src_ptr
= LLVMBuildBitCast(gallivm
->builder
, cas_src_ptr
, uint_bld
->elem_type
, "");
668 scalar
= LLVMBuildAtomicCmpXchg(builder
, addr_ptr
, value_ptr
,
670 LLVMAtomicOrderingSequentiallyConsistent
,
671 LLVMAtomicOrderingSequentiallyConsistent
,
673 scalar
= LLVMBuildExtractValue(gallivm
->builder
, scalar
, 0, "");
675 LLVMAtomicRMWBinOp op
;
677 case nir_intrinsic_global_atomic_add
:
678 op
= LLVMAtomicRMWBinOpAdd
;
680 case nir_intrinsic_global_atomic_exchange
:
681 op
= LLVMAtomicRMWBinOpXchg
;
683 case nir_intrinsic_global_atomic_and
:
684 op
= LLVMAtomicRMWBinOpAnd
;
686 case nir_intrinsic_global_atomic_or
:
687 op
= LLVMAtomicRMWBinOpOr
;
689 case nir_intrinsic_global_atomic_xor
:
690 op
= LLVMAtomicRMWBinOpXor
;
692 case nir_intrinsic_global_atomic_umin
:
693 op
= LLVMAtomicRMWBinOpUMin
;
695 case nir_intrinsic_global_atomic_umax
:
696 op
= LLVMAtomicRMWBinOpUMax
;
698 case nir_intrinsic_global_atomic_imin
:
699 op
= LLVMAtomicRMWBinOpMin
;
701 case nir_intrinsic_global_atomic_imax
:
702 op
= LLVMAtomicRMWBinOpMax
;
705 unreachable("unknown atomic op");
708 scalar
= LLVMBuildAtomicRMW(builder
, op
,
710 LLVMAtomicOrderingSequentiallyConsistent
,
713 temp_res
= LLVMBuildLoad(builder
, atom_res
, "");
714 temp_res
= LLVMBuildInsertElement(builder
, temp_res
, scalar
, loop_state
.counter
, "");
715 LLVMBuildStore(builder
, temp_res
, atom_res
);
716 lp_build_else(&ifthen
);
717 temp_res
= LLVMBuildLoad(builder
, atom_res
, "");
718 temp_res
= LLVMBuildInsertElement(builder
, temp_res
, lp_build_const_int32(gallivm
, 0), loop_state
.counter
, "");
719 LLVMBuildStore(builder
, temp_res
, atom_res
);
720 lp_build_endif(&ifthen
);
721 lp_build_loop_end_cond(&loop_state
, lp_build_const_int32(gallivm
, uint_bld
->type
.length
),
723 *result
= LLVMBuildLoad(builder
, atom_res
, "");
726 static void emit_load_ubo(struct lp_build_nir_context
*bld_base
,
729 bool offset_is_uniform
,
732 LLVMValueRef result
[NIR_MAX_VEC_COMPONENTS
])
734 struct lp_build_nir_soa_context
*bld
= (struct lp_build_nir_soa_context
*)bld_base
;
735 struct gallivm_state
*gallivm
= bld_base
->base
.gallivm
;
736 LLVMBuilderRef builder
= gallivm
->builder
;
737 struct lp_build_context
*uint_bld
= &bld_base
->uint_bld
;
738 struct lp_build_context
*bld_broad
= bit_size
== 64 ? &bld_base
->dbl_bld
: &bld_base
->base
;
739 LLVMValueRef consts_ptr
= lp_build_array_get(gallivm
, bld
->consts_ptr
, index
);
740 unsigned size_shift
= 0;
743 else if (bit_size
== 64)
746 offset
= lp_build_shr(uint_bld
, offset
, lp_build_const_int_vec(gallivm
, uint_bld
->type
, size_shift
));
747 if (bit_size
== 64) {
748 LLVMTypeRef dptr_type
= LLVMPointerType(bld_base
->dbl_bld
.elem_type
, 0);
749 consts_ptr
= LLVMBuildBitCast(builder
, consts_ptr
, dptr_type
, "");
752 if (offset_is_uniform
) {
753 offset
= LLVMBuildExtractElement(builder
, offset
, lp_build_const_int32(gallivm
, 0), "");
755 for (unsigned c
= 0; c
< nc
; c
++) {
756 LLVMValueRef this_offset
= LLVMBuildAdd(builder
, offset
, lp_build_const_int32(gallivm
, c
), "");
758 LLVMValueRef scalar
= lp_build_pointer_get(builder
, consts_ptr
, this_offset
);
759 result
[c
] = lp_build_broadcast_scalar(bld_broad
, scalar
);
762 LLVMValueRef overflow_mask
;
763 LLVMValueRef num_consts
= lp_build_array_get(gallivm
, bld
->const_sizes_ptr
, index
);
765 num_consts
= LLVMBuildShl(gallivm
->builder
, num_consts
, lp_build_const_int32(gallivm
, 4), "");
766 num_consts
= lp_build_broadcast_scalar(uint_bld
, num_consts
);
767 for (unsigned c
= 0; c
< nc
; c
++) {
768 LLVMValueRef this_offset
= lp_build_add(uint_bld
, offset
, lp_build_const_int_vec(gallivm
, uint_bld
->type
, c
));
769 overflow_mask
= lp_build_compare(gallivm
, uint_bld
->type
, PIPE_FUNC_GEQUAL
,
770 this_offset
, num_consts
);
772 result
[c
] = build_gather(bld_base
, bld_broad
, consts_ptr
, this_offset
, overflow_mask
, NULL
);
778 static void emit_load_mem(struct lp_build_nir_context
*bld_base
,
783 LLVMValueRef outval
[NIR_MAX_VEC_COMPONENTS
])
785 struct gallivm_state
*gallivm
= bld_base
->base
.gallivm
;
786 struct lp_build_nir_soa_context
*bld
= (struct lp_build_nir_soa_context
*)bld_base
;
787 LLVMBuilderRef builder
= bld
->bld_base
.base
.gallivm
->builder
;
788 LLVMValueRef ssbo_ptr
= NULL
;
789 struct lp_build_context
*uint_bld
= &bld_base
->uint_bld
;
790 struct lp_build_context
*uint64_bld
= &bld_base
->uint64_bld
;
791 LLVMValueRef ssbo_limit
= NULL
;
794 LLVMValueRef ssbo_size_ptr
= lp_build_array_get(gallivm
, bld
->ssbo_sizes_ptr
, LLVMBuildExtractElement(builder
, index
, lp_build_const_int32(gallivm
, 0), ""));
795 ssbo_limit
= LLVMBuildAShr(gallivm
->builder
, ssbo_size_ptr
, lp_build_const_int32(gallivm
, bit_size
== 64 ? 3 : 2), "");
796 ssbo_limit
= lp_build_broadcast_scalar(uint_bld
, ssbo_limit
);
798 ssbo_ptr
= lp_build_array_get(gallivm
, bld
->ssbo_ptr
, LLVMBuildExtractElement(builder
, index
, lp_build_const_int32(gallivm
, 0), ""));
800 ssbo_ptr
= bld
->shared_ptr
;
802 offset
= LLVMBuildAShr(gallivm
->builder
, offset
, lp_build_const_int_vec(gallivm
, uint_bld
->type
, bit_size
== 64 ? 3 : 2), "");
803 for (unsigned c
= 0; c
< nc
; c
++) {
804 LLVMValueRef loop_index
= lp_build_add(uint_bld
, offset
, lp_build_const_int_vec(gallivm
, uint_bld
->type
, c
));
805 LLVMValueRef exec_mask
= mask_vec(bld_base
);
808 LLVMValueRef ssbo_oob_cmp
= lp_build_cmp(uint_bld
, PIPE_FUNC_LESS
, loop_index
, ssbo_limit
);
809 exec_mask
= LLVMBuildAnd(builder
, exec_mask
, ssbo_oob_cmp
, "");
812 LLVMValueRef result
= lp_build_alloca(gallivm
, bit_size
== 64 ? uint64_bld
->vec_type
: uint_bld
->vec_type
, "");
813 struct lp_build_loop_state loop_state
;
814 lp_build_loop_begin(&loop_state
, gallivm
, lp_build_const_int32(gallivm
, 0));
816 struct lp_build_if_state ifthen
;
817 LLVMValueRef cond
, temp_res
;
819 loop_index
= LLVMBuildExtractElement(gallivm
->builder
, loop_index
,
820 loop_state
.counter
, "");
822 cond
= LLVMBuildICmp(gallivm
->builder
, LLVMIntNE
, exec_mask
, uint_bld
->zero
, "");
823 cond
= LLVMBuildExtractElement(gallivm
->builder
, cond
, loop_state
.counter
, "");
825 lp_build_if(&ifthen
, gallivm
, cond
);
827 if (bit_size
== 64) {
828 LLVMValueRef ssbo_ptr2
= LLVMBuildBitCast(builder
, ssbo_ptr
, LLVMPointerType(uint64_bld
->elem_type
, 0), "");
829 scalar
= lp_build_pointer_get(builder
, ssbo_ptr2
, loop_index
);
831 scalar
= lp_build_pointer_get(builder
, ssbo_ptr
, loop_index
);
833 temp_res
= LLVMBuildLoad(builder
, result
, "");
834 temp_res
= LLVMBuildInsertElement(builder
, temp_res
, scalar
, loop_state
.counter
, "");
835 LLVMBuildStore(builder
, temp_res
, result
);
836 lp_build_else(&ifthen
);
837 temp_res
= LLVMBuildLoad(builder
, result
, "");
840 zero
= LLVMConstInt(LLVMInt64TypeInContext(gallivm
->context
), 0, 0);
842 zero
= lp_build_const_int32(gallivm
, 0);
843 temp_res
= LLVMBuildInsertElement(builder
, temp_res
, zero
, loop_state
.counter
, "");
844 LLVMBuildStore(builder
, temp_res
, result
);
845 lp_build_endif(&ifthen
);
846 lp_build_loop_end_cond(&loop_state
, lp_build_const_int32(gallivm
, uint_bld
->type
.length
),
848 outval
[c
] = LLVMBuildLoad(gallivm
->builder
, result
, "");
852 static void emit_store_mem(struct lp_build_nir_context
*bld_base
,
860 struct gallivm_state
*gallivm
= bld_base
->base
.gallivm
;
861 struct lp_build_nir_soa_context
*bld
= (struct lp_build_nir_soa_context
*)bld_base
;
862 LLVMBuilderRef builder
= bld
->bld_base
.base
.gallivm
->builder
;
863 LLVMValueRef ssbo_ptr
;
864 struct lp_build_context
*uint_bld
= &bld_base
->uint_bld
;
865 LLVMValueRef ssbo_limit
= NULL
;
868 LLVMValueRef ssbo_size_ptr
= lp_build_array_get(gallivm
, bld
->ssbo_sizes_ptr
, LLVMBuildExtractElement(builder
, index
, lp_build_const_int32(gallivm
, 0), ""));
869 ssbo_limit
= LLVMBuildAShr(gallivm
->builder
, ssbo_size_ptr
, lp_build_const_int32(gallivm
, bit_size
== 64 ? 3 : 2), "");
870 ssbo_limit
= lp_build_broadcast_scalar(uint_bld
, ssbo_limit
);
871 ssbo_ptr
= lp_build_array_get(gallivm
, bld
->ssbo_ptr
, LLVMBuildExtractElement(builder
, index
, lp_build_const_int32(gallivm
, 0), ""));
873 ssbo_ptr
= bld
->shared_ptr
;
875 offset
= lp_build_shr_imm(uint_bld
, offset
, bit_size
== 64 ? 3 : 2);
876 for (unsigned c
= 0; c
< nc
; c
++) {
877 if (!(writemask
& (1u << c
)))
879 LLVMValueRef loop_index
= lp_build_add(uint_bld
, offset
, lp_build_const_int_vec(gallivm
, uint_bld
->type
, c
));
880 LLVMValueRef val
= (nc
== 1) ? dst
: LLVMBuildExtractValue(builder
, dst
, c
, "");
882 LLVMValueRef exec_mask
= mask_vec(bld_base
);
884 LLVMValueRef ssbo_oob_cmp
= lp_build_cmp(uint_bld
, PIPE_FUNC_LESS
, loop_index
, ssbo_limit
);
885 exec_mask
= LLVMBuildAnd(builder
, exec_mask
, ssbo_oob_cmp
, "");
888 struct lp_build_loop_state loop_state
;
889 lp_build_loop_begin(&loop_state
, gallivm
, lp_build_const_int32(gallivm
, 0));
890 LLVMValueRef value_ptr
= LLVMBuildExtractElement(gallivm
->builder
, val
,
891 loop_state
.counter
, "");
893 value_ptr
= LLVMBuildBitCast(gallivm
->builder
, value_ptr
, bld_base
->uint64_bld
.elem_type
, "");
895 value_ptr
= LLVMBuildBitCast(gallivm
->builder
, value_ptr
, uint_bld
->elem_type
, "");
896 struct lp_build_if_state ifthen
;
899 loop_index
= LLVMBuildExtractElement(gallivm
->builder
, loop_index
,
900 loop_state
.counter
, "");
901 cond
= LLVMBuildICmp(gallivm
->builder
, LLVMIntNE
, exec_mask
, uint_bld
->zero
, "");
902 cond
= LLVMBuildExtractElement(gallivm
->builder
, cond
, loop_state
.counter
, "");
903 lp_build_if(&ifthen
, gallivm
, cond
);
904 if (bit_size
== 64) {
905 LLVMValueRef ssbo_ptr2
= LLVMBuildBitCast(builder
, ssbo_ptr
, LLVMPointerType(bld_base
->uint64_bld
.elem_type
, 0), "");
906 lp_build_pointer_set(builder
, ssbo_ptr2
, loop_index
, value_ptr
);
908 lp_build_pointer_set(builder
, ssbo_ptr
, loop_index
, value_ptr
);
909 lp_build_endif(&ifthen
);
910 lp_build_loop_end_cond(&loop_state
, lp_build_const_int32(gallivm
, uint_bld
->type
.length
),
915 static void emit_atomic_mem(struct lp_build_nir_context
*bld_base
,
916 nir_intrinsic_op nir_op
,
917 LLVMValueRef index
, LLVMValueRef offset
,
918 LLVMValueRef val
, LLVMValueRef val2
,
919 LLVMValueRef
*result
)
921 struct gallivm_state
*gallivm
= bld_base
->base
.gallivm
;
922 struct lp_build_nir_soa_context
*bld
= (struct lp_build_nir_soa_context
*)bld_base
;
923 LLVMBuilderRef builder
= bld
->bld_base
.base
.gallivm
->builder
;
924 LLVMValueRef ssbo_ptr
;
925 struct lp_build_context
*uint_bld
= &bld_base
->uint_bld
;
926 LLVMValueRef ssbo_limit
= NULL
;
929 LLVMValueRef ssbo_size_ptr
= lp_build_array_get(gallivm
, bld
->ssbo_sizes_ptr
, LLVMBuildExtractElement(builder
, index
, lp_build_const_int32(gallivm
, 0), ""));
930 ssbo_limit
= LLVMBuildAShr(gallivm
->builder
, ssbo_size_ptr
, lp_build_const_int32(gallivm
, 2), "");
931 ssbo_limit
= lp_build_broadcast_scalar(uint_bld
, ssbo_limit
);
932 ssbo_ptr
= lp_build_array_get(gallivm
, bld
->ssbo_ptr
, LLVMBuildExtractElement(builder
, index
, lp_build_const_int32(gallivm
, 0), ""));
934 ssbo_ptr
= bld
->shared_ptr
;
936 offset
= lp_build_shr_imm(uint_bld
, offset
, 2);
937 LLVMValueRef atom_res
= lp_build_alloca(gallivm
,
938 uint_bld
->vec_type
, "");
940 LLVMValueRef exec_mask
= mask_vec(bld_base
);
942 LLVMValueRef ssbo_oob_cmp
= lp_build_cmp(uint_bld
, PIPE_FUNC_LESS
, offset
, ssbo_limit
);
943 exec_mask
= LLVMBuildAnd(builder
, exec_mask
, ssbo_oob_cmp
, "");
946 struct lp_build_loop_state loop_state
;
947 lp_build_loop_begin(&loop_state
, gallivm
, lp_build_const_int32(gallivm
, 0));
949 LLVMValueRef value_ptr
= LLVMBuildExtractElement(gallivm
->builder
, val
,
950 loop_state
.counter
, "");
951 value_ptr
= LLVMBuildBitCast(gallivm
->builder
, value_ptr
, uint_bld
->elem_type
, "");
953 offset
= LLVMBuildExtractElement(gallivm
->builder
, offset
,
954 loop_state
.counter
, "");
956 LLVMValueRef scalar_ptr
= LLVMBuildGEP(builder
, ssbo_ptr
,
959 struct lp_build_if_state ifthen
;
960 LLVMValueRef cond
, temp_res
;
962 cond
= LLVMBuildICmp(gallivm
->builder
, LLVMIntNE
, exec_mask
, uint_bld
->zero
, "");
963 cond
= LLVMBuildExtractElement(gallivm
->builder
, cond
, loop_state
.counter
, "");
964 lp_build_if(&ifthen
, gallivm
, cond
);
966 if (nir_op
== nir_intrinsic_ssbo_atomic_comp_swap
|| nir_op
== nir_intrinsic_shared_atomic_comp_swap
) {
967 LLVMValueRef cas_src_ptr
= LLVMBuildExtractElement(gallivm
->builder
, val2
,
968 loop_state
.counter
, "");
969 cas_src_ptr
= LLVMBuildBitCast(gallivm
->builder
, cas_src_ptr
, uint_bld
->elem_type
, "");
970 scalar
= LLVMBuildAtomicCmpXchg(builder
, scalar_ptr
, value_ptr
,
972 LLVMAtomicOrderingSequentiallyConsistent
,
973 LLVMAtomicOrderingSequentiallyConsistent
,
975 scalar
= LLVMBuildExtractValue(gallivm
->builder
, scalar
, 0, "");
977 LLVMAtomicRMWBinOp op
;
980 case nir_intrinsic_shared_atomic_add
:
981 case nir_intrinsic_ssbo_atomic_add
:
982 op
= LLVMAtomicRMWBinOpAdd
;
984 case nir_intrinsic_shared_atomic_exchange
:
985 case nir_intrinsic_ssbo_atomic_exchange
:
986 op
= LLVMAtomicRMWBinOpXchg
;
988 case nir_intrinsic_shared_atomic_and
:
989 case nir_intrinsic_ssbo_atomic_and
:
990 op
= LLVMAtomicRMWBinOpAnd
;
992 case nir_intrinsic_shared_atomic_or
:
993 case nir_intrinsic_ssbo_atomic_or
:
994 op
= LLVMAtomicRMWBinOpOr
;
996 case nir_intrinsic_shared_atomic_xor
:
997 case nir_intrinsic_ssbo_atomic_xor
:
998 op
= LLVMAtomicRMWBinOpXor
;
1000 case nir_intrinsic_shared_atomic_umin
:
1001 case nir_intrinsic_ssbo_atomic_umin
:
1002 op
= LLVMAtomicRMWBinOpUMin
;
1004 case nir_intrinsic_shared_atomic_umax
:
1005 case nir_intrinsic_ssbo_atomic_umax
:
1006 op
= LLVMAtomicRMWBinOpUMax
;
1008 case nir_intrinsic_ssbo_atomic_imin
:
1009 case nir_intrinsic_shared_atomic_imin
:
1010 op
= LLVMAtomicRMWBinOpMin
;
1012 case nir_intrinsic_ssbo_atomic_imax
:
1013 case nir_intrinsic_shared_atomic_imax
:
1014 op
= LLVMAtomicRMWBinOpMax
;
1017 unreachable("unknown atomic op");
1019 scalar
= LLVMBuildAtomicRMW(builder
, op
,
1020 scalar_ptr
, value_ptr
,
1021 LLVMAtomicOrderingSequentiallyConsistent
,
1024 temp_res
= LLVMBuildLoad(builder
, atom_res
, "");
1025 temp_res
= LLVMBuildInsertElement(builder
, temp_res
, scalar
, loop_state
.counter
, "");
1026 LLVMBuildStore(builder
, temp_res
, atom_res
);
1027 lp_build_else(&ifthen
);
1028 temp_res
= LLVMBuildLoad(builder
, atom_res
, "");
1029 temp_res
= LLVMBuildInsertElement(builder
, temp_res
, lp_build_const_int32(gallivm
, 0), loop_state
.counter
, "");
1030 LLVMBuildStore(builder
, temp_res
, atom_res
);
1031 lp_build_endif(&ifthen
);
1033 lp_build_loop_end_cond(&loop_state
, lp_build_const_int32(gallivm
, uint_bld
->type
.length
),
1035 *result
= LLVMBuildLoad(builder
, atom_res
, "");
1038 static void emit_barrier(struct lp_build_nir_context
*bld_base
)
1040 struct lp_build_nir_soa_context
*bld
= (struct lp_build_nir_soa_context
*)bld_base
;
1041 struct gallivm_state
* gallivm
= bld_base
->base
.gallivm
;
1043 LLVMBasicBlockRef resume
= lp_build_insert_new_block(gallivm
, "resume");
1045 lp_build_coro_suspend_switch(gallivm
, bld
->coro
, resume
, false);
1046 LLVMPositionBuilderAtEnd(gallivm
->builder
, resume
);
1049 static LLVMValueRef
emit_get_buffer_size(struct lp_build_nir_context
*bld_base
,
1052 struct gallivm_state
*gallivm
= bld_base
->base
.gallivm
;
1053 struct lp_build_nir_soa_context
*bld
= (struct lp_build_nir_soa_context
*)bld_base
;
1054 LLVMBuilderRef builder
= bld
->bld_base
.base
.gallivm
->builder
;
1055 struct lp_build_context
*bld_broad
= &bld_base
->uint_bld
;
1056 LLVMValueRef size_ptr
= lp_build_array_get(bld_base
->base
.gallivm
, bld
->ssbo_sizes_ptr
,
1057 LLVMBuildExtractElement(builder
, index
, lp_build_const_int32(gallivm
, 0), ""));
1058 return lp_build_broadcast_scalar(bld_broad
, size_ptr
);
1061 static void emit_image_op(struct lp_build_nir_context
*bld_base
,
1062 struct lp_img_params
*params
)
1064 struct lp_build_nir_soa_context
*bld
= (struct lp_build_nir_soa_context
*)bld_base
;
1065 params
->type
= bld_base
->base
.type
;
1066 params
->context_ptr
= bld
->context_ptr
;
1067 params
->thread_data_ptr
= bld
->thread_data_ptr
;
1068 params
->exec_mask
= mask_vec(bld_base
);
1069 bld
->image
->emit_op(bld
->image
,
1070 bld
->bld_base
.base
.gallivm
,
1075 static void emit_image_size(struct lp_build_nir_context
*bld_base
,
1076 struct lp_sampler_size_query_params
*params
)
1078 struct lp_build_nir_soa_context
*bld
= (struct lp_build_nir_soa_context
*)bld_base
;
1080 params
->int_type
= bld_base
->int_bld
.type
;
1081 params
->context_ptr
= bld
->context_ptr
;
1083 bld
->image
->emit_size_query(bld
->image
,
1084 bld
->bld_base
.base
.gallivm
,
1089 static void init_var_slots(struct lp_build_nir_context
*bld_base
,
1090 nir_variable
*var
, unsigned sc
)
1092 struct lp_build_nir_soa_context
*bld
= (struct lp_build_nir_soa_context
*)bld_base
;
1093 unsigned slots
= glsl_count_attribute_slots(var
->type
, false) * 4;
1095 for (unsigned comp
= sc
; comp
< slots
+ sc
; comp
++) {
1096 unsigned this_loc
= var
->data
.driver_location
+ (comp
/ 4);
1097 unsigned this_chan
= comp
% 4;
1099 if (!bld
->outputs
[this_loc
][this_chan
])
1100 bld
->outputs
[this_loc
][this_chan
] = lp_build_alloca(bld_base
->base
.gallivm
,
1101 bld_base
->base
.vec_type
, "output");
1105 static void emit_var_decl(struct lp_build_nir_context
*bld_base
,
1108 unsigned sc
= var
->data
.location_frac
;
1109 switch (var
->data
.mode
) {
1110 case nir_var_shader_out
: {
1111 if (bld_base
->shader
->info
.stage
== MESA_SHADER_FRAGMENT
) {
1112 if (var
->data
.location
== FRAG_RESULT_STENCIL
)
1114 else if (var
->data
.location
== FRAG_RESULT_DEPTH
)
1117 init_var_slots(bld_base
, var
, sc
);
1125 static void emit_tex(struct lp_build_nir_context
*bld_base
,
1126 struct lp_sampler_params
*params
)
1128 struct lp_build_nir_soa_context
*bld
= (struct lp_build_nir_soa_context
*)bld_base
;
1130 params
->type
= bld_base
->base
.type
;
1131 params
->context_ptr
= bld
->context_ptr
;
1132 params
->thread_data_ptr
= bld
->thread_data_ptr
;
1134 bld
->sampler
->emit_tex_sample(bld
->sampler
,
1135 bld
->bld_base
.base
.gallivm
,
1139 static void emit_tex_size(struct lp_build_nir_context
*bld_base
,
1140 struct lp_sampler_size_query_params
*params
)
1142 struct lp_build_nir_soa_context
*bld
= (struct lp_build_nir_soa_context
*)bld_base
;
1144 params
->int_type
= bld_base
->int_bld
.type
;
1145 params
->context_ptr
= bld
->context_ptr
;
1147 bld
->sampler
->emit_size_query(bld
->sampler
,
1148 bld
->bld_base
.base
.gallivm
,
1152 static void emit_sysval_intrin(struct lp_build_nir_context
*bld_base
,
1153 nir_intrinsic_instr
*instr
,
1154 LLVMValueRef result
[NIR_MAX_VEC_COMPONENTS
])
1156 struct lp_build_nir_soa_context
*bld
= (struct lp_build_nir_soa_context
*)bld_base
;
1157 struct gallivm_state
*gallivm
= bld_base
->base
.gallivm
;
1158 switch (instr
->intrinsic
) {
1159 case nir_intrinsic_load_instance_id
:
1160 result
[0] = lp_build_broadcast_scalar(&bld_base
->uint_bld
, bld
->system_values
.instance_id
);
1162 case nir_intrinsic_load_base_instance
:
1163 result
[0] = lp_build_broadcast_scalar(&bld_base
->uint_bld
, bld
->system_values
.base_instance
);
1165 case nir_intrinsic_load_base_vertex
:
1166 result
[0] = bld
->system_values
.basevertex
;
1168 case nir_intrinsic_load_vertex_id
:
1169 result
[0] = bld
->system_values
.vertex_id
;
1171 case nir_intrinsic_load_primitive_id
:
1172 result
[0] = bld
->system_values
.prim_id
;
1174 case nir_intrinsic_load_work_group_id
:
1175 for (unsigned i
= 0; i
< 3; i
++)
1176 result
[i
] = lp_build_broadcast_scalar(&bld_base
->uint_bld
, LLVMBuildExtractElement(gallivm
->builder
, bld
->system_values
.block_id
, lp_build_const_int32(gallivm
, i
), ""));
1178 case nir_intrinsic_load_local_invocation_id
:
1179 for (unsigned i
= 0; i
< 3; i
++)
1180 result
[i
] = LLVMBuildExtractValue(gallivm
->builder
, bld
->system_values
.thread_id
, i
, "");
1182 case nir_intrinsic_load_num_work_groups
:
1183 for (unsigned i
= 0; i
< 3; i
++)
1184 result
[i
] = lp_build_broadcast_scalar(&bld_base
->uint_bld
, LLVMBuildExtractElement(gallivm
->builder
, bld
->system_values
.grid_size
, lp_build_const_int32(gallivm
, i
), ""));
1186 case nir_intrinsic_load_invocation_id
:
1187 result
[0] = lp_build_broadcast_scalar(&bld_base
->uint_bld
, bld
->system_values
.invocation_id
);
1189 case nir_intrinsic_load_front_face
:
1190 result
[0] = lp_build_broadcast_scalar(&bld_base
->uint_bld
, bld
->system_values
.front_facing
);
1192 case nir_intrinsic_load_draw_id
:
1193 result
[0] = lp_build_broadcast_scalar(&bld_base
->uint_bld
, bld
->system_values
.draw_id
);
1197 case nir_intrinsic_load_local_group_size
:
1198 for (unsigned i
= 0; i
< 3; i
++)
1199 result
[i
] = lp_build_broadcast_scalar(&bld_base
->uint_bld
, LLVMBuildExtractElement(gallivm
->builder
, bld
->system_values
.block_size
, lp_build_const_int32(gallivm
, i
), ""));
1201 case nir_intrinsic_load_work_dim
:
1202 result
[0] = lp_build_broadcast_scalar(&bld_base
->uint_bld
, bld
->system_values
.work_dim
);
1207 static void bgnloop(struct lp_build_nir_context
*bld_base
)
1209 struct lp_build_nir_soa_context
*bld
= (struct lp_build_nir_soa_context
*)bld_base
;
1210 lp_exec_bgnloop(&bld
->exec_mask
, true);
1213 static void endloop(struct lp_build_nir_context
*bld_base
)
1215 struct lp_build_nir_soa_context
*bld
= (struct lp_build_nir_soa_context
*)bld_base
;
1216 lp_exec_endloop(bld_base
->base
.gallivm
, &bld
->exec_mask
);
1219 static void if_cond(struct lp_build_nir_context
*bld_base
, LLVMValueRef cond
)
1221 LLVMBuilderRef builder
= bld_base
->base
.gallivm
->builder
;
1222 struct lp_build_nir_soa_context
*bld
= (struct lp_build_nir_soa_context
*)bld_base
;
1223 lp_exec_mask_cond_push(&bld
->exec_mask
, LLVMBuildBitCast(builder
, cond
, bld_base
->base
.int_vec_type
, ""));
1226 static void else_stmt(struct lp_build_nir_context
*bld_base
)
1228 struct lp_build_nir_soa_context
*bld
= (struct lp_build_nir_soa_context
*)bld_base
;
1229 lp_exec_mask_cond_invert(&bld
->exec_mask
);
1232 static void endif_stmt(struct lp_build_nir_context
*bld_base
)
1234 struct lp_build_nir_soa_context
*bld
= (struct lp_build_nir_soa_context
*)bld_base
;
1235 lp_exec_mask_cond_pop(&bld
->exec_mask
);
1238 static void break_stmt(struct lp_build_nir_context
*bld_base
)
1240 struct lp_build_nir_soa_context
*bld
= (struct lp_build_nir_soa_context
*)bld_base
;
1242 lp_exec_break(&bld
->exec_mask
, NULL
, false);
1245 static void continue_stmt(struct lp_build_nir_context
*bld_base
)
1247 struct lp_build_nir_soa_context
*bld
= (struct lp_build_nir_soa_context
*)bld_base
;
1248 lp_exec_continue(&bld
->exec_mask
);
1251 static void discard(struct lp_build_nir_context
*bld_base
, LLVMValueRef cond
)
1253 struct lp_build_nir_soa_context
*bld
= (struct lp_build_nir_soa_context
*)bld_base
;
1254 LLVMBuilderRef builder
= bld
->bld_base
.base
.gallivm
->builder
;
1258 if (bld
->exec_mask
.has_mask
) {
1259 mask
= LLVMBuildNot(builder
, bld
->exec_mask
.exec_mask
, "kilp");
1261 mask
= LLVMConstNull(bld
->bld_base
.base
.int_vec_type
);
1264 mask
= LLVMBuildNot(builder
, cond
, "");
1265 if (bld
->exec_mask
.has_mask
) {
1266 LLVMValueRef invmask
;
1267 invmask
= LLVMBuildNot(builder
, bld
->exec_mask
.exec_mask
, "kilp");
1268 mask
= LLVMBuildOr(builder
, mask
, invmask
, "");
1271 lp_build_mask_update(bld
->mask
, mask
);
1275 increment_vec_ptr_by_mask(struct lp_build_nir_context
* bld_base
,
1279 LLVMBuilderRef builder
= bld_base
->base
.gallivm
->builder
;
1280 LLVMValueRef current_vec
= LLVMBuildLoad(builder
, ptr
, "");
1282 current_vec
= LLVMBuildSub(builder
, current_vec
, mask
, "");
1284 LLVMBuildStore(builder
, current_vec
, ptr
);
1288 clear_uint_vec_ptr_from_mask(struct lp_build_nir_context
* bld_base
,
1292 LLVMBuilderRef builder
= bld_base
->base
.gallivm
->builder
;
1293 LLVMValueRef current_vec
= LLVMBuildLoad(builder
, ptr
, "");
1295 current_vec
= lp_build_select(&bld_base
->uint_bld
,
1297 bld_base
->uint_bld
.zero
,
1300 LLVMBuildStore(builder
, current_vec
, ptr
);
1304 clamp_mask_to_max_output_vertices(struct lp_build_nir_soa_context
* bld
,
1305 LLVMValueRef current_mask_vec
,
1306 LLVMValueRef total_emitted_vertices_vec
)
1308 LLVMBuilderRef builder
= bld
->bld_base
.base
.gallivm
->builder
;
1309 struct lp_build_context
*int_bld
= &bld
->bld_base
.int_bld
;
1310 LLVMValueRef max_mask
= lp_build_cmp(int_bld
, PIPE_FUNC_LESS
,
1311 total_emitted_vertices_vec
,
1312 bld
->max_output_vertices_vec
);
1314 return LLVMBuildAnd(builder
, current_mask_vec
, max_mask
, "");
1317 static void emit_vertex(struct lp_build_nir_context
*bld_base
, uint32_t stream_id
)
1319 struct lp_build_nir_soa_context
*bld
= (struct lp_build_nir_soa_context
*)bld_base
;
1320 LLVMBuilderRef builder
= bld
->bld_base
.base
.gallivm
->builder
;
1322 assert(bld
->gs_iface
->emit_vertex
);
1323 LLVMValueRef total_emitted_vertices_vec
=
1324 LLVMBuildLoad(builder
, bld
->total_emitted_vertices_vec_ptr
[stream_id
], "");
1325 LLVMValueRef mask
= mask_vec(bld_base
);
1326 mask
= clamp_mask_to_max_output_vertices(bld
, mask
,
1327 total_emitted_vertices_vec
);
1328 bld
->gs_iface
->emit_vertex(bld
->gs_iface
, &bld
->bld_base
.base
,
1330 total_emitted_vertices_vec
,
1331 lp_build_const_int_vec(bld
->bld_base
.base
.gallivm
, bld
->bld_base
.base
.type
, stream_id
));
1333 increment_vec_ptr_by_mask(bld_base
, bld
->emitted_vertices_vec_ptr
[stream_id
],
1335 increment_vec_ptr_by_mask(bld_base
, bld
->total_emitted_vertices_vec_ptr
[stream_id
],
1340 end_primitive_masked(struct lp_build_nir_context
* bld_base
,
1341 LLVMValueRef mask
, uint32_t stream_id
)
1343 struct lp_build_nir_soa_context
*bld
= (struct lp_build_nir_soa_context
*)bld_base
;
1344 LLVMBuilderRef builder
= bld
->bld_base
.base
.gallivm
->builder
;
1346 struct lp_build_context
*uint_bld
= &bld_base
->uint_bld
;
1347 LLVMValueRef emitted_vertices_vec
=
1348 LLVMBuildLoad(builder
, bld
->emitted_vertices_vec_ptr
[stream_id
], "");
1349 LLVMValueRef emitted_prims_vec
=
1350 LLVMBuildLoad(builder
, bld
->emitted_prims_vec_ptr
[stream_id
], "");
1351 LLVMValueRef total_emitted_vertices_vec
=
1352 LLVMBuildLoad(builder
, bld
->total_emitted_vertices_vec_ptr
[stream_id
], "");
1354 LLVMValueRef emitted_mask
= lp_build_cmp(uint_bld
,
1356 emitted_vertices_vec
,
1358 mask
= LLVMBuildAnd(builder
, mask
, emitted_mask
, "");
1360 bld
->gs_iface
->end_primitive(bld
->gs_iface
, &bld
->bld_base
.base
,
1361 total_emitted_vertices_vec
,
1362 emitted_vertices_vec
, emitted_prims_vec
, mask_vec(bld_base
));
1363 increment_vec_ptr_by_mask(bld_base
, bld
->emitted_prims_vec_ptr
[stream_id
],
1365 clear_uint_vec_ptr_from_mask(bld_base
, bld
->emitted_vertices_vec_ptr
[stream_id
],
1369 static void end_primitive(struct lp_build_nir_context
*bld_base
, uint32_t stream_id
)
1371 ASSERTED
struct lp_build_nir_soa_context
*bld
= (struct lp_build_nir_soa_context
*)bld_base
;
1373 assert(bld
->gs_iface
->end_primitive
);
1375 LLVMValueRef mask
= mask_vec(bld_base
);
1376 end_primitive_masked(bld_base
, mask
, stream_id
);
1380 emit_prologue(struct lp_build_nir_soa_context
*bld
)
1382 struct gallivm_state
* gallivm
= bld
->bld_base
.base
.gallivm
;
1383 if (bld
->indirects
& nir_var_shader_in
&& !bld
->gs_iface
) {
1384 uint32_t num_inputs
= util_bitcount64(bld
->bld_base
.shader
->info
.inputs_read
);
1385 unsigned index
, chan
;
1386 LLVMTypeRef vec_type
= bld
->bld_base
.base
.vec_type
;
1387 LLVMValueRef array_size
= lp_build_const_int32(gallivm
, num_inputs
* 4);
1388 bld
->inputs_array
= lp_build_array_alloca(gallivm
,
1389 vec_type
, array_size
,
1392 for (index
= 0; index
< num_inputs
; ++index
) {
1393 for (chan
= 0; chan
< TGSI_NUM_CHANNELS
; ++chan
) {
1394 LLVMValueRef lindex
=
1395 lp_build_const_int32(gallivm
, index
* 4 + chan
);
1396 LLVMValueRef input_ptr
=
1397 LLVMBuildGEP(gallivm
->builder
, bld
->inputs_array
,
1399 LLVMValueRef value
= bld
->inputs
[index
][chan
];
1401 LLVMBuildStore(gallivm
->builder
, value
, input_ptr
);
1407 static void emit_vote(struct lp_build_nir_context
*bld_base
, LLVMValueRef src
, nir_intrinsic_instr
*instr
, LLVMValueRef result
[4])
1409 struct gallivm_state
* gallivm
= bld_base
->base
.gallivm
;
1410 LLVMBuilderRef builder
= gallivm
->builder
;
1412 LLVMValueRef exec_mask
= mask_vec(bld_base
);
1413 struct lp_build_loop_state loop_state
;
1415 LLVMValueRef outer_cond
= LLVMBuildICmp(builder
, LLVMIntNE
, exec_mask
, bld_base
->uint_bld
.zero
, "");
1417 LLVMValueRef res_store
= lp_build_alloca(gallivm
, bld_base
->int_bld
.elem_type
, "");
1418 LLVMValueRef init_val
= NULL
;
1419 if (instr
->intrinsic
== nir_intrinsic_vote_ieq
) {
1420 /* for equal we unfortunately have to loop and find the first valid one. */
1421 lp_build_loop_begin(&loop_state
, gallivm
, lp_build_const_int32(gallivm
, 0));
1422 LLVMValueRef if_cond
= LLVMBuildExtractElement(gallivm
->builder
, outer_cond
, loop_state
.counter
, "");
1424 struct lp_build_if_state ifthen
;
1425 lp_build_if(&ifthen
, gallivm
, if_cond
);
1426 LLVMValueRef value_ptr
= LLVMBuildExtractElement(gallivm
->builder
, src
,
1427 loop_state
.counter
, "");
1428 LLVMBuildStore(builder
, value_ptr
, res_store
);
1429 lp_build_endif(&ifthen
);
1430 lp_build_loop_end_cond(&loop_state
, lp_build_const_int32(gallivm
, bld_base
->uint_bld
.type
.length
),
1432 lp_build_print_value(gallivm
, "init_val is ", LLVMBuildLoad(builder
, res_store
, ""));
1433 init_val
= LLVMBuildLoad(builder
, res_store
, "");
1435 LLVMBuildStore(builder
, lp_build_const_int32(gallivm
, instr
->intrinsic
== nir_intrinsic_vote_any
? 0 : -1), res_store
);
1439 lp_build_loop_begin(&loop_state
, gallivm
, lp_build_const_int32(gallivm
, 0));
1440 LLVMValueRef value_ptr
= LLVMBuildExtractElement(gallivm
->builder
, src
,
1441 loop_state
.counter
, "");
1442 struct lp_build_if_state ifthen
;
1443 LLVMValueRef if_cond
;
1444 if_cond
= LLVMBuildExtractElement(gallivm
->builder
, outer_cond
, loop_state
.counter
, "");
1446 lp_build_if(&ifthen
, gallivm
, if_cond
);
1447 res
= LLVMBuildLoad(builder
, res_store
, "");
1449 if (instr
->intrinsic
== nir_intrinsic_vote_ieq
) {
1450 LLVMValueRef tmp
= LLVMBuildICmp(builder
, LLVMIntEQ
, init_val
, value_ptr
, "");
1451 tmp
= LLVMBuildSExt(builder
, tmp
, bld_base
->uint_bld
.elem_type
, "");
1452 res
= LLVMBuildOr(builder
, res
, tmp
, "");
1453 } else if (instr
->intrinsic
== nir_intrinsic_vote_any
)
1454 res
= LLVMBuildOr(builder
, res
, value_ptr
, "");
1456 res
= LLVMBuildAnd(builder
, res
, value_ptr
, "");
1457 LLVMBuildStore(builder
, res
, res_store
);
1458 lp_build_endif(&ifthen
);
1459 lp_build_loop_end_cond(&loop_state
, lp_build_const_int32(gallivm
, bld_base
->uint_bld
.type
.length
),
1461 result
[0] = lp_build_broadcast_scalar(&bld_base
->uint_bld
, LLVMBuildLoad(builder
, res_store
, ""));
1464 void lp_build_nir_soa(struct gallivm_state
*gallivm
,
1465 struct nir_shader
*shader
,
1466 const struct lp_build_tgsi_params
*params
,
1467 LLVMValueRef (*outputs
)[4])
1469 struct lp_build_nir_soa_context bld
;
1470 struct lp_type type
= params
->type
;
1471 struct lp_type res_type
;
1473 assert(type
.length
<= LP_MAX_VECTOR_LENGTH
);
1474 memset(&res_type
, 0, sizeof res_type
);
1475 res_type
.width
= type
.width
;
1476 res_type
.length
= type
.length
;
1479 /* Setup build context */
1480 memset(&bld
, 0, sizeof bld
);
1481 lp_build_context_init(&bld
.bld_base
.base
, gallivm
, type
);
1482 lp_build_context_init(&bld
.bld_base
.uint_bld
, gallivm
, lp_uint_type(type
));
1483 lp_build_context_init(&bld
.bld_base
.int_bld
, gallivm
, lp_int_type(type
));
1484 lp_build_context_init(&bld
.elem_bld
, gallivm
, lp_elem_type(type
));
1485 lp_build_context_init(&bld
.uint_elem_bld
, gallivm
, lp_elem_type(lp_uint_type(type
)));
1487 struct lp_type dbl_type
;
1489 dbl_type
.width
*= 2;
1490 lp_build_context_init(&bld
.bld_base
.dbl_bld
, gallivm
, dbl_type
);
1493 struct lp_type uint64_type
;
1494 uint64_type
= lp_uint_type(type
);
1495 uint64_type
.width
*= 2;
1496 lp_build_context_init(&bld
.bld_base
.uint64_bld
, gallivm
, uint64_type
);
1499 struct lp_type int64_type
;
1500 int64_type
= lp_int_type(type
);
1501 int64_type
.width
*= 2;
1502 lp_build_context_init(&bld
.bld_base
.int64_bld
, gallivm
, int64_type
);
1505 struct lp_type uint16_type
;
1506 uint16_type
= lp_uint_type(type
);
1507 uint16_type
.width
/= 2;
1508 lp_build_context_init(&bld
.bld_base
.uint16_bld
, gallivm
, uint16_type
);
1511 struct lp_type int16_type
;
1512 int16_type
= lp_int_type(type
);
1513 int16_type
.width
/= 2;
1514 lp_build_context_init(&bld
.bld_base
.int16_bld
, gallivm
, int16_type
);
1517 struct lp_type uint8_type
;
1518 uint8_type
= lp_uint_type(type
);
1519 uint8_type
.width
/= 4;
1520 lp_build_context_init(&bld
.bld_base
.uint8_bld
, gallivm
, uint8_type
);
1523 struct lp_type int8_type
;
1524 int8_type
= lp_int_type(type
);
1525 int8_type
.width
/= 4;
1526 lp_build_context_init(&bld
.bld_base
.int8_bld
, gallivm
, int8_type
);
1528 bld
.bld_base
.load_var
= emit_load_var
;
1529 bld
.bld_base
.store_var
= emit_store_var
;
1530 bld
.bld_base
.load_reg
= emit_load_reg
;
1531 bld
.bld_base
.store_reg
= emit_store_reg
;
1532 bld
.bld_base
.emit_var_decl
= emit_var_decl
;
1533 bld
.bld_base
.load_ubo
= emit_load_ubo
;
1534 bld
.bld_base
.load_kernel_arg
= emit_load_kernel_arg
;
1535 bld
.bld_base
.load_global
= emit_load_global
;
1536 bld
.bld_base
.store_global
= emit_store_global
;
1537 bld
.bld_base
.atomic_global
= emit_atomic_global
;
1538 bld
.bld_base
.tex
= emit_tex
;
1539 bld
.bld_base
.tex_size
= emit_tex_size
;
1540 bld
.bld_base
.bgnloop
= bgnloop
;
1541 bld
.bld_base
.endloop
= endloop
;
1542 bld
.bld_base
.if_cond
= if_cond
;
1543 bld
.bld_base
.else_stmt
= else_stmt
;
1544 bld
.bld_base
.endif_stmt
= endif_stmt
;
1545 bld
.bld_base
.break_stmt
= break_stmt
;
1546 bld
.bld_base
.continue_stmt
= continue_stmt
;
1547 bld
.bld_base
.sysval_intrin
= emit_sysval_intrin
;
1548 bld
.bld_base
.discard
= discard
;
1549 bld
.bld_base
.emit_vertex
= emit_vertex
;
1550 bld
.bld_base
.end_primitive
= end_primitive
;
1551 bld
.bld_base
.load_mem
= emit_load_mem
;
1552 bld
.bld_base
.store_mem
= emit_store_mem
;
1553 bld
.bld_base
.get_buffer_size
= emit_get_buffer_size
;
1554 bld
.bld_base
.atomic_mem
= emit_atomic_mem
;
1555 bld
.bld_base
.barrier
= emit_barrier
;
1556 bld
.bld_base
.image_op
= emit_image_op
;
1557 bld
.bld_base
.image_size
= emit_image_size
;
1558 bld
.bld_base
.vote
= emit_vote
;
1560 bld
.mask
= params
->mask
;
1561 bld
.inputs
= params
->inputs
;
1562 bld
.outputs
= outputs
;
1563 bld
.consts_ptr
= params
->consts_ptr
;
1564 bld
.const_sizes_ptr
= params
->const_sizes_ptr
;
1565 bld
.ssbo_ptr
= params
->ssbo_ptr
;
1566 bld
.ssbo_sizes_ptr
= params
->ssbo_sizes_ptr
;
1567 bld
.sampler
= params
->sampler
;
1568 // bld.bld_base.info = params->info;
1570 bld
.context_ptr
= params
->context_ptr
;
1571 bld
.thread_data_ptr
= params
->thread_data_ptr
;
1572 bld
.image
= params
->image
;
1573 bld
.shared_ptr
= params
->shared_ptr
;
1574 bld
.coro
= params
->coro
;
1575 bld
.kernel_args_ptr
= params
->kernel_args
;
1577 if (params
->info
->indirect_files
& (1 << TGSI_FILE_INPUT
))
1578 bld
.indirects
|= nir_var_shader_in
;
1580 bld
.gs_iface
= params
->gs_iface
;
1582 struct lp_build_context
*uint_bld
= &bld
.bld_base
.uint_bld
;
1584 bld
.max_output_vertices_vec
= lp_build_const_int_vec(gallivm
, bld
.bld_base
.int_bld
.type
,
1585 shader
->info
.gs
.vertices_out
);
1586 for (int i
= 0; i
< PIPE_MAX_VERTEX_STREAMS
; i
++) {
1587 bld
.emitted_prims_vec_ptr
[i
] =
1588 lp_build_alloca(gallivm
, uint_bld
->vec_type
, "emitted_prims_ptr");
1589 bld
.emitted_vertices_vec_ptr
[i
] =
1590 lp_build_alloca(gallivm
, uint_bld
->vec_type
, "emitted_vertices_ptr");
1591 bld
.total_emitted_vertices_vec_ptr
[i
] =
1592 lp_build_alloca(gallivm
, uint_bld
->vec_type
, "total_emitted_vertices_ptr");
1595 lp_exec_mask_init(&bld
.exec_mask
, &bld
.bld_base
.int_bld
);
1597 bld
.system_values
= *params
->system_values
;
1599 bld
.bld_base
.shader
= shader
;
1601 emit_prologue(&bld
);
1602 lp_build_nir_llvm(&bld
.bld_base
, shader
);
1605 LLVMBuilderRef builder
= bld
.bld_base
.base
.gallivm
->builder
;
1606 LLVMValueRef total_emitted_vertices_vec
;
1607 LLVMValueRef emitted_prims_vec
;
1609 end_primitive_masked(&bld
.bld_base
, lp_build_mask_value(bld
.mask
), 0);
1610 for (int i
= 0; i
< PIPE_MAX_VERTEX_STREAMS
; i
++) {
1611 total_emitted_vertices_vec
=
1612 LLVMBuildLoad(builder
, bld
.total_emitted_vertices_vec_ptr
[i
], "");
1615 LLVMBuildLoad(builder
, bld
.emitted_prims_vec_ptr
[i
], "");
1616 bld
.gs_iface
->gs_epilogue(bld
.gs_iface
,
1617 total_emitted_vertices_vec
,
1618 emitted_prims_vec
, i
);
1621 lp_exec_mask_fini(&bld
.exec_mask
);