| 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 |