Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d3d9f6225b | ||
|
|
f34b975536 | ||
|
|
b8c30540ba | ||
|
|
42979151c2 | ||
|
|
6bafe12b19 | ||
|
|
4b078bb1bc | ||
|
|
66f21608e0 | ||
|
|
c41d484595 | ||
|
|
4794b0e55f | ||
|
|
c48d21814c | ||
|
|
a7d313ad41 | ||
|
|
fe52f5d6b7 | ||
|
|
729ece7292 | ||
|
|
9722b4c30d | ||
|
|
ed8ee37967 | ||
|
|
7a50a2d692 | ||
|
|
357c6f24c5 | ||
|
|
83fcf53b95 | ||
|
|
8968597c20 | ||
|
|
95a4cbcb94 | ||
|
|
2c724c529f | ||
|
|
5da02d0800 | ||
|
|
11b243931c | ||
|
|
28e11c9857 | ||
|
|
4c9c026a1b | ||
|
|
1a47e44b72 | ||
|
|
1fb988cd6b | ||
|
|
c6498a29d0 | ||
|
|
fcd747217b | ||
|
|
6bf725ba7c | ||
|
|
e9a402ecd1 | ||
|
|
a7dd991418 | ||
|
|
2f6af2832d | ||
|
|
640c6daa85 | ||
|
|
512811023f | ||
|
|
c0a1dbb5d8 | ||
|
|
045c418031 | ||
|
|
8956aee21c | ||
|
|
0d9bc8df72 | ||
|
|
ca96c96cb3 | ||
|
|
4c50caa6b1 | ||
|
|
9edba0f4ea | ||
|
|
f4626bb22e | ||
|
|
7d66ef477b | ||
|
|
1b3b7ecb38 | ||
|
|
e082712373 | ||
|
|
185ffc39d3 | ||
|
|
3f4c6ac6e3 | ||
|
|
5e3b4cf0e2 | ||
|
|
dec21a5f65 | ||
|
|
2b0c400355 | ||
|
|
058e820efb | ||
|
|
d633a5541d | ||
|
|
563fa8b32c | ||
|
|
0894d751f1 | ||
|
|
23e8a0389d | ||
|
|
54f29c991b | ||
|
|
fd3af84024 | ||
|
|
a9a868f252 | ||
|
|
870e7adc71 | ||
|
|
bec88b6568 | ||
|
|
85a6d9c54c | ||
|
|
63919c188c | ||
|
|
76892f8577 | ||
|
|
44e783d59d | ||
|
|
0a642420af | ||
|
|
d208cbb4d9 | ||
|
|
0419f1d8cc | ||
|
|
c2309bbf79 | ||
|
|
e9149e8e9a | ||
|
|
c15bb92593 | ||
|
|
a1b56e8adc | ||
|
|
d85aea4c1a | ||
|
|
4498acd035 | ||
|
|
152073d7ac | ||
|
|
a90002157c | ||
|
|
f8c8d55c44 | ||
|
|
97600fb260 | ||
|
|
b6d6cba2a2 | ||
|
|
ead4835d35 | ||
|
|
eb4906c79c | ||
|
|
85b65574bb | ||
|
|
363c005f8e | ||
|
|
4422ca608c | ||
|
|
d38ac50b2b | ||
|
|
4d05b49867 | ||
|
|
a22e54cc49 | ||
|
|
46d131e056 | ||
|
|
f1d23c57ed | ||
|
|
265044e73f | ||
|
|
ca84d3425e | ||
|
|
418ec0bdfb | ||
|
|
2d1f8a6a97 | ||
|
|
9813d6a6ee | ||
|
|
255ab75c5f | ||
|
|
ece6b8345c | ||
|
|
59ec5d0fcd | ||
|
|
2cd05a8b2b | ||
|
|
08e54eb4c1 | ||
|
|
fb13a85505 | ||
|
|
fb81cb34de | ||
|
|
3ceca55050 | ||
|
|
87d45e6096 | ||
|
|
872ced9934 | ||
|
|
f987d717ef | ||
|
|
9b40fcb862 | ||
|
|
19605e0738 | ||
|
|
fe56a4dc3c | ||
|
|
4994f64729 | ||
|
|
7b4af861f4 | ||
|
|
82ef698bcf | ||
|
|
ca70fc388b | ||
|
|
ae06ac06a9 | ||
|
|
e2656563b1 | ||
|
|
752e905ecc | ||
|
|
d9e046d0c3 | ||
|
|
5945b87db9 | ||
|
|
0c92fff315 | ||
|
|
360ad9d0c3 | ||
|
|
6c34e0d090 | ||
|
|
794d90069c | ||
|
|
fb8e4405c7 | ||
|
|
36d53847c7 | ||
|
|
e45aabfb8a | ||
|
|
d66fbeb235 | ||
|
|
af13b7704f | ||
|
|
649d39f3a8 | ||
|
|
9b3362a394 | ||
|
|
fdb80242af | ||
|
|
fa7d1b4f89 | ||
|
|
f6cdaeb732 | ||
|
|
a9d59ed6c8 | ||
|
|
5633e5233d | ||
|
|
2b681c5f27 | ||
|
|
8a8f7c78aa | ||
|
|
159e440014 | ||
|
|
04d8b88026 | ||
|
|
1f8e43141c | ||
|
|
07c35e2ed2 | ||
|
|
a44f900b20 | ||
|
|
141aa737c6 | ||
|
|
f154b5f160 | ||
|
|
7f82ff96ce | ||
|
|
1112474494 | ||
|
|
b486e32e7c |
@@ -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
@@ -16,7 +16,7 @@
|
||||
|
||||
SET(EMBREE_VERSION_MAJOR 2)
|
||||
SET(EMBREE_VERSION_MINOR 17)
|
||||
SET(EMBREE_VERSION_PATCH 0)
|
||||
SET(EMBREE_VERSION_PATCH 1)
|
||||
SET(EMBREE_VERSION_NOTE "-alpha.0")
|
||||
SET(EMBREE_VERSION ${EMBREE_VERSION_MAJOR}.${EMBREE_VERSION_MINOR}.${EMBREE_VERSION_PATCH})
|
||||
MATH(EXPR EMBREE_VERSION_NUMBER "10000*${EMBREE_VERSION_MAJOR} + 100*${EMBREE_VERSION_MINOR} + ${EMBREE_VERSION_PATCH}")
|
||||
@@ -26,6 +26,7 @@ PROJECT(embree${EMBREE_VERSION_MAJOR})
|
||||
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.11)
|
||||
|
||||
|
||||
# find git version
|
||||
IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.git)
|
||||
FIND_PACKAGE(Git)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -14,13 +14,36 @@
|
||||
## limitations under the License. ##
|
||||
## ======================================================================== ##
|
||||
|
||||
IF (NOT TBB_ROOT)
|
||||
SET(TBB_ROOT $ENV{TBB_ROOT})
|
||||
ENDIF()
|
||||
IF (NOT TBB_ROOT)
|
||||
SET(TBB_ROOT $ENV{TBBROOT})
|
||||
ENDIF()
|
||||
|
||||
IF (WIN32)
|
||||
# workaround for parentheses in variable name / CMP0053
|
||||
SET(PROGRAMFILESx86 "PROGRAMFILES(x86)")
|
||||
SET(PROGRAMFILES32 "$ENV{${PROGRAMFILESx86}}")
|
||||
IF (NOT PROGRAMFILES32)
|
||||
SET(PROGRAMFILES32 "$ENV{PROGRAMFILES}")
|
||||
ENDIF()
|
||||
IF (NOT PROGRAMFILES32)
|
||||
SET(PROGRAMFILES32 "C:/Program Files (x86)")
|
||||
ENDIF()
|
||||
FIND_PATH(EMBREE_TBB_ROOT include/tbb/tbb.h
|
||||
DOC "Root of TBB installation"
|
||||
PATHS ${PROJECT_SOURCE_DIR}/tbb "C:/Program Files (x86)/Intel/Composer XE/tbb"
|
||||
PATHS ${PROJECT_SOURCE_DIR}/tbb
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
FIND_PATH(EMBREE_TBB_ROOT include/tbb/tbb.h)
|
||||
FIND_PATH(EMBREE_TBB_ROOT include/tbb/tbb.h
|
||||
HINTS ${TBB_ROOT}
|
||||
PATHS
|
||||
${PROJECT_SOURCE_DIR}/../tbb
|
||||
"${PROGRAMFILES32}/IntelSWTools/compilers_and_libraries/windows/tbb"
|
||||
"${PROGRAMFILES32}/Intel/Composer XE/tbb"
|
||||
"${PROGRAMFILES32}/Intel/compilers_and_libraries/windows/tbb"
|
||||
)
|
||||
|
||||
IF (CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
SET(TBB_ARCH intel64)
|
||||
@@ -32,8 +55,10 @@ IF (WIN32)
|
||||
SET(TBB_VCVER vc10)
|
||||
ELSEIF (MSVC11)
|
||||
SET(TBB_VCVER vc11)
|
||||
ELSE()
|
||||
ELSEIF (MSVC12)
|
||||
SET(TBB_VCVER vc12)
|
||||
ELSE()
|
||||
SET(TBB_VCVER vc14)
|
||||
ENDIF()
|
||||
|
||||
SET(TBB_LIBDIR ${EMBREE_TBB_ROOT}/lib/${TBB_ARCH}/${TBB_VCVER})
|
||||
@@ -56,17 +81,25 @@ ELSE ()
|
||||
|
||||
FIND_PATH(EMBREE_TBB_ROOT include/tbb/tbb.h
|
||||
DOC "Root of TBB installation"
|
||||
PATHS ${PROJECT_SOURCE_DIR}/tbb /opt/intel/tbb
|
||||
PATHS ${PROJECT_SOURCE_DIR}/tbb
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
FIND_PATH(EMBREE_TBB_ROOT include/tbb/tbb.h)
|
||||
FIND_PATH(EMBREE_TBB_ROOT include/tbb/tbb.h
|
||||
DOC "Root of TBB installation"
|
||||
HINTS ${TBB_ROOT}
|
||||
PATHS
|
||||
${PROJECT_SOURCE_DIR}/tbb
|
||||
/opt/intel/composerxe/tbb
|
||||
/opt/intel/compilers_and_libraries/tbb
|
||||
/opt/intel/tbb
|
||||
)
|
||||
|
||||
IF (EMBREE_TBB_ROOT STREQUAL "")
|
||||
FIND_PATH(TBB_INCLUDE_DIR tbb/task_scheduler_init.h)
|
||||
FIND_LIBRARY(TBB_LIBRARY tbb)
|
||||
FIND_LIBRARY(TBB_LIBRARY_MALLOC tbbmalloc)
|
||||
|
||||
ELSEIF (EXISTS ${EMBREE_TBB_ROOT}/src)
|
||||
ELSEIF (EXISTS ${EMBREE_TBB_ROOT}/cmake/TBBBuild.cmake)
|
||||
OPTION(EMBREE_TBB_STATIC_LIB "Build TBB as a static library (building TBB as a static library is NOT recommended)")
|
||||
if (EMBREE_TBB_STATIC_LIB)
|
||||
include(${EMBREE_TBB_ROOT}/cmake/TBBBuild.cmake)
|
||||
@@ -92,8 +125,9 @@ ELSE ()
|
||||
FIND_LIBRARY(TBB_LIBRARY_MALLOC tbbmalloc PATHS ${EMBREE_TBB_ROOT}/lib NO_DEFAULT_PATH)
|
||||
ELSE()
|
||||
FIND_PATH(TBB_INCLUDE_DIR tbb/task_scheduler_init.h PATHS ${EMBREE_TBB_ROOT}/include NO_DEFAULT_PATH)
|
||||
FIND_LIBRARY(TBB_LIBRARY tbb PATHS ${EMBREE_TBB_ROOT}/lib/intel64/gcc4.4 ${EMBREE_TBB_ROOT}/lib ${EMBREE_TBB_ROOT}/lib64 /usr/libx86_64-linux-gnu/ NO_DEFAULT_PATH)
|
||||
FIND_LIBRARY(TBB_LIBRARY_MALLOC tbbmalloc PATHS ${EMBREE_TBB_ROOT}/lib/intel64/gcc4.4 ${EMBREE_TBB_ROOT}/lib ${EMBREE_TBB_ROOT}/lib64 /usr/libx86_64-linux-gnu/ NO_DEFAULT_PATH)
|
||||
SET(TBB_HINTS HINTS ${EMBREE_TBB_ROOT}/lib/intel64/gcc4.4 ${EMBREE_TBB_ROOT}/lib ${EMBREE_TBB_ROOT}/lib64 PATHS /usr/libx86_64-linux-gnu/)
|
||||
FIND_LIBRARY(TBB_LIBRARY tbb ${TBB_HINTS})
|
||||
FIND_LIBRARY(TBB_LIBRARY_MALLOC tbbmalloc ${TBB_HINTS})
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
@@ -117,7 +151,6 @@ MARK_AS_ADVANCED(TBB_LIBRARY_MALLOC)
|
||||
|
||||
IF (WIN32)
|
||||
INSTALL(PROGRAMS ${TBB_BINDIR}/tbb.dll ${TBB_BINDIR}/tbbmalloc.dll DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT examples)
|
||||
INSTALL(PROGRAMS ${TBB_BINDIR}/tbb.dll ${TBB_BINDIR}/tbbmalloc.dll DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT lib)
|
||||
INSTALL(PROGRAMS ${TBB_LIBDIR}/tbb.lib ${TBB_LIBDIR}/tbbmalloc.lib DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT lib)
|
||||
ELSEIF (EMBREE_ZIP_MODE)
|
||||
IF (APPLE)
|
||||
|
||||
@@ -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
|
||||
|
||||
+16
-5
@@ -33,6 +33,11 @@ IF (WIN32)
|
||||
ELSE()
|
||||
SET(COMMON_CXX_FLAGS "${COMMON_CXX_FLAGS} /GS-") # do not protect against return address overrides
|
||||
ENDIF()
|
||||
MACRO(DISABLE_STACK_PROTECTOR_FOR_FILE file)
|
||||
IF (EMBREE_STACK_PROTECTOR)
|
||||
SET_SOURCE_FILES_PROPERTIES(${file} PROPERTIES COMPILE_FLAGS "/GS-")
|
||||
ENDIF()
|
||||
ENDMACRO()
|
||||
|
||||
SET(COMMON_CXX_FLAGS "${COMMON_CXX_FLAGS} /Qdiag-disable:11074 ") # remark #11074: Inlining inhibited by limit max-size
|
||||
SET(COMMON_CXX_FLAGS "${COMMON_CXX_FLAGS} /Qdiag-disable:11075 ") # remark #11075: To get full report use -Qopt-report:4 -Qopt-report-phase ipo
|
||||
@@ -46,14 +51,14 @@ IF (WIN32)
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Oi") # inline intrinsic functions
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Gy") # package individual functions
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Qinline-max-total-size-") # no size limit when performing inlining
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Qinline-factor=200") # increase default inline factors by 2x
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Qinline-factor=150") # increase default inline factors by 2x
|
||||
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${COMMON_CXX_FLAGS}")
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Ox") # enable full optimizations
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Oi") # inline intrinsic functions
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Gy") # package individual functions
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Qinline-max-total-size-") # no size limit when performing inlining
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Qinline-factor=200") # increase default inline factors by 2x
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Qinline-factor=150") # increase default inline factors by 2x
|
||||
SET(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} /DEBUG") # generate debug information
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO} /DEBUG") # generate debug information
|
||||
|
||||
@@ -105,6 +110,12 @@ ELSE()
|
||||
IF (EMBREE_STACK_PROTECTOR)
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstack-protector") # protects against return address overrides
|
||||
ENDIF()
|
||||
MACRO(DISABLE_STACK_PROTECTOR_FOR_FILE file)
|
||||
IF (EMBREE_STACK_PROTECTOR)
|
||||
SET_SOURCE_FILES_PROPERTIES(${file} PROPERTIES COMPILE_FLAGS "-fno-stack-protector")
|
||||
ENDIF()
|
||||
ENDMACRO()
|
||||
|
||||
IF(NOT CMAKE_CXX_COMPILER_WRAPPER STREQUAL "CrayPrgEnv")
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-intel") # links intel runtime statically
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -no-intel-extensions") # disables some intel extensions which cause symbols to be exported
|
||||
@@ -122,8 +133,8 @@ ELSE()
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -restrict") # enable restrict keyword
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -no-inline-max-total-size") # no size limit when performing inlining
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -no-inline-max-per-compile") # no maximal number of inlinings per compilation unit
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -inline-factor=200") # increase default inline factors limits by 2x
|
||||
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -inline-factor=150") # increase default inline factors limits by 2x
|
||||
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "")
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DDEBUG") # enables assertions
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DTBB_USE_DEBUG") # configures TBB in debug mode
|
||||
@@ -132,7 +143,7 @@ ELSE()
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -restrict") # enable restrict keyword
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -no-inline-max-total-size") # no size limit when performing inlining
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -no-inline-max-per-compile") # no maximal number of inlinings per compilation unit
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -inline-factor=200") # increase default inline factors by 2x
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -inline-factor=150") # increase default inline factors by 2x
|
||||
|
||||
#SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -g -debug inline-debug-info")
|
||||
#SET(CMAKE_EXE_LINKER_FLAGS "-g")
|
||||
|
||||
@@ -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,11 +125,12 @@ INSTALL(FILES "${PROJECT_BINARY_DIR}/embree-config-version.cmake" DESTINATION ${
|
||||
# CPack specific stuff
|
||||
##############################################################
|
||||
|
||||
SET(CPACK_PACKAGE_NAME "Embree")
|
||||
SET(CPACK_PACKAGE_NAME "Embree Ray Tracing Kernels")
|
||||
SET(CPACK_PACKAGE_FILE_NAME "embree-${EMBREE_VERSION}")
|
||||
#SET(CPACK_PACKAGE_ICON ${PROJECT_SOURCE_DIR}/embree-doc/images/icon.png)
|
||||
#SET(CPACK_PACKAGE_RELOCATABLE TRUE)
|
||||
SET(CPACK_STRIP_FILES TRUE)
|
||||
SET(CPACK_STRIP_FILES TRUE) # do not disable, stripping symbols is important for security reasons
|
||||
SET(CMAKE_STRIP "${PROJECT_SOURCE_DIR}/scripts/strip.sh") # needs this to properly strip under MacOSX
|
||||
|
||||
SET(CPACK_PACKAGE_VERSION_MAJOR ${EMBREE_VERSION_MAJOR})
|
||||
SET(CPACK_PACKAGE_VERSION_MINOR ${EMBREE_VERSION_MINOR})
|
||||
@@ -161,33 +162,19 @@ IF(WIN32)
|
||||
|
||||
IF (CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
SET(ARCH x64)
|
||||
SET(PROGRAMFILES "\$PROGRAMFILES64")
|
||||
SET(CPACK_PACKAGE_NAME "${CPACK_PACKAGE_NAME} x64")
|
||||
ELSE()
|
||||
SET(ARCH win32)
|
||||
SET(PROGRAMFILES "\$PROGRAMFILES")
|
||||
SET(CPACK_PACKAGE_NAME "${CPACK_PACKAGE_NAME} Win32")
|
||||
ENDIF()
|
||||
|
||||
# NSIS specific settings
|
||||
IF (NOT EMBREE_ZIP_MODE)
|
||||
SET(CPACK_GENERATOR NSIS)
|
||||
SET(CPACK_GENERATOR WIX)
|
||||
SET(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}.${ARCH}")
|
||||
SET(CPACK_COMPONENTS_ALL lib devel examples)
|
||||
SET(CPACK_NSIS_INSTALL_ROOT "${PROGRAMFILES}\\\\Intel")
|
||||
SET(CPACK_PACKAGE_INSTALL_DIRECTORY "Embree v${EMBREE_VERSION} ${ARCH}")
|
||||
SET(CPACK_NSIS_DISPLAY_NAME "Embree v${EMBREE_VERSION} ${ARCH}")
|
||||
SET(CPACK_NSIS_PACKAGE_NAME "Embree v${EMBREE_VERSION} ${ARCH}")
|
||||
SET(CPACK_NSIS_URL_INFO_ABOUT http://embree.github.io/)
|
||||
#SET(CPACK_NSIS_HELP_LINK http://embree.github.io/downloads.html#windows)
|
||||
SET(CPACK_NSIS_MUI_ICON ${PROJECT_SOURCE_DIR}/scripts/install_windows/icon32.ico)
|
||||
SET(CPACK_NSIS_CONTACT ${CPACK_PACKAGE_CONTACT})
|
||||
#SET(CPACK_NSIS_EXTRA_PREINSTALL_COMMANDS ${CPACK_NSIS_EXTRA_PREINSTALL_COMMANDS} "\n CreateDirectory \\\"$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\"")
|
||||
#SET(CPACK_NSIS_EXTRA_PREINSTALL_COMMANDS ${CPACK_NSIS_EXTRA_PREINSTALL_COMMANDS} "\n CreateDirectory \\\"$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\documentation\\\"")
|
||||
#SET(CPACK_NSIS_EXTRA_PREINSTALL_COMMANDS ${CPACK_NSIS_EXTRA_PREINSTALL_COMMANDS} "\n CreateDirectory \\\"$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\tutorials\\\" \n")
|
||||
#SET(CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS ${CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS} "\n ${UNINSTALL_LIST}\n RMDir \\\"$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\documentation\\\"")
|
||||
#SET(CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS ${CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS} "\n ${UNINSTALL_LIST}\n RMDir \\\"$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\tutorials\\\"")
|
||||
#SET(CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS ${CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS} "\n ${UNINSTALL_LIST}\n RMDir \\\"$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\"\n")
|
||||
SET(CPACK_PACKAGE_INSTALL_DIRECTORY "Intel\\\\Embree v${EMBREE_VERSION} ${ARCH}")
|
||||
SET(CPACK_WIX_PRODUCT_GUID "331BD5A9-DAD6-486B-A435-18AAB80${EMBREE_VERSION_NUMBER}")
|
||||
SET(CPACK_WIX_UPGRADE_GUID "331BD5A9-DAD6-486B-A435-18AAB80${EMBREE_VERSION_MAJOR}0000") # upgrade as long as major version is the same
|
||||
SET(CPACK_WIX_CMAKE_PACKAGE_REGISTRY TRUE)
|
||||
IF (EMBREE_TESTING_PACKAGE)
|
||||
ADD_TEST(NAME "BuildPackage" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMAND ${PROJECT_SOURCE_DIR}/scripts/package_win.bat ${CPACK_PACKAGE_FILE_NAME}.exe ${CMAKE_BUILD_TYPE})
|
||||
ENDIF()
|
||||
@@ -230,7 +217,6 @@ ELSEIF(APPLE)
|
||||
# Linux specific settings
|
||||
ELSE()
|
||||
|
||||
|
||||
IF (NOT EMBREE_ZIP_MODE)
|
||||
|
||||
SET(CPACK_GENERATOR RPM)
|
||||
|
||||
@@ -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);
|
||||
|
||||
/*! @} */
|
||||
|
||||
|
||||
@@ -16,6 +16,6 @@
|
||||
|
||||
#define RTCORE_VERSION_MAJOR 2
|
||||
#define RTCORE_VERSION_MINOR 17
|
||||
#define RTCORE_VERSION_PATCH 0
|
||||
#define RTCORE_VERSION 21700
|
||||
#define RTCORE_VERSION_STRING "2.17.0-alpha.0"
|
||||
#define RTCORE_VERSION_PATCH 1
|
||||
#define RTCORE_VERSION 21701
|
||||
#define RTCORE_VERSION_STRING "2.17.1-alpha.0"
|
||||
|
||||
@@ -14,6 +14,14 @@
|
||||
## limitations under the License. ##
|
||||
## ======================================================================== ##
|
||||
|
||||
MACRO(DISABLE_STACK_PROTECTOR_FOR_INTERSECTORS)
|
||||
FOREACH(src ${ARGN})
|
||||
IF (src MATCHES ".*intersector.*")
|
||||
DISABLE_STACK_PROTECTOR_FOR_FILE(${src})
|
||||
ENDIF()
|
||||
ENDFOREACH()
|
||||
ENDMACRO()
|
||||
|
||||
SOURCE_GROUP("Source Files\\bvh4" "/bvh4/" )
|
||||
SOURCE_GROUP("Source Files\\bvh8" "/bvh8/" )
|
||||
SOURCE_GROUP("Source Files\\geometry" "/geometry/" )
|
||||
@@ -62,6 +70,7 @@ SET(EMBREE_LIBRARY_FILES
|
||||
bvh/bvh_refit.cpp
|
||||
bvh/bvh_builder.cpp
|
||||
bvh/bvh_builder_hair.cpp
|
||||
bvh/bvh_builder_hair_mb.cpp
|
||||
bvh/bvh_builder_morton.cpp
|
||||
bvh/bvh_builder_sah.cpp
|
||||
bvh/bvh_builder_twolevel.cpp
|
||||
@@ -109,6 +118,7 @@ MACRO(embree_files TARGET ISA)
|
||||
bvh/bvh_refit.cpp
|
||||
bvh/bvh_builder.cpp
|
||||
bvh/bvh_builder_hair.cpp
|
||||
bvh/bvh_builder_hair_mb.cpp
|
||||
bvh/bvh_builder_sah.cpp
|
||||
bvh/bvh_builder_twolevel.cpp
|
||||
bvh/bvh_builder_instancing.cpp)
|
||||
@@ -208,6 +218,7 @@ MACRO (CheckGlobals library)
|
||||
ENDIF()
|
||||
ENDMACRO()
|
||||
|
||||
DISABLE_STACK_PROTECTOR_FOR_INTERSECTORS(${EMBREE_LIBRARY_FILES})
|
||||
ADD_ISPC_LIBRARY(embree ${EMBREE_LIB_TYPE} ${EMBREE_LIBRARY_FILES} $<TARGET_OBJECTS:algorithms>)
|
||||
SET_TARGET_PROPERTIES(embree PROPERTIES COMPILE_FLAGS "${FLAGS_LOWEST}")
|
||||
SET_TARGET_PROPERTIES(embree PROPERTIES COMPILE_DEFINITIONS "EMBREE_LOWEST_ISA")
|
||||
@@ -225,6 +236,7 @@ ENDIF()
|
||||
#ENDIF ()
|
||||
|
||||
IF (EMBREE_ISA_SSE42 AND EMBREE_LIBRARY_FILES_SSE42)
|
||||
DISABLE_STACK_PROTECTOR_FOR_INTERSECTORS(${EMBREE_LIBRARY_FILES_SSE42})
|
||||
ADD_LIBRARY(embree_sse42 STATIC ${EMBREE_LIBRARY_FILES_SSE42})
|
||||
SET_TARGET_PROPERTIES(embree_sse42 PROPERTIES COMPILE_FLAGS "${FLAGS_SSE42}")
|
||||
SET_PROPERTY(TARGET embree_sse42 PROPERTY FOLDER kernels)
|
||||
@@ -233,6 +245,7 @@ IF (EMBREE_ISA_SSE42 AND EMBREE_LIBRARY_FILES_SSE42)
|
||||
ENDIF ()
|
||||
|
||||
IF (EMBREE_ISA_AVX AND EMBREE_LIBRARY_FILES_AVX)
|
||||
DISABLE_STACK_PROTECTOR_FOR_INTERSECTORS(${EMBREE_LIBRARY_FILES_AVX})
|
||||
ADD_LIBRARY(embree_avx STATIC ${EMBREE_LIBRARY_FILES_AVX})
|
||||
SET_TARGET_PROPERTIES(embree_avx PROPERTIES COMPILE_FLAGS "${FLAGS_AVX}")
|
||||
SET_PROPERTY(TARGET embree_avx PROPERTY FOLDER kernels)
|
||||
@@ -241,6 +254,7 @@ IF (EMBREE_ISA_AVX AND EMBREE_LIBRARY_FILES_AVX)
|
||||
ENDIF()
|
||||
|
||||
IF (EMBREE_ISA_AVX2 AND EMBREE_LIBRARY_FILES_AVX2)
|
||||
DISABLE_STACK_PROTECTOR_FOR_INTERSECTORS(${EMBREE_LIBRARY_FILES_AVX2})
|
||||
ADD_LIBRARY(embree_avx2 STATIC ${EMBREE_LIBRARY_FILES_AVX2})
|
||||
SET_TARGET_PROPERTIES(embree_avx2 PROPERTIES COMPILE_FLAGS "${FLAGS_AVX2}")
|
||||
SET_PROPERTY(TARGET embree_avx2 PROPERTY FOLDER kernels)
|
||||
@@ -249,6 +263,7 @@ IF (EMBREE_ISA_AVX2 AND EMBREE_LIBRARY_FILES_AVX2)
|
||||
ENDIF()
|
||||
|
||||
IF (EMBREE_ISA_AVX512KNL AND EMBREE_LIBRARY_FILES_AVX512KNL)
|
||||
DISABLE_STACK_PROTECTOR_FOR_INTERSECTORS(${EMBREE_LIBRARY_FILES_AVX512KNL})
|
||||
ADD_LIBRARY(embree_avx512knl STATIC ${EMBREE_LIBRARY_FILES_AVX512KNL})
|
||||
SET_TARGET_PROPERTIES(embree_avx512knl PROPERTIES COMPILE_FLAGS "${FLAGS_AVX512KNL}")
|
||||
SET_PROPERTY(TARGET embree_avx512knl PROPERTY FOLDER kernels)
|
||||
@@ -257,6 +272,7 @@ IF (EMBREE_ISA_AVX512KNL AND EMBREE_LIBRARY_FILES_AVX512KNL)
|
||||
ENDIF()
|
||||
|
||||
IF (EMBREE_ISA_AVX512SKX AND EMBREE_LIBRARY_FILES_AVX512SKX)
|
||||
DISABLE_STACK_PROTECTOR_FOR_INTERSECTORS(${EMBREE_LIBRARY_FILES_AVX512SKX})
|
||||
ADD_LIBRARY(embree_avx512skx STATIC ${EMBREE_LIBRARY_FILES_AVX512SKX})
|
||||
SET_TARGET_PROPERTIES(embree_avx512skx PROPERTIES COMPILE_FLAGS "${FLAGS_AVX512SKX}")
|
||||
SET_PROPERTY(TARGET embree_avx512skx PROPERTY FOLDER kernels)
|
||||
|
||||
+12
-10
@@ -134,7 +134,7 @@ namespace embree
|
||||
/*! Maximal depth of the BVH. */
|
||||
static const size_t maxBuildDepth = 32;
|
||||
static const size_t maxBuildDepthLeaf = maxBuildDepth+8;
|
||||
static const size_t maxDepth = maxBuildDepth+maxBuildDepthLeaf;
|
||||
static const size_t maxDepth = 2*maxBuildDepthLeaf; // 2x because of two level builder
|
||||
|
||||
/*! Maximal number of primitive blocks in a leaf. */
|
||||
static const size_t maxLeafBlocks = items_mask-tyLeaf;
|
||||
@@ -169,6 +169,7 @@ namespace embree
|
||||
prefetchL2(((char*)ptr)+3*64);
|
||||
}
|
||||
if ((N >= 8) && (types > BVH_FLAG_ALIGNED_NODE)) {
|
||||
/* KNL still needs L2 prefetches for large nodes */
|
||||
prefetchL2(((char*)ptr)+4*64);
|
||||
prefetchL2(((char*)ptr)+5*64);
|
||||
prefetchL2(((char*)ptr)+6*64);
|
||||
@@ -191,10 +192,11 @@ namespace embree
|
||||
prefetchL1(((char*)ptr)+3*64);
|
||||
}
|
||||
if ((N >= 8) && (types > BVH_FLAG_ALIGNED_NODE)) {
|
||||
prefetchL1(((char*)ptr)+4*64);
|
||||
prefetchL1(((char*)ptr)+5*64);
|
||||
prefetchL1(((char*)ptr)+6*64);
|
||||
prefetchL1(((char*)ptr)+7*64);
|
||||
/* deactivate for large nodes on Xeon, as it introduces regressions */
|
||||
//prefetchL1(((char*)ptr)+4*64);
|
||||
//prefetchL1(((char*)ptr)+5*64);
|
||||
//prefetchL1(((char*)ptr)+6*64);
|
||||
//prefetchL1(((char*)ptr)+7*64);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -362,9 +364,9 @@ namespace embree
|
||||
__forceinline const QuantizedNode* quantizedNode() const { assert(isQuantizedNode()); return (const QuantizedNode*)(ptr & ~(size_t)align_mask ); }
|
||||
|
||||
/*! returns leaf pointer */
|
||||
__forceinline char* leaf(size_t& ty) const {
|
||||
__forceinline char* leaf(size_t& num) const {
|
||||
assert(isLeaf());
|
||||
ty = (ptr & (size_t)items_mask)-tyLeaf;
|
||||
num = (ptr & (size_t)items_mask)-tyLeaf;
|
||||
return (char*)(ptr & ~(size_t)align_mask);
|
||||
}
|
||||
|
||||
@@ -1454,10 +1456,10 @@ namespace embree
|
||||
}
|
||||
|
||||
/*! Encodes a leaf */
|
||||
static __forceinline NodeRef encodeLeaf(void* tri, size_t ty) {
|
||||
static __forceinline NodeRef encodeLeaf(void* tri, size_t num) {
|
||||
assert(!((size_t)tri & align_mask));
|
||||
assert(ty <= maxLeafBlocks);
|
||||
return NodeRef((size_t)tri | (tyLeaf+min(ty,(size_t)maxLeafBlocks)));
|
||||
assert(num <= maxLeafBlocks);
|
||||
return NodeRef((size_t)tri | (tyLeaf+min(num,(size_t)maxLeafBlocks)));
|
||||
}
|
||||
|
||||
/*! Encodes a leaf */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -78,7 +78,7 @@ namespace embree
|
||||
size_t items = set.size();
|
||||
Primitive* accel = (Primitive*) alloc.malloc1(items*sizeof(Primitive),BVH::byteAlignment);
|
||||
for (size_t i=0; i<items; i++) {
|
||||
accel[i].fill(prims,start,set.end(),bvh->scene,i==(items-1));
|
||||
accel[i].fill(prims,start,set.end(),bvh->scene);
|
||||
}
|
||||
return bvh->encodeLeaf((char*)accel,items);
|
||||
};
|
||||
@@ -109,103 +109,14 @@ namespace embree
|
||||
prims.clear();
|
||||
}
|
||||
};
|
||||
|
||||
/* FIXME: add fast path for single-segment motion blur */
|
||||
template<int N, typename Primitive>
|
||||
struct BVHNHairMBlurBuilderSAH : public Builder
|
||||
{
|
||||
typedef BVHN<N> BVH;
|
||||
typedef typename BVH::NodeRef NodeRef;
|
||||
typedef typename BVH::NodeRecordMB4D NodeRecordMB4D;
|
||||
|
||||
BVH* bvh;
|
||||
Scene* scene;
|
||||
|
||||
BVHNHairMBlurBuilderSAH (BVH* bvh, Scene* scene)
|
||||
: bvh(bvh), scene(scene) {}
|
||||
|
||||
void build()
|
||||
{
|
||||
/* fast path for empty BVH */
|
||||
const size_t numPrimitives = scene->getNumPrimitives<NativeCurves,true>();
|
||||
if (numPrimitives == 0) {
|
||||
bvh->set(BVH::emptyNode,empty,0);
|
||||
return;
|
||||
}
|
||||
|
||||
double t0 = bvh->preBuild(TOSTRING(isa) "::BVH" + toString(N) + "HairMBlurBuilderSAH");
|
||||
|
||||
//profile(1,5,numPrimitives,[&] (ProfileTimer& timer) {
|
||||
|
||||
/* create primref array */
|
||||
mvector<PrimRefMB> prims0(scene->device,numPrimitives);
|
||||
const PrimInfoMB pinfo = createPrimRefArrayMSMBlur<NativeCurves>(scene,prims0,bvh->scene->progressInterface);
|
||||
|
||||
/* estimate acceleration structure size */
|
||||
const size_t node_bytes = pinfo.num_time_segments*sizeof(typename BVH::AlignedNodeMB)/(4*N);
|
||||
const size_t leaf_bytes = size_t(1.2*Primitive::blocks(pinfo.num_time_segments)*sizeof(Primitive));
|
||||
bvh->alloc.init_estimate(node_bytes+leaf_bytes);
|
||||
|
||||
/* settings for BVH build */
|
||||
BVHBuilderHairMSMBlur::Settings settings;
|
||||
settings.branchingFactor = N;
|
||||
settings.maxDepth = BVH::maxBuildDepthLeaf;
|
||||
settings.logBlockSize = 1;
|
||||
settings.minLeafSize = 1;
|
||||
settings.maxLeafSize = BVH::maxLeafBlocks;
|
||||
|
||||
/* creates a leaf node */
|
||||
auto createLeaf = [&] (const SetMB& prims, const FastAllocator::CachedAllocator& alloc) -> NodeRecordMB4D
|
||||
{
|
||||
size_t start = prims.object_range.begin();
|
||||
size_t end = prims.object_range.end();
|
||||
size_t items = prims.object_range.size();
|
||||
Primitive* accel = (Primitive*) alloc.malloc1(items*sizeof(Primitive));
|
||||
const NodeRef node = bvh->encodeLeaf((char*)accel,items);
|
||||
|
||||
LBBox3fa bounds = empty;
|
||||
for (size_t i=0; i<items; i++)
|
||||
bounds.extend(accel[i].fillMB(prims.prims->data(),start,end,bvh->scene,prims.time_range,i==(items-1)));
|
||||
|
||||
return NodeRecordMB4D(node,bounds,prims.time_range);
|
||||
};
|
||||
|
||||
/* build the hierarchy */
|
||||
auto root = BVHBuilderHairMSMBlur::build<NodeRef>
|
||||
(scene, prims0, pinfo,
|
||||
RecalculatePrimRef<NativeCurves>(scene),
|
||||
typename BVH::CreateAlloc(bvh),
|
||||
typename BVH::AlignedNodeMB4D::Create(),
|
||||
typename BVH::AlignedNodeMB4D::Set(),
|
||||
typename BVH::UnalignedNodeMB::Create(),
|
||||
typename BVH::UnalignedNodeMB::Set(),
|
||||
createLeaf,
|
||||
bvh->scene->progressInterface,
|
||||
settings);
|
||||
|
||||
bvh->set(root.ref,root.lbounds,pinfo.num_time_segments);
|
||||
|
||||
//});
|
||||
|
||||
/* clear temporary data for static geometry */
|
||||
if (scene->isStatic()) bvh->shrink();
|
||||
bvh->cleanup();
|
||||
bvh->postBuild(t0);
|
||||
}
|
||||
|
||||
void clear() {
|
||||
}
|
||||
};
|
||||
|
||||
/*! entry functions for the builder */
|
||||
Builder* BVH4Bezier1vBuilder_OBB_New (void* bvh, Scene* scene, size_t mode) { return new BVHNHairBuilderSAH<4,Bezier1v>((BVH4*)bvh,scene); }
|
||||
Builder* BVH4Bezier1iBuilder_OBB_New (void* bvh, Scene* scene, size_t mode) { return new BVHNHairBuilderSAH<4,Bezier1i>((BVH4*)bvh,scene); }
|
||||
Builder* BVH4OBBBezier1iMBBuilder_OBB (void* bvh, Scene* scene, size_t mode) { return new BVHNHairMBlurBuilderSAH<4,Bezier1i>((BVH4*)bvh,scene); }
|
||||
|
||||
#if defined(__AVX__)
|
||||
Builder* BVH8Bezier1vBuilder_OBB_New (void* bvh, Scene* scene, size_t mode) { return new BVHNHairBuilderSAH<8,Bezier1v>((BVH8*)bvh,scene); }
|
||||
Builder* BVH8Bezier1iBuilder_OBB_New (void* bvh, Scene* scene, size_t mode) { return new BVHNHairBuilderSAH<8,Bezier1i>((BVH8*)bvh,scene); }
|
||||
Builder* BVH8OBBBezier1iMBBuilder_OBB (void* bvh, Scene* scene, size_t mode) { return new BVHNHairMBlurBuilderSAH<8,Bezier1i>((BVH8*)bvh,scene); }
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
// ======================================================================== //
|
||||
// Copyright 2009-2017 Intel Corporation //
|
||||
// //
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); //
|
||||
// you may not use this file except in compliance with the License. //
|
||||
// You may obtain a copy of the License at //
|
||||
// //
|
||||
// http://www.apache.org/licenses/LICENSE-2.0 //
|
||||
// //
|
||||
// Unless required by applicable law or agreed to in writing, software //
|
||||
// distributed under the License is distributed on an "AS IS" BASIS, //
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
|
||||
// See the License for the specific language governing permissions and //
|
||||
// limitations under the License. //
|
||||
// ======================================================================== //
|
||||
|
||||
#include "../builders/bvh_builder_hair.h"
|
||||
#include "../builders/bvh_builder_msmblur_hair.h"
|
||||
#include "../builders/primrefgen.h"
|
||||
|
||||
#include "../geometry/bezier1v.h"
|
||||
#include "../geometry/bezier1i.h"
|
||||
|
||||
#if defined(EMBREE_GEOMETRY_HAIR)
|
||||
|
||||
namespace embree
|
||||
{
|
||||
namespace isa
|
||||
{
|
||||
/* FIXME: add fast path for single-segment motion blur */
|
||||
template<int N, typename Primitive>
|
||||
struct BVHNHairMBlurBuilderSAH : public Builder
|
||||
{
|
||||
typedef BVHN<N> BVH;
|
||||
typedef typename BVH::NodeRef NodeRef;
|
||||
typedef typename BVH::NodeRecordMB4D NodeRecordMB4D;
|
||||
|
||||
BVH* bvh;
|
||||
Scene* scene;
|
||||
|
||||
BVHNHairMBlurBuilderSAH (BVH* bvh, Scene* scene)
|
||||
: bvh(bvh), scene(scene) {}
|
||||
|
||||
void build()
|
||||
{
|
||||
/* fast path for empty BVH */
|
||||
const size_t numPrimitives = scene->getNumPrimitives<NativeCurves,true>();
|
||||
if (numPrimitives == 0) {
|
||||
bvh->set(BVH::emptyNode,empty,0);
|
||||
return;
|
||||
}
|
||||
|
||||
double t0 = bvh->preBuild(TOSTRING(isa) "::BVH" + toString(N) + "HairMBlurBuilderSAH");
|
||||
|
||||
//profile(1,5,numPrimitives,[&] (ProfileTimer& timer) {
|
||||
|
||||
/* create primref array */
|
||||
mvector<PrimRefMB> prims0(scene->device,numPrimitives);
|
||||
const PrimInfoMB pinfo = createPrimRefArrayMSMBlur<NativeCurves>(scene,prims0,bvh->scene->progressInterface);
|
||||
|
||||
/* estimate acceleration structure size */
|
||||
const size_t node_bytes = pinfo.num_time_segments*sizeof(typename BVH::AlignedNodeMB)/(4*N);
|
||||
const size_t leaf_bytes = size_t(1.2*Primitive::blocks(pinfo.num_time_segments)*sizeof(Primitive));
|
||||
bvh->alloc.init_estimate(node_bytes+leaf_bytes);
|
||||
|
||||
/* settings for BVH build */
|
||||
BVHBuilderHairMSMBlur::Settings settings;
|
||||
settings.branchingFactor = N;
|
||||
settings.maxDepth = BVH::maxBuildDepthLeaf;
|
||||
settings.logBlockSize = 1;
|
||||
settings.minLeafSize = 1;
|
||||
settings.maxLeafSize = BVH::maxLeafBlocks;
|
||||
|
||||
/* creates a leaf node */
|
||||
auto createLeaf = [&] (const SetMB& prims, const FastAllocator::CachedAllocator& alloc) -> NodeRecordMB4D
|
||||
{
|
||||
size_t start = prims.object_range.begin();
|
||||
size_t end = prims.object_range.end();
|
||||
size_t items = prims.object_range.size();
|
||||
Primitive* accel = (Primitive*) alloc.malloc1(items*sizeof(Primitive));
|
||||
const NodeRef node = bvh->encodeLeaf((char*)accel,items);
|
||||
|
||||
LBBox3fa bounds = empty;
|
||||
for (size_t i=0; i<items; i++)
|
||||
bounds.extend(accel[i].fillMB(prims.prims->data(),start,end,bvh->scene,prims.time_range));
|
||||
|
||||
return NodeRecordMB4D(node,bounds,prims.time_range);
|
||||
};
|
||||
|
||||
/* build the hierarchy */
|
||||
auto root = BVHBuilderHairMSMBlur::build<NodeRef>
|
||||
(scene, prims0, pinfo,
|
||||
RecalculatePrimRef<NativeCurves>(scene),
|
||||
typename BVH::CreateAlloc(bvh),
|
||||
typename BVH::AlignedNodeMB4D::Create(),
|
||||
typename BVH::AlignedNodeMB4D::Set(),
|
||||
typename BVH::UnalignedNodeMB::Create(),
|
||||
typename BVH::UnalignedNodeMB::Set(),
|
||||
createLeaf,
|
||||
bvh->scene->progressInterface,
|
||||
settings);
|
||||
|
||||
bvh->set(root.ref,root.lbounds,pinfo.num_time_segments);
|
||||
|
||||
//});
|
||||
|
||||
/* clear temporary data for static geometry */
|
||||
if (scene->isStatic()) bvh->shrink();
|
||||
bvh->cleanup();
|
||||
bvh->postBuild(t0);
|
||||
}
|
||||
|
||||
void clear() {
|
||||
}
|
||||
};
|
||||
|
||||
/*! entry functions for the builder */
|
||||
Builder* BVH4OBBBezier1iMBBuilder_OBB (void* bvh, Scene* scene, size_t mode) { return new BVHNHairMBlurBuilderSAH<4,Bezier1i>((BVH4*)bvh,scene); }
|
||||
|
||||
#if defined(__AVX__)
|
||||
Builder* BVH8OBBBezier1iMBBuilder_OBB (void* bvh, Scene* scene, size_t mode) { return new BVHNHairMBlurBuilderSAH<8,Bezier1i>((BVH8*)bvh,scene); }
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -128,7 +128,7 @@ namespace embree
|
||||
v2.x[i] = p2.x; v2.y[i] = p2.y; v2.z[i] = p2.z;
|
||||
}
|
||||
|
||||
Triangle4::store_nt(accel,Triangle4(v0,v1,v2,vgeomID,vprimID,true));
|
||||
Triangle4::store_nt(accel,Triangle4(v0,v1,v2,vgeomID,vprimID));
|
||||
BBox3fa box_o = BBox3fa((Vec3fa)lower,(Vec3fa)upper);
|
||||
#if ROTATE_TREE
|
||||
if (N == 4)
|
||||
@@ -183,7 +183,7 @@ namespace embree
|
||||
v1.x[i] = p1.x; v1.y[i] = p1.y; v1.z[i] = p1.z;
|
||||
v2.x[i] = p2.x; v2.y[i] = p2.y; v2.z[i] = p2.z;
|
||||
}
|
||||
Triangle4v::store_nt(accel,Triangle4v(v0,v1,v2,vgeomID,vprimID,true));
|
||||
Triangle4v::store_nt(accel,Triangle4v(v0,v1,v2,vgeomID,vprimID));
|
||||
BBox3fa box_o = BBox3fa((Vec3fa)lower,(Vec3fa)upper);
|
||||
#if ROTATE_TREE
|
||||
if (N == 4)
|
||||
@@ -249,7 +249,7 @@ namespace embree
|
||||
v2[i] = 0;
|
||||
}
|
||||
|
||||
Triangle4i::store_nt(accel,Triangle4i(v0,v1,v2,vgeomID,vprimID,true));
|
||||
Triangle4i::store_nt(accel,Triangle4i(v0,v1,v2,vgeomID,vprimID));
|
||||
BBox3fa box_o = BBox3fa((Vec3fa)lower,(Vec3fa)upper);
|
||||
#if ROTATE_TREE
|
||||
if (N == 4)
|
||||
@@ -306,7 +306,7 @@ namespace embree
|
||||
v2.x[i] = p2.x; v2.y[i] = p2.y; v2.z[i] = p2.z;
|
||||
v3.x[i] = p3.x; v3.y[i] = p3.y; v3.z[i] = p3.z;
|
||||
}
|
||||
Quad4v::store_nt(accel,Quad4v(v0,v1,v2,v3,vgeomID,vprimID,true));
|
||||
Quad4v::store_nt(accel,Quad4v(v0,v1,v2,v3,vgeomID,vprimID));
|
||||
BBox3fa box_o = BBox3fa((Vec3fa)lower,(Vec3fa)upper);
|
||||
#if ROTATE_TREE
|
||||
if (N == 4)
|
||||
@@ -349,7 +349,7 @@ namespace embree
|
||||
const unsigned index = morton[start+i].index;
|
||||
const unsigned primID = index;
|
||||
bounds.extend(mesh->bounds(primID));
|
||||
new (&accel[i]) Object(geomID,primID,true);
|
||||
new (&accel[i]) Object(geomID,primID);
|
||||
}
|
||||
BBox3fa box_o = bounds;
|
||||
#if ROTATE_TREE
|
||||
|
||||
@@ -64,7 +64,7 @@ namespace embree
|
||||
Primitive* accel = (Primitive*) alloc.malloc1(items*sizeof(Primitive),BVH::byteAlignment);
|
||||
typename BVH::NodeRef node = BVH::encodeLeaf((char*)accel,items);
|
||||
for (size_t i=0; i<items; i++) {
|
||||
accel[i].fill(prims,start,set.end(),bvh->scene,i==(items-1));
|
||||
accel[i].fill(prims,start,set.end(),bvh->scene);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
@@ -89,7 +89,7 @@ namespace embree
|
||||
Primitive* accel = (Primitive*) alloc.malloc1(items*sizeof(Primitive),BVH::byteAlignment);
|
||||
typename BVH::NodeRef node = BVH::encodeLeaf((char*)accel,items);
|
||||
for (size_t i=0; i<items; i++) {
|
||||
accel[i].fill(prims,start,set.end(),bvh->scene,i==(items-1));
|
||||
accel[i].fill(prims,start,set.end(),bvh->scene);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
@@ -364,7 +364,7 @@ namespace embree
|
||||
|
||||
LBBox3fa allBounds = empty;
|
||||
for (size_t i=0; i<items; i++)
|
||||
allBounds.extend(accel[i].fillMB(prims, start, set.end(), bvh->scene, time, i==(items-1)));
|
||||
allBounds.extend(accel[i].fillMB(prims, start, set.end(), bvh->scene, time));
|
||||
|
||||
return NodeRecordMB(node,allBounds);
|
||||
}
|
||||
@@ -392,7 +392,7 @@ namespace embree
|
||||
NodeRef node = bvh->encodeLeaf((char*)accel,items);
|
||||
LBBox3fa allBounds = empty;
|
||||
for (size_t i=0; i<items; i++)
|
||||
allBounds.extend(accel[i].fillMB(current.prims.prims->data(), start, current.prims.object_range.end(), bvh->scene, current.prims.time_range, i==(items-1)));
|
||||
allBounds.extend(accel[i].fillMB(current.prims.prims->data(), start, current.prims.object_range.end(), bvh->scene, current.prims.time_range));
|
||||
return NodeRecordMB4D(node,allBounds,current.prims.time_range);
|
||||
}
|
||||
|
||||
|
||||
@@ -37,9 +37,10 @@ namespace embree
|
||||
namespace isa
|
||||
{
|
||||
template<int N, int types, bool robust, typename PrimitiveIntersector1>
|
||||
void BVHNIntersector1<N,types,robust,PrimitiveIntersector1>::intersect(const BVH* __restrict__ bvh, Ray& __restrict__ ray, IntersectContext* context)
|
||||
void BVHNIntersector1<N,types,robust,PrimitiveIntersector1>::intersect(const Accel::Intersectors* __restrict__ This, Ray& __restrict__ ray, IntersectContext* __restrict__ context)
|
||||
{
|
||||
/*! perform per ray precalculations required by the primitive intersector */
|
||||
const BVH* __restrict__ bvh = (const BVH*) This->ptr;
|
||||
Precalculations pre(ray,bvh);
|
||||
|
||||
/*! stack state */
|
||||
@@ -105,12 +106,8 @@ namespace embree
|
||||
if (unlikely(nodeTraverser.traverseTransform(cur,ray,vray,context,stackPtr,stackEnd)))
|
||||
goto pop;
|
||||
|
||||
/*! check for empty leaf in case we accidentally hit one */
|
||||
assert(cur != BVH::emptyNode);
|
||||
if (cur == BVH::emptyNode)
|
||||
goto pop;
|
||||
|
||||
/*! this is a leaf node */
|
||||
assert(cur != BVH::emptyNode);
|
||||
STAT3(normal.trav_leaves,1,1,1);
|
||||
size_t num; Primitive* prim = (Primitive*) cur.leaf(num);
|
||||
size_t lazy_node = 0;
|
||||
@@ -128,13 +125,14 @@ namespace embree
|
||||
}
|
||||
|
||||
template<int N, int types, bool robust, typename PrimitiveIntersector1>
|
||||
void BVHNIntersector1<N,types,robust,PrimitiveIntersector1>::occluded(const BVH* __restrict__ bvh, Ray& __restrict__ ray, IntersectContext* context)
|
||||
void BVHNIntersector1<N,types,robust,PrimitiveIntersector1>::occluded(const Accel::Intersectors* __restrict__ This, Ray& __restrict__ ray, IntersectContext* __restrict__ context)
|
||||
{
|
||||
/*! early out for already occluded rays */
|
||||
if (unlikely(ray.geomID == 0))
|
||||
return;
|
||||
|
||||
/*! perform per ray precalculations required by the primitive intersector */
|
||||
const BVH* __restrict__ bvh = (const BVH*) This->ptr;
|
||||
Precalculations pre(ray,bvh);
|
||||
|
||||
/*! stack state */
|
||||
@@ -191,12 +189,8 @@ namespace embree
|
||||
if (unlikely(nodeTraverser.traverseTransform(cur,ray,vray,context,stackPtr,stackEnd)))
|
||||
goto pop;
|
||||
|
||||
/*! check for empty leaf in case we accidentally hit one */
|
||||
assert(cur != BVH::emptyNode);
|
||||
if (cur == BVH::emptyNode)
|
||||
goto pop;
|
||||
|
||||
/*! this is a leaf node */
|
||||
assert(cur != BVH::emptyNode);
|
||||
STAT3(shadow.trav_leaves,1,1,1);
|
||||
size_t num; Primitive* prim = (Primitive*) cur.leaf(num);
|
||||
size_t lazy_node = 0;
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,12 +105,8 @@ namespace embree
|
||||
BVHNNodeTraverser1<N,Nx,types>::traverseClosestHit(cur,mask,tNear,stackPtr,stackEnd);
|
||||
}
|
||||
|
||||
/*! check for empty leaf in case we accidentally hit one */
|
||||
assert(cur != BVH::emptyNode);
|
||||
if (cur == BVH::emptyNode)
|
||||
goto pop;
|
||||
|
||||
/*! this is a leaf node */
|
||||
assert(cur != BVH::emptyNode);
|
||||
STAT3(normal.trav_leaves, 1, 1, 1);
|
||||
size_t num; Primitive* prim = (Primitive*)cur.leaf(num);
|
||||
|
||||
@@ -128,13 +124,15 @@ namespace embree
|
||||
}
|
||||
|
||||
template<int N, int K, int types, bool robust, typename PrimitiveIntersectorK, bool single>
|
||||
void BVHNIntersectorKHybrid<N,K,types,robust,PrimitiveIntersectorK,single>::intersect(vint<K>* __restrict__ valid_i, BVH* __restrict__ bvh, RayK<K>& __restrict__ ray, IntersectContext* context)
|
||||
void BVHNIntersectorKHybrid<N,K,types,robust,PrimitiveIntersectorK,single>::intersect(vint<K>* __restrict__ valid_i, Accel::Intersectors* __restrict__ This, RayK<K>& __restrict__ ray, IntersectContext* __restrict__ context)
|
||||
{
|
||||
BVH* __restrict__ bvh = (BVH*) This->ptr;
|
||||
|
||||
#if ENABLE_FAST_COHERENT_CODEPATHS == 1
|
||||
assert(context);
|
||||
if (unlikely(types == BVH_AN1 && context->user && isCoherent(context->user->flags)))
|
||||
{
|
||||
intersect_coherent(valid_i,bvh,ray,context);
|
||||
intersect_coherent(valid_i,This,ray,context);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@@ -181,7 +179,7 @@ namespace embree
|
||||
/* determine switch threshold based on flags */
|
||||
const size_t switchThreshold = (context->user && isCoherent(context->user->flags)) ? 2 : switchThresholdIncoherent;
|
||||
|
||||
vint<K> octant = \
|
||||
vint<K> octant =
|
||||
select(vfloat<K>(rdir.x) < 0.0f,vint<K>(1),vint<K>(zero)) |
|
||||
select(vfloat<K>(rdir.y) < 0.0f,vint<K>(2),vint<K>(zero)) |
|
||||
select(vfloat<K>(rdir.z) < 0.0f,vint<K>(4),vint<K>(zero));
|
||||
@@ -349,12 +347,8 @@ namespace embree
|
||||
break;
|
||||
}
|
||||
|
||||
/*! check for empty leaf in case we accidentally hit one */
|
||||
assert(cur != BVH::emptyNode);
|
||||
if (cur == BVH::emptyNode)
|
||||
goto pop;
|
||||
|
||||
/* intersect leaf */
|
||||
assert(cur != BVH::emptyNode);
|
||||
const vbool<K> valid_leaf = ray_tfar > curDist;
|
||||
STAT3(normal.trav_leaves,1,popcnt(valid_leaf),K);
|
||||
if (unlikely(none(valid_leaf))) continue;
|
||||
@@ -376,8 +370,13 @@ namespace embree
|
||||
|
||||
|
||||
template<int N, int K, int types, bool robust, typename PrimitiveIntersectorK, bool single>
|
||||
void BVHNIntersectorKHybrid<N,K,types,robust,PrimitiveIntersectorK,single>::intersect_coherent(vint<K>* __restrict__ valid_i, BVH* __restrict__ bvh, RayK<K>& __restrict__ ray, IntersectContext* context)
|
||||
void BVHNIntersectorKHybrid<N,K,types,robust,PrimitiveIntersectorK,single>::intersect_coherent(vint<K>* __restrict__ valid_i,
|
||||
Accel::Intersectors* __restrict__ This,
|
||||
RayK<K>& __restrict__ ray,
|
||||
IntersectContext* context)
|
||||
{
|
||||
BVH* __restrict__ bvh = (BVH*) This->ptr;
|
||||
|
||||
/* filter out invalid rays */
|
||||
vbool<K> valid = *valid_i == -1;
|
||||
#if defined(EMBREE_IGNORE_INVALID_RAYS)
|
||||
@@ -415,7 +414,7 @@ namespace embree
|
||||
const vfloat<K> ray_tnear = select(octant_valid,org_ray_tnear,vfloat<K>(pos_inf));
|
||||
vfloat<K> ray_tfar = select(octant_valid,org_ray_tfar ,vfloat<K>(neg_inf));
|
||||
|
||||
Frustum frustum(octant_valid,rdir,org,ray_tnear,ray_tfar);
|
||||
Frustum<N,Nx,K,robust> frustum(octant_valid,org,rdir,ray_tnear,ray_tfar);
|
||||
|
||||
StackItemT<NodeRef> stack[stackSizeSingle]; //!< stack of nodes
|
||||
StackItemT<NodeRef>* stackPtr = stack + 1; //!< current stack pointer
|
||||
@@ -442,8 +441,8 @@ namespace embree
|
||||
const NodeRef nodeRef = cur;
|
||||
const AlignedNode* __restrict__ const node = nodeRef.alignedNode();
|
||||
|
||||
__aligned(64) float fmin[16];
|
||||
size_t m_frusta_node = frustum.intersect(nodeRef,fmin);
|
||||
vfloat<Nx> fmin;
|
||||
size_t m_frusta_node = frustum.intersect(node,fmin);
|
||||
|
||||
if (unlikely(!m_frusta_node)) goto pop;
|
||||
cur = BVH::emptyNode;
|
||||
@@ -501,15 +500,12 @@ namespace embree
|
||||
std::swap(stackPtr[-3],stackPtr[-2]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*! check for empty leaf in case we accidentally hit one */
|
||||
assert(cur != BVH::emptyNode);
|
||||
if (cur == BVH::emptyNode)
|
||||
goto pop;
|
||||
|
||||
/* intersect leaf */
|
||||
assert(cur != BVH::invalidNode);
|
||||
assert(cur != BVH::emptyNode);
|
||||
const vbool<K> valid_leaf = ray_tfar > curDist;
|
||||
STAT3(normal.trav_leaves,1,popcnt(valid_leaf),K);
|
||||
if (unlikely(none(valid_leaf))) continue;
|
||||
@@ -517,17 +513,13 @@ namespace embree
|
||||
|
||||
size_t lazy_node = 0;
|
||||
PrimitiveIntersectorK::intersect(valid_leaf,pre,ray,context,prim,items,lazy_node);
|
||||
#if 1
|
||||
|
||||
/* reduce max distance interval on successful intersection */
|
||||
if (likely(any((ray.tfar < ray_tfar) & valid_leaf)))
|
||||
{
|
||||
ray_tfar = select(valid_leaf,ray.tfar,ray_tfar);
|
||||
//frusta_max_dist = reduce_max(ray_tfar);
|
||||
frustum.updateMaxDist(ray_tfar);
|
||||
}
|
||||
#else
|
||||
ray_tfar = select(valid_leaf,ray.tfar,ray_tfar);
|
||||
#endif
|
||||
|
||||
if (unlikely(lazy_node)) {
|
||||
stackPtr->ptr = lazy_node;
|
||||
@@ -588,12 +580,8 @@ namespace embree
|
||||
BVHNNodeTraverser1<N,Nx,types>::traverseAnyHit(cur,mask,tNear,stackPtr,stackEnd);
|
||||
}
|
||||
|
||||
/*! check for empty leaf in case we accidentally hit one */
|
||||
assert(cur != BVH::emptyNode);
|
||||
if (cur == BVH::emptyNode)
|
||||
goto pop;
|
||||
|
||||
/*! this is a leaf node */
|
||||
assert(cur != BVH::emptyNode);
|
||||
STAT3(shadow.trav_leaves,1,1,1);
|
||||
size_t num; Primitive* prim = (Primitive*) cur.leaf(num);
|
||||
|
||||
@@ -612,13 +600,15 @@ namespace embree
|
||||
}
|
||||
|
||||
template<int N, int K, int types, bool robust, typename PrimitiveIntersectorK, bool single>
|
||||
void BVHNIntersectorKHybrid<N,K,types,robust,PrimitiveIntersectorK,single>::occluded(vint<K>* __restrict__ valid_i, BVH* __restrict__ bvh, RayK<K>& __restrict__ ray, IntersectContext* context)
|
||||
void BVHNIntersectorKHybrid<N,K,types,robust,PrimitiveIntersectorK,single>::occluded(vint<K>* __restrict__ valid_i, Accel::Intersectors* __restrict__ This, RayK<K>& __restrict__ ray, IntersectContext* context)
|
||||
{
|
||||
BVH* __restrict__ bvh = (BVH*) This->ptr;
|
||||
|
||||
#if ENABLE_FAST_COHERENT_CODEPATHS == 1
|
||||
assert(context);
|
||||
if (unlikely(types == BVH_AN1 && context->user && isCoherent(context->user->flags)))
|
||||
{
|
||||
occluded_coherent(valid_i,bvh,ray,context);
|
||||
occluded_coherent(valid_i,This,ray,context);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@@ -778,12 +768,9 @@ namespace embree
|
||||
break;
|
||||
}
|
||||
|
||||
/*! check for empty leaf in case we accidentally hit one */
|
||||
assert(cur != BVH::emptyNode);
|
||||
if (cur == BVH::emptyNode)
|
||||
goto pop;
|
||||
|
||||
/* intersect leaf */
|
||||
assert(cur != BVH::emptyNode);
|
||||
const vbool<K> valid_leaf = ray_tfar > curDist;
|
||||
STAT3(shadow.trav_leaves,1,popcnt(valid_leaf),K);
|
||||
if (unlikely(none(valid_leaf))) continue;
|
||||
@@ -805,8 +792,11 @@ namespace embree
|
||||
|
||||
|
||||
template<int N, int K, int types, bool robust, typename PrimitiveIntersectorK, bool single>
|
||||
void BVHNIntersectorKHybrid<N,K,types,robust,PrimitiveIntersectorK,single>::occluded_coherent(vint<K>* __restrict__ valid_i, BVH* __restrict__ bvh, RayK<K>& __restrict__ ray, IntersectContext* context)
|
||||
void BVHNIntersectorKHybrid<N,K,types,robust,PrimitiveIntersectorK,single>::occluded_coherent(vint<K>* __restrict__ valid_i, Accel::Intersectors* __restrict__ This,
|
||||
RayK<K>& __restrict__ ray, IntersectContext* context)
|
||||
{
|
||||
BVH* __restrict__ bvh = (BVH*) This->ptr;
|
||||
|
||||
/* filter out invalid rays */
|
||||
vbool<K> valid = *valid_i == -1;
|
||||
#if defined(EMBREE_IGNORE_INVALID_RAYS)
|
||||
@@ -848,12 +838,12 @@ namespace embree
|
||||
const vfloat<K> ray_tnear = select(octant_valid,org_ray_tnear,vfloat<K>(pos_inf));
|
||||
const vfloat<K> ray_tfar = select(octant_valid,org_ray_tfar ,vfloat<K>(neg_inf));
|
||||
|
||||
const Frustum frustum(octant_valid,rdir,org,ray_tnear,ray_tfar);
|
||||
const Frustum<N,Nx,K,robust> frustum(octant_valid,org,rdir,ray_tnear,ray_tfar);
|
||||
|
||||
StackItemT<NodeRef> stack[stackSizeSingle]; //!< stack of nodes
|
||||
StackItemT<NodeRef>* stackPtr = stack + 1; //!< current stack pointer
|
||||
stack[0].ptr = bvh->root;
|
||||
stack[0].dist = movemask(octant_valid);
|
||||
stack[0].dist = (unsigned int)movemask(octant_valid);
|
||||
|
||||
while (1) pop:
|
||||
{
|
||||
@@ -875,8 +865,8 @@ namespace embree
|
||||
const NodeRef nodeRef = cur;
|
||||
const AlignedNode* __restrict__ const node = nodeRef.alignedNode();
|
||||
|
||||
__aligned(64) float fmin[16];
|
||||
size_t m_frusta_node = frustum.intersect(nodeRef,fmin);
|
||||
vfloat<Nx> fmin;
|
||||
size_t m_frusta_node = frustum.intersect(node,fmin);
|
||||
|
||||
if (unlikely(!m_frusta_node)) goto pop;
|
||||
cur = BVH::emptyNode;
|
||||
@@ -905,20 +895,16 @@ namespace embree
|
||||
stackPtr++;
|
||||
}
|
||||
cur = child;
|
||||
m_active = movemask(lhit);
|
||||
m_active = (unsigned int)movemask(lhit);
|
||||
}
|
||||
} while(m_frusta_node);
|
||||
|
||||
if (unlikely(cur == BVH::emptyNode)) goto pop;
|
||||
}
|
||||
|
||||
/*! check for empty leaf in case we accidentally hit one */
|
||||
assert(cur != BVH::emptyNode);
|
||||
if (cur == BVH::emptyNode)
|
||||
goto pop;
|
||||
|
||||
/* intersect leaf */
|
||||
assert(cur != BVH::invalidNode);
|
||||
assert(cur != BVH::emptyNode);
|
||||
#if defined(__AVX__)
|
||||
STAT3(normal.trav_leaves,1,__popcnt(m_active),K);
|
||||
#endif
|
||||
@@ -932,7 +918,7 @@ namespace embree
|
||||
|
||||
if (unlikely(lazy_node)) {
|
||||
stackPtr->ptr = lazy_node;
|
||||
stackPtr->dist = movemask(octant_valid);
|
||||
stackPtr->dist = (unsigned int)movemask(octant_valid);
|
||||
stackPtr++;
|
||||
}
|
||||
}
|
||||
@@ -942,5 +928,7 @@ namespace embree
|
||||
|
||||
AVX_ZERO_UPPER();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -214,7 +214,7 @@ namespace embree
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__AVX512F__)
|
||||
#if defined(__AVX512F__) && !defined(__AVX512VL__) // KNL
|
||||
|
||||
template<>
|
||||
__forceinline size_t intersectNode<4,16>(const typename BVH4::AlignedNode* node, const TravRay<4,16>& ray, const vfloat16& tnear, const vfloat16& tfar, vfloat16& dist)
|
||||
@@ -236,7 +236,6 @@ namespace embree
|
||||
template<>
|
||||
__forceinline size_t intersectNode<8,16>(const typename BVH8::AlignedNode* node, const TravRay<8,16>& ray, const vfloat16& tnear, const vfloat16& tfar, vfloat16& dist)
|
||||
{
|
||||
#if defined(__AVX512ER__)
|
||||
const vllong8 invalid((size_t)BVH8::emptyNode);
|
||||
const vboold8 m_valid(invalid != vllong8::loadu(node->children));
|
||||
const vfloat16 bminmaxX = permute(vfloat16::load((const float*)&node->lower_x), ray.permX);
|
||||
@@ -248,19 +247,7 @@ namespace embree
|
||||
const vfloat16 tNear = max(tNearFarX, tNearFarY, tNearFarZ, tnear);
|
||||
const vfloat16 tFar = min(tNearFarX, tNearFarY, tNearFarZ, tfar);
|
||||
const vbool16 vmask = le(vboolf16(m_valid),tNear,align_shift_right<8>(tFar, tFar));
|
||||
#else
|
||||
const vfloat16 tNearX = msub(vfloat16(*(vfloat8*)((const char*)&node->lower_x+ray.nearX)), ray.rdir.x, ray.org_rdir.x);
|
||||
const vfloat16 tNearY = msub(vfloat16(*(vfloat8*)((const char*)&node->lower_x+ray.nearY)), ray.rdir.y, ray.org_rdir.y);
|
||||
const vfloat16 tNearZ = msub(vfloat16(*(vfloat8*)((const char*)&node->lower_x+ray.nearZ)), ray.rdir.z, ray.org_rdir.z);
|
||||
const vfloat16 tFarX = msub(vfloat16(*(vfloat8*)((const char*)&node->lower_x+ray.farX )), ray.rdir.x, ray.org_rdir.x);
|
||||
const vfloat16 tFarY = msub(vfloat16(*(vfloat8*)((const char*)&node->lower_x+ray.farY )), ray.rdir.y, ray.org_rdir.y);
|
||||
const vfloat16 tFarZ = msub(vfloat16(*(vfloat8*)((const char*)&node->lower_x+ray.farZ )), ray.rdir.z, ray.org_rdir.z);
|
||||
|
||||
const vfloat16 tNear = max(tNearX,tNearY,tNearZ,tnear);
|
||||
const vfloat16 tFar = min(tFarX ,tFarY ,tFarZ ,tfar);
|
||||
const vbool16 vmask = le(vbool16(0xff),tNear,tFar);
|
||||
#endif
|
||||
const size_t mask = movemask(vmask);
|
||||
const size_t mask = movemask(vmask);
|
||||
dist = tNear;
|
||||
return mask;
|
||||
}
|
||||
@@ -338,7 +325,7 @@ namespace embree
|
||||
return mask;
|
||||
}
|
||||
|
||||
#if defined(__AVX512F__)
|
||||
#if defined(__AVX512F__) && !defined(__AVX512VL__) // KNL
|
||||
|
||||
template<>
|
||||
__forceinline size_t intersectNodeRobust<4,16>(const typename BVHN<4>::AlignedNode* node, const TravRay<4,16>& ray,
|
||||
@@ -849,7 +836,7 @@ namespace embree
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__AVX512F__)
|
||||
#if defined(__AVX512F__) && !defined(__AVX512VL__) // KNL
|
||||
|
||||
template<>
|
||||
__forceinline size_t intersectNode<4,16>(const typename BVH4::QuantizedNode* node, const TravRay<4,16>& ray, const vfloat16& tnear, const vfloat16& tfar, vfloat16& dist)
|
||||
@@ -884,7 +871,6 @@ namespace embree
|
||||
template<>
|
||||
__forceinline size_t intersectNode<8,16>(const typename BVH8::QuantizedNode* node, const TravRay<8,16>& ray, const vfloat16& tnear, const vfloat16& tfar, vfloat16& dist)
|
||||
{
|
||||
#if defined(__AVX512ER__)
|
||||
const vllong8 invalid((size_t)BVH8::emptyNode);
|
||||
const vboold8 m_valid(invalid != vllong8::loadu(node->children));
|
||||
const vfloat16 bminmaxX = node->dequantizeLowerUpperX<16>(ray.permX);
|
||||
@@ -896,31 +882,7 @@ namespace embree
|
||||
const vfloat16 tNear = max(tNearFarX, tNearFarY, tNearFarZ, tnear);
|
||||
const vfloat16 tFar = min(tNearFarX, tNearFarY, tNearFarZ, tfar);
|
||||
const vbool16 vmask = le(vboolf16(m_valid),tNear,align_shift_right<8>(tFar, tFar));
|
||||
#else
|
||||
const vfloat16 start_x(node->start.x);
|
||||
const vfloat16 scale_x(node->scale.x);
|
||||
const vfloat16 lower_x = madd(vfloat16(node->dequantize<8>(ray.nearX >> 2)),scale_x,start_x);
|
||||
const vfloat16 upper_x = madd(vfloat16(node->dequantize<8>(ray.farX >> 2)),scale_x,start_x);
|
||||
const vfloat16 start_y(node->start.y);
|
||||
const vfloat16 scale_y(node->scale.y);
|
||||
const vfloat16 lower_y = madd(vfloat16(node->dequantize<8>(ray.nearY >> 2)),scale_y,start_y);
|
||||
const vfloat16 upper_y = madd(vfloat16(node->dequantize<8>(ray.farY >> 2)),scale_y,start_y);
|
||||
const vfloat16 start_z(node->start.z);
|
||||
const vfloat16 scale_z(node->scale.z);
|
||||
const vfloat16 lower_z = madd(vfloat16(node->dequantize<8>(ray.nearZ >> 2)),scale_z,start_z);
|
||||
const vfloat16 upper_z = madd(vfloat16(node->dequantize<8>(ray.farZ >> 2)),scale_z,start_z);
|
||||
const vfloat16 tNearX = msub(lower_x, ray.rdir.x, ray.org_rdir.x);
|
||||
const vfloat16 tNearY = msub(lower_y, ray.rdir.y, ray.org_rdir.y);
|
||||
const vfloat16 tNearZ = msub(lower_z, ray.rdir.z, ray.org_rdir.z);
|
||||
const vfloat16 tFarX = msub(upper_x, ray.rdir.x, ray.org_rdir.x);
|
||||
const vfloat16 tFarY = msub(upper_y, ray.rdir.y, ray.org_rdir.y);
|
||||
const vfloat16 tFarZ = msub(upper_z, ray.rdir.z, ray.org_rdir.z);
|
||||
|
||||
const vfloat16 tNear = max(tNearX,tNearY,tNearZ,tnear);
|
||||
const vfloat16 tFar = min(tFarX ,tFarY ,tFarZ ,tfar);
|
||||
const vbool16 vmask = le(vbool16(0xff),tNear,tFar);
|
||||
#endif
|
||||
const size_t mask = movemask(vmask);
|
||||
const size_t mask = movemask(vmask);
|
||||
dist = tNear;
|
||||
return mask;
|
||||
}
|
||||
|
||||
@@ -34,36 +34,24 @@
|
||||
#include "../common/scene.h"
|
||||
#include <bitset>
|
||||
|
||||
// TODO: bvh->scene->intersect/occluded correct vs. global scene->intersect/occluded
|
||||
|
||||
#define MAX_RAYS 64
|
||||
|
||||
namespace embree
|
||||
{
|
||||
namespace isa
|
||||
{
|
||||
/* enable traversal of either two small streams or one large stream */
|
||||
#if !defined(__AVX512F__)
|
||||
static const size_t MAX_RAYS_PER_OCTANT = 8*sizeof(unsigned int);
|
||||
#else
|
||||
static const size_t MAX_RAYS_PER_OCTANT = 8*sizeof(size_t);
|
||||
#endif
|
||||
static_assert(MAX_RAYS_PER_OCTANT <= MAX_INTERNAL_STREAM_SIZE, "maximal internal stream size exceeded");
|
||||
|
||||
// =====================================================================================================
|
||||
// =====================================================================================================
|
||||
// =====================================================================================================
|
||||
|
||||
template<int N, int Nx, int K, int types, bool robust, typename PrimitiveIntersector>
|
||||
__forceinline void BVHNIntersectorStream<N, Nx, K, types, robust, PrimitiveIntersector>::intersectCoherent(BVH* __restrict__ bvh, RayK<K>** inputRays, size_t numOctantRays, IntersectContext* context)
|
||||
__forceinline void BVHNIntersectorStream<N, Nx, K, types, robust, PrimitiveIntersector>::intersect(Accel::Intersectors* __restrict__ This,
|
||||
RayK<K>** inputPackets, size_t numOctantRays, IntersectContext* context)
|
||||
{
|
||||
BVH* __restrict__ bvh = (BVH*) This->ptr;
|
||||
__aligned(64) StackItemMaskCoherent stack[stackSizeSingle]; //!< stack of nodes
|
||||
assert(numOctantRays <= MAX_INTERNAL_STREAM_SIZE);
|
||||
|
||||
RayK<K>** __restrict__ inputPackets = (RayK<K>**)inputRays;
|
||||
assert(numOctantRays <= MAX_RAYS);
|
||||
|
||||
__aligned(64) Packet packet[MAX_RAYS/K];
|
||||
__aligned(64) Frusta frusta;
|
||||
__aligned(64) Packet<K,robust> packet[MAX_INTERNAL_STREAM_SIZE/K];
|
||||
__aligned(64) Frustum<N,Nx,K,robust> frusta;
|
||||
|
||||
bool commonOctant = true;
|
||||
const size_t m_active = initPacketsAndFrusta<false>(inputPackets, numOctantRays, packet, frusta, commonOctant);
|
||||
@@ -74,7 +62,7 @@ namespace embree
|
||||
{
|
||||
const size_t numPackets = (numOctantRays+K-1)/K;
|
||||
for (size_t i = 0; i < numPackets; i++)
|
||||
bvh->scene->intersect(inputPackets[i]->tnear <= inputPackets[i]->tfar,*inputPackets[i],context);
|
||||
This->intersect(inputPackets[i]->tnear <= inputPackets[i]->tfar,*inputPackets[i],context);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -86,8 +74,6 @@ namespace embree
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const NearFarPreCompute pc(frusta.min_rdir);
|
||||
|
||||
StackItemMaskCoherent* stackPtr = stack + 1;
|
||||
|
||||
while (1) pop:
|
||||
@@ -111,7 +97,7 @@ namespace embree
|
||||
__aligned(64) size_t maskK[N];
|
||||
for (size_t i = 0; i < N; i++) maskK[i] = m_trav_active;
|
||||
vfloat<Nx> dist;
|
||||
const size_t m_node_hit = traverseCoherentStream(m_trav_active, packet, node, pc, frusta, maskK, dist);
|
||||
const size_t m_node_hit = traverseCoherentStream(m_trav_active, packet, node, frusta, maskK, dist);
|
||||
if (unlikely(m_node_hit == 0)) goto pop;
|
||||
|
||||
BVHNNodeTraverserStreamHitCoherent<N, Nx, types>::traverseClosestHit(cur, m_trav_active, vbool<Nx>((int)m_node_hit), dist, (size_t*)maskK, stackPtr);
|
||||
@@ -130,25 +116,12 @@ namespace embree
|
||||
break;
|
||||
}
|
||||
assert(b < N);
|
||||
char *ptr = (char*)&node->lower_x + b*sizeof(float);
|
||||
assert(cur == node->child(b));
|
||||
|
||||
const vfloat<K> minX = vfloat<K>(*(const float*)((const char*)ptr + pc.nearX));
|
||||
const vfloat<K> minY = vfloat<K>(*(const float*)((const char*)ptr + pc.nearY));
|
||||
const vfloat<K> minZ = vfloat<K>(*(const float*)((const char*)ptr + pc.nearZ));
|
||||
const vfloat<K> maxX = vfloat<K>(*(const float*)((const char*)ptr + pc.farX));
|
||||
const vfloat<K> maxY = vfloat<K>(*(const float*)((const char*)ptr + pc.farY));
|
||||
const vfloat<K> maxZ = vfloat<K>(*(const float*)((const char*)ptr + pc.farZ));
|
||||
|
||||
m_trav_active = intersectAlignedNodePacket(packet, minX, minY, minZ, maxX, maxY, maxZ, m_trav_active);
|
||||
m_trav_active = intersectAlignedNodePacket(packet, node, b, frusta.nf, m_trav_active);
|
||||
}
|
||||
|
||||
/*! check for empty leaf in case we accidentally hit one */
|
||||
assert(cur != BVH::emptyNode);
|
||||
if (cur == BVH::emptyNode)
|
||||
goto pop;
|
||||
|
||||
/*! this is a leaf node */
|
||||
assert(cur != BVH::emptyNode);
|
||||
STAT3(normal.trav_leaves, 1, 1, 1);
|
||||
size_t num; Primitive* prim = (Primitive*)cur.leaf(num);
|
||||
|
||||
@@ -166,7 +139,7 @@ namespace embree
|
||||
assert(m_isec & bits);
|
||||
bits &= ~m_isec;
|
||||
|
||||
Packet &p = packet[i];
|
||||
Packet<K,robust> &p = packet[i];
|
||||
vbool<K> m_valid = p.min_dist <= p.max_dist;
|
||||
PrimitiveIntersector::intersectK(m_valid, *inputPackets[i], context, prim, num, lazy_node);
|
||||
p.max_dist = min(p.max_dist, inputPackets[i]->tfar);
|
||||
@@ -176,16 +149,16 @@ namespace embree
|
||||
}
|
||||
|
||||
template<int N, int Nx, int K, int types, bool robust, typename PrimitiveIntersector>
|
||||
__forceinline void BVHNIntersectorStream<N, Nx, K, types, robust, PrimitiveIntersector>::occludedCoherent(BVH* __restrict__ bvh, RayK<K>** inputRays, size_t numOctantRays, IntersectContext* context)
|
||||
__forceinline void BVHNIntersectorStream<N, Nx, K, types, robust, PrimitiveIntersector>::occluded(Accel::Intersectors* __restrict__ This,
|
||||
RayK<K>** inputPackets, size_t numOctantRays, IntersectContext* context)
|
||||
{
|
||||
BVH* __restrict__ bvh = (BVH*) This->ptr;
|
||||
__aligned(64) StackItemMaskCoherent stack[stackSizeSingle]; //!< stack of nodes
|
||||
|
||||
RayK<K>** __restrict__ inputPackets = (RayK<K>**)inputRays;
|
||||
assert(numOctantRays <= MAX_RAYS);
|
||||
assert(numOctantRays <= MAX_INTERNAL_STREAM_SIZE);
|
||||
|
||||
/* inactive rays should have been filtered out before */
|
||||
__aligned(64) Packet packet[MAX_RAYS/K];
|
||||
__aligned(64) Frusta frusta;
|
||||
__aligned(64) Packet<K,robust> packet[MAX_INTERNAL_STREAM_SIZE/K];
|
||||
__aligned(64) Frustum<N,Nx,K,robust> frusta;
|
||||
|
||||
bool commonOctant = true;
|
||||
size_t m_active = initPacketsAndFrusta<true>(inputPackets, numOctantRays, packet, frusta, commonOctant);
|
||||
@@ -198,7 +171,7 @@ namespace embree
|
||||
{
|
||||
const size_t numPackets = (numOctantRays+K-1)/K;
|
||||
for (size_t i = 0; i < numPackets; i++)
|
||||
bvh->scene->occluded(inputPackets[i]->tnear <= inputPackets[i]->tfar,*inputPackets[i],context);
|
||||
This->occluded(inputPackets[i]->tnear <= inputPackets[i]->tfar,*inputPackets[i],context);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -210,8 +183,6 @@ namespace embree
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const NearFarPreCompute pc(frusta.min_rdir);
|
||||
|
||||
StackItemMaskCoherent* stackPtr = stack + 1;
|
||||
|
||||
while (1) pop:
|
||||
@@ -237,7 +208,7 @@ namespace embree
|
||||
for (size_t i = 0; i < N; i++) maskK[i] = m_trav_active;
|
||||
|
||||
vfloat<Nx> dist;
|
||||
const size_t m_node_hit = traverseCoherentStream(m_trav_active, packet, node, pc, frusta, maskK, dist);
|
||||
const size_t m_node_hit = traverseCoherentStream(m_trav_active, packet, node, frusta, maskK, dist);
|
||||
if (unlikely(m_node_hit == 0)) goto pop;
|
||||
|
||||
BVHNNodeTraverserStreamHitCoherent<N, Nx, types>::traverseAnyHit(cur, m_trav_active, vbool<Nx>((int)m_node_hit), (size_t*)maskK, stackPtr);
|
||||
@@ -252,25 +223,12 @@ namespace embree
|
||||
for (size_t i=0;i<N;i++)
|
||||
if (node->child(i) == cur) { b = i; break; }
|
||||
assert(b < N);
|
||||
char *ptr = (char*)&node->lower_x + b*sizeof(float);
|
||||
assert(cur == node->child(b));
|
||||
|
||||
const vfloat<K> minX = vfloat<K>(*(const float*)((const char*)ptr + pc.nearX));
|
||||
const vfloat<K> minY = vfloat<K>(*(const float*)((const char*)ptr + pc.nearY));
|
||||
const vfloat<K> minZ = vfloat<K>(*(const float*)((const char*)ptr + pc.nearZ));
|
||||
const vfloat<K> maxX = vfloat<K>(*(const float*)((const char*)ptr + pc.farX));
|
||||
const vfloat<K> maxY = vfloat<K>(*(const float*)((const char*)ptr + pc.farY));
|
||||
const vfloat<K> maxZ = vfloat<K>(*(const float*)((const char*)ptr + pc.farZ));
|
||||
|
||||
m_trav_active = intersectAlignedNodePacket(packet, minX, minY, minZ, maxX, maxY, maxZ, m_trav_active);
|
||||
m_trav_active = intersectAlignedNodePacket(packet, node, b, frusta.nf, m_trav_active);
|
||||
}
|
||||
|
||||
/*! check for empty leaf in case we accidentally hit one */
|
||||
assert(cur != BVH::emptyNode);
|
||||
if (cur == BVH::emptyNode)
|
||||
goto pop;
|
||||
|
||||
/*! this is a leaf node */
|
||||
assert(cur != BVH::emptyNode);
|
||||
STAT3(normal.trav_leaves, 1, 1, 1);
|
||||
size_t num; Primitive* prim = (Primitive*)cur.leaf(num);
|
||||
|
||||
@@ -286,7 +244,7 @@ namespace embree
|
||||
const size_t m_isec = ((((size_t)1 << K)-1) << (i*K));
|
||||
assert(m_isec & bits);
|
||||
bits &= ~m_isec;
|
||||
Packet &p = packet[i];
|
||||
Packet<K,robust> &p = packet[i];
|
||||
vbool<K> m_valid = p.min_dist <= p.max_dist;
|
||||
vbool<K> m_hit = PrimitiveIntersector::occludedK(m_valid, *inputPackets[i], context, prim, num, lazy_node);
|
||||
inputPackets[i]->geomID = select(m_hit & m_valid, vint<K>(zero), inputPackets[i]->geomID);
|
||||
@@ -296,54 +254,6 @@ namespace embree
|
||||
} // traversal + intersection
|
||||
}
|
||||
|
||||
// =====================================================================================================
|
||||
// =====================================================================================================
|
||||
// =====================================================================================================
|
||||
|
||||
template<int N, int Nx, int K, int types, bool robust, typename PrimitiveIntersector>
|
||||
void BVHNIntersectorStream<N, Nx, K, types, robust, PrimitiveIntersector>::intersect(BVH* __restrict__ bvh, RayK<K>** inputRays, size_t numTotalRays, IntersectContext* context)
|
||||
{
|
||||
#if ENABLE_COHERENT_STREAM_PATH == 1
|
||||
if (unlikely(PrimitiveIntersector::validIntersectorK && !robust && isCoherent(context->user->flags)))
|
||||
{
|
||||
intersectCoherent(bvh, inputRays, numTotalRays, context);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* fallback to packets */
|
||||
for (size_t i = 0; i < numTotalRays; i += K)
|
||||
{
|
||||
const vint<K> vi = vint<K>(int(i)) + vint<K>(step);
|
||||
vbool<K> valid = vi < vint<K>(int(numTotalRays));
|
||||
RayK<K>& ray = *(inputRays[i / K]);
|
||||
valid &= ray.tnear <= ray.tfar;
|
||||
bvh->scene->intersect(valid, ray, context);
|
||||
}
|
||||
}
|
||||
|
||||
template<int N, int Nx, int K, int types, bool robust, typename PrimitiveIntersector>
|
||||
void BVHNIntersectorStream<N, Nx, K, types, robust, PrimitiveIntersector>::occluded(BVH* __restrict__ bvh, RayK<K>** inputRays, size_t numTotalRays, IntersectContext* context)
|
||||
{
|
||||
#if ENABLE_COHERENT_STREAM_PATH == 1
|
||||
if (unlikely(PrimitiveIntersector::validIntersectorK && !robust && isCoherent(context->user->flags)))
|
||||
{
|
||||
occludedCoherent(bvh, inputRays, numTotalRays, context);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* fallback to packets */
|
||||
for (size_t i = 0; i < numTotalRays; i += K)
|
||||
{
|
||||
const vint<K> vi = vint<K>(int(i)) + vint<K>(step);
|
||||
vbool<K> valid = vi < vint<K>(int(numTotalRays));
|
||||
RayK<K>& ray = *(inputRays[i / K]);
|
||||
valid &= ray.tnear <= ray.tfar;
|
||||
bvh->scene->occluded(valid, ray, context);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// ArrayIntersectorKStream Definitions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -359,5 +269,39 @@ namespace embree
|
||||
typedef ArrayIntersectorKStream<VSIZEX,QuadMvIntersectorKPluecker<4 COMMA VSIZEX COMMA true > > Quad4vIntersectorStreamPluecker;
|
||||
typedef ArrayIntersectorKStream<VSIZEX,QuadMiIntersectorKPluecker<4 COMMA VSIZEX COMMA true > > Quad4iIntersectorStreamPluecker;
|
||||
typedef ArrayIntersectorKStream<VSIZEX,ObjectIntersectorK<VSIZEX COMMA false > > ObjectIntersectorStream;
|
||||
|
||||
|
||||
// =====================================================================================================
|
||||
// =====================================================================================================
|
||||
// =====================================================================================================
|
||||
|
||||
template<int N, int Nx, int K>
|
||||
void BVHNIntersectorStreamPacketFallback<N, Nx, K>::intersect(Accel::Intersectors* __restrict__ This, RayK<K>** inputRays, size_t numTotalRays, IntersectContext* context)
|
||||
{
|
||||
/* fallback to packets */
|
||||
for (size_t i = 0; i < numTotalRays; i += K)
|
||||
{
|
||||
const vint<K> vi = vint<K>(int(i)) + vint<K>(step);
|
||||
vbool<K> valid = vi < vint<K>(int(numTotalRays));
|
||||
RayK<K>& ray = *(inputRays[i / K]);
|
||||
valid &= ray.tnear <= ray.tfar;
|
||||
This->intersect(valid, ray, context);
|
||||
}
|
||||
}
|
||||
|
||||
template<int N, int Nx, int K>
|
||||
void BVHNIntersectorStreamPacketFallback<N, Nx, K>::occluded(Accel::Intersectors* __restrict__ This, RayK<K>** inputRays, size_t numTotalRays, IntersectContext* context)
|
||||
{
|
||||
/* fallback to packets */
|
||||
for (size_t i = 0; i < numTotalRays; i += K)
|
||||
{
|
||||
const vint<K> vi = vint<K>(int(i)) + vint<K>(step);
|
||||
vbool<K> valid = vi < vint<K>(int(numTotalRays));
|
||||
RayK<K>& ray = *(inputRays[i / K]);
|
||||
valid &= ray.tnear <= ray.tfar;
|
||||
This->occluded(valid, ray, context);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -21,193 +21,142 @@ namespace embree
|
||||
{
|
||||
namespace isa
|
||||
{
|
||||
static const size_t MAX_RAYS_PER_OCTANT = 8*sizeof(size_t);
|
||||
|
||||
static_assert(MAX_RAYS_PER_OCTANT <= MAX_INTERNAL_STREAM_SIZE, "maximal internal stream size exceeded");
|
||||
MAYBE_UNUSED static const size_t MAX_PACKET_STREAM_SIZE = MAX_INTERNAL_STREAM_SIZE / VSIZEX;
|
||||
|
||||
__forceinline void RayStreamFilter::filterAOS(Scene* scene, RTCRay* _rayN, size_t N, size_t stride, IntersectContext* context, bool intersect)
|
||||
{
|
||||
#if 1
|
||||
RayStreamAOS rayN(_rayN);
|
||||
for (size_t i = 0; i < N; i += VSIZEX)
|
||||
|
||||
/* use fast path for coherent ray mode */
|
||||
if (unlikely(isCoherent(context->user->flags)))
|
||||
{
|
||||
const vintx vi = vintx(int(i)) + vintx(step);
|
||||
vboolx valid = vi < vintx(int(N));
|
||||
const vintx offset = vi * int(stride);
|
||||
__aligned(64) RayK<VSIZEX> rays[MAX_PACKET_STREAM_SIZE];
|
||||
__aligned(64) RayK<VSIZEX>* rayPtrs[MAX_PACKET_STREAM_SIZE];
|
||||
|
||||
RayK<VSIZEX> ray = rayN.getRayByOffset<VSIZEX>(valid, offset);
|
||||
valid &= ray.tnear <= ray.tfar;
|
||||
|
||||
if (intersect)
|
||||
scene->intersect(valid, ray, context);
|
||||
else
|
||||
scene->occluded(valid, ray, context);
|
||||
|
||||
rayN.setHitByOffset<VSIZEX>(valid, offset, ray, intersect);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
Ray* __restrict__ rayN = (Ray*)_rayN;
|
||||
__aligned(64) Ray* octants[8][MAX_RAYS_PER_OCTANT];
|
||||
unsigned int rays_in_octant[8];
|
||||
|
||||
for (size_t i=0;i<8;i++) rays_in_octant[i] = 0;
|
||||
size_t inputRayID = 0;
|
||||
|
||||
while(1)
|
||||
{
|
||||
int cur_octant = -1;
|
||||
/* sort rays into octants */
|
||||
for (;inputRayID<N;)
|
||||
for (size_t i = 0; i < N; i += MAX_INTERNAL_STREAM_SIZE)
|
||||
{
|
||||
Ray &ray = *(Ray*)((char*)rayN + inputRayID * stride);
|
||||
/* filter out invalid rays */
|
||||
if (unlikely(ray.tnear > ray.tfar)) { inputRayID++; continue; }
|
||||
if (unlikely(!intersect && ray.geomID == 0)) { inputRayID++; continue; } // ignore already occluded rays
|
||||
const size_t size = min(N - i, MAX_INTERNAL_STREAM_SIZE);
|
||||
|
||||
#if defined(EMBREE_IGNORE_INVALID_RAYS)
|
||||
if (unlikely(!ray.valid())) { inputRayID++; continue; }
|
||||
#endif
|
||||
|
||||
const unsigned int octantID = movemask(vfloat4(ray.dir) < 0.0f) & 0x7;
|
||||
|
||||
assert(octantID < 8);
|
||||
octants[octantID][rays_in_octant[octantID]++] = &ray;
|
||||
inputRayID++;
|
||||
if (unlikely(rays_in_octant[octantID] == MAX_RAYS_PER_OCTANT))
|
||||
/* convert from AOS to SOA */
|
||||
for (size_t j = 0; j < size; j += VSIZEX)
|
||||
{
|
||||
cur_octant = octantID;
|
||||
break;
|
||||
const vintx vij = vintx(int(i+j)) + vintx(step);
|
||||
const vboolx valid = vij < vintx(int(N));
|
||||
const vintx offset = vij * int(stride);
|
||||
const size_t packetIndex = j / VSIZEX;
|
||||
|
||||
RayK<VSIZEX> ray = rayN.getRayByOffset(valid, offset);
|
||||
ray.tnear = select(valid, ray.tnear, zero);
|
||||
ray.tfar = select(valid, ray.tfar, neg_inf);
|
||||
|
||||
rays[packetIndex] = ray;
|
||||
rayPtrs[packetIndex] = &rays[packetIndex]; // rayPtrs might get reordered for occludedN
|
||||
}
|
||||
|
||||
/* trace stream */
|
||||
if (intersect)
|
||||
scene->intersectors.intersectN(rayPtrs, size, context);
|
||||
else
|
||||
scene->intersectors.occludedN(rayPtrs, size, context);
|
||||
|
||||
/* convert from SOA to AOS */
|
||||
for (size_t j = 0; j < size; j += VSIZEX)
|
||||
{
|
||||
const vintx vij = vintx(int(i+j)) + vintx(step);
|
||||
const vboolx valid = vij < vintx(int(N));
|
||||
const vintx offset = vij * int(stride);
|
||||
const size_t packetIndex = j / VSIZEX;
|
||||
rayN.setHitByOffset(valid, offset, rays[packetIndex], intersect);
|
||||
}
|
||||
}
|
||||
/* need to flush rays in octant ? */
|
||||
if (unlikely(cur_octant == -1))
|
||||
for (int i=0;i<8;i++)
|
||||
if (rays_in_octant[i])
|
||||
{
|
||||
cur_octant = i;
|
||||
break;
|
||||
}
|
||||
|
||||
/* all rays traced ? */
|
||||
if (unlikely(cur_octant == -1))
|
||||
break;
|
||||
|
||||
|
||||
Ray** rays = &octants[cur_octant][0];
|
||||
const size_t numOctantRays = rays_in_octant[cur_octant];
|
||||
|
||||
/* special codepath for very small number of rays per octant */
|
||||
if (numOctantRays == 1)
|
||||
{
|
||||
if (intersect) scene->intersect((RTCRay&)*rays[0],context);
|
||||
else scene->occluded ((RTCRay&)*rays[0],context);
|
||||
}
|
||||
/* codepath for large number of rays per octant */
|
||||
else
|
||||
{
|
||||
/* incoherent ray stream code path */
|
||||
if (intersect) scene->intersectN((RTCRay**)rays,numOctantRays,context);
|
||||
else scene->occludedN ((RTCRay**)rays,numOctantRays,context);
|
||||
}
|
||||
rays_in_octant[cur_octant] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* fallback to packets */
|
||||
for (size_t i=0; i<N; i+=VSIZEX)
|
||||
{
|
||||
const vintx vi = vintx(int(i)) + vintx(step);
|
||||
vboolx valid = vi < vintx(int(N));
|
||||
const vintx offset = vi * int(stride);
|
||||
|
||||
#endif
|
||||
RayK<VSIZEX> ray = rayN.getRayByOffset(valid, offset);
|
||||
valid &= ray.tnear <= ray.tfar;
|
||||
|
||||
if (intersect)
|
||||
scene->intersectors.intersect(valid, ray, context);
|
||||
else
|
||||
scene->intersectors.occluded(valid, ray, context);
|
||||
|
||||
rayN.setHitByOffset(valid, offset, ray, intersect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
__forceinline void RayStreamFilter::filterAOP(Scene* scene, RTCRay** _rayN, size_t N, IntersectContext* context, bool intersect)
|
||||
{
|
||||
#if 1
|
||||
|
||||
/* fallback to packets */
|
||||
RayStreamAOP rayN(_rayN);
|
||||
for (size_t i = 0; i < N; i += VSIZEX)
|
||||
|
||||
/* use fast path for coherent ray mode */
|
||||
if (unlikely(isCoherent(context->user->flags)))
|
||||
{
|
||||
const vintx vi = vintx(int(i)) + vintx(step);
|
||||
vboolx valid = vi < vintx(int(N));
|
||||
__aligned(64) RayK<VSIZEX> rays[MAX_PACKET_STREAM_SIZE];
|
||||
__aligned(64) RayK<VSIZEX>* rayPtrs[MAX_PACKET_STREAM_SIZE];
|
||||
|
||||
RayK<VSIZEX> ray = rayN.getRayByIndex<VSIZEX>(valid, i);
|
||||
valid &= ray.tnear <= ray.tfar;
|
||||
|
||||
if (intersect)
|
||||
scene->intersect(valid, ray, context);
|
||||
else
|
||||
scene->occluded(valid, ray, context);
|
||||
|
||||
rayN.setHitByIndex<VSIZEX>(valid, i, ray, intersect);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
Ray** __restrict__ rayN = (Ray**)_rayN;
|
||||
__aligned(64) Ray* octants[8][MAX_RAYS_PER_OCTANT];
|
||||
unsigned int rays_in_octant[8];
|
||||
|
||||
for (size_t i=0;i<8;i++) rays_in_octant[i] = 0;
|
||||
size_t inputRayID = 0;
|
||||
|
||||
while(1)
|
||||
{
|
||||
int cur_octant = -1;
|
||||
/* sort rays into octants */
|
||||
for (;inputRayID<N;)
|
||||
for (size_t i = 0; i < N; i += MAX_INTERNAL_STREAM_SIZE)
|
||||
{
|
||||
Ray &ray = *rayN[inputRayID];
|
||||
/* filter out invalid rays */
|
||||
if (unlikely(ray.tnear > ray.tfar)) { inputRayID++; continue; }
|
||||
if (unlikely(!intersect && ray.geomID == 0)) { inputRayID++; continue; } // ignore already occluded rays
|
||||
const size_t size = min(N - i, MAX_INTERNAL_STREAM_SIZE);
|
||||
|
||||
#if defined(EMBREE_IGNORE_INVALID_RAYS)
|
||||
if (unlikely(!ray.valid())) { inputRayID++; continue; }
|
||||
#endif
|
||||
|
||||
const unsigned int octantID = movemask(vfloat4(ray.dir) < 0.0f) & 0x7;
|
||||
|
||||
assert(octantID < 8);
|
||||
octants[octantID][rays_in_octant[octantID]++] = &ray;
|
||||
inputRayID++;
|
||||
if (unlikely(rays_in_octant[octantID] == MAX_RAYS_PER_OCTANT))
|
||||
/* convert from AOP to SOA */
|
||||
for (size_t j = 0; j < size; j += VSIZEX)
|
||||
{
|
||||
cur_octant = octantID;
|
||||
break;
|
||||
const vintx vij = vintx(int(i+j)) + vintx(step);
|
||||
const vboolx valid = vij < vintx(int(N));
|
||||
const size_t packetIndex = j / VSIZEX;
|
||||
|
||||
RayK<VSIZEX> ray = rayN.getRayByIndex(valid, i+j);
|
||||
ray.tnear = select(valid, ray.tnear, zero);
|
||||
ray.tfar = select(valid, ray.tfar, neg_inf);
|
||||
|
||||
rays[packetIndex] = ray;
|
||||
rayPtrs[packetIndex] = &rays[packetIndex]; // rayPtrs might get reordered for occludedN
|
||||
}
|
||||
|
||||
/* trace stream */
|
||||
if (intersect)
|
||||
scene->intersectors.intersectN(rayPtrs, size, context);
|
||||
else
|
||||
scene->intersectors.occludedN(rayPtrs, size, context);
|
||||
|
||||
/* convert from SOA to AOP */
|
||||
for (size_t j = 0; j < size; j += VSIZEX)
|
||||
{
|
||||
const vintx vij = vintx(int(i+j)) + vintx(step);
|
||||
const vboolx valid = vij < vintx(int(N));
|
||||
const size_t packetIndex = j / VSIZEX;
|
||||
|
||||
rayN.setHitByIndex(valid, i+j, rays[packetIndex], intersect);
|
||||
}
|
||||
}
|
||||
/* need to flush rays in octant ? */
|
||||
if (unlikely(cur_octant == -1))
|
||||
for (int i=0;i<8;i++)
|
||||
if (rays_in_octant[i])
|
||||
{
|
||||
cur_octant = i;
|
||||
break;
|
||||
}
|
||||
|
||||
/* all rays traced ? */
|
||||
if (unlikely(cur_octant == -1))
|
||||
break;
|
||||
|
||||
|
||||
Ray** rays = &octants[cur_octant][0];
|
||||
const size_t numOctantRays = rays_in_octant[cur_octant];
|
||||
|
||||
/* special codepath for very small number of rays per octant */
|
||||
if (numOctantRays == 1)
|
||||
{
|
||||
if (intersect) scene->intersect((RTCRay&)*rays[0],context);
|
||||
else scene->occluded ((RTCRay&)*rays[0],context);
|
||||
}
|
||||
/* codepath for large number of rays per octant */
|
||||
else
|
||||
{
|
||||
/* incoherent ray stream code path */
|
||||
if (intersect) scene->intersectN((RTCRay**)rays,numOctantRays,context);
|
||||
else scene->occludedN ((RTCRay**)rays,numOctantRays,context);
|
||||
}
|
||||
rays_in_octant[cur_octant] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* fallback to packets */
|
||||
for (size_t i = 0; i < N; i += VSIZEX)
|
||||
{
|
||||
const vintx vi = vintx(int(i)) + vintx(step);
|
||||
vboolx valid = vi < vintx(int(N));
|
||||
|
||||
#endif
|
||||
RayK<VSIZEX> ray = rayN.getRayByIndex(valid, i);
|
||||
valid &= ray.tnear <= ray.tfar;
|
||||
|
||||
if (intersect)
|
||||
scene->intersectors.intersect(valid, ray, context);
|
||||
else
|
||||
scene->intersectors.occluded(valid, ray, context);
|
||||
|
||||
rayN.setHitByIndex(valid, i, ray, intersect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
__forceinline void RayStreamFilter::filterSOA(Scene* scene, char* rayData, size_t N, size_t numPackets, size_t stride, IntersectContext* context, bool intersect)
|
||||
@@ -220,45 +169,40 @@ namespace embree
|
||||
!rayDataAlignment &&
|
||||
!offsetAlignment))
|
||||
{
|
||||
#if defined(__AVX__) && ENABLE_COHERENT_STREAM_PATH == 1
|
||||
/* all valid accels need to have a intersectN/occludedN */
|
||||
if (unlikely(isCoherent(context->user->flags) && !scene->isRobust() && scene->accels.validIsecN()))
|
||||
if (unlikely(isCoherent(context->user->flags)))
|
||||
{
|
||||
static const size_t MAX_COHERENT_RAY_PACKETS = MAX_RAYS_PER_OCTANT / VSIZEX;
|
||||
__aligned(64) RayK<VSIZEX>* rays_ptr[MAX_RAYS_PER_OCTANT / VSIZEX];
|
||||
|
||||
size_t numPacketsInOctant = 0;
|
||||
__aligned(64) RayK<VSIZEX>* rayPtrs[MAX_INTERNAL_STREAM_SIZE / VSIZEX];
|
||||
|
||||
size_t packetIndex = 0;
|
||||
for (size_t i = 0; i < numPackets; i++)
|
||||
{
|
||||
const size_t offset = i * stride;
|
||||
RayK<VSIZEX>& ray = *(RayK<VSIZEX>*)(rayData + offset);
|
||||
rays_ptr[numPacketsInOctant++] = &ray;
|
||||
rayPtrs[packetIndex++] = &ray;
|
||||
|
||||
/* trace as stream */
|
||||
if (unlikely(numPacketsInOctant == MAX_COHERENT_RAY_PACKETS))
|
||||
if (unlikely(packetIndex == MAX_PACKET_STREAM_SIZE))
|
||||
{
|
||||
const size_t size = numPacketsInOctant*VSIZEX;
|
||||
const size_t size = packetIndex*VSIZEX;
|
||||
if (intersect)
|
||||
scene->intersectN((void**)rays_ptr, size, context);
|
||||
scene->intersectors.intersectN(rayPtrs, size, context);
|
||||
else
|
||||
scene->occludedN((void**)rays_ptr, size, context);
|
||||
numPacketsInOctant = 0;
|
||||
scene->intersectors.occludedN(rayPtrs, size, context);
|
||||
packetIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* flush remaining packets */
|
||||
if (unlikely(numPacketsInOctant))
|
||||
if (unlikely(packetIndex > 0))
|
||||
{
|
||||
const size_t size = numPacketsInOctant*VSIZEX;
|
||||
const size_t size = packetIndex*VSIZEX;
|
||||
if (intersect)
|
||||
scene->intersectN((void**)rays_ptr, size, context);
|
||||
scene->intersectors.intersectN(rayPtrs, size, context);
|
||||
else
|
||||
scene->occludedN((void**)rays_ptr, size, context);
|
||||
scene->intersectors.occludedN(rayPtrs, size, context);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* fallback to packets */
|
||||
for (size_t i = 0; i < numPackets; i++)
|
||||
@@ -268,37 +212,34 @@ namespace embree
|
||||
const vboolx valid = ray.tnear <= ray.tfar;
|
||||
|
||||
if (intersect)
|
||||
scene->intersect(valid, ray, context);
|
||||
scene->intersectors.intersect(valid, ray, context);
|
||||
else
|
||||
scene->occluded(valid, ray, context);
|
||||
scene->intersectors.occluded(valid, ray, context);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* this is a very slow fallback path but it's extremely unlikely to be hit */
|
||||
/* fallback to packets for arbitrary packet size and alignment */
|
||||
for (size_t i = 0; i < numPackets; i++)
|
||||
{
|
||||
const size_t offset = i * stride;
|
||||
RayPacketSOA rayN(rayData + offset, N);
|
||||
RayK<VSIZEX> ray;
|
||||
{
|
||||
const size_t offsetN = i * stride;
|
||||
RayPacketSOA rayN(rayData + offsetN, N);
|
||||
|
||||
for (size_t j = 0; j < N; j++)
|
||||
for (size_t j = 0; j < N; j += VSIZEX)
|
||||
{
|
||||
/* invalidate all lanes */
|
||||
ray.tnear = 0.0f;
|
||||
ray.tfar = neg_inf;
|
||||
const size_t offset = j * sizeof(float);
|
||||
vboolx valid = (vintx(int(j)) + vintx(step)) < vintx(int(N));
|
||||
|
||||
/* extract single ray and copy data to first packet lane */
|
||||
rayN.getRayByIndex(j, ray, 0);
|
||||
const vboolx valid = ray.tnear <= ray.tfar;
|
||||
RayK<VSIZEX> ray = rayN.getRayByOffset(valid, offset);
|
||||
valid &= ray.tnear <= ray.tfar;
|
||||
|
||||
if (intersect)
|
||||
scene->intersect(valid, ray, context);
|
||||
scene->intersectors.intersect(valid, ray, context);
|
||||
else
|
||||
scene->occluded(valid, ray, context);
|
||||
scene->intersectors.occluded(valid, ray, context);
|
||||
|
||||
rayN.setHitByIndex(j, ray, 0, intersect);
|
||||
rayN.setHitByOffset(valid, offset, ray, intersect);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -309,70 +250,65 @@ namespace embree
|
||||
RayStreamSOP& rayN = *(RayStreamSOP*)&_rayN;
|
||||
|
||||
/* use fast path for coherent ray mode */
|
||||
#if defined(__AVX__) && ENABLE_COHERENT_STREAM_PATH == 1
|
||||
/* all valid accels need to have a intersectN/occludedN */
|
||||
if (unlikely(isCoherent(context->user->flags) && !scene->isRobust() && scene->accels.validIsecN()))
|
||||
if (unlikely(isCoherent(context->user->flags)))
|
||||
{
|
||||
static const size_t MAX_COHERENT_RAY_PACKETS = MAX_RAYS_PER_OCTANT / VSIZEX;
|
||||
__aligned(64) RayK<VSIZEX> rays[MAX_PACKET_STREAM_SIZE];
|
||||
__aligned(64) RayK<VSIZEX>* rayPtrs[MAX_PACKET_STREAM_SIZE];
|
||||
|
||||
__aligned(64) RayK<VSIZEX> rays[MAX_COHERENT_RAY_PACKETS];
|
||||
__aligned(64) RayK<VSIZEX>* rays_ptr[MAX_COHERENT_RAY_PACKETS];
|
||||
|
||||
for (size_t i = 0; i < N; i += MAX_RAYS_PER_OCTANT)
|
||||
for (size_t i = 0; i < N; i += MAX_INTERNAL_STREAM_SIZE)
|
||||
{
|
||||
const size_t size = min(N - i, MAX_RAYS_PER_OCTANT);
|
||||
const size_t size = min(N - i, MAX_INTERNAL_STREAM_SIZE);
|
||||
|
||||
/* convert from SOP to SOA */
|
||||
for (size_t j = 0; j < size; j += VSIZEX)
|
||||
{
|
||||
const vintx vij = vintx(int(i+j)) + vintx(step);
|
||||
const vboolx valid = vij < vintx(int(N));
|
||||
const size_t offset = sizeof(float) * (i+j);
|
||||
const size_t packet_index = j / VSIZEX;
|
||||
const size_t offset = (i+j) * sizeof(float);
|
||||
const size_t packetIndex = j / VSIZEX;
|
||||
|
||||
RayK<VSIZEX> ray = rayN.getRayByOffset(valid, offset);
|
||||
ray.tnear = select(valid, ray.tnear, zero);
|
||||
ray.tfar = select(valid, ray.tfar, neg_inf);
|
||||
|
||||
rays[packet_index] = ray;
|
||||
rays_ptr[packet_index] = &rays[packet_index]; // rays_ptr might get reordered for occludedN
|
||||
rays[packetIndex] = ray;
|
||||
rayPtrs[packetIndex] = &rays[packetIndex]; // rayPtrs might get reordered for occludedN
|
||||
}
|
||||
|
||||
/* trace stream */
|
||||
if (intersect)
|
||||
scene->intersectN((void**)rays_ptr, size, context);
|
||||
scene->intersectors.intersectN(rayPtrs, size, context);
|
||||
else
|
||||
scene->occludedN((void**)rays_ptr, size, context);
|
||||
scene->intersectors.occludedN(rayPtrs, size, context);
|
||||
|
||||
/* convert from SOA to SOP */
|
||||
for (size_t j = 0; j < size; j += VSIZEX)
|
||||
{
|
||||
const vintx vij = vintx(int(i+j)) + vintx(step);
|
||||
const vboolx valid = vij < vintx(int(N));
|
||||
const size_t offset = sizeof(float) * (i+j);
|
||||
const size_t packet_index = j / VSIZEX;
|
||||
const size_t offset = (i+j) * sizeof(float);
|
||||
const size_t packetIndex = j / VSIZEX;
|
||||
|
||||
rayN.setHitByOffset(valid, offset, rays[packet_index], intersect);
|
||||
rayN.setHitByOffset(valid, offset, rays[packetIndex], intersect);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* fallback to packets */
|
||||
for (size_t i = 0; i < N; i += VSIZEX)
|
||||
{
|
||||
const vintx vi = vintx(int(i)) + vintx(step);
|
||||
vboolx valid = vi < vintx(int(N));
|
||||
const size_t offset = sizeof(float) * i;
|
||||
const size_t offset = i * sizeof(float);
|
||||
|
||||
RayK<VSIZEX> ray = rayN.getRayByOffset(valid, offset);
|
||||
valid &= ray.tnear <= ray.tfar;
|
||||
|
||||
if (intersect)
|
||||
scene->intersect(valid, ray, context);
|
||||
scene->intersectors.intersect(valid, ray, context);
|
||||
else
|
||||
scene->occluded(valid, ray, context);
|
||||
scene->intersectors.occluded(valid, ray, context);
|
||||
|
||||
rayN.setHitByOffset(valid, offset, ray, intersect);
|
||||
}
|
||||
|
||||
@@ -89,14 +89,12 @@ namespace embree
|
||||
|
||||
virtual const BBox3fa leafBounds (NodeRef& ref) const
|
||||
{
|
||||
size_t ty; Primitive* prim = (Primitive*) ref.leaf(ty);
|
||||
size_t num; char* prim = ref.leaf(num);
|
||||
if (unlikely(ref == BVH::emptyNode)) return empty;
|
||||
|
||||
BBox3fa bounds = empty;
|
||||
for (size_t i=0;; i++) {
|
||||
bounds.extend(prim[i].update(mesh));
|
||||
if (prim[i].last()) break;
|
||||
}
|
||||
for (size_t i=0; i<num; i++)
|
||||
bounds.extend(((Primitive*)prim)[i].update(mesh));
|
||||
return bounds;
|
||||
}
|
||||
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -154,15 +154,11 @@ namespace embree
|
||||
}
|
||||
else if (node.isLeaf())
|
||||
{
|
||||
size_t ty; const char* tri = node.leaf(ty);
|
||||
if (node != BVH::emptyNode)
|
||||
size_t num; const char* tri = node.leaf(num);
|
||||
if (num)
|
||||
{
|
||||
size_t num = 0;
|
||||
while (true) {
|
||||
const char* cur = tri+num*bvh->primTy->bytes;
|
||||
s.statLeaf.numPrims += bvh->primTy->size(cur);
|
||||
num++;
|
||||
if (bvh->primTy->last(cur)) break;
|
||||
for (size_t i=0; i<num; i++) {
|
||||
s.statLeaf.numPrims += bvh->primTy->size(tri+i*bvh->primTy->bytes);
|
||||
}
|
||||
s.statLeaf.numLeaves++;
|
||||
s.statLeaf.numPrimBlocks += num;
|
||||
|
||||
@@ -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
-33
@@ -18,10 +18,14 @@
|
||||
|
||||
#include "default.h"
|
||||
|
||||
#define MAX_INTERNAL_STREAM_SIZE 64
|
||||
|
||||
namespace embree
|
||||
{
|
||||
#if defined(__X86_64__)
|
||||
static const size_t MAX_INTERNAL_STREAM_SIZE = 64;
|
||||
#else
|
||||
static const size_t MAX_INTERNAL_STREAM_SIZE = 32;
|
||||
#endif
|
||||
|
||||
/* Ray structure for K rays */
|
||||
template<int K>
|
||||
struct RayK
|
||||
@@ -364,35 +368,35 @@ namespace embree
|
||||
|
||||
struct RayPacketSOA
|
||||
{
|
||||
__forceinline RayPacketSOA(void* rays, size_t K)
|
||||
: ptr((char*)rays), K(K) {}
|
||||
__forceinline RayPacketSOA(void* rays, size_t N)
|
||||
: ptr((char*)rays), N(N) {}
|
||||
|
||||
/* ray data access functions */
|
||||
__forceinline float* orgx(size_t offset) { return (float*)&ptr[0*4*K+offset]; } //!< x coordinate of ray origin
|
||||
__forceinline float* orgy(size_t offset) { return (float*)&ptr[1*4*K+offset]; } //!< y coordinate of ray origin
|
||||
__forceinline float* orgz(size_t offset) { return (float*)&ptr[2*4*K+offset]; }; //!< z coordinate of ray origin
|
||||
__forceinline float* orgx(size_t offset) { return (float*)&ptr[0*4*N+offset]; } //!< x coordinate of ray origin
|
||||
__forceinline float* orgy(size_t offset) { return (float*)&ptr[1*4*N+offset]; } //!< y coordinate of ray origin
|
||||
__forceinline float* orgz(size_t offset) { return (float*)&ptr[2*4*N+offset]; }; //!< z coordinate of ray origin
|
||||
|
||||
__forceinline float* dirx(size_t offset) { return (float*)&ptr[3*4*K+offset]; }; //!< x coordinate of ray direction
|
||||
__forceinline float* diry(size_t offset) { return (float*)&ptr[4*4*K+offset]; }; //!< y coordinate of ray direction
|
||||
__forceinline float* dirz(size_t offset) { return (float*)&ptr[5*4*K+offset]; }; //!< z coordinate of ray direction
|
||||
__forceinline float* dirx(size_t offset) { return (float*)&ptr[3*4*N+offset]; }; //!< x coordinate of ray direction
|
||||
__forceinline float* diry(size_t offset) { return (float*)&ptr[4*4*N+offset]; }; //!< y coordinate of ray direction
|
||||
__forceinline float* dirz(size_t offset) { return (float*)&ptr[5*4*N+offset]; }; //!< z coordinate of ray direction
|
||||
|
||||
__forceinline float* tnear(size_t offset) { return (float*)&ptr[6*4*K+offset]; }; //!< Start of ray segment
|
||||
__forceinline float* tfar (size_t offset) { return (float*)&ptr[7*4*K+offset]; }; //!< End of ray segment (set to hit distance)
|
||||
__forceinline float* tnear(size_t offset) { return (float*)&ptr[6*4*N+offset]; }; //!< Start of ray segment
|
||||
__forceinline float* tfar (size_t offset) { return (float*)&ptr[7*4*N+offset]; }; //!< End of ray segment (set to hit distance)
|
||||
|
||||
__forceinline float* time(size_t offset) { return (float*)&ptr[8*4*K+offset]; }; //!< Time of this ray for motion blur
|
||||
__forceinline int* mask(size_t offset) { return (int*) &ptr[9*4*K+offset]; }; //!< Used to mask out objects during traversal (optional)
|
||||
__forceinline float* time(size_t offset) { return (float*)&ptr[8*4*N+offset]; }; //!< Time of this ray for motion blur
|
||||
__forceinline int* mask(size_t offset) { return (int*) &ptr[9*4*N+offset]; }; //!< Used to mask out objects during traversal (optional)
|
||||
|
||||
/* hit data access functions */
|
||||
__forceinline float* Ngx(size_t offset) { return (float*)&ptr[10*4*K+offset]; }; //!< x coordinate of geometry normal
|
||||
__forceinline float* Ngy(size_t offset) { return (float*)&ptr[11*4*K+offset]; }; //!< y coordinate of geometry normal
|
||||
__forceinline float* Ngz(size_t offset) { return (float*)&ptr[12*4*K+offset]; }; //!< z coordinate of geometry normal
|
||||
__forceinline float* Ngx(size_t offset) { return (float*)&ptr[10*4*N+offset]; }; //!< x coordinate of geometry normal
|
||||
__forceinline float* Ngy(size_t offset) { return (float*)&ptr[11*4*N+offset]; }; //!< y coordinate of geometry normal
|
||||
__forceinline float* Ngz(size_t offset) { return (float*)&ptr[12*4*N+offset]; }; //!< z coordinate of geometry normal
|
||||
|
||||
__forceinline float* u(size_t offset) { return (float*)&ptr[13*4*K+offset]; }; //!< Barycentric u coordinate of hit
|
||||
__forceinline float* v(size_t offset) { return (float*)&ptr[14*4*K+offset]; }; //!< Barycentric v coordinate of hit
|
||||
__forceinline float* u(size_t offset) { return (float*)&ptr[13*4*N+offset]; }; //!< Barycentric u coordinate of hit
|
||||
__forceinline float* v(size_t offset) { return (float*)&ptr[14*4*N+offset]; }; //!< Barycentric v coordinate of hit
|
||||
|
||||
__forceinline int* geomID(size_t offset) { return (int*)&ptr[15*4*K+offset]; }; //!< geometry ID
|
||||
__forceinline int* primID(size_t offset) { return (int*)&ptr[16*4*K+offset]; }; //!< primitive ID
|
||||
__forceinline int* instID(size_t offset) { return (int*)&ptr[17*4*K+offset]; }; //!< instance ID
|
||||
__forceinline int* geomID(size_t offset) { return (int*)&ptr[15*4*N+offset]; }; //!< geometry ID
|
||||
__forceinline int* primID(size_t offset) { return (int*)&ptr[16*4*N+offset]; }; //!< primitive ID
|
||||
__forceinline int* instID(size_t offset) { return (int*)&ptr[17*4*N+offset]; }; //!< instance ID
|
||||
|
||||
|
||||
__forceinline void setRayByIndex(size_t index, const Ray& ray, int* valid)
|
||||
@@ -467,8 +471,45 @@ namespace embree
|
||||
ray.tnear = vfloat<K>::loadu(tnear(offset));
|
||||
ray.tfar = vfloat<K>::loadu(tfar(offset));
|
||||
ray.time = vfloat<K>::loadu(time(offset));
|
||||
ray.mask = vint<K> ::loadu(mask(offset));
|
||||
ray.instID= vint<K> ::loadu(instID(offset));
|
||||
ray.mask = vint<K>::loadu(mask(offset));
|
||||
ray.instID = vint<K>::loadu(instID(offset));
|
||||
ray.geomID = RTC_INVALID_GEOMETRY_ID;
|
||||
return ray;
|
||||
}
|
||||
|
||||
template<int K>
|
||||
__forceinline RayK<K> getRayByOffset(const vbool<K>& valid, size_t offset)
|
||||
{
|
||||
RayK<K> ray;
|
||||
ray.org.x = vfloat<K>::loadu(valid, orgx(offset));
|
||||
ray.org.y = vfloat<K>::loadu(valid, orgy(offset));
|
||||
ray.org.z = vfloat<K>::loadu(valid, orgz(offset));
|
||||
ray.dir.x = vfloat<K>::loadu(valid, dirx(offset));
|
||||
ray.dir.y = vfloat<K>::loadu(valid, diry(offset));
|
||||
ray.dir.z = vfloat<K>::loadu(valid, dirz(offset));
|
||||
ray.tnear = vfloat<K>::loadu(valid, tnear(offset));
|
||||
ray.tfar = vfloat<K>::loadu(valid, tfar(offset));
|
||||
ray.time = vfloat<K>::loadu(valid, time(offset));
|
||||
ray.mask = vint<K>::loadu(valid, mask(offset));
|
||||
|
||||
#if !defined(__AVX__)
|
||||
/* SSE: some ray members must be loaded with scalar instructions to ensure that we don't cause memory faults,
|
||||
because the SSE masked loads always access the entire vector */
|
||||
if (unlikely(!all(valid)))
|
||||
{
|
||||
ray.instID = zero;
|
||||
for (size_t k = 0; k < K; k++)
|
||||
{
|
||||
if (likely(valid[k]))
|
||||
ray.instID[k] = instID(offset)[k];
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
ray.instID = vint<K>::loadu(valid, instID(offset));
|
||||
}
|
||||
|
||||
ray.geomID = RTC_INVALID_GEOMETRY_ID;
|
||||
return ray;
|
||||
}
|
||||
@@ -539,17 +580,43 @@ namespace embree
|
||||
|
||||
if (likely(any(valid)))
|
||||
{
|
||||
vint<K>::storeu(valid, geomID(offset), ray.geomID);
|
||||
#if !defined(__AVX__)
|
||||
/* SSE: some ray members must be stored with scalar instructions to ensure that we don't cause memory faults,
|
||||
because the SSE masked stores always access the entire vector */
|
||||
if (unlikely(!all(valid_i)))
|
||||
{
|
||||
for (size_t k = 0; k < K; k++)
|
||||
{
|
||||
if (likely(valid[k]))
|
||||
{
|
||||
geomID(offset)[k] = ray.geomID[k];
|
||||
if (intersect)
|
||||
{
|
||||
primID(offset)[k] = ray.primID[k];
|
||||
instID(offset)[k] = ray.instID[k];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
vint<K>::storeu(valid, geomID(offset), ray.geomID);
|
||||
if (intersect)
|
||||
{
|
||||
vint<K>::storeu(valid, primID(offset), ray.primID);
|
||||
vint<K>::storeu(valid, instID(offset), ray.instID);
|
||||
}
|
||||
}
|
||||
|
||||
if (intersect)
|
||||
{
|
||||
vfloat<K>::storeu(valid, tfar(offset), ray.tfar);
|
||||
vfloat<K>::storeu(valid, u(offset), ray.u);
|
||||
vfloat<K>::storeu(valid, v(offset), ray.v);
|
||||
vint<K> ::storeu(valid, primID(offset), ray.primID);
|
||||
vfloat<K>::storeu(valid, Ngx(offset), ray.Ng.x);
|
||||
vfloat<K>::storeu(valid, Ngy(offset), ray.Ng.y);
|
||||
vfloat<K>::storeu(valid, Ngz(offset), ray.Ng.z);
|
||||
vint<K> ::storeu(valid, instID(offset), ray.instID);
|
||||
vfloat<K>::storeu(valid, u(offset), ray.u);
|
||||
vfloat<K>::storeu(valid, v(offset), ray.v);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -571,7 +638,7 @@ namespace embree
|
||||
}
|
||||
|
||||
char* __restrict__ ptr;
|
||||
size_t K;
|
||||
size_t N;
|
||||
};
|
||||
|
||||
template<size_t MAX_K>
|
||||
@@ -780,8 +847,15 @@ namespace embree
|
||||
ray.time = vfloat<K>::template gather<1>(valid, &ptr->time, offset);
|
||||
ray.mask = vint<K>::template gather<1>(valid, &ptr->mask, offset);
|
||||
ray.instID = vint<K>::template gather<1>(valid, (int*)&ptr->instID, offset);
|
||||
ray.geomID = RTC_INVALID_GEOMETRY_ID;
|
||||
#else
|
||||
ray.org = zero;
|
||||
ray.dir = zero;
|
||||
ray.tnear = zero;
|
||||
ray.tfar = zero;
|
||||
ray.time = zero;
|
||||
ray.mask = zero;
|
||||
ray.instID = zero;
|
||||
|
||||
for (size_t k = 0; k < K; k++)
|
||||
{
|
||||
if (likely(valid[k]))
|
||||
@@ -799,11 +873,12 @@ namespace embree
|
||||
ray.time[k] = ray_k->time;
|
||||
ray.mask[k] = ray_k->mask;
|
||||
ray.instID[k] = ray_k->instID;
|
||||
ray.geomID[k] = RTC_INVALID_GEOMETRY_ID;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
ray.geomID = RTC_INVALID_GEOMETRY_ID;
|
||||
|
||||
return ray;
|
||||
}
|
||||
|
||||
@@ -1014,6 +1089,14 @@ namespace embree
|
||||
|
||||
RayK<K> ray;
|
||||
|
||||
ray.org = zero;
|
||||
ray.dir = zero;
|
||||
ray.tnear = zero;
|
||||
ray.tfar = zero;
|
||||
ray.time = zero;
|
||||
ray.mask = zero;
|
||||
ray.instID = zero;
|
||||
|
||||
for (size_t k = 0; k < K; k++)
|
||||
{
|
||||
if (likely(valid[k]))
|
||||
@@ -1031,10 +1114,11 @@ namespace embree
|
||||
ray.time[k] = ray_k->time;
|
||||
ray.mask[k] = ray_k->mask;
|
||||
ray.instID[k] = ray_k->instID;
|
||||
ray.geomID[k] = RTC_INVALID_GEOMETRY_ID;
|
||||
}
|
||||
}
|
||||
|
||||
ray.geomID = RTC_INVALID_GEOMETRY_ID;
|
||||
|
||||
return ray;
|
||||
}
|
||||
|
||||
|
||||
+22
-22
@@ -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]);
|
||||
|
||||
@@ -26,7 +26,6 @@ namespace embree
|
||||
struct Type : public PrimitiveType {
|
||||
Type ();
|
||||
size_t size(const char* This) const;
|
||||
bool last(const char* This) const;
|
||||
};
|
||||
static Type type;
|
||||
|
||||
@@ -44,20 +43,17 @@ namespace embree
|
||||
__forceinline Bezier1i () {}
|
||||
|
||||
/*! Construction from vertices and IDs. */
|
||||
__forceinline Bezier1i (const unsigned vertexID, const unsigned geomID, const unsigned primID, const bool last)
|
||||
: vertexID(vertexID), geom(geomID | (unsigned(last) << 31)), prim(primID) {}
|
||||
|
||||
/*! checks if this is the last primitive */
|
||||
__forceinline unsigned last() const { return geom & 0x80000000; }
|
||||
__forceinline Bezier1i (const unsigned vertexID, const unsigned geomID, const unsigned primID)
|
||||
: vertexID(vertexID), geom(geomID), prim(primID) {}
|
||||
|
||||
/*! returns geometry ID */
|
||||
__forceinline unsigned geomID() const { return geom & 0x7FFFFFFF; }
|
||||
__forceinline unsigned geomID() const { return geom; }
|
||||
|
||||
/*! returns primitive ID */
|
||||
__forceinline unsigned primID() const { return prim; }
|
||||
|
||||
/*! fill curve from curve list */
|
||||
__forceinline void fill(const PrimRef* prims, size_t& i, size_t end, Scene* scene, bool last)
|
||||
__forceinline void fill(const PrimRef* prims, size_t& i, size_t end, Scene* scene)
|
||||
{
|
||||
const PrimRef& prim = prims[i];
|
||||
i++;
|
||||
@@ -65,11 +61,11 @@ namespace embree
|
||||
const unsigned primID = prim.primID();
|
||||
const NativeCurves* curves = scene->get<NativeCurves>(geomID);
|
||||
const unsigned vertexID = curves->curve(primID);
|
||||
new (this) Bezier1i(vertexID,geomID,primID,last);
|
||||
new (this) Bezier1i(vertexID,geomID,primID);
|
||||
}
|
||||
|
||||
/*! fill curve from curve list */
|
||||
__forceinline LBBox3fa fillMB(const PrimRefMB* prims, size_t& i, size_t end, Scene* scene, const BBox1f time_range, bool last)
|
||||
__forceinline LBBox3fa fillMB(const PrimRefMB* prims, size_t& i, size_t end, Scene* scene, const BBox1f time_range)
|
||||
{
|
||||
const PrimRefMB& prim = prims[i];
|
||||
i++;
|
||||
@@ -77,7 +73,7 @@ namespace embree
|
||||
const unsigned primID = prim.primID();
|
||||
const NativeCurves* curves = scene->get<NativeCurves>(geomID);
|
||||
const unsigned vertexID = curves->curve(primID);
|
||||
new (this) Bezier1i(vertexID,geomID,primID,last);
|
||||
new (this) Bezier1i(vertexID,geomID,primID);
|
||||
return curves->linearBounds(primID,time_range);
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@ namespace embree
|
||||
{
|
||||
Type ();
|
||||
size_t size(const char* This) const;
|
||||
bool last(const char* This) const;
|
||||
};
|
||||
static Type type;
|
||||
|
||||
@@ -46,13 +45,8 @@ namespace embree
|
||||
__forceinline Bezier1v () {}
|
||||
|
||||
/*! Construction from vertices and IDs. */
|
||||
__forceinline Bezier1v (const Vec3fa& p0, const Vec3fa& p1, const Vec3fa& p2, const Vec3fa& p3, const unsigned int geomID, const unsigned int primID, const bool last)
|
||||
: p0(p0), p1(p1), p2(p2), p3(p3), geom(geomID | (unsigned(last) << 31)), prim(primID) {}
|
||||
|
||||
/*! checks if this is the last primitive */
|
||||
__forceinline unsigned last() const {
|
||||
return geom & 0x80000000;
|
||||
}
|
||||
__forceinline Bezier1v (const Vec3fa& p0, const Vec3fa& p1, const Vec3fa& p2, const Vec3fa& p3, const unsigned int geomID, const unsigned int primID)
|
||||
: p0(p0), p1(p1), p2(p2), p3(p3), geom(geomID), prim(primID) {}
|
||||
|
||||
/*! return primitive ID */
|
||||
__forceinline unsigned int primID() const {
|
||||
@@ -61,11 +55,11 @@ namespace embree
|
||||
|
||||
/*! return geometry ID */
|
||||
__forceinline unsigned int geomID() const {
|
||||
return geom & 0x7FFFFFFF;
|
||||
return geom;
|
||||
}
|
||||
|
||||
/*! fill triangle from triangle list */
|
||||
__forceinline void fill(const PrimRef* prims, size_t& i, size_t end, Scene* scene, bool last)
|
||||
__forceinline void fill(const PrimRef* prims, size_t& i, size_t end, Scene* scene)
|
||||
{
|
||||
const PrimRef& prim = prims[i];
|
||||
i++;
|
||||
@@ -77,7 +71,7 @@ namespace embree
|
||||
const Vec3fa& p1 = curves->vertex(id+1);
|
||||
const Vec3fa& p2 = curves->vertex(id+2);
|
||||
const Vec3fa& p3 = curves->vertex(id+3);
|
||||
new (this) Bezier1v(p0,p1,p2,p3,geomID,primID,last);
|
||||
new (this) Bezier1v(p0,p1,p2,p3,geomID,primID);
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& cout, const Bezier1v& b)
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -212,7 +212,7 @@ namespace embree
|
||||
if (Mx > M) valid &= (1<<M)-1;
|
||||
hit.finalize();
|
||||
size_t i = select_min(valid,hit.vt);
|
||||
int geomID = geomIDs[i] & 0x7FFFFFFF;
|
||||
int geomID = geomIDs[i];
|
||||
int instID = context->geomID_to_instID ? context->geomID_to_instID[0] : geomID;
|
||||
/* intersection filter test */
|
||||
#if defined(EMBREE_INTERSECTION_FILTER) || defined(EMBREE_RAY_MASK)
|
||||
@@ -223,7 +223,7 @@ namespace embree
|
||||
if (unlikely(none(valid))) return foundhit;
|
||||
i = select_min(valid,hit.vt);
|
||||
|
||||
geomID = geomIDs[i] & 0x7FFFFFFF;
|
||||
geomID = geomIDs[i];
|
||||
instID = context->geomID_to_instID ? context->geomID_to_instID[0] : geomID;
|
||||
entry:
|
||||
Geometry* geometry MAYBE_UNUSED = scene->get(geomID);
|
||||
@@ -291,7 +291,7 @@ namespace embree
|
||||
if (Mx > M) valid &= (1<<M)-1;
|
||||
hit.finalize();
|
||||
size_t i = select_min(valid,hit.vt);
|
||||
int geomID = geomIDs[i] & 0x7FFFFFFF;
|
||||
int geomID = geomIDs[i];
|
||||
int instID = context->geomID_to_instID ? context->geomID_to_instID[0] : geomID;
|
||||
|
||||
/* intersection filter test */
|
||||
@@ -303,7 +303,7 @@ namespace embree
|
||||
if (unlikely(none(valid))) return foundhit;
|
||||
i = select_min(valid,hit.vt);
|
||||
|
||||
geomID = geomIDs[i] & 0x7FFFFFFF;
|
||||
geomID = geomIDs[i];
|
||||
instID = context->geomID_to_instID ? context->geomID_to_instID[0] : geomID;
|
||||
entry:
|
||||
Geometry* geometry MAYBE_UNUSED = scene->get(geomID);
|
||||
@@ -374,7 +374,7 @@ namespace embree
|
||||
entry:
|
||||
size_t i=__bsf(m);
|
||||
|
||||
const int geomID = geomIDs[i] & 0x7FFFFFFF;
|
||||
const int geomID = geomIDs[i];
|
||||
const int instID = context->geomID_to_instID ? context->geomID_to_instID[0] : geomID;
|
||||
Geometry* geometry MAYBE_UNUSED = scene->get(geomID);
|
||||
|
||||
@@ -539,7 +539,7 @@ namespace embree
|
||||
|
||||
std::tie(u,v,t,Ng) = hit();
|
||||
|
||||
const int geomID = geomIDs[i] & 0x7FFFFFFF;
|
||||
const int geomID = geomIDs[i];
|
||||
const int primID = primIDs[i];
|
||||
Geometry* geometry MAYBE_UNUSED = scene->get(geomID);
|
||||
|
||||
@@ -596,7 +596,7 @@ namespace embree
|
||||
|
||||
/* ray masking test */
|
||||
Scene* scene = context->scene;
|
||||
const int geomID = geomIDs[i] & 0x7FFFFFFF;
|
||||
const int geomID = geomIDs[i];
|
||||
const int primID = primIDs[i];
|
||||
Geometry* geometry MAYBE_UNUSED = scene->get(geomID);
|
||||
#if defined(EMBREE_RAY_MASK)
|
||||
@@ -749,7 +749,7 @@ namespace embree
|
||||
if (Mx > M) valid &= (1<<M)-1;
|
||||
size_t i = select_min(valid,hit.vt);
|
||||
assert(i<M);
|
||||
int geomID = geomIDs[i] & 0x7FFFFFFF;
|
||||
int geomID = geomIDs[i];
|
||||
|
||||
/* intersection filter test */
|
||||
#if defined(EMBREE_INTERSECTION_FILTER) || defined(EMBREE_RAY_MASK)
|
||||
@@ -760,7 +760,7 @@ namespace embree
|
||||
if (unlikely(none(valid))) return foundhit;
|
||||
i = select_min(valid,hit.vt);
|
||||
assert(i<M);
|
||||
geomID = geomIDs[i] & 0x7FFFFFFF;
|
||||
geomID = geomIDs[i];
|
||||
entry:
|
||||
Geometry* geometry MAYBE_UNUSED = scene->get(geomID);
|
||||
|
||||
@@ -842,7 +842,7 @@ namespace embree
|
||||
entry:
|
||||
size_t i=__bsf(m);
|
||||
|
||||
const int geomID = geomIDs[i] & 0x7FFFFFFF;
|
||||
const int geomID = geomIDs[i];
|
||||
Geometry* geometry MAYBE_UNUSED = scene->get(geomID);
|
||||
|
||||
#if defined(EMBREE_RAY_MASK)
|
||||
|
||||
@@ -29,33 +29,28 @@ namespace embree
|
||||
typedef typename Intersector::Primitive Primitive;
|
||||
typedef typename Intersector::Precalculations Precalculations;
|
||||
|
||||
static const bool validIntersectorK = false; // FIXME: why do we need this
|
||||
|
||||
static __forceinline void intersect(Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive* prim, size_t ty, size_t& lazy_node)
|
||||
static __forceinline void intersect(Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive* prim, size_t num, size_t& lazy_node)
|
||||
{
|
||||
for (size_t i=0;; i++) {
|
||||
for (size_t i=0; i<num; i++)
|
||||
Intersector::intersect(pre,ray,context,prim[i]);
|
||||
if (prim[i].last()) break;
|
||||
}
|
||||
}
|
||||
|
||||
static __forceinline bool occluded(Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive* prim, size_t ty, size_t& lazy_node)
|
||||
static __forceinline bool occluded(Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive* prim, size_t num, size_t& lazy_node)
|
||||
{
|
||||
for (size_t i=0;; i++) {
|
||||
for (size_t i=0; i<num; i++) {
|
||||
if (Intersector::occluded(pre,ray,context,prim[i]))
|
||||
return true;
|
||||
if (prim[i].last()) break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template<int K>
|
||||
static __forceinline void intersectK(const vbool<K>& valid, /* PrecalculationsK& pre, */ RayK<K>& ray, IntersectContext* context, const Primitive* prim, size_t ty, size_t& lazy_node)
|
||||
static __forceinline void intersectK(const vbool<K>& valid, /* PrecalculationsK& pre, */ RayK<K>& ray, IntersectContext* context, const Primitive* prim, size_t num, size_t& lazy_node)
|
||||
{
|
||||
}
|
||||
|
||||
template<int K>
|
||||
static __forceinline vbool<K> occludedK(const vbool<K>& valid, /* PrecalculationsK& pre, */ RayK<K>& ray, IntersectContext* context, const Primitive* prim, size_t ty, size_t& lazy_node)
|
||||
static __forceinline vbool<K> occludedK(const vbool<K>& valid, /* PrecalculationsK& pre, */ RayK<K>& ray, IntersectContext* context, const Primitive* prim, size_t num, size_t& lazy_node)
|
||||
{
|
||||
return valid;
|
||||
}
|
||||
@@ -67,39 +62,35 @@ namespace embree
|
||||
typedef typename Intersector::Primitive Primitive;
|
||||
typedef typename Intersector::Precalculations Precalculations;
|
||||
|
||||
static __forceinline void intersect(const vbool<K>& valid, Precalculations& pre, RayK<K>& ray, IntersectContext* context, const Primitive* prim, size_t ty, size_t& lazy_node)
|
||||
static __forceinline void intersect(const vbool<K>& valid, Precalculations& pre, RayK<K>& ray, IntersectContext* context, const Primitive* prim, size_t num, size_t& lazy_node)
|
||||
{
|
||||
for (size_t i=0;; i++) {
|
||||
for (size_t i=0; i<num; i++) {
|
||||
Intersector::intersect(valid,pre,ray,context,prim[i]);
|
||||
if (prim[i].last()) break;
|
||||
}
|
||||
}
|
||||
|
||||
static __forceinline vbool<K> occluded(const vbool<K>& valid, Precalculations& pre, RayK<K>& ray, IntersectContext* context, const Primitive* prim, size_t ty, size_t& lazy_node)
|
||||
static __forceinline vbool<K> occluded(const vbool<K>& valid, Precalculations& pre, RayK<K>& ray, IntersectContext* context, const Primitive* prim, size_t num, size_t& lazy_node)
|
||||
{
|
||||
vbool<K> valid0 = valid;
|
||||
for (size_t i=0;; i++) {
|
||||
for (size_t i=0; i<num; i++) {
|
||||
valid0 &= !Intersector::occluded(valid0,pre,ray,context,prim[i]);
|
||||
if (none(valid0)) break;
|
||||
if (prim[i].last()) break;
|
||||
}
|
||||
return !valid0;
|
||||
}
|
||||
|
||||
static __forceinline void intersect(Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const Primitive* prim, size_t ty, size_t& lazy_node)
|
||||
static __forceinline void intersect(Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const Primitive* prim, size_t num, size_t& lazy_node)
|
||||
{
|
||||
for (size_t i=0;; i++) {
|
||||
for (size_t i=0; i<num; i++) {
|
||||
Intersector::intersect(pre,ray,k,context,prim[i]);
|
||||
if (prim[i].last()) break;
|
||||
}
|
||||
}
|
||||
|
||||
static __forceinline bool occluded(Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const Primitive* prim, size_t ty, size_t& lazy_node)
|
||||
static __forceinline bool occluded(Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const Primitive* prim, size_t num, size_t& lazy_node)
|
||||
{
|
||||
for (size_t i=0;; i++) {
|
||||
for (size_t i=0; i<num; i++) {
|
||||
if (Intersector::occluded(pre,ray,k,context,prim[i]))
|
||||
return true;
|
||||
if (prim[i].last()) break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -112,30 +103,27 @@ namespace embree
|
||||
{
|
||||
typedef typename IntersectorK::Primitive PrimitiveK;
|
||||
typedef typename IntersectorK::Precalculations PrecalculationsK;
|
||||
|
||||
static const bool validIntersectorK = true;
|
||||
|
||||
static __forceinline void intersectK(const vbool<K>& valid, /* PrecalculationsK& pre, */ RayK<K>& ray, IntersectContext* context, const PrimitiveK* prim, size_t ty, size_t& lazy_node)
|
||||
static __forceinline void intersectK(const vbool<K>& valid, /* PrecalculationsK& pre, */ RayK<K>& ray, IntersectContext* context, const PrimitiveK* prim, size_t num, size_t& lazy_node)
|
||||
{
|
||||
PrecalculationsK pre(valid,ray); // FIXME: might cause trouble
|
||||
|
||||
for (size_t i=0; ; i++) {
|
||||
for (size_t i=0; i<num; i++) {
|
||||
IntersectorK::intersect(valid,pre,ray,context,prim[i]);
|
||||
if (prim[i].last()) break;
|
||||
}
|
||||
}
|
||||
|
||||
static __forceinline vbool<K> occludedK(const vbool<K>& valid, /* PrecalculationsK& pre, */ RayK<K>& ray, IntersectContext* context, const PrimitiveK* prim, size_t ty, size_t& lazy_node)
|
||||
static __forceinline vbool<K> occludedK(const vbool<K>& valid, /* PrecalculationsK& pre, */ RayK<K>& ray, IntersectContext* context, const PrimitiveK* prim, size_t num, size_t& lazy_node)
|
||||
{
|
||||
PrecalculationsK pre(valid,ray); // FIXME: might cause trouble
|
||||
vbool<K> valid0 = valid;
|
||||
for (size_t i=0; ; i++) {
|
||||
for (size_t i=0; i<num; i++) {
|
||||
valid0 &= !IntersectorK::occluded(valid0,pre,ray,context,prim[i]);
|
||||
if (none(valid0)) break;
|
||||
if (prim[i].last()) break;
|
||||
}
|
||||
return !valid0;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
+18
-28
@@ -28,7 +28,6 @@ namespace embree
|
||||
{
|
||||
Type();
|
||||
size_t size(const char* This) const;
|
||||
bool last(const char* This) const;
|
||||
};
|
||||
static Type type;
|
||||
|
||||
@@ -49,11 +48,8 @@ namespace embree
|
||||
__forceinline LineMi() { }
|
||||
|
||||
/* Construction from vertices and IDs */
|
||||
__forceinline LineMi(const vint<M>& v0, const vint<M>& geomIDs, const vint<M>& primIDs, const bool last)
|
||||
: v0(v0), geomIDs(geomIDs), primIDs(primIDs)
|
||||
{
|
||||
this->geomIDs[0] |= unsigned(last) << 31;
|
||||
}
|
||||
__forceinline LineMi(const vint<M>& v0, const vint<M>& geomIDs, const vint<M>& primIDs)
|
||||
: v0(v0), geomIDs(geomIDs), primIDs(primIDs) {}
|
||||
|
||||
/* Returns a mask that tells which line segments are valid */
|
||||
__forceinline vbool<M> valid() const { return primIDs != vint<M>(-1); }
|
||||
@@ -68,16 +64,10 @@ namespace embree
|
||||
/* Returns the number of stored line segments */
|
||||
__forceinline size_t size() const { return __bsf(~movemask(valid())); }
|
||||
|
||||
/*! checks if this is the last primitive */
|
||||
__forceinline unsigned last() const { return geomIDs[0] & 0x80000000; }
|
||||
|
||||
/* Returns the geometry IDs */
|
||||
__forceinline vint<M>& geomID() { return geomIDs; }
|
||||
__forceinline const vint<M>& geomID() const { return geomIDs; }
|
||||
__forceinline int geomID(const size_t i) const {
|
||||
assert(i<M);
|
||||
return geomIDs[i] & 0x7FFFFFFF;
|
||||
}
|
||||
__forceinline int geomID(const size_t i) const { assert(i<M); return geomIDs[i]; }
|
||||
|
||||
/* Returns the primitive IDs */
|
||||
__forceinline vint<M>& primID() { return primIDs; }
|
||||
@@ -146,7 +136,7 @@ namespace embree
|
||||
|
||||
/* Fill line segment from line segment list */
|
||||
template<typename PrimRefT>
|
||||
__forceinline void fill(const PrimRefT* prims, size_t& begin, size_t end, Scene* scene, bool last)
|
||||
__forceinline void fill(const PrimRefT* prims, size_t& begin, size_t end, Scene* scene)
|
||||
{
|
||||
vint<M> geomID, primID;
|
||||
vint<M> v0;
|
||||
@@ -171,18 +161,18 @@ namespace embree
|
||||
if (begin<end) prim = &prims[begin];
|
||||
}
|
||||
|
||||
new (this) LineMi(v0,geomID,primID,last); // FIXME: use non temporal store
|
||||
new (this) LineMi(v0,geomID,primID); // FIXME: use non temporal store
|
||||
}
|
||||
|
||||
__forceinline LBBox3fa fillMB(const PrimRef* prims, size_t& begin, size_t end, Scene* scene, size_t itime, bool last)
|
||||
__forceinline LBBox3fa fillMB(const PrimRef* prims, size_t& begin, size_t end, Scene* scene, size_t itime)
|
||||
{
|
||||
fill(prims,begin,end,scene,last);
|
||||
fill(prims,begin,end,scene);
|
||||
return linearBounds(scene,itime);
|
||||
}
|
||||
|
||||
__forceinline LBBox3fa fillMB(const PrimRefMB* prims, size_t& begin, size_t end, Scene* scene, const BBox1f time_range, bool last)
|
||||
__forceinline LBBox3fa fillMB(const PrimRefMB* prims, size_t& begin, size_t end, Scene* scene, const BBox1f time_range)
|
||||
{
|
||||
fill(prims,begin,end,scene,last);
|
||||
fill(prims,begin,end,scene);
|
||||
return linearBounds(scene,time_range);
|
||||
}
|
||||
|
||||
@@ -203,7 +193,7 @@ namespace embree
|
||||
|
||||
/*! output operator */
|
||||
friend __forceinline std::ostream& operator<<(std::ostream& cout, const LineMi& line) {
|
||||
return cout << "Line" << M << "i {" << line.v0 << ", " << (line.geomIDs & 0x7FFFFFFF) << ", " << line.primIDs << "}";
|
||||
return cout << "Line" << M << "i {" << line.v0 << ", " << line.geomIDs << ", " << line.primIDs << "}";
|
||||
}
|
||||
|
||||
public:
|
||||
@@ -218,10 +208,10 @@ namespace embree
|
||||
Vec4vf4& p1,
|
||||
const Scene* scene) const
|
||||
{
|
||||
const LineSegments* geom0 = scene->get<LineSegments>(geomIDs[0] & 0x7FFFFFFF);
|
||||
const LineSegments* geom1 = scene->get<LineSegments>(geomIDs[1]);
|
||||
const LineSegments* geom2 = scene->get<LineSegments>(geomIDs[2]);
|
||||
const LineSegments* geom3 = scene->get<LineSegments>(geomIDs[3]);
|
||||
const LineSegments* geom0 = scene->get<LineSegments>(geomID(0));
|
||||
const LineSegments* geom1 = scene->get<LineSegments>(geomID(1));
|
||||
const LineSegments* geom2 = scene->get<LineSegments>(geomID(2));
|
||||
const LineSegments* geom3 = scene->get<LineSegments>(geomID(3));
|
||||
|
||||
const vfloat4 a0 = vfloat4::loadu(geom0->vertexPtr(v0[0]));
|
||||
const vfloat4 a1 = vfloat4::loadu(geom1->vertexPtr(v0[1]));
|
||||
@@ -268,10 +258,10 @@ namespace embree
|
||||
const Scene* scene,
|
||||
float time) const
|
||||
{
|
||||
const LineSegments* geom0 = scene->get<LineSegments>(geomIDs[0] & 0x7FFFFFFF);
|
||||
const LineSegments* geom1 = scene->get<LineSegments>(geomIDs[1]);
|
||||
const LineSegments* geom2 = scene->get<LineSegments>(geomIDs[2]);
|
||||
const LineSegments* geom3 = scene->get<LineSegments>(geomIDs[3]);
|
||||
const LineSegments* geom0 = scene->get<LineSegments>(geomID(0));
|
||||
const LineSegments* geom1 = scene->get<LineSegments>(geomID(1));
|
||||
const LineSegments* geom2 = scene->get<LineSegments>(geomID(2));
|
||||
const LineSegments* geom3 = scene->get<LineSegments>(geomID(3));
|
||||
|
||||
const vfloat4 numTimeSegments(geom0->fnumTimeSegments, geom1->fnumTimeSegments, geom2->fnumTimeSegments, geom3->fnumTimeSegments);
|
||||
vfloat4 ftime;
|
||||
|
||||
@@ -26,7 +26,6 @@ namespace embree
|
||||
{
|
||||
Type ();
|
||||
size_t size(const char* This) const;
|
||||
bool last(const char* This) const;
|
||||
};
|
||||
static Type type;
|
||||
|
||||
@@ -44,49 +43,42 @@ namespace embree
|
||||
public:
|
||||
|
||||
/*! constructs a virtual object */
|
||||
Object (unsigned geomID, unsigned primID, bool last)
|
||||
: _geomID(geomID | (unsigned(last) << 31)), _primID(primID) {}
|
||||
Object (unsigned geomID, unsigned primID)
|
||||
: _geomID(geomID), _primID(primID) {}
|
||||
|
||||
/*! checks if this is the last primitive */
|
||||
__forceinline unsigned last() const {
|
||||
return _geomID & 0x80000000;
|
||||
}
|
||||
|
||||
/*! returns geometry ID */
|
||||
__forceinline unsigned geomID() const {
|
||||
return _geomID & 0x7FFFFFFF;
|
||||
return _geomID;
|
||||
}
|
||||
|
||||
/*! returns primitive ID */
|
||||
__forceinline unsigned primID() const {
|
||||
return _primID;
|
||||
}
|
||||
|
||||
/*! fill triangle from triangle list */
|
||||
__forceinline void fill(const PrimRef* prims, size_t& i, size_t end, Scene* scene, bool last)
|
||||
__forceinline void fill(const PrimRef* prims, size_t& i, size_t end, Scene* scene)
|
||||
{
|
||||
const PrimRef& prim = prims[i]; i++;
|
||||
new (this) Object(prim.geomID(), prim.primID(),last);
|
||||
new (this) Object(prim.geomID(), prim.primID());
|
||||
}
|
||||
|
||||
/*! fill triangle from triangle list */
|
||||
__forceinline LBBox3fa fillMB(const PrimRef* prims, size_t& i, size_t end, Scene* scene, size_t itime, bool last)
|
||||
__forceinline LBBox3fa fillMB(const PrimRef* prims, size_t& i, size_t end, Scene* scene, size_t itime)
|
||||
{
|
||||
const PrimRef& prim = prims[i]; i++;
|
||||
const unsigned geomID = prim.geomID();
|
||||
const unsigned primID = prim.primID();
|
||||
new (this) Object(geomID, primID,last);
|
||||
new (this) Object(geomID, primID);
|
||||
AccelSet* accel = (AccelSet*) scene->get(geomID);
|
||||
return accel->linearBounds(primID,itime);
|
||||
}
|
||||
|
||||
/*! fill triangle from triangle list */
|
||||
__forceinline LBBox3fa fillMB(const PrimRefMB* prims, size_t& i, size_t end, Scene* scene, const BBox1f time_range, bool last)
|
||||
__forceinline LBBox3fa fillMB(const PrimRefMB* prims, size_t& i, size_t end, Scene* scene, const BBox1f time_range)
|
||||
{
|
||||
const PrimRefMB& prim = prims[i]; i++;
|
||||
const unsigned geomID = prim.geomID();
|
||||
const unsigned primID = prim.primID();
|
||||
new (this) Object(geomID, primID,last);
|
||||
new (this) Object(geomID, primID);
|
||||
AccelSet* accel = (AccelSet*) scene->get(geomID);
|
||||
return accel->linearBounds(primID,time_range);
|
||||
}
|
||||
|
||||
@@ -38,10 +38,6 @@ namespace embree
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool Bezier1v::Type::last(const char* This) const {
|
||||
return ((Bezier1v*)This)->last();
|
||||
}
|
||||
|
||||
Bezier1v::Type Bezier1v::type;
|
||||
|
||||
/********************** Bezier1i **************************/
|
||||
@@ -53,10 +49,6 @@ namespace embree
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool Bezier1i::Type::last(const char* This) const {
|
||||
return ((Bezier1i*)This)->last();
|
||||
}
|
||||
|
||||
Bezier1i::Type Bezier1i::type;
|
||||
|
||||
/********************** Line4i **************************/
|
||||
@@ -70,11 +62,6 @@ namespace embree
|
||||
return ((Line4i*)This)->size();
|
||||
}
|
||||
|
||||
template<>
|
||||
bool Line4i::Type::last(const char* This) const {
|
||||
return ((Line4i*)This)->last();
|
||||
}
|
||||
|
||||
/********************** Triangle4 **************************/
|
||||
|
||||
template<>
|
||||
@@ -86,11 +73,6 @@ namespace embree
|
||||
return ((Triangle4*)This)->size();
|
||||
}
|
||||
|
||||
template<>
|
||||
bool Triangle4::Type::last(const char* This) const {
|
||||
return ((Triangle4*)This)->last();
|
||||
}
|
||||
|
||||
/********************** Triangle4v **************************/
|
||||
|
||||
template<>
|
||||
@@ -102,11 +84,6 @@ namespace embree
|
||||
return ((Triangle4v*)This)->size();
|
||||
}
|
||||
|
||||
template<>
|
||||
bool Triangle4v::Type::last(const char* This) const {
|
||||
return ((Triangle4v*)This)->last();
|
||||
}
|
||||
|
||||
/********************** Triangle4i **************************/
|
||||
|
||||
template<>
|
||||
@@ -118,11 +95,6 @@ namespace embree
|
||||
return ((Triangle4i*)This)->size();
|
||||
}
|
||||
|
||||
template<>
|
||||
bool Triangle4i::Type::last(const char* This) const {
|
||||
return ((Triangle4i*)This)->last();
|
||||
}
|
||||
|
||||
/********************** Triangle4vMB **************************/
|
||||
|
||||
template<>
|
||||
@@ -134,11 +106,6 @@ namespace embree
|
||||
return ((Triangle4vMB*)This)->size();
|
||||
}
|
||||
|
||||
template<>
|
||||
bool Triangle4vMB::Type::last(const char* This) const {
|
||||
return ((Triangle4vMB*)This)->last();
|
||||
}
|
||||
|
||||
/********************** Quad4v **************************/
|
||||
|
||||
template<>
|
||||
@@ -150,11 +117,6 @@ namespace embree
|
||||
return ((Quad4v*)This)->size();
|
||||
}
|
||||
|
||||
template<>
|
||||
bool Quad4v::Type::last(const char* This) const {
|
||||
return ((Quad4v*)This)->last();
|
||||
}
|
||||
|
||||
/********************** Quad4i **************************/
|
||||
|
||||
template<>
|
||||
@@ -166,11 +128,6 @@ namespace embree
|
||||
return ((Quad4i*)This)->size();
|
||||
}
|
||||
|
||||
template<>
|
||||
bool Quad4i::Type::last(const char* This) const {
|
||||
return ((Quad4i*)This)->last();
|
||||
}
|
||||
|
||||
/********************** SubdivPatch1 **************************/
|
||||
|
||||
SubdivPatch1Cached::Type::Type ()
|
||||
@@ -180,10 +137,6 @@ namespace embree
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool SubdivPatch1Cached::Type::last(const char* This) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
SubdivPatch1Cached::Type SubdivPatch1Cached::type;
|
||||
|
||||
/********************** SubdivPatch1Cached **************************/
|
||||
@@ -195,10 +148,6 @@ namespace embree
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool SubdivPatch1Cached::TypeCached::last(const char* This) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
SubdivPatch1Cached::TypeCached SubdivPatch1Cached::type_cached;
|
||||
|
||||
/********************** Virtual Object **************************/
|
||||
@@ -210,9 +159,5 @@ namespace embree
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool Object::Type::last(const char* This) const {
|
||||
return ((Object*)This)->last();
|
||||
}
|
||||
|
||||
Object::Type Object::type;
|
||||
}
|
||||
|
||||
@@ -33,9 +33,6 @@ namespace embree
|
||||
/*! Returns the number of stored primitives in a block. */
|
||||
virtual size_t size(const char* This) const = 0;
|
||||
|
||||
/*! Returns if this is the last block in the leaf list. */
|
||||
virtual bool last(const char* This) const = 0;
|
||||
|
||||
public:
|
||||
std::string name; //!< name of this primitive type
|
||||
size_t bytes; //!< number of bytes of the triangle data
|
||||
|
||||
+22
-33
@@ -30,7 +30,6 @@ namespace embree
|
||||
{
|
||||
Type();
|
||||
size_t size(const char* This) const;
|
||||
bool last(const char* This) const;
|
||||
};
|
||||
static Type type;
|
||||
|
||||
@@ -56,12 +55,8 @@ namespace embree
|
||||
const vint<M>& v2,
|
||||
const vint<M>& v3,
|
||||
const vint<M>& geomIDs,
|
||||
const vint<M>& primIDs,
|
||||
const bool last)
|
||||
: v0(v0),v1(v1), v2(v2), v3(v3), geomIDs(geomIDs), primIDs(primIDs)
|
||||
{
|
||||
this->geomIDs[0] |= unsigned(last) << 31;
|
||||
}
|
||||
const vint<M>& primIDs)
|
||||
: v0(v0),v1(v1), v2(v2), v3(v3), geomIDs(geomIDs), primIDs(primIDs) {}
|
||||
|
||||
/* Returns a mask that tells which quads are valid */
|
||||
__forceinline vbool<M> valid() const { return primIDs != vint<M>(-1); }
|
||||
@@ -72,16 +67,10 @@ namespace embree
|
||||
/* Returns the number of stored quads */
|
||||
__forceinline size_t size() const { return __bsf(~movemask(valid())); }
|
||||
|
||||
/*! checks if this is the last primitive */
|
||||
__forceinline unsigned last() const { return geomIDs[0] & 0x80000000; }
|
||||
|
||||
/* Returns the geometry IDs */
|
||||
__forceinline vint<M>& geomID() { return geomIDs; }
|
||||
__forceinline const vint<M>& geomID() const { return geomIDs; }
|
||||
__forceinline int geomID(const size_t i) const {
|
||||
assert(i<M);
|
||||
return geomIDs[i] & 0x7FFFFFFF;
|
||||
}
|
||||
__forceinline int geomID(const size_t i) const { assert(i<M); assert(geomIDs[i] != -1); return geomIDs[i]; }
|
||||
|
||||
/* Returns the primitive IDs */
|
||||
__forceinline vint<M>& primID() { return primIDs; }
|
||||
@@ -234,7 +223,7 @@ namespace embree
|
||||
|
||||
/* Fill quad from quad list */
|
||||
template<typename PrimRefT>
|
||||
__forceinline void fill(const PrimRefT* prims, size_t& begin, size_t end, Scene* scene, bool last)
|
||||
__forceinline void fill(const PrimRefT* prims, size_t& begin, size_t end, Scene* scene)
|
||||
{
|
||||
vint<M> geomID = -1, primID = -1;
|
||||
vint<M> v0 = zero, v1 = zero, v2 = zero, v3 = zero;
|
||||
@@ -267,23 +256,23 @@ namespace embree
|
||||
if (begin<end) prim = &prims[begin];
|
||||
}
|
||||
|
||||
new (this) QuadMi(v0,v1,v2,v3,geomID,primID,last); // FIXME: use non temporal store
|
||||
new (this) QuadMi(v0,v1,v2,v3,geomID,primID); // FIXME: use non temporal store
|
||||
}
|
||||
|
||||
__forceinline LBBox3fa fillMB(const PrimRef* prims, size_t& begin, size_t end, Scene* scene, size_t itime, bool last)
|
||||
__forceinline LBBox3fa fillMB(const PrimRef* prims, size_t& begin, size_t end, Scene* scene, size_t itime)
|
||||
{
|
||||
fill(prims, begin, end, scene, last);
|
||||
fill(prims, begin, end, scene);
|
||||
return linearBounds(scene, itime);
|
||||
}
|
||||
|
||||
__forceinline LBBox3fa fillMB(const PrimRefMB* prims, size_t& begin, size_t end, Scene* scene, const BBox1f time_range, bool last)
|
||||
__forceinline LBBox3fa fillMB(const PrimRefMB* prims, size_t& begin, size_t end, Scene* scene, const BBox1f time_range)
|
||||
{
|
||||
fill(prims, begin, end, scene, last);
|
||||
fill(prims, begin, end, scene);
|
||||
return linearBounds(scene, time_range);
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& cout, const QuadMi& quad) {
|
||||
return cout << "QuadMi<" << M << ">( v0 = " << quad.v0 << ", v1 = " << quad.v1 << ", v2 = " << quad.v2 << ", v3 = " << quad.v3 << ", geomID = " << (quad.geomIDs & 0x7FFFFFFF) << ", primID = " << quad.primIDs << " )";
|
||||
return cout << "QuadMi<" << M << ">( v0 = " << quad.v0 << ", v1 = " << quad.v1 << ", v2 = " << quad.v2 << ", v3 = " << quad.v3 << ", geomID = " << quad.geomIDs << ", primID = " << quad.primIDs << " )";
|
||||
}
|
||||
|
||||
/* Updates the primitive */
|
||||
@@ -324,10 +313,10 @@ namespace embree
|
||||
{
|
||||
prefetchL1(((char*)this)+0*64);
|
||||
prefetchL1(((char*)this)+1*64);
|
||||
const int* vertices0 = scene->vertices[geomIDs[0] & 0x7FFFFFFF];
|
||||
const int* vertices1 = scene->vertices[geomIDs[1]];
|
||||
const int* vertices2 = scene->vertices[geomIDs[2]];
|
||||
const int* vertices3 = scene->vertices[geomIDs[3]];
|
||||
const int* vertices0 = scene->vertices[geomID(0)];
|
||||
const int* vertices1 = scene->vertices[geomID(1)];
|
||||
const int* vertices2 = scene->vertices[geomID(2)];
|
||||
const int* vertices3 = scene->vertices[geomID(3)];
|
||||
const vfloat4 a0 = vfloat4::loadu(vertices0 + v0[0]);
|
||||
const vfloat4 a1 = vfloat4::loadu(vertices1 + v0[1]);
|
||||
const vfloat4 a2 = vfloat4::loadu(vertices2 + v0[2]);
|
||||
@@ -359,10 +348,10 @@ namespace embree
|
||||
const Scene *const scene) const // FIXME: why do we have this special path here and not for triangles?
|
||||
{
|
||||
const vint16 perm(0,4,8,12,1,5,9,13,2,6,10,14,3,7,11,15);
|
||||
const int* vertices0 = scene->vertices[geomIDs[0] & 0x7FFFFFFF];
|
||||
const int* vertices1 = scene->vertices[geomIDs[1]];
|
||||
const int* vertices2 = scene->vertices[geomIDs[2]];
|
||||
const int* vertices3 = scene->vertices[geomIDs[3]];
|
||||
const int* vertices0 = scene->vertices[geomID(0)];
|
||||
const int* vertices1 = scene->vertices[geomID(1)];
|
||||
const int* vertices2 = scene->vertices[geomID(2)];
|
||||
const int* vertices3 = scene->vertices[geomID(3)];
|
||||
|
||||
const vfloat4 a0 = vfloat4::loadu(vertices0 + v0[0]);
|
||||
const vfloat4 a1 = vfloat4::loadu(vertices1 + v0[1]);
|
||||
@@ -451,10 +440,10 @@ namespace embree
|
||||
const Scene *const scene,
|
||||
const float time) const
|
||||
{
|
||||
const QuadMesh* mesh0 = scene->get<QuadMesh>(geomIDs[0] & 0x7FFFFFFF);
|
||||
const QuadMesh* mesh1 = scene->get<QuadMesh>(geomIDs[1]);
|
||||
const QuadMesh* mesh2 = scene->get<QuadMesh>(geomIDs[2]);
|
||||
const QuadMesh* mesh3 = scene->get<QuadMesh>(geomIDs[3]);
|
||||
const QuadMesh* mesh0 = scene->get<QuadMesh>(geomID(0));
|
||||
const QuadMesh* mesh1 = scene->get<QuadMesh>(geomID(1));
|
||||
const QuadMesh* mesh2 = scene->get<QuadMesh>(geomID(2));
|
||||
const QuadMesh* mesh3 = scene->get<QuadMesh>(geomID(3));
|
||||
|
||||
const vfloat4 numTimeSegments(mesh0->fnumTimeSegments, mesh1->fnumTimeSegments, mesh2->fnumTimeSegments, mesh3->fnumTimeSegments);
|
||||
vfloat4 ftime;
|
||||
|
||||
@@ -29,7 +29,6 @@ namespace embree
|
||||
{
|
||||
Type();
|
||||
size_t size(const char* This) const;
|
||||
bool last(const char* This) const;
|
||||
};
|
||||
static Type type;
|
||||
|
||||
@@ -47,11 +46,8 @@ namespace embree
|
||||
__forceinline QuadMv() {}
|
||||
|
||||
/* Construction from vertices and IDs */
|
||||
__forceinline QuadMv(const Vec3vf<M>& v0, const Vec3vf<M>& v1, const Vec3vf<M>& v2, const Vec3vf<M>& v3, const vint<M>& geomIDs, const vint<M>& primIDs, const bool last)
|
||||
: v0(v0), v1(v1), v2(v2), v3(v3), geomIDs(geomIDs), primIDs(primIDs)
|
||||
{
|
||||
this->geomIDs[0] |= unsigned(last) << 31;
|
||||
}
|
||||
__forceinline QuadMv(const Vec3vf<M>& v0, const Vec3vf<M>& v1, const Vec3vf<M>& v2, const Vec3vf<M>& v3, const vint<M>& geomIDs, const vint<M>& primIDs)
|
||||
: v0(v0), v1(v1), v2(v2), v3(v3), geomIDs(geomIDs), primIDs(primIDs) {}
|
||||
|
||||
/* Returns a mask that tells which quads are valid */
|
||||
__forceinline vbool<M> valid() const { return geomIDs != vint<M>(-1); }
|
||||
@@ -62,13 +58,10 @@ namespace embree
|
||||
/* Returns the number of stored quads */
|
||||
__forceinline size_t size() const { return __bsf(~movemask(valid())); }
|
||||
|
||||
/*! checks if this is the last primitive */
|
||||
__forceinline unsigned last() const { return geomIDs[0] & 0x80000000; }
|
||||
|
||||
/* Returns the geometry IDs */
|
||||
__forceinline vint<M>& geomID() { return geomIDs; }
|
||||
__forceinline const vint<M>& geomID() const { return geomIDs; }
|
||||
__forceinline int geomID(const size_t i) const { assert(i<M); return geomIDs[i] & 0x7FFFFFFF; }
|
||||
__forceinline int geomID(const size_t i) const { assert(i<M); return geomIDs[i]; }
|
||||
|
||||
/* Returns the primitive IDs */
|
||||
__forceinline vint<M> primID() { return primIDs; }
|
||||
@@ -111,7 +104,7 @@ namespace embree
|
||||
}
|
||||
|
||||
/* Fill quad from quad list */
|
||||
__forceinline void fill(const PrimRef* prims, size_t& begin, size_t end, Scene* scene, bool last)
|
||||
__forceinline void fill(const PrimRef* prims, size_t& begin, size_t end, Scene* scene)
|
||||
{
|
||||
vint<M> vgeomID = -1, vprimID = -1;
|
||||
Vec3vf<M> v0 = zero, v1 = zero, v2 = zero, v3 = zero;
|
||||
@@ -134,7 +127,7 @@ namespace embree
|
||||
v2.x[i] = p2.x; v2.y[i] = p2.y; v2.z[i] = p2.z;
|
||||
v3.x[i] = p3.x; v3.y[i] = p3.y; v3.z[i] = p3.z;
|
||||
}
|
||||
QuadMv::store_nt(this,QuadMv(v0,v1,v2,v3,vgeomID,vprimID,last));
|
||||
QuadMv::store_nt(this,QuadMv(v0,v1,v2,v3,vgeomID,vprimID));
|
||||
}
|
||||
|
||||
/* Updates the primitive */
|
||||
@@ -147,7 +140,7 @@ namespace embree
|
||||
for (size_t i=0; i<M; i++)
|
||||
{
|
||||
if (primID(i) == -1) break;
|
||||
const unsigned geomId = geomIDs[i]; // copies last bit
|
||||
const unsigned geomId = geomID(i);
|
||||
const unsigned primId = primID(i);
|
||||
const QuadMesh::Quad& quad = mesh->quad(primId);
|
||||
const Vec3fa p0 = mesh->vertex(quad.v[0]);
|
||||
@@ -162,7 +155,7 @@ namespace embree
|
||||
v2.x[i] = p2.x; v2.y[i] = p2.y; v2.z[i] = p2.z;
|
||||
v3.x[i] = p3.x; v3.y[i] = p3.y; v3.z[i] = p3.z;
|
||||
}
|
||||
QuadMv::store_nt(this,QuadMv(v0,v1,v2,v3,vgeomID,vprimID,false));
|
||||
new (this) QuadMv(v0,v1,v2,v3,vgeomID,vprimID);
|
||||
return bounds;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@ namespace embree
|
||||
{
|
||||
Type ();
|
||||
size_t size(const char* This) const;
|
||||
bool last(const char* This) const;
|
||||
};
|
||||
|
||||
static Type type;
|
||||
@@ -37,7 +36,6 @@ namespace embree
|
||||
{
|
||||
TypeCached ();
|
||||
size_t size(const char* This) const;
|
||||
bool last(const char* This) const;
|
||||
};
|
||||
|
||||
static TypeCached type_cached;
|
||||
|
||||
@@ -31,7 +31,6 @@ namespace embree
|
||||
{
|
||||
Type();
|
||||
size_t size(const char* This) const;
|
||||
bool last(const char* This) const;
|
||||
};
|
||||
static Type type;
|
||||
|
||||
@@ -49,11 +48,8 @@ namespace embree
|
||||
__forceinline TriangleM() {}
|
||||
|
||||
/* Construction from vertices and IDs */
|
||||
__forceinline TriangleM(const Vec3vf<M>& v0, const Vec3vf<M>& v1, const Vec3vf<M>& v2, const vint<M>& geomIDs, const vint<M>& primIDs, const bool last)
|
||||
: v0(v0), e1(v0-v1), e2(v2-v0), geomIDs(geomIDs), primIDs(primIDs)
|
||||
{
|
||||
this->geomIDs[0] |= unsigned(last) << 31;
|
||||
}
|
||||
__forceinline TriangleM(const Vec3vf<M>& v0, const Vec3vf<M>& v1, const Vec3vf<M>& v2, const vint<M>& geomIDs, const vint<M>& primIDs)
|
||||
: v0(v0), e1(v0-v1), e2(v2-v0), geomIDs(geomIDs), primIDs(primIDs) {}
|
||||
|
||||
/* Returns a mask that tells which triangles are valid */
|
||||
__forceinline vbool<M> valid() const { return geomIDs != vint<M>(-1); }
|
||||
@@ -64,13 +60,10 @@ namespace embree
|
||||
/* Returns the number of stored triangles */
|
||||
__forceinline size_t size() const { return __bsf(~movemask(valid())); }
|
||||
|
||||
/*! checks if this is the last primitive */
|
||||
__forceinline unsigned last() const { return geomIDs[0] & 0x80000000; }
|
||||
|
||||
/* Returns the geometry IDs */
|
||||
__forceinline vint<M>& geomID() { return geomIDs; }
|
||||
__forceinline const vint<M>& geomID() const { return geomIDs; }
|
||||
__forceinline int geomID(const size_t i) const { assert(i<M); return geomIDs[i] & 0x7FFFFFFF; }
|
||||
__forceinline int geomID(const size_t i) const { assert(i<M); return geomIDs[i]; }
|
||||
|
||||
/* Returns the primitive IDs */
|
||||
__forceinline vint<M>& primID() { return primIDs; }
|
||||
@@ -113,7 +106,7 @@ namespace embree
|
||||
}
|
||||
|
||||
/* Fill triangle from triangle list */
|
||||
__forceinline void fill(const PrimRef* prims, size_t& begin, size_t end, Scene* scene, bool last)
|
||||
__forceinline void fill(const PrimRef* prims, size_t& begin, size_t end, Scene* scene)
|
||||
{
|
||||
vint<M> vgeomID = -1, vprimID = -1;
|
||||
Vec3vf<M> v0 = zero, v1 = zero, v2 = zero;
|
||||
@@ -134,7 +127,7 @@ namespace embree
|
||||
v1.x[i] = p1.x; v1.y[i] = p1.y; v1.z[i] = p1.z;
|
||||
v2.x[i] = p2.x; v2.y[i] = p2.y; v2.z[i] = p2.z;
|
||||
}
|
||||
TriangleM::store_nt(this,TriangleM(v0,v1,v2,vgeomID,vprimID,last));
|
||||
TriangleM::store_nt(this,TriangleM(v0,v1,v2,vgeomID,vprimID));
|
||||
}
|
||||
|
||||
/* Updates the primitive */
|
||||
@@ -144,10 +137,10 @@ namespace embree
|
||||
vint<M> vgeomID = -1, vprimID = -1;
|
||||
Vec3vf<M> v0 = zero, v1 = zero, v2 = zero;
|
||||
|
||||
for (size_t i=0; i<M; i++)
|
||||
for (size_t i=0; i<M; i++)
|
||||
{
|
||||
if (unlikely(!valid(i))) break;
|
||||
const unsigned geomId = geomIDs[i]; // copies last bit
|
||||
if (unlikely(geomID(i) == -1)) break;
|
||||
const unsigned geomId = geomID(i);
|
||||
const unsigned primId = primID(i);
|
||||
const TriangleMesh::Triangle& tri = mesh->triangle(primId);
|
||||
const Vec3fa p0 = mesh->vertex(tri.v[0]);
|
||||
@@ -160,7 +153,7 @@ namespace embree
|
||||
v1.x[i] = p1.x; v1.y[i] = p1.y; v1.z[i] = p1.z;
|
||||
v2.x[i] = p2.x; v2.y[i] = p2.y; v2.z[i] = p2.z;
|
||||
}
|
||||
TriangleM::store_nt(this,TriangleM(v0,v1,v2,vgeomID,vprimID,false));
|
||||
TriangleM::store_nt(this,TriangleM(v0,v1,v2,vgeomID,vprimID));
|
||||
return bounds;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,6 @@ namespace embree
|
||||
{
|
||||
Type();
|
||||
size_t size(const char* This) const;
|
||||
bool last(const char* This) const;
|
||||
};
|
||||
static Type type;
|
||||
|
||||
@@ -55,12 +54,8 @@ namespace embree
|
||||
const vint<M>& v1,
|
||||
const vint<M>& v2,
|
||||
const vint<M>& geomIDs,
|
||||
const vint<M>& primIDs,
|
||||
const bool last)
|
||||
: v0(v0), v1(v1), v2(v2), geomIDs(geomIDs), primIDs(primIDs)
|
||||
{
|
||||
this->geomIDs[0] |= unsigned(last) << 31;
|
||||
}
|
||||
const vint<M>& primIDs)
|
||||
: v0(v0), v1(v1), v2(v2), geomIDs(geomIDs), primIDs(primIDs) {}
|
||||
|
||||
/* Returns a mask that tells which triangles are valid */
|
||||
__forceinline vbool<M> valid() const { return primIDs != vint<M>(-1); }
|
||||
@@ -71,12 +66,9 @@ namespace embree
|
||||
/* Returns the number of stored triangles */
|
||||
__forceinline size_t size() const { return __bsf(~movemask(valid())); }
|
||||
|
||||
/*! checks if this is the last primitive */
|
||||
__forceinline unsigned last() const { return geomIDs[0] & 0x80000000; }
|
||||
|
||||
/* Returns the geometry IDs */
|
||||
__forceinline vint<M> geomID() const { return geomIDs; }
|
||||
__forceinline int geomID(const size_t i) const { assert(i<M); return geomIDs[i] & 0x7FFFFFFF; }
|
||||
__forceinline int geomID(const size_t i) const { assert(i<M); return geomIDs[i]; }
|
||||
|
||||
/* Returns the primitive IDs */
|
||||
__forceinline vint<M> primID() const { return primIDs; }
|
||||
@@ -218,7 +210,7 @@ namespace embree
|
||||
|
||||
/* Fill triangle from triangle list */
|
||||
template<typename PrimRefT>
|
||||
__forceinline void fill(const PrimRefT* prims, size_t& begin, size_t end, Scene* scene, bool last)
|
||||
__forceinline void fill(const PrimRefT* prims, size_t& begin, size_t end, Scene* scene)
|
||||
{
|
||||
vint<M> geomID = -1, primID = -1;
|
||||
vint<M> v0 = zero, v1 = zero, v2 = zero;
|
||||
@@ -249,18 +241,18 @@ namespace embree
|
||||
if (begin<end) prim = &prims[begin];
|
||||
}
|
||||
|
||||
new (this) TriangleMi(v0,v1,v2,geomID,primID,last); // FIXME: use non temporal store
|
||||
new (this) TriangleMi(v0,v1,v2,geomID,primID); // FIXME: use non temporal store
|
||||
}
|
||||
|
||||
__forceinline LBBox3fa fillMB(const PrimRef* prims, size_t& begin, size_t end, Scene* scene, size_t itime, bool last)
|
||||
__forceinline LBBox3fa fillMB(const PrimRef* prims, size_t& begin, size_t end, Scene* scene, size_t itime)
|
||||
{
|
||||
fill(prims, begin, end, scene, last);
|
||||
fill(prims, begin, end, scene);
|
||||
return linearBounds(scene, itime);
|
||||
}
|
||||
|
||||
__forceinline LBBox3fa fillMB(const PrimRefMB* prims, size_t& begin, size_t end, Scene* scene, const BBox1f time_range, bool last)
|
||||
__forceinline LBBox3fa fillMB(const PrimRefMB* prims, size_t& begin, size_t end, Scene* scene, const BBox1f time_range)
|
||||
{
|
||||
fill(prims, begin, end, scene, last);
|
||||
fill(prims, begin, end, scene);
|
||||
return linearBounds(scene, time_range);
|
||||
}
|
||||
|
||||
@@ -296,10 +288,10 @@ namespace embree
|
||||
Vec3vf4& p2,
|
||||
const Scene* const scene) const
|
||||
{
|
||||
const int* vertices0 = scene->vertices[geomIDs[0] & 0x7FFFFFFF];
|
||||
const int* vertices1 = scene->vertices[geomIDs[1]];
|
||||
const int* vertices2 = scene->vertices[geomIDs[2]];
|
||||
const int* vertices3 = scene->vertices[geomIDs[3]];
|
||||
const int* vertices0 = scene->vertices[geomID(0)];
|
||||
const int* vertices1 = scene->vertices[geomID(1)];
|
||||
const int* vertices2 = scene->vertices[geomID(2)];
|
||||
const int* vertices3 = scene->vertices[geomID(3)];
|
||||
const vfloat4 a0 = vfloat4::loadu(vertices0 + v0[0]);
|
||||
const vfloat4 a1 = vfloat4::loadu(vertices1 + v0[1]);
|
||||
const vfloat4 a2 = vfloat4::loadu(vertices2 + v0[2]);
|
||||
@@ -355,10 +347,10 @@ namespace embree
|
||||
const Scene *const scene,
|
||||
const float time) const
|
||||
{
|
||||
const TriangleMesh* mesh0 = scene->get<TriangleMesh>(geomIDs[0] & 0x7FFFFFFF);
|
||||
const TriangleMesh* mesh1 = scene->get<TriangleMesh>(geomIDs[1]);
|
||||
const TriangleMesh* mesh2 = scene->get<TriangleMesh>(geomIDs[2]);
|
||||
const TriangleMesh* mesh3 = scene->get<TriangleMesh>(geomIDs[3]);
|
||||
const TriangleMesh* mesh0 = scene->get<TriangleMesh>(geomID(0));
|
||||
const TriangleMesh* mesh1 = scene->get<TriangleMesh>(geomID(1));
|
||||
const TriangleMesh* mesh2 = scene->get<TriangleMesh>(geomID(2));
|
||||
const TriangleMesh* mesh3 = scene->get<TriangleMesh>(geomID(3));
|
||||
|
||||
const vfloat4 numTimeSegments(mesh0->fnumTimeSegments, mesh1->fnumTimeSegments, mesh2->fnumTimeSegments, mesh3->fnumTimeSegments);
|
||||
vfloat4 ftime;
|
||||
|
||||
@@ -29,7 +29,6 @@ namespace embree
|
||||
{
|
||||
Type();
|
||||
size_t size(const char* This) const;
|
||||
bool last(const char* This) const;
|
||||
};
|
||||
static Type type;
|
||||
|
||||
@@ -47,11 +46,8 @@ namespace embree
|
||||
__forceinline TriangleMv() {}
|
||||
|
||||
/* Construction from vertices and IDs */
|
||||
__forceinline TriangleMv(const Vec3vf<M>& v0, const Vec3vf<M>& v1, const Vec3vf<M>& v2, const vint<M>& geomIDs, const vint<M>& primIDs, const bool last)
|
||||
: v0(v0), v1(v1), v2(v2), geomIDs(geomIDs), primIDs(primIDs)
|
||||
{
|
||||
this->geomIDs[0] |= unsigned(last) << 31;
|
||||
}
|
||||
__forceinline TriangleMv(const Vec3vf<M>& v0, const Vec3vf<M>& v1, const Vec3vf<M>& v2, const vint<M>& geomIDs, const vint<M>& primIDs)
|
||||
: v0(v0), v1(v1), v2(v2), geomIDs(geomIDs), primIDs(primIDs) {}
|
||||
|
||||
/* Returns a mask that tells which triangles are valid */
|
||||
__forceinline vbool<M> valid() const { return geomIDs != vint<M>(-1); }
|
||||
@@ -62,13 +58,10 @@ namespace embree
|
||||
/* Returns the number of stored triangles */
|
||||
__forceinline size_t size() const { return __bsf(~movemask(valid())); }
|
||||
|
||||
/*! checks if this is the last primitive */
|
||||
__forceinline unsigned last() const { return geomIDs[0] & 0x80000000; }
|
||||
|
||||
/* Returns the geometry IDs */
|
||||
__forceinline vint<M>& geomID() { return geomIDs; }
|
||||
__forceinline const vint<M>& geomID() const { return geomIDs; }
|
||||
__forceinline int geomID(const size_t i) const { assert(i<M); return geomIDs[i] & 0x7FFFFFFF; }
|
||||
__forceinline int geomID(const size_t i) const { assert(i<M); return geomIDs[i]; }
|
||||
|
||||
/* Returns the primitive IDs */
|
||||
__forceinline vint<M>& primID() { return primIDs; }
|
||||
@@ -108,7 +101,7 @@ namespace embree
|
||||
}
|
||||
|
||||
/* Fill triangle from triangle list */
|
||||
__forceinline void fill(const PrimRef* prims, size_t& begin, size_t end, Scene* scene, bool last)
|
||||
__forceinline void fill(const PrimRef* prims, size_t& begin, size_t end, Scene* scene)
|
||||
{
|
||||
vint<M> vgeomID = -1, vprimID = -1;
|
||||
Vec3vf<M> v0 = zero, v1 = zero, v2 = zero;
|
||||
@@ -129,7 +122,7 @@ namespace embree
|
||||
v1.x[i] = p1.x; v1.y[i] = p1.y; v1.z[i] = p1.z;
|
||||
v2.x[i] = p2.x; v2.y[i] = p2.y; v2.z[i] = p2.z;
|
||||
}
|
||||
TriangleMv::store_nt(this,TriangleMv(v0,v1,v2,vgeomID,vprimID,last));
|
||||
TriangleMv::store_nt(this,TriangleMv(v0,v1,v2,vgeomID,vprimID));
|
||||
}
|
||||
|
||||
/* Updates the primitive */
|
||||
@@ -142,7 +135,7 @@ namespace embree
|
||||
for (size_t i=0; i<M; i++)
|
||||
{
|
||||
if (primID(i) == -1) break;
|
||||
const unsigned geomId = geomIDs[i]; // copies last bit
|
||||
const unsigned geomId = geomID(i);
|
||||
const unsigned primId = primID(i);
|
||||
const TriangleMesh::Triangle& tri = mesh->triangle(primId);
|
||||
const Vec3fa p0 = mesh->vertex(tri.v[0]);
|
||||
@@ -155,7 +148,7 @@ namespace embree
|
||||
v1.x[i] = p1.x; v1.y[i] = p1.y; v1.z[i] = p1.z;
|
||||
v2.x[i] = p2.x; v2.y[i] = p2.y; v2.z[i] = p2.z;
|
||||
}
|
||||
new (this) TriangleMv(v0,v1,v2,vgeomID,vprimID,false);
|
||||
new (this) TriangleMv(v0,v1,v2,vgeomID,vprimID);
|
||||
return bounds;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,6 @@ namespace embree
|
||||
{
|
||||
Type();
|
||||
size_t size(const char* This) const;
|
||||
bool last(const char* This) const;
|
||||
};
|
||||
|
||||
static Type type;
|
||||
@@ -54,12 +53,8 @@ namespace embree
|
||||
__forceinline TriangleMvMB(const Vec3vf<M>& a0, const Vec3vf<M>& a1,
|
||||
const Vec3vf<M>& b0, const Vec3vf<M>& b1,
|
||||
const Vec3vf<M>& c0, const Vec3vf<M>& c1,
|
||||
const vint<M>& geomIDs, const vint<M>& primIDs,
|
||||
const bool last)
|
||||
: v0(a0), v1(b0), v2(c0), dv0(a1-a0), dv1(b1-b0), dv2(c1-c0), geomIDs(geomIDs), primIDs(primIDs)
|
||||
{
|
||||
this->geomIDs[0] |= unsigned(last) << 31;
|
||||
}
|
||||
const vint<M>& geomIDs, const vint<M>& primIDs)
|
||||
: v0(a0), v1(b0), v2(c0), dv0(a1-a0), dv1(b1-b0), dv2(c1-c0), geomIDs(geomIDs), primIDs(primIDs) {}
|
||||
|
||||
/* Returns a mask that tells which triangles are valid */
|
||||
__forceinline vbool<M> valid() const { return geomIDs != vint<M>(-1); }
|
||||
@@ -70,13 +65,10 @@ namespace embree
|
||||
/* Returns the number of stored triangles */
|
||||
__forceinline size_t size() const { return __bsf(~movemask(valid())); }
|
||||
|
||||
/*! checks if this is the last primitive */
|
||||
__forceinline unsigned last() const { return geomIDs[0] & 0x80000000; }
|
||||
|
||||
/* Returns the geometry IDs */
|
||||
__forceinline vint<M>& geomID() { return geomIDs; }
|
||||
__forceinline const vint<M>& geomID() const { return geomIDs; }
|
||||
__forceinline int geomID(const size_t i) const { assert(i<M); return geomIDs[i] & 0x7FFFFFFF; }
|
||||
__forceinline int geomID(const size_t i) const { assert(i<M); return geomIDs[i]; }
|
||||
|
||||
/* Returns the primitive IDs */
|
||||
__forceinline vint<M>& primID() { return primIDs; }
|
||||
@@ -124,7 +116,7 @@ namespace embree
|
||||
}
|
||||
|
||||
/* Fill triangle from triangle list */
|
||||
__forceinline LBBox3fa fillMB(const PrimRef* prims, size_t& begin, size_t end, Scene* scene, size_t itime, bool last)
|
||||
__forceinline LBBox3fa fillMB(const PrimRef* prims, size_t& begin, size_t end, Scene* scene, size_t itime)
|
||||
{
|
||||
vint<M> vgeomID = -1, vprimID = -1;
|
||||
Vec3vf<M> va0 = zero, vb0 = zero, vc0 = zero;
|
||||
@@ -155,12 +147,12 @@ namespace embree
|
||||
vc0.x[i] = c0.x; vc0.y[i] = c0.y; vc0.z[i] = c0.z;
|
||||
vc1.x[i] = c1.x; vc1.y[i] = c1.y; vc1.z[i] = c1.z;
|
||||
}
|
||||
new (this) TriangleMvMB(va0,va1,vb0,vb1,vc0,vc1,vgeomID,vprimID,last);
|
||||
new (this) TriangleMvMB(va0,va1,vb0,vb1,vc0,vc1,vgeomID,vprimID);
|
||||
return LBBox3fa(bounds0,bounds1);
|
||||
}
|
||||
|
||||
/* Fill triangle from triangle list */
|
||||
__forceinline LBBox3fa fillMB(const PrimRefMB* prims, size_t& begin, size_t end, Scene* scene, const BBox1f time_range, bool last)
|
||||
__forceinline LBBox3fa fillMB(const PrimRefMB* prims, size_t& begin, size_t end, Scene* scene, const BBox1f time_range)
|
||||
{
|
||||
vint<M> vgeomID = -1, vprimID = -1;
|
||||
Vec3vf<M> va0 = zero, vb0 = zero, vc0 = zero;
|
||||
@@ -198,7 +190,7 @@ namespace embree
|
||||
vc0.x[i] = c01.first .x; vc0.y[i] = c01.first .y; vc0.z[i] = c01.first .z;
|
||||
vc1.x[i] = c01.second.x; vc1.y[i] = c01.second.y; vc1.z[i] = c01.second.z;
|
||||
}
|
||||
new (this) TriangleMvMB(va0,va1,vb0,vb1,vc0,vc1,vgeomID,vprimID,last);
|
||||
new (this) TriangleMvMB(va0,va1,vb0,vb1,vc0,vc1,vgeomID,vprimID);
|
||||
return allBounds;
|
||||
}
|
||||
|
||||
|
||||
@@ -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():
|
||||
|
||||
@@ -33,7 +33,7 @@ done
|
||||
# now remove files
|
||||
echo Uninstalling Embree @EMBREE_VERSION@ ...
|
||||
for f in "${FILES[@]}"; do
|
||||
sudo rm -vd "$f"
|
||||
sudo /bin/rm -vd "$f"
|
||||
done
|
||||
|
||||
sudo pkgutil --forget com.intel.embree-@EMBREE_VERSION@
|
||||
sudo /usr/sbin/pkgutil --forget com.intel.embree-@EMBREE_VERSION@
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
# terminate if some error occurs
|
||||
set -e
|
||||
|
||||
# check version of symbols
|
||||
function check_symbols
|
||||
{
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
# terminate if some error occurs
|
||||
set -e
|
||||
|
||||
# read embree version
|
||||
#EMBREE_VERSION_MAJOR=`sed -n 's/#define __EMBREE_VERSION_MAJOR__ \(.*\)/\1/p' version.h`
|
||||
#EMBREE_VERSION_MINOR=`sed -n 's/#define __EMBREE_VERSION_MINOR__ \(.*\)/\1/p' version.h`
|
||||
|
||||
@@ -7,5 +7,9 @@ if "%build_type%" == "" (
|
||||
|
||||
cmake --build . --config %build_type% --target PACKAGE -- /m /nologo /verbosity:n
|
||||
|
||||
IF %ERRORLEVEL% NEQ 0 (
|
||||
exit /b
|
||||
)
|
||||
|
||||
@echo "<DartMeasurement name="%1" type="text/string">%1</DartMeasurement>"
|
||||
|
||||
|
||||
@@ -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 \
|
||||
|
||||
+1
-42
@@ -3,48 +3,6 @@
|
||||
setlocal
|
||||
set TBB_PATH_LOCAL=%cd%\tbb
|
||||
|
||||
mkdir -p build_win32
|
||||
cd build_win32
|
||||
del CMakeCache.txt
|
||||
del version.h
|
||||
|
||||
REM set release settings
|
||||
cmake -L ^
|
||||
-G "Visual Studio 12 2013" ^
|
||||
-T "Intel C++ Compiler 16.0" ^
|
||||
-D EMBREE_MAX_ISA=AVX512SKX ^
|
||||
-D EMBREE_TUTORIALS_IMAGE_MAGICK=OFF ^
|
||||
-D EMBREE_TUTORIALS_LIBJPEG=OFF ^
|
||||
-D EMBREE_TUTORIALS_LIBPNG=OFF ^
|
||||
-D EMBREE_TBB_ROOT=%TBB_PATH_LOCAL% ^
|
||||
..
|
||||
|
||||
REM compile
|
||||
cmake --clean-first --build . --config Release --target PREINSTALL -- /m /nologo /verbosity:n
|
||||
|
||||
REM create ZIP files
|
||||
cmake ^
|
||||
-D EMBREE_ZIP_MODE=ON ^
|
||||
-D CMAKE_INSTALL_INCLUDEDIR=include ^
|
||||
-D CMAKE_INSTALL_LIBDIR=lib ^
|
||||
-D CMAKE_INSTALL_DATAROOTDIR= ^
|
||||
-D CMAKE_INSTALL_DOCDIR=doc ^
|
||||
-D CMAKE_INSTALL_BINDIR=bin ^
|
||||
..
|
||||
cmake --build . --config Release --target PACKAGE -- /m /nologo /verbosity:n
|
||||
|
||||
REM create installers
|
||||
cmake ^
|
||||
-D EMBREE_ZIP_MODE=OFF ^
|
||||
-D CMAKE_INSTALL_INCLUDEDIR=include ^
|
||||
-D CMAKE_INSTALL_LIBDIR=lib ^
|
||||
-D CMAKE_INSTALL_DATAROOTDIR= ^
|
||||
-D CMAKE_INSTALL_DOCDIR=doc ^
|
||||
-D CMAKE_INSTALL_BINDIR=bin ^
|
||||
..
|
||||
cmake --build . --config Release --target PACKAGE -- /m /nologo /verbosity:n
|
||||
|
||||
cd ..
|
||||
mkdir build_x64
|
||||
cd build_x64
|
||||
del CMakeCache.txt # make sure to use default settings
|
||||
@@ -54,6 +12,7 @@ REM set release settings
|
||||
cmake -L ^
|
||||
-G "Visual Studio 12 2013 Win64" ^
|
||||
-T "Intel C++ Compiler 16.0" ^
|
||||
-D EMBREE_STACK_PROTECTOR=ON ^
|
||||
-D EMBREE_MAX_ISA=AVX512SKX ^
|
||||
-D EMBREE_TBB_ROOT=%TBB_PATH_LOCAL% ^
|
||||
-D ENABLE_XEON_PHI_SUPPORT=OFF ^
|
||||
|
||||
Executable
+3
@@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
echo stripping $1
|
||||
strip -x $1
|
||||
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):
|
||||
c = [] # CMake configuration
|
||||
e = [] # shell environment
|
||||
platform = config["platform"]
|
||||
build = config["build"]
|
||||
compiler = config["compiler"]
|
||||
isa = config["isa"]
|
||||
tasking = config["tasking"]
|
||||
if "intensive" in config: intensive = config["intensive"]
|
||||
else : intensive = "OFF"
|
||||
if "memcheck" in config: memcheck = config["memcheck"]
|
||||
else : memcheck = "OFF"
|
||||
if "benchmark" in config: benchmark = config["benchmark"]
|
||||
else : benchmark = "OFF"
|
||||
if "sde" in config: sde = config["sde"]
|
||||
else : sde = "OFF"
|
||||
if "test" in config: skip_testing = not config["test"]
|
||||
else : skip_testing = False
|
||||
if tasking == "INT": tasking = "INTERNAL"
|
||||
if tasking == "PPL": tasking = "PPL"
|
||||
name = "gitlab-"+platform+"-"+build+"-"+compiler+"-"+string_of_isa(isa)+"-"+tasking
|
||||
if "package" in config:
|
||||
c.append("-D EMBREE_STACK_PROTECTOR=ON")
|
||||
if config["package"] == "ZIP": name = name + "-package-zip"
|
||||
else : name = name + "-package-installer"
|
||||
|
||||
if "klocwork" in config: name = name + "-klocwork"
|
||||
ispc_ext = "-vs2013"
|
||||
if "package" in config and OS == 'linux': # we need up to date cmake for RPMs to work properly
|
||||
e.append("module load cmake")
|
||||
c.append("-D CMAKE_BUILD_TYPE="+build+"")
|
||||
if OS == "windows":
|
||||
ext = ""
|
||||
if platform == "x64":
|
||||
ext = " Win64"
|
||||
if (compiler == "V141"):
|
||||
c.append("-G \"Visual Studio 15 2017"+ext+"\"")
|
||||
c.append("-T \"V141\"")
|
||||
ispc_ext = "-vs2015"
|
||||
elif (compiler == "V140"):
|
||||
c.append("-G \"Visual Studio 14 2015"+ext+"\"")
|
||||
c.append("-T \"V140\"")
|
||||
ispc_ext = "-vs2015"
|
||||
elif (compiler == "V120"):
|
||||
c.append("-G \"Visual Studio 12 2013"+ext+"\"")
|
||||
c.append("-T \"V120\"")
|
||||
elif (compiler == "V110"):
|
||||
c.append("-G \"Visual Studio 11 2012"+ext+"\"")
|
||||
c.append("-T \"V110\"")
|
||||
elif (compiler == "ICC"):
|
||||
c.append("-G \"Visual Studio 12 2013"+ext+"\"")
|
||||
c.append("-T \"Intel C++ Compiler 17.0\"")
|
||||
elif (compiler == "ICC18"):
|
||||
c.append("-G \"Visual Studio 12 2013"+ext+"\"")
|
||||
c.append("-T \"Intel C++ Compiler 18.0\"")
|
||||
elif (compiler == "ICC17"):
|
||||
c.append("-G \"Visual Studio 12 2013"+ext+"\"")
|
||||
c.append("-T \"Intel C++ Compiler 17.0\"")
|
||||
elif (compiler == "ICC16"):
|
||||
c.append("-G \"Visual Studio 12 2013"+ext+"\"")
|
||||
c.append("-T \"Intel C++ Compiler 16.0\"")
|
||||
elif (compiler == "ICC15"):
|
||||
c.append("-G \"Visual Studio 12 2013"+ext+"\"")
|
||||
c.append("-T \"Intel C++ Compiler XE 15.0\"")
|
||||
elif (compiler == "CLANG"):
|
||||
c.append("-G \"Visual Studio 12 2013"+ext+"\"")
|
||||
c.append("-T \"LLVM-vs2013\"")
|
||||
else:
|
||||
raise ValueError('unknown compiler: ' + compiler + '')
|
||||
else:
|
||||
if (compiler == "ICC18"):
|
||||
c.append("-D CMAKE_CXX_COMPILER=icpc -D CMAKE_C_COMPILER=icc")
|
||||
e.append("module load intel/2018")
|
||||
elif (compiler == "ICC17"):
|
||||
c.append("-D CMAKE_CXX_COMPILER=icpc -D CMAKE_C_COMPILER=icc")
|
||||
e.append("module load intel/2017")
|
||||
elif (compiler == "ICC16"):
|
||||
c.append("-D CMAKE_CXX_COMPILER=icpc -D CMAKE_C_COMPILER=icc")
|
||||
e.append("module load intel/2016")
|
||||
elif (compiler == "ICC15"):
|
||||
c.append("-D CMAKE_CXX_COMPILER=icpc -D CMAKE_C_COMPILER=icc")
|
||||
e.append("module load intel/2015")
|
||||
elif (compiler == "ICC"):
|
||||
c.append("-D CMAKE_CXX_COMPILER=icpc -D CMAKE_C_COMPILER=icc")
|
||||
e.append("module load intel")
|
||||
elif (compiler == "GCC"):
|
||||
c.append("-D CMAKE_CXX_COMPILER=g++ -D CMAKE_C_COMPILER=gcc")
|
||||
elif (compiler == "CLANG4"):
|
||||
c.append("-D CMAKE_CXX_COMPILER=clang++ -D CMAKE_C_COMPILER=clang")
|
||||
e.append("module load clang/4")
|
||||
elif (compiler == "CLANG3.9"):
|
||||
c.append("-D CMAKE_CXX_COMPILER=clang++ -D CMAKE_C_COMPILER=clang")
|
||||
e.append("module load clang/3.9")
|
||||
elif (compiler == "CLANG3.8"):
|
||||
c.append("-D CMAKE_CXX_COMPILER=clang++ -D CMAKE_C_COMPILER=clang")
|
||||
e.append("module load clang/3.8")
|
||||
elif (compiler == "CLANG"):
|
||||
c.append("-D CMAKE_CXX_COMPILER=clang++ -D CMAKE_C_COMPILER=clang")
|
||||
else:
|
||||
raise ValueError('unknown compiler: ' + compiler + '')
|
||||
|
||||
if type(isa) == str:
|
||||
c.append("-D EMBREE_MAX_ISA="+isa+"")
|
||||
else:
|
||||
c.append("-D EMBREE_MAX_ISA=NONE")
|
||||
if "SSE2" in isa: c.append("-D EMBREE_ISA_SSE2=ON")
|
||||
else : c.append("-D EMBREE_ISA_SSE2=OFF")
|
||||
if "SSE42" in isa: c.append("-D EMBREE_ISA_SSE42=ON")
|
||||
else : c.append("-D EMBREE_ISA_SSE42=OFF")
|
||||
if "AVX" in isa: c.append("-D EMBREE_ISA_AVX=ON")
|
||||
else : c.append("-D EMBREE_ISA_AVX=OFF")
|
||||
if "AVX2" in isa: c.append("-D EMBREE_ISA_AVX2=ON")
|
||||
else : c.append("-D EMBREE_ISA_AVX2=OFF")
|
||||
if "AVX512KNL" in isa: c.append("-D EMBREE_ISA_AVX512KNL=ON")
|
||||
else : c.append("-D EMBREE_ISA_AVX512KNL=OFF")
|
||||
if "AVX512SKX" in isa: c.append("-D EMBREE_ISA_AVX512SKX=ON")
|
||||
else : c.append("-D EMBREE_ISA_AVX512SKX=OFF")
|
||||
|
||||
c.append("-D EMBREE_TASKING_SYSTEM="+tasking+"")
|
||||
c.append("-D EMBREE_TESTING_MEMCHECK="+memcheck+"")
|
||||
c.append("-D EMBREE_TESTING_INTENSIVE="+intensive+"")
|
||||
c.append("-D EMBREE_TESTING_SDE="+sde+"")
|
||||
|
||||
ispc_enabled = True
|
||||
if "ISPC_SUPPORT" in config:
|
||||
c.append("-D EMBREE_ISPC_SUPPORT="+config["ISPC_SUPPORT"])
|
||||
if config["ISPC_SUPPORT"] == "OFF": name += "-noispc"
|
||||
ispc_enabled = False
|
||||
if "STATIC_LIB" in config:
|
||||
c.append("-D EMBREE_STATIC_LIB="+config["STATIC_LIB"])
|
||||
if config["STATIC_LIB"] == "ON": name += "-static"
|
||||
if "TUTORIALS" in config:
|
||||
c.append("-D EMBREE_TUTORIALS="+config["TUTORIALS"])
|
||||
if config["TUTORIALS"] == "OFF": name += "-notutorials"
|
||||
if "BACKFACE_CULLING" in config:
|
||||
c.append("-D EMBREE_BACKFACE_CULLING="+config["BACKFACE_CULLING"])
|
||||
if config["BACKFACE_CULLING"] == "ON": name += "-backfaceculling"
|
||||
if "IGNORE_INVALID_RAYS" in config:
|
||||
c.append("-D EMBREE_IGNORE_INVALID_RAYS="+config["IGNORE_INVALID_RAYS"])
|
||||
if config["IGNORE_INVALID_RAYS"] == "ON": name += "-noinvalid"
|
||||
if "INTERSECTION_FILTER" in config:
|
||||
c.append("-D EMBREE_INTERSECTION_FILTER="+config["INTERSECTION_FILTER"])
|
||||
if config["INTERSECTION_FILTER"] == "OFF": name += "-nofilter"
|
||||
if "RAY_MASK" in config:
|
||||
c.append("-D EMBREE_RAY_MASK="+config["RAY_MASK"])
|
||||
if config["RAY_MASK"] == "ON": name += "-raymask"
|
||||
if "RAY_PACKETS" in config:
|
||||
c.append("-D EMBREE_RAY_PACKETS="+config["RAY_PACKETS"])
|
||||
if config["RAY_PACKETS"] == "OFF": name += "-nopackets"
|
||||
if "STAT_COUNTERS" in config:
|
||||
c.append("-D EMBREE_STAT_COUNTERS="+config["STAT_COUNTERS"])
|
||||
if config["STAT_COUNTERS"] == "ON": name += "-stats"
|
||||
if "TRIS" in config:
|
||||
c.append("-D EMBREE_GEOMETRY_TRIANGLES="+config["TRIS"])
|
||||
if config["TRIS"] == "ON": name += "-tris"
|
||||
if "QUADS" in config:
|
||||
c.append("-D EMBREE_GEOMETRY_QUADS="+config["QUADS"])
|
||||
if config["QUADS"] == "ON": name += "-quads"
|
||||
if "LINES" in config:
|
||||
c.append("-D EMBREE_GEOMETRY_LINES="+config["LINES"])
|
||||
if config["LINES"] == "ON": name += "-lines"
|
||||
if "HAIR" in config:
|
||||
c.append("-D EMBREE_GEOMETRY_HAIR="+config["HAIR"])
|
||||
if config["HAIR"] == "ON": name += "-hair"
|
||||
if "SUBDIV" in config:
|
||||
c.append("-D EMBREE_GEOMETRY_SUBDIV="+config["SUBDIV"])
|
||||
if config["SUBDIV"] == "ON": name += "-subdiv"
|
||||
if "USERGEOM" in config:
|
||||
c.append("-D EMBREE_GEOMETRY_USER="+config["USERGEOM"])
|
||||
if config["USERGEOM"] == "ON": name += "-usergeom"
|
||||
|
||||
if OS == "linux":
|
||||
if ispc_enabled: c.append("-D EMBREE_ISPC_EXECUTABLE=/NAS/packages/apps/ispc/1.9.1/ispc")
|
||||
if tasking == "TBB": c.append("-D EMBREE_TBB_ROOT=/NAS/packages/apps/tbb/tbb-2017-linux")
|
||||
elif OS == "macosx":
|
||||
{}
|
||||
#if ispc_enabled: c.append("-D EMBREE_ISPC_EXECUTABLE="+os.getcwd()+"/dependencies/ispc-v1.9.1-osx/ispc")
|
||||
#if tasking == "TBB": c.append("-D EMBREE_TBB_ROOT="+os.getcwd()+dash+"dependencies"+dash+"tbb-2017-osx")
|
||||
elif OS == "windows":
|
||||
#if ispc_enabled:
|
||||
#c.append("-D EMBREE_ISPC_EXECUTABLE="+os.getcwd()+dash+"dependencies"+dash+"ispc-v1.9.1-windows"+ispc_ext+dash+"ispc.exe")
|
||||
|
||||
if tasking == "TBB":
|
||||
#tbb_path = os.getcwd()+dash+"dependencies"+dash+"tbb-2017-windows"
|
||||
#c.append("-D EMBREE_TBB_ROOT="+tbb_path)
|
||||
if platform == "x64":
|
||||
e.append("set PATH="+tbb_path+"\\bin\\intel64\\vc12;%PATH%")
|
||||
else:
|
||||
e.append("set PATH="+tbb_path+"\\bin\\ia32\\vc12;%PATH%")
|
||||
else:
|
||||
sys.stderr.write("unknown operating system "+OS)
|
||||
sys.exit(1)
|
||||
|
||||
if "klocwork" in config:
|
||||
c.append("-D EMBREE_TESTING_KLOCWORK="+config["klocwork"])
|
||||
|
||||
if "package" in config:
|
||||
c.append("-D EMBREE_TESTING_PACKAGE=ON")
|
||||
c.append("-D EMBREE_TUTORIALS_IMAGE_MAGICK=OFF")
|
||||
c.append("-D EMBREE_TUTORIALS_LIBJPEG=OFF")
|
||||
c.append("-D EMBREE_TUTORIALS_LIBPNG=OFF")
|
||||
c.append("-D EMBREE_TUTORIALS_OPENEXR=OFF")
|
||||
if OS == "linux" and config["package"] == "ZIP":
|
||||
c.append("-D EMBREE_ZIP_MODE=ON")
|
||||
c.append("-D CMAKE_SKIP_INSTALL_RPATH=ON")
|
||||
c.append("-D CMAKE_INSTALL_INCLUDEDIR=include")
|
||||
c.append("-D CMAKE_INSTALL_LIBDIR=lib")
|
||||
c.append("-D CMAKE_INSTALL_DOCDIR=doc")
|
||||
c.append("-D CMAKE_INSTALL_BINDIR=bin")
|
||||
elif OS == "linux" and config["package"] == "RPM":
|
||||
c.append("-D EMBREE_ZIP_MODE=OFF")
|
||||
c.append("-D CMAKE_SKIP_INSTALL_RPATH=OFF")
|
||||
c.append("-D CMAKE_INSTALL_PREFIX=/usr")
|
||||
c.append("-D EMBREE_TBB_ROOT=/usr")
|
||||
elif OS == "macosx" and config["package"] == "ZIP":
|
||||
c.append("-D EMBREE_ZIP_MODE=ON")
|
||||
c.append("-D CMAKE_SKIP_INSTALL_RPATH=ON")
|
||||
c.append("-D CMAKE_MACOSX_RPATH=ON")
|
||||
c.append("-D CMAKE_INSTALL_INCLUDEDIR=include")
|
||||
c.append("-D CMAKE_INSTALL_LIBDIR=lib")
|
||||
c.append("-D CMAKE_INSTALL_DOCDIR=doc")
|
||||
c.append("-D CMAKE_INSTALL_BINDIR=bin")
|
||||
elif OS == "macosx" and config["package"] == "RPM":
|
||||
c.append("-D EMBREE_ZIP_MODE=OFF")
|
||||
c.append("-D CMAKE_SKIP_INSTALL_RPATH=OFF")
|
||||
c.append("-D CMAKE_INSTALL_PREFIX=/opt/local")
|
||||
c.append("-D CMAKE_INSTALL_INCLUDEDIR=include")
|
||||
c.append("-D CMAKE_INSTALL_LIBDIR=lib")
|
||||
c.append("-D CMAKE_INSTALL_DOCDIR=../../Applications/Embree2/doc")
|
||||
c.append("-D CMAKE_INSTALL_BINDIR=../../Applications/Embree2/bin")
|
||||
c.append("-D EMBREE_TBB_ROOT=/opt/local")
|
||||
elif OS == "windows" and config["package"] == "ZIP":
|
||||
c.append("-D EMBREE_ZIP_MODE=ON")
|
||||
c.append("-D CMAKE_INSTALL_INCLUDEDIR=include")
|
||||
c.append("-D CMAKE_INSTALL_LIBDIR=lib")
|
||||
c.append("-D CMAKE_INSTALL_DATAROOTDIR=")
|
||||
c.append("-D CMAKE_INSTALL_DOCDIR=doc")
|
||||
c.append("-D CMAKE_INSTALL_BINDIR=bin")
|
||||
elif OS == "windows" and config["package"] == "RPM":
|
||||
c.append("-D EMBREE_ZIP_MODE=OFF")
|
||||
c.append("-D CMAKE_INSTALL_INCLUDEDIR=include")
|
||||
c.append("-D CMAKE_INSTALL_LIBDIR=lib")
|
||||
c.append("-D CMAKE_INSTALL_DATAROOTDIR=")
|
||||
c.append("-D CMAKE_INSTALL_DOCDIR=doc")
|
||||
c.append("-D CMAKE_INSTALL_BINDIR=bin")
|
||||
else:
|
||||
sys.stderr.write("unknown package mode: "+OS+":"+config["package"])
|
||||
sys.exit(1)
|
||||
|
||||
return [name,build,skip_testing,benchmark,c,e]
|
||||
|
||||
# runs all tests for specified host machine
|
||||
def runConfig(cfg):
|
||||
[name,build,skip_testing,benchmark,conf,env] = createTest(cfg,OS)
|
||||
ctest = ""
|
||||
ctest += "ctest -VV -S scripts/test.cmake"
|
||||
if g_cdash != "": ctest += " -D CTEST_DROP_SITE="+g_cdash
|
||||
ctest += " -D TEST_NAME=\""+name+"\""
|
||||
if skip_testing: ctest += " -D CTEST_SKIP_TESTING=ON"
|
||||
else : ctest += " -D CTEST_SKIP_TESTING=OFF"
|
||||
ctest += " -D CTEST_CONFIGURATION_TYPE=\""+build+"\""
|
||||
ctest += " -D CTEST_BUILD_OPTIONS=\"" + escape(" ".join(conf))+"\""
|
||||
if g_debugMode:
|
||||
print(name)
|
||||
for e in env: print(' '+e)
|
||||
print(' '+ctest+'\n')
|
||||
else:
|
||||
cmd = ""
|
||||
for e in env: cmd += e + " && "
|
||||
cmd += ctest+"\n"
|
||||
subprocess.check_call(cmd, shell=True)
|
||||
#if OS == "windows":
|
||||
# subprocess.Popen(cmd, shell=True).communicate()
|
||||
#else: # we have to use a login shell to make "module load xxx" work
|
||||
# cmd = "export http_proxy= && export https_proxy= && " + cmd # cdash submission fails when proxy servers set
|
||||
# subprocess.Popen(['bash', '-l'], stdin=subprocess.PIPE).communicate(input=cmd.encode("utf-8"))
|
||||
|
||||
def parseCommandLine(argv):
|
||||
global g_cdash
|
||||
global g_config
|
||||
global g_mode
|
||||
global g_intensive
|
||||
global g_debugMode
|
||||
if len(argv) == 0:
|
||||
return;
|
||||
elif len(argv)>=2 and argv[0] == "--cdash":
|
||||
g_cdash = argv[1]
|
||||
parseCommandLine(argv[2:len(argv)])
|
||||
elif len(argv)>=2 and argv[0] == "--mode":
|
||||
g_mode = argv[1]
|
||||
parseCommandLine(argv[2:len(argv)])
|
||||
elif len(argv)>=1 and argv[0] == "--intensive":
|
||||
g_intensive = True
|
||||
parseCommandLine(argv[1:len(argv)])
|
||||
elif len(argv)>=1 and argv[0] == "--debug":
|
||||
g_debugMode = True
|
||||
parseCommandLine(argv[1:len(argv)])
|
||||
elif len(argv)>=1 and argv[0] == "--help":
|
||||
printUsage()
|
||||
return;
|
||||
elif ':' in argv[0]:
|
||||
p = argv[0].split(":")
|
||||
g_config[p[0]] = p[1]
|
||||
parseCommandLine(argv[1:len(argv)])
|
||||
else:
|
||||
sys.stderr.write("unknown command line option: "+argv[0])
|
||||
sys.exit(1)
|
||||
|
||||
parseCommandLine(sys.argv[1:len(sys.argv)])
|
||||
runConfig(g_config)
|
||||
|
||||
|
||||
|
||||
|
||||
Regular → Executable
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user