Compare commits
136
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c0d1b3a74a | ||
|
|
7c539db74c | ||
|
|
68f0344542 | ||
|
|
4f0de63859 | ||
|
|
c8ea4294ae | ||
|
|
4243db227a | ||
|
|
dc961964ee | ||
|
|
cb1fb07edf | ||
|
|
d7ce521c89 | ||
|
|
3bf2e5d694 | ||
|
|
f3aa55fa73 | ||
|
|
d93226eedf | ||
|
|
2d780d85fb | ||
|
|
e8aa112afa | ||
|
|
c48d21814c | ||
|
|
729ece7292 | ||
|
|
ed8ee37967 | ||
|
|
7a50a2d692 | ||
|
|
357c6f24c5 | ||
|
|
83fcf53b95 | ||
|
|
c6498a29d0 | ||
|
|
6bf725ba7c | ||
|
|
e9a402ecd1 | ||
|
|
2f6af2832d | ||
|
|
640c6daa85 | ||
|
|
512811023f | ||
|
|
c0a1dbb5d8 | ||
|
|
045c418031 | ||
|
|
8956aee21c | ||
|
|
0d9bc8df72 | ||
|
|
ca96c96cb3 | ||
|
|
4c50caa6b1 | ||
|
|
9edba0f4ea | ||
|
|
f4626bb22e | ||
|
|
7d66ef477b | ||
|
|
1b3b7ecb38 | ||
|
|
e082712373 | ||
|
|
185ffc39d3 | ||
|
|
3f4c6ac6e3 | ||
|
|
5e3b4cf0e2 | ||
|
|
dec21a5f65 | ||
|
|
2b0c400355 | ||
|
|
058e820efb | ||
|
|
d633a5541d | ||
|
|
563fa8b32c | ||
|
|
0894d751f1 | ||
|
|
23e8a0389d | ||
|
|
54f29c991b | ||
|
|
fd3af84024 | ||
|
|
a9a868f252 | ||
|
|
870e7adc71 | ||
|
|
bec88b6568 | ||
|
|
85a6d9c54c | ||
|
|
63919c188c | ||
|
|
76892f8577 | ||
|
|
44e783d59d | ||
|
|
0a642420af | ||
|
|
d208cbb4d9 | ||
|
|
0419f1d8cc | ||
|
|
c2309bbf79 | ||
|
|
e9149e8e9a | ||
|
|
c15bb92593 | ||
|
|
a1b56e8adc | ||
|
|
d85aea4c1a | ||
|
|
4498acd035 | ||
|
|
152073d7ac | ||
|
|
a90002157c | ||
|
|
f8c8d55c44 | ||
|
|
97600fb260 | ||
|
|
b6d6cba2a2 | ||
|
|
ead4835d35 | ||
|
|
eb4906c79c | ||
|
|
85b65574bb | ||
|
|
363c005f8e | ||
|
|
4422ca608c | ||
|
|
d38ac50b2b | ||
|
|
4d05b49867 | ||
|
|
a22e54cc49 | ||
|
|
46d131e056 | ||
|
|
f1d23c57ed | ||
|
|
265044e73f | ||
|
|
ca84d3425e | ||
|
|
418ec0bdfb | ||
|
|
2d1f8a6a97 | ||
|
|
9813d6a6ee | ||
|
|
255ab75c5f | ||
|
|
ece6b8345c | ||
|
|
59ec5d0fcd | ||
|
|
2cd05a8b2b | ||
|
|
08e54eb4c1 | ||
|
|
fb13a85505 | ||
|
|
fb81cb34de | ||
|
|
3ceca55050 | ||
|
|
87d45e6096 | ||
|
|
872ced9934 | ||
|
|
f987d717ef | ||
|
|
9b40fcb862 | ||
|
|
19605e0738 | ||
|
|
fe56a4dc3c | ||
|
|
4994f64729 | ||
|
|
7b4af861f4 | ||
|
|
82ef698bcf | ||
|
|
ca70fc388b | ||
|
|
ae06ac06a9 | ||
|
|
e2656563b1 | ||
|
|
752e905ecc | ||
|
|
d9e046d0c3 | ||
|
|
5945b87db9 | ||
|
|
0c92fff315 | ||
|
|
360ad9d0c3 | ||
|
|
6c34e0d090 | ||
|
|
794d90069c | ||
|
|
fb8e4405c7 | ||
|
|
36d53847c7 | ||
|
|
e45aabfb8a | ||
|
|
d66fbeb235 | ||
|
|
af13b7704f | ||
|
|
649d39f3a8 | ||
|
|
9b3362a394 | ||
|
|
fdb80242af | ||
|
|
fa7d1b4f89 | ||
|
|
f6cdaeb732 | ||
|
|
a9d59ed6c8 | ||
|
|
5633e5233d | ||
|
|
2b681c5f27 | ||
|
|
8a8f7c78aa | ||
|
|
159e440014 | ||
|
|
04d8b88026 | ||
|
|
1f8e43141c | ||
|
|
07c35e2ed2 | ||
|
|
a44f900b20 | ||
|
|
141aa737c6 | ||
|
|
f154b5f160 | ||
|
|
7f82ff96ce | ||
|
|
1112474494 | ||
|
|
b486e32e7c |
@@ -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
@@ -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
@@ -17,7 +17,7 @@
|
||||
SET(EMBREE_VERSION_MAJOR 2)
|
||||
SET(EMBREE_VERSION_MINOR 17)
|
||||
SET(EMBREE_VERSION_PATCH 0)
|
||||
SET(EMBREE_VERSION_NOTE "-alpha.0")
|
||||
SET(EMBREE_VERSION_NOTE "")
|
||||
SET(EMBREE_VERSION ${EMBREE_VERSION_MAJOR}.${EMBREE_VERSION_MINOR}.${EMBREE_VERSION_PATCH})
|
||||
MATH(EXPR EMBREE_VERSION_NUMBER "10000*${EMBREE_VERSION_MAJOR} + 100*${EMBREE_VERSION_MINOR} + ${EMBREE_VERSION_PATCH}")
|
||||
SET(CPACK_RPM_PACKAGE_RELEASE 1)
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -66,7 +66,7 @@ ELSE ()
|
||||
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)
|
||||
@@ -117,7 +117,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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
+17
-2
@@ -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
|
||||
@@ -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,12 @@ 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
|
||||
|
||||
IF (NOT APPLE)
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -inline-factor=200") # increase default inline factors limits by 2x
|
||||
ELSE(NOT APPLE)
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -inline-factor=150")
|
||||
ENDIF()
|
||||
|
||||
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
|
||||
|
||||
@@ -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}")
|
||||
|
||||
@@ -125,7 +125,7 @@ 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)
|
||||
@@ -161,33 +161,18 @@ 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
|
||||
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 +215,6 @@ ELSEIF(APPLE)
|
||||
# Linux specific settings
|
||||
ELSE()
|
||||
|
||||
|
||||
IF (NOT EMBREE_ZIP_MODE)
|
||||
|
||||
SET(CPACK_GENERATOR RPM)
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -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); }
|
||||
|
||||
|
||||
@@ -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
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace embree
|
||||
}
|
||||
|
||||
/*! run this task */
|
||||
__dllexport void TaskScheduler::Task::run (Thread& thread) // FIXME: avoid as many __dllexports as possible
|
||||
void TaskScheduler::Task::run_internal (Thread& thread) // FIXME: avoid as many __dllexports as possible
|
||||
{
|
||||
/* try to run if not already stolen */
|
||||
if (try_switch_state(INITIALIZED,DONE))
|
||||
@@ -71,14 +71,19 @@ namespace embree
|
||||
/* steal until all dependencies have completed */
|
||||
steal_loop(thread,
|
||||
[&] () { return dependencies>0; },
|
||||
[&] () { while (thread.tasks.execute_local(thread,this)); });
|
||||
[&] () { while (thread.tasks.execute_local_internal(thread,this)); });
|
||||
|
||||
/* now signal our parent task that we are finished */
|
||||
if (parent)
|
||||
parent->add_dependencies(-1);
|
||||
}
|
||||
|
||||
__dllexport bool TaskScheduler::TaskQueue::execute_local(Thread& thread, Task* parent)
|
||||
/*! run this task */
|
||||
__dllexport void TaskScheduler::Task::run (Thread& thread) {
|
||||
run_internal(thread);
|
||||
}
|
||||
|
||||
bool TaskScheduler::TaskQueue::execute_local_internal(Thread& thread, Task* parent)
|
||||
{
|
||||
/* stop if we run out of local tasks or reach the waiting task */
|
||||
if (right == 0 || &tasks[right-1] == parent)
|
||||
@@ -86,7 +91,7 @@ namespace embree
|
||||
|
||||
/* execute task */
|
||||
size_t oldRight = right;
|
||||
tasks[right-1].run(thread);
|
||||
tasks[right-1].run_internal(thread);
|
||||
if (right != oldRight) {
|
||||
THROW_RUNTIME_ERROR("you have to wait for spawned subtasks");
|
||||
}
|
||||
@@ -102,6 +107,10 @@ namespace embree
|
||||
return right != 0;
|
||||
}
|
||||
|
||||
__dllexport bool TaskScheduler::TaskQueue::execute_local(Thread& thread, Task* parent) {
|
||||
return execute_local_internal(thread,parent);
|
||||
}
|
||||
|
||||
bool TaskScheduler::TaskQueue::steal(Thread& thread)
|
||||
{
|
||||
size_t l = left;
|
||||
@@ -316,7 +325,7 @@ namespace embree
|
||||
{
|
||||
Thread* thread = TaskScheduler::thread();
|
||||
if (thread == nullptr) return true;
|
||||
while (thread->tasks.execute_local(*thread,thread->task)) {};
|
||||
while (thread->tasks.execute_local_internal(*thread,thread->task)) {};
|
||||
return thread->scheduler->cancellingException == nullptr;
|
||||
}
|
||||
|
||||
@@ -335,7 +344,7 @@ namespace embree
|
||||
[&] () { return anyTasksRunning > 0; },
|
||||
[&] () {
|
||||
anyTasksRunning++;
|
||||
while (thread.tasks.execute_local(thread,nullptr));
|
||||
while (thread.tasks.execute_local_internal(thread,nullptr));
|
||||
anyTasksRunning--;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -109,6 +109,8 @@ namespace embree
|
||||
/*! run this task */
|
||||
__dllexport void run(Thread& thread);
|
||||
|
||||
void run_internal(Thread& thread);
|
||||
|
||||
public:
|
||||
std::atomic<int> state; //!< state this task is in
|
||||
std::atomic<int> dependencies; //!< dependencies to wait for
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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);
|
||||
|
||||
/*! @} */
|
||||
|
||||
|
||||
@@ -18,4 +18,4 @@
|
||||
#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_STRING "2.17.0"
|
||||
|
||||
@@ -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/" )
|
||||
@@ -208,6 +216,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 +234,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 +243,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 +252,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 +261,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 +270,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)
|
||||
|
||||
+7
-5
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 */
|
||||
@@ -124,18 +125,19 @@ 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 */
|
||||
NodeRef stack[stackSize]; //!< stack of nodes that still need to get traversed
|
||||
NodeRef* stackPtr = stack+1; //!< current stack pointer
|
||||
NodeRef stack[stackSize]; //!< stack of nodes that still need to get traversed
|
||||
NodeRef* stackPtr = stack+1; //!< current stack pointer
|
||||
NodeRef* stackEnd = stack+stackSize;
|
||||
stack[0] = bvh->root;
|
||||
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,9 +34,11 @@
|
||||
|
||||
#define SWITCH_DURING_DOWN_TRAVERSAL 1
|
||||
#define FORCE_SINGLE_MODE 0
|
||||
|
||||
#define ENABLE_FAST_COHERENT_CODEPATHS 1
|
||||
|
||||
|
||||
#define STREAM_IN_HYBRID 0
|
||||
|
||||
namespace embree
|
||||
{
|
||||
namespace isa
|
||||
@@ -124,13 +126,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
|
||||
@@ -145,7 +149,6 @@ namespace embree
|
||||
size_t valid_bits = movemask(valid);
|
||||
if (unlikely(valid_bits == 0)) return;
|
||||
|
||||
|
||||
/* verify correct input */
|
||||
assert(all(valid,ray.valid()));
|
||||
assert(all(valid,ray.tnear >= 0.0f));
|
||||
@@ -177,12 +180,9 @@ namespace embree
|
||||
/* determine switch threshold based on flags */
|
||||
const size_t switchThreshold = (context->user && isCoherent(context->user->flags)) ? 2 : switchThresholdIncoherent;
|
||||
|
||||
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));
|
||||
|
||||
octant = select(valid,octant,vint<K>(0xffffffff));
|
||||
vint<K> octant = ray.octant();
|
||||
octant = select(valid, octant, vint<K>(0xffffffff));
|
||||
|
||||
do
|
||||
{
|
||||
const size_t valid_index = __bsf(valid_bits);
|
||||
@@ -264,7 +264,7 @@ namespace embree
|
||||
const NodeRef child = node->children[i];
|
||||
if (unlikely(child == BVH::emptyNode)) break;
|
||||
vfloat<K> lnearP;
|
||||
vbool<K> lhit(valid_node);
|
||||
vbool<K> lhit = valid_node;
|
||||
BVHNNodeIntersectorK<N,K,types,robust>::intersect(nodeRef,i,org,ray_dir,rdir,org_rdir,ray_tnear,ray_tfar,ray.time,lnearP,lhit);
|
||||
|
||||
/* if we hit the child we choose to continue with that child if it
|
||||
@@ -368,8 +368,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)
|
||||
@@ -407,7 +412,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
|
||||
@@ -434,8 +439,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;
|
||||
@@ -448,7 +453,7 @@ namespace embree
|
||||
do {
|
||||
const size_t i = __bscf(m_frusta_node);
|
||||
vfloat<K> lnearP;
|
||||
vbool<K> lhit( false );
|
||||
vbool<K> lhit = false; // motion blur is not supported, so the initial value will be ignored
|
||||
STAT3(normal.trav_nodes,1,1,1);
|
||||
BVHNNodeIntersectorK<N,K,types,robust>::intersect(nodeRef,i,org,ray_dir,rdir,org_rdir,ray_tnear,ray_tfar,ray.time,lnearP,lhit);
|
||||
|
||||
@@ -493,7 +498,6 @@ namespace embree
|
||||
std::swap(stackPtr[-3],stackPtr[-2]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* intersect leaf */
|
||||
@@ -506,17 +510,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;
|
||||
@@ -597,13 +597,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
|
||||
@@ -615,7 +617,7 @@ namespace embree
|
||||
#endif
|
||||
|
||||
/* return if there are no valid rays */
|
||||
const size_t valid_bits = movemask(valid);
|
||||
size_t valid_bits = movemask(valid);
|
||||
if (unlikely(valid_bits == 0)) return;
|
||||
|
||||
/* verify correct input */
|
||||
@@ -633,6 +635,154 @@ namespace embree
|
||||
const Vec3vf<K> org(ray_org), org_rdir = org * rdir;
|
||||
ray_tnear = select(valid,ray_tnear,vfloat<K>(pos_inf));
|
||||
ray_tfar = select(valid,ray_tfar ,vfloat<K>(neg_inf));
|
||||
|
||||
#if STREAM_IN_HYBRID == 1
|
||||
Vec3vi<K> nearXYZ;
|
||||
nearXYZ.x = select(rdir.x >= 0.0f,vint<K>(0*(int)sizeof(vfloat<N>)),vint<K>(1*(int)sizeof(vfloat<N>)));
|
||||
nearXYZ.y = select(rdir.y >= 0.0f,vint<K>(2*(int)sizeof(vfloat<N>)),vint<K>(3*(int)sizeof(vfloat<N>)));
|
||||
nearXYZ.z = select(rdir.z >= 0.0f,vint<K>(4*(int)sizeof(vfloat<N>)),vint<K>(5*(int)sizeof(vfloat<N>)));
|
||||
|
||||
const int shiftTable[8] = { (int)1 << 0, (int)1 << 1, (int)1 << 2, (int)1 << 3, (int)1 << 4, (int)1 << 5, (int)1 << 6, (int)1 << 7 };
|
||||
|
||||
{
|
||||
|
||||
/*! stack state */
|
||||
StackItemT<NodeRef> stack[stackSizeSingle]; //!< stack of nodes
|
||||
StackItemT<NodeRef>* stackPtr = stack + 1; //!< current stack pointer
|
||||
//StackItemT<NodeRef>* stackEnd = stack + stackSizeSingle;
|
||||
stack[0].ptr = bvh->root;
|
||||
stack[0].dist = movemask(valid);
|
||||
|
||||
|
||||
|
||||
while (1) pop:
|
||||
{
|
||||
if (unlikely(stackPtr == stack)) break;
|
||||
STAT3(shadow.trav_stack_pop,1,1,1);
|
||||
stackPtr--;
|
||||
NodeRef cur = NodeRef(stackPtr->ptr);
|
||||
size_t cur_mask = stackPtr->dist & movemask(!terminated);
|
||||
if (unlikely(cur_mask == 0)) continue;
|
||||
|
||||
while (true)
|
||||
{
|
||||
|
||||
/*! stop if we found a leaf node */
|
||||
if (unlikely(cur.isLeaf())) break;
|
||||
|
||||
const AlignedNode* __restrict__ const node = cur.alignedNode();
|
||||
|
||||
const vfloat<Nx> bminX = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_x));
|
||||
const vfloat<Nx> bmaxX = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->upper_x));
|
||||
const vfloat<Nx> bminY = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_y));
|
||||
const vfloat<Nx> bmaxY = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->upper_y));
|
||||
const vfloat<Nx> bminZ = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_z));
|
||||
const vfloat<Nx> bmaxZ = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->upper_z));
|
||||
|
||||
size_t bits = cur_mask;
|
||||
|
||||
#if defined(__AVX__)
|
||||
STAT3(shadow.trav_hit_boxes[__popcnt(cur_mask)],1,1,1);
|
||||
#endif
|
||||
|
||||
assert(bits);
|
||||
const vbool<Nx> valid_children = bminX <= bmaxX;
|
||||
|
||||
vint<Nx> vmask(zero);
|
||||
do
|
||||
{
|
||||
STAT3(shadow.trav_nodes,1,1,1);
|
||||
|
||||
const size_t i = __bscf(bits);
|
||||
assert(i < K);
|
||||
//const vint<Nx> bitmask = vint<Nx>((int)1 << i);
|
||||
|
||||
const vint<Nx> bitmask(shiftTable[i]);
|
||||
|
||||
const vfloat<Nx> tNearX = msub(bminX, rdir.x[i], org_rdir.x[i]);
|
||||
const vfloat<Nx> tNearY = msub(bminY, rdir.y[i], org_rdir.y[i]);
|
||||
const vfloat<Nx> tNearZ = msub(bminZ, rdir.z[i], org_rdir.z[i]);
|
||||
const vfloat<Nx> tFarX = msub(bmaxX, rdir.x[i], org_rdir.x[i]);
|
||||
const vfloat<Nx> tFarY = msub(bmaxY, rdir.y[i], org_rdir.y[i]);
|
||||
const vfloat<Nx> tFarZ = msub(bmaxZ, rdir.z[i], org_rdir.z[i]);
|
||||
|
||||
const vfloat<Nx> tNear = maxi(mini(tNearX,tFarX), mini(tNearY,tFarY), mini(tNearZ,tFarZ), vfloat<Nx>(ray_tnear[i]));
|
||||
const vfloat<Nx> tFar = mini(maxi(tNearX,tFarX), maxi(tNearY,tFarY), maxi(tNearZ,tFarZ), vfloat<Nx>(ray_tfar[i]));
|
||||
const vbool<Nx> hit_mask = tNear <= tFar;
|
||||
#if defined(__AVX2__)
|
||||
vmask = vmask | (bitmask & vint<Nx>(hit_mask));
|
||||
#else
|
||||
vmask = select(hit_mask, vmask | bitmask, vmask);
|
||||
#endif
|
||||
} while(bits);
|
||||
size_t mask = movemask( (vmask != vint<Nx>(zero)) & valid_children);
|
||||
if (unlikely(mask == 0)) goto pop;
|
||||
|
||||
/* select next child and push other children */
|
||||
//const BaseNode* node = cur.baseNode(types);
|
||||
|
||||
/*! one child is hit, continue with that child */
|
||||
size_t r = __bscf(mask);
|
||||
assert(r < N);
|
||||
cur = node->child(r);
|
||||
cur.prefetch(types);
|
||||
cur_mask = vmask[r];
|
||||
|
||||
/* simple in order sequence */
|
||||
assert(cur != BVH::emptyNode);
|
||||
if (likely(mask == 0)) continue;
|
||||
stackPtr->ptr = cur;
|
||||
stackPtr->dist = cur_mask;
|
||||
stackPtr++;
|
||||
|
||||
for (; ;)
|
||||
{
|
||||
r = __bscf(mask);
|
||||
assert(r < N);
|
||||
|
||||
cur = node->child(r);
|
||||
cur.prefetch(types);
|
||||
cur_mask = vmask[r];
|
||||
assert(cur != BVH::emptyNode);
|
||||
if (likely(mask == 0)) break;
|
||||
stackPtr->ptr = cur;
|
||||
stackPtr->dist = cur_mask;
|
||||
stackPtr++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*! 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 bits = cur_mask;
|
||||
size_t lazy_node = 0;
|
||||
|
||||
for (; bits!=0; )
|
||||
{
|
||||
const size_t k = __bscf(bits);
|
||||
if (PrimitiveIntersectorK::occluded(pre,ray,k,context,prim,num,lazy_node)) {
|
||||
ray.geomID[k] = 0;
|
||||
set(terminated, k);
|
||||
}
|
||||
/* lazy node */
|
||||
if (unlikely(lazy_node)) {
|
||||
stackPtr->ptr = lazy_node;
|
||||
stackPtr->dist = cur_mask;
|
||||
stackPtr++;
|
||||
}
|
||||
}
|
||||
|
||||
if (all(terminated)) break;
|
||||
}
|
||||
|
||||
}
|
||||
// while(valid_bits);
|
||||
|
||||
#else
|
||||
const vfloat<K> inf = vfloat<K>(pos_inf);
|
||||
|
||||
/* compute near/far per ray */
|
||||
@@ -711,33 +861,23 @@ namespace embree
|
||||
const NodeRef child = node->children[i];
|
||||
if (unlikely(child == BVH::emptyNode)) break;
|
||||
vfloat<K> lnearP;
|
||||
vbool<K> lhit(valid_node);
|
||||
vbool<K> lhit = valid_node;
|
||||
BVHNNodeIntersectorK<N,K,types,robust>::intersect(nodeRef,i,org,ray_dir,rdir,org_rdir,ray_tnear,ray_tfar,ray.time,lnearP,lhit);
|
||||
|
||||
/* if we hit the child we choose to continue with that child if it
|
||||
is closer than the current next child, or we push it onto the stack */
|
||||
/* if we hit the child we push the previously hit node onto the stack, and continue with the currently hit child */
|
||||
if (likely(any(lhit)))
|
||||
{
|
||||
assert(sptr_node < stackEnd);
|
||||
assert(child != BVH::emptyNode);
|
||||
const vfloat<K> childDist = select(lhit,lnearP,inf);
|
||||
|
||||
/* push cur node onto stack and continue with hit child */
|
||||
if (any(childDist < curDist))
|
||||
{
|
||||
if (likely(cur != BVH::emptyNode)) {
|
||||
*sptr_node = cur; sptr_node++;
|
||||
*sptr_near = curDist; sptr_near++;
|
||||
}
|
||||
curDist = childDist;
|
||||
cur = child;
|
||||
}
|
||||
|
||||
/* push hit child onto stack */
|
||||
else {
|
||||
*sptr_node = child; sptr_node++;
|
||||
*sptr_near = childDist; sptr_near++;
|
||||
/* push 'cur' node onto stack and continue with hit child */
|
||||
if (likely(cur != BVH::emptyNode)) {
|
||||
*sptr_node = cur; sptr_node++;
|
||||
*sptr_near = curDist; sptr_near++;
|
||||
}
|
||||
curDist = childDist;
|
||||
cur = child;
|
||||
}
|
||||
}
|
||||
if (unlikely(cur == BVH::emptyNode))
|
||||
@@ -772,23 +912,31 @@ namespace embree
|
||||
size_t items; const Primitive* prim = (Primitive*) cur.leaf(items);
|
||||
|
||||
size_t lazy_node = 0;
|
||||
#if defined(__AVX__)
|
||||
STAT3(shadow.trav_hit_boxes[popcnt(vbool<K>(!terminated))],1,1,1);
|
||||
#endif
|
||||
|
||||
terminated |= PrimitiveIntersectorK::occluded(!terminated,pre,ray,context,prim,items,lazy_node);
|
||||
if (all(terminated)) break;
|
||||
ray_tfar = select(terminated,vfloat<K>(neg_inf),ray_tfar);
|
||||
ray_tfar = select(terminated, vfloat<K>(neg_inf), ray_tfar); // ignore node intersections for terminated rays
|
||||
|
||||
if (unlikely(lazy_node)) {
|
||||
*sptr_node = lazy_node; sptr_node++;
|
||||
*sptr_near = neg_inf; sptr_near++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
vint<K>::store(valid & terminated,&ray.geomID,0);
|
||||
AVX_ZERO_UPPER();
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
@@ -802,7 +950,7 @@ namespace embree
|
||||
/* verify correct input */
|
||||
assert(all(valid,ray.valid()));
|
||||
assert(all(valid,ray.tnear >= 0.0f));
|
||||
assert(!(types & BVH_MB) || all(valid,(ray.time >= 0.0f) & (ray.time <= 1.0f)));
|
||||
assert(!(types & BVH_MB) || all(valid, (ray.time >= 0.0f) & (ray.time <= 1.0f)));
|
||||
Precalculations pre(valid,ray);
|
||||
|
||||
/* load ray */
|
||||
@@ -815,27 +963,24 @@ namespace embree
|
||||
const Vec3vf<K> org(ray_org);
|
||||
const Vec3vf<K> org_rdir = org * rdir;
|
||||
|
||||
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));
|
||||
|
||||
octant = select(valid,octant,vint<K>(0xffffffff));
|
||||
vint<K> octant = ray.octant();
|
||||
octant = select(valid, octant, vint<K>(0xffffffff));
|
||||
|
||||
do
|
||||
{
|
||||
const size_t valid_index = __bsf(valid_bits);
|
||||
vbool<K> octant_valid = octant[valid_index] == octant;
|
||||
valid_bits &= ~(size_t)movemask(octant_valid);
|
||||
|
||||
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 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));
|
||||
|
||||
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);
|
||||
StackItemMaskT<NodeRef> stack[stackSizeSingle]; //!< stack of nodes
|
||||
StackItemMaskT<NodeRef>* stackPtr = stack + 1; //!< current stack pointer
|
||||
stack[0].ptr = bvh->root;
|
||||
stack[0].mask = (unsigned int)movemask(octant_valid);
|
||||
|
||||
while (1) pop:
|
||||
{
|
||||
@@ -846,7 +991,7 @@ namespace embree
|
||||
NodeRef cur = NodeRef(stackPtr->ptr);
|
||||
|
||||
/* cull node of active rays have already been terminated */
|
||||
unsigned int m_active = stackPtr->dist & (~movemask(terminated));
|
||||
unsigned int m_active = stackPtr->mask & (~movemask(terminated));
|
||||
|
||||
if (unlikely(m_active == 0)) continue;
|
||||
|
||||
@@ -857,8 +1002,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;
|
||||
@@ -871,7 +1016,7 @@ namespace embree
|
||||
do {
|
||||
const size_t i = __bscf(m_frusta_node);
|
||||
vfloat<K> lnearP;
|
||||
vbool<K> lhit( false );
|
||||
vbool<K> lhit = false; // motion blur is not supported, so the initial value will be ignored
|
||||
STAT3(normal.trav_nodes,1,1,1);
|
||||
BVHNNodeIntersectorK<N,K,types,robust>::intersect(nodeRef,i,org,ray_dir,rdir,org_rdir,ray_tnear,ray_tfar,ray.time,lnearP,lhit);
|
||||
|
||||
@@ -883,11 +1028,11 @@ namespace embree
|
||||
if (likely(cur != BVH::emptyNode)) {
|
||||
num_child_hits++;
|
||||
stackPtr->ptr = cur;
|
||||
stackPtr->dist = m_active;
|
||||
stackPtr->mask = m_active;
|
||||
stackPtr++;
|
||||
}
|
||||
cur = child;
|
||||
m_active = movemask(lhit);
|
||||
m_active = (unsigned int)movemask(lhit);
|
||||
}
|
||||
} while(m_frusta_node);
|
||||
|
||||
@@ -907,20 +1052,18 @@ namespace embree
|
||||
terminated |= PrimitiveIntersectorK::occluded(!terminated,pre,ray,context,prim,items,lazy_node);
|
||||
octant_valid &= !terminated;
|
||||
if (unlikely(none(octant_valid))) break;
|
||||
ray_tfar = select(terminated, vfloat<K>(neg_inf), ray_tfar); // ignore node intersections for terminated rays
|
||||
|
||||
if (unlikely(lazy_node)) {
|
||||
stackPtr->ptr = lazy_node;
|
||||
stackPtr->dist = movemask(octant_valid);
|
||||
stackPtr->mask = (unsigned int)movemask(octant_valid);
|
||||
stackPtr++;
|
||||
}
|
||||
}
|
||||
|
||||
} while(valid_bits);
|
||||
vint<K>::store(valid & terminated,&ray.geomID,0);
|
||||
vint<K>::store(valid & terminated, &ray.geomID, 0);
|
||||
|
||||
AVX_ZERO_UPPER();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -23,9 +23,9 @@ namespace embree
|
||||
namespace isa
|
||||
{
|
||||
template<int N, int Nx>
|
||||
struct TravRay
|
||||
struct TravRay
|
||||
{
|
||||
__forceinline TravRay () {}
|
||||
__forceinline TravRay() {}
|
||||
|
||||
__forceinline TravRay(const Vec3fa& ray_org, const Vec3fa& ray_dir)
|
||||
: org_xyz(ray_org), dir_xyz(ray_dir)
|
||||
@@ -56,8 +56,8 @@ namespace embree
|
||||
}
|
||||
|
||||
template<int K>
|
||||
__forceinline TravRay (size_t k, const Vec3vf<K> &ray_org, const Vec3vf<K> &ray_dir,
|
||||
const Vec3vf<K> &ray_rdir, const Vec3vi<K>& nearXYZ, const size_t flip = sizeof(vfloat<N>))
|
||||
__forceinline TravRay(size_t k, const Vec3vf<K> &ray_org, const Vec3vf<K> &ray_dir,
|
||||
const Vec3vf<K> &ray_rdir, const Vec3vi<K>& nearXYZ, const size_t flip = sizeof(vfloat<N>))
|
||||
{
|
||||
org = Vec3vf<Nx>(ray_org.x[k], ray_org.y[k], ray_org.z[k]);
|
||||
dir = Vec3vf<Nx>(ray_dir.x[k], ray_dir.y[k], ray_dir.z[k]);
|
||||
@@ -82,7 +82,7 @@ namespace embree
|
||||
#endif
|
||||
}
|
||||
|
||||
__forceinline TravRay (const TravRay& ray)
|
||||
__forceinline TravRay(const TravRay& ray)
|
||||
{
|
||||
org_xyz = ray.org_xyz;
|
||||
dir_xyz = ray.dir_xyz;
|
||||
@@ -127,12 +127,12 @@ namespace embree
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<int N, int Nx>
|
||||
__forceinline size_t intersectNode(const typename BVHN<N>::AlignedNode* node, const TravRay<N,Nx>& ray,
|
||||
const vfloat<Nx>& tnear, const vfloat<Nx>& tfar, vfloat<Nx>& dist);
|
||||
__forceinline size_t intersectNode(const typename BVHN<N>::AlignedNode* node, const TravRay<N,Nx>& ray,
|
||||
const vfloat<Nx>& tnear, const vfloat<Nx>& tfar, vfloat<Nx>& dist);
|
||||
|
||||
template<>
|
||||
__forceinline size_t intersectNode<4,4>(const typename BVH4::AlignedNode* node, const TravRay<4,4>& ray,
|
||||
const vfloat4& tnear, const vfloat4& tfar, vfloat4& dist)
|
||||
__forceinline size_t intersectNode<4,4>(const typename BVH4::AlignedNode* node, const TravRay<4,4>& ray,
|
||||
const vfloat4& tnear, const vfloat4& tfar, vfloat4& dist)
|
||||
{
|
||||
#if defined(__AVX2__)
|
||||
const vfloat4 tNearX = msub(vfloat4::load((float*)((const char*)&node->lower_x+ray.nearX)), ray.rdir.x, ray.org_rdir.x);
|
||||
@@ -173,8 +173,8 @@ namespace embree
|
||||
#if defined(__AVX__)
|
||||
|
||||
template<>
|
||||
__forceinline size_t intersectNode<8,8>(const typename BVH8::AlignedNode* node, const TravRay<8,8>& ray,
|
||||
const vfloat8& tnear, const vfloat8& tfar, vfloat8& dist)
|
||||
__forceinline size_t intersectNode<8,8>(const typename BVH8::AlignedNode* node, const TravRay<8,8>& ray,
|
||||
const vfloat8& tnear, const vfloat8& tfar, vfloat8& dist)
|
||||
{
|
||||
#if defined(__AVX2__)
|
||||
const vfloat8 tNearX = msub(vfloat8::load((float*)((const char*)&node->lower_x+ray.nearX)), ray.rdir.x, ray.org_rdir.x);
|
||||
@@ -214,10 +214,10 @@ 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)
|
||||
__forceinline size_t intersectNode<4,16>(const typename BVH4::AlignedNode* node, const TravRay<4,16>& ray, const vfloat16& tnear, const vfloat16& tfar, vfloat16& dist)
|
||||
{
|
||||
const vfloat16 tNearX = msub(vfloat16(*(vfloat4*)((const char*)&node->lower_x+ray.nearX)), ray.rdir.x, ray.org_rdir.x);
|
||||
const vfloat16 tNearY = msub(vfloat16(*(vfloat4*)((const char*)&node->lower_x+ray.nearY)), ray.rdir.y, ray.org_rdir.y);
|
||||
@@ -234,9 +234,8 @@ 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)
|
||||
__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;
|
||||
}
|
||||
@@ -268,10 +255,10 @@ namespace embree
|
||||
#endif
|
||||
|
||||
template<int N, int K>
|
||||
__forceinline vbool<K> intersectNode(const typename BVHN<N>::AlignedNode* node, size_t i,
|
||||
const Vec3vf<K>& org, const Vec3vf<K>& dir, const Vec3vf<K>& rdir, const Vec3vf<K>& org_rdir,
|
||||
const vfloat<K>& tnear, const vfloat<K>& tfar, vfloat<K>& dist)
|
||||
|
||||
__forceinline vbool<K> intersectNode(const typename BVHN<N>::AlignedNode* node, size_t i,
|
||||
const Vec3vf<K>& org, const Vec3vf<K>& dir, const Vec3vf<K>& rdir, const Vec3vf<K>& org_rdir,
|
||||
const vfloat<K>& tnear, const vfloat<K>& tfar, vfloat<K>& dist)
|
||||
|
||||
{
|
||||
#if defined(__AVX2__)
|
||||
const vfloat<K> lclipMinX = msub(node->lower_x[i],rdir.x,org_rdir.x);
|
||||
@@ -319,8 +306,8 @@ namespace embree
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<int N,int Nx>
|
||||
__forceinline size_t intersectNodeRobust(const typename BVHN<N>::AlignedNode* node, const TravRay<N,Nx>& ray,
|
||||
const vfloat<Nx>& tnear, const vfloat<Nx>& tfar, vfloat<Nx>& dist)
|
||||
__forceinline size_t intersectNodeRobust(const typename BVHN<N>::AlignedNode* node, const TravRay<N,Nx>& ray,
|
||||
const vfloat<Nx>& tnear, const vfloat<Nx>& tfar, vfloat<Nx>& dist)
|
||||
{
|
||||
const vfloat<N> tNearX = (vfloat<N>::load((float*)((const char*)&node->lower_x+ray.nearX)) - ray.org.x) * ray.rdir.x;
|
||||
const vfloat<N> tNearY = (vfloat<N>::load((float*)((const char*)&node->lower_x+ray.nearY)) - ray.org.y) * ray.rdir.y;
|
||||
@@ -338,11 +325,11 @@ 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,
|
||||
const vfloat<16>& tnear, const vfloat<16>& tfar, vfloat<16>& dist)
|
||||
__forceinline size_t intersectNodeRobust<4,16>(const typename BVHN<4>::AlignedNode* node, const TravRay<4,16>& ray,
|
||||
const vfloat<16>& tnear, const vfloat<16>& tfar, vfloat<16>& dist)
|
||||
{
|
||||
const vfloat16 tNearX = (vfloat16(*(vfloat<4>*)((const char*)&node->lower_x+ray.nearX)) - ray.org.x) * ray.rdir.x;
|
||||
const vfloat16 tNearY = (vfloat16(*(vfloat<4>*)((const char*)&node->lower_x+ray.nearY)) - ray.org.y) * ray.rdir.y;
|
||||
@@ -361,8 +348,8 @@ namespace embree
|
||||
}
|
||||
|
||||
template<>
|
||||
__forceinline size_t intersectNodeRobust<8,16>(const typename BVHN<8>::AlignedNode* node, const TravRay<8,16>& ray,
|
||||
const vfloat<16>& tnear, const vfloat<16>& tfar, vfloat<16>& dist)
|
||||
__forceinline size_t intersectNodeRobust<8,16>(const typename BVHN<8>::AlignedNode* node, const TravRay<8,16>& ray,
|
||||
const vfloat<16>& tnear, const vfloat<16>& tfar, vfloat<16>& dist)
|
||||
{
|
||||
const vfloat16 tNearX = (vfloat16(*(vfloat<8>*)((const char*)&node->lower_x+ray.nearX)) - ray.org.x) * ray.rdir.x;
|
||||
const vfloat16 tNearY = (vfloat16(*(vfloat<8>*)((const char*)&node->lower_x+ray.nearY)) - ray.org.y) * ray.rdir.y;
|
||||
@@ -383,9 +370,9 @@ namespace embree
|
||||
#endif
|
||||
|
||||
template<int N, int K>
|
||||
__forceinline vbool<K> intersectNodeRobust(const typename BVHN<N>::AlignedNode* node, size_t i,
|
||||
const Vec3vf<K>& org, const Vec3vf<K>& dir, const Vec3vf<K>& rdir, const Vec3vf<K>& org_rdir,
|
||||
const vfloat<K>& tnear, const vfloat<K>& tfar, vfloat<K>& dist)
|
||||
__forceinline vbool<K> intersectNodeRobust(const typename BVHN<N>::AlignedNode* node, size_t i,
|
||||
const Vec3vf<K>& org, const Vec3vf<K>& dir, const Vec3vf<K>& rdir, const Vec3vf<K>& org_rdir,
|
||||
const vfloat<K>& tnear, const vfloat<K>& tfar, vfloat<K>& dist)
|
||||
{
|
||||
// FIXME: use per instruction rounding for AVX512
|
||||
const vfloat<K> lclipMinX = (node->lower_x[i] - org.x) * rdir.x;
|
||||
@@ -408,7 +395,7 @@ namespace embree
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<int N>
|
||||
__forceinline size_t intersectNode(const typename BVHN<N>::AlignedNodeMB* node, const TravRay<N,N>& ray, const vfloat<N>& tnear, const vfloat<N>& tfar, const float time, vfloat<N>& dist)
|
||||
__forceinline size_t intersectNode(const typename BVHN<N>::AlignedNodeMB* node, const TravRay<N,N>& ray, const vfloat<N>& tnear, const vfloat<N>& tfar, const float time, vfloat<N>& dist)
|
||||
{
|
||||
const vfloat<N>* pNearX = (const vfloat<N>*)((const char*)&node->lower_x+ray.nearX);
|
||||
const vfloat<N>* pNearY = (const vfloat<N>*)((const char*)&node->lower_x+ray.nearY);
|
||||
@@ -509,7 +496,7 @@ namespace embree
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<int N>
|
||||
__forceinline size_t intersectNodeRobust(const typename BVHN<N>::AlignedNodeMB* node, const TravRay<N,N>& ray, const vfloat<N>& tnear, const vfloat<N>& tfar, const float time, vfloat<N>& dist)
|
||||
__forceinline size_t intersectNodeRobust(const typename BVHN<N>::AlignedNodeMB* node, const TravRay<N,N>& ray, const vfloat<N>& tnear, const vfloat<N>& tfar, const float time, vfloat<N>& dist)
|
||||
{
|
||||
const vfloat<N>* pNearX = (const vfloat<N>*)((const char*)&node->lower_x+ray.nearX);
|
||||
const vfloat<N>* pNearY = (const vfloat<N>*)((const char*)&node->lower_x+ray.nearY);
|
||||
@@ -579,8 +566,8 @@ namespace embree
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<int N>
|
||||
__forceinline size_t intersectNodeMB4D(const typename BVHN<N>::NodeRef ref, const TravRay<N,N>& ray,
|
||||
const vfloat<N>& tnear, const vfloat<N>& tfar, const float time, vfloat<N>& dist)
|
||||
__forceinline size_t intersectNodeMB4D(const typename BVHN<N>::NodeRef ref, const TravRay<N,N>& ray,
|
||||
const vfloat<N>& tnear, const vfloat<N>& tfar, const float time, vfloat<N>& dist)
|
||||
{
|
||||
const typename BVHN<N>::AlignedNodeMB* node = ref.alignedNodeMB();
|
||||
|
||||
@@ -668,8 +655,8 @@ namespace embree
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<int N>
|
||||
__forceinline size_t intersectNodeMB4DRobust(const typename BVHN<N>::NodeRef ref, const TravRay<N,N>& ray,
|
||||
const vfloat<N>& tnear, const vfloat<N>& tfar, const float time, vfloat<N>& dist)
|
||||
__forceinline size_t intersectNodeMB4DRobust(const typename BVHN<N>::NodeRef ref, const TravRay<N,N>& ray,
|
||||
const vfloat<N>& tnear, const vfloat<N>& tfar, const float time, vfloat<N>& dist)
|
||||
{
|
||||
const typename BVHN<N>::AlignedNodeMB* node = ref.alignedNodeMB();
|
||||
|
||||
@@ -700,9 +687,9 @@ namespace embree
|
||||
}
|
||||
|
||||
template<int N, int K>
|
||||
__forceinline vbool<K> intersectNodeMB4DRobust(const typename BVHN<N>::NodeRef ref, const size_t i,
|
||||
const Vec3vf<K>& org, const Vec3vf<K>& dir, const Vec3vf<K>& rdir, const Vec3vf<K>& org_rdir,
|
||||
const vfloat<K>& tnear, const vfloat<K>& tfar, const vfloat<K>& time, vfloat<K>& dist)
|
||||
__forceinline vbool<K> intersectNodeMB4DRobust(const typename BVHN<N>::NodeRef ref, const size_t i,
|
||||
const Vec3vf<K>& org, const Vec3vf<K>& dir, const Vec3vf<K>& rdir, const Vec3vf<K>& org_rdir,
|
||||
const vfloat<K>& tnear, const vfloat<K>& tfar, const vfloat<K>& time, vfloat<K>& dist)
|
||||
{
|
||||
const typename BVHN<N>::AlignedNodeMB* node = ref.alignedNodeMB();
|
||||
|
||||
@@ -739,10 +726,10 @@ namespace embree
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<int N, int Nx>
|
||||
__forceinline size_t intersectNode(const typename BVHN<N>::QuantizedNode* node, const TravRay<N,Nx>& ray, const vfloat<Nx>& tnear, const vfloat<Nx>& tfar, vfloat<Nx>& dist);
|
||||
__forceinline size_t intersectNode(const typename BVHN<N>::QuantizedNode* node, const TravRay<N,Nx>& ray, const vfloat<Nx>& tnear, const vfloat<Nx>& tfar, vfloat<Nx>& dist);
|
||||
|
||||
template<>
|
||||
__forceinline size_t intersectNode<4,4>(const typename BVH4::QuantizedNode* node, const TravRay<4,4>& ray, const vfloat4& tnear, const vfloat4& tfar, vfloat4& dist)
|
||||
__forceinline size_t intersectNode<4,4>(const typename BVH4::QuantizedNode* node, const TravRay<4,4>& ray, const vfloat4& tnear, const vfloat4& tfar, vfloat4& dist)
|
||||
{
|
||||
const vfloat4 start_x(node->start.x);
|
||||
const vfloat4 scale_x(node->scale.x);
|
||||
@@ -796,7 +783,7 @@ namespace embree
|
||||
#if defined(__AVX__)
|
||||
|
||||
template<>
|
||||
__forceinline size_t intersectNode<8,8>(const typename BVH8::QuantizedNode* node, const TravRay<8,8>& ray, const vfloat8& tnear, const vfloat8& tfar, vfloat8& dist)
|
||||
__forceinline size_t intersectNode<8,8>(const typename BVH8::QuantizedNode* node, const TravRay<8,8>& ray, const vfloat8& tnear, const vfloat8& tfar, vfloat8& dist)
|
||||
{
|
||||
const vfloat8 start_x(node->start.x);
|
||||
const vfloat8 scale_x(node->scale.x);
|
||||
@@ -849,10 +836,10 @@ 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)
|
||||
__forceinline size_t intersectNode<4,16>(const typename BVH4::QuantizedNode* node, const TravRay<4,16>& ray, const vfloat16& tnear, const vfloat16& tfar, vfloat16& dist)
|
||||
{
|
||||
const vfloat16 start_x(node->start.x);
|
||||
const vfloat16 scale_x(node->scale.x);
|
||||
@@ -882,9 +869,8 @@ 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)
|
||||
__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;
|
||||
}
|
||||
@@ -932,8 +894,8 @@ namespace embree
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<int N>
|
||||
__forceinline size_t intersectNode(const typename BVHN<N>::UnalignedNode* node, const TravRay<N,N>& ray,
|
||||
const vfloat<N>& tnear, const vfloat<N>& tfar, vfloat<N>& dist)
|
||||
__forceinline size_t intersectNode(const typename BVHN<N>::UnalignedNode* node, const TravRay<N,N>& ray,
|
||||
const vfloat<N>& tnear, const vfloat<N>& tfar, vfloat<N>& dist)
|
||||
{
|
||||
const Vec3vf<N> dir = xfmVector(node->naabb,ray.dir);
|
||||
//const Vec3vf<N> nrdir = Vec3vf<N>(vfloat<N>(-1.0f))/dir;
|
||||
@@ -956,9 +918,9 @@ namespace embree
|
||||
}
|
||||
|
||||
template<int N, int K>
|
||||
__forceinline vbool<K> intersectNode(const typename BVHN<N>::UnalignedNode* node, const size_t i,
|
||||
const Vec3vf<K>& org_i, const Vec3vf<K>& dir_i, const Vec3vf<K>& rdir_i, const Vec3vf<K>& org_rdir_i,
|
||||
const vfloat<K>& tnear, const vfloat<K>& tfar, vfloat<K>& dist)
|
||||
__forceinline vbool<K> intersectNode(const typename BVHN<N>::UnalignedNode* node, const size_t i,
|
||||
const Vec3vf<K>& org_i, const Vec3vf<K>& dir_i, const Vec3vf<K>& rdir_i, const Vec3vf<K>& org_rdir_i,
|
||||
const vfloat<K>& tnear, const vfloat<K>& tfar, vfloat<K>& dist)
|
||||
{
|
||||
const AffineSpace3vf<K> naabb(Vec3f(node->naabb.l.vx.x[i],node->naabb.l.vx.y[i],node->naabb.l.vx.z[i]),
|
||||
Vec3f(node->naabb.l.vy.x[i],node->naabb.l.vy.y[i],node->naabb.l.vy.z[i]),
|
||||
@@ -988,8 +950,8 @@ namespace embree
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<int N>
|
||||
__forceinline size_t intersectNode(const typename BVHN<N>::UnalignedNodeMB* node, const TravRay<N,N>& ray,
|
||||
const vfloat<N>& tnear, const vfloat<N>& tfar, const float time, vfloat<N>& dist)
|
||||
__forceinline size_t intersectNode(const typename BVHN<N>::UnalignedNodeMB* node, const TravRay<N,N>& ray,
|
||||
const vfloat<N>& tnear, const vfloat<N>& tfar, const float time, vfloat<N>& dist)
|
||||
{
|
||||
const AffineSpace3vf<N> xfm = node->space0;
|
||||
const Vec3vf<N> b0_lower = zero;
|
||||
@@ -1019,9 +981,9 @@ namespace embree
|
||||
}
|
||||
|
||||
template<int N, int K>
|
||||
__forceinline vbool<K> intersectNode(const typename BVHN<N>::UnalignedNodeMB* node, const size_t i,
|
||||
const Vec3vf<K>& org_i, const Vec3vf<K>& dir_i, const Vec3vf<K>& rdir_i, const Vec3vf<K>& org_rdir_i,
|
||||
const vfloat<K>& tnear, const vfloat<K>& tfar, const vfloat<K>& time, vfloat<K>& dist)
|
||||
__forceinline vbool<K> intersectNode(const typename BVHN<N>::UnalignedNodeMB* node, const size_t i,
|
||||
const Vec3vf<K>& org_i, const Vec3vf<K>& dir_i, const Vec3vf<K>& rdir_i, const Vec3vf<K>& org_rdir_i,
|
||||
const vfloat<K>& tnear, const vfloat<K>& tfar, const vfloat<K>& time, vfloat<K>& dist)
|
||||
{
|
||||
const AffineSpace3vf<K> xfm(Vec3f(node->space0.l.vx.x[i],node->space0.l.vx.y[i],node->space0.l.vx.z[i]),
|
||||
Vec3f(node->space0.l.vy.x[i],node->space0.l.vy.y[i],node->space0.l.vy.z[i]),
|
||||
@@ -1062,7 +1024,7 @@ namespace embree
|
||||
struct BVHNNodeIntersector1;
|
||||
|
||||
template<int N, int Nx>
|
||||
struct BVHNNodeIntersector1<N,Nx,BVH_AN1,false>
|
||||
struct BVHNNodeIntersector1<N,Nx,BVH_AN1,false>
|
||||
{
|
||||
static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,Nx>& ray, const vfloat<Nx>& tnear, const vfloat<Nx>& tfar, const float time, vfloat<Nx>& dist, size_t& mask)
|
||||
{
|
||||
@@ -1073,7 +1035,7 @@ namespace embree
|
||||
};
|
||||
|
||||
template<int N, int Nx>
|
||||
struct BVHNNodeIntersector1<N,Nx,BVH_AN1,true>
|
||||
struct BVHNNodeIntersector1<N,Nx,BVH_AN1,true>
|
||||
{
|
||||
static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,Nx>& ray, const vfloat<Nx>& tnear, const vfloat<Nx>& tfar, const float time, vfloat<Nx>& dist, size_t& mask)
|
||||
{
|
||||
@@ -1084,7 +1046,7 @@ namespace embree
|
||||
};
|
||||
|
||||
template<int N, int Nx>
|
||||
struct BVHNNodeIntersector1<N,Nx,BVH_AN2,false>
|
||||
struct BVHNNodeIntersector1<N,Nx,BVH_AN2,false>
|
||||
{
|
||||
static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,Nx>& ray, const vfloat<N>& tnear, const vfloat<N>& tfar, const float time, vfloat<N>& dist, size_t& mask)
|
||||
{
|
||||
@@ -1095,7 +1057,7 @@ namespace embree
|
||||
};
|
||||
|
||||
template<int N, int Nx>
|
||||
struct BVHNNodeIntersector1<N,Nx,BVH_AN2,true>
|
||||
struct BVHNNodeIntersector1<N,Nx,BVH_AN2,true>
|
||||
{
|
||||
static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,Nx>& ray, const vfloat<N>& tnear, const vfloat<N>& tfar, const float time, vfloat<N>& dist, size_t& mask)
|
||||
{
|
||||
@@ -1106,7 +1068,7 @@ namespace embree
|
||||
};
|
||||
|
||||
template<int N, int Nx>
|
||||
struct BVHNNodeIntersector1<N,Nx,BVH_AN2_AN4D,false>
|
||||
struct BVHNNodeIntersector1<N,Nx,BVH_AN2_AN4D,false>
|
||||
{
|
||||
static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,Nx>& ray, const vfloat<N>& tnear, const vfloat<N>& tfar, const float time, vfloat<N>& dist, size_t& mask)
|
||||
{
|
||||
@@ -1117,7 +1079,7 @@ namespace embree
|
||||
};
|
||||
|
||||
template<int N, int Nx>
|
||||
struct BVHNNodeIntersector1<N,Nx,BVH_AN2_AN4D,true>
|
||||
struct BVHNNodeIntersector1<N,Nx,BVH_AN2_AN4D,true>
|
||||
{
|
||||
static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,Nx>& ray, const vfloat<N>& tnear, const vfloat<N>& tfar, const float time, vfloat<N>& dist, size_t& mask)
|
||||
{
|
||||
@@ -1128,7 +1090,7 @@ namespace embree
|
||||
};
|
||||
|
||||
template<int N, int Nx>
|
||||
struct BVHNNodeIntersector1<N,Nx,BVH_AN1_UN1,false>
|
||||
struct BVHNNodeIntersector1<N,Nx,BVH_AN1_UN1,false>
|
||||
{
|
||||
static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,Nx>& ray, const vfloat<N>& tnear, const vfloat<N>& tfar, const float time, vfloat<N>& dist, size_t& mask)
|
||||
{
|
||||
@@ -1140,7 +1102,7 @@ namespace embree
|
||||
};
|
||||
|
||||
template<int N, int Nx>
|
||||
struct BVHNNodeIntersector1<N,Nx,BVH_AN2_UN2,false>
|
||||
struct BVHNNodeIntersector1<N,Nx,BVH_AN2_UN2,false>
|
||||
{
|
||||
static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,Nx>& ray, const vfloat<N>& tnear, const vfloat<N>& tfar, const float time, vfloat<N>& dist, size_t& mask)
|
||||
{
|
||||
@@ -1152,7 +1114,7 @@ namespace embree
|
||||
};
|
||||
|
||||
template<int N, int Nx>
|
||||
struct BVHNNodeIntersector1<N,Nx,BVH_AN2_AN4D_UN2,false>
|
||||
struct BVHNNodeIntersector1<N,Nx,BVH_AN2_AN4D_UN2,false>
|
||||
{
|
||||
static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,Nx>& ray, const vfloat<N>& tnear, const vfloat<N>& tfar, const float time, vfloat<N>& dist, size_t& mask)
|
||||
{
|
||||
@@ -1164,7 +1126,7 @@ namespace embree
|
||||
};
|
||||
|
||||
template<int N, int Nx>
|
||||
struct BVHNNodeIntersector1<N,Nx,BVH_TN_AN1,false>
|
||||
struct BVHNNodeIntersector1<N,Nx,BVH_TN_AN1,false>
|
||||
{
|
||||
static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,Nx>& ray, const vfloat<N>& tnear, const vfloat<N>& tfar, const float time, vfloat<N>& dist, size_t& mask)
|
||||
{
|
||||
@@ -1175,7 +1137,7 @@ namespace embree
|
||||
};
|
||||
|
||||
template<int N, int Nx>
|
||||
struct BVHNNodeIntersector1<N,Nx,BVH_TN_AN1_AN2,false>
|
||||
struct BVHNNodeIntersector1<N,Nx,BVH_TN_AN1_AN2,false>
|
||||
{
|
||||
static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,Nx>& ray, const vfloat<N>& tnear, const vfloat<N>& tfar, const float time, vfloat<N>& dist, size_t& mask)
|
||||
{
|
||||
@@ -1187,7 +1149,7 @@ namespace embree
|
||||
};
|
||||
|
||||
template<int N, int Nx>
|
||||
struct BVHNNodeIntersector1<N,Nx,BVH_QN1,false>
|
||||
struct BVHNNodeIntersector1<N,Nx,BVH_QN1,false>
|
||||
{
|
||||
static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,Nx>& ray, const vfloat<Nx>& tnear, const vfloat<Nx>& tfar, const float time, vfloat<Nx>& dist, size_t& mask)
|
||||
{
|
||||
@@ -1198,7 +1160,7 @@ namespace embree
|
||||
};
|
||||
|
||||
template<int N, int Nx>
|
||||
struct BVHNNodeIntersector1<N,Nx,BVH_QN1,true>
|
||||
struct BVHNNodeIntersector1<N,Nx,BVH_QN1,true>
|
||||
{
|
||||
static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,Nx>& ray, const vfloat<Nx>& tnear, const vfloat<Nx>& tfar, const float time, vfloat<Nx>& dist, size_t& mask)
|
||||
{
|
||||
@@ -1215,6 +1177,10 @@ namespace embree
|
||||
template<int N, int K>
|
||||
struct BVHNNodeIntersectorK<N,K,BVH_AN1,false>
|
||||
{
|
||||
/* vmask is both an input and an output parameter! Its initial value should be the parent node
|
||||
hit mask, which is used for correctly computing the current hit mask. The parent hit mask
|
||||
is actually required only for motion blur node intersections (because different rays may
|
||||
have different times), so for regular nodes vmask is simply overwritten. */
|
||||
static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const size_t i, const Vec3vf<K>& org, const Vec3vf<K>& dir, const Vec3vf<K>& rdir, const Vec3vf<K>& org_rdir,
|
||||
const vfloat<K>& tnear, const vfloat<K>& tfar, const vfloat<K>& time, vfloat<K>& dist, vbool<K>& vmask)
|
||||
{
|
||||
@@ -1224,7 +1190,7 @@ namespace embree
|
||||
};
|
||||
|
||||
template<int N, int K>
|
||||
struct BVHNNodeIntersectorK<N,K,BVH_AN1,true>
|
||||
struct BVHNNodeIntersectorK<N,K,BVH_AN1,true>
|
||||
{
|
||||
static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const size_t i, const Vec3vf<K>& org, const Vec3vf<K>& dir, const Vec3vf<K>& rdir, const Vec3vf<K>& org_rdir,
|
||||
const vfloat<K>& tnear, const vfloat<K>& tfar, const vfloat<K>& time, vfloat<K>& dist, vbool<K>& vmask)
|
||||
@@ -1257,7 +1223,7 @@ namespace embree
|
||||
};
|
||||
|
||||
template<int N, int K>
|
||||
struct BVHNNodeIntersectorK<N,K,BVH_AN1_UN1,false>
|
||||
struct BVHNNodeIntersectorK<N,K,BVH_AN1_UN1,false>
|
||||
{
|
||||
static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const size_t i,
|
||||
const Vec3vf<K>& org, const Vec3vf<K>& dir, const Vec3vf<K>& rdir, const Vec3vf<K>& org_rdir,
|
||||
@@ -1270,7 +1236,7 @@ namespace embree
|
||||
};
|
||||
|
||||
template<int N, int K>
|
||||
struct BVHNNodeIntersectorK<N,K,BVH_AN2_UN2,false>
|
||||
struct BVHNNodeIntersectorK<N,K,BVH_AN2_UN2,false>
|
||||
{
|
||||
static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const size_t i,
|
||||
const Vec3vf<K>& org, const Vec3vf<K>& dir, const Vec3vf<K>& rdir, const Vec3vf<K>& org_rdir,
|
||||
@@ -1313,10 +1279,11 @@ namespace embree
|
||||
const Vec3vf<K>& org, const Vec3vf<K>& dir, const Vec3vf<K>& rdir, const Vec3vf<K>& org_rdir,
|
||||
const vfloat<K>& tnear, const vfloat<K>& tfar, const vfloat<K>& time, vfloat<K>& dist, vbool<K>& vmask)
|
||||
{
|
||||
if (likely(node.isAlignedNodeMB() || node.isAlignedNodeMB4D()))
|
||||
if (likely(node.isAlignedNodeMB() || node.isAlignedNodeMB4D())) {
|
||||
vmask &= intersectNodeMB4D<N,K>(node,i,org,dir,rdir,org_rdir,tnear,tfar,time,dist);
|
||||
else /*if (unlikely(node.isUnalignedNodeMB()))*/ {
|
||||
assert(node.isUnalignedNodeMB()); vmask &= intersectNode<N,K>(node.unalignedNodeMB(),i,org,dir,rdir,org_rdir,tnear,tfar,time,dist);
|
||||
} else /*if (unlikely(node.isUnalignedNodeMB()))*/ {
|
||||
assert(node.isUnalignedNodeMB());
|
||||
vmask &= intersectNode<N,K>(node.unalignedNodeMB(),i,org,dir,rdir,org_rdir,tnear,tfar,time,dist);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,391 +0,0 @@
|
||||
// ======================================================================== //
|
||||
// Copyright 2009-2017 Intel Corporation //
|
||||
// //
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); //
|
||||
// you may not use this file except in compliance with the License. //
|
||||
// You may obtain a copy of the License at //
|
||||
// //
|
||||
// http://www.apache.org/licenses/LICENSE-2.0 //
|
||||
// //
|
||||
// Unless required by applicable law or agreed to in writing, software //
|
||||
// distributed under the License is distributed on an "AS IS" BASIS, //
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
|
||||
// See the License for the specific language governing permissions and //
|
||||
// limitations under the License. //
|
||||
// ======================================================================== //
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "bvh.h"
|
||||
#include "bvh_intersector_node.h"
|
||||
#include "bvh_traverser1.h"
|
||||
#include "../common/ray.h"
|
||||
|
||||
namespace embree
|
||||
{
|
||||
namespace isa
|
||||
{
|
||||
/*! BVH single ray intersector for packets. */
|
||||
template<int N, int K, int types, bool robust, typename PrimitiveIntersectorK>
|
||||
class BVHNIntersectorKSingle
|
||||
{
|
||||
/* shortcuts for frequently used types */
|
||||
typedef typename PrimitiveIntersectorK::Precalculations Precalculations;
|
||||
typedef typename PrimitiveIntersectorK::Primitive Primitive;
|
||||
typedef BVHN<N> BVH;
|
||||
typedef typename BVH::NodeRef NodeRef;
|
||||
typedef typename BVH::BaseNode BaseNode;
|
||||
typedef typename BVH::AlignedNode AlignedNode;
|
||||
typedef Vec3<vfloat<N>> Vec3vfN;
|
||||
typedef Vec3<vfloat<K>> Vec3vfK;
|
||||
typedef Vec3<vint<K>> Vec3viK;
|
||||
|
||||
static const size_t stackSizeSingle = 1+(N-1)*BVH::maxDepth;
|
||||
|
||||
/* right now AVX512KNL SIMD extension only for standard node types */
|
||||
static const size_t Nx = types == BVH_AN1 ? vextend<N>::size : N;
|
||||
|
||||
public:
|
||||
|
||||
#if defined(__AVX512F__)
|
||||
__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);
|
||||
const vllong8 ptr_shift = align_shift_right<7>(ptr,ptr);
|
||||
const vbool16 m_leq = d <= dist;
|
||||
const vbool16 m_leq_shift = m_leq << 1;
|
||||
dist = select(m_leq,d,dist);
|
||||
ptr = select(vboold8(m_leq),p,ptr);
|
||||
dist = select(m_leq_shift,dist_shift,dist);
|
||||
ptr = select(vboold8(m_leq_shift),ptr_shift,ptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
static __forceinline void traverseClosestHitNew(const BaseNode* node,
|
||||
NodeRef& cur,
|
||||
size_t mask,
|
||||
const vfloat<Nx>& tNear,
|
||||
StackItemT<NodeRef>*& stackPtr,
|
||||
StackItemT<NodeRef>* stackEnd)
|
||||
{
|
||||
assert(mask != 0);
|
||||
//const BaseNode* node = cur.baseNode(types);
|
||||
#if defined(__AVX512F__)
|
||||
/*! one child is hit, continue with that child */
|
||||
const size_t hits = __popcnt(mask);
|
||||
|
||||
size_t r = __bscf(mask);
|
||||
cur = node->child(r);
|
||||
cur.prefetch(types);
|
||||
if (likely(mask == 0)) {
|
||||
assert(cur != BVH::emptyNode);
|
||||
return;
|
||||
}
|
||||
|
||||
const vllong8 c0(cur);
|
||||
const vfloat16 d0(tNear[r]);
|
||||
r = __bscf(mask);
|
||||
cur = node->child(r);
|
||||
cur.prefetch(types);
|
||||
const vllong8 c1(cur);
|
||||
const vfloat16 d1(tNear[r]);
|
||||
|
||||
const vboolf16 m_dist = d0 <= d1;
|
||||
const vfloat16 d_near = select(m_dist, d0, d1);
|
||||
const vfloat16 d_far = select(m_dist, d1, d0);
|
||||
const vllong8 c_near = select(vboold8(m_dist), c0, c1);
|
||||
const vllong8 c_far = select(vboold8(m_dist), c1, c0);
|
||||
|
||||
if (likely(mask == 0)) {
|
||||
cur = toScalar(c_near);
|
||||
*(float*)&stackPtr[0].dist = toScalar(d_far);
|
||||
stackPtr[0].ptr = toScalar(c_far);
|
||||
stackPtr++;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
r = __bscf(mask);
|
||||
cur = node->child(r);
|
||||
cur.prefetch(types);
|
||||
const vllong8 c2(cur);
|
||||
const vfloat16 d2(tNear[r]);
|
||||
|
||||
const vboolf16 m_dist1 = d_near <= d2;
|
||||
const vfloat16 d_near1 = select(m_dist1, d_near, d2);
|
||||
const vfloat16 d_far1 = select(m_dist1, d2, d_near);
|
||||
const vllong8 c_near1 = select(vboold8(m_dist1), c_near, c2);
|
||||
const vllong8 c_far1 = select(vboold8(m_dist1), c2, c_near);
|
||||
|
||||
const vboolf16 m_dist2 = d_far <= d_far1;
|
||||
const vfloat16 d_near2 = select(m_dist2, d_far , d_far1);
|
||||
const vfloat16 d_far2 = select(m_dist2, d_far1, d_far);
|
||||
const vllong8 c_near2 = select(vboold8(m_dist2), c_far, c_far1);
|
||||
const vllong8 c_far2 = select(vboold8(m_dist2), c_far1, c_far);
|
||||
|
||||
if (likely(mask == 0)) {
|
||||
|
||||
cur = toScalar(c_near1);
|
||||
*(float*)&stackPtr[0].dist = toScalar(d_far2);
|
||||
stackPtr[0].ptr = toScalar(c_far2);
|
||||
*(float*)&stackPtr[1].dist = toScalar(d_near2);
|
||||
stackPtr[1].ptr = toScalar(c_near2);
|
||||
stackPtr+=2;
|
||||
return;
|
||||
}
|
||||
|
||||
vfloat16 dist(pos_inf);
|
||||
vllong8 ptr(zero);
|
||||
|
||||
isort_update(dist,ptr,d0,c0);
|
||||
isort_update(dist,ptr,d1,c1);
|
||||
isort_update(dist,ptr,d2,c2);
|
||||
|
||||
do {
|
||||
const size_t r = __bscf(mask);
|
||||
cur = node->child(r);
|
||||
const vfloat16 new_dist(tNear[r]);
|
||||
const vllong8 new_ptr(cur);
|
||||
cur.prefetch(types);
|
||||
isort_update(dist,ptr,new_dist,new_ptr);
|
||||
} while(mask);
|
||||
|
||||
cur = toScalar(ptr);
|
||||
stackPtr += hits - 1;
|
||||
for (size_t i=0;i<hits-1;i++)
|
||||
{
|
||||
dist = align_shift_right<1>(dist,dist);
|
||||
ptr = align_shift_right<1>(ptr,ptr);
|
||||
stackPtr[-1-i].ptr = toScalar(ptr);
|
||||
*(float*)&stackPtr[-1-i].dist = toScalar(dist);
|
||||
}
|
||||
#else
|
||||
/*! one child is hit, continue with that child */
|
||||
size_t r = __bscf(mask);
|
||||
cur = node->child(r);
|
||||
cur.prefetch(types);
|
||||
if (likely(mask == 0)) {
|
||||
assert(cur != BVH::emptyNode);
|
||||
return;
|
||||
}
|
||||
|
||||
/*! two children are hit, push far child, and continue with closer child */
|
||||
NodeRef c0 = cur;
|
||||
const unsigned int d0 = ((unsigned int*)&tNear)[r];
|
||||
r = __bscf(mask);
|
||||
NodeRef c1 = node->child(r);
|
||||
c1.prefetch(types);
|
||||
const unsigned int d1 = ((unsigned int*)&tNear)[r];
|
||||
|
||||
assert(c0 != BVH::emptyNode);
|
||||
assert(c1 != BVH::emptyNode);
|
||||
if (likely(mask == 0)) {
|
||||
assert(stackPtr < stackEnd);
|
||||
if (d0 < d1) { stackPtr->ptr = c1; stackPtr->dist = d1; stackPtr++; cur = c0; return; }
|
||||
else { stackPtr->ptr = c0; stackPtr->dist = d0; stackPtr++; cur = c1; return; }
|
||||
}
|
||||
|
||||
/*! Here starts the slow path for 3 or 4 hit children. We push
|
||||
* all nodes onto the stack to sort them there. */
|
||||
assert(stackPtr < stackEnd);
|
||||
stackPtr->ptr = c0; stackPtr->dist = d0; stackPtr++;
|
||||
assert(stackPtr < stackEnd);
|
||||
stackPtr->ptr = c1; stackPtr->dist = d1; stackPtr++;
|
||||
|
||||
/*! three children are hit, push all onto stack and sort 3 stack items, continue with closest child */
|
||||
assert(stackPtr < stackEnd);
|
||||
r = __bscf(mask);
|
||||
NodeRef c = node->child(r);
|
||||
c.prefetch(types);
|
||||
unsigned int d = ((unsigned int*)&tNear)[r];
|
||||
stackPtr->ptr = c;
|
||||
stackPtr->dist = d;
|
||||
stackPtr++;
|
||||
assert(c != BVH::emptyNode);
|
||||
if (likely(mask == 0)) {
|
||||
sort(stackPtr[-1],stackPtr[-2],stackPtr[-3]);
|
||||
cur = (NodeRef) stackPtr[-1].ptr; stackPtr--;
|
||||
return;
|
||||
}
|
||||
|
||||
/*! four children are hit, push all onto stack and sort 4 stack items, continue with closest child */
|
||||
assert(stackPtr < stackEnd);
|
||||
r = __bscf(mask);
|
||||
c = node->child(r);
|
||||
c.prefetch(types);
|
||||
d = *(unsigned int*)&tNear[r];
|
||||
stackPtr->ptr = c;
|
||||
stackPtr->dist = d;
|
||||
stackPtr++;
|
||||
assert(c != BVH::emptyNode);
|
||||
if (likely(mask == 0)) {
|
||||
sort(stackPtr[-1],stackPtr[-2],stackPtr[-3],stackPtr[-4]);
|
||||
cur = (NodeRef) stackPtr[-1].ptr; stackPtr--;
|
||||
return;
|
||||
}
|
||||
|
||||
/*! fallback case if more than 4 children are hit */
|
||||
StackItemT<NodeRef>* stackFirst = stackPtr-4;
|
||||
while (1)
|
||||
{
|
||||
assert(stackPtr < stackEnd);
|
||||
r = __bscf(mask);
|
||||
c = node->child(r);
|
||||
c.prefetch(types);
|
||||
d = *(unsigned int*)&tNear[r];
|
||||
stackPtr->ptr = c; stackPtr->dist = d; stackPtr++;
|
||||
assert(c != BVH::emptyNode);
|
||||
if (unlikely(mask == 0)) break;
|
||||
}
|
||||
sort(stackFirst,stackPtr);
|
||||
cur = (NodeRef) stackPtr[-1].ptr; stackPtr--;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void intersect1(const BVH* bvh,
|
||||
NodeRef root,
|
||||
const size_t k,
|
||||
Precalculations& pre,
|
||||
RayK<K>& ray,
|
||||
const Vec3vfK &ray_org,
|
||||
const Vec3vfK &ray_dir,
|
||||
const Vec3vfK &ray_rdir,
|
||||
const vfloat<K> &ray_tnear,
|
||||
const vfloat<K> &ray_tfar,
|
||||
const Vec3viK& nearXYZ,
|
||||
IntersectContext* context)
|
||||
{
|
||||
/*! stack state */
|
||||
StackItemT<NodeRef> stack[stackSizeSingle]; //!< stack of nodes
|
||||
StackItemT<NodeRef>* stackPtr = stack + 1; //!< current stack pointer
|
||||
StackItemT<NodeRef>* stackEnd = stack + stackSizeSingle;
|
||||
stack[0].ptr = root;
|
||||
stack[0].dist = neg_inf;
|
||||
|
||||
/*! load the ray into SIMD registers */
|
||||
TravRay<N,Nx> vray(k,ray_org,ray_dir,ray_rdir,nearXYZ);
|
||||
vfloat<Nx> ray_near(ray_tnear[k]), ray_far(ray_tfar[k]);
|
||||
|
||||
/* pop loop */
|
||||
while (true) pop:
|
||||
{
|
||||
/*! pop next node */
|
||||
if (unlikely(stackPtr == stack)) break;
|
||||
stackPtr--;
|
||||
NodeRef cur = NodeRef(stackPtr->ptr);
|
||||
|
||||
/*! if popped node is too far, pop next one */
|
||||
//if (unlikely(*(float*)&stackPtr->dist > ray.tfar[k])) continue;
|
||||
if (unlikely((int)stackPtr->dist >= *(const int*)&ray.tfar[k])) continue;
|
||||
|
||||
/* downtraversal loop */
|
||||
while (true)
|
||||
{
|
||||
//cur.prefetch(types);
|
||||
/*! stop if we found a leaf node */
|
||||
if (unlikely(cur.isLeaf())) break;
|
||||
STAT3(normal.trav_nodes,1,1,1);
|
||||
|
||||
/* intersect node */
|
||||
size_t mask = 0;
|
||||
vfloat<Nx> tNear;
|
||||
BVHNNodeIntersector1<N,Nx,types,robust>::intersect(cur,vray,ray_near,ray_far,pre.ftime(k),tNear,mask);
|
||||
AlignedNode *node = cur.alignedNode();
|
||||
|
||||
/*! if no child is hit, pop next node */
|
||||
if (unlikely(mask == 0))
|
||||
goto pop;
|
||||
|
||||
/* select next child and push other children */
|
||||
#if defined(__AVX512F__)
|
||||
traverseClosestHitNew(node,cur,mask,tNear,stackPtr,stackEnd);
|
||||
#else
|
||||
BVHNNodeTraverser1<N,Nx,types>::traverseClosestHit(cur,mask,tNear,stackPtr,stackEnd);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*! 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;
|
||||
//const unsigned int old_primID = ray.primID[k];
|
||||
PrimitiveIntersectorK::intersect(pre, ray, k, context, prim, num, lazy_node);
|
||||
|
||||
ray_far = ray.tfar[k];
|
||||
|
||||
/* if (unlikely(lazy_node)) { */
|
||||
/* stackPtr->ptr = lazy_node; */
|
||||
/* stackPtr->dist = neg_inf; */
|
||||
/* stackPtr++; */
|
||||
/* } */
|
||||
}
|
||||
}
|
||||
|
||||
static bool occluded1(const BVH* bvh, NodeRef root, const size_t k, Precalculations& pre,
|
||||
RayK<K>& ray, const Vec3vfK &ray_org, const Vec3vfK &ray_dir, const Vec3vfK &ray_rdir, const vfloat<K> &ray_tnear, const vfloat<K> &ray_tfar,
|
||||
const Vec3viK& nearXYZ, IntersectContext* context)
|
||||
{
|
||||
/*! stack state */
|
||||
NodeRef stack[stackSizeSingle]; //!< stack of nodes that still need to get traversed
|
||||
NodeRef* stackPtr = stack+1; //!< current stack pointer
|
||||
NodeRef* stackEnd = stack+stackSizeSingle;
|
||||
stack[0] = root;
|
||||
|
||||
/*! load the ray into SIMD registers */
|
||||
TravRay<N,Nx> vray(k,ray_org,ray_dir,ray_rdir,nearXYZ);
|
||||
const vfloat<Nx> ray_near(ray_tnear[k]), ray_far(ray_tfar[k]);
|
||||
|
||||
/* pop loop */
|
||||
while (true) pop:
|
||||
{
|
||||
/*! pop next node */
|
||||
if (unlikely(stackPtr == stack)) break;
|
||||
stackPtr--;
|
||||
NodeRef cur = (NodeRef) *stackPtr;
|
||||
|
||||
/* downtraversal loop */
|
||||
while (true)
|
||||
{
|
||||
/*! stop if we found a leaf node */
|
||||
if (unlikely(cur.isLeaf())) break;
|
||||
STAT3(shadow.trav_nodes,1,1,1);
|
||||
|
||||
/* intersect node */
|
||||
size_t mask = 0;
|
||||
vfloat<Nx> tNear;
|
||||
BVHNNodeIntersector1<N,Nx,types,robust>::intersect(cur,vray,ray_near,ray_far,pre.ftime(k),tNear,mask);
|
||||
|
||||
/*! if no child is hit, pop next node */
|
||||
if (unlikely(mask == 0))
|
||||
goto pop;
|
||||
|
||||
/* select next child and push other children */
|
||||
BVHNNodeTraverser1<N,Nx,types>::traverseAnyHit(cur,mask,tNear,stackPtr,stackEnd);
|
||||
}
|
||||
|
||||
/*! 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;
|
||||
if (PrimitiveIntersectorK::occluded(pre,ray,k,context,prim,num,lazy_node)) {
|
||||
ray.geomID[k] = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (unlikely(lazy_node)) {
|
||||
*stackPtr = lazy_node;
|
||||
stackPtr++;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
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);
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -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,17 +116,8 @@ 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);
|
||||
}
|
||||
|
||||
/*! this is a leaf node */
|
||||
@@ -162,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);
|
||||
@@ -172,20 +149,184 @@ 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)
|
||||
{
|
||||
__aligned(64) StackItemMaskCoherent stack[stackSizeSingle]; //!< stack of nodes
|
||||
|
||||
RayK<K>** __restrict__ inputPackets = (RayK<K>**)inputRays;
|
||||
assert(numOctantRays <= MAX_RAYS);
|
||||
BVH* __restrict__ bvh = (BVH*) This->ptr;
|
||||
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;
|
||||
#if 1
|
||||
__aligned(64) Packet<K,false> packet[MAX_INTERNAL_STREAM_SIZE/K];
|
||||
|
||||
assert(numOctantRays <= 32);
|
||||
const size_t numPackets = (numOctantRays+K-1)/K;
|
||||
size_t m_active = 0;
|
||||
for (size_t i = 0; i < numPackets; i++)
|
||||
{
|
||||
const vfloat<K> tnear = inputPackets[i]->tnear;
|
||||
const vfloat<K> tfar = inputPackets[i]->tfar;
|
||||
vbool<K> m_valid = (tnear <= tfar) & (tnear >= 0.0f);
|
||||
m_active |= (size_t)movemask(m_valid) << (K*i);
|
||||
const Vec3vf<K>& org = inputPackets[i]->org;
|
||||
const Vec3vf<K>& dir = inputPackets[i]->dir;
|
||||
vfloat<K> packet_min_dist = max(tnear, 0.0f);
|
||||
vfloat<K> packet_max_dist = select(m_valid, tfar, neg_inf);
|
||||
new (&packet[i]) Packet<K,false>(org,dir,packet_min_dist,packet_max_dist);
|
||||
}
|
||||
|
||||
const int shiftTable[32] = {
|
||||
(int)1 << 0, (int)1 << 1, (int)1 << 2, (int)1 << 3, (int)1 << 4, (int)1 << 5, (int)1 << 6, (int)1 << 7,
|
||||
(int)1 << 8, (int)1 << 9, (int)1 << 10, (int)1 << 11, (int)1 << 12, (int)1 << 13, (int)1 << 14, (int)1 << 15,
|
||||
(int)1 << 16, (int)1 << 17, (int)1 << 18, (int)1 << 19, (int)1 << 20, (int)1 << 21, (int)1 << 22, (int)1 << 23,
|
||||
(int)1 << 24, (int)1 << 25, (int)1 << 26, (int)1 << 27, (int)1 << 28, (int)1 << 29, (int)1 << 30, (int)1 << 31
|
||||
};
|
||||
|
||||
StackItemT<NodeRef> stack[stackSizeSingle]; //!< stack of nodes
|
||||
StackItemT<NodeRef>* stackPtr = stack + 1; //!< current stack pointer
|
||||
stack[0].ptr = bvh->root;
|
||||
stack[0].dist = m_active;
|
||||
|
||||
size_t terminated = ~m_active;
|
||||
|
||||
while (1) pop:
|
||||
{
|
||||
if (unlikely(stackPtr == stack)) break;
|
||||
STAT3(shadow.trav_stack_pop,1,1,1);
|
||||
stackPtr--;
|
||||
NodeRef cur = NodeRef(stackPtr->ptr);
|
||||
size_t cur_mask = (size_t)stackPtr->dist & (~terminated);
|
||||
if (unlikely(cur_mask == 0)) continue;
|
||||
|
||||
while (true)
|
||||
{
|
||||
|
||||
/*! stop if we found a leaf node */
|
||||
if (unlikely(cur.isLeaf())) break;
|
||||
const AlignedNode* __restrict__ const node = cur.alignedNode();
|
||||
|
||||
const vfloat<Nx> bminX = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_x));
|
||||
const vfloat<Nx> bmaxX = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->upper_x));
|
||||
const vfloat<Nx> bminY = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_y));
|
||||
const vfloat<Nx> bmaxY = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->upper_y));
|
||||
const vfloat<Nx> bminZ = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_z));
|
||||
const vfloat<Nx> bmaxZ = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->upper_z));
|
||||
|
||||
size_t bits = cur_mask;
|
||||
#if defined(__AVX__)
|
||||
//STAT3(shadow.trav_hit_boxes[__popcnt(cur_mask)],1,1,1);
|
||||
#endif
|
||||
|
||||
assert(bits);
|
||||
vint<Nx> vmask(zero);
|
||||
do
|
||||
{
|
||||
STAT3(shadow.trav_nodes,1,1,1);
|
||||
|
||||
const size_t rayID = __bscf(bits);
|
||||
assert(rayID < MAX_INTERNAL_STREAM_SIZE);
|
||||
assert(rayID /K < numPackets);
|
||||
Packet<K,false> &p = packet[rayID /K];
|
||||
const size_t i = rayID % K;
|
||||
const vint<Nx> bitmask(shiftTable[rayID]);
|
||||
|
||||
const vfloat<Nx> tNearX = msub(bminX, p.rdir.x[i], p.org_rdir.x[i]);
|
||||
const vfloat<Nx> tNearY = msub(bminY, p.rdir.y[i], p.org_rdir.y[i]);
|
||||
const vfloat<Nx> tNearZ = msub(bminZ, p.rdir.z[i], p.org_rdir.z[i]);
|
||||
const vfloat<Nx> tFarX = msub(bmaxX, p.rdir.x[i], p.org_rdir.x[i]);
|
||||
const vfloat<Nx> tFarY = msub(bmaxY, p.rdir.y[i], p.org_rdir.y[i]);
|
||||
const vfloat<Nx> tFarZ = msub(bmaxZ, p.rdir.z[i], p.org_rdir.z[i]);
|
||||
|
||||
const vfloat<Nx> tNear = maxi(mini(tNearX,tFarX), mini(tNearY,tFarY), mini(tNearZ,tFarZ), vfloat<Nx>(p.min_dist[i]));
|
||||
const vfloat<Nx> tFar = mini(maxi(tNearX,tFarX), maxi(tNearY,tFarY), maxi(tNearZ,tFarZ), vfloat<Nx>(p.max_dist[i]));
|
||||
const vbool<Nx> hit_mask = tNear <= tFar;
|
||||
#if defined(__AVX2__)
|
||||
vmask = vmask | (bitmask & vint<Nx>(hit_mask));
|
||||
#else
|
||||
vmask = select(hit_mask, vmask | bitmask, vmask);
|
||||
#endif
|
||||
} while(bits);
|
||||
const vbool<Nx> valid_children = bminX <= bmaxX;
|
||||
|
||||
size_t mask = movemask( (vmask != vint<Nx>(zero)) & valid_children);
|
||||
if (unlikely(mask == 0)) goto pop;
|
||||
|
||||
__aligned(64) unsigned int child_mask[Nx];
|
||||
vint<Nx>::storeu(child_mask,vmask); // this explicit store here causes much better code generation
|
||||
|
||||
/* select next child and push other children */
|
||||
//const BaseNode* node = cur.baseNode(types);
|
||||
|
||||
/*! one child is hit, continue with that child */
|
||||
size_t r = __bscf(mask);
|
||||
assert(r < N);
|
||||
cur = node->child(r);
|
||||
cur.prefetch(types);
|
||||
cur_mask = child_mask[r];
|
||||
|
||||
/* simple in order sequence */
|
||||
assert(cur != BVH::emptyNode);
|
||||
if (likely(mask == 0)) continue;
|
||||
stackPtr->ptr = cur;
|
||||
stackPtr->dist = cur_mask;
|
||||
stackPtr++;
|
||||
|
||||
for (; ;)
|
||||
{
|
||||
r = __bscf(mask);
|
||||
assert(r < N);
|
||||
|
||||
cur = node->child(r);
|
||||
cur.prefetch(types);
|
||||
cur_mask = child_mask[r];
|
||||
assert(cur != BVH::emptyNode);
|
||||
if (likely(mask == 0)) break;
|
||||
stackPtr->ptr = cur;
|
||||
stackPtr->dist = cur_mask;
|
||||
stackPtr++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*! 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 bits = cur_mask;
|
||||
size_t lazy_node = 0;
|
||||
|
||||
for (; bits!=0; )
|
||||
{
|
||||
const size_t rayID = __bscf(bits);
|
||||
|
||||
RayK<K> &ray = *inputPackets[rayID / K];
|
||||
const size_t k = rayID % K;
|
||||
if (PrimitiveIntersector::occluded(ray,k,context,prim,num,lazy_node)) {
|
||||
ray.geomID[k] = 0;
|
||||
terminated |= (size_t)1 << rayID;
|
||||
}
|
||||
/* lazy node */
|
||||
if (unlikely(lazy_node)) {
|
||||
stackPtr->ptr = lazy_node;
|
||||
stackPtr->dist = cur_mask;
|
||||
stackPtr++;
|
||||
}
|
||||
}
|
||||
|
||||
if (unlikely(terminated == (size_t)-1)) { break; }
|
||||
}
|
||||
|
||||
#else
|
||||
__aligned(64) Packet<K,robust> packet[MAX_INTERNAL_STREAM_SIZE/K];
|
||||
__aligned(64) StackItemMaskCoherent stack[stackSizeSingle]; //!< stack of nodes
|
||||
__aligned(64) Frustum<N,Nx,K,robust> frusta;
|
||||
|
||||
bool commonOctant = true;
|
||||
size_t m_active = initPacketsAndFrusta<true>(inputPackets, numOctantRays, packet, frusta, commonOctant);
|
||||
|
||||
|
||||
/* valid rays */
|
||||
if (unlikely(m_active == 0)) return;
|
||||
|
||||
@@ -194,7 +335,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;
|
||||
}
|
||||
|
||||
@@ -206,8 +347,6 @@ namespace embree
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const NearFarPreCompute pc(frusta.min_rdir);
|
||||
|
||||
StackItemMaskCoherent* stackPtr = stack + 1;
|
||||
|
||||
while (1) pop:
|
||||
@@ -233,7 +372,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);
|
||||
@@ -248,17 +387,8 @@ 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);
|
||||
}
|
||||
|
||||
/*! this is a leaf node */
|
||||
@@ -278,62 +408,14 @@ 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);
|
||||
m_active &= ~((size_t)movemask(m_hit) << (i*K));
|
||||
}
|
||||
|
||||
} // 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);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -351,5 +433,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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -17,197 +17,155 @@
|
||||
#include "bvh_intersector_stream_filters.h"
|
||||
#include "bvh_intersector_stream.h"
|
||||
|
||||
#define FORCE_STREAM_OCCLUSION_KERNEL 1
|
||||
|
||||
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)
|
||||
{
|
||||
const vintx vi = vintx(int(i)) + vintx(step);
|
||||
vboolx valid = vi < vintx(int(N));
|
||||
const vintx offset = vi * int(stride);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/* use fast path for coherent ray mode */
|
||||
#if FORCE_STREAM_OCCLUSION_KERNEL == 1
|
||||
if (1)
|
||||
#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;)
|
||||
{
|
||||
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
|
||||
|
||||
#if defined(EMBREE_IGNORE_INVALID_RAYS)
|
||||
if (unlikely(!ray.valid())) { inputRayID++; continue; }
|
||||
if (unlikely(isCoherent(context->user->flags)))
|
||||
#endif
|
||||
{
|
||||
__aligned(64) RayK<VSIZEX> rays[MAX_PACKET_STREAM_SIZE];
|
||||
__aligned(64) RayK<VSIZEX>* rayPtrs[MAX_PACKET_STREAM_SIZE];
|
||||
|
||||
const unsigned int octantID = movemask(vfloat4(ray.dir) < 0.0f) & 0x7;
|
||||
for (size_t i = 0; i < N; i += MAX_INTERNAL_STREAM_SIZE)
|
||||
{
|
||||
const size_t size = min(N - i, MAX_INTERNAL_STREAM_SIZE);
|
||||
|
||||
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
|
||||
{
|
||||
static const size_t MAX_RAYS_PER_OCTANT = VSIZEX;
|
||||
|
||||
#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 vintx offset = vi * int(stride);
|
||||
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 +178,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 +221,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 +259,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);
|
||||
}
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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
-34
@@ -18,10 +18,14 @@
|
||||
|
||||
#include "default.h"
|
||||
|
||||
#define MAX_INTERNAL_STREAM_SIZE 64
|
||||
|
||||
namespace embree
|
||||
{
|
||||
#if defined(__X86_64__) && 0
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -899,7 +974,6 @@ namespace embree
|
||||
__forceinline Ray8 RayStreamAOS::getRayByOffset(const vint8& offset)
|
||||
{
|
||||
Ray8 ray;
|
||||
|
||||
/* gather: instID */
|
||||
ray.instID = vint8::gather<1>((int*)&ptr->instID, offset);
|
||||
|
||||
@@ -1014,6 +1088,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 +1113,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
@@ -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 {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace embree
|
||||
{
|
||||
/*! An item on the stack holds the node ID and distance of that node. */
|
||||
template<typename T>
|
||||
struct __aligned(16) StackItemT
|
||||
struct __aligned(16) StackItemT
|
||||
{
|
||||
/*! assert that the xchg function works */
|
||||
static_assert(sizeof(T) <= 12, "sizeof(T) <= 12 failed");
|
||||
@@ -79,7 +79,15 @@ namespace embree
|
||||
}
|
||||
|
||||
public:
|
||||
T ptr;
|
||||
T ptr;
|
||||
unsigned dist;
|
||||
};
|
||||
|
||||
/*! An item on the stack holds the node ID and active ray mask. */
|
||||
template<typename T>
|
||||
struct __aligned(16) StackItemMaskT
|
||||
{
|
||||
T ptr;
|
||||
unsigned mask;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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++)
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -29,8 +29,6 @@ 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 num, size_t& lazy_node)
|
||||
{
|
||||
for (size_t i=0; i<num; i++)
|
||||
@@ -105,8 +103,6 @@ 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 num, size_t& lazy_node)
|
||||
{
|
||||
@@ -128,6 +124,16 @@ namespace embree
|
||||
return !valid0;
|
||||
}
|
||||
|
||||
static __forceinline bool occluded(RayK<K>& ray, size_t k, IntersectContext* context, const PrimitiveK* prim, size_t num, size_t& lazy_node)
|
||||
{
|
||||
PrecalculationsK pre(vbool<K>(true),ray); // FIXME: might cause trouble
|
||||
for (size_t i=0; i<num; i++) {
|
||||
if (IntersectorK::occluded(pre,ray,k,context,prim[i]))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
Binary file not shown.
@@ -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():
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -12,6 +12,7 @@ REM set release settings
|
||||
cmake -L ^
|
||||
-G "Visual Studio 12 2013" ^
|
||||
-T "Intel C++ Compiler 16.0" ^
|
||||
-D EMBREE_STACK_PROTECTOR=ON ^
|
||||
-D EMBREE_MAX_ISA=AVX512SKX ^
|
||||
-D EMBREE_TUTORIALS_IMAGE_MAGICK=OFF ^
|
||||
-D EMBREE_TUTORIALS_LIBJPEG=OFF ^
|
||||
|
||||
Executable
+117
@@ -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()
|
||||
Executable
+514
@@ -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):
|
||||
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"
|
||||
c = [] # CMake configuration
|
||||
e = [] # shell environment
|
||||
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)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -238,7 +238,7 @@ namespace embree
|
||||
if (features & FEATURE_STREAM)
|
||||
{
|
||||
/* register parsing of stream mode */
|
||||
registerOption("mode", [this] (Ref<ParseStream> cin, const FileName& path) {
|
||||
registerOption("mode", [] (Ref<ParseStream> cin, const FileName& path) {
|
||||
std::string mode = cin->getString();
|
||||
if (mode == "normal") g_mode = MODE_NORMAL;
|
||||
else if (mode == "stream") g_mode = MODE_STREAM;
|
||||
@@ -744,8 +744,9 @@ namespace embree
|
||||
{
|
||||
/* update camera */
|
||||
camera.move(moveDelta.x*speed, moveDelta.y*speed, moveDelta.z*speed);
|
||||
|
||||
ISPCCamera ispccamera = camera.getISPCCamera(width,height,true);
|
||||
if (print_camera)
|
||||
std::cout << camera.str() << std::endl;
|
||||
|
||||
/* render image using ISPC */
|
||||
initRayStats();
|
||||
@@ -819,10 +820,7 @@ namespace embree
|
||||
stream << dt1*1000.0f << " ms, ";
|
||||
stream << width << "x" << height << " pixels";
|
||||
std::cout << stream.str() << std::endl;
|
||||
}
|
||||
|
||||
if (print_camera)
|
||||
std::cout << camera.str() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void TutorialApplication::reshapeFunc(int width, int height)
|
||||
|
||||
@@ -287,12 +287,12 @@ float Noise(float x, float y, float z)
|
||||
Tutorial()
|
||||
: TutorialApplication("hair_geometry",FEATURE_RTCORE)
|
||||
{
|
||||
registerOption("ambientlight", [this] (Ref<ParseStream> cin, const FileName& path) {
|
||||
registerOption("ambientlight", [] (Ref<ParseStream> cin, const FileName& path) {
|
||||
g_ambient_intensity = cin->getVec3fa();
|
||||
}, "--ambientlight r g b: adds an ambient light with intensity rgb");
|
||||
registerOptionAlias("ambientlight","ambient");
|
||||
|
||||
registerOption("directionallight", [this] (Ref<ParseStream> cin, const FileName& path) {
|
||||
registerOption("directionallight", [] (Ref<ParseStream> cin, const FileName& path) {
|
||||
g_dirlight_direction = normalize(cin->getVec3fa());
|
||||
g_dirlight_intensity = cin->getVec3fa();
|
||||
}, "--directionallight x y z r g b: adds a directional light with direction xyz and intensity rgb");
|
||||
|
||||
@@ -77,7 +77,7 @@ void convertHairSet(ISPCHairSet* hair, RTCScene scene_out)
|
||||
}
|
||||
rtcSetBuffer(scene_out,geomID,RTC_INDEX_BUFFER,hair->hairs,0,sizeof(ISPCHair));
|
||||
rtcSetOcclusionFilterFunction(scene_out,geomID,filterDispatch);
|
||||
rtcSetTessellationRate(scene_out,geomID,hair->tessellation_rate);
|
||||
rtcSetTessellationRate(scene_out,geomID,(float)hair->tessellation_rate);
|
||||
}
|
||||
|
||||
RTCScene convertScene(ISPCScene* scene_in)
|
||||
|
||||
@@ -29,16 +29,16 @@ namespace embree
|
||||
Tutorial()
|
||||
: TutorialApplication("motion_blur_geometry",FEATURE_RTCORE)
|
||||
{
|
||||
registerOption("time", [this] (Ref<ParseStream> cin, const FileName& path) {
|
||||
registerOption("time", [] (Ref<ParseStream> cin, const FileName& path) {
|
||||
g_time = cin->getFloat();
|
||||
}, "--time <float>: time to render image at");
|
||||
|
||||
registerOption("time-steps", [this] (Ref<ParseStream> cin, const FileName& path) {
|
||||
registerOption("time-steps", [] (Ref<ParseStream> cin, const FileName& path) {
|
||||
g_num_time_steps = cin->getInt();
|
||||
if (g_num_time_steps < 2) throw std::runtime_error("at least 2 time steps have to be used");
|
||||
}, "--time-steps <int>: number of time steps to use");
|
||||
|
||||
registerOption("time-steps2", [this] (Ref<ParseStream> cin, const FileName& path) {
|
||||
registerOption("time-steps2", [] (Ref<ParseStream> cin, const FileName& path) {
|
||||
g_num_time_steps2 = cin->getInt();
|
||||
if (g_num_time_steps2 < 2) throw std::runtime_error("at least 2 time steps have to be used");
|
||||
}, "--time-steps2 <int>: number of time steps to use");
|
||||
|
||||
@@ -17,3 +17,5 @@
|
||||
INCLUDE(tutorial)
|
||||
ADD_TUTORIAL(pathtracer)
|
||||
ADD_EMBREE_MODELS_TEST(pathtracer pathtracer pathtracer)
|
||||
ADD_EMBREE_MODELS_TEST(pathtracer_coherent pathtracer pathtracer --coherent)
|
||||
ADD_EMBREE_MODELS_TEST(pathtracer_incoherent pathtracer pathtracer --incoherent)
|
||||
|
||||
@@ -28,11 +28,11 @@ namespace embree
|
||||
Tutorial()
|
||||
: SceneLoadingTutorialApplication("pathtracer",FEATURE_RTCORE)
|
||||
{
|
||||
registerOption("spp", [this] (Ref<ParseStream> cin, const FileName& path) {
|
||||
registerOption("spp", [] (Ref<ParseStream> cin, const FileName& path) {
|
||||
g_spp = cin->getInt();
|
||||
}, "--spp: sets number of samples per pixel");
|
||||
|
||||
registerOption("accumulate", [this] (Ref<ParseStream> cin, const FileName& path) {
|
||||
registerOption("accumulate", [] (Ref<ParseStream> cin, const FileName& path) {
|
||||
g_accumulate = cin->getInt();
|
||||
}, "--accumulate <bool>: accumulate samples (on by default)");
|
||||
}
|
||||
|
||||
@@ -1461,6 +1461,7 @@ Vec3fa renderPixelFunction(float x, float y, RandomSampler& sampler, const ISPCC
|
||||
c = c * Material__sample(material_array,materialID,numMaterials,brdf,Lw, wo, dg, wi1, medium, RandomSampler_get2D(sampler));
|
||||
|
||||
/* iterate over lights */
|
||||
context.flags = g_iflags_incoherent;
|
||||
for (size_t i=0; i<g_ispc_scene->numLights; i++)
|
||||
{
|
||||
const Light* l = g_ispc_scene->lights[i];
|
||||
@@ -1501,7 +1502,7 @@ Vec3fa renderPixelStandard(float x, float y, const ISPCCamera& camera, RayStats&
|
||||
float fy = y + RandomSampler_get1D(sampler);
|
||||
L = L + renderPixelFunction(fx,fy,sampler,camera,stats);
|
||||
}
|
||||
L = L/g_spp;
|
||||
L = L/(float)g_spp;
|
||||
return L;
|
||||
}
|
||||
|
||||
|
||||
@@ -1459,6 +1459,7 @@ Vec3f renderPixelFunction(float x, float y, RandomSampler& sampler, const unifor
|
||||
c = c * Material__sample(material_array,materialID,numMaterials,brdf,Lw, wo, dg, wi1, medium, RandomSampler_get2D(sampler));
|
||||
|
||||
/* iterate over lights */
|
||||
context.flags = g_iflags_incoherent;
|
||||
for (uniform size_t i=0; i<g_ispc_scene->numLights; i++)
|
||||
{
|
||||
const uniform Light* uniform l = g_ispc_scene->lights[i];
|
||||
|
||||
@@ -664,7 +664,7 @@ namespace embree
|
||||
}
|
||||
|
||||
template<int N>
|
||||
inline void IntersectWithNMMode(IntersectVariant ivariant, RTCScene scene, RTCIntersectContext* context, RTCRay* rays, size_t Nrays)
|
||||
__noinline void IntersectWithNMMode(IntersectVariant ivariant, RTCScene scene, RTCIntersectContext* context, RTCRay* rays, size_t Nrays)
|
||||
{
|
||||
assert(Nrays<1024);
|
||||
const size_t alignment = size_t(rays) % 64;
|
||||
@@ -693,8 +693,45 @@ namespace embree
|
||||
for (size_t j=0; j<L; j++) rays[i+j] = getRay(ray,N,j);
|
||||
}
|
||||
}
|
||||
|
||||
__noinline void IntersectWithNpMode(IntersectVariant ivariant, RTCScene scene, RTCIntersectContext* context, RTCRay* rays, size_t N)
|
||||
{
|
||||
assert(N < 1024);
|
||||
const size_t alignment = size_t(rays) % 64;
|
||||
__aligned(64) char data[1024 * sizeof(RTCRay) + 64];
|
||||
RTCRayN* ray = (RTCRayN*)&data[alignment];
|
||||
for (size_t j = 0; j < N; j++) setRay(ray, N, j, rays[j]);
|
||||
|
||||
inline void IntersectWithModeInternal(IntersectMode mode, IntersectVariant ivariant, RTCScene scene, RTCRay* rays, size_t N)
|
||||
RTCRayNp rayp;
|
||||
rayp.orgx = &RTCRayN_org_x(ray, N, 0);
|
||||
rayp.orgy = &RTCRayN_org_y(ray, N, 0);
|
||||
rayp.orgz = &RTCRayN_org_z(ray, N, 0);
|
||||
rayp.dirx = &RTCRayN_dir_x(ray, N, 0);
|
||||
rayp.diry = &RTCRayN_dir_y(ray, N, 0);
|
||||
rayp.dirz = &RTCRayN_dir_z(ray, N, 0);
|
||||
rayp.tnear = &RTCRayN_tnear(ray, N, 0);
|
||||
rayp.tfar = &RTCRayN_tfar(ray, N, 0);
|
||||
rayp.time = &RTCRayN_time(ray, N, 0);
|
||||
rayp.mask = &RTCRayN_mask(ray, N, 0);
|
||||
rayp.instID = &RTCRayN_instID(ray, N, 0);
|
||||
rayp.geomID = &RTCRayN_geomID(ray, N, 0);
|
||||
rayp.primID = &RTCRayN_primID(ray, N, 0);
|
||||
rayp.u = &RTCRayN_u(ray, N, 0);
|
||||
rayp.v = &RTCRayN_v(ray, N, 0);
|
||||
rayp.Ngx = &RTCRayN_Ng_x(ray, N, 0);
|
||||
rayp.Ngy = &RTCRayN_Ng_y(ray, N, 0);
|
||||
rayp.Ngz = &RTCRayN_Ng_z(ray, N, 0);
|
||||
|
||||
switch (ivariant & VARIANT_INTERSECT_OCCLUDED_MASK) {
|
||||
case VARIANT_INTERSECT: rtcIntersectNp(scene, context, rayp, N); break;
|
||||
case VARIANT_OCCLUDED: rtcOccludedNp(scene, context, rayp, N); break;
|
||||
default: assert(false);
|
||||
}
|
||||
|
||||
for (size_t j = 0; j < N; j++) rays[j] = getRay(ray, N, j);
|
||||
}
|
||||
|
||||
__noinline void IntersectWithModeInternal(IntersectMode mode, IntersectVariant ivariant, RTCScene scene, RTCRay* rays, size_t N)
|
||||
{
|
||||
RTCIntersectContext context;
|
||||
context.flags = ((ivariant & VARIANT_COHERENT_INCOHERENT_MASK) == VARIANT_COHERENT) ? RTC_INTERSECT_COHERENT : RTC_INTERSECT_INCOHERENT;
|
||||
@@ -812,48 +849,14 @@ namespace embree
|
||||
IntersectWithNMMode<16>(ivariant,scene,&context,rays,N);
|
||||
break;
|
||||
}
|
||||
case MODE_INTERSECTNp:
|
||||
{
|
||||
assert(N<1024);
|
||||
const size_t alignment = size_t(rays) % 64;
|
||||
__aligned(64) char data[1024*sizeof(RTCRay)+64];
|
||||
RTCRayN* ray = (RTCRayN*) &data[alignment];
|
||||
for (size_t j=0; j<N; j++) setRay(ray,N,j,rays[j]);
|
||||
|
||||
RTCRayNp rayp;
|
||||
rayp.orgx = &RTCRayN_org_x(ray,N,0);
|
||||
rayp.orgy = &RTCRayN_org_y(ray,N,0);
|
||||
rayp.orgz = &RTCRayN_org_z(ray,N,0);
|
||||
rayp.dirx = &RTCRayN_dir_x(ray,N,0);
|
||||
rayp.diry = &RTCRayN_dir_y(ray,N,0);
|
||||
rayp.dirz = &RTCRayN_dir_z(ray,N,0);
|
||||
rayp.tnear = &RTCRayN_tnear(ray,N,0);
|
||||
rayp.tfar = &RTCRayN_tfar(ray,N,0);
|
||||
rayp.time = &RTCRayN_time(ray,N,0);
|
||||
rayp.mask = &RTCRayN_mask(ray,N,0);
|
||||
rayp.instID = &RTCRayN_instID(ray,N,0);
|
||||
rayp.geomID = &RTCRayN_geomID(ray,N,0);
|
||||
rayp.primID = &RTCRayN_primID(ray,N,0);
|
||||
rayp.u = &RTCRayN_u(ray,N,0);
|
||||
rayp.v = &RTCRayN_v(ray,N,0);
|
||||
rayp.Ngx = &RTCRayN_Ng_x(ray,N,0);
|
||||
rayp.Ngy = &RTCRayN_Ng_y(ray,N,0);
|
||||
rayp.Ngz = &RTCRayN_Ng_z(ray,N,0);
|
||||
|
||||
switch (ivariant & VARIANT_INTERSECT_OCCLUDED_MASK) {
|
||||
case VARIANT_INTERSECT: rtcIntersectNp(scene,&context,rayp,N); break;
|
||||
case VARIANT_OCCLUDED : rtcOccludedNp(scene,&context,rayp,N); break;
|
||||
default: assert(false);
|
||||
}
|
||||
|
||||
for (size_t j=0; j<N; j++) rays[j] = getRay(ray,N,j);
|
||||
|
||||
case MODE_INTERSECTNp: {
|
||||
IntersectWithNpMode(ivariant, scene, &context, rays, N);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void IntersectWithMode(IntersectMode mode, IntersectVariant ivariant, RTCScene scene, RTCRay* rays, size_t N)
|
||||
void IntersectWithMode(IntersectMode mode, IntersectVariant ivariant, RTCScene scene, RTCRay* rays, size_t N)
|
||||
{
|
||||
/* verify occluded result against intersect */
|
||||
if ((ivariant & VARIANT_INTERSECT_OCCLUDED) == VARIANT_INTERSECT_OCCLUDED)
|
||||
|
||||
@@ -16,8 +16,10 @@
|
||||
|
||||
INCLUDE(tutorial)
|
||||
ADD_TUTORIAL(viewer)
|
||||
ADD_EMBREE_MODELS_TEST(viewer viewer viewer)
|
||||
ADD_EMBREE_MODELS_TEST(viewer_quad viewer viewer -convert-triangles-to-quads)
|
||||
ADD_EMBREE_MODELS_TEST(viewer_coherent viewer viewer --coherent)
|
||||
ADD_EMBREE_MODELS_TEST(viewer_incoherent viewer viewer --incoherent)
|
||||
ADD_EMBREE_MODELS_TEST(viewer_quad_coherent viewer viewer -convert-triangles-to-quads)
|
||||
ADD_EMBREE_MODELS_TEST(viewer_quad_incoherent viewer viewer -convert-triangles-to-quads --incoherent)
|
||||
ADD_EMBREE_SUBDIV_MODELS_TEST(viewer viewer viewer viewer)
|
||||
|
||||
IF (EMBREE_TESTING_INTENSIVE)
|
||||
|
||||
@@ -268,7 +268,7 @@ Vec3fa renderPixelStandard(float x, float y, const ISPCCamera& camera, RayStats&
|
||||
|
||||
/* intersect ray with scene */
|
||||
RTCIntersectContext context;
|
||||
context.flags = RTC_INTERSECT_COHERENT;
|
||||
context.flags = g_iflags_coherent;
|
||||
rtcIntersect1Ex(g_scene,&context,ray);
|
||||
RayStats_addRay(stats);
|
||||
|
||||
|
||||
@@ -258,7 +258,7 @@ Vec3f renderPixelStandard(float x, float y, const uniform ISPCCamera& camera, un
|
||||
|
||||
/* intersect ray with scene */
|
||||
uniform RTCIntersectContext context;
|
||||
context.flags = RTC_INTERSECT_COHERENT;
|
||||
context.flags = g_iflags_coherent;
|
||||
rtcIntersectEx(g_scene,&context,ray);
|
||||
RayStats_addRay(stats);
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace embree {
|
||||
//#define rtcOccluded rtcIntersect
|
||||
//#define rtcOccluded1M rtcIntersect1M
|
||||
|
||||
#define SIMPLE_SHADING 1
|
||||
#define SIMPLE_SHADING 0
|
||||
|
||||
extern "C" ISPCScene* g_ispc_scene;
|
||||
|
||||
@@ -163,7 +163,7 @@ void renderTileStandard(int taskIndex,
|
||||
rtcIntersect1M(g_scene,&context,rays,N,sizeof(RTCRay));
|
||||
#elif USE_INTERFACE == 1
|
||||
for (size_t i=0; i<N; i++)
|
||||
rtcIntersect(g_scene,rays[i]);
|
||||
rtcIntersect1Ex(g_scene,&context,rays[i]);
|
||||
#else
|
||||
for (size_t i=0; i<N; i++)
|
||||
rtcIntersect1M(g_scene,&context,&rays[i],1,sizeof(RTCRay));
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
//#define rtcOccluded rtcIntersect
|
||||
//#define rtcOccludedVM rtcIntersectVM
|
||||
|
||||
#define SIMPLE_SHADING 1
|
||||
#define SIMPLE_SHADING 0
|
||||
|
||||
extern uniform ISPCScene* uniform g_ispc_scene;
|
||||
|
||||
@@ -167,7 +167,6 @@ void renderTileStandard(uniform int taskIndex,
|
||||
rtcIntersectVM(g_scene,&context,&rays[i],1,sizeof(RTCRay));
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
/* shade stream of rays */
|
||||
N = 0;
|
||||
foreach_tiled (y = y0 ... y1, x = x0 ... x1)
|
||||
@@ -191,7 +190,6 @@ void renderTileStandard(uniform int taskIndex,
|
||||
unsigned int b = (unsigned int) (255.0f * clamp(color.z,0.0f,1.0f));
|
||||
pixels[y*width+x] = (b << 16) + (g << 8) + r;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* task that renders a single screen tile */
|
||||
|
||||
Reference in New Issue
Block a user