Compare commits
314 Commits
tmp-gpu-sh
...
temp-T9490
Author | SHA1 | Date | |
---|---|---|---|
e94cd5eeed | |||
1bf6a880ab | |||
![]() |
a21bca0e20 | ||
b3bf46b78d | |||
0cb5eae9d0 | |||
1758dcd423 | |||
9338126ecc | |||
46ae083113 | |||
b06fff4737 | |||
94d2a611ec | |||
37e555d2fe | |||
086f191169 | |||
4c951bfa82 | |||
4530449317 | |||
c4bedeb018 | |||
83094d9a0d | |||
c1b5cea63a | |||
b45e71e22c | |||
597eaeaa11 | |||
52b2769b9c | |||
c847122096 | |||
1687903fb8 | |||
c89d6b0953 | |||
2637f94358 | |||
3e2591c83e | |||
0ec94d5359 | |||
932d8dba52 | |||
ec1b0c2014 | |||
97a023a0d5 | |||
e2a36a6e45 | |||
f26c36c96b | |||
c813a1b358 | |||
eab066cbf2 | |||
![]() |
2ed73fc97e | ||
a18bd403bf | |||
96667e3391 | |||
6c25aabddf | |||
0477ca75f0 | |||
![]() |
14f6afb090 | ||
368bfa80f9 | |||
460e0a1347 | |||
33ba298b5d | |||
![]() |
948211679f | ||
![]() |
3f42417cd4 | ||
196da819ba | |||
31296f6f9d | |||
0f89bcdbeb | |||
c5980ada4f | |||
![]() |
17b0c06946 | ||
a000de7c2a | |||
a54142f3f1 | |||
1b1693d43f | |||
2e9b8689e4 | |||
a2301b1d91 | |||
114b06b3cb | |||
2bf519d211 | |||
4d799db72f | |||
5a0c5912a4 | |||
083de503ce | |||
04c3b08518 | |||
263f862ba5 | |||
e2337b5342 | |||
90d61600fc | |||
![]() |
e673cfc2d7 | ||
25fa5792e6 | |||
a215d7e230 | |||
0928fe8710 | |||
4c617c06e9 | |||
796ef560b4 | |||
578baf95e0 | |||
e774f2c901 | |||
7708a848c9 | |||
4b1f243e4d | |||
f9b6a257bd | |||
95981c9876 | |||
46475b8e11 | |||
43e3a33082 | |||
c69a581c0b | |||
abf30007ab | |||
38c7378949 | |||
807c58aae4 | |||
889712927f | |||
5c4a5fd40d | |||
6cd977b903 | |||
dde997086c | |||
579e8ebe79 | |||
5ae76fae90 | |||
e88d966737 | |||
25c99e72cd | |||
b7878a4d45 | |||
![]() |
9350005d8b | ||
1f026a3db9 | |||
![]() |
45d038181a | ||
d590e223da | |||
68aa35ae74 | |||
294ab84909 | |||
1c23a06706 | |||
e07b217669 | |||
32ceb0b807 | |||
4f9be46526 | |||
54d69a2fd1 | |||
9d274a609c | |||
58f8eb54a3 | |||
![]() |
5b90c046d5 | ||
c20f209b1c | |||
59fc95bf97 | |||
d034b85f33 | |||
![]() |
c39d514a4e | ||
4251455dcd | |||
87c5423c5e | |||
![]() |
d68ce0e475 | ||
5e51a5e8a4 | |||
93065a67c6 | |||
f6888b530a | |||
36c40760a5 | |||
23fa5bb723 | |||
64196a6b29 | |||
872dc1038c | |||
53923f502d | |||
20655128c9 | |||
5fca280c80 | |||
1ac2d2dcb6 | |||
14d261d23a | |||
9ca1052226 | |||
4369c5817a | |||
22a8e934e4 | |||
e1ae95f6b2 | |||
24e00c115c | |||
2559d79d2f | |||
![]() |
cc1a48e395 | ||
6baccc36a0 | |||
d552b3c0c0 | |||
902a103f80 | |||
19622ffc5b | |||
f6c8a78ac6 | |||
9315215b20 | |||
264fe10ddd | |||
969a571e0f | |||
4425e0cd64 | |||
9b4c017031 | |||
ae349eb2d5 | |||
eb3ff1d6f9 | |||
1d536c21dd | |||
e3f9d9b206 | |||
b7fe27314b | |||
b47a1867e8 | |||
e7db1247b1 | |||
293aab2253 | |||
9a2d1cd5b7 | |||
cd0acba330 | |||
17cab47ed1 | |||
596ce11556 | |||
f179637222 | |||
ecf2f5ed01 | |||
eddad4e9a1 | |||
e49bf4019b | |||
1788298804 | |||
8a23d91a50 | |||
952a4fa456 | |||
71386c08f1 | |||
eb63646605 | |||
71879d665d | |||
ee6507f2b1 | |||
7e3b1e2c8f | |||
2e5aecf557 | |||
221ff895d9 | |||
a5610da1d5 | |||
9506dcf675 | |||
977baeaa26 | |||
09ecb089a5 | |||
15657b7ccd | |||
b88a37a490 | |||
4d5c08b938 | |||
796e9d442c | |||
dfe22a53bb | |||
0d7b3ed39c | |||
6952228386 | |||
6a8ad00bcc | |||
08d008a508 | |||
2486346f6f | |||
9f8ae130af | |||
5d7ac749c5 | |||
fce0b824a7 | |||
![]() |
36068487d0 | ||
d7822981b1 | |||
542d15b1cd | |||
1b94631975 | |||
6dd89afa96 | |||
db496a0b7d | |||
20df402adc | |||
7220897280 | |||
75d84b1b64 | |||
0fc9526178 | |||
84f6d86445 | |||
c11c2a4b91 | |||
![]() |
54fb1a75ee | ||
0fa36c81d9 | |||
3bbb39ecc1 | |||
44ca984dc7 | |||
8c1ddee10c | |||
b776c46d2f | |||
![]() |
449db0ab1e | ||
8af22719d0 | |||
fa1fef5081 | |||
194979e929 | |||
aa0ecd1791 | |||
4d10a46e63 | |||
a25cfc5db2 | |||
be8f10a4e2 | |||
e3fd0b1d17 | |||
7abdd82dfd | |||
59fcbdd815 | |||
0a08ac2528 | |||
9d3f35a0bf | |||
edee5a947b | |||
![]() |
8fb2ff458b | ||
08822801ac | |||
04feaa8bd0 | |||
e15449623d | |||
40c8e23d48 | |||
e1e3043a51 | |||
![]() |
a84621347d | ||
![]() |
34d424fd64 | ||
d914cfcb7a | |||
608d51c9c8 | |||
bc66cd9868 | |||
3574f2730d | |||
b87d87b1d3 | |||
e69020ad0f | |||
18c5d4ccb3 | |||
9664cc91f3 | |||
6a16a9e661 | |||
6e926e9b56 | |||
2a095d8bfe | |||
9fe704800e | |||
b7a27efd78 | |||
bba95d1901 | |||
67517c7d5c | |||
41495707d2 | |||
82d5905e4b | |||
ca9a749b21 | |||
e9a43a3b60 | |||
9109ea0b96 | |||
5703efab88 | |||
d723fa3d31 | |||
780633ec4b | |||
301bb5afa5 | |||
eb33ee566e | |||
85df7036f7 | |||
e57365a70b | |||
348631cffe | |||
8ae6995e98 | |||
c0d0e2788b | |||
ba48c1ee58 | |||
6f51cb0ad7 | |||
a5cb7c1e62 | |||
0cf746c1fa | |||
c0432d5edb | |||
86b7746e3c | |||
0a3de0305c | |||
c9a8975de5 | |||
261517e475 | |||
c8e536bac3 | |||
e0ac75cb44 | |||
7c568e7d36 | |||
cea588b9ef | |||
7a0cf2c72f | |||
1bd0a87384 | |||
8b3d798374 | |||
0c5ccae79d | |||
cfa53e0fbe | |||
800fc17367 | |||
1c4a1c13e0 | |||
5ecaa9a838 | |||
3537abe84b | |||
743b9c5e1d | |||
b8157f5bf1 | |||
22dc865a86 | |||
039cc32917 | |||
1a4f8ab389 | |||
f173973ae4 | |||
79e985ea54 | |||
19a6220308 | |||
d53738396f | |||
7bb572f208 | |||
0cf2fafd81 | |||
a3deef6fff | |||
eaa4cdaa42 | |||
![]() |
29450a2af3 | ||
![]() |
75a1a578bd | ||
f1a488d0f2 | |||
a7c9fb59ca | |||
227f0f3582 | |||
97c2c39916 | |||
a311fa96aa | |||
e594f23a27 | |||
fa8c2c7885 | |||
a0dcd0bf2c | |||
a72a9e099c | |||
![]() |
62a0de1673 | ||
![]() |
bab47b60cb | ||
![]() |
a909ab984c | ||
5f7ad4baaa | |||
![]() |
e5858a3ad0 | ||
ec5560db73 | |||
0882069095 | |||
1552b86b55 | |||
d43b5791e0 | |||
fb6bd88644 | |||
![]() |
46e049d0ce | ||
e5766752d0 | |||
![]() |
b2ccd8546c | ||
a2c1c368af | |||
d320f3677e |
@@ -273,11 +273,13 @@ endif()
|
|||||||
|
|
||||||
if(UNIX AND NOT APPLE)
|
if(UNIX AND NOT APPLE)
|
||||||
option(WITH_SYSTEM_GLEW "Use GLEW OpenGL wrapper library provided by the operating system" OFF)
|
option(WITH_SYSTEM_GLEW "Use GLEW OpenGL wrapper library provided by the operating system" OFF)
|
||||||
option(WITH_SYSTEM_GLES "Use OpenGL ES library provided by the operating system" ON)
|
option(WITH_SYSTEM_GLEW "Use GLEW OpenGL wrapper library provided by the operating system" OFF)
|
||||||
|
option(WITH_SYSTEM_FREETYPE "Use the freetype library provided by the operating system" OFF)
|
||||||
else()
|
else()
|
||||||
# not an option for other OS's
|
# not an option for other OS's
|
||||||
set(WITH_SYSTEM_GLEW OFF)
|
set(WITH_SYSTEM_GLEW OFF)
|
||||||
set(WITH_SYSTEM_GLES OFF)
|
set(WITH_SYSTEM_GLES OFF)
|
||||||
|
set(WITH_SYSTEM_FREETYPE OFF)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
@@ -569,6 +571,10 @@ if(UNIX AND NOT APPLE)
|
|||||||
option(WITH_LINKER_LLD "Use ld.lld linker which is usually faster than ld.gold" OFF)
|
option(WITH_LINKER_LLD "Use ld.lld linker which is usually faster than ld.gold" OFF)
|
||||||
mark_as_advanced(WITH_LINKER_LLD)
|
mark_as_advanced(WITH_LINKER_LLD)
|
||||||
endif()
|
endif()
|
||||||
|
if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||||
|
option(WITH_LINKER_MOLD "Use ld.mold linker which is usually faster than ld.gold & ld.lld." OFF)
|
||||||
|
mark_as_advanced(WITH_LINKER_MOLD)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
option(WITH_COMPILER_ASAN "Build and link against address sanitizer (only for Debug & RelWithDebInfo targets)." OFF)
|
option(WITH_COMPILER_ASAN "Build and link against address sanitizer (only for Debug & RelWithDebInfo targets)." OFF)
|
||||||
@@ -704,9 +710,12 @@ if(UNIX AND NOT APPLE)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Installation process.
|
# Installation process.
|
||||||
option(POSTINSTALL_SCRIPT "Run given CMake script after installation process" OFF)
|
set(POSTINSTALL_SCRIPT "" CACHE FILEPATH "Run given CMake script after installation process")
|
||||||
mark_as_advanced(POSTINSTALL_SCRIPT)
|
mark_as_advanced(POSTINSTALL_SCRIPT)
|
||||||
|
|
||||||
|
set(POSTCONFIGURE_SCRIPT "" CACHE FILEPATH "Run given CMake script as the last step of CMake configuration")
|
||||||
|
mark_as_advanced(POSTCONFIGURE_SCRIPT)
|
||||||
|
|
||||||
# end option(...)
|
# end option(...)
|
||||||
|
|
||||||
|
|
||||||
@@ -2070,3 +2079,8 @@ endif()
|
|||||||
if(0)
|
if(0)
|
||||||
print_all_vars()
|
print_all_vars()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Should be the last step of configuration.
|
||||||
|
if(POSTCONFIGURE_SCRIPT)
|
||||||
|
include(${POSTCONFIGURE_SCRIPT})
|
||||||
|
endif()
|
||||||
|
@@ -63,6 +63,7 @@ include(cmake/jpeg.cmake)
|
|||||||
include(cmake/blosc.cmake)
|
include(cmake/blosc.cmake)
|
||||||
include(cmake/pthreads.cmake)
|
include(cmake/pthreads.cmake)
|
||||||
include(cmake/openexr.cmake)
|
include(cmake/openexr.cmake)
|
||||||
|
include(cmake/brotli.cmake)
|
||||||
include(cmake/freetype.cmake)
|
include(cmake/freetype.cmake)
|
||||||
include(cmake/freeglut.cmake)
|
include(cmake/freeglut.cmake)
|
||||||
include(cmake/glew.cmake)
|
include(cmake/glew.cmake)
|
||||||
|
@@ -25,8 +25,13 @@ else()
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
set(BOOST_TOOLSET toolset=msvc-14.1)
|
if(MSVC_VERSION GREATER_EQUAL 1920) # 2019
|
||||||
set(BOOST_COMPILER_STRING -vc141)
|
set(BOOST_TOOLSET toolset=msvc-14.2)
|
||||||
|
set(BOOST_COMPILER_STRING -vc142)
|
||||||
|
else() # 2017
|
||||||
|
set(BOOST_TOOLSET toolset=msvc-14.1)
|
||||||
|
set(BOOST_COMPILER_STRING -vc141)
|
||||||
|
endif()
|
||||||
|
|
||||||
set(BOOST_CONFIGURE_COMMAND bootstrap.bat)
|
set(BOOST_CONFIGURE_COMMAND bootstrap.bat)
|
||||||
set(BOOST_BUILD_COMMAND b2)
|
set(BOOST_BUILD_COMMAND b2)
|
||||||
|
38
build_files/build_environment/cmake/brotli.cmake
Normal file
38
build_files/build_environment/cmake/brotli.cmake
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software Foundation,
|
||||||
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
#
|
||||||
|
# ***** END GPL LICENSE BLOCK *****
|
||||||
|
|
||||||
|
set(BROTLI_EXTRA_ARGS
|
||||||
|
)
|
||||||
|
|
||||||
|
ExternalProject_Add(external_brotli
|
||||||
|
URL file://${PACKAGE_DIR}/${BROTLI_FILE}
|
||||||
|
DOWNLOAD_DIR ${DOWNLOAD_DIR}
|
||||||
|
URL_HASH ${BROTLI_HASH_TYPE}=${BROTLI_HASH}
|
||||||
|
PREFIX ${BUILD_DIR}/brotli
|
||||||
|
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/brotli ${DEFAULT_CMAKE_FLAGS} ${BROTLI_EXTRA_ARGS}
|
||||||
|
INSTALL_DIR ${LIBDIR}/brotli
|
||||||
|
)
|
||||||
|
|
||||||
|
if(BUILD_MODE STREQUAL Release AND WIN32)
|
||||||
|
ExternalProject_Add_Step(external_brotli after_install
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/brotli/include ${HARVEST_TARGET}/brotli/include
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/brotli/lib/brotlidec-static${LIBEXT} ${HARVEST_TARGET}/brotli/lib/brotlidec-static${LIBEXT}
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/brotli/lib/brotlicommon-static${LIBEXT} ${HARVEST_TARGET}/brotli/lib/brotlicommon-static${LIBEXT}
|
||||||
|
DEPENDEES install
|
||||||
|
)
|
||||||
|
endif()
|
@@ -94,3 +94,4 @@ download_source(POTRACE)
|
|||||||
download_source(HARU)
|
download_source(HARU)
|
||||||
download_source(ZSTD)
|
download_source(ZSTD)
|
||||||
download_source(FLEX)
|
download_source(FLEX)
|
||||||
|
download_source(BROTLI)
|
||||||
|
@@ -23,9 +23,12 @@ set(FREETYPE_EXTRA_ARGS
|
|||||||
-DWITH_HarfBuzz=OFF
|
-DWITH_HarfBuzz=OFF
|
||||||
-DFT_WITH_HARFBUZZ=OFF
|
-DFT_WITH_HARFBUZZ=OFF
|
||||||
-DFT_WITH_BZIP2=OFF
|
-DFT_WITH_BZIP2=OFF
|
||||||
|
-DFT_WITH_BROTLI=ON
|
||||||
-DCMAKE_DISABLE_FIND_PACKAGE_HarfBuzz=TRUE
|
-DCMAKE_DISABLE_FIND_PACKAGE_HarfBuzz=TRUE
|
||||||
-DCMAKE_DISABLE_FIND_PACKAGE_BZip2=TRUE
|
-DCMAKE_DISABLE_FIND_PACKAGE_BZip2=TRUE
|
||||||
-DCMAKE_DISABLE_FIND_PACKAGE_BrotliDec=TRUE)
|
-DPC_BROTLIDEC_INCLUDEDIR=${LIBDIR}/brotli/include
|
||||||
|
-DPC_BROTLIDEC_LIBDIR=${LIBDIR}/brotli/lib
|
||||||
|
)
|
||||||
|
|
||||||
ExternalProject_Add(external_freetype
|
ExternalProject_Add(external_freetype
|
||||||
URL file://${PACKAGE_DIR}/${FREETYPE_FILE}
|
URL file://${PACKAGE_DIR}/${FREETYPE_FILE}
|
||||||
@@ -36,6 +39,11 @@ ExternalProject_Add(external_freetype
|
|||||||
INSTALL_DIR ${LIBDIR}/freetype
|
INSTALL_DIR ${LIBDIR}/freetype
|
||||||
)
|
)
|
||||||
|
|
||||||
|
add_dependencies(
|
||||||
|
external_freetype
|
||||||
|
external_brotli
|
||||||
|
)
|
||||||
|
|
||||||
if(BUILD_MODE STREQUAL Release AND WIN32)
|
if(BUILD_MODE STREQUAL Release AND WIN32)
|
||||||
ExternalProject_Add_Step(external_freetype after_install
|
ExternalProject_Add_Step(external_freetype after_install
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/freetype ${HARVEST_TARGET}/freetype
|
COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/freetype ${HARVEST_TARGET}/freetype
|
||||||
|
@@ -79,6 +79,8 @@ endfunction()
|
|||||||
harvest(alembic/include alembic/include "*.h")
|
harvest(alembic/include alembic/include "*.h")
|
||||||
harvest(alembic/lib/libAlembic.a alembic/lib/libAlembic.a)
|
harvest(alembic/lib/libAlembic.a alembic/lib/libAlembic.a)
|
||||||
harvest(alembic/bin alembic/bin "*")
|
harvest(alembic/bin alembic/bin "*")
|
||||||
|
harvest(brotli/include brotli/include "*.h")
|
||||||
|
harvest(brotli/lib brotli/lib "*.a")
|
||||||
harvest(boost/include boost/include "*")
|
harvest(boost/include boost/include "*")
|
||||||
harvest(boost/lib boost/lib "*.a")
|
harvest(boost/lib boost/lib "*.a")
|
||||||
harvest(ffmpeg/include ffmpeg/include "*.h")
|
harvest(ffmpeg/include ffmpeg/include "*.h")
|
||||||
|
@@ -83,9 +83,9 @@ else()
|
|||||||
set(OPENEXR_VERSION_POSTFIX)
|
set(OPENEXR_VERSION_POSTFIX)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(FREETYPE_VERSION 2.10.2)
|
set(FREETYPE_VERSION 2.11.0)
|
||||||
set(FREETYPE_URI http://prdownloads.sourceforge.net/freetype/freetype-${FREETYPE_VERSION}.tar.gz)
|
set(FREETYPE_URI http://prdownloads.sourceforge.net/freetype/freetype-${FREETYPE_VERSION}.tar.gz)
|
||||||
set(FREETYPE_HASH b1cb620e4c875cd4d1bfa04945400945)
|
set(FREETYPE_HASH cf09172322f6b50cf8f568bf8fe14bde)
|
||||||
set(FREETYPE_HASH_TYPE MD5)
|
set(FREETYPE_HASH_TYPE MD5)
|
||||||
set(FREETYPE_FILE freetype-${FREETYPE_VERSION}.tar.gz)
|
set(FREETYPE_FILE freetype-${FREETYPE_VERSION}.tar.gz)
|
||||||
|
|
||||||
@@ -500,3 +500,9 @@ set(ZSTD_FILE zstd-${ZSTD_VERSION}.tar.gz)
|
|||||||
|
|
||||||
set(SSE2NEON_GIT https://github.com/DLTcollab/sse2neon.git)
|
set(SSE2NEON_GIT https://github.com/DLTcollab/sse2neon.git)
|
||||||
set(SSE2NEON_GIT_HASH fe5ff00bb8d19b327714a3c290f3e2ce81ba3525)
|
set(SSE2NEON_GIT_HASH fe5ff00bb8d19b327714a3c290f3e2ce81ba3525)
|
||||||
|
|
||||||
|
set(BROTLI_VERSION v1.0.9)
|
||||||
|
set(BROTLI_URI https://github.com/google/brotli/archive/refs/tags/${BROTLI_VERSION}.tar.gz)
|
||||||
|
set(BROTLI_HASH f9e8d81d0405ba66d181529af42a3354f838c939095ff99930da6aa9cdf6fe46)
|
||||||
|
set(BROTLI_HASH_TYPE SHA256)
|
||||||
|
set(BROTLI_FILE brotli-${BROTLI_VERSION}.tar.gz)
|
||||||
|
@@ -492,7 +492,7 @@ OIIO_SKIP=false
|
|||||||
LLVM_VERSION="12.0.0"
|
LLVM_VERSION="12.0.0"
|
||||||
LLVM_VERSION_SHORT="12.0"
|
LLVM_VERSION_SHORT="12.0"
|
||||||
LLVM_VERSION_MIN="11.0"
|
LLVM_VERSION_MIN="11.0"
|
||||||
LLVM_VERSION_MEX="13.0"
|
LLVM_VERSION_MEX="14.0"
|
||||||
LLVM_VERSION_FOUND=""
|
LLVM_VERSION_FOUND=""
|
||||||
LLVM_FORCE_BUILD=false
|
LLVM_FORCE_BUILD=false
|
||||||
LLVM_FORCE_REBUILD=false
|
LLVM_FORCE_REBUILD=false
|
||||||
@@ -3620,8 +3620,8 @@ compile_FFmpeg() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
./configure --cc="gcc -Wl,--as-needed" \
|
./configure --cc="gcc -Wl,--as-needed" \
|
||||||
--extra-ldflags="-pthread -static-libgcc" \
|
--extra-ldflags="-pthread" \
|
||||||
--prefix=$_inst --enable-static \
|
--prefix=$_inst --enable-shared \
|
||||||
--disable-ffplay --disable-doc \
|
--disable-ffplay --disable-doc \
|
||||||
--enable-gray \
|
--enable-gray \
|
||||||
--enable-avfilter --disable-vdpau \
|
--enable-avfilter --disable-vdpau \
|
||||||
@@ -5721,76 +5721,6 @@ install_OTHER() {
|
|||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
# Printing User Info
|
# Printing User Info
|
||||||
|
|
||||||
print_info_ffmpeglink_DEB() {
|
|
||||||
dpkg -L $_packages | grep -e ".*\/lib[^\/]\+\.so" | gawk '{ printf(nlines ? "'"$_ffmpeg_list_sep"'%s" : "%s", gensub(/.*lib([^\/]+)\.so/, "\\1", "g", $0)); nlines++ }'
|
|
||||||
}
|
|
||||||
|
|
||||||
print_info_ffmpeglink_RPM() {
|
|
||||||
rpm -ql $_packages | grep -e ".*\/lib[^\/]\+\.so" | gawk '{ printf(nlines ? "'"$_ffmpeg_list_sep"'%s" : "%s", gensub(/.*lib([^\/]+)\.so/, "\\1", "g", $0)); nlines++ }'
|
|
||||||
}
|
|
||||||
|
|
||||||
print_info_ffmpeglink_ARCH() {
|
|
||||||
pacman -Ql $_packages | grep -e ".*\/lib[^\/]\+\.so$" | gawk '{ printf(nlines ? "'"$_ffmpeg_list_sep"'%s" : "%s", gensub(/.*lib([^\/]+)\.so/, "\\1", "g", $0)); nlines++ }'
|
|
||||||
}
|
|
||||||
|
|
||||||
print_info_ffmpeglink() {
|
|
||||||
# This func must only print a ';'-separated list of libs...
|
|
||||||
if [ -z "$DISTRO" ]; then
|
|
||||||
ERROR "Failed to detect distribution type"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Create list of packages from which to get libs names...
|
|
||||||
_packages=""
|
|
||||||
|
|
||||||
if [ "$THEORA_USE" = true ]; then
|
|
||||||
_packages="$_packages $THEORA_DEV"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$VORBIS_USE" = true ]; then
|
|
||||||
_packages="$_packages $VORBIS_DEV"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$OGG_USE" = true ]; then
|
|
||||||
_packages="$_packages $OGG_DEV"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$XVID_USE" = true ]; then
|
|
||||||
_packages="$_packages $XVID_DEV"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$VPX_USE" = true ]; then
|
|
||||||
_packages="$_packages $VPX_DEV"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$OPUS_USE" = true ]; then
|
|
||||||
_packages="$_packages $OPUS_DEV"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$MP3LAME_USE" = true ]; then
|
|
||||||
_packages="$_packages $MP3LAME_DEV"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$X264_USE" = true ]; then
|
|
||||||
_packages="$_packages $X264_DEV"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$OPENJPEG_USE" = true ]; then
|
|
||||||
_packages="$_packages $OPENJPEG_DEV"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$DISTRO" = "DEB" ]; then
|
|
||||||
print_info_ffmpeglink_DEB
|
|
||||||
elif [ "$DISTRO" = "RPM" ]; then
|
|
||||||
print_info_ffmpeglink_RPM
|
|
||||||
elif [ "$DISTRO" = "ARCH" ]; then
|
|
||||||
print_info_ffmpeglink_ARCH
|
|
||||||
# XXX TODO!
|
|
||||||
else
|
|
||||||
PRINT "<Could not determine additional link libraries needed for ffmpeg, replace this by valid list of libs...>"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
print_info() {
|
print_info() {
|
||||||
PRINT ""
|
PRINT ""
|
||||||
PRINT ""
|
PRINT ""
|
||||||
@@ -6002,12 +5932,10 @@ print_info() {
|
|||||||
|
|
||||||
if [ "$FFMPEG_SKIP" = false ]; then
|
if [ "$FFMPEG_SKIP" = false ]; then
|
||||||
_1="-D WITH_CODEC_FFMPEG=ON"
|
_1="-D WITH_CODEC_FFMPEG=ON"
|
||||||
_2="-D FFMPEG_LIBRARIES='avformat;avcodec;avutil;avdevice;swscale;swresample;lzma;rt;`print_info_ffmpeglink`'"
|
|
||||||
PRINT " $_1"
|
PRINT " $_1"
|
||||||
PRINT " $_2"
|
_buildargs="$_buildargs $_1"
|
||||||
_buildargs="$_buildargs $_1 $_2"
|
|
||||||
if [ -d $INST/ffmpeg ]; then
|
if [ -d $INST/ffmpeg ]; then
|
||||||
_1="-D FFMPEG=$INST/ffmpeg"
|
_1="-D FFMPEG_ROOT_DIR=$INST/ffmpeg"
|
||||||
PRINT " $_1"
|
PRINT " $_1"
|
||||||
_buildargs="$_buildargs $_1"
|
_buildargs="$_buildargs $_1"
|
||||||
fi
|
fi
|
||||||
|
@@ -1,64 +1,39 @@
|
|||||||
@echo off
|
@echo off
|
||||||
if NOT "%1" == "" (
|
if NOT "%1" == "" (
|
||||||
if "%1" == "2013" (
|
|
||||||
echo "Building for VS2013"
|
|
||||||
set VSVER=12.0
|
|
||||||
set VSVER_SHORT=12
|
|
||||||
set BuildDir=VS12
|
|
||||||
goto par2
|
|
||||||
)
|
|
||||||
if "%1" == "2015" (
|
|
||||||
echo "Building for VS2015"
|
|
||||||
set VSVER=14.0
|
|
||||||
set VSVER_SHORT=14
|
|
||||||
set BuildDir=VS14
|
|
||||||
goto par2
|
|
||||||
)
|
|
||||||
if "%1" == "2017" (
|
if "%1" == "2017" (
|
||||||
echo "Building for VS2017"
|
echo "Building for VS2017"
|
||||||
set VSVER=15.0
|
set VSVER=15.0
|
||||||
set VSVER_SHORT=15
|
set VSVER_SHORT=15
|
||||||
set BuildDir=VS15
|
set BuildDir=VS15
|
||||||
goto par2
|
goto par2
|
||||||
|
)
|
||||||
|
if "%1" == "2019" (
|
||||||
|
echo "Building for VS2019"
|
||||||
|
set VSVER=15.0
|
||||||
|
set VSVER_SHORT=15
|
||||||
|
set BuildDir=VS15
|
||||||
|
goto par2
|
||||||
)
|
)
|
||||||
|
|
||||||
)
|
)
|
||||||
:usage
|
:usage
|
||||||
|
|
||||||
Echo Usage build_deps 2013/2015/2017 x64/x86
|
Echo Usage build_deps 2017/2019 x64
|
||||||
goto exit
|
goto exit
|
||||||
:par2
|
:par2
|
||||||
if NOT "%2" == "" (
|
if NOT "%2" == "" (
|
||||||
if "%2" == "x86" (
|
|
||||||
echo "Building for x86"
|
|
||||||
set HARVESTROOT=Windows_vc
|
|
||||||
set ARCH=86
|
|
||||||
if "%1" == "2013" (
|
|
||||||
set CMAKE_BUILDER=Visual Studio 12 2013
|
|
||||||
)
|
|
||||||
if "%1" == "2015" (
|
|
||||||
set CMAKE_BUILDER=Visual Studio 14 2015
|
|
||||||
)
|
|
||||||
if "%1" == "2017" (
|
|
||||||
set CMAKE_BUILDER=Visual Studio 15 2017
|
|
||||||
)
|
|
||||||
|
|
||||||
goto start
|
|
||||||
)
|
|
||||||
if "%2" == "x64" (
|
if "%2" == "x64" (
|
||||||
echo "Building for x64"
|
echo "Building for x64"
|
||||||
set HARVESTROOT=Win64_vc
|
set HARVESTROOT=Win64_vc
|
||||||
set ARCH=64
|
set ARCH=64
|
||||||
if "%1" == "2013" (
|
if "%1" == "2019" (
|
||||||
set CMAKE_BUILDER=Visual Studio 12 2013 Win64
|
set CMAKE_BUILDER=Visual Studio 16 2019
|
||||||
)
|
set CMAKE_BUILD_ARCH=-A x64
|
||||||
if "%1" == "2015" (
|
|
||||||
set CMAKE_BUILDER=Visual Studio 14 2015 Win64
|
|
||||||
)
|
)
|
||||||
if "%1" == "2017" (
|
if "%1" == "2017" (
|
||||||
set CMAKE_BUILDER=Visual Studio 15 2017 Win64
|
set CMAKE_BUILDER=Visual Studio 15 2017 Win64
|
||||||
|
set CMAKE_BUILD_ARCH=
|
||||||
)
|
)
|
||||||
|
|
||||||
goto start
|
goto start
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -120,7 +95,7 @@ set path=%BUILD_DIR%\downloads\mingw\mingw64\msys\1.0\bin\;%BUILD_DIR%\downloads
|
|||||||
mkdir %STAGING%\%BuildDir%%ARCH%R
|
mkdir %STAGING%\%BuildDir%%ARCH%R
|
||||||
cd %Staging%\%BuildDir%%ARCH%R
|
cd %Staging%\%BuildDir%%ARCH%R
|
||||||
echo %DATE% %TIME% : Start > %StatusFile%
|
echo %DATE% %TIME% : Start > %StatusFile%
|
||||||
cmake -G "%CMAKE_BUILDER%" -Thost=x64 %SOURCE_DIR% -DPACKAGE_DIR=%BUILD_DIR%/packages -DDOWNLOAD_DIR=%BUILD_DIR%/downloads -DBUILD_MODE=Release -DHARVEST_TARGET=%HARVEST_DIR%/%HARVESTROOT%%VSVER_SHORT%/
|
cmake -G "%CMAKE_BUILDER%" %CMAKE_BUILD_ARCH% -Thost=x64 %SOURCE_DIR% -DPACKAGE_DIR=%BUILD_DIR%/packages -DDOWNLOAD_DIR=%BUILD_DIR%/downloads -DBUILD_MODE=Release -DHARVEST_TARGET=%HARVEST_DIR%/%HARVESTROOT%%VSVER_SHORT%/
|
||||||
echo %DATE% %TIME% : Release Configuration done >> %StatusFile%
|
echo %DATE% %TIME% : Release Configuration done >> %StatusFile%
|
||||||
if "%dobuild%" == "1" (
|
if "%dobuild%" == "1" (
|
||||||
msbuild /m "ll.vcxproj" /p:Configuration=Release /fl /flp:logfile=BlenderDeps_llvm.log;Verbosity=normal
|
msbuild /m "ll.vcxproj" /p:Configuration=Release /fl /flp:logfile=BlenderDeps_llvm.log;Verbosity=normal
|
||||||
@@ -133,7 +108,7 @@ if "%NODEBUG%" == "1" goto exit
|
|||||||
cd %BUILD_DIR%
|
cd %BUILD_DIR%
|
||||||
mkdir %STAGING%\%BuildDir%%ARCH%D
|
mkdir %STAGING%\%BuildDir%%ARCH%D
|
||||||
cd %Staging%\%BuildDir%%ARCH%D
|
cd %Staging%\%BuildDir%%ARCH%D
|
||||||
cmake -G "%CMAKE_BUILDER%" -Thost=x64 %SOURCE_DIR% -DPACKAGE_DIR=%BUILD_DIR%/packages -DDOWNLOAD_DIR=%BUILD_DIR%/downloads -DCMAKE_BUILD_TYPE=Debug -DBUILD_MODE=Debug -DHARVEST_TARGET=%HARVEST_DIR%/%HARVESTROOT%%VSVER_SHORT%/ %CMAKE_DEBUG_OPTIONS%
|
cmake -G "%CMAKE_BUILDER%" %CMAKE_BUILD_ARCH% -Thost=x64 %SOURCE_DIR% -DPACKAGE_DIR=%BUILD_DIR%/packages -DDOWNLOAD_DIR=%BUILD_DIR%/downloads -DCMAKE_BUILD_TYPE=Debug -DBUILD_MODE=Debug -DHARVEST_TARGET=%HARVEST_DIR%/%HARVESTROOT%%VSVER_SHORT%/ %CMAKE_DEBUG_OPTIONS%
|
||||||
echo %DATE% %TIME% : Debug Configuration done >> %StatusFile%
|
echo %DATE% %TIME% : Debug Configuration done >> %StatusFile%
|
||||||
if "%dobuild%" == "1" (
|
if "%dobuild%" == "1" (
|
||||||
msbuild /m "ll.vcxproj" /p:Configuration=Debug /fl /flp:logfile=BlenderDeps_llvm.log;;Verbosity=normal
|
msbuild /m "ll.vcxproj" /p:Configuration=Debug /fl /flp:logfile=BlenderDeps_llvm.log;;Verbosity=normal
|
||||||
|
83
build_files/cmake/Modules/FindBrotli.cmake
Normal file
83
build_files/cmake/Modules/FindBrotli.cmake
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
# - Find Brotli library (compression for freetype/woff2).
|
||||||
|
# This module defines
|
||||||
|
# BROTLI_INCLUDE_DIRS, where to find Brotli headers, Set when
|
||||||
|
# BROTLI_INCLUDE_DIR is found.
|
||||||
|
# BROTLI_LIBRARIES, libraries to link against to use Brotli.
|
||||||
|
# BROTLI_ROOT_DIR, The base directory to search for Brotli.
|
||||||
|
# This can also be an environment variable.
|
||||||
|
# BROTLI_FOUND, If false, do not try to use Brotli.
|
||||||
|
#
|
||||||
|
|
||||||
|
#=============================================================================
|
||||||
|
# Copyright 2022 Blender Foundation.
|
||||||
|
#
|
||||||
|
# Distributed under the OSI-approved BSD 3-Clause License,
|
||||||
|
# see accompanying file BSD-3-Clause-license.txt for details.
|
||||||
|
#=============================================================================
|
||||||
|
|
||||||
|
# If BROTLI_ROOT_DIR was defined in the environment, use it.
|
||||||
|
IF(NOT BROTLI_ROOT_DIR AND NOT $ENV{BROTLI_ROOT_DIR} STREQUAL "")
|
||||||
|
SET(BROTLI_ROOT_DIR $ENV{BROTLI_ROOT_DIR})
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
SET(_BROTLI_SEARCH_DIRS
|
||||||
|
${BROTLI_ROOT_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
FIND_PATH(BROTLI_INCLUDE_DIR
|
||||||
|
NAMES
|
||||||
|
brotli/decode.h
|
||||||
|
HINTS
|
||||||
|
${_BROTLI_SEARCH_DIRS}
|
||||||
|
PATH_SUFFIXES
|
||||||
|
include
|
||||||
|
DOC "Brotli header files"
|
||||||
|
)
|
||||||
|
|
||||||
|
FIND_LIBRARY(BROTLI_LIBRARY_COMMON
|
||||||
|
NAMES
|
||||||
|
# Some builds use a special `-static` postfix in their static libraries names.
|
||||||
|
brotlicommon-static
|
||||||
|
brotlicommon
|
||||||
|
HINTS
|
||||||
|
${_BROTLI_SEARCH_DIRS}
|
||||||
|
PATH_SUFFIXES
|
||||||
|
lib64 lib lib/static
|
||||||
|
DOC "Brotli static common library"
|
||||||
|
)
|
||||||
|
FIND_LIBRARY(BROTLI_LIBRARY_DEC
|
||||||
|
NAMES
|
||||||
|
# Some builds use a special `-static` postfix in their static libraries names.
|
||||||
|
brotlidec-static
|
||||||
|
brotlidec
|
||||||
|
HINTS
|
||||||
|
${_BROTLI_SEARCH_DIRS}
|
||||||
|
PATH_SUFFIXES
|
||||||
|
lib64 lib lib/static
|
||||||
|
DOC "Brotli static decode library"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
IF(${BROTLI_LIBRARY_COMMON_NOTFOUND} or ${BROTLI_LIBRARY_DEC_NOTFOUND})
|
||||||
|
set(BROTLI_FOUND FALSE)
|
||||||
|
ELSE()
|
||||||
|
# handle the QUIETLY and REQUIRED arguments and set BROTLI_FOUND to TRUE if
|
||||||
|
# all listed variables are TRUE
|
||||||
|
INCLUDE(FindPackageHandleStandardArgs)
|
||||||
|
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Brotli DEFAULT_MSG BROTLI_LIBRARY_COMMON BROTLI_LIBRARY_DEC BROTLI_INCLUDE_DIR)
|
||||||
|
|
||||||
|
IF(BROTLI_FOUND)
|
||||||
|
get_filename_component(BROTLI_LIBRARY_DIR ${BROTLI_LIBRARY_COMMON} DIRECTORY)
|
||||||
|
SET(BROTLI_INCLUDE_DIRS ${BROTLI_INCLUDE_DIR})
|
||||||
|
SET(BROTLI_LIBRARIES ${BROTLI_LIBRARY_DEC} ${BROTLI_LIBRARY_COMMON})
|
||||||
|
ENDIF()
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
MARK_AS_ADVANCED(
|
||||||
|
BROTLI_INCLUDE_DIR
|
||||||
|
BROTLI_LIBRARY_COMMON
|
||||||
|
BROTLI_LIBRARY_DEC
|
||||||
|
BROTLI_LIBRARY_DIR
|
||||||
|
)
|
||||||
|
|
||||||
|
UNSET(_BROTLI_SEARCH_DIRS)
|
@@ -33,6 +33,8 @@ if(NOT FFMPEG_FIND_COMPONENTS)
|
|||||||
avfilter
|
avfilter
|
||||||
avformat
|
avformat
|
||||||
avutil
|
avutil
|
||||||
|
swscale
|
||||||
|
swresample
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@@ -50,9 +52,9 @@ foreach(_component ${FFMPEG_FIND_COMPONENTS})
|
|||||||
string(TOUPPER ${_component} _upper_COMPONENT)
|
string(TOUPPER ${_component} _upper_COMPONENT)
|
||||||
find_library(FFMPEG_${_upper_COMPONENT}_LIBRARY
|
find_library(FFMPEG_${_upper_COMPONENT}_LIBRARY
|
||||||
NAMES
|
NAMES
|
||||||
${_upper_COMPONENT}
|
${_component}
|
||||||
HINTS
|
HINTS
|
||||||
${LIBDIR}/ffmpeg
|
${_ffmpeg_SEARCH_DIRS}
|
||||||
PATH_SUFFIXES
|
PATH_SUFFIXES
|
||||||
lib64 lib
|
lib64 lib
|
||||||
)
|
)
|
||||||
|
@@ -488,7 +488,6 @@ function(blender_add_test_executable
|
|||||||
|
|
||||||
include_directories(${includes})
|
include_directories(${includes})
|
||||||
include_directories(${includes_sys})
|
include_directories(${includes_sys})
|
||||||
setup_libdirs()
|
|
||||||
|
|
||||||
BLENDER_SRC_GTEST_EX(
|
BLENDER_SRC_GTEST_EX(
|
||||||
NAME ${name}
|
NAME ${name}
|
||||||
@@ -525,83 +524,6 @@ function(setup_heavy_lib_pool)
|
|||||||
endif()
|
endif()
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
function(SETUP_LIBDIRS)
|
|
||||||
|
|
||||||
# NOTE: For all new libraries, use absolute library paths.
|
|
||||||
# This should eventually be phased out.
|
|
||||||
# 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})
|
|
||||||
|
|
||||||
if(WITH_PYTHON) # AND NOT WITH_PYTHON_MODULE # WIN32 needs
|
|
||||||
link_directories(${PYTHON_LIBPATH})
|
|
||||||
endif()
|
|
||||||
if(WITH_SDL AND NOT WITH_SDL_DYNLOAD)
|
|
||||||
link_directories(${SDL_LIBPATH})
|
|
||||||
endif()
|
|
||||||
if(WITH_CODEC_FFMPEG)
|
|
||||||
link_directories(${FFMPEG_LIBPATH})
|
|
||||||
endif()
|
|
||||||
if(WITH_IMAGE_OPENEXR)
|
|
||||||
link_directories(${OPENEXR_LIBPATH})
|
|
||||||
endif()
|
|
||||||
if(WITH_IMAGE_TIFF)
|
|
||||||
link_directories(${TIFF_LIBPATH})
|
|
||||||
endif()
|
|
||||||
if(WITH_BOOST)
|
|
||||||
link_directories(${BOOST_LIBPATH})
|
|
||||||
endif()
|
|
||||||
if(WITH_OPENIMAGEIO)
|
|
||||||
link_directories(${OPENIMAGEIO_LIBPATH})
|
|
||||||
endif()
|
|
||||||
if(WITH_OPENIMAGEDENOISE)
|
|
||||||
link_directories(${OPENIMAGEDENOISE_LIBPATH})
|
|
||||||
endif()
|
|
||||||
if(WITH_OPENCOLORIO)
|
|
||||||
link_directories(${OPENCOLORIO_LIBPATH})
|
|
||||||
endif()
|
|
||||||
if(WITH_OPENVDB)
|
|
||||||
link_directories(${OPENVDB_LIBPATH})
|
|
||||||
endif()
|
|
||||||
if(WITH_OPENAL)
|
|
||||||
link_directories(${OPENAL_LIBPATH})
|
|
||||||
endif()
|
|
||||||
if(WITH_JACK AND NOT WITH_JACK_DYNLOAD)
|
|
||||||
link_directories(${JACK_LIBPATH})
|
|
||||||
endif()
|
|
||||||
if(WITH_PULSEAUDIO AND NOT WITH_PULSEAUDIO_DYNLOAD)
|
|
||||||
link_directories(${LIBPULSE_LIBPATH})
|
|
||||||
endif()
|
|
||||||
if(WITH_CODEC_SNDFILE)
|
|
||||||
link_directories(${LIBSNDFILE_LIBPATH})
|
|
||||||
endif()
|
|
||||||
if(WITH_FFTW3)
|
|
||||||
link_directories(${FFTW3_LIBPATH})
|
|
||||||
endif()
|
|
||||||
if(WITH_OPENCOLLADA)
|
|
||||||
link_directories(${OPENCOLLADA_LIBPATH})
|
|
||||||
# # Never set
|
|
||||||
# link_directories(${PCRE_LIBPATH})
|
|
||||||
# link_directories(${EXPAT_LIBPATH})
|
|
||||||
endif()
|
|
||||||
if(WITH_LLVM)
|
|
||||||
link_directories(${LLVM_LIBPATH})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(WITH_ALEMBIC)
|
|
||||||
link_directories(${ALEMBIC_LIBPATH})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(WITH_GMP)
|
|
||||||
link_directories(${GMP_LIBPATH})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(WIN32 AND NOT UNIX)
|
|
||||||
link_directories(${PTHREADS_LIBPATH})
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
# Platform specific linker flags for targets.
|
# Platform specific linker flags for targets.
|
||||||
function(setup_platform_linker_flags
|
function(setup_platform_linker_flags
|
||||||
target)
|
target)
|
||||||
|
@@ -166,13 +166,18 @@ if(WITH_FFTW3)
|
|||||||
find_package(Fftw3)
|
find_package(Fftw3)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# FreeType compiled with Brotli compression for woff2.
|
||||||
find_package(Freetype REQUIRED)
|
find_package(Freetype REQUIRED)
|
||||||
|
list(APPEND FREETYPE_LIBRARIES
|
||||||
|
${LIBDIR}/brotli/lib/libbrotlicommon-static.a
|
||||||
|
${LIBDIR}/brotli/lib/libbrotlidec-static.a)
|
||||||
|
|
||||||
if(WITH_IMAGE_OPENEXR)
|
if(WITH_IMAGE_OPENEXR)
|
||||||
find_package(OpenEXR)
|
find_package(OpenEXR)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WITH_CODEC_FFMPEG)
|
if(WITH_CODEC_FFMPEG)
|
||||||
|
set(FFMPEG_ROOT_DIR ${LIBDIR}/ffmpeg)
|
||||||
set(FFMPEG_FIND_COMPONENTS
|
set(FFMPEG_FIND_COMPONENTS
|
||||||
avcodec avdevice avformat avutil
|
avcodec avdevice avformat avutil
|
||||||
mp3lame ogg opus swresample swscale
|
mp3lame ogg opus swresample swscale
|
||||||
@@ -479,8 +484,11 @@ string(APPEND PLATFORM_LINKFLAGS " -stdlib=libc++")
|
|||||||
# Suppress ranlib "has no symbols" warnings (workaround for T48250)
|
# Suppress ranlib "has no symbols" warnings (workaround for T48250)
|
||||||
set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> Scr <TARGET> <LINK_FLAGS> <OBJECTS>")
|
set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> Scr <TARGET> <LINK_FLAGS> <OBJECTS>")
|
||||||
set(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> Scr <TARGET> <LINK_FLAGS> <OBJECTS>")
|
set(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> Scr <TARGET> <LINK_FLAGS> <OBJECTS>")
|
||||||
set(CMAKE_C_ARCHIVE_FINISH "<CMAKE_RANLIB> -no_warning_for_no_symbols -c <TARGET>")
|
# llvm-ranlib doesn't support this flag. Xcode's libtool does.
|
||||||
set(CMAKE_CXX_ARCHIVE_FINISH "<CMAKE_RANLIB> -no_warning_for_no_symbols -c <TARGET>")
|
if(NOT ${CMAKE_RANLIB} MATCHES ".*llvm-ranlib$")
|
||||||
|
set(CMAKE_C_ARCHIVE_FINISH "<CMAKE_RANLIB> -no_warning_for_no_symbols -c <TARGET>")
|
||||||
|
set(CMAKE_CXX_ARCHIVE_FINISH "<CMAKE_RANLIB> -no_warning_for_no_symbols -c <TARGET>")
|
||||||
|
endif()
|
||||||
|
|
||||||
if(WITH_COMPILER_CCACHE)
|
if(WITH_COMPILER_CCACHE)
|
||||||
if(NOT CMAKE_GENERATOR STREQUAL "Xcode")
|
if(NOT CMAKE_GENERATOR STREQUAL "Xcode")
|
||||||
@@ -507,3 +515,6 @@ list(APPEND CMAKE_BUILD_RPATH "${OpenMP_LIBRARY_DIR}")
|
|||||||
|
|
||||||
set(CMAKE_SKIP_INSTALL_RPATH FALSE)
|
set(CMAKE_SKIP_INSTALL_RPATH FALSE)
|
||||||
list(APPEND CMAKE_INSTALL_RPATH "@loader_path/../Resources/${BLENDER_VERSION}/lib")
|
list(APPEND CMAKE_INSTALL_RPATH "@loader_path/../Resources/${BLENDER_VERSION}/lib")
|
||||||
|
|
||||||
|
# Same as `CFBundleIdentifier` in Info.plist.
|
||||||
|
set(CMAKE_XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER "org.blenderfoundation.blender")
|
||||||
|
@@ -48,6 +48,9 @@ if(NOT DEFINED LIBDIR)
|
|||||||
unset(LIBDIR_CENTOS7_ABI)
|
unset(LIBDIR_CENTOS7_ABI)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Support restoring this value once pre-compiled libraries have been handled.
|
||||||
|
set(WITH_STATIC_LIBS_INIT ${WITH_STATIC_LIBS})
|
||||||
|
|
||||||
if(EXISTS ${LIBDIR})
|
if(EXISTS ${LIBDIR})
|
||||||
message(STATUS "Using pre-compiled LIBDIR: ${LIBDIR}")
|
message(STATUS "Using pre-compiled LIBDIR: ${LIBDIR}")
|
||||||
|
|
||||||
@@ -100,7 +103,22 @@ find_package_wrapper(JPEG REQUIRED)
|
|||||||
find_package_wrapper(PNG REQUIRED)
|
find_package_wrapper(PNG REQUIRED)
|
||||||
find_package_wrapper(ZLIB REQUIRED)
|
find_package_wrapper(ZLIB REQUIRED)
|
||||||
find_package_wrapper(Zstd REQUIRED)
|
find_package_wrapper(Zstd REQUIRED)
|
||||||
find_package_wrapper(Freetype REQUIRED)
|
|
||||||
|
if(NOT WITH_SYSTEM_FREETYPE)
|
||||||
|
# FreeType compiled with Brotli compression for woff2.
|
||||||
|
find_package_wrapper(Freetype REQUIRED)
|
||||||
|
if(EXISTS ${LIBDIR})
|
||||||
|
find_package_wrapper(Brotli REQUIRED)
|
||||||
|
|
||||||
|
# NOTE: This is done on WIN32 & APPLE but fails on some Linux systems.
|
||||||
|
# See: https://devtalk.blender.org/t/22536
|
||||||
|
# So `BROTLI_LIBRARIES` need to be added `FREETYPE_LIBRARIES`.
|
||||||
|
#
|
||||||
|
# list(APPEND FREETYPE_LIBRARIES
|
||||||
|
# ${BROTLI_LIBRARIES}
|
||||||
|
# )
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
if(WITH_PYTHON)
|
if(WITH_PYTHON)
|
||||||
# No way to set py35, remove for now.
|
# No way to set py35, remove for now.
|
||||||
@@ -178,26 +196,30 @@ endif()
|
|||||||
|
|
||||||
if(WITH_CODEC_FFMPEG)
|
if(WITH_CODEC_FFMPEG)
|
||||||
if(EXISTS ${LIBDIR})
|
if(EXISTS ${LIBDIR})
|
||||||
# For precompiled lib directory, all ffmpeg dependencies are in the same folder
|
set(FFMPEG_ROOT_DIR ${LIBDIR}/ffmpeg)
|
||||||
file(GLOB ffmpeg_libs ${LIBDIR}/ffmpeg/lib/*.a ${LIBDIR}/sndfile/lib/*.a)
|
# Override FFMPEG components to also include static library dependencies
|
||||||
set(FFMPEG ${LIBDIR}/ffmpeg CACHE PATH "FFMPEG Directory")
|
# included with precompiled libraries, and to ensure correct link order.
|
||||||
set(FFMPEG_LIBRARIES ${ffmpeg_libs} ${ffmpeg_libs} CACHE STRING "FFMPEG Libraries")
|
set(FFMPEG_FIND_COMPONENTS
|
||||||
else()
|
avformat avcodec avdevice avutil swresample swscale
|
||||||
set(FFMPEG /usr CACHE PATH "FFMPEG Directory")
|
sndfile
|
||||||
set(FFMPEG_LIBRARIES avformat avcodec avutil avdevice swscale CACHE STRING "FFMPEG Libraries")
|
FLAC
|
||||||
|
mp3lame
|
||||||
|
opus
|
||||||
|
theora theoradec theoraenc
|
||||||
|
vorbis vorbisenc vorbisfile ogg
|
||||||
|
vpx
|
||||||
|
x264
|
||||||
|
xvidcore)
|
||||||
|
elseif(FFMPEG)
|
||||||
|
# Old cache variable used for root dir, convert to new standard.
|
||||||
|
set(FFMPEG_ROOT_DIR ${FFMPEG})
|
||||||
endif()
|
endif()
|
||||||
|
find_package(FFmpeg)
|
||||||
|
|
||||||
mark_as_advanced(FFMPEG)
|
if(NOT FFMPEG_FOUND)
|
||||||
|
set(WITH_CODEC_FFMPEG OFF)
|
||||||
# lame, but until we have proper find module for ffmpeg
|
message(STATUS "FFmpeg not found, disabling it")
|
||||||
set(FFMPEG_INCLUDE_DIRS ${FFMPEG}/include)
|
|
||||||
if(EXISTS "${FFMPEG}/include/ffmpeg/")
|
|
||||||
list(APPEND FFMPEG_INCLUDE_DIRS "${FFMPEG}/include/ffmpeg")
|
|
||||||
endif()
|
endif()
|
||||||
# end lameness
|
|
||||||
|
|
||||||
mark_as_advanced(FFMPEG_LIBRARIES)
|
|
||||||
set(FFMPEG_LIBPATH ${FFMPEG}/lib)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WITH_FFTW3)
|
if(WITH_FFTW3)
|
||||||
@@ -532,6 +554,21 @@ add_definitions(-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE
|
|||||||
#
|
#
|
||||||
# Keep last, so indirectly linked libraries don't override our own pre-compiled libs.
|
# Keep last, so indirectly linked libraries don't override our own pre-compiled libs.
|
||||||
|
|
||||||
|
if(EXISTS ${LIBDIR})
|
||||||
|
# Clear the prefix path as it causes the `LIBDIR` to override system locations.
|
||||||
|
unset(CMAKE_PREFIX_PATH)
|
||||||
|
|
||||||
|
# Since the pre-compiled `LIBDIR` directories have been handled, don't prefer static libraries.
|
||||||
|
set(WITH_STATIC_LIBS ${WITH_STATIC_LIBS_INIT})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(WITH_SYSTEM_FREETYPE)
|
||||||
|
find_package_wrapper(Freetype)
|
||||||
|
if(NOT FREETYPE_FOUND)
|
||||||
|
message(FATAL_ERROR "Failed finding system FreeType version!")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
if(WITH_LZO AND WITH_SYSTEM_LZO)
|
if(WITH_LZO AND WITH_SYSTEM_LZO)
|
||||||
find_package_wrapper(LZO)
|
find_package_wrapper(LZO)
|
||||||
if(NOT LZO_FOUND)
|
if(NOT LZO_FOUND)
|
||||||
@@ -644,6 +681,9 @@ endif()
|
|||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
# Compilers
|
# Compilers
|
||||||
|
|
||||||
|
# Only set the linker once.
|
||||||
|
set(_IS_LINKER_DEFAULT ON)
|
||||||
|
|
||||||
# GNU Compiler
|
# GNU Compiler
|
||||||
if(CMAKE_COMPILER_IS_GNUCC)
|
if(CMAKE_COMPILER_IS_GNUCC)
|
||||||
# ffp-contract=off:
|
# ffp-contract=off:
|
||||||
@@ -662,26 +702,89 @@ if(CMAKE_COMPILER_IS_GNUCC)
|
|||||||
string(PREPEND CMAKE_CXX_FLAGS_RELWITHDEBINFO "${GCC_EXTRA_FLAGS_RELEASE} ")
|
string(PREPEND CMAKE_CXX_FLAGS_RELWITHDEBINFO "${GCC_EXTRA_FLAGS_RELEASE} ")
|
||||||
unset(GCC_EXTRA_FLAGS_RELEASE)
|
unset(GCC_EXTRA_FLAGS_RELEASE)
|
||||||
|
|
||||||
if(WITH_LINKER_GOLD)
|
# NOTE(@campbellbarton): Eventually mold will be able to use `-fuse-ld=mold`,
|
||||||
|
# however at the moment this only works for GCC 12.1+ (unreleased at time of writing).
|
||||||
|
# So a workaround is used here "-B" which points to another path to find system commands
|
||||||
|
# such as `ld`.
|
||||||
|
if(WITH_LINKER_MOLD AND _IS_LINKER_DEFAULT)
|
||||||
|
find_program(MOLD_BIN "mold")
|
||||||
|
mark_as_advanced(MOLD_BIN)
|
||||||
|
if(NOT MOLD_BIN)
|
||||||
|
message(STATUS "The \"mold\" binary could not be found, using system linker.")
|
||||||
|
set(WITH_LINKER_MOLD OFF)
|
||||||
|
else()
|
||||||
|
# By default mold installs the binary to:
|
||||||
|
# - `{PREFIX}/bin/mold` as well as a symbolic-link in...
|
||||||
|
# - `{PREFIX}/lib/mold/ld`.
|
||||||
|
# (where `PREFIX` is typically `/usr/`).
|
||||||
|
#
|
||||||
|
# This block of code finds `{PREFIX}/lib/mold` from the `mold` binary.
|
||||||
|
# Other methods of searching for the path could also be made to work,
|
||||||
|
# we could even make our own directory and symbolic-link, however it's more
|
||||||
|
# convenient to use the one provided by mold.
|
||||||
|
#
|
||||||
|
# Use the binary path to "mold", to find the common prefix which contains "lib/mold".
|
||||||
|
# The parent directory: e.g. `/usr/bin/mold` -> `/usr/bin/`.
|
||||||
|
get_filename_component(MOLD_PREFIX "${MOLD_BIN}" DIRECTORY)
|
||||||
|
# The common prefix path: e.g. `/usr/bin/` -> `/usr/` to use as a hint.
|
||||||
|
get_filename_component(MOLD_PREFIX "${MOLD_PREFIX}" DIRECTORY)
|
||||||
|
# Find `{PREFIX}/lib/mold/ld`, store the directory component (without the `ld`).
|
||||||
|
# Then pass `-B {PREFIX}/lib/mold` to GCC so the `ld` located there overrides the default.
|
||||||
|
find_path(
|
||||||
|
MOLD_BIN_DIR "ld"
|
||||||
|
HINTS "${MOLD_PREFIX}"
|
||||||
|
# The default path is `libexec`, Arch Linux for e.g.
|
||||||
|
# replaces this with `lib` so check both.
|
||||||
|
PATH_SUFFIXES "libexec/mold" "lib/mold" "lib64/mold"
|
||||||
|
NO_DEFAULT_PATH
|
||||||
|
NO_CACHE
|
||||||
|
)
|
||||||
|
if(NOT MOLD_BIN_DIR)
|
||||||
|
message(STATUS
|
||||||
|
"The mold linker could not find the directory containing the linker command "
|
||||||
|
"(typically "
|
||||||
|
"\"${MOLD_PREFIX}/libexec/mold/ld\") or "
|
||||||
|
"\"${MOLD_PREFIX}/lib/mold/ld\") using system linker.")
|
||||||
|
set(WITH_LINKER_MOLD OFF)
|
||||||
|
endif()
|
||||||
|
unset(MOLD_PREFIX)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(WITH_LINKER_MOLD)
|
||||||
|
# GCC will search for `ld` in this directory first.
|
||||||
|
string(APPEND CMAKE_EXE_LINKER_FLAGS " -B \"${MOLD_BIN_DIR}\"")
|
||||||
|
string(APPEND CMAKE_SHARED_LINKER_FLAGS " -B \"${MOLD_BIN_DIR}\"")
|
||||||
|
string(APPEND CMAKE_MODULE_LINKER_FLAGS " -B \"${MOLD_BIN_DIR}\"")
|
||||||
|
set(_IS_LINKER_DEFAULT OFF)
|
||||||
|
endif()
|
||||||
|
unset(MOLD_BIN)
|
||||||
|
unset(MOLD_BIN_DIR)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(WITH_LINKER_GOLD AND _IS_LINKER_DEFAULT)
|
||||||
execute_process(
|
execute_process(
|
||||||
COMMAND ${CMAKE_C_COMPILER} -fuse-ld=gold -Wl,--version
|
COMMAND ${CMAKE_C_COMPILER} -fuse-ld=gold -Wl,--version
|
||||||
ERROR_QUIET OUTPUT_VARIABLE LD_VERSION)
|
ERROR_QUIET OUTPUT_VARIABLE LD_VERSION)
|
||||||
if("${LD_VERSION}" MATCHES "GNU gold")
|
if("${LD_VERSION}" MATCHES "GNU gold")
|
||||||
string(APPEND CMAKE_C_FLAGS " -fuse-ld=gold")
|
string(APPEND CMAKE_EXE_LINKER_FLAGS " -fuse-ld=gold")
|
||||||
string(APPEND CMAKE_CXX_FLAGS " -fuse-ld=gold")
|
string(APPEND CMAKE_SHARED_LINKER_FLAGS " -fuse-ld=gold")
|
||||||
|
string(APPEND CMAKE_MODULE_LINKER_FLAGS " -fuse-ld=gold")
|
||||||
|
set(_IS_LINKER_DEFAULT OFF)
|
||||||
else()
|
else()
|
||||||
message(STATUS "GNU gold linker isn't available, using the default system linker.")
|
message(STATUS "GNU gold linker isn't available, using the default system linker.")
|
||||||
endif()
|
endif()
|
||||||
unset(LD_VERSION)
|
unset(LD_VERSION)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WITH_LINKER_LLD)
|
if(WITH_LINKER_LLD AND _IS_LINKER_DEFAULT)
|
||||||
execute_process(
|
execute_process(
|
||||||
COMMAND ${CMAKE_C_COMPILER} -fuse-ld=lld -Wl,--version
|
COMMAND ${CMAKE_C_COMPILER} -fuse-ld=lld -Wl,--version
|
||||||
ERROR_QUIET OUTPUT_VARIABLE LD_VERSION)
|
ERROR_QUIET OUTPUT_VARIABLE LD_VERSION)
|
||||||
if("${LD_VERSION}" MATCHES "LLD")
|
if("${LD_VERSION}" MATCHES "LLD")
|
||||||
string(APPEND CMAKE_C_FLAGS " -fuse-ld=lld")
|
string(APPEND CMAKE_EXE_LINKER_FLAGS " -fuse-ld=lld")
|
||||||
string(APPEND CMAKE_CXX_FLAGS " -fuse-ld=lld")
|
string(APPEND CMAKE_SHARED_LINKER_FLAGS " -fuse-ld=lld")
|
||||||
|
string(APPEND CMAKE_MODULE_LINKER_FLAGS " -fuse-ld=lld")
|
||||||
|
set(_IS_LINKER_DEFAULT OFF)
|
||||||
else()
|
else()
|
||||||
message(STATUS "LLD linker isn't available, using the default system linker.")
|
message(STATUS "LLD linker isn't available, using the default system linker.")
|
||||||
endif()
|
endif()
|
||||||
@@ -691,6 +794,28 @@ if(CMAKE_COMPILER_IS_GNUCC)
|
|||||||
# CLang is the same as GCC for now.
|
# CLang is the same as GCC for now.
|
||||||
elseif(CMAKE_C_COMPILER_ID MATCHES "Clang")
|
elseif(CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||||
set(PLATFORM_CFLAGS "-pipe -fPIC -funsigned-char -fno-strict-aliasing")
|
set(PLATFORM_CFLAGS "-pipe -fPIC -funsigned-char -fno-strict-aliasing")
|
||||||
|
|
||||||
|
if(WITH_LINKER_MOLD AND _IS_LINKER_DEFAULT)
|
||||||
|
find_program(MOLD_BIN "mold")
|
||||||
|
mark_as_advanced(MOLD_BIN)
|
||||||
|
if(NOT MOLD_BIN)
|
||||||
|
message(STATUS "The \"mold\" binary could not be found, using system linker.")
|
||||||
|
set(WITH_LINKER_MOLD OFF)
|
||||||
|
else()
|
||||||
|
if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 12.0)
|
||||||
|
string(APPEND CMAKE_EXE_LINKER_FLAGS " --ld-path=\"${MOLD_BIN}\"")
|
||||||
|
string(APPEND CMAKE_SHARED_LINKER_FLAGS " --ld-path=\"${MOLD_BIN}\"")
|
||||||
|
string(APPEND CMAKE_MODULE_LINKER_FLAGS " --ld-path=\"${MOLD_BIN}\"")
|
||||||
|
else()
|
||||||
|
string(APPEND CMAKE_EXE_LINKER_FLAGS " -fuse-ld=\"${MOLD_BIN}\"")
|
||||||
|
string(APPEND CMAKE_SHARED_LINKER_FLAGS " -fuse-ld=\"${MOLD_BIN}\"")
|
||||||
|
string(APPEND CMAKE_MODULE_LINKER_FLAGS " -fuse-ld=\"${MOLD_BIN}\"")
|
||||||
|
endif()
|
||||||
|
set(_IS_LINKER_DEFAULT OFF)
|
||||||
|
endif()
|
||||||
|
unset(MOLD_BIN)
|
||||||
|
endif()
|
||||||
|
|
||||||
# Intel C++ Compiler
|
# Intel C++ Compiler
|
||||||
elseif(CMAKE_C_COMPILER_ID MATCHES "Intel")
|
elseif(CMAKE_C_COMPILER_ID MATCHES "Intel")
|
||||||
# think these next two are broken
|
# think these next two are broken
|
||||||
@@ -714,6 +839,8 @@ elseif(CMAKE_C_COMPILER_ID MATCHES "Intel")
|
|||||||
string(APPEND PLATFORM_LINKFLAGS " -static-intel")
|
string(APPEND PLATFORM_LINKFLAGS " -static-intel")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
unset(_IS_LINKER_DEFAULT)
|
||||||
|
|
||||||
# Avoid conflicts with Mesa llvmpipe, Luxrender, and other plug-ins that may
|
# Avoid conflicts with Mesa llvmpipe, Luxrender, and other plug-ins that may
|
||||||
# use the same libraries as Blender with a different version or build options.
|
# use the same libraries as Blender with a different version or build options.
|
||||||
set(PLATFORM_LINKFLAGS
|
set(PLATFORM_LINKFLAGS
|
||||||
|
@@ -347,7 +347,11 @@ set(FREETYPE_INCLUDE_DIRS
|
|||||||
${LIBDIR}/freetype/include
|
${LIBDIR}/freetype/include
|
||||||
${LIBDIR}/freetype/include/freetype2
|
${LIBDIR}/freetype/include/freetype2
|
||||||
)
|
)
|
||||||
set(FREETYPE_LIBRARY ${LIBDIR}/freetype/lib/freetype2ST.lib)
|
set(FREETYPE_LIBRARIES
|
||||||
|
${LIBDIR}/freetype/lib/freetype2ST.lib
|
||||||
|
${LIBDIR}/brotli/lib/brotlidec-static.lib
|
||||||
|
${LIBDIR}/brotli/lib/brotlicommon-static.lib
|
||||||
|
)
|
||||||
windows_find_package(freetype REQUIRED)
|
windows_find_package(freetype REQUIRED)
|
||||||
|
|
||||||
if(WITH_FFTW3)
|
if(WITH_FFTW3)
|
||||||
|
@@ -3,7 +3,32 @@ for %%X in (svn.exe) do (set SVN=%%~$PATH:X)
|
|||||||
for %%X in (cmake.exe) do (set CMAKE=%%~$PATH:X)
|
for %%X in (cmake.exe) do (set CMAKE=%%~$PATH:X)
|
||||||
for %%X in (ctest.exe) do (set CTEST=%%~$PATH:X)
|
for %%X in (ctest.exe) do (set CTEST=%%~$PATH:X)
|
||||||
for %%X in (git.exe) do (set GIT=%%~$PATH:X)
|
for %%X in (git.exe) do (set GIT=%%~$PATH:X)
|
||||||
|
REM For python, default on 39 but if that does not exist also check
|
||||||
|
REM the 310,311 and 312 folders to see if those are there, it checks
|
||||||
|
REM this far ahead to ensure good lib folder compatiblity in the future.
|
||||||
set PYTHON=%BLENDER_DIR%\..\lib\win64_vc15\python\39\bin\python.exe
|
set PYTHON=%BLENDER_DIR%\..\lib\win64_vc15\python\39\bin\python.exe
|
||||||
|
if EXIST %PYTHON% (
|
||||||
|
goto detect_python_done
|
||||||
|
)
|
||||||
|
set PYTHON=%BLENDER_DIR%\..\lib\win64_vc15\python\310\bin\python.exe
|
||||||
|
if EXIST %PYTHON% (
|
||||||
|
goto detect_python_done
|
||||||
|
)
|
||||||
|
set PYTHON=%BLENDER_DIR%\..\lib\win64_vc15\python\311\bin\python.exe
|
||||||
|
if EXIST %PYTHON% (
|
||||||
|
goto detect_python_done
|
||||||
|
)
|
||||||
|
set PYTHON=%BLENDER_DIR%\..\lib\win64_vc15\python\312\bin\python.exe
|
||||||
|
if EXIST %PYTHON% (
|
||||||
|
goto detect_python_done
|
||||||
|
)
|
||||||
|
|
||||||
|
if NOT EXIST %PYTHON% (
|
||||||
|
echo Warning: Python not found, there is likely an issue with the library folder
|
||||||
|
set PYTHON=""
|
||||||
|
)
|
||||||
|
|
||||||
|
:detect_python_done
|
||||||
if NOT "%verbose%" == "" (
|
if NOT "%verbose%" == "" (
|
||||||
echo svn : "%SVN%"
|
echo svn : "%SVN%"
|
||||||
echo cmake : "%CMAKE%"
|
echo cmake : "%CMAKE%"
|
||||||
@@ -11,7 +36,3 @@ if NOT "%verbose%" == "" (
|
|||||||
echo git : "%GIT%"
|
echo git : "%GIT%"
|
||||||
echo python : "%PYTHON%"
|
echo python : "%PYTHON%"
|
||||||
)
|
)
|
||||||
if "%CMAKE%" == "" (
|
|
||||||
echo Cmake not found in path, required for building, exiting...
|
|
||||||
exit /b 1
|
|
||||||
)
|
|
||||||
|
@@ -9,17 +9,11 @@ exit /b 1
|
|||||||
:detect_done
|
:detect_done
|
||||||
echo found clang-format in %CF_PATH%
|
echo found clang-format in %CF_PATH%
|
||||||
|
|
||||||
if EXIST %PYTHON% (
|
if NOT EXIST %PYTHON% (
|
||||||
set PYTHON=%BLENDER_DIR%\..\lib\win64_vc15\python\39\bin\python.exe
|
echo python not found, required for this operation
|
||||||
goto detect_python_done
|
exit /b 1
|
||||||
)
|
)
|
||||||
|
|
||||||
echo python not found in lib folder
|
|
||||||
exit /b 1
|
|
||||||
|
|
||||||
:detect_python_done
|
|
||||||
echo found python (%PYTHON%)
|
|
||||||
|
|
||||||
set FORMAT_PATHS=%BLENDER_DIR%\source\tools\utils_maintenance\clang_format_paths.py
|
set FORMAT_PATHS=%BLENDER_DIR%\source\tools\utils_maintenance\clang_format_paths.py
|
||||||
|
|
||||||
REM The formatting script expects clang-format to be in the current PATH.
|
REM The formatting script expects clang-format to be in the current PATH.
|
||||||
|
@@ -1,18 +1,8 @@
|
|||||||
if EXIST "%PYTHON%" (
|
if NOT EXIST %PYTHON% (
|
||||||
goto detect_python_done
|
echo python not found, required for this operation
|
||||||
|
exit /b 1
|
||||||
)
|
)
|
||||||
|
|
||||||
set PYTHON=%BLENDER_DIR%\..\lib\win64_vc15\python\39\bin\python.exe
|
|
||||||
if EXIST %PYTHON% (
|
|
||||||
goto detect_python_done
|
|
||||||
)
|
|
||||||
|
|
||||||
echo python not found at %PYTHON%
|
|
||||||
exit /b 1
|
|
||||||
|
|
||||||
:detect_python_done
|
|
||||||
echo found python (%PYTHON%)
|
|
||||||
|
|
||||||
call "%~dp0\find_inkscape.cmd"
|
call "%~dp0\find_inkscape.cmd"
|
||||||
|
|
||||||
if EXIST "%INKSCAPE_BIN%" (
|
if EXIST "%INKSCAPE_BIN%" (
|
||||||
|
@@ -1,18 +1,8 @@
|
|||||||
if EXIST %PYTHON% (
|
if NOT EXIST %PYTHON% (
|
||||||
goto detect_python_done
|
echo python not found, required for this operation
|
||||||
|
exit /b 1
|
||||||
)
|
)
|
||||||
|
|
||||||
set PYTHON=%BLENDER_DIR%\..\lib\win64_vc15\python\39\bin\python.exe
|
|
||||||
if EXIST %PYTHON% (
|
|
||||||
goto detect_python_done
|
|
||||||
)
|
|
||||||
|
|
||||||
echo python not found at %PYTHON%
|
|
||||||
exit /b 1
|
|
||||||
|
|
||||||
:detect_python_done
|
|
||||||
echo found python (%PYTHON%)
|
|
||||||
|
|
||||||
call "%~dp0\find_blender.cmd"
|
call "%~dp0\find_blender.cmd"
|
||||||
|
|
||||||
if EXIST "%BLENDER_BIN%" (
|
if EXIST "%BLENDER_BIN%" (
|
||||||
|
@@ -1,10 +1,7 @@
|
|||||||
if EXIST %PYTHON% (
|
if NOT EXIST %PYTHON% (
|
||||||
goto detect_python_done
|
echo python not found, required for this operation
|
||||||
|
exit /b 1
|
||||||
)
|
)
|
||||||
|
|
||||||
echo python not found in lib folder
|
|
||||||
exit /b 1
|
|
||||||
|
|
||||||
:detect_python_done
|
:detect_python_done
|
||||||
|
|
||||||
REM Use -B to avoid writing __pycache__ in lib directory and causing update conflicts.
|
REM Use -B to avoid writing __pycache__ in lib directory and causing update conflicts.
|
||||||
|
@@ -8,27 +8,42 @@ def set_pose_matrices(obj, matrix_map):
|
|||||||
"Assign pose space matrices of all bones at once, ignoring constraints."
|
"Assign pose space matrices of all bones at once, ignoring constraints."
|
||||||
|
|
||||||
def rec(pbone, parent_matrix):
|
def rec(pbone, parent_matrix):
|
||||||
matrix = matrix_map[pbone.name]
|
if pbone.name in matrix_map:
|
||||||
|
matrix = matrix_map[pbone.name]
|
||||||
|
|
||||||
## Instead of:
|
## Instead of:
|
||||||
# pbone.matrix = matrix
|
# pbone.matrix = matrix
|
||||||
# bpy.context.view_layer.update()
|
# bpy.context.view_layer.update()
|
||||||
|
|
||||||
# Compute and assign local matrix, using the new parent matrix
|
# Compute and assign local matrix, using the new parent matrix
|
||||||
if pbone.parent:
|
if pbone.parent:
|
||||||
pbone.matrix_basis = pbone.bone.convert_local_to_pose(
|
pbone.matrix_basis = pbone.bone.convert_local_to_pose(
|
||||||
matrix,
|
matrix,
|
||||||
pbone.bone.matrix_local,
|
pbone.bone.matrix_local,
|
||||||
parent_matrix=parent_matrix,
|
parent_matrix=parent_matrix,
|
||||||
parent_matrix_local=pbone.parent.bone.matrix_local,
|
parent_matrix_local=pbone.parent.bone.matrix_local,
|
||||||
invert=True
|
invert=True
|
||||||
)
|
)
|
||||||
|
else:
|
||||||
|
pbone.matrix_basis = pbone.bone.convert_local_to_pose(
|
||||||
|
matrix,
|
||||||
|
pbone.bone.matrix_local,
|
||||||
|
invert=True
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
pbone.matrix_basis = pbone.bone.convert_local_to_pose(
|
# Compute the updated pose matrix from local and new parent matrix
|
||||||
matrix,
|
if pbone.parent:
|
||||||
pbone.bone.matrix_local,
|
matrix = pbone.bone.convert_local_to_pose(
|
||||||
invert=True
|
pbone.matrix_basis,
|
||||||
)
|
pbone.bone.matrix_local,
|
||||||
|
parent_matrix=parent_matrix,
|
||||||
|
parent_matrix_local=pbone.parent.bone.matrix_local,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
matrix = pbone.bone.convert_local_to_pose(
|
||||||
|
pbone.matrix_basis,
|
||||||
|
pbone.bone.matrix_local,
|
||||||
|
)
|
||||||
|
|
||||||
# Recursively process children, passing the new matrix through
|
# Recursively process children, passing the new matrix through
|
||||||
for child in pbone.children:
|
for child in pbone.children:
|
||||||
|
@@ -743,7 +743,7 @@ will re-allocate objects data,
|
|||||||
any references to a meshes vertices/polygons/UVs, armatures bones,
|
any references to a meshes vertices/polygons/UVs, armatures bones,
|
||||||
curves points, etc. cannot be accessed after switching mode.
|
curves points, etc. cannot be accessed after switching mode.
|
||||||
|
|
||||||
Only the reference to the data its self can be re-accessed, the following example will crash.
|
Only the reference to the data itself can be re-accessed, the following example will crash.
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
|
@@ -1762,6 +1762,7 @@ except ModuleNotFoundError:
|
|||||||
fw("html_show_sphinx = False\n")
|
fw("html_show_sphinx = False\n")
|
||||||
fw("html_baseurl = 'https://docs.blender.org/api/current/'\n")
|
fw("html_baseurl = 'https://docs.blender.org/api/current/'\n")
|
||||||
fw("html_use_opensearch = 'https://docs.blender.org/api/current'\n")
|
fw("html_use_opensearch = 'https://docs.blender.org/api/current'\n")
|
||||||
|
fw("html_show_search_summary = True\n")
|
||||||
fw("html_split_index = True\n")
|
fw("html_split_index = True\n")
|
||||||
fw("html_static_path = ['static']\n")
|
fw("html_static_path = ['static']\n")
|
||||||
fw("html_extra_path = ['static/favicon.ico', 'static/blender_logo.svg']\n")
|
fw("html_extra_path = ['static/favicon.ico', 'static/blender_logo.svg']\n")
|
||||||
|
6
extern/audaspace/CMakeLists.txt
vendored
6
extern/audaspace/CMakeLists.txt
vendored
@@ -1092,12 +1092,12 @@ if(WITH_PYTHON)
|
|||||||
configure_file(${PYTHON_SOURCE_DIRECTORY}/setup.py.in ${CMAKE_CURRENT_BINARY_DIR}/setup.py ESCAPE_QUOTES @ONLY)
|
configure_file(${PYTHON_SOURCE_DIRECTORY}/setup.py.in ${CMAKE_CURRENT_BINARY_DIR}/setup.py ESCAPE_QUOTES @ONLY)
|
||||||
|
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
add_custom_command(OUTPUT build COMMAND MACOSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET} ${PYTHON_EXECUTABLE} setup.py build DEPENDS ${PYTHON_SRC} ${PYTHON_HDR})
|
add_custom_command(OUTPUT build COMMAND MACOSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET} ${PYTHON_EXECUTABLE} setup.py build DEPENDS ${PYTHON_SRC} ${PYTHON_HDR} setup.py)
|
||||||
elseif(WIN32)
|
elseif(WIN32)
|
||||||
set(ENV{VS100COMNTOOLS} $ENV{VS120COMNTOOLS})
|
set(ENV{VS100COMNTOOLS} $ENV{VS120COMNTOOLS})
|
||||||
add_custom_command(OUTPUT build COMMAND ${PYTHON_EXECUTABLE} setup.py build DEPENDS ${PYTHON_SRC} ${PYTHON_HDR})
|
add_custom_command(OUTPUT build COMMAND ${PYTHON_EXECUTABLE} setup.py build DEPENDS ${PYTHON_SRC} ${PYTHON_HDR} setup.py)
|
||||||
else()
|
else()
|
||||||
add_custom_command(OUTPUT build COMMAND ${PYTHON_EXECUTABLE} setup.py build DEPENDS ${PYTHON_SRC} ${PYTHON_HDR})
|
add_custom_command(OUTPUT build COMMAND ${PYTHON_EXECUTABLE} setup.py build DEPENDS ${PYTHON_SRC} ${PYTHON_HDR} setup.py)
|
||||||
endif()
|
endif()
|
||||||
add_custom_target(pythonmodule ALL DEPENDS build SOURCES ${PYTHON_SOURCE_DIRECTORY}/setup.py.in ${PYTHON_SRC} ${PYTHON_HDR})
|
add_custom_target(pythonmodule ALL DEPENDS build SOURCES ${PYTHON_SOURCE_DIRECTORY}/setup.py.in ${PYTHON_SRC} ${PYTHON_HDR})
|
||||||
add_dependencies(pythonmodule audaspace)
|
add_dependencies(pythonmodule audaspace)
|
||||||
|
27
extern/audaspace/bindings/python/setup.py.in
vendored
27
extern/audaspace/bindings/python/setup.py.in
vendored
@@ -8,20 +8,20 @@ import numpy
|
|||||||
from distutils.core import setup, Extension
|
from distutils.core import setup, Extension
|
||||||
|
|
||||||
if len(sys.argv) > 2 and sys.argv[1] == '--build-docs':
|
if len(sys.argv) > 2 and sys.argv[1] == '--build-docs':
|
||||||
import subprocess
|
import subprocess
|
||||||
from distutils.core import Distribution
|
from distutils.core import Distribution
|
||||||
from distutils.command.build import build
|
from distutils.command.build import build
|
||||||
|
|
||||||
dist = Distribution()
|
dist = Distribution()
|
||||||
cmd = build(dist)
|
cmd = build(dist)
|
||||||
cmd.finalize_options()
|
cmd.finalize_options()
|
||||||
#print(cmd.build_platlib)
|
#print(cmd.build_platlib)
|
||||||
|
|
||||||
os.environ['PYTHONPATH'] = os.path.join(os.getcwd(), cmd.build_platlib)
|
os.environ['PYTHONPATH'] = os.path.join(os.getcwd(), cmd.build_platlib)
|
||||||
os.environ['LD_LIBRARY_PATH'] = os.getcwd()
|
os.environ['LD_LIBRARY_PATH'] = os.getcwd()
|
||||||
|
|
||||||
ret = subprocess.call(sys.argv[2:])
|
ret = subprocess.call(sys.argv[2:])
|
||||||
sys.exit(ret)
|
sys.exit(ret)
|
||||||
|
|
||||||
|
|
||||||
# the following line is not working due to https://bugs.python.org/issue9023
|
# the following line is not working due to https://bugs.python.org/issue9023
|
||||||
@@ -43,7 +43,8 @@ audaspace = Extension(
|
|||||||
library_dirs = ['.', 'Release', 'Debug'],
|
library_dirs = ['.', 'Release', 'Debug'],
|
||||||
language = 'c++',
|
language = 'c++',
|
||||||
extra_compile_args = extra_args,
|
extra_compile_args = extra_args,
|
||||||
sources = [os.path.join(source_directory, file) for file in ['PyAPI.cpp', 'PyDevice.cpp', 'PyHandle.cpp', 'PySound.cpp', 'PySequenceEntry.cpp', 'PySequence.cpp', 'PyPlaybackManager.cpp', 'PyDynamicMusic.cpp', 'PyThreadPool.cpp', 'PySource.cpp'] + (['PyImpulseResponse.cpp', 'PyHRTF.cpp'] if '@WITH_FFTW@' == 'ON' else [])]
|
define_macros = [('WITH_CONVOLUTION', None)] if '@WITH_FFTW@' == 'ON' else [],
|
||||||
|
sources = [os.path.join(source_directory, file) for file in ['PyAPI.cpp', 'PyDevice.cpp', 'PyHandle.cpp', 'PySound.cpp', 'PySequenceEntry.cpp', 'PySequence.cpp', 'PyPlaybackManager.cpp', 'PyDynamicMusic.cpp', 'PyThreadPool.cpp', 'PySource.cpp'] + (['PyImpulseResponse.cpp', 'PyHRTF.cpp'] if '@WITH_FFTW@' == 'ON' else [])]
|
||||||
)
|
)
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
@@ -56,6 +57,6 @@ setup(
|
|||||||
license = 'Apache License 2.0',
|
license = 'Apache License 2.0',
|
||||||
long_description = codecs.open(os.path.join(source_directory, '../../README.md'), 'r', 'utf-8').read(),
|
long_description = codecs.open(os.path.join(source_directory, '../../README.md'), 'r', 'utf-8').read(),
|
||||||
ext_modules = [audaspace],
|
ext_modules = [audaspace],
|
||||||
headers = [os.path.join(source_directory, file) for file in ['PyAPI.h', 'PyDevice.h', 'PyHandle.h', 'PySound.h', 'PySequenceEntry.h', 'PySequence.h', 'PyPlaybackManager.h', 'PyDynamicMusic.h', 'PyThreadPool.h', 'PySource.h'] + (['PyImpulseResponse.h', 'PyHRTF.h'] if '@WITH_FFTW@' == 'ON' else [])] + ['Audaspace.h']
|
headers = [os.path.join(source_directory, file) for file in ['PyAPI.h', 'PyDevice.h', 'PyHandle.h', 'PySound.h', 'PySequenceEntry.h', 'PySequence.h', 'PyPlaybackManager.h', 'PyDynamicMusic.h', 'PyThreadPool.h', 'PySource.h'] + (['PyImpulseResponse.h', 'PyHRTF.h'] if '@WITH_FFTW@' == 'ON' else [])] + ['Audaspace.h']
|
||||||
)
|
)
|
||||||
|
|
||||||
|
80
extern/audaspace/plugins/wasapi/WASAPIDevice.cpp
vendored
80
extern/audaspace/plugins/wasapi/WASAPIDevice.cpp
vendored
@@ -95,6 +95,13 @@ void WASAPIDevice::runMixingThread()
|
|||||||
sleep_duration = std::chrono::milliseconds(buffer_size * 1000 / int(m_specs.rate) / 2);
|
sleep_duration = std::chrono::milliseconds(buffer_size * 1000 / int(m_specs.rate) / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(m_default_device_changed)
|
||||||
|
{
|
||||||
|
m_default_device_changed = false;
|
||||||
|
result = AUDCLNT_E_DEVICE_INVALIDATED;
|
||||||
|
goto stop_thread;
|
||||||
|
}
|
||||||
|
|
||||||
if(FAILED(result = m_audio_client->GetCurrentPadding(&padding)))
|
if(FAILED(result = m_audio_client->GetCurrentPadding(&padding)))
|
||||||
goto stop_thread;
|
goto stop_thread;
|
||||||
|
|
||||||
@@ -296,13 +303,78 @@ bool WASAPIDevice::setupDevice(DeviceSpecs &specs)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ULONG WASAPIDevice::AddRef()
|
||||||
|
{
|
||||||
|
return InterlockedIncrement(&m_reference_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
ULONG WASAPIDevice::Release()
|
||||||
|
{
|
||||||
|
ULONG reference_count = InterlockedDecrement(&m_reference_count);
|
||||||
|
|
||||||
|
if(0 == reference_count)
|
||||||
|
delete this;
|
||||||
|
|
||||||
|
return reference_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT WASAPIDevice::QueryInterface(REFIID riid, void **ppvObject)
|
||||||
|
{
|
||||||
|
if(riid == __uuidof(IMMNotificationClient))
|
||||||
|
{
|
||||||
|
*ppvObject = reinterpret_cast<IMMNotificationClient*>(this);
|
||||||
|
AddRef();
|
||||||
|
}
|
||||||
|
else if(riid == IID_IUnknown)
|
||||||
|
{
|
||||||
|
*ppvObject = reinterpret_cast<IUnknown*>(this);
|
||||||
|
AddRef();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*ppvObject = nullptr;
|
||||||
|
return E_NOINTERFACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT WASAPIDevice::OnDeviceStateChanged(LPCWSTR pwstrDeviceId, DWORD dwNewState)
|
||||||
|
{
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT WASAPIDevice::OnDeviceAdded(LPCWSTR pwstrDeviceId)
|
||||||
|
{
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT WASAPIDevice::OnDeviceRemoved(LPCWSTR pwstrDeviceId)
|
||||||
|
{
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT WASAPIDevice::OnDefaultDeviceChanged(EDataFlow flow, ERole role, LPCWSTR pwstrDeviceId)
|
||||||
|
{
|
||||||
|
if(flow != EDataFlow::eCapture)
|
||||||
|
m_default_device_changed = true;
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT WASAPIDevice::OnPropertyValueChanged(LPCWSTR pwstrDeviceId, const PROPERTYKEY key)
|
||||||
|
{
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
WASAPIDevice::WASAPIDevice(DeviceSpecs specs, int buffersize) :
|
WASAPIDevice::WASAPIDevice(DeviceSpecs specs, int buffersize) :
|
||||||
m_buffersize(buffersize),
|
m_buffersize(buffersize),
|
||||||
m_imm_device_enumerator(nullptr),
|
m_imm_device_enumerator(nullptr),
|
||||||
m_imm_device(nullptr),
|
m_imm_device(nullptr),
|
||||||
m_audio_client(nullptr),
|
m_audio_client(nullptr),
|
||||||
|
m_wave_format_extensible({}),
|
||||||
m_wave_format_extensible({})
|
m_default_device_changed(false),
|
||||||
|
m_reference_count(1)
|
||||||
{
|
{
|
||||||
// initialize COM if it hasn't happened yet
|
// initialize COM if it hasn't happened yet
|
||||||
CoInitializeEx(nullptr, COINIT_MULTITHREADED);
|
CoInitializeEx(nullptr, COINIT_MULTITHREADED);
|
||||||
@@ -327,6 +399,8 @@ WASAPIDevice::WASAPIDevice(DeviceSpecs specs, int buffersize) :
|
|||||||
|
|
||||||
create();
|
create();
|
||||||
|
|
||||||
|
m_imm_device_enumerator->RegisterEndpointNotificationCallback(this);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
@@ -340,6 +414,8 @@ WASAPIDevice::~WASAPIDevice()
|
|||||||
{
|
{
|
||||||
stopMixingThread();
|
stopMixingThread();
|
||||||
|
|
||||||
|
m_imm_device_enumerator->UnregisterEndpointNotificationCallback(this);
|
||||||
|
|
||||||
SafeRelease(&m_audio_client);
|
SafeRelease(&m_audio_client);
|
||||||
SafeRelease(&m_imm_device);
|
SafeRelease(&m_imm_device);
|
||||||
SafeRelease(&m_imm_device_enumerator);
|
SafeRelease(&m_imm_device_enumerator);
|
||||||
|
15
extern/audaspace/plugins/wasapi/WASAPIDevice.h
vendored
15
extern/audaspace/plugins/wasapi/WASAPIDevice.h
vendored
@@ -40,7 +40,7 @@ AUD_NAMESPACE_BEGIN
|
|||||||
/**
|
/**
|
||||||
* This device plays back through WASAPI, the Windows audio API.
|
* This device plays back through WASAPI, the Windows audio API.
|
||||||
*/
|
*/
|
||||||
class AUD_PLUGIN_API WASAPIDevice : public ThreadedDevice
|
class AUD_PLUGIN_API WASAPIDevice : IMMNotificationClient, public ThreadedDevice
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
int m_buffersize;
|
int m_buffersize;
|
||||||
@@ -48,6 +48,8 @@ private:
|
|||||||
IMMDevice* m_imm_device;
|
IMMDevice* m_imm_device;
|
||||||
IAudioClient* m_audio_client;
|
IAudioClient* m_audio_client;
|
||||||
WAVEFORMATEXTENSIBLE m_wave_format_extensible;
|
WAVEFORMATEXTENSIBLE m_wave_format_extensible;
|
||||||
|
bool m_default_device_changed;
|
||||||
|
LONG m_reference_count;
|
||||||
|
|
||||||
AUD_LOCAL HRESULT setupRenderClient(IAudioRenderClient*& render_client, UINT32& buffer_size);
|
AUD_LOCAL HRESULT setupRenderClient(IAudioRenderClient*& render_client, UINT32& buffer_size);
|
||||||
|
|
||||||
@@ -58,6 +60,17 @@ private:
|
|||||||
|
|
||||||
AUD_LOCAL bool setupDevice(DeviceSpecs& specs);
|
AUD_LOCAL bool setupDevice(DeviceSpecs& specs);
|
||||||
|
|
||||||
|
// IUnknown implementation
|
||||||
|
ULONG STDMETHODCALLTYPE AddRef();
|
||||||
|
ULONG STDMETHODCALLTYPE Release();
|
||||||
|
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject);
|
||||||
|
// IMMNotificationClient implementation
|
||||||
|
HRESULT STDMETHODCALLTYPE OnDeviceStateChanged(LPCWSTR pwstrDeviceId, DWORD dwNewState);
|
||||||
|
HRESULT STDMETHODCALLTYPE OnDeviceAdded(LPCWSTR pwstrDeviceId);
|
||||||
|
HRESULT STDMETHODCALLTYPE OnDeviceRemoved(LPCWSTR pwstrDeviceId);
|
||||||
|
HRESULT STDMETHODCALLTYPE OnDefaultDeviceChanged(EDataFlow flow, ERole role, LPCWSTR pwstrDeviceId);
|
||||||
|
HRESULT STDMETHODCALLTYPE OnPropertyValueChanged(LPCWSTR pwstrDeviceId, const PROPERTYKEY key);
|
||||||
|
|
||||||
// delete copy constructor and operator=
|
// delete copy constructor and operator=
|
||||||
WASAPIDevice(const WASAPIDevice&) = delete;
|
WASAPIDevice(const WASAPIDevice&) = delete;
|
||||||
WASAPIDevice& operator=(const WASAPIDevice&) = delete;
|
WASAPIDevice& operator=(const WASAPIDevice&) = delete;
|
||||||
|
@@ -51,8 +51,6 @@ list(APPEND LIBRARIES ${CYCLES_GL_LIBRARIES})
|
|||||||
|
|
||||||
# Common configuration.
|
# Common configuration.
|
||||||
|
|
||||||
cycles_link_directories()
|
|
||||||
|
|
||||||
add_definitions(${GL_DEFINITIONS})
|
add_definitions(${GL_DEFINITIONS})
|
||||||
|
|
||||||
include_directories(${INC})
|
include_directories(${INC})
|
||||||
|
@@ -667,6 +667,11 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
|
|||||||
description="Use special type BVH optimized for hair (uses more ram but renders faster)",
|
description="Use special type BVH optimized for hair (uses more ram but renders faster)",
|
||||||
default=True,
|
default=True,
|
||||||
)
|
)
|
||||||
|
debug_use_compact_bvh: BoolProperty(
|
||||||
|
name="Use Compact BVH",
|
||||||
|
description="Use compact BVH structure (uses less ram but renders slower)",
|
||||||
|
default=True,
|
||||||
|
)
|
||||||
debug_bvh_time_steps: IntProperty(
|
debug_bvh_time_steps: IntProperty(
|
||||||
name="BVH Time Steps",
|
name="BVH Time Steps",
|
||||||
description="Split BVH primitives by this number of time steps to speed up render time in cost of memory",
|
description="Split BVH primitives by this number of time steps to speed up render time in cost of memory",
|
||||||
@@ -1447,6 +1452,19 @@ class CyclesPreferences(bpy.types.AddonPreferences):
|
|||||||
num += 1
|
num += 1
|
||||||
return num
|
return num
|
||||||
|
|
||||||
|
def has_multi_device(self):
|
||||||
|
import _cycles
|
||||||
|
compute_device_type = self.get_compute_device_type()
|
||||||
|
device_list = _cycles.available_devices(compute_device_type)
|
||||||
|
for device in device_list:
|
||||||
|
if device[1] == compute_device_type:
|
||||||
|
continue
|
||||||
|
for dev in self.devices:
|
||||||
|
if dev.use and dev.id == device[2]:
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
def has_active_device(self):
|
def has_active_device(self):
|
||||||
return self.get_num_gpu_devices() > 0
|
return self.get_num_gpu_devices() > 0
|
||||||
|
|
||||||
|
@@ -118,11 +118,11 @@ def use_optix(context):
|
|||||||
|
|
||||||
return (get_device_type(context) == 'OPTIX' and cscene.device == 'GPU')
|
return (get_device_type(context) == 'OPTIX' and cscene.device == 'GPU')
|
||||||
|
|
||||||
|
def use_multi_device(context):
|
||||||
def use_sample_all_lights(context):
|
|
||||||
cscene = context.scene.cycles
|
cscene = context.scene.cycles
|
||||||
|
if cscene.device != 'GPU':
|
||||||
return cscene.sample_all_lights_direct or cscene.sample_all_lights_indirect
|
return False
|
||||||
|
return context.preferences.addons[__package__].preferences.has_multi_device()
|
||||||
|
|
||||||
|
|
||||||
def show_device_active(context):
|
def show_device_active(context):
|
||||||
@@ -667,6 +667,10 @@ class CYCLES_RENDER_PT_performance_acceleration_structure(CyclesButtonsPanel, Pa
|
|||||||
bl_label = "Acceleration Structure"
|
bl_label = "Acceleration Structure"
|
||||||
bl_parent_id = "CYCLES_RENDER_PT_performance"
|
bl_parent_id = "CYCLES_RENDER_PT_performance"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def poll(cls, context):
|
||||||
|
return not use_optix(context) or has_multi_device(context)
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
import _cycles
|
import _cycles
|
||||||
|
|
||||||
@@ -679,21 +683,33 @@ class CYCLES_RENDER_PT_performance_acceleration_structure(CyclesButtonsPanel, Pa
|
|||||||
|
|
||||||
col = layout.column()
|
col = layout.column()
|
||||||
|
|
||||||
use_embree = False
|
use_embree = _cycles.with_embree
|
||||||
|
|
||||||
if use_cpu(context):
|
if use_cpu(context):
|
||||||
use_embree = _cycles.with_embree
|
col.prop(cscene, "debug_use_spatial_splits")
|
||||||
if not use_embree:
|
if use_embree:
|
||||||
|
col.prop(cscene, "debug_use_compact_bvh")
|
||||||
|
else:
|
||||||
|
sub = col.column()
|
||||||
|
sub.active = not cscene.debug_use_spatial_splits
|
||||||
|
sub.prop(cscene, "debug_bvh_time_steps")
|
||||||
|
|
||||||
|
col.prop(cscene, "debug_use_hair_bvh")
|
||||||
|
|
||||||
sub = col.column(align=True)
|
sub = col.column(align=True)
|
||||||
sub.label(text="Cycles built without Embree support")
|
sub.label(text="Cycles built without Embree support")
|
||||||
sub.label(text="CPU raytracing performance will be poor")
|
sub.label(text="CPU raytracing performance will be poor")
|
||||||
|
else:
|
||||||
|
col.prop(cscene, "debug_use_spatial_splits")
|
||||||
|
sub = col.column()
|
||||||
|
sub.active = not cscene.debug_use_spatial_splits
|
||||||
|
sub.prop(cscene, "debug_bvh_time_steps")
|
||||||
|
|
||||||
col.prop(cscene, "debug_use_spatial_splits")
|
col.prop(cscene, "debug_use_hair_bvh")
|
||||||
sub = col.column()
|
|
||||||
sub.active = not use_embree
|
# CPU is used in addition to a GPU
|
||||||
sub.prop(cscene, "debug_use_hair_bvh")
|
if use_multi_device(context) and use_embree:
|
||||||
sub = col.column()
|
col.prop(cscene, "debug_use_compact_bvh")
|
||||||
sub.active = not cscene.debug_use_spatial_splits and not use_embree
|
|
||||||
sub.prop(cscene, "debug_bvh_time_steps")
|
|
||||||
|
|
||||||
|
|
||||||
class CYCLES_RENDER_PT_performance_final_render(CyclesButtonsPanel, Panel):
|
class CYCLES_RENDER_PT_performance_final_render(CyclesButtonsPanel, Panel):
|
||||||
@@ -1803,18 +1819,45 @@ class CYCLES_RENDER_PT_bake_output(CyclesButtonsPanel, Panel):
|
|||||||
rd = scene.render
|
rd = scene.render
|
||||||
|
|
||||||
if rd.use_bake_multires:
|
if rd.use_bake_multires:
|
||||||
layout.prop(rd, "bake_margin")
|
|
||||||
layout.prop(rd, "use_bake_clear", text="Clear Image")
|
layout.prop(rd, "use_bake_clear", text="Clear Image")
|
||||||
|
|
||||||
if rd.bake_type == 'DISPLACEMENT':
|
if rd.bake_type == 'DISPLACEMENT':
|
||||||
layout.prop(rd, "use_bake_lores_mesh")
|
layout.prop(rd, "use_bake_lores_mesh")
|
||||||
else:
|
else:
|
||||||
layout.prop(cbk, "target")
|
layout.prop(cbk, "target")
|
||||||
|
|
||||||
if cbk.target == 'IMAGE_TEXTURES':
|
if cbk.target == 'IMAGE_TEXTURES':
|
||||||
layout.prop(cbk, "margin")
|
|
||||||
layout.prop(cbk, "use_clear", text="Clear Image")
|
layout.prop(cbk, "use_clear", text="Clear Image")
|
||||||
|
|
||||||
|
class CYCLES_RENDER_PT_bake_output_margin(CyclesButtonsPanel, Panel):
|
||||||
|
bl_label = "Margin"
|
||||||
|
bl_context = "render"
|
||||||
|
bl_parent_id = "CYCLES_RENDER_PT_bake_output"
|
||||||
|
COMPAT_ENGINES = {'CYCLES'}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def poll(cls, context):
|
||||||
|
scene = context.scene
|
||||||
|
cbk = scene.render.bake
|
||||||
|
return cbk.target == 'IMAGE_TEXTURES'
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
layout.use_property_split = True
|
||||||
|
layout.use_property_decorate = False # No animation.
|
||||||
|
|
||||||
|
scene = context.scene
|
||||||
|
cscene = scene.cycles
|
||||||
|
cbk = scene.render.bake
|
||||||
|
rd = scene.render
|
||||||
|
|
||||||
|
if rd.use_bake_multires:
|
||||||
|
layout.prop(rd, "bake_margin_type", text="Type")
|
||||||
|
layout.prop(rd, "bake_margin", text="Size")
|
||||||
|
else:
|
||||||
|
if cbk.target == 'IMAGE_TEXTURES':
|
||||||
|
layout.prop(cbk, "margin_type", text="Type")
|
||||||
|
layout.prop(cbk, "margin", text="Size")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class CYCLES_RENDER_PT_debug(CyclesDebugButtonsPanel, Panel):
|
class CYCLES_RENDER_PT_debug(CyclesDebugButtonsPanel, Panel):
|
||||||
bl_label = "Debug"
|
bl_label = "Debug"
|
||||||
@@ -2183,6 +2226,7 @@ classes = (
|
|||||||
CYCLES_RENDER_PT_bake_influence,
|
CYCLES_RENDER_PT_bake_influence,
|
||||||
CYCLES_RENDER_PT_bake_selected_to_active,
|
CYCLES_RENDER_PT_bake_selected_to_active,
|
||||||
CYCLES_RENDER_PT_bake_output,
|
CYCLES_RENDER_PT_bake_output,
|
||||||
|
CYCLES_RENDER_PT_bake_output_margin,
|
||||||
CYCLES_RENDER_PT_debug,
|
CYCLES_RENDER_PT_debug,
|
||||||
node_panel(CYCLES_MATERIAL_PT_settings),
|
node_panel(CYCLES_MATERIAL_PT_settings),
|
||||||
node_panel(CYCLES_MATERIAL_PT_settings_surface),
|
node_panel(CYCLES_MATERIAL_PT_settings_surface),
|
||||||
|
@@ -1071,7 +1071,15 @@ static void create_subd_mesh(Scene *scene,
|
|||||||
|
|
||||||
for (BL::MeshEdge &e : b_mesh.edges) {
|
for (BL::MeshEdge &e : b_mesh.edges) {
|
||||||
if (e.crease() != 0.0f) {
|
if (e.crease() != 0.0f) {
|
||||||
mesh->add_crease(e.vertices()[0], e.vertices()[1], e.crease());
|
mesh->add_edge_crease(e.vertices()[0], e.vertices()[1], e.crease());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (BL::MeshVertexCreaseLayer &c : b_mesh.vertex_creases) {
|
||||||
|
for (int i = 0; i < c.data.length(); ++i) {
|
||||||
|
if (c.data[i].value() != 0.0f) {
|
||||||
|
mesh->add_vertex_crease(i, c.data[i].value());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -529,6 +529,17 @@ void BlenderSync::sync_procedural(BL::Object &b_ob,
|
|||||||
string absolute_path = blender_absolute_path(b_data, b_ob, b_mesh_cache.cache_file().filepath());
|
string absolute_path = blender_absolute_path(b_data, b_ob, b_mesh_cache.cache_file().filepath());
|
||||||
procedural->set_filepath(ustring(absolute_path));
|
procedural->set_filepath(ustring(absolute_path));
|
||||||
|
|
||||||
|
array<ustring> layers;
|
||||||
|
for (BL::CacheFileLayer &layer : cache_file.layers) {
|
||||||
|
if (layer.hide_layer()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
absolute_path = blender_absolute_path(b_data, b_ob, layer.filepath());
|
||||||
|
layers.push_back_slow(ustring(absolute_path));
|
||||||
|
}
|
||||||
|
procedural->set_layers(layers);
|
||||||
|
|
||||||
procedural->set_scale(cache_file.scale());
|
procedural->set_scale(cache_file.scale());
|
||||||
|
|
||||||
procedural->set_use_prefetch(cache_file.use_prefetch());
|
procedural->set_use_prefetch(cache_file.use_prefetch());
|
||||||
|
@@ -51,8 +51,6 @@ bool BlenderOutputDriver::read_render_tile(const Tile &tile)
|
|||||||
|
|
||||||
BL::RenderLayer b_rlay = *b_single_rlay;
|
BL::RenderLayer b_rlay = *b_single_rlay;
|
||||||
|
|
||||||
vector<float> pixels(tile.size.x * tile.size.y * 4);
|
|
||||||
|
|
||||||
/* Copy each pass.
|
/* Copy each pass.
|
||||||
* TODO:copy only the required ones for better performance? */
|
* TODO:copy only the required ones for better performance? */
|
||||||
for (BL::RenderPass &b_pass : b_rlay.passes) {
|
for (BL::RenderPass &b_pass : b_rlay.passes) {
|
||||||
@@ -109,7 +107,7 @@ void BlenderOutputDriver::write_render_tile(const Tile &tile)
|
|||||||
|
|
||||||
BL::RenderLayer b_rlay = *b_single_rlay;
|
BL::RenderLayer b_rlay = *b_single_rlay;
|
||||||
|
|
||||||
vector<float> pixels(tile.size.x * tile.size.y * 4);
|
vector<float> pixels(static_cast<size_t>(tile.size.x) * tile.size.y * 4);
|
||||||
|
|
||||||
/* Copy each pass. */
|
/* Copy each pass. */
|
||||||
for (BL::RenderPass &b_pass : b_rlay.passes) {
|
for (BL::RenderPass &b_pass : b_rlay.passes) {
|
||||||
|
@@ -689,6 +689,9 @@ static ShaderNode *add_node(Scene *scene,
|
|||||||
else if (b_node.is_a(&RNA_ShaderNodeHairInfo)) {
|
else if (b_node.is_a(&RNA_ShaderNodeHairInfo)) {
|
||||||
node = graph->create_node<HairInfoNode>();
|
node = graph->create_node<HairInfoNode>();
|
||||||
}
|
}
|
||||||
|
else if (b_node.is_a(&RNA_ShaderNodePointInfo)) {
|
||||||
|
node = graph->create_node<PointInfoNode>();
|
||||||
|
}
|
||||||
else if (b_node.is_a(&RNA_ShaderNodeVolumeInfo)) {
|
else if (b_node.is_a(&RNA_ShaderNodeVolumeInfo)) {
|
||||||
node = graph->create_node<VolumeInfoNode>();
|
node = graph->create_node<VolumeInfoNode>();
|
||||||
}
|
}
|
||||||
|
@@ -787,6 +787,7 @@ SceneParams BlenderSync::get_scene_params(BL::Scene &b_scene, bool background)
|
|||||||
params.bvh_type = BVH_TYPE_DYNAMIC;
|
params.bvh_type = BVH_TYPE_DYNAMIC;
|
||||||
|
|
||||||
params.use_bvh_spatial_split = RNA_boolean_get(&cscene, "debug_use_spatial_splits");
|
params.use_bvh_spatial_split = RNA_boolean_get(&cscene, "debug_use_spatial_splits");
|
||||||
|
params.use_bvh_compact_structure = RNA_boolean_get(&cscene, "debug_use_compact_bvh");
|
||||||
params.use_bvh_unaligned_nodes = RNA_boolean_get(&cscene, "debug_use_hair_bvh");
|
params.use_bvh_unaligned_nodes = RNA_boolean_get(&cscene, "debug_use_hair_bvh");
|
||||||
params.num_bvh_time_steps = RNA_int_get(&cscene, "debug_bvh_time_steps");
|
params.num_bvh_time_steps = RNA_int_get(&cscene, "debug_bvh_time_steps");
|
||||||
|
|
||||||
|
@@ -935,7 +935,7 @@ BVHNode *BVHBuild::create_object_leaf_nodes(const BVHReference *ref, int start,
|
|||||||
|
|
||||||
BVHNode *BVHBuild::create_leaf_node(const BVHRange &range, const vector<BVHReference> &references)
|
BVHNode *BVHBuild::create_leaf_node(const BVHRange &range, const vector<BVHReference> &references)
|
||||||
{
|
{
|
||||||
/* This is a bit overallocating here (considering leaf size into account),
|
/* This is a bit over-allocating here (considering leaf size into account),
|
||||||
* but chunk-based re-allocation in vector makes it difficult to use small
|
* but chunk-based re-allocation in vector makes it difficult to use small
|
||||||
* size of stack storage here. Some tweaks are possible tho.
|
* size of stack storage here. Some tweaks are possible tho.
|
||||||
*
|
*
|
||||||
|
@@ -355,10 +355,12 @@ void BVHEmbree::build(Progress &progress, Stats *stats, RTCDevice rtc_device_)
|
|||||||
}
|
}
|
||||||
|
|
||||||
const bool dynamic = params.bvh_type == BVH_TYPE_DYNAMIC;
|
const bool dynamic = params.bvh_type == BVH_TYPE_DYNAMIC;
|
||||||
|
const bool compact = params.use_compact_structure;
|
||||||
|
|
||||||
scene = rtcNewScene(rtc_device);
|
scene = rtcNewScene(rtc_device);
|
||||||
const RTCSceneFlags scene_flags = (dynamic ? RTC_SCENE_FLAG_DYNAMIC : RTC_SCENE_FLAG_NONE) |
|
const RTCSceneFlags scene_flags = (dynamic ? RTC_SCENE_FLAG_DYNAMIC : RTC_SCENE_FLAG_NONE) |
|
||||||
RTC_SCENE_FLAG_COMPACT | RTC_SCENE_FLAG_ROBUST;
|
(compact ? RTC_SCENE_FLAG_COMPACT : RTC_SCENE_FLAG_NONE) |
|
||||||
|
RTC_SCENE_FLAG_ROBUST;
|
||||||
rtcSetSceneFlags(scene, scene_flags);
|
rtcSetSceneFlags(scene, scene_flags);
|
||||||
build_quality = dynamic ? RTC_BUILD_QUALITY_LOW :
|
build_quality = dynamic ? RTC_BUILD_QUALITY_LOW :
|
||||||
(params.use_spatial_split ? RTC_BUILD_QUALITY_HIGH :
|
(params.use_spatial_split ? RTC_BUILD_QUALITY_HIGH :
|
||||||
|
@@ -97,6 +97,9 @@ class BVHParams {
|
|||||||
*/
|
*/
|
||||||
bool use_unaligned_nodes;
|
bool use_unaligned_nodes;
|
||||||
|
|
||||||
|
/* Use compact acceleration structure (Embree)*/
|
||||||
|
bool use_compact_structure;
|
||||||
|
|
||||||
/* Split time range to this number of steps and create leaf node for each
|
/* Split time range to this number of steps and create leaf node for each
|
||||||
* of this time steps.
|
* of this time steps.
|
||||||
*
|
*
|
||||||
|
@@ -84,39 +84,6 @@ macro(cycles_add_library target library_deps)
|
|||||||
cycles_set_solution_folder(${target})
|
cycles_set_solution_folder(${target})
|
||||||
endmacro()
|
endmacro()
|
||||||
|
|
||||||
# Cycles library dependencies common to all executables
|
|
||||||
|
|
||||||
function(cycles_link_directories)
|
|
||||||
if(APPLE)
|
|
||||||
# APPLE platform uses full paths for linking libraries, and avoids link_directories.
|
|
||||||
return()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(WITH_OPENCOLORIO)
|
|
||||||
link_directories(${OPENCOLORIO_LIBPATH})
|
|
||||||
endif()
|
|
||||||
if(WITH_OPENVDB)
|
|
||||||
link_directories(${OPENVDB_LIBPATH} ${BLOSC_LIBPATH})
|
|
||||||
endif()
|
|
||||||
if(WITH_OPENSUBDIV)
|
|
||||||
link_directories(${OPENSUBDIV_LIBPATH})
|
|
||||||
endif()
|
|
||||||
if(WITH_OPENIMAGEDENOISE)
|
|
||||||
link_directories(${OPENIMAGEDENOISE_LIBPATH})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
link_directories(
|
|
||||||
${OPENIMAGEIO_LIBPATH}
|
|
||||||
${BOOST_LIBPATH}
|
|
||||||
${PNG_LIBPATH}
|
|
||||||
${JPEG_LIBPATH}
|
|
||||||
${ZLIB_LIBPATH}
|
|
||||||
${TIFF_LIBPATH}
|
|
||||||
${OPENEXR_LIBPATH}
|
|
||||||
${OPENJPEG_LIBPATH}
|
|
||||||
)
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
macro(cycles_target_link_libraries target)
|
macro(cycles_target_link_libraries target)
|
||||||
if(WITH_CYCLES_LOGGING)
|
if(WITH_CYCLES_LOGGING)
|
||||||
target_link_libraries(${target} ${GLOG_LIBRARIES} ${GFLAGS_LIBRARIES})
|
target_link_libraries(${target} ${GLOG_LIBRARIES} ${GFLAGS_LIBRARIES})
|
||||||
|
@@ -72,7 +72,7 @@ CPUDevice::CPUDevice(const DeviceInfo &info_, Stats &stats_, Profiler &profiler_
|
|||||||
<< " CPU kernels.";
|
<< " CPU kernels.";
|
||||||
|
|
||||||
if (info.cpu_threads == 0) {
|
if (info.cpu_threads == 0) {
|
||||||
info.cpu_threads = TaskScheduler::num_threads();
|
info.cpu_threads = TaskScheduler::max_concurrency();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WITH_OSL
|
#ifdef WITH_OSL
|
||||||
|
@@ -334,7 +334,7 @@ DeviceInfo Device::get_multi_device(const vector<DeviceInfo> &subdevices,
|
|||||||
/* Ensure CPU device does not slow down GPU. */
|
/* Ensure CPU device does not slow down GPU. */
|
||||||
if (device.type == DEVICE_CPU && subdevices.size() > 1) {
|
if (device.type == DEVICE_CPU && subdevices.size() > 1) {
|
||||||
if (background) {
|
if (background) {
|
||||||
int orig_cpu_threads = (threads) ? threads : TaskScheduler::num_threads();
|
int orig_cpu_threads = (threads) ? threads : TaskScheduler::max_concurrency();
|
||||||
int cpu_threads = max(orig_cpu_threads - (subdevices.size() - 1), 0);
|
int cpu_threads = max(orig_cpu_threads - (subdevices.size() - 1), 0);
|
||||||
|
|
||||||
VLOG(1) << "CPU render threads reduced from " << orig_cpu_threads << " to " << cpu_threads
|
VLOG(1) << "CPU render threads reduced from " << orig_cpu_threads << " to " << cpu_threads
|
||||||
|
@@ -58,6 +58,11 @@ class BVHMetal : public BVH {
|
|||||||
id<MTLCommandQueue> queue,
|
id<MTLCommandQueue> queue,
|
||||||
Geometry *const geom,
|
Geometry *const geom,
|
||||||
bool refit);
|
bool refit);
|
||||||
|
bool build_BLAS_pointcloud(Progress &progress,
|
||||||
|
id<MTLDevice> device,
|
||||||
|
id<MTLCommandQueue> queue,
|
||||||
|
Geometry *const geom,
|
||||||
|
bool refit);
|
||||||
bool build_TLAS(Progress &progress, id<MTLDevice> device, id<MTLCommandQueue> queue, bool refit);
|
bool build_TLAS(Progress &progress, id<MTLDevice> device, id<MTLCommandQueue> queue, bool refit);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -19,6 +19,7 @@
|
|||||||
# include "scene/hair.h"
|
# include "scene/hair.h"
|
||||||
# include "scene/mesh.h"
|
# include "scene/mesh.h"
|
||||||
# include "scene/object.h"
|
# include "scene/object.h"
|
||||||
|
# include "scene/pointcloud.h"
|
||||||
|
|
||||||
# include "util/progress.h"
|
# include "util/progress.h"
|
||||||
|
|
||||||
@@ -475,6 +476,220 @@ bool BVHMetal::build_BLAS_hair(Progress &progress,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BVHMetal::build_BLAS_pointcloud(Progress &progress,
|
||||||
|
id<MTLDevice> device,
|
||||||
|
id<MTLCommandQueue> queue,
|
||||||
|
Geometry *const geom,
|
||||||
|
bool refit)
|
||||||
|
{
|
||||||
|
if (@available(macos 12.0, *)) {
|
||||||
|
/* Build BLAS for point cloud */
|
||||||
|
PointCloud *pointcloud = static_cast<PointCloud *>(geom);
|
||||||
|
if (pointcloud->num_points() == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*------------------------------------------------*/
|
||||||
|
BVH_status("Building pointcloud BLAS | %7d points | %s",
|
||||||
|
(int)pointcloud->num_points(),
|
||||||
|
geom->name.c_str());
|
||||||
|
/*------------------------------------------------*/
|
||||||
|
|
||||||
|
const size_t num_points = pointcloud->get_points().size();
|
||||||
|
const float3 *points = pointcloud->get_points().data();
|
||||||
|
const float *radius = pointcloud->get_radius().data();
|
||||||
|
|
||||||
|
const bool use_fast_trace_bvh = (params.bvh_type == BVH_TYPE_STATIC);
|
||||||
|
|
||||||
|
size_t num_motion_steps = 1;
|
||||||
|
Attribute *motion_keys = pointcloud->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
|
||||||
|
if (motion_blur && pointcloud->get_use_motion_blur() && motion_keys) {
|
||||||
|
num_motion_steps = pointcloud->get_motion_steps();
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t num_aabbs = num_motion_steps;
|
||||||
|
|
||||||
|
MTLResourceOptions storage_mode;
|
||||||
|
if (device.hasUnifiedMemory) {
|
||||||
|
storage_mode = MTLResourceStorageModeShared;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
storage_mode = MTLResourceStorageModeManaged;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate a GPU buffer for the AABB data and populate it */
|
||||||
|
id<MTLBuffer> aabbBuf = [device
|
||||||
|
newBufferWithLength:num_aabbs * sizeof(MTLAxisAlignedBoundingBox)
|
||||||
|
options:storage_mode];
|
||||||
|
MTLAxisAlignedBoundingBox *aabb_data = (MTLAxisAlignedBoundingBox *)[aabbBuf contents];
|
||||||
|
|
||||||
|
/* Get AABBs for each motion step */
|
||||||
|
size_t center_step = (num_motion_steps - 1) / 2;
|
||||||
|
for (size_t step = 0; step < num_motion_steps; ++step) {
|
||||||
|
/* The center step for motion vertices is not stored in the attribute */
|
||||||
|
if (step != center_step) {
|
||||||
|
size_t attr_offset = (step > center_step) ? step - 1 : step;
|
||||||
|
points = motion_keys->data_float3() + attr_offset * num_points;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t j = 0; j < num_points; ++j) {
|
||||||
|
const PointCloud::Point point = pointcloud->get_point(j);
|
||||||
|
BoundBox bounds = BoundBox::empty;
|
||||||
|
point.bounds_grow(points, radius, bounds);
|
||||||
|
|
||||||
|
const size_t index = step * num_points + j;
|
||||||
|
aabb_data[index].min = (MTLPackedFloat3 &)bounds.min;
|
||||||
|
aabb_data[index].max = (MTLPackedFloat3 &)bounds.max;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (storage_mode == MTLResourceStorageModeManaged) {
|
||||||
|
[aabbBuf didModifyRange:NSMakeRange(0, aabbBuf.length)];
|
||||||
|
}
|
||||||
|
|
||||||
|
# if 0
|
||||||
|
for (size_t i=0; i<num_aabbs && i < 400; i++) {
|
||||||
|
MTLAxisAlignedBoundingBox& bb = aabb_data[i];
|
||||||
|
printf(" %d: %.1f,%.1f,%.1f -- %.1f,%.1f,%.1f\n", int(i), bb.min.x, bb.min.y, bb.min.z, bb.max.x, bb.max.y, bb.max.z);
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
|
MTLAccelerationStructureGeometryDescriptor *geomDesc;
|
||||||
|
if (motion_blur) {
|
||||||
|
std::vector<MTLMotionKeyframeData *> aabb_ptrs;
|
||||||
|
aabb_ptrs.reserve(num_motion_steps);
|
||||||
|
for (size_t step = 0; step < num_motion_steps; ++step) {
|
||||||
|
MTLMotionKeyframeData *k = [MTLMotionKeyframeData data];
|
||||||
|
k.buffer = aabbBuf;
|
||||||
|
k.offset = step * num_points * sizeof(MTLAxisAlignedBoundingBox);
|
||||||
|
aabb_ptrs.push_back(k);
|
||||||
|
}
|
||||||
|
|
||||||
|
MTLAccelerationStructureMotionBoundingBoxGeometryDescriptor *geomDescMotion =
|
||||||
|
[MTLAccelerationStructureMotionBoundingBoxGeometryDescriptor descriptor];
|
||||||
|
geomDescMotion.boundingBoxBuffers = [NSArray arrayWithObjects:aabb_ptrs.data()
|
||||||
|
count:aabb_ptrs.size()];
|
||||||
|
geomDescMotion.boundingBoxCount = num_points;
|
||||||
|
geomDescMotion.boundingBoxStride = sizeof(aabb_data[0]);
|
||||||
|
geomDescMotion.intersectionFunctionTableOffset = 2;
|
||||||
|
|
||||||
|
/* Force a single any-hit call, so shadow record-all behavior works correctly */
|
||||||
|
/* (Match optix behavior: unsigned int build_flags =
|
||||||
|
* OPTIX_GEOMETRY_FLAG_REQUIRE_SINGLE_ANYHIT_CALL;) */
|
||||||
|
geomDescMotion.allowDuplicateIntersectionFunctionInvocation = false;
|
||||||
|
geomDescMotion.opaque = true;
|
||||||
|
geomDesc = geomDescMotion;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
MTLAccelerationStructureBoundingBoxGeometryDescriptor *geomDescNoMotion =
|
||||||
|
[MTLAccelerationStructureBoundingBoxGeometryDescriptor descriptor];
|
||||||
|
geomDescNoMotion.boundingBoxBuffer = aabbBuf;
|
||||||
|
geomDescNoMotion.boundingBoxBufferOffset = 0;
|
||||||
|
geomDescNoMotion.boundingBoxCount = int(num_aabbs);
|
||||||
|
geomDescNoMotion.boundingBoxStride = sizeof(aabb_data[0]);
|
||||||
|
geomDescNoMotion.intersectionFunctionTableOffset = 2;
|
||||||
|
|
||||||
|
/* Force a single any-hit call, so shadow record-all behavior works correctly */
|
||||||
|
/* (Match optix behavior: unsigned int build_flags =
|
||||||
|
* OPTIX_GEOMETRY_FLAG_REQUIRE_SINGLE_ANYHIT_CALL;) */
|
||||||
|
geomDescNoMotion.allowDuplicateIntersectionFunctionInvocation = false;
|
||||||
|
geomDescNoMotion.opaque = true;
|
||||||
|
geomDesc = geomDescNoMotion;
|
||||||
|
}
|
||||||
|
|
||||||
|
MTLPrimitiveAccelerationStructureDescriptor *accelDesc =
|
||||||
|
[MTLPrimitiveAccelerationStructureDescriptor descriptor];
|
||||||
|
accelDesc.geometryDescriptors = @[ geomDesc ];
|
||||||
|
|
||||||
|
if (motion_blur) {
|
||||||
|
accelDesc.motionStartTime = 0.0f;
|
||||||
|
accelDesc.motionEndTime = 1.0f;
|
||||||
|
accelDesc.motionStartBorderMode = MTLMotionBorderModeVanish;
|
||||||
|
accelDesc.motionEndBorderMode = MTLMotionBorderModeVanish;
|
||||||
|
accelDesc.motionKeyframeCount = num_motion_steps;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!use_fast_trace_bvh) {
|
||||||
|
accelDesc.usage |= (MTLAccelerationStructureUsageRefit |
|
||||||
|
MTLAccelerationStructureUsagePreferFastBuild);
|
||||||
|
}
|
||||||
|
|
||||||
|
MTLAccelerationStructureSizes accelSizes = [device
|
||||||
|
accelerationStructureSizesWithDescriptor:accelDesc];
|
||||||
|
id<MTLAccelerationStructure> accel_uncompressed = [device
|
||||||
|
newAccelerationStructureWithSize:accelSizes.accelerationStructureSize];
|
||||||
|
id<MTLBuffer> scratchBuf = [device newBufferWithLength:accelSizes.buildScratchBufferSize
|
||||||
|
options:MTLResourceStorageModePrivate];
|
||||||
|
id<MTLBuffer> sizeBuf = [device newBufferWithLength:8 options:MTLResourceStorageModeShared];
|
||||||
|
id<MTLCommandBuffer> accelCommands = [queue commandBuffer];
|
||||||
|
id<MTLAccelerationStructureCommandEncoder> accelEnc =
|
||||||
|
[accelCommands accelerationStructureCommandEncoder];
|
||||||
|
if (refit) {
|
||||||
|
[accelEnc refitAccelerationStructure:accel_struct
|
||||||
|
descriptor:accelDesc
|
||||||
|
destination:accel_uncompressed
|
||||||
|
scratchBuffer:scratchBuf
|
||||||
|
scratchBufferOffset:0];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
[accelEnc buildAccelerationStructure:accel_uncompressed
|
||||||
|
descriptor:accelDesc
|
||||||
|
scratchBuffer:scratchBuf
|
||||||
|
scratchBufferOffset:0];
|
||||||
|
}
|
||||||
|
if (use_fast_trace_bvh) {
|
||||||
|
[accelEnc writeCompactedAccelerationStructureSize:accel_uncompressed
|
||||||
|
toBuffer:sizeBuf
|
||||||
|
offset:0
|
||||||
|
sizeDataType:MTLDataTypeULong];
|
||||||
|
}
|
||||||
|
[accelEnc endEncoding];
|
||||||
|
[accelCommands addCompletedHandler:^(id<MTLCommandBuffer> command_buffer) {
|
||||||
|
/* free temp resources */
|
||||||
|
[scratchBuf release];
|
||||||
|
[aabbBuf release];
|
||||||
|
|
||||||
|
if (use_fast_trace_bvh) {
|
||||||
|
/* Compact the accel structure */
|
||||||
|
uint64_t compressed_size = *(uint64_t *)sizeBuf.contents;
|
||||||
|
|
||||||
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||||
|
id<MTLCommandBuffer> accelCommands = [queue commandBuffer];
|
||||||
|
id<MTLAccelerationStructureCommandEncoder> accelEnc =
|
||||||
|
[accelCommands accelerationStructureCommandEncoder];
|
||||||
|
id<MTLAccelerationStructure> accel = [device
|
||||||
|
newAccelerationStructureWithSize:compressed_size];
|
||||||
|
[accelEnc copyAndCompactAccelerationStructure:accel_uncompressed
|
||||||
|
toAccelerationStructure:accel];
|
||||||
|
[accelEnc endEncoding];
|
||||||
|
[accelCommands addCompletedHandler:^(id<MTLCommandBuffer> command_buffer) {
|
||||||
|
uint64_t allocated_size = [accel allocatedSize];
|
||||||
|
stats.mem_alloc(allocated_size);
|
||||||
|
accel_struct = accel;
|
||||||
|
[accel_uncompressed release];
|
||||||
|
accel_struct_building = false;
|
||||||
|
}];
|
||||||
|
[accelCommands commit];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* set our acceleration structure to the uncompressed structure */
|
||||||
|
accel_struct = accel_uncompressed;
|
||||||
|
|
||||||
|
uint64_t allocated_size = [accel_struct allocatedSize];
|
||||||
|
stats.mem_alloc(allocated_size);
|
||||||
|
accel_struct_building = false;
|
||||||
|
}
|
||||||
|
[sizeBuf release];
|
||||||
|
}];
|
||||||
|
|
||||||
|
accel_struct_building = true;
|
||||||
|
[accelCommands commit];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool BVHMetal::build_BLAS(Progress &progress,
|
bool BVHMetal::build_BLAS(Progress &progress,
|
||||||
id<MTLDevice> device,
|
id<MTLDevice> device,
|
||||||
id<MTLCommandQueue> queue,
|
id<MTLCommandQueue> queue,
|
||||||
@@ -491,6 +706,8 @@ bool BVHMetal::build_BLAS(Progress &progress,
|
|||||||
return build_BLAS_mesh(progress, device, queue, geom, refit);
|
return build_BLAS_mesh(progress, device, queue, geom, refit);
|
||||||
case Geometry::HAIR:
|
case Geometry::HAIR:
|
||||||
return build_BLAS_hair(progress, device, queue, geom, refit);
|
return build_BLAS_hair(progress, device, queue, geom, refit);
|
||||||
|
case Geometry::POINTCLOUD:
|
||||||
|
return build_BLAS_pointcloud(progress, device, queue, geom, refit);
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@@ -115,6 +115,8 @@ class MetalDevice : public Device {
|
|||||||
|
|
||||||
void load_texture_info();
|
void load_texture_info();
|
||||||
|
|
||||||
|
void erase_allocation(device_memory &mem);
|
||||||
|
|
||||||
virtual bool should_use_graphics_interop() override;
|
virtual bool should_use_graphics_interop() override;
|
||||||
|
|
||||||
virtual unique_ptr<DeviceQueue> gpu_queue_create() override;
|
virtual unique_ptr<DeviceQueue> gpu_queue_create() override;
|
||||||
|
@@ -87,17 +87,14 @@ MetalDevice::MetalDevice(const DeviceInfo &info, Stats &stats, Profiler &profile
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
case METAL_GPU_INTEL: {
|
case METAL_GPU_INTEL: {
|
||||||
use_metalrt = false;
|
|
||||||
max_threads_per_threadgroup = 64;
|
max_threads_per_threadgroup = 64;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case METAL_GPU_AMD: {
|
case METAL_GPU_AMD: {
|
||||||
use_metalrt = false;
|
|
||||||
max_threads_per_threadgroup = 128;
|
max_threads_per_threadgroup = 128;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case METAL_GPU_APPLE: {
|
case METAL_GPU_APPLE: {
|
||||||
use_metalrt = true;
|
|
||||||
max_threads_per_threadgroup = 512;
|
max_threads_per_threadgroup = 512;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -432,6 +429,25 @@ void MetalDevice::load_texture_info()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MetalDevice::erase_allocation(device_memory &mem)
|
||||||
|
{
|
||||||
|
stats.mem_free(mem.device_size);
|
||||||
|
mem.device_pointer = 0;
|
||||||
|
mem.device_size = 0;
|
||||||
|
|
||||||
|
auto it = metal_mem_map.find(&mem);
|
||||||
|
if (it != metal_mem_map.end()) {
|
||||||
|
MetalMem *mmem = it->second.get();
|
||||||
|
|
||||||
|
/* blank out reference to MetalMem* in the launch params (fixes crash T94736) */
|
||||||
|
if (mmem->pointer_index >= 0) {
|
||||||
|
device_ptr *pointers = (device_ptr *)&launch_params;
|
||||||
|
pointers[mmem->pointer_index] = 0;
|
||||||
|
}
|
||||||
|
metal_mem_map.erase(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MetalDevice::MetalMem *MetalDevice::generic_alloc(device_memory &mem)
|
MetalDevice::MetalMem *MetalDevice::generic_alloc(device_memory &mem)
|
||||||
{
|
{
|
||||||
size_t size = mem.memory_size();
|
size_t size = mem.memory_size();
|
||||||
@@ -561,11 +577,7 @@ void MetalDevice::generic_free(device_memory &mem)
|
|||||||
mmem.mtlBuffer = nil;
|
mmem.mtlBuffer = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
stats.mem_free(mem.device_size);
|
erase_allocation(mem);
|
||||||
mem.device_pointer = 0;
|
|
||||||
mem.device_size = 0;
|
|
||||||
|
|
||||||
metal_mem_map.erase(&mem);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -954,10 +966,7 @@ void MetalDevice::tex_free(device_texture &mem)
|
|||||||
delayed_free_list.push_back(mmem.mtlTexture);
|
delayed_free_list.push_back(mmem.mtlTexture);
|
||||||
mmem.mtlTexture = nil;
|
mmem.mtlTexture = nil;
|
||||||
}
|
}
|
||||||
stats.mem_free(mem.device_size);
|
erase_allocation(mem);
|
||||||
mem.device_pointer = 0;
|
|
||||||
mem.device_size = 0;
|
|
||||||
metal_mem_map.erase(&mem);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -36,6 +36,8 @@ enum {
|
|||||||
METALRT_FUNC_CURVE_RIBBON_SHADOW,
|
METALRT_FUNC_CURVE_RIBBON_SHADOW,
|
||||||
METALRT_FUNC_CURVE_ALL,
|
METALRT_FUNC_CURVE_ALL,
|
||||||
METALRT_FUNC_CURVE_ALL_SHADOW,
|
METALRT_FUNC_CURVE_ALL_SHADOW,
|
||||||
|
METALRT_FUNC_POINT,
|
||||||
|
METALRT_FUNC_POINT_SHADOW,
|
||||||
METALRT_FUNC_NUM
|
METALRT_FUNC_NUM
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -358,6 +358,8 @@ bool MetalDeviceKernels::load(MetalDevice *device, int kernel_type)
|
|||||||
"__intersection__curve_ribbon_shadow",
|
"__intersection__curve_ribbon_shadow",
|
||||||
"__intersection__curve_all",
|
"__intersection__curve_all",
|
||||||
"__intersection__curve_all_shadow",
|
"__intersection__curve_all_shadow",
|
||||||
|
"__intersection__point",
|
||||||
|
"__intersection__point_shadow",
|
||||||
};
|
};
|
||||||
assert(sizeof(function_names) / sizeof(function_names[0]) == METALRT_FUNC_NUM);
|
assert(sizeof(function_names) / sizeof(function_names[0]) == METALRT_FUNC_NUM);
|
||||||
|
|
||||||
@@ -400,36 +402,50 @@ bool MetalDeviceKernels::load(MetalDevice *device, int kernel_type)
|
|||||||
NSArray *function_list = nil;
|
NSArray *function_list = nil;
|
||||||
|
|
||||||
if (device->use_metalrt) {
|
if (device->use_metalrt) {
|
||||||
id<MTLFunction> box_intersect_default = nil;
|
id<MTLFunction> curve_intersect_default = nil;
|
||||||
id<MTLFunction> box_intersect_shadow = nil;
|
id<MTLFunction> curve_intersect_shadow = nil;
|
||||||
|
id<MTLFunction> point_intersect_default = nil;
|
||||||
|
id<MTLFunction> point_intersect_shadow = nil;
|
||||||
if (device->kernel_features & KERNEL_FEATURE_HAIR) {
|
if (device->kernel_features & KERNEL_FEATURE_HAIR) {
|
||||||
/* Add curve intersection programs. */
|
/* Add curve intersection programs. */
|
||||||
if (device->kernel_features & KERNEL_FEATURE_HAIR_THICK) {
|
if (device->kernel_features & KERNEL_FEATURE_HAIR_THICK) {
|
||||||
/* Slower programs for thick hair since that also slows down ribbons.
|
/* Slower programs for thick hair since that also slows down ribbons.
|
||||||
* Ideally this should not be needed. */
|
* Ideally this should not be needed. */
|
||||||
box_intersect_default = rt_intersection_funcs[kernel_type][METALRT_FUNC_CURVE_ALL];
|
curve_intersect_default = rt_intersection_funcs[kernel_type][METALRT_FUNC_CURVE_ALL];
|
||||||
box_intersect_shadow = rt_intersection_funcs[kernel_type][METALRT_FUNC_CURVE_ALL_SHADOW];
|
curve_intersect_shadow =
|
||||||
|
rt_intersection_funcs[kernel_type][METALRT_FUNC_CURVE_ALL_SHADOW];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
box_intersect_default = rt_intersection_funcs[kernel_type][METALRT_FUNC_CURVE_RIBBON];
|
curve_intersect_default = rt_intersection_funcs[kernel_type][METALRT_FUNC_CURVE_RIBBON];
|
||||||
box_intersect_shadow =
|
curve_intersect_shadow =
|
||||||
rt_intersection_funcs[kernel_type][METALRT_FUNC_CURVE_RIBBON_SHADOW];
|
rt_intersection_funcs[kernel_type][METALRT_FUNC_CURVE_RIBBON_SHADOW];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (device->kernel_features & KERNEL_FEATURE_POINTCLOUD) {
|
||||||
|
point_intersect_default = rt_intersection_funcs[kernel_type][METALRT_FUNC_POINT];
|
||||||
|
point_intersect_shadow = rt_intersection_funcs[kernel_type][METALRT_FUNC_POINT_SHADOW];
|
||||||
|
}
|
||||||
table_functions[METALRT_TABLE_DEFAULT] = [NSArray
|
table_functions[METALRT_TABLE_DEFAULT] = [NSArray
|
||||||
arrayWithObjects:rt_intersection_funcs[kernel_type][METALRT_FUNC_DEFAULT_TRI],
|
arrayWithObjects:rt_intersection_funcs[kernel_type][METALRT_FUNC_DEFAULT_TRI],
|
||||||
box_intersect_default ?
|
curve_intersect_default ?
|
||||||
box_intersect_default :
|
curve_intersect_default :
|
||||||
|
rt_intersection_funcs[kernel_type][METALRT_FUNC_DEFAULT_BOX],
|
||||||
|
point_intersect_default ?
|
||||||
|
point_intersect_default :
|
||||||
rt_intersection_funcs[kernel_type][METALRT_FUNC_DEFAULT_BOX],
|
rt_intersection_funcs[kernel_type][METALRT_FUNC_DEFAULT_BOX],
|
||||||
nil];
|
nil];
|
||||||
table_functions[METALRT_TABLE_SHADOW] = [NSArray
|
table_functions[METALRT_TABLE_SHADOW] = [NSArray
|
||||||
arrayWithObjects:rt_intersection_funcs[kernel_type][METALRT_FUNC_SHADOW_TRI],
|
arrayWithObjects:rt_intersection_funcs[kernel_type][METALRT_FUNC_SHADOW_TRI],
|
||||||
box_intersect_shadow ?
|
curve_intersect_shadow ?
|
||||||
box_intersect_shadow :
|
curve_intersect_shadow :
|
||||||
|
rt_intersection_funcs[kernel_type][METALRT_FUNC_SHADOW_BOX],
|
||||||
|
point_intersect_shadow ?
|
||||||
|
point_intersect_shadow :
|
||||||
rt_intersection_funcs[kernel_type][METALRT_FUNC_SHADOW_BOX],
|
rt_intersection_funcs[kernel_type][METALRT_FUNC_SHADOW_BOX],
|
||||||
nil];
|
nil];
|
||||||
table_functions[METALRT_TABLE_LOCAL] = [NSArray
|
table_functions[METALRT_TABLE_LOCAL] = [NSArray
|
||||||
arrayWithObjects:rt_intersection_funcs[kernel_type][METALRT_FUNC_LOCAL_TRI],
|
arrayWithObjects:rt_intersection_funcs[kernel_type][METALRT_FUNC_LOCAL_TRI],
|
||||||
|
rt_intersection_funcs[kernel_type][METALRT_FUNC_LOCAL_BOX],
|
||||||
rt_intersection_funcs[kernel_type][METALRT_FUNC_LOCAL_BOX],
|
rt_intersection_funcs[kernel_type][METALRT_FUNC_LOCAL_BOX],
|
||||||
nil];
|
nil];
|
||||||
|
|
||||||
|
@@ -141,6 +141,7 @@ bool PassAccessor::get_render_tile_pixels(const RenderBuffers *render_buffers,
|
|||||||
const PassType type = pass_access_info_.type;
|
const PassType type = pass_access_info_.type;
|
||||||
const PassMode mode = pass_access_info_.mode;
|
const PassMode mode = pass_access_info_.mode;
|
||||||
const PassInfo pass_info = Pass::get_info(type, pass_access_info_.include_albedo);
|
const PassInfo pass_info = Pass::get_info(type, pass_access_info_.include_albedo);
|
||||||
|
int num_written_components = pass_info.num_components;
|
||||||
|
|
||||||
if (pass_info.num_components == 1) {
|
if (pass_info.num_components == 1) {
|
||||||
/* Single channel passes. */
|
/* Single channel passes. */
|
||||||
@@ -188,8 +189,10 @@ bool PassAccessor::get_render_tile_pixels(const RenderBuffers *render_buffers,
|
|||||||
else if ((pass_info.divide_type != PASS_NONE || pass_info.direct_type != PASS_NONE ||
|
else if ((pass_info.divide_type != PASS_NONE || pass_info.direct_type != PASS_NONE ||
|
||||||
pass_info.indirect_type != PASS_NONE) &&
|
pass_info.indirect_type != PASS_NONE) &&
|
||||||
mode != PassMode::DENOISED) {
|
mode != PassMode::DENOISED) {
|
||||||
/* RGB lighting passes that need to divide out color and/or sum direct and indirect. */
|
/* RGB lighting passes that need to divide out color and/or sum direct and indirect.
|
||||||
|
* These can also optionally write alpha like the combined pass. */
|
||||||
get_pass_light_path(render_buffers, buffer_params, destination);
|
get_pass_light_path(render_buffers, buffer_params, destination);
|
||||||
|
num_written_components = 4;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Passes that need no special computation, or denoised passes that already
|
/* Passes that need no special computation, or denoised passes that already
|
||||||
@@ -215,7 +218,7 @@ bool PassAccessor::get_render_tile_pixels(const RenderBuffers *render_buffers,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pad_pixels(buffer_params, destination, pass_info.num_components);
|
pad_pixels(buffer_params, destination, num_written_components);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@@ -820,8 +820,15 @@ void PathTrace::tile_buffer_read()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Read buffers back from device. */
|
||||||
|
tbb::parallel_for_each(path_trace_works_, [&](unique_ptr<PathTraceWork> &path_trace_work) {
|
||||||
|
path_trace_work->copy_render_buffers_from_device();
|
||||||
|
});
|
||||||
|
|
||||||
|
/* Read (subset of) passes from output driver. */
|
||||||
PathTraceTile tile(*this);
|
PathTraceTile tile(*this);
|
||||||
if (output_driver_->read_render_tile(tile)) {
|
if (output_driver_->read_render_tile(tile)) {
|
||||||
|
/* Copy buffers to device again. */
|
||||||
tbb::parallel_for_each(path_trace_works_, [](unique_ptr<PathTraceWork> &path_trace_work) {
|
tbb::parallel_for_each(path_trace_works_, [](unique_ptr<PathTraceWork> &path_trace_work) {
|
||||||
path_trace_work->copy_render_buffers_to_device();
|
path_trace_work->copy_render_buffers_to_device();
|
||||||
});
|
});
|
||||||
|
@@ -148,12 +148,23 @@ ccl_device_inline
|
|||||||
/* intersect ray against primitive */
|
/* intersect ray against primitive */
|
||||||
for (; prim_addr < prim_addr2; prim_addr++) {
|
for (; prim_addr < prim_addr2; prim_addr++) {
|
||||||
kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
|
kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
|
||||||
|
|
||||||
|
/* Only intersect with matching object, for instanced objects we
|
||||||
|
* already know we are only intersecting the right object. */
|
||||||
|
if (object == OBJECT_NONE) {
|
||||||
|
if (kernel_tex_fetch(__prim_object, prim_addr) != local_object) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const int prim = kernel_tex_fetch(__prim_index, prim_addr);
|
||||||
|
|
||||||
if (triangle_intersect_local(kg,
|
if (triangle_intersect_local(kg,
|
||||||
local_isect,
|
local_isect,
|
||||||
P,
|
P,
|
||||||
dir,
|
dir,
|
||||||
object,
|
|
||||||
local_object,
|
local_object,
|
||||||
|
prim,
|
||||||
prim_addr,
|
prim_addr,
|
||||||
isect_t,
|
isect_t,
|
||||||
lcg_state,
|
lcg_state,
|
||||||
@@ -168,13 +179,24 @@ ccl_device_inline
|
|||||||
/* intersect ray against primitive */
|
/* intersect ray against primitive */
|
||||||
for (; prim_addr < prim_addr2; prim_addr++) {
|
for (; prim_addr < prim_addr2; prim_addr++) {
|
||||||
kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
|
kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
|
||||||
|
|
||||||
|
/* Only intersect with matching object, for instanced objects we
|
||||||
|
* already know we are only intersecting the right object. */
|
||||||
|
if (object == OBJECT_NONE) {
|
||||||
|
if (kernel_tex_fetch(__prim_object, prim_addr) != local_object) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const int prim = kernel_tex_fetch(__prim_index, prim_addr);
|
||||||
|
|
||||||
if (motion_triangle_intersect_local(kg,
|
if (motion_triangle_intersect_local(kg,
|
||||||
local_isect,
|
local_isect,
|
||||||
P,
|
P,
|
||||||
dir,
|
dir,
|
||||||
ray->time,
|
ray->time,
|
||||||
object,
|
|
||||||
local_object,
|
local_object,
|
||||||
|
prim,
|
||||||
prim_addr,
|
prim_addr,
|
||||||
isect_t,
|
isect_t,
|
||||||
lcg_state,
|
lcg_state,
|
||||||
|
@@ -146,7 +146,7 @@ ccl_device_inline
|
|||||||
--stack_ptr;
|
--stack_ptr;
|
||||||
|
|
||||||
/* primitive intersection */
|
/* primitive intersection */
|
||||||
while (prim_addr < prim_addr2) {
|
for (; prim_addr < prim_addr2; prim_addr++) {
|
||||||
kernel_assert((kernel_tex_fetch(__prim_type, prim_addr) & PRIMITIVE_ALL) ==
|
kernel_assert((kernel_tex_fetch(__prim_type, prim_addr) & PRIMITIVE_ALL) ==
|
||||||
(type & PRIMITIVE_ALL));
|
(type & PRIMITIVE_ALL));
|
||||||
bool hit;
|
bool hit;
|
||||||
@@ -156,16 +156,29 @@ ccl_device_inline
|
|||||||
* might give a few % performance improvement */
|
* might give a few % performance improvement */
|
||||||
Intersection isect ccl_optional_struct_init;
|
Intersection isect ccl_optional_struct_init;
|
||||||
|
|
||||||
|
const int prim_object = (object == OBJECT_NONE) ?
|
||||||
|
kernel_tex_fetch(__prim_object, prim_addr) :
|
||||||
|
object;
|
||||||
|
const int prim = kernel_tex_fetch(__prim_index, prim_addr);
|
||||||
|
|
||||||
switch (type & PRIMITIVE_ALL) {
|
switch (type & PRIMITIVE_ALL) {
|
||||||
case PRIMITIVE_TRIANGLE: {
|
case PRIMITIVE_TRIANGLE: {
|
||||||
hit = triangle_intersect(
|
hit = triangle_intersect(
|
||||||
kg, &isect, P, dir, t_max_current, visibility, object, prim_addr);
|
kg, &isect, P, dir, t_max_current, visibility, prim_object, prim, prim_addr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#if BVH_FEATURE(BVH_MOTION)
|
#if BVH_FEATURE(BVH_MOTION)
|
||||||
case PRIMITIVE_MOTION_TRIANGLE: {
|
case PRIMITIVE_MOTION_TRIANGLE: {
|
||||||
hit = motion_triangle_intersect(
|
hit = motion_triangle_intersect(kg,
|
||||||
kg, &isect, P, dir, t_max_current, ray->time, visibility, object, prim_addr);
|
&isect,
|
||||||
|
P,
|
||||||
|
dir,
|
||||||
|
t_max_current,
|
||||||
|
ray->time,
|
||||||
|
visibility,
|
||||||
|
prim_object,
|
||||||
|
prim,
|
||||||
|
prim_addr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -182,20 +195,9 @@ ccl_device_inline
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const int curve_object = (object == OBJECT_NONE) ?
|
|
||||||
kernel_tex_fetch(__prim_object, prim_addr) :
|
|
||||||
object;
|
|
||||||
const int curve_type = kernel_tex_fetch(__prim_type, prim_addr);
|
const int curve_type = kernel_tex_fetch(__prim_type, prim_addr);
|
||||||
const int curve_prim = kernel_tex_fetch(__prim_index, prim_addr);
|
hit = curve_intersect(
|
||||||
hit = curve_intersect(kg,
|
kg, &isect, P, dir, t_max_current, prim_object, prim, ray->time, curve_type);
|
||||||
&isect,
|
|
||||||
P,
|
|
||||||
dir,
|
|
||||||
t_max_current,
|
|
||||||
curve_object,
|
|
||||||
curve_prim,
|
|
||||||
ray->time,
|
|
||||||
curve_type);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -211,20 +213,9 @@ ccl_device_inline
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const int point_object = (object == OBJECT_NONE) ?
|
|
||||||
kernel_tex_fetch(__prim_object, prim_addr) :
|
|
||||||
object;
|
|
||||||
const int point_prim = kernel_tex_fetch(__prim_index, prim_addr);
|
|
||||||
const int point_type = kernel_tex_fetch(__prim_type, prim_addr);
|
const int point_type = kernel_tex_fetch(__prim_type, prim_addr);
|
||||||
hit = point_intersect(kg,
|
hit = point_intersect(
|
||||||
&isect,
|
kg, &isect, P, dir, t_max_current, prim_object, prim, ray->time, point_type);
|
||||||
P,
|
|
||||||
dir,
|
|
||||||
t_max_current,
|
|
||||||
point_object,
|
|
||||||
point_prim,
|
|
||||||
ray->time,
|
|
||||||
point_type);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif /* BVH_FEATURE(BVH_POINTCLOUD) */
|
#endif /* BVH_FEATURE(BVH_POINTCLOUD) */
|
||||||
@@ -301,8 +292,6 @@ ccl_device_inline
|
|||||||
integrator_state_write_shadow_isect(state, &isect, record_index);
|
integrator_state_write_shadow_isect(state, &isect, record_index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
prim_addr++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@@ -137,8 +137,14 @@ ccl_device_noinline bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals kg,
|
|||||||
case PRIMITIVE_TRIANGLE: {
|
case PRIMITIVE_TRIANGLE: {
|
||||||
for (; prim_addr < prim_addr2; prim_addr++) {
|
for (; prim_addr < prim_addr2; prim_addr++) {
|
||||||
kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
|
kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
|
||||||
|
|
||||||
|
const int prim_object = (object == OBJECT_NONE) ?
|
||||||
|
kernel_tex_fetch(__prim_object, prim_addr) :
|
||||||
|
object;
|
||||||
|
const int prim = kernel_tex_fetch(__prim_index, prim_addr);
|
||||||
|
|
||||||
if (triangle_intersect(
|
if (triangle_intersect(
|
||||||
kg, isect, P, dir, isect->t, visibility, object, prim_addr)) {
|
kg, isect, P, dir, isect->t, visibility, prim_object, prim, prim_addr)) {
|
||||||
/* shadow ray early termination */
|
/* shadow ray early termination */
|
||||||
if (visibility & PATH_RAY_SHADOW_OPAQUE)
|
if (visibility & PATH_RAY_SHADOW_OPAQUE)
|
||||||
return true;
|
return true;
|
||||||
@@ -150,8 +156,22 @@ ccl_device_noinline bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals kg,
|
|||||||
case PRIMITIVE_MOTION_TRIANGLE: {
|
case PRIMITIVE_MOTION_TRIANGLE: {
|
||||||
for (; prim_addr < prim_addr2; prim_addr++) {
|
for (; prim_addr < prim_addr2; prim_addr++) {
|
||||||
kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
|
kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
|
||||||
if (motion_triangle_intersect(
|
|
||||||
kg, isect, P, dir, isect->t, ray->time, visibility, object, prim_addr)) {
|
const int prim_object = (object == OBJECT_NONE) ?
|
||||||
|
kernel_tex_fetch(__prim_object, prim_addr) :
|
||||||
|
object;
|
||||||
|
const int prim = kernel_tex_fetch(__prim_index, prim_addr);
|
||||||
|
|
||||||
|
if (motion_triangle_intersect(kg,
|
||||||
|
isect,
|
||||||
|
P,
|
||||||
|
dir,
|
||||||
|
isect->t,
|
||||||
|
ray->time,
|
||||||
|
visibility,
|
||||||
|
prim_object,
|
||||||
|
prim,
|
||||||
|
prim_addr)) {
|
||||||
/* shadow ray early termination */
|
/* shadow ray early termination */
|
||||||
if (visibility & PATH_RAY_SHADOW_OPAQUE)
|
if (visibility & PATH_RAY_SHADOW_OPAQUE)
|
||||||
return true;
|
return true;
|
||||||
@@ -173,13 +193,14 @@ ccl_device_noinline bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals kg,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const int curve_object = (object == OBJECT_NONE) ?
|
const int prim_object = (object == OBJECT_NONE) ?
|
||||||
kernel_tex_fetch(__prim_object, prim_addr) :
|
kernel_tex_fetch(__prim_object, prim_addr) :
|
||||||
object;
|
object;
|
||||||
const int curve_prim = kernel_tex_fetch(__prim_index, prim_addr);
|
const int prim = kernel_tex_fetch(__prim_index, prim_addr);
|
||||||
|
|
||||||
const int curve_type = kernel_tex_fetch(__prim_type, prim_addr);
|
const int curve_type = kernel_tex_fetch(__prim_type, prim_addr);
|
||||||
const bool hit = curve_intersect(
|
const bool hit = curve_intersect(
|
||||||
kg, isect, P, dir, isect->t, curve_object, curve_prim, ray->time, curve_type);
|
kg, isect, P, dir, isect->t, prim_object, prim, ray->time, curve_type);
|
||||||
if (hit) {
|
if (hit) {
|
||||||
/* shadow ray early termination */
|
/* shadow ray early termination */
|
||||||
if (visibility & PATH_RAY_SHADOW_OPAQUE)
|
if (visibility & PATH_RAY_SHADOW_OPAQUE)
|
||||||
@@ -200,13 +221,14 @@ ccl_device_noinline bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals kg,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const int point_object = (object == OBJECT_NONE) ?
|
const int prim_object = (object == OBJECT_NONE) ?
|
||||||
kernel_tex_fetch(__prim_object, prim_addr) :
|
kernel_tex_fetch(__prim_object, prim_addr) :
|
||||||
object;
|
object;
|
||||||
const int point_prim = kernel_tex_fetch(__prim_index, prim_addr);
|
const int prim = kernel_tex_fetch(__prim_index, prim_addr);
|
||||||
|
|
||||||
const int point_type = kernel_tex_fetch(__prim_type, prim_addr);
|
const int point_type = kernel_tex_fetch(__prim_type, prim_addr);
|
||||||
const bool hit = point_intersect(
|
const bool hit = point_intersect(
|
||||||
kg, isect, P, dir, isect->t, point_object, point_prim, ray->time, point_type);
|
kg, isect, P, dir, isect->t, prim_object, prim, ray->time, point_type);
|
||||||
if (hit) {
|
if (hit) {
|
||||||
/* shadow ray early termination */
|
/* shadow ray early termination */
|
||||||
if (visibility & PATH_RAY_SHADOW_OPAQUE)
|
if (visibility & PATH_RAY_SHADOW_OPAQUE)
|
||||||
|
@@ -140,14 +140,17 @@ ccl_device_inline
|
|||||||
for (; prim_addr < prim_addr2; prim_addr++) {
|
for (; prim_addr < prim_addr2; prim_addr++) {
|
||||||
kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
|
kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
|
||||||
/* only primitives from volume object */
|
/* only primitives from volume object */
|
||||||
uint tri_object = (object == OBJECT_NONE) ?
|
const int prim_object = (object == OBJECT_NONE) ?
|
||||||
kernel_tex_fetch(__prim_object, prim_addr) :
|
kernel_tex_fetch(__prim_object, prim_addr) :
|
||||||
object;
|
object;
|
||||||
int object_flag = kernel_tex_fetch(__object_flag, tri_object);
|
const int prim = kernel_tex_fetch(__prim_index, prim_addr);
|
||||||
|
|
||||||
|
int object_flag = kernel_tex_fetch(__object_flag, prim_object);
|
||||||
if ((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
|
if ((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
triangle_intersect(kg, isect, P, dir, isect->t, visibility, object, prim_addr);
|
triangle_intersect(
|
||||||
|
kg, isect, P, dir, isect->t, visibility, prim_object, prim, prim_addr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -157,15 +160,24 @@ ccl_device_inline
|
|||||||
for (; prim_addr < prim_addr2; prim_addr++) {
|
for (; prim_addr < prim_addr2; prim_addr++) {
|
||||||
kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
|
kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
|
||||||
/* only primitives from volume object */
|
/* only primitives from volume object */
|
||||||
uint tri_object = (object == OBJECT_NONE) ?
|
const int prim_object = (object == OBJECT_NONE) ?
|
||||||
kernel_tex_fetch(__prim_object, prim_addr) :
|
kernel_tex_fetch(__prim_object, prim_addr) :
|
||||||
object;
|
object;
|
||||||
int object_flag = kernel_tex_fetch(__object_flag, tri_object);
|
const int prim = kernel_tex_fetch(__prim_index, prim_addr);
|
||||||
|
int object_flag = kernel_tex_fetch(__object_flag, prim_object);
|
||||||
if ((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
|
if ((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
motion_triangle_intersect(
|
motion_triangle_intersect(kg,
|
||||||
kg, isect, P, dir, isect->t, ray->time, visibility, object, prim_addr);
|
isect,
|
||||||
|
P,
|
||||||
|
dir,
|
||||||
|
isect->t,
|
||||||
|
ray->time,
|
||||||
|
visibility,
|
||||||
|
prim_object,
|
||||||
|
prim,
|
||||||
|
prim_addr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -143,15 +143,16 @@ ccl_device_inline
|
|||||||
for (; prim_addr < prim_addr2; prim_addr++) {
|
for (; prim_addr < prim_addr2; prim_addr++) {
|
||||||
kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
|
kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
|
||||||
/* only primitives from volume object */
|
/* only primitives from volume object */
|
||||||
uint tri_object = (object == OBJECT_NONE) ?
|
const int prim_object = (object == OBJECT_NONE) ?
|
||||||
kernel_tex_fetch(__prim_object, prim_addr) :
|
kernel_tex_fetch(__prim_object, prim_addr) :
|
||||||
object;
|
object;
|
||||||
int object_flag = kernel_tex_fetch(__object_flag, tri_object);
|
const int prim = kernel_tex_fetch(__prim_index, prim_addr);
|
||||||
|
int object_flag = kernel_tex_fetch(__object_flag, prim_object);
|
||||||
if ((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
|
if ((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
hit = triangle_intersect(
|
hit = triangle_intersect(
|
||||||
kg, isect_array, P, dir, isect_t, visibility, object, prim_addr);
|
kg, isect_array, P, dir, isect_t, visibility, prim_object, prim, prim_addr);
|
||||||
if (hit) {
|
if (hit) {
|
||||||
/* Move on to next entry in intersections array. */
|
/* Move on to next entry in intersections array. */
|
||||||
isect_array++;
|
isect_array++;
|
||||||
@@ -183,15 +184,24 @@ ccl_device_inline
|
|||||||
for (; prim_addr < prim_addr2; prim_addr++) {
|
for (; prim_addr < prim_addr2; prim_addr++) {
|
||||||
kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
|
kernel_assert(kernel_tex_fetch(__prim_type, prim_addr) == type);
|
||||||
/* only primitives from volume object */
|
/* only primitives from volume object */
|
||||||
uint tri_object = (object == OBJECT_NONE) ?
|
const int prim_object = (object == OBJECT_NONE) ?
|
||||||
kernel_tex_fetch(__prim_object, prim_addr) :
|
kernel_tex_fetch(__prim_object, prim_addr) :
|
||||||
object;
|
object;
|
||||||
int object_flag = kernel_tex_fetch(__object_flag, tri_object);
|
const int prim = kernel_tex_fetch(__prim_index, prim_addr);
|
||||||
|
int object_flag = kernel_tex_fetch(__object_flag, prim_object);
|
||||||
if ((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
|
if ((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
hit = motion_triangle_intersect(
|
hit = motion_triangle_intersect(kg,
|
||||||
kg, isect_array, P, dir, isect_t, ray->time, visibility, object, prim_addr);
|
isect_array,
|
||||||
|
P,
|
||||||
|
dir,
|
||||||
|
isect_t,
|
||||||
|
ray->time,
|
||||||
|
visibility,
|
||||||
|
prim_object,
|
||||||
|
prim,
|
||||||
|
prim_addr);
|
||||||
if (hit) {
|
if (hit) {
|
||||||
/* Move on to next entry in intersections array. */
|
/* Move on to next entry in intersections array. */
|
||||||
isect_array++;
|
isect_array++;
|
||||||
|
@@ -199,22 +199,18 @@ ccl_device int volume_sample_channel(float3 albedo,
|
|||||||
* Tracing". Matt Jen-Yuan Chiang, Peter Kutz, Brent Burley. SIGGRAPH 2016. */
|
* Tracing". Matt Jen-Yuan Chiang, Peter Kutz, Brent Burley. SIGGRAPH 2016. */
|
||||||
float3 weights = fabs(throughput * albedo);
|
float3 weights = fabs(throughput * albedo);
|
||||||
float sum_weights = weights.x + weights.y + weights.z;
|
float sum_weights = weights.x + weights.y + weights.z;
|
||||||
float3 weights_pdf;
|
|
||||||
|
|
||||||
if (sum_weights > 0.0f) {
|
if (sum_weights > 0.0f) {
|
||||||
weights_pdf = weights / sum_weights;
|
*pdf = weights / sum_weights;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
weights_pdf = make_float3(1.0f / 3.0f, 1.0f / 3.0f, 1.0f / 3.0f);
|
*pdf = make_float3(1.0f / 3.0f, 1.0f / 3.0f, 1.0f / 3.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
*pdf = weights_pdf;
|
if (rand < pdf->x) {
|
||||||
|
|
||||||
/* OpenCL does not support -> on float3, so don't use pdf->x. */
|
|
||||||
if (rand < weights_pdf.x) {
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else if (rand < weights_pdf.x + weights_pdf.y) {
|
else if (rand < pdf->x + pdf->y) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@@ -243,6 +243,10 @@ ccl_gpu_kernel(GPU_KERNEL_BLOCK_NUM_THREADS, GPU_KERNEL_MAX_REGISTERS)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __KERNEL_METAL__
|
||||||
|
constant int __dummy_constant [[function_constant(0)]];
|
||||||
|
#endif
|
||||||
|
|
||||||
ccl_gpu_kernel(GPU_KERNEL_BLOCK_NUM_THREADS, GPU_KERNEL_MAX_REGISTERS)
|
ccl_gpu_kernel(GPU_KERNEL_BLOCK_NUM_THREADS, GPU_KERNEL_MAX_REGISTERS)
|
||||||
ccl_gpu_kernel_signature(integrator_shade_surface_raytrace,
|
ccl_gpu_kernel_signature(integrator_shade_surface_raytrace,
|
||||||
ccl_global const int *path_index_array,
|
ccl_global const int *path_index_array,
|
||||||
@@ -253,7 +257,16 @@ ccl_gpu_kernel(GPU_KERNEL_BLOCK_NUM_THREADS, GPU_KERNEL_MAX_REGISTERS)
|
|||||||
|
|
||||||
if (global_index < work_size) {
|
if (global_index < work_size) {
|
||||||
const int state = (path_index_array) ? path_index_array[global_index] : global_index;
|
const int state = (path_index_array) ? path_index_array[global_index] : global_index;
|
||||||
|
|
||||||
|
#ifdef __KERNEL_METAL__
|
||||||
|
KernelGlobals kg = NULL;
|
||||||
|
/* Workaround Ambient Occlusion and Bevel nodes not working with Metal.
|
||||||
|
* Dummy offset should not affect result, but somehow fixes bug! */
|
||||||
|
kg += __dummy_constant;
|
||||||
|
ccl_gpu_kernel_call(integrator_shade_surface_raytrace(kg, state, render_buffer));
|
||||||
|
#else
|
||||||
ccl_gpu_kernel_call(integrator_shade_surface_raytrace(NULL, state, render_buffer));
|
ccl_gpu_kernel_call(integrator_shade_surface_raytrace(NULL, state, render_buffer));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -576,6 +576,150 @@ __intersection__curve_all_shadow(constant KernelParamsMetal &launch_params_metal
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* __HAIR__ */
|
#endif /* __HAIR__ */
|
||||||
|
|
||||||
|
#ifdef __POINTCLOUD__
|
||||||
|
ccl_device_inline
|
||||||
|
void metalrt_intersection_point(constant KernelParamsMetal &launch_params_metal,
|
||||||
|
ray_data MetalKernelContext::MetalRTIntersectionPayload &payload,
|
||||||
|
const uint object,
|
||||||
|
const uint prim,
|
||||||
|
const uint type,
|
||||||
|
const float3 ray_origin,
|
||||||
|
const float3 ray_direction,
|
||||||
|
float time,
|
||||||
|
const float ray_tmax,
|
||||||
|
thread BoundingBoxIntersectionResult &result)
|
||||||
|
{
|
||||||
|
# ifdef __VISIBILITY_FLAG__
|
||||||
|
const uint visibility = payload.visibility;
|
||||||
|
if ((kernel_tex_fetch(__objects, object).visibility & visibility) == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
|
float3 P = ray_origin;
|
||||||
|
float3 dir = ray_direction;
|
||||||
|
|
||||||
|
/* The direction is not normalized by default, but the point intersection routine expects that */
|
||||||
|
float len;
|
||||||
|
dir = normalize_len(dir, &len);
|
||||||
|
|
||||||
|
Intersection isect;
|
||||||
|
isect.t = ray_tmax;
|
||||||
|
/* Transform maximum distance into object space. */
|
||||||
|
if (isect.t != FLT_MAX)
|
||||||
|
isect.t *= len;
|
||||||
|
|
||||||
|
MetalKernelContext context(launch_params_metal);
|
||||||
|
if (context.point_intersect(NULL, &isect, P, dir, isect.t, object, prim, time, type)) {
|
||||||
|
result = metalrt_visibility_test<BoundingBoxIntersectionResult, METALRT_HIT_BOUNDING_BOX>(
|
||||||
|
launch_params_metal, payload, object, prim, isect.u);
|
||||||
|
if (result.accept) {
|
||||||
|
result.distance = isect.t / len;
|
||||||
|
payload.u = isect.u;
|
||||||
|
payload.v = isect.v;
|
||||||
|
payload.prim = prim;
|
||||||
|
payload.type = type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ccl_device_inline
|
||||||
|
void metalrt_intersection_point_shadow(constant KernelParamsMetal &launch_params_metal,
|
||||||
|
ray_data MetalKernelContext::MetalRTIntersectionShadowPayload &payload,
|
||||||
|
const uint object,
|
||||||
|
const uint prim,
|
||||||
|
const uint type,
|
||||||
|
const float3 ray_origin,
|
||||||
|
const float3 ray_direction,
|
||||||
|
float time,
|
||||||
|
const float ray_tmax,
|
||||||
|
thread BoundingBoxIntersectionResult &result)
|
||||||
|
{
|
||||||
|
const uint visibility = payload.visibility;
|
||||||
|
|
||||||
|
float3 P = ray_origin;
|
||||||
|
float3 dir = ray_direction;
|
||||||
|
|
||||||
|
/* The direction is not normalized by default, but the point intersection routine expects that */
|
||||||
|
float len;
|
||||||
|
dir = normalize_len(dir, &len);
|
||||||
|
|
||||||
|
Intersection isect;
|
||||||
|
isect.t = ray_tmax;
|
||||||
|
/* Transform maximum distance into object space */
|
||||||
|
if (isect.t != FLT_MAX)
|
||||||
|
isect.t *= len;
|
||||||
|
|
||||||
|
MetalKernelContext context(launch_params_metal);
|
||||||
|
if (context.point_intersect(NULL, &isect, P, dir, isect.t, object, prim, time, type)) {
|
||||||
|
result.continue_search = metalrt_shadow_all_hit<METALRT_HIT_BOUNDING_BOX>(
|
||||||
|
launch_params_metal, payload, object, prim, float2(isect.u, isect.v), ray_tmax);
|
||||||
|
result.accept = !result.continue_search;
|
||||||
|
|
||||||
|
if (result.accept) {
|
||||||
|
result.distance = isect.t / len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[[intersection(bounding_box, triangle_data, METALRT_TAGS)]]
|
||||||
|
BoundingBoxIntersectionResult
|
||||||
|
__intersection__point(constant KernelParamsMetal &launch_params_metal [[buffer(1)]],
|
||||||
|
ray_data MetalKernelContext::MetalRTIntersectionPayload &payload [[payload]],
|
||||||
|
const uint object [[user_instance_id]],
|
||||||
|
const uint primitive_id [[primitive_id]],
|
||||||
|
const float3 ray_origin [[origin]],
|
||||||
|
const float3 ray_direction [[direction]],
|
||||||
|
const float ray_tmax [[max_distance]])
|
||||||
|
{
|
||||||
|
const uint prim = primitive_id + kernel_tex_fetch(__object_prim_offset, object);
|
||||||
|
const int type = kernel_tex_fetch(__objects, object).primitive_type;
|
||||||
|
|
||||||
|
BoundingBoxIntersectionResult result;
|
||||||
|
result.accept = false;
|
||||||
|
result.continue_search = true;
|
||||||
|
result.distance = ray_tmax;
|
||||||
|
|
||||||
|
metalrt_intersection_point(launch_params_metal, payload, object, prim, type, ray_origin, ray_direction,
|
||||||
|
# if defined(__METALRT_MOTION__)
|
||||||
|
payload.time,
|
||||||
|
# else
|
||||||
|
0.0f,
|
||||||
|
# endif
|
||||||
|
ray_tmax, result);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[intersection(bounding_box, triangle_data, METALRT_TAGS)]]
|
||||||
|
BoundingBoxIntersectionResult
|
||||||
|
__intersection__point_shadow(constant KernelParamsMetal &launch_params_metal [[buffer(1)]],
|
||||||
|
ray_data MetalKernelContext::MetalRTIntersectionShadowPayload &payload [[payload]],
|
||||||
|
const uint object [[user_instance_id]],
|
||||||
|
const uint primitive_id [[primitive_id]],
|
||||||
|
const float3 ray_origin [[origin]],
|
||||||
|
const float3 ray_direction [[direction]],
|
||||||
|
const float ray_tmax [[max_distance]])
|
||||||
|
{
|
||||||
|
const uint prim = primitive_id + kernel_tex_fetch(__object_prim_offset, object);
|
||||||
|
const int type = kernel_tex_fetch(__objects, object).primitive_type;
|
||||||
|
|
||||||
|
BoundingBoxIntersectionResult result;
|
||||||
|
result.accept = false;
|
||||||
|
result.continue_search = true;
|
||||||
|
result.distance = ray_tmax;
|
||||||
|
|
||||||
|
metalrt_intersection_point_shadow(launch_params_metal, payload, object, prim, type, ray_origin, ray_direction,
|
||||||
|
# if defined(__METALRT_MOTION__)
|
||||||
|
payload.time,
|
||||||
|
# else
|
||||||
|
0.0f,
|
||||||
|
# endif
|
||||||
|
ray_tmax, result);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#endif /* __POINTCLOUD__ */
|
||||||
#endif /* __METALRT__ */
|
#endif /* __METALRT__ */
|
||||||
|
@@ -92,6 +92,14 @@ ccl_device_forceinline void kernel_write_denoising_features_surface(
|
|||||||
else if (sc->type == CLOSURE_BSDF_HAIR_PRINCIPLED_ID) {
|
else if (sc->type == CLOSURE_BSDF_HAIR_PRINCIPLED_ID) {
|
||||||
closure_albedo *= bsdf_principled_hair_albedo(sc);
|
closure_albedo *= bsdf_principled_hair_albedo(sc);
|
||||||
}
|
}
|
||||||
|
else if (sc->type == CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID) {
|
||||||
|
/* BSSRDF already accounts for weight, retro-reflection would double up. */
|
||||||
|
ccl_private const PrincipledDiffuseBsdf *bsdf = (ccl_private const PrincipledDiffuseBsdf *)
|
||||||
|
sc;
|
||||||
|
if (bsdf->components == PRINCIPLED_DIFFUSE_RETRO_REFLECTION) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (bsdf_get_specular_roughness_squared(sc) > sqr(0.075f)) {
|
if (bsdf_get_specular_roughness_squared(sc) > sqr(0.075f)) {
|
||||||
diffuse_albedo += closure_albedo;
|
diffuse_albedo += closure_albedo;
|
||||||
|
@@ -214,6 +214,21 @@ ccl_device_inline void film_get_pass_pixel_light_path(
|
|||||||
pixel[0] = f.x;
|
pixel[0] = f.x;
|
||||||
pixel[1] = f.y;
|
pixel[1] = f.y;
|
||||||
pixel[2] = f.z;
|
pixel[2] = f.z;
|
||||||
|
|
||||||
|
/* Optional alpha channel. */
|
||||||
|
if (kfilm_convert->num_components >= 4) {
|
||||||
|
if (kfilm_convert->pass_combined != PASS_UNUSED) {
|
||||||
|
float scale, scale_exposure;
|
||||||
|
film_get_scale_and_scale_exposure(kfilm_convert, buffer, &scale, &scale_exposure);
|
||||||
|
|
||||||
|
ccl_global const float *in_combined = buffer + kfilm_convert->pass_combined;
|
||||||
|
const float alpha = in_combined[3] * scale;
|
||||||
|
pixel[3] = film_transparency_to_alpha(alpha);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pixel[3] = 1.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ccl_device_inline void film_get_pass_pixel_float3(ccl_global const KernelFilmConvert *ccl_restrict
|
ccl_device_inline void film_get_pass_pixel_float3(ccl_global const KernelFilmConvert *ccl_restrict
|
||||||
|
@@ -226,6 +226,18 @@ ccl_device float curve_thickness(KernelGlobals kg, ccl_private const ShaderData
|
|||||||
return r * 2.0f;
|
return r * 2.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Curve random */
|
||||||
|
|
||||||
|
ccl_device float curve_random(KernelGlobals kg, ccl_private const ShaderData *sd)
|
||||||
|
{
|
||||||
|
if (sd->type & PRIMITIVE_CURVE) {
|
||||||
|
const AttributeDescriptor desc = find_attribute(kg, sd, ATTR_STD_CURVE_RANDOM);
|
||||||
|
return (desc.offset != ATTR_STD_NOT_FOUND) ? curve_attribute_float(kg, sd, desc, NULL, NULL) :
|
||||||
|
0.0f;
|
||||||
|
}
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
/* Curve location for motion pass, linear interpolation between keys and
|
/* Curve location for motion pass, linear interpolation between keys and
|
||||||
* ignoring radius because we do the same for the motion keys */
|
* ignoring radius because we do the same for the motion keys */
|
||||||
|
|
||||||
|
@@ -153,14 +153,12 @@ ccl_device_inline bool motion_triangle_intersect(KernelGlobals kg,
|
|||||||
float time,
|
float time,
|
||||||
uint visibility,
|
uint visibility,
|
||||||
int object,
|
int object,
|
||||||
|
int prim,
|
||||||
int prim_addr)
|
int prim_addr)
|
||||||
{
|
{
|
||||||
/* Primitive index for vertex location lookup. */
|
|
||||||
int prim = kernel_tex_fetch(__prim_index, prim_addr);
|
|
||||||
int fobject = (object == OBJECT_NONE) ? kernel_tex_fetch(__prim_object, prim_addr) : object;
|
|
||||||
/* Get vertex locations for intersection. */
|
/* Get vertex locations for intersection. */
|
||||||
float3 verts[3];
|
float3 verts[3];
|
||||||
motion_triangle_vertices(kg, fobject, prim, time, verts);
|
motion_triangle_vertices(kg, object, prim, time, verts);
|
||||||
/* Ray-triangle intersection, unoptimized. */
|
/* Ray-triangle intersection, unoptimized. */
|
||||||
float t, u, v;
|
float t, u, v;
|
||||||
if (ray_triangle_intersect(P, dir, tmax, verts[0], verts[1], verts[2], &u, &v, &t)) {
|
if (ray_triangle_intersect(P, dir, tmax, verts[0], verts[1], verts[2], &u, &v, &t)) {
|
||||||
@@ -175,8 +173,7 @@ ccl_device_inline bool motion_triangle_intersect(KernelGlobals kg,
|
|||||||
isect->u = u;
|
isect->u = u;
|
||||||
isect->v = v;
|
isect->v = v;
|
||||||
isect->prim = prim;
|
isect->prim = prim;
|
||||||
isect->object = (object == OBJECT_NONE) ? kernel_tex_fetch(__prim_object, prim_addr) :
|
isect->object = object;
|
||||||
object;
|
|
||||||
isect->type = PRIMITIVE_MOTION_TRIANGLE;
|
isect->type = PRIMITIVE_MOTION_TRIANGLE;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -196,25 +193,15 @@ ccl_device_inline bool motion_triangle_intersect_local(KernelGlobals kg,
|
|||||||
float3 dir,
|
float3 dir,
|
||||||
float time,
|
float time,
|
||||||
int object,
|
int object,
|
||||||
int local_object,
|
int prim,
|
||||||
int prim_addr,
|
int prim_addr,
|
||||||
float tmax,
|
float tmax,
|
||||||
ccl_private uint *lcg_state,
|
ccl_private uint *lcg_state,
|
||||||
int max_hits)
|
int max_hits)
|
||||||
{
|
{
|
||||||
/* Only intersect with matching object, for instanced objects we
|
|
||||||
* already know we are only intersecting the right object. */
|
|
||||||
if (object == OBJECT_NONE) {
|
|
||||||
if (kernel_tex_fetch(__prim_object, prim_addr) != local_object) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Primitive index for vertex location lookup. */
|
|
||||||
int prim = kernel_tex_fetch(__prim_index, prim_addr);
|
|
||||||
/* Get vertex locations for intersection. */
|
/* Get vertex locations for intersection. */
|
||||||
float3 verts[3];
|
float3 verts[3];
|
||||||
motion_triangle_vertices(kg, local_object, prim, time, verts);
|
motion_triangle_vertices(kg, object, prim, time, verts);
|
||||||
/* Ray-triangle intersection, unoptimized. */
|
/* Ray-triangle intersection, unoptimized. */
|
||||||
float t, u, v;
|
float t, u, v;
|
||||||
if (!ray_triangle_intersect(P, dir, tmax, verts[0], verts[1], verts[2], &u, &v, &t)) {
|
if (!ray_triangle_intersect(P, dir, tmax, verts[0], verts[1], verts[2], &u, &v, &t)) {
|
||||||
@@ -266,7 +253,7 @@ ccl_device_inline bool motion_triangle_intersect_local(KernelGlobals kg,
|
|||||||
isect->u = u;
|
isect->u = u;
|
||||||
isect->v = v;
|
isect->v = v;
|
||||||
isect->prim = prim;
|
isect->prim = prim;
|
||||||
isect->object = local_object;
|
isect->object = object;
|
||||||
isect->type = PRIMITIVE_MOTION_TRIANGLE;
|
isect->type = PRIMITIVE_MOTION_TRIANGLE;
|
||||||
|
|
||||||
/* Record geometric normal. */
|
/* Record geometric normal. */
|
||||||
|
@@ -81,7 +81,7 @@ ccl_device float3 point_attribute_float3(KernelGlobals kg,
|
|||||||
# endif
|
# endif
|
||||||
|
|
||||||
if (desc.element == ATTR_ELEMENT_VERTEX) {
|
if (desc.element == ATTR_ELEMENT_VERTEX) {
|
||||||
return float4_to_float3(kernel_tex_fetch(__attributes_float4, desc.offset + sd->prim));
|
return kernel_tex_fetch(__attributes_float3, desc.offset + sd->prim);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return make_float3(0.0f, 0.0f, 0.0f);
|
return make_float3(0.0f, 0.0f, 0.0f);
|
||||||
@@ -109,17 +109,59 @@ ccl_device float4 point_attribute_float4(KernelGlobals kg,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Point position */
|
||||||
|
|
||||||
|
ccl_device float3 point_position(KernelGlobals kg, ccl_private const ShaderData *sd)
|
||||||
|
{
|
||||||
|
if (sd->type & PRIMITIVE_POINT) {
|
||||||
|
/* World space center. */
|
||||||
|
float3 P = (sd->type & PRIMITIVE_MOTION) ?
|
||||||
|
float4_to_float3(motion_point(kg, sd->object, sd->prim, sd->time)) :
|
||||||
|
float4_to_float3(kernel_tex_fetch(__points, sd->prim));
|
||||||
|
|
||||||
|
if (!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
|
||||||
|
object_position_transform(kg, sd, &P);
|
||||||
|
}
|
||||||
|
|
||||||
|
return P;
|
||||||
|
}
|
||||||
|
|
||||||
|
return zero_float3();
|
||||||
|
}
|
||||||
|
|
||||||
/* Point radius */
|
/* Point radius */
|
||||||
|
|
||||||
ccl_device float point_radius(KernelGlobals kg, ccl_private const ShaderData *sd)
|
ccl_device float point_radius(KernelGlobals kg, ccl_private const ShaderData *sd)
|
||||||
{
|
{
|
||||||
if (sd->type & PRIMITIVE_POINT) {
|
if (sd->type & PRIMITIVE_POINT) {
|
||||||
return kernel_tex_fetch(__points, sd->prim).w;
|
/* World space radius. */
|
||||||
|
const float r = kernel_tex_fetch(__points, sd->prim).w;
|
||||||
|
|
||||||
|
if (sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED) {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
float3 dir = make_float3(r, r, r);
|
||||||
|
object_dir_transform(kg, sd, &dir);
|
||||||
|
return average(dir);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Point random */
|
||||||
|
|
||||||
|
ccl_device float point_random(KernelGlobals kg, ccl_private const ShaderData *sd)
|
||||||
|
{
|
||||||
|
if (sd->type & PRIMITIVE_POINT) {
|
||||||
|
const AttributeDescriptor desc = find_attribute(kg, sd, ATTR_STD_POINT_RANDOM);
|
||||||
|
return (desc.offset != ATTR_STD_NOT_FOUND) ? point_attribute_float(kg, sd, desc, NULL, NULL) :
|
||||||
|
0.0f;
|
||||||
|
}
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
/* Point location for motion pass, linear interpolation between keys and
|
/* Point location for motion pass, linear interpolation between keys and
|
||||||
* ignoring radius because we do the same for the motion keys */
|
* ignoring radius because we do the same for the motion keys */
|
||||||
|
|
||||||
|
@@ -33,9 +33,9 @@ ccl_device_inline bool triangle_intersect(KernelGlobals kg,
|
|||||||
float tmax,
|
float tmax,
|
||||||
uint visibility,
|
uint visibility,
|
||||||
int object,
|
int object,
|
||||||
|
int prim,
|
||||||
int prim_addr)
|
int prim_addr)
|
||||||
{
|
{
|
||||||
const int prim = kernel_tex_fetch(__prim_index, prim_addr);
|
|
||||||
const uint tri_vindex = kernel_tex_fetch(__tri_vindex, prim).w;
|
const uint tri_vindex = kernel_tex_fetch(__tri_vindex, prim).w;
|
||||||
const float3 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_b = kernel_tex_fetch(__tri_verts, tri_vindex + 1),
|
||||||
@@ -49,8 +49,7 @@ ccl_device_inline bool triangle_intersect(KernelGlobals kg,
|
|||||||
if (kernel_tex_fetch(__prim_visibility, prim_addr) & visibility)
|
if (kernel_tex_fetch(__prim_visibility, prim_addr) & visibility)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
isect->object = (object == OBJECT_NONE) ? kernel_tex_fetch(__prim_object, prim_addr) :
|
isect->object = object;
|
||||||
object;
|
|
||||||
isect->prim = prim;
|
isect->prim = prim;
|
||||||
isect->type = PRIMITIVE_TRIANGLE;
|
isect->type = PRIMITIVE_TRIANGLE;
|
||||||
isect->u = u;
|
isect->u = u;
|
||||||
@@ -74,21 +73,12 @@ ccl_device_inline bool triangle_intersect_local(KernelGlobals kg,
|
|||||||
float3 P,
|
float3 P,
|
||||||
float3 dir,
|
float3 dir,
|
||||||
int object,
|
int object,
|
||||||
int local_object,
|
int prim,
|
||||||
int prim_addr,
|
int prim_addr,
|
||||||
float tmax,
|
float tmax,
|
||||||
ccl_private uint *lcg_state,
|
ccl_private uint *lcg_state,
|
||||||
int max_hits)
|
int max_hits)
|
||||||
{
|
{
|
||||||
/* Only intersect with matching object, for instanced objects we
|
|
||||||
* already know we are only intersecting the right object. */
|
|
||||||
if (object == OBJECT_NONE) {
|
|
||||||
if (kernel_tex_fetch(__prim_object, prim_addr) != local_object) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const int prim = kernel_tex_fetch(__prim_index, prim_addr);
|
|
||||||
const uint tri_vindex = kernel_tex_fetch(__tri_vindex, prim).w;
|
const uint tri_vindex = kernel_tex_fetch(__tri_vindex, prim).w;
|
||||||
const float3 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_b = kernel_tex_fetch(__tri_verts, tri_vindex + 1),
|
||||||
@@ -139,7 +129,7 @@ ccl_device_inline bool triangle_intersect_local(KernelGlobals kg,
|
|||||||
/* Record intersection. */
|
/* Record intersection. */
|
||||||
ccl_private Intersection *isect = &local_isect->hits[hit];
|
ccl_private Intersection *isect = &local_isect->hits[hit];
|
||||||
isect->prim = prim;
|
isect->prim = prim;
|
||||||
isect->object = local_object;
|
isect->object = object;
|
||||||
isect->type = PRIMITIVE_TRIANGLE;
|
isect->type = PRIMITIVE_TRIANGLE;
|
||||||
isect->u = u;
|
isect->u = u;
|
||||||
isect->v = v;
|
isect->v = v;
|
||||||
|
@@ -188,7 +188,7 @@ ccl_device_forceinline void integrate_surface_direct_light(KernelGlobals kg,
|
|||||||
const uint16_t transparent_bounce = INTEGRATOR_STATE(state, path, transparent_bounce);
|
const uint16_t transparent_bounce = INTEGRATOR_STATE(state, path, transparent_bounce);
|
||||||
uint32_t shadow_flag = INTEGRATOR_STATE(state, path, flag);
|
uint32_t shadow_flag = INTEGRATOR_STATE(state, path, flag);
|
||||||
shadow_flag |= (is_light) ? PATH_RAY_SHADOW_FOR_LIGHT : 0;
|
shadow_flag |= (is_light) ? PATH_RAY_SHADOW_FOR_LIGHT : 0;
|
||||||
shadow_flag |= PATH_RAY_SURFACE_PASS;
|
shadow_flag |= (shadow_flag & PATH_RAY_ANY_PASS) ? 0 : PATH_RAY_SURFACE_PASS;
|
||||||
const float3 throughput = INTEGRATOR_STATE(state, path, throughput) * bsdf_eval_sum(&bsdf_eval);
|
const float3 throughput = INTEGRATOR_STATE(state, path, throughput) * bsdf_eval_sum(&bsdf_eval);
|
||||||
|
|
||||||
if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) {
|
if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) {
|
||||||
|
@@ -797,7 +797,7 @@ ccl_device_forceinline void integrate_volume_direct_light(
|
|||||||
const uint16_t transparent_bounce = INTEGRATOR_STATE(state, path, transparent_bounce);
|
const uint16_t transparent_bounce = INTEGRATOR_STATE(state, path, transparent_bounce);
|
||||||
uint32_t shadow_flag = INTEGRATOR_STATE(state, path, flag);
|
uint32_t shadow_flag = INTEGRATOR_STATE(state, path, flag);
|
||||||
shadow_flag |= (is_light) ? PATH_RAY_SHADOW_FOR_LIGHT : 0;
|
shadow_flag |= (is_light) ? PATH_RAY_SHADOW_FOR_LIGHT : 0;
|
||||||
shadow_flag |= PATH_RAY_VOLUME_PASS;
|
shadow_flag |= (shadow_flag & PATH_RAY_ANY_PASS) ? 0 : PATH_RAY_VOLUME_PASS;
|
||||||
const float3 throughput_phase = throughput * bsdf_eval_sum(&phase_eval);
|
const float3 throughput_phase = throughput * bsdf_eval_sum(&phase_eval);
|
||||||
|
|
||||||
if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) {
|
if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) {
|
||||||
|
@@ -116,6 +116,8 @@ ustring OSLRenderServices::u_curve_tangent_normal("geom:curve_tangent_normal");
|
|||||||
ustring OSLRenderServices::u_curve_random("geom:curve_random");
|
ustring OSLRenderServices::u_curve_random("geom:curve_random");
|
||||||
ustring OSLRenderServices::u_is_point("geom:is_point");
|
ustring OSLRenderServices::u_is_point("geom:is_point");
|
||||||
ustring OSLRenderServices::u_point_radius("geom:point_radius");
|
ustring OSLRenderServices::u_point_radius("geom:point_radius");
|
||||||
|
ustring OSLRenderServices::u_point_position("geom:point_position");
|
||||||
|
ustring OSLRenderServices::u_point_random("geom:point_random");
|
||||||
ustring OSLRenderServices::u_normal_map_normal("geom:normal_map_normal");
|
ustring OSLRenderServices::u_normal_map_normal("geom:normal_map_normal");
|
||||||
ustring OSLRenderServices::u_path_ray_length("path:ray_length");
|
ustring OSLRenderServices::u_path_ray_length("path:ray_length");
|
||||||
ustring OSLRenderServices::u_path_ray_depth("path:ray_depth");
|
ustring OSLRenderServices::u_path_ray_depth("path:ray_depth");
|
||||||
@@ -999,6 +1001,10 @@ bool OSLRenderServices::get_object_standard_attribute(const KernelGlobalsCPU *kg
|
|||||||
float3 f = curve_tangent_normal(kg, sd);
|
float3 f = curve_tangent_normal(kg, sd);
|
||||||
return set_attribute_float3(f, type, derivatives, val);
|
return set_attribute_float3(f, type, derivatives, val);
|
||||||
}
|
}
|
||||||
|
else if (name == u_curve_random) {
|
||||||
|
float f = curve_random(kg, sd);
|
||||||
|
return set_attribute_float(f, type, derivatives, val);
|
||||||
|
}
|
||||||
/* point attributes */
|
/* point attributes */
|
||||||
else if (name == u_is_point) {
|
else if (name == u_is_point) {
|
||||||
float f = (sd->type & PRIMITIVE_POINT) != 0;
|
float f = (sd->type & PRIMITIVE_POINT) != 0;
|
||||||
@@ -1008,6 +1014,14 @@ bool OSLRenderServices::get_object_standard_attribute(const KernelGlobalsCPU *kg
|
|||||||
float f = point_radius(kg, sd);
|
float f = point_radius(kg, sd);
|
||||||
return set_attribute_float(f, type, derivatives, val);
|
return set_attribute_float(f, type, derivatives, val);
|
||||||
}
|
}
|
||||||
|
else if (name == u_point_position) {
|
||||||
|
float3 f = point_position(kg, sd);
|
||||||
|
return set_attribute_float3(f, type, derivatives, val);
|
||||||
|
}
|
||||||
|
else if (name == u_point_random) {
|
||||||
|
float f = point_random(kg, sd);
|
||||||
|
return set_attribute_float(f, type, derivatives, val);
|
||||||
|
}
|
||||||
else if (name == u_normal_map_normal) {
|
else if (name == u_normal_map_normal) {
|
||||||
if (sd->type & PRIMITIVE_TRIANGLE) {
|
if (sd->type & PRIMITIVE_TRIANGLE) {
|
||||||
float3 f = triangle_smooth_normal_unnormalized(kg, sd, sd->Ng, sd->prim, sd->u, sd->v);
|
float3 f = triangle_smooth_normal_unnormalized(kg, sd, sd->Ng, sd->prim, sd->u, sd->v);
|
||||||
|
@@ -298,7 +298,9 @@ class OSLRenderServices : public OSL::RendererServices {
|
|||||||
static ustring u_curve_tangent_normal;
|
static ustring u_curve_tangent_normal;
|
||||||
static ustring u_curve_random;
|
static ustring u_curve_random;
|
||||||
static ustring u_is_point;
|
static ustring u_is_point;
|
||||||
|
static ustring u_point_position;
|
||||||
static ustring u_point_radius;
|
static ustring u_point_radius;
|
||||||
|
static ustring u_point_random;
|
||||||
static ustring u_normal_map_normal;
|
static ustring u_normal_map_normal;
|
||||||
static ustring u_path_ray_length;
|
static ustring u_path_ray_length;
|
||||||
static ustring u_path_ray_depth;
|
static ustring u_path_ray_depth;
|
||||||
|
@@ -49,6 +49,7 @@ set(SRC_OSL
|
|||||||
node_glossy_bsdf.osl
|
node_glossy_bsdf.osl
|
||||||
node_gradient_texture.osl
|
node_gradient_texture.osl
|
||||||
node_hair_info.osl
|
node_hair_info.osl
|
||||||
|
node_point_info.osl
|
||||||
node_scatter_volume.osl
|
node_scatter_volume.osl
|
||||||
node_absorption_volume.osl
|
node_absorption_volume.osl
|
||||||
node_principled_volume.osl
|
node_principled_volume.osl
|
||||||
|
@@ -85,6 +85,4 @@ shader node_normal_map(normal NormalIn = N,
|
|||||||
|
|
||||||
if (Strength != 1.0)
|
if (Strength != 1.0)
|
||||||
Normal = normalize(NormalIn + (Normal - NormalIn) * max(Strength, 0.0));
|
Normal = normalize(NormalIn + (Normal - NormalIn) * max(Strength, 0.0));
|
||||||
|
|
||||||
Normal = ensure_valid_reflection(Ng, I, Normal);
|
|
||||||
}
|
}
|
||||||
|
26
intern/cycles/kernel/osl/shaders/node_point_info.osl
Normal file
26
intern/cycles/kernel/osl/shaders/node_point_info.osl
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2011-2022 Blender Foundation
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "stdcycles.h"
|
||||||
|
|
||||||
|
shader node_point_info(output point Position = point(0.0, 0.0, 0.0),
|
||||||
|
output float Radius = 0.0,
|
||||||
|
output float Random = 0.0)
|
||||||
|
{
|
||||||
|
getattribute("geom:point_position", Position);
|
||||||
|
getattribute("geom:point_radius", Radius);
|
||||||
|
getattribute("geom:point_random", Random);
|
||||||
|
}
|
@@ -87,7 +87,9 @@ ccl_device_noinline void svm_node_attr(KernelGlobals kg,
|
|||||||
if (node.y == ATTR_STD_GENERATED && desc.element == ATTR_ELEMENT_NONE) {
|
if (node.y == ATTR_STD_GENERATED && desc.element == ATTR_ELEMENT_NONE) {
|
||||||
/* No generated attribute, fall back to object coordinates. */
|
/* No generated attribute, fall back to object coordinates. */
|
||||||
float3 f = sd->P;
|
float3 f = sd->P;
|
||||||
object_inverse_position_transform(kg, sd, &f);
|
if (sd->object != OBJECT_NONE) {
|
||||||
|
object_inverse_position_transform(kg, sd, &f);
|
||||||
|
}
|
||||||
if (type == NODE_ATTR_OUTPUT_FLOAT) {
|
if (type == NODE_ATTR_OUTPUT_FLOAT) {
|
||||||
stack_store_float(stack, out_offset, average(f));
|
stack_store_float(stack, out_offset, average(f));
|
||||||
}
|
}
|
||||||
@@ -179,7 +181,9 @@ ccl_device_noinline void svm_node_attr_bump_dx(KernelGlobals kg,
|
|||||||
if (node.y == ATTR_STD_GENERATED && desc.element == ATTR_ELEMENT_NONE) {
|
if (node.y == ATTR_STD_GENERATED && desc.element == ATTR_ELEMENT_NONE) {
|
||||||
/* No generated attribute, fall back to object coordinates. */
|
/* No generated attribute, fall back to object coordinates. */
|
||||||
float3 f = sd->P + sd->dP.dx;
|
float3 f = sd->P + sd->dP.dx;
|
||||||
object_inverse_position_transform(kg, sd, &f);
|
if (sd->object != OBJECT_NONE) {
|
||||||
|
object_inverse_position_transform(kg, sd, &f);
|
||||||
|
}
|
||||||
if (type == NODE_ATTR_OUTPUT_FLOAT) {
|
if (type == NODE_ATTR_OUTPUT_FLOAT) {
|
||||||
stack_store_float(stack, out_offset, average(f));
|
stack_store_float(stack, out_offset, average(f));
|
||||||
}
|
}
|
||||||
@@ -275,7 +279,9 @@ ccl_device_noinline void svm_node_attr_bump_dy(KernelGlobals kg,
|
|||||||
if (node.y == ATTR_STD_GENERATED && desc.element == ATTR_ELEMENT_NONE) {
|
if (node.y == ATTR_STD_GENERATED && desc.element == ATTR_ELEMENT_NONE) {
|
||||||
/* No generated attribute, fall back to object coordinates. */
|
/* No generated attribute, fall back to object coordinates. */
|
||||||
float3 f = sd->P + sd->dP.dy;
|
float3 f = sd->P + sd->dP.dy;
|
||||||
object_inverse_position_transform(kg, sd, &f);
|
if (sd->object != OBJECT_NONE) {
|
||||||
|
object_inverse_position_transform(kg, sd, &f);
|
||||||
|
}
|
||||||
if (type == NODE_ATTR_OUTPUT_FLOAT) {
|
if (type == NODE_ATTR_OUTPUT_FLOAT) {
|
||||||
stack_store_float(stack, out_offset, average(f));
|
stack_store_float(stack, out_offset, average(f));
|
||||||
}
|
}
|
||||||
|
@@ -242,13 +242,6 @@ ccl_device_noinline void svm_node_hair_info(KernelGlobals kg,
|
|||||||
stack_store_float(stack, out_offset, data);
|
stack_store_float(stack, out_offset, data);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
# if 0
|
|
||||||
case NODE_INFO_CURVE_FADE: {
|
|
||||||
data = sd->curve_transparency;
|
|
||||||
stack_store_float(stack, out_offset, data);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
# endif
|
|
||||||
case NODE_INFO_CURVE_TANGENT_NORMAL: {
|
case NODE_INFO_CURVE_TANGENT_NORMAL: {
|
||||||
data3 = curve_tangent_normal(kg, sd);
|
data3 = curve_tangent_normal(kg, sd);
|
||||||
stack_store_float3(stack, out_offset, data3);
|
stack_store_float3(stack, out_offset, data3);
|
||||||
@@ -258,4 +251,28 @@ ccl_device_noinline void svm_node_hair_info(KernelGlobals kg,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __POINTCLOUD__
|
||||||
|
|
||||||
|
/* Point Info */
|
||||||
|
|
||||||
|
ccl_device_noinline void svm_node_point_info(KernelGlobals kg,
|
||||||
|
ccl_private ShaderData *sd,
|
||||||
|
ccl_private float *stack,
|
||||||
|
uint type,
|
||||||
|
uint out_offset)
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case NODE_INFO_POINT_POSITION:
|
||||||
|
stack_store_float3(stack, out_offset, point_position(kg, sd));
|
||||||
|
break;
|
||||||
|
case NODE_INFO_POINT_RADIUS:
|
||||||
|
stack_store_float(stack, out_offset, point_radius(kg, sd));
|
||||||
|
break;
|
||||||
|
case NODE_INFO_POINT_RANDOM:
|
||||||
|
break; /* handled as attribute */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
CCL_NAMESPACE_END
|
CCL_NAMESPACE_END
|
||||||
|
@@ -454,13 +454,14 @@ ccl_device void svm_eval_nodes(KernelGlobals kg,
|
|||||||
break;
|
break;
|
||||||
#if defined(__HAIR__)
|
#if defined(__HAIR__)
|
||||||
case NODE_HAIR_INFO:
|
case NODE_HAIR_INFO:
|
||||||
IF_KERNEL_NODES_FEATURE(HAIR)
|
svm_node_hair_info(kg, sd, stack, node.y, node.z);
|
||||||
{
|
break;
|
||||||
svm_node_hair_info(kg, sd, stack, node.y, node.z);
|
#endif
|
||||||
}
|
#if defined(__POINTCLOUD__)
|
||||||
|
case NODE_POINT_INFO:
|
||||||
|
svm_node_point_info(kg, sd, stack, node.y, node.z);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
case NODE_TEXTURE_MAPPING:
|
case NODE_TEXTURE_MAPPING:
|
||||||
offset = svm_node_texture_mapping(kg, sd, stack, node.y, node.z, offset);
|
offset = svm_node_texture_mapping(kg, sd, stack, node.y, node.z, offset);
|
||||||
break;
|
break;
|
||||||
|
@@ -81,6 +81,7 @@ typedef enum ShaderNodeType {
|
|||||||
NODE_OBJECT_INFO,
|
NODE_OBJECT_INFO,
|
||||||
NODE_PARTICLE_INFO,
|
NODE_PARTICLE_INFO,
|
||||||
NODE_HAIR_INFO,
|
NODE_HAIR_INFO,
|
||||||
|
NODE_POINT_INFO,
|
||||||
NODE_TEXTURE_MAPPING,
|
NODE_TEXTURE_MAPPING,
|
||||||
NODE_MAPPING,
|
NODE_MAPPING,
|
||||||
NODE_MIN_MAX,
|
NODE_MIN_MAX,
|
||||||
@@ -176,12 +177,16 @@ typedef enum NodeHairInfo {
|
|||||||
NODE_INFO_CURVE_INTERCEPT,
|
NODE_INFO_CURVE_INTERCEPT,
|
||||||
NODE_INFO_CURVE_LENGTH,
|
NODE_INFO_CURVE_LENGTH,
|
||||||
NODE_INFO_CURVE_THICKNESS,
|
NODE_INFO_CURVE_THICKNESS,
|
||||||
/* Fade for minimum hair width transiency. */
|
|
||||||
// NODE_INFO_CURVE_FADE,
|
|
||||||
NODE_INFO_CURVE_TANGENT_NORMAL,
|
NODE_INFO_CURVE_TANGENT_NORMAL,
|
||||||
NODE_INFO_CURVE_RANDOM,
|
NODE_INFO_CURVE_RANDOM,
|
||||||
} NodeHairInfo;
|
} NodeHairInfo;
|
||||||
|
|
||||||
|
typedef enum NodePointInfo {
|
||||||
|
NODE_INFO_POINT_POSITION,
|
||||||
|
NODE_INFO_POINT_RADIUS,
|
||||||
|
NODE_INFO_POINT_RANDOM,
|
||||||
|
} NodePointInfo;
|
||||||
|
|
||||||
typedef enum NodeLightPath {
|
typedef enum NodeLightPath {
|
||||||
NODE_LP_camera = 0,
|
NODE_LP_camera = 0,
|
||||||
NODE_LP_shadow,
|
NODE_LP_shadow,
|
||||||
|
@@ -1565,21 +1565,21 @@ enum KernelFeatureFlag : uint32_t {
|
|||||||
KERNEL_FEATURE_NODE_BSDF = (1U << 0U),
|
KERNEL_FEATURE_NODE_BSDF = (1U << 0U),
|
||||||
KERNEL_FEATURE_NODE_EMISSION = (1U << 1U),
|
KERNEL_FEATURE_NODE_EMISSION = (1U << 1U),
|
||||||
KERNEL_FEATURE_NODE_VOLUME = (1U << 2U),
|
KERNEL_FEATURE_NODE_VOLUME = (1U << 2U),
|
||||||
KERNEL_FEATURE_NODE_HAIR = (1U << 3U),
|
KERNEL_FEATURE_NODE_BUMP = (1U << 3U),
|
||||||
KERNEL_FEATURE_NODE_BUMP = (1U << 4U),
|
KERNEL_FEATURE_NODE_BUMP_STATE = (1U << 4U),
|
||||||
KERNEL_FEATURE_NODE_BUMP_STATE = (1U << 5U),
|
KERNEL_FEATURE_NODE_VORONOI_EXTRA = (1U << 5U),
|
||||||
KERNEL_FEATURE_NODE_VORONOI_EXTRA = (1U << 6U),
|
KERNEL_FEATURE_NODE_RAYTRACE = (1U << 6U),
|
||||||
KERNEL_FEATURE_NODE_RAYTRACE = (1U << 7U),
|
KERNEL_FEATURE_NODE_AOV = (1U << 7U),
|
||||||
KERNEL_FEATURE_NODE_AOV = (1U << 8U),
|
KERNEL_FEATURE_NODE_LIGHT_PATH = (1U << 8U),
|
||||||
KERNEL_FEATURE_NODE_LIGHT_PATH = (1U << 9U),
|
|
||||||
|
|
||||||
/* Use denoising kernels and output denoising passes. */
|
/* Use denoising kernels and output denoising passes. */
|
||||||
KERNEL_FEATURE_DENOISING = (1U << 10U),
|
KERNEL_FEATURE_DENOISING = (1U << 9U),
|
||||||
|
|
||||||
/* Use path tracing kernels. */
|
/* Use path tracing kernels. */
|
||||||
KERNEL_FEATURE_PATH_TRACING = (1U << 11U),
|
KERNEL_FEATURE_PATH_TRACING = (1U << 10U),
|
||||||
|
|
||||||
/* BVH/sampling kernel features. */
|
/* BVH/sampling kernel features. */
|
||||||
|
KERNEL_FEATURE_POINTCLOUD = (1U << 11U),
|
||||||
KERNEL_FEATURE_HAIR = (1U << 12U),
|
KERNEL_FEATURE_HAIR = (1U << 12U),
|
||||||
KERNEL_FEATURE_HAIR_THICK = (1U << 13U),
|
KERNEL_FEATURE_HAIR_THICK = (1U << 13U),
|
||||||
KERNEL_FEATURE_OBJECT_MOTION = (1U << 14U),
|
KERNEL_FEATURE_OBJECT_MOTION = (1U << 14U),
|
||||||
@@ -1616,9 +1616,6 @@ enum KernelFeatureFlag : uint32_t {
|
|||||||
KERNEL_FEATURE_AO_PASS = (1U << 25U),
|
KERNEL_FEATURE_AO_PASS = (1U << 25U),
|
||||||
KERNEL_FEATURE_AO_ADDITIVE = (1U << 26U),
|
KERNEL_FEATURE_AO_ADDITIVE = (1U << 26U),
|
||||||
KERNEL_FEATURE_AO = (KERNEL_FEATURE_AO_PASS | KERNEL_FEATURE_AO_ADDITIVE),
|
KERNEL_FEATURE_AO = (KERNEL_FEATURE_AO_PASS | KERNEL_FEATURE_AO_ADDITIVE),
|
||||||
|
|
||||||
/* Point clouds. */
|
|
||||||
KERNEL_FEATURE_POINTCLOUD = (1U << 27U),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Shader node feature mask, to specialize shader evaluation for kernels. */
|
/* Shader node feature mask, to specialize shader evaluation for kernels. */
|
||||||
@@ -1628,7 +1625,7 @@ enum KernelFeatureFlag : uint32_t {
|
|||||||
KERNEL_FEATURE_NODE_LIGHT_PATH)
|
KERNEL_FEATURE_NODE_LIGHT_PATH)
|
||||||
#define KERNEL_FEATURE_NODE_MASK_SURFACE_SHADOW \
|
#define KERNEL_FEATURE_NODE_MASK_SURFACE_SHADOW \
|
||||||
(KERNEL_FEATURE_NODE_BSDF | KERNEL_FEATURE_NODE_EMISSION | KERNEL_FEATURE_NODE_VOLUME | \
|
(KERNEL_FEATURE_NODE_BSDF | KERNEL_FEATURE_NODE_EMISSION | KERNEL_FEATURE_NODE_VOLUME | \
|
||||||
KERNEL_FEATURE_NODE_HAIR | KERNEL_FEATURE_NODE_BUMP | KERNEL_FEATURE_NODE_BUMP_STATE | \
|
KERNEL_FEATURE_NODE_BUMP | KERNEL_FEATURE_NODE_BUMP_STATE | \
|
||||||
KERNEL_FEATURE_NODE_VORONOI_EXTRA | KERNEL_FEATURE_NODE_LIGHT_PATH)
|
KERNEL_FEATURE_NODE_VORONOI_EXTRA | KERNEL_FEATURE_NODE_LIGHT_PATH)
|
||||||
#define KERNEL_FEATURE_NODE_MASK_SURFACE \
|
#define KERNEL_FEATURE_NODE_MASK_SURFACE \
|
||||||
(KERNEL_FEATURE_NODE_MASK_SURFACE_SHADOW | KERNEL_FEATURE_NODE_RAYTRACE | \
|
(KERNEL_FEATURE_NODE_MASK_SURFACE_SHADOW | KERNEL_FEATURE_NODE_RAYTRACE | \
|
||||||
|
@@ -742,6 +742,7 @@ NODE_DEFINE(AlembicProcedural)
|
|||||||
NodeType *type = NodeType::add("alembic", create);
|
NodeType *type = NodeType::add("alembic", create);
|
||||||
|
|
||||||
SOCKET_STRING(filepath, "Filename", ustring());
|
SOCKET_STRING(filepath, "Filename", ustring());
|
||||||
|
SOCKET_STRING_ARRAY(layers, "Layers", array<ustring>());
|
||||||
SOCKET_FLOAT(frame, "Frame", 1.0f);
|
SOCKET_FLOAT(frame, "Frame", 1.0f);
|
||||||
SOCKET_FLOAT(start_frame, "Start Frame", 1.0f);
|
SOCKET_FLOAT(start_frame, "Start Frame", 1.0f);
|
||||||
SOCKET_FLOAT(end_frame, "End Frame", 1.0f);
|
SOCKET_FLOAT(end_frame, "End Frame", 1.0f);
|
||||||
@@ -839,14 +840,26 @@ void AlembicProcedural::generate(Scene *scene, Progress &progress)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!archive.valid()) {
|
if (!archive.valid() || filepath_is_modified() || layers_is_modified()) {
|
||||||
Alembic::AbcCoreFactory::IFactory factory;
|
Alembic::AbcCoreFactory::IFactory factory;
|
||||||
factory.setPolicy(Alembic::Abc::ErrorHandler::kQuietNoopPolicy);
|
factory.setPolicy(Alembic::Abc::ErrorHandler::kQuietNoopPolicy);
|
||||||
archive = factory.getArchive(filepath.c_str());
|
|
||||||
|
std::vector<std::string> filenames;
|
||||||
|
filenames.push_back(filepath.c_str());
|
||||||
|
|
||||||
|
for (const ustring &layer : layers) {
|
||||||
|
filenames.push_back(layer.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We need to reverse the order as overriding archives should come first. */
|
||||||
|
std::reverse(filenames.begin(), filenames.end());
|
||||||
|
|
||||||
|
archive = factory.getArchive(filenames);
|
||||||
|
|
||||||
if (!archive.valid()) {
|
if (!archive.valid()) {
|
||||||
/* avoid potential infinite update loops in viewport synchronization */
|
/* avoid potential infinite update loops in viewport synchronization */
|
||||||
filepath.clear();
|
filepath.clear();
|
||||||
|
layers.clear();
|
||||||
clear_modified();
|
clear_modified();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1165,6 +1178,12 @@ void AlembicProcedural::read_subd(AlembicObject *abc_object, Abc::chrono_t frame
|
|||||||
cached_data.subd_creases_weight.copy_to_socket(
|
cached_data.subd_creases_weight.copy_to_socket(
|
||||||
frame_time, mesh, mesh->get_subd_creases_weight_socket());
|
frame_time, mesh, mesh->get_subd_creases_weight_socket());
|
||||||
|
|
||||||
|
cached_data.subd_vertex_crease_indices.copy_to_socket(
|
||||||
|
frame_time, mesh, mesh->get_subd_vert_creases_socket());
|
||||||
|
|
||||||
|
cached_data.subd_vertex_crease_weights.copy_to_socket(
|
||||||
|
frame_time, mesh, mesh->get_subd_vert_creases_weight_socket());
|
||||||
|
|
||||||
mesh->set_num_subd_faces(mesh->get_subd_shader().size());
|
mesh->set_num_subd_faces(mesh->get_subd_shader().size());
|
||||||
|
|
||||||
/* Update attributes. */
|
/* Update attributes. */
|
||||||
|
@@ -320,6 +320,8 @@ struct CachedData {
|
|||||||
DataStore<int> num_ngons;
|
DataStore<int> num_ngons;
|
||||||
DataStore<array<int>> subd_creases_edge;
|
DataStore<array<int>> subd_creases_edge;
|
||||||
DataStore<array<float>> subd_creases_weight;
|
DataStore<array<float>> subd_creases_weight;
|
||||||
|
DataStore<array<int>> subd_vertex_crease_indices;
|
||||||
|
DataStore<array<float>> subd_vertex_crease_weights;
|
||||||
|
|
||||||
/* hair data */
|
/* hair data */
|
||||||
DataStore<array<float3>> curve_keys;
|
DataStore<array<float3>> curve_keys;
|
||||||
@@ -479,6 +481,10 @@ class AlembicProcedural : public Procedural {
|
|||||||
/* The file path to the Alembic archive */
|
/* The file path to the Alembic archive */
|
||||||
NODE_SOCKET_API(ustring, filepath)
|
NODE_SOCKET_API(ustring, filepath)
|
||||||
|
|
||||||
|
/* Layers for the Alembic archive. Layers are in the order in which they override data, with the
|
||||||
|
* latter elements overriding the former ones. */
|
||||||
|
NODE_SOCKET_API_ARRAY(array<ustring>, layers)
|
||||||
|
|
||||||
/* The current frame to render. */
|
/* The current frame to render. */
|
||||||
NODE_SOCKET_API(float, frame)
|
NODE_SOCKET_API(float, frame)
|
||||||
|
|
||||||
|
@@ -478,7 +478,9 @@ static void add_subd_polygons(CachedData &cached_data, const SubDSchemaData &dat
|
|||||||
cached_data.uv_loops.add_data(uv_loops, time);
|
cached_data.uv_loops.add_data(uv_loops, time);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_subd_creases(CachedData &cached_data, const SubDSchemaData &data, chrono_t time)
|
static void add_subd_edge_creases(CachedData &cached_data,
|
||||||
|
const SubDSchemaData &data,
|
||||||
|
chrono_t time)
|
||||||
{
|
{
|
||||||
if (!(data.crease_indices.valid() && data.crease_indices.valid() &&
|
if (!(data.crease_indices.valid() && data.crease_indices.valid() &&
|
||||||
data.crease_sharpnesses.valid())) {
|
data.crease_sharpnesses.valid())) {
|
||||||
@@ -517,6 +519,37 @@ static void add_subd_creases(CachedData &cached_data, const SubDSchemaData &data
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void add_subd_vertex_creases(CachedData &cached_data,
|
||||||
|
const SubDSchemaData &data,
|
||||||
|
chrono_t time)
|
||||||
|
{
|
||||||
|
if (!(data.corner_indices.valid() && data.crease_sharpnesses.valid())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ISampleSelector iss = ISampleSelector(time);
|
||||||
|
const Int32ArraySamplePtr creases_indices = data.crease_indices.getValue(iss);
|
||||||
|
const FloatArraySamplePtr creases_sharpnesses = data.crease_sharpnesses.getValue(iss);
|
||||||
|
|
||||||
|
if (!(creases_indices && creases_sharpnesses) ||
|
||||||
|
creases_indices->size() != creases_sharpnesses->size()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
array<float> sharpnesses;
|
||||||
|
sharpnesses.reserve(creases_indices->size());
|
||||||
|
array<int> indices;
|
||||||
|
indices.reserve(creases_indices->size());
|
||||||
|
|
||||||
|
for (size_t i = 0; i < creases_indices->size(); i++) {
|
||||||
|
indices.push_back_reserved((*creases_indices)[i]);
|
||||||
|
sharpnesses.push_back_reserved((*creases_sharpnesses)[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
cached_data.subd_vertex_crease_indices.add_data(indices, time);
|
||||||
|
cached_data.subd_vertex_crease_weights.add_data(sharpnesses, time);
|
||||||
|
}
|
||||||
|
|
||||||
static void read_subd_geometry(CachedData &cached_data, const SubDSchemaData &data, chrono_t time)
|
static void read_subd_geometry(CachedData &cached_data, const SubDSchemaData &data, chrono_t time)
|
||||||
{
|
{
|
||||||
const ISampleSelector iss = ISampleSelector(time);
|
const ISampleSelector iss = ISampleSelector(time);
|
||||||
@@ -525,7 +558,8 @@ static void read_subd_geometry(CachedData &cached_data, const SubDSchemaData &da
|
|||||||
|
|
||||||
if (data.topology_variance != kHomogenousTopology || cached_data.shader.size() == 0) {
|
if (data.topology_variance != kHomogenousTopology || cached_data.shader.size() == 0) {
|
||||||
add_subd_polygons(cached_data, data, time);
|
add_subd_polygons(cached_data, data, time);
|
||||||
add_subd_creases(cached_data, data, time);
|
add_subd_edge_creases(cached_data, data, time);
|
||||||
|
add_subd_vertex_creases(cached_data, data, time);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -76,9 +76,10 @@ struct SubDSchemaData {
|
|||||||
|
|
||||||
vector<FaceSetShaderIndexPair> shader_face_sets;
|
vector<FaceSetShaderIndexPair> shader_face_sets;
|
||||||
|
|
||||||
// Those are unsupported for now.
|
|
||||||
Alembic::AbcGeom::IInt32ArrayProperty corner_indices;
|
Alembic::AbcGeom::IInt32ArrayProperty corner_indices;
|
||||||
Alembic::AbcGeom::IFloatArrayProperty corner_sharpnesses;
|
Alembic::AbcGeom::IFloatArrayProperty corner_sharpnesses;
|
||||||
|
|
||||||
|
// Those are unsupported for now.
|
||||||
Alembic::AbcGeom::IInt32Property face_varying_interpolate_boundary;
|
Alembic::AbcGeom::IInt32Property face_varying_interpolate_boundary;
|
||||||
Alembic::AbcGeom::IInt32Property face_varying_propagate_corners;
|
Alembic::AbcGeom::IInt32Property face_varying_propagate_corners;
|
||||||
Alembic::AbcGeom::IInt32Property interpolate_boundary;
|
Alembic::AbcGeom::IInt32Property interpolate_boundary;
|
||||||
|
@@ -263,7 +263,9 @@ template<typename T> inline void cast_from_float4(T *data, float4 value)
|
|||||||
|
|
||||||
/* Slower versions for other all data types, which needs to convert to float and back. */
|
/* Slower versions for other all data types, which needs to convert to float and back. */
|
||||||
template<typename T, bool compress_as_srgb = false>
|
template<typename T, bool compress_as_srgb = false>
|
||||||
inline void processor_apply_pixels(const OCIO::Processor *processor, T *pixels, size_t num_pixels)
|
inline void processor_apply_pixels_rgba(const OCIO::Processor *processor,
|
||||||
|
T *pixels,
|
||||||
|
size_t num_pixels)
|
||||||
{
|
{
|
||||||
/* TODO: implement faster version for when we know the conversion
|
/* TODO: implement faster version for when we know the conversion
|
||||||
* is a simple matrix transform between linear spaces. In that case
|
* is a simple matrix transform between linear spaces. In that case
|
||||||
@@ -310,25 +312,79 @@ inline void processor_apply_pixels(const OCIO::Processor *processor, T *pixels,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T, bool compress_as_srgb = false>
|
||||||
|
inline void processor_apply_pixels_grayscale(const OCIO::Processor *processor,
|
||||||
|
T *pixels,
|
||||||
|
size_t num_pixels)
|
||||||
|
{
|
||||||
|
OCIO::ConstCPUProcessorRcPtr device_processor = processor->getDefaultCPUProcessor();
|
||||||
|
|
||||||
|
/* Process large images in chunks to keep temporary memory requirement down. */
|
||||||
|
const size_t chunk_size = std::min((size_t)(16 * 1024 * 1024), num_pixels);
|
||||||
|
vector<float> float_pixels(chunk_size * 3);
|
||||||
|
|
||||||
|
for (size_t j = 0; j < num_pixels; j += chunk_size) {
|
||||||
|
size_t width = std::min(chunk_size, num_pixels - j);
|
||||||
|
|
||||||
|
/* Convert to 3 channels, since that's the minimum required by OpenColorIO. */
|
||||||
|
{
|
||||||
|
const T *pixel = pixels + j;
|
||||||
|
float *fpixel = float_pixels.data();
|
||||||
|
for (size_t i = 0; i < width; i++, pixel++, fpixel += 3) {
|
||||||
|
const float f = util_image_cast_to_float<T>(*pixel);
|
||||||
|
fpixel[0] = f;
|
||||||
|
fpixel[1] = f;
|
||||||
|
fpixel[2] = f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OCIO::PackedImageDesc desc((float *)float_pixels.data(), width, 1, 3);
|
||||||
|
device_processor->apply(desc);
|
||||||
|
|
||||||
|
{
|
||||||
|
T *pixel = pixels + j;
|
||||||
|
const float *fpixel = float_pixels.data();
|
||||||
|
for (size_t i = 0; i < width; i++, pixel++, fpixel += 3) {
|
||||||
|
float f = average(make_float3(fpixel[0], fpixel[1], fpixel[2]));
|
||||||
|
if (compress_as_srgb) {
|
||||||
|
f = color_linear_to_srgb(f);
|
||||||
|
}
|
||||||
|
*pixel = util_image_cast_from_float<T>(f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void ColorSpaceManager::to_scene_linear(ustring colorspace,
|
void ColorSpaceManager::to_scene_linear(
|
||||||
T *pixels,
|
ustring colorspace, T *pixels, size_t num_pixels, bool is_rgba, bool compress_as_srgb)
|
||||||
size_t num_pixels,
|
|
||||||
bool compress_as_srgb)
|
|
||||||
{
|
{
|
||||||
#ifdef WITH_OCIO
|
#ifdef WITH_OCIO
|
||||||
const OCIO::Processor *processor = (const OCIO::Processor *)get_processor(colorspace);
|
const OCIO::Processor *processor = (const OCIO::Processor *)get_processor(colorspace);
|
||||||
|
|
||||||
if (processor) {
|
if (processor) {
|
||||||
if (compress_as_srgb) {
|
if (is_rgba) {
|
||||||
/* Compress output as sRGB. */
|
if (compress_as_srgb) {
|
||||||
processor_apply_pixels<T, true>(processor, pixels, num_pixels);
|
/* Compress output as sRGB. */
|
||||||
|
processor_apply_pixels_rgba<T, true>(processor, pixels, num_pixels);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Write output as scene linear directly. */
|
||||||
|
processor_apply_pixels_rgba<T>(processor, pixels, num_pixels);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Write output as scene linear directly. */
|
if (compress_as_srgb) {
|
||||||
processor_apply_pixels<T>(processor, pixels, num_pixels);
|
/* Compress output as sRGB. */
|
||||||
|
processor_apply_pixels_grayscale<T, true>(processor, pixels, num_pixels);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Write output as scene linear directly. */
|
||||||
|
processor_apply_pixels_grayscale<T>(processor, pixels, num_pixels);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
@@ -348,6 +404,11 @@ void ColorSpaceManager::to_scene_linear(ColorSpaceProcessor *processor_,
|
|||||||
|
|
||||||
if (processor) {
|
if (processor) {
|
||||||
OCIO::ConstCPUProcessorRcPtr device_processor = processor->getDefaultCPUProcessor();
|
OCIO::ConstCPUProcessorRcPtr device_processor = processor->getDefaultCPUProcessor();
|
||||||
|
if (channels == 1) {
|
||||||
|
float3 rgb = make_float3(pixel[0], pixel[0], pixel[0]);
|
||||||
|
device_processor->applyRGB(&rgb.x);
|
||||||
|
pixel[0] = average(rgb);
|
||||||
|
}
|
||||||
if (channels == 3) {
|
if (channels == 3) {
|
||||||
device_processor->applyRGB(pixel);
|
device_processor->applyRGB(pixel);
|
||||||
}
|
}
|
||||||
@@ -390,9 +451,9 @@ void ColorSpaceManager::free_memory()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Template instantiations so we don't have to inline functions. */
|
/* Template instantiations so we don't have to inline functions. */
|
||||||
template void ColorSpaceManager::to_scene_linear(ustring, uchar *, size_t, bool);
|
template void ColorSpaceManager::to_scene_linear(ustring, uchar *, size_t, bool, bool);
|
||||||
template void ColorSpaceManager::to_scene_linear(ustring, ushort *, size_t, bool);
|
template void ColorSpaceManager::to_scene_linear(ustring, ushort *, size_t, bool, bool);
|
||||||
template void ColorSpaceManager::to_scene_linear(ustring, half *, size_t, bool);
|
template void ColorSpaceManager::to_scene_linear(ustring, half *, size_t, bool, bool);
|
||||||
template void ColorSpaceManager::to_scene_linear(ustring, float *, size_t, bool);
|
template void ColorSpaceManager::to_scene_linear(ustring, float *, size_t, bool, bool);
|
||||||
|
|
||||||
CCL_NAMESPACE_END
|
CCL_NAMESPACE_END
|
||||||
|
@@ -43,10 +43,8 @@ class ColorSpaceManager {
|
|||||||
/* Convert pixels in the specified colorspace to scene linear color for
|
/* Convert pixels in the specified colorspace to scene linear color for
|
||||||
* rendering. Must be a colorspace returned from detect_known_colorspace. */
|
* rendering. Must be a colorspace returned from detect_known_colorspace. */
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static void to_scene_linear(ustring colorspace,
|
static void to_scene_linear(
|
||||||
T *pixels,
|
ustring colorspace, T *pixels, size_t num_pixels, bool is_rgba, bool compress_as_srgb);
|
||||||
size_t num_pixels,
|
|
||||||
bool compress_as_srgb);
|
|
||||||
|
|
||||||
/* Efficiently convert pixels to scene linear colorspace at render time,
|
/* Efficiently convert pixels to scene linear colorspace at render time,
|
||||||
* for OSL where the image texture cache contains original pixels. The
|
* for OSL where the image texture cache contains original pixels. The
|
||||||
|
@@ -441,9 +441,13 @@ void ConstantFolder::fold_mapping(NodeMappingType type) const
|
|||||||
if (is_zero(scale_in)) {
|
if (is_zero(scale_in)) {
|
||||||
make_zero();
|
make_zero();
|
||||||
}
|
}
|
||||||
else if ((is_zero(location_in) || type == NODE_MAPPING_TYPE_VECTOR ||
|
else if (
|
||||||
type == NODE_MAPPING_TYPE_NORMAL) &&
|
/* Can't constant fold since we always need to normalize the output. */
|
||||||
is_zero(rotation_in) && is_one(scale_in)) {
|
(type != NODE_MAPPING_TYPE_NORMAL) &&
|
||||||
|
/* Check all use values are zero, note location is not used by vector and normal types. */
|
||||||
|
(is_zero(location_in) || type == NODE_MAPPING_TYPE_VECTOR ||
|
||||||
|
type == NODE_MAPPING_TYPE_NORMAL) &&
|
||||||
|
is_zero(rotation_in) && is_one(scale_in)) {
|
||||||
try_bypass_or_make_constant(vector_in);
|
try_bypass_or_make_constant(vector_in);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -236,6 +236,7 @@ void Geometry::compute_bvh(
|
|||||||
|
|
||||||
BVHParams bparams;
|
BVHParams bparams;
|
||||||
bparams.use_spatial_split = params->use_bvh_spatial_split;
|
bparams.use_spatial_split = params->use_bvh_spatial_split;
|
||||||
|
bparams.use_compact_structure = params->use_bvh_compact_structure;
|
||||||
bparams.bvh_layout = bvh_layout;
|
bparams.bvh_layout = bvh_layout;
|
||||||
bparams.use_unaligned_nodes = dscene->data.bvh.have_curves &&
|
bparams.use_unaligned_nodes = dscene->data.bvh.have_curves &&
|
||||||
params->use_bvh_unaligned_nodes;
|
params->use_bvh_unaligned_nodes;
|
||||||
|
@@ -576,13 +576,13 @@ bool ImageManager::file_load_image(Image *img, int texture_limit)
|
|||||||
pixels[i * 4 + 3] = one;
|
pixels[i * 4 + 3] = one;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (img->metadata.colorspace != u_colorspace_raw &&
|
if (img->metadata.colorspace != u_colorspace_raw &&
|
||||||
img->metadata.colorspace != u_colorspace_srgb) {
|
img->metadata.colorspace != u_colorspace_srgb) {
|
||||||
/* Convert to scene linear. */
|
/* Convert to scene linear. */
|
||||||
ColorSpaceManager::to_scene_linear(
|
ColorSpaceManager::to_scene_linear(
|
||||||
img->metadata.colorspace, pixels, num_pixels, img->metadata.compress_as_srgb);
|
img->metadata.colorspace, pixels, num_pixels, is_rgba, img->metadata.compress_as_srgb);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make sure we don't have buggy values. */
|
/* Make sure we don't have buggy values. */
|
||||||
@@ -891,6 +891,10 @@ void ImageManager::device_free(Device *device)
|
|||||||
void ImageManager::collect_statistics(RenderStats *stats)
|
void ImageManager::collect_statistics(RenderStats *stats)
|
||||||
{
|
{
|
||||||
foreach (const Image *image, images) {
|
foreach (const Image *image, images) {
|
||||||
|
if (!image) {
|
||||||
|
/* Image may have been freed due to lack of users. */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
stats->image.textures.add_entry(
|
stats->image.textures.add_entry(
|
||||||
NamedSizeEntry(image->loader->name(), image->mem->memory_size()));
|
NamedSizeEntry(image->loader->name(), image->mem->memory_size()));
|
||||||
}
|
}
|
||||||
|
@@ -141,6 +141,9 @@ NODE_DEFINE(Mesh)
|
|||||||
subdivision_type_enum.insert("catmull_clark", SUBDIVISION_CATMULL_CLARK);
|
subdivision_type_enum.insert("catmull_clark", SUBDIVISION_CATMULL_CLARK);
|
||||||
SOCKET_ENUM(subdivision_type, "Subdivision Type", subdivision_type_enum, SUBDIVISION_NONE);
|
SOCKET_ENUM(subdivision_type, "Subdivision Type", subdivision_type_enum, SUBDIVISION_NONE);
|
||||||
|
|
||||||
|
SOCKET_INT_ARRAY(subd_vert_creases, "Subdivision Vertex Crease", array<int>());
|
||||||
|
SOCKET_FLOAT_ARRAY(
|
||||||
|
subd_vert_creases_weight, "Subdivision Vertex Crease Weights", array<float>());
|
||||||
SOCKET_INT_ARRAY(subd_creases_edge, "Subdivision Crease Edges", array<int>());
|
SOCKET_INT_ARRAY(subd_creases_edge, "Subdivision Crease Edges", array<int>());
|
||||||
SOCKET_FLOAT_ARRAY(subd_creases_weight, "Subdivision Crease Weights", array<float>());
|
SOCKET_FLOAT_ARRAY(subd_creases_weight, "Subdivision Crease Weights", array<float>());
|
||||||
SOCKET_INT_ARRAY(subd_face_corners, "Subdivision Face Corners", array<int>());
|
SOCKET_INT_ARRAY(subd_face_corners, "Subdivision Face Corners", array<int>());
|
||||||
@@ -408,7 +411,7 @@ Mesh::SubdFace Mesh::get_subd_face(size_t index) const
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mesh::add_crease(int v0, int v1, float weight)
|
void Mesh::add_edge_crease(int v0, int v1, float weight)
|
||||||
{
|
{
|
||||||
subd_creases_edge.push_back_slow(v0);
|
subd_creases_edge.push_back_slow(v0);
|
||||||
subd_creases_edge.push_back_slow(v1);
|
subd_creases_edge.push_back_slow(v1);
|
||||||
@@ -419,6 +422,17 @@ void Mesh::add_crease(int v0, int v1, float weight)
|
|||||||
tag_subd_creases_weight_modified();
|
tag_subd_creases_weight_modified();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Mesh::add_vertex_crease(int v, float weight)
|
||||||
|
{
|
||||||
|
assert(v < verts.size());
|
||||||
|
|
||||||
|
subd_vert_creases.push_back_slow(v);
|
||||||
|
subd_vert_creases_weight.push_back_slow(weight);
|
||||||
|
|
||||||
|
tag_subd_vert_creases_modified();
|
||||||
|
tag_subd_vert_creases_weight_modified();
|
||||||
|
}
|
||||||
|
|
||||||
void Mesh::copy_center_to_motion_step(const int motion_step)
|
void Mesh::copy_center_to_motion_step(const int motion_step)
|
||||||
{
|
{
|
||||||
Attribute *attr_mP = attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
|
Attribute *attr_mP = attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
|
||||||
|
@@ -160,6 +160,9 @@ class Mesh : public Geometry {
|
|||||||
NODE_SOCKET_API_ARRAY(array<int>, subd_creases_edge)
|
NODE_SOCKET_API_ARRAY(array<int>, subd_creases_edge)
|
||||||
NODE_SOCKET_API_ARRAY(array<float>, subd_creases_weight)
|
NODE_SOCKET_API_ARRAY(array<float>, subd_creases_weight)
|
||||||
|
|
||||||
|
NODE_SOCKET_API_ARRAY(array<int>, subd_vert_creases)
|
||||||
|
NODE_SOCKET_API_ARRAY(array<float>, subd_vert_creases_weight)
|
||||||
|
|
||||||
/* Subdivisions parameters */
|
/* Subdivisions parameters */
|
||||||
NODE_SOCKET_API(float, subd_dicing_rate)
|
NODE_SOCKET_API(float, subd_dicing_rate)
|
||||||
NODE_SOCKET_API(int, subd_max_level)
|
NODE_SOCKET_API(int, subd_max_level)
|
||||||
@@ -210,7 +213,8 @@ class Mesh : public Geometry {
|
|||||||
void add_vertex_slow(float3 P);
|
void add_vertex_slow(float3 P);
|
||||||
void add_triangle(int v0, int v1, int v2, int shader, bool smooth);
|
void add_triangle(int v0, int v1, int v2, int shader, bool smooth);
|
||||||
void add_subd_face(int *corners, int num_corners, int shader_, bool smooth_);
|
void add_subd_face(int *corners, int num_corners, int shader_, bool smooth_);
|
||||||
void add_crease(int v0, int v1, float weight);
|
void add_edge_crease(int v0, int v1, float weight);
|
||||||
|
void add_vertex_crease(int v, float weight);
|
||||||
|
|
||||||
void copy_center_to_motion_step(const int motion_step);
|
void copy_center_to_motion_step(const int motion_step);
|
||||||
|
|
||||||
|
@@ -82,24 +82,54 @@ template<>
|
|||||||
bool TopologyRefinerFactory<ccl::Mesh>::assignComponentTags(TopologyRefiner &refiner,
|
bool TopologyRefinerFactory<ccl::Mesh>::assignComponentTags(TopologyRefiner &refiner,
|
||||||
ccl::Mesh const &mesh)
|
ccl::Mesh const &mesh)
|
||||||
{
|
{
|
||||||
|
/* Historical maximum crease weight used at Pixar, influencing the maximum in OpenSubDiv. */
|
||||||
|
static constexpr float CREASE_SCALE = 10.0f;
|
||||||
|
|
||||||
size_t num_creases = mesh.get_subd_creases_weight().size();
|
size_t num_creases = mesh.get_subd_creases_weight().size();
|
||||||
|
size_t num_vertex_creases = mesh.get_subd_vert_creases().size();
|
||||||
|
|
||||||
|
/* The last loop is over the vertices, so early exit to avoid iterating them needlessly. */
|
||||||
|
if (num_creases == 0 && num_vertex_creases == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < num_creases; i++) {
|
for (int i = 0; i < num_creases; i++) {
|
||||||
ccl::Mesh::SubdEdgeCrease crease = mesh.get_subd_crease(i);
|
ccl::Mesh::SubdEdgeCrease crease = mesh.get_subd_crease(i);
|
||||||
Index edge = findBaseEdge(refiner, crease.v[0], crease.v[1]);
|
Index edge = findBaseEdge(refiner, crease.v[0], crease.v[1]);
|
||||||
|
|
||||||
if (edge != INDEX_INVALID) {
|
if (edge != INDEX_INVALID) {
|
||||||
setBaseEdgeSharpness(refiner, edge, crease.crease * 10.0f);
|
setBaseEdgeSharpness(refiner, edge, crease.crease * CREASE_SCALE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::map<int, float> vertex_creases;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < num_vertex_creases; ++i) {
|
||||||
|
const int vertex_idx = mesh.get_subd_vert_creases()[i];
|
||||||
|
const float weight = mesh.get_subd_vert_creases_weight()[i];
|
||||||
|
|
||||||
|
vertex_creases[vertex_idx] = weight * CREASE_SCALE;
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < mesh.get_verts().size(); i++) {
|
for (int i = 0; i < mesh.get_verts().size(); i++) {
|
||||||
|
float sharpness = 0.0f;
|
||||||
|
std::map<int, float>::const_iterator iter = vertex_creases.find(i);
|
||||||
|
|
||||||
|
if (iter != vertex_creases.end()) {
|
||||||
|
sharpness = iter->second;
|
||||||
|
}
|
||||||
|
|
||||||
ConstIndexArray vert_edges = getBaseVertexEdges(refiner, i);
|
ConstIndexArray vert_edges = getBaseVertexEdges(refiner, i);
|
||||||
|
|
||||||
if (vert_edges.size() == 2) {
|
if (vert_edges.size() == 2) {
|
||||||
float sharpness = refiner.getLevel(0).getEdgeSharpness(vert_edges[0]);
|
const float sharpness0 = refiner.getLevel(0).getEdgeSharpness(vert_edges[0]);
|
||||||
sharpness = ccl::min(sharpness, refiner.getLevel(0).getEdgeSharpness(vert_edges[1]));
|
const float sharpness1 = refiner.getLevel(0).getEdgeSharpness(vert_edges[1]);
|
||||||
|
|
||||||
|
sharpness += ccl::min(sharpness0, sharpness1);
|
||||||
|
sharpness = ccl::min(sharpness, CREASE_SCALE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sharpness != 0.0f) {
|
||||||
setBaseVertexSharpness(refiner, i, sharpness);
|
setBaseVertexSharpness(refiner, i, sharpness);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -570,7 +570,6 @@ static void log_kernel_features(const uint features)
|
|||||||
<< "\n";
|
<< "\n";
|
||||||
VLOG(2) << "Use Emission " << string_from_bool(features & KERNEL_FEATURE_NODE_EMISSION) << "\n";
|
VLOG(2) << "Use Emission " << string_from_bool(features & KERNEL_FEATURE_NODE_EMISSION) << "\n";
|
||||||
VLOG(2) << "Use Volume " << string_from_bool(features & KERNEL_FEATURE_NODE_VOLUME) << "\n";
|
VLOG(2) << "Use Volume " << string_from_bool(features & KERNEL_FEATURE_NODE_VOLUME) << "\n";
|
||||||
VLOG(2) << "Use Hair " << string_from_bool(features & KERNEL_FEATURE_NODE_HAIR) << "\n";
|
|
||||||
VLOG(2) << "Use Bump " << string_from_bool(features & KERNEL_FEATURE_NODE_BUMP) << "\n";
|
VLOG(2) << "Use Bump " << string_from_bool(features & KERNEL_FEATURE_NODE_BUMP) << "\n";
|
||||||
VLOG(2) << "Use Voronoi " << string_from_bool(features & KERNEL_FEATURE_NODE_VORONOI_EXTRA)
|
VLOG(2) << "Use Voronoi " << string_from_bool(features & KERNEL_FEATURE_NODE_VORONOI_EXTRA)
|
||||||
<< "\n";
|
<< "\n";
|
||||||
|
@@ -160,6 +160,7 @@ class SceneParams {
|
|||||||
|
|
||||||
BVHType bvh_type;
|
BVHType bvh_type;
|
||||||
bool use_bvh_spatial_split;
|
bool use_bvh_spatial_split;
|
||||||
|
bool use_bvh_compact_structure;
|
||||||
bool use_bvh_unaligned_nodes;
|
bool use_bvh_unaligned_nodes;
|
||||||
int num_bvh_time_steps;
|
int num_bvh_time_steps;
|
||||||
int hair_subdivisions;
|
int hair_subdivisions;
|
||||||
@@ -174,6 +175,7 @@ class SceneParams {
|
|||||||
bvh_layout = BVH_LAYOUT_BVH2;
|
bvh_layout = BVH_LAYOUT_BVH2;
|
||||||
bvh_type = BVH_TYPE_DYNAMIC;
|
bvh_type = BVH_TYPE_DYNAMIC;
|
||||||
use_bvh_spatial_split = false;
|
use_bvh_spatial_split = false;
|
||||||
|
use_bvh_compact_structure = true;
|
||||||
use_bvh_unaligned_nodes = true;
|
use_bvh_unaligned_nodes = true;
|
||||||
num_bvh_time_steps = 0;
|
num_bvh_time_steps = 0;
|
||||||
hair_subdivisions = 3;
|
hair_subdivisions = 3;
|
||||||
@@ -187,6 +189,7 @@ class SceneParams {
|
|||||||
return !(shadingsystem == params.shadingsystem && bvh_layout == params.bvh_layout &&
|
return !(shadingsystem == params.shadingsystem && bvh_layout == params.bvh_layout &&
|
||||||
bvh_type == params.bvh_type &&
|
bvh_type == params.bvh_type &&
|
||||||
use_bvh_spatial_split == params.use_bvh_spatial_split &&
|
use_bvh_spatial_split == params.use_bvh_spatial_split &&
|
||||||
|
use_bvh_compact_structure == params.use_bvh_compact_structure &&
|
||||||
use_bvh_unaligned_nodes == params.use_bvh_unaligned_nodes &&
|
use_bvh_unaligned_nodes == params.use_bvh_unaligned_nodes &&
|
||||||
num_bvh_time_steps == params.num_bvh_time_steps &&
|
num_bvh_time_steps == params.num_bvh_time_steps &&
|
||||||
hair_subdivisions == params.hair_subdivisions && hair_shape == params.hair_shape &&
|
hair_subdivisions == params.hair_subdivisions && hair_shape == params.hair_shape &&
|
||||||
|
@@ -32,6 +32,7 @@
|
|||||||
#include "util/color.h"
|
#include "util/color.h"
|
||||||
#include "util/foreach.h"
|
#include "util/foreach.h"
|
||||||
#include "util/log.h"
|
#include "util/log.h"
|
||||||
|
#include "util/string.h"
|
||||||
#include "util/transform.h"
|
#include "util/transform.h"
|
||||||
|
|
||||||
#include "kernel/tables.h"
|
#include "kernel/tables.h"
|
||||||
@@ -462,8 +463,12 @@ void ImageTextureNode::compile(OSLCompiler &compiler)
|
|||||||
const ustring known_colorspace = metadata.colorspace;
|
const ustring known_colorspace = metadata.colorspace;
|
||||||
|
|
||||||
if (handle.svm_slot() == -1) {
|
if (handle.svm_slot() == -1) {
|
||||||
|
/* OIIO currently does not support <UVTILE> substitutions natively. Replace with a format they
|
||||||
|
* understand. */
|
||||||
|
std::string osl_filename = filename.string();
|
||||||
|
string_replace(osl_filename, "<UVTILE>", "<U>_<V>");
|
||||||
compiler.parameter_texture(
|
compiler.parameter_texture(
|
||||||
"filename", filename, compress_as_srgb ? u_colorspace_raw : known_colorspace);
|
"filename", ustring(osl_filename), compress_as_srgb ? u_colorspace_raw : known_colorspace);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
compiler.parameter_texture("filename", handle.svm_slot());
|
compiler.parameter_texture("filename", handle.svm_slot());
|
||||||
@@ -472,7 +477,8 @@ void ImageTextureNode::compile(OSLCompiler &compiler)
|
|||||||
const bool unassociate_alpha = !(ColorSpaceManager::colorspace_is_data(colorspace) ||
|
const bool unassociate_alpha = !(ColorSpaceManager::colorspace_is_data(colorspace) ||
|
||||||
alpha_type == IMAGE_ALPHA_CHANNEL_PACKED ||
|
alpha_type == IMAGE_ALPHA_CHANNEL_PACKED ||
|
||||||
alpha_type == IMAGE_ALPHA_IGNORE);
|
alpha_type == IMAGE_ALPHA_IGNORE);
|
||||||
const bool is_tiled = (filename.find("<UDIM>") != string::npos);
|
const bool is_tiled = (filename.find("<UDIM>") != string::npos ||
|
||||||
|
filename.find("<UVTILE>") != string::npos);
|
||||||
|
|
||||||
compiler.parameter(this, "projection");
|
compiler.parameter(this, "projection");
|
||||||
compiler.parameter(this, "projection_blend");
|
compiler.parameter(this, "projection_blend");
|
||||||
@@ -4388,9 +4394,6 @@ NODE_DEFINE(HairInfoNode)
|
|||||||
SOCKET_OUT_FLOAT(size, "Length");
|
SOCKET_OUT_FLOAT(size, "Length");
|
||||||
SOCKET_OUT_FLOAT(thickness, "Thickness");
|
SOCKET_OUT_FLOAT(thickness, "Thickness");
|
||||||
SOCKET_OUT_NORMAL(tangent_normal, "Tangent Normal");
|
SOCKET_OUT_NORMAL(tangent_normal, "Tangent Normal");
|
||||||
#if 0 /* Output for minimum hair width transparency - deactivated. */
|
|
||||||
SOCKET_OUT_FLOAT(fade, "Fade");
|
|
||||||
#endif
|
|
||||||
SOCKET_OUT_FLOAT(index, "Random");
|
SOCKET_OUT_FLOAT(index, "Random");
|
||||||
|
|
||||||
return type;
|
return type;
|
||||||
@@ -4448,12 +4451,7 @@ void HairInfoNode::compile(SVMCompiler &compiler)
|
|||||||
if (!out->links.empty()) {
|
if (!out->links.empty()) {
|
||||||
compiler.add_node(NODE_HAIR_INFO, NODE_INFO_CURVE_TANGENT_NORMAL, compiler.stack_assign(out));
|
compiler.add_node(NODE_HAIR_INFO, NODE_INFO_CURVE_TANGENT_NORMAL, compiler.stack_assign(out));
|
||||||
}
|
}
|
||||||
#if 0
|
|
||||||
out = output("Fade");
|
|
||||||
if(!out->links.empty()) {
|
|
||||||
compiler.add_node(NODE_HAIR_INFO, NODE_INFO_CURVE_FADE, compiler.stack_assign(out));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
out = output("Random");
|
out = output("Random");
|
||||||
if (!out->links.empty()) {
|
if (!out->links.empty()) {
|
||||||
int attr = compiler.attribute(ATTR_STD_CURVE_RANDOM);
|
int attr = compiler.attribute(ATTR_STD_CURVE_RANDOM);
|
||||||
@@ -4466,6 +4464,59 @@ void HairInfoNode::compile(OSLCompiler &compiler)
|
|||||||
compiler.add(this, "node_hair_info");
|
compiler.add(this, "node_hair_info");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Point Info */
|
||||||
|
|
||||||
|
NODE_DEFINE(PointInfoNode)
|
||||||
|
{
|
||||||
|
NodeType *type = NodeType::add("point_info", create, NodeType::SHADER);
|
||||||
|
|
||||||
|
SOCKET_OUT_POINT(position, "Position");
|
||||||
|
SOCKET_OUT_FLOAT(radius, "Radius");
|
||||||
|
SOCKET_OUT_FLOAT(random, "Random");
|
||||||
|
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
PointInfoNode::PointInfoNode() : ShaderNode(get_node_type())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void PointInfoNode::attributes(Shader *shader, AttributeRequestSet *attributes)
|
||||||
|
{
|
||||||
|
if (shader->has_surface_link()) {
|
||||||
|
if (!output("Random")->links.empty())
|
||||||
|
attributes->add(ATTR_STD_POINT_RANDOM);
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderNode::attributes(shader, attributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PointInfoNode::compile(SVMCompiler &compiler)
|
||||||
|
{
|
||||||
|
ShaderOutput *out;
|
||||||
|
|
||||||
|
out = output("Position");
|
||||||
|
if (!out->links.empty()) {
|
||||||
|
compiler.add_node(NODE_POINT_INFO, NODE_INFO_POINT_POSITION, compiler.stack_assign(out));
|
||||||
|
}
|
||||||
|
|
||||||
|
out = output("Radius");
|
||||||
|
if (!out->links.empty()) {
|
||||||
|
compiler.add_node(NODE_POINT_INFO, NODE_INFO_POINT_RADIUS, compiler.stack_assign(out));
|
||||||
|
}
|
||||||
|
|
||||||
|
out = output("Random");
|
||||||
|
if (!out->links.empty()) {
|
||||||
|
int attr = compiler.attribute(ATTR_STD_POINT_RANDOM);
|
||||||
|
compiler.add_node(NODE_ATTR, attr, compiler.stack_assign(out), NODE_ATTR_OUTPUT_FLOAT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PointInfoNode::compile(OSLCompiler &compiler)
|
||||||
|
{
|
||||||
|
compiler.add(this, "node_point_info");
|
||||||
|
}
|
||||||
|
|
||||||
/* Volume Info */
|
/* Volume Info */
|
||||||
|
|
||||||
NODE_DEFINE(VolumeInfoNode)
|
NODE_DEFINE(VolumeInfoNode)
|
||||||
|
@@ -1005,9 +1005,20 @@ class HairInfoNode : public ShaderNode {
|
|||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
virtual int get_feature()
|
};
|
||||||
|
|
||||||
|
class PointInfoNode : public ShaderNode {
|
||||||
|
public:
|
||||||
|
SHADER_NODE_CLASS(PointInfoNode)
|
||||||
|
|
||||||
|
void attributes(Shader *shader, AttributeRequestSet *attributes);
|
||||||
|
bool has_attribute_dependency()
|
||||||
{
|
{
|
||||||
return ShaderNode::get_feature() | KERNEL_FEATURE_NODE_HAIR;
|
return true;
|
||||||
|
}
|
||||||
|
bool has_spatial_varying()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -428,7 +428,7 @@ void Session::do_delayed_reset()
|
|||||||
|
|
||||||
/* Update temp directory on reset.
|
/* Update temp directory on reset.
|
||||||
* This potentially allows to finish the existing rendering with a previously configure temporary
|
* This potentially allows to finish the existing rendering with a previously configure temporary
|
||||||
* direcotry in the host software and switch to a new temp directory when new render starts. */
|
* directory in the host software and switch to a new temp directory when new render starts. */
|
||||||
tile_manager_.set_temp_dir(params.temp_dir);
|
tile_manager_.set_temp_dir(params.temp_dir);
|
||||||
|
|
||||||
/* Progress. */
|
/* Progress. */
|
||||||
|
@@ -38,8 +38,6 @@ set(ALL_CYCLES_LIBRARIES
|
|||||||
)
|
)
|
||||||
include_directories(${INC})
|
include_directories(${INC})
|
||||||
|
|
||||||
cycles_link_directories()
|
|
||||||
|
|
||||||
set(SRC
|
set(SRC
|
||||||
integrator_adaptive_sampling_test.cpp
|
integrator_adaptive_sampling_test.cpp
|
||||||
integrator_render_scheduler_test.cpp
|
integrator_render_scheduler_test.cpp
|
||||||
|
@@ -64,7 +64,7 @@ template<typename T, size_t alignment = MIN_ALIGNMENT_CPU_DATA_TYPES> class arra
|
|||||||
else {
|
else {
|
||||||
data_ = mem_allocate(from.datasize_);
|
data_ = mem_allocate(from.datasize_);
|
||||||
if (from.datasize_ > 0) {
|
if (from.datasize_ > 0) {
|
||||||
memcpy(data_, from.data_, from.datasize_ * sizeof(T));
|
mem_copy(data_, from.data_, from.datasize_);
|
||||||
}
|
}
|
||||||
datasize_ = from.datasize_;
|
datasize_ = from.datasize_;
|
||||||
capacity_ = datasize_;
|
capacity_ = datasize_;
|
||||||
@@ -76,7 +76,7 @@ template<typename T, size_t alignment = MIN_ALIGNMENT_CPU_DATA_TYPES> class arra
|
|||||||
if (this != &from) {
|
if (this != &from) {
|
||||||
resize(from.size());
|
resize(from.size());
|
||||||
if (datasize_ > 0) {
|
if (datasize_ > 0) {
|
||||||
memcpy((void *)data_, from.data_, datasize_ * sizeof(T));
|
mem_copy(data_, from.data_, datasize_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,7 +88,7 @@ template<typename T, size_t alignment = MIN_ALIGNMENT_CPU_DATA_TYPES> class arra
|
|||||||
resize(from.size());
|
resize(from.size());
|
||||||
|
|
||||||
if (from.size() > 0 && datasize_ > 0) {
|
if (from.size() > 0 && datasize_ > 0) {
|
||||||
memcpy(data_, &from[0], datasize_ * sizeof(T));
|
mem_copy(data_, from.data(), datasize_);
|
||||||
}
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
@@ -161,8 +161,7 @@ template<typename T, size_t alignment = MIN_ALIGNMENT_CPU_DATA_TYPES> class arra
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
else if (data_ != NULL) {
|
else if (data_ != NULL) {
|
||||||
memcpy(
|
mem_copy(newdata, data_, ((datasize_ < newsize) ? datasize_ : newsize));
|
||||||
(void *)newdata, data_, ((datasize_ < newsize) ? datasize_ : newsize) * sizeof(T));
|
|
||||||
mem_free(data_, capacity_);
|
mem_free(data_, capacity_);
|
||||||
}
|
}
|
||||||
data_ = newdata;
|
data_ = newdata;
|
||||||
@@ -246,7 +245,7 @@ template<typename T, size_t alignment = MIN_ALIGNMENT_CPU_DATA_TYPES> class arra
|
|||||||
if (newcapacity > capacity_) {
|
if (newcapacity > capacity_) {
|
||||||
T *newdata = mem_allocate(newcapacity);
|
T *newdata = mem_allocate(newcapacity);
|
||||||
if (data_ != NULL) {
|
if (data_ != NULL) {
|
||||||
memcpy(newdata, data_, ((datasize_ < newcapacity) ? datasize_ : newcapacity) * sizeof(T));
|
mem_copy(newdata, data_, ((datasize_ < newcapacity) ? datasize_ : newcapacity));
|
||||||
mem_free(data_, capacity_);
|
mem_free(data_, capacity_);
|
||||||
}
|
}
|
||||||
data_ = newdata;
|
data_ = newdata;
|
||||||
@@ -280,7 +279,7 @@ template<typename T, size_t alignment = MIN_ALIGNMENT_CPU_DATA_TYPES> class arra
|
|||||||
if (from.size()) {
|
if (from.size()) {
|
||||||
size_t old_size = size();
|
size_t old_size = size();
|
||||||
resize(old_size + from.size());
|
resize(old_size + from.size());
|
||||||
memcpy(data_ + old_size, from.data(), sizeof(T) * from.size());
|
mem_copy(data_ + old_size, from.data(), from.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -308,6 +307,11 @@ template<typename T, size_t alignment = MIN_ALIGNMENT_CPU_DATA_TYPES> class arra
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void mem_copy(T *mem_to, const T *mem_from, const size_t N)
|
||||||
|
{
|
||||||
|
memcpy((void *)mem_to, mem_from, sizeof(T) * N);
|
||||||
|
}
|
||||||
|
|
||||||
T *data_;
|
T *data_;
|
||||||
size_t datasize_;
|
size_t datasize_;
|
||||||
size_t capacity_;
|
size_t capacity_;
|
||||||
|
@@ -401,7 +401,7 @@ ccl_device_inline float fractf(float x)
|
|||||||
return x - floorf(x);
|
return x - floorf(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Adapted from godot-engine math_funcs.h. */
|
/* Adapted from `godot-engine` math_funcs.h. */
|
||||||
ccl_device_inline float wrapf(float value, float max, float min)
|
ccl_device_inline float wrapf(float value, float max, float min)
|
||||||
{
|
{
|
||||||
float range = max - min;
|
float range = max - min;
|
||||||
|
@@ -131,10 +131,7 @@ ccl_device_inline int4 clamp(const int4 &a, const int4 &mn, const int4 &mx)
|
|||||||
ccl_device_inline int4 select(const int4 &mask, const int4 &a, const int4 &b)
|
ccl_device_inline int4 select(const int4 &mask, const int4 &a, const int4 &b)
|
||||||
{
|
{
|
||||||
# ifdef __KERNEL_SSE__
|
# ifdef __KERNEL_SSE__
|
||||||
const __m128 m = _mm_cvtepi32_ps(mask);
|
return int4(_mm_or_si128(_mm_and_si128(mask, a), _mm_andnot_si128(mask, b)));
|
||||||
/* TODO(sergey): avoid cvt. */
|
|
||||||
return int4(_mm_castps_si128(
|
|
||||||
_mm_or_ps(_mm_and_ps(m, _mm_castsi128_ps(a)), _mm_andnot_ps(m, _mm_castsi128_ps(b)))));
|
|
||||||
# else
|
# else
|
||||||
return make_int4(
|
return make_int4(
|
||||||
(mask.x) ? a.x : b.x, (mask.y) ? a.y : b.y, (mask.z) ? a.z : b.z, (mask.w) ? a.w : b.w);
|
(mask.x) ? a.x : b.x, (mask.y) ? a.y : b.y, (mask.z) ? a.z : b.z, (mask.w) ? a.w : b.w);
|
||||||
|
@@ -109,9 +109,10 @@ void TaskScheduler::free_memory()
|
|||||||
assert(users == 0);
|
assert(users == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int TaskScheduler::num_threads()
|
int TaskScheduler::max_concurrency()
|
||||||
{
|
{
|
||||||
return active_num_threads;
|
thread_scoped_lock lock(mutex);
|
||||||
|
return (users > 0) ? active_num_threads : tbb::this_task_arena::max_concurrency();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Dedicated Task Pool */
|
/* Dedicated Task Pool */
|
||||||
|
@@ -86,10 +86,9 @@ class TaskScheduler {
|
|||||||
static void exit();
|
static void exit();
|
||||||
static void free_memory();
|
static void free_memory();
|
||||||
|
|
||||||
/* Approximate number of threads that will work on task, which may be lower
|
/* Maximum number of threads that will work on task. Use as little as
|
||||||
* or higher than the actual number of threads. Use as little as possible and
|
* possible and leave scheduling and splitting up tasks to the scheduler. */
|
||||||
* leave splitting up tasks to the scheduler. */
|
static int max_concurrency();
|
||||||
static int num_threads();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static thread_mutex mutex;
|
static thread_mutex mutex;
|
||||||
|
@@ -544,7 +544,7 @@ void GHOST_WindowX11::refreshXInputDevices()
|
|||||||
std::vector<XEventClass> xevents;
|
std::vector<XEventClass> xevents;
|
||||||
|
|
||||||
for (GHOST_SystemX11::GHOST_TabletX11 &xtablet : m_system->GetXTablets()) {
|
for (GHOST_SystemX11::GHOST_TabletX11 &xtablet : m_system->GetXTablets()) {
|
||||||
/* With modern XInput (xlib 1.6.2 at least and/or evdev 2.9.0) and some 'no-name' tablets
|
/* With modern XInput (XLIB 1.6.2 at least and/or EVDEV 2.9.0) and some 'no-name' tablets
|
||||||
* like 'UC-LOGIC Tablet WP5540U', we also need to 'select' ButtonPress for motion event,
|
* like 'UC-LOGIC Tablet WP5540U', we also need to 'select' ButtonPress for motion event,
|
||||||
* otherwise we do not get any tablet motion event once pen is pressed... See T43367.
|
* otherwise we do not get any tablet motion event once pen is pressed... See T43367.
|
||||||
*/
|
*/
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user