Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fdc8867102 |
No files matched your search
@@ -1,81 +0,0 @@
|
||||
|
||||
# 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]
|
||||
|
||||
|
||||
+2
-24
@@ -1,28 +1,6 @@
|
||||
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
|
||||
@@ -106,7 +84,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
|
||||
@@ -416,7 +394,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)
|
||||
|
||||
+1
-2
@@ -17,7 +17,7 @@
|
||||
SET(EMBREE_VERSION_MAJOR 2)
|
||||
SET(EMBREE_VERSION_MINOR 17)
|
||||
SET(EMBREE_VERSION_PATCH 0)
|
||||
SET(EMBREE_VERSION_NOTE "")
|
||||
SET(EMBREE_VERSION_NOTE "-alpha.0")
|
||||
SET(EMBREE_VERSION ${EMBREE_VERSION_MAJOR}.${EMBREE_VERSION_MINOR}.${EMBREE_VERSION_PATCH})
|
||||
MATH(EXPR EMBREE_VERSION_NUMBER "10000*${EMBREE_VERSION_MAJOR} + 100*${EMBREE_VERSION_MINOR} + ${EMBREE_VERSION_PATCH}")
|
||||
SET(CPACK_RPM_PACKAGE_RELEASE 1)
|
||||
@@ -26,7 +26,6 @@ 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.17.0
|
||||
% Embree: High Performance Ray Tracing Kernels 2.16.5
|
||||
% 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.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`.
|
||||
[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`.
|
||||
|
||||
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.17.0` and uninstall it.
|
||||
2.16.5` and uninstall it.
|
||||
|
||||
Windows ZIP File
|
||||
-----------------
|
||||
|
||||
Embree is also delivered as a ZIP file
|
||||
[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
|
||||
[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
|
||||
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.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)
|
||||
[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)
|
||||
to
|
||||
obtain the individual RPM files:
|
||||
|
||||
tar xzf embree-2.17.0.x86_64.rpm.tar.gz
|
||||
tar xzf embree-2.16.5.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.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
|
||||
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
|
||||
|
||||
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.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
|
||||
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
|
||||
|
||||
Linux tar.gz files
|
||||
------------------
|
||||
|
||||
The Linux version of Embree is also delivered as a tar.gz file
|
||||
[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
|
||||
[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
|
||||
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.17.0.x64.linux.tar.gz
|
||||
source embree-2.17.0.x64.linux/embree-vars.sh
|
||||
tar xzf embree-2.16.5.x64.linux.tar.gz
|
||||
source embree-2.16.5.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.17.0.x86_64.dmg](https://github.com/embree/embree/releases/download/v2.17.0/embree-2.17.0.x86_64.dmg). This
|
||||
[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
|
||||
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.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
|
||||
[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
|
||||
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.17.0.x64.macosx.tar.gz
|
||||
source embree-2.17.0.x64.macosx/embree-vars.sh
|
||||
tar xzf embree-2.16.5.x64.macosx.tar.gz
|
||||
source embree-2.16.5.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,9 +481,6 @@ 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
|
||||
@@ -584,6 +581,10 @@ 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
|
||||
==========
|
||||
|
||||
@@ -716,18 +717,13 @@ device.
|
||||
typedef void (*RTCErrorFunc2)(void* userPtr, const RTCError, const char* str);
|
||||
void rtcDeviceSetErrorFunction2(RTCDevice, RTCErrorFunc2, void* userPtr);
|
||||
|
||||
When invoked, the registered callback function gets passed a user
|
||||
When invoked, the registred 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
|
||||
-----
|
||||
|
||||
@@ -967,7 +963,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
|
||||
@@ -1020,7 +1016,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,
|
||||
@@ -1079,7 +1075,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
|
||||
@@ -1092,7 +1088,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
|
||||
@@ -1113,7 +1109,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
|
||||
@@ -1129,7 +1125,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
|
||||
@@ -1288,7 +1284,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
|
||||
@@ -1343,7 +1339,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
|
||||
@@ -1408,7 +1404,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
|
||||
@@ -1771,7 +1767,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
|
||||
@@ -1867,11 +1863,10 @@ 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. 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
|
||||
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
|
||||
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`
|
||||
@@ -1883,7 +1878,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 addresses
|
||||
packets to be stored sequentially in memory, but at different adresses
|
||||
as specified in the `RTCRayNp` structure.
|
||||
|
||||
The intersection context passed to the stream version of the ray query
|
||||
@@ -1982,8 +1977,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.
|
||||
|
||||
All output arrays must be padded to 16 bytes. The `RTC_INTERPOLATE`
|
||||
algorithm flag of a scene has to be enabled to perform interpolations.
|
||||
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
|
||||
@@ -2047,7 +2042,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`
|
||||
@@ -2117,7 +2112,7 @@ while modifying the scene with other threads.
|
||||
Geometry Mask
|
||||
-------------
|
||||
|
||||
A 32-bit geometry mask can be assigned to triangle meshes and hair
|
||||
A 32 bit geometry mask can be assigned to triangle meshes and hair
|
||||
geometries using the `rtcSetMask` call.
|
||||
|
||||
rtcSetMask(scene, geomID, mask);
|
||||
|
||||
@@ -66,7 +66,7 @@ ELSE ()
|
||||
FIND_LIBRARY(TBB_LIBRARY tbb)
|
||||
FIND_LIBRARY(TBB_LIBRARY_MALLOC tbbmalloc)
|
||||
|
||||
ELSEIF (EXISTS ${EMBREE_TBB_ROOT}/cmake/TBBBuild.cmake)
|
||||
ELSEIF (EXISTS ${EMBREE_TBB_ROOT}/src)
|
||||
OPTION(EMBREE_TBB_STATIC_LIB "Build TBB as a static library (building TBB as a static library is NOT recommended)")
|
||||
if (EMBREE_TBB_STATIC_LIB)
|
||||
include(${EMBREE_TBB_ROOT}/cmake/TBBBuild.cmake)
|
||||
@@ -117,6 +117,7 @@ MARK_AS_ADVANCED(TBB_LIBRARY_MALLOC)
|
||||
|
||||
IF (WIN32)
|
||||
INSTALL(PROGRAMS ${TBB_BINDIR}/tbb.dll ${TBB_BINDIR}/tbbmalloc.dll DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT examples)
|
||||
INSTALL(PROGRAMS ${TBB_BINDIR}/tbb.dll ${TBB_BINDIR}/tbbmalloc.dll DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT lib)
|
||||
INSTALL(PROGRAMS ${TBB_LIBDIR}/tbb.lib ${TBB_LIBDIR}/tbbmalloc.lib DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT lib)
|
||||
ELSEIF (EMBREE_ZIP_MODE)
|
||||
IF (APPLE)
|
||||
|
||||
@@ -36,11 +36,6 @@ 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
|
||||
@@ -93,11 +88,6 @@ 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,11 +41,6 @@ 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
|
||||
|
||||
+2
-17
@@ -33,11 +33,6 @@ 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
|
||||
@@ -110,12 +105,6 @@ 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
|
||||
@@ -133,12 +122,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
|
||||
IF (NOT APPLE)
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -inline-factor=200") # increase default inline factors limits by 2x
|
||||
ELSE(NOT APPLE)
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -inline-factor=150")
|
||||
ENDIF()
|
||||
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -inline-factor=200") # 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
|
||||
|
||||
@@ -28,11 +28,6 @@ IF (EMBREE_STACK_PROTECTOR)
|
||||
ELSE()
|
||||
SET(COMMON_CXX_FLAGS "${COMMON_CXX_FLAGS} /GS-") # do not protect against return address overrides
|
||||
ENDIF()
|
||||
MACRO(DISABLE_STACK_PROTECTOR_FOR_FILE file)
|
||||
IF (EMBREE_STACK_PROTECTOR)
|
||||
SET_SOURCE_FILES_PROPERTIES(${file} PROPERTIES COMPILE_FLAGS "/GS-")
|
||||
ENDIF()
|
||||
ENDMACRO()
|
||||
SET(COMMON_CXX_FLAGS "${COMMON_CXX_FLAGS} ${FLAGS_SSE2}")
|
||||
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${COMMON_CXX_FLAGS}")
|
||||
|
||||
@@ -125,7 +125,7 @@ INSTALL(FILES "${PROJECT_BINARY_DIR}/embree-config-version.cmake" DESTINATION ${
|
||||
# CPack specific stuff
|
||||
##############################################################
|
||||
|
||||
SET(CPACK_PACKAGE_NAME "Embree Ray Tracing Kernels")
|
||||
SET(CPACK_PACKAGE_NAME "Embree")
|
||||
SET(CPACK_PACKAGE_FILE_NAME "embree-${EMBREE_VERSION}")
|
||||
#SET(CPACK_PACKAGE_ICON ${PROJECT_SOURCE_DIR}/embree-doc/images/icon.png)
|
||||
#SET(CPACK_PACKAGE_RELOCATABLE TRUE)
|
||||
@@ -161,18 +161,33 @@ 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 WIX)
|
||||
SET(CPACK_GENERATOR NSIS)
|
||||
SET(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}.${ARCH}")
|
||||
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_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")
|
||||
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()
|
||||
@@ -215,6 +230,7 @@ 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 < 16); v = _mm_lookupmask_ps[mask]; }
|
||||
__forceinline vboolf(unsigned int mask) { assert(mask >= 0 && mask < 16); v = _mm_lookupmask_ps[mask]; }
|
||||
|
||||
/* return int32 mask */
|
||||
__forceinline __m128i mask32() const {
|
||||
|
||||
@@ -428,9 +428,6 @@ 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));
|
||||
@@ -533,7 +530,6 @@ 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);
|
||||
@@ -543,17 +539,6 @@ 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,14 +69,6 @@ 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); }
|
||||
|
||||
@@ -555,14 +547,6 @@ 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,14 +101,6 @@ 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,14 +77,6 @@ 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); }
|
||||
|
||||
@@ -408,18 +400,6 @@ 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,14 +89,6 @@ 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); }
|
||||
|
||||
@@ -371,11 +363,7 @@ namespace embree
|
||||
|
||||
template<int i>
|
||||
__forceinline vint8 align_shift_right(const vint8& a, const vint8& b) {
|
||||
#if defined(__AVX512VL__)
|
||||
return _mm256_alignr_epi32(a, b, i);
|
||||
#else
|
||||
return _mm256_alignr_epi8(a, b, 4*i);
|
||||
#endif
|
||||
return _mm256_alignr_epi8(a, b, i);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace embree
|
||||
}
|
||||
|
||||
/*! run this task */
|
||||
void TaskScheduler::Task::run_internal (Thread& thread) // FIXME: avoid as many __dllexports as possible
|
||||
__dllexport void TaskScheduler::Task::run (Thread& thread) // FIXME: avoid as many __dllexports as possible
|
||||
{
|
||||
/* try to run if not already stolen */
|
||||
if (try_switch_state(INITIALIZED,DONE))
|
||||
@@ -71,19 +71,14 @@ namespace embree
|
||||
/* steal until all dependencies have completed */
|
||||
steal_loop(thread,
|
||||
[&] () { return dependencies>0; },
|
||||
[&] () { while (thread.tasks.execute_local_internal(thread,this)); });
|
||||
[&] () { while (thread.tasks.execute_local(thread,this)); });
|
||||
|
||||
/* now signal our parent task that we are finished */
|
||||
if (parent)
|
||||
parent->add_dependencies(-1);
|
||||
}
|
||||
|
||||
/*! run this task */
|
||||
__dllexport void TaskScheduler::Task::run (Thread& thread) {
|
||||
run_internal(thread);
|
||||
}
|
||||
|
||||
bool TaskScheduler::TaskQueue::execute_local_internal(Thread& thread, Task* parent)
|
||||
__dllexport bool TaskScheduler::TaskQueue::execute_local(Thread& thread, Task* parent)
|
||||
{
|
||||
/* stop if we run out of local tasks or reach the waiting task */
|
||||
if (right == 0 || &tasks[right-1] == parent)
|
||||
@@ -91,7 +86,7 @@ namespace embree
|
||||
|
||||
/* execute task */
|
||||
size_t oldRight = right;
|
||||
tasks[right-1].run_internal(thread);
|
||||
tasks[right-1].run(thread);
|
||||
if (right != oldRight) {
|
||||
THROW_RUNTIME_ERROR("you have to wait for spawned subtasks");
|
||||
}
|
||||
@@ -107,10 +102,6 @@ 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;
|
||||
@@ -325,7 +316,7 @@ namespace embree
|
||||
{
|
||||
Thread* thread = TaskScheduler::thread();
|
||||
if (thread == nullptr) return true;
|
||||
while (thread->tasks.execute_local_internal(*thread,thread->task)) {};
|
||||
while (thread->tasks.execute_local(*thread,thread->task)) {};
|
||||
return thread->scheduler->cancellingException == nullptr;
|
||||
}
|
||||
|
||||
@@ -344,7 +335,7 @@ namespace embree
|
||||
[&] () { return anyTasksRunning > 0; },
|
||||
[&] () {
|
||||
anyTasksRunning++;
|
||||
while (thread.tasks.execute_local_internal(thread,nullptr));
|
||||
while (thread.tasks.execute_local(thread,nullptr));
|
||||
anyTasksRunning--;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -109,8 +109,6 @@ 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
|
||||
@@ -151,7 +149,6 @@ 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 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 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 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 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 int geomID, uniform float tessellationRate);
|
||||
void rtcSetTessellationRate (RTCScene scene, uniform unsigned 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 int geomID, uniform RTCBufferType vertexBuffer, uniform RTCBufferType indexBuffer);
|
||||
void rtcSetIndexBuffer(RTCScene scene, uniform unsigned 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 int geomID, uniform RTCIntersectFunc1Mp intersect);
|
||||
void rtcSetIntersectFunction1Mp (RTCScene scene, uniform unsigned 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 int geomID, uniform RTCIntersectFuncN intersect);
|
||||
void rtcSetIntersectFunctionN (RTCScene scene, uniform unsigned 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 int geomID, uniform RTCOccludedFunc1Mp occluded);
|
||||
void rtcSetOccludedFunction1Mp (RTCScene scene, uniform unsigned 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 int geomID, uniform RTCOccludedFuncN occluded);
|
||||
void rtcSetOccludedFunctionN (RTCScene scene, uniform unsigned geomID, uniform RTCOccludedFuncN occluded);
|
||||
|
||||
/*! @} */
|
||||
|
||||
|
||||
@@ -18,4 +18,4 @@
|
||||
#define RTCORE_VERSION_MINOR 17
|
||||
#define RTCORE_VERSION_PATCH 0
|
||||
#define RTCORE_VERSION 21700
|
||||
#define RTCORE_VERSION_STRING "2.17.0"
|
||||
#define RTCORE_VERSION_STRING "2.17.0-alpha.0"
|
||||
@@ -14,14 +14,6 @@
|
||||
## 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/" )
|
||||
@@ -216,7 +208,6 @@ 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")
|
||||
@@ -234,7 +225,6 @@ 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)
|
||||
@@ -243,7 +233,6 @@ 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)
|
||||
@@ -252,7 +241,6 @@ 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)
|
||||
@@ -261,7 +249,6 @@ 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)
|
||||
@@ -270,7 +257,6 @@ 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)
|
||||
|
||||
+10
-12
@@ -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 = 2*maxBuildDepthLeaf; // 2x because of two level builder
|
||||
static const size_t maxDepth = maxBuildDepth+maxBuildDepthLeaf;
|
||||
|
||||
/*! Maximal number of primitive blocks in a leaf. */
|
||||
static const size_t maxLeafBlocks = items_mask-tyLeaf;
|
||||
@@ -169,7 +169,6 @@ 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);
|
||||
@@ -192,11 +191,10 @@ namespace embree
|
||||
prefetchL1(((char*)ptr)+3*64);
|
||||
}
|
||||
if ((N >= 8) && (types > BVH_FLAG_ALIGNED_NODE)) {
|
||||
/* 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);
|
||||
prefetchL1(((char*)ptr)+4*64);
|
||||
prefetchL1(((char*)ptr)+5*64);
|
||||
prefetchL1(((char*)ptr)+6*64);
|
||||
prefetchL1(((char*)ptr)+7*64);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -364,9 +362,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& num) const {
|
||||
__forceinline char* leaf(size_t& ty) const {
|
||||
assert(isLeaf());
|
||||
num = (ptr & (size_t)items_mask)-tyLeaf;
|
||||
ty = (ptr & (size_t)items_mask)-tyLeaf;
|
||||
return (char*)(ptr & ~(size_t)align_mask);
|
||||
}
|
||||
|
||||
@@ -1456,10 +1454,10 @@ namespace embree
|
||||
}
|
||||
|
||||
/*! Encodes a leaf */
|
||||
static __forceinline NodeRef encodeLeaf(void* tri, size_t num) {
|
||||
static __forceinline NodeRef encodeLeaf(void* tri, size_t ty) {
|
||||
assert(!((size_t)tri & align_mask));
|
||||
assert(num <= maxLeafBlocks);
|
||||
return NodeRef((size_t)tri | (tyLeaf+min(num,(size_t)maxLeafBlocks)));
|
||||
assert(ty <= maxLeafBlocks);
|
||||
return NodeRef((size_t)tri | (tyLeaf+min(ty,(size_t)maxLeafBlocks)));
|
||||
}
|
||||
|
||||
/*! Encodes a leaf */
|
||||
|
||||
@@ -182,8 +182,6 @@ 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);
|
||||
@@ -499,8 +497,6 @@ 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));
|
||||
@@ -528,7 +524,7 @@ namespace embree
|
||||
intersectors.intersector4 = BVH4Bezier1vIntersector4Hybrid();
|
||||
intersectors.intersector8 = BVH4Bezier1vIntersector8Hybrid();
|
||||
intersectors.intersector16 = BVH4Bezier1vIntersector16Hybrid();
|
||||
intersectors.intersectorN = BVH4IntersectorStreamPacketFallback();
|
||||
//intersectors.intersectorN = BVH4Bezier1vIntersectorStream();
|
||||
#endif
|
||||
return intersectors;
|
||||
}
|
||||
@@ -542,7 +538,7 @@ namespace embree
|
||||
intersectors.intersector4 = BVH4Bezier1iIntersector4Hybrid();
|
||||
intersectors.intersector8 = BVH4Bezier1iIntersector8Hybrid();
|
||||
intersectors.intersector16 = BVH4Bezier1iIntersector16Hybrid();
|
||||
intersectors.intersectorN = BVH4IntersectorStreamPacketFallback();
|
||||
//intersectors.intersectorN = BVH4Bezier1iIntersectorStream();
|
||||
#endif
|
||||
return intersectors;
|
||||
}
|
||||
@@ -556,7 +552,7 @@ namespace embree
|
||||
intersectors.intersector4 = BVH4Line4iIntersector4();
|
||||
intersectors.intersector8 = BVH4Line4iIntersector8();
|
||||
intersectors.intersector16 = BVH4Line4iIntersector16();
|
||||
intersectors.intersectorN = BVH4IntersectorStreamPacketFallback();
|
||||
//intersectors.intersectorN = BVH4Line4iIntersectorStream();
|
||||
#endif
|
||||
return intersectors;
|
||||
}
|
||||
@@ -570,7 +566,7 @@ namespace embree
|
||||
intersectors.intersector4 = BVH4Line4iMBIntersector4();
|
||||
intersectors.intersector8 = BVH4Line4iMBIntersector8();
|
||||
intersectors.intersector16 = BVH4Line4iMBIntersector16();
|
||||
intersectors.intersectorN = BVH4IntersectorStreamPacketFallback();
|
||||
//intersectors.intersectorN = BVH4Line4iMBIntersectorStream();
|
||||
#endif
|
||||
return intersectors;
|
||||
}
|
||||
@@ -584,7 +580,7 @@ namespace embree
|
||||
intersectors.intersector4 = BVH4Bezier1vIntersector4Hybrid_OBB();
|
||||
intersectors.intersector8 = BVH4Bezier1vIntersector8Hybrid_OBB();
|
||||
intersectors.intersector16 = BVH4Bezier1vIntersector16Hybrid_OBB();
|
||||
intersectors.intersectorN = BVH4IntersectorStreamPacketFallback();
|
||||
//intersectors.intersectorN = BVH4Bezier1vIntersectorStream_OBB();
|
||||
#endif
|
||||
return intersectors;
|
||||
}
|
||||
@@ -598,7 +594,7 @@ namespace embree
|
||||
intersectors.intersector4 = BVH4Bezier1iIntersector4Hybrid_OBB();
|
||||
intersectors.intersector8 = BVH4Bezier1iIntersector8Hybrid_OBB();
|
||||
intersectors.intersector16 = BVH4Bezier1iIntersector16Hybrid_OBB();
|
||||
intersectors.intersectorN = BVH4IntersectorStreamPacketFallback();
|
||||
//intersectors.intersectorN = BVH4Bezier1iIntersectorStream_OBB();
|
||||
#endif
|
||||
return intersectors;
|
||||
}
|
||||
@@ -612,7 +608,7 @@ namespace embree
|
||||
intersectors.intersector4 = BVH4OBBBezier1iMBIntersector4Hybrid_OBB();
|
||||
intersectors.intersector8 = BVH4OBBBezier1iMBIntersector8Hybrid_OBB();
|
||||
intersectors.intersector16 = BVH4OBBBezier1iMBIntersector16Hybrid_OBB();
|
||||
intersectors.intersectorN = BVH4IntersectorStreamPacketFallback();
|
||||
//intersectors.intersectorN = BVH4OBBBezier1iMBIntersectorStream_OBB();
|
||||
#endif
|
||||
return intersectors;
|
||||
}
|
||||
@@ -704,7 +700,7 @@ namespace embree
|
||||
intersectors.intersector4 = BVH4Triangle4vMBIntersector4HybridMoeller();
|
||||
intersectors.intersector8 = BVH4Triangle4vMBIntersector8HybridMoeller();
|
||||
intersectors.intersector16 = BVH4Triangle4vMBIntersector16HybridMoeller();
|
||||
intersectors.intersectorN = BVH4IntersectorStreamPacketFallback();
|
||||
//intersectors.intersectorN = BVH4Triangle4vMBIntersectorStreamMoeller();
|
||||
#endif
|
||||
return intersectors;
|
||||
}
|
||||
@@ -717,7 +713,7 @@ namespace embree
|
||||
intersectors.intersector4 = BVH4Triangle4vMBIntersector4HybridPluecker();
|
||||
intersectors.intersector8 = BVH4Triangle4vMBIntersector8HybridPluecker();
|
||||
intersectors.intersector16 = BVH4Triangle4vMBIntersector16HybridPluecker();
|
||||
intersectors.intersectorN = BVH4IntersectorStreamPacketFallback();
|
||||
//intersectors.intersectorN = BVH4Triangle4vMBIntersectorStreamPluecker();
|
||||
#endif
|
||||
return intersectors;
|
||||
}
|
||||
@@ -737,7 +733,7 @@ namespace embree
|
||||
intersectors.intersector4 = BVH4Triangle4iMBIntersector4HybridMoeller();
|
||||
intersectors.intersector8 = BVH4Triangle4iMBIntersector8HybridMoeller();
|
||||
intersectors.intersector16 = BVH4Triangle4iMBIntersector16HybridMoeller();
|
||||
intersectors.intersectorN = BVH4IntersectorStreamPacketFallback();
|
||||
//intersectors.intersectorN = BVH4Triangle4iMBIntersectorStreamMoeller();
|
||||
#endif
|
||||
return intersectors;
|
||||
}
|
||||
@@ -750,7 +746,7 @@ namespace embree
|
||||
intersectors.intersector4 = BVH4Triangle4iMBIntersector4HybridPluecker();
|
||||
intersectors.intersector8 = BVH4Triangle4iMBIntersector8HybridPluecker();
|
||||
intersectors.intersector16 = BVH4Triangle4iMBIntersector16HybridPluecker();
|
||||
intersectors.intersectorN = BVH4IntersectorStreamPacketFallback();
|
||||
//intersectors.intersectorN = BVH4Triangle4iMBIntersectorStreamPluecker();
|
||||
#endif
|
||||
return intersectors;
|
||||
}
|
||||
@@ -840,7 +836,7 @@ namespace embree
|
||||
intersectors.intersector4 = BVH4Quad4iMBIntersector4HybridMoeller();
|
||||
intersectors.intersector8 = BVH4Quad4iMBIntersector8HybridMoeller();
|
||||
intersectors.intersector16= BVH4Quad4iMBIntersector16HybridMoeller();
|
||||
intersectors.intersectorN = BVH4IntersectorStreamPacketFallback();
|
||||
//intersectors.intersectorN = BVH4Quad4iMBIntersectorStreamMoeller();
|
||||
#endif
|
||||
return intersectors;
|
||||
}
|
||||
@@ -853,7 +849,7 @@ namespace embree
|
||||
intersectors.intersector4 = BVH4Quad4iMBIntersector4HybridPluecker();
|
||||
intersectors.intersector8 = BVH4Quad4iMBIntersector8HybridPluecker();
|
||||
intersectors.intersector16= BVH4Quad4iMBIntersector16HybridPluecker();
|
||||
intersectors.intersectorN = BVH4IntersectorStreamPacketFallback();
|
||||
//intersectors.intersectorN = BVH4Quad4iMBIntersectorStreamPluecker();
|
||||
#endif
|
||||
return intersectors;
|
||||
}
|
||||
@@ -900,7 +896,7 @@ namespace embree
|
||||
intersectors.intersector4 = BVH4VirtualMBIntersector4Chunk();
|
||||
intersectors.intersector8 = BVH4VirtualMBIntersector8Chunk();
|
||||
intersectors.intersector16 = BVH4VirtualMBIntersector16Chunk();
|
||||
intersectors.intersectorN = BVH4IntersectorStreamPacketFallback();
|
||||
//intersectors.intersectorN = BVH4VirtualMBIntersectorStream();
|
||||
#endif
|
||||
return intersectors;
|
||||
}
|
||||
@@ -914,7 +910,7 @@ namespace embree
|
||||
intersectors.intersector4 = BVH4SubdivPatch1Intersector4();
|
||||
intersectors.intersector8 = BVH4SubdivPatch1Intersector8();
|
||||
intersectors.intersector16 = BVH4SubdivPatch1Intersector16();
|
||||
intersectors.intersectorN = BVH4IntersectorStreamPacketFallback();
|
||||
//intersectors.intersectorN = BVH4SubdivPatch1IntersectorStream();
|
||||
#endif
|
||||
return intersectors;
|
||||
}
|
||||
@@ -928,7 +924,7 @@ namespace embree
|
||||
intersectors.intersector4 = BVH4SubdivPatch1EagerIntersector4();
|
||||
intersectors.intersector8 = BVH4SubdivPatch1EagerIntersector8();
|
||||
intersectors.intersector16 = BVH4SubdivPatch1EagerIntersector16();
|
||||
intersectors.intersectorN = BVH4IntersectorStreamPacketFallback();
|
||||
//intersectors.intersectorN = BVH4SubdivPatch1EagerIntersectorStream();
|
||||
#endif
|
||||
return intersectors;
|
||||
}
|
||||
@@ -942,7 +938,7 @@ namespace embree
|
||||
intersectors.intersector4 = BVH4SubdivPatch1CachedIntersector4();
|
||||
intersectors.intersector8 = BVH4SubdivPatch1CachedIntersector8();
|
||||
intersectors.intersector16 = BVH4SubdivPatch1CachedIntersector16();
|
||||
intersectors.intersectorN = BVH4IntersectorStreamPacketFallback();
|
||||
//intersectors.intersectorN = BVH4SubdivPatch1CachedIntersectorStream();
|
||||
#endif
|
||||
return intersectors;
|
||||
}
|
||||
@@ -956,7 +952,7 @@ namespace embree
|
||||
intersectors.intersector4 = BVH4SubdivPatch1MBIntersector4();
|
||||
intersectors.intersector8 = BVH4SubdivPatch1MBIntersector8();
|
||||
intersectors.intersector16 = BVH4SubdivPatch1MBIntersector16();
|
||||
intersectors.intersectorN = BVH4IntersectorStreamPacketFallback();
|
||||
//intersectors.intersectorN = BVH4SubdivPatch1MBStreamIntersector();
|
||||
#endif
|
||||
return intersectors;
|
||||
}
|
||||
@@ -970,7 +966,7 @@ namespace embree
|
||||
intersectors.intersector4 = BVH4SubdivPatch1CachedMBIntersector4();
|
||||
intersectors.intersector8 = BVH4SubdivPatch1CachedMBIntersector8();
|
||||
intersectors.intersector16 = BVH4SubdivPatch1CachedMBIntersector16();
|
||||
intersectors.intersectorN = BVH4IntersectorStreamPacketFallback();
|
||||
//intersectors.intersectorN = BVH4SubdivPatch1CachedMBStreamIntersector();
|
||||
#endif
|
||||
return intersectors;
|
||||
}
|
||||
|
||||
@@ -268,8 +268,6 @@ 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,9 +14,7 @@
|
||||
// limitations under the License. //
|
||||
// ======================================================================== //
|
||||
|
||||
#include "../common/isa.h" // to define EMBREE_TARGET_SIMD8
|
||||
|
||||
#if defined (EMBREE_TARGET_SIMD8)
|
||||
#if defined (EMBREE_TARGET_AVX)
|
||||
|
||||
#include "bvh8_factory.h"
|
||||
#include "../bvh/bvh.h"
|
||||
@@ -157,8 +155,6 @@ 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);
|
||||
@@ -416,9 +412,6 @@ 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));
|
||||
@@ -533,7 +526,7 @@ namespace embree
|
||||
intersectors.intersector4 = BVH8Bezier1vIntersector4Hybrid_OBB();
|
||||
intersectors.intersector8 = BVH8Bezier1vIntersector8Hybrid_OBB();
|
||||
intersectors.intersector16 = BVH8Bezier1vIntersector16Hybrid_OBB();
|
||||
intersectors.intersectorN = BVH8IntersectorStreamPacketFallback();
|
||||
//intersectors.intersectorN = BVH8Bezier1vIntersectorStream_OBB();
|
||||
#endif
|
||||
return intersectors;
|
||||
}
|
||||
@@ -547,7 +540,7 @@ namespace embree
|
||||
intersectors.intersector4 = BVH8Bezier1iIntersector4Hybrid_OBB();
|
||||
intersectors.intersector8 = BVH8Bezier1iIntersector8Hybrid_OBB();
|
||||
intersectors.intersector16 = BVH8Bezier1iIntersector16Hybrid_OBB();
|
||||
intersectors.intersectorN = BVH8IntersectorStreamPacketFallback();
|
||||
//intersectors.intersectorN = BVH8Bezier1iIntersectorStream_OBB();
|
||||
#endif
|
||||
return intersectors;
|
||||
}
|
||||
@@ -561,7 +554,7 @@ namespace embree
|
||||
intersectors.intersector4 = BVH8OBBBezier1iMBIntersector4Hybrid_OBB();
|
||||
intersectors.intersector8 = BVH8OBBBezier1iMBIntersector8Hybrid_OBB();
|
||||
intersectors.intersector16 = BVH8OBBBezier1iMBIntersector16Hybrid_OBB();
|
||||
intersectors.intersectorN = BVH8IntersectorStreamPacketFallback();
|
||||
//intersectors.intersectorN = BVH8OBBBezier1iMBIntersectorStream_OBB();
|
||||
#endif
|
||||
return intersectors;
|
||||
}
|
||||
@@ -575,7 +568,7 @@ namespace embree
|
||||
intersectors.intersector4 = BVH8Line4iIntersector4();
|
||||
intersectors.intersector8 = BVH8Line4iIntersector8();
|
||||
intersectors.intersector16 = BVH8Line4iIntersector16();
|
||||
intersectors.intersectorN = BVH8IntersectorStreamPacketFallback();
|
||||
//intersectors.intersectorN = BVH8Line4iIntersectorStream();
|
||||
#endif
|
||||
return intersectors;
|
||||
}
|
||||
@@ -589,7 +582,7 @@ namespace embree
|
||||
intersectors.intersector4 = BVH8Line4iMBIntersector4();
|
||||
intersectors.intersector8 = BVH8Line4iMBIntersector8();
|
||||
intersectors.intersector16 = BVH8Line4iMBIntersector16();
|
||||
intersectors.intersectorN = BVH8IntersectorStreamPacketFallback();
|
||||
//intersectors.intersectorN = BVH8Line4iMBIntersectorStream();
|
||||
#endif
|
||||
return intersectors;
|
||||
}
|
||||
@@ -673,7 +666,7 @@ namespace embree
|
||||
intersectors.intersector4 = BVH8Triangle4vMBIntersector4HybridMoeller();
|
||||
intersectors.intersector8 = BVH8Triangle4vMBIntersector8HybridMoeller();
|
||||
intersectors.intersector16 = BVH8Triangle4vMBIntersector16HybridMoeller();
|
||||
intersectors.intersectorN = BVH8IntersectorStreamPacketFallback();
|
||||
//intersectors.intersectorN = BVH8Triangle4vMBIntersectorStreamMoeller();
|
||||
#endif
|
||||
return intersectors;
|
||||
}
|
||||
@@ -686,7 +679,7 @@ namespace embree
|
||||
intersectors.intersector4 = BVH8Triangle4vMBIntersector4HybridPluecker();
|
||||
intersectors.intersector8 = BVH8Triangle4vMBIntersector8HybridPluecker();
|
||||
intersectors.intersector16 = BVH8Triangle4vMBIntersector16HybridPluecker();
|
||||
intersectors.intersectorN = BVH8IntersectorStreamPacketFallback();
|
||||
//intersectors.intersectorN = BVH8Triangle4vMBIntersectorStreamPluecker();
|
||||
#endif
|
||||
return intersectors;
|
||||
}
|
||||
@@ -706,7 +699,7 @@ namespace embree
|
||||
intersectors.intersector4 = BVH8Triangle4iMBIntersector4HybridMoeller();
|
||||
intersectors.intersector8 = BVH8Triangle4iMBIntersector8HybridMoeller();
|
||||
intersectors.intersector16 = BVH8Triangle4iMBIntersector16HybridMoeller();
|
||||
intersectors.intersectorN = BVH8IntersectorStreamPacketFallback();
|
||||
//intersectors.intersectorN = BVH8Triangle4iMBIntersectorStreamMoeller();
|
||||
#endif
|
||||
return intersectors;
|
||||
}
|
||||
@@ -719,7 +712,7 @@ namespace embree
|
||||
intersectors.intersector4 = BVH8Triangle4iMBIntersector4HybridPluecker();
|
||||
intersectors.intersector8 = BVH8Triangle4iMBIntersector8HybridPluecker();
|
||||
intersectors.intersector16 = BVH8Triangle4iMBIntersector16HybridPluecker();
|
||||
intersectors.intersectorN = BVH8IntersectorStreamPacketFallback();
|
||||
//intersectors.intersectorN = BVH8Triangle4iMBIntersectorStreamPluecker();
|
||||
#endif
|
||||
return intersectors;
|
||||
}
|
||||
@@ -809,7 +802,7 @@ namespace embree
|
||||
intersectors.intersector4 = BVH8Quad4iMBIntersector4HybridMoeller();
|
||||
intersectors.intersector8 = BVH8Quad4iMBIntersector8HybridMoeller();
|
||||
intersectors.intersector16 = BVH8Quad4iMBIntersector16HybridMoeller();
|
||||
intersectors.intersectorN = BVH8IntersectorStreamPacketFallback();
|
||||
//intersectors.intersectorN = BVH8Quad4iMBIntersectorStreamMoeller();
|
||||
#endif
|
||||
return intersectors;
|
||||
}
|
||||
@@ -822,7 +815,7 @@ namespace embree
|
||||
intersectors.intersector4 = BVH8Quad4iMBIntersector4HybridPluecker();
|
||||
intersectors.intersector8 = BVH8Quad4iMBIntersector8HybridPluecker();
|
||||
intersectors.intersector16 = BVH8Quad4iMBIntersector16HybridPluecker();
|
||||
intersectors.intersectorN = BVH8IntersectorStreamPacketFallback();
|
||||
//intersectors.intersectorN = BVH8Quad4iMBIntersectorStreamPluecker();
|
||||
#endif
|
||||
return intersectors;
|
||||
}
|
||||
@@ -877,7 +870,7 @@ namespace embree
|
||||
intersectors.intersector4 = BVH8VirtualMBIntersector4Chunk();
|
||||
intersectors.intersector8 = BVH8VirtualMBIntersector8Chunk();
|
||||
intersectors.intersector16 = BVH8VirtualMBIntersector16Chunk();
|
||||
intersectors.intersectorN = BVH8IntersectorStreamPacketFallback();
|
||||
//intersectors.intersectorN = BVH8VirtualMBIntersectorStream();
|
||||
#endif
|
||||
return intersectors;
|
||||
}
|
||||
|
||||
@@ -217,8 +217,6 @@ 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);
|
||||
accel[i].fill(prims,start,set.end(),bvh->scene,i==(items-1));
|
||||
}
|
||||
return bvh->encodeLeaf((char*)accel,items);
|
||||
};
|
||||
@@ -165,7 +165,7 @@ namespace embree
|
||||
|
||||
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));
|
||||
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);
|
||||
};
|
||||
|
||||
@@ -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));
|
||||
Triangle4::store_nt(accel,Triangle4(v0,v1,v2,vgeomID,vprimID,true));
|
||||
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));
|
||||
Triangle4v::store_nt(accel,Triangle4v(v0,v1,v2,vgeomID,vprimID,true));
|
||||
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));
|
||||
Triangle4i::store_nt(accel,Triangle4i(v0,v1,v2,vgeomID,vprimID,true));
|
||||
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));
|
||||
Quad4v::store_nt(accel,Quad4v(v0,v1,v2,v3,vgeomID,vprimID,true));
|
||||
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);
|
||||
new (&accel[i]) Object(geomID,primID,true);
|
||||
}
|
||||
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);
|
||||
accel[i].fill(prims,start,set.end(),bvh->scene,i==(items-1));
|
||||
}
|
||||
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);
|
||||
accel[i].fill(prims,start,set.end(),bvh->scene,i==(items-1));
|
||||
}
|
||||
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));
|
||||
allBounds.extend(accel[i].fillMB(prims, start, set.end(), bvh->scene, time, i==(items-1)));
|
||||
|
||||
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));
|
||||
allBounds.extend(accel[i].fillMB(current.prims.prims->data(), start, current.prims.object_range.end(), bvh->scene, current.prims.time_range, i==(items-1)));
|
||||
return NodeRecordMB4D(node,allBounds,current.prims.time_range);
|
||||
}
|
||||
|
||||
|
||||
@@ -37,10 +37,9 @@ namespace embree
|
||||
namespace isa
|
||||
{
|
||||
template<int N, int types, bool robust, typename PrimitiveIntersector1>
|
||||
void BVHNIntersector1<N,types,robust,PrimitiveIntersector1>::intersect(const Accel::Intersectors* __restrict__ This, Ray& __restrict__ ray, IntersectContext* __restrict__ context)
|
||||
void BVHNIntersector1<N,types,robust,PrimitiveIntersector1>::intersect(const BVH* __restrict__ bvh, Ray& __restrict__ ray, IntersectContext* context)
|
||||
{
|
||||
/*! perform per ray precalculations required by the primitive intersector */
|
||||
const BVH* __restrict__ bvh = (const BVH*) This->ptr;
|
||||
Precalculations pre(ray,bvh);
|
||||
|
||||
/*! stack state */
|
||||
@@ -106,8 +105,12 @@ namespace embree
|
||||
if (unlikely(nodeTraverser.traverseTransform(cur,ray,vray,context,stackPtr,stackEnd)))
|
||||
goto pop;
|
||||
|
||||
/*! this is a leaf node */
|
||||
/*! 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 */
|
||||
STAT3(normal.trav_leaves,1,1,1);
|
||||
size_t num; Primitive* prim = (Primitive*) cur.leaf(num);
|
||||
size_t lazy_node = 0;
|
||||
@@ -125,19 +128,18 @@ namespace embree
|
||||
}
|
||||
|
||||
template<int N, int types, bool robust, typename PrimitiveIntersector1>
|
||||
void BVHNIntersector1<N,types,robust,PrimitiveIntersector1>::occluded(const Accel::Intersectors* __restrict__ This, Ray& __restrict__ ray, IntersectContext* __restrict__ context)
|
||||
void BVHNIntersector1<N,types,robust,PrimitiveIntersector1>::occluded(const BVH* __restrict__ bvh, Ray& __restrict__ ray, IntersectContext* context)
|
||||
{
|
||||
/*! early out for already occluded rays */
|
||||
if (unlikely(ray.geomID == 0))
|
||||
return;
|
||||
|
||||
/*! perform per ray precalculations required by the primitive intersector */
|
||||
const BVH* __restrict__ bvh = (const BVH*) This->ptr;
|
||||
Precalculations pre(ray,bvh);
|
||||
|
||||
/*! stack state */
|
||||
NodeRef stack[stackSize]; //!< stack of nodes that still need to get traversed
|
||||
NodeRef* stackPtr = stack+1; //!< current stack pointer
|
||||
NodeRef stack[stackSize]; //!< stack of nodes that still need to get traversed
|
||||
NodeRef* stackPtr = stack+1; //!< current stack pointer
|
||||
NodeRef* stackEnd = stack+stackSize;
|
||||
stack[0] = bvh->root;
|
||||
|
||||
@@ -189,8 +191,12 @@ namespace embree
|
||||
if (unlikely(nodeTraverser.traverseTransform(cur,ray,vray,context,stackPtr,stackEnd)))
|
||||
goto pop;
|
||||
|
||||
/*! this is a leaf node */
|
||||
/*! 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 */
|
||||
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 Accel::Intersectors* This, Ray& ray, IntersectContext* context);
|
||||
static void occluded (const Accel::Intersectors* This, Ray& ray, IntersectContext* context);
|
||||
static void intersect(const BVH* This, Ray& ray, IntersectContext* context);
|
||||
static void occluded (const BVH* This, Ray& ray, IntersectContext* context);
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -34,11 +34,9 @@
|
||||
|
||||
#define SWITCH_DURING_DOWN_TRAVERSAL 1
|
||||
#define FORCE_SINGLE_MODE 0
|
||||
|
||||
#define ENABLE_FAST_COHERENT_CODEPATHS 1
|
||||
|
||||
|
||||
#define STREAM_IN_HYBRID 0
|
||||
|
||||
namespace embree
|
||||
{
|
||||
namespace isa
|
||||
@@ -107,8 +105,12 @@ namespace embree
|
||||
BVHNNodeTraverser1<N,Nx,types>::traverseClosestHit(cur,mask,tNear,stackPtr,stackEnd);
|
||||
}
|
||||
|
||||
/*! this is a leaf node */
|
||||
/*! 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 */
|
||||
STAT3(normal.trav_leaves, 1, 1, 1);
|
||||
size_t num; Primitive* prim = (Primitive*)cur.leaf(num);
|
||||
|
||||
@@ -126,15 +128,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(vint<K>* __restrict__ valid_i, Accel::Intersectors* __restrict__ This, RayK<K>& __restrict__ ray, IntersectContext* __restrict__ context)
|
||||
void BVHNIntersectorKHybrid<N,K,types,robust,PrimitiveIntersectorK,single>::intersect(vint<K>* __restrict__ valid_i, BVH* __restrict__ bvh, 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)))
|
||||
{
|
||||
intersect_coherent(valid_i,This,ray,context);
|
||||
intersect_coherent(valid_i,bvh,ray,context);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@@ -149,6 +149,7 @@ namespace embree
|
||||
size_t valid_bits = movemask(valid);
|
||||
if (unlikely(valid_bits == 0)) return;
|
||||
|
||||
|
||||
/* verify correct input */
|
||||
assert(all(valid,ray.valid()));
|
||||
assert(all(valid,ray.tnear >= 0.0f));
|
||||
@@ -180,9 +181,12 @@ namespace embree
|
||||
/* determine switch threshold based on flags */
|
||||
const size_t switchThreshold = (context->user && isCoherent(context->user->flags)) ? 2 : switchThresholdIncoherent;
|
||||
|
||||
vint<K> octant = ray.octant();
|
||||
octant = select(valid, octant, vint<K>(0xffffffff));
|
||||
|
||||
vint<K> octant = \
|
||||
select(vfloat<K>(rdir.x) < 0.0f,vint<K>(1),vint<K>(zero)) |
|
||||
select(vfloat<K>(rdir.y) < 0.0f,vint<K>(2),vint<K>(zero)) |
|
||||
select(vfloat<K>(rdir.z) < 0.0f,vint<K>(4),vint<K>(zero));
|
||||
|
||||
octant = select(valid,octant,vint<K>(0xffffffff));
|
||||
do
|
||||
{
|
||||
const size_t valid_index = __bsf(valid_bits);
|
||||
@@ -264,7 +268,7 @@ namespace embree
|
||||
const NodeRef child = node->children[i];
|
||||
if (unlikely(child == BVH::emptyNode)) break;
|
||||
vfloat<K> lnearP;
|
||||
vbool<K> lhit = valid_node;
|
||||
vbool<K> lhit(valid_node);
|
||||
BVHNNodeIntersectorK<N,K,types,robust>::intersect(nodeRef,i,org,ray_dir,rdir,org_rdir,ray_tnear,ray_tfar,ray.time,lnearP,lhit);
|
||||
|
||||
/* if we hit the child we choose to continue with that child if it
|
||||
@@ -345,8 +349,12 @@ namespace embree
|
||||
break;
|
||||
}
|
||||
|
||||
/* intersect leaf */
|
||||
/*! check for empty leaf in case we accidentally hit one */
|
||||
assert(cur != BVH::emptyNode);
|
||||
if (cur == BVH::emptyNode)
|
||||
goto pop;
|
||||
|
||||
/* intersect leaf */
|
||||
const vbool<K> valid_leaf = ray_tfar > curDist;
|
||||
STAT3(normal.trav_leaves,1,popcnt(valid_leaf),K);
|
||||
if (unlikely(none(valid_leaf))) continue;
|
||||
@@ -368,13 +376,8 @@ 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,
|
||||
Accel::Intersectors* __restrict__ This,
|
||||
RayK<K>& __restrict__ ray,
|
||||
IntersectContext* context)
|
||||
void BVHNIntersectorKHybrid<N,K,types,robust,PrimitiveIntersectorK,single>::intersect_coherent(vint<K>* __restrict__ valid_i, BVH* __restrict__ bvh, 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)
|
||||
@@ -412,7 +415,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<N,Nx,K,robust> frustum(octant_valid,org,rdir,ray_tnear,ray_tfar);
|
||||
Frustum frustum(octant_valid,rdir,org,ray_tnear,ray_tfar);
|
||||
|
||||
StackItemT<NodeRef> stack[stackSizeSingle]; //!< stack of nodes
|
||||
StackItemT<NodeRef>* stackPtr = stack + 1; //!< current stack pointer
|
||||
@@ -439,8 +442,8 @@ namespace embree
|
||||
const NodeRef nodeRef = cur;
|
||||
const AlignedNode* __restrict__ const node = nodeRef.alignedNode();
|
||||
|
||||
vfloat<Nx> fmin;
|
||||
size_t m_frusta_node = frustum.intersect(node,fmin);
|
||||
__aligned(64) float fmin[16];
|
||||
size_t m_frusta_node = frustum.intersect(nodeRef,fmin);
|
||||
|
||||
if (unlikely(!m_frusta_node)) goto pop;
|
||||
cur = BVH::emptyNode;
|
||||
@@ -453,7 +456,7 @@ namespace embree
|
||||
do {
|
||||
const size_t i = __bscf(m_frusta_node);
|
||||
vfloat<K> lnearP;
|
||||
vbool<K> lhit = false; // motion blur is not supported, so the initial value will be ignored
|
||||
vbool<K> lhit( false );
|
||||
STAT3(normal.trav_nodes,1,1,1);
|
||||
BVHNNodeIntersectorK<N,K,types,robust>::intersect(nodeRef,i,org,ray_dir,rdir,org_rdir,ray_tnear,ray_tfar,ray.time,lnearP,lhit);
|
||||
|
||||
@@ -500,9 +503,13 @@ namespace embree
|
||||
}
|
||||
}
|
||||
|
||||
/*! 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;
|
||||
@@ -510,13 +517,17 @@ 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;
|
||||
@@ -577,8 +588,12 @@ namespace embree
|
||||
BVHNNodeTraverser1<N,Nx,types>::traverseAnyHit(cur,mask,tNear,stackPtr,stackEnd);
|
||||
}
|
||||
|
||||
/*! this is a leaf node */
|
||||
/*! 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 */
|
||||
STAT3(shadow.trav_leaves,1,1,1);
|
||||
size_t num; Primitive* prim = (Primitive*) cur.leaf(num);
|
||||
|
||||
@@ -597,15 +612,13 @@ 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, Accel::Intersectors* __restrict__ This, RayK<K>& __restrict__ ray, IntersectContext* context)
|
||||
void BVHNIntersectorKHybrid<N,K,types,robust,PrimitiveIntersectorK,single>::occluded(vint<K>* __restrict__ valid_i, BVH* __restrict__ bvh, 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,This,ray,context);
|
||||
occluded_coherent(valid_i,bvh,ray,context);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@@ -617,7 +630,7 @@ namespace embree
|
||||
#endif
|
||||
|
||||
/* return if there are no valid rays */
|
||||
size_t valid_bits = movemask(valid);
|
||||
const size_t valid_bits = movemask(valid);
|
||||
if (unlikely(valid_bits == 0)) return;
|
||||
|
||||
/* verify correct input */
|
||||
@@ -635,154 +648,6 @@ namespace embree
|
||||
const Vec3vf<K> org(ray_org), org_rdir = org * rdir;
|
||||
ray_tnear = select(valid,ray_tnear,vfloat<K>(pos_inf));
|
||||
ray_tfar = select(valid,ray_tfar ,vfloat<K>(neg_inf));
|
||||
|
||||
#if STREAM_IN_HYBRID == 1
|
||||
Vec3vi<K> nearXYZ;
|
||||
nearXYZ.x = select(rdir.x >= 0.0f,vint<K>(0*(int)sizeof(vfloat<N>)),vint<K>(1*(int)sizeof(vfloat<N>)));
|
||||
nearXYZ.y = select(rdir.y >= 0.0f,vint<K>(2*(int)sizeof(vfloat<N>)),vint<K>(3*(int)sizeof(vfloat<N>)));
|
||||
nearXYZ.z = select(rdir.z >= 0.0f,vint<K>(4*(int)sizeof(vfloat<N>)),vint<K>(5*(int)sizeof(vfloat<N>)));
|
||||
|
||||
const int shiftTable[8] = { (int)1 << 0, (int)1 << 1, (int)1 << 2, (int)1 << 3, (int)1 << 4, (int)1 << 5, (int)1 << 6, (int)1 << 7 };
|
||||
|
||||
{
|
||||
|
||||
/*! stack state */
|
||||
StackItemT<NodeRef> stack[stackSizeSingle]; //!< stack of nodes
|
||||
StackItemT<NodeRef>* stackPtr = stack + 1; //!< current stack pointer
|
||||
//StackItemT<NodeRef>* stackEnd = stack + stackSizeSingle;
|
||||
stack[0].ptr = bvh->root;
|
||||
stack[0].dist = movemask(valid);
|
||||
|
||||
|
||||
|
||||
while (1) pop:
|
||||
{
|
||||
if (unlikely(stackPtr == stack)) break;
|
||||
STAT3(shadow.trav_stack_pop,1,1,1);
|
||||
stackPtr--;
|
||||
NodeRef cur = NodeRef(stackPtr->ptr);
|
||||
size_t cur_mask = stackPtr->dist & movemask(!terminated);
|
||||
if (unlikely(cur_mask == 0)) continue;
|
||||
|
||||
while (true)
|
||||
{
|
||||
|
||||
/*! stop if we found a leaf node */
|
||||
if (unlikely(cur.isLeaf())) break;
|
||||
|
||||
const AlignedNode* __restrict__ const node = cur.alignedNode();
|
||||
|
||||
const vfloat<Nx> bminX = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_x));
|
||||
const vfloat<Nx> bmaxX = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->upper_x));
|
||||
const vfloat<Nx> bminY = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_y));
|
||||
const vfloat<Nx> bmaxY = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->upper_y));
|
||||
const vfloat<Nx> bminZ = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_z));
|
||||
const vfloat<Nx> bmaxZ = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->upper_z));
|
||||
|
||||
size_t bits = cur_mask;
|
||||
|
||||
#if defined(__AVX__)
|
||||
STAT3(shadow.trav_hit_boxes[__popcnt(cur_mask)],1,1,1);
|
||||
#endif
|
||||
|
||||
assert(bits);
|
||||
const vbool<Nx> valid_children = bminX <= bmaxX;
|
||||
|
||||
vint<Nx> vmask(zero);
|
||||
do
|
||||
{
|
||||
STAT3(shadow.trav_nodes,1,1,1);
|
||||
|
||||
const size_t i = __bscf(bits);
|
||||
assert(i < K);
|
||||
//const vint<Nx> bitmask = vint<Nx>((int)1 << i);
|
||||
|
||||
const vint<Nx> bitmask(shiftTable[i]);
|
||||
|
||||
const vfloat<Nx> tNearX = msub(bminX, rdir.x[i], org_rdir.x[i]);
|
||||
const vfloat<Nx> tNearY = msub(bminY, rdir.y[i], org_rdir.y[i]);
|
||||
const vfloat<Nx> tNearZ = msub(bminZ, rdir.z[i], org_rdir.z[i]);
|
||||
const vfloat<Nx> tFarX = msub(bmaxX, rdir.x[i], org_rdir.x[i]);
|
||||
const vfloat<Nx> tFarY = msub(bmaxY, rdir.y[i], org_rdir.y[i]);
|
||||
const vfloat<Nx> tFarZ = msub(bmaxZ, rdir.z[i], org_rdir.z[i]);
|
||||
|
||||
const vfloat<Nx> tNear = maxi(mini(tNearX,tFarX), mini(tNearY,tFarY), mini(tNearZ,tFarZ), vfloat<Nx>(ray_tnear[i]));
|
||||
const vfloat<Nx> tFar = mini(maxi(tNearX,tFarX), maxi(tNearY,tFarY), maxi(tNearZ,tFarZ), vfloat<Nx>(ray_tfar[i]));
|
||||
const vbool<Nx> hit_mask = tNear <= tFar;
|
||||
#if defined(__AVX2__)
|
||||
vmask = vmask | (bitmask & vint<Nx>(hit_mask));
|
||||
#else
|
||||
vmask = select(hit_mask, vmask | bitmask, vmask);
|
||||
#endif
|
||||
} while(bits);
|
||||
size_t mask = movemask( (vmask != vint<Nx>(zero)) & valid_children);
|
||||
if (unlikely(mask == 0)) goto pop;
|
||||
|
||||
/* select next child and push other children */
|
||||
//const BaseNode* node = cur.baseNode(types);
|
||||
|
||||
/*! one child is hit, continue with that child */
|
||||
size_t r = __bscf(mask);
|
||||
assert(r < N);
|
||||
cur = node->child(r);
|
||||
cur.prefetch(types);
|
||||
cur_mask = vmask[r];
|
||||
|
||||
/* simple in order sequence */
|
||||
assert(cur != BVH::emptyNode);
|
||||
if (likely(mask == 0)) continue;
|
||||
stackPtr->ptr = cur;
|
||||
stackPtr->dist = cur_mask;
|
||||
stackPtr++;
|
||||
|
||||
for (; ;)
|
||||
{
|
||||
r = __bscf(mask);
|
||||
assert(r < N);
|
||||
|
||||
cur = node->child(r);
|
||||
cur.prefetch(types);
|
||||
cur_mask = vmask[r];
|
||||
assert(cur != BVH::emptyNode);
|
||||
if (likely(mask == 0)) break;
|
||||
stackPtr->ptr = cur;
|
||||
stackPtr->dist = cur_mask;
|
||||
stackPtr++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*! this is a leaf node */
|
||||
assert(cur != BVH::emptyNode);
|
||||
STAT3(shadow.trav_leaves,1,1,1);
|
||||
size_t num; Primitive* prim = (Primitive*) cur.leaf(num);
|
||||
|
||||
|
||||
size_t bits = cur_mask;
|
||||
size_t lazy_node = 0;
|
||||
|
||||
for (; bits!=0; )
|
||||
{
|
||||
const size_t k = __bscf(bits);
|
||||
if (PrimitiveIntersectorK::occluded(pre,ray,k,context,prim,num,lazy_node)) {
|
||||
ray.geomID[k] = 0;
|
||||
set(terminated, k);
|
||||
}
|
||||
/* lazy node */
|
||||
if (unlikely(lazy_node)) {
|
||||
stackPtr->ptr = lazy_node;
|
||||
stackPtr->dist = cur_mask;
|
||||
stackPtr++;
|
||||
}
|
||||
}
|
||||
|
||||
if (all(terminated)) break;
|
||||
}
|
||||
|
||||
}
|
||||
// while(valid_bits);
|
||||
|
||||
#else
|
||||
const vfloat<K> inf = vfloat<K>(pos_inf);
|
||||
|
||||
/* compute near/far per ray */
|
||||
@@ -861,23 +726,33 @@ namespace embree
|
||||
const NodeRef child = node->children[i];
|
||||
if (unlikely(child == BVH::emptyNode)) break;
|
||||
vfloat<K> lnearP;
|
||||
vbool<K> lhit = valid_node;
|
||||
vbool<K> lhit(valid_node);
|
||||
BVHNNodeIntersectorK<N,K,types,robust>::intersect(nodeRef,i,org,ray_dir,rdir,org_rdir,ray_tnear,ray_tfar,ray.time,lnearP,lhit);
|
||||
|
||||
/* if we hit the child we push the previously hit node onto the stack, and continue with the currently hit child */
|
||||
/* if we hit the child we choose to continue with that child if it
|
||||
is closer than the current next child, or we push it onto the stack */
|
||||
if (likely(any(lhit)))
|
||||
{
|
||||
assert(sptr_node < stackEnd);
|
||||
assert(child != BVH::emptyNode);
|
||||
const vfloat<K> childDist = select(lhit,lnearP,inf);
|
||||
|
||||
/* push 'cur' node onto stack and continue with hit child */
|
||||
if (likely(cur != BVH::emptyNode)) {
|
||||
*sptr_node = cur; sptr_node++;
|
||||
*sptr_near = curDist; sptr_near++;
|
||||
/* push cur node onto stack and continue with hit child */
|
||||
if (any(childDist < curDist))
|
||||
{
|
||||
if (likely(cur != BVH::emptyNode)) {
|
||||
*sptr_node = cur; sptr_node++;
|
||||
*sptr_near = curDist; sptr_near++;
|
||||
}
|
||||
curDist = childDist;
|
||||
cur = child;
|
||||
}
|
||||
|
||||
/* push hit child onto stack */
|
||||
else {
|
||||
*sptr_node = child; sptr_node++;
|
||||
*sptr_near = childDist; sptr_near++;
|
||||
}
|
||||
curDist = childDist;
|
||||
cur = child;
|
||||
}
|
||||
}
|
||||
if (unlikely(cur == BVH::emptyNode))
|
||||
@@ -903,40 +778,35 @@ 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;
|
||||
size_t items; const Primitive* prim = (Primitive*) cur.leaf(items);
|
||||
|
||||
size_t lazy_node = 0;
|
||||
#if defined(__AVX__)
|
||||
STAT3(shadow.trav_hit_boxes[popcnt(vbool<K>(!terminated))],1,1,1);
|
||||
#endif
|
||||
|
||||
terminated |= PrimitiveIntersectorK::occluded(!terminated,pre,ray,context,prim,items,lazy_node);
|
||||
if (all(terminated)) break;
|
||||
ray_tfar = select(terminated, vfloat<K>(neg_inf), ray_tfar); // ignore node intersections for terminated rays
|
||||
ray_tfar = select(terminated,vfloat<K>(neg_inf),ray_tfar);
|
||||
|
||||
if (unlikely(lazy_node)) {
|
||||
*sptr_node = lazy_node; sptr_node++;
|
||||
*sptr_near = neg_inf; sptr_near++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
vint<K>::store(valid & terminated,&ray.geomID,0);
|
||||
AVX_ZERO_UPPER();
|
||||
}
|
||||
|
||||
|
||||
template<int N, int K, int types, bool robust, typename PrimitiveIntersectorK, bool single>
|
||||
void BVHNIntersectorKHybrid<N,K,types,robust,PrimitiveIntersectorK,single>::occluded_coherent(vint<K>* __restrict__ valid_i, Accel::Intersectors* __restrict__ This,
|
||||
RayK<K>& __restrict__ ray, IntersectContext* context)
|
||||
void BVHNIntersectorKHybrid<N,K,types,robust,PrimitiveIntersectorK,single>::occluded_coherent(vint<K>* __restrict__ valid_i, BVH* __restrict__ bvh, 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)
|
||||
@@ -950,7 +820,7 @@ namespace embree
|
||||
/* verify correct input */
|
||||
assert(all(valid,ray.valid()));
|
||||
assert(all(valid,ray.tnear >= 0.0f));
|
||||
assert(!(types & BVH_MB) || all(valid, (ray.time >= 0.0f) & (ray.time <= 1.0f)));
|
||||
assert(!(types & BVH_MB) || all(valid,(ray.time >= 0.0f) & (ray.time <= 1.0f)));
|
||||
Precalculations pre(valid,ray);
|
||||
|
||||
/* load ray */
|
||||
@@ -963,24 +833,27 @@ namespace embree
|
||||
const Vec3vf<K> org(ray_org);
|
||||
const Vec3vf<K> org_rdir = org * rdir;
|
||||
|
||||
vint<K> octant = ray.octant();
|
||||
octant = select(valid, octant, vint<K>(0xffffffff));
|
||||
|
||||
vint<K> octant = \
|
||||
select(vfloat<K>(rdir.x) < 0.0f,vint<K>(1),vint<K>(zero)) |
|
||||
select(vfloat<K>(rdir.y) < 0.0f,vint<K>(2),vint<K>(zero)) |
|
||||
select(vfloat<K>(rdir.z) < 0.0f,vint<K>(4),vint<K>(zero));
|
||||
|
||||
octant = select(valid,octant,vint<K>(0xffffffff));
|
||||
do
|
||||
{
|
||||
const size_t valid_index = __bsf(valid_bits);
|
||||
vbool<K> octant_valid = octant[valid_index] == octant;
|
||||
valid_bits &= ~(size_t)movemask(octant_valid);
|
||||
|
||||
const vfloat<K> ray_tnear = select(octant_valid, org_ray_tnear, vfloat<K>(pos_inf));
|
||||
vfloat<K> ray_tfar = select(octant_valid, org_ray_tfar, vfloat<K>(neg_inf));
|
||||
const vfloat<K> ray_tnear = select(octant_valid,org_ray_tnear,vfloat<K>(pos_inf));
|
||||
const vfloat<K> ray_tfar = select(octant_valid,org_ray_tfar ,vfloat<K>(neg_inf));
|
||||
|
||||
const Frustum<N,Nx,K,robust> frustum(octant_valid, org, rdir, ray_tnear, ray_tfar);
|
||||
const Frustum frustum(octant_valid,rdir,org,ray_tnear,ray_tfar);
|
||||
|
||||
StackItemMaskT<NodeRef> stack[stackSizeSingle]; //!< stack of nodes
|
||||
StackItemMaskT<NodeRef>* stackPtr = stack + 1; //!< current stack pointer
|
||||
stack[0].ptr = bvh->root;
|
||||
stack[0].mask = (unsigned int)movemask(octant_valid);
|
||||
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);
|
||||
|
||||
while (1) pop:
|
||||
{
|
||||
@@ -991,7 +864,7 @@ namespace embree
|
||||
NodeRef cur = NodeRef(stackPtr->ptr);
|
||||
|
||||
/* cull node of active rays have already been terminated */
|
||||
unsigned int m_active = stackPtr->mask & (~movemask(terminated));
|
||||
unsigned int m_active = stackPtr->dist & (~movemask(terminated));
|
||||
|
||||
if (unlikely(m_active == 0)) continue;
|
||||
|
||||
@@ -1002,8 +875,8 @@ namespace embree
|
||||
const NodeRef nodeRef = cur;
|
||||
const AlignedNode* __restrict__ const node = nodeRef.alignedNode();
|
||||
|
||||
vfloat<Nx> fmin;
|
||||
size_t m_frusta_node = frustum.intersect(node,fmin);
|
||||
__aligned(64) float fmin[16];
|
||||
size_t m_frusta_node = frustum.intersect(nodeRef,fmin);
|
||||
|
||||
if (unlikely(!m_frusta_node)) goto pop;
|
||||
cur = BVH::emptyNode;
|
||||
@@ -1016,7 +889,7 @@ namespace embree
|
||||
do {
|
||||
const size_t i = __bscf(m_frusta_node);
|
||||
vfloat<K> lnearP;
|
||||
vbool<K> lhit = false; // motion blur is not supported, so the initial value will be ignored
|
||||
vbool<K> lhit( false );
|
||||
STAT3(normal.trav_nodes,1,1,1);
|
||||
BVHNNodeIntersectorK<N,K,types,robust>::intersect(nodeRef,i,org,ray_dir,rdir,org_rdir,ray_tnear,ray_tfar,ray.time,lnearP,lhit);
|
||||
|
||||
@@ -1028,20 +901,24 @@ namespace embree
|
||||
if (likely(cur != BVH::emptyNode)) {
|
||||
num_child_hits++;
|
||||
stackPtr->ptr = cur;
|
||||
stackPtr->mask = m_active;
|
||||
stackPtr->dist = m_active;
|
||||
stackPtr++;
|
||||
}
|
||||
cur = child;
|
||||
m_active = (unsigned int)movemask(lhit);
|
||||
m_active = 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
|
||||
@@ -1052,16 +929,16 @@ namespace embree
|
||||
terminated |= PrimitiveIntersectorK::occluded(!terminated,pre,ray,context,prim,items,lazy_node);
|
||||
octant_valid &= !terminated;
|
||||
if (unlikely(none(octant_valid))) break;
|
||||
ray_tfar = select(terminated, vfloat<K>(neg_inf), ray_tfar); // ignore node intersections for terminated rays
|
||||
|
||||
if (unlikely(lazy_node)) {
|
||||
stackPtr->ptr = lazy_node;
|
||||
stackPtr->mask = (unsigned int)movemask(octant_valid);
|
||||
stackPtr->dist = movemask(octant_valid);
|
||||
stackPtr++;
|
||||
}
|
||||
}
|
||||
|
||||
} while(valid_bits);
|
||||
vint<K>::store(valid & terminated, &ray.geomID, 0);
|
||||
vint<K>::store(valid & terminated,&ray.geomID,0);
|
||||
|
||||
AVX_ZERO_UPPER();
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
#include "bvh.h"
|
||||
#include "../common/ray.h"
|
||||
#include "../common/stack_item.h"
|
||||
#include "frustum.h"
|
||||
|
||||
namespace embree
|
||||
{
|
||||
@@ -39,6 +38,7 @@ 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,6 +49,178 @@ 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);
|
||||
@@ -56,11 +228,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, 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(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_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);
|
||||
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);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -23,9 +23,9 @@ namespace embree
|
||||
namespace isa
|
||||
{
|
||||
template<int N, int Nx>
|
||||
struct TravRay
|
||||
struct TravRay
|
||||
{
|
||||
__forceinline TravRay() {}
|
||||
__forceinline TravRay () {}
|
||||
|
||||
__forceinline TravRay(const Vec3fa& ray_org, const Vec3fa& ray_dir)
|
||||
: org_xyz(ray_org), dir_xyz(ray_dir)
|
||||
@@ -56,8 +56,8 @@ namespace embree
|
||||
}
|
||||
|
||||
template<int K>
|
||||
__forceinline TravRay(size_t k, const Vec3vf<K> &ray_org, const Vec3vf<K> &ray_dir,
|
||||
const Vec3vf<K> &ray_rdir, const Vec3vi<K>& nearXYZ, const size_t flip = sizeof(vfloat<N>))
|
||||
__forceinline TravRay (size_t k, const Vec3vf<K> &ray_org, const Vec3vf<K> &ray_dir,
|
||||
const Vec3vf<K> &ray_rdir, const Vec3vi<K>& nearXYZ, const size_t flip = sizeof(vfloat<N>))
|
||||
{
|
||||
org = Vec3vf<Nx>(ray_org.x[k], ray_org.y[k], ray_org.z[k]);
|
||||
dir = Vec3vf<Nx>(ray_dir.x[k], ray_dir.y[k], ray_dir.z[k]);
|
||||
@@ -82,7 +82,7 @@ namespace embree
|
||||
#endif
|
||||
}
|
||||
|
||||
__forceinline TravRay(const TravRay& ray)
|
||||
__forceinline TravRay (const TravRay& ray)
|
||||
{
|
||||
org_xyz = ray.org_xyz;
|
||||
dir_xyz = ray.dir_xyz;
|
||||
@@ -127,12 +127,12 @@ namespace embree
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<int N, int Nx>
|
||||
__forceinline size_t intersectNode(const typename BVHN<N>::AlignedNode* node, const TravRay<N,Nx>& ray,
|
||||
const vfloat<Nx>& tnear, const vfloat<Nx>& tfar, vfloat<Nx>& dist);
|
||||
__forceinline size_t intersectNode(const typename BVHN<N>::AlignedNode* node, const TravRay<N,Nx>& ray,
|
||||
const vfloat<Nx>& tnear, const vfloat<Nx>& tfar, vfloat<Nx>& dist);
|
||||
|
||||
template<>
|
||||
__forceinline size_t intersectNode<4,4>(const typename BVH4::AlignedNode* node, const TravRay<4,4>& ray,
|
||||
const vfloat4& tnear, const vfloat4& tfar, vfloat4& dist)
|
||||
__forceinline size_t intersectNode<4,4>(const typename BVH4::AlignedNode* node, const TravRay<4,4>& ray,
|
||||
const vfloat4& tnear, const vfloat4& tfar, vfloat4& dist)
|
||||
{
|
||||
#if defined(__AVX2__)
|
||||
const vfloat4 tNearX = msub(vfloat4::load((float*)((const char*)&node->lower_x+ray.nearX)), ray.rdir.x, ray.org_rdir.x);
|
||||
@@ -173,8 +173,8 @@ namespace embree
|
||||
#if defined(__AVX__)
|
||||
|
||||
template<>
|
||||
__forceinline size_t intersectNode<8,8>(const typename BVH8::AlignedNode* node, const TravRay<8,8>& ray,
|
||||
const vfloat8& tnear, const vfloat8& tfar, vfloat8& dist)
|
||||
__forceinline size_t intersectNode<8,8>(const typename BVH8::AlignedNode* node, const TravRay<8,8>& ray,
|
||||
const vfloat8& tnear, const vfloat8& tfar, vfloat8& dist)
|
||||
{
|
||||
#if defined(__AVX2__)
|
||||
const vfloat8 tNearX = msub(vfloat8::load((float*)((const char*)&node->lower_x+ray.nearX)), ray.rdir.x, ray.org_rdir.x);
|
||||
@@ -214,10 +214,10 @@ namespace embree
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__AVX512F__) && !defined(__AVX512VL__) // KNL
|
||||
#if defined(__AVX512F__)
|
||||
|
||||
template<>
|
||||
__forceinline size_t intersectNode<4,16>(const typename BVH4::AlignedNode* node, const TravRay<4,16>& ray, const vfloat16& tnear, const vfloat16& tfar, vfloat16& dist)
|
||||
__forceinline size_t intersectNode<4,16>(const typename BVH4::AlignedNode* node, const TravRay<4,16>& ray, const vfloat16& tnear, const vfloat16& tfar, vfloat16& dist)
|
||||
{
|
||||
const vfloat16 tNearX = msub(vfloat16(*(vfloat4*)((const char*)&node->lower_x+ray.nearX)), ray.rdir.x, ray.org_rdir.x);
|
||||
const vfloat16 tNearY = msub(vfloat16(*(vfloat4*)((const char*)&node->lower_x+ray.nearY)), ray.rdir.y, ray.org_rdir.y);
|
||||
@@ -234,8 +234,9 @@ namespace embree
|
||||
}
|
||||
|
||||
template<>
|
||||
__forceinline size_t intersectNode<8,16>(const typename BVH8::AlignedNode* node, const TravRay<8,16>& ray, const vfloat16& tnear, const vfloat16& tfar, vfloat16& dist)
|
||||
__forceinline size_t intersectNode<8,16>(const typename BVH8::AlignedNode* node, const TravRay<8,16>& ray, const vfloat16& tnear, const vfloat16& tfar, vfloat16& dist)
|
||||
{
|
||||
#if defined(__AVX512ER__)
|
||||
const vllong8 invalid((size_t)BVH8::emptyNode);
|
||||
const vboold8 m_valid(invalid != vllong8::loadu(node->children));
|
||||
const vfloat16 bminmaxX = permute(vfloat16::load((const float*)&node->lower_x), ray.permX);
|
||||
@@ -247,7 +248,19 @@ 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));
|
||||
const size_t mask = movemask(vmask);
|
||||
#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);
|
||||
dist = tNear;
|
||||
return mask;
|
||||
}
|
||||
@@ -255,10 +268,10 @@ namespace embree
|
||||
#endif
|
||||
|
||||
template<int N, int K>
|
||||
__forceinline vbool<K> intersectNode(const typename BVHN<N>::AlignedNode* node, size_t i,
|
||||
const Vec3vf<K>& org, const Vec3vf<K>& dir, const Vec3vf<K>& rdir, const Vec3vf<K>& org_rdir,
|
||||
const vfloat<K>& tnear, const vfloat<K>& tfar, vfloat<K>& dist)
|
||||
|
||||
__forceinline vbool<K> intersectNode(const typename BVHN<N>::AlignedNode* node, size_t i,
|
||||
const Vec3vf<K>& org, const Vec3vf<K>& dir, const Vec3vf<K>& rdir, const Vec3vf<K>& org_rdir,
|
||||
const vfloat<K>& tnear, const vfloat<K>& tfar, vfloat<K>& dist)
|
||||
|
||||
{
|
||||
#if defined(__AVX2__)
|
||||
const vfloat<K> lclipMinX = msub(node->lower_x[i],rdir.x,org_rdir.x);
|
||||
@@ -306,8 +319,8 @@ namespace embree
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<int N,int Nx>
|
||||
__forceinline size_t intersectNodeRobust(const typename BVHN<N>::AlignedNode* node, const TravRay<N,Nx>& ray,
|
||||
const vfloat<Nx>& tnear, const vfloat<Nx>& tfar, vfloat<Nx>& dist)
|
||||
__forceinline size_t intersectNodeRobust(const typename BVHN<N>::AlignedNode* node, const TravRay<N,Nx>& ray,
|
||||
const vfloat<Nx>& tnear, const vfloat<Nx>& tfar, vfloat<Nx>& dist)
|
||||
{
|
||||
const vfloat<N> tNearX = (vfloat<N>::load((float*)((const char*)&node->lower_x+ray.nearX)) - ray.org.x) * ray.rdir.x;
|
||||
const vfloat<N> tNearY = (vfloat<N>::load((float*)((const char*)&node->lower_x+ray.nearY)) - ray.org.y) * ray.rdir.y;
|
||||
@@ -325,11 +338,11 @@ namespace embree
|
||||
return mask;
|
||||
}
|
||||
|
||||
#if defined(__AVX512F__) && !defined(__AVX512VL__) // KNL
|
||||
#if defined(__AVX512F__)
|
||||
|
||||
template<>
|
||||
__forceinline size_t intersectNodeRobust<4,16>(const typename BVHN<4>::AlignedNode* node, const TravRay<4,16>& ray,
|
||||
const vfloat<16>& tnear, const vfloat<16>& tfar, vfloat<16>& dist)
|
||||
__forceinline size_t intersectNodeRobust<4,16>(const typename BVHN<4>::AlignedNode* node, const TravRay<4,16>& ray,
|
||||
const vfloat<16>& tnear, const vfloat<16>& tfar, vfloat<16>& dist)
|
||||
{
|
||||
const vfloat16 tNearX = (vfloat16(*(vfloat<4>*)((const char*)&node->lower_x+ray.nearX)) - ray.org.x) * ray.rdir.x;
|
||||
const vfloat16 tNearY = (vfloat16(*(vfloat<4>*)((const char*)&node->lower_x+ray.nearY)) - ray.org.y) * ray.rdir.y;
|
||||
@@ -348,8 +361,8 @@ namespace embree
|
||||
}
|
||||
|
||||
template<>
|
||||
__forceinline size_t intersectNodeRobust<8,16>(const typename BVHN<8>::AlignedNode* node, const TravRay<8,16>& ray,
|
||||
const vfloat<16>& tnear, const vfloat<16>& tfar, vfloat<16>& dist)
|
||||
__forceinline size_t intersectNodeRobust<8,16>(const typename BVHN<8>::AlignedNode* node, const TravRay<8,16>& ray,
|
||||
const vfloat<16>& tnear, const vfloat<16>& tfar, vfloat<16>& dist)
|
||||
{
|
||||
const vfloat16 tNearX = (vfloat16(*(vfloat<8>*)((const char*)&node->lower_x+ray.nearX)) - ray.org.x) * ray.rdir.x;
|
||||
const vfloat16 tNearY = (vfloat16(*(vfloat<8>*)((const char*)&node->lower_x+ray.nearY)) - ray.org.y) * ray.rdir.y;
|
||||
@@ -370,9 +383,9 @@ namespace embree
|
||||
#endif
|
||||
|
||||
template<int N, int K>
|
||||
__forceinline vbool<K> intersectNodeRobust(const typename BVHN<N>::AlignedNode* node, size_t i,
|
||||
const Vec3vf<K>& org, const Vec3vf<K>& dir, const Vec3vf<K>& rdir, const Vec3vf<K>& org_rdir,
|
||||
const vfloat<K>& tnear, const vfloat<K>& tfar, vfloat<K>& dist)
|
||||
__forceinline vbool<K> intersectNodeRobust(const typename BVHN<N>::AlignedNode* node, size_t i,
|
||||
const Vec3vf<K>& org, const Vec3vf<K>& dir, const Vec3vf<K>& rdir, const Vec3vf<K>& org_rdir,
|
||||
const vfloat<K>& tnear, const vfloat<K>& tfar, vfloat<K>& dist)
|
||||
{
|
||||
// FIXME: use per instruction rounding for AVX512
|
||||
const vfloat<K> lclipMinX = (node->lower_x[i] - org.x) * rdir.x;
|
||||
@@ -395,7 +408,7 @@ namespace embree
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<int N>
|
||||
__forceinline size_t intersectNode(const typename BVHN<N>::AlignedNodeMB* node, const TravRay<N,N>& ray, const vfloat<N>& tnear, const vfloat<N>& tfar, const float time, vfloat<N>& dist)
|
||||
__forceinline size_t intersectNode(const typename BVHN<N>::AlignedNodeMB* node, const TravRay<N,N>& ray, const vfloat<N>& tnear, const vfloat<N>& tfar, const float time, vfloat<N>& dist)
|
||||
{
|
||||
const vfloat<N>* pNearX = (const vfloat<N>*)((const char*)&node->lower_x+ray.nearX);
|
||||
const vfloat<N>* pNearY = (const vfloat<N>*)((const char*)&node->lower_x+ray.nearY);
|
||||
@@ -496,7 +509,7 @@ namespace embree
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<int N>
|
||||
__forceinline size_t intersectNodeRobust(const typename BVHN<N>::AlignedNodeMB* node, const TravRay<N,N>& ray, const vfloat<N>& tnear, const vfloat<N>& tfar, const float time, vfloat<N>& dist)
|
||||
__forceinline size_t intersectNodeRobust(const typename BVHN<N>::AlignedNodeMB* node, const TravRay<N,N>& ray, const vfloat<N>& tnear, const vfloat<N>& tfar, const float time, vfloat<N>& dist)
|
||||
{
|
||||
const vfloat<N>* pNearX = (const vfloat<N>*)((const char*)&node->lower_x+ray.nearX);
|
||||
const vfloat<N>* pNearY = (const vfloat<N>*)((const char*)&node->lower_x+ray.nearY);
|
||||
@@ -566,8 +579,8 @@ namespace embree
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<int N>
|
||||
__forceinline size_t intersectNodeMB4D(const typename BVHN<N>::NodeRef ref, const TravRay<N,N>& ray,
|
||||
const vfloat<N>& tnear, const vfloat<N>& tfar, const float time, vfloat<N>& dist)
|
||||
__forceinline size_t intersectNodeMB4D(const typename BVHN<N>::NodeRef ref, const TravRay<N,N>& ray,
|
||||
const vfloat<N>& tnear, const vfloat<N>& tfar, const float time, vfloat<N>& dist)
|
||||
{
|
||||
const typename BVHN<N>::AlignedNodeMB* node = ref.alignedNodeMB();
|
||||
|
||||
@@ -655,8 +668,8 @@ namespace embree
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<int N>
|
||||
__forceinline size_t intersectNodeMB4DRobust(const typename BVHN<N>::NodeRef ref, const TravRay<N,N>& ray,
|
||||
const vfloat<N>& tnear, const vfloat<N>& tfar, const float time, vfloat<N>& dist)
|
||||
__forceinline size_t intersectNodeMB4DRobust(const typename BVHN<N>::NodeRef ref, const TravRay<N,N>& ray,
|
||||
const vfloat<N>& tnear, const vfloat<N>& tfar, const float time, vfloat<N>& dist)
|
||||
{
|
||||
const typename BVHN<N>::AlignedNodeMB* node = ref.alignedNodeMB();
|
||||
|
||||
@@ -687,9 +700,9 @@ namespace embree
|
||||
}
|
||||
|
||||
template<int N, int K>
|
||||
__forceinline vbool<K> intersectNodeMB4DRobust(const typename BVHN<N>::NodeRef ref, const size_t i,
|
||||
const Vec3vf<K>& org, const Vec3vf<K>& dir, const Vec3vf<K>& rdir, const Vec3vf<K>& org_rdir,
|
||||
const vfloat<K>& tnear, const vfloat<K>& tfar, const vfloat<K>& time, vfloat<K>& dist)
|
||||
__forceinline vbool<K> intersectNodeMB4DRobust(const typename BVHN<N>::NodeRef ref, const size_t i,
|
||||
const Vec3vf<K>& org, const Vec3vf<K>& dir, const Vec3vf<K>& rdir, const Vec3vf<K>& org_rdir,
|
||||
const vfloat<K>& tnear, const vfloat<K>& tfar, const vfloat<K>& time, vfloat<K>& dist)
|
||||
{
|
||||
const typename BVHN<N>::AlignedNodeMB* node = ref.alignedNodeMB();
|
||||
|
||||
@@ -726,10 +739,10 @@ namespace embree
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<int N, int Nx>
|
||||
__forceinline size_t intersectNode(const typename BVHN<N>::QuantizedNode* node, const TravRay<N,Nx>& ray, const vfloat<Nx>& tnear, const vfloat<Nx>& tfar, vfloat<Nx>& dist);
|
||||
__forceinline size_t intersectNode(const typename BVHN<N>::QuantizedNode* node, const TravRay<N,Nx>& ray, const vfloat<Nx>& tnear, const vfloat<Nx>& tfar, vfloat<Nx>& dist);
|
||||
|
||||
template<>
|
||||
__forceinline size_t intersectNode<4,4>(const typename BVH4::QuantizedNode* node, const TravRay<4,4>& ray, const vfloat4& tnear, const vfloat4& tfar, vfloat4& dist)
|
||||
__forceinline size_t intersectNode<4,4>(const typename BVH4::QuantizedNode* node, const TravRay<4,4>& ray, const vfloat4& tnear, const vfloat4& tfar, vfloat4& dist)
|
||||
{
|
||||
const vfloat4 start_x(node->start.x);
|
||||
const vfloat4 scale_x(node->scale.x);
|
||||
@@ -783,7 +796,7 @@ namespace embree
|
||||
#if defined(__AVX__)
|
||||
|
||||
template<>
|
||||
__forceinline size_t intersectNode<8,8>(const typename BVH8::QuantizedNode* node, const TravRay<8,8>& ray, const vfloat8& tnear, const vfloat8& tfar, vfloat8& dist)
|
||||
__forceinline size_t intersectNode<8,8>(const typename BVH8::QuantizedNode* node, const TravRay<8,8>& ray, const vfloat8& tnear, const vfloat8& tfar, vfloat8& dist)
|
||||
{
|
||||
const vfloat8 start_x(node->start.x);
|
||||
const vfloat8 scale_x(node->scale.x);
|
||||
@@ -836,10 +849,10 @@ namespace embree
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__AVX512F__) && !defined(__AVX512VL__) // KNL
|
||||
#if defined(__AVX512F__)
|
||||
|
||||
template<>
|
||||
__forceinline size_t intersectNode<4,16>(const typename BVH4::QuantizedNode* node, const TravRay<4,16>& ray, const vfloat16& tnear, const vfloat16& tfar, vfloat16& dist)
|
||||
__forceinline size_t intersectNode<4,16>(const typename BVH4::QuantizedNode* node, const TravRay<4,16>& ray, const vfloat16& tnear, const vfloat16& tfar, vfloat16& dist)
|
||||
{
|
||||
const vfloat16 start_x(node->start.x);
|
||||
const vfloat16 scale_x(node->scale.x);
|
||||
@@ -869,8 +882,9 @@ namespace embree
|
||||
}
|
||||
|
||||
template<>
|
||||
__forceinline size_t intersectNode<8,16>(const typename BVH8::QuantizedNode* node, const TravRay<8,16>& ray, const vfloat16& tnear, const vfloat16& tfar, vfloat16& dist)
|
||||
__forceinline size_t intersectNode<8,16>(const typename BVH8::QuantizedNode* node, const TravRay<8,16>& ray, const vfloat16& tnear, const vfloat16& tfar, vfloat16& dist)
|
||||
{
|
||||
#if defined(__AVX512ER__)
|
||||
const vllong8 invalid((size_t)BVH8::emptyNode);
|
||||
const vboold8 m_valid(invalid != vllong8::loadu(node->children));
|
||||
const vfloat16 bminmaxX = node->dequantizeLowerUpperX<16>(ray.permX);
|
||||
@@ -882,7 +896,31 @@ 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));
|
||||
const size_t mask = movemask(vmask);
|
||||
#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);
|
||||
dist = tNear;
|
||||
return mask;
|
||||
}
|
||||
@@ -894,8 +932,8 @@ namespace embree
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<int N>
|
||||
__forceinline size_t intersectNode(const typename BVHN<N>::UnalignedNode* node, const TravRay<N,N>& ray,
|
||||
const vfloat<N>& tnear, const vfloat<N>& tfar, vfloat<N>& dist)
|
||||
__forceinline size_t intersectNode(const typename BVHN<N>::UnalignedNode* node, const TravRay<N,N>& ray,
|
||||
const vfloat<N>& tnear, const vfloat<N>& tfar, vfloat<N>& dist)
|
||||
{
|
||||
const Vec3vf<N> dir = xfmVector(node->naabb,ray.dir);
|
||||
//const Vec3vf<N> nrdir = Vec3vf<N>(vfloat<N>(-1.0f))/dir;
|
||||
@@ -918,9 +956,9 @@ namespace embree
|
||||
}
|
||||
|
||||
template<int N, int K>
|
||||
__forceinline vbool<K> intersectNode(const typename BVHN<N>::UnalignedNode* node, const size_t i,
|
||||
const Vec3vf<K>& org_i, const Vec3vf<K>& dir_i, const Vec3vf<K>& rdir_i, const Vec3vf<K>& org_rdir_i,
|
||||
const vfloat<K>& tnear, const vfloat<K>& tfar, vfloat<K>& dist)
|
||||
__forceinline vbool<K> intersectNode(const typename BVHN<N>::UnalignedNode* node, const size_t i,
|
||||
const Vec3vf<K>& org_i, const Vec3vf<K>& dir_i, const Vec3vf<K>& rdir_i, const Vec3vf<K>& org_rdir_i,
|
||||
const vfloat<K>& tnear, const vfloat<K>& tfar, vfloat<K>& dist)
|
||||
{
|
||||
const AffineSpace3vf<K> naabb(Vec3f(node->naabb.l.vx.x[i],node->naabb.l.vx.y[i],node->naabb.l.vx.z[i]),
|
||||
Vec3f(node->naabb.l.vy.x[i],node->naabb.l.vy.y[i],node->naabb.l.vy.z[i]),
|
||||
@@ -950,8 +988,8 @@ namespace embree
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<int N>
|
||||
__forceinline size_t intersectNode(const typename BVHN<N>::UnalignedNodeMB* node, const TravRay<N,N>& ray,
|
||||
const vfloat<N>& tnear, const vfloat<N>& tfar, const float time, vfloat<N>& dist)
|
||||
__forceinline size_t intersectNode(const typename BVHN<N>::UnalignedNodeMB* node, const TravRay<N,N>& ray,
|
||||
const vfloat<N>& tnear, const vfloat<N>& tfar, const float time, vfloat<N>& dist)
|
||||
{
|
||||
const AffineSpace3vf<N> xfm = node->space0;
|
||||
const Vec3vf<N> b0_lower = zero;
|
||||
@@ -981,9 +1019,9 @@ namespace embree
|
||||
}
|
||||
|
||||
template<int N, int K>
|
||||
__forceinline vbool<K> intersectNode(const typename BVHN<N>::UnalignedNodeMB* node, const size_t i,
|
||||
const Vec3vf<K>& org_i, const Vec3vf<K>& dir_i, const Vec3vf<K>& rdir_i, const Vec3vf<K>& org_rdir_i,
|
||||
const vfloat<K>& tnear, const vfloat<K>& tfar, const vfloat<K>& time, vfloat<K>& dist)
|
||||
__forceinline vbool<K> intersectNode(const typename BVHN<N>::UnalignedNodeMB* node, const size_t i,
|
||||
const Vec3vf<K>& org_i, const Vec3vf<K>& dir_i, const Vec3vf<K>& rdir_i, const Vec3vf<K>& org_rdir_i,
|
||||
const vfloat<K>& tnear, const vfloat<K>& tfar, const vfloat<K>& time, vfloat<K>& dist)
|
||||
{
|
||||
const AffineSpace3vf<K> xfm(Vec3f(node->space0.l.vx.x[i],node->space0.l.vx.y[i],node->space0.l.vx.z[i]),
|
||||
Vec3f(node->space0.l.vy.x[i],node->space0.l.vy.y[i],node->space0.l.vy.z[i]),
|
||||
@@ -1024,7 +1062,7 @@ namespace embree
|
||||
struct BVHNNodeIntersector1;
|
||||
|
||||
template<int N, int Nx>
|
||||
struct BVHNNodeIntersector1<N,Nx,BVH_AN1,false>
|
||||
struct BVHNNodeIntersector1<N,Nx,BVH_AN1,false>
|
||||
{
|
||||
static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,Nx>& ray, const vfloat<Nx>& tnear, const vfloat<Nx>& tfar, const float time, vfloat<Nx>& dist, size_t& mask)
|
||||
{
|
||||
@@ -1035,7 +1073,7 @@ namespace embree
|
||||
};
|
||||
|
||||
template<int N, int Nx>
|
||||
struct BVHNNodeIntersector1<N,Nx,BVH_AN1,true>
|
||||
struct BVHNNodeIntersector1<N,Nx,BVH_AN1,true>
|
||||
{
|
||||
static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,Nx>& ray, const vfloat<Nx>& tnear, const vfloat<Nx>& tfar, const float time, vfloat<Nx>& dist, size_t& mask)
|
||||
{
|
||||
@@ -1046,7 +1084,7 @@ namespace embree
|
||||
};
|
||||
|
||||
template<int N, int Nx>
|
||||
struct BVHNNodeIntersector1<N,Nx,BVH_AN2,false>
|
||||
struct BVHNNodeIntersector1<N,Nx,BVH_AN2,false>
|
||||
{
|
||||
static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,Nx>& ray, const vfloat<N>& tnear, const vfloat<N>& tfar, const float time, vfloat<N>& dist, size_t& mask)
|
||||
{
|
||||
@@ -1057,7 +1095,7 @@ namespace embree
|
||||
};
|
||||
|
||||
template<int N, int Nx>
|
||||
struct BVHNNodeIntersector1<N,Nx,BVH_AN2,true>
|
||||
struct BVHNNodeIntersector1<N,Nx,BVH_AN2,true>
|
||||
{
|
||||
static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,Nx>& ray, const vfloat<N>& tnear, const vfloat<N>& tfar, const float time, vfloat<N>& dist, size_t& mask)
|
||||
{
|
||||
@@ -1068,7 +1106,7 @@ namespace embree
|
||||
};
|
||||
|
||||
template<int N, int Nx>
|
||||
struct BVHNNodeIntersector1<N,Nx,BVH_AN2_AN4D,false>
|
||||
struct BVHNNodeIntersector1<N,Nx,BVH_AN2_AN4D,false>
|
||||
{
|
||||
static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,Nx>& ray, const vfloat<N>& tnear, const vfloat<N>& tfar, const float time, vfloat<N>& dist, size_t& mask)
|
||||
{
|
||||
@@ -1079,7 +1117,7 @@ namespace embree
|
||||
};
|
||||
|
||||
template<int N, int Nx>
|
||||
struct BVHNNodeIntersector1<N,Nx,BVH_AN2_AN4D,true>
|
||||
struct BVHNNodeIntersector1<N,Nx,BVH_AN2_AN4D,true>
|
||||
{
|
||||
static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,Nx>& ray, const vfloat<N>& tnear, const vfloat<N>& tfar, const float time, vfloat<N>& dist, size_t& mask)
|
||||
{
|
||||
@@ -1090,7 +1128,7 @@ namespace embree
|
||||
};
|
||||
|
||||
template<int N, int Nx>
|
||||
struct BVHNNodeIntersector1<N,Nx,BVH_AN1_UN1,false>
|
||||
struct BVHNNodeIntersector1<N,Nx,BVH_AN1_UN1,false>
|
||||
{
|
||||
static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,Nx>& ray, const vfloat<N>& tnear, const vfloat<N>& tfar, const float time, vfloat<N>& dist, size_t& mask)
|
||||
{
|
||||
@@ -1102,7 +1140,7 @@ namespace embree
|
||||
};
|
||||
|
||||
template<int N, int Nx>
|
||||
struct BVHNNodeIntersector1<N,Nx,BVH_AN2_UN2,false>
|
||||
struct BVHNNodeIntersector1<N,Nx,BVH_AN2_UN2,false>
|
||||
{
|
||||
static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,Nx>& ray, const vfloat<N>& tnear, const vfloat<N>& tfar, const float time, vfloat<N>& dist, size_t& mask)
|
||||
{
|
||||
@@ -1114,7 +1152,7 @@ namespace embree
|
||||
};
|
||||
|
||||
template<int N, int Nx>
|
||||
struct BVHNNodeIntersector1<N,Nx,BVH_AN2_AN4D_UN2,false>
|
||||
struct BVHNNodeIntersector1<N,Nx,BVH_AN2_AN4D_UN2,false>
|
||||
{
|
||||
static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,Nx>& ray, const vfloat<N>& tnear, const vfloat<N>& tfar, const float time, vfloat<N>& dist, size_t& mask)
|
||||
{
|
||||
@@ -1126,7 +1164,7 @@ namespace embree
|
||||
};
|
||||
|
||||
template<int N, int Nx>
|
||||
struct BVHNNodeIntersector1<N,Nx,BVH_TN_AN1,false>
|
||||
struct BVHNNodeIntersector1<N,Nx,BVH_TN_AN1,false>
|
||||
{
|
||||
static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,Nx>& ray, const vfloat<N>& tnear, const vfloat<N>& tfar, const float time, vfloat<N>& dist, size_t& mask)
|
||||
{
|
||||
@@ -1137,7 +1175,7 @@ namespace embree
|
||||
};
|
||||
|
||||
template<int N, int Nx>
|
||||
struct BVHNNodeIntersector1<N,Nx,BVH_TN_AN1_AN2,false>
|
||||
struct BVHNNodeIntersector1<N,Nx,BVH_TN_AN1_AN2,false>
|
||||
{
|
||||
static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,Nx>& ray, const vfloat<N>& tnear, const vfloat<N>& tfar, const float time, vfloat<N>& dist, size_t& mask)
|
||||
{
|
||||
@@ -1149,7 +1187,7 @@ namespace embree
|
||||
};
|
||||
|
||||
template<int N, int Nx>
|
||||
struct BVHNNodeIntersector1<N,Nx,BVH_QN1,false>
|
||||
struct BVHNNodeIntersector1<N,Nx,BVH_QN1,false>
|
||||
{
|
||||
static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,Nx>& ray, const vfloat<Nx>& tnear, const vfloat<Nx>& tfar, const float time, vfloat<Nx>& dist, size_t& mask)
|
||||
{
|
||||
@@ -1160,7 +1198,7 @@ namespace embree
|
||||
};
|
||||
|
||||
template<int N, int Nx>
|
||||
struct BVHNNodeIntersector1<N,Nx,BVH_QN1,true>
|
||||
struct BVHNNodeIntersector1<N,Nx,BVH_QN1,true>
|
||||
{
|
||||
static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const TravRay<N,Nx>& ray, const vfloat<Nx>& tnear, const vfloat<Nx>& tfar, const float time, vfloat<Nx>& dist, size_t& mask)
|
||||
{
|
||||
@@ -1177,10 +1215,6 @@ namespace embree
|
||||
template<int N, int K>
|
||||
struct BVHNNodeIntersectorK<N,K,BVH_AN1,false>
|
||||
{
|
||||
/* vmask is both an input and an output parameter! Its initial value should be the parent node
|
||||
hit mask, which is used for correctly computing the current hit mask. The parent hit mask
|
||||
is actually required only for motion blur node intersections (because different rays may
|
||||
have different times), so for regular nodes vmask is simply overwritten. */
|
||||
static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const size_t i, const Vec3vf<K>& org, const Vec3vf<K>& dir, const Vec3vf<K>& rdir, const Vec3vf<K>& org_rdir,
|
||||
const vfloat<K>& tnear, const vfloat<K>& tfar, const vfloat<K>& time, vfloat<K>& dist, vbool<K>& vmask)
|
||||
{
|
||||
@@ -1190,7 +1224,7 @@ namespace embree
|
||||
};
|
||||
|
||||
template<int N, int K>
|
||||
struct BVHNNodeIntersectorK<N,K,BVH_AN1,true>
|
||||
struct BVHNNodeIntersectorK<N,K,BVH_AN1,true>
|
||||
{
|
||||
static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const size_t i, const Vec3vf<K>& org, const Vec3vf<K>& dir, const Vec3vf<K>& rdir, const Vec3vf<K>& org_rdir,
|
||||
const vfloat<K>& tnear, const vfloat<K>& tfar, const vfloat<K>& time, vfloat<K>& dist, vbool<K>& vmask)
|
||||
@@ -1223,7 +1257,7 @@ namespace embree
|
||||
};
|
||||
|
||||
template<int N, int K>
|
||||
struct BVHNNodeIntersectorK<N,K,BVH_AN1_UN1,false>
|
||||
struct BVHNNodeIntersectorK<N,K,BVH_AN1_UN1,false>
|
||||
{
|
||||
static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const size_t i,
|
||||
const Vec3vf<K>& org, const Vec3vf<K>& dir, const Vec3vf<K>& rdir, const Vec3vf<K>& org_rdir,
|
||||
@@ -1236,7 +1270,7 @@ namespace embree
|
||||
};
|
||||
|
||||
template<int N, int K>
|
||||
struct BVHNNodeIntersectorK<N,K,BVH_AN2_UN2,false>
|
||||
struct BVHNNodeIntersectorK<N,K,BVH_AN2_UN2,false>
|
||||
{
|
||||
static __forceinline bool intersect(const typename BVHN<N>::NodeRef& node, const size_t i,
|
||||
const Vec3vf<K>& org, const Vec3vf<K>& dir, const Vec3vf<K>& rdir, const Vec3vf<K>& org_rdir,
|
||||
@@ -1279,11 +1313,10 @@ namespace embree
|
||||
const Vec3vf<K>& org, const Vec3vf<K>& dir, const Vec3vf<K>& rdir, const Vec3vf<K>& org_rdir,
|
||||
const vfloat<K>& tnear, const vfloat<K>& tfar, const vfloat<K>& time, vfloat<K>& dist, vbool<K>& vmask)
|
||||
{
|
||||
if (likely(node.isAlignedNodeMB() || node.isAlignedNodeMB4D())) {
|
||||
if (likely(node.isAlignedNodeMB() || node.isAlignedNodeMB4D()))
|
||||
vmask &= intersectNodeMB4D<N,K>(node,i,org,dir,rdir,org_rdir,tnear,tfar,time,dist);
|
||||
} else /*if (unlikely(node.isUnalignedNodeMB()))*/ {
|
||||
assert(node.isUnalignedNodeMB());
|
||||
vmask &= intersectNode<N,K>(node.unalignedNodeMB(),i,org,dir,rdir,org_rdir,tnear,tfar,time,dist);
|
||||
else /*if (unlikely(node.isUnalignedNodeMB()))*/ {
|
||||
assert(node.isUnalignedNodeMB()); vmask &= intersectNode<N,K>(node.unalignedNodeMB(),i,org,dir,rdir,org_rdir,tnear,tfar,time,dist);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -34,24 +34,36 @@
|
||||
#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>::intersect(Accel::Intersectors* __restrict__ This,
|
||||
RayK<K>** inputPackets, size_t numOctantRays, IntersectContext* context)
|
||||
__forceinline void BVHNIntersectorStream<N, Nx, K, types, robust, PrimitiveIntersector>::intersectCoherent(BVH* __restrict__ bvh, RayK<K>** inputRays, 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);
|
||||
|
||||
__aligned(64) Packet<K,robust> packet[MAX_INTERNAL_STREAM_SIZE/K];
|
||||
__aligned(64) Frustum<N,Nx,K,robust> frusta;
|
||||
RayK<K>** __restrict__ inputPackets = (RayK<K>**)inputRays;
|
||||
assert(numOctantRays <= MAX_RAYS);
|
||||
|
||||
__aligned(64) Packet packet[MAX_RAYS/K];
|
||||
__aligned(64) Frusta frusta;
|
||||
|
||||
bool commonOctant = true;
|
||||
const size_t m_active = initPacketsAndFrusta<false>(inputPackets, numOctantRays, packet, frusta, commonOctant);
|
||||
@@ -62,7 +74,7 @@ namespace embree
|
||||
{
|
||||
const size_t numPackets = (numOctantRays+K-1)/K;
|
||||
for (size_t i = 0; i < numPackets; i++)
|
||||
This->intersect(inputPackets[i]->tnear <= inputPackets[i]->tfar,*inputPackets[i],context);
|
||||
bvh->scene->intersect(inputPackets[i]->tnear <= inputPackets[i]->tfar,*inputPackets[i],context);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -74,6 +86,8 @@ namespace embree
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const NearFarPreCompute pc(frusta.min_rdir);
|
||||
|
||||
StackItemMaskCoherent* stackPtr = stack + 1;
|
||||
|
||||
while (1) pop:
|
||||
@@ -97,7 +111,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, frusta, maskK, dist);
|
||||
const size_t m_node_hit = traverseCoherentStream(m_trav_active, packet, node, pc, 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);
|
||||
@@ -116,12 +130,25 @@ namespace embree
|
||||
break;
|
||||
}
|
||||
assert(b < N);
|
||||
char *ptr = (char*)&node->lower_x + b*sizeof(float);
|
||||
assert(cur == node->child(b));
|
||||
m_trav_active = intersectAlignedNodePacket(packet, node, b, frusta.nf, m_trav_active);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/*! this is a leaf node */
|
||||
/*! 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 */
|
||||
STAT3(normal.trav_leaves, 1, 1, 1);
|
||||
size_t num; Primitive* prim = (Primitive*)cur.leaf(num);
|
||||
|
||||
@@ -139,7 +166,7 @@ namespace embree
|
||||
assert(m_isec & bits);
|
||||
bits &= ~m_isec;
|
||||
|
||||
Packet<K,robust> &p = packet[i];
|
||||
Packet &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);
|
||||
@@ -149,184 +176,20 @@ namespace embree
|
||||
}
|
||||
|
||||
template<int N, int Nx, int K, int types, bool robust, typename PrimitiveIntersector>
|
||||
__forceinline void BVHNIntersectorStream<N, Nx, K, types, robust, PrimitiveIntersector>::occluded(Accel::Intersectors* __restrict__ This,
|
||||
RayK<K>** inputPackets, size_t numOctantRays, IntersectContext* context)
|
||||
__forceinline void BVHNIntersectorStream<N, Nx, K, types, robust, PrimitiveIntersector>::occludedCoherent(BVH* __restrict__ bvh, RayK<K>** inputRays, size_t numOctantRays, IntersectContext* context)
|
||||
{
|
||||
BVH* __restrict__ bvh = (BVH*) This->ptr;
|
||||
assert(numOctantRays <= MAX_INTERNAL_STREAM_SIZE);
|
||||
__aligned(64) StackItemMaskCoherent stack[stackSizeSingle]; //!< stack of nodes
|
||||
|
||||
RayK<K>** __restrict__ inputPackets = (RayK<K>**)inputRays;
|
||||
assert(numOctantRays <= MAX_RAYS);
|
||||
|
||||
/* inactive rays should have been filtered out before */
|
||||
#if 1
|
||||
__aligned(64) Packet<K,false> packet[MAX_INTERNAL_STREAM_SIZE/K];
|
||||
|
||||
assert(numOctantRays <= 32);
|
||||
const size_t numPackets = (numOctantRays+K-1)/K;
|
||||
size_t m_active = 0;
|
||||
for (size_t i = 0; i < numPackets; i++)
|
||||
{
|
||||
const vfloat<K> tnear = inputPackets[i]->tnear;
|
||||
const vfloat<K> tfar = inputPackets[i]->tfar;
|
||||
vbool<K> m_valid = (tnear <= tfar) & (tnear >= 0.0f);
|
||||
m_active |= (size_t)movemask(m_valid) << (K*i);
|
||||
const Vec3vf<K>& org = inputPackets[i]->org;
|
||||
const Vec3vf<K>& dir = inputPackets[i]->dir;
|
||||
vfloat<K> packet_min_dist = max(tnear, 0.0f);
|
||||
vfloat<K> packet_max_dist = select(m_valid, tfar, neg_inf);
|
||||
new (&packet[i]) Packet<K,false>(org,dir,packet_min_dist,packet_max_dist);
|
||||
}
|
||||
|
||||
const int shiftTable[32] = {
|
||||
(int)1 << 0, (int)1 << 1, (int)1 << 2, (int)1 << 3, (int)1 << 4, (int)1 << 5, (int)1 << 6, (int)1 << 7,
|
||||
(int)1 << 8, (int)1 << 9, (int)1 << 10, (int)1 << 11, (int)1 << 12, (int)1 << 13, (int)1 << 14, (int)1 << 15,
|
||||
(int)1 << 16, (int)1 << 17, (int)1 << 18, (int)1 << 19, (int)1 << 20, (int)1 << 21, (int)1 << 22, (int)1 << 23,
|
||||
(int)1 << 24, (int)1 << 25, (int)1 << 26, (int)1 << 27, (int)1 << 28, (int)1 << 29, (int)1 << 30, (int)1 << 31
|
||||
};
|
||||
|
||||
StackItemT<NodeRef> stack[stackSizeSingle]; //!< stack of nodes
|
||||
StackItemT<NodeRef>* stackPtr = stack + 1; //!< current stack pointer
|
||||
stack[0].ptr = bvh->root;
|
||||
stack[0].dist = m_active;
|
||||
|
||||
size_t terminated = ~m_active;
|
||||
|
||||
while (1) pop:
|
||||
{
|
||||
if (unlikely(stackPtr == stack)) break;
|
||||
STAT3(shadow.trav_stack_pop,1,1,1);
|
||||
stackPtr--;
|
||||
NodeRef cur = NodeRef(stackPtr->ptr);
|
||||
size_t cur_mask = (size_t)stackPtr->dist & (~terminated);
|
||||
if (unlikely(cur_mask == 0)) continue;
|
||||
|
||||
while (true)
|
||||
{
|
||||
|
||||
/*! stop if we found a leaf node */
|
||||
if (unlikely(cur.isLeaf())) break;
|
||||
const AlignedNode* __restrict__ const node = cur.alignedNode();
|
||||
|
||||
const vfloat<Nx> bminX = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_x));
|
||||
const vfloat<Nx> bmaxX = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->upper_x));
|
||||
const vfloat<Nx> bminY = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_y));
|
||||
const vfloat<Nx> bmaxY = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->upper_y));
|
||||
const vfloat<Nx> bminZ = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->lower_z));
|
||||
const vfloat<Nx> bmaxZ = vfloat<Nx>(*(const vfloat<N>*)((const char*)&node->upper_z));
|
||||
|
||||
size_t bits = cur_mask;
|
||||
#if defined(__AVX__)
|
||||
//STAT3(shadow.trav_hit_boxes[__popcnt(cur_mask)],1,1,1);
|
||||
#endif
|
||||
|
||||
assert(bits);
|
||||
vint<Nx> vmask(zero);
|
||||
do
|
||||
{
|
||||
STAT3(shadow.trav_nodes,1,1,1);
|
||||
|
||||
const size_t rayID = __bscf(bits);
|
||||
assert(rayID < MAX_INTERNAL_STREAM_SIZE);
|
||||
assert(rayID /K < numPackets);
|
||||
Packet<K,false> &p = packet[rayID /K];
|
||||
const size_t i = rayID % K;
|
||||
const vint<Nx> bitmask(shiftTable[rayID]);
|
||||
|
||||
const vfloat<Nx> tNearX = msub(bminX, p.rdir.x[i], p.org_rdir.x[i]);
|
||||
const vfloat<Nx> tNearY = msub(bminY, p.rdir.y[i], p.org_rdir.y[i]);
|
||||
const vfloat<Nx> tNearZ = msub(bminZ, p.rdir.z[i], p.org_rdir.z[i]);
|
||||
const vfloat<Nx> tFarX = msub(bmaxX, p.rdir.x[i], p.org_rdir.x[i]);
|
||||
const vfloat<Nx> tFarY = msub(bmaxY, p.rdir.y[i], p.org_rdir.y[i]);
|
||||
const vfloat<Nx> tFarZ = msub(bmaxZ, p.rdir.z[i], p.org_rdir.z[i]);
|
||||
|
||||
const vfloat<Nx> tNear = maxi(mini(tNearX,tFarX), mini(tNearY,tFarY), mini(tNearZ,tFarZ), vfloat<Nx>(p.min_dist[i]));
|
||||
const vfloat<Nx> tFar = mini(maxi(tNearX,tFarX), maxi(tNearY,tFarY), maxi(tNearZ,tFarZ), vfloat<Nx>(p.max_dist[i]));
|
||||
const vbool<Nx> hit_mask = tNear <= tFar;
|
||||
#if defined(__AVX2__)
|
||||
vmask = vmask | (bitmask & vint<Nx>(hit_mask));
|
||||
#else
|
||||
vmask = select(hit_mask, vmask | bitmask, vmask);
|
||||
#endif
|
||||
} while(bits);
|
||||
const vbool<Nx> valid_children = bminX <= bmaxX;
|
||||
|
||||
size_t mask = movemask( (vmask != vint<Nx>(zero)) & valid_children);
|
||||
if (unlikely(mask == 0)) goto pop;
|
||||
|
||||
__aligned(64) unsigned int child_mask[Nx];
|
||||
vint<Nx>::storeu(child_mask,vmask); // this explicit store here causes much better code generation
|
||||
|
||||
/* select next child and push other children */
|
||||
//const BaseNode* node = cur.baseNode(types);
|
||||
|
||||
/*! one child is hit, continue with that child */
|
||||
size_t r = __bscf(mask);
|
||||
assert(r < N);
|
||||
cur = node->child(r);
|
||||
cur.prefetch(types);
|
||||
cur_mask = child_mask[r];
|
||||
|
||||
/* simple in order sequence */
|
||||
assert(cur != BVH::emptyNode);
|
||||
if (likely(mask == 0)) continue;
|
||||
stackPtr->ptr = cur;
|
||||
stackPtr->dist = cur_mask;
|
||||
stackPtr++;
|
||||
|
||||
for (; ;)
|
||||
{
|
||||
r = __bscf(mask);
|
||||
assert(r < N);
|
||||
|
||||
cur = node->child(r);
|
||||
cur.prefetch(types);
|
||||
cur_mask = child_mask[r];
|
||||
assert(cur != BVH::emptyNode);
|
||||
if (likely(mask == 0)) break;
|
||||
stackPtr->ptr = cur;
|
||||
stackPtr->dist = cur_mask;
|
||||
stackPtr++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*! this is a leaf node */
|
||||
assert(cur != BVH::emptyNode);
|
||||
STAT3(shadow.trav_leaves,1,1,1);
|
||||
size_t num; Primitive* prim = (Primitive*) cur.leaf(num);
|
||||
|
||||
|
||||
size_t bits = cur_mask;
|
||||
size_t lazy_node = 0;
|
||||
|
||||
for (; bits!=0; )
|
||||
{
|
||||
const size_t rayID = __bscf(bits);
|
||||
|
||||
RayK<K> &ray = *inputPackets[rayID / K];
|
||||
const size_t k = rayID % K;
|
||||
if (PrimitiveIntersector::occluded(ray,k,context,prim,num,lazy_node)) {
|
||||
ray.geomID[k] = 0;
|
||||
terminated |= (size_t)1 << rayID;
|
||||
}
|
||||
/* lazy node */
|
||||
if (unlikely(lazy_node)) {
|
||||
stackPtr->ptr = lazy_node;
|
||||
stackPtr->dist = cur_mask;
|
||||
stackPtr++;
|
||||
}
|
||||
}
|
||||
|
||||
if (unlikely(terminated == (size_t)-1)) { break; }
|
||||
}
|
||||
|
||||
#else
|
||||
__aligned(64) Packet<K,robust> packet[MAX_INTERNAL_STREAM_SIZE/K];
|
||||
__aligned(64) StackItemMaskCoherent stack[stackSizeSingle]; //!< stack of nodes
|
||||
__aligned(64) Frustum<N,Nx,K,robust> frusta;
|
||||
__aligned(64) Packet packet[MAX_RAYS/K];
|
||||
__aligned(64) Frusta frusta;
|
||||
|
||||
bool commonOctant = true;
|
||||
size_t m_active = initPacketsAndFrusta<true>(inputPackets, numOctantRays, packet, frusta, commonOctant);
|
||||
|
||||
|
||||
/* valid rays */
|
||||
if (unlikely(m_active == 0)) return;
|
||||
|
||||
@@ -335,7 +198,7 @@ namespace embree
|
||||
{
|
||||
const size_t numPackets = (numOctantRays+K-1)/K;
|
||||
for (size_t i = 0; i < numPackets; i++)
|
||||
This->occluded(inputPackets[i]->tnear <= inputPackets[i]->tfar,*inputPackets[i],context);
|
||||
bvh->scene->occluded(inputPackets[i]->tnear <= inputPackets[i]->tfar,*inputPackets[i],context);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -347,6 +210,8 @@ namespace embree
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const NearFarPreCompute pc(frusta.min_rdir);
|
||||
|
||||
StackItemMaskCoherent* stackPtr = stack + 1;
|
||||
|
||||
while (1) pop:
|
||||
@@ -372,7 +237,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, frusta, maskK, dist);
|
||||
const size_t m_node_hit = traverseCoherentStream(m_trav_active, packet, node, pc, 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);
|
||||
@@ -387,12 +252,25 @@ 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));
|
||||
m_trav_active = intersectAlignedNodePacket(packet, node, b, frusta.nf, m_trav_active);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/*! this is a leaf node */
|
||||
/*! 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 */
|
||||
STAT3(normal.trav_leaves, 1, 1, 1);
|
||||
size_t num; Primitive* prim = (Primitive*)cur.leaf(num);
|
||||
|
||||
@@ -408,14 +286,62 @@ namespace embree
|
||||
const size_t m_isec = ((((size_t)1 << K)-1) << (i*K));
|
||||
assert(m_isec & bits);
|
||||
bits &= ~m_isec;
|
||||
Packet<K,robust> &p = packet[i];
|
||||
Packet &p = packet[i];
|
||||
vbool<K> m_valid = p.min_dist <= p.max_dist;
|
||||
vbool<K> m_hit = PrimitiveIntersector::occludedK(m_valid, *inputPackets[i], context, prim, num, lazy_node);
|
||||
inputPackets[i]->geomID = select(m_hit & m_valid, vint<K>(zero), inputPackets[i]->geomID);
|
||||
m_active &= ~((size_t)movemask(m_hit) << (i*K));
|
||||
}
|
||||
|
||||
} // traversal + intersection
|
||||
}
|
||||
|
||||
// =====================================================================================================
|
||||
// =====================================================================================================
|
||||
// =====================================================================================================
|
||||
|
||||
template<int N, int Nx, int K, int types, bool robust, typename PrimitiveIntersector>
|
||||
void BVHNIntersectorStream<N, Nx, K, types, robust, PrimitiveIntersector>::intersect(BVH* __restrict__ bvh, RayK<K>** inputRays, size_t numTotalRays, IntersectContext* context)
|
||||
{
|
||||
#if ENABLE_COHERENT_STREAM_PATH == 1
|
||||
if (unlikely(PrimitiveIntersector::validIntersectorK && !robust && isCoherent(context->user->flags)))
|
||||
{
|
||||
intersectCoherent(bvh, inputRays, numTotalRays, context);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* fallback to packets */
|
||||
for (size_t i = 0; i < numTotalRays; i += K)
|
||||
{
|
||||
const vint<K> vi = vint<K>(int(i)) + vint<K>(step);
|
||||
vbool<K> valid = vi < vint<K>(int(numTotalRays));
|
||||
RayK<K>& ray = *(inputRays[i / K]);
|
||||
valid &= ray.tnear <= ray.tfar;
|
||||
bvh->scene->intersect(valid, ray, context);
|
||||
}
|
||||
}
|
||||
|
||||
template<int N, int Nx, int K, int types, bool robust, typename PrimitiveIntersector>
|
||||
void BVHNIntersectorStream<N, Nx, K, types, robust, PrimitiveIntersector>::occluded(BVH* __restrict__ bvh, RayK<K>** inputRays, size_t numTotalRays, IntersectContext* context)
|
||||
{
|
||||
#if ENABLE_COHERENT_STREAM_PATH == 1
|
||||
if (unlikely(PrimitiveIntersector::validIntersectorK && !robust && isCoherent(context->user->flags)))
|
||||
{
|
||||
occludedCoherent(bvh, inputRays, numTotalRays, context);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* fallback to packets */
|
||||
for (size_t i = 0; i < numTotalRays; i += K)
|
||||
{
|
||||
const vint<K> vi = vint<K>(int(i)) + vint<K>(step);
|
||||
vbool<K> valid = vi < vint<K>(int(numTotalRays));
|
||||
RayK<K>& ray = *(inputRays[i / K]);
|
||||
valid &= ray.tnear <= ray.tfar;
|
||||
bvh->scene->occluded(valid, ray, context);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -433,39 +359,5 @@ 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,7 +20,8 @@
|
||||
#include "../common/ray.h"
|
||||
#include "../common/stack_item.h"
|
||||
#include "bvh_traverser1.h"
|
||||
#include "frustum.h"
|
||||
|
||||
#define ENABLE_COHERENT_STREAM_PATH 1
|
||||
|
||||
namespace embree
|
||||
{
|
||||
@@ -203,8 +204,53 @@ 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<K,robust>* const packet, Frustum<N,Nx,K,robust>& frusta, bool &commonOctant)
|
||||
__forceinline static size_t initPacketsAndFrusta(RayK<K>** inputPackets, const size_t numOctantRays, Packet* const packet, Frusta& frusta, bool &commonOctant)
|
||||
{
|
||||
const size_t numPackets = (numOctantRays+K-1)/K;
|
||||
|
||||
@@ -229,25 +275,26 @@ namespace embree
|
||||
|
||||
m_active |= (size_t)movemask(m_valid) << (i*K);
|
||||
|
||||
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);
|
||||
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);
|
||||
|
||||
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;
|
||||
|
||||
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_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)));
|
||||
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) );
|
||||
@@ -264,26 +311,38 @@ 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 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);
|
||||
|
||||
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;
|
||||
|
||||
return m_active;
|
||||
}
|
||||
|
||||
|
||||
__forceinline static size_t intersectAlignedNodePacket(const Packet<K,robust>* const packet,
|
||||
const AlignedNode* __restrict__ const node,
|
||||
const size_t bid,
|
||||
const NearFarPreCompute& nf,
|
||||
__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,
|
||||
const size_t m_active)
|
||||
{
|
||||
assert(m_active);
|
||||
@@ -292,31 +351,92 @@ namespace embree
|
||||
size_t m_trav_active = 0;
|
||||
for (size_t i = startPacketID; i <= endPacketID; i++)
|
||||
{
|
||||
const size_t m_hit = packet[i].template intersect<N>(node,bid,nf);
|
||||
//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);
|
||||
m_trav_active |= m_hit << (i*K);
|
||||
}
|
||||
return m_trav_active;
|
||||
}
|
||||
|
||||
|
||||
__forceinline static size_t traverseCoherentStream(const size_t m_trav_active,
|
||||
Packet<K,robust>* const packet,
|
||||
Packet* const packet,
|
||||
const AlignedNode* __restrict__ const node,
|
||||
const Frustum<N,Nx,K,robust>& frusta,
|
||||
const NearFarPreCompute& pc,
|
||||
const Frusta& frusta,
|
||||
size_t* const maskK,
|
||||
vfloat<Nx>& dist)
|
||||
{
|
||||
size_t m_node_hit = frusta.intersect(node,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);
|
||||
// ==================
|
||||
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);
|
||||
|
||||
/* this make traversal independent of the ordering of rays */
|
||||
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;
|
||||
|
||||
|
||||
size_t m_node = m_node_hit ^ m_first_hit;
|
||||
while(unlikely(m_node))
|
||||
{
|
||||
const size_t b = __bscf(m_node);
|
||||
const size_t m_current = m_trav_active & intersectAlignedNodePacket(packet, node, b, frusta.nf, m_trav_active);
|
||||
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);
|
||||
m_node_hit ^= m_current ? (size_t)0 : ((size_t)1 << b);
|
||||
maskK[b] = m_current;
|
||||
}
|
||||
@@ -329,20 +449,13 @@ 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(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);
|
||||
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);
|
||||
};
|
||||
|
||||
|
||||
/*! 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,13 +20,6 @@ namespace embree
|
||||
{
|
||||
namespace isa
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// General BVHIntersectorStreamPacketFallback Intersector
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DEFINE_INTERSECTORN(BVH4IntersectorStreamPacketFallback,BVHNIntersectorStreamPacketFallback<SIMD_MODE(4) COMMA VSIZEX>);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// BVH4IntersectorStream Definitions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -20,12 +20,6 @@ namespace embree
|
||||
{
|
||||
namespace isa
|
||||
{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// General BVHIntersectorStreamPacketFallback Intersector
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DEFINE_INTERSECTORN(BVH8IntersectorStreamPacketFallback,BVHNIntersectorStreamPacketFallback<SIMD_MODE(8) COMMA VSIZEX>);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// BVH8IntersectorStream Definitions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -17,155 +17,197 @@
|
||||
#include "bvh_intersector_stream_filters.h"
|
||||
#include "bvh_intersector_stream.h"
|
||||
|
||||
#define FORCE_STREAM_OCCLUSION_KERNEL 1
|
||||
|
||||
namespace embree
|
||||
{
|
||||
namespace isa
|
||||
{
|
||||
MAYBE_UNUSED static const size_t MAX_PACKET_STREAM_SIZE = MAX_INTERNAL_STREAM_SIZE / VSIZEX;
|
||||
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");
|
||||
|
||||
__forceinline void RayStreamFilter::filterAOS(Scene* scene, RTCRay* _rayN, size_t N, size_t stride, IntersectContext* context, bool intersect)
|
||||
{
|
||||
#if 1
|
||||
RayStreamAOS rayN(_rayN);
|
||||
for (size_t i = 0; i < N; i += VSIZEX)
|
||||
{
|
||||
const vintx vi = vintx(int(i)) + vintx(step);
|
||||
vboolx valid = vi < vintx(int(N));
|
||||
const vintx offset = vi * int(stride);
|
||||
|
||||
RayK<VSIZEX> ray = rayN.getRayByOffset<VSIZEX>(valid, offset);
|
||||
valid &= ray.tnear <= ray.tfar;
|
||||
|
||||
if (intersect)
|
||||
scene->intersect(valid, ray, context);
|
||||
else
|
||||
scene->occluded(valid, ray, context);
|
||||
|
||||
rayN.setHitByOffset<VSIZEX>(valid, offset, ray, intersect);
|
||||
}
|
||||
|
||||
/* use fast path for coherent ray mode */
|
||||
#if FORCE_STREAM_OCCLUSION_KERNEL == 1
|
||||
if (1)
|
||||
#else
|
||||
if (unlikely(isCoherent(context->user->flags)))
|
||||
|
||||
Ray* __restrict__ rayN = (Ray*)_rayN;
|
||||
__aligned(64) Ray* octants[8][MAX_RAYS_PER_OCTANT];
|
||||
unsigned int rays_in_octant[8];
|
||||
|
||||
for (size_t i=0;i<8;i++) rays_in_octant[i] = 0;
|
||||
size_t inputRayID = 0;
|
||||
|
||||
while(1)
|
||||
{
|
||||
int cur_octant = -1;
|
||||
/* sort rays into octants */
|
||||
for (;inputRayID<N;)
|
||||
{
|
||||
Ray &ray = *(Ray*)((char*)rayN + inputRayID * stride);
|
||||
/* filter out invalid rays */
|
||||
if (unlikely(ray.tnear > ray.tfar)) { inputRayID++; continue; }
|
||||
if (unlikely(!intersect && ray.geomID == 0)) { inputRayID++; continue; } // ignore already occluded rays
|
||||
|
||||
#if defined(EMBREE_IGNORE_INVALID_RAYS)
|
||||
if (unlikely(!ray.valid())) { inputRayID++; continue; }
|
||||
#endif
|
||||
{
|
||||
__aligned(64) RayK<VSIZEX> rays[MAX_PACKET_STREAM_SIZE];
|
||||
__aligned(64) RayK<VSIZEX>* rayPtrs[MAX_PACKET_STREAM_SIZE];
|
||||
|
||||
for (size_t i = 0; i < N; i += MAX_INTERNAL_STREAM_SIZE)
|
||||
{
|
||||
const size_t size = min(N - i, MAX_INTERNAL_STREAM_SIZE);
|
||||
const unsigned int octantID = movemask(vfloat4(ray.dir) < 0.0f) & 0x7;
|
||||
|
||||
/* convert from AOS to SOA */
|
||||
for (size_t j = 0; j < size; j += VSIZEX)
|
||||
assert(octantID < 8);
|
||||
octants[octantID][rays_in_octant[octantID]++] = &ray;
|
||||
inputRayID++;
|
||||
if (unlikely(rays_in_octant[octantID] == MAX_RAYS_PER_OCTANT))
|
||||
{
|
||||
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);
|
||||
cur_octant = octantID;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
static const size_t MAX_RAYS_PER_OCTANT = VSIZEX;
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* fallback to packets */
|
||||
/* all rays traced ? */
|
||||
if (unlikely(cur_octant == -1))
|
||||
break;
|
||||
|
||||
for (size_t i=0; i<N; i+=VSIZEX)
|
||||
|
||||
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)
|
||||
{
|
||||
const vintx vi = vintx(int(i)) + vintx(step);
|
||||
vboolx valid = vi < vintx(int(N));
|
||||
const vintx offset = vi * int(stride);
|
||||
RayK<VSIZEX> ray = rayN.getRayByOffset(valid, offset);
|
||||
valid &= ray.tnear <= ray.tfar;
|
||||
if (intersect)
|
||||
scene->intersectors.intersect(valid, ray, context);
|
||||
else
|
||||
scene->intersectors.occluded(valid, ray, context);
|
||||
rayN.setHitByOffset(valid, offset, ray, intersect);
|
||||
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;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
__forceinline void RayStreamFilter::filterAOP(Scene* scene, RTCRay** _rayN, size_t N, IntersectContext* context, bool intersect)
|
||||
{
|
||||
#if 1
|
||||
|
||||
/* fallback to packets */
|
||||
RayStreamAOP rayN(_rayN);
|
||||
|
||||
/* use fast path for coherent ray mode */
|
||||
if (unlikely(isCoherent(context->user->flags)))
|
||||
for (size_t i = 0; i < N; i += VSIZEX)
|
||||
{
|
||||
__aligned(64) RayK<VSIZEX> rays[MAX_PACKET_STREAM_SIZE];
|
||||
__aligned(64) RayK<VSIZEX>* rayPtrs[MAX_PACKET_STREAM_SIZE];
|
||||
const vintx vi = vintx(int(i)) + vintx(step);
|
||||
vboolx valid = vi < vintx(int(N));
|
||||
|
||||
for (size_t i = 0; i < N; i += MAX_INTERNAL_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;)
|
||||
{
|
||||
const size_t size = min(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
|
||||
|
||||
/* convert from AOP to SOA */
|
||||
for (size_t j = 0; j < size; j += VSIZEX)
|
||||
#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))
|
||||
{
|
||||
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);
|
||||
cur_octant = octantID;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* fallback to packets */
|
||||
for (size_t i = 0; i < N; i += VSIZEX)
|
||||
/* 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)
|
||||
{
|
||||
const vintx vi = vintx(int(i)) + vintx(step);
|
||||
vboolx valid = vi < vintx(int(N));
|
||||
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
__forceinline void RayStreamFilter::filterSOA(Scene* scene, char* rayData, size_t N, size_t numPackets, size_t stride, IntersectContext* context, bool intersect)
|
||||
@@ -178,40 +220,45 @@ namespace embree
|
||||
!rayDataAlignment &&
|
||||
!offsetAlignment))
|
||||
{
|
||||
if (unlikely(isCoherent(context->user->flags)))
|
||||
#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()))
|
||||
{
|
||||
__aligned(64) RayK<VSIZEX>* rayPtrs[MAX_INTERNAL_STREAM_SIZE / VSIZEX];
|
||||
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;
|
||||
|
||||
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);
|
||||
rayPtrs[packetIndex++] = &ray;
|
||||
rays_ptr[numPacketsInOctant++] = &ray;
|
||||
|
||||
/* trace as stream */
|
||||
if (unlikely(packetIndex == MAX_PACKET_STREAM_SIZE))
|
||||
if (unlikely(numPacketsInOctant == MAX_COHERENT_RAY_PACKETS))
|
||||
{
|
||||
const size_t size = packetIndex*VSIZEX;
|
||||
const size_t size = numPacketsInOctant*VSIZEX;
|
||||
if (intersect)
|
||||
scene->intersectors.intersectN(rayPtrs, size, context);
|
||||
scene->intersectN((void**)rays_ptr, size, context);
|
||||
else
|
||||
scene->intersectors.occludedN(rayPtrs, size, context);
|
||||
packetIndex = 0;
|
||||
scene->occludedN((void**)rays_ptr, size, context);
|
||||
numPacketsInOctant = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* flush remaining packets */
|
||||
if (unlikely(packetIndex > 0))
|
||||
if (unlikely(numPacketsInOctant))
|
||||
{
|
||||
const size_t size = packetIndex*VSIZEX;
|
||||
const size_t size = numPacketsInOctant*VSIZEX;
|
||||
if (intersect)
|
||||
scene->intersectors.intersectN(rayPtrs, size, context);
|
||||
scene->intersectN((void**)rays_ptr, size, context);
|
||||
else
|
||||
scene->intersectors.occludedN(rayPtrs, size, context);
|
||||
scene->occludedN((void**)rays_ptr, size, context);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* fallback to packets */
|
||||
for (size_t i = 0; i < numPackets; i++)
|
||||
@@ -221,34 +268,37 @@ namespace embree
|
||||
const vboolx valid = ray.tnear <= ray.tfar;
|
||||
|
||||
if (intersect)
|
||||
scene->intersectors.intersect(valid, ray, context);
|
||||
scene->intersect(valid, ray, context);
|
||||
else
|
||||
scene->intersectors.occluded(valid, ray, context);
|
||||
scene->occluded(valid, ray, context);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* fallback to packets for arbitrary packet size and alignment */
|
||||
/* this is a very slow fallback path but it's extremely unlikely to be hit */
|
||||
for (size_t i = 0; i < numPackets; i++)
|
||||
{
|
||||
const size_t offsetN = i * stride;
|
||||
RayPacketSOA rayN(rayData + offsetN, N);
|
||||
{
|
||||
const size_t offset = i * stride;
|
||||
RayPacketSOA rayN(rayData + offset, N);
|
||||
RayK<VSIZEX> ray;
|
||||
|
||||
for (size_t j = 0; j < N; j += VSIZEX)
|
||||
for (size_t j = 0; j < N; j++)
|
||||
{
|
||||
const size_t offset = j * sizeof(float);
|
||||
vboolx valid = (vintx(int(j)) + vintx(step)) < vintx(int(N));
|
||||
/* invalidate all lanes */
|
||||
ray.tnear = 0.0f;
|
||||
ray.tfar = neg_inf;
|
||||
|
||||
RayK<VSIZEX> ray = rayN.getRayByOffset(valid, offset);
|
||||
valid &= ray.tnear <= ray.tfar;
|
||||
/* extract single ray and copy data to first packet lane */
|
||||
rayN.getRayByIndex(j, ray, 0);
|
||||
const vboolx valid = ray.tnear <= ray.tfar;
|
||||
|
||||
if (intersect)
|
||||
scene->intersectors.intersect(valid, ray, context);
|
||||
scene->intersect(valid, ray, context);
|
||||
else
|
||||
scene->intersectors.occluded(valid, ray, context);
|
||||
scene->occluded(valid, ray, context);
|
||||
|
||||
rayN.setHitByOffset(valid, offset, ray, intersect);
|
||||
rayN.setHitByIndex(j, ray, 0, intersect);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -259,65 +309,70 @@ namespace embree
|
||||
RayStreamSOP& rayN = *(RayStreamSOP*)&_rayN;
|
||||
|
||||
/* use fast path for coherent ray mode */
|
||||
if (unlikely(isCoherent(context->user->flags)))
|
||||
#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()))
|
||||
{
|
||||
__aligned(64) RayK<VSIZEX> rays[MAX_PACKET_STREAM_SIZE];
|
||||
__aligned(64) RayK<VSIZEX>* rayPtrs[MAX_PACKET_STREAM_SIZE];
|
||||
static const size_t MAX_COHERENT_RAY_PACKETS = MAX_RAYS_PER_OCTANT / VSIZEX;
|
||||
|
||||
for (size_t i = 0; i < N; i += MAX_INTERNAL_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)
|
||||
{
|
||||
const size_t size = min(N - i, MAX_INTERNAL_STREAM_SIZE);
|
||||
const size_t size = min(N - i, MAX_RAYS_PER_OCTANT);
|
||||
|
||||
/* 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 = (i+j) * sizeof(float);
|
||||
const size_t packetIndex = j / VSIZEX;
|
||||
const size_t offset = sizeof(float) * (i+j);
|
||||
const size_t packet_index = 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
|
||||
rays[packet_index] = ray;
|
||||
rays_ptr[packet_index] = &rays[packet_index]; // rays_ptr might get reordered for occludedN
|
||||
}
|
||||
|
||||
/* trace stream */
|
||||
if (intersect)
|
||||
scene->intersectors.intersectN(rayPtrs, size, context);
|
||||
scene->intersectN((void**)rays_ptr, size, context);
|
||||
else
|
||||
scene->intersectors.occludedN(rayPtrs, size, context);
|
||||
scene->occludedN((void**)rays_ptr, 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 = (i+j) * sizeof(float);
|
||||
const size_t packetIndex = j / VSIZEX;
|
||||
const size_t offset = sizeof(float) * (i+j);
|
||||
const size_t packet_index = j / VSIZEX;
|
||||
|
||||
rayN.setHitByOffset(valid, offset, rays[packetIndex], intersect);
|
||||
rayN.setHitByOffset(valid, offset, rays[packet_index], 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 = i * sizeof(float);
|
||||
const size_t offset = sizeof(float) * i;
|
||||
|
||||
RayK<VSIZEX> ray = rayN.getRayByOffset(valid, offset);
|
||||
valid &= ray.tnear <= ray.tfar;
|
||||
|
||||
if (intersect)
|
||||
scene->intersectors.intersect(valid, ray, context);
|
||||
scene->intersect(valid, ray, context);
|
||||
else
|
||||
scene->intersectors.occluded(valid, ray, context);
|
||||
scene->occluded(valid, ray, context);
|
||||
|
||||
rayN.setHitByOffset(valid, offset, ray, intersect);
|
||||
}
|
||||
|
||||
@@ -89,12 +89,14 @@ namespace embree
|
||||
|
||||
virtual const BBox3fa leafBounds (NodeRef& ref) const
|
||||
{
|
||||
size_t num; char* prim = ref.leaf(num);
|
||||
size_t ty; Primitive* prim = (Primitive*) ref.leaf(ty);
|
||||
if (unlikely(ref == BVH::emptyNode)) return empty;
|
||||
|
||||
BBox3fa bounds = empty;
|
||||
for (size_t i=0; i<num; i++)
|
||||
bounds.extend(((Primitive*)prim)[i].update(mesh));
|
||||
for (size_t i=0;; i++) {
|
||||
bounds.extend(prim[i].update(mesh));
|
||||
if (prim[i].last()) break;
|
||||
}
|
||||
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(int(c2)) != vint4(step);
|
||||
valid &= vint4(c2) != vint4(step);
|
||||
if (none(valid)) continue;
|
||||
size_t c1 = select_min(valid,area0123);
|
||||
float area = area0123[c1];
|
||||
|
||||
@@ -154,11 +154,15 @@ namespace embree
|
||||
}
|
||||
else if (node.isLeaf())
|
||||
{
|
||||
size_t num; const char* tri = node.leaf(num);
|
||||
if (num)
|
||||
size_t ty; const char* tri = node.leaf(ty);
|
||||
if (node != BVH::emptyNode)
|
||||
{
|
||||
for (size_t i=0; i<num; i++) {
|
||||
s.statLeaf.numPrims += bvh->primTy->size(tri+i*bvh->primTy->bytes);
|
||||
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;
|
||||
}
|
||||
s.statLeaf.numLeaves++;
|
||||
s.statLeaf.numPrimBlocks += num;
|
||||
|
||||
@@ -30,8 +30,6 @@ 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);
|
||||
@@ -232,196 +230,19 @@ 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 = node->child((unsigned int)toScalar(ptr));
|
||||
stackPtr->ptr = toScalar(ptr);
|
||||
*(float*)&stackPtr->dist = toScalar(dist);
|
||||
dist = align_shift_right<1>(dist,dist);
|
||||
ptr = align_shift_right<1>(ptr,ptr);
|
||||
stackPtr++;
|
||||
}
|
||||
cur = node->child((unsigned int)toScalar(ptr));
|
||||
cur = toScalar(ptr);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -442,16 +263,8 @@ 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);
|
||||
|
||||
@@ -555,16 +368,9 @@ 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);
|
||||
|
||||
|
||||
@@ -1,384 +0,0 @@
|
||||
// ======================================================================== //
|
||||
// Copyright 2009-2017 Intel Corporation //
|
||||
// //
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"); //
|
||||
// you may not use this file except in compliance with the License. //
|
||||
// You may obtain a copy of the License at //
|
||||
// //
|
||||
// http://www.apache.org/licenses/LICENSE-2.0 //
|
||||
// //
|
||||
// Unless required by applicable law or agreed to in writing, software //
|
||||
// distributed under the License is distributed on an "AS IS" BASIS, //
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
|
||||
// See the License for the specific language governing permissions and //
|
||||
// limitations under the License. //
|
||||
// ======================================================================== //
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "bvh.h"
|
||||
#include "../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;
|
||||
};
|
||||
}
|
||||
}
|
||||
+137
-127
@@ -61,64 +61,62 @@ namespace embree
|
||||
ALIGNED_CLASS;
|
||||
public:
|
||||
|
||||
struct Intersectors;
|
||||
|
||||
/*! Type of intersect function pointer for single rays. */
|
||||
typedef void (*IntersectFunc)(Intersectors* This, /*!< this pointer to accel */
|
||||
typedef void (*IntersectFunc)(void* ptr, /*!< pointer to user data */
|
||||
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 */
|
||||
Intersectors* This, /*!< this pointer to accel */
|
||||
void* ptr, /*!< pointer to user data */
|
||||
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 */
|
||||
Intersectors* This, /*!< this pointer to accel */
|
||||
void* ptr, /*!< pointer to user data */
|
||||
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 */
|
||||
Intersectors* This, /*!< this pointer to accel */
|
||||
typedef void (*IntersectFunc16)(const void* valid, /*!< pointer to valid mask */
|
||||
void* ptr, /*!< pointer to user data */
|
||||
RTCRay16& ray, /*!< ray packet to intersect */
|
||||
IntersectContext* context);
|
||||
|
||||
/*! Type of intersect function pointer for ray packets of size N. */
|
||||
typedef void (*IntersectFuncN)(Intersectors* This, /*!< this pointer to accel */
|
||||
RayK<VSIZEX>** ray, /*!< ray stream to intersect */
|
||||
typedef void (*IntersectFuncN)(void* ptr, /*!< pointer to user data */
|
||||
void** 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) (Intersectors* This, /*!< this pointer to accel */
|
||||
typedef void (*OccludedFunc) (void* ptr, /*!< pointer to user data */
|
||||
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 */
|
||||
Intersectors* This, /*!< this pointer to accel */
|
||||
void* ptr, /*!< pointer to user data */
|
||||
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 */
|
||||
Intersectors* This, /*!< this pointer to accel */
|
||||
void* ptr, /*!< pointer to user data */
|
||||
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 */
|
||||
Intersectors* This,/*!< this pointer to accel */
|
||||
void* ptr, /*!< pointer to user data */
|
||||
RTCRay16& ray, /*!< Ray packet to test occlusion. */
|
||||
IntersectContext* context);
|
||||
|
||||
/*! Type of intersect function pointer for ray packets of size N. */
|
||||
typedef void (*OccludedFuncN)(Intersectors* This, /*!< this pointer to accel */
|
||||
RayK<VSIZEX>** ray, /*!< ray stream to intersect */
|
||||
typedef void (*OccludedFuncN)(void* ptr, /*!< pointer to user data */
|
||||
void** ray, /*!< ray stream to intersect */
|
||||
const size_t N, /*!< number of rays in stream */
|
||||
IntersectContext* context /*!< layout flags */);
|
||||
typedef void (*ErrorFunc) ();
|
||||
@@ -260,118 +258,6 @@ 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;
|
||||
@@ -408,6 +294,130 @@ 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;
|
||||
};
|
||||
|
||||
+33
-31
@@ -22,7 +22,7 @@
|
||||
namespace embree
|
||||
{
|
||||
AccelN::AccelN ()
|
||||
: Accel(AccelData::TY_ACCELN), accels(nullptr), validAccels(nullptr) {}
|
||||
: Accel(AccelData::TY_ACCELN), accels(nullptr), validAccels(nullptr), validIntersectorN(false) {}
|
||||
|
||||
AccelN::~AccelN()
|
||||
{
|
||||
@@ -39,55 +39,55 @@ namespace embree
|
||||
accels.push_back(accel);
|
||||
}
|
||||
|
||||
void AccelN::intersect (Accel::Intersectors* This_in, RTCRay& ray, IntersectContext* context)
|
||||
void AccelN::intersect (void* ptr, RTCRay& ray, IntersectContext* context)
|
||||
{
|
||||
AccelN* This = (AccelN*)This_in->ptr;
|
||||
AccelN* This = (AccelN*)ptr;
|
||||
for (size_t i=0; i<This->validAccels.size(); i++)
|
||||
This->validAccels[i]->intersectors.intersect(ray,context);
|
||||
This->validAccels[i]->intersect(ray,context);
|
||||
}
|
||||
|
||||
void AccelN::intersect4 (const void* valid, Accel::Intersectors* This_in, RTCRay4& ray, IntersectContext* context)
|
||||
void AccelN::intersect4 (const void* valid, void* ptr, RTCRay4& ray, IntersectContext* context)
|
||||
{
|
||||
AccelN* This = (AccelN*)This_in->ptr;
|
||||
AccelN* This = (AccelN*)ptr;
|
||||
for (size_t i=0; i<This->validAccels.size(); i++)
|
||||
This->validAccels[i]->intersectors.intersect4(valid,ray,context);
|
||||
This->validAccels[i]->intersect4(valid,ray,context);
|
||||
}
|
||||
|
||||
void AccelN::intersect8 (const void* valid, Accel::Intersectors* This_in, RTCRay8& ray, IntersectContext* context)
|
||||
void AccelN::intersect8 (const void* valid, void* ptr, RTCRay8& ray, IntersectContext* context)
|
||||
{
|
||||
AccelN* This = (AccelN*)This_in->ptr;
|
||||
AccelN* This = (AccelN*)ptr;
|
||||
for (size_t i=0; i<This->validAccels.size(); i++)
|
||||
This->validAccels[i]->intersectors.intersect8(valid,ray,context);
|
||||
This->validAccels[i]->intersect8(valid,ray,context);
|
||||
}
|
||||
|
||||
void AccelN::intersect16 (const void* valid, Accel::Intersectors* This_in, RTCRay16& ray, IntersectContext* context)
|
||||
void AccelN::intersect16 (const void* valid, void* ptr, RTCRay16& ray, IntersectContext* context)
|
||||
{
|
||||
AccelN* This = (AccelN*)This_in->ptr;
|
||||
AccelN* This = (AccelN*)ptr;
|
||||
for (size_t i=0; i<This->validAccels.size(); i++)
|
||||
This->validAccels[i]->intersectors.intersect16(valid,ray,context);
|
||||
This->validAccels[i]->intersect16(valid,ray,context);
|
||||
}
|
||||
|
||||
void AccelN::intersectN (Accel::Intersectors* This_in, RayK<VSIZEX>** ray, const size_t N, IntersectContext* context)
|
||||
void AccelN::intersectN (void* ptr, void** ray, const size_t N, IntersectContext* context)
|
||||
{
|
||||
AccelN* This = (AccelN*)This_in->ptr;
|
||||
AccelN* This = (AccelN*)ptr;
|
||||
for (size_t i=0; i<This->validAccels.size(); i++)
|
||||
This->validAccels[i]->intersectors.intersectN(ray,N,context);
|
||||
This->validAccels[i]->intersectN(ray,N,context);
|
||||
}
|
||||
|
||||
void AccelN::occluded (Accel::Intersectors* This_in, RTCRay& ray, IntersectContext* context)
|
||||
void AccelN::occluded (void* ptr, RTCRay& ray, IntersectContext* context)
|
||||
{
|
||||
AccelN* This = (AccelN*)This_in->ptr;
|
||||
AccelN* This = (AccelN*)ptr;
|
||||
for (size_t i=0; i<This->validAccels.size(); i++) {
|
||||
This->validAccels[i]->intersectors.occluded(ray,context);
|
||||
This->validAccels[i]->occluded(ray,context);
|
||||
if (ray.geomID == 0) break;
|
||||
}
|
||||
}
|
||||
|
||||
void AccelN::occluded4 (const void* valid, Accel::Intersectors* This_in, RTCRay4& ray, IntersectContext* context)
|
||||
void AccelN::occluded4 (const void* valid, void* ptr, RTCRay4& ray, IntersectContext* context)
|
||||
{
|
||||
AccelN* This = (AccelN*)This_in->ptr;
|
||||
AccelN* This = (AccelN*)ptr;
|
||||
for (size_t i=0; i<This->validAccels.size(); i++) {
|
||||
This->validAccels[i]->intersectors.occluded4(valid,ray,context);
|
||||
This->validAccels[i]->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, Accel::Intersectors* This_in, RTCRay8& ray, IntersectContext* context)
|
||||
void AccelN::occluded8 (const void* valid, void* ptr, RTCRay8& ray, IntersectContext* context)
|
||||
{
|
||||
AccelN* This = (AccelN*)This_in->ptr;
|
||||
AccelN* This = (AccelN*)ptr;
|
||||
for (size_t i=0; i<This->validAccels.size(); i++) {
|
||||
This->validAccels[i]->intersectors.occluded8(valid,ray,context);
|
||||
This->validAccels[i]->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, Accel::Intersectors* This_in, RTCRay16& ray, IntersectContext* context)
|
||||
void AccelN::occluded16 (const void* valid, void* ptr, RTCRay16& ray, IntersectContext* context)
|
||||
{
|
||||
AccelN* This = (AccelN*)This_in->ptr;
|
||||
AccelN* This = (AccelN*)ptr;
|
||||
for (size_t i=0; i<This->validAccels.size(); i++) {
|
||||
This->validAccels[i]->intersectors.occluded16(valid,ray,context);
|
||||
This->validAccels[i]->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 (Accel::Intersectors* This_in, RayK<VSIZEX>** ray, const size_t N, IntersectContext* context)
|
||||
void AccelN::occludedN (void* ptr, void** ray, const size_t N, IntersectContext* context)
|
||||
{
|
||||
AccelN* This = (AccelN*)This_in->ptr;
|
||||
AccelN* This = (AccelN*)ptr;
|
||||
size_t M = N;
|
||||
for (size_t i=0; i<This->validAccels.size(); i++)
|
||||
This->validAccels[i]->intersectors.occludedN(ray,M,context);
|
||||
This->validAccels[i]->occludedN(ray,M,context);
|
||||
}
|
||||
|
||||
void AccelN::print(size_t ident)
|
||||
@@ -163,9 +163,11 @@ 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) {
|
||||
|
||||
+12
-10
@@ -31,18 +31,18 @@ namespace embree
|
||||
void add(Accel* accel);
|
||||
|
||||
public:
|
||||
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);
|
||||
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);
|
||||
|
||||
public:
|
||||
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);
|
||||
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);
|
||||
|
||||
public:
|
||||
void print(size_t ident);
|
||||
@@ -51,9 +51,11 @@ 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_SIMD8)
|
||||
#if defined(EMBREE_TARGET_AVX)
|
||||
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_SIMD8)
|
||||
#if defined(EMBREE_TARGET_AVX)
|
||||
std::unique_ptr<BVH8Factory> bvh8_factory;
|
||||
#endif
|
||||
|
||||
|
||||
+2
-10
@@ -16,9 +16,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../../common/sys/platform.h"
|
||||
#include "../../common/sys/sysinfo.h"
|
||||
|
||||
namespace embree
|
||||
{
|
||||
#define DEFINE_SYMBOL2(type,name) \
|
||||
@@ -72,17 +69,12 @@ namespace embree
|
||||
#define SELECT_SYMBOL_SSE42(features,intersector)
|
||||
#endif
|
||||
|
||||
#if defined(EMBREE_TARGET_AVX) || defined(__AVX__)
|
||||
#if defined(EMBREE_TARGET_AVX)
|
||||
#if !defined(EMBREE_TARGET_SIMD8)
|
||||
#define EMBREE_TARGET_SIMD8
|
||||
#endif
|
||||
#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) \
|
||||
#define SELECT_SYMBOL_AVX(features,intersector) \
|
||||
if ((features & AVX) == AVX) intersector = avx::intersector;
|
||||
#endif
|
||||
#else
|
||||
#define SELECT_SYMBOL_AVX(features,intersector)
|
||||
#endif
|
||||
|
||||
+34
-117
@@ -18,14 +18,10 @@
|
||||
|
||||
#include "default.h"
|
||||
|
||||
#define MAX_INTERNAL_STREAM_SIZE 64
|
||||
|
||||
namespace embree
|
||||
{
|
||||
#if defined(__X86_64__) && 0
|
||||
static const size_t MAX_INTERNAL_STREAM_SIZE = 64;
|
||||
#else
|
||||
static const size_t MAX_INTERNAL_STREAM_SIZE = 32;
|
||||
#endif
|
||||
|
||||
/* Ray structure for K rays */
|
||||
template<int K>
|
||||
struct RayK
|
||||
@@ -368,35 +364,35 @@ namespace embree
|
||||
|
||||
struct RayPacketSOA
|
||||
{
|
||||
__forceinline RayPacketSOA(void* rays, size_t N)
|
||||
: ptr((char*)rays), N(N) {}
|
||||
__forceinline RayPacketSOA(void* rays, size_t K)
|
||||
: ptr((char*)rays), K(K) {}
|
||||
|
||||
/* ray data access functions */
|
||||
__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* 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* 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* 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* 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* 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* 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)
|
||||
__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)
|
||||
|
||||
/* hit data access functions */
|
||||
__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* 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* 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 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 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 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 void setRayByIndex(size_t index, const Ray& ray, int* valid)
|
||||
@@ -471,45 +467,8 @@ 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.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.mask = vint<K> ::loadu(mask(offset));
|
||||
ray.instID= vint<K> ::loadu(instID(offset));
|
||||
ray.geomID = RTC_INVALID_GEOMETRY_ID;
|
||||
return ray;
|
||||
}
|
||||
@@ -580,43 +539,17 @@ namespace embree
|
||||
|
||||
if (likely(any(valid)))
|
||||
{
|
||||
#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);
|
||||
}
|
||||
}
|
||||
|
||||
vint<K>::storeu(valid, geomID(offset), ray.geomID);
|
||||
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);
|
||||
vfloat<K>::storeu(valid, u(offset), ray.u);
|
||||
vfloat<K>::storeu(valid, v(offset), ray.v);
|
||||
vint<K> ::storeu(valid, instID(offset), ray.instID);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -638,7 +571,7 @@ namespace embree
|
||||
}
|
||||
|
||||
char* __restrict__ ptr;
|
||||
size_t N;
|
||||
size_t K;
|
||||
};
|
||||
|
||||
template<size_t MAX_K>
|
||||
@@ -847,15 +780,8 @@ 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]))
|
||||
@@ -873,12 +799,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;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
ray.geomID = RTC_INVALID_GEOMETRY_ID;
|
||||
|
||||
return ray;
|
||||
}
|
||||
|
||||
@@ -974,6 +899,7 @@ namespace embree
|
||||
__forceinline Ray8 RayStreamAOS::getRayByOffset(const vint8& offset)
|
||||
{
|
||||
Ray8 ray;
|
||||
|
||||
/* gather: instID */
|
||||
ray.instID = vint8::gather<1>((int*)&ptr->instID, offset);
|
||||
|
||||
@@ -1088,14 +1014,6 @@ 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]))
|
||||
@@ -1113,11 +1031,10 @@ 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->intersectors.intersect(ray,&context);
|
||||
scene->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->intersectors.intersect(ray,&context);
|
||||
scene->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->intersectors.intersect4(valid,ray,&context);
|
||||
scene->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->intersectors.intersect4(valid,ray,&context);
|
||||
scene->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->intersectors.intersect8(valid,ray,&context);
|
||||
scene->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->intersectors.intersect8(valid,ray,&context);
|
||||
scene->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->intersectors.intersect16(valid,ray,&context);
|
||||
scene->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->intersectors.intersect16(valid,ray,&context);
|
||||
scene->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->intersectors.intersect(*rays,&context);
|
||||
scene->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->intersectors.intersect(*rays[0],&context);
|
||||
scene->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->intersectors.intersect(*(RTCRay*)rays,&context);
|
||||
scene->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->intersectors.occluded(ray,&context);
|
||||
scene->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->intersectors.occluded(ray,&context);
|
||||
scene->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->intersectors.occluded4(valid,ray,&context);
|
||||
scene->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->intersectors.occluded4(valid,ray,&context);
|
||||
scene->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->intersectors.occluded8(valid,ray,&context);
|
||||
scene->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->intersectors.occluded8(valid,ray,&context);
|
||||
scene->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->intersectors.occluded16(valid,ray,&context);
|
||||
scene->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->intersectors.occluded16(valid,ray,&context);
|
||||
scene->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->intersectors.occluded (*rays,&context);
|
||||
scene->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->intersectors.occluded (*rays[0],&context);
|
||||
scene->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->intersectors.occluded (*(RTCRay*)rays,&context);
|
||||
scene->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, const RTCIntersectContext* context, RTCRay& ray) {
|
||||
rtcOccluded1Ex(scene,context,ray);
|
||||
extern "C" void ispcOccluded1 (RTCScene scene, RTCRay& ray) {
|
||||
rtcOccluded(scene,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 int geomID, uniform float tessellationRate);
|
||||
extern "C" void ispcSetTessellationRate (RTCScene hscene, uniform unsigned 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 int geomID, uniform RTCBufferType vertexBuffer, uniform RTCBufferType indexBuffer) {
|
||||
void rtcSetIndexBuffer(RTCScene scene, uniform unsigned 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 int geomID, uniform float tessellationRate) {
|
||||
void rtcSetTessellationRate (RTCScene hscene, uniform unsigned 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((unsigned int)timesegments < max_time_steps);
|
||||
assert(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_SIMD8)
|
||||
#if defined (EMBREE_TARGET_AVX)
|
||||
if (device->hasISA(AVX))
|
||||
{
|
||||
if (isHighQuality())
|
||||
@@ -171,7 +171,7 @@ namespace embree
|
||||
break;
|
||||
|
||||
case /*0b01*/ 1:
|
||||
#if defined (EMBREE_TARGET_SIMD8)
|
||||
#if defined (EMBREE_TARGET_AVX)
|
||||
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_SIMD8)
|
||||
#if defined (EMBREE_TARGET_AVX)
|
||||
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_SIMD8)
|
||||
#if defined (EMBREE_TARGET_AVX)
|
||||
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_SIMD8)
|
||||
#if defined (EMBREE_TARGET_AVX)
|
||||
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_SIMD8)
|
||||
#if defined (EMBREE_TARGET_AVX)
|
||||
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_SIMD8)
|
||||
#if defined (EMBREE_TARGET_AVX)
|
||||
if (device->hasISA(AVX))
|
||||
{
|
||||
if (isHighQuality())
|
||||
@@ -293,7 +293,7 @@ namespace embree
|
||||
break;
|
||||
|
||||
case /*0b01*/ 1:
|
||||
#if defined (EMBREE_TARGET_SIMD8)
|
||||
#if defined (EMBREE_TARGET_AVX)
|
||||
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_SIMD8)
|
||||
#if defined (EMBREE_TARGET_AVX)
|
||||
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_SIMD8)
|
||||
#if defined (EMBREE_TARGET_AVX)
|
||||
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_SIMD8)
|
||||
#if defined (EMBREE_TARGET_AVX)
|
||||
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_SIMD8)
|
||||
#if defined (EMBREE_TARGET_AVX)
|
||||
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_SIMD8)
|
||||
#if defined (EMBREE_TARGET_AVX)
|
||||
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_SIMD8)
|
||||
#if defined (EMBREE_TARGET_AVX)
|
||||
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_SIMD8)
|
||||
#if defined (EMBREE_TARGET_AVX)
|
||||
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_SIMD8)
|
||||
#if defined (EMBREE_TARGET_AVX)
|
||||
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_SIMD8)
|
||||
#if defined (EMBREE_TARGET_AVX)
|
||||
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_SIMD8)
|
||||
#if defined (EMBREE_TARGET_AVX)
|
||||
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_SIMD8)
|
||||
#if defined (EMBREE_TARGET_AVX)
|
||||
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_SIMD8)
|
||||
#if defined (EMBREE_TARGET_AVX)
|
||||
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_SIMD8)
|
||||
#if defined (EMBREE_TARGET_AVX)
|
||||
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_SIMD8)
|
||||
#if defined (EMBREE_TARGET_AVX)
|
||||
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_SIMD8)
|
||||
#if defined (EMBREE_TARGET_AVX)
|
||||
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_SIMD8)
|
||||
#if defined (EMBREE_TARGET_AVX)
|
||||
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_SIMD8)
|
||||
#if defined (EMBREE_TARGET_AVX)
|
||||
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(int(numFloats));
|
||||
const vboolx valid = vintx((int)i)+vintx(step) < vintx(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(int(numFloats));
|
||||
const vboolx valid = vintx((int)i)+vintx(step) < vintx(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(int(i))+vint4(step) < vint4(int(numUVs));
|
||||
vbool4 valid1 = vint4(i)+vint4(step) < vint4(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(int(numFloats));
|
||||
const vboolx valid = vintx((int)i)+vintx(step) < vintx(numFloats);
|
||||
const vfloatx p0 = vfloatx::loadu(valid,(float*)&src[tri.v[0]*stride+ofs]);
|
||||
const vfloatx p1 = vfloatx::loadu(valid,(float*)&src[tri.v[1]*stride+ofs]);
|
||||
const vfloatx p2 = vfloatx::loadu(valid,(float*)&src[tri.v[2]*stride+ofs]);
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace embree
|
||||
{
|
||||
/*! An item on the stack holds the node ID and distance of that node. */
|
||||
template<typename T>
|
||||
struct __aligned(16) StackItemT
|
||||
struct __aligned(16) StackItemT
|
||||
{
|
||||
/*! assert that the xchg function works */
|
||||
static_assert(sizeof(T) <= 12, "sizeof(T) <= 12 failed");
|
||||
@@ -79,15 +79,7 @@ namespace embree
|
||||
}
|
||||
|
||||
public:
|
||||
T ptr;
|
||||
T ptr;
|
||||
unsigned dist;
|
||||
};
|
||||
|
||||
/*! An item on the stack holds the node ID and active ray mask. */
|
||||
template<typename T>
|
||||
struct __aligned(16) StackItemMaskT
|
||||
{
|
||||
T ptr;
|
||||
unsigned mask;
|
||||
};
|
||||
}
|
||||
@@ -26,6 +26,7 @@ namespace embree
|
||||
struct Type : public PrimitiveType {
|
||||
Type ();
|
||||
size_t size(const char* This) const;
|
||||
bool last(const char* This) const;
|
||||
};
|
||||
static Type type;
|
||||
|
||||
@@ -43,17 +44,20 @@ namespace embree
|
||||
__forceinline Bezier1i () {}
|
||||
|
||||
/*! Construction from vertices and IDs. */
|
||||
__forceinline Bezier1i (const unsigned vertexID, const unsigned geomID, const unsigned primID)
|
||||
: vertexID(vertexID), geom(geomID), prim(primID) {}
|
||||
__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; }
|
||||
|
||||
/*! returns geometry ID */
|
||||
__forceinline unsigned geomID() const { return geom; }
|
||||
__forceinline unsigned geomID() const { return geom & 0x7FFFFFFF; }
|
||||
|
||||
/*! 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)
|
||||
__forceinline void fill(const PrimRef* prims, size_t& i, size_t end, Scene* scene, bool last)
|
||||
{
|
||||
const PrimRef& prim = prims[i];
|
||||
i++;
|
||||
@@ -61,11 +65,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);
|
||||
new (this) Bezier1i(vertexID,geomID,primID,last);
|
||||
}
|
||||
|
||||
/*! fill curve from curve list */
|
||||
__forceinline LBBox3fa fillMB(const PrimRefMB* prims, size_t& i, size_t end, Scene* scene, const BBox1f time_range)
|
||||
__forceinline LBBox3fa fillMB(const PrimRefMB* prims, size_t& i, size_t end, Scene* scene, const BBox1f time_range, bool last)
|
||||
{
|
||||
const PrimRefMB& prim = prims[i];
|
||||
i++;
|
||||
@@ -73,7 +77,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);
|
||||
new (this) Bezier1i(vertexID,geomID,primID,last);
|
||||
return curves->linearBounds(primID,time_range);
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ namespace embree
|
||||
{
|
||||
Type ();
|
||||
size_t size(const char* This) const;
|
||||
bool last(const char* This) const;
|
||||
};
|
||||
static Type type;
|
||||
|
||||
@@ -45,8 +46,13 @@ 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)
|
||||
: p0(p0), p1(p1), p2(p2), p3(p3), geom(geomID), prim(primID) {}
|
||||
__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;
|
||||
}
|
||||
|
||||
/*! return primitive ID */
|
||||
__forceinline unsigned int primID() const {
|
||||
@@ -55,11 +61,11 @@ namespace embree
|
||||
|
||||
/*! return geometry ID */
|
||||
__forceinline unsigned int geomID() const {
|
||||
return geom;
|
||||
return geom & 0x7FFFFFFF;
|
||||
}
|
||||
|
||||
/*! fill triangle from triangle list */
|
||||
__forceinline void fill(const PrimRef* prims, size_t& i, size_t end, Scene* scene)
|
||||
__forceinline void fill(const PrimRef* prims, size_t& i, size_t end, Scene* scene, bool last)
|
||||
{
|
||||
const PrimRef& prim = prims[i];
|
||||
i++;
|
||||
@@ -71,7 +77,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);
|
||||
new (this) Bezier1v(p0,p1,p2,p3,geomID,primID,last);
|
||||
}
|
||||
|
||||
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,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));
|
||||
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));
|
||||
|
||||
/* 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->intersectors.intersect((RTCRay&)ray,&context);
|
||||
instance->object->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->intersectors.occluded((RTCRay&)ray,&context);
|
||||
instance->object->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->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); }
|
||||
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); }
|
||||
#endif
|
||||
#if defined (__AVX__)
|
||||
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); }
|
||||
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); }
|
||||
#endif
|
||||
#if defined (__AVX512F__)
|
||||
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); }
|
||||
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); }
|
||||
#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];
|
||||
int geomID = geomIDs[i] & 0x7FFFFFFF;
|
||||
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];
|
||||
geomID = geomIDs[i] & 0x7FFFFFFF;
|
||||
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];
|
||||
int geomID = geomIDs[i] & 0x7FFFFFFF;
|
||||
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];
|
||||
geomID = geomIDs[i] & 0x7FFFFFFF;
|
||||
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];
|
||||
const int geomID = geomIDs[i] & 0x7FFFFFFF;
|
||||
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];
|
||||
const int geomID = geomIDs[i] & 0x7FFFFFFF;
|
||||
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];
|
||||
const int geomID = geomIDs[i] & 0x7FFFFFFF;
|
||||
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];
|
||||
int geomID = geomIDs[i] & 0x7FFFFFFF;
|
||||
|
||||
/* 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];
|
||||
geomID = geomIDs[i] & 0x7FFFFFFF;
|
||||
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];
|
||||
const int geomID = geomIDs[i] & 0x7FFFFFFF;
|
||||
Geometry* geometry MAYBE_UNUSED = scene->get(geomID);
|
||||
|
||||
#if defined(EMBREE_RAY_MASK)
|
||||
|
||||
@@ -29,28 +29,33 @@ namespace embree
|
||||
typedef typename Intersector::Primitive Primitive;
|
||||
typedef typename Intersector::Precalculations Precalculations;
|
||||
|
||||
static __forceinline void intersect(Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive* prim, size_t num, size_t& lazy_node)
|
||||
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)
|
||||
{
|
||||
for (size_t i=0; i<num; i++)
|
||||
for (size_t i=0;; 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 num, size_t& lazy_node)
|
||||
static __forceinline bool occluded(Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive* prim, size_t ty, size_t& lazy_node)
|
||||
{
|
||||
for (size_t i=0; i<num; i++) {
|
||||
for (size_t i=0;; 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 num, size_t& lazy_node)
|
||||
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)
|
||||
{
|
||||
}
|
||||
|
||||
template<int K>
|
||||
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)
|
||||
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)
|
||||
{
|
||||
return valid;
|
||||
}
|
||||
@@ -62,35 +67,39 @@ 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 num, size_t& lazy_node)
|
||||
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)
|
||||
{
|
||||
for (size_t i=0; i<num; i++) {
|
||||
for (size_t i=0;; 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 num, 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 ty, size_t& lazy_node)
|
||||
{
|
||||
vbool<K> valid0 = valid;
|
||||
for (size_t i=0; i<num; i++) {
|
||||
for (size_t i=0;; 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 num, size_t& lazy_node)
|
||||
static __forceinline void intersect(Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const Primitive* prim, size_t ty, size_t& lazy_node)
|
||||
{
|
||||
for (size_t i=0; i<num; i++) {
|
||||
for (size_t i=0;; 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 num, size_t& lazy_node)
|
||||
static __forceinline bool occluded(Precalculations& pre, RayK<K>& ray, size_t k, IntersectContext* context, const Primitive* prim, size_t ty, size_t& lazy_node)
|
||||
{
|
||||
for (size_t i=0; i<num; i++) {
|
||||
for (size_t i=0;; i++) {
|
||||
if (Intersector::occluded(pre,ray,k,context,prim[i]))
|
||||
return true;
|
||||
if (prim[i].last()) break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -103,37 +112,30 @@ namespace embree
|
||||
{
|
||||
typedef typename IntersectorK::Primitive PrimitiveK;
|
||||
typedef typename IntersectorK::Precalculations PrecalculationsK;
|
||||
|
||||
static const bool validIntersectorK = true;
|
||||
|
||||
static __forceinline void intersectK(const vbool<K>& valid, /* PrecalculationsK& pre, */ RayK<K>& ray, IntersectContext* context, const PrimitiveK* prim, size_t num, size_t& lazy_node)
|
||||
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)
|
||||
{
|
||||
PrecalculationsK pre(valid,ray); // FIXME: might cause trouble
|
||||
|
||||
for (size_t i=0; i<num; i++) {
|
||||
for (size_t i=0; ; 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 num, 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 ty, size_t& lazy_node)
|
||||
{
|
||||
PrecalculationsK pre(valid,ray); // FIXME: might cause trouble
|
||||
vbool<K> valid0 = valid;
|
||||
for (size_t i=0; i<num; i++) {
|
||||
for (size_t i=0; ; i++) {
|
||||
valid0 &= !IntersectorK::occluded(valid0,pre,ray,context,prim[i]);
|
||||
if (none(valid0)) break;
|
||||
if (prim[i].last()) break;
|
||||
}
|
||||
return !valid0;
|
||||
}
|
||||
|
||||
static __forceinline bool occluded(RayK<K>& ray, size_t k, IntersectContext* context, const PrimitiveK* prim, size_t num, size_t& lazy_node)
|
||||
{
|
||||
PrecalculationsK pre(vbool<K>(true),ray); // FIXME: might cause trouble
|
||||
for (size_t i=0; i<num; i++) {
|
||||
if (IntersectorK::occluded(pre,ray,k,context,prim[i]))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
+28
-18
@@ -28,6 +28,7 @@ namespace embree
|
||||
{
|
||||
Type();
|
||||
size_t size(const char* This) const;
|
||||
bool last(const char* This) const;
|
||||
};
|
||||
static Type type;
|
||||
|
||||
@@ -48,8 +49,11 @@ namespace embree
|
||||
__forceinline LineMi() { }
|
||||
|
||||
/* Construction from vertices and IDs */
|
||||
__forceinline LineMi(const vint<M>& v0, const vint<M>& geomIDs, const vint<M>& primIDs)
|
||||
: v0(v0), geomIDs(geomIDs), primIDs(primIDs) {}
|
||||
__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;
|
||||
}
|
||||
|
||||
/* Returns a mask that tells which line segments are valid */
|
||||
__forceinline vbool<M> valid() const { return primIDs != vint<M>(-1); }
|
||||
@@ -64,10 +68,16 @@ 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]; }
|
||||
__forceinline int geomID(const size_t i) const {
|
||||
assert(i<M);
|
||||
return geomIDs[i] & 0x7FFFFFFF;
|
||||
}
|
||||
|
||||
/* Returns the primitive IDs */
|
||||
__forceinline vint<M>& primID() { return primIDs; }
|
||||
@@ -136,7 +146,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)
|
||||
__forceinline void fill(const PrimRefT* prims, size_t& begin, size_t end, Scene* scene, bool last)
|
||||
{
|
||||
vint<M> geomID, primID;
|
||||
vint<M> v0;
|
||||
@@ -161,18 +171,18 @@ namespace embree
|
||||
if (begin<end) prim = &prims[begin];
|
||||
}
|
||||
|
||||
new (this) LineMi(v0,geomID,primID); // FIXME: use non temporal store
|
||||
new (this) LineMi(v0,geomID,primID,last); // FIXME: use non temporal store
|
||||
}
|
||||
|
||||
__forceinline LBBox3fa fillMB(const PrimRef* prims, size_t& begin, size_t end, Scene* scene, size_t itime)
|
||||
__forceinline LBBox3fa fillMB(const PrimRef* prims, size_t& begin, size_t end, Scene* scene, size_t itime, bool last)
|
||||
{
|
||||
fill(prims,begin,end,scene);
|
||||
fill(prims,begin,end,scene,last);
|
||||
return linearBounds(scene,itime);
|
||||
}
|
||||
|
||||
__forceinline LBBox3fa fillMB(const PrimRefMB* prims, size_t& begin, size_t end, Scene* scene, const BBox1f time_range)
|
||||
__forceinline LBBox3fa fillMB(const PrimRefMB* prims, size_t& begin, size_t end, Scene* scene, const BBox1f time_range, bool last)
|
||||
{
|
||||
fill(prims,begin,end,scene);
|
||||
fill(prims,begin,end,scene,last);
|
||||
return linearBounds(scene,time_range);
|
||||
}
|
||||
|
||||
@@ -193,7 +203,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 << ", " << line.primIDs << "}";
|
||||
return cout << "Line" << M << "i {" << line.v0 << ", " << (line.geomIDs & 0x7FFFFFFF) << ", " << line.primIDs << "}";
|
||||
}
|
||||
|
||||
public:
|
||||
@@ -208,10 +218,10 @@ namespace embree
|
||||
Vec4vf4& p1,
|
||||
const Scene* scene) const
|
||||
{
|
||||
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 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 vfloat4 a0 = vfloat4::loadu(geom0->vertexPtr(v0[0]));
|
||||
const vfloat4 a1 = vfloat4::loadu(geom1->vertexPtr(v0[1]));
|
||||
@@ -258,10 +268,10 @@ namespace embree
|
||||
const Scene* scene,
|
||||
float time) const
|
||||
{
|
||||
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 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 vfloat4 numTimeSegments(geom0->fnumTimeSegments, geom1->fnumTimeSegments, geom2->fnumTimeSegments, geom3->fnumTimeSegments);
|
||||
vfloat4 ftime;
|
||||
|
||||
+18
-10
@@ -26,6 +26,7 @@ namespace embree
|
||||
{
|
||||
Type ();
|
||||
size_t size(const char* This) const;
|
||||
bool last(const char* This) const;
|
||||
};
|
||||
static Type type;
|
||||
|
||||
@@ -43,42 +44,49 @@ namespace embree
|
||||
public:
|
||||
|
||||
/*! constructs a virtual object */
|
||||
Object (unsigned geomID, unsigned primID)
|
||||
: _geomID(geomID), _primID(primID) {}
|
||||
Object (unsigned geomID, unsigned primID, bool last)
|
||||
: _geomID(geomID | (unsigned(last) << 31)), _primID(primID) {}
|
||||
|
||||
__forceinline unsigned geomID() const {
|
||||
return _geomID;
|
||||
/*! checks if this is the last primitive */
|
||||
__forceinline unsigned last() const {
|
||||
return _geomID & 0x80000000;
|
||||
}
|
||||
|
||||
/*! returns geometry ID */
|
||||
__forceinline unsigned geomID() const {
|
||||
return _geomID & 0x7FFFFFFF;
|
||||
}
|
||||
|
||||
/*! 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)
|
||||
__forceinline void fill(const PrimRef* prims, size_t& i, size_t end, Scene* scene, bool last)
|
||||
{
|
||||
const PrimRef& prim = prims[i]; i++;
|
||||
new (this) Object(prim.geomID(), prim.primID());
|
||||
new (this) Object(prim.geomID(), prim.primID(),last);
|
||||
}
|
||||
|
||||
/*! fill triangle from triangle list */
|
||||
__forceinline LBBox3fa fillMB(const PrimRef* prims, size_t& i, size_t end, Scene* scene, size_t itime)
|
||||
__forceinline LBBox3fa fillMB(const PrimRef* prims, size_t& i, size_t end, Scene* scene, size_t itime, bool last)
|
||||
{
|
||||
const PrimRef& prim = prims[i]; i++;
|
||||
const unsigned geomID = prim.geomID();
|
||||
const unsigned primID = prim.primID();
|
||||
new (this) Object(geomID, primID);
|
||||
new (this) Object(geomID, primID,last);
|
||||
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)
|
||||
__forceinline LBBox3fa fillMB(const PrimRefMB* prims, size_t& i, size_t end, Scene* scene, const BBox1f time_range, bool last)
|
||||
{
|
||||
const PrimRefMB& prim = prims[i]; i++;
|
||||
const unsigned geomID = prim.geomID();
|
||||
const unsigned primID = prim.primID();
|
||||
new (this) Object(geomID, primID);
|
||||
new (this) Object(geomID, primID,last);
|
||||
AccelSet* accel = (AccelSet*) scene->get(geomID);
|
||||
return accel->linearBounds(primID,time_range);
|
||||
}
|
||||
|
||||
@@ -38,6 +38,10 @@ namespace embree
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool Bezier1v::Type::last(const char* This) const {
|
||||
return ((Bezier1v*)This)->last();
|
||||
}
|
||||
|
||||
Bezier1v::Type Bezier1v::type;
|
||||
|
||||
/********************** Bezier1i **************************/
|
||||
@@ -49,6 +53,10 @@ namespace embree
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool Bezier1i::Type::last(const char* This) const {
|
||||
return ((Bezier1i*)This)->last();
|
||||
}
|
||||
|
||||
Bezier1i::Type Bezier1i::type;
|
||||
|
||||
/********************** Line4i **************************/
|
||||
@@ -62,6 +70,11 @@ namespace embree
|
||||
return ((Line4i*)This)->size();
|
||||
}
|
||||
|
||||
template<>
|
||||
bool Line4i::Type::last(const char* This) const {
|
||||
return ((Line4i*)This)->last();
|
||||
}
|
||||
|
||||
/********************** Triangle4 **************************/
|
||||
|
||||
template<>
|
||||
@@ -73,6 +86,11 @@ namespace embree
|
||||
return ((Triangle4*)This)->size();
|
||||
}
|
||||
|
||||
template<>
|
||||
bool Triangle4::Type::last(const char* This) const {
|
||||
return ((Triangle4*)This)->last();
|
||||
}
|
||||
|
||||
/********************** Triangle4v **************************/
|
||||
|
||||
template<>
|
||||
@@ -84,6 +102,11 @@ namespace embree
|
||||
return ((Triangle4v*)This)->size();
|
||||
}
|
||||
|
||||
template<>
|
||||
bool Triangle4v::Type::last(const char* This) const {
|
||||
return ((Triangle4v*)This)->last();
|
||||
}
|
||||
|
||||
/********************** Triangle4i **************************/
|
||||
|
||||
template<>
|
||||
@@ -95,6 +118,11 @@ namespace embree
|
||||
return ((Triangle4i*)This)->size();
|
||||
}
|
||||
|
||||
template<>
|
||||
bool Triangle4i::Type::last(const char* This) const {
|
||||
return ((Triangle4i*)This)->last();
|
||||
}
|
||||
|
||||
/********************** Triangle4vMB **************************/
|
||||
|
||||
template<>
|
||||
@@ -106,6 +134,11 @@ namespace embree
|
||||
return ((Triangle4vMB*)This)->size();
|
||||
}
|
||||
|
||||
template<>
|
||||
bool Triangle4vMB::Type::last(const char* This) const {
|
||||
return ((Triangle4vMB*)This)->last();
|
||||
}
|
||||
|
||||
/********************** Quad4v **************************/
|
||||
|
||||
template<>
|
||||
@@ -117,6 +150,11 @@ namespace embree
|
||||
return ((Quad4v*)This)->size();
|
||||
}
|
||||
|
||||
template<>
|
||||
bool Quad4v::Type::last(const char* This) const {
|
||||
return ((Quad4v*)This)->last();
|
||||
}
|
||||
|
||||
/********************** Quad4i **************************/
|
||||
|
||||
template<>
|
||||
@@ -128,6 +166,11 @@ namespace embree
|
||||
return ((Quad4i*)This)->size();
|
||||
}
|
||||
|
||||
template<>
|
||||
bool Quad4i::Type::last(const char* This) const {
|
||||
return ((Quad4i*)This)->last();
|
||||
}
|
||||
|
||||
/********************** SubdivPatch1 **************************/
|
||||
|
||||
SubdivPatch1Cached::Type::Type ()
|
||||
@@ -137,6 +180,10 @@ namespace embree
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool SubdivPatch1Cached::Type::last(const char* This) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
SubdivPatch1Cached::Type SubdivPatch1Cached::type;
|
||||
|
||||
/********************** SubdivPatch1Cached **************************/
|
||||
@@ -148,6 +195,10 @@ namespace embree
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool SubdivPatch1Cached::TypeCached::last(const char* This) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
SubdivPatch1Cached::TypeCached SubdivPatch1Cached::type_cached;
|
||||
|
||||
/********************** Virtual Object **************************/
|
||||
@@ -159,5 +210,9 @@ namespace embree
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool Object::Type::last(const char* This) const {
|
||||
return ((Object*)This)->last();
|
||||
}
|
||||
|
||||
Object::Type Object::type;
|
||||
}
|
||||
@@ -33,6 +33,9 @@ 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
|
||||
|
||||
+33
-22
@@ -30,6 +30,7 @@ namespace embree
|
||||
{
|
||||
Type();
|
||||
size_t size(const char* This) const;
|
||||
bool last(const char* This) const;
|
||||
};
|
||||
static Type type;
|
||||
|
||||
@@ -55,8 +56,12 @@ namespace embree
|
||||
const vint<M>& v2,
|
||||
const vint<M>& v3,
|
||||
const vint<M>& geomIDs,
|
||||
const vint<M>& primIDs)
|
||||
: v0(v0),v1(v1), v2(v2), v3(v3), geomIDs(geomIDs), primIDs(primIDs) {}
|
||||
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;
|
||||
}
|
||||
|
||||
/* Returns a mask that tells which quads are valid */
|
||||
__forceinline vbool<M> valid() const { return primIDs != vint<M>(-1); }
|
||||
@@ -67,10 +72,16 @@ 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); assert(geomIDs[i] != -1); return geomIDs[i]; }
|
||||
__forceinline int geomID(const size_t i) const {
|
||||
assert(i<M);
|
||||
return geomIDs[i] & 0x7FFFFFFF;
|
||||
}
|
||||
|
||||
/* Returns the primitive IDs */
|
||||
__forceinline vint<M>& primID() { return primIDs; }
|
||||
@@ -223,7 +234,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)
|
||||
__forceinline void fill(const PrimRefT* prims, size_t& begin, size_t end, Scene* scene, bool last)
|
||||
{
|
||||
vint<M> geomID = -1, primID = -1;
|
||||
vint<M> v0 = zero, v1 = zero, v2 = zero, v3 = zero;
|
||||
@@ -256,23 +267,23 @@ namespace embree
|
||||
if (begin<end) prim = &prims[begin];
|
||||
}
|
||||
|
||||
new (this) QuadMi(v0,v1,v2,v3,geomID,primID); // FIXME: use non temporal store
|
||||
new (this) QuadMi(v0,v1,v2,v3,geomID,primID,last); // FIXME: use non temporal store
|
||||
}
|
||||
|
||||
__forceinline LBBox3fa fillMB(const PrimRef* prims, size_t& begin, size_t end, Scene* scene, size_t itime)
|
||||
__forceinline LBBox3fa fillMB(const PrimRef* prims, size_t& begin, size_t end, Scene* scene, size_t itime, bool last)
|
||||
{
|
||||
fill(prims, begin, end, scene);
|
||||
fill(prims, begin, end, scene, last);
|
||||
return linearBounds(scene, itime);
|
||||
}
|
||||
|
||||
__forceinline LBBox3fa fillMB(const PrimRefMB* prims, size_t& begin, size_t end, Scene* scene, const BBox1f time_range)
|
||||
__forceinline LBBox3fa fillMB(const PrimRefMB* prims, size_t& begin, size_t end, Scene* scene, const BBox1f time_range, bool last)
|
||||
{
|
||||
fill(prims, begin, end, scene);
|
||||
fill(prims, begin, end, scene, last);
|
||||
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 << ", primID = " << quad.primIDs << " )";
|
||||
return cout << "QuadMi<" << M << ">( v0 = " << quad.v0 << ", v1 = " << quad.v1 << ", v2 = " << quad.v2 << ", v3 = " << quad.v3 << ", geomID = " << (quad.geomIDs & 0x7FFFFFFF) << ", primID = " << quad.primIDs << " )";
|
||||
}
|
||||
|
||||
/* Updates the primitive */
|
||||
@@ -313,10 +324,10 @@ namespace embree
|
||||
{
|
||||
prefetchL1(((char*)this)+0*64);
|
||||
prefetchL1(((char*)this)+1*64);
|
||||
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 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 vfloat4 a0 = vfloat4::loadu(vertices0 + v0[0]);
|
||||
const vfloat4 a1 = vfloat4::loadu(vertices1 + v0[1]);
|
||||
const vfloat4 a2 = vfloat4::loadu(vertices2 + v0[2]);
|
||||
@@ -348,10 +359,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[geomID(0)];
|
||||
const int* vertices1 = scene->vertices[geomID(1)];
|
||||
const int* vertices2 = scene->vertices[geomID(2)];
|
||||
const int* vertices3 = scene->vertices[geomID(3)];
|
||||
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 vfloat4 a0 = vfloat4::loadu(vertices0 + v0[0]);
|
||||
const vfloat4 a1 = vfloat4::loadu(vertices1 + v0[1]);
|
||||
@@ -440,10 +451,10 @@ namespace embree
|
||||
const Scene *const scene,
|
||||
const float time) const
|
||||
{
|
||||
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 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 vfloat4 numTimeSegments(mesh0->fnumTimeSegments, mesh1->fnumTimeSegments, mesh2->fnumTimeSegments, mesh3->fnumTimeSegments);
|
||||
vfloat4 ftime;
|
||||
|
||||
@@ -29,6 +29,7 @@ namespace embree
|
||||
{
|
||||
Type();
|
||||
size_t size(const char* This) const;
|
||||
bool last(const char* This) const;
|
||||
};
|
||||
static Type type;
|
||||
|
||||
@@ -46,8 +47,11 @@ 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)
|
||||
: v0(v0), v1(v1), v2(v2), v3(v3), geomIDs(geomIDs), primIDs(primIDs) {}
|
||||
__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;
|
||||
}
|
||||
|
||||
/* Returns a mask that tells which quads are valid */
|
||||
__forceinline vbool<M> valid() const { return geomIDs != vint<M>(-1); }
|
||||
@@ -58,10 +62,13 @@ 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]; }
|
||||
__forceinline int geomID(const size_t i) const { assert(i<M); return geomIDs[i] & 0x7FFFFFFF; }
|
||||
|
||||
/* Returns the primitive IDs */
|
||||
__forceinline vint<M> primID() { return primIDs; }
|
||||
@@ -104,7 +111,7 @@ namespace embree
|
||||
}
|
||||
|
||||
/* Fill quad from quad list */
|
||||
__forceinline void fill(const PrimRef* prims, size_t& begin, size_t end, Scene* scene)
|
||||
__forceinline void fill(const PrimRef* prims, size_t& begin, size_t end, Scene* scene, bool last)
|
||||
{
|
||||
vint<M> vgeomID = -1, vprimID = -1;
|
||||
Vec3vf<M> v0 = zero, v1 = zero, v2 = zero, v3 = zero;
|
||||
@@ -127,7 +134,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));
|
||||
QuadMv::store_nt(this,QuadMv(v0,v1,v2,v3,vgeomID,vprimID,last));
|
||||
}
|
||||
|
||||
/* Updates the primitive */
|
||||
@@ -140,7 +147,7 @@ namespace embree
|
||||
for (size_t i=0; i<M; i++)
|
||||
{
|
||||
if (primID(i) == -1) break;
|
||||
const unsigned geomId = geomID(i);
|
||||
const unsigned geomId = geomIDs[i]; // copies last bit
|
||||
const unsigned primId = primID(i);
|
||||
const QuadMesh::Quad& quad = mesh->quad(primId);
|
||||
const Vec3fa p0 = mesh->vertex(quad.v[0]);
|
||||
@@ -155,7 +162,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;
|
||||
}
|
||||
new (this) QuadMv(v0,v1,v2,v3,vgeomID,vprimID);
|
||||
QuadMv::store_nt(this,QuadMv(v0,v1,v2,v3,vgeomID,vprimID,false));
|
||||
return bounds;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ namespace embree
|
||||
{
|
||||
Type ();
|
||||
size_t size(const char* This) const;
|
||||
bool last(const char* This) const;
|
||||
};
|
||||
|
||||
static Type type;
|
||||
@@ -36,6 +37,7 @@ namespace embree
|
||||
{
|
||||
TypeCached ();
|
||||
size_t size(const char* This) const;
|
||||
bool last(const char* This) const;
|
||||
};
|
||||
|
||||
static TypeCached type_cached;
|
||||
|
||||
@@ -31,6 +31,7 @@ namespace embree
|
||||
{
|
||||
Type();
|
||||
size_t size(const char* This) const;
|
||||
bool last(const char* This) const;
|
||||
};
|
||||
static Type type;
|
||||
|
||||
@@ -48,8 +49,11 @@ 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)
|
||||
: v0(v0), e1(v0-v1), e2(v2-v0), geomIDs(geomIDs), primIDs(primIDs) {}
|
||||
__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;
|
||||
}
|
||||
|
||||
/* Returns a mask that tells which triangles are valid */
|
||||
__forceinline vbool<M> valid() const { return geomIDs != vint<M>(-1); }
|
||||
@@ -60,10 +64,13 @@ 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]; }
|
||||
__forceinline int geomID(const size_t i) const { assert(i<M); return geomIDs[i] & 0x7FFFFFFF; }
|
||||
|
||||
/* Returns the primitive IDs */
|
||||
__forceinline vint<M>& primID() { return primIDs; }
|
||||
@@ -106,7 +113,7 @@ namespace embree
|
||||
}
|
||||
|
||||
/* Fill triangle from triangle list */
|
||||
__forceinline void fill(const PrimRef* prims, size_t& begin, size_t end, Scene* scene)
|
||||
__forceinline void fill(const PrimRef* prims, size_t& begin, size_t end, Scene* scene, bool last)
|
||||
{
|
||||
vint<M> vgeomID = -1, vprimID = -1;
|
||||
Vec3vf<M> v0 = zero, v1 = zero, v2 = zero;
|
||||
@@ -127,7 +134,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));
|
||||
TriangleM::store_nt(this,TriangleM(v0,v1,v2,vgeomID,vprimID,last));
|
||||
}
|
||||
|
||||
/* Updates the primitive */
|
||||
@@ -137,10 +144,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(geomID(i) == -1)) break;
|
||||
const unsigned geomId = geomID(i);
|
||||
if (unlikely(!valid(i))) break;
|
||||
const unsigned geomId = geomIDs[i]; // copies last bit
|
||||
const unsigned primId = primID(i);
|
||||
const TriangleMesh::Triangle& tri = mesh->triangle(primId);
|
||||
const Vec3fa p0 = mesh->vertex(tri.v[0]);
|
||||
@@ -153,7 +160,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));
|
||||
TriangleM::store_nt(this,TriangleM(v0,v1,v2,vgeomID,vprimID,false));
|
||||
return bounds;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ namespace embree
|
||||
{
|
||||
Type();
|
||||
size_t size(const char* This) const;
|
||||
bool last(const char* This) const;
|
||||
};
|
||||
static Type type;
|
||||
|
||||
@@ -54,8 +55,12 @@ namespace embree
|
||||
const vint<M>& v1,
|
||||
const vint<M>& v2,
|
||||
const vint<M>& geomIDs,
|
||||
const vint<M>& primIDs)
|
||||
: v0(v0), v1(v1), v2(v2), geomIDs(geomIDs), primIDs(primIDs) {}
|
||||
const vint<M>& primIDs,
|
||||
const bool last)
|
||||
: v0(v0), v1(v1), v2(v2), geomIDs(geomIDs), primIDs(primIDs)
|
||||
{
|
||||
this->geomIDs[0] |= unsigned(last) << 31;
|
||||
}
|
||||
|
||||
/* Returns a mask that tells which triangles are valid */
|
||||
__forceinline vbool<M> valid() const { return primIDs != vint<M>(-1); }
|
||||
@@ -66,9 +71,12 @@ 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]; }
|
||||
__forceinline int geomID(const size_t i) const { assert(i<M); return geomIDs[i] & 0x7FFFFFFF; }
|
||||
|
||||
/* Returns the primitive IDs */
|
||||
__forceinline vint<M> primID() const { return primIDs; }
|
||||
@@ -210,7 +218,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)
|
||||
__forceinline void fill(const PrimRefT* prims, size_t& begin, size_t end, Scene* scene, bool last)
|
||||
{
|
||||
vint<M> geomID = -1, primID = -1;
|
||||
vint<M> v0 = zero, v1 = zero, v2 = zero;
|
||||
@@ -241,18 +249,18 @@ namespace embree
|
||||
if (begin<end) prim = &prims[begin];
|
||||
}
|
||||
|
||||
new (this) TriangleMi(v0,v1,v2,geomID,primID); // FIXME: use non temporal store
|
||||
new (this) TriangleMi(v0,v1,v2,geomID,primID,last); // FIXME: use non temporal store
|
||||
}
|
||||
|
||||
__forceinline LBBox3fa fillMB(const PrimRef* prims, size_t& begin, size_t end, Scene* scene, size_t itime)
|
||||
__forceinline LBBox3fa fillMB(const PrimRef* prims, size_t& begin, size_t end, Scene* scene, size_t itime, bool last)
|
||||
{
|
||||
fill(prims, begin, end, scene);
|
||||
fill(prims, begin, end, scene, last);
|
||||
return linearBounds(scene, itime);
|
||||
}
|
||||
|
||||
__forceinline LBBox3fa fillMB(const PrimRefMB* prims, size_t& begin, size_t end, Scene* scene, const BBox1f time_range)
|
||||
__forceinline LBBox3fa fillMB(const PrimRefMB* prims, size_t& begin, size_t end, Scene* scene, const BBox1f time_range, bool last)
|
||||
{
|
||||
fill(prims, begin, end, scene);
|
||||
fill(prims, begin, end, scene, last);
|
||||
return linearBounds(scene, time_range);
|
||||
}
|
||||
|
||||
@@ -288,10 +296,10 @@ namespace embree
|
||||
Vec3vf4& p2,
|
||||
const Scene* const scene) const
|
||||
{
|
||||
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 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 vfloat4 a0 = vfloat4::loadu(vertices0 + v0[0]);
|
||||
const vfloat4 a1 = vfloat4::loadu(vertices1 + v0[1]);
|
||||
const vfloat4 a2 = vfloat4::loadu(vertices2 + v0[2]);
|
||||
@@ -347,10 +355,10 @@ namespace embree
|
||||
const Scene *const scene,
|
||||
const float time) const
|
||||
{
|
||||
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 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 vfloat4 numTimeSegments(mesh0->fnumTimeSegments, mesh1->fnumTimeSegments, mesh2->fnumTimeSegments, mesh3->fnumTimeSegments);
|
||||
vfloat4 ftime;
|
||||
|
||||
@@ -29,6 +29,7 @@ namespace embree
|
||||
{
|
||||
Type();
|
||||
size_t size(const char* This) const;
|
||||
bool last(const char* This) const;
|
||||
};
|
||||
static Type type;
|
||||
|
||||
@@ -46,8 +47,11 @@ 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)
|
||||
: v0(v0), v1(v1), v2(v2), geomIDs(geomIDs), primIDs(primIDs) {}
|
||||
__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;
|
||||
}
|
||||
|
||||
/* Returns a mask that tells which triangles are valid */
|
||||
__forceinline vbool<M> valid() const { return geomIDs != vint<M>(-1); }
|
||||
@@ -58,10 +62,13 @@ 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]; }
|
||||
__forceinline int geomID(const size_t i) const { assert(i<M); return geomIDs[i] & 0x7FFFFFFF; }
|
||||
|
||||
/* Returns the primitive IDs */
|
||||
__forceinline vint<M>& primID() { return primIDs; }
|
||||
@@ -101,7 +108,7 @@ namespace embree
|
||||
}
|
||||
|
||||
/* Fill triangle from triangle list */
|
||||
__forceinline void fill(const PrimRef* prims, size_t& begin, size_t end, Scene* scene)
|
||||
__forceinline void fill(const PrimRef* prims, size_t& begin, size_t end, Scene* scene, bool last)
|
||||
{
|
||||
vint<M> vgeomID = -1, vprimID = -1;
|
||||
Vec3vf<M> v0 = zero, v1 = zero, v2 = zero;
|
||||
@@ -122,7 +129,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));
|
||||
TriangleMv::store_nt(this,TriangleMv(v0,v1,v2,vgeomID,vprimID,last));
|
||||
}
|
||||
|
||||
/* Updates the primitive */
|
||||
@@ -135,7 +142,7 @@ namespace embree
|
||||
for (size_t i=0; i<M; i++)
|
||||
{
|
||||
if (primID(i) == -1) break;
|
||||
const unsigned geomId = geomID(i);
|
||||
const unsigned geomId = geomIDs[i]; // copies last bit
|
||||
const unsigned primId = primID(i);
|
||||
const TriangleMesh::Triangle& tri = mesh->triangle(primId);
|
||||
const Vec3fa p0 = mesh->vertex(tri.v[0]);
|
||||
@@ -148,7 +155,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);
|
||||
new (this) TriangleMv(v0,v1,v2,vgeomID,vprimID,false);
|
||||
return bounds;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ namespace embree
|
||||
{
|
||||
Type();
|
||||
size_t size(const char* This) const;
|
||||
bool last(const char* This) const;
|
||||
};
|
||||
|
||||
static Type type;
|
||||
@@ -53,8 +54,12 @@ 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)
|
||||
: v0(a0), v1(b0), v2(c0), dv0(a1-a0), dv1(b1-b0), dv2(c1-c0), geomIDs(geomIDs), primIDs(primIDs) {}
|
||||
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;
|
||||
}
|
||||
|
||||
/* Returns a mask that tells which triangles are valid */
|
||||
__forceinline vbool<M> valid() const { return geomIDs != vint<M>(-1); }
|
||||
@@ -65,10 +70,13 @@ 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]; }
|
||||
__forceinline int geomID(const size_t i) const { assert(i<M); return geomIDs[i] & 0x7FFFFFFF; }
|
||||
|
||||
/* Returns the primitive IDs */
|
||||
__forceinline vint<M>& primID() { return primIDs; }
|
||||
@@ -116,7 +124,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)
|
||||
__forceinline LBBox3fa fillMB(const PrimRef* prims, size_t& begin, size_t end, Scene* scene, size_t itime, bool last)
|
||||
{
|
||||
vint<M> vgeomID = -1, vprimID = -1;
|
||||
Vec3vf<M> va0 = zero, vb0 = zero, vc0 = zero;
|
||||
@@ -147,12 +155,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);
|
||||
new (this) TriangleMvMB(va0,va1,vb0,vb1,vc0,vc1,vgeomID,vprimID,last);
|
||||
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)
|
||||
__forceinline LBBox3fa fillMB(const PrimRefMB* prims, size_t& begin, size_t end, Scene* scene, const BBox1f time_range, bool last)
|
||||
{
|
||||
vint<M> vgeomID = -1, vprimID = -1;
|
||||
Vec3vf<M> va0 = zero, vb0 = zero, vc0 = zero;
|
||||
@@ -190,7 +198,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);
|
||||
new (this) TriangleMvMB(va0,va1,vb0,vb1,vc0,vc1,vgeomID,vprimID,last);
|
||||
return allBounds;
|
||||
}
|
||||
|
||||
|
||||
@@ -214,7 +214,6 @@ 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,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));
|
||||
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));
|
||||
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,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));
|
||||
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));
|
||||
|
||||
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 8 32 > ' + logFile
|
||||
command += ' -rtcore verbose=2 -benchmark 4 16 > ' + logFile
|
||||
os.system(command)
|
||||
|
||||
def renderLoop():
|
||||
|
||||
@@ -94,7 +94,7 @@ outImageFileJpg = name + ".jpg"
|
||||
diffImageFileTga= name + ".diff.tga"
|
||||
diffImageFileJpg= name + ".diff.jpg"
|
||||
|
||||
executable = executable + " -rtcore verbose=0"
|
||||
executable = executable + " -rtcore verbose=2"
|
||||
|
||||
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://10.123.110.111:80/embree buildspec.txt --tables-directory mytables
|
||||
kwadmin --url http://10.123.110.111:80 load embree mytables
|
||||
kwbuildproject --force --url http://localhost:8080/embree buildspec.txt --tables-directory mytables
|
||||
kwadmin --url http://localhost:8080 load embree mytables
|
||||
#kwcheck list -F detailed
|
||||
#kwcheck list -F detailed > klocwork.log
|
||||
@@ -57,7 +57,6 @@ 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,7 +19,6 @@ cmake \
|
||||
|
||||
# set release settings
|
||||
cmake \
|
||||
-D EMBREE_STACK_PROTECTOR=ON\
|
||||
-D EMBREE_MAX_ISA=AVX2 \
|
||||
-D EMBREE_TUTORIALS_IMAGE_MAGICK=OFF \
|
||||
-D EMBREE_TUTORIALS_LIBJPEG=OFF \
|
||||
|
||||
@@ -12,7 +12,6 @@ REM set release settings
|
||||
cmake -L ^
|
||||
-G "Visual Studio 12 2013" ^
|
||||
-T "Intel C++ Compiler 16.0" ^
|
||||
-D EMBREE_STACK_PROTECTOR=ON ^
|
||||
-D EMBREE_MAX_ISA=AVX512SKX ^
|
||||
-D EMBREE_TUTORIALS_IMAGE_MAGICK=OFF ^
|
||||
-D EMBREE_TUTORIALS_LIBJPEG=OFF ^
|
||||
|
||||
@@ -1,117 +0,0 @@
|
||||
|
||||
message("CTEST_BUILD_OPTIONS = ${CTEST_BUILD_OPTIONS}")
|
||||
|
||||
# project and repository to clone from
|
||||
SET(CTEST_PROJECT_NAME "Embree")
|
||||
SET(TEST_REPOSITORY "https://github.com/embree/embree.git")
|
||||
|
||||
SET(TEST_ROOT_DIRECTORY "${CTEST_SCRIPT_DIRECTORY}/..")
|
||||
STRING(REPLACE ":/" ":\\" TEST_ROOT_DIRECTORY1 "${TEST_ROOT_DIRECTORY}") # cygwin git has issues with c:/dir paths
|
||||
#SET(TEST_MODELS_DIRECTORY ${TEST_ROOT_DIRECTORY}/dependencies/embree-models)
|
||||
SET(TEST_MODELS_DIRECTORY $ENV{HOME}/embree-models)
|
||||
MESSAGE("TEST_MODELS_DIRECTORY = ${TEST_MODELS_DIRECTORY}")
|
||||
|
||||
# set source and build directory
|
||||
set(CTEST_SOURCE_DIRECTORY "${TEST_ROOT_DIRECTORY1}")
|
||||
message("CTEST_SOURCE_DIRECTORY = ${CTEST_SOURCE_DIRECTORY}")
|
||||
set(CTEST_BINARY_DIRECTORY "${TEST_ROOT_DIRECTORY1}/build")
|
||||
|
||||
# update external model repository
|
||||
FIND_PROGRAM(CTEST_GIT_COMMAND NAMES git)
|
||||
|
||||
# macro that updates the test models
|
||||
MACRO(update_test_models)
|
||||
IF(NOT EXISTS "${TEST_MODELS_DIRECTORY}")
|
||||
MESSAGE("cloning test models ...")
|
||||
EXECUTE_PROCESS(
|
||||
COMMAND ${CTEST_GIT_COMMAND} "clone" "git@git.sdvis.org:embree-models.git" embree-models
|
||||
WORKING_DIRECTORY $ENV{HOME}
|
||||
)
|
||||
ELSE()
|
||||
MESSAGE("updating test models ...")
|
||||
EXECUTE_PROCESS(
|
||||
COMMAND ${CTEST_GIT_COMMAND} "fetch"
|
||||
WORKING_DIRECTORY ${TEST_MODELS_DIRECTORY}
|
||||
)
|
||||
ENDIF()
|
||||
IF (NOT TEST_MODELS_HASH)
|
||||
MESSAGE(FATAL_ERROR "no TEST_MODELS_HASH set")
|
||||
ENDIF()
|
||||
MESSAGE("checking out test models: ${TEST_MODELS_HASH}")
|
||||
EXECUTE_PROCESS(
|
||||
COMMAND ${CTEST_GIT_COMMAND} "checkout" ${TEST_MODELS_HASH}
|
||||
WORKING_DIRECTORY ${TEST_MODELS_DIRECTORY}
|
||||
)
|
||||
ENDMACRO()
|
||||
|
||||
# increase default output sizes for test outputs
|
||||
IF (NOT DEFINED CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE)
|
||||
SET(CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE 100000)
|
||||
ENDIF()
|
||||
IF(NOT DEFINED CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE)
|
||||
SET(CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE 800000)
|
||||
ENDIF()
|
||||
|
||||
# enable testing in Embree
|
||||
SET (CTEST_BUILD_OPTIONS "${CTEST_BUILD_OPTIONS} -D BUILD_TESTING:BOOL=ON -D EMBREE_TESTING_MODEL_DIR:PATH=${TEST_MODELS_DIRECTORY}")
|
||||
|
||||
# set site based on this machine's hostname
|
||||
SITE_NAME(HOSTNAME)
|
||||
set(CTEST_SITE "${HOSTNAME}")
|
||||
|
||||
# drop location
|
||||
set(CTEST_DROP_METHOD "http")
|
||||
IF(NOT CTEST_DROP_SITE)
|
||||
set(CTEST_DROP_SITE "10.123.110.90")
|
||||
ENDIF()
|
||||
set(CTEST_DROP_LOCATION "/CDash/submit.php?project=${CTEST_PROJECT_NAME}")
|
||||
set(CTEST_DROP_SITE_CDASH TRUE)
|
||||
|
||||
# get OS and CPU information
|
||||
find_program(UNAME NAMES uname)
|
||||
macro(getuname name flag)
|
||||
exec_program("${UNAME}" ARGS "${flag}" OUTPUT_VARIABLE "${name}")
|
||||
endmacro(getuname)
|
||||
|
||||
getuname(osname -s)
|
||||
getuname(osrel -r)
|
||||
getuname(cpu -m)
|
||||
|
||||
# build using as many processes as we have processors
|
||||
include(ProcessorCount)
|
||||
ProcessorCount(numProcessors)
|
||||
if(numProcessors EQUAL 0)
|
||||
SET(numProcessors 1)
|
||||
endif()
|
||||
|
||||
# set build name
|
||||
set(CTEST_BUILD_NAME "${TEST_NAME}-${osname}-${cpu}")
|
||||
set(CTEST_CMAKE_GENERATOR "Unix Makefiles")
|
||||
IF (WIN32)
|
||||
set(CTEST_BUILD_COMMAND "${CMAKE_COMMAND} --build . --config ${CTEST_CONFIGURATION_TYPE}")
|
||||
ELSE()
|
||||
set(CTEST_BUILD_COMMAND "make -j ${numProcessors}")
|
||||
ENDIF()
|
||||
|
||||
###################
|
||||
# execute the test
|
||||
###################
|
||||
|
||||
# requires CMake 2.8 or higher for git!!!
|
||||
#set(CTEST_UPDATE_COMMAND "${CTEST_GIT_COMMAND}")
|
||||
|
||||
set(CTEST_CONFIGURE_COMMAND "${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE:STRING=${CTEST_BUILD_CONFIGURATION}")
|
||||
set(CTEST_CONFIGURE_COMMAND "${CTEST_CONFIGURE_COMMAND} ${CTEST_BUILD_OPTIONS}")
|
||||
set(CTEST_CONFIGURE_COMMAND "${CTEST_CONFIGURE_COMMAND} ..")
|
||||
|
||||
# start the test
|
||||
ctest_empty_binary_directory(${CTEST_BINARY_DIRECTORY})
|
||||
ctest_start("Continuous")
|
||||
#ctest_update (RETURN_VALUE count)
|
||||
update_test_models()
|
||||
ctest_configure()
|
||||
ctest_build()
|
||||
IF (NOT CTEST_SKIP_TESTING)
|
||||
ctest_test()
|
||||
ENDIF()
|
||||
ctest_submit()
|
||||
-514
@@ -1,514 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import sys
|
||||
import os
|
||||
import ctypes
|
||||
import time
|
||||
import datetime
|
||||
import json
|
||||
import socket
|
||||
import subprocess
|
||||
|
||||
g_cdash = ""
|
||||
g_config = {}
|
||||
g_mode = "Experimental"
|
||||
g_intensive = False
|
||||
g_debugMode = False
|
||||
g_singleConfig = ""
|
||||
|
||||
def escape(str):
|
||||
str = str.replace("\\",r"\\")
|
||||
str = str.replace("\"",r"\"")
|
||||
str = str.replace(":","\:")
|
||||
return str
|
||||
|
||||
# detect platform
|
||||
if sys.platform.startswith("win"):
|
||||
dash = '\\'
|
||||
SEM_FAILCRITICALERRORS = 0x0001
|
||||
SEM_NOGPFAULTERRORBOX = 0x0002
|
||||
SEM_NOOPENFILEERRORBOX = 0x8000
|
||||
ctypes.windll.kernel32.SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);
|
||||
OS = "windows"
|
||||
elif sys.platform.startswith("cygwin"):
|
||||
dash = '/'
|
||||
SEM_FAILCRITICALERRORS = 0x0001
|
||||
SEM_NOGPFAULTERRORBOX = 0x0002
|
||||
SEM_NOOPENFILEERRORBOX = 0x8000
|
||||
ctypes.cdll.kernel32.SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);
|
||||
OS = "windows"
|
||||
elif sys.platform.startswith("linux"):
|
||||
dash = '/'
|
||||
OS = "linux"
|
||||
elif sys.platform.startswith("darwin"):
|
||||
dash = '/'
|
||||
OS = "macosx"
|
||||
else:
|
||||
print("unknown platform: "+ sys.platform);
|
||||
sys.exit(1)
|
||||
|
||||
# fast testing
|
||||
def createConfigsLight(branch,build,host):
|
||||
configs = []
|
||||
if host == "tcg-vis-ci-win1":
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"V140", "isa":"AVX2" , "tasking":"TBB", "intensive":"OFF"})
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG", "isa":"AVX2" , "tasking":"TBB", "intensive":"OFF"})
|
||||
if host == "tcg-vis-ci-win2":
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"V120", "isa":"AVX2" , "tasking":"TBB", "intensive":"OFF"})
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"ICC17", "isa":"AVX2" , "tasking":"TBB", "intensive":"OFF"})
|
||||
if host == "tcg-vis-mac-mini":
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG", "isa":"AVX2" , "tasking":"TBB", "intensive":"OFF"})
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"ICC16", "isa":"AVX2" , "tasking":"TBB", "intensive":"OFF"})
|
||||
if host == "tcg-vis-ci-ubuntu1604" or host == "tcg-vis-ubuntu1404":
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG", "isa":"AVX2" , "tasking":"TBB", "intensive":"OFF"})
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"GCC" , "isa":"AVX2" , "tasking":"TBB", "intensive":"OFF"})
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"ICC17", "isa":"AVX512KNL", "tasking":"TBB", "intensive":"OFF" })
|
||||
if host == "k7":
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"ICC17", "isa":"AVX512KNL", "tasking":"TBB", "intensive":"OFF" })
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG4","isa":"AVX512KNL", "tasking":"TBB", "intensive":"OFF" })
|
||||
if host == "swr-ivb-lnx-01":
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"ICC17", "isa":"AVX2", "tasking":"TBB", "klocwork":"ON"})
|
||||
if host == "skylake-b0":
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"ICC17", "isa":"AVX512SKX", "tasking":"TBB", "intensive":"OFF"})
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG4","isa":"AVX512SKX", "tasking":"TBB", "intensive":"OFF"})
|
||||
if host == "test":
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG", "isa":"SSE2" , "tasking":"TBB", "intensive":"OFF"})
|
||||
return configs
|
||||
|
||||
# intensive testing
|
||||
def createConfigsIntensive(branch,build,host):
|
||||
configs = []
|
||||
|
||||
if host == "tcg-vis-ci-win1":
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"ICC18","isa":"AVX512SKX", "tasking":"TBB", "intensive":"ON"})
|
||||
for platform in ["x64", "win32"]:
|
||||
if platform == "win32": intensive = "OFF" # runs only small win32 tests for win32 platform
|
||||
else: intensive = "ON"
|
||||
configs.append({"branch":branch, "platform":platform, "build":build, "compiler":"V140", "isa":"AVX2", "tasking":"TBB", "intensive":intensive})
|
||||
configs.append({"branch":branch, "platform":platform, "build":build, "compiler":"V140", "isa":"AVX2", "tasking":"INT", "intensive":intensive})
|
||||
configs.append({"branch":branch, "platform":platform, "build":build, "compiler":"V140", "isa":"AVX2", "tasking":"PPL", "intensive":intensive})
|
||||
configs.append({"branch":branch, "platform":platform, "build":build, "compiler":"CLANG","isa":"AVX2", "tasking":"TBB", "intensive":intensive})
|
||||
configs.append({"branch":branch, "platform":platform, "build":build, "compiler":"ICC16","isa":"AVX2", "tasking":"TBB", "intensive":intensive})
|
||||
|
||||
elif host == "tcg-vis-ci-win2":
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"ICC17", "isa":"AVX512SKX" , "tasking":"TBB", "intensive":"OFF", "sde":"skx"})
|
||||
for platform in ["x64", "win32"]:
|
||||
if platform == "win32": intensive = "OFF" # runs only small win32 tests for win32 platform
|
||||
else: intensive = "ON"
|
||||
configs.append({"branch":branch, "platform":platform, "build":build, "compiler":"V120", "isa":"SSE2", "tasking":"TBB", "intensive":intensive})
|
||||
configs.append({"branch":branch, "platform":platform, "build":build, "compiler":"V120", "isa":"AVX", "tasking":"INT", "intensive":intensive})
|
||||
configs.append({"branch":branch, "platform":platform, "build":build, "compiler":"V141", "isa":"AVX2", "tasking":"TBB", "intensive":intensive})
|
||||
configs.append({"branch":branch, "platform":platform, "build":build, "compiler":"ICC17", "isa":"AVX2", "tasking":"TBB", "intensive":intensive})
|
||||
|
||||
elif host == "k7":
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"ICC16" , "isa":"AVX512KNL", "tasking":"TBB", "intensive":"ON"})
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"ICC17" , "isa":"AVX512KNL", "tasking":"TBB", "intensive":"ON"})
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG4" , "isa":"AVX512KNL", "tasking":"TBB", "intensive":"ON"})
|
||||
|
||||
elif host == "skylake-b0":
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"ICC17" , "isa":"AVX512SKX", "tasking":"TBB", "intensive":"ON"})
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG4" , "isa":"AVX512SKX", "tasking":"TBB", "intensive":"ON"})
|
||||
|
||||
elif host == "tcg-vis-ci-ubuntu1604" or host == "tcg-vis-ubuntu1404":
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG", "isa":"SSE2", "tasking":"TBB", "intensive":"ON"})
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG", "isa":"AVX" , "tasking":"INT", "intensive":"ON"})
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG", "isa":"AVX2", "tasking":"TBB", "intensive":"ON"})
|
||||
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"GCC" , "isa":"SSE2", "tasking":"TBB", "intensive":"ON"})
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"GCC" , "isa":"AVX" , "tasking":"INT", "intensive":"ON"})
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"GCC" , "isa":"AVX2", "tasking":"TBB", "intensive":"ON"})
|
||||
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"ICC16" , "isa":"SSE2", "tasking":"TBB", "intensive":"ON"})
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"ICC15" , "isa":"AVX" , "tasking":"INT", "intensive":"ON"})
|
||||
|
||||
if build == "RelWithDebInfo":
|
||||
configs.append({"branch":branch, "platform":"x64", "build":"RelWithDebInfo", "compiler":"ICC18" , "isa":"AVX512SKX", "tasking":"TBB", "intensive":"ON"})
|
||||
configs.append({"branch":branch, "platform":"x64", "build":"RelWithDebInfo", "compiler":"ICC17" , "isa":"AVX512KNL", "tasking":"TBB", "intensive":"ON", "memcheck":"ON"})
|
||||
# configs.append({"branch":branch, "platform":"x64", "build":"Release", "compiler":"ICC17" , "isa":"AVX2", "tasking":"TBB", "intensive":"ON", "benchmark":"ON"})
|
||||
else:
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"ICC17" , "isa":"AVX2", "tasking":"TBB", "intensive":"ON"})
|
||||
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG" , "isa":"AVX2" , "tasking":"TBB", "ISPC_SUPPORT":"OFF", "test":False})
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG" , "isa":"AVX2" , "tasking":"TBB", "STATIC_LIB":"ON"})
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG" , "isa":"AVX2" , "tasking":"TBB", "TUTORIALS":"OFF", "test":False})
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG" , "isa":"AVX2" , "tasking":"TBB", "BACKFACE_CULLING":"ON", "test":False})
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG" , "isa":"AVX2" , "tasking":"TBB", "IGNORE_INVALID_RAYS":"ON"})
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG" , "isa":"AVX2" , "tasking":"TBB", "INTERSECTION_FILTER":"OFF", "test":False})
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG" , "isa":"AVX2" , "tasking":"TBB", "RAY_MASK":"ON"})
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG" , "isa":"AVX2" , "tasking":"TBB", "RAY_PACKETS":"OFF"})
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG" , "isa":"AVX2" , "tasking":"TBB", "STAT_COUNTERS":"ON", "test":False})
|
||||
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG4", "isa":["SSE2"], "tasking":"TBB", "test":False })
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG4", "isa":["SSE42"], "tasking":"TBB", "test":False })
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG4", "isa":["AVX"] , "tasking":"TBB", "test":False })
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG4", "isa":["AVX2"] , "tasking":"TBB", "test":False })
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG4", "isa":["AVX512KNL"], "tasking":"TBB", "test":False })
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG4", "isa":["AVX512SKX"], "tasking":"TBB", "test":False })
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG4", "isa":["AVX2","AVX512SKX"] , "tasking":"TBB", "test":False })
|
||||
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG" , "isa":"AVX2" , "tasking":"TBB", "test":False,
|
||||
"TRIS":"ON", "QUADS":"OFF", "LINES":"OFF", "HAIR":"OFF", "SUBDIV":"OFF", "USERGEOM":"OFF" })
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG" , "isa":"AVX2" , "tasking":"TBB", "test":False,
|
||||
"TRIS":"OFF", "QUADS":"ON", "LINES":"OFF", "HAIR":"OFF", "SUBDIV":"OFF", "USERGEOM":"OFF" })
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG" , "isa":"AVX2" , "tasking":"TBB", "test":False,
|
||||
"TRIS":"OFF", "QUADS":"OFF", "LINES":"ON", "HAIR":"OFF", "SUBDIV":"OFF", "USERGEOM":"OFF" })
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG" , "isa":"AVX2" , "tasking":"TBB", "test":False,
|
||||
"TRIS":"OFF", "QUADS":"OFF", "LINES":"OFF", "HAIR":"ON", "SUBDIV":"OFF", "USERGEOM":"OFF" })
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG" , "isa":"AVX2" , "tasking":"TBB", "test":False,
|
||||
"TRIS":"OFF", "QUADS":"OFF", "LINES":"OFF", "HAIR":"OFF", "SUBDIV":"ON", "USERGEOM":"OFF" })
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG" , "isa":"AVX2" , "tasking":"TBB", "test":False,
|
||||
"TRIS":"OFF", "QUADS":"OFF", "LINES":"OFF", "HAIR":"OFF", "SUBDIV":"OFF", "USERGEOM":"ON" })
|
||||
|
||||
elif host == "tcg-vis-mac-mini":
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG", "isa":"SSE2", "tasking":"TBB", "intensive":"ON"})
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG", "isa":"AVX" , "tasking":"INT", "intensive":"ON"})
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG", "isa":"AVX2", "tasking":"TBB", "intensive":"ON"})
|
||||
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"GCC" , "isa":"SSE2", "tasking":"TBB", "intensive":"ON"})
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"GCC" , "isa":"AVX" , "tasking":"INT", "intensive":"ON"})
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"GCC" , "isa":"AVX2", "tasking":"TBB", "intensive":"ON"})
|
||||
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"ICC16" , "isa":"SSE2", "tasking":"TBB", "intensive":"ON"})
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"ICC15" , "isa":"AVX" , "tasking":"INT", "intensive":"ON"})
|
||||
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"CLANG" , "isa":"AVX2" , "tasking":"TBB", "STATIC_LIB":"ON"})
|
||||
|
||||
# configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"ICC17" , "isa":"AVX2", "tasking":"TBB", "intensive":"ON"})
|
||||
|
||||
return configs
|
||||
|
||||
# intensive testing
|
||||
def createConfigsPackage(branch,build,host):
|
||||
configs = []
|
||||
isa_windows = ["SSE2","SSE42","AVX","AVX2","AVX512SKX"]
|
||||
isa_linux = ["SSE2","SSE42","AVX","AVX2","AVX512KNL","AVX512SKX"]
|
||||
isa_macosx = ["SSE2","SSE42","AVX","AVX2"]
|
||||
if host == "tcg-vis-ci-win1":
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"ICC17", "isa":isa_windows, "tasking":"TBB", "intensive":"ON", "package":"ZIP"})
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"ICC17", "isa":isa_windows, "tasking":"TBB", "intensive":"ON", "package":"RPM"})
|
||||
elif host == "swr-ivb-lnx-01":
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"ICC17", "isa":isa_linux, "tasking":"TBB", "intensive":"ON", "package":"ZIP"})
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"ICC17", "isa":isa_linux, "tasking":"TBB", "intensive":"ON", "package":"RPM"})
|
||||
elif host == "tcg-vis-mac-mini":
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"ICC16", "isa":isa_macosx, "tasking":"TBB", "intensive":"ON", "package":"ZIP"})
|
||||
configs.append({"branch":branch, "platform":"x64", "build":build, "compiler":"ICC16", "isa":isa_macosx, "tasking":"TBB", "intensive":"ON", "package":"RPM"})
|
||||
return configs
|
||||
|
||||
def string_of_isa(isa):
|
||||
if type(isa) == str: return isa;
|
||||
else: return "ISAS-" + ("-".join(isa))
|
||||
|
||||
def createTest(config,OS):
|
||||
platform = config["platform"]
|
||||
build = config["build"]
|
||||
compiler = config["compiler"]
|
||||
isa = config["isa"]
|
||||
tasking = config["tasking"]
|
||||
if "intensive" in config: intensive = config["intensive"]
|
||||
else : intensive = "OFF"
|
||||
if "memcheck" in config: memcheck = config["memcheck"]
|
||||
else : memcheck = "OFF"
|
||||
if "benchmark" in config: benchmark = config["benchmark"]
|
||||
else : benchmark = "OFF"
|
||||
if "sde" in config: sde = config["sde"]
|
||||
else : sde = "OFF"
|
||||
if "test" in config: skip_testing = not config["test"]
|
||||
else : skip_testing = False
|
||||
if tasking == "INT": tasking = "INTERNAL"
|
||||
if tasking == "PPL": tasking = "PPL"
|
||||
name = "gitlab-"+platform+"-"+build+"-"+compiler+"-"+string_of_isa(isa)+"-"+tasking
|
||||
if "package" in config:
|
||||
c.append("-D EMBREE_STACK_PROTECTOR=ON")
|
||||
if config["package"] == "ZIP": name = name + "-package-zip"
|
||||
else : name = name + "-package-installer"
|
||||
|
||||
if "klocwork" in config: name = name + "-klocwork"
|
||||
ispc_ext = "-vs2013"
|
||||
c = [] # CMake configuration
|
||||
e = [] # shell environment
|
||||
if "package" in config and OS == 'linux': # we need up to date cmake for RPMs to work properly
|
||||
e.append("module load cmake")
|
||||
c.append("-D CMAKE_BUILD_TYPE="+build+"")
|
||||
if OS == "windows":
|
||||
ext = ""
|
||||
if platform == "x64":
|
||||
ext = " Win64"
|
||||
if (compiler == "V141"):
|
||||
c.append("-G \"Visual Studio 15 2017"+ext+"\"")
|
||||
c.append("-T \"V141\"")
|
||||
ispc_ext = "-vs2015"
|
||||
elif (compiler == "V140"):
|
||||
c.append("-G \"Visual Studio 14 2015"+ext+"\"")
|
||||
c.append("-T \"V140\"")
|
||||
ispc_ext = "-vs2015"
|
||||
elif (compiler == "V120"):
|
||||
c.append("-G \"Visual Studio 12 2013"+ext+"\"")
|
||||
c.append("-T \"V120\"")
|
||||
elif (compiler == "V110"):
|
||||
c.append("-G \"Visual Studio 11 2012"+ext+"\"")
|
||||
c.append("-T \"V110\"")
|
||||
elif (compiler == "ICC"):
|
||||
c.append("-G \"Visual Studio 12 2013"+ext+"\"")
|
||||
c.append("-T \"Intel C++ Compiler 17.0\"")
|
||||
elif (compiler == "ICC18"):
|
||||
c.append("-G \"Visual Studio 12 2013"+ext+"\"")
|
||||
c.append("-T \"Intel C++ Compiler 18.0\"")
|
||||
elif (compiler == "ICC17"):
|
||||
c.append("-G \"Visual Studio 12 2013"+ext+"\"")
|
||||
c.append("-T \"Intel C++ Compiler 17.0\"")
|
||||
elif (compiler == "ICC16"):
|
||||
c.append("-G \"Visual Studio 12 2013"+ext+"\"")
|
||||
c.append("-T \"Intel C++ Compiler 16.0\"")
|
||||
elif (compiler == "ICC15"):
|
||||
c.append("-G \"Visual Studio 12 2013"+ext+"\"")
|
||||
c.append("-T \"Intel C++ Compiler XE 15.0\"")
|
||||
elif (compiler == "CLANG"):
|
||||
c.append("-G \"Visual Studio 12 2013"+ext+"\"")
|
||||
c.append("-T \"LLVM-vs2013\"")
|
||||
else:
|
||||
raise ValueError('unknown compiler: ' + compiler + '')
|
||||
else:
|
||||
if (compiler == "ICC18"):
|
||||
c.append("-D CMAKE_CXX_COMPILER=icpc -D CMAKE_C_COMPILER=icc")
|
||||
e.append("module load intel/2018")
|
||||
elif (compiler == "ICC17"):
|
||||
c.append("-D CMAKE_CXX_COMPILER=icpc -D CMAKE_C_COMPILER=icc")
|
||||
e.append("module load intel/2017")
|
||||
elif (compiler == "ICC16"):
|
||||
c.append("-D CMAKE_CXX_COMPILER=icpc -D CMAKE_C_COMPILER=icc")
|
||||
e.append("module load intel/2016")
|
||||
elif (compiler == "ICC15"):
|
||||
c.append("-D CMAKE_CXX_COMPILER=icpc -D CMAKE_C_COMPILER=icc")
|
||||
e.append("module load intel/2015")
|
||||
elif (compiler == "ICC"):
|
||||
c.append("-D CMAKE_CXX_COMPILER=icpc -D CMAKE_C_COMPILER=icc")
|
||||
e.append("module load intel")
|
||||
elif (compiler == "GCC"):
|
||||
c.append("-D CMAKE_CXX_COMPILER=g++ -D CMAKE_C_COMPILER=gcc")
|
||||
elif (compiler == "CLANG4"):
|
||||
c.append("-D CMAKE_CXX_COMPILER=clang++ -D CMAKE_C_COMPILER=clang")
|
||||
e.append("module load clang/4")
|
||||
elif (compiler == "CLANG3.9"):
|
||||
c.append("-D CMAKE_CXX_COMPILER=clang++ -D CMAKE_C_COMPILER=clang")
|
||||
e.append("module load clang/3.9")
|
||||
elif (compiler == "CLANG3.8"):
|
||||
c.append("-D CMAKE_CXX_COMPILER=clang++ -D CMAKE_C_COMPILER=clang")
|
||||
e.append("module load clang/3.8")
|
||||
elif (compiler == "CLANG"):
|
||||
c.append("-D CMAKE_CXX_COMPILER=clang++ -D CMAKE_C_COMPILER=clang")
|
||||
else:
|
||||
raise ValueError('unknown compiler: ' + compiler + '')
|
||||
|
||||
if type(isa) == str:
|
||||
c.append("-D EMBREE_MAX_ISA="+isa+"")
|
||||
else:
|
||||
c.append("-D EMBREE_MAX_ISA=NONE")
|
||||
if "SSE2" in isa: c.append("-D EMBREE_ISA_SSE2=ON")
|
||||
else : c.append("-D EMBREE_ISA_SSE2=OFF")
|
||||
if "SSE42" in isa: c.append("-D EMBREE_ISA_SSE42=ON")
|
||||
else : c.append("-D EMBREE_ISA_SSE42=OFF")
|
||||
if "AVX" in isa: c.append("-D EMBREE_ISA_AVX=ON")
|
||||
else : c.append("-D EMBREE_ISA_AVX=OFF")
|
||||
if "AVX2" in isa: c.append("-D EMBREE_ISA_AVX2=ON")
|
||||
else : c.append("-D EMBREE_ISA_AVX2=OFF")
|
||||
if "AVX512KNL" in isa: c.append("-D EMBREE_ISA_AVX512KNL=ON")
|
||||
else : c.append("-D EMBREE_ISA_AVX512KNL=OFF")
|
||||
if "AVX512SKX" in isa: c.append("-D EMBREE_ISA_AVX512SKX=ON")
|
||||
else : c.append("-D EMBREE_ISA_AVX512SKX=OFF")
|
||||
|
||||
c.append("-D EMBREE_TASKING_SYSTEM="+tasking+"")
|
||||
c.append("-D EMBREE_TESTING_MEMCHECK="+memcheck+"")
|
||||
c.append("-D EMBREE_TESTING_INTENSIVE="+intensive+"")
|
||||
c.append("-D EMBREE_TESTING_SDE="+sde+"")
|
||||
|
||||
ispc_enabled = True
|
||||
if "ISPC_SUPPORT" in config:
|
||||
c.append("-D EMBREE_ISPC_SUPPORT="+config["ISPC_SUPPORT"])
|
||||
if config["ISPC_SUPPORT"] == "OFF": name += "-noispc"
|
||||
ispc_enabled = False
|
||||
if "STATIC_LIB" in config:
|
||||
c.append("-D EMBREE_STATIC_LIB="+config["STATIC_LIB"])
|
||||
if config["STATIC_LIB"] == "ON": name += "-static"
|
||||
if "TUTORIALS" in config:
|
||||
c.append("-D EMBREE_TUTORIALS="+config["TUTORIALS"])
|
||||
if config["TUTORIALS"] == "OFF": name += "-notutorials"
|
||||
if "BACKFACE_CULLING" in config:
|
||||
c.append("-D EMBREE_BACKFACE_CULLING="+config["BACKFACE_CULLING"])
|
||||
if config["BACKFACE_CULLING"] == "ON": name += "-backfaceculling"
|
||||
if "IGNORE_INVALID_RAYS" in config:
|
||||
c.append("-D EMBREE_IGNORE_INVALID_RAYS="+config["IGNORE_INVALID_RAYS"])
|
||||
if config["IGNORE_INVALID_RAYS"] == "ON": name += "-noinvalid"
|
||||
if "INTERSECTION_FILTER" in config:
|
||||
c.append("-D EMBREE_INTERSECTION_FILTER="+config["INTERSECTION_FILTER"])
|
||||
if config["INTERSECTION_FILTER"] == "OFF": name += "-nofilter"
|
||||
if "RAY_MASK" in config:
|
||||
c.append("-D EMBREE_RAY_MASK="+config["RAY_MASK"])
|
||||
if config["RAY_MASK"] == "ON": name += "-raymask"
|
||||
if "RAY_PACKETS" in config:
|
||||
c.append("-D EMBREE_RAY_PACKETS="+config["RAY_PACKETS"])
|
||||
if config["RAY_PACKETS"] == "OFF": name += "-nopackets"
|
||||
if "STAT_COUNTERS" in config:
|
||||
c.append("-D EMBREE_STAT_COUNTERS="+config["STAT_COUNTERS"])
|
||||
if config["STAT_COUNTERS"] == "ON": name += "-stats"
|
||||
if "TRIS" in config:
|
||||
c.append("-D EMBREE_GEOMETRY_TRIANGLES="+config["TRIS"])
|
||||
if config["TRIS"] == "ON": name += "-tris"
|
||||
if "QUADS" in config:
|
||||
c.append("-D EMBREE_GEOMETRY_QUADS="+config["QUADS"])
|
||||
if config["QUADS"] == "ON": name += "-quads"
|
||||
if "LINES" in config:
|
||||
c.append("-D EMBREE_GEOMETRY_LINES="+config["LINES"])
|
||||
if config["LINES"] == "ON": name += "-lines"
|
||||
if "HAIR" in config:
|
||||
c.append("-D EMBREE_GEOMETRY_HAIR="+config["HAIR"])
|
||||
if config["HAIR"] == "ON": name += "-hair"
|
||||
if "SUBDIV" in config:
|
||||
c.append("-D EMBREE_GEOMETRY_SUBDIV="+config["SUBDIV"])
|
||||
if config["SUBDIV"] == "ON": name += "-subdiv"
|
||||
if "USERGEOM" in config:
|
||||
c.append("-D EMBREE_GEOMETRY_USER="+config["USERGEOM"])
|
||||
if config["USERGEOM"] == "ON": name += "-usergeom"
|
||||
|
||||
if OS == "linux":
|
||||
if ispc_enabled: c.append("-D EMBREE_ISPC_EXECUTABLE=/NAS/packages/apps/ispc/1.9.1/ispc")
|
||||
if tasking == "TBB": c.append("-D EMBREE_TBB_ROOT=/NAS/packages/apps/tbb/tbb-2017-linux")
|
||||
elif OS == "macosx":
|
||||
{}
|
||||
#if ispc_enabled: c.append("-D EMBREE_ISPC_EXECUTABLE="+os.getcwd()+"/dependencies/ispc-v1.9.1-osx/ispc")
|
||||
#if tasking == "TBB": c.append("-D EMBREE_TBB_ROOT="+os.getcwd()+dash+"dependencies"+dash+"tbb-2017-osx")
|
||||
elif OS == "windows":
|
||||
#if ispc_enabled:
|
||||
#c.append("-D EMBREE_ISPC_EXECUTABLE="+os.getcwd()+dash+"dependencies"+dash+"ispc-v1.9.1-windows"+ispc_ext+dash+"ispc.exe")
|
||||
|
||||
if tasking == "TBB":
|
||||
#tbb_path = os.getcwd()+dash+"dependencies"+dash+"tbb-2017-windows"
|
||||
#c.append("-D EMBREE_TBB_ROOT="+tbb_path)
|
||||
if platform == "x64":
|
||||
e.append("set PATH="+tbb_path+"\\bin\\intel64\\vc12;%PATH%")
|
||||
else:
|
||||
e.append("set PATH="+tbb_path+"\\bin\\ia32\\vc12;%PATH%")
|
||||
else:
|
||||
sys.stderr.write("unknown operating system "+OS)
|
||||
sys.exit(1)
|
||||
|
||||
if "klocwork" in config:
|
||||
c.append("-D EMBREE_TESTING_KLOCWORK="+config["klocwork"])
|
||||
|
||||
if "package" in config:
|
||||
c.append("-D EMBREE_TESTING_PACKAGE=ON")
|
||||
c.append("-D EMBREE_TUTORIALS_IMAGE_MAGICK=OFF")
|
||||
c.append("-D EMBREE_TUTORIALS_LIBJPEG=OFF")
|
||||
c.append("-D EMBREE_TUTORIALS_LIBPNG=OFF")
|
||||
c.append("-D EMBREE_TUTORIALS_OPENEXR=OFF")
|
||||
if OS == "linux" and config["package"] == "ZIP":
|
||||
c.append("-D EMBREE_ZIP_MODE=ON")
|
||||
c.append("-D CMAKE_SKIP_INSTALL_RPATH=ON")
|
||||
c.append("-D CMAKE_INSTALL_INCLUDEDIR=include")
|
||||
c.append("-D CMAKE_INSTALL_LIBDIR=lib")
|
||||
c.append("-D CMAKE_INSTALL_DOCDIR=doc")
|
||||
c.append("-D CMAKE_INSTALL_BINDIR=bin")
|
||||
elif OS == "linux" and config["package"] == "RPM":
|
||||
c.append("-D EMBREE_ZIP_MODE=OFF")
|
||||
c.append("-D CMAKE_SKIP_INSTALL_RPATH=OFF")
|
||||
c.append("-D CMAKE_INSTALL_PREFIX=/usr")
|
||||
c.append("-D EMBREE_TBB_ROOT=/usr")
|
||||
elif OS == "macosx" and config["package"] == "ZIP":
|
||||
c.append("-D EMBREE_ZIP_MODE=ON")
|
||||
c.append("-D CMAKE_SKIP_INSTALL_RPATH=ON")
|
||||
c.append("-D CMAKE_MACOSX_RPATH=ON")
|
||||
c.append("-D CMAKE_INSTALL_INCLUDEDIR=include")
|
||||
c.append("-D CMAKE_INSTALL_LIBDIR=lib")
|
||||
c.append("-D CMAKE_INSTALL_DOCDIR=doc")
|
||||
c.append("-D CMAKE_INSTALL_BINDIR=bin")
|
||||
elif OS == "macosx" and config["package"] == "RPM":
|
||||
c.append("-D EMBREE_ZIP_MODE=OFF")
|
||||
c.append("-D CMAKE_SKIP_INSTALL_RPATH=OFF")
|
||||
c.append("-D CMAKE_INSTALL_PREFIX=/opt/local")
|
||||
c.append("-D CMAKE_INSTALL_INCLUDEDIR=include")
|
||||
c.append("-D CMAKE_INSTALL_LIBDIR=lib")
|
||||
c.append("-D CMAKE_INSTALL_DOCDIR=../../Applications/Embree2/doc")
|
||||
c.append("-D CMAKE_INSTALL_BINDIR=../../Applications/Embree2/bin")
|
||||
c.append("-D EMBREE_TBB_ROOT=/opt/local")
|
||||
elif OS == "windows" and config["package"] == "ZIP":
|
||||
c.append("-D EMBREE_ZIP_MODE=ON")
|
||||
c.append("-D CMAKE_INSTALL_INCLUDEDIR=include")
|
||||
c.append("-D CMAKE_INSTALL_LIBDIR=lib")
|
||||
c.append("-D CMAKE_INSTALL_DATAROOTDIR=")
|
||||
c.append("-D CMAKE_INSTALL_DOCDIR=doc")
|
||||
c.append("-D CMAKE_INSTALL_BINDIR=bin")
|
||||
elif OS == "windows" and config["package"] == "RPM":
|
||||
c.append("-D EMBREE_ZIP_MODE=OFF")
|
||||
c.append("-D CMAKE_INSTALL_INCLUDEDIR=include")
|
||||
c.append("-D CMAKE_INSTALL_LIBDIR=lib")
|
||||
c.append("-D CMAKE_INSTALL_DATAROOTDIR=")
|
||||
c.append("-D CMAKE_INSTALL_DOCDIR=doc")
|
||||
c.append("-D CMAKE_INSTALL_BINDIR=bin")
|
||||
else:
|
||||
sys.stderr.write("unknown package mode: "+OS+":"+config["package"])
|
||||
sys.exit(1)
|
||||
|
||||
return [name,build,skip_testing,benchmark,c,e]
|
||||
|
||||
# runs all tests for specified host machine
|
||||
def runConfig(cfg):
|
||||
[name,build,skip_testing,benchmark,conf,env] = createTest(cfg,OS)
|
||||
ctest = ""
|
||||
ctest += "ctest -VV -S scripts/test.cmake"
|
||||
if g_cdash != "": ctest += " -D CTEST_DROP_SITE="+g_cdash
|
||||
ctest += " -D TEST_NAME=\""+name+"\""
|
||||
if skip_testing: ctest += " -D CTEST_SKIP_TESTING=ON"
|
||||
else : ctest += " -D CTEST_SKIP_TESTING=OFF"
|
||||
ctest += " -D CTEST_CONFIGURATION_TYPE=\""+build+"\""
|
||||
ctest += " -D CTEST_BUILD_OPTIONS=\"" + escape(" ".join(conf))+"\""
|
||||
if g_debugMode:
|
||||
print(name)
|
||||
for e in env: print(' '+e)
|
||||
print(' '+ctest+'\n')
|
||||
else:
|
||||
cmd = ""
|
||||
for e in env: cmd += e + " && "
|
||||
cmd += ctest+"\n"
|
||||
subprocess.check_call(cmd, shell=True)
|
||||
#if OS == "windows":
|
||||
# subprocess.Popen(cmd, shell=True).communicate()
|
||||
#else: # we have to use a login shell to make "module load xxx" work
|
||||
# cmd = "export http_proxy= && export https_proxy= && " + cmd # cdash submission fails when proxy servers set
|
||||
# subprocess.Popen(['bash', '-l'], stdin=subprocess.PIPE).communicate(input=cmd.encode("utf-8"))
|
||||
|
||||
def parseCommandLine(argv):
|
||||
global g_cdash
|
||||
global g_config
|
||||
global g_mode
|
||||
global g_intensive
|
||||
global g_debugMode
|
||||
if len(argv) == 0:
|
||||
return;
|
||||
elif len(argv)>=2 and argv[0] == "--cdash":
|
||||
g_cdash = argv[1]
|
||||
parseCommandLine(argv[2:len(argv)])
|
||||
elif len(argv)>=2 and argv[0] == "--mode":
|
||||
g_mode = argv[1]
|
||||
parseCommandLine(argv[2:len(argv)])
|
||||
elif len(argv)>=1 and argv[0] == "--intensive":
|
||||
g_intensive = True
|
||||
parseCommandLine(argv[1:len(argv)])
|
||||
elif len(argv)>=1 and argv[0] == "--debug":
|
||||
g_debugMode = True
|
||||
parseCommandLine(argv[1:len(argv)])
|
||||
elif len(argv)>=1 and argv[0] == "--help":
|
||||
printUsage()
|
||||
return;
|
||||
elif ':' in argv[0]:
|
||||
p = argv[0].split(":")
|
||||
g_config[p[0]] = p[1]
|
||||
parseCommandLine(argv[1:len(argv)])
|
||||
else:
|
||||
sys.stderr.write("unknown command line option: "+argv[0])
|
||||
sys.exit(1)
|
||||
|
||||
parseCommandLine(sys.argv[1:len(sys.argv)])
|
||||
runConfig(g_config)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -238,7 +238,7 @@ namespace embree
|
||||
if (features & FEATURE_STREAM)
|
||||
{
|
||||
/* register parsing of stream mode */
|
||||
registerOption("mode", [] (Ref<ParseStream> cin, const FileName& path) {
|
||||
registerOption("mode", [this] (Ref<ParseStream> cin, const FileName& path) {
|
||||
std::string mode = cin->getString();
|
||||
if (mode == "normal") g_mode = MODE_NORMAL;
|
||||
else if (mode == "stream") g_mode = MODE_STREAM;
|
||||
@@ -744,9 +744,8 @@ namespace embree
|
||||
{
|
||||
/* update camera */
|
||||
camera.move(moveDelta.x*speed, moveDelta.y*speed, moveDelta.z*speed);
|
||||
|
||||
ISPCCamera ispccamera = camera.getISPCCamera(width,height,true);
|
||||
if (print_camera)
|
||||
std::cout << camera.str() << std::endl;
|
||||
|
||||
/* render image using ISPC */
|
||||
initRayStats();
|
||||
@@ -820,7 +819,10 @@ namespace embree
|
||||
stream << dt1*1000.0f << " ms, ";
|
||||
stream << width << "x" << height << " pixels";
|
||||
std::cout << stream.str() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
if (print_camera)
|
||||
std::cout << camera.str() << std::endl;
|
||||
}
|
||||
|
||||
void TutorialApplication::reshapeFunc(int width, int height)
|
||||
|
||||
@@ -287,12 +287,12 @@ float Noise(float x, float y, float z)
|
||||
Tutorial()
|
||||
: TutorialApplication("hair_geometry",FEATURE_RTCORE)
|
||||
{
|
||||
registerOption("ambientlight", [] (Ref<ParseStream> cin, const FileName& path) {
|
||||
registerOption("ambientlight", [this] (Ref<ParseStream> cin, const FileName& path) {
|
||||
g_ambient_intensity = cin->getVec3fa();
|
||||
}, "--ambientlight r g b: adds an ambient light with intensity rgb");
|
||||
registerOptionAlias("ambientlight","ambient");
|
||||
|
||||
registerOption("directionallight", [] (Ref<ParseStream> cin, const FileName& path) {
|
||||
registerOption("directionallight", [this] (Ref<ParseStream> cin, const FileName& path) {
|
||||
g_dirlight_direction = normalize(cin->getVec3fa());
|
||||
g_dirlight_intensity = cin->getVec3fa();
|
||||
}, "--directionallight x y z r g b: adds a directional light with direction xyz and intensity rgb");
|
||||
|
||||
@@ -77,7 +77,7 @@ void convertHairSet(ISPCHairSet* hair, RTCScene scene_out)
|
||||
}
|
||||
rtcSetBuffer(scene_out,geomID,RTC_INDEX_BUFFER,hair->hairs,0,sizeof(ISPCHair));
|
||||
rtcSetOcclusionFilterFunction(scene_out,geomID,filterDispatch);
|
||||
rtcSetTessellationRate(scene_out,geomID,(float)hair->tessellation_rate);
|
||||
rtcSetTessellationRate(scene_out,geomID,hair->tessellation_rate);
|
||||
}
|
||||
|
||||
RTCScene convertScene(ISPCScene* scene_in)
|
||||
|
||||
@@ -29,16 +29,16 @@ namespace embree
|
||||
Tutorial()
|
||||
: TutorialApplication("motion_blur_geometry",FEATURE_RTCORE)
|
||||
{
|
||||
registerOption("time", [] (Ref<ParseStream> cin, const FileName& path) {
|
||||
registerOption("time", [this] (Ref<ParseStream> cin, const FileName& path) {
|
||||
g_time = cin->getFloat();
|
||||
}, "--time <float>: time to render image at");
|
||||
|
||||
registerOption("time-steps", [] (Ref<ParseStream> cin, const FileName& path) {
|
||||
registerOption("time-steps", [this] (Ref<ParseStream> cin, const FileName& path) {
|
||||
g_num_time_steps = cin->getInt();
|
||||
if (g_num_time_steps < 2) throw std::runtime_error("at least 2 time steps have to be used");
|
||||
}, "--time-steps <int>: number of time steps to use");
|
||||
|
||||
registerOption("time-steps2", [] (Ref<ParseStream> cin, const FileName& path) {
|
||||
registerOption("time-steps2", [this] (Ref<ParseStream> cin, const FileName& path) {
|
||||
g_num_time_steps2 = cin->getInt();
|
||||
if (g_num_time_steps2 < 2) throw std::runtime_error("at least 2 time steps have to be used");
|
||||
}, "--time-steps2 <int>: number of time steps to use");
|
||||
|
||||
@@ -17,5 +17,3 @@
|
||||
INCLUDE(tutorial)
|
||||
ADD_TUTORIAL(pathtracer)
|
||||
ADD_EMBREE_MODELS_TEST(pathtracer pathtracer pathtracer)
|
||||
ADD_EMBREE_MODELS_TEST(pathtracer_coherent pathtracer pathtracer --coherent)
|
||||
ADD_EMBREE_MODELS_TEST(pathtracer_incoherent pathtracer pathtracer --incoherent)
|
||||
@@ -28,11 +28,11 @@ namespace embree
|
||||
Tutorial()
|
||||
: SceneLoadingTutorialApplication("pathtracer",FEATURE_RTCORE)
|
||||
{
|
||||
registerOption("spp", [] (Ref<ParseStream> cin, const FileName& path) {
|
||||
registerOption("spp", [this] (Ref<ParseStream> cin, const FileName& path) {
|
||||
g_spp = cin->getInt();
|
||||
}, "--spp: sets number of samples per pixel");
|
||||
|
||||
registerOption("accumulate", [] (Ref<ParseStream> cin, const FileName& path) {
|
||||
registerOption("accumulate", [this] (Ref<ParseStream> cin, const FileName& path) {
|
||||
g_accumulate = cin->getInt();
|
||||
}, "--accumulate <bool>: accumulate samples (on by default)");
|
||||
}
|
||||
|
||||
@@ -1461,7 +1461,6 @@ Vec3fa renderPixelFunction(float x, float y, RandomSampler& sampler, const ISPCC
|
||||
c = c * Material__sample(material_array,materialID,numMaterials,brdf,Lw, wo, dg, wi1, medium, RandomSampler_get2D(sampler));
|
||||
|
||||
/* iterate over lights */
|
||||
context.flags = g_iflags_incoherent;
|
||||
for (size_t i=0; i<g_ispc_scene->numLights; i++)
|
||||
{
|
||||
const Light* l = g_ispc_scene->lights[i];
|
||||
@@ -1502,7 +1501,7 @@ Vec3fa renderPixelStandard(float x, float y, const ISPCCamera& camera, RayStats&
|
||||
float fy = y + RandomSampler_get1D(sampler);
|
||||
L = L + renderPixelFunction(fx,fy,sampler,camera,stats);
|
||||
}
|
||||
L = L/(float)g_spp;
|
||||
L = L/g_spp;
|
||||
return L;
|
||||
}
|
||||
|
||||
|
||||
@@ -1459,7 +1459,6 @@ Vec3f renderPixelFunction(float x, float y, RandomSampler& sampler, const unifor
|
||||
c = c * Material__sample(material_array,materialID,numMaterials,brdf,Lw, wo, dg, wi1, medium, RandomSampler_get2D(sampler));
|
||||
|
||||
/* iterate over lights */
|
||||
context.flags = g_iflags_incoherent;
|
||||
for (uniform size_t i=0; i<g_ispc_scene->numLights; i++)
|
||||
{
|
||||
const uniform Light* uniform l = g_ispc_scene->lights[i];
|
||||
|
||||
@@ -664,7 +664,7 @@ namespace embree
|
||||
}
|
||||
|
||||
template<int N>
|
||||
__noinline void IntersectWithNMMode(IntersectVariant ivariant, RTCScene scene, RTCIntersectContext* context, RTCRay* rays, size_t Nrays)
|
||||
inline void IntersectWithNMMode(IntersectVariant ivariant, RTCScene scene, RTCIntersectContext* context, RTCRay* rays, size_t Nrays)
|
||||
{
|
||||
assert(Nrays<1024);
|
||||
const size_t alignment = size_t(rays) % 64;
|
||||
@@ -693,45 +693,8 @@ namespace embree
|
||||
for (size_t j=0; j<L; j++) rays[i+j] = getRay(ray,N,j);
|
||||
}
|
||||
}
|
||||
|
||||
__noinline void IntersectWithNpMode(IntersectVariant ivariant, RTCScene scene, RTCIntersectContext* context, RTCRay* rays, size_t N)
|
||||
{
|
||||
assert(N < 1024);
|
||||
const size_t alignment = size_t(rays) % 64;
|
||||
__aligned(64) char data[1024 * sizeof(RTCRay) + 64];
|
||||
RTCRayN* ray = (RTCRayN*)&data[alignment];
|
||||
for (size_t j = 0; j < N; j++) setRay(ray, N, j, rays[j]);
|
||||
|
||||
RTCRayNp rayp;
|
||||
rayp.orgx = &RTCRayN_org_x(ray, N, 0);
|
||||
rayp.orgy = &RTCRayN_org_y(ray, N, 0);
|
||||
rayp.orgz = &RTCRayN_org_z(ray, N, 0);
|
||||
rayp.dirx = &RTCRayN_dir_x(ray, N, 0);
|
||||
rayp.diry = &RTCRayN_dir_y(ray, N, 0);
|
||||
rayp.dirz = &RTCRayN_dir_z(ray, N, 0);
|
||||
rayp.tnear = &RTCRayN_tnear(ray, N, 0);
|
||||
rayp.tfar = &RTCRayN_tfar(ray, N, 0);
|
||||
rayp.time = &RTCRayN_time(ray, N, 0);
|
||||
rayp.mask = &RTCRayN_mask(ray, N, 0);
|
||||
rayp.instID = &RTCRayN_instID(ray, N, 0);
|
||||
rayp.geomID = &RTCRayN_geomID(ray, N, 0);
|
||||
rayp.primID = &RTCRayN_primID(ray, N, 0);
|
||||
rayp.u = &RTCRayN_u(ray, N, 0);
|
||||
rayp.v = &RTCRayN_v(ray, N, 0);
|
||||
rayp.Ngx = &RTCRayN_Ng_x(ray, N, 0);
|
||||
rayp.Ngy = &RTCRayN_Ng_y(ray, N, 0);
|
||||
rayp.Ngz = &RTCRayN_Ng_z(ray, N, 0);
|
||||
|
||||
switch (ivariant & VARIANT_INTERSECT_OCCLUDED_MASK) {
|
||||
case VARIANT_INTERSECT: rtcIntersectNp(scene, context, rayp, N); break;
|
||||
case VARIANT_OCCLUDED: rtcOccludedNp(scene, context, rayp, N); break;
|
||||
default: assert(false);
|
||||
}
|
||||
|
||||
for (size_t j = 0; j < N; j++) rays[j] = getRay(ray, N, j);
|
||||
}
|
||||
|
||||
__noinline void IntersectWithModeInternal(IntersectMode mode, IntersectVariant ivariant, RTCScene scene, RTCRay* rays, size_t N)
|
||||
inline void IntersectWithModeInternal(IntersectMode mode, IntersectVariant ivariant, RTCScene scene, RTCRay* rays, size_t N)
|
||||
{
|
||||
RTCIntersectContext context;
|
||||
context.flags = ((ivariant & VARIANT_COHERENT_INCOHERENT_MASK) == VARIANT_COHERENT) ? RTC_INTERSECT_COHERENT : RTC_INTERSECT_INCOHERENT;
|
||||
@@ -849,14 +812,48 @@ namespace embree
|
||||
IntersectWithNMMode<16>(ivariant,scene,&context,rays,N);
|
||||
break;
|
||||
}
|
||||
case MODE_INTERSECTNp: {
|
||||
IntersectWithNpMode(ivariant, scene, &context, rays, N);
|
||||
case MODE_INTERSECTNp:
|
||||
{
|
||||
assert(N<1024);
|
||||
const size_t alignment = size_t(rays) % 64;
|
||||
__aligned(64) char data[1024*sizeof(RTCRay)+64];
|
||||
RTCRayN* ray = (RTCRayN*) &data[alignment];
|
||||
for (size_t j=0; j<N; j++) setRay(ray,N,j,rays[j]);
|
||||
|
||||
RTCRayNp rayp;
|
||||
rayp.orgx = &RTCRayN_org_x(ray,N,0);
|
||||
rayp.orgy = &RTCRayN_org_y(ray,N,0);
|
||||
rayp.orgz = &RTCRayN_org_z(ray,N,0);
|
||||
rayp.dirx = &RTCRayN_dir_x(ray,N,0);
|
||||
rayp.diry = &RTCRayN_dir_y(ray,N,0);
|
||||
rayp.dirz = &RTCRayN_dir_z(ray,N,0);
|
||||
rayp.tnear = &RTCRayN_tnear(ray,N,0);
|
||||
rayp.tfar = &RTCRayN_tfar(ray,N,0);
|
||||
rayp.time = &RTCRayN_time(ray,N,0);
|
||||
rayp.mask = &RTCRayN_mask(ray,N,0);
|
||||
rayp.instID = &RTCRayN_instID(ray,N,0);
|
||||
rayp.geomID = &RTCRayN_geomID(ray,N,0);
|
||||
rayp.primID = &RTCRayN_primID(ray,N,0);
|
||||
rayp.u = &RTCRayN_u(ray,N,0);
|
||||
rayp.v = &RTCRayN_v(ray,N,0);
|
||||
rayp.Ngx = &RTCRayN_Ng_x(ray,N,0);
|
||||
rayp.Ngy = &RTCRayN_Ng_y(ray,N,0);
|
||||
rayp.Ngz = &RTCRayN_Ng_z(ray,N,0);
|
||||
|
||||
switch (ivariant & VARIANT_INTERSECT_OCCLUDED_MASK) {
|
||||
case VARIANT_INTERSECT: rtcIntersectNp(scene,&context,rayp,N); break;
|
||||
case VARIANT_OCCLUDED : rtcOccludedNp(scene,&context,rayp,N); break;
|
||||
default: assert(false);
|
||||
}
|
||||
|
||||
for (size_t j=0; j<N; j++) rays[j] = getRay(ray,N,j);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IntersectWithMode(IntersectMode mode, IntersectVariant ivariant, RTCScene scene, RTCRay* rays, size_t N)
|
||||
inline void IntersectWithMode(IntersectMode mode, IntersectVariant ivariant, RTCScene scene, RTCRay* rays, size_t N)
|
||||
{
|
||||
/* verify occluded result against intersect */
|
||||
if ((ivariant & VARIANT_INTERSECT_OCCLUDED) == VARIANT_INTERSECT_OCCLUDED)
|
||||
|
||||
Loaded 100 of 105 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user