Compare commits

..
62 Commits
Author SHA1 Message Date
Sven Woop 82ac34a2d6 updates 2016-10-31 15:28:05 +01:00
Sven Woop e80450780c bugfix 2016-10-31 12:20:07 +01:00
Sven Woop 4d0329fe71 Merge branch 'devel' into collision 2016-10-31 11:38:52 +01:00
Sven Woop c3ff7ab7b5 merge 2016-10-31 11:33:34 +01:00
Sven Woop b3d327b24e updates 2016-10-31 10:05:43 +01:00
Sven Woop 969e751525 merge 2016-10-31 10:03:38 +01:00
Sven Woop 6dc16f6ed2 bugfix 2016-10-31 09:45:54 +01:00
Sven Woop e9c241fe29 updates 2016-10-31 09:25:08 +01:00
Sven Woop 6cb9789951 updates 2016-10-31 09:10:08 +01:00
Sven Woop 6a3ebf7871 bugfix 2016-10-31 08:54:38 +01:00
Sven Woop 8d3e0ec658 bugfix 2016-10-31 08:50:33 +01:00
Sven Woop a303bccf07 updates 2016-10-31 08:47:25 +01:00
Sven Woop 905f55ae26 added support to use user geometries for collision detection to collision.cpp 2016-10-31 08:44:38 +01:00
Sven Woop fe03dcf15a moved triangle_triangle_intersector to separate file 2016-10-31 08:14:45 +01:00
Sven Woop db3a9009c0 added usergeometry collider 2016-10-31 08:05:50 +01:00
Sven Woop 5b65aa7f74 cleanups in rtcCollide 2016-10-31 07:36:09 +01:00
Sven Woop d3c7621b02 cleanups in rtcCollide 2016-10-31 07:31:58 +01:00
Sven Woop a095872b94 added RTC_COLLIDE scene algorithm flag 2016-10-31 07:22:53 +01:00
Sven Woop 9675800bfd performance optimizations 2016-10-05 10:37:54 +02:00
Sven Woop 02e08538df updates 2016-10-05 09:43:07 +02:00
Sven Woop 72513cd242 updates 2016-10-05 09:35:34 +02:00
Sven Woop 212be4e85d updates 2016-10-05 09:17:44 +02:00
Sven Woop c2923b8db1 updates 2016-10-05 09:10:46 +02:00
Sven Woop c0adf11eca updates 2016-10-05 09:08:11 +02:00
Sven Woop ae933bc838 restored benchmark mode of collision tutorial 2016-10-05 09:06:49 +02:00
Sven Woop 68e1be6f74 collision tutorial can load animations 2016-10-05 08:56:11 +02:00
Sven Woop 73dbc25652 improved stability of 2D triangle/triangle test 2016-10-05 07:49:35 +02:00
Sven Woop 52985f445e bugfix in maxDim function 2016-10-05 07:49:20 +02:00
Sven Woop d6921ccb95 added collision_regression_test 2016-10-05 07:16:37 +02:00
Sven Woop 29a75f3bc1 updates 2016-10-04 14:55:20 +02:00
Sven Woop 88932255c0 added code for special case of co-planar triangles 2016-10-04 14:53:49 +02:00
Sven Woop ba9ef506e2 Merge branch 'devel' into collision 2016-10-04 13:34:57 +02:00
Sven Woop 0d07cb4c85 continued implementing triangle/triangle intersection 2016-10-04 12:46:41 +02:00
Sven Woop 0ea1424d5c updates 2016-09-30 15:19:31 +02:00
Sven Woop d5729dea0f updates 2016-09-30 14:15:17 +02:00
Sven Woop 08af796183 added statistics 2016-09-30 13:41:08 +02:00
Sven Woop 2bbe5f6b95 bugfix, started to add triangle/triangle intersection code 2016-09-30 13:29:52 +02:00
Sven Woop 9144d1e922 parallel version of collisions working 2016-09-29 11:18:26 +02:00
Sven Woop d334b0aa28 changed bvh_collider to standard recursive approach 2016-09-29 11:04:31 +02:00
Sven Woop 7eff2b710d adding support for colliding geometry against itself 2016-09-29 10:49:20 +02:00
Sven Woop 4635412713 merge 2016-09-29 10:38:13 +02:00
Sven Woop 79b4d9acd7 bugfix in error checking 2016-09-27 07:48:13 +02:00
Sven Woop 3ec24c2a76 printing result per collision 2016-09-27 07:43:39 +02:00
Sven Woop 908ecb984f added verification of result 2016-09-27 07:34:36 +02:00
Sven Woop 152cf7e05e optimized collision callback mechanism 2016-09-21 12:37:45 +02:00
Sven Woop 09580c66f0 optimization 2016-09-21 11:49:10 +02:00
Sven Woop f7123c27a5 added BVH8Collider 2016-09-21 11:19:45 +02:00
Sven Woop c1406f791c updates 2016-09-21 11:02:22 +02:00
Sven Woop 8fea89369d optimizations 2016-09-21 10:53:19 +02:00
Sven Woop 120f529e21 added benchmarking 2016-09-21 10:41:53 +02:00
Sven Woop 09ac15fbb7 optimizations 2016-09-21 10:27:11 +02:00
Sven Woop 9464ea90be bugfix 2016-09-21 10:15:55 +02:00
Sven Woop 8f95000bd4 coloring collision set 2016-09-21 10:11:59 +02:00
Sven Woop caadb6d2c8 updates 2016-09-21 10:05:53 +02:00
Sven Woop 4830e6667c added proper leaf processing 2016-09-21 10:02:58 +02:00
Sven Woop 62aba5dc83 switching to triangle4v layout 2016-09-21 09:39:32 +02:00
Sven Woop a018d36d8a bugfixes 2016-09-21 09:37:45 +02:00
Sven Woop 2a8a3a3cfa bugfix 2016-09-21 09:28:27 +02:00
Sven Woop bb0abc10f6 updates 2016-09-21 09:16:34 +02:00
Sven Woop 95e6ae6c32 added collide tutorial 2016-09-21 09:07:53 +02:00
Sven Woop ba28fb7200 added bvh_collider.cpp 2016-09-21 07:22:32 +02:00
Sven Woop 06d1363ec0 first implementation of collision detection 2016-09-20 15:01:26 +02:00
631 changed files with 46245 additions and 43186 deletions
-81
View File
@@ -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]
+55 -226
View File
@@ -1,203 +1,12 @@
Version History
---------------
### New Features in Embree 2.17.0
- Improved packet ray tracing performance for coherent rays by 10-60%
(requires RTC_INTERSECT_COHERENT flag).
- Improved ray tracing performance for incoherent rays on
AVX-512 architectures by 5%.
- Improved ray tracing performance for streams of incoherent rays
by 5-15%.
- Fixed tbb_debug.lib linking error under Windows.
- Fast coherent ray stream and packet code paths now also work in robust mode.
- Using less agressive prefetching for large BVH nodes which
results in 1-2% higher ray tracing performance.
- Precompiled binaries have stack-protector enabled, except for
traversal kernels. BVH builders can be slightly slower due to this
change. If you want stack-protectors disabled please turn off
EMBREE_STACK_PROTECTOR in cmake and build the binaries yourself.
- When enabling ISAs individually, the 8-wide BVH was previously only
available when the AVX ISA was also selected. This issue is now
fixed, and one can enable only AVX2 and still get best
performance by using an 8-wide BVH.
- Fixed rtcOccluded1 and rtcOccluded1Ex API functions which were
broken in ISPC.
### New Features in Embree 2.16.5
- Bugfix in the robust triangle intersector that rarely caused NaNs.
- Fixed bug in hybrid traversal kernel when BVH leaf was entered with no
active rays. This rarely caused crashes when used with instancing.
- Fixed bug introduced in Embree 2.16.2 which caused instancing not to
work properly when a smaller than the native SIMD width was
used in ray packet mode.
- Fixed bug in the curve geometry intersector that caused rendering
artefacts for Bézier curves with p0=p1 and/or p2=p3.
- Fixed bug in the curve geometry intersector that caused hit results
with NaNs to be reported.
- Fixed masking bug that caused rare cracks in curve geometry.
- Enabled support for SSE2 in precompiled binaries again.
### New Features in Embree 2.16.4
- Bugfix in the ribbon intersector for hair primitives. Non-normalized
rays caused wrong intersection distance to be reported.
### New Features in Embree 2.16.3
- Increased accuracy for handling subdivision surfaces. This fixes
cracks when using displacement mapping but reduces performance
at irregular vertices.
- Fixed a bug where subdivision geometry was not properly updated
when modifying only the tesselation rate and vertex array.
### New Features in Embree 2.16.2
- Fixed bug that caused NULL intersection context in intersection
filter when instancing was used.
- Fixed an issue where uv's where outside the triangle (or quad) for
very small triangles (or quads). In robust mode we improved the uv
calculation to avoid that issue, in fast mode we accept that
inconsistency for better performance.
- Changed UV encoding for non-quad subdivision patches to
allow a subpatch UV range of `[-0.5,1.5[`. Using this new encoding
one can use finite differences to calculate derivatives if required.
Please adjust your code in case you rely on the old encoding.
### New Features in Embree 2.16.1
- Workaround for compile issues with Visual Studio 2017
- Fixed bug in subdiv code for static scenes when using tessellation
levels larger than 50.
- Fixed low performance when adding many geometries to a scene.
- Fixed high memory consumption issue when using instances in
dynamic scene (by disabling two level builder for user geometries
and instances).
### New Features in Embree 2.16.0
- Improved multi-segment motion blur support for scenes with
different number of time steps per mesh.
- New top level BVH builder that improves build times and BVH quality
of two-level BVHs.
- Added support to enable only a single ISA. Previously code was
always compiled for SSE2.
- Improved single ray tracing performance for incoherent rays on
AVX-512 architectures by 5-10%.
- Improved packet/hybrid ray tracing performance for incoherent rays
on AVX-512 architectures by 10-30%.
- Improved stream ray tracing performance for coherent rays in
structure-of-pointers layout by 40-70%.
- BVH builder for compact scenes of triangles and quads needs
essentially no temporary memory anymore. This doubles the
maximal scene size that can be rendered in compact mode.
- Triangles no longer store the geometry normal in fast/default mode
which reduces memory consumption by up to 20%.
- Compact mode uses BVH4 now consistently which reduces memory
consumption by up to 10%.
- Reduced memory consumption for small scenes (of 10k-100k primitives)
and dynamic scenes.
- Improved performance of user geometries and instances through BVH8
support.
- The API supports now specifying the geometry ID of a geometry at
construction time. This way matching the geometry ID used by
Embree and the application is simplified.
- Fixed a bug that would have caused a failure of the BVH builder
for dynamic scenes when run on a machine with more then 1000 threads.
- Fixed a bug that could have been triggered when reaching the maximal
number of mappings under Linux (`vm.max_map_count`). This could have
happened when creating a large number of small static scenes.
- Added huge page support for Windows and MacOSX (experimental).
- Added support for Visual Studio 2017.
- Removed support for Visual Studio 2012.
- Precompiled binaries now require a CPU supporting at least the
SSE4.2 ISA.
- We no longer provide precompiled binaries for 32-bit on Windows.
- Under Windows one now has to use the platform toolset option in
CMake to switch to Clang or the Intel® Compiler.
- Fixed a bug for subdivision meshes when using the incoherent scene
flag.
- Fixed a bug in the line geometry intersection, that caused reporting
an invalid line segment intersection with primID -1.
- Buffer stride for vertex buffers of different time steps of triangle
and quad meshes have to be identical now.
- Fixed a bug in the curve geometry intersection code when passed a
perfect cylinder.
### New Features in Embree 2.15.0
- Added `rtcCommitJoin` mode that allows thread to join a build
operation. When using the internal tasking system this allows
Embree to solely use the threads that called `rtcCommitJoin` to
build the scene, while previously also normal worker threads
participated in the build. You should no longer use `rtcCommit`
to join a build.
- Added `rtcDeviceSetErrorFunction2` API call, which sets an error
callback function which additionally gets passed a user provided
pointer (`rtcDeviceSetErrorFunction` is now deprecated).
- Added `rtcDeviceSetMemoryMonitorFunction2` API call, which sets a
memory monitor callback function which additionally get passed a
user provided pointer. (`rtcDeviceSetMemoryMonitorFunction` is now
deprecated).
- Build performance for hair geometry improved by up to 2×.
- Standard BVH build performance increased by 5%.
- Added API extension to use internal Morton-code based builder, the
standard binned-SAH builder, and the spatial split-based SAH builder.
- Added support for BSpline hair and curves. Embree uses
either the Bézier or BSpline basis internally, and converts other
curves, which requires more memory during rendering. For reduced
memory consumption set the `EMBREE_NATIVE_SPLINE_BASIS` to the basis
your application uses (which is set to `BEZIER` by default).
- Setting the number of threads through `tbb::taskscheduler_init`
object on the application side is now working properly.
- Windows and Linux releases are build using AVX-512 support.
- Implemented hybrid traversal for hair and line segments for
improved ray packet performance.
- AVX-512 code compiles with Clang 4.0.0
- Fixed crash when ray packets were disabled in CMake.
### New Features in Embree 2.14.0
- Added `ignore_config_files` option to init flags that allows the
application to ignore Embree configuration files.
- Face-varying interpolation is now supported for subdivision surfaces.
- Up to 16 user vertex buffers are supported for vertex
attribute interpolation.
- Deprecated `rtcSetBoundaryMode` function, please use the new
`rtcSetSubdivisionMode` function.
- Added `RTC_SUBDIV_PIN_BOUNDARY` mode for handling boundaries of
subdivision meshes.
- Added `RTC_SUBDIV_PIN_ALL` mode to enforce linear interpolation
for subdivision meshes.
- Optimized object generation performance for dynamic scenes.
- Reduced memory consumption when using lots of small dynamic objects.
- Fixed bug for subdivision surfaces using low tessellation rates.
- Hair geometry now uses a new ribbon intersector that intersects with
ray-facing quads. The new intersector also returns the v-coordinate
of the hair intersection, and fixes artefacts at junction points
between segments, at the cost of a small performance hit.
- Added `rtcSetBuffer2` function, that additionally gets the number of
elements of a buffer. In dynamic scenes, this function allows to
quickly change buffer sizes, making it possible to change the number
of primitives of a mesh or the number of crease features for
subdivision surfaces.
- Added simple 'viewer_anim' tutorial for rendering key
frame animations and 'buildbench' for measuring BVH (re-)build
performance for static and dynamic scenes.
- Added more AVX-512 optimizations for future architectures.
### New Features in Embree 2.13.0
- Improved performance for compact (but not robust) scenes.
- Added robust mode for motion blurred triangles and quads.
- Added fast dynamic mode for user geometries.
- Up to 20% faster BVH build performance on the second generation
Intel® Xeon Phi™ processor codenamed Knights Landing.
- Improved quality of the spatial split builder.
- Improved performance for coherent streams of ray packets (SOA
layout), e.g. for fast primary visibility.
- Various bug fixes in tessellation cache, quad-based spatial
split builder, etc.
### New Features in Embree 2.12.0
- Added support for multi-segment motion blur for all primitive types.
- API support for stream of pointers to single rays (`rtcIntersect1Mp`
and `rtcOccluded1Mp`)
- Added support for multi-segment motion blur for all primitive
types.
- API support for stream of pointers to single rays (rtcIntersect1Mp and
rtcOccluded1Mp)
- Improved BVH refitting performance for dynamic scenes.
- Improved high-quality mode for quads (added spatial split builder
for quads)
@@ -205,34 +14,34 @@ Version History
enabled machines.
- Performance and correctness bugfix in optimization for streams of
coherent (single) rays.
- Fixed large memory consumption (issue introduced in Embree v2.11.0).
If you use Embree v2.11.0 please upgrade to Embree v2.12.0.
- Reduced memory consumption for dynamic scenes containing small
meshes.
- Fixed large memory consumption (issue introduced in Embree
v2.11.0). If you use Embree v2.11.0 please upgrade to Embree
v2.12.0.
- Reduced memory consumption for dynamic scenes containing small meshes.
- Added support to start and affinitize TBB worker threads by passing
"`start_threads=1,set_affinity=1`" to `rtcNewDevice`. These settings
"start_threads=1,set_affinity=1" to rtcNewDevice. These settings
are recommended on systems with a high thread count.
- `rtcInterpolate2` can now be called within a displacement shader.
- Added initial support for Microsoft's Parallel Pattern Library (PPL)
as tasking system alternative (for optimal performance TBB is
highly recommended).
- Updated to TBB 2017 which is released under the Apache v2.0 license.
- Dropped support for Visual Studio 2012 Win32 compiler. Visual Studio
2012 x64 is still supported.
- rtcInterpolate2 can now be called within a displacement shader.
- Added initial support for Microsoft's Parallel Pattern Library (PPL) as
tasking system alternative (for optimial performance TBB is highly recommended).
- Updated to TBB 2017 which is released under the Apache v2.0
license.
- Dropped support for Visual Studio 2012 Win32 compiler. Visual
Studio 2012 x64 is still supported.
### New Features in Embree 2.11.0
- Improved performance for streams of coherent (single) rays flagged
with `RTC_INTERSECT_COHERENT`. For such coherent ray streams, e.g.
primary rays, the performance typically improves by 1.3-2×.
- New spatial split BVH builder for triangles, which is 2-6× faster
primary rays, the performance typically improves by 1.3–2×.
- New spatial split BVH builder for triangles, which is 2–6× faster
than the previous version and more memory conservative.
- Improved performance and scalability of all standard BVH builders on
systems with large core counts.
- Fixed `rtcGetBounds` for motion blur scenes.
- Thread affinity is now on by default when running on the latest
Intel® Xeon Phi™ processor.
- Added AVX-512 support for future Intel® Xeon processors.
- Added AVX512 support for future Intel® Xeon processors.
### New Features in Embree 2.10.0
@@ -242,12 +51,12 @@ Version History
- Geometry types can get disabled at compile time.
- Modified and extended the ray stream API.
- Added new callback mechanism for the ray stream API.
- Improved ray stream performance (up to 5-10%).
- Improved ray stream performance (up to 5–10%).
- Up to 20% faster morton builder on machines with large core counts.
- Lots of optimizations for the second generation Intel® Xeon Phi™
processor codenamed Knights Landing.
- Added experimental support for compressed BVH nodes (reduces node
size to 56-62% of uncompressed size). Compression introduces a
size to 56–62% of uncompressed size). Compression introduces a
typical performance overhead of ~10%.
- Bugfix in backface culling mode. We do now properly cull the
backfaces and not the frontfaces.
@@ -258,8 +67,8 @@ Version History
### New Features in Embree 2.9.0
- Improved shadow ray performance (10-100% depending on the scene).
- Added initial support for ray streams (10-30% higher performance
- Improved shadow ray performance (10–100% depending on the scene).
- Added initial support for ray streams (10–30% higher performance
depending on ray coherence in the stream).
- Added support to calculate second order derivatives using the
`rtcInterpolate2` function.
@@ -279,30 +88,27 @@ Version History
- Added support for line segment geometry.
- Added support for quad geometry (replaces triangle-pairs feature).
- Added support for linear motion blur of user geometries.
- Improved performance through AVX-512 optimizations.
- Improved performance of lazy scene build (when using TBB 4.4 update
2).
- Improved performance through AVX512 optimizations.
- Improved performance of lazy scene build (when using TBB 4.4 update 2).
- Improved performance through huge page support under linux.
### New Features in Embree 2.7.1
- Internal tasking system supports cancellation of build operations.
- ISPC mode for robust and compact scenes got significantly faster
(implemented hybrid traversal for bvh4.triangle4v and
bvh4.triangle4i).
(implemented hybrid traversal for bvh4.triangle4v and bvh4.triangle4i).
- Hair rendering got faster as we fixed some issues with the SAH
heuristic cost factors.
- BVH8 got slight faster for single ray traversal (improved sorting
when hitting more than 4 boxes).
- BVH build performance got up to 30% faster on CPUs with high core
counts (improved parallel partition code).
- High quality build mode again working properly (spatial splits had
been deactivated in v2.7.0 due to some bug).
- High quality build mode again working properly (spatial splits had been
deactivated in v2.7.0 due to some bug).
- Support for merging two adjacent triangles sharing a common edge
into a triangle-pair primitive (can reduce memory consumption and
BVH build times by up to 50% for mostly quad-based input meshes).
- Internal cleanups (reduced number of traversal kernels by more
templating).
- Internal cleanups (reduced number of traversal kernels by more templating)
- Reduced stack size requirements of BVH builders.
- Fixed crash for dynamic scenes, triggered by deleting all
geometries from the scene.
@@ -330,7 +136,7 @@ Version History
- Reduced virtual address space usage for static geometries.
- Fixed some AVX2 code paths when compiling with GCC or Clang.
- Bugfix for subdiv patches with non-matching winding order.
- Bugfix in ISA detection of AVX-512.
- Bugfix in ISA detection of AVX512.
### New Features in Embree 2.6.1
@@ -338,7 +144,7 @@ Version History
e.g. up to 2× faster for scenes where only the tessellation levels
are changing per frame, and up to 3× faster for scenes with lots of
crease features
- Initial support for architectures supporting the new 16-wide AVX-512
- Initial support for architectures supporting the new 16-wide AVX512
ISA
- Implemented intersection filter callback support for subdivision
surfaces
@@ -416,7 +222,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)
@@ -472,6 +278,29 @@ Version History
- New variant of the SAH-based builder using triangle pre-splits
(Xeon Phi)
### Example Performance Numbers for Embree 2.1
BVH rebuild performance (including triangle accel generation, excluding
memory allocation) for scenes with 2–12 million triangles:
- Intel® Core™ i7 (Haswell-based CPU, 4 cores @ 3.0 GHz)
- 7–8 million triangles/s for the SAH-based BVH builder
- 30–36 million triangles/s for the Morton code-based BVH builder
- Intel® Xeon Phi™ 7120
- 37–40 million triangles/s for the SAH-based BVH builder
- 140–160 million triangles/s for the Morton code-based BVH
builder
Rendering of the Crown model (`crown.ecs`) with 4 samples per pixel
(`-spp 4`):
- Intel® Core™ i7 (Haswell-based CPU, 4 cores CPU @ 3.0 GHz)
- 1024×1024 resolution: 7.8 million rays per sec
- 1920×1080 resolution: 9.9 million rays per sec
- Intel® Xeon Phi™ 7120
- 1024×1024 resolution: 47.1 million rays per sec
- 1920×1080 resolution: 61.1 million rays per sec
### New Features in Embree 2.0
- Support for the Intel® Xeon Phi™ coprocessor platform
+106 -172
View File
@@ -1,5 +1,5 @@
## ======================================================================== ##
## Copyright 2009-2017 Intel Corporation ##
## Copyright 2009-2016 Intel Corporation ##
## ##
## Licensed under the Apache License, Version 2.0 (the "License"); ##
## you may not use this file except in compliance with the License. ##
@@ -15,9 +15,9 @@
## ======================================================================== ##
SET(EMBREE_VERSION_MAJOR 2)
SET(EMBREE_VERSION_MINOR 17)
SET(EMBREE_VERSION_PATCH 1)
SET(EMBREE_VERSION_NOTE "-alpha.0")
SET(EMBREE_VERSION_MINOR 13)
SET(EMBREE_VERSION_PATCH 0)
SET(EMBREE_VERSION_NOTE "-apha.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)
@@ -43,12 +42,8 @@ IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.git)
ENDIF()
CONFIGURE_FILE(
"${PROJECT_SOURCE_DIR}/kernels/rtcore_version.h.in"
"${PROJECT_SOURCE_DIR}/include/embree2/rtcore_version.h"
)
CONFIGURE_FILE(
"${PROJECT_SOURCE_DIR}/kernels/hash.h.in"
"${PROJECT_BINARY_DIR}/hash.h"
"${PROJECT_SOURCE_DIR}/kernels/version.h.in"
"${PROJECT_BINARY_DIR}/version.h"
)
FILE(WRITE "${PROJECT_BINARY_DIR}/hash" "${EMBREE_HASH}")
@@ -79,14 +74,7 @@ INCLUDE(test)
# Embree configuration
##############################################################
GET_PROPERTY(SHARED_LIBS_SUPPORTED GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS)
IF(SHARED_LIBS_SUPPORTED)
OPTION(EMBREE_STATIC_LIB "Build Embree as a static library.")
MARK_AS_ADVANCED(CLEAR EMBREE_STATIC_LIB)
ELSE()
SET(EMBREE_STATIC_LIB ON CACHE BOOL "Build Embree as a static library." FORCE)
MARK_AS_ADVANCED(EMBREE_STATIC_LIB)
ENDIF()
OPTION(EMBREE_STATIC_LIB "Build Embree as a static library." OFF)
IF (EMBREE_STATIC_LIB)
SET(EMBREE_LIB_TYPE STATIC)
ADD_DEFINITIONS(-DEMBREE_STATIC_LIB)
@@ -101,7 +89,6 @@ OPTION(EMBREE_TUTORIALS "Enable to build Embree tutorials" ON)
# Configurations (add configurations also to common/cmake/embree-config-default.cmake)
OPTION(EMBREE_STAT_COUNTERS "Enables statistic counters.")
OPTION(EMBREE_STACK_PROTECTOR "When enabled Embree compiles with stack protection against return address overrides." OFF)
OPTION(EMBREE_RAY_MASK "Enables ray mask support.")
OPTION(EMBREE_BACKFACE_CULLING "Enables backface culling.")
@@ -117,39 +104,24 @@ OPTION(EMBREE_GEOMETRY_SUBDIV "Enables support for subdiv geometries." ON)
OPTION(EMBREE_GEOMETRY_USER "Enables support for user geometries." ON)
OPTION(EMBREE_RAY_PACKETS "Enabled support for ray packets." ON)
SET(EMBREE_NATIVE_SPLINE_BASIS BEZIER CACHE STRING "Sets the basis for curves which Embree uses internally. Other types are converted and need more memory.")
SET_PROPERTY(CACHE EMBREE_NATIVE_SPLINE_BASIS PROPERTY STRINGS BSPLINE BEZIER)
IF (EMBREE_NATIVE_SPLINE_BASIS STREQUAL "BSPLINE")
SET(EMBREE_NATIVE_CURVE_BSPLINE ON)
ELSE()
SET(EMBREE_NATIVE_CURVE_BSPLINE OFF)
ENDIF()
SET(EMBREE_TASKING_SYSTEM "TBB" CACHE STRING "Selects tasking system")
IF (WIN32)
SET_PROPERTY(CACHE EMBREE_TASKING_SYSTEM PROPERTY STRINGS TBB INTERNAL PPL)
ELSE()
SET_PROPERTY(CACHE EMBREE_TASKING_SYSTEM PROPERTY STRINGS TBB INTERNAL)
ENDIF()
SET_PROPERTY(CACHE EMBREE_TASKING_SYSTEM PROPERTY STRINGS TBB INTERNAL PPL)
IF (EMBREE_TASKING_SYSTEM STREQUAL "TBB")
SET(TASKING_TBB ON )
SET(TASKING_INTERNAL OFF)
SET(TASKING_PPL OFF )
ADD_DEFINITIONS(-DTASKING_TBB)
LIST(APPEND ISPC_DEFINITIONS -DTASKING_TBB)
ELSEIF (EMBREE_TASKING_SYSTEM STREQUAL "PPL")
SET(TASKING_PPL ON )
SET(TASKING_TBB OFF )
SET(TASKING_INTERNAL OFF)
ADD_DEFINITIONS(-DTASKING_PPL)
LIST(APPEND ISPC_DEFINITIONS -DTASKING_PPL)
ELSE()
SET(TASKING_INTERNAL ON )
SET(TASKING_TBB OFF)
SET(TASKING_PPL OFF )
ADD_DEFINITIONS(-DTASKING_INTERNAL)
LIST(APPEND ISPC_DEFINITIONS -DTASKING_INTERNAL)
ENDIF()
CONFIGURE_FILE(
@@ -158,81 +130,9 @@ CONFIGURE_FILE(
)
##############################################################
# ISA configuration
# Create Binary Packages (uses above config options)
##############################################################
IF(CMAKE_CXX_COMPILER_WRAPPER STREQUAL "CrayPrgEnv")
SET(EMBREE_MAX_ISA "NONE" CACHE STRING "Selects highest ISA to support.")
ELSE()
SET(EMBREE_MAX_ISA "AVX2" CACHE STRING "Selects highest ISA to support.")
ENDIF()
SET_PROPERTY(CACHE EMBREE_MAX_ISA PROPERTY STRINGS NONE SSE2 SSE4.2 AVX AVX2 AVX512KNL AVX512SKX)
IF (EMBREE_MAX_ISA STREQUAL "NONE")
OPTION(EMBREE_ISA_SSE2 "Enables SSE2 ISA.")
OPTION(EMBREE_ISA_SSE42 "Enables SSE4.2 ISA.")
OPTION(EMBREE_ISA_AVX "Enables AVX ISA.")
OPTION(EMBREE_ISA_AVX2 "Enables AVX2 ISA.")
OPTION(EMBREE_ISA_AVX512KNL "Enables AVX512 ISA for Knights Landing.")
OPTION(EMBREE_ISA_AVX512SKX "Enables AVX512 ISA for Skylake.")
IF(NOT (EMBREE_ISA_SSE2 OR EMBREE_ISA_SSE42 OR EMBREE_ISA_AVX OR
EMBREE_ISA_AVX2 OR EMBREE_ISA_AVX512KNL OR EMBREE_ISA_AVX512SKX))
MESSAGE(STATUS "Detecting default ISA:")
INCLUDE(check_isa_default)
CHECK_ISA_DEFAULT(EMBREE_ISA_DEFAULT)
MESSAGE(STATUS "Detecting default ISA: ${EMBREE_ISA_DEFAULT}")
SET(EMBREE_ISA_${EMBREE_ISA_DEFAULT} ON)
ENDIF()
ELSE()
UNSET(EMBREE_ISA_SSE2 CACHE)
UNSET(EMBREE_ISA_SSE42 CACHE)
UNSET(EMBREE_ISA_AVX CACHE)
UNSET(EMBREE_ISA_AVX2 CACHE)
UNSET(EMBREE_ISA_AVX512KNL CACHE)
UNSET(EMBREE_ISA_AVX512SKX CACHE)
IF(EMBREE_MAX_ISA STREQUAL "SSE2")
SET(ISA 1)
ELSEIF(EMBREE_MAX_ISA STREQUAL "SSE4.2")
SET(ISA 2)
ELSEIF(EMBREE_MAX_ISA STREQUAL "AVX")
SET(ISA 3)
ELSEIF(EMBREE_MAX_ISA STREQUAL "AVX2")
SET(ISA 4)
ELSEIF(EMBREE_MAX_ISA STREQUAL "AVX512KNL")
SET(ISA 5)
ELSEIF(EMBREE_MAX_ISA STREQUAL "AVX512SKX")
SET(ISA 6)
ELSE()
MESSAGE(FATAL_ERROR "Unsupported ISA specified: " ${EMBREE_MAX_ISA})
ENDIF()
SET(EMBREE_ISA_SSE2 OFF)
SET(EMBREE_ISA_SSE42 OFF)
SET(EMBREE_ISA_AVX OFF)
SET(EMBREE_ISA_AVX2 OFF)
SET(EMBREE_ISA_AVX512KNL OFF)
SET(EMBREE_ISA_AVX512SKX OFF)
IF (ISA GREATER 0)
SET(EMBREE_ISA_SSE2 ON)
ENDIF ()
IF (ISA GREATER 1)
SET(EMBREE_ISA_SSE42 ON)
ENDIF ()
IF (ISA GREATER 2)
SET(EMBREE_ISA_AVX ON)
ENDIF ()
IF (ISA GREATER 3)
SET(EMBREE_ISA_AVX2 ON)
ENDIF ()
IF (ISA GREATER 4)
SET(EMBREE_ISA_AVX512KNL ON)
ENDIF ()
IF (ISA GREATER 5)
SET(EMBREE_ISA_AVX512SKX ON)
ENDIF ()
ENDIF()
include(package)
##############################################################
# Compiler
@@ -248,22 +148,13 @@ IF (WIN32)
SET_PROPERTY(GLOBAL PROPERTY USE_FOLDERS ON)
IF (${CMAKE_GENERATOR_TOOLSET} MATCHES "^LLVM" )
MESSAGE("CLANG detected")
INCLUDE(clang)
ELSEIF(${CMAKE_GENERATOR_TOOLSET} MATCHES "^Intel")
MESSAGE("Intel Compiler detected")
INCLUDE (icc)
ELSE()
IF (EMBREE_ISA_AVX512KNL OR EMBREE_ISA_AVX512SKX)
MESSAGE(FATAL_ERROR "Microsoft Visual C++ Compiler does not support AVX512. Please use Intel Compiler or Clang.")
ENDIF()
INCLUDE (msvc)
ENDIF()
ELSE (WIN32)
IF(CMAKE_CXX_COMPILER_WRAPPER STREQUAL "CrayPrgEnv")
INCLUDE(crayprgenv)
ELSEIF (${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU")
IF (${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU")
INCLUDE (gcc)
ELSEIF (${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang")
INCLUDE (clang)
@@ -284,79 +175,122 @@ ELSE (WIN32)
ENDIF (WIN32)
##############################################################
# ISA configuration continued
# ISA configuration
##############################################################
SET(SSE2 0)
SET(SSE42 1)
SET(AVX 2)
SET(AVX2 3)
SET(AVX512KNL 4)
SET(AVX512SKX 5)
IF(APPLE)
SET(EMBREE_MAX_ISA "AVX2" CACHE STRING "Selects highest ISA to support.")
ELSEIF(NOT COMPILER STREQUAL "ICC")
SET(EMBREE_MAX_ISA "AVX2" CACHE STRING "Selects highest ISA to support.")
ELSE()
SET(EMBREE_MAX_ISA "AVX512SKX" CACHE STRING "Selects highest ISA to support.")
ENDIF ()
UNSET(FLAGS_LOWEST)
SET_PROPERTY(CACHE EMBREE_MAX_ISA PROPERTY STRINGS SSE2 SSE3 SSSE3 SSE4.1 SSE4.2 AVX AVX-I AVX2 AVX512KNL AVX512SKX)
IF (EMBREE_ISA_SSE2)
ADD_DEFINITIONS(-DEMBREE_TARGET_SSE2)
LIST(APPEND ISPC_TARGETS "sse2")
IF(NOT FLAGS_LOWEST)
SET(ISA_LOWEST ${SSE2})
SET(FLAGS_LOWEST ${FLAGS_SSE2})
ENDIF()
ENDIF()
IF (EMBREE_MAX_ISA STREQUAL "SSE2")
SET(ISA 1)
ENDIF ()
IF (EMBREE_ISA_SSE42)
ADD_DEFINITIONS(-DEMBREE_TARGET_SSE42)
IF (EMBREE_MAX_ISA STREQUAL "SSE3")
SET(ISA 2)
ENDIF ()
IF (EMBREE_MAX_ISA STREQUAL "SSSE3")
SET(ISA 3)
ENDIF ()
IF (EMBREE_MAX_ISA STREQUAL "SSE4.1")
SET(ISA 4)
ENDIF ()
IF (EMBREE_MAX_ISA STREQUAL "SSE4.2")
SET(ISA 5)
ENDIF ()
IF (EMBREE_MAX_ISA STREQUAL "AVX")
SET(ISA 6)
ENDIF ()
IF (EMBREE_MAX_ISA STREQUAL "AVX-I")
SET(ISA 7)
ENDIF ()
IF (EMBREE_MAX_ISA STREQUAL "AVX2")
SET(ISA 8)
ENDIF ()
IF (EMBREE_MAX_ISA STREQUAL "AVX512KNL")
SET(ISA 9)
ENDIF ()
IF (EMBREE_MAX_ISA STREQUAL "AVX512SKX")
SET(ISA 10)
ENDIF ()
SET(TARGET_SSE2 OFF)
SET(TARGET_SSE3 OFF)
SET(TARGET_SSSE3 OFF)
SET(TARGET_SSE41 OFF)
SET(TARGET_SSE42 OFF)
SET(TARGET_AVX OFF)
SET(TARGET_AVX2 OFF)
SET(TARGET_AVX512KNL OFF)
SET(TARGET_AVX512SKX OFF)
IF (ISA GREATER 0)
SET(TARGET_SSE2 ON)
SET(ISPC_TARGETS "sse2")
ADD_DEFINITIONS(-D__TARGET_SSE2__)
ENDIF ()
IF (ISA GREATER 1)
SET(TARGET_SSE3 ON)
ADD_DEFINITIONS(-D__TARGET_SSE3__)
ENDIF ()
IF (ISA GREATER 2)
SET(TARGET_SSSE3 ON)
ADD_DEFINITIONS(-D__TARGET_SSSE3__)
ENDIF ()
IF (ISA GREATER 3)
SET(TARGET_SSE41 ON)
ADD_DEFINITIONS(-D__TARGET_SSE41__)
LIST(APPEND ISPC_TARGETS "sse4")
IF(NOT FLAGS_LOWEST)
SET(ISA_LOWEST ${SSE42})
SET(FLAGS_LOWEST ${FLAGS_SSE42})
ENDIF()
ENDIF ()
IF (EMBREE_ISA_AVX)
ADD_DEFINITIONS(-DEMBREE_TARGET_AVX)
IF (ISA GREATER 4)
SET(TARGET_SSE42 ON)
ADD_DEFINITIONS(-D__TARGET_SSE42__)
ENDIF ()
IF (ISA GREATER 5)
SET(TARGET_AVX ON)
ADD_DEFINITIONS(-D__TARGET_AVX__)
LIST(APPEND ISPC_TARGETS "avx")
IF(NOT FLAGS_LOWEST)
SET(ISA_LOWEST ${AVX})
SET(FLAGS_LOWEST ${FLAGS_AVX})
ENDIF()
ENDIF ()
IF (EMBREE_ISA_AVX2)
ADD_DEFINITIONS(-DEMBREE_TARGET_AVX2)
IF (ISA GREATER 7)
SET(TARGET_AVX2 ON)
ADD_DEFINITIONS(-D__TARGET_AVX2__)
LIST(APPEND ISPC_TARGETS "avx2")
IF(NOT FLAGS_LOWEST)
SET(ISA_LOWEST ${AVX2})
SET(FLAGS_LOWEST ${FLAGS_AVX2})
ENDIF()
ENDIF ()
IF (EMBREE_ISA_AVX512KNL)
ADD_DEFINITIONS(-DEMBREE_TARGET_AVX512KNL)
IF (ISA GREATER 8)
SET(TARGET_AVX512KNL ON)
ADD_DEFINITIONS(-D__TARGET_AVX512KNL__)
LIST(APPEND ISPC_TARGETS "avx512knl-i32x16")
IF(NOT FLAGS_LOWEST)
SET(ISA_LOWEST ${AVX512KNL})
SET(FLAGS_LOWEST ${FLAGS_AVX512KNL})
ENDIF()
ENDIF ()
IF (EMBREE_ISA_AVX512SKX)
ADD_DEFINITIONS(-DEMBREE_TARGET_AVX512SKX)
IF (ISA GREATER 9)
SET(TARGET_AVX512SKX ON)
ADD_DEFINITIONS(-D__TARGET_AVX512SKX__)
LIST(APPEND ISPC_TARGETS "avx512skx-i32x16")
IF(NOT FLAGS_LOWEST)
SET(ISA_LOWEST ${AVX512SKX})
SET(FLAGS_LOWEST ${FLAGS_AVX512SKX})
ENDIF()
ENDIF ()
INCLUDE (ispc)
##############################################################
# Create Binary Packages (uses above config options)
##############################################################
include(package)
##############################################################
# Search paths
##############################################################
@@ -399,7 +333,7 @@ add_custom_target(uninstall
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/uninstall.cmake)
SET_PROPERTY(TARGET uninstall PROPERTY FOLDER CMakePredefinedTargets)
##############################################################
# Has to be last
##############################################################
+3 -6
View File
@@ -1,5 +1,5 @@
## ======================================================================== ##
## Copyright 2009-2017 Intel Corporation ##
## Copyright 2009-2016 Intel Corporation ##
## ##
## Licensed under the Apache License, Version 2.0 (the "License"); ##
## you may not use this file except in compliance with the License. ##
@@ -16,7 +16,7 @@
set(CTEST_PROJECT_NAME "Embree")
set(CTEST_NIGHTLY_START_TIME "22:00:00 UTC")
set(TEST_MODELS_HASH 01ada7ec1ace15ddba73aaab3f53ac6aac6a0309)
set(TEST_MODELS_HASH 99ec031b11b08afec271357e4cb9326cf8ac9942)
IF (NOT CTEST_DROP_SITE)
set(CTEST_DROP_METHOD "http")
@@ -26,8 +26,5 @@ IF (NOT CTEST_DROP_SITE)
endif()
list (APPEND CTEST_CUSTOM_WARNING_EXCEPTION "warning #1478") # deprecated function used
#list (APPEND CTEST_CUSTOM_WARNING_EXCEPTION "warning #10237") # -lcilkrts linked in dynamically, static library not available")
list (APPEND CTEST_CUSTOM_WARNING_EXCEPTION "warning #10237") # -lcilkrts linked in dynamically, static library not available")
list (APPEND CTEST_CUSTOM_WARNING_EXCEPTION "-Wextern-initializer")
SET(CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE 200000)
SET(CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE 800000)
+416 -852
View File
File diff suppressed because it is too large Load Diff
+1 -2
View File
@@ -1,5 +1,5 @@
## ======================================================================== ##
## Copyright 2009-2017 Intel Corporation ##
## Copyright 2009-2016 Intel Corporation ##
## ##
## Licensed under the Apache License, Version 2.0 (the "License"); ##
## you may not use this file except in compliance with the License. ##
@@ -15,7 +15,6 @@
## ======================================================================== ##
ADD_SUBDIRECTORY(sys)
ADD_SUBDIRECTORY(math)
ADD_SUBDIRECTORY(simd)
ADD_SUBDIRECTORY(lexers)
ADD_SUBDIRECTORY(tasking)
+1 -2
View File
@@ -1,5 +1,5 @@
## ======================================================================== ##
## Copyright 2009-2017 Intel Corporation ##
## Copyright 2009-2016 Intel Corporation ##
## ##
## Licensed under the Apache License, Version 2.0 (the "License"); ##
## you may not use this file except in compliance with the License. ##
@@ -24,7 +24,6 @@ ADD_LIBRARY(algorithms OBJECT
parallel_sort.cpp
parallel_set.cpp
parallel_map.cpp
parallel_filter.cpp
)
SET_PROPERTY(TARGET algorithms PROPERTY FOLDER common)
-69
View File
@@ -1,69 +0,0 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
// You may obtain a copy of the License at //
// //
// http://www.apache.org/licenses/LICENSE-2.0 //
// //
// Unless required by applicable law or agreed to in writing, software //
// distributed under the License is distributed on an "AS IS" BASIS, //
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
// See the License for the specific language governing permissions and //
// limitations under the License. //
// ======================================================================== //
#include "parallel_filter.h"
#include "../sys/regression.h"
#include <map>
namespace embree
{
struct parallel_filter_regression_test : public RegressionTest
{
parallel_filter_regression_test(const char* name) : RegressionTest(name) {
registerRegressionTest(this);
}
bool run ()
{
bool passed = true;
auto pred = [&]( uint32_t v ) { return (v & 0x3) == 0; };
for (size_t N=10; N<1000000; N=size_t(2.1*N))
{
size_t N0 = rand() % N;
/* initialize array with random numbers */
std::vector<uint32_t> src(N);
std::map<uint32_t,int> m;
for (size_t i=0; i<N; i++) src[i] = rand();
/* count elements up */
for (size_t i=N0; i<N; i++)
if (pred(src[i]))
m[src[i]] = 0;
for (size_t i=N0; i<N; i++)
if (pred(src[i]))
m[src[i]]++;
/* filter array */
//size_t M = sequential_filter(src.data(),N0,N,pred);
size_t M = parallel_filter(src.data(),N0,N,size_t(1024),pred);
/* check if filtered data is correct */
for (size_t i=N0; i<M; i++) {
passed &= pred(src[i]);
m[src[i]]--;
}
for (size_t i=N0; i<M; i++)
passed &= (m[src[i]] == 0);
}
return passed;
}
};
parallel_filter_regression_test parallel_filter_regression("parallel_filter_regression");
}
-106
View File
@@ -1,106 +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 "parallel_for.h"
namespace embree
{
template<typename Ty, typename Index, typename Predicate>
inline Index sequential_filter( Ty* data, const Index first, const Index last, const Predicate& predicate)
{
Index j = first;
for (Index i=first; i<last; i++)
if (predicate(data[i]))
data[j++] = data[i];
return j;
}
template<typename Ty, typename Index, typename Predicate>
inline Index parallel_filter( Ty* data, const Index begin, const Index end, const Index minStepSize, const Predicate& predicate)
{
/* sequential fallback */
if (end-begin <= minStepSize)
return sequential_filter(data,begin,end,predicate);
/* calculate number of tasks to use */
enum { MAX_TASKS = 512 };
const Index numThreads = TaskScheduler::threadCount();
const Index numBlocks = (end-begin+minStepSize-1)/minStepSize;
const Index taskCount = min(numThreads,numBlocks,(Index)MAX_TASKS);
/* filter blocks */
Index nused[MAX_TASKS];
Index nfree[MAX_TASKS];
parallel_for(taskCount, [&](const Index taskIndex)
{
const Index i0 = begin+(taskIndex+0)*(end-begin)/taskCount;
const Index i1 = begin+(taskIndex+1)*(end-begin)/taskCount;
const Index i2 = sequential_filter(data,i0,i1,predicate);
nused[taskIndex] = i2-i0;
nfree[taskIndex] = i1-i2;
});
/* calculate offsets */
Index sused=0;
Index sfree=0;
Index pfree[MAX_TASKS];
for (Index i=0; i<taskCount; i++)
{
sused+=nused[i];
Index cfree = nfree[i]; pfree[i] = sfree; sfree+=cfree;
}
/* return if we did not filter out any element */
assert(sfree <= end-begin);
assert(sused <= end-begin);
if (sused == end-begin)
return end;
/* otherwise we have to copy misplaced elements around */
parallel_for(taskCount, [&](const Index taskIndex)
{
/* destination to write elements to */
Index dst = begin+(taskIndex+0)*(end-begin)/taskCount+nused[taskIndex];
Index dst_end = min(dst+nfree[taskIndex],begin+sused);
if (dst_end <= dst) return;
/* range of misplaced elements to copy to destination */
Index r0 = pfree[taskIndex];
Index r1 = r0+dst_end-dst;
/* find range in misplaced elements in back to front order */
Index k0=0;
for (Index i=taskCount-1; i>0; i--)
{
if (k0 > r1) break;
Index k1 = k0+nused[i];
Index src = begin+(i+0)*(end-begin)/taskCount+nused[i];
for (Index i=max(r0,k0); i<min(r1,k1); i++) {
Index isrc = src-i+k0-1;
assert(dst >= begin && dst < end);
assert(isrc >= begin && isrc < end);
data[dst++] = data[isrc];
}
k0 = k1;
}
});
return begin+sused;
}
}
+1 -1
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
+2 -45
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
@@ -71,7 +71,7 @@ namespace embree
throw std::runtime_error("task cancelled");
#elif defined(TASKING_PPL)
concurrency::parallel_for(first, last, Index(1) /*minStepSize*/, [&](Index i) {
concurrency::parallel_for(first, last, minStepSize, [&](Index i) {
func(range<Index>(i,i+1));
});
@@ -87,47 +87,4 @@ namespace embree
assert(first <= last);
parallel_for(first,last,(Index)1,func);
}
#if defined(TASKING_TBB) && (TBB_INTERFACE_VERSION > 4001)
template<typename Index, typename Func>
__forceinline void parallel_for_static( const Index N, const Func& func)
{
tbb::parallel_for(Index(0),N,Index(1),[&](Index i) {
func(i);
},tbb::simple_partitioner());
if (tbb::task::self().is_cancelled())
throw std::runtime_error("task cancelled");
}
typedef tbb::affinity_partitioner affinity_partitioner;
template<typename Index, typename Func>
__forceinline void parallel_for_affinity( const Index N, const Func& func, tbb::affinity_partitioner& ap)
{
tbb::parallel_for(Index(0),N,Index(1),[&](Index i) {
func(i);
},ap);
if (tbb::task::self().is_cancelled())
throw std::runtime_error("task cancelled");
}
#else
template<typename Index, typename Func>
__forceinline void parallel_for_static( const Index N, const Func& func)
{
parallel_for(N,func);
}
struct affinity_partitioner {
};
template<typename Index, typename Func>
__forceinline void parallel_for_affinity( const Index N, const Func& func, affinity_partitioner& ap)
{
parallel_for(N,func);
}
#endif
}
+1 -1
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
+2 -2
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
@@ -35,7 +35,7 @@ namespace embree
{
public:
enum { MAX_TASKS = 512 };
enum { MAX_TASKS = MAX_THREADS };
__forceinline ParallelForForState ()
: taskCount(0) {}
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
@@ -50,7 +50,7 @@ namespace embree
ParallelForForPrefixSumState<size_t> state(array2,size_t(1));
/* dry run only counts */
size_t S = parallel_for_for_prefix_sum0( state, array2, size_t(0), [&](std::vector<size_t>* v, const range<size_t>& r, size_t k) -> size_t
size_t S = parallel_for_for_prefix_sum( state, array2, size_t(0), [&](std::vector<size_t>* v, const range<size_t>& r, size_t k, const size_t base) -> size_t
{
size_t s = 0;
for (size_t i=r.begin(); i<r.end(); i++) {
@@ -62,10 +62,10 @@ namespace embree
/* create properly sized output array */
flattened.resize(S);
for (auto& a : flattened) a.store(0);
memset(flattened.data(),0,sizeof(atomic<size_t>)*S);
/* now we actually fill the flattened array */
parallel_for_for_prefix_sum1( state, array2, size_t(0), [&](std::vector<size_t>* v, const range<size_t>& r, size_t k, const size_t base) -> size_t
parallel_for_for_prefix_sum( state, array2, size_t(0), [&](std::vector<size_t>* v, const range<size_t>& r, size_t k, const size_t base) -> size_t
{
size_t s = 0;
for (size_t i=r.begin(); i<r.end(); i++) {
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
@@ -34,46 +34,8 @@ namespace embree
};
template<typename ArrayArray, typename Index, typename Value, typename Func, typename Reduction>
__forceinline Value parallel_for_for_prefix_sum0( ParallelForForPrefixSumState<Value>& state, ArrayArray& array2, Index minStepSize,
const Value& identity, const Func& func, const Reduction& reduction)
{
/* calculate number of tasks to use */
const size_t taskCount = state.taskCount;
/* perform parallel prefix sum */
parallel_for(taskCount, [&](const size_t taskIndex)
{
const size_t k0 = (taskIndex+0)*state.size()/taskCount;
const size_t k1 = (taskIndex+1)*state.size()/taskCount;
size_t i0 = state.i0[taskIndex];
size_t j0 = state.j0[taskIndex];
/* iterate over arrays */
size_t k=k0;
Value N=identity;
for (size_t i=i0; k<k1; i++) {
const size_t size = array2[i] ? array2[i]->size() : 0;
const size_t r0 = j0, r1 = min(size,r0+k1-k);
if (r1 > r0) N = reduction(N, func(array2[i],range<size_t>(r0,r1),k));
k+=r1-r0; j0 = 0;
}
state.prefix_state.counts[taskIndex] = N;
});
/* calculate prefix sum */
Value sum=identity;
for (size_t i=0; i<taskCount; i++)
{
const Value c = state.prefix_state.counts[i];
state.prefix_state.sums[i] = sum;
sum=reduction(sum,c);
}
return sum;
}
template<typename ArrayArray, typename Index, typename Value, typename Func, typename Reduction>
__forceinline Value parallel_for_for_prefix_sum1( ParallelForForPrefixSumState<Value>& state, ArrayArray& array2, Index minStepSize,
const Value& identity, const Func& func, const Reduction& reduction)
__forceinline Value parallel_for_for_prefix_sum( ParallelForForPrefixSumState<Value>& state, ArrayArray& array2, Index minStepSize,
const Value& identity, const Func& func, const Reduction& reduction)
{
/* calculate number of tasks to use */
const size_t taskCount = state.taskCount;
@@ -109,17 +71,10 @@ namespace embree
return sum;
}
template<typename ArrayArray, typename Value, typename Func, typename Reduction>
__forceinline Value parallel_for_for_prefix_sum0( ParallelForForPrefixSumState<Value>& state, ArrayArray& array2,
template<typename ArrayArray, typename Value, typename Func, typename Reduction>
__forceinline Value parallel_for_for_prefix_sum( ParallelForForPrefixSumState<Value>& state, ArrayArray& array2,
const Value& identity, const Func& func, const Reduction& reduction)
{
return parallel_for_for_prefix_sum0(state,array2,size_t(1),identity,func,reduction);
}
template<typename ArrayArray, typename Value, typename Func, typename Reduction>
__forceinline Value parallel_for_for_prefix_sum1( ParallelForForPrefixSumState<Value>& state, ArrayArray& array2,
const Value& identity, const Func& func, const Reduction& reduction)
{
return parallel_for_for_prefix_sum1(state,array2,size_t(1),identity,func,reduction);
return parallel_for_for_prefix_sum(state,array2,size_t(1),identity,func,reduction);
}
}
+1 -1
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
+1 -1
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
+1 -1
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
+7 -28
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
@@ -39,14 +39,18 @@ namespace embree
/* *l < pivot */
while (likely(l <= r && is_left(*l) ))
{
//prefetchw(l+4); // FIXME: enable?
#if defined(__AVX512F__)
prefetch<PFHINT_L1EX>(l+4);
#endif
reduction_t(leftReduction,*l);
++l;
}
/* *r >= pivot) */
while (likely(l <= r && !is_left(*r)))
{
//prefetchw(r-4); FIXME: enable?
#if defined(__AVX512F__)
prefetch<PFHINT_L1EX>(r-4);
#endif
reduction_t(rightReduction,*r);
--r;
}
@@ -250,29 +254,4 @@ namespace embree
return begin+p->partition(leftReduction,rightReduction);
}
}
template<typename T, typename V, typename Vi, typename IsLeft, typename Reduction_T, typename Reduction_V>
__noinline size_t parallel_partitioning(T* array,
const size_t begin,
const size_t end,
const Vi &identity,
V &leftReduction,
V &rightReduction,
const IsLeft& is_left,
const Reduction_T& reduction_t,
const Reduction_V& reduction_v,
size_t BLOCK_SIZE,
size_t PARALLEL_THRESHOLD)
{
/* fall back to single threaded partitioning for small N */
if (unlikely(end-begin < PARALLEL_THRESHOLD))
return serial_partitioning(array,begin,end,leftReduction,rightReduction,is_left,reduction_t);
/* otherwise use parallel code */
else {
typedef parallel_partition_task<T,V,Vi,IsLeft,Reduction_T,Reduction_V> partition_task;
std::unique_ptr<partition_task> p(new partition_task(&array[begin],end-begin,identity,is_left,reduction_t,reduction_v,BLOCK_SIZE));
return begin+p->partition(leftReduction,rightReduction);
}
}
}
+2 -2
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
@@ -41,7 +41,7 @@ namespace embree
/* calculate parallel prefix sum */
std::vector<uint32_t> dst(N);
for (auto& v : dst) v = 0;
memset(dst.data(),0,N*sizeof(uint32_t));
for (size_t i=0; i<M; i++) {
uint32_t sum1 = parallel_prefix_sum(src,dst,N,0,std::plus<uint32_t>());
+2 -2
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
@@ -23,7 +23,7 @@ namespace embree
template<typename Value>
struct ParallelPrefixSumState
{
enum { MAX_TASKS = 512 };
enum { MAX_TASKS = MAX_THREADS };
Value counts[MAX_TASKS];
Value sums [MAX_TASKS];
};
+1 -1
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
+45 -73
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
@@ -35,21 +35,21 @@ namespace embree
template<typename Index, typename Value, typename Func, typename Reduction>
__noinline Value parallel_reduce_internal( Index taskCount, const Index first, const Index last, const Index minStepSize, const Value& identity, const Func& func, const Reduction& reduction )
{
const Index maxTasks = 512;
const Index threadCount = (Index) TaskScheduler::threadCount();
const size_t maxTasks = MAX_THREADS;
const size_t threadCount = TaskScheduler::threadCount();
taskCount = min(taskCount,threadCount,maxTasks);
/* parallel invokation of all tasks */
dynamic_large_stack_array(Value,values,taskCount,4096); // consumes at most 4096 bytes on the stack
parallel_for(taskCount, [&](const Index taskIndex) {
const Index k0 = first+(taskIndex+0)*(last-first)/taskCount;
const Index k1 = first+(taskIndex+1)*(last-first)/taskCount;
parallel_for(taskCount, [&](const size_t taskIndex) {
const size_t k0 = first+(taskIndex+0)*(last-first)/taskCount;
const size_t k1 = first+(taskIndex+1)*(last-first)/taskCount;
values[taskIndex] = func(range<Index>(k0,k1));
});
/* perform reduction over all tasks */
Value v = identity;
for (Index i=0; i<taskCount; i++) v = reduction(v,values[i]);
for (size_t i=0; i<taskCount; i++) v = reduction(v,values[i]);
return v;
}
@@ -73,77 +73,49 @@ namespace embree
throw std::runtime_error("task cancelled");
return v;
#else // TASKING_PPL
struct AlignedValue
{
char storage[__alignof(Value)+sizeof(Value)];
static uintptr_t alignUp(uintptr_t p, size_t a) { return p + (~(p - 1) % a); };
Value* getValuePtr() { return reinterpret_cast<Value*>(alignUp(uintptr_t(storage), __alignof(Value))); }
const Value* getValuePtr() const { return reinterpret_cast<Value*>(alignUp(uintptr_t(storage), __alignof(Value))); }
AlignedValue(const Value& v) { new(getValuePtr()) Value(v); }
AlignedValue(const AlignedValue& v) { new(getValuePtr()) Value(*v.getValuePtr()); }
AlignedValue(const AlignedValue&& v) { new(getValuePtr()) Value(*v.getValuePtr()); };
AlignedValue& operator = (const AlignedValue& v) { *getValuePtr() = *v.getValuePtr(); return *this; };
AlignedValue& operator = (const AlignedValue&& v) { *getValuePtr() = *v.getValuePtr(); return *this; };
operator Value() const { return *getValuePtr(); }
};
struct Iterator_Index
{
Index v;
typedef std::forward_iterator_tag iterator_category;
typedef AlignedValue value_type;
typedef Index difference_type;
typedef Index distance_type;
typedef AlignedValue* pointer;
typedef AlignedValue& reference;
__forceinline Iterator_Index() {}
__forceinline Iterator_Index(Index v) : v(v) {}
__forceinline bool operator== (Iterator_Index other) { return v == other.v; }
__forceinline bool operator!= (Iterator_Index other) { return v != other.v; }
__forceinline Iterator_Index operator++() { return Iterator_Index(++v); }
__forceinline Iterator_Index operator++(int) { return Iterator_Index(v++); }
};
auto range_reduction = [&](Iterator_Index begin, Iterator_Index end, const AlignedValue& start) {
assert(begin.v < end.v);
return reduction(start, func(range<Index>(begin.v, end.v)));
};
const Value v = concurrency::parallel_reduce(Iterator_Index(first), Iterator_Index(last), AlignedValue(identity), range_reduction, reduction);
return v;
struct AlignedValue
{
char storage[__alignof(Value)+sizeof(Value)];
static uintptr_t alignUp(uintptr_t p, size_t a) { return p + (~(p - 1) % a); };
Value* getValuePtr() { return reinterpret_cast<Value*>(alignUp(uintptr_t(storage), __alignof(Value))); }
const Value* getValuePtr() const { return reinterpret_cast<Value*>(alignUp(uintptr_t(storage), __alignof(Value))); }
AlignedValue(const Value& v) { new(getValuePtr()) Value(v); }
AlignedValue(const AlignedValue& v) { new(getValuePtr()) Value(*v.getValuePtr()); }
AlignedValue(const AlignedValue&& v) { new(getValuePtr()) Value(*v.getValuePtr()); };
AlignedValue& operator = (const AlignedValue& v) { *getValuePtr() = *v.getValuePtr(); return *this; };
AlignedValue& operator = (const AlignedValue&& v) { *getValuePtr() = *v.getValuePtr(); return *this; };
operator Value() const { return *getValuePtr(); }
};
struct Iterator_size_t
{
size_t v;
typedef std::forward_iterator_tag iterator_category;
typedef AlignedValue value_type;
typedef size_t difference_type;
typedef size_t distance_type;
typedef AlignedValue* pointer;
typedef AlignedValue& reference;
__forceinline Iterator_size_t() {}
__forceinline Iterator_size_t(size_t v) : v(v) {}
__forceinline bool operator== (Iterator_size_t other) { return v == other.v; }
__forceinline bool operator!= (Iterator_size_t other) { return v != other.v; }
__forceinline Iterator_size_t operator++() { return Iterator_size_t(++v); }
__forceinline Iterator_size_t operator++(int) { return Iterator_size_t(v++); }
};
auto range_reduction = [&](Iterator_size_t begin, Iterator_size_t end, const AlignedValue& start) {
assert(begin.v < end.v);
return reduction(start, func(range<Index>(begin.v, end.v)));
};
const Value v = concurrency::parallel_reduce(Iterator_size_t(first), Iterator_size_t(last), AlignedValue(identity), range_reduction, reduction);
return v;
#endif
}
template<typename Index, typename Value, typename Func, typename Reduction>
__forceinline Value parallel_reduce( const Index first, const Index last, const Index minStepSize, const Index parallel_threshold, const Value& identity, const Func& func, const Reduction& reduction )
{
if (likely(last-first < parallel_threshold)) {
return func(range<Index>(first,last));
} else {
return parallel_reduce(first,last,minStepSize,identity,func,reduction);
}
}
template<typename Index, typename Value, typename Func, typename Reduction>
__forceinline Value parallel_reduce( const range<Index> range, const Index minStepSize, const Index parallel_threshold, const Value& identity, const Func& func, const Reduction& reduction )
{
return parallel_reduce(range.begin(),range.end(),minStepSize,parallel_threshold,identity,func,reduction);
}
template<typename Index, typename Value, typename Func, typename Reduction>
__forceinline Value parallel_reduce( const Index first, const Index last, const Value& identity, const Func& func, const Reduction& reduction )
{
auto funcr = [&] ( const range<Index> r ) {
Value v = identity;
for (Index i=r.begin(); i<r.end(); i++)
v = reduction(v,func(i));
return v;
};
return parallel_reduce(first,last,Index(1),identity,funcr,reduction);
}
template<typename Index, typename Value, typename Func, typename Reduction>
__forceinline Value parallel_reduce( const range<Index> range, const Value& identity, const Func& func, const Reduction& reduction )
{
return parallel_reduce(range.begin(),range.end(),Index(1),identity,func,reduction);
return parallel_reduce(first,last,Index(1),identity,func,reduction);
}
}
+1 -1
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
+1 -1
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
+1 -1
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
+7 -115
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
@@ -16,7 +16,6 @@
#pragma once
#include "../simd/simd.h"
#include "parallel_for.h"
#include <algorithm>
@@ -189,84 +188,10 @@ namespace embree
}
}
template<typename T>
static void radixsort32(T* const morton, const size_t num, const unsigned int shift = 3*8)
{
static const unsigned int BITS = 8;
static const unsigned int BUCKETS = (1 << BITS);
static const unsigned int CMP_SORT_THRESHOLD = 16;
__aligned(64) unsigned int count[BUCKETS];
/* clear buckets */
for (size_t i=0;i<BUCKETS;i++) count[i] = 0;
/* count buckets */
#if defined(__INTEL_COMPILER)
#pragma nounroll
#endif
for (size_t i=0;i<num;i++)
count[(unsigned(morton[i]) >> shift) & (BUCKETS-1)]++;
/* prefix sums */
__aligned(64) unsigned int head[BUCKETS];
__aligned(64) unsigned int tail[BUCKETS];
head[0] = 0;
for (size_t i=1; i<BUCKETS; i++)
head[i] = head[i-1] + count[i-1];
for (size_t i=0; i<BUCKETS-1; i++)
tail[i] = head[i+1];
tail[BUCKETS-1] = head[BUCKETS-1] + count[BUCKETS-1];
assert(tail[BUCKETS-1] == head[BUCKETS-1] + count[BUCKETS-1]);
assert(tail[BUCKETS-1] == num);
/* in-place swap */
for (size_t i=0;i<BUCKETS;i++)
{
/* process bucket */
while(head[i] < tail[i])
{
T v = morton[head[i]];
while(1)
{
const size_t b = (unsigned(v) >> shift) & (BUCKETS-1);
if (b == i) break;
std::swap(v,morton[head[b]++]);
}
assert((unsigned(v) >> shift & (BUCKETS-1)) == i);
morton[head[i]++] = v;
}
}
if (shift == 0) return;
size_t offset = 0;
for (size_t i=0;i<BUCKETS;i++)
if (count[i])
{
for (size_t j=offset;j<offset+count[i]-1;j++)
assert(((unsigned(morton[j]) >> shift) & (BUCKETS-1)) == i);
if (unlikely(count[i] < CMP_SORT_THRESHOLD))
insertionsort_ascending(morton + offset, count[i]);
else
radixsort32(morton + offset, count[i], shift-BITS);
for (size_t j=offset;j<offset+count[i]-1;j++)
assert(morton[j] <= morton[j+1]);
offset += count[i];
}
}
template<typename Ty, typename Key>
class ParallelRadixSort
{
static const size_t MAX_TASKS = 512;
static const size_t MAX_TASKS = MAX_THREADS;
static const size_t BITS = 8;
static const size_t BUCKETS = (1 << BITS);
typedef unsigned int TyRadixCount[BUCKETS];
@@ -313,19 +238,10 @@ namespace embree
/* count how many items go into the buckets */
for (size_t i=0; i<BUCKETS; i++)
radixCount[threadIndex][i] = 0;
/* iterate over src array and count buckets */
unsigned int * __restrict const count = radixCount[threadIndex];
#if defined(__INTEL_COMPILER)
#pragma nounroll
#endif
for (size_t i=startID; i<endID; i++) {
#if defined(__X86_64__)
const size_t index = ((size_t)(Key)src[i] >> (size_t)shift) & (size_t)mask;
#else
const Key index = ((Key)src[i] >> shift) & mask;
#endif
count[index]++;
radixCount[threadIndex][index]++;
}
}
@@ -342,22 +258,12 @@ namespace embree
/* calculate total number of items for each bucket */
__aligned(64) unsigned int total[BUCKETS];
/*
for (size_t i=0; i<BUCKETS; i++)
total[i] = 0;
*/
for (size_t i=0; i<BUCKETS; i+=VSIZEX)
vintx::store(&total[i], zero);
for (size_t i=0; i<threadCount; i++)
{
/*
for (size_t j=0; j<BUCKETS; j++)
total[j] += radixCount[i][j];
*/
for (size_t j=0; j<BUCKETS; j+=VSIZEX)
vintx::store(&total[j], vintx::load(&total[j]) + vintx::load(&radixCount[i][j]));
}
/* calculate start offset of each bucket */
__aligned(64) unsigned int offset[BUCKETS];
@@ -367,26 +273,13 @@ namespace embree
/* calculate start offset of each bucket for this thread */
for (size_t i=0; i<threadIndex; i++)
{
/*
for (size_t j=0; j<BUCKETS; j++)
offset[j] += radixCount[i][j];
*/
for (size_t j=0; j<BUCKETS; j+=VSIZEX)
vintx::store(&offset[j], vintx::load(&offset[j]) + vintx::load(&radixCount[i][j]));
}
/* copy items into their buckets */
#if defined(__INTEL_COMPILER)
#pragma nounroll
#endif
for (size_t i=startID; i<endID; i++) {
const Ty elt = src[i];
#if defined(__X86_64__)
const size_t index = ((size_t)(Key)src[i] >> (size_t)shift) & (size_t)mask;
#else
const size_t index = ((Key)src[i] >> shift) & mask;
#endif
const Key index = ((Key)src[i] >> shift) & mask;
dst[offset[index]++] = elt;
}
}
@@ -395,9 +288,8 @@ namespace embree
const Ty* __restrict src, Ty* __restrict dst,
const size_t numTasks)
{
affinity_partitioner ap;
parallel_for_affinity(numTasks,[&] (size_t taskIndex) { tbbRadixIteration0(shift,src,dst,taskIndex,numTasks); },ap);
parallel_for_affinity(numTasks,[&] (size_t taskIndex) { tbbRadixIteration1(shift,src,dst,taskIndex,numTasks); },ap);
parallel_for(numTasks,[&] (size_t taskIndex) { tbbRadixIteration0(shift,src,dst,taskIndex,numTasks); });
parallel_for(numTasks,[&] (size_t taskIndex) { tbbRadixIteration1(shift,src,dst,taskIndex,numTasks); });
}
void tbbRadixSort(const size_t numTasks)
+44
View File
@@ -0,0 +1,44 @@
## ======================================================================== ##
## Copyright 2009-2016 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. ##
## ======================================================================== ##
SET(LIBRARY_PATHS
/usr/lib /usr/local/lib /opt/local/lib)
FIND_PATH(OPENEXR_INCLUDE_DIR ImfHeader.h
/usr/include /usr/include/OpenEXR
/usr/local/include /usr/local/include/OpenEXR
/opt/local/include /opt/local/include/OpenEXR)
FIND_LIBRARY(OPENEXR_HALF_LIBRARY NAMES Half PATHS ${LIBRARY_PATHS})
FIND_LIBRARY(OPENEXR_IEX_LIBRARY NAMES Iex PATHS ${LIBRARY_PATHS})
FIND_LIBRARY(OPENEXR_IMATH_LIBRARY NAMES Imath PATHS ${LIBRARY_PATHS})
FIND_LIBRARY(OPENEXR_ILMIMF_LIBRARY NAMES IlmImf PATHS ${LIBRARY_PATHS})
FIND_LIBRARY(OPENEXR_ILMTHREAD_LIBRARY NAMES IlmThread PATHS ${LIBRARY_PATHS})
SET(OPENEXR_INCLUDE_DIRS ${OPENEXR_INCLUDE_DIR})
SET(OPENEXR_LIBRARIES ${OPENEXR_HALF_LIBRARY} ${OPENEXR_IEX_LIBRARY} ${OPENEXR_IMATH_LIBRARY} ${OPENEXR_ILMIMF_LIBRARY} ${OPENEXR_ILMTHREAD_LIBRARY})
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(OPENEXR DEFAULT_MSG OPENEXR_INCLUDE_DIR OPENEXR_HALF_LIBRARY OPENEXR_IEX_LIBRARY OPENEXR_IMATH_LIBRARY OPENEXR_ILMIMF_LIBRARY OPENEXR_ILMTHREAD_LIBRARY)
MARK_AS_ADVANCED(
OPENEXR_INCLUDE_DIR
OPENEXR_HALF_LIBRARY
OPENEXR_IEX_LIBRARY
OPENEXR_IMATH_LIBRARY
OPENEXR_ILMIMF_LIBRARY
OPENEXR_ILMTHREAD_LIBRARY
)
@@ -1,5 +1,5 @@
## ======================================================================== ##
## Copyright 2009-2017 Intel Corporation ##
## Copyright 2009-2016 Intel Corporation ##
## ##
## Licensed under the Apache License, Version 2.0 (the "License"); ##
## you may not use this file except in compliance with the License. ##
@@ -14,10 +14,13 @@
## limitations under the License. ##
## ======================================================================== ##
# use default install config
INCLUDE(${CMAKE_CURRENT_LIST_DIR}/embree-config-install.cmake)
FIND_PATH( OPENSUBDIV_INCLUDE_DIR NAMES opensubdiv/version.h )
FIND_LIBRARY( OPENSUBDIV_LIBRARY NAMES osdCPU)
# and override path variables to match for build directory
SET(EMBREE_INCLUDE_DIRS @PROJECT_SOURCE_DIR@/include)
SET(EMBREE_LIBRARY @PROJECT_BINARY_DIR@/@EMBREE_LIBRARY_NAME@)
SET(EMBREE_LIBRARIES ${EMBREE_LIBRARY})
SET(OPENSUBDIV_LIBRARIES ${OPENSUBDIV_LIBRARY} )
SET(OPENSUBDIV_INCLUDE_DIRS ${OPENSUBDIV_INCLUDE_DIR} )
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(OPENSUBDIV DEFAULT_MSG OPENSUBDIV_INCLUDE_DIR OPENSUBDIV_LIBRARY)
MARK_AS_ADVANCED(OPENSUBDIV_INCLUDE_DIR OPENSUBDIV_LIBRARY)
+1 -1
View File
@@ -1,5 +1,5 @@
## ======================================================================== ##
## Copyright 2009-2017 Intel Corporation ##
## Copyright 2009-2016 Intel Corporation ##
## ##
## Licensed under the Apache License, Version 2.0 (the "License"); ##
## you may not use this file except in compliance with the License. ##
+9 -60
View File
@@ -1,5 +1,5 @@
## ======================================================================== ##
## Copyright 2009-2017 Intel Corporation ##
## Copyright 2009-2016 Intel Corporation ##
## ##
## Licensed under the Apache License, Version 2.0 (the "License"); ##
## you may not use this file except in compliance with the License. ##
@@ -14,36 +14,13 @@
## limitations under the License. ##
## ======================================================================== ##
IF (NOT TBB_ROOT)
SET(TBB_ROOT $ENV{TBB_ROOT})
ENDIF()
IF (NOT TBB_ROOT)
SET(TBB_ROOT $ENV{TBBROOT})
ENDIF()
IF (WIN32)
# workaround for parentheses in variable name / CMP0053
SET(PROGRAMFILESx86 "PROGRAMFILES(x86)")
SET(PROGRAMFILES32 "$ENV{${PROGRAMFILESx86}}")
IF (NOT PROGRAMFILES32)
SET(PROGRAMFILES32 "$ENV{PROGRAMFILES}")
ENDIF()
IF (NOT PROGRAMFILES32)
SET(PROGRAMFILES32 "C:/Program Files (x86)")
ENDIF()
FIND_PATH(EMBREE_TBB_ROOT include/tbb/tbb.h
DOC "Root of TBB installation"
PATHS ${PROJECT_SOURCE_DIR}/tbb
PATHS ${PROJECT_SOURCE_DIR}/tbb "C:/Program Files (x86)/Intel/Composer XE/tbb"
NO_DEFAULT_PATH
)
FIND_PATH(EMBREE_TBB_ROOT include/tbb/tbb.h
HINTS ${TBB_ROOT}
PATHS
${PROJECT_SOURCE_DIR}/../tbb
"${PROGRAMFILES32}/IntelSWTools/compilers_and_libraries/windows/tbb"
"${PROGRAMFILES32}/Intel/Composer XE/tbb"
"${PROGRAMFILES32}/Intel/compilers_and_libraries/windows/tbb"
)
FIND_PATH(EMBREE_TBB_ROOT include/tbb/tbb.h)
IF (CMAKE_SIZEOF_VOID_P EQUAL 8)
SET(TBB_ARCH intel64)
@@ -55,10 +32,8 @@ IF (WIN32)
SET(TBB_VCVER vc10)
ELSEIF (MSVC11)
SET(TBB_VCVER vc11)
ELSEIF (MSVC12)
SET(TBB_VCVER vc12)
ELSE()
SET(TBB_VCVER vc14)
SET(TBB_VCVER vc12)
ENDIF()
SET(TBB_LIBDIR ${EMBREE_TBB_ROOT}/lib/${TBB_ARCH}/${TBB_VCVER})
@@ -81,40 +56,15 @@ ELSE ()
FIND_PATH(EMBREE_TBB_ROOT include/tbb/tbb.h
DOC "Root of TBB installation"
PATHS ${PROJECT_SOURCE_DIR}/tbb
PATHS ${PROJECT_SOURCE_DIR}/tbb /opt/intel/composerxe/tbb
NO_DEFAULT_PATH
)
FIND_PATH(EMBREE_TBB_ROOT include/tbb/tbb.h
DOC "Root of TBB installation"
HINTS ${TBB_ROOT}
PATHS
${PROJECT_SOURCE_DIR}/tbb
/opt/intel/composerxe/tbb
/opt/intel/compilers_and_libraries/tbb
/opt/intel/tbb
)
FIND_PATH(EMBREE_TBB_ROOT include/tbb/tbb.h)
IF (EMBREE_TBB_ROOT STREQUAL "")
FIND_PATH(TBB_INCLUDE_DIR tbb/task_scheduler_init.h)
FIND_LIBRARY(TBB_LIBRARY tbb)
FIND_LIBRARY(TBB_LIBRARY_MALLOC tbbmalloc)
ELSEIF (EXISTS ${EMBREE_TBB_ROOT}/cmake/TBBBuild.cmake)
OPTION(EMBREE_TBB_STATIC_LIB "Build TBB as a static library (building TBB as a static library is NOT recommended)")
if (EMBREE_TBB_STATIC_LIB)
include(${EMBREE_TBB_ROOT}/cmake/TBBBuild.cmake)
tbb_build(TBB_ROOT ${EMBREE_TBB_ROOT} CONFIG_DIR TBB_DIR MAKE_ARGS extra_inc=big_iron.inc)
SET(TBB_INCLUDE_DIR ${EMBREE_TBB_ROOT}/include)
SET(TBB_LIBRARY ${PROJECT_BINARY_DIR}/tbb_cmake_build/tbb_cmake_build_subdir_release/libtbb.a)
SET(TBB_LIBRARY_MALLOC ${PROJECT_BINARY_DIR}/tbb_cmake_build/tbb_cmake_build_subdir_release/libtbbmalloc.a)
else()
include(${EMBREE_TBB_ROOT}/cmake/TBBBuild.cmake)
tbb_build(TBB_ROOT ${EMBREE_TBB_ROOT} CONFIG_DIR TBB_DIR)
SET(TBB_INCLUDE_DIR ${EMBREE_TBB_ROOT}/include)
SET(TBB_LIBRARY ${PROJECT_BINARY_DIR}/tbb_cmake_build/tbb_cmake_build_subdir_release/libtbb.so.2)
SET(TBB_LIBRARY_MALLOC ${PROJECT_BINARY_DIR}/tbb_cmake_build/tbb_cmake_build_subdir_release/libtbbmalloc.so.2)
endif()
ELSE()
SET(TBB_INCLUDE_DIR TBB_INCLUDE_DIR-NOTFOUND)
SET(TBB_LIBRARY TBB_LIBRARY-NOTFOUND)
@@ -125,9 +75,8 @@ ELSE ()
FIND_LIBRARY(TBB_LIBRARY_MALLOC tbbmalloc PATHS ${EMBREE_TBB_ROOT}/lib NO_DEFAULT_PATH)
ELSE()
FIND_PATH(TBB_INCLUDE_DIR tbb/task_scheduler_init.h PATHS ${EMBREE_TBB_ROOT}/include NO_DEFAULT_PATH)
SET(TBB_HINTS HINTS ${EMBREE_TBB_ROOT}/lib/intel64/gcc4.4 ${EMBREE_TBB_ROOT}/lib ${EMBREE_TBB_ROOT}/lib64 PATHS /usr/libx86_64-linux-gnu/)
FIND_LIBRARY(TBB_LIBRARY tbb ${TBB_HINTS})
FIND_LIBRARY(TBB_LIBRARY_MALLOC tbbmalloc ${TBB_HINTS})
FIND_LIBRARY(TBB_LIBRARY tbb PATHS ${EMBREE_TBB_ROOT}/lib/intel64/gcc4.4 ${EMBREE_TBB_ROOT}/lib ${EMBREE_TBB_ROOT}/lib64 /usr/libx86_64-linux-gnu/ NO_DEFAULT_PATH)
FIND_LIBRARY(TBB_LIBRARY_MALLOC tbbmalloc PATHS ${EMBREE_TBB_ROOT}/lib/intel64/gcc4.4 ${EMBREE_TBB_ROOT}/lib ${EMBREE_TBB_ROOT}/lib64 /usr/libx86_64-linux-gnu/ NO_DEFAULT_PATH)
ENDIF()
ENDIF()
@@ -151,7 +100,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_LIBDIR}/tbb.lib ${TBB_LIBDIR}/tbbmalloc.lib DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT lib)
INSTALL(PROGRAMS ${TBB_BINDIR}/tbb.dll ${TBB_BINDIR}/tbbmalloc.dll DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT lib)
ELSEIF (EMBREE_ZIP_MODE)
IF (APPLE)
INSTALL(PROGRAMS ${EMBREE_TBB_ROOT}/lib/libtbb.dylib ${EMBREE_TBB_ROOT}/lib/libtbbmalloc.dylib DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT lib)
-31
View File
@@ -1,31 +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. ##
## ======================================================================== ##
IF (WIN32 OR APPLE)
return()
ENDIF()
execute_process(COMMAND objdump -C -t ${file} OUTPUT_VARIABLE output)
string(REPLACE "\n" ";" output ${output})
foreach (line ${output})
if ("${line}" MATCHES "O .bss")
if (NOT "${line}" MATCHES "std::__ioinit" AND # this is caused by iostream initialization and is likely also ok
NOT "${line}" MATCHES "\\(\\)::") # this matches a static inside a function which is fine
message(WARNING "\nProblematic global variable in non-SSE code:\n" ${line})
endif()
endif()
endforeach()
-40
View File
@@ -1,40 +0,0 @@
// ======================================================================== //
// Copyright 2017 Kitware, Inc. //
// //
// 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. //
// ======================================================================== //
#if \
defined(__AVX512F__) && defined(__AVX512CD__) && \
defined(__AVX512DQ__) && defined(__AVX512BW__) && defined(__AVX512VL__)
char const *info_isa = "ISA" ":" "AVX512SKX";
#elif \
defined(__AVX512F__) && defined(__AVX512CD__) && \
defined(__AVX512ER__) && defined(__AVX512PF__)
char const *info_isa = "ISA" ":" "AVX512KNL";
#elif defined(__AVX2__)
char const *info_isa = "ISA" ":" "AVX2";
#elif defined(__AVX__)
char const *info_isa = "ISA" ":" "AVX";
#elif defined(__SSE4_2__)
char const *info_isa = "ISA" ":" "SSE42";
#else // defined(__SSE2__)
char const *info_isa = "ISA" ":" "SSE2";
#endif
int main(int argc, char **argv)
{
int require = 0;
require += info_isa[argc];
return require;
}
-33
View File
@@ -1,33 +0,0 @@
## ======================================================================== ##
## Copyright 2017 Kitware, Inc. ##
## ##
## 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. ##
## ======================================================================== ##
SET(CHECK_ISA_DIR ${CMAKE_CURRENT_LIST_DIR})
FUNCTION(CHECK_ISA_DEFAULT OUTVAR)
SET(ISA_DEFAULT_BIN ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/check_isa_default.bin)
SET(SRC ${CHECK_ISA_DIR}/check_isa.cpp)
TRY_COMPILE(ISA_DEFAULT_COMPILE
${CMAKE_BINARY_DIR}
${SRC}
COPY_FILE ${ISA_DEFAULT_BIN}
)
IF(NOT ISA_DEFAULT_COMPILE)
SET(ISA_DEFAULT "SSE2")
RETURN()
ENDIF()
FILE(STRINGS ${ISA_DEFAULT_BIN} ISA_DEFAULT REGEX "^ISA:")
STRING(REPLACE "ISA:" "" ISA_DEFAULT "${ISA_DEFAULT}")
SET(${OUTVAR} ${ISA_DEFAULT} PARENT_SCOPE)
ENDFUNCTION()
+16 -97
View File
@@ -1,5 +1,5 @@
## ======================================================================== ##
## Copyright 2009-2017 Intel Corporation ##
## Copyright 2009-2016 Intel Corporation ##
## ##
## Licensed under the Apache License, Version 2.0 (the "License"); ##
## you may not use this file except in compliance with the License. ##
@@ -26,105 +26,24 @@ SET(FLAGS_AVX512SKX "-march=skx")
IF (WIN32)
SET(COMMON_CXX_FLAGS "")
SET(COMMON_CXX_FLAGS "${COMMON_CXX_FLAGS} /EHsc") # catch C++ exceptions only and extern "C" functions never throw a C++ exception
# SET(COMMON_CXX_FLAGS "${COMMON_CXX_FLAGS} /MP") # compile source files in parallel
SET(COMMON_CXX_FLAGS "${COMMON_CXX_FLAGS} /GR") # enable runtime type information (on by default)
SET(COMMON_CXX_FLAGS "${COMMON_CXX_FLAGS} -Xclang -fcxx-exceptions") # enable C++ exceptions in Clang
IF (EMBREE_STACK_PROTECTOR)
SET(COMMON_CXX_FLAGS "${COMMON_CXX_FLAGS} /GS") # protects against return address overrides
ELSE()
SET(COMMON_CXX_FLAGS "${COMMON_CXX_FLAGS} /GS-") # do not protect against return address overrides
ENDIF()
MACRO(DISABLE_STACK_PROTECTOR_FOR_FILE file)
IF (EMBREE_STACK_PROTECTOR)
SET_SOURCE_FILES_PROPERTIES(${file} PROPERTIES COMPILE_FLAGS "/GS-")
ENDIF()
ENDMACRO()
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${COMMON_CXX_FLAGS}")
SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /DEBUG") # generate debug information
SET(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} /DEBUG") # generate debug information
SET(COMMON_CXX_FLAGS "/EHsc /GR -Xclang -fcxx-exceptions")
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${COMMON_CXX_FLAGS} /DTBB_USE_DEBUG")
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${COMMON_CXX_FLAGS} /Ox /fp:fast /Oi /Gy")
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${COMMON_CXX_FLAGS} /Ox /fp:fast /Oi /Gy /DTBB_USE_DEBUG")
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${COMMON_CXX_FLAGS}")
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Ox") # enable full optimizations
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Oi") # inline intrinsic functions
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Gy") # package individual functions
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fno-vectorize") # disable auto vectorization
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${COMMON_CXX_FLAGS}")
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Ox") # enable full optimizations
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Oi") # inline intrinsic functions
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Gy") # package individual functions
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -fno-vectorize") # disable auto vectorization
SET(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} /DEBUG") # generate debug information
SET(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO} /DEBUG") # generate debug information
SET(SECURE_LINKER_FLAGS "")
SET(SECURE_LINKER_FLAGS "${SECURE_LINKER_FLAGS} /NXCompat") # compatible with data execution prevention (on by default)
SET(SECURE_LINKER_FLAGS "${SECURE_LINKER_FLAGS} /DynamicBase") # random rebase of executable at load time
IF (CMAKE_SIZEOF_VOID_P EQUAL 4)
SET(SECURE_LINKER_FLAGS "${SECURE_LINKER_FLAGS} /SafeSEH") # invoke known exception handlers (Win32 only, x64 exception handlers are safe by design)
ENDIF()
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${SECURE_LINKER_FLAGS}")
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${SECURE_LINKER_FLAGS}")
INCLUDE(msvc_post)
SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /DEBUG")
SET(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} /DEBUG")
ELSE()
OPTION(EMBREE_IGNORE_CMAKE_CXX_FLAGS "When enabled Embree ignores default CMAKE_CXX_FLAGS." ON)
IF (EMBREE_IGNORE_CMAKE_CXX_FLAGS)
SET(CMAKE_CXX_FLAGS "")
ENDIF()
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") # enables most warnings
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wformat -Wformat-security") # enables string format vulnerability warnings
IF (NOT APPLE)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIE") # enables support for more secure position independent execution
ENDIF()
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") # generate position independent code suitable for shared libraries
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") # enables C++11 features
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden") # makes all symbols hidden by default
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden") # makes all inline symbols hidden by default
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-strict-aliasing") # disables strict aliasing rules
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_FORTIFY_SOURCE=2") # perform extra security checks for some standard library calls
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-tree-vectorize") # disable auto vectorizer
IF (EMBREE_STACK_PROTECTOR)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstack-protector") # protects against return address overrides
ENDIF()
MACRO(DISABLE_STACK_PROTECTOR_FOR_FILE file)
IF (EMBREE_STACK_PROTECTOR)
SET_SOURCE_FILES_PROPERTIES(${file} PROPERTIES COMPILE_FLAGS "-fno-stack-protector")
ENDIF()
ENDMACRO()
SET(CMAKE_CXX_FLAGS_DEBUG "")
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG") # enable assertions
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DTBB_USE_DEBUG") # configure TBB in debug mode
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g") # generate debug information
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0") # disable optimizations
SET(CMAKE_CXX_FLAGS_RELEASE "")
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DNDEBUG") # disable assertions
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3") # enable full optimizations
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "")
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DDEBUG") # enable assertions
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DTBB_USE_DEBUG") # configure TBB in debug mode
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -g") # generate debug information
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -O3") # enable full optimizations
IF (APPLE)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=10.7") # makes sure code runs on older MacOSX versions
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") # link against libc++ which supports C++11 features
ELSE(APPLE)
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined") # issues link error for undefined symbols in shared library
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -z noexecstack") # we do not need an executable stack
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -z relro -z now") # re-arranges data sections to increase security
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -z noexecstack") # we do not need an executable stack
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -z relro -z now") # re-arranges data sections to increase security
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pie") # enables position independent execution for executable
ENDIF(APPLE)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fPIC -std=c++11 -fvisibility-inlines-hidden -fvisibility=hidden -fno-strict-aliasing")
SET(CMAKE_CXX_FLAGS_DEBUG "-DDEBUG -DTBB_USE_DEBUG -g -O0")
SET(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG -O3")
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-DDEBUG -DTBB_USE_DEBUG -g -O3")
ENDIF()
IF (APPLE)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=10.7 ") # we only use MacOSX 10.7 features
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++" ) # link against C++11 stdlib
ENDIF (APPLE)
+1 -1
View File
@@ -1,5 +1,5 @@
## ======================================================================== ##
## Copyright 2009-2017 Intel Corporation ##
## Copyright 2009-2016 Intel Corporation ##
## ##
## Licensed under the Apache License, Version 2.0 (the "License"); ##
## you may not use this file except in compliance with the License. ##
@@ -1,5 +1,5 @@
## ======================================================================== ##
## Copyright 2009-2017 Intel Corporation ##
## Copyright 2009-2016 Intel Corporation ##
## ##
## Licensed under the Apache License, Version 2.0 (the "License"); ##
## you may not use this file except in compliance with the License. ##
@@ -14,15 +14,6 @@
## limitations under the License. ##
## ======================================================================== ##
SET(EMBREE_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/@EMBREE_RELATIV_ROOT_DIR@)
GET_FILENAME_COMPONENT(EMBREE_ROOT_DIR "${EMBREE_ROOT_DIR}" ABSOLUTE)
SET(EMBREE_INCLUDE_DIRS ${EMBREE_ROOT_DIR}/@CMAKE_INSTALL_INCLUDEDIR@)
SET(EMBREE_LIBRARY ${EMBREE_ROOT_DIR}/@CMAKE_INSTALL_LIBDIR@/@EMBREE_LIBRARY_NAME@)
SET(EMBREE_LIBRARIES ${EMBREE_LIBRARY})
MARK_AS_ADVANCED(embree_DIR)
SET(EMBREE_VERSION @EMBREE_VERSION@)
SET(EMBREE_VERSION_MAJOR @EMBREE_VERSION_MAJOR@)
SET(EMBREE_VERSION_MINOR @EMBREE_VERSION_MINOR@)
@@ -30,13 +21,6 @@ SET(EMBREE_VERSION_PATCH @EMBREE_VERSION_PATCH@)
SET(EMBREE_VERSION_NOTE "@EMBREE_VERSION_NOTE@")
SET(EMBREE_MAX_ISA @EMBREE_MAX_ISA@)
SET(EMBREE_ISA_SSE2 @EMBREE_ISA_SSE2@)
SET(EMBREE_ISA_SSE42 @EMBREE_ISA_SSE42@)
SET(EMBREE_ISA_AVX @EMBREE_ISA_AVX@)
SET(EMBREE_ISA_AVX2 @EMBREE_ISA_AVX2@)
SET(EMBREE_ISA_AVX512KNL @EMBREE_ISA_AVX512KNL@)
SET(EMBREE_ISA_AVX512SKX @EMBREE_ISA_AVX512SKX@)
SET(EMBREE_BUILD_TYPE @CMAKE_BUILD_TYPE@)
SET(EMBREE_ISPC_SUPPORT @EMBREE_ISPC_SUPPORT@)
SET(EMBREE_STATIC_LIB @EMBREE_STATIC_LIB@)
@@ -1,5 +1,5 @@
## ======================================================================== ##
## Copyright 2009-2017 Intel Corporation ##
## Copyright 2009-2016 Intel Corporation ##
## ##
## Licensed under the Apache License, Version 2.0 (the "License"); ##
## you may not use this file except in compliance with the License. ##
@@ -14,24 +14,27 @@
## limitations under the License. ##
## ======================================================================== ##
IF (WIN32 OR APPLE)
return()
SET(EMBREE_INCLUDE_DIRS ${CMAKE_CURRENT_LIST_DIR}/../../../@CMAKE_INSTALL_INCLUDEDIR@)
SET(EMBREE_LIBRARY ${CMAKE_CURRENT_LIST_DIR}/../../@CMAKE_SHARED_LIBRARY_PREFIX@embree@CMAKE_SHARED_LIBRARY_SUFFIX@.@EMBREE_CONFIG_VERSION@)
SET(EMBREE_TASKING_TBB @TASKING_TBB@)
SET(EMBREE_USE_PACKAGED_TBB @EMBREE_ZIP_MODE@)
IF (${EMBREE_TASKING_TBB} AND ${EMBREE_USE_PACKAGED_TBB})
SET(EMBREE_TBB_LIBRARY ${CMAKE_CURRENT_LIST_DIR}/../../@CMAKE_SHARED_LIBRARY_PREFIX@tbb@CMAKE_SHARED_LIBRARY_SUFFIX@.2)
SET(EMBREE_TBB_LIBRARY_MALLOC ${CMAKE_CURRENT_LIST_DIR}/../../@CMAKE_SHARED_LIBRARY_PREFIX@tbbmalloc@CMAKE_SHARED_LIBRARY_SUFFIX@.2)
ELSE()
SET(EMBREE_USE_PACKAGED_TBB OFF)
UNSET(EMBREE_TBB_LIBRARY)
UNSET(EMBREE_TBB_LIBRARY_MALLOC)
ENDIF()
execute_process(COMMAND objdump -d ${file} OUTPUT_VARIABLE output)
string(REPLACE "\n" ";" output ${output})
SET(EMBREE_LIBRARIES
${EMBREE_LIBRARY}
${EMBREE_TBB_LIBRARY}
${EMBREE_TBB_LIBRARY_MALLOC}
)
SET(lastfunc "")
foreach (line ${output})
if ("${line}" MATCHES "^.*<([^>]*)>:$")
SET(lastfunc ${CMAKE_MATCH_1})
endif()
if ("${line}" MATCHES ".*sub[ ]+[$]([^,]*),%rsp.*")
set(bytes ${CMAKE_MATCH_1})
if ("${bytes}" GREATER "4096")
if ("${lastfunc}" MATCHES ".*recurse.*")
message(WARNING "Large stack space requirement: ${lastfunc} size: ${bytes}")
endif()
endif()
endif()
endforeach()
MARK_AS_ADVANCED(embree_DIR)
INCLUDE(${CMAKE_CURRENT_LIST_DIR}/embree-config-default.cmake)
@@ -1,5 +1,5 @@
## ======================================================================== ##
## Copyright 2017 Kitware, Inc. ##
## Copyright 2009-2016 Intel Corporation ##
## ##
## Licensed under the Apache License, Version 2.0 (the "License"); ##
## you may not use this file except in compliance with the License. ##
@@ -14,9 +14,9 @@
## limitations under the License. ##
## ======================================================================== ##
SET(FLAGS_SSE2 "-target-cpu=xeon")
SET(FLAGS_SSE42 "-target-cpu=interlagos")
SET(FLAGS_AVX "-target-cpu=sandybridge")
SET(FLAGS_AVX2 "-target-cpu=haswell")
SET(FLAGS_AVX512KNL "-target-cpu=mic-knl")
SET(FLAGS_AVX512SKX "-target-cpu=x86-skylake")
SET(EMBREE_INCLUDE_DIRS ${CMAKE_CURRENT_LIST_DIR}/../../../@CMAKE_INSTALL_INCLUDEDIR@)
SET(EMBREE_LIBRARY ${CMAKE_CURRENT_LIST_DIR}/../../libembree.@EMBREE_CONFIG_VERSION@.dylib)
MARK_AS_ADVANCED(embree_DIR)
INCLUDE(${CMAKE_CURRENT_LIST_DIR}/embree-config-default.cmake)
+1 -1
View File
@@ -1,5 +1,5 @@
## ======================================================================== ##
## Copyright 2009-2017 Intel Corporation ##
## Copyright 2009-2016 Intel Corporation ##
## ##
## Licensed under the Apache License, Version 2.0 (the "License"); ##
## you may not use this file except in compliance with the License. ##
@@ -1,5 +1,5 @@
## ======================================================================== ##
## Copyright 2009-2017 Intel Corporation ##
## Copyright 2009-2016 Intel Corporation ##
## ##
## Licensed under the Apache License, Version 2.0 (the "License"); ##
## you may not use this file except in compliance with the License. ##
@@ -14,7 +14,9 @@
## limitations under the License. ##
## ======================================================================== ##
INCLUDE(tutorial)
ADD_TUTORIAL(viewer_anim)
SET(EMBREE_INCLUDE_DIRS ${CMAKE_CURRENT_LIST_DIR}/../../../@CMAKE_INSTALL_INCLUDEDIR@)
SET(EMBREE_LIBRARY ${CMAKE_CURRENT_LIST_DIR}/../../embree.lib)
MARK_AS_ADVANCED(embree_DIR)
INCLUDE(${CMAKE_CURRENT_LIST_DIR}/embree-config-default.cmake)
+14 -54
View File
@@ -1,5 +1,5 @@
## ======================================================================== ##
## Copyright 2009-2017 Intel Corporation ##
## Copyright 2009-2016 Intel Corporation ##
## ##
## Licensed under the Apache License, Version 2.0 (the "License"); ##
## you may not use this file except in compliance with the License. ##
@@ -15,63 +15,23 @@
## ======================================================================== ##
SET(FLAGS_SSE2 "-msse2")
SET(FLAGS_SSE3 "-msse3")
SET(FLAGS_SSSE3 "-mssse3")
SET(FLAGS_SSE41 "-msse4.1")
SET(FLAGS_SSE42 "-msse4.2")
SET(FLAGS_AVX "-mavx")
SET(FLAGS_AVX2 "-mf16c -mavx2 -mfma -mlzcnt -mbmi -mbmi2")
SET(FLAGS_AVX512KNL "-mavx512f -mavx512pf -mavx512er -mavx512cd -mf16c -mavx2 -mfma -mlzcnt -mbmi -mbmi2")
SET(FLAGS_AVX512SKX "-mavx512f -mavx512dq -mavx512cd -mavx512bw -mavx512vl -mf16c -mavx2 -mfma -mlzcnt -mbmi -mbmi2")
SET(FLAGS_AVX512KNL "-mavx512f -mavx512pf -mavx512er -mavx512cd")
SET(FLAGS_AVX512SKX "-mavx512f -mavx512dq -mavx512cd -mavx512bw -mavx512vl")
OPTION(EMBREE_IGNORE_CMAKE_CXX_FLAGS "When enabled Embree ignores default CMAKE_CXX_FLAGS." ON)
IF (EMBREE_IGNORE_CMAKE_CXX_FLAGS)
SET(CMAKE_CXX_FLAGS "")
ENDIF()
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") # enables most warnings
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wformat -Wformat-security") # enables string format vulnerability warnings
IF (NOT APPLE)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIE") # enables support for more secure position independent execution
ENDIF()
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") # generate position independent code suitable for shared libraries
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") # enables C++11 features
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden") # makes all symbols hidden by default
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden") # makes all inline symbols hidden by default
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-strict-aliasing") # disables strict aliasing rules
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_FORTIFY_SOURCE=2") # perform extra security checks for some standard library calls
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-tree-vectorize") # disable auto vectorizer
IF (EMBREE_STACK_PROTECTOR)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstack-protector") # protects against return address overrides
ENDIF()
MACRO(DISABLE_STACK_PROTECTOR_FOR_FILE file)
IF (EMBREE_STACK_PROTECTOR)
SET_SOURCE_FILES_PROPERTIES(${file} PROPERTIES COMPILE_FLAGS "-fno-stack-protector")
ENDIF()
ENDMACRO()
SET(CMAKE_CXX_FLAGS_DEBUG "")
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG") # enable assertions
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DTBB_USE_DEBUG") # configure TBB in debug mode
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g") # generate debug information
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0") # disable optimizations
SET(CMAKE_CXX_FLAGS_RELEASE "")
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DNDEBUG") # disable assertions
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3") # enable full optimizations
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "")
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DDEBUG") # enable assertions
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DTBB_USE_DEBUG") # configure TBB in debug mode
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -g") # generate debug information
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -O3") # enable full optimizations
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fPIC -std=c++11 -fvisibility-inlines-hidden -fvisibility=hidden -fno-strict-aliasing")
SET(CMAKE_CXX_FLAGS_DEBUG "-DDEBUG -DTBB_USE_DEBUG -g -O0")
SET(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG -O3")
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-DDEBUG -DTBB_USE_DEBUG -g -O3")
SET(CMAKE_EXE_LINKER_FLAGS "")
IF (APPLE)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=10.7") # makes sure code runs on older MacOSX versions
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") # link against libc++ which supports C++11 features
ELSE(APPLE)
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined") # issues link error for undefined symbols in shared library
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -z noexecstack") # we do not need an executable stack
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -z relro -z now") # re-arranges data sections to increase security
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -z noexecstack") # we do not need an executable stack
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -z relro -z now") # re-arranges data sections to increase security
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pie") # enables position independent execution for executable
ENDIF(APPLE)
SET (CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS_INIT} -dynamiclib)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=10.7 -stdlib=libc++")
ENDIF (APPLE)
+22 -142
View File
@@ -1,5 +1,5 @@
## ======================================================================== ##
## Copyright 2009-2017 Intel Corporation ##
## Copyright 2009-2016 Intel Corporation ##
## ##
## Licensed under the Apache License, Version 2.0 (the "License"); ##
## you may not use this file except in compliance with the License. ##
@@ -14,150 +14,30 @@
## limitations under the License. ##
## ======================================================================== ##
IF (WIN32)
SET(FLAGS_SSE2 "-xsse2")
SET(FLAGS_SSE3 "-xsse3")
SET(FLAGS_SSSE3 "-xssse3")
SET(FLAGS_SSE41 "-xsse4.1")
SET(FLAGS_SSE42 "-xsse4.2")
SET(FLAGS_AVX "-xAVX")
SET(FLAGS_AVX2 "-xCORE-AVX2")
SET(FLAGS_AVX512KNL "-xMIC-AVX512")
SET(FLAGS_AVX512SKX "-xCORE-AVX512")
SET(FLAGS_SSE2 "/QxSSE2")
SET(FLAGS_SSE42 "/QxSSE4.2")
SET(FLAGS_AVX "/arch:AVX")
SET(FLAGS_AVX2 "/QxCORE-AVX2")
SET(FLAGS_AVX512KNL "/QxMIC-AVX512")
SET(FLAGS_AVX512SKX "/QxCORE-AVX512")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fPIC -std=c++11 -fvisibility-inlines-hidden -fvisibility=hidden -no-ansi-alias -fasm-blocks")
SET(COMMON_CXX_FLAGS "")
SET(COMMON_CXX_FLAGS "${COMMON_CXX_FLAGS} /EHsc") # catch C++ exceptions only and extern "C" functions never throw a C++ exception
SET(COMMON_CXX_FLAGS "${COMMON_CXX_FLAGS} /MP") # compile source files in parallel
SET(COMMON_CXX_FLAGS "${COMMON_CXX_FLAGS} /GR") # enable runtime type information (on by default)
SET(COMMON_CXX_FLAGS "${COMMON_CXX_FLAGS} /Qvec-") # disable auto vectorizer
IF (EMBREE_STACK_PROTECTOR)
SET(COMMON_CXX_FLAGS "${COMMON_CXX_FLAGS} /GS") # protects against return address overrides
ELSE()
SET(COMMON_CXX_FLAGS "${COMMON_CXX_FLAGS} /GS-") # do not protect against return address overrides
ENDIF()
MACRO(DISABLE_STACK_PROTECTOR_FOR_FILE file)
IF (EMBREE_STACK_PROTECTOR)
SET_SOURCE_FILES_PROPERTIES(${file} PROPERTIES COMPILE_FLAGS "/GS-")
ENDIF()
ENDMACRO()
SET(CMAKE_CXX_FLAGS_DEBUG "-DDEBUG -DTBB_USE_DEBUG -g -O0")
SET(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG -O3 -restrict -no-inline-max-total-size -inline-factor=200")
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-DDEBUG -DTBB_USE_DEBUG -g -O3 -restrict -no-inline-max-total-size -inline-factor=200")
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
# enable -static-intel and avoid to export ICC specific symbols from Embree
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-intel -no-intel-extensions")
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${COMMON_CXX_FLAGS}")
SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /DEBUG") # generate debug information
SET(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} /DEBUG") # generate debug information
#SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -g -debug inline-debug-info")
#SET(CMAKE_EXE_LINKER_FLAGS "-g")
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${COMMON_CXX_FLAGS}")
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Ox") # enable full optimizations
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Oi") # inline intrinsic functions
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Gy") # package individual functions
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Qinline-max-total-size-") # no size limit when performing inlining
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Qinline-factor=150") # increase default inline factors by 2x
IF (APPLE)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=10.7 ") # we only use MacOSX 10.7 features
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++" ) # link against C++11 stdlib
ENDIF (APPLE)
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${COMMON_CXX_FLAGS}")
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Ox") # enable full optimizations
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Oi") # inline intrinsic functions
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Gy") # package individual functions
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Qinline-max-total-size-") # no size limit when performing inlining
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Qinline-factor=150") # increase default inline factors by 2x
SET(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} /DEBUG") # generate debug information
SET(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO} /DEBUG") # generate debug information
SET(SECURE_LINKER_FLAGS "")
SET(SECURE_LINKER_FLAGS "${SECURE_LINKER_FLAGS} /NXCompat") # compatible with data execution prevention (on by default)
SET(SECURE_LINKER_FLAGS "${SECURE_LINKER_FLAGS} /DynamicBase") # random rebase of executable at load time
IF (CMAKE_SIZEOF_VOID_P EQUAL 4)
SET(SECURE_LINKER_FLAGS "${SECURE_LINKER_FLAGS} /SafeSEH") # invoke known exception handlers (Win32 only, x64 exception handlers are safe by design)
ENDIF()
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${SECURE_LINKER_FLAGS}")
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${SECURE_LINKER_FLAGS}")
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /IGNORE:4217") # locally defined symbol XXX imported in function YYY (happens as the ISPC API layer uses exported library functions)
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /IGNORE:4049") # warning LNK4049: locally defined symbol _rtcOccluded1M imported
INCLUDE(msvc_post)
ELSE()
IF (APPLE)
SET(FLAGS_SSE2 "-xssse3") # on MacOSX ICC does not support SSE2
ELSE()
SET(FLAGS_SSE2 "-xsse2")
ENDIF()
SET(FLAGS_SSE42 "-xsse4.2")
SET(FLAGS_AVX "-xAVX")
SET(FLAGS_AVX2 "-xCORE-AVX2")
SET(FLAGS_AVX512KNL "-xMIC-AVX512")
SET(FLAGS_AVX512SKX "-xCORE-AVX512")
OPTION(EMBREE_IGNORE_CMAKE_CXX_FLAGS "When enabled Embree ignores default CMAKE_CXX_FLAGS." ON)
IF (EMBREE_IGNORE_CMAKE_CXX_FLAGS)
SET(CMAKE_CXX_FLAGS "")
ENDIF()
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") # enables most warnings
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wformat -Wformat-security") # enables string format vulnerability warnings
IF (NOT APPLE)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIE") # enables support for more secure position independent execution
ENDIF()
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") # generate position independent code suitable for shared libraries
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") # enables C++11 features
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden") # makes all symbols hidden by default
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden") # makes all inline symbols hidden by default
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -no-ansi-alias") # disables strict aliasing rules
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_FORTIFY_SOURCE=2") # perform extra security checks for some standard library calls
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -no-vec") # disable auto vectorizer
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fasm-blocks") # enable assembly blocks
IF (EMBREE_STACK_PROTECTOR)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstack-protector") # protects against return address overrides
ENDIF()
MACRO(DISABLE_STACK_PROTECTOR_FOR_FILE file)
IF (EMBREE_STACK_PROTECTOR)
SET_SOURCE_FILES_PROPERTIES(${file} PROPERTIES COMPILE_FLAGS "-fno-stack-protector")
ENDIF()
ENDMACRO()
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
ENDIF()
SET(CMAKE_CXX_FLAGS_DEBUG "")
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG") # enables assertions
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DTBB_USE_DEBUG") # configures TBB in debug mode
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g") # generate debug information
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0") # disable all optimizations
SET(CMAKE_CXX_FLAGS_RELEASE "")
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DNDEBUG") # disable assertions
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3") # full optimizations
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -restrict") # enable restrict keyword
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -no-inline-max-total-size") # no size limit when performing inlining
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -no-inline-max-per-compile") # no maximal number of inlinings per compilation unit
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -inline-factor=150") # increase default inline factors limits by 2x
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "")
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DDEBUG") # enables assertions
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DTBB_USE_DEBUG") # configures TBB in debug mode
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -g") # generate debug information
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -O3") # full optimizations
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -restrict") # enable restrict keyword
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -no-inline-max-total-size") # no size limit when performing inlining
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -no-inline-max-per-compile") # no maximal number of inlinings per compilation unit
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -inline-factor=150") # increase default inline factors by 2x
#SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -g -debug inline-debug-info")
#SET(CMAKE_EXE_LINKER_FLAGS "-g")
IF (APPLE)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=10.7") # makes sure code runs on older MacOSX versions
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") # link against libc++ which supports C++11 features
ELSE(APPLE)
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined") # issues link error for undefined symbols in shared library
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -z noexecstack") # we do not need an executable stack
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -z relro -z now") # re-arranges data sections to increase security
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -z noexecstack") # we do not need an executable stack
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -z relro -z now") # re-arranges data sections to increase security
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pie") # enables position independent execution for executable
ENDIF(APPLE)
ENDIF()
+1 -2
View File
@@ -1,5 +1,5 @@
## ======================================================================== ##
## Copyright 2009-2017 Intel Corporation ##
## Copyright 2009-2016 Intel Corporation ##
## ##
## Licensed under the Apache License, Version 2.0 (the "License"); ##
## you may not use this file except in compliance with the License. ##
@@ -146,7 +146,6 @@ MACRO (ISPC_COMPILE)
COMMAND ${EMBREE_ISPC_EXECUTABLE}
-I ${CMAKE_CURRENT_SOURCE_DIR}
${ISPC_INCLUDE_DIR_PARMS}
${ISPC_DEFINITIONS}
--arch=${ISPC_ARCHITECTURE}
--addressing=${EMBREE_ISPC_ADDRESSING}
${ISPC_OPT_FLAGS}
+37 -42
View File
@@ -1,5 +1,5 @@
## ======================================================================== ##
## Copyright 2009-2017 Intel Corporation ##
## Copyright 2009-2016 Intel Corporation ##
## ##
## Licensed under the Apache License, Version 2.0 (the "License"); ##
## you may not use this file except in compliance with the License. ##
@@ -14,54 +14,49 @@
## limitations under the License. ##
## ======================================================================== ##
SET(FLAGS_SSE2 "/D__SSE__ /D__SSE2__")
SET(FLAGS_SSE42 "${FLAGS_SSE2} /D__SSE3__ /D__SSSE3__ /D__SSE4_1__ /D__SSE4_2__")
SET(FLAGS_AVX "${FLAGS_SSE42} /arch:AVX")
SET(FLAGS_AVX2 "${FLAGS_SSE42} /arch:AVX2")
# the /QxXXX flags are meant for the Intel Compiler, MSVC ignores them
SET(FLAGS_SSE2 "/QxSSE2")
SET(FLAGS_SSE3 "/QxSSE3")
SET(FLAGS_SSSE3 "/QxSSSE3")
SET(FLAGS_SSE41 "/DCONFIG_SSE41 /QxSSE4.1")
SET(FLAGS_SSE42 "/DCONFIG_SSE42 /QxSSE4.2")
SET(FLAGS_AVX "/arch:AVX /DCONFIG_AVX")
SET(COMMON_CXX_FLAGS "")
SET(COMMON_CXX_FLAGS "${COMMON_CXX_FLAGS} /EHsc") # catch C++ exceptions only and extern "C" functions never throw a C++ exception
SET(COMMON_CXX_FLAGS "${COMMON_CXX_FLAGS} /MP") # compile source files in parallel
SET(COMMON_CXX_FLAGS "${COMMON_CXX_FLAGS} /GR") # enable runtime type information (on by default)
IF (EMBREE_STACK_PROTECTOR)
SET(COMMON_CXX_FLAGS "${COMMON_CXX_FLAGS} /GS") # protects against return address overrides
# Intel Compiler 15, Update 1 unfortunately cannot handle /arch:AVX2
IF (${CMAKE_CXX_COMPILER_ID} STREQUAL "Intel")
SET(FLAGS_AVX2 "/DCONFIG_AVX2 /QxCORE-AVX2")
ELSE()
SET(COMMON_CXX_FLAGS "${COMMON_CXX_FLAGS} /GS-") # do not protect against return address overrides
SET(FLAGS_AVX2 "/arch:AVX2 /DCONFIG_AVX2 /QxCORE-AVX2")
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(FLAGS_AVX512KNL "")
SET(FLAGS_AVX512SKX "")
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${COMMON_CXX_FLAGS}")
SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /DEBUG") # generate debug information
SET(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} /DEBUG") # generate debug information
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${COMMON_CXX_FLAGS}")
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Ox") # enable full optimizations
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Oi") # inline intrinsic functions
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Gy") # package individual functions
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${COMMON_CXX_FLAGS}")
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Ox") # enable full optimizations
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Oi") # inline intrinsic functions
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Gy") # package individual functions
SET(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} /DEBUG") # generate debug information
SET(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO} /DEBUG") # generate debug information
SET(SECURE_LINKER_FLAGS "")
SET(SECURE_LINKER_FLAGS "${SECURE_LINKER_FLAGS} /NXCompat") # compatible with data execution prevention (on by default)
SET(SECURE_LINKER_FLAGS "${SECURE_LINKER_FLAGS} /DynamicBase") # random rebase of executable at load time
IF (CMAKE_SIZEOF_VOID_P EQUAL 4)
SET(SECURE_LINKER_FLAGS "${SECURE_LINKER_FLAGS} /SafeSEH") # invoke known exception handlers (Win32 only, x64 exception handlers are safe by design)
SET(COMMON_CXX_FLAGS "/EHsc /MP /GR /GS-")
IF (${CMAKE_CXX_COMPILER_ID} STREQUAL "Intel")
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
ENDIF()
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${SECURE_LINKER_FLAGS}")
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${SECURE_LINKER_FLAGS}")
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${COMMON_CXX_FLAGS}")
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${COMMON_CXX_FLAGS} /Ox /fp:fast /Oi /Gy /Qinline-max-total-size- /Qinline-factor=200 ")
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${COMMON_CXX_FLAGS} /Ox /fp:fast /Oi /Gy /Qinline-max-total-size- /Qinline-factor=200 ")
SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /DEBUG")
IF (${CMAKE_CXX_COMPILER_ID} STREQUAL "Intel")
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /Qdiag-disable:11082 ") # warning #11082: locally defined symbol XXX imported
ENDIF()
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /IGNORE:4217") # locally defined symbol XXX imported in function YYY (happens as the ISPC API layer uses exported library functions)
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /IGNORE:4049") # warning LNK4049: locally defined symbol _rtcOccluded1M imported
SET(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} /DEBUG")
INCLUDE(msvc_post)
# optionally use static runtime library
OPTION(EMBREE_STATIC_RUNTIME "Use the static version of the C/C++ runtime library." ON)
IF (EMBREE_STATIC_RUNTIME)
STRING(REPLACE "/MDd" "/MTd" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG})
STRING(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_RELWITHDEBINFO ${CMAKE_CXX_FLAGS_RELWITHDEBINFO})
STRING(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE})
ENDIF()
# remove define NDEBUG and instead set define DEBUG for config RelWithDebInfo
STRING(REPLACE "NDEBUG" "DEBUG" CMAKE_CXX_FLAGS_RELWITHDEBINFO ${CMAKE_CXX_FLAGS_RELWITHDEBINFO})
-26
View File
@@ -1,26 +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. ##
## ======================================================================== ##
# optionally use static runtime library
OPTION(EMBREE_STATIC_RUNTIME "Use the static version of the C/C++ runtime library." ON)
IF (EMBREE_STATIC_RUNTIME)
STRING(REPLACE "/MDd" "/MTd" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG})
STRING(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_RELWITHDEBINFO ${CMAKE_CXX_FLAGS_RELWITHDEBINFO})
STRING(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE})
ENDIF()
# remove define NDEBUG and instead set define DEBUG for config RelWithDebInfo
STRING(REPLACE "NDEBUG" "DEBUG" CMAKE_CXX_FLAGS_RELWITHDEBINFO ${CMAKE_CXX_FLAGS_RELWITHDEBINFO})
+39 -61
View File
@@ -1,5 +1,5 @@
## ======================================================================== ##
## Copyright 2009-2017 Intel Corporation ##
## Copyright 2009-2016 Intel Corporation ##
## ##
## Licensed under the Apache License, Version 2.0 (the "License"); ##
## you may not use this file except in compliance with the License. ##
@@ -25,21 +25,20 @@ IF (NOT EMBREE_ZIP_MODE AND NOT WIN32 AND NOT APPLE)
SET(CMAKE_INSTALL_FULL_BINDIR ${CMAKE_INSTALL_FULL_BINDIR}/embree${EMBREE_VERSION_MAJOR})
ENDIF()
# use full absolute path as install name
# use full absolute path as install name for PKG installer under MacOSX
IF (NOT EMBREE_ZIP_MODE)
SET(CMAKE_INSTALL_NAME_DIR ${CMAKE_INSTALL_FULL_LIBDIR})
ELSE()
IF(APPLE)
SET(CMAKE_INSTALL_RPATH "@loader_path/../lib")
ELSE()
SET(CMAKE_INSTALL_RPATH "$ORIGIN/../lib")
ENDIF()
ENDIF()
##############################################################
# Install Headers
##############################################################
INSTALL(DIRECTORY include/embree2 DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} COMPONENT devel)
CONFIGURE_FILE(include/embree2/rtcore.h rtcore.h @ONLY)
CONFIGURE_FILE(include/embree2/rtcore.isph rtcore.isph @ONLY)
INSTALL(FILES ${PROJECT_BINARY_DIR}/rtcore.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/embree2 COMPONENT devel)
INSTALL(FILES ${PROJECT_BINARY_DIR}/rtcore.isph DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/embree2 COMPONENT devel)
##############################################################
# Install Models
@@ -94,43 +93,29 @@ IF (APPLE AND NOT EMBREE_ZIP_MODE)
INSTALL(PROGRAMS "${PROJECT_BINARY_DIR}/uninstall.command" DESTINATION ${CMAKE_INSTALL_BINDIR}/.. COMPONENT lib)
ENDIF()
# why does this have to be so complicated...
IF (WIN32)
SET(EMBREE_LIBRARY_NAME ${CMAKE_IMPORT_LIBRARY_PREFIX}embree${CMAKE_IMPORT_LIBRARY_SUFFIX})
CONFIGURE_FILE(common/cmake/embree-config-windows.cmake embree-config.cmake @ONLY)
ELSEIF (APPLE)
SET(EMBREE_LIBRARY_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}embree.${EMBREE_CONFIG_VERSION}${CMAKE_SHARED_LIBRARY_SUFFIX})
CONFIGURE_FILE(common/cmake/embree-config-macosx.cmake embree-config.cmake @ONLY)
ELSE()
SET(EMBREE_LIBRARY_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}embree${CMAKE_SHARED_LIBRARY_SUFFIX}.${EMBREE_CONFIG_VERSION})
CONFIGURE_FILE(common/cmake/embree-config-linux.cmake embree-config.cmake @ONLY)
ENDIF()
IF (WIN32 OR EMBREE_ZIP_MODE)
# for local "installs" and on Windows we want the cmake config files placed
# in the install root, such that users can point the CMake variable
# embree_DIR just to the install folder
SET(EMBREE_CMAKECONFIG_DIR ".")
SET(EMBREE_RELATIV_ROOT_DIR ".")
ELSE()
SET(EMBREE_CMAKECONFIG_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/embree-${EMBREE_VERSION}")
SET(EMBREE_RELATIV_ROOT_DIR "../../..")
ENDIF()
CONFIGURE_FILE(common/cmake/embree-config.cmake embree-config-install.cmake @ONLY)
CONFIGURE_FILE(common/cmake/embree-config-default.cmake embree-config-default.cmake @ONLY)
CONFIGURE_FILE(common/cmake/embree-config-version.cmake embree-config-version.cmake @ONLY)
# create a config file for the build directory
CONFIGURE_FILE(common/cmake/embree-config-builddir.cmake embree-config.cmake @ONLY)
INSTALL(FILES "${PROJECT_BINARY_DIR}/embree-config-install.cmake" DESTINATION ${EMBREE_CMAKECONFIG_DIR} RENAME "embree-config.cmake" COMPONENT devel)
INSTALL(FILES "${PROJECT_BINARY_DIR}/embree-config-version.cmake" DESTINATION ${EMBREE_CMAKECONFIG_DIR} COMPONENT devel)
INSTALL(FILES "${PROJECT_BINARY_DIR}/embree-config.cmake" DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/embree-${EMBREE_VERSION}" COMPONENT devel)
INSTALL(FILES "${PROJECT_BINARY_DIR}/embree-config-default.cmake" DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/embree-${EMBREE_VERSION}" COMPONENT devel)
INSTALL(FILES "${PROJECT_BINARY_DIR}/embree-config-version.cmake" DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/embree-${EMBREE_VERSION}" COMPONENT devel)
##############################################################
# 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)
SET(CPACK_STRIP_FILES TRUE) # do not disable, stripping symbols is important for security reasons
SET(CMAKE_STRIP "${PROJECT_SOURCE_DIR}/scripts/strip.sh") # needs this to properly strip under MacOSX
#SET(CPACK_STRIP_FILES TRUE) # keep symbols, useful for bug reports
SET(CPACK_PACKAGE_VERSION_MAJOR ${EMBREE_VERSION_MAJOR})
SET(CPACK_PACKAGE_VERSION_MINOR ${EMBREE_VERSION_MINOR})
@@ -162,29 +147,37 @@ 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_WIX_CMAKE_PACKAGE_REGISTRY TRUE)
IF (EMBREE_TESTING_PACKAGE)
ADD_TEST(NAME "BuildPackage" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMAND ${PROJECT_SOURCE_DIR}/scripts/package_win.bat ${CPACK_PACKAGE_FILE_NAME}.exe ${CMAKE_BUILD_TYPE})
ENDIF()
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")
ELSE()
SET(CPACK_GENERATOR ZIP)
SET(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}.${ARCH}.windows")
SET(CPACK_MONOLITHIC_INSTALL 1)
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}.zip ${CMAKE_BUILD_TYPE})
ENDIF()
ENDIF()
# MacOSX specific settings
@@ -202,51 +195,36 @@ ELSEIF(APPLE)
SET(CPACK_PACKAGE_NAME embree-${EMBREE_VERSION})
SET(CPACK_PACKAGE_VENDOR "intel") # creates short name com.intel.embree2.xxx in pkgutil
SET(CPACK_OSX_PACKAGE_VERSION 10.7)
IF (EMBREE_TESTING_PACKAGE)
ADD_TEST(NAME "BuildPackage" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMAND ${PROJECT_SOURCE_DIR}/scripts/package_macosx.sh ${CMAKE_BUILD_TYPE} ${CPACK_PACKAGE_FILE_NAME}.dmg)
ENDIF()
ELSE()
SET(CPACK_GENERATOR TGZ)
SET(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}.x86_64.macosx")
SET(CPACK_MONOLITHIC_INSTALL 1)
IF (EMBREE_TESTING_PACKAGE)
ADD_TEST(NAME "BuildPackage" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMAND ${PROJECT_SOURCE_DIR}/scripts/package_macosx.sh ${CMAKE_BUILD_TYPE} ${CPACK_PACKAGE_FILE_NAME}.tgz)
ENDIF()
ENDIF()
# Linux specific settings
ELSE()
IF (NOT EMBREE_ZIP_MODE)
SET(CPACK_GENERATOR RPM)
SET(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}-${CPACK_RPM_PACKAGE_RELEASE}.x86_64")
SET(CPACK_COMPONENTS_ALL devel lib examples)
SET(CPACK_RPM_COMPONENT_INSTALL ON)
SET(CPACK_RPM_FILE_NAME RPM-DEFAULT)
SET(CPACK_RPM_devel_PACKAGE_ARCHITECTURE noarch)
SET(CPACK_RPM_PACKAGE_LICENSE "ASL 2.0") # Apache Software License, Version 2.0
SET(CPACK_RPM_PACKAGE_GROUP "Development/Libraries")
SET(CPACK_RPM_CHANGELOG_FILE ${CMAKE_BINARY_DIR}/rpm_changelog.txt) # ChangeLog of the RPM
STRING(TIMESTAMP CHANGELOG_DATE "%a %b %d %Y")
SET(RPM_CHANGELOG "* ${CHANGELOG_DATE} Johannes Günther <johannes.guenther@intel.com> - ${EMBREE_VERSION}-${CPACK_RPM_PACKAGE_RELEASE}\n- First package")
FILE(WRITE ${CPACK_RPM_CHANGELOG_FILE} ${RPM_CHANGELOG})
#SET(CPACK_RPM_CHANGELOG_FILE "") # ChangeLog of the RPM; also CHANGELOG.md is not in the required format
SET(CPACK_RPM_PACKAGE_ARCHITECTURE x86_64)
SET(CPACK_RPM_PACKAGE_URL http://embree.github.io/)
SET(CPACK_RPM_DEFAULT_DIR_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) # otherwise cmake directory has wrong 775 permissions
# post install and uninstall scripts
SET(CPACK_RPM_lib_POST_INSTALL_SCRIPT_FILE ${PROJECT_SOURCE_DIR}/common/cmake/rpm_ldconfig.sh)
SET(CPACK_RPM_lib_POST_UNINSTALL_SCRIPT_FILE ${PROJECT_SOURCE_DIR}/common/cmake/rpm_ldconfig.sh)
IF (EMBREE_TESTING_PACKAGE)
ADD_TEST(NAME "BuildPackage" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMAND ${PROJECT_SOURCE_DIR}/scripts/package_linux.sh ${EMBREE_ZIP_MODE} ${EMBREE_VERSION})
ENDIF()
ELSE()
SET(CPACK_GENERATOR TGZ)
SET(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}.x86_64.linux")
SET(CPACK_MONOLITHIC_INSTALL 1)
IF (EMBREE_TESTING_PACKAGE)
ADD_TEST(NAME "BuildPackage" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMAND ${PROJECT_SOURCE_DIR}/scripts/package_linux.sh ${EMBREE_ZIP_MODE} ${EMBREE_VERSION})
ENDIF()
ENDIF()
ENDIF()
+2 -14
View File
@@ -1,5 +1,5 @@
## ======================================================================== ##
## Copyright 2009-2017 Intel Corporation ##
## Copyright 2009-2016 Intel Corporation ##
## ##
## Licensed under the Apache License, Version 2.0 (the "License"); ##
## you may not use this file except in compliance with the License. ##
@@ -24,16 +24,11 @@ IF (BUILD_TESTING)
CMAKE_HOST_SYSTEM_INFORMATION(RESULT memory QUERY TOTAL_PHYSICAL_MEMORY)
SET(EMBREE_TESTING_MODEL_DIR "${PROJECT_SOURCE_DIR}/models" CACHE PATH "Path to the folder containing the Embree models for regression testing.")
SET(EMBREE_TESTING_MODEL_DIR "${PROJECT_SOURCE_DIR}/models" CACHE FILEPATH "Path to the folder containing the Embree models for regression testing.")
SET(EMBREE_TESTING_INTENSIVE OFF CACHE BOOL "Turns intensive testing on.")
SET(EMBREE_TESTING_MEMCHECK OFF CACHE BOOL "Turns on memory checking for some tests.")
SET(EMBREE_TESTING_BENCHMARK OFF CACHE BOOL "Turns benchmarking on.")
SET(EMBREE_TESTING_BENCHMARK_DATABASE "${PROJECT_BINARY_DIR}" CACHE PATH "Path to database for benchmarking.")
SET(EMBREE_TESTING_PACKAGE OFF CACHE BOOL "Packages release as test.")
SET(EMBREE_TESTING_KLOCWORK OFF CACHE BOOL "Runs Kocwork as test.")
SET(EMBREE_TESTING_SDE OFF CACHE STRING "Uses SDE to run tests for specified CPU.")
SET_PROPERTY(CACHE EMBREE_TESTING_SDE PROPERTY STRINGS OFF pnr nhm wsm snb ivb hsw bdw knl skl skx cnl)
IF( NOT EXISTS "${EMBREE_TESTING_MODEL_DIR}/embree-models-subdiv.txt"
OR NOT EXISTS "${EMBREE_TESTING_MODEL_DIR}/embree-models-small-win32.txt"
@@ -78,7 +73,6 @@ IF (BUILD_TESTING)
--modeldir ${EMBREE_TESTING_MODEL_DIR}
--reference ${reference}
--model ${model}
--sde ${EMBREE_TESTING_SDE}
--execute ${MY_PROJECT_BINARY_DIR}/${executable} ${args})
IF (EMBREE_ISPC_SUPPORT AND EMBREE_RAY_PACKETS)
@@ -89,7 +83,6 @@ IF (BUILD_TESTING)
--modeldir ${EMBREE_TESTING_MODEL_DIR}
--reference ${reference}
--model ${model}
--sde ${EMBREE_TESTING_SDE}
--execute ${MY_PROJECT_BINARY_DIR}/${executable}_ispc ${args})
ENDIF()
ENDMACRO()
@@ -110,11 +103,6 @@ IF (BUILD_TESTING)
ENDFOREACH()
ENDMACRO()
IF (EMBREE_TESTING_KLOCWORK)
ADD_TEST(NAME Klocwork WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMAND ${PROJECT_SOURCE_DIR}/scripts/klocwork.sh)
SET_TESTS_PROPERTIES(Klocwork PROPERTIES TIMEOUT 2400)
ENDIF()
ELSE()
MACRO (ADD_EMBREE_MODEL_TEST name reference executable args model)
+1 -1
View File
@@ -1,5 +1,5 @@
## ======================================================================== ##
## Copyright 2009-2017 Intel Corporation ##
## Copyright 2009-2016 Intel Corporation ##
## ##
## Licensed under the Apache License, Version 2.0 (the "License"); ##
## you may not use this file except in compliance with the License. ##
+3 -2
View File
@@ -1,5 +1,5 @@
## ======================================================================== ##
## Copyright 2009-2017 Intel Corporation ##
## Copyright 2009-2016 Intel Corporation ##
## ##
## Licensed under the Apache License, Version 2.0 (the "License"); ##
## you may not use this file except in compliance with the License. ##
@@ -18,5 +18,6 @@ ADD_LIBRARY(lexers STATIC
stringstream.cpp
tokenstream.cpp
)
TARGET_LINK_LIBRARIES(lexers sys math)
TARGET_LINK_LIBRARIES(lexers sys)
SET_PROPERTY(TARGET lexers PROPERTY FOLDER common)
+1 -1
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
+43 -40
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
@@ -28,25 +28,31 @@
namespace embree
{
class String : public RefCount {
public:
String(std::string str) : str(str) {}
std::string str;
};
/*! stores the location of a stream element in the source */
class ParseLocation
{
public:
ParseLocation () : lineNumber(-1), colNumber(-1), charNumber(-1) {}
ParseLocation (std::shared_ptr<std::string> fileName, ssize_t lineNumber, ssize_t colNumber, ssize_t charNumber)
ParseLocation () : fileName(nullptr), lineNumber(-1), colNumber(-1), charNumber(-1) {}
ParseLocation (Ref<String> fileName, ssize_t lineNumber, ssize_t colNumber, ssize_t charNumber)
: fileName(fileName), lineNumber(lineNumber), colNumber(colNumber), charNumber(charNumber) {}
std::string str() const
{
std::string str = "unknown";
if (fileName) str = *fileName;
if (fileName) str = fileName->str;
if (lineNumber >= 0) str += " line " + toString(lineNumber);
if (lineNumber >= 0 && colNumber >= 0) str += " character " + toString(colNumber);
return str;
}
private:
std::shared_ptr<std::string> fileName; /// name of the file (or stream) the token is from
Ref<String> fileName; /// name of the file (or stream) the token is from
ssize_t lineNumber; /// the line number the token is from
ssize_t colNumber; /// the character number in the current line
ssize_t charNumber; /// the character in the file
@@ -56,33 +62,33 @@ namespace embree
template<typename T> class Stream : public RefCount
{
enum { BUF_SIZE = 1024 };
private:
virtual T next() = 0;
virtual ParseLocation location() = 0;
__forceinline std::pair<T,ParseLocation> nextHelper() {
ParseLocation l = location();
T v = next();
return std::pair<T,ParseLocation>(v,l);
}
__forceinline void push_back(const std::pair<T,ParseLocation>& v) {
if (past+future == BUF_SIZE) pop_front();
size_t end = (start+past+future++)%BUF_SIZE;
buffer[end] = v;
}
__forceinline void pop_front() {
if (past == 0) THROW_RUNTIME_ERROR("stream buffer empty");
start = (start+1)%BUF_SIZE; past--;
}
__forceinline std::pair<T,ParseLocation> nextHelper() {
ParseLocation l = location();
T v = next();
return std::pair<T,ParseLocation>(v,l);
}
__forceinline void push_back(const std::pair<T,ParseLocation>& v) {
if (past+future == BUF_SIZE) pop_front();
int end = (start+past+future++)%BUF_SIZE;
buffer[end] = v;
}
__forceinline void pop_front() {
if (past == 0) THROW_RUNTIME_ERROR("stream buffer empty");
start = (start+1)%BUF_SIZE; past--;
}
public:
Stream () : start(0), past(0), future(0), buffer(BUF_SIZE) {}
virtual ~Stream() {}
Stream () : start(0), past(0), future(0), buffer(BUF_SIZE) {}
virtual ~Stream() {}
public:
const ParseLocation& loc() {
if (future == 0) push_back(nextHelper());
return buffer[(start+past)%BUF_SIZE].second;
const ParseLocation& loc() {
if (future == 0) push_back(nextHelper());
return buffer[(start+past)%BUF_SIZE].second;
}
T get() {
if (future == 0) push_back(nextHelper());
@@ -107,13 +113,13 @@ namespace embree
size_t start,past,future;
std::vector<std::pair<T,ParseLocation> > buffer;
};
/*! warps an iostream stream */
class StdStream : public Stream<int>
{
public:
StdStream (std::istream& cin, const std::string& name = "std::stream")
: cin(cin), lineNumber(1), colNumber(0), charNumber(0), name(std::shared_ptr<std::string>(new std::string(name))) {}
: cin(cin), lineNumber(1), colNumber(0), charNumber(0), name(new String(name)) {}
~StdStream() {}
ParseLocation location() {
return ParseLocation(name,lineNumber,colNumber,charNumber);
@@ -129,7 +135,7 @@ namespace embree
ssize_t lineNumber; /// the line number the token is from
ssize_t colNumber; /// the character number in the current line
ssize_t charNumber; /// the character in the file
std::shared_ptr<std::string> name; /// name of buffer
Ref<String> name; /// name of buffer
};
/*! creates a stream from a file */
@@ -138,10 +144,10 @@ namespace embree
public:
FileStream (FILE* file, const std::string& name = "file")
: file(file), lineNumber(1), colNumber(0), charNumber(0), name(std::shared_ptr<std::string>(new std::string(name))) {}
: file(file), lineNumber(1), colNumber(0), charNumber(0), name(new String(name)) {}
FileStream (const FileName& fileName)
: lineNumber(1), colNumber(0), charNumber(0), name(std::shared_ptr<std::string>(new std::string(fileName.str())))
: lineNumber(1), colNumber(0), charNumber(0), name(new String(fileName.str()))
{
file = fopen(fileName.c_str(),"r");
if (file == nullptr) THROW_RUNTIME_ERROR("cannot open file " + fileName.str());
@@ -165,7 +171,7 @@ namespace embree
ssize_t lineNumber; /// the line number the token is from
ssize_t colNumber; /// the character number in the current line
ssize_t charNumber; /// the character in the file
std::shared_ptr<std::string> name; /// name of buffer
Ref<String> name; /// name of buffer
};
/*! creates a stream from a string */
@@ -178,7 +184,7 @@ namespace embree
public:
ParseLocation location() {
return ParseLocation(std::shared_ptr<std::string>(),lineNumber,colNumber,charNumber);
return ParseLocation(nullptr,lineNumber,colNumber,charNumber);
}
int next() {
@@ -201,12 +207,9 @@ namespace embree
{
public:
CommandLineStream (int argc, char** argv, const std::string& name = "command line")
: i(0), j(0), charNumber(0), name(std::shared_ptr<std::string>(new std::string(name)))
: i(0), j(0), charNumber(0), name(new String(name))
{
if (argc > 0) {
for (size_t i=0; argv[0][i] && i<1024; i++) charNumber++;
charNumber++;
}
if (argc > 0) charNumber = strlen(argv[0])+1;
for (ssize_t k=1; k<argc; k++) args.push_back(argv[k]);
}
~CommandLineStream() {}
@@ -224,6 +227,6 @@ namespace embree
size_t i,j;
std::vector<std::string> args;
ssize_t charNumber; /// the character in the file
std::shared_ptr<std::string> name; /// name of buffer
Ref<String> name; /// name of buffer
};
}
+1 -1
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
+1 -1
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
+2 -2
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
@@ -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 isSepMap[c]; }
private:
Ref<Stream<int> > cin; /*! source character stream */
bool isSepMap[256]; /*! map for fast classification of separators */
+1 -1
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
+4 -4
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
@@ -107,7 +107,7 @@ namespace embree
if (t.ty == TY_INT) return cout << "Int(" << t.i << ")";
if (t.ty == TY_FLOAT) return cout << "Float(" << t.f << ")";
if (t.ty == TY_IDENTIFIER) return cout << "Id(" << t.str << ")";
if (t.ty == TY_STRING) return cout << "String(" << t.str << ")";
if (t.ty == TY_STRING) return cout << "String(" + t.str + ")";
if (t.ty == TY_SYMBOL) return cout << "Symbol(" << t.str << ")";
return cout << "unknown";
}
@@ -160,13 +160,13 @@ namespace embree
std::vector<std::string> symbols;
/*! checks if a character is a separator */
__forceinline bool isSeparator(int c) const { return c<256 && isSepMap[c]; }
__forceinline bool isSeparator(int c) const { return isSepMap[c]; }
/*! checks if a character is a number */
__forceinline bool isDigit(int c) const { return c >= '0' && c <= '9';}
/*! checks if a character is legal for an identifier */
__forceinline bool isAlpha(int c) const { return c<256 && isAlphaMap[c]; }
__forceinline bool isAlpha(int c) const { return isAlphaMap[c]; }
__forceinline bool isAlphaNum(int c) const { return isAlpha(c) || isDigit(c); }
};
}
+4 -18
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
@@ -107,9 +107,9 @@ namespace embree
template<typename L> __forceinline AffineSpaceT<L>& operator /=( AffineSpaceT<L>& a, const AffineSpaceT<L>& b ) { return a = a / b; }
template<typename L> __forceinline AffineSpaceT<L>& operator /=( AffineSpaceT<L>& a, const ScalarT & b ) { return a = a / b; }
template<typename L> __forceinline VectorT xfmPoint (const AffineSpaceT<L>& m, const VectorT& p) { return madd(VectorT(p.x),m.l.vx,madd(VectorT(p.y),m.l.vy,madd(VectorT(p.z),m.l.vz,m.p))); }
template<typename L> __forceinline VectorT xfmVector(const AffineSpaceT<L>& m, const VectorT& v) { return xfmVector(m.l,v); }
template<typename L> __forceinline VectorT xfmNormal(const AffineSpaceT<L>& m, const VectorT& n) { return xfmNormal(m.l,n); }
template<typename L> __forceinline const VectorT xfmPoint (const AffineSpaceT<L>& m, const VectorT& p) { return madd(VectorT(p.x),m.l.vx,madd(VectorT(p.y),m.l.vy,madd(VectorT(p.z),m.l.vz,m.p))); }
template<typename L> __forceinline const VectorT xfmVector(const AffineSpaceT<L>& m, const VectorT& v) { return xfmVector(m.l,v); }
template<typename L> __forceinline const VectorT xfmNormal(const AffineSpaceT<L>& m, const VectorT& n) { return xfmNormal(m.l,n); }
__forceinline const BBox<Vec3fa> xfmBounds(const AffineSpaceT<LinearSpace3<Vec3fa> >& m, const BBox<Vec3fa>& b)
{
@@ -132,20 +132,6 @@ namespace embree
template<typename L> __forceinline bool operator ==( const AffineSpaceT<L>& a, const AffineSpaceT<L>& b ) { return a.l == b.l && a.p == b.p; }
template<typename L> __forceinline bool operator !=( const AffineSpaceT<L>& a, const AffineSpaceT<L>& b ) { return a.l != b.l || a.p != b.p; }
////////////////////////////////////////////////////////////////////////////////
/// Select
////////////////////////////////////////////////////////////////////////////////
template<typename L> __forceinline AffineSpaceT<L> select ( const typename L::Vector::Scalar::Bool& s, const AffineSpaceT<L>& t, const AffineSpaceT<L>& f ) {
return AffineSpaceT<L>(select(s,t.l,f.l),select(s,t.p,f.p));
}
/*! blending */
template<typename T>
__forceinline AffineSpaceT<T> lerp(const AffineSpaceT<T>& l0, const AffineSpaceT<T>& l1, const float t) {
return AffineSpaceT<T>(lerp(l0.l,l1.l,t),lerp(l0.p,l1.p,t));
}
////////////////////////////////////////////////////////////////////////////////
// Output Operators
////////////////////////////////////////////////////////////////////////////////
+1 -122
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
@@ -56,11 +56,6 @@ namespace embree
/*! computes twice the center of the box */
__forceinline T center2() const { return lower+upper; }
/*! merges two boxes */
__forceinline static const BBox merge (const BBox& a, const BBox& b) {
return BBox(min(a.lower, b.lower), max(a.upper, b.upper));
}
////////////////////////////////////////////////////////////////////////////////
/// Constants
////////////////////////////////////////////////////////////////////////////////
@@ -118,10 +113,6 @@ namespace embree
template<typename Vec> __forceinline float safeArea( const BBox<Vec>& b ) { if (b.empty()) return 0.0f; else return area(b); }
template<typename T> __forceinline float expectedApproxHalfArea(const BBox<T>& box) {
return halfArea(box);
}
/*! merges bounding boxes and points */
template<typename T> __forceinline const BBox<T> merge( const BBox<T>& a, const T& b ) { return BBox<T>(min(a.lower, b ), max(a.upper, b )); }
template<typename T> __forceinline const BBox<T> merge( const T& a, const BBox<T>& b ) { return BBox<T>(min(a , b.lower), max(a , b.upper)); }
@@ -184,12 +175,6 @@ namespace embree
return true;
}
/*! blending */
template<typename T>
__forceinline BBox<T> lerp(const BBox<T>& b0, const BBox<T>& b1, const float t) {
return BBox<T>(lerp(b0.lower,b1.lower,t),lerp(b0.upper,b1.upper,t));
}
/*! output operator */
template<typename T> __forceinline std::ostream& operator<<(std::ostream& cout, const BBox<T>& box) {
return cout << "[" << box.lower << "; " << box.upper << "]";
@@ -201,109 +186,3 @@ namespace embree
typedef BBox<Vec3f> BBox3f;
typedef BBox<Vec3fa> BBox3fa;
}
////////////////////////////////////////////////////////////////////////////////
/// SSE / AVX / MIC specializations
////////////////////////////////////////////////////////////////////////////////
#if defined __SSE__
#include "../simd/sse.h"
#endif
#if defined __AVX__
#include "../simd/avx.h"
#endif
#if defined(__AVX512F__)
#include "../simd/avx512.h"
#endif
namespace embree
{
template<int N>
__forceinline BBox<Vec3<vfloat<N>>> transpose(const BBox3fa* bounds);
template<>
__forceinline BBox<Vec3<vfloat4>> transpose<4>(const BBox3fa* bounds)
{
BBox<Vec3<vfloat4>> dest;
transpose((vfloat4&)bounds[0].lower,
(vfloat4&)bounds[1].lower,
(vfloat4&)bounds[2].lower,
(vfloat4&)bounds[3].lower,
dest.lower.x,
dest.lower.y,
dest.lower.z);
transpose((vfloat4&)bounds[0].upper,
(vfloat4&)bounds[1].upper,
(vfloat4&)bounds[2].upper,
(vfloat4&)bounds[3].upper,
dest.upper.x,
dest.upper.y,
dest.upper.z);
return dest;
}
#if defined(__AVX__)
template<>
__forceinline BBox<Vec3<vfloat8>> transpose<8>(const BBox3fa* bounds)
{
BBox<Vec3<vfloat8>> dest;
transpose((vfloat4&)bounds[0].lower,
(vfloat4&)bounds[1].lower,
(vfloat4&)bounds[2].lower,
(vfloat4&)bounds[3].lower,
(vfloat4&)bounds[4].lower,
(vfloat4&)bounds[5].lower,
(vfloat4&)bounds[6].lower,
(vfloat4&)bounds[7].lower,
dest.lower.x,
dest.lower.y,
dest.lower.z);
transpose((vfloat4&)bounds[0].upper,
(vfloat4&)bounds[1].upper,
(vfloat4&)bounds[2].upper,
(vfloat4&)bounds[3].upper,
(vfloat4&)bounds[4].upper,
(vfloat4&)bounds[5].upper,
(vfloat4&)bounds[6].upper,
(vfloat4&)bounds[7].upper,
dest.upper.x,
dest.upper.y,
dest.upper.z);
return dest;
}
#endif
template<int N>
__forceinline BBox3fa merge(const BBox3fa* bounds);
template<>
__forceinline BBox3fa merge<4>(const BBox3fa* bounds)
{
const Vec3fa lower = min(min(bounds[0].lower,bounds[1].lower),
min(bounds[2].lower,bounds[3].lower));
const Vec3fa upper = max(max(bounds[0].upper,bounds[1].upper),
max(bounds[2].upper,bounds[3].upper));
return BBox3fa(lower,upper);
}
#if defined(__AVX__)
template<>
__forceinline BBox3fa merge<8>(const BBox3fa* bounds)
{
const Vec3fa lower = min(min(min(bounds[0].lower,bounds[1].lower),min(bounds[2].lower,bounds[3].lower)),
min(min(bounds[4].lower,bounds[5].lower),min(bounds[6].lower,bounds[7].lower)));
const Vec3fa upper = max(max(max(bounds[0].upper,bounds[1].upper),max(bounds[2].upper,bounds[3].upper)),
max(max(bounds[4].upper,bounds[5].upper),max(bounds[6].upper,bounds[7].upper)));
return BBox3fa(lower,upper);
}
#endif
}
+1 -1
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
+1 -1
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
+12 -18
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
@@ -53,8 +53,8 @@ namespace embree
__forceinline Color4 ( const Color4& other ) : m128(other.m128) {}
__forceinline Color4& operator=( const Color4& other ) { m128 = other.m128; return *this; }
__forceinline operator const __m128&() const { return m128; }
__forceinline operator __m128&() { return m128; }
__forceinline operator const __m128&( void ) const { return m128; }
__forceinline operator __m128&( void ) { return m128; }
////////////////////////////////////////////////////////////////////////////////
/// Set
@@ -115,8 +115,8 @@ namespace embree
__forceinline Color ( const Color4& other ) : m128(other.m128) {}
__forceinline Color& operator=( const Color4& other ) { m128 = other.m128; return *this; }
__forceinline operator const __m128&() const { return m128; }
__forceinline operator __m128&() { return m128; }
__forceinline operator const __m128&( void ) const { return m128; }
__forceinline operator __m128&( void ) { return m128; }
////////////////////////////////////////////////////////////////////////////////
/// Set
@@ -163,22 +163,12 @@ namespace embree
const __m128 mask = _mm_castsi128_ps(_mm_set1_epi32(0x7fffffff));
return _mm_and_ps(a.m128, mask);
}
__forceinline const Color rcp ( const Color& a )
{
#if defined(__AVX512VL__)
const Color r = _mm_rcp14_ps(a.m128);
#else
__forceinline const Color rcp ( const Color& a ) {
const Color r = _mm_rcp_ps(a.m128);
#endif
return _mm_sub_ps(_mm_add_ps(r, r), _mm_mul_ps(_mm_mul_ps(r, r), a));
}
__forceinline const Color rsqrt( const Color& a )
{
#if defined(__AVX512VL__)
__m128 r = _mm_rsqrt14_ps(a.m128);
#else
__forceinline const Color rsqrt( const Color& a ) {
__m128 r = _mm_rsqrt_ps(a.m128);
#endif
return _mm_add_ps(_mm_mul_ps(_mm_set1_ps(1.5f),r), _mm_mul_ps(_mm_mul_ps(_mm_mul_ps(a, _mm_set1_ps(-0.5f)), r), _mm_mul_ps(r, r)));
}
__forceinline const Color sqrt ( const Color& a ) { return _mm_sqrt_ps(a.m128); }
@@ -245,7 +235,11 @@ namespace embree
////////////////////////////////////////////////////////////////////////////////
/*! computes luminance of a color */
__forceinline float luminance (const Color& a) { return madd(0.212671f,a.r,madd(0.715160f,a.g,0.072169f*a.b)); }
__forceinline float luminance (const Color& a) { return 0.212671f*a.r + 0.715160f*a.g + 0.072169f*a.b; }
__forceinline Color exp (const Color& a) { return Color(exp_ps(a.m128)); }
__forceinline Color log (const Color& a) { return Color(log_ps(a.m128)); }
__forceinline Color pow (const Color& a, const float& b) { return Color(select(vfloat4(a)<=vfloat4(zero),vfloat4(zero),vfloat4(exp_ps(log(a)*b)))); }
/*! output operator */
inline std::ostream& operator<<(std::ostream& cout, const Color& a) {
+37 -79
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
@@ -32,19 +32,15 @@ namespace embree
/* we consider floating point numbers in that range as valid input numbers */
static float FLT_LARGE = 1.844E18f;
struct TrueTy {
static struct TrueTy {
__forceinline operator bool( ) const { return true; }
};
} True MAYBE_UNUSED;
extern MAYBE_UNUSED TrueTy True;
struct FalseTy {
static struct FalseTy {
__forceinline operator bool( ) const { return false; }
};
extern MAYBE_UNUSED FalseTy False;
} False MAYBE_UNUSED;
struct ZeroTy
static struct ZeroTy
{
__forceinline operator double ( ) const { return 0; }
__forceinline operator float ( ) const { return 0; }
@@ -58,11 +54,9 @@ namespace embree
__forceinline operator unsigned short ( ) const { return 0; }
__forceinline operator char ( ) const { return 0; }
__forceinline operator unsigned char ( ) const { return 0; }
};
} zero MAYBE_UNUSED;
extern MAYBE_UNUSED ZeroTy zero;
struct OneTy
static struct OneTy
{
__forceinline operator double ( ) const { return 1; }
__forceinline operator float ( ) const { return 1; }
@@ -76,11 +70,9 @@ namespace embree
__forceinline operator unsigned short ( ) const { return 1; }
__forceinline operator char ( ) const { return 1; }
__forceinline operator unsigned char ( ) const { return 1; }
};
} one MAYBE_UNUSED;
extern MAYBE_UNUSED OneTy one;
struct NegInfTy
static struct NegInfTy
{
__forceinline operator double ( ) const { return -std::numeric_limits<double>::infinity(); }
__forceinline operator float ( ) const { return -std::numeric_limits<float>::infinity(); }
@@ -95,11 +87,9 @@ namespace embree
__forceinline operator char ( ) const { return std::numeric_limits<char>::min(); }
__forceinline operator unsigned char ( ) const { return std::numeric_limits<unsigned char>::min(); }
};
} neg_inf MAYBE_UNUSED;
extern MAYBE_UNUSED NegInfTy neg_inf;
struct PosInfTy
static struct PosInfTy
{
__forceinline operator double ( ) const { return std::numeric_limits<double>::infinity(); }
__forceinline operator float ( ) const { return std::numeric_limits<float>::infinity(); }
@@ -113,97 +103,65 @@ namespace embree
__forceinline operator unsigned short ( ) const { return std::numeric_limits<unsigned short>::max(); }
__forceinline operator char ( ) const { return std::numeric_limits<char>::max(); }
__forceinline operator unsigned char ( ) const { return std::numeric_limits<unsigned char>::max(); }
};
} inf MAYBE_UNUSED, pos_inf MAYBE_UNUSED;
extern MAYBE_UNUSED PosInfTy inf;
extern MAYBE_UNUSED PosInfTy pos_inf;
struct NaNTy
static struct NaNTy
{
__forceinline operator double( ) const { return std::numeric_limits<double>::quiet_NaN(); }
__forceinline operator float ( ) const { return std::numeric_limits<float>::quiet_NaN(); }
};
} nan MAYBE_UNUSED;
extern MAYBE_UNUSED NaNTy nan;
struct UlpTy
static struct UlpTy
{
__forceinline operator double( ) const { return std::numeric_limits<double>::epsilon(); }
__forceinline operator float ( ) const { return std::numeric_limits<float>::epsilon(); }
};
} ulp MAYBE_UNUSED;
extern MAYBE_UNUSED UlpTy ulp;
struct PiTy
static struct PiTy
{
__forceinline operator double( ) const { return double(M_PI); }
__forceinline operator float ( ) const { return float(M_PI); }
};
} pi MAYBE_UNUSED;
extern MAYBE_UNUSED PiTy pi;
struct OneOverPiTy
static struct OneOverPiTy
{
__forceinline operator double( ) const { return double(M_1_PI); }
__forceinline operator float ( ) const { return float(M_1_PI); }
};
} one_over_pi MAYBE_UNUSED;
extern MAYBE_UNUSED OneOverPiTy one_over_pi;
struct TwoPiTy
static struct TwoPiTy
{
__forceinline operator double( ) const { return double(2.0*M_PI); }
__forceinline operator float ( ) const { return float(2.0*M_PI); }
};
} two_pi MAYBE_UNUSED;
extern MAYBE_UNUSED TwoPiTy two_pi;
struct OneOverTwoPiTy
static struct OneOverTwoPiTy
{
__forceinline operator double( ) const { return double(0.5*M_1_PI); }
__forceinline operator float ( ) const { return float(0.5*M_1_PI); }
};
} one_over_two_pi MAYBE_UNUSED;
extern MAYBE_UNUSED OneOverTwoPiTy one_over_two_pi;
struct FourPiTy
static struct FourPiTy
{
__forceinline operator double( ) const { return double(4.0*M_PI); }
__forceinline operator float ( ) const { return float(4.0*M_PI); }
};
} four_pi MAYBE_UNUSED;
extern MAYBE_UNUSED FourPiTy four_pi;
struct OneOverFourPiTy
static struct OneOverFourPiTy
{
__forceinline operator double( ) const { return double(0.25*M_1_PI); }
__forceinline operator float ( ) const { return float(0.25*M_1_PI); }
};
} one_over_four_pi MAYBE_UNUSED;
extern MAYBE_UNUSED OneOverFourPiTy one_over_four_pi;
static struct StepTy {
} step MAYBE_UNUSED;
struct StepTy {
};
static struct ReverseStepTy {
} reverse_step MAYBE_UNUSED;
extern MAYBE_UNUSED StepTy step;
static struct EmptyTy {
} empty MAYBE_UNUSED;
struct ReverseStepTy {
};
extern MAYBE_UNUSED ReverseStepTy reverse_step;
struct EmptyTy {
};
extern MAYBE_UNUSED EmptyTy empty;
struct FullTy {
};
extern MAYBE_UNUSED FullTy full;
struct UndefinedTy {
};
extern MAYBE_UNUSED UndefinedTy undefined;
static struct FullTy {
} full MAYBE_UNUSED;
}
+2 -134
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
@@ -17,19 +17,9 @@
#pragma once
#include "bbox.h"
#include "range.h"
namespace embree
{
template<typename T>
__forceinline std::pair<T,T> globalLinear(const std::pair<T,T>& v, const BBox1f& dt)
{
const float rcp_dt_size = float(1.0f)/dt.size();
const T g0 = lerp(v.first,v.second,-dt.lower*rcp_dt_size);
const T g1 = lerp(v.first,v.second,(1.0f-dt.lower)*rcp_dt_size);
return std::make_pair(g0,g1);
}
template<typename T>
struct LBBox
{
@@ -68,78 +58,7 @@ namespace embree
bounds0 = b0;
bounds1 = b1;
}
/*! calculates the linear bounds of a primitive for the specified time range */
template<typename BoundsFunc>
__forceinline LBBox(const BoundsFunc& bounds, const BBox1f& time_range, float numTimeSegments)
{
const float lower = time_range.lower*numTimeSegments;
const float upper = time_range.upper*numTimeSegments;
const float ilowerf = floor(lower);
const float iupperf = ceil(upper);
const int ilower = (int)ilowerf;
const int iupper = (int)iupperf;
const BBox<T> blower0 = bounds(ilower);
const BBox<T> bupper1 = bounds(iupper);
if (iupper-ilower == 1) {
bounds0 = lerp(blower0, bupper1, lower-ilowerf);
bounds1 = lerp(bupper1, blower0, iupperf-upper);
return;
}
const BBox<T> blower1 = bounds(ilower+1);
const BBox<T> bupper0 = bounds(iupper-1);
BBox<T> b0 = lerp(blower0, blower1, lower-ilowerf);
BBox<T> b1 = lerp(bupper1, bupper0, iupperf-upper);
for (int i = ilower+1; i < iupper; i++)
{
const float f = (float(i)/numTimeSegments - time_range.lower) / time_range.size();
const BBox<T> bt = lerp(b0, b1, f);
const BBox<T> bi = bounds(i);
const T dlower = min(bi.lower-bt.lower, T(zero));
const T dupper = max(bi.upper-bt.upper, T(zero));
b0.lower += dlower; b1.lower += dlower;
b0.upper += dupper; b1.upper += dupper;
}
bounds0 = b0;
bounds1 = b1;
}
/*! calculates the linear bounds of a primitive for the specified time range */
template<typename BoundsFunc>
__forceinline LBBox(const BoundsFunc& bounds, const range<int>& time_range, int numTimeSegments)
{
const int ilower = time_range.begin();
const int iupper = time_range.end();
BBox<T> b0 = bounds(ilower);
BBox<T> b1 = bounds(iupper);
if (iupper-ilower == 1) {
bounds0 = b0;
bounds1 = b1;
return;
}
for (int i = ilower+1; i<iupper; i++)
{
const float f = float(i - time_range.begin()) / float(time_range.size());
const BBox<T> bt = lerp(b0, b1, f);
const BBox<T> bi = bounds(i);
const T dlower = min(bi.lower-bt.lower, T(zero));
const T dupper = max(bi.upper-bt.upper, T(zero));
b0.lower += dlower; b1.lower += dlower;
b0.upper += dupper; b1.upper += dupper;
}
bounds0 = b0;
bounds1 = b1;
}
public:
__forceinline bool empty() const {
@@ -154,34 +73,11 @@ namespace embree
return lerp(bounds0,bounds1,t);
}
__forceinline LBBox<T> interpolate( const BBox1f& dt ) const {
return LBBox<T>(interpolate(dt.lower),interpolate(dt.upper));
}
__forceinline void extend( const LBBox& other ) {
bounds0.extend(other.bounds0);
bounds1.extend(other.bounds1);
}
__forceinline float expectedHalfArea() const;
__forceinline float expectedHalfArea(const BBox1f& dt) const {
return interpolate(dt).expectedHalfArea();
}
__forceinline float expectedApproxHalfArea() const {
return 0.5f*(halfArea(bounds0) + halfArea(bounds1));
}
/* calculates bounds for [0,1] time range from bounds in dt time range */
__forceinline LBBox global(const BBox1f& dt) const
{
const float rcp_dt_size = 1.0f/dt.size();
const BBox<T> b0 = interpolate(-dt.lower*rcp_dt_size);
const BBox<T> b1 = interpolate((1.0f-dt.lower)*rcp_dt_size);
return LBBox(b0,b1);
}
/*! Comparison Operators */
template<typename TT> friend __forceinline bool operator==( const LBBox<TT>& a, const LBBox<TT>& b ) { return a.bounds0 == b.bounds0 && a.bounds1 == b.bounds1; }
template<typename TT> friend __forceinline bool operator!=( const LBBox<TT>& a, const LBBox<TT>& b ) { return a.bounds0 != b.bounds0 || a.bounds1 != b.bounds1; }
@@ -195,34 +91,6 @@ namespace embree
BBox<T> bounds0, bounds1;
};
template<typename T>
__forceinline T expectedArea(const T& a0, const T& a1, const T& b0, const T& b1)
{
const T da = a1-a0;
const T db = b1-b0;
return a0*b0+(a0*db+da*b0)*T(0.5f) + da*db*T(1.0f/3.0f);
}
template<> __forceinline float LBBox<Vec3fa>::expectedHalfArea() const
{
const Vec3fa d0 = bounds0.size();
const Vec3fa d1 = bounds1.size();
return reduce_add(expectedArea(Vec3fa(d0.x,d0.y,d0.z),
Vec3fa(d1.x,d1.y,d1.z),
Vec3fa(d0.y,d0.z,d0.x),
Vec3fa(d1.y,d1.z,d1.x)));
}
template<typename T>
__forceinline float expectedApproxHalfArea(const LBBox<T>& box) {
return box.expectedApproxHalfArea();
}
template<typename T>
__forceinline LBBox<T> merge(const LBBox<T>& a, const LBBox<T>& b) {
return LBBox<T>(merge(a.bounds0, b.bounds0), merge(a.bounds1, b.bounds1));
}
/*! default template instantiations */
typedef LBBox<float> LBBox1f;
typedef LBBox<Vec2f> LBBox2f;
+3 -3
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
@@ -58,10 +58,10 @@ namespace embree
__forceinline const LinearSpace2 transposed() const { return LinearSpace2(vx.x,vx.y,vy.x,vy.y); }
/*! returns first row of matrix */
__forceinline Vector row0() const { return Vector(vx.x,vy.x); }
__forceinline const Vector row0() const { return Vector(vx.x,vy.x); }
/*! returns second row of matrix */
__forceinline Vector row1() const { return Vector(vx.y,vy.y); }
__forceinline const Vector row1() const { return Vector(vx.y,vy.y); }
////////////////////////////////////////////////////////////////////////////////
/// Constants
+5 -22
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
@@ -66,13 +66,13 @@ namespace embree
__forceinline const LinearSpace3 transposed() const { return LinearSpace3(vx.x,vx.y,vx.z,vy.x,vy.y,vy.z,vz.x,vz.y,vz.z); }
/*! returns first row of matrix */
__forceinline Vector row0() const { return Vector(vx.x,vy.x,vz.x); }
__forceinline const Vector row0() const { return Vector(vx.x,vy.x,vz.x); }
/*! returns second row of matrix */
__forceinline Vector row1() const { return Vector(vx.y,vy.y,vz.y); }
__forceinline const Vector row1() const { return Vector(vx.y,vy.y,vz.y); }
/*! returns third row of matrix */
__forceinline Vector row2() const { return Vector(vx.z,vy.z,vz.z); }
__forceinline const Vector row2() const { return Vector(vx.z,vy.z,vz.z); }
////////////////////////////////////////////////////////////////////////////////
/// Constants
@@ -156,7 +156,7 @@ namespace embree
template<typename T> __forceinline LinearSpace3<T> operator -( const LinearSpace3<T>& a, const LinearSpace3<T>& b ) { return LinearSpace3<T>(a.vx-b.vx,a.vy-b.vy,a.vz-b.vz); }
template<typename T> __forceinline LinearSpace3<T> operator*(const typename T::Scalar & a, const LinearSpace3<T>& b) { return LinearSpace3<T>(a*b.vx, a*b.vy, a*b.vz); }
template<typename T> __forceinline T operator*(const LinearSpace3<T>& a, const T & b) { return madd(T(b.x),a.vx,madd(T(b.y),a.vy,T(b.z)*a.vz)); }
template<typename T> __forceinline T operator*(const LinearSpace3<T>& a, const T & b) { return b.x*a.vx + b.y*a.vy + b.z*a.vz; }
template<typename T> __forceinline LinearSpace3<T> operator*(const LinearSpace3<T>& a, const LinearSpace3<T>& b) { return LinearSpace3<T>(a*b.vx, a*b.vy, a*b.vz); }
template<typename T> __forceinline LinearSpace3<T> operator/(const LinearSpace3<T>& a, const typename T::Scalar & b) { return LinearSpace3<T>(a.vx/b, a.vy/b, a.vz/b); }
@@ -176,23 +176,6 @@ namespace embree
template<typename T> __forceinline bool operator ==( const LinearSpace3<T>& a, const LinearSpace3<T>& b ) { return a.vx == b.vx && a.vy == b.vy && a.vz == b.vz; }
template<typename T> __forceinline bool operator !=( const LinearSpace3<T>& a, const LinearSpace3<T>& b ) { return a.vx != b.vx || a.vy != b.vy || a.vz != b.vz; }
////////////////////////////////////////////////////////////////////////////////
/// Select
////////////////////////////////////////////////////////////////////////////////
template<typename T> __forceinline LinearSpace3<T> select ( const typename T::Scalar::Bool& s, const LinearSpace3<T>& t, const LinearSpace3<T>& f ) {
return LinearSpace3<T>(select(s,t.vx,f.vx),select(s,t.vy,f.vy),select(s,t.vz,f.vz));
}
/*! blending */
template<typename T>
__forceinline LinearSpace3<T> lerp(const LinearSpace3<T>& l0, const LinearSpace3<T>& l1, const float t)
{
return LinearSpace3<T>(lerp(l0.vx,l1.vx,t),
lerp(l0.vy,l1.vy,t),
lerp(l0.vz,l1.vz,t));
}
////////////////////////////////////////////////////////////////////////////////
/// Output Operators
////////////////////////////////////////////////////////////////////////////////
+10 -48
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
@@ -17,13 +17,11 @@
#pragma once
#include "../sys/platform.h"
#include "../sys/intrinsics.h"
#include "constants.h"
#include <cmath>
#include <emmintrin.h>
#include <xmmintrin.h>
#include <immintrin.h>
#if defined(__WIN32__)
#if (__MSV_VER <= 1700)
@@ -60,17 +58,11 @@ namespace embree
__forceinline float rcp ( const float x )
{
const __m128 a = _mm_set_ss(x);
#if defined(__AVX512VL__)
const __m128 r = _mm_rcp14_ss(_mm_set_ss(0.0f),a);
#else
const __m128 r = _mm_rcp_ss(a);
#endif
const __m128 r = _mm_rcp_ps(a);
#if defined(__AVX2__)
return _mm_cvtss_f32(_mm_mul_ss(r,_mm_fnmadd_ss(r, a, _mm_set_ss(2.0f))));
return _mm_cvtss_f32(_mm_mul_ps(r,_mm_fnmadd_ps(r, a, _mm_set_ss(2.0f))));
#else
return _mm_cvtss_f32(_mm_mul_ss(r,_mm_sub_ss(_mm_set_ss(2.0f), _mm_mul_ss(r, a))));
return _mm_cvtss_f32(_mm_mul_ps(r,_mm_sub_ps(_mm_set_ss(2.0f), _mm_mul_ps(r, a))));
#endif
}
@@ -83,23 +75,17 @@ namespace embree
__forceinline float andf( const float x, const unsigned y ) {
return _mm_cvtss_f32(_mm_and_ps(_mm_set_ss(x),_mm_castsi128_ps(_mm_set1_epi32(y))));
}
__forceinline float rsqrt( const float x )
{
__forceinline float rsqrt( const float x ) {
const __m128 a = _mm_set_ss(x);
#if defined(__AVX512VL__)
const __m128 r = _mm_rsqrt14_ss(_mm_set_ss(0.0f),a);
#else
const __m128 r = _mm_rsqrt_ss(a);
#endif
const __m128 c = _mm_add_ss(_mm_mul_ss(_mm_set_ss(1.5f), r),
_mm_mul_ss(_mm_mul_ss(_mm_mul_ss(a, _mm_set_ss(-0.5f)), r), _mm_mul_ss(r, r)));
const __m128 r = _mm_rsqrt_ps(a);
const __m128 c = _mm_add_ps(_mm_mul_ps(_mm_set_ps(1.5f, 1.5f, 1.5f, 1.5f), r),
_mm_mul_ps(_mm_mul_ps(_mm_mul_ps(a, _mm_set_ps(-0.5f, -0.5f, -0.5f, -0.5f)), r), _mm_mul_ps(r, r)));
return _mm_cvtss_f32(c);
}
#if defined(__WIN32__) && (__MSC_VER <= 1700)
__forceinline float nextafter(float x, float y) { if ((x<y) == (x>0)) return x*(1.1f+float(ulp)); else return x*(0.9f-float(ulp)); }
__forceinline double nextafter(double x, double y) { return _nextafter(x, y); }
__forceinline int roundf(float f) { return (int)(f + 0.5f); }
#else
__forceinline float nextafter(float x, float y) { return ::nextafterf(x, y); }
__forceinline double nextafter(double x, double y) { return ::nextafter(x, y); }
@@ -168,9 +154,6 @@ namespace embree
}
#endif
template<typename T>
__forceinline T twice(const T& a) { return a+a; }
__forceinline int min(int a, int b) { return a<b ? a:b; }
__forceinline unsigned min(unsigned a, unsigned b) { return a<b ? a:b; }
__forceinline int64_t min(int64_t a, int64_t b) { return a<b ? a:b; }
@@ -184,10 +167,6 @@ namespace embree
template<typename T> __forceinline T min(const T& a, const T& b, const T& c, const T& d) { return min(min(a,b),min(c,d)); }
template<typename T> __forceinline T min(const T& a, const T& b, const T& c, const T& d, const T& e) { return min(min(min(a,b),min(c,d)),e); }
template<typename T> __forceinline T mini(const T& a, const T& b, const T& c) { return mini(mini(a,b),c); }
template<typename T> __forceinline T mini(const T& a, const T& b, const T& c, const T& d) { return mini(mini(a,b),mini(c,d)); }
template<typename T> __forceinline T mini(const T& a, const T& b, const T& c, const T& d, const T& e) { return mini(mini(mini(a,b),mini(c,d)),e); }
__forceinline int max(int a, int b) { return a<b ? b:a; }
__forceinline unsigned max(unsigned a, unsigned b) { return a<b ? b:a; }
__forceinline int64_t max(int64_t a, int64_t b) { return a<b ? b:a; }
@@ -201,10 +180,6 @@ namespace embree
template<typename T> __forceinline T max(const T& a, const T& b, const T& c, const T& d) { return max(max(a,b),max(c,d)); }
template<typename T> __forceinline T max(const T& a, const T& b, const T& c, const T& d, const T& e) { return max(max(max(a,b),max(c,d)),e); }
template<typename T> __forceinline T maxi(const T& a, const T& b, const T& c) { return maxi(maxi(a,b),c); }
template<typename T> __forceinline T maxi(const T& a, const T& b, const T& c, const T& d) { return maxi(maxi(a,b),maxi(c,d)); }
template<typename T> __forceinline T maxi(const T& a, const T& b, const T& c, const T& d, const T& e) { return maxi(maxi(maxi(a,b),maxi(c,d)),e); }
#if defined(__MACOSX__)
__forceinline ssize_t min(ssize_t a, ssize_t b) { return a<b ? a:b; }
__forceinline ssize_t max(ssize_t a, ssize_t b) { return a<b ? b:a; }
@@ -272,12 +247,12 @@ namespace embree
template<typename V>
__forceinline V lerp(const V& v0, const V& v1, const float t) {
return madd(V(1.0f-t),v0,t*v1);
return (1.0f-t)*v0 + t*v1;
}
template<typename T>
__forceinline T lerp2(const float x0, const float x1, const float x2, const float x3, const T& u, const T& v) {
return madd((1.0f-u),madd((1.0f-v),T(x0),v*T(x2)),u*madd((1.0f-v),T(x1),v*T(x3)));
return (1.0f-u)*(1.0f-v)*x0 + u*(1.0f-v)*x1 + (1.0f-u)*v*x2 + u*v*x3;
}
/*! exchange */
@@ -319,19 +294,6 @@ namespace embree
return x | (y << 1) | (z << 2);
}
#if defined(__AVX2__)
template<>
__forceinline unsigned int bitInterleave(const unsigned int &xi, const unsigned int& yi, const unsigned int& zi)
{
const unsigned int xx = pdep(xi,0x49249249 /* 0b01001001001001001001001001001001 */ );
const unsigned int yy = pdep(yi,0x92492492 /* 0b10010010010010010010010010010010 */);
const unsigned int zz = pdep(zi,0x24924924 /* 0b00100100100100100100100100100100 */);
return xx | yy | zz;
}
#endif
/*! bit interleave operation for 64bit data types*/
template<class T>
__forceinline T bitInterleave64(const T& xin, const T& yin, const T& zin){
+1 -1
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
+3 -3
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
@@ -33,7 +33,7 @@ namespace embree
/// Construction
////////////////////////////////////////////////////////////////////////////////
__forceinline QuaternionT () { }
__forceinline QuaternionT ( void ) { }
__forceinline QuaternionT ( const QuaternionT& other ) { r = other.r; i = other.i; j = other.j; k = other.k; }
__forceinline QuaternionT& operator=( const QuaternionT& other ) { r = other.r; i = other.i; j = other.j; k = other.k; return *this; }
@@ -58,7 +58,7 @@ namespace embree
}
/*! returns the rotation axis of the quaternion as a vector */
__forceinline Vec3<T> v( ) const { return Vec3<T>(i, j, k); }
__forceinline const Vec3<T> v( ) const { return Vec3<T>(i, j, k); }
public:
T r, i, j, k;
+34 -47
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
@@ -24,27 +24,13 @@ namespace embree
template<typename Ty>
struct range
{
__forceinline range() {}
__forceinline range () {}
__forceinline range(const Ty& begin)
: _begin(begin), _end(begin+1) {}
__forceinline range (const Ty& begin)
: _begin(begin), _end(begin+1) {}
__forceinline range(const Ty& begin, const Ty& end)
: _begin(begin), _end(end) {}
__forceinline range(const range& other)
: _begin(other._begin), _end(other._end) {}
template<typename T1>
__forceinline range(const range<T1>& other)
: _begin(Ty(other._begin)), _end(Ty(other._end)) {}
template<typename T1>
__forceinline range& operator =(const range<T1>& other) {
_begin = other._begin;
_end = other._end;
return *this;
}
__forceinline range (const Ty& begin, const Ty& end)
: _begin(begin), _end(end) {}
__forceinline Ty begin() const {
return _begin;
@@ -66,23 +52,12 @@ namespace embree
return _end <= _begin;
}
__forceinline Ty center() const {
return (_begin + _end)/2;
}
__forceinline std::pair<range,range> split() const
{
const Ty _center = center();
const Ty _center = (_begin+_end)/2;
return std::make_pair(range(_begin,_center),range(_center,_end));
}
__forceinline void split(range& left_o, range& right_o) const
{
const Ty _center = center();
left_o = range(_begin,_center);
right_o = range(_center,_end);
}
__forceinline friend bool operator< (const range& r0, const range& r1) {
return r0.size() < r1.size();
}
@@ -100,44 +75,56 @@ namespace embree
}
template<typename Ty>
struct extended_range : public range<Ty>
struct extended_range
{
__forceinline extended_range () {}
__forceinline extended_range (const Ty& begin)
: range<Ty>(begin), _ext_end(begin+1) {}
__forceinline extended_range (const Ty& begin)
: _begin(begin), _end(begin+1), _ext_end(begin+1) {}
__forceinline extended_range (const Ty& begin, const Ty& end)
: range<Ty>(begin,end), _ext_end(end) {}
__forceinline extended_range (const Ty& begin, const Ty& end)
: _begin(begin), _end(end), _ext_end(end) {}
__forceinline extended_range (const Ty& begin, const Ty& end, const Ty& ext_end)
: range<Ty>(begin,end), _ext_end(ext_end) {}
__forceinline extended_range (const Ty& begin, const Ty& end, const Ty& ext_end)
: _begin(begin), _end(end), _ext_end(ext_end) {}
__forceinline Ty begin() const {
return _begin;
}
__forceinline Ty end() const {
return _end;
}
__forceinline Ty ext_end() const {
return _ext_end;
}
__forceinline Ty size() const {
return _end - _begin;
}
__forceinline Ty ext_size() const {
return _ext_end - range<Ty>::_begin;
return _ext_end - _begin;
}
__forceinline Ty ext_range_size() const {
return _ext_end - range<Ty>::_end;
return _ext_end - _end;
}
__forceinline bool has_ext_range() const {
assert(_ext_end >= range<Ty>::_end);
return (_ext_end - range<Ty>::_end) > 0;
assert(_ext_end >= _end);
return (_ext_end - _end) > 0;
}
__forceinline void set_ext_range(const size_t ext_end){
assert(ext_end >= range<Ty>::_end);
assert(ext_end >= _end);
_ext_end = ext_end;
}
__forceinline void move_right(const size_t plus){
range<Ty>::_begin += plus;
range<Ty>::_end += plus;
_begin += plus;
_end += plus;
_ext_end += plus;
}
@@ -145,6 +132,6 @@ namespace embree
return cout << "extended_range [" << r.begin() << ", " << r.end() << " (" << r.ext_end() << ")]";
}
Ty _ext_end;
Ty _begin, _end, _ext_end;
};
}
+5 -10
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
@@ -92,15 +92,10 @@ namespace embree
/// Ternary Operators
////////////////////////////////////////////////////////////////////////////////
template<typename T> __forceinline Vec2<T> madd ( const Vec2<T>& a, const Vec2<T>& b, const Vec2<T>& c) { return Vec2<T>( madd(a.x,b.x,c.x), madd(a.y,b.y,c.y) ); }
template<typename T> __forceinline Vec2<T> msub ( const Vec2<T>& a, const Vec2<T>& b, const Vec2<T>& c) { return Vec2<T>( msub(a.x,b.x,c.x), msub(a.y,b.y,c.y) ); }
template<typename T> __forceinline Vec2<T> nmadd ( const Vec2<T>& a, const Vec2<T>& b, const Vec2<T>& c) { return Vec2<T>(nmadd(a.x,b.x,c.x),nmadd(a.y,b.y,c.y) ); }
template<typename T> __forceinline Vec2<T> nmsub ( const Vec2<T>& a, const Vec2<T>& b, const Vec2<T>& c) { return Vec2<T>(nmsub(a.x,b.x,c.x),nmsub(a.y,b.y,c.y) ); }
template<typename T> __forceinline Vec2<T> madd ( const T& a, const Vec2<T>& b, const Vec2<T>& c) { return Vec2<T>( madd(a,b.x,c.x), madd(a,b.y,c.y) ); }
template<typename T> __forceinline Vec2<T> msub ( const T& a, const Vec2<T>& b, const Vec2<T>& c) { return Vec2<T>( msub(a,b.x,c.x), msub(a,b.y,c.y) ); }
template<typename T> __forceinline Vec2<T> nmadd ( const T& a, const Vec2<T>& b, const Vec2<T>& c) { return Vec2<T>(nmadd(a,b.x,c.x),nmadd(a,b.y,c.y) ); }
template<typename T> __forceinline Vec2<T> nmsub ( const T& a, const Vec2<T>& b, const Vec2<T>& c) { return Vec2<T>(nmsub(a,b.x,c.x),nmsub(a,b.y,c.y) ); }
template<typename T> __forceinline const Vec2<T> madd ( const Vec2<T>& a, const Vec2<T>& b, const Vec2<T>& c) { return Vec2<T>( madd(a.x,b.x,c.x), madd(a.y,b.y,c.y) ); }
template<typename T> __forceinline const Vec2<T> msub ( const Vec2<T>& a, const Vec2<T>& b, const Vec2<T>& c) { return Vec2<T>( msub(a.x,b.x,c.x), msub(a.y,b.y,c.y) ); }
template<typename T> __forceinline const Vec2<T> nmadd ( const Vec2<T>& a, const Vec2<T>& b, const Vec2<T>& c) { return Vec2<T>(nmadd(a.x,b.x,c.x),nmadd(a.y,b.y,c.y) ); }
template<typename T> __forceinline const Vec2<T> nmsub ( const Vec2<T>& a, const Vec2<T>& b, const Vec2<T>& c) { return Vec2<T>(nmsub(a.x,b.x,c.x),nmsub(a.y,b.y,c.y) ); }
////////////////////////////////////////////////////////////////////////////////
/// Assignment Operators
+33 -47
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
@@ -77,7 +77,7 @@ namespace embree
select(abs(a.y)<min_rcp_input,T(min_rcp_input),a.y),
select(abs(a.z)<min_rcp_input,T(min_rcp_input),a.z));
}
template<typename T> __forceinline Vec3<T> rcp_safe(const Vec3<T>& a) { return rcp(zero_fix(a)); }
template<typename T> __forceinline const Vec3<T> rcp_safe(const Vec3<T>& a) { return rcp(zero_fix(a)); }
////////////////////////////////////////////////////////////////////////////////
/// Binary Operators
@@ -102,25 +102,20 @@ namespace embree
/// Ternary Operators
////////////////////////////////////////////////////////////////////////////////
template<typename T> __forceinline Vec3<T> madd ( const Vec3<T>& a, const Vec3<T>& b, const Vec3<T>& c) { return Vec3<T>( madd(a.x,b.x,c.x), madd(a.y,b.y,c.y), madd(a.z,b.z,c.z)); }
template<typename T> __forceinline Vec3<T> msub ( const Vec3<T>& a, const Vec3<T>& b, const Vec3<T>& c) { return Vec3<T>( msub(a.x,b.x,c.x), msub(a.y,b.y,c.y), msub(a.z,b.z,c.z)); }
template<typename T> __forceinline Vec3<T> nmadd ( const Vec3<T>& a, const Vec3<T>& b, const Vec3<T>& c) { return Vec3<T>(nmadd(a.x,b.x,c.x),nmadd(a.y,b.y,c.y),nmadd(a.z,b.z,c.z));}
template<typename T> __forceinline Vec3<T> nmsub ( const Vec3<T>& a, const Vec3<T>& b, const Vec3<T>& c) { return Vec3<T>(nmsub(a.x,b.x,c.x),nmsub(a.y,b.y,c.y),nmsub(a.z,b.z,c.z)); }
template<typename T> __forceinline Vec3<T> madd ( const T& a, const Vec3<T>& b, const Vec3<T>& c) { return Vec3<T>( madd(a,b.x,c.x), madd(a,b.y,c.y), madd(a,b.z,c.z)); }
template<typename T> __forceinline Vec3<T> msub ( const T& a, const Vec3<T>& b, const Vec3<T>& c) { return Vec3<T>( msub(a,b.x,c.x), msub(a,b.y,c.y), msub(a,b.z,c.z)); }
template<typename T> __forceinline Vec3<T> nmadd ( const T& a, const Vec3<T>& b, const Vec3<T>& c) { return Vec3<T>(nmadd(a,b.x,c.x),nmadd(a,b.y,c.y),nmadd(a,b.z,c.z));}
template<typename T> __forceinline Vec3<T> nmsub ( const T& a, const Vec3<T>& b, const Vec3<T>& c) { return Vec3<T>(nmsub(a,b.x,c.x),nmsub(a,b.y,c.y),nmsub(a,b.z,c.z)); }
template<typename T> __forceinline const Vec3<T> madd ( const Vec3<T>& a, const Vec3<T>& b, const Vec3<T>& c) { return Vec3<T>( madd(a.x,b.x,c.x), madd(a.y,b.y,c.y), madd(a.z,b.z,c.z)); }
template<typename T> __forceinline const Vec3<T> msub ( const Vec3<T>& a, const Vec3<T>& b, const Vec3<T>& c) { return Vec3<T>( msub(a.x,b.x,c.x), msub(a.y,b.y,c.y), msub(a.z,b.z,c.z)); }
template<typename T> __forceinline const Vec3<T> nmadd ( const Vec3<T>& a, const Vec3<T>& b, const Vec3<T>& c) { return Vec3<T>(nmadd(a.x,b.x,c.x),nmadd(a.y,b.y,c.y),nmadd(a.z,b.z,c.z));}
template<typename T> __forceinline const Vec3<T> nmsub ( const Vec3<T>& a, const Vec3<T>& b, const Vec3<T>& c) { return Vec3<T>(nmsub(a.x,b.x,c.x),nmsub(a.y,b.y,c.y),nmsub(a.z,b.z,c.z)); }
////////////////////////////////////////////////////////////////////////////////
/// Assignment Operators
////////////////////////////////////////////////////////////////////////////////
template<typename T> __forceinline Vec3<T>& operator +=( Vec3<T>& a, const T b ) { a.x += b; a.y += b; a.z += b; return a; }
template<typename T> __forceinline Vec3<T>& operator +=( Vec3<T>& a, const Vec3<T>& b ) { a.x += b.x; a.y += b.y; a.z += b.z; return a; }
template<typename T> __forceinline Vec3<T>& operator -=( Vec3<T>& a, const Vec3<T>& b ) { a.x -= b.x; a.y -= b.y; a.z -= b.z; return a; }
template<typename T> __forceinline Vec3<T>& operator *=( Vec3<T>& a, const T& b ) { a.x *= b ; a.y *= b ; a.z *= b ; return a; }
template<typename T> __forceinline Vec3<T>& operator /=( Vec3<T>& a, const T& b ) { a.x /= b ; a.y /= b ; a.z /= b ; return a; }
template<typename T> __forceinline const Vec3<T>& operator +=( Vec3<T>& a, const T b ) { a.x += b; a.y += b; a.z += b; return a; }
template<typename T> __forceinline const Vec3<T>& operator +=( Vec3<T>& a, const Vec3<T>& b ) { a.x += b.x; a.y += b.y; a.z += b.z; return a; }
template<typename T> __forceinline const Vec3<T>& operator -=( Vec3<T>& a, const Vec3<T>& b ) { a.x -= b.x; a.y -= b.y; a.z -= b.z; return a; }
template<typename T> __forceinline const Vec3<T>& operator *=( Vec3<T>& a, const T& b ) { a.x *= b ; a.y *= b ; a.z *= b ; return a; }
template<typename T> __forceinline const Vec3<T>& operator /=( Vec3<T>& a, const T& b ) { a.x /= b ; a.y /= b ; a.z /= b ; return a; }
////////////////////////////////////////////////////////////////////////////////
/// Reduction Operators
@@ -162,7 +157,7 @@ namespace embree
template<typename T>
__forceinline Vec3<T> lerp(const Vec3<T>& v0, const Vec3<T>& v1, const T& t) {
return madd(Vec3<T>(T(1.0f)-t),v0,t*v1);
return (T(1.0f)-t)*v0 + t*v1;
}
template<typename T> __forceinline int maxDim ( const Vec3<T>& a )
@@ -213,7 +208,7 @@ namespace embree
template<typename T> __forceinline T sum ( const Vec3<T>& a ) { return a.x+a.y+a.z; }
template<typename T> __forceinline T halfArea ( const Vec3<T>& d ) { return madd(d.x,(d.y+d.z),d.y*d.z); }
template<typename T> __forceinline T halfArea ( const Vec3<T>& d ) { return d.x*(d.y+d.z)+d.y*d.z; }
template<typename T> __forceinline T area ( const Vec3<T>& d ) { return 2.0f*halfArea(d); }
template<typename T> __forceinline Vec3<T> normalize_safe( const Vec3<T>& a ) {
@@ -270,70 +265,61 @@ namespace embree
namespace embree
{
template<typename Out, typename In>
__forceinline Vec3<Out> broadcast(const Vec3<In>& a, const size_t k) {
return Vec3<Out>(Out(a.x[k]), Out(a.y[k]), Out(a.z[k]));
__forceinline Vec3<Out> broadcast(const Vec3<In>& a, const size_t k) {
return Vec3<Out>(Out(a.x[k]),Out(a.y[k]),Out(a.z[k]));
}
template<> __forceinline Vec3<float>::Vec3(const Vec3fa& a) { x = a.x; y = a.y; z = a.z; }
template<> __forceinline Vec3<float>::Vec3( const Vec3fa& a ) { x = a.x; y = a.y; z = a.z; }
#if defined(__AVX__)
template<> __forceinline Vec3<vfloat4>::Vec3(const Vec3fa& a) {
x = a.x; y = a.y; z = a.z;
}
#elif defined(__SSE__)
template<>
__forceinline Vec3<vfloat4>::Vec3(const Vec3fa& a) {
#if defined (__SSE__)
template<> __forceinline Vec3<vfloat4>::Vec3( const Vec3fa& a ) {
const vfloat4 v = vfloat4(a); x = shuffle<0,0,0,0>(v); y = shuffle<1,1,1,1>(v); z = shuffle<2,2,2,2>(v);
}
#endif
#if defined(__SSE__)
__forceinline Vec3<vfloat4> broadcast4f(const Vec3<vfloat4>& a, const size_t k) {
__forceinline Vec3<vfloat4> broadcast4f( const Vec3<vfloat4>& a, const size_t k ) {
return Vec3<vfloat4>(vfloat4::broadcast(&a.x[k]), vfloat4::broadcast(&a.y[k]), vfloat4::broadcast(&a.z[k]));
}
template<>
__forceinline Vec3<vfloat4> broadcast<vfloat4,vfloat4>(const Vec3<vfloat4>& a, const size_t k) {
__forceinline Vec3<vfloat4> broadcast<vfloat4,vfloat4>( const Vec3<vfloat4>& a, const size_t k ) {
return Vec3<vfloat4>(vfloat4::broadcast(&a.x[k]), vfloat4::broadcast(&a.y[k]), vfloat4::broadcast(&a.z[k]));
}
template<int i0, int i1, int i2, int i3>
__forceinline Vec3<vfloat4> shuffle(const Vec3<vfloat4>& b) {
return Vec3<vfloat4>(shuffle<i0,i1,i2,i3>(b.x), shuffle<i0,i1,i2,i3>(b.y), shuffle<i0,i1,i2,i3>(b.z));
template<size_t i0, size_t i1, size_t i2, size_t i3> __forceinline const Vec3<vfloat4> shuffle( const Vec3<vfloat4>& b ) {
return Vec3<vfloat4>(shuffle<i0,i1,i2,i3>(b.x),shuffle<i0,i1,i2,i3>(b.y),shuffle<i0,i1,i2,i3>(b.z));
}
#endif
#if defined(__AVX__)
template<>
__forceinline Vec3<vfloat8>::Vec3(const Vec3fa& a) {
template<> __forceinline Vec3<vfloat8>::Vec3( const Vec3fa& a ) {
x = a.x; y = a.y; z = a.z;
}
__forceinline Vec3<vfloat4> broadcast4f(const Vec3<vfloat8>& a, const size_t k) {
__forceinline Vec3<vfloat4> broadcast4f( const Vec3<vfloat8>& a, const size_t k ) {
return Vec3<vfloat4>(vfloat4::broadcast(&a.x[k]), vfloat4::broadcast(&a.y[k]), vfloat4::broadcast(&a.z[k]));
}
__forceinline Vec3<vfloat8> broadcast8f(const Vec3<vfloat4>& a, const size_t k) {
__forceinline Vec3<vfloat8> broadcast8f( const Vec3<vfloat4>& a, const size_t k ) {
return Vec3<vfloat8>(vfloat8::broadcast(&a.x[k]), vfloat8::broadcast(&a.y[k]), vfloat8::broadcast(&a.z[k]));
}
__forceinline Vec3<vfloat8> broadcast8f(const Vec3<vfloat8>& a, const size_t k) {
__forceinline Vec3<vfloat8> broadcast8f( const Vec3<vfloat8>& a, const size_t k ) {
return Vec3<vfloat8>(vfloat8::broadcast(&a.x[k]), vfloat8::broadcast(&a.y[k]), vfloat8::broadcast(&a.z[k]));
}
template<>
__forceinline Vec3<vfloat8> broadcast<vfloat8,vfloat4>(const Vec3<vfloat4>& a, const size_t k) {
__forceinline Vec3<vfloat8> broadcast<vfloat8,vfloat4>( const Vec3<vfloat4>& a, const size_t k ) {
return Vec3<vfloat8>(vfloat8::broadcast(&a.x[k]), vfloat8::broadcast(&a.y[k]), vfloat8::broadcast(&a.z[k]));
}
template<>
__forceinline Vec3<vfloat8> broadcast<vfloat8,vfloat8>(const Vec3<vfloat8>& a, const size_t k) {
__forceinline Vec3<vfloat8> broadcast<vfloat8,vfloat8>( const Vec3<vfloat8>& a, const size_t k ) {
return Vec3<vfloat8>(vfloat8::broadcast(&a.x[k]), vfloat8::broadcast(&a.y[k]), vfloat8::broadcast(&a.z[k]));
}
template<int i0, int i1, int i2, int i3>
__forceinline Vec3<vfloat8> shuffle(const Vec3<vfloat8>& b) {
return Vec3<vfloat8>(shuffle<i0,i1,i2,i3>(b.x), shuffle<i0,i1,i2,i3>(b.y), shuffle<i0,i1,i2,i3>(b.z));
template<size_t i0, size_t i1, size_t i2, size_t i3> __forceinline const Vec3<vfloat8> shuffle( const Vec3<vfloat8>& b ) {
return Vec3<vfloat8>(shuffle<i0,i1,i2,i3>(b.x),shuffle<i0,i1,i2,i3>(b.y),shuffle<i0,i1,i2,i3>(b.z));
}
#endif
#if defined(__AVX512F__)
template<> __forceinline Vec3<vfloat16>::Vec3(const Vec3fa& a) : x(a.x), y(a.y), z(a.z) {}
template<> __forceinline Vec3<vfloat16>::Vec3( const Vec3fa& a ) : x(a.x), y(a.y), z(a.z) {}
#endif
}
+10 -10
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
@@ -52,8 +52,8 @@ namespace embree
__forceinline Vec3ba( bool a, bool b, bool c)
: m128(_mm_lookupmask_ps[(size_t(c) << 2) | (size_t(b) << 1) | size_t(a)]) {}
__forceinline operator const __m128&() const { return m128; }
__forceinline operator __m128&() { return m128; }
__forceinline operator const __m128&( void ) const { return m128; }
__forceinline operator __m128&( void ) { return m128; }
////////////////////////////////////////////////////////////////////////////////
/// Constants
@@ -75,23 +75,23 @@ namespace embree
/// Unary Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline Vec3ba operator !( const Vec3ba& a ) { return _mm_xor_ps(a.m128, Vec3ba(embree::True)); }
__forceinline const Vec3ba operator !( const Vec3ba& a ) { return _mm_xor_ps(a.m128, Vec3ba(embree::True)); }
////////////////////////////////////////////////////////////////////////////////
/// Binary Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline Vec3ba operator &( const Vec3ba& a, const Vec3ba& b ) { return _mm_and_ps(a.m128, b.m128); }
__forceinline Vec3ba operator |( const Vec3ba& a, const Vec3ba& b ) { return _mm_or_ps (a.m128, b.m128); }
__forceinline Vec3ba operator ^( const Vec3ba& a, const Vec3ba& b ) { return _mm_xor_ps(a.m128, b.m128); }
__forceinline const Vec3ba operator &( const Vec3ba& a, const Vec3ba& b ) { return _mm_and_ps(a.m128, b.m128); }
__forceinline const Vec3ba operator |( const Vec3ba& a, const Vec3ba& b ) { return _mm_or_ps (a.m128, b.m128); }
__forceinline const Vec3ba operator ^( const Vec3ba& a, const Vec3ba& b ) { return _mm_xor_ps(a.m128, b.m128); }
////////////////////////////////////////////////////////////////////////////////
/// Assignment Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline Vec3ba& operator &=( Vec3ba& a, const Vec3ba& b ) { return a = a & b; }
__forceinline Vec3ba& operator |=( Vec3ba& a, const Vec3ba& b ) { return a = a | b; }
__forceinline Vec3ba& operator ^=( Vec3ba& a, const Vec3ba& b ) { return a = a ^ b; }
__forceinline const Vec3ba operator &=( Vec3ba& a, const Vec3ba& b ) { return a = a & b; }
__forceinline const Vec3ba operator |=( Vec3ba& a, const Vec3ba& b ) { return a = a | b; }
__forceinline const Vec3ba operator ^=( Vec3ba& a, const Vec3ba& b ) { return a = a ^ b; }
////////////////////////////////////////////////////////////////////////////////
/// Comparison Operators + Select
+34 -55
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
@@ -63,13 +63,13 @@ namespace embree
__forceinline explicit Vec3fa( const __m128i a ) : m128(_mm_cvtepi32_ps(a)) {}
__forceinline operator const __m128&() const { return m128; }
__forceinline operator __m128&() { return m128; }
__forceinline operator const __m128&( void ) const { return m128; }
__forceinline operator __m128&( void ) { return m128; }
#if defined (__SSE4_1__)
friend __forceinline Vec3fa copy_a( const Vec3fa& a, const Vec3fa& b ) { return _mm_insert_ps(a, b, (3 << 4) | (3 << 6)); }
friend __forceinline const Vec3fa copy_a( const Vec3fa& a, const Vec3fa& b ) { return _mm_insert_ps(a, b, (3 << 4) | (3 << 6)); }
#else
friend __forceinline Vec3fa copy_a( const Vec3fa& a, const Vec3fa& b ) { Vec3fa c = a; c.a = b.a; return c; }
friend __forceinline const Vec3fa copy_a( const Vec3fa& a, const Vec3fa& b ) { Vec3fa c = a; c.a = b.a; return c; }
#endif
////////////////////////////////////////////////////////////////////////////////
@@ -109,54 +109,38 @@ namespace embree
/// Unary Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline Vec3fa operator +( const Vec3fa& a ) { return a; }
__forceinline Vec3fa operator -( const Vec3fa& a ) {
__forceinline const Vec3fa operator +( const Vec3fa& a ) { return a; }
__forceinline const Vec3fa operator -( const Vec3fa& a ) {
const __m128 mask = _mm_castsi128_ps(_mm_set1_epi32(0x80000000));
return _mm_xor_ps(a.m128, mask);
}
__forceinline Vec3fa abs ( const Vec3fa& a ) {
__forceinline const Vec3fa abs ( const Vec3fa& a ) {
const __m128 mask = _mm_castsi128_ps(_mm_set1_epi32(0x7fffffff));
return _mm_and_ps(a.m128, mask);
}
__forceinline Vec3fa sign ( const Vec3fa& a ) {
__forceinline const Vec3fa sign ( const Vec3fa& a ) {
return blendv_ps(Vec3fa(one), -Vec3fa(one), _mm_cmplt_ps (a,Vec3fa(zero)));
}
__forceinline Vec3fa rcp ( const Vec3fa& a )
{
#if defined(__AVX512VL__)
const Vec3fa r = _mm_rcp14_ps(a.m128);
#else
__forceinline const Vec3fa rcp ( const Vec3fa& a ) {
const Vec3fa r = _mm_rcp_ps(a.m128);
#endif
#if defined(__AVX2__)
const Vec3fa res = _mm_mul_ps(r,_mm_fnmadd_ps(r, a, vfloat4(2.0f)));
#else
const Vec3fa res = _mm_mul_ps(r,_mm_sub_ps(vfloat4(2.0f), _mm_mul_ps(r, a)));
//return _mm_sub_ps(_mm_add_ps(r, r), _mm_mul_ps(_mm_mul_ps(r, r), a));
#endif
return res;
}
__forceinline Vec3fa sqrt ( const Vec3fa& a ) { return _mm_sqrt_ps(a.m128); }
__forceinline Vec3fa sqr ( const Vec3fa& a ) { return _mm_mul_ps(a,a); }
__forceinline Vec3fa rsqrt( const Vec3fa& a )
{
#if defined(__AVX512VL__)
__m128 r = _mm_rsqrt14_ps(a.m128);
#else
__forceinline const Vec3fa sqrt ( const Vec3fa& a ) { return _mm_sqrt_ps(a.m128); }
__forceinline const Vec3fa sqr ( const Vec3fa& a ) { return _mm_mul_ps(a,a); }
__forceinline const Vec3fa rsqrt( const Vec3fa& a ) {
__m128 r = _mm_rsqrt_ps(a.m128);
#endif
return _mm_add_ps(_mm_mul_ps(_mm_set1_ps(1.5f),r), _mm_mul_ps(_mm_mul_ps(_mm_mul_ps(a, _mm_set1_ps(-0.5f)), r), _mm_mul_ps(r, r)));
}
__forceinline Vec3fa zero_fix(const Vec3fa& a) {
__forceinline const Vec3fa zero_fix(const Vec3fa& a) {
return blendv_ps(a, _mm_set1_ps(min_rcp_input), _mm_cmplt_ps (abs(a).m128, _mm_set1_ps(min_rcp_input)));
}
__forceinline Vec3fa rcp_safe(const Vec3fa& a) {
__forceinline const Vec3fa rcp_safe(const Vec3fa& a) {
return rcp(zero_fix(a));
}
__forceinline Vec3fa log ( const Vec3fa& a ) {
@@ -171,17 +155,17 @@ namespace embree
/// Binary Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline Vec3fa operator +( const Vec3fa& a, const Vec3fa& b ) { return _mm_add_ps(a.m128, b.m128); }
__forceinline Vec3fa operator -( const Vec3fa& a, const Vec3fa& b ) { return _mm_sub_ps(a.m128, b.m128); }
__forceinline Vec3fa operator *( const Vec3fa& a, const Vec3fa& b ) { return _mm_mul_ps(a.m128, b.m128); }
__forceinline Vec3fa operator *( const Vec3fa& a, const float b ) { return a * Vec3fa(b); }
__forceinline Vec3fa operator *( const float a, const Vec3fa& b ) { return Vec3fa(a) * b; }
__forceinline Vec3fa operator /( const Vec3fa& a, const Vec3fa& b ) { return _mm_div_ps(a.m128,b.m128); }
__forceinline Vec3fa operator /( const Vec3fa& a, const float b ) { return _mm_div_ps(a.m128,_mm_set1_ps(b)); }
__forceinline Vec3fa operator /( const float a, const Vec3fa& b ) { return _mm_div_ps(_mm_set1_ps(a),b.m128); }
__forceinline const Vec3fa operator +( const Vec3fa& a, const Vec3fa& b ) { return _mm_add_ps(a.m128, b.m128); }
__forceinline const Vec3fa operator -( const Vec3fa& a, const Vec3fa& b ) { return _mm_sub_ps(a.m128, b.m128); }
__forceinline const Vec3fa operator *( const Vec3fa& a, const Vec3fa& b ) { return _mm_mul_ps(a.m128, b.m128); }
__forceinline const Vec3fa operator *( const Vec3fa& a, const float b ) { return a * Vec3fa(b); }
__forceinline const Vec3fa operator *( const float a, const Vec3fa& b ) { return Vec3fa(a) * b; }
__forceinline const Vec3fa operator /( const Vec3fa& a, const Vec3fa& b ) { return _mm_div_ps(a.m128,b.m128); }
__forceinline const Vec3fa operator /( const Vec3fa& a, const float b ) { return _mm_div_ps(a.m128,_mm_set1_ps(b)); }
__forceinline const Vec3fa operator /( const float a, const Vec3fa& b ) { return _mm_div_ps(_mm_set1_ps(a),b.m128); }
__forceinline Vec3fa min( const Vec3fa& a, const Vec3fa& b ) { return _mm_min_ps(a.m128,b.m128); }
__forceinline Vec3fa max( const Vec3fa& a, const Vec3fa& b ) { return _mm_max_ps(a.m128,b.m128); }
__forceinline const Vec3fa min( const Vec3fa& a, const Vec3fa& b ) { return _mm_min_ps(a.m128,b.m128); }
__forceinline const Vec3fa max( const Vec3fa& a, const Vec3fa& b ) { return _mm_max_ps(a.m128,b.m128); }
#if defined(__SSE4_1__)
__forceinline Vec3fa mini(const Vec3fa& a, const Vec3fa& b) {
@@ -221,11 +205,6 @@ namespace embree
__forceinline Vec3fa nmsub ( const Vec3fa& a, const Vec3fa& b, const Vec3fa& c) { return -a*b-c; }
#endif
__forceinline Vec3fa madd ( const float a, const Vec3fa& b, const Vec3fa& c) { return madd(Vec3fa(a),b,c); }
__forceinline Vec3fa msub ( const float a, const Vec3fa& b, const Vec3fa& c) { return msub(Vec3fa(a),b,c); }
__forceinline Vec3fa nmadd ( const float a, const Vec3fa& b, const Vec3fa& c) { return nmadd(Vec3fa(a),b,c); }
__forceinline Vec3fa nmsub ( const float a, const Vec3fa& b, const Vec3fa& c) { return nmsub(Vec3fa(a),b,c); }
////////////////////////////////////////////////////////////////////////////////
/// Assignment Operators
////////////////////////////////////////////////////////////////////////////////
@@ -297,7 +276,7 @@ namespace embree
__forceinline float length ( const Vec3fa& a ) { return sqrt(dot(a,a)); }
__forceinline Vec3fa normalize( const Vec3fa& a ) { return a*rsqrt(dot(a,a)); }
__forceinline float distance ( const Vec3fa& a, const Vec3fa& b ) { return length(a-b); }
__forceinline float halfArea ( const Vec3fa& d ) { return madd(d.x,(d.y+d.z),d.y*d.z); }
__forceinline float halfArea ( const Vec3fa& d ) { return d.x*(d.y+d.z)+d.y*d.z; }
__forceinline float area ( const Vec3fa& d ) { return 2.0f*halfArea(d); }
__forceinline Vec3fa normalize_safe( const Vec3fa& a ) {
@@ -316,12 +295,12 @@ namespace embree
/// Select
////////////////////////////////////////////////////////////////////////////////
__forceinline Vec3fa select( bool s, const Vec3fa& t, const Vec3fa& f ) {
__forceinline const Vec3fa select( bool s, const Vec3fa& t, const Vec3fa& f ) {
__m128 mask = s ? _mm_castsi128_ps(_mm_cmpeq_epi32(_mm_setzero_si128(), _mm_setzero_si128())) : _mm_setzero_ps();
return blendv_ps(f, t, mask);
}
__forceinline Vec3fa select( const Vec3ba& s, const Vec3fa& t, const Vec3fa& f ) {
__forceinline const Vec3fa select( const Vec3ba& s, const Vec3fa& t, const Vec3fa& f ) {
return blendv_ps(f, t, s);
}
@@ -340,13 +319,13 @@ namespace embree
////////////////////////////////////////////////////////////////////////////////
#if defined (__SSE4_1__)
//__forceinline Vec3fa trunc( const Vec3fa& a ) { return _mm_round_ps(a, _MM_FROUND_TO_NEAREST_INT); }
__forceinline Vec3fa floor( const Vec3fa& a ) { return _mm_round_ps(a, _MM_FROUND_TO_NEG_INF ); }
__forceinline Vec3fa ceil ( const Vec3fa& a ) { return _mm_round_ps(a, _MM_FROUND_TO_POS_INF ); }
//__forceinline const Vec3fa trunc( const Vec3fa& a ) { return _mm_round_ps(a, _MM_FROUND_TO_NEAREST_INT); }
__forceinline const Vec3fa floor( const Vec3fa& a ) { return _mm_round_ps(a, _MM_FROUND_TO_NEG_INF ); }
__forceinline const Vec3fa ceil ( const Vec3fa& a ) { return _mm_round_ps(a, _MM_FROUND_TO_POS_INF ); }
#else
//__forceinline Vec3fa trunc( const Vec3fa& a ) { return Vec3fa(truncf(a.x),truncf(a.y),truncf(a.z)); }
__forceinline Vec3fa floor( const Vec3fa& a ) { return Vec3fa(floorf(a.x),floorf(a.y),floorf(a.z)); }
__forceinline Vec3fa ceil ( const Vec3fa& a ) { return Vec3fa(ceilf (a.x),ceilf (a.y),ceilf (a.z)); }
//__forceinline const Vec3fa trunc( const Vec3fa& a ) { return Vec3fa(truncf(a.x),truncf(a.y),truncf(a.z)); }
__forceinline const Vec3fa floor( const Vec3fa& a ) { return Vec3fa(floorf(a.x),floorf(a.y),floorf(a.z)); }
__forceinline const Vec3fa ceil ( const Vec3fa& a ) { return Vec3fa(ceilf (a.x),ceilf (a.y),ceilf (a.z)); }
#endif
////////////////////////////////////////////////////////////////////////////////
+34 -34
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
@@ -51,8 +51,8 @@ namespace embree
__forceinline Vec3ia( const int x, const int y, const int z) : m128(_mm_set_epi32(z, z, y, x)) {}
__forceinline explicit Vec3ia( const __m128 a ) : m128(_mm_cvtps_epi32(a)) {}
__forceinline operator const __m128i&() const { return m128; }
__forceinline operator __m128i&() { return m128; }
__forceinline operator const __m128i&( void ) const { return m128; }
__forceinline operator __m128i&( void ) { return m128; }
////////////////////////////////////////////////////////////////////////////////
/// Constants
@@ -76,48 +76,48 @@ namespace embree
/// Unary Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline Vec3ia operator +( const Vec3ia& a ) { return a; }
__forceinline Vec3ia operator -( const Vec3ia& a ) { return _mm_sub_epi32(_mm_setzero_si128(), a.m128); }
__forceinline const Vec3ia operator +( const Vec3ia& a ) { return a; }
__forceinline const Vec3ia operator -( const Vec3ia& a ) { return _mm_sub_epi32(_mm_setzero_si128(), a.m128); }
#if defined(__SSSE3__)
__forceinline Vec3ia abs ( const Vec3ia& a ) { return _mm_abs_epi32(a.m128); }
__forceinline const Vec3ia abs ( const Vec3ia& a ) { return _mm_abs_epi32(a.m128); }
#endif
////////////////////////////////////////////////////////////////////////////////
/// Binary Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline Vec3ia operator +( const Vec3ia& a, const Vec3ia& b ) { return _mm_add_epi32(a.m128, b.m128); }
__forceinline Vec3ia operator +( const Vec3ia& a, const int b ) { return a+Vec3ia(b); }
__forceinline Vec3ia operator +( const int a, const Vec3ia& b ) { return Vec3ia(a)+b; }
__forceinline const Vec3ia operator +( const Vec3ia& a, const Vec3ia& b ) { return _mm_add_epi32(a.m128, b.m128); }
__forceinline const Vec3ia operator +( const Vec3ia& a, const int b ) { return a+Vec3ia(b); }
__forceinline const Vec3ia operator +( const int a, const Vec3ia& b ) { return Vec3ia(a)+b; }
__forceinline Vec3ia operator -( const Vec3ia& a, const Vec3ia& b ) { return _mm_sub_epi32(a.m128, b.m128); }
__forceinline Vec3ia operator -( const Vec3ia& a, const int b ) { return a-Vec3ia(b); }
__forceinline Vec3ia operator -( const int a, const Vec3ia& b ) { return Vec3ia(a)-b; }
__forceinline const Vec3ia operator -( const Vec3ia& a, const Vec3ia& b ) { return _mm_sub_epi32(a.m128, b.m128); }
__forceinline const Vec3ia operator -( const Vec3ia& a, const int b ) { return a-Vec3ia(b); }
__forceinline const Vec3ia operator -( const int a, const Vec3ia& b ) { return Vec3ia(a)-b; }
#if defined(__SSE4_1__)
__forceinline Vec3ia operator *( const Vec3ia& a, const Vec3ia& b ) { return _mm_mullo_epi32(a.m128, b.m128); }
__forceinline Vec3ia operator *( const Vec3ia& a, const int b ) { return a * Vec3ia(b); }
__forceinline Vec3ia operator *( const int a, const Vec3ia& b ) { return Vec3ia(a) * b; }
__forceinline const Vec3ia operator *( const Vec3ia& a, const Vec3ia& b ) { return _mm_mullo_epi32(a.m128, b.m128); }
__forceinline const Vec3ia operator *( const Vec3ia& a, const int b ) { return a * Vec3ia(b); }
__forceinline const Vec3ia operator *( const int a, const Vec3ia& b ) { return Vec3ia(a) * b; }
#endif
__forceinline Vec3ia operator &( const Vec3ia& a, const Vec3ia& b ) { return _mm_and_si128(a.m128, b.m128); }
__forceinline Vec3ia operator &( const Vec3ia& a, const int b ) { return a & Vec3ia(b); }
__forceinline Vec3ia operator &( const int a, const Vec3ia& b ) { return Vec3ia(a) & b; }
__forceinline const Vec3ia operator &( const Vec3ia& a, const Vec3ia& b ) { return _mm_and_si128(a.m128, b.m128); }
__forceinline const Vec3ia operator &( const Vec3ia& a, const int b ) { return a & Vec3ia(b); }
__forceinline const Vec3ia operator &( const int a, const Vec3ia& b ) { return Vec3ia(a) & b; }
__forceinline Vec3ia operator |( const Vec3ia& a, const Vec3ia& b ) { return _mm_or_si128(a.m128, b.m128); }
__forceinline Vec3ia operator |( const Vec3ia& a, const int b ) { return a | Vec3ia(b); }
__forceinline Vec3ia operator |( const int a, const Vec3ia& b ) { return Vec3ia(a) | b; }
__forceinline const Vec3ia operator |( const Vec3ia& a, const Vec3ia& b ) { return _mm_or_si128(a.m128, b.m128); }
__forceinline const Vec3ia operator |( const Vec3ia& a, const int b ) { return a | Vec3ia(b); }
__forceinline const Vec3ia operator |( const int a, const Vec3ia& b ) { return Vec3ia(a) | b; }
__forceinline Vec3ia operator ^( const Vec3ia& a, const Vec3ia& b ) { return _mm_xor_si128(a.m128, b.m128); }
__forceinline Vec3ia operator ^( const Vec3ia& a, const int b ) { return a ^ Vec3ia(b); }
__forceinline Vec3ia operator ^( const int a, const Vec3ia& b ) { return Vec3ia(a) ^ b; }
__forceinline const Vec3ia operator ^( const Vec3ia& a, const Vec3ia& b ) { return _mm_xor_si128(a.m128, b.m128); }
__forceinline const Vec3ia operator ^( const Vec3ia& a, const int b ) { return a ^ Vec3ia(b); }
__forceinline const Vec3ia operator ^( const int a, const Vec3ia& b ) { return Vec3ia(a) ^ b; }
__forceinline Vec3ia operator <<( const Vec3ia& a, const int n ) { return _mm_slli_epi32(a.m128, n); }
__forceinline Vec3ia operator >>( const Vec3ia& a, const int n ) { return _mm_srai_epi32(a.m128, n); }
__forceinline const Vec3ia operator <<( const Vec3ia& a, const int n ) { return _mm_slli_epi32(a.m128, n); }
__forceinline const Vec3ia operator >>( const Vec3ia& a, const int n ) { return _mm_srai_epi32(a.m128, n); }
__forceinline Vec3ia sll ( const Vec3ia& a, const int b ) { return _mm_slli_epi32(a.m128, b); }
__forceinline Vec3ia sra ( const Vec3ia& a, const int b ) { return _mm_srai_epi32(a.m128, b); }
__forceinline Vec3ia srl ( const Vec3ia& a, const int b ) { return _mm_srli_epi32(a.m128, b); }
__forceinline const Vec3ia sll ( const Vec3ia& a, const int b ) { return _mm_slli_epi32(a.m128, b); }
__forceinline const Vec3ia sra ( const Vec3ia& a, const int b ) { return _mm_srai_epi32(a.m128, b); }
__forceinline const Vec3ia srl ( const Vec3ia& a, const int b ) { return _mm_srli_epi32(a.m128, b); }
////////////////////////////////////////////////////////////////////////////////
/// Assignment Operators
@@ -173,7 +173,7 @@ namespace embree
/// Select
////////////////////////////////////////////////////////////////////////////////
__forceinline Vec3ia select( const Vec3ba& m, const Vec3ia& t, const Vec3ia& f ) {
__forceinline const Vec3ia select( const Vec3ba& m, const Vec3ia& t, const Vec3ia& f ) {
#if defined(__SSE4_1__)
return _mm_castps_si128(_mm_blendv_ps(_mm_castsi128_ps(f), _mm_castsi128_ps(t), m));
#else
@@ -182,11 +182,11 @@ namespace embree
}
#if defined(__SSE4_1__)
__forceinline Vec3ia min( const Vec3ia& a, const Vec3ia& b ) { return _mm_min_epi32(a.m128,b.m128); }
__forceinline Vec3ia max( const Vec3ia& a, const Vec3ia& b ) { return _mm_max_epi32(a.m128,b.m128); }
__forceinline const Vec3ia min( const Vec3ia& a, const Vec3ia& b ) { return _mm_min_epi32(a.m128,b.m128); }
__forceinline const Vec3ia max( const Vec3ia& a, const Vec3ia& b ) { return _mm_max_epi32(a.m128,b.m128); }
#else
__forceinline Vec3ia min( const Vec3ia& a, const Vec3ia& b ) { return select(lt_mask(a,b),a,b); }
__forceinline Vec3ia max( const Vec3ia& a, const Vec3ia& b ) { return select(gt_mask(a,b),a,b); }
__forceinline const Vec3ia min( const Vec3ia& a, const Vec3ia& b ) { return select(lt_mask(a,b),a,b); }
__forceinline const Vec3ia max( const Vec3ia& a, const Vec3ia& b ) { return select(gt_mask(a,b),a,b); }
#endif
////////////////////////////////////////////////////////////////////////////////
+2 -28
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
@@ -95,20 +95,6 @@ namespace embree
template<typename T> __forceinline Vec4<T> min(const Vec4<T>& a, const Vec4<T>& b) { return Vec4<T>(min(a.x, b.x), min(a.y, b.y), min(a.z, b.z), min(a.w, b.w)); }
template<typename T> __forceinline Vec4<T> max(const Vec4<T>& a, const Vec4<T>& b) { return Vec4<T>(max(a.x, b.x), max(a.y, b.y), max(a.z, b.z), max(a.w, b.w)); }
////////////////////////////////////////////////////////////////////////////////
/// Ternary Operators
////////////////////////////////////////////////////////////////////////////////
template<typename T> __forceinline Vec4<T> madd ( const Vec4<T>& a, const Vec4<T>& b, const Vec4<T>& c) { return Vec4<T>( madd(a.x,b.x,c.x), madd(a.y,b.y,c.y), madd(a.z,b.z,c.z), madd(a.w,b.w,c.w)); }
template<typename T> __forceinline Vec4<T> msub ( const Vec4<T>& a, const Vec4<T>& b, const Vec4<T>& c) { return Vec4<T>( msub(a.x,b.x,c.x), msub(a.y,b.y,c.y), msub(a.z,b.z,c.z), msub(a.w,b.w,c.w)); }
template<typename T> __forceinline Vec4<T> nmadd ( const Vec4<T>& a, const Vec4<T>& b, const Vec4<T>& c) { return Vec4<T>(nmadd(a.x,b.x,c.x),nmadd(a.y,b.y,c.y),nmadd(a.z,b.z,c.z),nmadd(a.w,b.w,c.w)); }
template<typename T> __forceinline Vec4<T> nmsub ( const Vec4<T>& a, const Vec4<T>& b, const Vec4<T>& c) { return Vec4<T>(nmsub(a.x,b.x,c.x),nmsub(a.y,b.y,c.y),nmsub(a.z,b.z,c.z),nmsub(a.w,b.w,c.w)); }
template<typename T> __forceinline Vec4<T> madd ( const T& a, const Vec4<T>& b, const Vec4<T>& c) { return Vec4<T>( madd(a,b.x,c.x), madd(a,b.y,c.y), madd(a,b.z,c.z), madd(a,b.w,c.w)); }
template<typename T> __forceinline Vec4<T> msub ( const T& a, const Vec4<T>& b, const Vec4<T>& c) { return Vec4<T>( msub(a,b.x,c.x), msub(a,b.y,c.y), msub(a,b.z,c.z), msub(a,b.w,c.w)); }
template<typename T> __forceinline Vec4<T> nmadd ( const T& a, const Vec4<T>& b, const Vec4<T>& c) { return Vec4<T>(nmadd(a,b.x,c.x),nmadd(a,b.y,c.y),nmadd(a,b.z,c.z),nmadd(a,b.w,c.w)); }
template<typename T> __forceinline Vec4<T> nmsub ( const T& a, const Vec4<T>& b, const Vec4<T>& c) { return Vec4<T>(nmsub(a,b.x,c.x),nmsub(a,b.y,c.y),nmsub(a,b.z,c.z),nmsub(a,b.w,c.w)); }
////////////////////////////////////////////////////////////////////////////////
/// Assignment Operators
////////////////////////////////////////////////////////////////////////////////
@@ -175,11 +161,6 @@ namespace embree
return Vec4<T>(select(s,t.x,f.x),select(s,t.y,f.y),select(s,t.z,f.z),select(s,t.w,f.w));
}
template<typename T>
__forceinline Vec4<T> lerp(const Vec4<T>& v0, const Vec4<T>& v1, const T& t) {
return madd(Vec4<T>(T(1.0f)-t),v0,t*v1);
}
////////////////////////////////////////////////////////////////////////////////
/// Output Operators
////////////////////////////////////////////////////////////////////////////////
@@ -222,17 +203,10 @@ namespace embree
{
template<> __forceinline Vec4<float>::Vec4( const Vec3fa& a ) { x = a.x; y = a.y; z = a.z; w = a.w; }
#if defined(__AVX__)
template<> __forceinline Vec4<vfloat4>::Vec4( const Vec3fa& a ) {
x = a.x; y = a.y; z = a.z; w = a.w;
}
#elif defined(__SSE__)
#if defined (__SSE__)
template<> __forceinline Vec4<vfloat4>::Vec4( const Vec3fa& a ) {
const vfloat4 v = vfloat4(a); x = shuffle<0,0,0,0>(v); y = shuffle<1,1,1,1>(v); z = shuffle<2,2,2,2>(v); w = shuffle<3,3,3,3>(v);
}
#endif
#if defined(__SSE__)
__forceinline Vec4<vfloat4> broadcast4f( const Vec4<vfloat4>& a, const size_t k ) {
return Vec4<vfloat4>(vfloat4::broadcast(&a.x[k]), vfloat4::broadcast(&a.y[k]), vfloat4::broadcast(&a.z[k]), vfloat4::broadcast(&a.w[k]));
}
+1 -1
View File
@@ -1,5 +1,5 @@
## ======================================================================== ##
## Copyright 2009-2017 Intel Corporation ##
## Copyright 2009-2016 Intel Corporation ##
## ##
## Licensed under the Apache License, Version 2.0 (the "License"); ##
## you may not use this file except in compliance with the License. ##
+2 -2
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
@@ -29,7 +29,7 @@
#if defined(__AVX2__)
#include "vint8_avx2.h"
#if defined(__X86_64__)
#include "vllong4_avx2.h"
#include "vlong4_avx2.h"
#endif
#else
#include "vint8_avx.h"
+71 -2
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
@@ -21,13 +21,18 @@
#include "../math/constants.h"
#include "varying.h"
#if !defined(_MM_SHUF_PERM)
#define _MM_SHUF_PERM(e3, e2, e1, e0) ((_MM_PERM_ENUM)((e3)*64 + (e2)*16 + (e1)*4 + (e0)))
#define _MM_SHUF_PERM_NONE _MM_SHUF_PERM(3,2,1,0)
#endif
#include "vboolf16_avx512.h"
#include "vint16_avx512.h"
#include "vfloat16_avx512.h"
#include "vuint16_avx512.h"
#include "vboold8_avx512.h"
#include "vllong8_avx512.h"
#include "vlong8_avx512.h"
#include "vdouble8_avx512.h"
namespace embree
@@ -39,6 +44,9 @@ namespace embree
#define PFHINT_L1 0
#define PFHINT_L2 1
#define PFHINT_NT 2
#define PFHINT_L1EX 3
#define PFHINT_L2EX 4
#define PFHINT_NTEX 5
template<const unsigned int mode>
__forceinline void prefetch(const void * __restrict__ const m)
@@ -49,5 +57,66 @@ namespace embree
_mm_prefetch((const char*)m,_MM_HINT_T1);
else if (mode == PFHINT_NT)
_mm_prefetch((const char*)m,_MM_HINT_NTA);
else if (mode == PFHINT_L1EX)
_mm_prefetch((const char*)m,_MM_HINT_ET0);
else if (mode == PFHINT_L2EX)
_mm_prefetch((const char*)m,_MM_HINT_ET2);
else if (mode == PFHINT_NTEX)
_mm_prefetch((const char*)m,_MM_HINT_ENTA);
}
__forceinline void gather_prefetch(const vboolf16 &m_active,
const void *const ptr,
const vint16 index,
const int mode = _MM_HINT_T2,
const _MM_INDEX_SCALE_ENUM scale = _MM_SCALE_4,
const _MM_UPCONV_PS_ENUM up = _MM_UPCONV_PS_NONE)
{
#if defined(__AVX512PF__)
_mm512_mask_prefetch_i32extgather_ps(index,m_active,ptr,up,scale,mode);
#endif
}
__forceinline void scatter_prefetch(const vboolf16 &m_active,
void *const ptr,
const vint16 index,
const int mode = _MM_HINT_ET2,
const _MM_INDEX_SCALE_ENUM scale = _MM_SCALE_4,
const _MM_UPCONV_PS_ENUM up = _MM_UPCONV_PS_NONE)
{
#if defined(__AVX512PF__)
_mm512_mask_prefetch_i32extscatter_ps(ptr,m_active,index,up,scale,mode);
#endif
}
template<const int D, const int C, const int B, const int A>
__forceinline vfloat16 lshuf(const vfloat16 &in)
{
return _mm512_permute4f128_ps(in,(_MM_PERM_ENUM)_MM_SHUF_PERM(D,C,B,A));
}
template<const int D, const int C, const int B, const int A>
__forceinline vfloat16 lshuf(const vboolf16 &mask, vfloat16 &dest, const vfloat16 &in)
{
return _mm512_mask_permute4f128_ps(dest,mask,in,(_MM_PERM_ENUM) _MM_SHUF_PERM(D,C,B,A));
}
template<const int lane>
__forceinline vfloat16 lane_shuffle_gather(const vfloat16 &v0,const vfloat16 &v1,const vfloat16 &v2,const vfloat16 &v3)
{
vfloat16 t = lshuf<lane,lane,lane,lane>(v0);
t = lshuf<lane,lane,lane,lane>(0xf0,t,v1);
t = lshuf<lane,lane,lane,lane>(0xf00,t,v2);
t = lshuf<lane,lane,lane,lane>(0xf000,t,v3);
return t;
}
__forceinline vint16 mul_uint64_t( const vint16& a, const vint16& b) {
const vint16 low = _mm512_mullo_epi32(a, b);
const vint16 high = _mm512_mulhi_epu32(a, b);
return select(0x5555,low,high);
}
}
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
@@ -74,8 +74,8 @@ namespace embree
template<typename Closure>
__forceinline void foreach2(int x0, int x1, int y0, int y1, const Closure& closure)
{
__aligned(64) int U[2*VSIZEX];
__aligned(64) int V[2*VSIZEX];
__aligned(64) int U[128];
__aligned(64) int V[128];
int index = 0;
for (int y=y0; y<y1; y++) {
const bool lasty = y+1>=y1;
+2 -3
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
@@ -16,8 +16,7 @@
#include "sse.h"
namespace embree
{
namespace embree {
const __m128 _mm_lookupmask_ps[16] = {
_mm_castsi128_ps(_mm_set_epi32( 0, 0, 0, 0)),
_mm_castsi128_ps(_mm_set_epi32( 0, 0, 0,-1)),
+4 -4
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
@@ -20,15 +20,16 @@
#include "../sys/intrinsics.h"
#include "../math/constants.h"
#include "varying.h"
#include "sse_special.h"
namespace embree
{
#if defined(__SSE4_1__)
__forceinline __m128 blendv_ps(__m128 f, __m128 t, __m128 mask) {
__forceinline __m128 blendv_ps( __m128 f, __m128 t, __m128 mask ) {
return _mm_blendv_ps(f,t,mask);
}
#else
__forceinline __m128 blendv_ps(__m128 f, __m128 t, __m128 mask) {
__forceinline __m128 blendv_ps( __m128 f, __m128 t, __m128 mask ) {
return _mm_or_ps(_mm_and_ps(mask, t), _mm_andnot_ps(mask, f));
}
#endif
@@ -43,5 +44,4 @@ namespace embree
#include "vboolf4_sse2.h"
#endif
#include "vint4_sse2.h"
#include "vuint4_sse2.h"
#include "vfloat4_sse2.h"
+761
View File
@@ -0,0 +1,761 @@
/* SIMD (SSE1+MMX or SSE2) implementation of sin, cos, exp and log
Inspired by Intel Approximate Math library, and based on the
corresponding algorithms of the cephes math library
The default is to use the SSE1 version. If you define USE_SSE2 the
the SSE2 intrinsics will be used in place of the MMX intrinsics. Do
not expect any significant performance improvement with SSE2.
*/
/* Copyright (C) 2007 Julien Pommier
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
(this is the zlib license)
*/
#include <xmmintrin.h>
/* yes I know, the top of this file is quite ugly */
#ifdef _MSC_VER /* visual c++ */
# define ALIGN16_BEG __declspec(align(16))
# define ALIGN16_END
# define USE_SSE2
#else /* gcc or icc */
# define ALIGN16_BEG
# define ALIGN16_END __attribute__((aligned(16)))
#endif
/* __m128 is ugly to write */
typedef __m128 v4sf; // vector of 4 float (sse1)
#ifdef USE_SSE2
# include <emmintrin.h>
typedef __m128i v4si; // vector of 4 int (sse2)
#else
typedef __m64 v2si; // vector of 2 int (mmx)
#endif
/* declare some SSE constants -- why can't I figure a better way to do that? */
#define _PS_CONST(Name, Val) \
static const ALIGN16_BEG float _ps_##Name[4] ALIGN16_END = { Val, Val, Val, Val }
#define _PI32_CONST(Name, Val) \
static const ALIGN16_BEG int _pi32_##Name[4] ALIGN16_END = { Val, Val, Val, Val }
#define _PS_CONST_TYPE(Name, Type, Val) \
static const ALIGN16_BEG Type _ps_##Name[4] ALIGN16_END = { Val, Val, Val, Val }
_PS_CONST(1 , 1.0f);
_PS_CONST(0p5, 0.5f);
/* the smallest non denormalized float number */
_PS_CONST_TYPE(min_norm_pos, int, int(0x00800000));
_PS_CONST_TYPE(mant_mask, int, int(0x7f800000));
_PS_CONST_TYPE(inv_mant_mask, int, int(~0x7f800000));
_PS_CONST_TYPE(sign_mask, int, int(0x80000000));
_PS_CONST_TYPE(inv_sign_mask, int, int(~0x80000000));
_PI32_CONST(1, 1);
_PI32_CONST(inv1, ~1);
_PI32_CONST(2, 2);
_PI32_CONST(4, 4);
_PI32_CONST(0x7f, 0x7f);
_PS_CONST(cephes_SQRTHF, 0.707106781186547524f);
_PS_CONST(cephes_log_p0, 7.0376836292E-2f);
_PS_CONST(cephes_log_p1, - 1.1514610310E-1f);
_PS_CONST(cephes_log_p2, 1.1676998740E-1f);
_PS_CONST(cephes_log_p3, - 1.2420140846E-1f);
_PS_CONST(cephes_log_p4, + 1.4249322787E-1f);
_PS_CONST(cephes_log_p5, - 1.6668057665E-1f);
_PS_CONST(cephes_log_p6, + 2.0000714765E-1f);
_PS_CONST(cephes_log_p7, - 2.4999993993E-1f);
_PS_CONST(cephes_log_p8, + 3.3333331174E-1f);
_PS_CONST(cephes_log_q1, -2.12194440e-4f);
_PS_CONST(cephes_log_q2, 0.693359375f);
#if defined (__MINGW32__)
/* the ugly part below: many versions of gcc used to be completely buggy with respect to some intrinsics
The movehl_ps is fixed in mingw 3.4.5, but I found out that all the _mm_cmp* intrinsics were completely
broken on my mingw gcc 3.4.5 ...
Note that the bug on _mm_cmp* does occur only at -O0 optimization level
*/
inline __m128 my_movehl_ps(__m128 a, const __m128 b) {
asm (
"movhlps %2,%0\n\t"
: "=x" (a)
: "0" (a), "x"(b)
);
return a; }
#warning "redefined _mm_movehl_ps (see gcc bug 21179)"
#define _mm_movehl_ps my_movehl_ps
inline __m128 my_cmplt_ps(__m128 a, const __m128 b) {
asm (
"cmpltps %2,%0\n\t"
: "=x" (a)
: "0" (a), "x"(b)
);
return a;
}
inline __m128 my_cmpgt_ps(__m128 a, const __m128 b) {
asm (
"cmpnleps %2,%0\n\t"
: "=x" (a)
: "0" (a), "x"(b)
);
return a;
}
inline __m128 my_cmpeq_ps(__m128 a, const __m128 b) {
asm (
"cmpeqps %2,%0\n\t"
: "=x" (a)
: "0" (a), "x"(b)
);
return a;
}
#warning "redefined _mm_cmpxx_ps functions..."
#define _mm_cmplt_ps my_cmplt_ps
#define _mm_cmpgt_ps my_cmpgt_ps
#define _mm_cmpeq_ps my_cmpeq_ps
#endif
#ifndef USE_SSE2
typedef union xmm_mm_union {
__m128 xmm;
__m64 mm[2];
} xmm_mm_union;
#define COPY_XMM_TO_MM(xmm_, mm0_, mm1_) { \
xmm_mm_union u; u.xmm = xmm_; \
mm0_ = u.mm[0]; \
mm1_ = u.mm[1]; \
}
#define COPY_MM_TO_XMM(mm0_, mm1_, xmm_) { \
xmm_mm_union u; u.mm[0]=mm0_; u.mm[1]=mm1_; xmm_ = u.xmm; \
}
#endif // USE_SSE2
/* natural logarithm computed for 4 simultaneous float
return NaN for x <= 0
*/
inline v4sf log_ps(v4sf x) {
#ifdef USE_SSE2
v4si emm0;
#else
v2si mm0, mm1;
#endif
v4sf one = *(v4sf*)_ps_1;
v4sf invalid_mask = _mm_cmple_ps(x, _mm_setzero_ps());
x = _mm_max_ps(x, *(v4sf*)_ps_min_norm_pos); /* cut off denormalized stuff */
#ifndef USE_SSE2
/* part 1: x = frexpf(x, &e); */
COPY_XMM_TO_MM(x, mm0, mm1);
mm0 = _mm_srli_pi32(mm0, 23);
mm1 = _mm_srli_pi32(mm1, 23);
#else
emm0 = _mm_srli_epi32(_mm_castps_si128(x), 23);
#endif
/* keep only the fractional part */
x = _mm_and_ps(x, *(v4sf*)_ps_inv_mant_mask);
x = _mm_or_ps(x, *(v4sf*)_ps_0p5);
#ifndef USE_SSE2
/* now e=mm0:mm1 contain the really base-2 exponent */
mm0 = _mm_sub_pi32(mm0, *(v2si*)_pi32_0x7f);
mm1 = _mm_sub_pi32(mm1, *(v2si*)_pi32_0x7f);
v4sf e = _mm_cvtpi32x2_ps(mm0, mm1);
_mm_empty(); /* bye bye mmx */
#else
emm0 = _mm_sub_epi32(emm0, *(v4si*)_pi32_0x7f);
v4sf e = _mm_cvtepi32_ps(emm0);
#endif
e = _mm_add_ps(e, one);
/* part2:
if( x < SQRTHF ) {
e -= 1;
x = x + x - 1.0;
} else { x = x - 1.0; }
*/
v4sf mask = _mm_cmplt_ps(x, *(v4sf*)_ps_cephes_SQRTHF);
v4sf tmp = _mm_and_ps(x, mask);
x = _mm_sub_ps(x, one);
e = _mm_sub_ps(e, _mm_and_ps(one, mask));
x = _mm_add_ps(x, tmp);
v4sf z = _mm_mul_ps(x,x);
v4sf y = *(v4sf*)_ps_cephes_log_p0;
y = _mm_mul_ps(y, x);
y = _mm_add_ps(y, *(v4sf*)_ps_cephes_log_p1);
y = _mm_mul_ps(y, x);
y = _mm_add_ps(y, *(v4sf*)_ps_cephes_log_p2);
y = _mm_mul_ps(y, x);
y = _mm_add_ps(y, *(v4sf*)_ps_cephes_log_p3);
y = _mm_mul_ps(y, x);
y = _mm_add_ps(y, *(v4sf*)_ps_cephes_log_p4);
y = _mm_mul_ps(y, x);
y = _mm_add_ps(y, *(v4sf*)_ps_cephes_log_p5);
y = _mm_mul_ps(y, x);
y = _mm_add_ps(y, *(v4sf*)_ps_cephes_log_p6);
y = _mm_mul_ps(y, x);
y = _mm_add_ps(y, *(v4sf*)_ps_cephes_log_p7);
y = _mm_mul_ps(y, x);
y = _mm_add_ps(y, *(v4sf*)_ps_cephes_log_p8);
y = _mm_mul_ps(y, x);
y = _mm_mul_ps(y, z);
tmp = _mm_mul_ps(e, *(v4sf*)_ps_cephes_log_q1);
y = _mm_add_ps(y, tmp);
tmp = _mm_mul_ps(z, *(v4sf*)_ps_0p5);
y = _mm_sub_ps(y, tmp);
tmp = _mm_mul_ps(e, *(v4sf*)_ps_cephes_log_q2);
x = _mm_add_ps(x, y);
x = _mm_add_ps(x, tmp);
x = _mm_or_ps(x, invalid_mask); // negative arg will be NAN
return x;
}
_PS_CONST(exp_hi, 88.3762626647949f);
_PS_CONST(exp_lo, -88.3762626647949f);
_PS_CONST(cephes_LOG2EF, 1.44269504088896341f);
_PS_CONST(cephes_exp_C1, 0.693359375f);
_PS_CONST(cephes_exp_C2, -2.12194440e-4f);
_PS_CONST(cephes_exp_p0, 1.9875691500E-4f);
_PS_CONST(cephes_exp_p1, 1.3981999507E-3f);
_PS_CONST(cephes_exp_p2, 8.3334519073E-3f);
_PS_CONST(cephes_exp_p3, 4.1665795894E-2f);
_PS_CONST(cephes_exp_p4, 1.6666665459E-1f);
_PS_CONST(cephes_exp_p5, 5.0000001201E-1f);
inline v4sf exp_ps(v4sf x) {
v4sf tmp = _mm_setzero_ps(), fx;
#ifdef USE_SSE2
v4si emm0;
#else
v2si mm0, mm1;
#endif
v4sf one = *(v4sf*)_ps_1;
x = _mm_min_ps(x, *(v4sf*)_ps_exp_hi);
x = _mm_max_ps(x, *(v4sf*)_ps_exp_lo);
/* express exp(x) as exp(g + n*log(2)) */
fx = _mm_mul_ps(x, *(v4sf*)_ps_cephes_LOG2EF);
fx = _mm_add_ps(fx, *(v4sf*)_ps_0p5);
/* how to perform a floorf with SSE: just below */
#ifndef USE_SSE2
/* step 1 : cast to int */
tmp = _mm_movehl_ps(tmp, fx);
mm0 = _mm_cvttps_pi32(fx);
mm1 = _mm_cvttps_pi32(tmp);
/* step 2 : cast back to float */
tmp = _mm_cvtpi32x2_ps(mm0, mm1);
#else
emm0 = _mm_cvttps_epi32(fx);
tmp = _mm_cvtepi32_ps(emm0);
#endif
/* if greater, substract 1 */
v4sf mask = _mm_cmpgt_ps(tmp, fx);
mask = _mm_and_ps(mask, one);
fx = _mm_sub_ps(tmp, mask);
tmp = _mm_mul_ps(fx, *(v4sf*)_ps_cephes_exp_C1);
v4sf z = _mm_mul_ps(fx, *(v4sf*)_ps_cephes_exp_C2);
x = _mm_sub_ps(x, tmp);
x = _mm_sub_ps(x, z);
z = _mm_mul_ps(x,x);
v4sf y = *(v4sf*)_ps_cephes_exp_p0;
y = _mm_mul_ps(y, x);
y = _mm_add_ps(y, *(v4sf*)_ps_cephes_exp_p1);
y = _mm_mul_ps(y, x);
y = _mm_add_ps(y, *(v4sf*)_ps_cephes_exp_p2);
y = _mm_mul_ps(y, x);
y = _mm_add_ps(y, *(v4sf*)_ps_cephes_exp_p3);
y = _mm_mul_ps(y, x);
y = _mm_add_ps(y, *(v4sf*)_ps_cephes_exp_p4);
y = _mm_mul_ps(y, x);
y = _mm_add_ps(y, *(v4sf*)_ps_cephes_exp_p5);
y = _mm_mul_ps(y, z);
y = _mm_add_ps(y, x);
y = _mm_add_ps(y, one);
/* build 2^n */
#ifndef USE_SSE2
z = _mm_movehl_ps(z, fx);
mm0 = _mm_cvttps_pi32(fx);
mm1 = _mm_cvttps_pi32(z);
mm0 = _mm_add_pi32(mm0, *(v2si*)_pi32_0x7f);
mm1 = _mm_add_pi32(mm1, *(v2si*)_pi32_0x7f);
mm0 = _mm_slli_pi32(mm0, 23);
mm1 = _mm_slli_pi32(mm1, 23);
v4sf pow2n;
COPY_MM_TO_XMM(mm0, mm1, pow2n);
_mm_empty();
#else
emm0 = _mm_cvttps_epi32(fx);
emm0 = _mm_add_epi32(emm0, *(v4si*)_pi32_0x7f);
emm0 = _mm_slli_epi32(emm0, 23);
v4sf pow2n = _mm_castsi128_ps(emm0);
#endif
y = _mm_mul_ps(y, pow2n);
return y;
}
_PS_CONST(minus_cephes_DP1, -0.78515625f);
_PS_CONST(minus_cephes_DP2, -2.4187564849853515625e-4f);
_PS_CONST(minus_cephes_DP3, -3.77489497744594108e-8f);
_PS_CONST(sincof_p0, -1.9515295891E-4f);
_PS_CONST(sincof_p1, 8.3321608736E-3f);
_PS_CONST(sincof_p2, -1.6666654611E-1f);
_PS_CONST(coscof_p0, 2.443315711809948E-005f);
_PS_CONST(coscof_p1, -1.388731625493765E-003f);
_PS_CONST(coscof_p2, 4.166664568298827E-002f);
_PS_CONST(cephes_FOPI, 1.27323954473516f); // 4 / M_PI
/* evaluation of 4 sines at onces, using only SSE1+MMX intrinsics so
it runs also on old athlons XPs and the pentium III of your grand
mother.
The code is the exact rewriting of the cephes sinf function.
Precision is excellent as long as x < 8192 (I did not bother to
take into account the special handling they have for greater values
-- it does not return garbage for arguments over 8192, though, but
the extra precision is missing).
Note that it is such that sinf((float)M_PI) = 8.74e-8, which is the
surprising but correct result.
Performance is also surprisingly good, 1.33 times faster than the
macos vsinf SSE2 function, and 1.5 times faster than the
__vrs4_sinf of amd's ACML (which is only available in 64 bits). Not
too bad for an SSE1 function (with no special tuning) !
However the latter libraries probably have a much better handling of NaN,
Inf, denormalized and other special arguments..
On my core 1 duo, the execution of this function takes approximately 95 cycles.
From what I have observed on the experiments with Intel AMath lib, switching to an
SSE2 version would improve the perf by only 10%.
Since it is based on SSE intrinsics, it has to be compiled at -O2 to
deliver full speed.
*/
inline v4sf sin_ps(v4sf x) { // any x
v4sf xmm1, xmm2 = _mm_setzero_ps(), xmm3, sign_bit, y;
#ifdef USE_SSE2
v4si emm0, emm2;
#else
v2si mm0, mm1, mm2, mm3;
#endif
sign_bit = x;
/* take the absolute value */
x = _mm_and_ps(x, *(v4sf*)_ps_inv_sign_mask);
/* extract the sign bit (upper one) */
sign_bit = _mm_and_ps(sign_bit, *(v4sf*)_ps_sign_mask);
/* scale by 4/Pi */
y = _mm_mul_ps(x, *(v4sf*)_ps_cephes_FOPI);
//printf("plop:"); print4(y);
#ifdef USE_SSE2
/* store the integer part of y in mm0 */
emm2 = _mm_cvttps_epi32(y);
/* j=(j+1) & (~1) (see the cephes sources) */
emm2 = _mm_add_epi32(emm2, *(v4si*)_pi32_1);
emm2 = _mm_and_si128(emm2, *(v4si*)_pi32_inv1);
y = _mm_cvtepi32_ps(emm2);
/* get the swap sign flag */
emm0 = _mm_and_si128(emm2, *(v4si*)_pi32_4);
emm0 = _mm_slli_epi32(emm0, 29);
/* get the polynom selection mask
there is one polynom for 0 <= x <= Pi/4
and another one for Pi/4<x<=Pi/2
Both branches will be computed.
*/
emm2 = _mm_and_si128(emm2, *(v4si*)_pi32_2);
emm2 = _mm_cmpeq_epi32(emm2, _mm_setzero_si128());
v4sf swap_sign_bit = _mm_castsi128_ps(emm0);
v4sf poly_mask = _mm_castsi128_ps(emm2);
sign_bit = _mm_xor_ps(sign_bit, swap_sign_bit);
#else
/* store the integer part of y in mm0:mm1 */
xmm2 = _mm_movehl_ps(xmm2, y);
mm2 = _mm_cvttps_pi32(y);
mm3 = _mm_cvttps_pi32(xmm2);
/* j=(j+1) & (~1) (see the cephes sources) */
mm2 = _mm_add_pi32(mm2, *(v2si*)_pi32_1);
mm3 = _mm_add_pi32(mm3, *(v2si*)_pi32_1);
mm2 = _mm_and_si64(mm2, *(v2si*)_pi32_inv1);
mm3 = _mm_and_si64(mm3, *(v2si*)_pi32_inv1);
y = _mm_cvtpi32x2_ps(mm2, mm3);
/* get the swap sign flag */
mm0 = _mm_and_si64(mm2, *(v2si*)_pi32_4);
mm1 = _mm_and_si64(mm3, *(v2si*)_pi32_4);
mm0 = _mm_slli_pi32(mm0, 29);
mm1 = _mm_slli_pi32(mm1, 29);
/* get the polynom selection mask */
mm2 = _mm_and_si64(mm2, *(v2si*)_pi32_2);
mm3 = _mm_and_si64(mm3, *(v2si*)_pi32_2);
mm2 = _mm_cmpeq_pi32(mm2, _mm_setzero_si64());
mm3 = _mm_cmpeq_pi32(mm3, _mm_setzero_si64());
v4sf swap_sign_bit, poly_mask;
COPY_MM_TO_XMM(mm0, mm1, swap_sign_bit);
COPY_MM_TO_XMM(mm2, mm3, poly_mask);
sign_bit = _mm_xor_ps(sign_bit, swap_sign_bit);
_mm_empty(); /* good-bye mmx */
#endif
/* The magic pass: "Extended precision modular arithmetic"
x = ((x - y * DP1) - y * DP2) - y * DP3; */
xmm1 = *(v4sf*)_ps_minus_cephes_DP1;
xmm2 = *(v4sf*)_ps_minus_cephes_DP2;
xmm3 = *(v4sf*)_ps_minus_cephes_DP3;
xmm1 = _mm_mul_ps(y, xmm1);
xmm2 = _mm_mul_ps(y, xmm2);
xmm3 = _mm_mul_ps(y, xmm3);
x = _mm_add_ps(x, xmm1);
x = _mm_add_ps(x, xmm2);
x = _mm_add_ps(x, xmm3);
/* Evaluate the first polynom (0 <= x <= Pi/4) */
y = *(v4sf*)_ps_coscof_p0;
v4sf z = _mm_mul_ps(x,x);
y = _mm_mul_ps(y, z);
y = _mm_add_ps(y, *(v4sf*)_ps_coscof_p1);
y = _mm_mul_ps(y, z);
y = _mm_add_ps(y, *(v4sf*)_ps_coscof_p2);
y = _mm_mul_ps(y, z);
y = _mm_mul_ps(y, z);
v4sf tmp = _mm_mul_ps(z, *(v4sf*)_ps_0p5);
y = _mm_sub_ps(y, tmp);
y = _mm_add_ps(y, *(v4sf*)_ps_1);
/* Evaluate the second polynom (Pi/4 <= x <= 0) */
v4sf y2 = *(v4sf*)_ps_sincof_p0;
y2 = _mm_mul_ps(y2, z);
y2 = _mm_add_ps(y2, *(v4sf*)_ps_sincof_p1);
y2 = _mm_mul_ps(y2, z);
y2 = _mm_add_ps(y2, *(v4sf*)_ps_sincof_p2);
y2 = _mm_mul_ps(y2, z);
y2 = _mm_mul_ps(y2, x);
y2 = _mm_add_ps(y2, x);
/* select the correct result from the two polynoms */
xmm3 = poly_mask;
y2 = _mm_and_ps(xmm3, y2); //, xmm3);
y = _mm_andnot_ps(xmm3, y);
y = _mm_add_ps(y,y2);
/* update the sign */
y = _mm_xor_ps(y, sign_bit);
return y;
}
/* almost the same as sin_ps */
inline v4sf cos_ps(v4sf x) { // any x
v4sf xmm1, xmm2 = _mm_setzero_ps(), xmm3, y;
#ifdef USE_SSE2
v4si emm0, emm2;
#else
v2si mm0, mm1, mm2, mm3;
#endif
/* take the absolute value */
x = _mm_and_ps(x, *(v4sf*)_ps_inv_sign_mask);
/* scale by 4/Pi */
y = _mm_mul_ps(x, *(v4sf*)_ps_cephes_FOPI);
#ifdef USE_SSE2
/* store the integer part of y in mm0 */
emm2 = _mm_cvttps_epi32(y);
/* j=(j+1) & (~1) (see the cephes sources) */
emm2 = _mm_add_epi32(emm2, *(v4si*)_pi32_1);
emm2 = _mm_and_si128(emm2, *(v4si*)_pi32_inv1);
y = _mm_cvtepi32_ps(emm2);
emm2 = _mm_sub_epi32(emm2, *(v4si*)_pi32_2);
/* get the swap sign flag */
emm0 = _mm_andnot_si128(emm2, *(v4si*)_pi32_4);
emm0 = _mm_slli_epi32(emm0, 29);
/* get the polynom selection mask */
emm2 = _mm_and_si128(emm2, *(v4si*)_pi32_2);
emm2 = _mm_cmpeq_epi32(emm2, _mm_setzero_si128());
v4sf sign_bit = _mm_castsi128_ps(emm0);
v4sf poly_mask = _mm_castsi128_ps(emm2);
#else
/* store the integer part of y in mm0:mm1 */
xmm2 = _mm_movehl_ps(xmm2, y);
mm2 = _mm_cvttps_pi32(y);
mm3 = _mm_cvttps_pi32(xmm2);
/* j=(j+1) & (~1) (see the cephes sources) */
mm2 = _mm_add_pi32(mm2, *(v2si*)_pi32_1);
mm3 = _mm_add_pi32(mm3, *(v2si*)_pi32_1);
mm2 = _mm_and_si64(mm2, *(v2si*)_pi32_inv1);
mm3 = _mm_and_si64(mm3, *(v2si*)_pi32_inv1);
y = _mm_cvtpi32x2_ps(mm2, mm3);
mm2 = _mm_sub_pi32(mm2, *(v2si*)_pi32_2);
mm3 = _mm_sub_pi32(mm3, *(v2si*)_pi32_2);
/* get the swap sign flag in mm0:mm1 and the
polynom selection mask in mm2:mm3 */
mm0 = _mm_andnot_si64(mm2, *(v2si*)_pi32_4);
mm1 = _mm_andnot_si64(mm3, *(v2si*)_pi32_4);
mm0 = _mm_slli_pi32(mm0, 29);
mm1 = _mm_slli_pi32(mm1, 29);
mm2 = _mm_and_si64(mm2, *(v2si*)_pi32_2);
mm3 = _mm_and_si64(mm3, *(v2si*)_pi32_2);
mm2 = _mm_cmpeq_pi32(mm2, _mm_setzero_si64());
mm3 = _mm_cmpeq_pi32(mm3, _mm_setzero_si64());
v4sf sign_bit, poly_mask;
COPY_MM_TO_XMM(mm0, mm1, sign_bit);
COPY_MM_TO_XMM(mm2, mm3, poly_mask);
_mm_empty(); /* good-bye mmx */
#endif
/* The magic pass: "Extended precision modular arithmetic"
x = ((x - y * DP1) - y * DP2) - y * DP3; */
xmm1 = *(v4sf*)_ps_minus_cephes_DP1;
xmm2 = *(v4sf*)_ps_minus_cephes_DP2;
xmm3 = *(v4sf*)_ps_minus_cephes_DP3;
xmm1 = _mm_mul_ps(y, xmm1);
xmm2 = _mm_mul_ps(y, xmm2);
xmm3 = _mm_mul_ps(y, xmm3);
x = _mm_add_ps(x, xmm1);
x = _mm_add_ps(x, xmm2);
x = _mm_add_ps(x, xmm3);
/* Evaluate the first polynom (0 <= x <= Pi/4) */
y = *(v4sf*)_ps_coscof_p0;
v4sf z = _mm_mul_ps(x,x);
y = _mm_mul_ps(y, z);
y = _mm_add_ps(y, *(v4sf*)_ps_coscof_p1);
y = _mm_mul_ps(y, z);
y = _mm_add_ps(y, *(v4sf*)_ps_coscof_p2);
y = _mm_mul_ps(y, z);
y = _mm_mul_ps(y, z);
v4sf tmp = _mm_mul_ps(z, *(v4sf*)_ps_0p5);
y = _mm_sub_ps(y, tmp);
y = _mm_add_ps(y, *(v4sf*)_ps_1);
/* Evaluate the second polynom (Pi/4 <= x <= 0) */
v4sf y2 = *(v4sf*)_ps_sincof_p0;
y2 = _mm_mul_ps(y2, z);
y2 = _mm_add_ps(y2, *(v4sf*)_ps_sincof_p1);
y2 = _mm_mul_ps(y2, z);
y2 = _mm_add_ps(y2, *(v4sf*)_ps_sincof_p2);
y2 = _mm_mul_ps(y2, z);
y2 = _mm_mul_ps(y2, x);
y2 = _mm_add_ps(y2, x);
/* select the correct result from the two polynoms */
xmm3 = poly_mask;
y2 = _mm_and_ps(xmm3, y2); //, xmm3);
y = _mm_andnot_ps(xmm3, y);
y = _mm_add_ps(y,y2);
/* update the sign */
y = _mm_xor_ps(y, sign_bit);
return y;
}
/* since sin_ps and cos_ps are almost identical, sincos_ps could replace both of them..
it is almost as fast, and gives you a free cosine with your sine */
inline void sincos_ps(v4sf x, v4sf *s, v4sf *c) {
v4sf xmm1, xmm2, xmm3 = _mm_setzero_ps(), sign_bit_sin, y;
#ifdef USE_SSE2
v4si emm0, emm2, emm4;
#else
v2si mm0, mm1, mm2, mm3, mm4, mm5;
#endif
sign_bit_sin = x;
/* take the absolute value */
x = _mm_and_ps(x, *(v4sf*)_ps_inv_sign_mask);
/* extract the sign bit (upper one) */
sign_bit_sin = _mm_and_ps(sign_bit_sin, *(v4sf*)_ps_sign_mask);
/* scale by 4/Pi */
y = _mm_mul_ps(x, *(v4sf*)_ps_cephes_FOPI);
#ifdef USE_SSE2
/* store the integer part of y in emm2 */
emm2 = _mm_cvttps_epi32(y);
/* j=(j+1) & (~1) (see the cephes sources) */
emm2 = _mm_add_epi32(emm2, *(v4si*)_pi32_1);
emm2 = _mm_and_si128(emm2, *(v4si*)_pi32_inv1);
y = _mm_cvtepi32_ps(emm2);
emm4 = emm2;
/* get the swap sign flag for the sine */
emm0 = _mm_and_si128(emm2, *(v4si*)_pi32_4);
emm0 = _mm_slli_epi32(emm0, 29);
v4sf swap_sign_bit_sin = _mm_castsi128_ps(emm0);
/* get the polynom selection mask for the sine*/
emm2 = _mm_and_si128(emm2, *(v4si*)_pi32_2);
emm2 = _mm_cmpeq_epi32(emm2, _mm_setzero_si128());
v4sf poly_mask = _mm_castsi128_ps(emm2);
#else
/* store the integer part of y in mm2:mm3 */
xmm3 = _mm_movehl_ps(xmm3, y);
mm2 = _mm_cvttps_pi32(y);
mm3 = _mm_cvttps_pi32(xmm3);
/* j=(j+1) & (~1) (see the cephes sources) */
mm2 = _mm_add_pi32(mm2, *(v2si*)_pi32_1);
mm3 = _mm_add_pi32(mm3, *(v2si*)_pi32_1);
mm2 = _mm_and_si64(mm2, *(v2si*)_pi32_inv1);
mm3 = _mm_and_si64(mm3, *(v2si*)_pi32_inv1);
y = _mm_cvtpi32x2_ps(mm2, mm3);
mm4 = mm2;
mm5 = mm3;
/* get the swap sign flag for the sine */
mm0 = _mm_and_si64(mm2, *(v2si*)_pi32_4);
mm1 = _mm_and_si64(mm3, *(v2si*)_pi32_4);
mm0 = _mm_slli_pi32(mm0, 29);
mm1 = _mm_slli_pi32(mm1, 29);
v4sf swap_sign_bit_sin;
COPY_MM_TO_XMM(mm0, mm1, swap_sign_bit_sin);
/* get the polynom selection mask for the sine */
mm2 = _mm_and_si64(mm2, *(v2si*)_pi32_2);
mm3 = _mm_and_si64(mm3, *(v2si*)_pi32_2);
mm2 = _mm_cmpeq_pi32(mm2, _mm_setzero_si64());
mm3 = _mm_cmpeq_pi32(mm3, _mm_setzero_si64());
v4sf poly_mask;
COPY_MM_TO_XMM(mm2, mm3, poly_mask);
#endif
/* The magic pass: "Extended precision modular arithmetic"
x = ((x - y * DP1) - y * DP2) - y * DP3; */
xmm1 = *(v4sf*)_ps_minus_cephes_DP1;
xmm2 = *(v4sf*)_ps_minus_cephes_DP2;
xmm3 = *(v4sf*)_ps_minus_cephes_DP3;
xmm1 = _mm_mul_ps(y, xmm1);
xmm2 = _mm_mul_ps(y, xmm2);
xmm3 = _mm_mul_ps(y, xmm3);
x = _mm_add_ps(x, xmm1);
x = _mm_add_ps(x, xmm2);
x = _mm_add_ps(x, xmm3);
#ifdef USE_SSE2
emm4 = _mm_sub_epi32(emm4, *(v4si*)_pi32_2);
emm4 = _mm_andnot_si128(emm4, *(v4si*)_pi32_4);
emm4 = _mm_slli_epi32(emm4, 29);
v4sf sign_bit_cos = _mm_castsi128_ps(emm4);
#else
/* get the sign flag for the cosine */
mm4 = _mm_sub_pi32(mm4, *(v2si*)_pi32_2);
mm5 = _mm_sub_pi32(mm5, *(v2si*)_pi32_2);
mm4 = _mm_andnot_si64(mm4, *(v2si*)_pi32_4);
mm5 = _mm_andnot_si64(mm5, *(v2si*)_pi32_4);
mm4 = _mm_slli_pi32(mm4, 29);
mm5 = _mm_slli_pi32(mm5, 29);
v4sf sign_bit_cos;
COPY_MM_TO_XMM(mm4, mm5, sign_bit_cos);
_mm_empty(); /* good-bye mmx */
#endif
sign_bit_sin = _mm_xor_ps(sign_bit_sin, swap_sign_bit_sin);
/* Evaluate the first polynom (0 <= x <= Pi/4) */
v4sf z = _mm_mul_ps(x,x);
y = *(v4sf*)_ps_coscof_p0;
y = _mm_mul_ps(y, z);
y = _mm_add_ps(y, *(v4sf*)_ps_coscof_p1);
y = _mm_mul_ps(y, z);
y = _mm_add_ps(y, *(v4sf*)_ps_coscof_p2);
y = _mm_mul_ps(y, z);
y = _mm_mul_ps(y, z);
v4sf tmp = _mm_mul_ps(z, *(v4sf*)_ps_0p5);
y = _mm_sub_ps(y, tmp);
y = _mm_add_ps(y, *(v4sf*)_ps_1);
/* Evaluate the second polynom (Pi/4 <= x <= 0) */
v4sf y2 = *(v4sf*)_ps_sincof_p0;
y2 = _mm_mul_ps(y2, z);
y2 = _mm_add_ps(y2, *(v4sf*)_ps_sincof_p1);
y2 = _mm_mul_ps(y2, z);
y2 = _mm_add_ps(y2, *(v4sf*)_ps_sincof_p2);
y2 = _mm_mul_ps(y2, z);
y2 = _mm_mul_ps(y2, x);
y2 = _mm_add_ps(y2, x);
/* select the correct result from the two polynoms */
xmm3 = poly_mask;
v4sf ysin2 = _mm_and_ps(xmm3, y2);
v4sf ysin1 = _mm_andnot_ps(xmm3, y);
y2 = _mm_sub_ps(y2,ysin2);
y = _mm_sub_ps(y, ysin1);
xmm1 = _mm_add_ps(ysin1,ysin2);
xmm2 = _mm_add_ps(y,y2);
/* update the sign */
*s = _mm_xor_ps(xmm1, sign_bit_sin);
*c = _mm_xor_ps(xmm2, sign_bit_cos);
}
+21 -13
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
@@ -32,7 +32,7 @@ namespace embree
template<int N>
struct vdouble
{
union { double f[N]; long long i[N]; };
union { double f[N]; int64_t i[N]; };
__forceinline const double& operator [](size_t index) const { assert(index < N); return f[index]; }
__forceinline double& operator [](size_t index) { assert(index < N); return f[index]; }
};
@@ -54,20 +54,29 @@ namespace embree
};
template<int N>
struct vllong
struct vlong
{
long long i[N];
__forceinline const long long& operator [](size_t index) const { assert(index < N); return i[index]; }
__forceinline long long& operator [](size_t index) { assert(index < N); return i[index]; }
int64_t i[N];
__forceinline const int64_t& operator [](size_t index) const { assert(index < N); return i[index]; }
__forceinline int64_t& operator [](size_t index) { assert(index < N); return i[index]; }
};
#if !defined(_MSC_VER) || _MSC_VER >= 1800
/* Varying bool types */
template<int N> struct vboolf { int i[N]; }; // for float/int
template<int N> struct vboold { long long i[N]; }; // for double/long long
template<int N> struct vboolf { int i[N]; }; // for float/int
template<int N> struct vboold { int64_t i[N]; }; // for double/long
/* Aliases to default types */
template<int N> using vreal = vfloat<N>;
template<int N> using vbool = vboolf<N>;
#else
/* Workaround for VS2012 */
#define vreal vfloat
#define vboolf vbool
template<int N> struct vboolf { int i[N]; };
template<int N> struct vboold { int64_t i[N]; };
#endif
/* Maximum supported varying size */
#if defined(__AVX512F__)
@@ -98,8 +107,7 @@ namespace embree
typedef vdouble<4> vdouble4;
typedef vreal<4> vreal4;
typedef vint<4> vint4;
typedef vuint<4> vuint4;
typedef vllong<4> vllong4;
typedef vlong<4> vlong4;
typedef vbool<4> vbool4;
typedef vboolf<4> vboolf4;
typedef vboold<4> vboold4;
@@ -109,7 +117,7 @@ namespace embree
typedef vdouble<8> vdouble8;
typedef vreal<8> vreal8;
typedef vint<8> vint8;
typedef vllong<8> vllong8;
typedef vlong<8> vlong8;
typedef vbool<8> vbool8;
typedef vboolf<8> vboolf8;
typedef vboold<8> vboold8;
@@ -120,7 +128,7 @@ namespace embree
typedef vreal<16> vreal16;
typedef vint<16> vint16;
typedef vuint<16> vuint16;
typedef vllong<16> vllong16;
typedef vlong<16> vlong16;
typedef vbool<16> vbool16;
typedef vboolf<16> vboolf16;
typedef vboold<16> vboold16;
@@ -130,7 +138,7 @@ namespace embree
typedef vdouble<VSIZEX> vdoublex;
typedef vreal<VSIZEX> vrealx;
typedef vint<VSIZEX> vintx;
typedef vllong<VSIZEX> vllongx;
typedef vlong<VSIZEX> vlongx;
typedef vbool<VSIZEX> vboolx;
typedef vboolf<VSIZEX> vboolfx;
typedef vboold<VSIZEX> vbooldx;
+45 -47
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
@@ -28,25 +28,25 @@ namespace embree
union { // data
__m256d v;
struct { __m128d vl,vh; };
long long i[4];
};
int64_t i[4];
};
////////////////////////////////////////////////////////////////////////////////
/// Constructors, Assignment & Cast Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline vboold() {}
__forceinline vboold(const vboold4& a) { v = a.v; }
__forceinline vboold4& operator =(const vboold4& a) { v = a.v; return *this; }
__forceinline vboold () {}
__forceinline vboold ( const vboold4& a ) { v = a.v; }
__forceinline vboold4& operator=( const vboold4& a ) { v = a.v; return *this; }
__forceinline vboold(__m256d a) : v(a) {}
__forceinline vboold(__m256i a) : v(_mm256_castsi256_pd(a)) {}
__forceinline vboold( const __m256d a ) : v(a) {}
__forceinline vboold( const __m256i a ) : v(_mm256_castsi256_pd(a)) {}
__forceinline operator const __m256() const { return _mm256_castpd_ps(v); }
__forceinline operator const __m256i() const { return _mm256_castpd_si256(v); }
__forceinline operator const __m256d() const { return v; }
__forceinline operator const __m256( void ) const { return _mm256_castpd_ps(v); }
__forceinline operator const __m256i( void ) const { return _mm256_castpd_si256(v); }
__forceinline operator const __m256d( void ) const { return v; }
__forceinline vboold(int a)
__forceinline vboold ( const int a )
{
assert(a >= 0 && a <= 255);
#if defined (__AVX2__)
@@ -60,49 +60,49 @@ namespace embree
#endif
}
__forceinline vboold(__m128d a, __m128d b) : vl(a), vh(b) {}
__forceinline vboold ( const __m128d a, const __m128d b) : vl(a), vh(b) {}
////////////////////////////////////////////////////////////////////////////////
/// Constants
////////////////////////////////////////////////////////////////////////////////
__forceinline vboold(FalseTy) : v(_mm256_setzero_pd()) {}
__forceinline vboold(TrueTy) : v(_mm256_cmp_pd(_mm256_setzero_pd(), _mm256_setzero_pd(), _CMP_EQ_OQ)) {}
__forceinline vboold( FalseTy ) : v(_mm256_setzero_pd()) {}
__forceinline vboold( TrueTy ) : v(_mm256_cmp_pd(_mm256_setzero_pd(), _mm256_setzero_pd(), _CMP_EQ_OQ)) {}
////////////////////////////////////////////////////////////////////////////////
/// Array Access
////////////////////////////////////////////////////////////////////////////////
__forceinline bool operator [](size_t index) const { assert(index < 4); return (_mm256_movemask_pd(v) >> index) & 1; }
__forceinline long long& operator [](size_t index) { assert(index < 4); return i[index]; }
__forceinline bool operator []( const size_t index ) const { assert(index < 4); return (_mm256_movemask_pd(v) >> index) & 1; }
__forceinline int64_t& operator []( const size_t index ) { assert(index < 4); return i[index]; }
};
////////////////////////////////////////////////////////////////////////////////
/// Unary Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline vboold4 operator !(const vboold4& a) { return _mm256_xor_pd(a, vboold4(embree::True)); }
__forceinline const vboold4 operator !( const vboold4& a ) { return _mm256_xor_pd(a, vboold4(embree::True)); }
////////////////////////////////////////////////////////////////////////////////
/// Binary Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline vboold4 operator &(const vboold4& a, const vboold4& b) { return _mm256_and_pd(a, b); }
__forceinline vboold4 operator |(const vboold4& a, const vboold4& b) { return _mm256_or_pd (a, b); }
__forceinline vboold4 operator ^(const vboold4& a, const vboold4& b) { return _mm256_xor_pd(a, b); }
__forceinline const vboold4 operator &( const vboold4& a, const vboold4& b ) { return _mm256_and_pd(a, b); }
__forceinline const vboold4 operator |( const vboold4& a, const vboold4& b ) { return _mm256_or_pd (a, b); }
__forceinline const vboold4 operator ^( const vboold4& a, const vboold4& b ) { return _mm256_xor_pd(a, b); }
__forceinline vboold4& operator &=(vboold4& a, const vboold4& b) { return a = a & b; }
__forceinline vboold4& operator |=(vboold4& a, const vboold4& b) { return a = a | b; }
__forceinline vboold4& operator ^=(vboold4& a, const vboold4& b) { return a = a ^ b; }
__forceinline vboold4 operator &=( vboold4& a, const vboold4& b ) { return a = a & b; }
__forceinline vboold4 operator |=( vboold4& a, const vboold4& b ) { return a = a | b; }
__forceinline vboold4 operator ^=( vboold4& a, const vboold4& b ) { return a = a ^ b; }
////////////////////////////////////////////////////////////////////////////////
/// Comparison Operators + Select
////////////////////////////////////////////////////////////////////////////////
__forceinline vboold4 operator !=(const vboold4& a, const vboold4& b) { return _mm256_xor_pd(a, b); }
__forceinline vboold4 operator ==(const vboold4& a, const vboold4& b) { return _mm256_xor_pd(_mm256_xor_pd(a,b),vboold4(embree::True)); }
__forceinline const vboold4 operator !=( const vboold4& a, const vboold4& b ) { return _mm256_xor_pd(a, b); }
__forceinline const vboold4 operator ==( const vboold4& a, const vboold4& b ) { return _mm256_xor_pd(_mm256_xor_pd(a,b),vboold4(embree::True)); }
__forceinline vboold4 select(const vboold4& mask, const vboold4& t, const vboold4& f) {
__forceinline const vboold4 select( const vboold4& mask, const vboold4& t, const vboold4& f ) {
return _mm256_blendv_pd(f, t, mask);
}
@@ -110,19 +110,17 @@ namespace embree
/// Movement/Shifting/Shuffling Functions
////////////////////////////////////////////////////////////////////////////////
__forceinline vboold4 unpacklo(const vboold4& a, const vboold4& b) { return _mm256_unpacklo_pd(a, b); }
__forceinline vboold4 unpackhi(const vboold4& a, const vboold4& b) { return _mm256_unpackhi_pd(a, b); }
__forceinline vboold4 unpacklo( const vboold4& a, const vboold4& b ) { return _mm256_unpacklo_pd(a.v, b.v); }
__forceinline vboold4 unpackhi( const vboold4& a, const vboold4& b ) { return _mm256_unpackhi_pd(a.v, b.v); }
#if defined(__AVX2__)
template<int i0, int i1, int i2, int i3>
__forceinline vboold4 shuffle(const vboold4& v) {
return _mm256_permute4x64_pd(v, _MM_SHUFFLE(i3, i2, i1, i0));
template<size_t i0, size_t i1, size_t i2, size_t i3> __forceinline const vboold4 shuffle( const vboold4& a ) {
return _mm256_permute4x64_pd(a, _MM_SHUFFLE(i3, i2, i1, i0));
}
template<int i>
__forceinline vboold4 shuffle(const vboold4& v) {
return _mm256_permute4x64_pd(v, _MM_SHUFFLE(i, i, i, i));
template<size_t i> __forceinline const vboold4 shuffle( const vboold4& a ) {
return _mm256_permute4x64_pd(a, _MM_SHUFFLE(i, i, i, i));
}
#endif
@@ -131,33 +129,33 @@ namespace embree
/// Reduction Operations
////////////////////////////////////////////////////////////////////////////////
__forceinline bool reduce_and(const vboold4& a) { return _mm256_movemask_pd(a) == (unsigned int)0xf; }
__forceinline bool reduce_or (const vboold4& a) { return !_mm256_testz_pd(a,a); }
__forceinline bool reduce_and( const vboold4& a ) { return _mm256_movemask_pd(a) == (unsigned int)0xf; }
__forceinline bool reduce_or ( const vboold4& a ) { return !_mm256_testz_pd(a,a); }
__forceinline bool all (const vboold4& a) { return _mm256_movemask_pd(a) == (unsigned int)0xf; }
__forceinline bool any (const vboold4& a) { return !_mm256_testz_pd(a,a); }
__forceinline bool none(const vboold4& a) { return _mm256_testz_pd(a,a) != 0; }
__forceinline bool all ( const vboold4& a ) { return _mm256_movemask_pd(a) == (unsigned int)0xf; }
__forceinline bool any ( const vboold4& a ) { return !_mm256_testz_pd(a,a); }
__forceinline bool none ( const vboold4& a ) { return _mm256_testz_pd(a,a) != 0; }
__forceinline bool all (const vboold4& valid, const vboold4& b) { return all((!valid) | b); }
__forceinline bool any (const vboold4& valid, const vboold4& b) { return any(valid & b); }
__forceinline bool none(const vboold4& valid, const vboold4& b) { return none(valid & b); }
__forceinline bool all ( const vboold4& valid, const vboold4& b ) { return all((!valid) | b); }
__forceinline bool any ( const vboold4& valid, const vboold4& b ) { return any( valid & b); }
__forceinline bool none ( const vboold4& valid, const vboold4& b ) { return none(valid & b); }
__forceinline unsigned int movemask(const vboold4& a) { return _mm256_movemask_pd(a); }
__forceinline size_t popcnt (const vboold4& a) { return __popcnt((size_t)_mm256_movemask_pd(a)); }
__forceinline unsigned int movemask( const vboold4& a ) { return _mm256_movemask_pd(a); }
__forceinline size_t popcnt ( const vboold4& a ) { return __popcnt((size_t)_mm256_movemask_pd(a)); }
////////////////////////////////////////////////////////////////////////////////
/// Get/Set Functions
////////////////////////////////////////////////////////////////////////////////
__forceinline bool get(const vboold4& a, size_t index) { return a[index]; }
__forceinline void set (vboold4& a, size_t index) { a[index] = -1; }
__forceinline void set (vboold4& a, size_t index) { a[index] = -1; }
__forceinline void clear(vboold4& a, size_t index) { a[index] = 0; }
////////////////////////////////////////////////////////////////////////////////
/// Output Operators
////////////////////////////////////////////////////////////////////////////////
inline std::ostream& operator <<(std::ostream& cout, const vboold4& a) {
inline std::ostream& operator<<(std::ostream& cout, const vboold4& a) {
return cout << "<" << a[0] << ", " << a[1] << ", " << a[2] << ", " << a[3] << ", "
<< a[4] << ", " << a[5] << ", " << a[6] << ", " << a[7] << ">";
}
+26 -26
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
@@ -33,8 +33,8 @@ namespace embree
////////////////////////////////////////////////////////////////////////////////
__forceinline vboold() {}
__forceinline vboold(const vboold4& t) { v = t.v; }
__forceinline vboold4& operator =(const vboold4& f) { v = f.v; return *this; }
__forceinline vboold(const vboold4 &t) { v = t.v; }
__forceinline vboold4& operator=(const vboold4 &f) { v = f.v; return *this; }
__forceinline vboold(const __mmask8 &t) { v = t; }
__forceinline operator __mmask8() const { return v; }
@@ -62,42 +62,42 @@ namespace embree
/// Constants
////////////////////////////////////////////////////////////////////////////////
__forceinline vboold(FalseTy) : v(0x0) {}
__forceinline vboold(TrueTy) : v(0xf) {}
__forceinline vboold( FalseTy ) : v(0x0) {}
__forceinline vboold( TrueTy ) : v(0xf) {}
};
////////////////////////////////////////////////////////////////////////////////
/// Unary Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline vboold4 operator !(const vboold4& a) { return _mm512_kandn(a, 0xf); }
__forceinline vboold4 operator!(const vboold4 &a) { return _mm512_kandn(a, 0xf); }
////////////////////////////////////////////////////////////////////////////////
/// Binary Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline vboold4 operator &(const vboold4& a, const vboold4& b) { return _mm512_kand(a, b); }
__forceinline vboold4 operator |(const vboold4& a, const vboold4& b) { return _mm512_kor(a, b); }
__forceinline vboold4 operator ^(const vboold4& a, const vboold4& b) { return _mm512_kxor(a, b); }
__forceinline vboold4 operator&(const vboold4 &a, const vboold4 &b) { return _mm512_kand(a, b); }
__forceinline vboold4 operator|(const vboold4 &a, const vboold4 &b) { return _mm512_kor(a, b); }
__forceinline vboold4 operator^(const vboold4 &a, const vboold4 &b) { return _mm512_kxor(a, b); }
__forceinline vboold4 andn(const vboold4& a, const vboold4& b) { return _mm512_kandn(b, a); }
__forceinline vboold4 andn(const vboold4 &a, const vboold4 &b) { return _mm512_kandn(b, a); }
////////////////////////////////////////////////////////////////////////////////
/// Assignment Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline vboold4& operator &=(vboold4& a, const vboold4& b) { return a = a & b; }
__forceinline vboold4& operator |=(vboold4& a, const vboold4& b) { return a = a | b; }
__forceinline vboold4& operator ^=(vboold4& a, const vboold4& b) { return a = a ^ b; }
__forceinline const vboold4 operator &=( vboold4& a, const vboold4& b ) { return a = a & b; }
__forceinline const vboold4 operator |=( vboold4& a, const vboold4& b ) { return a = a | b; }
__forceinline const vboold4 operator ^=( vboold4& a, const vboold4& b ) { return a = a ^ b; }
////////////////////////////////////////////////////////////////////////////////
/// Comparison Operators + Select
////////////////////////////////////////////////////////////////////////////////
__forceinline vboold4 operator !=(const vboold4& a, const vboold4& b) { return _mm512_kxor(a, b); }
__forceinline vboold4 operator ==(const vboold4& a, const vboold4& b) { return _mm512_kand(_mm512_kxnor(a, b), 0xf); }
__forceinline const vboold4 operator !=( const vboold4& a, const vboold4& b ) { return _mm512_kxor(a, b); }
__forceinline const vboold4 operator ==( const vboold4& a, const vboold4& b ) { return _mm512_kand(_mm512_kxnor(a, b), 0xf); }
__forceinline vboold4 select(const vboold4& s, const vboold4& a, const vboold4& b) {
__forceinline vboold4 select (const vboold4 &s, const vboold4 &a, const vboold4 &b) {
return _mm512_kor(_mm512_kand(s, a), _mm512_kandn(s, b));
}
@@ -105,22 +105,22 @@ namespace embree
/// Reduction Operations
////////////////////////////////////////////////////////////////////////////////
__forceinline int all (const vboold4& a) { return a.v == 0xf; }
__forceinline int any (const vboold4& a) { return _mm512_kortestz(a, a) == 0; }
__forceinline int none(const vboold4& a) { return _mm512_kortestz(a, a) != 0; }
__forceinline int all (const vboold4 &a) { return a.v == 0xf; }
__forceinline int any (const vboold4 &a) { return _mm512_kortestz(a, a) == 0; }
__forceinline int none(const vboold4 &a) { return _mm512_kortestz(a, a) != 0; }
__forceinline int all (const vboold4& valid, const vboold4& b) { return all((!valid) | b); }
__forceinline int any (const vboold4& valid, const vboold4& b) { return any(valid & b); }
__forceinline int none(const vboold4& valid, const vboold4& b) { return none(valid & b); }
__forceinline int all ( const vboold4& valid, const vboold4& b ) { return all((!valid) | b); }
__forceinline int any ( const vboold4& valid, const vboold4& b ) { return any( valid & b); }
__forceinline int none( const vboold4& valid, const vboold4& b ) { return none(valid & b); }
__forceinline size_t movemask(const vboold4& a) { return _mm512_kmov(a); }
__forceinline size_t popcnt (const vboold4& a) { return __popcnt(a.v); }
__forceinline size_t movemask( const vboold4& a ) { return _mm512_kmov(a); }
__forceinline size_t popcnt ( const vboold4& a ) { return _mm_countbits_64(a.v); }
////////////////////////////////////////////////////////////////////////////////
/// Conversion Operations
////////////////////////////////////////////////////////////////////////////////
__forceinline unsigned int toInt(const vboold4& a) { return mm512_mask2int(a); }
__forceinline unsigned int toInt(const vboold4 &a) { return _mm512_mask2int(a); }
////////////////////////////////////////////////////////////////////////////////
/// Get/Set Functions
@@ -134,7 +134,7 @@ namespace embree
/// Output Operators
////////////////////////////////////////////////////////////////////////////////
inline std::ostream& operator <<(std::ostream& cout, const vboold4& a)
inline std::ostream& operator<<(std::ostream& cout, const vboold4& a)
{
cout << "<";
for (size_t i=0; i<4; i++) {
+31 -31
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
@@ -33,10 +33,10 @@ namespace embree
////////////////////////////////////////////////////////////////////////////////
__forceinline vboold() {}
__forceinline vboold(const vboold8& t) { v = t.v; }
__forceinline vboold8& operator =(const vboold8& f) { v = f.v; return *this; }
__forceinline vboold(const vboold8 &t) { v = t.v; }
__forceinline vboold8& operator=(const vboold8 &f) { v = f.v; return *this; }
__forceinline vboold(const __mmask8& t) { v = t; }
__forceinline vboold(const __mmask8 &t) { v = t; }
__forceinline operator __mmask8() const { return v; }
__forceinline vboold(bool b) { v = b ? 0xff : 0x00; }
@@ -48,8 +48,8 @@ namespace embree
#if defined(__AVX512BW__)
return _mm_movm_epi8(v);
#else
const __m512i f = _mm512_set1_epi64(0);
const __m512i t = _mm512_set1_epi64(-1);
const __m512i f = _mm512_set_1to8_epi64(0);
const __m512i t = _mm512_set_1to8_epi64(-1);
const __m512i m = _mm512_mask_or_epi64(f,v,t,t);
return _mm512_cvtepi64_epi8(m);
#endif
@@ -60,8 +60,8 @@ namespace embree
#if defined(__AVX512DQ__)
return _mm512_movm_epi64(v);
#else
const __m512i f = _mm512_set1_epi64(0);
const __m512i t = _mm512_set1_epi64(-1);
const __m512i f = _mm512_set_1to8_epi64(0);
const __m512i t = _mm512_set_1to8_epi64(-1);
return _mm512_mask_or_epi64(f,v,t,t);
#endif
}
@@ -70,42 +70,42 @@ namespace embree
/// Constants
////////////////////////////////////////////////////////////////////////////////
__forceinline vboold(FalseTy) : v(0x00) {}
__forceinline vboold(TrueTy) : v(0xff) {}
__forceinline vboold( FalseTy ) : v(0x00) {}
__forceinline vboold( TrueTy ) : v(0xff) {}
};
////////////////////////////////////////////////////////////////////////////////
/// Unary Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline vboold8 operator !(const vboold8& a) { return _mm512_knot(a); }
__forceinline vboold8 operator!(const vboold8 &a) { return _mm512_knot(a); }
////////////////////////////////////////////////////////////////////////////////
/// Binary Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline vboold8 operator &(const vboold8& a, const vboold8& b) { return _mm512_kand(a, b); }
__forceinline vboold8 operator |(const vboold8& a, const vboold8& b) { return _mm512_kor(a, b); }
__forceinline vboold8 operator ^(const vboold8& a, const vboold8& b) { return _mm512_kxor(a, b); }
__forceinline vboold8 operator&(const vboold8 &a, const vboold8 &b) { return _mm512_kand(a, b); }
__forceinline vboold8 operator|(const vboold8 &a, const vboold8 &b) { return _mm512_kor(a, b); }
__forceinline vboold8 operator^(const vboold8 &a, const vboold8 &b) { return _mm512_kxor(a, b); }
__forceinline vboold8 andn(const vboold8& a, const vboold8& b) { return _mm512_kandn(b, a); }
__forceinline vboold8 andn(const vboold8 &a, const vboold8 &b) { return _mm512_kandn(b, a); }
////////////////////////////////////////////////////////////////////////////////
/// Assignment Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline vboold8& operator &=(vboold8& a, const vboold8& b) { return a = a & b; }
__forceinline vboold8& operator |=(vboold8& a, const vboold8& b) { return a = a | b; }
__forceinline vboold8& operator ^=(vboold8& a, const vboold8& b) { return a = a ^ b; }
__forceinline const vboold8 operator &=( vboold8& a, const vboold8& b ) { return a = a & b; }
__forceinline const vboold8 operator |=( vboold8& a, const vboold8& b ) { return a = a | b; }
__forceinline const vboold8 operator ^=( vboold8& a, const vboold8& b ) { return a = a ^ b; }
////////////////////////////////////////////////////////////////////////////////
/// Comparison Operators + Select
////////////////////////////////////////////////////////////////////////////////
__forceinline vboold8 operator !=(const vboold8& a, const vboold8& b) { return _mm512_kxor(a, b); }
__forceinline vboold8 operator ==(const vboold8& a, const vboold8& b) { return _mm512_kxnor(a, b); }
__forceinline const vboold8 operator !=( const vboold8& a, const vboold8& b ) { return _mm512_kxor(a, b); }
__forceinline const vboold8 operator ==( const vboold8& a, const vboold8& b ) { return _mm512_kxnor(a, b); }
__forceinline vboold8 select(const vboold8& s, const vboold8& a, const vboold8& b) {
__forceinline vboold8 select(const vboold8 &s, const vboold8 &a, const vboold8 &b) {
return _mm512_kor(_mm512_kand(s, a), _mm512_kandn(s, b));
}
@@ -113,22 +113,22 @@ namespace embree
/// Reduction Operations
////////////////////////////////////////////////////////////////////////////////
__forceinline int all (const vboold8& a) { return a.v == 0xff; }
__forceinline int any (const vboold8& a) { return _mm512_kortestz(a, a) == 0; }
__forceinline int none(const vboold8& a) { return _mm512_kortestz(a, a) != 0; }
__forceinline int all (const vboold8 &a) { return a.v == 0xff; }
__forceinline int any (const vboold8 &a) { return _mm512_kortestz(a, a) == 0; }
__forceinline int none(const vboold8 &a) { return _mm512_kortestz(a, a) != 0; }
__forceinline int all (const vboold8& valid, const vboold8& b) { return all((!valid) | b); }
__forceinline int any (const vboold8& valid, const vboold8& b) { return any(valid & b); }
__forceinline int none(const vboold8& valid, const vboold8& b) { return none(valid & b); }
__forceinline int all ( const vboold8& valid, const vboold8& b ) { return all((!valid) | b); }
__forceinline int any ( const vboold8& valid, const vboold8& b ) { return any( valid & b); }
__forceinline int none( const vboold8& valid, const vboold8& b ) { return none(valid & b); }
__forceinline size_t movemask(const vboold8& a) { return _mm512_kmov(a); }
__forceinline size_t popcnt (const vboold8& a) { return __popcnt(a.v); }
__forceinline size_t movemask( const vboold8& a ) { return _mm512_kmov(a); }
__forceinline size_t popcnt ( const vboold8& a ) { return _mm_countbits_64(a.v); }
////////////////////////////////////////////////////////////////////////////////
/// Conversion Operations
////////////////////////////////////////////////////////////////////////////////
__forceinline unsigned int toInt(const vboold8& a) { return mm512_mask2int(a); }
__forceinline unsigned int toInt(const vboold8 &a) { return _mm512_mask2int(a); }
////////////////////////////////////////////////////////////////////////////////
/// Get/Set Functions
@@ -142,7 +142,7 @@ namespace embree
/// Output Operators
////////////////////////////////////////////////////////////////////////////////
inline std::ostream& operator <<(std::ostream& cout, const vboold8& a)
inline std::ostream& operator<<(std::ostream& cout, const vboold8& a)
{
cout << "<";
for (size_t i=0; i<8; i++) {
+33 -33
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
@@ -34,15 +34,15 @@ namespace embree
////////////////////////////////////////////////////////////////////////////////
__forceinline vboolf() {}
__forceinline vboolf(const vboolf16& t) { v = t.v; }
__forceinline vboolf16& operator =(const vboolf16& f) { v = f.v; return *this; }
__forceinline vboolf(const vboolf16 &t) { v = t.v; }
__forceinline vboolf16& operator=(const vboolf16 &f) { v = f.v; return *this; }
__forceinline vboolf(const __mmask16& t) { v = t; }
__forceinline operator __mmask16() const { return v; }
__forceinline vboolf(const __mmask16 &t) { v = t; }
__forceinline operator __mmask16 () const { return v; }
__forceinline vboolf(bool b) { v = b ? 0xFFFF : 0x0000; }
__forceinline vboolf(int t) { v = (__mmask16)t; }
__forceinline vboolf(unsigned int t) { v = (__mmask16)t; }
__forceinline vboolf(int t ) { v = (__mmask16)t; }
__forceinline vboolf(unsigned int t ) { v = (__mmask16)t; }
/* return int8 mask */
__forceinline __m128i mask8() const {
@@ -71,15 +71,15 @@ namespace embree
/// Constants
////////////////////////////////////////////////////////////////////////////////
__forceinline vboolf(FalseTy) : v(0x0000) {}
__forceinline vboolf(TrueTy) : v(0xffff) {}
__forceinline vboolf( FalseTy ) : v(0x0000) {}
__forceinline vboolf( TrueTy ) : v(0xffff) {}
////////////////////////////////////////////////////////////////////////////////
/// Array Access
////////////////////////////////////////////////////////////////////////////////
__forceinline bool operator [](size_t index) const {
assert(index < 16); return (mm512_mask2int(v) >> index) & 1;
__forceinline bool operator []( const size_t index ) const {
assert(index < 16); return (_mm512_mask2int(v) >> index) & 1;
}
};
@@ -87,34 +87,34 @@ namespace embree
/// Unary Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline vboolf16 operator !(const vboolf16& a) { return _mm512_knot(a); }
__forceinline vboolf16 operator!(const vboolf16 &a) { return _mm512_knot(a); }
////////////////////////////////////////////////////////////////////////////////
/// Binary Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline vboolf16 operator &(const vboolf16& a, const vboolf16& b) { return _mm512_kand(a,b); }
__forceinline vboolf16 operator |(const vboolf16& a, const vboolf16& b) { return _mm512_kor(a,b); }
__forceinline vboolf16 operator ^(const vboolf16& a, const vboolf16& b) { return _mm512_kxor(a,b); }
__forceinline vboolf16 operator&(const vboolf16 &a, const vboolf16 &b) { return _mm512_kand(a,b); }
__forceinline vboolf16 operator|(const vboolf16 &a, const vboolf16 &b) { return _mm512_kor(a,b); }
__forceinline vboolf16 operator^(const vboolf16 &a, const vboolf16 &b) { return _mm512_kxor(a,b); }
__forceinline vboolf16 andn(const vboolf16& a, const vboolf16& b) { return _mm512_kandn(b,a); }
__forceinline vboolf16 andn(const vboolf16 &a, const vboolf16 &b) { return _mm512_kandn(b,a); }
////////////////////////////////////////////////////////////////////////////////
/// Assignment Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline vboolf16& operator &=(vboolf16& a, const vboolf16& b) { return a = a & b; }
__forceinline vboolf16& operator |=(vboolf16& a, const vboolf16& b) { return a = a | b; }
__forceinline vboolf16& operator ^=(vboolf16& a, const vboolf16& b) { return a = a ^ b; }
__forceinline const vboolf16 operator &=( vboolf16& a, const vboolf16& b ) { return a = a & b; }
__forceinline const vboolf16 operator |=( vboolf16& a, const vboolf16& b ) { return a = a | b; }
__forceinline const vboolf16 operator ^=( vboolf16& a, const vboolf16& b ) { return a = a ^ b; }
////////////////////////////////////////////////////////////////////////////////
/// Comparison Operators + Select
////////////////////////////////////////////////////////////////////////////////
__forceinline vboolf16 operator !=(const vboolf16& a, const vboolf16& b) { return _mm512_kxor(a, b); }
__forceinline vboolf16 operator ==(const vboolf16& a, const vboolf16& b) { return _mm512_kxnor(a, b); }
__forceinline const vboolf16 operator !=( const vboolf16& a, const vboolf16& b ) { return _mm512_kxor(a, b); }
__forceinline const vboolf16 operator ==( const vboolf16& a, const vboolf16& b ) { return _mm512_kxnor(a, b); }
__forceinline vboolf16 select(const vboolf16& s, const vboolf16& a, const vboolf16& b) {
__forceinline vboolf16 select (const vboolf16 &s, const vboolf16 &a, const vboolf16 &b) {
return _mm512_kor(_mm512_kand(s,a),_mm512_kandn(s,b));
}
@@ -122,23 +122,23 @@ namespace embree
/// Reduction Operations
////////////////////////////////////////////////////////////////////////////////
__forceinline int all (const vboolf16& a) { return _mm512_kortestc(a,a) != 0; }
__forceinline int any (const vboolf16& a) { return _mm512_kortestz(a,a) == 0; }
__forceinline int none(const vboolf16& a) { return _mm512_kortestz(a,a) != 0; }
__forceinline int all (const vboolf16 &a) { return _mm512_kortestc(a,a) != 0; }
__forceinline int any (const vboolf16 &a) { return _mm512_kortestz(a,a) == 0; }
__forceinline int none(const vboolf16 &a) { return _mm512_kortestz(a,a) != 0; }
__forceinline int all (const vboolf16& valid, const vboolf16& b) { return all((!valid) | b); }
__forceinline int any (const vboolf16& valid, const vboolf16& b) { return any(valid & b); }
__forceinline int none(const vboolf16& valid, const vboolf16& b) { return none(valid & b); }
__forceinline int all ( const vboolf16& valid, const vboolf16& b ) { return all((!valid) | b); }
__forceinline int any ( const vboolf16& valid, const vboolf16& b ) { return any( valid & b); }
__forceinline int none( const vboolf16& valid, const vboolf16& b ) { return none(valid & b); }
__forceinline size_t movemask(const vboolf16& a) { return _mm512_kmov(a); }
__forceinline size_t popcnt (const vboolf16& a) { return __popcnt(a.v); }
__forceinline size_t movemask( const vboolf16& a ) { return _mm512_kmov(a); }
__forceinline size_t popcnt ( const vboolf16& a ) { return _mm_countbits_32(a.v); }
////////////////////////////////////////////////////////////////////////////////
/// Convertion Operations
////////////////////////////////////////////////////////////////////////////////
__forceinline unsigned int toInt (const vboolf16& a) { return mm512_mask2int(a); }
__forceinline vboolf16 toMask(const int& a) { return mm512_int2mask(a); }
__forceinline unsigned int toInt (const vboolf16 &a) { return _mm512_mask2int(a); }
__forceinline vboolf16 toMask(const int &a) { return _mm512_int2mask(a); }
////////////////////////////////////////////////////////////////////////////////
/// Get/Set Functions
@@ -152,7 +152,7 @@ namespace embree
/// Output Operators
////////////////////////////////////////////////////////////////////////////////
inline std::ostream& operator <<(std::ostream& cout, const vboolf16& a)
inline std::ostream& operator<<(std::ostream& cout, const vboolf16& a)
{
cout << "<";
for (size_t i=0; i<16; i++) {
+26 -26
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
@@ -33,8 +33,8 @@ namespace embree
////////////////////////////////////////////////////////////////////////////////
__forceinline vboolf() {}
__forceinline vboolf(const vboolf4& t) { v = t.v; }
__forceinline vboolf4& operator =(const vboolf4& f) { v = f.v; return *this; }
__forceinline vboolf(const vboolf4 &t) { v = t.v; }
__forceinline vboolf4& operator=(const vboolf4 &f) { v = f.v; return *this; }
__forceinline vboolf(const __mmask8 &t) { v = t; }
__forceinline operator __mmask8() const { return v; }
@@ -62,42 +62,42 @@ namespace embree
/// Constants
////////////////////////////////////////////////////////////////////////////////
__forceinline vboolf(FalseTy) : v(0x0) {}
__forceinline vboolf(TrueTy) : v(0xf) {}
__forceinline vboolf( FalseTy ) : v(0x0) {}
__forceinline vboolf( TrueTy ) : v(0xf) {}
};
////////////////////////////////////////////////////////////////////////////////
/// Unary Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline vboolf4 operator !(const vboolf4& a) { return _mm512_kandn(a, 0xf); }
__forceinline vboolf4 operator!(const vboolf4 &a) { return _mm512_kandn(a, 0xf); }
////////////////////////////////////////////////////////////////////////////////
/// Binary Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline vboolf4 operator &(const vboolf4& a, const vboolf4& b) { return _mm512_kand(a, b); }
__forceinline vboolf4 operator |(const vboolf4& a, const vboolf4& b) { return _mm512_kor(a, b); }
__forceinline vboolf4 operator ^(const vboolf4& a, const vboolf4& b) { return _mm512_kxor(a, b); }
__forceinline vboolf4 operator&(const vboolf4 &a, const vboolf4 &b) { return _mm512_kand(a, b); }
__forceinline vboolf4 operator|(const vboolf4 &a, const vboolf4 &b) { return _mm512_kor(a, b); }
__forceinline vboolf4 operator^(const vboolf4 &a, const vboolf4 &b) { return _mm512_kxor(a, b); }
__forceinline vboolf4 andn(const vboolf4& a, const vboolf4& b) { return _mm512_kandn(b, a); }
__forceinline vboolf4 andn(const vboolf4 &a, const vboolf4 &b) { return _mm512_kandn(b, a); }
////////////////////////////////////////////////////////////////////////////////
/// Assignment Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline vboolf4& operator &=(vboolf4& a, const vboolf4& b) { return a = a & b; }
__forceinline vboolf4& operator |=(vboolf4& a, const vboolf4& b) { return a = a | b; }
__forceinline vboolf4& operator ^=(vboolf4& a, const vboolf4& b) { return a = a ^ b; }
__forceinline const vboolf4 operator &=( vboolf4& a, const vboolf4& b ) { return a = a & b; }
__forceinline const vboolf4 operator |=( vboolf4& a, const vboolf4& b ) { return a = a | b; }
__forceinline const vboolf4 operator ^=( vboolf4& a, const vboolf4& b ) { return a = a ^ b; }
////////////////////////////////////////////////////////////////////////////////
/// Comparison Operators + Select
////////////////////////////////////////////////////////////////////////////////
__forceinline vboolf4 operator !=(const vboolf4& a, const vboolf4& b) { return _mm512_kxor(a, b); }
__forceinline vboolf4 operator ==(const vboolf4& a, const vboolf4& b) { return _mm512_kand(_mm512_kxnor(a, b), 0xf); }
__forceinline const vboolf4 operator !=( const vboolf4& a, const vboolf4& b ) { return _mm512_kxor(a, b); }
__forceinline const vboolf4 operator ==( const vboolf4& a, const vboolf4& b ) { return _mm512_kand(_mm512_kxnor(a, b), 0xf); }
__forceinline vboolf4 select(const vboolf4& s, const vboolf4& a, const vboolf4& b) {
__forceinline vboolf4 select (const vboolf4 &s, const vboolf4 &a, const vboolf4 &b) {
return _mm512_kor(_mm512_kand(s, a), _mm512_kandn(s, b));
}
@@ -105,22 +105,22 @@ namespace embree
/// Reduction Operations
////////////////////////////////////////////////////////////////////////////////
__forceinline int all (const vboolf4& a) { return a.v == 0xf; }
__forceinline int any (const vboolf4& a) { return _mm512_kortestz(a, a) == 0; }
__forceinline int none(const vboolf4& a) { return _mm512_kortestz(a, a) != 0; }
__forceinline int all (const vboolf4 &a) { return a.v == 0xf; }
__forceinline int any (const vboolf4 &a) { return _mm512_kortestz(a, a) == 0; }
__forceinline int none(const vboolf4 &a) { return _mm512_kortestz(a, a) != 0; }
__forceinline int all (const vboolf4& valid, const vboolf4& b) { return all((!valid) | b); }
__forceinline int any (const vboolf4& valid, const vboolf4& b) { return any(valid & b); }
__forceinline int none(const vboolf4& valid, const vboolf4& b) { return none(valid & b); }
__forceinline int all ( const vboolf4& valid, const vboolf4& b ) { return all((!valid) | b); }
__forceinline int any ( const vboolf4& valid, const vboolf4& b ) { return any( valid & b); }
__forceinline int none( const vboolf4& valid, const vboolf4& b ) { return none(valid & b); }
__forceinline size_t movemask(const vboolf4& a) { return _mm512_kmov(a); }
__forceinline size_t popcnt (const vboolf4& a) { return __popcnt(a.v); }
__forceinline size_t movemask( const vboolf4& a ) { return _mm512_kmov(a); }
__forceinline size_t popcnt ( const vboolf4& a ) { return _mm_countbits_64(a.v); }
////////////////////////////////////////////////////////////////////////////////
/// Conversion Operations
////////////////////////////////////////////////////////////////////////////////
__forceinline unsigned int toInt(const vboolf4& a) { return mm512_mask2int(a); }
__forceinline unsigned int toInt(const vboolf4 &a) { return _mm512_mask2int(a); }
////////////////////////////////////////////////////////////////////////////////
/// Get/Set Functions
@@ -134,7 +134,7 @@ namespace embree
/// Output Operators
////////////////////////////////////////////////////////////////////////////////
inline std::ostream& operator <<(std::ostream& cout, const vboolf4& a)
inline std::ostream& operator<<(std::ostream& cout, const vboolf4& a)
{
cout << "<";
for (size_t i=0; i<4; i++) {
+54 -55
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
@@ -33,23 +33,25 @@ namespace embree
/// Constructors, Assignment & Cast Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline vboolf() {}
__forceinline vboolf(const vboolf4& other) { v = other.v; }
__forceinline vboolf4& operator =(const vboolf4& other) { v = other.v; return *this; }
__forceinline vboolf ( ) {}
__forceinline vboolf ( const vboolf4& other ) { v = other.v; }
__forceinline vboolf4& operator=( const vboolf4& other ) { v = other.v; return *this; }
__forceinline vboolf(__m128 input) : v(input) {}
__forceinline operator const __m128&() const { return v; }
__forceinline operator const __m128i() const { return _mm_castps_si128(v); }
__forceinline operator const __m128d() const { return _mm_castps_pd(v); }
__forceinline vboolf( const __m128 input ) : v(input) {}
__forceinline operator const __m128&( void ) const { return v; }
__forceinline operator const __m128i( void ) const { return _mm_castps_si128(v); }
__forceinline operator const __m128d( void ) const { return _mm_castps_pd(v); }
__forceinline vboolf(bool a)
__forceinline vboolf( bool a )
: v(_mm_lookupmask_ps[(size_t(a) << 3) | (size_t(a) << 2) | (size_t(a) << 1) | size_t(a)]) {}
__forceinline vboolf(bool a, bool b)
__forceinline vboolf( bool a, bool b )
: v(_mm_lookupmask_ps[(size_t(b) << 3) | (size_t(a) << 2) | (size_t(b) << 1) | size_t(a)]) {}
__forceinline vboolf(bool a, bool b, bool c, bool d)
__forceinline vboolf( bool a, bool b, bool c, bool d )
: v(_mm_lookupmask_ps[(size_t(d) << 3) | (size_t(c) << 2) | (size_t(b) << 1) | size_t(a)]) {}
__forceinline vboolf(int mask) { assert(mask >= 0 && mask < 16); v = _mm_lookupmask_ps[mask]; }
__forceinline vboolf(unsigned int mask) { assert(mask < 16); v = _mm_lookupmask_ps[mask]; }
__forceinline vboolf( int mask ) {
assert(mask >= 0 && mask < 16);
v = _mm_lookupmask_ps[mask];
}
/* return int32 mask */
__forceinline __m128i mask32() const {
@@ -60,47 +62,47 @@ namespace embree
/// Constants
////////////////////////////////////////////////////////////////////////////////
__forceinline vboolf(FalseTy) : v(_mm_setzero_ps()) {}
__forceinline vboolf(TrueTy) : v(_mm_castsi128_ps(_mm_cmpeq_epi32(_mm_setzero_si128(), _mm_setzero_si128()))) {}
__forceinline vboolf( FalseTy ) : v(_mm_setzero_ps()) {}
__forceinline vboolf( TrueTy ) : v(_mm_castsi128_ps(_mm_cmpeq_epi32(_mm_setzero_si128(), _mm_setzero_si128()))) {}
////////////////////////////////////////////////////////////////////////////////
/// Array Access
////////////////////////////////////////////////////////////////////////////////
__forceinline bool operator [](size_t index) const { assert(index < 4); return (_mm_movemask_ps(v) >> index) & 1; }
__forceinline int& operator [](size_t index) { assert(index < 4); return i[index]; }
__forceinline bool operator []( const size_t index ) const { assert(index < 4); return (_mm_movemask_ps(v) >> index) & 1; }
__forceinline int& operator []( const size_t index ) { assert(index < 4); return i[index]; }
};
////////////////////////////////////////////////////////////////////////////////
/// Unary Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline vboolf4 operator !(const vboolf4& a) { return _mm_xor_ps(a, vboolf4(embree::True)); }
__forceinline const vboolf4 operator !( const vboolf4& a ) { return _mm_xor_ps(a, vboolf4(embree::True)); }
////////////////////////////////////////////////////////////////////////////////
/// Binary Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline vboolf4 operator &(const vboolf4& a, const vboolf4& b) { return _mm_and_ps(a, b); }
__forceinline vboolf4 operator |(const vboolf4& a, const vboolf4& b) { return _mm_or_ps (a, b); }
__forceinline vboolf4 operator ^(const vboolf4& a, const vboolf4& b) { return _mm_xor_ps(a, b); }
__forceinline const vboolf4 operator &( const vboolf4& a, const vboolf4& b ) { return _mm_and_ps(a, b); }
__forceinline const vboolf4 operator |( const vboolf4& a, const vboolf4& b ) { return _mm_or_ps (a, b); }
__forceinline const vboolf4 operator ^( const vboolf4& a, const vboolf4& b ) { return _mm_xor_ps(a, b); }
////////////////////////////////////////////////////////////////////////////////
/// Assignment Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline vboolf4& operator &=(vboolf4& a, const vboolf4& b) { return a = a & b; }
__forceinline vboolf4& operator |=(vboolf4& a, const vboolf4& b) { return a = a | b; }
__forceinline vboolf4& operator ^=(vboolf4& a, const vboolf4& b) { return a = a ^ b; }
__forceinline const vboolf4 operator &=( vboolf4& a, const vboolf4& b ) { return a = a & b; }
__forceinline const vboolf4 operator |=( vboolf4& a, const vboolf4& b ) { return a = a | b; }
__forceinline const vboolf4 operator ^=( vboolf4& a, const vboolf4& b ) { return a = a ^ b; }
////////////////////////////////////////////////////////////////////////////////
/// Comparison Operators + Select
////////////////////////////////////////////////////////////////////////////////
__forceinline vboolf4 operator !=(const vboolf4& a, const vboolf4& b) { return _mm_xor_ps(a, b); }
__forceinline vboolf4 operator ==(const vboolf4& a, const vboolf4& b) { return _mm_castsi128_ps(_mm_cmpeq_epi32(a, b)); }
__forceinline const vboolf4 operator !=( const vboolf4& a, const vboolf4& b ) { return _mm_xor_ps(a, b); }
__forceinline const vboolf4 operator ==( const vboolf4& a, const vboolf4& b ) { return _mm_castsi128_ps(_mm_cmpeq_epi32(a, b)); }
__forceinline vboolf4 select(const vboolf4& m, const vboolf4& t, const vboolf4& f) {
__forceinline const vboolf4 select( const vboolf4& m, const vboolf4& t, const vboolf4& f ) {
#if defined(__SSE4_1__)
return _mm_blendv_ps(f, t, m);
#else
@@ -112,56 +114,53 @@ namespace embree
/// Movement/Shifting/Shuffling Functions
////////////////////////////////////////////////////////////////////////////////
__forceinline vboolf4 unpacklo(const vboolf4& a, const vboolf4& b) { return _mm_unpacklo_ps(a, b); }
__forceinline vboolf4 unpackhi(const vboolf4& a, const vboolf4& b) { return _mm_unpackhi_ps(a, b); }
__forceinline const vboolf4 unpacklo( const vboolf4& a, const vboolf4& b ) { return _mm_unpacklo_ps(a, b); }
__forceinline const vboolf4 unpackhi( const vboolf4& a, const vboolf4& b ) { return _mm_unpackhi_ps(a, b); }
template<int i0, int i1, int i2, int i3>
__forceinline vboolf4 shuffle(const vboolf4& v) {
return _mm_shuffle_epi32(v, _MM_SHUFFLE(i3, i2, i1, i0));
template<size_t i0, size_t i1, size_t i2, size_t i3> __forceinline const vboolf4 shuffle( const vboolf4& a ) {
return _mm_shuffle_epi32(a, _MM_SHUFFLE(i3, i2, i1, i0));
}
template<int i0, int i1, int i2, int i3>
__forceinline vboolf4 shuffle(const vboolf4& a, const vboolf4& b) {
template<size_t i0, size_t i1, size_t i2, size_t i3> __forceinline const vboolf4 shuffle( const vboolf4& a, const vboolf4& b ) {
return _mm_shuffle_ps(a, b, _MM_SHUFFLE(i3, i2, i1, i0));
}
template<int i0>
__forceinline vboolf4 shuffle(const vboolf4& v) {
return shuffle<i0,i0,i0,i0>(v);
template<size_t i0> __forceinline const vboolf4 shuffle( const vboolf4& b ) {
return shuffle<i0,i0,i0,i0>(b);
}
#if defined(__SSE3__)
template<> __forceinline vboolf4 shuffle<0, 0, 2, 2>(const vboolf4& v) { return _mm_moveldup_ps(v); }
template<> __forceinline vboolf4 shuffle<1, 1, 3, 3>(const vboolf4& v) { return _mm_movehdup_ps(v); }
template<> __forceinline vboolf4 shuffle<0, 1, 0, 1>(const vboolf4& v) { return _mm_castpd_ps(_mm_movedup_pd(v)); }
template<> __forceinline const vboolf4 shuffle<0, 0, 2, 2>( const vboolf4& a ) { return _mm_moveldup_ps(a); }
template<> __forceinline const vboolf4 shuffle<1, 1, 3, 3>( const vboolf4& a ) { return _mm_movehdup_ps(a); }
template<> __forceinline const vboolf4 shuffle<0, 1, 0, 1>( const vboolf4& a ) { return _mm_castpd_ps(_mm_movedup_pd (a)); }
#endif
#if defined(__SSE4_1__)
template<int dst, int src, int clr> __forceinline vboolf4 insert(const vboolf4& a, const vboolf4& b) { return _mm_insert_ps(a, b, (dst << 4) | (src << 6) | clr); }
template<int dst, int src> __forceinline vboolf4 insert(const vboolf4& a, const vboolf4& b) { return insert<dst, src, 0>(a, b); }
template<int dst> __forceinline vboolf4 insert(const vboolf4& a, const bool b) { return insert<dst, 0>(a, vboolf4(b)); }
template<size_t dst, size_t src, size_t clr> __forceinline const vboolf4 insert( const vboolf4& a, const vboolf4& b ) { return _mm_insert_ps(a, b, (dst << 4) | (src << 6) | clr); }
template<size_t dst, size_t src> __forceinline const vboolf4 insert( const vboolf4& a, const vboolf4& b ) { return insert<dst, src, 0>(a, b); }
template<size_t dst> __forceinline const vboolf4 insert( const vboolf4& a, const bool b ) { return insert<dst,0>(a, vboolf4(b)); }
#endif
////////////////////////////////////////////////////////////////////////////////
/// Reduction Operations
////////////////////////////////////////////////////////////////////////////////
__forceinline bool reduce_and(const vboolf4& a) { return _mm_movemask_ps(a) == 0xf; }
__forceinline bool reduce_or (const vboolf4& a) { return _mm_movemask_ps(a) != 0x0; }
__forceinline bool reduce_and( const vboolf4& a ) { return _mm_movemask_ps(a) == 0xf; }
__forceinline bool reduce_or ( const vboolf4& a ) { return _mm_movemask_ps(a) != 0x0; }
__forceinline bool all (const vboolf4& b) { return _mm_movemask_ps(b) == 0xf; }
__forceinline bool any (const vboolf4& b) { return _mm_movemask_ps(b) != 0x0; }
__forceinline bool none(const vboolf4& b) { return _mm_movemask_ps(b) == 0x0; }
__forceinline bool all ( const vboolf4& b ) { return _mm_movemask_ps(b) == 0xf; }
__forceinline bool any ( const vboolf4& b ) { return _mm_movemask_ps(b) != 0x0; }
__forceinline bool none ( const vboolf4& b ) { return _mm_movemask_ps(b) == 0x0; }
__forceinline bool all (const vboolf4& valid, const vboolf4& b) { return all((!valid) | b); }
__forceinline bool any (const vboolf4& valid, const vboolf4& b) { return any(valid & b); }
__forceinline bool none(const vboolf4& valid, const vboolf4& b) { return none(valid & b); }
__forceinline bool all ( const vboolf4& valid, const vboolf4& b ) { return all((!valid) | b); }
__forceinline bool any ( const vboolf4& valid, const vboolf4& b ) { return any( valid & b); }
__forceinline bool none ( const vboolf4& valid, const vboolf4& b ) { return none(valid & b); }
__forceinline size_t movemask(const vboolf4& a) { return _mm_movemask_ps(a); }
__forceinline size_t movemask( const vboolf4& a ) { return _mm_movemask_ps(a); }
#if defined(__SSE4_2__)
__forceinline size_t popcnt(const vboolf4& a) { return __popcnt((size_t)_mm_movemask_ps(a)); }
__forceinline size_t popcnt( const vboolf4& a ) { return __popcnt((size_t)_mm_movemask_ps(a)); }
#else
__forceinline size_t popcnt(const vboolf4& a) { return bool(a[0])+bool(a[1])+bool(a[2])+bool(a[3]); }
__forceinline size_t popcnt( const vboolf4& a ) { return bool(a[0])+bool(a[1])+bool(a[2])+bool(a[3]); }
#endif
////////////////////////////////////////////////////////////////////////////////
@@ -176,7 +175,7 @@ namespace embree
/// Output Operators
////////////////////////////////////////////////////////////////////////////////
inline std::ostream& operator <<(std::ostream& cout, const vboolf4& a) {
inline std::ostream& operator<<(std::ostream& cout, const vboolf4& a) {
return cout << "<" << a[0] << ", " << a[1] << ", " << a[2] << ", " << a[3] << ">";
}
}
+57 -62
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
@@ -37,16 +37,16 @@ namespace embree
/// Constructors, Assignment & Cast Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline vboolf() {}
__forceinline vboolf(const vboolf8& a) { v = a.v; }
__forceinline vboolf8& operator =(const vboolf8& a) { v = a.v; return *this; }
__forceinline vboolf () {}
__forceinline vboolf ( const vboolf8& a ) { v = a.v; }
__forceinline vboolf8& operator=( const vboolf8& a ) { v = a.v; return *this; }
__forceinline vboolf(__m256 a) : v(a) {}
__forceinline operator const __m256&() const { return v; }
__forceinline operator const __m256i() const { return _mm256_castps_si256(v); }
__forceinline operator const __m256d() const { return _mm256_castps_pd(v); }
__forceinline vboolf( const __m256 a ) : v(a) {}
__forceinline operator const __m256&( void ) const { return v; }
__forceinline operator const __m256i( void ) const { return _mm256_castps_si256(v); }
__forceinline operator const __m256d( void ) const { return _mm256_castps_pd(v); }
__forceinline vboolf(int a)
__forceinline vboolf ( const int a )
{
assert(a >= 0 && a <= 255);
#if defined (__AVX2__)
@@ -60,14 +60,14 @@ namespace embree
#endif
}
__forceinline vboolf(const vboolf4& a) : v(_mm256_insertf128_ps(_mm256_castps128_ps256(a),a,1)) {}
__forceinline vboolf(const vboolf4& a, const vboolf4& b) : v(_mm256_insertf128_ps(_mm256_castps128_ps256(a),b,1)) {}
__forceinline vboolf(__m128 a, __m128 b) : vl(a), vh(b) {}
__forceinline vboolf ( const vboolf4& a ) : v(_mm256_insertf128_ps(_mm256_castps128_ps256(a),a,1)) {}
__forceinline vboolf ( const vboolf4& a, const vboolf4& b) : v(_mm256_insertf128_ps(_mm256_castps128_ps256(a),b,1)) {}
__forceinline vboolf ( const __m128 a, const __m128 b) : vl(a), vh(b) {}
__forceinline vboolf(bool a) : v(vboolf8(vboolf4(a), vboolf4(a))) {}
__forceinline vboolf(bool a, bool b) : v(vboolf8(vboolf4(a), vboolf4(b))) {}
__forceinline vboolf(bool a, bool b, bool c, bool d) : v(vboolf8(vboolf4(a,b), vboolf4(c,d))) {}
__forceinline vboolf(bool a, bool b, bool c, bool d, bool e, bool f, bool g, bool h) : v(vboolf8(vboolf4(a,b,c,d), vboolf4(e,f,g,h))) {}
__forceinline vboolf ( bool a ) : v(vboolf8(vboolf4(a), vboolf4(a))) {}
__forceinline vboolf ( bool a, bool b) : v(vboolf8(vboolf4(a), vboolf4(b))) {}
__forceinline vboolf ( bool a, bool b, bool c, bool d) : v(vboolf8(vboolf4(a,b), vboolf4(c,d))) {}
__forceinline vboolf ( bool a, bool b, bool c, bool d, bool e, bool f, bool g, bool vh ) : v(vboolf8(vboolf4(a,b,c,d), vboolf4(e,f,g,vh))) {}
/* return int32 mask */
__forceinline __m256i mask32() const {
@@ -78,43 +78,43 @@ namespace embree
/// Constants
////////////////////////////////////////////////////////////////////////////////
__forceinline vboolf(FalseTy) : v(_mm256_setzero_ps()) {}
__forceinline vboolf(TrueTy) : v(_mm256_cmp_ps(_mm256_setzero_ps(), _mm256_setzero_ps(), _CMP_EQ_OQ)) {}
__forceinline vboolf( FalseTy ) : v(_mm256_setzero_ps()) {}
__forceinline vboolf( TrueTy ) : v(_mm256_cmp_ps(_mm256_setzero_ps(), _mm256_setzero_ps(), _CMP_EQ_OQ)) {}
////////////////////////////////////////////////////////////////////////////////
/// Array Access
////////////////////////////////////////////////////////////////////////////////
__forceinline bool operator [](size_t index) const { assert(index < 8); return (_mm256_movemask_ps(v) >> index) & 1; }
__forceinline int& operator [](size_t index) { assert(index < 8); return i[index]; }
__forceinline bool operator []( const size_t index ) const { assert(index < 8); return (_mm256_movemask_ps(v) >> index) & 1; }
__forceinline int& operator []( const size_t index ) { assert(index < 8); return i[index]; }
};
////////////////////////////////////////////////////////////////////////////////
/// Unary Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline vboolf8 operator !(const vboolf8& a) { return _mm256_xor_ps(a, vboolf8(embree::True)); }
__forceinline const vboolf8 operator !( const vboolf8& a ) { return _mm256_xor_ps(a, vboolf8(embree::True)); }
////////////////////////////////////////////////////////////////////////////////
/// Binary Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline vboolf8 operator &(const vboolf8& a, const vboolf8& b) { return _mm256_and_ps(a, b); }
__forceinline vboolf8 operator |(const vboolf8& a, const vboolf8& b) { return _mm256_or_ps (a, b); }
__forceinline vboolf8 operator ^(const vboolf8& a, const vboolf8& b) { return _mm256_xor_ps(a, b); }
__forceinline const vboolf8 operator &( const vboolf8& a, const vboolf8& b ) { return _mm256_and_ps(a, b); }
__forceinline const vboolf8 operator |( const vboolf8& a, const vboolf8& b ) { return _mm256_or_ps (a, b); }
__forceinline const vboolf8 operator ^( const vboolf8& a, const vboolf8& b ) { return _mm256_xor_ps(a, b); }
__forceinline vboolf8& operator &=(vboolf8& a, const vboolf8& b) { return a = a & b; }
__forceinline vboolf8& operator |=(vboolf8& a, const vboolf8& b) { return a = a | b; }
__forceinline vboolf8& operator ^=(vboolf8& a, const vboolf8& b) { return a = a ^ b; }
__forceinline vboolf8 operator &=( vboolf8& a, const vboolf8& b ) { return a = a & b; }
__forceinline vboolf8 operator |=( vboolf8& a, const vboolf8& b ) { return a = a | b; }
__forceinline vboolf8 operator ^=( vboolf8& a, const vboolf8& b ) { return a = a ^ b; }
////////////////////////////////////////////////////////////////////////////////
/// Comparison Operators + Select
////////////////////////////////////////////////////////////////////////////////
__forceinline vboolf8 operator !=(const vboolf8& a, const vboolf8& b) { return _mm256_xor_ps(a, b); }
__forceinline vboolf8 operator ==(const vboolf8& a, const vboolf8& b) { return _mm256_xor_ps(_mm256_xor_ps(a,b),vboolf8(embree::True)); }
__forceinline const vboolf8 operator !=( const vboolf8& a, const vboolf8& b ) { return _mm256_xor_ps(a, b); }
__forceinline const vboolf8 operator ==( const vboolf8& a, const vboolf8& b ) { return _mm256_xor_ps(_mm256_xor_ps(a,b),vboolf8(embree::True)); }
__forceinline vboolf8 select(const vboolf8& mask, const vboolf8& t, const vboolf8& f) {
__forceinline const vboolf8 select( const vboolf8& mask, const vboolf8& t, const vboolf8& f ) {
return _mm256_blendv_ps(f, t, mask);
}
@@ -122,59 +122,54 @@ namespace embree
/// Movement/Shifting/Shuffling Functions
////////////////////////////////////////////////////////////////////////////////
__forceinline vboolf8 unpacklo(const vboolf8& a, const vboolf8& b) { return _mm256_unpacklo_ps(a, b); }
__forceinline vboolf8 unpackhi(const vboolf8& a, const vboolf8& b) { return _mm256_unpackhi_ps(a, b); }
__forceinline vboolf8 unpacklo( const vboolf8& a, const vboolf8& b ) { return _mm256_unpacklo_ps(a.v, b.v); }
__forceinline vboolf8 unpackhi( const vboolf8& a, const vboolf8& b ) { return _mm256_unpackhi_ps(a.v, b.v); }
template<int i>
__forceinline vboolf8 shuffle(const vboolf8& v) {
return _mm256_permute_ps(v, _MM_SHUFFLE(i, i, i, i));
template<size_t i> __forceinline const vboolf8 shuffle( const vboolf8& a ) {
return _mm256_permute_ps(a, _MM_SHUFFLE(i, i, i, i));
}
template<int i0, int i1>
__forceinline vboolf8 shuffle4(const vboolf8& v) {
return _mm256_permute2f128_ps(v, v, (i1 << 4) | (i0 << 0));
template<size_t i0, size_t i1> __forceinline const vboolf8 shuffle4( const vboolf8& a ) {
return _mm256_permute2f128_ps(a, a, (i1 << 4) | (i0 << 0));
}
template<int i0, int i1>
__forceinline vboolf8 shuffle4(const vboolf8& a, const vboolf8& b) {
template<size_t i0, size_t i1> __forceinline const vboolf8 shuffle4( const vboolf8& a, const vboolf8& b) {
return _mm256_permute2f128_ps(a, b, (i1 << 4) | (i0 << 0));
}
template<int i0, int i1, int i2, int i3>
__forceinline vboolf8 shuffle(const vboolf8& v) {
return _mm256_permute_ps(v, _MM_SHUFFLE(i3, i2, i1, i0));
template<size_t i0, size_t i1, size_t i2, size_t i3> __forceinline const vboolf8 shuffle( const vboolf8& a ) {
return _mm256_permute_ps(a, _MM_SHUFFLE(i3, i2, i1, i0));
}
template<int i0, int i1, int i2, int i3>
__forceinline vboolf8 shuffle(const vboolf8& a, const vboolf8& b) {
template<size_t i0, size_t i1, size_t i2, size_t i3> __forceinline const vboolf8 shuffle( const vboolf8& a, const vboolf8& b ) {
return _mm256_shuffle_ps(a, b, _MM_SHUFFLE(i3, i2, i1, i0));
}
template<> __forceinline vboolf8 shuffle<0, 0, 2, 2>(const vboolf8& v) { return _mm256_moveldup_ps(v); }
template<> __forceinline vboolf8 shuffle<1, 1, 3, 3>(const vboolf8& v) { return _mm256_movehdup_ps(v); }
template<> __forceinline vboolf8 shuffle<0, 1, 0, 1>(const vboolf8& v) { return _mm256_castpd_ps(_mm256_movedup_pd(_mm256_castps_pd(v))); }
template<> __forceinline const vboolf8 shuffle<0, 0, 2, 2>( const vboolf8& b ) { return _mm256_moveldup_ps(b); }
template<> __forceinline const vboolf8 shuffle<1, 1, 3, 3>( const vboolf8& b ) { return _mm256_movehdup_ps(b); }
template<> __forceinline const vboolf8 shuffle<0, 1, 0, 1>( const vboolf8& b ) { return _mm256_castpd_ps(_mm256_movedup_pd(_mm256_castps_pd(b))); }
template<int i> __forceinline vboolf8 insert4(const vboolf8& a, const vboolf4& b) { return _mm256_insertf128_ps(a, b, i); }
template<int i> __forceinline vboolf4 extract4 (const vboolf8& a) { return _mm256_extractf128_ps(a, i); }
template<> __forceinline vboolf4 extract4<0>(const vboolf8& a) { return _mm256_castps256_ps128(a); }
template<size_t i> __forceinline const vboolf8 insert4(const vboolf8& a, const vboolf4& b) { return _mm256_insertf128_ps(a, b, i); }
template<size_t i> __forceinline const vboolf4 extract4 (const vboolf8& a) { return _mm256_extractf128_ps(a, i); }
template<> __forceinline const vboolf4 extract4<0>(const vboolf8& a) { return _mm256_castps256_ps128(a); }
////////////////////////////////////////////////////////////////////////////////
/// Reduction Operations
////////////////////////////////////////////////////////////////////////////////
__forceinline bool reduce_and(const vboolf8& a) { return _mm256_movemask_ps(a) == (unsigned int)0xff; }
__forceinline bool reduce_or (const vboolf8& a) { return !_mm256_testz_ps(a,a); }
__forceinline bool reduce_and( const vboolf8& a ) { return _mm256_movemask_ps(a) == (unsigned int)0xff; }
__forceinline bool reduce_or ( const vboolf8& a ) { return !_mm256_testz_ps(a,a); }
__forceinline bool all (const vboolf8& a) { return _mm256_movemask_ps(a) == (unsigned int)0xff; }
__forceinline bool any (const vboolf8& a) { return !_mm256_testz_ps(a,a); }
__forceinline bool none(const vboolf8& a) { return _mm256_testz_ps(a,a) != 0; }
__forceinline bool all ( const vboolf8& a ) { return _mm256_movemask_ps(a) == (unsigned int)0xff; }
__forceinline bool any ( const vboolf8& a ) { return !_mm256_testz_ps(a,a); }
__forceinline bool none ( const vboolf8& a ) { return _mm256_testz_ps(a,a) != 0; }
__forceinline bool all (const vboolf8& valid, const vboolf8& b) { return all((!valid) | b); }
__forceinline bool any (const vboolf8& valid, const vboolf8& b) { return any(valid & b); }
__forceinline bool none(const vboolf8& valid, const vboolf8& b) { return none(valid & b); }
__forceinline bool all ( const vboolf8& valid, const vboolf8& b ) { return all((!valid) | b); }
__forceinline bool any ( const vboolf8& valid, const vboolf8& b ) { return any( valid & b); }
__forceinline bool none ( const vboolf8& valid, const vboolf8& b ) { return none(valid & b); }
__forceinline unsigned int movemask(const vboolf8& a) { return _mm256_movemask_ps(a); }
__forceinline size_t popcnt (const vboolf8& a) { return __popcnt((size_t)_mm256_movemask_ps(a)); }
__forceinline unsigned int movemask( const vboolf8& a ) { return _mm256_movemask_ps(a); }
__forceinline size_t popcnt ( const vboolf8& a ) { return __popcnt((size_t)_mm256_movemask_ps(a)); }
////////////////////////////////////////////////////////////////////////////////
/// Get/Set Functions
@@ -188,7 +183,7 @@ namespace embree
/// Output Operators
////////////////////////////////////////////////////////////////////////////////
inline std::ostream& operator <<(std::ostream& cout, const vboolf8& a) {
inline std::ostream& operator<<(std::ostream& cout, const vboolf8& a) {
return cout << "<" << a[0] << ", " << a[1] << ", " << a[2] << ", " << a[3] << ", "
<< a[4] << ", " << a[5] << ", " << a[6] << ", " << a[7] << ">";
}
+26 -26
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
@@ -33,8 +33,8 @@ namespace embree
////////////////////////////////////////////////////////////////////////////////
__forceinline vboolf() {}
__forceinline vboolf(const vboolf8& t) { v = t.v; }
__forceinline vboolf8& operator =(const vboolf8& f) { v = f.v; return *this; }
__forceinline vboolf(const vboolf8 &t) { v = t.v; }
__forceinline vboolf8& operator=(const vboolf8 &f) { v = f.v; return *this; }
__forceinline vboolf(const __mmask8 &t) { v = t; }
__forceinline operator __mmask8() const { return v; }
@@ -62,42 +62,42 @@ namespace embree
/// Constants
////////////////////////////////////////////////////////////////////////////////
__forceinline vboolf(FalseTy) : v(0x00) {}
__forceinline vboolf(TrueTy) : v(0xff) {}
__forceinline vboolf( FalseTy ) : v(0x00) {}
__forceinline vboolf( TrueTy ) : v(0xff) {}
};
////////////////////////////////////////////////////////////////////////////////
/// Unary Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline vboolf8 operator !(const vboolf8& a) { return _mm512_knot(a); }
__forceinline vboolf8 operator!(const vboolf8 &a) { return _mm512_knot(a); }
////////////////////////////////////////////////////////////////////////////////
/// Binary Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline vboolf8 operator &(const vboolf8& a, const vboolf8& b) { return _mm512_kand(a, b); }
__forceinline vboolf8 operator |(const vboolf8& a, const vboolf8& b) { return _mm512_kor(a, b); }
__forceinline vboolf8 operator ^(const vboolf8& a, const vboolf8& b) { return _mm512_kxor(a, b); }
__forceinline vboolf8 operator&(const vboolf8 &a, const vboolf8 &b) { return _mm512_kand(a, b); }
__forceinline vboolf8 operator|(const vboolf8 &a, const vboolf8 &b) { return _mm512_kor(a, b); }
__forceinline vboolf8 operator^(const vboolf8 &a, const vboolf8 &b) { return _mm512_kxor(a, b); }
__forceinline vboolf8 andn(const vboolf8& a, const vboolf8& b) { return _mm512_kandn(b, a); }
__forceinline vboolf8 andn(const vboolf8 &a, const vboolf8 &b) { return _mm512_kandn(b, a); }
////////////////////////////////////////////////////////////////////////////////
/// Assignment Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline vboolf8& operator &=(vboolf8& a, const vboolf8& b) { return a = a & b; }
__forceinline vboolf8& operator |=(vboolf8& a, const vboolf8& b) { return a = a | b; }
__forceinline vboolf8& operator ^=(vboolf8& a, const vboolf8& b) { return a = a ^ b; }
__forceinline const vboolf8 operator &=( vboolf8& a, const vboolf8& b ) { return a = a & b; }
__forceinline const vboolf8 operator |=( vboolf8& a, const vboolf8& b ) { return a = a | b; }
__forceinline const vboolf8 operator ^=( vboolf8& a, const vboolf8& b ) { return a = a ^ b; }
////////////////////////////////////////////////////////////////////////////////
/// Comparison Operators + Select
////////////////////////////////////////////////////////////////////////////////
__forceinline vboolf8 operator !=(const vboolf8& a, const vboolf8& b) { return _mm512_kxor(a, b); }
__forceinline vboolf8 operator ==(const vboolf8& a, const vboolf8& b) { return _mm512_kxnor(a, b); }
__forceinline const vboolf8 operator !=( const vboolf8& a, const vboolf8& b ) { return _mm512_kxor(a, b); }
__forceinline const vboolf8 operator ==( const vboolf8& a, const vboolf8& b ) { return _mm512_kxnor(a, b); }
__forceinline vboolf8 select(const vboolf8& s, const vboolf8& a, const vboolf8& b) {
__forceinline vboolf8 select(const vboolf8 &s, const vboolf8 &a, const vboolf8 &b) {
return _mm512_kor(_mm512_kand(s, a), _mm512_kandn(s, b));
}
@@ -105,22 +105,22 @@ namespace embree
/// Reduction Operations
////////////////////////////////////////////////////////////////////////////////
__forceinline int all (const vboolf8& a) { return a.v == 0xff; }
__forceinline int any (const vboolf8& a) { return _mm512_kortestz(a, a) == 0; }
__forceinline int none(const vboolf8& a) { return _mm512_kortestz(a, a) != 0; }
__forceinline int all (const vboolf8 &a) { return a.v == 0xff; }
__forceinline int any (const vboolf8 &a) { return _mm512_kortestz(a, a) == 0; }
__forceinline int none(const vboolf8 &a) { return _mm512_kortestz(a, a) != 0; }
__forceinline int all (const vboolf8& valid, const vboolf8& b) { return all((!valid) | b); }
__forceinline int any (const vboolf8& valid, const vboolf8& b) { return any(valid & b); }
__forceinline int none(const vboolf8& valid, const vboolf8& b) { return none(valid & b); }
__forceinline int all ( const vboolf8& valid, const vboolf8& b ) { return all((!valid) | b); }
__forceinline int any ( const vboolf8& valid, const vboolf8& b ) { return any( valid & b); }
__forceinline int none( const vboolf8& valid, const vboolf8& b ) { return none(valid & b); }
__forceinline size_t movemask(const vboolf8& a) { return _mm512_kmov(a); }
__forceinline size_t popcnt (const vboolf8& a) { return __popcnt(a.v); }
__forceinline size_t movemask( const vboolf8& a ) { return _mm512_kmov(a); }
__forceinline size_t popcnt ( const vboolf8& a ) { return _mm_countbits_64(a.v); }
////////////////////////////////////////////////////////////////////////////////
/// Conversion Operations
////////////////////////////////////////////////////////////////////////////////
__forceinline unsigned int toInt(const vboolf8& a) { return mm512_mask2int(a); }
__forceinline unsigned int toInt(const vboolf8 &a) { return _mm512_mask2int(a); }
////////////////////////////////////////////////////////////////////////////////
/// Get/Set Functions
@@ -134,7 +134,7 @@ namespace embree
/// Output Operators
////////////////////////////////////////////////////////////////////////////////
inline std::ostream& operator <<(std::ostream& cout, const vboolf8& a)
inline std::ostream& operator<<(std::ostream& cout, const vboolf8& a)
{
cout << "<";
for (size_t i=0; i<8; i++) {
+112 -120
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
@@ -18,7 +18,17 @@
namespace embree
{
/* 4-wide AVX 64-bit double type */
#ifndef _MM_SHUF_PERM2
#define _MM_SHUF_PERM2(e3, e2, e1, e0) \
((int)(((e3)<<3) | ((e2)<<2) | ((e1)<<1) | (e0)))
#endif
#ifndef _MM_SHUF_PERM3
#define _MM_SHUF_PERM3(e1, e0) \
((int)(((e1)<<4) | (e0)))
#endif
/* 4-wide AVX 64bit double type */
template<>
struct vdouble<4>
{
@@ -36,16 +46,16 @@ namespace embree
__forceinline vdouble() {}
__forceinline vdouble(const vdouble4& t) { v = t.v; }
__forceinline vdouble4& operator =(const vdouble4& f) { v = f.v; return *this; }
__forceinline vdouble4& operator=(const vdouble4& f) { v = f.v; return *this; }
__forceinline vdouble(const __m256d& t) { v = t; }
__forceinline operator __m256d() const { return v; }
__forceinline operator __m256d () const { return v; }
__forceinline vdouble(double i) {
__forceinline vdouble(const double i) {
v = _mm256_set1_pd(i);
}
__forceinline vdouble(double a, double b, double c, double d) {
__forceinline vdouble(const double a, const double b, const double c, const double d) {
v = _mm256_set_pd(d,c,b,a);
}
@@ -54,20 +64,25 @@ namespace embree
/// Constants
////////////////////////////////////////////////////////////////////////////////
__forceinline vdouble(ZeroTy) : v(_mm256_setzero_pd()) {}
__forceinline vdouble(OneTy) : v(_mm256_set1_pd(1)) {}
__forceinline vdouble(StepTy) : v(_mm256_set_pd(3.0,2.0,1.0,0.0)) {}
__forceinline vdouble(ReverseStepTy) : v(_mm256_setr_pd(3.0,2.0,1.0,0.0)) {}
__forceinline vdouble( ZeroTy ) : v(_mm256_setzero_pd()) {}
__forceinline vdouble( OneTy ) : v(_mm256_set1_pd(1)) {}
__forceinline vdouble( StepTy ) : v(_mm256_set_pd(3.0,2.0,1.0,0.0)) {}
__forceinline vdouble( ReverseStepTy ) : v(_mm256_setr_pd(3.0,2.0,1.0,0.0)) {}
__forceinline static vdouble4 zero() { return _mm256_setzero_pd(); }
__forceinline static vdouble4 one () { return _mm256_set1_pd(1.0); }
__forceinline static vdouble4 neg_one () { return _mm256_set1_pd(-1.0); }
////////////////////////////////////////////////////////////////////////////////
/// Loads and Stores
////////////////////////////////////////////////////////////////////////////////
static __forceinline void store_nt(double *__restrict__ ptr, const vdouble4& a) {
_mm256_stream_pd(ptr, a);
_mm256_stream_pd(ptr,a);
}
static __forceinline vdouble4 loadu(const double* addr) {
static __forceinline vdouble4 loadu(const double* addr)
{
return _mm256_loadu_pd(addr);
}
@@ -80,11 +95,11 @@ namespace embree
}
static __forceinline void store(double* ptr, const vdouble4& v) {
_mm256_store_pd(ptr, v);
_mm256_store_pd(ptr,v);
}
static __forceinline void storeu(double* ptr, const vdouble4& v) {
_mm256_storeu_pd(ptr, v);
static __forceinline void storeu(double* ptr, const vdouble4& v ) {
_mm256_storeu_pd(ptr,v);
}
@@ -92,71 +107,72 @@ namespace embree
/// Array Access
////////////////////////////////////////////////////////////////////////////////
__forceinline double& operator [](size_t index) { assert(index < 4); return i[index]; }
__forceinline const double& operator [](size_t index) const { assert(index < 4); return i[index]; }
__forceinline double& operator[](const size_t index) { assert(index < 8); return i[index]; }
__forceinline const double& operator[](const size_t index) const { assert(index < 8); return i[index]; }
};
////////////////////////////////////////////////////////////////////////////////
/// Unary Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline vdouble4 operator +(const vdouble4& a) { return a; }
__forceinline vdouble4 operator -(const vdouble4& a) { return _mm256_sub_pd(_mm256_setzero_pd(), a); }
__forceinline const vdouble4 operator +( const vdouble4& a ) { return a; }
__forceinline const vdouble4 operator -( const vdouble4& a ) { return _mm256_sub_pd(_mm256_setzero_pd(), a); }
////////////////////////////////////////////////////////////////////////////////
/// Binary Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline vdouble4 operator +(const vdouble4& a, const vdouble4& b) { return _mm256_add_pd(a, b); }
__forceinline vdouble4 operator +(const vdouble4& a, double b) { return a + vdouble4(b); }
__forceinline vdouble4 operator +(double a, const vdouble4& b) { return vdouble4(a) + b; }
__forceinline const vdouble4 operator +( const vdouble4& a, const vdouble4& b ) { return _mm256_add_pd(a, b); }
__forceinline const vdouble4 operator +( const vdouble4& a, const double b ) { return a + vdouble4(b); }
__forceinline const vdouble4 operator +( const double a, const vdouble4& b ) { return vdouble4(a) + b; }
__forceinline vdouble4 operator -(const vdouble4& a, const vdouble4& b) { return _mm256_sub_pd(a, b); }
__forceinline vdouble4 operator -(const vdouble4& a, double b) { return a - vdouble4(b); }
__forceinline vdouble4 operator -(double a, const vdouble4& b) { return vdouble4(a) - b; }
__forceinline const vdouble4 operator -( const vdouble4& a, const vdouble4& b ) { return _mm256_sub_pd(a, b); }
__forceinline const vdouble4 operator -( const vdouble4& a, const double b ) { return a - vdouble4(b); }
__forceinline const vdouble4 operator -( const double a, const vdouble4& b ) { return vdouble4(a) - b; }
__forceinline vdouble4 operator *(const vdouble4& a, const vdouble4& b) { return _mm256_mul_pd(a, b); }
__forceinline vdouble4 operator *(const vdouble4& a, double b) { return a * vdouble4(b); }
__forceinline vdouble4 operator *(double a, const vdouble4& b) { return vdouble4(a) * b; }
__forceinline const vdouble4 operator *( const vdouble4& a, const vdouble4& b ) { return _mm256_mul_pd(a, b); }
__forceinline const vdouble4 operator *( const vdouble4& a, const double b ) { return a * vdouble4(b); }
__forceinline const vdouble4 operator *( const double a, const vdouble4& b ) { return vdouble4(a) * b; }
__forceinline vdouble4 operator &(const vdouble4& a, const vdouble4& b) { return _mm256_and_pd(a, b); }
__forceinline vdouble4 operator &(const vdouble4& a, double b) { return a & vdouble4(b); }
__forceinline vdouble4 operator &(double a, const vdouble4& b) { return vdouble4(a) & b; }
__forceinline const vdouble4 operator &( const vdouble4& a, const vdouble4& b ) { return _mm256_and_pd(a, b); }
__forceinline const vdouble4 operator &( const vdouble4& a, const double b ) { return a & vdouble4(b); }
__forceinline const vdouble4 operator &( const double a, const vdouble4& b ) { return vdouble4(a) & b; }
__forceinline vdouble4 operator |(const vdouble4& a, const vdouble4& b) { return _mm256_or_pd(a, b); }
__forceinline vdouble4 operator |(const vdouble4& a, double b) { return a | vdouble4(b); }
__forceinline vdouble4 operator |(double a, const vdouble4& b) { return vdouble4(a) | b; }
__forceinline const vdouble4 operator |( const vdouble4& a, const vdouble4& b ) { return _mm256_or_pd(a, b); }
__forceinline const vdouble4 operator |( const vdouble4& a, const double b ) { return a | vdouble4(b); }
__forceinline const vdouble4 operator |( const double a, const vdouble4& b ) { return vdouble4(a) | b; }
__forceinline vdouble4 operator ^(const vdouble4& a, const vdouble4& b) { return _mm256_xor_pd(a, b); }
__forceinline vdouble4 operator ^(const vdouble4& a, double b) { return a ^ vdouble4(b); }
__forceinline vdouble4 operator ^(double a, const vdouble4& b) { return vdouble4(a) ^ b; }
__forceinline const vdouble4 operator ^( const vdouble4& a, const vdouble4& b ) { return _mm256_xor_pd(a, b); }
__forceinline const vdouble4 operator ^( const vdouble4& a, const double b ) { return a ^ vdouble4(b); }
__forceinline const vdouble4 operator ^( const double a, const vdouble4& b ) { return vdouble4(a) ^ b; }
__forceinline vdouble4 min(const vdouble4& a, const vdouble4& b) { return _mm256_min_pd(a, b); }
__forceinline vdouble4 min(const vdouble4& a, double b) { return min(a,vdouble4(b)); }
__forceinline vdouble4 min(double a, const vdouble4& b) { return min(vdouble4(a),b); }
__forceinline const vdouble4 min( const vdouble4& a, const vdouble4& b ) { return _mm256_min_pd(a, b); }
__forceinline const vdouble4 min( const vdouble4& a, const double b ) { return min(a,vdouble4(b)); }
__forceinline const vdouble4 min( const double a, const vdouble4& b ) { return min(vdouble4(a),b); }
__forceinline vdouble4 max(const vdouble4& a, const vdouble4& b) { return _mm256_max_pd(a, b); }
__forceinline vdouble4 max(const vdouble4& a, double b) { return max(a,vdouble4(b)); }
__forceinline vdouble4 max(double a, const vdouble4& b) { return max(vdouble4(a),b); }
__forceinline const vdouble4 max( const vdouble4& a, const vdouble4& b ) { return _mm256_max_pd(a, b); }
__forceinline const vdouble4 max( const vdouble4& a, const double b ) { return max(a,vdouble4(b)); }
__forceinline const vdouble4 max( const double a, const vdouble4& b ) { return max(vdouble4(a),b); }
////////////////////////////////////////////////////////////////////////////////
/// Assignment Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline vdouble4& operator +=(vdouble4& a, const vdouble4& b) { return a = a + b; }
__forceinline vdouble4& operator +=(vdouble4& a, double b) { return a = a + b; }
__forceinline vdouble4& operator +=( vdouble4& a, const vdouble4& b ) { return a = a + b; }
__forceinline vdouble4& operator +=( vdouble4& a, const double b ) { return a = a + b; }
__forceinline vdouble4& operator -=(vdouble4& a, const vdouble4& b) { return a = a - b; }
__forceinline vdouble4& operator -=(vdouble4& a, double b) { return a = a - b; }
__forceinline vdouble4& operator -=( vdouble4& a, const vdouble4& b ) { return a = a - b; }
__forceinline vdouble4& operator -=( vdouble4& a, const double b ) { return a = a - b; }
__forceinline vdouble4& operator *=(vdouble4& a, const vdouble4& b) { return a = a * b; }
__forceinline vdouble4& operator *=(vdouble4& a, double b) { return a = a * b; }
__forceinline vdouble4& operator *=( vdouble4& a, const vdouble4& b ) { return a = a * b; }
__forceinline vdouble4& operator *=( vdouble4& a, const double b ) { return a = a * b; }
__forceinline vdouble4& operator &=(vdouble4& a, const vdouble4& b) { return a = a & b; }
__forceinline vdouble4& operator &=(vdouble4& a, double b) { return a = a & b; }
__forceinline vdouble4& operator &=( vdouble4& a, const vdouble4& b ) { return a = a & b; }
__forceinline vdouble4& operator &=( vdouble4& a, const double b ) { return a = a & b; }
__forceinline vdouble4& operator |=(vdouble4& a, const vdouble4& b) { return a = a | b; }
__forceinline vdouble4& operator |=(vdouble4& a, double b) { return a = a | b; }
__forceinline vdouble4& operator |=( vdouble4& a, const vdouble4& b ) { return a = a | b; }
__forceinline vdouble4& operator |=( vdouble4& a, const double b ) { return a = a | b; }
////////////////////////////////////////////////////////////////////////////////
@@ -164,38 +180,38 @@ namespace embree
////////////////////////////////////////////////////////////////////////////////
#if defined(__AVX512VL__)
__forceinline vboold4 operator ==(const vdouble4& a, const vdouble4& b) { return _mm256_cmp_pd_mask(a,b,_MM_CMPINT_EQ); }
__forceinline vboold4 operator !=(const vdouble4& a, const vdouble4& b) { return _mm256_cmp_pd_mask(a,b,_MM_CMPINT_NE); }
__forceinline vboold4 operator < (const vdouble4& a, const vdouble4& b) { return _mm256_cmp_pd_mask(a,b,_MM_CMPINT_LT); }
__forceinline vboold4 operator >=(const vdouble4& a, const vdouble4& b) { return _mm256_cmp_pd_mask(a,b,_MM_CMPINT_GE); }
__forceinline vboold4 operator > (const vdouble4& a, const vdouble4& b) { return _mm256_cmp_pd_mask(a,b,_MM_CMPINT_GT); }
__forceinline vboold4 operator <=(const vdouble4& a, const vdouble4& b) { return _mm256_cmp_pd_mask(a,b,_MM_CMPINT_LE); }
__forceinline const vboold4 operator ==( const vdouble4& a, const vdouble4& b ) { return _mm256_cmp_pd_mask(a,b,_CMP_EQ_UQ); }
__forceinline const vboold4 operator !=( const vdouble4& a, const vdouble4& b ) { return _mm256_cmp_pd_mask(a,b,_CMP_NEQ_UQ); }
__forceinline const vboold4 operator < ( const vdouble4& a, const vdouble4& b ) { return _mm256_cmp_pd_mask(a,b,_CMP_LT_OQ); }
__forceinline const vboold4 operator >=( const vdouble4& a, const vdouble4& b ) { return _mm256_cmp_pd_mask(a,b,_CMP_GE_OQ); }
__forceinline const vboold4 operator > ( const vdouble4& a, const vdouble4& b ) { return _mm256_cmp_pd_mask(a,b,_CMP_GT_OQ); }
__forceinline const vboold4 operator <=( const vdouble4& a, const vdouble4& b ) { return _mm256_cmp_pd_mask(a,b,_CMP_LE_OQ); }
#else
__forceinline vboold4 operator ==(const vdouble4& a, const vdouble4& b) { return _mm256_cmp_pd(a,b,_CMP_EQ_UQ); }
__forceinline vboold4 operator !=(const vdouble4& a, const vdouble4& b) { return _mm256_cmp_pd(a,b,_CMP_NEQ_UQ); }
__forceinline vboold4 operator < (const vdouble4& a, const vdouble4& b) { return _mm256_cmp_pd(a,b,_CMP_LT_OQ); }
__forceinline vboold4 operator >=(const vdouble4& a, const vdouble4& b) { return _mm256_cmp_pd(a,b,_CMP_GE_OQ); }
__forceinline vboold4 operator > (const vdouble4& a, const vdouble4& b) { return _mm256_cmp_pd(a,b,_CMP_GT_OQ); }
__forceinline vboold4 operator <=(const vdouble4& a, const vdouble4& b) { return _mm256_cmp_pd(a,b,_CMP_LE_OQ); }
__forceinline const vboold4 operator ==( const vdouble4& a, const vdouble4& b ) { return _mm256_cmp_pd(a,b,_CMP_EQ_UQ); }
__forceinline const vboold4 operator !=( const vdouble4& a, const vdouble4& b ) { return _mm256_cmp_pd(a,b,_CMP_NEQ_UQ); }
__forceinline const vboold4 operator < ( const vdouble4& a, const vdouble4& b ) { return _mm256_cmp_pd(a,b,_CMP_LT_OQ); }
__forceinline const vboold4 operator >=( const vdouble4& a, const vdouble4& b ) { return _mm256_cmp_pd(a,b,_CMP_GE_OQ); }
__forceinline const vboold4 operator > ( const vdouble4& a, const vdouble4& b ) { return _mm256_cmp_pd(a,b,_CMP_GT_OQ); }
__forceinline const vboold4 operator <=( const vdouble4& a, const vdouble4& b ) { return _mm256_cmp_pd(a,b,_CMP_LE_OQ); }
#endif
__forceinline vboold4 operator ==(const vdouble4& a, double b) { return a == vdouble4(b); }
__forceinline vboold4 operator ==(double a, const vdouble4& b) { return vdouble4(a) == b; }
__forceinline const vboold4 operator ==( const vdouble4& a, const double b ) { return a == vdouble4(b); }
__forceinline const vboold4 operator ==( const double a, const vdouble4& b ) { return vdouble4(a) == b; }
__forceinline vboold4 operator !=(const vdouble4& a, double b) { return a != vdouble4(b); }
__forceinline vboold4 operator !=(double a, const vdouble4& b) { return vdouble4(a) != b; }
__forceinline const vboold4 operator !=( const vdouble4& a, const double b ) { return a != vdouble4(b); }
__forceinline const vboold4 operator !=( const double a, const vdouble4& b ) { return vdouble4(a) != b; }
__forceinline vboold4 operator < (const vdouble4& a, double b) { return a < vdouble4(b); }
__forceinline vboold4 operator < (double a, const vdouble4& b) { return vdouble4(a) < b; }
__forceinline const vboold4 operator < ( const vdouble4& a, const double b ) { return a < vdouble4(b); }
__forceinline const vboold4 operator < ( const double a, const vdouble4& b ) { return vdouble4(a) < b; }
__forceinline vboold4 operator >=(const vdouble4& a, double b) { return a >= vdouble4(b); }
__forceinline vboold4 operator >=(double a, const vdouble4& b) { return vdouble4(a) >= b; }
__forceinline const vboold4 operator >=( const vdouble4& a, const double b ) { return a >= vdouble4(b); }
__forceinline const vboold4 operator >=( const double a, const vdouble4& b ) { return vdouble4(a) >= b; }
__forceinline vboold4 operator > (const vdouble4& a, double b) { return a > vdouble4(b); }
__forceinline vboold4 operator > (double a, const vdouble4& b) { return vdouble4(a) > b; }
__forceinline const vboold4 operator > ( const vdouble4& a, const double b ) { return a > vdouble4(b); }
__forceinline const vboold4 operator > ( const double a, const vdouble4& b ) { return vdouble4(a) > b; }
__forceinline vboold4 operator <=(const vdouble4& a, double b) { return a <= vdouble4(b); }
__forceinline vboold4 operator <=(double a, const vdouble4& b) { return vdouble4(a) <= b; }
__forceinline const vboold4 operator <=( const vdouble4& a, const double b ) { return a <= vdouble4(b); }
__forceinline const vboold4 operator <=( const double a, const vdouble4& b ) { return vdouble4(a) <= b; }
__forceinline vboold4 eq(const vdouble4& a, const vdouble4& b) { return a == b; }
__forceinline vboold4 ne(const vdouble4& a, const vdouble4& b) { return a != b; }
@@ -203,24 +219,8 @@ namespace embree
__forceinline vboold4 ge(const vdouble4& a, const vdouble4& b) { return a >= b; }
__forceinline vboold4 gt(const vdouble4& a, const vdouble4& b) { return a > b; }
__forceinline vboold4 le(const vdouble4& a, const vdouble4& b) { return a <= b; }
#if defined(__AVX512VL__)
__forceinline vboold4 eq(const vboold4& mask, const vdouble4& a, const vdouble4& b) { return _mm256_mask_cmp_pd_mask(mask, a, b, _MM_CMPINT_EQ); }
__forceinline vboold4 ne(const vboold4& mask, const vdouble4& a, const vdouble4& b) { return _mm256_mask_cmp_pd_mask(mask, a, b, _MM_CMPINT_NE); }
__forceinline vboold4 lt(const vboold4& mask, const vdouble4& a, const vdouble4& b) { return _mm256_mask_cmp_pd_mask(mask, a, b, _MM_CMPINT_LT); }
__forceinline vboold4 ge(const vboold4& mask, const vdouble4& a, const vdouble4& b) { return _mm256_mask_cmp_pd_mask(mask, a, b, _MM_CMPINT_GE); }
__forceinline vboold4 gt(const vboold4& mask, const vdouble4& a, const vdouble4& b) { return _mm256_mask_cmp_pd_mask(mask, a, b, _MM_CMPINT_GT); }
__forceinline vboold4 le(const vboold4& mask, const vdouble4& a, const vdouble4& b) { return _mm256_mask_cmp_pd_mask(mask, a, b, _MM_CMPINT_LE); }
#else
__forceinline vboold4 eq(const vboold4& mask, const vdouble4& a, const vdouble4& b) { return mask & (a == b); }
__forceinline vboold4 ne(const vboold4& mask, const vdouble4& a, const vdouble4& b) { return mask & (a != b); }
__forceinline vboold4 lt(const vboold4& mask, const vdouble4& a, const vdouble4& b) { return mask & (a < b); }
__forceinline vboold4 ge(const vboold4& mask, const vdouble4& a, const vdouble4& b) { return mask & (a >= b); }
__forceinline vboold4 gt(const vboold4& mask, const vdouble4& a, const vdouble4& b) { return mask & (a > b); }
__forceinline vboold4 le(const vboold4& mask, const vdouble4& a, const vdouble4& b) { return mask & (a <= b); }
#endif
__forceinline vdouble4 select(const vboold4& m, const vdouble4& t, const vdouble4& f) {
__forceinline const vdouble4 select( const vboold4& m, const vdouble4& t, const vdouble4& f ) {
#if defined(__AVX512VL__)
return _mm256_mask_blend_pd(m, f, t);
#else
@@ -244,43 +244,35 @@ namespace embree
// Movement/Shifting/Shuffling Functions
////////////////////////////////////////////////////////////////////////////////
template<int i0, int i1>
__forceinline vdouble4 shuffle(const vdouble4& v) {
return _mm256_permute_pd(v, (i1 << 3) | (i0 << 2) | (i1 << 1) | i0);
}
template<int B, int A> __forceinline vdouble4 shuffle (const vdouble4& v) { return _mm256_permute_pd(v,(int)_MM_SHUF_PERM2(B,A,B,A)); }
template<int A> __forceinline vdouble4 shuffle (const vdouble4& x) { return shuffle<A,A>(x); }
template<int i>
__forceinline vdouble4 shuffle(const vdouble4& v) {
return shuffle<i, i>(v);
}
template<int B, int A> __forceinline vdouble4 shuffle2 (const vdouble4& v) { return _mm256_permute2f128_pd(v,v,(int)_MM_SHUF_PERM3(B,A)); }
template<int i0, int i1>
__forceinline vdouble4 shuffle2(const vdouble4& v) {
return _mm256_permute2f128_pd(v, v, (i1 << 4) | i0);
}
__forceinline double toScalar(const vdouble4& v) {
return _mm_cvtsd_f64(_mm256_castpd256_pd128(v));
__forceinline double toScalar(const vdouble4& a)
{
return _mm_cvtsd_f64(_mm256_castpd256_pd128(a));
}
////////////////////////////////////////////////////////////////////////////////
/// Reductions
////////////////////////////////////////////////////////////////////////////////
__forceinline vdouble4 vreduce_min2(const vdouble4& x) { return min(x, shuffle<1,0>(x)); }
__forceinline vdouble4 vreduce_min (const vdouble4& y) { const vdouble4 x = vreduce_min2(y); return min(x, shuffle2<1,0>(x)); }
__forceinline vdouble4 vreduce_min2(const vdouble4& x) { return min(x,shuffle<0,1>(x)); }
__forceinline vdouble4 vreduce_min (const vdouble4& y) { const vdouble4 x = vreduce_min2(y); return min(x,shuffle2<0,1>(x)); }
__forceinline vdouble4 vreduce_max2(const vdouble4& x) { return max(x,shuffle<1,0>(x)); }
__forceinline vdouble4 vreduce_max (const vdouble4& y) { const vdouble4 x = vreduce_max2(y); return max(x, shuffle2<1,0>(x)); }
__forceinline vdouble4 vreduce_max2(const vdouble4& x) { return max(x,shuffle<0,1>(x)); }
__forceinline vdouble4 vreduce_max (const vdouble4& y) { const vdouble4 x = vreduce_max2(y); return max(x,shuffle2<0,1>(x)); }
__forceinline vdouble4 vreduce_and2(const vdouble4& x) { return x & shuffle<1,0>(x); }
__forceinline vdouble4 vreduce_and (const vdouble4& y) { const vdouble4 x = vreduce_and2(y); return x & shuffle2<1,0>(x); }
__forceinline vdouble4 vreduce_and2(const vdouble4& x) { return x & shuffle<0,1>(x); }
__forceinline vdouble4 vreduce_and (const vdouble4& y) { const vdouble4 x = vreduce_and2(y); return x & shuffle2<0,1>(x); }
__forceinline vdouble4 vreduce_or2(const vdouble4& x) { return x | shuffle<1,0>(x); }
__forceinline vdouble4 vreduce_or (const vdouble4& y) { const vdouble4 x = vreduce_or2(y); return x | shuffle2<1,0>(x); }
__forceinline vdouble4 vreduce_or2(const vdouble4& x) { return x | shuffle<0,1>(x); }
__forceinline vdouble4 vreduce_or (const vdouble4& y) { const vdouble4 x = vreduce_or2(y); return x | shuffle2<0,1>(x); }
__forceinline vdouble4 vreduce_add2(const vdouble4& x) { return x + shuffle<1,0>(x); }
__forceinline vdouble4 vreduce_add (const vdouble4& y) { const vdouble4 x = vreduce_add2(y); return x + shuffle2<1,0>(x); }
__forceinline vdouble4 vreduce_add2(const vdouble4& x) { return x + shuffle<0,1>(x); }
__forceinline vdouble4 vreduce_add (const vdouble4& y) { const vdouble4 x = vreduce_add2(y); return x + shuffle2<0,1>(x); }
__forceinline double reduce_add(const vdouble4& a) { return toScalar(vreduce_add(a)); }
__forceinline double reduce_min(const vdouble4& a) { return toScalar(vreduce_min(a)); }
@@ -296,7 +288,7 @@ namespace embree
/// Output Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline std::ostream& operator <<(std::ostream& cout, const vdouble4& v)
__forceinline std::ostream& operator<<(std::ostream& cout, const vdouble4& v)
{
cout << "<" << v[0];
for (size_t i=1; i<4; i++) cout << ", " << v[i];
+186 -183
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
@@ -17,8 +17,8 @@
#pragma once
namespace embree
{
/* 8-wide AVX-512 64-bit double type */
{
/* 8-wide AVX-512 64bit double type */
template<>
struct vdouble<8>
{
@@ -26,236 +26,245 @@ namespace embree
enum { size = 8 }; // number of SIMD elements
union { // data
__m512d v;
double i[8];
__m512d v;
double i[8];
};
////////////////////////////////////////////////////////////////////////////////
/// Constructors, Assignment & Cast Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline vdouble() {}
__forceinline vdouble(const vdouble8& t) { v = t.v; }
__forceinline vdouble8& operator =(const vdouble8& f) { v = f.v; return *this; }
__forceinline vdouble8& operator=(const vdouble8& f) { v = f.v; return *this; }
__forceinline vdouble(const __m512d& t) { v = t; }
__forceinline operator __m512d() const { return v; }
__forceinline operator __m256d() const { return _mm512_castpd512_pd256(v); }
__forceinline operator __m512d () const { return v; }
__forceinline operator __m256d () const { return _mm512_castpd512_pd256(v); }
__forceinline vdouble(double i) {
v = _mm512_set1_pd(i);
__forceinline vdouble(const double i) {
v = _mm512_set_1to8_pd(i);
}
__forceinline vdouble(const double a, const double b, const double c, const double d) {
v = _mm512_set_4to8_pd(d,c,b,a);
}
__forceinline vdouble(double a, double b, double c, double d) {
v = _mm512_set4_pd(d,c,b,a);
}
__forceinline vdouble(double a0, double a1, double a2, double a3,
double a4, double a5, double a6, double a7)
__forceinline vdouble(const double a0 , const double a1 , const double a2 , const double a3,
const double a4 , const double a5 , const double a6 , const double a7)
{
v = _mm512_set_pd(a7,a6,a5,a4,a3,a2,a1,a0);
v = _mm512_set_8to8_pd(a7,a6,a5,a4,a3,a2,a1,a0);
}
////////////////////////////////////////////////////////////////////////////////
/// Constants
////////////////////////////////////////////////////////////////////////////////
__forceinline vdouble( ZeroTy ) : v(_mm512_setzero_pd()) {}
__forceinline vdouble( OneTy ) : v(_mm512_set_1to8_pd(1)) {}
__forceinline vdouble( StepTy ) : v(_mm512_set_8to8_pd(7.0,6.0,5.0,4.0,3.0,2.0,1.0,0.0)) {}
__forceinline vdouble( ReverseStepTy ) : v(_mm512_setr_pd(7.0,6.0,5.0,4.0,3.0,2.0,1.0,0.0)) {}
__forceinline vdouble(ZeroTy) : v(_mm512_setzero_pd()) {}
__forceinline vdouble(OneTy) : v(_mm512_set1_pd(1)) {}
__forceinline vdouble(StepTy) : v(_mm512_set_pd(7.0,6.0,5.0,4.0,3.0,2.0,1.0,0.0)) {}
__forceinline vdouble(ReverseStepTy) : v(_mm512_setr_pd(7.0,6.0,5.0,4.0,3.0,2.0,1.0,0.0)) {}
__forceinline static vdouble8 zero() { return _mm512_setzero_pd(); }
__forceinline static vdouble8 one () { return _mm512_set_1to8_pd(1); }
__forceinline static vdouble8 neg_one () { return _mm512_set_1to8_pd(-1); }
////////////////////////////////////////////////////////////////////////////////
/// Loads and Stores
////////////////////////////////////////////////////////////////////////////////
static __forceinline void store_nt(void *__restrict__ ptr, const vdouble8& a) {
_mm512_stream_pd((double*)ptr, a);
_mm512_stream_si512(ptr,_mm512_castpd_si512(a));
}
static __forceinline vdouble8 loadu(const void* addr) {
return _mm512_loadu_pd((double*)addr);
static __forceinline vdouble8 loadu(const void* addr)
{
return _mm512_loadu_si512(addr);
}
static __forceinline vdouble8 load(const vdouble8* addr) {
return _mm512_load_pd((double*)addr);
return _mm512_load_si512(addr);
}
static __forceinline vdouble8 load(const double* addr) {
return _mm512_load_pd(addr);
return _mm512_load_si512(addr);
}
static __forceinline void store(void* ptr, const vdouble8& v) {
_mm512_store_pd(ptr, v);
_mm512_store_si512(ptr,_mm512_castpd_si512(v));
}
static __forceinline void storeu(void* ptr, const vdouble8& v) {
_mm512_storeu_pd(ptr, v);
static __forceinline void storeu(void* ptr, const vdouble8& v ) {
_mm512_storeu_si512(ptr,_mm512_castpd_si512(v));
}
static __forceinline void storeu(const vboold8& mask, double* ptr, const vdouble8& f) {
_mm512_mask_storeu_pd(ptr, mask, f);
static __forceinline void storeu(const vboold8& mask, double* ptr, const vdouble8& f ) {
_mm512_mask_storeu_pd(ptr,mask,f);
}
static __forceinline void store(const vboold8& mask, void* addr, const vdouble8& v2) {
_mm512_mask_store_pd(addr, mask, v2);
_mm512_mask_store_pd(addr,mask,v2);
}
/* pass by value to avoid compiler generating inefficient code */
/* pass by value to avoid compiler generating inefficient code */
static __forceinline void storeu_compact(const vboold8 mask,void * addr, const vdouble8& reg) {
_mm512_mask_compressstoreu_pd(addr, mask, reg);
_mm512_mask_compressstoreu_pd(addr,mask,reg);
}
static __forceinline vdouble8 compact64bit(const vboold8& mask, vdouble8& v) {
return _mm512_mask_compress_pd(v, mask, v);
return _mm512_mask_compress_pd(v,mask,v);
}
static __forceinline vdouble8 compact(const vboold8& mask, vdouble8& v) {
return _mm512_mask_compress_pd(v, mask, v);
return _mm512_mask_compress_pd(v,mask,v);
}
static __forceinline vdouble8 compact(const vboold8& mask, const vdouble8& a, vdouble8& b) {
return _mm512_mask_compress_pd(a, mask, b);
return _mm512_mask_compress_pd(a,mask,b);
}
////////////////////////////////////////////////////////////////////////////////
/// Array Access
////////////////////////////////////////////////////////////////////////////////
__forceinline double& operator [](size_t index) { assert(index < 8); return i[index]; }
__forceinline const double& operator [](size_t index) const { assert(index < 8); return i[index]; }
__forceinline double& operator[](const size_t index) { assert(index < 8); return i[index]; }
__forceinline const double& operator[](const size_t index) const { assert(index < 8); return i[index]; }
};
////////////////////////////////////////////////////////////////////////////////
/// Unary Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline vdouble8 asDouble (const __m512& a) { return _mm512_castps_pd(a); }
__forceinline vdouble8 operator +(const vdouble8& a) { return a; }
__forceinline vdouble8 operator -(const vdouble8& a) { return _mm512_sub_pd(_mm512_setzero_pd(), a); }
__forceinline const vdouble8 asDouble ( const __m512& a ) { return _mm512_castps_si512(a); }
__forceinline const vdouble8 operator +( const vdouble8& a ) { return a; }
__forceinline const vdouble8 operator -( const vdouble8& a ) { return _mm512_sub_pd(_mm512_setzero_pd(), a); }
////////////////////////////////////////////////////////////////////////////////
/// Binary Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline vdouble8 operator +(const vdouble8& a, const vdouble8& b) { return _mm512_add_pd(a, b); }
__forceinline vdouble8 operator +(const vdouble8& a, double b) { return a + vdouble8(b); }
__forceinline vdouble8 operator +(double a, const vdouble8& b) { return vdouble8(a) + b; }
__forceinline const vdouble8 operator +( const vdouble8& a, const vdouble8& b ) { return _mm512_add_pd(a, b); }
__forceinline const vdouble8 operator +( const vdouble8& a, const double b ) { return a + vdouble8(b); }
__forceinline const vdouble8 operator +( const double a, const vdouble8& b ) { return vdouble8(a) + b; }
__forceinline vdouble8 operator -(const vdouble8& a, const vdouble8& b) { return _mm512_sub_pd(a, b); }
__forceinline vdouble8 operator -(const vdouble8& a, double b) { return a - vdouble8(b); }
__forceinline vdouble8 operator -(double a, const vdouble8& b) { return vdouble8(a) - b; }
__forceinline const vdouble8 operator -( const vdouble8& a, const vdouble8& b ) { return _mm512_sub_pd(a, b); }
__forceinline const vdouble8 operator -( const vdouble8& a, const double b ) { return a - vdouble8(b); }
__forceinline const vdouble8 operator -( const double a, const vdouble8& b ) { return vdouble8(a) - b; }
__forceinline vdouble8 operator *(const vdouble8& a, const vdouble8& b) { return _mm512_mul_pd(a, b); }
__forceinline vdouble8 operator *(const vdouble8& a, double b) { return a * vdouble8(b); }
__forceinline vdouble8 operator *(double a, const vdouble8& b) { return vdouble8(a) * b; }
__forceinline const vdouble8 operator *( const vdouble8& a, const vdouble8& b ) { return _mm512_mul_pd(a, b); }
__forceinline const vdouble8 operator *( const vdouble8& a, const double b ) { return a * vdouble8(b); }
__forceinline const vdouble8 operator *( const double a, const vdouble8& b ) { return vdouble8(a) * b; }
__forceinline vdouble8 operator &(const vdouble8& a, const vdouble8& b) { return _mm512_and_pd(a, b); }
__forceinline vdouble8 operator &(const vdouble8& a, double b) { return a & vdouble8(b); }
__forceinline vdouble8 operator &(double a, const vdouble8& b) { return vdouble8(a) & b; }
__forceinline const vdouble8 operator &( const vdouble8& a, const vdouble8& b ) { return _mm512_and_pd(a, b); }
__forceinline const vdouble8 operator &( const vdouble8& a, const double b ) { return a & vdouble8(b); }
__forceinline const vdouble8 operator &( const double a, const vdouble8& b ) { return vdouble8(a) & b; }
__forceinline vdouble8 operator |(const vdouble8& a, const vdouble8& b) { return _mm512_or_pd(a, b); }
__forceinline vdouble8 operator |(const vdouble8& a, double b) { return a | vdouble8(b); }
__forceinline vdouble8 operator |(double a, const vdouble8& b) { return vdouble8(a) | b; }
__forceinline const vdouble8 operator |( const vdouble8& a, const vdouble8& b ) { return _mm512_or_pd(a, b); }
__forceinline const vdouble8 operator |( const vdouble8& a, const double b ) { return a | vdouble8(b); }
__forceinline const vdouble8 operator |( const double a, const vdouble8& b ) { return vdouble8(a) | b; }
__forceinline vdouble8 operator ^(const vdouble8& a, const vdouble8& b) { return _mm512_xor_pd(a, b); }
__forceinline vdouble8 operator ^(const vdouble8& a, double b) { return a ^ vdouble8(b); }
__forceinline vdouble8 operator ^(double a, const vdouble8& b) { return vdouble8(a) ^ b; }
__forceinline const vdouble8 operator ^( const vdouble8& a, const vdouble8& b ) { return _mm512_xor_pd(a, b); }
__forceinline const vdouble8 operator ^( const vdouble8& a, const double b ) { return a ^ vdouble8(b); }
__forceinline const vdouble8 operator ^( const double a, const vdouble8& b ) { return vdouble8(a) ^ b; }
__forceinline vdouble8 operator <<(const vdouble8& a, const unsigned int n) { return _mm512_castsi512_pd(_mm512_slli_epi64(_mm512_castpd_si512(a), n)); }
__forceinline vdouble8 operator >>(const vdouble8& a, const unsigned int n) { return _mm512_castsi512_pd(_mm512_srai_epi64(_mm512_castpd_si512(a), n)); }
__forceinline const vdouble8 operator <<( const vdouble8& a, const unsigned int n ) { return _mm512_castsi512_pd(_mm512_slli_epi64(_mm512_castpd_si512(a), n)); }
__forceinline const vdouble8 operator >>( const vdouble8& a, const unsigned int n ) { return _mm512_castsi512_pd(_mm512_srai_epi64(_mm512_castpd_si512(a), n)); }
__forceinline vdouble8 operator <<(const vdouble8& a, const vllong8& n) { return _mm512_castsi512_pd(_mm512_sllv_epi64(_mm512_castpd_si512(a), n)); }
__forceinline vdouble8 operator >>(const vdouble8& a, const vllong8& n) { return _mm512_castsi512_pd(_mm512_srav_epi64(_mm512_castpd_si512(a), n)); }
__forceinline const vdouble8 operator <<( const vdouble8& a, const vlong8& n ) { return _mm512_castsi512_pd(_mm512_sllv_epi64(_mm512_castpd_si512(a), n)); }
__forceinline const vdouble8 operator >>( const vdouble8& a, const vlong8& n ) { return _mm512_castsi512_pd(_mm512_srav_epi64(_mm512_castpd_si512(a), n)); }
__forceinline vdouble8 sll (const vdouble8& a, const unsigned int b) { return _mm512_castsi512_pd(_mm512_slli_epi64(_mm512_castpd_si512(a), b)); }
__forceinline vdouble8 sra (const vdouble8& a, const unsigned int b) { return _mm512_castsi512_pd(_mm512_srai_epi64(_mm512_castpd_si512(a), b)); }
__forceinline vdouble8 srl (const vdouble8& a, const unsigned int b) { return _mm512_castsi512_pd(_mm512_srli_epi64(_mm512_castpd_si512(a), b)); }
__forceinline const vdouble8 sll ( const vdouble8& a, const unsigned int b ) { return _mm512_castsi512_pd(_mm512_slli_epi64(_mm512_castpd_si512(a), b)); }
__forceinline const vdouble8 sra ( const vdouble8& a, const unsigned int b ) { return _mm512_castsi512_pd(_mm512_srai_epi64(_mm512_castpd_si512(a), b)); }
__forceinline const vdouble8 srl ( const vdouble8& a, const unsigned int b ) { return _mm512_castsi512_pd(_mm512_srli_epi64(_mm512_castpd_si512(a), b)); }
__forceinline const vdouble8 min( const vdouble8& a, const vdouble8& b ) { return _mm512_min_pd(a, b); }
__forceinline const vdouble8 min( const vdouble8& a, const double b ) { return min(a,vdouble8(b)); }
__forceinline const vdouble8 min( const double a, const vdouble8& b ) { return min(vdouble8(a),b); }
__forceinline vdouble8 min(const vdouble8& a, const vdouble8& b) { return _mm512_min_pd(a, b); }
__forceinline vdouble8 min(const vdouble8& a, double b) { return min(a,vdouble8(b)); }
__forceinline vdouble8 min(double a, const vdouble8& b) { return min(vdouble8(a),b); }
__forceinline const vdouble8 max( const vdouble8& a, const vdouble8& b ) { return _mm512_max_pd(a, b); }
__forceinline const vdouble8 max( const vdouble8& a, const double b ) { return max(a,vdouble8(b)); }
__forceinline const vdouble8 max( const double a, const vdouble8& b ) { return max(vdouble8(a),b); }
__forceinline const vdouble8 mask_add(const vboold8& mask, vdouble8& c, const vdouble8& a, const vdouble8& b) { return _mm512_mask_add_pd(c,mask,a,b); }
__forceinline const vdouble8 mask_sub(const vboold8& mask, vdouble8& c, const vdouble8& a, const vdouble8& b) { return _mm512_mask_sub_pd(c,mask,a,b); }
__forceinline vdouble8 max(const vdouble8& a, const vdouble8& b) { return _mm512_max_pd(a, b); }
__forceinline vdouble8 max(const vdouble8& a, double b) { return max(a,vdouble8(b)); }
__forceinline vdouble8 max(double a, const vdouble8& b) { return max(vdouble8(a),b); }
__forceinline vdouble8 mask_add(const vboold8& mask, vdouble8& c, const vdouble8& a, const vdouble8& b) { return _mm512_mask_add_pd(c,mask,a,b); }
__forceinline vdouble8 mask_sub(const vboold8& mask, vdouble8& c, const vdouble8& a, const vdouble8& b) { return _mm512_mask_sub_pd(c,mask,a,b); }
__forceinline vdouble8 mask_and(const vboold8& m,vdouble8& c, const vdouble8& a, const vdouble8& b) { return _mm512_mask_and_pd(c,m,a,b); }
__forceinline vdouble8 mask_or (const vboold8& m,vdouble8& c, const vdouble8& a, const vdouble8& b) { return _mm512_mask_or_pd(c,m,a,b); }
__forceinline const vdouble8 mask_and(const vboold8& m,vdouble8& c, const vdouble8& a, const vdouble8& b) { return _mm512_mask_and_pd(c,m,a,b); }
__forceinline const vdouble8 mask_or (const vboold8& m,vdouble8& c, const vdouble8& a, const vdouble8& b) { return _mm512_mask_or_pd(c,m,a,b); }
////////////////////////////////////////////////////////////////////////////////
/// Assignment Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline vdouble8& operator +=(vdouble8& a, const vdouble8& b) { return a = a + b; }
__forceinline vdouble8& operator +=(vdouble8& a, double b) { return a = a + b; }
__forceinline vdouble8& operator +=( vdouble8& a, const vdouble8& b ) { return a = a + b; }
__forceinline vdouble8& operator +=( vdouble8& a, const double b ) { return a = a + b; }
__forceinline vdouble8& operator -=( vdouble8& a, const vdouble8& b ) { return a = a - b; }
__forceinline vdouble8& operator -=( vdouble8& a, const double b ) { return a = a - b; }
__forceinline vdouble8& operator -=(vdouble8& a, const vdouble8& b) { return a = a - b; }
__forceinline vdouble8& operator -=(vdouble8& a, double b) { return a = a - b; }
__forceinline vdouble8& operator *=(vdouble8& a, const vdouble8& b) { return a = a * b; }
__forceinline vdouble8& operator *=(vdouble8& a, double b) { return a = a * b; }
__forceinline vdouble8& operator &=(vdouble8& a, const vdouble8& b) { return a = a & b; }
__forceinline vdouble8& operator &=(vdouble8& a, double b) { return a = a & b; }
__forceinline vdouble8& operator |=(vdouble8& a, const vdouble8& b) { return a = a | b; }
__forceinline vdouble8& operator |=(vdouble8& a, double b) { return a = a | b; }
__forceinline vdouble8& operator <<=(vdouble8& a, const double b) { return a = a << b; }
__forceinline vdouble8& operator >>=(vdouble8& a, const double b) { return a = a >> b; }
__forceinline vdouble8& operator *=( vdouble8& a, const vdouble8& b ) { return a = a * b; }
__forceinline vdouble8& operator *=( vdouble8& a, const double b ) { return a = a * b; }
__forceinline vdouble8& operator &=( vdouble8& a, const vdouble8& b ) { return a = a & b; }
__forceinline vdouble8& operator &=( vdouble8& a, const double b ) { return a = a & b; }
__forceinline vdouble8& operator |=( vdouble8& a, const vdouble8& b ) { return a = a | b; }
__forceinline vdouble8& operator |=( vdouble8& a, const double b ) { return a = a | b; }
__forceinline vdouble8& operator <<=( vdouble8& a, const double b ) { return a = a << b; }
__forceinline vdouble8& operator >>=( vdouble8& a, const double b ) { return a = a >> b; }
////////////////////////////////////////////////////////////////////////////////
/// Comparison Operators + Select
////////////////////////////////////////////////////////////////////////////////
__forceinline vboold8 operator ==(const vdouble8& a, const vdouble8& b) { return _mm512_cmp_pd_mask(a,b,_MM_CMPINT_EQ); }
__forceinline vboold8 operator ==(const vdouble8& a, double b) { return a == vdouble8(b); }
__forceinline vboold8 operator ==(double a, const vdouble8& b) { return vdouble8(a) == b; }
__forceinline const vboold8 operator ==( const vdouble8& a, const vdouble8& b ) { return _mm512_cmp_pd_mask(a,b,_MM_CMPINT_EQ); }
__forceinline const vboold8 operator ==( const vdouble8& a, const double b ) { return a == vdouble8(b); }
__forceinline const vboold8 operator ==( const double a, const vdouble8& b ) { return vdouble8(a) == b; }
__forceinline const vboold8 operator !=( const vdouble8& a, const vdouble8& b ) { return _mm512_cmp_pd_mask(a,b,_MM_CMPINT_NE); }
__forceinline const vboold8 operator !=( const vdouble8& a, const double b ) { return a != vdouble8(b); }
__forceinline const vboold8 operator !=( const double a, const vdouble8& b ) { return vdouble8(a) != b; }
__forceinline const vboold8 operator < ( const vdouble8& a, const vdouble8& b ) { return _mm512_cmp_pd_mask(a,b,_MM_CMPINT_LT); }
__forceinline const vboold8 operator < ( const vdouble8& a, const double b ) { return a < vdouble8(b); }
__forceinline const vboold8 operator < ( const double a, const vdouble8& b ) { return vdouble8(a) < b; }
__forceinline const vboold8 operator >=( const vdouble8& a, const vdouble8& b ) { return _mm512_cmp_pd_mask(a,b,_MM_CMPINT_GE); }
__forceinline const vboold8 operator >=( const vdouble8& a, const double b ) { return a >= vdouble8(b); }
__forceinline const vboold8 operator >=( const double a, const vdouble8& b ) { return vdouble8(a) >= b; }
__forceinline vboold8 operator !=(const vdouble8& a, const vdouble8& b) { return _mm512_cmp_pd_mask(a,b,_MM_CMPINT_NE); }
__forceinline vboold8 operator !=(const vdouble8& a, double b) { return a != vdouble8(b); }
__forceinline vboold8 operator !=(double a, const vdouble8& b) { return vdouble8(a) != b; }
__forceinline const vboold8 operator > ( const vdouble8& a, const vdouble8& b ) { return _mm512_cmp_pd_mask(a,b,_MM_CMPINT_GT); }
__forceinline const vboold8 operator > ( const vdouble8& a, const double b ) { return a > vdouble8(b); }
__forceinline const vboold8 operator > ( const double a, const vdouble8& b ) { return vdouble8(a) > b; }
__forceinline vboold8 operator < (const vdouble8& a, const vdouble8& b) { return _mm512_cmp_pd_mask(a,b,_MM_CMPINT_LT); }
__forceinline vboold8 operator < (const vdouble8& a, double b) { return a < vdouble8(b); }
__forceinline vboold8 operator < (double a, const vdouble8& b) { return vdouble8(a) < b; }
__forceinline vboold8 operator >=(const vdouble8& a, const vdouble8& b) { return _mm512_cmp_pd_mask(a,b,_MM_CMPINT_GE); }
__forceinline vboold8 operator >=(const vdouble8& a, double b) { return a >= vdouble8(b); }
__forceinline vboold8 operator >=(double a, const vdouble8& b) { return vdouble8(a) >= b; }
__forceinline vboold8 operator > (const vdouble8& a, const vdouble8& b) { return _mm512_cmp_pd_mask(a,b,_MM_CMPINT_GT); }
__forceinline vboold8 operator > (const vdouble8& a, double b) { return a > vdouble8(b); }
__forceinline vboold8 operator > (double a, const vdouble8& b) { return vdouble8(a) > b; }
__forceinline vboold8 operator <=(const vdouble8& a, const vdouble8& b) { return _mm512_cmp_pd_mask(a,b,_MM_CMPINT_LE); }
__forceinline vboold8 operator <=(const vdouble8& a, double b) { return a <= vdouble8(b); }
__forceinline vboold8 operator <=(double a, const vdouble8& b) { return vdouble8(a) <= b; }
__forceinline vboold8 eq(const vdouble8& a, const vdouble8& b) { return _mm512_cmp_pd_mask(a,b,_MM_CMPINT_EQ); }
__forceinline vboold8 ne(const vdouble8& a, const vdouble8& b) { return _mm512_cmp_pd_mask(a,b,_MM_CMPINT_NE); }
__forceinline vboold8 lt(const vdouble8& a, const vdouble8& b) { return _mm512_cmp_pd_mask(a,b,_MM_CMPINT_LT); }
__forceinline vboold8 ge(const vdouble8& a, const vdouble8& b) { return _mm512_cmp_pd_mask(a,b,_MM_CMPINT_GE); }
__forceinline vboold8 gt(const vdouble8& a, const vdouble8& b) { return _mm512_cmp_pd_mask(a,b,_MM_CMPINT_GT); }
__forceinline vboold8 le(const vdouble8& a, const vdouble8& b) { return _mm512_cmp_pd_mask(a,b,_MM_CMPINT_LE); }
__forceinline const vboold8 operator <=( const vdouble8& a, const vdouble8& b ) { return _mm512_cmp_pd_mask(a,b,_MM_CMPINT_LE); }
__forceinline const vboold8 operator <=( const vdouble8& a, const double b ) { return a <= vdouble8(b); }
__forceinline const vboold8 operator <=( const double a, const vdouble8& b ) { return vdouble8(a) <= b; }
__forceinline vboold8 eq( const vdouble8& a, const vdouble8& b) { return _mm512_cmp_pd_mask(a,b,_MM_CMPINT_EQ); }
__forceinline vboold8 eq(const vboold8 mask, const vdouble8& a, const vdouble8& b) { return _mm512_mask_cmp_pd_mask(mask,a,b,_MM_CMPINT_EQ); }
__forceinline vboold8 ne( const vdouble8& a, const vdouble8& b) { return _mm512_cmp_pd_mask(a,b,_MM_CMPINT_NE); }
__forceinline vboold8 ne(const vboold8 mask, const vdouble8& a, const vdouble8& b) { return _mm512_mask_cmp_pd_mask(mask,a,b,_MM_CMPINT_NE); }
__forceinline vboold8 lt(const vboold8 mask, const vdouble8& a, const vdouble8& b) { return _mm512_mask_cmp_pd_mask(mask,a,b,_MM_CMPINT_LT); }
__forceinline vboold8 ge(const vboold8 mask, const vdouble8& a, const vdouble8& b) { return _mm512_mask_cmp_pd_mask(mask,a,b,_MM_CMPINT_GE); }
__forceinline vboold8 gt(const vboold8 mask, const vdouble8& a, const vdouble8& b) { return _mm512_mask_cmp_pd_mask(mask,a,b,_MM_CMPINT_GT); }
__forceinline vboold8 le(const vboold8 mask, const vdouble8& a, const vdouble8& b) { return _mm512_mask_cmp_pd_mask(mask,a,b,_MM_CMPINT_LE); }
__forceinline vdouble8 select(const vboold8& m, const vdouble8& t, const vdouble8& f) {
return _mm512_mask_or_pd(f,m,t,t);
__forceinline vboold8 lt( const vdouble8& a, const vdouble8& b) { return _mm512_cmp_pd_mask(a,b,_MM_CMPINT_LT); }
__forceinline vboold8 lt(const vboold8 mask, const vdouble8& a, const vdouble8& b) { return _mm512_mask_cmp_pd_mask(mask,a,b,_MM_CMPINT_LT); }
__forceinline vboold8 ge( const vdouble8& a, const vdouble8& b) { return _mm512_cmp_pd_mask(a,b,_MM_CMPINT_GE); }
__forceinline vboold8 ge(const vboold8 mask, const vdouble8& a, const vdouble8& b) { return _mm512_mask_cmp_pd_mask(mask,a,b,_MM_CMPINT_GE); }
__forceinline vboold8 gt( const vdouble8& a, const vdouble8& b) { return _mm512_cmp_pd_mask(a,b,_MM_CMPINT_GT); }
__forceinline vboold8 gt(const vboold8 mask, const vdouble8& a, const vdouble8& b) { return _mm512_mask_cmp_pd_mask(mask,a,b,_MM_CMPINT_GT); }
__forceinline vboold8 le( const vdouble8& a, const vdouble8& b) { return _mm512_cmp_pd_mask(a,b,_MM_CMPINT_LE); }
__forceinline vboold8 le(const vboold8 mask, const vdouble8& a, const vdouble8& b) { return _mm512_mask_cmp_pd_mask(mask,a,b,_MM_CMPINT_LE); }
__forceinline const vdouble8 select( const vboold8& m, const vdouble8& t, const vdouble8& f ) {
return _mm512_mask_or_pd(f,m,t,t);
}
__forceinline void xchg(const vboold8& m, vdouble8& a, vdouble8& b) {
@@ -274,77 +283,71 @@ namespace embree
// Movement/Shifting/Shuffling Functions
////////////////////////////////////////////////////////////////////////////////
template<int i0, int i1>
__forceinline vdouble8 shuffle(const vdouble8& v) {
return _mm512_permute_pd(v, (i1 << 7) | (i0 << 6) | (i1 << 5) | (i0 << 4) | (i1 << 3) | (i0 << 2) | (i1 << 1) | i0);
}
template<int i>
__forceinline vdouble8 shuffle(const vdouble8& v) {
return shuffle<i, i>(v);
}
template<int i0, int i1, int i2, int i3>
__forceinline vdouble8 shuffle(const vdouble8& v) {
return _mm512_permutex_pd(v, _MM_SHUFFLE(i3, i2, i1, i0));
}
template<int i0, int i1>
__forceinline vdouble8 shuffle4(const vdouble8& v) {
return _mm512_shuffle_f64x2(v, v, _MM_SHUFFLE(i1*2+1, i1*2, i0*2+1, i0*2));
}
template<int i>
__forceinline vdouble8 shuffle4(const vdouble8& v) {
return shuffle4<i, i>(v);
}
__forceinline vdouble8 shuffle (const vdouble8& x,int perm32 ) { return _mm512_permutex_pd(x,perm32); }
__forceinline vdouble8 shuffle4(const vdouble8& x,int perm128) { return _mm512_shuffle_f64x2(x,x,perm128); }
template<int i>
__forceinline vdouble8 align_shift_right(const vdouble8& a, const vdouble8& b) {
return _mm512_castsi512_pd(_mm512_alignr_epi64(_mm512_castpd_si512(a), _mm512_castpd_si512(b), i));
}
template<int D, int C, int B, int A> __forceinline vdouble8 shuffle (const vdouble8& v) { return _mm512_permutex_pd(v,(int)_MM_SHUF_PERM(D,C,B,A)); }
template<int A> __forceinline vdouble8 shuffle (const vdouble8& x) { return shuffle<A,A,A,A>(v); }
__forceinline double toScalar(const vdouble8& v) {
return _mm_cvtsd_f64(_mm512_castpd512_pd128(v));
template<int D, int C, int B, int A> __forceinline vdouble8 shuffle4(const vdouble8& v) { return shuffle4(v,(int)_MM_SHUF_PERM(D,C,B,A)); }
template<int A> __forceinline vdouble8 shuffle4(const vdouble8& x) { return shuffle4<A,A,A,A>(x); }
template<int i>
__forceinline vdouble8 align_shift_right(const vdouble8& a, const vdouble8& b)
{
return _mm512_alignr_pd(a,b,i);
};
__forceinline double toScalar(const vdouble8& a)
{
return _mm256_cvtsd_f64(_mm512_castpd512_pd256(a));
}
////////////////////////////////////////////////////////////////////////////////
/// Reductions
////////////////////////////////////////////////////////////////////////////////
__forceinline vdouble8 vreduce_add2(vdouble8 x) { return x + shuffle<1,0,3,2>(x); }
__forceinline vdouble8 vreduce_add4(vdouble8 x) { x = vreduce_add2(x); return x + shuffle<2,3,0,1>(x); }
__forceinline vdouble8 vreduce_add (vdouble8 x) { x = vreduce_add4(x); return x + shuffle4<1,0>(x); }
__forceinline double reduce_add(const vdouble8& a) { return _mm512_reduce_add_pd(a); }
__forceinline double reduce_min(const vdouble8& a) { return _mm512_reduce_min_pd(a); }
__forceinline double reduce_max(const vdouble8& a) { return _mm512_reduce_max_pd(a); }
__forceinline vdouble8 vreduce_min2(const vdouble8& x) { return min(x,shuffle(x,_MM_SHUF_PERM(2,3,0,1))); }
__forceinline vdouble8 vreduce_min4(const vdouble8& y) { const vdouble8 x = vreduce_min2(y); return min(x,shuffle(x,_MM_SHUF_PERM(1,0,3,2))); }
__forceinline vdouble8 vreduce_min (const vdouble8& y) { const vdouble8 x = vreduce_min4(y); return min(x,shuffle4(x,_MM_SHUF_PERM(1,0,3,2))); }
__forceinline vdouble8 vreduce_min2(vdouble8 x) { return min(x, shuffle<1,0,3,2>(x)); }
__forceinline vdouble8 vreduce_min4(vdouble8 x) { x = vreduce_min2(x); return min(x, shuffle<2,3,0,1>(x)); }
__forceinline vdouble8 vreduce_min (vdouble8 x) { x = vreduce_min4(x); return min(x, shuffle4<1,0>(x)); }
__forceinline vdouble8 vreduce_max2(const vdouble8& x) { return max(x,shuffle(x,_MM_SHUF_PERM(1,0,3,2))); }
__forceinline vdouble8 vreduce_max4(const vdouble8& y) { const vdouble8 x = vreduce_max2(y); return max(x,shuffle(x,_MM_SHUF_PERM(2,3,0,1))); }
__forceinline vdouble8 vreduce_max (const vdouble8& y) { const vdouble8 x = vreduce_max4(y); return max(x,shuffle4(x,_MM_SHUF_PERM(1,0,3,2))); }
__forceinline vdouble8 vreduce_max2(vdouble8 x) { return max(x, shuffle<1,0,3,2>(x)); }
__forceinline vdouble8 vreduce_max4(vdouble8 x) { x = vreduce_max2(x); return max(x, shuffle<2,3,0,1>(x)); }
__forceinline vdouble8 vreduce_max (vdouble8 x) { x = vreduce_max4(x); return max(x, shuffle4<1,0>(x)); }
__forceinline vdouble8 vreduce_and2(const vdouble8& x) { return x & shuffle(x,_MM_SHUF_PERM(1,0,3,2)); }
__forceinline vdouble8 vreduce_and4(const vdouble8& y) { const vdouble8 x = vreduce_and2(y); return x & shuffle(x,_MM_SHUF_PERM(2,3,0,1)); }
__forceinline vdouble8 vreduce_and (const vdouble8& y) { const vdouble8 x = vreduce_and4(y); return x & shuffle4(x,_MM_SHUF_PERM(1,0,3,2)); }
__forceinline double reduce_add(const vdouble8& v) { return toScalar(vreduce_add(v)); }
__forceinline double reduce_min(const vdouble8& v) { return toScalar(vreduce_min(v)); }
__forceinline double reduce_max(const vdouble8& v) { return toScalar(vreduce_max(v)); }
__forceinline vdouble8 vreduce_or2(const vdouble8& x) { return x | shuffle(x,_MM_SHUF_PERM(1,0,3,2)); }
__forceinline vdouble8 vreduce_or4(const vdouble8& y) { const vdouble8 x = vreduce_or2(y); return x | shuffle(x,_MM_SHUF_PERM(2,3,0,1)); }
__forceinline vdouble8 vreduce_or (const vdouble8& y) { const vdouble8 x = vreduce_or4(y); return x | shuffle4(x,_MM_SHUF_PERM(1,0,3,2)); }
__forceinline vdouble8 vreduce_add2(const vdouble8& x) { return x + shuffle(x,_MM_SHUF_PERM(1,0,3,2)); }
__forceinline vdouble8 vreduce_add4(const vdouble8& y) { const vdouble8 x = vreduce_add2(y); return x + shuffle(x,_MM_SHUF_PERM(2,3,0,1)); }
__forceinline vdouble8 vreduce_add (const vdouble8& y) { const vdouble8 x = vreduce_add4(y); return x + shuffle4(x,_MM_SHUF_PERM(1,0,3,2)); }
////////////////////////////////////////////////////////////////////////////////
/// Memory load and store operations
////////////////////////////////////////////////////////////////////////////////
__forceinline vdouble8 permute(const vdouble8& v, const vllong8& index) {
return _mm512_permutexvar_pd(index, v);
__forceinline vdouble8 permute(const vdouble8& v, const vlong8& index) {
return _mm512_permutexvar_pd(index,v);
}
__forceinline vdouble8 reverse(const vdouble8& a) {
return permute(a, vllong8(reverse_step));
return permute(a,vlong8(reverse_step));
}
////////////////////////////////////////////////////////////////////////////////
/// Output Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline std::ostream& operator <<(std::ostream& cout, const vdouble8& v)
__forceinline std::ostream& operator<<(std::ostream& cout, const vdouble8& v)
{
cout << "<" << v[0];
for (size_t i=1; i<8; i++) cout << ", " << v[i];
File diff suppressed because it is too large Load Diff
+189 -309
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
@@ -33,76 +33,67 @@ namespace embree
/// Constructors, Assignment & Cast Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline vfloat() {}
__forceinline vfloat(const vfloat4& other) { v = other.v; }
__forceinline vfloat4& operator =(const vfloat4& other) { v = other.v; return *this; }
__forceinline vfloat ( ) {}
__forceinline vfloat ( const vfloat4& other ) { v = other.v; }
__forceinline vfloat4& operator=( const vfloat4& other ) { v = other.v; return *this; }
__forceinline vfloat(__m128 a) : v(a) {}
__forceinline operator const __m128&() const { return v; }
__forceinline operator __m128&() { return v; }
__forceinline vfloat( const __m128 a ) : v(a) {}
__forceinline operator const __m128&( void ) const { return v; }
__forceinline operator __m128&( void ) { return v; }
__forceinline vfloat(float a) : v(_mm_set1_ps(a)) {}
__forceinline vfloat(float a, float b, float c, float d) : v(_mm_set_ps(d, c, b, a)) {}
__forceinline vfloat( float a ) : v(_mm_set1_ps(a)) {}
__forceinline vfloat( float a, float b, float c, float d) : v(_mm_set_ps(d, c, b, a)) {}
__forceinline explicit vfloat(__m128i a) : v(_mm_cvtepi32_ps(a)) {}
__forceinline explicit vfloat( const __m128i a ) : v(_mm_cvtepi32_ps(a)) {}
////////////////////////////////////////////////////////////////////////////////
/// Constants
////////////////////////////////////////////////////////////////////////////////
__forceinline vfloat(ZeroTy) : v(_mm_setzero_ps()) {}
__forceinline vfloat(OneTy) : v(_mm_set1_ps(1.0f)) {}
__forceinline vfloat(PosInfTy) : v(_mm_set1_ps(pos_inf)) {}
__forceinline vfloat(NegInfTy) : v(_mm_set1_ps(neg_inf)) {}
__forceinline vfloat(StepTy) : v(_mm_set_ps(3.0f, 2.0f, 1.0f, 0.0f)) {}
__forceinline vfloat(NaNTy) : v(_mm_set1_ps(nan)) {}
__forceinline vfloat(UndefinedTy) : v(_mm_undefined_ps()) {}
__forceinline vfloat( ZeroTy ) : v(_mm_setzero_ps()) {}
__forceinline vfloat( OneTy ) : v(_mm_set1_ps(1.0f)) {}
__forceinline vfloat( PosInfTy ) : v(_mm_set1_ps(pos_inf)) {}
__forceinline vfloat( NegInfTy ) : v(_mm_set1_ps(neg_inf)) {}
__forceinline vfloat( StepTy ) : v(_mm_set_ps(3.0f, 2.0f, 1.0f, 0.0f)) {}
__forceinline vfloat( NaNTy ) : v(_mm_set1_ps(nan)) {}
////////////////////////////////////////////////////////////////////////////////
/// Loads and Stores
////////////////////////////////////////////////////////////////////////////////
static __forceinline vfloat4 load (const void* a) { return _mm_load_ps((float*)a); }
static __forceinline vfloat4 loadu(const void* a) { return _mm_loadu_ps((float*)a); }
static __forceinline vfloat4 load ( const void* const a ) { return _mm_load_ps((float*)a); }
static __forceinline vfloat4 loadu( const void* const a ) { return _mm_loadu_ps((float*)a); }
static __forceinline void store (void* ptr, const vfloat4& v) { _mm_store_ps((float*)ptr,v); }
static __forceinline void storeu(void* ptr, const vfloat4& v) { _mm_storeu_ps((float*)ptr,v); }
static __forceinline void store ( void* ptr, const vfloat4& v ) { _mm_store_ps((float*)ptr,v); }
static __forceinline void storeu( void* ptr, const vfloat4& v ) { _mm_storeu_ps((float*)ptr,v); }
#if defined(__AVX512VL__)
static __forceinline vfloat4 load ( const vboolf4& mask, const void* const ptr) { return _mm_mask_load_ps (_mm_setzero_ps(),mask,(float*)ptr); }
static __forceinline vfloat4 loadu( const vboolf4& mask, const void* const ptr) { return _mm_mask_loadu_ps(_mm_setzero_ps(),mask,(float*)ptr); }
static __forceinline vfloat4 compact(const vboolf4& mask, vfloat4 &v) {
return _mm_mask_compress_ps(v, mask, v);
}
static __forceinline vfloat4 compact(const vboolf4& mask, vfloat4 &a, const vfloat4& b) {
return _mm_mask_compress_ps(a, mask, b);
}
static __forceinline vfloat4 load (const vboolf4& mask, const void* ptr) { return _mm_mask_load_ps (_mm_setzero_ps(),mask,(float*)ptr); }
static __forceinline vfloat4 loadu(const vboolf4& mask, const void* ptr) { return _mm_mask_loadu_ps(_mm_setzero_ps(),mask,(float*)ptr); }
static __forceinline void store (const vboolf4& mask, void* ptr, const vfloat4& v) { _mm_mask_store_ps ((float*)ptr,mask,v); }
static __forceinline void storeu(const vboolf4& mask, void* ptr, const vfloat4& v) { _mm_mask_storeu_ps((float*)ptr,mask,v); }
static __forceinline void store ( const vboolf4& mask, void* ptr, const vfloat4& v) { _mm_mask_store_ps ((float*)ptr,mask,v); }
static __forceinline void storeu( const vboolf4& mask, void* ptr, const vfloat4& v) { _mm_mask_storeu_ps((float*)ptr,mask,v); }
#elif defined(__AVX__)
static __forceinline vfloat4 load (const vboolf4& mask, const void* ptr) { return _mm_maskload_ps((float*)ptr,mask); }
static __forceinline vfloat4 loadu(const vboolf4& mask, const void* ptr) { return _mm_maskload_ps((float*)ptr,mask); }
static __forceinline vfloat4 load ( const vboolf4& mask, const void* const ptr ) { return _mm_maskload_ps((float*)ptr,mask); }
static __forceinline vfloat4 loadu( const vboolf4& mask, const void* const ptr ) { return _mm_maskload_ps((float*)ptr,mask); }
static __forceinline void store (const vboolf4& mask, void* ptr, const vfloat4& v) { _mm_maskstore_ps((float*)ptr,(__m128i)mask,v); }
static __forceinline void storeu(const vboolf4& mask, void* ptr, const vfloat4& v) { _mm_maskstore_ps((float*)ptr,(__m128i)mask,v); }
static __forceinline void store ( const vboolf4& mask, void* ptr, const vfloat4& v ) { _mm_maskstore_ps((float*)ptr,(__m128i)mask,v); }
static __forceinline void storeu( const vboolf4& mask, void* ptr, const vfloat4& v ) { _mm_maskstore_ps((float*)ptr,(__m128i)mask,v); }
#else
static __forceinline vfloat4 load (const vboolf4& mask, const void* ptr) { return _mm_and_ps(_mm_load_ps ((float*)ptr),mask); }
static __forceinline vfloat4 loadu(const vboolf4& mask, const void* ptr) { return _mm_and_ps(_mm_loadu_ps((float*)ptr),mask); }
static __forceinline vfloat4 load ( const vboolf4& mask, const void* const ptr ) { return _mm_and_ps(_mm_load_ps ((float*)ptr),mask); }
static __forceinline vfloat4 loadu( const vboolf4& mask, const void* const ptr ) { return _mm_and_ps(_mm_loadu_ps((float*)ptr),mask); }
static __forceinline void store (const vboolf4& mask, void* ptr, const vfloat4& v) { store (ptr,select(mask,v,load (ptr))); }
static __forceinline void storeu(const vboolf4& mask, void* ptr, const vfloat4& v) { storeu(ptr,select(mask,v,loadu(ptr))); }
static __forceinline void store ( const vboolf4& mask, void* ptr, const vfloat4& v ) { store (ptr,select(mask,v,load (ptr))); }
static __forceinline void storeu( const vboolf4& mask, void* ptr, const vfloat4& v ) { storeu(ptr,select(mask,v,loadu(ptr))); }
#endif
#if defined(__AVX__)
static __forceinline vfloat4 broadcast(const void* a) { return _mm_broadcast_ss((float*)a); }
static __forceinline vfloat4 broadcast( const void* const a ) { return _mm_broadcast_ss((float*)a); }
#else
static __forceinline vfloat4 broadcast(const void* a) { return _mm_set1_ps(*(float*)a); }
static __forceinline vfloat4 broadcast( const void* const a ) { return _mm_set1_ps(*(float*)a); }
#endif
static __forceinline vfloat4 load_nt (const float* ptr) {
static __forceinline vfloat4 load_nt ( const float* ptr ) {
#if defined (__SSE4_1__)
return _mm_castsi128_ps(_mm_stream_load_si128((__m128i*)ptr));
#else
@@ -111,21 +102,21 @@ namespace embree
}
#if defined(__SSE4_1__)
static __forceinline vfloat4 load(const unsigned char* ptr) {
static __forceinline vfloat4 load( const unsigned char* const ptr ) {
return _mm_cvtepi32_ps(_mm_cvtepu8_epi32(_mm_loadu_si128((__m128i*)ptr)));
}
#else
static __forceinline vfloat4 load(const unsigned char* ptr) {
static __forceinline vfloat4 load( const unsigned char* const ptr ) {
//return _mm_cvtpu8_ps(*(__m64*)ptr); // don't enable, will use MMX instructions
return vfloat4(ptr[0],ptr[1],ptr[2],ptr[3]);
}
#endif
static __forceinline vfloat4 load(const unsigned short* ptr) {
static __forceinline vfloat4 load(const unsigned short* const ptr) {
return _mm_mul_ps(vfloat4(vint4::load(ptr)),vfloat4(1.0f/65535.0f));
}
static __forceinline void store_nt(void* ptr, const vfloat4& v)
static __forceinline void store_nt ( void* ptr, const vfloat4& v)
{
#if defined (__SSE4_1__)
_mm_stream_ps((float*)ptr,v);
@@ -134,76 +125,33 @@ namespace embree
#endif
}
template<int scale = 4>
static __forceinline vfloat4 gather(const float* ptr, const vint4& index) {
#if defined(__AVX2__)
return _mm_i32gather_ps(ptr, index, scale);
#else
return vfloat4(
*(float*)(((char*)ptr)+scale*index[0]),
*(float*)(((char*)ptr)+scale*index[1]),
*(float*)(((char*)ptr)+scale*index[2]),
*(float*)(((char*)ptr)+scale*index[3]));
#endif
}
template<int scale = 4>
static __forceinline vfloat4 gather(const vboolf4& mask, const float* ptr, const vint4& index) {
vfloat4 r = zero;
#if defined(__AVX512VL__)
return _mm_mmask_i32gather_ps(r, mask, index, ptr, scale);
#elif defined(__AVX2__)
return _mm_mask_i32gather_ps(r, ptr, index, mask, scale);
#else
if (likely(mask[0])) r[0] = *(float*)(((char*)ptr)+scale*index[0]);
if (likely(mask[1])) r[1] = *(float*)(((char*)ptr)+scale*index[1]);
if (likely(mask[2])) r[2] = *(float*)(((char*)ptr)+scale*index[2]);
if (likely(mask[3])) r[3] = *(float*)(((char*)ptr)+scale*index[3]);
return r;
#endif
}
template<int scale = 4>
static __forceinline void scatter(void* ptr, const vint4& index, const vfloat4& v)
static __forceinline void store(const vboolf4& mask, void* ptr, const vint4& ofs, const vfloat4& v, const int scale = 1)
{
#if defined(__AVX512VL__)
_mm_i32scatter_ps((float*)ptr,index,v,scale);
_mm_mask_i32scatter_ps(ptr,mask,ofs,v,scale);
#else
*(float*)(((char*)ptr)+scale*index[0]) = v[0];
*(float*)(((char*)ptr)+scale*index[1]) = v[1];
*(float*)(((char*)ptr)+scale*index[2]) = v[2];
*(float*)(((char*)ptr)+scale*index[3]) = v[3];
#endif
}
template<int scale = 4>
static __forceinline void scatter(const vboolf4& mask, void* ptr, const vint4& index, const vfloat4& v)
{
#if defined(__AVX512VL__)
_mm_mask_i32scatter_ps((float*)ptr,mask,index,v,scale);
#else
if (likely(mask[0])) *(float*)(((char*)ptr)+scale*index[0]) = v[0];
if (likely(mask[1])) *(float*)(((char*)ptr)+scale*index[1]) = v[1];
if (likely(mask[2])) *(float*)(((char*)ptr)+scale*index[2]) = v[2];
if (likely(mask[3])) *(float*)(((char*)ptr)+scale*index[3]) = v[3];
if (likely(mask[0])) *(float*)(((char*)ptr)+scale*ofs[0]) = v[0];
if (likely(mask[1])) *(float*)(((char*)ptr)+scale*ofs[1]) = v[1];
if (likely(mask[2])) *(float*)(((char*)ptr)+scale*ofs[2]) = v[2];
if (likely(mask[3])) *(float*)(((char*)ptr)+scale*ofs[3]) = v[3];
#endif
}
static __forceinline void store(const vboolf4& mask, char* ptr, const vint4& ofs, const vfloat4& v) {
scatter<1>(mask,ptr,ofs,v);
store(mask,ptr,ofs,v,1);
}
static __forceinline void store(const vboolf4& mask, float* ptr, const vint4& ofs, const vfloat4& v) {
scatter<4>(mask,ptr,ofs,v);
store(mask,ptr,ofs,v,4);
}
////////////////////////////////////////////////////////////////////////////////
/// Array Access
////////////////////////////////////////////////////////////////////////////////
__forceinline const float& operator [](size_t index) const { assert(index < 4); return f[index]; }
__forceinline float& operator [](size_t index) { assert(index < 4); return f[index]; }
__forceinline const float& operator []( const size_t index ) const { assert(index < 4); return f[index]; }
__forceinline float& operator []( const size_t index ) { assert(index < 4); return f[index]; }
friend __forceinline vfloat4 select(const vboolf4& m, const vfloat4& t, const vfloat4& f) {
friend __forceinline const vfloat4 select( const vboolf4& m, const vfloat4& t, const vfloat4& f ) {
#if defined(__AVX512VL__)
return _mm_mask_blend_ps(m, f, t);
#elif defined(__SSE4_1__)
@@ -219,55 +167,34 @@ namespace embree
/// Unary Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline vfloat4 asFloat(const __m128i& a) { return _mm_castsi128_ps(a); }
__forceinline vfloat4 operator +(const vfloat4& a) { return a; }
__forceinline vfloat4 operator -(const vfloat4& a) { return _mm_xor_ps(a, _mm_castsi128_ps(_mm_set1_epi32(0x80000000))); }
__forceinline vfloat4 abs(const vfloat4& a) { return _mm_and_ps(a, _mm_castsi128_ps(_mm_set1_epi32(0x7fffffff))); }
__forceinline const vfloat4 asFloat ( const __m128i& a ) { return _mm_castsi128_ps(a); }
__forceinline const vfloat4 operator +( const vfloat4& a ) { return a; }
__forceinline const vfloat4 operator -( const vfloat4& a ) { return _mm_xor_ps(a.v, _mm_castsi128_ps(_mm_set1_epi32(0x80000000))); }
__forceinline const vfloat4 abs ( const vfloat4& a ) { return _mm_and_ps(a.v, _mm_castsi128_ps(_mm_set1_epi32(0x7fffffff))); }
#if defined(__AVX512VL__)
__forceinline vfloat4 sign(const vfloat4& a) { return _mm_mask_blend_ps(_mm_cmp_ps_mask(a, vfloat4(zero), _CMP_LT_OQ), vfloat4(one), -vfloat4(one)); }
__forceinline const vfloat4 sign ( const vfloat4& a ) { return _mm_mask_blend_ps(_mm_cmp_ps_mask(a, vfloat4(zero), _CMP_LT_OQ), vfloat4(one), -vfloat4(one)); }
#else
__forceinline vfloat4 sign(const vfloat4& a) { return blendv_ps(vfloat4(one), -vfloat4(one), _mm_cmplt_ps(a, vfloat4(zero))); }
__forceinline const vfloat4 sign ( const vfloat4& a ) { return blendv_ps(vfloat4(one), -vfloat4(one), _mm_cmplt_ps(a, vfloat4(zero))); }
#endif
__forceinline vfloat4 signmsk(const vfloat4& a) { return _mm_and_ps(a,_mm_castsi128_ps(_mm_set1_epi32(0x80000000))); }
__forceinline const vfloat4 signmsk ( const vfloat4& a ) { return _mm_and_ps(a.v,_mm_castsi128_ps(_mm_set1_epi32(0x80000000))); }
__forceinline vfloat4 rcp(const vfloat4& a)
{
#if defined(__AVX512VL__)
const vfloat4 r = _mm_rcp14_ps(a);
#else
const vfloat4 r = _mm_rcp_ps(a);
#endif
__forceinline const vfloat4 rcp ( const vfloat4& a ) {
const vfloat4 r = _mm_rcp_ps(a.v);
#if defined(__AVX2__)
return _mm_mul_ps(r,_mm_fnmadd_ps(r, a, vfloat4(2.0f)));
#else
return _mm_mul_ps(r,_mm_sub_ps(vfloat4(2.0f), _mm_mul_ps(r, a)));
#endif
}
__forceinline vfloat4 sqr (const vfloat4& a) { return _mm_mul_ps(a,a); }
__forceinline vfloat4 sqrt(const vfloat4& a) { return _mm_sqrt_ps(a); }
__forceinline vfloat4 rsqrt(const vfloat4& a)
{
#if defined(__AVX512VL__)
const vfloat4 r = _mm_rsqrt14_ps(a);
#else
const vfloat4 r = _mm_rsqrt_ps(a);
#endif
#if defined(__AVX2__)
return _mm_fmadd_ps(_mm_set1_ps(1.5f), r,
_mm_mul_ps(_mm_mul_ps(_mm_mul_ps(a, _mm_set1_ps(-0.5f)), r), _mm_mul_ps(r, r)));
#else
return _mm_add_ps(_mm_mul_ps(_mm_set1_ps(1.5f), r),
_mm_mul_ps(_mm_mul_ps(_mm_mul_ps(a, _mm_set1_ps(-0.5f)), r), _mm_mul_ps(r, r)));
#endif
__forceinline const vfloat4 sqr ( const vfloat4& a ) { return _mm_mul_ps(a,a); }
__forceinline const vfloat4 sqrt ( const vfloat4& a ) { return _mm_sqrt_ps(a.v); }
__forceinline const vfloat4 rsqrt( const vfloat4& a ) {
const vfloat4 r = _mm_rsqrt_ps(a.v);
return _mm_add_ps(_mm_mul_ps(_mm_set_ps(1.5f, 1.5f, 1.5f, 1.5f), r),
_mm_mul_ps(_mm_mul_ps(_mm_mul_ps(a, _mm_set_ps(-0.5f, -0.5f, -0.5f, -0.5f)), r), _mm_mul_ps(r, r)));
}
__forceinline vboolf4 isnan(const vfloat4& a) {
const vfloat4 b = _mm_and_ps(a, _mm_castsi128_ps(_mm_set1_epi32(0x7fffffff)));
__forceinline const vboolf4 isnan( const vfloat4& a ) {
const vfloat4 b = _mm_and_ps(a.v, _mm_castsi128_ps(_mm_set1_epi32(0x7fffffff)));
#if defined(__AVX512VL__)
return _mm_cmp_epi32_mask(_mm_castps_si128(b), _mm_set1_epi32(0x7f800000), _MM_CMPINT_GT);
#else
@@ -279,32 +206,32 @@ namespace embree
/// Binary Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline vfloat4 operator +(const vfloat4& a, const vfloat4& b) { return _mm_add_ps(a, b); }
__forceinline vfloat4 operator +(const vfloat4& a, float b) { return a + vfloat4(b); }
__forceinline vfloat4 operator +(float a, const vfloat4& b) { return vfloat4(a) + b; }
__forceinline const vfloat4 operator +( const vfloat4& a, const vfloat4& b ) { return _mm_add_ps(a.v, b.v); }
__forceinline const vfloat4 operator +( const vfloat4& a, const float& b ) { return a + vfloat4(b); }
__forceinline const vfloat4 operator +( const float& a, const vfloat4& b ) { return vfloat4(a) + b; }
__forceinline vfloat4 operator -(const vfloat4& a, const vfloat4& b) { return _mm_sub_ps(a, b); }
__forceinline vfloat4 operator -(const vfloat4& a, float b) { return a - vfloat4(b); }
__forceinline vfloat4 operator -(float a, const vfloat4& b) { return vfloat4(a) - b; }
__forceinline const vfloat4 operator -( const vfloat4& a, const vfloat4& b ) { return _mm_sub_ps(a.v, b.v); }
__forceinline const vfloat4 operator -( const vfloat4& a, const float& b ) { return a - vfloat4(b); }
__forceinline const vfloat4 operator -( const float& a, const vfloat4& b ) { return vfloat4(a) - b; }
__forceinline vfloat4 operator *(const vfloat4& a, const vfloat4& b) { return _mm_mul_ps(a, b); }
__forceinline vfloat4 operator *(const vfloat4& a, float b) { return a * vfloat4(b); }
__forceinline vfloat4 operator *(float a, const vfloat4& b) { return vfloat4(a) * b; }
__forceinline const vfloat4 operator *( const vfloat4& a, const vfloat4& b ) { return _mm_mul_ps(a.v, b.v); }
__forceinline const vfloat4 operator *( const vfloat4& a, const float& b ) { return a * vfloat4(b); }
__forceinline const vfloat4 operator *( const float& a, const vfloat4& b ) { return vfloat4(a) * b; }
__forceinline vfloat4 operator /(const vfloat4& a, const vfloat4& b) { return _mm_div_ps(a,b); }
__forceinline vfloat4 operator /(const vfloat4& a, float b) { return a/vfloat4(b); }
__forceinline vfloat4 operator /(float a, const vfloat4& b) { return vfloat4(a)/b; }
__forceinline const vfloat4 operator /( const vfloat4& a, const vfloat4& b ) { return _mm_div_ps(a.v,b.v); }
__forceinline const vfloat4 operator /( const vfloat4& a, const float& b ) { return a/vfloat4(b); }
__forceinline const vfloat4 operator /( const float& a, const vfloat4& b ) { return vfloat4(a)/b; }
__forceinline vfloat4 operator ^(const vfloat4& a, const vfloat4& b) { return _mm_xor_ps(a,b); }
__forceinline vfloat4 operator ^(const vfloat4& a, const vint4& b) { return _mm_xor_ps(a,_mm_castsi128_ps(b)); }
__forceinline const vfloat4 operator^( const vfloat4& a, const vfloat4& b ) { return _mm_xor_ps(a.v,b.v); }
__forceinline const vfloat4 operator^( const vfloat4& a, const vint4& b ) { return _mm_xor_ps(a.v,_mm_castsi128_ps(b.v)); }
__forceinline vfloat4 min(const vfloat4& a, const vfloat4& b) { return _mm_min_ps(a,b); }
__forceinline vfloat4 min(const vfloat4& a, float b) { return _mm_min_ps(a,vfloat4(b)); }
__forceinline vfloat4 min(float a, const vfloat4& b) { return _mm_min_ps(vfloat4(a),b); }
__forceinline const vfloat4 min( const vfloat4& a, const vfloat4& b ) { return _mm_min_ps(a.v,b.v); }
__forceinline const vfloat4 min( const vfloat4& a, const float& b ) { return _mm_min_ps(a.v,vfloat4(b)); }
__forceinline const vfloat4 min( const float& a, const vfloat4& b ) { return _mm_min_ps(vfloat4(a),b.v); }
__forceinline vfloat4 max(const vfloat4& a, const vfloat4& b) { return _mm_max_ps(a,b); }
__forceinline vfloat4 max(const vfloat4& a, float b) { return _mm_max_ps(a,vfloat4(b)); }
__forceinline vfloat4 max(float a, const vfloat4& b) { return _mm_max_ps(vfloat4(a),b); }
__forceinline const vfloat4 max( const vfloat4& a, const vfloat4& b ) { return _mm_max_ps(a.v,b.v); }
__forceinline const vfloat4 max( const vfloat4& a, const float& b ) { return _mm_max_ps(a.v,vfloat4(b)); }
__forceinline const vfloat4 max( const float& a, const vfloat4& b ) { return _mm_max_ps(vfloat4(a),b.v); }
#if defined(__SSE4_1__)
__forceinline vfloat4 mini(const vfloat4& a, const vfloat4& b) {
@@ -313,7 +240,6 @@ namespace embree
const vint4 ci = _mm_min_epi32(ai,bi);
return _mm_castsi128_ps(ci);
}
__forceinline vfloat4 maxi(const vfloat4& a, const vfloat4& b) {
const vint4 ai = _mm_castps_si128(a);
const vint4 bi = _mm_castps_si128(b);
@@ -327,18 +253,17 @@ namespace embree
const vint4 ci = _mm_min_epu32(ai,bi);
return _mm_castsi128_ps(ci);
}
__forceinline vfloat4 maxui(const vfloat4& a, const vfloat4& b) {
const vint4 ai = _mm_castps_si128(a);
const vint4 bi = _mm_castps_si128(b);
const vint4 ci = _mm_max_epu32(ai,bi);
return _mm_castsi128_ps(ci);
}
#else
__forceinline vfloat4 mini(const vfloat4& a, const vfloat4& b) {
return min(a,b);
}
__forceinline vfloat4 maxi(const vfloat4& a, const vfloat4& b) {
return max(a,b);
}
@@ -349,117 +274,101 @@ namespace embree
////////////////////////////////////////////////////////////////////////////////
#if defined(__AVX2__)
__forceinline vfloat4 madd (const vfloat4& a, const vfloat4& b, const vfloat4& c) { return _mm_fmadd_ps(a,b,c); }
__forceinline vfloat4 msub (const vfloat4& a, const vfloat4& b, const vfloat4& c) { return _mm_fmsub_ps(a,b,c); }
__forceinline vfloat4 nmadd(const vfloat4& a, const vfloat4& b, const vfloat4& c) { return _mm_fnmadd_ps(a,b,c); }
__forceinline vfloat4 nmsub(const vfloat4& a, const vfloat4& b, const vfloat4& c) { return _mm_fnmsub_ps(a,b,c); }
__forceinline const vfloat4 madd ( const vfloat4& a, const vfloat4& b, const vfloat4& c) { return _mm_fmadd_ps(a,b,c); }
__forceinline const vfloat4 msub ( const vfloat4& a, const vfloat4& b, const vfloat4& c) { return _mm_fmsub_ps(a,b,c); }
__forceinline const vfloat4 nmadd ( const vfloat4& a, const vfloat4& b, const vfloat4& c) { return _mm_fnmadd_ps(a,b,c); }
__forceinline const vfloat4 nmsub ( const vfloat4& a, const vfloat4& b, const vfloat4& c) { return _mm_fnmsub_ps(a,b,c); }
#else
__forceinline vfloat4 madd (const vfloat4& a, const vfloat4& b, const vfloat4& c) { return a*b+c; }
__forceinline vfloat4 msub (const vfloat4& a, const vfloat4& b, const vfloat4& c) { return a*b-c; }
__forceinline vfloat4 nmadd(const vfloat4& a, const vfloat4& b, const vfloat4& c) { return -a*b+c;}
__forceinline vfloat4 nmsub(const vfloat4& a, const vfloat4& b, const vfloat4& c) { return -a*b-c; }
__forceinline const vfloat4 madd ( const vfloat4& a, const vfloat4& b, const vfloat4& c) { return a*b+c; }
__forceinline const vfloat4 msub ( const vfloat4& a, const vfloat4& b, const vfloat4& c) { return a*b-c; }
__forceinline const vfloat4 nmadd ( const vfloat4& a, const vfloat4& b, const vfloat4& c) { return -a*b+c;}
__forceinline const vfloat4 nmsub ( const vfloat4& a, const vfloat4& b, const vfloat4& c) { return -a*b-c; }
#endif
////////////////////////////////////////////////////////////////////////////////
/// Assignment Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline vfloat4& operator +=(vfloat4& a, const vfloat4& b) { return a = a + b; }
__forceinline vfloat4& operator +=(vfloat4& a, float b) { return a = a + b; }
__forceinline vfloat4& operator +=( vfloat4& a, const vfloat4& b ) { return a = a + b; }
__forceinline vfloat4& operator +=( vfloat4& a, const float& b ) { return a = a + b; }
__forceinline vfloat4& operator -=(vfloat4& a, const vfloat4& b) { return a = a - b; }
__forceinline vfloat4& operator -=(vfloat4& a, float b) { return a = a - b; }
__forceinline vfloat4& operator -=( vfloat4& a, const vfloat4& b ) { return a = a - b; }
__forceinline vfloat4& operator -=( vfloat4& a, const float& b ) { return a = a - b; }
__forceinline vfloat4& operator *=(vfloat4& a, const vfloat4& b) { return a = a * b; }
__forceinline vfloat4& operator *=(vfloat4& a, float b) { return a = a * b; }
__forceinline vfloat4& operator *=( vfloat4& a, const vfloat4& b ) { return a = a * b; }
__forceinline vfloat4& operator *=( vfloat4& a, const float& b ) { return a = a * b; }
__forceinline vfloat4& operator /=(vfloat4& a, const vfloat4& b) { return a = a / b; }
__forceinline vfloat4& operator /=(vfloat4& a, float b) { return a = a / b; }
__forceinline vfloat4& operator /=( vfloat4& a, const vfloat4& b ) { return a = a / b; }
__forceinline vfloat4& operator /=( vfloat4& a, const float& b ) { return a = a / b; }
////////////////////////////////////////////////////////////////////////////////
/// Comparison Operators + Select
////////////////////////////////////////////////////////////////////////////////
#if defined(__AVX512VL__)
__forceinline vboolf4 operator ==(const vfloat4& a, const vfloat4& b) { return _mm_cmp_ps_mask(a, b, _MM_CMPINT_EQ); }
__forceinline vboolf4 operator !=(const vfloat4& a, const vfloat4& b) { return _mm_cmp_ps_mask(a, b, _MM_CMPINT_NE); }
__forceinline vboolf4 operator < (const vfloat4& a, const vfloat4& b) { return _mm_cmp_ps_mask(a, b, _MM_CMPINT_LT); }
__forceinline vboolf4 operator >=(const vfloat4& a, const vfloat4& b) { return _mm_cmp_ps_mask(a, b, _MM_CMPINT_GE); }
__forceinline vboolf4 operator > (const vfloat4& a, const vfloat4& b) { return _mm_cmp_ps_mask(a, b, _MM_CMPINT_GT); }
__forceinline vboolf4 operator <=(const vfloat4& a, const vfloat4& b) { return _mm_cmp_ps_mask(a, b, _MM_CMPINT_LE); }
__forceinline const vboolf4 operator ==( const vfloat4& a, const vfloat4& b ) { return _mm_cmp_ps_mask(a.v, b.v, _CMP_EQ_OQ ); }
__forceinline const vboolf4 operator !=( const vfloat4& a, const vfloat4& b ) { return _mm_cmp_ps_mask(a.v, b.v, _CMP_NEQ_OQ); }
__forceinline const vboolf4 operator < ( const vfloat4& a, const vfloat4& b ) { return _mm_cmp_ps_mask(a.v, b.v, _CMP_LT_OQ ); }
__forceinline const vboolf4 operator >=( const vfloat4& a, const vfloat4& b ) { return _mm_cmp_ps_mask(a.v, b.v, _CMP_GE_OQ ); }
__forceinline const vboolf4 operator > ( const vfloat4& a, const vfloat4& b ) { return _mm_cmp_ps_mask(a.v, b.v, _CMP_GT_OQ ); }
__forceinline const vboolf4 operator <=( const vfloat4& a, const vfloat4& b ) { return _mm_cmp_ps_mask(a.v, b.v, _CMP_LE_OQ ); }
#else
__forceinline vboolf4 operator ==(const vfloat4& a, const vfloat4& b) { return _mm_cmpeq_ps (a, b); }
__forceinline vboolf4 operator !=(const vfloat4& a, const vfloat4& b) { return _mm_cmpneq_ps(a, b); }
__forceinline vboolf4 operator < (const vfloat4& a, const vfloat4& b) { return _mm_cmplt_ps (a, b); }
__forceinline vboolf4 operator >=(const vfloat4& a, const vfloat4& b) { return _mm_cmpnlt_ps(a, b); }
__forceinline vboolf4 operator > (const vfloat4& a, const vfloat4& b) { return _mm_cmpnle_ps(a, b); }
__forceinline vboolf4 operator <=(const vfloat4& a, const vfloat4& b) { return _mm_cmple_ps (a, b); }
__forceinline const vboolf4 operator ==( const vfloat4& a, const vfloat4& b ) { return _mm_cmpeq_ps (a.v, b.v); }
__forceinline const vboolf4 operator !=( const vfloat4& a, const vfloat4& b ) { return _mm_cmpneq_ps(a.v, b.v); }
__forceinline const vboolf4 operator < ( const vfloat4& a, const vfloat4& b ) { return _mm_cmplt_ps (a.v, b.v); }
__forceinline const vboolf4 operator >=( const vfloat4& a, const vfloat4& b ) { return _mm_cmpnlt_ps(a.v, b.v); }
__forceinline const vboolf4 operator > ( const vfloat4& a, const vfloat4& b ) { return _mm_cmpnle_ps(a.v, b.v); }
__forceinline const vboolf4 operator <=( const vfloat4& a, const vfloat4& b ) { return _mm_cmple_ps (a.v, b.v); }
#endif
__forceinline vboolf4 operator ==(const vfloat4& a, float b) { return a == vfloat4(b); }
__forceinline vboolf4 operator ==(float a, const vfloat4& b) { return vfloat4(a) == b; }
__forceinline const vboolf4 operator ==( const vfloat4& a, const float& b ) { return a == vfloat4(b); }
__forceinline const vboolf4 operator ==( const float& a, const vfloat4& b ) { return vfloat4(a) == b; }
__forceinline vboolf4 operator !=(const vfloat4& a, float b) { return a != vfloat4(b); }
__forceinline vboolf4 operator !=(float a, const vfloat4& b) { return vfloat4(a) != b; }
__forceinline const vboolf4 operator !=( const vfloat4& a, const float& b ) { return a != vfloat4(b); }
__forceinline const vboolf4 operator !=( const float& a, const vfloat4& b ) { return vfloat4(a) != b; }
__forceinline vboolf4 operator < (const vfloat4& a, float b) { return a < vfloat4(b); }
__forceinline vboolf4 operator < (float a, const vfloat4& b) { return vfloat4(a) < b; }
__forceinline const vboolf4 operator < ( const vfloat4& a, const float& b ) { return a < vfloat4(b); }
__forceinline const vboolf4 operator < ( const float& a, const vfloat4& b ) { return vfloat4(a) < b; }
__forceinline vboolf4 operator >=(const vfloat4& a, float b) { return a >= vfloat4(b); }
__forceinline vboolf4 operator >=(float a, const vfloat4& b) { return vfloat4(a) >= b; }
__forceinline const vboolf4 operator >=( const vfloat4& a, const float& b ) { return a >= vfloat4(b); }
__forceinline const vboolf4 operator >=( const float& a, const vfloat4& b ) { return vfloat4(a) >= b; }
__forceinline vboolf4 operator > (const vfloat4& a, float b) { return a > vfloat4(b); }
__forceinline vboolf4 operator > (float a, const vfloat4& b) { return vfloat4(a) > b; }
__forceinline const vboolf4 operator > ( const vfloat4& a, const float& b ) { return a > vfloat4(b); }
__forceinline const vboolf4 operator > ( const float& a, const vfloat4& b ) { return vfloat4(a) > b; }
__forceinline vboolf4 operator <=(const vfloat4& a, float b) { return a <= vfloat4(b); }
__forceinline vboolf4 operator <=(float a, const vfloat4& b) { return vfloat4(a) <= b; }
__forceinline const vboolf4 operator <=( const vfloat4& a, const float& b ) { return a <= vfloat4(b); }
__forceinline const vboolf4 operator <=( const float& a, const vfloat4& b ) { return vfloat4(a) <= b; }
__forceinline vboolf4 eq(const vfloat4& a, const vfloat4& b) { return a == b; }
__forceinline vboolf4 ne(const vfloat4& a, const vfloat4& b) { return a != b; }
__forceinline vboolf4 lt(const vfloat4& a, const vfloat4& b) { return a < b; }
__forceinline vboolf4 ge(const vfloat4& a, const vfloat4& b) { return a >= b; }
__forceinline vboolf4 gt(const vfloat4& a, const vfloat4& b) { return a > b; }
__forceinline vboolf4 le(const vfloat4& a, const vfloat4& b) { return a <= b; }
#if defined(__AVX512VL__)
__forceinline vboolf4 eq(const vboolf4& mask, const vfloat4& a, const vfloat4& b) { return _mm_mask_cmp_ps_mask(mask, a, b, _MM_CMPINT_EQ); }
__forceinline vboolf4 ne(const vboolf4& mask, const vfloat4& a, const vfloat4& b) { return _mm_mask_cmp_ps_mask(mask, a, b, _MM_CMPINT_NE); }
__forceinline vboolf4 lt(const vboolf4& mask, const vfloat4& a, const vfloat4& b) { return _mm_mask_cmp_ps_mask(mask, a, b, _MM_CMPINT_LT); }
__forceinline vboolf4 ge(const vboolf4& mask, const vfloat4& a, const vfloat4& b) { return _mm_mask_cmp_ps_mask(mask, a, b, _MM_CMPINT_GE); }
__forceinline vboolf4 gt(const vboolf4& mask, const vfloat4& a, const vfloat4& b) { return _mm_mask_cmp_ps_mask(mask, a, b, _MM_CMPINT_GT); }
__forceinline vboolf4 le(const vboolf4& mask, const vfloat4& a, const vfloat4& b) { return _mm_mask_cmp_ps_mask(mask, a, b, _MM_CMPINT_LE); }
#else
__forceinline vboolf4 eq(const vboolf4& mask, const vfloat4& a, const vfloat4& b) { return mask & (a == b); }
__forceinline vboolf4 ne(const vboolf4& mask, const vfloat4& a, const vfloat4& b) { return mask & (a != b); }
__forceinline vboolf4 lt(const vboolf4& mask, const vfloat4& a, const vfloat4& b) { return mask & (a < b); }
__forceinline vboolf4 ge(const vboolf4& mask, const vfloat4& a, const vfloat4& b) { return mask & (a >= b); }
__forceinline vboolf4 gt(const vboolf4& mask, const vfloat4& a, const vfloat4& b) { return mask & (a > b); }
__forceinline vboolf4 le(const vboolf4& mask, const vfloat4& a, const vfloat4& b) { return mask & (a <= b); }
#endif
template<int mask>
__forceinline vfloat4 select(const vfloat4& t, const vfloat4& f)
{
#if defined(__SSE4_1__)
return _mm_blend_ps(f, t, mask);
#else
#if defined(__clang__) && !defined(__INTEL_COMPILER) || defined(_MSC_VER) && !defined(__INTEL_COMPILER) || defined(__INTEL_COMPILER) && defined(_DEBUG)
__forceinline const vfloat4 select(const int mask, const vfloat4& t, const vfloat4& f) {
return select(vboolf4(mask), t, f);
}
#else
__forceinline const vfloat4 select(const int mask, const vfloat4& t, const vfloat4& f) {
return _mm_blend_ps(f, t, mask);
}
#endif
#endif
__forceinline vfloat4 lerp(const vfloat4& a, const vfloat4& b, const vfloat4& t) {
#if defined(__AVX2__)
return madd(t, b, madd(-t, a, a));
#else
return a + t*(b-a);
#endif
}
__forceinline vfloat4 lerp(const vfloat4& a, const vfloat4& b, const vfloat4& t) {
return madd(t,b-a,a);
}
__forceinline bool isvalid(const vfloat4& v) {
__forceinline bool isvalid ( const vfloat4& v ) {
return all((v > vfloat4(-FLT_LARGE)) & (v < vfloat4(+FLT_LARGE)));
}
__forceinline bool is_finite(const vfloat4& a) {
__forceinline bool is_finite ( const vfloat4& a ) {
return all((a >= vfloat4(-FLT_MAX)) & (a <= vfloat4(+FLT_MAX)));
}
__forceinline bool is_finite(const vboolf4& valid, const vfloat4& a) {
__forceinline bool is_finite ( const vboolf4& valid, const vfloat4& a ) {
return all(valid, (a >= vfloat4(-FLT_MAX)) & (a <= vfloat4(+FLT_MAX)));
}
@@ -468,18 +377,18 @@ namespace embree
////////////////////////////////////////////////////////////////////////////////
#if defined (__SSE4_1__)
__forceinline vfloat4 floor(const vfloat4& a) { return _mm_round_ps(a, _MM_FROUND_TO_NEG_INF ); }
__forceinline vfloat4 ceil (const vfloat4& a) { return _mm_round_ps(a, _MM_FROUND_TO_POS_INF ); }
__forceinline vfloat4 trunc(const vfloat4& a) { return _mm_round_ps(a, _MM_FROUND_TO_ZERO ); }
__forceinline const vfloat4 floor ( const vfloat4& a ) { return _mm_round_ps(a, _MM_FROUND_TO_NEG_INF ); }
__forceinline const vfloat4 ceil ( const vfloat4& a ) { return _mm_round_ps(a, _MM_FROUND_TO_POS_INF ); }
__forceinline const vfloat4 trunc ( const vfloat4& a ) { return _mm_round_ps(a, _MM_FROUND_TO_ZERO ); }
#else
__forceinline vfloat4 floor(const vfloat4& a) { return vfloat4(floorf(a[0]),floorf(a[1]),floorf(a[2]),floorf(a[3])); }
__forceinline vfloat4 ceil (const vfloat4& a) { return vfloat4(ceilf (a[0]),ceilf (a[1]),ceilf (a[2]),ceilf (a[3])); }
//__forceinline vfloat4 trunc(const vfloat4& a) { return vfloat4(truncf(a[0]),truncf(a[1]),truncf(a[2]),truncf(a[3])); }
__forceinline const vfloat4 floor ( const vfloat4& a ) { return vfloat4(floorf(a[0]),floorf(a[1]),floorf(a[2]),floorf(a[3])); }
__forceinline const vfloat4 ceil ( const vfloat4& a ) { return vfloat4(ceilf (a[0]),ceilf (a[1]),ceilf (a[2]),ceilf (a[3])); }
//__forceinline const vfloat4 trunc ( const vfloat4& a ) { return vfloat4(truncf(a[0]),truncf(a[1]),truncf(a[2]),truncf(a[3])); }
#endif
__forceinline vfloat4 frac(const vfloat4& a) { return a-floor(a); }
__forceinline const vfloat4 frac ( const vfloat4& a ) { return a-floor(a); }
__forceinline vint4 floori(const vfloat4& a) {
#if defined(__SSE4_1__)
__forceinline vint4 floori (const vfloat4& a) {
#if defined (__SSE4_1__)
return vint4(floor(a));
#else
return vint4(a-vfloat4(0.5f));
@@ -490,59 +399,56 @@ namespace embree
/// Movement/Shifting/Shuffling Functions
////////////////////////////////////////////////////////////////////////////////
__forceinline vfloat4 unpacklo(const vfloat4& a, const vfloat4& b) { return _mm_unpacklo_ps(a, b); }
__forceinline vfloat4 unpackhi(const vfloat4& a, const vfloat4& b) { return _mm_unpackhi_ps(a, b); }
__forceinline vfloat4 unpacklo( const vfloat4& a, const vfloat4& b ) { return _mm_unpacklo_ps(a.v, b.v); }
__forceinline vfloat4 unpackhi( const vfloat4& a, const vfloat4& b ) { return _mm_unpackhi_ps(a.v, b.v); }
template<int i0, int i1, int i2, int i3>
__forceinline vfloat4 shuffle(const vfloat4& v) {
return _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(v), _MM_SHUFFLE(i3, i2, i1, i0)));
template<size_t i0, size_t i1, size_t i2, size_t i3> __forceinline const vfloat4 shuffle( const vfloat4& b ) {
return _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(b), _MM_SHUFFLE(i3, i2, i1, i0)));
}
template<int i0, int i1, int i2, int i3>
__forceinline vfloat4 shuffle(const vfloat4& a, const vfloat4& b) {
template<size_t i0, size_t i1, size_t i2, size_t i3> __forceinline const vfloat4 shuffle( const vfloat4& a, const vfloat4& b ) {
return _mm_shuffle_ps(a, b, _MM_SHUFFLE(i3, i2, i1, i0));
}
#if defined (__SSSE3__)
__forceinline vfloat4 shuffle8(const vfloat4& a, const vint4& shuf) {
__forceinline const vfloat4 shuffle8(const vfloat4& a, const vint4& shuf) {
return _mm_castsi128_ps(_mm_shuffle_epi8(_mm_castps_si128(a), shuf));
}
#endif
#if defined(__SSE3__)
template<> __forceinline vfloat4 shuffle<0, 0, 2, 2>(const vfloat4& v) { return _mm_moveldup_ps(v); }
template<> __forceinline vfloat4 shuffle<1, 1, 3, 3>(const vfloat4& v) { return _mm_movehdup_ps(v); }
template<> __forceinline vfloat4 shuffle<0, 1, 0, 1>(const vfloat4& v) { return _mm_castpd_ps(_mm_movedup_pd(_mm_castps_pd(v))); }
template<> __forceinline const vfloat4 shuffle<0, 0, 2, 2>( const vfloat4& b ) { return _mm_moveldup_ps(b); }
template<> __forceinline const vfloat4 shuffle<1, 1, 3, 3>( const vfloat4& b ) { return _mm_movehdup_ps(b); }
template<> __forceinline const vfloat4 shuffle<0, 1, 0, 1>( const vfloat4& b ) { return _mm_castpd_ps(_mm_movedup_pd(_mm_castps_pd(b))); }
#endif
template<int i>
__forceinline vfloat4 shuffle(const vfloat4& v) {
return shuffle<i,i,i,i>(v);
template<size_t i0> __forceinline const vfloat4 shuffle( const vfloat4& b ) {
return shuffle<i0,i0,i0,i0>(b);
}
#if defined (__SSE4_1__) && !defined(__GNUC__)
template<int i> __forceinline float extract(const vfloat4& a) { return _mm_cvtss_f32(_mm_extract_ps(a,i)); }
template<size_t i> __forceinline float extract ( const vfloat4& a ) { return _mm_cvtss_f32(_mm_extract_ps(a,i)); }
#else
template<int i> __forceinline float extract(const vfloat4& a) { return _mm_cvtss_f32(shuffle<i,i,i,i>(a)); }
template<size_t i> __forceinline float extract ( const vfloat4& a ) { return _mm_cvtss_f32(shuffle<i,i,i,i>(a)); }
#endif
template<> __forceinline float extract<0>(const vfloat4& a) { return _mm_cvtss_f32(a); }
template<> __forceinline float extract<0>( const vfloat4& a ) { return _mm_cvtss_f32(a); }
#if defined (__SSE4_1__)
template<int dst, int src, int clr> __forceinline vfloat4 insert(const vfloat4& a, const vfloat4& b) { return _mm_insert_ps(a, b, (dst << 4) | (src << 6) | clr); }
template<int dst, int src> __forceinline vfloat4 insert(const vfloat4& a, const vfloat4& b) { return insert<dst, src, 0>(a, b); }
template<int dst> __forceinline vfloat4 insert(const vfloat4& a, const float b) { return insert<dst, 0>(a, _mm_set_ss(b)); }
template<size_t dst, size_t src, size_t clr> __forceinline const vfloat4 insert( const vfloat4& a, const vfloat4& b ) { return _mm_insert_ps(a, b, (dst << 4) | (src << 6) | clr); }
template<size_t dst, size_t src> __forceinline const vfloat4 insert( const vfloat4& a, const vfloat4& b ) { return insert<dst, src, 0>(a, b); }
template<size_t dst> __forceinline const vfloat4 insert( const vfloat4& a, const float b ) { return insert<dst, 0>(a, _mm_set_ss(b)); }
#else
template<int dst, int src> __forceinline vfloat4 insert(const vfloat4& a, const vfloat4& b) { vfloat4 c = a; c[dst&3] = b[src&3]; return c; }
template<int dst> __forceinline vfloat4 insert(const vfloat4& a, float b) { vfloat4 c = a; c[dst&3] = b; return c; }
template<size_t dst, size_t src> __forceinline const vfloat4 insert( const vfloat4& a, const vfloat4& b ) { vfloat4 c = a; c[dst] = b[src]; return c; }
template<size_t dst> __forceinline const vfloat4 insert( const vfloat4& a, const float b ) { vfloat4 c = a; c[dst] = b; return c; }
#endif
__forceinline float toScalar(const vfloat4& v) { return _mm_cvtss_f32(v); }
__forceinline float toScalar(const vfloat4& a) { return _mm_cvtss_f32(a); }
__forceinline vfloat4 broadcast4f(const vfloat4& a, size_t k) {
__forceinline vfloat4 broadcast4f( const vfloat4& a, const size_t k ) {
return vfloat4::broadcast(&a[k]);
}
__forceinline vfloat4 shift_right_1(const vfloat4& x) {
__forceinline vfloat4 shift_right_1( const vfloat4& x) {
return _mm_castsi128_ps(_mm_srli_si128(_mm_castps_si128(x), 4));
}
@@ -551,55 +457,29 @@ namespace embree
return _mm_permutevar_ps(a,index);
}
__forceinline vfloat4 broadcast1f(const void* a) { return _mm_broadcast_ss((float*)a); }
__forceinline vfloat4 broadcast1f( const void* const a ) { return _mm_broadcast_ss((float*)a); }
#endif
#if defined(__AVX512VL__)
template<int i>
__forceinline vfloat4 align_shift_right(const vfloat4& a, const vfloat4& b) {
return _mm_castsi128_ps(_mm_alignr_epi32(_mm_castps_si128(a), _mm_castps_si128(b), i));
}
#endif
////////////////////////////////////////////////////////////////////////////////
/// Sorting Network
////////////////////////////////////////////////////////////////////////////////
__forceinline vfloat4 sort_ascending(const vfloat4& v)
__forceinline vfloat4 sortNetwork(const vfloat4& v)
{
const vfloat4 a0 = v;
const vfloat4 b0 = shuffle<1,0,3,2>(a0);
const vfloat4 c0 = min(a0,b0);
const vfloat4 d0 = max(a0,b0);
const vfloat4 a1 = select<0x5 /* 0b0101 */>(c0,d0);
const vfloat4 a1 = select(0x5 /* 0b0101 */,c0,d0);
const vfloat4 b1 = shuffle<2,3,0,1>(a1);
const vfloat4 c1 = min(a1,b1);
const vfloat4 d1 = max(a1,b1);
const vfloat4 a2 = select<0x3 /* 0b0011 */>(c1,d1);
const vfloat4 a2 = select(0x3 /* 0b0011 */,c1,d1);
const vfloat4 b2 = shuffle<0,2,1,3>(a2);
const vfloat4 c2 = min(a2,b2);
const vfloat4 d2 = max(a2,b2);
const vfloat4 a3 = select<0x2 /* 0b0010 */>(c2,d2);
return a3;
}
__forceinline vfloat4 sort_descending(const vfloat4& v)
{
const vfloat4 a0 = v;
const vfloat4 b0 = shuffle<1,0,3,2>(a0);
const vfloat4 c0 = max(a0,b0);
const vfloat4 d0 = min(a0,b0);
const vfloat4 a1 = select<0x5 /* 0b0101 */>(c0,d0);
const vfloat4 b1 = shuffle<2,3,0,1>(a1);
const vfloat4 c1 = max(a1,b1);
const vfloat4 d1 = min(a1,b1);
const vfloat4 a2 = select<0x3 /* 0b0011 */>(c1,d1);
const vfloat4 b2 = shuffle<0,2,1,3>(a2);
const vfloat4 c2 = max(a2,b2);
const vfloat4 d2 = min(a2,b2);
const vfloat4 a3 = select<0x2 /* 0b0010 */>(c2,d2);
const vfloat4 a3 = select(0x2 /* 0b0010 */,c2,d2);
return a3;
}
@@ -634,9 +514,9 @@ namespace embree
/// Reductions
////////////////////////////////////////////////////////////////////////////////
__forceinline vfloat4 vreduce_min(const vfloat4& v) { vfloat4 h = min(shuffle<1,0,3,2>(v),v); return min(shuffle<2,3,0,1>(h),h); }
__forceinline vfloat4 vreduce_max(const vfloat4& v) { vfloat4 h = max(shuffle<1,0,3,2>(v),v); return max(shuffle<2,3,0,1>(h),h); }
__forceinline vfloat4 vreduce_add(const vfloat4& v) { vfloat4 h = shuffle<1,0,3,2>(v) + v ; return shuffle<2,3,0,1>(h) + h ; }
__forceinline const vfloat4 vreduce_min(const vfloat4& v) { vfloat4 h = min(shuffle<1,0,3,2>(v),v); return min(shuffle<2,3,0,1>(h),h); }
__forceinline const vfloat4 vreduce_max(const vfloat4& v) { vfloat4 h = max(shuffle<1,0,3,2>(v),v); return max(shuffle<2,3,0,1>(h),h); }
__forceinline const vfloat4 vreduce_add(const vfloat4& v) { vfloat4 h = shuffle<1,0,3,2>(v) + v ; return shuffle<2,3,0,1>(h) + h ; }
__forceinline float reduce_min(const vfloat4& v) { return _mm_cvtss_f32(vreduce_min(v)); }
__forceinline float reduce_max(const vfloat4& v) { return _mm_cvtss_f32(vreduce_max(v)); }
@@ -659,11 +539,11 @@ namespace embree
/// Euclidian Space Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline float dot(const vfloat4& a, const vfloat4& b) {
__forceinline float dot ( const vfloat4& a, const vfloat4& b ) {
return reduce_add(a*b);
}
__forceinline vfloat4 cross(const vfloat4& a, const vfloat4& b)
__forceinline vfloat4 cross ( const vfloat4& a, const vfloat4& b )
{
const vfloat4 a0 = a;
const vfloat4 b0 = shuffle<1,2,0,3>(b);
@@ -676,7 +556,7 @@ namespace embree
/// Output Operators
////////////////////////////////////////////////////////////////////////////////
inline std::ostream& operator <<(std::ostream& cout, const vfloat4& a) {
inline std::ostream& operator<<(std::ostream& cout, const vfloat4& a) {
return cout << "<" << a[0] << ", " << a[1] << ", " << a[2] << ", " << a[3] << ">";
}
+245 -395
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
@@ -33,46 +33,45 @@ namespace embree
/// Constructors, Assignment & Cast Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline vfloat() {}
__forceinline vfloat(const vfloat8& other) { v = other.v; }
__forceinline vfloat8& operator =(const vfloat8& other) { v = other.v; return *this; }
__forceinline vfloat ( ) {}
__forceinline vfloat ( const vfloat8& other ) { v = other.v; }
__forceinline vfloat8& operator=( const vfloat8& other ) { v = other.v; return *this; }
__forceinline vfloat(__m256 a) : v(a) {}
__forceinline operator const __m256&() const { return v; }
__forceinline operator __m256&() { return v; }
__forceinline vfloat( const __m256 a ) : v(a) {}
__forceinline operator const __m256&( void ) const { return v; }
__forceinline operator __m256&( void ) { return v; }
__forceinline explicit vfloat(const vfloat4& a) : v(_mm256_insertf128_ps(_mm256_castps128_ps256(a),a,1)) {}
__forceinline vfloat(const vfloat4& a, const vfloat4& b) : v(_mm256_insertf128_ps(_mm256_castps128_ps256(a),b,1)) {}
__forceinline explicit vfloat( const vfloat4& a ) : v(_mm256_insertf128_ps(_mm256_castps128_ps256(a),a,1)) {}
__forceinline vfloat( const vfloat4& a, const vfloat4& b ) : v(_mm256_insertf128_ps(_mm256_castps128_ps256(a),b,1)) {}
__forceinline explicit vfloat(const char* a) : v(_mm256_loadu_ps((const float*)a)) {}
__forceinline vfloat(float a) : v(_mm256_set1_ps(a)) {}
__forceinline vfloat(float a, float b) : v(_mm256_set_ps(b, a, b, a, b, a, b, a)) {}
__forceinline vfloat(float a, float b, float c, float d) : v(_mm256_set_ps(d, c, b, a, d, c, b, a)) {}
__forceinline vfloat(float a, float b, float c, float d, float e, float f, float g, float h) : v(_mm256_set_ps(h, g, f, e, d, c, b, a)) {}
__forceinline explicit vfloat( const char* const a ) : v(_mm256_loadu_ps((const float*)a)) {}
__forceinline vfloat( const float& a ) : v(_mm256_broadcast_ss(&a)) {}
__forceinline vfloat( float a, float b) : v(_mm256_set_ps(b, a, b, a, b, a, b, a)) {}
__forceinline vfloat( float a, float b, float c, float d ) : v(_mm256_set_ps(d, c, b, a, d, c, b, a)) {}
__forceinline vfloat( float a, float b, float c, float d, float e, float f, float g, float h ) : v(_mm256_set_ps(h, g, f, e, d, c, b, a)) {}
__forceinline explicit vfloat(__m256i a) : v(_mm256_cvtepi32_ps(a)) {}
__forceinline explicit vfloat( const __m256i a ) : v(_mm256_cvtepi32_ps(a)) {}
////////////////////////////////////////////////////////////////////////////////
/// Constants
////////////////////////////////////////////////////////////////////////////////
__forceinline vfloat(ZeroTy) : v(_mm256_setzero_ps()) {}
__forceinline vfloat(OneTy) : v(_mm256_set1_ps(1.0f)) {}
__forceinline vfloat(PosInfTy) : v(_mm256_set1_ps(pos_inf)) {}
__forceinline vfloat(NegInfTy) : v(_mm256_set1_ps(neg_inf)) {}
__forceinline vfloat(StepTy) : v(_mm256_set_ps(7.0f, 6.0f, 5.0f, 4.0f, 3.0f, 2.0f, 1.0f, 0.0f)) {}
__forceinline vfloat(NaNTy) : v(_mm256_set1_ps(nan)) {}
__forceinline vfloat(UndefinedTy) : v(_mm256_undefined_ps()) {}
__forceinline vfloat( ZeroTy ) : v(_mm256_setzero_ps()) {}
__forceinline vfloat( OneTy ) : v(_mm256_set1_ps(1.0f)) {}
__forceinline vfloat( PosInfTy ) : v(_mm256_set1_ps(pos_inf)) {}
__forceinline vfloat( NegInfTy ) : v(_mm256_set1_ps(neg_inf)) {}
__forceinline vfloat( StepTy ) : v(_mm256_set_ps(7.0f, 6.0f, 5.0f, 4.0f, 3.0f, 2.0f, 1.0f, 0.0f)) {}
__forceinline vfloat( NaNTy ) : v(_mm256_set1_ps(nan)) {}
////////////////////////////////////////////////////////////////////////////////
/// Loads and Stores
////////////////////////////////////////////////////////////////////////////////
static __forceinline vfloat8 broadcast(const void* a) {
static __forceinline vfloat8 broadcast( const void* const a ) {
return _mm256_broadcast_ss((float*)a);
}
static __forceinline vfloat8 broadcast2(const float* a, const float* b) {
static __forceinline vfloat8 broadcast2( const float* const a, const float* const b ) {
#if defined(__INTEL_COMPILER)
const vfloat8 v0 = _mm256_broadcast_ss(a);
const vfloat8 v1 = _mm256_broadcast_ss(b);
@@ -82,11 +81,11 @@ namespace embree
#endif
}
static __forceinline vfloat8 broadcast4f(const vfloat4* ptr) {
static __forceinline const vfloat8 broadcast4f(const vfloat4* ptr) {
return _mm256_broadcast_ps((__m128*)ptr);
}
static __forceinline vfloat8 load(const unsigned char* ptr) {
static __forceinline vfloat8 load( const unsigned char* const ptr ) {
#if defined(__AVX2__)
return _mm256_cvtepi32_ps(_mm256_cvtepu8_epi32(_mm_loadu_si128((__m128i*)ptr)));
#else
@@ -94,32 +93,24 @@ namespace embree
#endif
}
static __forceinline vfloat8 load (const void* ptr) { return _mm256_load_ps((float*)ptr); }
static __forceinline vfloat8 loadu(const void* ptr) { return _mm256_loadu_ps((float*)ptr); }
static __forceinline vfloat8 load ( const void* const ptr) { return _mm256_load_ps((float*)ptr); }
static __forceinline vfloat8 loadu( const void* const ptr) { return _mm256_loadu_ps((float*)ptr); }
static __forceinline void store (void* ptr, const vfloat8& v) { return _mm256_store_ps((float*)ptr,v); }
static __forceinline void storeu(void* ptr, const vfloat8& v) { return _mm256_storeu_ps((float*)ptr,v); }
static __forceinline void store ( void* ptr, const vfloat8& v) { return _mm256_store_ps((float*)ptr,v); }
static __forceinline void storeu( void* ptr, const vfloat8& v) { return _mm256_storeu_ps((float*)ptr,v); }
#if defined(__AVX512VL__)
static __forceinline vfloat8 load ( const vboolf8& mask, const void* const ptr) { return _mm256_mask_load_ps (_mm256_setzero_ps(),mask,(float*)ptr); }
static __forceinline vfloat8 loadu( const vboolf8& mask, const void* const ptr) { return _mm256_mask_loadu_ps(_mm256_setzero_ps(),mask,(float*)ptr); }
static __forceinline vfloat8 compact(const vboolf8& mask, vfloat8 &v) {
return _mm256_mask_compress_ps(v, mask, v);
}
static __forceinline vfloat8 compact(const vboolf8& mask, vfloat8 &a, const vfloat8& b) {
return _mm256_mask_compress_ps(a, mask, b);
}
static __forceinline vfloat8 load (const vboolf8& mask, const void* ptr) { return _mm256_mask_load_ps (_mm256_setzero_ps(),mask,(float*)ptr); }
static __forceinline vfloat8 loadu(const vboolf8& mask, const void* ptr) { return _mm256_mask_loadu_ps(_mm256_setzero_ps(),mask,(float*)ptr); }
static __forceinline void store (const vboolf8& mask, void* ptr, const vfloat8& v) { _mm256_mask_store_ps ((float*)ptr,mask,v); }
static __forceinline void storeu(const vboolf8& mask, void* ptr, const vfloat8& v) { _mm256_mask_storeu_ps((float*)ptr,mask,v); }
static __forceinline void store ( const vboolf8& mask, void* ptr, const vfloat8& v) { _mm256_mask_store_ps ((float*)ptr,mask,v); }
static __forceinline void storeu( const vboolf8& mask, void* ptr, const vfloat8& v) { _mm256_mask_storeu_ps((float*)ptr,mask,v); }
#else
static __forceinline vfloat8 load (const vboolf8& mask, const void* ptr) { return _mm256_maskload_ps((float*)ptr,(__m256i)mask); }
static __forceinline vfloat8 loadu(const vboolf8& mask, const void* ptr) { return _mm256_maskload_ps((float*)ptr,(__m256i)mask); }
static __forceinline vfloat8 load ( const vboolf8& mask, const void* const ptr) { return _mm256_maskload_ps((float*)ptr,(__m256i)mask); }
static __forceinline vfloat8 loadu( const vboolf8& mask, const void* const ptr) { return _mm256_maskload_ps((float*)ptr,(__m256i)mask); }
static __forceinline void store (const vboolf8& mask, void* ptr, const vfloat8& v) { _mm256_maskstore_ps((float*)ptr,(__m256i)mask,v); }
static __forceinline void storeu(const vboolf8& mask, void* ptr, const vfloat8& v) { _mm256_maskstore_ps((float*)ptr,(__m256i)mask,v); }
static __forceinline void store ( const vboolf8& mask, void* ptr, const vfloat8& v) { _mm256_maskstore_ps((float*)ptr,(__m256i)mask,v); }
static __forceinline void storeu( const vboolf8& mask, void* ptr, const vfloat8& v) { _mm256_maskstore_ps((float*)ptr,(__m256i)mask,v); }
#endif
#if defined(__AVX2__)
@@ -132,65 +123,10 @@ namespace embree
_mm256_stream_ps((float*)ptr,v);
}
template<int scale = 4>
static __forceinline vfloat8 gather(const float* ptr, const vint8& index) {
#if defined(__AVX2__)
return _mm256_i32gather_ps(ptr, index ,scale);
#else
return vfloat8(
*(float*)(((char*)ptr)+scale*index[0]),
*(float*)(((char*)ptr)+scale*index[1]),
*(float*)(((char*)ptr)+scale*index[2]),
*(float*)(((char*)ptr)+scale*index[3]),
*(float*)(((char*)ptr)+scale*index[4]),
*(float*)(((char*)ptr)+scale*index[5]),
*(float*)(((char*)ptr)+scale*index[6]),
*(float*)(((char*)ptr)+scale*index[7]));
#endif
}
template<int scale = 4>
static __forceinline vfloat8 gather(const vboolf8& mask, const float* ptr, const vint8& index) {
vfloat8 r = zero;
#if defined(__AVX512VL__)
return _mm256_mmask_i32gather_ps(r, mask, index, ptr, scale);
#elif defined(__AVX2__)
return _mm256_mask_i32gather_ps(r, ptr, index, mask, scale);
#else
if (likely(mask[0])) r[0] = *(float*)(((char*)ptr)+scale*index[0]);
if (likely(mask[1])) r[1] = *(float*)(((char*)ptr)+scale*index[1]);
if (likely(mask[2])) r[2] = *(float*)(((char*)ptr)+scale*index[2]);
if (likely(mask[3])) r[3] = *(float*)(((char*)ptr)+scale*index[3]);
if (likely(mask[4])) r[4] = *(float*)(((char*)ptr)+scale*index[4]);
if (likely(mask[5])) r[5] = *(float*)(((char*)ptr)+scale*index[5]);
if (likely(mask[6])) r[6] = *(float*)(((char*)ptr)+scale*index[6]);
if (likely(mask[7])) r[7] = *(float*)(((char*)ptr)+scale*index[7]);
return r;
#endif
}
template<int scale = 4>
static __forceinline void scatter(void* ptr, const vint8& ofs, const vfloat8& v)
static __forceinline void store(const vboolf8& mask, void* ptr, const vint8& ofs, const vfloat8& v, const int scale = 1)
{
#if defined(__AVX512VL__)
_mm256_i32scatter_ps((float*)ptr,ofs,v,scale);
#else
*(float*)(((char*)ptr)+scale*ofs[0]) = v[0];
*(float*)(((char*)ptr)+scale*ofs[1]) = v[1];
*(float*)(((char*)ptr)+scale*ofs[2]) = v[2];
*(float*)(((char*)ptr)+scale*ofs[3]) = v[3];
*(float*)(((char*)ptr)+scale*ofs[4]) = v[4];
*(float*)(((char*)ptr)+scale*ofs[5]) = v[5];
*(float*)(((char*)ptr)+scale*ofs[6]) = v[6];
*(float*)(((char*)ptr)+scale*ofs[7]) = v[7];
#endif
}
template<int scale = 4>
static __forceinline void scatter(const vboolf8& mask, void* ptr, const vint8& ofs, const vfloat8& v)
{
#if defined(__AVX512VL__)
_mm256_mask_i32scatter_ps((float*)ptr,mask,ofs,v,scale);
_mm256_mask_i32scatter_ps(ptr,mask,ofs,v,scale);
#else
if (likely(mask[0])) *(float*)(((char*)ptr)+scale*ofs[0]) = v[0];
if (likely(mask[1])) *(float*)(((char*)ptr)+scale*ofs[1]) = v[1];
@@ -204,18 +140,18 @@ namespace embree
}
static __forceinline void store(const vboolf8& mask, char* ptr, const vint8& ofs, const vfloat8& v) {
scatter<1>(mask,ptr,ofs,v);
store(mask,ptr,ofs,v,1);
}
static __forceinline void store(const vboolf8& mask, float* ptr, const vint8& ofs, const vfloat8& v) {
scatter<4>(mask,ptr,ofs,v);
store(mask,ptr,ofs,v,4);
}
////////////////////////////////////////////////////////////////////////////////
/// Array Access
////////////////////////////////////////////////////////////////////////////////
__forceinline const float& operator [](size_t index) const { assert(index < 8); return f[index]; }
__forceinline float& operator [](size_t index) { assert(index < 8); return f[index]; }
__forceinline const float& operator []( const size_t index ) const { assert(index < 8); return f[index]; }
__forceinline float& operator []( const size_t index ) { assert(index < 8); return f[index]; }
};
@@ -223,129 +159,104 @@ namespace embree
/// Unary Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline vfloat8 asFloat(const vint8& a) { return _mm256_castsi256_ps(a); }
__forceinline vint8 asInt (const vfloat8& a) { return _mm256_castps_si256(a); }
__forceinline vfloat8 operator +(const vfloat8& a) { return a; }
__forceinline vfloat8 operator -(const vfloat8& a) {
__forceinline const vfloat8 asFloat ( const vint8& a ) { return _mm256_castsi256_ps(a); }
__forceinline const vint8 asInt ( const vfloat8& a ) { return _mm256_castps_si256(a); }
__forceinline const vfloat8 operator +( const vfloat8& a ) { return a; }
__forceinline const vfloat8 operator -( const vfloat8& a ) {
const __m256 mask = _mm256_castsi256_ps(_mm256_set1_epi32(0x80000000));
return _mm256_xor_ps(a, mask);
return _mm256_xor_ps(a.v, mask);
}
__forceinline vfloat8 abs(const vfloat8& a) {
__forceinline const vfloat8 abs ( const vfloat8& a ) {
const __m256 mask = _mm256_castsi256_ps(_mm256_set1_epi32(0x7fffffff));
return _mm256_and_ps(a, mask);
return _mm256_and_ps(a.v, mask);
}
__forceinline vfloat8 sign (const vfloat8& a) { return _mm256_blendv_ps(vfloat8(one), -vfloat8(one), _mm256_cmp_ps(a, vfloat8(zero), _CMP_NGE_UQ)); }
__forceinline vfloat8 signmsk(const vfloat8& a) { return _mm256_and_ps(a,_mm256_castsi256_ps(_mm256_set1_epi32(0x80000000))); }
__forceinline const vfloat8 sign ( const vfloat8& a ) { return _mm256_blendv_ps(vfloat8(one), -vfloat8(one), _mm256_cmp_ps(a, vfloat8(zero), _CMP_NGE_UQ )); }
__forceinline const vfloat8 signmsk ( const vfloat8& a ) { return _mm256_and_ps(a.v,_mm256_castsi256_ps(_mm256_set1_epi32(0x80000000))); }
__forceinline vfloat8 rcp(const vfloat8& a)
{
#if defined(__AVX512VL__)
const vfloat8 r = _mm256_rcp14_ps(a);
#else
const vfloat8 r = _mm256_rcp_ps(a);
#endif
__forceinline const vfloat8 rcp ( const vfloat8& a ) {
const vfloat8 r = _mm256_rcp_ps(a.v);
#if defined(__AVX2__)
return _mm256_mul_ps(r, _mm256_fnmadd_ps(r, a, vfloat8(2.0f)));
return _mm256_mul_ps(r,_mm256_fnmadd_ps(r, a, vfloat8(2.0f)));
#else
return _mm256_mul_ps(r, _mm256_sub_ps(vfloat8(2.0f), _mm256_mul_ps(r, a)));
return _mm256_mul_ps(r,_mm256_sub_ps(vfloat8(2.0f), _mm256_mul_ps(r, a)));
#endif
}
__forceinline vfloat8 sqr (const vfloat8& a) { return _mm256_mul_ps(a,a); }
__forceinline vfloat8 sqrt(const vfloat8& a) { return _mm256_sqrt_ps(a); }
__forceinline vfloat8 rsqrt(const vfloat8& a)
{
#if defined(__AVX512VL__)
const vfloat8 r = _mm256_rsqrt14_ps(a);
#else
const vfloat8 r = _mm256_rsqrt_ps(a);
#endif
#if defined(__AVX2__)
return _mm256_fmadd_ps(_mm256_set1_ps(1.5f), r,
_mm256_mul_ps(_mm256_mul_ps(_mm256_mul_ps(a, _mm256_set1_ps(-0.5f)), r), _mm256_mul_ps(r, r)));
#else
return _mm256_add_ps(_mm256_mul_ps(_mm256_set1_ps(1.5f), r),
_mm256_mul_ps(_mm256_mul_ps(_mm256_mul_ps(a, _mm256_set1_ps(-0.5f)), r), _mm256_mul_ps(r, r)));
#endif
__forceinline const vfloat8 sqr ( const vfloat8& a ) { return _mm256_mul_ps(a,a); }
__forceinline const vfloat8 sqrt ( const vfloat8& a ) { return _mm256_sqrt_ps(a.v); }
__forceinline const vfloat8 rsqrt( const vfloat8& a ) {
const vfloat8 r = _mm256_rsqrt_ps(a.v);
return _mm256_add_ps(_mm256_mul_ps(_mm256_set1_ps(1.5f), r), _mm256_mul_ps(_mm256_mul_ps(_mm256_mul_ps(a, _mm256_set1_ps(-0.5f)), r), _mm256_mul_ps(r, r)));
}
////////////////////////////////////////////////////////////////////////////////
/// Binary Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline vfloat8 operator +(const vfloat8& a, const vfloat8& b) { return _mm256_add_ps(a, b); }
__forceinline vfloat8 operator +(const vfloat8& a, float b) { return a + vfloat8(b); }
__forceinline vfloat8 operator +(float a, const vfloat8& b) { return vfloat8(a) + b; }
__forceinline const vfloat8 operator +( const vfloat8& a, const vfloat8& b ) { return _mm256_add_ps(a.v, b.v); }
__forceinline const vfloat8 operator +( const vfloat8& a, const float b ) { return a + vfloat8(b); }
__forceinline const vfloat8 operator +( const float a, const vfloat8& b ) { return vfloat8(a) + b; }
__forceinline vfloat8 operator -(const vfloat8& a, const vfloat8& b) { return _mm256_sub_ps(a, b); }
__forceinline vfloat8 operator -(const vfloat8& a, float b) { return a - vfloat8(b); }
__forceinline vfloat8 operator -(float a, const vfloat8& b) { return vfloat8(a) - b; }
__forceinline const vfloat8 operator -( const vfloat8& a, const vfloat8& b ) { return _mm256_sub_ps(a.v, b.v); }
__forceinline const vfloat8 operator -( const vfloat8& a, const float b ) { return a - vfloat8(b); }
__forceinline const vfloat8 operator -( const float a, const vfloat8& b ) { return vfloat8(a) - b; }
__forceinline vfloat8 operator *(const vfloat8& a, const vfloat8& b) { return _mm256_mul_ps(a, b); }
__forceinline vfloat8 operator *(const vfloat8& a, float b) { return a * vfloat8(b); }
__forceinline vfloat8 operator *(float a, const vfloat8& b) { return vfloat8(a) * b; }
__forceinline const vfloat8 operator *( const vfloat8& a, const vfloat8& b ) { return _mm256_mul_ps(a.v, b.v); }
__forceinline const vfloat8 operator *( const vfloat8& a, const float b ) { return a * vfloat8(b); }
__forceinline const vfloat8 operator *( const float a, const vfloat8& b ) { return vfloat8(a) * b; }
__forceinline vfloat8 operator /(const vfloat8& a, const vfloat8& b) { return _mm256_div_ps(a, b); }
__forceinline vfloat8 operator /(const vfloat8& a, float b) { return a / vfloat8(b); }
__forceinline vfloat8 operator /(float a, const vfloat8& b) { return vfloat8(a) / b; }
__forceinline const vfloat8 operator /( const vfloat8& a, const vfloat8& b ) { return _mm256_div_ps(a.v, b.v); }
__forceinline const vfloat8 operator /( const vfloat8& a, const float b ) { return a / vfloat8(b); }
__forceinline const vfloat8 operator /( const float a, const vfloat8& b ) { return vfloat8(a) / b; }
__forceinline vfloat8 operator ^(const vfloat8& a, const vfloat8& b) { return _mm256_xor_ps(a,b); }
__forceinline vfloat8 operator ^(const vfloat8& a, const vint8& b) { return _mm256_xor_ps(a,_mm256_castsi256_ps(b)); }
__forceinline const vfloat8 operator^( const vfloat8& a, const vfloat8& b ) { return _mm256_xor_ps(a.v,b.v); }
__forceinline const vfloat8 operator^( const vfloat8& a, const vint8& b ) { return _mm256_xor_ps(a.v,_mm256_castsi256_ps(b.v)); }
__forceinline vfloat8 operator &(const vfloat8& a, const vfloat8& b) { return _mm256_and_ps(a,b); }
__forceinline const vfloat8 operator&( const vfloat8& a, const vfloat8& b ) { return _mm256_and_ps(a.v,b.v); }
__forceinline vfloat8 min(const vfloat8& a, const vfloat8& b) { return _mm256_min_ps(a, b); }
__forceinline vfloat8 min(const vfloat8& a, float b) { return _mm256_min_ps(a, vfloat8(b)); }
__forceinline vfloat8 min(float a, const vfloat8& b) { return _mm256_min_ps(vfloat8(a), b); }
__forceinline const vfloat8 min( const vfloat8& a, const vfloat8& b ) { return _mm256_min_ps(a.v, b.v); }
__forceinline const vfloat8 min( const vfloat8& a, const float b ) { return _mm256_min_ps(a.v, vfloat8(b)); }
__forceinline const vfloat8 min( const float a, const vfloat8& b ) { return _mm256_min_ps(vfloat8(a), b.v); }
__forceinline vfloat8 max(const vfloat8& a, const vfloat8& b) { return _mm256_max_ps(a, b); }
__forceinline vfloat8 max(const vfloat8& a, float b) { return _mm256_max_ps(a, vfloat8(b)); }
__forceinline vfloat8 max(float a, const vfloat8& b) { return _mm256_max_ps(vfloat8(a), b); }
__forceinline const vfloat8 max( const vfloat8& a, const vfloat8& b ) { return _mm256_max_ps(a.v, b.v); }
__forceinline const vfloat8 max( const vfloat8& a, const float b ) { return _mm256_max_ps(a.v, vfloat8(b)); }
__forceinline const vfloat8 max( const float a, const vfloat8& b ) { return _mm256_max_ps(vfloat8(a), b.v); }
#if defined(__AVX2__)
#if defined (__AVX2__)
__forceinline vfloat8 mini(const vfloat8& a, const vfloat8& b) {
const vint8 ai = _mm256_castps_si256(a);
const vint8 bi = _mm256_castps_si256(b);
const vint8 ci = _mm256_min_epi32(ai,bi);
return _mm256_castsi256_ps(ci);
}
__forceinline vfloat8 mini(const vfloat8& a, const vfloat8& b) {
const vint8 ai = _mm256_castps_si256(a);
const vint8 bi = _mm256_castps_si256(b);
const vint8 ci = _mm256_min_epi32(ai,bi);
return _mm256_castsi256_ps(ci);
}
__forceinline vfloat8 maxi(const vfloat8& a, const vfloat8& b) {
const vint8 ai = _mm256_castps_si256(a);
const vint8 bi = _mm256_castps_si256(b);
const vint8 ci = _mm256_max_epi32(ai,bi);
return _mm256_castsi256_ps(ci);
}
__forceinline vfloat8 maxi(const vfloat8& a, const vfloat8& b) {
const vint8 ai = _mm256_castps_si256(a);
const vint8 bi = _mm256_castps_si256(b);
const vint8 ci = _mm256_max_epi32(ai,bi);
return _mm256_castsi256_ps(ci);
}
__forceinline vfloat8 minui(const vfloat8& a, const vfloat8& b) {
const vint8 ai = _mm256_castps_si256(a);
const vint8 bi = _mm256_castps_si256(b);
const vint8 ci = _mm256_min_epu32(ai,bi);
return _mm256_castsi256_ps(ci);
}
__forceinline vfloat8 maxui(const vfloat8& a, const vfloat8& b) {
const vint8 ai = _mm256_castps_si256(a);
const vint8 bi = _mm256_castps_si256(b);
const vint8 ci = _mm256_max_epu32(ai,bi);
return _mm256_castsi256_ps(ci);
}
__forceinline vfloat8 minui(const vfloat8& a, const vfloat8& b) {
const vint8 ai = _mm256_castps_si256(a);
const vint8 bi = _mm256_castps_si256(b);
const vint8 ci = _mm256_min_epu32(ai,bi);
return _mm256_castsi256_ps(ci);
}
__forceinline vfloat8 maxui(const vfloat8& a, const vfloat8& b) {
const vint8 ai = _mm256_castps_si256(a);
const vint8 bi = _mm256_castps_si256(b);
const vint8 ci = _mm256_max_epu32(ai,bi);
return _mm256_castsi256_ps(ci);
}
#else
__forceinline vfloat8 mini(const vfloat8& a, const vfloat8& b) {
return min(a,b);
}
__forceinline vfloat8 maxi(const vfloat8& a, const vfloat8& b) {
return max(a,b);
}
__forceinline vfloat8 mini(const vfloat8& a, const vfloat8& b) {
return min(a,b);
}
__forceinline vfloat8 maxi(const vfloat8& a, const vfloat8& b) {
return max(a,b);
}
#endif
////////////////////////////////////////////////////////////////////////////////
@@ -353,120 +264,107 @@ namespace embree
////////////////////////////////////////////////////////////////////////////////
#if defined(__AVX2__)
__forceinline vfloat8 madd (const vfloat8& a, const vfloat8& b, const vfloat8& c) { return _mm256_fmadd_ps(a,b,c); }
__forceinline vfloat8 msub (const vfloat8& a, const vfloat8& b, const vfloat8& c) { return _mm256_fmsub_ps(a,b,c); }
__forceinline vfloat8 nmadd (const vfloat8& a, const vfloat8& b, const vfloat8& c) { return _mm256_fnmadd_ps(a,b,c); }
__forceinline vfloat8 nmsub (const vfloat8& a, const vfloat8& b, const vfloat8& c) { return _mm256_fnmsub_ps(a,b,c); }
__forceinline const vfloat8 madd ( const vfloat8& a, const vfloat8& b, const vfloat8& c) { return _mm256_fmadd_ps(a,b,c); }
__forceinline const vfloat8 msub ( const vfloat8& a, const vfloat8& b, const vfloat8& c) { return _mm256_fmsub_ps(a,b,c); }
__forceinline const vfloat8 nmadd ( const vfloat8& a, const vfloat8& b, const vfloat8& c) { return _mm256_fnmadd_ps(a,b,c); }
__forceinline const vfloat8 nmsub ( const vfloat8& a, const vfloat8& b, const vfloat8& c) { return _mm256_fnmsub_ps(a,b,c); }
#else
__forceinline vfloat8 madd (const vfloat8& a, const vfloat8& b, const vfloat8& c) { return a*b+c; }
__forceinline vfloat8 msub (const vfloat8& a, const vfloat8& b, const vfloat8& c) { return a*b-c; }
__forceinline vfloat8 nmadd (const vfloat8& a, const vfloat8& b, const vfloat8& c) { return -a*b+c;}
__forceinline vfloat8 nmsub (const vfloat8& a, const vfloat8& b, const vfloat8& c) { return -a*b-c; }
__forceinline const vfloat8 madd ( const vfloat8& a, const vfloat8& b, const vfloat8& c) { return a*b+c; }
__forceinline const vfloat8 msub ( const vfloat8& a, const vfloat8& b, const vfloat8& c) { return a*b-c; }
__forceinline const vfloat8 nmadd ( const vfloat8& a, const vfloat8& b, const vfloat8& c) { return -a*b+c;}
__forceinline const vfloat8 nmsub ( const vfloat8& a, const vfloat8& b, const vfloat8& c) { return -a*b-c; }
#endif
////////////////////////////////////////////////////////////////////////////////
/// Assignment Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline vfloat8& operator +=(vfloat8& a, const vfloat8& b) { return a = a + b; }
__forceinline vfloat8& operator +=(vfloat8& a, float b) { return a = a + b; }
__forceinline vfloat8& operator +=( vfloat8& a, const vfloat8& b ) { return a = a + b; }
__forceinline vfloat8& operator +=( vfloat8& a, const float b ) { return a = a + b; }
__forceinline vfloat8& operator -=(vfloat8& a, const vfloat8& b) { return a = a - b; }
__forceinline vfloat8& operator -=(vfloat8& a, float b) { return a = a - b; }
__forceinline vfloat8& operator -=( vfloat8& a, const vfloat8& b ) { return a = a - b; }
__forceinline vfloat8& operator -=( vfloat8& a, const float b ) { return a = a - b; }
__forceinline vfloat8& operator *=(vfloat8& a, const vfloat8& b) { return a = a * b; }
__forceinline vfloat8& operator *=(vfloat8& a, float b) { return a = a * b; }
__forceinline vfloat8& operator *=( vfloat8& a, const vfloat8& b ) { return a = a * b; }
__forceinline vfloat8& operator *=( vfloat8& a, const float b ) { return a = a * b; }
__forceinline vfloat8& operator /=(vfloat8& a, const vfloat8& b) { return a = a / b; }
__forceinline vfloat8& operator /=(vfloat8& a, float b) { return a = a / b; }
__forceinline vfloat8& operator /=( vfloat8& a, const vfloat8& b ) { return a = a / b; }
__forceinline vfloat8& operator /=( vfloat8& a, const float b ) { return a = a / b; }
////////////////////////////////////////////////////////////////////////////////
/// Comparison Operators + Select
////////////////////////////////////////////////////////////////////////////////
#if defined(__AVX512VL__)
__forceinline vboolf8 operator ==(const vfloat8& a, const vfloat8& b) { return _mm256_cmp_ps_mask(a, b, _MM_CMPINT_EQ); }
__forceinline vboolf8 operator !=(const vfloat8& a, const vfloat8& b) { return _mm256_cmp_ps_mask(a, b, _MM_CMPINT_NE); }
__forceinline vboolf8 operator < (const vfloat8& a, const vfloat8& b) { return _mm256_cmp_ps_mask(a, b, _MM_CMPINT_LT); }
__forceinline vboolf8 operator >=(const vfloat8& a, const vfloat8& b) { return _mm256_cmp_ps_mask(a, b, _MM_CMPINT_GE); }
__forceinline vboolf8 operator > (const vfloat8& a, const vfloat8& b) { return _mm256_cmp_ps_mask(a, b, _MM_CMPINT_GT); }
__forceinline vboolf8 operator <=(const vfloat8& a, const vfloat8& b) { return _mm256_cmp_ps_mask(a, b, _MM_CMPINT_LE); }
__forceinline const vboolf8 operator ==( const vfloat8& a, const vfloat8& b ) { return _mm256_cmp_ps_mask(a.v, b.v, _CMP_EQ_OQ ); }
__forceinline const vboolf8 operator !=( const vfloat8& a, const vfloat8& b ) { return _mm256_cmp_ps_mask(a.v, b.v, _CMP_NEQ_OQ); }
__forceinline const vboolf8 operator < ( const vfloat8& a, const vfloat8& b ) { return _mm256_cmp_ps_mask(a.v, b.v, _CMP_LT_OQ ); }
__forceinline const vboolf8 operator >=( const vfloat8& a, const vfloat8& b ) { return _mm256_cmp_ps_mask(a.v, b.v, _CMP_GE_OQ ); }
__forceinline const vboolf8 operator > ( const vfloat8& a, const vfloat8& b ) { return _mm256_cmp_ps_mask(a.v, b.v, _CMP_GT_OQ ); }
__forceinline const vboolf8 operator <=( const vfloat8& a, const vfloat8& b ) { return _mm256_cmp_ps_mask(a.v, b.v, _CMP_LE_OQ ); }
__forceinline vfloat8 select(const vboolf8& m, const vfloat8& t, const vfloat8& f) {
__forceinline const vfloat8 select( const vboolf8& m, const vfloat8& t, const vfloat8& f ) {
return _mm256_mask_blend_ps(m, f, t);
}
#else
__forceinline vboolf8 operator ==(const vfloat8& a, const vfloat8& b) { return _mm256_cmp_ps(a, b, _CMP_EQ_OQ); }
__forceinline vboolf8 operator !=(const vfloat8& a, const vfloat8& b) { return _mm256_cmp_ps(a, b, _CMP_NEQ_OQ); }
__forceinline vboolf8 operator < (const vfloat8& a, const vfloat8& b) { return _mm256_cmp_ps(a, b, _CMP_LT_OQ); }
__forceinline vboolf8 operator >=(const vfloat8& a, const vfloat8& b) { return _mm256_cmp_ps(a, b, _CMP_GE_OQ); }
__forceinline vboolf8 operator > (const vfloat8& a, const vfloat8& b) { return _mm256_cmp_ps(a, b, _CMP_GT_OQ); }
__forceinline vboolf8 operator <=(const vfloat8& a, const vfloat8& b) { return _mm256_cmp_ps(a, b, _CMP_LE_OQ); }
__forceinline const vboolf8 operator ==( const vfloat8& a, const vfloat8& b ) { return _mm256_cmp_ps(a.v, b.v, _CMP_EQ_OQ ); }
__forceinline const vboolf8 operator !=( const vfloat8& a, const vfloat8& b ) { return _mm256_cmp_ps(a.v, b.v, _CMP_NEQ_OQ); }
__forceinline const vboolf8 operator < ( const vfloat8& a, const vfloat8& b ) { return _mm256_cmp_ps(a.v, b.v, _CMP_LT_OQ ); }
__forceinline const vboolf8 operator >=( const vfloat8& a, const vfloat8& b ) { return _mm256_cmp_ps(a.v, b.v, _CMP_GE_OQ ); }
__forceinline const vboolf8 operator > ( const vfloat8& a, const vfloat8& b ) { return _mm256_cmp_ps(a.v, b.v, _CMP_GT_OQ ); }
__forceinline const vboolf8 operator <=( const vfloat8& a, const vfloat8& b ) { return _mm256_cmp_ps(a.v, b.v, _CMP_LE_OQ ); }
__forceinline vfloat8 select(const vboolf8& m, const vfloat8& t, const vfloat8& f) {
__forceinline const vfloat8 select( const vboolf8& m, const vfloat8& t, const vfloat8& f ) {
return _mm256_blendv_ps(f, t, m);
}
#endif
template<int mask>
__forceinline vfloat8 select(const vfloat8& t, const vfloat8& f) {
return _mm256_blend_ps(f, t, mask);
#if defined(__clang__) && !defined(__INTEL_COMPILER) || defined(_MSC_VER) && !defined(__INTEL_COMPILER)
__forceinline const vfloat8 select(const int m, const vfloat8& t, const vfloat8& f) {
return select(vboolf8(m), t, f); // workaround for clang and Microsoft compiler bugs
}
__forceinline vboolf8 operator ==(const vfloat8& a, const float& b) { return a == vfloat8(b); }
__forceinline vboolf8 operator ==(const float& a, const vfloat8& b) { return vfloat8(a) == b; }
__forceinline vboolf8 operator !=(const vfloat8& a, const float& b) { return a != vfloat8(b); }
__forceinline vboolf8 operator !=(const float& a, const vfloat8& b) { return vfloat8(a) != b; }
__forceinline vboolf8 operator < (const vfloat8& a, const float& b) { return a < vfloat8(b); }
__forceinline vboolf8 operator < (const float& a, const vfloat8& b) { return vfloat8(a) < b; }
__forceinline vboolf8 operator >=(const vfloat8& a, const float& b) { return a >= vfloat8(b); }
__forceinline vboolf8 operator >=(const float& a, const vfloat8& b) { return vfloat8(a) >= b; }
__forceinline vboolf8 operator > (const vfloat8& a, const float& b) { return a > vfloat8(b); }
__forceinline vboolf8 operator > (const float& a, const vfloat8& b) { return vfloat8(a) > b; }
__forceinline vboolf8 operator <=(const vfloat8& a, const float& b) { return a <= vfloat8(b); }
__forceinline vboolf8 operator <=(const float& a, const vfloat8& b) { return vfloat8(a) <= b; }
__forceinline vboolf8 eq(const vfloat8& a, const vfloat8& b) { return a == b; }
__forceinline vboolf8 ne(const vfloat8& a, const vfloat8& b) { return a != b; }
__forceinline vboolf8 lt(const vfloat8& a, const vfloat8& b) { return a < b; }
__forceinline vboolf8 ge(const vfloat8& a, const vfloat8& b) { return a >= b; }
__forceinline vboolf8 gt(const vfloat8& a, const vfloat8& b) { return a > b; }
__forceinline vboolf8 le(const vfloat8& a, const vfloat8& b) { return a <= b; }
#if defined(__AVX512VL__)
__forceinline vboolf8 eq(const vboolf8& mask, const vfloat8& a, const vfloat8& b) { return _mm256_mask_cmp_ps_mask(mask, a, b, _MM_CMPINT_EQ); }
__forceinline vboolf8 ne(const vboolf8& mask, const vfloat8& a, const vfloat8& b) { return _mm256_mask_cmp_ps_mask(mask, a, b, _MM_CMPINT_NE); }
__forceinline vboolf8 lt(const vboolf8& mask, const vfloat8& a, const vfloat8& b) { return _mm256_mask_cmp_ps_mask(mask, a, b, _MM_CMPINT_LT); }
__forceinline vboolf8 ge(const vboolf8& mask, const vfloat8& a, const vfloat8& b) { return _mm256_mask_cmp_ps_mask(mask, a, b, _MM_CMPINT_GE); }
__forceinline vboolf8 gt(const vboolf8& mask, const vfloat8& a, const vfloat8& b) { return _mm256_mask_cmp_ps_mask(mask, a, b, _MM_CMPINT_GT); }
__forceinline vboolf8 le(const vboolf8& mask, const vfloat8& a, const vfloat8& b) { return _mm256_mask_cmp_ps_mask(mask, a, b, _MM_CMPINT_LE); }
#else
__forceinline vboolf8 eq(const vboolf8& mask, const vfloat8& a, const vfloat8& b) { return mask & (a == b); }
__forceinline vboolf8 ne(const vboolf8& mask, const vfloat8& a, const vfloat8& b) { return mask & (a != b); }
__forceinline vboolf8 lt(const vboolf8& mask, const vfloat8& a, const vfloat8& b) { return mask & (a < b); }
__forceinline vboolf8 ge(const vboolf8& mask, const vfloat8& a, const vfloat8& b) { return mask & (a >= b); }
__forceinline vboolf8 gt(const vboolf8& mask, const vfloat8& a, const vfloat8& b) { return mask & (a > b); }
__forceinline vboolf8 le(const vboolf8& mask, const vfloat8& a, const vfloat8& b) { return mask & (a <= b); }
__forceinline const vfloat8 select( const int m, const vfloat8& t, const vfloat8& f ) {
return _mm256_blend_ps(f, t, m);
}
#endif
__forceinline const vboolf8 operator ==( const vfloat8& a, const float& b ) { return a == vfloat8(b); }
__forceinline const vboolf8 operator ==( const float& a, const vfloat8& b ) { return vfloat8(a) == b; }
__forceinline const vboolf8 operator !=( const vfloat8& a, const float& b ) { return a != vfloat8(b); }
__forceinline const vboolf8 operator !=( const float& a, const vfloat8& b ) { return vfloat8(a) != b; }
__forceinline const vboolf8 operator < ( const vfloat8& a, const float& b ) { return a < vfloat8(b); }
__forceinline const vboolf8 operator < ( const float& a, const vfloat8& b ) { return vfloat8(a) < b; }
__forceinline const vboolf8 operator >=( const vfloat8& a, const float& b ) { return a >= vfloat8(b); }
__forceinline const vboolf8 operator >=( const float& a, const vfloat8& b ) { return vfloat8(a) >= b; }
__forceinline const vboolf8 operator > ( const vfloat8& a, const float& b ) { return a > vfloat8(b); }
__forceinline const vboolf8 operator > ( const float& a, const vfloat8& b ) { return vfloat8(a) > b; }
__forceinline const vboolf8 operator <=( const vfloat8& a, const float& b ) { return a <= vfloat8(b); }
__forceinline const vboolf8 operator <=( const float& a, const vfloat8& b ) { return vfloat8(a) <= b; }
__forceinline vfloat8 lerp(const vfloat8& a, const vfloat8& b, const vfloat8& t) {
return madd(t,b-a,a);
#if defined(__AVX2__)
return madd(t, b, madd(-t, a, a));
#else
return a + t*(b-a);
#endif
}
__forceinline bool isvalid (const vfloat8& v) {
__forceinline bool isvalid ( const vfloat8& v ) {
return all((v > vfloat8(-FLT_LARGE)) & (v < vfloat8(+FLT_LARGE)));
}
__forceinline bool is_finite (const vfloat8& a) {
__forceinline bool is_finite ( const vfloat8& a ) {
return all((a >= vfloat8(-FLT_MAX)) & (a <= vfloat8(+FLT_MAX)));
}
__forceinline bool is_finite (const vboolf8& valid, const vfloat8& a) {
__forceinline bool is_finite ( const vboolf8& valid, const vfloat8& a ) {
return all(valid, (a >= vfloat8(-FLT_MAX)) & (a <= vfloat8(+FLT_MAX)));
}
@@ -474,104 +372,92 @@ namespace embree
/// Rounding Functions
////////////////////////////////////////////////////////////////////////////////
__forceinline vfloat8 floor(const vfloat8& a) { return _mm256_round_ps(a, _MM_FROUND_TO_NEG_INF ); }
__forceinline vfloat8 ceil (const vfloat8& a) { return _mm256_round_ps(a, _MM_FROUND_TO_POS_INF ); }
__forceinline vfloat8 trunc(const vfloat8& a) { return _mm256_round_ps(a, _MM_FROUND_TO_ZERO ); }
__forceinline vfloat8 frac (const vfloat8& a) { return a-floor(a); }
__forceinline const vfloat8 floor( const vfloat8& a ) { return _mm256_round_ps(a, _MM_FROUND_TO_NEG_INF ); }
__forceinline const vfloat8 ceil ( const vfloat8& a ) { return _mm256_round_ps(a, _MM_FROUND_TO_POS_INF ); }
__forceinline const vfloat8 trunc( const vfloat8& a ) { return _mm256_round_ps(a, _MM_FROUND_TO_ZERO ); }
__forceinline const vfloat8 frac ( const vfloat8& a ) { return a-floor(a); }
////////////////////////////////////////////////////////////////////////////////
/// Movement/Shifting/Shuffling Functions
////////////////////////////////////////////////////////////////////////////////
__forceinline vfloat8 unpacklo(const vfloat8& a, const vfloat8& b) { return _mm256_unpacklo_ps(a, b); }
__forceinline vfloat8 unpackhi(const vfloat8& a, const vfloat8& b) { return _mm256_unpackhi_ps(a, b); }
__forceinline vfloat8 unpacklo( const vfloat8& a, const vfloat8& b ) { return _mm256_unpacklo_ps(a.v, b.v); }
__forceinline vfloat8 unpackhi( const vfloat8& a, const vfloat8& b ) { return _mm256_unpackhi_ps(a.v, b.v); }
template<int i>
__forceinline vfloat8 shuffle(const vfloat8& v) {
return _mm256_permute_ps(v, _MM_SHUFFLE(i, i, i, i));
template<size_t i> __forceinline const vfloat8 shuffle( const vfloat8& a ) {
return _mm256_permute_ps(a, _MM_SHUFFLE(i, i, i, i));
}
template<int i0, int i1>
__forceinline vfloat8 shuffle4(const vfloat8& v) {
return _mm256_permute2f128_ps(v, v, (i1 << 4) | (i0 << 0));
template<size_t i0, size_t i1> __forceinline const vfloat8 shuffle4( const vfloat8& a ) {
return _mm256_permute2f128_ps(a, a, (i1 << 4) | (i0 << 0));
}
template<int i0, int i1>
__forceinline vfloat8 shuffle4(const vfloat8& a, const vfloat8& b) {
template<size_t i0, size_t i1> __forceinline const vfloat8 shuffle4( const vfloat8& a, const vfloat8& b) {
return _mm256_permute2f128_ps(a, b, (i1 << 4) | (i0 << 0));
}
template<int i0, int i1, int i2, int i3>
__forceinline vfloat8 shuffle(const vfloat8& v) {
return _mm256_permute_ps(v, _MM_SHUFFLE(i3, i2, i1, i0));
template<size_t i0, size_t i1, size_t i2, size_t i3> __forceinline const vfloat8 shuffle( const vfloat8& a ) {
return _mm256_permute_ps(a, _MM_SHUFFLE(i3, i2, i1, i0));
}
template<int i0, int i1, int i2, int i3>
__forceinline vfloat8 shuffle(const vfloat8& a, const vfloat8& b) {
template<size_t i0, size_t i1, size_t i2, size_t i3> __forceinline const vfloat8 shuffle( const vfloat8& a, const vfloat8& b ) {
return _mm256_shuffle_ps(a, b, _MM_SHUFFLE(i3, i2, i1, i0));
}
template<> __forceinline vfloat8 shuffle<0, 0, 2, 2>(const vfloat8& v) { return _mm256_moveldup_ps(v); }
template<> __forceinline vfloat8 shuffle<1, 1, 3, 3>(const vfloat8& v) { return _mm256_movehdup_ps(v); }
template<> __forceinline vfloat8 shuffle<0, 1, 0, 1>(const vfloat8& v) { return _mm256_castpd_ps(_mm256_movedup_pd(_mm256_castps_pd(v))); }
template<> __forceinline const vfloat8 shuffle<0, 0, 2, 2>( const vfloat8& b ) { return _mm256_moveldup_ps(b); }
template<> __forceinline const vfloat8 shuffle<1, 1, 3, 3>( const vfloat8& b ) { return _mm256_movehdup_ps(b); }
template<> __forceinline const vfloat8 shuffle<0, 1, 0, 1>( const vfloat8& b ) { return _mm256_castpd_ps(_mm256_movedup_pd(_mm256_castps_pd(b))); }
__forceinline vfloat8 broadcast(const float* ptr) { return _mm256_broadcast_ss(ptr); }
template<size_t i> __forceinline vfloat8 insert4(const vfloat8& a, const vfloat4& b) { return _mm256_insertf128_ps(a, b, i); }
template<size_t i> __forceinline vfloat4 extract4 (const vfloat8& a) { return _mm256_extractf128_ps(a, i); }
template<> __forceinline vfloat4 extract4<0>(const vfloat8& a) { return _mm256_castps256_ps128(a); }
__forceinline const vfloat8 broadcast(const float* ptr) { return _mm256_broadcast_ss(ptr); }
template<size_t i> __forceinline const vfloat8 insert4(const vfloat8& a, const vfloat4& b) { return _mm256_insertf128_ps(a, b, i); }
template<size_t i> __forceinline const vfloat4 extract4 (const vfloat8& a) { return _mm256_extractf128_ps(a, i); }
template<> __forceinline const vfloat4 extract4<0>(const vfloat8& a) { return _mm256_castps256_ps128(a); }
__forceinline float toScalar(const vfloat8& v) { return _mm_cvtss_f32(_mm256_castps256_ps128(v)); }
__forceinline float toScalar(const vfloat8& a) { return _mm_cvtss_f32(_mm256_castps256_ps128(a)); }
__forceinline vfloat8 assign(const vfloat4& a) { return _mm256_castps128_ps256(a); }
__forceinline vfloat8 assign( const vfloat4& a ) { return _mm256_castps128_ps256(a); }
#if defined (__AVX2__)
__forceinline vfloat8 permute(const vfloat8& a, const __m256i& index) {
return _mm256_permutevar8x32_ps(a, index);
__forceinline vfloat8 permute(const vfloat8 &a, const __m256i &index) {
return _mm256_permutevar8x32_ps(a,index);
}
#endif
#if defined(__AVX512VL__)
template<int i>
__forceinline vfloat8 align_shift_right(const vfloat8& a, const vfloat8& b) {
return _mm256_castsi256_ps(_mm256_alignr_epi32(_mm256_castps_si256(a), _mm256_castps_si256(b), i));
__forceinline vfloat8 align_shift_right(const vfloat8 &a, const vfloat8 &b) {
return _mm256_castsi256_ps(_mm256_alignr_epi8(_mm256_castps_si256(a), _mm256_castps_si256(b), i));
}
#endif
#if defined (__AVX_I__)
template<const int mode>
__forceinline vint4 convert_to_hf16(const vfloat8& a) {
return _mm256_cvtps_ph(a, mode);
__forceinline vint4 convert_to_hf16(const vfloat8 &a) {
return _mm256_cvtps_ph(a,mode);
}
__forceinline vfloat8 convert_from_hf16(const vint4& a) {
__forceinline vfloat8 convert_from_hf16(const vint4 &a) {
return _mm256_cvtph_ps(a);
}
#endif
__forceinline vfloat4 broadcast4f(const vfloat8& a, const size_t k) {
__forceinline vfloat4 broadcast4f( const vfloat8& a, const size_t k ) {
return vfloat4::broadcast(&a[k]);
}
__forceinline vfloat8 broadcast8f(const vfloat8& a, const size_t k) {
__forceinline vfloat8 broadcast8f( const vfloat8& a, const size_t k ) {
return vfloat8::broadcast(&a[k]);
}
#if defined(__AVX512VL__)
__forceinline vfloat8 shift_right_1(const vfloat8& x) {
return align_shift_right<1>(zero,x);
__forceinline vfloat8 shift_right_1( const vfloat8& x)
{
__m256 t0 = _mm256_permute_ps(x,0x39);
__m256 t1 = _mm256_permute2f128_ps(t0,t0,0x81);
__m256 y = _mm256_blend_ps(t0,t1,0x88);
return y;
}
#else
__forceinline vfloat8 shift_right_1(const vfloat8& x) {
const vfloat8 t0 = shuffle<1,2,3,0>(x);
const vfloat8 t1 = shuffle4<1,0>(t0);
return _mm256_blend_ps(t0,t1,0x88);
}
#endif
__forceinline vint8 floori(const vfloat8& a) {
__forceinline vint8 floori (const vfloat8& a) {
return vint8(floor(a));
}
////////////////////////////////////////////////////////////////////////////////
/// Transpose
////////////////////////////////////////////////////////////////////////////////
@@ -614,12 +500,6 @@ namespace embree
c7 = shuffle4<1,3>(h3,h7);
}
__forceinline void transpose(const vfloat4& r0, const vfloat4& r1, const vfloat4& r2, const vfloat4& r3, const vfloat4& r4, const vfloat4& r5, const vfloat4& r6, const vfloat4& r7,
vfloat8& c0, vfloat8& c1, vfloat8& c2, vfloat8& c3)
{
transpose(vfloat8(r0,r4), vfloat8(r1,r5), vfloat8(r2,r6), vfloat8(r3,r7), c0, c1, c2, c3);
}
__forceinline void transpose(const vfloat4& r0, const vfloat4& r1, const vfloat4& r2, const vfloat4& r3, const vfloat4& r4, const vfloat4& r5, const vfloat4& r6, const vfloat4& r7,
vfloat8& c0, vfloat8& c1, vfloat8& c2)
{
@@ -630,17 +510,17 @@ namespace embree
/// Reductions
////////////////////////////////////////////////////////////////////////////////
__forceinline vfloat8 vreduce_min2(const vfloat8& v) { return min(v,shuffle<1,0,3,2>(v)); }
__forceinline vfloat8 vreduce_min4(const vfloat8& v) { vfloat8 v1 = vreduce_min2(v); return min(v1,shuffle<2,3,0,1>(v1)); }
__forceinline vfloat8 vreduce_min (const vfloat8& v) { vfloat8 v1 = vreduce_min4(v); return min(v1,shuffle4<1,0>(v1)); }
__forceinline const vfloat8 vreduce_min2(const vfloat8& v) { return min(v,shuffle<1,0,3,2>(v)); }
__forceinline const vfloat8 vreduce_min4(const vfloat8& v) { vfloat8 v1 = vreduce_min2(v); return min(v1,shuffle<2,3,0,1>(v1)); }
__forceinline const vfloat8 vreduce_min (const vfloat8& v) { vfloat8 v1 = vreduce_min4(v); return min(v1,shuffle4<1,0>(v1)); }
__forceinline vfloat8 vreduce_max2(const vfloat8& v) { return max(v,shuffle<1,0,3,2>(v)); }
__forceinline vfloat8 vreduce_max4(const vfloat8& v) { vfloat8 v1 = vreduce_max2(v); return max(v1,shuffle<2,3,0,1>(v1)); }
__forceinline vfloat8 vreduce_max (const vfloat8& v) { vfloat8 v1 = vreduce_max4(v); return max(v1,shuffle4<1,0>(v1)); }
__forceinline const vfloat8 vreduce_max2(const vfloat8& v) { return max(v,shuffle<1,0,3,2>(v)); }
__forceinline const vfloat8 vreduce_max4(const vfloat8& v) { vfloat8 v1 = vreduce_max2(v); return max(v1,shuffle<2,3,0,1>(v1)); }
__forceinline const vfloat8 vreduce_max (const vfloat8& v) { vfloat8 v1 = vreduce_max4(v); return max(v1,shuffle4<1,0>(v1)); }
__forceinline vfloat8 vreduce_add2(const vfloat8& v) { return v + shuffle<1,0,3,2>(v); }
__forceinline vfloat8 vreduce_add4(const vfloat8& v) { vfloat8 v1 = vreduce_add2(v); return v1 + shuffle<2,3,0,1>(v1); }
__forceinline vfloat8 vreduce_add (const vfloat8& v) { vfloat8 v1 = vreduce_add4(v); return v1 + shuffle4<1,0>(v1); }
__forceinline const vfloat8 vreduce_add2(const vfloat8& v) { return v + shuffle<1,0,3,2>(v); }
__forceinline const vfloat8 vreduce_add4(const vfloat8& v) { vfloat8 v1 = vreduce_add2(v); return v1 + shuffle<2,3,0,1>(v1); }
__forceinline const vfloat8 vreduce_add (const vfloat8& v) { vfloat8 v1 = vreduce_add4(v); return v1 + shuffle4<1,0>(v1); }
__forceinline float reduce_min(const vfloat8& v) { return toScalar(vreduce_min(v)); }
__forceinline float reduce_max(const vfloat8& v) { return toScalar(vreduce_max(v)); }
@@ -665,15 +545,15 @@ namespace embree
/// Euclidian Space Operators (pairs of Vec3fa's)
////////////////////////////////////////////////////////////////////////////////
//__forceinline vfloat8 dot(const vfloat8& a, const vfloat8& b) {
//__forceinline vfloat8 dot ( const vfloat8& a, const vfloat8& b ) {
// return vreduce_add4(a*b);
//}
__forceinline vfloat8 dot(const vfloat8& a, const vfloat8& b) {
__forceinline vfloat8 dot ( const vfloat8& a, const vfloat8& b ) {
return _mm256_dp_ps(a,b,0x7F);
}
__forceinline vfloat8 cross(const vfloat8& a, const vfloat8& b)
__forceinline vfloat8 cross ( const vfloat8& a, const vfloat8& b )
{
const vfloat8 a0 = a;
const vfloat8 b0 = shuffle<1,2,0,3>(b);
@@ -682,17 +562,17 @@ namespace embree
return shuffle<1,2,0,3>(msub(a0,b0,a1*b1));
}
//__forceinline float sqr_length (const vfloat<8>& a) { return dot(a,a); }
//__forceinline float rcp_length (const vfloat<8>& a) { return rsqrt(dot(a,a)); }
//__forceinline float rcp_length2(const vfloat<8>& a) { return rcp(dot(a,a)); }
//__forceinline float length (const vfloat<8>& a) { return sqrt(dot(a,a)); }
__forceinline vfloat<8> normalize(const vfloat<8>& a) { return a*rsqrt(dot(a,a)); }
//__forceinline float distance(const vfloat<8>& a, const vfloat<8>& b) { return length(a-b); }
//__forceinline float halfArea(const vfloat<8>& d) { return madd(d.x,(d.y+d.z),d.y*d.z); }
//__forceinline float area (const vfloat<8>& d) { return 2.0f*halfArea(d); }
//__forceinline vfloat<8> reflect(const vfloat<8>& V, const vfloat<8>& N) { return 2.0f*dot(V,N)*N-V; }
//__forceinline float sqr_length ( const vfloat<8>& a ) { return dot(a,a); }
//__forceinline float rcp_length ( const vfloat<8>& a ) { return rsqrt(dot(a,a)); }
//__forceinline float rcp_length2( const vfloat<8>& a ) { return rcp(dot(a,a)); }
//__forceinline float length ( const vfloat<8>& a ) { return sqrt(dot(a,a)); }
__forceinline vfloat<8> normalize( const vfloat<8>& a ) { return a*rsqrt(dot(a,a)); }
//__forceinline float distance ( const vfloat<8>& a, const vfloat<8>& b ) { return length(a-b); }
//__forceinline float halfArea ( const vfloat<8>& d ) { return d.x*(d.y+d.z)+d.y*d.z; }
//__forceinline float area ( const vfloat<8>& d ) { return 2.0f*halfArea(d); }
//__forceinline vfloat<8> reflect ( const vfloat<8>& V, const vfloat<8>& N ) { return 2.0f*dot(V,N)*N-V; }
//__forceinline vfloat<8> normalize_safe(const vfloat<8>& a) {
//__forceinline vfloat<8> normalize_safe( const vfloat<8>& a ) {
// const float d = dot(a,a); if (unlikely(d == 0.0f)) return a; else return a*rsqrt(d);
//}
@@ -700,63 +580,33 @@ namespace embree
/// In Register Sorting
////////////////////////////////////////////////////////////////////////////////
__forceinline vfloat8 sort_ascending(const vfloat8& v)
__forceinline vfloat8 sortNetwork(const vfloat8& v)
{
const vfloat8 a0 = v;
const vfloat8 b0 = shuffle<1,0,3,2>(a0);
const vfloat8 c0 = min(a0,b0);
const vfloat8 d0 = max(a0,b0);
const vfloat8 a1 = select<0x99 /* 0b10011001 */>(c0,d0);
const vfloat8 a1 = select(0x99 /* 0b10011001 */,c0,d0);
const vfloat8 b1 = shuffle<2,3,0,1>(a1);
const vfloat8 c1 = min(a1,b1);
const vfloat8 d1 = max(a1,b1);
const vfloat8 a2 = select<0xc3 /* 0b11000011 */>(c1,d1);
const vfloat8 a2 = select(0xc3 /* 0b11000011 */,c1,d1);
const vfloat8 b2 = shuffle<1,0,3,2>(a2);
const vfloat8 c2 = min(a2,b2);
const vfloat8 d2 = max(a2,b2);
const vfloat8 a3 = select<0xa5 /* 0b10100101 */>(c2,d2);
const vfloat8 a3 = select(0xa5 /* 0b10100101 */,c2,d2);
const vfloat8 b3 = shuffle4<1,0>(a3);
const vfloat8 c3 = min(a3,b3);
const vfloat8 d3 = max(a3,b3);
const vfloat8 a4 = select<0xf /* 0b00001111 */>(c3,d3);
const vfloat8 a4 = select(0xf /* 0b00001111 */,c3,d3);
const vfloat8 b4 = shuffle<2,3,0,1>(a4);
const vfloat8 c4 = min(a4,b4);
const vfloat8 d4 = max(a4,b4);
const vfloat8 a5 = select<0x33 /* 0b00110011 */>(c4,d4);
const vfloat8 a5 = select(0x33 /* 0b00110011 */,c4,d4);
const vfloat8 b5 = shuffle<1,0,3,2>(a5);
const vfloat8 c5 = min(a5,b5);
const vfloat8 d5 = max(a5,b5);
const vfloat8 a6 = select<0x55 /* 0b01010101 */>(c5,d5);
return a6;
}
__forceinline vfloat8 sort_descending(const vfloat8& v)
{
const vfloat8 a0 = v;
const vfloat8 b0 = shuffle<1,0,3,2>(a0);
const vfloat8 c0 = max(a0,b0);
const vfloat8 d0 = min(a0,b0);
const vfloat8 a1 = select<0x99 /* 0b10011001 */>(c0,d0);
const vfloat8 b1 = shuffle<2,3,0,1>(a1);
const vfloat8 c1 = max(a1,b1);
const vfloat8 d1 = min(a1,b1);
const vfloat8 a2 = select<0xc3 /* 0b11000011 */>(c1,d1);
const vfloat8 b2 = shuffle<1,0,3,2>(a2);
const vfloat8 c2 = max(a2,b2);
const vfloat8 d2 = min(a2,b2);
const vfloat8 a3 = select<0xa5 /* 0b10100101 */>(c2,d2);
const vfloat8 b3 = shuffle4<1,0>(a3);
const vfloat8 c3 = max(a3,b3);
const vfloat8 d3 = min(a3,b3);
const vfloat8 a4 = select<0xf /* 0b00001111 */>(c3,d3);
const vfloat8 b4 = shuffle<2,3,0,1>(a4);
const vfloat8 c4 = max(a4,b4);
const vfloat8 d4 = min(a4,b4);
const vfloat8 a5 = select<0x33 /* 0b00110011 */>(c4,d4);
const vfloat8 b5 = shuffle<1,0,3,2>(a5);
const vfloat8 c5 = max(a5,b5);
const vfloat8 d5 = min(a5,b5);
const vfloat8 a6 = select<0x55 /* 0b01010101 */>(c5,d5);
const vfloat8 a6 = select(0x55 /* 0b01010101 */,c5,d5);
return a6;
}
@@ -764,7 +614,7 @@ namespace embree
/// Output Operators
////////////////////////////////////////////////////////////////////////////////
inline std::ostream& operator <<(std::ostream& cout, const vfloat8& a) {
inline std::ostream& operator<<(std::ostream& cout, const vfloat8& a) {
return cout << "<" << a[0] << ", " << a[1] << ", " << a[2] << ", " << a[3] << ", " << a[4] << ", " << a[5] << ", " << a[6] << ", " << a[7] << ">";
}
}
+305 -234
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
@@ -38,47 +38,35 @@ namespace embree
__forceinline vint() {}
__forceinline vint(const vint16& t) { v = t.v; }
__forceinline vint16& operator =(const vint16& f) { v = f.v; return *this; }
__forceinline vint16& operator=(const vint16& f) { v = f.v; return *this; }
__forceinline vint(const __m512i& t) { v = t; }
__forceinline operator __m512i() const { return v; }
__forceinline operator __m256i() const { return _mm512_castsi512_si256(v); }
__forceinline operator __m512i () const { return v; }
__forceinline operator __m256i () const { return _mm512_castsi512_si256(v); }
__forceinline vint(int i) {
v = _mm512_set1_epi32(i);
__forceinline vint(const int i) {
v = _mm512_set_1to16_epi32(i);
}
__forceinline vint(int a, int b, int c, int d) {
v = _mm512_set4_epi32(d,c,b,a);
__forceinline vint(const int a, const int b, const int c, const int d) {
v = _mm512_set_4to16_epi32(d,c,b,a);
}
__forceinline vint(int a0 , int a1 , int a2 , int a3,
int a4 , int a5 , int a6 , int a7,
int a8 , int a9 , int a10, int a11,
int a12, int a13, int a14, int a15)
__forceinline vint(const int a0 , const int a1 , const int a2 , const int a3,
const int a4 , const int a5 , const int a6 , const int a7,
const int a8 , const int a9 , const int a10, const int a11,
const int a12, const int a13, const int a14, const int a15)
{
v = _mm512_set_epi32(a15,a14,a13,a12,a11,a10,a9,a8,a7,a6,a5,a4,a3,a2,a1,a0);
v = _mm512_set_16to16_epi32(a15,a14,a13,a12,a11,a10,a9,a8,a7,a6,a5,a4,a3,a2,a1,a0);
}
__forceinline vint(const vint4& i) {
v = _mm512_broadcast_i32x4(i);
}
__forceinline vint(const vint4& a, const vint4& b, const vint4& c, const vint4& d) {
v = _mm512_castsi128_si512(a);
v = _mm512_inserti32x4(v, b, 1);
v = _mm512_inserti32x4(v, c, 2);
v = _mm512_inserti32x4(v, d, 3);
}
__forceinline vint(const vint8& i) {
v = _mm512_castps_si512(_mm512_castpd_ps(_mm512_broadcast_f64x4(_mm256_castsi256_pd(i))));
}
__forceinline vint(const vint8& a, const vint8& b) {
v = _mm512_castsi256_si512(a);
v = _mm512_inserti64x4(v, b, 1);
}
__forceinline explicit vint(const __m512& f) {
v = _mm512_cvtps_epi32(f);
@@ -88,12 +76,17 @@ namespace embree
/// Constants
////////////////////////////////////////////////////////////////////////////////
__forceinline vint(ZeroTy) : v(_mm512_setzero_epi32()) {}
__forceinline vint(OneTy) : v(_mm512_set1_epi32(1)) {}
__forceinline vint(PosInfTy) : v(_mm512_set1_epi32(pos_inf)) {}
__forceinline vint(NegInfTy) : v(_mm512_set1_epi32(neg_inf)) {}
__forceinline vint(StepTy) : v(_mm512_set_epi32(15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0)) {}
__forceinline vint(ReverseStepTy) : v(_mm512_setr_epi32(15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0)) {}
__forceinline vint( ZeroTy ) : v(_mm512_setzero_epi32()) {}
__forceinline vint( OneTy ) : v(_mm512_set_1to16_epi32(1)) {}
__forceinline vint( PosInfTy ) : v(_mm512_set_1to16_epi32(pos_inf)) {}
__forceinline vint( NegInfTy ) : v(_mm512_set_1to16_epi32(neg_inf)) {}
__forceinline vint( StepTy ) : v(_mm512_set_16to16_epi32(15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0)) {}
__forceinline vint( ReverseStepTy ) : v(_mm512_setr_epi32(15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0)) {}
__forceinline static vint16 zero() { return _mm512_setzero_epi32(); }
__forceinline static vint16 one () { return _mm512_set_1to16_epi32(1); }
__forceinline static vint16 neg_one () { return _mm512_set_1to16_epi32(-1); }
////////////////////////////////////////////////////////////////////////////////
/// Loads and Stores
@@ -101,8 +94,7 @@ namespace embree
static __forceinline vint16 load (const void* addr) { return _mm512_load_si512((int*)addr); }
static __forceinline vint16 load(const unsigned char* ptr) { return _mm512_cvtepu8_epi32(_mm_load_si128((__m128i*)ptr)); }
static __forceinline vint16 load(const unsigned short* ptr) { return _mm512_cvtepu16_epi32(*(__m256i*)ptr); }
static __forceinline const vint16 load( const unsigned char* const ptr ) { return _mm512_cvtepu8_epi32(_mm_load_si128((__m128i*)ptr)); }
static __forceinline vint16 loadu(const void* addr) { return _mm512_loadu_si512(addr); }
@@ -113,20 +105,21 @@ namespace embree
static __forceinline void storeu(void* ptr, const vint16& v) { _mm512_storeu_si512(ptr,v); }
static __forceinline void store (const vboolf16& mask, void* addr, const vint16& v2) { _mm512_mask_store_epi32(addr,mask,v2); }
static __forceinline void storeu(const vboolf16& mask, void* ptr, const vint16& f) { _mm512_mask_storeu_epi32((int*)ptr,mask,f); }
static __forceinline void storeu(const vboolf16& mask, void* ptr, const vint16& f ) { _mm512_mask_storeu_epi32((int*)ptr,mask,f); }
static __forceinline void store_nt(void* __restrict__ ptr, const vint16& a) { _mm512_stream_si512((__m512i*)ptr,a); }
static __forceinline void store_nt(void *__restrict__ ptr, const vint16& a) { _mm512_stream_si512(ptr,a); }
/* pass by value to avoid compiler generating inefficient code */
static __forceinline void storeu_compact(const vboolf16 mask, void* addr, vint16 reg) {
static __forceinline void storeu_compact(const vboolf16 mask,void * addr, const vint16 reg) {
_mm512_mask_compressstoreu_epi32(addr,mask,reg);
}
static __forceinline void storeu_compact_single(const vboolf16 mask, void* addr, vint16 reg) {
static __forceinline void storeu_compact_single(const vboolf16 mask,void * addr, const vint16 reg) {
//_mm512_mask_compressstoreu_epi32(addr,mask,reg);
*(float*)addr = mm512_cvtss_f32(_mm512_mask_compress_ps(_mm512_castsi512_ps(reg),mask,_mm512_castsi512_ps(reg)));
*(float*)addr = _mm512_cvtss_f32(_mm512_mask_compress_ps(_mm512_castsi512_ps(reg),mask,_mm512_castsi512_ps(reg)));
}
static __forceinline vint16 compact64bit(const vboolf16& mask, vint16 &v) {
return _mm512_mask_compress_epi64(v,mask,v);
}
@@ -139,184 +132,175 @@ namespace embree
return _mm512_mask_compress_epi32(a,mask,b);
}
static __forceinline vint16 expand(const vboolf16& mask, const vint16& a, vint16& b) {
return _mm512_mask_expand_epi32(b,mask,a);
}
template<int scale = 4>
static __forceinline vint16 gather(const int* ptr, const vint16& index) {
return _mm512_i32gather_epi32(index,ptr,scale);
}
template<int scale = 4>
static __forceinline vint16 gather(const vboolf16& mask, const int* ptr, const vint16& index) {
return _mm512_mask_i32gather_epi32(_mm512_undefined_epi32(),mask,index,ptr,scale);
}
template<int scale = 4>
static __forceinline vint16 gather(const vboolf16& mask, vint16& dest, const int* ptr, const vint16& index) {
return _mm512_mask_i32gather_epi32(dest,mask,index,ptr,scale);
}
template<int scale = 4>
static __forceinline void scatter(int* ptr, const vint16& index, const vint16& v) {
_mm512_i32scatter_epi32((int*)ptr,index,v,scale);
}
template<int scale = 4>
static __forceinline void scatter(const vboolf16& mask, int* ptr, const vint16& index, const vint16& v) {
_mm512_mask_i32scatter_epi32((int*)ptr,mask,index,v,scale);
}
static __forceinline vint16 broadcast64bit(size_t v) {
return _mm512_set1_epi64(v);
}
static __forceinline size_t extracti64bit(const vint16& v) {
return _mm_cvtsi128_si64(_mm512_castsi512_si128(v));
}
static __forceinline vint4 extracti128bit(const vint16& v) {
return _mm512_castsi512_si128(v);
}
static __forceinline vint8 extracti256bit(const vint16& v) {
return _mm512_castsi512_si256(v);
}
////////////////////////////////////////////////////////////////////////////////
/// Array Access
////////////////////////////////////////////////////////////////////////////////
__forceinline int& operator [](size_t index) { assert(index < 16); return i[index]; }
__forceinline const int& operator [](size_t index) const { assert(index < 16); return i[index]; }
__forceinline int& operator[](const size_t index) { assert(index < 16); return i[index]; }
__forceinline const int& operator[](const size_t index) const { assert(index < 16); return i[index]; }
__forceinline unsigned int uint (size_t index) const { assert(index < 16); return ((unsigned int*)i)[index]; }
__forceinline size_t& uint64_t(size_t index) const { assert(index < 8); return ((size_t*)i)[index]; }
__forceinline unsigned int uint (const size_t index) const { assert(index < 16); return ((unsigned int*)i)[index]; }
__forceinline size_t& uint64_t(const size_t index) const { assert(index < 8); return ((size_t*)i)[index]; }
};
////////////////////////////////////////////////////////////////////////////////
/// Unary Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline vint16 asInt (const __m512& a) { return _mm512_castps_si512(a); }
__forceinline vint16 operator +(const vint16& a) { return a; }
__forceinline vint16 operator -(const vint16& a) { return _mm512_sub_epi32(_mm512_setzero_epi32(), a); }
__forceinline const vint16 asInt ( const __m512& a ) { return _mm512_castps_si512(a); }
__forceinline const vint16 operator +( const vint16& a ) { return a; }
__forceinline const vint16 operator -( const vint16& a ) { return _mm512_sub_epi32(_mm512_setzero_epi32(), a); }
////////////////////////////////////////////////////////////////////////////////
/// Binary Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline vint16 operator +(const vint16& a, const vint16& b) { return _mm512_add_epi32(a, b); }
__forceinline vint16 operator +(const vint16& a, int b) { return a + vint16(b); }
__forceinline vint16 operator +(int a, const vint16& b) { return vint16(a) + b; }
__forceinline const vint16 operator +( const vint16& a, const vint16& b ) { return _mm512_add_epi32(a, b); }
__forceinline const vint16 operator +( const vint16& a, const int b ) { return a + vint16(b); }
__forceinline const vint16 operator +( const int a, const vint16& b ) { return vint16(a) + b; }
__forceinline vint16 operator -(const vint16& a, const vint16& b) { return _mm512_sub_epi32(a, b); }
__forceinline vint16 operator -(const vint16& a, int b) { return a - vint16(b); }
__forceinline vint16 operator -(int a, const vint16& b) { return vint16(a) - b; }
__forceinline const vint16 operator -( const vint16& a, const vint16& b ) { return _mm512_sub_epi32(a, b); }
__forceinline const vint16 operator -( const vint16& a, const int b ) { return a - vint16(b); }
__forceinline const vint16 operator -( const int a, const vint16& b ) { return vint16(a) - b; }
__forceinline vint16 operator *(const vint16& a, const vint16& b) { return _mm512_mullo_epi32(a, b); }
__forceinline vint16 operator *(const vint16& a, int b) { return a * vint16(b); }
__forceinline vint16 operator *(int a, const vint16& b) { return vint16(a) * b; }
__forceinline const vint16 operator *( const vint16& a, const vint16& b ) { return _mm512_mullo_epi32(a, b); }
__forceinline const vint16 operator *( const vint16& a, const int b ) { return a * vint16(b); }
__forceinline const vint16 operator *( const int a, const vint16& b ) { return vint16(a) * b; }
__forceinline vint16 operator &(const vint16& a, const vint16& b) { return _mm512_and_epi32(a, b); }
__forceinline vint16 operator &(const vint16& a, int b) { return a & vint16(b); }
__forceinline vint16 operator &(int a, const vint16& b) { return vint16(a) & b; }
__forceinline const vint16 operator &( const vint16& a, const vint16& b ) { return _mm512_and_epi32(a, b); }
__forceinline const vint16 operator &( const vint16& a, const int b ) { return a & vint16(b); }
__forceinline const vint16 operator &( const int a, const vint16& b ) { return vint16(a) & b; }
__forceinline vint16 operator |(const vint16& a, const vint16& b) { return _mm512_or_epi32(a, b); }
__forceinline vint16 operator |(const vint16& a, int b) { return a | vint16(b); }
__forceinline vint16 operator |(int a, const vint16& b) { return vint16(a) | b; }
__forceinline const vint16 operator |( const vint16& a, const vint16& b ) { return _mm512_or_epi32(a, b); }
__forceinline const vint16 operator |( const vint16& a, const int b ) { return a | vint16(b); }
__forceinline const vint16 operator |( const int a, const vint16& b ) { return vint16(a) | b; }
__forceinline vint16 operator ^(const vint16& a, const vint16& b) { return _mm512_xor_epi32(a, b); }
__forceinline vint16 operator ^(const vint16& a, int b) { return a ^ vint16(b); }
__forceinline vint16 operator ^(int a, const vint16& b) { return vint16(a) ^ b; }
__forceinline const vint16 operator ^( const vint16& a, const vint16& b ) { return _mm512_xor_epi32(a, b); }
__forceinline const vint16 operator ^( const vint16& a, const int b ) { return a ^ vint16(b); }
__forceinline const vint16 operator ^( const int a, const vint16& b ) { return vint16(a) ^ b; }
__forceinline vint16 operator <<(const vint16& a, int n) { return _mm512_slli_epi32(a, n); }
__forceinline vint16 operator >>(const vint16& a, int n) { return _mm512_srai_epi32(a, n); }
__forceinline const vint16 operator <<( const vint16& a, const int n ) { return _mm512_slli_epi32(a, n); }
__forceinline const vint16 operator >>( const vint16& a, const int n ) { return _mm512_srai_epi32(a, n); }
__forceinline vint16 operator <<(const vint16& a, const vint16& n) { return _mm512_sllv_epi32(a, n); }
__forceinline vint16 operator >>(const vint16& a, const vint16& n) { return _mm512_srav_epi32(a, n); }
__forceinline const vint16 operator <<( const vint16& a, const vint16& n ) { return _mm512_sllv_epi32(a, n); }
__forceinline const vint16 operator >>( const vint16& a, const vint16& n ) { return _mm512_srav_epi32(a, n); }
__forceinline vint16 sll (const vint16& a, int b) { return _mm512_slli_epi32(a, b); }
__forceinline vint16 sra (const vint16& a, int b) { return _mm512_srai_epi32(a, b); }
__forceinline vint16 srl (const vint16& a, int b) { return _mm512_srli_epi32(a, b); }
__forceinline const vint16 sll ( const vint16& a, const int b ) { return _mm512_slli_epi32(a, b); }
__forceinline const vint16 sra ( const vint16& a, const int b ) { return _mm512_srai_epi32(a, b); }
__forceinline const vint16 srl ( const vint16& a, const int b ) { return _mm512_srli_epi32(a, b); }
__forceinline vint16 min(const vint16& a, const vint16& b) { return _mm512_min_epi32(a, b); }
__forceinline vint16 min(const vint16& a, int b) { return min(a,vint16(b)); }
__forceinline vint16 min(int a, const vint16& b) { return min(vint16(a),b); }
__forceinline const vint16 min( const vint16& a, const vint16& b ) { return _mm512_min_epi32(a, b); }
__forceinline const vint16 min( const vint16& a, const int b ) { return min(a,vint16(b)); }
__forceinline const vint16 min( const int a, const vint16& b ) { return min(vint16(a),b); }
__forceinline vint16 max(const vint16& a, const vint16& b) { return _mm512_max_epi32(a, b); }
__forceinline vint16 max(const vint16& a, int b) { return max(a,vint16(b)); }
__forceinline vint16 max(int a, const vint16& b) { return max(vint16(a),b); }
__forceinline const vint16 max( const vint16& a, const vint16& b ) { return _mm512_max_epi32(a, b); }
__forceinline const vint16 max( const vint16& a, const int b ) { return max(a,vint16(b)); }
__forceinline const vint16 max( const int a, const vint16& b ) { return max(vint16(a),b); }
__forceinline vint16 umin(const vint16& a, const vint16& b) { return _mm512_min_epu32(a, b); }
__forceinline vint16 umax(const vint16& a, const vint16& b) { return _mm512_max_epu32(a, b); }
__forceinline const vint16 umin( const vint16& a, const vint16& b ) { return _mm512_min_epu32(a.v, b.v); }
__forceinline const vint16 umax( const vint16& a, const vint16& b ) { return _mm512_max_epu32(a.v, b.v); }
__forceinline vint16 mask_add(const vboolf16& mask, vint16& c, const vint16& a, const vint16& b) { return _mm512_mask_add_epi32(c,mask,a,b); }
__forceinline vint16 mask_sub(const vboolf16& mask, vint16& c, const vint16& a, const vint16& b) { return _mm512_mask_sub_epi32(c,mask,a,b); }
__forceinline const vint16 mask_add(const vboolf16& mask, vint16& c, const vint16& a, const vint16& b) { return _mm512_mask_add_epi32(c,mask,a,b); }
__forceinline const vint16 mask_sub(const vboolf16& mask, vint16& c, const vint16& a, const vint16& b) { return _mm512_mask_sub_epi32(c,mask,a,b); }
__forceinline vint16 mask_and(const vboolf16& m, vint16& c, const vint16& a, const vint16& b) { return _mm512_mask_and_epi32(c,m,a,b); }
__forceinline vint16 mask_or (const vboolf16& m, vint16& c, const vint16& a, const vint16& b) { return _mm512_mask_or_epi32(c,m,a,b); }
__forceinline const vint16 mask_and(const vboolf16& m,vint16& c, const vint16& a, const vint16& b) { return _mm512_mask_and_epi32(c,m,a,b); }
__forceinline const vint16 mask_or (const vboolf16& m,vint16& c, const vint16& a, const vint16& b) { return _mm512_mask_or_epi32(c,m,a,b); }
////////////////////////////////////////////////////////////////////////////////
/// Assignment Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline vint16& operator +=(vint16& a, const vint16& b) { return a = a + b; }
__forceinline vint16& operator +=(vint16& a, int b) { return a = a + b; }
__forceinline vint16& operator +=( vint16& a, const vint16& b ) { return a = a + b; }
__forceinline vint16& operator +=( vint16& a, const int b ) { return a = a + b; }
__forceinline vint16& operator -=(vint16& a, const vint16& b) { return a = a - b; }
__forceinline vint16& operator -=(vint16& a, int b) { return a = a - b; }
__forceinline vint16& operator -=( vint16& a, const vint16& b ) { return a = a - b; }
__forceinline vint16& operator -=( vint16& a, const int b ) { return a = a - b; }
__forceinline vint16& operator *=(vint16& a, const vint16& b) { return a = a * b; }
__forceinline vint16& operator *=(vint16& a, int b) { return a = a * b; }
__forceinline vint16& operator *=( vint16& a, const vint16& b ) { return a = a * b; }
__forceinline vint16& operator *=( vint16& a, const int b ) { return a = a * b; }
__forceinline vint16& operator &=(vint16& a, const vint16& b) { return a = a & b; }
__forceinline vint16& operator &=(vint16& a, int b) { return a = a & b; }
__forceinline vint16& operator &=( vint16& a, const vint16& b ) { return a = a & b; }
__forceinline vint16& operator &=( vint16& a, const int b ) { return a = a & b; }
__forceinline vint16& operator |=(vint16& a, const vint16& b) { return a = a | b; }
__forceinline vint16& operator |=(vint16& a, int b) { return a = a | b; }
__forceinline vint16& operator |=( vint16& a, const vint16& b ) { return a = a | b; }
__forceinline vint16& operator |=( vint16& a, const int b ) { return a = a | b; }
__forceinline vint16& operator <<=(vint16& a, int b) { return a = a << b; }
__forceinline vint16& operator >>=(vint16& a, int b) { return a = a >> b; }
__forceinline vint16& operator <<=( vint16& a, const int b ) { return a = a << b; }
__forceinline vint16& operator >>=( vint16& a, const int b ) { return a = a >> b; }
////////////////////////////////////////////////////////////////////////////////
/// Comparison Operators + Select
////////////////////////////////////////////////////////////////////////////////
__forceinline vboolf16 operator ==(const vint16& a, const vint16& b) { return _mm512_cmp_epi32_mask(a,b,_MM_CMPINT_EQ); }
__forceinline vboolf16 operator ==(const vint16& a, int b) { return a == vint16(b); }
__forceinline vboolf16 operator ==(int a, const vint16& b) { return vint16(a) == b; }
__forceinline const vboolf16 operator ==( const vint16& a, const vint16& b ) { return _mm512_cmp_epi32_mask(a,b,_MM_CMPINT_EQ); }
__forceinline const vboolf16 operator ==( const vint16& a, const int b ) { return a == vint16(b); }
__forceinline const vboolf16 operator ==( const int a, const vint16& b ) { return vint16(a) == b; }
__forceinline vboolf16 operator !=(const vint16& a, const vint16& b) { return _mm512_cmp_epi32_mask(a,b,_MM_CMPINT_NE); }
__forceinline vboolf16 operator !=(const vint16& a, int b) { return a != vint16(b); }
__forceinline vboolf16 operator !=(int a, const vint16& b) { return vint16(a) != b; }
__forceinline const vboolf16 operator !=( const vint16& a, const vint16& b ) { return _mm512_cmp_epi32_mask(a,b,_MM_CMPINT_NE); }
__forceinline const vboolf16 operator !=( const vint16& a, const int b ) { return a != vint16(b); }
__forceinline const vboolf16 operator !=( const int a, const vint16& b ) { return vint16(a) != b; }
__forceinline vboolf16 operator < (const vint16& a, const vint16& b) { return _mm512_cmp_epi32_mask(a,b,_MM_CMPINT_LT); }
__forceinline vboolf16 operator < (const vint16& a, int b) { return a < vint16(b); }
__forceinline vboolf16 operator < (int a, const vint16& b) { return vint16(a) < b; }
__forceinline const vboolf16 operator < ( const vint16& a, const vint16& b ) { return _mm512_cmp_epi32_mask(a,b,_MM_CMPINT_LT); }
__forceinline const vboolf16 operator < ( const vint16& a, const int b ) { return a < vint16(b); }
__forceinline const vboolf16 operator < ( const int a, const vint16& b ) { return vint16(a) < b; }
__forceinline vboolf16 operator >=(const vint16& a, const vint16& b) { return _mm512_cmp_epi32_mask(a,b,_MM_CMPINT_GE); }
__forceinline vboolf16 operator >=(const vint16& a, int b) { return a >= vint16(b); }
__forceinline vboolf16 operator >=(int a, const vint16& b) { return vint16(a) >= b; }
__forceinline const vboolf16 operator >=( const vint16& a, const vint16& b ) { return _mm512_cmp_epi32_mask(a,b,_MM_CMPINT_GE); }
__forceinline const vboolf16 operator >=( const vint16& a, const int b ) { return a >= vint16(b); }
__forceinline const vboolf16 operator >=( const int a, const vint16& b ) { return vint16(a) >= b; }
__forceinline vboolf16 operator > (const vint16& a, const vint16& b) { return _mm512_cmp_epi32_mask(a,b,_MM_CMPINT_GT); }
__forceinline vboolf16 operator > (const vint16& a, int b) { return a > vint16(b); }
__forceinline vboolf16 operator > (int a, const vint16& b) { return vint16(a) > b; }
__forceinline const vboolf16 operator > ( const vint16& a, const vint16& b ) { return _mm512_cmp_epi32_mask(a,b,_MM_CMPINT_GT); }
__forceinline const vboolf16 operator > ( const vint16& a, const int b ) { return a > vint16(b); }
__forceinline const vboolf16 operator > ( const int a, const vint16& b ) { return vint16(a) > b; }
__forceinline vboolf16 operator <=(const vint16& a, const vint16& b) { return _mm512_cmp_epi32_mask(a,b,_MM_CMPINT_LE); }
__forceinline vboolf16 operator <=(const vint16& a, int b) { return a <= vint16(b); }
__forceinline vboolf16 operator <=(int a, const vint16& b) { return vint16(a) <= b; }
__forceinline vboolf16 eq(const vint16& a, const vint16& b) { return _mm512_cmp_epi32_mask(a,b,_MM_CMPINT_EQ); }
__forceinline vboolf16 ne(const vint16& a, const vint16& b) { return _mm512_cmp_epi32_mask(a,b,_MM_CMPINT_NE); }
__forceinline vboolf16 lt(const vint16& a, const vint16& b) { return _mm512_cmp_epi32_mask(a,b,_MM_CMPINT_LT); }
__forceinline vboolf16 ge(const vint16& a, const vint16& b) { return _mm512_cmp_epi32_mask(a,b,_MM_CMPINT_GE); }
__forceinline vboolf16 gt(const vint16& a, const vint16& b) { return _mm512_cmp_epi32_mask(a,b,_MM_CMPINT_GT); }
__forceinline vboolf16 le(const vint16& a, const vint16& b) { return _mm512_cmp_epi32_mask(a,b,_MM_CMPINT_LE); }
__forceinline vboolf16 uint_le(const vint16& a, const vint16& b) { return _mm512_cmp_epu32_mask(a,b,_MM_CMPINT_LE); }
__forceinline vboolf16 uint_gt(const vint16& a, const vint16& b) { return _mm512_cmp_epu32_mask(a,b,_MM_CMPINT_GT); }
__forceinline const vboolf16 operator <=( const vint16& a, const vint16& b ) { return _mm512_cmp_epi32_mask(a,b,_MM_CMPINT_LE); }
__forceinline const vboolf16 operator <=( const vint16& a, const int b ) { return a <= vint16(b); }
__forceinline const vboolf16 operator <=( const int a, const vint16& b ) { return vint16(a) <= b; }
__forceinline vboolf16 eq( const vint16& a, const vint16& b) { return _mm512_cmp_epi32_mask(a,b,_MM_CMPINT_EQ); }
__forceinline vboolf16 eq(const vboolf16 mask, const vint16& a, const vint16& b) { return _mm512_mask_cmp_epi32_mask(mask,a,b,_MM_CMPINT_EQ); }
__forceinline vboolf16 ne( const vint16& a, const vint16& b) { return _mm512_cmp_epi32_mask(a,b,_MM_CMPINT_NE); }
__forceinline vboolf16 ne(const vboolf16 mask, const vint16& a, const vint16& b) { return _mm512_mask_cmp_epi32_mask(mask,a,b,_MM_CMPINT_NE); }
__forceinline vboolf16 lt( const vint16& a, const vint16& b) { return _mm512_cmp_epi32_mask(a,b,_MM_CMPINT_LT); }
__forceinline vboolf16 lt(const vboolf16 mask, const vint16& a, const vint16& b) { return _mm512_mask_cmp_epi32_mask(mask,a,b,_MM_CMPINT_LT); }
__forceinline vboolf16 ge( const vint16& a, const vint16& b) { return _mm512_cmp_epi32_mask(a,b,_MM_CMPINT_GE); }
__forceinline vboolf16 ge(const vboolf16 mask, const vint16& a, const vint16& b) { return _mm512_mask_cmp_epi32_mask(mask,a,b,_MM_CMPINT_GE); }
__forceinline vboolf16 gt( const vint16& a, const vint16& b) { return _mm512_cmp_epi32_mask(a,b,_MM_CMPINT_GT); }
__forceinline vboolf16 gt(const vboolf16 mask, const vint16& a, const vint16& b) { return _mm512_mask_cmp_epi32_mask(mask,a,b,_MM_CMPINT_GT); }
__forceinline vboolf16 le( const vint16& a, const vint16& b) { return _mm512_cmp_epi32_mask(a,b,_MM_CMPINT_LE); }
__forceinline vboolf16 le(const vboolf16 mask, const vint16& a, const vint16& b) { return _mm512_mask_cmp_epi32_mask(mask,a,b,_MM_CMPINT_LE); }
__forceinline vboolf16 uint_le( const vint16& a, const vint16& b) { return _mm512_cmp_epu32_mask(a,b,_MM_CMPINT_LE); }
__forceinline vboolf16 uint_le(const vboolf16 mask, const vint16& a, const vint16& b) { return _mm512_mask_cmp_epu32_mask(mask,a,b,_MM_CMPINT_LE); }
__forceinline vboolf16 uint_gt( const vint16& a, const vint16& b) { return _mm512_cmp_epu32_mask(a,b,_MM_CMPINT_GT); }
__forceinline vboolf16 uint_gt(const vboolf16 mask, const vint16& a, const vint16& b) { return _mm512_mask_cmp_epu32_mask(mask,a,b,_MM_CMPINT_GT); }
__forceinline vint16 select(const vboolf16& m, const vint16& t, const vint16& f) {
__forceinline const vint16 select( const vboolf16& m, const vint16& t, const vint16& f ) {
return _mm512_mask_or_epi32(f,m,t,t);
}
@@ -336,119 +320,176 @@ namespace embree
// Movement/Shifting/Shuffling Functions
////////////////////////////////////////////////////////////////////////////////
__forceinline vint16 unpacklo(const vint16& a, const vint16& b) { return _mm512_unpacklo_epi32(a, b); }
__forceinline vint16 unpackhi(const vint16& a, const vint16& b) { return _mm512_unpackhi_epi32(a, b); }
__forceinline vint16 unpacklo( const vint16& a, const vint16& b ) { return _mm512_unpacklo_epi32(a.v, b.v); }
__forceinline vint16 unpackhi( const vint16& a, const vint16& b ) { return _mm512_unpackhi_epi32(a.v, b.v); }
template<int i>
__forceinline vint16 shuffle(const vint16& v) {
return _mm512_castps_si512(_mm512_permute_ps(_mm512_castsi512_ps(v), _MM_SHUFFLE(i, i, i, i)));
__forceinline vint16 shuffle(const vint16& x,_MM_SWIZZLE_ENUM perm32 ) { return _mm512_swizzle_epi32(x,perm32); }
__forceinline vint16 shuffle4(const vint16& x,_MM_PERM_ENUM perm128) { return _mm512_permute4f128_epi32(x,perm128); }
template<int D, int C, int B, int A> __forceinline vint16 shuffle (const vint16& v) { return _mm512_shuffle_epi32(v,_MM_SHUF_PERM(D,C,B,A)); }
template<int A> __forceinline vint16 shuffle (const vint16& x) { return shuffle<A,A,A,A>(v); }
template<> __forceinline vint16 shuffle<0>(const vint16& x) { return shuffle(x,_MM_SWIZ_REG_AAAA); }
template<> __forceinline vint16 shuffle<1>(const vint16& x) { return shuffle(x,_MM_SWIZ_REG_BBBB); }
template<> __forceinline vint16 shuffle<2>(const vint16& x) { return shuffle(x,_MM_SWIZ_REG_CCCC); }
template<> __forceinline vint16 shuffle<3>(const vint16& x) { return shuffle(x,_MM_SWIZ_REG_DDDD); }
template<int D, int C, int B, int A> __forceinline vint16 shuffle4(const vint16& v) { return shuffle4(v,_MM_SHUF_PERM(D,C,B,A)); }
template<int A> __forceinline vint16 shuffle4(const vint16& x) { return shuffle4<A,A,A,A>(x); }
__forceinline vint16 shuffle(const vint16& x,_MM_PERM_ENUM perm128, _MM_SWIZZLE_ENUM perm32) { return shuffle(shuffle4(x,perm128),perm32); }
__forceinline vint16 shuffle(const vboolf16& mask, vint16& v, const vint16& x,_MM_PERM_ENUM perm128, _MM_SWIZZLE_ENUM perm32) {
return _mm512_mask_swizzle_epi32(_mm512_mask_permute4f128_epi32(v,mask,x,perm128),mask,x,perm32);
}
template<int i0, int i1, int i2, int i3>
__forceinline vint16 shuffle(const vint16& v) {
return _mm512_castps_si512(_mm512_permute_ps(_mm512_castsi512_ps(v), _MM_SHUFFLE(i3, i2, i1, i0)));
__forceinline vint16 swAAAA(const vint16& x) {
return shuffle(x,_MM_SWIZ_REG_AAAA);
}
__forceinline vint16 swBBBB(const vint16& x) {
return shuffle(x,_MM_SWIZ_REG_BBBB);
}
__forceinline vint16 swCCCC(const vint16& x) {
return shuffle(x,_MM_SWIZ_REG_CCCC);
}
__forceinline vint16 swDDDD(const vint16& x) {
return shuffle(x,_MM_SWIZ_REG_DDDD);
}
template<int i>
__forceinline vint16 shuffle4(const vint16& v) {
return _mm512_castps_si512(_mm512_shuffle_f32x4(_mm512_castsi512_ps(v), _mm512_castsi512_ps(v), _MM_SHUFFLE(i, i, i, i)));
}
template<int i0, int i1, int i2, int i3>
__forceinline vint16 shuffle4(const vint16& v) {
return _mm512_castps_si512(_mm512_shuffle_f32x4(_mm512_castsi512_ps(v), _mm512_castsi512_ps(v), _MM_SHUFFLE(i3, i2, i1, i0)));
}
template<int i>
__forceinline vint16 align_shift_right(const vint16& a, const vint16& b) {
return _mm512_alignr_epi32(a, b, i);
__forceinline vint16 align_shift_right(const vint16& a, const vint16& b)
{
return _mm512_alignr_epi32(a,b,i);
};
__forceinline int toScalar(const vint16& v) {
return _mm_cvtsi128_si32(_mm512_castsi512_si128(v));
__forceinline int toScalar(const vint16& a)
{
return _mm_cvtsi128_si32(_mm512_castsi512_si128(a));
}
template<int i> __forceinline vint16 insert4(const vint16& a, const vint4& b) { return _mm512_inserti32x4(a, b, i); }
__forceinline size_t extract64bit(const vint16& v) {
return _mm_cvtsi128_si64(_mm512_castsi512_si128(v));
}
template<int N, int i>
vint<N> extractN(const vint16& v);
template<> __forceinline vint4 extractN<4,0>(const vint16& v) { return _mm512_castsi512_si128(v); }
template<> __forceinline vint4 extractN<4,1>(const vint16& v) { return _mm512_extracti32x4_epi32(v, 1); }
template<> __forceinline vint4 extractN<4,2>(const vint16& v) { return _mm512_extracti32x4_epi32(v, 2); }
template<> __forceinline vint4 extractN<4,3>(const vint16& v) { return _mm512_extracti32x4_epi32(v, 3); }
template<> __forceinline vint8 extractN<8,0>(const vint16& v) { return _mm512_castsi512_si256(v); }
template<> __forceinline vint8 extractN<8,1>(const vint16& v) { return _mm512_extracti32x8_epi32(v, 1); }
template<int i> __forceinline vint4 extract4 (const vint16& v) { return _mm512_extracti32x4_epi32(v, i); }
template<> __forceinline vint4 extract4<0>(const vint16& v) { return _mm512_castsi512_si128(v); }
template<int i> __forceinline vint8 extract8 (const vint16& v) { return _mm512_extracti32x8_epi32(v, i); }
template<> __forceinline vint8 extract8<0>(const vint16& v) { return _mm512_castsi512_si256(v); }
template<size_t i> __forceinline const vint16 insert4(const vint16& a, const vint4& b) { return _mm512_inserti32x4(a, b, i); }
////////////////////////////////////////////////////////////////////////////////
/// Reductions
////////////////////////////////////////////////////////////////////////////////
__forceinline vint16 vreduce_min2(vint16 x) { return min(x, shuffle<1,0,3,2>(x)); }
__forceinline vint16 vreduce_min4(vint16 x) { x = vreduce_min2(x); return min(x, shuffle<2,3,0,1>(x)); }
__forceinline vint16 vreduce_min8(vint16 x) { x = vreduce_min4(x); return min(x, shuffle4<1,0,3,2>(x)); }
__forceinline vint16 vreduce_min (vint16 x) { x = vreduce_min8(x); return min(x, shuffle4<2,3,0,1>(x)); }
__forceinline vint16 vreduce_max2(vint16 x) { return max(x, shuffle<1,0,3,2>(x)); }
__forceinline vint16 vreduce_max4(vint16 x) { x = vreduce_max2(x); return max(x, shuffle<2,3,0,1>(x)); }
__forceinline vint16 vreduce_max8(vint16 x) { x = vreduce_max4(x); return max(x, shuffle4<1,0,3,2>(x)); }
__forceinline vint16 vreduce_max (vint16 x) { x = vreduce_max8(x); return max(x, shuffle4<2,3,0,1>(x)); }
__forceinline vint16 vreduce_and2(vint16 x) { return x & shuffle<1,0,3,2>(x); }
__forceinline vint16 vreduce_and4(vint16 x) { x = vreduce_and2(x); return x & shuffle<2,3,0,1>(x); }
__forceinline vint16 vreduce_and8(vint16 x) { x = vreduce_and4(x); return x & shuffle4<1,0,3,2>(x); }
__forceinline vint16 vreduce_and (vint16 x) { x = vreduce_and8(x); return x & shuffle4<2,3,0,1>(x); }
__forceinline vint16 vreduce_or2(vint16 x) { return x | shuffle<1,0,3,2>(x); }
__forceinline vint16 vreduce_or4(vint16 x) { x = vreduce_or2(x); return x | shuffle<2,3,0,1>(x); }
__forceinline vint16 vreduce_or8(vint16 x) { x = vreduce_or4(x); return x | shuffle4<1,0,3,2>(x); }
__forceinline vint16 vreduce_or (vint16 x) { x = vreduce_or8(x); return x | shuffle4<2,3,0,1>(x); }
__forceinline vint16 vreduce_add2(vint16 x) { return x + shuffle<1,0,3,2>(x); }
__forceinline vint16 vreduce_add4(vint16 x) { x = vreduce_add2(x); return x + shuffle<2,3,0,1>(x); }
__forceinline vint16 vreduce_add8(vint16 x) { x = vreduce_add4(x); return x + shuffle4<1,0,3,2>(x); }
__forceinline vint16 vreduce_add (vint16 x) { x = vreduce_add8(x); return x + shuffle4<2,3,0,1>(x); }
__forceinline int reduce_min(const vint16& v) { return toScalar(vreduce_min(v)); }
__forceinline int reduce_max(const vint16& v) { return toScalar(vreduce_max(v)); }
__forceinline int reduce_and(const vint16& v) { return toScalar(vreduce_and(v)); }
__forceinline int reduce_or (const vint16& v) { return toScalar(vreduce_or (v)); }
__forceinline int reduce_add(const vint16& v) { return toScalar(vreduce_add(v)); }
__forceinline int reduce_add(vint16 a) { return _mm512_reduce_add_epi32(a); }
__forceinline int reduce_mul(vint16 a) { return _mm512_reduce_mul_epi32(a); }
__forceinline int reduce_min(vint16 a) { return _mm512_reduce_min_epi32(a); }
__forceinline int reduce_max(vint16 a) { return _mm512_reduce_max_epi32(a); }
__forceinline int reduce_and(vint16 a) { return _mm512_reduce_and_epi32(a); }
__forceinline vint16 vreduce_min2(vint16 x) { return min(x,shuffle(x,_MM_SWIZ_REG_BADC)); }
__forceinline vint16 vreduce_min4(vint16 x) { x = vreduce_min2(x); return min(x,shuffle(x,_MM_SWIZ_REG_CDAB)); }
__forceinline vint16 vreduce_min8(vint16 x) { x = vreduce_min4(x); return min(x,shuffle4(x,_MM_SHUF_PERM(2,3,0,1))); }
__forceinline vint16 vreduce_min (vint16 x) { x = vreduce_min8(x); return min(x,shuffle4(x,_MM_SHUF_PERM(1,0,3,2))); }
__forceinline vint16 vreduce_max2(vint16 x) { return max(x,shuffle(x,_MM_SWIZ_REG_BADC)); }
__forceinline vint16 vreduce_max4(vint16 x) { x = vreduce_max2(x); return max(x,shuffle(x,_MM_SWIZ_REG_CDAB)); }
__forceinline vint16 vreduce_max8(vint16 x) { x = vreduce_max4(x); return max(x,shuffle4(x,_MM_SHUF_PERM(2,3,0,1))); }
__forceinline vint16 vreduce_max (vint16 x) { x = vreduce_max8(x); return max(x,shuffle4(x,_MM_SHUF_PERM(1,0,3,2))); }
__forceinline vint16 vreduce_and2(vint16 x) { return x & shuffle(x,_MM_SWIZ_REG_BADC); }
__forceinline vint16 vreduce_and4(vint16 x) { x = vreduce_and2(x); return x & shuffle(x,_MM_SWIZ_REG_CDAB); }
__forceinline vint16 vreduce_and8(vint16 x) { x = vreduce_and4(x); return x & shuffle4(x,_MM_SHUF_PERM(2,3,0,1)); }
__forceinline vint16 vreduce_and (vint16 x) { x = vreduce_and8(x); return x & shuffle4(x,_MM_SHUF_PERM(1,0,3,2)); }
__forceinline vint16 vreduce_or2(vint16 x) { return x | shuffle(x,_MM_SWIZ_REG_BADC); }
__forceinline vint16 vreduce_or4(vint16 x) { x = vreduce_or2(x); return x | shuffle(x,_MM_SWIZ_REG_CDAB); }
__forceinline vint16 vreduce_or8(vint16 x) { x = vreduce_or4(x); return x | shuffle4(x,_MM_SHUF_PERM(2,3,0,1)); }
__forceinline vint16 vreduce_or (vint16 x) { x = vreduce_or8(x); return x | shuffle4(x,_MM_SHUF_PERM(1,0,3,2)); }
__forceinline vint16 vreduce_add2(vint16 x) { return x + shuffle(x,_MM_SWIZ_REG_BADC); }
__forceinline vint16 vreduce_add4(vint16 x) { x = vreduce_add2(x); return x + shuffle(x,_MM_SWIZ_REG_CDAB); }
__forceinline vint16 vreduce_add8(vint16 x) { x = vreduce_add4(x); return x + shuffle4(x,_MM_SHUF_PERM(2,3,0,1)); }
__forceinline vint16 vreduce_add (vint16 x) { x = vreduce_add8(x); return x + shuffle4(x,_MM_SHUF_PERM(1,0,3,2)); }
////////////////////////////////////////////////////////////////////////////////
/// Memory load and store operations
////////////////////////////////////////////////////////////////////////////////
__forceinline vint16 conflict(const vint16& index)
__forceinline vint16 broadcast4to16i(const int *const ptr) {
return _mm512_extload_epi32(ptr,_MM_UPCONV_EPI32_NONE,_MM_BROADCAST_4X16,_MM_HINT_NONE);
}
__forceinline vint16 gather16i_4i(const int *__restrict__ const ptr0,
const int *__restrict__ const ptr1,
const int *__restrict__ const ptr2,
const int *__restrict__ const ptr3)
{
vint16 v = broadcast4to16i(ptr0);
v = select((vboolf16)0xf0 , broadcast4to16i(ptr1),v);
v = select((vboolf16)0xf00 , broadcast4to16i(ptr2),v);
v = select((vboolf16)0xf000, broadcast4to16i(ptr3),v);
return v;
}
__forceinline vint16 gather16i_4i_align(const void *__restrict__ const ptr0,
const void *__restrict__ const ptr1,
const void *__restrict__ const ptr2,
const void *__restrict__ const ptr3)
{
vint16 v = broadcast4to16i((const int*)ptr3);
v = align_shift_right<12>(v,broadcast4to16i((const int*)ptr2));
v = align_shift_right<12>(v,broadcast4to16i((const int*)ptr1));
v = align_shift_right<12>(v,broadcast4to16i((const int*)ptr0));
return v;
}
__forceinline vint16 gather16i_4i_align(const vint16& v0,
const vint16& v1,
const vint16& v2,
const vint16& v3)
{
vint16 v = v3;
v = align_shift_right<12>(v,v2);
v = align_shift_right<12>(v,v1);
v = align_shift_right<12>(v,v0);
return v;
}
__forceinline vint16 gather16i(const vboolf16& mask, const int *const ptr, const vint16& index,const int scale = 4) {
return _mm512_mask_i32gather_epi32(_mm512_undefined_epi32(),mask,index,ptr,scale);
}
__forceinline vint16 gather16i(const vboolf16& mask, vint16& dest, const int *const ptr, const vint16& index,const int scale = 4) {
return _mm512_mask_i32gather_epi32(dest,mask,index,ptr,scale);
}
__forceinline void scatter16i(const vboolf16& mask,int *const ptr, const vint16& index,const vint16& v, const int scale = 4) {
_mm512_mask_i32scatter_epi32((int*)ptr,mask,index,v,scale);
}
__forceinline vint16 conflict16i(const vint16& index)
{
return _mm512_conflict_epi32(index);
}
__forceinline vint16 conflict(const vboolf16& mask, vint16& dest, const vint16& index)
__forceinline vint16 conflict16i(const vboolf16& mask, vint16& dest, const vint16& index)
{
return _mm512_mask_conflict_epi32(dest,mask,index);
}
__forceinline void compactustore16i_low(const vboolf16 mask, void *addr, const vint16& reg) {
_mm512_mask_compressstoreu_epi32(addr,mask,reg);
}
__forceinline vint16 convert_uint32_t(const __m512& f) {
return _mm512_cvtps_epu32(f);
}
__forceinline vint16 permute(vint16 v, vint16 index) {
return _mm512_permutexvar_epi32(index,v);
__forceinline vint16 permute(vint16 v,vint16 index)
{
return _mm512_permutev_epi32(index,v);
}
__forceinline vint16 reverse(const vint16 &a) {
__forceinline vint16 reverse(const vint16 &a)
{
return permute(a,vint16(reverse_step));
}
@@ -475,19 +516,49 @@ namespace embree
}
/* this should use a vbool8 and a vint8_64...*/
template<int scale = 1, int hint = _MM_HINT_T0>
__forceinline void gather_prefetch64(const void* base_addr, const vbool16& mask, const vint16& offset)
__forceinline void gather_prefetch64(void const* base_addr,const vbool16 &mask, const vint16& offset, const int scale = 1, const int hint = _MM_HINT_T0)
{
#if defined(__AVX512PF__)
_mm512_mask_prefetch_i64gather_pd(offset, mask, base_addr, scale, hint);
_mm512_mask_prefetch_i64gather_pd(offset,mask,base_addr,scale,hint);
#endif
}
__forceinline vint16 sortNetwork(const vint16& v)
{
const vint16 a0 = v;
const vint16 b0 = shuffle<1,0,3,2>(a0);
const vint16 c0 = umin(a0,b0);
const vint16 d0 = umax(a0,b0);
const vint16 a1 = select(0x99 /* 0b10011001 */,c0,d0);
const vint16 b1 = shuffle<2,3,0,1>(a1);
const vint16 c1 = umin(a1,b1);
const vint16 d1 = umax(a1,b1);
const vint16 a2 = select(0xc3 /* 0b11000011 */,c1,d1);
const vint16 b2 = shuffle<1,0,3,2>(a2);
const vint16 c2 = umin(a2,b2);
const vint16 d2 = umax(a2,b2);
const vint16 a3 = select(0xa5 /* 0b10100101 */,c2,d2);
const vint16 b3 = shuffle4<1,0,1,0>(a3);
const vint16 c3 = umin(a3,b3);
const vint16 d3 = umax(a3,b3);
const vint16 a4 = select(0xf /* 0b00001111 */,c3,d3);
const vint16 b4 = shuffle<2,3,0,1>(a4);
const vint16 c4 = umin(a4,b4);
const vint16 d4 = umax(a4,b4);
const vint16 a5 = select(0x33 /* 0b00110011 */,c4,d4);
const vint16 b5 = shuffle<1,0,3,2>(a5);
const vint16 c5 = umin(a5,b5);
const vint16 d5 = umax(a5,b5);
const vint16 a6 = select(0x55 /* 0b01010101 */,c5,d5);
return a6;
}
////////////////////////////////////////////////////////////////////////////////
/// Output Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline std::ostream& operator <<(std::ostream& cout, const vint16& v)
__forceinline std::ostream& operator<<(std::ostream& cout, const vint16& v)
{
cout << "<" << v[0];
for (int i=1; i<16; i++) cout << ", " << v[i];
+160 -289
View File
@@ -1,5 +1,5 @@
// ======================================================================== //
// Copyright 2009-2017 Intel Corporation //
// Copyright 2009-2016 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
@@ -35,86 +35,83 @@ namespace embree
/// Constructors, Assignment & Cast Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline vint() {}
__forceinline vint(const vint4& a) { v = a.v; }
__forceinline vint4& operator =(const vint4& a) { v = a.v; return *this; }
__forceinline vint ( ) {}
__forceinline vint ( const vint4& a ) { v = a.v; }
__forceinline vint4& operator=( const vint4& a ) { v = a.v; return *this; }
__forceinline vint(__m128i a) : v(a) {}
__forceinline operator const __m128i&() const { return v; }
__forceinline operator __m128i&() { return v; }
__forceinline vint( const __m128i a ) : v(a) {}
__forceinline operator const __m128i&( void ) const { return v; }
__forceinline operator __m128i&( void ) { return v; }
__forceinline vint(int a) : v(_mm_set1_epi32(a)) {}
__forceinline vint(int a, int b, int c, int d) : v(_mm_set_epi32(d, c, b, a)) {}
__forceinline explicit vint(__m128 a) : v(_mm_cvtps_epi32(a)) {}
__forceinline vint( const int& a ) : v(_mm_shuffle_epi32(_mm_castps_si128(_mm_load_ss((float*)&a)), _MM_SHUFFLE(0, 0, 0, 0))) {}
__forceinline vint( const uint32_t& a ) : v(_mm_shuffle_epi32(_mm_castps_si128(_mm_load_ss((float*)&a)), _MM_SHUFFLE(0, 0, 0, 0))) {}
#if defined(__X86_64__)
__forceinline vint( const size_t a ) : v(_mm_set1_epi32((int)a)) {}
#endif
__forceinline vint( int a, int b, int c, int d) : v(_mm_set_epi32(d, c, b, a)) {}
__forceinline explicit vint( const __m128 a ) : v(_mm_cvtps_epi32(a)) {}
#if defined(__AVX512VL__)
__forceinline explicit vint(const vboolf4& a) : v(_mm_movm_epi32(a)) {}
__forceinline explicit vint( const vboolf4 &a ) : v(_mm_movm_epi32(a)) {}
#else
__forceinline explicit vint(const vboolf4& a) : v(_mm_castps_si128((__m128)a)) {}
__forceinline explicit vint( const vboolf4 &a ) : v(_mm_castps_si128((__m128)a)) {}
#endif
////////////////////////////////////////////////////////////////////////////////
/// Constants
////////////////////////////////////////////////////////////////////////////////
__forceinline vint(ZeroTy) : v(_mm_setzero_si128()) {}
__forceinline vint(OneTy) : v(_mm_set_epi32(1, 1, 1, 1)) {}
__forceinline vint(PosInfTy) : v(_mm_set_epi32(pos_inf, pos_inf, pos_inf, pos_inf)) {}
__forceinline vint(NegInfTy) : v(_mm_set_epi32(neg_inf, neg_inf, neg_inf, neg_inf)) {}
__forceinline vint(StepTy) : v(_mm_set_epi32(3, 2, 1, 0)) {}
__forceinline vint(TrueTy) { v = _mm_cmpeq_epi32(v,v); }
__forceinline vint(UndefinedTy) : v(_mm_castps_si128(_mm_undefined_ps())) {}
__forceinline vint( ZeroTy ) : v(_mm_setzero_si128()) {}
__forceinline vint( OneTy ) : v(_mm_set_epi32(1, 1, 1, 1)) {}
__forceinline vint( PosInfTy ) : v(_mm_set_epi32(pos_inf, pos_inf, pos_inf, pos_inf)) {}
__forceinline vint( NegInfTy ) : v(_mm_set_epi32(neg_inf, neg_inf, neg_inf, neg_inf)) {}
__forceinline vint( StepTy ) : v(_mm_set_epi32(3, 2, 1, 0)) {}
__forceinline vint( TrueTy ) { v = _mm_cmpeq_epi32(v,v); }
////////////////////////////////////////////////////////////////////////////////
/// Loads and Stores
////////////////////////////////////////////////////////////////////////////////
static __forceinline vint4 load (const void* a) { return _mm_load_si128((__m128i*)a); }
static __forceinline vint4 loadu(const void* a) { return _mm_loadu_si128((__m128i*)a); }
static __forceinline vint4 load ( const void* const a ) { return _mm_load_si128((__m128i*)a); }
static __forceinline vint4 loadu( const void* const a ) { return _mm_loadu_si128((__m128i*)a); }
static __forceinline void store (void* ptr, const vint4& v) { _mm_store_si128((__m128i*)ptr,v); }
static __forceinline void storeu(void* ptr, const vint4& v) { _mm_storeu_si128((__m128i*)ptr,v); }
#if defined(__AVX512VL__)
static __forceinline vint4 load ( const vboolf4& mask, const void* const ptr ) { return _mm_mask_load_epi32 (_mm_setzero_si128(),mask,ptr); }
static __forceinline vint4 loadu( const vboolf4& mask, const void* const ptr ) { return _mm_mask_loadu_epi32(_mm_setzero_si128(),mask,ptr); }
static __forceinline vint4 compact(const vboolf4& mask, vint4 &v) {
return _mm_mask_compress_epi32(v, mask, v);
}
static __forceinline vint4 compact(const vboolf4& mask, vint4 &a, const vint4& b) {
return _mm_mask_compress_epi32(a, mask, b);
}
static __forceinline vint4 load (const vboolf4& mask, const void* ptr) { return _mm_mask_load_epi32 (_mm_setzero_si128(),mask,ptr); }
static __forceinline vint4 loadu(const vboolf4& mask, const void* ptr) { return _mm_mask_loadu_epi32(_mm_setzero_si128(),mask,ptr); }
static __forceinline void store (const vboolf4& mask, void* ptr, const vint4& v) { _mm_mask_store_epi32 (ptr,mask,v); }
static __forceinline void storeu(const vboolf4& mask, void* ptr, const vint4& v) { _mm_mask_storeu_epi32(ptr,mask,v); }
static __forceinline void store ( const vboolf4& mask, void* ptr, const vint4& v ) { _mm_mask_store_epi32 (ptr,mask,v); }
static __forceinline void storeu( const vboolf4& mask, void* ptr, const vint4& v ) { _mm_mask_storeu_epi32(ptr,mask,v); }
#elif defined(__AVX__)
static __forceinline vint4 load (const vbool4& mask, const void* a) { return _mm_castps_si128(_mm_maskload_ps((float*)a,mask)); }
static __forceinline vint4 loadu(const vbool4& mask, const void* a) { return _mm_castps_si128(_mm_maskload_ps((float*)a,mask)); }
static __forceinline vint4 load ( const vbool4& mask, const void* const a ) { return _mm_castps_si128(_mm_maskload_ps((float*)a,mask)); }
static __forceinline vint4 loadu( const vbool4& mask, const void* const a ) { return _mm_castps_si128(_mm_maskload_ps((float*)a,mask)); }
static __forceinline void store (const vboolf4& mask, void* ptr, const vint4& i) { _mm_maskstore_ps((float*)ptr,(__m128i)mask,_mm_castsi128_ps(i)); }
static __forceinline void storeu(const vboolf4& mask, void* ptr, const vint4& i) { _mm_maskstore_ps((float*)ptr,(__m128i)mask,_mm_castsi128_ps(i)); }
static __forceinline void store ( const vboolf4& mask, void* ptr, const vint4& i ) { _mm_maskstore_ps((float*)ptr,(__m128i)mask,_mm_castsi128_ps(i)); }
static __forceinline void storeu( const vboolf4& mask, void* ptr, const vint4& i ) { _mm_maskstore_ps((float*)ptr,(__m128i)mask,_mm_castsi128_ps(i)); }
#else
static __forceinline vint4 load (const vbool4& mask, const void* a) { return _mm_and_si128(_mm_load_si128 ((__m128i*)a),mask); }
static __forceinline vint4 loadu(const vbool4& mask, const void* a) { return _mm_and_si128(_mm_loadu_si128((__m128i*)a),mask); }
static __forceinline vint4 load ( const vbool4& mask, const void* const a ) { return _mm_and_si128(_mm_load_si128 ((__m128i*)a),mask); }
static __forceinline vint4 loadu( const vbool4& mask, const void* const a ) { return _mm_and_si128(_mm_loadu_si128((__m128i*)a),mask); }
static __forceinline void store (const vboolf4& mask, void* ptr, const vint4& i) { store (ptr,select(mask,i,load (ptr))); }
static __forceinline void storeu(const vboolf4& mask, void* ptr, const vint4& i) { storeu(ptr,select(mask,i,loadu(ptr))); }
static __forceinline void store ( const vboolf4& mask, void* ptr, const vint4& i ) { store (ptr,select(mask,i,load (ptr))); }
static __forceinline void storeu( const vboolf4& mask, void* ptr, const vint4& i ) { storeu(ptr,select(mask,i,loadu(ptr))); }
#endif
#if defined(__SSE4_1__)
static __forceinline vint4 load(const unsigned char* ptr) {
static __forceinline vint4 load( const unsigned char* const ptr ) {
return _mm_cvtepu8_epi32(_mm_load_si128((__m128i*)ptr));
}
static __forceinline vint4 loadu(const unsigned char* ptr) {
static __forceinline vint4 loadu( const unsigned char* const ptr ) {
return _mm_cvtepu8_epi32(_mm_loadu_si128((__m128i*)ptr));
}
#endif
static __forceinline vint4 load(const unsigned short* ptr) {
static __forceinline vint4 load(const unsigned short* const ptr) {
#if defined (__SSE4_1__)
return _mm_cvtepu16_epi32(_mm_loadu_si128((__m128i*)ptr));
#else
@@ -122,7 +119,7 @@ namespace embree
#endif
}
static __forceinline void store(unsigned char* ptr, const vint4& v) {
static __forceinline void store_uchar( unsigned char* const ptr, const vint4& v ) {
#if defined(__SSE4_1__)
__m128i x = v;
x = _mm_packus_epi32(x, x);
@@ -134,12 +131,7 @@ namespace embree
#endif
}
static __forceinline void store(unsigned short* ptr, const vint4& v) {
for (size_t i=0;i<4;i++)
ptr[i] = (unsigned short)v[i];
}
static __forceinline vint4 load_nt(void* ptr) {
static __forceinline vint4 load_nt (void* ptr) {
#if defined(__SSE4_1__)
return _mm_stream_load_si128((__m128i*)ptr);
#else
@@ -149,53 +141,24 @@ namespace embree
static __forceinline void store_nt(void* ptr, const vint4& v) {
#if defined(__SSE4_1__)
_mm_stream_ps((float*)ptr, _mm_castsi128_ps(v));
_mm_stream_ps((float*)ptr,_mm_castsi128_ps(v));
#else
_mm_store_si128((__m128i*)ptr,v);
#endif
}
template<int scale = 4>
static __forceinline vint4 gather(const int* ptr, const vint4& index) {
#if defined(__AVX2__)
return _mm_i32gather_epi32(ptr, index, scale);
#else
return vint4(
*(int*)(((char*)ptr)+scale*index[0]),
*(int*)(((char*)ptr)+scale*index[1]),
*(int*)(((char*)ptr)+scale*index[2]),
*(int*)(((char*)ptr)+scale*index[3]));
#endif
}
template<int scale = 4>
static __forceinline vint4 gather(const vboolf4& mask, const int* ptr, const vint4& index) {
vint4 r = zero;
#if defined(__AVX512VL__)
return _mm_mmask_i32gather_epi32(r, mask, index, ptr, scale);
#elif defined(__AVX2__)
return _mm_mask_i32gather_epi32(r, ptr, index, mask, scale);
#else
if (likely(mask[0])) r[0] = *(int*)(((char*)ptr)+scale*index[0]);
if (likely(mask[1])) r[1] = *(int*)(((char*)ptr)+scale*index[1]);
if (likely(mask[2])) r[2] = *(int*)(((char*)ptr)+scale*index[2]);
if (likely(mask[3])) r[3] = *(int*)(((char*)ptr)+scale*index[3]);
return r;
#endif
}
#if defined(__x86_64__)
static __forceinline vint4 broadcast64(long long a) { return _mm_set1_epi64x(a); }
static __forceinline vint4 broadcast64(const long long &a) { return _mm_set1_epi64x(a); }
#endif
////////////////////////////////////////////////////////////////////////////////
/// Array Access
////////////////////////////////////////////////////////////////////////////////
__forceinline const int& operator [](size_t index) const { assert(index < 4); return i[index]; }
__forceinline int& operator [](size_t index) { assert(index < 4); return i[index]; }
__forceinline const int& operator []( const size_t index ) const { assert(index < 4); return i[index]; }
__forceinline int& operator []( const size_t index ) { assert(index < 4); return i[index]; }
friend __forceinline vint4 select(const vboolf4& m, const vint4& t, const vint4& f) {
friend __forceinline const vint4 select( const vboolf4& m, const vint4& t, const vint4& f ) {
#if defined(__AVX512VL__)
return _mm_mask_blend_epi32(m, f, t);
#elif defined(__SSE4_1__)
@@ -210,224 +173,190 @@ namespace embree
/// Unary Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline vint4 asInt(const __m128& a) { return _mm_castps_si128(a); }
__forceinline vint4 operator +(const vint4& a) { return a; }
__forceinline vint4 operator -(const vint4& a) { return _mm_sub_epi32(_mm_setzero_si128(), a); }
__forceinline const vint4 asInt ( const __m128& a ) { return _mm_castps_si128(a); }
__forceinline const vint4 operator +( const vint4& a ) { return a; }
__forceinline const vint4 operator -( const vint4& a ) { return _mm_sub_epi32(_mm_setzero_si128(), a.v); }
#if defined(__SSSE3__)
__forceinline vint4 abs(const vint4& a) { return _mm_abs_epi32(a); }
__forceinline const vint4 abs ( const vint4& a ) { return _mm_abs_epi32(a.v); }
#endif
////////////////////////////////////////////////////////////////////////////////
/// Binary Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline vint4 operator +(const vint4& a, const vint4& b) { return _mm_add_epi32(a, b); }
__forceinline vint4 operator +(const vint4& a, int b) { return a + vint4(b); }
__forceinline vint4 operator +(int a, const vint4& b) { return vint4(a) + b; }
__forceinline const vint4 operator +( const vint4& a, const vint4& b ) { return _mm_add_epi32(a.v, b.v); }
__forceinline const vint4 operator +( const vint4& a, const int& b ) { return a + vint4(b); }
__forceinline const vint4 operator +( const int& a, const vint4& b ) { return vint4(a) + b; }
__forceinline vint4 operator -(const vint4& a, const vint4& b) { return _mm_sub_epi32(a, b); }
__forceinline vint4 operator -(const vint4& a, int b) { return a - vint4(b); }
__forceinline vint4 operator -(int a, const vint4& b) { return vint4(a) - b; }
__forceinline const vint4 operator -( const vint4& a, const vint4& b ) { return _mm_sub_epi32(a.v, b.v); }
__forceinline const vint4 operator -( const vint4& a, const int& b ) { return a - vint4(b); }
__forceinline const vint4 operator -( const int& a, const vint4& b ) { return vint4(a) - b; }
#if defined(__SSE4_1__)
__forceinline vint4 operator *(const vint4& a, const vint4& b) { return _mm_mullo_epi32(a, b); }
__forceinline const vint4 operator *( const vint4& a, const vint4& b ) { return _mm_mullo_epi32(a.v, b.v); }
#else
__forceinline vint4 operator *(const vint4& a, const vint4& b) { return vint4(a[0]*b[0],a[1]*b[1],a[2]*b[2],a[3]*b[3]); }
__forceinline const vint4 operator *( const vint4& a, const vint4& b ) { return vint4(a[0]*b[0],a[1]*b[1],a[2]*b[2],a[3]*b[3]); }
#endif
__forceinline vint4 operator *(const vint4& a, int b) { return a * vint4(b); }
__forceinline vint4 operator *(int a, const vint4& b) { return vint4(a) * b; }
__forceinline const vint4 operator *( const vint4& a, const int& b ) { return a * vint4(b); }
__forceinline const vint4 operator *( const int& a, const vint4& b ) { return vint4(a) * b; }
__forceinline vint4 operator &(const vint4& a, const vint4& b) { return _mm_and_si128(a, b); }
__forceinline vint4 operator &(const vint4& a, int b) { return a & vint4(b); }
__forceinline vint4 operator &(int a, const vint4& b) { return vint4(a) & b; }
__forceinline const vint4 operator &( const vint4& a, const vint4& b ) { return _mm_and_si128(a.v, b.v); }
__forceinline const vint4 operator &( const vint4& a, const int& b ) { return a & vint4(b); }
__forceinline const vint4 operator &( const int& a, const vint4& b ) { return vint4(a) & b; }
__forceinline vint4 operator |(const vint4& a, const vint4& b) { return _mm_or_si128(a, b); }
__forceinline vint4 operator |(const vint4& a, int b) { return a | vint4(b); }
__forceinline vint4 operator |(int a, const vint4& b) { return vint4(a) | b; }
__forceinline const vint4 operator |( const vint4& a, const vint4& b ) { return _mm_or_si128(a.v, b.v); }
__forceinline const vint4 operator |( const vint4& a, const int& b ) { return a | vint4(b); }
__forceinline const vint4 operator |( const int& a, const vint4& b ) { return vint4(a) | b; }
__forceinline vint4 operator ^(const vint4& a, const vint4& b) { return _mm_xor_si128(a, b); }
__forceinline vint4 operator ^(const vint4& a, int b) { return a ^ vint4(b); }
__forceinline vint4 operator ^(int a, const vint4& b) { return vint4(a) ^ b; }
__forceinline const vint4 operator ^( const vint4& a, const vint4& b ) { return _mm_xor_si128(a.v, b.v); }
__forceinline const vint4 operator ^( const vint4& a, const int& b ) { return a ^ vint4(b); }
__forceinline const vint4 operator ^( const int& a, const vint4& b ) { return vint4(a) ^ b; }
__forceinline vint4 operator <<(const vint4& a, int n) { return _mm_slli_epi32(a, n); }
__forceinline vint4 operator >>(const vint4& a, int n) { return _mm_srai_epi32(a, n); }
__forceinline const vint4 operator <<( const vint4& a, const int& n ) { return _mm_slli_epi32(a.v, n); }
__forceinline const vint4 operator >>( const vint4& a, const int& n ) { return _mm_srai_epi32(a.v, n); }
__forceinline vint4 sll (const vint4& a, int b) { return _mm_slli_epi32(a, b); }
__forceinline vint4 sra (const vint4& a, int b) { return _mm_srai_epi32(a, b); }
__forceinline vint4 srl (const vint4& a, int b) { return _mm_srli_epi32(a, b); }
__forceinline const vint4 sll ( const vint4& a, const int& b ) { return _mm_slli_epi32(a.v, b); }
__forceinline const vint4 sra ( const vint4& a, const int& b ) { return _mm_srai_epi32(a.v, b); }
__forceinline const vint4 srl ( const vint4& a, const int& b ) { return _mm_srli_epi32(a.v, b); }
#if defined(__SSE4_1__)
__forceinline const vint4 min( const vint4& a, const vint4& b ) { return _mm_min_epi32(a.v, b.v); }
__forceinline const vint4 max( const vint4& a, const vint4& b ) { return _mm_max_epi32(a.v, b.v); }
__forceinline const vint4 umin( const vint4& a, const vint4& b ) { return _mm_min_epu32(a.v, b.v); }
__forceinline const vint4 umax( const vint4& a, const vint4& b ) { return _mm_max_epu32(a.v, b.v); }
#else
__forceinline const vint4 min( const vint4& a, const vint4& b ) { return vint4(min(a[0],b[0]),min(a[1],b[1]),min(a[2],b[2]),min(a[3],b[3])); }
__forceinline const vint4 max( const vint4& a, const vint4& b ) { return vint4(max(a[0],b[0]),max(a[1],b[1]),max(a[2],b[2]),max(a[3],b[3])); }
#endif
__forceinline const vint4 min( const vint4& a, const int& b ) { return min(a,vint4(b)); }
__forceinline const vint4 min( const int& a, const vint4& b ) { return min(vint4(a),b); }
__forceinline const vint4 max( const vint4& a, const int& b ) { return max(a,vint4(b)); }
__forceinline const vint4 max( const int& a, const vint4& b ) { return max(vint4(a),b); }
////////////////////////////////////////////////////////////////////////////////
/// Assignment Operators
////////////////////////////////////////////////////////////////////////////////
__forceinline vint4& operator +=(vint4& a, const vint4& b) { return a = a + b; }
__forceinline vint4& operator +=(vint4& a, int b) { return a = a + b; }
__forceinline vint4& operator +=( vint4& a, const vint4& b ) { return a = a + b; }
__forceinline vint4& operator +=( vint4& a, const int& b ) { return a = a + b; }
__forceinline vint4& operator -=(vint4& a, const vint4& b) { return a = a - b; }
__forceinline vint4& operator -=(vint4& a, int b) { return a = a - b; }
__forceinline vint4& operator -=( vint4& a, const vint4& b ) { return a = a - b; }
__forceinline vint4& operator -=( vint4& a, const int& b ) { return a = a - b; }
#if defined(__SSE4_1__)
__forceinline vint4& operator *=(vint4& a, const vint4& b) { return a = a * b; }
__forceinline vint4& operator *=(vint4& a, int b) { return a = a * b; }
__forceinline vint4& operator *=( vint4& a, const vint4& b ) { return a = a * b; }
__forceinline vint4& operator *=( vint4& a, const int& b ) { return a = a * b; }
#endif
__forceinline vint4& operator &=(vint4& a, const vint4& b) { return a = a & b; }
__forceinline vint4& operator &=(vint4& a, int b) { return a = a & b; }
__forceinline vint4& operator &=( vint4& a, const vint4& b ) { return a = a & b; }
__forceinline vint4& operator &=( vint4& a, const int& b ) { return a = a & b; }
__forceinline vint4& operator |=(vint4& a, const vint4& b) { return a = a | b; }
__forceinline vint4& operator |=(vint4& a, int b) { return a = a | b; }
__forceinline vint4& operator |=( vint4& a, const vint4& b ) { return a = a | b; }
__forceinline vint4& operator |=( vint4& a, const int& b ) { return a = a | b; }
__forceinline vint4& operator <<=(vint4& a, int b) { return a = a << b; }
__forceinline vint4& operator >>=(vint4& a, int b) { return a = a >> b; }
__forceinline vint4& operator <<=( vint4& a, const int& b ) { return a = a << b; }
__forceinline vint4& operator >>=( vint4& a, const int& b ) { return a = a >> b; }
////////////////////////////////////////////////////////////////////////////////
/// Comparison Operators + Select
////////////////////////////////////////////////////////////////////////////////
#if defined(__AVX512VL__)
__forceinline vboolf4 operator ==(const vint4& a, const vint4& b) { return _mm_cmp_epi32_mask(a,b,_MM_CMPINT_EQ); }
__forceinline vboolf4 operator !=(const vint4& a, const vint4& b) { return _mm_cmp_epi32_mask(a,b,_MM_CMPINT_NE); }
__forceinline vboolf4 operator < (const vint4& a, const vint4& b) { return _mm_cmp_epi32_mask(a,b,_MM_CMPINT_LT); }
__forceinline vboolf4 operator >=(const vint4& a, const vint4& b) { return _mm_cmp_epi32_mask(a,b,_MM_CMPINT_GE); }
__forceinline vboolf4 operator > (const vint4& a, const vint4& b) { return _mm_cmp_epi32_mask(a,b,_MM_CMPINT_GT); }
__forceinline vboolf4 operator <=(const vint4& a, const vint4& b) { return _mm_cmp_epi32_mask(a,b,_MM_CMPINT_LE); }
__forceinline const vboolf4 operator ==( const vint4& a, const vint4& b ) { return _mm_cmp_epi32_mask(a,b,_MM_CMPINT_EQ); }
__forceinline const vboolf4 operator !=( const vint4& a, const vint4& b ) { return _mm_cmp_epi32_mask(a,b,_MM_CMPINT_NE); }
__forceinline const vboolf4 operator < ( const vint4& a, const vint4& b ) { return _mm_cmp_epi32_mask(a,b,_MM_CMPINT_LT); }
__forceinline const vboolf4 operator >=( const vint4& a, const vint4& b ) { return _mm_cmp_epi32_mask(a,b,_MM_CMPINT_GE); }
__forceinline const vboolf4 operator > ( const vint4& a, const vint4& b ) { return _mm_cmp_epi32_mask(a,b,_MM_CMPINT_GT); }
__forceinline const vboolf4 operator <=( const vint4& a, const vint4& b ) { return _mm_cmp_epi32_mask(a,b,_MM_CMPINT_LE); }
#else
__forceinline vboolf4 operator ==(const vint4& a, const vint4& b) { return _mm_castsi128_ps(_mm_cmpeq_epi32(a, b)); }
__forceinline vboolf4 operator !=(const vint4& a, const vint4& b) { return !(a == b); }
__forceinline vboolf4 operator < (const vint4& a, const vint4& b) { return _mm_castsi128_ps(_mm_cmplt_epi32(a, b)); }
__forceinline vboolf4 operator >=(const vint4& a, const vint4& b) { return !(a < b); }
__forceinline vboolf4 operator > (const vint4& a, const vint4& b) { return _mm_castsi128_ps(_mm_cmpgt_epi32(a, b)); }
__forceinline vboolf4 operator <=(const vint4& a, const vint4& b) { return !(a > b); }
__forceinline const vboolf4 operator ==( const vint4& a, const vint4& b ) { return _mm_castsi128_ps(_mm_cmpeq_epi32 (a.v, b.v)); }
__forceinline const vboolf4 operator !=( const vint4& a, const vint4& b ) { return !(a == b); }
__forceinline const vboolf4 operator < ( const vint4& a, const vint4& b ) { return _mm_castsi128_ps(_mm_cmplt_epi32 (a.v, b.v)); }
__forceinline const vboolf4 operator >=( const vint4& a, const vint4& b ) { return !(a < b); }
__forceinline const vboolf4 operator > ( const vint4& a, const vint4& b ) { return _mm_castsi128_ps(_mm_cmpgt_epi32 (a.v, b.v)); }
__forceinline const vboolf4 operator <=( const vint4& a, const vint4& b ) { return !(a > b); }
#endif
__forceinline vboolf4 operator ==(const vint4& a, int b) { return a == vint4(b); }
__forceinline vboolf4 operator ==(int a, const vint4& b) { return vint4(a) == b; }
__forceinline const vboolf4 operator ==( const vint4& a, const int& b ) { return a == vint4(b); }
__forceinline const vboolf4 operator ==( const int& a, const vint4& b ) { return vint4(a) == b; }
__forceinline vboolf4 operator !=(const vint4& a, int b) { return a != vint4(b); }
__forceinline vboolf4 operator !=(int a, const vint4& b) { return vint4(a) != b; }
__forceinline const vboolf4 operator !=( const vint4& a, const int& b ) { return a != vint4(b); }
__forceinline const vboolf4 operator !=( const int& a, const vint4& b ) { return vint4(a) != b; }
__forceinline vboolf4 operator < (const vint4& a, int b) { return a < vint4(b); }
__forceinline vboolf4 operator < (int a, const vint4& b) { return vint4(a) < b; }
__forceinline const vboolf4 operator < ( const vint4& a, const int& b ) { return a < vint4(b); }
__forceinline const vboolf4 operator < ( const int& a, const vint4& b ) { return vint4(a) < b; }
__forceinline vboolf4 operator >=(const vint4& a, int b) { return a >= vint4(b); }
__forceinline vboolf4 operator >=(int a, const vint4& b) { return vint4(a) >= b; }
__forceinline const vboolf4 operator >=( const vint4& a, const int& b ) { return a >= vint4(b); }
__forceinline const vboolf4 operator >=( const int& a, const vint4& b ) { return vint4(a) >= b; }
__forceinline vboolf4 operator > (const vint4& a, int b) { return a > vint4(b); }
__forceinline vboolf4 operator > (int a, const vint4& b) { return vint4(a) > b; }
__forceinline const vboolf4 operator > ( const vint4& a, const int& b ) { return a > vint4(b); }
__forceinline const vboolf4 operator > ( const int& a, const vint4& b ) { return vint4(a) > b; }
__forceinline vboolf4 operator <=(const vint4& a, int b) { return a <= vint4(b); }
__forceinline vboolf4 operator <=(int a, const vint4& b) { return vint4(a) <= b; }
__forceinline const vboolf4 operator <=( const vint4& a, const int& b ) { return a <= vint4(b); }
__forceinline const vboolf4 operator <=( const int& a, const vint4& b ) { return vint4(a) <= b; }
__forceinline vboolf4 eq(const vint4& a, const vint4& b) { return a == b; }
__forceinline vboolf4 ne(const vint4& a, const vint4& b) { return a != b; }
__forceinline vboolf4 lt(const vint4& a, const vint4& b) { return a < b; }
__forceinline vboolf4 ge(const vint4& a, const vint4& b) { return a >= b; }
__forceinline vboolf4 gt(const vint4& a, const vint4& b) { return a > b; }
__forceinline vboolf4 le(const vint4& a, const vint4& b) { return a <= b; }
#if defined(__AVX512VL__)
__forceinline vboolf4 eq(const vboolf4& mask, const vint4& a, const vint4& b) { return _mm_mask_cmp_epi32_mask(mask, a, b, _MM_CMPINT_EQ); }
__forceinline vboolf4 ne(const vboolf4& mask, const vint4& a, const vint4& b) { return _mm_mask_cmp_epi32_mask(mask, a, b, _MM_CMPINT_NE); }
__forceinline vboolf4 lt(const vboolf4& mask, const vint4& a, const vint4& b) { return _mm_mask_cmp_epi32_mask(mask, a, b, _MM_CMPINT_LT); }
__forceinline vboolf4 ge(const vboolf4& mask, const vint4& a, const vint4& b) { return _mm_mask_cmp_epi32_mask(mask, a, b, _MM_CMPINT_GE); }
__forceinline vboolf4 gt(const vboolf4& mask, const vint4& a, const vint4& b) { return _mm_mask_cmp_epi32_mask(mask, a, b, _MM_CMPINT_GT); }
__forceinline vboolf4 le(const vboolf4& mask, const vint4& a, const vint4& b) { return _mm_mask_cmp_epi32_mask(mask, a, b, _MM_CMPINT_LE); }
#else
__forceinline vboolf4 eq(const vboolf4& mask, const vint4& a, const vint4& b) { return mask & (a == b); }
__forceinline vboolf4 ne(const vboolf4& mask, const vint4& a, const vint4& b) { return mask & (a != b); }
__forceinline vboolf4 lt(const vboolf4& mask, const vint4& a, const vint4& b) { return mask & (a < b); }
__forceinline vboolf4 ge(const vboolf4& mask, const vint4& a, const vint4& b) { return mask & (a >= b); }
__forceinline vboolf4 gt(const vboolf4& mask, const vint4& a, const vint4& b) { return mask & (a > b); }
__forceinline vboolf4 le(const vboolf4& mask, const vint4& a, const vint4& b) { return mask & (a <= b); }
#endif
template<int mask>
__forceinline vint4 select(const vint4& t, const vint4& f) {
#if defined(__SSE4_1__)
return _mm_castps_si128(_mm_blend_ps(_mm_castsi128_ps(f), _mm_castsi128_ps(t), mask));
#else
return select(vboolf4(mask), t, f);
#endif
#if defined(__clang__) && !defined(__INTEL_COMPILER) || defined(_MSC_VER) && !defined(__INTEL_COMPILER) || defined(__GNUC__) && !defined(__INTEL_COMPILER) // still required for clang
__forceinline const vint4 select(const int mask, const vint4& t, const vint4& f) {
return select(vboolf4(mask), t, f);
}
#if defined(__SSE4_1__)
__forceinline vint4 min(const vint4& a, const vint4& b) { return _mm_min_epi32(a, b); }
__forceinline vint4 max(const vint4& a, const vint4& b) { return _mm_max_epi32(a, b); }
__forceinline vint4 umin(const vint4& a, const vint4& b) { return _mm_min_epu32(a, b); }
__forceinline vint4 umax(const vint4& a, const vint4& b) { return _mm_max_epu32(a, b); }
#else
__forceinline vint4 min(const vint4& a, const vint4& b) { return select(a < b,a,b); }
__forceinline vint4 max(const vint4& a, const vint4& b) { return select(a < b,b,a); }
__forceinline const vint4 select(const int m, const vint4& t, const vint4& f) {
return _mm_castps_si128(_mm_blend_ps(_mm_castsi128_ps(f), _mm_castsi128_ps(t), m));
}
#endif
#endif
__forceinline vint4 min(const vint4& a, int b) { return min(a,vint4(b)); }
__forceinline vint4 min(int a, const vint4& b) { return min(vint4(a),b); }
__forceinline vint4 max(const vint4& a, int b) { return max(a,vint4(b)); }
__forceinline vint4 max(int a, const vint4& b) { return max(vint4(a),b); }
////////////////////////////////////////////////////////////////////////////////
// Movement/Shifting/Shuffling Functions
////////////////////////////////////////////////////////////////////////////////
__forceinline vint4 unpacklo(const vint4& a, const vint4& b) { return _mm_castps_si128(_mm_unpacklo_ps(_mm_castsi128_ps(a), _mm_castsi128_ps(b))); }
__forceinline vint4 unpackhi(const vint4& a, const vint4& b) { return _mm_castps_si128(_mm_unpackhi_ps(_mm_castsi128_ps(a), _mm_castsi128_ps(b))); }
__forceinline vint4 unpacklo( const vint4& a, const vint4& b ) { return _mm_castps_si128(_mm_unpacklo_ps(_mm_castsi128_ps(a.v), _mm_castsi128_ps(b.v))); }
__forceinline vint4 unpackhi( const vint4& a, const vint4& b ) { return _mm_castps_si128(_mm_unpackhi_ps(_mm_castsi128_ps(a.v), _mm_castsi128_ps(b.v))); }
template<int i0, int i1, int i2, int i3>
__forceinline vint4 shuffle(const vint4& v) {
return _mm_shuffle_epi32(v, _MM_SHUFFLE(i3, i2, i1, i0));
template<size_t i0, size_t i1, size_t i2, size_t i3> __forceinline const vint4 shuffle( const vint4& a ) {
return _mm_shuffle_epi32(a, _MM_SHUFFLE(i3, i2, i1, i0));
}
template<int i0, int i1, int i2, int i3>
__forceinline vint4 shuffle(const vint4& a, const vint4& b) {
template<size_t i0, size_t i1, size_t i2, size_t i3> __forceinline const vint4 shuffle( const vint4& a, const vint4& b ) {
return _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(a), _mm_castsi128_ps(b), _MM_SHUFFLE(i3, i2, i1, i0)));
}
#if defined(__SSE3__)
template<> __forceinline vint4 shuffle<0, 0, 2, 2>(const vint4& v) { return _mm_castps_si128(_mm_moveldup_ps(_mm_castsi128_ps(v))); }
template<> __forceinline vint4 shuffle<1, 1, 3, 3>(const vint4& v) { return _mm_castps_si128(_mm_movehdup_ps(_mm_castsi128_ps(v))); }
template<> __forceinline vint4 shuffle<0, 1, 0, 1>(const vint4& v) { return _mm_castpd_si128(_mm_movedup_pd (_mm_castsi128_pd(v))); }
template<> __forceinline const vint4 shuffle<0, 0, 2, 2>( const vint4& a ) { return _mm_castps_si128(_mm_moveldup_ps(_mm_castsi128_ps(a))); }
template<> __forceinline const vint4 shuffle<1, 1, 3, 3>( const vint4& a ) { return _mm_castps_si128(_mm_movehdup_ps(_mm_castsi128_ps(a))); }
template<> __forceinline const vint4 shuffle<0, 1, 0, 1>( const vint4& a ) { return _mm_castpd_si128(_mm_movedup_pd (_mm_castsi128_pd(a))); }
#endif
template<int i>
__forceinline vint4 shuffle(const vint4& v) {
return shuffle<i,i,i,i>(v);
template<size_t i0> __forceinline const vint4 shuffle( const vint4& b ) {
return shuffle<i0,i0,i0,i0>(b);
}
#if defined(__SSE4_1__)
template<int src> __forceinline int extract(const vint4& b) { return _mm_extract_epi32(b, src); }
template<int dst> __forceinline vint4 insert(const vint4& a, const int b) { return _mm_insert_epi32(a, b, dst); }
template<size_t src> __forceinline int extract( const vint4& b ) { return _mm_extract_epi32(b, src); }
template<size_t dst> __forceinline const vint4 insert( const vint4& a, const int b ) { return _mm_insert_epi32(a, b, dst); }
#else
template<int src> __forceinline int extract(const vint4& b) { return b[src&3]; }
template<int dst> __forceinline vint4 insert(const vint4& a, int b) { vint4 c = a; c[dst&3] = b; return c; }
template<size_t src> __forceinline int extract( const vint4& b ) { return b[src]; }
template<size_t dst> __forceinline const vint4 insert( const vint4& a, const int b ) { vint4 c = a; c[dst] = b; return c; }
#endif
template<> __forceinline int extract<0>(const vint4& b) { return _mm_cvtsi128_si32(b); }
template<> __forceinline int extract<0>( const vint4& b ) { return _mm_cvtsi128_si32(b); }
__forceinline int toScalar(const vint4& 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
__forceinline int toScalar(const vint4& a) { return _mm_cvtsi128_si32(a); }
////////////////////////////////////////////////////////////////////////////////
/// Reductions
////////////////////////////////////////////////////////////////////////////////
#if defined(__SSE4_1__)
__forceinline vint4 vreduce_min(const vint4& v) { vint4 h = min(shuffle<1,0,3,2>(v),v); return min(shuffle<2,3,0,1>(h),h); }
__forceinline vint4 vreduce_max(const vint4& v) { vint4 h = max(shuffle<1,0,3,2>(v),v); return max(shuffle<2,3,0,1>(h),h); }
__forceinline vint4 vreduce_add(const vint4& v) { vint4 h = shuffle<1,0,3,2>(v) + v ; return shuffle<2,3,0,1>(h) + h ; }
__forceinline const vint4 vreduce_min(const vint4& v) { vint4 h = min(shuffle<1,0,3,2>(v),v); return min(shuffle<2,3,0,1>(h),h); }
__forceinline const vint4 vreduce_max(const vint4& v) { vint4 h = max(shuffle<1,0,3,2>(v),v); return max(shuffle<2,3,0,1>(h),h); }
__forceinline const vint4 vreduce_add(const vint4& v) { vint4 h = shuffle<1,0,3,2>(v) + v ; return shuffle<2,3,0,1>(h) + h ; }
__forceinline int reduce_min(const vint4& v) { return toScalar(vreduce_min(v)); }
__forceinline int reduce_max(const vint4& v) { return toScalar(vreduce_max(v)); }
@@ -452,88 +381,30 @@ namespace embree
////////////////////////////////////////////////////////////////////////////////
#if defined(__SSE4_1__)
__forceinline vint4 usort_ascending(const vint4& v)
__forceinline vint4 sortNetwork(const vint4& v)
{
const vint4 a0 = v;
const vint4 b0 = shuffle<1,0,3,2>(a0);
const vint4 c0 = umin(a0,b0);
const vint4 d0 = umax(a0,b0);
const vint4 a1 = select<0x5 /* 0b0101 */>(c0,d0);
const vint4 a1 = select(0x5 /* 0b0101 */,c0,d0);
const vint4 b1 = shuffle<2,3,0,1>(a1);
const vint4 c1 = umin(a1,b1);
const vint4 d1 = umax(a1,b1);
const vint4 a2 = select<0x3 /* 0b0011 */>(c1,d1);
const vint4 a2 = select(0x3 /* 0b0011 */,c1,d1);
const vint4 b2 = shuffle<0,2,1,3>(a2);
const vint4 c2 = umin(a2,b2);
const vint4 d2 = umax(a2,b2);
const vint4 a3 = select<0x2 /* 0b0010 */>(c2,d2);
const vint4 a3 = select(0x2 /* 0b0010 */,c2,d2);
return a3;
}
__forceinline vint4 usort_descending(const vint4& v)
{
const vint4 a0 = v;
const vint4 b0 = shuffle<1,0,3,2>(a0);
const vint4 c0 = umax(a0,b0);
const vint4 d0 = umin(a0,b0);
const vint4 a1 = select<0x5 /* 0b0101 */>(c0,d0);
const vint4 b1 = shuffle<2,3,0,1>(a1);
const vint4 c1 = umax(a1,b1);
const vint4 d1 = umin(a1,b1);
const vint4 a2 = select<0x3 /* 0b0011 */>(c1,d1);
const vint4 b2 = shuffle<0,2,1,3>(a2);
const vint4 c2 = umax(a2,b2);
const vint4 d2 = umin(a2,b2);
const vint4 a3 = select<0x2 /* 0b0010 */>(c2,d2);
return a3;
}
#else
__forceinline vint4 usort_ascending(const vint4& v)
{
const vint4 a0 = v-vint4(0x80000000);
const vint4 b0 = shuffle<1,0,3,2>(a0);
const vint4 c0 = min(a0,b0);
const vint4 d0 = max(a0,b0);
const vint4 a1 = select<0x5 /* 0b0101 */>(c0,d0);
const vint4 b1 = shuffle<2,3,0,1>(a1);
const vint4 c1 = min(a1,b1);
const vint4 d1 = max(a1,b1);
const vint4 a2 = select<0x3 /* 0b0011 */>(c1,d1);
const vint4 b2 = shuffle<0,2,1,3>(a2);
const vint4 c2 = min(a2,b2);
const vint4 d2 = max(a2,b2);
const vint4 a3 = select<0x2 /* 0b0010 */>(c2,d2);
return a3+vint4(0x80000000);
}
__forceinline vint4 usort_descending(const vint4& v)
{
const vint4 a0 = v-vint4(0x80000000);
const vint4 b0 = shuffle<1,0,3,2>(a0);
const vint4 c0 = max(a0,b0);
const vint4 d0 = min(a0,b0);
const vint4 a1 = select<0x5 /* 0b0101 */>(c0,d0);
const vint4 b1 = shuffle<2,3,0,1>(a1);
const vint4 c1 = max(a1,b1);
const vint4 d1 = min(a1,b1);
const vint4 a2 = select<0x3 /* 0b0011 */>(c1,d1);
const vint4 b2 = shuffle<0,2,1,3>(a2);
const vint4 c2 = max(a2,b2);
const vint4 d2 = min(a2,b2);
const vint4 a3 = select<0x2 /* 0b0010 */>(c2,d2);
return a3+vint4(0x80000000);
}
#endif
////////////////////////////////////////////////////////////////////////////////
/// Output Operators
////////////////////////////////////////////////////////////////////////////////
inline std::ostream& operator <<(std::ostream& cout, const vint4& a) {
inline std::ostream& operator<<(std::ostream& cout, const vint4& a) {
return cout << "<" << a[0] << ", " << a[1] << ", " << a[2] << ", " << a[3] << ">";
}
}

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