Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d3d9f6225b | ||
|
|
f34b975536 | ||
|
|
b8c30540ba | ||
|
|
42979151c2 | ||
|
|
6bafe12b19 | ||
|
|
4b078bb1bc | ||
|
|
66f21608e0 | ||
|
|
c41d484595 | ||
|
|
4794b0e55f | ||
|
|
c48d21814c | ||
|
|
a7d313ad41 | ||
|
|
fe52f5d6b7 | ||
|
|
729ece7292 | ||
|
|
9722b4c30d | ||
|
|
ed8ee37967 | ||
|
|
7a50a2d692 | ||
|
|
357c6f24c5 | ||
|
|
83fcf53b95 | ||
|
|
8968597c20 | ||
|
|
95a4cbcb94 | ||
|
|
2c724c529f | ||
|
|
5da02d0800 | ||
|
|
11b243931c | ||
|
|
28e11c9857 | ||
|
|
4c9c026a1b | ||
|
|
1a47e44b72 | ||
|
|
1fb988cd6b | ||
|
|
c6498a29d0 | ||
|
|
fcd747217b | ||
|
|
6bf725ba7c | ||
|
|
e9a402ecd1 | ||
|
|
a7dd991418 | ||
|
|
2f6af2832d | ||
|
|
640c6daa85 | ||
|
|
512811023f | ||
|
|
c0a1dbb5d8 | ||
|
|
045c418031 | ||
|
|
8956aee21c | ||
|
|
0d9bc8df72 | ||
|
|
ca96c96cb3 | ||
|
|
4c50caa6b1 | ||
|
|
9edba0f4ea | ||
|
|
f4626bb22e | ||
|
|
7d66ef477b | ||
|
|
1b3b7ecb38 | ||
|
|
e082712373 | ||
|
|
185ffc39d3 | ||
|
|
3f4c6ac6e3 | ||
|
|
5e3b4cf0e2 | ||
|
|
dec21a5f65 | ||
|
|
2b0c400355 | ||
|
|
058e820efb | ||
|
|
d633a5541d | ||
|
|
563fa8b32c | ||
|
|
0894d751f1 | ||
|
|
23e8a0389d | ||
|
|
54f29c991b | ||
|
|
fd3af84024 | ||
|
|
a9a868f252 | ||
|
|
870e7adc71 | ||
|
|
bec88b6568 | ||
|
|
85a6d9c54c | ||
|
|
63919c188c | ||
|
|
76892f8577 | ||
|
|
44e783d59d | ||
|
|
0a642420af | ||
|
|
d208cbb4d9 | ||
|
|
0419f1d8cc | ||
|
|
c2309bbf79 | ||
|
|
e9149e8e9a | ||
|
|
c15bb92593 | ||
|
|
a1b56e8adc | ||
|
|
d85aea4c1a | ||
|
|
4498acd035 | ||
|
|
152073d7ac | ||
|
|
a90002157c | ||
|
|
f8c8d55c44 | ||
|
|
97600fb260 | ||
|
|
b6d6cba2a2 | ||
|
|
ead4835d35 | ||
|
|
eb4906c79c | ||
|
|
85b65574bb | ||
|
|
363c005f8e | ||
|
|
4422ca608c | ||
|
|
d38ac50b2b | ||
|
|
4d05b49867 | ||
|
|
a22e54cc49 | ||
|
|
46d131e056 | ||
|
|
f1d23c57ed | ||
|
|
265044e73f | ||
|
|
ca84d3425e | ||
|
|
418ec0bdfb | ||
|
|
2d1f8a6a97 | ||
|
|
9813d6a6ee | ||
|
|
255ab75c5f | ||
|
|
ece6b8345c | ||
|
|
59ec5d0fcd | ||
|
|
2cd05a8b2b | ||
|
|
08e54eb4c1 | ||
|
|
fb13a85505 | ||
|
|
fb81cb34de | ||
|
|
3ceca55050 | ||
|
|
87d45e6096 | ||
|
|
872ced9934 | ||
|
|
f987d717ef | ||
|
|
9b40fcb862 | ||
|
|
19605e0738 | ||
|
|
fe56a4dc3c | ||
|
|
4994f64729 | ||
|
|
7b4af861f4 | ||
|
|
82ef698bcf | ||
|
|
ca70fc388b | ||
|
|
ae06ac06a9 | ||
|
|
e2656563b1 | ||
|
|
752e905ecc | ||
|
|
d9e046d0c3 | ||
|
|
5945b87db9 | ||
|
|
0c92fff315 | ||
|
|
360ad9d0c3 | ||
|
|
6c34e0d090 | ||
|
|
794d90069c | ||
|
|
fb8e4405c7 | ||
|
|
36d53847c7 | ||
|
|
e45aabfb8a | ||
|
|
d66fbeb235 | ||
|
|
af13b7704f | ||
|
|
649d39f3a8 | ||
|
|
9b3362a394 | ||
|
|
fdb80242af | ||
|
|
fa7d1b4f89 | ||
|
|
f6cdaeb732 | ||
|
|
a9d59ed6c8 | ||
|
|
5633e5233d | ||
|
|
2b681c5f27 | ||
|
|
8a8f7c78aa | ||
|
|
159e440014 | ||
|
|
04d8b88026 | ||
|
|
1f8e43141c | ||
|
|
07c35e2ed2 | ||
|
|
a44f900b20 | ||
|
|
141aa737c6 | ||
|
|
f154b5f160 | ||
|
|
7f82ff96ce | ||
|
|
1112474494 | ||
|
|
b486e32e7c | ||
|
|
8375fa6ddc | ||
|
|
1c618498f1 | ||
|
|
412f96bd78 | ||
|
|
d29f6463fc | ||
|
|
83cf25ff11 | ||
|
|
7502c34550 | ||
|
|
e70e719de9 | ||
|
|
da88c40c5a | ||
|
|
97d9c48aea | ||
|
|
ff0adca3d2 | ||
|
|
386aca9c02 | ||
|
|
9f19cc077b | ||
|
|
9631f41e77 | ||
|
|
9f034802bb | ||
|
|
437e87a931 | ||
|
|
081a301f20 | ||
|
|
71495578a4 | ||
|
|
d2960b7b5c | ||
|
|
78a9ad27c3 | ||
|
|
ecda1d8a44 | ||
|
|
9da3d17093 | ||
|
|
8d0a5962a9 | ||
|
|
e9a41e05e1 | ||
|
|
24e7f7e369 | ||
|
|
28737d9ee9 | ||
|
|
6dafd1d4d3 | ||
|
|
6353759cce | ||
|
|
fb0def1684 | ||
|
|
caea79c997 | ||
|
|
c775d0de2e | ||
|
|
843d6dd4c8 | ||
|
|
c935e0da39 | ||
|
|
d87d7df513 | ||
|
|
77dc26ef4f | ||
|
|
8963303344 | ||
|
|
746cadf4e4 | ||
|
|
417eb0d7b8 | ||
|
|
5d19c5bb68 | ||
|
|
b479fb5d9f | ||
|
|
6901238ba7 | ||
|
|
0e296bba08 | ||
|
|
01adb67d9f | ||
|
|
305a169b01 | ||
|
|
6c598c3c35 | ||
|
|
24b98e170e | ||
|
|
b2bd8f62b2 | ||
|
|
1d143a08dd | ||
|
|
23908e9c71 | ||
|
|
9fc5e527e9 | ||
|
|
5f13249d40 | ||
|
|
1a745a5d1d | ||
|
|
6cbc00fb19 | ||
|
|
ee3387e59d | ||
|
|
fb7f022fc3 | ||
|
|
fbeaa1002f | ||
|
|
9328d403ee | ||
|
|
3e927e6874 | ||
|
|
15a5d109c7 | ||
|
|
96f8c8f414 | ||
|
|
6e888ebdbf | ||
|
|
ba945af43a | ||
|
|
c62e54d720 | ||
|
|
d9763d57bf | ||
|
|
299b53370d | ||
|
|
61a0b1f35f | ||
|
|
a8604e6a68 | ||
|
|
5f1bc27167 | ||
|
|
620d45feb4 | ||
|
|
cb81b83199 | ||
|
|
14813caba9 | ||
|
|
7bbd847b33 | ||
|
|
32aa21e991 | ||
|
|
dea80f4954 | ||
|
|
e1415c4474 | ||
|
|
fbbb077fb7 | ||
|
|
7d604fc519 | ||
|
|
e23b856425 | ||
|
|
16872d6323 | ||
|
|
1b82440464 | ||
|
|
5ac4f24a6c | ||
|
|
2d87a836dd | ||
|
|
eea2e26f27 | ||
|
|
34a5076448 | ||
|
|
8dcb052322 | ||
|
|
d3b5b12a5a | ||
|
|
c44b69807d | ||
|
|
5248d162d7 | ||
|
|
d3db45d710 | ||
|
|
70a24218cf | ||
|
|
b2bc8807b5 | ||
|
|
db90caa563 | ||
|
|
4837531a00 | ||
|
|
4586f0bbb4 | ||
|
|
6db9a37056 | ||
|
|
360ece9e98 | ||
|
|
a6dea3e220 | ||
|
|
10e494b220 | ||
|
|
b57c862896 | ||
|
|
2fb5038a4e | ||
|
|
7cc0ed4dcb | ||
|
|
12e0435035 | ||
|
|
e5ccab49c2 | ||
|
|
c954c616a8 | ||
|
|
fd9674c6c0 | ||
|
|
71a828ebfd | ||
|
|
8ac982ad08 | ||
|
|
bf5af56f19 | ||
|
|
9a4aedeecb | ||
|
|
26df12ba62 | ||
|
|
20221e0fcd | ||
|
|
17f16c7f13 | ||
|
|
c5c2493a80 | ||
|
|
3e2a13182b | ||
|
|
34568ddfec | ||
|
|
60838a7555 | ||
|
|
d07c1c4e57 | ||
|
|
601da2a282 | ||
|
|
188388ce2f | ||
|
|
6615050cf2 | ||
|
|
ef5aeb5065 | ||
|
|
9fcfb997e5 | ||
|
|
06f7784f31 | ||
|
|
7b4979c100 | ||
|
|
90b83aea4b | ||
|
|
2e0a5011e7 | ||
|
|
897c893d50 | ||
|
|
821c0d4d7c | ||
|
|
2929c4d4a9 | ||
|
|
199cbdba2f | ||
|
|
da71a4116a | ||
|
|
2a0ae0225a | ||
|
|
7a68a3dab5 | ||
|
|
dc191dabcf | ||
|
|
ccc00a7cc0 | ||
|
|
2908742a66 | ||
|
|
1693f87a5d | ||
|
|
4ec31fc480 | ||
|
|
1801d8e60c | ||
|
|
552ea1f55c | ||
|
|
d228ba1027 | ||
|
|
42490d8395 | ||
|
|
27aaf7ce61 | ||
|
|
e2027ab2a1 | ||
|
|
8ec7a998c9 | ||
|
|
5cfaf6b9a9 | ||
|
|
27319c93db | ||
|
|
6821947508 | ||
|
|
51c709a7da | ||
|
|
efc316bee9 | ||
|
|
5caee9ba5e | ||
|
|
5c10d17b89 | ||
|
|
995e7883a9 | ||
|
|
467f13fd50 | ||
|
|
0e9eb89dd8 | ||
|
|
cb3923da42 | ||
|
|
470b9c2f5f | ||
|
|
0981bc1c34 | ||
|
|
ca9e9989d0 | ||
|
|
e3a283905d | ||
|
|
cc29db2665 | ||
|
|
3a15addfb0 | ||
|
|
b6b2dc3bd5 | ||
|
|
6cf6fc14d2 | ||
|
|
f5f43863e2 | ||
|
|
14b39eb106 | ||
|
|
ae957a4a3d | ||
|
|
4e66c586f0 | ||
|
|
a257e6df95 | ||
|
|
5adea052a3 | ||
|
|
2647217c70 | ||
|
|
f01d534202 | ||
|
|
389c9267d3 | ||
|
|
733a1f8db6 | ||
|
|
661336d18b | ||
|
|
5758aa3986 | ||
|
|
6b900ed9a7 | ||
|
|
4cf545b763 | ||
|
|
339eb9fb98 | ||
|
|
156ac538cb | ||
|
|
66c5b693ae | ||
|
|
cf3826df6c | ||
|
|
46c9952cd5 | ||
|
|
dc21219be0 | ||
|
|
4ae61b1e95 | ||
|
|
facb73b64c | ||
|
|
abdedb8680 | ||
|
|
6c49e40df6 | ||
|
|
3a266e9ea5 | ||
|
|
f545575d1b | ||
|
|
dcb846ee00 | ||
|
|
fc2f36fe52 | ||
|
|
b5cff0b840 | ||
|
|
edd38d1e05 | ||
|
|
5538ff3720 | ||
|
|
68e27509c1 | ||
|
|
799aebcb34 | ||
|
|
38f3286b92 | ||
|
|
e692393935 | ||
|
|
169c80df85 | ||
|
|
e3c7ba0f9f | ||
|
|
1f295a492b | ||
|
|
eebad657b8 | ||
|
|
9cc5f09fd6 | ||
|
|
365174a376 | ||
|
|
c27655b52e | ||
|
|
04ed0b9a7f | ||
|
|
def9ffdf5d | ||
|
|
4f5814142e | ||
|
|
e9f29bb2fe | ||
|
|
b15603013c | ||
|
|
abf06ab28f | ||
|
|
d75751c610 | ||
|
|
168bef78d7 | ||
|
|
d748b4ab21 | ||
|
|
9bdc237098 | ||
|
|
36ae76cd43 | ||
|
|
6835cc16bf | ||
|
|
a0df9f4677 | ||
|
|
af19eecb09 | ||
|
|
1aadf8edc4 | ||
|
|
1bf79fb49a | ||
|
|
f1de9dd828 | ||
|
|
d2cae64d59 | ||
|
|
9c1b26ad9d | ||
|
|
cad0f8e70f | ||
|
|
4163b5e2bb | ||
|
|
d69fbc1d55 | ||
|
|
98c5a3f3d0 | ||
|
|
5fca4e4808 | ||
|
|
08fa094069 | ||
|
|
63df1246a7 | ||
|
|
41f82f6c4c | ||
|
|
c30dcbd51d | ||
|
|
e51b891169 | ||
|
|
0c90158577 | ||
|
|
4ced89f6c5 | ||
|
|
7cfbff5ab2 | ||
|
|
7c9afe7666 | ||
|
|
8c7bae6e96 | ||
|
|
8bfcca7793 | ||
|
|
f79699fbee | ||
|
|
1cf5cb51c9 | ||
|
|
51a2a57a55 | ||
|
|
fe19c8d140 | ||
|
|
c97766cf6e | ||
|
|
ad48abf863 | ||
|
|
6b5845b8db | ||
|
|
9b1ecd8fcb | ||
|
|
31a2dd189a | ||
|
|
5f8976f9e9 | ||
|
|
d83294ae24 | ||
|
|
2d62cb4f65 | ||
|
|
37e3d7cd10 | ||
|
|
e84331a505 | ||
|
|
3fa4799b87 | ||
|
|
dfae7e082c | ||
|
|
30ffd1c9ca | ||
|
|
a7976875c7 | ||
|
|
f764a98382 | ||
|
|
96b77bc423 | ||
|
|
d668f4c479 | ||
|
|
f574ef434d | ||
|
|
740315f828 | ||
|
|
92d1f529c2 | ||
|
|
30a095afe1 | ||
|
|
ab89e99311 | ||
|
|
187af3c675 | ||
|
|
c60a3cac1c | ||
|
|
c9cb2c5dc5 | ||
|
|
73c02815de | ||
|
|
d80067bc64 | ||
|
|
ca69cd410e | ||
|
|
a1cc4946c4 | ||
|
|
1ad3e67440 | ||
|
|
2c52981b5f | ||
|
|
45b97468f4 | ||
|
|
f7a276e00b | ||
|
|
e4ef689276 | ||
|
|
7379e75ded | ||
|
|
c95596d398 | ||
|
|
1b6ea047a0 | ||
|
|
30b08617f7 | ||
|
|
12f3fe074e | ||
|
|
d0ae78e8c2 | ||
|
|
a855710386 | ||
|
|
6ea9510929 | ||
|
|
7c0f6fcf37 | ||
|
|
59a74f5c53 | ||
|
|
cb1c23397b | ||
|
|
e23e368bbb | ||
|
|
ee11bbb967 | ||
|
|
627318c847 | ||
|
|
b348b4a923 | ||
|
|
3392f195e3 | ||
|
|
c95a469e53 | ||
|
|
323f065342 | ||
|
|
d31b5e28c0 | ||
|
|
7e9701dbfe | ||
|
|
001dc353b0 | ||
|
|
999a1e0940 | ||
|
|
468f0b006e | ||
|
|
797cb841cb | ||
|
|
4c18806032 | ||
|
|
e158b4aeb4 | ||
|
|
a421584457 | ||
|
|
7e2ef21e8a | ||
|
|
555bf49f82 | ||
|
|
530e12fd08 | ||
|
|
3a985370e1 | ||
|
|
04413db408 | ||
|
|
b7a754bf1e | ||
|
|
bd6450fae9 | ||
|
|
9bf5063504 | ||
|
|
ab16bfb9ff | ||
|
|
ee1b3e0974 | ||
|
|
782c3a00b9 | ||
|
|
fd6d8eebfc | ||
|
|
74a0465bd9 | ||
|
|
788d9129bd | ||
|
|
270be28fa1 | ||
|
|
4cf85a5d3a | ||
|
|
bcf566e242 | ||
|
|
261135446b | ||
|
|
8d7737a40d | ||
|
|
a503458f46 | ||
|
|
f58120e3d9 | ||
|
|
a91a622031 | ||
|
|
a497a0d420 | ||
|
|
bfdde3a838 | ||
|
|
18ff8964e9 | ||
|
|
9d666f3c60 | ||
|
|
70283e66cd | ||
|
|
91641f03f0 | ||
|
|
4dfbb4f634 | ||
|
|
8a0b5ace23 | ||
|
|
84b31bec95 | ||
|
|
555d73a939 | ||
|
|
ecd9fec37d | ||
|
|
cef647b6f0 | ||
|
|
c624afc9af | ||
|
|
dff2d930c1 | ||
|
|
8e34329cb8 | ||
|
|
5e7c954431 | ||
|
|
344b55c0e3 | ||
|
|
39d239c532 | ||
|
|
d11fab4176 | ||
|
|
abe0530dd8 | ||
|
|
a62a51eb8a | ||
|
|
72e0ebb1ca | ||
|
|
2c77282a31 | ||
|
|
67d3896680 | ||
|
|
96d11769a8 | ||
|
|
e5f9f21586 | ||
|
|
ec23630dfb | ||
|
|
e6d389b4d9 | ||
|
|
3d8f66e496 | ||
|
|
2764be05aa | ||
|
|
e49f0f68b0 | ||
|
|
89dedd512f | ||
|
|
7421bf3faf | ||
|
|
9497a83c3c | ||
|
|
ac7ef24c4b | ||
|
|
d02419b1ec | ||
|
|
ef4791be82 | ||
|
|
48ec6b4982 | ||
|
|
0d2a8ec3cb | ||
|
|
2fe5c3dfe5 | ||
|
|
15a90015b3 | ||
|
|
79f79a3043 | ||
|
|
c10b251bd0 | ||
|
|
afc105f211 | ||
|
|
774731d456 | ||
|
|
2a80cb21ad | ||
|
|
222536b63f | ||
|
|
e6af6c3c1d | ||
|
|
1f361ae496 | ||
|
|
2e0e512d6d | ||
|
|
5c76db9d32 | ||
|
|
2502dcb73b | ||
|
|
9525b0ded8 | ||
|
|
5915152b28 | ||
|
|
d832a6bf13 | ||
|
|
955e1701be | ||
|
|
703d1cf38b | ||
|
|
bdad88f276 | ||
|
|
c177d88e73 | ||
|
|
c721ab734e | ||
|
|
c80cc59a31 | ||
|
|
ad4d18367d | ||
|
|
add47a2007 | ||
|
|
dd7772fb7c | ||
|
|
5e5a1732d8 | ||
|
|
c6e0e35356 | ||
|
|
40cd5ca468 | ||
|
|
58b1db62d7 | ||
|
|
7a2448158b | ||
|
|
8584438138 | ||
|
|
dc750313a3 | ||
|
|
a79423d727 | ||
|
|
46fab1953c | ||
|
|
b108520812 | ||
|
|
8e76d782c3 | ||
|
|
808436be23 | ||
|
|
997ea3cffd | ||
|
|
09c41bd813 | ||
|
|
1fbc9852eb | ||
|
|
f593f4662e | ||
|
|
3628b44c68 | ||
|
|
0947794ef1 | ||
|
|
48dbdafe3e | ||
|
|
9f700284b5 | ||
|
|
984845812a | ||
|
|
7ae934c340 | ||
|
|
cde999ab5d | ||
|
|
413360fb5b | ||
|
|
bb75f2f3c6 | ||
|
|
c43f04ff2f | ||
|
|
198cd858db | ||
|
|
fad1918545 | ||
|
|
463155a1bc | ||
|
|
98ce178ce3 | ||
|
|
d23edf3b8f | ||
|
|
4abe5db03d | ||
|
|
fd3d496232 | ||
|
|
f559545523 | ||
|
|
c5450e92fe | ||
|
|
6456c4f3c7 | ||
|
|
d43ef73908 | ||
|
|
9d624e49ea | ||
|
|
2edda871df | ||
|
|
edd543069f | ||
|
|
cd1b4e33bd | ||
|
|
8a835efcc2 | ||
|
|
c39552f417 | ||
|
|
168749d762 | ||
|
|
1d7cb42e60 | ||
|
|
bfe17bb80c | ||
|
|
bf3acb9d59 | ||
|
|
47ba786010 | ||
|
|
f6bb338869 | ||
|
|
4859c7931f | ||
|
|
5513cfc963 | ||
|
|
d4d2c4b57e | ||
|
|
d66e0a8b9f | ||
|
|
d3e6290bcb | ||
|
|
5af8c6376e | ||
|
|
4dee38860b | ||
|
|
c5f0c18759 | ||
|
|
1422e18f2a | ||
|
|
5819d40c71 | ||
|
|
856fcfb119 | ||
|
|
49726b589f | ||
|
|
fc5cbabc39 | ||
|
|
9ebe020db5 | ||
|
|
fb8766e7e2 | ||
|
|
ab5acfb6fb | ||
|
|
34ff5912e4 | ||
|
|
3790892968 | ||
|
|
b29260d342 | ||
|
|
db170e7fa2 | ||
|
|
23c418b6e5 | ||
|
|
fcab0dbd72 | ||
|
|
b7809f9614 | ||
|
|
812b477637 | ||
|
|
0a80def516 | ||
|
|
736d28592e | ||
|
|
242531273f | ||
|
|
3bfc06e637 | ||
|
|
1bfe141883 | ||
|
|
882dc41460 | ||
|
|
b3dc0c76f3 | ||
|
|
39d9fde114 | ||
|
|
7fbc12bfa8 | ||
|
|
52d7468d8f | ||
|
|
7eefc31f87 | ||
|
|
7755090d76 | ||
|
|
5b349e324c | ||
|
|
0f36893bdb | ||
|
|
9db42a42e1 | ||
|
|
5d8bd7fa12 | ||
|
|
d776a5a3ba | ||
|
|
f05a6c7977 | ||
|
|
98ff0713c2 | ||
|
|
c017b5e5a6 | ||
|
|
70c39601c4 | ||
|
|
d057db526f | ||
|
|
9e7e8bc38f | ||
|
|
1db3616236 | ||
|
|
c81578dd06 | ||
|
|
cca6e644db | ||
|
|
2627a3e6aa | ||
|
|
cd7c280825 | ||
|
|
892b57dbb5 | ||
|
|
fccf939e42 | ||
|
|
7bcaf8a539 | ||
|
|
8d99340118 | ||
|
|
aa2b2c442f | ||
|
|
c24c08ffa6 | ||
|
|
7fe6f8de32 | ||
|
|
885395bd36 | ||
|
|
f71d3db828 | ||
|
|
546daeab5e | ||
|
|
2cffe6f6e5 | ||
|
|
d6362a44dc | ||
|
|
98bc2f7bea | ||
|
|
5036ea9b10 | ||
|
|
b855e06437 | ||
|
|
978f4b7e79 | ||
|
|
d70a7412e7 | ||
|
|
3cf7f3b65f | ||
|
|
98f88dabdc | ||
|
|
32f812e576 | ||
|
|
5b25f26a20 | ||
|
|
e36ac7e8f6 | ||
|
|
edd1c233c8 | ||
|
|
530cfc23f0 | ||
|
|
9ac1af39bd | ||
|
|
28cc65b124 | ||
|
|
8f7ad8752e | ||
|
|
47d0d2ea02 | ||
|
|
e3c3cd41cd | ||
|
|
482cccc172 | ||
|
|
20e564fb27 | ||
|
|
3a3a7b232f | ||
|
|
3d727fa459 | ||
|
|
5af3cf7907 | ||
|
|
373176d58c | ||
|
|
970cd0b454 | ||
|
|
9f706fa429 | ||
|
|
6cef830a2a | ||
|
|
d513f0bd32 | ||
|
|
ee9bb538b3 | ||
|
|
9405a1912f | ||
|
|
d364491d99 | ||
|
|
db231a40f8 | ||
|
|
ced929b265 | ||
|
|
2d58fc0461 | ||
|
|
3fc60a3c85 | ||
|
|
9784267543 | ||
|
|
9c3036e7da | ||
|
|
f045058ded | ||
|
|
1e9b9173a2 | ||
|
|
532c43bf75 | ||
|
|
7cac067244 | ||
|
|
6a25443f07 | ||
|
|
b4c3aee893 | ||
|
|
84c1243797 | ||
|
|
51d22ee3e4 | ||
|
|
c161a1f311 | ||
|
|
e038be50ce | ||
|
|
5b8aa24e76 | ||
|
|
bd7fb9e436 | ||
|
|
99c977a0d2 | ||
|
|
1a077bd957 | ||
|
|
be3497baeb | ||
|
|
5dd4428771 | ||
|
|
9e0a15f701 | ||
|
|
8e608c22ff | ||
|
|
979f97bb08 | ||
|
|
7226a5fbc6 | ||
|
|
6965907cfd | ||
|
|
3f27ef3e47 | ||
|
|
a8dab9bc02 | ||
|
|
a00de166e3 | ||
|
|
f5bc499537 | ||
|
|
1876e3d0c5 | ||
|
|
c0bef11c5c | ||
|
|
bcbb0f7dc5 | ||
|
|
aa99cd3068 | ||
|
|
4a0ff52fed | ||
|
|
60a4d86c51 | ||
|
|
4fb7ebb10b | ||
|
|
74fb6a1cc6 | ||
|
|
89bf200f4a | ||
|
|
3d8d025fc9 | ||
|
|
99429bc2e7 | ||
|
|
ed31151b7b | ||
|
|
3321403096 | ||
|
|
65acc52e9b | ||
|
|
5b1b55ca3d | ||
|
|
32086d24b0 | ||
|
|
be4f7b0971 | ||
|
|
650e7f4413 | ||
|
|
42ad7c3c15 | ||
|
|
3e9a23b0c2 | ||
|
|
d5ba1ad118 | ||
|
|
25eabd1cf5 | ||
|
|
b84a6446e0 | ||
|
|
6e86742a1e | ||
|
|
e888e4f5b5 | ||
|
|
3764b6af59 | ||
|
|
fb4580b1d8 | ||
|
|
979525d85b | ||
|
|
8335910113 | ||
|
|
47a18fef09 | ||
|
|
e79ee5506d | ||
|
|
6aed72c3cb | ||
|
|
16bee21512 | ||
|
|
34e070e2e6 | ||
|
|
7b58f587c6 | ||
|
|
54e0227e3c | ||
|
|
12de968465 | ||
|
|
f7b5a14555 | ||
|
|
97e6f4c2a0 | ||
|
|
1804f9cda9 | ||
|
|
b03e4f2c25 | ||
|
|
5e6edf1916 | ||
|
|
ea06788681 | ||
|
|
6ccbf45b53 | ||
|
|
818907e679 | ||
|
|
2cc71ff726 | ||
|
|
f67b7cb7d4 | ||
|
|
ee63896f22 | ||
|
|
272bba72a6 | ||
|
|
a335fab7bc | ||
|
|
303def8b2f | ||
|
|
11af0d5487 | ||
|
|
a5398177fe | ||
|
|
b53199a00e | ||
|
|
b1924f7411 | ||
|
|
4cd399f356 | ||
|
|
c71348e149 | ||
|
|
b6c9cbc725 | ||
|
|
0a758fc284 | ||
|
|
17e86ea0d3 | ||
|
|
a05e8bc79c | ||
|
|
9742130614 | ||
|
|
83d14dc5be | ||
|
|
a43bb541fd | ||
|
|
0cdb81ae31 | ||
|
|
c865c6b1a0 | ||
|
|
4d394f08a8 | ||
|
|
b7dd77cb9c | ||
|
|
9580084b2e | ||
|
|
ddb2ac9dba | ||
|
|
a341cab53e | ||
|
|
12cebdf624 | ||
|
|
728b1187ea | ||
|
|
a92e807f0f | ||
|
|
9abac6ec14 | ||
|
|
e3eead7859 | ||
|
|
816c220091 | ||
|
|
e95c8c252c | ||
|
|
8d8eebe99a | ||
|
|
0470b16268 | ||
|
|
1c6ec17756 | ||
|
|
27f6d4ede8 | ||
|
|
166f274706 | ||
|
|
0c23aa10ad | ||
|
|
f373a08f6a | ||
|
|
58d967a485 | ||
|
|
f2cce4787b | ||
|
|
9f1356d39b | ||
|
|
4b139e7518 | ||
|
|
a158cc6907 | ||
|
|
5efc849353 | ||
|
|
538fd546c3 | ||
|
|
13022b6f90 | ||
|
|
3e8fa0a7c8 | ||
|
|
602ba53314 | ||
|
|
11c3b08a0f | ||
|
|
0249967ebb | ||
|
|
3ceb6cdb8d | ||
|
|
1fec174297 | ||
|
|
e755170fd9 | ||
|
|
48def083c9 | ||
|
|
94c665accf | ||
|
|
125a2223ee |
No files matched your search
@@ -0,0 +1,81 @@
|
||||
|
||||
# have to disable proxy servers as otherwise CDash commits fail
|
||||
before_script:
|
||||
- export http_proxy=
|
||||
- export https_proxy=
|
||||
|
||||
build-centos6-gcc:
|
||||
script:
|
||||
- "./scripts/test.py platform:x64 build:RelWithDebInfo compiler:ICC isa:SSE2 tasking:TBB"
|
||||
|
||||
#####################################################################
|
||||
# WINDOWS
|
||||
####################################################################
|
||||
|
||||
.windows-x64-RelWithDebInfo-V140-AVX2-TBB:
|
||||
script: "./sripts/test.py platform:x64 build:RelWithDebInfo compiler:V140 isa:AVX2 tasking:TBB intensive:OFF"
|
||||
tags: [win, v140]
|
||||
|
||||
.windows-x64-RelWithDebInfo-V120-AVX2-TBB:
|
||||
script: "./scripts/test.py platform:x64 build:RelWithDebInfo compiler:V120 isa:AVX2 tasking:TBB intensive:OFF"
|
||||
tags: [win, v120]
|
||||
|
||||
.windows-x64-RelWithDebInfo-ICC17-AVX2-TBB:
|
||||
script: "./scripts/test.py platform:x64 build:RelWithDebInfo compiler:ICC17 isa:AVX2 tasking:TBB intensive:OFF"
|
||||
tags: [win, icc17]
|
||||
|
||||
.windows-x64-RelWithDebInfo-CLANG-AVX2-TBB:
|
||||
script: "./scripts/test.py platform:x64 build:RelWithDebInfo compiler:CLANG isa:AVX2 tasking:TBB intensive:OFF"
|
||||
tags: [win, clang]
|
||||
|
||||
|
||||
#####################################################################
|
||||
# MACOSX
|
||||
####################################################################
|
||||
|
||||
.macosx-x64-RelWithDebInfo-CLANG-AVX2:
|
||||
script: "./scripts/test.py platform:x64 build:RelWithDebInfo compiler:CLANG isa:AVX2 tasking:TBB intensive:OFF"
|
||||
tags: [macosx, clang]
|
||||
|
||||
.macosx-x64-RelWithDebInfo-ICC16-AVX2:
|
||||
script: "./scripts/test.py platform:x64 build:RelWithDebInfo compiler:ICC16 isa:AVX2 tasking:TBB intensive:OFF"
|
||||
tags: [macosx, icc16]
|
||||
|
||||
|
||||
#####################################################################
|
||||
# LINUX
|
||||
####################################################################
|
||||
|
||||
.linux-x64-RelWithDebInfo-CLANG-AVX2-TBB:
|
||||
script: "./scripts/test.py platform:x64 build:RelWithDebInfo compiler:CLANG isa:AVX2 tasking:TBB intensive:OFF"
|
||||
tags: [linux, clang]
|
||||
|
||||
.linux-x64-RelWithDebInfo-GCC-AVX2-TBB:
|
||||
script: "./scripts/test.py platform:x64 build:RelWithDebInfo compiler:GCC isa:AVX2 tasking:TBB intensive:OFF"
|
||||
tags: [linux, gcc]
|
||||
|
||||
.linux-x64-RelWithDebInfo-ICC17-AVX512KNL-TBB:
|
||||
script: "./scripts/test.py platform:x64 build:RelWithDebInfo compiler:ICC17 isa:AVX512KNL tasking:TBB intensive:OFF"
|
||||
tags: [linux, icc17]
|
||||
|
||||
.linux-x64-RelWithDebInfo-ICC17-AVX2-TBB-KLOCKWORK:
|
||||
script: "./scripts/test.py platform:x64 build:RelWithDebInfo compiler:ICC17 isa:AVX2 tasking:TBB klocwork:ON"
|
||||
tags: [linux, icc17, klocwork]
|
||||
|
||||
.linux-knl-x64-RelWithDebInfo-ICC17-AVX512KNL-TBB:
|
||||
script: "./scripts/test.py platform:x64 build:RelWithDebInfo compiler:ICC17 isa:AVX512KNL tasking:TBB intensive:OFF"
|
||||
tags: [linux, knl, icc17]
|
||||
|
||||
.linux-knl-x64-RelWithDebInfo-CLANG4-AVX512KNL-TBB:
|
||||
script: "./scripts/test.py platform:x64 build:RelWithDebInfo compiler:CLANG4 isa:AVX512KNL tasking:TBB intensive:OFF"
|
||||
tags: [linux, knl, clang4]
|
||||
|
||||
.linux-skx-x64-RelWithDebInfo-ICC17-AVX512SKX-TBB:
|
||||
script: "./scripts/test.py platform:x64 build:RelWithDebInfo compiler:ICC17 isa:AVX512SKX tasking:TBB intensive:OFF"
|
||||
tags: [linux, skx, icc17]
|
||||
|
||||
.linux-skx-x64-RelWithDebInfo-CLANG4-AVX512SKX-TBB:
|
||||
script: "./scripts/test.py platform:x64 build:RelWithDebInfo compiler:CLANG4 isa:AVX512SKX tasking:TBB intensive:OFF"
|
||||
tags: [linux, skx, clang4]
|
||||
|
||||
|
||||
+153
-55
@@ -1,13 +1,130 @@
|
||||
Version History
|
||||
---------------
|
||||
|
||||
### New Features in Embree 2.17.0
|
||||
- Improved packet ray tracing performance for coherent rays by 10-60%
|
||||
(requires RTC_INTERSECT_COHERENT flag).
|
||||
- Improved ray tracing performance for incoherent rays on
|
||||
AVX-512 architectures by 5%.
|
||||
- Improved ray tracing performance for streams of incoherent rays
|
||||
by 5-15%.
|
||||
- Fixed tbb_debug.lib linking error under Windows.
|
||||
- Fast coherent ray stream and packet code paths now also work in robust mode.
|
||||
- Using less agressive prefetching for large BVH nodes which
|
||||
results in 1-2% higher ray tracing performance.
|
||||
- Precompiled binaries have stack-protector enabled, except for
|
||||
traversal kernels. BVH builders can be slightly slower due to this
|
||||
change. If you want stack-protectors disabled please turn off
|
||||
EMBREE_STACK_PROTECTOR in cmake and build the binaries yourself.
|
||||
- When enabling ISAs individually, the 8-wide BVH was previously only
|
||||
available when the AVX ISA was also selected. This issue is now
|
||||
fixed, and one can enable only AVX2 and still get best
|
||||
performance by using an 8-wide BVH.
|
||||
- Fixed rtcOccluded1 and rtcOccluded1Ex API functions which were
|
||||
broken in ISPC.
|
||||
|
||||
### New Features in Embree 2.16.5
|
||||
- Bugfix in the robust triangle intersector that rarely caused NaNs.
|
||||
- Fixed bug in hybrid traversal kernel when BVH leaf was entered with no
|
||||
active rays. This rarely caused crashes when used with instancing.
|
||||
- Fixed bug introduced in Embree 2.16.2 which caused instancing not to
|
||||
work properly when a smaller than the native SIMD width was
|
||||
used in ray packet mode.
|
||||
- Fixed bug in the curve geometry intersector that caused rendering
|
||||
artefacts for Bézier curves with p0=p1 and/or p2=p3.
|
||||
- Fixed bug in the curve geometry intersector that caused hit results
|
||||
with NaNs to be reported.
|
||||
- Fixed masking bug that caused rare cracks in curve geometry.
|
||||
- Enabled support for SSE2 in precompiled binaries again.
|
||||
|
||||
### New Features in Embree 2.16.4
|
||||
- Bugfix in the ribbon intersector for hair primitives. Non-normalized
|
||||
rays caused wrong intersection distance to be reported.
|
||||
|
||||
### New Features in Embree 2.16.3
|
||||
- Increased accuracy for handling subdivision surfaces. This fixes
|
||||
cracks when using displacement mapping but reduces performance
|
||||
at irregular vertices.
|
||||
- Fixed a bug where subdivision geometry was not properly updated
|
||||
when modifying only the tesselation rate and vertex array.
|
||||
|
||||
### New Features in Embree 2.16.2
|
||||
- Fixed bug that caused NULL intersection context in intersection
|
||||
filter when instancing was used.
|
||||
- Fixed an issue where uv's where outside the triangle (or quad) for
|
||||
very small triangles (or quads). In robust mode we improved the uv
|
||||
calculation to avoid that issue, in fast mode we accept that
|
||||
inconsistency for better performance.
|
||||
- Changed UV encoding for non-quad subdivision patches to
|
||||
allow a subpatch UV range of `[-0.5,1.5[`. Using this new encoding
|
||||
one can use finite differences to calculate derivatives if required.
|
||||
Please adjust your code in case you rely on the old encoding.
|
||||
|
||||
### New Features in Embree 2.16.1
|
||||
- Workaround for compile issues with Visual Studio 2017
|
||||
- Fixed bug in subdiv code for static scenes when using tessellation
|
||||
levels larger than 50.
|
||||
- Fixed low performance when adding many geometries to a scene.
|
||||
- Fixed high memory consumption issue when using instances in
|
||||
dynamic scene (by disabling two level builder for user geometries
|
||||
and instances).
|
||||
|
||||
### New Features in Embree 2.16.0
|
||||
- Improved multi-segment motion blur support for scenes with
|
||||
different number of time steps per mesh.
|
||||
- New top level BVH builder that improves build times and BVH quality
|
||||
of two-level BVHs.
|
||||
- Added support to enable only a single ISA. Previously code was
|
||||
always compiled for SSE2.
|
||||
- Improved single ray tracing performance for incoherent rays on
|
||||
AVX-512 architectures by 5-10%.
|
||||
- Improved packet/hybrid ray tracing performance for incoherent rays
|
||||
on AVX-512 architectures by 10-30%.
|
||||
- Improved stream ray tracing performance for coherent rays in
|
||||
structure-of-pointers layout by 40-70%.
|
||||
- BVH builder for compact scenes of triangles and quads needs
|
||||
essentially no temporary memory anymore. This doubles the
|
||||
maximal scene size that can be rendered in compact mode.
|
||||
- Triangles no longer store the geometry normal in fast/default mode
|
||||
which reduces memory consumption by up to 20%.
|
||||
- Compact mode uses BVH4 now consistently which reduces memory
|
||||
consumption by up to 10%.
|
||||
- Reduced memory consumption for small scenes (of 10k-100k primitives)
|
||||
and dynamic scenes.
|
||||
- Improved performance of user geometries and instances through BVH8
|
||||
support.
|
||||
- The API supports now specifying the geometry ID of a geometry at
|
||||
construction time. This way matching the geometry ID used by
|
||||
Embree and the application is simplified.
|
||||
- Fixed a bug that would have caused a failure of the BVH builder
|
||||
for dynamic scenes when run on a machine with more then 1000 threads.
|
||||
- Fixed a bug that could have been triggered when reaching the maximal
|
||||
number of mappings under Linux (`vm.max_map_count`). This could have
|
||||
happened when creating a large number of small static scenes.
|
||||
- Added huge page support for Windows and MacOSX (experimental).
|
||||
- Added support for Visual Studio 2017.
|
||||
- Removed support for Visual Studio 2012.
|
||||
- Precompiled binaries now require a CPU supporting at least the
|
||||
SSE4.2 ISA.
|
||||
- We no longer provide precompiled binaries for 32-bit on Windows.
|
||||
- Under Windows one now has to use the platform toolset option in
|
||||
CMake to switch to Clang or the Intel® Compiler.
|
||||
- Fixed a bug for subdivision meshes when using the incoherent scene
|
||||
flag.
|
||||
- Fixed a bug in the line geometry intersection, that caused reporting
|
||||
an invalid line segment intersection with primID -1.
|
||||
- Buffer stride for vertex buffers of different time steps of triangle
|
||||
and quad meshes have to be identical now.
|
||||
- Fixed a bug in the curve geometry intersection code when passed a
|
||||
perfect cylinder.
|
||||
|
||||
### New Features in Embree 2.15.0
|
||||
|
||||
- Added `rtcCommitJoin` mode that allows thread to join a build
|
||||
operation. When using the internal tasking system this allows
|
||||
Embree to solely use the threads that called `rtcCommitJoin` to
|
||||
build the scene, while previously also normal worker threads
|
||||
participated in the build. You should no longer use `rtcCommit`
|
||||
participated in the build. You should no longer use `rtcCommit`
|
||||
to join a build.
|
||||
- Added `rtcDeviceSetErrorFunction2` API call, which sets an error
|
||||
callback function which additionally gets passed a user provided
|
||||
@@ -16,20 +133,21 @@ Version History
|
||||
memory monitor callback function which additionally get passed a
|
||||
user provided pointer. (`rtcDeviceSetMemoryMonitorFunction` is now
|
||||
deprecated).
|
||||
- Build performance for hair geometry improved up to 2x.
|
||||
- Added API extension to use internal Morton builder, standard SAH
|
||||
builder, and spatial split SAH builder.
|
||||
- Build performance for hair geometry improved by up to 2×.
|
||||
- Standard BVH build performance increased by 5%.
|
||||
- Added API extension to use internal Morton-code based builder, the
|
||||
standard binned-SAH builder, and the spatial split-based SAH builder.
|
||||
- Added support for BSpline hair and curves. Embree uses
|
||||
either the Bezier or BSpline basis internally, and converts other
|
||||
curves, which requiring more memory during rendering. For reduced
|
||||
memory consumption set the EMBREE_NATIVE_SPLINE_BASIS to the basis
|
||||
your application uses (which is set to BEZIER by default).
|
||||
- Setting the number of threads through an application side
|
||||
tbb::taskscheduler_init object is now working properly.
|
||||
- Windows and Linux releases are build using AVX512 support.
|
||||
either the Bézier or BSpline basis internally, and converts other
|
||||
curves, which requires more memory during rendering. For reduced
|
||||
memory consumption set the `EMBREE_NATIVE_SPLINE_BASIS` to the basis
|
||||
your application uses (which is set to `BEZIER` by default).
|
||||
- Setting the number of threads through `tbb::taskscheduler_init`
|
||||
object on the application side is now working properly.
|
||||
- Windows and Linux releases are build using AVX-512 support.
|
||||
- Implemented hybrid traversal for hair and line segments for
|
||||
improved ray packet performance.
|
||||
- AVX512 code compiles with Clang 4.0.0
|
||||
- AVX-512 code compiles with Clang 4.0.0
|
||||
- Fixed crash when ray packets were disabled in CMake.
|
||||
|
||||
### New Features in Embree 2.14.0
|
||||
@@ -49,14 +167,14 @@ Version History
|
||||
- Reduced memory consumption when using lots of small dynamic objects.
|
||||
- Fixed bug for subdivision surfaces using low tessellation rates.
|
||||
- Hair geometry now uses a new ribbon intersector that intersects with
|
||||
ray-facing quads. The new intersector also returns the
|
||||
v-coordinate of the hair intersection, and fixes artefacts at junction
|
||||
points between segments, at the cost of a small performance hit.
|
||||
ray-facing quads. The new intersector also returns the v-coordinate
|
||||
of the hair intersection, and fixes artefacts at junction points
|
||||
between segments, at the cost of a small performance hit.
|
||||
- Added `rtcSetBuffer2` function, that additionally gets the number of
|
||||
elements of a buffer. In dynamic scenes, this function allows to
|
||||
quickly change buffer sizes, making it possible to change the number of
|
||||
primitives of a mesh or the number of crease features for subdivision
|
||||
surfaces.
|
||||
quickly change buffer sizes, making it possible to change the number
|
||||
of primitives of a mesh or the number of crease features for
|
||||
subdivision surfaces.
|
||||
- Added simple 'viewer_anim' tutorial for rendering key
|
||||
frame animations and 'buildbench' for measuring BVH (re-)build
|
||||
performance for static and dynamic scenes.
|
||||
@@ -70,8 +188,8 @@ Version History
|
||||
- Up to 20% faster BVH build performance on the second generation
|
||||
Intel® Xeon Phi™ processor codenamed Knights Landing.
|
||||
- Improved quality of the spatial split builder.
|
||||
- Improved performance for coherent streams of ray packets (SOA layout),
|
||||
e.g. for fast primary visibility.
|
||||
- Improved performance for coherent streams of ray packets (SOA
|
||||
layout), e.g. for fast primary visibility.
|
||||
- Various bug fixes in tessellation cache, quad-based spatial
|
||||
split builder, etc.
|
||||
|
||||
@@ -106,8 +224,8 @@ Version History
|
||||
|
||||
- Improved performance for streams of coherent (single) rays flagged
|
||||
with `RTC_INTERSECT_COHERENT`. For such coherent ray streams, e.g.
|
||||
primary rays, the performance typically improves by 1.3–2×.
|
||||
- New spatial split BVH builder for triangles, which is 2–6× faster
|
||||
primary rays, the performance typically improves by 1.3-2×.
|
||||
- New spatial split BVH builder for triangles, which is 2-6× faster
|
||||
than the previous version and more memory conservative.
|
||||
- Improved performance and scalability of all standard BVH builders on
|
||||
systems with large core counts.
|
||||
@@ -124,12 +242,12 @@ Version History
|
||||
- Geometry types can get disabled at compile time.
|
||||
- Modified and extended the ray stream API.
|
||||
- Added new callback mechanism for the ray stream API.
|
||||
- Improved ray stream performance (up to 5–10%).
|
||||
- Improved ray stream performance (up to 5-10%).
|
||||
- Up to 20% faster morton builder on machines with large core counts.
|
||||
- Lots of optimizations for the second generation Intel® Xeon Phi™
|
||||
processor codenamed Knights Landing.
|
||||
- Added experimental support for compressed BVH nodes (reduces node
|
||||
size to 56–62% of uncompressed size). Compression introduces a
|
||||
size to 56-62% of uncompressed size). Compression introduces a
|
||||
typical performance overhead of ~10%.
|
||||
- Bugfix in backface culling mode. We do now properly cull the
|
||||
backfaces and not the frontfaces.
|
||||
@@ -140,8 +258,8 @@ Version History
|
||||
|
||||
### New Features in Embree 2.9.0
|
||||
|
||||
- Improved shadow ray performance (10–100% depending on the scene).
|
||||
- Added initial support for ray streams (10–30% higher performance
|
||||
- Improved shadow ray performance (10-100% depending on the scene).
|
||||
- Added initial support for ray streams (10-30% higher performance
|
||||
depending on ray coherence in the stream).
|
||||
- Added support to calculate second order derivatives using the
|
||||
`rtcInterpolate2` function.
|
||||
@@ -162,26 +280,29 @@ Version History
|
||||
- Added support for quad geometry (replaces triangle-pairs feature).
|
||||
- Added support for linear motion blur of user geometries.
|
||||
- Improved performance through AVX-512 optimizations.
|
||||
- Improved performance of lazy scene build (when using TBB 4.4 update 2).
|
||||
- Improved performance of lazy scene build (when using TBB 4.4 update
|
||||
2).
|
||||
- Improved performance through huge page support under linux.
|
||||
|
||||
### New Features in Embree 2.7.1
|
||||
|
||||
- Internal tasking system supports cancellation of build operations.
|
||||
- ISPC mode for robust and compact scenes got significantly faster
|
||||
(implemented hybrid traversal for bvh4.triangle4v and bvh4.triangle4i).
|
||||
(implemented hybrid traversal for bvh4.triangle4v and
|
||||
bvh4.triangle4i).
|
||||
- Hair rendering got faster as we fixed some issues with the SAH
|
||||
heuristic cost factors.
|
||||
- BVH8 got slight faster for single ray traversal (improved sorting
|
||||
when hitting more than 4 boxes).
|
||||
- BVH build performance got up to 30% faster on CPUs with high core
|
||||
counts (improved parallel partition code).
|
||||
- High quality build mode again working properly (spatial splits had been
|
||||
deactivated in v2.7.0 due to some bug).
|
||||
- High quality build mode again working properly (spatial splits had
|
||||
been deactivated in v2.7.0 due to some bug).
|
||||
- Support for merging two adjacent triangles sharing a common edge
|
||||
into a triangle-pair primitive (can reduce memory consumption and
|
||||
BVH build times by up to 50% for mostly quad-based input meshes).
|
||||
- Internal cleanups (reduced number of traversal kernels by more templating)
|
||||
- Internal cleanups (reduced number of traversal kernels by more
|
||||
templating).
|
||||
- Reduced stack size requirements of BVH builders.
|
||||
- Fixed crash for dynamic scenes, triggered by deleting all
|
||||
geometries from the scene.
|
||||
@@ -295,7 +416,7 @@ Version History
|
||||
|
||||
- Improved mixed AABB/OBB-BVH for hair geometry (Xeon Phi)
|
||||
- Reduced amount of pre-allocated memory for BVH builders (Xeon Phi)
|
||||
- New 64 bit Morton code-based BVH builder (Xeon Phi)
|
||||
- New 64-bit Morton code-based BVH builder (Xeon Phi)
|
||||
- (Enhanced) Morton code-based BVH builders use now tree rotations to
|
||||
improve BVH quality (Xeon Phi)
|
||||
- Bug fixes (Xeon and Xeon Phi)
|
||||
@@ -351,29 +472,6 @@ Version History
|
||||
- New variant of the SAH-based builder using triangle pre-splits
|
||||
(Xeon Phi)
|
||||
|
||||
### Example Performance Numbers for Embree 2.1
|
||||
|
||||
BVH rebuild performance (including triangle accel generation, excluding
|
||||
memory allocation) for scenes with 2–12 million triangles:
|
||||
|
||||
- Intel® Core™ i7 (Haswell-based CPU, 4 cores @ 3.0 GHz)
|
||||
- 7–8 million triangles/s for the SAH-based BVH builder
|
||||
- 30–36 million triangles/s for the Morton code-based BVH builder
|
||||
- Intel® Xeon Phi™ 7120
|
||||
- 37–40 million triangles/s for the SAH-based BVH builder
|
||||
- 140–160 million triangles/s for the Morton code-based BVH
|
||||
builder
|
||||
|
||||
Rendering of the Crown model (`crown.ecs`) with 4 samples per pixel
|
||||
(`-spp 4`):
|
||||
|
||||
- Intel® Core™ i7 (Haswell-based CPU, 4 cores CPU @ 3.0 GHz)
|
||||
- 1024×1024 resolution: 7.8 million rays per sec
|
||||
- 1920×1080 resolution: 9.9 million rays per sec
|
||||
- Intel® Xeon Phi™ 7120
|
||||
- 1024×1024 resolution: 47.1 million rays per sec
|
||||
- 1920×1080 resolution: 61.1 million rays per sec
|
||||
|
||||
### New Features in Embree 2.0
|
||||
|
||||
- Support for the Intel® Xeon Phi™ coprocessor platform
|
||||
|
||||
+46
-25
@@ -15,9 +15,9 @@
|
||||
## ======================================================================== ##
|
||||
|
||||
SET(EMBREE_VERSION_MAJOR 2)
|
||||
SET(EMBREE_VERSION_MINOR 16)
|
||||
SET(EMBREE_VERSION_PATCH 0)
|
||||
SET(EMBREE_VERSION_NOTE "-alpha.3")
|
||||
SET(EMBREE_VERSION_MINOR 17)
|
||||
SET(EMBREE_VERSION_PATCH 1)
|
||||
SET(EMBREE_VERSION_NOTE "-alpha.0")
|
||||
SET(EMBREE_VERSION ${EMBREE_VERSION_MAJOR}.${EMBREE_VERSION_MINOR}.${EMBREE_VERSION_PATCH})
|
||||
MATH(EXPR EMBREE_VERSION_NUMBER "10000*${EMBREE_VERSION_MAJOR} + 100*${EMBREE_VERSION_MINOR} + ${EMBREE_VERSION_PATCH}")
|
||||
SET(CPACK_RPM_PACKAGE_RELEASE 1)
|
||||
@@ -43,8 +43,12 @@ IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.git)
|
||||
ENDIF()
|
||||
|
||||
CONFIGURE_FILE(
|
||||
"${PROJECT_SOURCE_DIR}/kernels/version.h.in"
|
||||
"${PROJECT_BINARY_DIR}/version.h"
|
||||
"${PROJECT_SOURCE_DIR}/kernels/rtcore_version.h.in"
|
||||
"${PROJECT_SOURCE_DIR}/include/embree2/rtcore_version.h"
|
||||
)
|
||||
CONFIGURE_FILE(
|
||||
"${PROJECT_SOURCE_DIR}/kernels/hash.h.in"
|
||||
"${PROJECT_BINARY_DIR}/hash.h"
|
||||
)
|
||||
FILE(WRITE "${PROJECT_BINARY_DIR}/hash" "${EMBREE_HASH}")
|
||||
|
||||
@@ -74,11 +78,14 @@ INCLUDE(test)
|
||||
##############################################################
|
||||
# Embree configuration
|
||||
##############################################################
|
||||
|
||||
GET_PROPERTY(SHARED_LIBS_SUPPORTED GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS)
|
||||
IF(SHARED_LIBS_SUPPORTED)
|
||||
OPTION(EMBREE_STATIC_LIB "Build Embree as a static library." OFF)
|
||||
OPTION(EMBREE_STATIC_LIB "Build Embree as a static library.")
|
||||
MARK_AS_ADVANCED(CLEAR EMBREE_STATIC_LIB)
|
||||
ELSE()
|
||||
OPTION(EMBREE_STATIC_LIB "Build Embree as a static library." ON)
|
||||
SET(EMBREE_STATIC_LIB ON CACHE BOOL "Build Embree as a static library." FORCE)
|
||||
MARK_AS_ADVANCED(EMBREE_STATIC_LIB)
|
||||
ENDIF()
|
||||
IF (EMBREE_STATIC_LIB)
|
||||
SET(EMBREE_LIB_TYPE STATIC)
|
||||
@@ -94,6 +101,7 @@ OPTION(EMBREE_TUTORIALS "Enable to build Embree tutorials" ON)
|
||||
# Configurations (add configurations also to common/cmake/embree-config-default.cmake)
|
||||
|
||||
OPTION(EMBREE_STAT_COUNTERS "Enables statistic counters.")
|
||||
OPTION(EMBREE_STACK_PROTECTOR "When enabled Embree compiles with stack protection against return address overrides." OFF)
|
||||
|
||||
OPTION(EMBREE_RAY_MASK "Enables ray mask support.")
|
||||
OPTION(EMBREE_BACKFACE_CULLING "Enables backface culling.")
|
||||
@@ -161,12 +169,12 @@ ENDIF()
|
||||
SET_PROPERTY(CACHE EMBREE_MAX_ISA PROPERTY STRINGS NONE SSE2 SSE4.2 AVX AVX2 AVX512KNL AVX512SKX)
|
||||
|
||||
IF (EMBREE_MAX_ISA STREQUAL "NONE")
|
||||
SET(EMBREE_ISA_SSE2 "OFF" CACHE BOOL "Enables SSE2 ISA.")
|
||||
SET(EMBREE_ISA_SSE42 "OFF" CACHE BOOL "Enables SSE4.2 ISA.")
|
||||
SET(EMBREE_ISA_AVX "OFF" CACHE BOOL "Enables AVX ISA.")
|
||||
SET(EMBREE_ISA_AVX2 "OFF" CACHE BOOL "Enables AVX2 ISA.")
|
||||
SET(EMBREE_ISA_AVX512KNL "OFF" CACHE BOOL "Enables AVX512 ISA for Knights Landing.")
|
||||
SET(EMBREE_ISA_AVX512SKX "OFF" CACHE BOOL "Enables AVX512 ISA for Skylake.")
|
||||
OPTION(EMBREE_ISA_SSE2 "Enables SSE2 ISA.")
|
||||
OPTION(EMBREE_ISA_SSE42 "Enables SSE4.2 ISA.")
|
||||
OPTION(EMBREE_ISA_AVX "Enables AVX ISA.")
|
||||
OPTION(EMBREE_ISA_AVX2 "Enables AVX2 ISA.")
|
||||
OPTION(EMBREE_ISA_AVX512KNL "Enables AVX512 ISA for Knights Landing.")
|
||||
OPTION(EMBREE_ISA_AVX512SKX "Enables AVX512 ISA for Skylake.")
|
||||
IF(NOT (EMBREE_ISA_SSE2 OR EMBREE_ISA_SSE42 OR EMBREE_ISA_AVX OR
|
||||
EMBREE_ISA_AVX2 OR EMBREE_ISA_AVX512KNL OR EMBREE_ISA_AVX512SKX))
|
||||
MESSAGE(STATUS "Detecting default ISA:")
|
||||
@@ -279,53 +287,66 @@ ENDIF (WIN32)
|
||||
# ISA configuration continued
|
||||
##############################################################
|
||||
|
||||
SET(SSE2 0)
|
||||
SET(SSE42 1)
|
||||
SET(AVX 2)
|
||||
SET(AVX2 3)
|
||||
SET(AVX512KNL 4)
|
||||
SET(AVX512SKX 5)
|
||||
|
||||
UNSET(FLAGS_LOWEST)
|
||||
|
||||
IF (EMBREE_ISA_SSE2)
|
||||
ADD_DEFINITIONS(-D__TARGET_SSE2__)
|
||||
ADD_DEFINITIONS(-DEMBREE_TARGET_SSE2)
|
||||
LIST(APPEND ISPC_TARGETS "sse2")
|
||||
IF(NOT FLAGS_LOWEST)
|
||||
SET(FLAGS_LOWEST ${FLAGS_SSE2})
|
||||
SET(ISA_LOWEST ${SSE2})
|
||||
SET(FLAGS_LOWEST ${FLAGS_SSE2})
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
IF (EMBREE_ISA_SSE42)
|
||||
ADD_DEFINITIONS(-D__TARGET_SSE42__)
|
||||
ADD_DEFINITIONS(-DEMBREE_TARGET_SSE42)
|
||||
LIST(APPEND ISPC_TARGETS "sse4")
|
||||
IF(NOT FLAGS_LOWEST)
|
||||
SET(FLAGS_LOWEST ${FLAGS_SSE42})
|
||||
SET(ISA_LOWEST ${SSE42})
|
||||
SET(FLAGS_LOWEST ${FLAGS_SSE42})
|
||||
ENDIF()
|
||||
ENDIF ()
|
||||
|
||||
IF (EMBREE_ISA_AVX)
|
||||
ADD_DEFINITIONS(-D__TARGET_AVX__)
|
||||
ADD_DEFINITIONS(-DEMBREE_TARGET_AVX)
|
||||
LIST(APPEND ISPC_TARGETS "avx")
|
||||
IF(NOT FLAGS_LOWEST)
|
||||
SET(FLAGS_LOWEST ${FLAGS_AVX})
|
||||
SET(ISA_LOWEST ${AVX})
|
||||
SET(FLAGS_LOWEST ${FLAGS_AVX})
|
||||
ENDIF()
|
||||
ENDIF ()
|
||||
|
||||
IF (EMBREE_ISA_AVX2)
|
||||
ADD_DEFINITIONS(-D__TARGET_AVX2__)
|
||||
ADD_DEFINITIONS(-DEMBREE_TARGET_AVX2)
|
||||
LIST(APPEND ISPC_TARGETS "avx2")
|
||||
IF(NOT FLAGS_LOWEST)
|
||||
SET(FLAGS_LOWEST ${FLAGS_AVX2})
|
||||
SET(ISA_LOWEST ${AVX2})
|
||||
SET(FLAGS_LOWEST ${FLAGS_AVX2})
|
||||
ENDIF()
|
||||
ENDIF ()
|
||||
|
||||
IF (EMBREE_ISA_AVX512KNL)
|
||||
ADD_DEFINITIONS(-D__TARGET_AVX512KNL__)
|
||||
ADD_DEFINITIONS(-DEMBREE_TARGET_AVX512KNL)
|
||||
LIST(APPEND ISPC_TARGETS "avx512knl-i32x16")
|
||||
IF(NOT FLAGS_LOWEST)
|
||||
SET(FLAGS_LOWEST ${FLAGS_AVX512KNL})
|
||||
SET(ISA_LOWEST ${AVX512KNL})
|
||||
SET(FLAGS_LOWEST ${FLAGS_AVX512KNL})
|
||||
ENDIF()
|
||||
ENDIF ()
|
||||
|
||||
IF (EMBREE_ISA_AVX512SKX)
|
||||
ADD_DEFINITIONS(-D__TARGET_AVX512SKX__)
|
||||
ADD_DEFINITIONS(-DEMBREE_TARGET_AVX512SKX)
|
||||
LIST(APPEND ISPC_TARGETS "avx512skx-i32x16")
|
||||
IF(NOT FLAGS_LOWEST)
|
||||
SET(FLAGS_LOWEST ${FLAGS_AVX512SKX})
|
||||
SET(ISA_LOWEST ${AVX512SKX})
|
||||
SET(FLAGS_LOWEST ${FLAGS_AVX512SKX})
|
||||
ENDIF()
|
||||
ENDIF ()
|
||||
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@
|
||||
|
||||
set(CTEST_PROJECT_NAME "Embree")
|
||||
set(CTEST_NIGHTLY_START_TIME "22:00:00 UTC")
|
||||
set(TEST_MODELS_HASH 208ffea4545822ac58015d215b19927ee9449918)
|
||||
set(TEST_MODELS_HASH 01ada7ec1ace15ddba73aaab3f53ac6aac6a0309)
|
||||
|
||||
IF (NOT CTEST_DROP_SITE)
|
||||
set(CTEST_DROP_METHOD "http")
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
## ======================================================================== ##
|
||||
|
||||
ADD_SUBDIRECTORY(sys)
|
||||
ADD_SUBDIRECTORY(math)
|
||||
ADD_SUBDIRECTORY(simd)
|
||||
ADD_SUBDIRECTORY(lexers)
|
||||
ADD_SUBDIRECTORY(tasking)
|
||||
|
||||
@@ -33,29 +33,31 @@ namespace embree
|
||||
|
||||
for (size_t N=10; N<1000000; N=size_t(2.1*N))
|
||||
{
|
||||
size_t N0 = rand() % N;
|
||||
|
||||
/* initialize array with random numbers */
|
||||
std::vector<uint32_t> src(N);
|
||||
std::map<uint32_t,int> m;
|
||||
for (size_t i=0; i<N; i++) src[i] = rand();
|
||||
|
||||
/* count elements up */
|
||||
for (size_t i=0; i<N; i++)
|
||||
for (size_t i=N0; i<N; i++)
|
||||
if (pred(src[i]))
|
||||
m[src[i]] = 0;
|
||||
for (size_t i=0; i<N; i++)
|
||||
for (size_t i=N0; i<N; i++)
|
||||
if (pred(src[i]))
|
||||
m[src[i]]++;
|
||||
|
||||
/* filter array */
|
||||
//size_t_t M = sequential_filter(src.data(),size_t(0),N,pred);
|
||||
size_t M = parallel_filter(src.data(),size_t(0),N,size_t(1024),pred);
|
||||
//size_t M = sequential_filter(src.data(),N0,N,pred);
|
||||
size_t M = parallel_filter(src.data(),N0,N,size_t(1024),pred);
|
||||
|
||||
/* check if filtered data is correct */
|
||||
for (size_t i=0; i<M; i++) {
|
||||
for (size_t i=N0; i<M; i++) {
|
||||
passed &= pred(src[i]);
|
||||
m[src[i]]--;
|
||||
}
|
||||
for (size_t i=0; i<M; i++)
|
||||
for (size_t i=N0; i<M; i++)
|
||||
passed &= (m[src[i]] == 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -76,8 +76,8 @@ namespace embree
|
||||
parallel_for(taskCount, [&](const Index taskIndex)
|
||||
{
|
||||
/* destination to write elements to */
|
||||
Index dst = (taskIndex+0)*(end-begin)/taskCount+nused[taskIndex];
|
||||
Index dst_end = min(dst+nfree[taskIndex],sused);
|
||||
Index dst = begin+(taskIndex+0)*(end-begin)/taskCount+nused[taskIndex];
|
||||
Index dst_end = min(dst+nfree[taskIndex],begin+sused);
|
||||
if (dst_end <= dst) return;
|
||||
|
||||
/* range of misplaced elements to copy to destination */
|
||||
@@ -92,7 +92,10 @@ namespace embree
|
||||
Index k1 = k0+nused[i];
|
||||
Index src = begin+(i+0)*(end-begin)/taskCount+nused[i];
|
||||
for (Index i=max(r0,k0); i<min(r1,k1); i++) {
|
||||
data[dst++] = data[src-i+k0-1];
|
||||
Index isrc = src-i+k0-1;
|
||||
assert(dst >= begin && dst < end);
|
||||
assert(isrc >= begin && isrc < end);
|
||||
data[dst++] = data[isrc];
|
||||
}
|
||||
k0 = k1;
|
||||
}
|
||||
|
||||
@@ -14,13 +14,36 @@
|
||||
## limitations under the License. ##
|
||||
## ======================================================================== ##
|
||||
|
||||
IF (NOT TBB_ROOT)
|
||||
SET(TBB_ROOT $ENV{TBB_ROOT})
|
||||
ENDIF()
|
||||
IF (NOT TBB_ROOT)
|
||||
SET(TBB_ROOT $ENV{TBBROOT})
|
||||
ENDIF()
|
||||
|
||||
IF (WIN32)
|
||||
# workaround for parentheses in variable name / CMP0053
|
||||
SET(PROGRAMFILESx86 "PROGRAMFILES(x86)")
|
||||
SET(PROGRAMFILES32 "$ENV{${PROGRAMFILESx86}}")
|
||||
IF (NOT PROGRAMFILES32)
|
||||
SET(PROGRAMFILES32 "$ENV{PROGRAMFILES}")
|
||||
ENDIF()
|
||||
IF (NOT PROGRAMFILES32)
|
||||
SET(PROGRAMFILES32 "C:/Program Files (x86)")
|
||||
ENDIF()
|
||||
FIND_PATH(EMBREE_TBB_ROOT include/tbb/tbb.h
|
||||
DOC "Root of TBB installation"
|
||||
PATHS ${PROJECT_SOURCE_DIR}/tbb "C:/Program Files (x86)/Intel/Composer XE/tbb"
|
||||
PATHS ${PROJECT_SOURCE_DIR}/tbb
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
FIND_PATH(EMBREE_TBB_ROOT include/tbb/tbb.h)
|
||||
FIND_PATH(EMBREE_TBB_ROOT include/tbb/tbb.h
|
||||
HINTS ${TBB_ROOT}
|
||||
PATHS
|
||||
${PROJECT_SOURCE_DIR}/../tbb
|
||||
"${PROGRAMFILES32}/IntelSWTools/compilers_and_libraries/windows/tbb"
|
||||
"${PROGRAMFILES32}/Intel/Composer XE/tbb"
|
||||
"${PROGRAMFILES32}/Intel/compilers_and_libraries/windows/tbb"
|
||||
)
|
||||
|
||||
IF (CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
SET(TBB_ARCH intel64)
|
||||
@@ -32,8 +55,10 @@ IF (WIN32)
|
||||
SET(TBB_VCVER vc10)
|
||||
ELSEIF (MSVC11)
|
||||
SET(TBB_VCVER vc11)
|
||||
ELSE()
|
||||
ELSEIF (MSVC12)
|
||||
SET(TBB_VCVER vc12)
|
||||
ELSE()
|
||||
SET(TBB_VCVER vc14)
|
||||
ENDIF()
|
||||
|
||||
SET(TBB_LIBDIR ${EMBREE_TBB_ROOT}/lib/${TBB_ARCH}/${TBB_VCVER})
|
||||
@@ -56,15 +81,40 @@ ELSE ()
|
||||
|
||||
FIND_PATH(EMBREE_TBB_ROOT include/tbb/tbb.h
|
||||
DOC "Root of TBB installation"
|
||||
PATHS ${PROJECT_SOURCE_DIR}/tbb /opt/intel/tbb
|
||||
PATHS ${PROJECT_SOURCE_DIR}/tbb
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
FIND_PATH(EMBREE_TBB_ROOT include/tbb/tbb.h)
|
||||
FIND_PATH(EMBREE_TBB_ROOT include/tbb/tbb.h
|
||||
DOC "Root of TBB installation"
|
||||
HINTS ${TBB_ROOT}
|
||||
PATHS
|
||||
${PROJECT_SOURCE_DIR}/tbb
|
||||
/opt/intel/composerxe/tbb
|
||||
/opt/intel/compilers_and_libraries/tbb
|
||||
/opt/intel/tbb
|
||||
)
|
||||
|
||||
IF (EMBREE_TBB_ROOT STREQUAL "")
|
||||
FIND_PATH(TBB_INCLUDE_DIR tbb/task_scheduler_init.h)
|
||||
FIND_LIBRARY(TBB_LIBRARY tbb)
|
||||
FIND_LIBRARY(TBB_LIBRARY_MALLOC tbbmalloc)
|
||||
|
||||
ELSEIF (EXISTS ${EMBREE_TBB_ROOT}/cmake/TBBBuild.cmake)
|
||||
OPTION(EMBREE_TBB_STATIC_LIB "Build TBB as a static library (building TBB as a static library is NOT recommended)")
|
||||
if (EMBREE_TBB_STATIC_LIB)
|
||||
include(${EMBREE_TBB_ROOT}/cmake/TBBBuild.cmake)
|
||||
tbb_build(TBB_ROOT ${EMBREE_TBB_ROOT} CONFIG_DIR TBB_DIR MAKE_ARGS extra_inc=big_iron.inc)
|
||||
SET(TBB_INCLUDE_DIR ${EMBREE_TBB_ROOT}/include)
|
||||
SET(TBB_LIBRARY ${PROJECT_BINARY_DIR}/tbb_cmake_build/tbb_cmake_build_subdir_release/libtbb.a)
|
||||
SET(TBB_LIBRARY_MALLOC ${PROJECT_BINARY_DIR}/tbb_cmake_build/tbb_cmake_build_subdir_release/libtbbmalloc.a)
|
||||
else()
|
||||
include(${EMBREE_TBB_ROOT}/cmake/TBBBuild.cmake)
|
||||
tbb_build(TBB_ROOT ${EMBREE_TBB_ROOT} CONFIG_DIR TBB_DIR)
|
||||
SET(TBB_INCLUDE_DIR ${EMBREE_TBB_ROOT}/include)
|
||||
SET(TBB_LIBRARY ${PROJECT_BINARY_DIR}/tbb_cmake_build/tbb_cmake_build_subdir_release/libtbb.so.2)
|
||||
SET(TBB_LIBRARY_MALLOC ${PROJECT_BINARY_DIR}/tbb_cmake_build/tbb_cmake_build_subdir_release/libtbbmalloc.so.2)
|
||||
endif()
|
||||
|
||||
ELSE()
|
||||
SET(TBB_INCLUDE_DIR TBB_INCLUDE_DIR-NOTFOUND)
|
||||
SET(TBB_LIBRARY TBB_LIBRARY-NOTFOUND)
|
||||
@@ -75,8 +125,9 @@ ELSE ()
|
||||
FIND_LIBRARY(TBB_LIBRARY_MALLOC tbbmalloc PATHS ${EMBREE_TBB_ROOT}/lib NO_DEFAULT_PATH)
|
||||
ELSE()
|
||||
FIND_PATH(TBB_INCLUDE_DIR tbb/task_scheduler_init.h PATHS ${EMBREE_TBB_ROOT}/include NO_DEFAULT_PATH)
|
||||
FIND_LIBRARY(TBB_LIBRARY tbb PATHS ${EMBREE_TBB_ROOT}/lib/intel64/gcc4.4 ${EMBREE_TBB_ROOT}/lib ${EMBREE_TBB_ROOT}/lib64 /usr/libx86_64-linux-gnu/ NO_DEFAULT_PATH)
|
||||
FIND_LIBRARY(TBB_LIBRARY_MALLOC tbbmalloc PATHS ${EMBREE_TBB_ROOT}/lib/intel64/gcc4.4 ${EMBREE_TBB_ROOT}/lib ${EMBREE_TBB_ROOT}/lib64 /usr/libx86_64-linux-gnu/ NO_DEFAULT_PATH)
|
||||
SET(TBB_HINTS HINTS ${EMBREE_TBB_ROOT}/lib/intel64/gcc4.4 ${EMBREE_TBB_ROOT}/lib ${EMBREE_TBB_ROOT}/lib64 PATHS /usr/libx86_64-linux-gnu/)
|
||||
FIND_LIBRARY(TBB_LIBRARY tbb ${TBB_HINTS})
|
||||
FIND_LIBRARY(TBB_LIBRARY_MALLOC tbbmalloc ${TBB_HINTS})
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
@@ -100,7 +151,7 @@ MARK_AS_ADVANCED(TBB_LIBRARY_MALLOC)
|
||||
|
||||
IF (WIN32)
|
||||
INSTALL(PROGRAMS ${TBB_BINDIR}/tbb.dll ${TBB_BINDIR}/tbbmalloc.dll DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT examples)
|
||||
INSTALL(PROGRAMS ${TBB_BINDIR}/tbb.dll ${TBB_BINDIR}/tbbmalloc.dll DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT lib)
|
||||
INSTALL(PROGRAMS ${TBB_LIBDIR}/tbb.lib ${TBB_LIBDIR}/tbbmalloc.lib DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT lib)
|
||||
ELSEIF (EMBREE_ZIP_MODE)
|
||||
IF (APPLE)
|
||||
INSTALL(PROGRAMS ${EMBREE_TBB_ROOT}/lib/libtbb.dylib ${EMBREE_TBB_ROOT}/lib/libtbbmalloc.dylib DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT lib)
|
||||
|
||||
@@ -23,7 +23,8 @@ string(REPLACE "\n" ";" output ${output})
|
||||
|
||||
foreach (line ${output})
|
||||
if ("${line}" MATCHES "O .bss")
|
||||
if (NOT "${line}" MATCHES "std::__ioinit")
|
||||
if (NOT "${line}" MATCHES "std::__ioinit" AND # this is caused by iostream initialization and is likely also ok
|
||||
NOT "${line}" MATCHES "\\(\\)::") # this matches a static inside a function which is fine
|
||||
message(WARNING "\nProblematic global variable in non-SSE code:\n" ${line})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
+85
-13
@@ -26,13 +26,48 @@ SET(FLAGS_AVX512SKX "-march=skx")
|
||||
|
||||
IF (WIN32)
|
||||
|
||||
SET(COMMON_CXX_FLAGS "/EHsc /GR -Xclang -fcxx-exceptions")
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${COMMON_CXX_FLAGS}")
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${COMMON_CXX_FLAGS} /Ox /Oi /Gy -fno-vectorize")
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${COMMON_CXX_FLAGS} /Ox /Oi /Gy -fno-vectorize")
|
||||
SET(COMMON_CXX_FLAGS "")
|
||||
SET(COMMON_CXX_FLAGS "${COMMON_CXX_FLAGS} /EHsc") # catch C++ exceptions only and extern "C" functions never throw a C++ exception
|
||||
# SET(COMMON_CXX_FLAGS "${COMMON_CXX_FLAGS} /MP") # compile source files in parallel
|
||||
SET(COMMON_CXX_FLAGS "${COMMON_CXX_FLAGS} /GR") # enable runtime type information (on by default)
|
||||
SET(COMMON_CXX_FLAGS "${COMMON_CXX_FLAGS} -Xclang -fcxx-exceptions") # enable C++ exceptions in Clang
|
||||
IF (EMBREE_STACK_PROTECTOR)
|
||||
SET(COMMON_CXX_FLAGS "${COMMON_CXX_FLAGS} /GS") # protects against return address overrides
|
||||
ELSE()
|
||||
SET(COMMON_CXX_FLAGS "${COMMON_CXX_FLAGS} /GS-") # do not protect against return address overrides
|
||||
ENDIF()
|
||||
MACRO(DISABLE_STACK_PROTECTOR_FOR_FILE file)
|
||||
IF (EMBREE_STACK_PROTECTOR)
|
||||
SET_SOURCE_FILES_PROPERTIES(${file} PROPERTIES COMPILE_FLAGS "/GS-")
|
||||
ENDIF()
|
||||
ENDMACRO()
|
||||
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${COMMON_CXX_FLAGS}")
|
||||
SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /DEBUG") # generate debug information
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} /DEBUG") # generate debug information
|
||||
|
||||
SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /DEBUG")
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} /DEBUG")
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${COMMON_CXX_FLAGS}")
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Ox") # enable full optimizations
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Oi") # inline intrinsic functions
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Gy") # package individual functions
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fno-vectorize") # disable auto vectorization
|
||||
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${COMMON_CXX_FLAGS}")
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Ox") # enable full optimizations
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Oi") # inline intrinsic functions
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Gy") # package individual functions
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -fno-vectorize") # disable auto vectorization
|
||||
SET(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} /DEBUG") # generate debug information
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO} /DEBUG") # generate debug information
|
||||
|
||||
SET(SECURE_LINKER_FLAGS "")
|
||||
SET(SECURE_LINKER_FLAGS "${SECURE_LINKER_FLAGS} /NXCompat") # compatible with data execution prevention (on by default)
|
||||
SET(SECURE_LINKER_FLAGS "${SECURE_LINKER_FLAGS} /DynamicBase") # random rebase of executable at load time
|
||||
IF (CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
SET(SECURE_LINKER_FLAGS "${SECURE_LINKER_FLAGS} /SafeSEH") # invoke known exception handlers (Win32 only, x64 exception handlers are safe by design)
|
||||
ENDIF()
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${SECURE_LINKER_FLAGS}")
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${SECURE_LINKER_FLAGS}")
|
||||
|
||||
INCLUDE(msvc_post)
|
||||
|
||||
@@ -43,16 +78,53 @@ ELSE()
|
||||
SET(CMAKE_CXX_FLAGS "")
|
||||
ENDIF()
|
||||
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fPIC -std=c++11 -fvisibility-inlines-hidden -fvisibility=hidden -fno-strict-aliasing")
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG "-DDEBUG -DTBB_USE_DEBUG -g -O0")
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG -O3 -fno-vectorize")
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-DDEBUG -DTBB_USE_DEBUG -g -O3 -fno-vectorize")
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") # enables most warnings
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wformat -Wformat-security") # enables string format vulnerability warnings
|
||||
IF (NOT APPLE)
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIE") # enables support for more secure position independent execution
|
||||
ENDIF()
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") # generate position independent code suitable for shared libraries
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") # enables C++11 features
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden") # makes all symbols hidden by default
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden") # makes all inline symbols hidden by default
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-strict-aliasing") # disables strict aliasing rules
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_FORTIFY_SOURCE=2") # perform extra security checks for some standard library calls
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-tree-vectorize") # disable auto vectorizer
|
||||
IF (EMBREE_STACK_PROTECTOR)
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstack-protector") # protects against return address overrides
|
||||
ENDIF()
|
||||
MACRO(DISABLE_STACK_PROTECTOR_FOR_FILE file)
|
||||
IF (EMBREE_STACK_PROTECTOR)
|
||||
SET_SOURCE_FILES_PROPERTIES(${file} PROPERTIES COMPILE_FLAGS "-fno-stack-protector")
|
||||
ENDIF()
|
||||
ENDMACRO()
|
||||
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG "")
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG") # enable assertions
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DTBB_USE_DEBUG") # configure TBB in debug mode
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g") # generate debug information
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0") # disable optimizations
|
||||
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "")
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DNDEBUG") # disable assertions
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3") # enable full optimizations
|
||||
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "")
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DDEBUG") # enable assertions
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DTBB_USE_DEBUG") # configure TBB in debug mode
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -g") # generate debug information
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -O3") # enable full optimizations
|
||||
|
||||
IF (APPLE)
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=10.7 ") # we only use MacOSX 10.7 features
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++" ) # link against C++11 stdlib
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=10.7") # makes sure code runs on older MacOSX versions
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") # link against libc++ which supports C++11 features
|
||||
ELSE(APPLE)
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined")
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined") # issues link error for undefined symbols in shared library
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -z noexecstack") # we do not need an executable stack
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -z relro -z now") # re-arranges data sections to increase security
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -z noexecstack") # we do not need an executable stack
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -z relro -z now") # re-arranges data sections to increase security
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pie") # enables position independent execution for executable
|
||||
ENDIF(APPLE)
|
||||
|
||||
ENDIF()
|
||||
@@ -15,8 +15,8 @@
|
||||
## ======================================================================== ##
|
||||
|
||||
SET(FLAGS_SSE2 "-target-cpu=xeon")
|
||||
SET(FLAGS_SSE42 "ERROR_ISA_NOT_SUPPORTED")
|
||||
SET(FLAGS_SSE42 "-target-cpu=interlagos")
|
||||
SET(FLAGS_AVX "-target-cpu=sandybridge")
|
||||
SET(FLAGS_AVX2 "-target-cpu=haswell")
|
||||
SET(FLAGS_AVX512KNL "-target-cpu=mic-knl")
|
||||
SET(FLAGS_AVX512SKX "ERROR_ISA_NOT_SUPPORTED")
|
||||
SET(FLAGS_AVX512SKX "-target-cpu=x86-skylake")
|
||||
@@ -15,6 +15,7 @@
|
||||
## ======================================================================== ##
|
||||
|
||||
SET(EMBREE_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/@EMBREE_RELATIV_ROOT_DIR@)
|
||||
GET_FILENAME_COMPONENT(EMBREE_ROOT_DIR "${EMBREE_ROOT_DIR}" ABSOLUTE)
|
||||
|
||||
SET(EMBREE_INCLUDE_DIRS ${EMBREE_ROOT_DIR}/@CMAKE_INSTALL_INCLUDEDIR@)
|
||||
SET(EMBREE_LIBRARY ${EMBREE_ROOT_DIR}/@CMAKE_INSTALL_LIBDIR@/@EMBREE_LIBRARY_NAME@)
|
||||
|
||||
+44
-8
@@ -26,16 +26,52 @@ IF (EMBREE_IGNORE_CMAKE_CXX_FLAGS)
|
||||
SET(CMAKE_CXX_FLAGS "")
|
||||
ENDIF()
|
||||
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fPIC -std=c++11 -fvisibility-inlines-hidden -fvisibility=hidden -fno-strict-aliasing")
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG "-DDEBUG -DTBB_USE_DEBUG -g -O0")
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG -O3 -fno-tree-vectorize")
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-DDEBUG -DTBB_USE_DEBUG -g -O3 -fno-tree-vectorize")
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "")
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") # enables most warnings
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wformat -Wformat-security") # enables string format vulnerability warnings
|
||||
IF (NOT APPLE)
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIE") # enables support for more secure position independent execution
|
||||
ENDIF()
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") # generate position independent code suitable for shared libraries
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") # enables C++11 features
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden") # makes all symbols hidden by default
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden") # makes all inline symbols hidden by default
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-strict-aliasing") # disables strict aliasing rules
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_FORTIFY_SOURCE=2") # perform extra security checks for some standard library calls
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-tree-vectorize") # disable auto vectorizer
|
||||
IF (EMBREE_STACK_PROTECTOR)
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstack-protector") # protects against return address overrides
|
||||
ENDIF()
|
||||
MACRO(DISABLE_STACK_PROTECTOR_FOR_FILE file)
|
||||
IF (EMBREE_STACK_PROTECTOR)
|
||||
SET_SOURCE_FILES_PROPERTIES(${file} PROPERTIES COMPILE_FLAGS "-fno-stack-protector")
|
||||
ENDIF()
|
||||
ENDMACRO()
|
||||
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG "")
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG") # enable assertions
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DTBB_USE_DEBUG") # configure TBB in debug mode
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g") # generate debug information
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0") # disable optimizations
|
||||
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "")
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DNDEBUG") # disable assertions
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3") # enable full optimizations
|
||||
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "")
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DDEBUG") # enable assertions
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DTBB_USE_DEBUG") # configure TBB in debug mode
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -g") # generate debug information
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -O3") # enable full optimizations
|
||||
|
||||
IF (APPLE)
|
||||
SET (CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS_INIT} -dynamiclib)
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=10.7 -stdlib=libc++")
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=10.7") # makes sure code runs on older MacOSX versions
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") # link against libc++ which supports C++11 features
|
||||
ELSE(APPLE)
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined")
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined") # issues link error for undefined symbols in shared library
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -z noexecstack") # we do not need an executable stack
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -z relro -z now") # re-arranges data sections to increase security
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -z noexecstack") # we do not need an executable stack
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -z relro -z now") # re-arranges data sections to increase security
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pie") # enables position independent execution for executable
|
||||
ENDIF(APPLE)
|
||||
|
||||
+105
-22
@@ -23,27 +23,65 @@ IF (WIN32)
|
||||
SET(FLAGS_AVX512KNL "/QxMIC-AVX512")
|
||||
SET(FLAGS_AVX512SKX "/QxCORE-AVX512")
|
||||
|
||||
SET(COMMON_CXX_FLAGS "/EHsc /MP /GR /GS-")
|
||||
SET(COMMON_CXX_FLAGS "")
|
||||
SET(COMMON_CXX_FLAGS "${COMMON_CXX_FLAGS} /EHsc") # catch C++ exceptions only and extern "C" functions never throw a C++ exception
|
||||
SET(COMMON_CXX_FLAGS "${COMMON_CXX_FLAGS} /MP") # compile source files in parallel
|
||||
SET(COMMON_CXX_FLAGS "${COMMON_CXX_FLAGS} /GR") # enable runtime type information (on by default)
|
||||
SET(COMMON_CXX_FLAGS "${COMMON_CXX_FLAGS} /Qvec-") # disable auto vectorizer
|
||||
IF (EMBREE_STACK_PROTECTOR)
|
||||
SET(COMMON_CXX_FLAGS "${COMMON_CXX_FLAGS} /GS") # protects against return address overrides
|
||||
ELSE()
|
||||
SET(COMMON_CXX_FLAGS "${COMMON_CXX_FLAGS} /GS-") # do not protect against return address overrides
|
||||
ENDIF()
|
||||
MACRO(DISABLE_STACK_PROTECTOR_FOR_FILE file)
|
||||
IF (EMBREE_STACK_PROTECTOR)
|
||||
SET_SOURCE_FILES_PROPERTIES(${file} PROPERTIES COMPILE_FLAGS "/GS-")
|
||||
ENDIF()
|
||||
ENDMACRO()
|
||||
|
||||
SET(COMMON_CXX_FLAGS "${COMMON_CXX_FLAGS} /Qdiag-disable:11074 ") # remark #11074: Inlining inhibited by limit max-size
|
||||
SET(COMMON_CXX_FLAGS "${COMMON_CXX_FLAGS} /Qdiag-disable:11075 ") # remark #11075: To get full report use -Qopt-report:4 -Qopt-report-phase ipo
|
||||
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${COMMON_CXX_FLAGS}")
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${COMMON_CXX_FLAGS} /Ox /Oi /Gy /Qinline-max-total-size- /Qinline-factor=200 /Qvec- ")
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${COMMON_CXX_FLAGS} /Ox /Oi /Gy /Qinline-max-total-size- /Qinline-factor=200 /Qvec- ")
|
||||
|
||||
SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /DEBUG")
|
||||
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${COMMON_CXX_FLAGS}")
|
||||
SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /DEBUG") # generate debug information
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} /DEBUG") # generate debug information
|
||||
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${COMMON_CXX_FLAGS}")
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Ox") # enable full optimizations
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Oi") # inline intrinsic functions
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Gy") # package individual functions
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Qinline-max-total-size-") # no size limit when performing inlining
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Qinline-factor=150") # increase default inline factors by 2x
|
||||
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${COMMON_CXX_FLAGS}")
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Ox") # enable full optimizations
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Oi") # inline intrinsic functions
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Gy") # package individual functions
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Qinline-max-total-size-") # no size limit when performing inlining
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Qinline-factor=150") # increase default inline factors by 2x
|
||||
SET(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} /DEBUG") # generate debug information
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO} /DEBUG") # generate debug information
|
||||
|
||||
SET(SECURE_LINKER_FLAGS "")
|
||||
SET(SECURE_LINKER_FLAGS "${SECURE_LINKER_FLAGS} /NXCompat") # compatible with data execution prevention (on by default)
|
||||
SET(SECURE_LINKER_FLAGS "${SECURE_LINKER_FLAGS} /DynamicBase") # random rebase of executable at load time
|
||||
IF (CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
SET(SECURE_LINKER_FLAGS "${SECURE_LINKER_FLAGS} /SafeSEH") # invoke known exception handlers (Win32 only, x64 exception handlers are safe by design)
|
||||
ENDIF()
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${SECURE_LINKER_FLAGS}")
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${SECURE_LINKER_FLAGS}")
|
||||
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /IGNORE:4217") # locally defined symbol XXX imported in function YYY (happens as the ISPC API layer uses exported library functions)
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /IGNORE:4049") # warning LNK4049: locally defined symbol _rtcOccluded1M imported
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} /DEBUG")
|
||||
|
||||
INCLUDE(msvc_post)
|
||||
|
||||
ELSE()
|
||||
|
||||
IF (APPLE)
|
||||
SET(FLAGS_SSE2 "-xssse3") # in MacOSX ICC does not support SSE2
|
||||
SET(FLAGS_SSE2 "-xssse3") # on MacOSX ICC does not support SSE2
|
||||
ELSE()
|
||||
SET(FLAGS_SSE2 "-xsse2")
|
||||
SET(FLAGS_SSE2 "-xsse2")
|
||||
ENDIF()
|
||||
SET(FLAGS_SSE42 "-xsse4.2")
|
||||
SET(FLAGS_AVX "-xAVX")
|
||||
@@ -55,26 +93,71 @@ ELSE()
|
||||
IF (EMBREE_IGNORE_CMAKE_CXX_FLAGS)
|
||||
SET(CMAKE_CXX_FLAGS "")
|
||||
ENDIF()
|
||||
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") # enables most warnings
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wformat -Wformat-security") # enables string format vulnerability warnings
|
||||
IF (NOT APPLE)
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIE") # enables support for more secure position independent execution
|
||||
ENDIF()
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") # generate position independent code suitable for shared libraries
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") # enables C++11 features
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden") # makes all symbols hidden by default
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden") # makes all inline symbols hidden by default
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -no-ansi-alias") # disables strict aliasing rules
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_FORTIFY_SOURCE=2") # perform extra security checks for some standard library calls
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -no-vec") # disable auto vectorizer
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fasm-blocks") # enable assembly blocks
|
||||
IF (EMBREE_STACK_PROTECTOR)
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstack-protector") # protects against return address overrides
|
||||
ENDIF()
|
||||
MACRO(DISABLE_STACK_PROTECTOR_FOR_FILE file)
|
||||
IF (EMBREE_STACK_PROTECTOR)
|
||||
SET_SOURCE_FILES_PROPERTIES(${file} PROPERTIES COMPILE_FLAGS "-fno-stack-protector")
|
||||
ENDIF()
|
||||
ENDMACRO()
|
||||
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fPIC -std=c++11 -fvisibility-inlines-hidden -fvisibility=hidden -no-ansi-alias -fasm-blocks")
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG "-DDEBUG -DTBB_USE_DEBUG -g -O0")
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG -O3 -restrict -no-inline-max-total-size -inline-factor=200 -no-inline-max-per-compile -no-vec")
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-DDEBUG -DTBB_USE_DEBUG -g -O3 -restrict -no-inline-max-total-size -inline-factor=200 -no-inline-max-per-compile -no-vec")
|
||||
|
||||
# Don't change linker flags used by Cray wrappers
|
||||
IF(NOT CMAKE_CXX_COMPILER_WRAPPER STREQUAL "CrayPrgEnv")
|
||||
# enable -static-intel and -no-intel-extensions to void to export ICC specific symbols from Embree
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-intel -no-intel-extensions")
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-intel") # links intel runtime statically
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -no-intel-extensions") # disables some intel extensions which cause symbols to be exported
|
||||
ENDIF()
|
||||
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG "")
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG") # enables assertions
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DTBB_USE_DEBUG") # configures TBB in debug mode
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g") # generate debug information
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0") # disable all optimizations
|
||||
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "")
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DNDEBUG") # disable assertions
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3") # full optimizations
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -restrict") # enable restrict keyword
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -no-inline-max-total-size") # no size limit when performing inlining
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -no-inline-max-per-compile") # no maximal number of inlinings per compilation unit
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -inline-factor=150") # increase default inline factors limits by 2x
|
||||
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "")
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DDEBUG") # enables assertions
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DTBB_USE_DEBUG") # configures TBB in debug mode
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -g") # generate debug information
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -O3") # full optimizations
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -restrict") # enable restrict keyword
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -no-inline-max-total-size") # no size limit when performing inlining
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -no-inline-max-per-compile") # no maximal number of inlinings per compilation unit
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -inline-factor=150") # increase default inline factors by 2x
|
||||
|
||||
#SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -g -debug inline-debug-info")
|
||||
#SET(CMAKE_EXE_LINKER_FLAGS "-g")
|
||||
|
||||
|
||||
IF (APPLE)
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=10.7 ") # we only use MacOSX 10.7 features
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++" ) # link against C++11 stdlib
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=10.7") # makes sure code runs on older MacOSX versions
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") # link against libc++ which supports C++11 features
|
||||
ELSE(APPLE)
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined")
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined") # issues link error for undefined symbols in shared library
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -z noexecstack") # we do not need an executable stack
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -z relro -z now") # re-arranges data sections to increase security
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -z noexecstack") # we do not need an executable stack
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -z relro -z now") # re-arranges data sections to increase security
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pie") # enables position independent execution for executable
|
||||
ENDIF(APPLE)
|
||||
|
||||
ENDIF()
|
||||
+39
-6
@@ -19,16 +19,49 @@ SET(FLAGS_SSE42 "${FLAGS_SSE2} /D__SSE3__ /D__SSSE3__ /D__SSE4_1__ /D__SSE4_2__"
|
||||
SET(FLAGS_AVX "${FLAGS_SSE42} /arch:AVX")
|
||||
SET(FLAGS_AVX2 "${FLAGS_SSE42} /arch:AVX2")
|
||||
|
||||
SET(COMMON_CXX_FLAGS "/EHsc /MP /GR /GS- ${FLAGS_SSE2}")
|
||||
SET(COMMON_CXX_FLAGS "")
|
||||
SET(COMMON_CXX_FLAGS "${COMMON_CXX_FLAGS} /EHsc") # catch C++ exceptions only and extern "C" functions never throw a C++ exception
|
||||
SET(COMMON_CXX_FLAGS "${COMMON_CXX_FLAGS} /MP") # compile source files in parallel
|
||||
SET(COMMON_CXX_FLAGS "${COMMON_CXX_FLAGS} /GR") # enable runtime type information (on by default)
|
||||
IF (EMBREE_STACK_PROTECTOR)
|
||||
SET(COMMON_CXX_FLAGS "${COMMON_CXX_FLAGS} /GS") # protects against return address overrides
|
||||
ELSE()
|
||||
SET(COMMON_CXX_FLAGS "${COMMON_CXX_FLAGS} /GS-") # do not protect against return address overrides
|
||||
ENDIF()
|
||||
MACRO(DISABLE_STACK_PROTECTOR_FOR_FILE file)
|
||||
IF (EMBREE_STACK_PROTECTOR)
|
||||
SET_SOURCE_FILES_PROPERTIES(${file} PROPERTIES COMPILE_FLAGS "/GS-")
|
||||
ENDIF()
|
||||
ENDMACRO()
|
||||
SET(COMMON_CXX_FLAGS "${COMMON_CXX_FLAGS} ${FLAGS_SSE2}")
|
||||
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${COMMON_CXX_FLAGS}")
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${COMMON_CXX_FLAGS} /Ox /Oi /Gy")
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${COMMON_CXX_FLAGS} /Ox /Oi /Gy")
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${COMMON_CXX_FLAGS}")
|
||||
SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /DEBUG") # generate debug information
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} /DEBUG") # generate debug information
|
||||
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${COMMON_CXX_FLAGS}")
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Ox") # enable full optimizations
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Oi") # inline intrinsic functions
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Gy") # package individual functions
|
||||
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${COMMON_CXX_FLAGS}")
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Ox") # enable full optimizations
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Oi") # inline intrinsic functions
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Gy") # package individual functions
|
||||
SET(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} /DEBUG") # generate debug information
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO} /DEBUG") # generate debug information
|
||||
|
||||
SET(SECURE_LINKER_FLAGS "")
|
||||
SET(SECURE_LINKER_FLAGS "${SECURE_LINKER_FLAGS} /NXCompat") # compatible with data execution prevention (on by default)
|
||||
SET(SECURE_LINKER_FLAGS "${SECURE_LINKER_FLAGS} /DynamicBase") # random rebase of executable at load time
|
||||
IF (CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
SET(SECURE_LINKER_FLAGS "${SECURE_LINKER_FLAGS} /SafeSEH") # invoke known exception handlers (Win32 only, x64 exception handlers are safe by design)
|
||||
ENDIF()
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${SECURE_LINKER_FLAGS}")
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${SECURE_LINKER_FLAGS}")
|
||||
|
||||
SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /DEBUG")
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /IGNORE:4217") # locally defined symbol XXX imported in function YYY (happens as the ISPC API layer uses exported library functions)
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /IGNORE:4049") # warning LNK4049: locally defined symbol _rtcOccluded1M imported
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} /DEBUG")
|
||||
|
||||
INCLUDE(msvc_post)
|
||||
|
||||
+20
-32
@@ -39,12 +39,7 @@ ENDIF()
|
||||
##############################################################
|
||||
# Install Headers
|
||||
##############################################################
|
||||
|
||||
INSTALL(DIRECTORY include/embree2 DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} COMPONENT devel)
|
||||
CONFIGURE_FILE(include/embree2/rtcore.h rtcore.h @ONLY)
|
||||
CONFIGURE_FILE(include/embree2/rtcore.isph rtcore.isph @ONLY)
|
||||
INSTALL(FILES ${PROJECT_BINARY_DIR}/rtcore.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/embree2 COMPONENT devel)
|
||||
INSTALL(FILES ${PROJECT_BINARY_DIR}/rtcore.isph DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/embree2 COMPONENT devel)
|
||||
|
||||
##############################################################
|
||||
# Install Models
|
||||
@@ -99,11 +94,15 @@ IF (APPLE AND NOT EMBREE_ZIP_MODE)
|
||||
INSTALL(PROGRAMS "${PROJECT_BINARY_DIR}/uninstall.command" DESTINATION ${CMAKE_INSTALL_BINDIR}/.. COMPONENT lib)
|
||||
ENDIF()
|
||||
|
||||
# why does this have to be so complicated...
|
||||
IF (WIN32)
|
||||
SET(EMBREE_LIBRARY_NAME embree.lib)
|
||||
SET(EMBREE_LIBRARY_NAME ${CMAKE_IMPORT_LIBRARY_PREFIX}embree${CMAKE_IMPORT_LIBRARY_SUFFIX})
|
||||
ELSEIF (APPLE)
|
||||
SET(EMBREE_LIBRARY_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}embree.${EMBREE_CONFIG_VERSION}${CMAKE_SHARED_LIBRARY_SUFFIX})
|
||||
ELSE()
|
||||
SET(EMBREE_LIBRARY_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}embree${CMAKE_SHARED_LIBRARY_SUFFIX})
|
||||
SET(EMBREE_LIBRARY_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}embree${CMAKE_SHARED_LIBRARY_SUFFIX}.${EMBREE_CONFIG_VERSION})
|
||||
ENDIF()
|
||||
|
||||
IF (WIN32 OR EMBREE_ZIP_MODE)
|
||||
# for local "installs" and on Windows we want the cmake config files placed
|
||||
# in the install root, such that users can point the CMake variable
|
||||
@@ -126,11 +125,12 @@ INSTALL(FILES "${PROJECT_BINARY_DIR}/embree-config-version.cmake" DESTINATION ${
|
||||
# CPack specific stuff
|
||||
##############################################################
|
||||
|
||||
SET(CPACK_PACKAGE_NAME "Embree")
|
||||
SET(CPACK_PACKAGE_NAME "Embree Ray Tracing Kernels")
|
||||
SET(CPACK_PACKAGE_FILE_NAME "embree-${EMBREE_VERSION}")
|
||||
#SET(CPACK_PACKAGE_ICON ${PROJECT_SOURCE_DIR}/embree-doc/images/icon.png)
|
||||
#SET(CPACK_PACKAGE_RELOCATABLE TRUE)
|
||||
SET(CPACK_STRIP_FILES TRUE)
|
||||
SET(CPACK_STRIP_FILES TRUE) # do not disable, stripping symbols is important for security reasons
|
||||
SET(CMAKE_STRIP "${PROJECT_SOURCE_DIR}/scripts/strip.sh") # needs this to properly strip under MacOSX
|
||||
|
||||
SET(CPACK_PACKAGE_VERSION_MAJOR ${EMBREE_VERSION_MAJOR})
|
||||
SET(CPACK_PACKAGE_VERSION_MINOR ${EMBREE_VERSION_MINOR})
|
||||
@@ -162,33 +162,19 @@ IF(WIN32)
|
||||
|
||||
IF (CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
SET(ARCH x64)
|
||||
SET(PROGRAMFILES "\$PROGRAMFILES64")
|
||||
SET(CPACK_PACKAGE_NAME "${CPACK_PACKAGE_NAME} x64")
|
||||
ELSE()
|
||||
SET(ARCH win32)
|
||||
SET(PROGRAMFILES "\$PROGRAMFILES")
|
||||
SET(CPACK_PACKAGE_NAME "${CPACK_PACKAGE_NAME} Win32")
|
||||
ENDIF()
|
||||
|
||||
# NSIS specific settings
|
||||
IF (NOT EMBREE_ZIP_MODE)
|
||||
SET(CPACK_GENERATOR NSIS)
|
||||
SET(CPACK_GENERATOR WIX)
|
||||
SET(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}.${ARCH}")
|
||||
SET(CPACK_COMPONENTS_ALL lib devel examples)
|
||||
SET(CPACK_NSIS_INSTALL_ROOT "${PROGRAMFILES}\\\\Intel")
|
||||
SET(CPACK_PACKAGE_INSTALL_DIRECTORY "Embree v${EMBREE_VERSION} ${ARCH}")
|
||||
SET(CPACK_NSIS_DISPLAY_NAME "Embree v${EMBREE_VERSION} ${ARCH}")
|
||||
SET(CPACK_NSIS_PACKAGE_NAME "Embree v${EMBREE_VERSION} ${ARCH}")
|
||||
SET(CPACK_NSIS_URL_INFO_ABOUT http://embree.github.io/)
|
||||
#SET(CPACK_NSIS_HELP_LINK http://embree.github.io/downloads.html#windows)
|
||||
SET(CPACK_NSIS_MUI_ICON ${PROJECT_SOURCE_DIR}/scripts/install_windows/icon32.ico)
|
||||
SET(CPACK_NSIS_CONTACT ${CPACK_PACKAGE_CONTACT})
|
||||
#SET(CPACK_NSIS_EXTRA_PREINSTALL_COMMANDS ${CPACK_NSIS_EXTRA_PREINSTALL_COMMANDS} "\n CreateDirectory \\\"$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\"")
|
||||
#SET(CPACK_NSIS_EXTRA_PREINSTALL_COMMANDS ${CPACK_NSIS_EXTRA_PREINSTALL_COMMANDS} "\n CreateDirectory \\\"$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\documentation\\\"")
|
||||
#SET(CPACK_NSIS_EXTRA_PREINSTALL_COMMANDS ${CPACK_NSIS_EXTRA_PREINSTALL_COMMANDS} "\n CreateDirectory \\\"$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\tutorials\\\" \n")
|
||||
#SET(CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS ${CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS} "\n ${UNINSTALL_LIST}\n RMDir \\\"$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\documentation\\\"")
|
||||
#SET(CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS ${CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS} "\n ${UNINSTALL_LIST}\n RMDir \\\"$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\tutorials\\\"")
|
||||
#SET(CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS ${CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS} "\n ${UNINSTALL_LIST}\n RMDir \\\"$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\"\n")
|
||||
SET(CPACK_PACKAGE_INSTALL_DIRECTORY "Intel\\\\Embree v${EMBREE_VERSION} ${ARCH}")
|
||||
SET(CPACK_WIX_PRODUCT_GUID "331BD5A9-DAD6-486B-A435-18AAB80${EMBREE_VERSION_NUMBER}")
|
||||
SET(CPACK_WIX_UPGRADE_GUID "331BD5A9-DAD6-486B-A435-18AAB80${EMBREE_VERSION_MAJOR}0000") # upgrade as long as major version is the same
|
||||
SET(CPACK_WIX_CMAKE_PACKAGE_REGISTRY TRUE)
|
||||
IF (EMBREE_TESTING_PACKAGE)
|
||||
ADD_TEST(NAME "BuildPackage" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMAND ${PROJECT_SOURCE_DIR}/scripts/package_win.bat ${CPACK_PACKAGE_FILE_NAME}.exe ${CMAKE_BUILD_TYPE})
|
||||
ENDIF()
|
||||
@@ -231,17 +217,19 @@ ELSEIF(APPLE)
|
||||
# Linux specific settings
|
||||
ELSE()
|
||||
|
||||
|
||||
IF (NOT EMBREE_ZIP_MODE)
|
||||
|
||||
SET(CPACK_GENERATOR RPM)
|
||||
SET(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}-${CPACK_RPM_PACKAGE_RELEASE}.x86_64")
|
||||
SET(CPACK_COMPONENTS_ALL devel lib examples)
|
||||
SET(CPACK_RPM_COMPONENT_INSTALL ON)
|
||||
SET(CPACK_RPM_FILE_NAME RPM-DEFAULT)
|
||||
SET(CPACK_RPM_devel_PACKAGE_ARCHITECTURE noarch)
|
||||
SET(CPACK_RPM_PACKAGE_LICENSE "ASL 2.0") # Apache Software License, Version 2.0
|
||||
SET(CPACK_RPM_PACKAGE_GROUP "Development/Libraries")
|
||||
#SET(CPACK_RPM_CHANGELOG_FILE "") # ChangeLog of the RPM; also CHANGELOG.md is not in the required format
|
||||
SET(CPACK_RPM_PACKAGE_ARCHITECTURE x86_64)
|
||||
SET(CPACK_RPM_CHANGELOG_FILE ${CMAKE_BINARY_DIR}/rpm_changelog.txt) # ChangeLog of the RPM
|
||||
STRING(TIMESTAMP CHANGELOG_DATE "%a %b %d %Y")
|
||||
SET(RPM_CHANGELOG "* ${CHANGELOG_DATE} Johannes Günther <johannes.guenther@intel.com> - ${EMBREE_VERSION}-${CPACK_RPM_PACKAGE_RELEASE}\n- First package")
|
||||
FILE(WRITE ${CPACK_RPM_CHANGELOG_FILE} ${RPM_CHANGELOG})
|
||||
SET(CPACK_RPM_PACKAGE_URL http://embree.github.io/)
|
||||
SET(CPACK_RPM_DEFAULT_DIR_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) # otherwise cmake directory has wrong 775 permissions
|
||||
|
||||
|
||||
@@ -18,6 +18,5 @@ ADD_LIBRARY(lexers STATIC
|
||||
stringstream.cpp
|
||||
tokenstream.cpp
|
||||
)
|
||||
|
||||
TARGET_LINK_LIBRARIES(lexers sys)
|
||||
TARGET_LINK_LIBRARIES(lexers sys math)
|
||||
SET_PROPERTY(TARGET lexers PROPERTY FOLDER common)
|
||||
+20
-17
@@ -32,21 +32,21 @@ namespace embree
|
||||
class ParseLocation
|
||||
{
|
||||
public:
|
||||
ParseLocation () : fileName(nullptr), lineNumber(-1), colNumber(-1), charNumber(-1) {}
|
||||
ParseLocation (const char* fileName, ssize_t lineNumber, ssize_t colNumber, ssize_t charNumber)
|
||||
ParseLocation () : lineNumber(-1), colNumber(-1), charNumber(-1) {}
|
||||
ParseLocation (std::shared_ptr<std::string> fileName, ssize_t lineNumber, ssize_t colNumber, ssize_t charNumber)
|
||||
: fileName(fileName), lineNumber(lineNumber), colNumber(colNumber), charNumber(charNumber) {}
|
||||
|
||||
std::string str() const
|
||||
{
|
||||
std::string str = "unknown";
|
||||
if (fileName) str = fileName;
|
||||
if (fileName) str = *fileName;
|
||||
if (lineNumber >= 0) str += " line " + toString(lineNumber);
|
||||
if (lineNumber >= 0 && colNumber >= 0) str += " character " + toString(colNumber);
|
||||
return str;
|
||||
}
|
||||
|
||||
private:
|
||||
const char* fileName; /// name of the file (or stream) the token is from
|
||||
std::shared_ptr<std::string> fileName; /// name of the file (or stream) the token is from
|
||||
ssize_t lineNumber; /// the line number the token is from
|
||||
ssize_t colNumber; /// the character number in the current line
|
||||
ssize_t charNumber; /// the character in the file
|
||||
@@ -67,7 +67,7 @@ namespace embree
|
||||
}
|
||||
__forceinline void push_back(const std::pair<T,ParseLocation>& v) {
|
||||
if (past+future == BUF_SIZE) pop_front();
|
||||
int end = (start+past+future++)%BUF_SIZE;
|
||||
size_t end = (start+past+future++)%BUF_SIZE;
|
||||
buffer[end] = v;
|
||||
}
|
||||
__forceinline void pop_front() {
|
||||
@@ -113,10 +113,10 @@ namespace embree
|
||||
{
|
||||
public:
|
||||
StdStream (std::istream& cin, const std::string& name = "std::stream")
|
||||
: cin(cin), lineNumber(1), colNumber(0), charNumber(0), name(name) {}
|
||||
: cin(cin), lineNumber(1), colNumber(0), charNumber(0), name(std::shared_ptr<std::string>(new std::string(name))) {}
|
||||
~StdStream() {}
|
||||
ParseLocation location() {
|
||||
return ParseLocation(name.c_str(),lineNumber,colNumber,charNumber);
|
||||
return ParseLocation(name,lineNumber,colNumber,charNumber);
|
||||
}
|
||||
int next() {
|
||||
int c = cin.get();
|
||||
@@ -129,7 +129,7 @@ namespace embree
|
||||
ssize_t lineNumber; /// the line number the token is from
|
||||
ssize_t colNumber; /// the character number in the current line
|
||||
ssize_t charNumber; /// the character in the file
|
||||
std::string name; /// name of buffer
|
||||
std::shared_ptr<std::string> name; /// name of buffer
|
||||
};
|
||||
|
||||
/*! creates a stream from a file */
|
||||
@@ -138,10 +138,10 @@ namespace embree
|
||||
public:
|
||||
|
||||
FileStream (FILE* file, const std::string& name = "file")
|
||||
: file(file), lineNumber(1), colNumber(0), charNumber(0), name(name) {}
|
||||
: file(file), lineNumber(1), colNumber(0), charNumber(0), name(std::shared_ptr<std::string>(new std::string(name))) {}
|
||||
|
||||
FileStream (const FileName& fileName)
|
||||
: lineNumber(1), colNumber(0), charNumber(0), name(fileName.str())
|
||||
: lineNumber(1), colNumber(0), charNumber(0), name(std::shared_ptr<std::string>(new std::string(fileName.str())))
|
||||
{
|
||||
file = fopen(fileName.c_str(),"r");
|
||||
if (file == nullptr) THROW_RUNTIME_ERROR("cannot open file " + fileName.str());
|
||||
@@ -150,7 +150,7 @@ namespace embree
|
||||
|
||||
public:
|
||||
ParseLocation location() {
|
||||
return ParseLocation(name.c_str(),lineNumber,colNumber,charNumber);
|
||||
return ParseLocation(name,lineNumber,colNumber,charNumber);
|
||||
}
|
||||
|
||||
int next() {
|
||||
@@ -165,7 +165,7 @@ namespace embree
|
||||
ssize_t lineNumber; /// the line number the token is from
|
||||
ssize_t colNumber; /// the character number in the current line
|
||||
ssize_t charNumber; /// the character in the file
|
||||
std::string name; /// name of buffer
|
||||
std::shared_ptr<std::string> name; /// name of buffer
|
||||
};
|
||||
|
||||
/*! creates a stream from a string */
|
||||
@@ -178,7 +178,7 @@ namespace embree
|
||||
|
||||
public:
|
||||
ParseLocation location() {
|
||||
return ParseLocation(nullptr,lineNumber,colNumber,charNumber);
|
||||
return ParseLocation(std::shared_ptr<std::string>(),lineNumber,colNumber,charNumber);
|
||||
}
|
||||
|
||||
int next() {
|
||||
@@ -201,15 +201,18 @@ namespace embree
|
||||
{
|
||||
public:
|
||||
CommandLineStream (int argc, char** argv, const std::string& name = "command line")
|
||||
: i(0), j(0), charNumber(0), name(name)
|
||||
: i(0), j(0), charNumber(0), name(std::shared_ptr<std::string>(new std::string(name)))
|
||||
{
|
||||
if (argc > 0) charNumber = strlen(argv[0])+1;
|
||||
if (argc > 0) {
|
||||
for (size_t i=0; argv[0][i] && i<1024; i++) charNumber++;
|
||||
charNumber++;
|
||||
}
|
||||
for (ssize_t k=1; k<argc; k++) args.push_back(argv[k]);
|
||||
}
|
||||
~CommandLineStream() {}
|
||||
public:
|
||||
ParseLocation location() {
|
||||
return ParseLocation(name.c_str(),0,charNumber,charNumber);
|
||||
return ParseLocation(name,0,charNumber,charNumber);
|
||||
}
|
||||
int next() {
|
||||
if (i == args.size()) return EOF;
|
||||
@@ -221,6 +224,6 @@ namespace embree
|
||||
size_t i,j;
|
||||
std::vector<std::string> args;
|
||||
ssize_t charNumber; /// the character in the file
|
||||
std::string name; /// name of buffer
|
||||
std::shared_ptr<std::string> name; /// name of buffer
|
||||
};
|
||||
}
|
||||
@@ -30,7 +30,7 @@ namespace embree
|
||||
ParseLocation location() { return cin->loc(); }
|
||||
std::string next();
|
||||
private:
|
||||
__forceinline bool isSeparator(int c) const { return isSepMap[c]; }
|
||||
__forceinline bool isSeparator(int c) const { return c<256 && isSepMap[c]; }
|
||||
private:
|
||||
Ref<Stream<int> > cin; /*! source character stream */
|
||||
bool isSepMap[256]; /*! map for fast classification of separators */
|
||||
|
||||
@@ -160,13 +160,13 @@ namespace embree
|
||||
std::vector<std::string> symbols;
|
||||
|
||||
/*! checks if a character is a separator */
|
||||
__forceinline bool isSeparator(int c) const { return isSepMap[c]; }
|
||||
__forceinline bool isSeparator(int c) const { return c<256 && isSepMap[c]; }
|
||||
|
||||
/*! checks if a character is a number */
|
||||
__forceinline bool isDigit(int c) const { return c >= '0' && c <= '9';}
|
||||
|
||||
/*! checks if a character is legal for an identifier */
|
||||
__forceinline bool isAlpha(int c) const { return isAlphaMap[c]; }
|
||||
__forceinline bool isAlpha(int c) const { return c<256 && isAlphaMap[c]; }
|
||||
__forceinline bool isAlphaNum(int c) const { return isAlpha(c) || isDigit(c); }
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
## ======================================================================== ##
|
||||
## Copyright 2009-2017 Intel Corporation ##
|
||||
## ##
|
||||
## Licensed under the Apache License, Version 2.0 (the "License"); ##
|
||||
## you may not use this file except in compliance with the License. ##
|
||||
## You may obtain a copy of the License at ##
|
||||
## ##
|
||||
## http://www.apache.org/licenses/LICENSE-2.0 ##
|
||||
## ##
|
||||
## Unless required by applicable law or agreed to in writing, software ##
|
||||
## distributed under the License is distributed on an "AS IS" BASIS, ##
|
||||
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ##
|
||||
## See the License for the specific language governing permissions and ##
|
||||
## limitations under the License. ##
|
||||
## ======================================================================== ##
|
||||
|
||||
ADD_LIBRARY(math STATIC constants.cpp)
|
||||
SET_PROPERTY(TARGET math PROPERTY FOLDER common)
|
||||
@@ -107,9 +107,9 @@ namespace embree
|
||||
template<typename L> __forceinline AffineSpaceT<L>& operator /=( AffineSpaceT<L>& a, const AffineSpaceT<L>& b ) { return a = a / b; }
|
||||
template<typename L> __forceinline AffineSpaceT<L>& operator /=( AffineSpaceT<L>& a, const ScalarT & b ) { return a = a / b; }
|
||||
|
||||
template<typename L> __forceinline const VectorT xfmPoint (const AffineSpaceT<L>& m, const VectorT& p) { return madd(VectorT(p.x),m.l.vx,madd(VectorT(p.y),m.l.vy,madd(VectorT(p.z),m.l.vz,m.p))); }
|
||||
template<typename L> __forceinline const VectorT xfmVector(const AffineSpaceT<L>& m, const VectorT& v) { return xfmVector(m.l,v); }
|
||||
template<typename L> __forceinline const VectorT xfmNormal(const AffineSpaceT<L>& m, const VectorT& n) { return xfmNormal(m.l,n); }
|
||||
template<typename L> __forceinline VectorT xfmPoint (const AffineSpaceT<L>& m, const VectorT& p) { return madd(VectorT(p.x),m.l.vx,madd(VectorT(p.y),m.l.vy,madd(VectorT(p.z),m.l.vz,m.p))); }
|
||||
template<typename L> __forceinline VectorT xfmVector(const AffineSpaceT<L>& m, const VectorT& v) { return xfmVector(m.l,v); }
|
||||
template<typename L> __forceinline VectorT xfmNormal(const AffineSpaceT<L>& m, const VectorT& n) { return xfmNormal(m.l,n); }
|
||||
|
||||
__forceinline const BBox<Vec3fa> xfmBounds(const AffineSpaceT<LinearSpace3<Vec3fa> >& m, const BBox<Vec3fa>& b)
|
||||
{
|
||||
|
||||
+4
-4
@@ -53,8 +53,8 @@ namespace embree
|
||||
__forceinline Color4 ( const Color4& other ) : m128(other.m128) {}
|
||||
__forceinline Color4& operator=( const Color4& other ) { m128 = other.m128; return *this; }
|
||||
|
||||
__forceinline operator const __m128&( void ) const { return m128; }
|
||||
__forceinline operator __m128&( void ) { return m128; }
|
||||
__forceinline operator const __m128&() const { return m128; }
|
||||
__forceinline operator __m128&() { return m128; }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Set
|
||||
@@ -115,8 +115,8 @@ namespace embree
|
||||
__forceinline Color ( const Color4& other ) : m128(other.m128) {}
|
||||
__forceinline Color& operator=( const Color4& other ) { m128 = other.m128; return *this; }
|
||||
|
||||
__forceinline operator const __m128&( void ) const { return m128; }
|
||||
__forceinline operator __m128&( void ) { return m128; }
|
||||
__forceinline operator const __m128&() const { return m128; }
|
||||
__forceinline operator __m128&() { return m128; }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Set
|
||||
|
||||
@@ -14,24 +14,27 @@
|
||||
// limitations under the License. //
|
||||
// ======================================================================== //
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../common/scene_instance.h"
|
||||
#include "../common/ray.h"
|
||||
#include "constants.h"
|
||||
|
||||
namespace embree
|
||||
{
|
||||
namespace isa
|
||||
{
|
||||
template<int K>
|
||||
struct FastInstanceIntersectorK
|
||||
{
|
||||
static void intersect(vint<K>* valid, const Instance* instance, RayK<K>& ray, size_t item);
|
||||
static void occluded (vint<K>* valid, const Instance* instance, RayK<K>& ray, size_t item);
|
||||
};
|
||||
|
||||
typedef FastInstanceIntersectorK<4> FastInstanceIntersector4;
|
||||
typedef FastInstanceIntersectorK<8> FastInstanceIntersector8;
|
||||
typedef FastInstanceIntersectorK<16> FastInstanceIntersector16;
|
||||
}
|
||||
TrueTy True;
|
||||
FalseTy False;
|
||||
ZeroTy zero;
|
||||
OneTy one;
|
||||
NegInfTy neg_inf;
|
||||
PosInfTy inf;
|
||||
PosInfTy pos_inf;
|
||||
NaNTy nan;
|
||||
UlpTy ulp;
|
||||
PiTy pi;
|
||||
OneOverPiTy one_over_pi;
|
||||
TwoPiTy two_pi;
|
||||
OneOverTwoPiTy one_over_two_pi;
|
||||
FourPiTy four_pi;
|
||||
OneOverFourPiTy one_over_four_pi;
|
||||
StepTy step;
|
||||
ReverseStepTy reverse_step;
|
||||
EmptyTy empty;
|
||||
UndefinedTy undefined;
|
||||
}
|
||||
+78
-36
@@ -32,15 +32,19 @@ namespace embree
|
||||
/* we consider floating point numbers in that range as valid input numbers */
|
||||
static float FLT_LARGE = 1.844E18f;
|
||||
|
||||
static struct TrueTy {
|
||||
struct TrueTy {
|
||||
__forceinline operator bool( ) const { return true; }
|
||||
} True MAYBE_UNUSED;
|
||||
};
|
||||
|
||||
static struct FalseTy {
|
||||
extern MAYBE_UNUSED TrueTy True;
|
||||
|
||||
struct FalseTy {
|
||||
__forceinline operator bool( ) const { return false; }
|
||||
} False MAYBE_UNUSED;
|
||||
};
|
||||
|
||||
extern MAYBE_UNUSED FalseTy False;
|
||||
|
||||
static struct ZeroTy
|
||||
struct ZeroTy
|
||||
{
|
||||
__forceinline operator double ( ) const { return 0; }
|
||||
__forceinline operator float ( ) const { return 0; }
|
||||
@@ -54,9 +58,11 @@ namespace embree
|
||||
__forceinline operator unsigned short ( ) const { return 0; }
|
||||
__forceinline operator char ( ) const { return 0; }
|
||||
__forceinline operator unsigned char ( ) const { return 0; }
|
||||
} zero MAYBE_UNUSED;
|
||||
};
|
||||
|
||||
static struct OneTy
|
||||
extern MAYBE_UNUSED ZeroTy zero;
|
||||
|
||||
struct OneTy
|
||||
{
|
||||
__forceinline operator double ( ) const { return 1; }
|
||||
__forceinline operator float ( ) const { return 1; }
|
||||
@@ -70,9 +76,11 @@ namespace embree
|
||||
__forceinline operator unsigned short ( ) const { return 1; }
|
||||
__forceinline operator char ( ) const { return 1; }
|
||||
__forceinline operator unsigned char ( ) const { return 1; }
|
||||
} one MAYBE_UNUSED;
|
||||
};
|
||||
|
||||
static struct NegInfTy
|
||||
extern MAYBE_UNUSED OneTy one;
|
||||
|
||||
struct NegInfTy
|
||||
{
|
||||
__forceinline operator double ( ) const { return -std::numeric_limits<double>::infinity(); }
|
||||
__forceinline operator float ( ) const { return -std::numeric_limits<float>::infinity(); }
|
||||
@@ -87,9 +95,11 @@ namespace embree
|
||||
__forceinline operator char ( ) const { return std::numeric_limits<char>::min(); }
|
||||
__forceinline operator unsigned char ( ) const { return std::numeric_limits<unsigned char>::min(); }
|
||||
|
||||
} neg_inf MAYBE_UNUSED;
|
||||
};
|
||||
|
||||
static struct PosInfTy
|
||||
extern MAYBE_UNUSED NegInfTy neg_inf;
|
||||
|
||||
struct PosInfTy
|
||||
{
|
||||
__forceinline operator double ( ) const { return std::numeric_limits<double>::infinity(); }
|
||||
__forceinline operator float ( ) const { return std::numeric_limits<float>::infinity(); }
|
||||
@@ -103,65 +113,97 @@ namespace embree
|
||||
__forceinline operator unsigned short ( ) const { return std::numeric_limits<unsigned short>::max(); }
|
||||
__forceinline operator char ( ) const { return std::numeric_limits<char>::max(); }
|
||||
__forceinline operator unsigned char ( ) const { return std::numeric_limits<unsigned char>::max(); }
|
||||
} inf MAYBE_UNUSED, pos_inf MAYBE_UNUSED;
|
||||
};
|
||||
|
||||
static struct NaNTy
|
||||
extern MAYBE_UNUSED PosInfTy inf;
|
||||
extern MAYBE_UNUSED PosInfTy pos_inf;
|
||||
|
||||
struct NaNTy
|
||||
{
|
||||
__forceinline operator double( ) const { return std::numeric_limits<double>::quiet_NaN(); }
|
||||
__forceinline operator float ( ) const { return std::numeric_limits<float>::quiet_NaN(); }
|
||||
} nan MAYBE_UNUSED;
|
||||
};
|
||||
|
||||
static struct UlpTy
|
||||
extern MAYBE_UNUSED NaNTy nan;
|
||||
|
||||
struct UlpTy
|
||||
{
|
||||
__forceinline operator double( ) const { return std::numeric_limits<double>::epsilon(); }
|
||||
__forceinline operator float ( ) const { return std::numeric_limits<float>::epsilon(); }
|
||||
} ulp MAYBE_UNUSED;
|
||||
};
|
||||
|
||||
static struct PiTy
|
||||
extern MAYBE_UNUSED UlpTy ulp;
|
||||
|
||||
struct PiTy
|
||||
{
|
||||
__forceinline operator double( ) const { return double(M_PI); }
|
||||
__forceinline operator float ( ) const { return float(M_PI); }
|
||||
} pi MAYBE_UNUSED;
|
||||
};
|
||||
|
||||
static struct OneOverPiTy
|
||||
extern MAYBE_UNUSED PiTy pi;
|
||||
|
||||
struct OneOverPiTy
|
||||
{
|
||||
__forceinline operator double( ) const { return double(M_1_PI); }
|
||||
__forceinline operator float ( ) const { return float(M_1_PI); }
|
||||
} one_over_pi MAYBE_UNUSED;
|
||||
};
|
||||
|
||||
static struct TwoPiTy
|
||||
extern MAYBE_UNUSED OneOverPiTy one_over_pi;
|
||||
|
||||
struct TwoPiTy
|
||||
{
|
||||
__forceinline operator double( ) const { return double(2.0*M_PI); }
|
||||
__forceinline operator float ( ) const { return float(2.0*M_PI); }
|
||||
} two_pi MAYBE_UNUSED;
|
||||
};
|
||||
|
||||
static struct OneOverTwoPiTy
|
||||
extern MAYBE_UNUSED TwoPiTy two_pi;
|
||||
|
||||
struct OneOverTwoPiTy
|
||||
{
|
||||
__forceinline operator double( ) const { return double(0.5*M_1_PI); }
|
||||
__forceinline operator float ( ) const { return float(0.5*M_1_PI); }
|
||||
} one_over_two_pi MAYBE_UNUSED;
|
||||
};
|
||||
|
||||
static struct FourPiTy
|
||||
extern MAYBE_UNUSED OneOverTwoPiTy one_over_two_pi;
|
||||
|
||||
struct FourPiTy
|
||||
{
|
||||
__forceinline operator double( ) const { return double(4.0*M_PI); }
|
||||
__forceinline operator float ( ) const { return float(4.0*M_PI); }
|
||||
} four_pi MAYBE_UNUSED;
|
||||
};
|
||||
|
||||
static struct OneOverFourPiTy
|
||||
extern MAYBE_UNUSED FourPiTy four_pi;
|
||||
|
||||
struct OneOverFourPiTy
|
||||
{
|
||||
__forceinline operator double( ) const { return double(0.25*M_1_PI); }
|
||||
__forceinline operator float ( ) const { return float(0.25*M_1_PI); }
|
||||
} one_over_four_pi MAYBE_UNUSED;
|
||||
};
|
||||
|
||||
static struct StepTy {
|
||||
} step MAYBE_UNUSED;
|
||||
extern MAYBE_UNUSED OneOverFourPiTy one_over_four_pi;
|
||||
|
||||
static struct ReverseStepTy {
|
||||
} reverse_step MAYBE_UNUSED;
|
||||
struct StepTy {
|
||||
};
|
||||
|
||||
static struct EmptyTy {
|
||||
} empty MAYBE_UNUSED;
|
||||
extern MAYBE_UNUSED StepTy step;
|
||||
|
||||
static struct FullTy {
|
||||
} full MAYBE_UNUSED;
|
||||
struct ReverseStepTy {
|
||||
};
|
||||
|
||||
extern MAYBE_UNUSED ReverseStepTy reverse_step;
|
||||
|
||||
struct EmptyTy {
|
||||
};
|
||||
|
||||
extern MAYBE_UNUSED EmptyTy empty;
|
||||
|
||||
struct FullTy {
|
||||
};
|
||||
|
||||
extern MAYBE_UNUSED FullTy full;
|
||||
|
||||
struct UndefinedTy {
|
||||
};
|
||||
|
||||
extern MAYBE_UNUSED UndefinedTy undefined;
|
||||
}
|
||||
+2
-2
@@ -94,7 +94,7 @@ namespace embree
|
||||
BBox<T> b0 = lerp(blower0, blower1, lower-ilowerf);
|
||||
BBox<T> b1 = lerp(bupper1, bupper0, iupperf-upper);
|
||||
|
||||
for (size_t i = ilower+1; i < iupper; i++)
|
||||
for (int i = ilower+1; i < iupper; i++)
|
||||
{
|
||||
const float f = (float(i)/numTimeSegments - time_range.lower) / time_range.size();
|
||||
const BBox<T> bt = lerp(b0, b1, f);
|
||||
@@ -125,7 +125,7 @@ namespace embree
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i = ilower+1; i<iupper; i++)
|
||||
for (int i = ilower+1; i<iupper; i++)
|
||||
{
|
||||
const float f = float(i - time_range.begin()) / float(time_range.size());
|
||||
const BBox<T> bt = lerp(b0, b1, f);
|
||||
|
||||
@@ -58,10 +58,10 @@ namespace embree
|
||||
__forceinline const LinearSpace2 transposed() const { return LinearSpace2(vx.x,vx.y,vy.x,vy.y); }
|
||||
|
||||
/*! returns first row of matrix */
|
||||
__forceinline const Vector row0() const { return Vector(vx.x,vy.x); }
|
||||
__forceinline Vector row0() const { return Vector(vx.x,vy.x); }
|
||||
|
||||
/*! returns second row of matrix */
|
||||
__forceinline const Vector row1() const { return Vector(vx.y,vy.y); }
|
||||
__forceinline Vector row1() const { return Vector(vx.y,vy.y); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Constants
|
||||
|
||||
@@ -66,13 +66,13 @@ namespace embree
|
||||
__forceinline const LinearSpace3 transposed() const { return LinearSpace3(vx.x,vx.y,vx.z,vy.x,vy.y,vy.z,vz.x,vz.y,vz.z); }
|
||||
|
||||
/*! returns first row of matrix */
|
||||
__forceinline const Vector row0() const { return Vector(vx.x,vy.x,vz.x); }
|
||||
__forceinline Vector row0() const { return Vector(vx.x,vy.x,vz.x); }
|
||||
|
||||
/*! returns second row of matrix */
|
||||
__forceinline const Vector row1() const { return Vector(vx.y,vy.y,vz.y); }
|
||||
__forceinline Vector row1() const { return Vector(vx.y,vy.y,vz.y); }
|
||||
|
||||
/*! returns third row of matrix */
|
||||
__forceinline const Vector row2() const { return Vector(vx.z,vy.z,vz.z); }
|
||||
__forceinline Vector row2() const { return Vector(vx.z,vy.z,vz.z); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Constants
|
||||
|
||||
+8
-8
@@ -62,15 +62,15 @@ namespace embree
|
||||
const __m128 a = _mm_set_ss(x);
|
||||
|
||||
#if defined(__AVX512VL__)
|
||||
const __m128 r = _mm_rcp14_ps(a);
|
||||
const __m128 r = _mm_rcp14_ss(_mm_set_ss(0.0f),a);
|
||||
#else
|
||||
const __m128 r = _mm_rcp_ps(a);
|
||||
const __m128 r = _mm_rcp_ss(a);
|
||||
#endif
|
||||
|
||||
#if defined(__AVX2__)
|
||||
return _mm_cvtss_f32(_mm_mul_ps(r,_mm_fnmadd_ps(r, a, _mm_set_ss(2.0f))));
|
||||
return _mm_cvtss_f32(_mm_mul_ss(r,_mm_fnmadd_ss(r, a, _mm_set_ss(2.0f))));
|
||||
#else
|
||||
return _mm_cvtss_f32(_mm_mul_ps(r,_mm_sub_ps(_mm_set_ss(2.0f), _mm_mul_ps(r, a))));
|
||||
return _mm_cvtss_f32(_mm_mul_ss(r,_mm_sub_ss(_mm_set_ss(2.0f), _mm_mul_ss(r, a))));
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -87,12 +87,12 @@ namespace embree
|
||||
{
|
||||
const __m128 a = _mm_set_ss(x);
|
||||
#if defined(__AVX512VL__)
|
||||
const __m128 r = _mm_rsqrt14_ps(a);
|
||||
const __m128 r = _mm_rsqrt14_ss(_mm_set_ss(0.0f),a);
|
||||
#else
|
||||
const __m128 r = _mm_rsqrt_ps(a);
|
||||
const __m128 r = _mm_rsqrt_ss(a);
|
||||
#endif
|
||||
const __m128 c = _mm_add_ps(_mm_mul_ps(_mm_set_ps(1.5f, 1.5f, 1.5f, 1.5f), r),
|
||||
_mm_mul_ps(_mm_mul_ps(_mm_mul_ps(a, _mm_set_ps(-0.5f, -0.5f, -0.5f, -0.5f)), r), _mm_mul_ps(r, r)));
|
||||
const __m128 c = _mm_add_ss(_mm_mul_ss(_mm_set_ss(1.5f), r),
|
||||
_mm_mul_ss(_mm_mul_ss(_mm_mul_ss(a, _mm_set_ss(-0.5f)), r), _mm_mul_ss(r, r)));
|
||||
return _mm_cvtss_f32(c);
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace embree
|
||||
/// Construction
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline QuaternionT ( void ) { }
|
||||
__forceinline QuaternionT () { }
|
||||
__forceinline QuaternionT ( const QuaternionT& other ) { r = other.r; i = other.i; j = other.j; k = other.k; }
|
||||
__forceinline QuaternionT& operator=( const QuaternionT& other ) { r = other.r; i = other.i; j = other.j; k = other.k; return *this; }
|
||||
|
||||
@@ -58,7 +58,7 @@ namespace embree
|
||||
}
|
||||
|
||||
/*! returns the rotation axis of the quaternion as a vector */
|
||||
__forceinline const Vec3<T> v( ) const { return Vec3<T>(i, j, k); }
|
||||
__forceinline Vec3<T> v( ) const { return Vec3<T>(i, j, k); }
|
||||
|
||||
public:
|
||||
T r, i, j, k;
|
||||
|
||||
+12
-24
@@ -100,56 +100,44 @@ namespace embree
|
||||
}
|
||||
|
||||
template<typename Ty>
|
||||
struct extended_range
|
||||
struct extended_range : public range<Ty>
|
||||
{
|
||||
__forceinline extended_range () {}
|
||||
|
||||
__forceinline extended_range (const Ty& begin)
|
||||
: _begin(begin), _end(begin+1), _ext_end(begin+1) {}
|
||||
: range<Ty>(begin), _ext_end(begin+1) {}
|
||||
|
||||
__forceinline extended_range (const Ty& begin, const Ty& end)
|
||||
: _begin(begin), _end(end), _ext_end(end) {}
|
||||
: range<Ty>(begin,end), _ext_end(end) {}
|
||||
|
||||
__forceinline extended_range (const Ty& begin, const Ty& end, const Ty& ext_end)
|
||||
: _begin(begin), _end(end), _ext_end(ext_end) {}
|
||||
: range<Ty>(begin,end), _ext_end(ext_end) {}
|
||||
|
||||
__forceinline Ty begin() const {
|
||||
return _begin;
|
||||
}
|
||||
|
||||
__forceinline Ty end() const {
|
||||
return _end;
|
||||
}
|
||||
|
||||
__forceinline Ty ext_end() const {
|
||||
return _ext_end;
|
||||
}
|
||||
|
||||
__forceinline Ty size() const {
|
||||
return _end - _begin;
|
||||
}
|
||||
|
||||
__forceinline Ty ext_size() const {
|
||||
return _ext_end - _begin;
|
||||
return _ext_end - range<Ty>::_begin;
|
||||
}
|
||||
|
||||
__forceinline Ty ext_range_size() const {
|
||||
return _ext_end - _end;
|
||||
return _ext_end - range<Ty>::_end;
|
||||
}
|
||||
|
||||
__forceinline bool has_ext_range() const {
|
||||
assert(_ext_end >= _end);
|
||||
return (_ext_end - _end) > 0;
|
||||
assert(_ext_end >= range<Ty>::_end);
|
||||
return (_ext_end - range<Ty>::_end) > 0;
|
||||
}
|
||||
|
||||
__forceinline void set_ext_range(const size_t ext_end){
|
||||
assert(ext_end >= _end);
|
||||
assert(ext_end >= range<Ty>::_end);
|
||||
_ext_end = ext_end;
|
||||
}
|
||||
|
||||
__forceinline void move_right(const size_t plus){
|
||||
_begin += plus;
|
||||
_end += plus;
|
||||
range<Ty>::_begin += plus;
|
||||
range<Ty>::_end += plus;
|
||||
_ext_end += plus;
|
||||
}
|
||||
|
||||
@@ -157,6 +145,6 @@ namespace embree
|
||||
return cout << "extended_range [" << r.begin() << ", " << r.end() << " (" << r.ext_end() << ")]";
|
||||
}
|
||||
|
||||
Ty _begin, _end, _ext_end;
|
||||
Ty _ext_end;
|
||||
};
|
||||
}
|
||||
+8
-8
@@ -92,15 +92,15 @@ namespace embree
|
||||
/// Ternary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<typename T> __forceinline const Vec2<T> madd ( const Vec2<T>& a, const Vec2<T>& b, const Vec2<T>& c) { return Vec2<T>( madd(a.x,b.x,c.x), madd(a.y,b.y,c.y) ); }
|
||||
template<typename T> __forceinline const Vec2<T> msub ( const Vec2<T>& a, const Vec2<T>& b, const Vec2<T>& c) { return Vec2<T>( msub(a.x,b.x,c.x), msub(a.y,b.y,c.y) ); }
|
||||
template<typename T> __forceinline const Vec2<T> nmadd ( const Vec2<T>& a, const Vec2<T>& b, const Vec2<T>& c) { return Vec2<T>(nmadd(a.x,b.x,c.x),nmadd(a.y,b.y,c.y) ); }
|
||||
template<typename T> __forceinline const Vec2<T> nmsub ( const Vec2<T>& a, const Vec2<T>& b, const Vec2<T>& c) { return Vec2<T>(nmsub(a.x,b.x,c.x),nmsub(a.y,b.y,c.y) ); }
|
||||
template<typename T> __forceinline Vec2<T> madd ( const Vec2<T>& a, const Vec2<T>& b, const Vec2<T>& c) { return Vec2<T>( madd(a.x,b.x,c.x), madd(a.y,b.y,c.y) ); }
|
||||
template<typename T> __forceinline Vec2<T> msub ( const Vec2<T>& a, const Vec2<T>& b, const Vec2<T>& c) { return Vec2<T>( msub(a.x,b.x,c.x), msub(a.y,b.y,c.y) ); }
|
||||
template<typename T> __forceinline Vec2<T> nmadd ( const Vec2<T>& a, const Vec2<T>& b, const Vec2<T>& c) { return Vec2<T>(nmadd(a.x,b.x,c.x),nmadd(a.y,b.y,c.y) ); }
|
||||
template<typename T> __forceinline Vec2<T> nmsub ( const Vec2<T>& a, const Vec2<T>& b, const Vec2<T>& c) { return Vec2<T>(nmsub(a.x,b.x,c.x),nmsub(a.y,b.y,c.y) ); }
|
||||
|
||||
template<typename T> __forceinline const Vec2<T> madd ( const T& a, const Vec2<T>& b, const Vec2<T>& c) { return Vec2<T>( madd(a,b.x,c.x), madd(a,b.y,c.y) ); }
|
||||
template<typename T> __forceinline const Vec2<T> msub ( const T& a, const Vec2<T>& b, const Vec2<T>& c) { return Vec2<T>( msub(a,b.x,c.x), msub(a,b.y,c.y) ); }
|
||||
template<typename T> __forceinline const Vec2<T> nmadd ( const T& a, const Vec2<T>& b, const Vec2<T>& c) { return Vec2<T>(nmadd(a,b.x,c.x),nmadd(a,b.y,c.y) ); }
|
||||
template<typename T> __forceinline const Vec2<T> nmsub ( const T& a, const Vec2<T>& b, const Vec2<T>& c) { return Vec2<T>(nmsub(a,b.x,c.x),nmsub(a,b.y,c.y) ); }
|
||||
template<typename T> __forceinline Vec2<T> madd ( const T& a, const Vec2<T>& b, const Vec2<T>& c) { return Vec2<T>( madd(a,b.x,c.x), madd(a,b.y,c.y) ); }
|
||||
template<typename T> __forceinline Vec2<T> msub ( const T& a, const Vec2<T>& b, const Vec2<T>& c) { return Vec2<T>( msub(a,b.x,c.x), msub(a,b.y,c.y) ); }
|
||||
template<typename T> __forceinline Vec2<T> nmadd ( const T& a, const Vec2<T>& b, const Vec2<T>& c) { return Vec2<T>(nmadd(a,b.x,c.x),nmadd(a,b.y,c.y) ); }
|
||||
template<typename T> __forceinline Vec2<T> nmsub ( const T& a, const Vec2<T>& b, const Vec2<T>& c) { return Vec2<T>(nmsub(a,b.x,c.x),nmsub(a,b.y,c.y) ); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Assignment Operators
|
||||
|
||||
+36
-32
@@ -77,7 +77,7 @@ namespace embree
|
||||
select(abs(a.y)<min_rcp_input,T(min_rcp_input),a.y),
|
||||
select(abs(a.z)<min_rcp_input,T(min_rcp_input),a.z));
|
||||
}
|
||||
template<typename T> __forceinline const Vec3<T> rcp_safe(const Vec3<T>& a) { return rcp(zero_fix(a)); }
|
||||
template<typename T> __forceinline Vec3<T> rcp_safe(const Vec3<T>& a) { return rcp(zero_fix(a)); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Binary Operators
|
||||
@@ -102,25 +102,25 @@ namespace embree
|
||||
/// Ternary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<typename T> __forceinline const Vec3<T> madd ( const Vec3<T>& a, const Vec3<T>& b, const Vec3<T>& c) { return Vec3<T>( madd(a.x,b.x,c.x), madd(a.y,b.y,c.y), madd(a.z,b.z,c.z)); }
|
||||
template<typename T> __forceinline const Vec3<T> msub ( const Vec3<T>& a, const Vec3<T>& b, const Vec3<T>& c) { return Vec3<T>( msub(a.x,b.x,c.x), msub(a.y,b.y,c.y), msub(a.z,b.z,c.z)); }
|
||||
template<typename T> __forceinline const Vec3<T> nmadd ( const Vec3<T>& a, const Vec3<T>& b, const Vec3<T>& c) { return Vec3<T>(nmadd(a.x,b.x,c.x),nmadd(a.y,b.y,c.y),nmadd(a.z,b.z,c.z));}
|
||||
template<typename T> __forceinline const Vec3<T> nmsub ( const Vec3<T>& a, const Vec3<T>& b, const Vec3<T>& c) { return Vec3<T>(nmsub(a.x,b.x,c.x),nmsub(a.y,b.y,c.y),nmsub(a.z,b.z,c.z)); }
|
||||
template<typename T> __forceinline Vec3<T> madd ( const Vec3<T>& a, const Vec3<T>& b, const Vec3<T>& c) { return Vec3<T>( madd(a.x,b.x,c.x), madd(a.y,b.y,c.y), madd(a.z,b.z,c.z)); }
|
||||
template<typename T> __forceinline Vec3<T> msub ( const Vec3<T>& a, const Vec3<T>& b, const Vec3<T>& c) { return Vec3<T>( msub(a.x,b.x,c.x), msub(a.y,b.y,c.y), msub(a.z,b.z,c.z)); }
|
||||
template<typename T> __forceinline Vec3<T> nmadd ( const Vec3<T>& a, const Vec3<T>& b, const Vec3<T>& c) { return Vec3<T>(nmadd(a.x,b.x,c.x),nmadd(a.y,b.y,c.y),nmadd(a.z,b.z,c.z));}
|
||||
template<typename T> __forceinline Vec3<T> nmsub ( const Vec3<T>& a, const Vec3<T>& b, const Vec3<T>& c) { return Vec3<T>(nmsub(a.x,b.x,c.x),nmsub(a.y,b.y,c.y),nmsub(a.z,b.z,c.z)); }
|
||||
|
||||
template<typename T> __forceinline const Vec3<T> madd ( const T& a, const Vec3<T>& b, const Vec3<T>& c) { return Vec3<T>( madd(a,b.x,c.x), madd(a,b.y,c.y), madd(a,b.z,c.z)); }
|
||||
template<typename T> __forceinline const Vec3<T> msub ( const T& a, const Vec3<T>& b, const Vec3<T>& c) { return Vec3<T>( msub(a,b.x,c.x), msub(a,b.y,c.y), msub(a,b.z,c.z)); }
|
||||
template<typename T> __forceinline const Vec3<T> nmadd ( const T& a, const Vec3<T>& b, const Vec3<T>& c) { return Vec3<T>(nmadd(a,b.x,c.x),nmadd(a,b.y,c.y),nmadd(a,b.z,c.z));}
|
||||
template<typename T> __forceinline const Vec3<T> nmsub ( const T& a, const Vec3<T>& b, const Vec3<T>& c) { return Vec3<T>(nmsub(a,b.x,c.x),nmsub(a,b.y,c.y),nmsub(a,b.z,c.z)); }
|
||||
template<typename T> __forceinline Vec3<T> madd ( const T& a, const Vec3<T>& b, const Vec3<T>& c) { return Vec3<T>( madd(a,b.x,c.x), madd(a,b.y,c.y), madd(a,b.z,c.z)); }
|
||||
template<typename T> __forceinline Vec3<T> msub ( const T& a, const Vec3<T>& b, const Vec3<T>& c) { return Vec3<T>( msub(a,b.x,c.x), msub(a,b.y,c.y), msub(a,b.z,c.z)); }
|
||||
template<typename T> __forceinline Vec3<T> nmadd ( const T& a, const Vec3<T>& b, const Vec3<T>& c) { return Vec3<T>(nmadd(a,b.x,c.x),nmadd(a,b.y,c.y),nmadd(a,b.z,c.z));}
|
||||
template<typename T> __forceinline Vec3<T> nmsub ( const T& a, const Vec3<T>& b, const Vec3<T>& c) { return Vec3<T>(nmsub(a,b.x,c.x),nmsub(a,b.y,c.y),nmsub(a,b.z,c.z)); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Assignment Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<typename T> __forceinline const Vec3<T>& operator +=( Vec3<T>& a, const T b ) { a.x += b; a.y += b; a.z += b; return a; }
|
||||
template<typename T> __forceinline const Vec3<T>& operator +=( Vec3<T>& a, const Vec3<T>& b ) { a.x += b.x; a.y += b.y; a.z += b.z; return a; }
|
||||
template<typename T> __forceinline const Vec3<T>& operator -=( Vec3<T>& a, const Vec3<T>& b ) { a.x -= b.x; a.y -= b.y; a.z -= b.z; return a; }
|
||||
template<typename T> __forceinline const Vec3<T>& operator *=( Vec3<T>& a, const T& b ) { a.x *= b ; a.y *= b ; a.z *= b ; return a; }
|
||||
template<typename T> __forceinline const Vec3<T>& operator /=( Vec3<T>& a, const T& b ) { a.x /= b ; a.y /= b ; a.z /= b ; return a; }
|
||||
template<typename T> __forceinline Vec3<T>& operator +=( Vec3<T>& a, const T b ) { a.x += b; a.y += b; a.z += b; return a; }
|
||||
template<typename T> __forceinline Vec3<T>& operator +=( Vec3<T>& a, const Vec3<T>& b ) { a.x += b.x; a.y += b.y; a.z += b.z; return a; }
|
||||
template<typename T> __forceinline Vec3<T>& operator -=( Vec3<T>& a, const Vec3<T>& b ) { a.x -= b.x; a.y -= b.y; a.z -= b.z; return a; }
|
||||
template<typename T> __forceinline Vec3<T>& operator *=( Vec3<T>& a, const T& b ) { a.x *= b ; a.y *= b ; a.z *= b ; return a; }
|
||||
template<typename T> __forceinline Vec3<T>& operator /=( Vec3<T>& a, const T& b ) { a.x /= b ; a.y /= b ; a.z /= b ; return a; }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Reduction Operators
|
||||
@@ -270,66 +270,70 @@ namespace embree
|
||||
namespace embree
|
||||
{
|
||||
template<typename Out, typename In>
|
||||
__forceinline Vec3<Out> broadcast(const Vec3<In>& a, const size_t k) {
|
||||
return Vec3<Out>(Out(a.x[k]),Out(a.y[k]),Out(a.z[k]));
|
||||
__forceinline Vec3<Out> broadcast(const Vec3<In>& a, const size_t k) {
|
||||
return Vec3<Out>(Out(a.x[k]), Out(a.y[k]), Out(a.z[k]));
|
||||
}
|
||||
|
||||
template<> __forceinline Vec3<float>::Vec3( const Vec3fa& a ) { x = a.x; y = a.y; z = a.z; }
|
||||
template<> __forceinline Vec3<float>::Vec3(const Vec3fa& a) { x = a.x; y = a.y; z = a.z; }
|
||||
|
||||
#if defined(__AVX__)
|
||||
template<> __forceinline Vec3<vfloat4>::Vec3( const Vec3fa& a ) {
|
||||
template<> __forceinline Vec3<vfloat4>::Vec3(const Vec3fa& a) {
|
||||
x = a.x; y = a.y; z = a.z;
|
||||
}
|
||||
#elif defined(__SSE__)
|
||||
template<> __forceinline Vec3<vfloat4>::Vec3( const Vec3fa& a ) {
|
||||
template<>
|
||||
__forceinline Vec3<vfloat4>::Vec3(const Vec3fa& a) {
|
||||
const vfloat4 v = vfloat4(a); x = shuffle<0,0,0,0>(v); y = shuffle<1,1,1,1>(v); z = shuffle<2,2,2,2>(v);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__SSE__)
|
||||
__forceinline Vec3<vfloat4> broadcast4f( const Vec3<vfloat4>& a, const size_t k ) {
|
||||
__forceinline Vec3<vfloat4> broadcast4f(const Vec3<vfloat4>& a, const size_t k) {
|
||||
return Vec3<vfloat4>(vfloat4::broadcast(&a.x[k]), vfloat4::broadcast(&a.y[k]), vfloat4::broadcast(&a.z[k]));
|
||||
}
|
||||
|
||||
template<>
|
||||
__forceinline Vec3<vfloat4> broadcast<vfloat4,vfloat4>( const Vec3<vfloat4>& a, const size_t k ) {
|
||||
__forceinline Vec3<vfloat4> broadcast<vfloat4,vfloat4>(const Vec3<vfloat4>& a, const size_t k) {
|
||||
return Vec3<vfloat4>(vfloat4::broadcast(&a.x[k]), vfloat4::broadcast(&a.y[k]), vfloat4::broadcast(&a.z[k]));
|
||||
}
|
||||
|
||||
template<size_t i0, size_t i1, size_t i2, size_t i3> __forceinline const Vec3<vfloat4> shuffle( const Vec3<vfloat4>& b ) {
|
||||
return Vec3<vfloat4>(shuffle<i0,i1,i2,i3>(b.x),shuffle<i0,i1,i2,i3>(b.y),shuffle<i0,i1,i2,i3>(b.z));
|
||||
template<int i0, int i1, int i2, int i3>
|
||||
__forceinline Vec3<vfloat4> shuffle(const Vec3<vfloat4>& b) {
|
||||
return Vec3<vfloat4>(shuffle<i0,i1,i2,i3>(b.x), shuffle<i0,i1,i2,i3>(b.y), shuffle<i0,i1,i2,i3>(b.z));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__AVX__)
|
||||
template<> __forceinline Vec3<vfloat8>::Vec3( const Vec3fa& a ) {
|
||||
template<>
|
||||
__forceinline Vec3<vfloat8>::Vec3(const Vec3fa& a) {
|
||||
x = a.x; y = a.y; z = a.z;
|
||||
}
|
||||
__forceinline Vec3<vfloat4> broadcast4f( const Vec3<vfloat8>& a, const size_t k ) {
|
||||
__forceinline Vec3<vfloat4> broadcast4f(const Vec3<vfloat8>& a, const size_t k) {
|
||||
return Vec3<vfloat4>(vfloat4::broadcast(&a.x[k]), vfloat4::broadcast(&a.y[k]), vfloat4::broadcast(&a.z[k]));
|
||||
}
|
||||
__forceinline Vec3<vfloat8> broadcast8f( const Vec3<vfloat4>& a, const size_t k ) {
|
||||
__forceinline Vec3<vfloat8> broadcast8f(const Vec3<vfloat4>& a, const size_t k) {
|
||||
return Vec3<vfloat8>(vfloat8::broadcast(&a.x[k]), vfloat8::broadcast(&a.y[k]), vfloat8::broadcast(&a.z[k]));
|
||||
}
|
||||
__forceinline Vec3<vfloat8> broadcast8f( const Vec3<vfloat8>& a, const size_t k ) {
|
||||
__forceinline Vec3<vfloat8> broadcast8f(const Vec3<vfloat8>& a, const size_t k) {
|
||||
return Vec3<vfloat8>(vfloat8::broadcast(&a.x[k]), vfloat8::broadcast(&a.y[k]), vfloat8::broadcast(&a.z[k]));
|
||||
}
|
||||
|
||||
template<>
|
||||
__forceinline Vec3<vfloat8> broadcast<vfloat8,vfloat4>( const Vec3<vfloat4>& a, const size_t k ) {
|
||||
__forceinline Vec3<vfloat8> broadcast<vfloat8,vfloat4>(const Vec3<vfloat4>& a, const size_t k) {
|
||||
return Vec3<vfloat8>(vfloat8::broadcast(&a.x[k]), vfloat8::broadcast(&a.y[k]), vfloat8::broadcast(&a.z[k]));
|
||||
}
|
||||
template<>
|
||||
__forceinline Vec3<vfloat8> broadcast<vfloat8,vfloat8>( const Vec3<vfloat8>& a, const size_t k ) {
|
||||
__forceinline Vec3<vfloat8> broadcast<vfloat8,vfloat8>(const Vec3<vfloat8>& a, const size_t k) {
|
||||
return Vec3<vfloat8>(vfloat8::broadcast(&a.x[k]), vfloat8::broadcast(&a.y[k]), vfloat8::broadcast(&a.z[k]));
|
||||
}
|
||||
|
||||
template<size_t i0, size_t i1, size_t i2, size_t i3> __forceinline const Vec3<vfloat8> shuffle( const Vec3<vfloat8>& b ) {
|
||||
return Vec3<vfloat8>(shuffle<i0,i1,i2,i3>(b.x),shuffle<i0,i1,i2,i3>(b.y),shuffle<i0,i1,i2,i3>(b.z));
|
||||
template<int i0, int i1, int i2, int i3>
|
||||
__forceinline Vec3<vfloat8> shuffle(const Vec3<vfloat8>& b) {
|
||||
return Vec3<vfloat8>(shuffle<i0,i1,i2,i3>(b.x), shuffle<i0,i1,i2,i3>(b.y), shuffle<i0,i1,i2,i3>(b.z));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__AVX512F__)
|
||||
template<> __forceinline Vec3<vfloat16>::Vec3( const Vec3fa& a ) : x(a.x), y(a.y), z(a.z) {}
|
||||
template<> __forceinline Vec3<vfloat16>::Vec3(const Vec3fa& a) : x(a.x), y(a.y), z(a.z) {}
|
||||
#endif
|
||||
}
|
||||
@@ -52,8 +52,8 @@ namespace embree
|
||||
__forceinline Vec3ba( bool a, bool b, bool c)
|
||||
: m128(_mm_lookupmask_ps[(size_t(c) << 2) | (size_t(b) << 1) | size_t(a)]) {}
|
||||
|
||||
__forceinline operator const __m128&( void ) const { return m128; }
|
||||
__forceinline operator __m128&( void ) { return m128; }
|
||||
__forceinline operator const __m128&() const { return m128; }
|
||||
__forceinline operator __m128&() { return m128; }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Constants
|
||||
@@ -75,23 +75,23 @@ namespace embree
|
||||
/// Unary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const Vec3ba operator !( const Vec3ba& a ) { return _mm_xor_ps(a.m128, Vec3ba(embree::True)); }
|
||||
__forceinline Vec3ba operator !( const Vec3ba& a ) { return _mm_xor_ps(a.m128, Vec3ba(embree::True)); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Binary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const Vec3ba operator &( const Vec3ba& a, const Vec3ba& b ) { return _mm_and_ps(a.m128, b.m128); }
|
||||
__forceinline const Vec3ba operator |( const Vec3ba& a, const Vec3ba& b ) { return _mm_or_ps (a.m128, b.m128); }
|
||||
__forceinline const Vec3ba operator ^( const Vec3ba& a, const Vec3ba& b ) { return _mm_xor_ps(a.m128, b.m128); }
|
||||
__forceinline Vec3ba operator &( const Vec3ba& a, const Vec3ba& b ) { return _mm_and_ps(a.m128, b.m128); }
|
||||
__forceinline Vec3ba operator |( const Vec3ba& a, const Vec3ba& b ) { return _mm_or_ps (a.m128, b.m128); }
|
||||
__forceinline Vec3ba operator ^( const Vec3ba& a, const Vec3ba& b ) { return _mm_xor_ps(a.m128, b.m128); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Assignment Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const Vec3ba operator &=( Vec3ba& a, const Vec3ba& b ) { return a = a & b; }
|
||||
__forceinline const Vec3ba operator |=( Vec3ba& a, const Vec3ba& b ) { return a = a | b; }
|
||||
__forceinline const Vec3ba operator ^=( Vec3ba& a, const Vec3ba& b ) { return a = a ^ b; }
|
||||
__forceinline Vec3ba& operator &=( Vec3ba& a, const Vec3ba& b ) { return a = a & b; }
|
||||
__forceinline Vec3ba& operator |=( Vec3ba& a, const Vec3ba& b ) { return a = a | b; }
|
||||
__forceinline Vec3ba& operator ^=( Vec3ba& a, const Vec3ba& b ) { return a = a ^ b; }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Comparison Operators + Select
|
||||
|
||||
+32
-32
@@ -63,13 +63,13 @@ namespace embree
|
||||
|
||||
__forceinline explicit Vec3fa( const __m128i a ) : m128(_mm_cvtepi32_ps(a)) {}
|
||||
|
||||
__forceinline operator const __m128&( void ) const { return m128; }
|
||||
__forceinline operator __m128&( void ) { return m128; }
|
||||
__forceinline operator const __m128&() const { return m128; }
|
||||
__forceinline operator __m128&() { return m128; }
|
||||
|
||||
#if defined (__SSE4_1__)
|
||||
friend __forceinline const Vec3fa copy_a( const Vec3fa& a, const Vec3fa& b ) { return _mm_insert_ps(a, b, (3 << 4) | (3 << 6)); }
|
||||
friend __forceinline Vec3fa copy_a( const Vec3fa& a, const Vec3fa& b ) { return _mm_insert_ps(a, b, (3 << 4) | (3 << 6)); }
|
||||
#else
|
||||
friend __forceinline const Vec3fa copy_a( const Vec3fa& a, const Vec3fa& b ) { Vec3fa c = a; c.a = b.a; return c; }
|
||||
friend __forceinline Vec3fa copy_a( const Vec3fa& a, const Vec3fa& b ) { Vec3fa c = a; c.a = b.a; return c; }
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -109,20 +109,20 @@ namespace embree
|
||||
/// Unary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const Vec3fa operator +( const Vec3fa& a ) { return a; }
|
||||
__forceinline const Vec3fa operator -( const Vec3fa& a ) {
|
||||
__forceinline Vec3fa operator +( const Vec3fa& a ) { return a; }
|
||||
__forceinline Vec3fa operator -( const Vec3fa& a ) {
|
||||
const __m128 mask = _mm_castsi128_ps(_mm_set1_epi32(0x80000000));
|
||||
return _mm_xor_ps(a.m128, mask);
|
||||
}
|
||||
__forceinline const Vec3fa abs ( const Vec3fa& a ) {
|
||||
__forceinline Vec3fa abs ( const Vec3fa& a ) {
|
||||
const __m128 mask = _mm_castsi128_ps(_mm_set1_epi32(0x7fffffff));
|
||||
return _mm_and_ps(a.m128, mask);
|
||||
}
|
||||
__forceinline const Vec3fa sign ( const Vec3fa& a ) {
|
||||
__forceinline Vec3fa sign ( const Vec3fa& a ) {
|
||||
return blendv_ps(Vec3fa(one), -Vec3fa(one), _mm_cmplt_ps (a,Vec3fa(zero)));
|
||||
}
|
||||
|
||||
__forceinline const Vec3fa rcp ( const Vec3fa& a )
|
||||
__forceinline Vec3fa rcp ( const Vec3fa& a )
|
||||
{
|
||||
#if defined(__AVX512VL__)
|
||||
const Vec3fa r = _mm_rcp14_ps(a.m128);
|
||||
@@ -140,10 +140,10 @@ namespace embree
|
||||
return res;
|
||||
}
|
||||
|
||||
__forceinline const Vec3fa sqrt ( const Vec3fa& a ) { return _mm_sqrt_ps(a.m128); }
|
||||
__forceinline const Vec3fa sqr ( const Vec3fa& a ) { return _mm_mul_ps(a,a); }
|
||||
__forceinline Vec3fa sqrt ( const Vec3fa& a ) { return _mm_sqrt_ps(a.m128); }
|
||||
__forceinline Vec3fa sqr ( const Vec3fa& a ) { return _mm_mul_ps(a,a); }
|
||||
|
||||
__forceinline const Vec3fa rsqrt( const Vec3fa& a )
|
||||
__forceinline Vec3fa rsqrt( const Vec3fa& a )
|
||||
{
|
||||
#if defined(__AVX512VL__)
|
||||
__m128 r = _mm_rsqrt14_ps(a.m128);
|
||||
@@ -153,10 +153,10 @@ namespace embree
|
||||
return _mm_add_ps(_mm_mul_ps(_mm_set1_ps(1.5f),r), _mm_mul_ps(_mm_mul_ps(_mm_mul_ps(a, _mm_set1_ps(-0.5f)), r), _mm_mul_ps(r, r)));
|
||||
}
|
||||
|
||||
__forceinline const Vec3fa zero_fix(const Vec3fa& a) {
|
||||
__forceinline Vec3fa zero_fix(const Vec3fa& a) {
|
||||
return blendv_ps(a, _mm_set1_ps(min_rcp_input), _mm_cmplt_ps (abs(a).m128, _mm_set1_ps(min_rcp_input)));
|
||||
}
|
||||
__forceinline const Vec3fa rcp_safe(const Vec3fa& a) {
|
||||
__forceinline Vec3fa rcp_safe(const Vec3fa& a) {
|
||||
return rcp(zero_fix(a));
|
||||
}
|
||||
__forceinline Vec3fa log ( const Vec3fa& a ) {
|
||||
@@ -171,17 +171,17 @@ namespace embree
|
||||
/// Binary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const Vec3fa operator +( const Vec3fa& a, const Vec3fa& b ) { return _mm_add_ps(a.m128, b.m128); }
|
||||
__forceinline const Vec3fa operator -( const Vec3fa& a, const Vec3fa& b ) { return _mm_sub_ps(a.m128, b.m128); }
|
||||
__forceinline const Vec3fa operator *( const Vec3fa& a, const Vec3fa& b ) { return _mm_mul_ps(a.m128, b.m128); }
|
||||
__forceinline const Vec3fa operator *( const Vec3fa& a, const float b ) { return a * Vec3fa(b); }
|
||||
__forceinline const Vec3fa operator *( const float a, const Vec3fa& b ) { return Vec3fa(a) * b; }
|
||||
__forceinline const Vec3fa operator /( const Vec3fa& a, const Vec3fa& b ) { return _mm_div_ps(a.m128,b.m128); }
|
||||
__forceinline const Vec3fa operator /( const Vec3fa& a, const float b ) { return _mm_div_ps(a.m128,_mm_set1_ps(b)); }
|
||||
__forceinline const Vec3fa operator /( const float a, const Vec3fa& b ) { return _mm_div_ps(_mm_set1_ps(a),b.m128); }
|
||||
__forceinline Vec3fa operator +( const Vec3fa& a, const Vec3fa& b ) { return _mm_add_ps(a.m128, b.m128); }
|
||||
__forceinline Vec3fa operator -( const Vec3fa& a, const Vec3fa& b ) { return _mm_sub_ps(a.m128, b.m128); }
|
||||
__forceinline Vec3fa operator *( const Vec3fa& a, const Vec3fa& b ) { return _mm_mul_ps(a.m128, b.m128); }
|
||||
__forceinline Vec3fa operator *( const Vec3fa& a, const float b ) { return a * Vec3fa(b); }
|
||||
__forceinline Vec3fa operator *( const float a, const Vec3fa& b ) { return Vec3fa(a) * b; }
|
||||
__forceinline Vec3fa operator /( const Vec3fa& a, const Vec3fa& b ) { return _mm_div_ps(a.m128,b.m128); }
|
||||
__forceinline Vec3fa operator /( const Vec3fa& a, const float b ) { return _mm_div_ps(a.m128,_mm_set1_ps(b)); }
|
||||
__forceinline Vec3fa operator /( const float a, const Vec3fa& b ) { return _mm_div_ps(_mm_set1_ps(a),b.m128); }
|
||||
|
||||
__forceinline const Vec3fa min( const Vec3fa& a, const Vec3fa& b ) { return _mm_min_ps(a.m128,b.m128); }
|
||||
__forceinline const Vec3fa max( const Vec3fa& a, const Vec3fa& b ) { return _mm_max_ps(a.m128,b.m128); }
|
||||
__forceinline Vec3fa min( const Vec3fa& a, const Vec3fa& b ) { return _mm_min_ps(a.m128,b.m128); }
|
||||
__forceinline Vec3fa max( const Vec3fa& a, const Vec3fa& b ) { return _mm_max_ps(a.m128,b.m128); }
|
||||
|
||||
#if defined(__SSE4_1__)
|
||||
__forceinline Vec3fa mini(const Vec3fa& a, const Vec3fa& b) {
|
||||
@@ -316,12 +316,12 @@ namespace embree
|
||||
/// Select
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const Vec3fa select( bool s, const Vec3fa& t, const Vec3fa& f ) {
|
||||
__forceinline Vec3fa select( bool s, const Vec3fa& t, const Vec3fa& f ) {
|
||||
__m128 mask = s ? _mm_castsi128_ps(_mm_cmpeq_epi32(_mm_setzero_si128(), _mm_setzero_si128())) : _mm_setzero_ps();
|
||||
return blendv_ps(f, t, mask);
|
||||
}
|
||||
|
||||
__forceinline const Vec3fa select( const Vec3ba& s, const Vec3fa& t, const Vec3fa& f ) {
|
||||
__forceinline Vec3fa select( const Vec3ba& s, const Vec3fa& t, const Vec3fa& f ) {
|
||||
return blendv_ps(f, t, s);
|
||||
}
|
||||
|
||||
@@ -340,13 +340,13 @@ namespace embree
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined (__SSE4_1__)
|
||||
//__forceinline const Vec3fa trunc( const Vec3fa& a ) { return _mm_round_ps(a, _MM_FROUND_TO_NEAREST_INT); }
|
||||
__forceinline const Vec3fa floor( const Vec3fa& a ) { return _mm_round_ps(a, _MM_FROUND_TO_NEG_INF ); }
|
||||
__forceinline const Vec3fa ceil ( const Vec3fa& a ) { return _mm_round_ps(a, _MM_FROUND_TO_POS_INF ); }
|
||||
//__forceinline Vec3fa trunc( const Vec3fa& a ) { return _mm_round_ps(a, _MM_FROUND_TO_NEAREST_INT); }
|
||||
__forceinline Vec3fa floor( const Vec3fa& a ) { return _mm_round_ps(a, _MM_FROUND_TO_NEG_INF ); }
|
||||
__forceinline Vec3fa ceil ( const Vec3fa& a ) { return _mm_round_ps(a, _MM_FROUND_TO_POS_INF ); }
|
||||
#else
|
||||
//__forceinline const Vec3fa trunc( const Vec3fa& a ) { return Vec3fa(truncf(a.x),truncf(a.y),truncf(a.z)); }
|
||||
__forceinline const Vec3fa floor( const Vec3fa& a ) { return Vec3fa(floorf(a.x),floorf(a.y),floorf(a.z)); }
|
||||
__forceinline const Vec3fa ceil ( const Vec3fa& a ) { return Vec3fa(ceilf (a.x),ceilf (a.y),ceilf (a.z)); }
|
||||
//__forceinline Vec3fa trunc( const Vec3fa& a ) { return Vec3fa(truncf(a.x),truncf(a.y),truncf(a.z)); }
|
||||
__forceinline Vec3fa floor( const Vec3fa& a ) { return Vec3fa(floorf(a.x),floorf(a.y),floorf(a.z)); }
|
||||
__forceinline Vec3fa ceil ( const Vec3fa& a ) { return Vec3fa(ceilf (a.x),ceilf (a.y),ceilf (a.z)); }
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
+33
-33
@@ -51,8 +51,8 @@ namespace embree
|
||||
__forceinline Vec3ia( const int x, const int y, const int z) : m128(_mm_set_epi32(z, z, y, x)) {}
|
||||
__forceinline explicit Vec3ia( const __m128 a ) : m128(_mm_cvtps_epi32(a)) {}
|
||||
|
||||
__forceinline operator const __m128i&( void ) const { return m128; }
|
||||
__forceinline operator __m128i&( void ) { return m128; }
|
||||
__forceinline operator const __m128i&() const { return m128; }
|
||||
__forceinline operator __m128i&() { return m128; }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Constants
|
||||
@@ -76,48 +76,48 @@ namespace embree
|
||||
/// Unary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const Vec3ia operator +( const Vec3ia& a ) { return a; }
|
||||
__forceinline const Vec3ia operator -( const Vec3ia& a ) { return _mm_sub_epi32(_mm_setzero_si128(), a.m128); }
|
||||
__forceinline Vec3ia operator +( const Vec3ia& a ) { return a; }
|
||||
__forceinline Vec3ia operator -( const Vec3ia& a ) { return _mm_sub_epi32(_mm_setzero_si128(), a.m128); }
|
||||
#if defined(__SSSE3__)
|
||||
__forceinline const Vec3ia abs ( const Vec3ia& a ) { return _mm_abs_epi32(a.m128); }
|
||||
__forceinline Vec3ia abs ( const Vec3ia& a ) { return _mm_abs_epi32(a.m128); }
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Binary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const Vec3ia operator +( const Vec3ia& a, const Vec3ia& b ) { return _mm_add_epi32(a.m128, b.m128); }
|
||||
__forceinline const Vec3ia operator +( const Vec3ia& a, const int b ) { return a+Vec3ia(b); }
|
||||
__forceinline const Vec3ia operator +( const int a, const Vec3ia& b ) { return Vec3ia(a)+b; }
|
||||
__forceinline Vec3ia operator +( const Vec3ia& a, const Vec3ia& b ) { return _mm_add_epi32(a.m128, b.m128); }
|
||||
__forceinline Vec3ia operator +( const Vec3ia& a, const int b ) { return a+Vec3ia(b); }
|
||||
__forceinline Vec3ia operator +( const int a, const Vec3ia& b ) { return Vec3ia(a)+b; }
|
||||
|
||||
__forceinline const Vec3ia operator -( const Vec3ia& a, const Vec3ia& b ) { return _mm_sub_epi32(a.m128, b.m128); }
|
||||
__forceinline const Vec3ia operator -( const Vec3ia& a, const int b ) { return a-Vec3ia(b); }
|
||||
__forceinline const Vec3ia operator -( const int a, const Vec3ia& b ) { return Vec3ia(a)-b; }
|
||||
__forceinline Vec3ia operator -( const Vec3ia& a, const Vec3ia& b ) { return _mm_sub_epi32(a.m128, b.m128); }
|
||||
__forceinline Vec3ia operator -( const Vec3ia& a, const int b ) { return a-Vec3ia(b); }
|
||||
__forceinline Vec3ia operator -( const int a, const Vec3ia& b ) { return Vec3ia(a)-b; }
|
||||
|
||||
#if defined(__SSE4_1__)
|
||||
__forceinline const Vec3ia operator *( const Vec3ia& a, const Vec3ia& b ) { return _mm_mullo_epi32(a.m128, b.m128); }
|
||||
__forceinline const Vec3ia operator *( const Vec3ia& a, const int b ) { return a * Vec3ia(b); }
|
||||
__forceinline const Vec3ia operator *( const int a, const Vec3ia& b ) { return Vec3ia(a) * b; }
|
||||
__forceinline Vec3ia operator *( const Vec3ia& a, const Vec3ia& b ) { return _mm_mullo_epi32(a.m128, b.m128); }
|
||||
__forceinline Vec3ia operator *( const Vec3ia& a, const int b ) { return a * Vec3ia(b); }
|
||||
__forceinline Vec3ia operator *( const int a, const Vec3ia& b ) { return Vec3ia(a) * b; }
|
||||
#endif
|
||||
|
||||
__forceinline const Vec3ia operator &( const Vec3ia& a, const Vec3ia& b ) { return _mm_and_si128(a.m128, b.m128); }
|
||||
__forceinline const Vec3ia operator &( const Vec3ia& a, const int b ) { return a & Vec3ia(b); }
|
||||
__forceinline const Vec3ia operator &( const int a, const Vec3ia& b ) { return Vec3ia(a) & b; }
|
||||
__forceinline Vec3ia operator &( const Vec3ia& a, const Vec3ia& b ) { return _mm_and_si128(a.m128, b.m128); }
|
||||
__forceinline Vec3ia operator &( const Vec3ia& a, const int b ) { return a & Vec3ia(b); }
|
||||
__forceinline Vec3ia operator &( const int a, const Vec3ia& b ) { return Vec3ia(a) & b; }
|
||||
|
||||
__forceinline const Vec3ia operator |( const Vec3ia& a, const Vec3ia& b ) { return _mm_or_si128(a.m128, b.m128); }
|
||||
__forceinline const Vec3ia operator |( const Vec3ia& a, const int b ) { return a | Vec3ia(b); }
|
||||
__forceinline const Vec3ia operator |( const int a, const Vec3ia& b ) { return Vec3ia(a) | b; }
|
||||
__forceinline Vec3ia operator |( const Vec3ia& a, const Vec3ia& b ) { return _mm_or_si128(a.m128, b.m128); }
|
||||
__forceinline Vec3ia operator |( const Vec3ia& a, const int b ) { return a | Vec3ia(b); }
|
||||
__forceinline Vec3ia operator |( const int a, const Vec3ia& b ) { return Vec3ia(a) | b; }
|
||||
|
||||
__forceinline const Vec3ia operator ^( const Vec3ia& a, const Vec3ia& b ) { return _mm_xor_si128(a.m128, b.m128); }
|
||||
__forceinline const Vec3ia operator ^( const Vec3ia& a, const int b ) { return a ^ Vec3ia(b); }
|
||||
__forceinline const Vec3ia operator ^( const int a, const Vec3ia& b ) { return Vec3ia(a) ^ b; }
|
||||
__forceinline Vec3ia operator ^( const Vec3ia& a, const Vec3ia& b ) { return _mm_xor_si128(a.m128, b.m128); }
|
||||
__forceinline Vec3ia operator ^( const Vec3ia& a, const int b ) { return a ^ Vec3ia(b); }
|
||||
__forceinline Vec3ia operator ^( const int a, const Vec3ia& b ) { return Vec3ia(a) ^ b; }
|
||||
|
||||
__forceinline const Vec3ia operator <<( const Vec3ia& a, const int n ) { return _mm_slli_epi32(a.m128, n); }
|
||||
__forceinline const Vec3ia operator >>( const Vec3ia& a, const int n ) { return _mm_srai_epi32(a.m128, n); }
|
||||
__forceinline Vec3ia operator <<( const Vec3ia& a, const int n ) { return _mm_slli_epi32(a.m128, n); }
|
||||
__forceinline Vec3ia operator >>( const Vec3ia& a, const int n ) { return _mm_srai_epi32(a.m128, n); }
|
||||
|
||||
__forceinline const Vec3ia sll ( const Vec3ia& a, const int b ) { return _mm_slli_epi32(a.m128, b); }
|
||||
__forceinline const Vec3ia sra ( const Vec3ia& a, const int b ) { return _mm_srai_epi32(a.m128, b); }
|
||||
__forceinline const Vec3ia srl ( const Vec3ia& a, const int b ) { return _mm_srli_epi32(a.m128, b); }
|
||||
__forceinline Vec3ia sll ( const Vec3ia& a, const int b ) { return _mm_slli_epi32(a.m128, b); }
|
||||
__forceinline Vec3ia sra ( const Vec3ia& a, const int b ) { return _mm_srai_epi32(a.m128, b); }
|
||||
__forceinline Vec3ia srl ( const Vec3ia& a, const int b ) { return _mm_srli_epi32(a.m128, b); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Assignment Operators
|
||||
@@ -173,7 +173,7 @@ namespace embree
|
||||
/// Select
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const Vec3ia select( const Vec3ba& m, const Vec3ia& t, const Vec3ia& f ) {
|
||||
__forceinline Vec3ia select( const Vec3ba& m, const Vec3ia& t, const Vec3ia& f ) {
|
||||
#if defined(__SSE4_1__)
|
||||
return _mm_castps_si128(_mm_blendv_ps(_mm_castsi128_ps(f), _mm_castsi128_ps(t), m));
|
||||
#else
|
||||
@@ -182,11 +182,11 @@ namespace embree
|
||||
}
|
||||
|
||||
#if defined(__SSE4_1__)
|
||||
__forceinline const Vec3ia min( const Vec3ia& a, const Vec3ia& b ) { return _mm_min_epi32(a.m128,b.m128); }
|
||||
__forceinline const Vec3ia max( const Vec3ia& a, const Vec3ia& b ) { return _mm_max_epi32(a.m128,b.m128); }
|
||||
__forceinline Vec3ia min( const Vec3ia& a, const Vec3ia& b ) { return _mm_min_epi32(a.m128,b.m128); }
|
||||
__forceinline Vec3ia max( const Vec3ia& a, const Vec3ia& b ) { return _mm_max_epi32(a.m128,b.m128); }
|
||||
#else
|
||||
__forceinline const Vec3ia min( const Vec3ia& a, const Vec3ia& b ) { return select(lt_mask(a,b),a,b); }
|
||||
__forceinline const Vec3ia max( const Vec3ia& a, const Vec3ia& b ) { return select(gt_mask(a,b),a,b); }
|
||||
__forceinline Vec3ia min( const Vec3ia& a, const Vec3ia& b ) { return select(lt_mask(a,b),a,b); }
|
||||
__forceinline Vec3ia max( const Vec3ia& a, const Vec3ia& b ) { return select(gt_mask(a,b),a,b); }
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
+8
-8
@@ -99,15 +99,15 @@ namespace embree
|
||||
/// Ternary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<typename T> __forceinline const Vec4<T> madd ( const Vec4<T>& a, const Vec4<T>& b, const Vec4<T>& c) { return Vec4<T>( madd(a.x,b.x,c.x), madd(a.y,b.y,c.y), madd(a.z,b.z,c.z), madd(a.w,b.w,c.w)); }
|
||||
template<typename T> __forceinline const Vec4<T> msub ( const Vec4<T>& a, const Vec4<T>& b, const Vec4<T>& c) { return Vec4<T>( msub(a.x,b.x,c.x), msub(a.y,b.y,c.y), msub(a.z,b.z,c.z), msub(a.w,b.w,c.w)); }
|
||||
template<typename T> __forceinline const Vec4<T> nmadd ( const Vec4<T>& a, const Vec4<T>& b, const Vec4<T>& c) { return Vec4<T>(nmadd(a.x,b.x,c.x),nmadd(a.y,b.y,c.y),nmadd(a.z,b.z,c.z),nmadd(a.w,b.w,c.w)); }
|
||||
template<typename T> __forceinline const Vec4<T> nmsub ( const Vec4<T>& a, const Vec4<T>& b, const Vec4<T>& c) { return Vec4<T>(nmsub(a.x,b.x,c.x),nmsub(a.y,b.y,c.y),nmsub(a.z,b.z,c.z),nmsub(a.w,b.w,c.w)); }
|
||||
template<typename T> __forceinline Vec4<T> madd ( const Vec4<T>& a, const Vec4<T>& b, const Vec4<T>& c) { return Vec4<T>( madd(a.x,b.x,c.x), madd(a.y,b.y,c.y), madd(a.z,b.z,c.z), madd(a.w,b.w,c.w)); }
|
||||
template<typename T> __forceinline Vec4<T> msub ( const Vec4<T>& a, const Vec4<T>& b, const Vec4<T>& c) { return Vec4<T>( msub(a.x,b.x,c.x), msub(a.y,b.y,c.y), msub(a.z,b.z,c.z), msub(a.w,b.w,c.w)); }
|
||||
template<typename T> __forceinline Vec4<T> nmadd ( const Vec4<T>& a, const Vec4<T>& b, const Vec4<T>& c) { return Vec4<T>(nmadd(a.x,b.x,c.x),nmadd(a.y,b.y,c.y),nmadd(a.z,b.z,c.z),nmadd(a.w,b.w,c.w)); }
|
||||
template<typename T> __forceinline Vec4<T> nmsub ( const Vec4<T>& a, const Vec4<T>& b, const Vec4<T>& c) { return Vec4<T>(nmsub(a.x,b.x,c.x),nmsub(a.y,b.y,c.y),nmsub(a.z,b.z,c.z),nmsub(a.w,b.w,c.w)); }
|
||||
|
||||
template<typename T> __forceinline const Vec4<T> madd ( const T& a, const Vec4<T>& b, const Vec4<T>& c) { return Vec4<T>( madd(a,b.x,c.x), madd(a,b.y,c.y), madd(a,b.z,c.z), madd(a,b.w,c.w)); }
|
||||
template<typename T> __forceinline const Vec4<T> msub ( const T& a, const Vec4<T>& b, const Vec4<T>& c) { return Vec4<T>( msub(a,b.x,c.x), msub(a,b.y,c.y), msub(a,b.z,c.z), msub(a,b.w,c.w)); }
|
||||
template<typename T> __forceinline const Vec4<T> nmadd ( const T& a, const Vec4<T>& b, const Vec4<T>& c) { return Vec4<T>(nmadd(a,b.x,c.x),nmadd(a,b.y,c.y),nmadd(a,b.z,c.z),nmadd(a,b.w,c.w)); }
|
||||
template<typename T> __forceinline const Vec4<T> nmsub ( const T& a, const Vec4<T>& b, const Vec4<T>& c) { return Vec4<T>(nmsub(a,b.x,c.x),nmsub(a,b.y,c.y),nmsub(a,b.z,c.z),nmsub(a,b.w,c.w)); }
|
||||
template<typename T> __forceinline Vec4<T> madd ( const T& a, const Vec4<T>& b, const Vec4<T>& c) { return Vec4<T>( madd(a,b.x,c.x), madd(a,b.y,c.y), madd(a,b.z,c.z), madd(a,b.w,c.w)); }
|
||||
template<typename T> __forceinline Vec4<T> msub ( const T& a, const Vec4<T>& b, const Vec4<T>& c) { return Vec4<T>( msub(a,b.x,c.x), msub(a,b.y,c.y), msub(a,b.z,c.z), msub(a,b.w,c.w)); }
|
||||
template<typename T> __forceinline Vec4<T> nmadd ( const T& a, const Vec4<T>& b, const Vec4<T>& c) { return Vec4<T>(nmadd(a,b.x,c.x),nmadd(a,b.y,c.y),nmadd(a,b.z,c.z),nmadd(a,b.w,c.w)); }
|
||||
template<typename T> __forceinline Vec4<T> nmsub ( const T& a, const Vec4<T>& b, const Vec4<T>& c) { return Vec4<T>(nmsub(a,b.x,c.x),nmsub(a,b.y,c.y),nmsub(a,b.z,c.z),nmsub(a,b.w,c.w)); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Assignment Operators
|
||||
|
||||
+2
-2
@@ -74,8 +74,8 @@ namespace embree
|
||||
template<typename Closure>
|
||||
__forceinline void foreach2(int x0, int x1, int y0, int y1, const Closure& closure)
|
||||
{
|
||||
__aligned(64) int U[128];
|
||||
__aligned(64) int V[128];
|
||||
__aligned(64) int U[2*VSIZEX];
|
||||
__aligned(64) int V[2*VSIZEX];
|
||||
int index = 0;
|
||||
for (int y=y0; y<y1; y++) {
|
||||
const bool lasty = y+1>=y1;
|
||||
|
||||
+2
-2
@@ -24,11 +24,11 @@
|
||||
namespace embree
|
||||
{
|
||||
#if defined(__SSE4_1__)
|
||||
__forceinline __m128 blendv_ps( __m128 f, __m128 t, __m128 mask ) {
|
||||
__forceinline __m128 blendv_ps(__m128 f, __m128 t, __m128 mask) {
|
||||
return _mm_blendv_ps(f,t,mask);
|
||||
}
|
||||
#else
|
||||
__forceinline __m128 blendv_ps( __m128 f, __m128 t, __m128 mask ) {
|
||||
__forceinline __m128 blendv_ps(__m128 f, __m128 t, __m128 mask) {
|
||||
return _mm_or_ps(_mm_and_ps(mask, t), _mm_andnot_ps(mask, f));
|
||||
}
|
||||
#endif
|
||||
|
||||
+44
-42
@@ -35,18 +35,18 @@ namespace embree
|
||||
/// Constructors, Assignment & Cast Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vboold () {}
|
||||
__forceinline vboold ( const vboold4& a ) { v = a.v; }
|
||||
__forceinline vboold4& operator=( const vboold4& a ) { v = a.v; return *this; }
|
||||
__forceinline vboold() {}
|
||||
__forceinline vboold(const vboold4& a) { v = a.v; }
|
||||
__forceinline vboold4& operator =(const vboold4& a) { v = a.v; return *this; }
|
||||
|
||||
__forceinline vboold( const __m256d a ) : v(a) {}
|
||||
__forceinline vboold( const __m256i a ) : v(_mm256_castsi256_pd(a)) {}
|
||||
__forceinline vboold(__m256d a) : v(a) {}
|
||||
__forceinline vboold(__m256i a) : v(_mm256_castsi256_pd(a)) {}
|
||||
|
||||
__forceinline operator const __m256( void ) const { return _mm256_castpd_ps(v); }
|
||||
__forceinline operator const __m256i( void ) const { return _mm256_castpd_si256(v); }
|
||||
__forceinline operator const __m256d( void ) const { return v; }
|
||||
__forceinline operator const __m256() const { return _mm256_castpd_ps(v); }
|
||||
__forceinline operator const __m256i() const { return _mm256_castpd_si256(v); }
|
||||
__forceinline operator const __m256d() const { return v; }
|
||||
|
||||
__forceinline vboold ( const int a )
|
||||
__forceinline vboold(int a)
|
||||
{
|
||||
assert(a >= 0 && a <= 255);
|
||||
#if defined (__AVX2__)
|
||||
@@ -60,49 +60,49 @@ namespace embree
|
||||
#endif
|
||||
}
|
||||
|
||||
__forceinline vboold ( const __m128d a, const __m128d b) : vl(a), vh(b) {}
|
||||
__forceinline vboold(__m128d a, __m128d b) : vl(a), vh(b) {}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Constants
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vboold( FalseTy ) : v(_mm256_setzero_pd()) {}
|
||||
__forceinline vboold( TrueTy ) : v(_mm256_cmp_pd(_mm256_setzero_pd(), _mm256_setzero_pd(), _CMP_EQ_OQ)) {}
|
||||
__forceinline vboold(FalseTy) : v(_mm256_setzero_pd()) {}
|
||||
__forceinline vboold(TrueTy) : v(_mm256_cmp_pd(_mm256_setzero_pd(), _mm256_setzero_pd(), _CMP_EQ_OQ)) {}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Array Access
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline bool operator []( const size_t index ) const { assert(index < 4); return (_mm256_movemask_pd(v) >> index) & 1; }
|
||||
__forceinline long long& operator []( const size_t index ) { assert(index < 4); return i[index]; }
|
||||
__forceinline bool operator [](size_t index) const { assert(index < 4); return (_mm256_movemask_pd(v) >> index) & 1; }
|
||||
__forceinline long long& operator [](size_t index) { assert(index < 4); return i[index]; }
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Unary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vboold4 operator !( const vboold4& a ) { return _mm256_xor_pd(a, vboold4(embree::True)); }
|
||||
__forceinline vboold4 operator !(const vboold4& a) { return _mm256_xor_pd(a, vboold4(embree::True)); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Binary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vboold4 operator &( const vboold4& a, const vboold4& b ) { return _mm256_and_pd(a, b); }
|
||||
__forceinline const vboold4 operator |( const vboold4& a, const vboold4& b ) { return _mm256_or_pd (a, b); }
|
||||
__forceinline const vboold4 operator ^( const vboold4& a, const vboold4& b ) { return _mm256_xor_pd(a, b); }
|
||||
__forceinline vboold4 operator &(const vboold4& a, const vboold4& b) { return _mm256_and_pd(a, b); }
|
||||
__forceinline vboold4 operator |(const vboold4& a, const vboold4& b) { return _mm256_or_pd (a, b); }
|
||||
__forceinline vboold4 operator ^(const vboold4& a, const vboold4& b) { return _mm256_xor_pd(a, b); }
|
||||
|
||||
__forceinline vboold4 operator &=( vboold4& a, const vboold4& b ) { return a = a & b; }
|
||||
__forceinline vboold4 operator |=( vboold4& a, const vboold4& b ) { return a = a | b; }
|
||||
__forceinline vboold4 operator ^=( vboold4& a, const vboold4& b ) { return a = a ^ b; }
|
||||
__forceinline vboold4& operator &=(vboold4& a, const vboold4& b) { return a = a & b; }
|
||||
__forceinline vboold4& operator |=(vboold4& a, const vboold4& b) { return a = a | b; }
|
||||
__forceinline vboold4& operator ^=(vboold4& a, const vboold4& b) { return a = a ^ b; }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Comparison Operators + Select
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vboold4 operator !=( const vboold4& a, const vboold4& b ) { return _mm256_xor_pd(a, b); }
|
||||
__forceinline const vboold4 operator ==( const vboold4& a, const vboold4& b ) { return _mm256_xor_pd(_mm256_xor_pd(a,b),vboold4(embree::True)); }
|
||||
__forceinline vboold4 operator !=(const vboold4& a, const vboold4& b) { return _mm256_xor_pd(a, b); }
|
||||
__forceinline vboold4 operator ==(const vboold4& a, const vboold4& b) { return _mm256_xor_pd(_mm256_xor_pd(a,b),vboold4(embree::True)); }
|
||||
|
||||
__forceinline const vboold4 select( const vboold4& mask, const vboold4& t, const vboold4& f ) {
|
||||
__forceinline vboold4 select(const vboold4& mask, const vboold4& t, const vboold4& f) {
|
||||
return _mm256_blendv_pd(f, t, mask);
|
||||
}
|
||||
|
||||
@@ -110,17 +110,19 @@ namespace embree
|
||||
/// Movement/Shifting/Shuffling Functions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vboold4 unpacklo( const vboold4& a, const vboold4& b ) { return _mm256_unpacklo_pd(a.v, b.v); }
|
||||
__forceinline vboold4 unpackhi( const vboold4& a, const vboold4& b ) { return _mm256_unpackhi_pd(a.v, b.v); }
|
||||
__forceinline vboold4 unpacklo(const vboold4& a, const vboold4& b) { return _mm256_unpacklo_pd(a, b); }
|
||||
__forceinline vboold4 unpackhi(const vboold4& a, const vboold4& b) { return _mm256_unpackhi_pd(a, b); }
|
||||
|
||||
|
||||
#if defined(__AVX2__)
|
||||
template<size_t i0, size_t i1, size_t i2, size_t i3> __forceinline const vboold4 shuffle( const vboold4& a ) {
|
||||
return _mm256_permute4x64_pd(a, _MM_SHUFFLE(i3, i2, i1, i0));
|
||||
template<int i0, int i1, int i2, int i3>
|
||||
__forceinline vboold4 shuffle(const vboold4& v) {
|
||||
return _mm256_permute4x64_pd(v, _MM_SHUFFLE(i3, i2, i1, i0));
|
||||
}
|
||||
|
||||
template<size_t i> __forceinline const vboold4 shuffle( const vboold4& a ) {
|
||||
return _mm256_permute4x64_pd(a, _MM_SHUFFLE(i, i, i, i));
|
||||
template<int i>
|
||||
__forceinline vboold4 shuffle(const vboold4& v) {
|
||||
return _mm256_permute4x64_pd(v, _MM_SHUFFLE(i, i, i, i));
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -129,33 +131,33 @@ namespace embree
|
||||
/// Reduction Operations
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline bool reduce_and( const vboold4& a ) { return _mm256_movemask_pd(a) == (unsigned int)0xf; }
|
||||
__forceinline bool reduce_or ( const vboold4& a ) { return !_mm256_testz_pd(a,a); }
|
||||
__forceinline bool reduce_and(const vboold4& a) { return _mm256_movemask_pd(a) == (unsigned int)0xf; }
|
||||
__forceinline bool reduce_or (const vboold4& a) { return !_mm256_testz_pd(a,a); }
|
||||
|
||||
__forceinline bool all ( const vboold4& a ) { return _mm256_movemask_pd(a) == (unsigned int)0xf; }
|
||||
__forceinline bool any ( const vboold4& a ) { return !_mm256_testz_pd(a,a); }
|
||||
__forceinline bool none ( const vboold4& a ) { return _mm256_testz_pd(a,a) != 0; }
|
||||
__forceinline bool all (const vboold4& a) { return _mm256_movemask_pd(a) == (unsigned int)0xf; }
|
||||
__forceinline bool any (const vboold4& a) { return !_mm256_testz_pd(a,a); }
|
||||
__forceinline bool none(const vboold4& a) { return _mm256_testz_pd(a,a) != 0; }
|
||||
|
||||
__forceinline bool all ( const vboold4& valid, const vboold4& b ) { return all((!valid) | b); }
|
||||
__forceinline bool any ( const vboold4& valid, const vboold4& b ) { return any( valid & b); }
|
||||
__forceinline bool none ( const vboold4& valid, const vboold4& b ) { return none(valid & b); }
|
||||
__forceinline bool all (const vboold4& valid, const vboold4& b) { return all((!valid) | b); }
|
||||
__forceinline bool any (const vboold4& valid, const vboold4& b) { return any(valid & b); }
|
||||
__forceinline bool none(const vboold4& valid, const vboold4& b) { return none(valid & b); }
|
||||
|
||||
__forceinline unsigned int movemask( const vboold4& a ) { return _mm256_movemask_pd(a); }
|
||||
__forceinline size_t popcnt ( const vboold4& a ) { return __popcnt((size_t)_mm256_movemask_pd(a)); }
|
||||
__forceinline unsigned int movemask(const vboold4& a) { return _mm256_movemask_pd(a); }
|
||||
__forceinline size_t popcnt (const vboold4& a) { return __popcnt((size_t)_mm256_movemask_pd(a)); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Get/Set Functions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline bool get(const vboold4& a, size_t index) { return a[index]; }
|
||||
__forceinline void set (vboold4& a, size_t index) { a[index] = -1; }
|
||||
__forceinline void set (vboold4& a, size_t index) { a[index] = -1; }
|
||||
__forceinline void clear(vboold4& a, size_t index) { a[index] = 0; }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Output Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& cout, const vboold4& a) {
|
||||
inline std::ostream& operator <<(std::ostream& cout, const vboold4& a) {
|
||||
return cout << "<" << a[0] << ", " << a[1] << ", " << a[2] << ", " << a[3] << ", "
|
||||
<< a[4] << ", " << a[5] << ", " << a[6] << ", " << a[7] << ">";
|
||||
}
|
||||
|
||||
@@ -33,8 +33,8 @@ namespace embree
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vboold() {}
|
||||
__forceinline vboold(const vboold4 &t) { v = t.v; }
|
||||
__forceinline vboold4& operator=(const vboold4 &f) { v = f.v; return *this; }
|
||||
__forceinline vboold(const vboold4& t) { v = t.v; }
|
||||
__forceinline vboold4& operator =(const vboold4& f) { v = f.v; return *this; }
|
||||
|
||||
__forceinline vboold(const __mmask8 &t) { v = t; }
|
||||
__forceinline operator __mmask8() const { return v; }
|
||||
@@ -62,42 +62,42 @@ namespace embree
|
||||
/// Constants
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vboold( FalseTy ) : v(0x0) {}
|
||||
__forceinline vboold( TrueTy ) : v(0xf) {}
|
||||
__forceinline vboold(FalseTy) : v(0x0) {}
|
||||
__forceinline vboold(TrueTy) : v(0xf) {}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Unary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vboold4 operator!(const vboold4 &a) { return _mm512_kandn(a, 0xf); }
|
||||
__forceinline vboold4 operator !(const vboold4& a) { return _mm512_kandn(a, 0xf); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Binary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vboold4 operator&(const vboold4 &a, const vboold4 &b) { return _mm512_kand(a, b); }
|
||||
__forceinline vboold4 operator|(const vboold4 &a, const vboold4 &b) { return _mm512_kor(a, b); }
|
||||
__forceinline vboold4 operator^(const vboold4 &a, const vboold4 &b) { return _mm512_kxor(a, b); }
|
||||
__forceinline vboold4 operator &(const vboold4& a, const vboold4& b) { return _mm512_kand(a, b); }
|
||||
__forceinline vboold4 operator |(const vboold4& a, const vboold4& b) { return _mm512_kor(a, b); }
|
||||
__forceinline vboold4 operator ^(const vboold4& a, const vboold4& b) { return _mm512_kxor(a, b); }
|
||||
|
||||
__forceinline vboold4 andn(const vboold4 &a, const vboold4 &b) { return _mm512_kandn(b, a); }
|
||||
__forceinline vboold4 andn(const vboold4& a, const vboold4& b) { return _mm512_kandn(b, a); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Assignment Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vboold4 operator &=( vboold4& a, const vboold4& b ) { return a = a & b; }
|
||||
__forceinline const vboold4 operator |=( vboold4& a, const vboold4& b ) { return a = a | b; }
|
||||
__forceinline const vboold4 operator ^=( vboold4& a, const vboold4& b ) { return a = a ^ b; }
|
||||
__forceinline vboold4& operator &=(vboold4& a, const vboold4& b) { return a = a & b; }
|
||||
__forceinline vboold4& operator |=(vboold4& a, const vboold4& b) { return a = a | b; }
|
||||
__forceinline vboold4& operator ^=(vboold4& a, const vboold4& b) { return a = a ^ b; }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Comparison Operators + Select
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vboold4 operator !=( const vboold4& a, const vboold4& b ) { return _mm512_kxor(a, b); }
|
||||
__forceinline const vboold4 operator ==( const vboold4& a, const vboold4& b ) { return _mm512_kand(_mm512_kxnor(a, b), 0xf); }
|
||||
__forceinline vboold4 operator !=(const vboold4& a, const vboold4& b) { return _mm512_kxor(a, b); }
|
||||
__forceinline vboold4 operator ==(const vboold4& a, const vboold4& b) { return _mm512_kand(_mm512_kxnor(a, b), 0xf); }
|
||||
|
||||
__forceinline vboold4 select (const vboold4 &s, const vboold4 &a, const vboold4 &b) {
|
||||
__forceinline vboold4 select(const vboold4& s, const vboold4& a, const vboold4& b) {
|
||||
return _mm512_kor(_mm512_kand(s, a), _mm512_kandn(s, b));
|
||||
}
|
||||
|
||||
@@ -105,22 +105,22 @@ namespace embree
|
||||
/// Reduction Operations
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline int all (const vboold4 &a) { return a.v == 0xf; }
|
||||
__forceinline int any (const vboold4 &a) { return _mm512_kortestz(a, a) == 0; }
|
||||
__forceinline int none(const vboold4 &a) { return _mm512_kortestz(a, a) != 0; }
|
||||
__forceinline int all (const vboold4& a) { return a.v == 0xf; }
|
||||
__forceinline int any (const vboold4& a) { return _mm512_kortestz(a, a) == 0; }
|
||||
__forceinline int none(const vboold4& a) { return _mm512_kortestz(a, a) != 0; }
|
||||
|
||||
__forceinline int all ( const vboold4& valid, const vboold4& b ) { return all((!valid) | b); }
|
||||
__forceinline int any ( const vboold4& valid, const vboold4& b ) { return any( valid & b); }
|
||||
__forceinline int none( const vboold4& valid, const vboold4& b ) { return none(valid & b); }
|
||||
__forceinline int all (const vboold4& valid, const vboold4& b) { return all((!valid) | b); }
|
||||
__forceinline int any (const vboold4& valid, const vboold4& b) { return any(valid & b); }
|
||||
__forceinline int none(const vboold4& valid, const vboold4& b) { return none(valid & b); }
|
||||
|
||||
__forceinline size_t movemask( const vboold4& a ) { return _mm512_kmov(a); }
|
||||
__forceinline size_t popcnt ( const vboold4& a ) { return __popcnt(a.v); }
|
||||
__forceinline size_t movemask(const vboold4& a) { return _mm512_kmov(a); }
|
||||
__forceinline size_t popcnt (const vboold4& a) { return __popcnt(a.v); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Conversion Operations
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline unsigned int toInt(const vboold4 &a) { return mm512_mask2int(a); }
|
||||
__forceinline unsigned int toInt(const vboold4& a) { return mm512_mask2int(a); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Get/Set Functions
|
||||
@@ -134,7 +134,7 @@ namespace embree
|
||||
/// Output Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& cout, const vboold4& a)
|
||||
inline std::ostream& operator <<(std::ostream& cout, const vboold4& a)
|
||||
{
|
||||
cout << "<";
|
||||
for (size_t i=0; i<4; i++) {
|
||||
|
||||
@@ -33,10 +33,10 @@ namespace embree
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vboold() {}
|
||||
__forceinline vboold(const vboold8 &t) { v = t.v; }
|
||||
__forceinline vboold8& operator=(const vboold8 &f) { v = f.v; return *this; }
|
||||
__forceinline vboold(const vboold8& t) { v = t.v; }
|
||||
__forceinline vboold8& operator =(const vboold8& f) { v = f.v; return *this; }
|
||||
|
||||
__forceinline vboold(const __mmask8 &t) { v = t; }
|
||||
__forceinline vboold(const __mmask8& t) { v = t; }
|
||||
__forceinline operator __mmask8() const { return v; }
|
||||
|
||||
__forceinline vboold(bool b) { v = b ? 0xff : 0x00; }
|
||||
@@ -70,42 +70,42 @@ namespace embree
|
||||
/// Constants
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vboold( FalseTy ) : v(0x00) {}
|
||||
__forceinline vboold( TrueTy ) : v(0xff) {}
|
||||
__forceinline vboold(FalseTy) : v(0x00) {}
|
||||
__forceinline vboold(TrueTy) : v(0xff) {}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Unary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vboold8 operator!(const vboold8 &a) { return _mm512_knot(a); }
|
||||
__forceinline vboold8 operator !(const vboold8& a) { return _mm512_knot(a); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Binary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vboold8 operator&(const vboold8 &a, const vboold8 &b) { return _mm512_kand(a, b); }
|
||||
__forceinline vboold8 operator|(const vboold8 &a, const vboold8 &b) { return _mm512_kor(a, b); }
|
||||
__forceinline vboold8 operator^(const vboold8 &a, const vboold8 &b) { return _mm512_kxor(a, b); }
|
||||
__forceinline vboold8 operator &(const vboold8& a, const vboold8& b) { return _mm512_kand(a, b); }
|
||||
__forceinline vboold8 operator |(const vboold8& a, const vboold8& b) { return _mm512_kor(a, b); }
|
||||
__forceinline vboold8 operator ^(const vboold8& a, const vboold8& b) { return _mm512_kxor(a, b); }
|
||||
|
||||
__forceinline vboold8 andn(const vboold8 &a, const vboold8 &b) { return _mm512_kandn(b, a); }
|
||||
__forceinline vboold8 andn(const vboold8& a, const vboold8& b) { return _mm512_kandn(b, a); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Assignment Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vboold8 operator &=( vboold8& a, const vboold8& b ) { return a = a & b; }
|
||||
__forceinline const vboold8 operator |=( vboold8& a, const vboold8& b ) { return a = a | b; }
|
||||
__forceinline const vboold8 operator ^=( vboold8& a, const vboold8& b ) { return a = a ^ b; }
|
||||
__forceinline vboold8& operator &=(vboold8& a, const vboold8& b) { return a = a & b; }
|
||||
__forceinline vboold8& operator |=(vboold8& a, const vboold8& b) { return a = a | b; }
|
||||
__forceinline vboold8& operator ^=(vboold8& a, const vboold8& b) { return a = a ^ b; }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Comparison Operators + Select
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vboold8 operator !=( const vboold8& a, const vboold8& b ) { return _mm512_kxor(a, b); }
|
||||
__forceinline const vboold8 operator ==( const vboold8& a, const vboold8& b ) { return _mm512_kxnor(a, b); }
|
||||
__forceinline vboold8 operator !=(const vboold8& a, const vboold8& b) { return _mm512_kxor(a, b); }
|
||||
__forceinline vboold8 operator ==(const vboold8& a, const vboold8& b) { return _mm512_kxnor(a, b); }
|
||||
|
||||
__forceinline vboold8 select(const vboold8 &s, const vboold8 &a, const vboold8 &b) {
|
||||
__forceinline vboold8 select(const vboold8& s, const vboold8& a, const vboold8& b) {
|
||||
return _mm512_kor(_mm512_kand(s, a), _mm512_kandn(s, b));
|
||||
}
|
||||
|
||||
@@ -113,22 +113,22 @@ namespace embree
|
||||
/// Reduction Operations
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline int all (const vboold8 &a) { return a.v == 0xff; }
|
||||
__forceinline int any (const vboold8 &a) { return _mm512_kortestz(a, a) == 0; }
|
||||
__forceinline int none(const vboold8 &a) { return _mm512_kortestz(a, a) != 0; }
|
||||
__forceinline int all (const vboold8& a) { return a.v == 0xff; }
|
||||
__forceinline int any (const vboold8& a) { return _mm512_kortestz(a, a) == 0; }
|
||||
__forceinline int none(const vboold8& a) { return _mm512_kortestz(a, a) != 0; }
|
||||
|
||||
__forceinline int all ( const vboold8& valid, const vboold8& b ) { return all((!valid) | b); }
|
||||
__forceinline int any ( const vboold8& valid, const vboold8& b ) { return any( valid & b); }
|
||||
__forceinline int none( const vboold8& valid, const vboold8& b ) { return none(valid & b); }
|
||||
__forceinline int all (const vboold8& valid, const vboold8& b) { return all((!valid) | b); }
|
||||
__forceinline int any (const vboold8& valid, const vboold8& b) { return any(valid & b); }
|
||||
__forceinline int none(const vboold8& valid, const vboold8& b) { return none(valid & b); }
|
||||
|
||||
__forceinline size_t movemask( const vboold8& a ) { return _mm512_kmov(a); }
|
||||
__forceinline size_t popcnt ( const vboold8& a ) { return __popcnt(a.v); }
|
||||
__forceinline size_t movemask(const vboold8& a) { return _mm512_kmov(a); }
|
||||
__forceinline size_t popcnt (const vboold8& a) { return __popcnt(a.v); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Conversion Operations
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline unsigned int toInt(const vboold8 &a) { return mm512_mask2int(a); }
|
||||
__forceinline unsigned int toInt(const vboold8& a) { return mm512_mask2int(a); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Get/Set Functions
|
||||
@@ -142,7 +142,7 @@ namespace embree
|
||||
/// Output Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& cout, const vboold8& a)
|
||||
inline std::ostream& operator <<(std::ostream& cout, const vboold8& a)
|
||||
{
|
||||
cout << "<";
|
||||
for (size_t i=0; i<8; i++) {
|
||||
|
||||
@@ -34,15 +34,15 @@ namespace embree
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vboolf() {}
|
||||
__forceinline vboolf(const vboolf16 &t) { v = t.v; }
|
||||
__forceinline vboolf16& operator=(const vboolf16 &f) { v = f.v; return *this; }
|
||||
__forceinline vboolf(const vboolf16& t) { v = t.v; }
|
||||
__forceinline vboolf16& operator =(const vboolf16& f) { v = f.v; return *this; }
|
||||
|
||||
__forceinline vboolf(const __mmask16 &t) { v = t; }
|
||||
__forceinline operator __mmask16 () const { return v; }
|
||||
__forceinline vboolf(const __mmask16& t) { v = t; }
|
||||
__forceinline operator __mmask16() const { return v; }
|
||||
|
||||
__forceinline vboolf(bool b) { v = b ? 0xFFFF : 0x0000; }
|
||||
__forceinline vboolf(int t ) { v = (__mmask16)t; }
|
||||
__forceinline vboolf(unsigned int t ) { v = (__mmask16)t; }
|
||||
__forceinline vboolf(int t) { v = (__mmask16)t; }
|
||||
__forceinline vboolf(unsigned int t) { v = (__mmask16)t; }
|
||||
|
||||
/* return int8 mask */
|
||||
__forceinline __m128i mask8() const {
|
||||
@@ -71,14 +71,14 @@ namespace embree
|
||||
/// Constants
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vboolf( FalseTy ) : v(0x0000) {}
|
||||
__forceinline vboolf( TrueTy ) : v(0xffff) {}
|
||||
__forceinline vboolf(FalseTy) : v(0x0000) {}
|
||||
__forceinline vboolf(TrueTy) : v(0xffff) {}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Array Access
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline bool operator []( const size_t index ) const {
|
||||
__forceinline bool operator [](size_t index) const {
|
||||
assert(index < 16); return (mm512_mask2int(v) >> index) & 1;
|
||||
}
|
||||
};
|
||||
@@ -87,34 +87,34 @@ namespace embree
|
||||
/// Unary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vboolf16 operator!(const vboolf16 &a) { return _mm512_knot(a); }
|
||||
__forceinline vboolf16 operator !(const vboolf16& a) { return _mm512_knot(a); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Binary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vboolf16 operator&(const vboolf16 &a, const vboolf16 &b) { return _mm512_kand(a,b); }
|
||||
__forceinline vboolf16 operator|(const vboolf16 &a, const vboolf16 &b) { return _mm512_kor(a,b); }
|
||||
__forceinline vboolf16 operator^(const vboolf16 &a, const vboolf16 &b) { return _mm512_kxor(a,b); }
|
||||
__forceinline vboolf16 operator &(const vboolf16& a, const vboolf16& b) { return _mm512_kand(a,b); }
|
||||
__forceinline vboolf16 operator |(const vboolf16& a, const vboolf16& b) { return _mm512_kor(a,b); }
|
||||
__forceinline vboolf16 operator ^(const vboolf16& a, const vboolf16& b) { return _mm512_kxor(a,b); }
|
||||
|
||||
__forceinline vboolf16 andn(const vboolf16 &a, const vboolf16 &b) { return _mm512_kandn(b,a); }
|
||||
__forceinline vboolf16 andn(const vboolf16& a, const vboolf16& b) { return _mm512_kandn(b,a); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Assignment Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vboolf16 operator &=( vboolf16& a, const vboolf16& b ) { return a = a & b; }
|
||||
__forceinline const vboolf16 operator |=( vboolf16& a, const vboolf16& b ) { return a = a | b; }
|
||||
__forceinline const vboolf16 operator ^=( vboolf16& a, const vboolf16& b ) { return a = a ^ b; }
|
||||
__forceinline vboolf16& operator &=(vboolf16& a, const vboolf16& b) { return a = a & b; }
|
||||
__forceinline vboolf16& operator |=(vboolf16& a, const vboolf16& b) { return a = a | b; }
|
||||
__forceinline vboolf16& operator ^=(vboolf16& a, const vboolf16& b) { return a = a ^ b; }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Comparison Operators + Select
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vboolf16 operator !=( const vboolf16& a, const vboolf16& b ) { return _mm512_kxor(a, b); }
|
||||
__forceinline const vboolf16 operator ==( const vboolf16& a, const vboolf16& b ) { return _mm512_kxnor(a, b); }
|
||||
__forceinline vboolf16 operator !=(const vboolf16& a, const vboolf16& b) { return _mm512_kxor(a, b); }
|
||||
__forceinline vboolf16 operator ==(const vboolf16& a, const vboolf16& b) { return _mm512_kxnor(a, b); }
|
||||
|
||||
__forceinline vboolf16 select (const vboolf16 &s, const vboolf16 &a, const vboolf16 &b) {
|
||||
__forceinline vboolf16 select(const vboolf16& s, const vboolf16& a, const vboolf16& b) {
|
||||
return _mm512_kor(_mm512_kand(s,a),_mm512_kandn(s,b));
|
||||
}
|
||||
|
||||
@@ -122,23 +122,23 @@ namespace embree
|
||||
/// Reduction Operations
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline int all (const vboolf16 &a) { return _mm512_kortestc(a,a) != 0; }
|
||||
__forceinline int any (const vboolf16 &a) { return _mm512_kortestz(a,a) == 0; }
|
||||
__forceinline int none(const vboolf16 &a) { return _mm512_kortestz(a,a) != 0; }
|
||||
__forceinline int all (const vboolf16& a) { return _mm512_kortestc(a,a) != 0; }
|
||||
__forceinline int any (const vboolf16& a) { return _mm512_kortestz(a,a) == 0; }
|
||||
__forceinline int none(const vboolf16& a) { return _mm512_kortestz(a,a) != 0; }
|
||||
|
||||
__forceinline int all ( const vboolf16& valid, const vboolf16& b ) { return all((!valid) | b); }
|
||||
__forceinline int any ( const vboolf16& valid, const vboolf16& b ) { return any( valid & b); }
|
||||
__forceinline int none( const vboolf16& valid, const vboolf16& b ) { return none(valid & b); }
|
||||
__forceinline int all (const vboolf16& valid, const vboolf16& b) { return all((!valid) | b); }
|
||||
__forceinline int any (const vboolf16& valid, const vboolf16& b) { return any(valid & b); }
|
||||
__forceinline int none(const vboolf16& valid, const vboolf16& b) { return none(valid & b); }
|
||||
|
||||
__forceinline size_t movemask( const vboolf16& a ) { return _mm512_kmov(a); }
|
||||
__forceinline size_t popcnt ( const vboolf16& a ) { return __popcnt(a.v); }
|
||||
__forceinline size_t movemask(const vboolf16& a) { return _mm512_kmov(a); }
|
||||
__forceinline size_t popcnt (const vboolf16& a) { return __popcnt(a.v); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Convertion Operations
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline unsigned int toInt (const vboolf16 &a) { return mm512_mask2int(a); }
|
||||
__forceinline vboolf16 toMask(const int &a) { return mm512_int2mask(a); }
|
||||
__forceinline unsigned int toInt (const vboolf16& a) { return mm512_mask2int(a); }
|
||||
__forceinline vboolf16 toMask(const int& a) { return mm512_int2mask(a); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Get/Set Functions
|
||||
@@ -152,7 +152,7 @@ namespace embree
|
||||
/// Output Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& cout, const vboolf16& a)
|
||||
inline std::ostream& operator <<(std::ostream& cout, const vboolf16& a)
|
||||
{
|
||||
cout << "<";
|
||||
for (size_t i=0; i<16; i++) {
|
||||
|
||||
@@ -33,8 +33,8 @@ namespace embree
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vboolf() {}
|
||||
__forceinline vboolf(const vboolf4 &t) { v = t.v; }
|
||||
__forceinline vboolf4& operator=(const vboolf4 &f) { v = f.v; return *this; }
|
||||
__forceinline vboolf(const vboolf4& t) { v = t.v; }
|
||||
__forceinline vboolf4& operator =(const vboolf4& f) { v = f.v; return *this; }
|
||||
|
||||
__forceinline vboolf(const __mmask8 &t) { v = t; }
|
||||
__forceinline operator __mmask8() const { return v; }
|
||||
@@ -62,42 +62,42 @@ namespace embree
|
||||
/// Constants
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vboolf( FalseTy ) : v(0x0) {}
|
||||
__forceinline vboolf( TrueTy ) : v(0xf) {}
|
||||
__forceinline vboolf(FalseTy) : v(0x0) {}
|
||||
__forceinline vboolf(TrueTy) : v(0xf) {}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Unary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vboolf4 operator!(const vboolf4 &a) { return _mm512_kandn(a, 0xf); }
|
||||
__forceinline vboolf4 operator !(const vboolf4& a) { return _mm512_kandn(a, 0xf); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Binary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vboolf4 operator&(const vboolf4 &a, const vboolf4 &b) { return _mm512_kand(a, b); }
|
||||
__forceinline vboolf4 operator|(const vboolf4 &a, const vboolf4 &b) { return _mm512_kor(a, b); }
|
||||
__forceinline vboolf4 operator^(const vboolf4 &a, const vboolf4 &b) { return _mm512_kxor(a, b); }
|
||||
__forceinline vboolf4 operator &(const vboolf4& a, const vboolf4& b) { return _mm512_kand(a, b); }
|
||||
__forceinline vboolf4 operator |(const vboolf4& a, const vboolf4& b) { return _mm512_kor(a, b); }
|
||||
__forceinline vboolf4 operator ^(const vboolf4& a, const vboolf4& b) { return _mm512_kxor(a, b); }
|
||||
|
||||
__forceinline vboolf4 andn(const vboolf4 &a, const vboolf4 &b) { return _mm512_kandn(b, a); }
|
||||
__forceinline vboolf4 andn(const vboolf4& a, const vboolf4& b) { return _mm512_kandn(b, a); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Assignment Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vboolf4 operator &=( vboolf4& a, const vboolf4& b ) { return a = a & b; }
|
||||
__forceinline const vboolf4 operator |=( vboolf4& a, const vboolf4& b ) { return a = a | b; }
|
||||
__forceinline const vboolf4 operator ^=( vboolf4& a, const vboolf4& b ) { return a = a ^ b; }
|
||||
__forceinline vboolf4& operator &=(vboolf4& a, const vboolf4& b) { return a = a & b; }
|
||||
__forceinline vboolf4& operator |=(vboolf4& a, const vboolf4& b) { return a = a | b; }
|
||||
__forceinline vboolf4& operator ^=(vboolf4& a, const vboolf4& b) { return a = a ^ b; }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Comparison Operators + Select
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vboolf4 operator !=( const vboolf4& a, const vboolf4& b ) { return _mm512_kxor(a, b); }
|
||||
__forceinline const vboolf4 operator ==( const vboolf4& a, const vboolf4& b ) { return _mm512_kand(_mm512_kxnor(a, b), 0xf); }
|
||||
__forceinline vboolf4 operator !=(const vboolf4& a, const vboolf4& b) { return _mm512_kxor(a, b); }
|
||||
__forceinline vboolf4 operator ==(const vboolf4& a, const vboolf4& b) { return _mm512_kand(_mm512_kxnor(a, b), 0xf); }
|
||||
|
||||
__forceinline vboolf4 select (const vboolf4 &s, const vboolf4 &a, const vboolf4 &b) {
|
||||
__forceinline vboolf4 select(const vboolf4& s, const vboolf4& a, const vboolf4& b) {
|
||||
return _mm512_kor(_mm512_kand(s, a), _mm512_kandn(s, b));
|
||||
}
|
||||
|
||||
@@ -105,22 +105,22 @@ namespace embree
|
||||
/// Reduction Operations
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline int all (const vboolf4 &a) { return a.v == 0xf; }
|
||||
__forceinline int any (const vboolf4 &a) { return _mm512_kortestz(a, a) == 0; }
|
||||
__forceinline int none(const vboolf4 &a) { return _mm512_kortestz(a, a) != 0; }
|
||||
__forceinline int all (const vboolf4& a) { return a.v == 0xf; }
|
||||
__forceinline int any (const vboolf4& a) { return _mm512_kortestz(a, a) == 0; }
|
||||
__forceinline int none(const vboolf4& a) { return _mm512_kortestz(a, a) != 0; }
|
||||
|
||||
__forceinline int all ( const vboolf4& valid, const vboolf4& b ) { return all((!valid) | b); }
|
||||
__forceinline int any ( const vboolf4& valid, const vboolf4& b ) { return any( valid & b); }
|
||||
__forceinline int none( const vboolf4& valid, const vboolf4& b ) { return none(valid & b); }
|
||||
__forceinline int all (const vboolf4& valid, const vboolf4& b) { return all((!valid) | b); }
|
||||
__forceinline int any (const vboolf4& valid, const vboolf4& b) { return any(valid & b); }
|
||||
__forceinline int none(const vboolf4& valid, const vboolf4& b) { return none(valid & b); }
|
||||
|
||||
__forceinline size_t movemask( const vboolf4& a ) { return _mm512_kmov(a); }
|
||||
__forceinline size_t popcnt ( const vboolf4& a ) { return __popcnt(a.v); }
|
||||
__forceinline size_t movemask(const vboolf4& a) { return _mm512_kmov(a); }
|
||||
__forceinline size_t popcnt (const vboolf4& a) { return __popcnt(a.v); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Conversion Operations
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline unsigned int toInt(const vboolf4 &a) { return mm512_mask2int(a); }
|
||||
__forceinline unsigned int toInt(const vboolf4& a) { return mm512_mask2int(a); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Get/Set Functions
|
||||
@@ -134,7 +134,7 @@ namespace embree
|
||||
/// Output Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& cout, const vboolf4& a)
|
||||
inline std::ostream& operator <<(std::ostream& cout, const vboolf4& a)
|
||||
{
|
||||
cout << "<";
|
||||
for (size_t i=0; i<4; i++) {
|
||||
|
||||
+54
-51
@@ -33,23 +33,23 @@ namespace embree
|
||||
/// Constructors, Assignment & Cast Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vboolf ( ) {}
|
||||
__forceinline vboolf ( const vboolf4& other ) { v = other.v; }
|
||||
__forceinline vboolf4& operator=( const vboolf4& other ) { v = other.v; return *this; }
|
||||
__forceinline vboolf() {}
|
||||
__forceinline vboolf(const vboolf4& other) { v = other.v; }
|
||||
__forceinline vboolf4& operator =(const vboolf4& other) { v = other.v; return *this; }
|
||||
|
||||
__forceinline vboolf( const __m128 input ) : v(input) {}
|
||||
__forceinline operator const __m128&( void ) const { return v; }
|
||||
__forceinline operator const __m128i( void ) const { return _mm_castps_si128(v); }
|
||||
__forceinline operator const __m128d( void ) const { return _mm_castps_pd(v); }
|
||||
__forceinline vboolf(__m128 input) : v(input) {}
|
||||
__forceinline operator const __m128&() const { return v; }
|
||||
__forceinline operator const __m128i() const { return _mm_castps_si128(v); }
|
||||
__forceinline operator const __m128d() const { return _mm_castps_pd(v); }
|
||||
|
||||
__forceinline vboolf( bool a )
|
||||
__forceinline vboolf(bool a)
|
||||
: v(_mm_lookupmask_ps[(size_t(a) << 3) | (size_t(a) << 2) | (size_t(a) << 1) | size_t(a)]) {}
|
||||
__forceinline vboolf( bool a, bool b )
|
||||
__forceinline vboolf(bool a, bool b)
|
||||
: v(_mm_lookupmask_ps[(size_t(b) << 3) | (size_t(a) << 2) | (size_t(b) << 1) | size_t(a)]) {}
|
||||
__forceinline vboolf( bool a, bool b, bool c, bool d )
|
||||
__forceinline vboolf(bool a, bool b, bool c, bool d)
|
||||
: v(_mm_lookupmask_ps[(size_t(d) << 3) | (size_t(c) << 2) | (size_t(b) << 1) | size_t(a)]) {}
|
||||
__forceinline vboolf( int mask ) { assert(mask >= 0 && mask < 16); v = _mm_lookupmask_ps[mask]; }
|
||||
__forceinline vboolf( unsigned mask ) { assert(mask >= 0 && mask < 16); v = _mm_lookupmask_ps[mask]; }
|
||||
__forceinline vboolf(int mask) { assert(mask >= 0 && mask < 16); v = _mm_lookupmask_ps[mask]; }
|
||||
__forceinline vboolf(unsigned int mask) { assert(mask < 16); v = _mm_lookupmask_ps[mask]; }
|
||||
|
||||
/* return int32 mask */
|
||||
__forceinline __m128i mask32() const {
|
||||
@@ -60,47 +60,47 @@ namespace embree
|
||||
/// Constants
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vboolf( FalseTy ) : v(_mm_setzero_ps()) {}
|
||||
__forceinline vboolf( TrueTy ) : v(_mm_castsi128_ps(_mm_cmpeq_epi32(_mm_setzero_si128(), _mm_setzero_si128()))) {}
|
||||
__forceinline vboolf(FalseTy) : v(_mm_setzero_ps()) {}
|
||||
__forceinline vboolf(TrueTy) : v(_mm_castsi128_ps(_mm_cmpeq_epi32(_mm_setzero_si128(), _mm_setzero_si128()))) {}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Array Access
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline bool operator []( const size_t index ) const { assert(index < 4); return (_mm_movemask_ps(v) >> index) & 1; }
|
||||
__forceinline int& operator []( const size_t index ) { assert(index < 4); return i[index]; }
|
||||
__forceinline bool operator [](size_t index) const { assert(index < 4); return (_mm_movemask_ps(v) >> index) & 1; }
|
||||
__forceinline int& operator [](size_t index) { assert(index < 4); return i[index]; }
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Unary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vboolf4 operator !( const vboolf4& a ) { return _mm_xor_ps(a, vboolf4(embree::True)); }
|
||||
__forceinline vboolf4 operator !(const vboolf4& a) { return _mm_xor_ps(a, vboolf4(embree::True)); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Binary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vboolf4 operator &( const vboolf4& a, const vboolf4& b ) { return _mm_and_ps(a, b); }
|
||||
__forceinline const vboolf4 operator |( const vboolf4& a, const vboolf4& b ) { return _mm_or_ps (a, b); }
|
||||
__forceinline const vboolf4 operator ^( const vboolf4& a, const vboolf4& b ) { return _mm_xor_ps(a, b); }
|
||||
__forceinline vboolf4 operator &(const vboolf4& a, const vboolf4& b) { return _mm_and_ps(a, b); }
|
||||
__forceinline vboolf4 operator |(const vboolf4& a, const vboolf4& b) { return _mm_or_ps (a, b); }
|
||||
__forceinline vboolf4 operator ^(const vboolf4& a, const vboolf4& b) { return _mm_xor_ps(a, b); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Assignment Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vboolf4 operator &=( vboolf4& a, const vboolf4& b ) { return a = a & b; }
|
||||
__forceinline const vboolf4 operator |=( vboolf4& a, const vboolf4& b ) { return a = a | b; }
|
||||
__forceinline const vboolf4 operator ^=( vboolf4& a, const vboolf4& b ) { return a = a ^ b; }
|
||||
__forceinline vboolf4& operator &=(vboolf4& a, const vboolf4& b) { return a = a & b; }
|
||||
__forceinline vboolf4& operator |=(vboolf4& a, const vboolf4& b) { return a = a | b; }
|
||||
__forceinline vboolf4& operator ^=(vboolf4& a, const vboolf4& b) { return a = a ^ b; }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Comparison Operators + Select
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vboolf4 operator !=( const vboolf4& a, const vboolf4& b ) { return _mm_xor_ps(a, b); }
|
||||
__forceinline const vboolf4 operator ==( const vboolf4& a, const vboolf4& b ) { return _mm_castsi128_ps(_mm_cmpeq_epi32(a, b)); }
|
||||
__forceinline vboolf4 operator !=(const vboolf4& a, const vboolf4& b) { return _mm_xor_ps(a, b); }
|
||||
__forceinline vboolf4 operator ==(const vboolf4& a, const vboolf4& b) { return _mm_castsi128_ps(_mm_cmpeq_epi32(a, b)); }
|
||||
|
||||
__forceinline const vboolf4 select( const vboolf4& m, const vboolf4& t, const vboolf4& f ) {
|
||||
__forceinline vboolf4 select(const vboolf4& m, const vboolf4& t, const vboolf4& f) {
|
||||
#if defined(__SSE4_1__)
|
||||
return _mm_blendv_ps(f, t, m);
|
||||
#else
|
||||
@@ -112,53 +112,56 @@ namespace embree
|
||||
/// Movement/Shifting/Shuffling Functions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vboolf4 unpacklo( const vboolf4& a, const vboolf4& b ) { return _mm_unpacklo_ps(a, b); }
|
||||
__forceinline const vboolf4 unpackhi( const vboolf4& a, const vboolf4& b ) { return _mm_unpackhi_ps(a, b); }
|
||||
__forceinline vboolf4 unpacklo(const vboolf4& a, const vboolf4& b) { return _mm_unpacklo_ps(a, b); }
|
||||
__forceinline vboolf4 unpackhi(const vboolf4& a, const vboolf4& b) { return _mm_unpackhi_ps(a, b); }
|
||||
|
||||
template<size_t i0, size_t i1, size_t i2, size_t i3> __forceinline const vboolf4 shuffle( const vboolf4& a ) {
|
||||
return _mm_shuffle_epi32(a, _MM_SHUFFLE(i3, i2, i1, i0));
|
||||
template<int i0, int i1, int i2, int i3>
|
||||
__forceinline vboolf4 shuffle(const vboolf4& v) {
|
||||
return _mm_shuffle_epi32(v, _MM_SHUFFLE(i3, i2, i1, i0));
|
||||
}
|
||||
|
||||
template<size_t i0, size_t i1, size_t i2, size_t i3> __forceinline const vboolf4 shuffle( const vboolf4& a, const vboolf4& b ) {
|
||||
template<int i0, int i1, int i2, int i3>
|
||||
__forceinline vboolf4 shuffle(const vboolf4& a, const vboolf4& b) {
|
||||
return _mm_shuffle_ps(a, b, _MM_SHUFFLE(i3, i2, i1, i0));
|
||||
}
|
||||
|
||||
template<size_t i0> __forceinline const vboolf4 shuffle( const vboolf4& b ) {
|
||||
return shuffle<i0,i0,i0,i0>(b);
|
||||
template<int i0>
|
||||
__forceinline vboolf4 shuffle(const vboolf4& v) {
|
||||
return shuffle<i0,i0,i0,i0>(v);
|
||||
}
|
||||
|
||||
#if defined(__SSE3__)
|
||||
template<> __forceinline const vboolf4 shuffle<0, 0, 2, 2>( const vboolf4& a ) { return _mm_moveldup_ps(a); }
|
||||
template<> __forceinline const vboolf4 shuffle<1, 1, 3, 3>( const vboolf4& a ) { return _mm_movehdup_ps(a); }
|
||||
template<> __forceinline const vboolf4 shuffle<0, 1, 0, 1>( const vboolf4& a ) { return _mm_castpd_ps(_mm_movedup_pd (a)); }
|
||||
template<> __forceinline vboolf4 shuffle<0, 0, 2, 2>(const vboolf4& v) { return _mm_moveldup_ps(v); }
|
||||
template<> __forceinline vboolf4 shuffle<1, 1, 3, 3>(const vboolf4& v) { return _mm_movehdup_ps(v); }
|
||||
template<> __forceinline vboolf4 shuffle<0, 1, 0, 1>(const vboolf4& v) { return _mm_castpd_ps(_mm_movedup_pd(v)); }
|
||||
#endif
|
||||
|
||||
#if defined(__SSE4_1__)
|
||||
template<size_t dst, size_t src, size_t clr> __forceinline const vboolf4 insert( const vboolf4& a, const vboolf4& b ) { return _mm_insert_ps(a, b, (dst << 4) | (src << 6) | clr); }
|
||||
template<size_t dst, size_t src> __forceinline const vboolf4 insert( const vboolf4& a, const vboolf4& b ) { return insert<dst, src, 0>(a, b); }
|
||||
template<size_t dst> __forceinline const vboolf4 insert( const vboolf4& a, const bool b ) { return insert<dst,0>(a, vboolf4(b)); }
|
||||
template<int dst, int src, int clr> __forceinline vboolf4 insert(const vboolf4& a, const vboolf4& b) { return _mm_insert_ps(a, b, (dst << 4) | (src << 6) | clr); }
|
||||
template<int dst, int src> __forceinline vboolf4 insert(const vboolf4& a, const vboolf4& b) { return insert<dst, src, 0>(a, b); }
|
||||
template<int dst> __forceinline vboolf4 insert(const vboolf4& a, const bool b) { return insert<dst, 0>(a, vboolf4(b)); }
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Reduction Operations
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline bool reduce_and( const vboolf4& a ) { return _mm_movemask_ps(a) == 0xf; }
|
||||
__forceinline bool reduce_or ( const vboolf4& a ) { return _mm_movemask_ps(a) != 0x0; }
|
||||
__forceinline bool reduce_and(const vboolf4& a) { return _mm_movemask_ps(a) == 0xf; }
|
||||
__forceinline bool reduce_or (const vboolf4& a) { return _mm_movemask_ps(a) != 0x0; }
|
||||
|
||||
__forceinline bool all ( const vboolf4& b ) { return _mm_movemask_ps(b) == 0xf; }
|
||||
__forceinline bool any ( const vboolf4& b ) { return _mm_movemask_ps(b) != 0x0; }
|
||||
__forceinline bool none ( const vboolf4& b ) { return _mm_movemask_ps(b) == 0x0; }
|
||||
__forceinline bool all (const vboolf4& b) { return _mm_movemask_ps(b) == 0xf; }
|
||||
__forceinline bool any (const vboolf4& b) { return _mm_movemask_ps(b) != 0x0; }
|
||||
__forceinline bool none(const vboolf4& b) { return _mm_movemask_ps(b) == 0x0; }
|
||||
|
||||
__forceinline bool all ( const vboolf4& valid, const vboolf4& b ) { return all((!valid) | b); }
|
||||
__forceinline bool any ( const vboolf4& valid, const vboolf4& b ) { return any( valid & b); }
|
||||
__forceinline bool none ( const vboolf4& valid, const vboolf4& b ) { return none(valid & b); }
|
||||
__forceinline bool all (const vboolf4& valid, const vboolf4& b) { return all((!valid) | b); }
|
||||
__forceinline bool any (const vboolf4& valid, const vboolf4& b) { return any(valid & b); }
|
||||
__forceinline bool none(const vboolf4& valid, const vboolf4& b) { return none(valid & b); }
|
||||
|
||||
__forceinline size_t movemask( const vboolf4& a ) { return _mm_movemask_ps(a); }
|
||||
__forceinline size_t movemask(const vboolf4& a) { return _mm_movemask_ps(a); }
|
||||
#if defined(__SSE4_2__)
|
||||
__forceinline size_t popcnt( const vboolf4& a ) { return __popcnt((size_t)_mm_movemask_ps(a)); }
|
||||
__forceinline size_t popcnt(const vboolf4& a) { return __popcnt((size_t)_mm_movemask_ps(a)); }
|
||||
#else
|
||||
__forceinline size_t popcnt( const vboolf4& a ) { return bool(a[0])+bool(a[1])+bool(a[2])+bool(a[3]); }
|
||||
__forceinline size_t popcnt(const vboolf4& a) { return bool(a[0])+bool(a[1])+bool(a[2])+bool(a[3]); }
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -173,7 +176,7 @@ namespace embree
|
||||
/// Output Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& cout, const vboolf4& a) {
|
||||
inline std::ostream& operator <<(std::ostream& cout, const vboolf4& a) {
|
||||
return cout << "<" << a[0] << ", " << a[1] << ", " << a[2] << ", " << a[3] << ">";
|
||||
}
|
||||
}
|
||||
+61
-56
@@ -37,16 +37,16 @@ namespace embree
|
||||
/// Constructors, Assignment & Cast Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vboolf () {}
|
||||
__forceinline vboolf ( const vboolf8& a ) { v = a.v; }
|
||||
__forceinline vboolf8& operator=( const vboolf8& a ) { v = a.v; return *this; }
|
||||
__forceinline vboolf() {}
|
||||
__forceinline vboolf(const vboolf8& a) { v = a.v; }
|
||||
__forceinline vboolf8& operator =(const vboolf8& a) { v = a.v; return *this; }
|
||||
|
||||
__forceinline vboolf( const __m256 a ) : v(a) {}
|
||||
__forceinline operator const __m256&( void ) const { return v; }
|
||||
__forceinline operator const __m256i( void ) const { return _mm256_castps_si256(v); }
|
||||
__forceinline operator const __m256d( void ) const { return _mm256_castps_pd(v); }
|
||||
__forceinline vboolf(__m256 a) : v(a) {}
|
||||
__forceinline operator const __m256&() const { return v; }
|
||||
__forceinline operator const __m256i() const { return _mm256_castps_si256(v); }
|
||||
__forceinline operator const __m256d() const { return _mm256_castps_pd(v); }
|
||||
|
||||
__forceinline vboolf ( const int a )
|
||||
__forceinline vboolf(int a)
|
||||
{
|
||||
assert(a >= 0 && a <= 255);
|
||||
#if defined (__AVX2__)
|
||||
@@ -60,14 +60,14 @@ namespace embree
|
||||
#endif
|
||||
}
|
||||
|
||||
__forceinline vboolf ( const vboolf4& a ) : v(_mm256_insertf128_ps(_mm256_castps128_ps256(a),a,1)) {}
|
||||
__forceinline vboolf ( const vboolf4& a, const vboolf4& b) : v(_mm256_insertf128_ps(_mm256_castps128_ps256(a),b,1)) {}
|
||||
__forceinline vboolf ( const __m128 a, const __m128 b) : vl(a), vh(b) {}
|
||||
__forceinline vboolf(const vboolf4& a) : v(_mm256_insertf128_ps(_mm256_castps128_ps256(a),a,1)) {}
|
||||
__forceinline vboolf(const vboolf4& a, const vboolf4& b) : v(_mm256_insertf128_ps(_mm256_castps128_ps256(a),b,1)) {}
|
||||
__forceinline vboolf(__m128 a, __m128 b) : vl(a), vh(b) {}
|
||||
|
||||
__forceinline vboolf ( bool a ) : v(vboolf8(vboolf4(a), vboolf4(a))) {}
|
||||
__forceinline vboolf ( bool a, bool b) : v(vboolf8(vboolf4(a), vboolf4(b))) {}
|
||||
__forceinline vboolf ( bool a, bool b, bool c, bool d) : v(vboolf8(vboolf4(a,b), vboolf4(c,d))) {}
|
||||
__forceinline vboolf ( bool a, bool b, bool c, bool d, bool e, bool f, bool g, bool vh ) : v(vboolf8(vboolf4(a,b,c,d), vboolf4(e,f,g,vh))) {}
|
||||
__forceinline vboolf(bool a) : v(vboolf8(vboolf4(a), vboolf4(a))) {}
|
||||
__forceinline vboolf(bool a, bool b) : v(vboolf8(vboolf4(a), vboolf4(b))) {}
|
||||
__forceinline vboolf(bool a, bool b, bool c, bool d) : v(vboolf8(vboolf4(a,b), vboolf4(c,d))) {}
|
||||
__forceinline vboolf(bool a, bool b, bool c, bool d, bool e, bool f, bool g, bool h) : v(vboolf8(vboolf4(a,b,c,d), vboolf4(e,f,g,h))) {}
|
||||
|
||||
/* return int32 mask */
|
||||
__forceinline __m256i mask32() const {
|
||||
@@ -78,43 +78,43 @@ namespace embree
|
||||
/// Constants
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vboolf( FalseTy ) : v(_mm256_setzero_ps()) {}
|
||||
__forceinline vboolf( TrueTy ) : v(_mm256_cmp_ps(_mm256_setzero_ps(), _mm256_setzero_ps(), _CMP_EQ_OQ)) {}
|
||||
__forceinline vboolf(FalseTy) : v(_mm256_setzero_ps()) {}
|
||||
__forceinline vboolf(TrueTy) : v(_mm256_cmp_ps(_mm256_setzero_ps(), _mm256_setzero_ps(), _CMP_EQ_OQ)) {}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Array Access
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline bool operator []( const size_t index ) const { assert(index < 8); return (_mm256_movemask_ps(v) >> index) & 1; }
|
||||
__forceinline int& operator []( const size_t index ) { assert(index < 8); return i[index]; }
|
||||
__forceinline bool operator [](size_t index) const { assert(index < 8); return (_mm256_movemask_ps(v) >> index) & 1; }
|
||||
__forceinline int& operator [](size_t index) { assert(index < 8); return i[index]; }
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Unary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vboolf8 operator !( const vboolf8& a ) { return _mm256_xor_ps(a, vboolf8(embree::True)); }
|
||||
__forceinline vboolf8 operator !(const vboolf8& a) { return _mm256_xor_ps(a, vboolf8(embree::True)); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Binary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vboolf8 operator &( const vboolf8& a, const vboolf8& b ) { return _mm256_and_ps(a, b); }
|
||||
__forceinline const vboolf8 operator |( const vboolf8& a, const vboolf8& b ) { return _mm256_or_ps (a, b); }
|
||||
__forceinline const vboolf8 operator ^( const vboolf8& a, const vboolf8& b ) { return _mm256_xor_ps(a, b); }
|
||||
__forceinline vboolf8 operator &(const vboolf8& a, const vboolf8& b) { return _mm256_and_ps(a, b); }
|
||||
__forceinline vboolf8 operator |(const vboolf8& a, const vboolf8& b) { return _mm256_or_ps (a, b); }
|
||||
__forceinline vboolf8 operator ^(const vboolf8& a, const vboolf8& b) { return _mm256_xor_ps(a, b); }
|
||||
|
||||
__forceinline vboolf8 operator &=( vboolf8& a, const vboolf8& b ) { return a = a & b; }
|
||||
__forceinline vboolf8 operator |=( vboolf8& a, const vboolf8& b ) { return a = a | b; }
|
||||
__forceinline vboolf8 operator ^=( vboolf8& a, const vboolf8& b ) { return a = a ^ b; }
|
||||
__forceinline vboolf8& operator &=(vboolf8& a, const vboolf8& b) { return a = a & b; }
|
||||
__forceinline vboolf8& operator |=(vboolf8& a, const vboolf8& b) { return a = a | b; }
|
||||
__forceinline vboolf8& operator ^=(vboolf8& a, const vboolf8& b) { return a = a ^ b; }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Comparison Operators + Select
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vboolf8 operator !=( const vboolf8& a, const vboolf8& b ) { return _mm256_xor_ps(a, b); }
|
||||
__forceinline const vboolf8 operator ==( const vboolf8& a, const vboolf8& b ) { return _mm256_xor_ps(_mm256_xor_ps(a,b),vboolf8(embree::True)); }
|
||||
__forceinline vboolf8 operator !=(const vboolf8& a, const vboolf8& b) { return _mm256_xor_ps(a, b); }
|
||||
__forceinline vboolf8 operator ==(const vboolf8& a, const vboolf8& b) { return _mm256_xor_ps(_mm256_xor_ps(a,b),vboolf8(embree::True)); }
|
||||
|
||||
__forceinline const vboolf8 select( const vboolf8& mask, const vboolf8& t, const vboolf8& f ) {
|
||||
__forceinline vboolf8 select(const vboolf8& mask, const vboolf8& t, const vboolf8& f) {
|
||||
return _mm256_blendv_ps(f, t, mask);
|
||||
}
|
||||
|
||||
@@ -122,54 +122,59 @@ namespace embree
|
||||
/// Movement/Shifting/Shuffling Functions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vboolf8 unpacklo( const vboolf8& a, const vboolf8& b ) { return _mm256_unpacklo_ps(a.v, b.v); }
|
||||
__forceinline vboolf8 unpackhi( const vboolf8& a, const vboolf8& b ) { return _mm256_unpackhi_ps(a.v, b.v); }
|
||||
__forceinline vboolf8 unpacklo(const vboolf8& a, const vboolf8& b) { return _mm256_unpacklo_ps(a, b); }
|
||||
__forceinline vboolf8 unpackhi(const vboolf8& a, const vboolf8& b) { return _mm256_unpackhi_ps(a, b); }
|
||||
|
||||
template<size_t i> __forceinline const vboolf8 shuffle( const vboolf8& a ) {
|
||||
return _mm256_permute_ps(a, _MM_SHUFFLE(i, i, i, i));
|
||||
template<int i>
|
||||
__forceinline vboolf8 shuffle(const vboolf8& v) {
|
||||
return _mm256_permute_ps(v, _MM_SHUFFLE(i, i, i, i));
|
||||
}
|
||||
|
||||
template<size_t i0, size_t i1> __forceinline const vboolf8 shuffle4( const vboolf8& a ) {
|
||||
return _mm256_permute2f128_ps(a, a, (i1 << 4) | (i0 << 0));
|
||||
template<int i0, int i1>
|
||||
__forceinline vboolf8 shuffle4(const vboolf8& v) {
|
||||
return _mm256_permute2f128_ps(v, v, (i1 << 4) | (i0 << 0));
|
||||
}
|
||||
|
||||
template<size_t i0, size_t i1> __forceinline const vboolf8 shuffle4( const vboolf8& a, const vboolf8& b) {
|
||||
template<int i0, int i1>
|
||||
__forceinline vboolf8 shuffle4(const vboolf8& a, const vboolf8& b) {
|
||||
return _mm256_permute2f128_ps(a, b, (i1 << 4) | (i0 << 0));
|
||||
}
|
||||
|
||||
template<size_t i0, size_t i1, size_t i2, size_t i3> __forceinline const vboolf8 shuffle( const vboolf8& a ) {
|
||||
return _mm256_permute_ps(a, _MM_SHUFFLE(i3, i2, i1, i0));
|
||||
template<int i0, int i1, int i2, int i3>
|
||||
__forceinline vboolf8 shuffle(const vboolf8& v) {
|
||||
return _mm256_permute_ps(v, _MM_SHUFFLE(i3, i2, i1, i0));
|
||||
}
|
||||
|
||||
template<size_t i0, size_t i1, size_t i2, size_t i3> __forceinline const vboolf8 shuffle( const vboolf8& a, const vboolf8& b ) {
|
||||
template<int i0, int i1, int i2, int i3>
|
||||
__forceinline vboolf8 shuffle(const vboolf8& a, const vboolf8& b) {
|
||||
return _mm256_shuffle_ps(a, b, _MM_SHUFFLE(i3, i2, i1, i0));
|
||||
}
|
||||
|
||||
template<> __forceinline const vboolf8 shuffle<0, 0, 2, 2>( const vboolf8& b ) { return _mm256_moveldup_ps(b); }
|
||||
template<> __forceinline const vboolf8 shuffle<1, 1, 3, 3>( const vboolf8& b ) { return _mm256_movehdup_ps(b); }
|
||||
template<> __forceinline const vboolf8 shuffle<0, 1, 0, 1>( const vboolf8& b ) { return _mm256_castpd_ps(_mm256_movedup_pd(_mm256_castps_pd(b))); }
|
||||
template<> __forceinline vboolf8 shuffle<0, 0, 2, 2>(const vboolf8& v) { return _mm256_moveldup_ps(v); }
|
||||
template<> __forceinline vboolf8 shuffle<1, 1, 3, 3>(const vboolf8& v) { return _mm256_movehdup_ps(v); }
|
||||
template<> __forceinline vboolf8 shuffle<0, 1, 0, 1>(const vboolf8& v) { return _mm256_castpd_ps(_mm256_movedup_pd(_mm256_castps_pd(v))); }
|
||||
|
||||
template<size_t i> __forceinline const vboolf8 insert4(const vboolf8& a, const vboolf4& b) { return _mm256_insertf128_ps(a, b, i); }
|
||||
template<size_t i> __forceinline const vboolf4 extract4 (const vboolf8& a) { return _mm256_extractf128_ps(a, i); }
|
||||
template<> __forceinline const vboolf4 extract4<0>(const vboolf8& a) { return _mm256_castps256_ps128(a); }
|
||||
template<int i> __forceinline vboolf8 insert4(const vboolf8& a, const vboolf4& b) { return _mm256_insertf128_ps(a, b, i); }
|
||||
template<int i> __forceinline vboolf4 extract4 (const vboolf8& a) { return _mm256_extractf128_ps(a, i); }
|
||||
template<> __forceinline vboolf4 extract4<0>(const vboolf8& a) { return _mm256_castps256_ps128(a); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Reduction Operations
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline bool reduce_and( const vboolf8& a ) { return _mm256_movemask_ps(a) == (unsigned int)0xff; }
|
||||
__forceinline bool reduce_or ( const vboolf8& a ) { return !_mm256_testz_ps(a,a); }
|
||||
__forceinline bool reduce_and(const vboolf8& a) { return _mm256_movemask_ps(a) == (unsigned int)0xff; }
|
||||
__forceinline bool reduce_or (const vboolf8& a) { return !_mm256_testz_ps(a,a); }
|
||||
|
||||
__forceinline bool all ( const vboolf8& a ) { return _mm256_movemask_ps(a) == (unsigned int)0xff; }
|
||||
__forceinline bool any ( const vboolf8& a ) { return !_mm256_testz_ps(a,a); }
|
||||
__forceinline bool none ( const vboolf8& a ) { return _mm256_testz_ps(a,a) != 0; }
|
||||
__forceinline bool all (const vboolf8& a) { return _mm256_movemask_ps(a) == (unsigned int)0xff; }
|
||||
__forceinline bool any (const vboolf8& a) { return !_mm256_testz_ps(a,a); }
|
||||
__forceinline bool none(const vboolf8& a) { return _mm256_testz_ps(a,a) != 0; }
|
||||
|
||||
__forceinline bool all ( const vboolf8& valid, const vboolf8& b ) { return all((!valid) | b); }
|
||||
__forceinline bool any ( const vboolf8& valid, const vboolf8& b ) { return any( valid & b); }
|
||||
__forceinline bool none ( const vboolf8& valid, const vboolf8& b ) { return none(valid & b); }
|
||||
__forceinline bool all (const vboolf8& valid, const vboolf8& b) { return all((!valid) | b); }
|
||||
__forceinline bool any (const vboolf8& valid, const vboolf8& b) { return any(valid & b); }
|
||||
__forceinline bool none(const vboolf8& valid, const vboolf8& b) { return none(valid & b); }
|
||||
|
||||
__forceinline unsigned int movemask( const vboolf8& a ) { return _mm256_movemask_ps(a); }
|
||||
__forceinline size_t popcnt ( const vboolf8& a ) { return __popcnt((size_t)_mm256_movemask_ps(a)); }
|
||||
__forceinline unsigned int movemask(const vboolf8& a) { return _mm256_movemask_ps(a); }
|
||||
__forceinline size_t popcnt (const vboolf8& a) { return __popcnt((size_t)_mm256_movemask_ps(a)); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Get/Set Functions
|
||||
@@ -183,7 +188,7 @@ namespace embree
|
||||
/// Output Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& cout, const vboolf8& a) {
|
||||
inline std::ostream& operator <<(std::ostream& cout, const vboolf8& a) {
|
||||
return cout << "<" << a[0] << ", " << a[1] << ", " << a[2] << ", " << a[3] << ", "
|
||||
<< a[4] << ", " << a[5] << ", " << a[6] << ", " << a[7] << ">";
|
||||
}
|
||||
|
||||
@@ -33,8 +33,8 @@ namespace embree
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vboolf() {}
|
||||
__forceinline vboolf(const vboolf8 &t) { v = t.v; }
|
||||
__forceinline vboolf8& operator=(const vboolf8 &f) { v = f.v; return *this; }
|
||||
__forceinline vboolf(const vboolf8& t) { v = t.v; }
|
||||
__forceinline vboolf8& operator =(const vboolf8& f) { v = f.v; return *this; }
|
||||
|
||||
__forceinline vboolf(const __mmask8 &t) { v = t; }
|
||||
__forceinline operator __mmask8() const { return v; }
|
||||
@@ -62,42 +62,42 @@ namespace embree
|
||||
/// Constants
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vboolf( FalseTy ) : v(0x00) {}
|
||||
__forceinline vboolf( TrueTy ) : v(0xff) {}
|
||||
__forceinline vboolf(FalseTy) : v(0x00) {}
|
||||
__forceinline vboolf(TrueTy) : v(0xff) {}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Unary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vboolf8 operator!(const vboolf8 &a) { return _mm512_knot(a); }
|
||||
__forceinline vboolf8 operator !(const vboolf8& a) { return _mm512_knot(a); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Binary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vboolf8 operator&(const vboolf8 &a, const vboolf8 &b) { return _mm512_kand(a, b); }
|
||||
__forceinline vboolf8 operator|(const vboolf8 &a, const vboolf8 &b) { return _mm512_kor(a, b); }
|
||||
__forceinline vboolf8 operator^(const vboolf8 &a, const vboolf8 &b) { return _mm512_kxor(a, b); }
|
||||
__forceinline vboolf8 operator &(const vboolf8& a, const vboolf8& b) { return _mm512_kand(a, b); }
|
||||
__forceinline vboolf8 operator |(const vboolf8& a, const vboolf8& b) { return _mm512_kor(a, b); }
|
||||
__forceinline vboolf8 operator ^(const vboolf8& a, const vboolf8& b) { return _mm512_kxor(a, b); }
|
||||
|
||||
__forceinline vboolf8 andn(const vboolf8 &a, const vboolf8 &b) { return _mm512_kandn(b, a); }
|
||||
__forceinline vboolf8 andn(const vboolf8& a, const vboolf8& b) { return _mm512_kandn(b, a); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Assignment Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vboolf8 operator &=( vboolf8& a, const vboolf8& b ) { return a = a & b; }
|
||||
__forceinline const vboolf8 operator |=( vboolf8& a, const vboolf8& b ) { return a = a | b; }
|
||||
__forceinline const vboolf8 operator ^=( vboolf8& a, const vboolf8& b ) { return a = a ^ b; }
|
||||
__forceinline vboolf8& operator &=(vboolf8& a, const vboolf8& b) { return a = a & b; }
|
||||
__forceinline vboolf8& operator |=(vboolf8& a, const vboolf8& b) { return a = a | b; }
|
||||
__forceinline vboolf8& operator ^=(vboolf8& a, const vboolf8& b) { return a = a ^ b; }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Comparison Operators + Select
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vboolf8 operator !=( const vboolf8& a, const vboolf8& b ) { return _mm512_kxor(a, b); }
|
||||
__forceinline const vboolf8 operator ==( const vboolf8& a, const vboolf8& b ) { return _mm512_kxnor(a, b); }
|
||||
__forceinline vboolf8 operator !=(const vboolf8& a, const vboolf8& b) { return _mm512_kxor(a, b); }
|
||||
__forceinline vboolf8 operator ==(const vboolf8& a, const vboolf8& b) { return _mm512_kxnor(a, b); }
|
||||
|
||||
__forceinline vboolf8 select(const vboolf8 &s, const vboolf8 &a, const vboolf8 &b) {
|
||||
__forceinline vboolf8 select(const vboolf8& s, const vboolf8& a, const vboolf8& b) {
|
||||
return _mm512_kor(_mm512_kand(s, a), _mm512_kandn(s, b));
|
||||
}
|
||||
|
||||
@@ -105,22 +105,22 @@ namespace embree
|
||||
/// Reduction Operations
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline int all (const vboolf8 &a) { return a.v == 0xff; }
|
||||
__forceinline int any (const vboolf8 &a) { return _mm512_kortestz(a, a) == 0; }
|
||||
__forceinline int none(const vboolf8 &a) { return _mm512_kortestz(a, a) != 0; }
|
||||
__forceinline int all (const vboolf8& a) { return a.v == 0xff; }
|
||||
__forceinline int any (const vboolf8& a) { return _mm512_kortestz(a, a) == 0; }
|
||||
__forceinline int none(const vboolf8& a) { return _mm512_kortestz(a, a) != 0; }
|
||||
|
||||
__forceinline int all ( const vboolf8& valid, const vboolf8& b ) { return all((!valid) | b); }
|
||||
__forceinline int any ( const vboolf8& valid, const vboolf8& b ) { return any( valid & b); }
|
||||
__forceinline int none( const vboolf8& valid, const vboolf8& b ) { return none(valid & b); }
|
||||
__forceinline int all (const vboolf8& valid, const vboolf8& b) { return all((!valid) | b); }
|
||||
__forceinline int any (const vboolf8& valid, const vboolf8& b) { return any(valid & b); }
|
||||
__forceinline int none(const vboolf8& valid, const vboolf8& b) { return none(valid & b); }
|
||||
|
||||
__forceinline size_t movemask( const vboolf8& a ) { return _mm512_kmov(a); }
|
||||
__forceinline size_t popcnt ( const vboolf8& a ) { return __popcnt(a.v); }
|
||||
__forceinline size_t movemask(const vboolf8& a) { return _mm512_kmov(a); }
|
||||
__forceinline size_t popcnt (const vboolf8& a) { return __popcnt(a.v); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Conversion Operations
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline unsigned int toInt(const vboolf8 &a) { return mm512_mask2int(a); }
|
||||
__forceinline unsigned int toInt(const vboolf8& a) { return mm512_mask2int(a); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Get/Set Functions
|
||||
@@ -134,7 +134,7 @@ namespace embree
|
||||
/// Output Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& cout, const vboolf8& a)
|
||||
inline std::ostream& operator <<(std::ostream& cout, const vboolf8& a)
|
||||
{
|
||||
cout << "<";
|
||||
for (size_t i=0; i<8; i++) {
|
||||
|
||||
+103
-111
@@ -18,17 +18,7 @@
|
||||
|
||||
namespace embree
|
||||
{
|
||||
#ifndef _MM_SHUF_PERM2
|
||||
#define _MM_SHUF_PERM2(e3, e2, e1, e0) \
|
||||
((int)(((e3)<<3) | ((e2)<<2) | ((e1)<<1) | (e0)))
|
||||
#endif
|
||||
|
||||
#ifndef _MM_SHUF_PERM3
|
||||
#define _MM_SHUF_PERM3(e1, e0) \
|
||||
((int)(((e1)<<4) | (e0)))
|
||||
#endif
|
||||
|
||||
/* 4-wide AVX 64bit double type */
|
||||
/* 4-wide AVX 64-bit double type */
|
||||
template<>
|
||||
struct vdouble<4>
|
||||
{
|
||||
@@ -46,16 +36,16 @@ namespace embree
|
||||
|
||||
__forceinline vdouble() {}
|
||||
__forceinline vdouble(const vdouble4& t) { v = t.v; }
|
||||
__forceinline vdouble4& operator=(const vdouble4& f) { v = f.v; return *this; }
|
||||
__forceinline vdouble4& operator =(const vdouble4& f) { v = f.v; return *this; }
|
||||
|
||||
__forceinline vdouble(const __m256d& t) { v = t; }
|
||||
__forceinline operator __m256d () const { return v; }
|
||||
__forceinline operator __m256d() const { return v; }
|
||||
|
||||
__forceinline vdouble(const double i) {
|
||||
__forceinline vdouble(double i) {
|
||||
v = _mm256_set1_pd(i);
|
||||
}
|
||||
|
||||
__forceinline vdouble(const double a, const double b, const double c, const double d) {
|
||||
__forceinline vdouble(double a, double b, double c, double d) {
|
||||
v = _mm256_set_pd(d,c,b,a);
|
||||
}
|
||||
|
||||
@@ -64,25 +54,20 @@ namespace embree
|
||||
/// Constants
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vdouble( ZeroTy ) : v(_mm256_setzero_pd()) {}
|
||||
__forceinline vdouble( OneTy ) : v(_mm256_set1_pd(1)) {}
|
||||
__forceinline vdouble( StepTy ) : v(_mm256_set_pd(3.0,2.0,1.0,0.0)) {}
|
||||
__forceinline vdouble( ReverseStepTy ) : v(_mm256_setr_pd(3.0,2.0,1.0,0.0)) {}
|
||||
|
||||
__forceinline static vdouble4 zero() { return _mm256_setzero_pd(); }
|
||||
__forceinline static vdouble4 one () { return _mm256_set1_pd(1.0); }
|
||||
__forceinline static vdouble4 neg_one () { return _mm256_set1_pd(-1.0); }
|
||||
__forceinline vdouble(ZeroTy) : v(_mm256_setzero_pd()) {}
|
||||
__forceinline vdouble(OneTy) : v(_mm256_set1_pd(1)) {}
|
||||
__forceinline vdouble(StepTy) : v(_mm256_set_pd(3.0,2.0,1.0,0.0)) {}
|
||||
__forceinline vdouble(ReverseStepTy) : v(_mm256_setr_pd(3.0,2.0,1.0,0.0)) {}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Loads and Stores
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static __forceinline void store_nt(double *__restrict__ ptr, const vdouble4& a) {
|
||||
_mm256_stream_pd(ptr,a);
|
||||
_mm256_stream_pd(ptr, a);
|
||||
}
|
||||
|
||||
static __forceinline vdouble4 loadu(const double* addr)
|
||||
{
|
||||
static __forceinline vdouble4 loadu(const double* addr) {
|
||||
return _mm256_loadu_pd(addr);
|
||||
}
|
||||
|
||||
@@ -95,11 +80,11 @@ namespace embree
|
||||
}
|
||||
|
||||
static __forceinline void store(double* ptr, const vdouble4& v) {
|
||||
_mm256_store_pd(ptr,v);
|
||||
_mm256_store_pd(ptr, v);
|
||||
}
|
||||
|
||||
static __forceinline void storeu(double* ptr, const vdouble4& v ) {
|
||||
_mm256_storeu_pd(ptr,v);
|
||||
static __forceinline void storeu(double* ptr, const vdouble4& v) {
|
||||
_mm256_storeu_pd(ptr, v);
|
||||
}
|
||||
|
||||
|
||||
@@ -107,72 +92,71 @@ namespace embree
|
||||
/// Array Access
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline double& operator[](const size_t index) { assert(index < 8); return i[index]; }
|
||||
__forceinline const double& operator[](const size_t index) const { assert(index < 8); return i[index]; }
|
||||
|
||||
__forceinline double& operator [](size_t index) { assert(index < 4); return i[index]; }
|
||||
__forceinline const double& operator [](size_t index) const { assert(index < 4); return i[index]; }
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Unary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vdouble4 operator +( const vdouble4& a ) { return a; }
|
||||
__forceinline const vdouble4 operator -( const vdouble4& a ) { return _mm256_sub_pd(_mm256_setzero_pd(), a); }
|
||||
__forceinline vdouble4 operator +(const vdouble4& a) { return a; }
|
||||
__forceinline vdouble4 operator -(const vdouble4& a) { return _mm256_sub_pd(_mm256_setzero_pd(), a); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Binary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vdouble4 operator +( const vdouble4& a, const vdouble4& b ) { return _mm256_add_pd(a, b); }
|
||||
__forceinline const vdouble4 operator +( const vdouble4& a, const double b ) { return a + vdouble4(b); }
|
||||
__forceinline const vdouble4 operator +( const double a, const vdouble4& b ) { return vdouble4(a) + b; }
|
||||
__forceinline vdouble4 operator +(const vdouble4& a, const vdouble4& b) { return _mm256_add_pd(a, b); }
|
||||
__forceinline vdouble4 operator +(const vdouble4& a, double b) { return a + vdouble4(b); }
|
||||
__forceinline vdouble4 operator +(double a, const vdouble4& b) { return vdouble4(a) + b; }
|
||||
|
||||
__forceinline const vdouble4 operator -( const vdouble4& a, const vdouble4& b ) { return _mm256_sub_pd(a, b); }
|
||||
__forceinline const vdouble4 operator -( const vdouble4& a, const double b ) { return a - vdouble4(b); }
|
||||
__forceinline const vdouble4 operator -( const double a, const vdouble4& b ) { return vdouble4(a) - b; }
|
||||
__forceinline vdouble4 operator -(const vdouble4& a, const vdouble4& b) { return _mm256_sub_pd(a, b); }
|
||||
__forceinline vdouble4 operator -(const vdouble4& a, double b) { return a - vdouble4(b); }
|
||||
__forceinline vdouble4 operator -(double a, const vdouble4& b) { return vdouble4(a) - b; }
|
||||
|
||||
__forceinline const vdouble4 operator *( const vdouble4& a, const vdouble4& b ) { return _mm256_mul_pd(a, b); }
|
||||
__forceinline const vdouble4 operator *( const vdouble4& a, const double b ) { return a * vdouble4(b); }
|
||||
__forceinline const vdouble4 operator *( const double a, const vdouble4& b ) { return vdouble4(a) * b; }
|
||||
__forceinline vdouble4 operator *(const vdouble4& a, const vdouble4& b) { return _mm256_mul_pd(a, b); }
|
||||
__forceinline vdouble4 operator *(const vdouble4& a, double b) { return a * vdouble4(b); }
|
||||
__forceinline vdouble4 operator *(double a, const vdouble4& b) { return vdouble4(a) * b; }
|
||||
|
||||
__forceinline const vdouble4 operator &( const vdouble4& a, const vdouble4& b ) { return _mm256_and_pd(a, b); }
|
||||
__forceinline const vdouble4 operator &( const vdouble4& a, const double b ) { return a & vdouble4(b); }
|
||||
__forceinline const vdouble4 operator &( const double a, const vdouble4& b ) { return vdouble4(a) & b; }
|
||||
__forceinline vdouble4 operator &(const vdouble4& a, const vdouble4& b) { return _mm256_and_pd(a, b); }
|
||||
__forceinline vdouble4 operator &(const vdouble4& a, double b) { return a & vdouble4(b); }
|
||||
__forceinline vdouble4 operator &(double a, const vdouble4& b) { return vdouble4(a) & b; }
|
||||
|
||||
__forceinline const vdouble4 operator |( const vdouble4& a, const vdouble4& b ) { return _mm256_or_pd(a, b); }
|
||||
__forceinline const vdouble4 operator |( const vdouble4& a, const double b ) { return a | vdouble4(b); }
|
||||
__forceinline const vdouble4 operator |( const double a, const vdouble4& b ) { return vdouble4(a) | b; }
|
||||
__forceinline vdouble4 operator |(const vdouble4& a, const vdouble4& b) { return _mm256_or_pd(a, b); }
|
||||
__forceinline vdouble4 operator |(const vdouble4& a, double b) { return a | vdouble4(b); }
|
||||
__forceinline vdouble4 operator |(double a, const vdouble4& b) { return vdouble4(a) | b; }
|
||||
|
||||
__forceinline const vdouble4 operator ^( const vdouble4& a, const vdouble4& b ) { return _mm256_xor_pd(a, b); }
|
||||
__forceinline const vdouble4 operator ^( const vdouble4& a, const double b ) { return a ^ vdouble4(b); }
|
||||
__forceinline const vdouble4 operator ^( const double a, const vdouble4& b ) { return vdouble4(a) ^ b; }
|
||||
__forceinline vdouble4 operator ^(const vdouble4& a, const vdouble4& b) { return _mm256_xor_pd(a, b); }
|
||||
__forceinline vdouble4 operator ^(const vdouble4& a, double b) { return a ^ vdouble4(b); }
|
||||
__forceinline vdouble4 operator ^(double a, const vdouble4& b) { return vdouble4(a) ^ b; }
|
||||
|
||||
__forceinline const vdouble4 min( const vdouble4& a, const vdouble4& b ) { return _mm256_min_pd(a, b); }
|
||||
__forceinline const vdouble4 min( const vdouble4& a, const double b ) { return min(a,vdouble4(b)); }
|
||||
__forceinline const vdouble4 min( const double a, const vdouble4& b ) { return min(vdouble4(a),b); }
|
||||
__forceinline vdouble4 min(const vdouble4& a, const vdouble4& b) { return _mm256_min_pd(a, b); }
|
||||
__forceinline vdouble4 min(const vdouble4& a, double b) { return min(a,vdouble4(b)); }
|
||||
__forceinline vdouble4 min(double a, const vdouble4& b) { return min(vdouble4(a),b); }
|
||||
|
||||
__forceinline const vdouble4 max( const vdouble4& a, const vdouble4& b ) { return _mm256_max_pd(a, b); }
|
||||
__forceinline const vdouble4 max( const vdouble4& a, const double b ) { return max(a,vdouble4(b)); }
|
||||
__forceinline const vdouble4 max( const double a, const vdouble4& b ) { return max(vdouble4(a),b); }
|
||||
__forceinline vdouble4 max(const vdouble4& a, const vdouble4& b) { return _mm256_max_pd(a, b); }
|
||||
__forceinline vdouble4 max(const vdouble4& a, double b) { return max(a,vdouble4(b)); }
|
||||
__forceinline vdouble4 max(double a, const vdouble4& b) { return max(vdouble4(a),b); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Assignment Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vdouble4& operator +=( vdouble4& a, const vdouble4& b ) { return a = a + b; }
|
||||
__forceinline vdouble4& operator +=( vdouble4& a, const double b ) { return a = a + b; }
|
||||
__forceinline vdouble4& operator +=(vdouble4& a, const vdouble4& b) { return a = a + b; }
|
||||
__forceinline vdouble4& operator +=(vdouble4& a, double b) { return a = a + b; }
|
||||
|
||||
__forceinline vdouble4& operator -=( vdouble4& a, const vdouble4& b ) { return a = a - b; }
|
||||
__forceinline vdouble4& operator -=( vdouble4& a, const double b ) { return a = a - b; }
|
||||
__forceinline vdouble4& operator -=(vdouble4& a, const vdouble4& b) { return a = a - b; }
|
||||
__forceinline vdouble4& operator -=(vdouble4& a, double b) { return a = a - b; }
|
||||
|
||||
__forceinline vdouble4& operator *=( vdouble4& a, const vdouble4& b ) { return a = a * b; }
|
||||
__forceinline vdouble4& operator *=( vdouble4& a, const double b ) { return a = a * b; }
|
||||
__forceinline vdouble4& operator *=(vdouble4& a, const vdouble4& b) { return a = a * b; }
|
||||
__forceinline vdouble4& operator *=(vdouble4& a, double b) { return a = a * b; }
|
||||
|
||||
__forceinline vdouble4& operator &=( vdouble4& a, const vdouble4& b ) { return a = a & b; }
|
||||
__forceinline vdouble4& operator &=( vdouble4& a, const double b ) { return a = a & b; }
|
||||
__forceinline vdouble4& operator &=(vdouble4& a, const vdouble4& b) { return a = a & b; }
|
||||
__forceinline vdouble4& operator &=(vdouble4& a, double b) { return a = a & b; }
|
||||
|
||||
__forceinline vdouble4& operator |=( vdouble4& a, const vdouble4& b ) { return a = a | b; }
|
||||
__forceinline vdouble4& operator |=( vdouble4& a, const double b ) { return a = a | b; }
|
||||
__forceinline vdouble4& operator |=(vdouble4& a, const vdouble4& b) { return a = a | b; }
|
||||
__forceinline vdouble4& operator |=(vdouble4& a, double b) { return a = a | b; }
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -180,38 +164,38 @@ namespace embree
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined(__AVX512VL__)
|
||||
__forceinline const vboold4 operator ==( const vdouble4& a, const vdouble4& b ) { return _mm256_cmp_pd_mask(a,b,_MM_CMPINT_EQ); }
|
||||
__forceinline const vboold4 operator !=( const vdouble4& a, const vdouble4& b ) { return _mm256_cmp_pd_mask(a,b,_MM_CMPINT_NE); }
|
||||
__forceinline const vboold4 operator < ( const vdouble4& a, const vdouble4& b ) { return _mm256_cmp_pd_mask(a,b,_MM_CMPINT_LT); }
|
||||
__forceinline const vboold4 operator >=( const vdouble4& a, const vdouble4& b ) { return _mm256_cmp_pd_mask(a,b,_MM_CMPINT_GE); }
|
||||
__forceinline const vboold4 operator > ( const vdouble4& a, const vdouble4& b ) { return _mm256_cmp_pd_mask(a,b,_MM_CMPINT_GT); }
|
||||
__forceinline const vboold4 operator <=( const vdouble4& a, const vdouble4& b ) { return _mm256_cmp_pd_mask(a,b,_MM_CMPINT_LE); }
|
||||
__forceinline vboold4 operator ==(const vdouble4& a, const vdouble4& b) { return _mm256_cmp_pd_mask(a,b,_MM_CMPINT_EQ); }
|
||||
__forceinline vboold4 operator !=(const vdouble4& a, const vdouble4& b) { return _mm256_cmp_pd_mask(a,b,_MM_CMPINT_NE); }
|
||||
__forceinline vboold4 operator < (const vdouble4& a, const vdouble4& b) { return _mm256_cmp_pd_mask(a,b,_MM_CMPINT_LT); }
|
||||
__forceinline vboold4 operator >=(const vdouble4& a, const vdouble4& b) { return _mm256_cmp_pd_mask(a,b,_MM_CMPINT_GE); }
|
||||
__forceinline vboold4 operator > (const vdouble4& a, const vdouble4& b) { return _mm256_cmp_pd_mask(a,b,_MM_CMPINT_GT); }
|
||||
__forceinline vboold4 operator <=(const vdouble4& a, const vdouble4& b) { return _mm256_cmp_pd_mask(a,b,_MM_CMPINT_LE); }
|
||||
#else
|
||||
__forceinline const vboold4 operator ==( const vdouble4& a, const vdouble4& b ) { return _mm256_cmp_pd(a,b,_CMP_EQ_UQ); }
|
||||
__forceinline const vboold4 operator !=( const vdouble4& a, const vdouble4& b ) { return _mm256_cmp_pd(a,b,_CMP_NEQ_UQ); }
|
||||
__forceinline const vboold4 operator < ( const vdouble4& a, const vdouble4& b ) { return _mm256_cmp_pd(a,b,_CMP_LT_OQ); }
|
||||
__forceinline const vboold4 operator >=( const vdouble4& a, const vdouble4& b ) { return _mm256_cmp_pd(a,b,_CMP_GE_OQ); }
|
||||
__forceinline const vboold4 operator > ( const vdouble4& a, const vdouble4& b ) { return _mm256_cmp_pd(a,b,_CMP_GT_OQ); }
|
||||
__forceinline const vboold4 operator <=( const vdouble4& a, const vdouble4& b ) { return _mm256_cmp_pd(a,b,_CMP_LE_OQ); }
|
||||
__forceinline vboold4 operator ==(const vdouble4& a, const vdouble4& b) { return _mm256_cmp_pd(a,b,_CMP_EQ_UQ); }
|
||||
__forceinline vboold4 operator !=(const vdouble4& a, const vdouble4& b) { return _mm256_cmp_pd(a,b,_CMP_NEQ_UQ); }
|
||||
__forceinline vboold4 operator < (const vdouble4& a, const vdouble4& b) { return _mm256_cmp_pd(a,b,_CMP_LT_OQ); }
|
||||
__forceinline vboold4 operator >=(const vdouble4& a, const vdouble4& b) { return _mm256_cmp_pd(a,b,_CMP_GE_OQ); }
|
||||
__forceinline vboold4 operator > (const vdouble4& a, const vdouble4& b) { return _mm256_cmp_pd(a,b,_CMP_GT_OQ); }
|
||||
__forceinline vboold4 operator <=(const vdouble4& a, const vdouble4& b) { return _mm256_cmp_pd(a,b,_CMP_LE_OQ); }
|
||||
#endif
|
||||
|
||||
__forceinline const vboold4 operator ==( const vdouble4& a, const double b ) { return a == vdouble4(b); }
|
||||
__forceinline const vboold4 operator ==( const double a, const vdouble4& b ) { return vdouble4(a) == b; }
|
||||
__forceinline vboold4 operator ==(const vdouble4& a, double b) { return a == vdouble4(b); }
|
||||
__forceinline vboold4 operator ==(double a, const vdouble4& b) { return vdouble4(a) == b; }
|
||||
|
||||
__forceinline const vboold4 operator !=( const vdouble4& a, const double b ) { return a != vdouble4(b); }
|
||||
__forceinline const vboold4 operator !=( const double a, const vdouble4& b ) { return vdouble4(a) != b; }
|
||||
__forceinline vboold4 operator !=(const vdouble4& a, double b) { return a != vdouble4(b); }
|
||||
__forceinline vboold4 operator !=(double a, const vdouble4& b) { return vdouble4(a) != b; }
|
||||
|
||||
__forceinline const vboold4 operator < ( const vdouble4& a, const double b ) { return a < vdouble4(b); }
|
||||
__forceinline const vboold4 operator < ( const double a, const vdouble4& b ) { return vdouble4(a) < b; }
|
||||
__forceinline vboold4 operator < (const vdouble4& a, double b) { return a < vdouble4(b); }
|
||||
__forceinline vboold4 operator < (double a, const vdouble4& b) { return vdouble4(a) < b; }
|
||||
|
||||
__forceinline const vboold4 operator >=( const vdouble4& a, const double b ) { return a >= vdouble4(b); }
|
||||
__forceinline const vboold4 operator >=( const double a, const vdouble4& b ) { return vdouble4(a) >= b; }
|
||||
__forceinline vboold4 operator >=(const vdouble4& a, double b) { return a >= vdouble4(b); }
|
||||
__forceinline vboold4 operator >=(double a, const vdouble4& b) { return vdouble4(a) >= b; }
|
||||
|
||||
__forceinline const vboold4 operator > ( const vdouble4& a, const double b ) { return a > vdouble4(b); }
|
||||
__forceinline const vboold4 operator > ( const double a, const vdouble4& b ) { return vdouble4(a) > b; }
|
||||
__forceinline vboold4 operator > (const vdouble4& a, double b) { return a > vdouble4(b); }
|
||||
__forceinline vboold4 operator > (double a, const vdouble4& b) { return vdouble4(a) > b; }
|
||||
|
||||
__forceinline const vboold4 operator <=( const vdouble4& a, const double b ) { return a <= vdouble4(b); }
|
||||
__forceinline const vboold4 operator <=( const double a, const vdouble4& b ) { return vdouble4(a) <= b; }
|
||||
__forceinline vboold4 operator <=(const vdouble4& a, double b) { return a <= vdouble4(b); }
|
||||
__forceinline vboold4 operator <=(double a, const vdouble4& b) { return vdouble4(a) <= b; }
|
||||
|
||||
__forceinline vboold4 eq(const vdouble4& a, const vdouble4& b) { return a == b; }
|
||||
__forceinline vboold4 ne(const vdouble4& a, const vdouble4& b) { return a != b; }
|
||||
@@ -236,7 +220,7 @@ namespace embree
|
||||
__forceinline vboold4 le(const vboold4& mask, const vdouble4& a, const vdouble4& b) { return mask & (a <= b); }
|
||||
#endif
|
||||
|
||||
__forceinline const vdouble4 select( const vboold4& m, const vdouble4& t, const vdouble4& f ) {
|
||||
__forceinline vdouble4 select(const vboold4& m, const vdouble4& t, const vdouble4& f) {
|
||||
#if defined(__AVX512VL__)
|
||||
return _mm256_mask_blend_pd(m, f, t);
|
||||
#else
|
||||
@@ -260,35 +244,43 @@ namespace embree
|
||||
// Movement/Shifting/Shuffling Functions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<int B, int A> __forceinline vdouble4 shuffle (const vdouble4& v) { return _mm256_permute_pd(v,(int)_MM_SHUF_PERM2(B,A,B,A)); }
|
||||
template<int A> __forceinline vdouble4 shuffle (const vdouble4& x) { return shuffle<A,A>(x); }
|
||||
template<int i0, int i1>
|
||||
__forceinline vdouble4 shuffle(const vdouble4& v) {
|
||||
return _mm256_permute_pd(v, (i1 << 3) | (i0 << 2) | (i1 << 1) | i0);
|
||||
}
|
||||
|
||||
template<int B, int A> __forceinline vdouble4 shuffle2 (const vdouble4& v) { return _mm256_permute2f128_pd(v,v,(int)_MM_SHUF_PERM3(B,A)); }
|
||||
template<int i>
|
||||
__forceinline vdouble4 shuffle(const vdouble4& v) {
|
||||
return shuffle<i, i>(v);
|
||||
}
|
||||
|
||||
__forceinline double toScalar(const vdouble4& a)
|
||||
{
|
||||
return _mm_cvtsd_f64(_mm256_castpd256_pd128(a));
|
||||
template<int i0, int i1>
|
||||
__forceinline vdouble4 shuffle2(const vdouble4& v) {
|
||||
return _mm256_permute2f128_pd(v, v, (i1 << 4) | i0);
|
||||
}
|
||||
|
||||
__forceinline double toScalar(const vdouble4& v) {
|
||||
return _mm_cvtsd_f64(_mm256_castpd256_pd128(v));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Reductions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
__forceinline vdouble4 vreduce_min2(const vdouble4& x) { return min(x,shuffle<0,1>(x)); }
|
||||
__forceinline vdouble4 vreduce_min (const vdouble4& y) { const vdouble4 x = vreduce_min2(y); return min(x,shuffle2<0,1>(x)); }
|
||||
__forceinline vdouble4 vreduce_min2(const vdouble4& x) { return min(x, shuffle<1,0>(x)); }
|
||||
__forceinline vdouble4 vreduce_min (const vdouble4& y) { const vdouble4 x = vreduce_min2(y); return min(x, shuffle2<1,0>(x)); }
|
||||
|
||||
__forceinline vdouble4 vreduce_max2(const vdouble4& x) { return max(x,shuffle<0,1>(x)); }
|
||||
__forceinline vdouble4 vreduce_max (const vdouble4& y) { const vdouble4 x = vreduce_max2(y); return max(x,shuffle2<0,1>(x)); }
|
||||
__forceinline vdouble4 vreduce_max2(const vdouble4& x) { return max(x,shuffle<1,0>(x)); }
|
||||
__forceinline vdouble4 vreduce_max (const vdouble4& y) { const vdouble4 x = vreduce_max2(y); return max(x, shuffle2<1,0>(x)); }
|
||||
|
||||
__forceinline vdouble4 vreduce_and2(const vdouble4& x) { return x & shuffle<0,1>(x); }
|
||||
__forceinline vdouble4 vreduce_and (const vdouble4& y) { const vdouble4 x = vreduce_and2(y); return x & shuffle2<0,1>(x); }
|
||||
__forceinline vdouble4 vreduce_and2(const vdouble4& x) { return x & shuffle<1,0>(x); }
|
||||
__forceinline vdouble4 vreduce_and (const vdouble4& y) { const vdouble4 x = vreduce_and2(y); return x & shuffle2<1,0>(x); }
|
||||
|
||||
__forceinline vdouble4 vreduce_or2(const vdouble4& x) { return x | shuffle<0,1>(x); }
|
||||
__forceinline vdouble4 vreduce_or (const vdouble4& y) { const vdouble4 x = vreduce_or2(y); return x | shuffle2<0,1>(x); }
|
||||
__forceinline vdouble4 vreduce_or2(const vdouble4& x) { return x | shuffle<1,0>(x); }
|
||||
__forceinline vdouble4 vreduce_or (const vdouble4& y) { const vdouble4 x = vreduce_or2(y); return x | shuffle2<1,0>(x); }
|
||||
|
||||
__forceinline vdouble4 vreduce_add2(const vdouble4& x) { return x + shuffle<0,1>(x); }
|
||||
__forceinline vdouble4 vreduce_add (const vdouble4& y) { const vdouble4 x = vreduce_add2(y); return x + shuffle2<0,1>(x); }
|
||||
__forceinline vdouble4 vreduce_add2(const vdouble4& x) { return x + shuffle<1,0>(x); }
|
||||
__forceinline vdouble4 vreduce_add (const vdouble4& y) { const vdouble4 x = vreduce_add2(y); return x + shuffle2<1,0>(x); }
|
||||
|
||||
__forceinline double reduce_add(const vdouble4& a) { return toScalar(vreduce_add(a)); }
|
||||
__forceinline double reduce_min(const vdouble4& a) { return toScalar(vreduce_min(a)); }
|
||||
@@ -304,7 +296,7 @@ namespace embree
|
||||
/// Output Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline std::ostream& operator<<(std::ostream& cout, const vdouble4& v)
|
||||
__forceinline std::ostream& operator <<(std::ostream& cout, const vdouble4& v)
|
||||
{
|
||||
cout << "<" << v[0];
|
||||
for (size_t i=1; i<4; i++) cout << ", " << v[i];
|
||||
|
||||
+125
-125
@@ -18,7 +18,7 @@
|
||||
|
||||
namespace embree
|
||||
{
|
||||
/* 8-wide AVX-512 64bit double type */
|
||||
/* 8-wide AVX-512 64-bit double type */
|
||||
template<>
|
||||
struct vdouble<8>
|
||||
{
|
||||
@@ -36,22 +36,22 @@ namespace embree
|
||||
|
||||
__forceinline vdouble() {}
|
||||
__forceinline vdouble(const vdouble8& t) { v = t.v; }
|
||||
__forceinline vdouble8& operator=(const vdouble8& f) { v = f.v; return *this; }
|
||||
__forceinline vdouble8& operator =(const vdouble8& f) { v = f.v; return *this; }
|
||||
|
||||
__forceinline vdouble(const __m512d& t) { v = t; }
|
||||
__forceinline operator __m512d () const { return v; }
|
||||
__forceinline operator __m256d () const { return _mm512_castpd512_pd256(v); }
|
||||
__forceinline operator __m512d() const { return v; }
|
||||
__forceinline operator __m256d() const { return _mm512_castpd512_pd256(v); }
|
||||
|
||||
__forceinline vdouble(const double i) {
|
||||
__forceinline vdouble(double i) {
|
||||
v = _mm512_set1_pd(i);
|
||||
}
|
||||
|
||||
__forceinline vdouble(const double a, const double b, const double c, const double d) {
|
||||
__forceinline vdouble(double a, double b, double c, double d) {
|
||||
v = _mm512_set4_pd(d,c,b,a);
|
||||
}
|
||||
|
||||
__forceinline vdouble(const double a0 , const double a1 , const double a2 , const double a3,
|
||||
const double a4 , const double a5 , const double a6 , const double a7)
|
||||
__forceinline vdouble(double a0, double a1, double a2, double a3,
|
||||
double a4, double a5, double a6, double a7)
|
||||
{
|
||||
v = _mm512_set_pd(a7,a6,a5,a4,a3,a2,a1,a0);
|
||||
}
|
||||
@@ -61,21 +61,17 @@ namespace embree
|
||||
/// Constants
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vdouble( ZeroTy ) : v(_mm512_setzero_pd()) {}
|
||||
__forceinline vdouble( OneTy ) : v(_mm512_set1_pd(1)) {}
|
||||
__forceinline vdouble( StepTy ) : v(_mm512_set_pd(7.0,6.0,5.0,4.0,3.0,2.0,1.0,0.0)) {}
|
||||
__forceinline vdouble( ReverseStepTy ) : v(_mm512_setr_pd(7.0,6.0,5.0,4.0,3.0,2.0,1.0,0.0)) {}
|
||||
|
||||
__forceinline static vdouble8 zero() { return _mm512_setzero_pd(); }
|
||||
__forceinline static vdouble8 one () { return _mm512_set1_pd(1); }
|
||||
__forceinline static vdouble8 neg_one () { return _mm512_set1_pd(-1); }
|
||||
__forceinline vdouble(ZeroTy) : v(_mm512_setzero_pd()) {}
|
||||
__forceinline vdouble(OneTy) : v(_mm512_set1_pd(1)) {}
|
||||
__forceinline vdouble(StepTy) : v(_mm512_set_pd(7.0,6.0,5.0,4.0,3.0,2.0,1.0,0.0)) {}
|
||||
__forceinline vdouble(ReverseStepTy) : v(_mm512_setr_pd(7.0,6.0,5.0,4.0,3.0,2.0,1.0,0.0)) {}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Loads and Stores
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static __forceinline void store_nt(void *__restrict__ ptr, const vdouble8& a) {
|
||||
_mm512_stream_pd((double*)ptr,a);
|
||||
_mm512_stream_pd((double*)ptr, a);
|
||||
}
|
||||
|
||||
static __forceinline vdouble8 loadu(const void* addr) {
|
||||
@@ -91,36 +87,36 @@ namespace embree
|
||||
}
|
||||
|
||||
static __forceinline void store(void* ptr, const vdouble8& v) {
|
||||
_mm512_store_pd(ptr,v);
|
||||
_mm512_store_pd(ptr, v);
|
||||
}
|
||||
|
||||
static __forceinline void storeu(void* ptr, const vdouble8& v ) {
|
||||
_mm512_storeu_pd(ptr,v);
|
||||
static __forceinline void storeu(void* ptr, const vdouble8& v) {
|
||||
_mm512_storeu_pd(ptr, v);
|
||||
}
|
||||
|
||||
static __forceinline void storeu(const vboold8& mask, double* ptr, const vdouble8& f ) {
|
||||
_mm512_mask_storeu_pd(ptr,mask,f);
|
||||
static __forceinline void storeu(const vboold8& mask, double* ptr, const vdouble8& f) {
|
||||
_mm512_mask_storeu_pd(ptr, mask, f);
|
||||
}
|
||||
|
||||
static __forceinline void store(const vboold8& mask, void* addr, const vdouble8& v2) {
|
||||
_mm512_mask_store_pd(addr,mask,v2);
|
||||
_mm512_mask_store_pd(addr, mask, v2);
|
||||
}
|
||||
|
||||
/* pass by value to avoid compiler generating inefficient code */
|
||||
static __forceinline void storeu_compact(const vboold8 mask,void * addr, const vdouble8& reg) {
|
||||
_mm512_mask_compressstoreu_pd(addr,mask,reg);
|
||||
_mm512_mask_compressstoreu_pd(addr, mask, reg);
|
||||
}
|
||||
|
||||
static __forceinline vdouble8 compact64bit(const vboold8& mask, vdouble8& v) {
|
||||
return _mm512_mask_compress_pd(v,mask,v);
|
||||
return _mm512_mask_compress_pd(v, mask, v);
|
||||
}
|
||||
|
||||
static __forceinline vdouble8 compact(const vboold8& mask, vdouble8& v) {
|
||||
return _mm512_mask_compress_pd(v,mask,v);
|
||||
return _mm512_mask_compress_pd(v, mask, v);
|
||||
}
|
||||
|
||||
static __forceinline vdouble8 compact(const vboold8& mask, const vdouble8& a, vdouble8& b) {
|
||||
return _mm512_mask_compress_pd(a,mask,b);
|
||||
return _mm512_mask_compress_pd(a, mask, b);
|
||||
}
|
||||
|
||||
|
||||
@@ -128,8 +124,8 @@ namespace embree
|
||||
/// Array Access
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline double& operator[](const size_t index) { assert(index < 8); return i[index]; }
|
||||
__forceinline const double& operator[](const size_t index) const { assert(index < 8); return i[index]; }
|
||||
__forceinline double& operator [](size_t index) { assert(index < 8); return i[index]; }
|
||||
__forceinline const double& operator [](size_t index) const { assert(index < 8); return i[index]; }
|
||||
|
||||
};
|
||||
|
||||
@@ -137,112 +133,112 @@ namespace embree
|
||||
/// Unary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vdouble8 asDouble ( const __m512& a ) { return _mm512_castps_pd(a); }
|
||||
__forceinline const vdouble8 operator +( const vdouble8& a ) { return a; }
|
||||
__forceinline const vdouble8 operator -( const vdouble8& a ) { return _mm512_sub_pd(_mm512_setzero_pd(), a); }
|
||||
__forceinline vdouble8 asDouble (const __m512& a) { return _mm512_castps_pd(a); }
|
||||
__forceinline vdouble8 operator +(const vdouble8& a) { return a; }
|
||||
__forceinline vdouble8 operator -(const vdouble8& a) { return _mm512_sub_pd(_mm512_setzero_pd(), a); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Binary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vdouble8 operator +( const vdouble8& a, const vdouble8& b ) { return _mm512_add_pd(a, b); }
|
||||
__forceinline const vdouble8 operator +( const vdouble8& a, const double b ) { return a + vdouble8(b); }
|
||||
__forceinline const vdouble8 operator +( const double a, const vdouble8& b ) { return vdouble8(a) + b; }
|
||||
__forceinline vdouble8 operator +(const vdouble8& a, const vdouble8& b) { return _mm512_add_pd(a, b); }
|
||||
__forceinline vdouble8 operator +(const vdouble8& a, double b) { return a + vdouble8(b); }
|
||||
__forceinline vdouble8 operator +(double a, const vdouble8& b) { return vdouble8(a) + b; }
|
||||
|
||||
__forceinline const vdouble8 operator -( const vdouble8& a, const vdouble8& b ) { return _mm512_sub_pd(a, b); }
|
||||
__forceinline const vdouble8 operator -( const vdouble8& a, const double b ) { return a - vdouble8(b); }
|
||||
__forceinline const vdouble8 operator -( const double a, const vdouble8& b ) { return vdouble8(a) - b; }
|
||||
__forceinline vdouble8 operator -(const vdouble8& a, const vdouble8& b) { return _mm512_sub_pd(a, b); }
|
||||
__forceinline vdouble8 operator -(const vdouble8& a, double b) { return a - vdouble8(b); }
|
||||
__forceinline vdouble8 operator -(double a, const vdouble8& b) { return vdouble8(a) - b; }
|
||||
|
||||
__forceinline const vdouble8 operator *( const vdouble8& a, const vdouble8& b ) { return _mm512_mul_pd(a, b); }
|
||||
__forceinline const vdouble8 operator *( const vdouble8& a, const double b ) { return a * vdouble8(b); }
|
||||
__forceinline const vdouble8 operator *( const double a, const vdouble8& b ) { return vdouble8(a) * b; }
|
||||
__forceinline vdouble8 operator *(const vdouble8& a, const vdouble8& b) { return _mm512_mul_pd(a, b); }
|
||||
__forceinline vdouble8 operator *(const vdouble8& a, double b) { return a * vdouble8(b); }
|
||||
__forceinline vdouble8 operator *(double a, const vdouble8& b) { return vdouble8(a) * b; }
|
||||
|
||||
__forceinline const vdouble8 operator &( const vdouble8& a, const vdouble8& b ) { return _mm512_and_pd(a, b); }
|
||||
__forceinline const vdouble8 operator &( const vdouble8& a, const double b ) { return a & vdouble8(b); }
|
||||
__forceinline const vdouble8 operator &( const double a, const vdouble8& b ) { return vdouble8(a) & b; }
|
||||
__forceinline vdouble8 operator &(const vdouble8& a, const vdouble8& b) { return _mm512_and_pd(a, b); }
|
||||
__forceinline vdouble8 operator &(const vdouble8& a, double b) { return a & vdouble8(b); }
|
||||
__forceinline vdouble8 operator &(double a, const vdouble8& b) { return vdouble8(a) & b; }
|
||||
|
||||
__forceinline const vdouble8 operator |( const vdouble8& a, const vdouble8& b ) { return _mm512_or_pd(a, b); }
|
||||
__forceinline const vdouble8 operator |( const vdouble8& a, const double b ) { return a | vdouble8(b); }
|
||||
__forceinline const vdouble8 operator |( const double a, const vdouble8& b ) { return vdouble8(a) | b; }
|
||||
__forceinline vdouble8 operator |(const vdouble8& a, const vdouble8& b) { return _mm512_or_pd(a, b); }
|
||||
__forceinline vdouble8 operator |(const vdouble8& a, double b) { return a | vdouble8(b); }
|
||||
__forceinline vdouble8 operator |(double a, const vdouble8& b) { return vdouble8(a) | b; }
|
||||
|
||||
__forceinline const vdouble8 operator ^( const vdouble8& a, const vdouble8& b ) { return _mm512_xor_pd(a, b); }
|
||||
__forceinline const vdouble8 operator ^( const vdouble8& a, const double b ) { return a ^ vdouble8(b); }
|
||||
__forceinline const vdouble8 operator ^( const double a, const vdouble8& b ) { return vdouble8(a) ^ b; }
|
||||
__forceinline vdouble8 operator ^(const vdouble8& a, const vdouble8& b) { return _mm512_xor_pd(a, b); }
|
||||
__forceinline vdouble8 operator ^(const vdouble8& a, double b) { return a ^ vdouble8(b); }
|
||||
__forceinline vdouble8 operator ^(double a, const vdouble8& b) { return vdouble8(a) ^ b; }
|
||||
|
||||
__forceinline const vdouble8 operator <<( const vdouble8& a, const unsigned int n ) { return _mm512_castsi512_pd(_mm512_slli_epi64(_mm512_castpd_si512(a), n)); }
|
||||
__forceinline const vdouble8 operator >>( const vdouble8& a, const unsigned int n ) { return _mm512_castsi512_pd(_mm512_srai_epi64(_mm512_castpd_si512(a), n)); }
|
||||
__forceinline vdouble8 operator <<(const vdouble8& a, const unsigned int n) { return _mm512_castsi512_pd(_mm512_slli_epi64(_mm512_castpd_si512(a), n)); }
|
||||
__forceinline vdouble8 operator >>(const vdouble8& a, const unsigned int n) { return _mm512_castsi512_pd(_mm512_srai_epi64(_mm512_castpd_si512(a), n)); }
|
||||
|
||||
__forceinline const vdouble8 operator <<( const vdouble8& a, const vllong8& n ) { return _mm512_castsi512_pd(_mm512_sllv_epi64(_mm512_castpd_si512(a), n)); }
|
||||
__forceinline const vdouble8 operator >>( const vdouble8& a, const vllong8& n ) { return _mm512_castsi512_pd(_mm512_srav_epi64(_mm512_castpd_si512(a), n)); }
|
||||
__forceinline vdouble8 operator <<(const vdouble8& a, const vllong8& n) { return _mm512_castsi512_pd(_mm512_sllv_epi64(_mm512_castpd_si512(a), n)); }
|
||||
__forceinline vdouble8 operator >>(const vdouble8& a, const vllong8& n) { return _mm512_castsi512_pd(_mm512_srav_epi64(_mm512_castpd_si512(a), n)); }
|
||||
|
||||
__forceinline const vdouble8 sll ( const vdouble8& a, const unsigned int b ) { return _mm512_castsi512_pd(_mm512_slli_epi64(_mm512_castpd_si512(a), b)); }
|
||||
__forceinline const vdouble8 sra ( const vdouble8& a, const unsigned int b ) { return _mm512_castsi512_pd(_mm512_srai_epi64(_mm512_castpd_si512(a), b)); }
|
||||
__forceinline const vdouble8 srl ( const vdouble8& a, const unsigned int b ) { return _mm512_castsi512_pd(_mm512_srli_epi64(_mm512_castpd_si512(a), b)); }
|
||||
__forceinline vdouble8 sll (const vdouble8& a, const unsigned int b) { return _mm512_castsi512_pd(_mm512_slli_epi64(_mm512_castpd_si512(a), b)); }
|
||||
__forceinline vdouble8 sra (const vdouble8& a, const unsigned int b) { return _mm512_castsi512_pd(_mm512_srai_epi64(_mm512_castpd_si512(a), b)); }
|
||||
__forceinline vdouble8 srl (const vdouble8& a, const unsigned int b) { return _mm512_castsi512_pd(_mm512_srli_epi64(_mm512_castpd_si512(a), b)); }
|
||||
|
||||
__forceinline const vdouble8 min( const vdouble8& a, const vdouble8& b ) { return _mm512_min_pd(a, b); }
|
||||
__forceinline const vdouble8 min( const vdouble8& a, const double b ) { return min(a,vdouble8(b)); }
|
||||
__forceinline const vdouble8 min( const double a, const vdouble8& b ) { return min(vdouble8(a),b); }
|
||||
__forceinline vdouble8 min(const vdouble8& a, const vdouble8& b) { return _mm512_min_pd(a, b); }
|
||||
__forceinline vdouble8 min(const vdouble8& a, double b) { return min(a,vdouble8(b)); }
|
||||
__forceinline vdouble8 min(double a, const vdouble8& b) { return min(vdouble8(a),b); }
|
||||
|
||||
__forceinline const vdouble8 max( const vdouble8& a, const vdouble8& b ) { return _mm512_max_pd(a, b); }
|
||||
__forceinline const vdouble8 max( const vdouble8& a, const double b ) { return max(a,vdouble8(b)); }
|
||||
__forceinline const vdouble8 max( const double a, const vdouble8& b ) { return max(vdouble8(a),b); }
|
||||
__forceinline vdouble8 max(const vdouble8& a, const vdouble8& b) { return _mm512_max_pd(a, b); }
|
||||
__forceinline vdouble8 max(const vdouble8& a, double b) { return max(a,vdouble8(b)); }
|
||||
__forceinline vdouble8 max(double a, const vdouble8& b) { return max(vdouble8(a),b); }
|
||||
|
||||
__forceinline const vdouble8 mask_add(const vboold8& mask, vdouble8& c, const vdouble8& a, const vdouble8& b) { return _mm512_mask_add_pd(c,mask,a,b); }
|
||||
__forceinline const vdouble8 mask_sub(const vboold8& mask, vdouble8& c, const vdouble8& a, const vdouble8& b) { return _mm512_mask_sub_pd(c,mask,a,b); }
|
||||
__forceinline vdouble8 mask_add(const vboold8& mask, vdouble8& c, const vdouble8& a, const vdouble8& b) { return _mm512_mask_add_pd(c,mask,a,b); }
|
||||
__forceinline vdouble8 mask_sub(const vboold8& mask, vdouble8& c, const vdouble8& a, const vdouble8& b) { return _mm512_mask_sub_pd(c,mask,a,b); }
|
||||
|
||||
__forceinline const vdouble8 mask_and(const vboold8& m,vdouble8& c, const vdouble8& a, const vdouble8& b) { return _mm512_mask_and_pd(c,m,a,b); }
|
||||
__forceinline const vdouble8 mask_or (const vboold8& m,vdouble8& c, const vdouble8& a, const vdouble8& b) { return _mm512_mask_or_pd(c,m,a,b); }
|
||||
__forceinline vdouble8 mask_and(const vboold8& m,vdouble8& c, const vdouble8& a, const vdouble8& b) { return _mm512_mask_and_pd(c,m,a,b); }
|
||||
__forceinline vdouble8 mask_or (const vboold8& m,vdouble8& c, const vdouble8& a, const vdouble8& b) { return _mm512_mask_or_pd(c,m,a,b); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Assignment Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vdouble8& operator +=( vdouble8& a, const vdouble8& b ) { return a = a + b; }
|
||||
__forceinline vdouble8& operator +=( vdouble8& a, const double b ) { return a = a + b; }
|
||||
__forceinline vdouble8& operator +=(vdouble8& a, const vdouble8& b) { return a = a + b; }
|
||||
__forceinline vdouble8& operator +=(vdouble8& a, double b) { return a = a + b; }
|
||||
|
||||
__forceinline vdouble8& operator -=( vdouble8& a, const vdouble8& b ) { return a = a - b; }
|
||||
__forceinline vdouble8& operator -=( vdouble8& a, const double b ) { return a = a - b; }
|
||||
__forceinline vdouble8& operator -=(vdouble8& a, const vdouble8& b) { return a = a - b; }
|
||||
__forceinline vdouble8& operator -=(vdouble8& a, double b) { return a = a - b; }
|
||||
|
||||
__forceinline vdouble8& operator *=( vdouble8& a, const vdouble8& b ) { return a = a * b; }
|
||||
__forceinline vdouble8& operator *=( vdouble8& a, const double b ) { return a = a * b; }
|
||||
__forceinline vdouble8& operator *=(vdouble8& a, const vdouble8& b) { return a = a * b; }
|
||||
__forceinline vdouble8& operator *=(vdouble8& a, double b) { return a = a * b; }
|
||||
|
||||
__forceinline vdouble8& operator &=( vdouble8& a, const vdouble8& b ) { return a = a & b; }
|
||||
__forceinline vdouble8& operator &=( vdouble8& a, const double b ) { return a = a & b; }
|
||||
__forceinline vdouble8& operator &=(vdouble8& a, const vdouble8& b) { return a = a & b; }
|
||||
__forceinline vdouble8& operator &=(vdouble8& a, double b) { return a = a & b; }
|
||||
|
||||
__forceinline vdouble8& operator |=( vdouble8& a, const vdouble8& b ) { return a = a | b; }
|
||||
__forceinline vdouble8& operator |=( vdouble8& a, const double b ) { return a = a | b; }
|
||||
__forceinline vdouble8& operator |=(vdouble8& a, const vdouble8& b) { return a = a | b; }
|
||||
__forceinline vdouble8& operator |=(vdouble8& a, double b) { return a = a | b; }
|
||||
|
||||
__forceinline vdouble8& operator <<=( vdouble8& a, const double b ) { return a = a << b; }
|
||||
__forceinline vdouble8& operator >>=( vdouble8& a, const double b ) { return a = a >> b; }
|
||||
__forceinline vdouble8& operator <<=(vdouble8& a, const double b) { return a = a << b; }
|
||||
__forceinline vdouble8& operator >>=(vdouble8& a, const double b) { return a = a >> b; }
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Comparison Operators + Select
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vboold8 operator ==( const vdouble8& a, const vdouble8& b ) { return _mm512_cmp_pd_mask(a,b,_MM_CMPINT_EQ); }
|
||||
__forceinline const vboold8 operator ==( const vdouble8& a, const double b ) { return a == vdouble8(b); }
|
||||
__forceinline const vboold8 operator ==( const double a, const vdouble8& b ) { return vdouble8(a) == b; }
|
||||
__forceinline vboold8 operator ==(const vdouble8& a, const vdouble8& b) { return _mm512_cmp_pd_mask(a,b,_MM_CMPINT_EQ); }
|
||||
__forceinline vboold8 operator ==(const vdouble8& a, double b) { return a == vdouble8(b); }
|
||||
__forceinline vboold8 operator ==(double a, const vdouble8& b) { return vdouble8(a) == b; }
|
||||
|
||||
__forceinline const vboold8 operator !=( const vdouble8& a, const vdouble8& b ) { return _mm512_cmp_pd_mask(a,b,_MM_CMPINT_NE); }
|
||||
__forceinline const vboold8 operator !=( const vdouble8& a, const double b ) { return a != vdouble8(b); }
|
||||
__forceinline const vboold8 operator !=( const double a, const vdouble8& b ) { return vdouble8(a) != b; }
|
||||
__forceinline vboold8 operator !=(const vdouble8& a, const vdouble8& b) { return _mm512_cmp_pd_mask(a,b,_MM_CMPINT_NE); }
|
||||
__forceinline vboold8 operator !=(const vdouble8& a, double b) { return a != vdouble8(b); }
|
||||
__forceinline vboold8 operator !=(double a, const vdouble8& b) { return vdouble8(a) != b; }
|
||||
|
||||
__forceinline const vboold8 operator < ( const vdouble8& a, const vdouble8& b ) { return _mm512_cmp_pd_mask(a,b,_MM_CMPINT_LT); }
|
||||
__forceinline const vboold8 operator < ( const vdouble8& a, const double b ) { return a < vdouble8(b); }
|
||||
__forceinline const vboold8 operator < ( const double a, const vdouble8& b ) { return vdouble8(a) < b; }
|
||||
__forceinline vboold8 operator < (const vdouble8& a, const vdouble8& b) { return _mm512_cmp_pd_mask(a,b,_MM_CMPINT_LT); }
|
||||
__forceinline vboold8 operator < (const vdouble8& a, double b) { return a < vdouble8(b); }
|
||||
__forceinline vboold8 operator < (double a, const vdouble8& b) { return vdouble8(a) < b; }
|
||||
|
||||
__forceinline const vboold8 operator >=( const vdouble8& a, const vdouble8& b ) { return _mm512_cmp_pd_mask(a,b,_MM_CMPINT_GE); }
|
||||
__forceinline const vboold8 operator >=( const vdouble8& a, const double b ) { return a >= vdouble8(b); }
|
||||
__forceinline const vboold8 operator >=( const double a, const vdouble8& b ) { return vdouble8(a) >= b; }
|
||||
__forceinline vboold8 operator >=(const vdouble8& a, const vdouble8& b) { return _mm512_cmp_pd_mask(a,b,_MM_CMPINT_GE); }
|
||||
__forceinline vboold8 operator >=(const vdouble8& a, double b) { return a >= vdouble8(b); }
|
||||
__forceinline vboold8 operator >=(double a, const vdouble8& b) { return vdouble8(a) >= b; }
|
||||
|
||||
__forceinline const vboold8 operator > ( const vdouble8& a, const vdouble8& b ) { return _mm512_cmp_pd_mask(a,b,_MM_CMPINT_GT); }
|
||||
__forceinline const vboold8 operator > ( const vdouble8& a, const double b ) { return a > vdouble8(b); }
|
||||
__forceinline const vboold8 operator > ( const double a, const vdouble8& b ) { return vdouble8(a) > b; }
|
||||
__forceinline vboold8 operator > (const vdouble8& a, const vdouble8& b) { return _mm512_cmp_pd_mask(a,b,_MM_CMPINT_GT); }
|
||||
__forceinline vboold8 operator > (const vdouble8& a, double b) { return a > vdouble8(b); }
|
||||
__forceinline vboold8 operator > (double a, const vdouble8& b) { return vdouble8(a) > b; }
|
||||
|
||||
__forceinline const vboold8 operator <=( const vdouble8& a, const vdouble8& b ) { return _mm512_cmp_pd_mask(a,b,_MM_CMPINT_LE); }
|
||||
__forceinline const vboold8 operator <=( const vdouble8& a, const double b ) { return a <= vdouble8(b); }
|
||||
__forceinline const vboold8 operator <=( const double a, const vdouble8& b ) { return vdouble8(a) <= b; }
|
||||
__forceinline vboold8 operator <=(const vdouble8& a, const vdouble8& b) { return _mm512_cmp_pd_mask(a,b,_MM_CMPINT_LE); }
|
||||
__forceinline vboold8 operator <=(const vdouble8& a, double b) { return a <= vdouble8(b); }
|
||||
__forceinline vboold8 operator <=(double a, const vdouble8& b) { return vdouble8(a) <= b; }
|
||||
|
||||
__forceinline vboold8 eq(const vdouble8& a, const vdouble8& b) { return _mm512_cmp_pd_mask(a,b,_MM_CMPINT_EQ); }
|
||||
__forceinline vboold8 ne(const vdouble8& a, const vdouble8& b) { return _mm512_cmp_pd_mask(a,b,_MM_CMPINT_NE); }
|
||||
@@ -258,7 +254,7 @@ namespace embree
|
||||
__forceinline vboold8 gt(const vboold8 mask, const vdouble8& a, const vdouble8& b) { return _mm512_mask_cmp_pd_mask(mask,a,b,_MM_CMPINT_GT); }
|
||||
__forceinline vboold8 le(const vboold8 mask, const vdouble8& a, const vdouble8& b) { return _mm512_mask_cmp_pd_mask(mask,a,b,_MM_CMPINT_LE); }
|
||||
|
||||
__forceinline const vdouble8 select( const vboold8& m, const vdouble8& t, const vdouble8& f ) {
|
||||
__forceinline vdouble8 select(const vboold8& m, const vdouble8& t, const vdouble8& f) {
|
||||
return _mm512_mask_or_pd(f,m,t,t);
|
||||
}
|
||||
|
||||
@@ -278,34 +274,38 @@ namespace embree
|
||||
// Movement/Shifting/Shuffling Functions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<size_t i>
|
||||
__forceinline const vdouble8 shuffle( const vdouble8& a ) {
|
||||
return _mm512_permute_pd(a, _MM_SHUFFLE(i, i, i, i));
|
||||
}
|
||||
|
||||
template<int A, int B, int C, int D>
|
||||
__forceinline vdouble8 shuffle (const vdouble8& v) {
|
||||
return _mm512_permute_pd(v,_MM_SHUFFLE(D,C,B,A));
|
||||
template<int i0, int i1>
|
||||
__forceinline vdouble8 shuffle(const vdouble8& v) {
|
||||
return _mm512_permute_pd(v, (i1 << 7) | (i0 << 6) | (i1 << 5) | (i0 << 4) | (i1 << 3) | (i0 << 2) | (i1 << 1) | i0);
|
||||
}
|
||||
|
||||
template<int i>
|
||||
__forceinline vdouble8 shuffle4(const vdouble8& x) {
|
||||
return _mm512_shuffle_f64x2(x,x,_MM_SHUFFLE(i,i,i,i));
|
||||
__forceinline vdouble8 shuffle(const vdouble8& v) {
|
||||
return shuffle<i, i>(v);
|
||||
}
|
||||
|
||||
template<int A, int B>
|
||||
__forceinline vdouble8 shuffle4(const vdouble8& x) {
|
||||
return _mm512_shuffle_f64x2(x,x,_MM_SHUFFLE(0,0,B,A));
|
||||
template<int i0, int i1, int i2, int i3>
|
||||
__forceinline vdouble8 shuffle(const vdouble8& v) {
|
||||
return _mm512_permutex_pd(v, _MM_SHUFFLE(i3, i2, i1, i0));
|
||||
}
|
||||
|
||||
template<int i0, int i1>
|
||||
__forceinline vdouble8 shuffle4(const vdouble8& v) {
|
||||
return _mm512_shuffle_f64x2(v, v, _MM_SHUFFLE(i1*2+1, i1*2, i0*2+1, i0*2));
|
||||
}
|
||||
|
||||
template<int i>
|
||||
__forceinline vdouble8 shuffle4(const vdouble8& v) {
|
||||
return shuffle4<i, i>(v);
|
||||
}
|
||||
|
||||
template<int i>
|
||||
__forceinline vdouble8 align_shift_right(const vdouble8& a, const vdouble8& b)
|
||||
{
|
||||
return _mm512_castsi512_pd(_mm512_alignr_epi64(_mm512_castpd_si512(a),_mm512_castpd_si512(b),i));
|
||||
__forceinline vdouble8 align_shift_right(const vdouble8& a, const vdouble8& b) {
|
||||
return _mm512_castsi512_pd(_mm512_alignr_epi64(_mm512_castpd_si512(a), _mm512_castpd_si512(b), i));
|
||||
}
|
||||
|
||||
__forceinline double toScalar(const vdouble8& a) {
|
||||
return _mm_cvtsd_f64(_mm512_castpd512_pd128(a));
|
||||
__forceinline double toScalar(const vdouble8& v) {
|
||||
return _mm_cvtsd_f64(_mm512_castpd512_pd128(v));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -316,13 +316,13 @@ namespace embree
|
||||
__forceinline vdouble8 vreduce_add4(vdouble8 x) { x = vreduce_add2(x); return x + shuffle<2,3,0,1>(x); }
|
||||
__forceinline vdouble8 vreduce_add (vdouble8 x) { x = vreduce_add4(x); return x + shuffle4<1,0>(x); }
|
||||
|
||||
__forceinline vdouble8 vreduce_min2(vdouble8 x) { return min(x,shuffle<1,0,3,2>(x)); }
|
||||
__forceinline vdouble8 vreduce_min4(vdouble8 x) { x = vreduce_min2(x); return min(x,shuffle<2,3,0,1>(x)); }
|
||||
__forceinline vdouble8 vreduce_min (vdouble8 x) { x = vreduce_min4(x); return min(x,shuffle4<1,0>(x)); }
|
||||
__forceinline vdouble8 vreduce_min2(vdouble8 x) { return min(x, shuffle<1,0,3,2>(x)); }
|
||||
__forceinline vdouble8 vreduce_min4(vdouble8 x) { x = vreduce_min2(x); return min(x, shuffle<2,3,0,1>(x)); }
|
||||
__forceinline vdouble8 vreduce_min (vdouble8 x) { x = vreduce_min4(x); return min(x, shuffle4<1,0>(x)); }
|
||||
|
||||
__forceinline vdouble8 vreduce_max2(vdouble8 x) { return max(x,shuffle<1,0,3,2>(x)); }
|
||||
__forceinline vdouble8 vreduce_max4(vdouble8 x) { x = vreduce_max2(x); return max(x,shuffle<2,3,0,1>(x)); }
|
||||
__forceinline vdouble8 vreduce_max (vdouble8 x) { x = vreduce_max4(x); return max(x,shuffle4<1,0>(x)); }
|
||||
__forceinline vdouble8 vreduce_max2(vdouble8 x) { return max(x, shuffle<1,0,3,2>(x)); }
|
||||
__forceinline vdouble8 vreduce_max4(vdouble8 x) { x = vreduce_max2(x); return max(x, shuffle<2,3,0,1>(x)); }
|
||||
__forceinline vdouble8 vreduce_max (vdouble8 x) { x = vreduce_max4(x); return max(x, shuffle4<1,0>(x)); }
|
||||
|
||||
__forceinline double reduce_add(const vdouble8& v) { return toScalar(vreduce_add(v)); }
|
||||
__forceinline double reduce_min(const vdouble8& v) { return toScalar(vreduce_min(v)); }
|
||||
@@ -333,18 +333,18 @@ namespace embree
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vdouble8 permute(const vdouble8& v, const vllong8& index) {
|
||||
return _mm512_permutexvar_pd(index,v);
|
||||
return _mm512_permutexvar_pd(index, v);
|
||||
}
|
||||
|
||||
__forceinline vdouble8 reverse(const vdouble8& a) {
|
||||
return permute(a,vllong8(reverse_step));
|
||||
return permute(a, vllong8(reverse_step));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Output Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline std::ostream& operator<<(std::ostream& cout, const vdouble8& v)
|
||||
__forceinline std::ostream& operator <<(std::ostream& cout, const vdouble8& v)
|
||||
{
|
||||
cout << "<" << v[0];
|
||||
for (size_t i=1; i<8; i++) cout << ", " << v[i];
|
||||
|
||||
+295
-193
@@ -39,47 +39,51 @@ namespace embree
|
||||
|
||||
__forceinline vfloat() {}
|
||||
__forceinline vfloat(const vfloat16& t) { v = t; }
|
||||
__forceinline vfloat16& operator=(const vfloat16& f) { v = f.v; return *this; }
|
||||
__forceinline vfloat16& operator =(const vfloat16& f) { v = f.v; return *this; }
|
||||
|
||||
__forceinline vfloat(const __m512& t) { v = t; }
|
||||
__forceinline operator __m512 () const { return v; }
|
||||
__forceinline operator __m256 () const { return _mm512_castps512_ps256(v); }
|
||||
__forceinline operator __m512() const { return v; }
|
||||
__forceinline operator __m256() const { return _mm512_castps512_ps256(v); }
|
||||
|
||||
__forceinline vfloat(const float& f) {
|
||||
__forceinline vfloat(float f) {
|
||||
v = _mm512_set1_ps(f);
|
||||
}
|
||||
__forceinline vfloat(const float& a, const float& b, const float& c, const float& d) {
|
||||
v = _mm512_set4_ps(a,b,c,d);
|
||||
|
||||
__forceinline vfloat(float a, float b, float c, float d) {
|
||||
v = _mm512_set4_ps(a, b, c, d);
|
||||
}
|
||||
|
||||
__forceinline vfloat(const vfloat4 &i) {
|
||||
__forceinline vfloat(const vfloat4& i) {
|
||||
v = _mm512_broadcast_f32x4(i);
|
||||
}
|
||||
|
||||
__forceinline vfloat(const vfloat4 &a, const vfloat4 &b, const vfloat4 &c, const vfloat4 &d) {
|
||||
v = _mm512_broadcast_f32x4(a);
|
||||
__forceinline vfloat(const vfloat4& a, const vfloat4& b, const vfloat4& c, const vfloat4& d) {
|
||||
v = _mm512_castps128_ps512(a);
|
||||
v = _mm512_insertf32x4(v, b, 1);
|
||||
v = _mm512_insertf32x4(v, c, 2);
|
||||
v = _mm512_insertf32x4(v, d, 3);
|
||||
}
|
||||
|
||||
__forceinline vfloat(const vboolf16& mask, const vfloat4 &a, const vfloat4 &b) {
|
||||
__forceinline vfloat(const vboolf16& mask, const vfloat4& a, const vfloat4& b) {
|
||||
v = _mm512_broadcast_f32x4(a);
|
||||
v = _mm512_mask_broadcast_f32x4(v,mask,b);
|
||||
}
|
||||
|
||||
__forceinline vfloat(const vfloat8 &i) {
|
||||
__forceinline vfloat(const vfloat8& i) {
|
||||
v = _mm512_castpd_ps(_mm512_broadcast_f64x4(_mm256_castps_pd(i)));
|
||||
}
|
||||
|
||||
__forceinline vfloat(const vfloat8 &a, const vfloat8 &b) { // FIXME: optimize
|
||||
const vfloat aa = _mm512_castpd_ps(_mm512_broadcast_f64x4(_mm256_castps_pd(a)));
|
||||
const vfloat bb = _mm512_castpd_ps(_mm512_broadcast_f64x4(_mm256_castps_pd(b)));
|
||||
v = _mm512_mask_blend_ps(0xff, bb, aa);
|
||||
__forceinline vfloat(const vfloat8& a, const vfloat8& b) {
|
||||
v = _mm512_castps256_ps512(a);
|
||||
#if defined(__AVX512DQ__)
|
||||
v = _mm512_insertf32x8(v, b, 1);
|
||||
#else
|
||||
v = _mm512_castpd_ps(_mm512_insertf64x4(_mm512_castps_pd(v), _mm256_castps_pd(b), 1));
|
||||
#endif
|
||||
}
|
||||
|
||||
/* WARNING: due to f64x4 the mask is considered as an 8bit mask */
|
||||
__forceinline vfloat(const vboolf16& mask, const vfloat8 &a, const vfloat8 &b) {
|
||||
__forceinline vfloat(const vboolf16& mask, const vfloat8& a, const vfloat8& b) {
|
||||
__m512d aa = _mm512_broadcast_f64x4(_mm256_castps_pd(a));
|
||||
aa = _mm512_mask_broadcast_f64x4(aa,mask,_mm256_castps_pd(b));
|
||||
v = _mm512_castpd_ps(aa);
|
||||
@@ -89,111 +93,127 @@ namespace embree
|
||||
v = _mm512_cvtepi32_ps(a);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Constants
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vfloat(ZeroTy) : v(_mm512_setzero_ps()) {}
|
||||
__forceinline vfloat(OneTy) : v(_mm512_set1_ps(1.0f)) {}
|
||||
__forceinline vfloat(PosInfTy) : v(_mm512_set1_ps(pos_inf)) {}
|
||||
__forceinline vfloat(NegInfTy) : v(_mm512_set1_ps(neg_inf)) {}
|
||||
__forceinline vfloat(StepTy) : v(_mm512_set_ps(15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0)) {}
|
||||
__forceinline vfloat(NaNTy) : v(_mm512_set1_ps(nan)) {}
|
||||
__forceinline vfloat(UndefinedTy) : v(_mm512_undefined_ps()) {}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Loads and Stores
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static __forceinline vfloat16 load (const void* const ptr) { return _mm512_load_ps((float*)ptr); }
|
||||
static __forceinline vfloat16 loadu(const void* const ptr) { return _mm512_loadu_ps((float*)ptr); }
|
||||
static __forceinline vfloat16 load (const void* ptr) { return _mm512_load_ps((float*)ptr); }
|
||||
static __forceinline vfloat16 loadu(const void* ptr) { return _mm512_loadu_ps((float*)ptr); }
|
||||
|
||||
static __forceinline vfloat16 load (const vboolf16& mask, const void* const ptr) { return _mm512_mask_load_ps (_mm512_setzero_ps(),mask,(float*)ptr); }
|
||||
static __forceinline vfloat16 loadu(const vboolf16& mask, const void* const ptr) { return _mm512_mask_loadu_ps(_mm512_setzero_ps(),mask,(float*)ptr); }
|
||||
static __forceinline vfloat16 load (const vboolf16& mask, const void* ptr) { return _mm512_mask_load_ps (_mm512_setzero_ps(),mask,(float*)ptr); }
|
||||
static __forceinline vfloat16 loadu(const vboolf16& mask, const void* ptr) { return _mm512_mask_loadu_ps(_mm512_setzero_ps(),mask,(float*)ptr); }
|
||||
|
||||
static __forceinline void store (void* const ptr, const vfloat16& v) { _mm512_store_ps ((float*)ptr,v); }
|
||||
static __forceinline void storeu(void* const ptr, const vfloat16& v) { _mm512_storeu_ps((float*)ptr,v); }
|
||||
static __forceinline void store (void* ptr, const vfloat16& v) { _mm512_store_ps ((float*)ptr,v); }
|
||||
static __forceinline void storeu(void* ptr, const vfloat16& v) { _mm512_storeu_ps((float*)ptr,v); }
|
||||
|
||||
static __forceinline void store (const vboolf16& mask, void* ptr, const vfloat16& v) { _mm512_mask_store_ps ((float*)ptr,mask,v); }
|
||||
static __forceinline void storeu(const vboolf16& mask, void* ptr, const vfloat16& v) { _mm512_mask_storeu_ps((float*)ptr,mask,v); }
|
||||
|
||||
static __forceinline void store_nt(void *__restrict__ ptr, const vfloat16& a) {
|
||||
static __forceinline void store_nt(void* __restrict__ ptr, const vfloat16& a) {
|
||||
_mm512_stream_ps((float*)ptr,a);
|
||||
}
|
||||
|
||||
static __forceinline vfloat16 broadcast(const float *const f) {
|
||||
static __forceinline vfloat16 broadcast(const float* f) {
|
||||
return _mm512_set1_ps(*f);
|
||||
}
|
||||
|
||||
static __forceinline vfloat16 compact(const vboolf16& mask, vfloat16 &v) {
|
||||
return _mm512_mask_compress_ps(v,mask,v);
|
||||
return _mm512_mask_compress_ps(v, mask, v);
|
||||
}
|
||||
static __forceinline vfloat16 compact(const vboolf16& mask, const vfloat16 &a, vfloat16 &b) {
|
||||
return _mm512_mask_compress_ps(a,mask,b);
|
||||
static __forceinline vfloat16 compact(const vboolf16& mask, vfloat16 &a, const vfloat16& b) {
|
||||
return _mm512_mask_compress_ps(a, mask, b);
|
||||
}
|
||||
|
||||
static __forceinline vfloat16 expand(const vboolf16& mask, const vfloat16& a, vfloat16& b) {
|
||||
return _mm512_mask_expand_ps(b,mask,a);
|
||||
return _mm512_mask_expand_ps(b, mask, a);
|
||||
}
|
||||
|
||||
static __forceinline vfloat16 loadu_compact(const vboolf16& mask, const void *const ptr) {
|
||||
return _mm512_mask_expandloadu_ps(vfloat16::undefined(),mask,(float*)ptr);
|
||||
static __forceinline vfloat16 loadu_compact(const vboolf16& mask, const void* ptr) {
|
||||
return _mm512_mask_expandloadu_ps(_mm512_setzero_ps(), mask, (float*)ptr);
|
||||
}
|
||||
|
||||
static __forceinline void storeu_compact(const vboolf16& mask, float *addr, const vfloat16 reg) {
|
||||
_mm512_mask_compressstoreu_ps(addr,mask,reg);
|
||||
_mm512_mask_compressstoreu_ps(addr, mask, reg);
|
||||
}
|
||||
|
||||
static __forceinline void storeu_compact_single(const vboolf16& mask, float * addr, const vfloat16 ®) {
|
||||
static __forceinline void storeu_compact_single(const vboolf16& mask, float * addr, const vfloat16& reg) {
|
||||
//_mm512_mask_compressstoreu_ps(addr,mask,reg);
|
||||
*addr = mm512_cvtss_f32(_mm512_mask_compress_ps(reg,mask,reg));
|
||||
*addr = mm512_cvtss_f32(_mm512_mask_compress_ps(reg, mask, reg));
|
||||
}
|
||||
|
||||
template<int scale = 4>
|
||||
static __forceinline vfloat16 gather(const float* ptr, const vint16& index) {
|
||||
return _mm512_i32gather_ps(index, ptr, scale);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Constants
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vfloat( ZeroTy ) : v(_mm512_setzero_ps()) {}
|
||||
__forceinline vfloat( OneTy ) : v(_mm512_set1_ps(1.0f)) {}
|
||||
__forceinline vfloat( PosInfTy ) : v(_mm512_set1_ps(pos_inf)) {}
|
||||
__forceinline vfloat( NegInfTy ) : v(_mm512_set1_ps(neg_inf)) {}
|
||||
__forceinline vfloat( StepTy ) : v(_mm512_set_ps(15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0)) {}
|
||||
__forceinline vfloat( NaNTy ) : v(_mm512_set1_ps(nan)) {}
|
||||
template<int scale = 4>
|
||||
static __forceinline vfloat16 gather(const vboolf16& mask, const float* ptr, const vint16& index) {
|
||||
vfloat16 r = zero;
|
||||
return _mm512_mask_i32gather_ps(r, mask, index, ptr, scale);
|
||||
}
|
||||
|
||||
__forceinline static vfloat16 undefined() { return _mm512_undefined_ps(); }
|
||||
__forceinline static vfloat16 zero() { return _mm512_setzero_ps(); }
|
||||
__forceinline static vfloat16 one () { return _mm512_set1_ps(1.0f); }
|
||||
__forceinline static vfloat16 ulp () { return _mm512_set1_ps(embree::ulp); }
|
||||
__forceinline static vfloat16 inf () { return _mm512_set1_ps((float)pos_inf); }
|
||||
__forceinline static vfloat16 minus_inf () { return _mm512_set1_ps((float)neg_inf); }
|
||||
template<int scale = 4>
|
||||
static __forceinline void scatter(float* ptr, const vint16& index, const vfloat16& v) {
|
||||
_mm512_i32scatter_ps(ptr, index, v, scale);
|
||||
}
|
||||
|
||||
template<int scale = 4>
|
||||
static __forceinline void scatter(const vboolf16& mask, float* ptr, const vint16& index, const vfloat16& v) {
|
||||
_mm512_mask_i32scatter_ps(ptr, mask, index, v, scale);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Array Access
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline float& operator [](const size_t index) { assert(index < 16); return f[index]; }
|
||||
__forceinline const float& operator [](const size_t index) const { assert(index < 16); return f[index]; }
|
||||
__forceinline float& operator [](size_t index) { assert(index < 16); return f[index]; }
|
||||
__forceinline const float& operator [](size_t index) const { assert(index < 16); return f[index]; }
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Unary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vfloat16 asFloat ( const __m512i& a ) { return _mm512_castsi512_ps(a); }
|
||||
__forceinline const vfloat16 operator +( const vfloat16& a ) { return a; }
|
||||
__forceinline const vfloat16 operator -( const vfloat16& a ) { return _mm512_mul_ps(a,vfloat16(-1)); }
|
||||
__forceinline const vfloat16 abs ( const vfloat16& a ) { return _mm512_castsi512_ps(_mm512_and_epi32(_mm512_castps_si512(a),_mm512_set1_epi32(0x7FFFFFFF))); }
|
||||
__forceinline const vfloat16 signmsk ( const vfloat16& a ) { return _mm512_castsi512_ps(_mm512_and_epi32(_mm512_castps_si512(a),_mm512_set1_epi32(0x80000000))); }
|
||||
__forceinline vfloat16 asFloat(const __m512i& a) { return _mm512_castsi512_ps(a); }
|
||||
|
||||
__forceinline const vfloat16 rcp(const vfloat16& a) {
|
||||
__forceinline vfloat16 operator +(const vfloat16& a) { return a; }
|
||||
__forceinline vfloat16 operator -(const vfloat16& a) { return _mm512_mul_ps(a,vfloat16(-1)); }
|
||||
|
||||
__forceinline vfloat16 abs (const vfloat16& a) { return _mm512_castsi512_ps(_mm512_and_epi32(_mm512_castps_si512(a),_mm512_set1_epi32(0x7FFFFFFF))); }
|
||||
__forceinline vfloat16 signmsk(const vfloat16& a) { return _mm512_castsi512_ps(_mm512_and_epi32(_mm512_castps_si512(a),_mm512_set1_epi32(0x80000000))); }
|
||||
|
||||
__forceinline vfloat16 rcp(const vfloat16& a) {
|
||||
#if defined(__AVX512ER__)
|
||||
return _mm512_rcp28_ps(a);
|
||||
#else
|
||||
const vfloat16 r = _mm512_rcp14_ps(a.v);
|
||||
const vfloat16 r = _mm512_rcp14_ps(a);
|
||||
return _mm512_mul_ps(r, _mm512_fnmadd_ps(r, a, vfloat16(2.0f)));
|
||||
#endif
|
||||
}
|
||||
|
||||
__forceinline const vfloat16 sqr ( const vfloat16& a ) { return _mm512_mul_ps(a,a); }
|
||||
__forceinline const vfloat16 sqrt ( const vfloat16& a ) { return _mm512_sqrt_ps(a); }
|
||||
__forceinline vfloat16 sqr (const vfloat16& a) { return _mm512_mul_ps(a,a); }
|
||||
__forceinline vfloat16 sqrt(const vfloat16& a) { return _mm512_sqrt_ps(a); }
|
||||
|
||||
__forceinline const vfloat16 rsqrt( const vfloat16& a )
|
||||
__forceinline vfloat16 rsqrt(const vfloat16& a)
|
||||
{
|
||||
#if defined(__AVX512VL__)
|
||||
const vfloat16 r = _mm512_rsqrt14_ps(a.v);
|
||||
const vfloat16 r = _mm512_rsqrt14_ps(a);
|
||||
return _mm512_fmadd_ps(_mm512_set1_ps(1.5f), r,
|
||||
_mm512_mul_ps(_mm512_mul_ps(_mm512_mul_ps(a, _mm512_set1_ps(-0.5f)), r), _mm512_mul_ps(r, r)));
|
||||
#else
|
||||
return _mm512_rsqrt28_ps(a.v);
|
||||
return _mm512_rsqrt28_ps(a);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -201,43 +221,43 @@ namespace embree
|
||||
/// Binary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vfloat16 operator +( const vfloat16& a, const vfloat16& b ) { return _mm512_add_ps(a, b); }
|
||||
__forceinline const vfloat16 operator +( const vfloat16& a, const float& b ) { return a + vfloat16(b); }
|
||||
__forceinline const vfloat16 operator +( const float& a, const vfloat16& b ) { return vfloat16(a) + b; }
|
||||
__forceinline vfloat16 operator +(const vfloat16& a, const vfloat16& b) { return _mm512_add_ps(a, b); }
|
||||
__forceinline vfloat16 operator +(const vfloat16& a, float b) { return a + vfloat16(b); }
|
||||
__forceinline vfloat16 operator +(float a, const vfloat16& b) { return vfloat16(a) + b; }
|
||||
|
||||
__forceinline const vfloat16 operator -( const vfloat16& a, const vfloat16& b ) { return _mm512_sub_ps(a, b); }
|
||||
__forceinline const vfloat16 operator -( const vfloat16& a, const float& b ) { return a - vfloat16(b); }
|
||||
__forceinline const vfloat16 operator -( const float& a, const vfloat16& b ) { return vfloat16(a) - b; }
|
||||
__forceinline vfloat16 operator -(const vfloat16& a, const vfloat16& b) { return _mm512_sub_ps(a, b); }
|
||||
__forceinline vfloat16 operator -(const vfloat16& a, float b) { return a - vfloat16(b); }
|
||||
__forceinline vfloat16 operator -(float a, const vfloat16& b) { return vfloat16(a) - b; }
|
||||
|
||||
__forceinline const vfloat16 operator *( const vfloat16& a, const vfloat16& b ) { return _mm512_mul_ps(a, b); }
|
||||
__forceinline const vfloat16 operator *( const vfloat16& a, const float& b ) { return a * vfloat16(b); }
|
||||
__forceinline const vfloat16 operator *( const float& a, const vfloat16& b ) { return vfloat16(a) * b; }
|
||||
__forceinline vfloat16 operator *(const vfloat16& a, const vfloat16& b) { return _mm512_mul_ps(a, b); }
|
||||
__forceinline vfloat16 operator *(const vfloat16& a, float b) { return a * vfloat16(b); }
|
||||
__forceinline vfloat16 operator *(float a, const vfloat16& b) { return vfloat16(a) * b; }
|
||||
|
||||
__forceinline const vfloat16 operator /( const vfloat16& a, const vfloat16& b ) { return _mm512_div_ps(a,b); }
|
||||
__forceinline const vfloat16 operator /( const vfloat16& a, const float& b ) { return a/vfloat16(b); }
|
||||
__forceinline const vfloat16 operator /( const float& a, const vfloat16& b ) { return vfloat16(a)/b; }
|
||||
__forceinline vfloat16 operator /(const vfloat16& a, const vfloat16& b) { return _mm512_div_ps(a,b); }
|
||||
__forceinline vfloat16 operator /(const vfloat16& a, float b) { return a/vfloat16(b); }
|
||||
__forceinline vfloat16 operator /(float a, const vfloat16& b) { return vfloat16(a)/b; }
|
||||
|
||||
__forceinline const vfloat16 operator^(const vfloat16& a, const vfloat16& b) {
|
||||
__forceinline vfloat16 operator ^(const vfloat16& a, const vfloat16& b) {
|
||||
return _mm512_castsi512_ps(_mm512_xor_epi32(_mm512_castps_si512(a),_mm512_castps_si512(b)));
|
||||
}
|
||||
|
||||
__forceinline const vfloat16 min( const vfloat16& a, const vfloat16& b ) {
|
||||
__forceinline vfloat16 min(const vfloat16& a, const vfloat16& b) {
|
||||
return _mm512_min_ps(a,b);
|
||||
}
|
||||
__forceinline const vfloat16 min( const vfloat16& a, const float& b ) {
|
||||
__forceinline vfloat16 min(const vfloat16& a, float b) {
|
||||
return _mm512_min_ps(a,vfloat16(b));
|
||||
}
|
||||
__forceinline const vfloat16 min( const float& a, const vfloat16& b ) {
|
||||
__forceinline vfloat16 min(const float& a, const vfloat16& b) {
|
||||
return _mm512_min_ps(vfloat16(a),b);
|
||||
}
|
||||
|
||||
__forceinline const vfloat16 max( const vfloat16& a, const vfloat16& b ) {
|
||||
__forceinline vfloat16 max(const vfloat16& a, const vfloat16& b) {
|
||||
return _mm512_max_ps(a,b);
|
||||
}
|
||||
__forceinline const vfloat16 max( const vfloat16& a, const float& b ) {
|
||||
__forceinline vfloat16 max(const vfloat16& a, float b) {
|
||||
return _mm512_max_ps(a,vfloat16(b));
|
||||
}
|
||||
__forceinline const vfloat16 max( const float& a, const vfloat16& b ) {
|
||||
__forceinline vfloat16 max(const float& a, const vfloat16& b) {
|
||||
return _mm512_max_ps(vfloat16(a),b);
|
||||
}
|
||||
|
||||
@@ -276,12 +296,11 @@ namespace embree
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vfloat16 madd (const vfloat16& a, const vfloat16& b, const vfloat16& c) { return _mm512_fmadd_ps(a,b,c); }
|
||||
|
||||
__forceinline vfloat16 msub (const vfloat16& a, const vfloat16& b, const vfloat16& c) { return _mm512_fmsub_ps(a,b,c); }
|
||||
__forceinline vfloat16 nmadd (const vfloat16& a, const vfloat16& b, const vfloat16& c) { return _mm512_fnmadd_ps(a,b,c); }
|
||||
__forceinline vfloat16 nmsub (const vfloat16& a, const vfloat16& b, const vfloat16& c) { return _mm512_fnmsub_ps(a,b,c); }
|
||||
__forceinline vfloat16 nmadd(const vfloat16& a, const vfloat16& b, const vfloat16& c) { return _mm512_fnmadd_ps(a,b,c); }
|
||||
__forceinline vfloat16 nmsub(const vfloat16& a, const vfloat16& b, const vfloat16& c) { return _mm512_fnmsub_ps(a,b,c); }
|
||||
|
||||
__forceinline vfloat16 mask_msub (const vboolf16& mask,const vfloat16& a, const vfloat16& b, const vfloat16& c) { return _mm512_mask_fmsub_ps(a,mask,b,c); }
|
||||
__forceinline vfloat16 mask_msub(const vboolf16& mask,const vfloat16& a, const vfloat16& b, const vfloat16& c) { return _mm512_mask_fmsub_ps(a,mask,b,c); }
|
||||
|
||||
__forceinline vfloat16 madd231 (const vfloat16& a, const vfloat16& b, const vfloat16& c) { return _mm512_fmadd_ps(c,b,a); }
|
||||
__forceinline vfloat16 msub213 (const vfloat16& a, const vfloat16& b, const vfloat16& c) { return _mm512_fmsub_ps(a,b,c); }
|
||||
@@ -293,74 +312,74 @@ namespace embree
|
||||
/// Operators with rounding
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vfloat16 madd_round_down (const vfloat16& a, const vfloat16& b, const vfloat16& c) { return _mm512_fmadd_round_ps(a,b,c,_MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC); }
|
||||
__forceinline vfloat16 madd_round_up (const vfloat16& a, const vfloat16& b, const vfloat16& c) { return _mm512_fmadd_round_ps(a,b,c,_MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC); }
|
||||
__forceinline vfloat16 madd_round_down(const vfloat16& a, const vfloat16& b, const vfloat16& c) { return _mm512_fmadd_round_ps(a,b,c,_MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC); }
|
||||
__forceinline vfloat16 madd_round_up (const vfloat16& a, const vfloat16& b, const vfloat16& c) { return _mm512_fmadd_round_ps(a,b,c,_MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC); }
|
||||
|
||||
__forceinline vfloat16 mul_round_down (const vfloat16& a, const vfloat16& b) { return _mm512_mul_round_ps(a,b,_MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC); }
|
||||
__forceinline vfloat16 mul_round_up (const vfloat16& a, const vfloat16& b) { return _mm512_mul_round_ps(a,b,_MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC); }
|
||||
__forceinline vfloat16 mul_round_down(const vfloat16& a, const vfloat16& b) { return _mm512_mul_round_ps(a,b,_MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC); }
|
||||
__forceinline vfloat16 mul_round_up (const vfloat16& a, const vfloat16& b) { return _mm512_mul_round_ps(a,b,_MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC); }
|
||||
|
||||
__forceinline vfloat16 add_round_down (const vfloat16& a, const vfloat16& b) { return _mm512_add_round_ps(a,b,_MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC); }
|
||||
__forceinline vfloat16 add_round_up (const vfloat16& a, const vfloat16& b) { return _mm512_add_round_ps(a,b,_MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC); }
|
||||
__forceinline vfloat16 add_round_down(const vfloat16& a, const vfloat16& b) { return _mm512_add_round_ps(a,b,_MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC); }
|
||||
__forceinline vfloat16 add_round_up (const vfloat16& a, const vfloat16& b) { return _mm512_add_round_ps(a,b,_MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC); }
|
||||
|
||||
__forceinline vfloat16 sub_round_down (const vfloat16& a, const vfloat16& b) { return _mm512_sub_round_ps(a,b,_MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC); }
|
||||
__forceinline vfloat16 sub_round_up (const vfloat16& a, const vfloat16& b) { return _mm512_sub_round_ps(a,b,_MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC); }
|
||||
__forceinline vfloat16 sub_round_down(const vfloat16& a, const vfloat16& b) { return _mm512_sub_round_ps(a,b,_MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC); }
|
||||
__forceinline vfloat16 sub_round_up (const vfloat16& a, const vfloat16& b) { return _mm512_sub_round_ps(a,b,_MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC); }
|
||||
|
||||
__forceinline vfloat16 div_round_down (const vfloat16& a, const vfloat16& b) { return _mm512_div_round_ps(a,b,_MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC); }
|
||||
__forceinline vfloat16 div_round_up (const vfloat16& a, const vfloat16& b) { return _mm512_div_round_ps(a,b,_MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC); }
|
||||
__forceinline vfloat16 div_round_down(const vfloat16& a, const vfloat16& b) { return _mm512_div_round_ps(a,b,_MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC); }
|
||||
__forceinline vfloat16 div_round_up (const vfloat16& a, const vfloat16& b) { return _mm512_div_round_ps(a,b,_MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC); }
|
||||
|
||||
__forceinline vfloat16 mask_msub_round_down (const vboolf16& mask,const vfloat16& a, const vfloat16& b, const vfloat16& c) { return _mm512_mask_fmsub_round_ps(a,mask,b,c,_MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC); }
|
||||
__forceinline vfloat16 mask_msub_round_up (const vboolf16& mask,const vfloat16& a, const vfloat16& b, const vfloat16& c) { return _mm512_mask_fmsub_round_ps(a,mask,b,c,_MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC); }
|
||||
__forceinline vfloat16 mask_msub_round_down(const vboolf16& mask,const vfloat16& a, const vfloat16& b, const vfloat16& c) { return _mm512_mask_fmsub_round_ps(a,mask,b,c,_MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC); }
|
||||
__forceinline vfloat16 mask_msub_round_up (const vboolf16& mask,const vfloat16& a, const vfloat16& b, const vfloat16& c) { return _mm512_mask_fmsub_round_ps(a,mask,b,c,_MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC); }
|
||||
|
||||
__forceinline vfloat16 mask_mul_round_down (const vboolf16& mask,const vfloat16& a, const vfloat16& b, const vfloat16& c) { return _mm512_mask_mul_round_ps(a,mask,b,c,_MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC); }
|
||||
__forceinline vfloat16 mask_mul_round_up (const vboolf16& mask,const vfloat16& a, const vfloat16& b, const vfloat16& c) { return _mm512_mask_mul_round_ps(a,mask,b,c,_MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC); }
|
||||
__forceinline vfloat16 mask_mul_round_down(const vboolf16& mask,const vfloat16& a, const vfloat16& b, const vfloat16& c) { return _mm512_mask_mul_round_ps(a,mask,b,c,_MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC); }
|
||||
__forceinline vfloat16 mask_mul_round_up (const vboolf16& mask,const vfloat16& a, const vfloat16& b, const vfloat16& c) { return _mm512_mask_mul_round_ps(a,mask,b,c,_MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC); }
|
||||
|
||||
__forceinline vfloat16 mask_sub_round_down (const vboolf16& mask,const vfloat16& a, const vfloat16& b, const vfloat16& c) { return _mm512_mask_sub_round_ps(a,mask,b,c,_MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC); }
|
||||
__forceinline vfloat16 mask_sub_round_up (const vboolf16& mask,const vfloat16& a, const vfloat16& b, const vfloat16& c) { return _mm512_mask_sub_round_ps(a,mask,b,c,_MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC); }
|
||||
__forceinline vfloat16 mask_sub_round_down(const vboolf16& mask,const vfloat16& a, const vfloat16& b, const vfloat16& c) { return _mm512_mask_sub_round_ps(a,mask,b,c,_MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC); }
|
||||
__forceinline vfloat16 mask_sub_round_up (const vboolf16& mask,const vfloat16& a, const vfloat16& b, const vfloat16& c) { return _mm512_mask_sub_round_ps(a,mask,b,c,_MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC); }
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Assignment Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vfloat16& operator +=( vfloat16& a, const vfloat16& b ) { return a = a + b; }
|
||||
__forceinline vfloat16& operator +=( vfloat16& a, const float& b ) { return a = a + b; }
|
||||
__forceinline vfloat16& operator +=(vfloat16& a, const vfloat16& b) { return a = a + b; }
|
||||
__forceinline vfloat16& operator +=(vfloat16& a, float b) { return a = a + b; }
|
||||
|
||||
__forceinline vfloat16& operator -=( vfloat16& a, const vfloat16& b ) { return a = a - b; }
|
||||
__forceinline vfloat16& operator -=( vfloat16& a, const float& b ) { return a = a - b; }
|
||||
__forceinline vfloat16& operator -=(vfloat16& a, const vfloat16& b) { return a = a - b; }
|
||||
__forceinline vfloat16& operator -=(vfloat16& a, float b) { return a = a - b; }
|
||||
|
||||
__forceinline vfloat16& operator *=( vfloat16& a, const vfloat16& b ) { return a = a * b; }
|
||||
__forceinline vfloat16& operator *=( vfloat16& a, const float& b ) { return a = a * b; }
|
||||
__forceinline vfloat16& operator *=(vfloat16& a, const vfloat16& b) { return a = a * b; }
|
||||
__forceinline vfloat16& operator *=(vfloat16& a, float b) { return a = a * b; }
|
||||
|
||||
__forceinline vfloat16& operator /=( vfloat16& a, const vfloat16& b ) { return a = a / b; }
|
||||
__forceinline vfloat16& operator /=( vfloat16& a, const float& b ) { return a = a / b; }
|
||||
__forceinline vfloat16& operator /=(vfloat16& a, const vfloat16& b) { return a = a / b; }
|
||||
__forceinline vfloat16& operator /=(vfloat16& a, float b) { return a = a / b; }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Comparison Operators + Select
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vboolf16 operator ==( const vfloat16& a, const vfloat16& b ) { return _mm512_cmp_ps_mask(a,b,_MM_CMPINT_EQ); }
|
||||
__forceinline const vboolf16 operator ==( const vfloat16& a, const float& b ) { return a == vfloat16(b); }
|
||||
__forceinline const vboolf16 operator ==( const float& a, const vfloat16& b ) { return vfloat16(a) == b; }
|
||||
__forceinline vboolf16 operator ==(const vfloat16& a, const vfloat16& b) { return _mm512_cmp_ps_mask(a,b,_MM_CMPINT_EQ); }
|
||||
__forceinline vboolf16 operator ==(const vfloat16& a, float b) { return a == vfloat16(b); }
|
||||
__forceinline vboolf16 operator ==(float a, const vfloat16& b) { return vfloat16(a) == b; }
|
||||
|
||||
__forceinline const vboolf16 operator !=( const vfloat16& a, const vfloat16& b ) { return _mm512_cmp_ps_mask(a,b,_MM_CMPINT_NE); }
|
||||
__forceinline const vboolf16 operator !=( const vfloat16& a, const float& b ) { return a != vfloat16(b); }
|
||||
__forceinline const vboolf16 operator !=( const float& a, const vfloat16& b ) { return vfloat16(a) != b; }
|
||||
__forceinline vboolf16 operator !=(const vfloat16& a, const vfloat16& b) { return _mm512_cmp_ps_mask(a,b,_MM_CMPINT_NE); }
|
||||
__forceinline vboolf16 operator !=(const vfloat16& a, float b) { return a != vfloat16(b); }
|
||||
__forceinline vboolf16 operator !=(float a, const vfloat16& b) { return vfloat16(a) != b; }
|
||||
|
||||
__forceinline const vboolf16 operator < ( const vfloat16& a, const vfloat16& b ) { return _mm512_cmp_ps_mask(a,b,_MM_CMPINT_LT); }
|
||||
__forceinline const vboolf16 operator < ( const vfloat16& a, const float& b ) { return a < vfloat16(b); }
|
||||
__forceinline const vboolf16 operator < ( const float& a, const vfloat16& b ) { return vfloat16(a) < b; }
|
||||
__forceinline vboolf16 operator < (const vfloat16& a, const vfloat16& b) { return _mm512_cmp_ps_mask(a,b,_MM_CMPINT_LT); }
|
||||
__forceinline vboolf16 operator < (const vfloat16& a, float b) { return a < vfloat16(b); }
|
||||
__forceinline vboolf16 operator < (float a, const vfloat16& b) { return vfloat16(a) < b; }
|
||||
|
||||
__forceinline const vboolf16 operator >=( const vfloat16& a, const vfloat16& b ) { return _mm512_cmp_ps_mask(a,b,_MM_CMPINT_GE); }
|
||||
__forceinline const vboolf16 operator >=( const vfloat16& a, const float& b ) { return a >= vfloat16(b); }
|
||||
__forceinline const vboolf16 operator >=( const float& a, const vfloat16& b ) { return vfloat16(a) >= b; }
|
||||
__forceinline vboolf16 operator >=(const vfloat16& a, const vfloat16& b) { return _mm512_cmp_ps_mask(a,b,_MM_CMPINT_GE); }
|
||||
__forceinline vboolf16 operator >=(const vfloat16& a, float b) { return a >= vfloat16(b); }
|
||||
__forceinline vboolf16 operator >=(float a, const vfloat16& b) { return vfloat16(a) >= b; }
|
||||
|
||||
__forceinline const vboolf16 operator > ( const vfloat16& a, const vfloat16& b ) { return _mm512_cmp_ps_mask(a,b,_MM_CMPINT_GT); }
|
||||
__forceinline const vboolf16 operator > ( const vfloat16& a, const float& b ) { return a > vfloat16(b); }
|
||||
__forceinline const vboolf16 operator > ( const float& a, const vfloat16& b ) { return vfloat16(a) > b; }
|
||||
__forceinline vboolf16 operator > (const vfloat16& a, const vfloat16& b) { return _mm512_cmp_ps_mask(a,b,_MM_CMPINT_GT); }
|
||||
__forceinline vboolf16 operator > (const vfloat16& a, float b) { return a > vfloat16(b); }
|
||||
__forceinline vboolf16 operator > (float a, const vfloat16& b) { return vfloat16(a) > b; }
|
||||
|
||||
__forceinline const vboolf16 operator <=( const vfloat16& a, const vfloat16& b ) { return _mm512_cmp_ps_mask(a,b,_MM_CMPINT_LE); }
|
||||
__forceinline const vboolf16 operator <=( const vfloat16& a, const float& b ) { return a <= vfloat16(b); }
|
||||
__forceinline const vboolf16 operator <=( const float& a, const vfloat16& b ) { return vfloat16(a) <= b; }
|
||||
__forceinline vboolf16 operator <=(const vfloat16& a, const vfloat16& b) { return _mm512_cmp_ps_mask(a,b,_MM_CMPINT_LE); }
|
||||
__forceinline vboolf16 operator <=(const vfloat16& a, float b) { return a <= vfloat16(b); }
|
||||
__forceinline vboolf16 operator <=(float a, const vfloat16& b) { return vfloat16(a) <= b; }
|
||||
|
||||
__forceinline vboolf16 eq(const vfloat16& a, const vfloat16& b) { return _mm512_cmp_ps_mask(a,b,_MM_CMPINT_EQ); }
|
||||
__forceinline vboolf16 ne(const vfloat16& a, const vfloat16& b) { return _mm512_cmp_ps_mask(a,b,_MM_CMPINT_NE); }
|
||||
@@ -376,7 +395,7 @@ namespace embree
|
||||
__forceinline vboolf16 gt(const vboolf16& mask, const vfloat16& a, const vfloat16& b) { return _mm512_mask_cmp_ps_mask(mask,a,b,_MM_CMPINT_GT); }
|
||||
__forceinline vboolf16 le(const vboolf16& mask, const vfloat16& a, const vfloat16& b) { return _mm512_mask_cmp_ps_mask(mask,a,b,_MM_CMPINT_LE); }
|
||||
|
||||
__forceinline const vfloat16 select( const vboolf16& s, const vfloat16& t, const vfloat16& f ) {
|
||||
__forceinline vfloat16 select(const vboolf16& s, const vfloat16& t, const vfloat16& f) {
|
||||
return _mm512_mask_blend_ps(s, f, t);
|
||||
}
|
||||
|
||||
@@ -409,61 +428,86 @@ namespace embree
|
||||
/// Movement/Shifting/Shuffling Functions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<size_t i>
|
||||
__forceinline const vfloat16 shuffle( const vfloat16& a ) {
|
||||
return _mm512_permute_ps(a, _MM_SHUFFLE(i, i, i, i));
|
||||
__forceinline vfloat16 unpacklo(const vfloat16& a, const vfloat16& b) { return _mm512_unpacklo_ps(a, b); }
|
||||
__forceinline vfloat16 unpackhi(const vfloat16& a, const vfloat16& b) { return _mm512_unpackhi_ps(a, b); }
|
||||
|
||||
template<int i>
|
||||
__forceinline vfloat16 shuffle(const vfloat16& v) {
|
||||
return _mm512_permute_ps(v, _MM_SHUFFLE(i, i, i, i));
|
||||
}
|
||||
|
||||
template<int A, int B, int C, int D>
|
||||
__forceinline vfloat16 shuffle (const vfloat16& v) {
|
||||
return _mm512_permute_ps(v,_MM_SHUFFLE(D,C,B,A));
|
||||
template<int i0, int i1, int i2, int i3>
|
||||
__forceinline vfloat16 shuffle(const vfloat16& v) {
|
||||
return _mm512_permute_ps(v, _MM_SHUFFLE(i3, i2, i1, i0));
|
||||
}
|
||||
|
||||
template<int i>
|
||||
__forceinline vfloat16 shuffle4(const vfloat16& x) {
|
||||
return _mm512_shuffle_f32x4(x,x,_MM_SHUFFLE(i,i,i,i));
|
||||
__forceinline vfloat16 shuffle4(const vfloat16& v) {
|
||||
return _mm512_shuffle_f32x4(v, v ,_MM_SHUFFLE(i, i, i, i));
|
||||
}
|
||||
|
||||
template<int A, int B, int C, int D>
|
||||
__forceinline vfloat16 shuffle4(const vfloat16& x) {
|
||||
return _mm512_shuffle_f32x4(x,x,_MM_SHUFFLE(D,C,B,A));
|
||||
template<int i0, int i1, int i2, int i3>
|
||||
__forceinline vfloat16 shuffle4(const vfloat16& v) {
|
||||
return _mm512_shuffle_f32x4(v, v, _MM_SHUFFLE(i3, i2, i1, i0));
|
||||
}
|
||||
|
||||
__forceinline vfloat16 permute(vfloat16 v,__m512i index)
|
||||
{
|
||||
return _mm512_castsi512_ps(_mm512_permutexvar_epi32(index,_mm512_castps_si512(v)));
|
||||
__forceinline vfloat16 interleave_even(const vfloat16& a, const vfloat16& b) {
|
||||
return _mm512_castsi512_ps(_mm512_mask_shuffle_epi32(_mm512_castps_si512(a), mm512_int2mask(0xaaaa), _mm512_castps_si512(b), 0xb1));
|
||||
}
|
||||
|
||||
__forceinline vfloat16 reverse(const vfloat16 &a)
|
||||
{
|
||||
return permute(a,_mm512_setr_epi32(15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0));
|
||||
__forceinline vfloat16 interleave_odd(const vfloat16& a, const vfloat16& b) {
|
||||
return _mm512_castsi512_ps(_mm512_mask_shuffle_epi32(_mm512_castps_si512(b), mm512_int2mask(0x5555), _mm512_castps_si512(a), 0xb1));
|
||||
}
|
||||
|
||||
__forceinline vfloat16 interleave2_even(const vfloat16& a, const vfloat16& b) {
|
||||
/* mask should be 8-bit but is 16-bit to reuse for interleave_even */
|
||||
return _mm512_castsi512_ps(_mm512_mask_permutex_epi64(_mm512_castps_si512(a), mm512_int2mask(0xaaaa), _mm512_castps_si512(b), 0xb1));
|
||||
}
|
||||
|
||||
__forceinline vfloat16 interleave2_odd(const vfloat16& a, const vfloat16& b) {
|
||||
/* mask should be 8-bit but is 16-bit to reuse for interleave_odd */
|
||||
return _mm512_castsi512_ps(_mm512_mask_permutex_epi64(_mm512_castps_si512(b), mm512_int2mask(0x5555), _mm512_castps_si512(a), 0xb1));
|
||||
}
|
||||
|
||||
__forceinline vfloat16 interleave4_even(const vfloat16& a, const vfloat16& b) {
|
||||
return _mm512_castsi512_ps(_mm512_mask_permutex_epi64(_mm512_castps_si512(a), mm512_int2mask(0xcc), _mm512_castps_si512(b), 0x4e));
|
||||
}
|
||||
|
||||
__forceinline vfloat16 interleave4_odd(const vfloat16& a, const vfloat16& b) {
|
||||
return _mm512_castsi512_ps(_mm512_mask_permutex_epi64(_mm512_castps_si512(b), mm512_int2mask(0x33), _mm512_castps_si512(a), 0x4e));
|
||||
}
|
||||
|
||||
__forceinline vfloat16 permute(vfloat16 v, __m512i index) {
|
||||
return _mm512_castsi512_ps(_mm512_permutexvar_epi32(index, _mm512_castps_si512(v)));
|
||||
}
|
||||
|
||||
__forceinline vfloat16 reverse(const vfloat16& v) {
|
||||
return permute(v,_mm512_setr_epi32(15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0));
|
||||
}
|
||||
|
||||
template<int i>
|
||||
__forceinline vfloat16 align_shift_right(const vfloat16 &a, const vfloat16 &b)
|
||||
{
|
||||
__forceinline vfloat16 align_shift_right(const vfloat16& a, const vfloat16& b) {
|
||||
return _mm512_castsi512_ps(_mm512_alignr_epi32(_mm512_castps_si512(a),_mm512_castps_si512(b),i));
|
||||
};
|
||||
|
||||
template<int i>
|
||||
__forceinline vfloat16 mask_align_shift_right(const vboolf16 &mask,vfloat16 &c,const vfloat16 &a, const vfloat16 &b)
|
||||
{
|
||||
__forceinline vfloat16 mask_align_shift_right(const vboolf16& mask, vfloat16& c, const vfloat16& a, const vfloat16& b) {
|
||||
return _mm512_castsi512_ps(_mm512_mask_alignr_epi32(_mm512_castps_si512(c),mask,_mm512_castps_si512(a),_mm512_castps_si512(b),i));
|
||||
};
|
||||
|
||||
__forceinline vfloat16 shift_left_1(const vfloat16 &a) {
|
||||
vfloat16 z = vfloat16::zero();
|
||||
__forceinline vfloat16 shift_left_1(const vfloat16& a) {
|
||||
vfloat16 z = zero;
|
||||
return mask_align_shift_right<15>(0xfffe,z,a,a);
|
||||
}
|
||||
|
||||
__forceinline vfloat16 shift_right_1( const vfloat16& x) {
|
||||
__forceinline vfloat16 shift_right_1(const vfloat16& x) {
|
||||
return align_shift_right<1>(zero,x);
|
||||
}
|
||||
|
||||
__forceinline float toScalar(const vfloat16& a) { return mm512_cvtss_f32(a); }
|
||||
__forceinline float toScalar(const vfloat16& v) { return mm512_cvtss_f32(v); }
|
||||
|
||||
|
||||
template<int i> __forceinline const vfloat16 insert4(const vfloat16& a, const vfloat4& b) { return _mm512_insertf32x4(a, b, i); }
|
||||
template<int i> __forceinline vfloat16 insert4(const vfloat16& a, const vfloat4& b) { return _mm512_insertf32x4(a, b, i); }
|
||||
|
||||
template<int N, int i>
|
||||
vfloat<N> extractN(const vfloat16& v);
|
||||
@@ -482,6 +526,79 @@ namespace embree
|
||||
template<int i> __forceinline vfloat8 extract8 (const vfloat16& v) { return _mm512_extractf32x8_ps(v, i); }
|
||||
template<> __forceinline vfloat8 extract8<0>(const vfloat16& v) { return _mm512_castps512_ps256(v); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Transpose
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline void transpose(const vfloat16& r0, const vfloat16& r1, const vfloat16& r2, const vfloat16& r3,
|
||||
vfloat16& c0, vfloat16& c1, vfloat16& c2, vfloat16& c3)
|
||||
{
|
||||
#if defined(__AVX512F__) && !defined(__AVX512VL__) // KNL
|
||||
vfloat16 a0a1_c0c1 = interleave_even(r0, r1);
|
||||
vfloat16 a2a3_c2c3 = interleave_even(r2, r3);
|
||||
vfloat16 b0b1_d0d1 = interleave_odd (r0, r1);
|
||||
vfloat16 b2b3_d2d3 = interleave_odd (r2, r3);
|
||||
|
||||
c0 = interleave2_even(a0a1_c0c1, a2a3_c2c3);
|
||||
c1 = interleave2_even(b0b1_d0d1, b2b3_d2d3);
|
||||
c2 = interleave2_odd (a0a1_c0c1, a2a3_c2c3);
|
||||
c3 = interleave2_odd (b0b1_d0d1, b2b3_d2d3);
|
||||
#else
|
||||
vfloat16 a0a2_b0b2 = unpacklo(r0, r2);
|
||||
vfloat16 c0c2_d0d2 = unpackhi(r0, r2);
|
||||
vfloat16 a1a3_b1b3 = unpacklo(r1, r3);
|
||||
vfloat16 c1c3_d1d3 = unpackhi(r1, r3);
|
||||
|
||||
c0 = unpacklo(a0a2_b0b2, a1a3_b1b3);
|
||||
c1 = unpackhi(a0a2_b0b2, a1a3_b1b3);
|
||||
c2 = unpacklo(c0c2_d0d2, c1c3_d1d3);
|
||||
c3 = unpackhi(c0c2_d0d2, c1c3_d1d3);
|
||||
#endif
|
||||
}
|
||||
|
||||
__forceinline void transpose(const vfloat4& r0, const vfloat4& r1, const vfloat4& r2, const vfloat4& r3,
|
||||
const vfloat4& r4, const vfloat4& r5, const vfloat4& r6, const vfloat4& r7,
|
||||
const vfloat4& r8, const vfloat4& r9, const vfloat4& r10, const vfloat4& r11,
|
||||
const vfloat4& r12, const vfloat4& r13, const vfloat4& r14, const vfloat4& r15,
|
||||
vfloat16& c0, vfloat16& c1, vfloat16& c2, vfloat16& c3)
|
||||
{
|
||||
return transpose(vfloat16(r0, r4, r8, r12), vfloat16(r1, r5, r9, r13), vfloat16(r2, r6, r10, r14), vfloat16(r3, r7, r11, r15),
|
||||
c0, c1, c2, c3);
|
||||
}
|
||||
|
||||
__forceinline void transpose(const vfloat16& r0, const vfloat16& r1, const vfloat16& r2, const vfloat16& r3,
|
||||
const vfloat16& r4, const vfloat16& r5, const vfloat16& r6, const vfloat16& r7,
|
||||
vfloat16& c0, vfloat16& c1, vfloat16& c2, vfloat16& c3,
|
||||
vfloat16& c4, vfloat16& c5, vfloat16& c6, vfloat16& c7)
|
||||
{
|
||||
vfloat16 a0a1a2a3_e0e1e2e3, b0b1b2b3_f0f1f2f3, c0c1c2c3_g0g1g2g3, d0d1d2d3_h0h1h2h3;
|
||||
transpose(r0, r1, r2, r3, a0a1a2a3_e0e1e2e3, b0b1b2b3_f0f1f2f3, c0c1c2c3_g0g1g2g3, d0d1d2d3_h0h1h2h3);
|
||||
|
||||
vfloat16 a4a5a6a7_e4e5e6e7, b4b5b6b7_f4f5f6f7, c4c5c6c7_g4g5g6g7, d4d5d6d7_h4h5h6h7;
|
||||
transpose(r4, r5, r6, r7, a4a5a6a7_e4e5e6e7, b4b5b6b7_f4f5f6f7, c4c5c6c7_g4g5g6g7, d4d5d6d7_h4h5h6h7);
|
||||
|
||||
c0 = interleave4_even(a0a1a2a3_e0e1e2e3, a4a5a6a7_e4e5e6e7);
|
||||
c1 = interleave4_even(b0b1b2b3_f0f1f2f3, b4b5b6b7_f4f5f6f7);
|
||||
c2 = interleave4_even(c0c1c2c3_g0g1g2g3, c4c5c6c7_g4g5g6g7);
|
||||
c3 = interleave4_even(d0d1d2d3_h0h1h2h3, d4d5d6d7_h4h5h6h7);
|
||||
c4 = interleave4_odd (a0a1a2a3_e0e1e2e3, a4a5a6a7_e4e5e6e7);
|
||||
c5 = interleave4_odd (b0b1b2b3_f0f1f2f3, b4b5b6b7_f4f5f6f7);
|
||||
c6 = interleave4_odd (c0c1c2c3_g0g1g2g3, c4c5c6c7_g4g5g6g7);
|
||||
c7 = interleave4_odd (d0d1d2d3_h0h1h2h3, d4d5d6d7_h4h5h6h7);
|
||||
}
|
||||
|
||||
__forceinline void transpose(const vfloat8& r0, const vfloat8& r1, const vfloat8& r2, const vfloat8& r3,
|
||||
const vfloat8& r4, const vfloat8& r5, const vfloat8& r6, const vfloat8& r7,
|
||||
const vfloat8& r8, const vfloat8& r9, const vfloat8& r10, const vfloat8& r11,
|
||||
const vfloat8& r12, const vfloat8& r13, const vfloat8& r14, const vfloat8& r15,
|
||||
vfloat16& c0, vfloat16& c1, vfloat16& c2, vfloat16& c3,
|
||||
vfloat16& c4, vfloat16& c5, vfloat16& c6, vfloat16& c7)
|
||||
{
|
||||
return transpose(vfloat16(r0, r8), vfloat16(r1, r9), vfloat16(r2, r10), vfloat16(r3, r11),
|
||||
vfloat16(r4, r12), vfloat16(r5, r13), vfloat16(r6, r14), vfloat16(r7, r15),
|
||||
c0, c1, c2, c3, c4, c5, c6, c7);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Reductions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -491,15 +608,15 @@ namespace embree
|
||||
__forceinline vfloat16 vreduce_add8(vfloat16 x) { x = vreduce_add4(x); return x + shuffle4<1,0,3,2>(x); }
|
||||
__forceinline vfloat16 vreduce_add (vfloat16 x) { x = vreduce_add8(x); return x + shuffle4<2,3,0,1>(x); }
|
||||
|
||||
__forceinline vfloat16 vreduce_min2(vfloat16 x) { return min(x,shuffle<1,0,3,2>(x)); }
|
||||
__forceinline vfloat16 vreduce_min4(vfloat16 x) { x = vreduce_min2(x); return min(x,shuffle<2,3,0,1>(x)); }
|
||||
__forceinline vfloat16 vreduce_min8(vfloat16 x) { x = vreduce_min4(x); return min(x,shuffle4<1,0,3,2>(x)); }
|
||||
__forceinline vfloat16 vreduce_min (vfloat16 x) { x = vreduce_min8(x); return min(x,shuffle4<2,3,0,1>(x)); }
|
||||
__forceinline vfloat16 vreduce_min2(vfloat16 x) { return min(x, shuffle<1,0,3,2>(x)); }
|
||||
__forceinline vfloat16 vreduce_min4(vfloat16 x) { x = vreduce_min2(x); return min(x, shuffle<2,3,0,1>(x)); }
|
||||
__forceinline vfloat16 vreduce_min8(vfloat16 x) { x = vreduce_min4(x); return min(x, shuffle4<1,0,3,2>(x)); }
|
||||
__forceinline vfloat16 vreduce_min (vfloat16 x) { x = vreduce_min8(x); return min(x, shuffle4<2,3,0,1>(x)); }
|
||||
|
||||
__forceinline vfloat16 vreduce_max2(vfloat16 x) { return max(x,shuffle<1,0,3,2>(x)); }
|
||||
__forceinline vfloat16 vreduce_max4(vfloat16 x) { x = vreduce_max2(x); return max(x,shuffle<2,3,0,1>(x)); }
|
||||
__forceinline vfloat16 vreduce_max8(vfloat16 x) { x = vreduce_max4(x); return max(x,shuffle4<1,0,3,2>(x)); }
|
||||
__forceinline vfloat16 vreduce_max (vfloat16 x) { x = vreduce_max8(x); return max(x,shuffle4<2,3,0,1>(x)); }
|
||||
__forceinline vfloat16 vreduce_max2(vfloat16 x) { return max(x, shuffle<1,0,3,2>(x)); }
|
||||
__forceinline vfloat16 vreduce_max4(vfloat16 x) { x = vreduce_max2(x); return max(x, shuffle<2,3,0,1>(x)); }
|
||||
__forceinline vfloat16 vreduce_max8(vfloat16 x) { x = vreduce_max4(x); return max(x, shuffle4<1,0,3,2>(x)); }
|
||||
__forceinline vfloat16 vreduce_max (vfloat16 x) { x = vreduce_max8(x); return max(x, shuffle4<2,3,0,1>(x)); }
|
||||
|
||||
__forceinline float reduce_add(const vfloat16& v) { return toScalar(vreduce_add(v)); }
|
||||
__forceinline float reduce_min(const vfloat16& v) { return toScalar(vreduce_min(v)); }
|
||||
@@ -598,47 +715,32 @@ namespace embree
|
||||
/// Memory load and store operations
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline void compactustore16f_low(const vboolf16& mask, float * addr, const vfloat16 ®) {
|
||||
_mm512_mask_compressstoreu_ps(addr,mask,reg);
|
||||
}
|
||||
|
||||
template<int scale = 4>
|
||||
__forceinline vfloat16 gather16f(const vboolf16& mask, const float *const ptr, __m512i index) {
|
||||
vfloat16 r = vfloat16::undefined();
|
||||
return _mm512_mask_i32gather_ps(r,mask,index,ptr,scale);
|
||||
}
|
||||
|
||||
template<int scale = 4>
|
||||
__forceinline void scatter16f(const vboolf16& mask,const float *const ptr, const __m512i index,const vfloat16 v) {
|
||||
_mm512_mask_i32scatter_ps(ptr,mask,index,v,scale);
|
||||
}
|
||||
|
||||
__forceinline vfloat16 loadAOS4to16f(const float& x,const float& y, const float& z)
|
||||
__forceinline vfloat16 loadAOS4to16f(const float& x, const float& y, const float& z)
|
||||
{
|
||||
vfloat16 f = vfloat16::zero();
|
||||
vfloat16 f = zero;
|
||||
f = select(0x1111,vfloat16::broadcast(&x),f);
|
||||
f = select(0x2222,vfloat16::broadcast(&y),f);
|
||||
f = select(0x4444,vfloat16::broadcast(&z),f);
|
||||
return f;
|
||||
}
|
||||
|
||||
__forceinline vfloat16 loadAOS4to16f(const unsigned int index,
|
||||
const vfloat16 &x,
|
||||
const vfloat16 &y,
|
||||
const vfloat16 &z)
|
||||
__forceinline vfloat16 loadAOS4to16f(unsigned int index,
|
||||
const vfloat16& x,
|
||||
const vfloat16& y,
|
||||
const vfloat16& z)
|
||||
{
|
||||
vfloat16 f = vfloat16::zero();
|
||||
vfloat16 f = zero;
|
||||
f = select(0x1111,vfloat16::broadcast((float*)&x + index),f);
|
||||
f = select(0x2222,vfloat16::broadcast((float*)&y + index),f);
|
||||
f = select(0x4444,vfloat16::broadcast((float*)&z + index),f);
|
||||
return f;
|
||||
}
|
||||
|
||||
__forceinline vfloat16 loadAOS4to16f(const unsigned int index,
|
||||
const vfloat16 &x,
|
||||
const vfloat16 &y,
|
||||
const vfloat16 &z,
|
||||
const vfloat16 &fill)
|
||||
__forceinline vfloat16 loadAOS4to16f(unsigned int index,
|
||||
const vfloat16& x,
|
||||
const vfloat16& y,
|
||||
const vfloat16& z,
|
||||
const vfloat16& fill)
|
||||
{
|
||||
vfloat16 f = fill;
|
||||
f = select(0x1111,vfloat16::broadcast((float*)&x + index),f);
|
||||
@@ -647,15 +749,15 @@ namespace embree
|
||||
return f;
|
||||
}
|
||||
|
||||
__forceinline vfloat16 rcp_safe( const vfloat16& a ) {
|
||||
return rcp(select(a != vfloat16::zero(),a,vfloat16(min_rcp_input)));
|
||||
__forceinline vfloat16 rcp_safe(const vfloat16& a) {
|
||||
return rcp(select(a != vfloat16(zero), a, vfloat16(min_rcp_input)));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Output Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline std::ostream &operator<<(std::ostream& cout, const vfloat16& v)
|
||||
__forceinline std::ostream& operator <<(std::ostream& cout, const vfloat16& v)
|
||||
{
|
||||
cout << "<" << v[0];
|
||||
for (int i=1; i<16; i++) cout << ", " << v[i];
|
||||
|
||||
+233
-167
@@ -33,67 +33,76 @@ namespace embree
|
||||
/// Constructors, Assignment & Cast Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vfloat ( ) {}
|
||||
__forceinline vfloat ( const vfloat4& other ) { v = other.v; }
|
||||
__forceinline vfloat4& operator=( const vfloat4& other ) { v = other.v; return *this; }
|
||||
__forceinline vfloat() {}
|
||||
__forceinline vfloat(const vfloat4& other) { v = other.v; }
|
||||
__forceinline vfloat4& operator =(const vfloat4& other) { v = other.v; return *this; }
|
||||
|
||||
__forceinline vfloat( const __m128 a ) : v(a) {}
|
||||
__forceinline operator const __m128&( void ) const { return v; }
|
||||
__forceinline operator __m128&( void ) { return v; }
|
||||
__forceinline vfloat(__m128 a) : v(a) {}
|
||||
__forceinline operator const __m128&() const { return v; }
|
||||
__forceinline operator __m128&() { return v; }
|
||||
|
||||
__forceinline vfloat( float a ) : v(_mm_set1_ps(a)) {}
|
||||
__forceinline vfloat( float a, float b, float c, float d) : v(_mm_set_ps(d, c, b, a)) {}
|
||||
__forceinline vfloat(float a) : v(_mm_set1_ps(a)) {}
|
||||
__forceinline vfloat(float a, float b, float c, float d) : v(_mm_set_ps(d, c, b, a)) {}
|
||||
|
||||
__forceinline explicit vfloat( const __m128i a ) : v(_mm_cvtepi32_ps(a)) {}
|
||||
__forceinline explicit vfloat(__m128i a) : v(_mm_cvtepi32_ps(a)) {}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Constants
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vfloat( ZeroTy ) : v(_mm_setzero_ps()) {}
|
||||
__forceinline vfloat( OneTy ) : v(_mm_set1_ps(1.0f)) {}
|
||||
__forceinline vfloat( PosInfTy ) : v(_mm_set1_ps(pos_inf)) {}
|
||||
__forceinline vfloat( NegInfTy ) : v(_mm_set1_ps(neg_inf)) {}
|
||||
__forceinline vfloat( StepTy ) : v(_mm_set_ps(3.0f, 2.0f, 1.0f, 0.0f)) {}
|
||||
__forceinline vfloat( NaNTy ) : v(_mm_set1_ps(nan)) {}
|
||||
__forceinline vfloat(ZeroTy) : v(_mm_setzero_ps()) {}
|
||||
__forceinline vfloat(OneTy) : v(_mm_set1_ps(1.0f)) {}
|
||||
__forceinline vfloat(PosInfTy) : v(_mm_set1_ps(pos_inf)) {}
|
||||
__forceinline vfloat(NegInfTy) : v(_mm_set1_ps(neg_inf)) {}
|
||||
__forceinline vfloat(StepTy) : v(_mm_set_ps(3.0f, 2.0f, 1.0f, 0.0f)) {}
|
||||
__forceinline vfloat(NaNTy) : v(_mm_set1_ps(nan)) {}
|
||||
__forceinline vfloat(UndefinedTy) : v(_mm_undefined_ps()) {}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Loads and Stores
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static __forceinline vfloat4 load ( const void* const a ) { return _mm_load_ps((float*)a); }
|
||||
static __forceinline vfloat4 loadu( const void* const a ) { return _mm_loadu_ps((float*)a); }
|
||||
static __forceinline vfloat4 load (const void* a) { return _mm_load_ps((float*)a); }
|
||||
static __forceinline vfloat4 loadu(const void* a) { return _mm_loadu_ps((float*)a); }
|
||||
|
||||
static __forceinline void store ( void* ptr, const vfloat4& v ) { _mm_store_ps((float*)ptr,v); }
|
||||
static __forceinline void storeu( void* ptr, const vfloat4& v ) { _mm_storeu_ps((float*)ptr,v); }
|
||||
static __forceinline void store (void* ptr, const vfloat4& v) { _mm_store_ps((float*)ptr,v); }
|
||||
static __forceinline void storeu(void* ptr, const vfloat4& v) { _mm_storeu_ps((float*)ptr,v); }
|
||||
|
||||
#if defined(__AVX512VL__)
|
||||
static __forceinline vfloat4 load ( const vboolf4& mask, const void* const ptr) { return _mm_mask_load_ps (_mm_setzero_ps(),mask,(float*)ptr); }
|
||||
static __forceinline vfloat4 loadu( const vboolf4& mask, const void* const ptr) { return _mm_mask_loadu_ps(_mm_setzero_ps(),mask,(float*)ptr); }
|
||||
|
||||
static __forceinline void store ( const vboolf4& mask, void* ptr, const vfloat4& v) { _mm_mask_store_ps ((float*)ptr,mask,v); }
|
||||
static __forceinline void storeu( const vboolf4& mask, void* ptr, const vfloat4& v) { _mm_mask_storeu_ps((float*)ptr,mask,v); }
|
||||
static __forceinline vfloat4 compact(const vboolf4& mask, vfloat4 &v) {
|
||||
return _mm_mask_compress_ps(v, mask, v);
|
||||
}
|
||||
static __forceinline vfloat4 compact(const vboolf4& mask, vfloat4 &a, const vfloat4& b) {
|
||||
return _mm_mask_compress_ps(a, mask, b);
|
||||
}
|
||||
|
||||
static __forceinline vfloat4 load (const vboolf4& mask, const void* ptr) { return _mm_mask_load_ps (_mm_setzero_ps(),mask,(float*)ptr); }
|
||||
static __forceinline vfloat4 loadu(const vboolf4& mask, const void* ptr) { return _mm_mask_loadu_ps(_mm_setzero_ps(),mask,(float*)ptr); }
|
||||
|
||||
static __forceinline void store (const vboolf4& mask, void* ptr, const vfloat4& v) { _mm_mask_store_ps ((float*)ptr,mask,v); }
|
||||
static __forceinline void storeu(const vboolf4& mask, void* ptr, const vfloat4& v) { _mm_mask_storeu_ps((float*)ptr,mask,v); }
|
||||
#elif defined(__AVX__)
|
||||
static __forceinline vfloat4 load ( const vboolf4& mask, const void* const ptr ) { return _mm_maskload_ps((float*)ptr,mask); }
|
||||
static __forceinline vfloat4 loadu( const vboolf4& mask, const void* const ptr ) { return _mm_maskload_ps((float*)ptr,mask); }
|
||||
static __forceinline vfloat4 load (const vboolf4& mask, const void* ptr) { return _mm_maskload_ps((float*)ptr,mask); }
|
||||
static __forceinline vfloat4 loadu(const vboolf4& mask, const void* ptr) { return _mm_maskload_ps((float*)ptr,mask); }
|
||||
|
||||
static __forceinline void store ( const vboolf4& mask, void* ptr, const vfloat4& v ) { _mm_maskstore_ps((float*)ptr,(__m128i)mask,v); }
|
||||
static __forceinline void storeu( const vboolf4& mask, void* ptr, const vfloat4& v ) { _mm_maskstore_ps((float*)ptr,(__m128i)mask,v); }
|
||||
static __forceinline void store (const vboolf4& mask, void* ptr, const vfloat4& v) { _mm_maskstore_ps((float*)ptr,(__m128i)mask,v); }
|
||||
static __forceinline void storeu(const vboolf4& mask, void* ptr, const vfloat4& v) { _mm_maskstore_ps((float*)ptr,(__m128i)mask,v); }
|
||||
#else
|
||||
static __forceinline vfloat4 load ( const vboolf4& mask, const void* const ptr ) { return _mm_and_ps(_mm_load_ps ((float*)ptr),mask); }
|
||||
static __forceinline vfloat4 loadu( const vboolf4& mask, const void* const ptr ) { return _mm_and_ps(_mm_loadu_ps((float*)ptr),mask); }
|
||||
static __forceinline vfloat4 load (const vboolf4& mask, const void* ptr) { return _mm_and_ps(_mm_load_ps ((float*)ptr),mask); }
|
||||
static __forceinline vfloat4 loadu(const vboolf4& mask, const void* ptr) { return _mm_and_ps(_mm_loadu_ps((float*)ptr),mask); }
|
||||
|
||||
static __forceinline void store ( const vboolf4& mask, void* ptr, const vfloat4& v ) { store (ptr,select(mask,v,load (ptr))); }
|
||||
static __forceinline void storeu( const vboolf4& mask, void* ptr, const vfloat4& v ) { storeu(ptr,select(mask,v,loadu(ptr))); }
|
||||
static __forceinline void store (const vboolf4& mask, void* ptr, const vfloat4& v) { store (ptr,select(mask,v,load (ptr))); }
|
||||
static __forceinline void storeu(const vboolf4& mask, void* ptr, const vfloat4& v) { storeu(ptr,select(mask,v,loadu(ptr))); }
|
||||
#endif
|
||||
|
||||
#if defined(__AVX__)
|
||||
static __forceinline vfloat4 broadcast( const void* const a ) { return _mm_broadcast_ss((float*)a); }
|
||||
static __forceinline vfloat4 broadcast(const void* a) { return _mm_broadcast_ss((float*)a); }
|
||||
#else
|
||||
static __forceinline vfloat4 broadcast( const void* const a ) { return _mm_set1_ps(*(float*)a); }
|
||||
static __forceinline vfloat4 broadcast(const void* a) { return _mm_set1_ps(*(float*)a); }
|
||||
#endif
|
||||
|
||||
static __forceinline vfloat4 load_nt ( const float* ptr ) {
|
||||
static __forceinline vfloat4 load_nt (const float* ptr) {
|
||||
#if defined (__SSE4_1__)
|
||||
return _mm_castsi128_ps(_mm_stream_load_si128((__m128i*)ptr));
|
||||
#else
|
||||
@@ -102,21 +111,21 @@ namespace embree
|
||||
}
|
||||
|
||||
#if defined(__SSE4_1__)
|
||||
static __forceinline vfloat4 load( const unsigned char* const ptr ) {
|
||||
static __forceinline vfloat4 load(const unsigned char* ptr) {
|
||||
return _mm_cvtepi32_ps(_mm_cvtepu8_epi32(_mm_loadu_si128((__m128i*)ptr)));
|
||||
}
|
||||
#else
|
||||
static __forceinline vfloat4 load( const unsigned char* const ptr ) {
|
||||
static __forceinline vfloat4 load(const unsigned char* ptr) {
|
||||
//return _mm_cvtpu8_ps(*(__m64*)ptr); // don't enable, will use MMX instructions
|
||||
return vfloat4(ptr[0],ptr[1],ptr[2],ptr[3]);
|
||||
}
|
||||
#endif
|
||||
|
||||
static __forceinline vfloat4 load(const unsigned short* const ptr) {
|
||||
static __forceinline vfloat4 load(const unsigned short* ptr) {
|
||||
return _mm_mul_ps(vfloat4(vint4::load(ptr)),vfloat4(1.0f/65535.0f));
|
||||
}
|
||||
|
||||
static __forceinline void store_nt ( void* ptr, const vfloat4& v)
|
||||
static __forceinline void store_nt(void* ptr, const vfloat4& v)
|
||||
{
|
||||
#if defined (__SSE4_1__)
|
||||
_mm_stream_ps((float*)ptr,v);
|
||||
@@ -125,16 +134,58 @@ namespace embree
|
||||
#endif
|
||||
}
|
||||
|
||||
template<int scale>
|
||||
static __forceinline void scatter(const vboolf4& mask, void* ptr, const vint4& ofs, const vfloat4& v)
|
||||
template<int scale = 4>
|
||||
static __forceinline vfloat4 gather(const float* ptr, const vint4& index) {
|
||||
#if defined(__AVX2__)
|
||||
return _mm_i32gather_ps(ptr, index, scale);
|
||||
#else
|
||||
return vfloat4(
|
||||
*(float*)(((char*)ptr)+scale*index[0]),
|
||||
*(float*)(((char*)ptr)+scale*index[1]),
|
||||
*(float*)(((char*)ptr)+scale*index[2]),
|
||||
*(float*)(((char*)ptr)+scale*index[3]));
|
||||
#endif
|
||||
}
|
||||
|
||||
template<int scale = 4>
|
||||
static __forceinline vfloat4 gather(const vboolf4& mask, const float* ptr, const vint4& index) {
|
||||
vfloat4 r = zero;
|
||||
#if defined(__AVX512VL__)
|
||||
return _mm_mmask_i32gather_ps(r, mask, index, ptr, scale);
|
||||
#elif defined(__AVX2__)
|
||||
return _mm_mask_i32gather_ps(r, ptr, index, mask, scale);
|
||||
#else
|
||||
if (likely(mask[0])) r[0] = *(float*)(((char*)ptr)+scale*index[0]);
|
||||
if (likely(mask[1])) r[1] = *(float*)(((char*)ptr)+scale*index[1]);
|
||||
if (likely(mask[2])) r[2] = *(float*)(((char*)ptr)+scale*index[2]);
|
||||
if (likely(mask[3])) r[3] = *(float*)(((char*)ptr)+scale*index[3]);
|
||||
return r;
|
||||
#endif
|
||||
}
|
||||
|
||||
template<int scale = 4>
|
||||
static __forceinline void scatter(void* ptr, const vint4& index, const vfloat4& v)
|
||||
{
|
||||
#if defined(__AVX512VL__)
|
||||
_mm_mask_i32scatter_ps((float*)ptr,mask,ofs,v,scale);
|
||||
_mm_i32scatter_ps((float*)ptr,index,v,scale);
|
||||
#else
|
||||
if (likely(mask[0])) *(float*)(((char*)ptr)+scale*ofs[0]) = v[0];
|
||||
if (likely(mask[1])) *(float*)(((char*)ptr)+scale*ofs[1]) = v[1];
|
||||
if (likely(mask[2])) *(float*)(((char*)ptr)+scale*ofs[2]) = v[2];
|
||||
if (likely(mask[3])) *(float*)(((char*)ptr)+scale*ofs[3]) = v[3];
|
||||
*(float*)(((char*)ptr)+scale*index[0]) = v[0];
|
||||
*(float*)(((char*)ptr)+scale*index[1]) = v[1];
|
||||
*(float*)(((char*)ptr)+scale*index[2]) = v[2];
|
||||
*(float*)(((char*)ptr)+scale*index[3]) = v[3];
|
||||
#endif
|
||||
}
|
||||
|
||||
template<int scale = 4>
|
||||
static __forceinline void scatter(const vboolf4& mask, void* ptr, const vint4& index, const vfloat4& v)
|
||||
{
|
||||
#if defined(__AVX512VL__)
|
||||
_mm_mask_i32scatter_ps((float*)ptr,mask,index,v,scale);
|
||||
#else
|
||||
if (likely(mask[0])) *(float*)(((char*)ptr)+scale*index[0]) = v[0];
|
||||
if (likely(mask[1])) *(float*)(((char*)ptr)+scale*index[1]) = v[1];
|
||||
if (likely(mask[2])) *(float*)(((char*)ptr)+scale*index[2]) = v[2];
|
||||
if (likely(mask[3])) *(float*)(((char*)ptr)+scale*index[3]) = v[3];
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -149,10 +200,10 @@ namespace embree
|
||||
/// Array Access
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const float& operator []( const size_t index ) const { assert(index < 4); return f[index]; }
|
||||
__forceinline float& operator []( const size_t index ) { assert(index < 4); return f[index]; }
|
||||
__forceinline const float& operator [](size_t index) const { assert(index < 4); return f[index]; }
|
||||
__forceinline float& operator [](size_t index) { assert(index < 4); return f[index]; }
|
||||
|
||||
friend __forceinline const vfloat4 select( const vboolf4& m, const vfloat4& t, const vfloat4& f ) {
|
||||
friend __forceinline vfloat4 select(const vboolf4& m, const vfloat4& t, const vfloat4& f) {
|
||||
#if defined(__AVX512VL__)
|
||||
return _mm_mask_blend_ps(m, f, t);
|
||||
#elif defined(__SSE4_1__)
|
||||
@@ -168,23 +219,25 @@ namespace embree
|
||||
/// Unary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vfloat4 asFloat ( const __m128i& a ) { return _mm_castsi128_ps(a); }
|
||||
__forceinline const vfloat4 operator +( const vfloat4& a ) { return a; }
|
||||
__forceinline const vfloat4 operator -( const vfloat4& a ) { return _mm_xor_ps(a.v, _mm_castsi128_ps(_mm_set1_epi32(0x80000000))); }
|
||||
__forceinline const vfloat4 abs ( const vfloat4& a ) { return _mm_and_ps(a.v, _mm_castsi128_ps(_mm_set1_epi32(0x7fffffff))); }
|
||||
__forceinline vfloat4 asFloat(const __m128i& a) { return _mm_castsi128_ps(a); }
|
||||
|
||||
__forceinline vfloat4 operator +(const vfloat4& a) { return a; }
|
||||
__forceinline vfloat4 operator -(const vfloat4& a) { return _mm_xor_ps(a, _mm_castsi128_ps(_mm_set1_epi32(0x80000000))); }
|
||||
|
||||
__forceinline vfloat4 abs(const vfloat4& a) { return _mm_and_ps(a, _mm_castsi128_ps(_mm_set1_epi32(0x7fffffff))); }
|
||||
#if defined(__AVX512VL__)
|
||||
__forceinline const vfloat4 sign ( const vfloat4& a ) { return _mm_mask_blend_ps(_mm_cmp_ps_mask(a, vfloat4(zero), _CMP_LT_OQ), vfloat4(one), -vfloat4(one)); }
|
||||
__forceinline vfloat4 sign(const vfloat4& a) { return _mm_mask_blend_ps(_mm_cmp_ps_mask(a, vfloat4(zero), _CMP_LT_OQ), vfloat4(one), -vfloat4(one)); }
|
||||
#else
|
||||
__forceinline const vfloat4 sign ( const vfloat4& a ) { return blendv_ps(vfloat4(one), -vfloat4(one), _mm_cmplt_ps(a, vfloat4(zero))); }
|
||||
__forceinline vfloat4 sign(const vfloat4& a) { return blendv_ps(vfloat4(one), -vfloat4(one), _mm_cmplt_ps(a, vfloat4(zero))); }
|
||||
#endif
|
||||
__forceinline const vfloat4 signmsk ( const vfloat4& a ) { return _mm_and_ps(a.v,_mm_castsi128_ps(_mm_set1_epi32(0x80000000))); }
|
||||
__forceinline vfloat4 signmsk(const vfloat4& a) { return _mm_and_ps(a,_mm_castsi128_ps(_mm_set1_epi32(0x80000000))); }
|
||||
|
||||
__forceinline const vfloat4 rcp ( const vfloat4& a )
|
||||
__forceinline vfloat4 rcp(const vfloat4& a)
|
||||
{
|
||||
#if defined(__AVX512VL__)
|
||||
const vfloat4 r = _mm_rcp14_ps(a.v);
|
||||
const vfloat4 r = _mm_rcp14_ps(a);
|
||||
#else
|
||||
const vfloat4 r = _mm_rcp_ps(a.v);
|
||||
const vfloat4 r = _mm_rcp_ps(a);
|
||||
#endif
|
||||
|
||||
#if defined(__AVX2__)
|
||||
@@ -193,15 +246,15 @@ namespace embree
|
||||
return _mm_mul_ps(r,_mm_sub_ps(vfloat4(2.0f), _mm_mul_ps(r, a)));
|
||||
#endif
|
||||
}
|
||||
__forceinline const vfloat4 sqr ( const vfloat4& a ) { return _mm_mul_ps(a,a); }
|
||||
__forceinline const vfloat4 sqrt ( const vfloat4& a ) { return _mm_sqrt_ps(a.v); }
|
||||
__forceinline vfloat4 sqr (const vfloat4& a) { return _mm_mul_ps(a,a); }
|
||||
__forceinline vfloat4 sqrt(const vfloat4& a) { return _mm_sqrt_ps(a); }
|
||||
|
||||
__forceinline const vfloat4 rsqrt( const vfloat4& a )
|
||||
__forceinline vfloat4 rsqrt(const vfloat4& a)
|
||||
{
|
||||
#if defined(__AVX512VL__)
|
||||
const vfloat4 r = _mm_rsqrt14_ps(a.v);
|
||||
const vfloat4 r = _mm_rsqrt14_ps(a);
|
||||
#else
|
||||
const vfloat4 r = _mm_rsqrt_ps(a.v);
|
||||
const vfloat4 r = _mm_rsqrt_ps(a);
|
||||
#endif
|
||||
|
||||
#if defined(__AVX2__)
|
||||
@@ -213,8 +266,8 @@ namespace embree
|
||||
#endif
|
||||
}
|
||||
|
||||
__forceinline const vboolf4 isnan( const vfloat4& a ) {
|
||||
const vfloat4 b = _mm_and_ps(a.v, _mm_castsi128_ps(_mm_set1_epi32(0x7fffffff)));
|
||||
__forceinline vboolf4 isnan(const vfloat4& a) {
|
||||
const vfloat4 b = _mm_and_ps(a, _mm_castsi128_ps(_mm_set1_epi32(0x7fffffff)));
|
||||
#if defined(__AVX512VL__)
|
||||
return _mm_cmp_epi32_mask(_mm_castps_si128(b), _mm_set1_epi32(0x7f800000), _MM_CMPINT_GT);
|
||||
#else
|
||||
@@ -226,32 +279,32 @@ namespace embree
|
||||
/// Binary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vfloat4 operator +( const vfloat4& a, const vfloat4& b ) { return _mm_add_ps(a.v, b.v); }
|
||||
__forceinline const vfloat4 operator +( const vfloat4& a, const float& b ) { return a + vfloat4(b); }
|
||||
__forceinline const vfloat4 operator +( const float& a, const vfloat4& b ) { return vfloat4(a) + b; }
|
||||
__forceinline vfloat4 operator +(const vfloat4& a, const vfloat4& b) { return _mm_add_ps(a, b); }
|
||||
__forceinline vfloat4 operator +(const vfloat4& a, float b) { return a + vfloat4(b); }
|
||||
__forceinline vfloat4 operator +(float a, const vfloat4& b) { return vfloat4(a) + b; }
|
||||
|
||||
__forceinline const vfloat4 operator -( const vfloat4& a, const vfloat4& b ) { return _mm_sub_ps(a.v, b.v); }
|
||||
__forceinline const vfloat4 operator -( const vfloat4& a, const float& b ) { return a - vfloat4(b); }
|
||||
__forceinline const vfloat4 operator -( const float& a, const vfloat4& b ) { return vfloat4(a) - b; }
|
||||
__forceinline vfloat4 operator -(const vfloat4& a, const vfloat4& b) { return _mm_sub_ps(a, b); }
|
||||
__forceinline vfloat4 operator -(const vfloat4& a, float b) { return a - vfloat4(b); }
|
||||
__forceinline vfloat4 operator -(float a, const vfloat4& b) { return vfloat4(a) - b; }
|
||||
|
||||
__forceinline const vfloat4 operator *( const vfloat4& a, const vfloat4& b ) { return _mm_mul_ps(a.v, b.v); }
|
||||
__forceinline const vfloat4 operator *( const vfloat4& a, const float& b ) { return a * vfloat4(b); }
|
||||
__forceinline const vfloat4 operator *( const float& a, const vfloat4& b ) { return vfloat4(a) * b; }
|
||||
__forceinline vfloat4 operator *(const vfloat4& a, const vfloat4& b) { return _mm_mul_ps(a, b); }
|
||||
__forceinline vfloat4 operator *(const vfloat4& a, float b) { return a * vfloat4(b); }
|
||||
__forceinline vfloat4 operator *(float a, const vfloat4& b) { return vfloat4(a) * b; }
|
||||
|
||||
__forceinline const vfloat4 operator /( const vfloat4& a, const vfloat4& b ) { return _mm_div_ps(a.v,b.v); }
|
||||
__forceinline const vfloat4 operator /( const vfloat4& a, const float& b ) { return a/vfloat4(b); }
|
||||
__forceinline const vfloat4 operator /( const float& a, const vfloat4& b ) { return vfloat4(a)/b; }
|
||||
__forceinline vfloat4 operator /(const vfloat4& a, const vfloat4& b) { return _mm_div_ps(a,b); }
|
||||
__forceinline vfloat4 operator /(const vfloat4& a, float b) { return a/vfloat4(b); }
|
||||
__forceinline vfloat4 operator /(float a, const vfloat4& b) { return vfloat4(a)/b; }
|
||||
|
||||
__forceinline const vfloat4 operator^( const vfloat4& a, const vfloat4& b ) { return _mm_xor_ps(a.v,b.v); }
|
||||
__forceinline const vfloat4 operator^( const vfloat4& a, const vint4& b ) { return _mm_xor_ps(a.v,_mm_castsi128_ps(b.v)); }
|
||||
__forceinline vfloat4 operator ^(const vfloat4& a, const vfloat4& b) { return _mm_xor_ps(a,b); }
|
||||
__forceinline vfloat4 operator ^(const vfloat4& a, const vint4& b) { return _mm_xor_ps(a,_mm_castsi128_ps(b)); }
|
||||
|
||||
__forceinline const vfloat4 min( const vfloat4& a, const vfloat4& b ) { return _mm_min_ps(a.v,b.v); }
|
||||
__forceinline const vfloat4 min( const vfloat4& a, const float& b ) { return _mm_min_ps(a.v,vfloat4(b)); }
|
||||
__forceinline const vfloat4 min( const float& a, const vfloat4& b ) { return _mm_min_ps(vfloat4(a),b.v); }
|
||||
__forceinline vfloat4 min(const vfloat4& a, const vfloat4& b) { return _mm_min_ps(a,b); }
|
||||
__forceinline vfloat4 min(const vfloat4& a, float b) { return _mm_min_ps(a,vfloat4(b)); }
|
||||
__forceinline vfloat4 min(float a, const vfloat4& b) { return _mm_min_ps(vfloat4(a),b); }
|
||||
|
||||
__forceinline const vfloat4 max( const vfloat4& a, const vfloat4& b ) { return _mm_max_ps(a.v,b.v); }
|
||||
__forceinline const vfloat4 max( const vfloat4& a, const float& b ) { return _mm_max_ps(a.v,vfloat4(b)); }
|
||||
__forceinline const vfloat4 max( const float& a, const vfloat4& b ) { return _mm_max_ps(vfloat4(a),b.v); }
|
||||
__forceinline vfloat4 max(const vfloat4& a, const vfloat4& b) { return _mm_max_ps(a,b); }
|
||||
__forceinline vfloat4 max(const vfloat4& a, float b) { return _mm_max_ps(a,vfloat4(b)); }
|
||||
__forceinline vfloat4 max(float a, const vfloat4& b) { return _mm_max_ps(vfloat4(a),b); }
|
||||
|
||||
#if defined(__SSE4_1__)
|
||||
__forceinline vfloat4 mini(const vfloat4& a, const vfloat4& b) {
|
||||
@@ -260,6 +313,7 @@ namespace embree
|
||||
const vint4 ci = _mm_min_epi32(ai,bi);
|
||||
return _mm_castsi128_ps(ci);
|
||||
}
|
||||
|
||||
__forceinline vfloat4 maxi(const vfloat4& a, const vfloat4& b) {
|
||||
const vint4 ai = _mm_castps_si128(a);
|
||||
const vint4 bi = _mm_castps_si128(b);
|
||||
@@ -273,17 +327,18 @@ namespace embree
|
||||
const vint4 ci = _mm_min_epu32(ai,bi);
|
||||
return _mm_castsi128_ps(ci);
|
||||
}
|
||||
|
||||
__forceinline vfloat4 maxui(const vfloat4& a, const vfloat4& b) {
|
||||
const vint4 ai = _mm_castps_si128(a);
|
||||
const vint4 bi = _mm_castps_si128(b);
|
||||
const vint4 ci = _mm_max_epu32(ai,bi);
|
||||
return _mm_castsi128_ps(ci);
|
||||
}
|
||||
|
||||
#else
|
||||
__forceinline vfloat4 mini(const vfloat4& a, const vfloat4& b) {
|
||||
return min(a,b);
|
||||
}
|
||||
|
||||
__forceinline vfloat4 maxi(const vfloat4& a, const vfloat4& b) {
|
||||
return max(a,b);
|
||||
}
|
||||
@@ -294,70 +349,70 @@ namespace embree
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined(__AVX2__)
|
||||
__forceinline const vfloat4 madd ( const vfloat4& a, const vfloat4& b, const vfloat4& c) { return _mm_fmadd_ps(a,b,c); }
|
||||
__forceinline const vfloat4 msub ( const vfloat4& a, const vfloat4& b, const vfloat4& c) { return _mm_fmsub_ps(a,b,c); }
|
||||
__forceinline const vfloat4 nmadd ( const vfloat4& a, const vfloat4& b, const vfloat4& c) { return _mm_fnmadd_ps(a,b,c); }
|
||||
__forceinline const vfloat4 nmsub ( const vfloat4& a, const vfloat4& b, const vfloat4& c) { return _mm_fnmsub_ps(a,b,c); }
|
||||
__forceinline vfloat4 madd (const vfloat4& a, const vfloat4& b, const vfloat4& c) { return _mm_fmadd_ps(a,b,c); }
|
||||
__forceinline vfloat4 msub (const vfloat4& a, const vfloat4& b, const vfloat4& c) { return _mm_fmsub_ps(a,b,c); }
|
||||
__forceinline vfloat4 nmadd(const vfloat4& a, const vfloat4& b, const vfloat4& c) { return _mm_fnmadd_ps(a,b,c); }
|
||||
__forceinline vfloat4 nmsub(const vfloat4& a, const vfloat4& b, const vfloat4& c) { return _mm_fnmsub_ps(a,b,c); }
|
||||
#else
|
||||
__forceinline const vfloat4 madd ( const vfloat4& a, const vfloat4& b, const vfloat4& c) { return a*b+c; }
|
||||
__forceinline const vfloat4 msub ( const vfloat4& a, const vfloat4& b, const vfloat4& c) { return a*b-c; }
|
||||
__forceinline const vfloat4 nmadd ( const vfloat4& a, const vfloat4& b, const vfloat4& c) { return -a*b+c;}
|
||||
__forceinline const vfloat4 nmsub ( const vfloat4& a, const vfloat4& b, const vfloat4& c) { return -a*b-c; }
|
||||
__forceinline vfloat4 madd (const vfloat4& a, const vfloat4& b, const vfloat4& c) { return a*b+c; }
|
||||
__forceinline vfloat4 msub (const vfloat4& a, const vfloat4& b, const vfloat4& c) { return a*b-c; }
|
||||
__forceinline vfloat4 nmadd(const vfloat4& a, const vfloat4& b, const vfloat4& c) { return -a*b+c;}
|
||||
__forceinline vfloat4 nmsub(const vfloat4& a, const vfloat4& b, const vfloat4& c) { return -a*b-c; }
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Assignment Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vfloat4& operator +=( vfloat4& a, const vfloat4& b ) { return a = a + b; }
|
||||
__forceinline vfloat4& operator +=( vfloat4& a, const float& b ) { return a = a + b; }
|
||||
__forceinline vfloat4& operator +=(vfloat4& a, const vfloat4& b) { return a = a + b; }
|
||||
__forceinline vfloat4& operator +=(vfloat4& a, float b) { return a = a + b; }
|
||||
|
||||
__forceinline vfloat4& operator -=( vfloat4& a, const vfloat4& b ) { return a = a - b; }
|
||||
__forceinline vfloat4& operator -=( vfloat4& a, const float& b ) { return a = a - b; }
|
||||
__forceinline vfloat4& operator -=(vfloat4& a, const vfloat4& b) { return a = a - b; }
|
||||
__forceinline vfloat4& operator -=(vfloat4& a, float b) { return a = a - b; }
|
||||
|
||||
__forceinline vfloat4& operator *=( vfloat4& a, const vfloat4& b ) { return a = a * b; }
|
||||
__forceinline vfloat4& operator *=( vfloat4& a, const float& b ) { return a = a * b; }
|
||||
__forceinline vfloat4& operator *=(vfloat4& a, const vfloat4& b) { return a = a * b; }
|
||||
__forceinline vfloat4& operator *=(vfloat4& a, float b) { return a = a * b; }
|
||||
|
||||
__forceinline vfloat4& operator /=( vfloat4& a, const vfloat4& b ) { return a = a / b; }
|
||||
__forceinline vfloat4& operator /=( vfloat4& a, const float& b ) { return a = a / b; }
|
||||
__forceinline vfloat4& operator /=(vfloat4& a, const vfloat4& b) { return a = a / b; }
|
||||
__forceinline vfloat4& operator /=(vfloat4& a, float b) { return a = a / b; }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Comparison Operators + Select
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined(__AVX512VL__)
|
||||
__forceinline const vboolf4 operator ==( const vfloat4& a, const vfloat4& b ) { return _mm_cmp_ps_mask(a, b, _MM_CMPINT_EQ); }
|
||||
__forceinline const vboolf4 operator !=( const vfloat4& a, const vfloat4& b ) { return _mm_cmp_ps_mask(a, b, _MM_CMPINT_NE); }
|
||||
__forceinline const vboolf4 operator < ( const vfloat4& a, const vfloat4& b ) { return _mm_cmp_ps_mask(a, b, _MM_CMPINT_LT); }
|
||||
__forceinline const vboolf4 operator >=( const vfloat4& a, const vfloat4& b ) { return _mm_cmp_ps_mask(a, b, _MM_CMPINT_GE); }
|
||||
__forceinline const vboolf4 operator > ( const vfloat4& a, const vfloat4& b ) { return _mm_cmp_ps_mask(a, b, _MM_CMPINT_GT); }
|
||||
__forceinline const vboolf4 operator <=( const vfloat4& a, const vfloat4& b ) { return _mm_cmp_ps_mask(a, b, _MM_CMPINT_LE); }
|
||||
__forceinline vboolf4 operator ==(const vfloat4& a, const vfloat4& b) { return _mm_cmp_ps_mask(a, b, _MM_CMPINT_EQ); }
|
||||
__forceinline vboolf4 operator !=(const vfloat4& a, const vfloat4& b) { return _mm_cmp_ps_mask(a, b, _MM_CMPINT_NE); }
|
||||
__forceinline vboolf4 operator < (const vfloat4& a, const vfloat4& b) { return _mm_cmp_ps_mask(a, b, _MM_CMPINT_LT); }
|
||||
__forceinline vboolf4 operator >=(const vfloat4& a, const vfloat4& b) { return _mm_cmp_ps_mask(a, b, _MM_CMPINT_GE); }
|
||||
__forceinline vboolf4 operator > (const vfloat4& a, const vfloat4& b) { return _mm_cmp_ps_mask(a, b, _MM_CMPINT_GT); }
|
||||
__forceinline vboolf4 operator <=(const vfloat4& a, const vfloat4& b) { return _mm_cmp_ps_mask(a, b, _MM_CMPINT_LE); }
|
||||
#else
|
||||
__forceinline const vboolf4 operator ==( const vfloat4& a, const vfloat4& b ) { return _mm_cmpeq_ps (a, b); }
|
||||
__forceinline const vboolf4 operator !=( const vfloat4& a, const vfloat4& b ) { return _mm_cmpneq_ps(a, b); }
|
||||
__forceinline const vboolf4 operator < ( const vfloat4& a, const vfloat4& b ) { return _mm_cmplt_ps (a, b); }
|
||||
__forceinline const vboolf4 operator >=( const vfloat4& a, const vfloat4& b ) { return _mm_cmpnlt_ps(a, b); }
|
||||
__forceinline const vboolf4 operator > ( const vfloat4& a, const vfloat4& b ) { return _mm_cmpnle_ps(a, b); }
|
||||
__forceinline const vboolf4 operator <=( const vfloat4& a, const vfloat4& b ) { return _mm_cmple_ps (a, b); }
|
||||
__forceinline vboolf4 operator ==(const vfloat4& a, const vfloat4& b) { return _mm_cmpeq_ps (a, b); }
|
||||
__forceinline vboolf4 operator !=(const vfloat4& a, const vfloat4& b) { return _mm_cmpneq_ps(a, b); }
|
||||
__forceinline vboolf4 operator < (const vfloat4& a, const vfloat4& b) { return _mm_cmplt_ps (a, b); }
|
||||
__forceinline vboolf4 operator >=(const vfloat4& a, const vfloat4& b) { return _mm_cmpnlt_ps(a, b); }
|
||||
__forceinline vboolf4 operator > (const vfloat4& a, const vfloat4& b) { return _mm_cmpnle_ps(a, b); }
|
||||
__forceinline vboolf4 operator <=(const vfloat4& a, const vfloat4& b) { return _mm_cmple_ps (a, b); }
|
||||
#endif
|
||||
|
||||
__forceinline const vboolf4 operator ==( const vfloat4& a, const float& b ) { return a == vfloat4(b); }
|
||||
__forceinline const vboolf4 operator ==( const float& a, const vfloat4& b ) { return vfloat4(a) == b; }
|
||||
__forceinline vboolf4 operator ==(const vfloat4& a, float b) { return a == vfloat4(b); }
|
||||
__forceinline vboolf4 operator ==(float a, const vfloat4& b) { return vfloat4(a) == b; }
|
||||
|
||||
__forceinline const vboolf4 operator !=( const vfloat4& a, const float& b ) { return a != vfloat4(b); }
|
||||
__forceinline const vboolf4 operator !=( const float& a, const vfloat4& b ) { return vfloat4(a) != b; }
|
||||
__forceinline vboolf4 operator !=(const vfloat4& a, float b) { return a != vfloat4(b); }
|
||||
__forceinline vboolf4 operator !=(float a, const vfloat4& b) { return vfloat4(a) != b; }
|
||||
|
||||
__forceinline const vboolf4 operator < ( const vfloat4& a, const float& b ) { return a < vfloat4(b); }
|
||||
__forceinline const vboolf4 operator < ( const float& a, const vfloat4& b ) { return vfloat4(a) < b; }
|
||||
__forceinline vboolf4 operator < (const vfloat4& a, float b) { return a < vfloat4(b); }
|
||||
__forceinline vboolf4 operator < (float a, const vfloat4& b) { return vfloat4(a) < b; }
|
||||
|
||||
__forceinline const vboolf4 operator >=( const vfloat4& a, const float& b ) { return a >= vfloat4(b); }
|
||||
__forceinline const vboolf4 operator >=( const float& a, const vfloat4& b ) { return vfloat4(a) >= b; }
|
||||
__forceinline vboolf4 operator >=(const vfloat4& a, float b) { return a >= vfloat4(b); }
|
||||
__forceinline vboolf4 operator >=(float a, const vfloat4& b) { return vfloat4(a) >= b; }
|
||||
|
||||
__forceinline const vboolf4 operator > ( const vfloat4& a, const float& b ) { return a > vfloat4(b); }
|
||||
__forceinline const vboolf4 operator > ( const float& a, const vfloat4& b ) { return vfloat4(a) > b; }
|
||||
__forceinline vboolf4 operator > (const vfloat4& a, float b) { return a > vfloat4(b); }
|
||||
__forceinline vboolf4 operator > (float a, const vfloat4& b) { return vfloat4(a) > b; }
|
||||
|
||||
__forceinline const vboolf4 operator <=( const vfloat4& a, const float& b ) { return a <= vfloat4(b); }
|
||||
__forceinline const vboolf4 operator <=( const float& a, const vfloat4& b ) { return vfloat4(a) <= b; }
|
||||
__forceinline vboolf4 operator <=(const vfloat4& a, float b) { return a <= vfloat4(b); }
|
||||
__forceinline vboolf4 operator <=(float a, const vfloat4& b) { return vfloat4(a) <= b; }
|
||||
|
||||
__forceinline vboolf4 eq(const vfloat4& a, const vfloat4& b) { return a == b; }
|
||||
__forceinline vboolf4 ne(const vfloat4& a, const vfloat4& b) { return a != b; }
|
||||
@@ -383,7 +438,7 @@ namespace embree
|
||||
#endif
|
||||
|
||||
template<int mask>
|
||||
__forceinline const vfloat4 select(const vfloat4& t, const vfloat4& f)
|
||||
__forceinline vfloat4 select(const vfloat4& t, const vfloat4& f)
|
||||
{
|
||||
#if defined(__SSE4_1__)
|
||||
return _mm_blend_ps(f, t, mask);
|
||||
@@ -396,15 +451,15 @@ namespace embree
|
||||
return madd(t,b-a,a);
|
||||
}
|
||||
|
||||
__forceinline bool isvalid ( const vfloat4& v ) {
|
||||
__forceinline bool isvalid(const vfloat4& v) {
|
||||
return all((v > vfloat4(-FLT_LARGE)) & (v < vfloat4(+FLT_LARGE)));
|
||||
}
|
||||
|
||||
__forceinline bool is_finite ( const vfloat4& a ) {
|
||||
__forceinline bool is_finite(const vfloat4& a) {
|
||||
return all((a >= vfloat4(-FLT_MAX)) & (a <= vfloat4(+FLT_MAX)));
|
||||
}
|
||||
|
||||
__forceinline bool is_finite ( const vboolf4& valid, const vfloat4& a ) {
|
||||
__forceinline bool is_finite(const vboolf4& valid, const vfloat4& a) {
|
||||
return all(valid, (a >= vfloat4(-FLT_MAX)) & (a <= vfloat4(+FLT_MAX)));
|
||||
}
|
||||
|
||||
@@ -413,17 +468,17 @@ namespace embree
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined (__SSE4_1__)
|
||||
__forceinline const vfloat4 floor ( const vfloat4& a ) { return _mm_round_ps(a, _MM_FROUND_TO_NEG_INF ); }
|
||||
__forceinline const vfloat4 ceil ( const vfloat4& a ) { return _mm_round_ps(a, _MM_FROUND_TO_POS_INF ); }
|
||||
__forceinline const vfloat4 trunc ( const vfloat4& a ) { return _mm_round_ps(a, _MM_FROUND_TO_ZERO ); }
|
||||
__forceinline vfloat4 floor(const vfloat4& a) { return _mm_round_ps(a, _MM_FROUND_TO_NEG_INF ); }
|
||||
__forceinline vfloat4 ceil (const vfloat4& a) { return _mm_round_ps(a, _MM_FROUND_TO_POS_INF ); }
|
||||
__forceinline vfloat4 trunc(const vfloat4& a) { return _mm_round_ps(a, _MM_FROUND_TO_ZERO ); }
|
||||
#else
|
||||
__forceinline const vfloat4 floor ( const vfloat4& a ) { return vfloat4(floorf(a[0]),floorf(a[1]),floorf(a[2]),floorf(a[3])); }
|
||||
__forceinline const vfloat4 ceil ( const vfloat4& a ) { return vfloat4(ceilf (a[0]),ceilf (a[1]),ceilf (a[2]),ceilf (a[3])); }
|
||||
//__forceinline const vfloat4 trunc ( const vfloat4& a ) { return vfloat4(truncf(a[0]),truncf(a[1]),truncf(a[2]),truncf(a[3])); }
|
||||
__forceinline vfloat4 floor(const vfloat4& a) { return vfloat4(floorf(a[0]),floorf(a[1]),floorf(a[2]),floorf(a[3])); }
|
||||
__forceinline vfloat4 ceil (const vfloat4& a) { return vfloat4(ceilf (a[0]),ceilf (a[1]),ceilf (a[2]),ceilf (a[3])); }
|
||||
//__forceinline vfloat4 trunc(const vfloat4& a) { return vfloat4(truncf(a[0]),truncf(a[1]),truncf(a[2]),truncf(a[3])); }
|
||||
#endif
|
||||
__forceinline const vfloat4 frac ( const vfloat4& a ) { return a-floor(a); }
|
||||
__forceinline vfloat4 frac(const vfloat4& a) { return a-floor(a); }
|
||||
|
||||
__forceinline vint4 floori (const vfloat4& a) {
|
||||
__forceinline vint4 floori(const vfloat4& a) {
|
||||
#if defined(__SSE4_1__)
|
||||
return vint4(floor(a));
|
||||
#else
|
||||
@@ -435,56 +490,59 @@ namespace embree
|
||||
/// Movement/Shifting/Shuffling Functions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vfloat4 unpacklo( const vfloat4& a, const vfloat4& b ) { return _mm_unpacklo_ps(a.v, b.v); }
|
||||
__forceinline vfloat4 unpackhi( const vfloat4& a, const vfloat4& b ) { return _mm_unpackhi_ps(a.v, b.v); }
|
||||
__forceinline vfloat4 unpacklo(const vfloat4& a, const vfloat4& b) { return _mm_unpacklo_ps(a, b); }
|
||||
__forceinline vfloat4 unpackhi(const vfloat4& a, const vfloat4& b) { return _mm_unpackhi_ps(a, b); }
|
||||
|
||||
template<size_t i0, size_t i1, size_t i2, size_t i3> __forceinline const vfloat4 shuffle( const vfloat4& b ) {
|
||||
return _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(b), _MM_SHUFFLE(i3, i2, i1, i0)));
|
||||
template<int i0, int i1, int i2, int i3>
|
||||
__forceinline vfloat4 shuffle(const vfloat4& v) {
|
||||
return _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(v), _MM_SHUFFLE(i3, i2, i1, i0)));
|
||||
}
|
||||
|
||||
template<size_t i0, size_t i1, size_t i2, size_t i3> __forceinline const vfloat4 shuffle( const vfloat4& a, const vfloat4& b ) {
|
||||
template<int i0, int i1, int i2, int i3>
|
||||
__forceinline vfloat4 shuffle(const vfloat4& a, const vfloat4& b) {
|
||||
return _mm_shuffle_ps(a, b, _MM_SHUFFLE(i3, i2, i1, i0));
|
||||
}
|
||||
|
||||
#if defined (__SSSE3__)
|
||||
__forceinline const vfloat4 shuffle8(const vfloat4& a, const vint4& shuf) {
|
||||
__forceinline vfloat4 shuffle8(const vfloat4& a, const vint4& shuf) {
|
||||
return _mm_castsi128_ps(_mm_shuffle_epi8(_mm_castps_si128(a), shuf));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__SSE3__)
|
||||
template<> __forceinline const vfloat4 shuffle<0, 0, 2, 2>( const vfloat4& b ) { return _mm_moveldup_ps(b); }
|
||||
template<> __forceinline const vfloat4 shuffle<1, 1, 3, 3>( const vfloat4& b ) { return _mm_movehdup_ps(b); }
|
||||
template<> __forceinline const vfloat4 shuffle<0, 1, 0, 1>( const vfloat4& b ) { return _mm_castpd_ps(_mm_movedup_pd(_mm_castps_pd(b))); }
|
||||
template<> __forceinline vfloat4 shuffle<0, 0, 2, 2>(const vfloat4& v) { return _mm_moveldup_ps(v); }
|
||||
template<> __forceinline vfloat4 shuffle<1, 1, 3, 3>(const vfloat4& v) { return _mm_movehdup_ps(v); }
|
||||
template<> __forceinline vfloat4 shuffle<0, 1, 0, 1>(const vfloat4& v) { return _mm_castpd_ps(_mm_movedup_pd(_mm_castps_pd(v))); }
|
||||
#endif
|
||||
|
||||
template<size_t i0> __forceinline const vfloat4 shuffle( const vfloat4& b ) {
|
||||
return shuffle<i0,i0,i0,i0>(b);
|
||||
template<int i>
|
||||
__forceinline vfloat4 shuffle(const vfloat4& v) {
|
||||
return shuffle<i,i,i,i>(v);
|
||||
}
|
||||
|
||||
#if defined (__SSE4_1__) && !defined(__GNUC__)
|
||||
template<size_t i> __forceinline float extract ( const vfloat4& a ) { return _mm_cvtss_f32(_mm_extract_ps(a,i)); }
|
||||
template<int i> __forceinline float extract(const vfloat4& a) { return _mm_cvtss_f32(_mm_extract_ps(a,i)); }
|
||||
#else
|
||||
template<size_t i> __forceinline float extract ( const vfloat4& a ) { return _mm_cvtss_f32(shuffle<i,i,i,i>(a)); }
|
||||
template<int i> __forceinline float extract(const vfloat4& a) { return _mm_cvtss_f32(shuffle<i,i,i,i>(a)); }
|
||||
#endif
|
||||
template<> __forceinline float extract<0>( const vfloat4& a ) { return _mm_cvtss_f32(a); }
|
||||
template<> __forceinline float extract<0>(const vfloat4& a) { return _mm_cvtss_f32(a); }
|
||||
|
||||
#if defined (__SSE4_1__)
|
||||
template<size_t dst, size_t src, size_t clr> __forceinline const vfloat4 insert( const vfloat4& a, const vfloat4& b ) { return _mm_insert_ps(a, b, (dst << 4) | (src << 6) | clr); }
|
||||
template<size_t dst, size_t src> __forceinline const vfloat4 insert( const vfloat4& a, const vfloat4& b ) { return insert<dst, src, 0>(a, b); }
|
||||
template<size_t dst> __forceinline const vfloat4 insert( const vfloat4& a, const float b ) { return insert<dst, 0>(a, _mm_set_ss(b)); }
|
||||
template<int dst, int src, int clr> __forceinline vfloat4 insert(const vfloat4& a, const vfloat4& b) { return _mm_insert_ps(a, b, (dst << 4) | (src << 6) | clr); }
|
||||
template<int dst, int src> __forceinline vfloat4 insert(const vfloat4& a, const vfloat4& b) { return insert<dst, src, 0>(a, b); }
|
||||
template<int dst> __forceinline vfloat4 insert(const vfloat4& a, const float b) { return insert<dst, 0>(a, _mm_set_ss(b)); }
|
||||
#else
|
||||
template<size_t dst, size_t src> __forceinline const vfloat4 insert( const vfloat4& a, const vfloat4& b ) { vfloat4 c = a; c[dst] = b[src]; return c; }
|
||||
template<size_t dst> __forceinline const vfloat4 insert( const vfloat4& a, const float b ) { vfloat4 c = a; c[dst] = b; return c; }
|
||||
template<int dst, int src> __forceinline vfloat4 insert(const vfloat4& a, const vfloat4& b) { vfloat4 c = a; c[dst&3] = b[src&3]; return c; }
|
||||
template<int dst> __forceinline vfloat4 insert(const vfloat4& a, float b) { vfloat4 c = a; c[dst&3] = b; return c; }
|
||||
#endif
|
||||
|
||||
__forceinline float toScalar(const vfloat4& a) { return _mm_cvtss_f32(a); }
|
||||
__forceinline float toScalar(const vfloat4& v) { return _mm_cvtss_f32(v); }
|
||||
|
||||
__forceinline vfloat4 broadcast4f( const vfloat4& a, const size_t k ) {
|
||||
__forceinline vfloat4 broadcast4f(const vfloat4& a, size_t k) {
|
||||
return vfloat4::broadcast(&a[k]);
|
||||
}
|
||||
|
||||
__forceinline vfloat4 shift_right_1( const vfloat4& x) {
|
||||
__forceinline vfloat4 shift_right_1(const vfloat4& x) {
|
||||
return _mm_castsi128_ps(_mm_srli_si128(_mm_castps_si128(x), 4));
|
||||
}
|
||||
|
||||
@@ -493,10 +551,18 @@ namespace embree
|
||||
return _mm_permutevar_ps(a,index);
|
||||
}
|
||||
|
||||
__forceinline vfloat4 broadcast1f( const void* const a ) { return _mm_broadcast_ss((float*)a); }
|
||||
__forceinline vfloat4 broadcast1f(const void* a) { return _mm_broadcast_ss((float*)a); }
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__AVX512VL__)
|
||||
template<int i>
|
||||
__forceinline vfloat4 align_shift_right(const vfloat4& a, const vfloat4& b) {
|
||||
return _mm_castsi128_ps(_mm_alignr_epi32(_mm_castps_si128(a), _mm_castps_si128(b), i));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Sorting Network
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -568,9 +634,9 @@ namespace embree
|
||||
/// Reductions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vfloat4 vreduce_min(const vfloat4& v) { vfloat4 h = min(shuffle<1,0,3,2>(v),v); return min(shuffle<2,3,0,1>(h),h); }
|
||||
__forceinline const vfloat4 vreduce_max(const vfloat4& v) { vfloat4 h = max(shuffle<1,0,3,2>(v),v); return max(shuffle<2,3,0,1>(h),h); }
|
||||
__forceinline const vfloat4 vreduce_add(const vfloat4& v) { vfloat4 h = shuffle<1,0,3,2>(v) + v ; return shuffle<2,3,0,1>(h) + h ; }
|
||||
__forceinline vfloat4 vreduce_min(const vfloat4& v) { vfloat4 h = min(shuffle<1,0,3,2>(v),v); return min(shuffle<2,3,0,1>(h),h); }
|
||||
__forceinline vfloat4 vreduce_max(const vfloat4& v) { vfloat4 h = max(shuffle<1,0,3,2>(v),v); return max(shuffle<2,3,0,1>(h),h); }
|
||||
__forceinline vfloat4 vreduce_add(const vfloat4& v) { vfloat4 h = shuffle<1,0,3,2>(v) + v ; return shuffle<2,3,0,1>(h) + h ; }
|
||||
|
||||
__forceinline float reduce_min(const vfloat4& v) { return _mm_cvtss_f32(vreduce_min(v)); }
|
||||
__forceinline float reduce_max(const vfloat4& v) { return _mm_cvtss_f32(vreduce_max(v)); }
|
||||
@@ -593,11 +659,11 @@ namespace embree
|
||||
/// Euclidian Space Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline float dot ( const vfloat4& a, const vfloat4& b ) {
|
||||
__forceinline float dot(const vfloat4& a, const vfloat4& b) {
|
||||
return reduce_add(a*b);
|
||||
}
|
||||
|
||||
__forceinline vfloat4 cross ( const vfloat4& a, const vfloat4& b )
|
||||
__forceinline vfloat4 cross(const vfloat4& a, const vfloat4& b)
|
||||
{
|
||||
const vfloat4 a0 = a;
|
||||
const vfloat4 b0 = shuffle<1,2,0,3>(b);
|
||||
@@ -610,7 +676,7 @@ namespace embree
|
||||
/// Output Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& cout, const vfloat4& a) {
|
||||
inline std::ostream& operator <<(std::ostream& cout, const vfloat4& a) {
|
||||
return cout << "<" << a[0] << ", " << a[1] << ", " << a[2] << ", " << a[3] << ">";
|
||||
}
|
||||
|
||||
|
||||
+295
-214
@@ -33,45 +33,46 @@ namespace embree
|
||||
/// Constructors, Assignment & Cast Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vfloat ( ) {}
|
||||
__forceinline vfloat ( const vfloat8& other ) { v = other.v; }
|
||||
__forceinline vfloat8& operator=( const vfloat8& other ) { v = other.v; return *this; }
|
||||
__forceinline vfloat() {}
|
||||
__forceinline vfloat(const vfloat8& other) { v = other.v; }
|
||||
__forceinline vfloat8& operator =(const vfloat8& other) { v = other.v; return *this; }
|
||||
|
||||
__forceinline vfloat( const __m256 a ) : v(a) {}
|
||||
__forceinline operator const __m256&( void ) const { return v; }
|
||||
__forceinline operator __m256&( void ) { return v; }
|
||||
__forceinline vfloat(__m256 a) : v(a) {}
|
||||
__forceinline operator const __m256&() const { return v; }
|
||||
__forceinline operator __m256&() { return v; }
|
||||
|
||||
__forceinline explicit vfloat( const vfloat4& a ) : v(_mm256_insertf128_ps(_mm256_castps128_ps256(a),a,1)) {}
|
||||
__forceinline vfloat( const vfloat4& a, const vfloat4& b ) : v(_mm256_insertf128_ps(_mm256_castps128_ps256(a),b,1)) {}
|
||||
__forceinline explicit vfloat(const vfloat4& a) : v(_mm256_insertf128_ps(_mm256_castps128_ps256(a),a,1)) {}
|
||||
__forceinline vfloat(const vfloat4& a, const vfloat4& b) : v(_mm256_insertf128_ps(_mm256_castps128_ps256(a),b,1)) {}
|
||||
|
||||
__forceinline explicit vfloat( const char* const a ) : v(_mm256_loadu_ps((const float*)a)) {}
|
||||
__forceinline vfloat( const float& a ) : v(_mm256_broadcast_ss(&a)) {}
|
||||
__forceinline vfloat( float a, float b) : v(_mm256_set_ps(b, a, b, a, b, a, b, a)) {}
|
||||
__forceinline vfloat( float a, float b, float c, float d ) : v(_mm256_set_ps(d, c, b, a, d, c, b, a)) {}
|
||||
__forceinline vfloat( float a, float b, float c, float d, float e, float f, float g, float h ) : v(_mm256_set_ps(h, g, f, e, d, c, b, a)) {}
|
||||
__forceinline explicit vfloat(const char* a) : v(_mm256_loadu_ps((const float*)a)) {}
|
||||
__forceinline vfloat(float a) : v(_mm256_set1_ps(a)) {}
|
||||
__forceinline vfloat(float a, float b) : v(_mm256_set_ps(b, a, b, a, b, a, b, a)) {}
|
||||
__forceinline vfloat(float a, float b, float c, float d) : v(_mm256_set_ps(d, c, b, a, d, c, b, a)) {}
|
||||
__forceinline vfloat(float a, float b, float c, float d, float e, float f, float g, float h) : v(_mm256_set_ps(h, g, f, e, d, c, b, a)) {}
|
||||
|
||||
__forceinline explicit vfloat( const __m256i a ) : v(_mm256_cvtepi32_ps(a)) {}
|
||||
__forceinline explicit vfloat(__m256i a) : v(_mm256_cvtepi32_ps(a)) {}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Constants
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vfloat( ZeroTy ) : v(_mm256_setzero_ps()) {}
|
||||
__forceinline vfloat( OneTy ) : v(_mm256_set1_ps(1.0f)) {}
|
||||
__forceinline vfloat( PosInfTy ) : v(_mm256_set1_ps(pos_inf)) {}
|
||||
__forceinline vfloat( NegInfTy ) : v(_mm256_set1_ps(neg_inf)) {}
|
||||
__forceinline vfloat( StepTy ) : v(_mm256_set_ps(7.0f, 6.0f, 5.0f, 4.0f, 3.0f, 2.0f, 1.0f, 0.0f)) {}
|
||||
__forceinline vfloat( NaNTy ) : v(_mm256_set1_ps(nan)) {}
|
||||
__forceinline vfloat(ZeroTy) : v(_mm256_setzero_ps()) {}
|
||||
__forceinline vfloat(OneTy) : v(_mm256_set1_ps(1.0f)) {}
|
||||
__forceinline vfloat(PosInfTy) : v(_mm256_set1_ps(pos_inf)) {}
|
||||
__forceinline vfloat(NegInfTy) : v(_mm256_set1_ps(neg_inf)) {}
|
||||
__forceinline vfloat(StepTy) : v(_mm256_set_ps(7.0f, 6.0f, 5.0f, 4.0f, 3.0f, 2.0f, 1.0f, 0.0f)) {}
|
||||
__forceinline vfloat(NaNTy) : v(_mm256_set1_ps(nan)) {}
|
||||
__forceinline vfloat(UndefinedTy) : v(_mm256_undefined_ps()) {}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Loads and Stores
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static __forceinline vfloat8 broadcast( const void* const a ) {
|
||||
static __forceinline vfloat8 broadcast(const void* a) {
|
||||
return _mm256_broadcast_ss((float*)a);
|
||||
}
|
||||
|
||||
static __forceinline vfloat8 broadcast2( const float* const a, const float* const b ) {
|
||||
static __forceinline vfloat8 broadcast2(const float* a, const float* b) {
|
||||
#if defined(__INTEL_COMPILER)
|
||||
const vfloat8 v0 = _mm256_broadcast_ss(a);
|
||||
const vfloat8 v1 = _mm256_broadcast_ss(b);
|
||||
@@ -81,11 +82,11 @@ namespace embree
|
||||
#endif
|
||||
}
|
||||
|
||||
static __forceinline const vfloat8 broadcast4f(const vfloat4* ptr) {
|
||||
static __forceinline vfloat8 broadcast4f(const vfloat4* ptr) {
|
||||
return _mm256_broadcast_ps((__m128*)ptr);
|
||||
}
|
||||
|
||||
static __forceinline vfloat8 load( const unsigned char* const ptr ) {
|
||||
static __forceinline vfloat8 load(const unsigned char* ptr) {
|
||||
#if defined(__AVX2__)
|
||||
return _mm256_cvtepi32_ps(_mm256_cvtepu8_epi32(_mm_loadu_si128((__m128i*)ptr)));
|
||||
#else
|
||||
@@ -93,24 +94,32 @@ namespace embree
|
||||
#endif
|
||||
}
|
||||
|
||||
static __forceinline vfloat8 load ( const void* const ptr) { return _mm256_load_ps((float*)ptr); }
|
||||
static __forceinline vfloat8 loadu( const void* const ptr) { return _mm256_loadu_ps((float*)ptr); }
|
||||
static __forceinline vfloat8 load (const void* ptr) { return _mm256_load_ps((float*)ptr); }
|
||||
static __forceinline vfloat8 loadu(const void* ptr) { return _mm256_loadu_ps((float*)ptr); }
|
||||
|
||||
static __forceinline void store ( void* ptr, const vfloat8& v) { return _mm256_store_ps((float*)ptr,v); }
|
||||
static __forceinline void storeu( void* ptr, const vfloat8& v) { return _mm256_storeu_ps((float*)ptr,v); }
|
||||
static __forceinline void store (void* ptr, const vfloat8& v) { return _mm256_store_ps((float*)ptr,v); }
|
||||
static __forceinline void storeu(void* ptr, const vfloat8& v) { return _mm256_storeu_ps((float*)ptr,v); }
|
||||
|
||||
#if defined(__AVX512VL__)
|
||||
static __forceinline vfloat8 load ( const vboolf8& mask, const void* const ptr) { return _mm256_mask_load_ps (_mm256_setzero_ps(),mask,(float*)ptr); }
|
||||
static __forceinline vfloat8 loadu( const vboolf8& mask, const void* const ptr) { return _mm256_mask_loadu_ps(_mm256_setzero_ps(),mask,(float*)ptr); }
|
||||
|
||||
static __forceinline void store ( const vboolf8& mask, void* ptr, const vfloat8& v) { _mm256_mask_store_ps ((float*)ptr,mask,v); }
|
||||
static __forceinline void storeu( const vboolf8& mask, void* ptr, const vfloat8& v) { _mm256_mask_storeu_ps((float*)ptr,mask,v); }
|
||||
static __forceinline vfloat8 compact(const vboolf8& mask, vfloat8 &v) {
|
||||
return _mm256_mask_compress_ps(v, mask, v);
|
||||
}
|
||||
static __forceinline vfloat8 compact(const vboolf8& mask, vfloat8 &a, const vfloat8& b) {
|
||||
return _mm256_mask_compress_ps(a, mask, b);
|
||||
}
|
||||
|
||||
static __forceinline vfloat8 load (const vboolf8& mask, const void* ptr) { return _mm256_mask_load_ps (_mm256_setzero_ps(),mask,(float*)ptr); }
|
||||
static __forceinline vfloat8 loadu(const vboolf8& mask, const void* ptr) { return _mm256_mask_loadu_ps(_mm256_setzero_ps(),mask,(float*)ptr); }
|
||||
|
||||
static __forceinline void store (const vboolf8& mask, void* ptr, const vfloat8& v) { _mm256_mask_store_ps ((float*)ptr,mask,v); }
|
||||
static __forceinline void storeu(const vboolf8& mask, void* ptr, const vfloat8& v) { _mm256_mask_storeu_ps((float*)ptr,mask,v); }
|
||||
#else
|
||||
static __forceinline vfloat8 load ( const vboolf8& mask, const void* const ptr) { return _mm256_maskload_ps((float*)ptr,(__m256i)mask); }
|
||||
static __forceinline vfloat8 loadu( const vboolf8& mask, const void* const ptr) { return _mm256_maskload_ps((float*)ptr,(__m256i)mask); }
|
||||
static __forceinline vfloat8 load (const vboolf8& mask, const void* ptr) { return _mm256_maskload_ps((float*)ptr,(__m256i)mask); }
|
||||
static __forceinline vfloat8 loadu(const vboolf8& mask, const void* ptr) { return _mm256_maskload_ps((float*)ptr,(__m256i)mask); }
|
||||
|
||||
static __forceinline void store ( const vboolf8& mask, void* ptr, const vfloat8& v) { _mm256_maskstore_ps((float*)ptr,(__m256i)mask,v); }
|
||||
static __forceinline void storeu( const vboolf8& mask, void* ptr, const vfloat8& v) { _mm256_maskstore_ps((float*)ptr,(__m256i)mask,v); }
|
||||
static __forceinline void store (const vboolf8& mask, void* ptr, const vfloat8& v) { _mm256_maskstore_ps((float*)ptr,(__m256i)mask,v); }
|
||||
static __forceinline void storeu(const vboolf8& mask, void* ptr, const vfloat8& v) { _mm256_maskstore_ps((float*)ptr,(__m256i)mask,v); }
|
||||
#endif
|
||||
|
||||
#if defined(__AVX2__)
|
||||
@@ -123,8 +132,62 @@ namespace embree
|
||||
_mm256_stream_ps((float*)ptr,v);
|
||||
}
|
||||
|
||||
template<int scale>
|
||||
static __forceinline void scatter(const vboolf8& mask, void* ptr, const vint8& ofs, const vfloat8& v)
|
||||
template<int scale = 4>
|
||||
static __forceinline vfloat8 gather(const float* ptr, const vint8& index) {
|
||||
#if defined(__AVX2__)
|
||||
return _mm256_i32gather_ps(ptr, index ,scale);
|
||||
#else
|
||||
return vfloat8(
|
||||
*(float*)(((char*)ptr)+scale*index[0]),
|
||||
*(float*)(((char*)ptr)+scale*index[1]),
|
||||
*(float*)(((char*)ptr)+scale*index[2]),
|
||||
*(float*)(((char*)ptr)+scale*index[3]),
|
||||
*(float*)(((char*)ptr)+scale*index[4]),
|
||||
*(float*)(((char*)ptr)+scale*index[5]),
|
||||
*(float*)(((char*)ptr)+scale*index[6]),
|
||||
*(float*)(((char*)ptr)+scale*index[7]));
|
||||
#endif
|
||||
}
|
||||
|
||||
template<int scale = 4>
|
||||
static __forceinline vfloat8 gather(const vboolf8& mask, const float* ptr, const vint8& index) {
|
||||
vfloat8 r = zero;
|
||||
#if defined(__AVX512VL__)
|
||||
return _mm256_mmask_i32gather_ps(r, mask, index, ptr, scale);
|
||||
#elif defined(__AVX2__)
|
||||
return _mm256_mask_i32gather_ps(r, ptr, index, mask, scale);
|
||||
#else
|
||||
if (likely(mask[0])) r[0] = *(float*)(((char*)ptr)+scale*index[0]);
|
||||
if (likely(mask[1])) r[1] = *(float*)(((char*)ptr)+scale*index[1]);
|
||||
if (likely(mask[2])) r[2] = *(float*)(((char*)ptr)+scale*index[2]);
|
||||
if (likely(mask[3])) r[3] = *(float*)(((char*)ptr)+scale*index[3]);
|
||||
if (likely(mask[4])) r[4] = *(float*)(((char*)ptr)+scale*index[4]);
|
||||
if (likely(mask[5])) r[5] = *(float*)(((char*)ptr)+scale*index[5]);
|
||||
if (likely(mask[6])) r[6] = *(float*)(((char*)ptr)+scale*index[6]);
|
||||
if (likely(mask[7])) r[7] = *(float*)(((char*)ptr)+scale*index[7]);
|
||||
return r;
|
||||
#endif
|
||||
}
|
||||
|
||||
template<int scale = 4>
|
||||
static __forceinline void scatter(void* ptr, const vint8& ofs, const vfloat8& v)
|
||||
{
|
||||
#if defined(__AVX512VL__)
|
||||
_mm256_i32scatter_ps((float*)ptr,ofs,v,scale);
|
||||
#else
|
||||
*(float*)(((char*)ptr)+scale*ofs[0]) = v[0];
|
||||
*(float*)(((char*)ptr)+scale*ofs[1]) = v[1];
|
||||
*(float*)(((char*)ptr)+scale*ofs[2]) = v[2];
|
||||
*(float*)(((char*)ptr)+scale*ofs[3]) = v[3];
|
||||
*(float*)(((char*)ptr)+scale*ofs[4]) = v[4];
|
||||
*(float*)(((char*)ptr)+scale*ofs[5]) = v[5];
|
||||
*(float*)(((char*)ptr)+scale*ofs[6]) = v[6];
|
||||
*(float*)(((char*)ptr)+scale*ofs[7]) = v[7];
|
||||
#endif
|
||||
}
|
||||
|
||||
template<int scale = 4>
|
||||
static __forceinline void scatter(const vboolf8& mask, void* ptr, const vint8& ofs, const vfloat8& v)
|
||||
{
|
||||
#if defined(__AVX512VL__)
|
||||
_mm256_mask_i32scatter_ps((float*)ptr,mask,ofs,v,scale);
|
||||
@@ -151,8 +214,8 @@ namespace embree
|
||||
/// Array Access
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const float& operator []( const size_t index ) const { assert(index < 8); return f[index]; }
|
||||
__forceinline float& operator []( const size_t index ) { assert(index < 8); return f[index]; }
|
||||
__forceinline const float& operator [](size_t index) const { assert(index < 8); return f[index]; }
|
||||
__forceinline float& operator [](size_t index) { assert(index < 8); return f[index]; }
|
||||
};
|
||||
|
||||
|
||||
@@ -160,44 +223,45 @@ namespace embree
|
||||
/// Unary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vfloat8 asFloat ( const vint8& a ) { return _mm256_castsi256_ps(a); }
|
||||
__forceinline const vint8 asInt ( const vfloat8& a ) { return _mm256_castps_si256(a); }
|
||||
__forceinline const vfloat8 operator +( const vfloat8& a ) { return a; }
|
||||
__forceinline const vfloat8 operator -( const vfloat8& a ) {
|
||||
__forceinline vfloat8 asFloat(const vint8& a) { return _mm256_castsi256_ps(a); }
|
||||
__forceinline vint8 asInt (const vfloat8& a) { return _mm256_castps_si256(a); }
|
||||
|
||||
__forceinline vfloat8 operator +(const vfloat8& a) { return a; }
|
||||
__forceinline vfloat8 operator -(const vfloat8& a) {
|
||||
const __m256 mask = _mm256_castsi256_ps(_mm256_set1_epi32(0x80000000));
|
||||
return _mm256_xor_ps(a.v, mask);
|
||||
return _mm256_xor_ps(a, mask);
|
||||
}
|
||||
__forceinline const vfloat8 abs ( const vfloat8& a ) {
|
||||
__forceinline vfloat8 abs(const vfloat8& a) {
|
||||
const __m256 mask = _mm256_castsi256_ps(_mm256_set1_epi32(0x7fffffff));
|
||||
return _mm256_and_ps(a.v, mask);
|
||||
return _mm256_and_ps(a, mask);
|
||||
}
|
||||
__forceinline const vfloat8 sign ( const vfloat8& a ) { return _mm256_blendv_ps(vfloat8(one), -vfloat8(one), _mm256_cmp_ps(a, vfloat8(zero), _CMP_NGE_UQ )); }
|
||||
__forceinline const vfloat8 signmsk ( const vfloat8& a ) { return _mm256_and_ps(a.v,_mm256_castsi256_ps(_mm256_set1_epi32(0x80000000))); }
|
||||
__forceinline vfloat8 sign (const vfloat8& a) { return _mm256_blendv_ps(vfloat8(one), -vfloat8(one), _mm256_cmp_ps(a, vfloat8(zero), _CMP_NGE_UQ)); }
|
||||
__forceinline vfloat8 signmsk(const vfloat8& a) { return _mm256_and_ps(a,_mm256_castsi256_ps(_mm256_set1_epi32(0x80000000))); }
|
||||
|
||||
|
||||
__forceinline const vfloat8 rcp(const vfloat8& a)
|
||||
__forceinline vfloat8 rcp(const vfloat8& a)
|
||||
{
|
||||
#if defined(__AVX512VL__)
|
||||
const vfloat8 r = _mm256_rcp14_ps(a.v);
|
||||
const vfloat8 r = _mm256_rcp14_ps(a);
|
||||
#else
|
||||
const vfloat8 r = _mm256_rcp_ps(a.v);
|
||||
const vfloat8 r = _mm256_rcp_ps(a);
|
||||
#endif
|
||||
|
||||
#if defined(__AVX2__)
|
||||
return _mm256_mul_ps(r,_mm256_fnmadd_ps(r, a, vfloat8(2.0f)));
|
||||
return _mm256_mul_ps(r, _mm256_fnmadd_ps(r, a, vfloat8(2.0f)));
|
||||
#else
|
||||
return _mm256_mul_ps(r,_mm256_sub_ps(vfloat8(2.0f), _mm256_mul_ps(r, a)));
|
||||
return _mm256_mul_ps(r, _mm256_sub_ps(vfloat8(2.0f), _mm256_mul_ps(r, a)));
|
||||
#endif
|
||||
}
|
||||
__forceinline const vfloat8 sqr ( const vfloat8& a ) { return _mm256_mul_ps(a,a); }
|
||||
__forceinline const vfloat8 sqrt ( const vfloat8& a ) { return _mm256_sqrt_ps(a.v); }
|
||||
__forceinline vfloat8 sqr (const vfloat8& a) { return _mm256_mul_ps(a,a); }
|
||||
__forceinline vfloat8 sqrt(const vfloat8& a) { return _mm256_sqrt_ps(a); }
|
||||
|
||||
__forceinline const vfloat8 rsqrt( const vfloat8& a )
|
||||
__forceinline vfloat8 rsqrt(const vfloat8& a)
|
||||
{
|
||||
#if defined(__AVX512VL__)
|
||||
const vfloat8 r = _mm256_rsqrt14_ps(a.v);
|
||||
const vfloat8 r = _mm256_rsqrt14_ps(a);
|
||||
#else
|
||||
const vfloat8 r = _mm256_rsqrt_ps(a.v);
|
||||
const vfloat8 r = _mm256_rsqrt_ps(a);
|
||||
#endif
|
||||
|
||||
#if defined(__AVX2__)
|
||||
@@ -213,70 +277,75 @@ namespace embree
|
||||
/// Binary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vfloat8 operator +( const vfloat8& a, const vfloat8& b ) { return _mm256_add_ps(a.v, b.v); }
|
||||
__forceinline const vfloat8 operator +( const vfloat8& a, const float b ) { return a + vfloat8(b); }
|
||||
__forceinline const vfloat8 operator +( const float a, const vfloat8& b ) { return vfloat8(a) + b; }
|
||||
__forceinline vfloat8 operator +(const vfloat8& a, const vfloat8& b) { return _mm256_add_ps(a, b); }
|
||||
__forceinline vfloat8 operator +(const vfloat8& a, float b) { return a + vfloat8(b); }
|
||||
__forceinline vfloat8 operator +(float a, const vfloat8& b) { return vfloat8(a) + b; }
|
||||
|
||||
__forceinline const vfloat8 operator -( const vfloat8& a, const vfloat8& b ) { return _mm256_sub_ps(a.v, b.v); }
|
||||
__forceinline const vfloat8 operator -( const vfloat8& a, const float b ) { return a - vfloat8(b); }
|
||||
__forceinline const vfloat8 operator -( const float a, const vfloat8& b ) { return vfloat8(a) - b; }
|
||||
__forceinline vfloat8 operator -(const vfloat8& a, const vfloat8& b) { return _mm256_sub_ps(a, b); }
|
||||
__forceinline vfloat8 operator -(const vfloat8& a, float b) { return a - vfloat8(b); }
|
||||
__forceinline vfloat8 operator -(float a, const vfloat8& b) { return vfloat8(a) - b; }
|
||||
|
||||
__forceinline const vfloat8 operator *( const vfloat8& a, const vfloat8& b ) { return _mm256_mul_ps(a.v, b.v); }
|
||||
__forceinline const vfloat8 operator *( const vfloat8& a, const float b ) { return a * vfloat8(b); }
|
||||
__forceinline const vfloat8 operator *( const float a, const vfloat8& b ) { return vfloat8(a) * b; }
|
||||
__forceinline vfloat8 operator *(const vfloat8& a, const vfloat8& b) { return _mm256_mul_ps(a, b); }
|
||||
__forceinline vfloat8 operator *(const vfloat8& a, float b) { return a * vfloat8(b); }
|
||||
__forceinline vfloat8 operator *(float a, const vfloat8& b) { return vfloat8(a) * b; }
|
||||
|
||||
__forceinline const vfloat8 operator /( const vfloat8& a, const vfloat8& b ) { return _mm256_div_ps(a.v, b.v); }
|
||||
__forceinline const vfloat8 operator /( const vfloat8& a, const float b ) { return a / vfloat8(b); }
|
||||
__forceinline const vfloat8 operator /( const float a, const vfloat8& b ) { return vfloat8(a) / b; }
|
||||
__forceinline vfloat8 operator /(const vfloat8& a, const vfloat8& b) { return _mm256_div_ps(a, b); }
|
||||
__forceinline vfloat8 operator /(const vfloat8& a, float b) { return a / vfloat8(b); }
|
||||
__forceinline vfloat8 operator /(float a, const vfloat8& b) { return vfloat8(a) / b; }
|
||||
|
||||
__forceinline const vfloat8 operator^( const vfloat8& a, const vfloat8& b ) { return _mm256_xor_ps(a.v,b.v); }
|
||||
__forceinline const vfloat8 operator^( const vfloat8& a, const vint8& b ) { return _mm256_xor_ps(a.v,_mm256_castsi256_ps(b.v)); }
|
||||
__forceinline vfloat8 operator ^(const vfloat8& a, const vfloat8& b) { return _mm256_xor_ps(a,b); }
|
||||
__forceinline vfloat8 operator ^(const vfloat8& a, const vint8& b) { return _mm256_xor_ps(a,_mm256_castsi256_ps(b)); }
|
||||
|
||||
__forceinline const vfloat8 operator&( const vfloat8& a, const vfloat8& b ) { return _mm256_and_ps(a.v,b.v); }
|
||||
__forceinline vfloat8 operator &(const vfloat8& a, const vfloat8& b) { return _mm256_and_ps(a,b); }
|
||||
|
||||
__forceinline const vfloat8 min( const vfloat8& a, const vfloat8& b ) { return _mm256_min_ps(a.v, b.v); }
|
||||
__forceinline const vfloat8 min( const vfloat8& a, const float b ) { return _mm256_min_ps(a.v, vfloat8(b)); }
|
||||
__forceinline const vfloat8 min( const float a, const vfloat8& b ) { return _mm256_min_ps(vfloat8(a), b.v); }
|
||||
__forceinline vfloat8 min(const vfloat8& a, const vfloat8& b) { return _mm256_min_ps(a, b); }
|
||||
__forceinline vfloat8 min(const vfloat8& a, float b) { return _mm256_min_ps(a, vfloat8(b)); }
|
||||
__forceinline vfloat8 min(float a, const vfloat8& b) { return _mm256_min_ps(vfloat8(a), b); }
|
||||
|
||||
__forceinline const vfloat8 max( const vfloat8& a, const vfloat8& b ) { return _mm256_max_ps(a.v, b.v); }
|
||||
__forceinline const vfloat8 max( const vfloat8& a, const float b ) { return _mm256_max_ps(a.v, vfloat8(b)); }
|
||||
__forceinline const vfloat8 max( const float a, const vfloat8& b ) { return _mm256_max_ps(vfloat8(a), b.v); }
|
||||
__forceinline vfloat8 max(const vfloat8& a, const vfloat8& b) { return _mm256_max_ps(a, b); }
|
||||
__forceinline vfloat8 max(const vfloat8& a, float b) { return _mm256_max_ps(a, vfloat8(b)); }
|
||||
__forceinline vfloat8 max(float a, const vfloat8& b) { return _mm256_max_ps(vfloat8(a), b); }
|
||||
|
||||
#if defined (__AVX2__)
|
||||
#if defined(__AVX2__)
|
||||
|
||||
__forceinline vfloat8 mini(const vfloat8& a, const vfloat8& b) {
|
||||
const vint8 ai = _mm256_castps_si256(a);
|
||||
const vint8 bi = _mm256_castps_si256(b);
|
||||
const vint8 ci = _mm256_min_epi32(ai,bi);
|
||||
return _mm256_castsi256_ps(ci);
|
||||
}
|
||||
__forceinline vfloat8 maxi(const vfloat8& a, const vfloat8& b) {
|
||||
const vint8 ai = _mm256_castps_si256(a);
|
||||
const vint8 bi = _mm256_castps_si256(b);
|
||||
const vint8 ci = _mm256_max_epi32(ai,bi);
|
||||
return _mm256_castsi256_ps(ci);
|
||||
}
|
||||
__forceinline vfloat8 mini(const vfloat8& a, const vfloat8& b) {
|
||||
const vint8 ai = _mm256_castps_si256(a);
|
||||
const vint8 bi = _mm256_castps_si256(b);
|
||||
const vint8 ci = _mm256_min_epi32(ai,bi);
|
||||
return _mm256_castsi256_ps(ci);
|
||||
}
|
||||
|
||||
__forceinline vfloat8 minui(const vfloat8& a, const vfloat8& b) {
|
||||
const vint8 ai = _mm256_castps_si256(a);
|
||||
const vint8 bi = _mm256_castps_si256(b);
|
||||
const vint8 ci = _mm256_min_epu32(ai,bi);
|
||||
return _mm256_castsi256_ps(ci);
|
||||
}
|
||||
__forceinline vfloat8 maxui(const vfloat8& a, const vfloat8& b) {
|
||||
const vint8 ai = _mm256_castps_si256(a);
|
||||
const vint8 bi = _mm256_castps_si256(b);
|
||||
const vint8 ci = _mm256_max_epu32(ai,bi);
|
||||
return _mm256_castsi256_ps(ci);
|
||||
}
|
||||
__forceinline vfloat8 maxi(const vfloat8& a, const vfloat8& b) {
|
||||
const vint8 ai = _mm256_castps_si256(a);
|
||||
const vint8 bi = _mm256_castps_si256(b);
|
||||
const vint8 ci = _mm256_max_epi32(ai,bi);
|
||||
return _mm256_castsi256_ps(ci);
|
||||
}
|
||||
|
||||
__forceinline vfloat8 minui(const vfloat8& a, const vfloat8& b) {
|
||||
const vint8 ai = _mm256_castps_si256(a);
|
||||
const vint8 bi = _mm256_castps_si256(b);
|
||||
const vint8 ci = _mm256_min_epu32(ai,bi);
|
||||
return _mm256_castsi256_ps(ci);
|
||||
}
|
||||
|
||||
__forceinline vfloat8 maxui(const vfloat8& a, const vfloat8& b) {
|
||||
const vint8 ai = _mm256_castps_si256(a);
|
||||
const vint8 bi = _mm256_castps_si256(b);
|
||||
const vint8 ci = _mm256_max_epu32(ai,bi);
|
||||
return _mm256_castsi256_ps(ci);
|
||||
}
|
||||
|
||||
#else
|
||||
__forceinline vfloat8 mini(const vfloat8& a, const vfloat8& b) {
|
||||
return min(a,b);
|
||||
}
|
||||
__forceinline vfloat8 maxi(const vfloat8& a, const vfloat8& b) {
|
||||
return max(a,b);
|
||||
}
|
||||
|
||||
__forceinline vfloat8 mini(const vfloat8& a, const vfloat8& b) {
|
||||
return min(a,b);
|
||||
}
|
||||
|
||||
__forceinline vfloat8 maxi(const vfloat8& a, const vfloat8& b) {
|
||||
return max(a,b);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -284,83 +353,83 @@ namespace embree
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined(__AVX2__)
|
||||
__forceinline const vfloat8 madd ( const vfloat8& a, const vfloat8& b, const vfloat8& c) { return _mm256_fmadd_ps(a,b,c); }
|
||||
__forceinline const vfloat8 msub ( const vfloat8& a, const vfloat8& b, const vfloat8& c) { return _mm256_fmsub_ps(a,b,c); }
|
||||
__forceinline const vfloat8 nmadd ( const vfloat8& a, const vfloat8& b, const vfloat8& c) { return _mm256_fnmadd_ps(a,b,c); }
|
||||
__forceinline const vfloat8 nmsub ( const vfloat8& a, const vfloat8& b, const vfloat8& c) { return _mm256_fnmsub_ps(a,b,c); }
|
||||
__forceinline vfloat8 madd (const vfloat8& a, const vfloat8& b, const vfloat8& c) { return _mm256_fmadd_ps(a,b,c); }
|
||||
__forceinline vfloat8 msub (const vfloat8& a, const vfloat8& b, const vfloat8& c) { return _mm256_fmsub_ps(a,b,c); }
|
||||
__forceinline vfloat8 nmadd (const vfloat8& a, const vfloat8& b, const vfloat8& c) { return _mm256_fnmadd_ps(a,b,c); }
|
||||
__forceinline vfloat8 nmsub (const vfloat8& a, const vfloat8& b, const vfloat8& c) { return _mm256_fnmsub_ps(a,b,c); }
|
||||
#else
|
||||
__forceinline const vfloat8 madd ( const vfloat8& a, const vfloat8& b, const vfloat8& c) { return a*b+c; }
|
||||
__forceinline const vfloat8 msub ( const vfloat8& a, const vfloat8& b, const vfloat8& c) { return a*b-c; }
|
||||
__forceinline const vfloat8 nmadd ( const vfloat8& a, const vfloat8& b, const vfloat8& c) { return -a*b+c;}
|
||||
__forceinline const vfloat8 nmsub ( const vfloat8& a, const vfloat8& b, const vfloat8& c) { return -a*b-c; }
|
||||
__forceinline vfloat8 madd (const vfloat8& a, const vfloat8& b, const vfloat8& c) { return a*b+c; }
|
||||
__forceinline vfloat8 msub (const vfloat8& a, const vfloat8& b, const vfloat8& c) { return a*b-c; }
|
||||
__forceinline vfloat8 nmadd (const vfloat8& a, const vfloat8& b, const vfloat8& c) { return -a*b+c;}
|
||||
__forceinline vfloat8 nmsub (const vfloat8& a, const vfloat8& b, const vfloat8& c) { return -a*b-c; }
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Assignment Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vfloat8& operator +=( vfloat8& a, const vfloat8& b ) { return a = a + b; }
|
||||
__forceinline vfloat8& operator +=( vfloat8& a, const float b ) { return a = a + b; }
|
||||
__forceinline vfloat8& operator +=(vfloat8& a, const vfloat8& b) { return a = a + b; }
|
||||
__forceinline vfloat8& operator +=(vfloat8& a, float b) { return a = a + b; }
|
||||
|
||||
__forceinline vfloat8& operator -=( vfloat8& a, const vfloat8& b ) { return a = a - b; }
|
||||
__forceinline vfloat8& operator -=( vfloat8& a, const float b ) { return a = a - b; }
|
||||
__forceinline vfloat8& operator -=(vfloat8& a, const vfloat8& b) { return a = a - b; }
|
||||
__forceinline vfloat8& operator -=(vfloat8& a, float b) { return a = a - b; }
|
||||
|
||||
__forceinline vfloat8& operator *=( vfloat8& a, const vfloat8& b ) { return a = a * b; }
|
||||
__forceinline vfloat8& operator *=( vfloat8& a, const float b ) { return a = a * b; }
|
||||
__forceinline vfloat8& operator *=(vfloat8& a, const vfloat8& b) { return a = a * b; }
|
||||
__forceinline vfloat8& operator *=(vfloat8& a, float b) { return a = a * b; }
|
||||
|
||||
__forceinline vfloat8& operator /=( vfloat8& a, const vfloat8& b ) { return a = a / b; }
|
||||
__forceinline vfloat8& operator /=( vfloat8& a, const float b ) { return a = a / b; }
|
||||
__forceinline vfloat8& operator /=(vfloat8& a, const vfloat8& b) { return a = a / b; }
|
||||
__forceinline vfloat8& operator /=(vfloat8& a, float b) { return a = a / b; }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Comparison Operators + Select
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined(__AVX512VL__)
|
||||
__forceinline const vboolf8 operator ==( const vfloat8& a, const vfloat8& b ) { return _mm256_cmp_ps_mask(a, b, _MM_CMPINT_EQ); }
|
||||
__forceinline const vboolf8 operator !=( const vfloat8& a, const vfloat8& b ) { return _mm256_cmp_ps_mask(a, b, _MM_CMPINT_NE); }
|
||||
__forceinline const vboolf8 operator < ( const vfloat8& a, const vfloat8& b ) { return _mm256_cmp_ps_mask(a, b, _MM_CMPINT_LT); }
|
||||
__forceinline const vboolf8 operator >=( const vfloat8& a, const vfloat8& b ) { return _mm256_cmp_ps_mask(a, b, _MM_CMPINT_GE); }
|
||||
__forceinline const vboolf8 operator > ( const vfloat8& a, const vfloat8& b ) { return _mm256_cmp_ps_mask(a, b, _MM_CMPINT_GT); }
|
||||
__forceinline const vboolf8 operator <=( const vfloat8& a, const vfloat8& b ) { return _mm256_cmp_ps_mask(a, b, _MM_CMPINT_LE); }
|
||||
__forceinline vboolf8 operator ==(const vfloat8& a, const vfloat8& b) { return _mm256_cmp_ps_mask(a, b, _MM_CMPINT_EQ); }
|
||||
__forceinline vboolf8 operator !=(const vfloat8& a, const vfloat8& b) { return _mm256_cmp_ps_mask(a, b, _MM_CMPINT_NE); }
|
||||
__forceinline vboolf8 operator < (const vfloat8& a, const vfloat8& b) { return _mm256_cmp_ps_mask(a, b, _MM_CMPINT_LT); }
|
||||
__forceinline vboolf8 operator >=(const vfloat8& a, const vfloat8& b) { return _mm256_cmp_ps_mask(a, b, _MM_CMPINT_GE); }
|
||||
__forceinline vboolf8 operator > (const vfloat8& a, const vfloat8& b) { return _mm256_cmp_ps_mask(a, b, _MM_CMPINT_GT); }
|
||||
__forceinline vboolf8 operator <=(const vfloat8& a, const vfloat8& b) { return _mm256_cmp_ps_mask(a, b, _MM_CMPINT_LE); }
|
||||
|
||||
__forceinline const vfloat8 select( const vboolf8& m, const vfloat8& t, const vfloat8& f ) {
|
||||
__forceinline vfloat8 select(const vboolf8& m, const vfloat8& t, const vfloat8& f) {
|
||||
return _mm256_mask_blend_ps(m, f, t);
|
||||
}
|
||||
#else
|
||||
__forceinline const vboolf8 operator ==( const vfloat8& a, const vfloat8& b ) { return _mm256_cmp_ps(a, b, _CMP_EQ_OQ ); }
|
||||
__forceinline const vboolf8 operator !=( const vfloat8& a, const vfloat8& b ) { return _mm256_cmp_ps(a, b, _CMP_NEQ_OQ); }
|
||||
__forceinline const vboolf8 operator < ( const vfloat8& a, const vfloat8& b ) { return _mm256_cmp_ps(a, b, _CMP_LT_OQ ); }
|
||||
__forceinline const vboolf8 operator >=( const vfloat8& a, const vfloat8& b ) { return _mm256_cmp_ps(a, b, _CMP_GE_OQ ); }
|
||||
__forceinline const vboolf8 operator > ( const vfloat8& a, const vfloat8& b ) { return _mm256_cmp_ps(a, b, _CMP_GT_OQ ); }
|
||||
__forceinline const vboolf8 operator <=( const vfloat8& a, const vfloat8& b ) { return _mm256_cmp_ps(a, b, _CMP_LE_OQ ); }
|
||||
__forceinline vboolf8 operator ==(const vfloat8& a, const vfloat8& b) { return _mm256_cmp_ps(a, b, _CMP_EQ_OQ); }
|
||||
__forceinline vboolf8 operator !=(const vfloat8& a, const vfloat8& b) { return _mm256_cmp_ps(a, b, _CMP_NEQ_OQ); }
|
||||
__forceinline vboolf8 operator < (const vfloat8& a, const vfloat8& b) { return _mm256_cmp_ps(a, b, _CMP_LT_OQ); }
|
||||
__forceinline vboolf8 operator >=(const vfloat8& a, const vfloat8& b) { return _mm256_cmp_ps(a, b, _CMP_GE_OQ); }
|
||||
__forceinline vboolf8 operator > (const vfloat8& a, const vfloat8& b) { return _mm256_cmp_ps(a, b, _CMP_GT_OQ); }
|
||||
__forceinline vboolf8 operator <=(const vfloat8& a, const vfloat8& b) { return _mm256_cmp_ps(a, b, _CMP_LE_OQ); }
|
||||
|
||||
__forceinline const vfloat8 select( const vboolf8& m, const vfloat8& t, const vfloat8& f ) {
|
||||
__forceinline vfloat8 select(const vboolf8& m, const vfloat8& t, const vfloat8& f) {
|
||||
return _mm256_blendv_ps(f, t, m);
|
||||
}
|
||||
#endif
|
||||
|
||||
template<int mask>
|
||||
__forceinline const vfloat8 select( const vfloat8& t, const vfloat8& f ) {
|
||||
__forceinline vfloat8 select(const vfloat8& t, const vfloat8& f) {
|
||||
return _mm256_blend_ps(f, t, mask);
|
||||
}
|
||||
|
||||
__forceinline const vboolf8 operator ==( const vfloat8& a, const float& b ) { return a == vfloat8(b); }
|
||||
__forceinline const vboolf8 operator ==( const float& a, const vfloat8& b ) { return vfloat8(a) == b; }
|
||||
__forceinline vboolf8 operator ==(const vfloat8& a, const float& b) { return a == vfloat8(b); }
|
||||
__forceinline vboolf8 operator ==(const float& a, const vfloat8& b) { return vfloat8(a) == b; }
|
||||
|
||||
__forceinline const vboolf8 operator !=( const vfloat8& a, const float& b ) { return a != vfloat8(b); }
|
||||
__forceinline const vboolf8 operator !=( const float& a, const vfloat8& b ) { return vfloat8(a) != b; }
|
||||
__forceinline vboolf8 operator !=(const vfloat8& a, const float& b) { return a != vfloat8(b); }
|
||||
__forceinline vboolf8 operator !=(const float& a, const vfloat8& b) { return vfloat8(a) != b; }
|
||||
|
||||
__forceinline const vboolf8 operator < ( const vfloat8& a, const float& b ) { return a < vfloat8(b); }
|
||||
__forceinline const vboolf8 operator < ( const float& a, const vfloat8& b ) { return vfloat8(a) < b; }
|
||||
__forceinline vboolf8 operator < (const vfloat8& a, const float& b) { return a < vfloat8(b); }
|
||||
__forceinline vboolf8 operator < (const float& a, const vfloat8& b) { return vfloat8(a) < b; }
|
||||
|
||||
__forceinline const vboolf8 operator >=( const vfloat8& a, const float& b ) { return a >= vfloat8(b); }
|
||||
__forceinline const vboolf8 operator >=( const float& a, const vfloat8& b ) { return vfloat8(a) >= b; }
|
||||
__forceinline vboolf8 operator >=(const vfloat8& a, const float& b) { return a >= vfloat8(b); }
|
||||
__forceinline vboolf8 operator >=(const float& a, const vfloat8& b) { return vfloat8(a) >= b; }
|
||||
|
||||
__forceinline const vboolf8 operator > ( const vfloat8& a, const float& b ) { return a > vfloat8(b); }
|
||||
__forceinline const vboolf8 operator > ( const float& a, const vfloat8& b ) { return vfloat8(a) > b; }
|
||||
__forceinline vboolf8 operator > (const vfloat8& a, const float& b) { return a > vfloat8(b); }
|
||||
__forceinline vboolf8 operator > (const float& a, const vfloat8& b) { return vfloat8(a) > b; }
|
||||
|
||||
__forceinline const vboolf8 operator <=( const vfloat8& a, const float& b ) { return a <= vfloat8(b); }
|
||||
__forceinline const vboolf8 operator <=( const float& a, const vfloat8& b ) { return vfloat8(a) <= b; }
|
||||
__forceinline vboolf8 operator <=(const vfloat8& a, const float& b) { return a <= vfloat8(b); }
|
||||
__forceinline vboolf8 operator <=(const float& a, const vfloat8& b) { return vfloat8(a) <= b; }
|
||||
|
||||
__forceinline vboolf8 eq(const vfloat8& a, const vfloat8& b) { return a == b; }
|
||||
__forceinline vboolf8 ne(const vfloat8& a, const vfloat8& b) { return a != b; }
|
||||
@@ -389,15 +458,15 @@ namespace embree
|
||||
return madd(t,b-a,a);
|
||||
}
|
||||
|
||||
__forceinline bool isvalid ( const vfloat8& v ) {
|
||||
__forceinline bool isvalid (const vfloat8& v) {
|
||||
return all((v > vfloat8(-FLT_LARGE)) & (v < vfloat8(+FLT_LARGE)));
|
||||
}
|
||||
|
||||
__forceinline bool is_finite ( const vfloat8& a ) {
|
||||
__forceinline bool is_finite (const vfloat8& a) {
|
||||
return all((a >= vfloat8(-FLT_MAX)) & (a <= vfloat8(+FLT_MAX)));
|
||||
}
|
||||
|
||||
__forceinline bool is_finite ( const vboolf8& valid, const vfloat8& a ) {
|
||||
__forceinline bool is_finite (const vboolf8& valid, const vfloat8& a) {
|
||||
return all(valid, (a >= vfloat8(-FLT_MAX)) & (a <= vfloat8(+FLT_MAX)));
|
||||
}
|
||||
|
||||
@@ -405,98 +474,104 @@ namespace embree
|
||||
/// Rounding Functions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vfloat8 floor( const vfloat8& a ) { return _mm256_round_ps(a, _MM_FROUND_TO_NEG_INF ); }
|
||||
__forceinline const vfloat8 ceil ( const vfloat8& a ) { return _mm256_round_ps(a, _MM_FROUND_TO_POS_INF ); }
|
||||
__forceinline const vfloat8 trunc( const vfloat8& a ) { return _mm256_round_ps(a, _MM_FROUND_TO_ZERO ); }
|
||||
__forceinline const vfloat8 frac ( const vfloat8& a ) { return a-floor(a); }
|
||||
__forceinline vfloat8 floor(const vfloat8& a) { return _mm256_round_ps(a, _MM_FROUND_TO_NEG_INF ); }
|
||||
__forceinline vfloat8 ceil (const vfloat8& a) { return _mm256_round_ps(a, _MM_FROUND_TO_POS_INF ); }
|
||||
__forceinline vfloat8 trunc(const vfloat8& a) { return _mm256_round_ps(a, _MM_FROUND_TO_ZERO ); }
|
||||
__forceinline vfloat8 frac (const vfloat8& a) { return a-floor(a); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Movement/Shifting/Shuffling Functions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vfloat8 unpacklo( const vfloat8& a, const vfloat8& b ) { return _mm256_unpacklo_ps(a.v, b.v); }
|
||||
__forceinline vfloat8 unpackhi( const vfloat8& a, const vfloat8& b ) { return _mm256_unpackhi_ps(a.v, b.v); }
|
||||
__forceinline vfloat8 unpacklo(const vfloat8& a, const vfloat8& b) { return _mm256_unpacklo_ps(a, b); }
|
||||
__forceinline vfloat8 unpackhi(const vfloat8& a, const vfloat8& b) { return _mm256_unpackhi_ps(a, b); }
|
||||
|
||||
template<size_t i> __forceinline const vfloat8 shuffle( const vfloat8& a ) {
|
||||
return _mm256_permute_ps(a, _MM_SHUFFLE(i, i, i, i));
|
||||
template<int i>
|
||||
__forceinline vfloat8 shuffle(const vfloat8& v) {
|
||||
return _mm256_permute_ps(v, _MM_SHUFFLE(i, i, i, i));
|
||||
}
|
||||
|
||||
template<size_t i0, size_t i1> __forceinline const vfloat8 shuffle4( const vfloat8& a ) {
|
||||
return _mm256_permute2f128_ps(a, a, (i1 << 4) | (i0 << 0));
|
||||
template<int i0, int i1>
|
||||
__forceinline vfloat8 shuffle4(const vfloat8& v) {
|
||||
return _mm256_permute2f128_ps(v, v, (i1 << 4) | (i0 << 0));
|
||||
}
|
||||
|
||||
template<size_t i0, size_t i1> __forceinline const vfloat8 shuffle4( const vfloat8& a, const vfloat8& b) {
|
||||
template<int i0, int i1>
|
||||
__forceinline vfloat8 shuffle4(const vfloat8& a, const vfloat8& b) {
|
||||
return _mm256_permute2f128_ps(a, b, (i1 << 4) | (i0 << 0));
|
||||
}
|
||||
|
||||
template<size_t i0, size_t i1, size_t i2, size_t i3> __forceinline const vfloat8 shuffle( const vfloat8& a ) {
|
||||
return _mm256_permute_ps(a, _MM_SHUFFLE(i3, i2, i1, i0));
|
||||
template<int i0, int i1, int i2, int i3>
|
||||
__forceinline vfloat8 shuffle(const vfloat8& v) {
|
||||
return _mm256_permute_ps(v, _MM_SHUFFLE(i3, i2, i1, i0));
|
||||
}
|
||||
|
||||
template<size_t i0, size_t i1, size_t i2, size_t i3> __forceinline const vfloat8 shuffle( const vfloat8& a, const vfloat8& b ) {
|
||||
template<int i0, int i1, int i2, int i3>
|
||||
__forceinline vfloat8 shuffle(const vfloat8& a, const vfloat8& b) {
|
||||
return _mm256_shuffle_ps(a, b, _MM_SHUFFLE(i3, i2, i1, i0));
|
||||
}
|
||||
|
||||
template<> __forceinline const vfloat8 shuffle<0, 0, 2, 2>( const vfloat8& b ) { return _mm256_moveldup_ps(b); }
|
||||
template<> __forceinline const vfloat8 shuffle<1, 1, 3, 3>( const vfloat8& b ) { return _mm256_movehdup_ps(b); }
|
||||
template<> __forceinline const vfloat8 shuffle<0, 1, 0, 1>( const vfloat8& b ) { return _mm256_castpd_ps(_mm256_movedup_pd(_mm256_castps_pd(b))); }
|
||||
template<> __forceinline vfloat8 shuffle<0, 0, 2, 2>(const vfloat8& v) { return _mm256_moveldup_ps(v); }
|
||||
template<> __forceinline vfloat8 shuffle<1, 1, 3, 3>(const vfloat8& v) { return _mm256_movehdup_ps(v); }
|
||||
template<> __forceinline vfloat8 shuffle<0, 1, 0, 1>(const vfloat8& v) { return _mm256_castpd_ps(_mm256_movedup_pd(_mm256_castps_pd(v))); }
|
||||
|
||||
__forceinline const vfloat8 broadcast(const float* ptr) { return _mm256_broadcast_ss(ptr); }
|
||||
template<size_t i> __forceinline const vfloat8 insert4(const vfloat8& a, const vfloat4& b) { return _mm256_insertf128_ps(a, b, i); }
|
||||
template<size_t i> __forceinline const vfloat4 extract4 (const vfloat8& a) { return _mm256_extractf128_ps(a, i); }
|
||||
template<> __forceinline const vfloat4 extract4<0>(const vfloat8& a) { return _mm256_castps256_ps128(a); }
|
||||
__forceinline vfloat8 broadcast(const float* ptr) { return _mm256_broadcast_ss(ptr); }
|
||||
template<size_t i> __forceinline vfloat8 insert4(const vfloat8& a, const vfloat4& b) { return _mm256_insertf128_ps(a, b, i); }
|
||||
template<size_t i> __forceinline vfloat4 extract4 (const vfloat8& a) { return _mm256_extractf128_ps(a, i); }
|
||||
template<> __forceinline vfloat4 extract4<0>(const vfloat8& a) { return _mm256_castps256_ps128(a); }
|
||||
|
||||
__forceinline float toScalar(const vfloat8& a) { return _mm_cvtss_f32(_mm256_castps256_ps128(a)); }
|
||||
__forceinline float toScalar(const vfloat8& v) { return _mm_cvtss_f32(_mm256_castps256_ps128(v)); }
|
||||
|
||||
__forceinline vfloat8 assign( const vfloat4& a ) { return _mm256_castps128_ps256(a); }
|
||||
__forceinline vfloat8 assign(const vfloat4& a) { return _mm256_castps128_ps256(a); }
|
||||
|
||||
#if defined (__AVX2__)
|
||||
__forceinline vfloat8 permute(const vfloat8 &a, const __m256i &index) {
|
||||
return _mm256_permutevar8x32_ps(a,index);
|
||||
__forceinline vfloat8 permute(const vfloat8& a, const __m256i& index) {
|
||||
return _mm256_permutevar8x32_ps(a, index);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__AVX512VL__)
|
||||
template<int i>
|
||||
__forceinline vfloat8 align_shift_right(const vfloat8 &a, const vfloat8 &b) {
|
||||
__forceinline vfloat8 align_shift_right(const vfloat8& a, const vfloat8& b) {
|
||||
return _mm256_castsi256_ps(_mm256_alignr_epi32(_mm256_castps_si256(a), _mm256_castps_si256(b), i));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined (__AVX_I__)
|
||||
template<const int mode>
|
||||
__forceinline vint4 convert_to_hf16(const vfloat8 &a) {
|
||||
return _mm256_cvtps_ph(a,mode);
|
||||
__forceinline vint4 convert_to_hf16(const vfloat8& a) {
|
||||
return _mm256_cvtps_ph(a, mode);
|
||||
}
|
||||
|
||||
__forceinline vfloat8 convert_from_hf16(const vint4 &a) {
|
||||
__forceinline vfloat8 convert_from_hf16(const vint4& a) {
|
||||
return _mm256_cvtph_ps(a);
|
||||
}
|
||||
#endif
|
||||
|
||||
__forceinline vfloat4 broadcast4f( const vfloat8& a, const size_t k ) {
|
||||
__forceinline vfloat4 broadcast4f(const vfloat8& a, const size_t k) {
|
||||
return vfloat4::broadcast(&a[k]);
|
||||
}
|
||||
|
||||
__forceinline vfloat8 broadcast8f( const vfloat8& a, const size_t k ) {
|
||||
__forceinline vfloat8 broadcast8f(const vfloat8& a, const size_t k) {
|
||||
return vfloat8::broadcast(&a[k]);
|
||||
}
|
||||
|
||||
#if defined(__AVX512VL__)
|
||||
__forceinline vfloat8 shift_right_1( const vfloat8& x) {
|
||||
__forceinline vfloat8 shift_right_1(const vfloat8& x) {
|
||||
return align_shift_right<1>(zero,x);
|
||||
}
|
||||
#else
|
||||
__forceinline vfloat8 shift_right_1( const vfloat8& x) {
|
||||
__forceinline vfloat8 shift_right_1(const vfloat8& x) {
|
||||
const vfloat8 t0 = shuffle<1,2,3,0>(x);
|
||||
const vfloat8 t1 = shuffle4<1,0>(t0);
|
||||
return _mm256_blend_ps(t0,t1,0x88);
|
||||
}
|
||||
#endif
|
||||
|
||||
__forceinline vint8 floori (const vfloat8& a) {
|
||||
__forceinline vint8 floori(const vfloat8& a) {
|
||||
return vint8(floor(a));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Transpose
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -539,6 +614,12 @@ namespace embree
|
||||
c7 = shuffle4<1,3>(h3,h7);
|
||||
}
|
||||
|
||||
__forceinline void transpose(const vfloat4& r0, const vfloat4& r1, const vfloat4& r2, const vfloat4& r3, const vfloat4& r4, const vfloat4& r5, const vfloat4& r6, const vfloat4& r7,
|
||||
vfloat8& c0, vfloat8& c1, vfloat8& c2, vfloat8& c3)
|
||||
{
|
||||
transpose(vfloat8(r0,r4), vfloat8(r1,r5), vfloat8(r2,r6), vfloat8(r3,r7), c0, c1, c2, c3);
|
||||
}
|
||||
|
||||
__forceinline void transpose(const vfloat4& r0, const vfloat4& r1, const vfloat4& r2, const vfloat4& r3, const vfloat4& r4, const vfloat4& r5, const vfloat4& r6, const vfloat4& r7,
|
||||
vfloat8& c0, vfloat8& c1, vfloat8& c2)
|
||||
{
|
||||
@@ -549,17 +630,17 @@ namespace embree
|
||||
/// Reductions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vfloat8 vreduce_min2(const vfloat8& v) { return min(v,shuffle<1,0,3,2>(v)); }
|
||||
__forceinline const vfloat8 vreduce_min4(const vfloat8& v) { vfloat8 v1 = vreduce_min2(v); return min(v1,shuffle<2,3,0,1>(v1)); }
|
||||
__forceinline const vfloat8 vreduce_min (const vfloat8& v) { vfloat8 v1 = vreduce_min4(v); return min(v1,shuffle4<1,0>(v1)); }
|
||||
__forceinline vfloat8 vreduce_min2(const vfloat8& v) { return min(v,shuffle<1,0,3,2>(v)); }
|
||||
__forceinline vfloat8 vreduce_min4(const vfloat8& v) { vfloat8 v1 = vreduce_min2(v); return min(v1,shuffle<2,3,0,1>(v1)); }
|
||||
__forceinline vfloat8 vreduce_min (const vfloat8& v) { vfloat8 v1 = vreduce_min4(v); return min(v1,shuffle4<1,0>(v1)); }
|
||||
|
||||
__forceinline const vfloat8 vreduce_max2(const vfloat8& v) { return max(v,shuffle<1,0,3,2>(v)); }
|
||||
__forceinline const vfloat8 vreduce_max4(const vfloat8& v) { vfloat8 v1 = vreduce_max2(v); return max(v1,shuffle<2,3,0,1>(v1)); }
|
||||
__forceinline const vfloat8 vreduce_max (const vfloat8& v) { vfloat8 v1 = vreduce_max4(v); return max(v1,shuffle4<1,0>(v1)); }
|
||||
__forceinline vfloat8 vreduce_max2(const vfloat8& v) { return max(v,shuffle<1,0,3,2>(v)); }
|
||||
__forceinline vfloat8 vreduce_max4(const vfloat8& v) { vfloat8 v1 = vreduce_max2(v); return max(v1,shuffle<2,3,0,1>(v1)); }
|
||||
__forceinline vfloat8 vreduce_max (const vfloat8& v) { vfloat8 v1 = vreduce_max4(v); return max(v1,shuffle4<1,0>(v1)); }
|
||||
|
||||
__forceinline const vfloat8 vreduce_add2(const vfloat8& v) { return v + shuffle<1,0,3,2>(v); }
|
||||
__forceinline const vfloat8 vreduce_add4(const vfloat8& v) { vfloat8 v1 = vreduce_add2(v); return v1 + shuffle<2,3,0,1>(v1); }
|
||||
__forceinline const vfloat8 vreduce_add (const vfloat8& v) { vfloat8 v1 = vreduce_add4(v); return v1 + shuffle4<1,0>(v1); }
|
||||
__forceinline vfloat8 vreduce_add2(const vfloat8& v) { return v + shuffle<1,0,3,2>(v); }
|
||||
__forceinline vfloat8 vreduce_add4(const vfloat8& v) { vfloat8 v1 = vreduce_add2(v); return v1 + shuffle<2,3,0,1>(v1); }
|
||||
__forceinline vfloat8 vreduce_add (const vfloat8& v) { vfloat8 v1 = vreduce_add4(v); return v1 + shuffle4<1,0>(v1); }
|
||||
|
||||
__forceinline float reduce_min(const vfloat8& v) { return toScalar(vreduce_min(v)); }
|
||||
__forceinline float reduce_max(const vfloat8& v) { return toScalar(vreduce_max(v)); }
|
||||
@@ -584,15 +665,15 @@ namespace embree
|
||||
/// Euclidian Space Operators (pairs of Vec3fa's)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//__forceinline vfloat8 dot ( const vfloat8& a, const vfloat8& b ) {
|
||||
//__forceinline vfloat8 dot(const vfloat8& a, const vfloat8& b) {
|
||||
// return vreduce_add4(a*b);
|
||||
//}
|
||||
|
||||
__forceinline vfloat8 dot ( const vfloat8& a, const vfloat8& b ) {
|
||||
__forceinline vfloat8 dot(const vfloat8& a, const vfloat8& b) {
|
||||
return _mm256_dp_ps(a,b,0x7F);
|
||||
}
|
||||
|
||||
__forceinline vfloat8 cross ( const vfloat8& a, const vfloat8& b )
|
||||
__forceinline vfloat8 cross(const vfloat8& a, const vfloat8& b)
|
||||
{
|
||||
const vfloat8 a0 = a;
|
||||
const vfloat8 b0 = shuffle<1,2,0,3>(b);
|
||||
@@ -601,17 +682,17 @@ namespace embree
|
||||
return shuffle<1,2,0,3>(msub(a0,b0,a1*b1));
|
||||
}
|
||||
|
||||
//__forceinline float sqr_length ( const vfloat<8>& a ) { return dot(a,a); }
|
||||
//__forceinline float rcp_length ( const vfloat<8>& a ) { return rsqrt(dot(a,a)); }
|
||||
//__forceinline float rcp_length2( const vfloat<8>& a ) { return rcp(dot(a,a)); }
|
||||
//__forceinline float length ( const vfloat<8>& a ) { return sqrt(dot(a,a)); }
|
||||
__forceinline vfloat<8> normalize( const vfloat<8>& a ) { return a*rsqrt(dot(a,a)); }
|
||||
//__forceinline float distance ( const vfloat<8>& a, const vfloat<8>& b ) { return length(a-b); }
|
||||
//__forceinline float halfArea ( const vfloat<8>& d ) { return madd(d.x,(d.y+d.z),d.y*d.z); }
|
||||
//__forceinline float area ( const vfloat<8>& d ) { return 2.0f*halfArea(d); }
|
||||
//__forceinline vfloat<8> reflect ( const vfloat<8>& V, const vfloat<8>& N ) { return 2.0f*dot(V,N)*N-V; }
|
||||
//__forceinline float sqr_length (const vfloat<8>& a) { return dot(a,a); }
|
||||
//__forceinline float rcp_length (const vfloat<8>& a) { return rsqrt(dot(a,a)); }
|
||||
//__forceinline float rcp_length2(const vfloat<8>& a) { return rcp(dot(a,a)); }
|
||||
//__forceinline float length (const vfloat<8>& a) { return sqrt(dot(a,a)); }
|
||||
__forceinline vfloat<8> normalize(const vfloat<8>& a) { return a*rsqrt(dot(a,a)); }
|
||||
//__forceinline float distance(const vfloat<8>& a, const vfloat<8>& b) { return length(a-b); }
|
||||
//__forceinline float halfArea(const vfloat<8>& d) { return madd(d.x,(d.y+d.z),d.y*d.z); }
|
||||
//__forceinline float area (const vfloat<8>& d) { return 2.0f*halfArea(d); }
|
||||
//__forceinline vfloat<8> reflect(const vfloat<8>& V, const vfloat<8>& N) { return 2.0f*dot(V,N)*N-V; }
|
||||
|
||||
//__forceinline vfloat<8> normalize_safe( const vfloat<8>& a ) {
|
||||
//__forceinline vfloat<8> normalize_safe(const vfloat<8>& a) {
|
||||
// const float d = dot(a,a); if (unlikely(d == 0.0f)) return a; else return a*rsqrt(d);
|
||||
//}
|
||||
|
||||
@@ -683,7 +764,7 @@ namespace embree
|
||||
/// Output Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& cout, const vfloat8& a) {
|
||||
inline std::ostream& operator <<(std::ostream& cout, const vfloat8& a) {
|
||||
return cout << "<" << a[0] << ", " << a[1] << ", " << a[2] << ", " << a[3] << ", " << a[4] << ", " << a[5] << ", " << a[6] << ", " << a[7] << ">";
|
||||
}
|
||||
}
|
||||
+164
-155
@@ -38,24 +38,24 @@ namespace embree
|
||||
|
||||
__forceinline vint() {}
|
||||
__forceinline vint(const vint16& t) { v = t.v; }
|
||||
__forceinline vint16& operator=(const vint16& f) { v = f.v; return *this; }
|
||||
__forceinline vint16& operator =(const vint16& f) { v = f.v; return *this; }
|
||||
|
||||
__forceinline vint(const __m512i& t) { v = t; }
|
||||
__forceinline operator __m512i () const { return v; }
|
||||
__forceinline operator __m256i () const { return _mm512_castsi512_si256(v); }
|
||||
__forceinline operator __m512i() const { return v; }
|
||||
__forceinline operator __m256i() const { return _mm512_castsi512_si256(v); }
|
||||
|
||||
__forceinline vint(const int i) {
|
||||
__forceinline vint(int i) {
|
||||
v = _mm512_set1_epi32(i);
|
||||
}
|
||||
|
||||
__forceinline vint(const int a, const int b, const int c, const int d) {
|
||||
__forceinline vint(int a, int b, int c, int d) {
|
||||
v = _mm512_set4_epi32(d,c,b,a);
|
||||
}
|
||||
|
||||
__forceinline vint(const int a0 , const int a1 , const int a2 , const int a3,
|
||||
const int a4 , const int a5 , const int a6 , const int a7,
|
||||
const int a8 , const int a9 , const int a10, const int a11,
|
||||
const int a12, const int a13, const int a14, const int a15)
|
||||
__forceinline vint(int a0 , int a1 , int a2 , int a3,
|
||||
int a4 , int a5 , int a6 , int a7,
|
||||
int a8 , int a9 , int a10, int a11,
|
||||
int a12, int a13, int a14, int a15)
|
||||
{
|
||||
v = _mm512_set_epi32(a15,a14,a13,a12,a11,a10,a9,a8,a7,a6,a5,a4,a3,a2,a1,a0);
|
||||
}
|
||||
@@ -64,9 +64,21 @@ namespace embree
|
||||
v = _mm512_broadcast_i32x4(i);
|
||||
}
|
||||
|
||||
__forceinline vint(const vint4& a, const vint4& b, const vint4& c, const vint4& d) {
|
||||
v = _mm512_castsi128_si512(a);
|
||||
v = _mm512_inserti32x4(v, b, 1);
|
||||
v = _mm512_inserti32x4(v, c, 2);
|
||||
v = _mm512_inserti32x4(v, d, 3);
|
||||
}
|
||||
|
||||
__forceinline vint(const vint8& i) {
|
||||
v = _mm512_castps_si512(_mm512_castpd_ps(_mm512_broadcast_f64x4(_mm256_castsi256_pd(i))));
|
||||
}
|
||||
|
||||
__forceinline vint(const vint8& a, const vint8& b) {
|
||||
v = _mm512_castsi256_si512(a);
|
||||
v = _mm512_inserti64x4(v, b, 1);
|
||||
}
|
||||
|
||||
__forceinline explicit vint(const __m512& f) {
|
||||
v = _mm512_cvtps_epi32(f);
|
||||
@@ -76,17 +88,12 @@ namespace embree
|
||||
/// Constants
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vint( ZeroTy ) : v(_mm512_setzero_epi32()) {}
|
||||
__forceinline vint( OneTy ) : v(_mm512_set1_epi32(1)) {}
|
||||
__forceinline vint( PosInfTy ) : v(_mm512_set1_epi32(pos_inf)) {}
|
||||
__forceinline vint( NegInfTy ) : v(_mm512_set1_epi32(neg_inf)) {}
|
||||
__forceinline vint( StepTy ) : v(_mm512_set_epi32(15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0)) {}
|
||||
|
||||
__forceinline vint( ReverseStepTy ) : v(_mm512_setr_epi32(15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0)) {}
|
||||
|
||||
__forceinline static vint16 zero() { return _mm512_setzero_epi32(); }
|
||||
__forceinline static vint16 one () { return _mm512_set1_epi32(1); }
|
||||
__forceinline static vint16 neg_one () { return _mm512_set1_epi32(-1); }
|
||||
__forceinline vint(ZeroTy) : v(_mm512_setzero_epi32()) {}
|
||||
__forceinline vint(OneTy) : v(_mm512_set1_epi32(1)) {}
|
||||
__forceinline vint(PosInfTy) : v(_mm512_set1_epi32(pos_inf)) {}
|
||||
__forceinline vint(NegInfTy) : v(_mm512_set1_epi32(neg_inf)) {}
|
||||
__forceinline vint(StepTy) : v(_mm512_set_epi32(15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0)) {}
|
||||
__forceinline vint(ReverseStepTy) : v(_mm512_setr_epi32(15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0)) {}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Loads and Stores
|
||||
@@ -94,8 +101,8 @@ namespace embree
|
||||
|
||||
static __forceinline vint16 load (const void* addr) { return _mm512_load_si512((int*)addr); }
|
||||
|
||||
static __forceinline const vint16 load( const unsigned char* const ptr ) { return _mm512_cvtepu8_epi32(_mm_load_si128((__m128i*)ptr)); }
|
||||
static __forceinline const vint16 load( const unsigned short* const ptr ) { return _mm512_cvtepu16_epi32(*(__m256i*)ptr); }
|
||||
static __forceinline vint16 load(const unsigned char* ptr) { return _mm512_cvtepu8_epi32(_mm_load_si128((__m128i*)ptr)); }
|
||||
static __forceinline vint16 load(const unsigned short* ptr) { return _mm512_cvtepu16_epi32(*(__m256i*)ptr); }
|
||||
|
||||
static __forceinline vint16 loadu(const void* addr) { return _mm512_loadu_si512(addr); }
|
||||
|
||||
@@ -106,16 +113,16 @@ namespace embree
|
||||
static __forceinline void storeu(void* ptr, const vint16& v) { _mm512_storeu_si512(ptr,v); }
|
||||
|
||||
static __forceinline void store (const vboolf16& mask, void* addr, const vint16& v2) { _mm512_mask_store_epi32(addr,mask,v2); }
|
||||
static __forceinline void storeu(const vboolf16& mask, void* ptr, const vint16& f ) { _mm512_mask_storeu_epi32((int*)ptr,mask,f); }
|
||||
static __forceinline void storeu(const vboolf16& mask, void* ptr, const vint16& f) { _mm512_mask_storeu_epi32((int*)ptr,mask,f); }
|
||||
|
||||
static __forceinline void store_nt(void *__restrict__ ptr, const vint16& a) { _mm512_stream_si512((__m512i*)ptr,a); }
|
||||
static __forceinline void store_nt(void* __restrict__ ptr, const vint16& a) { _mm512_stream_si512((__m512i*)ptr,a); }
|
||||
|
||||
/* pass by value to avoid compiler generating inefficient code */
|
||||
static __forceinline void storeu_compact(const vboolf16 mask,void * addr, const vint16 reg) {
|
||||
static __forceinline void storeu_compact(const vboolf16 mask, void* addr, vint16 reg) {
|
||||
_mm512_mask_compressstoreu_epi32(addr,mask,reg);
|
||||
}
|
||||
|
||||
static __forceinline void storeu_compact_single(const vboolf16 mask,void * addr, const vint16 reg) {
|
||||
static __forceinline void storeu_compact_single(const vboolf16 mask, void* addr, vint16 reg) {
|
||||
//_mm512_mask_compressstoreu_epi32(addr,mask,reg);
|
||||
*(float*)addr = mm512_cvtss_f32(_mm512_mask_compress_ps(_mm512_castsi512_ps(reg),mask,_mm512_castsi512_ps(reg)));
|
||||
}
|
||||
@@ -136,135 +143,159 @@ namespace embree
|
||||
return _mm512_mask_expand_epi32(b,mask,a);
|
||||
}
|
||||
|
||||
template<int scale = 4>
|
||||
static __forceinline vint16 gather(const int* ptr, const vint16& index) {
|
||||
return _mm512_i32gather_epi32(index,ptr,scale);
|
||||
}
|
||||
|
||||
template<int scale = 4>
|
||||
static __forceinline vint16 gather(const vboolf16& mask, const int* ptr, const vint16& index) {
|
||||
return _mm512_mask_i32gather_epi32(_mm512_undefined_epi32(),mask,index,ptr,scale);
|
||||
}
|
||||
|
||||
template<int scale = 4>
|
||||
static __forceinline vint16 gather(const vboolf16& mask, vint16& dest, const int* ptr, const vint16& index) {
|
||||
return _mm512_mask_i32gather_epi32(dest,mask,index,ptr,scale);
|
||||
}
|
||||
|
||||
template<int scale = 4>
|
||||
static __forceinline void scatter(int* ptr, const vint16& index, const vint16& v) {
|
||||
_mm512_i32scatter_epi32((int*)ptr,index,v,scale);
|
||||
}
|
||||
|
||||
template<int scale = 4>
|
||||
static __forceinline void scatter(const vboolf16& mask, int* ptr, const vint16& index, const vint16& v) {
|
||||
_mm512_mask_i32scatter_epi32((int*)ptr,mask,index,v,scale);
|
||||
}
|
||||
|
||||
static __forceinline vint16 broadcast64bit(size_t v) {
|
||||
return _mm512_set1_epi64(v);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Array Access
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline int& operator[](const size_t index) { assert(index < 16); return i[index]; }
|
||||
__forceinline const int& operator[](const size_t index) const { assert(index < 16); return i[index]; }
|
||||
__forceinline int& operator [](size_t index) { assert(index < 16); return i[index]; }
|
||||
__forceinline const int& operator [](size_t index) const { assert(index < 16); return i[index]; }
|
||||
|
||||
__forceinline unsigned int uint (const size_t index) const { assert(index < 16); return ((unsigned int*)i)[index]; }
|
||||
__forceinline size_t& uint64_t(const size_t index) const { assert(index < 8); return ((size_t*)i)[index]; }
|
||||
__forceinline unsigned int uint (size_t index) const { assert(index < 16); return ((unsigned int*)i)[index]; }
|
||||
__forceinline size_t& uint64_t(size_t index) const { assert(index < 8); return ((size_t*)i)[index]; }
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Unary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vint16 asInt ( const __m512& a ) { return _mm512_castps_si512(a); }
|
||||
__forceinline const vint16 operator +( const vint16& a ) { return a; }
|
||||
__forceinline const vint16 operator -( const vint16& a ) { return _mm512_sub_epi32(_mm512_setzero_epi32(), a); }
|
||||
__forceinline vint16 asInt (const __m512& a) { return _mm512_castps_si512(a); }
|
||||
__forceinline vint16 operator +(const vint16& a) { return a; }
|
||||
__forceinline vint16 operator -(const vint16& a) { return _mm512_sub_epi32(_mm512_setzero_epi32(), a); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Binary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vint16 operator +( const vint16& a, const vint16& b ) { return _mm512_add_epi32(a, b); }
|
||||
__forceinline const vint16 operator +( const vint16& a, const int b ) { return a + vint16(b); }
|
||||
__forceinline const vint16 operator +( const int a, const vint16& b ) { return vint16(a) + b; }
|
||||
__forceinline vint16 operator +(const vint16& a, const vint16& b) { return _mm512_add_epi32(a, b); }
|
||||
__forceinline vint16 operator +(const vint16& a, int b) { return a + vint16(b); }
|
||||
__forceinline vint16 operator +(int a, const vint16& b) { return vint16(a) + b; }
|
||||
|
||||
__forceinline const vint16 operator -( const vint16& a, const vint16& b ) { return _mm512_sub_epi32(a, b); }
|
||||
__forceinline const vint16 operator -( const vint16& a, const int b ) { return a - vint16(b); }
|
||||
__forceinline const vint16 operator -( const int a, const vint16& b ) { return vint16(a) - b; }
|
||||
__forceinline vint16 operator -(const vint16& a, const vint16& b) { return _mm512_sub_epi32(a, b); }
|
||||
__forceinline vint16 operator -(const vint16& a, int b) { return a - vint16(b); }
|
||||
__forceinline vint16 operator -(int a, const vint16& b) { return vint16(a) - b; }
|
||||
|
||||
__forceinline const vint16 operator *( const vint16& a, const vint16& b ) { return _mm512_mullo_epi32(a, b); }
|
||||
__forceinline const vint16 operator *( const vint16& a, const int b ) { return a * vint16(b); }
|
||||
__forceinline const vint16 operator *( const int a, const vint16& b ) { return vint16(a) * b; }
|
||||
__forceinline vint16 operator *(const vint16& a, const vint16& b) { return _mm512_mullo_epi32(a, b); }
|
||||
__forceinline vint16 operator *(const vint16& a, int b) { return a * vint16(b); }
|
||||
__forceinline vint16 operator *(int a, const vint16& b) { return vint16(a) * b; }
|
||||
|
||||
__forceinline const vint16 operator &( const vint16& a, const vint16& b ) { return _mm512_and_epi32(a, b); }
|
||||
__forceinline const vint16 operator &( const vint16& a, const int b ) { return a & vint16(b); }
|
||||
__forceinline const vint16 operator &( const int a, const vint16& b ) { return vint16(a) & b; }
|
||||
__forceinline vint16 operator &(const vint16& a, const vint16& b) { return _mm512_and_epi32(a, b); }
|
||||
__forceinline vint16 operator &(const vint16& a, int b) { return a & vint16(b); }
|
||||
__forceinline vint16 operator &(int a, const vint16& b) { return vint16(a) & b; }
|
||||
|
||||
__forceinline const vint16 operator |( const vint16& a, const vint16& b ) { return _mm512_or_epi32(a, b); }
|
||||
__forceinline const vint16 operator |( const vint16& a, const int b ) { return a | vint16(b); }
|
||||
__forceinline const vint16 operator |( const int a, const vint16& b ) { return vint16(a) | b; }
|
||||
__forceinline vint16 operator |(const vint16& a, const vint16& b) { return _mm512_or_epi32(a, b); }
|
||||
__forceinline vint16 operator |(const vint16& a, int b) { return a | vint16(b); }
|
||||
__forceinline vint16 operator |(int a, const vint16& b) { return vint16(a) | b; }
|
||||
|
||||
__forceinline const vint16 operator ^( const vint16& a, const vint16& b ) { return _mm512_xor_epi32(a, b); }
|
||||
__forceinline const vint16 operator ^( const vint16& a, const int b ) { return a ^ vint16(b); }
|
||||
__forceinline const vint16 operator ^( const int a, const vint16& b ) { return vint16(a) ^ b; }
|
||||
__forceinline vint16 operator ^(const vint16& a, const vint16& b) { return _mm512_xor_epi32(a, b); }
|
||||
__forceinline vint16 operator ^(const vint16& a, int b) { return a ^ vint16(b); }
|
||||
__forceinline vint16 operator ^(int a, const vint16& b) { return vint16(a) ^ b; }
|
||||
|
||||
__forceinline const vint16 operator <<( const vint16& a, const int n ) { return _mm512_slli_epi32(a, n); }
|
||||
__forceinline const vint16 operator >>( const vint16& a, const int n ) { return _mm512_srai_epi32(a, n); }
|
||||
__forceinline vint16 operator <<(const vint16& a, int n) { return _mm512_slli_epi32(a, n); }
|
||||
__forceinline vint16 operator >>(const vint16& a, int n) { return _mm512_srai_epi32(a, n); }
|
||||
|
||||
__forceinline const vint16 operator <<( const vint16& a, const vint16& n ) { return _mm512_sllv_epi32(a, n); }
|
||||
__forceinline const vint16 operator >>( const vint16& a, const vint16& n ) { return _mm512_srav_epi32(a, n); }
|
||||
__forceinline vint16 operator <<(const vint16& a, const vint16& n) { return _mm512_sllv_epi32(a, n); }
|
||||
__forceinline vint16 operator >>(const vint16& a, const vint16& n) { return _mm512_srav_epi32(a, n); }
|
||||
|
||||
__forceinline const vint16 sll ( const vint16& a, const int b ) { return _mm512_slli_epi32(a, b); }
|
||||
__forceinline const vint16 sra ( const vint16& a, const int b ) { return _mm512_srai_epi32(a, b); }
|
||||
__forceinline const vint16 srl ( const vint16& a, const int b ) { return _mm512_srli_epi32(a, b); }
|
||||
__forceinline vint16 sll (const vint16& a, int b) { return _mm512_slli_epi32(a, b); }
|
||||
__forceinline vint16 sra (const vint16& a, int b) { return _mm512_srai_epi32(a, b); }
|
||||
__forceinline vint16 srl (const vint16& a, int b) { return _mm512_srli_epi32(a, b); }
|
||||
|
||||
__forceinline const vint16 min( const vint16& a, const vint16& b ) { return _mm512_min_epi32(a, b); }
|
||||
__forceinline const vint16 min( const vint16& a, const int b ) { return min(a,vint16(b)); }
|
||||
__forceinline const vint16 min( const int a, const vint16& b ) { return min(vint16(a),b); }
|
||||
__forceinline vint16 min(const vint16& a, const vint16& b) { return _mm512_min_epi32(a, b); }
|
||||
__forceinline vint16 min(const vint16& a, int b) { return min(a,vint16(b)); }
|
||||
__forceinline vint16 min(int a, const vint16& b) { return min(vint16(a),b); }
|
||||
|
||||
__forceinline const vint16 max( const vint16& a, const vint16& b ) { return _mm512_max_epi32(a, b); }
|
||||
__forceinline const vint16 max( const vint16& a, const int b ) { return max(a,vint16(b)); }
|
||||
__forceinline const vint16 max( const int a, const vint16& b ) { return max(vint16(a),b); }
|
||||
__forceinline vint16 max(const vint16& a, const vint16& b) { return _mm512_max_epi32(a, b); }
|
||||
__forceinline vint16 max(const vint16& a, int b) { return max(a,vint16(b)); }
|
||||
__forceinline vint16 max(int a, const vint16& b) { return max(vint16(a),b); }
|
||||
|
||||
__forceinline const vint16 umin( const vint16& a, const vint16& b ) { return _mm512_min_epu32(a.v, b.v); }
|
||||
__forceinline const vint16 umax( const vint16& a, const vint16& b ) { return _mm512_max_epu32(a.v, b.v); }
|
||||
__forceinline vint16 umin(const vint16& a, const vint16& b) { return _mm512_min_epu32(a, b); }
|
||||
__forceinline vint16 umax(const vint16& a, const vint16& b) { return _mm512_max_epu32(a, b); }
|
||||
|
||||
__forceinline const vint16 mask_add(const vboolf16& mask, vint16& c, const vint16& a, const vint16& b) { return _mm512_mask_add_epi32(c,mask,a,b); }
|
||||
__forceinline const vint16 mask_sub(const vboolf16& mask, vint16& c, const vint16& a, const vint16& b) { return _mm512_mask_sub_epi32(c,mask,a,b); }
|
||||
__forceinline vint16 mask_add(const vboolf16& mask, vint16& c, const vint16& a, const vint16& b) { return _mm512_mask_add_epi32(c,mask,a,b); }
|
||||
__forceinline vint16 mask_sub(const vboolf16& mask, vint16& c, const vint16& a, const vint16& b) { return _mm512_mask_sub_epi32(c,mask,a,b); }
|
||||
|
||||
__forceinline const vint16 mask_and(const vboolf16& m,vint16& c, const vint16& a, const vint16& b) { return _mm512_mask_and_epi32(c,m,a,b); }
|
||||
__forceinline const vint16 mask_or (const vboolf16& m,vint16& c, const vint16& a, const vint16& b) { return _mm512_mask_or_epi32(c,m,a,b); }
|
||||
__forceinline vint16 mask_and(const vboolf16& m, vint16& c, const vint16& a, const vint16& b) { return _mm512_mask_and_epi32(c,m,a,b); }
|
||||
__forceinline vint16 mask_or (const vboolf16& m, vint16& c, const vint16& a, const vint16& b) { return _mm512_mask_or_epi32(c,m,a,b); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Assignment Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vint16& operator +=( vint16& a, const vint16& b ) { return a = a + b; }
|
||||
__forceinline vint16& operator +=( vint16& a, const int b ) { return a = a + b; }
|
||||
__forceinline vint16& operator +=(vint16& a, const vint16& b) { return a = a + b; }
|
||||
__forceinline vint16& operator +=(vint16& a, int b) { return a = a + b; }
|
||||
|
||||
__forceinline vint16& operator -=( vint16& a, const vint16& b ) { return a = a - b; }
|
||||
__forceinline vint16& operator -=( vint16& a, const int b ) { return a = a - b; }
|
||||
__forceinline vint16& operator -=(vint16& a, const vint16& b) { return a = a - b; }
|
||||
__forceinline vint16& operator -=(vint16& a, int b) { return a = a - b; }
|
||||
|
||||
__forceinline vint16& operator *=( vint16& a, const vint16& b ) { return a = a * b; }
|
||||
__forceinline vint16& operator *=( vint16& a, const int b ) { return a = a * b; }
|
||||
__forceinline vint16& operator *=(vint16& a, const vint16& b) { return a = a * b; }
|
||||
__forceinline vint16& operator *=(vint16& a, int b) { return a = a * b; }
|
||||
|
||||
__forceinline vint16& operator &=( vint16& a, const vint16& b ) { return a = a & b; }
|
||||
__forceinline vint16& operator &=( vint16& a, const int b ) { return a = a & b; }
|
||||
__forceinline vint16& operator &=(vint16& a, const vint16& b) { return a = a & b; }
|
||||
__forceinline vint16& operator &=(vint16& a, int b) { return a = a & b; }
|
||||
|
||||
__forceinline vint16& operator |=( vint16& a, const vint16& b ) { return a = a | b; }
|
||||
__forceinline vint16& operator |=( vint16& a, const int b ) { return a = a | b; }
|
||||
__forceinline vint16& operator |=(vint16& a, const vint16& b) { return a = a | b; }
|
||||
__forceinline vint16& operator |=(vint16& a, int b) { return a = a | b; }
|
||||
|
||||
__forceinline vint16& operator <<=( vint16& a, const int b ) { return a = a << b; }
|
||||
__forceinline vint16& operator >>=( vint16& a, const int b ) { return a = a >> b; }
|
||||
__forceinline vint16& operator <<=(vint16& a, int b) { return a = a << b; }
|
||||
__forceinline vint16& operator >>=(vint16& a, int b) { return a = a >> b; }
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Comparison Operators + Select
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vboolf16 operator ==( const vint16& a, const vint16& b ) { return _mm512_cmp_epi32_mask(a,b,_MM_CMPINT_EQ); }
|
||||
__forceinline const vboolf16 operator ==( const vint16& a, const int b ) { return a == vint16(b); }
|
||||
__forceinline const vboolf16 operator ==( const int a, const vint16& b ) { return vint16(a) == b; }
|
||||
__forceinline vboolf16 operator ==(const vint16& a, const vint16& b) { return _mm512_cmp_epi32_mask(a,b,_MM_CMPINT_EQ); }
|
||||
__forceinline vboolf16 operator ==(const vint16& a, int b) { return a == vint16(b); }
|
||||
__forceinline vboolf16 operator ==(int a, const vint16& b) { return vint16(a) == b; }
|
||||
|
||||
__forceinline const vboolf16 operator !=( const vint16& a, const vint16& b ) { return _mm512_cmp_epi32_mask(a,b,_MM_CMPINT_NE); }
|
||||
__forceinline const vboolf16 operator !=( const vint16& a, const int b ) { return a != vint16(b); }
|
||||
__forceinline const vboolf16 operator !=( const int a, const vint16& b ) { return vint16(a) != b; }
|
||||
__forceinline vboolf16 operator !=(const vint16& a, const vint16& b) { return _mm512_cmp_epi32_mask(a,b,_MM_CMPINT_NE); }
|
||||
__forceinline vboolf16 operator !=(const vint16& a, int b) { return a != vint16(b); }
|
||||
__forceinline vboolf16 operator !=(int a, const vint16& b) { return vint16(a) != b; }
|
||||
|
||||
__forceinline const vboolf16 operator < ( const vint16& a, const vint16& b ) { return _mm512_cmp_epi32_mask(a,b,_MM_CMPINT_LT); }
|
||||
__forceinline const vboolf16 operator < ( const vint16& a, const int b ) { return a < vint16(b); }
|
||||
__forceinline const vboolf16 operator < ( const int a, const vint16& b ) { return vint16(a) < b; }
|
||||
__forceinline vboolf16 operator < (const vint16& a, const vint16& b) { return _mm512_cmp_epi32_mask(a,b,_MM_CMPINT_LT); }
|
||||
__forceinline vboolf16 operator < (const vint16& a, int b) { return a < vint16(b); }
|
||||
__forceinline vboolf16 operator < (int a, const vint16& b) { return vint16(a) < b; }
|
||||
|
||||
__forceinline const vboolf16 operator >=( const vint16& a, const vint16& b ) { return _mm512_cmp_epi32_mask(a,b,_MM_CMPINT_GE); }
|
||||
__forceinline const vboolf16 operator >=( const vint16& a, const int b ) { return a >= vint16(b); }
|
||||
__forceinline const vboolf16 operator >=( const int a, const vint16& b ) { return vint16(a) >= b; }
|
||||
__forceinline vboolf16 operator >=(const vint16& a, const vint16& b) { return _mm512_cmp_epi32_mask(a,b,_MM_CMPINT_GE); }
|
||||
__forceinline vboolf16 operator >=(const vint16& a, int b) { return a >= vint16(b); }
|
||||
__forceinline vboolf16 operator >=(int a, const vint16& b) { return vint16(a) >= b; }
|
||||
|
||||
__forceinline const vboolf16 operator > ( const vint16& a, const vint16& b ) { return _mm512_cmp_epi32_mask(a,b,_MM_CMPINT_GT); }
|
||||
__forceinline const vboolf16 operator > ( const vint16& a, const int b ) { return a > vint16(b); }
|
||||
__forceinline const vboolf16 operator > ( const int a, const vint16& b ) { return vint16(a) > b; }
|
||||
__forceinline vboolf16 operator > (const vint16& a, const vint16& b) { return _mm512_cmp_epi32_mask(a,b,_MM_CMPINT_GT); }
|
||||
__forceinline vboolf16 operator > (const vint16& a, int b) { return a > vint16(b); }
|
||||
__forceinline vboolf16 operator > (int a, const vint16& b) { return vint16(a) > b; }
|
||||
|
||||
__forceinline const vboolf16 operator <=( const vint16& a, const vint16& b ) { return _mm512_cmp_epi32_mask(a,b,_MM_CMPINT_LE); }
|
||||
__forceinline const vboolf16 operator <=( const vint16& a, const int b ) { return a <= vint16(b); }
|
||||
__forceinline const vboolf16 operator <=( const int a, const vint16& b ) { return vint16(a) <= b; }
|
||||
__forceinline vboolf16 operator <=(const vint16& a, const vint16& b) { return _mm512_cmp_epi32_mask(a,b,_MM_CMPINT_LE); }
|
||||
__forceinline vboolf16 operator <=(const vint16& a, int b) { return a <= vint16(b); }
|
||||
__forceinline vboolf16 operator <=(int a, const vint16& b) { return vint16(a) <= b; }
|
||||
|
||||
__forceinline vboolf16 eq(const vint16& a, const vint16& b) { return _mm512_cmp_epi32_mask(a,b,_MM_CMPINT_EQ); }
|
||||
__forceinline vboolf16 ne(const vint16& a, const vint16& b) { return _mm512_cmp_epi32_mask(a,b,_MM_CMPINT_NE); }
|
||||
@@ -285,7 +316,7 @@ namespace embree
|
||||
__forceinline vboolf16 uint_gt(const vboolf16 mask, const vint16& a, const vint16& b) { return _mm512_mask_cmp_epu32_mask(mask,a,b,_MM_CMPINT_GT); }
|
||||
|
||||
|
||||
__forceinline const vint16 select( const vboolf16& m, const vint16& t, const vint16& f ) {
|
||||
__forceinline vint16 select(const vboolf16& m, const vint16& t, const vint16& f) {
|
||||
return _mm512_mask_or_epi32(f,m,t,t);
|
||||
}
|
||||
|
||||
@@ -305,41 +336,39 @@ namespace embree
|
||||
// Movement/Shifting/Shuffling Functions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vint16 unpacklo( const vint16& a, const vint16& b ) { return _mm512_unpacklo_epi32(a.v, b.v); }
|
||||
__forceinline vint16 unpackhi( const vint16& a, const vint16& b ) { return _mm512_unpackhi_epi32(a.v, b.v); }
|
||||
__forceinline vint16 unpacklo(const vint16& a, const vint16& b) { return _mm512_unpacklo_epi32(a, b); }
|
||||
__forceinline vint16 unpackhi(const vint16& a, const vint16& b) { return _mm512_unpackhi_epi32(a, b); }
|
||||
|
||||
template<size_t i>
|
||||
__forceinline const vint16 shuffle( const vint16& a ) {
|
||||
return _mm512_castps_si512(_mm512_permute_ps(_mm512_castsi512_ps(a), _MM_SHUFFLE(i, i, i, i)));
|
||||
template<int i>
|
||||
__forceinline vint16 shuffle(const vint16& v) {
|
||||
return _mm512_castps_si512(_mm512_permute_ps(_mm512_castsi512_ps(v), _MM_SHUFFLE(i, i, i, i)));
|
||||
}
|
||||
|
||||
template<int A, int B, int C, int D>
|
||||
__forceinline vint16 shuffle (const vint16& v) {
|
||||
return _mm512_castps_si512(_mm512_permute_ps(_mm512_castsi512_ps(v),_MM_SHUFFLE(D,C,B,A)));
|
||||
template<int i0, int i1, int i2, int i3>
|
||||
__forceinline vint16 shuffle(const vint16& v) {
|
||||
return _mm512_castps_si512(_mm512_permute_ps(_mm512_castsi512_ps(v), _MM_SHUFFLE(i3, i2, i1, i0)));
|
||||
}
|
||||
|
||||
template<int i>
|
||||
__forceinline vint16 shuffle4(const vint16& x) {
|
||||
return _mm512_castps_si512(_mm512_shuffle_f32x4(_mm512_castsi512_ps(x),_mm512_castsi512_ps(x),_MM_SHUFFLE(i,i,i,i)));
|
||||
__forceinline vint16 shuffle4(const vint16& v) {
|
||||
return _mm512_castps_si512(_mm512_shuffle_f32x4(_mm512_castsi512_ps(v), _mm512_castsi512_ps(v), _MM_SHUFFLE(i, i, i, i)));
|
||||
}
|
||||
|
||||
template<int A, int B, int C, int D>
|
||||
__forceinline vint16 shuffle4(const vint16& x) {
|
||||
return _mm512_castps_si512(_mm512_shuffle_f32x4(_mm512_castsi512_ps(x),_mm512_castsi512_ps(x),_MM_SHUFFLE(D,C,B,A)));
|
||||
template<int i0, int i1, int i2, int i3>
|
||||
__forceinline vint16 shuffle4(const vint16& v) {
|
||||
return _mm512_castps_si512(_mm512_shuffle_f32x4(_mm512_castsi512_ps(v), _mm512_castsi512_ps(v), _MM_SHUFFLE(i3, i2, i1, i0)));
|
||||
}
|
||||
|
||||
template<int i>
|
||||
__forceinline vint16 align_shift_right(const vint16& a, const vint16& b)
|
||||
{
|
||||
return _mm512_alignr_epi32(a,b,i);
|
||||
__forceinline vint16 align_shift_right(const vint16& a, const vint16& b) {
|
||||
return _mm512_alignr_epi32(a, b, i);
|
||||
};
|
||||
|
||||
__forceinline int toScalar(const vint16& a)
|
||||
{
|
||||
return _mm_cvtsi128_si32(_mm512_castsi512_si128(a));
|
||||
__forceinline int toScalar(const vint16& v) {
|
||||
return _mm_cvtsi128_si32(_mm512_castsi512_si128(v));
|
||||
}
|
||||
|
||||
template<int i> __forceinline const vint16 insert4(const vint16& a, const vint4& b) { return _mm512_inserti32x4(a, b, i); }
|
||||
template<int i> __forceinline vint16 insert4(const vint16& a, const vint4& b) { return _mm512_inserti32x4(a, b, i); }
|
||||
|
||||
__forceinline size_t extract64bit(const vint16& v) {
|
||||
return _mm_cvtsi128_si64(_mm512_castsi512_si128(v));
|
||||
@@ -366,15 +395,15 @@ namespace embree
|
||||
/// Reductions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vint16 vreduce_min2(vint16 x) { return min(x,shuffle<1,0,3,2>(x)); }
|
||||
__forceinline vint16 vreduce_min4(vint16 x) { x = vreduce_min2(x); return min(x,shuffle<2,3,0,1>(x)); }
|
||||
__forceinline vint16 vreduce_min8(vint16 x) { x = vreduce_min4(x); return min(x,shuffle4<1,0,3,2>(x)); }
|
||||
__forceinline vint16 vreduce_min (vint16 x) { x = vreduce_min8(x); return min(x,shuffle4<2,3,0,1>(x)); }
|
||||
__forceinline vint16 vreduce_min2(vint16 x) { return min(x, shuffle<1,0,3,2>(x)); }
|
||||
__forceinline vint16 vreduce_min4(vint16 x) { x = vreduce_min2(x); return min(x, shuffle<2,3,0,1>(x)); }
|
||||
__forceinline vint16 vreduce_min8(vint16 x) { x = vreduce_min4(x); return min(x, shuffle4<1,0,3,2>(x)); }
|
||||
__forceinline vint16 vreduce_min (vint16 x) { x = vreduce_min8(x); return min(x, shuffle4<2,3,0,1>(x)); }
|
||||
|
||||
__forceinline vint16 vreduce_max2(vint16 x) { return max(x,shuffle<1,0,3,2>(x)); }
|
||||
__forceinline vint16 vreduce_max4(vint16 x) { x = vreduce_max2(x); return max(x,shuffle<2,3,0,1>(x)); }
|
||||
__forceinline vint16 vreduce_max8(vint16 x) { x = vreduce_max4(x); return max(x,shuffle4<1,0,3,2>(x)); }
|
||||
__forceinline vint16 vreduce_max (vint16 x) { x = vreduce_max8(x); return max(x,shuffle4<2,3,0,1>(x)); }
|
||||
__forceinline vint16 vreduce_max2(vint16 x) { return max(x, shuffle<1,0,3,2>(x)); }
|
||||
__forceinline vint16 vreduce_max4(vint16 x) { x = vreduce_max2(x); return max(x, shuffle<2,3,0,1>(x)); }
|
||||
__forceinline vint16 vreduce_max8(vint16 x) { x = vreduce_max4(x); return max(x, shuffle4<1,0,3,2>(x)); }
|
||||
__forceinline vint16 vreduce_max (vint16 x) { x = vreduce_max8(x); return max(x, shuffle4<2,3,0,1>(x)); }
|
||||
|
||||
__forceinline vint16 vreduce_and2(vint16 x) { return x & shuffle<1,0,3,2>(x); }
|
||||
__forceinline vint16 vreduce_and4(vint16 x) { x = vreduce_and2(x); return x & shuffle<2,3,0,1>(x); }
|
||||
@@ -401,36 +430,16 @@ namespace embree
|
||||
/// Memory load and store operations
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<int scale = 4>
|
||||
__forceinline vint16 gather16i(const vboolf16& mask, const int *const ptr, const vint16& index) {
|
||||
return _mm512_mask_i32gather_epi32(_mm512_undefined_epi32(),mask,index,ptr,scale);
|
||||
}
|
||||
|
||||
template<int scale = 4>
|
||||
__forceinline vint16 gather16i(const vboolf16& mask, vint16& dest, const int *const ptr, const vint16& index) {
|
||||
return _mm512_mask_i32gather_epi32(dest,mask,index,ptr,scale);
|
||||
}
|
||||
|
||||
template<int scale = 4>
|
||||
__forceinline void scatter16i(const vboolf16& mask,int *const ptr, const vint16& index,const vint16& v) {
|
||||
_mm512_mask_i32scatter_epi32((int*)ptr,mask,index,v,scale);
|
||||
}
|
||||
|
||||
__forceinline vint16 conflict16i(const vint16& index)
|
||||
__forceinline vint16 conflict(const vint16& index)
|
||||
{
|
||||
return _mm512_conflict_epi32(index);
|
||||
}
|
||||
|
||||
__forceinline vint16 conflict16i(const vboolf16& mask, vint16& dest, const vint16& index)
|
||||
__forceinline vint16 conflict(const vboolf16& mask, vint16& dest, const vint16& index)
|
||||
{
|
||||
return _mm512_mask_conflict_epi32(dest,mask,index);
|
||||
}
|
||||
|
||||
__forceinline void compactustore16i_low(const vboolf16 mask, void *addr, const vint16& reg) {
|
||||
_mm512_mask_compressstoreu_epi32(addr,mask,reg);
|
||||
}
|
||||
|
||||
|
||||
__forceinline vint16 convert_uint32_t(const __m512& f) {
|
||||
return _mm512_cvtps_epu32(f);
|
||||
}
|
||||
@@ -467,10 +476,10 @@ namespace embree
|
||||
|
||||
/* this should use a vbool8 and a vint8_64...*/
|
||||
template<int scale = 1, int hint = _MM_HINT_T0>
|
||||
__forceinline void gather_prefetch64(void const* base_addr,const vbool16 &mask, const vint16& offset)
|
||||
__forceinline void gather_prefetch64(const void* base_addr, const vbool16& mask, const vint16& offset)
|
||||
{
|
||||
#if defined(__AVX512PF__)
|
||||
_mm512_mask_prefetch_i64gather_pd(offset,mask,base_addr,scale,hint);
|
||||
_mm512_mask_prefetch_i64gather_pd(offset, mask, base_addr, scale, hint);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -478,7 +487,7 @@ namespace embree
|
||||
/// Output Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline std::ostream& operator<<(std::ostream& cout, const vint16& v)
|
||||
__forceinline std::ostream& operator <<(std::ostream& cout, const vint16& v)
|
||||
{
|
||||
cout << "<" << v[0];
|
||||
for (int i=1; i<16; i++) cout << ", " << v[i];
|
||||
|
||||
+190
-143
@@ -35,83 +35,86 @@ namespace embree
|
||||
/// Constructors, Assignment & Cast Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vint ( ) {}
|
||||
__forceinline vint ( const vint4& a ) { v = a.v; }
|
||||
__forceinline vint4& operator=( const vint4& a ) { v = a.v; return *this; }
|
||||
__forceinline vint() {}
|
||||
__forceinline vint(const vint4& a) { v = a.v; }
|
||||
__forceinline vint4& operator =(const vint4& a) { v = a.v; return *this; }
|
||||
|
||||
__forceinline vint( const __m128i a ) : v(a) {}
|
||||
__forceinline operator const __m128i&( void ) const { return v; }
|
||||
__forceinline operator __m128i&( void ) { return v; }
|
||||
__forceinline vint(__m128i a) : v(a) {}
|
||||
__forceinline operator const __m128i&() const { return v; }
|
||||
__forceinline operator __m128i&() { return v; }
|
||||
|
||||
__forceinline vint(int a) : v(_mm_set1_epi32(a)) {}
|
||||
__forceinline vint(int a, int b, int c, int d) : v(_mm_set_epi32(d, c, b, a)) {}
|
||||
|
||||
__forceinline vint( const int& a ) : v(_mm_shuffle_epi32(_mm_castps_si128(_mm_load_ss((float*)&a)), _MM_SHUFFLE(0, 0, 0, 0))) {}
|
||||
__forceinline vint( const uint32_t& a ) : v(_mm_shuffle_epi32(_mm_castps_si128(_mm_load_ss((float*)&a)), _MM_SHUFFLE(0, 0, 0, 0))) {}
|
||||
#if defined(__X86_64__)
|
||||
__forceinline vint( const size_t a ) : v(_mm_set1_epi32((int)a)) {}
|
||||
#endif
|
||||
__forceinline vint( int a, int b, int c, int d) : v(_mm_set_epi32(d, c, b, a)) {}
|
||||
|
||||
__forceinline explicit vint( const __m128 a ) : v(_mm_cvtps_epi32(a)) {}
|
||||
__forceinline explicit vint(__m128 a) : v(_mm_cvtps_epi32(a)) {}
|
||||
#if defined(__AVX512VL__)
|
||||
__forceinline explicit vint( const vboolf4 &a ) : v(_mm_movm_epi32(a)) {}
|
||||
__forceinline explicit vint(const vboolf4& a) : v(_mm_movm_epi32(a)) {}
|
||||
#else
|
||||
__forceinline explicit vint( const vboolf4 &a ) : v(_mm_castps_si128((__m128)a)) {}
|
||||
__forceinline explicit vint(const vboolf4& a) : v(_mm_castps_si128((__m128)a)) {}
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Constants
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vint( ZeroTy ) : v(_mm_setzero_si128()) {}
|
||||
__forceinline vint( OneTy ) : v(_mm_set_epi32(1, 1, 1, 1)) {}
|
||||
__forceinline vint( PosInfTy ) : v(_mm_set_epi32(pos_inf, pos_inf, pos_inf, pos_inf)) {}
|
||||
__forceinline vint( NegInfTy ) : v(_mm_set_epi32(neg_inf, neg_inf, neg_inf, neg_inf)) {}
|
||||
__forceinline vint( StepTy ) : v(_mm_set_epi32(3, 2, 1, 0)) {}
|
||||
__forceinline vint( TrueTy ) { v = _mm_cmpeq_epi32(v,v); }
|
||||
__forceinline vint(ZeroTy) : v(_mm_setzero_si128()) {}
|
||||
__forceinline vint(OneTy) : v(_mm_set_epi32(1, 1, 1, 1)) {}
|
||||
__forceinline vint(PosInfTy) : v(_mm_set_epi32(pos_inf, pos_inf, pos_inf, pos_inf)) {}
|
||||
__forceinline vint(NegInfTy) : v(_mm_set_epi32(neg_inf, neg_inf, neg_inf, neg_inf)) {}
|
||||
__forceinline vint(StepTy) : v(_mm_set_epi32(3, 2, 1, 0)) {}
|
||||
__forceinline vint(TrueTy) { v = _mm_cmpeq_epi32(v,v); }
|
||||
__forceinline vint(UndefinedTy) : v(_mm_castps_si128(_mm_undefined_ps())) {}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Loads and Stores
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static __forceinline vint4 load ( const void* const a ) { return _mm_load_si128((__m128i*)a); }
|
||||
static __forceinline vint4 loadu( const void* const a ) { return _mm_loadu_si128((__m128i*)a); }
|
||||
static __forceinline vint4 load (const void* a) { return _mm_load_si128((__m128i*)a); }
|
||||
static __forceinline vint4 loadu(const void* a) { return _mm_loadu_si128((__m128i*)a); }
|
||||
|
||||
static __forceinline void store (void* ptr, const vint4& v) { _mm_store_si128((__m128i*)ptr,v); }
|
||||
static __forceinline void storeu(void* ptr, const vint4& v) { _mm_storeu_si128((__m128i*)ptr,v); }
|
||||
|
||||
#if defined(__AVX512VL__)
|
||||
static __forceinline vint4 load ( const vboolf4& mask, const void* const ptr ) { return _mm_mask_load_epi32 (_mm_setzero_si128(),mask,ptr); }
|
||||
static __forceinline vint4 loadu( const vboolf4& mask, const void* const ptr ) { return _mm_mask_loadu_epi32(_mm_setzero_si128(),mask,ptr); }
|
||||
|
||||
static __forceinline void store ( const vboolf4& mask, void* ptr, const vint4& v ) { _mm_mask_store_epi32 (ptr,mask,v); }
|
||||
static __forceinline void storeu( const vboolf4& mask, void* ptr, const vint4& v ) { _mm_mask_storeu_epi32(ptr,mask,v); }
|
||||
static __forceinline vint4 compact(const vboolf4& mask, vint4 &v) {
|
||||
return _mm_mask_compress_epi32(v, mask, v);
|
||||
}
|
||||
static __forceinline vint4 compact(const vboolf4& mask, vint4 &a, const vint4& b) {
|
||||
return _mm_mask_compress_epi32(a, mask, b);
|
||||
}
|
||||
|
||||
static __forceinline vint4 load (const vboolf4& mask, const void* ptr) { return _mm_mask_load_epi32 (_mm_setzero_si128(),mask,ptr); }
|
||||
static __forceinline vint4 loadu(const vboolf4& mask, const void* ptr) { return _mm_mask_loadu_epi32(_mm_setzero_si128(),mask,ptr); }
|
||||
|
||||
static __forceinline void store (const vboolf4& mask, void* ptr, const vint4& v) { _mm_mask_store_epi32 (ptr,mask,v); }
|
||||
static __forceinline void storeu(const vboolf4& mask, void* ptr, const vint4& v) { _mm_mask_storeu_epi32(ptr,mask,v); }
|
||||
#elif defined(__AVX__)
|
||||
static __forceinline vint4 load ( const vbool4& mask, const void* const a ) { return _mm_castps_si128(_mm_maskload_ps((float*)a,mask)); }
|
||||
static __forceinline vint4 loadu( const vbool4& mask, const void* const a ) { return _mm_castps_si128(_mm_maskload_ps((float*)a,mask)); }
|
||||
static __forceinline vint4 load (const vbool4& mask, const void* a) { return _mm_castps_si128(_mm_maskload_ps((float*)a,mask)); }
|
||||
static __forceinline vint4 loadu(const vbool4& mask, const void* a) { return _mm_castps_si128(_mm_maskload_ps((float*)a,mask)); }
|
||||
|
||||
static __forceinline void store ( const vboolf4& mask, void* ptr, const vint4& i ) { _mm_maskstore_ps((float*)ptr,(__m128i)mask,_mm_castsi128_ps(i)); }
|
||||
static __forceinline void storeu( const vboolf4& mask, void* ptr, const vint4& i ) { _mm_maskstore_ps((float*)ptr,(__m128i)mask,_mm_castsi128_ps(i)); }
|
||||
static __forceinline void store (const vboolf4& mask, void* ptr, const vint4& i) { _mm_maskstore_ps((float*)ptr,(__m128i)mask,_mm_castsi128_ps(i)); }
|
||||
static __forceinline void storeu(const vboolf4& mask, void* ptr, const vint4& i) { _mm_maskstore_ps((float*)ptr,(__m128i)mask,_mm_castsi128_ps(i)); }
|
||||
#else
|
||||
static __forceinline vint4 load ( const vbool4& mask, const void* const a ) { return _mm_and_si128(_mm_load_si128 ((__m128i*)a),mask); }
|
||||
static __forceinline vint4 loadu( const vbool4& mask, const void* const a ) { return _mm_and_si128(_mm_loadu_si128((__m128i*)a),mask); }
|
||||
static __forceinline vint4 load (const vbool4& mask, const void* a) { return _mm_and_si128(_mm_load_si128 ((__m128i*)a),mask); }
|
||||
static __forceinline vint4 loadu(const vbool4& mask, const void* a) { return _mm_and_si128(_mm_loadu_si128((__m128i*)a),mask); }
|
||||
|
||||
static __forceinline void store ( const vboolf4& mask, void* ptr, const vint4& i ) { store (ptr,select(mask,i,load (ptr))); }
|
||||
static __forceinline void storeu( const vboolf4& mask, void* ptr, const vint4& i ) { storeu(ptr,select(mask,i,loadu(ptr))); }
|
||||
static __forceinline void store (const vboolf4& mask, void* ptr, const vint4& i) { store (ptr,select(mask,i,load (ptr))); }
|
||||
static __forceinline void storeu(const vboolf4& mask, void* ptr, const vint4& i) { storeu(ptr,select(mask,i,loadu(ptr))); }
|
||||
#endif
|
||||
|
||||
#if defined(__SSE4_1__)
|
||||
static __forceinline vint4 load( const unsigned char* const ptr ) {
|
||||
static __forceinline vint4 load(const unsigned char* ptr) {
|
||||
return _mm_cvtepu8_epi32(_mm_load_si128((__m128i*)ptr));
|
||||
}
|
||||
|
||||
static __forceinline vint4 loadu( const unsigned char* const ptr ) {
|
||||
static __forceinline vint4 loadu(const unsigned char* ptr) {
|
||||
return _mm_cvtepu8_epi32(_mm_loadu_si128((__m128i*)ptr));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static __forceinline vint4 load(const unsigned short* const ptr) {
|
||||
static __forceinline vint4 load(const unsigned short* ptr) {
|
||||
#if defined (__SSE4_1__)
|
||||
return _mm_cvtepu16_epi32(_mm_loadu_si128((__m128i*)ptr));
|
||||
#else
|
||||
@@ -119,7 +122,7 @@ namespace embree
|
||||
#endif
|
||||
}
|
||||
|
||||
static __forceinline void store_uchar( unsigned char* const ptr, const vint4& v ) {
|
||||
static __forceinline void store(unsigned char* ptr, const vint4& v) {
|
||||
#if defined(__SSE4_1__)
|
||||
__m128i x = v;
|
||||
x = _mm_packus_epi32(x, x);
|
||||
@@ -131,12 +134,12 @@ namespace embree
|
||||
#endif
|
||||
}
|
||||
|
||||
static __forceinline void store_ushort( unsigned short* const ptr, const vint4& v ) {
|
||||
static __forceinline void store(unsigned short* ptr, const vint4& v) {
|
||||
for (size_t i=0;i<4;i++)
|
||||
ptr[i] = (unsigned short)v[i];
|
||||
}
|
||||
|
||||
static __forceinline vint4 load_nt (void* ptr) {
|
||||
static __forceinline vint4 load_nt(void* ptr) {
|
||||
#if defined(__SSE4_1__)
|
||||
return _mm_stream_load_si128((__m128i*)ptr);
|
||||
#else
|
||||
@@ -146,24 +149,53 @@ namespace embree
|
||||
|
||||
static __forceinline void store_nt(void* ptr, const vint4& v) {
|
||||
#if defined(__SSE4_1__)
|
||||
_mm_stream_ps((float*)ptr,_mm_castsi128_ps(v));
|
||||
_mm_stream_ps((float*)ptr, _mm_castsi128_ps(v));
|
||||
#else
|
||||
_mm_store_si128((__m128i*)ptr,v);
|
||||
#endif
|
||||
}
|
||||
|
||||
template<int scale = 4>
|
||||
static __forceinline vint4 gather(const int* ptr, const vint4& index) {
|
||||
#if defined(__AVX2__)
|
||||
return _mm_i32gather_epi32(ptr, index, scale);
|
||||
#else
|
||||
return vint4(
|
||||
*(int*)(((char*)ptr)+scale*index[0]),
|
||||
*(int*)(((char*)ptr)+scale*index[1]),
|
||||
*(int*)(((char*)ptr)+scale*index[2]),
|
||||
*(int*)(((char*)ptr)+scale*index[3]));
|
||||
#endif
|
||||
}
|
||||
|
||||
template<int scale = 4>
|
||||
static __forceinline vint4 gather(const vboolf4& mask, const int* ptr, const vint4& index) {
|
||||
vint4 r = zero;
|
||||
#if defined(__AVX512VL__)
|
||||
return _mm_mmask_i32gather_epi32(r, mask, index, ptr, scale);
|
||||
#elif defined(__AVX2__)
|
||||
return _mm_mask_i32gather_epi32(r, ptr, index, mask, scale);
|
||||
#else
|
||||
if (likely(mask[0])) r[0] = *(int*)(((char*)ptr)+scale*index[0]);
|
||||
if (likely(mask[1])) r[1] = *(int*)(((char*)ptr)+scale*index[1]);
|
||||
if (likely(mask[2])) r[2] = *(int*)(((char*)ptr)+scale*index[2]);
|
||||
if (likely(mask[3])) r[3] = *(int*)(((char*)ptr)+scale*index[3]);
|
||||
return r;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(__x86_64__)
|
||||
static __forceinline vint4 broadcast64(const long long &a) { return _mm_set1_epi64x(a); }
|
||||
static __forceinline vint4 broadcast64(long long a) { return _mm_set1_epi64x(a); }
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Array Access
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const int& operator []( const size_t index ) const { assert(index < 4); return i[index]; }
|
||||
__forceinline int& operator []( const size_t index ) { assert(index < 4); return i[index]; }
|
||||
__forceinline const int& operator [](size_t index) const { assert(index < 4); return i[index]; }
|
||||
__forceinline int& operator [](size_t index) { assert(index < 4); return i[index]; }
|
||||
|
||||
friend __forceinline const vint4 select( const vboolf4& m, const vint4& t, const vint4& f ) {
|
||||
friend __forceinline vint4 select(const vboolf4& m, const vint4& t, const vint4& f) {
|
||||
#if defined(__AVX512VL__)
|
||||
return _mm_mask_blend_epi32(m, f, t);
|
||||
#elif defined(__SSE4_1__)
|
||||
@@ -178,113 +210,113 @@ namespace embree
|
||||
/// Unary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vint4 asInt ( const __m128& a ) { return _mm_castps_si128(a); }
|
||||
__forceinline const vint4 operator +( const vint4& a ) { return a; }
|
||||
__forceinline const vint4 operator -( const vint4& a ) { return _mm_sub_epi32(_mm_setzero_si128(), a.v); }
|
||||
__forceinline vint4 asInt(const __m128& a) { return _mm_castps_si128(a); }
|
||||
__forceinline vint4 operator +(const vint4& a) { return a; }
|
||||
__forceinline vint4 operator -(const vint4& a) { return _mm_sub_epi32(_mm_setzero_si128(), a); }
|
||||
#if defined(__SSSE3__)
|
||||
__forceinline const vint4 abs ( const vint4& a ) { return _mm_abs_epi32(a.v); }
|
||||
__forceinline vint4 abs(const vint4& a) { return _mm_abs_epi32(a); }
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Binary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vint4 operator +( const vint4& a, const vint4& b ) { return _mm_add_epi32(a.v, b.v); }
|
||||
__forceinline const vint4 operator +( const vint4& a, const int& b ) { return a + vint4(b); }
|
||||
__forceinline const vint4 operator +( const int& a, const vint4& b ) { return vint4(a) + b; }
|
||||
__forceinline vint4 operator +(const vint4& a, const vint4& b) { return _mm_add_epi32(a, b); }
|
||||
__forceinline vint4 operator +(const vint4& a, int b) { return a + vint4(b); }
|
||||
__forceinline vint4 operator +(int a, const vint4& b) { return vint4(a) + b; }
|
||||
|
||||
__forceinline const vint4 operator -( const vint4& a, const vint4& b ) { return _mm_sub_epi32(a.v, b.v); }
|
||||
__forceinline const vint4 operator -( const vint4& a, const int& b ) { return a - vint4(b); }
|
||||
__forceinline const vint4 operator -( const int& a, const vint4& b ) { return vint4(a) - b; }
|
||||
__forceinline vint4 operator -(const vint4& a, const vint4& b) { return _mm_sub_epi32(a, b); }
|
||||
__forceinline vint4 operator -(const vint4& a, int b) { return a - vint4(b); }
|
||||
__forceinline vint4 operator -(int a, const vint4& b) { return vint4(a) - b; }
|
||||
|
||||
#if defined(__SSE4_1__)
|
||||
__forceinline const vint4 operator *( const vint4& a, const vint4& b ) { return _mm_mullo_epi32(a.v, b.v); }
|
||||
__forceinline vint4 operator *(const vint4& a, const vint4& b) { return _mm_mullo_epi32(a, b); }
|
||||
#else
|
||||
__forceinline const vint4 operator *( const vint4& a, const vint4& b ) { return vint4(a[0]*b[0],a[1]*b[1],a[2]*b[2],a[3]*b[3]); }
|
||||
__forceinline vint4 operator *(const vint4& a, const vint4& b) { return vint4(a[0]*b[0],a[1]*b[1],a[2]*b[2],a[3]*b[3]); }
|
||||
#endif
|
||||
__forceinline const vint4 operator *( const vint4& a, const int& b ) { return a * vint4(b); }
|
||||
__forceinline const vint4 operator *( const int& a, const vint4& b ) { return vint4(a) * b; }
|
||||
__forceinline vint4 operator *(const vint4& a, int b) { return a * vint4(b); }
|
||||
__forceinline vint4 operator *(int a, const vint4& b) { return vint4(a) * b; }
|
||||
|
||||
__forceinline const vint4 operator &( const vint4& a, const vint4& b ) { return _mm_and_si128(a.v, b.v); }
|
||||
__forceinline const vint4 operator &( const vint4& a, const int& b ) { return a & vint4(b); }
|
||||
__forceinline const vint4 operator &( const int& a, const vint4& b ) { return vint4(a) & b; }
|
||||
__forceinline vint4 operator &(const vint4& a, const vint4& b) { return _mm_and_si128(a, b); }
|
||||
__forceinline vint4 operator &(const vint4& a, int b) { return a & vint4(b); }
|
||||
__forceinline vint4 operator &(int a, const vint4& b) { return vint4(a) & b; }
|
||||
|
||||
__forceinline const vint4 operator |( const vint4& a, const vint4& b ) { return _mm_or_si128(a.v, b.v); }
|
||||
__forceinline const vint4 operator |( const vint4& a, const int& b ) { return a | vint4(b); }
|
||||
__forceinline const vint4 operator |( const int& a, const vint4& b ) { return vint4(a) | b; }
|
||||
__forceinline vint4 operator |(const vint4& a, const vint4& b) { return _mm_or_si128(a, b); }
|
||||
__forceinline vint4 operator |(const vint4& a, int b) { return a | vint4(b); }
|
||||
__forceinline vint4 operator |(int a, const vint4& b) { return vint4(a) | b; }
|
||||
|
||||
__forceinline const vint4 operator ^( const vint4& a, const vint4& b ) { return _mm_xor_si128(a.v, b.v); }
|
||||
__forceinline const vint4 operator ^( const vint4& a, const int& b ) { return a ^ vint4(b); }
|
||||
__forceinline const vint4 operator ^( const int& a, const vint4& b ) { return vint4(a) ^ b; }
|
||||
__forceinline vint4 operator ^(const vint4& a, const vint4& b) { return _mm_xor_si128(a, b); }
|
||||
__forceinline vint4 operator ^(const vint4& a, int b) { return a ^ vint4(b); }
|
||||
__forceinline vint4 operator ^(int a, const vint4& b) { return vint4(a) ^ b; }
|
||||
|
||||
__forceinline const vint4 operator <<( const vint4& a, const int& n ) { return _mm_slli_epi32(a.v, n); }
|
||||
__forceinline const vint4 operator >>( const vint4& a, const int& n ) { return _mm_srai_epi32(a.v, n); }
|
||||
__forceinline vint4 operator <<(const vint4& a, int n) { return _mm_slli_epi32(a, n); }
|
||||
__forceinline vint4 operator >>(const vint4& a, int n) { return _mm_srai_epi32(a, n); }
|
||||
|
||||
__forceinline const vint4 sll ( const vint4& a, const int& b ) { return _mm_slli_epi32(a.v, b); }
|
||||
__forceinline const vint4 sra ( const vint4& a, const int& b ) { return _mm_srai_epi32(a.v, b); }
|
||||
__forceinline const vint4 srl ( const vint4& a, const int& b ) { return _mm_srli_epi32(a.v, b); }
|
||||
__forceinline vint4 sll (const vint4& a, int b) { return _mm_slli_epi32(a, b); }
|
||||
__forceinline vint4 sra (const vint4& a, int b) { return _mm_srai_epi32(a, b); }
|
||||
__forceinline vint4 srl (const vint4& a, int b) { return _mm_srli_epi32(a, b); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Assignment Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vint4& operator +=( vint4& a, const vint4& b ) { return a = a + b; }
|
||||
__forceinline vint4& operator +=( vint4& a, const int& b ) { return a = a + b; }
|
||||
__forceinline vint4& operator +=(vint4& a, const vint4& b) { return a = a + b; }
|
||||
__forceinline vint4& operator +=(vint4& a, int b) { return a = a + b; }
|
||||
|
||||
__forceinline vint4& operator -=( vint4& a, const vint4& b ) { return a = a - b; }
|
||||
__forceinline vint4& operator -=( vint4& a, const int& b ) { return a = a - b; }
|
||||
__forceinline vint4& operator -=(vint4& a, const vint4& b) { return a = a - b; }
|
||||
__forceinline vint4& operator -=(vint4& a, int b) { return a = a - b; }
|
||||
|
||||
#if defined(__SSE4_1__)
|
||||
__forceinline vint4& operator *=( vint4& a, const vint4& b ) { return a = a * b; }
|
||||
__forceinline vint4& operator *=( vint4& a, const int& b ) { return a = a * b; }
|
||||
__forceinline vint4& operator *=(vint4& a, const vint4& b) { return a = a * b; }
|
||||
__forceinline vint4& operator *=(vint4& a, int b) { return a = a * b; }
|
||||
#endif
|
||||
|
||||
__forceinline vint4& operator &=( vint4& a, const vint4& b ) { return a = a & b; }
|
||||
__forceinline vint4& operator &=( vint4& a, const int& b ) { return a = a & b; }
|
||||
__forceinline vint4& operator &=(vint4& a, const vint4& b) { return a = a & b; }
|
||||
__forceinline vint4& operator &=(vint4& a, int b) { return a = a & b; }
|
||||
|
||||
__forceinline vint4& operator |=( vint4& a, const vint4& b ) { return a = a | b; }
|
||||
__forceinline vint4& operator |=( vint4& a, const int& b ) { return a = a | b; }
|
||||
__forceinline vint4& operator |=(vint4& a, const vint4& b) { return a = a | b; }
|
||||
__forceinline vint4& operator |=(vint4& a, int b) { return a = a | b; }
|
||||
|
||||
__forceinline vint4& operator <<=( vint4& a, const int& b ) { return a = a << b; }
|
||||
__forceinline vint4& operator >>=( vint4& a, const int& b ) { return a = a >> b; }
|
||||
__forceinline vint4& operator <<=(vint4& a, int b) { return a = a << b; }
|
||||
__forceinline vint4& operator >>=(vint4& a, int b) { return a = a >> b; }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Comparison Operators + Select
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined(__AVX512VL__)
|
||||
__forceinline const vboolf4 operator ==( const vint4& a, const vint4& b ) { return _mm_cmp_epi32_mask(a,b,_MM_CMPINT_EQ); }
|
||||
__forceinline const vboolf4 operator !=( const vint4& a, const vint4& b ) { return _mm_cmp_epi32_mask(a,b,_MM_CMPINT_NE); }
|
||||
__forceinline const vboolf4 operator < ( const vint4& a, const vint4& b ) { return _mm_cmp_epi32_mask(a,b,_MM_CMPINT_LT); }
|
||||
__forceinline const vboolf4 operator >=( const vint4& a, const vint4& b ) { return _mm_cmp_epi32_mask(a,b,_MM_CMPINT_GE); }
|
||||
__forceinline const vboolf4 operator > ( const vint4& a, const vint4& b ) { return _mm_cmp_epi32_mask(a,b,_MM_CMPINT_GT); }
|
||||
__forceinline const vboolf4 operator <=( const vint4& a, const vint4& b ) { return _mm_cmp_epi32_mask(a,b,_MM_CMPINT_LE); }
|
||||
__forceinline vboolf4 operator ==(const vint4& a, const vint4& b) { return _mm_cmp_epi32_mask(a,b,_MM_CMPINT_EQ); }
|
||||
__forceinline vboolf4 operator !=(const vint4& a, const vint4& b) { return _mm_cmp_epi32_mask(a,b,_MM_CMPINT_NE); }
|
||||
__forceinline vboolf4 operator < (const vint4& a, const vint4& b) { return _mm_cmp_epi32_mask(a,b,_MM_CMPINT_LT); }
|
||||
__forceinline vboolf4 operator >=(const vint4& a, const vint4& b) { return _mm_cmp_epi32_mask(a,b,_MM_CMPINT_GE); }
|
||||
__forceinline vboolf4 operator > (const vint4& a, const vint4& b) { return _mm_cmp_epi32_mask(a,b,_MM_CMPINT_GT); }
|
||||
__forceinline vboolf4 operator <=(const vint4& a, const vint4& b) { return _mm_cmp_epi32_mask(a,b,_MM_CMPINT_LE); }
|
||||
#else
|
||||
__forceinline const vboolf4 operator ==( const vint4& a, const vint4& b ) { return _mm_castsi128_ps(_mm_cmpeq_epi32(a, b)); }
|
||||
__forceinline const vboolf4 operator !=( const vint4& a, const vint4& b ) { return !(a == b); }
|
||||
__forceinline const vboolf4 operator < ( const vint4& a, const vint4& b ) { return _mm_castsi128_ps(_mm_cmplt_epi32(a, b)); }
|
||||
__forceinline const vboolf4 operator >=( const vint4& a, const vint4& b ) { return !(a < b); }
|
||||
__forceinline const vboolf4 operator > ( const vint4& a, const vint4& b ) { return _mm_castsi128_ps(_mm_cmpgt_epi32(a, b)); }
|
||||
__forceinline const vboolf4 operator <=( const vint4& a, const vint4& b ) { return !(a > b); }
|
||||
__forceinline vboolf4 operator ==(const vint4& a, const vint4& b) { return _mm_castsi128_ps(_mm_cmpeq_epi32(a, b)); }
|
||||
__forceinline vboolf4 operator !=(const vint4& a, const vint4& b) { return !(a == b); }
|
||||
__forceinline vboolf4 operator < (const vint4& a, const vint4& b) { return _mm_castsi128_ps(_mm_cmplt_epi32(a, b)); }
|
||||
__forceinline vboolf4 operator >=(const vint4& a, const vint4& b) { return !(a < b); }
|
||||
__forceinline vboolf4 operator > (const vint4& a, const vint4& b) { return _mm_castsi128_ps(_mm_cmpgt_epi32(a, b)); }
|
||||
__forceinline vboolf4 operator <=(const vint4& a, const vint4& b) { return !(a > b); }
|
||||
#endif
|
||||
|
||||
__forceinline const vboolf4 operator ==( const vint4& a, const int& b ) { return a == vint4(b); }
|
||||
__forceinline const vboolf4 operator ==( const int& a, const vint4& b ) { return vint4(a) == b; }
|
||||
__forceinline vboolf4 operator ==(const vint4& a, int b) { return a == vint4(b); }
|
||||
__forceinline vboolf4 operator ==(int a, const vint4& b) { return vint4(a) == b; }
|
||||
|
||||
__forceinline const vboolf4 operator !=( const vint4& a, const int& b ) { return a != vint4(b); }
|
||||
__forceinline const vboolf4 operator !=( const int& a, const vint4& b ) { return vint4(a) != b; }
|
||||
__forceinline vboolf4 operator !=(const vint4& a, int b) { return a != vint4(b); }
|
||||
__forceinline vboolf4 operator !=(int a, const vint4& b) { return vint4(a) != b; }
|
||||
|
||||
__forceinline const vboolf4 operator < ( const vint4& a, const int& b ) { return a < vint4(b); }
|
||||
__forceinline const vboolf4 operator < ( const int& a, const vint4& b ) { return vint4(a) < b; }
|
||||
__forceinline vboolf4 operator < (const vint4& a, int b) { return a < vint4(b); }
|
||||
__forceinline vboolf4 operator < (int a, const vint4& b) { return vint4(a) < b; }
|
||||
|
||||
__forceinline const vboolf4 operator >=( const vint4& a, const int& b ) { return a >= vint4(b); }
|
||||
__forceinline const vboolf4 operator >=( const int& a, const vint4& b ) { return vint4(a) >= b; }
|
||||
__forceinline vboolf4 operator >=(const vint4& a, int b) { return a >= vint4(b); }
|
||||
__forceinline vboolf4 operator >=(int a, const vint4& b) { return vint4(a) >= b; }
|
||||
|
||||
__forceinline const vboolf4 operator > ( const vint4& a, const int& b ) { return a > vint4(b); }
|
||||
__forceinline const vboolf4 operator > ( const int& a, const vint4& b ) { return vint4(a) > b; }
|
||||
__forceinline vboolf4 operator > (const vint4& a, int b) { return a > vint4(b); }
|
||||
__forceinline vboolf4 operator > (int a, const vint4& b) { return vint4(a) > b; }
|
||||
|
||||
__forceinline const vboolf4 operator <=( const vint4& a, const int& b ) { return a <= vint4(b); }
|
||||
__forceinline const vboolf4 operator <=( const int& a, const vint4& b ) { return vint4(a) <= b; }
|
||||
__forceinline vboolf4 operator <=(const vint4& a, int b) { return a <= vint4(b); }
|
||||
__forceinline vboolf4 operator <=(int a, const vint4& b) { return vint4(a) <= b; }
|
||||
|
||||
__forceinline vboolf4 eq(const vint4& a, const vint4& b) { return a == b; }
|
||||
__forceinline vboolf4 ne(const vint4& a, const vint4& b) { return a != b; }
|
||||
@@ -310,7 +342,7 @@ namespace embree
|
||||
#endif
|
||||
|
||||
template<int mask>
|
||||
__forceinline const vint4 select(const vint4& t, const vint4& f) {
|
||||
__forceinline vint4 select(const vint4& t, const vint4& f) {
|
||||
#if defined(__SSE4_1__)
|
||||
return _mm_castps_si128(_mm_blend_ps(_mm_castsi128_ps(f), _mm_castsi128_ps(t), mask));
|
||||
#else
|
||||
@@ -319,68 +351,83 @@ namespace embree
|
||||
}
|
||||
|
||||
#if defined(__SSE4_1__)
|
||||
__forceinline const vint4 min( const vint4& a, const vint4& b ) { return _mm_min_epi32(a.v, b.v); }
|
||||
__forceinline const vint4 max( const vint4& a, const vint4& b ) { return _mm_max_epi32(a.v, b.v); }
|
||||
__forceinline vint4 min(const vint4& a, const vint4& b) { return _mm_min_epi32(a, b); }
|
||||
__forceinline vint4 max(const vint4& a, const vint4& b) { return _mm_max_epi32(a, b); }
|
||||
|
||||
__forceinline const vint4 umin( const vint4& a, const vint4& b ) { return _mm_min_epu32(a.v, b.v); }
|
||||
__forceinline const vint4 umax( const vint4& a, const vint4& b ) { return _mm_max_epu32(a.v, b.v); }
|
||||
__forceinline vint4 umin(const vint4& a, const vint4& b) { return _mm_min_epu32(a, b); }
|
||||
__forceinline vint4 umax(const vint4& a, const vint4& b) { return _mm_max_epu32(a, b); }
|
||||
|
||||
#else
|
||||
__forceinline const vint4 min( const vint4& a, const vint4& b ) { return select(a < b,a,b); }
|
||||
__forceinline const vint4 max( const vint4& a, const vint4& b ) { return select(a < b,b,a); }
|
||||
__forceinline vint4 min(const vint4& a, const vint4& b) { return select(a < b,a,b); }
|
||||
__forceinline vint4 max(const vint4& a, const vint4& b) { return select(a < b,b,a); }
|
||||
#endif
|
||||
|
||||
__forceinline const vint4 min( const vint4& a, const int& b ) { return min(a,vint4(b)); }
|
||||
__forceinline const vint4 min( const int& a, const vint4& b ) { return min(vint4(a),b); }
|
||||
__forceinline const vint4 max( const vint4& a, const int& b ) { return max(a,vint4(b)); }
|
||||
__forceinline const vint4 max( const int& a, const vint4& b ) { return max(vint4(a),b); }
|
||||
__forceinline vint4 min(const vint4& a, int b) { return min(a,vint4(b)); }
|
||||
__forceinline vint4 min(int a, const vint4& b) { return min(vint4(a),b); }
|
||||
__forceinline vint4 max(const vint4& a, int b) { return max(a,vint4(b)); }
|
||||
__forceinline vint4 max(int a, const vint4& b) { return max(vint4(a),b); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Movement/Shifting/Shuffling Functions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vint4 unpacklo( const vint4& a, const vint4& b ) { return _mm_castps_si128(_mm_unpacklo_ps(_mm_castsi128_ps(a.v), _mm_castsi128_ps(b.v))); }
|
||||
__forceinline vint4 unpackhi( const vint4& a, const vint4& b ) { return _mm_castps_si128(_mm_unpackhi_ps(_mm_castsi128_ps(a.v), _mm_castsi128_ps(b.v))); }
|
||||
__forceinline vint4 unpacklo(const vint4& a, const vint4& b) { return _mm_castps_si128(_mm_unpacklo_ps(_mm_castsi128_ps(a), _mm_castsi128_ps(b))); }
|
||||
__forceinline vint4 unpackhi(const vint4& a, const vint4& b) { return _mm_castps_si128(_mm_unpackhi_ps(_mm_castsi128_ps(a), _mm_castsi128_ps(b))); }
|
||||
|
||||
template<size_t i0, size_t i1, size_t i2, size_t i3> __forceinline const vint4 shuffle( const vint4& a ) {
|
||||
return _mm_shuffle_epi32(a, _MM_SHUFFLE(i3, i2, i1, i0));
|
||||
template<int i0, int i1, int i2, int i3>
|
||||
__forceinline vint4 shuffle(const vint4& v) {
|
||||
return _mm_shuffle_epi32(v, _MM_SHUFFLE(i3, i2, i1, i0));
|
||||
}
|
||||
|
||||
template<size_t i0, size_t i1, size_t i2, size_t i3> __forceinline const vint4 shuffle( const vint4& a, const vint4& b ) {
|
||||
template<int i0, int i1, int i2, int i3>
|
||||
__forceinline vint4 shuffle(const vint4& a, const vint4& b) {
|
||||
return _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(a), _mm_castsi128_ps(b), _MM_SHUFFLE(i3, i2, i1, i0)));
|
||||
}
|
||||
|
||||
#if defined(__SSE3__)
|
||||
template<> __forceinline const vint4 shuffle<0, 0, 2, 2>( const vint4& a ) { return _mm_castps_si128(_mm_moveldup_ps(_mm_castsi128_ps(a))); }
|
||||
template<> __forceinline const vint4 shuffle<1, 1, 3, 3>( const vint4& a ) { return _mm_castps_si128(_mm_movehdup_ps(_mm_castsi128_ps(a))); }
|
||||
template<> __forceinline const vint4 shuffle<0, 1, 0, 1>( const vint4& a ) { return _mm_castpd_si128(_mm_movedup_pd (_mm_castsi128_pd(a))); }
|
||||
template<> __forceinline vint4 shuffle<0, 0, 2, 2>(const vint4& v) { return _mm_castps_si128(_mm_moveldup_ps(_mm_castsi128_ps(v))); }
|
||||
template<> __forceinline vint4 shuffle<1, 1, 3, 3>(const vint4& v) { return _mm_castps_si128(_mm_movehdup_ps(_mm_castsi128_ps(v))); }
|
||||
template<> __forceinline vint4 shuffle<0, 1, 0, 1>(const vint4& v) { return _mm_castpd_si128(_mm_movedup_pd (_mm_castsi128_pd(v))); }
|
||||
#endif
|
||||
|
||||
template<size_t i0> __forceinline const vint4 shuffle( const vint4& b ) {
|
||||
return shuffle<i0,i0,i0,i0>(b);
|
||||
template<int i>
|
||||
__forceinline vint4 shuffle(const vint4& v) {
|
||||
return shuffle<i,i,i,i>(v);
|
||||
}
|
||||
|
||||
#if defined(__SSE4_1__)
|
||||
template<size_t src> __forceinline int extract( const vint4& b ) { return _mm_extract_epi32(b, src); }
|
||||
template<size_t dst> __forceinline const vint4 insert( const vint4& a, const int b ) { return _mm_insert_epi32(a, b, dst); }
|
||||
template<int src> __forceinline int extract(const vint4& b) { return _mm_extract_epi32(b, src); }
|
||||
template<int dst> __forceinline vint4 insert(const vint4& a, const int b) { return _mm_insert_epi32(a, b, dst); }
|
||||
#else
|
||||
template<size_t src> __forceinline int extract( const vint4& b ) { return b[src]; }
|
||||
template<size_t dst> __forceinline const vint4 insert( const vint4& a, const int b ) { vint4 c = a; c[dst] = b; return c; }
|
||||
template<int src> __forceinline int extract(const vint4& b) { return b[src&3]; }
|
||||
template<int dst> __forceinline vint4 insert(const vint4& a, int b) { vint4 c = a; c[dst&3] = b; return c; }
|
||||
#endif
|
||||
|
||||
|
||||
template<> __forceinline int extract<0>( const vint4& b ) { return _mm_cvtsi128_si32(b); }
|
||||
template<> __forceinline int extract<0>(const vint4& b) { return _mm_cvtsi128_si32(b); }
|
||||
|
||||
__forceinline int toScalar(const vint4& a) { return _mm_cvtsi128_si32(a); }
|
||||
__forceinline int toScalar(const vint4& v) { return _mm_cvtsi128_si32(v); }
|
||||
|
||||
#if defined(__AVX512VL__)
|
||||
|
||||
__forceinline vint4 permute(const vint4 &a, const vint4 &index) {
|
||||
return _mm_castps_si128(_mm_permutevar_ps(_mm_castsi128_ps(a),index));
|
||||
}
|
||||
|
||||
template<int i>
|
||||
__forceinline vint4 align_shift_right(const vint4& a, const vint4& b) {
|
||||
return _mm_alignr_epi32(a, b, i);
|
||||
}
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Reductions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined(__SSE4_1__)
|
||||
__forceinline const vint4 vreduce_min(const vint4& v) { vint4 h = min(shuffle<1,0,3,2>(v),v); return min(shuffle<2,3,0,1>(h),h); }
|
||||
__forceinline const vint4 vreduce_max(const vint4& v) { vint4 h = max(shuffle<1,0,3,2>(v),v); return max(shuffle<2,3,0,1>(h),h); }
|
||||
__forceinline const vint4 vreduce_add(const vint4& v) { vint4 h = shuffle<1,0,3,2>(v) + v ; return shuffle<2,3,0,1>(h) + h ; }
|
||||
__forceinline vint4 vreduce_min(const vint4& v) { vint4 h = min(shuffle<1,0,3,2>(v),v); return min(shuffle<2,3,0,1>(h),h); }
|
||||
__forceinline vint4 vreduce_max(const vint4& v) { vint4 h = max(shuffle<1,0,3,2>(v),v); return max(shuffle<2,3,0,1>(h),h); }
|
||||
__forceinline vint4 vreduce_add(const vint4& v) { vint4 h = shuffle<1,0,3,2>(v) + v ; return shuffle<2,3,0,1>(h) + h ; }
|
||||
|
||||
__forceinline int reduce_min(const vint4& v) { return toScalar(vreduce_min(v)); }
|
||||
__forceinline int reduce_max(const vint4& v) { return toScalar(vreduce_max(v)); }
|
||||
@@ -486,7 +533,7 @@ namespace embree
|
||||
/// Output Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& cout, const vint4& a) {
|
||||
inline std::ostream& operator <<(std::ostream& cout, const vint4& a) {
|
||||
return cout << "<" << a[0] << ", " << a[1] << ", " << a[2] << ", " << a[3] << ">";
|
||||
}
|
||||
}
|
||||
|
||||
+170
-137
@@ -37,214 +37,242 @@ namespace embree
|
||||
/// Constructors, Assignment & Cast Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vint ( ) {}
|
||||
__forceinline vint ( const vint8& a ) { v = a.v; }
|
||||
__forceinline vint8& operator=( const vint8& a ) { v = a.v; return *this; }
|
||||
__forceinline vint() {}
|
||||
__forceinline vint(const vint8& a) { v = a.v; }
|
||||
__forceinline vint8& operator =(const vint8& a) { v = a.v; return *this; }
|
||||
|
||||
__forceinline vint( const __m256i a ) : v(a) {}
|
||||
__forceinline operator const __m256i&( void ) const { return v; }
|
||||
__forceinline operator __m256i&( void ) { return v; }
|
||||
__forceinline vint(__m256i a) : v(a) {}
|
||||
__forceinline operator const __m256i&() const { return v; }
|
||||
__forceinline operator __m256i&() { return v; }
|
||||
|
||||
__forceinline explicit vint( const vint4& a ) : v(_mm256_insertf128_si256(_mm256_castsi128_si256(a),a,1)) {}
|
||||
__forceinline vint( const vint4& a, const vint4& b ) : v(_mm256_insertf128_si256(_mm256_castsi128_si256(a),b,1)) {}
|
||||
__forceinline vint( const __m128i& a, const __m128i& b ) : vl(a), vh(b) {}
|
||||
__forceinline explicit vint(const vint4& a) : v(_mm256_insertf128_si256(_mm256_castsi128_si256(a),a,1)) {}
|
||||
__forceinline vint(const vint4& a, const vint4& b) : v(_mm256_insertf128_si256(_mm256_castsi128_si256(a),b,1)) {}
|
||||
__forceinline vint(const __m128i& a, const __m128i& b) : vl(a), vh(b) {}
|
||||
|
||||
__forceinline explicit vint ( const int* const a ) : v(_mm256_castps_si256(_mm256_loadu_ps((const float*)a))) {}
|
||||
__forceinline vint ( int a ) : v(_mm256_set1_epi32(a)) {}
|
||||
__forceinline vint ( int a, int b) : v(_mm256_set_epi32(b, a, b, a, b, a, b, a)) {}
|
||||
__forceinline vint ( int a, int b, int c, int d) : v(_mm256_set_epi32(d, c, b, a, d, c, b, a)) {}
|
||||
__forceinline vint ( int a, int b, int c, int d, int e, int f, int g, int vh) : v(_mm256_set_epi32(vh, g, f, e, d, c, b, a)) {}
|
||||
__forceinline explicit vint(const int* a) : v(_mm256_castps_si256(_mm256_loadu_ps((const float*)a))) {}
|
||||
__forceinline vint(int a) : v(_mm256_set1_epi32(a)) {}
|
||||
__forceinline vint(int a, int b) : v(_mm256_set_epi32(b, a, b, a, b, a, b, a)) {}
|
||||
__forceinline vint(int a, int b, int c, int d) : v(_mm256_set_epi32(d, c, b, a, d, c, b, a)) {}
|
||||
__forceinline vint(int a, int b, int c, int d, int e, int f, int g, int vh) : v(_mm256_set_epi32(vh, g, f, e, d, c, b, a)) {}
|
||||
|
||||
__forceinline explicit vint( const __m256 a ) : v(_mm256_cvtps_epi32(a)) {}
|
||||
__forceinline explicit vint(__m256 a) : v(_mm256_cvtps_epi32(a)) {}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Constants
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vint( ZeroTy ) : v(_mm256_setzero_si256()) {}
|
||||
__forceinline vint( OneTy ) : v(_mm256_set_epi32(1,1,1,1,1,1,1,1)) {}
|
||||
__forceinline vint( PosInfTy ) : v(_mm256_set_epi32(pos_inf,pos_inf,pos_inf,pos_inf,pos_inf,pos_inf,pos_inf,pos_inf)) {}
|
||||
__forceinline vint( NegInfTy ) : v(_mm256_set_epi32(neg_inf,neg_inf,neg_inf,neg_inf,neg_inf,neg_inf,neg_inf,neg_inf)) {}
|
||||
__forceinline vint( StepTy ) : v(_mm256_set_epi32(7, 6, 5, 4, 3, 2, 1, 0)) {}
|
||||
__forceinline vint(ZeroTy) : v(_mm256_setzero_si256()) {}
|
||||
__forceinline vint(OneTy) : v(_mm256_set_epi32(1,1,1,1,1,1,1,1)) {}
|
||||
__forceinline vint(PosInfTy) : v(_mm256_set_epi32(pos_inf,pos_inf,pos_inf,pos_inf,pos_inf,pos_inf,pos_inf,pos_inf)) {}
|
||||
__forceinline vint(NegInfTy) : v(_mm256_set_epi32(neg_inf,neg_inf,neg_inf,neg_inf,neg_inf,neg_inf,neg_inf,neg_inf)) {}
|
||||
__forceinline vint(StepTy) : v(_mm256_set_epi32(7, 6, 5, 4, 3, 2, 1, 0)) {}
|
||||
__forceinline vint(UndefinedTy) : v(_mm256_undefined_si256()) {}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Loads and Stores
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static __forceinline vint8 load ( const void* const a) { return _mm256_castps_si256(_mm256_load_ps((float*)a)); }
|
||||
static __forceinline vint8 loadu( const void* const a) { return _mm256_castps_si256(_mm256_loadu_ps((float*)a)); }
|
||||
static __forceinline vint8 load (const void* a) { return _mm256_castps_si256(_mm256_load_ps((float*)a)); }
|
||||
static __forceinline vint8 loadu(const void* a) { return _mm256_castps_si256(_mm256_loadu_ps((float*)a)); }
|
||||
|
||||
static __forceinline vint8 load ( const vboolf8& mask, const void* const a ) { return _mm256_castps_si256(_mm256_maskload_ps((float*)a,mask)); }
|
||||
static __forceinline vint8 loadu( const vboolf8& mask, const void* const a ) { return _mm256_castps_si256(_mm256_maskload_ps((float*)a,mask)); }
|
||||
static __forceinline vint8 load (const vboolf8& mask, const void* a) { return _mm256_castps_si256(_mm256_maskload_ps((float*)a,mask)); }
|
||||
static __forceinline vint8 loadu(const vboolf8& mask, const void* a) { return _mm256_castps_si256(_mm256_maskload_ps((float*)a,mask)); }
|
||||
|
||||
static __forceinline void store ( void* ptr, const vint8& f ) { _mm256_store_ps((float*)ptr,_mm256_castsi256_ps(f)); }
|
||||
static __forceinline void storeu( void* ptr, const vint8& f ) { _mm256_storeu_ps((float*)ptr,_mm256_castsi256_ps(f)); }
|
||||
static __forceinline void store (void* ptr, const vint8& f) { _mm256_store_ps((float*)ptr,_mm256_castsi256_ps(f)); }
|
||||
static __forceinline void storeu(void* ptr, const vint8& f) { _mm256_storeu_ps((float*)ptr,_mm256_castsi256_ps(f)); }
|
||||
|
||||
static __forceinline void store ( const vboolf8& mask, void* ptr, const vint8& f ) { _mm256_maskstore_ps((float*)ptr,(__m256i)mask,_mm256_castsi256_ps(f)); }
|
||||
static __forceinline void storeu( const vboolf8& mask, void* ptr, const vint8& f ) { _mm256_maskstore_ps((float*)ptr,(__m256i)mask,_mm256_castsi256_ps(f)); }
|
||||
static __forceinline void store (const vboolf8& mask, void* ptr, const vint8& f) { _mm256_maskstore_ps((float*)ptr,(__m256i)mask,_mm256_castsi256_ps(f)); }
|
||||
static __forceinline void storeu(const vboolf8& mask, void* ptr, const vint8& f) { _mm256_maskstore_ps((float*)ptr,(__m256i)mask,_mm256_castsi256_ps(f)); }
|
||||
|
||||
static __forceinline void store_nt(void* ptr, const vint8& v) {
|
||||
_mm256_stream_ps((float*)ptr,_mm256_castsi256_ps(v));
|
||||
}
|
||||
|
||||
static __forceinline vint8 load( const unsigned char* const ptr ) {
|
||||
static __forceinline vint8 load(const unsigned char* ptr) {
|
||||
vint4 il = vint4::load(ptr+0);
|
||||
vint4 ih = vint4::load(ptr+4);
|
||||
return vint8(il,ih);
|
||||
}
|
||||
|
||||
static __forceinline vint8 loadu( const unsigned char* const ptr ) {
|
||||
static __forceinline vint8 loadu(const unsigned char* ptr) {
|
||||
vint4 il = vint4::loadu(ptr+0);
|
||||
vint4 ih = vint4::loadu(ptr+4);
|
||||
return vint8(il,ih);
|
||||
}
|
||||
|
||||
static __forceinline vint8 load( const unsigned short* const ptr ) {
|
||||
static __forceinline vint8 load(const unsigned short* ptr) {
|
||||
vint4 il = vint4::load(ptr+0);
|
||||
vint4 ih = vint4::load(ptr+4);
|
||||
return vint8(il,ih);
|
||||
}
|
||||
|
||||
static __forceinline vint8 loadu( const unsigned short* const ptr ) {
|
||||
static __forceinline vint8 loadu(const unsigned short* ptr) {
|
||||
vint4 il = vint4::loadu(ptr+0);
|
||||
vint4 ih = vint4::loadu(ptr+4);
|
||||
return vint8(il,ih);
|
||||
}
|
||||
|
||||
static __forceinline void store_uchar( unsigned char* const ptr, const vint8& i ) {
|
||||
static __forceinline void store(unsigned char* ptr, const vint8& i) {
|
||||
vint4 il(i.vl);
|
||||
vint4 ih(i.vh);
|
||||
vint4::store_uchar(ptr + 0,il);
|
||||
vint4::store_uchar(ptr + 4,ih);
|
||||
vint4::store(ptr + 0,il);
|
||||
vint4::store(ptr + 4,ih);
|
||||
}
|
||||
|
||||
static __forceinline void store_ushort( unsigned short* const ptr, const vint8& v ) {
|
||||
static __forceinline void store(unsigned short* ptr, const vint8& v) {
|
||||
for (size_t i=0;i<8;i++)
|
||||
ptr[i] = (unsigned short)v[i];
|
||||
}
|
||||
|
||||
template<int scale = 4>
|
||||
static __forceinline vint8 gather(const int* ptr, const vint8& index) {
|
||||
return vint8(
|
||||
*(int*)(((char*)ptr)+scale*index[0]),
|
||||
*(int*)(((char*)ptr)+scale*index[1]),
|
||||
*(int*)(((char*)ptr)+scale*index[2]),
|
||||
*(int*)(((char*)ptr)+scale*index[3]),
|
||||
*(int*)(((char*)ptr)+scale*index[4]),
|
||||
*(int*)(((char*)ptr)+scale*index[5]),
|
||||
*(int*)(((char*)ptr)+scale*index[6]),
|
||||
*(int*)(((char*)ptr)+scale*index[7]));
|
||||
}
|
||||
|
||||
static __forceinline vint8 broadcast64(const long long &a) { return _mm256_set1_epi64x(a); }
|
||||
template<int scale = 4>
|
||||
static __forceinline vint8 gather(const vboolf8& mask, const int* ptr, const vint8& index) {
|
||||
vint8 r = zero;
|
||||
if (likely(mask[0])) r[0] = *(int*)(((char*)ptr)+scale*index[0]);
|
||||
if (likely(mask[1])) r[1] = *(int*)(((char*)ptr)+scale*index[1]);
|
||||
if (likely(mask[2])) r[2] = *(int*)(((char*)ptr)+scale*index[2]);
|
||||
if (likely(mask[3])) r[3] = *(int*)(((char*)ptr)+scale*index[3]);
|
||||
if (likely(mask[4])) r[4] = *(int*)(((char*)ptr)+scale*index[4]);
|
||||
if (likely(mask[5])) r[5] = *(int*)(((char*)ptr)+scale*index[5]);
|
||||
if (likely(mask[6])) r[6] = *(int*)(((char*)ptr)+scale*index[6]);
|
||||
if (likely(mask[7])) r[7] = *(int*)(((char*)ptr)+scale*index[7]);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
static __forceinline vint8 broadcast64(const long long& a) { return _mm256_set1_epi64x(a); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Array Access
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const int& operator []( const size_t index ) const { assert(index < 8); return i[index]; }
|
||||
__forceinline int& operator []( const size_t index ) { assert(index < 8); return i[index]; }
|
||||
__forceinline const int& operator [](size_t index) const { assert(index < 8); return i[index]; }
|
||||
__forceinline int& operator [](size_t index) { assert(index < 8); return i[index]; }
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Unary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vint8 operator +( const vint8& a ) { return a; }
|
||||
__forceinline const vint8 operator -( const vint8& a ) { return vint8(_mm_sub_epi32(_mm_setzero_si128(), a.vl), _mm_sub_epi32(_mm_setzero_si128(), a.vh)); }
|
||||
__forceinline const vint8 abs ( const vint8& a ) { return vint8(_mm_abs_epi32(a.vl), _mm_abs_epi32(a.vh)); }
|
||||
__forceinline vint8 operator +(const vint8& a) { return a; }
|
||||
__forceinline vint8 operator -(const vint8& a) { return vint8(_mm_sub_epi32(_mm_setzero_si128(), a.vl), _mm_sub_epi32(_mm_setzero_si128(), a.vh)); }
|
||||
__forceinline vint8 abs (const vint8& a) { return vint8(_mm_abs_epi32(a.vl), _mm_abs_epi32(a.vh)); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Binary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vint8 operator +( const vint8& a, const vint8& b ) { return vint8(_mm_add_epi32(a.vl, b.vl), _mm_add_epi32(a.vh, b.vh)); }
|
||||
__forceinline const vint8 operator +( const vint8& a, const int b ) { return a + vint8(b); }
|
||||
__forceinline const vint8 operator +( const int a, const vint8& b ) { return vint8(a) + b; }
|
||||
__forceinline vint8 operator +(const vint8& a, const vint8& b) { return vint8(_mm_add_epi32(a.vl, b.vl), _mm_add_epi32(a.vh, b.vh)); }
|
||||
__forceinline vint8 operator +(const vint8& a, int b) { return a + vint8(b); }
|
||||
__forceinline vint8 operator +(int a, const vint8& b) { return vint8(a) + b; }
|
||||
|
||||
__forceinline const vint8 operator -( const vint8& a, const vint8& b ) { return vint8(_mm_sub_epi32(a.vl, b.vl), _mm_sub_epi32(a.vh, b.vh)); }
|
||||
__forceinline const vint8 operator -( const vint8& a, const int b ) { return a - vint8(b); }
|
||||
__forceinline const vint8 operator -( const int a, const vint8& b ) { return vint8(a) - b; }
|
||||
__forceinline vint8 operator -(const vint8& a, const vint8& b) { return vint8(_mm_sub_epi32(a.vl, b.vl), _mm_sub_epi32(a.vh, b.vh)); }
|
||||
__forceinline vint8 operator -(const vint8& a, int b) { return a - vint8(b); }
|
||||
__forceinline vint8 operator -(int a, const vint8& b) { return vint8(a) - b; }
|
||||
|
||||
__forceinline const vint8 operator *( const vint8& a, const vint8& b ) { return vint8(_mm_mullo_epi32(a.vl, b.vl), _mm_mullo_epi32(a.vh, b.vh)); }
|
||||
__forceinline const vint8 operator *( const vint8& a, const int b ) { return a * vint8(b); }
|
||||
__forceinline const vint8 operator *( const int a, const vint8& b ) { return vint8(a) * b; }
|
||||
__forceinline vint8 operator *(const vint8& a, const vint8& b) { return vint8(_mm_mullo_epi32(a.vl, b.vl), _mm_mullo_epi32(a.vh, b.vh)); }
|
||||
__forceinline vint8 operator *(const vint8& a, int b) { return a * vint8(b); }
|
||||
__forceinline vint8 operator *(int a, const vint8& b) { return vint8(a) * b; }
|
||||
|
||||
__forceinline const vint8 operator &( const vint8& a, const vint8& b ) { return _mm256_castps_si256(_mm256_and_ps(_mm256_castsi256_ps(a), _mm256_castsi256_ps(b))); }
|
||||
__forceinline const vint8 operator &( const vint8& a, const int b ) { return a & vint8(b); }
|
||||
__forceinline const vint8 operator &( const int a, const vint8& b ) { return vint8(a) & b; }
|
||||
__forceinline vint8 operator &(const vint8& a, const vint8& b) { return _mm256_castps_si256(_mm256_and_ps(_mm256_castsi256_ps(a), _mm256_castsi256_ps(b))); }
|
||||
__forceinline vint8 operator &(const vint8& a, int b) { return a & vint8(b); }
|
||||
__forceinline vint8 operator &(int a, const vint8& b) { return vint8(a) & b; }
|
||||
|
||||
__forceinline const vint8 operator |( const vint8& a, const vint8& b ) { return _mm256_castps_si256(_mm256_or_ps (_mm256_castsi256_ps(a), _mm256_castsi256_ps(b))); }
|
||||
__forceinline const vint8 operator |( const vint8& a, const int b ) { return a | vint8(b); }
|
||||
__forceinline const vint8 operator |( const int a, const vint8& b ) { return vint8(a) | b; }
|
||||
__forceinline vint8 operator |(const vint8& a, const vint8& b) { return _mm256_castps_si256(_mm256_or_ps (_mm256_castsi256_ps(a), _mm256_castsi256_ps(b))); }
|
||||
__forceinline vint8 operator |(const vint8& a, int b) { return a | vint8(b); }
|
||||
__forceinline vint8 operator |(int a, const vint8& b) { return vint8(a) | b; }
|
||||
|
||||
__forceinline const vint8 operator ^( const vint8& a, const vint8& b ) { return _mm256_castps_si256(_mm256_xor_ps(_mm256_castsi256_ps(a), _mm256_castsi256_ps(b))); }
|
||||
__forceinline const vint8 operator ^( const vint8& a, const int b ) { return a ^ vint8(b); }
|
||||
__forceinline const vint8 operator ^( const int a, const vint8& b ) { return vint8(a) ^ b; }
|
||||
__forceinline vint8 operator ^(const vint8& a, const vint8& b) { return _mm256_castps_si256(_mm256_xor_ps(_mm256_castsi256_ps(a), _mm256_castsi256_ps(b))); }
|
||||
__forceinline vint8 operator ^(const vint8& a, int b) { return a ^ vint8(b); }
|
||||
__forceinline vint8 operator ^(int a, const vint8& b) { return vint8(a) ^ b; }
|
||||
|
||||
__forceinline const vint8 operator <<( const vint8& a, const int n ) { return vint8(_mm_slli_epi32(a.vl, n), _mm_slli_epi32(a.vh, n)); }
|
||||
__forceinline const vint8 operator >>( const vint8& a, const int n ) { return vint8(_mm_srai_epi32(a.vl, n), _mm_srai_epi32(a.vh, n)); }
|
||||
__forceinline vint8 operator <<(const vint8& a, int n) { return vint8(_mm_slli_epi32(a.vl, n), _mm_slli_epi32(a.vh, n)); }
|
||||
__forceinline vint8 operator >>(const vint8& a, int n) { return vint8(_mm_srai_epi32(a.vl, n), _mm_srai_epi32(a.vh, n)); }
|
||||
|
||||
__forceinline const vint8 sll ( const vint8& a, const int b ) { return vint8(_mm_slli_epi32(a.vl, b), _mm_slli_epi32(a.vh, b)); }
|
||||
__forceinline const vint8 sra ( const vint8& a, const int b ) { return vint8(_mm_srai_epi32(a.vl, b), _mm_srai_epi32(a.vh, b)); }
|
||||
__forceinline const vint8 srl ( const vint8& a, const int b ) { return vint8(_mm_srli_epi32(a.vl, b), _mm_srli_epi32(a.vh, b)); }
|
||||
__forceinline vint8 sll (const vint8& a, int b) { return vint8(_mm_slli_epi32(a.vl, b), _mm_slli_epi32(a.vh, b)); }
|
||||
__forceinline vint8 sra (const vint8& a, int b) { return vint8(_mm_srai_epi32(a.vl, b), _mm_srai_epi32(a.vh, b)); }
|
||||
__forceinline vint8 srl (const vint8& a, int b) { return vint8(_mm_srli_epi32(a.vl, b), _mm_srli_epi32(a.vh, b)); }
|
||||
|
||||
__forceinline const vint8 min( const vint8& a, const vint8& b ) { return vint8(_mm_min_epi32(a.vl, b.vl), _mm_min_epi32(a.vh, b.vh)); }
|
||||
__forceinline const vint8 min( const vint8& a, const int b ) { return min(a,vint8(b)); }
|
||||
__forceinline const vint8 min( const int a, const vint8& b ) { return min(vint8(a),b); }
|
||||
__forceinline vint8 min(const vint8& a, const vint8& b) { return vint8(_mm_min_epi32(a.vl, b.vl), _mm_min_epi32(a.vh, b.vh)); }
|
||||
__forceinline vint8 min(const vint8& a, int b) { return min(a,vint8(b)); }
|
||||
__forceinline vint8 min(int a, const vint8& b) { return min(vint8(a),b); }
|
||||
|
||||
__forceinline const vint8 max( const vint8& a, const vint8& b ) { return vint8(_mm_max_epi32(a.vl, b.vl), _mm_max_epi32(a.vh, b.vh)); }
|
||||
__forceinline const vint8 max( const vint8& a, const int b ) { return max(a,vint8(b)); }
|
||||
__forceinline const vint8 max( const int a, const vint8& b ) { return max(vint8(a),b); }
|
||||
__forceinline vint8 max(const vint8& a, const vint8& b) { return vint8(_mm_max_epi32(a.vl, b.vl), _mm_max_epi32(a.vh, b.vh)); }
|
||||
__forceinline vint8 max(const vint8& a, int b) { return max(a,vint8(b)); }
|
||||
__forceinline vint8 max(int a, const vint8& b) { return max(vint8(a),b); }
|
||||
|
||||
__forceinline const vint8 umin( const vint8& a, const vint8& b ) { return vint8(_mm_min_epu32(a.vl, b.vl), _mm_min_epu32(a.vh, b.vh)); }
|
||||
__forceinline const vint8 umin( const vint8& a, const int b ) { return umin(a,vint8(b)); }
|
||||
__forceinline const vint8 umin( const int a, const vint8& b ) { return umin(vint8(a),b); }
|
||||
__forceinline vint8 umin(const vint8& a, const vint8& b) { return vint8(_mm_min_epu32(a.vl, b.vl), _mm_min_epu32(a.vh, b.vh)); }
|
||||
__forceinline vint8 umin(const vint8& a, int b) { return umin(a,vint8(b)); }
|
||||
__forceinline vint8 umin(int a, const vint8& b) { return umin(vint8(a),b); }
|
||||
|
||||
__forceinline const vint8 umax( const vint8& a, const vint8& b ) { return vint8(_mm_max_epu32(a.vl, b.vl), _mm_max_epu32(a.vh, b.vh)); }
|
||||
__forceinline const vint8 umax( const vint8& a, const int b ) { return umax(a,vint8(b)); }
|
||||
__forceinline const vint8 umax( const int a, const vint8& b ) { return umax(vint8(a),b); }
|
||||
__forceinline vint8 umax(const vint8& a, const vint8& b) { return vint8(_mm_max_epu32(a.vl, b.vl), _mm_max_epu32(a.vh, b.vh)); }
|
||||
__forceinline vint8 umax(const vint8& a, int b) { return umax(a,vint8(b)); }
|
||||
__forceinline vint8 umax(int a, const vint8& b) { return umax(vint8(a),b); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Assignment Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vint8& operator +=( vint8& a, const vint8& b ) { return a = a + b; }
|
||||
__forceinline vint8& operator +=( vint8& a, const int b ) { return a = a + b; }
|
||||
__forceinline vint8& operator +=(vint8& a, const vint8& b) { return a = a + b; }
|
||||
__forceinline vint8& operator +=(vint8& a, int b) { return a = a + b; }
|
||||
|
||||
__forceinline vint8& operator -=( vint8& a, const vint8& b ) { return a = a - b; }
|
||||
__forceinline vint8& operator -=( vint8& a, const int b ) { return a = a - b; }
|
||||
__forceinline vint8& operator -=(vint8& a, const vint8& b) { return a = a - b; }
|
||||
__forceinline vint8& operator -=(vint8& a, int b) { return a = a - b; }
|
||||
|
||||
__forceinline vint8& operator *=( vint8& a, const vint8& b ) { return a = a * b; }
|
||||
__forceinline vint8& operator *=( vint8& a, const int b ) { return a = a * b; }
|
||||
__forceinline vint8& operator *=(vint8& a, const vint8& b) { return a = a * b; }
|
||||
__forceinline vint8& operator *=(vint8& a, int b) { return a = a * b; }
|
||||
|
||||
__forceinline vint8& operator &=( vint8& a, const vint8& b ) { return a = a & b; }
|
||||
__forceinline vint8& operator &=( vint8& a, const int b ) { return a = a & b; }
|
||||
__forceinline vint8& operator &=(vint8& a, const vint8& b) { return a = a & b; }
|
||||
__forceinline vint8& operator &=(vint8& a, int b) { return a = a & b; }
|
||||
|
||||
__forceinline vint8& operator |=( vint8& a, const vint8& b ) { return a = a | b; }
|
||||
__forceinline vint8& operator |=( vint8& a, const int b ) { return a = a | b; }
|
||||
__forceinline vint8& operator |=(vint8& a, const vint8& b) { return a = a | b; }
|
||||
__forceinline vint8& operator |=(vint8& a, int b) { return a = a | b; }
|
||||
|
||||
__forceinline vint8& operator <<=( vint8& a, const int b ) { return a = a << b; }
|
||||
__forceinline vint8& operator >>=( vint8& a, const int b ) { return a = a >> b; }
|
||||
__forceinline vint8& operator <<=(vint8& a, int b) { return a = a << b; }
|
||||
__forceinline vint8& operator >>=(vint8& a, int b) { return a = a >> b; }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Comparison Operators + Select
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vboolf8 operator ==( const vint8& a, const vint8& b ) { return vboolf8(_mm_castsi128_ps(_mm_cmpeq_epi32 (a.vl, b.vl)),
|
||||
__forceinline vboolf8 operator ==(const vint8& a, const vint8& b) { return vboolf8(_mm_castsi128_ps(_mm_cmpeq_epi32 (a.vl, b.vl)),
|
||||
_mm_castsi128_ps(_mm_cmpeq_epi32 (a.vh, b.vh))); }
|
||||
__forceinline const vboolf8 operator ==( const vint8& a, const int b ) { return a == vint8(b); }
|
||||
__forceinline const vboolf8 operator ==( const int a, const vint8& b ) { return vint8(a) == b; }
|
||||
__forceinline vboolf8 operator ==(const vint8& a, int b) { return a == vint8(b); }
|
||||
__forceinline vboolf8 operator ==(int a, const vint8& b) { return vint8(a) == b; }
|
||||
|
||||
__forceinline const vboolf8 operator !=( const vint8& a, const vint8& b ) { return !(a == b); }
|
||||
__forceinline const vboolf8 operator !=( const vint8& a, const int b ) { return a != vint8(b); }
|
||||
__forceinline const vboolf8 operator !=( const int a, const vint8& b ) { return vint8(a) != b; }
|
||||
__forceinline vboolf8 operator !=(const vint8& a, const vint8& b) { return !(a == b); }
|
||||
__forceinline vboolf8 operator !=(const vint8& a, int b) { return a != vint8(b); }
|
||||
__forceinline vboolf8 operator !=(int a, const vint8& b) { return vint8(a) != b; }
|
||||
|
||||
__forceinline const vboolf8 operator < ( const vint8& a, const vint8& b ) { return vboolf8(_mm_castsi128_ps(_mm_cmplt_epi32 (a.vl, b.vl)),
|
||||
__forceinline vboolf8 operator < (const vint8& a, const vint8& b) { return vboolf8(_mm_castsi128_ps(_mm_cmplt_epi32 (a.vl, b.vl)),
|
||||
_mm_castsi128_ps(_mm_cmplt_epi32 (a.vh, b.vh))); }
|
||||
__forceinline const vboolf8 operator < ( const vint8& a, const int b ) { return a < vint8(b); }
|
||||
__forceinline const vboolf8 operator < ( const int a, const vint8& b ) { return vint8(a) < b; }
|
||||
__forceinline vboolf8 operator < (const vint8& a, int b) { return a < vint8(b); }
|
||||
__forceinline vboolf8 operator < (int a, const vint8& b) { return vint8(a) < b; }
|
||||
|
||||
__forceinline const vboolf8 operator >=( const vint8& a, const vint8& b ) { return !(a < b); }
|
||||
__forceinline const vboolf8 operator >=( const vint8& a, const int b ) { return a >= vint8(b); }
|
||||
__forceinline const vboolf8 operator >=( const int a, const vint8& b ) { return vint8(a) >= b; }
|
||||
__forceinline vboolf8 operator >=(const vint8& a, const vint8& b) { return !(a < b); }
|
||||
__forceinline vboolf8 operator >=(const vint8& a, int b) { return a >= vint8(b); }
|
||||
__forceinline vboolf8 operator >=(int a, const vint8& b) { return vint8(a) >= b; }
|
||||
|
||||
__forceinline const vboolf8 operator > ( const vint8& a, const vint8& b ) { return vboolf8(_mm_castsi128_ps(_mm_cmpgt_epi32 (a.vl, b.vl)),
|
||||
__forceinline vboolf8 operator > (const vint8& a, const vint8& b) { return vboolf8(_mm_castsi128_ps(_mm_cmpgt_epi32 (a.vl, b.vl)),
|
||||
_mm_castsi128_ps(_mm_cmpgt_epi32 (a.vh, b.vh))); }
|
||||
__forceinline const vboolf8 operator > ( const vint8& a, const int b ) { return a > vint8(b); }
|
||||
__forceinline const vboolf8 operator > ( const int a, const vint8& b ) { return vint8(a) > b; }
|
||||
__forceinline vboolf8 operator > (const vint8& a, int b) { return a > vint8(b); }
|
||||
__forceinline vboolf8 operator > (int a, const vint8& b) { return vint8(a) > b; }
|
||||
|
||||
__forceinline const vboolf8 operator <=( const vint8& a, const vint8& b ) { return !(a > b); }
|
||||
__forceinline const vboolf8 operator <=( const vint8& a, const int b ) { return a <= vint8(b); }
|
||||
__forceinline const vboolf8 operator <=( const int a, const vint8& b ) { return vint8(a) <= b; }
|
||||
__forceinline vboolf8 operator <=(const vint8& a, const vint8& b) { return !(a > b); }
|
||||
__forceinline vboolf8 operator <=(const vint8& a, int b) { return a <= vint8(b); }
|
||||
__forceinline vboolf8 operator <=(int a, const vint8& b) { return vint8(a) <= b; }
|
||||
|
||||
__forceinline vboolf8 eq(const vint8& a, const vint8& b) { return a == b; }
|
||||
__forceinline vboolf8 ne(const vint8& a, const vint8& b) { return a != b; }
|
||||
@@ -260,11 +288,11 @@ namespace embree
|
||||
__forceinline vboolf8 gt(const vboolf8& mask, const vint8& a, const vint8& b) { return mask & (a > b); }
|
||||
__forceinline vboolf8 le(const vboolf8& mask, const vint8& a, const vint8& b) { return mask & (a <= b); }
|
||||
|
||||
__forceinline const vint8 select( const vboolf8& m, const vint8& t, const vint8& f ) {
|
||||
__forceinline vint8 select(const vboolf8& m, const vint8& t, const vint8& f) {
|
||||
return _mm256_castps_si256(_mm256_blendv_ps(_mm256_castsi256_ps(f), _mm256_castsi256_ps(t), m));
|
||||
}
|
||||
|
||||
__forceinline const vint8 notand( const vboolf8& m, const vint8& f) {
|
||||
__forceinline vint8 notand(const vboolf8& m, const vint8& f) {
|
||||
return _mm256_castps_si256(_mm256_andnot_ps(m, _mm256_castsi256_ps(f)));
|
||||
}
|
||||
|
||||
@@ -273,56 +301,61 @@ namespace embree
|
||||
/// Movement/Shifting/Shuffling Functions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vint8 unpacklo( const vint8& a, const vint8& b ) { return _mm256_castps_si256(_mm256_unpacklo_ps(_mm256_castsi256_ps(a), _mm256_castsi256_ps(b))); }
|
||||
__forceinline vint8 unpackhi( const vint8& a, const vint8& b ) { return _mm256_castps_si256(_mm256_unpackhi_ps(_mm256_castsi256_ps(a), _mm256_castsi256_ps(b))); }
|
||||
__forceinline vint8 unpacklo(const vint8& a, const vint8& b) { return _mm256_castps_si256(_mm256_unpacklo_ps(_mm256_castsi256_ps(a), _mm256_castsi256_ps(b))); }
|
||||
__forceinline vint8 unpackhi(const vint8& a, const vint8& b) { return _mm256_castps_si256(_mm256_unpackhi_ps(_mm256_castsi256_ps(a), _mm256_castsi256_ps(b))); }
|
||||
|
||||
template<size_t i> __forceinline const vint8 shuffle( const vint8& a ) {
|
||||
return _mm256_castps_si256(_mm256_permute_ps(_mm256_castsi256_ps(a), _MM_SHUFFLE(i, i, i, i)));
|
||||
template<int i>
|
||||
__forceinline vint8 shuffle(const vint8& v) {
|
||||
return _mm256_castps_si256(_mm256_permute_ps(_mm256_castsi256_ps(v), _MM_SHUFFLE(i, i, i, i)));
|
||||
}
|
||||
|
||||
template<size_t i0, size_t i1> __forceinline const vint8 shuffle4( const vint8& a ) {
|
||||
return _mm256_permute2f128_si256(a, a, (i1 << 4) | (i0 << 0));
|
||||
template<int i0, int i1>
|
||||
__forceinline vint8 shuffle4(const vint8& v) {
|
||||
return _mm256_permute2f128_si256(v, v, (i1 << 4) | (i0 << 0));
|
||||
}
|
||||
|
||||
template<size_t i0, size_t i1> __forceinline const vint8 shuffle4( const vint8& a, const vint8& b) {
|
||||
template<int i0, int i1>
|
||||
__forceinline vint8 shuffle4(const vint8& a, const vint8& b) {
|
||||
return _mm256_permute2f128_si256(a, b, (i1 << 4) | (i0 << 0));
|
||||
}
|
||||
|
||||
template<size_t i0, size_t i1, size_t i2, size_t i3> __forceinline const vint8 shuffle( const vint8& a ) {
|
||||
return _mm256_castps_si256(_mm256_permute_ps(_mm256_castsi256_ps(a), _MM_SHUFFLE(i3, i2, i1, i0)));
|
||||
template<int i0, int i1, int i2, int i3>
|
||||
__forceinline vint8 shuffle(const vint8& v) {
|
||||
return _mm256_castps_si256(_mm256_permute_ps(_mm256_castsi256_ps(v), _MM_SHUFFLE(i3, i2, i1, i0)));
|
||||
}
|
||||
|
||||
template<size_t i0, size_t i1, size_t i2, size_t i3> __forceinline const vint8 shuffle( const vint8& a, const vint8& b ) {
|
||||
template<int i0, int i1, int i2, int i3>
|
||||
__forceinline vint8 shuffle(const vint8& a, const vint8& b) {
|
||||
return _mm256_castps_si256(_mm256_shuffle_ps(_mm256_castsi256_ps(a), _mm256_castsi256_ps(b), _MM_SHUFFLE(i3, i2, i1, i0)));
|
||||
}
|
||||
|
||||
template<> __forceinline const vint8 shuffle<0, 0, 2, 2>( const vint8& b ) { return _mm256_castps_si256(_mm256_moveldup_ps(_mm256_castsi256_ps(b))); }
|
||||
template<> __forceinline const vint8 shuffle<1, 1, 3, 3>( const vint8& b ) { return _mm256_castps_si256(_mm256_movehdup_ps(_mm256_castsi256_ps(b))); }
|
||||
template<> __forceinline const vint8 shuffle<0, 1, 0, 1>( const vint8& b ) { return _mm256_castps_si256(_mm256_castpd_ps(_mm256_movedup_pd(_mm256_castps_pd(_mm256_castsi256_ps(b))))); }
|
||||
template<> __forceinline vint8 shuffle<0, 0, 2, 2>(const vint8& v) { return _mm256_castps_si256(_mm256_moveldup_ps(_mm256_castsi256_ps(v))); }
|
||||
template<> __forceinline vint8 shuffle<1, 1, 3, 3>(const vint8& v) { return _mm256_castps_si256(_mm256_movehdup_ps(_mm256_castsi256_ps(v))); }
|
||||
template<> __forceinline vint8 shuffle<0, 1, 0, 1>(const vint8& v) { return _mm256_castps_si256(_mm256_castpd_ps(_mm256_movedup_pd(_mm256_castps_pd(_mm256_castsi256_ps(v))))); }
|
||||
|
||||
__forceinline const vint8 broadcast(const int* ptr) { return _mm256_castps_si256(_mm256_broadcast_ss((const float*)ptr)); }
|
||||
template<size_t i> __forceinline const vint8 insert4(const vint8& a, const vint4& b) { return _mm256_insertf128_si256(a, b, i); }
|
||||
template<size_t i> __forceinline const vint4 extract4 (const vint8& a) { return _mm256_extractf128_si256(a, i); }
|
||||
template<> __forceinline const vint4 extract4<0>(const vint8& a) { return _mm256_castsi256_si128(a); }
|
||||
__forceinline vint8 broadcast(const int* ptr) { return _mm256_castps_si256(_mm256_broadcast_ss((const float*)ptr)); }
|
||||
template<int i> __forceinline vint8 insert4(const vint8& a, const vint4& b) { return _mm256_insertf128_si256(a, b, i); }
|
||||
template<int i> __forceinline vint4 extract4(const vint8& a) { return _mm256_extractf128_si256(a, i); }
|
||||
template<> __forceinline vint4 extract4<0>(const vint8& a) { return _mm256_castsi256_si128(a); }
|
||||
|
||||
__forceinline int toScalar(const vint8& a) { return _mm_cvtsi128_si32(_mm256_castsi256_si128(a)); }
|
||||
__forceinline int toScalar(const vint8& v) { return _mm_cvtsi128_si32(_mm256_castsi256_si128(v)); }
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Reductions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vint8 vreduce_min2(const vint8& v) { return min(v,shuffle<1,0,3,2>(v)); }
|
||||
__forceinline const vint8 vreduce_min4(const vint8& v) { vint8 v1 = vreduce_min2(v); return min(v1,shuffle<2,3,0,1>(v1)); }
|
||||
__forceinline const vint8 vreduce_min (const vint8& v) { vint8 v1 = vreduce_min4(v); return min(v1,shuffle4<1,0>(v1)); }
|
||||
__forceinline vint8 vreduce_min2(const vint8& v) { return min(v,shuffle<1,0,3,2>(v)); }
|
||||
__forceinline vint8 vreduce_min4(const vint8& v) { vint8 v1 = vreduce_min2(v); return min(v1,shuffle<2,3,0,1>(v1)); }
|
||||
__forceinline vint8 vreduce_min (const vint8& v) { vint8 v1 = vreduce_min4(v); return min(v1,shuffle4<1,0>(v1)); }
|
||||
|
||||
__forceinline const vint8 vreduce_max2(const vint8& v) { return max(v,shuffle<1,0,3,2>(v)); }
|
||||
__forceinline const vint8 vreduce_max4(const vint8& v) { vint8 v1 = vreduce_max2(v); return max(v1,shuffle<2,3,0,1>(v1)); }
|
||||
__forceinline const vint8 vreduce_max (const vint8& v) { vint8 v1 = vreduce_max4(v); return max(v1,shuffle4<1,0>(v1)); }
|
||||
__forceinline vint8 vreduce_max2(const vint8& v) { return max(v,shuffle<1,0,3,2>(v)); }
|
||||
__forceinline vint8 vreduce_max4(const vint8& v) { vint8 v1 = vreduce_max2(v); return max(v1,shuffle<2,3,0,1>(v1)); }
|
||||
__forceinline vint8 vreduce_max (const vint8& v) { vint8 v1 = vreduce_max4(v); return max(v1,shuffle4<1,0>(v1)); }
|
||||
|
||||
__forceinline const vint8 vreduce_add2(const vint8& v) { return v + shuffle<1,0,3,2>(v); }
|
||||
__forceinline const vint8 vreduce_add4(const vint8& v) { vint8 v1 = vreduce_add2(v); return v1 + shuffle<2,3,0,1>(v1); }
|
||||
__forceinline const vint8 vreduce_add (const vint8& v) { vint8 v1 = vreduce_add4(v); return v1 + shuffle4<1,0>(v1); }
|
||||
__forceinline vint8 vreduce_add2(const vint8& v) { return v + shuffle<1,0,3,2>(v); }
|
||||
__forceinline vint8 vreduce_add4(const vint8& v) { vint8 v1 = vreduce_add2(v); return v1 + shuffle<2,3,0,1>(v1); }
|
||||
__forceinline vint8 vreduce_add (const vint8& v) { vint8 v1 = vreduce_add4(v); return v1 + shuffle4<1,0>(v1); }
|
||||
|
||||
__forceinline int reduce_min(const vint8& v) { return toScalar(vreduce_min(v)); }
|
||||
__forceinline int reduce_max(const vint8& v) { return toScalar(vreduce_max(v)); }
|
||||
@@ -402,7 +435,7 @@ namespace embree
|
||||
/// Output Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& cout, const vint8& a) {
|
||||
inline std::ostream& operator <<(std::ostream& cout, const vint8& a) {
|
||||
return cout << "<" << a[0] << ", " << a[1] << ", " << a[2] << ", " << a[3] << ", " << a[4] << ", " << a[5] << ", " << a[6] << ", " << a[7] << ">";
|
||||
}
|
||||
}
|
||||
+188
-158
@@ -36,82 +36,89 @@ namespace embree
|
||||
/// Constructors, Assignment & Cast Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vint ( ) {}
|
||||
__forceinline vint ( const vint8& a ) { v = a.v; }
|
||||
__forceinline vint8& operator=( const vint8& a ) { v = a.v; return *this; }
|
||||
__forceinline vint() {}
|
||||
__forceinline vint(const vint8& a) { v = a.v; }
|
||||
__forceinline vint8& operator =(const vint8& a) { v = a.v; return *this; }
|
||||
|
||||
__forceinline vint( const __m256i a ) : v(a) {}
|
||||
__forceinline operator const __m256i&( void ) const { return v; }
|
||||
__forceinline operator __m256i&( void ) { return v; }
|
||||
__forceinline vint(__m256i a) : v(a) {}
|
||||
__forceinline operator const __m256i&() const { return v; }
|
||||
__forceinline operator __m256i&() { return v; }
|
||||
|
||||
__forceinline explicit vint( const vint4& a ) : v(_mm256_insertf128_si256(_mm256_castsi128_si256(a),a,1)) {}
|
||||
__forceinline vint( const vint4& a, const vint4& b ) : v(_mm256_insertf128_si256(_mm256_castsi128_si256(a),b,1)) {}
|
||||
__forceinline vint( const __m128i& a, const __m128i& b ) : v(_mm256_insertf128_si256(_mm256_castsi128_si256(a),b,1)) {}
|
||||
__forceinline explicit vint(const vint4& a) : v(_mm256_insertf128_si256(_mm256_castsi128_si256(a),a,1)) {}
|
||||
__forceinline vint(const vint4& a, const vint4& b) : v(_mm256_insertf128_si256(_mm256_castsi128_si256(a),b,1)) {}
|
||||
__forceinline vint(const __m128i& a, const __m128i& b) : v(_mm256_insertf128_si256(_mm256_castsi128_si256(a),b,1)) {}
|
||||
|
||||
__forceinline explicit vint ( const int* const a ) : v(_mm256_castps_si256(_mm256_loadu_ps((const float*)a))) {}
|
||||
__forceinline vint ( int a ) : v(_mm256_set1_epi32(a)) {}
|
||||
__forceinline vint ( int a, int b) : v(_mm256_set_epi32(b, a, b, a, b, a, b, a)) {}
|
||||
__forceinline vint ( int a, int b, int c, int d) : v(_mm256_set_epi32(d, c, b, a, d, c, b, a)) {}
|
||||
__forceinline vint ( int a, int b, int c, int d, int e, int f, int g, int h) : v(_mm256_set_epi32(h, g, f, e, d, c, b, a)) {}
|
||||
__forceinline explicit vint(const int* a) : v(_mm256_castps_si256(_mm256_loadu_ps((const float*)a))) {}
|
||||
__forceinline vint(int a) : v(_mm256_set1_epi32(a)) {}
|
||||
__forceinline vint(int a, int b) : v(_mm256_set_epi32(b, a, b, a, b, a, b, a)) {}
|
||||
__forceinline vint(int a, int b, int c, int d) : v(_mm256_set_epi32(d, c, b, a, d, c, b, a)) {}
|
||||
__forceinline vint(int a, int b, int c, int d, int e, int f, int g, int h) : v(_mm256_set_epi32(h, g, f, e, d, c, b, a)) {}
|
||||
|
||||
__forceinline explicit vint( const __m256 a ) : v(_mm256_cvtps_epi32(a)) {}
|
||||
__forceinline explicit vint(__m256 a) : v(_mm256_cvtps_epi32(a)) {}
|
||||
|
||||
#if defined(__AVX512VL__)
|
||||
__forceinline explicit vint( const vboolf8 &a ) : v(_mm256_movm_epi32(a)) {}
|
||||
__forceinline explicit vint(const vboolf8& a) : v(_mm256_movm_epi32(a)) {}
|
||||
#else
|
||||
__forceinline explicit vint( const vboolf8 &a ) : v(_mm256_castps_si256((__m256)a)) {}
|
||||
__forceinline explicit vint(const vboolf8& a) : v(_mm256_castps_si256((__m256)a)) {}
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Constants
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vint( ZeroTy ) : v(_mm256_setzero_si256()) {}
|
||||
__forceinline vint( OneTy ) : v(_mm256_set1_epi32(1)) {}
|
||||
__forceinline vint( PosInfTy ) : v(_mm256_set1_epi32(pos_inf)) {}
|
||||
__forceinline vint( NegInfTy ) : v(_mm256_set1_epi32(neg_inf)) {}
|
||||
__forceinline vint( StepTy ) : v(_mm256_set_epi32(7, 6, 5, 4, 3, 2, 1, 0)) {}
|
||||
__forceinline vint(ZeroTy) : v(_mm256_setzero_si256()) {}
|
||||
__forceinline vint(OneTy) : v(_mm256_set1_epi32(1)) {}
|
||||
__forceinline vint(PosInfTy) : v(_mm256_set1_epi32(pos_inf)) {}
|
||||
__forceinline vint(NegInfTy) : v(_mm256_set1_epi32(neg_inf)) {}
|
||||
__forceinline vint(StepTy) : v(_mm256_set_epi32(7, 6, 5, 4, 3, 2, 1, 0)) {}
|
||||
__forceinline vint(UndefinedTy) : v(_mm256_undefined_si256()) {}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Loads and Stores
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static __forceinline const vint8 load( const unsigned char* const ptr ) { return _mm256_cvtepu8_epi32(_mm_load_si128((__m128i*)ptr)); }
|
||||
static __forceinline const vint8 loadu( const unsigned char* const ptr ) { return _mm256_cvtepu8_epi32(_mm_loadu_si128((__m128i*)ptr)); }
|
||||
static __forceinline const vint8 load( const unsigned short* const ptr ) { return _mm256_cvtepu16_epi32(_mm_load_si128((__m128i*)ptr)); }
|
||||
static __forceinline const vint8 loadu( const unsigned short* const ptr ) { return _mm256_cvtepu16_epi32(_mm_loadu_si128((__m128i*)ptr)); }
|
||||
static __forceinline vint8 load(const unsigned char* ptr) { return _mm256_cvtepu8_epi32(_mm_load_si128((__m128i*)ptr)); }
|
||||
static __forceinline vint8 loadu(const unsigned char* ptr) { return _mm256_cvtepu8_epi32(_mm_loadu_si128((__m128i*)ptr)); }
|
||||
static __forceinline vint8 load(const unsigned short* ptr) { return _mm256_cvtepu16_epi32(_mm_load_si128((__m128i*)ptr)); }
|
||||
static __forceinline vint8 loadu(const unsigned short* ptr) { return _mm256_cvtepu16_epi32(_mm_loadu_si128((__m128i*)ptr)); }
|
||||
|
||||
static __forceinline const vint8 load( const void* const ptr ) { return _mm256_load_si256((__m256i*)ptr); }
|
||||
static __forceinline const vint8 loadu(const void* const ptr ) { return _mm256_loadu_si256((__m256i*)ptr); }
|
||||
static __forceinline vint8 load(const void* ptr) { return _mm256_load_si256((__m256i*)ptr); }
|
||||
static __forceinline vint8 loadu(const void* ptr) { return _mm256_loadu_si256((__m256i*)ptr); }
|
||||
|
||||
static __forceinline void store ( void* ptr, const vint8& v ) { _mm256_store_si256((__m256i*)ptr,v); }
|
||||
static __forceinline void storeu( void* ptr, const vint8& v ) { _mm256_storeu_ps((float*)ptr,_mm256_castsi256_ps(v)); }
|
||||
static __forceinline void store (void* ptr, const vint8& v) { _mm256_store_si256((__m256i*)ptr,v); }
|
||||
static __forceinline void storeu(void* ptr, const vint8& v) { _mm256_storeu_ps((float*)ptr,_mm256_castsi256_ps(v)); }
|
||||
|
||||
#if defined(__AVX512VL__)
|
||||
static __forceinline vint8 load ( const vboolf8& mask, const void* const ptr ) { return _mm256_mask_load_epi32 (_mm256_setzero_si256(),mask,ptr); }
|
||||
static __forceinline vint8 loadu( const vboolf8& mask, const void* const ptr ) { return _mm256_mask_loadu_epi32(_mm256_setzero_si256(),mask,ptr); }
|
||||
|
||||
static __forceinline void store ( const vboolf8& mask, void* ptr, const vint8& v ) { _mm256_mask_store_epi32 (ptr,mask,v); }
|
||||
static __forceinline void storeu( const vboolf8& mask, void* ptr, const vint8& v ) { _mm256_mask_storeu_epi32(ptr,mask,v); }
|
||||
static __forceinline vint8 compact(const vboolf8& mask, vint8 &v) {
|
||||
return _mm256_mask_compress_epi32(v, mask, v);
|
||||
}
|
||||
static __forceinline vint8 compact(const vboolf8& mask, vint8 &a, const vint8& b) {
|
||||
return _mm256_mask_compress_epi32(a, mask, b);
|
||||
}
|
||||
|
||||
static __forceinline vint8 load (const vboolf8& mask, const void* ptr) { return _mm256_mask_load_epi32 (_mm256_setzero_si256(),mask,ptr); }
|
||||
static __forceinline vint8 loadu(const vboolf8& mask, const void* ptr) { return _mm256_mask_loadu_epi32(_mm256_setzero_si256(),mask,ptr); }
|
||||
|
||||
static __forceinline void store (const vboolf8& mask, void* ptr, const vint8& v) { _mm256_mask_store_epi32 (ptr,mask,v); }
|
||||
static __forceinline void storeu(const vboolf8& mask, void* ptr, const vint8& v) { _mm256_mask_storeu_epi32(ptr,mask,v); }
|
||||
#else
|
||||
static __forceinline vint8 load ( const vboolf8& mask, const void* const ptr ) { return _mm256_castps_si256(_mm256_maskload_ps((float*)ptr,mask)); }
|
||||
static __forceinline vint8 loadu( const vboolf8& mask, const void* const ptr ) { return _mm256_castps_si256(_mm256_maskload_ps((float*)ptr,mask)); }
|
||||
static __forceinline vint8 load (const vboolf8& mask, const void* ptr) { return _mm256_castps_si256(_mm256_maskload_ps((float*)ptr,mask)); }
|
||||
static __forceinline vint8 loadu(const vboolf8& mask, const void* ptr) { return _mm256_castps_si256(_mm256_maskload_ps((float*)ptr,mask)); }
|
||||
|
||||
static __forceinline void store ( const vboolf8& mask, void* ptr, const vint8& v ) { _mm256_maskstore_epi32((int*)ptr,mask,v); }
|
||||
static __forceinline void storeu( const vboolf8& mask, void* ptr, const vint8& v ) { _mm256_maskstore_epi32((int*)ptr,mask,v); }
|
||||
static __forceinline void store (const vboolf8& mask, void* ptr, const vint8& v) { _mm256_maskstore_epi32((int*)ptr,mask,v); }
|
||||
static __forceinline void storeu(const vboolf8& mask, void* ptr, const vint8& v) { _mm256_maskstore_epi32((int*)ptr,mask,v); }
|
||||
#endif
|
||||
|
||||
#if defined (__AVX2__)
|
||||
static __forceinline vint8 load_nt(void* ptr) {
|
||||
return _mm256_stream_load_si256((__m256i*)ptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
static __forceinline void store_nt(void* ptr, const vint8& v) {
|
||||
_mm256_stream_ps((float*)ptr,_mm256_castsi256_ps(v));
|
||||
}
|
||||
|
||||
static __forceinline void store_uchar( unsigned char* const ptr, const vint8& i ) {
|
||||
static __forceinline void store(unsigned char* ptr, const vint8& i) {
|
||||
__m256i x = i;
|
||||
x = _mm256_packus_epi32(x, x);
|
||||
x = _mm256_packus_epi16(x, x);
|
||||
@@ -123,154 +130,169 @@ namespace embree
|
||||
#endif
|
||||
}
|
||||
|
||||
static __forceinline void store_ushort( unsigned short* const ptr, const vint8& v ) {
|
||||
static __forceinline void store(unsigned short* ptr, const vint8& v) {
|
||||
for (size_t i=0;i<8;i++)
|
||||
ptr[i] = (unsigned short)v[i];
|
||||
}
|
||||
|
||||
template<int scale = 4>
|
||||
static __forceinline vint8 gather(const int *const ptr, const vint8& index) {
|
||||
return _mm256_i32gather_epi32(ptr, index, scale);
|
||||
}
|
||||
|
||||
template<int scale = 4>
|
||||
static __forceinline vint8 gather(const vboolf8& mask, const int *const ptr, const vint8& index) {
|
||||
vint8 r = zero;
|
||||
#if defined(__AVX512VL__)
|
||||
return _mm256_mmask_i32gather_epi32(r, mask, index, ptr, scale);
|
||||
#else
|
||||
return _mm256_mask_i32gather_epi32(r, ptr, index, mask, scale);
|
||||
#endif
|
||||
}
|
||||
|
||||
static __forceinline vint8 broadcast64(const long long &a) { return _mm256_set1_epi64x(a); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Array Access
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const int& operator []( const size_t index ) const { assert(index < 8); return i[index]; }
|
||||
__forceinline int& operator []( const size_t index ) { assert(index < 8); return i[index]; }
|
||||
__forceinline const int& operator [](size_t index) const { assert(index < 8); return i[index]; }
|
||||
__forceinline int& operator [](size_t index) { assert(index < 8); return i[index]; }
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Unary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vint8 operator +( const vint8& a ) { return a; }
|
||||
__forceinline const vint8 operator -( const vint8& a ) { return _mm256_sub_epi32(_mm256_setzero_si256(), a.v); }
|
||||
__forceinline const vint8 abs ( const vint8& a ) { return _mm256_abs_epi32(a.v); }
|
||||
__forceinline vint8 operator +(const vint8& a) { return a; }
|
||||
__forceinline vint8 operator -(const vint8& a) { return _mm256_sub_epi32(_mm256_setzero_si256(), a); }
|
||||
__forceinline vint8 abs (const vint8& a) { return _mm256_abs_epi32(a); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Binary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vint8 operator +( const vint8& a, const vint8& b ) { return _mm256_add_epi32(a.v, b.v); }
|
||||
__forceinline const vint8 operator +( const vint8& a, const int b ) { return a + vint8(b); }
|
||||
__forceinline const vint8 operator +( const int a, const vint8& b ) { return vint8(a) + b; }
|
||||
__forceinline vint8 operator +(const vint8& a, const vint8& b) { return _mm256_add_epi32(a, b); }
|
||||
__forceinline vint8 operator +(const vint8& a, int b) { return a + vint8(b); }
|
||||
__forceinline vint8 operator +(int a, const vint8& b) { return vint8(a) + b; }
|
||||
|
||||
__forceinline const vint8 operator -( const vint8& a, const vint8& b ) { return _mm256_sub_epi32(a.v, b.v); }
|
||||
__forceinline const vint8 operator -( const vint8& a, const int b ) { return a - vint8(b); }
|
||||
__forceinline const vint8 operator -( const int a, const vint8& b ) { return vint8(a) - b; }
|
||||
__forceinline vint8 operator -(const vint8& a, const vint8& b) { return _mm256_sub_epi32(a, b); }
|
||||
__forceinline vint8 operator -(const vint8& a, int b) { return a - vint8(b); }
|
||||
__forceinline vint8 operator -(int a, const vint8& b) { return vint8(a) - b; }
|
||||
|
||||
__forceinline const vint8 operator *( const vint8& a, const vint8& b ) { return _mm256_mullo_epi32(a.v, b.v); }
|
||||
__forceinline const vint8 operator *( const vint8& a, const int b ) { return a * vint8(b); }
|
||||
__forceinline const vint8 operator *( const int a, const vint8& b ) { return vint8(a) * b; }
|
||||
__forceinline vint8 operator *(const vint8& a, const vint8& b) { return _mm256_mullo_epi32(a, b); }
|
||||
__forceinline vint8 operator *(const vint8& a, int b) { return a * vint8(b); }
|
||||
__forceinline vint8 operator *(int a, const vint8& b) { return vint8(a) * b; }
|
||||
|
||||
__forceinline const vint8 operator &( const vint8& a, const vint8& b ) { return _mm256_and_si256(a.v, b.v); }
|
||||
__forceinline const vint8 operator &( const vint8& a, const int b ) { return a & vint8(b); }
|
||||
__forceinline const vint8 operator &( const int a, const vint8& b ) { return vint8(a) & b; }
|
||||
__forceinline vint8 operator &(const vint8& a, const vint8& b) { return _mm256_and_si256(a, b); }
|
||||
__forceinline vint8 operator &(const vint8& a, int b) { return a & vint8(b); }
|
||||
__forceinline vint8 operator &(int a, const vint8& b) { return vint8(a) & b; }
|
||||
|
||||
__forceinline const vint8 operator |( const vint8& a, const vint8& b ) { return _mm256_or_si256(a.v, b.v); }
|
||||
__forceinline const vint8 operator |( const vint8& a, const int b ) { return a | vint8(b); }
|
||||
__forceinline const vint8 operator |( const int a, const vint8& b ) { return vint8(a) | b; }
|
||||
__forceinline vint8 operator |(const vint8& a, const vint8& b) { return _mm256_or_si256(a, b); }
|
||||
__forceinline vint8 operator |(const vint8& a, int b) { return a | vint8(b); }
|
||||
__forceinline vint8 operator |(int a, const vint8& b) { return vint8(a) | b; }
|
||||
|
||||
__forceinline const vint8 operator ^( const vint8& a, const vint8& b ) { return _mm256_xor_si256(a.v, b.v); }
|
||||
__forceinline const vint8 operator ^( const vint8& a, const int b ) { return a ^ vint8(b); }
|
||||
__forceinline const vint8 operator ^( const int a, const vint8& b ) { return vint8(a) ^ b; }
|
||||
__forceinline vint8 operator ^(const vint8& a, const vint8& b) { return _mm256_xor_si256(a, b); }
|
||||
__forceinline vint8 operator ^(const vint8& a, int b) { return a ^ vint8(b); }
|
||||
__forceinline vint8 operator ^(int a, const vint8& b) { return vint8(a) ^ b; }
|
||||
|
||||
__forceinline const vint8 operator <<( const vint8& a, const int n ) { return _mm256_slli_epi32(a.v, n); }
|
||||
__forceinline const vint8 operator >>( const vint8& a, const int n ) { return _mm256_srai_epi32(a.v, n); }
|
||||
__forceinline vint8 operator <<(const vint8& a, int n) { return _mm256_slli_epi32(a, n); }
|
||||
__forceinline vint8 operator >>(const vint8& a, int n) { return _mm256_srai_epi32(a, n); }
|
||||
|
||||
__forceinline const vint8 operator <<( const vint8& a, const vint8& n ) { return _mm256_sllv_epi32(a.v, n); }
|
||||
__forceinline const vint8 operator >>( const vint8& a, const vint8& n ) { return _mm256_srav_epi32(a.v, n); }
|
||||
__forceinline vint8 operator <<(const vint8& a, const vint8& n) { return _mm256_sllv_epi32(a, n); }
|
||||
__forceinline vint8 operator >>(const vint8& a, const vint8& n) { return _mm256_srav_epi32(a, n); }
|
||||
|
||||
__forceinline const vint8 sll ( const vint8& a, const int b ) { return _mm256_slli_epi32(a.v, b); }
|
||||
__forceinline const vint8 sra ( const vint8& a, const int b ) { return _mm256_srai_epi32(a.v, b); }
|
||||
__forceinline const vint8 srl ( const vint8& a, const int b ) { return _mm256_srli_epi32(a.v, b); }
|
||||
__forceinline vint8 sll(const vint8& a, int b) { return _mm256_slli_epi32(a, b); }
|
||||
__forceinline vint8 sra(const vint8& a, int b) { return _mm256_srai_epi32(a, b); }
|
||||
__forceinline vint8 srl(const vint8& a, int b) { return _mm256_srli_epi32(a, b); }
|
||||
|
||||
__forceinline const vint8 sll ( const vint8& a, const vint8 &b ) { return _mm256_sllv_epi32(a.v, b.v); }
|
||||
__forceinline const vint8 sra ( const vint8& a, const vint8 &b ) { return _mm256_srav_epi32(a.v, b.v); }
|
||||
__forceinline const vint8 srl ( const vint8& a, const vint8 &b ) { return _mm256_srlv_epi32(a.v, b.v); }
|
||||
__forceinline vint8 sll(const vint8& a, const vint8& b) { return _mm256_sllv_epi32(a, b); }
|
||||
__forceinline vint8 sra(const vint8& a, const vint8& b) { return _mm256_srav_epi32(a, b); }
|
||||
__forceinline vint8 srl(const vint8& a, const vint8& b) { return _mm256_srlv_epi32(a, b); }
|
||||
|
||||
__forceinline const vint8 min( const vint8& a, const vint8& b ) { return _mm256_min_epi32(a.v, b.v); }
|
||||
__forceinline const vint8 min( const vint8& a, const int b ) { return min(a,vint8(b)); }
|
||||
__forceinline const vint8 min( const int a, const vint8& b ) { return min(vint8(a),b); }
|
||||
__forceinline vint8 min(const vint8& a, const vint8& b) { return _mm256_min_epi32(a, b); }
|
||||
__forceinline vint8 min(const vint8& a, int b) { return min(a,vint8(b)); }
|
||||
__forceinline vint8 min(int a, const vint8& b) { return min(vint8(a),b); }
|
||||
|
||||
__forceinline const vint8 max( const vint8& a, const vint8& b ) { return _mm256_max_epi32(a.v, b.v); }
|
||||
__forceinline const vint8 max( const vint8& a, const int b ) { return max(a,vint8(b)); }
|
||||
__forceinline const vint8 max( const int a, const vint8& b ) { return max(vint8(a),b); }
|
||||
__forceinline vint8 max(const vint8& a, const vint8& b) { return _mm256_max_epi32(a, b); }
|
||||
__forceinline vint8 max(const vint8& a, int b) { return max(a,vint8(b)); }
|
||||
__forceinline vint8 max(int a, const vint8& b) { return max(vint8(a),b); }
|
||||
|
||||
__forceinline const vint8 umin( const vint8& a, const vint8& b ) { return _mm256_min_epu32(a.v, b.v); }
|
||||
__forceinline const vint8 umax( const vint8& a, const vint8& b ) { return _mm256_max_epu32(a.v, b.v); }
|
||||
__forceinline vint8 umin(const vint8& a, const vint8& b) { return _mm256_min_epu32(a, b); }
|
||||
__forceinline vint8 umax(const vint8& a, const vint8& b) { return _mm256_max_epu32(a, b); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Assignment Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vint8& operator +=( vint8& a, const vint8& b ) { return a = a + b; }
|
||||
__forceinline vint8& operator +=( vint8& a, const int b ) { return a = a + b; }
|
||||
__forceinline vint8& operator +=(vint8& a, const vint8& b) { return a = a + b; }
|
||||
__forceinline vint8& operator +=(vint8& a, int b) { return a = a + b; }
|
||||
|
||||
__forceinline vint8& operator -=( vint8& a, const vint8& b ) { return a = a - b; }
|
||||
__forceinline vint8& operator -=( vint8& a, const int b ) { return a = a - b; }
|
||||
__forceinline vint8& operator -=(vint8& a, const vint8& b) { return a = a - b; }
|
||||
__forceinline vint8& operator -=(vint8& a, int b) { return a = a - b; }
|
||||
|
||||
__forceinline vint8& operator *=( vint8& a, const vint8& b ) { return a = a * b; }
|
||||
__forceinline vint8& operator *=( vint8& a, const int b ) { return a = a * b; }
|
||||
__forceinline vint8& operator *=(vint8& a, const vint8& b) { return a = a * b; }
|
||||
__forceinline vint8& operator *=(vint8& a, int b) { return a = a * b; }
|
||||
|
||||
__forceinline vint8& operator &=( vint8& a, const vint8& b ) { return a = a & b; }
|
||||
__forceinline vint8& operator &=( vint8& a, const int b ) { return a = a & b; }
|
||||
__forceinline vint8& operator &=(vint8& a, const vint8& b) { return a = a & b; }
|
||||
__forceinline vint8& operator &=(vint8& a, int b) { return a = a & b; }
|
||||
|
||||
__forceinline vint8& operator |=( vint8& a, const vint8& b ) { return a = a | b; }
|
||||
__forceinline vint8& operator |=( vint8& a, const int b ) { return a = a | b; }
|
||||
__forceinline vint8& operator |=(vint8& a, const vint8& b) { return a = a | b; }
|
||||
__forceinline vint8& operator |=(vint8& a, int b) { return a = a | b; }
|
||||
|
||||
__forceinline vint8& operator <<=( vint8& a, const int b ) { return a = a << b; }
|
||||
__forceinline vint8& operator >>=( vint8& a, const int b ) { return a = a >> b; }
|
||||
__forceinline vint8& operator <<=(vint8& a, const int b) { return a = a << b; }
|
||||
__forceinline vint8& operator >>=(vint8& a, const int b) { return a = a >> b; }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Comparison Operators + Select
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined(__AVX512VL__)
|
||||
__forceinline const vboolf8 operator ==( const vint8& a, const vint8& b ) { return _mm256_cmp_epi32_mask(a,b,_MM_CMPINT_EQ); }
|
||||
__forceinline const vboolf8 operator !=( const vint8& a, const vint8& b ) { return _mm256_cmp_epi32_mask(a,b,_MM_CMPINT_NE); }
|
||||
__forceinline const vboolf8 operator < ( const vint8& a, const vint8& b ) { return _mm256_cmp_epi32_mask(a,b,_MM_CMPINT_LT); }
|
||||
__forceinline const vboolf8 operator >=( const vint8& a, const vint8& b ) { return _mm256_cmp_epi32_mask(a,b,_MM_CMPINT_GE); }
|
||||
__forceinline const vboolf8 operator > ( const vint8& a, const vint8& b ) { return _mm256_cmp_epi32_mask(a,b,_MM_CMPINT_GT); }
|
||||
__forceinline const vboolf8 operator <=( const vint8& a, const vint8& b ) { return _mm256_cmp_epi32_mask(a,b,_MM_CMPINT_LE); }
|
||||
__forceinline vboolf8 operator ==(const vint8& a, const vint8& b) { return _mm256_cmp_epi32_mask(a,b,_MM_CMPINT_EQ); }
|
||||
__forceinline vboolf8 operator !=(const vint8& a, const vint8& b) { return _mm256_cmp_epi32_mask(a,b,_MM_CMPINT_NE); }
|
||||
__forceinline vboolf8 operator < (const vint8& a, const vint8& b) { return _mm256_cmp_epi32_mask(a,b,_MM_CMPINT_LT); }
|
||||
__forceinline vboolf8 operator >=(const vint8& a, const vint8& b) { return _mm256_cmp_epi32_mask(a,b,_MM_CMPINT_GE); }
|
||||
__forceinline vboolf8 operator > (const vint8& a, const vint8& b) { return _mm256_cmp_epi32_mask(a,b,_MM_CMPINT_GT); }
|
||||
__forceinline vboolf8 operator <=(const vint8& a, const vint8& b) { return _mm256_cmp_epi32_mask(a,b,_MM_CMPINT_LE); }
|
||||
|
||||
__forceinline const vint8 select( const vboolf8& m, const vint8& t, const vint8& f ) {
|
||||
__forceinline vint8 select(const vboolf8& m, const vint8& t, const vint8& f) {
|
||||
return _mm256_mask_blend_epi32(m, f, t);
|
||||
}
|
||||
#else
|
||||
__forceinline const vboolf8 operator ==( const vint8& a, const vint8& b ) { return _mm256_castsi256_ps(_mm256_cmpeq_epi32(a, b)); }
|
||||
__forceinline const vboolf8 operator !=( const vint8& a, const vint8& b ) { return !(a == b); }
|
||||
__forceinline const vboolf8 operator < ( const vint8& a, const vint8& b ) { return _mm256_castsi256_ps(_mm256_cmpgt_epi32(b, a)); }
|
||||
__forceinline const vboolf8 operator >=( const vint8& a, const vint8& b ) { return !(a < b); }
|
||||
__forceinline const vboolf8 operator > ( const vint8& a, const vint8& b ) { return _mm256_castsi256_ps(_mm256_cmpgt_epi32(a, b)); }
|
||||
__forceinline const vboolf8 operator <=( const vint8& a, const vint8& b ) { return !(a > b); }
|
||||
__forceinline vboolf8 operator ==(const vint8& a, const vint8& b) { return _mm256_castsi256_ps(_mm256_cmpeq_epi32(a, b)); }
|
||||
__forceinline vboolf8 operator !=(const vint8& a, const vint8& b) { return !(a == b); }
|
||||
__forceinline vboolf8 operator < (const vint8& a, const vint8& b) { return _mm256_castsi256_ps(_mm256_cmpgt_epi32(b, a)); }
|
||||
__forceinline vboolf8 operator >=(const vint8& a, const vint8& b) { return !(a < b); }
|
||||
__forceinline vboolf8 operator > (const vint8& a, const vint8& b) { return _mm256_castsi256_ps(_mm256_cmpgt_epi32(a, b)); }
|
||||
__forceinline vboolf8 operator <=(const vint8& a, const vint8& b) { return !(a > b); }
|
||||
|
||||
__forceinline const vint8 select( const vboolf8& m, const vint8& t, const vint8& f ) {
|
||||
__forceinline vint8 select(const vboolf8& m, const vint8& t, const vint8& f) {
|
||||
return _mm256_castps_si256(_mm256_blendv_ps(_mm256_castsi256_ps(f), _mm256_castsi256_ps(t), m));
|
||||
}
|
||||
#endif
|
||||
|
||||
template<int mask>
|
||||
__forceinline const vint8 select(const vint8& t, const vint8& f) {
|
||||
__forceinline vint8 select(const vint8& t, const vint8& f) {
|
||||
return _mm256_blend_epi32(f, t, mask);
|
||||
}
|
||||
|
||||
__forceinline const vboolf8 operator ==( const vint8& a, const int b ) { return a == vint8(b); }
|
||||
__forceinline const vboolf8 operator ==( const int a, const vint8& b ) { return vint8(a) == b; }
|
||||
__forceinline vboolf8 operator ==(const vint8& a, int b) { return a == vint8(b); }
|
||||
__forceinline vboolf8 operator ==(int a, const vint8& b) { return vint8(a) == b; }
|
||||
|
||||
__forceinline const vboolf8 operator !=( const vint8& a, const int b ) { return a != vint8(b); }
|
||||
__forceinline const vboolf8 operator !=( const int a, const vint8& b ) { return vint8(a) != b; }
|
||||
__forceinline vboolf8 operator !=(const vint8& a, int b) { return a != vint8(b); }
|
||||
__forceinline vboolf8 operator !=(int a, const vint8& b) { return vint8(a) != b; }
|
||||
|
||||
__forceinline const vboolf8 operator < ( const vint8& a, const int b ) { return a < vint8(b); }
|
||||
__forceinline const vboolf8 operator < ( const int a, const vint8& b ) { return vint8(a) < b; }
|
||||
__forceinline vboolf8 operator < (const vint8& a, int b) { return a < vint8(b); }
|
||||
__forceinline vboolf8 operator < (int a, const vint8& b) { return vint8(a) < b; }
|
||||
|
||||
__forceinline const vboolf8 operator >=( const vint8& a, const int b ) { return a >= vint8(b); }
|
||||
__forceinline const vboolf8 operator >=( const int a, const vint8& b ) { return vint8(a) >= b; }
|
||||
__forceinline vboolf8 operator >=(const vint8& a, int b) { return a >= vint8(b); }
|
||||
__forceinline vboolf8 operator >=(int a, const vint8& b) { return vint8(a) >= b; }
|
||||
|
||||
__forceinline const vboolf8 operator > ( const vint8& a, const int b ) { return a > vint8(b); }
|
||||
__forceinline const vboolf8 operator > ( const int a, const vint8& b ) { return vint8(a) > b; }
|
||||
__forceinline vboolf8 operator > (const vint8& a, int b) { return a > vint8(b); }
|
||||
__forceinline vboolf8 operator > (int a, const vint8& b) { return vint8(a) > b; }
|
||||
|
||||
__forceinline const vboolf8 operator <=( const vint8& a, const int b ) { return a <= vint8(b); }
|
||||
__forceinline const vboolf8 operator <=( const int a, const vint8& b ) { return vint8(a) <= b; }
|
||||
__forceinline vboolf8 operator <=(const vint8& a, int b) { return a <= vint8(b); }
|
||||
__forceinline vboolf8 operator <=(int a, const vint8& b) { return vint8(a) <= b; }
|
||||
|
||||
__forceinline vboolf8 eq(const vint8& a, const vint8& b) { return a == b; }
|
||||
__forceinline vboolf8 ne(const vint8& a, const vint8& b) { return a != b; }
|
||||
@@ -299,70 +321,78 @@ namespace embree
|
||||
/// Movement/Shifting/Shuffling Functions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vint8 unpacklo( const vint8& a, const vint8& b ) { return _mm256_unpacklo_epi32(a.v, b.v); }
|
||||
__forceinline vint8 unpackhi( const vint8& a, const vint8& b ) { return _mm256_unpackhi_epi32(a.v, b.v); }
|
||||
__forceinline vint8 unpacklo(const vint8& a, const vint8& b) { return _mm256_unpacklo_epi32(a, b); }
|
||||
__forceinline vint8 unpackhi(const vint8& a, const vint8& b) { return _mm256_unpackhi_epi32(a, b); }
|
||||
|
||||
template<size_t i> __forceinline const vint8 shuffle( const vint8& a ) {
|
||||
return _mm256_castps_si256(_mm256_permute_ps(_mm256_castsi256_ps(a), _MM_SHUFFLE(i, i, i, i)));
|
||||
template<int i>
|
||||
__forceinline vint8 shuffle(const vint8& v) {
|
||||
return _mm256_castps_si256(_mm256_permute_ps(_mm256_castsi256_ps(v), _MM_SHUFFLE(i, i, i, i)));
|
||||
}
|
||||
|
||||
template<size_t i0, size_t i1> __forceinline const vint8 shuffle4( const vint8& a ) {
|
||||
return _mm256_permute2f128_si256(a, a, (i1 << 4) | (i0 << 0));
|
||||
template<int i0, int i1>
|
||||
__forceinline vint8 shuffle4(const vint8& v) {
|
||||
return _mm256_permute2f128_si256(v, v, (i1 << 4) | (i0 << 0));
|
||||
}
|
||||
|
||||
template<size_t i0, size_t i1> __forceinline const vint8 shuffle4( const vint8& a, const vint8& b) {
|
||||
template<int i0, int i1>
|
||||
__forceinline vint8 shuffle4(const vint8& a, const vint8& b) {
|
||||
return _mm256_permute2f128_si256(a, b, (i1 << 4) | (i0 << 0));
|
||||
}
|
||||
|
||||
template<size_t i0, size_t i1, size_t i2, size_t i3> __forceinline const vint8 shuffle( const vint8& a ) {
|
||||
return _mm256_castps_si256(_mm256_permute_ps(_mm256_castsi256_ps(a), _MM_SHUFFLE(i3, i2, i1, i0)));
|
||||
template<int i0, int i1, int i2, int i3>
|
||||
__forceinline vint8 shuffle(const vint8& v) {
|
||||
return _mm256_castps_si256(_mm256_permute_ps(_mm256_castsi256_ps(v), _MM_SHUFFLE(i3, i2, i1, i0)));
|
||||
}
|
||||
|
||||
template<size_t i0, size_t i1, size_t i2, size_t i3> __forceinline const vint8 shuffle( const vint8& a, const vint8& b ) {
|
||||
template<int i0, int i1, int i2, int i3>
|
||||
__forceinline vint8 shuffle(const vint8& a, const vint8& b) {
|
||||
return _mm256_castps_si256(_mm256_shuffle_ps(_mm256_castsi256_ps(a), _mm256_castsi256_ps(b), _MM_SHUFFLE(i3, i2, i1, i0)));
|
||||
}
|
||||
|
||||
template<> __forceinline const vint8 shuffle<0, 0, 2, 2>( const vint8& b ) { return _mm256_castps_si256(_mm256_moveldup_ps(_mm256_castsi256_ps(b))); }
|
||||
template<> __forceinline const vint8 shuffle<1, 1, 3, 3>( const vint8& b ) { return _mm256_castps_si256(_mm256_movehdup_ps(_mm256_castsi256_ps(b))); }
|
||||
template<> __forceinline const vint8 shuffle<0, 1, 0, 1>( const vint8& b ) { return _mm256_castps_si256(_mm256_castpd_ps(_mm256_movedup_pd(_mm256_castps_pd(_mm256_castsi256_ps(b))))); }
|
||||
template<> __forceinline vint8 shuffle<0, 0, 2, 2>(const vint8& v) { return _mm256_castps_si256(_mm256_moveldup_ps(_mm256_castsi256_ps(v))); }
|
||||
template<> __forceinline vint8 shuffle<1, 1, 3, 3>(const vint8& v) { return _mm256_castps_si256(_mm256_movehdup_ps(_mm256_castsi256_ps(v))); }
|
||||
template<> __forceinline vint8 shuffle<0, 1, 0, 1>(const vint8& v) { return _mm256_castps_si256(_mm256_castpd_ps(_mm256_movedup_pd(_mm256_castps_pd(_mm256_castsi256_ps(v))))); }
|
||||
|
||||
__forceinline const vint8 broadcast(const int* ptr) { return _mm256_castps_si256(_mm256_broadcast_ss((const float*)ptr)); }
|
||||
__forceinline vint8 broadcast(const int* ptr) { return _mm256_castps_si256(_mm256_broadcast_ss((const float*)ptr)); }
|
||||
|
||||
template<size_t i> __forceinline const vint8 insert4(const vint8& a, const vint4& b) { return _mm256_insertf128_si256(a, b, i); }
|
||||
template<size_t i> __forceinline const vint4 extract4 (const vint8& a) { return _mm256_extractf128_si256(a, i); }
|
||||
template<> __forceinline const vint4 extract4<0>(const vint8& a) { return _mm256_castsi256_si128(a); }
|
||||
template<int i> __forceinline vint8 insert4(const vint8& a, const vint4& b) { return _mm256_insertf128_si256(a, b, i); }
|
||||
template<int i> __forceinline vint4 extract4(const vint8& a) { return _mm256_extractf128_si256(a, i); }
|
||||
template<> __forceinline vint4 extract4<0>(const vint8& a) { return _mm256_castsi256_si128(a); }
|
||||
|
||||
__forceinline int toScalar(const vint8& a) { return _mm_cvtsi128_si32(_mm256_castsi256_si128(a)); }
|
||||
__forceinline int toScalar(const vint8& v) { return _mm_cvtsi128_si32(_mm256_castsi256_si128(v)); }
|
||||
|
||||
__forceinline vint8 permute(const vint8& a, const __m256i& index) {
|
||||
return _mm256_permutevar8x32_epi32(a,index);
|
||||
__forceinline vint8 permute(const vint8& v, const __m256i& index) {
|
||||
return _mm256_permutevar8x32_epi32(v, index);
|
||||
}
|
||||
|
||||
__forceinline vint8 shuffle(const vint8& a, const __m256i& index) {
|
||||
return _mm256_castps_si256(_mm256_permutevar_ps(_mm256_castsi256_ps(a),index));
|
||||
__forceinline vint8 shuffle(const vint8& v, const __m256i& index) {
|
||||
return _mm256_castps_si256(_mm256_permutevar_ps(_mm256_castsi256_ps(v), index));
|
||||
}
|
||||
|
||||
template<int i>
|
||||
__forceinline vint8 align_shift_right(const vint8 &a, const vint8 &b) {
|
||||
return _mm256_alignr_epi8(a, b, i);
|
||||
__forceinline vint8 align_shift_right(const vint8& a, const vint8& b) {
|
||||
#if defined(__AVX512VL__)
|
||||
return _mm256_alignr_epi32(a, b, i);
|
||||
#else
|
||||
return _mm256_alignr_epi8(a, b, 4*i);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Reductions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vint8 vreduce_min2(const vint8& v) { return min(v,shuffle<1,0,3,2>(v)); }
|
||||
__forceinline const vint8 vreduce_min4(const vint8& v) { vint8 v1 = vreduce_min2(v); return min(v1,shuffle<2,3,0,1>(v1)); }
|
||||
__forceinline const vint8 vreduce_min (const vint8& v) { vint8 v1 = vreduce_min4(v); return min(v1,shuffle4<1,0>(v1)); }
|
||||
__forceinline vint8 vreduce_min2(const vint8& v) { return min(v,shuffle<1,0,3,2>(v)); }
|
||||
__forceinline vint8 vreduce_min4(const vint8& v) { vint8 v1 = vreduce_min2(v); return min(v1,shuffle<2,3,0,1>(v1)); }
|
||||
__forceinline vint8 vreduce_min (const vint8& v) { vint8 v1 = vreduce_min4(v); return min(v1,shuffle4<1,0>(v1)); }
|
||||
|
||||
__forceinline const vint8 vreduce_max2(const vint8& v) { return max(v,shuffle<1,0,3,2>(v)); }
|
||||
__forceinline const vint8 vreduce_max4(const vint8& v) { vint8 v1 = vreduce_max2(v); return max(v1,shuffle<2,3,0,1>(v1)); }
|
||||
__forceinline const vint8 vreduce_max (const vint8& v) { vint8 v1 = vreduce_max4(v); return max(v1,shuffle4<1,0>(v1)); }
|
||||
__forceinline vint8 vreduce_max2(const vint8& v) { return max(v,shuffle<1,0,3,2>(v)); }
|
||||
__forceinline vint8 vreduce_max4(const vint8& v) { vint8 v1 = vreduce_max2(v); return max(v1,shuffle<2,3,0,1>(v1)); }
|
||||
__forceinline vint8 vreduce_max (const vint8& v) { vint8 v1 = vreduce_max4(v); return max(v1,shuffle4<1,0>(v1)); }
|
||||
|
||||
__forceinline const vint8 vreduce_add2(const vint8& v) { return v + shuffle<1,0,3,2>(v); }
|
||||
__forceinline const vint8 vreduce_add4(const vint8& v) { vint8 v1 = vreduce_add2(v); return v1 + shuffle<2,3,0,1>(v1); }
|
||||
__forceinline const vint8 vreduce_add (const vint8& v) { vint8 v1 = vreduce_add4(v); return v1 + shuffle4<1,0>(v1); }
|
||||
__forceinline vint8 vreduce_add2(const vint8& v) { return v + shuffle<1,0,3,2>(v); }
|
||||
__forceinline vint8 vreduce_add4(const vint8& v) { vint8 v1 = vreduce_add2(v); return v1 + shuffle<2,3,0,1>(v1); }
|
||||
__forceinline vint8 vreduce_add (const vint8& v) { vint8 v1 = vreduce_add4(v); return v1 + shuffle4<1,0>(v1); }
|
||||
|
||||
__forceinline int reduce_min(const vint8& v) { return toScalar(vreduce_min(v)); }
|
||||
__forceinline int reduce_max(const vint8& v) { return toScalar(vreduce_max(v)); }
|
||||
@@ -375,7 +405,7 @@ namespace embree
|
||||
__forceinline size_t select_max(const vboolf8& valid, const vint8& v) { const vint8 a = select(valid,v,vint8(neg_inf)); return __bsf(movemask(valid & (a == vreduce_max(a)))); }
|
||||
|
||||
|
||||
__forceinline vint8 assign( const vint4& a ) { return _mm256_castsi128_si256(a); }
|
||||
__forceinline vint8 assign(const vint4& a) { return _mm256_castsi128_si256(a); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Sorting networks
|
||||
@@ -445,7 +475,7 @@ namespace embree
|
||||
/// Output Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& cout, const vint8& a) {
|
||||
inline std::ostream& operator <<(std::ostream& cout, const vint8& a) {
|
||||
return cout << "<" << a[0] << ", " << a[1] << ", " << a[2] << ", " << a[3] << ", " << a[4] << ", " << a[5] << ", " << a[6] << ", " << a[7] << ">";
|
||||
}
|
||||
}
|
||||
+108
-114
@@ -18,17 +18,7 @@
|
||||
|
||||
namespace embree
|
||||
{
|
||||
#ifndef _MM_SHUF_PERM2
|
||||
#define _MM_SHUF_PERM2(e3, e2, e1, e0) \
|
||||
((int)(((e3)<<3) | ((e2)<<2) | ((e1)<<1) | (e0)))
|
||||
#endif
|
||||
|
||||
#ifndef _MM_SHUF_PERM3
|
||||
#define _MM_SHUF_PERM3(e1, e0) \
|
||||
((int)(((e1)<<4) | (e0)))
|
||||
#endif
|
||||
|
||||
/* 4-wide AVX2 64bit long long type */
|
||||
/* 4-wide AVX2 64-bit long long type */
|
||||
template<>
|
||||
struct vllong<4>
|
||||
{
|
||||
@@ -46,18 +36,18 @@ namespace embree
|
||||
|
||||
__forceinline vllong() {}
|
||||
__forceinline vllong(const vllong4& t) { v = t.v; }
|
||||
__forceinline vllong4& operator=(const vllong4& f) { v = f.v; return *this; }
|
||||
__forceinline vllong4& operator =(const vllong4& f) { v = f.v; return *this; }
|
||||
|
||||
__forceinline vllong(const __m256i& t) { v = t; }
|
||||
__forceinline operator __m256i () const { return v; }
|
||||
__forceinline operator __m256d () const { return _mm256_castsi256_pd(v); }
|
||||
__forceinline operator __m256i() const { return v; }
|
||||
__forceinline operator __m256d() const { return _mm256_castsi256_pd(v); }
|
||||
|
||||
|
||||
__forceinline vllong(const long long i) {
|
||||
__forceinline vllong(long long i) {
|
||||
v = _mm256_set1_epi64x(i);
|
||||
}
|
||||
|
||||
__forceinline vllong(const long long a, const long long b, const long long c, const long long d) {
|
||||
__forceinline vllong(long long a, long long b, long long c, long long d) {
|
||||
v = _mm256_set_epi64x(d,c,b,a);
|
||||
}
|
||||
|
||||
@@ -66,20 +56,16 @@ namespace embree
|
||||
/// Constants
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vllong( ZeroTy ) : v(_mm256_setzero_si256()) {}
|
||||
__forceinline vllong( OneTy ) : v(_mm256_set1_epi64x(1)) {}
|
||||
__forceinline vllong( StepTy ) : v(_mm256_set_epi64x(3,2,1,0)) {}
|
||||
__forceinline vllong( ReverseStepTy ) : v(_mm256_set_epi64x(0,1,2,3)) {}
|
||||
|
||||
__forceinline static vllong4 zero() { return _mm256_setzero_si256(); }
|
||||
__forceinline static vllong4 one () { return _mm256_set1_epi64x(1); }
|
||||
__forceinline static vllong4 neg_one () { return _mm256_set1_epi64x(-1); }
|
||||
__forceinline vllong(ZeroTy) : v(_mm256_setzero_si256()) {}
|
||||
__forceinline vllong(OneTy) : v(_mm256_set1_epi64x(1)) {}
|
||||
__forceinline vllong(StepTy) : v(_mm256_set_epi64x(3,2,1,0)) {}
|
||||
__forceinline vllong(ReverseStepTy) : v(_mm256_set_epi64x(0,1,2,3)) {}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Loads and Stores
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static __forceinline void store_nt(void *__restrict__ ptr, const vllong4& a) {
|
||||
static __forceinline void store_nt(void* __restrict__ ptr, const vllong4& a) {
|
||||
_mm256_stream_ps((float*)ptr,_mm256_castsi256_ps(a));
|
||||
}
|
||||
|
||||
@@ -134,8 +120,8 @@ namespace embree
|
||||
/// Array Access
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline long long& operator[](const size_t index) { assert(index < 4); return i[index]; }
|
||||
__forceinline const long long& operator[](const size_t index) const { assert(index < 4); return i[index]; }
|
||||
__forceinline long long& operator [](size_t index) { assert(index < 4); return i[index]; }
|
||||
__forceinline const long long& operator [](size_t index) const { assert(index < 4); return i[index]; }
|
||||
|
||||
};
|
||||
|
||||
@@ -143,7 +129,7 @@ namespace embree
|
||||
/// Select
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vllong4 select( const vboold4& m, const vllong4& t, const vllong4& f ) {
|
||||
__forceinline vllong4 select(const vboold4& m, const vllong4& t, const vllong4& f) {
|
||||
#if defined(__AVX512VL__)
|
||||
return _mm256_mask_blend_epi64(m, f, t);
|
||||
#else
|
||||
@@ -155,123 +141,123 @@ namespace embree
|
||||
/// Unary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vllong4 asLong ( const __m256& a ) { return _mm256_castps_si256(a); }
|
||||
__forceinline const vllong4 operator +( const vllong4& a ) { return a; }
|
||||
__forceinline const vllong4 operator -( const vllong4& a ) { return _mm256_sub_epi64(_mm256_setzero_si256(), a); }
|
||||
__forceinline vllong4 asLong (const __m256& a) { return _mm256_castps_si256(a); }
|
||||
__forceinline vllong4 operator +(const vllong4& a) { return a; }
|
||||
__forceinline vllong4 operator -(const vllong4& a) { return _mm256_sub_epi64(_mm256_setzero_si256(), a); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Binary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vllong4 operator +( const vllong4& a, const vllong4& b ) { return _mm256_add_epi64(a, b); }
|
||||
__forceinline const vllong4 operator +( const vllong4& a, const long long b ) { return a + vllong4(b); }
|
||||
__forceinline const vllong4 operator +( const long long a, const vllong4& b ) { return vllong4(a) + b; }
|
||||
__forceinline vllong4 operator +(const vllong4& a, const vllong4& b) { return _mm256_add_epi64(a, b); }
|
||||
__forceinline vllong4 operator +(const vllong4& a, long long b) { return a + vllong4(b); }
|
||||
__forceinline vllong4 operator +(long long a, const vllong4& b) { return vllong4(a) + b; }
|
||||
|
||||
__forceinline const vllong4 operator -( const vllong4& a, const vllong4& b ) { return _mm256_sub_epi64(a, b); }
|
||||
__forceinline const vllong4 operator -( const vllong4& a, const long long b ) { return a - vllong4(b); }
|
||||
__forceinline const vllong4 operator -( const long long a, const vllong4& b ) { return vllong4(a) - b; }
|
||||
__forceinline vllong4 operator -(const vllong4& a, const vllong4& b) { return _mm256_sub_epi64(a, b); }
|
||||
__forceinline vllong4 operator -(const vllong4& a, long long b) { return a - vllong4(b); }
|
||||
__forceinline vllong4 operator -(long long a, const vllong4& b) { return vllong4(a) - b; }
|
||||
|
||||
/* only low 32bit part */
|
||||
__forceinline const vllong4 operator *( const vllong4& a, const vllong4& b ) { return _mm256_mul_epi32(a, b); }
|
||||
__forceinline const vllong4 operator *( const vllong4& a, const long long b ) { return a * vllong4(b); }
|
||||
__forceinline const vllong4 operator *( const long long a, const vllong4& b ) { return vllong4(a) * b; }
|
||||
__forceinline vllong4 operator *(const vllong4& a, const vllong4& b) { return _mm256_mul_epi32(a, b); }
|
||||
__forceinline vllong4 operator *(const vllong4& a, long long b) { return a * vllong4(b); }
|
||||
__forceinline vllong4 operator *(long long a, const vllong4& b) { return vllong4(a) * b; }
|
||||
|
||||
__forceinline const vllong4 operator &( const vllong4& a, const vllong4& b ) { return _mm256_and_si256(a, b); }
|
||||
__forceinline const vllong4 operator &( const vllong4& a, const long long b ) { return a & vllong4(b); }
|
||||
__forceinline const vllong4 operator &( const long long a, const vllong4& b ) { return vllong4(a) & b; }
|
||||
__forceinline vllong4 operator &(const vllong4& a, const vllong4& b) { return _mm256_and_si256(a, b); }
|
||||
__forceinline vllong4 operator &(const vllong4& a, long long b) { return a & vllong4(b); }
|
||||
__forceinline vllong4 operator &(long long a, const vllong4& b) { return vllong4(a) & b; }
|
||||
|
||||
__forceinline const vllong4 operator |( const vllong4& a, const vllong4& b ) { return _mm256_or_si256(a, b); }
|
||||
__forceinline const vllong4 operator |( const vllong4& a, const long long b ) { return a | vllong4(b); }
|
||||
__forceinline const vllong4 operator |( const long long a, const vllong4& b ) { return vllong4(a) | b; }
|
||||
__forceinline vllong4 operator |(const vllong4& a, const vllong4& b) { return _mm256_or_si256(a, b); }
|
||||
__forceinline vllong4 operator |(const vllong4& a, long long b) { return a | vllong4(b); }
|
||||
__forceinline vllong4 operator |(long long a, const vllong4& b) { return vllong4(a) | b; }
|
||||
|
||||
__forceinline const vllong4 operator ^( const vllong4& a, const vllong4& b ) { return _mm256_xor_si256(a, b); }
|
||||
__forceinline const vllong4 operator ^( const vllong4& a, const long long b ) { return a ^ vllong4(b); }
|
||||
__forceinline const vllong4 operator ^( const long long a, const vllong4& b ) { return vllong4(a) ^ b; }
|
||||
__forceinline vllong4 operator ^(const vllong4& a, const vllong4& b) { return _mm256_xor_si256(a, b); }
|
||||
__forceinline vllong4 operator ^(const vllong4& a, long long b) { return a ^ vllong4(b); }
|
||||
__forceinline vllong4 operator ^(long long a, const vllong4& b) { return vllong4(a) ^ b; }
|
||||
|
||||
__forceinline const vllong4 operator <<( const vllong4& a, const long long n ) { return _mm256_slli_epi64(a, n); }
|
||||
//__forceinline const vllong4 operator >>( const vllong4& a, const long long n ) { return _mm256_srai_epi64(a, n); }
|
||||
__forceinline vllong4 operator <<(const vllong4& a, long long n) { return _mm256_slli_epi64(a, (int)n); }
|
||||
//__forceinline vllong4 operator >>(const vllong4& a, long long n) { return _mm256_srai_epi64(a, n); }
|
||||
|
||||
__forceinline const vllong4 operator <<( const vllong4& a, const vllong4& n ) { return _mm256_sllv_epi64(a, n); }
|
||||
//__forceinline const vllong4 operator >>( const vllong4& a, const vllong4& n ) { return _mm256_srav_epi64(a, n); }
|
||||
//__forceinline const vllong4 sra ( const vllong4& a, const long long b ) { return _mm256_srai_epi64(a, b); }
|
||||
__forceinline vllong4 operator <<(const vllong4& a, const vllong4& n) { return _mm256_sllv_epi64(a, n); }
|
||||
//__forceinline vllong4 operator >>(const vllong4& a, const vllong4& n) { return _mm256_srav_epi64(a, n); }
|
||||
//__forceinline vllong4 sra(const vllong4& a, long long b) { return _mm256_srai_epi64(a, b); }
|
||||
|
||||
__forceinline const vllong4 srl ( const vllong4& a, const long long b ) { return _mm256_srli_epi64(a, b); }
|
||||
__forceinline vllong4 srl(const vllong4& a, long long b) { return _mm256_srli_epi64(a, (int)b); }
|
||||
|
||||
//__forceinline const vllong4 min( const vllong4& a, const vllong4& b ) { return _mm256_min_epi64(a, b); }
|
||||
//__forceinline const vllong4 min( const vllong4& a, const long long b ) { return min(a,vllong4(b)); }
|
||||
//__forceinline const vllong4 min( const long long a, const vllong4& b ) { return min(vllong4(a),b); }
|
||||
//__forceinline vllong4 min(const vllong4& a, const vllong4& b) { return _mm256_min_epi64(a, b); }
|
||||
//__forceinline vllong4 min(const vllong4& a, long long b) { return min(a,vllong4(b)); }
|
||||
//__forceinline vllong4 min(long long a, const vllong4& b) { return min(vllong4(a),b); }
|
||||
|
||||
//__forceinline const vllong4 max( const vllong4& a, const vllong4& b ) { return _mm256_max_epi64(a, b); }
|
||||
//__forceinline const vllong4 max( const vllong4& a, const long long b ) { return max(a,vllong4(b)); }
|
||||
//__forceinline const vllong4 max( const long long a, const vllong4& b ) { return max(vllong4(a),b); }
|
||||
//__forceinline vllong4 max(const vllong4& a, const vllong4& b) { return _mm256_max_epi64(a, b); }
|
||||
//__forceinline vllong4 max(const vllong4& a, long long b) { return max(a,vllong4(b)); }
|
||||
//__forceinline vllong4 max(long long a, const vllong4& b) { return max(vllong4(a),b); }
|
||||
|
||||
#if defined(__AVX512VL__)
|
||||
__forceinline const vllong4 mask_and(const vboold4& m, const vllong4& c, const vllong4& a, const vllong4& b) { return _mm256_mask_and_epi64(c,m,a,b); }
|
||||
__forceinline const vllong4 mask_or (const vboold4& m, const vllong4& c, const vllong4& a, const vllong4& b) { return _mm256_mask_or_epi64(c,m,a,b); }
|
||||
__forceinline vllong4 mask_and(const vboold4& m, const vllong4& c, const vllong4& a, const vllong4& b) { return _mm256_mask_and_epi64(c,m,a,b); }
|
||||
__forceinline vllong4 mask_or (const vboold4& m, const vllong4& c, const vllong4& a, const vllong4& b) { return _mm256_mask_or_epi64(c,m,a,b); }
|
||||
#else
|
||||
__forceinline const vllong4 mask_and(const vboold4& m, const vllong4& c, const vllong4& a, const vllong4& b) { return select(m, a & b, c); }
|
||||
__forceinline const vllong4 mask_or (const vboold4& m, const vllong4& c, const vllong4& a, const vllong4& b) { return select(m, a | b, c); }
|
||||
__forceinline vllong4 mask_and(const vboold4& m, const vllong4& c, const vllong4& a, const vllong4& b) { return select(m, a & b, c); }
|
||||
__forceinline vllong4 mask_or (const vboold4& m, const vllong4& c, const vllong4& a, const vllong4& b) { return select(m, a | b, c); }
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Assignment Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vllong4& operator +=( vllong4& a, const vllong4& b ) { return a = a + b; }
|
||||
__forceinline vllong4& operator +=( vllong4& a, const long long b ) { return a = a + b; }
|
||||
__forceinline vllong4& operator +=(vllong4& a, const vllong4& b) { return a = a + b; }
|
||||
__forceinline vllong4& operator +=(vllong4& a, long long b) { return a = a + b; }
|
||||
|
||||
__forceinline vllong4& operator -=( vllong4& a, const vllong4& b ) { return a = a - b; }
|
||||
__forceinline vllong4& operator -=( vllong4& a, const long long b ) { return a = a - b; }
|
||||
__forceinline vllong4& operator -=(vllong4& a, const vllong4& b) { return a = a - b; }
|
||||
__forceinline vllong4& operator -=(vllong4& a, long long b) { return a = a - b; }
|
||||
|
||||
__forceinline vllong4& operator *=( vllong4& a, const vllong4& b ) { return a = a * b; }
|
||||
__forceinline vllong4& operator *=( vllong4& a, const long long b ) { return a = a * b; }
|
||||
__forceinline vllong4& operator *=(vllong4& a, const vllong4& b) { return a = a * b; }
|
||||
__forceinline vllong4& operator *=(vllong4& a, long long b) { return a = a * b; }
|
||||
|
||||
__forceinline vllong4& operator &=( vllong4& a, const vllong4& b ) { return a = a & b; }
|
||||
__forceinline vllong4& operator &=( vllong4& a, const long long b ) { return a = a & b; }
|
||||
__forceinline vllong4& operator &=(vllong4& a, const vllong4& b) { return a = a & b; }
|
||||
__forceinline vllong4& operator &=(vllong4& a, long long b) { return a = a & b; }
|
||||
|
||||
__forceinline vllong4& operator |=( vllong4& a, const vllong4& b ) { return a = a | b; }
|
||||
__forceinline vllong4& operator |=( vllong4& a, const long long b ) { return a = a | b; }
|
||||
__forceinline vllong4& operator |=(vllong4& a, const vllong4& b) { return a = a | b; }
|
||||
__forceinline vllong4& operator |=(vllong4& a, long long b) { return a = a | b; }
|
||||
|
||||
__forceinline vllong4& operator <<=( vllong4& a, const long long b ) { return a = a << b; }
|
||||
//__forceinline vllong4& operator >>=( vllong4& a, const long long b ) { return a = a >> b; }
|
||||
__forceinline vllong4& operator <<=(vllong4& a, long long b) { return a = a << b; }
|
||||
//__forceinline vllong4& operator >>=(vllong4& a, long long b) { return a = a >> b; }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Comparison Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined(__AVX512VL__)
|
||||
__forceinline const vboold4 operator ==( const vllong4& a, const vllong4& b ) { return _mm256_cmp_epi64_mask(a,b,_MM_CMPINT_EQ); }
|
||||
__forceinline const vboold4 operator !=( const vllong4& a, const vllong4& b ) { return _mm256_cmp_epi64_mask(a,b,_MM_CMPINT_NE); }
|
||||
__forceinline const vboold4 operator < ( const vllong4& a, const vllong4& b ) { return _mm256_cmp_epi64_mask(a,b,_MM_CMPINT_LT); }
|
||||
__forceinline const vboold4 operator >=( const vllong4& a, const vllong4& b ) { return _mm256_cmp_epi64_mask(a,b,_MM_CMPINT_GE); }
|
||||
__forceinline const vboold4 operator > ( const vllong4& a, const vllong4& b ) { return _mm256_cmp_epi64_mask(a,b,_MM_CMPINT_GT); }
|
||||
__forceinline const vboold4 operator <=( const vllong4& a, const vllong4& b ) { return _mm256_cmp_epi64_mask(a,b,_MM_CMPINT_LE); }
|
||||
__forceinline vboold4 operator ==(const vllong4& a, const vllong4& b) { return _mm256_cmp_epi64_mask(a,b,_MM_CMPINT_EQ); }
|
||||
__forceinline vboold4 operator !=(const vllong4& a, const vllong4& b) { return _mm256_cmp_epi64_mask(a,b,_MM_CMPINT_NE); }
|
||||
__forceinline vboold4 operator < (const vllong4& a, const vllong4& b) { return _mm256_cmp_epi64_mask(a,b,_MM_CMPINT_LT); }
|
||||
__forceinline vboold4 operator >=(const vllong4& a, const vllong4& b) { return _mm256_cmp_epi64_mask(a,b,_MM_CMPINT_GE); }
|
||||
__forceinline vboold4 operator > (const vllong4& a, const vllong4& b) { return _mm256_cmp_epi64_mask(a,b,_MM_CMPINT_GT); }
|
||||
__forceinline vboold4 operator <=(const vllong4& a, const vllong4& b) { return _mm256_cmp_epi64_mask(a,b,_MM_CMPINT_LE); }
|
||||
#else
|
||||
__forceinline const vboold4 operator ==( const vllong4& a, const vllong4& b ) { return _mm256_cmpeq_epi64(a,b); }
|
||||
__forceinline const vboold4 operator !=( const vllong4& a, const vllong4& b ) { return !(a == b); }
|
||||
__forceinline const vboold4 operator > ( const vllong4& a, const vllong4& b ) { return _mm256_cmpgt_epi64(a,b); }
|
||||
__forceinline const vboold4 operator < ( const vllong4& a, const vllong4& b ) { return _mm256_cmpgt_epi64(b,a); }
|
||||
__forceinline const vboold4 operator >=( const vllong4& a, const vllong4& b ) { return !(a < b); }
|
||||
__forceinline const vboold4 operator <=( const vllong4& a, const vllong4& b ) { return !(a > b); }
|
||||
__forceinline vboold4 operator ==(const vllong4& a, const vllong4& b) { return _mm256_cmpeq_epi64(a,b); }
|
||||
__forceinline vboold4 operator !=(const vllong4& a, const vllong4& b) { return !(a == b); }
|
||||
__forceinline vboold4 operator > (const vllong4& a, const vllong4& b) { return _mm256_cmpgt_epi64(a,b); }
|
||||
__forceinline vboold4 operator < (const vllong4& a, const vllong4& b) { return _mm256_cmpgt_epi64(b,a); }
|
||||
__forceinline vboold4 operator >=(const vllong4& a, const vllong4& b) { return !(a < b); }
|
||||
__forceinline vboold4 operator <=(const vllong4& a, const vllong4& b) { return !(a > b); }
|
||||
#endif
|
||||
|
||||
__forceinline const vboold4 operator ==( const vllong4& a, const long long b ) { return a == vllong4(b); }
|
||||
__forceinline const vboold4 operator ==( const long long a, const vllong4& b ) { return vllong4(a) == b; }
|
||||
__forceinline vboold4 operator ==(const vllong4& a, long long b) { return a == vllong4(b); }
|
||||
__forceinline vboold4 operator ==(long long a, const vllong4& b) { return vllong4(a) == b; }
|
||||
|
||||
__forceinline const vboold4 operator !=( const vllong4& a, const long long b ) { return a != vllong4(b); }
|
||||
__forceinline const vboold4 operator !=( const long long a, const vllong4& b ) { return vllong4(a) != b; }
|
||||
__forceinline vboold4 operator !=(const vllong4& a, long long b) { return a != vllong4(b); }
|
||||
__forceinline vboold4 operator !=(long long a, const vllong4& b) { return vllong4(a) != b; }
|
||||
|
||||
__forceinline const vboold4 operator > ( const vllong4& a, const long long b ) { return a > vllong4(b); }
|
||||
__forceinline const vboold4 operator > ( const long long a, const vllong4& b ) { return vllong4(a) > b; }
|
||||
__forceinline vboold4 operator > (const vllong4& a, long long b) { return a > vllong4(b); }
|
||||
__forceinline vboold4 operator > (long long a, const vllong4& b) { return vllong4(a) > b; }
|
||||
|
||||
__forceinline const vboold4 operator < ( const vllong4& a, const long long b ) { return a < vllong4(b); }
|
||||
__forceinline const vboold4 operator < ( const long long a, const vllong4& b ) { return vllong4(a) < b; }
|
||||
__forceinline vboold4 operator < (const vllong4& a, long long b) { return a < vllong4(b); }
|
||||
__forceinline vboold4 operator < (long long a, const vllong4& b) { return vllong4(a) < b; }
|
||||
|
||||
__forceinline const vboold4 operator >=( const vllong4& a, const long long b ) { return a >= vllong4(b); }
|
||||
__forceinline const vboold4 operator >=( const long long a, const vllong4& b ) { return vllong4(a) >= b; }
|
||||
__forceinline vboold4 operator >=(const vllong4& a, long long b) { return a >= vllong4(b); }
|
||||
__forceinline vboold4 operator >=(long long a, const vllong4& b) { return vllong4(a) >= b; }
|
||||
|
||||
__forceinline const vboold4 operator <=( const vllong4& a, const long long b ) { return a <= vllong4(b); }
|
||||
__forceinline const vboold4 operator <=( const long long a, const vllong4& b ) { return vllong4(a) <= b; }
|
||||
__forceinline vboold4 operator <=(const vllong4& a, long long b) { return a <= vllong4(b); }
|
||||
__forceinline vboold4 operator <=(long long a, const vllong4& b) { return vllong4(a) <= b; }
|
||||
|
||||
__forceinline vboold4 eq(const vllong4& a, const vllong4& b) { return a == b; }
|
||||
__forceinline vboold4 ne(const vllong4& a, const vllong4& b) { return a != b; }
|
||||
@@ -312,15 +298,23 @@ namespace embree
|
||||
// Movement/Shifting/Shuffling Functions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<int B, int A> __forceinline vllong4 shuffle (const vllong4& v) { return _mm256_castpd_si256(_mm256_permute_pd(_mm256_castsi256_pd(v),(int)_MM_SHUF_PERM2(B,A,B,A))); }
|
||||
template<int A> __forceinline vllong4 shuffle (const vllong4& x) { return shuffle<A,A>(x); }
|
||||
template<int i0, int i1>
|
||||
__forceinline vllong4 shuffle(const vllong4& v) {
|
||||
return _mm256_castpd_si256(_mm256_permute_pd(_mm256_castsi256_pd(v), (i1 << 3) | (i0 << 2) | (i1 << 1) | i0));
|
||||
}
|
||||
|
||||
template<int B, int A> __forceinline vllong4 shuffle2 (const vllong4& v) { return _mm256_castpd_si256(_mm256_permute2f128_pd(_mm256_castsi256_pd(v),v,(int)_MM_SHUF_PERM3(B,A))); }
|
||||
template<int i>
|
||||
__forceinline vllong4 shuffle(const vllong4& v) {
|
||||
return shuffle<i, i>(v);
|
||||
}
|
||||
|
||||
template<int i0, int i1>
|
||||
__forceinline vllong4 shuffle2(const vllong4& v) {
|
||||
return _mm256_castpd_si256(_mm256_permute2f128_pd(_mm256_castsi256_pd(v), _mm256_castsi256_pd(v), (i1 << 4) | i0));
|
||||
}
|
||||
|
||||
__forceinline long long toScalar(const vllong4& a)
|
||||
{
|
||||
return _mm_cvtsi128_si64(_mm256_castsi256_si128(a));
|
||||
__forceinline long long toScalar(const vllong4& v) {
|
||||
return _mm_cvtsi128_si64(_mm256_castsi256_si128(v));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -328,14 +322,14 @@ namespace embree
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
__forceinline vllong4 vreduce_and2(const vllong4& x) { return x & shuffle<0,1>(x); }
|
||||
__forceinline vllong4 vreduce_and (const vllong4& y) { const vllong4 x = vreduce_and2(y); return x & shuffle2<0,1>(x); }
|
||||
__forceinline vllong4 vreduce_and2(const vllong4& x) { return x & shuffle<1,0>(x); }
|
||||
__forceinline vllong4 vreduce_and (const vllong4& y) { const vllong4 x = vreduce_and2(y); return x & shuffle2<1,0>(x); }
|
||||
|
||||
__forceinline vllong4 vreduce_or2(const vllong4& x) { return x | shuffle<0,1>(x); }
|
||||
__forceinline vllong4 vreduce_or (const vllong4& y) { const vllong4 x = vreduce_or2(y); return x | shuffle2<0,1>(x); }
|
||||
__forceinline vllong4 vreduce_or2(const vllong4& x) { return x | shuffle<1,0>(x); }
|
||||
__forceinline vllong4 vreduce_or (const vllong4& y) { const vllong4 x = vreduce_or2(y); return x | shuffle2<1,0>(x); }
|
||||
|
||||
__forceinline vllong4 vreduce_add2(const vllong4& x) { return x + shuffle<0,1>(x); }
|
||||
__forceinline vllong4 vreduce_add (const vllong4& y) { const vllong4 x = vreduce_add2(y); return x + shuffle2<0,1>(x); }
|
||||
__forceinline vllong4 vreduce_add2(const vllong4& x) { return x + shuffle<1,0>(x); }
|
||||
__forceinline vllong4 vreduce_add (const vllong4& y) { const vllong4 x = vreduce_add2(y); return x + shuffle2<1,0>(x); }
|
||||
|
||||
__forceinline long long reduce_add(const vllong4& a) { return toScalar(vreduce_add(a)); }
|
||||
__forceinline long long reduce_or (const vllong4& a) { return toScalar(vreduce_or(a)); }
|
||||
@@ -345,7 +339,7 @@ namespace embree
|
||||
/// Output Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline std::ostream& operator<<(std::ostream& cout, const vllong4& v)
|
||||
__forceinline std::ostream& operator <<(std::ostream& cout, const vllong4& v)
|
||||
{
|
||||
cout << "<" << v[0];
|
||||
for (size_t i=1; i<4; i++) cout << ", " << v[i];
|
||||
|
||||
+121
-119
@@ -18,7 +18,7 @@
|
||||
|
||||
namespace embree
|
||||
{
|
||||
/* 8-wide AVX-512 64bit long long type */
|
||||
/* 8-wide AVX-512 64-bit long long type */
|
||||
template<>
|
||||
struct vllong<8>
|
||||
{
|
||||
@@ -36,45 +36,44 @@ namespace embree
|
||||
|
||||
__forceinline vllong() {}
|
||||
__forceinline vllong(const vllong8& t) { v = t.v; }
|
||||
__forceinline vllong8& operator=(const vllong8& f) { v = f.v; return *this; }
|
||||
__forceinline vllong8& operator =(const vllong8& f) { v = f.v; return *this; }
|
||||
|
||||
__forceinline vllong(const __m512i& t) { v = t; }
|
||||
__forceinline operator __m512i () const { return v; }
|
||||
__forceinline operator __m256i () const { return _mm512_castsi512_si256(v); }
|
||||
__forceinline operator __m512i() const { return v; }
|
||||
__forceinline operator __m256i() const { return _mm512_castsi512_si256(v); }
|
||||
|
||||
__forceinline vllong(const long long i) {
|
||||
__forceinline vllong(long long i) {
|
||||
v = _mm512_set1_epi64(i);
|
||||
}
|
||||
|
||||
__forceinline vllong(const long long a, const long long b, const long long c, const long long d) {
|
||||
__forceinline vllong(long long a, long long b, long long c, long long d) {
|
||||
v = _mm512_set4_epi64(d,c,b,a);
|
||||
}
|
||||
|
||||
__forceinline vllong(const long long a0, const long long a1, const long long a2, const long long a3,
|
||||
const long long a4, const long long a5, const long long a6, const long long a7)
|
||||
__forceinline vllong(long long a0, long long a1, long long a2, long long a3,
|
||||
long long a4, long long a5, long long a6, long long a7)
|
||||
{
|
||||
v = _mm512_set_epi64(a7,a6,a5,a4,a3,a2,a1,a0);
|
||||
}
|
||||
|
||||
__forceinline vllong(const vllong<4>& i) {
|
||||
v = _mm512_broadcast_i64x4(i);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Constants
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vllong( ZeroTy ) : v(_mm512_setzero_epi32()) {}
|
||||
__forceinline vllong( OneTy ) : v(_mm512_set1_epi64(1)) {}
|
||||
__forceinline vllong( StepTy ) : v(_mm512_set_epi64(7,6,5,4,3,2,1,0)) {}
|
||||
__forceinline vllong( ReverseStepTy ) : v(_mm512_setr_epi64(7,6,5,4,3,2,1,0)) {}
|
||||
|
||||
__forceinline static vllong8 zero() { return _mm512_setzero_epi32(); }
|
||||
__forceinline static vllong8 one () { return _mm512_set1_epi64(1); }
|
||||
__forceinline static vllong8 neg_one () { return _mm512_set1_epi64(-1); }
|
||||
__forceinline vllong(ZeroTy) : v(_mm512_setzero_epi32()) {}
|
||||
__forceinline vllong(OneTy) : v(_mm512_set1_epi64(1)) {}
|
||||
__forceinline vllong(StepTy) : v(_mm512_set_epi64(7,6,5,4,3,2,1,0)) {}
|
||||
__forceinline vllong(ReverseStepTy) : v(_mm512_setr_epi64(7,6,5,4,3,2,1,0)) {}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Loads and Stores
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static __forceinline void store_nt(void *__restrict__ ptr, const vllong8& a) {
|
||||
static __forceinline void store_nt(void* __restrict__ ptr, const vllong8& a) {
|
||||
_mm512_stream_si512((__m512i*)ptr,a);
|
||||
}
|
||||
|
||||
@@ -90,7 +89,7 @@ namespace embree
|
||||
return _mm512_load_si512(addr);
|
||||
}
|
||||
|
||||
static __forceinline const vllong8 load( const unsigned char* const ptr ) {
|
||||
static __forceinline vllong8 load(const unsigned char* ptr) {
|
||||
return _mm512_cvtepu8_epi64(*(__m128i*)ptr);
|
||||
}
|
||||
|
||||
@@ -98,11 +97,11 @@ namespace embree
|
||||
_mm512_store_si512(ptr,v);
|
||||
}
|
||||
|
||||
static __forceinline void storeu(void* ptr, const vllong8& v ) {
|
||||
static __forceinline void storeu(void* ptr, const vllong8& v) {
|
||||
_mm512_storeu_si512(ptr,v);
|
||||
}
|
||||
|
||||
static __forceinline void storeu(const vboold8& mask, long long* ptr, const vllong8& f ) {
|
||||
static __forceinline void storeu(const vboold8& mask, long long* ptr, const vllong8& f) {
|
||||
_mm512_mask_storeu_epi64(ptr,mask,f);
|
||||
}
|
||||
|
||||
@@ -111,7 +110,7 @@ namespace embree
|
||||
}
|
||||
|
||||
/* pass by value to avoid compiler generating inefficient code */
|
||||
static __forceinline void storeu_compact(const vboold8 mask,void * addr, const vllong8& reg) {
|
||||
static __forceinline void storeu_compact(const vboold8 mask, void* addr, const vllong8& reg) {
|
||||
_mm512_mask_compressstoreu_epi64(addr,mask,reg);
|
||||
}
|
||||
|
||||
@@ -149,8 +148,8 @@ namespace embree
|
||||
/// Array Access
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline long long& operator[](const size_t index) { assert(index < 8); return i[index]; }
|
||||
__forceinline const long long& operator[](const size_t index) const { assert(index < 8); return i[index]; }
|
||||
__forceinline long long& operator [](size_t index) { assert(index < 8); return i[index]; }
|
||||
__forceinline const long long& operator [](size_t index) const { assert(index < 8); return i[index]; }
|
||||
|
||||
};
|
||||
|
||||
@@ -158,111 +157,111 @@ namespace embree
|
||||
/// Unary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vllong8 asLong ( const __m512& a ) { return _mm512_castps_si512(a); }
|
||||
__forceinline const vllong8 operator +( const vllong8& a ) { return a; }
|
||||
__forceinline const vllong8 operator -( const vllong8& a ) { return _mm512_sub_epi64(_mm512_setzero_epi32(), a); }
|
||||
__forceinline vllong8 asLong (const __m512& a) { return _mm512_castps_si512(a); }
|
||||
__forceinline vllong8 operator +(const vllong8& a) { return a; }
|
||||
__forceinline vllong8 operator -(const vllong8& a) { return _mm512_sub_epi64(_mm512_setzero_epi32(), a); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Binary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vllong8 operator +( const vllong8& a, const vllong8& b ) { return _mm512_add_epi64(a, b); }
|
||||
__forceinline const vllong8 operator +( const vllong8& a, const long long b ) { return a + vllong8(b); }
|
||||
__forceinline const vllong8 operator +( const long long a, const vllong8& b ) { return vllong8(a) + b; }
|
||||
__forceinline vllong8 operator +(const vllong8& a, const vllong8& b) { return _mm512_add_epi64(a, b); }
|
||||
__forceinline vllong8 operator +(const vllong8& a, long long b) { return a + vllong8(b); }
|
||||
__forceinline vllong8 operator +(long long a, const vllong8& b) { return vllong8(a) + b; }
|
||||
|
||||
__forceinline const vllong8 operator -( const vllong8& a, const vllong8& b ) { return _mm512_sub_epi64(a, b); }
|
||||
__forceinline const vllong8 operator -( const vllong8& a, const long long b ) { return a - vllong8(b); }
|
||||
__forceinline const vllong8 operator -( const long long a, const vllong8& b ) { return vllong8(a) - b; }
|
||||
__forceinline vllong8 operator -(const vllong8& a, const vllong8& b) { return _mm512_sub_epi64(a, b); }
|
||||
__forceinline vllong8 operator -(const vllong8& a, long long b) { return a - vllong8(b); }
|
||||
__forceinline vllong8 operator -(long long a, const vllong8& b) { return vllong8(a) - b; }
|
||||
|
||||
__forceinline const vllong8 operator *( const vllong8& a, const vllong8& b ) { return _mm512_mullo_epi64(a, b); }
|
||||
__forceinline const vllong8 operator *( const vllong8& a, const long long b ) { return a * vllong8(b); }
|
||||
__forceinline const vllong8 operator *( const long long a, const vllong8& b ) { return vllong8(a) * b; }
|
||||
__forceinline vllong8 operator *(const vllong8& a, const vllong8& b) { return _mm512_mullo_epi64(a, b); }
|
||||
__forceinline vllong8 operator *(const vllong8& a, long long b) { return a * vllong8(b); }
|
||||
__forceinline vllong8 operator *(long long a, const vllong8& b) { return vllong8(a) * b; }
|
||||
|
||||
__forceinline const vllong8 operator &( const vllong8& a, const vllong8& b ) { return _mm512_and_epi64(a, b); }
|
||||
__forceinline const vllong8 operator &( const vllong8& a, const long long b ) { return a & vllong8(b); }
|
||||
__forceinline const vllong8 operator &( const long long a, const vllong8& b ) { return vllong8(a) & b; }
|
||||
__forceinline vllong8 operator &(const vllong8& a, const vllong8& b) { return _mm512_and_epi64(a, b); }
|
||||
__forceinline vllong8 operator &(const vllong8& a, long long b) { return a & vllong8(b); }
|
||||
__forceinline vllong8 operator &(long long a, const vllong8& b) { return vllong8(a) & b; }
|
||||
|
||||
__forceinline const vllong8 operator |( const vllong8& a, const vllong8& b ) { return _mm512_or_epi64(a, b); }
|
||||
__forceinline const vllong8 operator |( const vllong8& a, const long long b ) { return a | vllong8(b); }
|
||||
__forceinline const vllong8 operator |( const long long a, const vllong8& b ) { return vllong8(a) | b; }
|
||||
__forceinline vllong8 operator |(const vllong8& a, const vllong8& b) { return _mm512_or_epi64(a, b); }
|
||||
__forceinline vllong8 operator |(const vllong8& a, long long b) { return a | vllong8(b); }
|
||||
__forceinline vllong8 operator |(long long a, const vllong8& b) { return vllong8(a) | b; }
|
||||
|
||||
__forceinline const vllong8 operator ^( const vllong8& a, const vllong8& b ) { return _mm512_xor_epi64(a, b); }
|
||||
__forceinline const vllong8 operator ^( const vllong8& a, const long long b ) { return a ^ vllong8(b); }
|
||||
__forceinline const vllong8 operator ^( const long long a, const vllong8& b ) { return vllong8(a) ^ b; }
|
||||
__forceinline vllong8 operator ^(const vllong8& a, const vllong8& b) { return _mm512_xor_epi64(a, b); }
|
||||
__forceinline vllong8 operator ^(const vllong8& a, long long b) { return a ^ vllong8(b); }
|
||||
__forceinline vllong8 operator ^(long long a, const vllong8& b) { return vllong8(a) ^ b; }
|
||||
|
||||
__forceinline const vllong8 operator <<( const vllong8& a, const long long n ) { return _mm512_slli_epi64(a, n); }
|
||||
__forceinline const vllong8 operator >>( const vllong8& a, const long long n ) { return _mm512_srai_epi64(a, n); }
|
||||
__forceinline vllong8 operator <<(const vllong8& a, long long n) { return _mm512_slli_epi64(a, n); }
|
||||
__forceinline vllong8 operator >>(const vllong8& a, long long n) { return _mm512_srai_epi64(a, n); }
|
||||
|
||||
__forceinline const vllong8 operator <<( const vllong8& a, const vllong8& n ) { return _mm512_sllv_epi64(a, n); }
|
||||
__forceinline const vllong8 operator >>( const vllong8& a, const vllong8& n ) { return _mm512_srav_epi64(a, n); }
|
||||
__forceinline vllong8 operator <<(const vllong8& a, const vllong8& n) { return _mm512_sllv_epi64(a, n); }
|
||||
__forceinline vllong8 operator >>(const vllong8& a, const vllong8& n) { return _mm512_srav_epi64(a, n); }
|
||||
|
||||
__forceinline const vllong8 sll ( const vllong8& a, const long long b ) { return _mm512_slli_epi64(a, b); }
|
||||
__forceinline const vllong8 sra ( const vllong8& a, const long long b ) { return _mm512_srai_epi64(a, b); }
|
||||
__forceinline const vllong8 srl ( const vllong8& a, const long long b ) { return _mm512_srli_epi64(a, b); }
|
||||
__forceinline vllong8 sll (const vllong8& a, long long b) { return _mm512_slli_epi64(a, b); }
|
||||
__forceinline vllong8 sra (const vllong8& a, long long b) { return _mm512_srai_epi64(a, b); }
|
||||
__forceinline vllong8 srl (const vllong8& a, long long b) { return _mm512_srli_epi64(a, b); }
|
||||
|
||||
__forceinline const vllong8 min( const vllong8& a, const vllong8& b ) { return _mm512_min_epi64(a, b); }
|
||||
__forceinline const vllong8 min( const vllong8& a, const long long b ) { return min(a,vllong8(b)); }
|
||||
__forceinline const vllong8 min( const long long a, const vllong8& b ) { return min(vllong8(a),b); }
|
||||
__forceinline vllong8 min(const vllong8& a, const vllong8& b) { return _mm512_min_epi64(a, b); }
|
||||
__forceinline vllong8 min(const vllong8& a, long long b) { return min(a,vllong8(b)); }
|
||||
__forceinline vllong8 min(long long a, const vllong8& b) { return min(vllong8(a),b); }
|
||||
|
||||
__forceinline const vllong8 max( const vllong8& a, const vllong8& b ) { return _mm512_max_epi64(a, b); }
|
||||
__forceinline const vllong8 max( const vllong8& a, const long long b ) { return max(a,vllong8(b)); }
|
||||
__forceinline const vllong8 max( const long long a, const vllong8& b ) { return max(vllong8(a),b); }
|
||||
__forceinline vllong8 max(const vllong8& a, const vllong8& b) { return _mm512_max_epi64(a, b); }
|
||||
__forceinline vllong8 max(const vllong8& a, long long b) { return max(a,vllong8(b)); }
|
||||
__forceinline vllong8 max(long long a, const vllong8& b) { return max(vllong8(a),b); }
|
||||
|
||||
__forceinline const vllong8 mask_add(const vboold8& m, const vllong8& c, const vllong8& a, const vllong8& b) { return _mm512_mask_add_epi64(c,m,a,b); }
|
||||
__forceinline const vllong8 mask_sub(const vboold8& m, const vllong8& c, const vllong8& a, const vllong8& b) { return _mm512_mask_sub_epi64(c,m,a,b); }
|
||||
__forceinline vllong8 mask_add(const vboold8& m, const vllong8& c, const vllong8& a, const vllong8& b) { return _mm512_mask_add_epi64(c,m,a,b); }
|
||||
__forceinline vllong8 mask_sub(const vboold8& m, const vllong8& c, const vllong8& a, const vllong8& b) { return _mm512_mask_sub_epi64(c,m,a,b); }
|
||||
|
||||
__forceinline const vllong8 mask_and(const vboold8& m, const vllong8& c, const vllong8& a, const vllong8& b) { return _mm512_mask_and_epi64(c,m,a,b); }
|
||||
__forceinline const vllong8 mask_or (const vboold8& m, const vllong8& c, const vllong8& a, const vllong8& b) { return _mm512_mask_or_epi64(c,m,a,b); }
|
||||
__forceinline vllong8 mask_and(const vboold8& m, const vllong8& c, const vllong8& a, const vllong8& b) { return _mm512_mask_and_epi64(c,m,a,b); }
|
||||
__forceinline vllong8 mask_or (const vboold8& m, const vllong8& c, const vllong8& a, const vllong8& b) { return _mm512_mask_or_epi64(c,m,a,b); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Assignment Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vllong8& operator +=( vllong8& a, const vllong8& b ) { return a = a + b; }
|
||||
__forceinline vllong8& operator +=( vllong8& a, const long long b ) { return a = a + b; }
|
||||
__forceinline vllong8& operator +=(vllong8& a, const vllong8& b) { return a = a + b; }
|
||||
__forceinline vllong8& operator +=(vllong8& a, long long b) { return a = a + b; }
|
||||
|
||||
__forceinline vllong8& operator -=( vllong8& a, const vllong8& b ) { return a = a - b; }
|
||||
__forceinline vllong8& operator -=( vllong8& a, const long long b ) { return a = a - b; }
|
||||
__forceinline vllong8& operator -=(vllong8& a, const vllong8& b) { return a = a - b; }
|
||||
__forceinline vllong8& operator -=(vllong8& a, long long b) { return a = a - b; }
|
||||
|
||||
__forceinline vllong8& operator *=( vllong8& a, const vllong8& b ) { return a = a * b; }
|
||||
__forceinline vllong8& operator *=( vllong8& a, const long long b ) { return a = a * b; }
|
||||
__forceinline vllong8& operator *=(vllong8& a, const vllong8& b) { return a = a * b; }
|
||||
__forceinline vllong8& operator *=(vllong8& a, long long b) { return a = a * b; }
|
||||
|
||||
__forceinline vllong8& operator &=( vllong8& a, const vllong8& b ) { return a = a & b; }
|
||||
__forceinline vllong8& operator &=( vllong8& a, const long long b ) { return a = a & b; }
|
||||
__forceinline vllong8& operator &=(vllong8& a, const vllong8& b) { return a = a & b; }
|
||||
__forceinline vllong8& operator &=(vllong8& a, long long b) { return a = a & b; }
|
||||
|
||||
__forceinline vllong8& operator |=( vllong8& a, const vllong8& b ) { return a = a | b; }
|
||||
__forceinline vllong8& operator |=( vllong8& a, const long long b ) { return a = a | b; }
|
||||
__forceinline vllong8& operator |=(vllong8& a, const vllong8& b) { return a = a | b; }
|
||||
__forceinline vllong8& operator |=(vllong8& a, long long b) { return a = a | b; }
|
||||
|
||||
__forceinline vllong8& operator <<=( vllong8& a, const long long b ) { return a = a << b; }
|
||||
__forceinline vllong8& operator >>=( vllong8& a, const long long b ) { return a = a >> b; }
|
||||
__forceinline vllong8& operator <<=(vllong8& a, long long b) { return a = a << b; }
|
||||
__forceinline vllong8& operator >>=(vllong8& a, long long b) { return a = a >> b; }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Comparison Operators + Select
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vboold8 operator ==( const vllong8& a, const vllong8& b ) { return _mm512_cmp_epi64_mask(a,b,_MM_CMPINT_EQ); }
|
||||
__forceinline const vboold8 operator ==( const vllong8& a, const long long b ) { return a == vllong8(b); }
|
||||
__forceinline const vboold8 operator ==( const long long a, const vllong8& b ) { return vllong8(a) == b; }
|
||||
__forceinline vboold8 operator ==(const vllong8& a, const vllong8& b) { return _mm512_cmp_epi64_mask(a,b,_MM_CMPINT_EQ); }
|
||||
__forceinline vboold8 operator ==(const vllong8& a, long long b) { return a == vllong8(b); }
|
||||
__forceinline vboold8 operator ==(long long a, const vllong8& b) { return vllong8(a) == b; }
|
||||
|
||||
__forceinline const vboold8 operator !=( const vllong8& a, const vllong8& b ) { return _mm512_cmp_epi64_mask(a,b,_MM_CMPINT_NE); }
|
||||
__forceinline const vboold8 operator !=( const vllong8& a, const long long b ) { return a != vllong8(b); }
|
||||
__forceinline const vboold8 operator !=( const long long a, const vllong8& b ) { return vllong8(a) != b; }
|
||||
__forceinline vboold8 operator !=(const vllong8& a, const vllong8& b) { return _mm512_cmp_epi64_mask(a,b,_MM_CMPINT_NE); }
|
||||
__forceinline vboold8 operator !=(const vllong8& a, long long b) { return a != vllong8(b); }
|
||||
__forceinline vboold8 operator !=(long long a, const vllong8& b) { return vllong8(a) != b; }
|
||||
|
||||
__forceinline const vboold8 operator < ( const vllong8& a, const vllong8& b ) { return _mm512_cmp_epi64_mask(a,b,_MM_CMPINT_LT); }
|
||||
__forceinline const vboold8 operator < ( const vllong8& a, const long long b ) { return a < vllong8(b); }
|
||||
__forceinline const vboold8 operator < ( const long long a, const vllong8& b ) { return vllong8(a) < b; }
|
||||
__forceinline vboold8 operator < (const vllong8& a, const vllong8& b) { return _mm512_cmp_epi64_mask(a,b,_MM_CMPINT_LT); }
|
||||
__forceinline vboold8 operator < (const vllong8& a, long long b) { return a < vllong8(b); }
|
||||
__forceinline vboold8 operator < (long long a, const vllong8& b) { return vllong8(a) < b; }
|
||||
|
||||
__forceinline const vboold8 operator >=( const vllong8& a, const vllong8& b ) { return _mm512_cmp_epi64_mask(a,b,_MM_CMPINT_GE); }
|
||||
__forceinline const vboold8 operator >=( const vllong8& a, const long long b ) { return a >= vllong8(b); }
|
||||
__forceinline const vboold8 operator >=( const long long a, const vllong8& b ) { return vllong8(a) >= b; }
|
||||
__forceinline vboold8 operator >=(const vllong8& a, const vllong8& b) { return _mm512_cmp_epi64_mask(a,b,_MM_CMPINT_GE); }
|
||||
__forceinline vboold8 operator >=(const vllong8& a, long long b) { return a >= vllong8(b); }
|
||||
__forceinline vboold8 operator >=(long long a, const vllong8& b) { return vllong8(a) >= b; }
|
||||
|
||||
__forceinline const vboold8 operator > ( const vllong8& a, const vllong8& b ) { return _mm512_cmp_epi64_mask(a,b,_MM_CMPINT_GT); }
|
||||
__forceinline const vboold8 operator > ( const vllong8& a, const long long b ) { return a > vllong8(b); }
|
||||
__forceinline const vboold8 operator > ( const long long a, const vllong8& b ) { return vllong8(a) > b; }
|
||||
__forceinline vboold8 operator > (const vllong8& a, const vllong8& b) { return _mm512_cmp_epi64_mask(a,b,_MM_CMPINT_GT); }
|
||||
__forceinline vboold8 operator > (const vllong8& a, long long b) { return a > vllong8(b); }
|
||||
__forceinline vboold8 operator > (long long a, const vllong8& b) { return vllong8(a) > b; }
|
||||
|
||||
__forceinline const vboold8 operator <=( const vllong8& a, const vllong8& b ) { return _mm512_cmp_epi64_mask(a,b,_MM_CMPINT_LE); }
|
||||
__forceinline const vboold8 operator <=( const vllong8& a, const long long b ) { return a <= vllong8(b); }
|
||||
__forceinline const vboold8 operator <=( const long long a, const vllong8& b ) { return vllong8(a) <= b; }
|
||||
__forceinline vboold8 operator <=(const vllong8& a, const vllong8& b) { return _mm512_cmp_epi64_mask(a,b,_MM_CMPINT_LE); }
|
||||
__forceinline vboold8 operator <=(const vllong8& a, long long b) { return a <= vllong8(b); }
|
||||
__forceinline vboold8 operator <=(long long a, const vllong8& b) { return vllong8(a) <= b; }
|
||||
|
||||
__forceinline vboold8 eq(const vllong8& a, const vllong8& b) { return _mm512_cmp_epi64_mask(a,b,_MM_CMPINT_EQ); }
|
||||
__forceinline vboold8 ne(const vllong8& a, const vllong8& b) { return _mm512_cmp_epi64_mask(a,b,_MM_CMPINT_NE); }
|
||||
@@ -278,7 +277,7 @@ namespace embree
|
||||
__forceinline vboold8 gt(const vboold8 mask, const vllong8& a, const vllong8& b) { return _mm512_mask_cmp_epi64_mask(mask,a,b,_MM_CMPINT_GT); }
|
||||
__forceinline vboold8 le(const vboold8 mask, const vllong8& a, const vllong8& b) { return _mm512_mask_cmp_epi64_mask(mask,a,b,_MM_CMPINT_LE); }
|
||||
|
||||
__forceinline const vllong8 select( const vboold8& m, const vllong8& t, const vllong8& f ) {
|
||||
__forceinline vllong8 select(const vboold8& m, const vllong8& t, const vllong8& f) {
|
||||
return _mm512_mask_or_epi64(f,m,t,t);
|
||||
}
|
||||
|
||||
@@ -298,38 +297,41 @@ namespace embree
|
||||
// Movement/Shifting/Shuffling Functions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<size_t i>
|
||||
__forceinline const vllong8 shuffle( const vllong8& a ) {
|
||||
return _mm512_castpd_si512(_mm512_permute_pd(_mm512_castsi512_pd(a), _MM_SHUFFLE(i, i, i, i)));
|
||||
}
|
||||
|
||||
template<int A, int B, int C, int D>
|
||||
__forceinline vllong8 shuffle (const vllong8& v) {
|
||||
return _mm512_castpd_si512(_mm512_permute_pd(_mm512_castsi512_pd(v),_MM_SHUFFLE(D,C,B,A)));
|
||||
template<int i0, int i1>
|
||||
__forceinline vllong8 shuffle(const vllong8& v) {
|
||||
return _mm512_castpd_si512(_mm512_permute_pd(_mm512_castsi512_pd(v), (i1 << 7) | (i0 << 6) | (i1 << 5) | (i0 << 4) | (i1 << 3) | (i0 << 2) | (i1 << 1) | i0));
|
||||
}
|
||||
|
||||
template<int i>
|
||||
__forceinline vllong8 shuffle4(const vllong8& x) {
|
||||
return _mm512_castpd_si512(_mm512_shuffle_f64x2(_mm512_castsi512_pd(x),_mm512_castsi512_pd(x),_MM_SHUFFLE(i,i,i,i)));
|
||||
__forceinline vllong8 shuffle(const vllong8& v) {
|
||||
return shuffle<i, i>(v);
|
||||
}
|
||||
|
||||
template<int A, int B>
|
||||
__forceinline vllong8 shuffle4(const vllong8& x) {
|
||||
return _mm512_castpd_si512(_mm512_shuffle_f64x2(_mm512_castsi512_pd(x),_mm512_castsi512_pd(x),_MM_SHUFFLE(0,0,B,A)));
|
||||
template<int i0, int i1, int i2, int i3>
|
||||
__forceinline vllong8 shuffle(const vllong8& v) {
|
||||
return _mm512_permutex_epi64(v, _MM_SHUFFLE(i3, i2, i1, i0));
|
||||
}
|
||||
|
||||
template<int i0, int i1>
|
||||
__forceinline vllong8 shuffle4(const vllong8& v) {
|
||||
return _mm512_shuffle_i64x2(v, v, _MM_SHUFFLE(i1*2+1, i1*2, i0*2+1, i0*2));
|
||||
}
|
||||
|
||||
template<int i>
|
||||
__forceinline vllong8 align_shift_right(const vllong8& a, const vllong8& b)
|
||||
{
|
||||
return _mm512_alignr_epi64(a,b,i);
|
||||
__forceinline vllong8 shuffle4(const vllong8& v) {
|
||||
return shuffle4<i, i>(v);
|
||||
}
|
||||
|
||||
template<int i>
|
||||
__forceinline vllong8 align_shift_right(const vllong8& a, const vllong8& b) {
|
||||
return _mm512_alignr_epi64(a, b, i);
|
||||
};
|
||||
|
||||
__forceinline long long toScalar(const vllong8& a)
|
||||
{
|
||||
return _mm_cvtsi128_si64(_mm512_castsi512_si128(a));
|
||||
__forceinline long long toScalar(const vllong8& v) {
|
||||
return _mm_cvtsi128_si64(_mm512_castsi512_si128(v));
|
||||
}
|
||||
|
||||
__forceinline vllong8 zeroExtend32Bit(const __m512i &a) {
|
||||
__forceinline vllong8 zeroExtend32Bit(const __m512i& a) {
|
||||
return _mm512_cvtepu32_epi64(_mm512_castsi512_si256(a));
|
||||
}
|
||||
|
||||
@@ -337,13 +339,13 @@ namespace embree
|
||||
/// Reductions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vllong8 vreduce_min2(vllong8 x) { return min(x,shuffle<1,0,3,2>(x)); }
|
||||
__forceinline vllong8 vreduce_min4(vllong8 x) { x = vreduce_min2(x); return min(x,shuffle<2,3,0,1>(x)); }
|
||||
__forceinline vllong8 vreduce_min (vllong8 x) { x = vreduce_min4(x); return min(x,shuffle4<1,0>(x)); }
|
||||
__forceinline vllong8 vreduce_min2(vllong8 x) { return min(x, shuffle<1,0,3,2>(x)); }
|
||||
__forceinline vllong8 vreduce_min4(vllong8 x) { x = vreduce_min2(x); return min(x, shuffle<2,3,0,1>(x)); }
|
||||
__forceinline vllong8 vreduce_min (vllong8 x) { x = vreduce_min4(x); return min(x, shuffle4<1,0>(x)); }
|
||||
|
||||
__forceinline vllong8 vreduce_max2(vllong8 x) { return max(x,shuffle<1,0,3,2>(x)); }
|
||||
__forceinline vllong8 vreduce_max4(vllong8 x) { x = vreduce_max2(x); return max(x,shuffle<2,3,0,1>(x)); }
|
||||
__forceinline vllong8 vreduce_max (vllong8 x) { x = vreduce_max4(x); return max(x,shuffle4<1,0>(x)); }
|
||||
__forceinline vllong8 vreduce_max2(vllong8 x) { return max(x, shuffle<1,0,3,2>(x)); }
|
||||
__forceinline vllong8 vreduce_max4(vllong8 x) { x = vreduce_max2(x); return max(x, shuffle<2,3,0,1>(x)); }
|
||||
__forceinline vllong8 vreduce_max (vllong8 x) { x = vreduce_max4(x); return max(x, shuffle4<1,0>(x)); }
|
||||
|
||||
__forceinline vllong8 vreduce_and2(vllong8 x) { return x & shuffle<1,0,3,2>(x); }
|
||||
__forceinline vllong8 vreduce_and4(vllong8 x) { x = vreduce_and2(x); return x & shuffle<2,3,0,1>(x); }
|
||||
@@ -379,7 +381,7 @@ namespace embree
|
||||
/// Output Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline std::ostream& operator<<(std::ostream& cout, const vllong8& v)
|
||||
__forceinline std::ostream& operator <<(std::ostream& cout, const vllong8& v)
|
||||
{
|
||||
cout << "<" << v[0];
|
||||
for (size_t i=1; i<8; i++) cout << ", " << v[i];
|
||||
|
||||
+145
-147
@@ -38,24 +38,24 @@ namespace embree
|
||||
|
||||
__forceinline vuint() {}
|
||||
__forceinline vuint(const vuint16& t) { v = t.v; }
|
||||
__forceinline vuint16& operator=(const vuint16& f) { v = f.v; return *this; }
|
||||
__forceinline vuint16& operator =(const vuint16& f) { v = f.v; return *this; }
|
||||
|
||||
__forceinline vuint(const __m512i& t) { v = t; }
|
||||
__forceinline operator __m512i () const { return v; }
|
||||
__forceinline operator __m256i () const { return _mm512_castsi512_si256(v); }
|
||||
__forceinline operator __m512i() const { return v; }
|
||||
__forceinline operator __m256i() const { return _mm512_castsi512_si256(v); }
|
||||
|
||||
__forceinline vuint(const unsigned int i) {
|
||||
__forceinline vuint(unsigned int i) {
|
||||
v = _mm512_set1_epi32(i);
|
||||
}
|
||||
|
||||
__forceinline vuint(const unsigned int a, const unsigned int b, const unsigned int c, const unsigned int d) {
|
||||
__forceinline vuint(unsigned int a, unsigned int b, unsigned int c, unsigned int d) {
|
||||
v = _mm512_set4_epi32(d,c,b,a);
|
||||
}
|
||||
|
||||
__forceinline vuint(const unsigned int a0 , const unsigned int a1 , const unsigned int a2 , const unsigned int a3,
|
||||
const unsigned int a4 , const unsigned int a5 , const unsigned int a6 , const unsigned int a7,
|
||||
const unsigned int a8 , const unsigned int a9 , const unsigned int a10, const unsigned int a11,
|
||||
const unsigned int a12, const unsigned int a13, const unsigned int a14, const unsigned int a15)
|
||||
__forceinline vuint(unsigned int a0 , unsigned int a1 , unsigned int a2 , unsigned int a3,
|
||||
unsigned int a4 , unsigned int a5 , unsigned int a6 , unsigned int a7,
|
||||
unsigned int a8 , unsigned int a9 , unsigned int a10, unsigned int a11,
|
||||
unsigned int a12, unsigned int a13, unsigned int a14, unsigned int a15)
|
||||
{
|
||||
v = _mm512_set_epi32(a15,a14,a13,a12,a11,a10,a9,a8,a7,a6,a5,a4,a3,a2,a1,a0);
|
||||
}
|
||||
@@ -68,20 +68,16 @@ namespace embree
|
||||
/// Constants
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vuint( ZeroTy ) : v(_mm512_setzero_epi32()) {}
|
||||
__forceinline vuint( OneTy ) : v(_mm512_set1_epi32(1)) {}
|
||||
__forceinline vuint( StepTy ) : v(_mm512_set_epi32(15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0)) {}
|
||||
__forceinline vuint( ReverseStepTy ) : v(_mm512_setr_epi32(15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0)) {}
|
||||
|
||||
__forceinline static vuint16 zero() { return _mm512_setzero_epi32(); }
|
||||
__forceinline static vuint16 one () { return _mm512_set1_epi32(1); }
|
||||
__forceinline static vuint16 neg_one () { return _mm512_set1_epi32(-1); }
|
||||
__forceinline vuint(ZeroTy) : v(_mm512_setzero_epi32()) {}
|
||||
__forceinline vuint(OneTy) : v(_mm512_set1_epi32(1)) {}
|
||||
__forceinline vuint(StepTy) : v(_mm512_set_epi32(15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0)) {}
|
||||
__forceinline vuint(ReverseStepTy) : v(_mm512_setr_epi32(15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0)) {}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Loads and Stores
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static __forceinline void store_nt(void *__restrict__ ptr, const vuint16& a) {
|
||||
static __forceinline void store_nt(void* __restrict__ ptr, const vuint16& a) {
|
||||
_mm512_stream_si512((__m512i*)ptr,a);
|
||||
}
|
||||
|
||||
@@ -98,18 +94,18 @@ namespace embree
|
||||
return _mm512_load_si512(addr);
|
||||
}
|
||||
|
||||
static __forceinline vuint16 load( const unsigned short* const ptr ) { return _mm512_cvtepu16_epi32(*(__m256i*)ptr); }
|
||||
static __forceinline vuint16 load(unsigned short* ptr) { return _mm512_cvtepu16_epi32(*(__m256i*)ptr); }
|
||||
|
||||
|
||||
static __forceinline void store(void* ptr, const vuint16& v) {
|
||||
_mm512_store_si512(ptr,v);
|
||||
}
|
||||
|
||||
static __forceinline void storeu(void* ptr, const vuint16& v ) {
|
||||
static __forceinline void storeu(void* ptr, const vuint16& v) {
|
||||
_mm512_storeu_si512(ptr,v);
|
||||
}
|
||||
|
||||
static __forceinline void storeu(const vboolf16& mask, int* ptr, const vuint16& f ) {
|
||||
static __forceinline void storeu(const vboolf16& mask, int* ptr, const vuint16& f) {
|
||||
_mm512_mask_storeu_epi32(ptr,mask,f);
|
||||
}
|
||||
|
||||
@@ -117,20 +113,20 @@ namespace embree
|
||||
_mm512_mask_store_epi32(addr,mask,v2);
|
||||
}
|
||||
|
||||
/* pass by value to avoid compiler generating inefficient code */
|
||||
static __forceinline void storeu_compact(const vboolf16 mask,void * addr, const vuint16 reg) {
|
||||
/* pass by value to avoid compiler generating inefficient code */
|
||||
static __forceinline void storeu_compact(const vboolf16 mask, void* addr, const vuint16 reg) {
|
||||
_mm512_mask_compressstoreu_epi32(addr,mask,reg);
|
||||
}
|
||||
|
||||
static __forceinline vuint16 compact64bit(const vboolf16& mask, vuint16 &v) {
|
||||
static __forceinline vuint16 compact64bit(const vboolf16& mask, vuint16& v) {
|
||||
return _mm512_mask_compress_epi64(v,mask,v);
|
||||
}
|
||||
|
||||
static __forceinline vuint16 compact(const vboolf16& mask, vuint16 &v) {
|
||||
static __forceinline vuint16 compact(const vboolf16& mask, vuint16& v) {
|
||||
return _mm512_mask_compress_epi32(v,mask,v);
|
||||
}
|
||||
|
||||
static __forceinline vuint16 compact(const vboolf16& mask, const vuint16 &a, vuint16 &b) {
|
||||
static __forceinline vuint16 compact(const vboolf16& mask, const vuint16& a, vuint16& b) {
|
||||
return _mm512_mask_compress_epi32(a,mask,b);
|
||||
}
|
||||
|
||||
@@ -138,6 +134,30 @@ namespace embree
|
||||
return _mm512_mask_expand_epi32(b,mask,a);
|
||||
}
|
||||
|
||||
template<int scale = 4>
|
||||
static __forceinline vuint16 gather(const unsigned int* ptr, const vint16& index) {
|
||||
return _mm512_i32gather_epi32(index,ptr,scale);
|
||||
}
|
||||
|
||||
template<int scale = 4>
|
||||
static __forceinline vuint16 gather(const vboolf16& mask, const unsigned int* ptr, const vint16& index) {
|
||||
return _mm512_mask_i32gather_epi32(_mm512_undefined_epi32(),mask,index,ptr,scale);
|
||||
}
|
||||
|
||||
template<int scale = 4>
|
||||
static __forceinline vuint16 gather(const vboolf16& mask, vuint16& dest, const unsigned int* ptr, const vint16& index) {
|
||||
return _mm512_mask_i32gather_epi32(dest,mask,index,ptr,scale);
|
||||
}
|
||||
|
||||
template<int scale = 4>
|
||||
static __forceinline void scatter(unsigned int* ptr, const vint16& index, const vuint16& v) {
|
||||
_mm512_i32scatter_epi32((int*)ptr,index,v,scale);
|
||||
}
|
||||
|
||||
template<int scale = 4>
|
||||
static __forceinline void scatter(const vboolf16& mask, unsigned int* ptr, const vint16& index, const vuint16& v) {
|
||||
_mm512_mask_i32scatter_epi32((int*)ptr,mask,index,v,scale);
|
||||
}
|
||||
|
||||
static __forceinline vuint16 broadcast64bit(size_t v) {
|
||||
return _mm512_set1_epi64(v);
|
||||
@@ -148,128 +168,127 @@ namespace embree
|
||||
return _mm_cvtsi128_si64(_mm512_castsi512_si128(v));
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Array Access
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline unsigned int& operator[](const size_t index) { assert(index < 16); return i[index]; }
|
||||
__forceinline const unsigned int& operator[](const size_t index) const { assert(index < 16); return i[index]; }
|
||||
__forceinline unsigned int& operator [](size_t index) { assert(index < 16); return i[index]; }
|
||||
__forceinline const unsigned int& operator [](size_t index) const { assert(index < 16); return i[index]; }
|
||||
|
||||
__forceinline unsigned int uint (const size_t index) const { assert(index < 16); return ((unsigned int*)i)[index]; }
|
||||
__forceinline size_t& uint64_t(const size_t index) const { assert(index < 8); return ((size_t*)i)[index]; }
|
||||
__forceinline unsigned int uint (size_t index) const { assert(index < 16); return ((unsigned int*)i)[index]; }
|
||||
__forceinline size_t& uint64_t(size_t index) const { assert(index < 8); return ((size_t*)i)[index]; }
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Unary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vuint16 asUInt ( const __m512& a ) { return _mm512_castps_si512(a); }
|
||||
__forceinline const vuint16 operator +( const vuint16& a ) { return a; }
|
||||
__forceinline const vuint16 operator -( const vuint16& a ) { return _mm512_sub_epi32(_mm512_setzero_epi32(), a); }
|
||||
__forceinline vuint16 asUInt(const __m512& a) { return _mm512_castps_si512(a); }
|
||||
__forceinline vuint16 operator +(const vuint16& a) { return a; }
|
||||
__forceinline vuint16 operator -(const vuint16& a) { return _mm512_sub_epi32(_mm512_setzero_epi32(), a); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Binary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vuint16 operator +( const vuint16& a, const vuint16& b ) { return _mm512_add_epi32(a, b); }
|
||||
__forceinline const vuint16 operator +( const vuint16& a, const unsigned int b ) { return a + vuint16(b); }
|
||||
__forceinline const vuint16 operator +( const unsigned int a, const vuint16& b ) { return vuint16(a) + b; }
|
||||
__forceinline vuint16 operator +(const vuint16& a, const vuint16& b) { return _mm512_add_epi32(a, b); }
|
||||
__forceinline vuint16 operator +(const vuint16& a, unsigned int b) { return a + vuint16(b); }
|
||||
__forceinline vuint16 operator +(unsigned int a, const vuint16& b) { return vuint16(a) + b; }
|
||||
|
||||
__forceinline const vuint16 operator -( const vuint16& a, const vuint16& b ) { return _mm512_sub_epi32(a, b); }
|
||||
__forceinline const vuint16 operator -( const vuint16& a, const unsigned int b ) { return a - vuint16(b); }
|
||||
__forceinline const vuint16 operator -( const unsigned int a, const vuint16& b ) { return vuint16(a) - b; }
|
||||
__forceinline vuint16 operator -(const vuint16& a, const vuint16& b) { return _mm512_sub_epi32(a, b); }
|
||||
__forceinline vuint16 operator -(const vuint16& a, unsigned int b) { return a - vuint16(b); }
|
||||
__forceinline vuint16 operator -(unsigned int a, const vuint16& b) { return vuint16(a) - b; }
|
||||
|
||||
__forceinline const vuint16 operator *( const vuint16& a, const vuint16& b ) { return _mm512_mul_epu32(a, b); }
|
||||
__forceinline const vuint16 operator *( const vuint16& a, const unsigned int b ) { return a * vuint16(b); }
|
||||
__forceinline const vuint16 operator *( const unsigned int a, const vuint16& b ) { return vuint16(a) * b; }
|
||||
__forceinline vuint16 operator *(const vuint16& a, const vuint16& b) { return _mm512_mul_epu32(a, b); }
|
||||
__forceinline vuint16 operator *(const vuint16& a, unsigned int b) { return a * vuint16(b); }
|
||||
__forceinline vuint16 operator *(unsigned int a, const vuint16& b) { return vuint16(a) * b; }
|
||||
|
||||
__forceinline const vuint16 operator &( const vuint16& a, const vuint16& b ) { return _mm512_and_epi32(a, b); }
|
||||
__forceinline const vuint16 operator &( const vuint16& a, const unsigned int b ) { return a & vuint16(b); }
|
||||
__forceinline const vuint16 operator &( const unsigned int a, const vuint16& b ) { return vuint16(a) & b; }
|
||||
__forceinline vuint16 operator &(const vuint16& a, const vuint16& b) { return _mm512_and_epi32(a, b); }
|
||||
__forceinline vuint16 operator &(const vuint16& a, unsigned int b) { return a & vuint16(b); }
|
||||
__forceinline vuint16 operator &(unsigned int a, const vuint16& b) { return vuint16(a) & b; }
|
||||
|
||||
__forceinline const vuint16 operator |( const vuint16& a, const vuint16& b ) { return _mm512_or_epi32(a, b); }
|
||||
__forceinline const vuint16 operator |( const vuint16& a, const unsigned int b ) { return a | vuint16(b); }
|
||||
__forceinline const vuint16 operator |( const unsigned int a, const vuint16& b ) { return vuint16(a) | b; }
|
||||
__forceinline vuint16 operator |(const vuint16& a, const vuint16& b) { return _mm512_or_epi32(a, b); }
|
||||
__forceinline vuint16 operator |(const vuint16& a, unsigned int b) { return a | vuint16(b); }
|
||||
__forceinline vuint16 operator |(unsigned int a, const vuint16& b) { return vuint16(a) | b; }
|
||||
|
||||
__forceinline const vuint16 operator ^( const vuint16& a, const vuint16& b ) { return _mm512_xor_epi32(a, b); }
|
||||
__forceinline const vuint16 operator ^( const vuint16& a, const unsigned int b ) { return a ^ vuint16(b); }
|
||||
__forceinline const vuint16 operator ^( const unsigned int a, const vuint16& b ) { return vuint16(a) ^ b; }
|
||||
__forceinline vuint16 operator ^(const vuint16& a, const vuint16& b) { return _mm512_xor_epi32(a, b); }
|
||||
__forceinline vuint16 operator ^(const vuint16& a, unsigned int b) { return a ^ vuint16(b); }
|
||||
__forceinline vuint16 operator ^(unsigned int a, const vuint16& b) { return vuint16(a) ^ b; }
|
||||
|
||||
__forceinline const vuint16 operator <<( const vuint16& a, const unsigned int n ) { return _mm512_slli_epi32(a, n); }
|
||||
__forceinline const vuint16 operator >>( const vuint16& a, const unsigned int n ) { return _mm512_srli_epi32(a, n); }
|
||||
__forceinline vuint16 operator <<(const vuint16& a, unsigned int n) { return _mm512_slli_epi32(a, n); }
|
||||
__forceinline vuint16 operator >>(const vuint16& a, unsigned int n) { return _mm512_srli_epi32(a, n); }
|
||||
|
||||
__forceinline const vuint16 operator <<( const vuint16& a, const vuint16& n ) { return _mm512_sllv_epi32(a, n); }
|
||||
__forceinline const vuint16 operator >>( const vuint16& a, const vuint16& n ) { return _mm512_srlv_epi32(a, n); }
|
||||
__forceinline vuint16 operator <<(const vuint16& a, const vuint16& n) { return _mm512_sllv_epi32(a, n); }
|
||||
__forceinline vuint16 operator >>(const vuint16& a, const vuint16& n) { return _mm512_srlv_epi32(a, n); }
|
||||
|
||||
__forceinline const vuint16 sll ( const vuint16& a, const unsigned int b ) { return _mm512_slli_epi32(a, b); }
|
||||
__forceinline const vuint16 sra ( const vuint16& a, const unsigned int b ) { return _mm512_srai_epi32(a, b); }
|
||||
__forceinline const vuint16 srl ( const vuint16& a, const unsigned int b ) { return _mm512_srli_epi32(a, b); }
|
||||
__forceinline vuint16 sll (const vuint16& a, unsigned int b) { return _mm512_slli_epi32(a, b); }
|
||||
__forceinline vuint16 sra (const vuint16& a, unsigned int b) { return _mm512_srai_epi32(a, b); }
|
||||
__forceinline vuint16 srl (const vuint16& a, unsigned int b) { return _mm512_srli_epi32(a, b); }
|
||||
|
||||
__forceinline const vuint16 min( const vuint16& a, const vuint16& b ) { return _mm512_min_epu32(a, b); }
|
||||
__forceinline const vuint16 min( const vuint16& a, const unsigned int b ) { return min(a,vuint16(b)); }
|
||||
__forceinline const vuint16 min( const unsigned int a, const vuint16& b ) { return min(vuint16(a),b); }
|
||||
__forceinline vuint16 min(const vuint16& a, const vuint16& b) { return _mm512_min_epu32(a, b); }
|
||||
__forceinline vuint16 min(const vuint16& a, unsigned int b) { return min(a,vuint16(b)); }
|
||||
__forceinline vuint16 min(unsigned int a, const vuint16& b) { return min(vuint16(a),b); }
|
||||
|
||||
__forceinline const vuint16 max( const vuint16& a, const vuint16& b ) { return _mm512_max_epu32(a, b); }
|
||||
__forceinline const vuint16 max( const vuint16& a, const unsigned int b ) { return max(a,vuint16(b)); }
|
||||
__forceinline const vuint16 max( const unsigned int a, const vuint16& b ) { return max(vuint16(a),b); }
|
||||
__forceinline vuint16 max(const vuint16& a, const vuint16& b) { return _mm512_max_epu32(a, b); }
|
||||
__forceinline vuint16 max(const vuint16& a, unsigned int b) { return max(a,vuint16(b)); }
|
||||
__forceinline vuint16 max(unsigned int a, const vuint16& b) { return max(vuint16(a),b); }
|
||||
|
||||
__forceinline const vuint16 mask_add(const vboolf16& mask, vuint16& c, const vuint16& a, const vuint16& b) { return _mm512_mask_add_epi32(c,mask,a,b); }
|
||||
__forceinline const vuint16 mask_sub(const vboolf16& mask, vuint16& c, const vuint16& a, const vuint16& b) { return _mm512_mask_sub_epi32(c,mask,a,b); }
|
||||
__forceinline vuint16 mask_add(const vboolf16& mask, vuint16& c, const vuint16& a, const vuint16& b) { return _mm512_mask_add_epi32(c,mask,a,b); }
|
||||
__forceinline vuint16 mask_sub(const vboolf16& mask, vuint16& c, const vuint16& a, const vuint16& b) { return _mm512_mask_sub_epi32(c,mask,a,b); }
|
||||
|
||||
__forceinline const vuint16 mask_and(const vboolf16& m,vuint16& c, const vuint16& a, const vuint16& b) { return _mm512_mask_and_epi32(c,m,a,b); }
|
||||
__forceinline const vuint16 mask_or (const vboolf16& m,vuint16& c, const vuint16& a, const vuint16& b) { return _mm512_mask_or_epi32(c,m,a,b); }
|
||||
__forceinline vuint16 mask_and(const vboolf16& m, vuint16& c, const vuint16& a, const vuint16& b) { return _mm512_mask_and_epi32(c,m,a,b); }
|
||||
__forceinline vuint16 mask_or (const vboolf16& m, vuint16& c, const vuint16& a, const vuint16& b) { return _mm512_mask_or_epi32(c,m,a,b); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Assignment Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vuint16& operator +=( vuint16& a, const vuint16& b ) { return a = a + b; }
|
||||
__forceinline vuint16& operator +=( vuint16& a, const unsigned int b ) { return a = a + b; }
|
||||
__forceinline vuint16& operator +=(vuint16& a, const vuint16& b) { return a = a + b; }
|
||||
__forceinline vuint16& operator +=(vuint16& a, unsigned int b) { return a = a + b; }
|
||||
|
||||
__forceinline vuint16& operator -=( vuint16& a, const vuint16& b ) { return a = a - b; }
|
||||
__forceinline vuint16& operator -=( vuint16& a, const unsigned int b ) { return a = a - b; }
|
||||
__forceinline vuint16& operator -=(vuint16& a, const vuint16& b) { return a = a - b; }
|
||||
__forceinline vuint16& operator -=(vuint16& a, unsigned int b) { return a = a - b; }
|
||||
|
||||
__forceinline vuint16& operator *=( vuint16& a, const vuint16& b ) { return a = a * b; }
|
||||
__forceinline vuint16& operator *=( vuint16& a, const unsigned int b ) { return a = a * b; }
|
||||
__forceinline vuint16& operator *=(vuint16& a, const vuint16& b) { return a = a * b; }
|
||||
__forceinline vuint16& operator *=(vuint16& a, unsigned int b) { return a = a * b; }
|
||||
|
||||
__forceinline vuint16& operator &=( vuint16& a, const vuint16& b ) { return a = a & b; }
|
||||
__forceinline vuint16& operator &=( vuint16& a, const unsigned int b ) { return a = a & b; }
|
||||
__forceinline vuint16& operator &=(vuint16& a, const vuint16& b) { return a = a & b; }
|
||||
__forceinline vuint16& operator &=(vuint16& a, unsigned int b) { return a = a & b; }
|
||||
|
||||
__forceinline vuint16& operator |=( vuint16& a, const vuint16& b ) { return a = a | b; }
|
||||
__forceinline vuint16& operator |=( vuint16& a, const unsigned int b ) { return a = a | b; }
|
||||
__forceinline vuint16& operator |=(vuint16& a, const vuint16& b) { return a = a | b; }
|
||||
__forceinline vuint16& operator |=(vuint16& a, unsigned int b) { return a = a | b; }
|
||||
|
||||
__forceinline vuint16& operator <<=( vuint16& a, const unsigned int b ) { return a = a << b; }
|
||||
__forceinline vuint16& operator >>=( vuint16& a, const unsigned int b ) { return a = a >> b; }
|
||||
__forceinline vuint16& operator <<=(vuint16& a, unsigned int b) { return a = a << b; }
|
||||
__forceinline vuint16& operator >>=(vuint16& a, unsigned int b) { return a = a >> b; }
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Comparison Operators + Select
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vboolf16 operator ==( const vuint16& a, const vuint16& b ) { return _mm512_cmp_epu32_mask(a,b,_MM_CMPINT_EQ); }
|
||||
__forceinline const vboolf16 operator ==( const vuint16& a, const unsigned int b ) { return a == vuint16(b); }
|
||||
__forceinline const vboolf16 operator ==( const unsigned int a, const vuint16& b ) { return vuint16(a) == b; }
|
||||
__forceinline vboolf16 operator ==(const vuint16& a, const vuint16& b) { return _mm512_cmp_epu32_mask(a,b,_MM_CMPINT_EQ); }
|
||||
__forceinline vboolf16 operator ==(const vuint16& a, unsigned int b) { return a == vuint16(b); }
|
||||
__forceinline vboolf16 operator ==(unsigned int a, const vuint16& b) { return vuint16(a) == b; }
|
||||
|
||||
__forceinline const vboolf16 operator !=( const vuint16& a, const vuint16& b ) { return _mm512_cmp_epu32_mask(a,b,_MM_CMPINT_NE); }
|
||||
__forceinline const vboolf16 operator !=( const vuint16& a, const unsigned int b ) { return a != vuint16(b); }
|
||||
__forceinline const vboolf16 operator !=( const unsigned int a, const vuint16& b ) { return vuint16(a) != b; }
|
||||
__forceinline vboolf16 operator !=(const vuint16& a, const vuint16& b) { return _mm512_cmp_epu32_mask(a,b,_MM_CMPINT_NE); }
|
||||
__forceinline vboolf16 operator !=(const vuint16& a, unsigned int b) { return a != vuint16(b); }
|
||||
__forceinline vboolf16 operator !=(unsigned int a, const vuint16& b) { return vuint16(a) != b; }
|
||||
|
||||
__forceinline const vboolf16 operator < ( const vuint16& a, const vuint16& b ) { return _mm512_cmp_epu32_mask(a,b,_MM_CMPINT_LT); }
|
||||
__forceinline const vboolf16 operator < ( const vuint16& a, const unsigned int b ) { return a < vuint16(b); }
|
||||
__forceinline const vboolf16 operator < ( const unsigned int a, const vuint16& b ) { return vuint16(a) < b; }
|
||||
__forceinline vboolf16 operator < (const vuint16& a, const vuint16& b) { return _mm512_cmp_epu32_mask(a,b,_MM_CMPINT_LT); }
|
||||
__forceinline vboolf16 operator < (const vuint16& a, unsigned int b) { return a < vuint16(b); }
|
||||
__forceinline vboolf16 operator < (unsigned int a, const vuint16& b) { return vuint16(a) < b; }
|
||||
|
||||
__forceinline const vboolf16 operator >=( const vuint16& a, const vuint16& b ) { return _mm512_cmp_epu32_mask(a,b,_MM_CMPINT_GE); }
|
||||
__forceinline const vboolf16 operator >=( const vuint16& a, const unsigned int b ) { return a >= vuint16(b); }
|
||||
__forceinline const vboolf16 operator >=( const unsigned int a, const vuint16& b ) { return vuint16(a) >= b; }
|
||||
__forceinline vboolf16 operator >=(const vuint16& a, const vuint16& b) { return _mm512_cmp_epu32_mask(a,b,_MM_CMPINT_GE); }
|
||||
__forceinline vboolf16 operator >=(const vuint16& a, unsigned int b) { return a >= vuint16(b); }
|
||||
__forceinline vboolf16 operator >=(unsigned int a, const vuint16& b) { return vuint16(a) >= b; }
|
||||
|
||||
__forceinline const vboolf16 operator > ( const vuint16& a, const vuint16& b ) { return _mm512_cmp_epu32_mask(a,b,_MM_CMPINT_GT); }
|
||||
__forceinline const vboolf16 operator > ( const vuint16& a, const unsigned int b ) { return a > vuint16(b); }
|
||||
__forceinline const vboolf16 operator > ( const unsigned int a, const vuint16& b ) { return vuint16(a) > b; }
|
||||
__forceinline vboolf16 operator > (const vuint16& a, const vuint16& b) { return _mm512_cmp_epu32_mask(a,b,_MM_CMPINT_GT); }
|
||||
__forceinline vboolf16 operator > (const vuint16& a, unsigned int b) { return a > vuint16(b); }
|
||||
__forceinline vboolf16 operator > (unsigned int a, const vuint16& b) { return vuint16(a) > b; }
|
||||
|
||||
__forceinline const vboolf16 operator <=( const vuint16& a, const vuint16& b ) { return _mm512_cmp_epu32_mask(a,b,_MM_CMPINT_LE); }
|
||||
__forceinline const vboolf16 operator <=( const vuint16& a, const unsigned int b ) { return a <= vuint16(b); }
|
||||
__forceinline const vboolf16 operator <=( const unsigned int a, const vuint16& b ) { return vuint16(a) <= b; }
|
||||
__forceinline vboolf16 operator <=(const vuint16& a, const vuint16& b) { return _mm512_cmp_epu32_mask(a,b,_MM_CMPINT_LE); }
|
||||
__forceinline vboolf16 operator <=(const vuint16& a, unsigned int b) { return a <= vuint16(b); }
|
||||
__forceinline vboolf16 operator <=(unsigned int a, const vuint16& b) { return vuint16(a) <= b; }
|
||||
|
||||
__forceinline vboolf16 eq(const vuint16& a, const vuint16& b) { return _mm512_cmp_epu32_mask(a,b,_MM_CMPINT_EQ); }
|
||||
__forceinline vboolf16 ne(const vuint16& a, const vuint16& b) { return _mm512_cmp_epu32_mask(a,b,_MM_CMPINT_NE); }
|
||||
@@ -286,7 +305,7 @@ namespace embree
|
||||
__forceinline vboolf16 le(const vboolf16 mask, const vuint16& a, const vuint16& b) { return _mm512_mask_cmp_epu32_mask(mask,a,b,_MM_CMPINT_LE); }
|
||||
|
||||
|
||||
__forceinline const vuint16 select( const vboolf16& m, const vuint16& t, const vuint16& f ) {
|
||||
__forceinline vuint16 select(const vboolf16& m, const vuint16& t, const vuint16& f) {
|
||||
return _mm512_mask_or_epi32(f,m,t,t);
|
||||
}
|
||||
|
||||
@@ -306,50 +325,48 @@ namespace embree
|
||||
// Movement/Shifting/Shuffling Functions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<size_t i>
|
||||
__forceinline const vuint16 shuffle( const vuint16& a ) {
|
||||
return _mm512_castps_si512(_mm512_permute_ps(_mm512_castsi512_ps(a), _MM_SHUFFLE(i, i, i, i)));
|
||||
template<int i>
|
||||
__forceinline vuint16 shuffle(const vuint16& v) {
|
||||
return _mm512_castps_si512(_mm512_permute_ps(_mm512_castsi512_ps(v), _MM_SHUFFLE(i, i, i, i)));
|
||||
}
|
||||
|
||||
template<int A, int B, int C, int D>
|
||||
__forceinline vuint16 shuffle (const vuint16& v) {
|
||||
return _mm512_castps_si512(_mm512_permute_ps(_mm512_castsi512_ps(v),_MM_SHUFFLE(D,C,B,A)));
|
||||
template<int i0, int i1, int i2, int i3>
|
||||
__forceinline vuint16 shuffle(const vuint16& v) {
|
||||
return _mm512_castps_si512(_mm512_permute_ps(_mm512_castsi512_ps(v), _MM_SHUFFLE(i3, i2, i1, i0)));
|
||||
}
|
||||
|
||||
template<int i>
|
||||
__forceinline vuint16 shuffle4(const vuint16& x) {
|
||||
return _mm512_castps_si512(_mm512_shuffle_f32x4(_mm512_castsi512_ps(x),_mm512_castsi512_ps(x),_MM_SHUFFLE(i,i,i,i)));
|
||||
__forceinline vuint16 shuffle4(const vuint16& v) {
|
||||
return _mm512_castps_si512(_mm512_shuffle_f32x4(_mm512_castsi512_ps(v), _mm512_castsi512_ps(v) ,_MM_SHUFFLE(i, i, i, i)));
|
||||
}
|
||||
|
||||
template<int A, int B, int C, int D>
|
||||
__forceinline vuint16 shuffle4(const vuint16& x) {
|
||||
return _mm512_castps_si512(_mm512_shuffle_f32x4(_mm512_castsi512_ps(x),_mm512_castsi512_ps(x),_MM_SHUFFLE(D,C,B,A)));
|
||||
template<int i0, int i1, int i2, int i3>
|
||||
__forceinline vuint16 shuffle4(const vuint16& v) {
|
||||
return _mm512_castps_si512(_mm512_shuffle_f32x4(_mm512_castsi512_ps(v), _mm512_castsi512_ps(v), _MM_SHUFFLE(i3, i2, i1, i0)));
|
||||
}
|
||||
|
||||
template<int i>
|
||||
__forceinline vuint16 align_shift_right(const vuint16& a, const vuint16& b)
|
||||
{
|
||||
return _mm512_alignr_epi32(a,b,i);
|
||||
__forceinline vuint16 align_shift_right(const vuint16& a, const vuint16& b) {
|
||||
return _mm512_alignr_epi32(a, b, i);
|
||||
};
|
||||
|
||||
__forceinline unsigned int toScalar(const vuint16& a)
|
||||
{
|
||||
return _mm_cvtsi128_si32(_mm512_castsi512_si128(a));
|
||||
__forceinline unsigned int toScalar(const vuint16& v) {
|
||||
return _mm_cvtsi128_si32(_mm512_castsi512_si128(v));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Reductions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vuint16 vreduce_min2(vuint16 x) { return min(x,shuffle<1,0,3,2>(x)); }
|
||||
__forceinline vuint16 vreduce_min4(vuint16 x) { x = vreduce_min2(x); return min(x,shuffle<2,3,0,1>(x)); }
|
||||
__forceinline vuint16 vreduce_min8(vuint16 x) { x = vreduce_min4(x); return min(x,shuffle4<1,0,3,2>(x)); }
|
||||
__forceinline vuint16 vreduce_min (vuint16 x) { x = vreduce_min8(x); return min(x,shuffle4<2,3,0,1>(x)); }
|
||||
__forceinline vuint16 vreduce_min2(vuint16 x) { return min(x, shuffle<1,0,3,2>(x)); }
|
||||
__forceinline vuint16 vreduce_min4(vuint16 x) { x = vreduce_min2(x); return min(x, shuffle<2,3,0,1>(x)); }
|
||||
__forceinline vuint16 vreduce_min8(vuint16 x) { x = vreduce_min4(x); return min(x, shuffle4<1,0,3,2>(x)); }
|
||||
__forceinline vuint16 vreduce_min (vuint16 x) { x = vreduce_min8(x); return min(x, shuffle4<2,3,0,1>(x)); }
|
||||
|
||||
__forceinline vuint16 vreduce_max2(vuint16 x) { return max(x,shuffle<1,0,3,2>(x)); }
|
||||
__forceinline vuint16 vreduce_max4(vuint16 x) { x = vreduce_max2(x); return max(x,shuffle<2,3,0,1>(x)); }
|
||||
__forceinline vuint16 vreduce_max8(vuint16 x) { x = vreduce_max4(x); return max(x,shuffle4<1,0,3,2>(x)); }
|
||||
__forceinline vuint16 vreduce_max (vuint16 x) { x = vreduce_max8(x); return max(x,shuffle4<2,3,0,1>(x)); }
|
||||
__forceinline vuint16 vreduce_max2(vuint16 x) { return max(x, shuffle<1,0,3,2>(x)); }
|
||||
__forceinline vuint16 vreduce_max4(vuint16 x) { x = vreduce_max2(x); return max(x, shuffle<2,3,0,1>(x)); }
|
||||
__forceinline vuint16 vreduce_max8(vuint16 x) { x = vreduce_max4(x); return max(x, shuffle4<1,0,3,2>(x)); }
|
||||
__forceinline vuint16 vreduce_max (vuint16 x) { x = vreduce_max8(x); return max(x, shuffle4<2,3,0,1>(x)); }
|
||||
|
||||
__forceinline vuint16 vreduce_and2(vuint16 x) { return x & shuffle<1,0,3,2>(x); }
|
||||
__forceinline vuint16 vreduce_and4(vuint16 x) { x = vreduce_and2(x); return x & shuffle<2,3,0,1>(x); }
|
||||
@@ -375,31 +392,12 @@ namespace embree
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Memory load and store operations
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<int scale = 4>
|
||||
__forceinline vuint16 gather16i(const vboolf16& mask, const unsigned int *const ptr, const vuint16& index) {
|
||||
return _mm512_mask_i32gather_epi32(_mm512_undefined_epi32(),mask,index,ptr,scale);
|
||||
}
|
||||
|
||||
template<int scale = 4>
|
||||
__forceinline vuint16 gather16i(const vboolf16& mask, vuint16& dest, const unsigned int *const ptr, const vuint16& index) {
|
||||
return _mm512_mask_i32gather_epi32(dest,mask,index,ptr,scale);
|
||||
}
|
||||
|
||||
template<int scale = 4>
|
||||
__forceinline void scatter16i(const vboolf16& mask,unsigned int *const ptr, const vuint16& index,const vuint16& v) {
|
||||
_mm512_mask_i32scatter_epi32((int*)ptr,mask,index,v,scale);
|
||||
}
|
||||
|
||||
__forceinline void compactustore16i_low(const vboolf16 mask, void *addr, const vuint16& reg) {
|
||||
_mm512_mask_compressstoreu_epi32(addr,mask,reg);
|
||||
}
|
||||
|
||||
__forceinline vuint16 permute(vuint16 v,vuint16 index) {
|
||||
__forceinline vuint16 permute(vuint16 v, vuint16 index) {
|
||||
return _mm512_permutexvar_epi32(index,v);
|
||||
}
|
||||
|
||||
__forceinline vuint16 reverse(const vuint16 &a) {
|
||||
__forceinline vuint16 reverse(const vuint16& a) {
|
||||
return permute(a,vuint16(reverse_step));
|
||||
}
|
||||
|
||||
@@ -429,7 +427,7 @@ namespace embree
|
||||
/// Output Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline std::ostream& operator<<(std::ostream& cout, const vuint16& v)
|
||||
__forceinline std::ostream& operator <<(std::ostream& cout, const vuint16& v)
|
||||
{
|
||||
cout << "<" << v[0];
|
||||
for (int i=1; i<16; i++) cout << ", " << v[i];
|
||||
|
||||
+172
-143
@@ -28,88 +28,85 @@ namespace embree
|
||||
typedef vuint4 Int;
|
||||
typedef vfloat4 Float;
|
||||
|
||||
enum { size = 4 }; // number of SIMD elements
|
||||
union { __m128i v; unsigned i[4]; }; // data
|
||||
enum { size = 4 }; // number of SIMD elements
|
||||
union { __m128i v; unsigned int i[4]; }; // data
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Constructors, Assignment & Cast Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vuint ( ) {}
|
||||
__forceinline vuint ( const vuint4& a ) { v = a.v; }
|
||||
__forceinline vuint4& operator=( const vuint4& a ) { v = a.v; return *this; }
|
||||
__forceinline vuint() {}
|
||||
__forceinline vuint(const vuint4& a) { v = a.v; }
|
||||
__forceinline vuint4& operator =(const vuint4& a) { v = a.v; return *this; }
|
||||
|
||||
__forceinline vuint( const __m128i a ) : v(a) {}
|
||||
__forceinline operator const __m128i&( void ) const { return v; }
|
||||
__forceinline operator __m128i&( void ) { return v; }
|
||||
__forceinline vuint(const __m128i a) : v(a) {}
|
||||
__forceinline operator const __m128i&() const { return v; }
|
||||
__forceinline operator __m128i&() { return v; }
|
||||
|
||||
|
||||
__forceinline vuint( const unsigned& a ) : v(_mm_shuffle_epi32(_mm_castps_si128(_mm_load_ss((float*)&a)), _MM_SHUFFLE(0, 0, 0, 0))) {}
|
||||
#if defined(__X86_64__)
|
||||
__forceinline vuint( const size_t a ) : v(_mm_set1_epi32((int)a)) {}
|
||||
#endif
|
||||
__forceinline vuint( unsigned a, unsigned b, unsigned c, unsigned d) : v(_mm_set_epi32(d, c, b, a)) {}
|
||||
__forceinline vuint(unsigned int a) : v(_mm_set1_epi32(a)) {}
|
||||
__forceinline vuint(unsigned int a, unsigned int b, unsigned int c, unsigned int d) : v(_mm_set_epi32(d, c, b, a)) {}
|
||||
|
||||
//__forceinline explicit vuint( const __m128 a ) : v(_mm_cvtps_epu32(a)) {}
|
||||
//__forceinline explicit vuint(__m128 a) : v(_mm_cvtps_epu32(a)) {}
|
||||
#if defined(__AVX512VL__)
|
||||
__forceinline explicit vuint( const vboolf4 &a ) : v(_mm_movm_epi32(a)) {}
|
||||
__forceinline explicit vuint(const vboolf4& a) : v(_mm_movm_epi32(a)) {}
|
||||
#else
|
||||
__forceinline explicit vuint( const vboolf4 &a ) : v(_mm_castps_si128((__m128)a)) {}
|
||||
__forceinline explicit vuint(const vboolf4& a) : v(_mm_castps_si128((__m128)a)) {}
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Constants
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vuint( ZeroTy ) : v(_mm_setzero_si128()) {}
|
||||
__forceinline vuint( OneTy ) : v(_mm_set1_epi32(1)) {}
|
||||
__forceinline vuint( PosInfTy ) : v(_mm_set1_epi32(unsigned(pos_inf))) {}
|
||||
__forceinline vuint( StepTy ) : v(_mm_set_epi32(3, 2, 1, 0)) {}
|
||||
__forceinline vuint( TrueTy ) { v = _mm_cmpeq_epi32(v,v); }
|
||||
|
||||
__forceinline vuint(ZeroTy) : v(_mm_setzero_si128()) {}
|
||||
__forceinline vuint(OneTy) : v(_mm_set1_epi32(1)) {}
|
||||
__forceinline vuint(PosInfTy) : v(_mm_set1_epi32(unsigned(pos_inf))) {}
|
||||
__forceinline vuint(StepTy) : v(_mm_set_epi32(3, 2, 1, 0)) {}
|
||||
__forceinline vuint(TrueTy) { v = _mm_cmpeq_epi32(v,v); }
|
||||
__forceinline vuint(UndefinedTy) : v(_mm_castps_si128(_mm_undefined_ps())) {}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Loads and Stores
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static __forceinline vuint4 load ( const void* const a ) { return _mm_load_si128((__m128i*)a); }
|
||||
static __forceinline vuint4 loadu( const void* const a ) { return _mm_loadu_si128((__m128i*)a); }
|
||||
static __forceinline vuint4 load (const void* a) { return _mm_load_si128((__m128i*)a); }
|
||||
static __forceinline vuint4 loadu(const void* a) { return _mm_loadu_si128((__m128i*)a); }
|
||||
|
||||
static __forceinline void store (void* ptr, const vuint4& v) { _mm_store_si128((__m128i*)ptr,v); }
|
||||
static __forceinline void storeu(void* ptr, const vuint4& v) { _mm_storeu_si128((__m128i*)ptr,v); }
|
||||
|
||||
#if defined(__AVX512VL__)
|
||||
static __forceinline vuint4 load ( const vboolf4& mask, const void* const ptr ) { return _mm_mask_load_epi32 (_mm_setzero_si128(),mask,ptr); }
|
||||
static __forceinline vuint4 loadu( const vboolf4& mask, const void* const ptr ) { return _mm_mask_loadu_epi32(_mm_setzero_si128(),mask,ptr); }
|
||||
static __forceinline vuint4 load (const vboolf4& mask, const void* ptr) { return _mm_mask_load_epi32 (_mm_setzero_si128(),mask,ptr); }
|
||||
static __forceinline vuint4 loadu(const vboolf4& mask, const void* ptr) { return _mm_mask_loadu_epi32(_mm_setzero_si128(),mask,ptr); }
|
||||
|
||||
static __forceinline void store ( const vboolf4& mask, void* ptr, const vuint4& v ) { _mm_mask_store_epi32 (ptr,mask,v); }
|
||||
static __forceinline void storeu( const vboolf4& mask, void* ptr, const vuint4& v ) { _mm_mask_storeu_epi32(ptr,mask,v); }
|
||||
static __forceinline void store (const vboolf4& mask, void* ptr, const vuint4& v) { _mm_mask_store_epi32 (ptr,mask,v); }
|
||||
static __forceinline void storeu(const vboolf4& mask, void* ptr, const vuint4& v) { _mm_mask_storeu_epi32(ptr,mask,v); }
|
||||
#elif defined(__AVX__)
|
||||
static __forceinline vuint4 load ( const vbool4& mask, const void* const a ) { return _mm_castps_si128(_mm_maskload_ps((float*)a,mask)); }
|
||||
static __forceinline vuint4 loadu( const vbool4& mask, const void* const a ) { return _mm_castps_si128(_mm_maskload_ps((float*)a,mask)); }
|
||||
static __forceinline vuint4 load (const vbool4& mask, const void* a) { return _mm_castps_si128(_mm_maskload_ps((float*)a,mask)); }
|
||||
static __forceinline vuint4 loadu(const vbool4& mask, const void* a) { return _mm_castps_si128(_mm_maskload_ps((float*)a,mask)); }
|
||||
|
||||
static __forceinline void store ( const vboolf4& mask, void* ptr, const vuint4& i ) { _mm_maskstore_ps((float*)ptr,(__m128i)mask,_mm_castsi128_ps(i)); }
|
||||
static __forceinline void storeu( const vboolf4& mask, void* ptr, const vuint4& i ) { _mm_maskstore_ps((float*)ptr,(__m128i)mask,_mm_castsi128_ps(i)); }
|
||||
static __forceinline void store (const vboolf4& mask, void* ptr, const vuint4& i) { _mm_maskstore_ps((float*)ptr,(__m128i)mask,_mm_castsi128_ps(i)); }
|
||||
static __forceinline void storeu(const vboolf4& mask, void* ptr, const vuint4& i) { _mm_maskstore_ps((float*)ptr,(__m128i)mask,_mm_castsi128_ps(i)); }
|
||||
#else
|
||||
static __forceinline vuint4 load ( const vbool4& mask, const void* const a ) { return _mm_and_si128(_mm_load_si128 ((__m128i*)a),mask); }
|
||||
static __forceinline vuint4 loadu( const vbool4& mask, const void* const a ) { return _mm_and_si128(_mm_loadu_si128((__m128i*)a),mask); }
|
||||
static __forceinline vuint4 load (const vbool4& mask, const void* a) { return _mm_and_si128(_mm_load_si128 ((__m128i*)a),mask); }
|
||||
static __forceinline vuint4 loadu(const vbool4& mask, const void* a) { return _mm_and_si128(_mm_loadu_si128((__m128i*)a),mask); }
|
||||
|
||||
static __forceinline void store ( const vboolf4& mask, void* ptr, const vuint4& i ) { store (ptr,select(mask,i,load (ptr))); }
|
||||
static __forceinline void storeu( const vboolf4& mask, void* ptr, const vuint4& i ) { storeu(ptr,select(mask,i,loadu(ptr))); }
|
||||
static __forceinline void store (const vboolf4& mask, void* ptr, const vuint4& i) { store (ptr,select(mask,i,load (ptr))); }
|
||||
static __forceinline void storeu(const vboolf4& mask, void* ptr, const vuint4& i) { storeu(ptr,select(mask,i,loadu(ptr))); }
|
||||
#endif
|
||||
|
||||
#if defined(__SSE4_1__)
|
||||
static __forceinline vuint4 load( const unsigned char* const ptr ) {
|
||||
static __forceinline vuint4 load(const unsigned char* ptr) {
|
||||
return _mm_cvtepu8_epi32(_mm_load_si128((__m128i*)ptr));
|
||||
}
|
||||
|
||||
static __forceinline vuint4 loadu( const unsigned char* const ptr ) {
|
||||
static __forceinline vuint4 loadu(const unsigned char* ptr) {
|
||||
return _mm_cvtepu8_epi32(_mm_loadu_si128((__m128i*)ptr));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static __forceinline vuint4 load(const unsigned short* const ptr) {
|
||||
static __forceinline vuint4 load(const unsigned short* ptr) {
|
||||
#if defined (__SSE4_1__)
|
||||
return _mm_cvtepu16_epi32(_mm_loadu_si128((__m128i*)ptr));
|
||||
#else
|
||||
@@ -117,7 +114,7 @@ namespace embree
|
||||
#endif
|
||||
}
|
||||
|
||||
static __forceinline void store_uchar( unsigned char* const ptr, const vuint4& v ) {
|
||||
static __forceinline void store_uchar(unsigned char* ptr, const vuint4& v) {
|
||||
#if defined(__SSE4_1__)
|
||||
__m128i x = v;
|
||||
x = _mm_packus_epi32(x, x);
|
||||
@@ -129,12 +126,12 @@ namespace embree
|
||||
#endif
|
||||
}
|
||||
|
||||
static __forceinline void store_uchar( unsigned short* const ptr, const vuint4& v ) {
|
||||
static __forceinline void store_uchar(unsigned short* ptr, const vuint4& v) {
|
||||
for (size_t i=0;i<4;i++)
|
||||
ptr[i] = (unsigned short)v[i];
|
||||
}
|
||||
|
||||
static __forceinline vuint4 load_nt (void* ptr) {
|
||||
static __forceinline vuint4 load_nt(void* ptr) {
|
||||
#if defined(__SSE4_1__)
|
||||
return _mm_stream_load_si128((__m128i*)ptr);
|
||||
#else
|
||||
@@ -150,14 +147,43 @@ namespace embree
|
||||
#endif
|
||||
}
|
||||
|
||||
template<int scale = 4>
|
||||
static __forceinline vuint4 gather(const unsigned int* ptr, const vint4& index) {
|
||||
#if defined(__AVX2__)
|
||||
return _mm_i32gather_epi32((const int*)ptr, index, scale);
|
||||
#else
|
||||
return vuint4(
|
||||
*(unsigned int*)(((char*)ptr)+scale*index[0]),
|
||||
*(unsigned int*)(((char*)ptr)+scale*index[1]),
|
||||
*(unsigned int*)(((char*)ptr)+scale*index[2]),
|
||||
*(unsigned int*)(((char*)ptr)+scale*index[3]));
|
||||
#endif
|
||||
}
|
||||
|
||||
template<int scale = 4>
|
||||
static __forceinline vuint4 gather(const vboolf4& mask, const unsigned int* ptr, const vint4& index) {
|
||||
vuint4 r = zero;
|
||||
#if defined(__AVX512VL__)
|
||||
return _mm_mmask_i32gather_epi32(r, mask, index, ptr, scale);
|
||||
#elif defined(__AVX2__)
|
||||
return _mm_mask_i32gather_epi32(r, (const int*)ptr, index, mask, scale);
|
||||
#else
|
||||
if (likely(mask[0])) r[0] = *(unsigned int*)(((char*)ptr)+scale*index[0]);
|
||||
if (likely(mask[1])) r[1] = *(unsigned int*)(((char*)ptr)+scale*index[1]);
|
||||
if (likely(mask[2])) r[2] = *(unsigned int*)(((char*)ptr)+scale*index[2]);
|
||||
if (likely(mask[3])) r[3] = *(unsigned int*)(((char*)ptr)+scale*index[3]);
|
||||
return r;
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Array Access
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const unsigned& operator []( const size_t index ) const { assert(index < 4); return i[index]; }
|
||||
__forceinline unsigned& operator []( const size_t index ) { assert(index < 4); return i[index]; }
|
||||
__forceinline const unsigned int& operator [](size_t index) const { assert(index < 4); return i[index]; }
|
||||
__forceinline unsigned int& operator [](size_t index) { assert(index < 4); return i[index]; }
|
||||
|
||||
friend __forceinline const vuint4 select( const vboolf4& m, const vuint4& t, const vuint4& f ) {
|
||||
friend __forceinline vuint4 select(const vboolf4& m, const vuint4& t, const vuint4& f) {
|
||||
#if defined(__AVX512VL__)
|
||||
return _mm_mask_blend_epi32(m, f, t);
|
||||
#elif defined(__SSE4_1__)
|
||||
@@ -172,110 +198,110 @@ namespace embree
|
||||
/// Unary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vuint4 asUint ( const __m128& a ) { return _mm_castps_si128(a); }
|
||||
__forceinline const vuint4 operator +( const vuint4& a ) { return a; }
|
||||
__forceinline const vuint4 operator -( const vuint4& a ) { return _mm_sub_epi32(_mm_setzero_si128(), a.v); }
|
||||
__forceinline vuint4 asUint(const __m128& a) { return _mm_castps_si128(a); }
|
||||
__forceinline vuint4 operator +(const vuint4& a) { return a; }
|
||||
__forceinline vuint4 operator -(const vuint4& a) { return _mm_sub_epi32(_mm_setzero_si128(), a); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Binary Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline const vuint4 operator +( const vuint4& a, const vuint4& b ) { return _mm_add_epi32(a.v, b.v); }
|
||||
__forceinline const vuint4 operator +( const vuint4& a, const unsigned& b ) { return a + vuint4(b); }
|
||||
__forceinline const vuint4 operator +( const unsigned& a, const vuint4& b ) { return vuint4(a) + b; }
|
||||
__forceinline vuint4 operator +(const vuint4& a, const vuint4& b) { return _mm_add_epi32(a, b); }
|
||||
__forceinline vuint4 operator +(const vuint4& a, unsigned int b) { return a + vuint4(b); }
|
||||
__forceinline vuint4 operator +(unsigned int a, const vuint4& b) { return vuint4(a) + b; }
|
||||
|
||||
__forceinline const vuint4 operator -( const vuint4& a, const vuint4& b ) { return _mm_sub_epi32(a.v, b.v); }
|
||||
__forceinline const vuint4 operator -( const vuint4& a, const unsigned& b ) { return a - vuint4(b); }
|
||||
__forceinline const vuint4 operator -( const unsigned& a, const vuint4& b ) { return vuint4(a) - b; }
|
||||
__forceinline vuint4 operator -(const vuint4& a, const vuint4& b) { return _mm_sub_epi32(a, b); }
|
||||
__forceinline vuint4 operator -(const vuint4& a, unsigned int b) { return a - vuint4(b); }
|
||||
__forceinline vuint4 operator -(unsigned int a, const vuint4& b) { return vuint4(a) - b; }
|
||||
|
||||
//#if defined(__SSE4_1__)
|
||||
// __forceinline const vuint4 operator *( const vuint4& a, const vuint4& b ) { return _mm_mullo_epu32(a.v, b.v); }
|
||||
// __forceinline vuint4 operator *(const vuint4& a, const vuint4& b) { return _mm_mullo_epu32(a, b); }
|
||||
//#else
|
||||
// __forceinline const vuint4 operator *( const vuint4& a, const vuint4& b ) { return vuint4(a[0]*b[0],a[1]*b[1],a[2]*b[2],a[3]*b[3]); }
|
||||
// __forceinline vuint4 operator *(const vuint4& a, const vuint4& b) { return vuint4(a[0]*b[0],a[1]*b[1],a[2]*b[2],a[3]*b[3]); }
|
||||
//#endif
|
||||
// __forceinline const vuint4 operator *( const vuint4& a, const unsigned& b ) { return a * vuint4(b); }
|
||||
// __forceinline const vuint4 operator *( const unsigned& a, const vuint4& b ) { return vuint4(a) * b; }
|
||||
// __forceinline vuint4 operator *(const vuint4& a, unsigned int b) { return a * vuint4(b); }
|
||||
// __forceinline vuint4 operator *(unsigned int a, const vuint4& b) { return vuint4(a) * b; }
|
||||
|
||||
__forceinline const vuint4 operator &( const vuint4& a, const vuint4& b ) { return _mm_and_si128(a.v, b.v); }
|
||||
__forceinline const vuint4 operator &( const vuint4& a, const unsigned& b ) { return a & vuint4(b); }
|
||||
__forceinline const vuint4 operator &( const unsigned& a, const vuint4& b ) { return vuint4(a) & b; }
|
||||
__forceinline vuint4 operator &(const vuint4& a, const vuint4& b) { return _mm_and_si128(a, b); }
|
||||
__forceinline vuint4 operator &(const vuint4& a, unsigned int b) { return a & vuint4(b); }
|
||||
__forceinline vuint4 operator &(unsigned int a, const vuint4& b) { return vuint4(a) & b; }
|
||||
|
||||
__forceinline const vuint4 operator |( const vuint4& a, const vuint4& b ) { return _mm_or_si128(a.v, b.v); }
|
||||
__forceinline const vuint4 operator |( const vuint4& a, const unsigned& b ) { return a | vuint4(b); }
|
||||
__forceinline const vuint4 operator |( const unsigned& a, const vuint4& b ) { return vuint4(a) | b; }
|
||||
__forceinline vuint4 operator |(const vuint4& a, const vuint4& b) { return _mm_or_si128(a, b); }
|
||||
__forceinline vuint4 operator |(const vuint4& a, unsigned int b) { return a | vuint4(b); }
|
||||
__forceinline vuint4 operator |(unsigned int a, const vuint4& b) { return vuint4(a) | b; }
|
||||
|
||||
__forceinline const vuint4 operator ^( const vuint4& a, const vuint4& b ) { return _mm_xor_si128(a.v, b.v); }
|
||||
__forceinline const vuint4 operator ^( const vuint4& a, const unsigned& b ) { return a ^ vuint4(b); }
|
||||
__forceinline const vuint4 operator ^( const unsigned& a, const vuint4& b ) { return vuint4(a) ^ b; }
|
||||
__forceinline vuint4 operator ^(const vuint4& a, const vuint4& b) { return _mm_xor_si128(a, b); }
|
||||
__forceinline vuint4 operator ^(const vuint4& a, unsigned int b) { return a ^ vuint4(b); }
|
||||
__forceinline vuint4 operator ^(unsigned int a, const vuint4& b) { return vuint4(a) ^ b; }
|
||||
|
||||
__forceinline const vuint4 operator <<( const vuint4& a, const unsigned& n ) { return _mm_slli_epi32(a.v, n); }
|
||||
__forceinline const vuint4 operator >>( const vuint4& a, const unsigned& n ) { return _mm_srli_epi32(a.v, n); }
|
||||
__forceinline vuint4 operator <<(const vuint4& a, unsigned int n) { return _mm_slli_epi32(a, n); }
|
||||
__forceinline vuint4 operator >>(const vuint4& a, unsigned int n) { return _mm_srli_epi32(a, n); }
|
||||
|
||||
__forceinline const vuint4 sll ( const vuint4& a, const unsigned& b ) { return _mm_slli_epi32(a.v, b); }
|
||||
__forceinline const vuint4 sra ( const vuint4& a, const unsigned& b ) { return _mm_srai_epi32(a.v, b); }
|
||||
__forceinline const vuint4 srl ( const vuint4& a, const unsigned& b ) { return _mm_srli_epi32(a.v, b); }
|
||||
__forceinline vuint4 sll (const vuint4& a, unsigned int b) { return _mm_slli_epi32(a, b); }
|
||||
__forceinline vuint4 sra (const vuint4& a, unsigned int b) { return _mm_srai_epi32(a, b); }
|
||||
__forceinline vuint4 srl (const vuint4& a, unsigned int b) { return _mm_srli_epi32(a, b); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Assignment Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vuint4& operator +=( vuint4& a, const vuint4& b ) { return a = a + b; }
|
||||
__forceinline vuint4& operator +=( vuint4& a, const unsigned& b ) { return a = a + b; }
|
||||
__forceinline vuint4& operator +=(vuint4& a, const vuint4& b) { return a = a + b; }
|
||||
__forceinline vuint4& operator +=(vuint4& a, unsigned int b) { return a = a + b; }
|
||||
|
||||
__forceinline vuint4& operator -=( vuint4& a, const vuint4& b ) { return a = a - b; }
|
||||
__forceinline vuint4& operator -=( vuint4& a, const unsigned& b ) { return a = a - b; }
|
||||
__forceinline vuint4& operator -=(vuint4& a, const vuint4& b) { return a = a - b; }
|
||||
__forceinline vuint4& operator -=(vuint4& a, unsigned int b) { return a = a - b; }
|
||||
|
||||
//#if defined(__SSE4_1__)
|
||||
// __forceinline vuint4& operator *=( vuint4& a, const vuint4& b ) { return a = a * b; }
|
||||
// __forceinline vuint4& operator *=( vuint4& a, const unsigned& b ) { return a = a * b; }
|
||||
// __forceinline vuint4& operator *=(vuint4& a, const vuint4& b) { return a = a * b; }
|
||||
// __forceinline vuint4& operator *=(vuint4& a, unsigned int b) { return a = a * b; }
|
||||
//#endif
|
||||
|
||||
__forceinline vuint4& operator &=( vuint4& a, const vuint4& b ) { return a = a & b; }
|
||||
__forceinline vuint4& operator &=( vuint4& a, const unsigned& b ) { return a = a & b; }
|
||||
__forceinline vuint4& operator &=(vuint4& a, const vuint4& b) { return a = a & b; }
|
||||
__forceinline vuint4& operator &=(vuint4& a, unsigned int b) { return a = a & b; }
|
||||
|
||||
__forceinline vuint4& operator |=( vuint4& a, const vuint4& b ) { return a = a | b; }
|
||||
__forceinline vuint4& operator |=( vuint4& a, const unsigned& b ) { return a = a | b; }
|
||||
__forceinline vuint4& operator |=(vuint4& a, const vuint4& b) { return a = a | b; }
|
||||
__forceinline vuint4& operator |=(vuint4& a, unsigned int b) { return a = a | b; }
|
||||
|
||||
__forceinline vuint4& operator <<=( vuint4& a, const unsigned& b ) { return a = a << b; }
|
||||
__forceinline vuint4& operator >>=( vuint4& a, const unsigned& b ) { return a = a >> b; }
|
||||
__forceinline vuint4& operator <<=(vuint4& a, unsigned int b) { return a = a << b; }
|
||||
__forceinline vuint4& operator >>=(vuint4& a, unsigned int b) { return a = a >> b; }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Comparison Operators + Select
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined(__AVX512VL__)
|
||||
__forceinline const vboolf4 operator ==( const vuint4& a, const vuint4& b ) { return _mm_cmp_epu32_mask(a,b,_MM_CMPINT_EQ); }
|
||||
__forceinline const vboolf4 operator !=( const vuint4& a, const vuint4& b ) { return _mm_cmp_epu32_mask(a,b,_MM_CMPINT_NE); }
|
||||
//__forceinline const vboolf4 operator < ( const vuint4& a, const vuint4& b ) { return _mm_cmp_epu32_mask(a,b,_MM_CMPINT_LT); }
|
||||
//__forceinline const vboolf4 operator >=( const vuint4& a, const vuint4& b ) { return _mm_cmp_epu32_mask(a,b,_MM_CMPINT_GE); }
|
||||
//__forceinline const vboolf4 operator > ( const vuint4& a, const vuint4& b ) { return _mm_cmp_epu32_mask(a,b,_MM_CMPINT_GT); }
|
||||
//__forceinline const vboolf4 operator <=( const vuint4& a, const vuint4& b ) { return _mm_cmp_epu32_mask(a,b,_MM_CMPINT_LE); }
|
||||
__forceinline vboolf4 operator ==(const vuint4& a, const vuint4& b) { return _mm_cmp_epu32_mask(a,b,_MM_CMPINT_EQ); }
|
||||
__forceinline vboolf4 operator !=(const vuint4& a, const vuint4& b) { return _mm_cmp_epu32_mask(a,b,_MM_CMPINT_NE); }
|
||||
//__forceinline vboolf4 operator < (const vuint4& a, const vuint4& b) { return _mm_cmp_epu32_mask(a,b,_MM_CMPINT_LT); }
|
||||
//__forceinline vboolf4 operator >=(const vuint4& a, const vuint4& b) { return _mm_cmp_epu32_mask(a,b,_MM_CMPINT_GE); }
|
||||
//__forceinline vboolf4 operator > (const vuint4& a, const vuint4& b) { return _mm_cmp_epu32_mask(a,b,_MM_CMPINT_GT); }
|
||||
//__forceinline vboolf4 operator <=(const vuint4& a, const vuint4& b) { return _mm_cmp_epu32_mask(a,b,_MM_CMPINT_LE); }
|
||||
#else
|
||||
__forceinline const vboolf4 operator ==( const vuint4& a, const vuint4& b ) { return _mm_castsi128_ps(_mm_cmpeq_epi32(a, b)); }
|
||||
__forceinline const vboolf4 operator !=( const vuint4& a, const vuint4& b ) { return !(a == b); }
|
||||
//__forceinline const vboolf4 operator < ( const vuint4& a, const vuint4& b ) { return _mm_castsi128_ps(_mm_cmplt_epu32(a, b)); }
|
||||
//__forceinline const vboolf4 operator >=( const vuint4& a, const vuint4& b ) { return !(a < b); }
|
||||
//__forceinline const vboolf4 operator > ( const vuint4& a, const vuint4& b ) { return _mm_castsi128_ps(_mm_cmpgt_epu32(a, b)); }
|
||||
//__forceinline const vboolf4 operator <=( const vuint4& a, const vuint4& b ) { return !(a > b); }
|
||||
__forceinline vboolf4 operator ==(const vuint4& a, const vuint4& b) { return _mm_castsi128_ps(_mm_cmpeq_epi32(a, b)); }
|
||||
__forceinline vboolf4 operator !=(const vuint4& a, const vuint4& b) { return !(a == b); }
|
||||
//__forceinline vboolf4 operator < (const vuint4& a, const vuint4& b) { return _mm_castsi128_ps(_mm_cmplt_epu32(a, b)); }
|
||||
//__forceinline vboolf4 operator >=(const vuint4& a, const vuint4& b) { return !(a < b); }
|
||||
//__forceinline vboolf4 operator > (const vuint4& a, const vuint4& b) { return _mm_castsi128_ps(_mm_cmpgt_epu32(a, b)); }
|
||||
//__forceinline vboolf4 operator <=(const vuint4& a, const vuint4& b) { return !(a > b); }
|
||||
#endif
|
||||
|
||||
__forceinline const vboolf4 operator ==( const vuint4& a, const unsigned& b ) { return a == vuint4(b); }
|
||||
__forceinline const vboolf4 operator ==( const unsigned& a, const vuint4& b ) { return vuint4(a) == b; }
|
||||
__forceinline vboolf4 operator ==(const vuint4& a, unsigned int b) { return a == vuint4(b); }
|
||||
__forceinline vboolf4 operator ==(unsigned int a, const vuint4& b) { return vuint4(a) == b; }
|
||||
|
||||
__forceinline const vboolf4 operator !=( const vuint4& a, const unsigned& b ) { return a != vuint4(b); }
|
||||
__forceinline const vboolf4 operator !=( const unsigned& a, const vuint4& b ) { return vuint4(a) != b; }
|
||||
__forceinline vboolf4 operator !=(const vuint4& a, unsigned int b) { return a != vuint4(b); }
|
||||
__forceinline vboolf4 operator !=(unsigned int a, const vuint4& b) { return vuint4(a) != b; }
|
||||
|
||||
//__forceinline const vboolf4 operator < ( const vuint4& a, const unsigned& b ) { return a < vuint4(b); }
|
||||
//__forceinline const vboolf4 operator < ( const unsigned& a, const vuint4& b ) { return vuint4(a) < b; }
|
||||
//__forceinline vboolf4 operator < (const vuint4& a, unsigned int b) { return a < vuint4(b); }
|
||||
//__forceinline vboolf4 operator < (unsigned int a, const vuint4& b) { return vuint4(a) < b; }
|
||||
|
||||
//__forceinline const vboolf4 operator >=( const vuint4& a, const unsigned& b ) { return a >= vuint4(b); }
|
||||
//__forceinline const vboolf4 operator >=( const unsigned& a, const vuint4& b ) { return vuint4(a) >= b; }
|
||||
//__forceinline vboolf4 operator >=(const vuint4& a, unsigned int b) { return a >= vuint4(b); }
|
||||
//__forceinline vboolf4 operator >=(unsigned int a, const vuint4& b) { return vuint4(a) >= b; }
|
||||
|
||||
//__forceinline const vboolf4 operator > ( const vuint4& a, const unsigned& b ) { return a > vuint4(b); }
|
||||
//__forceinline const vboolf4 operator > ( const unsigned& a, const vuint4& b ) { return vuint4(a) > b; }
|
||||
//__forceinline vboolf4 operator > (const vuint4& a, unsigned int b) { return a > vuint4(b); }
|
||||
//__forceinline vboolf4 operator > (unsigned int a, const vuint4& b) { return vuint4(a) > b; }
|
||||
|
||||
//__forceinline const vboolf4 operator <=( const vuint4& a, const unsigned& b ) { return a <= vuint4(b); }
|
||||
//__forceinline const vboolf4 operator <=( const unsigned& a, const vuint4& b ) { return vuint4(a) <= b; }
|
||||
//__forceinline vboolf4 operator <=(const vuint4& a, unsigned int b) { return a <= vuint4(b); }
|
||||
//__forceinline vboolf4 operator <=(unsigned int a, const vuint4& b) { return vuint4(a) <= b; }
|
||||
|
||||
__forceinline vboolf4 eq(const vuint4& a, const vuint4& b) { return a == b; }
|
||||
__forceinline vboolf4 ne(const vuint4& a, const vuint4& b) { return a != b; }
|
||||
@@ -301,7 +327,7 @@ namespace embree
|
||||
#endif
|
||||
|
||||
template<int mask>
|
||||
__forceinline const vuint4 select(const vuint4& t, const vuint4& f) {
|
||||
__forceinline vuint4 select(const vuint4& t, const vuint4& f) {
|
||||
#if defined(__SSE4_1__)
|
||||
return _mm_castps_si128(_mm_blend_ps(_mm_castsi128_ps(f), _mm_castsi128_ps(t), mask));
|
||||
#else
|
||||
@@ -310,56 +336,59 @@ namespace embree
|
||||
}
|
||||
|
||||
/*#if defined(__SSE4_1__)
|
||||
__forceinline const vuint4 min( const vuint4& a, const vuint4& b ) { return _mm_min_epu32(a.v, b.v); }
|
||||
__forceinline const vuint4 max( const vuint4& a, const vuint4& b ) { return _mm_max_epu32(a.v, b.v); }
|
||||
__forceinline vuint4 min(const vuint4& a, const vuint4& b) { return _mm_min_epu32(a, b); }
|
||||
__forceinline vuint4 max(const vuint4& a, const vuint4& b) { return _mm_max_epu32(a, b); }
|
||||
|
||||
#else
|
||||
__forceinline const vuint4 min( const vuint4& a, const vuint4& b ) { return select(a < b,a,b); }
|
||||
__forceinline const vuint4 max( const vuint4& a, const vuint4& b ) { return select(a < b,b,a); }
|
||||
__forceinline vuint4 min(const vuint4& a, const vuint4& b) { return select(a < b,a,b); }
|
||||
__forceinline vuint4 max(const vuint4& a, const vuint4& b) { return select(a < b,b,a); }
|
||||
#endif
|
||||
|
||||
__forceinline const vuint4 min( const vuint4& a, const unsigned& b ) { return min(a,vuint4(b)); }
|
||||
__forceinline const vuint4 min( const unsigned& a, const vuint4& b ) { return min(vuint4(a),b); }
|
||||
__forceinline const vuint4 max( const vuint4& a, const unsigned& b ) { return max(a,vuint4(b)); }
|
||||
__forceinline const vuint4 max( const unsigned& a, const vuint4& b ) { return max(vuint4(a),b); }*/
|
||||
__forceinline vuint4 min(const vuint4& a, unsigned int b) { return min(a,vuint4(b)); }
|
||||
__forceinline vuint4 min(unsigned int a, const vuint4& b) { return min(vuint4(a),b); }
|
||||
__forceinline vuint4 max(const vuint4& a, unsigned int b) { return max(a,vuint4(b)); }
|
||||
__forceinline vuint4 max(unsigned int a, const vuint4& b) { return max(vuint4(a),b); }*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Movement/Shifting/Shuffling Functions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline vuint4 unpacklo( const vuint4& a, const vuint4& b ) { return _mm_castps_si128(_mm_unpacklo_ps(_mm_castsi128_ps(a.v), _mm_castsi128_ps(b.v))); }
|
||||
__forceinline vuint4 unpackhi( const vuint4& a, const vuint4& b ) { return _mm_castps_si128(_mm_unpackhi_ps(_mm_castsi128_ps(a.v), _mm_castsi128_ps(b.v))); }
|
||||
__forceinline vuint4 unpacklo(const vuint4& a, const vuint4& b) { return _mm_castps_si128(_mm_unpacklo_ps(_mm_castsi128_ps(a), _mm_castsi128_ps(b))); }
|
||||
__forceinline vuint4 unpackhi(const vuint4& a, const vuint4& b) { return _mm_castps_si128(_mm_unpackhi_ps(_mm_castsi128_ps(a), _mm_castsi128_ps(b))); }
|
||||
|
||||
template<size_t i0, size_t i1, size_t i2, size_t i3> __forceinline const vuint4 shuffle( const vuint4& a ) {
|
||||
return _mm_shuffle_epi32(a, _MM_SHUFFLE(i3, i2, i1, i0));
|
||||
template<int i0, int i1, int i2, int i3>
|
||||
__forceinline vuint4 shuffle(const vuint4& v) {
|
||||
return _mm_shuffle_epi32(v, _MM_SHUFFLE(i3, i2, i1, i0));
|
||||
}
|
||||
|
||||
template<size_t i0, size_t i1, size_t i2, size_t i3> __forceinline const vuint4 shuffle( const vuint4& a, const vuint4& b ) {
|
||||
template<int i0, int i1, int i2, int i3>
|
||||
__forceinline vuint4 shuffle(const vuint4& a, const vuint4& b) {
|
||||
return _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(a), _mm_castsi128_ps(b), _MM_SHUFFLE(i3, i2, i1, i0)));
|
||||
}
|
||||
|
||||
#if defined(__SSE3__)
|
||||
template<> __forceinline const vuint4 shuffle<0, 0, 2, 2>( const vuint4& a ) { return _mm_castps_si128(_mm_moveldup_ps(_mm_castsi128_ps(a))); }
|
||||
template<> __forceinline const vuint4 shuffle<1, 1, 3, 3>( const vuint4& a ) { return _mm_castps_si128(_mm_movehdup_ps(_mm_castsi128_ps(a))); }
|
||||
template<> __forceinline const vuint4 shuffle<0, 1, 0, 1>( const vuint4& a ) { return _mm_castpd_si128(_mm_movedup_pd (_mm_castsi128_pd(a))); }
|
||||
template<> __forceinline vuint4 shuffle<0, 0, 2, 2>(const vuint4& v) { return _mm_castps_si128(_mm_moveldup_ps(_mm_castsi128_ps(v))); }
|
||||
template<> __forceinline vuint4 shuffle<1, 1, 3, 3>(const vuint4& v) { return _mm_castps_si128(_mm_movehdup_ps(_mm_castsi128_ps(v))); }
|
||||
template<> __forceinline vuint4 shuffle<0, 1, 0, 1>(const vuint4& v) { return _mm_castpd_si128(_mm_movedup_pd (_mm_castsi128_pd(v))); }
|
||||
#endif
|
||||
|
||||
template<size_t i0> __forceinline const vuint4 shuffle( const vuint4& b ) {
|
||||
return shuffle<i0,i0,i0,i0>(b);
|
||||
template<int i>
|
||||
__forceinline vuint4 shuffle(const vuint4& v) {
|
||||
return shuffle<i,i,i,i>(v);
|
||||
}
|
||||
|
||||
#if defined(__SSE4_1__)
|
||||
template<size_t src> __forceinline unsigned extract( const vuint4& b ) { return _mm_extract_epi32(b, src); }
|
||||
template<size_t dst> __forceinline const vuint4 insert( const vuint4& a, const unsigned b ) { return _mm_insert_epi32(a, b, dst); }
|
||||
template<int src> __forceinline unsigned int extract(const vuint4& b) { return _mm_extract_epi32(b, src); }
|
||||
template<int dst> __forceinline vuint4 insert(const vuint4& a, const unsigned b) { return _mm_insert_epi32(a, b, dst); }
|
||||
#else
|
||||
template<size_t src> __forceinline unsigned extract( const vuint4& b ) { return b[src]; }
|
||||
template<size_t dst> __forceinline const vuint4 insert( const vuint4& a, const unsigned b ) { vuint4 c = a; c[dst] = b; return c; }
|
||||
template<int src> __forceinline unsigned int extract(const vuint4& b) { return b[src&3]; }
|
||||
template<int dst> __forceinline vuint4 insert(const vuint4& a, const unsigned b) { vuint4 c = a; c[dst&3] = b; return c; }
|
||||
#endif
|
||||
|
||||
|
||||
template<> __forceinline unsigned extract<0>( const vuint4& b ) { return _mm_cvtsi128_si32(b); }
|
||||
template<> __forceinline unsigned int extract<0>(const vuint4& b) { return _mm_cvtsi128_si32(b); }
|
||||
|
||||
__forceinline unsigned toScalar(const vuint4& a) { return _mm_cvtsi128_si32(a); }
|
||||
__forceinline unsigned int toScalar(const vuint4& v) { return _mm_cvtsi128_si32(v); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Reductions
|
||||
@@ -368,13 +397,13 @@ namespace embree
|
||||
#if 0
|
||||
#if defined(__SSE4_1__)
|
||||
|
||||
__forceinline const vuint4 vreduce_min(const vuint4& v) { vuint4 h = min(shuffle<1,0,3,2>(v),v); return min(shuffle<2,3,0,1>(h),h); }
|
||||
__forceinline const vuint4 vreduce_max(const vuint4& v) { vuint4 h = max(shuffle<1,0,3,2>(v),v); return max(shuffle<2,3,0,1>(h),h); }
|
||||
__forceinline const vuint4 vreduce_add(const vuint4& v) { vuint4 h = shuffle<1,0,3,2>(v) + v ; return shuffle<2,3,0,1>(h) + h ; }
|
||||
__forceinline vuint4 vreduce_min(const vuint4& v) { vuint4 h = min(shuffle<1,0,3,2>(v),v); return min(shuffle<2,3,0,1>(h),h); }
|
||||
__forceinline vuint4 vreduce_max(const vuint4& v) { vuint4 h = max(shuffle<1,0,3,2>(v),v); return max(shuffle<2,3,0,1>(h),h); }
|
||||
__forceinline vuint4 vreduce_add(const vuint4& v) { vuint4 h = shuffle<1,0,3,2>(v) + v ; return shuffle<2,3,0,1>(h) + h ; }
|
||||
|
||||
__forceinline unsigned reduce_min(const vuint4& v) { return toScalar(vreduce_min(v)); }
|
||||
__forceinline unsigned reduce_max(const vuint4& v) { return toScalar(vreduce_max(v)); }
|
||||
__forceinline unsigned reduce_add(const vuint4& v) { return toScalar(vreduce_add(v)); }
|
||||
__forceinline unsigned int reduce_min(const vuint4& v) { return toScalar(vreduce_min(v)); }
|
||||
__forceinline unsigned int reduce_max(const vuint4& v) { return toScalar(vreduce_max(v)); }
|
||||
__forceinline unsigned int reduce_add(const vuint4& v) { return toScalar(vreduce_add(v)); }
|
||||
|
||||
__forceinline size_t select_min(const vuint4& v) { return __bsf(movemask(v == vreduce_min(v))); }
|
||||
__forceinline size_t select_max(const vuint4& v) { return __bsf(movemask(v == vreduce_max(v))); }
|
||||
@@ -384,9 +413,9 @@ namespace embree
|
||||
|
||||
#else
|
||||
|
||||
__forceinline unsigned reduce_min(const vuint4& v) { return min(v[0],v[1],v[2],v[3]); }
|
||||
__forceinline unsigned reduce_max(const vuint4& v) { return max(v[0],v[1],v[2],v[3]); }
|
||||
__forceinline unsigned reduce_add(const vuint4& v) { return v[0]+v[1]+v[2]+v[3]; }
|
||||
__forceinline unsigned int reduce_min(const vuint4& v) { return min(v[0],v[1],v[2],v[3]); }
|
||||
__forceinline unsigned int reduce_max(const vuint4& v) { return max(v[0],v[1],v[2],v[3]); }
|
||||
__forceinline unsigned int reduce_add(const vuint4& v) { return v[0]+v[1]+v[2]+v[3]; }
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -395,7 +424,7 @@ namespace embree
|
||||
/// Output Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& cout, const vuint4& a) {
|
||||
inline std::ostream& operator <<(std::ostream& cout, const vuint4& a) {
|
||||
return cout << "<" << a[0] << ", " << a[1] << ", " << a[2] << ", " << a[3] << ">";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@ ADD_LIBRARY(sys STATIC
|
||||
filename.cpp
|
||||
library.cpp
|
||||
thread.cpp
|
||||
network.cpp
|
||||
string.cpp
|
||||
regression.cpp
|
||||
mutex.cpp
|
||||
|
||||
+20
-9
@@ -28,6 +28,9 @@ namespace embree
|
||||
{
|
||||
void* alignedMalloc(size_t size, size_t align)
|
||||
{
|
||||
if (size == 0)
|
||||
return nullptr;
|
||||
|
||||
assert((align & (align-1)) == 0);
|
||||
void* ptr = _mm_malloc(size,align);
|
||||
|
||||
@@ -37,8 +40,10 @@ namespace embree
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void alignedFree(void* ptr) {
|
||||
_mm_free(ptr);
|
||||
void alignedFree(void* ptr)
|
||||
{
|
||||
if (ptr)
|
||||
_mm_free(ptr);
|
||||
}
|
||||
|
||||
static bool huge_pages_enabled = false;
|
||||
@@ -185,6 +190,7 @@ namespace embree
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sstream>
|
||||
|
||||
#if defined(__MACOSX__)
|
||||
#include <mach/vm_statistics.h>
|
||||
@@ -214,13 +220,18 @@ namespace embree
|
||||
}
|
||||
|
||||
std::string line;
|
||||
int val; char tag[41], unit[6];
|
||||
while (getline(file,line)) {
|
||||
if (sscanf(line.c_str(),"%40s %i %5s",tag,&val,unit) == 3) {
|
||||
if (std::string(tag) == "Hugepagesize:" && std::string(unit) == "kB") {
|
||||
hugepagesize = val*1024;
|
||||
break;
|
||||
}
|
||||
while (getline(file,line))
|
||||
{
|
||||
std::stringstream sline(line);
|
||||
while (!sline.eof() && sline.peek() == ' ') sline.ignore();
|
||||
std::string tag; getline(sline,tag,' ');
|
||||
while (!sline.eof() && sline.peek() == ' ') sline.ignore();
|
||||
std::string val; getline(sline,val,' ');
|
||||
while (!sline.eof() && sline.peek() == ' ') sline.ignore();
|
||||
std::string unit; getline(sline,unit,' ');
|
||||
if (tag == "Hugepagesize:" && unit == "kB") {
|
||||
hugepagesize = std::stoi(val)*1024;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+10
-8
@@ -58,7 +58,7 @@ namespace embree
|
||||
T items[N];
|
||||
};
|
||||
|
||||
/*! static array with dyamic size */
|
||||
/*! static array with dynamic size */
|
||||
template<typename T, size_t N>
|
||||
class darray_t
|
||||
{
|
||||
@@ -130,7 +130,8 @@ namespace embree
|
||||
template<typename Ty, size_t max_stack_bytes>
|
||||
struct __aligned(64) StackArray
|
||||
{
|
||||
__forceinline StackArray (const size_t N)
|
||||
__forceinline StackArray (const size_t N)
|
||||
: N(N)
|
||||
{
|
||||
if (N*sizeof(Ty) <= max_stack_bytes)
|
||||
data = &arr[0];
|
||||
@@ -145,19 +146,20 @@ namespace embree
|
||||
__forceinline operator Ty* () { return data; }
|
||||
__forceinline operator const Ty* () const { return data; }
|
||||
|
||||
__forceinline Ty& operator[](const int i) { return data[i]; }
|
||||
__forceinline const Ty& operator[](const int i) const { return data[i]; }
|
||||
__forceinline Ty& operator[](const int i) { assert(i>=0 && i<N); return data[i]; }
|
||||
__forceinline const Ty& operator[](const int i) const { assert(i>=0 && i<N); return data[i]; }
|
||||
|
||||
__forceinline Ty& operator[](const unsigned i) { return data[i]; }
|
||||
__forceinline const Ty& operator[](const unsigned i) const { return data[i]; }
|
||||
__forceinline Ty& operator[](const unsigned i) { assert(i<N); return data[i]; }
|
||||
__forceinline const Ty& operator[](const unsigned i) const { assert(i<N); return data[i]; }
|
||||
|
||||
#if defined(__X86_64__)
|
||||
__forceinline Ty& operator[](const size_t i) { return data[i]; }
|
||||
__forceinline const Ty& operator[](const size_t i) const { return data[i]; }
|
||||
__forceinline Ty& operator[](const size_t i) { assert(i<N); return data[i]; }
|
||||
__forceinline const Ty& operator[](const size_t i) const { assert(i<N); return data[i]; }
|
||||
#endif
|
||||
|
||||
private:
|
||||
Ty arr[max_stack_bytes/sizeof(Ty)];
|
||||
Ty* data;
|
||||
size_t N;
|
||||
};
|
||||
}
|
||||
+37
-10
@@ -366,7 +366,7 @@ namespace embree
|
||||
size_t r = 0; asm ("btr %1,%0" : "=r"(r) : "r"(i), "0"(v) : "flags"); return r;
|
||||
}
|
||||
|
||||
__forceinline int32_t atomic_cmpxchg( int32_t volatile* value, int32_t comparand, const int32_t input ) {
|
||||
__forceinline int32_t atomic_cmpxchg(int32_t volatile* value, int32_t comparand, const int32_t input) {
|
||||
return __sync_val_compare_and_swap(value, comparand, input);
|
||||
}
|
||||
|
||||
@@ -376,6 +376,21 @@ namespace embree
|
||||
/// All Platforms
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined(__clang__) || defined(__GNUC__)
|
||||
#if !defined(_mm_undefined_ps)
|
||||
__forceinline __m128 _mm_undefined_ps() { return _mm_setzero_ps(); }
|
||||
#endif
|
||||
#if !defined(_mm_undefined_si128)
|
||||
__forceinline __m128i _mm_undefined_si128() { return _mm_setzero_si128(); }
|
||||
#endif
|
||||
#if !defined(_mm256_undefined_ps) && (__AVX__)
|
||||
__forceinline __m256 _mm256_undefined_ps() { return _mm256_setzero_ps(); }
|
||||
#endif
|
||||
#if !defined(_mm_undefined_si128) && (__AVX__)
|
||||
__forceinline __m256i _mm256_undefined_si256() { return _mm256_setzero_si256(); }
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__SSE4_2__)
|
||||
|
||||
__forceinline int __popcnt(int in) {
|
||||
@@ -403,7 +418,7 @@ namespace embree
|
||||
return clock;
|
||||
}
|
||||
|
||||
__forceinline void __pause_cpu (const size_t N = 8)
|
||||
__forceinline void __pause_cpu(const size_t N = 8)
|
||||
{
|
||||
for (size_t i=0; i<N; i++)
|
||||
_mm_pause();
|
||||
@@ -430,23 +445,35 @@ namespace embree
|
||||
prefetchEX(ptr);
|
||||
}
|
||||
#if defined(__AVX2__)
|
||||
__forceinline unsigned int pext(const unsigned int a, const unsigned int b) { return _pext_u32(a,b); }
|
||||
__forceinline unsigned int pdep(const unsigned int a, const unsigned int b) { return _pdep_u32(a,b); }
|
||||
__forceinline unsigned int pext(unsigned int a, unsigned int b) { return _pext_u32(a, b); }
|
||||
__forceinline unsigned int pdep(unsigned int a, unsigned int b) { return _pdep_u32(a, b); }
|
||||
#if defined(__X86_64__)
|
||||
__forceinline size_t pext(const size_t a, const size_t b) { return _pext_u64(a,b); }
|
||||
__forceinline size_t pdep(const size_t a, const size_t b) { return _pdep_u64(a,b); }
|
||||
__forceinline size_t pext(size_t a, size_t b) { return _pext_u64(a, b); }
|
||||
__forceinline size_t pdep(size_t a, size_t b) { return _pdep_u64(a, b); }
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined (__AVX512F__)
|
||||
__forceinline float mm512_cvtss_f32 (__m512 v) { // FIXME: _mm512_cvtss_f32 neither supported by clang v4.0.0 nor GCC 6.3
|
||||
#if defined(__AVX512F__)
|
||||
#if defined(__INTEL_COMPILER)
|
||||
__forceinline float mm512_cvtss_f32(__m512 v) {
|
||||
return _mm512_cvtss_f32(v);
|
||||
}
|
||||
__forceinline int mm512_mask2int(__mmask16 k1) {
|
||||
return _mm512_mask2int(k1);
|
||||
}
|
||||
__forceinline __mmask16 mm512_int2mask(int mask) {
|
||||
return _mm512_int2mask(mask);
|
||||
}
|
||||
#else
|
||||
__forceinline float mm512_cvtss_f32(__m512 v) { // FIXME: _mm512_cvtss_f32 neither supported by clang v4.0.0 nor GCC 6.3
|
||||
return _mm_cvtss_f32(_mm512_castps512_ps128(v));
|
||||
}
|
||||
__forceinline int mm512_mask2int (__mmask16 k1) { // FIXME: _mm512_mask2int not yet supported by GCC 6.3
|
||||
__forceinline int mm512_mask2int(__mmask16 k1) { // FIXME: _mm512_mask2int not yet supported by GCC 6.3
|
||||
return (int)k1;
|
||||
}
|
||||
__forceinline __mmask16 mm512_int2mask (int mask) { // FIXME: _mm512_int2mask not yet supported by GCC 6.3
|
||||
__forceinline __mmask16 mm512_int2mask(int mask) { // FIXME: _mm512_int2mask not yet supported by GCC 6.3
|
||||
return (__mmask16)mask;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
+10
-10
@@ -25,11 +25,11 @@
|
||||
|
||||
namespace embree
|
||||
{
|
||||
MutexSys::MutexSys( void ) { mutex = new CRITICAL_SECTION; InitializeCriticalSection((CRITICAL_SECTION*)mutex); }
|
||||
MutexSys::~MutexSys( void ) { DeleteCriticalSection((CRITICAL_SECTION*)mutex); delete (CRITICAL_SECTION*)mutex; }
|
||||
void MutexSys::lock( void ) { EnterCriticalSection((CRITICAL_SECTION*)mutex); }
|
||||
bool MutexSys::try_lock( void ) { return TryEnterCriticalSection((CRITICAL_SECTION*)mutex) != 0; }
|
||||
void MutexSys::unlock( void ) { LeaveCriticalSection((CRITICAL_SECTION*)mutex); }
|
||||
MutexSys::MutexSys() { mutex = new CRITICAL_SECTION; InitializeCriticalSection((CRITICAL_SECTION*)mutex); }
|
||||
MutexSys::~MutexSys() { DeleteCriticalSection((CRITICAL_SECTION*)mutex); delete (CRITICAL_SECTION*)mutex; }
|
||||
void MutexSys::lock() { EnterCriticalSection((CRITICAL_SECTION*)mutex); }
|
||||
bool MutexSys::try_lock() { return TryEnterCriticalSection((CRITICAL_SECTION*)mutex) != 0; }
|
||||
void MutexSys::unlock() { LeaveCriticalSection((CRITICAL_SECTION*)mutex); }
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -38,31 +38,31 @@ namespace embree
|
||||
namespace embree
|
||||
{
|
||||
/*! system mutex using pthreads */
|
||||
MutexSys::MutexSys( void )
|
||||
MutexSys::MutexSys()
|
||||
{
|
||||
mutex = new pthread_mutex_t;
|
||||
if (pthread_mutex_init((pthread_mutex_t*)mutex, nullptr) != 0)
|
||||
THROW_RUNTIME_ERROR("pthread_mutex_init failed");
|
||||
}
|
||||
|
||||
MutexSys::~MutexSys( void )
|
||||
MutexSys::~MutexSys()
|
||||
{
|
||||
MAYBE_UNUSED bool ok = pthread_mutex_destroy((pthread_mutex_t*)mutex) == 0;
|
||||
assert(ok);
|
||||
delete (pthread_mutex_t*)mutex;
|
||||
}
|
||||
|
||||
void MutexSys::lock( void )
|
||||
void MutexSys::lock()
|
||||
{
|
||||
if (pthread_mutex_lock((pthread_mutex_t*)mutex) != 0)
|
||||
THROW_RUNTIME_ERROR("pthread_mutex_lock failed");
|
||||
}
|
||||
|
||||
bool MutexSys::try_lock( void ) {
|
||||
bool MutexSys::try_lock() {
|
||||
return pthread_mutex_trylock((pthread_mutex_t*)mutex) == 0;
|
||||
}
|
||||
|
||||
void MutexSys::unlock( void )
|
||||
void MutexSys::unlock()
|
||||
{
|
||||
if (pthread_mutex_unlock((pthread_mutex_t*)mutex) != 0)
|
||||
THROW_RUNTIME_ERROR("pthread_mutex_unlock failed");
|
||||
|
||||
+5
-5
@@ -26,17 +26,17 @@ namespace embree
|
||||
class MutexSys {
|
||||
friend struct ConditionImplementation;
|
||||
public:
|
||||
MutexSys( void );
|
||||
~MutexSys( void );
|
||||
MutexSys();
|
||||
~MutexSys();
|
||||
|
||||
private:
|
||||
MutexSys (const MutexSys& other) DELETED; // do not implement
|
||||
MutexSys& operator= (const MutexSys& other) DELETED; // do not implement
|
||||
|
||||
public:
|
||||
void lock( void );
|
||||
bool try_lock( void );
|
||||
void unlock( void );
|
||||
void lock();
|
||||
bool try_lock();
|
||||
void unlock();
|
||||
|
||||
protected:
|
||||
void* mutex;
|
||||
|
||||
@@ -1,355 +0,0 @@
|
||||
// ======================================================================== //
|
||||
// Copyright 2009-2017 Intel Corporation //
|
||||
// //
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); //
|
||||
// you may not use this file except in compliance with the License. //
|
||||
// You may obtain a copy of the License at //
|
||||
// //
|
||||
// http://www.apache.org/licenses/LICENSE-2.0 //
|
||||
// //
|
||||
// Unless required by applicable law or agreed to in writing, software //
|
||||
// distributed under the License is distributed on an "AS IS" BASIS, //
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
|
||||
// See the License for the specific language governing permissions and //
|
||||
// limitations under the License. //
|
||||
// ======================================================================== //
|
||||
|
||||
#include "network.h"
|
||||
#include "string.h"
|
||||
#include "mutex.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Platforms supporting Socket interface
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined(__WIN32__)
|
||||
#define _WINSOCK_DEPRECATED_NO_WARNINGS
|
||||
//#include <winsock2.h>
|
||||
//#include <io.h>
|
||||
typedef int socklen_t;
|
||||
#define SHUT_RDWR 0x2
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <netdb.h>
|
||||
#define SOCKET int
|
||||
#define INVALID_SOCKET -1
|
||||
#define closesocket ::close
|
||||
#endif
|
||||
|
||||
/*! ignore if not supported */
|
||||
#ifndef MSG_NOSIGNAL
|
||||
#define MSG_NOSIGNAL 0
|
||||
#endif
|
||||
|
||||
#define BUFFERING 1
|
||||
|
||||
namespace embree
|
||||
{
|
||||
namespace network
|
||||
{
|
||||
__forceinline void initialize() {
|
||||
#ifdef __WIN32__
|
||||
static bool initialized = false;
|
||||
static MutexSys initMutex;
|
||||
Lock<MutexSys> lock(initMutex);
|
||||
WSADATA wsaData;
|
||||
short version = MAKEWORD(1,1);
|
||||
if (WSAStartup(version,&wsaData) != 0)
|
||||
THROW_RUNTIME_ERROR("Winsock initialization failed");
|
||||
initialized = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
struct buffered_socket_t
|
||||
{
|
||||
buffered_socket_t (SOCKET fd, size_t isize = 64*1024, size_t osize = 64*1024)
|
||||
: fd(fd),
|
||||
ibuf(new char[isize]), isize(isize), istart(0), iend(0),
|
||||
obuf(new char[osize]), osize(osize), oend(0) {
|
||||
}
|
||||
|
||||
~buffered_socket_t () {
|
||||
delete[] ibuf; ibuf = nullptr;
|
||||
delete[] obuf; obuf = nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
buffered_socket_t (const buffered_socket_t& other) DELETED; // do not implement
|
||||
buffered_socket_t& operator= (const buffered_socket_t& other) DELETED; // do not implement
|
||||
|
||||
public:
|
||||
SOCKET fd; //!< file descriptor of the socket
|
||||
char* ibuf;
|
||||
size_t isize;
|
||||
size_t istart,iend;
|
||||
char* obuf;
|
||||
size_t osize;
|
||||
size_t oend;
|
||||
};
|
||||
|
||||
struct AutoCloseSocket
|
||||
{
|
||||
SOCKET sock;
|
||||
AutoCloseSocket (SOCKET sock) : sock(sock) {}
|
||||
~AutoCloseSocket () {
|
||||
if (sock != INVALID_SOCKET) {
|
||||
closesocket(sock);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
socket_t connect(const char* host, unsigned short port)
|
||||
{
|
||||
initialize();
|
||||
|
||||
/*! create a new socket */
|
||||
SOCKET sockfd = ::socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (sockfd == INVALID_SOCKET) THROW_RUNTIME_ERROR("cannot create socket");
|
||||
AutoCloseSocket auto_close(sockfd);
|
||||
|
||||
/*! perform DNS lookup */
|
||||
struct hostent* server = ::gethostbyname(host);
|
||||
if (!server)
|
||||
THROW_RUNTIME_ERROR("server "+std::string(host)+" not found");
|
||||
if (server->h_length != sizeof(in_addr))
|
||||
THROW_RUNTIME_ERROR("gethostbyname error");
|
||||
|
||||
/*! perform connection */
|
||||
struct sockaddr_in serv_addr;
|
||||
memset((char*)&serv_addr, 0, sizeof(serv_addr));
|
||||
serv_addr.sin_family = AF_INET;
|
||||
serv_addr.sin_port = (unsigned short) htons(port);
|
||||
serv_addr.sin_addr = *(in_addr*) server->h_addr;
|
||||
|
||||
if (::connect(sockfd,(struct sockaddr*) &serv_addr,sizeof(serv_addr)) < 0)
|
||||
THROW_RUNTIME_ERROR("connection to "+std::string(host)+":"+toString(port)+" failed");
|
||||
|
||||
/*! enable TCP_NODELAY */
|
||||
#ifdef TCP_NODELAY
|
||||
{ int flag = 1; ::setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (const char*)&flag, sizeof(int)); }
|
||||
#endif
|
||||
|
||||
/*! we do not want SIGPIPE to be thrown */
|
||||
#ifdef SO_NOSIGPIPE
|
||||
{ int flag = 1; setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, (const char*) &flag, sizeof(int)); }
|
||||
#endif
|
||||
|
||||
auto_close.sock = INVALID_SOCKET;
|
||||
return (socket_t) new buffered_socket_t(sockfd);
|
||||
}
|
||||
|
||||
socket_t bind(unsigned short port)
|
||||
{
|
||||
initialize();
|
||||
|
||||
/*! create a new socket */
|
||||
SOCKET sockfd = ::socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (sockfd == INVALID_SOCKET) THROW_RUNTIME_ERROR("cannot create socket");
|
||||
AutoCloseSocket auto_close(sockfd);
|
||||
|
||||
/* When the server completes, the server socket enters a time-wait state during which the local
|
||||
address and port used by the socket are believed to be in use by the OS. The wait state may
|
||||
last several minutes. This socket option allows bind() to reuse the port immediately. */
|
||||
#ifdef SO_REUSEADDR
|
||||
{ int flag = true; ::setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const char*)&flag, sizeof(int)); }
|
||||
#endif
|
||||
|
||||
/*! bind socket to port */
|
||||
struct sockaddr_in serv_addr;
|
||||
memset((char *) &serv_addr, 0, sizeof(serv_addr));
|
||||
serv_addr.sin_family = AF_INET;
|
||||
serv_addr.sin_port = (unsigned short) htons(port);
|
||||
serv_addr.sin_addr.s_addr = INADDR_ANY;
|
||||
|
||||
if (::bind(sockfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) < 0)
|
||||
THROW_RUNTIME_ERROR("binding to port "+toString(port)+" failed");
|
||||
|
||||
/*! listen to port, up to 5 pending connections */
|
||||
if (::listen(sockfd,5) < 0)
|
||||
THROW_RUNTIME_ERROR("listening on socket failed");
|
||||
|
||||
auto_close.sock = INVALID_SOCKET;
|
||||
return (socket_t) new buffered_socket_t(sockfd);
|
||||
}
|
||||
|
||||
socket_t listen(socket_t hsock)
|
||||
{
|
||||
SOCKET sockfd = ((buffered_socket_t*) hsock)->fd;
|
||||
|
||||
/*! accept incoming connection */
|
||||
struct sockaddr_in addr;
|
||||
socklen_t len = sizeof(addr);
|
||||
SOCKET fd = ::accept(sockfd, (struct sockaddr *) &addr, &len);
|
||||
if (fd == INVALID_SOCKET) THROW_RUNTIME_ERROR("cannot accept connection");
|
||||
|
||||
/*! enable TCP_NODELAY */
|
||||
#ifdef TCP_NODELAY
|
||||
{ int flag = 1; ::setsockopt(fd,IPPROTO_TCP,TCP_NODELAY,(char*)&flag,sizeof(int)); }
|
||||
#endif
|
||||
|
||||
/*! we do not want SIGPIPE to be thrown */
|
||||
#ifdef SO_NOSIGPIPE
|
||||
{ int flag = 1; setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, (void*)&flag, sizeof(int)); }
|
||||
#endif
|
||||
|
||||
return (socket_t) new buffered_socket_t(fd);
|
||||
}
|
||||
|
||||
void read(socket_t hsock_i, void* data_i, size_t bytes)
|
||||
{
|
||||
#if BUFFERING
|
||||
char* data = (char*)data_i;
|
||||
buffered_socket_t* hsock = (buffered_socket_t*) hsock_i;
|
||||
while (bytes) {
|
||||
if (hsock->istart == hsock->iend) {
|
||||
ssize_t n = ::recv(hsock->fd,hsock->ibuf,int(hsock->isize),MSG_NOSIGNAL);
|
||||
if (n == 0) throw Disconnect();
|
||||
else if (n < 0) THROW_RUNTIME_ERROR("error reading from socket");
|
||||
hsock->istart = 0;
|
||||
hsock->iend = n;
|
||||
}
|
||||
size_t bsize = hsock->iend-hsock->istart;
|
||||
if (bytes < bsize) bsize = bytes;
|
||||
memcpy(data,hsock->ibuf+hsock->istart,bsize);
|
||||
data += bsize;
|
||||
hsock->istart += bsize;
|
||||
bytes -= bsize;
|
||||
}
|
||||
#else
|
||||
char* data = (char*) data_i;
|
||||
buffered_socket_t* hsock = (buffered_socket_t*) hsock_i;
|
||||
while (bytes) {
|
||||
ssize_t n = ::read(hsock->fd,data,bytes);
|
||||
if (n == 0) throw Disconnect();
|
||||
else if (n < 0) THROW_RUNTIME_ERROR("error reading from socket");
|
||||
data+=n;
|
||||
bytes-=n;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void write(socket_t hsock_i, const void* data_i, size_t bytes)
|
||||
{
|
||||
#if BUFFERING
|
||||
const char* data = (const char*) data_i;
|
||||
buffered_socket_t* hsock = (buffered_socket_t*) hsock_i;
|
||||
while (bytes) {
|
||||
if (hsock->oend == hsock->osize) flush(hsock_i);
|
||||
size_t bsize = hsock->osize-hsock->oend;
|
||||
if (bytes < bsize) bsize = bytes;
|
||||
memcpy(hsock->obuf+hsock->oend,data,bsize);
|
||||
data += bsize;
|
||||
hsock->oend += bsize;
|
||||
bytes -= bsize;
|
||||
}
|
||||
#else
|
||||
const char* data = (const char*) data_i;
|
||||
buffered_socket_t* hsock = (buffered_socket_t*) hsock_i;
|
||||
while (bytes) {
|
||||
ssize_t n = ::write(hsock->fd,data,bytes);
|
||||
if (n < 0) THROW_RUNTIME_ERROR("error writing to socket");
|
||||
data+=n;
|
||||
bytes-=n;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void flush(socket_t hsock_i)
|
||||
{
|
||||
#if BUFFERING
|
||||
buffered_socket_t* hsock = (buffered_socket_t*) hsock_i;
|
||||
char* data = hsock->obuf;
|
||||
size_t bytes = hsock->oend;
|
||||
while (bytes > 0) {
|
||||
ssize_t n = ::send(hsock->fd,data,(int)bytes,MSG_NOSIGNAL);
|
||||
if (n < 0) THROW_RUNTIME_ERROR("error writing to socket");
|
||||
bytes -= n;
|
||||
data += n;
|
||||
}
|
||||
hsock->oend = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void close(socket_t hsock_i) {
|
||||
buffered_socket_t* hsock = (buffered_socket_t*) hsock_i;
|
||||
::shutdown(hsock->fd,SHUT_RDWR);
|
||||
closesocket(hsock->fd);
|
||||
delete hsock;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// All Platforms
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace embree
|
||||
{
|
||||
namespace network
|
||||
{
|
||||
bool read_bool(socket_t socket)
|
||||
{
|
||||
bool value = 0;
|
||||
read(socket,&value,sizeof(bool));
|
||||
return value;
|
||||
}
|
||||
|
||||
char read_char(socket_t socket)
|
||||
{
|
||||
char value = 0;
|
||||
read(socket,&value,sizeof(char));
|
||||
return value;
|
||||
}
|
||||
|
||||
int read_int(socket_t socket)
|
||||
{
|
||||
int value = 0;
|
||||
read(socket,&value,sizeof(int));
|
||||
return value;
|
||||
}
|
||||
|
||||
float read_float(socket_t socket)
|
||||
{
|
||||
float value = 0.0f;
|
||||
read(socket,&value,sizeof(float));
|
||||
return value;
|
||||
}
|
||||
|
||||
std::string read_string(socket_t socket)
|
||||
{
|
||||
int bytes = read_int(socket);
|
||||
char* str = new char[bytes+1];
|
||||
read(socket,str,bytes);
|
||||
str[bytes] = 0x00;
|
||||
std::string s(str);
|
||||
delete[] str;
|
||||
return s;
|
||||
}
|
||||
|
||||
void write(socket_t socket, bool value) {
|
||||
write(socket,&value,sizeof(bool));
|
||||
}
|
||||
|
||||
void write(socket_t socket, char value) {
|
||||
write(socket,&value,sizeof(char));
|
||||
}
|
||||
|
||||
void write(socket_t socket, int value) {
|
||||
write(socket,&value,sizeof(int));
|
||||
}
|
||||
|
||||
void write(socket_t socket, float value) {
|
||||
write(socket,&value,sizeof(float));
|
||||
}
|
||||
|
||||
void write(socket_t socket, const std::string& str) {
|
||||
write(socket,(int)str.size());
|
||||
write(socket,str.c_str(),str.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
// ======================================================================== //
|
||||
// Copyright 2009-2017 Intel Corporation //
|
||||
// //
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); //
|
||||
// you may not use this file except in compliance with the License. //
|
||||
// You may obtain a copy of the License at //
|
||||
// //
|
||||
// http://www.apache.org/licenses/LICENSE-2.0 //
|
||||
// //
|
||||
// Unless required by applicable law or agreed to in writing, software //
|
||||
// distributed under the License is distributed on an "AS IS" BASIS, //
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
|
||||
// See the License for the specific language governing permissions and //
|
||||
// limitations under the License. //
|
||||
// ======================================================================== //
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
namespace embree
|
||||
{
|
||||
namespace network
|
||||
{
|
||||
/*! type for a socket */
|
||||
typedef struct opaque_socket_t* socket_t;
|
||||
|
||||
/*! exception thrown when other side disconnects */
|
||||
struct Disconnect : public std::exception {
|
||||
virtual const char* what() const throw() {
|
||||
return "network disconnect";
|
||||
}
|
||||
};
|
||||
|
||||
/*! creates a socket bound to a port */
|
||||
socket_t bind(unsigned short port);
|
||||
|
||||
/*! listens for an incoming connection and accepts that connection */
|
||||
socket_t listen(socket_t sockfd);
|
||||
|
||||
/*! initiates a connection */
|
||||
socket_t connect(const char* host, unsigned short port);
|
||||
|
||||
/*! read data from the socket */
|
||||
void read(socket_t socket, void* data, size_t bytes);
|
||||
|
||||
/*! write data to the socket */
|
||||
void write(socket_t socket, const void* data, size_t bytes);
|
||||
|
||||
/*! flushes the write buffer */
|
||||
void flush(socket_t socket);
|
||||
|
||||
/*! close a socket */
|
||||
void close(socket_t socket);
|
||||
|
||||
/*! reads a bool from the socket */
|
||||
bool read_bool(socket_t socket);
|
||||
|
||||
/*! reads a character from the socket */
|
||||
char read_char(socket_t socket);
|
||||
|
||||
/*! reads an integer from the socket */
|
||||
int read_int(socket_t socket);
|
||||
|
||||
/*! reads a float from the socket */
|
||||
float read_float(socket_t socket);
|
||||
|
||||
/*! reads a string from the socket */
|
||||
std::string read_string(socket_t socket);
|
||||
|
||||
/*! writes a bool to the socket */
|
||||
void write(socket_t socket, bool value);
|
||||
|
||||
/*! writes a character to the socket */
|
||||
void write(socket_t socket, char value);
|
||||
|
||||
/*! writes an integer to the socket */
|
||||
void write(socket_t socket, int value);
|
||||
|
||||
/*! writes a float to the socket */
|
||||
void write(socket_t socket, float value);
|
||||
|
||||
/*! writes a string to the socket */
|
||||
void write(socket_t socket, const std::string& str);
|
||||
}
|
||||
}
|
||||
@@ -18,8 +18,6 @@
|
||||
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
|
||||
//__asm__(".symver memcpy,memcpy@GLIBC_2.2.5");
|
||||
|
||||
#include <cstddef>
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
@@ -251,6 +249,7 @@ __forceinline std::string toString(long long value) {
|
||||
#pragma warning(disable:4503) // decorated name length exceeded, name was truncated
|
||||
#pragma warning(disable:4180) // qualifier applied to function type has no meaning; ignored
|
||||
#pragma warning(disable:4258) // definition from the for loop is ignored; the definition from the enclosing scope is used
|
||||
#pragma warning(disable:4789) // buffer '' of size 8 bytes will be overrun; 32 bytes will be written starting at offset 0
|
||||
#endif
|
||||
|
||||
#if defined(__clang__) && !defined(__INTEL_COMPILER)
|
||||
@@ -353,7 +352,7 @@ namespace embree
|
||||
template <typename Closure>
|
||||
OnScopeExitHelper<Closure> OnScopeExit(const Closure f) {
|
||||
return OnScopeExitHelper<Closure>(f);
|
||||
};
|
||||
}
|
||||
|
||||
#define STRING_JOIN2(arg1, arg2) DO_STRING_JOIN2(arg1, arg2)
|
||||
#define DO_STRING_JOIN2(arg1, arg2) arg1 ## arg2
|
||||
@@ -364,4 +363,5 @@ namespace embree
|
||||
std::unique_ptr<Ty> make_unique(Ty* ptr) {
|
||||
return std::unique_ptr<Ty>(ptr);
|
||||
}
|
||||
|
||||
}
|
||||
+7
-7
@@ -48,7 +48,7 @@ namespace embree
|
||||
/// Constructors, Assignment & Cast Operators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
__forceinline Ref( void ) : ptr(nullptr) {}
|
||||
__forceinline Ref() : ptr(nullptr) {}
|
||||
__forceinline Ref(NullTy) : ptr(nullptr) {}
|
||||
__forceinline Ref( const Ref& input ) : ptr(input.ptr) { if ( ptr ) ptr->refInc(); }
|
||||
|
||||
@@ -57,7 +57,7 @@ namespace embree
|
||||
ptr->refInc();
|
||||
}
|
||||
|
||||
__forceinline ~Ref( void ) {
|
||||
__forceinline ~Ref() {
|
||||
if (ptr) ptr->refDec();
|
||||
}
|
||||
|
||||
@@ -83,12 +83,12 @@ namespace embree
|
||||
return *this;
|
||||
}
|
||||
|
||||
__forceinline operator bool( void ) const { return ptr != nullptr; }
|
||||
__forceinline operator bool() const { return ptr != nullptr; }
|
||||
|
||||
__forceinline const Type& operator *( void ) const { return *ptr; }
|
||||
__forceinline Type& operator *( void ) { return *ptr; }
|
||||
__forceinline const Type* operator ->( void ) const { return ptr; }
|
||||
__forceinline Type* operator ->( void ) { return ptr; }
|
||||
__forceinline const Type& operator *() const { return *ptr; }
|
||||
__forceinline Type& operator *() { return *ptr; }
|
||||
__forceinline const Type* operator ->() const { return ptr; }
|
||||
__forceinline Type* operator ->() { return ptr; }
|
||||
|
||||
template<typename TypeOut>
|
||||
__forceinline Ref<TypeOut> cast() { return Ref<TypeOut>(static_cast<TypeOut*>(ptr)); }
|
||||
|
||||
@@ -25,4 +25,13 @@ namespace embree
|
||||
char to_upper(char c) { return char(toupper(int(c))); }
|
||||
std::string toLowerCase(const std::string& s) { std::string dst(s); std::transform(dst.begin(), dst.end(), dst.begin(), to_lower); return dst; }
|
||||
std::string toUpperCase(const std::string& s) { std::string dst(s); std::transform(dst.begin(), dst.end(), dst.begin(), to_upper); return dst; }
|
||||
|
||||
Vec3f string_to_Vec3f ( std::string str )
|
||||
{
|
||||
size_t next = 0;
|
||||
const float x = std::stof(str,&next); str = str.substr(next+1);
|
||||
const float y = std::stof(str,&next); str = str.substr(next+1);
|
||||
const float z = std::stof(str,&next);
|
||||
return Vec3f(x,y,z);
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "platform.h"
|
||||
#include "../math/vec3.h"
|
||||
|
||||
namespace embree
|
||||
{
|
||||
@@ -40,4 +41,6 @@ namespace embree
|
||||
|
||||
std::string toLowerCase(const std::string& s);
|
||||
std::string toUpperCase(const std::string& s);
|
||||
|
||||
Vec3f string_to_Vec3f ( std::string str );
|
||||
}
|
||||
+15
-10
@@ -341,7 +341,8 @@ namespace embree
|
||||
{
|
||||
std::string getExecutableFileName() {
|
||||
char filename[1024];
|
||||
if (!GetModuleFileName(nullptr, filename, sizeof(filename))) return std::string();
|
||||
if (!GetModuleFileName(nullptr, filename, sizeof(filename)))
|
||||
return std::string();
|
||||
return std::string(filename);
|
||||
}
|
||||
|
||||
@@ -411,10 +412,11 @@ namespace embree
|
||||
{
|
||||
std::string getExecutableFileName()
|
||||
{
|
||||
char pid[32]; sprintf(pid, "/proc/%d/exe", getpid());
|
||||
char buf[1024];
|
||||
int bytes = readlink(pid, buf, sizeof(buf)-1);
|
||||
if (bytes != -1) buf[bytes] = '\0';
|
||||
std::string pid = "/proc/" + toString(getpid()) + "/exe";
|
||||
char buf[4096];
|
||||
memset(buf,0,sizeof(buf));
|
||||
if (readlink(pid.c_str(), buf, sizeof(buf)-1) == -1)
|
||||
return std::string();
|
||||
return std::string(buf);
|
||||
}
|
||||
}
|
||||
@@ -434,9 +436,11 @@ namespace embree
|
||||
std::string getExecutableFileName()
|
||||
{
|
||||
const int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
|
||||
char buf[1024];
|
||||
size_t len = sizeof(buf);
|
||||
if (sysctl(mib, 4, buf, &len, 0x0, 0) == -1) *buf = '\0';
|
||||
char buf[4096];
|
||||
memset(buf,0,sizeof(buf));
|
||||
size_t len = sizeof(buf)-1;
|
||||
if (sysctl(mib, 4, buf, &len, 0x0, 0) == -1)
|
||||
return std::string();
|
||||
return std::string(buf);
|
||||
}
|
||||
}
|
||||
@@ -455,9 +459,10 @@ namespace embree
|
||||
{
|
||||
std::string getExecutableFileName()
|
||||
{
|
||||
char buf[1024];
|
||||
char buf[4096];
|
||||
uint32_t size = sizeof(buf);
|
||||
if (_NSGetExecutablePath(buf, &size) != 0) return std::string();
|
||||
if (_NSGetExecutablePath(buf, &size) != 0)
|
||||
return std::string();
|
||||
return std::string(buf);
|
||||
}
|
||||
}
|
||||
|
||||
+5
-6
@@ -93,7 +93,7 @@ namespace embree
|
||||
|
||||
|
||||
__forceinline void resize(size_t new_size) {
|
||||
internal_resize(new_size,size_alloced < new_size ? new_size : size_alloced);
|
||||
internal_resize(new_size,internal_grow_size(new_size));
|
||||
}
|
||||
|
||||
__forceinline void reserve(size_t new_alloced)
|
||||
@@ -130,7 +130,7 @@ namespace embree
|
||||
__forceinline void push_back(const T& nt)
|
||||
{
|
||||
const T v = nt; // need local copy as input reference could point to this vector
|
||||
internal_grow(size_active+1);
|
||||
internal_resize(size_active,internal_grow_size(size_active+1));
|
||||
::new (&items[size_active++]) T(v);
|
||||
}
|
||||
|
||||
@@ -216,11 +216,11 @@ namespace embree
|
||||
size_alloced = new_alloced;
|
||||
}
|
||||
|
||||
__forceinline void internal_grow(size_t new_alloced)
|
||||
__forceinline size_t internal_grow_size(size_t new_alloced)
|
||||
{
|
||||
/* do nothing if container already large enough */
|
||||
if (new_alloced <= size_alloced)
|
||||
return;
|
||||
return size_alloced;
|
||||
|
||||
/* resize to next power of 2 otherwise */
|
||||
size_t new_size_alloced = size_alloced;
|
||||
@@ -228,8 +228,7 @@ namespace embree
|
||||
new_size_alloced = 2*new_size_alloced;
|
||||
if (new_size_alloced == 0) new_size_alloced = 1;
|
||||
}
|
||||
|
||||
internal_resize(size_active,new_size_alloced);
|
||||
return new_size_alloced;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -20,12 +20,12 @@ ENDIF()
|
||||
|
||||
IF (TASKING_TBB)
|
||||
ADD_LIBRARY(tasking STATIC taskschedulertbb.cpp)
|
||||
TARGET_LINK_LIBRARIES(tasking sys ${TBB_LIBRARIES})
|
||||
TARGET_LINK_LIBRARIES(tasking sys math ${TBB_LIBRARIES})
|
||||
ENDIF()
|
||||
|
||||
IF (TASKING_PPL)
|
||||
ADD_LIBRARY(tasking STATIC taskschedulerppl.cpp)
|
||||
TARGET_LINK_LIBRARIES(tasking sys ${PPL_LIBRARIES})
|
||||
TARGET_LINK_LIBRARIES(tasking sys math ${PPL_LIBRARIES})
|
||||
ENDIF()
|
||||
|
||||
SET_PROPERTY(TARGET tasking PROPERTY FOLDER common)
|
||||
@@ -50,7 +50,7 @@ namespace embree
|
||||
}
|
||||
|
||||
/*! run this task */
|
||||
__dllexport void TaskScheduler::Task::run (Thread& thread) // FIXME: avoid as many __dllexports as possible
|
||||
void TaskScheduler::Task::run_internal (Thread& thread) // FIXME: avoid as many __dllexports as possible
|
||||
{
|
||||
/* try to run if not already stolen */
|
||||
if (try_switch_state(INITIALIZED,DONE))
|
||||
@@ -71,14 +71,19 @@ namespace embree
|
||||
/* steal until all dependencies have completed */
|
||||
steal_loop(thread,
|
||||
[&] () { return dependencies>0; },
|
||||
[&] () { while (thread.tasks.execute_local(thread,this)); });
|
||||
[&] () { while (thread.tasks.execute_local_internal(thread,this)); });
|
||||
|
||||
/* now signal our parent task that we are finished */
|
||||
if (parent)
|
||||
parent->add_dependencies(-1);
|
||||
}
|
||||
|
||||
__dllexport bool TaskScheduler::TaskQueue::execute_local(Thread& thread, Task* parent)
|
||||
/*! run this task */
|
||||
__dllexport void TaskScheduler::Task::run (Thread& thread) {
|
||||
run_internal(thread);
|
||||
}
|
||||
|
||||
bool TaskScheduler::TaskQueue::execute_local_internal(Thread& thread, Task* parent)
|
||||
{
|
||||
/* stop if we run out of local tasks or reach the waiting task */
|
||||
if (right == 0 || &tasks[right-1] == parent)
|
||||
@@ -86,7 +91,7 @@ namespace embree
|
||||
|
||||
/* execute task */
|
||||
size_t oldRight = right;
|
||||
tasks[right-1].run(thread);
|
||||
tasks[right-1].run_internal(thread);
|
||||
if (right != oldRight) {
|
||||
THROW_RUNTIME_ERROR("you have to wait for spawned subtasks");
|
||||
}
|
||||
@@ -102,6 +107,10 @@ namespace embree
|
||||
return right != 0;
|
||||
}
|
||||
|
||||
__dllexport bool TaskScheduler::TaskQueue::execute_local(Thread& thread, Task* parent) {
|
||||
return execute_local_internal(thread,parent);
|
||||
}
|
||||
|
||||
bool TaskScheduler::TaskQueue::steal(Thread& thread)
|
||||
{
|
||||
size_t l = left;
|
||||
@@ -316,7 +325,7 @@ namespace embree
|
||||
{
|
||||
Thread* thread = TaskScheduler::thread();
|
||||
if (thread == nullptr) return true;
|
||||
while (thread->tasks.execute_local(*thread,thread->task)) {};
|
||||
while (thread->tasks.execute_local_internal(*thread,thread->task)) {};
|
||||
return thread->scheduler->cancellingException == nullptr;
|
||||
}
|
||||
|
||||
@@ -335,7 +344,7 @@ namespace embree
|
||||
[&] () { return anyTasksRunning > 0; },
|
||||
[&] () {
|
||||
anyTasksRunning++;
|
||||
while (thread.tasks.execute_local(thread,nullptr));
|
||||
while (thread.tasks.execute_local_internal(thread,nullptr));
|
||||
anyTasksRunning--;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -109,6 +109,8 @@ namespace embree
|
||||
/*! run this task */
|
||||
__dllexport void run(Thread& thread);
|
||||
|
||||
void run_internal(Thread& thread);
|
||||
|
||||
public:
|
||||
std::atomic<int> state; //!< state this task is in
|
||||
std::atomic<int> dependencies; //!< dependencies to wait for
|
||||
@@ -124,16 +126,20 @@ namespace embree
|
||||
TaskQueue ()
|
||||
: left(0), right(0), stackPtr(0) {}
|
||||
|
||||
__forceinline void* alloc(size_t bytes, size_t align = 64) {
|
||||
stackPtr += bytes + ((align - stackPtr) & (align-1));
|
||||
assert(stackPtr <= CLOSURE_STACK_SIZE);
|
||||
__forceinline void* alloc(size_t bytes, size_t align = 64)
|
||||
{
|
||||
size_t ofs = bytes + ((align - stackPtr) & (align-1));
|
||||
if (stackPtr + ofs > CLOSURE_STACK_SIZE)
|
||||
throw std::runtime_error("closure stack overflow");
|
||||
stackPtr += ofs;
|
||||
return &stack[stackPtr-bytes];
|
||||
}
|
||||
|
||||
template<typename Closure>
|
||||
__forceinline void push_right(Thread& thread, const size_t size, const Closure& closure)
|
||||
{
|
||||
assert(right < TASK_STACK_SIZE);
|
||||
if (right >= TASK_STACK_SIZE)
|
||||
throw std::runtime_error("task stack overflow");
|
||||
|
||||
/* allocate new task on right side of stack */
|
||||
size_t oldStackPtr = stackPtr;
|
||||
@@ -145,6 +151,7 @@ namespace embree
|
||||
}
|
||||
|
||||
__dllexport bool execute_local(Thread& thread, Task* parent);
|
||||
bool execute_local_internal(Thread& thread, Task* parent);
|
||||
bool steal(Thread& thread);
|
||||
size_t getTaskSizeAtLeft();
|
||||
|
||||
|
||||
@@ -28,6 +28,12 @@
|
||||
# define NOMINMAX
|
||||
#endif
|
||||
|
||||
// We need to define these to avoid implicit linkage against
|
||||
// tbb_debug.lib under Windows. When removing these lines debug build
|
||||
// under Windows fails.
|
||||
#define __TBB_NO_IMPLICIT_LINKAGE 1
|
||||
#define __TBBMALLOC_NO_IMPLICIT_LINKAGE 1
|
||||
|
||||
#include "tbb/tbb.h"
|
||||
#include "tbb/parallel_sort.h"
|
||||
|
||||
@@ -67,5 +73,7 @@ namespace embree
|
||||
return tbb::task_scheduler_init::default_num_threads();
|
||||
#endif
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
@@ -20,6 +20,8 @@
|
||||
#include <stddef.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "rtcore_version.h"
|
||||
|
||||
#if defined(_WIN32)
|
||||
#if defined(_M_X64)
|
||||
typedef long long ssize_t;
|
||||
@@ -58,12 +60,6 @@ typedef int ssize_t;
|
||||
# define RTCORE_FORCEINLINE inline __attribute__((always_inline))
|
||||
#endif
|
||||
|
||||
/*! Embree API version */
|
||||
#define RTCORE_VERSION_MAJOR @EMBREE_VERSION_MAJOR@
|
||||
#define RTCORE_VERSION_MINOR @EMBREE_VERSION_MINOR@
|
||||
#define RTCORE_VERSION_PATCH @EMBREE_VERSION_PATCH@
|
||||
#define RTCORE_VERSION @EMBREE_VERSION_NUMBER@
|
||||
|
||||
/*! \file rtcore.h Defines the Embree Ray Tracing Kernel API for C and C++
|
||||
|
||||
This file defines the Embree ray tracing kernel API for C and
|
||||
@@ -156,7 +152,7 @@ enum RTCParameter {
|
||||
RTC_CONFIG_INTERSECTION_FILTER = 8, //!< checks if intersection filters are enabled (read only)
|
||||
RTC_CONFIG_INTERSECTION_FILTER_RESTORE = 9, //!< checks if intersection filters restores previous hit (read only)
|
||||
RTC_CONFIG_IGNORE_INVALID_RAYS = 11, //!< checks if invalid rays are ignored (read only)
|
||||
RTC_CONFIG_TASKING_SYSTEM = 12, //!< return used tasking system (0 = INTERNAL, 1 = TBB) (read only)
|
||||
RTC_CONFIG_TASKING_SYSTEM = 12, //!< return used tasking system (0 = INTERNAL, 1 = TBB, 2 = PPL) (read only)
|
||||
|
||||
RTC_CONFIG_VERSION_MAJOR = 13, //!< returns Embree major version (read only)
|
||||
RTC_CONFIG_VERSION_MINOR = 14, //!< returns Embree minor version (read only)
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
#ifndef __RTCORE_ISPH__
|
||||
#define __RTCORE_ISPH__
|
||||
|
||||
#include "rtcore_version.h"
|
||||
|
||||
#if !defined(RTCORE_API)
|
||||
#define RTCORE_API extern "C" unmasked
|
||||
#endif
|
||||
@@ -31,12 +33,6 @@
|
||||
#define RTCORE_DEPRECATED // FIXME: deprecation not supported by ISPC
|
||||
#endif
|
||||
|
||||
/*! Embree API version */
|
||||
#define RTCORE_VERSION_MAJOR @EMBREE_VERSION_MAJOR@
|
||||
#define RTCORE_VERSION_MINOR @EMBREE_VERSION_MINOR@
|
||||
#define RTCORE_VERSION_PATCH @EMBREE_VERSION_PATCH@
|
||||
#define RTCORE_VERSION @EMBREE_VERSION_NUMBER@
|
||||
|
||||
/*! \file rtcore.isph Defines the Embree Ray Tracing Kernel API for ISPC.
|
||||
|
||||
This file defines the Embree ray tracing kernel API for C and
|
||||
|
||||
@@ -226,7 +226,7 @@ RTCORE_API void rtcSetTransform2 (RTCScene scene, //!< s
|
||||
(numTriangles), number of vertices (numVertices), and number of time
|
||||
steps (1 for normal meshes, and up to RTC_MAX_TIME_STEPS for multi
|
||||
segment motion blur), have to get specified. The triangle indices
|
||||
can be set be mapping and writing to the index buffer
|
||||
can be set by mapping and writing to the index buffer
|
||||
(RTC_INDEX_BUFFER) and the triangle vertices can be set by mapping
|
||||
and writing into the vertex buffer (RTC_VERTEX_BUFFER). In case of
|
||||
multi-segment motion blur, multiple vertex buffers have to get filled
|
||||
@@ -255,7 +255,7 @@ RTCORE_API unsigned rtcNewTriangleMesh2 (RTCScene scene, //!<
|
||||
/*! \brief Creates a new quad mesh. The number of quads (numQuads),
|
||||
number of vertices (numVertices), and number of time steps (1 for
|
||||
normal meshes, and up to RTC_MAX_TIME_STEPS for multi-segment motion
|
||||
blur), have to get specified. The quad indices can be set be mapping
|
||||
blur), have to get specified. The quad indices can be set by mapping
|
||||
and writing to the index buffer (RTC_INDEX_BUFFER) and the quad
|
||||
vertices can be set by mapping and writing into the vertex buffer
|
||||
(RTC_VERTEX_BUFFER). In case of multi-segment motion blur, multiple
|
||||
|
||||
@@ -165,15 +165,15 @@ RTCORE_DEPRECATED uniform unsigned int rtcNewInstance (RTCScene target,
|
||||
the provided scene. If any geometry is hit, the instance ID (instID)
|
||||
member of the ray will get set to the geometry ID of the
|
||||
instance. */
|
||||
uniform unsigned rtcNewInstance2 (RTCScene target, //!< the scene the instance belongs to
|
||||
RTCScene source, //!< the scene to instantiate
|
||||
uniform size_t numTimeSteps = 1 //!< number of timesteps, one matrix per timestep
|
||||
uniform unsigned int rtcNewInstance2 (RTCScene target, //!< the scene the instance belongs to
|
||||
RTCScene source, //!< the scene to instantiate
|
||||
uniform size_t numTimeSteps = 1 //!< number of timesteps, one matrix per timestep
|
||||
);
|
||||
|
||||
uniform unsigned rtcNewInstance3 (RTCScene target, //!< the scene the instance belongs to
|
||||
RTCScene source, //!< the scene to instantiate
|
||||
uniform size_t numTimeSteps = 1, //!< number of timesteps, one matrix per timestep
|
||||
uniform unsigned int geomID = -1 //!< optional geometry ID to assign
|
||||
uniform unsigned int rtcNewInstance3 (RTCScene target, //!< the scene the instance belongs to
|
||||
RTCScene source, //!< the scene to instantiate
|
||||
uniform size_t numTimeSteps = 1, //!< number of timesteps, one matrix per timestep
|
||||
uniform unsigned int geomID = -1 //!< optional geometry ID to assign
|
||||
);
|
||||
|
||||
/*! \brief Creates a new geometry instance.
|
||||
@@ -208,7 +208,7 @@ void rtcSetTransform2 (RTCScene scene, //!< scen
|
||||
(numTriangles), number of vertices (numVertices), and number of time
|
||||
steps (1 for normal meshes, and up to RTC_MAX_TIME_STEPS for multi
|
||||
segment motion blur), have to get specified. The triangle indices
|
||||
can be set be mapping and writing to the index buffer
|
||||
can be set by mapping and writing to the index buffer
|
||||
(RTC_INDEX_BUFFER) and the triangle vertices can be set by mapping
|
||||
and writing into the vertex buffer (RTC_VERTEX_BUFFER). In case of
|
||||
multi-segment motion blur, multiple vertex buffers have to get filled
|
||||
@@ -236,7 +236,7 @@ uniform unsigned int rtcNewTriangleMesh2(RTCScene scene, //!<
|
||||
/*! \brief Creates a new quad mesh. The number of quads (numQuads),
|
||||
number of vertices (numVertices), and number of time steps (1 for
|
||||
normal meshes, and up to RTC_MAX_TIME_STEPS for multi-segment motion
|
||||
blur), have to get specified. The quad indices can be set be mapping
|
||||
blur), have to get specified. The quad indices can be set by mapping
|
||||
and writing to the index buffer (RTC_INDEX_BUFFER) and the quad
|
||||
vertices can be set by mapping and writing into the vertex buffer
|
||||
(RTC_VERTEX_BUFFER). In case of multi-segment motion blur, multiple
|
||||
@@ -564,7 +564,7 @@ uniform unsigned int rtcNewLineSegments2(RTCScene scene, //!<
|
||||
/*! Sets a uniform tessellation rate for subdiv meshes and hair
|
||||
* geometry. For subdivision meshes the RTC_LEVEL_BUFFER can also be used
|
||||
* optionally to set a different tessellation rate per edge.*/
|
||||
void rtcSetTessellationRate (RTCScene scene, uniform unsigned geomID, uniform float tessellationRate);
|
||||
void rtcSetTessellationRate (RTCScene scene, uniform unsigned int geomID, uniform float tessellationRate);
|
||||
|
||||
/*! \brief Sets 32 bit ray mask. */
|
||||
void rtcSetMask (RTCScene scene, uniform unsigned int geomID, uniform int mask);
|
||||
@@ -578,7 +578,7 @@ RTCORE_DEPRECATED void rtcSetBoundaryMode(RTCScene scene, uniform unsigned int g
|
||||
void rtcSetSubdivisionMode(RTCScene scene, uniform unsigned int geomID, uniform unsigned int topologyID, uniform RTCSubdivisionMode mode);
|
||||
|
||||
/*! \brief Binds a user vertex buffer to some index buffer topology. */
|
||||
void rtcSetIndexBuffer(RTCScene scene, uniform unsigned geomID, uniform RTCBufferType vertexBuffer, uniform RTCBufferType indexBuffer);
|
||||
void rtcSetIndexBuffer(RTCScene scene, uniform unsigned int geomID, uniform RTCBufferType vertexBuffer, uniform RTCBufferType indexBuffer);
|
||||
|
||||
/*! \brief Maps specified buffer. This function can be used to set index and
|
||||
* vertex buffers of geometries. */
|
||||
|
||||
@@ -153,12 +153,12 @@ void rtcSetIntersectFunction (RTCScene scene, uniform unsigned int geomID, unifo
|
||||
/*! Set intersect function for stream of rays. The rtcIntersectN function
|
||||
* will call the passed function for intersecting the user
|
||||
* geometry. */
|
||||
void rtcSetIntersectFunction1Mp (RTCScene scene, uniform unsigned geomID, uniform RTCIntersectFunc1Mp intersect);
|
||||
void rtcSetIntersectFunction1Mp (RTCScene scene, uniform unsigned int geomID, uniform RTCIntersectFunc1Mp intersect);
|
||||
|
||||
/*! Set intersect function for ray packets of size N. The rtcIntersectN function
|
||||
* will call the passed function for intersecting the user
|
||||
* geometry. */
|
||||
void rtcSetIntersectFunctionN (RTCScene scene, uniform unsigned geomID, uniform RTCIntersectFuncN intersect);
|
||||
void rtcSetIntersectFunctionN (RTCScene scene, uniform unsigned int geomID, uniform RTCIntersectFuncN intersect);
|
||||
|
||||
/*! Set occlusion function for uniform rays. The rtcOccluded1 function
|
||||
* will call the passed function for intersecting the user
|
||||
@@ -173,12 +173,12 @@ void rtcSetOccludedFunction (RTCScene scene, uniform unsigned int geomID, unifor
|
||||
/*! Set occlusion function for a stream of single rays. The rtcOccludedN function
|
||||
* will call the passed function for intersecting the user
|
||||
* geometry. */
|
||||
void rtcSetOccludedFunction1Mp (RTCScene scene, uniform unsigned geomID, uniform RTCOccludedFunc1Mp occluded);
|
||||
void rtcSetOccludedFunction1Mp (RTCScene scene, uniform unsigned int geomID, uniform RTCOccludedFunc1Mp occluded);
|
||||
|
||||
/*! Set occlusion function for a ray packets of size N. The rtcOccludedN function
|
||||
* will call the passed function for intersecting the user
|
||||
* geometry. */
|
||||
void rtcSetOccludedFunctionN (RTCScene scene, uniform unsigned geomID, uniform RTCOccludedFuncN occluded);
|
||||
void rtcSetOccludedFunctionN (RTCScene scene, uniform unsigned int geomID, uniform RTCOccludedFuncN occluded);
|
||||
|
||||
/*! @} */
|
||||
|
||||
|
||||
@@ -169,28 +169,28 @@ public:
|
||||
struct RTCRayN {};
|
||||
RTCORE_FORCEINLINE float& RTCRayN_org_x(RTCRayN* ptr, size_t N, size_t i) { const size_t N1 = (size_t)(N == 1); return ((float*)ptr)[0*N+0*N1+i]; } //!< x coordinate of ray origin
|
||||
RTCORE_FORCEINLINE float& RTCRayN_org_y(RTCRayN* ptr, size_t N, size_t i) { const size_t N1 = (size_t)(N == 1); return ((float*)ptr)[1*N+0*N1+i]; } //!< y coordinate of ray origin
|
||||
RTCORE_FORCEINLINE float& RTCRayN_org_z(RTCRayN* ptr, size_t N, size_t i) { const size_t N1 = (size_t)(N == 1); return ((float*)ptr)[2*N+0*N1+i]; }; //!< z coordinate of ray origin
|
||||
RTCORE_FORCEINLINE float& RTCRayN_org_z(RTCRayN* ptr, size_t N, size_t i) { const size_t N1 = (size_t)(N == 1); return ((float*)ptr)[2*N+0*N1+i]; } //!< z coordinate of ray origin
|
||||
|
||||
RTCORE_FORCEINLINE float& RTCRayN_dir_x(RTCRayN* ptr, size_t N, size_t i) { const size_t N1 = (size_t)(N == 1); return ((float*)ptr)[3*N+1*N1+i]; }; //!< x coordinate of ray direction
|
||||
RTCORE_FORCEINLINE float& RTCRayN_dir_y(RTCRayN* ptr, size_t N, size_t i) { const size_t N1 = (size_t)(N == 1); return ((float*)ptr)[4*N+1*N1+i]; }; //!< y coordinate of ray direction
|
||||
RTCORE_FORCEINLINE float& RTCRayN_dir_z(RTCRayN* ptr, size_t N, size_t i) { const size_t N1 = (size_t)(N == 1); return ((float*)ptr)[5*N+1*N1+i]; }; //!< z coordinate of ray direction
|
||||
RTCORE_FORCEINLINE float& RTCRayN_dir_x(RTCRayN* ptr, size_t N, size_t i) { const size_t N1 = (size_t)(N == 1); return ((float*)ptr)[3*N+1*N1+i]; } //!< x coordinate of ray direction
|
||||
RTCORE_FORCEINLINE float& RTCRayN_dir_y(RTCRayN* ptr, size_t N, size_t i) { const size_t N1 = (size_t)(N == 1); return ((float*)ptr)[4*N+1*N1+i]; } //!< y coordinate of ray direction
|
||||
RTCORE_FORCEINLINE float& RTCRayN_dir_z(RTCRayN* ptr, size_t N, size_t i) { const size_t N1 = (size_t)(N == 1); return ((float*)ptr)[5*N+1*N1+i]; } //!< z coordinate of ray direction
|
||||
|
||||
RTCORE_FORCEINLINE float& RTCRayN_tnear(RTCRayN* ptr, size_t N, size_t i) { const size_t N1 = (size_t)(N == 1); return ((float*)ptr)[6*N+2*N1+i]; }; //!< Start of ray segment
|
||||
RTCORE_FORCEINLINE float& RTCRayN_tfar (RTCRayN* ptr, size_t N, size_t i) { const size_t N1 = (size_t)(N == 1); return ((float*)ptr)[7*N+2*N1+i]; }; //!< End of ray segment (set to hit distance)
|
||||
RTCORE_FORCEINLINE float& RTCRayN_tnear(RTCRayN* ptr, size_t N, size_t i) { const size_t N1 = (size_t)(N == 1); return ((float*)ptr)[6*N+2*N1+i]; } //!< Start of ray segment
|
||||
RTCORE_FORCEINLINE float& RTCRayN_tfar (RTCRayN* ptr, size_t N, size_t i) { const size_t N1 = (size_t)(N == 1); return ((float*)ptr)[7*N+2*N1+i]; } //!< End of ray segment (set to hit distance)
|
||||
|
||||
RTCORE_FORCEINLINE float& RTCRayN_time(RTCRayN* ptr, size_t N, size_t i) { const size_t N1 = (size_t)(N == 1); return ((float*) ptr)[8*N+2*N1+i]; }; //!< Time of this ray for motion blur
|
||||
RTCORE_FORCEINLINE unsigned& RTCRayN_mask(RTCRayN* ptr, size_t N, size_t i) { const size_t N1 = (size_t)(N == 1); return ((unsigned*)ptr)[9*N+2*N1+i]; }; //!< Used to mask out objects during traversal
|
||||
RTCORE_FORCEINLINE float& RTCRayN_time(RTCRayN* ptr, size_t N, size_t i) { const size_t N1 = (size_t)(N == 1); return ((float*) ptr)[8*N+2*N1+i]; } //!< Time of this ray for motion blur
|
||||
RTCORE_FORCEINLINE unsigned& RTCRayN_mask(RTCRayN* ptr, size_t N, size_t i) { const size_t N1 = (size_t)(N == 1); return ((unsigned*)ptr)[9*N+2*N1+i]; } //!< Used to mask out objects during traversal
|
||||
|
||||
RTCORE_FORCEINLINE float& RTCRayN_Ng_x(RTCRayN* ptr, size_t N, size_t i) { const size_t N1 = (size_t)(N == 1); return ((float*)ptr)[10*N+2*N1+i]; }; //!< x coordinate of geometry normal
|
||||
RTCORE_FORCEINLINE float& RTCRayN_Ng_y(RTCRayN* ptr, size_t N, size_t i) { const size_t N1 = (size_t)(N == 1); return ((float*)ptr)[11*N+2*N1+i]; }; //!< y coordinate of geometry normal
|
||||
RTCORE_FORCEINLINE float& RTCRayN_Ng_z(RTCRayN* ptr, size_t N, size_t i) { const size_t N1 = (size_t)(N == 1); return ((float*)ptr)[12*N+2*N1+i]; }; //!< z coordinate of geometry normal
|
||||
RTCORE_FORCEINLINE float& RTCRayN_Ng_x(RTCRayN* ptr, size_t N, size_t i) { const size_t N1 = (size_t)(N == 1); return ((float*)ptr)[10*N+2*N1+i]; } //!< x coordinate of geometry normal
|
||||
RTCORE_FORCEINLINE float& RTCRayN_Ng_y(RTCRayN* ptr, size_t N, size_t i) { const size_t N1 = (size_t)(N == 1); return ((float*)ptr)[11*N+2*N1+i]; } //!< y coordinate of geometry normal
|
||||
RTCORE_FORCEINLINE float& RTCRayN_Ng_z(RTCRayN* ptr, size_t N, size_t i) { const size_t N1 = (size_t)(N == 1); return ((float*)ptr)[12*N+2*N1+i]; } //!< z coordinate of geometry normal
|
||||
|
||||
RTCORE_FORCEINLINE float& RTCRayN_u (RTCRayN* ptr, size_t N, size_t i) { const size_t N1 = (size_t)(N == 1); return ((float*)ptr)[13*N+3*N1+i]; }; //!< Barycentric u coordinate of hit
|
||||
RTCORE_FORCEINLINE float& RTCRayN_v (RTCRayN* ptr, size_t N, size_t i) { const size_t N1 = (size_t)(N == 1); return ((float*)ptr)[14*N+3*N1+i]; }; //!< Barycentric v coordinate of hit
|
||||
RTCORE_FORCEINLINE float& RTCRayN_u (RTCRayN* ptr, size_t N, size_t i) { const size_t N1 = (size_t)(N == 1); return ((float*)ptr)[13*N+3*N1+i]; } //!< Barycentric u coordinate of hit
|
||||
RTCORE_FORCEINLINE float& RTCRayN_v (RTCRayN* ptr, size_t N, size_t i) { const size_t N1 = (size_t)(N == 1); return ((float*)ptr)[14*N+3*N1+i]; } //!< Barycentric v coordinate of hit
|
||||
|
||||
RTCORE_FORCEINLINE unsigned& RTCRayN_geomID(RTCRayN* ptr, size_t N, size_t i) { const size_t N1 = (size_t)(N == 1); return ((unsigned*)ptr)[15*N+3*N1+i]; }; //!< geometry ID
|
||||
RTCORE_FORCEINLINE unsigned& RTCRayN_primID(RTCRayN* ptr, size_t N, size_t i) { const size_t N1 = (size_t)(N == 1); return ((unsigned*)ptr)[16*N+3*N1+i]; }; //!< primitive ID
|
||||
RTCORE_FORCEINLINE unsigned& RTCRayN_instID(RTCRayN* ptr, size_t N, size_t i) { const size_t N1 = (size_t)(N == 1); return ((unsigned*)ptr)[17*N+3*N1+i]; }; //!< instance ID
|
||||
RTCORE_FORCEINLINE unsigned& RTCRayN_geomID(RTCRayN* ptr, size_t N, size_t i) { const size_t N1 = (size_t)(N == 1); return ((unsigned*)ptr)[15*N+3*N1+i]; } //!< geometry ID
|
||||
RTCORE_FORCEINLINE unsigned& RTCRayN_primID(RTCRayN* ptr, size_t N, size_t i) { const size_t N1 = (size_t)(N == 1); return ((unsigned*)ptr)[16*N+3*N1+i]; } //!< primitive ID
|
||||
RTCORE_FORCEINLINE unsigned& RTCRayN_instID(RTCRayN* ptr, size_t N, size_t i) { const size_t N1 = (size_t)(N == 1); return ((unsigned*)ptr)[17*N+3*N1+i]; } //!< instance ID
|
||||
#endif
|
||||
|
||||
/* Helper structure to create a ray packet of compile time size N */
|
||||
@@ -272,17 +272,17 @@ public:
|
||||
#ifndef __RTCHitN__
|
||||
#define __RTCHitN__
|
||||
struct RTCHitN {};
|
||||
RTCORE_FORCEINLINE float& RTCHitN_Ng_x(const RTCHitN* ptr, size_t N, size_t i) { return ((float*)ptr)[0*N+i]; }; //!< x coordinate of geometry normal
|
||||
RTCORE_FORCEINLINE float& RTCHitN_Ng_y(const RTCHitN* ptr, size_t N, size_t i) { return ((float*)ptr)[1*N+i]; }; //!< y coordinate of geometry normal
|
||||
RTCORE_FORCEINLINE float& RTCHitN_Ng_z(const RTCHitN* ptr, size_t N, size_t i) { return ((float*)ptr)[2*N+i]; }; //!< z coordinate of geometry normal
|
||||
RTCORE_FORCEINLINE float& RTCHitN_Ng_x(const RTCHitN* ptr, size_t N, size_t i) { return ((float*)ptr)[0*N+i]; } //!< x coordinate of geometry normal
|
||||
RTCORE_FORCEINLINE float& RTCHitN_Ng_y(const RTCHitN* ptr, size_t N, size_t i) { return ((float*)ptr)[1*N+i]; } //!< y coordinate of geometry normal
|
||||
RTCORE_FORCEINLINE float& RTCHitN_Ng_z(const RTCHitN* ptr, size_t N, size_t i) { return ((float*)ptr)[2*N+i]; } //!< z coordinate of geometry normal
|
||||
|
||||
RTCORE_FORCEINLINE unsigned& RTCHitN_instID(const RTCHitN* ptr, size_t N, size_t i) { return ((unsigned*)ptr)[3*N+i]; }; //!< instance ID
|
||||
RTCORE_FORCEINLINE unsigned& RTCHitN_geomID(const RTCHitN* ptr, size_t N, size_t i) { return ((unsigned*)ptr)[4*N+i]; }; //!< geometry ID
|
||||
RTCORE_FORCEINLINE unsigned& RTCHitN_primID(const RTCHitN* ptr, size_t N, size_t i) { return ((unsigned*)ptr)[5*N+i]; }; //!< primitive ID
|
||||
RTCORE_FORCEINLINE unsigned& RTCHitN_instID(const RTCHitN* ptr, size_t N, size_t i) { return ((unsigned*)ptr)[3*N+i]; } //!< instance ID
|
||||
RTCORE_FORCEINLINE unsigned& RTCHitN_geomID(const RTCHitN* ptr, size_t N, size_t i) { return ((unsigned*)ptr)[4*N+i]; } //!< geometry ID
|
||||
RTCORE_FORCEINLINE unsigned& RTCHitN_primID(const RTCHitN* ptr, size_t N, size_t i) { return ((unsigned*)ptr)[5*N+i]; } //!< primitive ID
|
||||
|
||||
RTCORE_FORCEINLINE float& RTCHitN_u (const RTCHitN* ptr, size_t N, size_t i) { return ((float*)ptr)[6*N+i]; }; //!< Barycentric u coordinate of hit
|
||||
RTCORE_FORCEINLINE float& RTCHitN_v (const RTCHitN* ptr, size_t N, size_t i) { return ((float*)ptr)[7*N+i]; }; //!< Barycentric v coordinate of hit
|
||||
RTCORE_FORCEINLINE float& RTCHitN_t (const RTCHitN* ptr, size_t N, size_t i) { return ((float*)ptr)[8*N+i]; }; //!< hit distance
|
||||
RTCORE_FORCEINLINE float& RTCHitN_u (const RTCHitN* ptr, size_t N, size_t i) { return ((float*)ptr)[6*N+i]; } //!< Barycentric u coordinate of hit
|
||||
RTCORE_FORCEINLINE float& RTCHitN_v (const RTCHitN* ptr, size_t N, size_t i) { return ((float*)ptr)[7*N+i]; } //!< Barycentric v coordinate of hit
|
||||
RTCORE_FORCEINLINE float& RTCHitN_t (const RTCHitN* ptr, size_t N, size_t i) { return ((float*)ptr)[8*N+i]; } //!< hit distance
|
||||
#endif
|
||||
|
||||
/* Helper structure to create a hit packet of compile time size N */
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
// ======================================================================== //
|
||||
// Copyright 2009-2017 Intel Corporation //
|
||||
// //
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); //
|
||||
// you may not use this file except in compliance with the License. //
|
||||
// You may obtain a copy of the License at //
|
||||
// //
|
||||
// http://www.apache.org/licenses/LICENSE-2.0 //
|
||||
// //
|
||||
// Unless required by applicable law or agreed to in writing, software //
|
||||
// distributed under the License is distributed on an "AS IS" BASIS, //
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
|
||||
// See the License for the specific language governing permissions and //
|
||||
// limitations under the License. //
|
||||
// ======================================================================== //
|
||||
|
||||
#define RTCORE_VERSION_MAJOR 2
|
||||
#define RTCORE_VERSION_MINOR 17
|
||||
#define RTCORE_VERSION_PATCH 1
|
||||
#define RTCORE_VERSION 21701
|
||||
#define RTCORE_VERSION_STRING "2.17.1-alpha.0"
|
||||
+116
-149
@@ -14,6 +14,14 @@
|
||||
## limitations under the License. ##
|
||||
## ======================================================================== ##
|
||||
|
||||
MACRO(DISABLE_STACK_PROTECTOR_FOR_INTERSECTORS)
|
||||
FOREACH(src ${ARGN})
|
||||
IF (src MATCHES ".*intersector.*")
|
||||
DISABLE_STACK_PROTECTOR_FOR_FILE(${src})
|
||||
ENDIF()
|
||||
ENDFOREACH()
|
||||
ENDMACRO()
|
||||
|
||||
SOURCE_GROUP("Source Files\\bvh4" "/bvh4/" )
|
||||
SOURCE_GROUP("Source Files\\bvh8" "/bvh8/" )
|
||||
SOURCE_GROUP("Source Files\\geometry" "/geometry/" )
|
||||
@@ -51,7 +59,6 @@ SET(EMBREE_LIBRARY_FILES
|
||||
|
||||
geometry/primitive.cpp
|
||||
geometry/instance_intersector1.cpp
|
||||
geometry/instance_intersector.cpp
|
||||
builders/primrefgen.cpp
|
||||
|
||||
bvh/bvh.cpp
|
||||
@@ -63,6 +70,7 @@ SET(EMBREE_LIBRARY_FILES
|
||||
bvh/bvh_refit.cpp
|
||||
bvh/bvh_builder.cpp
|
||||
bvh/bvh_builder_hair.cpp
|
||||
bvh/bvh_builder_hair_mb.cpp
|
||||
bvh/bvh_builder_morton.cpp
|
||||
bvh/bvh_builder_sah.cpp
|
||||
bvh/bvh_builder_twolevel.cpp
|
||||
@@ -93,158 +101,93 @@ IF (EMBREE_RAY_PACKETS)
|
||||
bvh/bvh_intersector_stream_filters.cpp)
|
||||
ENDIF()
|
||||
|
||||
SET(EMBREE_LIBRARY_FILES_SSE42
|
||||
MACRO(embree_files TARGET ISA)
|
||||
|
||||
SET(${TARGET}
|
||||
geometry/instance_intersector1.cpp
|
||||
bvh/bvh_intersector1_bvh4.cpp)
|
||||
|
||||
IF (EMBREE_GEOMETRY_SUBDIV)
|
||||
SET(EMBREE_LIBRARY_FILES_SSE42 ${EMBREE_LIBRARY_FILES_SSE42}
|
||||
geometry/grid_soa.cpp
|
||||
subdiv/subdivpatch1base_eval.cpp)
|
||||
ENDIF()
|
||||
|
||||
IF (EMBREE_RAY_PACKETS)
|
||||
SET(EMBREE_LIBRARY_FILES_SSE42 ${EMBREE_LIBRARY_FILES_SSE42}
|
||||
bvh/bvh_intersector_hybrid4_bvh4.cpp
|
||||
bvh/bvh_intersector_stream_bvh4.cpp
|
||||
bvh/bvh_intersector_stream_filters.cpp)
|
||||
ENDIF()
|
||||
|
||||
SET(EMBREE_LIBRARY_FILES_AVX
|
||||
|
||||
geometry/instance_intersector1.cpp
|
||||
builders/primrefgen.cpp
|
||||
|
||||
bvh/bvh_rotate.cpp
|
||||
bvh/bvh_refit.cpp
|
||||
bvh/bvh_builder.cpp
|
||||
bvh/bvh_builder_hair.cpp
|
||||
bvh/bvh_builder_morton.cpp
|
||||
bvh/bvh_builder_sah.cpp
|
||||
bvh/bvh_builder_twolevel.cpp
|
||||
bvh/bvh_builder_instancing.cpp
|
||||
bvh/bvh_intersector1_bvh4.cpp
|
||||
bvh/bvh_intersector1_bvh8.cpp
|
||||
IF (${ISA} EQUAL ${SSE2} OR ${ISA} EQUAL ${AVX} OR ${ISA} EQUAL ${AVX512KNL} OR ${ISA_LOWEST} EQUAL ${ISA})
|
||||
|
||||
bvh/bvh.cpp
|
||||
bvh/bvh_statistics.cpp)
|
||||
LIST(APPEND ${TARGET}
|
||||
common/scene_triangle_mesh.cpp
|
||||
common/scene_quad_mesh.cpp
|
||||
common/scene_bezier_curves.cpp
|
||||
common/scene_line_segments.cpp
|
||||
|
||||
bvh/bvh_refit.cpp
|
||||
bvh/bvh_builder.cpp
|
||||
bvh/bvh_builder_hair.cpp
|
||||
bvh/bvh_builder_hair_mb.cpp
|
||||
bvh/bvh_builder_sah.cpp
|
||||
bvh/bvh_builder_twolevel.cpp
|
||||
bvh/bvh_builder_instancing.cpp)
|
||||
|
||||
IF (EMBREE_GEOMETRY_SUBDIV)
|
||||
SET(EMBREE_LIBRARY_FILES_AVX ${EMBREE_LIBRARY_FILES_AVX}
|
||||
geometry/grid_soa.cpp
|
||||
subdiv/subdivpatch1base_eval.cpp
|
||||
common/scene_subdiv_mesh_avx.cpp
|
||||
bvh/bvh_builder_subdiv.cpp)
|
||||
ENDIF()
|
||||
IF (EMBREE_GEOMETRY_SUBDIV)
|
||||
LIST(APPEND ${TARGET} bvh/bvh_builder_subdiv.cpp)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
IF (EMBREE_RAY_PACKETS)
|
||||
SET(EMBREE_LIBRARY_FILES_AVX ${EMBREE_LIBRARY_FILES_AVX}
|
||||
IF (${ISA} EQUAL ${SSE2} OR ${ISA} EQUAL ${AVX} OR ${ISA} EQUAL ${AVX2} OR ${ISA} EQUAL ${AVX512KNL} OR ${ISA_LOWEST} EQUAL ${ISA})
|
||||
LIST(APPEND ${TARGET}
|
||||
bvh/bvh_builder_morton.cpp
|
||||
bvh/bvh_rotate.cpp
|
||||
builders/primrefgen.cpp)
|
||||
ENDIF()
|
||||
|
||||
IF (${ISA} GREATER ${SSE42})
|
||||
LIST(APPEND ${TARGET} bvh/bvh_intersector1_bvh8.cpp)
|
||||
ENDIF()
|
||||
|
||||
geometry/instance_intersector.cpp
|
||||
IF (${ISA} EQUAL ${AVX})
|
||||
LIST(APPEND ${TARGET}
|
||||
bvh/bvh.cpp
|
||||
bvh/bvh_statistics.cpp)
|
||||
ENDIF()
|
||||
|
||||
bvh/bvh_intersector_hybrid4_bvh4.cpp
|
||||
bvh/bvh_intersector_hybrid8_bvh4.cpp
|
||||
bvh/bvh_intersector_hybrid4_bvh8.cpp
|
||||
bvh/bvh_intersector_hybrid8_bvh8.cpp
|
||||
bvh/bvh_intersector_stream_bvh4.cpp
|
||||
bvh/bvh_intersector_stream_bvh8.cpp
|
||||
bvh/bvh_intersector_stream_filters.cpp)
|
||||
ENDIF()
|
||||
IF (EMBREE_GEOMETRY_SUBDIV)
|
||||
LIST(APPEND ${TARGET}
|
||||
common/scene_subdiv_mesh.cpp
|
||||
geometry/grid_soa.cpp
|
||||
subdiv/subdivpatch1base_eval.cpp)
|
||||
ENDIF()
|
||||
|
||||
IF (EMBREE_RAY_PACKETS)
|
||||
LIST(APPEND ${TARGET}
|
||||
bvh/bvh_intersector_hybrid4_bvh4.cpp
|
||||
bvh/bvh_intersector_stream_bvh4.cpp
|
||||
bvh/bvh_intersector_stream_filters.cpp)
|
||||
|
||||
SET(EMBREE_LIBRARY_FILES_AVX2
|
||||
IF (${ISA} GREATER ${SSE42})
|
||||
LIST(APPEND ${TARGET}
|
||||
bvh/bvh_intersector_hybrid8_bvh4.cpp
|
||||
bvh/bvh_intersector_hybrid4_bvh8.cpp
|
||||
bvh/bvh_intersector_hybrid8_bvh8.cpp
|
||||
bvh/bvh_intersector_stream_bvh8.cpp)
|
||||
ENDIF()
|
||||
|
||||
geometry/instance_intersector1.cpp
|
||||
builders/primrefgen.cpp
|
||||
bvh/bvh_builder_morton.cpp
|
||||
bvh/bvh_rotate.cpp
|
||||
bvh/bvh_intersector1_bvh4.cpp
|
||||
bvh/bvh_intersector1_bvh8.cpp)
|
||||
IF (${ISA} GREATER ${AVX2})
|
||||
LIST(APPEND ${TARGET}
|
||||
bvh/bvh_intersector_hybrid16_bvh8.cpp
|
||||
bvh/bvh_intersector_hybrid16_bvh4.cpp)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
ENDMACRO()
|
||||
|
||||
IF (EMBREE_GEOMETRY_SUBDIV)
|
||||
SET(EMBREE_LIBRARY_FILES_AVX2 ${EMBREE_LIBRARY_FILES_AVX2}
|
||||
geometry/grid_soa.cpp
|
||||
subdiv/subdivpatch1base_eval.cpp)
|
||||
ENDIF()
|
||||
#embree_files(EMBREE_LIBRARY_FILES_SSE2 ${SSE2})
|
||||
embree_files(EMBREE_LIBRARY_FILES_SSE42 ${SSE42})
|
||||
embree_files(EMBREE_LIBRARY_FILES_AVX ${AVX})
|
||||
embree_files(EMBREE_LIBRARY_FILES_AVX2 ${AVX2})
|
||||
embree_files(EMBREE_LIBRARY_FILES_AVX512KNL ${AVX512KNL})
|
||||
embree_files(EMBREE_LIBRARY_FILES_AVX512SKX ${AVX512SKX})
|
||||
|
||||
IF (EMBREE_RAY_PACKETS)
|
||||
SET(EMBREE_LIBRARY_FILES_AVX2 ${EMBREE_LIBRARY_FILES_AVX2}
|
||||
geometry/instance_intersector.cpp
|
||||
|
||||
bvh/bvh_intersector_hybrid4_bvh4.cpp
|
||||
bvh/bvh_intersector_hybrid8_bvh4.cpp
|
||||
bvh/bvh_intersector_hybrid4_bvh8.cpp
|
||||
bvh/bvh_intersector_hybrid8_bvh8.cpp
|
||||
bvh/bvh_intersector_stream_bvh4.cpp
|
||||
bvh/bvh_intersector_stream_bvh8.cpp
|
||||
bvh/bvh_intersector_stream_filters.cpp)
|
||||
ENDIF()
|
||||
|
||||
SET(EMBREE_LIBRARY_FILES_AVX512KNL
|
||||
|
||||
geometry/instance_intersector1.cpp
|
||||
|
||||
bvh/bvh_refit.cpp
|
||||
bvh/bvh_rotate.cpp
|
||||
bvh/bvh_intersector1_bvh4.cpp
|
||||
bvh/bvh_intersector1_bvh8.cpp
|
||||
|
||||
builders/primrefgen.cpp
|
||||
bvh/bvh_builder.cpp
|
||||
bvh/bvh_builder_sah.cpp
|
||||
bvh/bvh_builder_twolevel.cpp
|
||||
bvh/bvh_builder_instancing.cpp
|
||||
bvh/bvh_builder_morton.cpp)
|
||||
|
||||
IF (EMBREE_GEOMETRY_SUBDIV)
|
||||
SET(EMBREE_LIBRARY_FILES_AVX512KNL ${EMBREE_LIBRARY_FILES_AVX512KNL}
|
||||
geometry/grid_soa.cpp
|
||||
subdiv/subdivpatch1base_eval.cpp
|
||||
bvh/bvh_builder_subdiv.cpp)
|
||||
ENDIF()
|
||||
|
||||
IF (EMBREE_RAY_PACKETS)
|
||||
SET(EMBREE_LIBRARY_FILES_AVX512KNL ${EMBREE_LIBRARY_FILES_AVX512KNL}
|
||||
|
||||
geometry/instance_intersector.cpp
|
||||
|
||||
bvh/bvh_intersector_hybrid4_bvh4.cpp
|
||||
bvh/bvh_intersector_hybrid8_bvh4.cpp
|
||||
bvh/bvh_intersector_hybrid16_bvh4.cpp
|
||||
bvh/bvh_intersector_hybrid4_bvh8.cpp
|
||||
bvh/bvh_intersector_hybrid8_bvh8.cpp
|
||||
bvh/bvh_intersector_hybrid16_bvh8.cpp
|
||||
bvh/bvh_intersector_stream_bvh4.cpp
|
||||
bvh/bvh_intersector_stream_bvh8.cpp
|
||||
bvh/bvh_intersector_stream_filters.cpp)
|
||||
ENDIF()
|
||||
|
||||
SET(EMBREE_LIBRARY_FILES_AVX512SKX
|
||||
|
||||
geometry/instance_intersector1.cpp
|
||||
|
||||
bvh/bvh_intersector1_bvh4.cpp
|
||||
bvh/bvh_intersector1_bvh8.cpp)
|
||||
|
||||
IF (EMBREE_GEOMETRY_SUBDIV)
|
||||
SET(EMBREE_LIBRARY_FILES_AVX512SKX ${EMBREE_LIBRARY_FILES_AVX512SKX}
|
||||
geometry/grid_soa.cpp
|
||||
subdiv/subdivpatch1base_eval.cpp)
|
||||
ENDIF()
|
||||
|
||||
IF (EMBREE_RAY_PACKETS)
|
||||
SET(EMBREE_LIBRARY_FILES_AVX512SKX ${EMBREE_LIBRARY_FILES_AVX512SKX}
|
||||
|
||||
geometry/instance_intersector.cpp
|
||||
|
||||
bvh/bvh_intersector_hybrid4_bvh4.cpp
|
||||
bvh/bvh_intersector_hybrid8_bvh4.cpp
|
||||
bvh/bvh_intersector_hybrid16_bvh4.cpp
|
||||
bvh/bvh_intersector_hybrid4_bvh8.cpp
|
||||
bvh/bvh_intersector_hybrid8_bvh8.cpp
|
||||
bvh/bvh_intersector_hybrid16_bvh8.cpp
|
||||
bvh/bvh_intersector_stream_bvh4.cpp
|
||||
bvh/bvh_intersector_stream_bvh8.cpp
|
||||
bvh/bvh_intersector_stream_filters.cpp)
|
||||
ENDIF()
|
||||
#message("SSE2: ${EMBREE_LIBRARY_FILES_SSE2}")
|
||||
#message("SSE42: ${EMBREE_LIBRARY_FILES_SSE42}")
|
||||
#message("AVX: ${EMBREE_LIBRARY_FILES_AVX}")
|
||||
#message("AVX2: ${EMBREE_LIBRARY_FILES_AVX2}")
|
||||
#message("AVX512KNL: ${EMBREE_LIBRARY_FILES_AVX512KNL}")
|
||||
#message("AVX512SKX: ${EMBREE_LIBRARY_FILES_AVX512SKX}")
|
||||
|
||||
# replaces all .cpp files with a dummy file that includes that .cpp file
|
||||
# this is to work around an ICC name mangling issue related to lambda functions under windows
|
||||
@@ -262,58 +205,82 @@ MACRO (CreateISADummyFiles list isa)
|
||||
DEPENDS ${src_file})
|
||||
ENDFOREACH()
|
||||
ENDMACRO()
|
||||
#CreateISADummyFiles(EMBREE_LIBRARY_FILES_SSE2 sse2 ${EMBREE_LIBRARY_FILES_SSE2})
|
||||
CreateISADummyFiles(EMBREE_LIBRARY_FILES_SSE42 sse42 ${EMBREE_LIBRARY_FILES_SSE42})
|
||||
CreateISADummyFiles(EMBREE_LIBRARY_FILES_AVX avx ${EMBREE_LIBRARY_FILES_AVX})
|
||||
CreateISADummyFiles(EMBREE_LIBRARY_FILES_AVX2 avx2 ${EMBREE_LIBRARY_FILES_AVX2})
|
||||
CreateISADummyFiles(EMBREE_LIBRARY_FILES_AVX512KNL avx512knl ${EMBREE_LIBRARY_FILES_AVX512KNL})
|
||||
CreateISADummyFiles(EMBREE_LIBRARY_FILES_AVX512SKX avx512skx ${EMBREE_LIBRARY_FILES_AVX512SKX})
|
||||
|
||||
MACRO (CheckGlobals library)
|
||||
IF (NOT WIN32 AND NOT APPLE)
|
||||
ADD_CUSTOM_TARGET(${library}_check_globals ALL COMMAND ${CMAKE_COMMAND} -D file=$<TARGET_FILE:${library}> -P ${PROJECT_SOURCE_DIR}/common/cmake/check_globals.cmake DEPENDS ${library})
|
||||
ENDIF()
|
||||
ENDMACRO()
|
||||
|
||||
DISABLE_STACK_PROTECTOR_FOR_INTERSECTORS(${EMBREE_LIBRARY_FILES})
|
||||
ADD_ISPC_LIBRARY(embree ${EMBREE_LIB_TYPE} ${EMBREE_LIBRARY_FILES} $<TARGET_OBJECTS:algorithms>)
|
||||
SET_TARGET_PROPERTIES(embree PROPERTIES COMPILE_FLAGS "${FLAGS_LOWEST}")
|
||||
SET_TARGET_PROPERTIES(embree PROPERTIES COMPILE_DEFINITIONS "EMBREE_LOWEST_ISA")
|
||||
SET_PROPERTY(TARGET embree PROPERTY FOLDER kernels)
|
||||
ADD_CUSTOM_TARGET(embree_check_stack_frame_size COMMAND ${CMAKE_COMMAND} -D file=$<TARGET_FILE:embree> -P ${PROJECT_SOURCE_DIR}/common/cmake/check_stack_frame_size.cmake DEPENDS embree)
|
||||
IF (NOT WIN32 AND NOT APPLE)
|
||||
ADD_CUSTOM_TARGET(embree_check_stack_frame_size COMMAND ${CMAKE_COMMAND} -D file=$<TARGET_FILE:embree> -P ${PROJECT_SOURCE_DIR}/common/cmake/check_stack_frame_size.cmake DEPENDS embree)
|
||||
ENDIF()
|
||||
|
||||
#IF (EMBREE_ISA_SSE2 AND EMBREE_LIBRARY_FILES_SSE2)
|
||||
# ADD_LIBRARY(embree_sse2 STATIC ${EMBREE_LIBRARY_FILES_SSE2})
|
||||
# SET_TARGET_PROPERTIES(embree_sse2 PROPERTIES COMPILE_FLAGS "${FLAGS_SSE2}")
|
||||
# SET_PROPERTY(TARGET embree_sse2 PROPERTY FOLDER kernels)
|
||||
# SET(EMBREE_LIBRARIES ${EMBREE_LIBRARIES} embree_sse2)
|
||||
# CheckGlobals(embree_sse2)
|
||||
#ENDIF ()
|
||||
|
||||
IF (EMBREE_ISA_SSE42 AND EMBREE_LIBRARY_FILES_SSE42)
|
||||
DISABLE_STACK_PROTECTOR_FOR_INTERSECTORS(${EMBREE_LIBRARY_FILES_SSE42})
|
||||
ADD_LIBRARY(embree_sse42 STATIC ${EMBREE_LIBRARY_FILES_SSE42})
|
||||
SET_TARGET_PROPERTIES(embree_sse42 PROPERTIES COMPILE_FLAGS "${FLAGS_SSE42}")
|
||||
SET_PROPERTY(TARGET embree_sse42 PROPERTY FOLDER kernels)
|
||||
SET(EMBREE_LIBRARIES ${EMBREE_LIBRARIES} embree_sse42)
|
||||
ADD_CUSTOM_TARGET(embree_sse42_check_globals ALL COMMAND ${CMAKE_COMMAND} -D file=$<TARGET_FILE:embree_sse42> -P ${PROJECT_SOURCE_DIR}/common/cmake/check_globals.cmake DEPENDS embree_sse42)
|
||||
CheckGlobals(embree_sse42)
|
||||
ENDIF ()
|
||||
|
||||
IF (EMBREE_ISA_AVX AND EMBREE_LIBRARY_FILES_AVX)
|
||||
DISABLE_STACK_PROTECTOR_FOR_INTERSECTORS(${EMBREE_LIBRARY_FILES_AVX})
|
||||
ADD_LIBRARY(embree_avx STATIC ${EMBREE_LIBRARY_FILES_AVX})
|
||||
SET_TARGET_PROPERTIES(embree_avx PROPERTIES COMPILE_FLAGS "${FLAGS_AVX}")
|
||||
SET_PROPERTY(TARGET embree_avx PROPERTY FOLDER kernels)
|
||||
SET(EMBREE_LIBRARIES ${EMBREE_LIBRARIES} embree_avx)
|
||||
ADD_CUSTOM_TARGET(embree_avx_check_globals ALL COMMAND ${CMAKE_COMMAND} -D file=$<TARGET_FILE:embree_avx> -P ${PROJECT_SOURCE_DIR}/common/cmake/check_globals.cmake DEPENDS embree_avx)
|
||||
CheckGlobals(embree_avx)
|
||||
ENDIF()
|
||||
|
||||
IF (EMBREE_ISA_AVX2 AND EMBREE_LIBRARY_FILES_AVX2)
|
||||
DISABLE_STACK_PROTECTOR_FOR_INTERSECTORS(${EMBREE_LIBRARY_FILES_AVX2})
|
||||
ADD_LIBRARY(embree_avx2 STATIC ${EMBREE_LIBRARY_FILES_AVX2})
|
||||
SET_TARGET_PROPERTIES(embree_avx2 PROPERTIES COMPILE_FLAGS "${FLAGS_AVX2}")
|
||||
SET_PROPERTY(TARGET embree_avx2 PROPERTY FOLDER kernels)
|
||||
SET(EMBREE_LIBRARIES ${EMBREE_LIBRARIES} embree_avx2)
|
||||
ADD_CUSTOM_TARGET(embree_avx2_check_globals ALL COMMAND ${CMAKE_COMMAND} -D file=$<TARGET_FILE:embree_avx2> -P ${PROJECT_SOURCE_DIR}/common/cmake/check_globals.cmake DEPENDS embree_avx2)
|
||||
CheckGlobals(embree_avx2)
|
||||
ENDIF()
|
||||
|
||||
IF (EMBREE_ISA_AVX512KNL AND EMBREE_LIBRARY_FILES_AVX512KNL)
|
||||
DISABLE_STACK_PROTECTOR_FOR_INTERSECTORS(${EMBREE_LIBRARY_FILES_AVX512KNL})
|
||||
ADD_LIBRARY(embree_avx512knl STATIC ${EMBREE_LIBRARY_FILES_AVX512KNL})
|
||||
SET_TARGET_PROPERTIES(embree_avx512knl PROPERTIES COMPILE_FLAGS "${FLAGS_AVX512KNL}")
|
||||
SET_PROPERTY(TARGET embree_avx512knl PROPERTY FOLDER kernels)
|
||||
SET(EMBREE_LIBRARIES ${EMBREE_LIBRARIES} embree_avx512knl)
|
||||
ADD_CUSTOM_TARGET(embree_avx512knl_check_globals ALL COMMAND ${CMAKE_COMMAND} -D file=$<TARGET_FILE:embree_avx512knl> -P ${PROJECT_SOURCE_DIR}/common/cmake/check_globals.cmake DEPENDS embree_avx512knl)
|
||||
CheckGlobals(embree_avx512knl)
|
||||
ENDIF()
|
||||
|
||||
IF (EMBREE_ISA_AVX512SKX AND EMBREE_LIBRARY_FILES_AVX512SKX)
|
||||
DISABLE_STACK_PROTECTOR_FOR_INTERSECTORS(${EMBREE_LIBRARY_FILES_AVX512SKX})
|
||||
ADD_LIBRARY(embree_avx512skx STATIC ${EMBREE_LIBRARY_FILES_AVX512SKX})
|
||||
SET_TARGET_PROPERTIES(embree_avx512skx PROPERTIES COMPILE_FLAGS "${FLAGS_AVX512SKX}")
|
||||
SET_PROPERTY(TARGET embree_avx512skx PROPERTY FOLDER kernels)
|
||||
SET(EMBREE_LIBRARIES ${EMBREE_LIBRARIES} embree_avx512skx)
|
||||
ADD_CUSTOM_TARGET(embree_avx512skx_check_globals ALL COMMAND ${CMAKE_COMMAND} -D file=$<TARGET_FILE:embree_avx512skx> -P ${PROJECT_SOURCE_DIR}/common/cmake/check_globals.cmake DEPENDS embree_avx512skx)
|
||||
CheckGlobals(embree_avx512skx)
|
||||
ENDIF()
|
||||
|
||||
TARGET_LINK_LIBRARIES(embree ${EMBREE_LIBRARIES} sys simd lexers tasking)
|
||||
TARGET_LINK_LIBRARIES(embree ${EMBREE_LIBRARIES} sys math simd lexers tasking)
|
||||
SET_TARGET_PROPERTIES(embree PROPERTIES INSTALL_RPATH "") # no RPATH for installed libembree
|
||||
|
||||
IF (WIN32)
|
||||
|
||||
@@ -55,7 +55,7 @@ namespace embree
|
||||
typename CreateLeafFunc,
|
||||
typename ProgressMonitor>
|
||||
|
||||
class BuilderT : private Settings
|
||||
class BuilderT
|
||||
{
|
||||
ALIGNED_CLASS;
|
||||
friend struct BVHBuilderHair;
|
||||
@@ -84,7 +84,8 @@ namespace embree
|
||||
const ProgressMonitor& progressMonitor,
|
||||
const Settings settings)
|
||||
|
||||
: Settings(settings),
|
||||
: cfg(settings),
|
||||
prims(prims),
|
||||
createAlloc(createAlloc),
|
||||
createAlignedNode(createAlignedNode),
|
||||
setAlignedNode(setAlignedNode),
|
||||
@@ -98,12 +99,12 @@ namespace embree
|
||||
NodeRef createLargeLeaf(size_t depth, const PrimInfoRange& pinfo, Allocator alloc)
|
||||
{
|
||||
/* this should never occur but is a fatal error */
|
||||
if (depth > maxDepth)
|
||||
if (depth > cfg.maxDepth)
|
||||
throw_RTCError(RTC_UNKNOWN_ERROR,"depth limit reached");
|
||||
|
||||
/* create leaf for few primitives */
|
||||
if (pinfo.size() <= maxLeafSize)
|
||||
return createLeaf(depth,pinfo,alloc);
|
||||
if (pinfo.size() <= cfg.maxLeafSize)
|
||||
return createLeaf(prims,pinfo,alloc);
|
||||
|
||||
/* fill all children by always splitting the largest one */
|
||||
PrimInfoRange children[MAX_BRANCHING_FACTOR];
|
||||
@@ -118,7 +119,7 @@ namespace embree
|
||||
for (unsigned i=0; i<numChildren; i++)
|
||||
{
|
||||
/* ignore leaves as they cannot get split */
|
||||
if (children[i].size() <= maxLeafSize)
|
||||
if (children[i].size() <= cfg.maxLeafSize)
|
||||
continue;
|
||||
|
||||
/* remember child with largest size */
|
||||
@@ -139,7 +140,7 @@ namespace embree
|
||||
children[numChildren+0] = right;
|
||||
numChildren++;
|
||||
|
||||
} while (numChildren < branchingFactor);
|
||||
} while (numChildren < cfg.branchingFactor);
|
||||
|
||||
/* create node */
|
||||
auto node = createAlignedNode(alloc);
|
||||
@@ -232,7 +233,7 @@ namespace embree
|
||||
PrimInfoRange children[MAX_BRANCHING_FACTOR];
|
||||
|
||||
/* create leaf node */
|
||||
if (depth+MIN_LARGE_LEAF_LEVELS >= maxDepth || pinfo.size() <= minLeafSize) {
|
||||
if (depth+MIN_LARGE_LEAF_LEVELS >= cfg.maxDepth || pinfo.size() <= cfg.minLeafSize) {
|
||||
alignedHeuristic.deterministic_order(pinfo);
|
||||
return createLargeLeaf(depth,pinfo,alloc);
|
||||
}
|
||||
@@ -250,7 +251,7 @@ namespace embree
|
||||
for (size_t i=0; i<numChildren; i++)
|
||||
{
|
||||
/* ignore leaves as they cannot get split */
|
||||
if (children[i].size() <= minLeafSize)
|
||||
if (children[i].size() <= cfg.minLeafSize)
|
||||
continue;
|
||||
|
||||
/* remember child with largest area */
|
||||
@@ -271,7 +272,7 @@ namespace embree
|
||||
children[numChildren+0] = right;
|
||||
numChildren++;
|
||||
|
||||
} while (numChildren < branchingFactor);
|
||||
} while (numChildren < cfg.branchingFactor);
|
||||
|
||||
/* create aligned node */
|
||||
if (aligned)
|
||||
@@ -329,6 +330,8 @@ namespace embree
|
||||
}
|
||||
|
||||
private:
|
||||
Settings cfg;
|
||||
PrimRef* prims;
|
||||
const CreateAllocFunc& createAlloc;
|
||||
const CreateAlignedNodeFunc& createAlignedNode;
|
||||
const SetAlignedNodeFunc& setAlignedNode;
|
||||
|
||||
@@ -127,18 +127,19 @@ namespace embree
|
||||
const Mesh* mesh = scene->get<Mesh>(geomID);
|
||||
const LBBox3fa lbounds = mesh->linearBounds(primID, time_range);
|
||||
const unsigned num_time_segments = mesh->numTimeSegments();
|
||||
const range<int> tbounds = getTimeSegmentRange(time_range, num_time_segments);
|
||||
const range<int> tbounds = getTimeSegmentRange(time_range, (float)num_time_segments);
|
||||
return PrimRefMB (lbounds, tbounds.size(), num_time_segments, geomID, primID);
|
||||
}
|
||||
|
||||
__forceinline PrimRefMB operator() (const PrimRefMB& prim, const BBox1f time_range, const LinearSpace3fa& space) const
|
||||
// __noinline is workaround for ICC16 bug under MacOSX
|
||||
__noinline PrimRefMB operator() (const PrimRefMB& prim, const BBox1f time_range, const LinearSpace3fa& space) const
|
||||
{
|
||||
const unsigned geomID = prim.geomID();
|
||||
const unsigned primID = prim.primID();
|
||||
const Mesh* mesh = scene->get<Mesh>(geomID);
|
||||
const LBBox3fa lbounds = mesh->linearBounds(space, primID, time_range);
|
||||
const unsigned num_time_segments = mesh->numTimeSegments();
|
||||
const range<int> tbounds = getTimeSegmentRange(time_range, num_time_segments);
|
||||
const range<int> tbounds = getTimeSegmentRange(time_range, (float)num_time_segments);
|
||||
return PrimRefMB (lbounds, tbounds.size(), num_time_segments, geomID, primID);
|
||||
}
|
||||
|
||||
@@ -146,7 +147,8 @@ namespace embree
|
||||
return scene->get<Mesh>(prim.geomID())->linearBounds(prim.primID(), time_range);
|
||||
}
|
||||
|
||||
__forceinline LBBox3fa linearBounds(const PrimRefMB& prim, const BBox1f time_range, const LinearSpace3fa& space) const {
|
||||
// __noinline is workaround for ICC16 bug under MacOSX
|
||||
__noinline LBBox3fa linearBounds(const PrimRefMB& prim, const BBox1f time_range, const LinearSpace3fa& space) const {
|
||||
return scene->get<Mesh>(prim.geomID())->linearBounds(space, prim.primID(), time_range);
|
||||
}
|
||||
};
|
||||
@@ -182,8 +184,8 @@ namespace embree
|
||||
__forceinline BuildRecord (size_t depth)
|
||||
: depth(depth) {}
|
||||
|
||||
__forceinline BuildRecord (const SetMB& prims, const BinSplit<MBLUR_NUM_OBJECT_BINS>& split, size_t depth)
|
||||
: depth(depth), prims(prims), split(split) {}
|
||||
__forceinline BuildRecord (const SetMB& prims, size_t depth)
|
||||
: depth(depth), prims(prims) {}
|
||||
|
||||
__forceinline friend bool operator< (const BuildRecord& a, const BuildRecord& b) {
|
||||
return a.prims.size() < b.prims.size();
|
||||
@@ -196,7 +198,19 @@ namespace embree
|
||||
public:
|
||||
size_t depth; //!< Depth of the root of this subtree.
|
||||
SetMB prims; //!< The list of primitives.
|
||||
BinSplit<MBLUR_NUM_OBJECT_BINS> split; //!< The best split for the primitives.
|
||||
};
|
||||
|
||||
struct BuildRecordSplit : public BuildRecord
|
||||
{
|
||||
__forceinline BuildRecordSplit () {}
|
||||
|
||||
__forceinline BuildRecordSplit (size_t depth)
|
||||
: BuildRecord(depth) {}
|
||||
|
||||
__forceinline BuildRecordSplit (const BuildRecord& record, const BinSplit<MBLUR_NUM_OBJECT_BINS>& split)
|
||||
: BuildRecord(record), split(split) {}
|
||||
|
||||
BinSplit<MBLUR_NUM_OBJECT_BINS> split;
|
||||
};
|
||||
|
||||
template<
|
||||
@@ -209,18 +223,18 @@ namespace embree
|
||||
typename CreateLeafFunc,
|
||||
typename ProgressMonitor>
|
||||
|
||||
class BuilderT : private Settings
|
||||
class BuilderT
|
||||
{
|
||||
ALIGNED_CLASS;
|
||||
static const size_t MAX_BRANCHING_FACTOR = 8; //!< maximal supported BVH branching factor
|
||||
static const size_t MIN_LARGE_LEAF_LEVELS = 8; //!< create balanced tree if we are that many levels before the maximal tree depth
|
||||
|
||||
typedef BVHNodeRecordMB4D<NodeRef> NodeRecordMB4D;
|
||||
|
||||
typedef BinSplit<MBLUR_NUM_OBJECT_BINS> Split;
|
||||
typedef mvector<PrimRefMB>* PrimRefVector;
|
||||
typedef SharedVector<mvector<PrimRefMB>> SharedPrimRefVector;
|
||||
typedef LocalChildListT<BuildRecord,MAX_BRANCHING_FACTOR> LocalChildList;
|
||||
typedef LocalChildListT<BuildRecordSplit,MAX_BRANCHING_FACTOR> LocalChildListSplit;
|
||||
|
||||
public:
|
||||
|
||||
@@ -232,13 +246,13 @@ namespace embree
|
||||
const CreateLeafFunc createLeaf,
|
||||
const ProgressMonitor progressMonitor,
|
||||
const Settings& settings)
|
||||
: Settings(settings),
|
||||
: cfg(settings),
|
||||
heuristicObjectSplit(),
|
||||
heuristicTemporalSplit(device, recalculatePrimRef),
|
||||
recalculatePrimRef(recalculatePrimRef), createAlloc(createAlloc), createNode(createNode), setNode(setNode), createLeaf(createLeaf),
|
||||
progressMonitor(progressMonitor)
|
||||
{
|
||||
if (branchingFactor > MAX_BRANCHING_FACTOR)
|
||||
if (cfg.branchingFactor > MAX_BRANCHING_FACTOR)
|
||||
throw_RTCError(RTC_UNKNOWN_ERROR,"bvh_builder: branching factor too large");
|
||||
}
|
||||
|
||||
@@ -246,18 +260,18 @@ namespace embree
|
||||
const Split find(const SetMB& set)
|
||||
{
|
||||
/* first try standard object split */
|
||||
const Split object_split = heuristicObjectSplit.find(set,logBlockSize);
|
||||
const Split object_split = heuristicObjectSplit.find(set,cfg.logBlockSize);
|
||||
const float object_split_sah = object_split.splitSAH();
|
||||
|
||||
/* test temporal splits only when object split was bad */
|
||||
const float leaf_sah = set.leafSAH(logBlockSize);
|
||||
const float leaf_sah = set.leafSAH(cfg.logBlockSize);
|
||||
if (object_split_sah < 0.50f*leaf_sah)
|
||||
return object_split;
|
||||
|
||||
/* do temporal splits only if the the time range is big enough */
|
||||
if (set.time_range.size() > 1.01f/float(set.max_num_time_segments))
|
||||
{
|
||||
const Split temporal_split = heuristicTemporalSplit.find(set,logBlockSize);
|
||||
const Split temporal_split = heuristicTemporalSplit.find(set,cfg.logBlockSize);
|
||||
const float temporal_split_sah = temporal_split.splitSAH();
|
||||
|
||||
/* take temporal split if it improved SAH */
|
||||
@@ -269,20 +283,20 @@ namespace embree
|
||||
}
|
||||
|
||||
/*! array partitioning */
|
||||
__forceinline std::unique_ptr<mvector<PrimRefMB>> split(const BuildRecord& brecord, BuildRecord& lrecord, BuildRecord& rrecord)
|
||||
__forceinline std::unique_ptr<mvector<PrimRefMB>> split(const Split& split, const SetMB& set, SetMB& lset, SetMB& rset)
|
||||
{
|
||||
/* perform object split */
|
||||
if (likely(brecord.split.data == Split::SPLIT_OBJECT)) {
|
||||
heuristicObjectSplit.split(brecord.split,brecord.prims,lrecord.prims,rrecord.prims);
|
||||
if (likely(split.data == Split::SPLIT_OBJECT)) {
|
||||
heuristicObjectSplit.split(split,set,lset,rset);
|
||||
}
|
||||
/* perform temporal split */
|
||||
else if (likely(brecord.split.data == Split::SPLIT_TEMPORAL)) {
|
||||
return heuristicTemporalSplit.split(brecord.split,brecord.prims,lrecord.prims,rrecord.prims);
|
||||
else if (likely(split.data == Split::SPLIT_TEMPORAL)) {
|
||||
return heuristicTemporalSplit.split(split,set,lset,rset);
|
||||
}
|
||||
/* perform fallback split */
|
||||
else if (unlikely(brecord.split.data == Split::SPLIT_FALLBACK)) {
|
||||
brecord.prims.deterministic_order();
|
||||
splitFallback(brecord.prims,lrecord.prims,rrecord.prims);
|
||||
else if (unlikely(split.data == Split::SPLIT_FALLBACK)) {
|
||||
set.deterministic_order();
|
||||
splitFallback(set,lset,rset);
|
||||
}
|
||||
else
|
||||
assert(false);
|
||||
@@ -291,16 +305,16 @@ namespace embree
|
||||
}
|
||||
|
||||
/*! finds the best fallback split */
|
||||
__forceinline Split findFallback(const SetMB& set)
|
||||
__noinline Split findFallback(const SetMB& set)
|
||||
{
|
||||
/* if a leaf can only hold a single time-segment, we might have to do additional temporal splits */
|
||||
if (singleLeafTimeSegment)
|
||||
if (cfg.singleLeafTimeSegment)
|
||||
{
|
||||
/* test if one primitive has more than one time segment in time range, if so split time */
|
||||
for (size_t i=set.object_range.begin(); i<set.object_range.end(); i++)
|
||||
{
|
||||
const PrimRefMB& prim = (*set.prims)[i];
|
||||
const range<int> itime_range = getTimeSegmentRange(set.time_range,prim.totalTimeSegments());
|
||||
const range<int> itime_range = getTimeSegmentRange(set.time_range,(float)prim.totalTimeSegments());
|
||||
const int localTimeSegments = itime_range.size();
|
||||
assert(localTimeSegments > 0);
|
||||
if (localTimeSegments > 1) {
|
||||
@@ -339,20 +353,20 @@ namespace embree
|
||||
const NodeRecordMB4D createLargeLeaf(const BuildRecord& in, Allocator alloc)
|
||||
{
|
||||
/* this should never occur but is a fatal error */
|
||||
if (in.depth > maxDepth)
|
||||
if (in.depth > cfg.maxDepth)
|
||||
throw_RTCError(RTC_UNKNOWN_ERROR,"depth limit reached");
|
||||
|
||||
/* replace already found split by fallback split */
|
||||
const BuildRecord current(in.prims,findFallback(in.prims),in.depth);
|
||||
const BuildRecordSplit current(BuildRecord(in.prims,in.depth),findFallback(in.prims));
|
||||
|
||||
/* create leaf for few primitives */
|
||||
if (current.size() <= maxLeafSize && current.split.data != Split::SPLIT_TEMPORAL)
|
||||
if (current.size() <= cfg.maxLeafSize && current.split.data != Split::SPLIT_TEMPORAL)
|
||||
return createLeaf(current,alloc);
|
||||
|
||||
/* fill all children by always splitting the largest one */
|
||||
bool hasTimeSplits = false;
|
||||
NodeRecordMB4D values[MAX_BRANCHING_FACTOR];
|
||||
LocalChildList children(current);
|
||||
LocalChildListSplit children(current);
|
||||
|
||||
do {
|
||||
/* find best child with largest bounding box area */
|
||||
@@ -361,7 +375,7 @@ namespace embree
|
||||
for (size_t i=0; i<children.size(); i++)
|
||||
{
|
||||
/* ignore leaves as they cannot get split */
|
||||
if (children[i].size() <= maxLeafSize && children[i].split.data != Split::SPLIT_TEMPORAL)
|
||||
if (children[i].size() <= cfg.maxLeafSize && children[i].split.data != Split::SPLIT_TEMPORAL)
|
||||
continue;
|
||||
|
||||
/* remember child with largest size */
|
||||
@@ -373,10 +387,10 @@ namespace embree
|
||||
if (bestChild == -1) break;
|
||||
|
||||
/* perform best found split */
|
||||
BuildRecord& brecord = children[bestChild];
|
||||
BuildRecord lrecord(current.depth+1);
|
||||
BuildRecord rrecord(current.depth+1);
|
||||
std::unique_ptr<mvector<PrimRefMB>> new_vector = split(brecord,lrecord,rrecord);
|
||||
BuildRecordSplit& brecord = children[bestChild];
|
||||
BuildRecordSplit lrecord(current.depth+1);
|
||||
BuildRecordSplit rrecord(current.depth+1);
|
||||
std::unique_ptr<mvector<PrimRefMB>> new_vector = split(brecord.split,brecord.prims,lrecord.prims,rrecord.prims);
|
||||
hasTimeSplits |= new_vector != nullptr;
|
||||
|
||||
/* find new splits */
|
||||
@@ -384,7 +398,7 @@ namespace embree
|
||||
rrecord.split = findFallback(rrecord.prims);
|
||||
children.split(bestChild,lrecord,rrecord,std::move(new_vector));
|
||||
|
||||
} while (children.size() < branchingFactor);
|
||||
} while (children.size() < cfg.branchingFactor);
|
||||
|
||||
/* create node */
|
||||
auto node = createNode(alloc, hasTimeSplits);
|
||||
@@ -411,52 +425,59 @@ namespace embree
|
||||
alloc = createAlloc();
|
||||
|
||||
/* call memory monitor function to signal progress */
|
||||
if (toplevel && current.size() <= singleThreadThreshold)
|
||||
if (toplevel && current.size() <= cfg.singleThreadThreshold)
|
||||
progressMonitor(current.size());
|
||||
|
||||
/*! find best split */
|
||||
const Split csplit = find(current.prims);
|
||||
|
||||
/*! compute leaf and split cost */
|
||||
const float leafSAH = intCost*current.prims.leafSAH(logBlockSize);
|
||||
const float splitSAH = travCost*current.prims.halfArea()+intCost*current.split.splitSAH();
|
||||
const float leafSAH = cfg.intCost*current.prims.leafSAH(cfg.logBlockSize);
|
||||
const float splitSAH = cfg.travCost*current.prims.halfArea()+cfg.intCost*csplit.splitSAH();
|
||||
assert((current.size() == 0) || ((leafSAH >= 0) && (splitSAH >= 0)));
|
||||
|
||||
/*! create a leaf node when threshold reached or SAH tells us to stop */
|
||||
if (current.size() <= minLeafSize || current.depth+MIN_LARGE_LEAF_LEVELS >= maxDepth || (current.size() <= maxLeafSize && leafSAH <= splitSAH)) {
|
||||
if (current.size() <= cfg.minLeafSize || current.depth+MIN_LARGE_LEAF_LEVELS >= cfg.maxDepth || (current.size() <= cfg.maxLeafSize && leafSAH <= splitSAH)) {
|
||||
current.prims.deterministic_order();
|
||||
return createLargeLeaf(current,alloc);
|
||||
}
|
||||
|
||||
/*! initialize child list */
|
||||
bool hasTimeSplits = false;
|
||||
/*! perform initial split */
|
||||
SetMB lprims,rprims;
|
||||
std::unique_ptr<mvector<PrimRefMB>> new_vector = split(csplit,current.prims,lprims,rprims);
|
||||
bool hasTimeSplits = new_vector != nullptr;
|
||||
NodeRecordMB4D values[MAX_BRANCHING_FACTOR];
|
||||
LocalChildList children(current);
|
||||
{
|
||||
BuildRecord lrecord(lprims,current.depth+1);
|
||||
BuildRecord rrecord(rprims,current.depth+1);
|
||||
children.split(0,lrecord,rrecord,std::move(new_vector));
|
||||
}
|
||||
|
||||
/*! split until node is full or SAH tells us to stop */
|
||||
do {
|
||||
while (children.size() < cfg.branchingFactor)
|
||||
{
|
||||
/*! find best child to split */
|
||||
float bestArea = neg_inf;
|
||||
ssize_t bestChild = -1;
|
||||
for (size_t i=0; i<children.size(); i++)
|
||||
{
|
||||
if (children[i].size() <= minLeafSize) continue;
|
||||
if (children[i].size() <= cfg.minLeafSize) continue;
|
||||
if (expectedApproxHalfArea(children[i].prims.geomBounds) > bestArea) {
|
||||
bestChild = i; bestArea = expectedApproxHalfArea(children[i].prims.geomBounds);
|
||||
}
|
||||
}
|
||||
if (bestChild == -1) break;
|
||||
|
||||
/* perform best found split */
|
||||
/* perform split */
|
||||
BuildRecord& brecord = children[bestChild];
|
||||
BuildRecord lrecord(current.depth+1);
|
||||
BuildRecord rrecord(current.depth+1);
|
||||
std::unique_ptr<mvector<PrimRefMB>> new_vector = split(brecord,lrecord,rrecord);
|
||||
Split csplit = find(brecord.prims);
|
||||
std::unique_ptr<mvector<PrimRefMB>> new_vector = split(csplit,brecord.prims,lrecord.prims,rrecord.prims);
|
||||
hasTimeSplits |= new_vector != nullptr;
|
||||
|
||||
/* find new splits */
|
||||
lrecord.split = find(lrecord.prims);
|
||||
rrecord.split = find(rrecord.prims);
|
||||
children.split(bestChild,lrecord,rrecord,std::move(new_vector));
|
||||
|
||||
} while (children.size() < branchingFactor);
|
||||
}
|
||||
|
||||
/* sort buildrecords for simpler shadow ray traversal */
|
||||
//std::sort(&children[0],&children[children.size()],std::greater<BuildRecord>()); // FIXME: reduces traversal performance of bvh8.triangle4 (need to verified) !!
|
||||
@@ -466,7 +487,7 @@ namespace embree
|
||||
LBBox3fa gbounds = empty;
|
||||
|
||||
/* spawn tasks */
|
||||
if (unlikely(current.size() > singleThreadThreshold))
|
||||
if (unlikely(current.size() > cfg.singleThreadThreshold))
|
||||
{
|
||||
/*! parallel_for is faster than spawing sub-tasks */
|
||||
parallel_for(size_t(0), children.size(), [&] (const range<size_t>& r) {
|
||||
@@ -503,12 +524,13 @@ namespace embree
|
||||
__forceinline const NodeRecordMB4D operator() (mvector<PrimRefMB>& prims, const PrimInfoMB& pinfo)
|
||||
{
|
||||
const SetMB set(pinfo,&prims);
|
||||
auto ret = recurse(BuildRecord(set,find(set),1),nullptr,true);
|
||||
auto ret = recurse(BuildRecord(set,1),nullptr,true);
|
||||
_mm_mfence(); // to allow non-temporal stores during build
|
||||
return ret;
|
||||
}
|
||||
|
||||
private:
|
||||
Settings cfg;
|
||||
HeuristicArrayBinningMB<PrimRefMB,MBLUR_NUM_OBJECT_BINS> heuristicObjectSplit;
|
||||
HeuristicMBlurTemporalSplit<PrimRefMB,RecalculatePrimRef,MBLUR_NUM_TEMPORAL_BINS> heuristicTemporalSplit;
|
||||
const RecalculatePrimRef recalculatePrimRef;
|
||||
|
||||
@@ -67,16 +67,14 @@ namespace embree
|
||||
template<typename NodeRef,
|
||||
typename RecalculatePrimRef,
|
||||
typename CreateAllocFunc,
|
||||
typename CreateAlignedNodeFunc,
|
||||
typename SetAlignedNodeFunc,
|
||||
typename CreateUnalignedNodeFunc,
|
||||
typename SetUnalignedNodeFunc,
|
||||
typename CreateAlignedNode4DFunc,
|
||||
typename SetAlignedNode4DFunc,
|
||||
typename CreateAlignedNodeMBFunc,
|
||||
typename SetAlignedNodeMBFunc,
|
||||
typename CreateUnalignedNodeMBFunc,
|
||||
typename SetUnalignedNodeMBFunc,
|
||||
typename CreateLeafFunc,
|
||||
typename ProgressMonitor>
|
||||
|
||||
class BuilderT : private Settings
|
||||
class BuilderT
|
||||
{
|
||||
ALIGNED_CLASS;
|
||||
|
||||
@@ -99,23 +97,20 @@ namespace embree
|
||||
BuilderT (Scene* scene,
|
||||
const RecalculatePrimRef& recalculatePrimRef,
|
||||
const CreateAllocFunc& createAlloc,
|
||||
const CreateAlignedNodeFunc& createAlignedNode,
|
||||
const SetAlignedNodeFunc& setAlignedNode,
|
||||
const CreateUnalignedNodeFunc& createUnalignedNode,
|
||||
const SetUnalignedNodeFunc& setUnalignedNode,
|
||||
const CreateAlignedNode4DFunc& createAlignedNode4D,
|
||||
const SetAlignedNode4DFunc& setAlignedNode4D,
|
||||
const CreateAlignedNodeMBFunc& createAlignedNodeMB,
|
||||
const SetAlignedNodeMBFunc& setAlignedNodeMB,
|
||||
const CreateUnalignedNodeMBFunc& createUnalignedNodeMB,
|
||||
const SetUnalignedNodeMBFunc& setUnalignedNodeMB,
|
||||
const CreateLeafFunc& createLeaf,
|
||||
const ProgressMonitor& progressMonitor,
|
||||
const Settings settings)
|
||||
|
||||
: Settings(settings),
|
||||
: cfg(settings),
|
||||
scene(scene),
|
||||
recalculatePrimRef(recalculatePrimRef),
|
||||
createAlloc(createAlloc),
|
||||
createAlignedNode(createAlignedNode), setAlignedNode(setAlignedNode),
|
||||
createUnalignedNode(createUnalignedNode), setUnalignedNode(setUnalignedNode),
|
||||
createAlignedNode4D(createAlignedNode4D), setAlignedNode4D(setAlignedNode4D),
|
||||
createAlignedNodeMB(createAlignedNodeMB), setAlignedNodeMB(setAlignedNodeMB),
|
||||
createUnalignedNodeMB(createUnalignedNodeMB), setUnalignedNodeMB(setUnalignedNodeMB),
|
||||
createLeaf(createLeaf),
|
||||
progressMonitor(progressMonitor),
|
||||
unalignedHeuristic(scene),
|
||||
@@ -145,14 +140,14 @@ namespace embree
|
||||
}
|
||||
|
||||
/*! creates a large leaf that could be larger than supported by the BVH */
|
||||
NodeRecordMB createLargeLeaf(BuildRecord& current, Allocator alloc)
|
||||
NodeRecordMB4D createLargeLeaf(BuildRecord& current, Allocator alloc)
|
||||
{
|
||||
/* this should never occur but is a fatal error */
|
||||
if (current.depth > maxDepth)
|
||||
if (current.depth > cfg.maxDepth)
|
||||
throw_RTCError(RTC_UNKNOWN_ERROR,"depth limit reached");
|
||||
|
||||
/* create leaf for few primitives */
|
||||
if (current.size() <= maxLeafSize)
|
||||
if (current.size() <= cfg.maxLeafSize)
|
||||
return createLeaf(current.prims,alloc);
|
||||
|
||||
/* fill all children by always splitting the largest one */
|
||||
@@ -166,7 +161,7 @@ namespace embree
|
||||
for (unsigned i=0; i<children.size(); i++)
|
||||
{
|
||||
/* ignore leaves as they cannot get split */
|
||||
if (children[i].size() <= maxLeafSize)
|
||||
if (children[i].size() <= cfg.maxLeafSize)
|
||||
continue;
|
||||
|
||||
/* remember child with largest size */
|
||||
@@ -183,19 +178,19 @@ namespace embree
|
||||
splitFallback(children[bestChild].prims,left.prims,right.prims);
|
||||
children.split(bestChild,left,right,std::unique_ptr<mvector<PrimRefMB>>());
|
||||
|
||||
} while (children.size() < branchingFactor);
|
||||
} while (children.size() < cfg.branchingFactor);
|
||||
|
||||
/* create node */
|
||||
NodeRef node = createAlignedNode(alloc);
|
||||
NodeRef node = createAlignedNodeMB(alloc,false);
|
||||
|
||||
LBBox3fa bounds = empty;
|
||||
for (size_t i=0; i<children.size(); i++) {
|
||||
const auto child = createLargeLeaf(children[i],alloc);
|
||||
setAlignedNode(node,i,NodeRecordMB4D(child.ref,child.lbounds,children[i].prims.time_range));
|
||||
setAlignedNodeMB(node,i,child);
|
||||
bounds.extend(child.lbounds);
|
||||
}
|
||||
|
||||
return NodeRecordMB(node,bounds);
|
||||
return NodeRecordMB4D(node,bounds,current.prims.time_range);
|
||||
}
|
||||
|
||||
/*! performs split */
|
||||
@@ -227,7 +222,7 @@ namespace embree
|
||||
typename HeuristicTemporal::Split temporal_split;
|
||||
if (bestSAH > 0.5f*leafSAH) {
|
||||
if (current.prims.time_range.size() > 1.01f/float(current.prims.max_num_time_segments)) {
|
||||
temporal_split = temporalSplitHeuristic.find(current.prims, 0);
|
||||
temporal_split = temporalSplitHeuristic.find(current.prims, size_t(0));
|
||||
temporal_split_sah = temporal_split.splitSAH();
|
||||
bestSAH = min(temporal_split_sah,bestSAH);
|
||||
}
|
||||
@@ -259,7 +254,7 @@ namespace embree
|
||||
}
|
||||
|
||||
/*! recursive build */
|
||||
NodeRecordMB recurse(BuildRecord& current, Allocator alloc, bool toplevel)
|
||||
NodeRecordMB4D recurse(BuildRecord& current, Allocator alloc, bool toplevel)
|
||||
{
|
||||
/* get thread local allocator */
|
||||
if (!alloc)
|
||||
@@ -270,7 +265,7 @@ namespace embree
|
||||
progressMonitor(current.size());
|
||||
|
||||
/* create leaf node */
|
||||
if (current.depth+MIN_LARGE_LEAF_LEVELS >= maxDepth || current.size() <= minLeafSize) {
|
||||
if (current.depth+MIN_LARGE_LEAF_LEVELS >= cfg.maxDepth || current.size() <= cfg.minLeafSize) {
|
||||
current.prims.deterministic_order();
|
||||
return createLargeLeaf(current,alloc);
|
||||
}
|
||||
@@ -288,7 +283,7 @@ namespace embree
|
||||
for (size_t i=0; i<children.size(); i++)
|
||||
{
|
||||
/* ignore leaves as they cannot get split */
|
||||
if (children[i].size() <= minLeafSize)
|
||||
if (children[i].size() <= cfg.minLeafSize)
|
||||
continue;
|
||||
|
||||
/* remember child with largest area */
|
||||
@@ -306,12 +301,12 @@ namespace embree
|
||||
std::unique_ptr<mvector<PrimRefMB>> new_vector = split(children[bestChild],left,right,aligned,timesplit);
|
||||
children.split(bestChild,left,right,std::move(new_vector));
|
||||
|
||||
} while (children.size() < branchingFactor);
|
||||
} while (children.size() < cfg.branchingFactor);
|
||||
|
||||
/* create time split node */
|
||||
if (timesplit)
|
||||
{
|
||||
const NodeRef node = createAlignedNode4D(alloc);
|
||||
const NodeRef node = createAlignedNodeMB(alloc,true);
|
||||
|
||||
/* spawn tasks or ... */
|
||||
if (current.size() > SINGLE_THREADED_THRESHOLD)
|
||||
@@ -319,7 +314,7 @@ namespace embree
|
||||
parallel_for(size_t(0), children.size(), [&] (const range<size_t>& r) {
|
||||
for (size_t i=r.begin(); i<r.end(); i++) {
|
||||
const auto child = recurse(children[i],nullptr,true);
|
||||
setAlignedNode4D(node,i,NodeRecordMB4D(child.ref,child.lbounds,children[i].prims.time_range));
|
||||
setAlignedNodeMB(node,i,child);
|
||||
_mm_mfence(); // to allow non-temporal stores during build
|
||||
}
|
||||
});
|
||||
@@ -328,18 +323,18 @@ namespace embree
|
||||
else {
|
||||
for (size_t i=0; i<children.size(); i++) {
|
||||
const auto child = recurse(children[i],alloc,false);
|
||||
setAlignedNode4D(node,i,NodeRecordMB4D(child.ref,child.lbounds,children[i].prims.time_range));
|
||||
setAlignedNodeMB(node,i,child);
|
||||
}
|
||||
}
|
||||
|
||||
const LBBox3fa bounds = current.prims.linearBounds(recalculatePrimRef);
|
||||
return NodeRecordMB(node,bounds);
|
||||
return NodeRecordMB4D(node,bounds,current.prims.time_range);
|
||||
}
|
||||
|
||||
/* create aligned node */
|
||||
else if (aligned)
|
||||
{
|
||||
const NodeRef node = createAlignedNode(alloc);
|
||||
const NodeRef node = createAlignedNodeMB(alloc,false);
|
||||
|
||||
/* spawn tasks or ... */
|
||||
if (current.size() > SINGLE_THREADED_THRESHOLD)
|
||||
@@ -348,7 +343,7 @@ namespace embree
|
||||
parallel_for(size_t(0), children.size(), [&] (const range<size_t>& r) {
|
||||
for (size_t i=r.begin(); i<r.end(); i++) {
|
||||
const auto child = recurse(children[i],nullptr,true);
|
||||
setAlignedNode(node,i,NodeRecordMB4D(child.ref,child.lbounds,children[i].prims.time_range));
|
||||
setAlignedNodeMB(node,i,child);
|
||||
cbounds[i] = child.lbounds;
|
||||
_mm_mfence(); // to allow non-temporal stores during build
|
||||
}
|
||||
@@ -358,7 +353,7 @@ namespace embree
|
||||
for (size_t i=0; i<children.size(); i++)
|
||||
bounds.extend(cbounds[i]);
|
||||
|
||||
return NodeRecordMB(node,bounds);
|
||||
return NodeRecordMB4D(node,bounds,current.prims.time_range);
|
||||
}
|
||||
/* ... continue sequentially */
|
||||
else
|
||||
@@ -366,17 +361,17 @@ namespace embree
|
||||
LBBox3fa bounds = empty;
|
||||
for (size_t i=0; i<children.size(); i++) {
|
||||
const auto child = recurse(children[i],alloc,false);
|
||||
setAlignedNode(node,i,NodeRecordMB4D(child.ref,child.lbounds,children[i].prims.time_range));
|
||||
setAlignedNodeMB(node,i,child);
|
||||
bounds.extend(child.lbounds);
|
||||
}
|
||||
return NodeRecordMB(node,bounds);
|
||||
return NodeRecordMB4D(node,bounds,current.prims.time_range);
|
||||
}
|
||||
}
|
||||
|
||||
/* create unaligned node */
|
||||
else
|
||||
{
|
||||
const NodeRef node = createUnalignedNode(alloc);
|
||||
const NodeRef node = createUnalignedNodeMB(alloc);
|
||||
|
||||
/* spawn tasks or ... */
|
||||
if (current.size() > SINGLE_THREADED_THRESHOLD)
|
||||
@@ -386,7 +381,7 @@ namespace embree
|
||||
const LinearSpace3fa space = unalignedHeuristic.computeAlignedSpaceMB(scene,children[i].prims);
|
||||
const LBBox3fa lbounds = children[i].prims.linearBounds(recalculatePrimRef,space);
|
||||
const auto child = recurse(children[i],nullptr,true);
|
||||
setUnalignedNode(node,i,child.ref,space,lbounds,children[i].prims.time_range);
|
||||
setUnalignedNodeMB(node,i,child.ref,space,lbounds,children[i].prims.time_range);
|
||||
_mm_mfence(); // to allow non-temporal stores during build
|
||||
}
|
||||
});
|
||||
@@ -398,19 +393,19 @@ namespace embree
|
||||
const LinearSpace3fa space = unalignedHeuristic.computeAlignedSpaceMB(scene,children[i].prims);
|
||||
const LBBox3fa lbounds = children[i].prims.linearBounds(recalculatePrimRef,space);
|
||||
const auto child = recurse(children[i],alloc,false);
|
||||
setUnalignedNode(node,i,child.ref,space,lbounds,children[i].prims.time_range);
|
||||
setUnalignedNodeMB(node,i,child.ref,space,lbounds,children[i].prims.time_range);
|
||||
}
|
||||
}
|
||||
|
||||
const LBBox3fa bounds = current.prims.linearBounds(recalculatePrimRef);
|
||||
return NodeRecordMB(node,bounds);
|
||||
return NodeRecordMB4D(node,bounds,current.prims.time_range);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/*! entry point into builder */
|
||||
NodeRecordMB operator() (mvector<PrimRefMB>& prims, const PrimInfoMB& pinfo)
|
||||
NodeRecordMB4D operator() (mvector<PrimRefMB>& prims, const PrimInfoMB& pinfo)
|
||||
{
|
||||
BuildRecord record(SetMB(pinfo,&prims),1);
|
||||
auto root = recurse(record,nullptr,true);
|
||||
@@ -419,15 +414,14 @@ namespace embree
|
||||
}
|
||||
|
||||
private:
|
||||
Settings cfg;
|
||||
Scene* scene;
|
||||
const RecalculatePrimRef& recalculatePrimRef;
|
||||
const CreateAllocFunc& createAlloc;
|
||||
const CreateAlignedNodeFunc& createAlignedNode;
|
||||
const SetAlignedNodeFunc& setAlignedNode;
|
||||
const CreateUnalignedNodeFunc& createUnalignedNode;
|
||||
const SetUnalignedNodeFunc& setUnalignedNode;
|
||||
const CreateAlignedNode4DFunc& createAlignedNode4D;
|
||||
const SetAlignedNode4DFunc& setAlignedNode4D;
|
||||
const CreateAlignedNodeMBFunc& createAlignedNodeMB;
|
||||
const SetAlignedNodeMBFunc& setAlignedNodeMB;
|
||||
const CreateUnalignedNodeMBFunc& createUnalignedNodeMB;
|
||||
const SetUnalignedNodeMBFunc& setUnalignedNodeMB;
|
||||
const CreateLeafFunc& createLeaf;
|
||||
const ProgressMonitor& progressMonitor;
|
||||
|
||||
@@ -440,38 +434,32 @@ namespace embree
|
||||
template<typename NodeRef,
|
||||
typename RecalculatePrimRef,
|
||||
typename CreateAllocFunc,
|
||||
typename CreateAlignedNodeFunc,
|
||||
typename SetAlignedNodeFunc,
|
||||
typename CreateUnalignedNodeFunc,
|
||||
typename SetUnalignedNodeFunc,
|
||||
typename CreateAlignedNode4DFunc,
|
||||
typename SetAlignedNode4DFunc,
|
||||
typename CreateAlignedNodeMBFunc,
|
||||
typename SetAlignedNodeMBFunc,
|
||||
typename CreateUnalignedNodeMBFunc,
|
||||
typename SetUnalignedNodeMBFunc,
|
||||
typename CreateLeafFunc,
|
||||
typename ProgressMonitor>
|
||||
|
||||
static BVHNodeRecordMB<NodeRef> build (Scene* scene, mvector<PrimRefMB>& prims, const PrimInfoMB& pinfo,
|
||||
static BVHNodeRecordMB4D<NodeRef> build (Scene* scene, mvector<PrimRefMB>& prims, const PrimInfoMB& pinfo,
|
||||
const RecalculatePrimRef& recalculatePrimRef,
|
||||
const CreateAllocFunc& createAlloc,
|
||||
const CreateAlignedNodeFunc& createAlignedNode,
|
||||
const SetAlignedNodeFunc& setAlignedNode,
|
||||
const CreateUnalignedNodeFunc& createUnalignedNode,
|
||||
const SetUnalignedNodeFunc& setUnalignedNode,
|
||||
const CreateAlignedNode4DFunc& createAlignedNode4D,
|
||||
const SetAlignedNode4DFunc& setAlignedNode4D,
|
||||
const CreateAlignedNodeMBFunc& createAlignedNodeMB,
|
||||
const SetAlignedNodeMBFunc& setAlignedNodeMB,
|
||||
const CreateUnalignedNodeMBFunc& createUnalignedNodeMB,
|
||||
const SetUnalignedNodeMBFunc& setUnalignedNodeMB,
|
||||
const CreateLeafFunc& createLeaf,
|
||||
const ProgressMonitor& progressMonitor,
|
||||
const Settings settings)
|
||||
{
|
||||
typedef BuilderT<NodeRef,RecalculatePrimRef,CreateAllocFunc,
|
||||
CreateAlignedNodeFunc,SetAlignedNodeFunc,
|
||||
CreateUnalignedNodeFunc,SetUnalignedNodeFunc,
|
||||
CreateAlignedNode4DFunc,SetAlignedNode4DFunc,
|
||||
CreateAlignedNodeMBFunc,SetAlignedNodeMBFunc,
|
||||
CreateUnalignedNodeMBFunc,SetUnalignedNodeMBFunc,
|
||||
CreateLeafFunc,ProgressMonitor> Builder;
|
||||
|
||||
Builder builder(scene,recalculatePrimRef,createAlloc,
|
||||
createAlignedNode,setAlignedNode,
|
||||
createUnalignedNode,setUnalignedNode,
|
||||
createAlignedNode4D,setAlignedNode4D,
|
||||
createAlignedNodeMB,setAlignedNodeMB,
|
||||
createUnalignedNodeMB,setUnalignedNodeMB,
|
||||
createLeaf,progressMonitor,settings);
|
||||
|
||||
return builder(prims,pinfo);
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#include "heuristic_binning_array_aligned.h"
|
||||
#include "heuristic_spatial_array.h"
|
||||
#include "heuristic_openmerge_array.h"
|
||||
|
||||
#if defined(__AVX512F__)
|
||||
# define NUM_OBJECT_BINS 16
|
||||
@@ -103,6 +104,7 @@ namespace embree
|
||||
template<typename BuildRecord,
|
||||
typename Heuristic,
|
||||
typename Set,
|
||||
typename PrimRef,
|
||||
typename ReductionTy,
|
||||
typename Allocator,
|
||||
typename CreateAllocFunc,
|
||||
@@ -111,11 +113,12 @@ namespace embree
|
||||
typename CreateLeafFunc,
|
||||
typename ProgressMonitor>
|
||||
|
||||
class BuilderT : private Settings
|
||||
class BuilderT
|
||||
{
|
||||
friend struct GeneralBVHBuilder;
|
||||
|
||||
BuilderT (Heuristic& heuristic,
|
||||
BuilderT (PrimRef* prims,
|
||||
Heuristic& heuristic,
|
||||
const CreateAllocFunc& createAlloc,
|
||||
const CreateNodeFunc& createNode,
|
||||
const UpdateNodeFunc& updateNode,
|
||||
@@ -123,24 +126,25 @@ namespace embree
|
||||
const ProgressMonitor& progressMonitor,
|
||||
const Settings& settings)
|
||||
|
||||
: Settings(settings),
|
||||
: cfg(settings),
|
||||
prims(prims),
|
||||
heuristic(heuristic),
|
||||
createAlloc(createAlloc), createNode(createNode), updateNode(updateNode), createLeaf(createLeaf),
|
||||
progressMonitor(progressMonitor)
|
||||
{
|
||||
if (branchingFactor > MAX_BRANCHING_FACTOR)
|
||||
if (cfg.branchingFactor > MAX_BRANCHING_FACTOR)
|
||||
throw_RTCError(RTC_UNKNOWN_ERROR,"bvh_builder: branching factor too large");
|
||||
}
|
||||
|
||||
const ReductionTy createLargeLeaf(const BuildRecord& current, Allocator alloc)
|
||||
{
|
||||
/* this should never occur but is a fatal error */
|
||||
if (current.depth > maxDepth)
|
||||
if (current.depth > cfg.maxDepth)
|
||||
throw_RTCError(RTC_UNKNOWN_ERROR,"depth limit reached");
|
||||
|
||||
/* create leaf for few primitives */
|
||||
if (current.prims.size() <= maxLeafSize)
|
||||
return createLeaf(current,alloc);
|
||||
if (current.prims.size() <= cfg.maxLeafSize)
|
||||
return createLeaf(prims,current.prims,alloc);
|
||||
|
||||
/* fill all children by always splitting the largest one */
|
||||
ReductionTy values[MAX_BRANCHING_FACTOR];
|
||||
@@ -155,7 +159,7 @@ namespace embree
|
||||
for (size_t i=0; i<numChildren; i++)
|
||||
{
|
||||
/* ignore leaves as they cannot get split */
|
||||
if (children[i].prims.size() <= maxLeafSize)
|
||||
if (children[i].prims.size() <= cfg.maxLeafSize)
|
||||
continue;
|
||||
|
||||
/* remember child with largest size */
|
||||
@@ -177,12 +181,12 @@ namespace embree
|
||||
children[numChildren+0] = right;
|
||||
numChildren++;
|
||||
|
||||
} while (numChildren < branchingFactor);
|
||||
} while (numChildren < cfg.branchingFactor);
|
||||
|
||||
/* set barrier for primrefarrayalloc */
|
||||
if (unlikely(current.size() > primrefarrayalloc))
|
||||
if (unlikely(current.size() > cfg.primrefarrayalloc))
|
||||
for (size_t i=0; i<numChildren; i++)
|
||||
children[i].alloc_barrier = children[i].size() <= primrefarrayalloc;
|
||||
children[i].alloc_barrier = children[i].size() <= cfg.primrefarrayalloc;
|
||||
|
||||
/* create node */
|
||||
auto node = createNode(children,numChildren,alloc);
|
||||
@@ -202,19 +206,19 @@ namespace embree
|
||||
alloc = createAlloc();
|
||||
|
||||
/* call memory monitor function to signal progress */
|
||||
if (toplevel && current.size() <= singleThreadThreshold)
|
||||
if (toplevel && current.size() <= cfg.singleThreadThreshold)
|
||||
progressMonitor(current.size());
|
||||
|
||||
/*! find best split */
|
||||
auto split = heuristic.find(current.prims,logBlockSize);
|
||||
auto split = heuristic.find(current.prims,cfg.logBlockSize);
|
||||
|
||||
/*! compute leaf and split cost */
|
||||
const float leafSAH = intCost*current.prims.leafSAH(logBlockSize);
|
||||
const float splitSAH = travCost*halfArea(current.prims.geomBounds)+intCost*split.splitSAH();
|
||||
const float leafSAH = cfg.intCost*current.prims.leafSAH(cfg.logBlockSize);
|
||||
const float splitSAH = cfg.travCost*halfArea(current.prims.geomBounds)+cfg.intCost*split.splitSAH();
|
||||
assert((current.prims.size() == 0) || ((leafSAH >= 0) && (splitSAH >= 0)));
|
||||
|
||||
/*! create a leaf node when threshold reached or SAH tells us to stop */
|
||||
if (current.prims.size() <= minLeafSize || current.depth+MIN_LARGE_LEAF_LEVELS >= maxDepth || (current.prims.size() <= maxLeafSize && leafSAH <= splitSAH)) {
|
||||
if (current.prims.size() <= cfg.minLeafSize || current.depth+MIN_LARGE_LEAF_LEVELS >= cfg.maxDepth || (current.prims.size() <= cfg.maxLeafSize && leafSAH <= splitSAH)) {
|
||||
heuristic.deterministic_order(current.prims);
|
||||
return createLargeLeaf(current,alloc);
|
||||
}
|
||||
@@ -231,7 +235,7 @@ namespace embree
|
||||
size_t numChildren = 2;
|
||||
|
||||
/*! split until node is full or SAH tells us to stop */
|
||||
while (numChildren < branchingFactor)
|
||||
while (numChildren < cfg.branchingFactor)
|
||||
{
|
||||
/*! find best child to split */
|
||||
float bestArea = neg_inf;
|
||||
@@ -239,7 +243,7 @@ namespace embree
|
||||
for (size_t i=0; i<numChildren; i++)
|
||||
{
|
||||
/* ignore leaves as they cannot get split */
|
||||
if (children[i].prims.size() <= minLeafSize) continue;
|
||||
if (children[i].prims.size() <= cfg.minLeafSize) continue;
|
||||
|
||||
/* find child with largest surface area */
|
||||
if (halfArea(children[i].prims.geomBounds) > bestArea) {
|
||||
@@ -253,7 +257,7 @@ namespace embree
|
||||
BuildRecord& brecord = children[bestChild];
|
||||
BuildRecord lrecord(current.depth+1);
|
||||
BuildRecord rrecord(current.depth+1);
|
||||
auto split = heuristic.find(brecord.prims,logBlockSize);
|
||||
auto split = heuristic.find(brecord.prims,cfg.logBlockSize);
|
||||
heuristic.split(split,brecord.prims,lrecord.prims,rrecord.prims);
|
||||
children[bestChild ] = lrecord;
|
||||
children[numChildren] = rrecord;
|
||||
@@ -261,9 +265,9 @@ namespace embree
|
||||
}
|
||||
|
||||
/* set barrier for primrefarrayalloc */
|
||||
if (unlikely(current.size() > primrefarrayalloc))
|
||||
if (unlikely(current.size() > cfg.primrefarrayalloc))
|
||||
for (size_t i=0; i<numChildren; i++)
|
||||
children[i].alloc_barrier = children[i].size() <= primrefarrayalloc;
|
||||
children[i].alloc_barrier = children[i].size() <= cfg.primrefarrayalloc;
|
||||
|
||||
/* sort buildrecords for faster shadow ray traversal */
|
||||
std::sort(&children[0],&children[numChildren],std::greater<BuildRecord>());
|
||||
@@ -272,7 +276,7 @@ namespace embree
|
||||
auto node = createNode(children,numChildren,alloc);
|
||||
|
||||
/* spawn tasks */
|
||||
if (current.size() > singleThreadThreshold)
|
||||
if (current.size() > cfg.singleThreadThreshold)
|
||||
{
|
||||
/*! parallel_for is faster than spawing sub-tasks */
|
||||
parallel_for(size_t(0), numChildren, [&] (const range<size_t>& r) { // FIXME: no range here
|
||||
@@ -295,6 +299,8 @@ namespace embree
|
||||
}
|
||||
|
||||
private:
|
||||
Settings cfg;
|
||||
PrimRef* prims;
|
||||
Heuristic& heuristic;
|
||||
const CreateAllocFunc& createAlloc;
|
||||
const CreateNodeFunc& createNode;
|
||||
@@ -307,6 +313,7 @@ namespace embree
|
||||
typename ReductionTy,
|
||||
typename Heuristic,
|
||||
typename Set,
|
||||
typename PrimRef,
|
||||
typename CreateAllocFunc,
|
||||
typename CreateNodeFunc,
|
||||
typename UpdateNodeFunc,
|
||||
@@ -314,6 +321,7 @@ namespace embree
|
||||
typename ProgressMonitor>
|
||||
|
||||
__noinline static ReductionTy build(Heuristic& heuristic,
|
||||
PrimRef* prims,
|
||||
const Set& set,
|
||||
CreateAllocFunc createAlloc,
|
||||
CreateNodeFunc createNode, UpdateNodeFunc updateNode,
|
||||
@@ -327,6 +335,7 @@ namespace embree
|
||||
BuildRecord,
|
||||
Heuristic,
|
||||
Set,
|
||||
PrimRef,
|
||||
ReductionTy,
|
||||
decltype(createAlloc()),
|
||||
CreateAllocFunc,
|
||||
@@ -336,7 +345,8 @@ namespace embree
|
||||
ProgressMonitor> Builder;
|
||||
|
||||
/* instantiate builder */
|
||||
Builder builder(heuristic,
|
||||
Builder builder(prims,
|
||||
heuristic,
|
||||
createAlloc,
|
||||
createNode,
|
||||
updateNode,
|
||||
@@ -377,9 +387,10 @@ namespace embree
|
||||
const Settings& settings)
|
||||
{
|
||||
Heuristic heuristic(prims);
|
||||
return GeneralBVHBuilder::build<ReductionTy,Heuristic,Set>(
|
||||
return GeneralBVHBuilder::build<ReductionTy,Heuristic,Set,PrimRef>(
|
||||
heuristic,
|
||||
PrimInfoRange(0,pinfo.size(),pinfo.geomBounds,pinfo.centBounds),
|
||||
prims,
|
||||
PrimInfoRange(0,pinfo.size(),pinfo),
|
||||
createAlloc,
|
||||
createNode,
|
||||
updateNode,
|
||||
@@ -403,21 +414,20 @@ namespace embree
|
||||
template<typename ReductionTy, typename UserCreateLeaf>
|
||||
struct CreateLeafExt
|
||||
{
|
||||
__forceinline CreateLeafExt (const UserCreateLeaf userCreateLeaf, PrimRef* prims)
|
||||
: userCreateLeaf(userCreateLeaf), prims(prims) {}
|
||||
__forceinline CreateLeafExt (const UserCreateLeaf userCreateLeaf)
|
||||
: userCreateLeaf(userCreateLeaf) {}
|
||||
|
||||
// __noinline is workaround for ICC2016 compiler bug
|
||||
template<typename Allocator>
|
||||
__noinline ReductionTy operator() (const BuildRecord& current, Allocator alloc) const
|
||||
__noinline ReductionTy operator() (PrimRef* prims, const range<size_t>& range, Allocator alloc) const
|
||||
{
|
||||
for (size_t i=current.prims.begin(); i<current.prims.end(); i++)
|
||||
for (size_t i=range.begin(); i<range.end(); i++)
|
||||
prims[i].lower.a &= GEOMID_MASK;
|
||||
|
||||
return userCreateLeaf(current,alloc);
|
||||
return userCreateLeaf(prims,range,alloc);
|
||||
}
|
||||
|
||||
const UserCreateLeaf userCreateLeaf;
|
||||
PrimRef* prims;
|
||||
};
|
||||
|
||||
/*! special builder that propagates reduction over the tree */
|
||||
@@ -472,16 +482,64 @@ namespace embree
|
||||
}
|
||||
});
|
||||
|
||||
return GeneralBVHBuilder::build<ReductionTy,Heuristic,Set>(
|
||||
return GeneralBVHBuilder::build<ReductionTy,Heuristic,Set,PrimRef>(
|
||||
heuristic,
|
||||
PrimInfoExtRange(0,pinfo.size(),extSize,pinfo.geomBounds,pinfo.centBounds),
|
||||
prims,
|
||||
PrimInfoExtRange(0,pinfo.size(),extSize,pinfo),
|
||||
createAlloc,
|
||||
createNode,
|
||||
updateNode,
|
||||
CreateLeafExt<ReductionTy,CreateLeafFunc>(createLeaf,prims),
|
||||
CreateLeafExt<ReductionTy,CreateLeafFunc>(createLeaf),
|
||||
progressMonitor,
|
||||
settings);
|
||||
}
|
||||
};
|
||||
|
||||
/* Open/Merge SAH builder that operates on an array of BuildRecords */
|
||||
struct BVHBuilderBinnedOpenMergeSAH
|
||||
{
|
||||
static const size_t NUM_OBJECT_BINS_HQ = 32;
|
||||
typedef PrimInfoExtRange Set;
|
||||
typedef BinSplit<NUM_OBJECT_BINS_HQ> Split;
|
||||
typedef GeneralBVHBuilder::BuildRecordT<Set,Split> BuildRecord;
|
||||
typedef GeneralBVHBuilder::Settings Settings;
|
||||
|
||||
/*! special builder that propagates reduction over the tree */
|
||||
template<
|
||||
typename ReductionTy,
|
||||
typename BuildRef,
|
||||
typename CreateAllocFunc,
|
||||
typename CreateNodeFunc,
|
||||
typename UpdateNodeFunc,
|
||||
typename CreateLeafFunc,
|
||||
typename NodeOpenerFunc,
|
||||
typename ProgressMonitor>
|
||||
|
||||
static ReductionTy build(CreateAllocFunc createAlloc,
|
||||
CreateNodeFunc createNode,
|
||||
UpdateNodeFunc updateNode,
|
||||
const CreateLeafFunc& createLeaf,
|
||||
NodeOpenerFunc nodeOpenerFunc,
|
||||
ProgressMonitor progressMonitor,
|
||||
BuildRef* prims,
|
||||
const size_t extSize,
|
||||
const PrimInfo& pinfo,
|
||||
const Settings& settings)
|
||||
{
|
||||
typedef HeuristicArrayOpenMergeSAH<NodeOpenerFunc,BuildRef,NUM_OBJECT_BINS_HQ> Heuristic;
|
||||
Heuristic heuristic(nodeOpenerFunc,prims,settings.branchingFactor);
|
||||
|
||||
return GeneralBVHBuilder::build<ReductionTy,Heuristic,Set,BuildRef>(
|
||||
heuristic,
|
||||
prims,
|
||||
PrimInfoExtRange(0,pinfo.size(),extSize,pinfo),
|
||||
createAlloc,
|
||||
createNode,
|
||||
updateNode,
|
||||
createLeaf,
|
||||
progressMonitor,
|
||||
settings);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -37,8 +37,20 @@ namespace embree
|
||||
__forceinline BinMapping(size_t N, const BBox3fa& centBounds)
|
||||
{
|
||||
num = min(BINS,size_t(4.0f + 0.05f*N));
|
||||
const vfloat4 diag = (vfloat4) centBounds.size();
|
||||
scale = select(diag > vfloat4(1E-34f),vfloat4(0.99f*num)/diag,vfloat4(0.0f));
|
||||
assert(num >= 1);
|
||||
const vfloat4 eps = 1E-34f;
|
||||
const vfloat4 diag = max(eps, (vfloat4) centBounds.size());
|
||||
scale = select(diag > eps,vfloat4(0.99f*num)/diag,vfloat4(0.0f));
|
||||
ofs = (vfloat4) centBounds.lower;
|
||||
}
|
||||
|
||||
/*! calculates the mapping */
|
||||
__forceinline BinMapping(const BBox3fa& centBounds)
|
||||
{
|
||||
num = BINS;
|
||||
const vfloat4 eps = 1E-34f;
|
||||
const vfloat4 diag = max(eps, (vfloat4) centBounds.size());
|
||||
scale = select(diag > eps,vfloat4(0.99f*num)/diag,vfloat4(0.0f));
|
||||
ofs = (vfloat4) centBounds.lower;
|
||||
}
|
||||
|
||||
@@ -46,9 +58,10 @@ namespace embree
|
||||
template<typename PrimInfo>
|
||||
__forceinline BinMapping(const PrimInfo& pinfo)
|
||||
{
|
||||
const vfloat4 eps = 1E-34f;
|
||||
num = min(BINS,size_t(4.0f + 0.05f*pinfo.size()));
|
||||
const vfloat4 diag = (vfloat4) pinfo.centBounds.size();
|
||||
scale = select(diag > vfloat4(1E-34f),vfloat4(0.99f*num)/diag,vfloat4(0.0f));
|
||||
const vfloat4 diag = max(eps,(vfloat4) pinfo.centBounds.size());
|
||||
scale = select(diag > eps,vfloat4(0.99f*num)/diag,vfloat4(0.0f));
|
||||
ofs = (vfloat4) pinfo.centBounds.lower;
|
||||
}
|
||||
|
||||
@@ -81,9 +94,9 @@ namespace embree
|
||||
}
|
||||
|
||||
/*! faster but unsafe binning */
|
||||
template<typename PrimRef>
|
||||
__forceinline Vec3ia bin_unsafe(const PrimRef& p, const LinearSpace3fa& space, void* user = nullptr) const {
|
||||
return bin_unsafe(p.binCenter(space,user));
|
||||
template<typename PrimRef, typename BinBoundsAndCenter>
|
||||
__forceinline Vec3ia bin_unsafe(const PrimRef& p, const BinBoundsAndCenter& binBoundsAndCenter) const {
|
||||
return bin_unsafe(binBoundsAndCenter.binCenter(p));
|
||||
}
|
||||
|
||||
template<typename PrimRef>
|
||||
@@ -94,6 +107,11 @@ namespace embree
|
||||
return any(((vint4)bin_unsafe(center2(ref.bounds())) < vSplitPos) & splitDimMask);
|
||||
}
|
||||
|
||||
/*! calculates left spatial position of bin */
|
||||
__forceinline float pos(const size_t bin, const size_t dim) const {
|
||||
return madd(float(bin),1.0f / scale[dim],ofs[dim]);
|
||||
}
|
||||
|
||||
/*! returns true if the mapping is invalid in some dimension */
|
||||
__forceinline bool invalid(const size_t dim) const {
|
||||
return scale[dim] == 0.0f;
|
||||
@@ -115,9 +133,9 @@ namespace embree
|
||||
{
|
||||
enum
|
||||
{
|
||||
SPLIT_OBJECT = 0,
|
||||
SPLIT_TEMPORAL = -1,
|
||||
SPLIT_FALLBACK = -2,
|
||||
SPLIT_OBJECT = 0,
|
||||
SPLIT_TEMPORAL = 1,
|
||||
SPLIT_FALLBACK = 2,
|
||||
};
|
||||
|
||||
/*! construct an invalid split by default */
|
||||
@@ -223,7 +241,7 @@ namespace embree
|
||||
const unsigned int b00 = extract<0>(bin0); bounds(b00,0).extend(prim0);
|
||||
const unsigned int b01 = extract<1>(bin0); bounds(b01,1).extend(prim0);
|
||||
const unsigned int b02 = extract<2>(bin0); bounds(b02,2).extend(prim0);
|
||||
const unsigned int s0 = prims[i+0].size();
|
||||
const unsigned int s0 = (unsigned int)prims[i+0].size();
|
||||
counts(b00,0)+=s0;
|
||||
counts(b01,1)+=s0;
|
||||
counts(b02,2)+=s0;
|
||||
@@ -232,7 +250,7 @@ namespace embree
|
||||
const unsigned int b10 = extract<0>(bin1); bounds(b10,0).extend(prim1);
|
||||
const unsigned int b11 = extract<1>(bin1); bounds(b11,1).extend(prim1);
|
||||
const unsigned int b12 = extract<2>(bin1); bounds(b12,2).extend(prim1);
|
||||
const unsigned int s1 = prims[i+1].size();
|
||||
const unsigned int s1 = (unsigned int)prims[i+1].size();
|
||||
counts(b10,0)+=s1;
|
||||
counts(b11,1)+=s1;
|
||||
counts(b12,2)+=s1;
|
||||
@@ -246,7 +264,7 @@ namespace embree
|
||||
const vint4 bin0 = (vint4)mapping.bin(center0);
|
||||
|
||||
/*! increase bounds of bins */
|
||||
const unsigned int s0 = prims[i].size();
|
||||
const unsigned int s0 = (unsigned int)prims[i].size();
|
||||
const int b00 = extract<0>(bin0); counts(b00,0)+=s0; bounds(b00,0).extend(prim0);
|
||||
const int b01 = extract<1>(bin0); counts(b01,1)+=s0; bounds(b01,1).extend(prim0);
|
||||
const int b02 = extract<2>(bin0); counts(b02,2)+=s0; bounds(b02,2).extend(prim0);
|
||||
@@ -254,7 +272,8 @@ namespace embree
|
||||
}
|
||||
|
||||
/*! bins an array of primitives */
|
||||
__forceinline void bin (const PrimRef* prims, size_t N, const BinMapping<BINS>& mapping, const AffineSpace3fa& space, void* user = nullptr)
|
||||
template<typename BinBoundsAndCenter>
|
||||
__forceinline void bin (const PrimRef* prims, size_t N, const BinMapping<BINS>& mapping, const BinBoundsAndCenter& binBoundsAndCenter)
|
||||
{
|
||||
if (N == 0) return;
|
||||
|
||||
@@ -262,9 +281,9 @@ namespace embree
|
||||
for (i=0; i<N-1; i+=2)
|
||||
{
|
||||
/*! map even and odd primitive to bin */
|
||||
BBox prim0; Vec3fa center0; prims[i+0].binBoundsAndCenter(prim0,center0,space,user);
|
||||
BBox prim0; Vec3fa center0; binBoundsAndCenter.binBoundsAndCenter(prims[i+0],prim0,center0);
|
||||
const vint4 bin0 = (vint4)mapping.bin(center0);
|
||||
BBox prim1; Vec3fa center1; prims[i+1].binBoundsAndCenter(prim1,center1,space,user);
|
||||
BBox prim1; Vec3fa center1; binBoundsAndCenter.binBoundsAndCenter(prims[i+1],prim1,center1);
|
||||
const vint4 bin1 = (vint4)mapping.bin(center1);
|
||||
|
||||
/*! increase bounds for bins for even primitive */
|
||||
@@ -284,7 +303,7 @@ namespace embree
|
||||
if (i < N)
|
||||
{
|
||||
/*! map primitive to bin */
|
||||
BBox prim0; Vec3fa center0; prims[i+0].binBoundsAndCenter(prim0,center0,space,user);
|
||||
BBox prim0; Vec3fa center0; binBoundsAndCenter.binBoundsAndCenter(prims[i+0],prim0,center0);
|
||||
const vint4 bin0 = (vint4)mapping.bin(center0);
|
||||
|
||||
/*! increase bounds of bins */
|
||||
@@ -299,9 +318,10 @@ namespace embree
|
||||
bin(prims+begin,end-begin,mapping);
|
||||
}
|
||||
|
||||
__forceinline void bin(const PrimRef* prims, size_t begin, size_t end, const BinMapping<BINS>& mapping, const AffineSpace3fa& space, void* user = nullptr) {
|
||||
bin(prims+begin,end-begin,mapping,space,user);
|
||||
}
|
||||
template<typename BinBoundsAndCenter>
|
||||
__forceinline void bin(const PrimRef* prims, size_t begin, size_t end, const BinMapping<BINS>& mapping, const BinBoundsAndCenter& binBoundsAndCenter) {
|
||||
bin<BinBoundsAndCenter>(prims+begin,end-begin,mapping,binBoundsAndCenter);
|
||||
}
|
||||
|
||||
/*! merges in other binning information */
|
||||
__forceinline void merge (const BinInfoT& other, size_t numBins)
|
||||
@@ -451,8 +471,9 @@ namespace embree
|
||||
__forceinline BinMapping(const PrimInfo& pinfo)
|
||||
{
|
||||
num = 16;
|
||||
const vfloat4 diag = (vfloat4) pinfo.centBounds.size();
|
||||
scale = select(diag > vfloat4(1E-34f),vfloat4(0.99f*num)/diag,vfloat4(0.0f));
|
||||
const vfloat4 eps = 1E-34f;
|
||||
const vfloat4 diag = max(eps,(vfloat4) pinfo.centBounds.size());
|
||||
scale = select(diag > eps,vfloat4(0.99f*num)/diag,vfloat4(0.0f));
|
||||
ofs = (vfloat4) pinfo.centBounds.lower;
|
||||
scale16 = scale;
|
||||
ofs16 = ofs;
|
||||
@@ -593,9 +614,9 @@ namespace embree
|
||||
max_z1 = init_max;
|
||||
max_z2 = init_max;
|
||||
|
||||
count0 = vint16::zero();
|
||||
count1 = vint16::zero();
|
||||
count2 = vint16::zero();
|
||||
count0 = zero;
|
||||
count1 = zero;
|
||||
count2 = zero;
|
||||
|
||||
const vint16 step16(step);
|
||||
size_t i;
|
||||
@@ -925,14 +946,14 @@ namespace embree
|
||||
}
|
||||
}
|
||||
|
||||
template<typename BinInfoT, typename BinMapping, typename PrimRef>
|
||||
__forceinline void bin_parallel(BinInfoT& binner, const PrimRef* prims, size_t begin, size_t end, size_t blockSize, size_t parallelThreshold, const BinMapping& mapping, const AffineSpace3fa& space, void* user = nullptr)
|
||||
template<typename BinBoundsAndCenter, typename BinInfoT, typename BinMapping, typename PrimRef>
|
||||
__forceinline void bin_parallel(BinInfoT& binner, const PrimRef* prims, size_t begin, size_t end, size_t blockSize, size_t parallelThreshold, const BinMapping& mapping, const BinBoundsAndCenter& binBoundsAndCenter)
|
||||
{
|
||||
if (likely(end-begin < parallelThreshold)) {
|
||||
binner.bin(prims,begin,end,mapping,space,user);
|
||||
binner.bin(prims,begin,end,mapping,binBoundsAndCenter);
|
||||
} else {
|
||||
binner = parallel_reduce(begin,end,blockSize,binner,
|
||||
[&](const range<size_t>& r) -> BinInfoT { BinInfoT binner(empty); binner.bin(prims + r.begin(), r.size(), mapping, space, user); return binner; },
|
||||
[&](const range<size_t>& r) -> BinInfoT { BinInfoT binner(empty); binner.bin(prims + r.begin(), r.size(), mapping, binBoundsAndCenter); return binner; },
|
||||
[&](const BinInfoT& b0, const BinInfoT& b1) -> BinInfoT { BinInfoT r = b0; r.merge(b1, mapping.size()); return r; });
|
||||
}
|
||||
}
|
||||
@@ -949,14 +970,14 @@ namespace embree
|
||||
}
|
||||
}
|
||||
|
||||
template<bool parallel, typename BinInfoT, typename BinMapping, typename PrimRef>
|
||||
__forceinline void bin_serial_or_parallel(BinInfoT& binner, const PrimRef* prims, size_t begin, size_t end, size_t blockSize, const BinMapping& mapping, const AffineSpace3fa& space, void* user = nullptr)
|
||||
template<bool parallel, typename BinBoundsAndCenter, typename BinInfoT, typename BinMapping, typename PrimRef>
|
||||
__forceinline void bin_serial_or_parallel(BinInfoT& binner, const PrimRef* prims, size_t begin, size_t end, size_t blockSize, const BinMapping& mapping, const BinBoundsAndCenter& binBoundsAndCenter)
|
||||
{
|
||||
if (!parallel) {
|
||||
binner.bin(prims,begin,end,mapping,space,user);
|
||||
binner.bin(prims,begin,end,mapping,binBoundsAndCenter);
|
||||
} else {
|
||||
binner = parallel_reduce(begin,end,blockSize,binner,
|
||||
[&](const range<size_t>& r) -> BinInfoT { BinInfoT binner(empty); binner.bin(prims + r.begin(), r.size(), mapping, space, user); return binner; },
|
||||
[&](const range<size_t>& r) -> BinInfoT { BinInfoT binner(empty); binner.bin(prims + r.begin(), r.size(), mapping, binBoundsAndCenter); return binner; },
|
||||
[&](const BinInfoT& b0, const BinInfoT& b1) -> BinInfoT { BinInfoT r = b0; r.merge(b1, mapping.size()); return r; });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,8 +33,8 @@ namespace embree
|
||||
__forceinline PrimInfoRange(EmptyTy)
|
||||
: CentGeomBBox3fa(EmptyTy()), range<size_t>(0,0) {}
|
||||
|
||||
__forceinline PrimInfoRange (size_t begin, size_t end, const BBox3fa& geomBounds, const BBox3fa& centBounds)
|
||||
: CentGeomBBox3fa(geomBounds,centBounds), range<size_t>(begin,end) {}
|
||||
__forceinline PrimInfoRange (size_t begin, size_t end, const CentGeomBBox3fa& centGeomBounds)
|
||||
: CentGeomBBox3fa(centGeomBounds), range<size_t>(begin,end) {}
|
||||
|
||||
__forceinline float leafSAH() const {
|
||||
return expectedApproxHalfArea(geomBounds)*float(size());
|
||||
@@ -119,16 +119,16 @@ namespace embree
|
||||
size_t center = 0;
|
||||
if (!parallel)
|
||||
center = serial_partitioning(prims,begin,end,local_left,local_right,isLeft,
|
||||
[] (CentGeomBBox3fa& pinfo,const PrimRef& ref) { pinfo.extend(ref.bounds()); });
|
||||
[] (CentGeomBBox3fa& pinfo,const PrimRef& ref) { pinfo.extend_center2(ref); });
|
||||
else
|
||||
center = parallel_partitioning(
|
||||
prims,begin,end,EmptyTy(),local_left,local_right,isLeft,
|
||||
[] (CentGeomBBox3fa& pinfo,const PrimRef &ref) { pinfo.extend(ref.bounds()); },
|
||||
[] (CentGeomBBox3fa& pinfo0,const CentGeomBBox3fa &pinfo1) { pinfo0.merge(pinfo1); },
|
||||
[] (CentGeomBBox3fa& pinfo,const PrimRef& ref) { pinfo.extend_center2(ref); },
|
||||
[] (CentGeomBBox3fa& pinfo0,const CentGeomBBox3fa& pinfo1) { pinfo0.merge(pinfo1); },
|
||||
PARALLEL_PARTITION_BLOCK_SIZE);
|
||||
|
||||
new (&lset) PrimInfoRange(begin,center,local_left.geomBounds,local_left.centBounds);
|
||||
new (&rset) PrimInfoRange(center,end,local_right.geomBounds,local_right.centBounds);
|
||||
new (&lset) PrimInfoRange(begin,center,local_left);
|
||||
new (&rset) PrimInfoRange(center,end,local_right);
|
||||
assert(area(lset.geomBounds) >= 0.0f);
|
||||
assert(area(rset.geomBounds) >= 0.0f);
|
||||
}
|
||||
@@ -145,15 +145,15 @@ namespace embree
|
||||
const size_t end = pinfo.end();
|
||||
const size_t center = (begin + end)/2;
|
||||
|
||||
CentGeomBBox3fa left; left.reset();
|
||||
CentGeomBBox3fa left(empty);
|
||||
for (size_t i=begin; i<center; i++)
|
||||
left.extend(prims[i].bounds());
|
||||
new (&linfo) PrimInfoRange(begin,center,left.geomBounds,left.centBounds);
|
||||
left.extend_center2(prims[i]);
|
||||
new (&linfo) PrimInfoRange(begin,center,left);
|
||||
|
||||
CentGeomBBox3fa right; right.reset();
|
||||
CentGeomBBox3fa right(empty);
|
||||
for (size_t i=center; i<end; i++)
|
||||
right.extend(prims[i].bounds());
|
||||
new (&rinfo) PrimInfoRange(center,end,right.geomBounds,right.centBounds);
|
||||
right.extend_center2(prims[i]);
|
||||
new (&rinfo) PrimInfoRange(center,end,right);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -76,8 +76,35 @@ namespace embree
|
||||
const CentGeomBBox3fa bounds = parallel_reduce(set.begin(), set.end(), size_t(1024), size_t(4096),
|
||||
CentGeomBBox3fa(empty), computeBounds, CentGeomBBox3fa::merge2);
|
||||
|
||||
return PrimInfo(set.begin(),set.end(),bounds.geomBounds,bounds.centBounds);
|
||||
return PrimInfo(set.begin(),set.end(),bounds);
|
||||
}
|
||||
|
||||
struct BinBoundsAndCenter
|
||||
{
|
||||
__forceinline BinBoundsAndCenter(Scene* scene, const LinearSpace3fa& space)
|
||||
: scene(scene), space(space) {}
|
||||
|
||||
/*! returns center for binning */
|
||||
__forceinline Vec3fa binCenter(const PrimRef& ref) const
|
||||
{
|
||||
NativeCurves* mesh = (NativeCurves*) scene->get(ref.geomID());
|
||||
BBox3fa bounds = mesh->bounds(space,ref.primID());
|
||||
return embree::center2(bounds);
|
||||
}
|
||||
|
||||
/*! returns bounds and centroid used for binning */
|
||||
__forceinline void binBoundsAndCenter(const PrimRef& ref, BBox3fa& bounds_o, Vec3fa& center_o) const
|
||||
{
|
||||
NativeCurves* mesh = (NativeCurves*) scene->get(ref.geomID());
|
||||
BBox3fa bounds = mesh->bounds(space,ref.primID());
|
||||
bounds_o = bounds;
|
||||
center_o = embree::center2(bounds);
|
||||
}
|
||||
|
||||
private:
|
||||
Scene* scene;
|
||||
const LinearSpace3fa space;
|
||||
};
|
||||
|
||||
/*! finds the best split */
|
||||
__forceinline const Split find(const PrimInfoRange& pinfo, const size_t logBlockSize, const LinearSpace3fa& space)
|
||||
@@ -94,7 +121,8 @@ namespace embree
|
||||
{
|
||||
Binner binner(empty);
|
||||
const BinMapping<BINS> mapping(set);
|
||||
bin_serial_or_parallel<parallel>(binner,prims,set.begin(),set.end(),size_t(4096),mapping,space,scene);
|
||||
BinBoundsAndCenter binBoundsAndCenter(scene,space);
|
||||
bin_serial_or_parallel<parallel>(binner,prims,set.begin(),set.end(),size_t(4096),mapping,binBoundsAndCenter);
|
||||
return binner.best(mapping,logBlockSize);
|
||||
}
|
||||
|
||||
@@ -122,21 +150,22 @@ namespace embree
|
||||
CentGeomBBox3fa local_right(empty);
|
||||
const int splitPos = split.pos;
|
||||
const int splitDim = split.dim;
|
||||
BinBoundsAndCenter binBoundsAndCenter(scene,space);
|
||||
|
||||
size_t center = 0;
|
||||
if (likely(set.size() < 10000))
|
||||
center = serial_partitioning(prims,begin,end,local_left,local_right,
|
||||
[&] (const PrimRef& ref) { return split.mapping.bin_unsafe(ref,space,scene)[splitDim] < splitPos; },
|
||||
[] (CentGeomBBox3fa& pinfo,const PrimRef& ref) { pinfo.extend(ref.bounds()); });
|
||||
[&] (const PrimRef& ref) { return split.mapping.bin_unsafe(ref,binBoundsAndCenter)[splitDim] < splitPos; },
|
||||
[] (CentGeomBBox3fa& pinfo,const PrimRef& ref) { pinfo.extend_center2(ref); });
|
||||
else
|
||||
center = parallel_partitioning(prims,begin,end,EmptyTy(),local_left,local_right,
|
||||
[&] (const PrimRef& ref) { return split.mapping.bin_unsafe(ref,space,scene)[splitDim] < splitPos; },
|
||||
[] (CentGeomBBox3fa& pinfo,const PrimRef& ref) { pinfo.extend(ref.bounds()); },
|
||||
[&] (const PrimRef& ref) { return split.mapping.bin_unsafe(ref,binBoundsAndCenter)[splitDim] < splitPos; },
|
||||
[] (CentGeomBBox3fa& pinfo,const PrimRef& ref) { pinfo.extend_center2(ref); },
|
||||
[] (CentGeomBBox3fa& pinfo0,const CentGeomBBox3fa& pinfo1) { pinfo0.merge(pinfo1); },
|
||||
128);
|
||||
|
||||
new (&lset) PrimInfoRange(begin,center,local_left.geomBounds,local_left.centBounds);
|
||||
new (&rset) PrimInfoRange(center,end,local_right.geomBounds,local_right.centBounds);
|
||||
new (&lset) PrimInfoRange(begin,center,local_left);
|
||||
new (&rset) PrimInfoRange(center,end,local_right);
|
||||
assert(area(lset.geomBounds) >= 0.0f);
|
||||
assert(area(rset.geomBounds) >= 0.0f);
|
||||
}
|
||||
@@ -153,15 +182,15 @@ namespace embree
|
||||
const size_t end = set.end();
|
||||
const size_t center = (begin + end)/2;
|
||||
|
||||
CentGeomBBox3fa left; left.reset();
|
||||
CentGeomBBox3fa left(empty);
|
||||
for (size_t i=begin; i<center; i++)
|
||||
left.extend(prims[i].bounds());
|
||||
new (&lset) PrimInfoRange(begin,center,left.geomBounds,left.centBounds);
|
||||
left.extend_center2(prims[i]);
|
||||
new (&lset) PrimInfoRange(begin,center,left);
|
||||
|
||||
CentGeomBBox3fa right; right.reset();
|
||||
CentGeomBBox3fa right(empty);
|
||||
for (size_t i=center; i<end; i++)
|
||||
right.extend(prims[i].bounds());
|
||||
new (&rset) PrimInfoRange(center,end,right.geomBounds,right.centBounds);
|
||||
right.extend_center2(prims[i]);
|
||||
new (&rset) PrimInfoRange(center,end,right);
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -197,7 +226,7 @@ namespace embree
|
||||
const NativeCurves* mesh = scene->get<NativeCurves>(geomID);
|
||||
|
||||
const unsigned num_time_segments = mesh->numTimeSegments();
|
||||
const range<int> tbounds = getTimeSegmentRange(set.time_range, num_time_segments);
|
||||
const range<int> tbounds = getTimeSegmentRange(set.time_range, (float)num_time_segments);
|
||||
if (tbounds.size() == 0) continue;
|
||||
|
||||
const size_t t = (tbounds.begin()+tbounds.end())/2;
|
||||
@@ -214,13 +243,51 @@ namespace embree
|
||||
return frame(axis0).transposed();
|
||||
}
|
||||
|
||||
struct BinBoundsAndCenter
|
||||
{
|
||||
__forceinline BinBoundsAndCenter(Scene* scene, BBox1f time_range, const LinearSpace3fa& space)
|
||||
: scene(scene), time_range(time_range), space(space) {}
|
||||
|
||||
/*! returns center for binning */
|
||||
template<typename PrimRef>
|
||||
__forceinline Vec3fa binCenter(const PrimRef& ref) const
|
||||
{
|
||||
NativeCurves* mesh = scene->get<NativeCurves>(ref.geomID());
|
||||
LBBox3fa lbounds = mesh->linearBounds(space,ref.primID(),time_range);
|
||||
return center2(lbounds.interpolate(0.5f));
|
||||
}
|
||||
|
||||
/*! returns bounds and centroid used for binning */
|
||||
__noinline void binBoundsAndCenter (const PrimRefMB& ref, BBox3fa& bounds_o, Vec3fa& center_o) const // __noinline is workaround for ICC16 bug under MacOSX
|
||||
{
|
||||
NativeCurves* mesh = scene->get<NativeCurves>(ref.geomID());
|
||||
LBBox3fa lbounds = mesh->linearBounds(space,ref.primID(),time_range);
|
||||
bounds_o = lbounds.interpolate(0.5f);
|
||||
center_o = center2(bounds_o);
|
||||
}
|
||||
|
||||
/*! returns bounds and centroid used for binning */
|
||||
__noinline void binBoundsAndCenter (const PrimRefMB& ref, LBBox3fa& bounds_o, Vec3fa& center_o) const // __noinline is workaround for ICC16 bug under MacOSX
|
||||
{
|
||||
NativeCurves* mesh = scene->get<NativeCurves>(ref.geomID());
|
||||
LBBox3fa lbounds = mesh->linearBounds(space,ref.primID(),time_range);
|
||||
bounds_o = lbounds;
|
||||
center_o = center2(lbounds.interpolate(0.5f));
|
||||
}
|
||||
|
||||
private:
|
||||
Scene* scene;
|
||||
BBox1f time_range;
|
||||
const LinearSpace3fa space;
|
||||
};
|
||||
|
||||
/*! finds the best split */
|
||||
const Split find(const SetMB& set, const size_t logBlockSize, const LinearSpace3fa& space)
|
||||
{
|
||||
UserPrimRefData user(scene,set.time_range);
|
||||
BinBoundsAndCenter binBoundsAndCenter(scene,set.time_range,space);
|
||||
ObjectBinner binner(empty);
|
||||
const BinMapping<BINS> mapping(set.size(),set.centBounds);
|
||||
bin_parallel(binner,set.prims->data(),set.object_range.begin(),set.object_range.end(),PARALLEL_FIND_BLOCK_SIZE,PARALLEL_THRESHOLD,mapping,space,&user);
|
||||
bin_parallel(binner,set.prims->data(),set.object_range.begin(),set.object_range.end(),PARALLEL_FIND_BLOCK_SIZE,PARALLEL_THRESHOLD,mapping,binBoundsAndCenter);
|
||||
Split osplit = binner.best(mapping,logBlockSize);
|
||||
osplit.sah *= set.time_range.size();
|
||||
if (!osplit.valid()) osplit.data = Split::SPLIT_FALLBACK; // use fallback split
|
||||
@@ -230,14 +297,14 @@ namespace embree
|
||||
/*! array partitioning */
|
||||
__forceinline void split(const Split& split, const LinearSpace3fa& space, const SetMB& set, SetMB& lset, SetMB& rset)
|
||||
{
|
||||
UserPrimRefData user(scene,set.time_range);
|
||||
BinBoundsAndCenter binBoundsAndCenter(scene,set.time_range,space);
|
||||
const size_t begin = set.object_range.begin();
|
||||
const size_t end = set.object_range.end();
|
||||
PrimInfoMB left = empty;
|
||||
PrimInfoMB right = empty;
|
||||
const vint4 vSplitPos(split.pos);
|
||||
const vbool4 vSplitMask(1 << split.dim);
|
||||
auto isLeft = [&] (const PrimRefMB &ref) { return any(((vint4)split.mapping.bin_unsafe(ref,space,&user) < vSplitPos) & vSplitMask); };
|
||||
auto isLeft = [&] (const PrimRefMB &ref) { return any(((vint4)split.mapping.bin_unsafe(ref,binBoundsAndCenter) < vSplitPos) & vSplitMask); };
|
||||
auto reduction = [] (PrimInfoMB& pinfo, const PrimRefMB& ref) { pinfo.add_primref(ref); };
|
||||
auto reduction2 = [] (PrimInfoMB& pinfo0,const PrimInfoMB& pinfo1) { pinfo0.merge(pinfo1); };
|
||||
size_t center = parallel_partitioning(set.prims->data(),begin,end,EmptyTy(),left,right,isLeft,reduction,reduction2,PARALLEL_PARTITION_BLOCK_SIZE,PARALLEL_THRESHOLD);
|
||||
|
||||
@@ -0,0 +1,456 @@
|
||||
// ======================================================================== //
|
||||
// Copyright 2009-2017 Intel Corporation //
|
||||
// //
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); //
|
||||
// you may not use this file except in compliance with the License. //
|
||||
// You may obtain a copy of the License at //
|
||||
// //
|
||||
// http://www.apache.org/licenses/LICENSE-2.0 //
|
||||
// //
|
||||
// Unless required by applicable law or agreed to in writing, software //
|
||||
// distributed under the License is distributed on an "AS IS" BASIS, //
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
|
||||
// See the License for the specific language governing permissions and //
|
||||
// limitations under the License. //
|
||||
// ======================================================================== //
|
||||
|
||||
// TODO:
|
||||
// - adjust parallel build thresholds
|
||||
// - openNodesBasedOnExtend should consider max extended size
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "heuristic_binning.h"
|
||||
#include "heuristic_spatial.h"
|
||||
|
||||
/* stop opening of all bref.geomIDs are the same */
|
||||
#define EQUAL_GEOMID_STOP_CRITERIA 1
|
||||
|
||||
/* 10% spatial extend threshold */
|
||||
#define MAX_EXTEND_THRESHOLD 0.1f
|
||||
|
||||
/* maximum is 8 children */
|
||||
#define MAX_OPENED_CHILD_NODES 8
|
||||
|
||||
/* open until all build refs are below threshold size in one step */
|
||||
#define USE_LOOP_OPENING 0
|
||||
|
||||
namespace embree
|
||||
{
|
||||
namespace isa
|
||||
{
|
||||
/*! Performs standard object binning */
|
||||
template<typename NodeOpenerFunc, typename PrimRef, size_t OBJECT_BINS>
|
||||
struct HeuristicArrayOpenMergeSAH
|
||||
{
|
||||
typedef BinSplit<OBJECT_BINS> Split;
|
||||
typedef BinInfoT<OBJECT_BINS,PrimRef,BBox3fa> Binner;
|
||||
|
||||
static const size_t PARALLEL_THRESHOLD = 1024;
|
||||
static const size_t PARALLEL_FIND_BLOCK_SIZE = 512;
|
||||
static const size_t PARALLEL_PARTITION_BLOCK_SIZE = 128;
|
||||
|
||||
static const size_t MOVE_STEP_SIZE = 64;
|
||||
static const size_t CREATE_SPLITS_STEP_SIZE = 128;
|
||||
|
||||
__forceinline HeuristicArrayOpenMergeSAH ()
|
||||
: prims0(nullptr) {}
|
||||
|
||||
/*! remember prim array */
|
||||
__forceinline HeuristicArrayOpenMergeSAH (const NodeOpenerFunc& nodeOpenerFunc, PrimRef* prims0, size_t max_open_size)
|
||||
: prims0(prims0), nodeOpenerFunc(nodeOpenerFunc), max_open_size(max_open_size)
|
||||
{
|
||||
assert(max_open_size <= MAX_OPENED_CHILD_NODES);
|
||||
}
|
||||
|
||||
struct OpenHeuristic
|
||||
{
|
||||
__forceinline OpenHeuristic( const PrimInfoExtRange& pinfo )
|
||||
{
|
||||
const Vec3fa diag = pinfo.geomBounds.size();
|
||||
dim = maxDim(diag);
|
||||
assert(diag[dim] > 0.0f);
|
||||
inv_max_extend = 1.0f / diag[dim];
|
||||
}
|
||||
|
||||
__forceinline bool operator () ( PrimRef& prim ) const {
|
||||
return !prim.node.isLeaf() && prim.bounds().size()[dim] * inv_max_extend > MAX_EXTEND_THRESHOLD;
|
||||
}
|
||||
|
||||
private:
|
||||
size_t dim;
|
||||
float inv_max_extend;
|
||||
};
|
||||
|
||||
/*! compute extended ranges */
|
||||
__forceinline void setExtentedRanges(const PrimInfoExtRange& set, PrimInfoExtRange& lset, PrimInfoExtRange& rset, const size_t lweight, const size_t rweight)
|
||||
{
|
||||
assert(set.ext_range_size() > 0);
|
||||
const float left_factor = (float)lweight / (lweight + rweight);
|
||||
const size_t ext_range_size = set.ext_range_size();
|
||||
const size_t left_ext_range_size = min((size_t)(floorf(left_factor * ext_range_size)),ext_range_size);
|
||||
const size_t right_ext_range_size = ext_range_size - left_ext_range_size;
|
||||
lset.set_ext_range(lset.end() + left_ext_range_size);
|
||||
rset.set_ext_range(rset.end() + right_ext_range_size);
|
||||
}
|
||||
|
||||
/*! move ranges */
|
||||
__forceinline void moveExtentedRange(const PrimInfoExtRange& set, const PrimInfoExtRange& lset, PrimInfoExtRange& rset)
|
||||
{
|
||||
const size_t left_ext_range_size = lset.ext_range_size();
|
||||
const size_t right_size = rset.size();
|
||||
|
||||
/* has the left child an extended range? */
|
||||
if (left_ext_range_size > 0)
|
||||
{
|
||||
/* left extended range smaller than right range ? */
|
||||
if (left_ext_range_size < right_size)
|
||||
{
|
||||
/* only move a small part of the beginning of the right range to the end */
|
||||
parallel_for( rset.begin(), rset.begin()+left_ext_range_size, MOVE_STEP_SIZE, [&](const range<size_t>& r) {
|
||||
for (size_t i=r.begin(); i<r.end(); i++)
|
||||
prims0[i+right_size] = prims0[i];
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
/* no overlap, move entire right range to new location, can be made fully parallel */
|
||||
parallel_for( rset.begin(), rset.end(), MOVE_STEP_SIZE, [&](const range<size_t>& r) {
|
||||
for (size_t i=r.begin(); i<r.end(); i++)
|
||||
prims0[i+left_ext_range_size] = prims0[i];
|
||||
});
|
||||
}
|
||||
/* update right range */
|
||||
assert(rset.ext_end() + left_ext_range_size == set.ext_end());
|
||||
rset.move_right(left_ext_range_size);
|
||||
}
|
||||
}
|
||||
|
||||
/* estimates the extra space required when opening, and checks if all primitives are from same geometry */
|
||||
__noinline std::pair<size_t,bool> getProperties(const PrimInfoExtRange& set)
|
||||
{
|
||||
const OpenHeuristic heuristic(set);
|
||||
const unsigned int geomID = prims0[set.begin()].geomID();
|
||||
|
||||
auto body = [&] (const range<size_t>& r) -> std::pair<size_t,bool> {
|
||||
bool commonGeomID = true;
|
||||
size_t opens = 0;
|
||||
for (size_t i=r.begin(); i<r.end(); i++) {
|
||||
commonGeomID &= prims0[i].geomID() == geomID;
|
||||
if (heuristic(prims0[i]))
|
||||
opens += prims0[i].node.getN()-1; // coarse approximation
|
||||
}
|
||||
return std::pair<size_t,bool>(opens,commonGeomID);
|
||||
};
|
||||
auto reduction = [&] (const std::pair<size_t,bool>& b0, const std::pair<size_t,bool>& b1) -> std::pair<size_t,bool> {
|
||||
return std::pair<size_t,bool>(b0.first+b1.first,b0.second && b1.second);
|
||||
};
|
||||
return parallel_reduce(set.begin(),set.end(),PARALLEL_FIND_BLOCK_SIZE,PARALLEL_THRESHOLD,std::pair<size_t,bool>(0,true),body,reduction);
|
||||
}
|
||||
|
||||
// FIXME: should consider maximum available extended size
|
||||
__noinline void openNodesBasedOnExtend(PrimInfoExtRange& set)
|
||||
{
|
||||
const OpenHeuristic heuristic(set);
|
||||
const size_t ext_range_start = set.end();
|
||||
|
||||
if (false && set.size() < PARALLEL_THRESHOLD)
|
||||
{
|
||||
size_t extra_elements = 0;
|
||||
for (size_t i=set.begin(); i<set.end(); i++)
|
||||
{
|
||||
if (heuristic(prims0[i]))
|
||||
{
|
||||
PrimRef tmp[MAX_OPENED_CHILD_NODES];
|
||||
const size_t n = nodeOpenerFunc(prims0[i],tmp);
|
||||
assert(extra_elements + n-1 <= set.ext_range_size());
|
||||
for (size_t j=0; j<n; j++)
|
||||
set.extend_center2(tmp[j]);
|
||||
|
||||
prims0[i] = tmp[0];
|
||||
for (size_t j=1; j<n; j++)
|
||||
prims0[ext_range_start+extra_elements+j-1] = tmp[j];
|
||||
extra_elements += n-1;
|
||||
}
|
||||
}
|
||||
set._end += extra_elements;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::atomic<size_t> ext_elements;
|
||||
ext_elements.store(0);
|
||||
PrimInfo info = parallel_reduce( set.begin(), set.end(), CREATE_SPLITS_STEP_SIZE, PrimInfo(empty), [&](const range<size_t>& r) -> PrimInfo {
|
||||
PrimInfo info(empty);
|
||||
for (size_t i=r.begin(); i<r.end(); i++)
|
||||
if (heuristic(prims0[i]))
|
||||
{
|
||||
PrimRef tmp[MAX_OPENED_CHILD_NODES];
|
||||
const size_t n = nodeOpenerFunc(prims0[i],tmp);
|
||||
const size_t ID = ext_elements.fetch_add(n-1);
|
||||
assert(ID + n-1 <= set.ext_range_size());
|
||||
|
||||
for (size_t j=0; j<n; j++)
|
||||
info.extend_center2(tmp[j]);
|
||||
|
||||
prims0[i] = tmp[0];
|
||||
for (size_t j=1; j<n; j++)
|
||||
prims0[ext_range_start+ID+j-1] = tmp[j];
|
||||
}
|
||||
return info;
|
||||
}, [] (const PrimInfo& a, const PrimInfo& b) { return PrimInfo::merge(a,b); });
|
||||
set.centBounds.extend(info.centBounds);
|
||||
assert(ext_elements.load() <= set.ext_range_size());
|
||||
set._end += ext_elements.load();
|
||||
}
|
||||
}
|
||||
|
||||
__noinline void openNodesBasedOnExtendLoop(PrimInfoExtRange& set, const size_t est_new_elements)
|
||||
{
|
||||
const OpenHeuristic heuristic(set);
|
||||
size_t next_iteration_extra_elements = est_new_elements;
|
||||
|
||||
while (next_iteration_extra_elements <= set.ext_range_size())
|
||||
{
|
||||
next_iteration_extra_elements = 0;
|
||||
size_t extra_elements = 0;
|
||||
const size_t ext_range_start = set.end();
|
||||
|
||||
for (size_t i=set.begin(); i<set.end(); i++)
|
||||
{
|
||||
if (heuristic(prims0[i]))
|
||||
{
|
||||
PrimRef tmp[MAX_OPENED_CHILD_NODES];
|
||||
const size_t n = nodeOpenerFunc(prims0[i],tmp);
|
||||
assert(extra_elements + n-1 <= set.ext_range_size());
|
||||
for (size_t j=0;j<n;j++)
|
||||
set.extend_center2(tmp[j]);
|
||||
|
||||
prims0[i] = tmp[0];
|
||||
for (size_t j=1;j<n;j++)
|
||||
prims0[ext_range_start+extra_elements+j-1] = tmp[j];
|
||||
extra_elements += n-1;
|
||||
|
||||
for (size_t j=0; j<n; j++)
|
||||
if (heuristic(tmp[j]))
|
||||
next_iteration_extra_elements += tmp[j].node.getN()-1; // coarse approximation
|
||||
|
||||
}
|
||||
}
|
||||
assert( extra_elements <= set.ext_range_size());
|
||||
set._end += extra_elements;
|
||||
|
||||
for (size_t i=set.begin();i<set.end();i++)
|
||||
assert(prims0[i].numPrimitives() > 0);
|
||||
|
||||
if (unlikely(next_iteration_extra_elements == 0)) break;
|
||||
}
|
||||
}
|
||||
|
||||
__noinline const Split find(PrimInfoExtRange& set, const size_t logBlockSize)
|
||||
{
|
||||
/* single element */
|
||||
if (set.size() <= 1)
|
||||
return Split();
|
||||
|
||||
/* disable opening if there is no overlap */
|
||||
const size_t D = 4;
|
||||
if (unlikely(set.has_ext_range() && set.size() <= D))
|
||||
{
|
||||
bool disjoint = true;
|
||||
for (size_t j=set.begin(); j<set.end()-1; j++) {
|
||||
for (size_t i=set.begin()+1; i<set.end(); i++) {
|
||||
if (conjoint(prims0[j].bounds(),prims0[i].bounds())) {
|
||||
disjoint = false; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (disjoint) set.set_ext_range(set.end()); /* disables opening */
|
||||
}
|
||||
|
||||
std::pair<size_t,bool> p(0,false);
|
||||
|
||||
/* disable opening when all primitives are from same geometry */
|
||||
if (unlikely(set.has_ext_range()))
|
||||
{
|
||||
p = getProperties(set);
|
||||
#if EQUAL_GEOMID_STOP_CRITERIA == 1
|
||||
if (p.second) set.set_ext_range(set.end()); /* disable opening */
|
||||
#endif
|
||||
}
|
||||
|
||||
/* open nodes when we have sufficient space available */
|
||||
if (unlikely(set.has_ext_range()))
|
||||
{
|
||||
#if USE_LOOP_OPENING == 1
|
||||
openNodesBasedOnExtendLoop(set,p.first);
|
||||
#else
|
||||
if (p.first <= set.ext_range_size())
|
||||
openNodesBasedOnExtend(set);
|
||||
#endif
|
||||
|
||||
/* disable opening when unsufficient space for opening a node available */
|
||||
if (set.ext_range_size() < max_open_size-1)
|
||||
set.set_ext_range(set.end()); /* disable opening */
|
||||
}
|
||||
|
||||
/* find best split */
|
||||
return object_find(set,logBlockSize);
|
||||
}
|
||||
|
||||
|
||||
/*! finds the best object split */
|
||||
__forceinline const Split object_find(const PrimInfoExtRange& set,const size_t logBlockSize)
|
||||
{
|
||||
if (set.size() < PARALLEL_THRESHOLD) return sequential_object_find(set,logBlockSize);
|
||||
else return parallel_object_find (set,logBlockSize);
|
||||
}
|
||||
|
||||
/*! finds the best object split */
|
||||
__noinline const Split sequential_object_find(const PrimInfoExtRange& set, const size_t logBlockSize)
|
||||
{
|
||||
Binner binner(empty);
|
||||
const BinMapping<OBJECT_BINS> mapping(set.centBounds);
|
||||
binner.bin(prims0,set.begin(),set.end(),mapping);
|
||||
return binner.best(mapping,logBlockSize);
|
||||
}
|
||||
|
||||
/*! finds the best split */
|
||||
__noinline const Split parallel_object_find(const PrimInfoExtRange& set, const size_t logBlockSize)
|
||||
{
|
||||
Binner binner(empty);
|
||||
const BinMapping<OBJECT_BINS> mapping(set.centBounds);
|
||||
const BinMapping<OBJECT_BINS>& _mapping = mapping; // CLANG 3.4 parser bug workaround
|
||||
auto body = [&] (const range<size_t>& r) -> Binner {
|
||||
Binner binner(empty); binner.bin(prims0+r.begin(),r.size(),_mapping); return binner;
|
||||
};
|
||||
auto reduction = [&] (const Binner& b0, const Binner& b1) -> Binner {
|
||||
Binner r = b0; r.merge(b1,_mapping.size()); return r;
|
||||
};
|
||||
binner = parallel_reduce(set.begin(),set.end(),PARALLEL_FIND_BLOCK_SIZE,binner,body,reduction);
|
||||
return binner.best(mapping,logBlockSize);
|
||||
}
|
||||
|
||||
/*! array partitioning */
|
||||
__noinline void split(const Split& split, const PrimInfoExtRange& set_i, PrimInfoExtRange& lset, PrimInfoExtRange& rset)
|
||||
{
|
||||
PrimInfoExtRange set = set_i;
|
||||
|
||||
/* valid split */
|
||||
if (unlikely(!split.valid())) {
|
||||
deterministic_order(set);
|
||||
splitFallback(set,lset,rset);
|
||||
return;
|
||||
}
|
||||
|
||||
std::pair<size_t,size_t> ext_weights(0,0);
|
||||
|
||||
/* object split */
|
||||
if (likely(set.size() < PARALLEL_THRESHOLD))
|
||||
ext_weights = sequential_object_split(split,set,lset,rset);
|
||||
else
|
||||
ext_weights = parallel_object_split(split,set,lset,rset);
|
||||
|
||||
/* if we have an extended range, set extended child ranges and move right split range */
|
||||
if (unlikely(set.has_ext_range()))
|
||||
{
|
||||
setExtentedRanges(set,lset,rset,ext_weights.first,ext_weights.second);
|
||||
moveExtentedRange(set,lset,rset);
|
||||
}
|
||||
}
|
||||
|
||||
/*! array partitioning */
|
||||
std::pair<size_t,size_t> sequential_object_split(const Split& split, const PrimInfoExtRange& set, PrimInfoExtRange& lset, PrimInfoExtRange& rset)
|
||||
{
|
||||
const size_t begin = set.begin();
|
||||
const size_t end = set.end();
|
||||
PrimInfo local_left(empty);
|
||||
PrimInfo local_right(empty);
|
||||
const unsigned int splitPos = split.pos;
|
||||
const unsigned int splitDim = split.dim;
|
||||
const unsigned int splitDimMask = (unsigned int)1 << splitDim;
|
||||
|
||||
const vint4 vSplitPos(splitPos);
|
||||
const vbool4 vSplitMask( (int)splitDimMask );
|
||||
|
||||
size_t center = serial_partitioning(prims0,
|
||||
begin,end,local_left,local_right,
|
||||
[&] (const PrimRef& ref) { return split.mapping.bin_unsafe(ref,vSplitPos,vSplitMask); },
|
||||
[] (PrimInfo& pinfo,const PrimRef& ref) { pinfo.add_center2(ref); });
|
||||
|
||||
new (&lset) PrimInfoExtRange(begin,center,center,local_left);
|
||||
new (&rset) PrimInfoExtRange(center,end,end,local_right);
|
||||
assert(area(lset.geomBounds) >= 0.0f);
|
||||
assert(area(rset.geomBounds) >= 0.0f);
|
||||
return std::pair<size_t,size_t>(local_left.size(),local_right.size());
|
||||
}
|
||||
|
||||
/*! array partitioning */
|
||||
__noinline std::pair<size_t,size_t> parallel_object_split(const Split& split, const PrimInfoExtRange& set, PrimInfoExtRange& lset, PrimInfoExtRange& rset)
|
||||
{
|
||||
const size_t begin = set.begin();
|
||||
const size_t end = set.end();
|
||||
PrimInfo left(empty);
|
||||
PrimInfo right(empty);
|
||||
const unsigned int splitPos = split.pos;
|
||||
const unsigned int splitDim = split.dim;
|
||||
const unsigned int splitDimMask = (unsigned int)1 << splitDim;
|
||||
|
||||
const vint4 vSplitPos(splitPos);
|
||||
const vbool4 vSplitMask( (int)splitDimMask );
|
||||
auto isLeft = [&] (const PrimRef& ref) { return split.mapping.bin_unsafe(ref,vSplitPos,vSplitMask); };
|
||||
|
||||
const size_t center = parallel_partitioning(
|
||||
prims0,begin,end,EmptyTy(),left,right,isLeft,
|
||||
[] (PrimInfo& pinfo,const PrimRef& ref) { pinfo.add_center2(ref); },
|
||||
[] (PrimInfo& pinfo0,const PrimInfo& pinfo1) { pinfo0.merge(pinfo1); },
|
||||
PARALLEL_PARTITION_BLOCK_SIZE);
|
||||
|
||||
new (&lset) PrimInfoExtRange(begin,center,center,left);
|
||||
new (&rset) PrimInfoExtRange(center,end,end,right);
|
||||
assert(area(lset.geomBounds) >= 0.0f);
|
||||
assert(area(rset.geomBounds) >= 0.0f);
|
||||
|
||||
return std::pair<size_t,size_t>(left.size(),right.size());
|
||||
}
|
||||
|
||||
void deterministic_order(const extended_range<size_t>& set)
|
||||
{
|
||||
/* required as parallel partition destroys original primitive order */
|
||||
std::sort(&prims0[set.begin()],&prims0[set.end()]);
|
||||
}
|
||||
|
||||
__forceinline void splitFallback(const PrimInfoExtRange& set, PrimInfoExtRange& lset, PrimInfoExtRange& rset)
|
||||
{
|
||||
const size_t begin = set.begin();
|
||||
const size_t end = set.end();
|
||||
const size_t center = (begin + end)/2;
|
||||
|
||||
PrimInfo left(empty);
|
||||
for (size_t i=begin; i<center; i++)
|
||||
left.add_center2(prims0[i]);
|
||||
|
||||
const size_t lweight = left.end;
|
||||
|
||||
PrimInfo right(empty);
|
||||
for (size_t i=center; i<end; i++)
|
||||
right.add_center2(prims0[i]);
|
||||
|
||||
const size_t rweight = right.end;
|
||||
new (&lset) PrimInfoExtRange(begin,center,center,left);
|
||||
new (&rset) PrimInfoExtRange(center,end,end,right);
|
||||
|
||||
/* if we have an extended range */
|
||||
if (set.has_ext_range())
|
||||
{
|
||||
setExtentedRanges(set,lset,rset,lweight,rweight);
|
||||
moveExtentedRange(set,lset,rset);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
PrimRef* const prims0;
|
||||
const NodeOpenerFunc& nodeOpenerFunc;
|
||||
size_t max_open_size;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -35,9 +35,9 @@ namespace embree
|
||||
{
|
||||
const vfloat4 lower = (vfloat4) pinfo.geomBounds.lower;
|
||||
const vfloat4 upper = (vfloat4) pinfo.geomBounds.upper;
|
||||
const vbool4 ulpsized = upper - lower <= max(vfloat4(1E-19f),128.0f*vfloat4(ulp)*max(abs(lower),abs(upper)));
|
||||
const vfloat4 diag = (vfloat4) pinfo.geomBounds.size();
|
||||
scale = select(ulpsized,vfloat4(0.0f),vfloat4(BINS)/diag);
|
||||
const vfloat4 eps = 128.0f*vfloat4(ulp)*max(abs(lower),abs(upper));
|
||||
const vfloat4 diag = max(eps,(vfloat4) pinfo.geomBounds.size());
|
||||
scale = select(upper-lower <= eps,vfloat4(0.0f),vfloat4(BINS)/diag);
|
||||
ofs = (vfloat4) pinfo.geomBounds.lower;
|
||||
inv_scale = 1.0f / scale;
|
||||
}
|
||||
@@ -149,14 +149,15 @@ namespace embree
|
||||
const size_t beginID,
|
||||
const size_t endID,
|
||||
const size_t binID,
|
||||
const BBox3fa &b)
|
||||
const BBox3fa &b,
|
||||
const size_t n = 1)
|
||||
{
|
||||
assert(beginID < BINS);
|
||||
assert(endID < BINS);
|
||||
assert(binID < BINS);
|
||||
|
||||
numBegin[beginID][dim]++;
|
||||
numEnd [endID][dim]++;
|
||||
numBegin[beginID][dim]+=(unsigned int)n;
|
||||
numEnd [endID][dim]+=(unsigned int)n;
|
||||
bounds [binID][dim].extend(b);
|
||||
}
|
||||
|
||||
@@ -278,6 +279,41 @@ namespace embree
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*! bins an array of primitives */
|
||||
__forceinline void binSubTreeRefs(const PrimRef* source, size_t begin, size_t end, const SpatialBinMapping<BINS>& mapping)
|
||||
{
|
||||
for (size_t i=begin; i<end; i++)
|
||||
{
|
||||
const PrimRef &prim = source[i];
|
||||
const vint4 bin0 = mapping.bin(prim.bounds().lower);
|
||||
const vint4 bin1 = mapping.bin(prim.bounds().upper);
|
||||
|
||||
for (size_t dim=0; dim<3; dim++)
|
||||
{
|
||||
if (unlikely(mapping.invalid(dim)))
|
||||
continue;
|
||||
|
||||
const size_t l = bin0[dim];
|
||||
const size_t r = bin1[dim];
|
||||
|
||||
const unsigned int n = prim.primID();
|
||||
|
||||
// same bin optimization
|
||||
if (likely(l == r))
|
||||
{
|
||||
add(dim,l,l,l,prim.bounds(),n);
|
||||
continue;
|
||||
}
|
||||
const size_t bin_start = bin0[dim];
|
||||
const size_t bin_end = bin1[dim];
|
||||
for (size_t bin=bin_start; bin<bin_end; bin++)
|
||||
add(dim,l,r,bin,prim.bounds(),n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*! merges in other binning information */
|
||||
void merge (const SpatialBinInfo& other)
|
||||
@@ -308,7 +344,7 @@ namespace embree
|
||||
}
|
||||
|
||||
/*! finds the best split by scanning binning information */
|
||||
SpatialBinSplit<BINS> best(const SpatialBinMapping<BINS>& mapping, const size_t blocks_shift, const size_t maxCount = (size_t)-1) const
|
||||
SpatialBinSplit<BINS> best(const SpatialBinMapping<BINS>& mapping, const size_t blocks_shift) const
|
||||
{
|
||||
/* sweep from right to left and compute parallel prefix of merged bounds */
|
||||
vfloat4 rAreas[BINS];
|
||||
@@ -359,7 +395,7 @@ namespace embree
|
||||
continue;
|
||||
|
||||
/* test if this is a better dimension */
|
||||
if (vbestSAH[dim] < bestSAH && vbestPos[dim] != 0 /* && (vbestlCount[dim]+vbestrCount[dim]<=(int)maxCount) */) {
|
||||
if (vbestSAH[dim] < bestSAH && vbestPos[dim] != 0) {
|
||||
bestDim = dim;
|
||||
bestPos = vbestPos[dim];
|
||||
bestSAH = vbestSAH[dim];
|
||||
|
||||
@@ -41,8 +41,8 @@ namespace embree
|
||||
__forceinline PrimInfoExtRange(EmptyTy)
|
||||
: CentGeomBBox3fa(EmptyTy()), extended_range<size_t>(0,0,0) {}
|
||||
|
||||
__forceinline PrimInfoExtRange(size_t begin, size_t end, size_t ext_end, const BBox3fa& geomBounds, const BBox3fa& centBounds)
|
||||
: CentGeomBBox3fa(geomBounds,centBounds), extended_range<size_t>(begin,end,ext_end) {}
|
||||
__forceinline PrimInfoExtRange(size_t begin, size_t end, size_t ext_end, const CentGeomBBox3fa& centGeomBounds)
|
||||
: CentGeomBBox3fa(centGeomBounds), extended_range<size_t>(begin,end,ext_end) {}
|
||||
|
||||
__forceinline float leafSAH() const {
|
||||
return expectedApproxHalfArea(geomBounds)*float(size());
|
||||
@@ -404,13 +404,12 @@ namespace embree
|
||||
[&] (const PrimRef& ref) {
|
||||
return split.mapping.bin_unsafe(ref,vSplitPos,vSplitMask);
|
||||
},
|
||||
[] (PrimInfo& pinfo,const PrimRef& ref) { pinfo.add(ref.bounds(),ref.lower.a >> 24); });
|
||||
|
||||
[] (PrimInfo& pinfo,const PrimRef& ref) { pinfo.add_center2(ref,ref.lower.a >> 24); });
|
||||
const size_t left_weight = local_left.end;
|
||||
const size_t right_weight = local_right.end;
|
||||
|
||||
new (&lset) PrimInfoExtRange(begin,center,center,local_left.geomBounds,local_left.centBounds);
|
||||
new (&rset) PrimInfoExtRange(center,end,end,local_right.geomBounds,local_right.centBounds);
|
||||
new (&lset) PrimInfoExtRange(begin,center,center,local_left);
|
||||
new (&rset) PrimInfoExtRange(center,end,end,local_right);
|
||||
|
||||
assert(area(lset.geomBounds) >= 0.0f);
|
||||
assert(area(rset.geomBounds) >= 0.0f);
|
||||
@@ -430,7 +429,7 @@ namespace embree
|
||||
const unsigned int splitDimMask = (unsigned int)1 << splitDim;
|
||||
|
||||
/* init spatial mapping */
|
||||
const SpatialBinMapping<SPATIAL_BINS> mapping = split.mapping;
|
||||
const SpatialBinMapping<SPATIAL_BINS> &mapping = split.mapping;
|
||||
const vint4 vSplitPos(splitPos);
|
||||
const vbool4 vSplitMask( (int)splitDimMask );
|
||||
|
||||
@@ -440,13 +439,13 @@ namespace embree
|
||||
const Vec3fa c = ref.bounds().center();
|
||||
return any(((vint4)mapping.bin(c) < vSplitPos) & vSplitMask);
|
||||
},
|
||||
[] (PrimInfo& pinfo,const PrimRef& ref) { pinfo.add(ref.bounds(),ref.lower.a >> 24); });
|
||||
[] (PrimInfo& pinfo,const PrimRef& ref) { pinfo.add_center2(ref,ref.lower.a >> 24); });
|
||||
|
||||
const size_t left_weight = local_left.end;
|
||||
const size_t right_weight = local_right.end;
|
||||
|
||||
new (&lset) PrimInfoExtRange(begin,center,center,local_left.geomBounds,local_left.centBounds);
|
||||
new (&rset) PrimInfoExtRange(center,end,end,local_right.geomBounds,local_right.centBounds);
|
||||
new (&lset) PrimInfoExtRange(begin,center,center,local_left);
|
||||
new (&rset) PrimInfoExtRange(center,end,end,local_right);
|
||||
assert(area(lset.geomBounds) >= 0.0f);
|
||||
assert(area(rset.geomBounds) >= 0.0f);
|
||||
return std::pair<size_t,size_t>(left_weight,right_weight);
|
||||
@@ -459,8 +458,8 @@ namespace embree
|
||||
{
|
||||
const size_t begin = set.begin();
|
||||
const size_t end = set.end();
|
||||
PrimInfo left; left.reset();
|
||||
PrimInfo right; right.reset();
|
||||
PrimInfo left(empty);
|
||||
PrimInfo right(empty);
|
||||
const unsigned int splitPos = split.pos;
|
||||
const unsigned int splitDim = split.dim;
|
||||
const unsigned int splitDimMask = (unsigned int)1 << splitDim;
|
||||
@@ -476,7 +475,7 @@ namespace embree
|
||||
|
||||
const size_t center = parallel_partitioning(
|
||||
prims0,begin,end,EmptyTy(),left,right,isLeft,
|
||||
[] (PrimInfo &pinfo,const PrimRef &ref) { pinfo.add(ref.bounds(),ref.lower.a >> 24); },
|
||||
[] (PrimInfo &pinfo,const PrimRef &ref) { pinfo.add_center2(ref,ref.lower.a >> 24); },
|
||||
[] (PrimInfo &pinfo0,const PrimInfo &pinfo1) { pinfo0.merge(pinfo1); },
|
||||
PARALLEL_PARTITION_BLOCK_SIZE);
|
||||
|
||||
@@ -486,8 +485,8 @@ namespace embree
|
||||
left.begin = begin; left.end = center;
|
||||
right.begin = center; right.end = end;
|
||||
|
||||
new (&lset) PrimInfoExtRange(begin,center,center,left.geomBounds,left.centBounds);
|
||||
new (&rset) PrimInfoExtRange(center,end,end,right.geomBounds,right.centBounds);
|
||||
new (&lset) PrimInfoExtRange(begin,center,center,left);
|
||||
new (&rset) PrimInfoExtRange(center,end,end,right);
|
||||
|
||||
assert(area(left.geomBounds) >= 0.0f);
|
||||
assert(area(right.geomBounds) >= 0.0f);
|
||||
@@ -499,8 +498,8 @@ namespace embree
|
||||
{
|
||||
const size_t begin = set.begin();
|
||||
const size_t end = set.end();
|
||||
PrimInfo left; left.reset();
|
||||
PrimInfo right; right.reset();
|
||||
PrimInfo left(empty);
|
||||
PrimInfo right(empty);
|
||||
const unsigned int splitPos = split.pos;
|
||||
const unsigned int splitDim = split.dim;
|
||||
const unsigned int splitDimMask = (unsigned int)1 << splitDim;
|
||||
@@ -516,7 +515,7 @@ namespace embree
|
||||
|
||||
const size_t center = parallel_partitioning(
|
||||
prims0,begin,end,EmptyTy(),left,right,isLeft,
|
||||
[] (PrimInfo &pinfo,const PrimRef &ref) { pinfo.add(ref.bounds(),ref.lower.a >> 24); },
|
||||
[] (PrimInfo &pinfo,const PrimRef &ref) { pinfo.add_center2(ref,ref.lower.a >> 24); },
|
||||
[] (PrimInfo &pinfo0,const PrimInfo &pinfo1) { pinfo0.merge(pinfo1); },
|
||||
PARALLEL_PARTITION_BLOCK_SIZE);
|
||||
|
||||
@@ -526,8 +525,8 @@ namespace embree
|
||||
left.begin = begin; left.end = center;
|
||||
right.begin = center; right.end = end;
|
||||
|
||||
new (&lset) PrimInfoExtRange(begin,center,center,left.geomBounds,left.centBounds);
|
||||
new (&rset) PrimInfoExtRange(center,end,end,right.geomBounds,right.centBounds);
|
||||
new (&lset) PrimInfoExtRange(begin,center,center,left);
|
||||
new (&rset) PrimInfoExtRange(center,end,end,right);
|
||||
|
||||
assert(area(left.geomBounds) >= 0.0f);
|
||||
assert(area(right.geomBounds) >= 0.0f);
|
||||
@@ -550,18 +549,18 @@ namespace embree
|
||||
|
||||
PrimInfo left(empty);
|
||||
for (size_t i=begin; i<center; i++) {
|
||||
left.add(prims0[i].bounds(),prims0[i].lower.a >> 24);
|
||||
left.add_center2(prims0[i],prims0[i].lower.a >> 24);
|
||||
}
|
||||
const size_t lweight = left.end;
|
||||
|
||||
PrimInfo right(empty);
|
||||
for (size_t i=center; i<end; i++) {
|
||||
right.add(prims0[i].bounds(),prims0[i].lower.a >> 24);
|
||||
right.add_center2(prims0[i],prims0[i].lower.a >> 24);
|
||||
}
|
||||
const size_t rweight = right.end;
|
||||
|
||||
new (&lset) PrimInfoExtRange(begin,center,center,left.geomBounds,left.centBounds);
|
||||
new (&rset) PrimInfoExtRange(center,end,end,right.geomBounds,right.centBounds);
|
||||
new (&lset) PrimInfoExtRange(begin,center,center,left);
|
||||
new (&rset) PrimInfoExtRange(center,end,end,right);
|
||||
|
||||
/* if we have an extended range */
|
||||
if (set.has_ext_range()) {
|
||||
|
||||
@@ -260,8 +260,8 @@ namespace embree
|
||||
|
||||
size_t center = serial_partitioning(prims,begin,end,local_left,local_right,primOnLeftSide,mergePrimBounds);
|
||||
|
||||
new (&lset) PrimInfoRange(begin,center,local_left.geomBounds,local_left.centBounds);
|
||||
new (&rset) PrimInfoRange(center,end,local_right.geomBounds,local_right.centBounds);
|
||||
new (&lset) PrimInfoRange(begin,center,local_left);
|
||||
new (&rset) PrimInfoRange(center,end,local_right);
|
||||
assert(area(lset.geomBounds) >= 0.0f);
|
||||
assert(area(rset.geomBounds) >= 0.0f);
|
||||
}
|
||||
@@ -284,16 +284,16 @@ namespace embree
|
||||
return cos0 > cos1;
|
||||
};
|
||||
|
||||
PrimInfo linfo; linfo.reset(); // FIXME: use CentGeomBBox3fa
|
||||
PrimInfo rinfo; rinfo.reset();
|
||||
CentGeomBBox3fa linfo(empty); // FIXME: use CentGeomBBox3fa
|
||||
CentGeomBBox3fa rinfo(empty);
|
||||
const size_t center = parallel_partitioning(
|
||||
prims,begin,end,EmptyTy(),linfo,rinfo,primOnLeftSide,
|
||||
[this] (PrimInfo &pinfo, const PrimRef& ref) { pinfo.add(bounds(ref)); },
|
||||
[] (PrimInfo &pinfo0,const PrimInfo& pinfo1) { pinfo0.merge(pinfo1); },
|
||||
[this] (CentGeomBBox3fa& pinfo, const PrimRef& ref) { pinfo.extend(bounds(ref)); },
|
||||
[] (CentGeomBBox3fa& pinfo0, const CentGeomBBox3fa& pinfo1) { pinfo0.merge(pinfo1); },
|
||||
PARALLEL_PARTITION_BLOCK_SIZE);
|
||||
|
||||
new (&lset) PrimInfoRange(begin,center,linfo.geomBounds,linfo.centBounds);
|
||||
new (&rset) PrimInfoRange(center,end,rinfo.geomBounds,rinfo.centBounds);
|
||||
new (&lset) PrimInfoRange(begin,center,linfo);
|
||||
new (&rset) PrimInfoRange(center,end,rinfo);
|
||||
}
|
||||
|
||||
void deterministic_order(const Set& set)
|
||||
@@ -308,15 +308,15 @@ namespace embree
|
||||
const size_t end = set.end();
|
||||
const size_t center = (begin + end)/2;
|
||||
|
||||
CentGeomBBox3fa left; left.reset();
|
||||
CentGeomBBox3fa left(empty);
|
||||
for (size_t i=begin; i<center; i++)
|
||||
left.extend(bounds(prims[i]));
|
||||
new (&lset) PrimInfoRange(begin,center,left.geomBounds,left.centBounds);
|
||||
new (&lset) PrimInfoRange(begin,center,left);
|
||||
|
||||
CentGeomBBox3fa right; right.reset();
|
||||
CentGeomBBox3fa right(empty);
|
||||
for (size_t i=center; i<end; i++)
|
||||
right.extend(bounds(prims[i]));
|
||||
new (&rset) PrimInfoRange(center,end,right.geomBounds,right.centBounds);
|
||||
new (&rset) PrimInfoRange(center,end,right);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -77,8 +77,8 @@ namespace embree
|
||||
bounds0[b].extend(bn0.interpolate(0.5f));
|
||||
bounds1[b].extend(bn1.interpolate(0.5f));
|
||||
#endif
|
||||
count0[b] += getTimeSegmentRange(dt0,prims[i].totalTimeSegments()).size();
|
||||
count1[b] += getTimeSegmentRange(dt1,prims[i].totalTimeSegments()).size();
|
||||
count0[b] += getTimeSegmentRange(dt0,(float)prims[i].totalTimeSegments()).size();
|
||||
count1[b] += getTimeSegmentRange(dt1,(float)prims[i].totalTimeSegments()).size();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -128,8 +128,8 @@ namespace embree
|
||||
const BBox1f dt1(center_time,time_range.upper);
|
||||
|
||||
/* calculate sah */
|
||||
const size_t lCount = (count0[b]+(1 << logBlockSize)-1) >> int(logBlockSize);
|
||||
const size_t rCount = (count1[b]+(1 << logBlockSize)-1) >> int(logBlockSize);
|
||||
const size_t lCount = (count0[b]+(size_t(1) << logBlockSize)-1) >> int(logBlockSize);
|
||||
const size_t rCount = (count1[b]+(size_t(1) << logBlockSize)-1) >> int(logBlockSize);
|
||||
const float sah0 = expectedApproxHalfArea(bounds0[b])*float(lCount)*dt0.size();
|
||||
const float sah1 = expectedApproxHalfArea(bounds1[b])*float(rCount)*dt1.size();
|
||||
const float sah = sah0+sah1;
|
||||
@@ -153,10 +153,10 @@ namespace embree
|
||||
const Split find(const SetMB& set, const size_t logBlockSize)
|
||||
{
|
||||
assert(set.object_range.size() > 0);
|
||||
unsigned numTimeSegments = set.max_num_time_segments;
|
||||
unsigned numTimeSegments = unsigned(set.max_num_time_segments);
|
||||
TemporalBinInfo binner(empty);
|
||||
binner.bin_parallel(set.prims->data(),set.object_range.begin(),set.object_range.end(),PARALLEL_FIND_BLOCK_SIZE,PARALLEL_THRESHOLD,set.time_range,numTimeSegments,recalculatePrimRef);
|
||||
Split tsplit = binner.best(logBlockSize,set.time_range,numTimeSegments);
|
||||
Split tsplit = binner.best((int)logBlockSize,set.time_range,numTimeSegments);
|
||||
if (!tsplit.valid()) tsplit.data = Split::SPLIT_FALLBACK; // use fallback split
|
||||
return tsplit;
|
||||
}
|
||||
|
||||
+25
-33
@@ -36,16 +36,6 @@ namespace embree
|
||||
__forceinline CentGeom (const BBox& geomBounds, const BBox3fa& centBounds)
|
||||
: geomBounds(geomBounds), centBounds(centBounds) {}
|
||||
|
||||
__forceinline void extend(const BBox& geomBounds_, const BBox3fa& centBounds_) {
|
||||
geomBounds.extend(geomBounds_);
|
||||
centBounds.extend(centBounds_);
|
||||
}
|
||||
|
||||
__forceinline void reset() {
|
||||
geomBounds = empty;
|
||||
centBounds = empty;
|
||||
}
|
||||
|
||||
template<typename PrimRef>
|
||||
__forceinline void extend_primref(const PrimRef& prim)
|
||||
{
|
||||
@@ -55,6 +45,14 @@ namespace embree
|
||||
centBounds.extend(center);
|
||||
}
|
||||
|
||||
template<typename PrimRef>
|
||||
__forceinline void extend_center2(const PrimRef& prim)
|
||||
{
|
||||
BBox3fa bounds = prim.bounds();
|
||||
geomBounds.extend(bounds);
|
||||
centBounds.extend(bounds.center2());
|
||||
}
|
||||
|
||||
__forceinline void extend(const BBox& geomBounds_) {
|
||||
geomBounds.extend(geomBounds_);
|
||||
centBounds.extend(center2(geomBounds_));
|
||||
@@ -90,16 +88,8 @@ namespace embree
|
||||
__forceinline PrimInfoT (EmptyTy)
|
||||
: CentGeom<BBox>(empty), begin(0), end(0) {}
|
||||
|
||||
__forceinline void reset() {
|
||||
CentGeom<BBox>::reset();
|
||||
begin = end = 0;
|
||||
}
|
||||
|
||||
__forceinline PrimInfoT (size_t num, const BBox& geomBounds, const BBox3fa& centBounds)
|
||||
: CentGeom<BBox>(geomBounds,centBounds), begin(0), end(num) {}
|
||||
|
||||
__forceinline PrimInfoT (size_t begin, size_t end, const BBox& geomBounds, const BBox3fa& centBounds)
|
||||
: CentGeom<BBox>(geomBounds,centBounds), begin(begin), end(end) {}
|
||||
__forceinline PrimInfoT (size_t begin, size_t end, const CentGeomBBox3fa& centGeomBounds)
|
||||
: CentGeom<BBox>(centGeomBounds), begin(begin), end(end) {}
|
||||
|
||||
template<typename PrimRef>
|
||||
__forceinline void add_primref(const PrimRef& prim)
|
||||
@@ -108,29 +98,31 @@ namespace embree
|
||||
end++;
|
||||
}
|
||||
|
||||
__forceinline void add(const BBox& geomBounds_) {
|
||||
template<typename PrimRef>
|
||||
__forceinline void add_center2(const PrimRef& prim) {
|
||||
CentGeom<BBox>::extend_center2(prim);
|
||||
end++;
|
||||
}
|
||||
|
||||
template<typename PrimRef>
|
||||
__forceinline void add_center2(const PrimRef& prim, const size_t i) {
|
||||
CentGeom<BBox>::extend_center2(prim);
|
||||
end+=i;
|
||||
}
|
||||
|
||||
/*__forceinline void add(const BBox& geomBounds_) {
|
||||
CentGeom<BBox>::extend(geomBounds_);
|
||||
end++;
|
||||
}
|
||||
|
||||
__forceinline void add(const BBox& geomBounds_, const size_t i) {
|
||||
CentGeom<BBox>::extend(geomBounds_,center2(geomBounds_));
|
||||
CentGeom<BBox>::extend(geomBounds_);
|
||||
end+=i;
|
||||
}
|
||||
|
||||
__forceinline void add(const size_t i=1) {
|
||||
end+=i;
|
||||
}
|
||||
|
||||
__forceinline void add(const BBox& geomBounds_, const BBox3fa& centBounds_, size_t num_ = 1) {
|
||||
CentGeom<BBox>::extend(geomBounds_,centBounds_);
|
||||
end += num_;
|
||||
}
|
||||
}*/
|
||||
|
||||
__forceinline void merge(const PrimInfoT& other)
|
||||
{
|
||||
CentGeom<BBox>::merge(other);
|
||||
//assert(begin == 0);
|
||||
begin += other.begin;
|
||||
end += other.end;
|
||||
}
|
||||
|
||||
Loaded 100 of 304 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user