1 /**************************************************************************
3 * Copyright 2010 VMware, Inc.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
18 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 * USE OR OTHER DEALINGS IN THE SOFTWARE.
22 * The above copyright notice and this permission notice (including the
23 * next paragraph) shall be included in all copies or substantial portions
26 **************************************************************************/
29 #include "util/u_debug.h"
30 #include "lp_bld_debug.h"
31 #include "lp_bld_const.h"
32 #include "lp_bld_format.h"
33 #include "lp_bld_gather.h"
37 * Get the pointer to one element from scatter positions in memory.
39 * @sa lp_build_gather()
42 lp_build_gather_elem_ptr(LLVMBuilderRef builder
,
44 LLVMValueRef base_ptr
,
51 assert(LLVMTypeOf(base_ptr
) == LLVMPointerType(LLVMInt8Type(), 0));
57 LLVMValueRef index
= LLVMConstInt(LLVMInt32Type(), i
, 0);
58 offset
= LLVMBuildExtractElement(builder
, offsets
, index
, "");
61 ptr
= LLVMBuildGEP(builder
, base_ptr
, &offset
, 1, "");
68 * Gather one element from scatter positions in memory.
70 * @sa lp_build_gather()
73 lp_build_gather_elem(LLVMBuilderRef builder
,
77 LLVMValueRef base_ptr
,
81 LLVMTypeRef src_type
= LLVMIntType(src_width
);
82 LLVMTypeRef src_ptr_type
= LLVMPointerType(src_type
, 0);
83 LLVMTypeRef dst_elem_type
= LLVMIntType(dst_width
);
87 assert(LLVMTypeOf(base_ptr
) == LLVMPointerType(LLVMInt8Type(), 0));
89 ptr
= lp_build_gather_elem_ptr(builder
, length
, base_ptr
, offsets
, i
);
90 ptr
= LLVMBuildBitCast(builder
, ptr
, src_ptr_type
, "");
91 res
= LLVMBuildLoad(builder
, ptr
, "");
93 assert(src_width
<= dst_width
);
94 if (src_width
> dst_width
)
95 res
= LLVMBuildTrunc(builder
, res
, dst_elem_type
, "");
96 if (src_width
< dst_width
)
97 res
= LLVMBuildZExt(builder
, res
, dst_elem_type
, "");
104 * Gather elements from scatter positions in memory into a single vector.
105 * Use for fetching texels from a texture.
106 * For SSE, typical values are length=4, src_width=32, dst_width=32.
108 * @param length length of the offsets
109 * @param src_width src element width in bits
110 * @param dst_width result element width in bits (src will be expanded to fit)
111 * @param base_ptr base pointer, should be a i8 pointer type.
112 * @param offsets vector with offsets
115 lp_build_gather(LLVMBuilderRef builder
,
119 LLVMValueRef base_ptr
,
120 LLVMValueRef offsets
)
126 return lp_build_gather_elem(builder
, length
,
127 src_width
, dst_width
,
128 base_ptr
, offsets
, 0);
132 LLVMTypeRef dst_elem_type
= LLVMIntType(dst_width
);
133 LLVMTypeRef dst_vec_type
= LLVMVectorType(dst_elem_type
, length
);
136 res
= LLVMGetUndef(dst_vec_type
);
137 for (i
= 0; i
< length
; ++i
) {
138 LLVMValueRef index
= LLVMConstInt(LLVMInt32Type(), i
, 0);
140 elem
= lp_build_gather_elem(builder
, length
,
141 src_width
, dst_width
,
142 base_ptr
, offsets
, i
);
143 res
= LLVMBuildInsertElement(builder
, res
, elem
, index
, "");