Line | Branch | Exec | Source |
---|---|---|---|
1 | // Copyright Contributors to the OpenVDB Project | ||
2 | // SPDX-License-Identifier: MPL-2.0 | ||
3 | |||
4 | #include <openvdb/points/AttributeArray.h> // for native codec types | ||
5 | |||
6 | #include "Codecs.h" | ||
7 | |||
8 | #include "openvdb_ax/codegen/Functions.h" | ||
9 | #include "openvdb_ax/codegen/FunctionTypes.h" | ||
10 | #include "openvdb_ax/codegen/Types.h" | ||
11 | #include "openvdb_ax/codegen/Utils.h" | ||
12 | |||
13 | namespace openvdb { | ||
14 | OPENVDB_USE_VERSION_NAMESPACE | ||
15 | namespace OPENVDB_VERSION_NAME { | ||
16 | namespace ax { | ||
17 | namespace codegen { | ||
18 | |||
19 | /////////////////////////////////////////////////////////////////////////////// | ||
20 | /////////////////////////////////////////////////////////////////////////////// | ||
21 | |||
22 | /// Codec functions | ||
23 | |||
24 | /// @note Expected signature for decoders void(Type* out, Type* in); | ||
25 | /// @note Expected signature for encoders void(Type* out, Type* in); | ||
26 | |||
27 | using namespace codegen; | ||
28 | |||
29 | 1 | inline FunctionGroup::UniquePtr axtrncdecode() | |
30 | { | ||
31 | static auto generate = | ||
32 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 353 times.
|
353 | [](const std::vector<llvm::Value*>& args, |
33 | llvm::IRBuilder<>& B) -> llvm::Value* | ||
34 | { | ||
35 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 353 times.
|
353 | assert(args.size() == 2); |
36 | 353 | llvm::Value* out = args[0]; | |
37 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 353 times.
|
353 | llvm::Value* in = args[1]; |
38 | llvm::Type* type = in->getType()->getPointerElementType(); | ||
39 | |||
40 |
2/2✓ Branch 0 taken 352 times.
✓ Branch 1 taken 1 times.
|
353 | if (type->isIntegerTy() || type->isFloatingPointTy()) |
41 | { | ||
42 |
2/2✓ Branch 2 taken 233 times.
✓ Branch 3 taken 1 times.
|
234 | in = B.CreateLoad(in); |
43 | const bool intconversion = type->isIntegerTy(); | ||
44 |
3/4✓ Branch 0 taken 233 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 233 times.
|
234 | assert(intconversion || type->isHalfTy()); |
45 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 233 times.
|
234 | llvm::Value* result = intconversion ? |
46 | 1 | arithmeticConversion(in, B.getInt32Ty(), B) : | |
47 | 233 | arithmeticConversion(in, B.getFloatTy(), B); | |
48 | 234 | B.CreateStore(result, out); | |
49 | } | ||
50 | else { | ||
51 | std::vector<llvm::Value*> outelem, inelem; | ||
52 |
1/2✓ Branch 1 taken 119 times.
✗ Branch 2 not taken.
|
119 | arrayUnpack(out, outelem, B, /*load*/false); |
53 |
1/2✓ Branch 1 taken 119 times.
✗ Branch 2 not taken.
|
119 | arrayUnpack(in, inelem, B, /*load*/true); |
54 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 119 times.
|
119 | assert(outelem.size() == inelem.size()); |
55 |
2/2✓ Branch 0 taken 116 times.
✓ Branch 1 taken 3 times.
|
119 | const bool intconversion = inelem.front()->getType()->isIntegerTy(); |
56 |
3/4✓ Branch 0 taken 116 times.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 116 times.
|
119 | assert(intconversion || inelem.front()->getType()->isHalfTy()); |
57 | |||
58 |
3/4✓ Branch 0 taken 3 times.
✓ Branch 1 taken 116 times.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
|
122 | if (intconversion) arithmeticConversion(inelem, B.getInt32Ty(), B); |
59 |
1/2✓ Branch 1 taken 116 times.
✗ Branch 2 not taken.
|
116 | else arithmeticConversion(inelem, B.getFloatTy(), B); |
60 | |||
61 |
2/2✓ Branch 0 taken 357 times.
✓ Branch 1 taken 119 times.
|
476 | for (size_t i = 0; i < inelem.size(); ++i) { |
62 |
1/2✓ Branch 1 taken 357 times.
✗ Branch 2 not taken.
|
357 | B.CreateStore(inelem[i], outelem[i]); |
63 | } | ||
64 | } | ||
65 | 353 | return nullptr; | |
66 | }; | ||
67 | |||
68 | 1 | return FunctionBuilder("__trncdecode") | |
69 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | .addSignature<void(float*, openvdb::math::half*)>(generate) |
70 |
2/6✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
2 | .addSignature<void(int32_t*, int16_t*)>(generate) |
71 |
2/6✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
2 | .addSignature<void(openvdb::math::Vec2<int32_t>*,openvdb::math::Vec2<int16_t>*)>(generate) |
72 |
2/6✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
2 | .addSignature<void(openvdb::math::Vec2<float>*,openvdb::math::Vec2<openvdb::math::half>*)>(generate) |
73 |
2/6✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
2 | .addSignature<void(openvdb::math::Vec3<int32_t>*,openvdb::math::Vec3<int16_t>*)>(generate) |
74 |
2/6✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
2 | .addSignature<void(openvdb::math::Vec3<float>*,openvdb::math::Vec3<openvdb::math::half>*)>(generate) |
75 |
2/6✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
2 | .addSignature<void(openvdb::math::Vec4<int32_t>*,openvdb::math::Vec4<int16_t>*)>(generate) |
76 |
2/6✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
2 | .addSignature<void(openvdb::math::Vec4<float>*,openvdb::math::Vec4<openvdb::math::half>*)>(generate) |
77 | .setDocumentation("") | ||
78 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | .get(); |
79 | } | ||
80 | |||
81 | 1 | inline FunctionGroup::UniquePtr axtrncencode() | |
82 | { | ||
83 | static auto generate = | ||
84 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
|
344 | [](const std::vector<llvm::Value*>& args, |
85 | llvm::IRBuilder<>& B) -> llvm::Value* | ||
86 | { | ||
87 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
|
344 | assert(args.size() == 2); |
88 | 344 | llvm::Value* out = args[0]; | |
89 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
|
344 | llvm::Value* in = args[1]; |
90 | llvm::Type* type = in->getType()->getPointerElementType(); | ||
91 | |||
92 |
2/2✓ Branch 0 taken 343 times.
✓ Branch 1 taken 1 times.
|
344 | if (type->isIntegerTy() || type->isFloatingPointTy()) |
93 | { | ||
94 |
2/2✓ Branch 2 taken 225 times.
✓ Branch 3 taken 1 times.
|
226 | in = B.CreateLoad(in); |
95 | const bool intconversion = in->getType()->isIntegerTy(); | ||
96 |
3/4✓ Branch 0 taken 225 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 225 times.
|
226 | assert(intconversion || in->getType()->isFloatTy()); |
97 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 225 times.
|
226 | llvm::Value* result = intconversion ? |
98 | 1 | arithmeticConversion(in, B.getInt16Ty(), B) : | |
99 | 225 | arithmeticConversion(in, B.getHalfTy(), B); | |
100 | 226 | B.CreateStore(result, out); | |
101 | } | ||
102 | else { | ||
103 | std::vector<llvm::Value*> outelem, inelem; | ||
104 |
1/2✓ Branch 1 taken 118 times.
✗ Branch 2 not taken.
|
118 | arrayUnpack(out, outelem, B, /*load*/false); |
105 |
1/2✓ Branch 1 taken 118 times.
✗ Branch 2 not taken.
|
118 | arrayUnpack(in, inelem, B, /*load*/true); |
106 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 118 times.
|
118 | assert(outelem.size() == inelem.size()); |
107 |
2/2✓ Branch 0 taken 115 times.
✓ Branch 1 taken 3 times.
|
118 | const bool intconversion = inelem.front()->getType()->isIntegerTy(); |
108 |
3/4✓ Branch 0 taken 115 times.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 115 times.
|
118 | assert(intconversion || inelem.front()->getType()->isFloatTy()); |
109 | |||
110 |
3/4✓ Branch 0 taken 3 times.
✓ Branch 1 taken 115 times.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
|
121 | if (intconversion) arithmeticConversion(inelem, B.getInt16Ty(), B); |
111 |
1/2✓ Branch 1 taken 115 times.
✗ Branch 2 not taken.
|
115 | else arithmeticConversion(inelem, B.getHalfTy(), B); |
112 | |||
113 |
2/2✓ Branch 0 taken 354 times.
✓ Branch 1 taken 118 times.
|
472 | for (size_t i = 0; i < inelem.size(); ++i) { |
114 |
1/2✓ Branch 1 taken 354 times.
✗ Branch 2 not taken.
|
354 | B.CreateStore(inelem[i], outelem[i]); |
115 | } | ||
116 | } | ||
117 | 344 | return nullptr; | |
118 | }; | ||
119 | |||
120 | 1 | return FunctionBuilder("__trncencode") | |
121 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | .addSignature<void(openvdb::math::half*, float*)>(generate) |
122 |
2/6✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
2 | .addSignature<void(int16_t*, int32_t*)>(generate) |
123 |
2/6✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
2 | .addSignature<void(openvdb::math::Vec2<int16_t>*, openvdb::math::Vec2<int32_t>*)>(generate) |
124 |
2/6✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
2 | .addSignature<void(openvdb::math::Vec2<openvdb::math::half>*, openvdb::math::Vec2<float>*)>(generate) |
125 |
2/6✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
2 | .addSignature<void(openvdb::math::Vec3<int16_t>*, openvdb::math::Vec3<int32_t>*)>(generate) |
126 |
2/6✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
2 | .addSignature<void(openvdb::math::Vec3<openvdb::math::half>*, openvdb::math::Vec3<float>*)>(generate) |
127 |
2/6✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
2 | .addSignature<void(openvdb::math::Vec4<int16_t>*, openvdb::math::Vec4<int32_t>*)>(generate) |
128 |
2/6✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
2 | .addSignature<void(openvdb::math::Vec4<openvdb::math::half>*, openvdb::math::Vec4<float>*)>(generate) |
129 | .setDocumentation("") | ||
130 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | .get(); |
131 | } | ||
132 | |||
133 | 4 | inline FunctionGroup::UniquePtr axfxptdecode(const bool OneByte, const bool IsPositionRange) | |
134 | { | ||
135 | auto generate = | ||
136 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 924 times.
|
924 | [IsPositionRange](const std::vector<llvm::Value*>& args, |
137 | 1836 | llvm::IRBuilder<>& B) -> llvm::Value* | |
138 | { | ||
139 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 924 times.
|
924 | assert(args.size() == 2); |
140 | 924 | llvm::Value* out = args[0]; // out | |
141 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 924 times.
|
924 | llvm::Value* in = args[1]; // in |
142 | llvm::Type* type = in->getType()->getPointerElementType(); | ||
143 | |||
144 | 924 | llvm::Value* offset = LLVMType<float>::get(B.getContext(), 0.5f); | |
145 | |||
146 |
2/2✓ Branch 0 taken 468 times.
✓ Branch 1 taken 456 times.
|
924 | if (type->isIntegerTy()) |
147 | { | ||
148 | 468 | in = B.CreateLoad(in); | |
149 |
3/4✓ Branch 1 taken 234 times.
✓ Branch 2 taken 234 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 234 times.
|
468 | assert(type->isIntegerTy(8) || type->isIntegerTy(16)); |
150 | 936 | llvm::Value* s = B.CreateUIToFP(in, B.getFloatTy()); | |
151 | 468 | llvm::Value* d = type->isIntegerTy(8) ? | |
152 | 234 | LLVMType<float>::get(B.getContext(), float(std::numeric_limits<uint8_t>::max())) : | |
153 |
2/2✓ Branch 0 taken 234 times.
✓ Branch 1 taken 234 times.
|
468 | LLVMType<float>::get(B.getContext(), float(std::numeric_limits<uint16_t>::max())); |
154 | 468 | llvm::Value* result = B.CreateFDiv(s, d); | |
155 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 466 times.
|
468 | if (IsPositionRange) result = B.CreateFSub(result, offset); |
156 | 468 | B.CreateStore(result, out); | |
157 | } | ||
158 | else { | ||
159 | std::vector<llvm::Value*> outelem, inelem; | ||
160 |
1/2✓ Branch 1 taken 456 times.
✗ Branch 2 not taken.
|
456 | arrayUnpack(out, outelem, B, /*load*/false); |
161 |
1/2✓ Branch 1 taken 456 times.
✗ Branch 2 not taken.
|
456 | arrayUnpack(in, inelem, B, /*load*/true); |
162 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 456 times.
|
456 | assert(inelem.size() >= 3); |
163 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 456 times.
|
456 | assert(outelem.size() == inelem.size()); |
164 |
5/8✓ Branch 1 taken 456 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 228 times.
✓ Branch 4 taken 228 times.
✓ Branch 6 taken 228 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 228 times.
|
456 | assert(inelem.front()->getType()->isIntegerTy(8) || inelem.front()->getType()->isIntegerTy(16)); |
165 | |||
166 |
1/2✓ Branch 1 taken 456 times.
✗ Branch 2 not taken.
|
456 | llvm::Value* d = inelem.front()->getType()->isIntegerTy(8) ? |
167 |
1/2✓ Branch 1 taken 228 times.
✗ Branch 2 not taken.
|
228 | LLVMType<float>::get(B.getContext(), float(std::numeric_limits<uint8_t>::max())) : |
168 |
3/4✓ Branch 0 taken 228 times.
✓ Branch 1 taken 228 times.
✓ Branch 3 taken 228 times.
✗ Branch 4 not taken.
|
456 | LLVMType<float>::get(B.getContext(), float(std::numeric_limits<uint16_t>::max())); |
169 | |||
170 |
2/2✓ Branch 0 taken 1368 times.
✓ Branch 1 taken 456 times.
|
1824 | for (size_t i = 0; i < inelem.size(); ++i) { |
171 |
1/2✓ Branch 2 taken 1368 times.
✗ Branch 3 not taken.
|
2736 | llvm::Value* result = B.CreateUIToFP(inelem[i], B.getFloatTy()); |
172 |
1/2✓ Branch 2 taken 1368 times.
✗ Branch 3 not taken.
|
1368 | result = B.CreateFDiv(result, d); |
173 |
3/6✓ Branch 0 taken 684 times.
✓ Branch 1 taken 684 times.
✓ Branch 4 taken 684 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
1368 | if (IsPositionRange) result = B.CreateFSub(result, offset); |
174 |
1/2✓ Branch 1 taken 1368 times.
✗ Branch 2 not taken.
|
1368 | B.CreateStore(result, outelem[i]); |
175 | } | ||
176 | } | ||
177 | 924 | return nullptr; | |
178 | 4 | }; | |
179 | |||
180 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
|
4 | if (OneByte) { |
181 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
|
5 | return FunctionBuilder(IsPositionRange ? "__prfxpt8decode" : "__ufxpt8decode") |
182 |
1/2✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
4 | .addSignature<void(float*, uint8_t*)>(generate) |
183 |
2/6✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
4 | .addSignature<void(openvdb::math::Vec3<float>*,openvdb::math::Vec3<uint8_t>*)>(generate) |
184 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | .get(); |
185 | } | ||
186 | else { | ||
187 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
|
5 | return FunctionBuilder(IsPositionRange ? "__prfxpt16decode" : "__ufxpt16decode") |
188 |
1/2✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
4 | .addSignature<void(float*, uint16_t*)>(generate) |
189 |
2/6✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
4 | .addSignature<void(openvdb::math::Vec3<float>*,openvdb::math::Vec3<uint16_t>*)>(generate) |
190 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | .get(); |
191 | } | ||
192 | } | ||
193 | |||
194 | 456 | inline FunctionGroup::UniquePtr axfxptencode(const bool OneByte, const bool IsPositionRange) | |
195 | { | ||
196 | auto generate = | ||
197 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 854 times.
|
854 | [IsPositionRange](const std::vector<llvm::Value*>& args, |
198 | 854 | llvm::IRBuilder<>& B) -> llvm::Value* | |
199 | { | ||
200 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 854 times.
|
854 | assert(args.size() == 2); |
201 | llvm::LLVMContext& C = B.getContext(); | ||
202 | llvm::Function* base = B.GetInsertBlock()->getParent(); | ||
203 | 854 | llvm::Value* u = args[0]; // out | |
204 | 854 | llvm::Value* s = args[1]; // in | |
205 | 854 | s = B.CreateLoad(s); | |
206 | |||
207 | 854 | llvm::Value* offset = LLVMType<float>::get(B.getContext(), 0.5f); | |
208 |
2/2✓ Branch 0 taken 226 times.
✓ Branch 1 taken 628 times.
|
854 | if (IsPositionRange) s = B.CreateFAdd(s, offset); |
209 | |||
210 | 854 | const bool ftx8 = u->getType()->getPointerElementType()->isIntegerTy(8); | |
211 | |||
212 | 854 | llvm::BasicBlock* lt0 = llvm::BasicBlock::Create(C, "lt0", base); | |
213 | 854 | llvm::BasicBlock* els = llvm::BasicBlock::Create(C, "else", base); | |
214 | 854 | llvm::BasicBlock* fin = llvm::BasicBlock::Create(C, "finish", base); | |
215 | 854 | llvm::Value* r1 = binaryOperator(LLVMType<float>::get(C, 0.0f), s, ast::tokens::MORETHAN, B); | |
216 | 854 | B.CreateCondBr(r1, lt0, els); | |
217 | |||
218 | B.SetInsertPoint(lt0); | ||
219 | { | ||
220 | llvm::Value* d = ftx8 ? | ||
221 | 427 | LLVMType<uint8_t>::get(C, std::numeric_limits<uint8_t>::min()) : | |
222 |
2/2✓ Branch 0 taken 427 times.
✓ Branch 1 taken 427 times.
|
854 | LLVMType<uint16_t>::get(C, std::numeric_limits<uint16_t>::min()); |
223 | 854 | B.CreateStore(d, u); | |
224 | 854 | B.CreateBr(fin); | |
225 | } | ||
226 | |||
227 | B.SetInsertPoint(els); | ||
228 | { | ||
229 | 854 | llvm::BasicBlock* lte1 = llvm::BasicBlock::Create(C, "lte1", base); | |
230 | 854 | llvm::BasicBlock* post = llvm::BasicBlock::Create(C, "post", base); | |
231 | 854 | r1 = binaryOperator(LLVMType<float>::get(C, 1.0f), s, ast::tokens::LESSTHANOREQUAL, B); | |
232 | 854 | B.CreateCondBr(r1, lte1, post); | |
233 | B.SetInsertPoint(lte1); | ||
234 | { | ||
235 | llvm::Value* d = ftx8 ? | ||
236 | 427 | LLVMType<uint8_t>::get(C, std::numeric_limits<uint8_t>::max()) : | |
237 |
2/2✓ Branch 0 taken 427 times.
✓ Branch 1 taken 427 times.
|
854 | LLVMType<uint16_t>::get(C, std::numeric_limits<uint16_t>::max()); |
238 | 854 | B.CreateStore(d, u); | |
239 | 854 | B.CreateBr(fin); | |
240 | } | ||
241 | |||
242 | B.SetInsertPoint(post); | ||
243 | { | ||
244 | llvm::Value* d = ftx8 ? | ||
245 | 427 | LLVMType<float>::get(C, float(std::numeric_limits<uint8_t>::max())) : | |
246 |
2/2✓ Branch 0 taken 427 times.
✓ Branch 1 taken 427 times.
|
854 | LLVMType<float>::get(C, float(std::numeric_limits<uint16_t>::max())); |
247 | 854 | d = binaryOperator(s, d, ast::tokens::MULTIPLY, B); | |
248 | 1708 | d = B.CreateFPToUI(d, u->getType()->getPointerElementType()); | |
249 | 854 | B.CreateStore(d, u); | |
250 | 854 | B.CreateBr(fin); | |
251 | } | ||
252 | } | ||
253 | |||
254 | B.SetInsertPoint(fin); | ||
255 | 854 | return B.CreateRetVoid(); | |
256 | 456 | }; | |
257 | |||
258 | auto generate_vec = | ||
259 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 452 times.
|
452 | [OneByte, IsPositionRange](const std::vector<llvm::Value*>& args, |
260 | 452 | llvm::IRBuilder<>& B) -> llvm::Value* | |
261 | { | ||
262 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 452 times.
|
452 | assert(args.size() == 2); |
263 | std::vector<llvm::Value*> out, in; | ||
264 |
1/2✓ Branch 1 taken 452 times.
✗ Branch 2 not taken.
|
452 | arrayUnpack(args[0], out, B, /*load*/false); |
265 |
1/2✓ Branch 1 taken 452 times.
✗ Branch 2 not taken.
|
452 | arrayUnpack(args[1], in, B, /*load*/false); |
266 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 452 times.
|
452 | assert(in.size() >= 3); |
267 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 452 times.
|
452 | assert(out.size() == in.size()); |
268 | |||
269 |
1/2✓ Branch 1 taken 452 times.
✗ Branch 2 not taken.
|
904 | auto F = axfxptencode(OneByte, IsPositionRange); |
270 |
2/2✓ Branch 0 taken 1356 times.
✓ Branch 1 taken 452 times.
|
1808 | for (size_t i = 0; i < in.size(); ++i) { |
271 |
2/4✓ Branch 1 taken 1356 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1356 times.
✗ Branch 5 not taken.
|
2712 | F->execute({out[i], in[i]}, B); |
272 | } | ||
273 | |||
274 | 452 | return nullptr; | |
275 | 456 | }; | |
276 | |||
277 |
2/2✓ Branch 0 taken 228 times.
✓ Branch 1 taken 228 times.
|
456 | if (OneByte) { |
278 |
2/2✓ Branch 0 taken 114 times.
✓ Branch 1 taken 114 times.
|
570 | return FunctionBuilder(IsPositionRange ? "__prfxpt8encode" : "__ufxpt8encode") |
279 |
1/2✓ Branch 2 taken 228 times.
✗ Branch 3 not taken.
|
456 | .addSignature<void(uint8_t*, float*)>(generate) |
280 |
2/6✓ Branch 2 taken 228 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 228 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
456 | .addSignature<void(openvdb::math::Vec3<uint8_t>*,openvdb::math::Vec3<float>*)>(generate_vec) |
281 |
1/2✓ Branch 1 taken 228 times.
✗ Branch 2 not taken.
|
228 | .get(); |
282 | } | ||
283 | else { | ||
284 |
2/2✓ Branch 0 taken 114 times.
✓ Branch 1 taken 114 times.
|
570 | return FunctionBuilder(IsPositionRange ? "__prfxpt16encode" : "__ufxpt16encode") |
285 |
1/2✓ Branch 2 taken 228 times.
✗ Branch 3 not taken.
|
456 | .addSignature<void(uint16_t*, float*)>(generate) |
286 |
2/6✓ Branch 2 taken 228 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 228 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
456 | .addSignature<void(openvdb::math::Vec3<uint16_t>*,openvdb::math::Vec3<float>*)>(generate_vec) |
287 |
1/2✓ Branch 1 taken 228 times.
✗ Branch 2 not taken.
|
228 | .get(); |
288 | } | ||
289 | } | ||
290 | |||
291 | /// @note For some reason templating axfxptdecode/axfxptencode with a bool | ||
292 | /// doesn't compile i.e. template <IsPositionRange> | ||
293 | 1 | inline FunctionGroup::UniquePtr axufxpt8decode() { return axfxptdecode(true, false); } | |
294 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | inline FunctionGroup::UniquePtr axufxpt8encode() { return axfxptencode(true, false); } |
295 | 1 | inline FunctionGroup::UniquePtr axprfxpt8decode() { return axfxptdecode(true, true); } | |
296 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | inline FunctionGroup::UniquePtr axprfxpt8encode() { return axfxptencode(true, true); } |
297 | |||
298 | 1 | inline FunctionGroup::UniquePtr axufxpt16decode() { return axfxptdecode(false, false); } | |
299 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | inline FunctionGroup::UniquePtr axufxpt16encode() { return axfxptencode(false, false); } |
300 | 1 | inline FunctionGroup::UniquePtr axprfxpt16decode() { return axfxptdecode(false, true); } | |
301 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | inline FunctionGroup::UniquePtr axprfxpt16encode() { return axfxptencode(false, true); } |
302 | |||
303 | /////////////////////////////////////////////////////////////////////////////// | ||
304 | /////////////////////////////////////////////////////////////////////////////// | ||
305 | |||
306 | 34942 | const CodecTypeMap& getCodecTypeMap() | |
307 | { | ||
308 | // Initialise the static codec registry of supported types. | ||
309 | // This can easily be exposed to users so they can write their own codecs, | ||
310 | // but it would turn into either another static mutex regitry or another | ||
311 | // object that would have to be passed from the codegen to the executables. | ||
312 | // When we have AX pipelines we should expose this | ||
313 | |||
314 | // @note This should really be another static registry which mirrors | ||
315 | // whatever is registered in the AttributeArray registry. This is easy to | ||
316 | // do but required changes to the exposed AttributeArray API. To be done | ||
317 | // in a separate change set. | ||
318 | |||
319 | static std::array<Codec::UniquePtr, 5> codecs { | ||
320 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
2 | std::make_unique<Codec>(axtrncencode(), axtrncdecode(), 1<<0), |
321 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | std::make_unique<Codec>(axufxpt8encode(), axufxpt8decode(), 1<<1), |
322 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | std::make_unique<Codec>(axufxpt16encode(), axufxpt16decode(), 1<<2), |
323 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | std::make_unique<Codec>(axprfxpt8encode(), axprfxpt8decode(), 1<<3), |
324 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | std::make_unique<Codec>(axprfxpt16encode(), axprfxpt16decode(), 1<<4), |
325 |
8/14✓ Branch 0 taken 1 times.
✓ Branch 1 taken 34941 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 1 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
|
34948 | }; |
326 | |||
327 | static CodecTypeMap map { | ||
328 | { | ||
329 | ast::tokens::FLOAT, | ||
330 | { | ||
331 | { points::TruncateCodec::name(), codecs[0].get() }, | ||
332 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | { points::FixedPointCodec<true, points::UnitRange>::name(), codecs[1].get() }, |
333 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | { points::FixedPointCodec<false, points::UnitRange>::name(), codecs[2].get() } |
334 | } | ||
335 | }, | ||
336 | { | ||
337 | ast::tokens::VEC3F, | ||
338 | { | ||
339 | { points::TruncateCodec::name(), codecs[0].get() }, | ||
340 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | { points::FixedPointCodec<true, points::UnitRange>::name(), codecs[1].get() }, |
341 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | { points::FixedPointCodec<false, points::UnitRange>::name(), codecs[2].get() }, |
342 | { points::FixedPointCodec<true, points::PositionRange>::name(), codecs[3].get() }, | ||
343 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | { points::FixedPointCodec<false, points::PositionRange>::name(), codecs[4].get() } |
344 | } | ||
345 | }, | ||
346 |
12/22✓ Branch 0 taken 1 times.
✓ Branch 1 taken 34941 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 1 times.
✓ Branch 16 taken 2 times.
✓ Branch 17 taken 1 times.
✓ Branch 20 taken 5 times.
✓ Branch 21 taken 1 times.
✓ Branch 24 taken 3 times.
✓ Branch 25 taken 1 times.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
|
34955 | }; |
347 | |||
348 | 34942 | return map; | |
349 | } | ||
350 | |||
351 | 8791 | llvm::Type* Codec::findReturnTypeFromArg(const codegen::FunctionGroup* const group, llvm::Type* arg) const | |
352 | { | ||
353 | const auto& functions = group->list(); | ||
354 | std::vector<llvm::Type*> types; | ||
355 |
2/2✓ Branch 0 taken 15418 times.
✓ Branch 1 taken 12 times.
|
15430 | for (const auto& F : functions) { |
356 | types.clear(); | ||
357 |
1/2✓ Branch 1 taken 15418 times.
✗ Branch 2 not taken.
|
15418 | F->types(types, arg->getContext()); |
358 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 15418 times.
|
15418 | assert(types.size() == 2); |
359 |
2/2✓ Branch 0 taken 6639 times.
✓ Branch 1 taken 8779 times.
|
15418 | if (types[1] != arg) continue; |
360 | 8779 | return types[0]; | |
361 | } | ||
362 | // no supported conversion | ||
363 | 12 | return nullptr; | |
364 | } | ||
365 | |||
366 | 9766 | const Codec* getCodec(const ast::tokens::CoreType type, const std::string& name) | |
367 | { | ||
368 | 9766 | const CodecTypeMap& map = getCodecTypeMap(); | |
369 | |||
370 |
2/2✓ Branch 0 taken 1562 times.
✓ Branch 1 taken 8204 times.
|
9766 | auto typeiter = map.find(type); |
371 |
2/2✓ Branch 0 taken 1562 times.
✓ Branch 1 taken 8204 times.
|
9766 | if (typeiter != map.cend()) { |
372 |
2/2✓ Branch 0 taken 9 times.
✓ Branch 1 taken 1553 times.
|
1562 | auto iter = typeiter->second.find(name); |
373 |
2/2✓ Branch 0 taken 9 times.
✓ Branch 1 taken 1553 times.
|
1562 | if (iter != typeiter->second.cend()) { |
374 | 9 | return iter->second; | |
375 | } | ||
376 | } | ||
377 | return nullptr; | ||
378 | } | ||
379 | |||
380 | 25170 | const CodecNameMap* getTypeSupportedCodecs(const ast::tokens::CoreType type) | |
381 | { | ||
382 | 25170 | const CodecTypeMap& map = getCodecTypeMap(); | |
383 | |||
384 |
2/2✓ Branch 0 taken 4075 times.
✓ Branch 1 taken 21095 times.
|
25170 | auto typeiter = map.find(type); |
385 |
2/2✓ Branch 0 taken 4075 times.
✓ Branch 1 taken 21095 times.
|
25170 | if (typeiter != map.cend()) { |
386 | 4075 | return &(typeiter->second); | |
387 | } | ||
388 | return nullptr; | ||
389 | } | ||
390 | |||
391 | |||
392 | } // namespace codegen | ||
393 | } // namespace ax | ||
394 | } // namespace OPENVDB_VERSION_NAME | ||
395 | } // namespace openvdb | ||
396 | |||
397 |