Compare commits
288 Commits
node-tree-
...
gpu-shader
Author | SHA1 | Date | |
---|---|---|---|
f240ac1673 | |||
a590474f4c | |||
b2462b6f5c | |||
21ee89c52f | |||
2c95da88aa | |||
7358a5aba2 | |||
9159295c3c | |||
62a04f7aa6 | |||
38a3819171 | |||
3844e9dbe7 | |||
ea93e5df6c | |||
60befc8f02 | |||
62b50c612f | |||
9e5aae4215 | |||
c09e8a3590 | |||
792badcfef | |||
c0a2b21744 | |||
fb4851fbbc | |||
b40e930ac7 | |||
cf266ecaa6 | |||
e4986f92f3 | |||
fab39440e9 | |||
a9eb4e6f59 | |||
a6b7f32112 | |||
db450c9320 | |||
70424195a8 | |||
71c80bd939 | |||
2cbb9d7a76 | |||
b716a771b4 | |||
![]() |
3bb8d173e7 | ||
fca8eb0185 | |||
2c2b79191f | |||
1a7c32a0ab | |||
4b13dcaf02 | |||
ceb25cbeba | |||
8897e0aa8f | |||
5efddc4347 | |||
1df8abff25 | |||
47276b8470 | |||
0bedd5d14f | |||
436ce22194 | |||
dab04bc053 | |||
d7b7cbb047 | |||
0479a66313 | |||
611e4ffaab | |||
89b927a720 | |||
fecdf9d44b | |||
b7c98c87ac | |||
a6d1a2d3fc | |||
![]() |
bba6fe83e2 | ||
6ab3349bd4 | |||
cf299bee80 | |||
3e65bb86f9 | |||
f392ce50c4 | |||
cd2849c89b | |||
605cdc4346 | |||
0452a04f1a | |||
6c8f73b220 | |||
b9b98448a6 | |||
fbb4a7eb43 | |||
f657356062 | |||
b02ac2d8be | |||
84be741329 | |||
6987060f70 | |||
28870a8f89 | |||
59754ef0b2 | |||
![]() |
34370d9fdf | ||
![]() |
b42494cf6b | ||
d1a4e043bd | |||
![]() |
f749506163 | ||
8600d4491f | |||
456d5e14b8 | |||
481f032f5c | |||
34615cd269 | |||
48c2b4012f | |||
29681f186e | |||
e2b736aa40 | |||
![]() |
73b1ad1920 | ||
bfff9ca5f1 | |||
![]() |
ee0277271c | ||
cc6bcb53b2 | |||
5ad4ca4e02 | |||
8a84a61f6b | |||
0129178376 | |||
55c82d8380 | |||
1706bf7780 | |||
336ca6796a | |||
25c83c217b | |||
059da44fbc | |||
d7cf7d4048 | |||
fe274d91a1 | |||
9c2a4d158c | |||
875f24352a | |||
![]() |
0624235900 | ||
be876b8db6 | |||
178947dec3 | |||
![]() |
819b9bdfa1 | ||
77ddc6e350 | |||
7e8f9213e9 | |||
7b09213f2f | |||
9b6f3d2d0a | |||
9bbb5f5a6a | |||
29f6ec56e6 | |||
0b246ed813 | |||
31864a40ba | |||
c850189adf | |||
db20837c3a | |||
6c16bb2706 | |||
6eaa69c66c | |||
fb470c256a | |||
873f6148ad | |||
940e6525c7 | |||
15011e0b70 | |||
6ee2abde82 | |||
d455eadcd8 | |||
b3ee9f44cf | |||
1b2ee3cf20 | |||
e949ac0bfc | |||
59ffe1c5b1 | |||
![]() |
f2bb42a095 | ||
3d447b6335 | |||
b20997cb34 | |||
3baaab15fc | |||
411261fb32 | |||
092df87534 | |||
15ecd47b96 | |||
01df48a983 | |||
a0780ad625 | |||
cfbc9df60e | |||
217d0a1524 | |||
51a7961e09 | |||
c3fed4d463 | |||
fb0ea94c63 | |||
50ad0e15fe | |||
00e4d665f4 | |||
fabd088067 | |||
1222c45544 | |||
ba8dd0f24f | |||
06a2e2b28c | |||
ef687bd7c2 | |||
97533eede4 | |||
1b686c60b5 | |||
0f1a200a67 | |||
9e3a913b35 | |||
1a1ddcb5e2 | |||
ec71054a9b | |||
06ead314b6 | |||
330290d2a8 | |||
33c5e7bcd5 | |||
d6ea881a74 | |||
d7aaa145c6 | |||
04ec36f677 | |||
0852805ed7 | |||
a20e703d1a | |||
06691d1b21 | |||
1b94c53aa6 | |||
7d5ef64bfb | |||
fa6a913ef1 | |||
83e245023c | |||
eb071c9ff4 | |||
de3fda29c7 | |||
48e64a5fb5 | |||
4ea6b4ba84 | |||
992634427e | |||
b8dc845e57 | |||
4d09a692e2 | |||
5ed3a5d023 | |||
3f288e9414 | |||
b2d37c35d0 | |||
167ee8f2c7 | |||
fd2a155d06 | |||
f190f2d267 | |||
0c33411bdd | |||
ea42c1a22e | |||
f61a73093b | |||
ada6742601 | |||
701f2dfd5b | |||
b8bf40ed4b | |||
717a971035 | |||
![]() |
2a9cfdac7e | ||
c7f9a782aa | |||
![]() |
25fa6c74b9 | ||
7c4e4d605c | |||
3531021d1b | |||
12fc395436 | |||
![]() |
805181bffa | ||
77df32548b | |||
![]() |
5e6fdaa07f | ||
![]() |
1d1855e95f | ||
cb3ba68ec4 | |||
![]() |
f19bd637e2 | ||
f0be276514 | |||
ed91e759d1 | |||
67b4eecac9 | |||
![]() |
dd31b8bd50 | ||
5816eb4c56 | |||
8d1357ea6b | |||
beb9e332ca | |||
31afa1bb9a | |||
0624acf088 | |||
b926f54f3c | |||
d1f944c186 | |||
d19e35873f | |||
c0d52db783 | |||
f71813204c | |||
3ad2bf1327 | |||
bd2e3bb7bd | |||
2b63a76041 | |||
e5774282b9 | |||
![]() |
e1a3b697ec | ||
![]() |
8c0370ef7b | ||
![]() |
9cf3d841a8 | ||
f1f7a8b018 | |||
a182b05f07 | |||
032ab0270d | |||
![]() |
daaa43232d | ||
ceec400975 | |||
d8fd575af9 | |||
d6b5251572 | |||
b071083496 | |||
fa7a6d67a8 | |||
![]() |
d9bc8f189c | ||
063ad8635e | |||
9937d5379c | |||
89d5714d8f | |||
ea7efa5569 | |||
00a9617f92 | |||
c3422c48ad | |||
e5f05bc7a6 | |||
f5dde382af | |||
83a4d51997 | |||
c2ab47e729 | |||
51b8e34fb7 | |||
473be239c3 | |||
e3c974b7e4 | |||
6e6123b40f | |||
ecad33f214 | |||
61bffa565e | |||
f72dc00569 | |||
9bdf3fa5f0 | |||
4c988eb3e1 | |||
![]() |
dea26253a0 | ||
8290edefad | |||
2f39b45e8c | |||
f829b86039 | |||
93f26d652e | |||
fbf4fe6963 | |||
1e4d1eb398 | |||
59da22c309 | |||
b496c1c721 | |||
3189171a94 | |||
cf83719761 | |||
c9fb08e075 | |||
f30e1fd2f0 | |||
25d30e6c99 | |||
cfd0e96e47 | |||
7293c1b357 | |||
![]() |
9d7422b817 | ||
917218269e | |||
1572c4d3d3 | |||
bd37553850 | |||
0335df9384 | |||
ba6427adfa | |||
b3529ecf0e | |||
72ee62e0da | |||
bee7a56687 | |||
07af45eec5 | |||
![]() |
64003fa4b0 | ||
85ac9b8584 | |||
ce0d817bb7 | |||
12a986c9b5 | |||
c7a1e115b5 | |||
faa8aa3bb9 | |||
052c22199d | |||
7da714f387 | |||
![]() |
da14a482f2 | ||
d4c868da9f | |||
6d35972b06 | |||
7d985d6b69 | |||
57ed435def | |||
7e42ae7c1a | |||
165cacc6f0 | |||
62da6ffe08 | |||
46f5f60c13 | |||
a040d2a93a | |||
7e148c45c8 | |||
d3c45e1c39 | |||
ef8240e64c |
@@ -269,5 +269,9 @@ StatementMacros:
|
||||
- PyObject_HEAD
|
||||
- PyObject_VAR_HEAD
|
||||
|
||||
StatementMacros:
|
||||
- GPU_STAGE_INTERFACE_CREATE
|
||||
- GPU_SHADER_DESCRIPTOR
|
||||
|
||||
MacroBlockBegin: "^BSDF_CLOSURE_CLASS_BEGIN$"
|
||||
MacroBlockEnd: "^BSDF_CLOSURE_CLASS_END$"
|
||||
|
@@ -12,6 +12,8 @@ Checks: >
|
||||
-readability-avoid-const-params-in-decls,
|
||||
-readability-simplify-boolean-expr,
|
||||
-readability-make-member-function-const,
|
||||
-readability-suspicious-call-argument,
|
||||
-readability-redundant-member-init,
|
||||
|
||||
-readability-misleading-indentation,
|
||||
|
||||
@@ -25,6 +27,8 @@ Checks: >
|
||||
-bugprone-branch-clone,
|
||||
-bugprone-macro-parentheses,
|
||||
-bugprone-reserved-identifier,
|
||||
-bugprone-easily-swappable-parameters,
|
||||
-bugprone-implicit-widening-of-multiplication-result,
|
||||
|
||||
-bugprone-sizeof-expression,
|
||||
-bugprone-integer-division,
|
||||
@@ -40,7 +44,8 @@ Checks: >
|
||||
-modernize-pass-by-value,
|
||||
# Cannot be enabled yet, because using raw string literals in tests breaks
|
||||
# the windows compiler currently.
|
||||
-modernize-raw-string-literal
|
||||
-modernize-raw-string-literal,
|
||||
-modernize-return-braced-init-list
|
||||
|
||||
CheckOptions:
|
||||
- key: modernize-use-default-member-init.UseAssignment
|
||||
|
@@ -411,6 +411,7 @@ option(WITH_CYCLES "Enable Cycles Render Engine" ON)
|
||||
option(WITH_CYCLES_OSL "Build Cycles with OpenShadingLanguage support" ON)
|
||||
option(WITH_CYCLES_EMBREE "Build Cycles with Embree support" ON)
|
||||
option(WITH_CYCLES_LOGGING "Build Cycles with logging support" ON)
|
||||
option(WITH_CYCLES_DEBUG "Build Cycles with options useful for debugging (e.g., MIS)" OFF)
|
||||
|
||||
option(WITH_CYCLES_STANDALONE "Build Cycles standalone application" OFF)
|
||||
option(WITH_CYCLES_STANDALONE_GUI "Build Cycles standalone with GUI" OFF)
|
||||
@@ -1069,7 +1070,7 @@ if(MSVC)
|
||||
add_definitions(-D__LITTLE_ENDIAN__)
|
||||
|
||||
# OSX-Note: as we do cross-compiling with specific set architecture,
|
||||
# endianess-detection and auto-setting is counterproductive
|
||||
# endianness-detection and auto-setting is counterproductive
|
||||
# so we just set endianness according CMAKE_OSX_ARCHITECTURES
|
||||
|
||||
elseif(CMAKE_OSX_ARCHITECTURES MATCHES i386 OR CMAKE_OSX_ARCHITECTURES MATCHES x86_64 OR CMAKE_OSX_ARCHITECTURES MATCHES arm64)
|
||||
@@ -1759,7 +1760,7 @@ endif()
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
# If C++17 is not available, downgrading to an earlier standard is NOT OK.
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
# Do not enable compiler specific language extentions.
|
||||
# Do not enable compiler specific language extensions.
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
|
||||
# Make MSVC properly report the value of the __cplusplus preprocessor macro
|
||||
|
@@ -51,7 +51,7 @@ Other Convenience Targets
|
||||
* config: Run cmake configuration tool to set build options.
|
||||
* deps: Build library dependencies (intended only for platform maintainers).
|
||||
|
||||
The existance of locally build dependancies overrides the pre-built dependencies from subversion.
|
||||
The existance of locally build dependencies overrides the pre-built dependencies from subversion.
|
||||
These must be manually removed from '../lib/' to go back to using the pre-compiled libraries.
|
||||
|
||||
Project Files
|
||||
|
@@ -17,7 +17,7 @@
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
|
||||
########################################################################
|
||||
# Copy all generated files to the proper strucure as blender prefers
|
||||
# Copy all generated files to the proper structure as blender prefers
|
||||
########################################################################
|
||||
|
||||
if(NOT DEFINED HARVEST_TARGET)
|
||||
|
@@ -42,6 +42,7 @@ ExternalProject_Add(nanovdb
|
||||
URL_HASH ${NANOVDB_HASH_TYPE}=${NANOVDB_HASH}
|
||||
PREFIX ${BUILD_DIR}/nanovdb
|
||||
SOURCE_SUBDIR nanovdb
|
||||
PATCH_COMMAND ${PATCH_CMD} -p 1 -d ${BUILD_DIR}/nanovdb/src/nanovdb < ${PATCH_DIR}/nanovdb.diff
|
||||
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/nanovdb ${DEFAULT_CMAKE_FLAGS} ${NANOVDB_EXTRA_ARGS}
|
||||
INSTALL_DIR ${LIBDIR}/nanovdb
|
||||
)
|
||||
|
@@ -39,7 +39,7 @@ endif()
|
||||
set(DOWNLOAD_DIR "${CMAKE_CURRENT_BINARY_DIR}/downloads" CACHE STRING "Path for downloaded files")
|
||||
# This path must be hard-coded like this, so that the GNUmakefile knows where it is and can pass it to make_source_archive.py:
|
||||
set(PACKAGE_DIR "${CMAKE_CURRENT_BINARY_DIR}/packages")
|
||||
option(PACKAGE_USE_UPSTREAM_SOURCES "Use soures upstream to download the package sources, when OFF the blender mirror will be used" ON)
|
||||
option(PACKAGE_USE_UPSTREAM_SOURCES "Use sources upstream to download the package sources, when OFF the blender mirror will be used" ON)
|
||||
|
||||
file(TO_CMAKE_PATH ${DOWNLOAD_DIR} DOWNLOAD_DIR)
|
||||
file(TO_CMAKE_PATH ${PACKAGE_DIR} PACKAGE_DIR)
|
||||
|
@@ -24,7 +24,7 @@ if(MSVC)
|
||||
add_custom_command(
|
||||
OUTPUT ${PYTARGET}/bin/python${PYTHON_POSTFIX}.exe
|
||||
COMMAND echo packaging python
|
||||
COMMAND echo this should ouput at ${PYTARGET}/bin/python${PYTHON_POSTFIX}.exe
|
||||
COMMAND echo this should output at ${PYTARGET}/bin/python${PYTHON_POSTFIX}.exe
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${PYTARGET}/libs
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${PYSRC}/libs/python${PYTHON_SHORT_VERSION_NO_DOTS}.lib ${PYTARGET}/libs/python${PYTHON_SHORT_VERSION_NO_DOTS}.lib
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${PYSRC}/python.exe ${PYTARGET}/bin/python.exe
|
||||
@@ -43,7 +43,7 @@ if(MSVC)
|
||||
add_custom_command(
|
||||
OUTPUT ${PYTARGET}/bin/python${PYTHON_POSTFIX}.exe
|
||||
COMMAND echo packaging python
|
||||
COMMAND echo this should ouput at ${PYTARGET}/bin/python${PYTHON_POSTFIX}.exe
|
||||
COMMAND echo this should output at ${PYTARGET}/bin/python${PYTHON_POSTFIX}.exe
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${PYTARGET}/libs
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${PYSRC}/libs/python${PYTHON_SHORT_VERSION_NO_DOTS}${PYTHON_POSTFIX}.lib ${PYTARGET}/libs/python${PYTHON_SHORT_VERSION_NO_DOTS}${PYTHON_POSTFIX}.lib
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${PYSRC}/python${PYTHON_POSTFIX}.exe ${PYTARGET}/bin/python${PYTHON_POSTFIX}.exe
|
||||
|
@@ -1826,7 +1826,7 @@ compile_OCIO() {
|
||||
# Force linking against static libs
|
||||
#rm -f $_inst/lib/*.so*
|
||||
|
||||
# Additional depencencies
|
||||
# Additional dependencies
|
||||
#cp ext/dist/lib/libtinyxml.a $_inst/lib
|
||||
#cp ext/dist/lib/libyaml-cpp.a $_inst/lib
|
||||
|
||||
|
374
build_files/build_environment/patches/nanovdb.diff
Normal file
374
build_files/build_environment/patches/nanovdb.diff
Normal file
@@ -0,0 +1,374 @@
|
||||
Index: nanovdb/nanovdb/NanoVDB.h
|
||||
===================================================================
|
||||
--- a/nanovdb/nanovdb/NanoVDB.h (revision 62751)
|
||||
+++ b/nanovdb/nanovdb/NanoVDB.h (working copy)
|
||||
@@ -152,8 +152,8 @@
|
||||
|
||||
#endif // __CUDACC_RTC__
|
||||
|
||||
-#ifdef __CUDACC__
|
||||
-// Only define __hostdev__ when using NVIDIA CUDA compiler
|
||||
+#if defined(__CUDACC__) || defined(__HIP__)
|
||||
+// Only define __hostdev__ when using NVIDIA CUDA or HIP compiler
|
||||
#define __hostdev__ __host__ __device__
|
||||
#else
|
||||
#define __hostdev__
|
||||
@@ -461,7 +461,7 @@
|
||||
/// Maximum floating-point values
|
||||
template<typename T>
|
||||
struct Maximum;
|
||||
-#ifdef __CUDA_ARCH__
|
||||
+#if defined(__CUDA_ARCH__) || defined(__HIP__)
|
||||
template<>
|
||||
struct Maximum<int>
|
||||
{
|
||||
@@ -1006,10 +1006,10 @@
|
||||
using Vec3i = Vec3<int>;
|
||||
|
||||
/// @brief Return a single precision floating-point vector of this coordinate
|
||||
-Vec3f Coord::asVec3s() const { return Vec3f(float(mVec[0]), float(mVec[1]), float(mVec[2])); }
|
||||
+inline __hostdev__ Vec3f Coord::asVec3s() const { return Vec3f(float(mVec[0]), float(mVec[1]), float(mVec[2])); }
|
||||
|
||||
/// @brief Return a double precision floating-point vector of this coordinate
|
||||
-Vec3d Coord::asVec3d() const { return Vec3d(double(mVec[0]), double(mVec[1]), double(mVec[2])); }
|
||||
+inline __hostdev__ Vec3d Coord::asVec3d() const { return Vec3d(double(mVec[0]), double(mVec[1]), double(mVec[2])); }
|
||||
|
||||
// ----------------------------> Vec4 <--------------------------------------
|
||||
|
||||
@@ -1820,7 +1820,7 @@
|
||||
}; // Map
|
||||
|
||||
template<typename Mat4T>
|
||||
-void Map::set(const Mat4T& mat, const Mat4T& invMat, double taper)
|
||||
+__hostdev__ void Map::set(const Mat4T& mat, const Mat4T& invMat, double taper)
|
||||
{
|
||||
float * mf = mMatF, *vf = mVecF;
|
||||
float* mif = mInvMatF;
|
||||
@@ -2170,7 +2170,7 @@
|
||||
}; // Class Grid
|
||||
|
||||
template<typename TreeT>
|
||||
-int Grid<TreeT>::findBlindDataForSemantic(GridBlindDataSemantic semantic) const
|
||||
+__hostdev__ int Grid<TreeT>::findBlindDataForSemantic(GridBlindDataSemantic semantic) const
|
||||
{
|
||||
for (uint32_t i = 0, n = blindDataCount(); i < n; ++i)
|
||||
if (blindMetaData(i).mSemantic == semantic)
|
||||
@@ -2328,7 +2328,7 @@
|
||||
}; // Tree class
|
||||
|
||||
template<typename RootT>
|
||||
-void Tree<RootT>::extrema(ValueType& min, ValueType& max) const
|
||||
+__hostdev__ void Tree<RootT>::extrema(ValueType& min, ValueType& max) const
|
||||
{
|
||||
min = this->root().valueMin();
|
||||
max = this->root().valueMax();
|
||||
@@ -2336,7 +2336,7 @@
|
||||
|
||||
template<typename RootT>
|
||||
template<typename NodeT>
|
||||
-const NodeT* Tree<RootT>::getNode(uint32_t i) const
|
||||
+__hostdev__ const NodeT* Tree<RootT>::getNode(uint32_t i) const
|
||||
{
|
||||
static_assert(is_same<TreeNodeT<NodeT::LEVEL>, NodeT>::value, "Tree::getNode: unvalid node type");
|
||||
NANOVDB_ASSERT(i < DataType::mCount[NodeT::LEVEL]);
|
||||
@@ -2345,7 +2345,7 @@
|
||||
|
||||
template<typename RootT>
|
||||
template<int LEVEL>
|
||||
-const typename TreeNode<Tree<RootT>, LEVEL>::type* Tree<RootT>::getNode(uint32_t i) const
|
||||
+__hostdev__ const typename TreeNode<Tree<RootT>, LEVEL>::type* Tree<RootT>::getNode(uint32_t i) const
|
||||
{
|
||||
NANOVDB_ASSERT(i < DataType::mCount[LEVEL]);
|
||||
return reinterpret_cast<const TreeNodeT<LEVEL>*>(reinterpret_cast<const uint8_t*>(this) + DataType::mBytes[LEVEL]) + i;
|
||||
@@ -2353,7 +2353,7 @@
|
||||
|
||||
template<typename RootT>
|
||||
template<typename NodeT>
|
||||
-NodeT* Tree<RootT>::getNode(uint32_t i)
|
||||
+__hostdev__ NodeT* Tree<RootT>::getNode(uint32_t i)
|
||||
{
|
||||
static_assert(is_same<TreeNodeT<NodeT::LEVEL>, NodeT>::value, "Tree::getNode: invalid node type");
|
||||
NANOVDB_ASSERT(i < DataType::mCount[NodeT::LEVEL]);
|
||||
@@ -2362,7 +2362,7 @@
|
||||
|
||||
template<typename RootT>
|
||||
template<int LEVEL>
|
||||
-typename TreeNode<Tree<RootT>, LEVEL>::type* Tree<RootT>::getNode(uint32_t i)
|
||||
+__hostdev__ typename TreeNode<Tree<RootT>, LEVEL>::type* Tree<RootT>::getNode(uint32_t i)
|
||||
{
|
||||
NANOVDB_ASSERT(i < DataType::mCount[LEVEL]);
|
||||
return reinterpret_cast<TreeNodeT<LEVEL>*>(reinterpret_cast<uint8_t*>(this) + DataType::mBytes[LEVEL]) + i;
|
||||
@@ -2370,7 +2370,7 @@
|
||||
|
||||
template<typename RootT>
|
||||
template<typename NodeT>
|
||||
-uint32_t Tree<RootT>::getNodeID(const NodeT& node) const
|
||||
+__hostdev__ uint32_t Tree<RootT>::getNodeID(const NodeT& node) const
|
||||
{
|
||||
static_assert(is_same<TreeNodeT<NodeT::LEVEL>, NodeT>::value, "Tree::getNodeID: invalid node type");
|
||||
const NodeT* first = reinterpret_cast<const NodeT*>(reinterpret_cast<const uint8_t*>(this) + DataType::mBytes[NodeT::LEVEL]);
|
||||
@@ -2380,7 +2380,7 @@
|
||||
|
||||
template<typename RootT>
|
||||
template<typename NodeT>
|
||||
-uint32_t Tree<RootT>::getLinearOffset(const NodeT& node) const
|
||||
+__hostdev__ uint32_t Tree<RootT>::getLinearOffset(const NodeT& node) const
|
||||
{
|
||||
return this->getNodeID(node) + DataType::mPFSum[NodeT::LEVEL];
|
||||
}
|
||||
@@ -3366,7 +3366,7 @@
|
||||
}; // LeafNode class
|
||||
|
||||
template<typename ValueT, typename CoordT, template<uint32_t> class MaskT, uint32_t LOG2DIM>
|
||||
-inline void LeafNode<ValueT, CoordT, MaskT, LOG2DIM>::updateBBox()
|
||||
+inline __hostdev__ void LeafNode<ValueT, CoordT, MaskT, LOG2DIM>::updateBBox()
|
||||
{
|
||||
static_assert(LOG2DIM == 3, "LeafNode::updateBBox: only supports LOGDIM = 3!");
|
||||
if (!this->isActive()) return;
|
||||
Index: nanovdb/nanovdb/util/SampleFromVoxels.h
|
||||
===================================================================
|
||||
--- a/nanovdb/nanovdb/util/SampleFromVoxels.h (revision 62751)
|
||||
+++ b/nanovdb/nanovdb/util/SampleFromVoxels.h (working copy)
|
||||
@@ -22,7 +22,7 @@
|
||||
#define NANOVDB_SAMPLE_FROM_VOXELS_H_HAS_BEEN_INCLUDED
|
||||
|
||||
// Only define __hostdev__ when compiling as NVIDIA CUDA
|
||||
-#ifdef __CUDACC__
|
||||
+#if defined(__CUDACC__) || defined(__HIP__)
|
||||
#define __hostdev__ __host__ __device__
|
||||
#else
|
||||
#include <cmath> // for floor
|
||||
@@ -136,7 +136,7 @@
|
||||
|
||||
template<typename TreeOrAccT>
|
||||
template<typename Vec3T>
|
||||
-typename TreeOrAccT::ValueType SampleFromVoxels<TreeOrAccT, 0, true>::operator()(const Vec3T& xyz) const
|
||||
+__hostdev__ typename TreeOrAccT::ValueType SampleFromVoxels<TreeOrAccT, 0, true>::operator()(const Vec3T& xyz) const
|
||||
{
|
||||
const CoordT ijk = Round<CoordT>(xyz);
|
||||
if (ijk != mPos) {
|
||||
@@ -147,7 +147,7 @@
|
||||
}
|
||||
|
||||
template<typename TreeOrAccT>
|
||||
-typename TreeOrAccT::ValueType SampleFromVoxels<TreeOrAccT, 0, true>::operator()(const CoordT& ijk) const
|
||||
+__hostdev__ typename TreeOrAccT::ValueType SampleFromVoxels<TreeOrAccT, 0, true>::operator()(const CoordT& ijk) const
|
||||
{
|
||||
if (ijk != mPos) {
|
||||
mPos = ijk;
|
||||
@@ -158,7 +158,7 @@
|
||||
|
||||
template<typename TreeOrAccT>
|
||||
template<typename Vec3T>
|
||||
-typename TreeOrAccT::ValueType SampleFromVoxels<TreeOrAccT, 0, false>::operator()(const Vec3T& xyz) const
|
||||
+__hostdev__ typename TreeOrAccT::ValueType SampleFromVoxels<TreeOrAccT, 0, false>::operator()(const Vec3T& xyz) const
|
||||
{
|
||||
return mAcc.getValue(Round<CoordT>(xyz));
|
||||
}
|
||||
@@ -195,7 +195,7 @@
|
||||
}; // TrilinearSamplerBase
|
||||
|
||||
template<typename TreeOrAccT>
|
||||
-void TrilinearSampler<TreeOrAccT>::stencil(CoordT& ijk, ValueT (&v)[2][2][2]) const
|
||||
+__hostdev__ void TrilinearSampler<TreeOrAccT>::stencil(CoordT& ijk, ValueT (&v)[2][2][2]) const
|
||||
{
|
||||
v[0][0][0] = mAcc.getValue(ijk); // i, j, k
|
||||
|
||||
@@ -224,7 +224,7 @@
|
||||
|
||||
template<typename TreeOrAccT>
|
||||
template<typename RealT, template<typename...> class Vec3T>
|
||||
-typename TreeOrAccT::ValueType TrilinearSampler<TreeOrAccT>::sample(const Vec3T<RealT> &uvw, const ValueT (&v)[2][2][2])
|
||||
+__hostdev__ typename TreeOrAccT::ValueType TrilinearSampler<TreeOrAccT>::sample(const Vec3T<RealT> &uvw, const ValueT (&v)[2][2][2])
|
||||
{
|
||||
#if 0
|
||||
auto lerp = [](ValueT a, ValueT b, ValueT w){ return fma(w, b-a, a); };// = w*(b-a) + a
|
||||
@@ -239,7 +239,7 @@
|
||||
|
||||
template<typename TreeOrAccT>
|
||||
template<typename RealT, template<typename...> class Vec3T>
|
||||
-Vec3T<typename TreeOrAccT::ValueType> TrilinearSampler<TreeOrAccT>::gradient(const Vec3T<RealT> &uvw, const ValueT (&v)[2][2][2])
|
||||
+__hostdev__ Vec3T<typename TreeOrAccT::ValueType> TrilinearSampler<TreeOrAccT>::gradient(const Vec3T<RealT> &uvw, const ValueT (&v)[2][2][2])
|
||||
{
|
||||
static_assert(std::is_floating_point<ValueT>::value, "TrilinearSampler::gradient requires a floating-point type");
|
||||
#if 0
|
||||
@@ -270,7 +270,7 @@
|
||||
}
|
||||
|
||||
template<typename TreeOrAccT>
|
||||
-bool TrilinearSampler<TreeOrAccT>::zeroCrossing(const ValueT (&v)[2][2][2])
|
||||
+__hostdev__ bool TrilinearSampler<TreeOrAccT>::zeroCrossing(const ValueT (&v)[2][2][2])
|
||||
{
|
||||
static_assert(std::is_floating_point<ValueT>::value, "TrilinearSampler::zeroCrossing requires a floating-point type");
|
||||
const bool less = v[0][0][0] < ValueT(0);
|
||||
@@ -363,7 +363,7 @@
|
||||
|
||||
template<typename TreeOrAccT>
|
||||
template<typename RealT, template<typename...> class Vec3T>
|
||||
-typename TreeOrAccT::ValueType SampleFromVoxels<TreeOrAccT, 1, true>::operator()(Vec3T<RealT> xyz) const
|
||||
+__hostdev__ typename TreeOrAccT::ValueType SampleFromVoxels<TreeOrAccT, 1, true>::operator()(Vec3T<RealT> xyz) const
|
||||
{
|
||||
this->cache(xyz);
|
||||
return BaseT::sample(xyz, mVal);
|
||||
@@ -370,7 +370,7 @@
|
||||
}
|
||||
|
||||
template<typename TreeOrAccT>
|
||||
-typename TreeOrAccT::ValueType SampleFromVoxels<TreeOrAccT, 1, true>::operator()(const CoordT &ijk) const
|
||||
+__hostdev__ typename TreeOrAccT::ValueType SampleFromVoxels<TreeOrAccT, 1, true>::operator()(const CoordT &ijk) const
|
||||
{
|
||||
return ijk == mPos ? mVal[0][0][0] : BaseT::mAcc.getValue(ijk);
|
||||
}
|
||||
@@ -377,7 +377,7 @@
|
||||
|
||||
template<typename TreeOrAccT>
|
||||
template<typename RealT, template<typename...> class Vec3T>
|
||||
-Vec3T<typename TreeOrAccT::ValueType> SampleFromVoxels<TreeOrAccT, 1, true>::gradient(Vec3T<RealT> xyz) const
|
||||
+__hostdev__ Vec3T<typename TreeOrAccT::ValueType> SampleFromVoxels<TreeOrAccT, 1, true>::gradient(Vec3T<RealT> xyz) const
|
||||
{
|
||||
this->cache(xyz);
|
||||
return BaseT::gradient(xyz, mVal);
|
||||
@@ -393,7 +393,7 @@
|
||||
|
||||
template<typename TreeOrAccT>
|
||||
template<typename RealT, template<typename...> class Vec3T>
|
||||
-void SampleFromVoxels<TreeOrAccT, 1, true>::cache(Vec3T<RealT>& xyz) const
|
||||
+__hostdev__ void SampleFromVoxels<TreeOrAccT, 1, true>::cache(Vec3T<RealT>& xyz) const
|
||||
{
|
||||
CoordT ijk = Floor<CoordT>(xyz);
|
||||
if (ijk != mPos) {
|
||||
@@ -406,7 +406,7 @@
|
||||
|
||||
template<typename TreeOrAccT>
|
||||
template<typename RealT, template<typename...> class Vec3T>
|
||||
-typename TreeOrAccT::ValueType SampleFromVoxels<TreeOrAccT, 1, false>::operator()(Vec3T<RealT> xyz) const
|
||||
+__hostdev__ typename TreeOrAccT::ValueType SampleFromVoxels<TreeOrAccT, 1, false>::operator()(Vec3T<RealT> xyz) const
|
||||
{
|
||||
ValueT val[2][2][2];
|
||||
CoordT ijk = Floor<CoordT>(xyz);
|
||||
@@ -418,7 +418,7 @@
|
||||
|
||||
template<typename TreeOrAccT>
|
||||
template<typename RealT, template<typename...> class Vec3T>
|
||||
-typename TreeOrAccT::ValueType SampleFromVoxels<TreeOrAccT, 1, false>::operator()(Vec3T<RealT> xyz) const
|
||||
+__hostdev__ typename TreeOrAccT::ValueType SampleFromVoxels<TreeOrAccT, 1, false>::operator()(Vec3T<RealT> xyz) const
|
||||
{
|
||||
auto lerp = [](ValueT a, ValueT b, RealT w) { return a + ValueT(w) * (b - a); };
|
||||
|
||||
@@ -463,7 +463,7 @@
|
||||
|
||||
template<typename TreeOrAccT>
|
||||
template<typename RealT, template<typename...> class Vec3T>
|
||||
-inline Vec3T<typename TreeOrAccT::ValueType> SampleFromVoxels<TreeOrAccT, 1, false>::gradient(Vec3T<RealT> xyz) const
|
||||
+inline __hostdev__ Vec3T<typename TreeOrAccT::ValueType> SampleFromVoxels<TreeOrAccT, 1, false>::gradient(Vec3T<RealT> xyz) const
|
||||
{
|
||||
ValueT val[2][2][2];
|
||||
CoordT ijk = Floor<CoordT>(xyz);
|
||||
@@ -473,7 +473,7 @@
|
||||
|
||||
template<typename TreeOrAccT>
|
||||
template<typename RealT, template<typename...> class Vec3T>
|
||||
-bool SampleFromVoxels<TreeOrAccT, 1, false>::zeroCrossing(Vec3T<RealT> xyz) const
|
||||
+__hostdev__ bool SampleFromVoxels<TreeOrAccT, 1, false>::zeroCrossing(Vec3T<RealT> xyz) const
|
||||
{
|
||||
ValueT val[2][2][2];
|
||||
CoordT ijk = Floor<CoordT>(xyz);
|
||||
@@ -510,7 +510,7 @@
|
||||
}; // TriquadraticSamplerBase
|
||||
|
||||
template<typename TreeOrAccT>
|
||||
-void TriquadraticSampler<TreeOrAccT>::stencil(const CoordT &ijk, ValueT (&v)[3][3][3]) const
|
||||
+__hostdev__ void TriquadraticSampler<TreeOrAccT>::stencil(const CoordT &ijk, ValueT (&v)[3][3][3]) const
|
||||
{
|
||||
CoordT p(ijk[0] - 1, 0, 0);
|
||||
for (int dx = 0; dx < 3; ++dx, ++p[0]) {
|
||||
@@ -526,7 +526,7 @@
|
||||
|
||||
template<typename TreeOrAccT>
|
||||
template<typename RealT, template<typename...> class Vec3T>
|
||||
-typename TreeOrAccT::ValueType TriquadraticSampler<TreeOrAccT>::sample(const Vec3T<RealT> &uvw, const ValueT (&v)[3][3][3])
|
||||
+__hostdev__ typename TreeOrAccT::ValueType TriquadraticSampler<TreeOrAccT>::sample(const Vec3T<RealT> &uvw, const ValueT (&v)[3][3][3])
|
||||
{
|
||||
auto kernel = [](const ValueT* value, double weight)->ValueT {
|
||||
return weight * (weight * (0.5f * (value[0] + value[2]) - value[1]) +
|
||||
@@ -545,7 +545,7 @@
|
||||
}
|
||||
|
||||
template<typename TreeOrAccT>
|
||||
-bool TriquadraticSampler<TreeOrAccT>::zeroCrossing(const ValueT (&v)[3][3][3])
|
||||
+__hostdev__ bool TriquadraticSampler<TreeOrAccT>::zeroCrossing(const ValueT (&v)[3][3][3])
|
||||
{
|
||||
static_assert(std::is_floating_point<ValueT>::value, "TrilinearSampler::zeroCrossing requires a floating-point type");
|
||||
const bool less = v[0][0][0] < ValueT(0);
|
||||
@@ -624,7 +624,7 @@
|
||||
|
||||
template<typename TreeOrAccT>
|
||||
template<typename RealT, template<typename...> class Vec3T>
|
||||
-typename TreeOrAccT::ValueType SampleFromVoxels<TreeOrAccT, 2, true>::operator()(Vec3T<RealT> xyz) const
|
||||
+__hostdev__ typename TreeOrAccT::ValueType SampleFromVoxels<TreeOrAccT, 2, true>::operator()(Vec3T<RealT> xyz) const
|
||||
{
|
||||
this->cache(xyz);
|
||||
return BaseT::sample(xyz, mVal);
|
||||
@@ -631,7 +631,7 @@
|
||||
}
|
||||
|
||||
template<typename TreeOrAccT>
|
||||
-typename TreeOrAccT::ValueType SampleFromVoxels<TreeOrAccT, 2, true>::operator()(const CoordT &ijk) const
|
||||
+__hostdev__ typename TreeOrAccT::ValueType SampleFromVoxels<TreeOrAccT, 2, true>::operator()(const CoordT &ijk) const
|
||||
{
|
||||
return ijk == mPos ? mVal[1][1][1] : BaseT::mAcc.getValue(ijk);
|
||||
}
|
||||
@@ -646,7 +646,7 @@
|
||||
|
||||
template<typename TreeOrAccT>
|
||||
template<typename RealT, template<typename...> class Vec3T>
|
||||
-void SampleFromVoxels<TreeOrAccT, 2, true>::cache(Vec3T<RealT>& xyz) const
|
||||
+__hostdev__ void SampleFromVoxels<TreeOrAccT, 2, true>::cache(Vec3T<RealT>& xyz) const
|
||||
{
|
||||
CoordT ijk = Floor<CoordT>(xyz);
|
||||
if (ijk != mPos) {
|
||||
@@ -657,7 +657,7 @@
|
||||
|
||||
template<typename TreeOrAccT>
|
||||
template<typename RealT, template<typename...> class Vec3T>
|
||||
-typename TreeOrAccT::ValueType SampleFromVoxels<TreeOrAccT, 2, false>::operator()(Vec3T<RealT> xyz) const
|
||||
+__hostdev__ typename TreeOrAccT::ValueType SampleFromVoxels<TreeOrAccT, 2, false>::operator()(Vec3T<RealT> xyz) const
|
||||
{
|
||||
ValueT val[3][3][3];
|
||||
CoordT ijk = Floor<CoordT>(xyz);
|
||||
@@ -667,7 +667,7 @@
|
||||
|
||||
template<typename TreeOrAccT>
|
||||
template<typename RealT, template<typename...> class Vec3T>
|
||||
-bool SampleFromVoxels<TreeOrAccT, 2, false>::zeroCrossing(Vec3T<RealT> xyz) const
|
||||
+__hostdev__ bool SampleFromVoxels<TreeOrAccT, 2, false>::zeroCrossing(Vec3T<RealT> xyz) const
|
||||
{
|
||||
ValueT val[3][3][3];
|
||||
CoordT ijk = Floor<CoordT>(xyz);
|
||||
@@ -710,7 +710,7 @@
|
||||
}; // TricubicSampler
|
||||
|
||||
template<typename TreeOrAccT>
|
||||
-void TricubicSampler<TreeOrAccT>::stencil(const CoordT& ijk, ValueT (&C)[64]) const
|
||||
+__hostdev__ void TricubicSampler<TreeOrAccT>::stencil(const CoordT& ijk, ValueT (&C)[64]) const
|
||||
{
|
||||
auto fetch = [&](int i, int j, int k) -> ValueT& { return C[((i + 1) << 4) + ((j + 1) << 2) + k + 1]; };
|
||||
|
||||
@@ -929,7 +929,7 @@
|
||||
|
||||
template<typename TreeOrAccT>
|
||||
template<typename RealT, template<typename...> class Vec3T>
|
||||
-typename TreeOrAccT::ValueType SampleFromVoxels<TreeOrAccT, 3, true>::operator()(Vec3T<RealT> xyz) const
|
||||
+__hostdev__ typename TreeOrAccT::ValueType SampleFromVoxels<TreeOrAccT, 3, true>::operator()(Vec3T<RealT> xyz) const
|
||||
{
|
||||
this->cache(xyz);
|
||||
return BaseT::sample(xyz, mC);
|
||||
@@ -937,7 +937,7 @@
|
||||
|
||||
template<typename TreeOrAccT>
|
||||
template<typename RealT, template<typename...> class Vec3T>
|
||||
-void SampleFromVoxels<TreeOrAccT, 3, true>::cache(Vec3T<RealT>& xyz) const
|
||||
+__hostdev__ void SampleFromVoxels<TreeOrAccT, 3, true>::cache(Vec3T<RealT>& xyz) const
|
||||
{
|
||||
CoordT ijk = Floor<CoordT>(xyz);
|
||||
if (ijk != mPos) {
|
@@ -180,7 +180,7 @@ def create_nb_project_main():
|
||||
f.write(' </logicalFolder>\n')
|
||||
|
||||
f.write(' </logicalFolder>\n')
|
||||
# default, but this dir is infact not in blender dir so we can ignore it
|
||||
# default, but this dir is in fact not in blender dir so we can ignore it
|
||||
# f.write(' <sourceFolderFilter>^(nbproject)$</sourceFolderFilter>\n')
|
||||
f.write(r' <sourceFolderFilter>^(nbproject|__pycache__|.*\.py|.*\.html|.*\.blend)$</sourceFolderFilter>\n')
|
||||
|
||||
|
@@ -529,7 +529,7 @@ function(SETUP_LIBDIRS)
|
||||
|
||||
# NOTE: For all new libraries, use absolute library paths.
|
||||
# This should eventually be phased out.
|
||||
# APPLE plaform uses full paths for linking libraries, and avoids link_directories.
|
||||
# APPLE platform uses full paths for linking libraries, and avoids link_directories.
|
||||
if(NOT MSVC AND NOT APPLE)
|
||||
link_directories(${JPEG_LIBPATH} ${PNG_LIBPATH} ${ZLIB_LIBPATH} ${FREETYPE_LIBPATH})
|
||||
|
||||
|
@@ -27,7 +27,7 @@ if(WITH_WINDOWS_BUNDLE_CRT)
|
||||
# Install the CRT to the blender.crt Sub folder.
|
||||
install(FILES ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS} DESTINATION ./blender.crt COMPONENT Libraries)
|
||||
|
||||
# Generating the manifest is a relativly expensive operation since
|
||||
# Generating the manifest is a relatively expensive operation since
|
||||
# it is collecting an sha1 hash for every file required. so only do
|
||||
# this work when the libs have either changed or the manifest does
|
||||
# not exist yet.
|
||||
|
@@ -11,7 +11,7 @@ import queue
|
||||
|
||||
execution_queue = queue.Queue()
|
||||
|
||||
# This function can savely be called in another thread.
|
||||
# This function can safely be called in another thread.
|
||||
# The function will be executed when the timer runs the next time.
|
||||
def run_in_main_thread(function):
|
||||
execution_queue.put(function)
|
||||
|
@@ -42,8 +42,13 @@ class SimpleMouseOperator(bpy.types.Operator):
|
||||
self.y = event.mouse_y
|
||||
return self.execute(context)
|
||||
|
||||
# Only needed if you want to add into a dynamic menu
|
||||
def menu_func(self, context):
|
||||
self.layout.operator(SimpleMouseOperator.bl_idname, text="Simple Mouse Operator")
|
||||
|
||||
# Register and add to the view menu (required to also use F3 search "Simple Mouse Operator" for quick access)
|
||||
bpy.utils.register_class(SimpleMouseOperator)
|
||||
bpy.types.VIEW3D_MT_view.append(menu_func)
|
||||
|
||||
# Test call to the newly defined operator.
|
||||
# Here we call the operator and invoke it, meaning that the settings are taken
|
||||
|
@@ -43,7 +43,7 @@ def menu_func(self, context):
|
||||
self.layout.operator(ExportSomeData.bl_idname, text="Text Export Operator")
|
||||
|
||||
|
||||
# Register and add to the file selector
|
||||
# Register and add to the file selector (required to also use F3 search "Text Export Operator" for quick access)
|
||||
bpy.utils.register_class(ExportSomeData)
|
||||
bpy.types.TOPBAR_MT_file_export.append(menu_func)
|
||||
|
||||
|
@@ -27,8 +27,14 @@ class DialogOperator(bpy.types.Operator):
|
||||
wm = context.window_manager
|
||||
return wm.invoke_props_dialog(self)
|
||||
|
||||
# Only needed if you want to add into a dynamic menu
|
||||
def menu_func(self, context):
|
||||
self.layout.operator(DialogOperator.bl_idname, text="Dialog Operator")
|
||||
|
||||
|
||||
# Register and add to the object menu (required to also use F3 search "Dialog Operator" for quick access)
|
||||
bpy.utils.register_class(DialogOperator)
|
||||
bpy.types.VIEW3D_MT_object.append(menu_func)
|
||||
|
||||
# Test call.
|
||||
bpy.ops.object.dialog_operator('INVOKE_DEFAULT')
|
||||
|
@@ -41,8 +41,13 @@ class CustomDrawOperator(bpy.types.Operator):
|
||||
|
||||
col.prop(self, "my_string")
|
||||
|
||||
# Only needed if you want to add into a dynamic menu
|
||||
def menu_func(self, context):
|
||||
self.layout.operator(CustomDrawOperator.bl_idname, text="Custom Draw Operator")
|
||||
|
||||
# Register and add to the object menu (required to also use F3 search "Custom Draw Operator" for quick access)
|
||||
bpy.utils.register_class(CustomDrawOperator)
|
||||
bpy.types.VIEW3D_MT_object.append(menu_func)
|
||||
|
||||
# test call
|
||||
bpy.ops.object.custom_draw('INVOKE_DEFAULT')
|
||||
|
@@ -55,8 +55,13 @@ class ModalOperator(bpy.types.Operator):
|
||||
context.window_manager.modal_handler_add(self)
|
||||
return {'RUNNING_MODAL'}
|
||||
|
||||
# Only needed if you want to add into a dynamic menu
|
||||
def menu_func(self, context):
|
||||
self.layout.operator(ModalOperator.bl_idname, text="Modal Operator")
|
||||
|
||||
# Register and add to the object menu (required to also use F3 search "Modal Operator" for quick access)
|
||||
bpy.utils.register_class(ModalOperator)
|
||||
bpy.types.VIEW3D_MT_object.append(menu_func)
|
||||
|
||||
# test call
|
||||
bpy.ops.object.modal_operator('INVOKE_DEFAULT')
|
||||
|
@@ -31,8 +31,13 @@ class SearchEnumOperator(bpy.types.Operator):
|
||||
context.window_manager.invoke_search_popup(self)
|
||||
return {'RUNNING_MODAL'}
|
||||
|
||||
# Only needed if you want to add into a dynamic menu
|
||||
def menu_func(self, context):
|
||||
self.layout.operator(SearchEnumOperator.bl_idname, text="Search Enum Operator")
|
||||
|
||||
# Register and add to the object menu (required to also use F3 search "Search Enum Operator" for quick access)
|
||||
bpy.utils.register_class(SearchEnumOperator)
|
||||
bpy.types.VIEW3D_MT_object.append(menu_func)
|
||||
|
||||
# test call
|
||||
bpy.ops.object.search_enum_operator('INVOKE_DEFAULT')
|
||||
|
@@ -22,8 +22,13 @@ class HelloWorldOperator(bpy.types.Operator):
|
||||
print("Hello World")
|
||||
return {'FINISHED'}
|
||||
|
||||
# Only needed if you want to add into a dynamic menu
|
||||
def menu_func(self, context):
|
||||
self.layout.operator(HelloWorldOperator.bl_idname, text="Hello World Operator")
|
||||
|
||||
# Register and add to the view menu (required to also use F3 search "Hello World Operator" for quick access)
|
||||
bpy.utils.register_class(HelloWorldOperator)
|
||||
bpy.types.VIEW3D_MT_view.append(menu_func)
|
||||
|
||||
# test call to the newly defined operator
|
||||
bpy.ops.wm.hello_world()
|
||||
|
@@ -106,24 +106,6 @@ including advanced features.
|
||||
floating-point values. These values are interpreted as a plane equation.
|
||||
|
||||
|
||||
.. function:: glColor (red, green, blue, alpha):
|
||||
|
||||
B{glColor3b, glColor3d, glColor3f, glColor3i, glColor3s, glColor3ub, glColor3ui, glColor3us,
|
||||
glColor4b, glColor4d, glColor4f, glColor4i, glColor4s, glColor4ub, glColor4ui, glColor4us,
|
||||
glColor3bv, glColor3dv, glColor3fv, glColor3iv, glColor3sv, glColor3ubv, glColor3uiv,
|
||||
glColor3usv, glColor4bv, glColor4dv, glColor4fv, glColor4iv, glColor4sv, glColor4ubv,
|
||||
glColor4uiv, glColor4usv}
|
||||
|
||||
Set a new color.
|
||||
|
||||
.. seealso:: `OpenGL Docs <https://khronos.org/registry/OpenGL-Refpages/gl4/html/glColor.xhtml>`__
|
||||
|
||||
:type red, green, blue, alpha: Depends on function prototype.
|
||||
:arg red, green, blue: Specify new red, green, and blue values for the current color.
|
||||
:arg alpha: Specifies a new alpha value for the current color. Included only in the
|
||||
four-argument glColor4 commands. (With '4' colors only)
|
||||
|
||||
|
||||
.. function:: glColorMask(red, green, blue, alpha):
|
||||
|
||||
Enable and disable writing of frame buffer color components
|
||||
|
@@ -728,7 +728,7 @@ Abusing RNA property callbacks
|
||||
------------------------------
|
||||
|
||||
Python-defined RNA properties can have custom callbacks. Trying to perform complex operations
|
||||
from there, like calling an operator, may work, but is not officialy recommended nor supported.
|
||||
from there, like calling an operator, may work, but is not officially recommended nor supported.
|
||||
|
||||
Main reason is that those callback should be very fast, but additionally, it may for example
|
||||
create issues with undo/redo system (most operators store an history step, and editing an RNA
|
||||
|
43
extern/hipew/include/hipew.h
vendored
43
extern/hipew/include/hipew.h
vendored
@@ -804,31 +804,29 @@ typedef enum hipDeviceP2PAttr {
|
||||
} hipDeviceP2PAttr;
|
||||
|
||||
typedef struct HIP_MEMCPY3D {
|
||||
size_t srcXInBytes;
|
||||
size_t srcY;
|
||||
size_t srcZ;
|
||||
size_t srcLOD;
|
||||
unsigned int srcXInBytes;
|
||||
unsigned int srcY;
|
||||
unsigned int srcZ;
|
||||
unsigned int srcLOD;
|
||||
hipMemoryType srcMemoryType;
|
||||
const void* srcHost;
|
||||
hipDeviceptr_t srcDevice;
|
||||
hArray * srcArray;
|
||||
void* reserved0;
|
||||
size_t srcPitch;
|
||||
size_t srcHeight;
|
||||
size_t dstXInBytes;
|
||||
size_t dstY;
|
||||
size_t dstZ;
|
||||
size_t dstLOD;
|
||||
hArray srcArray;
|
||||
unsigned int srcPitch;
|
||||
unsigned int srcHeight;
|
||||
unsigned int dstXInBytes;
|
||||
unsigned int dstY;
|
||||
unsigned int dstZ;
|
||||
unsigned int dstLOD;
|
||||
hipMemoryType dstMemoryType;
|
||||
void* dstHost;
|
||||
hipDeviceptr_t dstDevice;
|
||||
hArray * dstArray;
|
||||
void* reserved1;
|
||||
size_t dstPitch;
|
||||
size_t dstHeight;
|
||||
size_t WidthInBytes;
|
||||
size_t Height;
|
||||
size_t Depth;
|
||||
hArray dstArray;
|
||||
unsigned int dstPitch;
|
||||
unsigned int dstHeight;
|
||||
unsigned int WidthInBytes;
|
||||
unsigned int Height;
|
||||
unsigned int Depth;
|
||||
} HIP_MEMCPY3D;
|
||||
|
||||
typedef struct HIP_MEMCPY3D_PEER_st {
|
||||
@@ -879,7 +877,7 @@ typedef struct HIP_RESOURCE_DESC_st {
|
||||
hipResourceType resType;
|
||||
union {
|
||||
struct {
|
||||
hArray * h_Array;
|
||||
hArray h_Array;
|
||||
} array;
|
||||
struct {
|
||||
hipMipmappedArray_t hMipmappedArray;
|
||||
@@ -1074,9 +1072,10 @@ typedef enum hiprtcResult {
|
||||
typedef hipError_t HIPAPI thipGetErrorName(hipError_t error, const char** pStr);
|
||||
typedef hipError_t HIPAPI thipInit(unsigned int Flags);
|
||||
typedef hipError_t HIPAPI thipDriverGetVersion(int* driverVersion);
|
||||
typedef hipError_t HIPAPI thipGetDevice(hipDevice_t* device, int ordinal);
|
||||
typedef hipError_t HIPAPI thipGetDevice(int* device);
|
||||
typedef hipError_t HIPAPI thipGetDeviceCount(int* count);
|
||||
typedef hipError_t HIPAPI thipGetDeviceProperties(hipDeviceProp_t* props, int deviceId);
|
||||
typedef hipError_t HIPAPI thipDeviceGet(hipDevice_t* device, int ordinal);
|
||||
typedef hipError_t HIPAPI thipDeviceGetName(char* name, int len, hipDevice_t dev);
|
||||
typedef hipError_t HIPAPI thipDeviceGetAttribute(int* pi, hipDeviceAttribute_t attrib, hipDevice_t dev);
|
||||
typedef hipError_t HIPAPI thipDeviceComputeCapability(int* major, int* minor, hipDevice_t dev);
|
||||
@@ -1209,6 +1208,7 @@ extern thipDriverGetVersion *hipDriverGetVersion;
|
||||
extern thipGetDevice *hipGetDevice;
|
||||
extern thipGetDeviceCount *hipGetDeviceCount;
|
||||
extern thipGetDeviceProperties *hipGetDeviceProperties;
|
||||
extern thipDeviceGet* hipDeviceGet;
|
||||
extern thipDeviceGetName *hipDeviceGetName;
|
||||
extern thipDeviceGetAttribute *hipDeviceGetAttribute;
|
||||
extern thipDeviceComputeCapability *hipDeviceComputeCapability;
|
||||
@@ -1333,6 +1333,7 @@ enum {
|
||||
HIPEW_SUCCESS = 0,
|
||||
HIPEW_ERROR_OPEN_FAILED = -1,
|
||||
HIPEW_ERROR_ATEXIT_FAILED = -2,
|
||||
HIPEW_ERROR_OLD_DRIVER = -3,
|
||||
};
|
||||
|
||||
enum {
|
||||
|
40
extern/hipew/src/hipew.c
vendored
40
extern/hipew/src/hipew.c
vendored
@@ -71,6 +71,7 @@ thipDriverGetVersion *hipDriverGetVersion;
|
||||
thipGetDevice *hipGetDevice;
|
||||
thipGetDeviceCount *hipGetDeviceCount;
|
||||
thipGetDeviceProperties *hipGetDeviceProperties;
|
||||
thipDeviceGet* hipDeviceGet;
|
||||
thipDeviceGetName *hipDeviceGetName;
|
||||
thipDeviceGetAttribute *hipDeviceGetAttribute;
|
||||
thipDeviceComputeCapability *hipDeviceComputeCapability;
|
||||
@@ -213,6 +214,36 @@ static void hipewHipExit(void) {
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
static int hipewHasOldDriver(const char *hip_path) {
|
||||
DWORD verHandle = 0;
|
||||
DWORD verSize = GetFileVersionInfoSize(hip_path, &verHandle);
|
||||
int old_driver = 0;
|
||||
if(verSize != 0) {
|
||||
LPSTR verData = (LPSTR)malloc(verSize);
|
||||
if(GetFileVersionInfo(hip_path, verHandle, verSize, verData)) {
|
||||
LPBYTE lpBuffer = NULL;
|
||||
UINT size = 0;
|
||||
if(VerQueryValue(verData, "\\", (VOID FAR * FAR *)&lpBuffer, &size)) {
|
||||
if(size) {
|
||||
VS_FIXEDFILEINFO *verInfo = (VS_FIXEDFILEINFO *)lpBuffer;
|
||||
/* Magic value from
|
||||
* https://docs.microsoft.com/en-us/windows/win32/api/verrsrc/ns-verrsrc-vs_fixedfileinfo */
|
||||
if(verInfo->dwSignature == 0xfeef04bd) {
|
||||
unsigned int fileVersionLS0 = (verInfo->dwFileVersionLS >> 16) & 0xffff;
|
||||
unsigned int fileversionLS1 = (verInfo->dwFileVersionLS >> 0) & 0xffff;
|
||||
/* Corresponds to versions older than AMD Radeon Pro 21.Q4. */
|
||||
old_driver = ((fileVersionLS0 < 3354) || (fileVersionLS0 == 3354 && fileversionLS1 < 13));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
free(verData);
|
||||
}
|
||||
return old_driver;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int hipewHipInit(void) {
|
||||
/* Library paths. */
|
||||
#ifdef _WIN32
|
||||
@@ -240,6 +271,14 @@ static int hipewHipInit(void) {
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
/* Test for driver version. */
|
||||
if(hipewHasOldDriver(hip_paths[0])) {
|
||||
result = HIPEW_ERROR_OLD_DRIVER;
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Load library. */
|
||||
hip_lib = dynamic_library_open_find(hip_paths);
|
||||
|
||||
@@ -255,6 +294,7 @@ static int hipewHipInit(void) {
|
||||
HIP_LIBRARY_FIND_CHECKED(hipGetDevice);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipGetDeviceCount);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipGetDeviceProperties);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipDeviceGet);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipDeviceGetName);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipDeviceGetAttribute);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipDeviceComputeCapability);
|
||||
|
@@ -226,6 +226,9 @@ add_definitions(
|
||||
-DCCL_NAMESPACE_END=}
|
||||
)
|
||||
|
||||
if(WITH_CYCLES_DEBUG)
|
||||
add_definitions(-DWITH_CYCLES_DEBUG)
|
||||
endif()
|
||||
if(WITH_CYCLES_STANDALONE_GUI)
|
||||
add_definitions(-DWITH_CYCLES_STANDALONE_GUI)
|
||||
endif()
|
||||
@@ -334,7 +337,7 @@ else()
|
||||
endif()
|
||||
|
||||
# Warnings
|
||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
||||
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CMAKE_CXX_FLAGS _has_cxxflag_float_conversion "-Werror=float-conversion")
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CMAKE_CXX_FLAGS _has_cxxflag_double_promotion "-Werror=double-promotion")
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CMAKE_CXX_FLAGS _has_no_error_unused_macros "-Wno-error=unused-macros")
|
||||
|
@@ -218,6 +218,12 @@ enum_denoising_prefilter = (
|
||||
('ACCURATE', "Accurate", "Prefilter noisy guiding passes before denoising color. Improves quality when guiding passes are noisy using extra processing time", 3),
|
||||
)
|
||||
|
||||
enum_direct_light_sampling_type = (
|
||||
('MULTIPLE_IMPORTANCE_SAMPLING', "Multiple Importance Sampling", "Multiple importance sampling is used to combine direct light contributions from next-event estimation and forward path tracing", 0),
|
||||
('FORWARD_PATH_TRACING', "Forward Path Tracing", "Direct light contributions are only sampled using forward path tracing", 1),
|
||||
('NEXT_EVENT_ESTIMATION', "Next-Event Estimation", "Direct light contributions are only sampled using next-event estimation", 2),
|
||||
)
|
||||
|
||||
def update_render_passes(self, context):
|
||||
scene = context.scene
|
||||
view_layer = context.view_layer
|
||||
@@ -353,7 +359,7 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
|
||||
name="Scrambling Distance",
|
||||
default=1.0,
|
||||
min=0.0, max=1.0,
|
||||
description="Lower values give faster rendering with GPU rendering and less noise with all devices at the cost of possible artifacts if set too low. Only works when not using adaptive sampling",
|
||||
description="Reduce randomization between pixels to improve GPU rendering performance, at the cost of possible rendering artifacts if set too low. Only works when not using adaptive sampling",
|
||||
)
|
||||
preview_scrambling_distance: BoolProperty(
|
||||
name="Scrambling Distance viewport",
|
||||
@@ -361,10 +367,10 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
|
||||
description="Uses the Scrambling Distance value for the viewport. Faster but may flicker",
|
||||
)
|
||||
|
||||
adaptive_scrambling_distance: BoolProperty(
|
||||
name="Adaptive Scrambling Distance",
|
||||
auto_scrambling_distance: BoolProperty(
|
||||
name="Automatic Scrambling Distance",
|
||||
default=False,
|
||||
description="Uses a formula to adapt the scrambling distance strength based on the sample count",
|
||||
description="Automatically reduce the randomization between pixels to improve GPU rendering performance, at the cost of possible rendering artifacts. Only works when not using adaptive sampling",
|
||||
)
|
||||
|
||||
use_layer_samples: EnumProperty(
|
||||
@@ -422,6 +428,13 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
|
||||
default=0,
|
||||
)
|
||||
|
||||
direct_light_sampling_type: EnumProperty(
|
||||
name="Direct Light Sampling Type",
|
||||
description="The type of strategy used for sampling direct light contributions",
|
||||
items=enum_direct_light_sampling_type,
|
||||
default='MULTIPLE_IMPORTANCE_SAMPLING',
|
||||
)
|
||||
|
||||
min_light_bounces: IntProperty(
|
||||
name="Min Light Bounces",
|
||||
description="Minimum number of light bounces. Setting this higher reduces noise in the first bounces, "
|
||||
@@ -777,8 +790,8 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
|
||||
)
|
||||
|
||||
use_auto_tile: BoolProperty(
|
||||
name="Auto Tiles",
|
||||
description="Automatically render high resolution images in tiles to reduce memory usage, using the specified tile size. Tiles are cached to disk while rendering to save memory",
|
||||
name="Using Tiling",
|
||||
description="Render high resolution images in tiles to reduce memory usage, using the specified tile size. Tiles are cached to disk while rendering to save memory",
|
||||
default=True,
|
||||
)
|
||||
tile_size: IntProperty(
|
||||
|
@@ -295,13 +295,13 @@ class CYCLES_RENDER_PT_sampling_advanced(CyclesButtonsPanel, Panel):
|
||||
|
||||
layout.separator()
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.active = not (cscene.use_adaptive_sampling and cscene.use_preview_adaptive_sampling)
|
||||
col.prop(cscene, "scrambling_distance", text="Scrambling Distance")
|
||||
col.prop(cscene, "adaptive_scrambling_distance", text="Adaptive")
|
||||
sub = col.row(align=True)
|
||||
heading = layout.column(align=True, heading="Scrambling Distance")
|
||||
heading.active = not (cscene.use_adaptive_sampling and cscene.use_preview_adaptive_sampling)
|
||||
heading.prop(cscene, "auto_scrambling_distance", text="Automatic")
|
||||
sub = heading.row()
|
||||
sub.active = not cscene.use_preview_adaptive_sampling
|
||||
sub.prop(cscene, "preview_scrambling_distance", text="Viewport")
|
||||
heading.prop(cscene, "scrambling_distance", text="Multiplier")
|
||||
|
||||
layout.separator()
|
||||
|
||||
|
@@ -199,7 +199,7 @@ static bool ObtainCacheParticleUV(Hair *hair,
|
||||
b_mesh->uv_layers.begin(l);
|
||||
|
||||
float2 uv = zero_float2();
|
||||
if (b_mesh->uv_layers.length())
|
||||
if (!b_mesh->uv_layers.empty())
|
||||
b_psys.uv_on_emitter(psmd, *b_pa, pa_no, uv_num, &uv.x);
|
||||
CData->curve_uv.push_back_slow(uv);
|
||||
|
||||
@@ -261,7 +261,7 @@ static bool ObtainCacheParticleVcol(Hair *hair,
|
||||
b_mesh->vertex_colors.begin(l);
|
||||
|
||||
float4 vcol = make_float4(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
if (b_mesh->vertex_colors.length())
|
||||
if (!b_mesh->vertex_colors.empty())
|
||||
b_psys.mcol_on_emitter(psmd, *b_pa, pa_no, vcol_num, &vcol.x);
|
||||
CData->curve_vcol.push_back_slow(vcol);
|
||||
|
||||
|
@@ -334,7 +334,7 @@ bool BlenderDisplayDriver::update_begin(const Params ¶ms,
|
||||
|
||||
/* Update PBO dimensions if needed.
|
||||
*
|
||||
* NOTE: Allocate the PBO for the the size which will fit the final render resolution (as in,
|
||||
* NOTE: Allocate the PBO for the size which will fit the final render resolution (as in,
|
||||
* at a resolution divider 1. This was we don't need to recreate graphics interoperability
|
||||
* objects which are costly and which are tied to the specific underlying buffer size.
|
||||
* The downside of this approach is that when graphics interoperability is not used we are
|
||||
|
@@ -555,7 +555,7 @@ static void attr_create_vertex_color(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh,
|
||||
/* Create uv map attributes. */
|
||||
static void attr_create_uv_map(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh)
|
||||
{
|
||||
if (b_mesh.uv_layers.length() != 0) {
|
||||
if (!b_mesh.uv_layers.empty()) {
|
||||
for (BL::MeshUVLoopLayer &l : b_mesh.uv_layers) {
|
||||
const bool active_render = l.active_render();
|
||||
AttributeStandard uv_std = (active_render) ? ATTR_STD_UV : ATTR_STD_NONE;
|
||||
@@ -619,7 +619,7 @@ static void attr_create_uv_map(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh)
|
||||
|
||||
static void attr_create_subd_uv_map(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, bool subdivide_uvs)
|
||||
{
|
||||
if (b_mesh.uv_layers.length() != 0) {
|
||||
if (!b_mesh.uv_layers.empty()) {
|
||||
BL::Mesh::uv_layers_iterator l;
|
||||
int i = 0;
|
||||
|
||||
@@ -951,7 +951,7 @@ static void create_mesh(Scene *scene,
|
||||
N = attr_N->data_float3();
|
||||
|
||||
/* create generated coordinates from undeformed coordinates */
|
||||
const bool need_default_tangent = (subdivision == false) && (b_mesh.uv_layers.length() == 0) &&
|
||||
const bool need_default_tangent = (subdivision == false) && (b_mesh.uv_layers.empty()) &&
|
||||
(mesh->need_attribute(scene, ATTR_STD_UV_TANGENT));
|
||||
if (mesh->need_attribute(scene, ATTR_STD_GENERATED) || need_default_tangent) {
|
||||
Attribute *attr = attributes.add(ATTR_STD_GENERATED);
|
||||
|
@@ -129,7 +129,7 @@ void BlenderSession::create_session()
|
||||
/* reset status/progress */
|
||||
last_status = "";
|
||||
last_error = "";
|
||||
last_progress = -1.0f;
|
||||
last_progress = -1.0;
|
||||
start_resize_time = 0.0;
|
||||
|
||||
/* create session */
|
||||
@@ -606,19 +606,6 @@ void BlenderSession::bake(BL::Depsgraph &b_depsgraph_,
|
||||
pass->set_type(bake_type_to_pass(bake_type, bake_filter));
|
||||
pass->set_include_albedo((bake_filter & BL::BakeSettings::pass_filter_COLOR));
|
||||
|
||||
if (pass->get_type() == PASS_COMBINED) {
|
||||
/* Filtering settings for combined pass. */
|
||||
Integrator *integrator = scene->integrator;
|
||||
integrator->set_use_direct_light((bake_filter & BL::BakeSettings::pass_filter_DIRECT) != 0);
|
||||
integrator->set_use_indirect_light((bake_filter & BL::BakeSettings::pass_filter_INDIRECT) !=
|
||||
0);
|
||||
integrator->set_use_diffuse((bake_filter & BL::BakeSettings::pass_filter_DIFFUSE) != 0);
|
||||
integrator->set_use_glossy((bake_filter & BL::BakeSettings::pass_filter_GLOSSY) != 0);
|
||||
integrator->set_use_transmission((bake_filter & BL::BakeSettings::pass_filter_TRANSMISSION) !=
|
||||
0);
|
||||
integrator->set_use_emission((bake_filter & BL::BakeSettings::pass_filter_EMIT) != 0);
|
||||
}
|
||||
|
||||
session->set_display_driver(nullptr);
|
||||
session->set_output_driver(make_unique<BlenderOutputDriver>(b_engine));
|
||||
|
||||
@@ -628,6 +615,24 @@ void BlenderSession::bake(BL::Depsgraph &b_depsgraph_,
|
||||
sync->sync_camera(b_render, b_camera_override, width, height, "");
|
||||
sync->sync_data(
|
||||
b_render, b_depsgraph, b_v3d, b_camera_override, width, height, &python_thread_state);
|
||||
|
||||
/* Filtering settings for combined pass. */
|
||||
if (pass->get_type() == PASS_COMBINED) {
|
||||
Integrator *integrator = scene->integrator;
|
||||
integrator->set_use_direct_light((bake_filter & BL::BakeSettings::pass_filter_DIRECT) != 0);
|
||||
integrator->set_use_indirect_light((bake_filter & BL::BakeSettings::pass_filter_INDIRECT) !=
|
||||
0);
|
||||
integrator->set_use_diffuse((bake_filter & BL::BakeSettings::pass_filter_DIFFUSE) != 0);
|
||||
integrator->set_use_glossy((bake_filter & BL::BakeSettings::pass_filter_GLOSSY) != 0);
|
||||
integrator->set_use_transmission(
|
||||
(bake_filter & BL::BakeSettings::pass_filter_TRANSMISSION) != 0);
|
||||
integrator->set_use_emission((bake_filter & BL::BakeSettings::pass_filter_EMIT) != 0);
|
||||
}
|
||||
|
||||
/* Always use transpanent background for baking. */
|
||||
scene->background->set_transparent(true);
|
||||
|
||||
/* Load built-in images from Blender. */
|
||||
builtin_images_load();
|
||||
}
|
||||
|
||||
@@ -854,7 +859,7 @@ void BlenderSession::get_status(string &status, string &substatus)
|
||||
session->progress.get_status(status, substatus);
|
||||
}
|
||||
|
||||
void BlenderSession::get_progress(float &progress, double &total_time, double &render_time)
|
||||
void BlenderSession::get_progress(double &progress, double &total_time, double &render_time)
|
||||
{
|
||||
session->progress.get_time(total_time, render_time);
|
||||
progress = session->progress.get_progress();
|
||||
@@ -862,10 +867,10 @@ void BlenderSession::get_progress(float &progress, double &total_time, double &r
|
||||
|
||||
void BlenderSession::update_bake_progress()
|
||||
{
|
||||
float progress = session->progress.get_progress();
|
||||
double progress = session->progress.get_progress();
|
||||
|
||||
if (progress != last_progress) {
|
||||
b_engine.update_progress(progress);
|
||||
b_engine.update_progress((float)progress);
|
||||
last_progress = progress;
|
||||
}
|
||||
}
|
||||
@@ -874,7 +879,7 @@ void BlenderSession::update_status_progress()
|
||||
{
|
||||
string timestatus, status, substatus;
|
||||
string scene_status = "";
|
||||
float progress;
|
||||
double progress;
|
||||
double total_time, remaining_time = 0, render_time;
|
||||
float mem_used = (float)session->stats.mem_used / 1024.0f / 1024.0f;
|
||||
float mem_peak = (float)session->stats.mem_peak / 1024.0f / 1024.0f;
|
||||
@@ -918,7 +923,7 @@ void BlenderSession::update_status_progress()
|
||||
last_status_time = current_time;
|
||||
}
|
||||
if (progress != last_progress) {
|
||||
b_engine.update_progress(progress);
|
||||
b_engine.update_progress((float)progress);
|
||||
last_progress = progress;
|
||||
}
|
||||
|
||||
|
@@ -82,7 +82,7 @@ class BlenderSession {
|
||||
void tag_redraw();
|
||||
void tag_update();
|
||||
void get_status(string &status, string &substatus);
|
||||
void get_progress(float &progress, double &total_time, double &render_time);
|
||||
void get_progress(double &progress, double &total_time, double &render_time);
|
||||
void test_cancel();
|
||||
void update_status_progress();
|
||||
void update_bake_progress();
|
||||
@@ -108,7 +108,7 @@ class BlenderSession {
|
||||
|
||||
string last_status;
|
||||
string last_error;
|
||||
float last_progress;
|
||||
double last_progress;
|
||||
double last_status_time;
|
||||
|
||||
int width, height;
|
||||
|
@@ -365,8 +365,8 @@ void BlenderSync::sync_integrator(BL::ViewLayer &b_view_layer, bool background)
|
||||
|
||||
int samples = get_int(cscene, "samples");
|
||||
float scrambling_distance = get_float(cscene, "scrambling_distance");
|
||||
bool adaptive_scrambling_distance = get_boolean(cscene, "adaptive_scrambling_distance");
|
||||
if (adaptive_scrambling_distance) {
|
||||
bool auto_scrambling_distance = get_boolean(cscene, "auto_scrambling_distance");
|
||||
if (auto_scrambling_distance) {
|
||||
scrambling_distance *= 4.0f / sqrtf(samples);
|
||||
}
|
||||
|
||||
@@ -392,6 +392,12 @@ void BlenderSync::sync_integrator(BL::ViewLayer &b_view_layer, bool background)
|
||||
integrator->set_ao_bounces(0);
|
||||
}
|
||||
|
||||
#ifdef WITH_CYCLES_DEBUG
|
||||
DirectLightSamplingType direct_light_sampling_type = (DirectLightSamplingType)get_enum(
|
||||
cscene, "direct_light_sampling_type", DIRECT_LIGHT_SAMPLING_NUM, DIRECT_LIGHT_SAMPLING_MIS);
|
||||
integrator->set_direct_light_sampling_type(direct_light_sampling_type);
|
||||
#endif
|
||||
|
||||
const DenoiseParams denoise_params = get_denoise_params(b_scene, b_view_layer, background);
|
||||
integrator->set_use_denoise(denoise_params.use);
|
||||
|
||||
@@ -872,7 +878,7 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine &b_engine,
|
||||
|
||||
/* Time limit. */
|
||||
if (background) {
|
||||
params.time_limit = get_float(cscene, "time_limit");
|
||||
params.time_limit = (double)get_float(cscene, "time_limit");
|
||||
}
|
||||
else {
|
||||
/* For the viewport it kind of makes more sense to think in terms of the noise floor, which is
|
||||
|
@@ -303,7 +303,7 @@ static inline string image_user_file_path(BL::ImageUser &iuser,
|
||||
string filepath_str = string(filepath);
|
||||
if (load_tiled && ima.source() == BL::Image::source_TILED) {
|
||||
string udim;
|
||||
if (ima.tiles.length() > 0) {
|
||||
if (!ima.tiles.empty()) {
|
||||
udim = to_string(ima.tiles[0].number());
|
||||
}
|
||||
string_replace(filepath_str, udim, "<UDIM>");
|
||||
@@ -647,7 +647,7 @@ static inline Mesh::SubdivisionType object_subdivision_type(BL::Object &b_ob,
|
||||
{
|
||||
PointerRNA cobj = RNA_pointer_get(&b_ob.ptr, "cycles");
|
||||
|
||||
if (cobj.data && b_ob.modifiers.length() > 0 && experimental) {
|
||||
if (cobj.data && !b_ob.modifiers.empty() && experimental) {
|
||||
BL::Modifier mod = b_ob.modifiers[b_ob.modifiers.length() - 1];
|
||||
bool enabled = preview ? mod.show_viewport() : mod.show_render();
|
||||
|
||||
|
@@ -303,7 +303,7 @@ static void rtc_error_func(void *, enum RTCError, const char *str)
|
||||
VLOG(1) << str;
|
||||
}
|
||||
|
||||
static double progress_start_time = 0.0f;
|
||||
static double progress_start_time = 0.0;
|
||||
|
||||
static bool rtc_progress_func(void *user_ptr, const double n)
|
||||
{
|
||||
|
@@ -153,7 +153,7 @@ void BVHNode::update_time()
|
||||
namespace {
|
||||
|
||||
struct DumpTraversalContext {
|
||||
/* Descriptor of wile where writing is happening. */
|
||||
/* Descriptor of while where writing is happening. */
|
||||
FILE *stream;
|
||||
/* Unique identifier of the node current. */
|
||||
int id;
|
||||
|
@@ -178,7 +178,7 @@ class InnerNode : public BVHNode {
|
||||
reset_unused_children();
|
||||
}
|
||||
|
||||
/* NOTE: This function is only used during binary BVH builder, and it
|
||||
/* NOTE: This function is only used during binary BVH builder, and it's
|
||||
* supposed to be configured to have 2 children which will be filled-in in a
|
||||
* bit. But this is important to have children reset to NULL. */
|
||||
explicit InnerNode(const BoundBox &bounds) : BVHNode(bounds), num_children_(0)
|
||||
|
@@ -30,15 +30,17 @@ BVHOptiX::BVHOptiX(const BVHParams ¶ms_,
|
||||
: BVH(params_, geometry_, objects_),
|
||||
device(device),
|
||||
traversable_handle(0),
|
||||
as_data(device, params_.top_level ? "optix tlas" : "optix blas", false),
|
||||
motion_transform_data(device, "optix motion transform", false)
|
||||
as_data(make_unique<device_only_memory<char>>(
|
||||
device, params.top_level ? "optix tlas" : "optix blas", false)),
|
||||
motion_transform_data(
|
||||
make_unique<device_only_memory<char>>(device, "optix motion transform", false))
|
||||
{
|
||||
}
|
||||
|
||||
BVHOptiX::~BVHOptiX()
|
||||
{
|
||||
// Acceleration structure memory is delayed freed on device, since deleting the
|
||||
// BVH may happen while still being used for rendering.
|
||||
/* Acceleration structure memory is delayed freed on device, since deleting the
|
||||
* BVH may happen while still being used for rendering. */
|
||||
device->release_optix_bvh(this);
|
||||
}
|
||||
|
||||
|
@@ -25,14 +25,16 @@
|
||||
|
||||
# include "device/memory.h"
|
||||
|
||||
# include "util/unique_ptr.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
class BVHOptiX : public BVH {
|
||||
public:
|
||||
Device *device;
|
||||
uint64_t traversable_handle;
|
||||
device_only_memory<char> as_data;
|
||||
device_only_memory<char> motion_transform_data;
|
||||
unique_ptr<device_only_memory<char>> as_data;
|
||||
unique_ptr<device_only_memory<char>> motion_transform_data;
|
||||
|
||||
protected:
|
||||
friend class BVH;
|
||||
|
@@ -88,7 +88,7 @@ endmacro()
|
||||
|
||||
function(cycles_link_directories)
|
||||
if(APPLE)
|
||||
# APPLE plaform uses full paths for linking libraries, and avoids link_directories.
|
||||
# APPLE platform uses full paths for linking libraries, and avoids link_directories.
|
||||
return()
|
||||
endif()
|
||||
|
||||
|
@@ -93,11 +93,6 @@ CPUDevice::~CPUDevice()
|
||||
texture_info.free();
|
||||
}
|
||||
|
||||
bool CPUDevice::show_samples() const
|
||||
{
|
||||
return (info.cpu_threads == 1);
|
||||
}
|
||||
|
||||
BVHLayoutMask CPUDevice::get_bvh_layout_mask() const
|
||||
{
|
||||
BVHLayoutMask bvh_layout_mask = BVH_LAYOUT_BVH2;
|
||||
|
@@ -60,8 +60,6 @@ class CPUDevice : public Device {
|
||||
CPUDevice(const DeviceInfo &info_, Stats &stats_, Profiler &profiler_);
|
||||
~CPUDevice();
|
||||
|
||||
virtual bool show_samples() const override;
|
||||
|
||||
virtual BVHLayoutMask get_bvh_layout_mask() const override;
|
||||
|
||||
/* Returns true if the texture info was copied to the device (meaning, some more
|
||||
|
@@ -46,12 +46,6 @@ bool CUDADevice::have_precompiled_kernels()
|
||||
return path_exists(cubins_path);
|
||||
}
|
||||
|
||||
bool CUDADevice::show_samples() const
|
||||
{
|
||||
/* The CUDADevice only processes one tile at a time, so showing samples is fine. */
|
||||
return true;
|
||||
}
|
||||
|
||||
BVHLayoutMask CUDADevice::get_bvh_layout_mask() const
|
||||
{
|
||||
return BVH_LAYOUT_BVH2;
|
||||
@@ -242,6 +236,10 @@ string CUDADevice::compile_kernel_get_common_cflags(const uint kernel_features)
|
||||
cflags += " -DWITH_NANOVDB";
|
||||
# endif
|
||||
|
||||
# ifdef WITH_CYCLES_DEBUG
|
||||
cflags += " -DWITH_CYCLES_DEBUG";
|
||||
# endif
|
||||
|
||||
return cflags;
|
||||
}
|
||||
|
||||
@@ -777,6 +775,7 @@ void CUDADevice::generic_free(device_memory &mem)
|
||||
if (mem.device_pointer) {
|
||||
CUDAContextScope scope(this);
|
||||
thread_scoped_lock lock(cuda_mem_map_mutex);
|
||||
DCHECK(cuda_mem_map.find(&mem) != cuda_mem_map.end());
|
||||
const CUDAMem &cmem = cuda_mem_map[&mem];
|
||||
|
||||
/* If cmem.use_mapped_host is true, reference counting is used
|
||||
@@ -1143,6 +1142,7 @@ void CUDADevice::tex_free(device_texture &mem)
|
||||
if (mem.device_pointer) {
|
||||
CUDAContextScope scope(this);
|
||||
thread_scoped_lock lock(cuda_mem_map_mutex);
|
||||
DCHECK(cuda_mem_map.find(&mem) != cuda_mem_map.end());
|
||||
const CUDAMem &cmem = cuda_mem_map[&mem];
|
||||
|
||||
if (cmem.texobject) {
|
||||
|
@@ -76,8 +76,6 @@ class CUDADevice : public Device {
|
||||
|
||||
static bool have_precompiled_kernels();
|
||||
|
||||
virtual bool show_samples() const override;
|
||||
|
||||
virtual BVHLayoutMask get_bvh_layout_mask() const override;
|
||||
|
||||
void set_error(const string &error) override;
|
||||
|
@@ -149,10 +149,6 @@ class Device {
|
||||
fprintf(stderr, "%s\n", error.c_str());
|
||||
fflush(stderr);
|
||||
}
|
||||
virtual bool show_samples() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
virtual BVHLayoutMask get_bvh_layout_mask() const = 0;
|
||||
|
||||
/* statistics */
|
||||
|
@@ -57,9 +57,16 @@ bool device_hip_init()
|
||||
}
|
||||
}
|
||||
else {
|
||||
VLOG(1) << "HIPEW initialization failed: "
|
||||
<< ((hipew_result == HIPEW_ERROR_ATEXIT_FAILED) ? "Error setting up atexit() handler" :
|
||||
"Error opening the library");
|
||||
if (hipew_result == HIPEW_ERROR_ATEXIT_FAILED) {
|
||||
VLOG(1) << "HIPEW initialization failed: Error setting up atexit() handler";
|
||||
}
|
||||
else if (hipew_result == HIPEW_ERROR_OLD_DRIVER) {
|
||||
VLOG(1) << "HIPEW initialization failed: Driver version too old, requires AMD Radeon Pro "
|
||||
"21.Q4 driver or newer";
|
||||
}
|
||||
else {
|
||||
VLOG(1) << "HIPEW initialization failed: Error opening HIP dynamic library";
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@@ -47,12 +47,6 @@ bool HIPDevice::have_precompiled_kernels()
|
||||
return path_exists(fatbins_path);
|
||||
}
|
||||
|
||||
bool HIPDevice::show_samples() const
|
||||
{
|
||||
/* The HIPDevice only processes one tile at a time, so showing samples is fine. */
|
||||
return true;
|
||||
}
|
||||
|
||||
BVHLayoutMask HIPDevice::get_bvh_layout_mask() const
|
||||
{
|
||||
return BVH_LAYOUT_BVH2;
|
||||
@@ -99,7 +93,7 @@ HIPDevice::HIPDevice(const DeviceInfo &info, Stats &stats, Profiler &profiler)
|
||||
}
|
||||
|
||||
/* Setup device and context. */
|
||||
result = hipGetDevice(&hipDevice, hipDevId);
|
||||
result = hipDeviceGet(&hipDevice, hipDevId);
|
||||
if (result != hipSuccess) {
|
||||
set_error(string_printf("Failed to get HIP device handle from ordinal (%s)",
|
||||
hipewErrorString(result)));
|
||||
@@ -744,6 +738,7 @@ void HIPDevice::generic_free(device_memory &mem)
|
||||
if (mem.device_pointer) {
|
||||
HIPContextScope scope(this);
|
||||
thread_scoped_lock lock(hip_mem_map_mutex);
|
||||
DCHECK(hip_mem_map.find(&mem) != hip_mem_map.end());
|
||||
const HIPMem &cmem = hip_mem_map[&mem];
|
||||
|
||||
/* If cmem.use_mapped_host is true, reference counting is used
|
||||
@@ -986,16 +981,16 @@ void HIPDevice::tex_alloc(device_texture &mem)
|
||||
<< string_human_readable_number(mem.memory_size()) << " bytes. ("
|
||||
<< string_human_readable_size(mem.memory_size()) << ")";
|
||||
|
||||
hip_assert(hipArray3DCreate(&array_3d, &desc));
|
||||
hip_assert(hipArray3DCreate((hArray *)&array_3d, &desc));
|
||||
|
||||
if (!array_3d) {
|
||||
return;
|
||||
}
|
||||
|
||||
HIP_MEMCPY3D param;
|
||||
memset(¶m, 0, sizeof(param));
|
||||
memset(¶m, 0, sizeof(HIP_MEMCPY3D));
|
||||
param.dstMemoryType = hipMemoryTypeArray;
|
||||
param.dstArray = &array_3d;
|
||||
param.dstArray = array_3d;
|
||||
param.srcMemoryType = hipMemoryTypeHost;
|
||||
param.srcHost = mem.host_pointer;
|
||||
param.srcPitch = src_pitch;
|
||||
@@ -1061,12 +1056,13 @@ void HIPDevice::tex_alloc(device_texture &mem)
|
||||
|
||||
if (mem.info.data_type != IMAGE_DATA_TYPE_NANOVDB_FLOAT &&
|
||||
mem.info.data_type != IMAGE_DATA_TYPE_NANOVDB_FLOAT3) {
|
||||
/* Bindless textures. */
|
||||
hipResourceDesc resDesc;
|
||||
memset(&resDesc, 0, sizeof(resDesc));
|
||||
|
||||
if (array_3d) {
|
||||
resDesc.resType = hipResourceTypeArray;
|
||||
resDesc.res.array.h_Array = &array_3d;
|
||||
resDesc.res.array.h_Array = array_3d;
|
||||
resDesc.flags = 0;
|
||||
}
|
||||
else if (mem.data_height > 0) {
|
||||
@@ -1111,6 +1107,7 @@ void HIPDevice::tex_free(device_texture &mem)
|
||||
if (mem.device_pointer) {
|
||||
HIPContextScope scope(this);
|
||||
thread_scoped_lock lock(hip_mem_map_mutex);
|
||||
DCHECK(hip_mem_map.find(&mem) != hip_mem_map.end());
|
||||
const HIPMem &cmem = hip_mem_map[&mem];
|
||||
|
||||
if (cmem.texobject) {
|
||||
|
@@ -75,8 +75,6 @@ class HIPDevice : public Device {
|
||||
|
||||
static bool have_precompiled_kernels();
|
||||
|
||||
virtual bool show_samples() const override;
|
||||
|
||||
virtual BVHLayoutMask get_bvh_layout_mask() const override;
|
||||
|
||||
void set_error(const string &error) override;
|
||||
|
@@ -23,7 +23,7 @@ CCL_NAMESPACE_BEGIN
|
||||
|
||||
device_memory::device_memory(Device *device, const char *name, MemoryType type)
|
||||
: data_type(device_type_traits<uchar>::data_type),
|
||||
data_elements(device_type_traits<uchar>::num_elements_cpu),
|
||||
data_elements(device_type_traits<uchar>::num_elements),
|
||||
data_size(0),
|
||||
device_size(0),
|
||||
data_width(0),
|
||||
@@ -44,45 +44,6 @@ device_memory::device_memory(Device *device, const char *name, MemoryType type)
|
||||
{
|
||||
}
|
||||
|
||||
device_memory::device_memory(device_memory &&other) noexcept
|
||||
: data_type(other.data_type),
|
||||
data_elements(other.data_elements),
|
||||
data_size(other.data_size),
|
||||
device_size(other.device_size),
|
||||
data_width(other.data_width),
|
||||
data_height(other.data_height),
|
||||
data_depth(other.data_depth),
|
||||
type(other.type),
|
||||
name(other.name),
|
||||
device(other.device),
|
||||
device_pointer(other.device_pointer),
|
||||
host_pointer(other.host_pointer),
|
||||
shared_pointer(other.shared_pointer),
|
||||
shared_counter(other.shared_counter),
|
||||
original_device_ptr(other.original_device_ptr),
|
||||
original_device_size(other.original_device_size),
|
||||
original_device(other.original_device),
|
||||
need_realloc_(other.need_realloc_),
|
||||
modified(other.modified)
|
||||
{
|
||||
other.data_elements = 0;
|
||||
other.data_size = 0;
|
||||
other.device_size = 0;
|
||||
other.data_width = 0;
|
||||
other.data_height = 0;
|
||||
other.data_depth = 0;
|
||||
other.device = 0;
|
||||
other.device_pointer = 0;
|
||||
other.host_pointer = 0;
|
||||
other.shared_pointer = 0;
|
||||
other.shared_counter = 0;
|
||||
other.original_device_ptr = 0;
|
||||
other.original_device_size = 0;
|
||||
other.original_device = 0;
|
||||
other.need_realloc_ = false;
|
||||
other.modified = false;
|
||||
}
|
||||
|
||||
device_memory::~device_memory()
|
||||
{
|
||||
assert(shared_pointer == 0);
|
||||
|
@@ -81,155 +81,140 @@ static constexpr size_t datatype_size(DataType datatype)
|
||||
|
||||
template<typename T> struct device_type_traits {
|
||||
static const DataType data_type = TYPE_UNKNOWN;
|
||||
static const size_t num_elements_cpu = sizeof(T);
|
||||
static const size_t num_elements_gpu = sizeof(T);
|
||||
static const size_t num_elements = sizeof(T);
|
||||
};
|
||||
|
||||
template<> struct device_type_traits<uchar> {
|
||||
static const DataType data_type = TYPE_UCHAR;
|
||||
static const size_t num_elements_cpu = 1;
|
||||
static const size_t num_elements_gpu = 1;
|
||||
static_assert(sizeof(uchar) == num_elements_cpu * datatype_size(data_type));
|
||||
static const size_t num_elements = 1;
|
||||
static_assert(sizeof(uchar) == num_elements * datatype_size(data_type));
|
||||
};
|
||||
|
||||
template<> struct device_type_traits<uchar2> {
|
||||
static const DataType data_type = TYPE_UCHAR;
|
||||
static const size_t num_elements_cpu = 2;
|
||||
static const size_t num_elements_gpu = 2;
|
||||
static_assert(sizeof(uchar2) == num_elements_cpu * datatype_size(data_type));
|
||||
static const size_t num_elements = 2;
|
||||
static_assert(sizeof(uchar2) == num_elements * datatype_size(data_type));
|
||||
};
|
||||
|
||||
template<> struct device_type_traits<uchar3> {
|
||||
static const DataType data_type = TYPE_UCHAR;
|
||||
static const size_t num_elements_cpu = 3;
|
||||
static const size_t num_elements_gpu = 3;
|
||||
static_assert(sizeof(uchar3) == num_elements_cpu * datatype_size(data_type));
|
||||
static const size_t num_elements = 3;
|
||||
static_assert(sizeof(uchar3) == num_elements * datatype_size(data_type));
|
||||
};
|
||||
|
||||
template<> struct device_type_traits<uchar4> {
|
||||
static const DataType data_type = TYPE_UCHAR;
|
||||
static const size_t num_elements_cpu = 4;
|
||||
static const size_t num_elements_gpu = 4;
|
||||
static_assert(sizeof(uchar4) == num_elements_cpu * datatype_size(data_type));
|
||||
static const size_t num_elements = 4;
|
||||
static_assert(sizeof(uchar4) == num_elements * datatype_size(data_type));
|
||||
};
|
||||
|
||||
template<> struct device_type_traits<uint> {
|
||||
static const DataType data_type = TYPE_UINT;
|
||||
static const size_t num_elements_cpu = 1;
|
||||
static const size_t num_elements_gpu = 1;
|
||||
static_assert(sizeof(uint) == num_elements_cpu * datatype_size(data_type));
|
||||
static const size_t num_elements = 1;
|
||||
static_assert(sizeof(uint) == num_elements * datatype_size(data_type));
|
||||
};
|
||||
|
||||
template<> struct device_type_traits<uint2> {
|
||||
static const DataType data_type = TYPE_UINT;
|
||||
static const size_t num_elements_cpu = 2;
|
||||
static const size_t num_elements_gpu = 2;
|
||||
static_assert(sizeof(uint2) == num_elements_cpu * datatype_size(data_type));
|
||||
static const size_t num_elements = 2;
|
||||
static_assert(sizeof(uint2) == num_elements * datatype_size(data_type));
|
||||
};
|
||||
|
||||
template<> struct device_type_traits<uint3> {
|
||||
static const DataType data_type = TYPE_UINT;
|
||||
static const size_t num_elements_cpu = 3;
|
||||
static const size_t num_elements_gpu = 3;
|
||||
static_assert(sizeof(uint3) == num_elements_cpu * datatype_size(data_type));
|
||||
static const size_t num_elements = 3;
|
||||
static_assert(sizeof(uint3) == num_elements * datatype_size(data_type));
|
||||
};
|
||||
|
||||
template<> struct device_type_traits<uint4> {
|
||||
static const DataType data_type = TYPE_UINT;
|
||||
static const size_t num_elements_cpu = 4;
|
||||
static const size_t num_elements_gpu = 4;
|
||||
static_assert(sizeof(uint4) == num_elements_cpu * datatype_size(data_type));
|
||||
static const size_t num_elements = 4;
|
||||
static_assert(sizeof(uint4) == num_elements * datatype_size(data_type));
|
||||
};
|
||||
|
||||
template<> struct device_type_traits<int> {
|
||||
static const DataType data_type = TYPE_INT;
|
||||
static const size_t num_elements_cpu = 1;
|
||||
static const size_t num_elements_gpu = 1;
|
||||
static_assert(sizeof(int) == num_elements_cpu * datatype_size(data_type));
|
||||
static const size_t num_elements = 1;
|
||||
static_assert(sizeof(int) == num_elements * datatype_size(data_type));
|
||||
};
|
||||
|
||||
template<> struct device_type_traits<int2> {
|
||||
static const DataType data_type = TYPE_INT;
|
||||
static const size_t num_elements_cpu = 2;
|
||||
static const size_t num_elements_gpu = 2;
|
||||
static_assert(sizeof(int2) == num_elements_cpu * datatype_size(data_type));
|
||||
static const size_t num_elements = 2;
|
||||
static_assert(sizeof(int2) == num_elements * datatype_size(data_type));
|
||||
};
|
||||
|
||||
template<> struct device_type_traits<int3> {
|
||||
static const DataType data_type = TYPE_INT;
|
||||
static const size_t num_elements_cpu = 4;
|
||||
static const size_t num_elements_gpu = 3;
|
||||
static_assert(sizeof(int3) == num_elements_cpu * datatype_size(data_type));
|
||||
static const size_t num_elements = 4;
|
||||
static_assert(sizeof(int3) == num_elements * datatype_size(data_type));
|
||||
};
|
||||
|
||||
template<> struct device_type_traits<int4> {
|
||||
static const DataType data_type = TYPE_INT;
|
||||
static const size_t num_elements_cpu = 4;
|
||||
static const size_t num_elements_gpu = 4;
|
||||
static_assert(sizeof(int4) == num_elements_cpu * datatype_size(data_type));
|
||||
static const size_t num_elements = 4;
|
||||
static_assert(sizeof(int4) == num_elements * datatype_size(data_type));
|
||||
};
|
||||
|
||||
template<> struct device_type_traits<float> {
|
||||
static const DataType data_type = TYPE_FLOAT;
|
||||
static const size_t num_elements_cpu = 1;
|
||||
static const size_t num_elements_gpu = 1;
|
||||
static_assert(sizeof(float) == num_elements_cpu * datatype_size(data_type));
|
||||
static const size_t num_elements = 1;
|
||||
static_assert(sizeof(float) == num_elements * datatype_size(data_type));
|
||||
};
|
||||
|
||||
template<> struct device_type_traits<float2> {
|
||||
static const DataType data_type = TYPE_FLOAT;
|
||||
static const size_t num_elements_cpu = 2;
|
||||
static const size_t num_elements_gpu = 2;
|
||||
static_assert(sizeof(float2) == num_elements_cpu * datatype_size(data_type));
|
||||
static const size_t num_elements = 2;
|
||||
static_assert(sizeof(float2) == num_elements * datatype_size(data_type));
|
||||
};
|
||||
|
||||
template<> struct device_type_traits<float3> {
|
||||
/* float3 has different size depending on the device, can't use it for interchanging
|
||||
* memory between CPU and GPU.
|
||||
*
|
||||
* Leave body empty to trigger a compile error if used. */
|
||||
};
|
||||
|
||||
template<> struct device_type_traits<packed_float3> {
|
||||
static const DataType data_type = TYPE_FLOAT;
|
||||
static const size_t num_elements_cpu = 4;
|
||||
static const size_t num_elements_gpu = 3;
|
||||
static_assert(sizeof(float3) == num_elements_cpu * datatype_size(data_type));
|
||||
static const size_t num_elements = 3;
|
||||
static_assert(sizeof(packed_float3) == num_elements * datatype_size(data_type));
|
||||
};
|
||||
|
||||
template<> struct device_type_traits<float4> {
|
||||
static const DataType data_type = TYPE_FLOAT;
|
||||
static const size_t num_elements_cpu = 4;
|
||||
static const size_t num_elements_gpu = 4;
|
||||
static_assert(sizeof(float4) == num_elements_cpu * datatype_size(data_type));
|
||||
static const size_t num_elements = 4;
|
||||
static_assert(sizeof(float4) == num_elements * datatype_size(data_type));
|
||||
};
|
||||
|
||||
template<> struct device_type_traits<half> {
|
||||
static const DataType data_type = TYPE_HALF;
|
||||
static const size_t num_elements_cpu = 1;
|
||||
static const size_t num_elements_gpu = 1;
|
||||
static_assert(sizeof(half) == num_elements_cpu * datatype_size(data_type));
|
||||
static const size_t num_elements = 1;
|
||||
static_assert(sizeof(half) == num_elements * datatype_size(data_type));
|
||||
};
|
||||
|
||||
template<> struct device_type_traits<ushort4> {
|
||||
static const DataType data_type = TYPE_UINT16;
|
||||
static const size_t num_elements_cpu = 4;
|
||||
static const size_t num_elements_gpu = 4;
|
||||
static_assert(sizeof(ushort4) == num_elements_cpu * datatype_size(data_type));
|
||||
static const size_t num_elements = 4;
|
||||
static_assert(sizeof(ushort4) == num_elements * datatype_size(data_type));
|
||||
};
|
||||
|
||||
template<> struct device_type_traits<uint16_t> {
|
||||
static const DataType data_type = TYPE_UINT16;
|
||||
static const size_t num_elements_cpu = 1;
|
||||
static const size_t num_elements_gpu = 1;
|
||||
static_assert(sizeof(uint16_t) == num_elements_cpu * datatype_size(data_type));
|
||||
static const size_t num_elements = 1;
|
||||
static_assert(sizeof(uint16_t) == num_elements * datatype_size(data_type));
|
||||
};
|
||||
|
||||
template<> struct device_type_traits<half4> {
|
||||
static const DataType data_type = TYPE_HALF;
|
||||
static const size_t num_elements_cpu = 4;
|
||||
static const size_t num_elements_gpu = 4;
|
||||
static_assert(sizeof(half4) == num_elements_cpu * datatype_size(data_type));
|
||||
static const size_t num_elements = 4;
|
||||
static_assert(sizeof(half4) == num_elements * datatype_size(data_type));
|
||||
};
|
||||
|
||||
template<> struct device_type_traits<uint64_t> {
|
||||
static const DataType data_type = TYPE_UINT64;
|
||||
static const size_t num_elements_cpu = 1;
|
||||
static const size_t num_elements_gpu = 1;
|
||||
static_assert(sizeof(uint64_t) == num_elements_cpu * datatype_size(data_type));
|
||||
static const size_t num_elements = 1;
|
||||
static_assert(sizeof(uint64_t) == num_elements * datatype_size(data_type));
|
||||
};
|
||||
|
||||
/* Device Memory
|
||||
@@ -281,11 +266,16 @@ class device_memory {
|
||||
|
||||
/* Only create through subclasses. */
|
||||
device_memory(Device *device, const char *name, MemoryType type);
|
||||
device_memory(device_memory &&other) noexcept;
|
||||
|
||||
/* No copying allowed. */
|
||||
/* No copying and allowed.
|
||||
*
|
||||
* This is because device implementation might need to register device memory in an allocation
|
||||
* map of some sort and use pointer as a key to identify blocks. Moving data from one place to
|
||||
* another bypassing device allocation routines will make those maps hard to maintain. */
|
||||
device_memory(const device_memory &) = delete;
|
||||
device_memory(device_memory &&other) noexcept = delete;
|
||||
device_memory &operator=(const device_memory &) = delete;
|
||||
device_memory &operator=(device_memory &&) = delete;
|
||||
|
||||
/* Host allocation on the device. All host_pointer memory should be
|
||||
* allocated with these functions, for devices that support using
|
||||
@@ -320,9 +310,7 @@ template<typename T> class device_only_memory : public device_memory {
|
||||
: device_memory(device, name, allow_host_memory_fallback ? MEM_READ_WRITE : MEM_DEVICE_ONLY)
|
||||
{
|
||||
data_type = device_type_traits<T>::data_type;
|
||||
data_elements = max(device_is_cpu() ? device_type_traits<T>::num_elements_cpu :
|
||||
device_type_traits<T>::num_elements_gpu,
|
||||
1);
|
||||
data_elements = max(device_type_traits<T>::num_elements, 1);
|
||||
}
|
||||
|
||||
device_only_memory(device_only_memory &&other) noexcept : device_memory(std::move(other))
|
||||
@@ -378,15 +366,11 @@ template<typename T> class device_only_memory : public device_memory {
|
||||
|
||||
template<typename T> class device_vector : public device_memory {
|
||||
public:
|
||||
/* Can only use this for types that have the same size on CPU and GPU. */
|
||||
static_assert(device_type_traits<T>::num_elements_cpu ==
|
||||
device_type_traits<T>::num_elements_gpu);
|
||||
|
||||
device_vector(Device *device, const char *name, MemoryType type)
|
||||
: device_memory(device, name, type)
|
||||
{
|
||||
data_type = device_type_traits<T>::data_type;
|
||||
data_elements = device_type_traits<T>::num_elements_cpu;
|
||||
data_elements = device_type_traits<T>::num_elements;
|
||||
modified = true;
|
||||
need_realloc_ = true;
|
||||
|
||||
|
@@ -109,14 +109,6 @@ class MultiDevice : public Device {
|
||||
return error_msg;
|
||||
}
|
||||
|
||||
virtual bool show_samples() const override
|
||||
{
|
||||
if (devices.size() > 1) {
|
||||
return false;
|
||||
}
|
||||
return devices.front().device->show_samples();
|
||||
}
|
||||
|
||||
virtual BVHLayoutMask get_bvh_layout_mask() const override
|
||||
{
|
||||
BVHLayoutMask bvh_layout_mask = BVH_LAYOUT_ALL;
|
||||
|
@@ -1032,7 +1032,7 @@ bool OptiXDevice::build_optix_bvh(BVHOptiX *bvh,
|
||||
return false;
|
||||
}
|
||||
|
||||
device_only_memory<char> &out_data = bvh->as_data;
|
||||
device_only_memory<char> &out_data = *bvh->as_data;
|
||||
if (operation == OPTIX_BUILD_OPERATION_BUILD) {
|
||||
assert(out_data.device == this);
|
||||
out_data.alloc_to_device(sizes.outputSizeInBytes);
|
||||
@@ -1123,7 +1123,7 @@ void OptiXDevice::build_bvh(BVH *bvh, Progress &progress, bool refit)
|
||||
operation = OPTIX_BUILD_OPERATION_UPDATE;
|
||||
}
|
||||
else {
|
||||
bvh_optix->as_data.free();
|
||||
bvh_optix->as_data->free();
|
||||
bvh_optix->traversable_handle = 0;
|
||||
}
|
||||
|
||||
@@ -1344,9 +1344,9 @@ void OptiXDevice::build_bvh(BVH *bvh, Progress &progress, bool refit)
|
||||
unsigned int num_instances = 0;
|
||||
unsigned int max_num_instances = 0xFFFFFFFF;
|
||||
|
||||
bvh_optix->as_data.free();
|
||||
bvh_optix->as_data->free();
|
||||
bvh_optix->traversable_handle = 0;
|
||||
bvh_optix->motion_transform_data.free();
|
||||
bvh_optix->motion_transform_data->free();
|
||||
|
||||
optixDeviceContextGetProperty(context,
|
||||
OPTIX_DEVICE_PROPERTY_LIMIT_MAX_INSTANCE_ID,
|
||||
@@ -1379,8 +1379,8 @@ void OptiXDevice::build_bvh(BVH *bvh, Progress &progress, bool refit)
|
||||
}
|
||||
}
|
||||
|
||||
assert(bvh_optix->motion_transform_data.device == this);
|
||||
bvh_optix->motion_transform_data.alloc_to_device(total_motion_transform_size);
|
||||
assert(bvh_optix->motion_transform_data->device == this);
|
||||
bvh_optix->motion_transform_data->alloc_to_device(total_motion_transform_size);
|
||||
}
|
||||
|
||||
for (Object *ob : bvh->objects) {
|
||||
@@ -1441,7 +1441,7 @@ void OptiXDevice::build_bvh(BVH *bvh, Progress &progress, bool refit)
|
||||
|
||||
motion_transform_offset = align_up(motion_transform_offset,
|
||||
OPTIX_TRANSFORM_BYTE_ALIGNMENT);
|
||||
CUdeviceptr motion_transform_gpu = bvh_optix->motion_transform_data.device_pointer +
|
||||
CUdeviceptr motion_transform_gpu = bvh_optix->motion_transform_data->device_pointer +
|
||||
motion_transform_offset;
|
||||
motion_transform_offset += motion_transform_size;
|
||||
|
||||
|
@@ -23,6 +23,7 @@
|
||||
# include "device/optix/queue.h"
|
||||
# include "device/optix/util.h"
|
||||
# include "kernel/types.h"
|
||||
# include "util/unique_ptr.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
@@ -76,7 +77,7 @@ class OptiXDevice : public CUDADevice {
|
||||
device_only_memory<KernelParamsOptiX> launch_params;
|
||||
OptixTraversableHandle tlas_handle = 0;
|
||||
|
||||
vector<device_only_memory<char>> delayed_free_bvh_memory;
|
||||
vector<unique_ptr<device_only_memory<char>>> delayed_free_bvh_memory;
|
||||
thread_mutex delayed_free_bvh_mutex;
|
||||
|
||||
class Denoiser {
|
||||
|
@@ -3,7 +3,7 @@ This program uses code from various sources, the default license is Apache 2.0
|
||||
for all code, with the following exceptions.
|
||||
|
||||
Modified BSD License
|
||||
* Code adapated from Open Shading Language
|
||||
* Code adapted from Open Shading Language
|
||||
* Sobol direction vectors
|
||||
* Matrix inversion code from OpenEXR
|
||||
* MD5 Hash code
|
||||
|
@@ -47,9 +47,6 @@ static bool oidn_progress_monitor_function(void *user_ptr, double /*n*/)
|
||||
OIDNDenoiser *oidn_denoiser = reinterpret_cast<OIDNDenoiser *>(user_ptr);
|
||||
return !oidn_denoiser->is_cancelled();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WITH_OPENIMAGEDENOISE
|
||||
|
||||
class OIDNPass {
|
||||
public:
|
||||
@@ -547,7 +544,6 @@ class OIDNDenoiseContext {
|
||||
* the fake values and denoising of passes which do need albedo can no longer happen. */
|
||||
bool albedo_replaced_with_fake_ = false;
|
||||
};
|
||||
#endif
|
||||
|
||||
static unique_ptr<DeviceQueue> create_device_queue(const RenderBuffers *render_buffers)
|
||||
{
|
||||
@@ -582,18 +578,20 @@ static void copy_render_buffers_to_device(unique_ptr<DeviceQueue> &queue,
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
bool OIDNDenoiser::denoise_buffer(const BufferParams &buffer_params,
|
||||
RenderBuffers *render_buffers,
|
||||
const int num_samples,
|
||||
bool allow_inplace_modification)
|
||||
{
|
||||
#ifdef WITH_OPENIMAGEDENOISE
|
||||
thread_scoped_lock lock(mutex_);
|
||||
|
||||
/* Make sure the host-side data is available for denoising. */
|
||||
unique_ptr<DeviceQueue> queue = create_device_queue(render_buffers);
|
||||
copy_render_buffers_from_device(queue, render_buffers);
|
||||
|
||||
#ifdef WITH_OPENIMAGEDENOISE
|
||||
OIDNDenoiseContext context(
|
||||
this, params_, buffer_params, render_buffers, num_samples, allow_inplace_modification);
|
||||
|
||||
@@ -620,6 +618,11 @@ bool OIDNDenoiser::denoise_buffer(const BufferParams &buffer_params,
|
||||
* copies data from the device it doesn't overwrite the denoiser buffers. */
|
||||
copy_render_buffers_to_device(queue, render_buffers);
|
||||
}
|
||||
#else
|
||||
(void)buffer_params;
|
||||
(void)render_buffers;
|
||||
(void)num_samples;
|
||||
(void)allow_inplace_modification;
|
||||
#endif
|
||||
|
||||
/* This code is not supposed to run when compiled without OIDN support, so can assume if we made
|
||||
|
@@ -296,13 +296,13 @@ static BufferParams scale_buffer_params(const BufferParams ¶ms, int resoluti
|
||||
|
||||
scaled_params.window_x = params.window_x / resolution_divider;
|
||||
scaled_params.window_y = params.window_y / resolution_divider;
|
||||
scaled_params.window_width = params.window_width / resolution_divider;
|
||||
scaled_params.window_height = params.window_height / resolution_divider;
|
||||
scaled_params.window_width = max(1, params.window_width / resolution_divider);
|
||||
scaled_params.window_height = max(1, params.window_height / resolution_divider);
|
||||
|
||||
scaled_params.full_x = params.full_x / resolution_divider;
|
||||
scaled_params.full_y = params.full_y / resolution_divider;
|
||||
scaled_params.full_width = params.full_width / resolution_divider;
|
||||
scaled_params.full_height = params.full_height / resolution_divider;
|
||||
scaled_params.full_width = max(1, params.full_width / resolution_divider);
|
||||
scaled_params.full_height = max(1, params.full_height / resolution_divider);
|
||||
|
||||
scaled_params.update_offset_stride();
|
||||
|
||||
@@ -850,7 +850,8 @@ void PathTrace::progress_update_if_needed(const RenderWork &render_work)
|
||||
{
|
||||
if (progress_ != nullptr) {
|
||||
const int2 tile_size = get_render_tile_size();
|
||||
const int num_samples_added = tile_size.x * tile_size.y * render_work.path_trace.num_samples;
|
||||
const uint64_t num_samples_added = uint64_t(tile_size.x) * tile_size.y *
|
||||
render_work.path_trace.num_samples;
|
||||
const int current_sample = render_work.path_trace.start_sample +
|
||||
render_work.path_trace.num_samples -
|
||||
render_work.path_trace.sample_offset;
|
||||
|
@@ -76,7 +76,7 @@ class PathTraceDisplay {
|
||||
|
||||
/* Copy buffer of rendered pixels of a given size into a given position of the texture.
|
||||
*
|
||||
* This function does not acquire a lock. The reason for this is is to allow use of this function
|
||||
* This function does not acquire a lock. The reason for this is to allow use of this function
|
||||
* for partial updates from different devices. In this case the caller will acquire the lock
|
||||
* once, update all the slices and release
|
||||
* the lock once. This will ensure that draw() will never use partially updated texture. */
|
||||
|
@@ -840,6 +840,26 @@ int RenderScheduler::get_num_samples_to_path_trace() const
|
||||
num_samples_to_occupy = lround(state_.occupancy_num_samples * 0.7f / state_.occupancy);
|
||||
}
|
||||
|
||||
/* When time limit is used clamp the calculated number of samples to keep occupancy.
|
||||
* This is because time limit causes the last render iteration to happen with less number of
|
||||
* samples, which conflicts with the occupancy (lower number of samples causes lower
|
||||
* occupancy, also the calculation is based on number of previously rendered samples).
|
||||
*
|
||||
* When time limit is not used the number of samples per render iteration is either increasing
|
||||
* or stays the same, so there is no need to clamp number of samples calculated for occupancy.
|
||||
*/
|
||||
if (time_limit_ != 0.0 && state_.start_render_time != 0.0) {
|
||||
const double remaining_render_time = max(
|
||||
0.0, time_limit_ - (time_dt() - state_.start_render_time));
|
||||
const double time_per_sample_average = path_trace_time_.get_average();
|
||||
const double predicted_render_time = num_samples_to_occupy * time_per_sample_average;
|
||||
|
||||
if (predicted_render_time > remaining_render_time) {
|
||||
num_samples_to_occupy = lround(num_samples_to_occupy *
|
||||
(remaining_render_time / predicted_render_time));
|
||||
}
|
||||
}
|
||||
|
||||
num_samples_to_render = max(num_samples_to_render,
|
||||
min(num_samples_to_occupy, max_num_samples_to_render));
|
||||
}
|
||||
|
@@ -273,6 +273,7 @@ set(SRC_KERNEL_UTIL_HEADERS
|
||||
)
|
||||
|
||||
set(SRC_KERNEL_TYPES_HEADERS
|
||||
tables.h
|
||||
textures.h
|
||||
types.h
|
||||
)
|
||||
@@ -410,12 +411,8 @@ if(WITH_CYCLES_CUDA_BINARIES)
|
||||
-I ${CMAKE_CURRENT_SOURCE_DIR}/..
|
||||
-I ${CMAKE_CURRENT_SOURCE_DIR}/device/cuda
|
||||
--use_fast_math
|
||||
-o ${CMAKE_CURRENT_BINARY_DIR}/${cuda_file})
|
||||
|
||||
if(${experimental})
|
||||
set(cuda_flags ${cuda_flags} -D __KERNEL_EXPERIMENTAL__)
|
||||
set(name ${name}_experimental)
|
||||
endif()
|
||||
-o ${CMAKE_CURRENT_BINARY_DIR}/${cuda_file}
|
||||
-Wno-deprecated-gpu-targets)
|
||||
|
||||
if(WITH_NANOVDB)
|
||||
set(cuda_flags ${cuda_flags}
|
||||
@@ -423,6 +420,10 @@ if(WITH_CYCLES_CUDA_BINARIES)
|
||||
-I "${NANOVDB_INCLUDE_DIR}")
|
||||
endif()
|
||||
|
||||
if(WITH_CYCLES_DEBUG)
|
||||
set(cuda_flags ${cuda_flags} -D WITH_CYCLES_DEBUG)
|
||||
endif()
|
||||
|
||||
if(WITH_CYCLES_CUBIN_COMPILER)
|
||||
string(SUBSTRING ${arch} 3 -1 CUDA_ARCH)
|
||||
|
||||
@@ -571,13 +572,14 @@ if(WITH_CYCLES_HIP_BINARIES AND WITH_CYCLES_DEVICE_HIP)
|
||||
-ffast-math
|
||||
-o ${CMAKE_CURRENT_BINARY_DIR}/${hip_file})
|
||||
|
||||
if(${experimental})
|
||||
set(hip_flags ${hip_flags} -D __KERNEL_EXPERIMENTAL__)
|
||||
set(name ${name}_experimental)
|
||||
if(WITH_NANOVDB)
|
||||
set(hip_flags ${hip_flags}
|
||||
-D WITH_NANOVDB
|
||||
-I "${NANOVDB_INCLUDE_DIR}")
|
||||
endif()
|
||||
|
||||
if(WITH_CYCLES_DEBUG)
|
||||
set(hip_flags ${hip_flags} -D __KERNEL_DEBUG__)
|
||||
set(hip_flags ${hip_flags} -D WITH_CYCLES_DEBUG)
|
||||
endif()
|
||||
|
||||
add_custom_command(
|
||||
@@ -618,6 +620,10 @@ if(WITH_CYCLES_DEVICE_OPTIX AND WITH_CYCLES_CUDA_BINARIES)
|
||||
-I "${NANOVDB_INCLUDE_DIR}")
|
||||
endif()
|
||||
|
||||
if(WITH_CYCLES_DEBUG)
|
||||
set(cuda_flags ${cuda_flags} -D WITH_CYCLES_DEBUG)
|
||||
endif()
|
||||
|
||||
if(WITH_CYCLES_CUBIN_COMPILER)
|
||||
# Needed to find libnvrtc-builtins.so. Can't do it from inside
|
||||
# cycles_cubin_cc since the env variable is read before main()
|
||||
@@ -706,7 +712,7 @@ if(WITH_COMPILER_ASAN)
|
||||
string(APPEND CMAKE_CXX_FLAGS_RELWITHDEBINFO " -fno-sanitize=all")
|
||||
string(APPEND CMAKE_CXX_FLAGS_DEBUG " -fno-sanitize=vptr")
|
||||
elseif(CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
# With OSL, Cycles disables rtti in some modules, wich then breaks at linking
|
||||
# With OSL, Cycles disables rtti in some modules, which then breaks at linking
|
||||
# when trying to use vptr sanitizer (included into 'undefined' general option).
|
||||
string(APPEND CMAKE_CXX_FLAGS_RELWITHDEBINFO " -fno-sanitize=vptr")
|
||||
string(APPEND CMAKE_CXX_FLAGS_DEBUG " -fno-sanitize=vptr")
|
||||
|
@@ -97,7 +97,7 @@ ccl_device_inline void sort_intersections_and_normals(ccl_private Intersection *
|
||||
swapped = false;
|
||||
for (int j = 0; j < num_hits - 1; ++j) {
|
||||
if (hits[j].t > hits[j + 1].t) {
|
||||
struct Intersection tmp_hit = hits[j];
|
||||
Intersection tmp_hit = hits[j];
|
||||
float3 tmp_Ng = Ng[j];
|
||||
hits[j] = hits[j + 1];
|
||||
Ng[j] = Ng[j + 1];
|
||||
|
@@ -438,7 +438,7 @@ ccl_device_inline int bsdf_sample(KernelGlobals kg,
|
||||
if (label & LABEL_TRANSMIT) {
|
||||
float threshold_squared = kernel_data.background.transparent_roughness_squared_threshold;
|
||||
|
||||
if (threshold_squared >= 0.0f) {
|
||||
if (threshold_squared >= 0.0f && !(label & LABEL_DIFFUSE)) {
|
||||
if (bsdf_get_specular_roughness_squared(sc) <= threshold_squared) {
|
||||
label |= LABEL_TRANSMIT_TRANSPARENT;
|
||||
}
|
||||
|
@@ -18,6 +18,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "kernel/tables.h"
|
||||
#include "kernel/types.h"
|
||||
#include "kernel/util/profiling.h"
|
||||
|
||||
|
@@ -52,8 +52,9 @@ typedef unsigned long long uint64_t;
|
||||
#endif
|
||||
#define ccl_device_noinline __device__ __noinline__
|
||||
#define ccl_device_noinline_cpu ccl_device
|
||||
#define ccl_device_inline_method ccl_device
|
||||
#define ccl_global
|
||||
#define ccl_static_constant __constant__
|
||||
#define ccl_inline_constant __constant__
|
||||
#define ccl_device_constant __constant__ __device__
|
||||
#define ccl_constant const
|
||||
#define ccl_gpu_shared __shared__
|
||||
@@ -85,7 +86,6 @@ typedef unsigned long long uint64_t;
|
||||
#define ccl_gpu_syncthreads() __syncthreads()
|
||||
#define ccl_gpu_ballot(predicate) __ballot_sync(0xFFFFFFFF, predicate)
|
||||
#define ccl_gpu_shfl_down_sync(mask, var, detla) __shfl_down_sync(mask, var, detla)
|
||||
#define ccl_gpu_popc(x) __popc(x)
|
||||
|
||||
/* GPU texture objects */
|
||||
|
||||
|
@@ -21,6 +21,9 @@
|
||||
#include "kernel/device/gpu/parallel_sorted_index.h"
|
||||
#include "kernel/device/gpu/work_stealing.h"
|
||||
|
||||
/* Include constant tables before entering Metal's context class scope (context_begin.h) */
|
||||
#include "kernel/tables.h"
|
||||
|
||||
#ifdef __KERNEL_METAL__
|
||||
# include "kernel/device/metal/context_begin.h"
|
||||
#endif
|
||||
@@ -464,7 +467,7 @@ ccl_gpu_kernel(GPU_KERNEL_BLOCK_NUM_THREADS, GPU_KERNEL_MAX_REGISTERS)
|
||||
const auto num_active_pixels_mask = ccl_gpu_ballot(!converged);
|
||||
const int lane_id = ccl_gpu_thread_idx_x % ccl_gpu_warp_size;
|
||||
if (lane_id == 0) {
|
||||
atomic_fetch_and_add_uint32(num_active_pixels, ccl_gpu_popc(num_active_pixels_mask));
|
||||
atomic_fetch_and_add_uint32(num_active_pixels, popcount(num_active_pixels_mask));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -892,6 +895,6 @@ ccl_gpu_kernel(GPU_KERNEL_BLOCK_NUM_THREADS, GPU_KERNEL_MAX_REGISTERS)
|
||||
const auto can_split_mask = ccl_gpu_ballot(can_split);
|
||||
const int lane_id = ccl_gpu_thread_idx_x % ccl_gpu_warp_size;
|
||||
if (lane_id == 0) {
|
||||
atomic_fetch_and_add_uint32(num_possible_splits, ccl_gpu_popc(can_split_mask));
|
||||
atomic_fetch_and_add_uint32(num_possible_splits, popcount(can_split_mask));
|
||||
}
|
||||
}
|
||||
|
@@ -85,8 +85,8 @@ __device__ void gpu_parallel_active_index_array(const uint num_states,
|
||||
const uint is_active = (state_index < num_states) ? is_active_op(state_index) : 0;
|
||||
|
||||
/* For each thread within a warp compute how many other active states precede it. */
|
||||
const uint thread_offset = ccl_gpu_popc(ccl_gpu_ballot(is_active) &
|
||||
ccl_gpu_thread_mask(thread_warp));
|
||||
const uint thread_offset = popcount(ccl_gpu_ballot(is_active) &
|
||||
ccl_gpu_thread_mask(thread_warp));
|
||||
|
||||
/* Last thread in warp stores number of active states for each warp. */
|
||||
if (thread_warp == ccl_gpu_warp_size - 1) {
|
||||
|
@@ -45,8 +45,9 @@ typedef unsigned long long uint64_t;
|
||||
#define ccl_device_forceinline __device__ __forceinline__
|
||||
#define ccl_device_noinline __device__ __noinline__
|
||||
#define ccl_device_noinline_cpu ccl_device
|
||||
#define ccl_device_inline_method ccl_device
|
||||
#define ccl_global
|
||||
#define ccl_static_constant __constant__
|
||||
#define ccl_inline_constant __constant__
|
||||
#define ccl_device_constant __constant__ __device__
|
||||
#define ccl_constant const
|
||||
#define ccl_gpu_shared __shared__
|
||||
@@ -84,7 +85,6 @@ typedef unsigned long long uint64_t;
|
||||
#define ccl_gpu_syncthreads() __syncthreads()
|
||||
#define ccl_gpu_ballot(predicate) __ballot(predicate)
|
||||
#define ccl_gpu_shfl_down_sync(mask, var, detla) __shfl_down(var, detla)
|
||||
#define ccl_gpu_popc(x) __popc(x)
|
||||
|
||||
/* GPU texture objects */
|
||||
typedef hipTextureObject_t ccl_gpu_tex_object;
|
||||
|
@@ -34,6 +34,7 @@ using namespace metal;
|
||||
|
||||
#pragma clang diagnostic ignored "-Wunused-variable"
|
||||
#pragma clang diagnostic ignored "-Wsign-compare"
|
||||
#pragma clang diagnostic ignored "-Wuninitialized"
|
||||
|
||||
/* Qualifiers */
|
||||
|
||||
@@ -42,8 +43,9 @@ using namespace metal;
|
||||
#define ccl_device_forceinline ccl_device
|
||||
#define ccl_device_noinline ccl_device __attribute__((noinline))
|
||||
#define ccl_device_noinline_cpu ccl_device
|
||||
#define ccl_device_inline_method ccl_device
|
||||
#define ccl_global device
|
||||
#define ccl_static_constant static constant constexpr
|
||||
#define ccl_inline_constant static constant constexpr
|
||||
#define ccl_device_constant constant
|
||||
#define ccl_constant const device
|
||||
#define ccl_gpu_shared threadgroup
|
||||
@@ -64,7 +66,7 @@ using namespace metal;
|
||||
#define ccl_gpu_thread_mask(thread_warp) uint64_t((1ull << thread_warp) - 1)
|
||||
|
||||
#define ccl_gpu_ballot(predicate) ((uint64_t)((simd_vote::vote_t)simd_ballot(predicate)))
|
||||
#define ccl_gpu_popc(x) popcount(x)
|
||||
#define ccl_gpu_syncthreads() threadgroup_barrier(mem_flags::mem_threadgroup);
|
||||
|
||||
// clang-format off
|
||||
|
||||
@@ -123,7 +125,6 @@ kernel void kernel_metal_##name(device const kernel_gpu_##name *params_struct, \
|
||||
uint simd_group_index [[simdgroup_index_in_threadgroup]], \
|
||||
uint num_simd_groups [[simdgroups_per_threadgroup]]) { \
|
||||
MetalKernelContext context(_launch_params_metal, _metal_ancillaries); \
|
||||
INIT_DEBUG_BUFFER \
|
||||
params_struct->run(context, simdgroup_offset, metal_global_id, metal_local_id, metal_local_size, simdgroup_size, simd_lane_index, simd_group_index, num_simd_groups); \
|
||||
} \
|
||||
void kernel_gpu_##name::run(thread MetalKernelContext& context, \
|
||||
@@ -150,6 +151,31 @@ void kernel_gpu_##name::run(thread MetalKernelContext& context, \
|
||||
|
||||
// clang-format on
|
||||
|
||||
/* volumetric lambda functions - use function objects for lambda-like functionality */
|
||||
#define VOLUME_READ_LAMBDA(function_call) \
|
||||
struct FnObjectRead { \
|
||||
KernelGlobals kg; \
|
||||
ccl_private MetalKernelContext *context; \
|
||||
int state; \
|
||||
\
|
||||
VolumeStack operator()(const int i) const \
|
||||
{ \
|
||||
return context->function_call; \
|
||||
} \
|
||||
} volume_read_lambda_pass{kg, this, state};
|
||||
|
||||
#define VOLUME_WRITE_LAMBDA(function_call) \
|
||||
struct FnObjectWrite { \
|
||||
KernelGlobals kg; \
|
||||
ccl_private MetalKernelContext *context; \
|
||||
int state; \
|
||||
\
|
||||
void operator()(const int i, VolumeStack entry) const \
|
||||
{ \
|
||||
context->function_call; \
|
||||
} \
|
||||
} volume_write_lambda_pass{kg, this, state};
|
||||
|
||||
/* make_type definitions with Metal style element initializers */
|
||||
#ifdef make_float2
|
||||
# undef make_float2
|
||||
@@ -204,6 +230,7 @@ void kernel_gpu_##name::run(thread MetalKernelContext& context, \
|
||||
#define sinhf(x) sinh(float(x))
|
||||
#define coshf(x) cosh(float(x))
|
||||
#define tanhf(x) tanh(float(x))
|
||||
#define saturatef(x) saturate(float(x))
|
||||
|
||||
/* Use native functions with possibly lower precision for performance,
|
||||
* no issues found so far. */
|
||||
@@ -217,6 +244,8 @@ void kernel_gpu_##name::run(thread MetalKernelContext& context, \
|
||||
|
||||
#define NULL 0
|
||||
|
||||
#define __device__
|
||||
|
||||
/* texture bindings and sampler setup */
|
||||
|
||||
struct Texture2DParamsMetal {
|
||||
@@ -231,6 +260,9 @@ struct MetalAncillaries {
|
||||
device Texture3DParamsMetal *textures_3d;
|
||||
};
|
||||
|
||||
#include "util/half.h"
|
||||
#include "util/types.h"
|
||||
|
||||
enum SamplerType {
|
||||
SamplerFilterNearest_AddressRepeat,
|
||||
SamplerFilterNearest_AddressClampEdge,
|
||||
|
@@ -25,7 +25,7 @@ CCL_NAMESPACE_BEGIN
|
||||
|
||||
typedef struct KernelParamsMetal {
|
||||
|
||||
#define KERNEL_TEX(type, name) ccl_constant type *name;
|
||||
#define KERNEL_TEX(type, name) ccl_global const type *name;
|
||||
#include "kernel/textures.h"
|
||||
#undef KERNEL_TEX
|
||||
|
||||
|
@@ -49,10 +49,11 @@ typedef unsigned long long uint64_t;
|
||||
__device__ __forceinline__ // Function calls are bad for OptiX performance, so inline everything
|
||||
#define ccl_device_inline ccl_device
|
||||
#define ccl_device_forceinline ccl_device
|
||||
#define ccl_device_inline_method ccl_device
|
||||
#define ccl_device_noinline __device__ __noinline__
|
||||
#define ccl_device_noinline_cpu ccl_device
|
||||
#define ccl_global
|
||||
#define ccl_static_constant __constant__
|
||||
#define ccl_inline_constant __constant__
|
||||
#define ccl_device_constant __constant__ __device__
|
||||
#define ccl_constant const
|
||||
#define ccl_gpu_shared __shared__
|
||||
@@ -86,7 +87,6 @@ typedef unsigned long long uint64_t;
|
||||
#define ccl_gpu_syncthreads() __syncthreads()
|
||||
#define ccl_gpu_ballot(predicate) __ballot_sync(0xFFFFFFFF, predicate)
|
||||
#define ccl_gpu_shfl_down_sync(mask, var, detla) __shfl_down_sync(mask, var, detla)
|
||||
#define ccl_gpu_popc(x) __popc(x)
|
||||
|
||||
/* GPU texture objects */
|
||||
|
||||
|
@@ -21,6 +21,8 @@
|
||||
|
||||
#include "kernel/device/gpu/image.h" /* Texture lookup uses normal CUDA intrinsics. */
|
||||
|
||||
#include "kernel/tables.h"
|
||||
|
||||
#include "kernel/integrator/state.h"
|
||||
#include "kernel/integrator/state_flow.h"
|
||||
#include "kernel/integrator/state_util.h"
|
||||
@@ -44,7 +46,7 @@ template<typename T> ccl_device_forceinline T *get_payload_ptr_2()
|
||||
ccl_device_forceinline int get_object_id()
|
||||
{
|
||||
#ifdef __OBJECT_MOTION__
|
||||
/* Always get the the instance ID from the TLAS
|
||||
/* Always get the instance ID from the TLAS
|
||||
* There might be a motion transform node between TLAS and BLAS which does not have one. */
|
||||
return optixGetInstanceIdFromHandle(optixGetTransformListHandle(0));
|
||||
#else
|
||||
@@ -159,9 +161,9 @@ extern "C" __global__ void __anyhit__kernel_optix_local_hit()
|
||||
|
||||
/* Record geometric normal. */
|
||||
const uint tri_vindex = kernel_tex_fetch(__tri_vindex, prim).w;
|
||||
const float3 tri_a = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex + 0));
|
||||
const float3 tri_b = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex + 1));
|
||||
const float3 tri_c = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex + 2));
|
||||
const float3 tri_a = kernel_tex_fetch(__tri_verts, tri_vindex + 0);
|
||||
const float3 tri_b = kernel_tex_fetch(__tri_verts, tri_vindex + 1);
|
||||
const float3 tri_c = kernel_tex_fetch(__tri_verts, tri_vindex + 2);
|
||||
local_isect->Ng[hit] = normalize(cross(tri_b - tri_a, tri_c - tri_a));
|
||||
|
||||
/* Continue tracing (without this the trace call would return after the first hit). */
|
||||
|
@@ -160,7 +160,8 @@ ccl_device_inline int kernel_accum_sample(KernelGlobals kg,
|
||||
|
||||
ccl_global float *buffer = kernel_accum_pixel_render_buffer(kg, state, render_buffer);
|
||||
|
||||
return atomic_fetch_and_add_uint32((uint *)(buffer) + kernel_data.film.pass_sample_count, 1) +
|
||||
return atomic_fetch_and_add_uint32(
|
||||
(ccl_global uint *)(buffer) + kernel_data.film.pass_sample_count, 1) +
|
||||
sample_offset;
|
||||
}
|
||||
|
||||
@@ -501,7 +502,7 @@ ccl_device_inline void kernel_accum_light(KernelGlobals kg,
|
||||
|
||||
/* Write shadow pass. */
|
||||
if (kernel_data.film.pass_shadow != PASS_UNUSED && (path_flag & PATH_RAY_SHADOW_FOR_LIGHT) &&
|
||||
(path_flag & PATH_RAY_CAMERA)) {
|
||||
(path_flag & PATH_RAY_TRANSPARENT_BACKGROUND)) {
|
||||
const float3 unshadowed_throughput = INTEGRATOR_STATE(
|
||||
state, shadow_path, unshadowed_throughput);
|
||||
const float3 shadowed_throughput = INTEGRATOR_STATE(state, shadow_path, throughput);
|
||||
@@ -552,7 +553,7 @@ ccl_device_inline void kernel_accum_background(KernelGlobals kg,
|
||||
const bool is_transparent_background_ray,
|
||||
ccl_global float *ccl_restrict render_buffer)
|
||||
{
|
||||
float3 contribution = INTEGRATOR_STATE(state, path, throughput) * L;
|
||||
float3 contribution = float3(INTEGRATOR_STATE(state, path, throughput)) * L;
|
||||
kernel_accum_clamp(kg, &contribution, INTEGRATOR_STATE(state, path, bounce) - 1);
|
||||
|
||||
ccl_global float *buffer = kernel_accum_pixel_render_buffer(kg, state, render_buffer);
|
||||
|
@@ -177,7 +177,7 @@ ccl_device_inline void kernel_write_data_passes(KernelGlobals kg,
|
||||
#ifdef __PASSES__
|
||||
const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag);
|
||||
|
||||
if (!(path_flag & PATH_RAY_CAMERA)) {
|
||||
if (!(path_flag & PATH_RAY_TRANSPARENT_BACKGROUND)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@@ -27,7 +27,12 @@ CCL_NAMESPACE_BEGIN
|
||||
* Lookup of attributes is different between OSL and SVM, as OSL is ustring
|
||||
* based while for SVM we use integer ids. */
|
||||
|
||||
ccl_device_inline uint subd_triangle_patch(KernelGlobals kg, ccl_private const ShaderData *sd);
|
||||
/* Patch index for triangle, -1 if not subdivision triangle */
|
||||
|
||||
ccl_device_inline uint subd_triangle_patch(KernelGlobals kg, ccl_private const ShaderData *sd)
|
||||
{
|
||||
return (sd->prim != PRIM_NONE) ? kernel_tex_fetch(__tri_patch, sd->prim) : ~0;
|
||||
}
|
||||
|
||||
ccl_device_inline uint attribute_primitive_type(KernelGlobals kg, ccl_private const ShaderData *sd)
|
||||
{
|
||||
@@ -106,9 +111,9 @@ ccl_device Transform primitive_attribute_matrix(KernelGlobals kg,
|
||||
{
|
||||
Transform tfm;
|
||||
|
||||
tfm.x = kernel_tex_fetch(__attributes_float3, desc.offset + 0);
|
||||
tfm.y = kernel_tex_fetch(__attributes_float3, desc.offset + 1);
|
||||
tfm.z = kernel_tex_fetch(__attributes_float3, desc.offset + 2);
|
||||
tfm.x = kernel_tex_fetch(__attributes_float4, desc.offset + 0);
|
||||
tfm.y = kernel_tex_fetch(__attributes_float4, desc.offset + 1);
|
||||
tfm.z = kernel_tex_fetch(__attributes_float4, desc.offset + 2);
|
||||
|
||||
return tfm;
|
||||
}
|
||||
|
@@ -126,8 +126,8 @@ ccl_device float3 curve_attribute_float3(KernelGlobals kg,
|
||||
int k0 = curve.first_key + PRIMITIVE_UNPACK_SEGMENT(sd->type);
|
||||
int k1 = k0 + 1;
|
||||
|
||||
float3 f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + k0));
|
||||
float3 f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + k1));
|
||||
float3 f0 = kernel_tex_fetch(__attributes_float3, desc.offset + k0);
|
||||
float3 f1 = kernel_tex_fetch(__attributes_float3, desc.offset + k1);
|
||||
|
||||
# ifdef __RAY_DIFFERENTIALS__
|
||||
if (dx)
|
||||
@@ -149,7 +149,7 @@ ccl_device float3 curve_attribute_float3(KernelGlobals kg,
|
||||
if (desc.element & (ATTR_ELEMENT_CURVE | ATTR_ELEMENT_OBJECT | ATTR_ELEMENT_MESH)) {
|
||||
const int offset = (desc.element == ATTR_ELEMENT_CURVE) ? desc.offset + sd->prim :
|
||||
desc.offset;
|
||||
return float4_to_float3(kernel_tex_fetch(__attributes_float3, offset));
|
||||
return kernel_tex_fetch(__attributes_float3, offset);
|
||||
}
|
||||
else {
|
||||
return make_float3(0.0f, 0.0f, 0.0f);
|
||||
@@ -168,8 +168,8 @@ ccl_device float4 curve_attribute_float4(KernelGlobals kg,
|
||||
int k0 = curve.first_key + PRIMITIVE_UNPACK_SEGMENT(sd->type);
|
||||
int k1 = k0 + 1;
|
||||
|
||||
float4 f0 = kernel_tex_fetch(__attributes_float3, desc.offset + k0);
|
||||
float4 f1 = kernel_tex_fetch(__attributes_float3, desc.offset + k1);
|
||||
float4 f0 = kernel_tex_fetch(__attributes_float4, desc.offset + k0);
|
||||
float4 f1 = kernel_tex_fetch(__attributes_float4, desc.offset + k1);
|
||||
|
||||
# ifdef __RAY_DIFFERENTIALS__
|
||||
if (dx)
|
||||
@@ -191,7 +191,7 @@ ccl_device float4 curve_attribute_float4(KernelGlobals kg,
|
||||
if (desc.element & (ATTR_ELEMENT_CURVE | ATTR_ELEMENT_OBJECT | ATTR_ELEMENT_MESH)) {
|
||||
const int offset = (desc.element == ATTR_ELEMENT_CURVE) ? desc.offset + sd->prim :
|
||||
desc.offset;
|
||||
return kernel_tex_fetch(__attributes_float3, offset);
|
||||
return kernel_tex_fetch(__attributes_float4, offset);
|
||||
}
|
||||
else {
|
||||
return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
@@ -48,8 +48,8 @@ ccl_device_inline void motion_curve_keys_for_step_linear(KernelGlobals kg,
|
||||
|
||||
offset += step * numkeys;
|
||||
|
||||
keys[0] = kernel_tex_fetch(__attributes_float3, offset + k0);
|
||||
keys[1] = kernel_tex_fetch(__attributes_float3, offset + k1);
|
||||
keys[0] = kernel_tex_fetch(__attributes_float4, offset + k0);
|
||||
keys[1] = kernel_tex_fetch(__attributes_float4, offset + k1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,10 +106,10 @@ ccl_device_inline void motion_curve_keys_for_step(KernelGlobals kg,
|
||||
|
||||
offset += step * numkeys;
|
||||
|
||||
keys[0] = kernel_tex_fetch(__attributes_float3, offset + k0);
|
||||
keys[1] = kernel_tex_fetch(__attributes_float3, offset + k1);
|
||||
keys[2] = kernel_tex_fetch(__attributes_float3, offset + k2);
|
||||
keys[3] = kernel_tex_fetch(__attributes_float3, offset + k3);
|
||||
keys[0] = kernel_tex_fetch(__attributes_float4, offset + k0);
|
||||
keys[1] = kernel_tex_fetch(__attributes_float4, offset + k1);
|
||||
keys[2] = kernel_tex_fetch(__attributes_float4, offset + k2);
|
||||
keys[3] = kernel_tex_fetch(__attributes_float4, offset + k3);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -43,9 +43,9 @@ ccl_device_inline void motion_triangle_verts_for_step(KernelGlobals kg,
|
||||
{
|
||||
if (step == numsteps) {
|
||||
/* center step: regular vertex location */
|
||||
verts[0] = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex.w + 0));
|
||||
verts[1] = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex.w + 1));
|
||||
verts[2] = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex.w + 2));
|
||||
verts[0] = kernel_tex_fetch(__tri_verts, tri_vindex.w + 0);
|
||||
verts[1] = kernel_tex_fetch(__tri_verts, tri_vindex.w + 1);
|
||||
verts[2] = kernel_tex_fetch(__tri_verts, tri_vindex.w + 2);
|
||||
}
|
||||
else {
|
||||
/* center step not store in this array */
|
||||
@@ -54,9 +54,9 @@ ccl_device_inline void motion_triangle_verts_for_step(KernelGlobals kg,
|
||||
|
||||
offset += step * numverts;
|
||||
|
||||
verts[0] = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + tri_vindex.x));
|
||||
verts[1] = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + tri_vindex.y));
|
||||
verts[2] = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + tri_vindex.z));
|
||||
verts[0] = kernel_tex_fetch(__attributes_float3, offset + tri_vindex.x);
|
||||
verts[1] = kernel_tex_fetch(__attributes_float3, offset + tri_vindex.y);
|
||||
verts[2] = kernel_tex_fetch(__attributes_float3, offset + tri_vindex.z);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,9 +70,9 @@ ccl_device_inline void motion_triangle_normals_for_step(KernelGlobals kg,
|
||||
{
|
||||
if (step == numsteps) {
|
||||
/* center step: regular vertex location */
|
||||
normals[0] = float4_to_float3(kernel_tex_fetch(__tri_vnormal, tri_vindex.x));
|
||||
normals[1] = float4_to_float3(kernel_tex_fetch(__tri_vnormal, tri_vindex.y));
|
||||
normals[2] = float4_to_float3(kernel_tex_fetch(__tri_vnormal, tri_vindex.z));
|
||||
normals[0] = kernel_tex_fetch(__tri_vnormal, tri_vindex.x);
|
||||
normals[1] = kernel_tex_fetch(__tri_vnormal, tri_vindex.y);
|
||||
normals[2] = kernel_tex_fetch(__tri_vnormal, tri_vindex.z);
|
||||
}
|
||||
else {
|
||||
/* center step is not stored in this array */
|
||||
@@ -81,9 +81,9 @@ ccl_device_inline void motion_triangle_normals_for_step(KernelGlobals kg,
|
||||
|
||||
offset += step * numverts;
|
||||
|
||||
normals[0] = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + tri_vindex.x));
|
||||
normals[1] = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + tri_vindex.y));
|
||||
normals[2] = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + tri_vindex.z));
|
||||
normals[0] = kernel_tex_fetch(__attributes_float3, offset + tri_vindex.x);
|
||||
normals[1] = kernel_tex_fetch(__attributes_float3, offset + tri_vindex.y);
|
||||
normals[2] = kernel_tex_fetch(__attributes_float3, offset + tri_vindex.z);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -163,19 +163,7 @@ ccl_device_inline bool motion_triangle_intersect(KernelGlobals kg,
|
||||
motion_triangle_vertices(kg, fobject, prim, time, verts);
|
||||
/* Ray-triangle intersection, unoptimized. */
|
||||
float t, u, v;
|
||||
if (ray_triangle_intersect(P,
|
||||
dir,
|
||||
tmax,
|
||||
#if defined(__KERNEL_SSE2__) && defined(__KERNEL_SSE__)
|
||||
(ssef *)verts,
|
||||
#else
|
||||
verts[0],
|
||||
verts[1],
|
||||
verts[2],
|
||||
#endif
|
||||
&u,
|
||||
&v,
|
||||
&t)) {
|
||||
if (ray_triangle_intersect(P, dir, tmax, verts[0], verts[1], verts[2], &u, &v, &t)) {
|
||||
#ifdef __VISIBILITY_FLAG__
|
||||
/* Visibility flag test. we do it here under the assumption
|
||||
* that most triangles are culled by node flags.
|
||||
@@ -229,19 +217,7 @@ ccl_device_inline bool motion_triangle_intersect_local(KernelGlobals kg,
|
||||
motion_triangle_vertices(kg, local_object, prim, time, verts);
|
||||
/* Ray-triangle intersection, unoptimized. */
|
||||
float t, u, v;
|
||||
if (!ray_triangle_intersect(P,
|
||||
dir,
|
||||
tmax,
|
||||
# if defined(__KERNEL_SSE2__) && defined(__KERNEL_SSE__)
|
||||
(ssef *)verts,
|
||||
# else
|
||||
verts[0],
|
||||
verts[1],
|
||||
verts[2],
|
||||
# endif
|
||||
&u,
|
||||
&v,
|
||||
&t)) {
|
||||
if (!ray_triangle_intersect(P, dir, tmax, verts[0], verts[1], verts[2], &u, &v, &t)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@@ -380,7 +380,7 @@ ccl_device float3 patch_eval_float3(KernelGlobals kg,
|
||||
*dv = make_float3(0.0f, 0.0f, 0.0f);
|
||||
|
||||
for (int i = 0; i < num_control; i++) {
|
||||
float3 v = float4_to_float3(kernel_tex_fetch(__attributes_float3, offset + indices[i]));
|
||||
float3 v = kernel_tex_fetch(__attributes_float3, offset + indices[i]);
|
||||
|
||||
val += v * weights[i];
|
||||
if (du)
|
||||
@@ -417,7 +417,7 @@ ccl_device float4 patch_eval_float4(KernelGlobals kg,
|
||||
*dv = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
for (int i = 0; i < num_control; i++) {
|
||||
float4 v = kernel_tex_fetch(__attributes_float3, offset + indices[i]);
|
||||
float4 v = kernel_tex_fetch(__attributes_float4, offset + indices[i]);
|
||||
|
||||
val += v * weights[i];
|
||||
if (du)
|
||||
|
@@ -284,18 +284,33 @@ ccl_device_inline float4 primitive_motion_vector(KernelGlobals kg,
|
||||
int numverts, numkeys;
|
||||
object_motion_info(kg, sd->object, NULL, &numverts, &numkeys);
|
||||
|
||||
/* lookup attributes */
|
||||
motion_pre = primitive_surface_attribute_float3(kg, sd, desc, NULL, NULL);
|
||||
|
||||
desc.offset += (sd->type & PRIMITIVE_ALL_TRIANGLE) ? numverts : numkeys;
|
||||
motion_post = primitive_surface_attribute_float3(kg, sd, desc, NULL, NULL);
|
||||
|
||||
#ifdef __HAIR__
|
||||
if (is_curve_primitive && (sd->object_flag & SD_OBJECT_HAS_VERTEX_MOTION) == 0) {
|
||||
object_position_transform(kg, sd, &motion_pre);
|
||||
object_position_transform(kg, sd, &motion_post);
|
||||
if (is_curve_primitive) {
|
||||
motion_pre = float4_to_float3(curve_attribute_float4(kg, sd, desc, NULL, NULL));
|
||||
desc.offset += numkeys;
|
||||
motion_post = float4_to_float3(curve_attribute_float4(kg, sd, desc, NULL, NULL));
|
||||
|
||||
/* Curve */
|
||||
if ((sd->object_flag & SD_OBJECT_HAS_VERTEX_MOTION) == 0) {
|
||||
object_position_transform(kg, sd, &motion_pre);
|
||||
object_position_transform(kg, sd, &motion_post);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (sd->type & PRIMITIVE_ALL_TRIANGLE) {
|
||||
/* Triangle */
|
||||
if (subd_triangle_patch(kg, sd) == ~0) {
|
||||
motion_pre = triangle_attribute_float3(kg, sd, desc, NULL, NULL);
|
||||
desc.offset += numverts;
|
||||
motion_post = triangle_attribute_float3(kg, sd, desc, NULL, NULL);
|
||||
}
|
||||
else {
|
||||
motion_pre = subd_triangle_attribute_float3(kg, sd, desc, NULL, NULL);
|
||||
desc.offset += numverts;
|
||||
motion_post = subd_triangle_attribute_float3(kg, sd, desc, NULL, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* object motion. note that depending on the mesh having motion vectors, this
|
||||
|
@@ -20,13 +20,6 @@
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
/* Patch index for triangle, -1 if not subdivision triangle */
|
||||
|
||||
ccl_device_inline uint subd_triangle_patch(KernelGlobals kg, ccl_private const ShaderData *sd)
|
||||
{
|
||||
return (sd->prim != PRIM_NONE) ? kernel_tex_fetch(__tri_patch, sd->prim) : ~0;
|
||||
}
|
||||
|
||||
/* UV coords of triangle within patch */
|
||||
|
||||
ccl_device_inline void subd_triangle_patch_uv(KernelGlobals kg,
|
||||
@@ -443,8 +436,8 @@ ccl_device_noinline float3 subd_triangle_attribute_float3(KernelGlobals kg,
|
||||
if (dy)
|
||||
*dy = make_float3(0.0f, 0.0f, 0.0f);
|
||||
|
||||
return float4_to_float3(
|
||||
kernel_tex_fetch(__attributes_float3, desc.offset + subd_triangle_patch_face(kg, patch)));
|
||||
return kernel_tex_fetch(__attributes_float3,
|
||||
desc.offset + subd_triangle_patch_face(kg, patch));
|
||||
}
|
||||
else if (desc.element == ATTR_ELEMENT_VERTEX || desc.element == ATTR_ELEMENT_VERTEX_MOTION) {
|
||||
float2 uv[3];
|
||||
@@ -452,10 +445,10 @@ ccl_device_noinline float3 subd_triangle_attribute_float3(KernelGlobals kg,
|
||||
|
||||
uint4 v = subd_triangle_patch_indices(kg, patch);
|
||||
|
||||
float3 f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + v.x));
|
||||
float3 f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + v.y));
|
||||
float3 f2 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + v.z));
|
||||
float3 f3 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + v.w));
|
||||
float3 f0 = kernel_tex_fetch(__attributes_float3, desc.offset + v.x);
|
||||
float3 f1 = kernel_tex_fetch(__attributes_float3, desc.offset + v.y);
|
||||
float3 f2 = kernel_tex_fetch(__attributes_float3, desc.offset + v.z);
|
||||
float3 f3 = kernel_tex_fetch(__attributes_float3, desc.offset + v.w);
|
||||
|
||||
if (subd_triangle_patch_num_corners(kg, patch) != 4) {
|
||||
f1 = (f1 + f0) * 0.5f;
|
||||
@@ -484,10 +477,10 @@ ccl_device_noinline float3 subd_triangle_attribute_float3(KernelGlobals kg,
|
||||
|
||||
float3 f0, f1, f2, f3;
|
||||
|
||||
f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, corners[0] + desc.offset));
|
||||
f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, corners[1] + desc.offset));
|
||||
f2 = float4_to_float3(kernel_tex_fetch(__attributes_float3, corners[2] + desc.offset));
|
||||
f3 = float4_to_float3(kernel_tex_fetch(__attributes_float3, corners[3] + desc.offset));
|
||||
f0 = kernel_tex_fetch(__attributes_float3, corners[0] + desc.offset);
|
||||
f1 = kernel_tex_fetch(__attributes_float3, corners[1] + desc.offset);
|
||||
f2 = kernel_tex_fetch(__attributes_float3, corners[2] + desc.offset);
|
||||
f3 = kernel_tex_fetch(__attributes_float3, corners[3] + desc.offset);
|
||||
|
||||
if (subd_triangle_patch_num_corners(kg, patch) != 4) {
|
||||
f1 = (f1 + f0) * 0.5f;
|
||||
@@ -513,7 +506,7 @@ ccl_device_noinline float3 subd_triangle_attribute_float3(KernelGlobals kg,
|
||||
if (dy)
|
||||
*dy = make_float3(0.0f, 0.0f, 0.0f);
|
||||
|
||||
return float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset));
|
||||
return kernel_tex_fetch(__attributes_float3, desc.offset);
|
||||
}
|
||||
else {
|
||||
if (dx)
|
||||
@@ -590,7 +583,7 @@ ccl_device_noinline float4 subd_triangle_attribute_float4(KernelGlobals kg,
|
||||
if (dy)
|
||||
*dy = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
return kernel_tex_fetch(__attributes_float3,
|
||||
return kernel_tex_fetch(__attributes_float4,
|
||||
desc.offset + subd_triangle_patch_face(kg, patch));
|
||||
}
|
||||
else if (desc.element == ATTR_ELEMENT_VERTEX || desc.element == ATTR_ELEMENT_VERTEX_MOTION) {
|
||||
@@ -599,10 +592,10 @@ ccl_device_noinline float4 subd_triangle_attribute_float4(KernelGlobals kg,
|
||||
|
||||
uint4 v = subd_triangle_patch_indices(kg, patch);
|
||||
|
||||
float4 f0 = kernel_tex_fetch(__attributes_float3, desc.offset + v.x);
|
||||
float4 f1 = kernel_tex_fetch(__attributes_float3, desc.offset + v.y);
|
||||
float4 f2 = kernel_tex_fetch(__attributes_float3, desc.offset + v.z);
|
||||
float4 f3 = kernel_tex_fetch(__attributes_float3, desc.offset + v.w);
|
||||
float4 f0 = kernel_tex_fetch(__attributes_float4, desc.offset + v.x);
|
||||
float4 f1 = kernel_tex_fetch(__attributes_float4, desc.offset + v.y);
|
||||
float4 f2 = kernel_tex_fetch(__attributes_float4, desc.offset + v.z);
|
||||
float4 f3 = kernel_tex_fetch(__attributes_float4, desc.offset + v.w);
|
||||
|
||||
if (subd_triangle_patch_num_corners(kg, patch) != 4) {
|
||||
f1 = (f1 + f0) * 0.5f;
|
||||
@@ -642,10 +635,10 @@ ccl_device_noinline float4 subd_triangle_attribute_float4(KernelGlobals kg,
|
||||
color_uchar4_to_float4(kernel_tex_fetch(__attributes_uchar4, corners[3] + desc.offset)));
|
||||
}
|
||||
else {
|
||||
f0 = kernel_tex_fetch(__attributes_float3, corners[0] + desc.offset);
|
||||
f1 = kernel_tex_fetch(__attributes_float3, corners[1] + desc.offset);
|
||||
f2 = kernel_tex_fetch(__attributes_float3, corners[2] + desc.offset);
|
||||
f3 = kernel_tex_fetch(__attributes_float3, corners[3] + desc.offset);
|
||||
f0 = kernel_tex_fetch(__attributes_float4, corners[0] + desc.offset);
|
||||
f1 = kernel_tex_fetch(__attributes_float4, corners[1] + desc.offset);
|
||||
f2 = kernel_tex_fetch(__attributes_float4, corners[2] + desc.offset);
|
||||
f3 = kernel_tex_fetch(__attributes_float4, corners[3] + desc.offset);
|
||||
}
|
||||
|
||||
if (subd_triangle_patch_num_corners(kg, patch) != 4) {
|
||||
@@ -672,7 +665,7 @@ ccl_device_noinline float4 subd_triangle_attribute_float4(KernelGlobals kg,
|
||||
if (dy)
|
||||
*dy = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
return kernel_tex_fetch(__attributes_float3, desc.offset);
|
||||
return kernel_tex_fetch(__attributes_float4, desc.offset);
|
||||
}
|
||||
else {
|
||||
if (dx)
|
||||
|
@@ -29,9 +29,9 @@ ccl_device_inline float3 triangle_normal(KernelGlobals kg, ccl_private ShaderDat
|
||||
{
|
||||
/* load triangle vertices */
|
||||
const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, sd->prim);
|
||||
const float3 v0 = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex.w + 0));
|
||||
const float3 v1 = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex.w + 1));
|
||||
const float3 v2 = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex.w + 2));
|
||||
const float3 v0 = kernel_tex_fetch(__tri_verts, tri_vindex.w + 0);
|
||||
const float3 v1 = kernel_tex_fetch(__tri_verts, tri_vindex.w + 1);
|
||||
const float3 v2 = kernel_tex_fetch(__tri_verts, tri_vindex.w + 2);
|
||||
|
||||
/* return normal */
|
||||
if (sd->object_flag & SD_OBJECT_NEGATIVE_SCALE_APPLIED) {
|
||||
@@ -54,9 +54,9 @@ ccl_device_inline void triangle_point_normal(KernelGlobals kg,
|
||||
{
|
||||
/* load triangle vertices */
|
||||
const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim);
|
||||
float3 v0 = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex.w + 0));
|
||||
float3 v1 = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex.w + 1));
|
||||
float3 v2 = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex.w + 2));
|
||||
float3 v0 = kernel_tex_fetch(__tri_verts, tri_vindex.w + 0);
|
||||
float3 v1 = kernel_tex_fetch(__tri_verts, tri_vindex.w + 1);
|
||||
float3 v2 = kernel_tex_fetch(__tri_verts, tri_vindex.w + 2);
|
||||
/* compute point */
|
||||
float t = 1.0f - u - v;
|
||||
*P = (u * v0 + v * v1 + t * v2);
|
||||
@@ -78,9 +78,9 @@ ccl_device_inline void triangle_point_normal(KernelGlobals kg,
|
||||
ccl_device_inline void triangle_vertices(KernelGlobals kg, int prim, float3 P[3])
|
||||
{
|
||||
const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim);
|
||||
P[0] = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex.w + 0));
|
||||
P[1] = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex.w + 1));
|
||||
P[2] = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex.w + 2));
|
||||
P[0] = kernel_tex_fetch(__tri_verts, tri_vindex.w + 0);
|
||||
P[1] = kernel_tex_fetch(__tri_verts, tri_vindex.w + 1);
|
||||
P[2] = kernel_tex_fetch(__tri_verts, tri_vindex.w + 2);
|
||||
}
|
||||
|
||||
/* Triangle vertex locations and vertex normals */
|
||||
@@ -91,12 +91,12 @@ ccl_device_inline void triangle_vertices_and_normals(KernelGlobals kg,
|
||||
float3 N[3])
|
||||
{
|
||||
const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim);
|
||||
P[0] = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex.w + 0));
|
||||
P[1] = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex.w + 1));
|
||||
P[2] = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex.w + 2));
|
||||
N[0] = float4_to_float3(kernel_tex_fetch(__tri_vnormal, tri_vindex.x));
|
||||
N[1] = float4_to_float3(kernel_tex_fetch(__tri_vnormal, tri_vindex.y));
|
||||
N[2] = float4_to_float3(kernel_tex_fetch(__tri_vnormal, tri_vindex.z));
|
||||
P[0] = kernel_tex_fetch(__tri_verts, tri_vindex.w + 0);
|
||||
P[1] = kernel_tex_fetch(__tri_verts, tri_vindex.w + 1);
|
||||
P[2] = kernel_tex_fetch(__tri_verts, tri_vindex.w + 2);
|
||||
N[0] = kernel_tex_fetch(__tri_vnormal, tri_vindex.x);
|
||||
N[1] = kernel_tex_fetch(__tri_vnormal, tri_vindex.y);
|
||||
N[2] = kernel_tex_fetch(__tri_vnormal, tri_vindex.z);
|
||||
}
|
||||
|
||||
/* Interpolate smooth vertex normal from vertices */
|
||||
@@ -106,9 +106,9 @@ triangle_smooth_normal(KernelGlobals kg, float3 Ng, int prim, float u, float v)
|
||||
{
|
||||
/* load triangle vertices */
|
||||
const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim);
|
||||
float3 n0 = float4_to_float3(kernel_tex_fetch(__tri_vnormal, tri_vindex.x));
|
||||
float3 n1 = float4_to_float3(kernel_tex_fetch(__tri_vnormal, tri_vindex.y));
|
||||
float3 n2 = float4_to_float3(kernel_tex_fetch(__tri_vnormal, tri_vindex.z));
|
||||
float3 n0 = kernel_tex_fetch(__tri_vnormal, tri_vindex.x);
|
||||
float3 n1 = kernel_tex_fetch(__tri_vnormal, tri_vindex.y);
|
||||
float3 n2 = kernel_tex_fetch(__tri_vnormal, tri_vindex.z);
|
||||
|
||||
float3 N = safe_normalize((1.0f - u - v) * n2 + u * n0 + v * n1);
|
||||
|
||||
@@ -120,9 +120,9 @@ ccl_device_inline float3 triangle_smooth_normal_unnormalized(
|
||||
{
|
||||
/* load triangle vertices */
|
||||
const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim);
|
||||
float3 n0 = float4_to_float3(kernel_tex_fetch(__tri_vnormal, tri_vindex.x));
|
||||
float3 n1 = float4_to_float3(kernel_tex_fetch(__tri_vnormal, tri_vindex.y));
|
||||
float3 n2 = float4_to_float3(kernel_tex_fetch(__tri_vnormal, tri_vindex.z));
|
||||
float3 n0 = kernel_tex_fetch(__tri_vnormal, tri_vindex.x);
|
||||
float3 n1 = kernel_tex_fetch(__tri_vnormal, tri_vindex.y);
|
||||
float3 n2 = kernel_tex_fetch(__tri_vnormal, tri_vindex.z);
|
||||
|
||||
/* ensure that the normals are in object space */
|
||||
if (sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED) {
|
||||
@@ -145,9 +145,9 @@ ccl_device_inline void triangle_dPdudv(KernelGlobals kg,
|
||||
{
|
||||
/* fetch triangle vertex coordinates */
|
||||
const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim);
|
||||
const float3 p0 = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex.w + 0));
|
||||
const float3 p1 = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex.w + 1));
|
||||
const float3 p2 = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex.w + 2));
|
||||
const float3 p0 = kernel_tex_fetch(__tri_verts, tri_vindex.w + 0);
|
||||
const float3 p1 = kernel_tex_fetch(__tri_verts, tri_vindex.w + 1);
|
||||
const float3 p2 = kernel_tex_fetch(__tri_verts, tri_vindex.w + 2);
|
||||
|
||||
/* compute derivatives of P w.r.t. uv */
|
||||
*dPdu = (p0 - p2);
|
||||
@@ -267,15 +267,15 @@ ccl_device float3 triangle_attribute_float3(KernelGlobals kg,
|
||||
|
||||
if (desc.element & (ATTR_ELEMENT_VERTEX | ATTR_ELEMENT_VERTEX_MOTION)) {
|
||||
const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, sd->prim);
|
||||
f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + tri_vindex.x));
|
||||
f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + tri_vindex.y));
|
||||
f2 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + tri_vindex.z));
|
||||
f0 = kernel_tex_fetch(__attributes_float3, desc.offset + tri_vindex.x);
|
||||
f1 = kernel_tex_fetch(__attributes_float3, desc.offset + tri_vindex.y);
|
||||
f2 = kernel_tex_fetch(__attributes_float3, desc.offset + tri_vindex.z);
|
||||
}
|
||||
else {
|
||||
const int tri = desc.offset + sd->prim * 3;
|
||||
f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, tri + 0));
|
||||
f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, tri + 1));
|
||||
f2 = float4_to_float3(kernel_tex_fetch(__attributes_float3, tri + 2));
|
||||
f0 = kernel_tex_fetch(__attributes_float3, tri + 0);
|
||||
f1 = kernel_tex_fetch(__attributes_float3, tri + 1);
|
||||
f2 = kernel_tex_fetch(__attributes_float3, tri + 2);
|
||||
}
|
||||
|
||||
#ifdef __RAY_DIFFERENTIALS__
|
||||
@@ -298,7 +298,7 @@ ccl_device float3 triangle_attribute_float3(KernelGlobals kg,
|
||||
if (desc.element & (ATTR_ELEMENT_FACE | ATTR_ELEMENT_OBJECT | ATTR_ELEMENT_MESH)) {
|
||||
const int offset = (desc.element == ATTR_ELEMENT_FACE) ? desc.offset + sd->prim :
|
||||
desc.offset;
|
||||
return float4_to_float3(kernel_tex_fetch(__attributes_float3, offset));
|
||||
return kernel_tex_fetch(__attributes_float3, offset);
|
||||
}
|
||||
else {
|
||||
return make_float3(0.0f, 0.0f, 0.0f);
|
||||
@@ -318,16 +318,16 @@ ccl_device float4 triangle_attribute_float4(KernelGlobals kg,
|
||||
|
||||
if (desc.element & (ATTR_ELEMENT_VERTEX | ATTR_ELEMENT_VERTEX_MOTION)) {
|
||||
const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, sd->prim);
|
||||
f0 = kernel_tex_fetch(__attributes_float3, desc.offset + tri_vindex.x);
|
||||
f1 = kernel_tex_fetch(__attributes_float3, desc.offset + tri_vindex.y);
|
||||
f2 = kernel_tex_fetch(__attributes_float3, desc.offset + tri_vindex.z);
|
||||
f0 = kernel_tex_fetch(__attributes_float4, desc.offset + tri_vindex.x);
|
||||
f1 = kernel_tex_fetch(__attributes_float4, desc.offset + tri_vindex.y);
|
||||
f2 = kernel_tex_fetch(__attributes_float4, desc.offset + tri_vindex.z);
|
||||
}
|
||||
else {
|
||||
const int tri = desc.offset + sd->prim * 3;
|
||||
if (desc.element == ATTR_ELEMENT_CORNER) {
|
||||
f0 = kernel_tex_fetch(__attributes_float3, tri + 0);
|
||||
f1 = kernel_tex_fetch(__attributes_float3, tri + 1);
|
||||
f2 = kernel_tex_fetch(__attributes_float3, tri + 2);
|
||||
f0 = kernel_tex_fetch(__attributes_float4, tri + 0);
|
||||
f1 = kernel_tex_fetch(__attributes_float4, tri + 1);
|
||||
f2 = kernel_tex_fetch(__attributes_float4, tri + 2);
|
||||
}
|
||||
else {
|
||||
f0 = color_srgb_to_linear_v4(
|
||||
@@ -359,7 +359,7 @@ ccl_device float4 triangle_attribute_float4(KernelGlobals kg,
|
||||
if (desc.element & (ATTR_ELEMENT_FACE | ATTR_ELEMENT_OBJECT | ATTR_ELEMENT_MESH)) {
|
||||
const int offset = (desc.element == ATTR_ELEMENT_FACE) ? desc.offset + sd->prim :
|
||||
desc.offset;
|
||||
return kernel_tex_fetch(__attributes_float3, offset);
|
||||
return kernel_tex_fetch(__attributes_float4, offset);
|
||||
}
|
||||
else {
|
||||
return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
@@ -37,27 +37,11 @@ ccl_device_inline bool triangle_intersect(KernelGlobals kg,
|
||||
{
|
||||
const int prim = kernel_tex_fetch(__prim_index, prim_addr);
|
||||
const uint tri_vindex = kernel_tex_fetch(__tri_vindex, prim).w;
|
||||
#if defined(__KERNEL_SSE2__) && defined(__KERNEL_SSE__)
|
||||
const ssef *ssef_verts = (ssef *)&kg->__tri_verts.data[tri_vindex];
|
||||
#else
|
||||
const float4 tri_a = kernel_tex_fetch(__tri_verts, tri_vindex + 0),
|
||||
const float3 tri_a = kernel_tex_fetch(__tri_verts, tri_vindex + 0),
|
||||
tri_b = kernel_tex_fetch(__tri_verts, tri_vindex + 1),
|
||||
tri_c = kernel_tex_fetch(__tri_verts, tri_vindex + 2);
|
||||
#endif
|
||||
float t, u, v;
|
||||
if (ray_triangle_intersect(P,
|
||||
dir,
|
||||
tmax,
|
||||
#if defined(__KERNEL_SSE2__) && defined(__KERNEL_SSE__)
|
||||
ssef_verts,
|
||||
#else
|
||||
float4_to_float3(tri_a),
|
||||
float4_to_float3(tri_b),
|
||||
float4_to_float3(tri_c),
|
||||
#endif
|
||||
&u,
|
||||
&v,
|
||||
&t)) {
|
||||
if (ray_triangle_intersect(P, dir, tmax, tri_a, tri_b, tri_c, &u, &v, &t)) {
|
||||
#ifdef __VISIBILITY_FLAG__
|
||||
/* Visibility flag test. we do it here under the assumption
|
||||
* that most triangles are culled by node flags.
|
||||
@@ -106,27 +90,11 @@ ccl_device_inline bool triangle_intersect_local(KernelGlobals kg,
|
||||
|
||||
const int prim = kernel_tex_fetch(__prim_index, prim_addr);
|
||||
const uint tri_vindex = kernel_tex_fetch(__tri_vindex, prim).w;
|
||||
# if defined(__KERNEL_SSE2__) && defined(__KERNEL_SSE__)
|
||||
const ssef *ssef_verts = (ssef *)&kg->__tri_verts.data[tri_vindex];
|
||||
# else
|
||||
const float3 tri_a = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex + 0)),
|
||||
tri_b = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex + 1)),
|
||||
tri_c = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex + 2));
|
||||
# endif
|
||||
const float3 tri_a = kernel_tex_fetch(__tri_verts, tri_vindex + 0),
|
||||
tri_b = kernel_tex_fetch(__tri_verts, tri_vindex + 1),
|
||||
tri_c = kernel_tex_fetch(__tri_verts, tri_vindex + 2);
|
||||
float t, u, v;
|
||||
if (!ray_triangle_intersect(P,
|
||||
dir,
|
||||
tmax,
|
||||
# if defined(__KERNEL_SSE2__) && defined(__KERNEL_SSE__)
|
||||
ssef_verts,
|
||||
# else
|
||||
tri_a,
|
||||
tri_b,
|
||||
tri_c,
|
||||
# endif
|
||||
&u,
|
||||
&v,
|
||||
&t)) {
|
||||
if (!ray_triangle_intersect(P, dir, tmax, tri_a, tri_b, tri_c, &u, &v, &t)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -178,11 +146,6 @@ ccl_device_inline bool triangle_intersect_local(KernelGlobals kg,
|
||||
isect->t = t;
|
||||
|
||||
/* Record geometric normal. */
|
||||
# if defined(__KERNEL_SSE2__) && defined(__KERNEL_SSE__)
|
||||
const float3 tri_a = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex + 0)),
|
||||
tri_b = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex + 1)),
|
||||
tri_c = float4_to_float3(kernel_tex_fetch(__tri_verts, tri_vindex + 2));
|
||||
# endif
|
||||
local_isect->Ng[hit] = normalize(cross(tri_b - tri_a, tri_c - tri_a));
|
||||
|
||||
return false;
|
||||
@@ -223,9 +186,9 @@ ccl_device_inline float3 triangle_refine(KernelGlobals kg,
|
||||
P = P + D * t;
|
||||
|
||||
const uint tri_vindex = kernel_tex_fetch(__tri_vindex, isect_prim).w;
|
||||
const float4 tri_a = kernel_tex_fetch(__tri_verts, tri_vindex + 0),
|
||||
tri_b = kernel_tex_fetch(__tri_verts, tri_vindex + 1),
|
||||
tri_c = kernel_tex_fetch(__tri_verts, tri_vindex + 2);
|
||||
const packed_float3 tri_a = kernel_tex_fetch(__tri_verts, tri_vindex + 0),
|
||||
tri_b = kernel_tex_fetch(__tri_verts, tri_vindex + 1),
|
||||
tri_c = kernel_tex_fetch(__tri_verts, tri_vindex + 2);
|
||||
float3 edge1 = make_float3(tri_a.x - tri_c.x, tri_a.y - tri_c.y, tri_a.z - tri_c.z);
|
||||
float3 edge2 = make_float3(tri_b.x - tri_c.x, tri_b.y - tri_c.y, tri_b.z - tri_c.z);
|
||||
float3 tvec = make_float3(P.x - tri_c.x, P.y - tri_c.y, P.z - tri_c.z);
|
||||
@@ -280,9 +243,9 @@ ccl_device_inline float3 triangle_refine_local(KernelGlobals kg,
|
||||
|
||||
# ifdef __INTERSECTION_REFINE__
|
||||
const uint tri_vindex = kernel_tex_fetch(__tri_vindex, isect_prim).w;
|
||||
const float4 tri_a = kernel_tex_fetch(__tri_verts, tri_vindex + 0),
|
||||
tri_b = kernel_tex_fetch(__tri_verts, tri_vindex + 1),
|
||||
tri_c = kernel_tex_fetch(__tri_verts, tri_vindex + 2);
|
||||
const packed_float3 tri_a = kernel_tex_fetch(__tri_verts, tri_vindex + 0),
|
||||
tri_b = kernel_tex_fetch(__tri_verts, tri_vindex + 1),
|
||||
tri_c = kernel_tex_fetch(__tri_verts, tri_vindex + 2);
|
||||
float3 edge1 = make_float3(tri_a.x - tri_c.x, tri_a.y - tri_c.y, tri_a.z - tri_c.z);
|
||||
float3 edge2 = make_float3(tri_b.x - tri_c.x, tri_b.y - tri_c.y, tri_b.z - tri_c.z);
|
||||
float3 tvec = make_float3(P.x - tri_c.x, P.y - tri_c.y, P.z - tri_c.z);
|
||||
|
@@ -75,7 +75,7 @@ ccl_device float4 volume_attribute_float4(KernelGlobals kg,
|
||||
const AttributeDescriptor desc)
|
||||
{
|
||||
if (desc.element & (ATTR_ELEMENT_OBJECT | ATTR_ELEMENT_MESH)) {
|
||||
return kernel_tex_fetch(__attributes_float3, desc.offset);
|
||||
return kernel_tex_fetch(__attributes_float4, desc.offset);
|
||||
}
|
||||
else if (desc.element == ATTR_ELEMENT_VOXEL) {
|
||||
/* todo: optimize this so we don't have to transform both here and in
|
||||
|
@@ -71,14 +71,16 @@ ccl_device bool integrator_init_from_bake(KernelGlobals kg,
|
||||
/* Setup render buffers. */
|
||||
const int index = INTEGRATOR_STATE(state, path, render_pixel_index);
|
||||
const int pass_stride = kernel_data.film.pass_stride;
|
||||
render_buffer += index * pass_stride;
|
||||
ccl_global float *buffer = render_buffer + index * pass_stride;
|
||||
|
||||
ccl_global float *primitive = render_buffer + kernel_data.film.pass_bake_primitive;
|
||||
ccl_global float *differential = render_buffer + kernel_data.film.pass_bake_differential;
|
||||
ccl_global float *primitive = buffer + kernel_data.film.pass_bake_primitive;
|
||||
ccl_global float *differential = buffer + kernel_data.film.pass_bake_differential;
|
||||
|
||||
const int seed = __float_as_uint(primitive[0]);
|
||||
int prim = __float_as_uint(primitive[1]);
|
||||
if (prim == -1) {
|
||||
/* Accumulate transparency for empty pixels. */
|
||||
kernel_accum_transparent(kg, state, 0, 1.0f, buffer);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@@ -122,7 +122,7 @@ ccl_device_inline void path_state_next(KernelGlobals kg, IntegratorState state,
|
||||
/* volume scatter */
|
||||
flag |= PATH_RAY_VOLUME_SCATTER;
|
||||
flag &= ~PATH_RAY_TRANSPARENT_BACKGROUND;
|
||||
if (bounce == 1) {
|
||||
if (!(flag & PATH_RAY_ANY_PASS)) {
|
||||
flag |= PATH_RAY_VOLUME_PASS;
|
||||
}
|
||||
|
||||
@@ -184,7 +184,7 @@ ccl_device_inline void path_state_next(KernelGlobals kg, IntegratorState state,
|
||||
}
|
||||
|
||||
/* Render pass categories. */
|
||||
if (bounce == 1) {
|
||||
if (!(flag & PATH_RAY_ANY_PASS) && !(flag & PATH_RAY_TRANSPARENT_BACKGROUND)) {
|
||||
flag |= PATH_RAY_SURFACE_PASS;
|
||||
}
|
||||
}
|
||||
@@ -208,9 +208,7 @@ ccl_device_inline bool path_state_volume_next(IntegratorState state)
|
||||
}
|
||||
|
||||
/* Random number generator next bounce. */
|
||||
if (volume_bounds_bounce > 1) {
|
||||
INTEGRATOR_STATE_WRITE(state, path, rng_offset) += PRNG_BOUNCE_NUM;
|
||||
}
|
||||
INTEGRATOR_STATE_WRITE(state, path, rng_offset) += PRNG_BOUNCE_NUM;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@@ -20,7 +20,6 @@
|
||||
#include "kernel/integrator/shader_eval.h"
|
||||
#include "kernel/light/light.h"
|
||||
#include "kernel/light/sample.h"
|
||||
#include "kernel/sample/mis.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
@@ -81,8 +80,7 @@ ccl_device float3 integrator_eval_background_shader(KernelGlobals kg,
|
||||
/* multiple importance sampling, get background light pdf for ray
|
||||
* direction, and compute weight with respect to BSDF pdf */
|
||||
const float pdf = background_light_pdf(kg, ray_P - ray_D * mis_ray_t, ray_D);
|
||||
const float mis_weight = power_heuristic(mis_ray_pdf, pdf);
|
||||
|
||||
const float mis_weight = light_sample_mis_weight_forward(kg, mis_ray_pdf, pdf);
|
||||
L *= mis_weight;
|
||||
}
|
||||
# endif
|
||||
@@ -169,7 +167,7 @@ ccl_device_inline void integrate_distant_lights(KernelGlobals kg,
|
||||
/* multiple importance sampling, get regular light pdf,
|
||||
* and compute weight with respect to BSDF pdf */
|
||||
const float mis_ray_pdf = INTEGRATOR_STATE(state, path, mis_ray_pdf);
|
||||
const float mis_weight = power_heuristic(mis_ray_pdf, ls.pdf);
|
||||
const float mis_weight = light_sample_mis_weight_forward(kg, mis_ray_pdf, ls.pdf);
|
||||
light_eval *= mis_weight;
|
||||
}
|
||||
|
||||
|
@@ -84,7 +84,7 @@ ccl_device_inline void integrate_light(KernelGlobals kg,
|
||||
/* multiple importance sampling, get regular light pdf,
|
||||
* and compute weight with respect to BSDF pdf */
|
||||
const float mis_ray_pdf = INTEGRATOR_STATE(state, path, mis_ray_pdf);
|
||||
const float mis_weight = power_heuristic(mis_ray_pdf, ls.pdf);
|
||||
const float mis_weight = light_sample_mis_weight_forward(kg, mis_ray_pdf, ls.pdf);
|
||||
light_eval *= mis_weight;
|
||||
}
|
||||
|
||||
|
@@ -95,8 +95,8 @@ ccl_device_inline void integrate_transparent_volume_shadow(KernelGlobals kg,
|
||||
|
||||
shader_setup_from_volume(kg, shadow_sd, &ray);
|
||||
|
||||
const float step_size = volume_stack_step_size(
|
||||
kg, [=](const int i) { return integrator_state_read_shadow_volume_stack(state, i); });
|
||||
VOLUME_READ_LAMBDA(integrator_state_read_shadow_volume_stack(state, i));
|
||||
const float step_size = volume_stack_step_size(kg, volume_read_lambda_pass);
|
||||
|
||||
volume_shadow_heterogeneous(kg, state, &ray, shadow_sd, throughput, step_size);
|
||||
}
|
||||
|
@@ -27,8 +27,6 @@
|
||||
#include "kernel/light/light.h"
|
||||
#include "kernel/light/sample.h"
|
||||
|
||||
#include "kernel/sample/mis.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
ccl_device_forceinline void integrate_surface_shader_setup(KernelGlobals kg,
|
||||
@@ -95,8 +93,7 @@ ccl_device_forceinline void integrate_surface_emission(KernelGlobals kg,
|
||||
/* Multiple importance sampling, get triangle light pdf,
|
||||
* and compute weight with respect to BSDF pdf. */
|
||||
float pdf = triangle_light_pdf(kg, sd, t);
|
||||
float mis_weight = power_heuristic(bsdf_pdf, pdf);
|
||||
|
||||
float mis_weight = light_sample_mis_weight_forward(kg, bsdf_pdf, pdf);
|
||||
L *= mis_weight;
|
||||
}
|
||||
|
||||
@@ -155,7 +152,7 @@ ccl_device_forceinline void integrate_surface_direct_light(KernelGlobals kg,
|
||||
bsdf_eval_mul3(&bsdf_eval, light_eval / ls.pdf);
|
||||
|
||||
if (ls.shader & SHADER_USE_MIS) {
|
||||
const float mis_weight = power_heuristic(ls.pdf, bsdf_pdf);
|
||||
const float mis_weight = light_sample_mis_weight_nee(kg, ls.pdf, bsdf_pdf);
|
||||
bsdf_eval_mul(&bsdf_eval, mis_weight);
|
||||
}
|
||||
|
||||
@@ -195,12 +192,13 @@ ccl_device_forceinline void integrate_surface_direct_light(KernelGlobals kg,
|
||||
const float3 throughput = INTEGRATOR_STATE(state, path, throughput) * bsdf_eval_sum(&bsdf_eval);
|
||||
|
||||
if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) {
|
||||
const float3 pass_diffuse_weight = (bounce == 0) ?
|
||||
bsdf_eval_pass_diffuse_weight(&bsdf_eval) :
|
||||
INTEGRATOR_STATE(state, path, pass_diffuse_weight);
|
||||
const float3 pass_glossy_weight = (bounce == 0) ?
|
||||
bsdf_eval_pass_glossy_weight(&bsdf_eval) :
|
||||
INTEGRATOR_STATE(state, path, pass_glossy_weight);
|
||||
const packed_float3 pass_diffuse_weight =
|
||||
(bounce == 0) ? packed_float3(bsdf_eval_pass_diffuse_weight(&bsdf_eval)) :
|
||||
INTEGRATOR_STATE(state, path, pass_diffuse_weight);
|
||||
const packed_float3 pass_glossy_weight = (bounce == 0) ?
|
||||
packed_float3(
|
||||
bsdf_eval_pass_glossy_weight(&bsdf_eval)) :
|
||||
INTEGRATOR_STATE(state, path, pass_glossy_weight);
|
||||
INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, pass_diffuse_weight) = pass_diffuse_weight;
|
||||
INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, pass_glossy_weight) = pass_glossy_weight;
|
||||
}
|
||||
|
@@ -27,8 +27,6 @@
|
||||
#include "kernel/light/light.h"
|
||||
#include "kernel/light/sample.h"
|
||||
|
||||
#include "kernel/sample/mis.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
#ifdef __VOLUME__
|
||||
@@ -78,9 +76,8 @@ ccl_device_inline bool shadow_volume_shader_sample(KernelGlobals kg,
|
||||
ccl_private ShaderData *ccl_restrict sd,
|
||||
ccl_private float3 *ccl_restrict extinction)
|
||||
{
|
||||
shader_eval_volume<true>(kg, state, sd, PATH_RAY_SHADOW, [=](const int i) {
|
||||
return integrator_state_read_shadow_volume_stack(state, i);
|
||||
});
|
||||
VOLUME_READ_LAMBDA(integrator_state_read_shadow_volume_stack(state, i))
|
||||
shader_eval_volume<true>(kg, state, sd, PATH_RAY_SHADOW, volume_read_lambda_pass);
|
||||
|
||||
if (!(sd->flag & SD_EXTINCTION)) {
|
||||
return false;
|
||||
@@ -98,9 +95,8 @@ ccl_device_inline bool volume_shader_sample(KernelGlobals kg,
|
||||
ccl_private VolumeShaderCoefficients *coeff)
|
||||
{
|
||||
const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag);
|
||||
shader_eval_volume<false>(kg, state, sd, path_flag, [=](const int i) {
|
||||
return integrator_state_read_volume_stack(state, i);
|
||||
});
|
||||
VOLUME_READ_LAMBDA(integrator_state_read_volume_stack(state, i))
|
||||
shader_eval_volume<false>(kg, state, sd, path_flag, volume_read_lambda_pass);
|
||||
|
||||
if (!(sd->flag & (SD_EXTINCTION | SD_SCATTER | SD_EMISSION))) {
|
||||
return false;
|
||||
@@ -263,6 +259,12 @@ ccl_device void volume_shadow_heterogeneous(KernelGlobals kg,
|
||||
/* Equi-angular sampling as in:
|
||||
* "Importance Sampling Techniques for Path Tracing in Participating Media" */
|
||||
|
||||
/* Below this pdf we ignore samples, as they tend to lead to very long distances.
|
||||
* This can cause performance issues with BVH traversal in OptiX, leading it to
|
||||
* traverse many nodes. Since these contribute very little to the image, just ignore
|
||||
* those samples. */
|
||||
# define VOLUME_SAMPLE_PDF_CUTOFF 1e-8f
|
||||
|
||||
ccl_device float volume_equiangular_sample(ccl_private const Ray *ccl_restrict ray,
|
||||
const float3 light_P,
|
||||
const float xi,
|
||||
@@ -437,7 +439,8 @@ ccl_device_forceinline void volume_integrate_step_scattering(
|
||||
|
||||
/* Equiangular sampling for direct lighting. */
|
||||
if (vstate.direct_sample_method == VOLUME_SAMPLE_EQUIANGULAR && !result.direct_scatter) {
|
||||
if (result.direct_t >= vstate.start_t && result.direct_t <= vstate.end_t) {
|
||||
if (result.direct_t >= vstate.start_t && result.direct_t <= vstate.end_t &&
|
||||
vstate.equiangular_pdf > VOLUME_SAMPLE_PDF_CUTOFF) {
|
||||
const float new_dt = result.direct_t - vstate.start_t;
|
||||
const float3 new_transmittance = volume_color_transmittance(coeff.sigma_t, new_dt);
|
||||
|
||||
@@ -474,26 +477,28 @@ ccl_device_forceinline void volume_integrate_step_scattering(
|
||||
const float3 new_transmittance = volume_color_transmittance(coeff.sigma_t, new_dt);
|
||||
const float distance_pdf = dot(channel_pdf, coeff.sigma_t * new_transmittance);
|
||||
|
||||
/* throughput */
|
||||
result.indirect_scatter = true;
|
||||
result.indirect_t = new_t;
|
||||
result.indirect_throughput *= coeff.sigma_s * new_transmittance / distance_pdf;
|
||||
shader_copy_volume_phases(&result.indirect_phases, sd);
|
||||
if (vstate.distance_pdf * distance_pdf > VOLUME_SAMPLE_PDF_CUTOFF) {
|
||||
/* throughput */
|
||||
result.indirect_scatter = true;
|
||||
result.indirect_t = new_t;
|
||||
result.indirect_throughput *= coeff.sigma_s * new_transmittance / distance_pdf;
|
||||
shader_copy_volume_phases(&result.indirect_phases, sd);
|
||||
|
||||
if (vstate.direct_sample_method != VOLUME_SAMPLE_EQUIANGULAR) {
|
||||
/* If using distance sampling for direct light, just copy parameters
|
||||
* of indirect light since we scatter at the same point then. */
|
||||
result.direct_scatter = true;
|
||||
result.direct_t = result.indirect_t;
|
||||
result.direct_throughput = result.indirect_throughput;
|
||||
shader_copy_volume_phases(&result.direct_phases, sd);
|
||||
if (vstate.direct_sample_method != VOLUME_SAMPLE_EQUIANGULAR) {
|
||||
/* If using distance sampling for direct light, just copy parameters
|
||||
* of indirect light since we scatter at the same point then. */
|
||||
result.direct_scatter = true;
|
||||
result.direct_t = result.indirect_t;
|
||||
result.direct_throughput = result.indirect_throughput;
|
||||
shader_copy_volume_phases(&result.direct_phases, sd);
|
||||
|
||||
/* Multiple importance sampling. */
|
||||
if (vstate.use_mis) {
|
||||
const float equiangular_pdf = volume_equiangular_pdf(ray, equiangular_light_P, new_t);
|
||||
const float mis_weight = power_heuristic(vstate.distance_pdf * distance_pdf,
|
||||
equiangular_pdf);
|
||||
result.direct_throughput *= 2.0f * mis_weight;
|
||||
/* Multiple importance sampling. */
|
||||
if (vstate.use_mis) {
|
||||
const float equiangular_pdf = volume_equiangular_pdf(ray, equiangular_light_P, new_t);
|
||||
const float mis_weight = power_heuristic(vstate.distance_pdf * distance_pdf,
|
||||
equiangular_pdf);
|
||||
result.direct_throughput *= 2.0f * mis_weight;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -694,8 +699,10 @@ ccl_device_forceinline bool integrate_volume_sample_light(
|
||||
float light_u, light_v;
|
||||
path_state_rng_2D(kg, rng_state, PRNG_LIGHT_U, &light_u, &light_v);
|
||||
|
||||
light_distribution_sample_from_volume_segment(
|
||||
kg, light_u, light_v, sd->time, sd->P, bounce, path_flag, ls);
|
||||
if (!light_distribution_sample_from_volume_segment(
|
||||
kg, light_u, light_v, sd->time, sd->P, bounce, path_flag, ls)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ls->shader & SHADER_EXCLUDE_SCATTER) {
|
||||
return false;
|
||||
@@ -761,7 +768,7 @@ ccl_device_forceinline void integrate_volume_direct_light(
|
||||
const float phase_pdf = shader_volume_phase_eval(kg, sd, phases, ls->D, &phase_eval);
|
||||
|
||||
if (ls->shader & SHADER_USE_MIS) {
|
||||
float mis_weight = power_heuristic(ls->pdf, phase_pdf);
|
||||
float mis_weight = light_sample_mis_weight_nee(kg, ls->pdf, phase_pdf);
|
||||
bsdf_eval_mul(&phase_eval, mis_weight);
|
||||
}
|
||||
|
||||
@@ -794,9 +801,10 @@ ccl_device_forceinline void integrate_volume_direct_light(
|
||||
const float3 throughput_phase = throughput * bsdf_eval_sum(&phase_eval);
|
||||
|
||||
if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) {
|
||||
const float3 pass_diffuse_weight = (bounce == 0) ?
|
||||
one_float3() :
|
||||
INTEGRATOR_STATE(state, path, pass_diffuse_weight);
|
||||
const packed_float3 pass_diffuse_weight = (bounce == 0) ?
|
||||
packed_float3(one_float3()) :
|
||||
INTEGRATOR_STATE(
|
||||
state, path, pass_diffuse_weight);
|
||||
INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, pass_diffuse_weight) = pass_diffuse_weight;
|
||||
INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, pass_glossy_weight) = zero_float3();
|
||||
}
|
||||
@@ -921,8 +929,8 @@ ccl_device VolumeIntegrateEvent volume_integrate(KernelGlobals kg,
|
||||
VOLUME_SAMPLE_DISTANCE;
|
||||
|
||||
/* Step through volume. */
|
||||
const float step_size = volume_stack_step_size(
|
||||
kg, [=](const int i) { return integrator_state_read_volume_stack(state, i); });
|
||||
VOLUME_READ_LAMBDA(integrator_state_read_volume_stack(state, i))
|
||||
const float step_size = volume_stack_step_size(kg, volume_read_lambda_pass);
|
||||
|
||||
/* TODO: expensive to zero closures? */
|
||||
VolumeIntegrateResult result = {};
|
||||
|
@@ -122,23 +122,20 @@ ccl_device_inline void shader_prepare_surface_closures(KernelGlobals kg,
|
||||
for (int i = 0; i < sd->num_closure; i++) {
|
||||
ccl_private ShaderClosure *sc = &sd->closure[i];
|
||||
|
||||
if (CLOSURE_IS_BSDF_DIFFUSE(sc->type)) {
|
||||
if (kernel_data.integrator.filter_closures & FILTER_CLOSURE_DIFFUSE) {
|
||||
sc->type = CLOSURE_NONE_ID;
|
||||
sc->sample_weight = 0.0f;
|
||||
}
|
||||
if ((CLOSURE_IS_BSDF_DIFFUSE(sc->type) &&
|
||||
(kernel_data.integrator.filter_closures & FILTER_CLOSURE_DIFFUSE)) ||
|
||||
(CLOSURE_IS_BSDF_GLOSSY(sc->type) &&
|
||||
(kernel_data.integrator.filter_closures & FILTER_CLOSURE_GLOSSY)) ||
|
||||
(CLOSURE_IS_BSDF_TRANSMISSION(sc->type) &&
|
||||
(kernel_data.integrator.filter_closures & FILTER_CLOSURE_TRANSMISSION))) {
|
||||
sc->type = CLOSURE_NONE_ID;
|
||||
sc->sample_weight = 0.0f;
|
||||
}
|
||||
else if (CLOSURE_IS_BSDF_GLOSSY(sc->type)) {
|
||||
if (kernel_data.integrator.filter_closures & FILTER_CLOSURE_GLOSSY) {
|
||||
sc->type = CLOSURE_NONE_ID;
|
||||
sc->sample_weight = 0.0f;
|
||||
}
|
||||
}
|
||||
else if (CLOSURE_IS_BSDF_TRANSMISSION(sc->type)) {
|
||||
if (kernel_data.integrator.filter_closures & FILTER_CLOSURE_TRANSMISSION) {
|
||||
sc->type = CLOSURE_NONE_ID;
|
||||
sc->sample_weight = 0.0f;
|
||||
}
|
||||
else if ((CLOSURE_IS_BSDF_TRANSPARENT(sc->type) &&
|
||||
(kernel_data.integrator.filter_closures & FILTER_CLOSURE_TRANSPARENT))) {
|
||||
sc->type = CLOSURE_HOLDOUT_ID;
|
||||
sc->sample_weight = 0.0f;
|
||||
sd->flag |= SD_HOLDOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -40,15 +40,15 @@ KERNEL_STRUCT_MEMBER(shadow_path, uint16_t, queued_kernel, KERNEL_FEATURE_PATH_T
|
||||
/* enum PathRayFlag */
|
||||
KERNEL_STRUCT_MEMBER(shadow_path, uint32_t, flag, KERNEL_FEATURE_PATH_TRACING)
|
||||
/* Throughput. */
|
||||
KERNEL_STRUCT_MEMBER(shadow_path, float3, throughput, KERNEL_FEATURE_PATH_TRACING)
|
||||
KERNEL_STRUCT_MEMBER(shadow_path, packed_float3, throughput, KERNEL_FEATURE_PATH_TRACING)
|
||||
/* Throughput for shadow pass. */
|
||||
KERNEL_STRUCT_MEMBER(shadow_path,
|
||||
float3,
|
||||
packed_float3,
|
||||
unshadowed_throughput,
|
||||
KERNEL_FEATURE_SHADOW_PASS | KERNEL_FEATURE_AO_ADDITIVE)
|
||||
/* Ratio of throughput to distinguish diffuse / glossy / transmission render passes. */
|
||||
KERNEL_STRUCT_MEMBER(shadow_path, float3, pass_diffuse_weight, KERNEL_FEATURE_LIGHT_PASSES)
|
||||
KERNEL_STRUCT_MEMBER(shadow_path, float3, pass_glossy_weight, KERNEL_FEATURE_LIGHT_PASSES)
|
||||
KERNEL_STRUCT_MEMBER(shadow_path, packed_float3, pass_diffuse_weight, KERNEL_FEATURE_LIGHT_PASSES)
|
||||
KERNEL_STRUCT_MEMBER(shadow_path, packed_float3, pass_glossy_weight, KERNEL_FEATURE_LIGHT_PASSES)
|
||||
/* Number of intersections found by ray-tracing. */
|
||||
KERNEL_STRUCT_MEMBER(shadow_path, uint16_t, num_hits, KERNEL_FEATURE_PATH_TRACING)
|
||||
KERNEL_STRUCT_END(shadow_path)
|
||||
@@ -56,8 +56,8 @@ KERNEL_STRUCT_END(shadow_path)
|
||||
/********************************** Shadow Ray *******************************/
|
||||
|
||||
KERNEL_STRUCT_BEGIN(shadow_ray)
|
||||
KERNEL_STRUCT_MEMBER(shadow_ray, float3, P, KERNEL_FEATURE_PATH_TRACING)
|
||||
KERNEL_STRUCT_MEMBER(shadow_ray, float3, D, KERNEL_FEATURE_PATH_TRACING)
|
||||
KERNEL_STRUCT_MEMBER(shadow_ray, packed_float3, P, KERNEL_FEATURE_PATH_TRACING)
|
||||
KERNEL_STRUCT_MEMBER(shadow_ray, packed_float3, D, KERNEL_FEATURE_PATH_TRACING)
|
||||
KERNEL_STRUCT_MEMBER(shadow_ray, float, t, KERNEL_FEATURE_PATH_TRACING)
|
||||
KERNEL_STRUCT_MEMBER(shadow_ray, float, time, KERNEL_FEATURE_PATH_TRACING)
|
||||
KERNEL_STRUCT_MEMBER(shadow_ray, float, dP, KERNEL_FEATURE_PATH_TRACING)
|
||||
|
@@ -59,12 +59,12 @@ KERNEL_STRUCT_MEMBER(path, float, min_ray_pdf, KERNEL_FEATURE_PATH_TRACING)
|
||||
/* Continuation probability for path termination. */
|
||||
KERNEL_STRUCT_MEMBER(path, float, continuation_probability, KERNEL_FEATURE_PATH_TRACING)
|
||||
/* Throughput. */
|
||||
KERNEL_STRUCT_MEMBER(path, float3, throughput, KERNEL_FEATURE_PATH_TRACING)
|
||||
KERNEL_STRUCT_MEMBER(path, packed_float3, throughput, KERNEL_FEATURE_PATH_TRACING)
|
||||
/* Ratio of throughput to distinguish diffuse / glossy / transmission render passes. */
|
||||
KERNEL_STRUCT_MEMBER(path, float3, pass_diffuse_weight, KERNEL_FEATURE_LIGHT_PASSES)
|
||||
KERNEL_STRUCT_MEMBER(path, float3, pass_glossy_weight, KERNEL_FEATURE_LIGHT_PASSES)
|
||||
KERNEL_STRUCT_MEMBER(path, packed_float3, pass_diffuse_weight, KERNEL_FEATURE_LIGHT_PASSES)
|
||||
KERNEL_STRUCT_MEMBER(path, packed_float3, pass_glossy_weight, KERNEL_FEATURE_LIGHT_PASSES)
|
||||
/* Denoising. */
|
||||
KERNEL_STRUCT_MEMBER(path, float3, denoising_feature_throughput, KERNEL_FEATURE_DENOISING)
|
||||
KERNEL_STRUCT_MEMBER(path, packed_float3, denoising_feature_throughput, KERNEL_FEATURE_DENOISING)
|
||||
/* Shader sorting. */
|
||||
/* TODO: compress as uint16? or leave out entirely and recompute key in sorting code? */
|
||||
KERNEL_STRUCT_MEMBER(path, uint32_t, shader_sort_key, KERNEL_FEATURE_PATH_TRACING)
|
||||
@@ -73,8 +73,8 @@ KERNEL_STRUCT_END(path)
|
||||
/************************************** Ray ***********************************/
|
||||
|
||||
KERNEL_STRUCT_BEGIN(ray)
|
||||
KERNEL_STRUCT_MEMBER(ray, float3, P, KERNEL_FEATURE_PATH_TRACING)
|
||||
KERNEL_STRUCT_MEMBER(ray, float3, D, KERNEL_FEATURE_PATH_TRACING)
|
||||
KERNEL_STRUCT_MEMBER(ray, packed_float3, P, KERNEL_FEATURE_PATH_TRACING)
|
||||
KERNEL_STRUCT_MEMBER(ray, packed_float3, D, KERNEL_FEATURE_PATH_TRACING)
|
||||
KERNEL_STRUCT_MEMBER(ray, float, t, KERNEL_FEATURE_PATH_TRACING)
|
||||
KERNEL_STRUCT_MEMBER(ray, float, time, KERNEL_FEATURE_PATH_TRACING)
|
||||
KERNEL_STRUCT_MEMBER(ray, float, dP, KERNEL_FEATURE_PATH_TRACING)
|
||||
@@ -96,10 +96,10 @@ KERNEL_STRUCT_END(isect)
|
||||
/*************** Subsurface closure state for subsurface kernel ***************/
|
||||
|
||||
KERNEL_STRUCT_BEGIN(subsurface)
|
||||
KERNEL_STRUCT_MEMBER(subsurface, float3, albedo, KERNEL_FEATURE_SUBSURFACE)
|
||||
KERNEL_STRUCT_MEMBER(subsurface, float3, radius, KERNEL_FEATURE_SUBSURFACE)
|
||||
KERNEL_STRUCT_MEMBER(subsurface, packed_float3, albedo, KERNEL_FEATURE_SUBSURFACE)
|
||||
KERNEL_STRUCT_MEMBER(subsurface, packed_float3, radius, KERNEL_FEATURE_SUBSURFACE)
|
||||
KERNEL_STRUCT_MEMBER(subsurface, float, anisotropy, KERNEL_FEATURE_SUBSURFACE)
|
||||
KERNEL_STRUCT_MEMBER(subsurface, float3, Ng, KERNEL_FEATURE_SUBSURFACE)
|
||||
KERNEL_STRUCT_MEMBER(subsurface, packed_float3, Ng, KERNEL_FEATURE_SUBSURFACE)
|
||||
KERNEL_STRUCT_END(subsurface)
|
||||
|
||||
/********************************** Volume Stack ******************************/
|
||||
|
@@ -71,6 +71,10 @@ ccl_device int subsurface_bounce(KernelGlobals kg,
|
||||
}
|
||||
# endif
|
||||
|
||||
if (sd->flag & SD_BACKFACING) {
|
||||
path_flag |= PATH_RAY_SUBSURFACE_BACKFACING;
|
||||
}
|
||||
|
||||
INTEGRATOR_STATE_WRITE(state, path, throughput) *= weight;
|
||||
INTEGRATOR_STATE_WRITE(state, path, flag) = path_flag;
|
||||
|
||||
|
@@ -47,6 +47,7 @@ ccl_device_inline bool subsurface_disk(KernelGlobals kg,
|
||||
const float time = INTEGRATOR_STATE(state, ray, time);
|
||||
const float3 Ng = INTEGRATOR_STATE(state, subsurface, Ng);
|
||||
const int object = INTEGRATOR_STATE(state, isect, object);
|
||||
const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag);
|
||||
|
||||
/* Read subsurface scattering parameters. */
|
||||
const float3 radius = INTEGRATOR_STATE(state, subsurface, radius);
|
||||
@@ -123,6 +124,9 @@ ccl_device_inline bool subsurface_disk(KernelGlobals kg,
|
||||
const int object = ss_isect.hits[hit].object;
|
||||
const int object_flag = kernel_tex_fetch(__object_flag, object);
|
||||
float3 hit_Ng = ss_isect.Ng[hit];
|
||||
if (path_flag & PATH_RAY_SUBSURFACE_BACKFACING) {
|
||||
hit_Ng = -hit_Ng;
|
||||
}
|
||||
if (object_flag & SD_OBJECT_NEGATIVE_SCALE_APPLIED) {
|
||||
hit_Ng = -hit_Ng;
|
||||
}
|
||||
|
@@ -18,6 +18,14 @@
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
/* Volumetric read/write lambda functions - default implementations */
|
||||
#ifndef VOLUME_READ_LAMBDA
|
||||
# define VOLUME_READ_LAMBDA(function_call) \
|
||||
auto volume_read_lambda_pass = [=](const int i) { return function_call; };
|
||||
# define VOLUME_WRITE_LAMBDA(function_call) \
|
||||
auto volume_write_lambda_pass = [=](const int i, VolumeStack entry) { function_call; };
|
||||
#endif
|
||||
|
||||
/* Volume Stack
|
||||
*
|
||||
* This is an array of object/shared ID's that the current segment of the path
|
||||
@@ -88,26 +96,18 @@ ccl_device void volume_stack_enter_exit(KernelGlobals kg,
|
||||
IntegratorState state,
|
||||
ccl_private const ShaderData *sd)
|
||||
{
|
||||
volume_stack_enter_exit(
|
||||
kg,
|
||||
sd,
|
||||
[=](const int i) { return integrator_state_read_volume_stack(state, i); },
|
||||
[=](const int i, const VolumeStack entry) {
|
||||
integrator_state_write_volume_stack(state, i, entry);
|
||||
});
|
||||
VOLUME_READ_LAMBDA(integrator_state_read_volume_stack(state, i))
|
||||
VOLUME_WRITE_LAMBDA(integrator_state_write_volume_stack(state, i, entry))
|
||||
volume_stack_enter_exit(kg, sd, volume_read_lambda_pass, volume_write_lambda_pass);
|
||||
}
|
||||
|
||||
ccl_device void shadow_volume_stack_enter_exit(KernelGlobals kg,
|
||||
IntegratorShadowState state,
|
||||
ccl_private const ShaderData *sd)
|
||||
{
|
||||
volume_stack_enter_exit(
|
||||
kg,
|
||||
sd,
|
||||
[=](const int i) { return integrator_state_read_shadow_volume_stack(state, i); },
|
||||
[=](const int i, const VolumeStack entry) {
|
||||
integrator_state_write_shadow_volume_stack(state, i, entry);
|
||||
});
|
||||
VOLUME_READ_LAMBDA(integrator_state_read_shadow_volume_stack(state, i))
|
||||
VOLUME_WRITE_LAMBDA(integrator_state_write_shadow_volume_stack(state, i, entry))
|
||||
volume_stack_enter_exit(kg, sd, volume_read_lambda_pass, volume_write_lambda_pass);
|
||||
}
|
||||
|
||||
/* Clean stack after the last bounce.
|
||||
|
@@ -73,7 +73,7 @@ ccl_device_inline bool light_sample(KernelGlobals kg,
|
||||
ls->P = zero_float3();
|
||||
ls->Ng = zero_float3();
|
||||
ls->D = zero_float3();
|
||||
ls->pdf = true;
|
||||
ls->pdf = 1.0f;
|
||||
ls->t = FLT_MAX;
|
||||
return true;
|
||||
}
|
||||
@@ -131,7 +131,7 @@ ccl_device_inline bool light_sample(KernelGlobals kg,
|
||||
float3 dir = make_float3(klight->spot.dir[0], klight->spot.dir[1], klight->spot.dir[2]);
|
||||
ls->eval_fac *= spot_light_attenuation(
|
||||
dir, klight->spot.spot_angle, klight->spot.spot_smooth, ls->Ng);
|
||||
if (ls->eval_fac == 0.0f) {
|
||||
if (!in_volume_segment && ls->eval_fac == 0.0f) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -170,7 +170,7 @@ ccl_device_inline bool light_sample(KernelGlobals kg,
|
||||
float3 sample_axisu = axisu;
|
||||
float3 sample_axisv = axisv;
|
||||
|
||||
if (klight->area.tan_spread > 0.0f) {
|
||||
if (!in_volume_segment && klight->area.tan_spread > 0.0f) {
|
||||
if (!light_spread_clamp_area_light(
|
||||
P, Ng, &ls->P, &sample_axisu, &sample_axisv, klight->area.tan_spread)) {
|
||||
return false;
|
||||
@@ -203,7 +203,7 @@ ccl_device_inline bool light_sample(KernelGlobals kg,
|
||||
|
||||
ls->pdf *= kernel_data.integrator.pdf_lights;
|
||||
|
||||
return (ls->pdf > 0.0f);
|
||||
return in_volume_segment || (ls->pdf > 0.0f);
|
||||
}
|
||||
|
||||
ccl_device bool lights_intersect(KernelGlobals kg,
|
||||
@@ -676,19 +676,7 @@ ccl_device_forceinline void triangle_light_sample(KernelGlobals kg,
|
||||
ls->D = z * B + safe_sqrtf(1.0f - z * z) * safe_normalize(C_ - dot(C_, B) * B);
|
||||
|
||||
/* calculate intersection with the planar triangle */
|
||||
if (!ray_triangle_intersect(P,
|
||||
ls->D,
|
||||
FLT_MAX,
|
||||
#if defined(__KERNEL_SSE2__) && defined(__KERNEL_SSE__)
|
||||
(ssef *)V,
|
||||
#else
|
||||
V[0],
|
||||
V[1],
|
||||
V[2],
|
||||
#endif
|
||||
&ls->u,
|
||||
&ls->v,
|
||||
&ls->t)) {
|
||||
if (!ray_triangle_intersect(P, ls->D, FLT_MAX, V[0], V[1], V[2], &ls->u, &ls->v, &ls->t)) {
|
||||
ls->pdf = 0.0f;
|
||||
return;
|
||||
}
|
||||
|
@@ -22,6 +22,7 @@
|
||||
#include "kernel/light/light.h"
|
||||
|
||||
#include "kernel/sample/mapping.h"
|
||||
#include "kernel/sample/mis.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
@@ -268,4 +269,36 @@ ccl_device_inline void light_sample_to_volume_shadow_ray(
|
||||
shadow_ray_setup(sd, ls, P, ray);
|
||||
}
|
||||
|
||||
ccl_device_inline float light_sample_mis_weight_forward(KernelGlobals kg,
|
||||
const float forward_pdf,
|
||||
const float nee_pdf)
|
||||
{
|
||||
#ifdef WITH_CYCLES_DEBUG
|
||||
if (kernel_data.integrator.direct_light_sampling_type == DIRECT_LIGHT_SAMPLING_FORWARD) {
|
||||
return 1.0f;
|
||||
}
|
||||
else if (kernel_data.integrator.direct_light_sampling_type == DIRECT_LIGHT_SAMPLING_NEE) {
|
||||
return 0.0f;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
return power_heuristic(forward_pdf, nee_pdf);
|
||||
}
|
||||
|
||||
ccl_device_inline float light_sample_mis_weight_nee(KernelGlobals kg,
|
||||
const float nee_pdf,
|
||||
const float forward_pdf)
|
||||
{
|
||||
#ifdef WITH_CYCLES_DEBUG
|
||||
if (kernel_data.integrator.direct_light_sampling_type == DIRECT_LIGHT_SAMPLING_FORWARD) {
|
||||
return 0.0f;
|
||||
}
|
||||
else if (kernel_data.integrator.direct_light_sampling_type == DIRECT_LIGHT_SAMPLING_NEE) {
|
||||
return 1.0f;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
return power_heuristic(nee_pdf, forward_pdf);
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
@@ -55,7 +55,7 @@ if(APPLE)
|
||||
# Disable allocation warning on macOS prior to 10.14: the OSLRenderServices
|
||||
# contains member which is 64 bytes aligned (cache inside of OIIO's
|
||||
# unordered_map_concurrent). This is not something what the SDK supportsm, but
|
||||
# since we take care of allocations ourselves is is OK to ignore the
|
||||
# since we take care of allocations ourselves is OK to ignore the
|
||||
# diagnostic message.
|
||||
string(APPEND CMAKE_CXX_FLAGS " -faligned-allocation")
|
||||
endif()
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user