Compare commits

..
145 Commits
Author SHA1 Message Date
cbenthin d3d9f6225b Merge remote-tracking branch 'origin/devel' into cbenthin 2017-09-28 16:14:37 +02:00
Johannes Günther f34b975536 More robust FindTBB 2017-09-28 14:11:02 +02:00
Johannes Günther b8c30540ba Let WIX set CMake registry ==> Embree will be found without embree_DIR 2017-09-26 11:43:36 +02:00
Sven Woop 42979151c2 added missing precompiled freeglut 3.0.0 library 2017-09-26 10:25:21 +02:00
Sven Woop 6bafe12b19 replacing old freeglut with freeglut 3.0.0 2017-09-26 08:48:19 +02:00
Sven Woop 4b078bb1bc package scripts properly return errors now 2017-09-25 08:39:56 +02:00
Sven Woop 66f21608e0 improved MacOSX uninstall script, calling rm and pkgutil using global path /bin/rm and /usr/sbin/pkgutil 2017-09-25 08:25:58 +02:00
Sven Woop c41d484595 Merge branch 'release' into devel 2017-09-25 07:37:54 +02:00
cbenthin 4794b0e55f updates 2017-09-22 06:57:45 -07:00
Sven Woop c48d21814c updates 2017-09-22 15:09:48 +02:00
Sven Woop a7d313ad41 Merge branch 'release' into devel 2017-09-22 13:12:05 +02:00
Sven Woop fe52f5d6b7 setting version to v2.17.1-alpha.0 2017-09-22 13:11:57 +02:00
Sven Woop 729ece7292 update 2017-09-22 13:10:44 +02:00
Sven Woop 9722b4c30d Merge branch 'release' into devel 2017-09-22 12:21:36 +02:00
Sven Woop ed8ee37967 setting product and upgrade GUI for WiX 2017-09-22 12:02:50 +02:00
Sven Woop 7a50a2d692 WiX also installs Embree to Intel folder under Program Files 2017-09-22 11:52:19 +02:00
Sven Woop 357c6f24c5 no longer installing tbb.dll into lib folder (but only to bin folder) 2017-09-22 11:49:52 +02:00
Sven Woop 83fcf53b95 replaced NSIS by WiX to generate MSI installer for Windows 2017-09-22 11:47:13 +02:00
cbenthin 8968597c20 updates to sub-pixel pattern 2017-09-22 11:36:53 +02:00
cbenthin 95a4cbcb94 updates 2017-09-22 10:40:44 +02:00
Sven Woop 2c724c529f fixed stripping of releases under MacOSX 2017-09-22 10:11:18 +02:00
cbenthin 5da02d0800 some MSAA experiments 2017-09-22 10:04:36 +02:00
Sven Woop 11b243931c added security comment to stipping of binaries 2017-09-22 09:08:15 +02:00
Sven Woop 28e11c9857 updates to release_win.bat, removed 32 bit build 2017-09-22 08:28:13 +02:00
Sven Woop 4c9c026a1b updates to release_win.bat, enabling stack protector for all builds 2017-09-22 08:27:30 +02:00
cbenthin 1a47e44b72 sync with devel 2017-09-21 18:23:40 +02:00
cbenthin 1fb988cd6b sync with master/release 2017-09-21 13:49:25 +02:00
Sven Woop c6498a29d0 compile fix for internal task scheduler 2017-09-21 07:19:34 +02:00
cbenthin fcd747217b set -inline-factor to 150 for the intel compiler to reduce compile times, moved mb builders from bvh_builder_hair.cpp into bvh_builder_hair_mb.cpp 2017-09-20 17:02:06 +02:00
Sven Woop 6bf725ba7c fixed compile issues with ICC and internal task scheduler 2017-09-20 14:14:46 +02:00
CDash e9a402ecd1 reduced inline-factor to 150 for intel compiler on mac os to prevent internal compiler error 2017-09-20 06:26:17 -05:00
Sven Woop a7dd991418 bugfix in test.py 2017-09-20 07:34:42 +02:00
Sven Woop 2f6af2832d updated documentation 2017-09-19 16:28:30 +02:00
Sven Woop 640c6daa85 setting version to 2.17.0 2017-09-19 16:27:07 +02:00
Sven Woop 512811023f bugfix in rtcOccluded1 and rtcOccluded1Ex API functions for ISPC 2017-09-19 12:11:35 +02:00
Sven Woop c0a1dbb5d8 cleanups 2017-09-19 10:18:31 +02:00
Sven Woop 045c418031 fixed some Clang 5 compile warnings 2017-09-19 10:01:58 +02:00
Sven Woop 8956aee21c enabling stack protector for releases 2017-09-19 09:48:27 +02:00
Sven Woop 0d9bc8df72 enabled stack protector for releases 2017-09-19 09:45:43 +02:00
Sven Woop ca96c96cb3 disabled stack protector by default 2017-09-19 09:43:38 +02:00
Sven Woop 4c50caa6b1 Merge branch 'devel' of https://github.com/embree/embree into devel 2017-09-19 09:19:21 +02:00
Sven Woop 9edba0f4ea reduced stack requirement for verify IntersectWithMode function 2017-09-19 09:19:06 +02:00
Sven Woop f4626bb22e reduced stack requirement for subdiv code 2017-09-19 09:18:44 +02:00
cbenthin 7d66ef477b fixed few msvc compile warnings 2017-09-18 05:49:12 -07:00
cbenthin 1b3b7ecb38 fixed few msvc compile warnings 2017-09-18 05:39:24 -07:00
Sven Woop e082712373 enabling stack protector by default 2017-09-18 07:05:17 +02:00
Sven Woop 185ffc39d3 added more tests to gitlab-ci 2017-09-15 14:47:28 +02:00
Sven Woop 3f4c6ac6e3 verbose=0 for tests 2017-09-15 14:20:21 +02:00
Sven Woop 5e3b4cf0e2 updates to CI 2017-09-15 14:11:40 +02:00
Sven Woop dec21a5f65 updates to CI 2017-09-15 14:08:14 +02:00
Sven Woop 2b0c400355 updates to CI 2017-09-15 14:06:52 +02:00
Sven Woop 058e820efb updates 2017-09-15 14:04:55 +02:00
Sven Woop d633a5541d updates to test.cmake 2017-09-15 13:59:16 +02:00
Sven Woop 563fa8b32c updates to test.cmake 2017-09-15 13:51:44 +02:00
Sven Woop 0894d751f1 updates to test.cmake 2017-09-15 13:50:45 +02:00
Sven Woop 23e8a0389d updates to test.cmake 2017-09-15 13:44:51 +02:00
Sven Woop 54f29c991b updates to test.cmake 2017-09-15 13:42:12 +02:00
Sven Woop fd3af84024 updates 2017-09-15 13:34:06 +02:00
Sven Woop a9a868f252 updates to test.cmake 2017-09-15 13:24:09 +02:00
Sven Woop 870e7adc71 updates to test.cmake 2017-09-15 13:19:25 +02:00
Sven Woop bec88b6568 Merge branch 'devel' of gitlab.com:embree/embree into devel 2017-09-15 13:13:16 +02:00
Sven Woop 85a6d9c54c updates to test.py 2017-09-15 13:11:35 +02:00
Sven Woop 63919c188c updates 2017-09-15 12:40:05 +02:00
Sven Woop 76892f8577 updates to test.py script 2017-09-15 12:38:12 +02:00
Sven Woop 44e783d59d updates to test.py 2017-09-15 12:31:08 +02:00
Sven Woop 0a642420af updates to test script 2017-09-15 12:25:20 +02:00
Sven Woop d208cbb4d9 added embree test scripts 2017-09-15 11:15:39 +02:00
Sven Woop 0419f1d8cc bugfix in FindTBB.cmake 2017-09-15 09:56:31 +02:00
Sven Woop c2309bbf79 updates to CI 2017-09-15 09:48:31 +02:00
Sven Woop e9149e8e9a added .gitlab-ci.yml with experimental settings 2017-09-15 09:30:26 +02:00
Sven Woop c15bb92593 Added support for BVH8 when AVX target was not enabled but targets higher than AVX.
Previously we did not use BVH8 in this case. This makes it e.g. possible to build
Embree properly for AVX2 only.
2017-09-15 08:51:35 +02:00
Sven Woop a1b56e8adc never enabling stack protector for traversal kernels 2017-09-14 13:38:38 +02:00
Sven Woop d85aea4c1a cleanups in frustum.h 2017-09-14 11:50:19 +02:00
Sven Woop 4498acd035 setting max internal stream size to 32 for 32 bit platforms 2017-09-14 11:43:56 +02:00
Sven Woop 152073d7ac cleanups 2017-09-14 11:42:43 +02:00
Sven Woop a90002157c cleanups in bvh_intersector_stream.h 2017-09-14 11:37:15 +02:00
Sven Woop f8c8d55c44 specializing frustum for robust and fast mode 2017-09-14 11:34:56 +02:00
Sven Woop 97600fb260 cleanups 2017-09-14 11:28:54 +02:00
Sven Woop b6d6cba2a2 specializing Packet for robust and non-robust mode 2017-09-14 11:23:27 +02:00
Sven Woop ead4835d35 cleanups in Packet class 2017-09-14 11:17:30 +02:00
Sven Woop eb4906c79c adding Packet constructor 2017-09-14 11:13:55 +02:00
Sven Woop 85b65574bb NearFarPreCompute no longer templated 2017-09-14 10:55:21 +02:00
Sven Woop 363c005f8e moved more code into packet struct 2017-09-14 10:42:48 +02:00
Sven Woop 4422ca608c re-using packet box test 2017-09-14 10:05:56 +02:00
Sven Woop d38ac50b2b moving packet intersection code to packet struct 2017-09-14 09:51:53 +02:00
Sven Woop 4d05b49867 moving Packet struct 2017-09-14 09:41:20 +02:00
Sven Woop a22e54cc49 cleanups 2017-09-14 09:36:44 +02:00
Sven Woop 46d131e056 re-using frustum intersection in stream frustum kernel 2017-09-14 09:36:06 +02:00
Sven Woop f1d23c57ed updates to frustum intersection interface 2017-09-14 09:30:53 +02:00
Sven Woop 265044e73f using new frustum struct in frustum stream traverser 2017-09-14 09:25:44 +02:00
Sven Woop ca84d3425e modifying frustum interface 2017-09-14 09:08:35 +02:00
Sven Woop 418ec0bdfb unifying frustm intersection interface 2017-09-14 08:52:45 +02:00
Sven Woop 2d1f8a6a97 updates to bvh_intersector_stream.h 2017-09-14 08:45:24 +02:00
Sven Woop 9813d6a6ee re-using NearFarPreCompute struct 2017-09-14 08:40:44 +02:00
Sven Woop 255ab75c5f first step to separate frustum structure 2017-09-14 08:26:45 +02:00
Sven Woop ece6b8345c removed unused file 2017-09-14 08:09:15 +02:00
Sven Woop 59ec5d0fcd Merge branch 'devel' of https://github.com/embree/embree into devel 2017-09-14 08:08:34 +02:00
Sven Woop 2cd05a8b2b Removing KNL optimization of frustum code for ray packet mode.
This caused a 5% slowdown, but frustum path is still significantly
faster (38%) than hybrid kernel. This change will make it easier
having a single frustum infrastructure for all frustum kernels.
2017-09-14 08:06:15 +02:00
cbenthin 08e54eb4c1 cleanups 2017-09-13 13:57:01 +02:00
cbenthin fb13a85505 cleanups 2017-09-13 13:45:46 +02:00
Sven Woop fb81cb34de removed no longer required packet fallback from bvh_intersector_stream.cpp 2017-09-13 12:27:02 +02:00
Sven Woop 3ceca55050 enabling stream kernels also for SSE, this codepath was already implemented but not selected 2017-09-13 12:20:48 +02:00
Sven Woop 87d45e6096 Merge branch 'devel' of https://github.com/embree/embree into devel 2017-09-13 12:07:29 +02:00
Sven Woop 872ced9934 printing camera before rendering 2017-09-13 12:07:16 +02:00
cbenthin f987d717ef removed validIsec checks in stream filters 2017-09-13 12:01:59 +02:00
cbenthin 9b40fcb862 Merge branch 'devel' of https://github.com/embree/embree into devel 2017-09-13 11:56:58 +02:00
cbenthin 19605e0738 added fallback to packet intersectorNs to isa namespaces, removed fallback in accel.h 2017-09-13 11:56:52 +02:00
Sven Woop fe56a4dc3c renames in bvh_intersector_hybrid.h 2017-09-13 11:55:53 +02:00
Sven Woop 4994f64729 implemented robust stream traversal 2017-09-13 11:29:08 +02:00
Sven Woop 7b4af861f4 adding first robust code to bvh_intersector_stream.h 2017-09-13 11:10:20 +02:00
Sven Woop 82ef698bcf Passing Accel::Intersectors* instead of BVH* to all intersector routines.
This way all intersectors can properly fallback to other interectors.

Moved intersect helper functions from Accel to Accel::Intersectors struct.

Fixed issue in stream kernels, that did fallback to packet traversal
using scene->intersect. This is wrong as causes iteration over all BVH
types again.
2017-09-13 08:59:00 +02:00
cbenthin ca70fc388b re-added accels.validIsecN test in stream filters otherwise verify crashes 2017-09-12 21:04:08 +02:00
Sven Woop ae06ac06a9 Merge branch 'devel' of https://github.com/embree/embree into devel 2017-09-12 16:12:17 +02:00
Sven Woop e2656563b1 cleanups in stream filters, not isRobust and validISecN tests are not required 2017-09-12 16:12:04 +02:00
cbenthin 752e905ecc increased benchmark iterations for more consistent results 2017-09-12 15:17:45 +02:00
Sven Woop d9e046d0c3 cleanups 2017-09-12 12:58:17 +02:00
Sven Woop 5945b87db9 cleanups in bvh_intersector_stream.cpp 2017-09-12 12:26:40 +02:00
Sven Woop 0c92fff315 Removed MAX_RAYS_PER_OCTANT (we have no octant sorting anymore). Only using MAX_INTERNAL_STREAM_SIZE. 2017-09-12 12:24:50 +02:00
Sven Woop 360ad9d0c3 fixed interface of intersectN/occludedN functions to RayK<VSIZEX> 2017-09-12 12:03:52 +02:00
Sven Woop 6c34e0d090 variable renames in frustum traverser 2017-09-12 11:39:34 +02:00
Sven Woop 794d90069c variable renames in frustum traverser 2017-09-12 11:27:09 +02:00
Sven Woop fb8e4405c7 cleanups in frustum packet traverser, added docu to frustum packet traverser 2017-09-12 11:23:20 +02:00
Sven Woop 36d53847c7 cleanups 2017-09-12 09:45:06 +02:00
Sven Woop e45aabfb8a added docu to maxDepth BVH member 2017-09-12 09:12:14 +02:00
Sven Woop d66fbeb235 making occlusion rays always incoherent in pathtracer 2017-09-12 08:50:21 +02:00
Sven Woop af13b7704f adding coherent/incoherent tests for viewer and pathtracer 2017-09-12 08:38:29 +02:00
Sven Woop 649d39f3a8 coherent/incoherent mode can be set from command line for viewer 2017-09-12 08:30:27 +02:00
Sven Woop 9b3362a394 fixed warning 2017-09-12 08:15:40 +02:00
Sven Woop fdb80242af returning in feature_adaptive_eval for out of bounds subpatch ID 2017-09-12 08:14:24 +02:00
Sven Woop fa7d1b4f89 bugfix of potential out of range access in stringstream.h 2017-09-12 08:00:18 +02:00
cbenthin f6cdaeb732 added AVX512VL sorting code to both 4 and 8-wide code paths 2017-09-11 18:27:06 +02:00
cbenthin a9d59ed6c8 Merge remote-tracking branch 'origin/devel' into cbenthin 2017-09-11 17:21:34 +02:00
cbenthin 5633e5233d deactivating all prefetches for large nodes on Xeon but still keep L2 prefetches for KNL 2017-09-11 16:33:21 +02:00
cbenthin 2b681c5f27 removed implicit int->uint conversion in sorting code 2017-09-09 08:01:30 -05:00
cbenthin 8a8f7c78aa sync 2017-09-08 16:54:27 +02:00
Sven Woop 159e440014 updates klocwork server 2017-09-08 07:24:07 +02:00
atafra 04d8b88026 added transpose optimization for SKX 2017-09-07 18:03:21 +03:00
atafra 1f8e43141c removed unused node intersection code 2017-09-07 14:05:24 +03:00
Sven Woop 07c35e2ed2 change 2017-09-07 07:46:12 +02:00
Sven Woop a44f900b20 replaced unsigned -> unsigned int for ISPC 2017-09-07 07:12:28 +02:00
atafra 141aa737c6 minor cleanup 2017-09-07 01:41:55 +03:00
atafra f154b5f160 improved very slow fallback path in filterSOA so it's not slow anymore 2017-09-07 01:39:43 +03:00
atafra 7f82ff96ce fixes and cleanups in RayPacketSOA, RayStreamAOS, and RayStreamAOP 2017-09-07 01:26:26 +03:00
atafra 1112474494 filter cleanups 2017-09-06 13:23:57 +03:00
atafra b486e32e7c implemented coherent code path for filterAOS and filterAOP 2017-09-06 12:42:32 +03:00
131 changed files with 2938 additions and 15486 deletions
+81
View File
@@ -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]
+24 -2
View File
@@ -1,6 +1,28 @@
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
@@ -84,7 +106,7 @@ Version History
- 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.
- 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
@@ -394,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)
+2 -1
View File
@@ -16,7 +16,7 @@
SET(EMBREE_VERSION_MAJOR 2)
SET(EMBREE_VERSION_MINOR 17)
SET(EMBREE_VERSION_PATCH 0)
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}")
@@ -26,6 +26,7 @@ PROJECT(embree${EMBREE_VERSION_MAJOR})
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.11)
# find git version
IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.git)
FIND_PACKAGE(Git)
+54 -49
View File
@@ -1,4 +1,4 @@
% Embree: High Performance Ray Tracing Kernels 2.16.5
% Embree: High Performance Ray Tracing Kernels 2.17.0
% Intel Corporation
Embree Overview
@@ -46,8 +46,8 @@ Renderer]).
Supported Platforms
-------------------
Embree supports Windows (32 bit and 64 bit), Linux (64 bit) and Mac
OS X (64 bit). The code compiles with the Intel Compiler, GCC, Clang
Embree supports Windows (32-bit and 64-bit), Linux (64-bit) and Mac
OS X (64-bit). The code compiles with the Intel Compiler, GCC, Clang
and the Microsoft Compiler.
Using the Intel Compiler improves performance by approximately
@@ -94,9 +94,9 @@ Windows Installer
You can install the Embree library using the Windows installer
application
[embree-2.16.5-x64.exe](https://github.com/embree/embree/releases/download/v2.16.5/embree-2.16.5.x64.exe). This
will install the 64 bit Embree version by default in `Program
Files\Intel\Embree v2.16.5 x64`.
[embree-2.17.0-x64.exe](https://github.com/embree/embree/releases/download/v2.17.0/embree-2.17.0.x64.exe). This
will install the 64-bit Embree version by default in `Program
Files\Intel\Embree v2.17.0 x64`.
You have to set the path to the `lib` folder manually to your `PATH`
environment variable for applications to find Embree. To compile
@@ -107,13 +107,13 @@ Embree installation.
To uninstall Embree again open `Programs and Features` by clicking the
`Start button`, clicking `Control Panel`, clicking `Programs`, and
then clicking `Programs and Features`. Select `Embree
2.16.5` and uninstall it.
2.17.0` and uninstall it.
Windows ZIP File
-----------------
Embree is also delivered as a ZIP file
[embree-2.16.5.x64.windows.zip](https://github.com/embree/embree/releases/download/v2.16.5/embree-2.16.5.x64.windows.zip). After
[embree-2.17.0.x64.windows.zip](https://github.com/embree/embree/releases/download/v2.17.0/embree-2.17.0.x64.windows.zip). After
unpacking this ZIP file you should set the path to the `lib` folder
manually to your `PATH` environment variable for applications to find
Embree. To compile applications with Embree you also have to set the
@@ -127,18 +127,18 @@ Linux RPMs
----------
Uncompress the 'tar.gz' file
[embree-2.16.5.x86_64.rpm.tar.gz](https://github.com/embree/embree/releases/download/v2.16.5/embree-2.16.5.x86_64.rpm.tar.gz)
[embree-2.17.0.x86_64.rpm.tar.gz](https://github.com/embree/embree/releases/download/v2.17.0/embree-2.17.0.x86_64.rpm.tar.gz)
to
obtain the individual RPM files:
tar xzf embree-2.16.5.x86_64.rpm.tar.gz
tar xzf embree-2.17.0.x86_64.rpm.tar.gz
To install the Embree using the RPM packages on your Linux system type
the following:
sudo rpm --install embree-lib-2.16.5-1.x86_64.rpm
sudo rpm --install embree-devel-2.16.5-1.noarch.rpm
sudo rpm --install embree-examples-2.16.5-1.x86_64.rpm
sudo rpm --install embree-lib-2.17.0-1.x86_64.rpm
sudo rpm --install embree-devel-2.17.0-1.noarch.rpm
sudo rpm --install embree-examples-2.17.0-1.x86_64.rpm
You also have to install the Intel® Threading Building Blocks (TBB)
using `yum`:
@@ -168,21 +168,21 @@ the tutorials to start them.
To uninstall Embree again just execute the following:
sudo rpm --erase embree-lib-2.16.5-1.x86_64
sudo rpm --erase embree-devel-2.16.5-1.noarch
sudo rpm --erase embree-examples-2.16.5-1.x86_64
sudo rpm --erase embree-lib-2.17.0-1.x86_64
sudo rpm --erase embree-devel-2.17.0-1.noarch
sudo rpm --erase embree-examples-2.17.0-1.x86_64
Linux tar.gz files
------------------
The Linux version of Embree is also delivered as a tar.gz file
[embree-2.16.5.x86_64.linux.tar.gz](https://github.com/embree/embree/releases/download/v2.16.5/embree-2.16.5.x86_64.linux.tar.gz). Unpack
[embree-2.17.0.x86_64.linux.tar.gz](https://github.com/embree/embree/releases/download/v2.17.0/embree-2.17.0.x86_64.linux.tar.gz). Unpack
this file using `tar` and source the provided `embree-vars.sh` (if you
are using the bash shell) or `embree-vars.csh` (if you are using the
C shell) to setup the environment properly:
tar xzf embree-2.16.5.x64.linux.tar.gz
source embree-2.16.5.x64.linux/embree-vars.sh
tar xzf embree-2.17.0.x64.linux.tar.gz
source embree-2.17.0.x64.linux/embree-vars.sh
If you want to ship Embree with your application best use the Embree
version provided through the tar.gz file.
@@ -195,7 +195,7 @@ Mac OS X PKG Installer
To install the Embree library on your Mac OS X system use the
provided package installer inside
[embree-2.16.5.x86_64.dmg](https://github.com/embree/embree/releases/download/v2.16.5/embree-2.16.5.x86_64.dmg). This
[embree-2.17.0.x86_64.dmg](https://github.com/embree/embree/releases/download/v2.17.0/embree-2.17.0.x86_64.dmg). This
will install Embree by default into `/opt/local/lib` and
`/opt/local/include` directories. The Embree tutorials are installed
into the `/Applications/Embree2` folder.
@@ -217,13 +217,13 @@ Mac OS X tar.gz file
---------------------
The Mac OS X version of Embree is also delivered as a tar.gz file
[embree-2.16.5.x86_64.macosx.tar.gz](https://github.com/embree/embree/releases/download/v2.16.5/embree-2.16.5.x86_64.macosx.tar.gz). Unpack
[embree-2.17.0.x86_64.macosx.tar.gz](https://github.com/embree/embree/releases/download/v2.17.0/embree-2.17.0.x86_64.macosx.tar.gz). Unpack
this file using `tar` and source the provided `embree-vars.sh` (if you
are using the bash shell) or `embree-vars.csh` (if you are using the
C shell) to setup the environment properly:
tar xzf embree-2.16.5.x64.macosx.tar.gz
source embree-2.16.5.x64.macosx/embree-vars.sh
tar xzf embree-2.17.0.x64.macosx.tar.gz
source embree-2.17.0.x64.macosx/embree-vars.sh
If you want to ship Embree with your application please use the Embree
library of the provided tar.gz file. The library name of that Embree
@@ -398,8 +398,8 @@ for Visual Studio.
Run `cmake-gui`, browse to the Embree sources, set the build directory
and click Configure. Now you can select the Generator, e.g. "Visual
Studio 12 2013" for a 32 bit build or "Visual Studio 12 2013 Win64"
for a 64 bit build.
Studio 12 2013" for a 32-bit build or "Visual Studio 12 2013 Win64"
for a 64-bit build.
To use a different compile than the Microsoft Visual C++ compiler, you
additionally need to specify the proper compiler toolset through the
@@ -481,6 +481,9 @@ parameters that can be configured in CMake:
and debug symbols
(RelWithDebInfo).
EMBREE_STACK_PROTECTOR Enables protection of return OFF
address from buffer overwrites.
EMBREE_ISPC_SUPPORT Enables ISPC support of Embree. ON
EMBREE_STATIC_LIB Builds Embree as a static OFF
@@ -581,10 +584,6 @@ different ISAs selected (e.g. embree2.a, embree2_sse42.a,
embree2_avx.a, embree2_avx2.a, embree2_avx512knl.a,
embree2_avx512skx.a). You have to link these libraries in increasing
ISA order (the order shown in the example).
When selecting ISAs individually, the AVX ISA always has to get
enabled when a larger ISA than AVX is enabled, otherwise the code will
not compile.
Embree API
==========
@@ -717,13 +716,18 @@ device.
typedef void (*RTCErrorFunc2)(void* userPtr, const RTCError, const char* str);
void rtcDeviceSetErrorFunction2(RTCDevice, RTCErrorFunc2, void* userPtr);
When invoked, the registred callback function gets passed a user
When invoked, the registered callback function gets passed a user
defined pointer `userPtr`, the error code `code`, as well as some
string `str` that describes the error further. Passing `NULL` as
function pointer to `rtcDeviceSetErrorFunction2` disables the set
callback function again. The previously described error flags are also
set if an error callback function is present.
Arrays and buffers passed to Embree in most cases have strict alignment and
padding requirements to facilitate efficient SIMD processing. The required
alignment and padding vary between 16 and 64 bytes, depending on the actual
function and data type.
Scene
-----
@@ -963,7 +967,7 @@ motion blur:
The triangle indices 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`). The
index buffer contains an array of three 32 bit indices, while the
index buffer contains an array of three 32-bit indices, while the
vertex buffer contains an array of three float values. The vertex
buffer can be at most 16GB large. When the vertex buffer is managed
internally the stride between vertices is 16 bytes. For multi segment
@@ -1016,7 +1020,7 @@ without motion blur:
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`). The index buffer
contains an array of four 32 bit indices, while the vertex buffer
contains an array of four 32-bit indices, while the vertex buffer
contains an array of three float values. The vertex buffer can be at
most 16GB large. When the vertex buffer is managed internally the
stride between vertices is 16 bytes. For multi segment motion blur,
@@ -1075,7 +1079,7 @@ The number of faces (`numFaces`), edges/indices (`numEdges`), vertices
The following buffers have to get setup by the application: the face
buffer (`RTC_FACE_BUFFER`) contains the number edges/indices (3 to 15) of
each of the `numFaces` faces, the index buffer (`RTC_INDEX_BUFFER`)
contains multiple (3 to 15) 32 bit vertex indices for each face and
contains multiple (3 to 15) 32-bit vertex indices for each face and
`numEdges` indices in total, the vertex buffer (`RTC_VERTEX_BUFFER`)
stores `numVertices` vertices as single precision `x`, `y`, `z` floating
point coordinates aligned to 16 bytes. The value of the 4th float used
@@ -1088,7 +1092,7 @@ geometry topology (topology 0) thus use `RTC_INDEX_BUFFER0`. Data
interpolation may use different topologies as described later.
Optionally, the application can setup the hole buffer (`RTC_HOLE_BUFFER`)
with `numHoles` many 32 bit indices of faces that should be considered
with `numHoles` many 32-bit indices of faces that should be considered
non-existing in all topologies.
Optionally, the application can fill the level buffer
@@ -1109,7 +1113,7 @@ uniform tessellation rate.
Optionally, the application can fill the sparse edge crease buffers to
make some edges appear sharper. The edge crease index buffer
(`RTC_EDGE_CREASE_INDEX_BUFFER`) contains `numEdgeCreases` many pairs
of 32 bit vertex indices that specify unoriented edges in the
of 32-bit vertex indices that specify unoriented edges in the
geometry topology. The edge crease weight buffer
(`RTC_EDGE_CREASE_WEIGHT_BUFFER`) stores for each of theses crease
edges a positive floating point weight. The larger this weight, the
@@ -1125,7 +1129,7 @@ topology, but copied to all other topologies automatically.
Optionally, the application can fill the sparse vertex crease buffers
to make some vertices appear sharper. The vertex crease index buffer
(`RTC_VERTEX_CREASE_INDEX_BUFFER`), contains `numVertexCreases` many
32 bit vertex indices to specify a set of vertices from the geometry
32-bit vertex indices to specify a set of vertices from the geometry
topology. The vertex crease weight buffer
(`RTC_VERTEX_CREASE_WEIGHT_BUFFER`) specifies for each of these
vertices a positive floating point weight. The larger this weight, the
@@ -1284,7 +1288,7 @@ writing into the vertex buffer (`RTC_VERTEX_BUFFER`). In case of
motion blur, the vertex buffers (`RTC_VERTEX_BUFFER0+t`) have to get
filled for each time step `t`.
The index buffer contains an array of 32 bit indices pointing to the
The index buffer contains an array of 32-bit indices pointing to the
ID of the first of two vertices, while the vertex buffer
stores all control points in the form of a single precision position
and radius stored in `x`, `y`, `z`, `r` order in memory. The
@@ -1339,7 +1343,7 @@ mapping and writing into the vertex buffer (`RTC_VERTEX_BUFFER`). In
case of motion blur, the vertex buffers `RTC_VERTEX_BUFFER0+t` have to
get filled for each time step.
The index buffer contains an array of 32 bit indices pointing to the
The index buffer contains an array of 32-bit indices pointing to the
ID of the first of four control vertices, while the vertex buffer
stores all control points in the form of a single precision position
and radius stored in `x`, `y`, `z`, `r` order in memory. The hair
@@ -1404,7 +1408,7 @@ mapping and writing into the vertex buffer (`RTC_VERTEX_BUFFER`). In
case of motion blur, the vertex buffers `RTC_VERTEX_BUFFER0+t` have to
get filled for each time step.
The index buffer contains an array of 32 bit indices pointing to the
The index buffer contains an array of 32-bit indices pointing to the
ID of the first of four control vertices, while the vertex buffer
stores all control points in the form of a single precision position
and radius stored in `x`, `y`, `z`, `r` order in memory. The curve
@@ -1767,7 +1771,7 @@ operate on ray packets of size 8, and the `rtcIntersect16` and
`rtcOccluded16` functions operate on ray packets of size 16.
For the ray packet mode with packet size of 4, 8, or 16, the user has
to provide a pointer to 4, 8, or 16 of 32 bit integers that act as a
to provide a pointer to 4, 8, or 16 of 32-bit integers that act as a
ray activity mask (`valid` argument). If one of these integers is set
to `0x00000000` the corresponding ray is considered inactive and if
the integer is set to `0xFFFFFFFF`, the ray is considered active. Rays
@@ -1863,10 +1867,11 @@ streams of rays:
The `rtcIntersectNM` and `rtcOccludedNM` ray stream functions operate
on an array of `M` ray packets of packet size `N`. The offset in bytes
between consecutive ray packets can be specified by the `stride`
parameter. Data alignment requirements for ray streams is 16
bytes. The packet size `N` has to be larger than 0 and the stream size
`M` can be an arbitrary positive integer including 0. Tracing for
example a ray stream consisting of four 8-wide SOA ray packets just
parameter. The required data alignment and padding for ray streams is 16
bytes, but for maximum performance, streams should be aligned to the native
SIMD size (e.g. 64 bytes for AVX-512). The packet size `N` has to be larger than
0 and the stream size `M` can be an arbitrary positive integer including 0.
Tracing for example a ray stream consisting of four 8-wide SOA ray packets just
requires to set the parameters `N` to 8, `M` to 4 and the `stride` to
`sizeof(RTCRay8)`. A ray in a ray stream is considered inactive during
traversal/intersection if its `tnear` value is larger than its `tfar`
@@ -1878,7 +1883,7 @@ just a shortcut for single ray streams with a packet size of
`rtcIntersect1M` and `rtcOccluded1M` while taking a stream of pointers
to single rays as input. The `rtcIntersectNp` and `rtcOccludedNp`
functions do not require the individual components of the SOA ray
packets to be stored sequentially in memory, but at different adresses
packets to be stored sequentially in memory, but at different addresses
as specified in the `RTCRayNp` structure.
The intersection context passed to the stream version of the ray query
@@ -1977,8 +1982,8 @@ The second order derivatives are stored at the `ddPdudu`, `ddPdvdv`,
and `ddPdudv` memory locations. One can avoid storing second order
derivatives by setting these three pointers to NULL.
The `RTC_INTERPOLATE` algorithm flag of a scene has to be enabled to
perform interpolations.
All output arrays must be padded to 16 bytes. The `RTC_INTERPOLATE`
algorithm flag of a scene has to be enabled to perform interpolations.
It is explicitly allowed to call this function on disabled
geometries. This makes it possible to use a separate subdivision mesh
@@ -2042,7 +2047,7 @@ the different elements of the shared buffer and the `size` parameter
specified the number of elements stored inside the buffer. This
support for offset and stride allows the application quite some
freedom in the data layout of these buffers, however, some
restrictions apply. Index buffers always store 32 bit indices and
restrictions apply. Index buffers always store 32-bit indices and
vertex buffers always store single precision floating point data. The
start address `ptr+offset` and `stride` always have to be aligned to 4
bytes, otherwise the `rtcSetBuffer2` function will fail. The `size`
@@ -2112,7 +2117,7 @@ while modifying the scene with other threads.
Geometry Mask
-------------
A 32 bit geometry mask can be assigned to triangle meshes and hair
A 32-bit geometry mask can be assigned to triangle meshes and hair
geometries using the `rtcSetMask` call.
rtcSetMask(scene, geomID, mask);
+42 -9
View File
@@ -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,17 +81,25 @@ 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}/src)
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)
@@ -92,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()
@@ -117,7 +151,6 @@ 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)
+10
View File
@@ -36,6 +36,11 @@ IF (WIN32)
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
@@ -88,6 +93,11 @@ ELSE()
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
+5
View File
@@ -41,6 +41,11 @@ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-tree-vectorize") # disable
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
+16 -5
View File
@@ -33,6 +33,11 @@ IF (WIN32)
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
@@ -46,14 +51,14 @@ IF (WIN32)
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=200") # increase default inline factors by 2x
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=200") # increase default inline factors by 2x
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
@@ -105,6 +110,12 @@ ELSE()
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()
IF(NOT CMAKE_CXX_COMPILER_WRAPPER STREQUAL "CrayPrgEnv")
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
@@ -122,8 +133,8 @@ ELSE()
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=200") # increase default inline factors limits by 2x
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
@@ -132,7 +143,7 @@ ELSE()
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=200") # increase default inline factors by 2x
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")
+5
View File
@@ -28,6 +28,11 @@ IF (EMBREE_STACK_PROTECTOR)
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}")
+8 -22
View File
@@ -125,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})
@@ -161,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()
@@ -230,7 +217,6 @@ ELSEIF(APPLE)
# Linux specific settings
ELSE()
IF (NOT EMBREE_ZIP_MODE)
SET(CPACK_GENERATOR RPM)
+1 -1
View File
@@ -30,7 +30,7 @@ namespace embree
ParseLocation location() { return cin->loc(); }
std::string next();
private:
__forceinline bool isSeparator(int c) const { return c <= 256 && 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 */
+1 -1
View File
@@ -49,7 +49,7 @@ namespace embree
__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 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 {
+15
View File
@@ -428,6 +428,9 @@ namespace embree
/// Movement/Shifting/Shuffling Functions
////////////////////////////////////////////////////////////////////////////////
__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));
@@ -530,6 +533,7 @@ namespace embree
__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);
@@ -539,6 +543,17 @@ namespace embree
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,
+16
View File
@@ -69,6 +69,14 @@ namespace embree
static __forceinline void storeu(void* ptr, const vfloat4& v) { _mm_storeu_ps((float*)ptr,v); }
#if defined(__AVX512VL__)
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); }
@@ -547,6 +555,14 @@ namespace embree
#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
////////////////////////////////////////////////////////////////////////////////
+8
View File
@@ -101,6 +101,14 @@ namespace embree
static __forceinline void storeu(void* ptr, const vfloat8& v) { return _mm256_storeu_ps((float*)ptr,v); }
#if defined(__AVX512VL__)
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); }
+20
View File
@@ -77,6 +77,14 @@ namespace embree
static __forceinline void storeu(void* ptr, const vint4& v) { _mm_storeu_si128((__m128i*)ptr,v); }
#if defined(__AVX512VL__)
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); }
@@ -400,6 +408,18 @@ namespace embree
__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
////////////////////////////////////////////////////////////////////////////////
+13 -1
View File
@@ -89,6 +89,14 @@ namespace embree
static __forceinline void storeu(void* ptr, const vint8& v) { _mm256_storeu_ps((float*)ptr,_mm256_castsi256_ps(v)); }
#if defined(__AVX512VL__)
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); }
@@ -363,7 +371,11 @@ namespace embree
template<int i>
__forceinline vint8 align_shift_right(const vint8& a, const vint8& b) {
return _mm256_alignr_epi8(a, b, i);
#if defined(__AVX512VL__)
return _mm256_alignr_epi32(a, b, i);
#else
return _mm256_alignr_epi8(a, b, 4*i);
#endif
}
////////////////////////////////////////////////////////////////////////////////
+15 -6
View File
@@ -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--;
});
}
+3
View File
@@ -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
@@ -149,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();
+9 -9
View File
@@ -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.
@@ -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. */
+4 -4
View File
@@ -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);
/*! @} */
+3 -3
View File
@@ -16,6 +16,6 @@
#define RTCORE_VERSION_MAJOR 2
#define RTCORE_VERSION_MINOR 17
#define RTCORE_VERSION_PATCH 0
#define RTCORE_VERSION 21700
#define RTCORE_VERSION_STRING "2.17.0-alpha.0"
#define RTCORE_VERSION_PATCH 1
#define RTCORE_VERSION 21701
#define RTCORE_VERSION_STRING "2.17.1-alpha.0"
+16
View File
@@ -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/" )
@@ -62,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
@@ -109,6 +118,7 @@ MACRO(embree_files TARGET ISA)
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)
@@ -208,6 +218,7 @@ MACRO (CheckGlobals 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")
@@ -225,6 +236,7 @@ ENDIF()
#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)
@@ -233,6 +245,7 @@ IF (EMBREE_ISA_SSE42 AND EMBREE_LIBRARY_FILES_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)
@@ -241,6 +254,7 @@ IF (EMBREE_ISA_AVX AND EMBREE_LIBRARY_FILES_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)
@@ -249,6 +263,7 @@ IF (EMBREE_ISA_AVX2 AND EMBREE_LIBRARY_FILES_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)
@@ -257,6 +272,7 @@ IF (EMBREE_ISA_AVX512KNL AND EMBREE_LIBRARY_FILES_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)
+12 -10
View File
@@ -134,7 +134,7 @@ namespace embree
/*! Maximal depth of the BVH. */
static const size_t maxBuildDepth = 32;
static const size_t maxBuildDepthLeaf = maxBuildDepth+8;
static const size_t maxDepth = maxBuildDepth+maxBuildDepthLeaf;
static const size_t maxDepth = 2*maxBuildDepthLeaf; // 2x because of two level builder
/*! Maximal number of primitive blocks in a leaf. */
static const size_t maxLeafBlocks = items_mask-tyLeaf;
@@ -169,6 +169,7 @@ namespace embree
prefetchL2(((char*)ptr)+3*64);
}
if ((N >= 8) && (types > BVH_FLAG_ALIGNED_NODE)) {
/* KNL still needs L2 prefetches for large nodes */
prefetchL2(((char*)ptr)+4*64);
prefetchL2(((char*)ptr)+5*64);
prefetchL2(((char*)ptr)+6*64);
@@ -191,10 +192,11 @@ namespace embree
prefetchL1(((char*)ptr)+3*64);
}
if ((N >= 8) && (types > BVH_FLAG_ALIGNED_NODE)) {
prefetchL1(((char*)ptr)+4*64);
prefetchL1(((char*)ptr)+5*64);
prefetchL1(((char*)ptr)+6*64);
prefetchL1(((char*)ptr)+7*64);
/* deactivate for large nodes on Xeon, as it introduces regressions */
//prefetchL1(((char*)ptr)+4*64);
//prefetchL1(((char*)ptr)+5*64);
//prefetchL1(((char*)ptr)+6*64);
//prefetchL1(((char*)ptr)+7*64);
}
}
else
@@ -362,9 +364,9 @@ namespace embree
__forceinline const QuantizedNode* quantizedNode() const { assert(isQuantizedNode()); return (const QuantizedNode*)(ptr & ~(size_t)align_mask ); }
/*! returns leaf pointer */
__forceinline char* leaf(size_t& ty) const {
__forceinline char* leaf(size_t& num) const {
assert(isLeaf());
ty = (ptr & (size_t)items_mask)-tyLeaf;
num = (ptr & (size_t)items_mask)-tyLeaf;
return (char*)(ptr & ~(size_t)align_mask);
}
@@ -1454,10 +1456,10 @@ namespace embree
}
/*! Encodes a leaf */
static __forceinline NodeRef encodeLeaf(void* tri, size_t ty) {
static __forceinline NodeRef encodeLeaf(void* tri, size_t num) {
assert(!((size_t)tri & align_mask));
assert(ty <= maxLeafBlocks);
return NodeRef((size_t)tri | (tyLeaf+min(ty,(size_t)maxLeafBlocks)));
assert(num <= maxLeafBlocks);
return NodeRef((size_t)tri | (tyLeaf+min(num,(size_t)maxLeafBlocks)));
}
/*! Encodes a leaf */
+23 -19
View File
@@ -182,6 +182,8 @@ namespace embree
DECLARE_SYMBOL2(Accel::Intersector16,BVH4VirtualIntersector16Chunk);
DECLARE_SYMBOL2(Accel::Intersector16,BVH4VirtualMBIntersector16Chunk);
DECLARE_SYMBOL2(Accel::IntersectorN,BVH4IntersectorStreamPacketFallback);
DECLARE_SYMBOL2(Accel::IntersectorN,BVH4Line4iIntersectorStream);
DECLARE_SYMBOL2(Accel::IntersectorN,BVH4Bezier1vIntersectorStream);
DECLARE_SYMBOL2(Accel::IntersectorN,BVH4Bezier1iIntersectorStream);
@@ -497,6 +499,8 @@ namespace embree
//IF_ENABLED_HAIR(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2 (features,BVH4Bezier1vIntersectorStream_OBB));
//IF_ENABLED_HAIR(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2 (features,BVH4Bezier1iIntersectorStream_OBB));
SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH4IntersectorStreamPacketFallback);
IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH4Triangle4IntersectorStreamMoeller));
IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH4Triangle4IntersectorStreamMoellerNoFilter));
IF_ENABLED_TRIS(SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH4Triangle4iIntersectorStreamMoeller));
@@ -524,7 +528,7 @@ namespace embree
intersectors.intersector4 = BVH4Bezier1vIntersector4Hybrid();
intersectors.intersector8 = BVH4Bezier1vIntersector8Hybrid();
intersectors.intersector16 = BVH4Bezier1vIntersector16Hybrid();
//intersectors.intersectorN = BVH4Bezier1vIntersectorStream();
intersectors.intersectorN = BVH4IntersectorStreamPacketFallback();
#endif
return intersectors;
}
@@ -538,7 +542,7 @@ namespace embree
intersectors.intersector4 = BVH4Bezier1iIntersector4Hybrid();
intersectors.intersector8 = BVH4Bezier1iIntersector8Hybrid();
intersectors.intersector16 = BVH4Bezier1iIntersector16Hybrid();
//intersectors.intersectorN = BVH4Bezier1iIntersectorStream();
intersectors.intersectorN = BVH4IntersectorStreamPacketFallback();
#endif
return intersectors;
}
@@ -552,7 +556,7 @@ namespace embree
intersectors.intersector4 = BVH4Line4iIntersector4();
intersectors.intersector8 = BVH4Line4iIntersector8();
intersectors.intersector16 = BVH4Line4iIntersector16();
//intersectors.intersectorN = BVH4Line4iIntersectorStream();
intersectors.intersectorN = BVH4IntersectorStreamPacketFallback();
#endif
return intersectors;
}
@@ -566,7 +570,7 @@ namespace embree
intersectors.intersector4 = BVH4Line4iMBIntersector4();
intersectors.intersector8 = BVH4Line4iMBIntersector8();
intersectors.intersector16 = BVH4Line4iMBIntersector16();
//intersectors.intersectorN = BVH4Line4iMBIntersectorStream();
intersectors.intersectorN = BVH4IntersectorStreamPacketFallback();
#endif
return intersectors;
}
@@ -580,7 +584,7 @@ namespace embree
intersectors.intersector4 = BVH4Bezier1vIntersector4Hybrid_OBB();
intersectors.intersector8 = BVH4Bezier1vIntersector8Hybrid_OBB();
intersectors.intersector16 = BVH4Bezier1vIntersector16Hybrid_OBB();
//intersectors.intersectorN = BVH4Bezier1vIntersectorStream_OBB();
intersectors.intersectorN = BVH4IntersectorStreamPacketFallback();
#endif
return intersectors;
}
@@ -594,7 +598,7 @@ namespace embree
intersectors.intersector4 = BVH4Bezier1iIntersector4Hybrid_OBB();
intersectors.intersector8 = BVH4Bezier1iIntersector8Hybrid_OBB();
intersectors.intersector16 = BVH4Bezier1iIntersector16Hybrid_OBB();
//intersectors.intersectorN = BVH4Bezier1iIntersectorStream_OBB();
intersectors.intersectorN = BVH4IntersectorStreamPacketFallback();
#endif
return intersectors;
}
@@ -608,7 +612,7 @@ namespace embree
intersectors.intersector4 = BVH4OBBBezier1iMBIntersector4Hybrid_OBB();
intersectors.intersector8 = BVH4OBBBezier1iMBIntersector8Hybrid_OBB();
intersectors.intersector16 = BVH4OBBBezier1iMBIntersector16Hybrid_OBB();
//intersectors.intersectorN = BVH4OBBBezier1iMBIntersectorStream_OBB();
intersectors.intersectorN = BVH4IntersectorStreamPacketFallback();
#endif
return intersectors;
}
@@ -700,7 +704,7 @@ namespace embree
intersectors.intersector4 = BVH4Triangle4vMBIntersector4HybridMoeller();
intersectors.intersector8 = BVH4Triangle4vMBIntersector8HybridMoeller();
intersectors.intersector16 = BVH4Triangle4vMBIntersector16HybridMoeller();
//intersectors.intersectorN = BVH4Triangle4vMBIntersectorStreamMoeller();
intersectors.intersectorN = BVH4IntersectorStreamPacketFallback();
#endif
return intersectors;
}
@@ -713,7 +717,7 @@ namespace embree
intersectors.intersector4 = BVH4Triangle4vMBIntersector4HybridPluecker();
intersectors.intersector8 = BVH4Triangle4vMBIntersector8HybridPluecker();
intersectors.intersector16 = BVH4Triangle4vMBIntersector16HybridPluecker();
//intersectors.intersectorN = BVH4Triangle4vMBIntersectorStreamPluecker();
intersectors.intersectorN = BVH4IntersectorStreamPacketFallback();
#endif
return intersectors;
}
@@ -733,7 +737,7 @@ namespace embree
intersectors.intersector4 = BVH4Triangle4iMBIntersector4HybridMoeller();
intersectors.intersector8 = BVH4Triangle4iMBIntersector8HybridMoeller();
intersectors.intersector16 = BVH4Triangle4iMBIntersector16HybridMoeller();
//intersectors.intersectorN = BVH4Triangle4iMBIntersectorStreamMoeller();
intersectors.intersectorN = BVH4IntersectorStreamPacketFallback();
#endif
return intersectors;
}
@@ -746,7 +750,7 @@ namespace embree
intersectors.intersector4 = BVH4Triangle4iMBIntersector4HybridPluecker();
intersectors.intersector8 = BVH4Triangle4iMBIntersector8HybridPluecker();
intersectors.intersector16 = BVH4Triangle4iMBIntersector16HybridPluecker();
//intersectors.intersectorN = BVH4Triangle4iMBIntersectorStreamPluecker();
intersectors.intersectorN = BVH4IntersectorStreamPacketFallback();
#endif
return intersectors;
}
@@ -836,7 +840,7 @@ namespace embree
intersectors.intersector4 = BVH4Quad4iMBIntersector4HybridMoeller();
intersectors.intersector8 = BVH4Quad4iMBIntersector8HybridMoeller();
intersectors.intersector16= BVH4Quad4iMBIntersector16HybridMoeller();
//intersectors.intersectorN = BVH4Quad4iMBIntersectorStreamMoeller();
intersectors.intersectorN = BVH4IntersectorStreamPacketFallback();
#endif
return intersectors;
}
@@ -849,7 +853,7 @@ namespace embree
intersectors.intersector4 = BVH4Quad4iMBIntersector4HybridPluecker();
intersectors.intersector8 = BVH4Quad4iMBIntersector8HybridPluecker();
intersectors.intersector16= BVH4Quad4iMBIntersector16HybridPluecker();
//intersectors.intersectorN = BVH4Quad4iMBIntersectorStreamPluecker();
intersectors.intersectorN = BVH4IntersectorStreamPacketFallback();
#endif
return intersectors;
}
@@ -896,7 +900,7 @@ namespace embree
intersectors.intersector4 = BVH4VirtualMBIntersector4Chunk();
intersectors.intersector8 = BVH4VirtualMBIntersector8Chunk();
intersectors.intersector16 = BVH4VirtualMBIntersector16Chunk();
//intersectors.intersectorN = BVH4VirtualMBIntersectorStream();
intersectors.intersectorN = BVH4IntersectorStreamPacketFallback();
#endif
return intersectors;
}
@@ -910,7 +914,7 @@ namespace embree
intersectors.intersector4 = BVH4SubdivPatch1Intersector4();
intersectors.intersector8 = BVH4SubdivPatch1Intersector8();
intersectors.intersector16 = BVH4SubdivPatch1Intersector16();
//intersectors.intersectorN = BVH4SubdivPatch1IntersectorStream();
intersectors.intersectorN = BVH4IntersectorStreamPacketFallback();
#endif
return intersectors;
}
@@ -924,7 +928,7 @@ namespace embree
intersectors.intersector4 = BVH4SubdivPatch1EagerIntersector4();
intersectors.intersector8 = BVH4SubdivPatch1EagerIntersector8();
intersectors.intersector16 = BVH4SubdivPatch1EagerIntersector16();
//intersectors.intersectorN = BVH4SubdivPatch1EagerIntersectorStream();
intersectors.intersectorN = BVH4IntersectorStreamPacketFallback();
#endif
return intersectors;
}
@@ -938,7 +942,7 @@ namespace embree
intersectors.intersector4 = BVH4SubdivPatch1CachedIntersector4();
intersectors.intersector8 = BVH4SubdivPatch1CachedIntersector8();
intersectors.intersector16 = BVH4SubdivPatch1CachedIntersector16();
//intersectors.intersectorN = BVH4SubdivPatch1CachedIntersectorStream();
intersectors.intersectorN = BVH4IntersectorStreamPacketFallback();
#endif
return intersectors;
}
@@ -952,7 +956,7 @@ namespace embree
intersectors.intersector4 = BVH4SubdivPatch1MBIntersector4();
intersectors.intersector8 = BVH4SubdivPatch1MBIntersector8();
intersectors.intersector16 = BVH4SubdivPatch1MBIntersector16();
//intersectors.intersectorN = BVH4SubdivPatch1MBStreamIntersector();
intersectors.intersectorN = BVH4IntersectorStreamPacketFallback();
#endif
return intersectors;
}
@@ -966,7 +970,7 @@ namespace embree
intersectors.intersector4 = BVH4SubdivPatch1CachedMBIntersector4();
intersectors.intersector8 = BVH4SubdivPatch1CachedMBIntersector8();
intersectors.intersector16 = BVH4SubdivPatch1CachedMBIntersector16();
//intersectors.intersectorN = BVH4SubdivPatch1CachedMBStreamIntersector();
intersectors.intersectorN = BVH4IntersectorStreamPacketFallback();
#endif
return intersectors;
}
+2
View File
@@ -268,6 +268,8 @@ namespace embree
//DEFINE_SYMBOL2(Accel::IntersectorN,BVH4Bezier1vIntersectorStream_OBB);
//DEFINE_SYMBOL2(Accel::IntersectorN,BVH4Bezier1iIntersectorStream_OBB);
DEFINE_SYMBOL2(Accel::IntersectorN, BVH4IntersectorStreamPacketFallback);
DEFINE_SYMBOL2(Accel::IntersectorN, BVH4Triangle4IntersectorStreamMoeller);
DEFINE_SYMBOL2(Accel::IntersectorN, BVH4Triangle4IntersectorStreamMoellerNoFilter);
DEFINE_SYMBOL2(Accel::IntersectorN, BVH4Triangle4iIntersectorStreamMoeller);
+20 -13
View File
@@ -14,7 +14,9 @@
// limitations under the License. //
// ======================================================================== //
#if defined (EMBREE_TARGET_AVX)
#include "../common/isa.h" // to define EMBREE_TARGET_SIMD8
#if defined (EMBREE_TARGET_SIMD8)
#include "bvh8_factory.h"
#include "../bvh/bvh.h"
@@ -155,6 +157,8 @@ namespace embree
DECLARE_SYMBOL2(Accel::Intersector16,BVH8VirtualIntersector16Chunk);
DECLARE_SYMBOL2(Accel::Intersector16,BVH8VirtualMBIntersector16Chunk);
DECLARE_SYMBOL2(Accel::IntersectorN,BVH8IntersectorStreamPacketFallback);
//DECLARE_SYMBOL2(Accel::IntersectorN,BVH8Line4iIntersectorStream);
//DECLARE_SYMBOL2(Accel::IntersectorN,BVH8Bezier1vIntersectorStream_OBB);
//DECLARE_SYMBOL2(Accel::IntersectorN,BVH8Bezier1iIntersectorStream_OBB);
@@ -412,6 +416,9 @@ namespace embree
IF_ENABLED_USER(SELECT_SYMBOL_INIT_AVX512KNL_AVX512SKX(features,BVH8VirtualMBIntersector16Chunk));
/* select stream intersectors */
SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH8IntersectorStreamPacketFallback);
IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH8Triangle4IntersectorStreamMoeller));
IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH8Triangle4IntersectorStreamMoellerNoFilter));
IF_ENABLED_TRIS(SELECT_SYMBOL_INIT_AVX_AVX2_AVX512KNL_AVX512SKX(features,BVH8Triangle4iIntersectorStreamMoeller));
@@ -526,7 +533,7 @@ namespace embree
intersectors.intersector4 = BVH8Bezier1vIntersector4Hybrid_OBB();
intersectors.intersector8 = BVH8Bezier1vIntersector8Hybrid_OBB();
intersectors.intersector16 = BVH8Bezier1vIntersector16Hybrid_OBB();
//intersectors.intersectorN = BVH8Bezier1vIntersectorStream_OBB();
intersectors.intersectorN = BVH8IntersectorStreamPacketFallback();
#endif
return intersectors;
}
@@ -540,7 +547,7 @@ namespace embree
intersectors.intersector4 = BVH8Bezier1iIntersector4Hybrid_OBB();
intersectors.intersector8 = BVH8Bezier1iIntersector8Hybrid_OBB();
intersectors.intersector16 = BVH8Bezier1iIntersector16Hybrid_OBB();
//intersectors.intersectorN = BVH8Bezier1iIntersectorStream_OBB();
intersectors.intersectorN = BVH8IntersectorStreamPacketFallback();
#endif
return intersectors;
}
@@ -554,7 +561,7 @@ namespace embree
intersectors.intersector4 = BVH8OBBBezier1iMBIntersector4Hybrid_OBB();
intersectors.intersector8 = BVH8OBBBezier1iMBIntersector8Hybrid_OBB();
intersectors.intersector16 = BVH8OBBBezier1iMBIntersector16Hybrid_OBB();
//intersectors.intersectorN = BVH8OBBBezier1iMBIntersectorStream_OBB();
intersectors.intersectorN = BVH8IntersectorStreamPacketFallback();
#endif
return intersectors;
}
@@ -568,7 +575,7 @@ namespace embree
intersectors.intersector4 = BVH8Line4iIntersector4();
intersectors.intersector8 = BVH8Line4iIntersector8();
intersectors.intersector16 = BVH8Line4iIntersector16();
//intersectors.intersectorN = BVH8Line4iIntersectorStream();
intersectors.intersectorN = BVH8IntersectorStreamPacketFallback();
#endif
return intersectors;
}
@@ -582,7 +589,7 @@ namespace embree
intersectors.intersector4 = BVH8Line4iMBIntersector4();
intersectors.intersector8 = BVH8Line4iMBIntersector8();
intersectors.intersector16 = BVH8Line4iMBIntersector16();
//intersectors.intersectorN = BVH8Line4iMBIntersectorStream();
intersectors.intersectorN = BVH8IntersectorStreamPacketFallback();
#endif
return intersectors;
}
@@ -666,7 +673,7 @@ namespace embree
intersectors.intersector4 = BVH8Triangle4vMBIntersector4HybridMoeller();
intersectors.intersector8 = BVH8Triangle4vMBIntersector8HybridMoeller();
intersectors.intersector16 = BVH8Triangle4vMBIntersector16HybridMoeller();
//intersectors.intersectorN = BVH8Triangle4vMBIntersectorStreamMoeller();
intersectors.intersectorN = BVH8IntersectorStreamPacketFallback();
#endif
return intersectors;
}
@@ -679,7 +686,7 @@ namespace embree
intersectors.intersector4 = BVH8Triangle4vMBIntersector4HybridPluecker();
intersectors.intersector8 = BVH8Triangle4vMBIntersector8HybridPluecker();
intersectors.intersector16 = BVH8Triangle4vMBIntersector16HybridPluecker();
//intersectors.intersectorN = BVH8Triangle4vMBIntersectorStreamPluecker();
intersectors.intersectorN = BVH8IntersectorStreamPacketFallback();
#endif
return intersectors;
}
@@ -699,7 +706,7 @@ namespace embree
intersectors.intersector4 = BVH8Triangle4iMBIntersector4HybridMoeller();
intersectors.intersector8 = BVH8Triangle4iMBIntersector8HybridMoeller();
intersectors.intersector16 = BVH8Triangle4iMBIntersector16HybridMoeller();
//intersectors.intersectorN = BVH8Triangle4iMBIntersectorStreamMoeller();
intersectors.intersectorN = BVH8IntersectorStreamPacketFallback();
#endif
return intersectors;
}
@@ -712,7 +719,7 @@ namespace embree
intersectors.intersector4 = BVH8Triangle4iMBIntersector4HybridPluecker();
intersectors.intersector8 = BVH8Triangle4iMBIntersector8HybridPluecker();
intersectors.intersector16 = BVH8Triangle4iMBIntersector16HybridPluecker();
//intersectors.intersectorN = BVH8Triangle4iMBIntersectorStreamPluecker();
intersectors.intersectorN = BVH8IntersectorStreamPacketFallback();
#endif
return intersectors;
}
@@ -802,7 +809,7 @@ namespace embree
intersectors.intersector4 = BVH8Quad4iMBIntersector4HybridMoeller();
intersectors.intersector8 = BVH8Quad4iMBIntersector8HybridMoeller();
intersectors.intersector16 = BVH8Quad4iMBIntersector16HybridMoeller();
//intersectors.intersectorN = BVH8Quad4iMBIntersectorStreamMoeller();
intersectors.intersectorN = BVH8IntersectorStreamPacketFallback();
#endif
return intersectors;
}
@@ -815,7 +822,7 @@ namespace embree
intersectors.intersector4 = BVH8Quad4iMBIntersector4HybridPluecker();
intersectors.intersector8 = BVH8Quad4iMBIntersector8HybridPluecker();
intersectors.intersector16 = BVH8Quad4iMBIntersector16HybridPluecker();
//intersectors.intersectorN = BVH8Quad4iMBIntersectorStreamPluecker();
intersectors.intersectorN = BVH8IntersectorStreamPacketFallback();
#endif
return intersectors;
}
@@ -870,7 +877,7 @@ namespace embree
intersectors.intersector4 = BVH8VirtualMBIntersector4Chunk();
intersectors.intersector8 = BVH8VirtualMBIntersector8Chunk();
intersectors.intersector16 = BVH8VirtualMBIntersector16Chunk();
//intersectors.intersectorN = BVH8VirtualMBIntersectorStream();
intersectors.intersectorN = BVH8IntersectorStreamPacketFallback();
#endif
return intersectors;
}
+2
View File
@@ -217,6 +217,8 @@ namespace embree
//DEFINE_SYMBOL2(Accel::IntersectorN,BVH8Bezier1vIntersectorStream_OBB);
//DEFINE_SYMBOL2(Accel::IntersectorN,BVH8Bezier1iIntersectorStream_OBB);
DEFINE_SYMBOL2(Accel::IntersectorN,BVH8IntersectorStreamPacketFallback);
DEFINE_SYMBOL2(Accel::IntersectorN,BVH8Triangle4IntersectorStreamMoeller);
DEFINE_SYMBOL2(Accel::IntersectorN,BVH8Triangle4IntersectorStreamMoellerNoFilter);
DEFINE_SYMBOL2(Accel::IntersectorN,BVH8Triangle4iIntersectorStreamMoeller);
+1 -90
View File
@@ -78,7 +78,7 @@ namespace embree
size_t items = set.size();
Primitive* accel = (Primitive*) alloc.malloc1(items*sizeof(Primitive),BVH::byteAlignment);
for (size_t i=0; i<items; i++) {
accel[i].fill(prims,start,set.end(),bvh->scene,i==(items-1));
accel[i].fill(prims,start,set.end(),bvh->scene);
}
return bvh->encodeLeaf((char*)accel,items);
};
@@ -109,103 +109,14 @@ namespace embree
prims.clear();
}
};
/* FIXME: add fast path for single-segment motion blur */
template<int N, typename Primitive>
struct BVHNHairMBlurBuilderSAH : public Builder
{
typedef BVHN<N> BVH;
typedef typename BVH::NodeRef NodeRef;
typedef typename BVH::NodeRecordMB4D NodeRecordMB4D;
BVH* bvh;
Scene* scene;
BVHNHairMBlurBuilderSAH (BVH* bvh, Scene* scene)
: bvh(bvh), scene(scene) {}
void build()
{
/* fast path for empty BVH */
const size_t numPrimitives = scene->getNumPrimitives<NativeCurves,true>();
if (numPrimitives == 0) {
bvh->set(BVH::emptyNode,empty,0);
return;
}
double t0 = bvh->preBuild(TOSTRING(isa) "::BVH" + toString(N) + "HairMBlurBuilderSAH");
//profile(1,5,numPrimitives,[&] (ProfileTimer& timer) {
/* create primref array */
mvector<PrimRefMB> prims0(scene->device,numPrimitives);
const PrimInfoMB pinfo = createPrimRefArrayMSMBlur<NativeCurves>(scene,prims0,bvh->scene->progressInterface);
/* estimate acceleration structure size */
const size_t node_bytes = pinfo.num_time_segments*sizeof(typename BVH::AlignedNodeMB)/(4*N);
const size_t leaf_bytes = size_t(1.2*Primitive::blocks(pinfo.num_time_segments)*sizeof(Primitive));
bvh->alloc.init_estimate(node_bytes+leaf_bytes);
/* settings for BVH build */
BVHBuilderHairMSMBlur::Settings settings;
settings.branchingFactor = N;
settings.maxDepth = BVH::maxBuildDepthLeaf;
settings.logBlockSize = 1;
settings.minLeafSize = 1;
settings.maxLeafSize = BVH::maxLeafBlocks;
/* creates a leaf node */
auto createLeaf = [&] (const SetMB& prims, const FastAllocator::CachedAllocator& alloc) -> NodeRecordMB4D
{
size_t start = prims.object_range.begin();
size_t end = prims.object_range.end();
size_t items = prims.object_range.size();
Primitive* accel = (Primitive*) alloc.malloc1(items*sizeof(Primitive));
const NodeRef node = bvh->encodeLeaf((char*)accel,items);
LBBox3fa bounds = empty;
for (size_t i=0; i<items; i++)
bounds.extend(accel[i].fillMB(prims.prims->data(),start,end,bvh->scene,prims.time_range,i==(items-1)));
return NodeRecordMB4D(node,bounds,prims.time_range);
};
/* build the hierarchy */
auto root = BVHBuilderHairMSMBlur::build<NodeRef>
(scene, prims0, pinfo,
RecalculatePrimRef<NativeCurves>(scene),
typename BVH::CreateAlloc(bvh),
typename BVH::AlignedNodeMB4D::Create(),
typename BVH::AlignedNodeMB4D::Set(),
typename BVH::UnalignedNodeMB::Create(),
typename BVH::UnalignedNodeMB::Set(),
createLeaf,
bvh->scene->progressInterface,
settings);
bvh->set(root.ref,root.lbounds,pinfo.num_time_segments);
//});
/* clear temporary data for static geometry */
if (scene->isStatic()) bvh->shrink();
bvh->cleanup();
bvh->postBuild(t0);
}
void clear() {
}
};
/*! entry functions for the builder */
Builder* BVH4Bezier1vBuilder_OBB_New (void* bvh, Scene* scene, size_t mode) { return new BVHNHairBuilderSAH<4,Bezier1v>((BVH4*)bvh,scene); }
Builder* BVH4Bezier1iBuilder_OBB_New (void* bvh, Scene* scene, size_t mode) { return new BVHNHairBuilderSAH<4,Bezier1i>((BVH4*)bvh,scene); }
Builder* BVH4OBBBezier1iMBBuilder_OBB (void* bvh, Scene* scene, size_t mode) { return new BVHNHairMBlurBuilderSAH<4,Bezier1i>((BVH4*)bvh,scene); }
#if defined(__AVX__)
Builder* BVH8Bezier1vBuilder_OBB_New (void* bvh, Scene* scene, size_t mode) { return new BVHNHairBuilderSAH<8,Bezier1v>((BVH8*)bvh,scene); }
Builder* BVH8Bezier1iBuilder_OBB_New (void* bvh, Scene* scene, size_t mode) { return new BVHNHairBuilderSAH<8,Bezier1i>((BVH8*)bvh,scene); }
Builder* BVH8OBBBezier1iMBBuilder_OBB (void* bvh, Scene* scene, size_t mode) { return new BVHNHairMBlurBuilderSAH<8,Bezier1i>((BVH8*)bvh,scene); }
#endif
}
+126
View File
@@ -0,0 +1,126 @@
// ======================================================================== //
// 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 "../builders/bvh_builder_hair.h"
#include "../builders/bvh_builder_msmblur_hair.h"
#include "../builders/primrefgen.h"
#include "../geometry/bezier1v.h"
#include "../geometry/bezier1i.h"
#if defined(EMBREE_GEOMETRY_HAIR)
namespace embree
{
namespace isa
{
/* FIXME: add fast path for single-segment motion blur */
template<int N, typename Primitive>
struct BVHNHairMBlurBuilderSAH : public Builder
{
typedef BVHN<N> BVH;
typedef typename BVH::NodeRef NodeRef;
typedef typename BVH::NodeRecordMB4D NodeRecordMB4D;
BVH* bvh;
Scene* scene;
BVHNHairMBlurBuilderSAH (BVH* bvh, Scene* scene)
: bvh(bvh), scene(scene) {}
void build()
{
/* fast path for empty BVH */
const size_t numPrimitives = scene->getNumPrimitives<NativeCurves,true>();
if (numPrimitives == 0) {
bvh->set(BVH::emptyNode,empty,0);
return;
}
double t0 = bvh->preBuild(TOSTRING(isa) "::BVH" + toString(N) + "HairMBlurBuilderSAH");
//profile(1,5,numPrimitives,[&] (ProfileTimer& timer) {
/* create primref array */
mvector<PrimRefMB> prims0(scene->device,numPrimitives);
const PrimInfoMB pinfo = createPrimRefArrayMSMBlur<NativeCurves>(scene,prims0,bvh->scene->progressInterface);
/* estimate acceleration structure size */
const size_t node_bytes = pinfo.num_time_segments*sizeof(typename BVH::AlignedNodeMB)/(4*N);
const size_t leaf_bytes = size_t(1.2*Primitive::blocks(pinfo.num_time_segments)*sizeof(Primitive));
bvh->alloc.init_estimate(node_bytes+leaf_bytes);
/* settings for BVH build */
BVHBuilderHairMSMBlur::Settings settings;
settings.branchingFactor = N;
settings.maxDepth = BVH::maxBuildDepthLeaf;
settings.logBlockSize = 1;
settings.minLeafSize = 1;
settings.maxLeafSize = BVH::maxLeafBlocks;
/* creates a leaf node */
auto createLeaf = [&] (const SetMB& prims, const FastAllocator::CachedAllocator& alloc) -> NodeRecordMB4D
{
size_t start = prims.object_range.begin();
size_t end = prims.object_range.end();
size_t items = prims.object_range.size();
Primitive* accel = (Primitive*) alloc.malloc1(items*sizeof(Primitive));
const NodeRef node = bvh->encodeLeaf((char*)accel,items);
LBBox3fa bounds = empty;
for (size_t i=0; i<items; i++)
bounds.extend(accel[i].fillMB(prims.prims->data(),start,end,bvh->scene,prims.time_range));
return NodeRecordMB4D(node,bounds,prims.time_range);
};
/* build the hierarchy */
auto root = BVHBuilderHairMSMBlur::build<NodeRef>
(scene, prims0, pinfo,
RecalculatePrimRef<NativeCurves>(scene),
typename BVH::CreateAlloc(bvh),
typename BVH::AlignedNodeMB4D::Create(),
typename BVH::AlignedNodeMB4D::Set(),
typename BVH::UnalignedNodeMB::Create(),
typename BVH::UnalignedNodeMB::Set(),
createLeaf,
bvh->scene->progressInterface,
settings);
bvh->set(root.ref,root.lbounds,pinfo.num_time_segments);
//});
/* clear temporary data for static geometry */
if (scene->isStatic()) bvh->shrink();
bvh->cleanup();
bvh->postBuild(t0);
}
void clear() {
}
};
/*! entry functions for the builder */
Builder* BVH4OBBBezier1iMBBuilder_OBB (void* bvh, Scene* scene, size_t mode) { return new BVHNHairMBlurBuilderSAH<4,Bezier1i>((BVH4*)bvh,scene); }
#if defined(__AVX__)
Builder* BVH8OBBBezier1iMBBuilder_OBB (void* bvh, Scene* scene, size_t mode) { return new BVHNHairMBlurBuilderSAH<8,Bezier1i>((BVH8*)bvh,scene); }
#endif
}
}
#endif
+5 -5
View File
@@ -128,7 +128,7 @@ namespace embree
v2.x[i] = p2.x; v2.y[i] = p2.y; v2.z[i] = p2.z;
}
Triangle4::store_nt(accel,Triangle4(v0,v1,v2,vgeomID,vprimID,true));
Triangle4::store_nt(accel,Triangle4(v0,v1,v2,vgeomID,vprimID));
BBox3fa box_o = BBox3fa((Vec3fa)lower,(Vec3fa)upper);
#if ROTATE_TREE
if (N == 4)
@@ -183,7 +183,7 @@ namespace embree
v1.x[i] = p1.x; v1.y[i] = p1.y; v1.z[i] = p1.z;
v2.x[i] = p2.x; v2.y[i] = p2.y; v2.z[i] = p2.z;
}
Triangle4v::store_nt(accel,Triangle4v(v0,v1,v2,vgeomID,vprimID,true));
Triangle4v::store_nt(accel,Triangle4v(v0,v1,v2,vgeomID,vprimID));
BBox3fa box_o = BBox3fa((Vec3fa)lower,(Vec3fa)upper);
#if ROTATE_TREE
if (N == 4)
@@ -249,7 +249,7 @@ namespace embree
v2[i] = 0;
}
Triangle4i::store_nt(accel,Triangle4i(v0,v1,v2,vgeomID,vprimID,true));
Triangle4i::store_nt(accel,Triangle4i(v0,v1,v2,vgeomID,vprimID));
BBox3fa box_o = BBox3fa((Vec3fa)lower,(Vec3fa)upper);
#if ROTATE_TREE
if (N == 4)
@@ -306,7 +306,7 @@ namespace embree
v2.x[i] = p2.x; v2.y[i] = p2.y; v2.z[i] = p2.z;
v3.x[i] = p3.x; v3.y[i] = p3.y; v3.z[i] = p3.z;
}
Quad4v::store_nt(accel,Quad4v(v0,v1,v2,v3,vgeomID,vprimID,true));
Quad4v::store_nt(accel,Quad4v(v0,v1,v2,v3,vgeomID,vprimID));
BBox3fa box_o = BBox3fa((Vec3fa)lower,(Vec3fa)upper);
#if ROTATE_TREE
if (N == 4)
@@ -349,7 +349,7 @@ namespace embree
const unsigned index = morton[start+i].index;
const unsigned primID = index;
bounds.extend(mesh->bounds(primID));
new (&accel[i]) Object(geomID,primID,true);
new (&accel[i]) Object(geomID,primID);
}
BBox3fa box_o = bounds;
#if ROTATE_TREE
+4 -4
View File
@@ -64,7 +64,7 @@ namespace embree
Primitive* accel = (Primitive*) alloc.malloc1(items*sizeof(Primitive),BVH::byteAlignment);
typename BVH::NodeRef node = BVH::encodeLeaf((char*)accel,items);
for (size_t i=0; i<items; i++) {
accel[i].fill(prims,start,set.end(),bvh->scene,i==(items-1));
accel[i].fill(prims,start,set.end(),bvh->scene);
}
return node;
}
@@ -89,7 +89,7 @@ namespace embree
Primitive* accel = (Primitive*) alloc.malloc1(items*sizeof(Primitive),BVH::byteAlignment);
typename BVH::NodeRef node = BVH::encodeLeaf((char*)accel,items);
for (size_t i=0; i<items; i++) {
accel[i].fill(prims,start,set.end(),bvh->scene,i==(items-1));
accel[i].fill(prims,start,set.end(),bvh->scene);
}
return node;
}
@@ -364,7 +364,7 @@ namespace embree
LBBox3fa allBounds = empty;
for (size_t i=0; i<items; i++)
allBounds.extend(accel[i].fillMB(prims, start, set.end(), bvh->scene, time, i==(items-1)));
allBounds.extend(accel[i].fillMB(prims, start, set.end(), bvh->scene, time));
return NodeRecordMB(node,allBounds);
}
@@ -392,7 +392,7 @@ namespace embree
NodeRef node = bvh->encodeLeaf((char*)accel,items);
LBBox3fa allBounds = empty;
for (size_t i=0; i<items; i++)
allBounds.extend(accel[i].fillMB(current.prims.prims->data(), start, current.prims.object_range.end(), bvh->scene, current.prims.time_range, i==(items-1)));
allBounds.extend(accel[i].fillMB(current.prims.prims->data(), start, current.prims.object_range.end(), bvh->scene, current.prims.time_range));
return NodeRecordMB4D(node,allBounds,current.prims.time_range);
}
+6 -12
View File
@@ -37,9 +37,10 @@ namespace embree
namespace isa
{
template<int N, int types, bool robust, typename PrimitiveIntersector1>
void BVHNIntersector1<N,types,robust,PrimitiveIntersector1>::intersect(const BVH* __restrict__ bvh, Ray& __restrict__ ray, IntersectContext* context)
void BVHNIntersector1<N,types,robust,PrimitiveIntersector1>::intersect(const Accel::Intersectors* __restrict__ This, Ray& __restrict__ ray, IntersectContext* __restrict__ context)
{
/*! perform per ray precalculations required by the primitive intersector */
const BVH* __restrict__ bvh = (const BVH*) This->ptr;
Precalculations pre(ray,bvh);
/*! stack state */
@@ -105,12 +106,8 @@ namespace embree
if (unlikely(nodeTraverser.traverseTransform(cur,ray,vray,context,stackPtr,stackEnd)))
goto pop;
/*! check for empty leaf in case we accidentally hit one */
assert(cur != BVH::emptyNode);
if (cur == BVH::emptyNode)
goto pop;
/*! this is a leaf node */
assert(cur != BVH::emptyNode);
STAT3(normal.trav_leaves,1,1,1);
size_t num; Primitive* prim = (Primitive*) cur.leaf(num);
size_t lazy_node = 0;
@@ -128,13 +125,14 @@ namespace embree
}
template<int N, int types, bool robust, typename PrimitiveIntersector1>
void BVHNIntersector1<N,types,robust,PrimitiveIntersector1>::occluded(const BVH* __restrict__ bvh, Ray& __restrict__ ray, IntersectContext* context)
void BVHNIntersector1<N,types,robust,PrimitiveIntersector1>::occluded(const Accel::Intersectors* __restrict__ This, Ray& __restrict__ ray, IntersectContext* __restrict__ context)
{
/*! early out for already occluded rays */
if (unlikely(ray.geomID == 0))
return;
/*! perform per ray precalculations required by the primitive intersector */
const BVH* __restrict__ bvh = (const BVH*) This->ptr;
Precalculations pre(ray,bvh);
/*! stack state */
@@ -191,12 +189,8 @@ namespace embree
if (unlikely(nodeTraverser.traverseTransform(cur,ray,vray,context,stackPtr,stackEnd)))
goto pop;
/*! check for empty leaf in case we accidentally hit one */
assert(cur != BVH::emptyNode);
if (cur == BVH::emptyNode)
goto pop;
/*! this is a leaf node */
assert(cur != BVH::emptyNode);
STAT3(shadow.trav_leaves,1,1,1);
size_t num; Primitive* prim = (Primitive*) cur.leaf(num);
size_t lazy_node = 0;
+2 -2
View File
@@ -42,8 +42,8 @@ namespace embree
static const size_t Nx = (types == BVH_AN1 || types == BVH_QN1) ? vextend<N>::size : N;
public:
static void intersect(const BVH* This, Ray& ray, IntersectContext* context);
static void occluded (const BVH* This, Ray& ray, IntersectContext* context);
static void intersect(const Accel::Intersectors* This, Ray& ray, IntersectContext* context);
static void occluded (const Accel::Intersectors* This, Ray& ray, IntersectContext* context);
};
}
}
+38 -50
View File
@@ -105,12 +105,8 @@ namespace embree
BVHNNodeTraverser1<N,Nx,types>::traverseClosestHit(cur,mask,tNear,stackPtr,stackEnd);
}
/*! check for empty leaf in case we accidentally hit one */
assert(cur != BVH::emptyNode);
if (cur == BVH::emptyNode)
goto pop;
/*! this is a leaf node */
assert(cur != BVH::emptyNode);
STAT3(normal.trav_leaves, 1, 1, 1);
size_t num; Primitive* prim = (Primitive*)cur.leaf(num);
@@ -128,13 +124,15 @@ namespace embree
}
template<int N, int K, int types, bool robust, typename PrimitiveIntersectorK, bool single>
void BVHNIntersectorKHybrid<N,K,types,robust,PrimitiveIntersectorK,single>::intersect(vint<K>* __restrict__ valid_i, BVH* __restrict__ bvh, RayK<K>& __restrict__ ray, IntersectContext* context)
void BVHNIntersectorKHybrid<N,K,types,robust,PrimitiveIntersectorK,single>::intersect(vint<K>* __restrict__ valid_i, Accel::Intersectors* __restrict__ This, RayK<K>& __restrict__ ray, IntersectContext* __restrict__ context)
{
BVH* __restrict__ bvh = (BVH*) This->ptr;
#if ENABLE_FAST_COHERENT_CODEPATHS == 1
assert(context);
if (unlikely(types == BVH_AN1 && context->user && isCoherent(context->user->flags)))
{
intersect_coherent(valid_i,bvh,ray,context);
intersect_coherent(valid_i,This,ray,context);
return;
}
#endif
@@ -181,7 +179,7 @@ namespace embree
/* determine switch threshold based on flags */
const size_t switchThreshold = (context->user && isCoherent(context->user->flags)) ? 2 : switchThresholdIncoherent;
vint<K> octant = \
vint<K> octant =
select(vfloat<K>(rdir.x) < 0.0f,vint<K>(1),vint<K>(zero)) |
select(vfloat<K>(rdir.y) < 0.0f,vint<K>(2),vint<K>(zero)) |
select(vfloat<K>(rdir.z) < 0.0f,vint<K>(4),vint<K>(zero));
@@ -349,12 +347,8 @@ namespace embree
break;
}
/*! check for empty leaf in case we accidentally hit one */
assert(cur != BVH::emptyNode);
if (cur == BVH::emptyNode)
goto pop;
/* intersect leaf */
assert(cur != BVH::emptyNode);
const vbool<K> valid_leaf = ray_tfar > curDist;
STAT3(normal.trav_leaves,1,popcnt(valid_leaf),K);
if (unlikely(none(valid_leaf))) continue;
@@ -376,8 +370,13 @@ namespace embree
template<int N, int K, int types, bool robust, typename PrimitiveIntersectorK, bool single>
void BVHNIntersectorKHybrid<N,K,types,robust,PrimitiveIntersectorK,single>::intersect_coherent(vint<K>* __restrict__ valid_i, BVH* __restrict__ bvh, RayK<K>& __restrict__ ray, IntersectContext* context)
void BVHNIntersectorKHybrid<N,K,types,robust,PrimitiveIntersectorK,single>::intersect_coherent(vint<K>* __restrict__ valid_i,
Accel::Intersectors* __restrict__ This,
RayK<K>& __restrict__ ray,
IntersectContext* context)
{
BVH* __restrict__ bvh = (BVH*) This->ptr;
/* filter out invalid rays */
vbool<K> valid = *valid_i == -1;
#if defined(EMBREE_IGNORE_INVALID_RAYS)
@@ -415,7 +414,7 @@ namespace embree
const vfloat<K> ray_tnear = select(octant_valid,org_ray_tnear,vfloat<K>(pos_inf));
vfloat<K> ray_tfar = select(octant_valid,org_ray_tfar ,vfloat<K>(neg_inf));
Frustum frustum(octant_valid,rdir,org,ray_tnear,ray_tfar);
Frustum<N,Nx,K,robust> frustum(octant_valid,org,rdir,ray_tnear,ray_tfar);
StackItemT<NodeRef> stack[stackSizeSingle]; //!< stack of nodes
StackItemT<NodeRef>* stackPtr = stack + 1; //!< current stack pointer
@@ -442,8 +441,8 @@ namespace embree
const NodeRef nodeRef = cur;
const AlignedNode* __restrict__ const node = nodeRef.alignedNode();
__aligned(64) float fmin[16];
size_t m_frusta_node = frustum.intersect(nodeRef,fmin);
vfloat<Nx> fmin;
size_t m_frusta_node = frustum.intersect(node,fmin);
if (unlikely(!m_frusta_node)) goto pop;
cur = BVH::emptyNode;
@@ -501,15 +500,12 @@ namespace embree
std::swap(stackPtr[-3],stackPtr[-2]);
}
}
}
/*! check for empty leaf in case we accidentally hit one */
assert(cur != BVH::emptyNode);
if (cur == BVH::emptyNode)
goto pop;
/* intersect leaf */
assert(cur != BVH::invalidNode);
assert(cur != BVH::emptyNode);
const vbool<K> valid_leaf = ray_tfar > curDist;
STAT3(normal.trav_leaves,1,popcnt(valid_leaf),K);
if (unlikely(none(valid_leaf))) continue;
@@ -517,17 +513,13 @@ namespace embree
size_t lazy_node = 0;
PrimitiveIntersectorK::intersect(valid_leaf,pre,ray,context,prim,items,lazy_node);
#if 1
/* reduce max distance interval on successful intersection */
if (likely(any((ray.tfar < ray_tfar) & valid_leaf)))
{
ray_tfar = select(valid_leaf,ray.tfar,ray_tfar);
//frusta_max_dist = reduce_max(ray_tfar);
frustum.updateMaxDist(ray_tfar);
}
#else
ray_tfar = select(valid_leaf,ray.tfar,ray_tfar);
#endif
if (unlikely(lazy_node)) {
stackPtr->ptr = lazy_node;
@@ -588,12 +580,8 @@ namespace embree
BVHNNodeTraverser1<N,Nx,types>::traverseAnyHit(cur,mask,tNear,stackPtr,stackEnd);
}
/*! check for empty leaf in case we accidentally hit one */
assert(cur != BVH::emptyNode);
if (cur == BVH::emptyNode)
goto pop;
/*! this is a leaf node */
assert(cur != BVH::emptyNode);
STAT3(shadow.trav_leaves,1,1,1);
size_t num; Primitive* prim = (Primitive*) cur.leaf(num);
@@ -612,13 +600,15 @@ namespace embree
}
template<int N, int K, int types, bool robust, typename PrimitiveIntersectorK, bool single>
void BVHNIntersectorKHybrid<N,K,types,robust,PrimitiveIntersectorK,single>::occluded(vint<K>* __restrict__ valid_i, BVH* __restrict__ bvh, RayK<K>& __restrict__ ray, IntersectContext* context)
void BVHNIntersectorKHybrid<N,K,types,robust,PrimitiveIntersectorK,single>::occluded(vint<K>* __restrict__ valid_i, Accel::Intersectors* __restrict__ This, RayK<K>& __restrict__ ray, IntersectContext* context)
{
BVH* __restrict__ bvh = (BVH*) This->ptr;
#if ENABLE_FAST_COHERENT_CODEPATHS == 1
assert(context);
if (unlikely(types == BVH_AN1 && context->user && isCoherent(context->user->flags)))
{
occluded_coherent(valid_i,bvh,ray,context);
occluded_coherent(valid_i,This,ray,context);
return;
}
#endif
@@ -778,12 +768,9 @@ namespace embree
break;
}
/*! check for empty leaf in case we accidentally hit one */
assert(cur != BVH::emptyNode);
if (cur == BVH::emptyNode)
goto pop;
/* intersect leaf */
assert(cur != BVH::emptyNode);
const vbool<K> valid_leaf = ray_tfar > curDist;
STAT3(shadow.trav_leaves,1,popcnt(valid_leaf),K);
if (unlikely(none(valid_leaf))) continue;
@@ -805,8 +792,11 @@ namespace embree
template<int N, int K, int types, bool robust, typename PrimitiveIntersectorK, bool single>
void BVHNIntersectorKHybrid<N,K,types,robust,PrimitiveIntersectorK,single>::occluded_coherent(vint<K>* __restrict__ valid_i, BVH* __restrict__ bvh, RayK<K>& __restrict__ ray, IntersectContext* context)
void BVHNIntersectorKHybrid<N,K,types,robust,PrimitiveIntersectorK,single>::occluded_coherent(vint<K>* __restrict__ valid_i, Accel::Intersectors* __restrict__ This,
RayK<K>& __restrict__ ray, IntersectContext* context)
{
BVH* __restrict__ bvh = (BVH*) This->ptr;
/* filter out invalid rays */
vbool<K> valid = *valid_i == -1;
#if defined(EMBREE_IGNORE_INVALID_RAYS)
@@ -848,12 +838,12 @@ namespace embree
const vfloat<K> ray_tnear = select(octant_valid,org_ray_tnear,vfloat<K>(pos_inf));
const vfloat<K> ray_tfar = select(octant_valid,org_ray_tfar ,vfloat<K>(neg_inf));
const Frustum frustum(octant_valid,rdir,org,ray_tnear,ray_tfar);
const Frustum<N,Nx,K,robust> frustum(octant_valid,org,rdir,ray_tnear,ray_tfar);
StackItemT<NodeRef> stack[stackSizeSingle]; //!< stack of nodes
StackItemT<NodeRef>* stackPtr = stack + 1; //!< current stack pointer
stack[0].ptr = bvh->root;
stack[0].dist = movemask(octant_valid);
stack[0].dist = (unsigned int)movemask(octant_valid);
while (1) pop:
{
@@ -875,8 +865,8 @@ namespace embree
const NodeRef nodeRef = cur;
const AlignedNode* __restrict__ const node = nodeRef.alignedNode();
__aligned(64) float fmin[16];
size_t m_frusta_node = frustum.intersect(nodeRef,fmin);
vfloat<Nx> fmin;
size_t m_frusta_node = frustum.intersect(node,fmin);
if (unlikely(!m_frusta_node)) goto pop;
cur = BVH::emptyNode;
@@ -905,20 +895,16 @@ namespace embree
stackPtr++;
}
cur = child;
m_active = movemask(lhit);
m_active = (unsigned int)movemask(lhit);
}
} while(m_frusta_node);
if (unlikely(cur == BVH::emptyNode)) goto pop;
}
/*! check for empty leaf in case we accidentally hit one */
assert(cur != BVH::emptyNode);
if (cur == BVH::emptyNode)
goto pop;
/* intersect leaf */
assert(cur != BVH::invalidNode);
assert(cur != BVH::emptyNode);
#if defined(__AVX__)
STAT3(normal.trav_leaves,1,__popcnt(m_active),K);
#endif
@@ -932,7 +918,7 @@ namespace embree
if (unlikely(lazy_node)) {
stackPtr->ptr = lazy_node;
stackPtr->dist = movemask(octant_valid);
stackPtr->dist = (unsigned int)movemask(octant_valid);
stackPtr++;
}
}
@@ -942,5 +928,7 @@ namespace embree
AVX_ZERO_UPPER();
}
}
}
+5 -177
View File
@@ -19,6 +19,7 @@
#include "bvh.h"
#include "../common/ray.h"
#include "../common/stack_item.h"
#include "frustum.h"
namespace embree
{
@@ -38,7 +39,6 @@ namespace embree
typedef typename BVH::NodeRef NodeRef;
typedef typename BVH::BaseNode BaseNode;
typedef typename BVH::AlignedNode AlignedNode;
typedef typename BVH::AlignedNodeMB AlignedNodeMB;
static const size_t stackSizeSingle = 1+(N-1)*BVH::maxDepth+3; // +3 due to 16-wide store
static const size_t stackSizeChunk = 1+(N-1)*BVH::maxDepth;
@@ -49,178 +49,6 @@ namespace embree
(K==16) ? 14 : // 14 seems to work best for KNL due to better ordered chunk traversal
0;
struct Frustum
{
__forceinline Frustum(const vbool<K> &octant_valid,
const Vec3vf<K> &rdir,
const Vec3vf<K> &org,
const vfloat<K> &ray_tnear,
const vfloat<K> &ray_tfar)
{
const Vec3fa reduced_min_rdir( reduce_min(select(octant_valid,rdir.x,pos_inf)),
reduce_min(select(octant_valid,rdir.y,pos_inf)),
reduce_min(select(octant_valid,rdir.z,pos_inf)) );
const Vec3fa reduced_max_rdir( reduce_max(select(octant_valid,rdir.x,neg_inf)),
reduce_max(select(octant_valid,rdir.y,neg_inf)),
reduce_max(select(octant_valid,rdir.z,neg_inf)) );
const Vec3fa reduced_min_org( reduce_min(select(octant_valid,org.x,pos_inf)),
reduce_min(select(octant_valid,org.y,pos_inf)),
reduce_min(select(octant_valid,org.z,pos_inf)) );
const Vec3fa reduced_max_org( reduce_max(select(octant_valid,org.x,neg_inf)),
reduce_max(select(octant_valid,org.y,neg_inf)),
reduce_max(select(octant_valid,org.z,neg_inf)) );
min_rdir = select(ge_mask(reduced_min_rdir, Vec3fa(zero)), reduced_min_rdir, reduced_max_rdir);
max_rdir = select(ge_mask(reduced_min_rdir, Vec3fa(zero)), reduced_max_rdir, reduced_min_rdir);
if (!robust)
{
min_org_rdir = min_rdir * select(ge_mask(reduced_min_rdir, Vec3fa(zero)), reduced_max_org, reduced_min_org);
max_org_rdir = max_rdir * select(ge_mask(reduced_min_rdir, Vec3fa(zero)), reduced_min_org, reduced_max_org);
}
else
{
min_org_rdir = select(ge_mask(reduced_min_rdir, Vec3fa(zero)), reduced_max_org, reduced_min_org);
max_org_rdir = select(ge_mask(reduced_min_rdir, Vec3fa(zero)), reduced_min_org, reduced_max_org);
}
min_dist = reduce_min(select(octant_valid,ray_tnear,vfloat<K>(pos_inf)));
max_dist = reduce_max(select(octant_valid,ray_tfar ,vfloat<K>(neg_inf)));
#if defined(__AVX512ER__) // KNL+
min_max_rdirX = align_shift_right<16/2>(vfloat16(max_rdir.x),vfloat16(min_rdir.x));
min_max_rdirY = align_shift_right<16/2>(vfloat16(max_rdir.y),vfloat16(min_rdir.y));
min_max_rdirZ = align_shift_right<16/2>(vfloat16(max_rdir.z),vfloat16(min_rdir.z));
min_max_org_rdirX = align_shift_right<16/2>(vfloat16(max_org_rdir.x),vfloat16(min_org_rdir.x));
min_max_org_rdirY = align_shift_right<16/2>(vfloat16(max_org_rdir.y),vfloat16(min_org_rdir.y));
min_max_org_rdirZ = align_shift_right<16/2>(vfloat16(max_org_rdir.z),vfloat16(min_org_rdir.z));
maskX = (vfloat<16>(min_rdir.x) >= 0.0f) ^ vbool16(0xff00);
maskY = (vfloat<16>(min_rdir.y) >= 0.0f) ^ vbool16(0xff00);
maskZ = (vfloat<16>(min_rdir.z) >= 0.0f) ^ vbool16(0xff00);
#else
nearX = (min_rdir.x < 0.0f) ? 1*sizeof(vfloat<N>) : 0*sizeof(vfloat<N>);
nearY = (min_rdir.y < 0.0f) ? 3*sizeof(vfloat<N>) : 2*sizeof(vfloat<N>);
nearZ = (min_rdir.z < 0.0f) ? 5*sizeof(vfloat<N>) : 4*sizeof(vfloat<N>);
farX = nearX ^ sizeof(vfloat<N>);
farY = nearY ^ sizeof(vfloat<N>);
farZ = nearZ ^ sizeof(vfloat<N>);
#endif
}
__forceinline unsigned int intersect(const NodeRef &nodeRef, float * const __restrict__ dist) const
{
/* only default alignedNodes are currently supported */
const AlignedNode* __restrict__ const node = nodeRef.alignedNode();
#if defined(__AVX512ER__)
const vfloat16 lowerX = vfloat16(*(const vfloat<N>*)((const char*)&node->lower_x));
const vfloat16 lowerY = vfloat16(*(const vfloat<N>*)((const char*)&node->lower_y));
const vfloat16 lowerZ = vfloat16(*(const vfloat<N>*)((const char*)&node->lower_z));
const vfloat16 upperX = vfloat16(*(const vfloat<N>*)((const char*)&node->upper_x));
const vfloat16 upperY = vfloat16(*(const vfloat<N>*)((const char*)&node->upper_y));
const vfloat16 upperZ = vfloat16(*(const vfloat<N>*)((const char*)&node->upper_z));
const vfloat16 bminmaxX = select(maskX,lowerX,upperX);
const vfloat16 bminmaxY = select(maskY,lowerY,upperY);
const vfloat16 bminmaxZ = select(maskZ,lowerZ,upperZ);
if (robust)
{
const vfloat16 fminmaxX = (bminmaxX - min_max_org_rdirX) * min_max_rdirX;
const vfloat16 fminmaxY = (bminmaxY - min_max_org_rdirY) * min_max_rdirY;
const vfloat16 fminmaxZ = (bminmaxZ - min_max_org_rdirZ) * min_max_rdirZ;
const float round_down = 1.0f-2.0f*float(ulp); // FIXME: use per instruction rounding for AVX512
const float round_up = 1.0f+2.0f*float(ulp);
const vfloat16 fmin = round_down*max(fminmaxX, fminmaxY, fminmaxZ, vfloat16(min_dist));
vfloat16::store(dist,fmin);
const vfloat16 fmax = round_up*min(fminmaxX, fminmaxY, fminmaxZ, vfloat16(max_dist));
const vbool16 vmask_node_hit = le(vbool16((((int)1 << N)-1)),fmin,align_shift_right<8>(fmax,fmax));
return movemask(vmask_node_hit);
}
else
{
const vfloat16 fminmaxX = msub(bminmaxX, min_max_rdirX, min_max_org_rdirX);
const vfloat16 fminmaxY = msub(bminmaxY, min_max_rdirY, min_max_org_rdirY);
const vfloat16 fminmaxZ = msub(bminmaxZ, min_max_rdirZ, min_max_org_rdirZ);
const vfloat16 fmin = max(fminmaxX, fminmaxY, fminmaxZ, vfloat16(min_dist));
vfloat16::store(dist,fmin);
const vfloat16 fmax = min(fminmaxX, fminmaxY, fminmaxZ, vfloat16(max_dist));
const vbool16 vmask_node_hit = le(vbool16((((int)1 << N)-1)),fmin,align_shift_right<8>(fmax,fmax));
return movemask(vmask_node_hit);
}
#else
const vfloat<N> bminX = vfloat<N>(*(const vfloat<N>*)((const char*)&node->lower_x + nearX));
const vfloat<N> bminY = vfloat<N>(*(const vfloat<N>*)((const char*)&node->lower_x + nearY));
const vfloat<N> bminZ = vfloat<N>(*(const vfloat<N>*)((const char*)&node->lower_x + nearZ));
const vfloat<N> bmaxX = vfloat<N>(*(const vfloat<N>*)((const char*)&node->lower_x + farX));
const vfloat<N> bmaxY = vfloat<N>(*(const vfloat<N>*)((const char*)&node->lower_x + farY));
const vfloat<N> bmaxZ = vfloat<N>(*(const vfloat<N>*)((const char*)&node->lower_x + farZ));
if (robust)
{
const vfloat<N> fminX = (bminX - vfloat<N>(min_org_rdir.x)) * vfloat<N>(min_rdir.x);
const vfloat<N> fminY = (bminY - vfloat<N>(min_org_rdir.y)) * vfloat<N>(min_rdir.y);
const vfloat<N> fminZ = (bminZ - vfloat<N>(min_org_rdir.z)) * vfloat<N>(min_rdir.z);
const vfloat<N> fmaxX = (bmaxX - vfloat<N>(max_org_rdir.x)) * vfloat<N>(max_rdir.x);
const vfloat<N> fmaxY = (bmaxY - vfloat<N>(max_org_rdir.y)) * vfloat<N>(max_rdir.y);
const vfloat<N> fmaxZ = (bmaxZ - vfloat<N>(max_org_rdir.z)) * vfloat<N>(max_rdir.z);
const float round_down = 1.0f-2.0f*float(ulp); // FIXME: use per instruction rounding for AVX512
const float round_up = 1.0f+2.0f*float(ulp);
const vfloat<N> fmin = max(fminX, fminY, fminZ, vfloat<N>(min_dist));
vfloat<N>::store(dist,fmin);
const vfloat<N> fmax = min(fmaxX, fmaxY, fmaxZ, vfloat<N>(max_dist));
const vbool<N> vmask_node_hit = (round_down*fmin <= round_up*fmax);
size_t m_node = movemask(vmask_node_hit) & (((size_t)1 << N)-1);
return m_node;
}
else
{
const vfloat<N> fminX = msub(bminX, vfloat<N>(min_rdir.x), vfloat<N>(min_org_rdir.x));
const vfloat<N> fminY = msub(bminY, vfloat<N>(min_rdir.y), vfloat<N>(min_org_rdir.y));
const vfloat<N> fminZ = msub(bminZ, vfloat<N>(min_rdir.z), vfloat<N>(min_org_rdir.z));
const vfloat<N> fmaxX = msub(bmaxX, vfloat<N>(max_rdir.x), vfloat<N>(max_org_rdir.x));
const vfloat<N> fmaxY = msub(bmaxY, vfloat<N>(max_rdir.y), vfloat<N>(max_org_rdir.y));
const vfloat<N> fmaxZ = msub(bmaxZ, vfloat<N>(max_rdir.z), vfloat<N>(max_org_rdir.z));
const vfloat<N> fmin = maxi(fminX, fminY, fminZ, vfloat<N>(min_dist));
vfloat<N>::store(dist,fmin);
const vfloat<N> fmax = mini(fmaxX, fmaxY, fmaxZ, vfloat<N>(max_dist));
const vbool<N> vmask_node_hit = fmin <= fmax;
size_t m_node = movemask(vmask_node_hit) & (((size_t)1 << N)-1);
return m_node;
}
#endif
}
__forceinline void updateMaxDist(const vfloat<K> &ray_tfar)
{
max_dist = reduce_max(ray_tfar);
}
#if defined(__AVX512ER__) // KNL+
vbool16 maskX, maskY, maskZ;
vfloat16 min_max_rdirX, min_max_rdirY, min_max_rdirZ;
vfloat16 min_max_org_rdirX, min_max_org_rdirY, min_max_org_rdirZ;
#else
size_t nearX, nearY, nearZ;
size_t farX, farY, farZ;
#endif
Vec3fa min_rdir;
Vec3fa max_rdir;
Vec3fa min_org_rdir;
Vec3fa max_org_rdir;
float min_dist;
float max_dist;
};
private:
static void intersect1(const BVH* bvh, NodeRef root, const size_t k, Precalculations& pre,
RayK<K>& ray, const Vec3vf<K> &ray_org, const Vec3vf<K> &ray_dir, const Vec3vf<K> &ray_rdir, const vfloat<K> &ray_tnear, const vfloat<K> &ray_tfar, const Vec3vi<K>& nearXYZ, IntersectContext* context);
@@ -228,11 +56,11 @@ namespace embree
RayK<K>& ray, const Vec3vf<K> &ray_org, const Vec3vf<K> &ray_dir, const Vec3vf<K> &ray_rdir, const vfloat<K> &ray_tnear, const vfloat<K> &ray_tfar, const Vec3vi<K>& nearXYZ, IntersectContext* context);
public:
static void intersect(vint<K>* valid, BVH* bvh, RayK<K>& ray, IntersectContext* context);
static void occluded (vint<K>* valid, BVH* bvh, RayK<K>& ray, IntersectContext* context);
static void intersect(vint<K>* valid, Accel::Intersectors* This, RayK<K>& ray, IntersectContext* context);
static void occluded (vint<K>* valid, Accel::Intersectors* This, RayK<K>& ray, IntersectContext* context);
static void intersect_coherent(vint<K>* valid, BVH* bvh, RayK<K>& ray, IntersectContext* context);
static void occluded_coherent(vint<K>* valid, BVH* bvh, RayK<K>& ray, IntersectContext* context);
static void intersect_coherent(vint<K>* valid, Accel::Intersectors* This, RayK<K>& ray, IntersectContext* context);
static void occluded_coherent (vint<K>* valid, Accel::Intersectors* This, RayK<K>& ray, IntersectContext* context);
};
+5 -43
View File
@@ -214,7 +214,7 @@ namespace embree
#endif
#if defined(__AVX512F__)
#if defined(__AVX512F__) && !defined(__AVX512VL__) // KNL
template<>
__forceinline size_t intersectNode<4,16>(const typename BVH4::AlignedNode* node, const TravRay<4,16>& ray, const vfloat16& tnear, const vfloat16& tfar, vfloat16& dist)
@@ -236,7 +236,6 @@ namespace embree
template<>
__forceinline size_t intersectNode<8,16>(const typename BVH8::AlignedNode* node, const TravRay<8,16>& ray, const vfloat16& tnear, const vfloat16& tfar, vfloat16& dist)
{
#if defined(__AVX512ER__)
const vllong8 invalid((size_t)BVH8::emptyNode);
const vboold8 m_valid(invalid != vllong8::loadu(node->children));
const vfloat16 bminmaxX = permute(vfloat16::load((const float*)&node->lower_x), ray.permX);
@@ -248,19 +247,7 @@ namespace embree
const vfloat16 tNear = max(tNearFarX, tNearFarY, tNearFarZ, tnear);
const vfloat16 tFar = min(tNearFarX, tNearFarY, tNearFarZ, tfar);
const vbool16 vmask = le(vboolf16(m_valid),tNear,align_shift_right<8>(tFar, tFar));
#else
const vfloat16 tNearX = msub(vfloat16(*(vfloat8*)((const char*)&node->lower_x+ray.nearX)), ray.rdir.x, ray.org_rdir.x);
const vfloat16 tNearY = msub(vfloat16(*(vfloat8*)((const char*)&node->lower_x+ray.nearY)), ray.rdir.y, ray.org_rdir.y);
const vfloat16 tNearZ = msub(vfloat16(*(vfloat8*)((const char*)&node->lower_x+ray.nearZ)), ray.rdir.z, ray.org_rdir.z);
const vfloat16 tFarX = msub(vfloat16(*(vfloat8*)((const char*)&node->lower_x+ray.farX )), ray.rdir.x, ray.org_rdir.x);
const vfloat16 tFarY = msub(vfloat16(*(vfloat8*)((const char*)&node->lower_x+ray.farY )), ray.rdir.y, ray.org_rdir.y);
const vfloat16 tFarZ = msub(vfloat16(*(vfloat8*)((const char*)&node->lower_x+ray.farZ )), ray.rdir.z, ray.org_rdir.z);
const vfloat16 tNear = max(tNearX,tNearY,tNearZ,tnear);
const vfloat16 tFar = min(tFarX ,tFarY ,tFarZ ,tfar);
const vbool16 vmask = le(vbool16(0xff),tNear,tFar);
#endif
const size_t mask = movemask(vmask);
const size_t mask = movemask(vmask);
dist = tNear;
return mask;
}
@@ -338,7 +325,7 @@ namespace embree
return mask;
}
#if defined(__AVX512F__)
#if defined(__AVX512F__) && !defined(__AVX512VL__) // KNL
template<>
__forceinline size_t intersectNodeRobust<4,16>(const typename BVHN<4>::AlignedNode* node, const TravRay<4,16>& ray,
@@ -849,7 +836,7 @@ namespace embree
#endif
#if defined(__AVX512F__)
#if defined(__AVX512F__) && !defined(__AVX512VL__) // KNL
template<>
__forceinline size_t intersectNode<4,16>(const typename BVH4::QuantizedNode* node, const TravRay<4,16>& ray, const vfloat16& tnear, const vfloat16& tfar, vfloat16& dist)
@@ -884,7 +871,6 @@ namespace embree
template<>
__forceinline size_t intersectNode<8,16>(const typename BVH8::QuantizedNode* node, const TravRay<8,16>& ray, const vfloat16& tnear, const vfloat16& tfar, vfloat16& dist)
{
#if defined(__AVX512ER__)
const vllong8 invalid((size_t)BVH8::emptyNode);
const vboold8 m_valid(invalid != vllong8::loadu(node->children));
const vfloat16 bminmaxX = node->dequantizeLowerUpperX<16>(ray.permX);
@@ -896,31 +882,7 @@ namespace embree
const vfloat16 tNear = max(tNearFarX, tNearFarY, tNearFarZ, tnear);
const vfloat16 tFar = min(tNearFarX, tNearFarY, tNearFarZ, tfar);
const vbool16 vmask = le(vboolf16(m_valid),tNear,align_shift_right<8>(tFar, tFar));
#else
const vfloat16 start_x(node->start.x);
const vfloat16 scale_x(node->scale.x);
const vfloat16 lower_x = madd(vfloat16(node->dequantize<8>(ray.nearX >> 2)),scale_x,start_x);
const vfloat16 upper_x = madd(vfloat16(node->dequantize<8>(ray.farX >> 2)),scale_x,start_x);
const vfloat16 start_y(node->start.y);
const vfloat16 scale_y(node->scale.y);
const vfloat16 lower_y = madd(vfloat16(node->dequantize<8>(ray.nearY >> 2)),scale_y,start_y);
const vfloat16 upper_y = madd(vfloat16(node->dequantize<8>(ray.farY >> 2)),scale_y,start_y);
const vfloat16 start_z(node->start.z);
const vfloat16 scale_z(node->scale.z);
const vfloat16 lower_z = madd(vfloat16(node->dequantize<8>(ray.nearZ >> 2)),scale_z,start_z);
const vfloat16 upper_z = madd(vfloat16(node->dequantize<8>(ray.farZ >> 2)),scale_z,start_z);
const vfloat16 tNearX = msub(lower_x, ray.rdir.x, ray.org_rdir.x);
const vfloat16 tNearY = msub(lower_y, ray.rdir.y, ray.org_rdir.y);
const vfloat16 tNearZ = msub(lower_z, ray.rdir.z, ray.org_rdir.z);
const vfloat16 tFarX = msub(upper_x, ray.rdir.x, ray.org_rdir.x);
const vfloat16 tFarY = msub(upper_y, ray.rdir.y, ray.org_rdir.y);
const vfloat16 tFarZ = msub(upper_z, ray.rdir.z, ray.org_rdir.z);
const vfloat16 tNear = max(tNearX,tNearY,tNearZ,tnear);
const vfloat16 tFar = min(tFarX ,tFarY ,tFarZ ,tfar);
const vbool16 vmask = le(vbool16(0xff),tNear,tFar);
#endif
const size_t mask = movemask(vmask);
const size_t mask = movemask(vmask);
dist = tNear;
return mask;
}
+56 -112
View File
@@ -34,36 +34,24 @@
#include "../common/scene.h"
#include <bitset>
// TODO: bvh->scene->intersect/occluded correct vs. global scene->intersect/occluded
#define MAX_RAYS 64
namespace embree
{
namespace isa
{
/* enable traversal of either two small streams or one large stream */
#if !defined(__AVX512F__)
static const size_t MAX_RAYS_PER_OCTANT = 8*sizeof(unsigned int);
#else
static const size_t MAX_RAYS_PER_OCTANT = 8*sizeof(size_t);
#endif
static_assert(MAX_RAYS_PER_OCTANT <= MAX_INTERNAL_STREAM_SIZE, "maximal internal stream size exceeded");
// =====================================================================================================
// =====================================================================================================
// =====================================================================================================
template<int N, int Nx, int K, int types, bool robust, typename PrimitiveIntersector>
__forceinline void BVHNIntersectorStream<N, Nx, K, types, robust, PrimitiveIntersector>::intersectCoherent(BVH* __restrict__ bvh, RayK<K>** inputRays, size_t numOctantRays, IntersectContext* context)
__forceinline void BVHNIntersectorStream<N, Nx, K, types, robust, PrimitiveIntersector>::intersect(Accel::Intersectors* __restrict__ This,
RayK<K>** inputPackets, size_t numOctantRays, IntersectContext* context)
{
BVH* __restrict__ bvh = (BVH*) This->ptr;
__aligned(64) StackItemMaskCoherent stack[stackSizeSingle]; //!< stack of nodes
assert(numOctantRays <= MAX_INTERNAL_STREAM_SIZE);
RayK<K>** __restrict__ inputPackets = (RayK<K>**)inputRays;
assert(numOctantRays <= MAX_RAYS);
__aligned(64) Packet packet[MAX_RAYS/K];
__aligned(64) Frusta frusta;
__aligned(64) Packet<K,robust> packet[MAX_INTERNAL_STREAM_SIZE/K];
__aligned(64) Frustum<N,Nx,K,robust> frusta;
bool commonOctant = true;
const size_t m_active = initPacketsAndFrusta<false>(inputPackets, numOctantRays, packet, frusta, commonOctant);
@@ -74,7 +62,7 @@ namespace embree
{
const size_t numPackets = (numOctantRays+K-1)/K;
for (size_t i = 0; i < numPackets; i++)
bvh->scene->intersect(inputPackets[i]->tnear <= inputPackets[i]->tfar,*inputPackets[i],context);
This->intersect(inputPackets[i]->tnear <= inputPackets[i]->tfar,*inputPackets[i],context);
return;
}
@@ -86,8 +74,6 @@ namespace embree
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
const NearFarPreCompute pc(frusta.min_rdir);
StackItemMaskCoherent* stackPtr = stack + 1;
while (1) pop:
@@ -111,7 +97,7 @@ namespace embree
__aligned(64) size_t maskK[N];
for (size_t i = 0; i < N; i++) maskK[i] = m_trav_active;
vfloat<Nx> dist;
const size_t m_node_hit = traverseCoherentStream(m_trav_active, packet, node, pc, frusta, maskK, dist);
const size_t m_node_hit = traverseCoherentStream(m_trav_active, packet, node, frusta, maskK, dist);
if (unlikely(m_node_hit == 0)) goto pop;
BVHNNodeTraverserStreamHitCoherent<N, Nx, types>::traverseClosestHit(cur, m_trav_active, vbool<Nx>((int)m_node_hit), dist, (size_t*)maskK, stackPtr);
@@ -130,25 +116,12 @@ namespace embree
break;
}
assert(b < N);
char *ptr = (char*)&node->lower_x + b*sizeof(float);
assert(cur == node->child(b));
const vfloat<K> minX = vfloat<K>(*(const float*)((const char*)ptr + pc.nearX));
const vfloat<K> minY = vfloat<K>(*(const float*)((const char*)ptr + pc.nearY));
const vfloat<K> minZ = vfloat<K>(*(const float*)((const char*)ptr + pc.nearZ));
const vfloat<K> maxX = vfloat<K>(*(const float*)((const char*)ptr + pc.farX));
const vfloat<K> maxY = vfloat<K>(*(const float*)((const char*)ptr + pc.farY));
const vfloat<K> maxZ = vfloat<K>(*(const float*)((const char*)ptr + pc.farZ));
m_trav_active = intersectAlignedNodePacket(packet, minX, minY, minZ, maxX, maxY, maxZ, m_trav_active);
m_trav_active = intersectAlignedNodePacket(packet, node, b, frusta.nf, m_trav_active);
}
/*! check for empty leaf in case we accidentally hit one */
assert(cur != BVH::emptyNode);
if (cur == BVH::emptyNode)
goto pop;
/*! this is a leaf node */
assert(cur != BVH::emptyNode);
STAT3(normal.trav_leaves, 1, 1, 1);
size_t num; Primitive* prim = (Primitive*)cur.leaf(num);
@@ -166,7 +139,7 @@ namespace embree
assert(m_isec & bits);
bits &= ~m_isec;
Packet &p = packet[i];
Packet<K,robust> &p = packet[i];
vbool<K> m_valid = p.min_dist <= p.max_dist;
PrimitiveIntersector::intersectK(m_valid, *inputPackets[i], context, prim, num, lazy_node);
p.max_dist = min(p.max_dist, inputPackets[i]->tfar);
@@ -176,16 +149,16 @@ namespace embree
}
template<int N, int Nx, int K, int types, bool robust, typename PrimitiveIntersector>
__forceinline void BVHNIntersectorStream<N, Nx, K, types, robust, PrimitiveIntersector>::occludedCoherent(BVH* __restrict__ bvh, RayK<K>** inputRays, size_t numOctantRays, IntersectContext* context)
__forceinline void BVHNIntersectorStream<N, Nx, K, types, robust, PrimitiveIntersector>::occluded(Accel::Intersectors* __restrict__ This,
RayK<K>** inputPackets, size_t numOctantRays, IntersectContext* context)
{
BVH* __restrict__ bvh = (BVH*) This->ptr;
__aligned(64) StackItemMaskCoherent stack[stackSizeSingle]; //!< stack of nodes
RayK<K>** __restrict__ inputPackets = (RayK<K>**)inputRays;
assert(numOctantRays <= MAX_RAYS);
assert(numOctantRays <= MAX_INTERNAL_STREAM_SIZE);
/* inactive rays should have been filtered out before */
__aligned(64) Packet packet[MAX_RAYS/K];
__aligned(64) Frusta frusta;
__aligned(64) Packet<K,robust> packet[MAX_INTERNAL_STREAM_SIZE/K];
__aligned(64) Frustum<N,Nx,K,robust> frusta;
bool commonOctant = true;
size_t m_active = initPacketsAndFrusta<true>(inputPackets, numOctantRays, packet, frusta, commonOctant);
@@ -198,7 +171,7 @@ namespace embree
{
const size_t numPackets = (numOctantRays+K-1)/K;
for (size_t i = 0; i < numPackets; i++)
bvh->scene->occluded(inputPackets[i]->tnear <= inputPackets[i]->tfar,*inputPackets[i],context);
This->occluded(inputPackets[i]->tnear <= inputPackets[i]->tfar,*inputPackets[i],context);
return;
}
@@ -210,8 +183,6 @@ namespace embree
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
const NearFarPreCompute pc(frusta.min_rdir);
StackItemMaskCoherent* stackPtr = stack + 1;
while (1) pop:
@@ -237,7 +208,7 @@ namespace embree
for (size_t i = 0; i < N; i++) maskK[i] = m_trav_active;
vfloat<Nx> dist;
const size_t m_node_hit = traverseCoherentStream(m_trav_active, packet, node, pc, frusta, maskK, dist);
const size_t m_node_hit = traverseCoherentStream(m_trav_active, packet, node, frusta, maskK, dist);
if (unlikely(m_node_hit == 0)) goto pop;
BVHNNodeTraverserStreamHitCoherent<N, Nx, types>::traverseAnyHit(cur, m_trav_active, vbool<Nx>((int)m_node_hit), (size_t*)maskK, stackPtr);
@@ -252,25 +223,12 @@ namespace embree
for (size_t i=0;i<N;i++)
if (node->child(i) == cur) { b = i; break; }
assert(b < N);
char *ptr = (char*)&node->lower_x + b*sizeof(float);
assert(cur == node->child(b));
const vfloat<K> minX = vfloat<K>(*(const float*)((const char*)ptr + pc.nearX));
const vfloat<K> minY = vfloat<K>(*(const float*)((const char*)ptr + pc.nearY));
const vfloat<K> minZ = vfloat<K>(*(const float*)((const char*)ptr + pc.nearZ));
const vfloat<K> maxX = vfloat<K>(*(const float*)((const char*)ptr + pc.farX));
const vfloat<K> maxY = vfloat<K>(*(const float*)((const char*)ptr + pc.farY));
const vfloat<K> maxZ = vfloat<K>(*(const float*)((const char*)ptr + pc.farZ));
m_trav_active = intersectAlignedNodePacket(packet, minX, minY, minZ, maxX, maxY, maxZ, m_trav_active);
m_trav_active = intersectAlignedNodePacket(packet, node, b, frusta.nf, m_trav_active);
}
/*! check for empty leaf in case we accidentally hit one */
assert(cur != BVH::emptyNode);
if (cur == BVH::emptyNode)
goto pop;
/*! this is a leaf node */
assert(cur != BVH::emptyNode);
STAT3(normal.trav_leaves, 1, 1, 1);
size_t num; Primitive* prim = (Primitive*)cur.leaf(num);
@@ -286,7 +244,7 @@ namespace embree
const size_t m_isec = ((((size_t)1 << K)-1) << (i*K));
assert(m_isec & bits);
bits &= ~m_isec;
Packet &p = packet[i];
Packet<K,robust> &p = packet[i];
vbool<K> m_valid = p.min_dist <= p.max_dist;
vbool<K> m_hit = PrimitiveIntersector::occludedK(m_valid, *inputPackets[i], context, prim, num, lazy_node);
inputPackets[i]->geomID = select(m_hit & m_valid, vint<K>(zero), inputPackets[i]->geomID);
@@ -296,54 +254,6 @@ namespace embree
} // traversal + intersection
}
// =====================================================================================================
// =====================================================================================================
// =====================================================================================================
template<int N, int Nx, int K, int types, bool robust, typename PrimitiveIntersector>
void BVHNIntersectorStream<N, Nx, K, types, robust, PrimitiveIntersector>::intersect(BVH* __restrict__ bvh, RayK<K>** inputRays, size_t numTotalRays, IntersectContext* context)
{
#if ENABLE_COHERENT_STREAM_PATH == 1
if (unlikely(PrimitiveIntersector::validIntersectorK && !robust && isCoherent(context->user->flags)))
{
intersectCoherent(bvh, inputRays, numTotalRays, context);
return;
}
#endif
/* fallback to packets */
for (size_t i = 0; i < numTotalRays; i += K)
{
const vint<K> vi = vint<K>(int(i)) + vint<K>(step);
vbool<K> valid = vi < vint<K>(int(numTotalRays));
RayK<K>& ray = *(inputRays[i / K]);
valid &= ray.tnear <= ray.tfar;
bvh->scene->intersect(valid, ray, context);
}
}
template<int N, int Nx, int K, int types, bool robust, typename PrimitiveIntersector>
void BVHNIntersectorStream<N, Nx, K, types, robust, PrimitiveIntersector>::occluded(BVH* __restrict__ bvh, RayK<K>** inputRays, size_t numTotalRays, IntersectContext* context)
{
#if ENABLE_COHERENT_STREAM_PATH == 1
if (unlikely(PrimitiveIntersector::validIntersectorK && !robust && isCoherent(context->user->flags)))
{
occludedCoherent(bvh, inputRays, numTotalRays, context);
return;
}
#endif
/* fallback to packets */
for (size_t i = 0; i < numTotalRays; i += K)
{
const vint<K> vi = vint<K>(int(i)) + vint<K>(step);
vbool<K> valid = vi < vint<K>(int(numTotalRays));
RayK<K>& ray = *(inputRays[i / K]);
valid &= ray.tnear <= ray.tfar;
bvh->scene->occluded(valid, ray, context);
}
}
////////////////////////////////////////////////////////////////////////////////
/// ArrayIntersectorKStream Definitions
////////////////////////////////////////////////////////////////////////////////
@@ -359,5 +269,39 @@ namespace embree
typedef ArrayIntersectorKStream<VSIZEX,QuadMvIntersectorKPluecker<4 COMMA VSIZEX COMMA true > > Quad4vIntersectorStreamPluecker;
typedef ArrayIntersectorKStream<VSIZEX,QuadMiIntersectorKPluecker<4 COMMA VSIZEX COMMA true > > Quad4iIntersectorStreamPluecker;
typedef ArrayIntersectorKStream<VSIZEX,ObjectIntersectorK<VSIZEX COMMA false > > ObjectIntersectorStream;
// =====================================================================================================
// =====================================================================================================
// =====================================================================================================
template<int N, int Nx, int K>
void BVHNIntersectorStreamPacketFallback<N, Nx, K>::intersect(Accel::Intersectors* __restrict__ This, RayK<K>** inputRays, size_t numTotalRays, IntersectContext* context)
{
/* fallback to packets */
for (size_t i = 0; i < numTotalRays; i += K)
{
const vint<K> vi = vint<K>(int(i)) + vint<K>(step);
vbool<K> valid = vi < vint<K>(int(numTotalRays));
RayK<K>& ray = *(inputRays[i / K]);
valid &= ray.tnear <= ray.tfar;
This->intersect(valid, ray, context);
}
}
template<int N, int Nx, int K>
void BVHNIntersectorStreamPacketFallback<N, Nx, K>::occluded(Accel::Intersectors* __restrict__ This, RayK<K>** inputRays, size_t numTotalRays, IntersectContext* context)
{
/* fallback to packets */
for (size_t i = 0; i < numTotalRays; i += K)
{
const vint<K> vi = vint<K>(int(i)) + vint<K>(step);
vbool<K> valid = vi < vint<K>(int(numTotalRays));
RayK<K>& ray = *(inputRays[i / K]);
valid &= ray.tnear <= ray.tfar;
This->occluded(valid, ray, context);
}
}
}
}
+44 -157
View File
@@ -20,8 +20,7 @@
#include "../common/ray.h"
#include "../common/stack_item.h"
#include "bvh_traverser1.h"
#define ENABLE_COHERENT_STREAM_PATH 1
#include "frustum.h"
namespace embree
{
@@ -204,53 +203,8 @@ namespace embree
// =============================================================================================
// =============================================================================================
struct Packet
{
Vec3vf<K> rdir;
Vec3vf<K> org_rdir;
vfloat<K> min_dist;
vfloat<K> max_dist;
};
struct Frusta
{
Vec3fa min_rdir;
Vec3fa max_rdir;
Vec3fa min_org_rdir;
Vec3fa max_org_rdir;
float min_dist;
float max_dist;
};
struct NearFarPreCompute
{
#if defined(__AVX512F__)
vint16 permX, permY, permZ;
#endif
size_t nearX, nearY, nearZ;
size_t farX, farY, farZ;
__forceinline NearFarPreCompute(const Vec3fa& dir)
{
#if defined(__AVX512F__)
/* optimization works only for 8-wide BVHs with 16-wide SIMD */
const vint<16> id(step);
const vint<16> id2 = align_shift_right<16/2>(id, id);
permX = select(vfloat<16>(dir.x) >= 0.0f, id, id2);
permY = select(vfloat<16>(dir.y) >= 0.0f, id, id2);
permZ = select(vfloat<16>(dir.z) >= 0.0f, id, id2);
#endif
nearX = (dir.x < 0.0f) ? 1*sizeof(vfloat<N>) : 0*sizeof(vfloat<N>);
nearY = (dir.y < 0.0f) ? 3*sizeof(vfloat<N>) : 2*sizeof(vfloat<N>);
nearZ = (dir.z < 0.0f) ? 5*sizeof(vfloat<N>) : 4*sizeof(vfloat<N>);
farX = nearX ^ sizeof(vfloat<N>);
farY = nearY ^ sizeof(vfloat<N>);
farZ = nearZ ^ sizeof(vfloat<N>);
}
};
template<bool occluded>
__forceinline static size_t initPacketsAndFrusta(RayK<K>** inputPackets, const size_t numOctantRays, Packet* const packet, Frusta& frusta, bool &commonOctant)
__forceinline static size_t initPacketsAndFrusta(RayK<K>** inputPackets, const size_t numOctantRays, Packet<K,robust>* const packet, Frustum<N,Nx,K,robust>& frusta, bool &commonOctant)
{
const size_t numPackets = (numOctantRays+K-1)/K;
@@ -275,26 +229,25 @@ namespace embree
m_active |= (size_t)movemask(m_valid) << (i*K);
packet[i].min_dist = max(tnear, 0.0f);
packet[i].max_dist = select(m_valid, tfar, neg_inf);
tmp_min_dist = min(tmp_min_dist, packet[i].min_dist);
tmp_max_dist = max(tmp_max_dist, packet[i].max_dist);
vfloat<K> packet_min_dist = max(tnear, 0.0f);
vfloat<K> packet_max_dist = select(m_valid, tfar, neg_inf);
tmp_min_dist = min(tmp_min_dist, packet_min_dist);
tmp_max_dist = max(tmp_max_dist, packet_max_dist);
const Vec3vf<K>& org = inputPackets[i]->org;
const Vec3vf<K>& dir = inputPackets[i]->dir;
const Vec3vf<K> rdir = rcp_safe(dir);
const Vec3vf<K> org_rdir = org * rdir;
packet[i].rdir = rdir;
packet[i].org_rdir = org_rdir;
tmp_min_rdir = min(tmp_min_rdir, select(m_valid,rdir, Vec3vf<K>(pos_inf)));
tmp_max_rdir = max(tmp_max_rdir, select(m_valid,rdir, Vec3vf<K>(neg_inf)));
new (&packet[i]) Packet<K,robust>(org,dir,packet_min_dist,packet_max_dist);
tmp_min_rdir = min(tmp_min_rdir, select(m_valid,packet[i].rdir, Vec3vf<K>(pos_inf)));
tmp_max_rdir = max(tmp_max_rdir, select(m_valid,packet[i].rdir, Vec3vf<K>(neg_inf)));
tmp_min_org = min(tmp_min_org , select(m_valid,org , Vec3vf<K>(pos_inf)));
tmp_max_org = max(tmp_max_org , select(m_valid,org , Vec3vf<K>(neg_inf)));
}
m_active &= (numOctantRays == (8 * sizeof(size_t))) ? (size_t)-1 : (((size_t)1 << numOctantRays)-1);
const Vec3fa reduced_min_rdir( reduce_min(tmp_min_rdir.x),
reduce_min(tmp_min_rdir.y),
reduce_min(tmp_min_rdir.z) );
@@ -311,38 +264,26 @@ namespace embree
reduce_max(tmp_max_org.y),
reduce_max(tmp_max_org.z) );
const float frusta_min_dist = reduce_min(tmp_min_dist);
const float frusta_max_dist = reduce_max(tmp_max_dist);
commonOctant =
(reduced_max_rdir.x < 0.0f || reduced_min_rdir.x >= 0.0f) &&
(reduced_max_rdir.y < 0.0f || reduced_min_rdir.y >= 0.0f) &&
(reduced_max_rdir.z < 0.0f || reduced_min_rdir.z >= 0.0f);
const Vec3fa frusta_min_rdir = select(ge_mask(reduced_min_rdir, Vec3fa(zero)), reduced_min_rdir, reduced_max_rdir);
const Vec3fa frusta_max_rdir = select(ge_mask(reduced_min_rdir, Vec3fa(zero)), reduced_max_rdir, reduced_min_rdir);
const Vec3fa frusta_min_org_rdir = frusta_min_rdir * select(ge_mask(reduced_min_rdir, Vec3fa(zero)), reduced_max_origin, reduced_min_origin);
const Vec3fa frusta_max_org_rdir = frusta_max_rdir * select(ge_mask(reduced_min_rdir, Vec3fa(zero)), reduced_min_origin, reduced_max_origin);
frusta.min_rdir = frusta_min_rdir;
frusta.max_rdir = frusta_max_rdir;
frusta.min_org_rdir = frusta_min_org_rdir;
frusta.max_org_rdir = frusta_max_org_rdir;
frusta.min_dist = frusta_min_dist;
frusta.max_dist = frusta_max_dist;
const float frusta_min_dist = reduce_min(tmp_min_dist);
const float frusta_max_dist = reduce_max(tmp_max_dist);
frusta.init(reduced_min_origin,reduced_max_origin,
reduced_min_rdir,reduced_max_rdir,
frusta_min_dist,frusta_max_dist);
return m_active;
}
__forceinline static size_t intersectAlignedNodePacket(const Packet* const packet,
const vfloat<K>& minX,
const vfloat<K>& minY,
const vfloat<K>& minZ,
const vfloat<K>& maxX,
const vfloat<K>& maxY,
const vfloat<K>& maxZ,
__forceinline static size_t intersectAlignedNodePacket(const Packet<K,robust>* const packet,
const AlignedNode* __restrict__ const node,
const size_t bid,
const NearFarPreCompute& nf,
const size_t m_active)
{
assert(m_active);
@@ -351,92 +292,31 @@ namespace embree
size_t m_trav_active = 0;
for (size_t i = startPacketID; i <= endPacketID; i++)
{
//STAT3(normal.trav_nodes,1,1,1);
const Packet& p = packet[i];
const vfloat<K> tminX = msub(minX, p.rdir.x, p.org_rdir.x);
const vfloat<K> tminY = msub(minY, p.rdir.y, p.org_rdir.y);
const vfloat<K> tminZ = msub(minZ, p.rdir.z, p.org_rdir.z);
const vfloat<K> tmaxX = msub(maxX, p.rdir.x, p.org_rdir.x);
const vfloat<K> tmaxY = msub(maxY, p.rdir.y, p.org_rdir.y);
const vfloat<K> tmaxZ = msub(maxZ, p.rdir.z, p.org_rdir.z);
const vfloat<K> tmin = maxi(tminX, tminY, tminZ, p.min_dist);
const vfloat<K> tmax = mini(tmaxX, tmaxY, tmaxZ, p.max_dist);
const vbool<K> vmask = tmin <= tmax;
const size_t m_hit = movemask(vmask);
const size_t m_hit = packet[i].template intersect<N>(node,bid,nf);
m_trav_active |= m_hit << (i*K);
}
return m_trav_active;
}
__forceinline static size_t traverseCoherentStream(const size_t m_trav_active,
Packet* const packet,
Packet<K,robust>* const packet,
const AlignedNode* __restrict__ const node,
const NearFarPreCompute& pc,
const Frusta& frusta,
const Frustum<N,Nx,K,robust>& frusta,
size_t* const maskK,
vfloat<Nx>& dist)
{
/* interval-based culling test */
const vfloat<Nx> bminX = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_x + pc.nearX));
const vfloat<Nx> bminY = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_x + pc.nearY));
const vfloat<Nx> bminZ = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_x + pc.nearZ));
const vfloat<Nx> bmaxX = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_x + pc.farX));
const vfloat<Nx> bmaxY = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_x + pc.farY));
const vfloat<Nx> bmaxZ = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_x + pc.farZ));
const vfloat<Nx> fminX = msub(bminX, vfloat<Nx>(frusta.min_rdir.x), vfloat<Nx>(frusta.min_org_rdir.x));
const vfloat<Nx> fminY = msub(bminY, vfloat<Nx>(frusta.min_rdir.y), vfloat<Nx>(frusta.min_org_rdir.y));
const vfloat<Nx> fminZ = msub(bminZ, vfloat<Nx>(frusta.min_rdir.z), vfloat<Nx>(frusta.min_org_rdir.z));
const vfloat<Nx> fmaxX = msub(bmaxX, vfloat<Nx>(frusta.max_rdir.x), vfloat<Nx>(frusta.max_org_rdir.x));
const vfloat<Nx> fmaxY = msub(bmaxY, vfloat<Nx>(frusta.max_rdir.y), vfloat<Nx>(frusta.max_org_rdir.y));
const vfloat<Nx> fmaxZ = msub(bmaxZ, vfloat<Nx>(frusta.max_rdir.z), vfloat<Nx>(frusta.max_org_rdir.z));
const vfloat<Nx> fmin = maxi(fminX, fminY, fminZ, vfloat<Nx>(frusta.min_dist));
const vfloat<Nx> fmax = mini(fmaxX, fmaxY, fmaxZ, vfloat<Nx>(frusta.max_dist));
const vbool<Nx> vmask_node_hit = fmin <= fmax;
//STAT3(normal.trav_nodes,1,1,1);
size_t m_node_hit = movemask(vmask_node_hit) & (((size_t)1 << N)-1);
// ==================
size_t m_node_hit = frusta.intersect(node,dist);
const size_t first_index = __bsf(m_trav_active);
const size_t first_packetID = first_index / K;
const size_t first_rayID = first_index % K;
size_t m_first_hit = packet[first_packetID].template intersectRay<N,Nx>(node,first_rayID,frusta.nf);
Packet &p = packet[first_packetID];
//STAT3(normal.trav_nodes,1,1,1);
const vfloat<Nx> rminX = msub(bminX, vfloat<Nx>(p.rdir.x[first_rayID]), vfloat<Nx>(p.org_rdir.x[first_rayID]));
const vfloat<Nx> rminY = msub(bminY, vfloat<Nx>(p.rdir.y[first_rayID]), vfloat<Nx>(p.org_rdir.y[first_rayID]));
const vfloat<Nx> rminZ = msub(bminZ, vfloat<Nx>(p.rdir.z[first_rayID]), vfloat<Nx>(p.org_rdir.z[first_rayID]));
const vfloat<Nx> rmaxX = msub(bmaxX, vfloat<Nx>(p.rdir.x[first_rayID]), vfloat<Nx>(p.org_rdir.x[first_rayID]));
const vfloat<Nx> rmaxY = msub(bmaxY, vfloat<Nx>(p.rdir.y[first_rayID]), vfloat<Nx>(p.org_rdir.y[first_rayID]));
const vfloat<Nx> rmaxZ = msub(bmaxZ, vfloat<Nx>(p.rdir.z[first_rayID]), vfloat<Nx>(p.org_rdir.z[first_rayID]));
const vfloat<Nx> rmin = maxi(rminX, rminY, rminZ, vfloat<Nx>(p.min_dist[first_rayID]));
const vfloat<Nx> rmax = mini(rmaxX, rmaxY, rmaxZ, vfloat<Nx>(p.max_dist[first_rayID]));
const vbool<Nx> vmask_first_hit = rmin <= rmax;
size_t m_first_hit = movemask(vmask_first_hit) & (((size_t)1 << N)-1);
// ==================
/* this causes a traversal order dependence with respect to the order of rays within the stream */
//dist = select(vmask_first_hit, rmin, fmin);
/* this is independent of the ordering of rays */
dist = fmin;
/* this make traversal independent of the ordering of rays */
size_t m_node = m_node_hit ^ m_first_hit;
while(unlikely(m_node))
{
const size_t b = __bscf(m_node);
const vfloat<K> minX = vfloat<K>(bminX[b]);
const vfloat<K> minY = vfloat<K>(bminY[b]);
const vfloat<K> minZ = vfloat<K>(bminZ[b]);
const vfloat<K> maxX = vfloat<K>(bmaxX[b]);
const vfloat<K> maxY = vfloat<K>(bmaxY[b]);
const vfloat<K> maxZ = vfloat<K>(bmaxZ[b]);
const size_t m_current = m_trav_active & intersectAlignedNodePacket(packet, minX, minY, minZ, maxX, maxY, maxZ, m_trav_active);
const size_t m_current = m_trav_active & intersectAlignedNodePacket(packet, node, b, frusta.nf, m_trav_active);
m_node_hit ^= m_current ? (size_t)0 : ((size_t)1 << b);
maskK[b] = m_current;
}
@@ -449,13 +329,20 @@ namespace embree
// =============================================================================================
// =============================================================================================
static void intersectCoherent(BVH* bvh, RayK<K>** inputRays, size_t numValidStreams, IntersectContext* context);
static void occludedCoherent(BVH* bvh, RayK<K>** inputRays, size_t numValidStreams, IntersectContext* context);
public:
static void intersect(BVH* bvh, RayK<K>** inputRays, size_t numRays, IntersectContext* context);
static void occluded (BVH* bvh, RayK<K>** inputRays, size_t numRays, IntersectContext* context);
static void intersect(Accel::Intersectors* This, RayK<K>** inputRays, size_t numRays, IntersectContext* context);
static void occluded (Accel::Intersectors* This, RayK<K>** inputRays, size_t numRays, IntersectContext* context);
};
/*! BVH ray stream intersector with direct fallback to packets. */
template<int N, int Nx, int K>
class BVHNIntersectorStreamPacketFallback
{
public:
static void intersect(Accel::Intersectors* This, RayK<K>** inputRays, size_t numRays, IntersectContext* context);
static void occluded (Accel::Intersectors* This, RayK<K>** inputRays, size_t numRays, IntersectContext* context);
};
}
}
@@ -20,6 +20,13 @@ namespace embree
{
namespace isa
{
////////////////////////////////////////////////////////////////////////////////
/// General BVHIntersectorStreamPacketFallback Intersector
////////////////////////////////////////////////////////////////////////////////
DEFINE_INTERSECTORN(BVH4IntersectorStreamPacketFallback,BVHNIntersectorStreamPacketFallback<SIMD_MODE(4) COMMA VSIZEX>);
////////////////////////////////////////////////////////////////////////////////
/// BVH4IntersectorStream Definitions
////////////////////////////////////////////////////////////////////////////////
@@ -20,6 +20,12 @@ namespace embree
{
namespace isa
{
////////////////////////////////////////////////////////////////////////////////
/// General BVHIntersectorStreamPacketFallback Intersector
////////////////////////////////////////////////////////////////////////////////
DEFINE_INTERSECTORN(BVH8IntersectorStreamPacketFallback,BVHNIntersectorStreamPacketFallback<SIMD_MODE(8) COMMA VSIZEX>);
////////////////////////////////////////////////////////////////////////////////
/// BVH8IntersectorStream Definitions
////////////////////////////////////////////////////////////////////////////////
+153 -217
View File
@@ -21,193 +21,142 @@ namespace embree
{
namespace isa
{
static const size_t MAX_RAYS_PER_OCTANT = 8*sizeof(size_t);
static_assert(MAX_RAYS_PER_OCTANT <= MAX_INTERNAL_STREAM_SIZE, "maximal internal stream size exceeded");
MAYBE_UNUSED static const size_t MAX_PACKET_STREAM_SIZE = MAX_INTERNAL_STREAM_SIZE / VSIZEX;
__forceinline void RayStreamFilter::filterAOS(Scene* scene, RTCRay* _rayN, size_t N, size_t stride, IntersectContext* context, bool intersect)
{
#if 1
RayStreamAOS rayN(_rayN);
for (size_t i = 0; i < N; i += VSIZEX)
/* use fast path for coherent ray mode */
if (unlikely(isCoherent(context->user->flags)))
{
const vintx vi = vintx(int(i)) + vintx(step);
vboolx valid = vi < vintx(int(N));
const vintx offset = vi * int(stride);
__aligned(64) RayK<VSIZEX> rays[MAX_PACKET_STREAM_SIZE];
__aligned(64) RayK<VSIZEX>* rayPtrs[MAX_PACKET_STREAM_SIZE];
RayK<VSIZEX> ray = rayN.getRayByOffset<VSIZEX>(valid, offset);
valid &= ray.tnear <= ray.tfar;
if (intersect)
scene->intersect(valid, ray, context);
else
scene->occluded(valid, ray, context);
rayN.setHitByOffset<VSIZEX>(valid, offset, ray, intersect);
}
#else
Ray* __restrict__ rayN = (Ray*)_rayN;
__aligned(64) Ray* octants[8][MAX_RAYS_PER_OCTANT];
unsigned int rays_in_octant[8];
for (size_t i=0;i<8;i++) rays_in_octant[i] = 0;
size_t inputRayID = 0;
while(1)
{
int cur_octant = -1;
/* sort rays into octants */
for (;inputRayID<N;)
for (size_t i = 0; i < N; i += MAX_INTERNAL_STREAM_SIZE)
{
Ray &ray = *(Ray*)((char*)rayN + inputRayID * stride);
/* filter out invalid rays */
if (unlikely(ray.tnear > ray.tfar)) { inputRayID++; continue; }
if (unlikely(!intersect && ray.geomID == 0)) { inputRayID++; continue; } // ignore already occluded rays
const size_t size = min(N - i, MAX_INTERNAL_STREAM_SIZE);
#if defined(EMBREE_IGNORE_INVALID_RAYS)
if (unlikely(!ray.valid())) { inputRayID++; continue; }
#endif
const unsigned int octantID = movemask(vfloat4(ray.dir) < 0.0f) & 0x7;
assert(octantID < 8);
octants[octantID][rays_in_octant[octantID]++] = &ray;
inputRayID++;
if (unlikely(rays_in_octant[octantID] == MAX_RAYS_PER_OCTANT))
/* convert from AOS to SOA */
for (size_t j = 0; j < size; j += VSIZEX)
{
cur_octant = octantID;
break;
const vintx vij = vintx(int(i+j)) + vintx(step);
const vboolx valid = vij < vintx(int(N));
const vintx offset = vij * int(stride);
const size_t packetIndex = j / VSIZEX;
RayK<VSIZEX> ray = rayN.getRayByOffset(valid, offset);
ray.tnear = select(valid, ray.tnear, zero);
ray.tfar = select(valid, ray.tfar, neg_inf);
rays[packetIndex] = ray;
rayPtrs[packetIndex] = &rays[packetIndex]; // rayPtrs might get reordered for occludedN
}
/* trace stream */
if (intersect)
scene->intersectors.intersectN(rayPtrs, size, context);
else
scene->intersectors.occludedN(rayPtrs, size, context);
/* convert from SOA to AOS */
for (size_t j = 0; j < size; j += VSIZEX)
{
const vintx vij = vintx(int(i+j)) + vintx(step);
const vboolx valid = vij < vintx(int(N));
const vintx offset = vij * int(stride);
const size_t packetIndex = j / VSIZEX;
rayN.setHitByOffset(valid, offset, rays[packetIndex], intersect);
}
}
/* need to flush rays in octant ? */
if (unlikely(cur_octant == -1))
for (int i=0;i<8;i++)
if (rays_in_octant[i])
{
cur_octant = i;
break;
}
/* all rays traced ? */
if (unlikely(cur_octant == -1))
break;
Ray** rays = &octants[cur_octant][0];
const size_t numOctantRays = rays_in_octant[cur_octant];
/* special codepath for very small number of rays per octant */
if (numOctantRays == 1)
{
if (intersect) scene->intersect((RTCRay&)*rays[0],context);
else scene->occluded ((RTCRay&)*rays[0],context);
}
/* codepath for large number of rays per octant */
else
{
/* incoherent ray stream code path */
if (intersect) scene->intersectN((RTCRay**)rays,numOctantRays,context);
else scene->occludedN ((RTCRay**)rays,numOctantRays,context);
}
rays_in_octant[cur_octant] = 0;
}
else
{
/* fallback to packets */
for (size_t i=0; i<N; i+=VSIZEX)
{
const vintx vi = vintx(int(i)) + vintx(step);
vboolx valid = vi < vintx(int(N));
const vintx offset = vi * int(stride);
#endif
RayK<VSIZEX> ray = rayN.getRayByOffset(valid, offset);
valid &= ray.tnear <= ray.tfar;
if (intersect)
scene->intersectors.intersect(valid, ray, context);
else
scene->intersectors.occluded(valid, ray, context);
rayN.setHitByOffset(valid, offset, ray, intersect);
}
}
}
__forceinline void RayStreamFilter::filterAOP(Scene* scene, RTCRay** _rayN, size_t N, IntersectContext* context, bool intersect)
{
#if 1
/* fallback to packets */
RayStreamAOP rayN(_rayN);
for (size_t i = 0; i < N; i += VSIZEX)
/* use fast path for coherent ray mode */
if (unlikely(isCoherent(context->user->flags)))
{
const vintx vi = vintx(int(i)) + vintx(step);
vboolx valid = vi < vintx(int(N));
__aligned(64) RayK<VSIZEX> rays[MAX_PACKET_STREAM_SIZE];
__aligned(64) RayK<VSIZEX>* rayPtrs[MAX_PACKET_STREAM_SIZE];
RayK<VSIZEX> ray = rayN.getRayByIndex<VSIZEX>(valid, i);
valid &= ray.tnear <= ray.tfar;
if (intersect)
scene->intersect(valid, ray, context);
else
scene->occluded(valid, ray, context);
rayN.setHitByIndex<VSIZEX>(valid, i, ray, intersect);
}
#else
Ray** __restrict__ rayN = (Ray**)_rayN;
__aligned(64) Ray* octants[8][MAX_RAYS_PER_OCTANT];
unsigned int rays_in_octant[8];
for (size_t i=0;i<8;i++) rays_in_octant[i] = 0;
size_t inputRayID = 0;
while(1)
{
int cur_octant = -1;
/* sort rays into octants */
for (;inputRayID<N;)
for (size_t i = 0; i < N; i += MAX_INTERNAL_STREAM_SIZE)
{
Ray &ray = *rayN[inputRayID];
/* filter out invalid rays */
if (unlikely(ray.tnear > ray.tfar)) { inputRayID++; continue; }
if (unlikely(!intersect && ray.geomID == 0)) { inputRayID++; continue; } // ignore already occluded rays
const size_t size = min(N - i, MAX_INTERNAL_STREAM_SIZE);
#if defined(EMBREE_IGNORE_INVALID_RAYS)
if (unlikely(!ray.valid())) { inputRayID++; continue; }
#endif
const unsigned int octantID = movemask(vfloat4(ray.dir) < 0.0f) & 0x7;
assert(octantID < 8);
octants[octantID][rays_in_octant[octantID]++] = &ray;
inputRayID++;
if (unlikely(rays_in_octant[octantID] == MAX_RAYS_PER_OCTANT))
/* convert from AOP to SOA */
for (size_t j = 0; j < size; j += VSIZEX)
{
cur_octant = octantID;
break;
const vintx vij = vintx(int(i+j)) + vintx(step);
const vboolx valid = vij < vintx(int(N));
const size_t packetIndex = j / VSIZEX;
RayK<VSIZEX> ray = rayN.getRayByIndex(valid, i+j);
ray.tnear = select(valid, ray.tnear, zero);
ray.tfar = select(valid, ray.tfar, neg_inf);
rays[packetIndex] = ray;
rayPtrs[packetIndex] = &rays[packetIndex]; // rayPtrs might get reordered for occludedN
}
/* trace stream */
if (intersect)
scene->intersectors.intersectN(rayPtrs, size, context);
else
scene->intersectors.occludedN(rayPtrs, size, context);
/* convert from SOA to AOP */
for (size_t j = 0; j < size; j += VSIZEX)
{
const vintx vij = vintx(int(i+j)) + vintx(step);
const vboolx valid = vij < vintx(int(N));
const size_t packetIndex = j / VSIZEX;
rayN.setHitByIndex(valid, i+j, rays[packetIndex], intersect);
}
}
/* need to flush rays in octant ? */
if (unlikely(cur_octant == -1))
for (int i=0;i<8;i++)
if (rays_in_octant[i])
{
cur_octant = i;
break;
}
/* all rays traced ? */
if (unlikely(cur_octant == -1))
break;
Ray** rays = &octants[cur_octant][0];
const size_t numOctantRays = rays_in_octant[cur_octant];
/* special codepath for very small number of rays per octant */
if (numOctantRays == 1)
{
if (intersect) scene->intersect((RTCRay&)*rays[0],context);
else scene->occluded ((RTCRay&)*rays[0],context);
}
/* codepath for large number of rays per octant */
else
{
/* incoherent ray stream code path */
if (intersect) scene->intersectN((RTCRay**)rays,numOctantRays,context);
else scene->occludedN ((RTCRay**)rays,numOctantRays,context);
}
rays_in_octant[cur_octant] = 0;
}
else
{
/* fallback to packets */
for (size_t i = 0; i < N; i += VSIZEX)
{
const vintx vi = vintx(int(i)) + vintx(step);
vboolx valid = vi < vintx(int(N));
#endif
RayK<VSIZEX> ray = rayN.getRayByIndex(valid, i);
valid &= ray.tnear <= ray.tfar;
if (intersect)
scene->intersectors.intersect(valid, ray, context);
else
scene->intersectors.occluded(valid, ray, context);
rayN.setHitByIndex(valid, i, ray, intersect);
}
}
}
__forceinline void RayStreamFilter::filterSOA(Scene* scene, char* rayData, size_t N, size_t numPackets, size_t stride, IntersectContext* context, bool intersect)
@@ -220,45 +169,40 @@ namespace embree
!rayDataAlignment &&
!offsetAlignment))
{
#if defined(__AVX__) && ENABLE_COHERENT_STREAM_PATH == 1
/* all valid accels need to have a intersectN/occludedN */
if (unlikely(isCoherent(context->user->flags) && !scene->isRobust() && scene->accels.validIsecN()))
if (unlikely(isCoherent(context->user->flags)))
{
static const size_t MAX_COHERENT_RAY_PACKETS = MAX_RAYS_PER_OCTANT / VSIZEX;
__aligned(64) RayK<VSIZEX>* rays_ptr[MAX_RAYS_PER_OCTANT / VSIZEX];
size_t numPacketsInOctant = 0;
__aligned(64) RayK<VSIZEX>* rayPtrs[MAX_INTERNAL_STREAM_SIZE / VSIZEX];
size_t packetIndex = 0;
for (size_t i = 0; i < numPackets; i++)
{
const size_t offset = i * stride;
RayK<VSIZEX>& ray = *(RayK<VSIZEX>*)(rayData + offset);
rays_ptr[numPacketsInOctant++] = &ray;
rayPtrs[packetIndex++] = &ray;
/* trace as stream */
if (unlikely(numPacketsInOctant == MAX_COHERENT_RAY_PACKETS))
if (unlikely(packetIndex == MAX_PACKET_STREAM_SIZE))
{
const size_t size = numPacketsInOctant*VSIZEX;
const size_t size = packetIndex*VSIZEX;
if (intersect)
scene->intersectN((void**)rays_ptr, size, context);
scene->intersectors.intersectN(rayPtrs, size, context);
else
scene->occludedN((void**)rays_ptr, size, context);
numPacketsInOctant = 0;
scene->intersectors.occludedN(rayPtrs, size, context);
packetIndex = 0;
}
}
/* flush remaining packets */
if (unlikely(numPacketsInOctant))
if (unlikely(packetIndex > 0))
{
const size_t size = numPacketsInOctant*VSIZEX;
const size_t size = packetIndex*VSIZEX;
if (intersect)
scene->intersectN((void**)rays_ptr, size, context);
scene->intersectors.intersectN(rayPtrs, size, context);
else
scene->occludedN((void**)rays_ptr, size, context);
scene->intersectors.occludedN(rayPtrs, size, context);
}
}
else
#endif
{
/* fallback to packets */
for (size_t i = 0; i < numPackets; i++)
@@ -268,37 +212,34 @@ namespace embree
const vboolx valid = ray.tnear <= ray.tfar;
if (intersect)
scene->intersect(valid, ray, context);
scene->intersectors.intersect(valid, ray, context);
else
scene->occluded(valid, ray, context);
scene->intersectors.occluded(valid, ray, context);
}
}
}
else
{
/* this is a very slow fallback path but it's extremely unlikely to be hit */
/* fallback to packets for arbitrary packet size and alignment */
for (size_t i = 0; i < numPackets; i++)
{
const size_t offset = i * stride;
RayPacketSOA rayN(rayData + offset, N);
RayK<VSIZEX> ray;
{
const size_t offsetN = i * stride;
RayPacketSOA rayN(rayData + offsetN, N);
for (size_t j = 0; j < N; j++)
for (size_t j = 0; j < N; j += VSIZEX)
{
/* invalidate all lanes */
ray.tnear = 0.0f;
ray.tfar = neg_inf;
const size_t offset = j * sizeof(float);
vboolx valid = (vintx(int(j)) + vintx(step)) < vintx(int(N));
/* extract single ray and copy data to first packet lane */
rayN.getRayByIndex(j, ray, 0);
const vboolx valid = ray.tnear <= ray.tfar;
RayK<VSIZEX> ray = rayN.getRayByOffset(valid, offset);
valid &= ray.tnear <= ray.tfar;
if (intersect)
scene->intersect(valid, ray, context);
scene->intersectors.intersect(valid, ray, context);
else
scene->occluded(valid, ray, context);
scene->intersectors.occluded(valid, ray, context);
rayN.setHitByIndex(j, ray, 0, intersect);
rayN.setHitByOffset(valid, offset, ray, intersect);
}
}
}
@@ -309,70 +250,65 @@ namespace embree
RayStreamSOP& rayN = *(RayStreamSOP*)&_rayN;
/* use fast path for coherent ray mode */
#if defined(__AVX__) && ENABLE_COHERENT_STREAM_PATH == 1
/* all valid accels need to have a intersectN/occludedN */
if (unlikely(isCoherent(context->user->flags) && !scene->isRobust() && scene->accels.validIsecN()))
if (unlikely(isCoherent(context->user->flags)))
{
static const size_t MAX_COHERENT_RAY_PACKETS = MAX_RAYS_PER_OCTANT / VSIZEX;
__aligned(64) RayK<VSIZEX> rays[MAX_PACKET_STREAM_SIZE];
__aligned(64) RayK<VSIZEX>* rayPtrs[MAX_PACKET_STREAM_SIZE];
__aligned(64) RayK<VSIZEX> rays[MAX_COHERENT_RAY_PACKETS];
__aligned(64) RayK<VSIZEX>* rays_ptr[MAX_COHERENT_RAY_PACKETS];
for (size_t i = 0; i < N; i += MAX_RAYS_PER_OCTANT)
for (size_t i = 0; i < N; i += MAX_INTERNAL_STREAM_SIZE)
{
const size_t size = min(N - i, MAX_RAYS_PER_OCTANT);
const size_t size = min(N - i, MAX_INTERNAL_STREAM_SIZE);
/* convert from SOP to SOA */
for (size_t j = 0; j < size; j += VSIZEX)
{
const vintx vij = vintx(int(i+j)) + vintx(step);
const vboolx valid = vij < vintx(int(N));
const size_t offset = sizeof(float) * (i+j);
const size_t packet_index = j / VSIZEX;
const size_t offset = (i+j) * sizeof(float);
const size_t packetIndex = j / VSIZEX;
RayK<VSIZEX> ray = rayN.getRayByOffset(valid, offset);
ray.tnear = select(valid, ray.tnear, zero);
ray.tfar = select(valid, ray.tfar, neg_inf);
rays[packet_index] = ray;
rays_ptr[packet_index] = &rays[packet_index]; // rays_ptr might get reordered for occludedN
rays[packetIndex] = ray;
rayPtrs[packetIndex] = &rays[packetIndex]; // rayPtrs might get reordered for occludedN
}
/* trace stream */
if (intersect)
scene->intersectN((void**)rays_ptr, size, context);
scene->intersectors.intersectN(rayPtrs, size, context);
else
scene->occludedN((void**)rays_ptr, size, context);
scene->intersectors.occludedN(rayPtrs, size, context);
/* convert from SOA to SOP */
for (size_t j = 0; j < size; j += VSIZEX)
{
const vintx vij = vintx(int(i+j)) + vintx(step);
const vboolx valid = vij < vintx(int(N));
const size_t offset = sizeof(float) * (i+j);
const size_t packet_index = j / VSIZEX;
const size_t offset = (i+j) * sizeof(float);
const size_t packetIndex = j / VSIZEX;
rayN.setHitByOffset(valid, offset, rays[packet_index], intersect);
rayN.setHitByOffset(valid, offset, rays[packetIndex], intersect);
}
}
}
else
#endif
{
/* fallback to packets */
for (size_t i = 0; i < N; i += VSIZEX)
{
const vintx vi = vintx(int(i)) + vintx(step);
vboolx valid = vi < vintx(int(N));
const size_t offset = sizeof(float) * i;
const size_t offset = i * sizeof(float);
RayK<VSIZEX> ray = rayN.getRayByOffset(valid, offset);
valid &= ray.tnear <= ray.tfar;
if (intersect)
scene->intersect(valid, ray, context);
scene->intersectors.intersect(valid, ray, context);
else
scene->occluded(valid, ray, context);
scene->intersectors.occluded(valid, ray, context);
rayN.setHitByOffset(valid, offset, ray, intersect);
}
+3 -5
View File
@@ -89,14 +89,12 @@ namespace embree
virtual const BBox3fa leafBounds (NodeRef& ref) const
{
size_t ty; Primitive* prim = (Primitive*) ref.leaf(ty);
size_t num; char* prim = ref.leaf(num);
if (unlikely(ref == BVH::emptyNode)) return empty;
BBox3fa bounds = empty;
for (size_t i=0;; i++) {
bounds.extend(prim[i].update(mesh));
if (prim[i].last()) break;
}
for (size_t i=0; i<num; i++)
bounds.extend(((Primitive*)prim)[i].update(mesh));
return bounds;
}
+1 -1
View File
@@ -106,7 +106,7 @@ namespace embree
int pos[4] = { pos0,pos1,pos2,pos3 };
const size_t mbd = BVH4::maxBuildDepth;
vbool4 valid = vint4(int(depth+1))+cdepth <= vint4(mbd); // only select swaps that fulfill depth constraints
valid &= vint4(c2) != vint4(step);
valid &= vint4(int(c2)) != vint4(step);
if (none(valid)) continue;
size_t c1 = select_min(valid,area0123);
float area = area0123[c1];
+4 -8
View File
@@ -154,15 +154,11 @@ namespace embree
}
else if (node.isLeaf())
{
size_t ty; const char* tri = node.leaf(ty);
if (node != BVH::emptyNode)
size_t num; const char* tri = node.leaf(num);
if (num)
{
size_t num = 0;
while (true) {
const char* cur = tri+num*bvh->primTy->bytes;
s.statLeaf.numPrims += bvh->primTy->size(cur);
num++;
if (bvh->primTy->last(cur)) break;
for (size_t i=0; i<num; i++) {
s.statLeaf.numPrims += bvh->primTy->size(tri+i*bvh->primTy->bytes);
}
s.statLeaf.numLeaves++;
s.statLeaf.numPrimBlocks += num;
+198 -4
View File
@@ -30,6 +30,8 @@ namespace embree
/*! Helper functions for fast sorting using AVX512 instructions. */
#if defined(__AVX512F__)
/* KNL code path */
__forceinline static void isort_update(vfloat16 &dist, vllong8 &ptr, const vfloat16 &d, const vllong8 &p)
{
const vfloat16 dist_shift = align_shift_right<15>(dist,dist);
@@ -230,19 +232,196 @@ namespace embree
vuint16::storeu(stackPtr + 4,stackElementB1);
/* increase stack pointer */
stackPtr += hits-1;
}
/* SKX code path */
#if defined(__AVX512VL__)
template<int N>
__forceinline static void isort_update(vfloat<N> &dist, vint<N> &ptr, const vfloat<N> &d, const vint<N> &p)
{
const vfloat<N> dist_shift = align_shift_right<N-1>(dist,dist);
const vint<N> ptr_shift = align_shift_right<N-1>(ptr,ptr);
const vboolf<N> m_geq = d >= dist;
const vboolf<N> m_geq_shift = m_geq << 1;
dist = select(m_geq,d,dist);
ptr = select(m_geq,p,ptr);
dist = select(m_geq_shift,dist_shift,dist);
ptr = select(m_geq_shift,ptr_shift,ptr);
}
template<int N>
__forceinline static void isort_quick_update(vfloat<N> &dist, vint<N> &ptr, const vfloat<N> &d, const vint<N> &p)
{
dist = align_shift_right<N-1>(dist,permute(d,vint<N>(zero)));
ptr = align_shift_right<N-1>(ptr,permute(p,vint<N>(zero)));
}
template<int N, int Nx, int types, class NodeRef, class BaseNode>
static __forceinline void traverseClosestHitAVX512VL(NodeRef& cur,
size_t mask,
const vfloat<Nx>& tNear,
StackItemT<NodeRef>*& stackPtr,
StackItemT<NodeRef>* stackEnd)
{
assert(mask != 0);
const BaseNode* node = cur.baseNode(types);
vint<N> children( step );
children = vint<N>::compact((int)mask,children);
vfloat<N> distance = tNear;
distance = vfloat<N>::compact((int)mask,distance,tNear);
cur = node->child((unsigned int)toScalar(children));
cur.prefetch(types);
mask &= mask-1;
if (likely(mask == 0)) return;
/* 2 hits: order A0 B0 */
const vint<N> c0(children);
const vfloat<N> d0(distance);
children = align_shift_right<1>(children,children);
distance = align_shift_right<1>(distance,distance);
const vint<N> c1(children);
const vfloat<N> d1(distance);
cur = node->child((unsigned int)toScalar(children));
cur.prefetch(types);
/* a '<' keeps the order for equal distances, scenes like powerplant largely benefit from it */
const vboolf<N> m_dist = d0 < d1;
const vfloat<N> dist_A0 = select(m_dist, d0, d1);
const vfloat<N> dist_B0 = select(m_dist, d1, d0);
const vint<N> ptr_A0 = select(vboolf<N>(m_dist), c0, c1);
const vint<N> ptr_B0 = select(vboolf<N>(m_dist), c1, c0);
mask &= mask-1;
if (likely(mask == 0)) {
cur = node->child((unsigned int)toScalar(ptr_A0));
stackPtr[0].ptr = node->child((unsigned int)toScalar(ptr_B0));
*(float*)&stackPtr[0].dist = toScalar(dist_B0);
stackPtr++;
return;
}
/* 3 hits: order A1 B1 C1 */
children = align_shift_right<1>(children,children);
distance = align_shift_right<1>(distance,distance);
const vint<N> c2(children);
const vfloat<N> d2(distance);
cur = node->child((unsigned int)toScalar(children));
cur.prefetch(types);
const vboolf<N> m_dist1 = dist_A0 <= d2;
const vfloat<N> dist_tmp_B1 = select(m_dist1, d2, dist_A0);
const vint<N> ptr_A1 = select(vboolf<N>(m_dist1), ptr_A0, c2);
const vint<N> ptr_tmp_B1 = select(vboolf<N>(m_dist1), c2, ptr_A0);
const vboolf<N> m_dist2 = dist_B0 <= dist_tmp_B1;
const vfloat<N> dist_B1 = select(m_dist2, dist_B0 , dist_tmp_B1);
const vfloat<N> dist_C1 = select(m_dist2, dist_tmp_B1, dist_B0);
const vint<N> ptr_B1 = select(vboolf<N>(m_dist2), ptr_B0, ptr_tmp_B1);
const vint<N> ptr_C1 = select(vboolf<N>(m_dist2), ptr_tmp_B1, ptr_B0);
mask &= mask-1;
if (likely(mask == 0)) {
cur = node->child((unsigned int)toScalar(ptr_A1));
stackPtr[0].ptr = node->child((unsigned int)toScalar(ptr_C1));
*(float*)&stackPtr[0].dist = toScalar(dist_C1);
stackPtr[1].ptr = node->child((unsigned int)toScalar(ptr_B1));
*(float*)&stackPtr[1].dist = toScalar(dist_B1);
stackPtr+=2;
return;
}
/* 4 hits: order A2 B2 C2 D2 */
const vfloat<N> dist_A1 = select(m_dist1, dist_A0, d2);
children = align_shift_right<1>(children,children);
distance = align_shift_right<1>(distance,distance);
const vint<N> c3(children);
const vfloat<N> d3(distance);
cur = node->child((unsigned int)toScalar(children));
cur.prefetch(types);
const vboolf<N> m_dist3 = dist_A1 <= d3;
const vfloat<N> dist_tmp_B2 = select(m_dist3, d3, dist_A1);
const vint<N> ptr_A2 = select(vboolf<N>(m_dist3), ptr_A1, c3);
const vint<N> ptr_tmp_B2 = select(vboolf<N>(m_dist3), c3, ptr_A1);
const vboolf<N> m_dist4 = dist_B1 <= dist_tmp_B2;
const vfloat<N> dist_B2 = select(m_dist4, dist_B1 , dist_tmp_B2);
const vfloat<N> dist_tmp_C2 = select(m_dist4, dist_tmp_B2, dist_B1);
const vint<N> ptr_B2 = select(vboolf<N>(m_dist4), ptr_B1, ptr_tmp_B2);
const vint<N> ptr_tmp_C2 = select(vboolf<N>(m_dist4), ptr_tmp_B2, ptr_B1);
const vboolf<N> m_dist5 = dist_C1 <= dist_tmp_C2;
const vfloat<N> dist_C2 = select(m_dist5, dist_C1 , dist_tmp_C2);
const vfloat<N> dist_D2 = select(m_dist5, dist_tmp_C2, dist_C1);
const vint<N> ptr_C2 = select(vboolf<N>(m_dist5), ptr_C1, ptr_tmp_C2);
const vint<N> ptr_D2 = select(vboolf<N>(m_dist5), ptr_tmp_C2, ptr_C1);
mask &= mask-1;
if (likely(mask == 0)) {
cur = node->child((unsigned int)toScalar(ptr_A2));
stackPtr[0].ptr = node->child((unsigned int)toScalar(ptr_D2));
*(float*)&stackPtr[0].dist = toScalar(dist_D2);
stackPtr[1].ptr = node->child((unsigned int)toScalar(ptr_C2));
*(float*)&stackPtr[1].dist = toScalar(dist_C2);
stackPtr[2].ptr = node->child((unsigned int)toScalar(ptr_B2));
*(float*)&stackPtr[2].dist = toScalar(dist_B2);
stackPtr+=3;
return;
}
/* >=5 hits: reverse to descending order for writing to stack */
const size_t hits = 4 + __popcnt(mask);
const vfloat<N> dist_A2 = select(m_dist3, dist_A1, d3);
vfloat<N> dist(neg_inf);
vint<N> ptr(zero);
isort_quick_update(dist,ptr,dist_A2,ptr_A2);
isort_quick_update(dist,ptr,dist_B2,ptr_B2);
isort_quick_update(dist,ptr,dist_C2,ptr_C2);
isort_quick_update(dist,ptr,dist_D2,ptr_D2);
do {
children = align_shift_right<1>(children,children);
distance = align_shift_right<1>(distance,distance);
cur = node->child((unsigned int)toScalar(children));
cur.prefetch(types);
const vfloat<N> new_dist(permute(distance,vint<N>(zero)));
const vint<N> new_ptr(permute(children,vint<N>(zero)));
mask &= mask-1;
isort_update(dist,ptr,new_dist,new_ptr);
} while(mask);
#if 0
for (size_t i=0;i<hits-1;i++)
{
stackPtr->ptr = toScalar(ptr);
stackPtr->ptr = node->child((unsigned int)toScalar(ptr));
*(float*)&stackPtr->dist = toScalar(dist);
dist = align_shift_right<1>(dist,dist);
ptr = align_shift_right<1>(ptr,ptr);
stackPtr++;
}
cur = toScalar(ptr);
#endif
cur = node->child((unsigned int)toScalar(ptr));
}
#endif
#endif
@@ -263,8 +442,16 @@ namespace embree
StackItemT<NodeRef>* stackEnd)
{
assert(mask != 0);
#if defined(__AVX512F__) && 1
#if defined(__AVX512ER__)
traverseClosestHitAVX512<4,Nx,types,NodeRef,BaseNode>(cur,mask,tNear,stackPtr,stackEnd);
#elif defined(__AVX512VL__)
traverseClosestHitAVX512VL<4,Nx,types,NodeRef,BaseNode>(cur,mask,tNear,stackPtr,stackEnd);
#else
static_assert(false);
#endif
#else
const BaseNode* node = cur.baseNode(types);
@@ -368,9 +555,16 @@ namespace embree
StackItemT<NodeRef>* stackEnd)
{
assert(mask != 0);
#if defined(__AVX512F__) && 1
#if defined(__AVX512ER__)
traverseClosestHitAVX512<8,Nx,types,NodeRef,BaseNode>(cur,mask,tNear,stackPtr,stackEnd);
#elif defined(__AVX512VL__)
traverseClosestHitAVX512VL<8,Nx,types,NodeRef,BaseNode>(cur,mask,tNear,stackPtr,stackEnd);
#else
static_assert(false);
#endif
#else
const BaseNode* node = cur.baseNode(types);
+384
View File
@@ -0,0 +1,384 @@
// ======================================================================== //
// 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 "bvh.h"
#include "../common/ray.h"
#include "../common/stack_item.h"
namespace embree
{
namespace isa
{
struct NearFarPreCompute
{
size_t nearX, nearY, nearZ;
size_t farX, farY, farZ;
__forceinline NearFarPreCompute() {}
__forceinline NearFarPreCompute(const Vec3fa& dir, size_t N)
{
const size_t M = sizeof(float)*N;
nearX = (dir.x < 0.0f) ? 1*M : 0*M;
nearY = (dir.y < 0.0f) ? 3*M : 2*M;
nearZ = (dir.z < 0.0f) ? 5*M : 4*M;
farX = nearX ^ M;
farY = nearY ^ M;
farZ = nearZ ^ M;
}
};
template<int K, bool robust>
struct Packet;
template<int K>
struct Packet<K,false>
{
Vec3vf<K> rdir;
Vec3vf<K> org_rdir;
vfloat<K> min_dist;
vfloat<K> max_dist;
__forceinline Packet () {}
__forceinline Packet (const Vec3vf<K>& org, const Vec3vf<K>& dir, const vfloat<K>& tnear, const vfloat<K>& tfar)
: rdir(rcp_safe(dir)), org_rdir(org*rdir), min_dist(tnear), max_dist(tfar) {}
template<int N, int Nx>
__forceinline size_t intersectRay(const typename BVHN<N>::AlignedNode* __restrict__ node, size_t rid, const NearFarPreCompute& nf) const
{
const vfloat<Nx> bminX = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.nearX));
const vfloat<Nx> bminY = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.nearY));
const vfloat<Nx> bminZ = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.nearZ));
const vfloat<Nx> bmaxX = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.farX));
const vfloat<Nx> bmaxY = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.farY));
const vfloat<Nx> bmaxZ = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.farZ));
const vfloat<Nx> rminX = msub(bminX, vfloat<Nx>(rdir.x[rid]), vfloat<Nx>(org_rdir.x[rid]));
const vfloat<Nx> rminY = msub(bminY, vfloat<Nx>(rdir.y[rid]), vfloat<Nx>(org_rdir.y[rid]));
const vfloat<Nx> rminZ = msub(bminZ, vfloat<Nx>(rdir.z[rid]), vfloat<Nx>(org_rdir.z[rid]));
const vfloat<Nx> rmaxX = msub(bmaxX, vfloat<Nx>(rdir.x[rid]), vfloat<Nx>(org_rdir.x[rid]));
const vfloat<Nx> rmaxY = msub(bmaxY, vfloat<Nx>(rdir.y[rid]), vfloat<Nx>(org_rdir.y[rid]));
const vfloat<Nx> rmaxZ = msub(bmaxZ, vfloat<Nx>(rdir.z[rid]), vfloat<Nx>(org_rdir.z[rid]));
const vfloat<Nx> rmin = maxi(rminX, rminY, rminZ, vfloat<Nx>(min_dist[rid]));
const vfloat<Nx> rmax = mini(rmaxX, rmaxY, rmaxZ, vfloat<Nx>(max_dist[rid]));
const vbool<Nx> vmask_first_hit = rmin <= rmax;
return movemask(vmask_first_hit) & (((size_t)1 << N)-1);
}
template<int N>
__forceinline size_t intersect(const typename BVHN<N>::AlignedNode* __restrict__ node, size_t bid, const NearFarPreCompute& nf) const
{
char *ptr = (char*)&node->lower_x + bid*sizeof(float);
const vfloat<K> bminX = *(const float*)(ptr + nf.nearX);
const vfloat<K> bminY = *(const float*)(ptr + nf.nearY);
const vfloat<K> bminZ = *(const float*)(ptr + nf.nearZ);
const vfloat<K> bmaxX = *(const float*)(ptr + nf.farX);
const vfloat<K> bmaxY = *(const float*)(ptr + nf.farY);
const vfloat<K> bmaxZ = *(const float*)(ptr + nf.farZ);
const vfloat<K> rminX = msub(bminX, rdir.x, org_rdir.x);
const vfloat<K> rminY = msub(bminY, rdir.y, org_rdir.y);
const vfloat<K> rminZ = msub(bminZ, rdir.z, org_rdir.z);
const vfloat<K> rmaxX = msub(bmaxX, rdir.x, org_rdir.x);
const vfloat<K> rmaxY = msub(bmaxY, rdir.y, org_rdir.y);
const vfloat<K> rmaxZ = msub(bmaxZ, rdir.z, org_rdir.z);
const vfloat<K> rmin = maxi(rminX, rminY, rminZ, min_dist);
const vfloat<K> rmax = mini(rmaxX, rmaxY, rmaxZ, max_dist);
const vbool<K> vmask_first_hit = rmin <= rmax;
return movemask(vmask_first_hit);
}
};
template<int K>
struct Packet<K,true>
{
Vec3vf<K> rdir;
Vec3vf<K> org;
vfloat<K> min_dist;
vfloat<K> max_dist;
__forceinline Packet () {}
__forceinline Packet (const Vec3vf<K>& org, const Vec3vf<K>& dir, const vfloat<K>& tnear, const vfloat<K>& tfar)
: rdir(rcp_safe(dir)), org(org), min_dist(tnear), max_dist(tfar) {}
template<int N, int Nx>
__forceinline size_t intersectRay(const typename BVHN<N>::AlignedNode* __restrict__ node, size_t rid, const NearFarPreCompute& nf) const
{
const vfloat<Nx> bminX = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.nearX));
const vfloat<Nx> bminY = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.nearY));
const vfloat<Nx> bminZ = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.nearZ));
const vfloat<Nx> bmaxX = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.farX));
const vfloat<Nx> bmaxY = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.farY));
const vfloat<Nx> bmaxZ = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_x + nf.farZ));
const vfloat<Nx> rminX = (bminX - vfloat<Nx>(org.x[rid])) * vfloat<Nx>(rdir.x[rid]);
const vfloat<Nx> rminY = (bminY - vfloat<Nx>(org.y[rid])) * vfloat<Nx>(rdir.y[rid]);
const vfloat<Nx> rminZ = (bminZ - vfloat<Nx>(org.z[rid])) * vfloat<Nx>(rdir.z[rid]);
const vfloat<Nx> rmaxX = (bmaxX - vfloat<Nx>(org.x[rid])) * vfloat<Nx>(rdir.x[rid]);
const vfloat<Nx> rmaxY = (bmaxY - vfloat<Nx>(org.y[rid])) * vfloat<Nx>(rdir.y[rid]);
const vfloat<Nx> rmaxZ = (bmaxZ - vfloat<Nx>(org.z[rid])) * vfloat<Nx>(rdir.z[rid]);
const float round_down = 1.0f-2.0f*float(ulp); // FIXME: use per instruction rounding for AVX512
const float round_up = 1.0f+2.0f*float(ulp);
const vfloat<Nx> rmin = round_down*max(rminX, rminY, rminZ, vfloat<Nx>(min_dist[rid]));
const vfloat<Nx> rmax = round_up *min(rmaxX, rmaxY, rmaxZ, vfloat<Nx>(max_dist[rid]));
const vbool<Nx> vmask_first_hit = rmin <= rmax;
return movemask(vmask_first_hit) & (((size_t)1 << N)-1);
}
template<int N>
__forceinline size_t intersect(const typename BVHN<N>::AlignedNode* __restrict__ node, size_t bid, const NearFarPreCompute& nf) const
{
char *ptr = (char*)&node->lower_x + bid*sizeof(float);
const vfloat<K> bminX = *(const float*)(ptr + nf.nearX);
const vfloat<K> bminY = *(const float*)(ptr + nf.nearY);
const vfloat<K> bminZ = *(const float*)(ptr + nf.nearZ);
const vfloat<K> bmaxX = *(const float*)(ptr + nf.farX);
const vfloat<K> bmaxY = *(const float*)(ptr + nf.farY);
const vfloat<K> bmaxZ = *(const float*)(ptr + nf.farZ);
const vfloat<K> rminX = (bminX - org.x) * rdir.x;
const vfloat<K> rminY = (bminY - org.y) * rdir.y;
const vfloat<K> rminZ = (bminZ - org.z) * rdir.z;
const vfloat<K> rmaxX = (bmaxX - org.x) * rdir.x;
const vfloat<K> rmaxY = (bmaxY - org.y) * rdir.y;
const vfloat<K> rmaxZ = (bmaxZ - org.z) * rdir.z;
const float round_down = 1.0f-2.0f*float(ulp); // FIXME: use per instruction rounding for AVX512
const float round_up = 1.0f+2.0f*float(ulp);
const vfloat<K> rmin = round_down*max(rminX, rminY, rminZ, vfloat<K>(min_dist));
const vfloat<K> rmax = round_up *min(rmaxX, rmaxY, rmaxZ, vfloat<K>(max_dist));
const vbool<K> vmask_first_hit = rmin <= rmax;
return movemask(vmask_first_hit);
}
};
/* Optimized frustum test. We calculate t=(p-org)/dir in ray/box
* intersection. We assume the rays are split by octant, thus
* dir intervals are either positive or negative in each
* dimension.
Case 1: dir.min >= 0 && dir.max >= 0:
t_min = (p_min - org_max) / dir_max = (p_min - org_max)*rdir_min = p_min*rdir_min - org_max*rdir_min
t_max = (p_max - org_min) / dir_min = (p_max - org_min)*rdir_max = p_max*rdir_max - org_min*rdir_max
Case 2: dir.min < 0 && dir.max < 0:
t_min = (p_max - org_min) / dir_min = (p_max - org_min)*rdir_max = p_max*rdir_max - org_min*rdir_max
t_max = (p_min - org_max) / dir_max = (p_min - org_max)*rdir_min = p_min*rdir_min - org_max*rdir_min
*/
template<int N, int Nx, int K, bool robust>
struct Frustum;
template<int N, int Nx, int K>
struct Frustum<N,Nx,K,false>
{
__forceinline Frustum() {}
__forceinline Frustum(const vbool<K>& valid, const Vec3vf<K>& org, const Vec3vf<K>& rdir, const vfloat<K>& ray_tnear, const vfloat<K>& ray_tfar) {
init(valid,org,rdir,ray_tnear,ray_tfar);
}
__forceinline void init(const vbool<K>& valid, const Vec3vf<K>& org, const Vec3vf<K>& rdir, const vfloat<K>& ray_tnear, const vfloat<K>& ray_tfar)
{
const Vec3fa reduced_min_org( reduce_min(select(valid,org.x,pos_inf)),
reduce_min(select(valid,org.y,pos_inf)),
reduce_min(select(valid,org.z,pos_inf)) );
const Vec3fa reduced_max_org( reduce_max(select(valid,org.x,neg_inf)),
reduce_max(select(valid,org.y,neg_inf)),
reduce_max(select(valid,org.z,neg_inf)) );
const Vec3fa reduced_min_rdir( reduce_min(select(valid,rdir.x,pos_inf)),
reduce_min(select(valid,rdir.y,pos_inf)),
reduce_min(select(valid,rdir.z,pos_inf)) );
const Vec3fa reduced_max_rdir( reduce_max(select(valid,rdir.x,neg_inf)),
reduce_max(select(valid,rdir.y,neg_inf)),
reduce_max(select(valid,rdir.z,neg_inf)) );
const float reduced_min_dist = reduce_min(select(valid,ray_tnear,vfloat<K>(pos_inf)));
const float reduced_max_dist = reduce_max(select(valid,ray_tfar ,vfloat<K>(neg_inf)));
init(reduced_min_org, reduced_max_org, reduced_min_rdir, reduced_max_rdir, reduced_min_dist, reduced_max_dist);
}
__forceinline void init(const Vec3fa& reduced_min_org,
const Vec3fa& reduced_max_org,
const Vec3fa& reduced_min_rdir,
const Vec3fa& reduced_max_rdir,
const float reduced_min_dist,
const float reduced_max_dist)
{
const Vec3ba pos_rdir = ge_mask(reduced_min_rdir, Vec3fa(zero));
min_rdir = select(pos_rdir, reduced_min_rdir, reduced_max_rdir);
max_rdir = select(pos_rdir, reduced_max_rdir, reduced_min_rdir);
min_org_rdir = min_rdir * select(pos_rdir, reduced_max_org, reduced_min_org);
max_org_rdir = max_rdir * select(pos_rdir, reduced_min_org, reduced_max_org);
min_dist = reduced_min_dist;
max_dist = reduced_max_dist;
nf = NearFarPreCompute(min_rdir,N);
}
__forceinline size_t intersect(const typename BVHN<N>::AlignedNode* __restrict__ node, vfloat<Nx>& dist) const
{
const vfloat<Nx> bminX = *(const vfloat<N>*)((const char*)&node->lower_x + nf.nearX);
const vfloat<Nx> bminY = *(const vfloat<N>*)((const char*)&node->lower_x + nf.nearY);
const vfloat<Nx> bminZ = *(const vfloat<N>*)((const char*)&node->lower_x + nf.nearZ);
const vfloat<Nx> bmaxX = *(const vfloat<N>*)((const char*)&node->lower_x + nf.farX);
const vfloat<Nx> bmaxY = *(const vfloat<N>*)((const char*)&node->lower_x + nf.farY);
const vfloat<Nx> bmaxZ = *(const vfloat<N>*)((const char*)&node->lower_x + nf.farZ);
const vfloat<Nx> fminX = msub(bminX, vfloat<Nx>(min_rdir.x), vfloat<Nx>(min_org_rdir.x));
const vfloat<Nx> fminY = msub(bminY, vfloat<Nx>(min_rdir.y), vfloat<Nx>(min_org_rdir.y));
const vfloat<Nx> fminZ = msub(bminZ, vfloat<Nx>(min_rdir.z), vfloat<Nx>(min_org_rdir.z));
const vfloat<Nx> fmaxX = msub(bmaxX, vfloat<Nx>(max_rdir.x), vfloat<Nx>(max_org_rdir.x));
const vfloat<Nx> fmaxY = msub(bmaxY, vfloat<Nx>(max_rdir.y), vfloat<Nx>(max_org_rdir.y));
const vfloat<Nx> fmaxZ = msub(bmaxZ, vfloat<Nx>(max_rdir.z), vfloat<Nx>(max_org_rdir.z));
const vfloat<Nx> fmin = maxi(fminX, fminY, fminZ, vfloat<Nx>(min_dist));
dist = fmin;
const vfloat<Nx> fmax = mini(fmaxX, fmaxY, fmaxZ, vfloat<Nx>(max_dist));
const vbool<Nx> vmask_node_hit = fmin <= fmax;
size_t m_node = movemask(vmask_node_hit) & (((size_t)1 << N)-1);
return m_node;
}
__forceinline void updateMaxDist(const vfloat<K>& ray_tfar) {
max_dist = reduce_max(ray_tfar);
}
NearFarPreCompute nf;
Vec3fa min_rdir;
Vec3fa max_rdir;
Vec3fa min_org_rdir;
Vec3fa max_org_rdir;
float min_dist;
float max_dist;
};
template<int N, int Nx, int K>
struct Frustum<N,Nx,K,true >
{
__forceinline Frustum() {}
__forceinline Frustum(const vbool<K>& valid, const Vec3vf<K>& org, const Vec3vf<K>& rdir, const vfloat<K>& ray_tnear, const vfloat<K>& ray_tfar) {
init(valid,org,rdir,ray_tnear,ray_tfar);
}
__forceinline void init(const vbool<K>& valid, const Vec3vf<K>& org, const Vec3vf<K>& rdir, const vfloat<K>& ray_tnear, const vfloat<K>& ray_tfar)
{
const Vec3fa reduced_min_org( reduce_min(select(valid,org.x,pos_inf)),
reduce_min(select(valid,org.y,pos_inf)),
reduce_min(select(valid,org.z,pos_inf)) );
const Vec3fa reduced_max_org( reduce_max(select(valid,org.x,neg_inf)),
reduce_max(select(valid,org.y,neg_inf)),
reduce_max(select(valid,org.z,neg_inf)) );
const Vec3fa reduced_min_rdir( reduce_min(select(valid,rdir.x,pos_inf)),
reduce_min(select(valid,rdir.y,pos_inf)),
reduce_min(select(valid,rdir.z,pos_inf)) );
const Vec3fa reduced_max_rdir( reduce_max(select(valid,rdir.x,neg_inf)),
reduce_max(select(valid,rdir.y,neg_inf)),
reduce_max(select(valid,rdir.z,neg_inf)) );
const float reduced_min_dist = reduce_min(select(valid,ray_tnear,vfloat<K>(pos_inf)));
const float reduced_max_dist = reduce_max(select(valid,ray_tfar ,vfloat<K>(neg_inf)));
init(reduced_min_org, reduced_max_org, reduced_min_rdir, reduced_max_rdir, reduced_min_dist, reduced_max_dist);
}
__forceinline void init(const Vec3fa& reduced_min_org,
const Vec3fa& reduced_max_org,
const Vec3fa& reduced_min_rdir,
const Vec3fa& reduced_max_rdir,
const float reduced_min_dist,
const float reduced_max_dist)
{
const Vec3ba pos_rdir = ge_mask(reduced_min_rdir, Vec3fa(zero));
min_rdir = select(pos_rdir, reduced_min_rdir, reduced_max_rdir);
max_rdir = select(pos_rdir, reduced_max_rdir, reduced_min_rdir);
min_org = select(pos_rdir, reduced_max_org, reduced_min_org);
max_org = select(pos_rdir, reduced_min_org, reduced_max_org);
min_dist = reduced_min_dist;
max_dist = reduced_max_dist;
nf = NearFarPreCompute(min_rdir,N);
}
__forceinline size_t intersect(const typename BVHN<N>::AlignedNode* __restrict__ node, vfloat<Nx>& dist) const
{
const vfloat<Nx> bminX = *(const vfloat<N>*)((const char*)&node->lower_x + nf.nearX);
const vfloat<Nx> bminY = *(const vfloat<N>*)((const char*)&node->lower_x + nf.nearY);
const vfloat<Nx> bminZ = *(const vfloat<N>*)((const char*)&node->lower_x + nf.nearZ);
const vfloat<Nx> bmaxX = *(const vfloat<N>*)((const char*)&node->lower_x + nf.farX);
const vfloat<Nx> bmaxY = *(const vfloat<N>*)((const char*)&node->lower_x + nf.farY);
const vfloat<Nx> bmaxZ = *(const vfloat<N>*)((const char*)&node->lower_x + nf.farZ);
const vfloat<Nx> fminX = (bminX - vfloat<Nx>(min_org.x)) * vfloat<Nx>(min_rdir.x);
const vfloat<Nx> fminY = (bminY - vfloat<Nx>(min_org.y)) * vfloat<Nx>(min_rdir.y);
const vfloat<Nx> fminZ = (bminZ - vfloat<Nx>(min_org.z)) * vfloat<Nx>(min_rdir.z);
const vfloat<Nx> fmaxX = (bmaxX - vfloat<Nx>(max_org.x)) * vfloat<Nx>(max_rdir.x);
const vfloat<Nx> fmaxY = (bmaxY - vfloat<Nx>(max_org.y)) * vfloat<Nx>(max_rdir.y);
const vfloat<Nx> fmaxZ = (bmaxZ - vfloat<Nx>(max_org.z)) * vfloat<Nx>(max_rdir.z);
const float round_down = 1.0f-2.0f*float(ulp); // FIXME: use per instruction rounding for AVX512
const float round_up = 1.0f+2.0f*float(ulp);
const vfloat<Nx> fmin = max(fminX, fminY, fminZ, vfloat<Nx>(min_dist));
dist = fmin;
const vfloat<Nx> fmax = min(fmaxX, fmaxY, fmaxZ, vfloat<Nx>(max_dist));
const vbool<Nx> vmask_node_hit = (round_down*fmin <= round_up*fmax);
size_t m_node = movemask(vmask_node_hit) & (((size_t)1 << N)-1);
return m_node;
}
__forceinline void updateMaxDist(const vfloat<K>& ray_tfar) {
max_dist = reduce_max(ray_tfar);
}
NearFarPreCompute nf;
Vec3fa min_rdir;
Vec3fa max_rdir;
Vec3fa min_org;
Vec3fa max_org;
float min_dist;
float max_dist;
};
}
}
+127 -137
View File
@@ -61,62 +61,64 @@ namespace embree
ALIGNED_CLASS;
public:
struct Intersectors;
/*! Type of intersect function pointer for single rays. */
typedef void (*IntersectFunc)(void* ptr, /*!< pointer to user data */
typedef void (*IntersectFunc)(Intersectors* This, /*!< this pointer to accel */
RTCRay& ray, /*!< ray to intersect */
IntersectContext* context);
/*! Type of intersect function pointer for ray packets of size 4. */
typedef void (*IntersectFunc4)(const void* valid, /*!< pointer to valid mask */
void* ptr, /*!< pointer to user data */
Intersectors* This, /*!< this pointer to accel */
RTCRay4& ray, /*!< ray packet to intersect */
IntersectContext* context);
/*! Type of intersect function pointer for ray packets of size 8. */
typedef void (*IntersectFunc8)(const void* valid, /*!< pointer to valid mask */
void* ptr, /*!< pointer to user data */
Intersectors* This, /*!< this pointer to accel */
RTCRay8& ray, /*!< ray packet to intersect */
IntersectContext* context);
/*! Type of intersect function pointer for ray packets of size 16. */
typedef void (*IntersectFunc16)(const void* valid, /*!< pointer to valid mask */
void* ptr, /*!< pointer to user data */
typedef void (*IntersectFunc16)(const void* valid, /*!< pointer to valid mask */
Intersectors* This, /*!< this pointer to accel */
RTCRay16& ray, /*!< ray packet to intersect */
IntersectContext* context);
/*! Type of intersect function pointer for ray packets of size N. */
typedef void (*IntersectFuncN)(void* ptr, /*!< pointer to user data */
void** ray, /*!< ray stream to intersect */
typedef void (*IntersectFuncN)(Intersectors* This, /*!< this pointer to accel */
RayK<VSIZEX>** ray, /*!< ray stream to intersect */
const size_t N, /*!< number of rays in stream */
IntersectContext* context /*!< layout flags */);
/*! Type of occlusion function pointer for single rays. */
typedef void (*OccludedFunc) (void* ptr, /*!< pointer to user data */
typedef void (*OccludedFunc) (Intersectors* This, /*!< this pointer to accel */
RTCRay& ray, /*!< ray to test occlusion */
IntersectContext* context);
/*! Type of occlusion function pointer for ray packets of size 4. */
typedef void (*OccludedFunc4) (const void* valid, /*! pointer to valid mask */
void* ptr, /*!< pointer to user data */
Intersectors* This, /*!< this pointer to accel */
RTCRay4& ray, /*!< Ray packet to test occlusion. */
IntersectContext* context);
/*! Type of occlusion function pointer for ray packets of size 8. */
typedef void (*OccludedFunc8) (const void* valid, /*! pointer to valid mask */
void* ptr, /*!< pointer to user data */
Intersectors* This, /*!< this pointer to accel */
RTCRay8& ray, /*!< Ray packet to test occlusion. */
IntersectContext* context);
/*! Type of occlusion function pointer for ray packets of size 16. */
typedef void (*OccludedFunc16) (const void* valid, /*! pointer to valid mask */
void* ptr, /*!< pointer to user data */
Intersectors* This,/*!< this pointer to accel */
RTCRay16& ray, /*!< Ray packet to test occlusion. */
IntersectContext* context);
/*! Type of intersect function pointer for ray packets of size N. */
typedef void (*OccludedFuncN)(void* ptr, /*!< pointer to user data */
void** ray, /*!< ray stream to intersect */
typedef void (*OccludedFuncN)(Intersectors* This, /*!< this pointer to accel */
RayK<VSIZEX>** ray, /*!< ray stream to intersect */
const size_t N, /*!< number of rays in stream */
IntersectContext* context /*!< layout flags */);
typedef void (*ErrorFunc) ();
@@ -258,6 +260,118 @@ namespace embree
}
}
/*! Intersects a single ray with the scene. */
__forceinline void intersect (RTCRay& ray, IntersectContext* context) {
assert(intersector1.intersect);
intersector1.intersect(this,ray,context);
}
/*! Intersects a packet of 4 rays with the scene. */
__forceinline void intersect4 (const void* valid, RTCRay4& ray, IntersectContext* context) {
assert(intersector4.intersect);
intersector4.intersect(valid,this,ray,context);
}
/*! Intersects a packet of 8 rays with the scene. */
__forceinline void intersect8 (const void* valid, RTCRay8& ray, IntersectContext* context) {
assert(intersector8.intersect);
intersector8.intersect(valid,this,ray,context);
}
/*! Intersects a packet of 16 rays with the scene. */
__forceinline void intersect16 (const void* valid, RTCRay16& ray, IntersectContext* context) {
assert(intersector16.intersect);
intersector16.intersect(valid,this,ray,context);
}
/*! Intersects a packet of N rays in SOA layout with the scene. */
__forceinline void intersectN (RayK<VSIZEX>** rayN, const size_t N, IntersectContext* context)
{
assert(intersectorN.intersect);
intersectorN.intersect(this,rayN,N,context);
}
#if defined(__SSE__)
__forceinline void intersect(const vbool4& valid, RayK<4>& ray, IntersectContext* context) {
const vint<4> mask = valid.mask32();
intersect4(&mask,(RTCRay4&)ray,context);
}
#endif
#if defined(__AVX__)
__forceinline void intersect(const vbool8& valid, RayK<8>& ray, IntersectContext* context) {
const vint<8> mask = valid.mask32();
intersect8(&mask,(RTCRay8&)ray,context);
}
#endif
#if defined(__AVX512F__)
__forceinline void intersect(const vbool16& valid, RayK<16>& ray, IntersectContext* context) {
const vint<16> mask = valid.mask32();
intersect16(&mask,(RTCRay16&)ray,context);
}
#endif
/*! Tests if single ray is occluded by the scene. */
__forceinline void occluded (RTCRay& ray, IntersectContext* context) {
assert(intersector1.occluded);
intersector1.occluded(this,ray,context);
}
/*! Tests if a packet of 4 rays is occluded by the scene. */
__forceinline void occluded4 (const void* valid, RTCRay4& ray, IntersectContext* context) {
assert(intersector4.occluded);
intersector4.occluded(valid,this,ray,context);
}
/*! Tests if a packet of 8 rays is occluded by the scene. */
__forceinline void occluded8 (const void* valid, RTCRay8& ray, IntersectContext* context) {
assert(intersector8.occluded);
intersector8.occluded(valid,this,ray,context);
}
/*! Tests if a packet of 16 rays is occluded by the scene. */
__forceinline void occluded16 (const void* valid, RTCRay16& ray, IntersectContext* context) {
assert(intersector16.occluded);
intersector16.occluded(valid,this,ray,context);
}
/*! Tests if a packet of N rays in SOA layout is occluded by the scene. */
__forceinline void occludedN (RayK<VSIZEX>** rayN, const size_t N, IntersectContext* context)
{
//assert(intersectorN.occluded);
if (intersectorN.occluded)
intersectorN.occluded(this,rayN,N,context);
else
{
const size_t numPackets = (N+VSIZEX-1)/VSIZEX;
for (size_t i=0; i<numPackets; i++)
{
RayK<VSIZEX> &ray = *rayN[i];
vbool<VSIZEX> valid = ray.tnear <= ray.tfar;
occluded(valid,ray,context);
}
}
}
#if defined(__SSE__)
__forceinline void occluded(const vbool4& valid, RayK<4>& ray, IntersectContext* context) {
const vint<4> mask = valid.mask32();
occluded4(&mask,(RTCRay4&)ray,context);
}
#endif
#if defined(__AVX__)
__forceinline void occluded(const vbool8& valid, RayK<8>& ray, IntersectContext* context) {
const vint<8> mask = valid.mask32();
occluded8(&mask,(RTCRay8&)ray,context);
}
#endif
#if defined(__AVX512F__)
__forceinline void occluded(const vbool16& valid, RayK<16>& ray, IntersectContext* context) {
const vint<16> mask = valid.mask32();
occluded16(&mask,(RTCRay16&)ray,context);
}
#endif
public:
AccelData* ptr;
Intersector1 intersector1;
@@ -294,130 +408,6 @@ namespace embree
/*! build acceleration structure */
virtual void build () = 0;
/*! Intersects a single ray with the scene. */
__forceinline void intersect (RTCRay& ray, IntersectContext* context) {
assert(intersectors.intersector1.intersect);
intersectors.intersector1.intersect(intersectors.ptr,ray,context);
}
/*! Intersects a packet of 4 rays with the scene. */
__forceinline void intersect4 (const void* valid, RTCRay4& ray, IntersectContext* context) {
assert(intersectors.intersector4.intersect);
intersectors.intersector4.intersect(valid,intersectors.ptr,ray,context);
}
/*! Intersects a packet of 8 rays with the scene. */
__forceinline void intersect8 (const void* valid, RTCRay8& ray, IntersectContext* context) {
assert(intersectors.intersector8.intersect);
intersectors.intersector8.intersect(valid,intersectors.ptr,ray,context);
}
/*! Intersects a packet of 16 rays with the scene. */
__forceinline void intersect16 (const void* valid, RTCRay16& ray, IntersectContext* context) {
assert(intersectors.intersector16.intersect);
intersectors.intersector16.intersect(valid,intersectors.ptr,ray,context);
}
/*! Intersects a packet of N rays in SOA layout with the scene. */
__forceinline void intersectN (void **rayN, const size_t N, IntersectContext* context)
{
//assert(intersectors.intersectorN.intersect);
if (intersectors.intersectorN.intersect)
intersectors.intersectorN.intersect(intersectors.ptr,rayN,N,context);
else
{
const size_t numPackets = (N+VSIZEX-1)/VSIZEX;
for (size_t i=0; i<numPackets; i++)
{
RayK<VSIZEX> &ray = *(RayK<VSIZEX>*)rayN[i];
vbool<VSIZEX> valid = ray.tnear <= ray.tfar;
intersect(valid,ray,context);
}
}
}
#if defined(__SSE__)
__forceinline void intersect(const vbool4& valid, RayK<4>& ray, IntersectContext* context) {
const vint<4> mask = valid.mask32();
intersect4(&mask,(RTCRay4&)ray,context);
}
#endif
#if defined(__AVX__)
__forceinline void intersect(const vbool8& valid, RayK<8>& ray, IntersectContext* context) {
const vint<8> mask = valid.mask32();
intersect8(&mask,(RTCRay8&)ray,context);
}
#endif
#if defined(__AVX512F__)
__forceinline void intersect(const vbool16& valid, RayK<16>& ray, IntersectContext* context) {
const vint<16> mask = valid.mask32();
intersect16(&mask,(RTCRay16&)ray,context);
}
#endif
/*! Tests if single ray is occluded by the scene. */
__forceinline void occluded (RTCRay& ray, IntersectContext* context) {
assert(intersectors.intersector1.occluded);
intersectors.intersector1.occluded(intersectors.ptr,ray,context);
}
/*! Tests if a packet of 4 rays is occluded by the scene. */
__forceinline void occluded4 (const void* valid, RTCRay4& ray, IntersectContext* context) {
assert(intersectors.intersector4.occluded);
intersectors.intersector4.occluded(valid,intersectors.ptr,ray,context);
}
/*! Tests if a packet of 8 rays is occluded by the scene. */
__forceinline void occluded8 (const void* valid, RTCRay8& ray, IntersectContext* context) {
assert(intersectors.intersector8.occluded);
intersectors.intersector8.occluded(valid,intersectors.ptr,ray,context);
}
/*! Tests if a packet of 16 rays is occluded by the scene. */
__forceinline void occluded16 (const void* valid, RTCRay16& ray, IntersectContext* context) {
assert(intersectors.intersector16.occluded);
intersectors.intersector16.occluded(valid,intersectors.ptr,ray,context);
}
/*! Tests if a packet of N rays in SOA layout is occluded by the scene. */
__forceinline void occludedN (void **rayN, const size_t N, IntersectContext* context)
{
//assert(intersectors.intersectorN.occluded);
if (intersectors.intersectorN.occluded)
intersectors.intersectorN.occluded(intersectors.ptr,rayN,N,context);
else
{
const size_t numPackets = (N+VSIZEX-1)/VSIZEX;
for (size_t i=0; i<numPackets; i++)
{
RayK<VSIZEX> &ray = *(RayK<VSIZEX>*)rayN[i];
vbool<VSIZEX> valid = ray.tnear <= ray.tfar;
occluded(valid,ray,context);
}
}
}
#if defined(__SSE__)
__forceinline void occluded(const vbool4& valid, RayK<4>& ray, IntersectContext* context) {
const vint<4> mask = valid.mask32();
occluded4(&mask,(RTCRay4&)ray,context);
}
#endif
#if defined(__AVX__)
__forceinline void occluded(const vbool8& valid, RayK<8>& ray, IntersectContext* context) {
const vint<8> mask = valid.mask32();
occluded8(&mask,(RTCRay8&)ray,context);
}
#endif
#if defined(__AVX512F__)
__forceinline void occluded(const vbool16& valid, RayK<16>& ray, IntersectContext* context) {
const vint<16> mask = valid.mask32();
occluded16(&mask,(RTCRay16&)ray,context);
}
#endif
public:
Intersectors intersectors;
};
+31 -33
View File
@@ -22,7 +22,7 @@
namespace embree
{
AccelN::AccelN ()
: Accel(AccelData::TY_ACCELN), accels(nullptr), validAccels(nullptr), validIntersectorN(false) {}
: Accel(AccelData::TY_ACCELN), accels(nullptr), validAccels(nullptr) {}
AccelN::~AccelN()
{
@@ -39,55 +39,55 @@ namespace embree
accels.push_back(accel);
}
void AccelN::intersect (void* ptr, RTCRay& ray, IntersectContext* context)
void AccelN::intersect (Accel::Intersectors* This_in, RTCRay& ray, IntersectContext* context)
{
AccelN* This = (AccelN*)ptr;
AccelN* This = (AccelN*)This_in->ptr;
for (size_t i=0; i<This->validAccels.size(); i++)
This->validAccels[i]->intersect(ray,context);
This->validAccels[i]->intersectors.intersect(ray,context);
}
void AccelN::intersect4 (const void* valid, void* ptr, RTCRay4& ray, IntersectContext* context)
void AccelN::intersect4 (const void* valid, Accel::Intersectors* This_in, RTCRay4& ray, IntersectContext* context)
{
AccelN* This = (AccelN*)ptr;
AccelN* This = (AccelN*)This_in->ptr;
for (size_t i=0; i<This->validAccels.size(); i++)
This->validAccels[i]->intersect4(valid,ray,context);
This->validAccels[i]->intersectors.intersect4(valid,ray,context);
}
void AccelN::intersect8 (const void* valid, void* ptr, RTCRay8& ray, IntersectContext* context)
void AccelN::intersect8 (const void* valid, Accel::Intersectors* This_in, RTCRay8& ray, IntersectContext* context)
{
AccelN* This = (AccelN*)ptr;
AccelN* This = (AccelN*)This_in->ptr;
for (size_t i=0; i<This->validAccels.size(); i++)
This->validAccels[i]->intersect8(valid,ray,context);
This->validAccels[i]->intersectors.intersect8(valid,ray,context);
}
void AccelN::intersect16 (const void* valid, void* ptr, RTCRay16& ray, IntersectContext* context)
void AccelN::intersect16 (const void* valid, Accel::Intersectors* This_in, RTCRay16& ray, IntersectContext* context)
{
AccelN* This = (AccelN*)ptr;
AccelN* This = (AccelN*)This_in->ptr;
for (size_t i=0; i<This->validAccels.size(); i++)
This->validAccels[i]->intersect16(valid,ray,context);
This->validAccels[i]->intersectors.intersect16(valid,ray,context);
}
void AccelN::intersectN (void* ptr, void** ray, const size_t N, IntersectContext* context)
void AccelN::intersectN (Accel::Intersectors* This_in, RayK<VSIZEX>** ray, const size_t N, IntersectContext* context)
{
AccelN* This = (AccelN*)ptr;
AccelN* This = (AccelN*)This_in->ptr;
for (size_t i=0; i<This->validAccels.size(); i++)
This->validAccels[i]->intersectN(ray,N,context);
This->validAccels[i]->intersectors.intersectN(ray,N,context);
}
void AccelN::occluded (void* ptr, RTCRay& ray, IntersectContext* context)
void AccelN::occluded (Accel::Intersectors* This_in, RTCRay& ray, IntersectContext* context)
{
AccelN* This = (AccelN*)ptr;
AccelN* This = (AccelN*)This_in->ptr;
for (size_t i=0; i<This->validAccels.size(); i++) {
This->validAccels[i]->occluded(ray,context);
This->validAccels[i]->intersectors.occluded(ray,context);
if (ray.geomID == 0) break;
}
}
void AccelN::occluded4 (const void* valid, void* ptr, RTCRay4& ray, IntersectContext* context)
void AccelN::occluded4 (const void* valid, Accel::Intersectors* This_in, RTCRay4& ray, IntersectContext* context)
{
AccelN* This = (AccelN*)ptr;
AccelN* This = (AccelN*)This_in->ptr;
for (size_t i=0; i<This->validAccels.size(); i++) {
This->validAccels[i]->occluded4(valid,ray,context);
This->validAccels[i]->intersectors.occluded4(valid,ray,context);
#if defined(__SSE2__)
vbool4 valid0 = ((vbool4*)valid)[0];
vbool4 hit0 = ((vint4*)ray.geomID)[0] != vint4(0);
@@ -96,11 +96,11 @@ namespace embree
}
}
void AccelN::occluded8 (const void* valid, void* ptr, RTCRay8& ray, IntersectContext* context)
void AccelN::occluded8 (const void* valid, Accel::Intersectors* This_in, RTCRay8& ray, IntersectContext* context)
{
AccelN* This = (AccelN*)ptr;
AccelN* This = (AccelN*)This_in->ptr;
for (size_t i=0; i<This->validAccels.size(); i++) {
This->validAccels[i]->occluded8(valid,ray,context);
This->validAccels[i]->intersectors.occluded8(valid,ray,context);
#if defined(__SSE2__) // FIXME: use higher ISA
vbool4 valid0 = ((vbool4*)valid)[0];
vbool4 hit0 = ((vint4*)ray.geomID)[0] != vint4(0);
@@ -111,11 +111,11 @@ namespace embree
}
}
void AccelN::occluded16 (const void* valid, void* ptr, RTCRay16& ray, IntersectContext* context)
void AccelN::occluded16 (const void* valid, Accel::Intersectors* This_in, RTCRay16& ray, IntersectContext* context)
{
AccelN* This = (AccelN*)ptr;
AccelN* This = (AccelN*)This_in->ptr;
for (size_t i=0; i<This->validAccels.size(); i++) {
This->validAccels[i]->occluded16(valid,ray,context);
This->validAccels[i]->intersectors.occluded16(valid,ray,context);
#if defined(__SSE2__) // FIXME: use higher ISA
vbool4 valid0 = ((vbool4*)valid)[0];
vbool4 hit0 = ((vint4*)ray.geomID)[0] != vint4(0);
@@ -130,12 +130,12 @@ namespace embree
}
}
void AccelN::occludedN (void* ptr, void** ray, const size_t N, IntersectContext* context)
void AccelN::occludedN (Accel::Intersectors* This_in, RayK<VSIZEX>** ray, const size_t N, IntersectContext* context)
{
AccelN* This = (AccelN*)ptr;
AccelN* This = (AccelN*)This_in->ptr;
size_t M = N;
for (size_t i=0; i<This->validAccels.size(); i++)
This->validAccels[i]->occludedN(ray,M,context);
This->validAccels[i]->intersectors.occludedN(ray,M,context);
}
void AccelN::print(size_t ident)
@@ -163,11 +163,9 @@ namespace embree
/* create list of non-empty acceleration structures */
validAccels.clear();
validIntersectorN = true;
for (size_t i=0; i<accels.size(); i++) {
if (accels[i]->bounds.empty()) continue;
validAccels.push_back(accels[i]);
if (!accels[i]->intersectors.intersectorN) validIntersectorN = false;
}
if (validAccels.size() == 1) {
+10 -12
View File
@@ -31,18 +31,18 @@ namespace embree
void add(Accel* accel);
public:
static void intersect (void* ptr, RTCRay& ray, IntersectContext* context);
static void intersect4 (const void* valid, void* ptr, RTCRay4& ray, IntersectContext* context);
static void intersect8 (const void* valid, void* ptr, RTCRay8& ray, IntersectContext* context);
static void intersect16 (const void* valid, void* ptr, RTCRay16& ray, IntersectContext* context);
static void intersectN (void* ptr, void** ray, const size_t N, IntersectContext* context);
static void intersect (Accel::Intersectors* This, RTCRay& ray, IntersectContext* context);
static void intersect4 (const void* valid, Accel::Intersectors* This, RTCRay4& ray, IntersectContext* context);
static void intersect8 (const void* valid, Accel::Intersectors* This, RTCRay8& ray, IntersectContext* context);
static void intersect16 (const void* valid, Accel::Intersectors* This, RTCRay16& ray, IntersectContext* context);
static void intersectN (Accel::Intersectors* This, RayK<VSIZEX>** ray, const size_t N, IntersectContext* context);
public:
static void occluded (void* ptr, RTCRay& ray, IntersectContext* context);
static void occluded4 (const void* valid, void* ptr, RTCRay4& ray, IntersectContext* context);
static void occluded8 (const void* valid, void* ptr, RTCRay8& ray, IntersectContext* context);
static void occluded16 (const void* valid, void* ptr, RTCRay16& ray, IntersectContext* context);
static void occludedN (void* ptr, void** ray, const size_t N, IntersectContext* context);
static void occluded (Accel::Intersectors* This, RTCRay& ray, IntersectContext* context);
static void occluded4 (const void* valid, Accel::Intersectors* This, RTCRay4& ray, IntersectContext* context);
static void occluded8 (const void* valid, Accel::Intersectors* This, RTCRay8& ray, IntersectContext* context);
static void occluded16 (const void* valid, Accel::Intersectors* This, RTCRay16& ray, IntersectContext* context);
static void occludedN (Accel::Intersectors* This, RayK<VSIZEX>** ray, const size_t N, IntersectContext* context);
public:
void print(size_t ident);
@@ -51,11 +51,9 @@ namespace embree
void select(bool filter4, bool filter8, bool filter16, bool filterN);
void deleteGeometry(size_t geomID);
void clear ();
__forceinline bool validIsecN() { return validIntersectorN; }
public:
darray_t<Accel*,16> accels;
darray_t<Accel*,16> validAccels;
bool validIntersectorN;
};
}
+1 -1
View File
@@ -101,7 +101,7 @@ namespace embree
bvh4_factory = make_unique(new BVH4Factory(enabled_builder_cpu_features, enabled_cpu_features));
#if defined(EMBREE_TARGET_AVX)
#if defined(EMBREE_TARGET_SIMD8)
bvh8_factory = make_unique(new BVH8Factory(enabled_builder_cpu_features, enabled_cpu_features));
#endif
+1 -1
View File
@@ -88,7 +88,7 @@ namespace embree
std::unique_ptr<InstanceFactory> instance_factory;
std::unique_ptr<BVH4Factory> bvh4_factory;
#if defined(EMBREE_TARGET_AVX)
#if defined(EMBREE_TARGET_SIMD8)
std::unique_ptr<BVH8Factory> bvh8_factory;
#endif
+10 -2
View File
@@ -16,6 +16,9 @@
#pragma once
#include "../../common/sys/platform.h"
#include "../../common/sys/sysinfo.h"
namespace embree
{
#define DEFINE_SYMBOL2(type,name) \
@@ -69,12 +72,17 @@ namespace embree
#define SELECT_SYMBOL_SSE42(features,intersector)
#endif
#if defined(EMBREE_TARGET_AVX)
#if defined(EMBREE_TARGET_AVX) || defined(__AVX__)
#if !defined(EMBREE_TARGET_SIMD8)
#define EMBREE_TARGET_SIMD8
#endif
#define SELECT_SYMBOL_AVX(features,intersector) \
#if defined(__AVX__) // if default ISA is >= AVX we treat AVX target as default target
#define SELECT_SYMBOL_AVX(features,intersector) \
if ((features & ISA) == ISA) intersector = isa::intersector;
#else
#define SELECT_SYMBOL_AVX(features,intersector) \
if ((features & AVX) == AVX) intersector = avx::intersector;
#endif
#else
#define SELECT_SYMBOL_AVX(features,intersector)
#endif
+117 -33
View File
@@ -18,10 +18,14 @@
#include "default.h"
#define MAX_INTERNAL_STREAM_SIZE 64
namespace embree
{
#if defined(__X86_64__)
static const size_t MAX_INTERNAL_STREAM_SIZE = 64;
#else
static const size_t MAX_INTERNAL_STREAM_SIZE = 32;
#endif
/* Ray structure for K rays */
template<int K>
struct RayK
@@ -364,35 +368,35 @@ namespace embree
struct RayPacketSOA
{
__forceinline RayPacketSOA(void* rays, size_t K)
: ptr((char*)rays), K(K) {}
__forceinline RayPacketSOA(void* rays, size_t N)
: ptr((char*)rays), N(N) {}
/* ray data access functions */
__forceinline float* orgx(size_t offset) { return (float*)&ptr[0*4*K+offset]; } //!< x coordinate of ray origin
__forceinline float* orgy(size_t offset) { return (float*)&ptr[1*4*K+offset]; } //!< y coordinate of ray origin
__forceinline float* orgz(size_t offset) { return (float*)&ptr[2*4*K+offset]; }; //!< z coordinate of ray origin
__forceinline float* orgx(size_t offset) { return (float*)&ptr[0*4*N+offset]; } //!< x coordinate of ray origin
__forceinline float* orgy(size_t offset) { return (float*)&ptr[1*4*N+offset]; } //!< y coordinate of ray origin
__forceinline float* orgz(size_t offset) { return (float*)&ptr[2*4*N+offset]; }; //!< z coordinate of ray origin
__forceinline float* dirx(size_t offset) { return (float*)&ptr[3*4*K+offset]; }; //!< x coordinate of ray direction
__forceinline float* diry(size_t offset) { return (float*)&ptr[4*4*K+offset]; }; //!< y coordinate of ray direction
__forceinline float* dirz(size_t offset) { return (float*)&ptr[5*4*K+offset]; }; //!< z coordinate of ray direction
__forceinline float* dirx(size_t offset) { return (float*)&ptr[3*4*N+offset]; }; //!< x coordinate of ray direction
__forceinline float* diry(size_t offset) { return (float*)&ptr[4*4*N+offset]; }; //!< y coordinate of ray direction
__forceinline float* dirz(size_t offset) { return (float*)&ptr[5*4*N+offset]; }; //!< z coordinate of ray direction
__forceinline float* tnear(size_t offset) { return (float*)&ptr[6*4*K+offset]; }; //!< Start of ray segment
__forceinline float* tfar (size_t offset) { return (float*)&ptr[7*4*K+offset]; }; //!< End of ray segment (set to hit distance)
__forceinline float* tnear(size_t offset) { return (float*)&ptr[6*4*N+offset]; }; //!< Start of ray segment
__forceinline float* tfar (size_t offset) { return (float*)&ptr[7*4*N+offset]; }; //!< End of ray segment (set to hit distance)
__forceinline float* time(size_t offset) { return (float*)&ptr[8*4*K+offset]; }; //!< Time of this ray for motion blur
__forceinline int* mask(size_t offset) { return (int*) &ptr[9*4*K+offset]; }; //!< Used to mask out objects during traversal (optional)
__forceinline float* time(size_t offset) { return (float*)&ptr[8*4*N+offset]; }; //!< Time of this ray for motion blur
__forceinline int* mask(size_t offset) { return (int*) &ptr[9*4*N+offset]; }; //!< Used to mask out objects during traversal (optional)
/* hit data access functions */
__forceinline float* Ngx(size_t offset) { return (float*)&ptr[10*4*K+offset]; }; //!< x coordinate of geometry normal
__forceinline float* Ngy(size_t offset) { return (float*)&ptr[11*4*K+offset]; }; //!< y coordinate of geometry normal
__forceinline float* Ngz(size_t offset) { return (float*)&ptr[12*4*K+offset]; }; //!< z coordinate of geometry normal
__forceinline float* Ngx(size_t offset) { return (float*)&ptr[10*4*N+offset]; }; //!< x coordinate of geometry normal
__forceinline float* Ngy(size_t offset) { return (float*)&ptr[11*4*N+offset]; }; //!< y coordinate of geometry normal
__forceinline float* Ngz(size_t offset) { return (float*)&ptr[12*4*N+offset]; }; //!< z coordinate of geometry normal
__forceinline float* u(size_t offset) { return (float*)&ptr[13*4*K+offset]; }; //!< Barycentric u coordinate of hit
__forceinline float* v(size_t offset) { return (float*)&ptr[14*4*K+offset]; }; //!< Barycentric v coordinate of hit
__forceinline float* u(size_t offset) { return (float*)&ptr[13*4*N+offset]; }; //!< Barycentric u coordinate of hit
__forceinline float* v(size_t offset) { return (float*)&ptr[14*4*N+offset]; }; //!< Barycentric v coordinate of hit
__forceinline int* geomID(size_t offset) { return (int*)&ptr[15*4*K+offset]; }; //!< geometry ID
__forceinline int* primID(size_t offset) { return (int*)&ptr[16*4*K+offset]; }; //!< primitive ID
__forceinline int* instID(size_t offset) { return (int*)&ptr[17*4*K+offset]; }; //!< instance ID
__forceinline int* geomID(size_t offset) { return (int*)&ptr[15*4*N+offset]; }; //!< geometry ID
__forceinline int* primID(size_t offset) { return (int*)&ptr[16*4*N+offset]; }; //!< primitive ID
__forceinline int* instID(size_t offset) { return (int*)&ptr[17*4*N+offset]; }; //!< instance ID
__forceinline void setRayByIndex(size_t index, const Ray& ray, int* valid)
@@ -467,8 +471,45 @@ namespace embree
ray.tnear = vfloat<K>::loadu(tnear(offset));
ray.tfar = vfloat<K>::loadu(tfar(offset));
ray.time = vfloat<K>::loadu(time(offset));
ray.mask = vint<K> ::loadu(mask(offset));
ray.instID= vint<K> ::loadu(instID(offset));
ray.mask = vint<K>::loadu(mask(offset));
ray.instID = vint<K>::loadu(instID(offset));
ray.geomID = RTC_INVALID_GEOMETRY_ID;
return ray;
}
template<int K>
__forceinline RayK<K> getRayByOffset(const vbool<K>& valid, size_t offset)
{
RayK<K> ray;
ray.org.x = vfloat<K>::loadu(valid, orgx(offset));
ray.org.y = vfloat<K>::loadu(valid, orgy(offset));
ray.org.z = vfloat<K>::loadu(valid, orgz(offset));
ray.dir.x = vfloat<K>::loadu(valid, dirx(offset));
ray.dir.y = vfloat<K>::loadu(valid, diry(offset));
ray.dir.z = vfloat<K>::loadu(valid, dirz(offset));
ray.tnear = vfloat<K>::loadu(valid, tnear(offset));
ray.tfar = vfloat<K>::loadu(valid, tfar(offset));
ray.time = vfloat<K>::loadu(valid, time(offset));
ray.mask = vint<K>::loadu(valid, mask(offset));
#if !defined(__AVX__)
/* SSE: some ray members must be loaded with scalar instructions to ensure that we don't cause memory faults,
because the SSE masked loads always access the entire vector */
if (unlikely(!all(valid)))
{
ray.instID = zero;
for (size_t k = 0; k < K; k++)
{
if (likely(valid[k]))
ray.instID[k] = instID(offset)[k];
}
}
else
#endif
{
ray.instID = vint<K>::loadu(valid, instID(offset));
}
ray.geomID = RTC_INVALID_GEOMETRY_ID;
return ray;
}
@@ -539,17 +580,43 @@ namespace embree
if (likely(any(valid)))
{
vint<K>::storeu(valid, geomID(offset), ray.geomID);
#if !defined(__AVX__)
/* SSE: some ray members must be stored with scalar instructions to ensure that we don't cause memory faults,
because the SSE masked stores always access the entire vector */
if (unlikely(!all(valid_i)))
{
for (size_t k = 0; k < K; k++)
{
if (likely(valid[k]))
{
geomID(offset)[k] = ray.geomID[k];
if (intersect)
{
primID(offset)[k] = ray.primID[k];
instID(offset)[k] = ray.instID[k];
}
}
}
}
else
#endif
{
vint<K>::storeu(valid, geomID(offset), ray.geomID);
if (intersect)
{
vint<K>::storeu(valid, primID(offset), ray.primID);
vint<K>::storeu(valid, instID(offset), ray.instID);
}
}
if (intersect)
{
vfloat<K>::storeu(valid, tfar(offset), ray.tfar);
vfloat<K>::storeu(valid, u(offset), ray.u);
vfloat<K>::storeu(valid, v(offset), ray.v);
vint<K> ::storeu(valid, primID(offset), ray.primID);
vfloat<K>::storeu(valid, Ngx(offset), ray.Ng.x);
vfloat<K>::storeu(valid, Ngy(offset), ray.Ng.y);
vfloat<K>::storeu(valid, Ngz(offset), ray.Ng.z);
vint<K> ::storeu(valid, instID(offset), ray.instID);
vfloat<K>::storeu(valid, u(offset), ray.u);
vfloat<K>::storeu(valid, v(offset), ray.v);
}
}
}
@@ -571,7 +638,7 @@ namespace embree
}
char* __restrict__ ptr;
size_t K;
size_t N;
};
template<size_t MAX_K>
@@ -780,8 +847,15 @@ namespace embree
ray.time = vfloat<K>::template gather<1>(valid, &ptr->time, offset);
ray.mask = vint<K>::template gather<1>(valid, &ptr->mask, offset);
ray.instID = vint<K>::template gather<1>(valid, (int*)&ptr->instID, offset);
ray.geomID = RTC_INVALID_GEOMETRY_ID;
#else
ray.org = zero;
ray.dir = zero;
ray.tnear = zero;
ray.tfar = zero;
ray.time = zero;
ray.mask = zero;
ray.instID = zero;
for (size_t k = 0; k < K; k++)
{
if (likely(valid[k]))
@@ -799,11 +873,12 @@ namespace embree
ray.time[k] = ray_k->time;
ray.mask[k] = ray_k->mask;
ray.instID[k] = ray_k->instID;
ray.geomID[k] = RTC_INVALID_GEOMETRY_ID;
}
}
#endif
ray.geomID = RTC_INVALID_GEOMETRY_ID;
return ray;
}
@@ -1014,6 +1089,14 @@ namespace embree
RayK<K> ray;
ray.org = zero;
ray.dir = zero;
ray.tnear = zero;
ray.tfar = zero;
ray.time = zero;
ray.mask = zero;
ray.instID = zero;
for (size_t k = 0; k < K; k++)
{
if (likely(valid[k]))
@@ -1031,10 +1114,11 @@ namespace embree
ray.time[k] = ray_k->time;
ray.mask[k] = ray_k->mask;
ray.instID[k] = ray_k->instID;
ray.geomID[k] = RTC_INVALID_GEOMETRY_ID;
}
}
ray.geomID = RTC_INVALID_GEOMETRY_ID;
return ray;
}
+22 -22
View File
@@ -346,7 +346,7 @@ namespace embree
#endif
STAT3(normal.travs,1,1,1);
IntersectContext context(scene,nullptr);
scene->intersect(ray,&context);
scene->intersectors.intersect(ray,&context);
#if defined(DEBUG)
((Ray&)ray).verifyHit();
#endif
@@ -365,7 +365,7 @@ namespace embree
#endif
STAT3(normal.travs,1,1,1);
IntersectContext context(scene,user_context);
scene->intersect(ray,&context);
scene->intersectors.intersect(ray,&context);
#if defined(DEBUG)
((Ray&)ray).verifyHit();
#endif
@@ -388,7 +388,7 @@ namespace embree
STAT(size_t cnt=0; for (size_t i=0; i<4; i++) cnt += ((int*)valid)[i] == -1;);
STAT3(normal.travs,cnt,cnt,cnt);
IntersectContext context(scene,nullptr);
scene->intersect4(valid,ray,&context);
scene->intersectors.intersect4(valid,ray,&context);
#else
throw_RTCError(RTC_INVALID_OPERATION,"rtcIntersect4 not supported");
#endif
@@ -411,7 +411,7 @@ namespace embree
STAT(size_t cnt=0; for (size_t i=0; i<4; i++) cnt += ((int*)valid)[i] == -1;);
STAT3(normal.travs,cnt,cnt,cnt);
IntersectContext context(scene,user_context);
scene->intersect4(valid,ray,&context);
scene->intersectors.intersect4(valid,ray,&context);
#else
throw_RTCError(RTC_INVALID_OPERATION,"rtcIntersect4Ex not supported");
#endif
@@ -434,7 +434,7 @@ namespace embree
STAT(size_t cnt=0; for (size_t i=0; i<8; i++) cnt += ((int*)valid)[i] == -1;);
STAT3(normal.travs,cnt,cnt,cnt);
IntersectContext context(scene,nullptr);
scene->intersect8(valid,ray,&context);
scene->intersectors.intersect8(valid,ray,&context);
#else
throw_RTCError(RTC_INVALID_OPERATION,"rtcIntersect8 not supported");
#endif
@@ -458,7 +458,7 @@ namespace embree
STAT3(normal.travs,cnt,cnt,cnt);
IntersectContext context(scene,user_context);
scene->intersect8(valid,ray,&context);
scene->intersectors.intersect8(valid,ray,&context);
#else
throw_RTCError(RTC_INVALID_OPERATION,"rtcIntersect8Ex not supported");
#endif
@@ -482,7 +482,7 @@ namespace embree
STAT3(normal.travs,cnt,cnt,cnt);
IntersectContext context(scene,nullptr);
scene->intersect16(valid,ray,&context);
scene->intersectors.intersect16(valid,ray,&context);
#else
throw_RTCError(RTC_INVALID_OPERATION,"rtcIntersect16 not supported");
#endif
@@ -506,7 +506,7 @@ namespace embree
STAT3(normal.travs,cnt,cnt,cnt);
IntersectContext context(scene,user_context);
scene->intersect16(valid,ray,&context);
scene->intersectors.intersect16(valid,ray,&context);
#else
throw_RTCError(RTC_INVALID_OPERATION,"rtcIntersect16Ex not supported");
#endif
@@ -531,7 +531,7 @@ namespace embree
/* fast codepath for single rays */
if (likely(M == 1)) {
if (likely(rays->tnear <= rays->tfar))
scene->intersect(*rays,&context);
scene->intersectors.intersect(*rays,&context);
}
/* codepath for streams */
@@ -562,7 +562,7 @@ namespace embree
/* fast codepath for single rays */
if (likely(M == 1)) {
if (likely(rays[0]->tnear <= rays[0]->tfar))
scene->intersect(*rays[0],&context);
scene->intersectors.intersect(*rays[0],&context);
}
/* codepath for streams */
@@ -596,7 +596,7 @@ namespace embree
/* fast code path for streams of size 1 */
if (likely(M == 1)) {
if (likely(((RTCRay*)rays)->tnear <= ((RTCRay*)rays)->tfar))
scene->intersect(*(RTCRay*)rays,&context);
scene->intersectors.intersect(*(RTCRay*)rays,&context);
}
/* normal codepath for single ray streams */
else {
@@ -663,7 +663,7 @@ namespace embree
if (((size_t)&ray) & 0x0F ) throw_RTCError(RTC_INVALID_ARGUMENT, "ray not aligned to 16 bytes");
#endif
IntersectContext context(scene,nullptr);
scene->occluded(ray,&context);
scene->intersectors.occluded(ray,&context);
RTCORE_CATCH_END2(scene);
}
@@ -679,7 +679,7 @@ namespace embree
if (((size_t)&ray) & 0x0F ) throw_RTCError(RTC_INVALID_ARGUMENT, "ray not aligned to 16 bytes");
#endif
IntersectContext context(scene,user_context);
scene->occluded(ray,&context);
scene->intersectors.occluded(ray,&context);
RTCORE_CATCH_END2(scene);
}
@@ -699,7 +699,7 @@ namespace embree
STAT(size_t cnt=0; for (size_t i=0; i<4; i++) cnt += ((int*)valid)[i] == -1;);
STAT3(shadow.travs,cnt,cnt,cnt);
IntersectContext context(scene,nullptr);
scene->occluded4(valid,ray,&context);
scene->intersectors.occluded4(valid,ray,&context);
#else
throw_RTCError(RTC_INVALID_OPERATION,"rtcOccluded4 not supported");
#endif
@@ -722,7 +722,7 @@ namespace embree
STAT(size_t cnt=0; for (size_t i=0; i<4; i++) cnt += ((int*)valid)[i] == -1;);
STAT3(shadow.travs,cnt,cnt,cnt);
IntersectContext context(scene,user_context);
scene->occluded4(valid,ray,&context);
scene->intersectors.occluded4(valid,ray,&context);
#else
throw_RTCError(RTC_INVALID_OPERATION,"rtcOccluded4Ex not supported");
#endif
@@ -745,7 +745,7 @@ namespace embree
STAT(size_t cnt=0; for (size_t i=0; i<8; i++) cnt += ((int*)valid)[i] == -1;);
STAT3(shadow.travs,cnt,cnt,cnt);
IntersectContext context(scene,nullptr);
scene->occluded8(valid,ray,&context);
scene->intersectors.occluded8(valid,ray,&context);
#else
throw_RTCError(RTC_INVALID_OPERATION,"rtcOccluded8 not supported");
#endif
@@ -769,7 +769,7 @@ namespace embree
STAT3(shadow.travs,cnt,cnt,cnt);
IntersectContext context(scene,user_context);
scene->occluded8(valid,ray,&context);
scene->intersectors.occluded8(valid,ray,&context);
#else
throw_RTCError(RTC_INVALID_OPERATION,"rtcOccluded8Ex not supported");
#endif
@@ -793,7 +793,7 @@ namespace embree
STAT3(shadow.travs,cnt,cnt,cnt);
IntersectContext context(scene,nullptr);
scene->occluded16(valid,ray,&context);
scene->intersectors.occluded16(valid,ray,&context);
#else
throw_RTCError(RTC_INVALID_OPERATION,"rtcOccluded16 not supported");
#endif
@@ -817,7 +817,7 @@ namespace embree
STAT3(shadow.travs,cnt,cnt,cnt);
IntersectContext context(scene,user_context);
scene->occluded16(valid,ray,&context);
scene->intersectors.occluded16(valid,ray,&context);
#else
throw_RTCError(RTC_INVALID_OPERATION,"rtcOccluded16Ex not supported");
#endif
@@ -842,7 +842,7 @@ namespace embree
/* fast codepath for streams of size 1 */
if (likely(M == 1)) {
if (likely(rays->tnear <= rays->tfar))
scene->occluded (*rays,&context);
scene->intersectors.occluded (*rays,&context);
}
/* codepath for normal streams */
else {
@@ -872,7 +872,7 @@ namespace embree
/* fast codepath for streams of size 1 */
if (likely(M == 1)) {
if (likely(rays[0]->tnear <= rays[0]->tfar))
scene->occluded (*rays[0],&context);
scene->intersectors.occluded (*rays[0],&context);
}
/* codepath for normal streams */
else {
@@ -906,7 +906,7 @@ namespace embree
/* fast path for streams of size 1 */
if (likely(M == 1)) {
if (likely(((RTCRay*)rays)->tnear <= ((RTCRay*)rays)->tfar))
scene->occluded (*(RTCRay*)rays,&context);
scene->intersectors.occluded (*(RTCRay*)rays,&context);
}
/* codepath for normal ray streams */
else {
+2 -2
View File
@@ -161,8 +161,8 @@ namespace embree
rtcIntersectNp(scene,context,rays,N);
}
extern "C" void ispcOccluded1 (RTCScene scene, RTCRay& ray) {
rtcOccluded(scene,ray);
extern "C" void ispcOccluded1 (RTCScene scene, const RTCIntersectContext* context, RTCRay& ray) {
rtcOccluded1Ex(scene,context,ray);
}
extern "C" void ispcOccluded4 (const void* valid, RTCScene scene, const RTCIntersectContext* context, RTCRay4& ray) {
+3 -3
View File
@@ -130,7 +130,7 @@ extern "C" void ispcDeleteGeometry (RTCScene scene, uniform unsigned int geomID)
extern "C" void ispcSetBoundsFunction (RTCScene scene, uniform unsigned int geomID, void* uniform bounds);
extern "C" void ispcSetBoundsFunction2 (RTCScene scene, uniform unsigned int geomID, void* uniform bounds, void* uniform userPtr);
extern "C" void ispcSetBoundsFunction3 (RTCScene scene, uniform unsigned int geomID, void* uniform bounds, void* uniform userPtr);
extern "C" void ispcSetTessellationRate (RTCScene hscene, uniform unsigned geomID, uniform float tessellationRate);
extern "C" void ispcSetTessellationRate (RTCScene hscene, uniform unsigned int geomID, uniform float tessellationRate);
extern "C" void ispcSetUserData (RTCScene scene, uniform unsigned int geomID, void* uniform ptr);
extern "C" void* uniform ispcGetUserData (RTCScene scene, uniform unsigned int geomID);
@@ -540,7 +540,7 @@ void rtcSetSubdivisionMode(RTCScene scene, uniform unsigned int geomID, uniform
ispcSetSubdivisionMode(scene,geomID,topologyID,mode);
}
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) {
ispcSetIndexBuffer(scene,geomID,vertexBuffer,indexBuffer);
}
@@ -580,7 +580,7 @@ void rtcDeleteGeometry (RTCScene scene, uniform unsigned int geomID) {
ispcDeleteGeometry(scene,geomID);
}
void rtcSetTessellationRate (RTCScene hscene, uniform unsigned geomID, uniform float tessellationRate) {
void rtcSetTessellationRate (RTCScene hscene, uniform unsigned int geomID, uniform float tessellationRate) {
ispcSetTessellationRate(hscene,geomID,tessellationRate);
}
+26 -26
View File
@@ -108,7 +108,7 @@ namespace embree
int ty = __bsf(get(i)->type);
assert(ty<Geometry::NUM_TYPES);
int timesegments = get(i)->numTimeSegments();
assert(timesegments < max_time_steps);
assert((unsigned int)timesegments < max_time_steps);
statistics[ty][timesegments] += get(i)->size();
}
@@ -152,7 +152,7 @@ namespace embree
int mode = 2*(int)isCompact() + 1*(int)isRobust();
switch (mode) {
case /*0b00*/ 0:
#if defined (EMBREE_TARGET_AVX)
#if defined (EMBREE_TARGET_SIMD8)
if (device->hasISA(AVX))
{
if (isHighQuality())
@@ -171,7 +171,7 @@ namespace embree
break;
case /*0b01*/ 1:
#if defined (EMBREE_TARGET_AVX)
#if defined (EMBREE_TARGET_SIMD8)
if (device->hasISA(AVX))
accels.add(device->bvh8_factory->BVH8Triangle4v(this,BVHFactory::BuildVariant::STATIC,BVHFactory::IntersectVariant::ROBUST));
else
@@ -185,7 +185,7 @@ namespace embree
}
else /* dynamic */
{
#if defined (EMBREE_TARGET_AVX)
#if defined (EMBREE_TARGET_SIMD8)
if (device->hasISA(AVX))
{
int mode = 2*(int)isCompact() + 1*(int)isRobust();
@@ -214,7 +214,7 @@ namespace embree
else if (device->tri_accel == "bvh4.triangle4i") accels.add(device->bvh4_factory->BVH4Triangle4i(this));
else if (device->tri_accel == "qbvh4.triangle4i") accels.add(device->bvh4_factory->BVH4QuantizedTriangle4i(this));
#if defined (EMBREE_TARGET_AVX)
#if defined (EMBREE_TARGET_SIMD8)
else if (device->tri_accel == "bvh8.triangle4") accels.add(device->bvh8_factory->BVH8Triangle4 (this));
else if (device->tri_accel == "bvh8.triangle4v") accels.add(device->bvh8_factory->BVH8Triangle4v(this));
else if (device->tri_accel == "bvh8.triangle4i") accels.add(device->bvh8_factory->BVH8Triangle4i(this));
@@ -232,7 +232,7 @@ namespace embree
{
int mode = 2*(int)isCompact() + 1*(int)isRobust();
#if defined (EMBREE_TARGET_AVX)
#if defined (EMBREE_TARGET_SIMD8)
if (device->hasISA(AVX2)) // BVH8 reduces performance on AVX only-machines
{
switch (mode) {
@@ -255,7 +255,7 @@ namespace embree
}
else if (device->tri_accel_mb == "bvh4.triangle4imb") accels.add(device->bvh4_factory->BVH4Triangle4iMB(this));
else if (device->tri_accel_mb == "bvh4.triangle4vmb") accels.add(device->bvh4_factory->BVH4Triangle4vMB(this));
#if defined (EMBREE_TARGET_AVX)
#if defined (EMBREE_TARGET_SIMD8)
else if (device->tri_accel_mb == "bvh8.triangle4imb") accels.add(device->bvh8_factory->BVH8Triangle4iMB(this));
else if (device->tri_accel_mb == "bvh8.triangle4vmb") accels.add(device->bvh8_factory->BVH8Triangle4vMB(this));
#endif
@@ -274,7 +274,7 @@ namespace embree
int mode = 2*(int)isCompact() + 1*(int)isRobust();
switch (mode) {
case /*0b00*/ 0:
#if defined (EMBREE_TARGET_AVX)
#if defined (EMBREE_TARGET_SIMD8)
if (device->hasISA(AVX))
{
if (isHighQuality())
@@ -293,7 +293,7 @@ namespace embree
break;
case /*0b01*/ 1:
#if defined (EMBREE_TARGET_AVX)
#if defined (EMBREE_TARGET_SIMD8)
if (device->hasISA(AVX))
accels.add(device->bvh8_factory->BVH8Quad4v(this,BVHFactory::BuildVariant::STATIC,BVHFactory::IntersectVariant::ROBUST));
else
@@ -307,7 +307,7 @@ namespace embree
}
else /* dynamic */
{
#if defined (EMBREE_TARGET_AVX)
#if defined (EMBREE_TARGET_SIMD8)
if (device->hasISA(AVX))
{
int mode = 2*(int)isCompact() + 1*(int)isRobust();
@@ -335,7 +335,7 @@ namespace embree
else if (device->quad_accel == "bvh4.quad4i") accels.add(device->bvh4_factory->BVH4Quad4i(this));
else if (device->quad_accel == "qbvh4.quad4i") accels.add(device->bvh4_factory->BVH4QuantizedQuad4i(this));
#if defined (EMBREE_TARGET_AVX)
#if defined (EMBREE_TARGET_SIMD8)
else if (device->quad_accel == "bvh8.quad4v") accels.add(device->bvh8_factory->BVH8Quad4v(this));
else if (device->quad_accel == "bvh8.quad4i") accels.add(device->bvh8_factory->BVH8Quad4i(this));
else if (device->quad_accel == "qbvh8.quad4i") accels.add(device->bvh8_factory->BVH8QuantizedQuad4i(this));
@@ -352,7 +352,7 @@ namespace embree
int mode = 2*(int)isCompact() + 1*(int)isRobust();
switch (mode) {
case /*0b00*/ 0:
#if defined (EMBREE_TARGET_AVX)
#if defined (EMBREE_TARGET_SIMD8)
if (device->hasISA(AVX))
accels.add(device->bvh8_factory->BVH8Quad4iMB(this,BVHFactory::BuildVariant::STATIC,BVHFactory::IntersectVariant::FAST));
else
@@ -361,7 +361,7 @@ namespace embree
break;
case /*0b01*/ 1:
#if defined (EMBREE_TARGET_AVX)
#if defined (EMBREE_TARGET_SIMD8)
if (device->hasISA(AVX))
accels.add(device->bvh8_factory->BVH8Quad4iMB(this,BVHFactory::BuildVariant::STATIC,BVHFactory::IntersectVariant::ROBUST));
else
@@ -374,7 +374,7 @@ namespace embree
}
}
else if (device->quad_accel_mb == "bvh4.quad4imb") accels.add(device->bvh4_factory->BVH4Quad4iMB(this));
#if defined (EMBREE_TARGET_AVX)
#if defined (EMBREE_TARGET_SIMD8)
else if (device->quad_accel_mb == "bvh8.quad4imb") accels.add(device->bvh8_factory->BVH8Quad4iMB(this));
#endif
else throw_RTCError(RTC_INVALID_ARGUMENT,"unknown quad motion blur acceleration structure "+device->quad_accel_mb);
@@ -389,7 +389,7 @@ namespace embree
int mode = 2*(int)isCompact() + 1*(int)isRobust();
if (isStatic())
{
#if defined (EMBREE_TARGET_AVX)
#if defined (EMBREE_TARGET_SIMD8)
if (device->hasISA(AVX2)) // only enable on HSW machines, for SNB this codepath is slower
{
switch (mode) {
@@ -424,7 +424,7 @@ namespace embree
else if (device->hair_accel == "bvh4.bezier1i" ) accels.add(device->bvh4_factory->BVH4Bezier1i(this));
else if (device->hair_accel == "bvh4obb.bezier1v" ) accels.add(device->bvh4_factory->BVH4OBBBezier1v(this));
else if (device->hair_accel == "bvh4obb.bezier1i" ) accels.add(device->bvh4_factory->BVH4OBBBezier1i(this));
#if defined (EMBREE_TARGET_AVX)
#if defined (EMBREE_TARGET_SIMD8)
else if (device->hair_accel == "bvh8obb.bezier1v" ) accels.add(device->bvh8_factory->BVH8OBBBezier1v(this));
else if (device->hair_accel == "bvh8obb.bezier1i" ) accels.add(device->bvh8_factory->BVH8OBBBezier1i(this));
#endif
@@ -437,7 +437,7 @@ namespace embree
#if defined(EMBREE_GEOMETRY_HAIR)
if (device->hair_accel_mb == "default")
{
#if defined (EMBREE_TARGET_AVX)
#if defined (EMBREE_TARGET_SIMD8)
if (device->hasISA(AVX2) && !isCompact()) // only enable on HSW machines, on SNB this codepath is slower
{
accels.add(device->bvh8_factory->BVH8OBBBezier1iMB(this));
@@ -449,7 +449,7 @@ namespace embree
}
}
else if (device->hair_accel_mb == "bvh4.bezier1imb") accels.add(device->bvh4_factory->BVH4OBBBezier1iMB(this));
#if defined (EMBREE_TARGET_AVX)
#if defined (EMBREE_TARGET_SIMD8)
else if (device->hair_accel_mb == "bvh8.bezier1imb") accels.add(device->bvh8_factory->BVH8OBBBezier1iMB(this));
#endif
else throw_RTCError(RTC_INVALID_ARGUMENT,"unknown motion blur hair acceleration structure "+device->hair_accel_mb);
@@ -463,7 +463,7 @@ namespace embree
{
if (isStatic())
{
#if defined (EMBREE_TARGET_AVX)
#if defined (EMBREE_TARGET_SIMD8)
if (device->hasISA(AVX) && !isCompact())
accels.add(device->bvh8_factory->BVH8Line4i(this));
else
@@ -476,7 +476,7 @@ namespace embree
}
}
else if (device->line_accel == "bvh4.line4i") accels.add(device->bvh4_factory->BVH4Line4i(this));
#if defined (EMBREE_TARGET_AVX)
#if defined (EMBREE_TARGET_SIMD8)
else if (device->line_accel == "bvh8.line4i") accels.add(device->bvh8_factory->BVH8Line4i(this));
#endif
else throw_RTCError(RTC_INVALID_ARGUMENT,"unknown line segment acceleration structure "+device->line_accel);
@@ -488,7 +488,7 @@ namespace embree
#if defined(EMBREE_GEOMETRY_LINES)
if (device->line_accel_mb == "default")
{
#if defined (EMBREE_TARGET_AVX)
#if defined (EMBREE_TARGET_SIMD8)
if (device->hasISA(AVX) && !isCompact())
accels.add(device->bvh8_factory->BVH8Line4iMB(this));
else
@@ -496,7 +496,7 @@ namespace embree
accels.add(device->bvh4_factory->BVH4Line4iMB(this));
}
else if (device->line_accel_mb == "bvh4.line4imb") accels.add(device->bvh4_factory->BVH4Line4iMB(this));
#if defined (EMBREE_TARGET_AVX)
#if defined (EMBREE_TARGET_SIMD8)
else if (device->line_accel_mb == "bvh8.line4imb") accels.add(device->bvh8_factory->BVH8Line4iMB(this));
#endif
else throw_RTCError(RTC_INVALID_ARGUMENT,"unknown motion blur line segment acceleration structure "+device->line_accel_mb);
@@ -542,7 +542,7 @@ namespace embree
#if defined(EMBREE_GEOMETRY_USER)
if (device->object_accel == "default")
{
#if defined (EMBREE_TARGET_AVX)
#if defined (EMBREE_TARGET_SIMD8)
if (device->hasISA(AVX) && !isCompact())
{
//if (isStatic()) {
@@ -562,7 +562,7 @@ namespace embree
}
}
else if (device->object_accel == "bvh4.object") accels.add(device->bvh4_factory->BVH4UserGeometry(this));
#if defined (EMBREE_TARGET_AVX)
#if defined (EMBREE_TARGET_SIMD8)
else if (device->object_accel == "bvh8.object") accels.add(device->bvh8_factory->BVH8UserGeometry(this));
#endif
else throw_RTCError(RTC_INVALID_ARGUMENT,"unknown user geometry accel "+device->object_accel);
@@ -573,7 +573,7 @@ namespace embree
{
#if defined(EMBREE_GEOMETRY_USER)
if (device->object_accel_mb == "default" ) {
#if defined (EMBREE_TARGET_AVX)
#if defined (EMBREE_TARGET_SIMD8)
if (device->hasISA(AVX) && !isCompact())
accels.add(device->bvh8_factory->BVH8UserGeometryMB(this));
else
@@ -581,7 +581,7 @@ namespace embree
accels.add(device->bvh4_factory->BVH4UserGeometryMB(this));
}
else if (device->object_accel_mb == "bvh4.object") accels.add(device->bvh4_factory->BVH4UserGeometryMB(this));
#if defined (EMBREE_TARGET_AVX)
#if defined (EMBREE_TARGET_SIMD8)
else if (device->object_accel_mb == "bvh8.object") accels.add(device->bvh8_factory->BVH8UserGeometryMB(this));
#endif
else throw_RTCError(RTC_INVALID_ARGUMENT,"unknown user geometry mblur accel "+device->object_accel_mb);
+1 -1
View File
@@ -185,7 +185,7 @@ namespace embree
{
const size_t ofs = i*sizeof(float);
const size_t segment = segments[primID];
const vboolx valid = vintx((int)i)+vintx(step) < vintx(numFloats);
const vboolx valid = vintx((int)i)+vintx(step) < vintx(int(numFloats));
const vfloatx p0 = vfloatx::loadu(valid,(float*)&src[(segment+0)*stride+ofs]);
const vfloatx p1 = vfloatx::loadu(valid,(float*)&src[(segment+1)*stride+ofs]);
if (P ) vfloatx::storeu(valid,P+i,lerp(p0,p1,u));
+1 -1
View File
@@ -200,7 +200,7 @@ namespace embree
for (size_t i=0; i<numFloats; i+=VSIZEX)
{
const vboolx valid = vintx((int)i)+vintx(step) < vintx(numFloats);
const vboolx valid = vintx((int)i)+vintx(step) < vintx(int(numFloats));
const size_t ofs = i*sizeof(float);
const Quad& tri = quad(primID);
const vfloatx p0 = vfloatx::loadu(valid,(float*)&src[tri.v[0]*stride+ofs]);
+1 -1
View File
@@ -873,7 +873,7 @@ namespace embree
for (size_t i=0; i<numUVs; i+=4)
{
vbool4 valid1 = vint4(i)+vint4(step) < vint4(numUVs);
vbool4 valid1 = vint4(int(i))+vint4(step) < vint4(int(numUVs));
if (valid) valid1 &= vint4::loadu(&valid[i]) == vint4(-1);
if (none(valid1)) continue;
+1 -1
View File
@@ -207,7 +207,7 @@ namespace embree
size_t ofs = i*sizeof(float);
const float w = 1.0f-u-v;
const Triangle& tri = triangle(primID);
const vboolx valid = vintx((int)i)+vintx(step) < vintx(numFloats);
const vboolx valid = vintx((int)i)+vintx(step) < vintx(int(numFloats));
const vfloatx p0 = vfloatx::loadu(valid,(float*)&src[tri.v[0]*stride+ofs]);
const vfloatx p1 = vfloatx::loadu(valid,(float*)&src[tri.v[1]*stride+ofs]);
const vfloatx p2 = vfloatx::loadu(valid,(float*)&src[tri.v[2]*stride+ofs]);
+7 -11
View File
@@ -26,7 +26,6 @@ namespace embree
struct Type : public PrimitiveType {
Type ();
size_t size(const char* This) const;
bool last(const char* This) const;
};
static Type type;
@@ -44,20 +43,17 @@ namespace embree
__forceinline Bezier1i () {}
/*! Construction from vertices and IDs. */
__forceinline Bezier1i (const unsigned vertexID, const unsigned geomID, const unsigned primID, const bool last)
: vertexID(vertexID), geom(geomID | (unsigned(last) << 31)), prim(primID) {}
/*! checks if this is the last primitive */
__forceinline unsigned last() const { return geom & 0x80000000; }
__forceinline Bezier1i (const unsigned vertexID, const unsigned geomID, const unsigned primID)
: vertexID(vertexID), geom(geomID), prim(primID) {}
/*! returns geometry ID */
__forceinline unsigned geomID() const { return geom & 0x7FFFFFFF; }
__forceinline unsigned geomID() const { return geom; }
/*! returns primitive ID */
__forceinline unsigned primID() const { return prim; }
/*! fill curve from curve list */
__forceinline void fill(const PrimRef* prims, size_t& i, size_t end, Scene* scene, bool last)
__forceinline void fill(const PrimRef* prims, size_t& i, size_t end, Scene* scene)
{
const PrimRef& prim = prims[i];
i++;
@@ -65,11 +61,11 @@ namespace embree
const unsigned primID = prim.primID();
const NativeCurves* curves = scene->get<NativeCurves>(geomID);
const unsigned vertexID = curves->curve(primID);
new (this) Bezier1i(vertexID,geomID,primID,last);
new (this) Bezier1i(vertexID,geomID,primID);
}
/*! fill curve from curve list */
__forceinline LBBox3fa fillMB(const PrimRefMB* prims, size_t& i, size_t end, Scene* scene, const BBox1f time_range, bool last)
__forceinline LBBox3fa fillMB(const PrimRefMB* prims, size_t& i, size_t end, Scene* scene, const BBox1f time_range)
{
const PrimRefMB& prim = prims[i];
i++;
@@ -77,7 +73,7 @@ namespace embree
const unsigned primID = prim.primID();
const NativeCurves* curves = scene->get<NativeCurves>(geomID);
const unsigned vertexID = curves->curve(primID);
new (this) Bezier1i(vertexID,geomID,primID,last);
new (this) Bezier1i(vertexID,geomID,primID);
return curves->linearBounds(primID,time_range);
}
+5 -11
View File
@@ -28,7 +28,6 @@ namespace embree
{
Type ();
size_t size(const char* This) const;
bool last(const char* This) const;
};
static Type type;
@@ -46,13 +45,8 @@ namespace embree
__forceinline Bezier1v () {}
/*! Construction from vertices and IDs. */
__forceinline Bezier1v (const Vec3fa& p0, const Vec3fa& p1, const Vec3fa& p2, const Vec3fa& p3, const unsigned int geomID, const unsigned int primID, const bool last)
: p0(p0), p1(p1), p2(p2), p3(p3), geom(geomID | (unsigned(last) << 31)), prim(primID) {}
/*! checks if this is the last primitive */
__forceinline unsigned last() const {
return geom & 0x80000000;
}
__forceinline Bezier1v (const Vec3fa& p0, const Vec3fa& p1, const Vec3fa& p2, const Vec3fa& p3, const unsigned int geomID, const unsigned int primID)
: p0(p0), p1(p1), p2(p2), p3(p3), geom(geomID), prim(primID) {}
/*! return primitive ID */
__forceinline unsigned int primID() const {
@@ -61,11 +55,11 @@ namespace embree
/*! return geometry ID */
__forceinline unsigned int geomID() const {
return geom & 0x7FFFFFFF;
return geom;
}
/*! fill triangle from triangle list */
__forceinline void fill(const PrimRef* prims, size_t& i, size_t end, Scene* scene, bool last)
__forceinline void fill(const PrimRef* prims, size_t& i, size_t end, Scene* scene)
{
const PrimRef& prim = prims[i];
i++;
@@ -77,7 +71,7 @@ namespace embree
const Vec3fa& p1 = curves->vertex(id+1);
const Vec3fa& p2 = curves->vertex(id+2);
const Vec3fa& p3 = curves->vertex(id+3);
new (this) Bezier1v(p0,p1,p2,p3,geomID,primID,last);
new (this) Bezier1v(p0,p1,p2,p3,geomID,primID);
}
friend std::ostream& operator<<(std::ostream& cout, const Bezier1v& b)
+6 -6
View File
@@ -30,12 +30,12 @@ namespace embree
{
/* the generate loops need padded arrays, thus first store into these temporary arrays */
unsigned temp_size = width*height+VSIZEX;
dynamic_large_stack_array(float,local_grid_u,temp_size,64*64*sizeof(float));
dynamic_large_stack_array(float,local_grid_v,temp_size,64*64*sizeof(float));
dynamic_large_stack_array(float,local_grid_x,temp_size,64*64*sizeof(float));
dynamic_large_stack_array(float,local_grid_y,temp_size,64*64*sizeof(float));
dynamic_large_stack_array(float,local_grid_z,temp_size,64*64*sizeof(float));
dynamic_large_stack_array(int,local_grid_uv,temp_size,64*64*sizeof(int));
dynamic_large_stack_array(float,local_grid_u,temp_size,32*32*sizeof(float));
dynamic_large_stack_array(float,local_grid_v,temp_size,32*32*sizeof(float));
dynamic_large_stack_array(float,local_grid_x,temp_size,32*32*sizeof(float));
dynamic_large_stack_array(float,local_grid_y,temp_size,32*32*sizeof(float));
dynamic_large_stack_array(float,local_grid_z,temp_size,32*32*sizeof(float));
dynamic_large_stack_array(int,local_grid_uv,temp_size,32*32*sizeof(int));
/* first create the grids for each time step */
for (size_t t=0; t<time_steps; t++)
+8 -8
View File
@@ -52,7 +52,7 @@ namespace embree
ray.geomID = RTC_INVALID_GEOMETRY_ID;
ray.instID = instance->geomID;
IntersectContext context(instance->object,user_context);
instance->object->intersect((RTCRay&)ray,&context);
instance->object->intersectors.intersect((RTCRay&)ray,&context);
ray.org = ray_org;
ray.dir = ray_dir;
if (ray.geomID == RTC_INVALID_GEOMETRY_ID) {
@@ -71,7 +71,7 @@ namespace embree
ray.dir = xfmVector(world2local,ray_dir);
ray.instID = instance->geomID;
IntersectContext context(instance->object,user_context);
instance->object->occluded((RTCRay&)ray,&context);
instance->object->intersectors.occluded((RTCRay&)ray,&context);
ray.org = ray_org;
ray.dir = ray_dir;
}
@@ -82,16 +82,16 @@ namespace embree
__forceinline void occludedObject(vint<K>* valid, Scene* object, IntersectContext* context, RayK<K>& ray);
#if defined (__SSE__)
template<> __forceinline void intersectObject<4>(vint4* valid, Scene* object, IntersectContext* context, Ray4& ray) { object->intersect4(valid,(RTCRay4&)ray,context); }
template<> __forceinline void occludedObject <4>(vint4* valid, Scene* object, IntersectContext* context, Ray4& ray) { object->occluded4 (valid,(RTCRay4&)ray,context); }
template<> __forceinline void intersectObject<4>(vint4* valid, Scene* object, IntersectContext* context, Ray4& ray) { object->intersectors.intersect4(valid,(RTCRay4&)ray,context); }
template<> __forceinline void occludedObject <4>(vint4* valid, Scene* object, IntersectContext* context, Ray4& ray) { object->intersectors.occluded4 (valid,(RTCRay4&)ray,context); }
#endif
#if defined (__AVX__)
template<> __forceinline void intersectObject<8>(vint8* valid, Scene* object, IntersectContext* context, Ray8& ray) { object->intersect8(valid,(RTCRay8&)ray,context); }
template<> __forceinline void occludedObject <8>(vint8* valid, Scene* object, IntersectContext* context, Ray8& ray) { object->occluded8 (valid,(RTCRay8&)ray,context); }
template<> __forceinline void intersectObject<8>(vint8* valid, Scene* object, IntersectContext* context, Ray8& ray) { object->intersectors.intersect8(valid,(RTCRay8&)ray,context); }
template<> __forceinline void occludedObject <8>(vint8* valid, Scene* object, IntersectContext* context, Ray8& ray) { object->intersectors.occluded8 (valid,(RTCRay8&)ray,context); }
#endif
#if defined (__AVX512F__)
template<> __forceinline void intersectObject<16>(vint16* valid, Scene* object, IntersectContext* context, Ray16& ray) { object->intersect16(valid,(RTCRay16&)ray,context); }
template<> __forceinline void occludedObject <16>(vint16* valid, Scene* object, IntersectContext* context, Ray16& ray) { object->occluded16 (valid,(RTCRay16&)ray,context); }
template<> __forceinline void intersectObject<16>(vint16* valid, Scene* object, IntersectContext* context, Ray16& ray) { object->intersectors.intersect16(valid,(RTCRay16&)ray,context); }
template<> __forceinline void occludedObject <16>(vint16* valid, Scene* object, IntersectContext* context, Ray16& ray) { object->intersectors.occluded16 (valid,(RTCRay16&)ray,context); }
#endif
template<int N>
+10 -10
View File
@@ -212,7 +212,7 @@ namespace embree
if (Mx > M) valid &= (1<<M)-1;
hit.finalize();
size_t i = select_min(valid,hit.vt);
int geomID = geomIDs[i] & 0x7FFFFFFF;
int geomID = geomIDs[i];
int instID = context->geomID_to_instID ? context->geomID_to_instID[0] : geomID;
/* intersection filter test */
#if defined(EMBREE_INTERSECTION_FILTER) || defined(EMBREE_RAY_MASK)
@@ -223,7 +223,7 @@ namespace embree
if (unlikely(none(valid))) return foundhit;
i = select_min(valid,hit.vt);
geomID = geomIDs[i] & 0x7FFFFFFF;
geomID = geomIDs[i];
instID = context->geomID_to_instID ? context->geomID_to_instID[0] : geomID;
entry:
Geometry* geometry MAYBE_UNUSED = scene->get(geomID);
@@ -291,7 +291,7 @@ namespace embree
if (Mx > M) valid &= (1<<M)-1;
hit.finalize();
size_t i = select_min(valid,hit.vt);
int geomID = geomIDs[i] & 0x7FFFFFFF;
int geomID = geomIDs[i];
int instID = context->geomID_to_instID ? context->geomID_to_instID[0] : geomID;
/* intersection filter test */
@@ -303,7 +303,7 @@ namespace embree
if (unlikely(none(valid))) return foundhit;
i = select_min(valid,hit.vt);
geomID = geomIDs[i] & 0x7FFFFFFF;
geomID = geomIDs[i];
instID = context->geomID_to_instID ? context->geomID_to_instID[0] : geomID;
entry:
Geometry* geometry MAYBE_UNUSED = scene->get(geomID);
@@ -374,7 +374,7 @@ namespace embree
entry:
size_t i=__bsf(m);
const int geomID = geomIDs[i] & 0x7FFFFFFF;
const int geomID = geomIDs[i];
const int instID = context->geomID_to_instID ? context->geomID_to_instID[0] : geomID;
Geometry* geometry MAYBE_UNUSED = scene->get(geomID);
@@ -539,7 +539,7 @@ namespace embree
std::tie(u,v,t,Ng) = hit();
const int geomID = geomIDs[i] & 0x7FFFFFFF;
const int geomID = geomIDs[i];
const int primID = primIDs[i];
Geometry* geometry MAYBE_UNUSED = scene->get(geomID);
@@ -596,7 +596,7 @@ namespace embree
/* ray masking test */
Scene* scene = context->scene;
const int geomID = geomIDs[i] & 0x7FFFFFFF;
const int geomID = geomIDs[i];
const int primID = primIDs[i];
Geometry* geometry MAYBE_UNUSED = scene->get(geomID);
#if defined(EMBREE_RAY_MASK)
@@ -749,7 +749,7 @@ namespace embree
if (Mx > M) valid &= (1<<M)-1;
size_t i = select_min(valid,hit.vt);
assert(i<M);
int geomID = geomIDs[i] & 0x7FFFFFFF;
int geomID = geomIDs[i];
/* intersection filter test */
#if defined(EMBREE_INTERSECTION_FILTER) || defined(EMBREE_RAY_MASK)
@@ -760,7 +760,7 @@ namespace embree
if (unlikely(none(valid))) return foundhit;
i = select_min(valid,hit.vt);
assert(i<M);
geomID = geomIDs[i] & 0x7FFFFFFF;
geomID = geomIDs[i];
entry:
Geometry* geometry MAYBE_UNUSED = scene->get(geomID);
@@ -842,7 +842,7 @@ namespace embree
entry:
size_t i=__bsf(m);
const int geomID = geomIDs[i] & 0x7FFFFFFF;
const int geomID = geomIDs[i];
Geometry* geometry MAYBE_UNUSED = scene->get(geomID);
#if defined(EMBREE_RAY_MASK)
+19 -31
View File
@@ -29,33 +29,28 @@ namespace embree
typedef typename Intersector::Primitive Primitive;
typedef typename Intersector::Precalculations Precalculations;
static const bool validIntersectorK = false; // FIXME: why do we need this
static __forceinline void intersect(Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive* prim, size_t ty, size_t& lazy_node)
static __forceinline void intersect(Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive* prim, size_t num, size_t& lazy_node)
{
for (size_t i=0;; i++) {
for (size_t i=0; i<num; i++)
Intersector::intersect(pre,ray,context,prim[i]);
if (prim[i].last()) break;
}
}
static __forceinline bool occluded(Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive* prim, size_t ty, size_t& lazy_node)
static __forceinline bool occluded(Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive* prim, size_t num, size_t& lazy_node)
{
for (size_t i=0;; i++) {
for (size_t i=0; i<num; i++) {
if (Intersector::occluded(pre,ray,context,prim[i]))
return true;
if (prim[i].last()) break;
}
return false;
}
template<int K>
static __forceinline void intersectK(const vbool<K>& valid, /* PrecalculationsK& pre, */ RayK<K>& ray, IntersectContext* context, const Primitive* prim, size_t ty, size_t& lazy_node)
static __forceinline void intersectK(const vbool<K>& valid, /* PrecalculationsK& pre, */ RayK<K>& ray, IntersectContext* context, const Primitive* prim, size_t num, size_t& lazy_node)
{
}
template<int K>
static __forceinline vbool<K> occludedK(const vbool<K>& valid, /* PrecalculationsK& pre, */ RayK<K>& ray, IntersectContext* context, const Primitive* prim, size_t ty, size_t& lazy_node)
static __forceinline vbool<K> occludedK(const vbool<K>& valid, /* PrecalculationsK& pre, */ RayK<K>& ray, IntersectContext* context, const Primitive* prim, size_t num, size_t& lazy_node)
{
return valid;
}
@@ -67,39 +62,35 @@ namespace embree
typedef typename Intersector::Primitive Primitive;
typedef typename Intersector::Precalculations Precalculations;
static __forceinline void intersect(const vbool<K>& valid, Precalculations& pre, RayK<K>& ray, IntersectContext* context, const Primitive* prim, size_t ty, size_t& lazy_node)
static __forceinline void intersect(const vbool<K>& valid, Precalculations& pre, RayK<K>& ray, IntersectContext* context, const Primitive* prim, size_t num, size_t& lazy_node)
{
for (size_t i=0;; i++) {
for (size_t i=0; i<num; i++) {
Intersector::intersect(valid,pre,ray,context,prim[i]);
if (prim[i].last()) break;
}
}
static __forceinline vbool<K> occluded(const vbool<K>& valid, Precalculations& pre, RayK<K>& ray, IntersectContext* context, const Primitive* prim, size_t ty, size_t& lazy_node)
static __forceinline vbool<K> occluded(const vbool<K>& valid, Precalculations& pre, RayK<K>& ray, IntersectContext* context, const Primitive* prim, size_t num, size_t& lazy_node)
{
vbool<K> valid0 = valid;
for (size_t i=0;; i++) {
for (size_t i=0; i<num; i++) {
valid0 &= !Intersector::occluded(valid0,pre,ray,context,prim[i]);
if (none(valid0)) break;
if (prim[i].last()) break;
}
return !valid0;
}
static __forceinline void intersect(Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const Primitive* prim, size_t ty, size_t& lazy_node)
static __forceinline void intersect(Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const Primitive* prim, size_t num, size_t& lazy_node)
{
for (size_t i=0;; i++) {
for (size_t i=0; i<num; i++) {
Intersector::intersect(pre,ray,k,context,prim[i]);
if (prim[i].last()) break;
}
}
static __forceinline bool occluded(Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const Primitive* prim, size_t ty, size_t& lazy_node)
static __forceinline bool occluded(Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const Primitive* prim, size_t num, size_t& lazy_node)
{
for (size_t i=0;; i++) {
for (size_t i=0; i<num; i++) {
if (Intersector::occluded(pre,ray,k,context,prim[i]))
return true;
if (prim[i].last()) break;
}
return false;
}
@@ -112,30 +103,27 @@ namespace embree
{
typedef typename IntersectorK::Primitive PrimitiveK;
typedef typename IntersectorK::Precalculations PrecalculationsK;
static const bool validIntersectorK = true;
static __forceinline void intersectK(const vbool<K>& valid, /* PrecalculationsK& pre, */ RayK<K>& ray, IntersectContext* context, const PrimitiveK* prim, size_t ty, size_t& lazy_node)
static __forceinline void intersectK(const vbool<K>& valid, /* PrecalculationsK& pre, */ RayK<K>& ray, IntersectContext* context, const PrimitiveK* prim, size_t num, size_t& lazy_node)
{
PrecalculationsK pre(valid,ray); // FIXME: might cause trouble
for (size_t i=0; ; i++) {
for (size_t i=0; i<num; i++) {
IntersectorK::intersect(valid,pre,ray,context,prim[i]);
if (prim[i].last()) break;
}
}
static __forceinline vbool<K> occludedK(const vbool<K>& valid, /* PrecalculationsK& pre, */ RayK<K>& ray, IntersectContext* context, const PrimitiveK* prim, size_t ty, size_t& lazy_node)
static __forceinline vbool<K> occludedK(const vbool<K>& valid, /* PrecalculationsK& pre, */ RayK<K>& ray, IntersectContext* context, const PrimitiveK* prim, size_t num, size_t& lazy_node)
{
PrecalculationsK pre(valid,ray); // FIXME: might cause trouble
vbool<K> valid0 = valid;
for (size_t i=0; ; i++) {
for (size_t i=0; i<num; i++) {
valid0 &= !IntersectorK::occluded(valid0,pre,ray,context,prim[i]);
if (none(valid0)) break;
if (prim[i].last()) break;
}
return !valid0;
}
};
}
}
+18 -28
View File
@@ -28,7 +28,6 @@ namespace embree
{
Type();
size_t size(const char* This) const;
bool last(const char* This) const;
};
static Type type;
@@ -49,11 +48,8 @@ namespace embree
__forceinline LineMi() { }
/* Construction from vertices and IDs */
__forceinline LineMi(const vint<M>& v0, const vint<M>& geomIDs, const vint<M>& primIDs, const bool last)
: v0(v0), geomIDs(geomIDs), primIDs(primIDs)
{
this->geomIDs[0] |= unsigned(last) << 31;
}
__forceinline LineMi(const vint<M>& v0, const vint<M>& geomIDs, const vint<M>& primIDs)
: v0(v0), geomIDs(geomIDs), primIDs(primIDs) {}
/* Returns a mask that tells which line segments are valid */
__forceinline vbool<M> valid() const { return primIDs != vint<M>(-1); }
@@ -68,16 +64,10 @@ namespace embree
/* Returns the number of stored line segments */
__forceinline size_t size() const { return __bsf(~movemask(valid())); }
/*! checks if this is the last primitive */
__forceinline unsigned last() const { return geomIDs[0] & 0x80000000; }
/* Returns the geometry IDs */
__forceinline vint<M>& geomID() { return geomIDs; }
__forceinline const vint<M>& geomID() const { return geomIDs; }
__forceinline int geomID(const size_t i) const {
assert(i<M);
return geomIDs[i] & 0x7FFFFFFF;
}
__forceinline int geomID(const size_t i) const { assert(i<M); return geomIDs[i]; }
/* Returns the primitive IDs */
__forceinline vint<M>& primID() { return primIDs; }
@@ -146,7 +136,7 @@ namespace embree
/* Fill line segment from line segment list */
template<typename PrimRefT>
__forceinline void fill(const PrimRefT* prims, size_t& begin, size_t end, Scene* scene, bool last)
__forceinline void fill(const PrimRefT* prims, size_t& begin, size_t end, Scene* scene)
{
vint<M> geomID, primID;
vint<M> v0;
@@ -171,18 +161,18 @@ namespace embree
if (begin<end) prim = &prims[begin];
}
new (this) LineMi(v0,geomID,primID,last); // FIXME: use non temporal store
new (this) LineMi(v0,geomID,primID); // FIXME: use non temporal store
}
__forceinline LBBox3fa fillMB(const PrimRef* prims, size_t& begin, size_t end, Scene* scene, size_t itime, bool last)
__forceinline LBBox3fa fillMB(const PrimRef* prims, size_t& begin, size_t end, Scene* scene, size_t itime)
{
fill(prims,begin,end,scene,last);
fill(prims,begin,end,scene);
return linearBounds(scene,itime);
}
__forceinline LBBox3fa fillMB(const PrimRefMB* prims, size_t& begin, size_t end, Scene* scene, const BBox1f time_range, bool last)
__forceinline LBBox3fa fillMB(const PrimRefMB* prims, size_t& begin, size_t end, Scene* scene, const BBox1f time_range)
{
fill(prims,begin,end,scene,last);
fill(prims,begin,end,scene);
return linearBounds(scene,time_range);
}
@@ -203,7 +193,7 @@ namespace embree
/*! output operator */
friend __forceinline std::ostream& operator<<(std::ostream& cout, const LineMi& line) {
return cout << "Line" << M << "i {" << line.v0 << ", " << (line.geomIDs & 0x7FFFFFFF) << ", " << line.primIDs << "}";
return cout << "Line" << M << "i {" << line.v0 << ", " << line.geomIDs << ", " << line.primIDs << "}";
}
public:
@@ -218,10 +208,10 @@ namespace embree
Vec4vf4& p1,
const Scene* scene) const
{
const LineSegments* geom0 = scene->get<LineSegments>(geomIDs[0] & 0x7FFFFFFF);
const LineSegments* geom1 = scene->get<LineSegments>(geomIDs[1]);
const LineSegments* geom2 = scene->get<LineSegments>(geomIDs[2]);
const LineSegments* geom3 = scene->get<LineSegments>(geomIDs[3]);
const LineSegments* geom0 = scene->get<LineSegments>(geomID(0));
const LineSegments* geom1 = scene->get<LineSegments>(geomID(1));
const LineSegments* geom2 = scene->get<LineSegments>(geomID(2));
const LineSegments* geom3 = scene->get<LineSegments>(geomID(3));
const vfloat4 a0 = vfloat4::loadu(geom0->vertexPtr(v0[0]));
const vfloat4 a1 = vfloat4::loadu(geom1->vertexPtr(v0[1]));
@@ -268,10 +258,10 @@ namespace embree
const Scene* scene,
float time) const
{
const LineSegments* geom0 = scene->get<LineSegments>(geomIDs[0] & 0x7FFFFFFF);
const LineSegments* geom1 = scene->get<LineSegments>(geomIDs[1]);
const LineSegments* geom2 = scene->get<LineSegments>(geomIDs[2]);
const LineSegments* geom3 = scene->get<LineSegments>(geomIDs[3]);
const LineSegments* geom0 = scene->get<LineSegments>(geomID(0));
const LineSegments* geom1 = scene->get<LineSegments>(geomID(1));
const LineSegments* geom2 = scene->get<LineSegments>(geomID(2));
const LineSegments* geom3 = scene->get<LineSegments>(geomID(3));
const vfloat4 numTimeSegments(geom0->fnumTimeSegments, geom1->fnumTimeSegments, geom2->fnumTimeSegments, geom3->fnumTimeSegments);
vfloat4 ftime;
+9 -17
View File
@@ -26,7 +26,6 @@ namespace embree
{
Type ();
size_t size(const char* This) const;
bool last(const char* This) const;
};
static Type type;
@@ -44,49 +43,42 @@ namespace embree
public:
/*! constructs a virtual object */
Object (unsigned geomID, unsigned primID, bool last)
: _geomID(geomID | (unsigned(last) << 31)), _primID(primID) {}
Object (unsigned geomID, unsigned primID)
: _geomID(geomID), _primID(primID) {}
/*! checks if this is the last primitive */
__forceinline unsigned last() const {
return _geomID & 0x80000000;
}
/*! returns geometry ID */
__forceinline unsigned geomID() const {
return _geomID & 0x7FFFFFFF;
return _geomID;
}
/*! returns primitive ID */
__forceinline unsigned primID() const {
return _primID;
}
/*! fill triangle from triangle list */
__forceinline void fill(const PrimRef* prims, size_t& i, size_t end, Scene* scene, bool last)
__forceinline void fill(const PrimRef* prims, size_t& i, size_t end, Scene* scene)
{
const PrimRef& prim = prims[i]; i++;
new (this) Object(prim.geomID(), prim.primID(),last);
new (this) Object(prim.geomID(), prim.primID());
}
/*! fill triangle from triangle list */
__forceinline LBBox3fa fillMB(const PrimRef* prims, size_t& i, size_t end, Scene* scene, size_t itime, bool last)
__forceinline LBBox3fa fillMB(const PrimRef* prims, size_t& i, size_t end, Scene* scene, size_t itime)
{
const PrimRef& prim = prims[i]; i++;
const unsigned geomID = prim.geomID();
const unsigned primID = prim.primID();
new (this) Object(geomID, primID,last);
new (this) Object(geomID, primID);
AccelSet* accel = (AccelSet*) scene->get(geomID);
return accel->linearBounds(primID,itime);
}
/*! fill triangle from triangle list */
__forceinline LBBox3fa fillMB(const PrimRefMB* prims, size_t& i, size_t end, Scene* scene, const BBox1f time_range, bool last)
__forceinline LBBox3fa fillMB(const PrimRefMB* prims, size_t& i, size_t end, Scene* scene, const BBox1f time_range)
{
const PrimRefMB& prim = prims[i]; i++;
const unsigned geomID = prim.geomID();
const unsigned primID = prim.primID();
new (this) Object(geomID, primID,last);
new (this) Object(geomID, primID);
AccelSet* accel = (AccelSet*) scene->get(geomID);
return accel->linearBounds(primID,time_range);
}
-55
View File
@@ -38,10 +38,6 @@ namespace embree
return 1;
}
bool Bezier1v::Type::last(const char* This) const {
return ((Bezier1v*)This)->last();
}
Bezier1v::Type Bezier1v::type;
/********************** Bezier1i **************************/
@@ -53,10 +49,6 @@ namespace embree
return 1;
}
bool Bezier1i::Type::last(const char* This) const {
return ((Bezier1i*)This)->last();
}
Bezier1i::Type Bezier1i::type;
/********************** Line4i **************************/
@@ -70,11 +62,6 @@ namespace embree
return ((Line4i*)This)->size();
}
template<>
bool Line4i::Type::last(const char* This) const {
return ((Line4i*)This)->last();
}
/********************** Triangle4 **************************/
template<>
@@ -86,11 +73,6 @@ namespace embree
return ((Triangle4*)This)->size();
}
template<>
bool Triangle4::Type::last(const char* This) const {
return ((Triangle4*)This)->last();
}
/********************** Triangle4v **************************/
template<>
@@ -102,11 +84,6 @@ namespace embree
return ((Triangle4v*)This)->size();
}
template<>
bool Triangle4v::Type::last(const char* This) const {
return ((Triangle4v*)This)->last();
}
/********************** Triangle4i **************************/
template<>
@@ -118,11 +95,6 @@ namespace embree
return ((Triangle4i*)This)->size();
}
template<>
bool Triangle4i::Type::last(const char* This) const {
return ((Triangle4i*)This)->last();
}
/********************** Triangle4vMB **************************/
template<>
@@ -134,11 +106,6 @@ namespace embree
return ((Triangle4vMB*)This)->size();
}
template<>
bool Triangle4vMB::Type::last(const char* This) const {
return ((Triangle4vMB*)This)->last();
}
/********************** Quad4v **************************/
template<>
@@ -150,11 +117,6 @@ namespace embree
return ((Quad4v*)This)->size();
}
template<>
bool Quad4v::Type::last(const char* This) const {
return ((Quad4v*)This)->last();
}
/********************** Quad4i **************************/
template<>
@@ -166,11 +128,6 @@ namespace embree
return ((Quad4i*)This)->size();
}
template<>
bool Quad4i::Type::last(const char* This) const {
return ((Quad4i*)This)->last();
}
/********************** SubdivPatch1 **************************/
SubdivPatch1Cached::Type::Type ()
@@ -180,10 +137,6 @@ namespace embree
return 1;
}
bool SubdivPatch1Cached::Type::last(const char* This) const {
return true;
}
SubdivPatch1Cached::Type SubdivPatch1Cached::type;
/********************** SubdivPatch1Cached **************************/
@@ -195,10 +148,6 @@ namespace embree
return 1;
}
bool SubdivPatch1Cached::TypeCached::last(const char* This) const {
return true;
}
SubdivPatch1Cached::TypeCached SubdivPatch1Cached::type_cached;
/********************** Virtual Object **************************/
@@ -210,9 +159,5 @@ namespace embree
return 1;
}
bool Object::Type::last(const char* This) const {
return ((Object*)This)->last();
}
Object::Type Object::type;
}
-3
View File
@@ -33,9 +33,6 @@ namespace embree
/*! Returns the number of stored primitives in a block. */
virtual size_t size(const char* This) const = 0;
/*! Returns if this is the last block in the leaf list. */
virtual bool last(const char* This) const = 0;
public:
std::string name; //!< name of this primitive type
size_t bytes; //!< number of bytes of the triangle data
+22 -33
View File
@@ -30,7 +30,6 @@ namespace embree
{
Type();
size_t size(const char* This) const;
bool last(const char* This) const;
};
static Type type;
@@ -56,12 +55,8 @@ namespace embree
const vint<M>& v2,
const vint<M>& v3,
const vint<M>& geomIDs,
const vint<M>& primIDs,
const bool last)
: v0(v0),v1(v1), v2(v2), v3(v3), geomIDs(geomIDs), primIDs(primIDs)
{
this->geomIDs[0] |= unsigned(last) << 31;
}
const vint<M>& primIDs)
: v0(v0),v1(v1), v2(v2), v3(v3), geomIDs(geomIDs), primIDs(primIDs) {}
/* Returns a mask that tells which quads are valid */
__forceinline vbool<M> valid() const { return primIDs != vint<M>(-1); }
@@ -72,16 +67,10 @@ namespace embree
/* Returns the number of stored quads */
__forceinline size_t size() const { return __bsf(~movemask(valid())); }
/*! checks if this is the last primitive */
__forceinline unsigned last() const { return geomIDs[0] & 0x80000000; }
/* Returns the geometry IDs */
__forceinline vint<M>& geomID() { return geomIDs; }
__forceinline const vint<M>& geomID() const { return geomIDs; }
__forceinline int geomID(const size_t i) const {
assert(i<M);
return geomIDs[i] & 0x7FFFFFFF;
}
__forceinline int geomID(const size_t i) const { assert(i<M); assert(geomIDs[i] != -1); return geomIDs[i]; }
/* Returns the primitive IDs */
__forceinline vint<M>& primID() { return primIDs; }
@@ -234,7 +223,7 @@ namespace embree
/* Fill quad from quad list */
template<typename PrimRefT>
__forceinline void fill(const PrimRefT* prims, size_t& begin, size_t end, Scene* scene, bool last)
__forceinline void fill(const PrimRefT* prims, size_t& begin, size_t end, Scene* scene)
{
vint<M> geomID = -1, primID = -1;
vint<M> v0 = zero, v1 = zero, v2 = zero, v3 = zero;
@@ -267,23 +256,23 @@ namespace embree
if (begin<end) prim = &prims[begin];
}
new (this) QuadMi(v0,v1,v2,v3,geomID,primID,last); // FIXME: use non temporal store
new (this) QuadMi(v0,v1,v2,v3,geomID,primID); // FIXME: use non temporal store
}
__forceinline LBBox3fa fillMB(const PrimRef* prims, size_t& begin, size_t end, Scene* scene, size_t itime, bool last)
__forceinline LBBox3fa fillMB(const PrimRef* prims, size_t& begin, size_t end, Scene* scene, size_t itime)
{
fill(prims, begin, end, scene, last);
fill(prims, begin, end, scene);
return linearBounds(scene, itime);
}
__forceinline LBBox3fa fillMB(const PrimRefMB* prims, size_t& begin, size_t end, Scene* scene, const BBox1f time_range, bool last)
__forceinline LBBox3fa fillMB(const PrimRefMB* prims, size_t& begin, size_t end, Scene* scene, const BBox1f time_range)
{
fill(prims, begin, end, scene, last);
fill(prims, begin, end, scene);
return linearBounds(scene, time_range);
}
friend std::ostream& operator<<(std::ostream& cout, const QuadMi& quad) {
return cout << "QuadMi<" << M << ">( v0 = " << quad.v0 << ", v1 = " << quad.v1 << ", v2 = " << quad.v2 << ", v3 = " << quad.v3 << ", geomID = " << (quad.geomIDs & 0x7FFFFFFF) << ", primID = " << quad.primIDs << " )";
return cout << "QuadMi<" << M << ">( v0 = " << quad.v0 << ", v1 = " << quad.v1 << ", v2 = " << quad.v2 << ", v3 = " << quad.v3 << ", geomID = " << quad.geomIDs << ", primID = " << quad.primIDs << " )";
}
/* Updates the primitive */
@@ -324,10 +313,10 @@ namespace embree
{
prefetchL1(((char*)this)+0*64);
prefetchL1(((char*)this)+1*64);
const int* vertices0 = scene->vertices[geomIDs[0] & 0x7FFFFFFF];
const int* vertices1 = scene->vertices[geomIDs[1]];
const int* vertices2 = scene->vertices[geomIDs[2]];
const int* vertices3 = scene->vertices[geomIDs[3]];
const int* vertices0 = scene->vertices[geomID(0)];
const int* vertices1 = scene->vertices[geomID(1)];
const int* vertices2 = scene->vertices[geomID(2)];
const int* vertices3 = scene->vertices[geomID(3)];
const vfloat4 a0 = vfloat4::loadu(vertices0 + v0[0]);
const vfloat4 a1 = vfloat4::loadu(vertices1 + v0[1]);
const vfloat4 a2 = vfloat4::loadu(vertices2 + v0[2]);
@@ -359,10 +348,10 @@ namespace embree
const Scene *const scene) const // FIXME: why do we have this special path here and not for triangles?
{
const vint16 perm(0,4,8,12,1,5,9,13,2,6,10,14,3,7,11,15);
const int* vertices0 = scene->vertices[geomIDs[0] & 0x7FFFFFFF];
const int* vertices1 = scene->vertices[geomIDs[1]];
const int* vertices2 = scene->vertices[geomIDs[2]];
const int* vertices3 = scene->vertices[geomIDs[3]];
const int* vertices0 = scene->vertices[geomID(0)];
const int* vertices1 = scene->vertices[geomID(1)];
const int* vertices2 = scene->vertices[geomID(2)];
const int* vertices3 = scene->vertices[geomID(3)];
const vfloat4 a0 = vfloat4::loadu(vertices0 + v0[0]);
const vfloat4 a1 = vfloat4::loadu(vertices1 + v0[1]);
@@ -451,10 +440,10 @@ namespace embree
const Scene *const scene,
const float time) const
{
const QuadMesh* mesh0 = scene->get<QuadMesh>(geomIDs[0] & 0x7FFFFFFF);
const QuadMesh* mesh1 = scene->get<QuadMesh>(geomIDs[1]);
const QuadMesh* mesh2 = scene->get<QuadMesh>(geomIDs[2]);
const QuadMesh* mesh3 = scene->get<QuadMesh>(geomIDs[3]);
const QuadMesh* mesh0 = scene->get<QuadMesh>(geomID(0));
const QuadMesh* mesh1 = scene->get<QuadMesh>(geomID(1));
const QuadMesh* mesh2 = scene->get<QuadMesh>(geomID(2));
const QuadMesh* mesh3 = scene->get<QuadMesh>(geomID(3));
const vfloat4 numTimeSegments(mesh0->fnumTimeSegments, mesh1->fnumTimeSegments, mesh2->fnumTimeSegments, mesh3->fnumTimeSegments);
vfloat4 ftime;
+7 -14
View File
@@ -29,7 +29,6 @@ namespace embree
{
Type();
size_t size(const char* This) const;
bool last(const char* This) const;
};
static Type type;
@@ -47,11 +46,8 @@ namespace embree
__forceinline QuadMv() {}
/* Construction from vertices and IDs */
__forceinline QuadMv(const Vec3vf<M>& v0, const Vec3vf<M>& v1, const Vec3vf<M>& v2, const Vec3vf<M>& v3, const vint<M>& geomIDs, const vint<M>& primIDs, const bool last)
: v0(v0), v1(v1), v2(v2), v3(v3), geomIDs(geomIDs), primIDs(primIDs)
{
this->geomIDs[0] |= unsigned(last) << 31;
}
__forceinline QuadMv(const Vec3vf<M>& v0, const Vec3vf<M>& v1, const Vec3vf<M>& v2, const Vec3vf<M>& v3, const vint<M>& geomIDs, const vint<M>& primIDs)
: v0(v0), v1(v1), v2(v2), v3(v3), geomIDs(geomIDs), primIDs(primIDs) {}
/* Returns a mask that tells which quads are valid */
__forceinline vbool<M> valid() const { return geomIDs != vint<M>(-1); }
@@ -62,13 +58,10 @@ namespace embree
/* Returns the number of stored quads */
__forceinline size_t size() const { return __bsf(~movemask(valid())); }
/*! checks if this is the last primitive */
__forceinline unsigned last() const { return geomIDs[0] & 0x80000000; }
/* Returns the geometry IDs */
__forceinline vint<M>& geomID() { return geomIDs; }
__forceinline const vint<M>& geomID() const { return geomIDs; }
__forceinline int geomID(const size_t i) const { assert(i<M); return geomIDs[i] & 0x7FFFFFFF; }
__forceinline int geomID(const size_t i) const { assert(i<M); return geomIDs[i]; }
/* Returns the primitive IDs */
__forceinline vint<M> primID() { return primIDs; }
@@ -111,7 +104,7 @@ namespace embree
}
/* Fill quad from quad list */
__forceinline void fill(const PrimRef* prims, size_t& begin, size_t end, Scene* scene, bool last)
__forceinline void fill(const PrimRef* prims, size_t& begin, size_t end, Scene* scene)
{
vint<M> vgeomID = -1, vprimID = -1;
Vec3vf<M> v0 = zero, v1 = zero, v2 = zero, v3 = zero;
@@ -134,7 +127,7 @@ namespace embree
v2.x[i] = p2.x; v2.y[i] = p2.y; v2.z[i] = p2.z;
v3.x[i] = p3.x; v3.y[i] = p3.y; v3.z[i] = p3.z;
}
QuadMv::store_nt(this,QuadMv(v0,v1,v2,v3,vgeomID,vprimID,last));
QuadMv::store_nt(this,QuadMv(v0,v1,v2,v3,vgeomID,vprimID));
}
/* Updates the primitive */
@@ -147,7 +140,7 @@ namespace embree
for (size_t i=0; i<M; i++)
{
if (primID(i) == -1) break;
const unsigned geomId = geomIDs[i]; // copies last bit
const unsigned geomId = geomID(i);
const unsigned primId = primID(i);
const QuadMesh::Quad& quad = mesh->quad(primId);
const Vec3fa p0 = mesh->vertex(quad.v[0]);
@@ -162,7 +155,7 @@ namespace embree
v2.x[i] = p2.x; v2.y[i] = p2.y; v2.z[i] = p2.z;
v3.x[i] = p3.x; v3.y[i] = p3.y; v3.z[i] = p3.z;
}
QuadMv::store_nt(this,QuadMv(v0,v1,v2,v3,vgeomID,vprimID,false));
new (this) QuadMv(v0,v1,v2,v3,vgeomID,vprimID);
return bounds;
}
-2
View File
@@ -28,7 +28,6 @@ namespace embree
{
Type ();
size_t size(const char* This) const;
bool last(const char* This) const;
};
static Type type;
@@ -37,7 +36,6 @@ namespace embree
{
TypeCached ();
size_t size(const char* This) const;
bool last(const char* This) const;
};
static TypeCached type_cached;
+9 -16
View File
@@ -31,7 +31,6 @@ namespace embree
{
Type();
size_t size(const char* This) const;
bool last(const char* This) const;
};
static Type type;
@@ -49,11 +48,8 @@ namespace embree
__forceinline TriangleM() {}
/* Construction from vertices and IDs */
__forceinline TriangleM(const Vec3vf<M>& v0, const Vec3vf<M>& v1, const Vec3vf<M>& v2, const vint<M>& geomIDs, const vint<M>& primIDs, const bool last)
: v0(v0), e1(v0-v1), e2(v2-v0), geomIDs(geomIDs), primIDs(primIDs)
{
this->geomIDs[0] |= unsigned(last) << 31;
}
__forceinline TriangleM(const Vec3vf<M>& v0, const Vec3vf<M>& v1, const Vec3vf<M>& v2, const vint<M>& geomIDs, const vint<M>& primIDs)
: v0(v0), e1(v0-v1), e2(v2-v0), geomIDs(geomIDs), primIDs(primIDs) {}
/* Returns a mask that tells which triangles are valid */
__forceinline vbool<M> valid() const { return geomIDs != vint<M>(-1); }
@@ -64,13 +60,10 @@ namespace embree
/* Returns the number of stored triangles */
__forceinline size_t size() const { return __bsf(~movemask(valid())); }
/*! checks if this is the last primitive */
__forceinline unsigned last() const { return geomIDs[0] & 0x80000000; }
/* Returns the geometry IDs */
__forceinline vint<M>& geomID() { return geomIDs; }
__forceinline const vint<M>& geomID() const { return geomIDs; }
__forceinline int geomID(const size_t i) const { assert(i<M); return geomIDs[i] & 0x7FFFFFFF; }
__forceinline int geomID(const size_t i) const { assert(i<M); return geomIDs[i]; }
/* Returns the primitive IDs */
__forceinline vint<M>& primID() { return primIDs; }
@@ -113,7 +106,7 @@ namespace embree
}
/* Fill triangle from triangle list */
__forceinline void fill(const PrimRef* prims, size_t& begin, size_t end, Scene* scene, bool last)
__forceinline void fill(const PrimRef* prims, size_t& begin, size_t end, Scene* scene)
{
vint<M> vgeomID = -1, vprimID = -1;
Vec3vf<M> v0 = zero, v1 = zero, v2 = zero;
@@ -134,7 +127,7 @@ namespace embree
v1.x[i] = p1.x; v1.y[i] = p1.y; v1.z[i] = p1.z;
v2.x[i] = p2.x; v2.y[i] = p2.y; v2.z[i] = p2.z;
}
TriangleM::store_nt(this,TriangleM(v0,v1,v2,vgeomID,vprimID,last));
TriangleM::store_nt(this,TriangleM(v0,v1,v2,vgeomID,vprimID));
}
/* Updates the primitive */
@@ -144,10 +137,10 @@ namespace embree
vint<M> vgeomID = -1, vprimID = -1;
Vec3vf<M> v0 = zero, v1 = zero, v2 = zero;
for (size_t i=0; i<M; i++)
for (size_t i=0; i<M; i++)
{
if (unlikely(!valid(i))) break;
const unsigned geomId = geomIDs[i]; // copies last bit
if (unlikely(geomID(i) == -1)) break;
const unsigned geomId = geomID(i);
const unsigned primId = primID(i);
const TriangleMesh::Triangle& tri = mesh->triangle(primId);
const Vec3fa p0 = mesh->vertex(tri.v[0]);
@@ -160,7 +153,7 @@ namespace embree
v1.x[i] = p1.x; v1.y[i] = p1.y; v1.z[i] = p1.z;
v2.x[i] = p2.x; v2.y[i] = p2.y; v2.z[i] = p2.z;
}
TriangleM::store_nt(this,TriangleM(v0,v1,v2,vgeomID,vprimID,false));
TriangleM::store_nt(this,TriangleM(v0,v1,v2,vgeomID,vprimID));
return bounds;
}
+17 -25
View File
@@ -30,7 +30,6 @@ namespace embree
{
Type();
size_t size(const char* This) const;
bool last(const char* This) const;
};
static Type type;
@@ -55,12 +54,8 @@ namespace embree
const vint<M>& v1,
const vint<M>& v2,
const vint<M>& geomIDs,
const vint<M>& primIDs,
const bool last)
: v0(v0), v1(v1), v2(v2), geomIDs(geomIDs), primIDs(primIDs)
{
this->geomIDs[0] |= unsigned(last) << 31;
}
const vint<M>& primIDs)
: v0(v0), v1(v1), v2(v2), geomIDs(geomIDs), primIDs(primIDs) {}
/* Returns a mask that tells which triangles are valid */
__forceinline vbool<M> valid() const { return primIDs != vint<M>(-1); }
@@ -71,12 +66,9 @@ namespace embree
/* Returns the number of stored triangles */
__forceinline size_t size() const { return __bsf(~movemask(valid())); }
/*! checks if this is the last primitive */
__forceinline unsigned last() const { return geomIDs[0] & 0x80000000; }
/* Returns the geometry IDs */
__forceinline vint<M> geomID() const { return geomIDs; }
__forceinline int geomID(const size_t i) const { assert(i<M); return geomIDs[i] & 0x7FFFFFFF; }
__forceinline int geomID(const size_t i) const { assert(i<M); return geomIDs[i]; }
/* Returns the primitive IDs */
__forceinline vint<M> primID() const { return primIDs; }
@@ -218,7 +210,7 @@ namespace embree
/* Fill triangle from triangle list */
template<typename PrimRefT>
__forceinline void fill(const PrimRefT* prims, size_t& begin, size_t end, Scene* scene, bool last)
__forceinline void fill(const PrimRefT* prims, size_t& begin, size_t end, Scene* scene)
{
vint<M> geomID = -1, primID = -1;
vint<M> v0 = zero, v1 = zero, v2 = zero;
@@ -249,18 +241,18 @@ namespace embree
if (begin<end) prim = &prims[begin];
}
new (this) TriangleMi(v0,v1,v2,geomID,primID,last); // FIXME: use non temporal store
new (this) TriangleMi(v0,v1,v2,geomID,primID); // FIXME: use non temporal store
}
__forceinline LBBox3fa fillMB(const PrimRef* prims, size_t& begin, size_t end, Scene* scene, size_t itime, bool last)
__forceinline LBBox3fa fillMB(const PrimRef* prims, size_t& begin, size_t end, Scene* scene, size_t itime)
{
fill(prims, begin, end, scene, last);
fill(prims, begin, end, scene);
return linearBounds(scene, itime);
}
__forceinline LBBox3fa fillMB(const PrimRefMB* prims, size_t& begin, size_t end, Scene* scene, const BBox1f time_range, bool last)
__forceinline LBBox3fa fillMB(const PrimRefMB* prims, size_t& begin, size_t end, Scene* scene, const BBox1f time_range)
{
fill(prims, begin, end, scene, last);
fill(prims, begin, end, scene);
return linearBounds(scene, time_range);
}
@@ -296,10 +288,10 @@ namespace embree
Vec3vf4& p2,
const Scene* const scene) const
{
const int* vertices0 = scene->vertices[geomIDs[0] & 0x7FFFFFFF];
const int* vertices1 = scene->vertices[geomIDs[1]];
const int* vertices2 = scene->vertices[geomIDs[2]];
const int* vertices3 = scene->vertices[geomIDs[3]];
const int* vertices0 = scene->vertices[geomID(0)];
const int* vertices1 = scene->vertices[geomID(1)];
const int* vertices2 = scene->vertices[geomID(2)];
const int* vertices3 = scene->vertices[geomID(3)];
const vfloat4 a0 = vfloat4::loadu(vertices0 + v0[0]);
const vfloat4 a1 = vfloat4::loadu(vertices1 + v0[1]);
const vfloat4 a2 = vfloat4::loadu(vertices2 + v0[2]);
@@ -355,10 +347,10 @@ namespace embree
const Scene *const scene,
const float time) const
{
const TriangleMesh* mesh0 = scene->get<TriangleMesh>(geomIDs[0] & 0x7FFFFFFF);
const TriangleMesh* mesh1 = scene->get<TriangleMesh>(geomIDs[1]);
const TriangleMesh* mesh2 = scene->get<TriangleMesh>(geomIDs[2]);
const TriangleMesh* mesh3 = scene->get<TriangleMesh>(geomIDs[3]);
const TriangleMesh* mesh0 = scene->get<TriangleMesh>(geomID(0));
const TriangleMesh* mesh1 = scene->get<TriangleMesh>(geomID(1));
const TriangleMesh* mesh2 = scene->get<TriangleMesh>(geomID(2));
const TriangleMesh* mesh3 = scene->get<TriangleMesh>(geomID(3));
const vfloat4 numTimeSegments(mesh0->fnumTimeSegments, mesh1->fnumTimeSegments, mesh2->fnumTimeSegments, mesh3->fnumTimeSegments);
vfloat4 ftime;
+7 -14
View File
@@ -29,7 +29,6 @@ namespace embree
{
Type();
size_t size(const char* This) const;
bool last(const char* This) const;
};
static Type type;
@@ -47,11 +46,8 @@ namespace embree
__forceinline TriangleMv() {}
/* Construction from vertices and IDs */
__forceinline TriangleMv(const Vec3vf<M>& v0, const Vec3vf<M>& v1, const Vec3vf<M>& v2, const vint<M>& geomIDs, const vint<M>& primIDs, const bool last)
: v0(v0), v1(v1), v2(v2), geomIDs(geomIDs), primIDs(primIDs)
{
this->geomIDs[0] |= unsigned(last) << 31;
}
__forceinline TriangleMv(const Vec3vf<M>& v0, const Vec3vf<M>& v1, const Vec3vf<M>& v2, const vint<M>& geomIDs, const vint<M>& primIDs)
: v0(v0), v1(v1), v2(v2), geomIDs(geomIDs), primIDs(primIDs) {}
/* Returns a mask that tells which triangles are valid */
__forceinline vbool<M> valid() const { return geomIDs != vint<M>(-1); }
@@ -62,13 +58,10 @@ namespace embree
/* Returns the number of stored triangles */
__forceinline size_t size() const { return __bsf(~movemask(valid())); }
/*! checks if this is the last primitive */
__forceinline unsigned last() const { return geomIDs[0] & 0x80000000; }
/* Returns the geometry IDs */
__forceinline vint<M>& geomID() { return geomIDs; }
__forceinline const vint<M>& geomID() const { return geomIDs; }
__forceinline int geomID(const size_t i) const { assert(i<M); return geomIDs[i] & 0x7FFFFFFF; }
__forceinline int geomID(const size_t i) const { assert(i<M); return geomIDs[i]; }
/* Returns the primitive IDs */
__forceinline vint<M>& primID() { return primIDs; }
@@ -108,7 +101,7 @@ namespace embree
}
/* Fill triangle from triangle list */
__forceinline void fill(const PrimRef* prims, size_t& begin, size_t end, Scene* scene, bool last)
__forceinline void fill(const PrimRef* prims, size_t& begin, size_t end, Scene* scene)
{
vint<M> vgeomID = -1, vprimID = -1;
Vec3vf<M> v0 = zero, v1 = zero, v2 = zero;
@@ -129,7 +122,7 @@ namespace embree
v1.x[i] = p1.x; v1.y[i] = p1.y; v1.z[i] = p1.z;
v2.x[i] = p2.x; v2.y[i] = p2.y; v2.z[i] = p2.z;
}
TriangleMv::store_nt(this,TriangleMv(v0,v1,v2,vgeomID,vprimID,last));
TriangleMv::store_nt(this,TriangleMv(v0,v1,v2,vgeomID,vprimID));
}
/* Updates the primitive */
@@ -142,7 +135,7 @@ namespace embree
for (size_t i=0; i<M; i++)
{
if (primID(i) == -1) break;
const unsigned geomId = geomIDs[i]; // copies last bit
const unsigned geomId = geomID(i);
const unsigned primId = primID(i);
const TriangleMesh::Triangle& tri = mesh->triangle(primId);
const Vec3fa p0 = mesh->vertex(tri.v[0]);
@@ -155,7 +148,7 @@ namespace embree
v1.x[i] = p1.x; v1.y[i] = p1.y; v1.z[i] = p1.z;
v2.x[i] = p2.x; v2.y[i] = p2.y; v2.z[i] = p2.z;
}
new (this) TriangleMv(v0,v1,v2,vgeomID,vprimID,false);
new (this) TriangleMv(v0,v1,v2,vgeomID,vprimID);
return bounds;
}
+7 -15
View File
@@ -29,7 +29,6 @@ namespace embree
{
Type();
size_t size(const char* This) const;
bool last(const char* This) const;
};
static Type type;
@@ -54,12 +53,8 @@ namespace embree
__forceinline TriangleMvMB(const Vec3vf<M>& a0, const Vec3vf<M>& a1,
const Vec3vf<M>& b0, const Vec3vf<M>& b1,
const Vec3vf<M>& c0, const Vec3vf<M>& c1,
const vint<M>& geomIDs, const vint<M>& primIDs,
const bool last)
: v0(a0), v1(b0), v2(c0), dv0(a1-a0), dv1(b1-b0), dv2(c1-c0), geomIDs(geomIDs), primIDs(primIDs)
{
this->geomIDs[0] |= unsigned(last) << 31;
}
const vint<M>& geomIDs, const vint<M>& primIDs)
: v0(a0), v1(b0), v2(c0), dv0(a1-a0), dv1(b1-b0), dv2(c1-c0), geomIDs(geomIDs), primIDs(primIDs) {}
/* Returns a mask that tells which triangles are valid */
__forceinline vbool<M> valid() const { return geomIDs != vint<M>(-1); }
@@ -70,13 +65,10 @@ namespace embree
/* Returns the number of stored triangles */
__forceinline size_t size() const { return __bsf(~movemask(valid())); }
/*! checks if this is the last primitive */
__forceinline unsigned last() const { return geomIDs[0] & 0x80000000; }
/* Returns the geometry IDs */
__forceinline vint<M>& geomID() { return geomIDs; }
__forceinline const vint<M>& geomID() const { return geomIDs; }
__forceinline int geomID(const size_t i) const { assert(i<M); return geomIDs[i] & 0x7FFFFFFF; }
__forceinline int geomID(const size_t i) const { assert(i<M); return geomIDs[i]; }
/* Returns the primitive IDs */
__forceinline vint<M>& primID() { return primIDs; }
@@ -124,7 +116,7 @@ namespace embree
}
/* Fill triangle from triangle list */
__forceinline LBBox3fa fillMB(const PrimRef* prims, size_t& begin, size_t end, Scene* scene, size_t itime, bool last)
__forceinline LBBox3fa fillMB(const PrimRef* prims, size_t& begin, size_t end, Scene* scene, size_t itime)
{
vint<M> vgeomID = -1, vprimID = -1;
Vec3vf<M> va0 = zero, vb0 = zero, vc0 = zero;
@@ -155,12 +147,12 @@ namespace embree
vc0.x[i] = c0.x; vc0.y[i] = c0.y; vc0.z[i] = c0.z;
vc1.x[i] = c1.x; vc1.y[i] = c1.y; vc1.z[i] = c1.z;
}
new (this) TriangleMvMB(va0,va1,vb0,vb1,vc0,vc1,vgeomID,vprimID,last);
new (this) TriangleMvMB(va0,va1,vb0,vb1,vc0,vc1,vgeomID,vprimID);
return LBBox3fa(bounds0,bounds1);
}
/* Fill triangle from triangle list */
__forceinline LBBox3fa fillMB(const PrimRefMB* prims, size_t& begin, size_t end, Scene* scene, const BBox1f time_range, bool last)
__forceinline LBBox3fa fillMB(const PrimRefMB* prims, size_t& begin, size_t end, Scene* scene, const BBox1f time_range)
{
vint<M> vgeomID = -1, vprimID = -1;
Vec3vf<M> va0 = zero, vb0 = zero, vc0 = zero;
@@ -198,7 +190,7 @@ namespace embree
vc0.x[i] = c01.first .x; vc0.y[i] = c01.first .y; vc0.z[i] = c01.first .z;
vc1.x[i] = c01.second.x; vc1.y[i] = c01.second.y; vc1.z[i] = c01.second.z;
}
new (this) TriangleMvMB(va0,va1,vb0,vb1,vc0,vc1,vgeomID,vprimID,last);
new (this) TriangleMvMB(va0,va1,vb0,vb1,vc0,vc1,vgeomID,vprimID);
return allBounds;
}
+1
View File
@@ -214,6 +214,7 @@ namespace embree
const unsigned l = (unsigned) floor(0.5f*uv.x); const float u = 2.0f*frac(0.5f*uv.x)-0.5f;
const unsigned h = (unsigned) floor(0.5f*uv.y); const float v = 2.0f*frac(0.5f*uv.y)-0.5f;
const unsigned i = 4*h+l; assert(i<N);
if (i >= N) return;
#if PATCH_USE_GREGORY == 2
BezierCurve borders[2]; patch.getLimitBorder(borders,i);
+8 -8
View File
@@ -323,14 +323,14 @@ namespace embree
const unsigned x1s = stitch(x1,fine_x,coarse_x);
const unsigned M = x1s-x0s+1;
dynamic_large_stack_array(float,px,M,64*sizeof(float));
dynamic_large_stack_array(float,py,M,64*sizeof(float));
dynamic_large_stack_array(float,pz,M,64*sizeof(float));
dynamic_large_stack_array(float,u,M,64*sizeof(float));
dynamic_large_stack_array(float,v,M,64*sizeof(float));
dynamic_large_stack_array(float,nx,M,64*sizeof(float));
dynamic_large_stack_array(float,ny,M,64*sizeof(float));
dynamic_large_stack_array(float,nz,M,64*sizeof(float));
dynamic_large_stack_array(float,px,M,32*sizeof(float));
dynamic_large_stack_array(float,py,M,32*sizeof(float));
dynamic_large_stack_array(float,pz,M,32*sizeof(float));
dynamic_large_stack_array(float,u,M,32*sizeof(float));
dynamic_large_stack_array(float,v,M,32*sizeof(float));
dynamic_large_stack_array(float,nx,M,32*sizeof(float));
dynamic_large_stack_array(float,ny,M,32*sizeof(float));
dynamic_large_stack_array(float,nz,M,32*sizeof(float));
const bool has_Nxyz = Nx; assert(!Nx || (Ny && Nz));
Eval(patch,subPatch, x0s,x1s, bottom,bottom, coarse_x+1,2, px,py,pz,u,v,
has_Nxyz ? (float*)nx :nullptr, has_Nxyz ? (float*)ny : nullptr , has_Nxyz ? (float*)nz : nullptr, 4097,1);
+3 -3
View File
@@ -95,9 +95,9 @@ namespace embree
{
const bool displ = geom->displFunc || geom->displFunc2;
const unsigned N = displ ? M : 0;
dynamic_large_stack_array(float,grid_Ng_x,N,64*64*sizeof(float));
dynamic_large_stack_array(float,grid_Ng_y,N,64*64*sizeof(float));
dynamic_large_stack_array(float,grid_Ng_z,N,64*64*sizeof(float));
dynamic_large_stack_array(float,grid_Ng_x,N,32*32*sizeof(float));
dynamic_large_stack_array(float,grid_Ng_y,N,32*32*sizeof(float));
dynamic_large_stack_array(float,grid_Ng_z,N,32*32*sizeof(float));
if (geom->patch_eval_trees.size())
{
BIN
View File
Binary file not shown.
+1 -1
View File
@@ -42,7 +42,7 @@ def render(name,modelname,model):
command += ' -c ' + model
for arg in args:
command += ' ' + arg
command += ' -rtcore verbose=2 -benchmark 4 16 > ' + logFile
command += ' -rtcore verbose=2 -benchmark 8 32 > ' + logFile
os.system(command)
def renderLoop():
+2 -2
View File
@@ -33,7 +33,7 @@ done
# now remove files
echo Uninstalling Embree @EMBREE_VERSION@ ...
for f in "${FILES[@]}"; do
sudo rm -vd "$f"
sudo /bin/rm -vd "$f"
done
sudo pkgutil --forget com.intel.embree-@EMBREE_VERSION@
sudo /usr/sbin/pkgutil --forget com.intel.embree-@EMBREE_VERSION@
+1 -1
View File
@@ -94,7 +94,7 @@ outImageFileJpg = name + ".jpg"
diffImageFileTga= name + ".diff.tga"
diffImageFileJpg= name + ".diff.jpg"
executable = executable + " -rtcore verbose=2"
executable = executable + " -rtcore verbose=0"
if (model != "" and model != "default"):
executable = executable + " -c " + modeldir + dash + model
+2 -2
View File
@@ -3,7 +3,7 @@ make clean > /dev/null
kwinject -w -o buildspec.txt make -j 8 > /dev/null
#kwcheck create -b buildspec.txt --url http://localhost:8080/embree
#kwcheck run
kwbuildproject --force --url http://localhost:8080/embree buildspec.txt --tables-directory mytables
kwadmin --url http://localhost:8080 load embree mytables
kwbuildproject --force --url http://10.123.110.111:80/embree buildspec.txt --tables-directory mytables
kwadmin --url http://10.123.110.111:80 load embree mytables
#kwcheck list -F detailed
#kwcheck list -F detailed > klocwork.log
+3
View File
@@ -1,5 +1,8 @@
#!/bin/bash
# terminate if some error occurs
set -e
# check version of symbols
function check_symbols
{
+3
View File
@@ -1,5 +1,8 @@
#!/bin/bash
# terminate if some error occurs
set -e
# read embree version
#EMBREE_VERSION_MAJOR=`sed -n 's/#define __EMBREE_VERSION_MAJOR__ \(.*\)/\1/p' version.h`
#EMBREE_VERSION_MINOR=`sed -n 's/#define __EMBREE_VERSION_MINOR__ \(.*\)/\1/p' version.h`
+4
View File
@@ -7,5 +7,9 @@ if "%build_type%" == "" (
cmake --build . --config %build_type% --target PACKAGE -- /m /nologo /verbosity:n
IF %ERRORLEVEL% NEQ 0 (
exit /b
)
@echo "<DartMeasurement name="%1" type="text/string">%1</DartMeasurement>"
+1
View File
@@ -57,6 +57,7 @@ cmake \
# set release settings
cmake \
-D EMBREE_STACK_PROTECTOR=ON\
-D EMBREE_MAX_ISA=NONE \
-D EMBREE_ISA_SSE2=ON \
-D EMBREE_ISA_SSE42=ON \
+1
View File
@@ -19,6 +19,7 @@ cmake \
# set release settings
cmake \
-D EMBREE_STACK_PROTECTOR=ON\
-D EMBREE_MAX_ISA=AVX2 \
-D EMBREE_TUTORIALS_IMAGE_MAGICK=OFF \
-D EMBREE_TUTORIALS_LIBJPEG=OFF \
+1 -42
View File
@@ -3,48 +3,6 @@
setlocal
set TBB_PATH_LOCAL=%cd%\tbb
mkdir -p build_win32
cd build_win32
del CMakeCache.txt
del version.h
REM set release settings
cmake -L ^
-G "Visual Studio 12 2013" ^
-T "Intel C++ Compiler 16.0" ^
-D EMBREE_MAX_ISA=AVX512SKX ^
-D EMBREE_TUTORIALS_IMAGE_MAGICK=OFF ^
-D EMBREE_TUTORIALS_LIBJPEG=OFF ^
-D EMBREE_TUTORIALS_LIBPNG=OFF ^
-D EMBREE_TBB_ROOT=%TBB_PATH_LOCAL% ^
..
REM compile
cmake --clean-first --build . --config Release --target PREINSTALL -- /m /nologo /verbosity:n
REM create ZIP files
cmake ^
-D EMBREE_ZIP_MODE=ON ^
-D CMAKE_INSTALL_INCLUDEDIR=include ^
-D CMAKE_INSTALL_LIBDIR=lib ^
-D CMAKE_INSTALL_DATAROOTDIR= ^
-D CMAKE_INSTALL_DOCDIR=doc ^
-D CMAKE_INSTALL_BINDIR=bin ^
..
cmake --build . --config Release --target PACKAGE -- /m /nologo /verbosity:n
REM create installers
cmake ^
-D EMBREE_ZIP_MODE=OFF ^
-D CMAKE_INSTALL_INCLUDEDIR=include ^
-D CMAKE_INSTALL_LIBDIR=lib ^
-D CMAKE_INSTALL_DATAROOTDIR= ^
-D CMAKE_INSTALL_DOCDIR=doc ^
-D CMAKE_INSTALL_BINDIR=bin ^
..
cmake --build . --config Release --target PACKAGE -- /m /nologo /verbosity:n
cd ..
mkdir build_x64
cd build_x64
del CMakeCache.txt # make sure to use default settings
@@ -54,6 +12,7 @@ REM set release settings
cmake -L ^
-G "Visual Studio 12 2013 Win64" ^
-T "Intel C++ Compiler 16.0" ^
-D EMBREE_STACK_PROTECTOR=ON ^
-D EMBREE_MAX_ISA=AVX512SKX ^
-D EMBREE_TBB_ROOT=%TBB_PATH_LOCAL% ^
-D ENABLE_XEON_PHI_SUPPORT=OFF ^
+3
View File
@@ -0,0 +1,3 @@
#!/bin/bash
echo stripping $1
strip -x $1
+117
View File
@@ -0,0 +1,117 @@
message("CTEST_BUILD_OPTIONS = ${CTEST_BUILD_OPTIONS}")
# project and repository to clone from
SET(CTEST_PROJECT_NAME "Embree")
SET(TEST_REPOSITORY "https://github.com/embree/embree.git")
SET(TEST_ROOT_DIRECTORY "${CTEST_SCRIPT_DIRECTORY}/..")
STRING(REPLACE ":/" ":\\" TEST_ROOT_DIRECTORY1 "${TEST_ROOT_DIRECTORY}") # cygwin git has issues with c:/dir paths
#SET(TEST_MODELS_DIRECTORY ${TEST_ROOT_DIRECTORY}/dependencies/embree-models)
SET(TEST_MODELS_DIRECTORY $ENV{HOME}/embree-models)
MESSAGE("TEST_MODELS_DIRECTORY = ${TEST_MODELS_DIRECTORY}")
# set source and build directory
set(CTEST_SOURCE_DIRECTORY "${TEST_ROOT_DIRECTORY1}")
message("CTEST_SOURCE_DIRECTORY = ${CTEST_SOURCE_DIRECTORY}")
set(CTEST_BINARY_DIRECTORY "${TEST_ROOT_DIRECTORY1}/build")
# update external model repository
FIND_PROGRAM(CTEST_GIT_COMMAND NAMES git)
# macro that updates the test models
MACRO(update_test_models)
IF(NOT EXISTS "${TEST_MODELS_DIRECTORY}")
MESSAGE("cloning test models ...")
EXECUTE_PROCESS(
COMMAND ${CTEST_GIT_COMMAND} "clone" "git@git.sdvis.org:embree-models.git" embree-models
WORKING_DIRECTORY $ENV{HOME}
)
ELSE()
MESSAGE("updating test models ...")
EXECUTE_PROCESS(
COMMAND ${CTEST_GIT_COMMAND} "fetch"
WORKING_DIRECTORY ${TEST_MODELS_DIRECTORY}
)
ENDIF()
IF (NOT TEST_MODELS_HASH)
MESSAGE(FATAL_ERROR "no TEST_MODELS_HASH set")
ENDIF()
MESSAGE("checking out test models: ${TEST_MODELS_HASH}")
EXECUTE_PROCESS(
COMMAND ${CTEST_GIT_COMMAND} "checkout" ${TEST_MODELS_HASH}
WORKING_DIRECTORY ${TEST_MODELS_DIRECTORY}
)
ENDMACRO()
# increase default output sizes for test outputs
IF (NOT DEFINED CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE)
SET(CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE 100000)
ENDIF()
IF(NOT DEFINED CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE)
SET(CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE 800000)
ENDIF()
# enable testing in Embree
SET (CTEST_BUILD_OPTIONS "${CTEST_BUILD_OPTIONS} -D BUILD_TESTING:BOOL=ON -D EMBREE_TESTING_MODEL_DIR:PATH=${TEST_MODELS_DIRECTORY}")
# set site based on this machine's hostname
SITE_NAME(HOSTNAME)
set(CTEST_SITE "${HOSTNAME}")
# drop location
set(CTEST_DROP_METHOD "http")
IF(NOT CTEST_DROP_SITE)
set(CTEST_DROP_SITE "10.123.110.90")
ENDIF()
set(CTEST_DROP_LOCATION "/CDash/submit.php?project=${CTEST_PROJECT_NAME}")
set(CTEST_DROP_SITE_CDASH TRUE)
# get OS and CPU information
find_program(UNAME NAMES uname)
macro(getuname name flag)
exec_program("${UNAME}" ARGS "${flag}" OUTPUT_VARIABLE "${name}")
endmacro(getuname)
getuname(osname -s)
getuname(osrel -r)
getuname(cpu -m)
# build using as many processes as we have processors
include(ProcessorCount)
ProcessorCount(numProcessors)
if(numProcessors EQUAL 0)
SET(numProcessors 1)
endif()
# set build name
set(CTEST_BUILD_NAME "${TEST_NAME}-${osname}-${cpu}")
set(CTEST_CMAKE_GENERATOR "Unix Makefiles")
IF (WIN32)
set(CTEST_BUILD_COMMAND "${CMAKE_COMMAND} --build . --config ${CTEST_CONFIGURATION_TYPE}")
ELSE()
set(CTEST_BUILD_COMMAND "make -j ${numProcessors}")
ENDIF()
###################
# execute the test
###################
# requires CMake 2.8 or higher for git!!!
#set(CTEST_UPDATE_COMMAND "${CTEST_GIT_COMMAND}")
set(CTEST_CONFIGURE_COMMAND "${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE:STRING=${CTEST_BUILD_CONFIGURATION}")
set(CTEST_CONFIGURE_COMMAND "${CTEST_CONFIGURE_COMMAND} ${CTEST_BUILD_OPTIONS}")
set(CTEST_CONFIGURE_COMMAND "${CTEST_CONFIGURE_COMMAND} ..")
# start the test
ctest_empty_binary_directory(${CTEST_BINARY_DIRECTORY})
ctest_start("Continuous")
#ctest_update (RETURN_VALUE count)
update_test_models()
ctest_configure()
ctest_build()
IF (NOT CTEST_SKIP_TESTING)
ctest_test()
ENDIF()
ctest_submit()
+514
View File
@@ -0,0 +1,514 @@
#!/usr/bin/python
import sys
import os
import ctypes
import time
import datetime
import json
import socket
import subprocess
g_cdash = ""
g_config = {}
g_mode = "Experimental"
g_intensive = False
g_debugMode = False
g_singleConfig = ""
def escape(str):
str = str.replace("\\",r"\\")
str = str.replace("\"",r"\"")
str = str.replace(":","\:")
return str
# detect platform
if sys.platform.startswith("win"):
dash = '\\'
SEM_FAILCRITICALERRORS = 0x0001
SEM_NOGPFAULTERRORBOX = 0x0002
SEM_NOOPENFILEERRORBOX = 0x8000
ctypes.windll.kernel32.SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);
OS = "windows"
elif sys.platform.startswith("cygwin"):
dash = '/'
SEM_FAILCRITICALERRORS = 0x0001
SEM_NOGPFAULTERRORBOX = 0x0002
SEM_NOOPENFILEERRORBOX = 0x8000
ctypes.cdll.kernel32.SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);
OS = "windows"
elif sys.platform.startswith("linux"):
dash = '/'
OS = "linux"
elif sys.platform.startswith("darwin"):
dash = '/'
OS = "macosx"
else:
print("unknown platform: "+ sys.platform);
sys.exit(1)
# fast testing
def createConfigsLight(branch,build,host):
configs = []
if host == "tcg-vis-ci-win1":
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"V140", "isa":"AVX2" , "tasking":"TBB", "intensive":"OFF"})
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG", "isa":"AVX2" , "tasking":"TBB", "intensive":"OFF"})
if host == "tcg-vis-ci-win2":
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"V120", "isa":"AVX2" , "tasking":"TBB", "intensive":"OFF"})
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"ICC17", "isa":"AVX2" , "tasking":"TBB", "intensive":"OFF"})
if host == "tcg-vis-mac-mini":
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG", "isa":"AVX2" , "tasking":"TBB", "intensive":"OFF"})
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"ICC16", "isa":"AVX2" , "tasking":"TBB", "intensive":"OFF"})
if host == "tcg-vis-ci-ubuntu1604" or host == "tcg-vis-ubuntu1404":
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG", "isa":"AVX2" , "tasking":"TBB", "intensive":"OFF"})
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"GCC" , "isa":"AVX2" , "tasking":"TBB", "intensive":"OFF"})
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"ICC17", "isa":"AVX512KNL", "tasking":"TBB", "intensive":"OFF" })
if host == "k7":
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"ICC17", "isa":"AVX512KNL", "tasking":"TBB", "intensive":"OFF" })
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG4","isa":"AVX512KNL", "tasking":"TBB", "intensive":"OFF" })
if host == "swr-ivb-lnx-01":
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"ICC17", "isa":"AVX2", "tasking":"TBB", "klocwork":"ON"})
if host == "skylake-b0":
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"ICC17", "isa":"AVX512SKX", "tasking":"TBB", "intensive":"OFF"})
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG4","isa":"AVX512SKX", "tasking":"TBB", "intensive":"OFF"})
if host == "test":
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG", "isa":"SSE2" , "tasking":"TBB", "intensive":"OFF"})
return configs
# intensive testing
def createConfigsIntensive(branch,build,host):
configs = []
if host == "tcg-vis-ci-win1":
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"ICC18","isa":"AVX512SKX", "tasking":"TBB", "intensive":"ON"})
for platform in ["x64", "win32"]:
if platform == "win32": intensive = "OFF" # runs only small win32 tests for win32 platform
else: intensive = "ON"
configs.append({"branch":branch, "platform":platform, "build":build, "compiler":"V140", "isa":"AVX2", "tasking":"TBB", "intensive":intensive})
configs.append({"branch":branch, "platform":platform, "build":build, "compiler":"V140", "isa":"AVX2", "tasking":"INT", "intensive":intensive})
configs.append({"branch":branch, "platform":platform, "build":build, "compiler":"V140", "isa":"AVX2", "tasking":"PPL", "intensive":intensive})
configs.append({"branch":branch, "platform":platform, "build":build, "compiler":"CLANG","isa":"AVX2", "tasking":"TBB", "intensive":intensive})
configs.append({"branch":branch, "platform":platform, "build":build, "compiler":"ICC16","isa":"AVX2", "tasking":"TBB", "intensive":intensive})
elif host == "tcg-vis-ci-win2":
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"ICC17", "isa":"AVX512SKX" , "tasking":"TBB", "intensive":"OFF", "sde":"skx"})
for platform in ["x64", "win32"]:
if platform == "win32": intensive = "OFF" # runs only small win32 tests for win32 platform
else: intensive = "ON"
configs.append({"branch":branch, "platform":platform, "build":build, "compiler":"V120", "isa":"SSE2", "tasking":"TBB", "intensive":intensive})
configs.append({"branch":branch, "platform":platform, "build":build, "compiler":"V120", "isa":"AVX", "tasking":"INT", "intensive":intensive})
configs.append({"branch":branch, "platform":platform, "build":build, "compiler":"V141", "isa":"AVX2", "tasking":"TBB", "intensive":intensive})
configs.append({"branch":branch, "platform":platform, "build":build, "compiler":"ICC17", "isa":"AVX2", "tasking":"TBB", "intensive":intensive})
elif host == "k7":
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"ICC16" , "isa":"AVX512KNL", "tasking":"TBB", "intensive":"ON"})
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"ICC17" , "isa":"AVX512KNL", "tasking":"TBB", "intensive":"ON"})
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG4" , "isa":"AVX512KNL", "tasking":"TBB", "intensive":"ON"})
elif host == "skylake-b0":
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"ICC17" , "isa":"AVX512SKX", "tasking":"TBB", "intensive":"ON"})
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG4" , "isa":"AVX512SKX", "tasking":"TBB", "intensive":"ON"})
elif host == "tcg-vis-ci-ubuntu1604" or host == "tcg-vis-ubuntu1404":
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG", "isa":"SSE2", "tasking":"TBB", "intensive":"ON"})
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG", "isa":"AVX" , "tasking":"INT", "intensive":"ON"})
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG", "isa":"AVX2", "tasking":"TBB", "intensive":"ON"})
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"GCC" , "isa":"SSE2", "tasking":"TBB", "intensive":"ON"})
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"GCC" , "isa":"AVX" , "tasking":"INT", "intensive":"ON"})
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"GCC" , "isa":"AVX2", "tasking":"TBB", "intensive":"ON"})
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"ICC16" , "isa":"SSE2", "tasking":"TBB", "intensive":"ON"})
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"ICC15" , "isa":"AVX" , "tasking":"INT", "intensive":"ON"})
if build == "RelWithDebInfo":
configs.append({"branch":branch, "platform":"x64", "build":"RelWithDebInfo", "compiler":"ICC18" , "isa":"AVX512SKX", "tasking":"TBB", "intensive":"ON"})
configs.append({"branch":branch, "platform":"x64", "build":"RelWithDebInfo", "compiler":"ICC17" , "isa":"AVX512KNL", "tasking":"TBB", "intensive":"ON", "memcheck":"ON"})
# configs.append({"branch":branch, "platform":"x64", "build":"Release", "compiler":"ICC17" , "isa":"AVX2", "tasking":"TBB", "intensive":"ON", "benchmark":"ON"})
else:
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"ICC17" , "isa":"AVX2", "tasking":"TBB", "intensive":"ON"})
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG" , "isa":"AVX2" , "tasking":"TBB", "ISPC_SUPPORT":"OFF", "test":False})
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG" , "isa":"AVX2" , "tasking":"TBB", "STATIC_LIB":"ON"})
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG" , "isa":"AVX2" , "tasking":"TBB", "TUTORIALS":"OFF", "test":False})
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG" , "isa":"AVX2" , "tasking":"TBB", "BACKFACE_CULLING":"ON", "test":False})
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG" , "isa":"AVX2" , "tasking":"TBB", "IGNORE_INVALID_RAYS":"ON"})
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG" , "isa":"AVX2" , "tasking":"TBB", "INTERSECTION_FILTER":"OFF", "test":False})
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG" , "isa":"AVX2" , "tasking":"TBB", "RAY_MASK":"ON"})
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG" , "isa":"AVX2" , "tasking":"TBB", "RAY_PACKETS":"OFF"})
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG" , "isa":"AVX2" , "tasking":"TBB", "STAT_COUNTERS":"ON", "test":False})
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG4", "isa":["SSE2"], "tasking":"TBB", "test":False })
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG4", "isa":["SSE42"], "tasking":"TBB", "test":False })
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG4", "isa":["AVX"] , "tasking":"TBB", "test":False })
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG4", "isa":["AVX2"] , "tasking":"TBB", "test":False })
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG4", "isa":["AVX512KNL"], "tasking":"TBB", "test":False })
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG4", "isa":["AVX512SKX"], "tasking":"TBB", "test":False })
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG4", "isa":["AVX2","AVX512SKX"] , "tasking":"TBB", "test":False })
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG" , "isa":"AVX2" , "tasking":"TBB", "test":False,
"TRIS":"ON", "QUADS":"OFF", "LINES":"OFF", "HAIR":"OFF", "SUBDIV":"OFF", "USERGEOM":"OFF" })
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG" , "isa":"AVX2" , "tasking":"TBB", "test":False,
"TRIS":"OFF", "QUADS":"ON", "LINES":"OFF", "HAIR":"OFF", "SUBDIV":"OFF", "USERGEOM":"OFF" })
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG" , "isa":"AVX2" , "tasking":"TBB", "test":False,
"TRIS":"OFF", "QUADS":"OFF", "LINES":"ON", "HAIR":"OFF", "SUBDIV":"OFF", "USERGEOM":"OFF" })
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG" , "isa":"AVX2" , "tasking":"TBB", "test":False,
"TRIS":"OFF", "QUADS":"OFF", "LINES":"OFF", "HAIR":"ON", "SUBDIV":"OFF", "USERGEOM":"OFF" })
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG" , "isa":"AVX2" , "tasking":"TBB", "test":False,
"TRIS":"OFF", "QUADS":"OFF", "LINES":"OFF", "HAIR":"OFF", "SUBDIV":"ON", "USERGEOM":"OFF" })
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG" , "isa":"AVX2" , "tasking":"TBB", "test":False,
"TRIS":"OFF", "QUADS":"OFF", "LINES":"OFF", "HAIR":"OFF", "SUBDIV":"OFF", "USERGEOM":"ON" })
elif host == "tcg-vis-mac-mini":
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG", "isa":"SSE2", "tasking":"TBB", "intensive":"ON"})
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG", "isa":"AVX" , "tasking":"INT", "intensive":"ON"})
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG", "isa":"AVX2", "tasking":"TBB", "intensive":"ON"})
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"GCC" , "isa":"SSE2", "tasking":"TBB", "intensive":"ON"})
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"GCC" , "isa":"AVX" , "tasking":"INT", "intensive":"ON"})
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"GCC" , "isa":"AVX2", "tasking":"TBB", "intensive":"ON"})
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"ICC16" , "isa":"SSE2", "tasking":"TBB", "intensive":"ON"})
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"ICC15" , "isa":"AVX" , "tasking":"INT", "intensive":"ON"})
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG" , "isa":"AVX2" , "tasking":"TBB", "STATIC_LIB":"ON"})
# configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"ICC17" , "isa":"AVX2", "tasking":"TBB", "intensive":"ON"})
return configs
# intensive testing
def createConfigsPackage(branch,build,host):
configs = []
isa_windows = ["SSE2","SSE42","AVX","AVX2","AVX512SKX"]
isa_linux = ["SSE2","SSE42","AVX","AVX2","AVX512KNL","AVX512SKX"]
isa_macosx = ["SSE2","SSE42","AVX","AVX2"]
if host == "tcg-vis-ci-win1":
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"ICC17", "isa":isa_windows, "tasking":"TBB", "intensive":"ON", "package":"ZIP"})
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"ICC17", "isa":isa_windows, "tasking":"TBB", "intensive":"ON", "package":"RPM"})
elif host == "swr-ivb-lnx-01":
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"ICC17", "isa":isa_linux, "tasking":"TBB", "intensive":"ON", "package":"ZIP"})
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"ICC17", "isa":isa_linux, "tasking":"TBB", "intensive":"ON", "package":"RPM"})
elif host == "tcg-vis-mac-mini":
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"ICC16", "isa":isa_macosx, "tasking":"TBB", "intensive":"ON", "package":"ZIP"})
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"ICC16", "isa":isa_macosx, "tasking":"TBB", "intensive":"ON", "package":"RPM"})
return configs
def string_of_isa(isa):
if type(isa) == str: return isa;
else: return "ISAS-" + ("-".join(isa))
def createTest(config,OS):
c = [] # CMake configuration
e = [] # shell environment
platform = config["platform"]
build = config["build"]
compiler = config["compiler"]
isa = config["isa"]
tasking = config["tasking"]
if "intensive" in config: intensive = config["intensive"]
else : intensive = "OFF"
if "memcheck" in config: memcheck = config["memcheck"]
else : memcheck = "OFF"
if "benchmark" in config: benchmark = config["benchmark"]
else : benchmark = "OFF"
if "sde" in config: sde = config["sde"]
else : sde = "OFF"
if "test" in config: skip_testing = not config["test"]
else : skip_testing = False
if tasking == "INT": tasking = "INTERNAL"
if tasking == "PPL": tasking = "PPL"
name = "gitlab-"+platform+"-"+build+"-"+compiler+"-"+string_of_isa(isa)+"-"+tasking
if "package" in config:
c.append("-D EMBREE_STACK_PROTECTOR=ON")
if config["package"] == "ZIP": name = name + "-package-zip"
else : name = name + "-package-installer"
if "klocwork" in config: name = name + "-klocwork"
ispc_ext = "-vs2013"
if "package" in config and OS == 'linux': # we need up to date cmake for RPMs to work properly
e.append("module load cmake")
c.append("-D CMAKE_BUILD_TYPE="+build+"")
if OS == "windows":
ext = ""
if platform == "x64":
ext = " Win64"
if (compiler == "V141"):
c.append("-G \"Visual Studio 15 2017"+ext+"\"")
c.append("-T \"V141\"")
ispc_ext = "-vs2015"
elif (compiler == "V140"):
c.append("-G \"Visual Studio 14 2015"+ext+"\"")
c.append("-T \"V140\"")
ispc_ext = "-vs2015"
elif (compiler == "V120"):
c.append("-G \"Visual Studio 12 2013"+ext+"\"")
c.append("-T \"V120\"")
elif (compiler == "V110"):
c.append("-G \"Visual Studio 11 2012"+ext+"\"")
c.append("-T \"V110\"")
elif (compiler == "ICC"):
c.append("-G \"Visual Studio 12 2013"+ext+"\"")
c.append("-T \"Intel C++ Compiler 17.0\"")
elif (compiler == "ICC18"):
c.append("-G \"Visual Studio 12 2013"+ext+"\"")
c.append("-T \"Intel C++ Compiler 18.0\"")
elif (compiler == "ICC17"):
c.append("-G \"Visual Studio 12 2013"+ext+"\"")
c.append("-T \"Intel C++ Compiler 17.0\"")
elif (compiler == "ICC16"):
c.append("-G \"Visual Studio 12 2013"+ext+"\"")
c.append("-T \"Intel C++ Compiler 16.0\"")
elif (compiler == "ICC15"):
c.append("-G \"Visual Studio 12 2013"+ext+"\"")
c.append("-T \"Intel C++ Compiler XE 15.0\"")
elif (compiler == "CLANG"):
c.append("-G \"Visual Studio 12 2013"+ext+"\"")
c.append("-T \"LLVM-vs2013\"")
else:
raise ValueError('unknown compiler: ' + compiler + '')
else:
if (compiler == "ICC18"):
c.append("-D CMAKE_CXX_COMPILER=icpc -D CMAKE_C_COMPILER=icc")
e.append("module load intel/2018")
elif (compiler == "ICC17"):
c.append("-D CMAKE_CXX_COMPILER=icpc -D CMAKE_C_COMPILER=icc")
e.append("module load intel/2017")
elif (compiler == "ICC16"):
c.append("-D CMAKE_CXX_COMPILER=icpc -D CMAKE_C_COMPILER=icc")
e.append("module load intel/2016")
elif (compiler == "ICC15"):
c.append("-D CMAKE_CXX_COMPILER=icpc -D CMAKE_C_COMPILER=icc")
e.append("module load intel/2015")
elif (compiler == "ICC"):
c.append("-D CMAKE_CXX_COMPILER=icpc -D CMAKE_C_COMPILER=icc")
e.append("module load intel")
elif (compiler == "GCC"):
c.append("-D CMAKE_CXX_COMPILER=g++ -D CMAKE_C_COMPILER=gcc")
elif (compiler == "CLANG4"):
c.append("-D CMAKE_CXX_COMPILER=clang++ -D CMAKE_C_COMPILER=clang")
e.append("module load clang/4")
elif (compiler == "CLANG3.9"):
c.append("-D CMAKE_CXX_COMPILER=clang++ -D CMAKE_C_COMPILER=clang")
e.append("module load clang/3.9")
elif (compiler == "CLANG3.8"):
c.append("-D CMAKE_CXX_COMPILER=clang++ -D CMAKE_C_COMPILER=clang")
e.append("module load clang/3.8")
elif (compiler == "CLANG"):
c.append("-D CMAKE_CXX_COMPILER=clang++ -D CMAKE_C_COMPILER=clang")
else:
raise ValueError('unknown compiler: ' + compiler + '')
if type(isa) == str:
c.append("-D EMBREE_MAX_ISA="+isa+"")
else:
c.append("-D EMBREE_MAX_ISA=NONE")
if "SSE2" in isa: c.append("-D EMBREE_ISA_SSE2=ON")
else : c.append("-D EMBREE_ISA_SSE2=OFF")
if "SSE42" in isa: c.append("-D EMBREE_ISA_SSE42=ON")
else : c.append("-D EMBREE_ISA_SSE42=OFF")
if "AVX" in isa: c.append("-D EMBREE_ISA_AVX=ON")
else : c.append("-D EMBREE_ISA_AVX=OFF")
if "AVX2" in isa: c.append("-D EMBREE_ISA_AVX2=ON")
else : c.append("-D EMBREE_ISA_AVX2=OFF")
if "AVX512KNL" in isa: c.append("-D EMBREE_ISA_AVX512KNL=ON")
else : c.append("-D EMBREE_ISA_AVX512KNL=OFF")
if "AVX512SKX" in isa: c.append("-D EMBREE_ISA_AVX512SKX=ON")
else : c.append("-D EMBREE_ISA_AVX512SKX=OFF")
c.append("-D EMBREE_TASKING_SYSTEM="+tasking+"")
c.append("-D EMBREE_TESTING_MEMCHECK="+memcheck+"")
c.append("-D EMBREE_TESTING_INTENSIVE="+intensive+"")
c.append("-D EMBREE_TESTING_SDE="+sde+"")
ispc_enabled = True
if "ISPC_SUPPORT" in config:
c.append("-D EMBREE_ISPC_SUPPORT="+config["ISPC_SUPPORT"])
if config["ISPC_SUPPORT"] == "OFF": name += "-noispc"
ispc_enabled = False
if "STATIC_LIB" in config:
c.append("-D EMBREE_STATIC_LIB="+config["STATIC_LIB"])
if config["STATIC_LIB"] == "ON": name += "-static"
if "TUTORIALS" in config:
c.append("-D EMBREE_TUTORIALS="+config["TUTORIALS"])
if config["TUTORIALS"] == "OFF": name += "-notutorials"
if "BACKFACE_CULLING" in config:
c.append("-D EMBREE_BACKFACE_CULLING="+config["BACKFACE_CULLING"])
if config["BACKFACE_CULLING"] == "ON": name += "-backfaceculling"
if "IGNORE_INVALID_RAYS" in config:
c.append("-D EMBREE_IGNORE_INVALID_RAYS="+config["IGNORE_INVALID_RAYS"])
if config["IGNORE_INVALID_RAYS"] == "ON": name += "-noinvalid"
if "INTERSECTION_FILTER" in config:
c.append("-D EMBREE_INTERSECTION_FILTER="+config["INTERSECTION_FILTER"])
if config["INTERSECTION_FILTER"] == "OFF": name += "-nofilter"
if "RAY_MASK" in config:
c.append("-D EMBREE_RAY_MASK="+config["RAY_MASK"])
if config["RAY_MASK"] == "ON": name += "-raymask"
if "RAY_PACKETS" in config:
c.append("-D EMBREE_RAY_PACKETS="+config["RAY_PACKETS"])
if config["RAY_PACKETS"] == "OFF": name += "-nopackets"
if "STAT_COUNTERS" in config:
c.append("-D EMBREE_STAT_COUNTERS="+config["STAT_COUNTERS"])
if config["STAT_COUNTERS"] == "ON": name += "-stats"
if "TRIS" in config:
c.append("-D EMBREE_GEOMETRY_TRIANGLES="+config["TRIS"])
if config["TRIS"] == "ON": name += "-tris"
if "QUADS" in config:
c.append("-D EMBREE_GEOMETRY_QUADS="+config["QUADS"])
if config["QUADS"] == "ON": name += "-quads"
if "LINES" in config:
c.append("-D EMBREE_GEOMETRY_LINES="+config["LINES"])
if config["LINES"] == "ON": name += "-lines"
if "HAIR" in config:
c.append("-D EMBREE_GEOMETRY_HAIR="+config["HAIR"])
if config["HAIR"] == "ON": name += "-hair"
if "SUBDIV" in config:
c.append("-D EMBREE_GEOMETRY_SUBDIV="+config["SUBDIV"])
if config["SUBDIV"] == "ON": name += "-subdiv"
if "USERGEOM" in config:
c.append("-D EMBREE_GEOMETRY_USER="+config["USERGEOM"])
if config["USERGEOM"] == "ON": name += "-usergeom"
if OS == "linux":
if ispc_enabled: c.append("-D EMBREE_ISPC_EXECUTABLE=/NAS/packages/apps/ispc/1.9.1/ispc")
if tasking == "TBB": c.append("-D EMBREE_TBB_ROOT=/NAS/packages/apps/tbb/tbb-2017-linux")
elif OS == "macosx":
{}
#if ispc_enabled: c.append("-D EMBREE_ISPC_EXECUTABLE="+os.getcwd()+"/dependencies/ispc-v1.9.1-osx/ispc")
#if tasking == "TBB": c.append("-D EMBREE_TBB_ROOT="+os.getcwd()+dash+"dependencies"+dash+"tbb-2017-osx")
elif OS == "windows":
#if ispc_enabled:
#c.append("-D EMBREE_ISPC_EXECUTABLE="+os.getcwd()+dash+"dependencies"+dash+"ispc-v1.9.1-windows"+ispc_ext+dash+"ispc.exe")
if tasking == "TBB":
#tbb_path = os.getcwd()+dash+"dependencies"+dash+"tbb-2017-windows"
#c.append("-D EMBREE_TBB_ROOT="+tbb_path)
if platform == "x64":
e.append("set PATH="+tbb_path+"\\bin\\intel64\\vc12;%PATH%")
else:
e.append("set PATH="+tbb_path+"\\bin\\ia32\\vc12;%PATH%")
else:
sys.stderr.write("unknown operating system "+OS)
sys.exit(1)
if "klocwork" in config:
c.append("-D EMBREE_TESTING_KLOCWORK="+config["klocwork"])
if "package" in config:
c.append("-D EMBREE_TESTING_PACKAGE=ON")
c.append("-D EMBREE_TUTORIALS_IMAGE_MAGICK=OFF")
c.append("-D EMBREE_TUTORIALS_LIBJPEG=OFF")
c.append("-D EMBREE_TUTORIALS_LIBPNG=OFF")
c.append("-D EMBREE_TUTORIALS_OPENEXR=OFF")
if OS == "linux" and config["package"] == "ZIP":
c.append("-D EMBREE_ZIP_MODE=ON")
c.append("-D CMAKE_SKIP_INSTALL_RPATH=ON")
c.append("-D CMAKE_INSTALL_INCLUDEDIR=include")
c.append("-D CMAKE_INSTALL_LIBDIR=lib")
c.append("-D CMAKE_INSTALL_DOCDIR=doc")
c.append("-D CMAKE_INSTALL_BINDIR=bin")
elif OS == "linux" and config["package"] == "RPM":
c.append("-D EMBREE_ZIP_MODE=OFF")
c.append("-D CMAKE_SKIP_INSTALL_RPATH=OFF")
c.append("-D CMAKE_INSTALL_PREFIX=/usr")
c.append("-D EMBREE_TBB_ROOT=/usr")
elif OS == "macosx" and config["package"] == "ZIP":
c.append("-D EMBREE_ZIP_MODE=ON")
c.append("-D CMAKE_SKIP_INSTALL_RPATH=ON")
c.append("-D CMAKE_MACOSX_RPATH=ON")
c.append("-D CMAKE_INSTALL_INCLUDEDIR=include")
c.append("-D CMAKE_INSTALL_LIBDIR=lib")
c.append("-D CMAKE_INSTALL_DOCDIR=doc")
c.append("-D CMAKE_INSTALL_BINDIR=bin")
elif OS == "macosx" and config["package"] == "RPM":
c.append("-D EMBREE_ZIP_MODE=OFF")
c.append("-D CMAKE_SKIP_INSTALL_RPATH=OFF")
c.append("-D CMAKE_INSTALL_PREFIX=/opt/local")
c.append("-D CMAKE_INSTALL_INCLUDEDIR=include")
c.append("-D CMAKE_INSTALL_LIBDIR=lib")
c.append("-D CMAKE_INSTALL_DOCDIR=../../Applications/Embree2/doc")
c.append("-D CMAKE_INSTALL_BINDIR=../../Applications/Embree2/bin")
c.append("-D EMBREE_TBB_ROOT=/opt/local")
elif OS == "windows" and config["package"] == "ZIP":
c.append("-D EMBREE_ZIP_MODE=ON")
c.append("-D CMAKE_INSTALL_INCLUDEDIR=include")
c.append("-D CMAKE_INSTALL_LIBDIR=lib")
c.append("-D CMAKE_INSTALL_DATAROOTDIR=")
c.append("-D CMAKE_INSTALL_DOCDIR=doc")
c.append("-D CMAKE_INSTALL_BINDIR=bin")
elif OS == "windows" and config["package"] == "RPM":
c.append("-D EMBREE_ZIP_MODE=OFF")
c.append("-D CMAKE_INSTALL_INCLUDEDIR=include")
c.append("-D CMAKE_INSTALL_LIBDIR=lib")
c.append("-D CMAKE_INSTALL_DATAROOTDIR=")
c.append("-D CMAKE_INSTALL_DOCDIR=doc")
c.append("-D CMAKE_INSTALL_BINDIR=bin")
else:
sys.stderr.write("unknown package mode: "+OS+":"+config["package"])
sys.exit(1)
return [name,build,skip_testing,benchmark,c,e]
# runs all tests for specified host machine
def runConfig(cfg):
[name,build,skip_testing,benchmark,conf,env] = createTest(cfg,OS)
ctest = ""
ctest += "ctest -VV -S scripts/test.cmake"
if g_cdash != "": ctest += " -D CTEST_DROP_SITE="+g_cdash
ctest += " -D TEST_NAME=\""+name+"\""
if skip_testing: ctest += " -D CTEST_SKIP_TESTING=ON"
else : ctest += " -D CTEST_SKIP_TESTING=OFF"
ctest += " -D CTEST_CONFIGURATION_TYPE=\""+build+"\""
ctest += " -D CTEST_BUILD_OPTIONS=\"" + escape(" ".join(conf))+"\""
if g_debugMode:
print(name)
for e in env: print(' '+e)
print(' '+ctest+'\n')
else:
cmd = ""
for e in env: cmd += e + " && "
cmd += ctest+"\n"
subprocess.check_call(cmd, shell=True)
#if OS == "windows":
# subprocess.Popen(cmd, shell=True).communicate()
#else: # we have to use a login shell to make "module load xxx" work
# cmd = "export http_proxy= && export https_proxy= && " + cmd # cdash submission fails when proxy servers set
# subprocess.Popen(['bash', '-l'], stdin=subprocess.PIPE).communicate(input=cmd.encode("utf-8"))
def parseCommandLine(argv):
global g_cdash
global g_config
global g_mode
global g_intensive
global g_debugMode
if len(argv) == 0:
return;
elif len(argv)>=2 and argv[0] == "--cdash":
g_cdash = argv[1]
parseCommandLine(argv[2:len(argv)])
elif len(argv)>=2 and argv[0] == "--mode":
g_mode = argv[1]
parseCommandLine(argv[2:len(argv)])
elif len(argv)>=1 and argv[0] == "--intensive":
g_intensive = True
parseCommandLine(argv[1:len(argv)])
elif len(argv)>=1 and argv[0] == "--debug":
g_debugMode = True
parseCommandLine(argv[1:len(argv)])
elif len(argv)>=1 and argv[0] == "--help":
printUsage()
return;
elif ':' in argv[0]:
p = argv[0].split(":")
g_config[p[0]] = p[1]
parseCommandLine(argv[1:len(argv)])
else:
sys.stderr.write("unknown command line option: "+argv[0])
sys.exit(1)
parseCommandLine(sys.argv[1:len(sys.argv)])
runConfig(g_config)
Binary file not shown.
Binary file not shown.
Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More