Compare commits
14 Commits
temp-unity
...
temp-field
Author | SHA1 | Date | |
---|---|---|---|
d26165747e | |||
6dc2045054 | |||
362bd7889b | |||
620da869f1 | |||
50df35e4a4 | |||
6a72188b3e | |||
5d183c5af3 | |||
dcf72a30e1 | |||
0bec1f5dad | |||
a5fbd81510 | |||
234de0bf71 | |||
a5b9323fd5 | |||
52de232811 | |||
1931878f57 |
@@ -180,7 +180,6 @@ ForEachMacros:
|
||||
- CTX_DATA_BEGIN_WITH_ID
|
||||
- DEG_OBJECT_ITER_BEGIN
|
||||
- DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN
|
||||
- DRW_ENABLED_ENGINE_ITER
|
||||
- DRIVER_TARGETS_LOOPER_BEGIN
|
||||
- DRIVER_TARGETS_USED_LOOPER_BEGIN
|
||||
- FOREACH_BASE_IN_EDIT_MODE_BEGIN
|
||||
@@ -268,6 +267,3 @@ ForEachMacros:
|
||||
StatementMacros:
|
||||
- PyObject_HEAD
|
||||
- PyObject_VAR_HEAD
|
||||
|
||||
MacroBlockBegin: "^BSDF_CLOSURE_CLASS_BEGIN$"
|
||||
MacroBlockEnd: "^BSDF_CLOSURE_CLASS_END$"
|
||||
|
5
.github/pull_request_template.md
vendored
5
.github/pull_request_template.md
vendored
@@ -1,5 +0,0 @@
|
||||
This repository is only used as a mirror of git.blender.org. Blender development happens on
|
||||
https://developer.blender.org.
|
||||
|
||||
To get started with contributing code, please see:
|
||||
https://wiki.blender.org/wiki/Process/Contributing_Code
|
@@ -30,7 +30,7 @@ if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
|
||||
"CMake generation for blender is not allowed within the source directory!"
|
||||
"\n Remove \"${CMAKE_SOURCE_DIR}/CMakeCache.txt\" and try again from another folder, e.g.:"
|
||||
"\n "
|
||||
"\n rm -rf CMakeCache.txt CMakeFiles"
|
||||
"\n rm CMakeCache.txt"
|
||||
"\n cd .."
|
||||
"\n mkdir cmake-make"
|
||||
"\n cd cmake-make"
|
||||
@@ -156,15 +156,6 @@ get_blender_version()
|
||||
option(WITH_BLENDER "Build blender (disable to build only the blender player)" ON)
|
||||
mark_as_advanced(WITH_BLENDER)
|
||||
|
||||
if(APPLE)
|
||||
# Currently this causes a build error linking, disable.
|
||||
set(WITH_BLENDER_THUMBNAILER OFF)
|
||||
elseif(WIN32)
|
||||
option(WITH_BLENDER_THUMBNAILER "Build \"BlendThumb.dll\" helper for Windows explorer integration" ON)
|
||||
else()
|
||||
option(WITH_BLENDER_THUMBNAILER "Build \"blender-thumbnailer\" thumbnail extraction utility" ON)
|
||||
endif()
|
||||
|
||||
option(WITH_INTERNATIONAL "Enable I18N (International fonts and text)" ON)
|
||||
|
||||
option(WITH_PYTHON "Enable Embedded Python API (only disable for development)" ON)
|
||||
@@ -397,55 +388,46 @@ if(WITH_PYTHON_INSTALL)
|
||||
set(PYTHON_REQUESTS_PATH "" CACHE PATH "Path to python site-packages or dist-packages containing 'requests' module")
|
||||
mark_as_advanced(PYTHON_REQUESTS_PATH)
|
||||
endif()
|
||||
|
||||
option(WITH_PYTHON_INSTALL_ZSTANDARD "Copy zstandard into the blender install folder" ON)
|
||||
set(PYTHON_ZSTANDARD_PATH "" CACHE PATH "Path to python site-packages or dist-packages containing 'zstandard' module")
|
||||
mark_as_advanced(PYTHON_ZSTANDARD_PATH)
|
||||
endif()
|
||||
|
||||
option(WITH_CPU_SIMD "Enable SIMD instruction if they're detected on the host machine" ON)
|
||||
mark_as_advanced(WITH_CPU_SIMD)
|
||||
|
||||
# Cycles
|
||||
option(WITH_CYCLES "Enable Cycles Render Engine" ON)
|
||||
option(WITH_CYCLES_OSL "Build Cycles with OpenShadingLanguage support" ON)
|
||||
option(WITH_CYCLES_EMBREE "Build Cycles with Embree support" ON)
|
||||
option(WITH_CYCLES_LOGGING "Build Cycles with logging support" ON)
|
||||
|
||||
option(WITH_CYCLES_STANDALONE "Build Cycles standalone application" OFF)
|
||||
option(WITH_CYCLES_STANDALONE_GUI "Build Cycles standalone with GUI" OFF)
|
||||
|
||||
option(WITH_CYCLES_DEBUG_NAN "Build Cycles with additional asserts for detecting NaNs and invalid values" OFF)
|
||||
option(WITH_CYCLES_NATIVE_ONLY "Build Cycles with native kernel only (which fits current CPU, use for development only)" OFF)
|
||||
option(WITH_CYCLES_KERNEL_ASAN "Build Cycles kernels with address sanitizer when WITH_COMPILER_ASAN is on, even if it's very slow" OFF)
|
||||
set(CYCLES_TEST_DEVICES CPU CACHE STRING "Run regression tests on the specified device types (CPU CUDA OPTIX HIP)" )
|
||||
option(WITH_CYCLES "Enable Cycles Render Engine" ON)
|
||||
option(WITH_CYCLES_STANDALONE "Build Cycles standalone application" OFF)
|
||||
option(WITH_CYCLES_STANDALONE_GUI "Build Cycles standalone with GUI" OFF)
|
||||
option(WITH_CYCLES_OSL "Build Cycles with OSL support" ON)
|
||||
option(WITH_CYCLES_EMBREE "Build Cycles with Embree support" ON)
|
||||
option(WITH_CYCLES_CUDA_BINARIES "Build Cycles CUDA binaries" OFF)
|
||||
option(WITH_CYCLES_CUBIN_COMPILER "Build cubins with nvrtc based compiler instead of nvcc" OFF)
|
||||
option(WITH_CYCLES_CUDA_BUILD_SERIAL "Build cubins one after another (useful on machines with limited RAM)" OFF)
|
||||
mark_as_advanced(WITH_CYCLES_CUDA_BUILD_SERIAL)
|
||||
set(CYCLES_TEST_DEVICES CPU CACHE STRING "Run regression tests on the specified device types (CPU CUDA OPTIX OPENCL)" )
|
||||
set(CYCLES_CUDA_BINARIES_ARCH sm_30 sm_35 sm_37 sm_50 sm_52 sm_60 sm_61 sm_70 sm_75 sm_86 compute_75 CACHE STRING "CUDA architectures to build binaries for")
|
||||
mark_as_advanced(CYCLES_CUDA_BINARIES_ARCH)
|
||||
unset(PLATFORM_DEFAULT)
|
||||
option(WITH_CYCLES_LOGGING "Build Cycles with logging support" ON)
|
||||
option(WITH_CYCLES_DEBUG_NAN "Build Cycles with additional asserts for detecting NaNs and invalid values" OFF)
|
||||
option(WITH_CYCLES_NATIVE_ONLY "Build Cycles with native kernel only (which fits current CPU, use for development only)" OFF)
|
||||
option(WITH_CYCLES_KERNEL_ASAN "Build Cycles kernels with address sanitizer when WITH_COMPILER_ASAN is on, even if it's very slow" OFF)
|
||||
mark_as_advanced(WITH_CYCLES_KERNEL_ASAN)
|
||||
mark_as_advanced(WITH_CYCLES_CUBIN_COMPILER)
|
||||
mark_as_advanced(WITH_CYCLES_LOGGING)
|
||||
mark_as_advanced(WITH_CYCLES_DEBUG_NAN)
|
||||
mark_as_advanced(WITH_CYCLES_NATIVE_ONLY)
|
||||
|
||||
# NVIDIA CUDA & OptiX
|
||||
option(WITH_CYCLES_DEVICE_CUDA "Enable Cycles NVIDIA CUDA compute support" ON)
|
||||
option(WITH_CYCLES_DEVICE_OPTIX "Enable Cycles NVIDIA OptiX support" ON)
|
||||
option(WITH_CYCLES_DEVICE_CUDA "Enable Cycles CUDA compute support" ON)
|
||||
option(WITH_CYCLES_DEVICE_OPTIX "Enable Cycles OptiX support" OFF)
|
||||
option(WITH_CYCLES_DEVICE_OPENCL "Enable Cycles OpenCL compute support" ON)
|
||||
option(WITH_CYCLES_NETWORK "Enable Cycles compute over network support (EXPERIMENTAL and unfinished)" OFF)
|
||||
mark_as_advanced(WITH_CYCLES_DEVICE_CUDA)
|
||||
mark_as_advanced(WITH_CYCLES_DEVICE_OPENCL)
|
||||
mark_as_advanced(WITH_CYCLES_NETWORK)
|
||||
|
||||
option(WITH_CYCLES_CUDA_BINARIES "Build Cycles NVIDIA CUDA binaries" OFF)
|
||||
set(CYCLES_CUDA_BINARIES_ARCH sm_30 sm_35 sm_37 sm_50 sm_52 sm_60 sm_61 sm_70 sm_75 sm_86 compute_75 CACHE STRING "CUDA architectures to build binaries for")
|
||||
option(WITH_CYCLES_CUBIN_COMPILER "Build cubins with nvrtc based compiler instead of nvcc" OFF)
|
||||
option(WITH_CYCLES_CUDA_BUILD_SERIAL "Build cubins one after another (useful on machines with limited RAM)" OFF)
|
||||
option(WITH_CUDA_DYNLOAD "Dynamically load CUDA libraries at runtime (for developers, makes cuda-gdb work)" ON)
|
||||
mark_as_advanced(CYCLES_CUDA_BINARIES_ARCH)
|
||||
mark_as_advanced(WITH_CYCLES_CUBIN_COMPILER)
|
||||
mark_as_advanced(WITH_CYCLES_CUDA_BUILD_SERIAL)
|
||||
option(WITH_CUDA_DYNLOAD "Dynamically load CUDA libraries at runtime" ON)
|
||||
mark_as_advanced(WITH_CUDA_DYNLOAD)
|
||||
|
||||
# AMD HIP
|
||||
option(WITH_CYCLES_DEVICE_HIP "Enable Cycles AMD HIP support" OFF)
|
||||
option(WITH_CYCLES_HIP_BINARIES "Build Cycles AMD HIP binaries" OFF)
|
||||
set(CYCLES_HIP_BINARIES_ARCH gfx1010 gfx1011 gfx1012 gfx1030 gfx1031 gfx1032 gfx1034 CACHE STRING "AMD HIP architectures to build binaries for")
|
||||
mark_as_advanced(WITH_CYCLES_DEVICE_HIP)
|
||||
mark_as_advanced(CYCLES_HIP_BINARIES_ARCH)
|
||||
|
||||
# Draw Manager
|
||||
option(WITH_DRAW_DEBUG "Add extra debug capabilities to Draw Manager" OFF)
|
||||
mark_as_advanced(WITH_DRAW_DEBUG)
|
||||
@@ -642,7 +624,7 @@ if(WIN32)
|
||||
option(WITH_WINDOWS_PDB "Generate a pdb file for client side stacktraces" ON)
|
||||
mark_as_advanced(WITH_WINDOWS_PDB)
|
||||
|
||||
option(WITH_WINDOWS_STRIPPED_PDB "Use a stripped PDB file" ON)
|
||||
option(WITH_WINDOWS_STRIPPED_PDB "Use a stripped PDB file" On)
|
||||
mark_as_advanced(WITH_WINDOWS_STRIPPED_PDB)
|
||||
|
||||
endif()
|
||||
@@ -843,11 +825,6 @@ if(NOT WITH_CUDA_DYNLOAD)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WITH_CYCLES_DEVICE_HIP)
|
||||
# Currently HIP must be dynamically loaded, this may change in future toolkits
|
||||
set(WITH_HIP_DYNLOAD ON)
|
||||
endif()
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Check check if submodules are cloned
|
||||
|
||||
@@ -1743,12 +1720,6 @@ if(WITH_PYTHON)
|
||||
elseif(WITH_PYTHON_INSTALL_REQUESTS)
|
||||
find_python_package(requests "")
|
||||
endif()
|
||||
|
||||
if(WIN32 OR APPLE)
|
||||
# pass, we have this in lib/python/site-packages
|
||||
elseif(WITH_PYTHON_INSTALL_ZSTANDARD)
|
||||
find_python_package(zstandard "")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Select C++17 as the standard for C++ projects.
|
||||
@@ -1883,9 +1854,6 @@ elseif(WITH_CYCLES_STANDALONE)
|
||||
if(WITH_CUDA_DYNLOAD)
|
||||
add_subdirectory(extern/cuew)
|
||||
endif()
|
||||
if(WITH_HIP_DYNLOAD)
|
||||
add_subdirectory(extern/hipew)
|
||||
endif()
|
||||
if(NOT WITH_SYSTEM_GLEW)
|
||||
add_subdirectory(extern/glew)
|
||||
endif()
|
||||
@@ -2020,7 +1988,6 @@ if(FIRST_RUN)
|
||||
endif()
|
||||
info_cfg_option(WITH_PYTHON_INSTALL)
|
||||
info_cfg_option(WITH_PYTHON_INSTALL_NUMPY)
|
||||
info_cfg_option(WITH_PYTHON_INSTALL_ZSTANDARD)
|
||||
info_cfg_option(WITH_PYTHON_MODULE)
|
||||
info_cfg_option(WITH_PYTHON_SAFETY)
|
||||
|
||||
|
@@ -27,7 +27,7 @@
|
||||
define HELP_TEXT
|
||||
|
||||
Blender Convenience Targets
|
||||
Provided for building Blender (multiple targets can be used at once).
|
||||
Provided for building Blender, (multiple at once can be used).
|
||||
|
||||
* debug: Build a debug binary.
|
||||
* full: Enable all supported dependencies & options.
|
||||
@@ -40,8 +40,6 @@ Blender Convenience Targets
|
||||
* ninja: Use ninja build tool for faster builds.
|
||||
* ccache: Use ccache for faster rebuilds.
|
||||
|
||||
Note: when passing in multiple targets their order is not important.
|
||||
So for a fast build you can for e.g. run 'make lite ccache ninja'.
|
||||
Note: passing the argument 'BUILD_DIR=path' when calling make will override the default build dir.
|
||||
Note: passing the argument 'BUILD_CMAKE_ARGS=args' lets you add cmake arguments.
|
||||
|
||||
|
@@ -38,6 +38,7 @@ ExternalProject_Add(external_numpy
|
||||
PREFIX ${BUILD_DIR}/numpy
|
||||
PATCH_COMMAND ${NUMPY_PATCH}
|
||||
CONFIGURE_COMMAND ""
|
||||
PATCH_COMMAND COMMAND ${PATCH_CMD} -p 1 -d ${BUILD_DIR}/numpy/src/external_numpy < ${PATCH_DIR}/numpy.diff
|
||||
LOG_BUILD 1
|
||||
BUILD_COMMAND ${PYTHON_BINARY} ${BUILD_DIR}/numpy/src/external_numpy/setup.py build ${NUMPY_BUILD_OPTION} install --old-and-unmanageable
|
||||
INSTALL_COMMAND ""
|
||||
|
@@ -18,20 +18,14 @@
|
||||
|
||||
if(WIN32 AND BUILD_MODE STREQUAL Debug)
|
||||
set(SITE_PACKAGES_EXTRA --global-option build --global-option --debug)
|
||||
# zstandard is determined to build and link release mode libs in a debug
|
||||
# configuration, the only way to make it happy is to bend to its will
|
||||
# and give it a library to link with.
|
||||
set(PIP_CONFIGURE_COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/python/libs/python${PYTHON_SHORT_VERSION_NO_DOTS}_d.lib ${LIBDIR}/python/libs/python${PYTHON_SHORT_VERSION_NO_DOTS}.lib)
|
||||
else()
|
||||
set(PIP_CONFIGURE_COMMAND echo ".")
|
||||
endif()
|
||||
|
||||
ExternalProject_Add(external_python_site_packages
|
||||
DOWNLOAD_COMMAND ""
|
||||
CONFIGURE_COMMAND ${PIP_CONFIGURE_COMMAND}
|
||||
CONFIGURE_COMMAND ""
|
||||
BUILD_COMMAND ""
|
||||
PREFIX ${BUILD_DIR}/site_packages
|
||||
INSTALL_COMMAND ${PYTHON_BINARY} -m pip install ${SITE_PACKAGES_EXTRA} cython==${CYTHON_VERSION} idna==${IDNA_VERSION} charset-normalizer==${CHARSET_NORMALIZER_VERSION} urllib3==${URLLIB3_VERSION} certifi==${CERTIFI_VERSION} requests==${REQUESTS_VERSION} zstandard==${ZSTANDARD_VERSION} --no-binary :all:
|
||||
INSTALL_COMMAND ${PYTHON_BINARY} -m pip install ${SITE_PACKAGES_EXTRA} cython==${CYTHON_VERSION} idna==${IDNA_VERSION} chardet==${CHARDET_VERSION} urllib3==${URLLIB3_VERSION} certifi==${CERTIFI_VERSION} requests==${REQUESTS_VERSION} --no-binary :all:
|
||||
)
|
||||
|
||||
if(USE_PIP_NUMPY)
|
||||
|
@@ -189,11 +189,11 @@ set(OSL_HASH 1abd7ce40481771a9fa937f19595d2f2)
|
||||
set(OSL_HASH_TYPE MD5)
|
||||
set(OSL_FILE OpenShadingLanguage-${OSL_VERSION}.tar.gz)
|
||||
|
||||
set(PYTHON_VERSION 3.9.7)
|
||||
set(PYTHON_VERSION 3.9.2)
|
||||
set(PYTHON_SHORT_VERSION 3.9)
|
||||
set(PYTHON_SHORT_VERSION_NO_DOTS 39)
|
||||
set(PYTHON_URI https://www.python.org/ftp/python/${PYTHON_VERSION}/Python-${PYTHON_VERSION}.tar.xz)
|
||||
set(PYTHON_HASH fddb060b483bc01850a3f412eea1d954)
|
||||
set(PYTHON_HASH f0dc9000312abeb16de4eccce9a870ab)
|
||||
set(PYTHON_HASH_TYPE MD5)
|
||||
set(PYTHON_FILE Python-${PYTHON_VERSION}.tar.xz)
|
||||
|
||||
@@ -215,18 +215,17 @@ set(NANOVDB_HASH e7b9e863ec2f3b04ead171dec2322807)
|
||||
set(NANOVDB_HASH_TYPE MD5)
|
||||
set(NANOVDB_FILE nano-vdb-${NANOVDB_GIT_UID}.tar.gz)
|
||||
|
||||
set(IDNA_VERSION 3.2)
|
||||
set(CHARSET_NORMALIZER_VERSION 2.0.6)
|
||||
set(URLLIB3_VERSION 1.26.7)
|
||||
set(CERTIFI_VERSION 2021.10.8)
|
||||
set(REQUESTS_VERSION 2.26.0)
|
||||
set(CYTHON_VERSION 0.29.24)
|
||||
set(ZSTANDARD_VERSION 0.15.2 )
|
||||
set(IDNA_VERSION 2.10)
|
||||
set(CHARDET_VERSION 4.0.0)
|
||||
set(URLLIB3_VERSION 1.26.3)
|
||||
set(CERTIFI_VERSION 2020.12.5)
|
||||
set(REQUESTS_VERSION 2.25.1)
|
||||
set(CYTHON_VERSION 0.29.21)
|
||||
|
||||
set(NUMPY_VERSION 1.21.2)
|
||||
set(NUMPY_SHORT_VERSION 1.21)
|
||||
set(NUMPY_VERSION 1.19.5)
|
||||
set(NUMPY_SHORT_VERSION 1.19)
|
||||
set(NUMPY_URI https://github.com/numpy/numpy/releases/download/v${NUMPY_VERSION}/numpy-${NUMPY_VERSION}.zip)
|
||||
set(NUMPY_HASH 5638d5dae3ca387be562912312db842e)
|
||||
set(NUMPY_HASH f6a1b48717c552bbc18f1adc3cc1fe0e)
|
||||
set(NUMPY_HASH_TYPE MD5)
|
||||
set(NUMPY_FILE numpy-${NUMPY_VERSION}.zip)
|
||||
|
||||
|
@@ -371,78 +371,71 @@ NO_BUILD=false
|
||||
NO_CONFIRM=false
|
||||
USE_CXX11=true
|
||||
|
||||
# Note about versions: Min is inclusive, Mex is 'minimum exclusive' (i.e. XXX_VERSION_MIN <= ACTUAL_VERSION < XXX_VERSION_MEX)
|
||||
# Note about versions: Min is inclusive, Max is exclusive (i.e. XXX_VERSION_MIN <= ACTUAL_VERSION < XXX_VERSION_MAX)
|
||||
# XXX_VERSION is officially supported/used version in official builds.
|
||||
# XXX_VERSION_SHORT is used for various things, like preferred version (when distribution provides several of them),
|
||||
# and to name shortcuts to built libraries' installation directories...
|
||||
|
||||
CLANG_FORMAT_VERSION_MIN="6.0"
|
||||
CLANG_FORMAT_VERSION_MEX="10.0"
|
||||
CLANG_FORMAT_VERSION_MAX="10.0"
|
||||
|
||||
PYTHON_VERSION="3.9.7"
|
||||
PYTHON_VERSION="3.9.2"
|
||||
PYTHON_VERSION_SHORT="3.9"
|
||||
PYTHON_VERSION_MIN="3.7"
|
||||
PYTHON_VERSION_MEX="3.11"
|
||||
PYTHON_VERSION_MAX="3.11"
|
||||
PYTHON_VERSION_INSTALLED=$PYTHON_VERSION_SHORT
|
||||
PYTHON_FORCE_BUILD=false
|
||||
PYTHON_FORCE_REBUILD=false
|
||||
PYTHON_SKIP=false
|
||||
|
||||
# Additional Python modules.
|
||||
PYTHON_IDNA_VERSION="3.2"
|
||||
PYTHON_IDNA_VERSION="2.9"
|
||||
PYTHON_IDNA_VERSION_MIN="2.0"
|
||||
PYTHON_IDNA_VERSION_MEX="4.0"
|
||||
PYTHON_IDNA_VERSION_MAX="3.0"
|
||||
PYTHON_IDNA_NAME="idna"
|
||||
|
||||
PYTHON_CHARSET_NORMALIZER_VERSION="2.0.6"
|
||||
PYTHON_CHARSET_NORMALIZER_VERSION_MIN="2.0.6"
|
||||
PYTHON_CHARSET_NORMALIZER_VERSION_MEX="2.1.0" # requests uses `charset_normalizer~=2.0.0`
|
||||
PYTHON_CHARSET_NORMALIZER_NAME="charset-normalizer"
|
||||
PYTHON_CHARDET_VERSION="3.0.4"
|
||||
PYTHON_CHARDET_VERSION_MIN="3.0"
|
||||
PYTHON_CHARDET_VERSION_MAX="5.0"
|
||||
PYTHON_CHARDET_NAME="chardet"
|
||||
|
||||
PYTHON_URLLIB3_VERSION="1.26.7"
|
||||
PYTHON_URLLIB3_VERSION="1.25.9"
|
||||
PYTHON_URLLIB3_VERSION_MIN="1.0"
|
||||
PYTHON_URLLIB3_VERSION_MEX="2.0"
|
||||
PYTHON_URLLIB3_VERSION_MAX="2.0"
|
||||
PYTHON_URLLIB3_NAME="urllib3"
|
||||
|
||||
PYTHON_CERTIFI_VERSION="2021.10.8"
|
||||
PYTHON_CERTIFI_VERSION_MIN="2021.0"
|
||||
PYTHON_CERTIFI_VERSION_MEX="2023.0"
|
||||
PYTHON_CERTIFI_VERSION="2020.4.5.2"
|
||||
PYTHON_CERTIFI_VERSION_MIN="2020.0"
|
||||
PYTHON_CERTIFI_VERSION_MAX="2021.0"
|
||||
PYTHON_CERTIFI_NAME="certifi"
|
||||
|
||||
PYTHON_REQUESTS_VERSION="2.23.0"
|
||||
PYTHON_REQUESTS_VERSION_MIN="2.0"
|
||||
PYTHON_REQUESTS_VERSION_MEX="3.0"
|
||||
PYTHON_REQUESTS_VERSION_MAX="3.0"
|
||||
PYTHON_REQUESTS_NAME="requests"
|
||||
|
||||
PYTHON_ZSTANDARD_VERSION="0.15.2"
|
||||
PYTHON_ZSTANDARD_VERSION_MIN="0.15.2"
|
||||
PYTHON_ZSTANDARD_VERSION_MEX="0.16.0"
|
||||
PYTHON_ZSTANDARD_NAME="zstandard"
|
||||
|
||||
PYTHON_NUMPY_VERSION="1.21.2"
|
||||
PYTHON_NUMPY_VERSION="1.19.5"
|
||||
PYTHON_NUMPY_VERSION_MIN="1.14"
|
||||
PYTHON_NUMPY_VERSION_MEX="2.0"
|
||||
PYTHON_NUMPY_VERSION_MAX="2.0"
|
||||
PYTHON_NUMPY_NAME="numpy"
|
||||
|
||||
# As package-ready parameters (only used with distro packages).
|
||||
PYTHON_MODULES_PACKAGES=(
|
||||
"$PYTHON_IDNA_NAME $PYTHON_IDNA_VERSION_MIN $PYTHON_IDNA_VERSION_MEX"
|
||||
"$PYTHON_CHARSET_NORMALIZER_NAME $PYTHON_CHARSET_NORMALIZER_VERSION_MIN $PYTHON_CHARSET_NORMALIZER_VERSION_MEX"
|
||||
"$PYTHON_URLLIB3_NAME $PYTHON_URLLIB3_VERSION_MIN $PYTHON_URLLIB3_VERSION_MEX"
|
||||
"$PYTHON_CERTIFI_NAME $PYTHON_CERTIFI_VERSION_MIN $PYTHON_CERTIFI_VERSION_MEX"
|
||||
"$PYTHON_REQUESTS_NAME $PYTHON_REQUESTS_VERSION_MIN $PYTHON_REQUESTS_VERSION_MEX"
|
||||
"$PYTHON_ZSTANDARD_NAME $PYTHON_ZSTANDARD_VERSION_MIN $PYTHON_ZSTANDARD_VERSION_MEX"
|
||||
"$PYTHON_NUMPY_NAME $PYTHON_NUMPY_VERSION_MIN $PYTHON_NUMPY_VERSION_MEX"
|
||||
"$PYTHON_IDNA_NAME $PYTHON_IDNA_VERSION_MIN $PYTHON_IDNA_VERSION_MAX"
|
||||
"$PYTHON_CHARDET_NAME $PYTHON_CHARDET_VERSION_MIN $PYTHON_CHARDET_VERSION_MAX"
|
||||
"$PYTHON_URLLIB3_NAME $PYTHON_URLLIB3_VERSION_MIN $PYTHON_URLLIB3_VERSION_MAX"
|
||||
"$PYTHON_CERTIFI_NAME $PYTHON_CERTIFI_VERSION_MIN $PYTHON_CERTIFI_VERSION_MAX"
|
||||
"$PYTHON_REQUESTS_NAME $PYTHON_REQUESTS_VERSION_MIN $PYTHON_REQUESTS_VERSION_MAX"
|
||||
"$PYTHON_NUMPY_NAME $PYTHON_NUMPY_VERSION_MIN $PYTHON_NUMPY_VERSION_MAX"
|
||||
)
|
||||
|
||||
# As pip-ready parameters (only used when building python).
|
||||
PYTHON_MODULES_PIP=(
|
||||
"$PYTHON_IDNA_NAME==$PYTHON_IDNA_VERSION"
|
||||
"$PYTHON_CHARSET_NORMALIZER_NAME==$PYTHON_CHARSET_NORMALIZER_VERSION"
|
||||
"$PYTHON_CHARDET_NAME==$PYTHON_CHARDET_VERSION"
|
||||
"$PYTHON_URLLIB3_NAME==$PYTHON_URLLIB3_VERSION"
|
||||
"$PYTHON_CERTIFI_NAME==$PYTHON_CERTIFI_VERSION"
|
||||
"$PYTHON_REQUESTS_NAME==$PYTHON_REQUESTS_VERSION"
|
||||
"$PYTHON_ZSTANDARD_NAME==$PYTHON_ZSTANDARD_VERSION"
|
||||
"$PYTHON_NUMPY_NAME==$PYTHON_NUMPY_VERSION"
|
||||
)
|
||||
|
||||
@@ -450,7 +443,7 @@ PYTHON_MODULES_PIP=(
|
||||
BOOST_VERSION="1.73.0"
|
||||
BOOST_VERSION_SHORT="1.73"
|
||||
BOOST_VERSION_MIN="1.49"
|
||||
BOOST_VERSION_MEX="2.0"
|
||||
BOOST_VERSION_MAX="2.0"
|
||||
BOOST_FORCE_BUILD=false
|
||||
BOOST_FORCE_REBUILD=false
|
||||
BOOST_SKIP=false
|
||||
@@ -459,7 +452,7 @@ TBB_VERSION="2020"
|
||||
TBB_VERSION_SHORT="2020"
|
||||
TBB_VERSION_UPDATE="_U2" # Used for source packages...
|
||||
TBB_VERSION_MIN="2018"
|
||||
TBB_VERSION_MEX="2022"
|
||||
TBB_VERSION_MAX="2022"
|
||||
TBB_FORCE_BUILD=false
|
||||
TBB_FORCE_REBUILD=false
|
||||
TBB_SKIP=false
|
||||
@@ -467,7 +460,7 @@ TBB_SKIP=false
|
||||
OCIO_VERSION="2.0.0"
|
||||
OCIO_VERSION_SHORT="2.0"
|
||||
OCIO_VERSION_MIN="2.0"
|
||||
OCIO_VERSION_MEX="3.0"
|
||||
OCIO_VERSION_MAX="3.0"
|
||||
OCIO_FORCE_BUILD=false
|
||||
OCIO_FORCE_REBUILD=false
|
||||
OCIO_SKIP=false
|
||||
@@ -475,7 +468,7 @@ OCIO_SKIP=false
|
||||
OPENEXR_VERSION="2.5.5"
|
||||
OPENEXR_VERSION_SHORT="2.5"
|
||||
OPENEXR_VERSION_MIN="2.4"
|
||||
OPENEXR_VERSION_MEX="3.0"
|
||||
OPENEXR_VERSION_MAX="3.0"
|
||||
OPENEXR_FORCE_BUILD=false
|
||||
OPENEXR_FORCE_REBUILD=false
|
||||
OPENEXR_SKIP=false
|
||||
@@ -484,7 +477,7 @@ _with_built_openexr=false
|
||||
OIIO_VERSION="2.2.15.1"
|
||||
OIIO_VERSION_SHORT="2.2"
|
||||
OIIO_VERSION_MIN="2.1.12"
|
||||
OIIO_VERSION_MEX="2.3.0"
|
||||
OIIO_VERSION_MAX="2.3.0"
|
||||
OIIO_FORCE_BUILD=false
|
||||
OIIO_FORCE_REBUILD=false
|
||||
OIIO_SKIP=false
|
||||
@@ -492,7 +485,7 @@ OIIO_SKIP=false
|
||||
LLVM_VERSION="12.0.0"
|
||||
LLVM_VERSION_SHORT="12.0"
|
||||
LLVM_VERSION_MIN="11.0"
|
||||
LLVM_VERSION_MEX="13.0"
|
||||
LLVM_VERSION_MAX="13.0"
|
||||
LLVM_VERSION_FOUND=""
|
||||
LLVM_FORCE_BUILD=false
|
||||
LLVM_FORCE_REBUILD=false
|
||||
@@ -502,7 +495,7 @@ LLVM_SKIP=false
|
||||
OSL_VERSION="1.11.14.1"
|
||||
OSL_VERSION_SHORT="1.11"
|
||||
OSL_VERSION_MIN="1.11"
|
||||
OSL_VERSION_MEX="2.0"
|
||||
OSL_VERSION_MAX="2.0"
|
||||
OSL_FORCE_BUILD=false
|
||||
OSL_FORCE_REBUILD=false
|
||||
OSL_SKIP=false
|
||||
@@ -511,7 +504,7 @@ OSL_SKIP=false
|
||||
OSD_VERSION="3.4.3"
|
||||
OSD_VERSION_SHORT="3.4"
|
||||
OSD_VERSION_MIN="3.4"
|
||||
OSD_VERSION_MEX="4.0"
|
||||
OSD_VERSION_MAX="4.0"
|
||||
OSD_FORCE_BUILD=false
|
||||
OSD_FORCE_REBUILD=false
|
||||
OSD_SKIP=false
|
||||
@@ -522,7 +515,7 @@ OPENVDB_BLOSC_VERSION="1.5.0"
|
||||
OPENVDB_VERSION="8.0.1"
|
||||
OPENVDB_VERSION_SHORT="8.0"
|
||||
OPENVDB_VERSION_MIN="8.0"
|
||||
OPENVDB_VERSION_MEX="8.1"
|
||||
OPENVDB_VERSION_MAX="8.1"
|
||||
OPENVDB_FORCE_BUILD=false
|
||||
OPENVDB_FORCE_REBUILD=false
|
||||
OPENVDB_SKIP=false
|
||||
@@ -531,7 +524,7 @@ OPENVDB_SKIP=false
|
||||
ALEMBIC_VERSION="1.7.16"
|
||||
ALEMBIC_VERSION_SHORT="1.7"
|
||||
ALEMBIC_VERSION_MIN="1.7"
|
||||
ALEMBIC_VERSION_MEX="2.0"
|
||||
ALEMBIC_VERSION_MAX="2.0"
|
||||
ALEMBIC_FORCE_BUILD=false
|
||||
ALEMBIC_FORCE_REBUILD=false
|
||||
ALEMBIC_SKIP=false
|
||||
@@ -539,7 +532,7 @@ ALEMBIC_SKIP=false
|
||||
USD_VERSION="21.02"
|
||||
USD_VERSION_SHORT="21.02"
|
||||
USD_VERSION_MIN="20.05"
|
||||
USD_VERSION_MEX="22.00"
|
||||
USD_VERSION_MAX="22.00"
|
||||
USD_FORCE_BUILD=false
|
||||
USD_FORCE_REBUILD=false
|
||||
USD_SKIP=false
|
||||
@@ -547,7 +540,7 @@ USD_SKIP=false
|
||||
OPENCOLLADA_VERSION="1.6.68"
|
||||
OPENCOLLADA_VERSION_SHORT="1.6"
|
||||
OPENCOLLADA_VERSION_MIN="1.6.68"
|
||||
OPENCOLLADA_VERSION_MEX="1.7"
|
||||
OPENCOLLADA_VERSION_MAX="1.7"
|
||||
OPENCOLLADA_FORCE_BUILD=false
|
||||
OPENCOLLADA_FORCE_REBUILD=false
|
||||
OPENCOLLADA_SKIP=false
|
||||
@@ -555,7 +548,7 @@ OPENCOLLADA_SKIP=false
|
||||
EMBREE_VERSION="3.10.0"
|
||||
EMBREE_VERSION_SHORT="3.10"
|
||||
EMBREE_VERSION_MIN="3.10"
|
||||
EMBREE_VERSION_MEX="4.0"
|
||||
EMBREE_VERSION_MAX="4.0"
|
||||
EMBREE_FORCE_BUILD=false
|
||||
EMBREE_FORCE_REBUILD=false
|
||||
EMBREE_SKIP=false
|
||||
@@ -563,7 +556,7 @@ EMBREE_SKIP=false
|
||||
OIDN_VERSION="1.4.1"
|
||||
OIDN_VERSION_SHORT="1.4"
|
||||
OIDN_VERSION_MIN="1.4.0"
|
||||
OIDN_VERSION_MEX="1.5"
|
||||
OIDN_VERSION_MAX="1.5"
|
||||
OIDN_FORCE_BUILD=false
|
||||
OIDN_FORCE_REBUILD=false
|
||||
OIDN_SKIP=false
|
||||
@@ -573,7 +566,7 @@ ISPC_VERSION="1.16.0"
|
||||
FFMPEG_VERSION="4.4"
|
||||
FFMPEG_VERSION_SHORT="4.4"
|
||||
FFMPEG_VERSION_MIN="3.0"
|
||||
FFMPEG_VERSION_MEX="5.0"
|
||||
FFMPEG_VERSION_MAX="5.0"
|
||||
FFMPEG_FORCE_BUILD=false
|
||||
FFMPEG_FORCE_REBUILD=false
|
||||
FFMPEG_SKIP=false
|
||||
@@ -582,7 +575,7 @@ _ffmpeg_list_sep=";"
|
||||
XR_OPENXR_VERSION="1.0.17"
|
||||
XR_OPENXR_VERSION_SHORT="1.0"
|
||||
XR_OPENXR_VERSION_MIN="1.0.8"
|
||||
XR_OPENXR_VERSION_MEX="2.0"
|
||||
XR_OPENXR_VERSION_MAX="2.0"
|
||||
XR_OPENXR_FORCE_BUILD=false
|
||||
XR_OPENXR_FORCE_REBUILD=false
|
||||
XR_OPENXR_SKIP=false
|
||||
@@ -1148,11 +1141,10 @@ You may also want to build them yourself (optional ones are [between brackets]):
|
||||
|
||||
* Python $PYTHON_VERSION (from $PYTHON_SOURCE).
|
||||
** [IDNA $PYTHON_IDNA_VERSION] (use pip).
|
||||
** [Charset Normalizer $PYTHON_CHARSET_NORMALIZER_VERSION] (use pip).
|
||||
** [Chardet $PYTHON_CHARDET_VERSION] (use pip).
|
||||
** [Urllib3 $PYTHON_URLLIB3_VERSION] (use pip).
|
||||
** [Certifi $PYTHON_CERTIFI_VERSION] (use pip).
|
||||
** [Requests $PYTHON_REQUESTS_VERSION] (use pip).
|
||||
** [ZStandard $PYTHON_ZSTANDARD_VERSION] (use pip).
|
||||
** [NumPy $PYTHON_NUMPY_VERSION] (use pip).
|
||||
* Boost $BOOST_VERSION (from $BOOST_SOURCE, modules: $BOOST_BUILD_MODULES).
|
||||
* TBB $TBB_VERSION (from $TBB_SOURCE).
|
||||
@@ -2021,7 +2013,7 @@ compile_OIIO() {
|
||||
fi
|
||||
|
||||
# To be changed each time we make edits that would modify the compiled result!
|
||||
oiio_magic=18
|
||||
oiio_magic=17
|
||||
_init_oiio
|
||||
|
||||
# Force having own builds for the dependencies.
|
||||
@@ -2096,7 +2088,6 @@ compile_OIIO() {
|
||||
cmake_d="$cmake_d -D USE_PYTHON=OFF"
|
||||
cmake_d="$cmake_d -D USE_FFMPEG=OFF"
|
||||
cmake_d="$cmake_d -D USE_OPENCV=OFF"
|
||||
cmake_d="$cmake_d -D USE_OPENVDB=OFF"
|
||||
cmake_d="$cmake_d -D BUILD_TESTING=OFF"
|
||||
cmake_d="$cmake_d -D OIIO_BUILD_TESTS=OFF"
|
||||
cmake_d="$cmake_d -D OIIO_BUILD_TOOLS=OFF"
|
||||
@@ -4036,7 +4027,7 @@ install_DEB() {
|
||||
INFO "Forced Python building, as requested..."
|
||||
_do_compile_python=true
|
||||
else
|
||||
check_package_version_ge_lt_DEB python3-dev $PYTHON_VERSION_MIN $PYTHON_VERSION_MEX
|
||||
check_package_version_ge_lt_DEB python3-dev $PYTHON_VERSION_MIN $PYTHON_VERSION_MAX
|
||||
if [ $? -eq 0 ]; then
|
||||
PYTHON_VERSION_INSTALLED=$(echo `get_package_version_DEB python3-dev` | sed -r 's/^([0-9]+\.[0-9]+).*/\1/')
|
||||
|
||||
@@ -4049,8 +4040,8 @@ install_DEB() {
|
||||
module=($module)
|
||||
package="python3-${module[0]}"
|
||||
package_vmin=${module[1]}
|
||||
package_vmex=${module[2]}
|
||||
check_package_version_ge_lt_DEB "$package" $package_vmin $package_vmex
|
||||
package_vmax=${module[2]}
|
||||
check_package_version_ge_lt_DEB "$package" $package_vmin $package_vmax
|
||||
if [ $? -eq 0 ]; then
|
||||
install_packages_DEB "$package"
|
||||
else
|
||||
@@ -4076,7 +4067,7 @@ install_DEB() {
|
||||
INFO "Forced Boost building, as requested..."
|
||||
compile_Boost
|
||||
else
|
||||
check_package_version_ge_lt_DEB libboost-dev $BOOST_VERSION_MIN $BOOST_VERSION_MEX
|
||||
check_package_version_ge_lt_DEB libboost-dev $BOOST_VERSION_MIN $BOOST_VERSION_MAX
|
||||
if [ $? -eq 0 ]; then
|
||||
install_packages_DEB libboost-dev
|
||||
|
||||
@@ -4097,7 +4088,7 @@ install_DEB() {
|
||||
INFO "Forced TBB building, as requested..."
|
||||
compile_TBB
|
||||
else
|
||||
check_package_version_ge_lt_DEB libtbb-dev $TBB_VERSION_MIN $TBB_VERSION_MEX
|
||||
check_package_version_ge_lt_DEB libtbb-dev $TBB_VERSION_MIN $TBB_VERSION_MAX
|
||||
if [ $? -eq 0 ]; then
|
||||
install_packages_DEB libtbb-dev
|
||||
clean_TBB
|
||||
@@ -4114,7 +4105,7 @@ install_DEB() {
|
||||
INFO "Forced OpenColorIO building, as requested..."
|
||||
compile_OCIO
|
||||
else
|
||||
check_package_version_ge_lt_DEB libopencolorio-dev $OCIO_VERSION_MIN $OCIO_VERSION_MEX
|
||||
check_package_version_ge_lt_DEB libopencolorio-dev $OCIO_VERSION_MIN $OCIO_VERSION_MAX
|
||||
if [ $? -eq 0 ]; then
|
||||
install_packages_DEB libopencolorio-dev
|
||||
clean_OCIO
|
||||
@@ -4131,7 +4122,7 @@ install_DEB() {
|
||||
INFO "Forced ILMBase/OpenEXR building, as requested..."
|
||||
compile_OPENEXR
|
||||
else
|
||||
check_package_version_ge_lt_DEB libopenexr-dev $OPENEXR_VERSION_MIN $OPENEXR_VERSION_MEX
|
||||
check_package_version_ge_lt_DEB libopenexr-dev $OPENEXR_VERSION_MIN $OPENEXR_VERSION_MAX
|
||||
if [ $? -eq 0 ]; then
|
||||
install_packages_DEB libopenexr-dev
|
||||
OPENEXR_VERSION=`get_package_version_DEB libopenexr-dev`
|
||||
@@ -4152,7 +4143,7 @@ install_DEB() {
|
||||
INFO "Forced OpenImageIO building, as requested..."
|
||||
compile_OIIO
|
||||
else
|
||||
check_package_version_ge_lt_DEB libopenimageio-dev $OIIO_VERSION_MIN $OIIO_VERSION_MEX
|
||||
check_package_version_ge_lt_DEB libopenimageio-dev $OIIO_VERSION_MIN $OIIO_VERSION_MAX
|
||||
if [ $? -eq 0 -a "$_with_built_openexr" = false ]; then
|
||||
install_packages_DEB libopenimageio-dev openimageio-tools
|
||||
clean_OIIO
|
||||
@@ -4172,7 +4163,7 @@ install_DEB() {
|
||||
INFO "Forced LLVM building, as requested..."
|
||||
_do_compile_llvm=true
|
||||
else
|
||||
check_package_version_ge_lt_DEB llvm-dev $LLVM_VERSION_MIN $LLVM_VERSION_MEX
|
||||
check_package_version_ge_lt_DEB llvm-dev $LLVM_VERSION_MIN $LLVM_VERSION_MAX
|
||||
if [ $? -eq 0 ]; then
|
||||
install_packages_DEB llvm-dev clang libclang-dev
|
||||
have_llvm=true
|
||||
@@ -4203,7 +4194,7 @@ install_DEB() {
|
||||
INFO "Forced OpenShadingLanguage building, as requested..."
|
||||
_do_compile_osl=true
|
||||
else
|
||||
check_package_version_ge_lt_DEB libopenshadinglanguage-dev $OSL_VERSION_MIN $OSL_VERSION_MEX
|
||||
check_package_version_ge_lt_DEB libopenshadinglanguage-dev $OSL_VERSION_MIN $OSL_VERSION_MAX
|
||||
if [ $? -eq 0 ]; then
|
||||
install_packages_DEB libopenshadinglanguage-dev
|
||||
clean_OSL
|
||||
@@ -4241,7 +4232,7 @@ install_DEB() {
|
||||
INFO "Forced OpenVDB building, as requested..."
|
||||
compile_OPENVDB
|
||||
else
|
||||
check_package_version_ge_lt_DEB libopenvdb-dev $OPENVDB_VERSION_MIN $OPENVDB_VERSION_MEX
|
||||
check_package_version_ge_lt_DEB libopenvdb-dev $OPENVDB_VERSION_MIN $OPENVDB_VERSION_MAX
|
||||
if [ $? -eq 0 ]; then
|
||||
install_packages_DEB libopenvdb-dev libblosc-dev
|
||||
clean_OPENVDB
|
||||
@@ -4303,7 +4294,7 @@ install_DEB() {
|
||||
_do_compile_embree=true
|
||||
else
|
||||
# There is a package, but it does not provide everything that Blender needs...
|
||||
#~ check_package_version_ge_lt_DEB libembree-dev $EMBREE_VERSION_MIN $EMBREE_VERSION_MEX
|
||||
#~ check_package_version_ge_lt_DEB libembree-dev $EMBREE_VERSION_MIN $EMBREE_VERSION_MAX
|
||||
#~ if [ $? -eq 0 ]; then
|
||||
#~ install_packages_DEB libembree-dev
|
||||
#~ clean_Embree
|
||||
@@ -4345,7 +4336,7 @@ install_DEB() {
|
||||
# XXX Debian Testing / Ubuntu 16.04 finally includes FFmpeg, so check as usual
|
||||
check_package_DEB ffmpeg
|
||||
if [ $? -eq 0 ]; then
|
||||
check_package_version_ge_lt_DEB ffmpeg $FFMPEG_VERSION_MIN $FFMPEG_VERSION_MEX
|
||||
check_package_version_ge_lt_DEB ffmpeg $FFMPEG_VERSION_MIN $FFMPEG_VERSION_MAX
|
||||
if [ $? -eq 0 ]; then
|
||||
install_packages_DEB libavdevice-dev
|
||||
clean_FFmpeg
|
||||
@@ -4679,7 +4670,7 @@ install_RPM() {
|
||||
INFO "Forced Python building, as requested..."
|
||||
_do_compile_python=true
|
||||
else
|
||||
check_package_version_ge_lt_RPM python3-devel $PYTHON_VERSION_MIN $PYTHON_VERSION_MEX
|
||||
check_package_version_ge_lt_RPM python3-devel $PYTHON_VERSION_MIN $PYTHON_VERSION_MAX
|
||||
if [ $? -eq 0 ]; then
|
||||
PYTHON_VERSION_INSTALLED=$(echo `get_package_version_RPM python3-devel` | sed -r 's/^([0-9]+\.[0-9]+).*/\1/')
|
||||
|
||||
@@ -4691,8 +4682,8 @@ install_RPM() {
|
||||
module=($module)
|
||||
package="python3-${module[0]}"
|
||||
package_vmin=${module[1]}
|
||||
package_vmex=${module[2]}
|
||||
check_package_version_ge_lt_RPM "$package" $package_vmin $package_vmex
|
||||
package_vmax=${module[2]}
|
||||
check_package_version_ge_lt_RPM "$package" $package_vmin $package_vmax
|
||||
if [ $? -eq 0 ]; then
|
||||
install_packages_RPM "$package"
|
||||
else
|
||||
@@ -4719,7 +4710,7 @@ install_RPM() {
|
||||
INFO "Forced Boost building, as requested..."
|
||||
_do_compile_boost=true
|
||||
else
|
||||
check_package_version_ge_lt_RPM boost-devel $BOOST_VERSION_MIN $BOOST_VERSION_MEX
|
||||
check_package_version_ge_lt_RPM boost-devel $BOOST_VERSION_MIN $BOOST_VERSION_MAX
|
||||
if [ $? -eq 0 ]; then
|
||||
install_packages_RPM boost-devel
|
||||
clean_Boost
|
||||
@@ -4746,7 +4737,7 @@ install_RPM() {
|
||||
INFO "Forced TBB building, as requested..."
|
||||
compile_TBB
|
||||
else
|
||||
check_package_version_ge_lt_RPM tbb-devel $TBB_VERSION_MIN $TBB_VERSION_MEX
|
||||
check_package_version_ge_lt_RPM tbb-devel $TBB_VERSION_MIN $TBB_VERSION_MAX
|
||||
if [ $? -eq 0 ]; then
|
||||
install_packages_RPM tbb-devel
|
||||
clean_TBB
|
||||
@@ -4764,7 +4755,7 @@ install_RPM() {
|
||||
compile_OCIO
|
||||
else
|
||||
if [ "$RPM" = "SUSE" ]; then
|
||||
check_package_version_ge_lt_RPM OpenColorIO-devel $OCIO_VERSION_MIN $OCIO_VERSION_MEX
|
||||
check_package_version_ge_lt_RPM OpenColorIO-devel $OCIO_VERSION_MIN $OCIO_VERSION_MAX
|
||||
if [ $? -eq 0 ]; then
|
||||
install_packages_RPM OpenColorIO-devel
|
||||
clean_OCIO
|
||||
@@ -4784,7 +4775,7 @@ install_RPM() {
|
||||
INFO "Forced ILMBase/OpenEXR building, as requested..."
|
||||
compile_OPENEXR
|
||||
else
|
||||
check_package_version_ge_lt_RPM openexr-devel $OPENEXR_VERSION_MIN $OPENEXR_VERSION_MEX
|
||||
check_package_version_ge_lt_RPM openexr-devel $OPENEXR_VERSION_MIN $OPENEXR_VERSION_MAX
|
||||
if [ $? -eq 0 ]; then
|
||||
install_packages_RPM openexr-devel
|
||||
OPENEXR_VERSION=`get_package_version_RPM openexr-devel`
|
||||
@@ -4802,7 +4793,7 @@ install_RPM() {
|
||||
INFO "Forced OpenImageIO building, as requested..."
|
||||
compile_OIIO
|
||||
else
|
||||
check_package_version_ge_lt_RPM OpenImageIO-devel $OIIO_VERSION_MIN $OIIO_VERSION_MEX
|
||||
check_package_version_ge_lt_RPM OpenImageIO-devel $OIIO_VERSION_MIN $OIIO_VERSION_MAX
|
||||
if [ $? -eq 0 -a $_with_built_openexr == false ]; then
|
||||
install_packages_RPM OpenImageIO-devel OpenImageIO-utils
|
||||
clean_OIIO
|
||||
@@ -4827,7 +4818,7 @@ install_RPM() {
|
||||
else
|
||||
CLANG_DEV="clang-devel"
|
||||
fi
|
||||
check_package_version_ge_lt_RPM llvm-devel $LLVM_VERSION_MIN $LLVM_VERSION_MEX
|
||||
check_package_version_ge_lt_RPM llvm-devel $LLVM_VERSION_MIN $LLVM_VERSION_MAX
|
||||
if [ $? -eq 0 ]; then
|
||||
install_packages_RPM llvm-devel $CLANG_DEV
|
||||
have_llvm=true
|
||||
@@ -4863,7 +4854,7 @@ install_RPM() {
|
||||
else
|
||||
OSL_DEV="openshadinglanguage-devel"
|
||||
fi
|
||||
check_package_version_ge_lt_RPM $OSL_DEV $OSL_VERSION_MIN $OSL_VERSION_MEX
|
||||
check_package_version_ge_lt_RPM $OSL_DEV $OSL_VERSION_MIN $OSL_VERSION_MAX
|
||||
if [ $? -eq 0 ]; then
|
||||
install_packages_RPM $OSL_DEV
|
||||
clean_OSL
|
||||
@@ -4958,7 +4949,7 @@ install_RPM() {
|
||||
_do_compile_embree=true
|
||||
else
|
||||
# There is a package, but it does not provide everything that Blender needs...
|
||||
#~ check_package_version_ge_lt_RPM embree-devel $EMBREE_VERSION_MIN $EMBREE_VERSION_MEX
|
||||
#~ check_package_version_ge_lt_RPM embree-devel $EMBREE_VERSION_MIN $EMBREE_VERSION_MAX
|
||||
#~ if [ $? -eq 0 ]; then
|
||||
#~ install_packages_RPM embree-devel
|
||||
#~ clean_Embree
|
||||
@@ -4997,7 +4988,7 @@ install_RPM() {
|
||||
INFO "Forced FFMpeg building, as requested..."
|
||||
compile_FFmpeg
|
||||
else
|
||||
check_package_version_ge_lt_RPM ffmpeg-devel $FFMPEG_VERSION_MIN $FFMPEG_VERSION_MEX
|
||||
check_package_version_ge_lt_RPM ffmpeg-devel $FFMPEG_VERSION_MIN $FFMPEG_VERSION_MAX
|
||||
if [ $? -eq 0 ]; then
|
||||
install_packages_RPM ffmpeg ffmpeg-devel
|
||||
clean_FFmpeg
|
||||
@@ -5222,7 +5213,7 @@ install_ARCH() {
|
||||
INFO "Forced Python building, as requested..."
|
||||
_do_compile_python=true
|
||||
else
|
||||
check_package_version_ge_lt_ARCH python $PYTHON_VERSION_MIN $PYTHON_VERSION_MEX
|
||||
check_package_version_ge_lt_ARCH python $PYTHON_VERSION_MIN $PYTHON_VERSION_MAX
|
||||
if [ $? -eq 0 ]; then
|
||||
PYTHON_VERSION_INSTALLED=$(echo `get_package_version_ARCH python` | sed -r 's/^([0-9]+\.[0-9]+).*/\1/')
|
||||
|
||||
@@ -5235,8 +5226,8 @@ install_ARCH() {
|
||||
module=($module)
|
||||
package="python-${module[0]}"
|
||||
package_vmin=${module[1]}
|
||||
package_vmex=${module[2]}
|
||||
check_package_version_ge_lt_ARCH "$package" $package_vmin $package_vmex
|
||||
package_vmax=${module[2]}
|
||||
check_package_version_ge_lt_ARCH "$package" $package_vmin $package_vmax
|
||||
if [ $? -eq 0 ]; then
|
||||
install_packages_ARCH "$package"
|
||||
else
|
||||
@@ -5262,7 +5253,7 @@ install_ARCH() {
|
||||
INFO "Forced Boost building, as requested..."
|
||||
compile_Boost
|
||||
else
|
||||
check_package_version_ge_lt_ARCH boost $BOOST_VERSION_MIN $BOOST_VERSION_MEX
|
||||
check_package_version_ge_lt_ARCH boost $BOOST_VERSION_MIN $BOOST_VERSION_MAX
|
||||
if [ $? -eq 0 ]; then
|
||||
install_packages_ARCH boost
|
||||
clean_Boost
|
||||
@@ -5279,7 +5270,7 @@ install_ARCH() {
|
||||
INFO "Forced TBB building, as requested..."
|
||||
compile_TBB
|
||||
else
|
||||
check_package_version_ge_lt_ARCH intel-tbb $TBB_VERSION_MIN $TBB_VERSION_MEX
|
||||
check_package_version_ge_lt_ARCH intel-tbb $TBB_VERSION_MIN $TBB_VERSION_MAX
|
||||
if [ $? -eq 0 ]; then
|
||||
install_packages_ARCH intel-tbb
|
||||
clean_TBB
|
||||
@@ -5296,7 +5287,7 @@ install_ARCH() {
|
||||
INFO "Forced OpenColorIO building, as requested..."
|
||||
compile_OCIO
|
||||
else
|
||||
check_package_version_ge_lt_ARCH opencolorio $OCIO_VERSION_MIN $OCIO_VERSION_MEX
|
||||
check_package_version_ge_lt_ARCH opencolorio $OCIO_VERSION_MIN $OCIO_VERSION_MAX
|
||||
if [ $? -eq 0 ]; then
|
||||
install_packages_ARCH opencolorio
|
||||
clean_OCIO
|
||||
@@ -5313,7 +5304,7 @@ install_ARCH() {
|
||||
INFO "Forced ILMBase/OpenEXR building, as requested..."
|
||||
compile_OPENEXR
|
||||
else
|
||||
check_package_version_ge_lt_ARCH openexr $OPENEXR_VERSION_MIN $OPENEXR_VERSION_MEX
|
||||
check_package_version_ge_lt_ARCH openexr $OPENEXR_VERSION_MIN $OPENEXR_VERSION_MAX
|
||||
if [ $? -eq 0 ]; then
|
||||
install_packages_ARCH openexr
|
||||
OPENEXR_VERSION=`get_package_version_ARCH openexr`
|
||||
@@ -5332,7 +5323,7 @@ install_ARCH() {
|
||||
INFO "Forced OpenImageIO building, as requested..."
|
||||
compile_OIIO
|
||||
else
|
||||
check_package_version_ge_lt_ARCH openimageio $OIIO_VERSION_MIN $OIIO_VERSION_MEX
|
||||
check_package_version_ge_lt_ARCH openimageio $OIIO_VERSION_MIN $OIIO_VERSION_MAX
|
||||
if [ $? -eq 0 ]; then
|
||||
install_packages_ARCH openimageio
|
||||
clean_OIIO
|
||||
@@ -5352,7 +5343,7 @@ install_ARCH() {
|
||||
INFO "Forced LLVM building, as requested..."
|
||||
_do_compile_llvm=true
|
||||
else
|
||||
check_package_version_ge_lt_ARCH llvm $LLVM_VERSION_MIN $LLVM_VERSION_MEX
|
||||
check_package_version_ge_lt_ARCH llvm $LLVM_VERSION_MIN $LLVM_VERSION_MAX
|
||||
if [ $? -eq 0 ]; then
|
||||
install_packages_ARCH llvm clang
|
||||
have_llvm=true
|
||||
@@ -5383,7 +5374,7 @@ install_ARCH() {
|
||||
INFO "Forced OpenShadingLanguage building, as requested..."
|
||||
_do_compile_osl=true
|
||||
else
|
||||
check_package_version_ge_lt_ARCH openshadinglanguage $OSL_VERSION_MIN $OSL_VERSION_MEX
|
||||
check_package_version_ge_lt_ARCH openshadinglanguage $OSL_VERSION_MIN $OSL_VERSION_MAX
|
||||
if [ $? -eq 0 ]; then
|
||||
install_packages_ARCH openshadinglanguage
|
||||
clean_OSL
|
||||
@@ -5409,7 +5400,7 @@ install_ARCH() {
|
||||
INFO "Forced OpenSubdiv building, as requested..."
|
||||
compile_OSD
|
||||
else
|
||||
check_package_version_ge_lt_ARCH opensubdiv $OSD_VERSION_MIN $OSD_VERSION_MEX
|
||||
check_package_version_ge_lt_ARCH opensubdiv $OSD_VERSION_MIN $OSD_VERSION_MAX
|
||||
if [ $? -eq 0 ]; then
|
||||
install_packages_ARCH opensubdiv
|
||||
clean_OSD
|
||||
@@ -5426,7 +5417,7 @@ install_ARCH() {
|
||||
INFO "Forced OpenVDB building, as requested..."
|
||||
compile_OPENVDB
|
||||
else
|
||||
check_package_version_ge_lt_ARCH openvdb $OPENVDB_VERSION_MIN $OPENVDB_VERSION_MEX
|
||||
check_package_version_ge_lt_ARCH openvdb $OPENVDB_VERSION_MIN $OPENVDB_VERSION_MAX
|
||||
if [ $? -eq 0 ]; then
|
||||
install_packages_ARCH openvdb
|
||||
clean_OPENVDB
|
||||
@@ -5492,7 +5483,7 @@ install_ARCH() {
|
||||
_do_compile_embree=true
|
||||
else
|
||||
# There is a package, but it does not provide everything that Blender needs...
|
||||
#~ check_package_version_ge_lt_ARCH embree $EMBREE_VERSION_MIN $EMBREE_VERSION_MEX
|
||||
#~ check_package_version_ge_lt_ARCH embree $EMBREE_VERSION_MIN $EMBREE_VERSION_MAX
|
||||
#~ if [ $? -eq 0 ]; then
|
||||
#~ install_packages_ARCH embree
|
||||
#~ clean_Embree
|
||||
@@ -5531,7 +5522,7 @@ install_ARCH() {
|
||||
INFO "Forced FFMpeg building, as requested..."
|
||||
compile_FFmpeg
|
||||
else
|
||||
check_package_version_ge_lt_ARCH ffmpeg $FFMPEG_VERSION_MIN $FFMPEG_VERSION_MEX
|
||||
check_package_version_ge_lt_ARCH ffmpeg $FFMPEG_VERSION_MIN $FFMPEG_VERSION_MAX
|
||||
if [ $? -eq 0 ]; then
|
||||
install_packages_ARCH ffmpeg
|
||||
clean_FFmpeg
|
||||
|
@@ -70,18 +70,16 @@
|
||||
}
|
||||
--- a/libavcodec/rl.c
|
||||
+++ b/libavcodec/rl.c
|
||||
@@ -71,17 +71,19 @@
|
||||
@@ -71,7 +71,7 @@ av_cold void ff_rl_init(RLTable *rl,
|
||||
av_cold void ff_rl_init_vlc(RLTable *rl, unsigned static_size)
|
||||
{
|
||||
int i, q;
|
||||
- VLC_TYPE table[1500][2] = {{0}};
|
||||
+ VLC_TYPE (*table)[2] = av_calloc(sizeof(VLC_TYPE), 1500 * 2);
|
||||
VLC vlc = { .table = table, .table_allocated = static_size };
|
||||
- av_assert0(static_size <= FF_ARRAY_ELEMS(table));
|
||||
+ av_assert0(static_size < 1500);
|
||||
av_assert0(static_size <= FF_ARRAY_ELEMS(table));
|
||||
init_vlc(&vlc, 9, rl->n + 1, &rl->table_vlc[0][1], 4, 2, &rl->table_vlc[0][0], 4, 2, INIT_VLC_USE_NEW_STATIC);
|
||||
|
||||
for (q = 0; q < 32; q++) {
|
||||
@@ -80,8 +80,10 @@ av_cold void ff_rl_init_vlc(RLTable *rl, unsigned static_size)
|
||||
int qmul = q * 2;
|
||||
int qadd = (q - 1) | 1;
|
||||
|
||||
@@ -93,7 +91,7 @@
|
||||
|
||||
if (q == 0) {
|
||||
qmul = 1;
|
||||
@@ -113,4 +115,5 @@
|
||||
@@ -113,4 +115,5 @@ av_cold void ff_rl_init_vlc(RLTable *rl, unsigned static_size)
|
||||
rl->rl_vlc[q][i].run = run;
|
||||
}
|
||||
}
|
||||
|
27
build_files/build_environment/patches/numpy.diff
Normal file
27
build_files/build_environment/patches/numpy.diff
Normal file
@@ -0,0 +1,27 @@
|
||||
diff --git a/numpy/distutils/system_info.py b/numpy/distutils/system_info.py
|
||||
index ba2b1f4..b10f7df 100644
|
||||
--- a/numpy/distutils/system_info.py
|
||||
+++ b/numpy/distutils/system_info.py
|
||||
@@ -2164,8 +2164,8 @@ class accelerate_info(system_info):
|
||||
'accelerate' in libraries):
|
||||
if intel:
|
||||
args.extend(['-msse3'])
|
||||
- else:
|
||||
- args.extend(['-faltivec'])
|
||||
+# else:
|
||||
+# args.extend(['-faltivec'])
|
||||
args.extend([
|
||||
'-I/System/Library/Frameworks/vecLib.framework/Headers'])
|
||||
link_args.extend(['-Wl,-framework', '-Wl,Accelerate'])
|
||||
@@ -2174,8 +2174,8 @@ class accelerate_info(system_info):
|
||||
'veclib' in libraries):
|
||||
if intel:
|
||||
args.extend(['-msse3'])
|
||||
- else:
|
||||
- args.extend(['-faltivec'])
|
||||
+# else:
|
||||
+# args.extend(['-faltivec'])
|
||||
args.extend([
|
||||
'-I/System/Library/Frameworks/vecLib.framework/Headers'])
|
||||
link_args.extend(['-Wl,-framework', '-Wl,vecLib'])
|
||||
|
@@ -79,9 +79,6 @@ set STAGING=%BUILD_DIR%\S
|
||||
rem for python module build
|
||||
set MSSdk=1
|
||||
set DISTUTILS_USE_SDK=1
|
||||
rem if you let pip pick its own build dirs, it'll stick it somewhere deep inside the user profile
|
||||
rem and cython will refuse to link due to a path that gets too long.
|
||||
set TMPDIR=c:\t\
|
||||
rem for python externals source to be shared between the various archs and compilers
|
||||
mkdir %BUILD_DIR%\downloads\externals
|
||||
|
||||
|
@@ -1,81 +0,0 @@
|
||||
# - Find HIP compiler
|
||||
#
|
||||
# This module defines
|
||||
# HIP_HIPCC_EXECUTABLE, the full path to the hipcc executable
|
||||
# HIP_VERSION, the HIP compiler version
|
||||
#
|
||||
# HIP_FOUND, if the HIP toolkit is found.
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2021 Blender Foundation.
|
||||
#
|
||||
# Distributed under the OSI-approved BSD 3-Clause License,
|
||||
# see accompanying file BSD-3-Clause-license.txt for details.
|
||||
#=============================================================================
|
||||
|
||||
# If HIP_ROOT_DIR was defined in the environment, use it.
|
||||
if(NOT HIP_ROOT_DIR AND NOT $ENV{HIP_ROOT_DIR} STREQUAL "")
|
||||
set(HIP_ROOT_DIR $ENV{HIP_ROOT_DIR})
|
||||
endif()
|
||||
|
||||
set(_hip_SEARCH_DIRS
|
||||
${HIP_ROOT_DIR}
|
||||
)
|
||||
|
||||
find_program(HIP_HIPCC_EXECUTABLE
|
||||
NAMES
|
||||
hipcc
|
||||
HINTS
|
||||
${_hip_SEARCH_DIRS}
|
||||
PATH_SUFFIXES
|
||||
bin
|
||||
)
|
||||
|
||||
if(HIP_HIPCC_EXECUTABLE AND NOT EXISTS ${HIP_HIPCC_EXECUTABLE})
|
||||
message(WARNING "Cached or directly specified hipcc executable does not exist.")
|
||||
set(HIP_FOUND FALSE)
|
||||
elseif(HIP_HIPCC_EXECUTABLE)
|
||||
set(HIP_FOUND TRUE)
|
||||
|
||||
set(HIP_VERSION_MAJOR 0)
|
||||
set(HIP_VERSION_MINOR 0)
|
||||
set(HIP_VERSION_PATCH 0)
|
||||
|
||||
# Get version from the output.
|
||||
execute_process(COMMAND ${HIP_HIPCC_EXECUTABLE} --version
|
||||
OUTPUT_VARIABLE HIP_VERSION_RAW
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
# Parse parts.
|
||||
if(HIP_VERSION_RAW MATCHES "HIP version: .*")
|
||||
# Strip the HIP prefix and get list of individual version components.
|
||||
string(REGEX REPLACE
|
||||
".*HIP version: ([.0-9]+).*" "\\1"
|
||||
HIP_SEMANTIC_VERSION "${HIP_VERSION_RAW}")
|
||||
string(REPLACE "." ";" HIP_VERSION_PARTS "${HIP_SEMANTIC_VERSION}")
|
||||
list(LENGTH HIP_VERSION_PARTS NUM_HIP_VERSION_PARTS)
|
||||
|
||||
# Extract components into corresponding variables.
|
||||
if(NUM_HIP_VERSION_PARTS GREATER 0)
|
||||
list(GET HIP_VERSION_PARTS 0 HIP_VERSION_MAJOR)
|
||||
endif()
|
||||
if(NUM_HIP_VERSION_PARTS GREATER 1)
|
||||
list(GET HIP_VERSION_PARTS 1 HIP_VERSION_MINOR)
|
||||
endif()
|
||||
if(NUM_HIP_VERSION_PARTS GREATER 2)
|
||||
list(GET HIP_VERSION_PARTS 2 HIP_VERSION_PATCH)
|
||||
endif()
|
||||
|
||||
# Unset temp variables.
|
||||
unset(NUM_HIP_VERSION_PARTS)
|
||||
unset(HIP_SEMANTIC_VERSION)
|
||||
unset(HIP_VERSION_PARTS)
|
||||
endif()
|
||||
|
||||
# Construct full semantic version.
|
||||
set(HIP_VERSION "${HIP_VERSION_MAJOR}.${HIP_VERSION_MINOR}.${HIP_VERSION_PATCH}")
|
||||
unset(HIP_VERSION_RAW)
|
||||
else()
|
||||
set(HIP_FOUND FALSE)
|
||||
endif()
|
@@ -33,23 +33,11 @@ FIND_PATH(OPTIX_INCLUDE_DIR
|
||||
include
|
||||
)
|
||||
|
||||
IF(EXISTS "${OPTIX_INCLUDE_DIR}/optix.h")
|
||||
FILE(STRINGS "${OPTIX_INCLUDE_DIR}/optix.h" _optix_version REGEX "^#define OPTIX_VERSION[ \t].*$")
|
||||
STRING(REGEX MATCHALL "[0-9]+" _optix_version ${_optix_version})
|
||||
|
||||
MATH(EXPR _optix_version_major "${_optix_version} / 10000")
|
||||
MATH(EXPR _optix_version_minor "(${_optix_version} % 10000) / 100")
|
||||
MATH(EXPR _optix_version_patch "${_optix_version} % 100")
|
||||
|
||||
SET(OPTIX_VERSION "${_optix_version_major}.${_optix_version_minor}.${_optix_version_patch}")
|
||||
ENDIF()
|
||||
|
||||
# handle the QUIETLY and REQUIRED arguments and set OPTIX_FOUND to TRUE if
|
||||
# all listed variables are TRUE
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(OptiX
|
||||
REQUIRED_VARS OPTIX_INCLUDE_DIR
|
||||
VERSION_VAR OPTIX_VERSION)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(OptiX DEFAULT_MSG
|
||||
OPTIX_INCLUDE_DIR)
|
||||
|
||||
IF(OPTIX_FOUND)
|
||||
SET(OPTIX_INCLUDE_DIRS ${OPTIX_INCLUDE_DIR})
|
||||
@@ -57,7 +45,6 @@ ENDIF()
|
||||
|
||||
MARK_AS_ADVANCED(
|
||||
OPTIX_INCLUDE_DIR
|
||||
OPTIX_VERSION
|
||||
)
|
||||
|
||||
UNSET(_optix_SEARCH_DIRS)
|
||||
|
@@ -24,7 +24,6 @@ import project_source_info
|
||||
import subprocess
|
||||
import sys
|
||||
import os
|
||||
import tempfile
|
||||
|
||||
from typing import (
|
||||
Any,
|
||||
@@ -36,6 +35,7 @@ USE_QUIET = (os.environ.get("QUIET", None) is not None)
|
||||
|
||||
CHECKER_IGNORE_PREFIX = [
|
||||
"extern",
|
||||
"intern/moto",
|
||||
]
|
||||
|
||||
CHECKER_BIN = "cppcheck"
|
||||
@@ -47,19 +47,13 @@ CHECKER_ARGS = [
|
||||
"--max-configs=1", # speeds up execution
|
||||
# "--check-config", # when includes are missing
|
||||
"--enable=all", # if you want sixty hundred pedantic suggestions
|
||||
|
||||
# Quiet output, otherwise all defines/includes are printed (overly verbose).
|
||||
# Only enable this for troubleshooting (if defines are not set as expected for example).
|
||||
"--quiet",
|
||||
|
||||
# NOTE: `--cppcheck-build-dir=<dir>` is added later as a temporary directory.
|
||||
]
|
||||
|
||||
if USE_QUIET:
|
||||
CHECKER_ARGS.append("--quiet")
|
||||
|
||||
|
||||
def cppcheck() -> None:
|
||||
def main() -> None:
|
||||
source_info = project_source_info.build_info(ignore_prefix_list=CHECKER_IGNORE_PREFIX)
|
||||
source_defines = project_source_info.build_defines_as_args()
|
||||
|
||||
@@ -84,10 +78,7 @@ def cppcheck() -> None:
|
||||
percent_str = "[" + ("%.2f]" % percent).rjust(7) + " %:"
|
||||
|
||||
sys.stdout.flush()
|
||||
sys.stdout.write("%s %s\n" % (
|
||||
percent_str,
|
||||
os.path.relpath(c, project_source_info.SOURCE_DIR)
|
||||
))
|
||||
sys.stdout.write("%s " % percent_str)
|
||||
|
||||
return subprocess.Popen(cmd)
|
||||
|
||||
@@ -99,11 +90,5 @@ def cppcheck() -> None:
|
||||
print("Finished!")
|
||||
|
||||
|
||||
def main() -> None:
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
CHECKER_ARGS.append("--cppcheck-build-dir=" + temp_dir)
|
||||
cppcheck()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
@@ -9,7 +9,6 @@ set(WITH_INSTALL_PORTABLE ON CACHE BOOL "" FORCE)
|
||||
|
||||
set(WITH_ALEMBIC OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_AUDASPACE OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_BLENDER_THUMBNAILER OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_BOOST OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_BUILDINFO OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_BULLET OFF CACHE BOOL "" FORCE)
|
||||
|
@@ -27,7 +27,7 @@ if(NOT MSVC)
|
||||
endif()
|
||||
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
set(MSVC_CLANG ON)
|
||||
set(MSVC_CLANG On)
|
||||
set(VC_TOOLS_DIR $ENV{VCToolsRedistDir} CACHE STRING "Location of the msvc redistributables")
|
||||
set(MSVC_REDIST_DIR ${VC_TOOLS_DIR})
|
||||
if(DEFINED MSVC_REDIST_DIR)
|
||||
@@ -53,7 +53,7 @@ if(CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
endif()
|
||||
if(WITH_WINDOWS_STRIPPED_PDB)
|
||||
message(WARNING "stripped pdb not supported with clang, disabling..")
|
||||
set(WITH_WINDOWS_STRIPPED_PDB OFF)
|
||||
set(WITH_WINDOWS_STRIPPED_PDB Off)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -159,7 +159,7 @@ endif()
|
||||
if(WITH_COMPILER_ASAN AND MSVC AND NOT MSVC_CLANG)
|
||||
if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.28.29828)
|
||||
#set a flag so we don't have to do this comparison all the time
|
||||
SET(MSVC_ASAN ON)
|
||||
SET(MSVC_ASAN On)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /fsanitize=address")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /fsanitize=address")
|
||||
string(APPEND CMAKE_EXE_LINKER_FLAGS_DEBUG " /INCREMENTAL:NO")
|
||||
@@ -179,22 +179,22 @@ endif()
|
||||
|
||||
if(WITH_WINDOWS_SCCACHE AND CMAKE_VS_MSBUILD_COMMAND)
|
||||
message(WARNING "Disabling sccache, sccache is not supported with msbuild")
|
||||
set(WITH_WINDOWS_SCCACHE OFF)
|
||||
set(WITH_WINDOWS_SCCACHE Off)
|
||||
endif()
|
||||
|
||||
# Debug Symbol format
|
||||
# sccache # MSVC_ASAN # format # why
|
||||
# ON # ON # Z7 # sccache will only play nice with Z7
|
||||
# ON # OFF # Z7 # sccache will only play nice with Z7
|
||||
# OFF # ON # Zi # Asan will not play nice with Edit and Continue
|
||||
# OFF # OFF # ZI # Neither asan nor sscache is enabled Edit and Continue is available
|
||||
# On # On # Z7 # sccache will only play nice with Z7
|
||||
# On # Off # Z7 # sccache will only play nice with Z7
|
||||
# Off # On # Zi # Asan will not play nice with Edit and Continue
|
||||
# Off # Off # ZI # Neither asan nor sscache is enabled Edit and Continue is available
|
||||
|
||||
# Release Symbol format
|
||||
# sccache # MSVC_ASAN # format # why
|
||||
# ON # ON # Z7 # sccache will only play nice with Z7
|
||||
# ON # OFF # Z7 # sccache will only play nice with Z7
|
||||
# OFF # ON # Zi # Asan will not play nice with Edit and Continue
|
||||
# OFF # OFF # Zi # Edit and Continue disables some optimizations
|
||||
# On # On # Z7 # sccache will only play nice with Z7
|
||||
# On # Off # Z7 # sccache will only play nice with Z7
|
||||
# Off # On # Zi # Asan will not play nice with Edit and Continue
|
||||
# Off # Off # Zi # Edit and Continue disables some optimizations
|
||||
|
||||
|
||||
if(WITH_WINDOWS_SCCACHE)
|
||||
@@ -288,7 +288,7 @@ if(CMAKE_GENERATOR MATCHES "^Visual Studio.+" AND # Only supported in the VS IDE
|
||||
"EnableMicrosoftCodeAnalysis=false"
|
||||
"EnableClangTidyCodeAnalysis=true"
|
||||
)
|
||||
set(VS_CLANG_TIDY ON)
|
||||
set(VS_CLANG_TIDY On)
|
||||
endif()
|
||||
|
||||
# Mark libdir as system headers with a lower warn level, to resolve some warnings
|
||||
@@ -469,7 +469,7 @@ if(WITH_PYTHON)
|
||||
|
||||
set(PYTHON_INCLUDE_DIR ${LIBDIR}/python/${_PYTHON_VERSION_NO_DOTS}/include)
|
||||
set(PYTHON_NUMPY_INCLUDE_DIRS ${LIBDIR}/python/${_PYTHON_VERSION_NO_DOTS}/lib/site-packages/numpy/core/include)
|
||||
set(NUMPY_FOUND ON)
|
||||
set(NUMPY_FOUND On)
|
||||
unset(_PYTHON_VERSION_NO_DOTS)
|
||||
# uncached vars
|
||||
set(PYTHON_INCLUDE_DIRS "${PYTHON_INCLUDE_DIR}")
|
||||
@@ -853,18 +853,18 @@ if(WITH_GMP)
|
||||
set(GMP_INCLUDE_DIRS ${LIBDIR}/gmp/include)
|
||||
set(GMP_LIBRARIES ${LIBDIR}/gmp/lib/libgmp-10.lib optimized ${LIBDIR}/gmp/lib/libgmpxx.lib debug ${LIBDIR}/gmp/lib/libgmpxx_d.lib)
|
||||
set(GMP_ROOT_DIR ${LIBDIR}/gmp)
|
||||
set(GMP_FOUND ON)
|
||||
set(GMP_FOUND On)
|
||||
endif()
|
||||
|
||||
if(WITH_POTRACE)
|
||||
set(POTRACE_INCLUDE_DIRS ${LIBDIR}/potrace/include)
|
||||
set(POTRACE_LIBRARIES ${LIBDIR}/potrace/lib/potrace.lib)
|
||||
set(POTRACE_FOUND ON)
|
||||
set(POTRACE_FOUND On)
|
||||
endif()
|
||||
|
||||
if(WITH_HARU)
|
||||
if(EXISTS ${LIBDIR}/haru)
|
||||
set(HARU_FOUND ON)
|
||||
set(HARU_FOUND On)
|
||||
set(HARU_ROOT_DIR ${LIBDIR}/haru)
|
||||
set(HARU_INCLUDE_DIRS ${HARU_ROOT_DIR}/include)
|
||||
set(HARU_LIBRARIES ${HARU_ROOT_DIR}/lib/libhpdfs.lib)
|
||||
|
@@ -243,9 +243,7 @@ def build_defines_as_args() -> List[str]:
|
||||
# use this module.
|
||||
def queue_processes(
|
||||
process_funcs: Sequence[Tuple[Callable[..., subprocess.Popen[Any]], Tuple[Any, ...]]],
|
||||
*,
|
||||
job_total: int =-1,
|
||||
sleep: float = 0.1,
|
||||
) -> None:
|
||||
""" Takes a list of function arg pairs, each function must return a process
|
||||
"""
|
||||
@@ -273,20 +271,14 @@ def queue_processes(
|
||||
|
||||
if len(processes) <= job_total:
|
||||
break
|
||||
time.sleep(sleep)
|
||||
else:
|
||||
time.sleep(0.1)
|
||||
|
||||
sys.stdout.flush()
|
||||
sys.stderr.flush()
|
||||
|
||||
processes.append(func(*args))
|
||||
|
||||
# Don't return until all jobs have finished.
|
||||
while 1:
|
||||
processes[:] = [p for p in processes if p.poll() is None]
|
||||
if not processes:
|
||||
break
|
||||
time.sleep(sleep)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
if not os.path.exists(join(CMAKE_DIR, "CMakeCache.txt")):
|
||||
|
@@ -5,38 +5,38 @@
|
||||
update-code:
|
||||
git:
|
||||
submodules:
|
||||
- branch: blender-v3.0-release
|
||||
- branch: master
|
||||
commit_id: HEAD
|
||||
path: release/scripts/addons
|
||||
- branch: blender-v3.0-release
|
||||
- branch: master
|
||||
commit_id: HEAD
|
||||
path: release/scripts/addons_contrib
|
||||
- branch: blender-v3.0-release
|
||||
- branch: master
|
||||
commit_id: HEAD
|
||||
path: release/datafiles/locale
|
||||
- branch: blender-v3.0-release
|
||||
- branch: master
|
||||
commit_id: HEAD
|
||||
path: source/tools
|
||||
svn:
|
||||
libraries:
|
||||
darwin-arm64:
|
||||
branch: tags/blender-3.0-release
|
||||
branch: trunk
|
||||
commit_id: HEAD
|
||||
path: lib/darwin_arm64
|
||||
darwin-x86_64:
|
||||
branch: tags/blender-3.0-release
|
||||
branch: trunk
|
||||
commit_id: HEAD
|
||||
path: lib/darwin
|
||||
linux-x86_64:
|
||||
branch: tags/blender-3.0-release
|
||||
branch: trunk
|
||||
commit_id: HEAD
|
||||
path: lib/linux_centos7_x86_64
|
||||
windows-amd64:
|
||||
branch: tags/blender-3.0-release
|
||||
branch: trunk
|
||||
commit_id: HEAD
|
||||
path: lib/win64_vc15
|
||||
tests:
|
||||
branch: tags/blender-3.0-release
|
||||
branch: trunk
|
||||
commit_id: HEAD
|
||||
path: lib/tests
|
||||
benchmarks:
|
||||
@@ -55,7 +55,7 @@ buildbot:
|
||||
cuda11:
|
||||
version: '11.4.1'
|
||||
optix:
|
||||
version: '7.3.0'
|
||||
version: '7.1.0'
|
||||
cmake:
|
||||
default:
|
||||
version: any
|
||||
|
@@ -200,20 +200,16 @@ def submodules_update(args, release_version, branch):
|
||||
if msg:
|
||||
skip_msg += submodule_path + " skipped: " + msg + "\n"
|
||||
else:
|
||||
# Find a matching branch that exists.
|
||||
call([args.git_command, "fetch", "origin"])
|
||||
if make_utils.git_branch_exists(args.git_command, submodule_branch):
|
||||
pass
|
||||
elif make_utils.git_branch_exists(args.git_command, submodule_branch_fallback):
|
||||
submodule_branch = submodule_branch_fallback
|
||||
else:
|
||||
submodule_branch = None
|
||||
|
||||
# Switch to branch and pull.
|
||||
if submodule_branch:
|
||||
if make_utils.git_branch(args.git_command) != submodule_branch:
|
||||
call([args.git_command, "checkout", submodule_branch])
|
||||
call([args.git_command, "pull", "--rebase", "origin", submodule_branch])
|
||||
# We are using `exit_on_error=False` here because sub-modules are allowed to not have requested branch,
|
||||
# in which case falling back to default back-up branch is fine.
|
||||
if make_utils.git_branch(args.git_command) != submodule_branch:
|
||||
call([args.git_command, "fetch", "origin"])
|
||||
call([args.git_command, "checkout", submodule_branch], exit_on_error=False)
|
||||
call([args.git_command, "pull", "--rebase", "origin", submodule_branch], exit_on_error=False)
|
||||
# If we cannot find the specified branch for this submodule, fallback to default one (aka master).
|
||||
if make_utils.git_branch(args.git_command) != submodule_branch:
|
||||
call([args.git_command, "checkout", submodule_branch_fallback])
|
||||
call([args.git_command, "pull", "--rebase", "origin", submodule_branch_fallback])
|
||||
finally:
|
||||
os.chdir(cwd)
|
||||
|
||||
|
@@ -8,19 +8,14 @@ import subprocess
|
||||
import sys
|
||||
|
||||
|
||||
def call(cmd, exit_on_error=True, silent=False):
|
||||
if not silent:
|
||||
print(" ".join(cmd))
|
||||
def call(cmd, exit_on_error=True):
|
||||
print(" ".join(cmd))
|
||||
|
||||
# Flush to ensure correct order output on Windows.
|
||||
sys.stdout.flush()
|
||||
sys.stderr.flush()
|
||||
|
||||
if silent:
|
||||
retcode = subprocess.call(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||
else:
|
||||
retcode = subprocess.call(cmd)
|
||||
|
||||
retcode = subprocess.call(cmd)
|
||||
if exit_on_error and retcode != 0:
|
||||
sys.exit(retcode)
|
||||
return retcode
|
||||
@@ -43,11 +38,6 @@ def check_output(cmd, exit_on_error=True):
|
||||
return output.strip()
|
||||
|
||||
|
||||
def git_branch_exists(git_command, branch):
|
||||
return call([git_command, "rev-parse", "--verify", branch], exit_on_error=False, silent=True) == 0 or \
|
||||
call([git_command, "rev-parse", "--verify", "remotes/origin/" + branch], exit_on_error=False, silent=True) == 0
|
||||
|
||||
|
||||
def git_branch(git_command):
|
||||
# Get current branch name.
|
||||
try:
|
||||
|
@@ -3,7 +3,7 @@ for %%X in (svn.exe) do (set SVN=%%~$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 (git.exe) do (set GIT=%%~$PATH:X)
|
||||
set PYTHON=%BLENDER_DIR%\..\lib\win64_vc15\python\39\bin\python.exe
|
||||
set PYTHON=%BLENDER_DIR%\..\lib\win64_vc15\python\37\bin\python.exe
|
||||
if NOT "%verbose%" == "" (
|
||||
echo svn : "%SVN%"
|
||||
echo cmake : "%CMAKE%"
|
||||
|
@@ -10,7 +10,7 @@ exit /b 1
|
||||
echo found clang-format in %CF_PATH%
|
||||
|
||||
if EXIST %PYTHON% (
|
||||
set PYTHON=%BLENDER_DIR%\..\lib\win64_vc15\python\39\bin\python.exe
|
||||
set PYTHON=%BLENDER_DIR%\..\lib\win64_vc15\python\37\bin\python.exe
|
||||
goto detect_python_done
|
||||
)
|
||||
|
||||
|
@@ -116,9 +116,6 @@ if NOT "%1" == "" (
|
||||
) else if "%1" == "doc_py" (
|
||||
set DOC_PY=1
|
||||
goto EOF
|
||||
) else if "%1" == "svnfix" (
|
||||
set SVN_FIX=1
|
||||
goto EOF
|
||||
) else (
|
||||
echo Command "%1" unknown, aborting!
|
||||
goto ERR
|
||||
|
@@ -1,26 +0,0 @@
|
||||
if "%BUILD_VS_YEAR%"=="2017" set BUILD_VS_LIBDIRPOST=vc15
|
||||
if "%BUILD_VS_YEAR%"=="2019" set BUILD_VS_LIBDIRPOST=vc15
|
||||
if "%BUILD_VS_YEAR%"=="2022" set BUILD_VS_LIBDIRPOST=vc15
|
||||
|
||||
set BUILD_VS_SVNDIR=win64_%BUILD_VS_LIBDIRPOST%
|
||||
set BUILD_VS_LIBDIR="%BLENDER_DIR%..\lib\%BUILD_VS_SVNDIR%"
|
||||
|
||||
echo Starting cleanup in %BUILD_VS_LIBDIR%.
|
||||
cd %BUILD_VS_LIBDIR%
|
||||
:RETRY
|
||||
"%SVN%" cleanup
|
||||
"%SVN%" update
|
||||
if errorlevel 1 (
|
||||
set /p LibRetry= "Error during update, retry? y/n"
|
||||
if /I "!LibRetry!"=="Y" (
|
||||
goto RETRY
|
||||
)
|
||||
echo.
|
||||
echo Error: Download of external libraries failed.
|
||||
echo This is needed for building, please manually run 'svn cleanup' and 'svn update' in
|
||||
echo %BUILD_VS_LIBDIR% , until this is resolved you CANNOT make a successful blender build
|
||||
echo.
|
||||
exit /b 1
|
||||
)
|
||||
echo Cleanup complete
|
||||
|
@@ -1,40 +0,0 @@
|
||||
"""
|
||||
This method enables conversions between Local and Pose space for bones in
|
||||
the middle of updating the armature without having to update dependencies
|
||||
after each change, by manually carrying updated matrices in a recursive walk.
|
||||
"""
|
||||
|
||||
def set_pose_matrices(obj, matrix_map):
|
||||
"Assign pose space matrices of all bones at once, ignoring constraints."
|
||||
|
||||
def rec(pbone, parent_matrix):
|
||||
matrix = matrix_map[pbone.name]
|
||||
|
||||
## Instead of:
|
||||
# pbone.matrix = matrix
|
||||
# bpy.context.view_layer.update()
|
||||
|
||||
# Compute and assign local matrix, using the new parent matrix
|
||||
if pbone.parent:
|
||||
pbone.matrix_basis = pbone.bone.convert_local_to_pose(
|
||||
matrix,
|
||||
pbone.bone.matrix_local,
|
||||
parent_matrix=parent_matrix,
|
||||
parent_matrix_local=pbone.parent.bone.matrix_local,
|
||||
invert=True
|
||||
)
|
||||
else:
|
||||
pbone.matrix_basis = pbone.bone.convert_local_to_pose(
|
||||
matrix,
|
||||
pbone.bone.matrix_local,
|
||||
invert=True
|
||||
)
|
||||
|
||||
# Recursively process children, passing the new matrix through
|
||||
for child in pbone.children:
|
||||
rec(child, matrix)
|
||||
|
||||
# Scan all bone trees from their roots
|
||||
for pbone in obj.pose.bones:
|
||||
if not pbone.parent:
|
||||
rec(pbone, None)
|
@@ -32,7 +32,7 @@ def draw():
|
||||
context.region,
|
||||
view_matrix,
|
||||
projection_matrix,
|
||||
do_color_management=True)
|
||||
True)
|
||||
|
||||
gpu.state.depth_mask_set(False)
|
||||
draw_texture_2d(offscreen.texture_color, (10, 10), WIDTH, HEIGHT)
|
||||
|
@@ -1101,18 +1101,14 @@ context_type_map = {
|
||||
"scene": ("Scene", False),
|
||||
"sculpt_object": ("Object", False),
|
||||
"selectable_objects": ("Object", True),
|
||||
"selected_asset_files": ("FileSelectEntry", True),
|
||||
"selected_bones": ("EditBone", True),
|
||||
"selected_editable_bones": ("EditBone", True),
|
||||
"selected_editable_fcurves": ("FCurve", True),
|
||||
"selected_editable_keyframes": ("Keyframe", True),
|
||||
"selected_editable_objects": ("Object", True),
|
||||
"selected_editable_sequences": ("Sequence", True),
|
||||
"selected_ids": ("ID", True),
|
||||
"selected_files": ("FileSelectEntry", True),
|
||||
"selected_ids": ("ID", True),
|
||||
"selected_nla_strips": ("NlaStrip", True),
|
||||
"selected_movieclip_tracks": ("MovieTrackingTrack", True),
|
||||
"selected_nodes": ("Node", True),
|
||||
"selected_objects": ("Object", True),
|
||||
"selected_pose_bones": ("PoseBone", True),
|
||||
|
5
extern/CMakeLists.txt
vendored
5
extern/CMakeLists.txt
vendored
@@ -67,12 +67,9 @@ endif()
|
||||
|
||||
if(WITH_CYCLES OR WITH_COMPOSITOR OR WITH_OPENSUBDIV)
|
||||
add_subdirectory(clew)
|
||||
if((WITH_CYCLES_DEVICE_CUDA OR WITH_CYCLES_DEVICE_OPTIX) AND WITH_CUDA_DYNLOAD)
|
||||
if(WITH_CUDA_DYNLOAD)
|
||||
add_subdirectory(cuew)
|
||||
endif()
|
||||
if(WITH_CYCLES_DEVICE_HIP AND WITH_HIP_DYNLOAD)
|
||||
add_subdirectory(hipew)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WITH_GHOST_X11 AND WITH_GHOST_XDND)
|
||||
|
2
extern/audaspace/CMakeLists.txt
vendored
2
extern/audaspace/CMakeLists.txt
vendored
@@ -129,7 +129,6 @@ set(SRC
|
||||
src/util/Barrier.cpp
|
||||
src/util/Buffer.cpp
|
||||
src/util/BufferReader.cpp
|
||||
src/util/RingBuffer.cpp
|
||||
src/util/StreamBuffer.cpp
|
||||
src/util/ThreadPool.cpp
|
||||
)
|
||||
@@ -246,7 +245,6 @@ set(PUBLIC_HDR
|
||||
include/util/BufferReader.h
|
||||
include/util/ILockable.h
|
||||
include/util/Math3D.h
|
||||
include/util/RingBuffer.h
|
||||
include/util/StreamBuffer.h
|
||||
include/util/ThreadPool.h
|
||||
)
|
||||
|
38
extern/audaspace/bindings/C/AUD_Sound.cpp
vendored
38
extern/audaspace/bindings/C/AUD_Sound.cpp
vendored
@@ -102,30 +102,26 @@ AUD_API int AUD_Sound_getFileStreams(AUD_Sound* sound, AUD_StreamInfo **stream_i
|
||||
|
||||
if(file)
|
||||
{
|
||||
try
|
||||
{
|
||||
auto streams = file->queryStreams();
|
||||
|
||||
size_t size = sizeof(AUD_StreamInfo) * streams.size();
|
||||
|
||||
if(!size)
|
||||
{
|
||||
*stream_infos = nullptr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
*stream_infos = reinterpret_cast<AUD_StreamInfo*>(std::malloc(size));
|
||||
std::memcpy(*stream_infos, streams.data(), size);
|
||||
|
||||
return streams.size();
|
||||
}
|
||||
catch(Exception&)
|
||||
auto streams = file->queryStreams();
|
||||
|
||||
size_t size = sizeof(AUD_StreamInfo) * streams.size();
|
||||
|
||||
if(!size)
|
||||
{
|
||||
*stream_infos = nullptr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
*stream_infos = reinterpret_cast<AUD_StreamInfo*>(std::malloc(size));
|
||||
std::memcpy(*stream_infos, streams.data(), size);
|
||||
|
||||
return streams.size();
|
||||
}
|
||||
else
|
||||
{
|
||||
*stream_infos = nullptr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
*stream_infos = nullptr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
AUD_API sample_t* AUD_Sound_data(AUD_Sound* sound, int* length, AUD_Specs* specs)
|
||||
|
2
extern/audaspace/bindings/python/PySound.cpp
vendored
2
extern/audaspace/bindings/python/PySound.cpp
vendored
@@ -290,7 +290,7 @@ PyDoc_STRVAR(M_aud_Sound_buffer_doc,
|
||||
".. classmethod:: buffer(data, rate)\n\n"
|
||||
" Creates a sound from a data buffer.\n\n"
|
||||
" :arg data: The data as two dimensional numpy array.\n"
|
||||
" :type data: :class:`numpy.ndarray`\n"
|
||||
" :type data: numpy.ndarray\n"
|
||||
" :arg rate: The sample rate.\n"
|
||||
" :type rate: double\n"
|
||||
" :return: The created :class:`Sound` object.\n"
|
||||
|
97
extern/audaspace/include/util/RingBuffer.h
vendored
97
extern/audaspace/include/util/RingBuffer.h
vendored
@@ -1,97 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright 2009-2021 Jörg Müller
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @file RingBuffer.h
|
||||
* @ingroup util
|
||||
* The RingBuffer class.
|
||||
*/
|
||||
|
||||
#include "Audaspace.h"
|
||||
#include "Buffer.h"
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
AUD_NAMESPACE_BEGIN
|
||||
|
||||
/**
|
||||
* This class is a simple ring buffer in RAM which is 32 Byte aligned and provides
|
||||
* functionality for concurrent reading and writting without locks.
|
||||
*/
|
||||
class AUD_API RingBuffer
|
||||
{
|
||||
private:
|
||||
/// The buffer storing the actual data.
|
||||
Buffer m_buffer;
|
||||
|
||||
/// The reading pointer.
|
||||
volatile size_t m_read;
|
||||
|
||||
/// The writing pointer.
|
||||
volatile size_t m_write;
|
||||
|
||||
// delete copy constructor and operator=
|
||||
RingBuffer(const RingBuffer&) = delete;
|
||||
RingBuffer& operator=(const RingBuffer&) = delete;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a new ring buffer.
|
||||
* \param size The size of the buffer in bytes.
|
||||
*/
|
||||
RingBuffer(int size = 0);
|
||||
|
||||
/**
|
||||
* Returns the pointer to the ring buffer in memory.
|
||||
*/
|
||||
sample_t* getBuffer() const;
|
||||
|
||||
/**
|
||||
* Returns the size of the ring buffer in bytes.
|
||||
*/
|
||||
int getSize() const;
|
||||
|
||||
size_t getReadSize() const;
|
||||
|
||||
size_t getWriteSize() const;
|
||||
|
||||
size_t read(data_t* target, size_t size);
|
||||
|
||||
size_t write(data_t* source, size_t size);
|
||||
|
||||
/**
|
||||
* Resets the ring buffer to a state where nothing has been written or read.
|
||||
*/
|
||||
void reset();
|
||||
|
||||
/**
|
||||
* Resizes the ring buffer.
|
||||
* \param size The new size of the ring buffer, measured in bytes.
|
||||
*/
|
||||
void resize(int size);
|
||||
|
||||
/**
|
||||
* Makes sure the ring buffer has a minimum size.
|
||||
* If size is >= current size, nothing will happen.
|
||||
* Otherwise the ring buffer is resized with keep as parameter.
|
||||
* \param size The new minimum size of the ring buffer, measured in bytes.
|
||||
*/
|
||||
void assureSize(int size);
|
||||
};
|
||||
|
||||
AUD_NAMESPACE_END
|
@@ -23,121 +23,95 @@
|
||||
|
||||
AUD_NAMESPACE_BEGIN
|
||||
|
||||
PulseAudioDevice::PulseAudioSynchronizer::PulseAudioSynchronizer(PulseAudioDevice *device) :
|
||||
m_device(device)
|
||||
{
|
||||
}
|
||||
|
||||
double PulseAudioDevice::PulseAudioSynchronizer::getPosition(std::shared_ptr<IHandle> handle)
|
||||
{
|
||||
pa_usec_t latency;
|
||||
int negative;
|
||||
AUD_pa_stream_get_latency(m_device->m_stream, &latency, &negative);
|
||||
|
||||
double delay = m_device->m_ring_buffer.getReadSize() / (AUD_SAMPLE_SIZE(m_device->m_specs) * m_device->m_specs.rate) + latency * 1.0e-6;
|
||||
|
||||
return handle->getPosition() - delay;
|
||||
}
|
||||
|
||||
void PulseAudioDevice::updateRingBuffer()
|
||||
{
|
||||
unsigned int samplesize = AUD_SAMPLE_SIZE(m_specs);
|
||||
|
||||
std::unique_lock<std::mutex> lock(m_mixingLock);
|
||||
|
||||
Buffer buffer;
|
||||
|
||||
while(m_valid)
|
||||
{
|
||||
size_t size = m_ring_buffer.getWriteSize();
|
||||
|
||||
size_t sample_count = size / samplesize;
|
||||
|
||||
if(sample_count > 0)
|
||||
{
|
||||
size = sample_count * samplesize;
|
||||
|
||||
buffer.assureSize(size);
|
||||
|
||||
mix(reinterpret_cast<data_t*>(buffer.getBuffer()), sample_count);
|
||||
|
||||
m_ring_buffer.write(reinterpret_cast<data_t*>(buffer.getBuffer()), size);
|
||||
}
|
||||
|
||||
m_mixingCondition.wait(lock);
|
||||
}
|
||||
}
|
||||
|
||||
void PulseAudioDevice::PulseAudio_state_callback(pa_context *context, void *data)
|
||||
{
|
||||
PulseAudioDevice* device = (PulseAudioDevice*)data;
|
||||
|
||||
device->m_state = AUD_pa_context_get_state(context);
|
||||
std::lock_guard<ILockable> lock(*device);
|
||||
|
||||
AUD_pa_threaded_mainloop_signal(device->m_mainloop, 0);
|
||||
device->m_state = AUD_pa_context_get_state(context);
|
||||
}
|
||||
|
||||
void PulseAudioDevice::PulseAudio_request(pa_stream *stream, size_t total_bytes, void *data)
|
||||
{
|
||||
PulseAudioDevice* device = (PulseAudioDevice*)data;
|
||||
|
||||
data_t* buffer;
|
||||
|
||||
size_t sample_size = AUD_DEVICE_SAMPLE_SIZE(device->m_specs);
|
||||
void* buffer;
|
||||
|
||||
while(total_bytes > 0)
|
||||
{
|
||||
size_t num_bytes = total_bytes;
|
||||
|
||||
AUD_pa_stream_begin_write(stream, reinterpret_cast<void**>(&buffer), &num_bytes);
|
||||
AUD_pa_stream_begin_write(stream, &buffer, &num_bytes);
|
||||
|
||||
size_t readsamples = device->m_ring_buffer.getReadSize();
|
||||
device->mix((data_t*)buffer, num_bytes / AUD_DEVICE_SAMPLE_SIZE(device->m_specs));
|
||||
|
||||
readsamples = std::min(readsamples, size_t(num_bytes)) / sample_size;
|
||||
|
||||
device->m_ring_buffer.read(buffer, readsamples * sample_size);
|
||||
|
||||
if(readsamples * sample_size < num_bytes)
|
||||
std::memset(buffer + readsamples * sample_size, 0, num_bytes - readsamples * sample_size);
|
||||
|
||||
if(device->m_mixingLock.try_lock())
|
||||
{
|
||||
device->m_mixingCondition.notify_all();
|
||||
device->m_mixingLock.unlock();
|
||||
}
|
||||
|
||||
AUD_pa_stream_write(stream, reinterpret_cast<void*>(buffer), num_bytes, nullptr, 0, PA_SEEK_RELATIVE);
|
||||
AUD_pa_stream_write(stream, buffer, num_bytes, nullptr, 0, PA_SEEK_RELATIVE);
|
||||
|
||||
total_bytes -= num_bytes;
|
||||
}
|
||||
}
|
||||
|
||||
void PulseAudioDevice::playing(bool playing)
|
||||
void PulseAudioDevice::PulseAudio_underflow(pa_stream *stream, void *data)
|
||||
{
|
||||
m_playback = playing;
|
||||
PulseAudioDevice* device = (PulseAudioDevice*)data;
|
||||
|
||||
AUD_pa_threaded_mainloop_lock(m_mainloop);
|
||||
AUD_pa_stream_cork(m_stream, playing ? 0 : 1, nullptr, nullptr);
|
||||
AUD_pa_threaded_mainloop_unlock(m_mainloop);
|
||||
DeviceSpecs specs = device->getSpecs();
|
||||
|
||||
if(++device->m_underflows > 4 && device->m_buffersize < AUD_DEVICE_SAMPLE_SIZE(specs) * specs.rate * 2)
|
||||
{
|
||||
device->m_buffersize <<= 1;
|
||||
device->m_underflows = 0;
|
||||
|
||||
pa_buffer_attr buffer_attr;
|
||||
|
||||
buffer_attr.fragsize = -1U;
|
||||
buffer_attr.maxlength = -1U;
|
||||
buffer_attr.minreq = -1U;
|
||||
buffer_attr.prebuf = -1U;
|
||||
buffer_attr.tlength = device->m_buffersize;
|
||||
|
||||
AUD_pa_stream_set_buffer_attr(stream, &buffer_attr, nullptr, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void PulseAudioDevice::runMixingThread()
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
{
|
||||
std::lock_guard<ILockable> lock(*this);
|
||||
|
||||
if(shouldStop())
|
||||
{
|
||||
AUD_pa_stream_cork(m_stream, 1, nullptr, nullptr);
|
||||
AUD_pa_stream_flush(m_stream, nullptr, nullptr);
|
||||
doStop();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(AUD_pa_stream_is_corked(m_stream))
|
||||
AUD_pa_stream_cork(m_stream, 0, nullptr, nullptr);
|
||||
|
||||
// similar to AUD_pa_mainloop_iterate(m_mainloop, false, nullptr); except with a longer timeout
|
||||
AUD_pa_mainloop_prepare(m_mainloop, 1 << 14);
|
||||
AUD_pa_mainloop_poll(m_mainloop);
|
||||
AUD_pa_mainloop_dispatch(m_mainloop);
|
||||
}
|
||||
}
|
||||
|
||||
PulseAudioDevice::PulseAudioDevice(std::string name, DeviceSpecs specs, int buffersize) :
|
||||
m_synchronizer(this),
|
||||
m_playback(false),
|
||||
m_state(PA_CONTEXT_UNCONNECTED),
|
||||
m_valid(true),
|
||||
m_underflows(0)
|
||||
{
|
||||
m_mainloop = AUD_pa_threaded_mainloop_new();
|
||||
m_mainloop = AUD_pa_mainloop_new();
|
||||
|
||||
AUD_pa_threaded_mainloop_lock(m_mainloop);
|
||||
|
||||
m_context = AUD_pa_context_new(AUD_pa_threaded_mainloop_get_api(m_mainloop), name.c_str());
|
||||
m_context = AUD_pa_context_new(AUD_pa_mainloop_get_api(m_mainloop), name.c_str());
|
||||
|
||||
if(!m_context)
|
||||
{
|
||||
AUD_pa_threaded_mainloop_unlock(m_mainloop);
|
||||
AUD_pa_threaded_mainloop_free(m_mainloop);
|
||||
AUD_pa_mainloop_free(m_mainloop);
|
||||
|
||||
AUD_THROW(DeviceException, "Could not connect to PulseAudio.");
|
||||
}
|
||||
@@ -146,26 +120,21 @@ PulseAudioDevice::PulseAudioDevice(std::string name, DeviceSpecs specs, int buff
|
||||
|
||||
AUD_pa_context_connect(m_context, nullptr, PA_CONTEXT_NOFLAGS, nullptr);
|
||||
|
||||
AUD_pa_threaded_mainloop_start(m_mainloop);
|
||||
|
||||
while(m_state != PA_CONTEXT_READY)
|
||||
{
|
||||
switch(m_state)
|
||||
{
|
||||
case PA_CONTEXT_FAILED:
|
||||
case PA_CONTEXT_TERMINATED:
|
||||
AUD_pa_threaded_mainloop_unlock(m_mainloop);
|
||||
AUD_pa_threaded_mainloop_stop(m_mainloop);
|
||||
|
||||
AUD_pa_context_disconnect(m_context);
|
||||
AUD_pa_context_unref(m_context);
|
||||
|
||||
AUD_pa_threaded_mainloop_free(m_mainloop);
|
||||
AUD_pa_mainloop_free(m_mainloop);
|
||||
|
||||
AUD_THROW(DeviceException, "Could not connect to PulseAudio.");
|
||||
break;
|
||||
default:
|
||||
AUD_pa_threaded_mainloop_wait(m_mainloop);
|
||||
AUD_pa_mainloop_iterate(m_mainloop, true, nullptr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -213,18 +182,16 @@ PulseAudioDevice::PulseAudioDevice(std::string name, DeviceSpecs specs, int buff
|
||||
|
||||
if(!m_stream)
|
||||
{
|
||||
AUD_pa_threaded_mainloop_unlock(m_mainloop);
|
||||
AUD_pa_threaded_mainloop_stop(m_mainloop);
|
||||
|
||||
AUD_pa_context_disconnect(m_context);
|
||||
AUD_pa_context_unref(m_context);
|
||||
|
||||
AUD_pa_threaded_mainloop_free(m_mainloop);
|
||||
AUD_pa_mainloop_free(m_mainloop);
|
||||
|
||||
AUD_THROW(DeviceException, "Could not create PulseAudio stream.");
|
||||
}
|
||||
|
||||
AUD_pa_stream_set_write_callback(m_stream, PulseAudio_request, this);
|
||||
AUD_pa_stream_set_underflow_callback(m_stream, PulseAudio_underflow, this);
|
||||
|
||||
buffersize *= AUD_DEVICE_SAMPLE_SIZE(m_specs);
|
||||
m_buffersize = buffersize;
|
||||
@@ -237,53 +204,31 @@ PulseAudioDevice::PulseAudioDevice(std::string name, DeviceSpecs specs, int buff
|
||||
buffer_attr.prebuf = -1U;
|
||||
buffer_attr.tlength = buffersize;
|
||||
|
||||
m_ring_buffer.resize(buffersize);
|
||||
|
||||
if(AUD_pa_stream_connect_playback(m_stream, nullptr, &buffer_attr, static_cast<pa_stream_flags_t>(PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_ADJUST_LATENCY | PA_STREAM_AUTO_TIMING_UPDATE), nullptr, nullptr) < 0)
|
||||
if(AUD_pa_stream_connect_playback(m_stream, nullptr, &buffer_attr, static_cast<pa_stream_flags_t>(PA_STREAM_START_CORKED | PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_ADJUST_LATENCY | PA_STREAM_AUTO_TIMING_UPDATE), nullptr, nullptr) < 0)
|
||||
{
|
||||
AUD_pa_threaded_mainloop_unlock(m_mainloop);
|
||||
AUD_pa_threaded_mainloop_stop(m_mainloop);
|
||||
|
||||
AUD_pa_context_disconnect(m_context);
|
||||
AUD_pa_context_unref(m_context);
|
||||
|
||||
AUD_pa_threaded_mainloop_free(m_mainloop);
|
||||
AUD_pa_mainloop_free(m_mainloop);
|
||||
|
||||
AUD_THROW(DeviceException, "Could not connect PulseAudio stream.");
|
||||
}
|
||||
|
||||
AUD_pa_threaded_mainloop_unlock(m_mainloop);
|
||||
|
||||
create();
|
||||
|
||||
m_mixingThread = std::thread(&PulseAudioDevice::updateRingBuffer, this);
|
||||
}
|
||||
|
||||
PulseAudioDevice::~PulseAudioDevice()
|
||||
{
|
||||
m_valid = false;
|
||||
|
||||
m_mixingLock.lock();
|
||||
m_mixingCondition.notify_all();
|
||||
m_mixingLock.unlock();
|
||||
|
||||
m_mixingThread.join();
|
||||
|
||||
AUD_pa_threaded_mainloop_stop(m_mainloop);
|
||||
stopMixingThread();
|
||||
|
||||
AUD_pa_context_disconnect(m_context);
|
||||
AUD_pa_context_unref(m_context);
|
||||
|
||||
AUD_pa_threaded_mainloop_free(m_mainloop);
|
||||
AUD_pa_mainloop_free(m_mainloop);
|
||||
|
||||
destroy();
|
||||
}
|
||||
|
||||
ISynchronizer *PulseAudioDevice::getSynchronizer()
|
||||
{
|
||||
return &m_synchronizer;
|
||||
}
|
||||
|
||||
class PulseAudioDeviceFactory : public IDeviceFactory
|
||||
{
|
||||
private:
|
||||
|
@@ -26,11 +26,7 @@
|
||||
* The PulseAudioDevice class.
|
||||
*/
|
||||
|
||||
#include "devices/SoftwareDevice.h"
|
||||
#include "util/RingBuffer.h"
|
||||
|
||||
#include <condition_variable>
|
||||
#include <thread>
|
||||
#include "devices/ThreadedDevice.h"
|
||||
|
||||
#include <pulse/pulseaudio.h>
|
||||
|
||||
@@ -39,65 +35,17 @@ AUD_NAMESPACE_BEGIN
|
||||
/**
|
||||
* This device plays back through PulseAudio, the simple direct media layer.
|
||||
*/
|
||||
class AUD_PLUGIN_API PulseAudioDevice : public SoftwareDevice
|
||||
class AUD_PLUGIN_API PulseAudioDevice : public ThreadedDevice
|
||||
{
|
||||
private:
|
||||
class PulseAudioSynchronizer : public DefaultSynchronizer
|
||||
{
|
||||
PulseAudioDevice* m_device;
|
||||
|
||||
public:
|
||||
PulseAudioSynchronizer(PulseAudioDevice* device);
|
||||
|
||||
virtual double getPosition(std::shared_ptr<IHandle> handle);
|
||||
};
|
||||
|
||||
/// Synchronizer.
|
||||
PulseAudioSynchronizer m_synchronizer;
|
||||
|
||||
/**
|
||||
* Whether there is currently playback.
|
||||
*/
|
||||
volatile bool m_playback;
|
||||
|
||||
pa_threaded_mainloop* m_mainloop;
|
||||
pa_mainloop* m_mainloop;
|
||||
pa_context* m_context;
|
||||
pa_stream* m_stream;
|
||||
pa_context_state_t m_state;
|
||||
|
||||
/**
|
||||
* The mixing ring buffer.
|
||||
*/
|
||||
RingBuffer m_ring_buffer;
|
||||
|
||||
/**
|
||||
* Whether the device is valid.
|
||||
*/
|
||||
bool m_valid;
|
||||
|
||||
int m_buffersize;
|
||||
uint32_t m_underflows;
|
||||
|
||||
/**
|
||||
* The mixing thread.
|
||||
*/
|
||||
std::thread m_mixingThread;
|
||||
|
||||
/**
|
||||
* Mutex for mixing.
|
||||
*/
|
||||
std::mutex m_mixingLock;
|
||||
|
||||
/**
|
||||
* Condition for mixing.
|
||||
*/
|
||||
std::condition_variable m_mixingCondition;
|
||||
|
||||
/**
|
||||
* Updates the ring buffer.
|
||||
*/
|
||||
AUD_LOCAL void updateRingBuffer();
|
||||
|
||||
/**
|
||||
* Reports the state of the PulseAudio server connection.
|
||||
* \param context The PulseAudio context.
|
||||
@@ -113,13 +61,23 @@ private:
|
||||
*/
|
||||
AUD_LOCAL static void PulseAudio_request(pa_stream* stream, size_t total_bytes, void* data);
|
||||
|
||||
/**
|
||||
* Reports an underflow from the PulseAudio server.
|
||||
* Automatically adjusts the latency if this happens too often.
|
||||
* @param stream The PulseAudio stream.
|
||||
* \param data The PulseAudio device.
|
||||
*/
|
||||
AUD_LOCAL static void PulseAudio_underflow(pa_stream* stream, void* data);
|
||||
|
||||
/**
|
||||
* Streaming thread main function.
|
||||
*/
|
||||
AUD_LOCAL void runMixingThread();
|
||||
|
||||
// delete copy constructor and operator=
|
||||
PulseAudioDevice(const PulseAudioDevice&) = delete;
|
||||
PulseAudioDevice& operator=(const PulseAudioDevice&) = delete;
|
||||
|
||||
protected:
|
||||
virtual void playing(bool playing);
|
||||
|
||||
public:
|
||||
/**
|
||||
* Opens the PulseAudio audio device for playback.
|
||||
@@ -135,8 +93,6 @@ public:
|
||||
*/
|
||||
virtual ~PulseAudioDevice();
|
||||
|
||||
virtual ISynchronizer* getSynchronizer();
|
||||
|
||||
/**
|
||||
* Registers this plugin.
|
||||
*/
|
||||
|
@@ -25,7 +25,6 @@ PULSEAUDIO_SYMBOL(pa_stream_begin_write);
|
||||
PULSEAUDIO_SYMBOL(pa_stream_connect_playback);
|
||||
PULSEAUDIO_SYMBOL(pa_stream_cork);
|
||||
PULSEAUDIO_SYMBOL(pa_stream_flush);
|
||||
PULSEAUDIO_SYMBOL(pa_stream_get_latency);
|
||||
PULSEAUDIO_SYMBOL(pa_stream_is_corked);
|
||||
PULSEAUDIO_SYMBOL(pa_stream_new);
|
||||
PULSEAUDIO_SYMBOL(pa_stream_set_buffer_attr);
|
||||
@@ -40,13 +39,3 @@ PULSEAUDIO_SYMBOL(pa_mainloop_iterate);
|
||||
PULSEAUDIO_SYMBOL(pa_mainloop_prepare);
|
||||
PULSEAUDIO_SYMBOL(pa_mainloop_poll);
|
||||
PULSEAUDIO_SYMBOL(pa_mainloop_dispatch);
|
||||
|
||||
PULSEAUDIO_SYMBOL(pa_threaded_mainloop_free);
|
||||
PULSEAUDIO_SYMBOL(pa_threaded_mainloop_get_api);
|
||||
PULSEAUDIO_SYMBOL(pa_threaded_mainloop_lock);
|
||||
PULSEAUDIO_SYMBOL(pa_threaded_mainloop_new);
|
||||
PULSEAUDIO_SYMBOL(pa_threaded_mainloop_signal);
|
||||
PULSEAUDIO_SYMBOL(pa_threaded_mainloop_start);
|
||||
PULSEAUDIO_SYMBOL(pa_threaded_mainloop_stop);
|
||||
PULSEAUDIO_SYMBOL(pa_threaded_mainloop_unlock);
|
||||
PULSEAUDIO_SYMBOL(pa_threaded_mainloop_wait);
|
||||
|
137
extern/audaspace/src/util/RingBuffer.cpp
vendored
137
extern/audaspace/src/util/RingBuffer.cpp
vendored
@@ -1,137 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright 2009-2021 Jörg Müller
|
||||
*
|
||||
* 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 "util/RingBuffer.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
#define ALIGNMENT 32
|
||||
#define ALIGN(a) (a + ALIGNMENT - ((long long)a & (ALIGNMENT-1)))
|
||||
|
||||
AUD_NAMESPACE_BEGIN
|
||||
|
||||
RingBuffer::RingBuffer(int size) :
|
||||
m_buffer(size),
|
||||
m_read(0),
|
||||
m_write(0)
|
||||
{
|
||||
}
|
||||
|
||||
sample_t* RingBuffer::getBuffer() const
|
||||
{
|
||||
return m_buffer.getBuffer();
|
||||
}
|
||||
|
||||
int RingBuffer::getSize() const
|
||||
{
|
||||
return m_buffer.getSize();
|
||||
}
|
||||
|
||||
size_t RingBuffer::getReadSize() const
|
||||
{
|
||||
size_t read = m_read;
|
||||
size_t write = m_write;
|
||||
|
||||
if(read > write)
|
||||
return write + getSize() - read;
|
||||
else
|
||||
return write - read;
|
||||
}
|
||||
|
||||
size_t RingBuffer::getWriteSize() const
|
||||
{
|
||||
size_t read = m_read;
|
||||
size_t write = m_write;
|
||||
|
||||
if(read > write)
|
||||
return read - write - 1;
|
||||
else
|
||||
return read + getSize() - write - 1;
|
||||
}
|
||||
|
||||
size_t RingBuffer::read(data_t* target, size_t size)
|
||||
{
|
||||
size = std::min(size, getReadSize());
|
||||
|
||||
data_t* buffer = reinterpret_cast<data_t*>(m_buffer.getBuffer());
|
||||
|
||||
if(m_read + size > m_buffer.getSize())
|
||||
{
|
||||
size_t read_first = m_buffer.getSize() - m_read;
|
||||
size_t read_second = size - read_first;
|
||||
|
||||
std::memcpy(target, buffer + m_read, read_first);
|
||||
std::memcpy(target + read_first, buffer, read_second);
|
||||
|
||||
m_read = read_second;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::memcpy(target, buffer + m_read, size);
|
||||
|
||||
m_read += size;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
size_t RingBuffer::write(data_t* source, size_t size)
|
||||
{
|
||||
size = std::min(size, getWriteSize());
|
||||
|
||||
data_t* buffer = reinterpret_cast<data_t*>(m_buffer.getBuffer());
|
||||
|
||||
if(m_write + size > m_buffer.getSize())
|
||||
{
|
||||
size_t write_first = m_buffer.getSize() - m_write;
|
||||
size_t write_second = size - write_first;
|
||||
|
||||
std::memcpy(buffer + m_write, source, write_first);
|
||||
std::memcpy(buffer, source + write_first, write_second);
|
||||
|
||||
m_write = write_second;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::memcpy(buffer + m_write, source, size);
|
||||
|
||||
m_write += size;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
void RingBuffer::reset()
|
||||
{
|
||||
m_read = 0;
|
||||
m_write = 0;
|
||||
}
|
||||
|
||||
void RingBuffer::resize(int size)
|
||||
{
|
||||
m_buffer.resize(size);
|
||||
reset();
|
||||
}
|
||||
|
||||
void RingBuffer::assureSize(int size)
|
||||
{
|
||||
m_buffer.assureSize(size);
|
||||
reset();
|
||||
}
|
||||
|
||||
AUD_NAMESPACE_END
|
4
extern/cuew/include/cuew.h
vendored
4
extern/cuew/include/cuew.h
vendored
@@ -609,7 +609,6 @@ typedef enum cudaError_enum {
|
||||
CUDA_ERROR_INVALID_GRAPHICS_CONTEXT = 219,
|
||||
CUDA_ERROR_NVLINK_UNCORRECTABLE = 220,
|
||||
CUDA_ERROR_JIT_COMPILER_NOT_FOUND = 221,
|
||||
CUDA_ERROR_UNSUPPORTED_PTX_VERSION = 222,
|
||||
CUDA_ERROR_INVALID_SOURCE = 300,
|
||||
CUDA_ERROR_FILE_NOT_FOUND = 301,
|
||||
CUDA_ERROR_SHARED_OBJECT_SYMBOL_NOT_FOUND = 302,
|
||||
@@ -646,8 +645,7 @@ typedef enum CUdevice_P2PAttribute_enum {
|
||||
CU_DEVICE_P2P_ATTRIBUTE_PERFORMANCE_RANK = 0x01,
|
||||
CU_DEVICE_P2P_ATTRIBUTE_ACCESS_SUPPORTED = 0x02,
|
||||
CU_DEVICE_P2P_ATTRIBUTE_NATIVE_ATOMIC_SUPPORTED = 0x03,
|
||||
CU_DEVICE_P2P_ATTRIBUTE_ACCESS_ACCESS_SUPPORTED = 0x04,
|
||||
CU_DEVICE_P2P_ATTRIBUTE_CUDA_ARRAY_ACCESS_SUPPORTED = 0x04,
|
||||
CU_DEVICE_P2P_ATTRIBUTE_ARRAY_ACCESS_ACCESS_SUPPORTED = 0x04,
|
||||
} CUdevice_P2PAttribute;
|
||||
|
||||
typedef void (CUDA_CB *CUstreamCallback)(CUstream hStream, CUresult status, void* userData);
|
||||
|
1
extern/cuew/src/cuew.c
vendored
1
extern/cuew/src/cuew.c
vendored
@@ -736,7 +736,6 @@ const char *cuewErrorString(CUresult result) {
|
||||
case CUDA_ERROR_INVALID_GRAPHICS_CONTEXT: return "Invalid graphics context";
|
||||
case CUDA_ERROR_NVLINK_UNCORRECTABLE: return "Nvlink uncorrectable";
|
||||
case CUDA_ERROR_JIT_COMPILER_NOT_FOUND: return "Jit compiler not found";
|
||||
case CUDA_ERROR_UNSUPPORTED_PTX_VERSION: return "Unsupported PTX version";
|
||||
case CUDA_ERROR_INVALID_SOURCE: return "Invalid source";
|
||||
case CUDA_ERROR_FILE_NOT_FOUND: return "File not found";
|
||||
case CUDA_ERROR_SHARED_OBJECT_SYMBOL_NOT_FOUND: return "Link to a shared object failed to resolve";
|
||||
|
39
extern/hipew/CMakeLists.txt
vendored
39
extern/hipew/CMakeLists.txt
vendored
@@ -1,39 +0,0 @@
|
||||
# ***** 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.
|
||||
#
|
||||
# The Original Code is Copyright (C) 2021, Blender Foundation
|
||||
# All rights reserved.
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
|
||||
set(INC
|
||||
.
|
||||
include
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
|
||||
)
|
||||
|
||||
set(SRC
|
||||
src/hipew.c
|
||||
|
||||
include/hipew.h
|
||||
)
|
||||
|
||||
set(LIB
|
||||
)
|
||||
|
||||
blender_add_lib(extern_hipew "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
|
1352
extern/hipew/include/hipew.h
vendored
1352
extern/hipew/include/hipew.h
vendored
File diff suppressed because it is too large
Load Diff
556
extern/hipew/src/hipew.c
vendored
556
extern/hipew/src/hipew.c
vendored
@@ -1,556 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011-2021 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
|
||||
*/
|
||||
#ifdef _MSC_VER
|
||||
# if _MSC_VER < 1900
|
||||
# define snprintf _snprintf
|
||||
# endif
|
||||
# define popen _popen
|
||||
# define pclose _pclose
|
||||
# define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
|
||||
#include <hipew.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# define VC_EXTRALEAN
|
||||
# include <windows.h>
|
||||
|
||||
/* Utility macros. */
|
||||
|
||||
typedef HMODULE DynamicLibrary;
|
||||
|
||||
# define dynamic_library_open(path) LoadLibraryA(path)
|
||||
# define dynamic_library_close(lib) FreeLibrary(lib)
|
||||
# define dynamic_library_find(lib, symbol) GetProcAddress(lib, symbol)
|
||||
#else
|
||||
# include <dlfcn.h>
|
||||
|
||||
typedef void* DynamicLibrary;
|
||||
|
||||
# define dynamic_library_open(path) dlopen(path, RTLD_NOW)
|
||||
# define dynamic_library_close(lib) dlclose(lib)
|
||||
# define dynamic_library_find(lib, symbol) dlsym(lib, symbol)
|
||||
#endif
|
||||
|
||||
#define _LIBRARY_FIND_CHECKED(lib, name) \
|
||||
name = (t##name *)dynamic_library_find(lib, #name); \
|
||||
assert(name);
|
||||
|
||||
#define _LIBRARY_FIND(lib, name) \
|
||||
name = (t##name *)dynamic_library_find(lib, #name);
|
||||
|
||||
#define HIP_LIBRARY_FIND_CHECKED(name) \
|
||||
_LIBRARY_FIND_CHECKED(hip_lib, name)
|
||||
#define HIP_LIBRARY_FIND(name) _LIBRARY_FIND(hip_lib, name)
|
||||
|
||||
|
||||
static DynamicLibrary hip_lib;
|
||||
|
||||
/* Function definitions. */
|
||||
thipGetErrorName *hipGetErrorName;
|
||||
thipInit *hipInit;
|
||||
thipDriverGetVersion *hipDriverGetVersion;
|
||||
thipGetDevice *hipGetDevice;
|
||||
thipGetDeviceCount *hipGetDeviceCount;
|
||||
thipGetDeviceProperties *hipGetDeviceProperties;
|
||||
thipDeviceGetName *hipDeviceGetName;
|
||||
thipDeviceGetAttribute *hipDeviceGetAttribute;
|
||||
thipDeviceComputeCapability *hipDeviceComputeCapability;
|
||||
thipDevicePrimaryCtxRetain *hipDevicePrimaryCtxRetain;
|
||||
thipDevicePrimaryCtxRelease *hipDevicePrimaryCtxRelease;
|
||||
thipDevicePrimaryCtxSetFlags *hipDevicePrimaryCtxSetFlags;
|
||||
thipDevicePrimaryCtxGetState *hipDevicePrimaryCtxGetState;
|
||||
thipDevicePrimaryCtxReset *hipDevicePrimaryCtxReset;
|
||||
thipCtxCreate *hipCtxCreate;
|
||||
thipCtxDestroy *hipCtxDestroy;
|
||||
thipCtxPushCurrent *hipCtxPushCurrent;
|
||||
thipCtxPopCurrent *hipCtxPopCurrent;
|
||||
thipCtxSetCurrent *hipCtxSetCurrent;
|
||||
thipCtxGetCurrent *hipCtxGetCurrent;
|
||||
thipCtxGetDevice *hipCtxGetDevice;
|
||||
thipCtxGetFlags *hipCtxGetFlags;
|
||||
thipCtxSynchronize *hipCtxSynchronize;
|
||||
thipDeviceSynchronize *hipDeviceSynchronize;
|
||||
thipCtxGetCacheConfig *hipCtxGetCacheConfig;
|
||||
thipCtxSetCacheConfig *hipCtxSetCacheConfig;
|
||||
thipCtxGetSharedMemConfig *hipCtxGetSharedMemConfig;
|
||||
thipCtxSetSharedMemConfig *hipCtxSetSharedMemConfig;
|
||||
thipCtxGetApiVersion *hipCtxGetApiVersion;
|
||||
thipModuleLoad *hipModuleLoad;
|
||||
thipModuleLoadData *hipModuleLoadData;
|
||||
thipModuleLoadDataEx *hipModuleLoadDataEx;
|
||||
thipModuleUnload *hipModuleUnload;
|
||||
thipModuleGetFunction *hipModuleGetFunction;
|
||||
thipModuleGetGlobal *hipModuleGetGlobal;
|
||||
thipModuleGetTexRef *hipModuleGetTexRef;
|
||||
thipMemGetInfo *hipMemGetInfo;
|
||||
thipMalloc *hipMalloc;
|
||||
thipMemAllocPitch *hipMemAllocPitch;
|
||||
thipFree *hipFree;
|
||||
thipMemGetAddressRange *hipMemGetAddressRange;
|
||||
thipHostMalloc *hipHostMalloc;
|
||||
thipHostFree *hipHostFree;
|
||||
thipHostGetDevicePointer *hipHostGetDevicePointer;
|
||||
thipHostGetFlags *hipHostGetFlags;
|
||||
thipMallocManaged *hipMallocManaged;
|
||||
thipDeviceGetByPCIBusId *hipDeviceGetByPCIBusId;
|
||||
thipDeviceGetPCIBusId *hipDeviceGetPCIBusId;
|
||||
thipMemcpyPeer *hipMemcpyPeer;
|
||||
thipMemcpyHtoD *hipMemcpyHtoD;
|
||||
thipMemcpyDtoH *hipMemcpyDtoH;
|
||||
thipMemcpyDtoD *hipMemcpyDtoD;
|
||||
thipDrvMemcpy2DUnaligned *hipDrvMemcpy2DUnaligned;
|
||||
thipMemcpyParam2D *hipMemcpyParam2D;
|
||||
thipDrvMemcpy3D *hipDrvMemcpy3D;
|
||||
thipMemcpyHtoDAsync *hipMemcpyHtoDAsync;
|
||||
thipMemcpyDtoHAsync *hipMemcpyDtoHAsync;
|
||||
thipMemcpyParam2DAsync *hipMemcpyParam2DAsync;
|
||||
thipDrvMemcpy3DAsync *hipDrvMemcpy3DAsync;
|
||||
thipMemsetD8 *hipMemsetD8;
|
||||
thipMemsetD16 *hipMemsetD16;
|
||||
thipMemsetD32 *hipMemsetD32;
|
||||
thipMemsetD8Async *hipMemsetD8Async;
|
||||
thipMemsetD16Async *hipMemsetD16Async;
|
||||
thipMemsetD32Async *hipMemsetD32Async;
|
||||
thipArrayCreate *hipArrayCreate;
|
||||
thipArrayDestroy *hipArrayDestroy;
|
||||
thipArray3DCreate *hipArray3DCreate;
|
||||
thipStreamCreateWithFlags *hipStreamCreateWithFlags;
|
||||
thipStreamCreateWithPriority *hipStreamCreateWithPriority;
|
||||
thipStreamGetPriority *hipStreamGetPriority;
|
||||
thipStreamGetFlags *hipStreamGetFlags;
|
||||
thipStreamWaitEvent *hipStreamWaitEvent;
|
||||
thipStreamAddCallback *hipStreamAddCallback;
|
||||
thipStreamQuery *hipStreamQuery;
|
||||
thipStreamSynchronize *hipStreamSynchronize;
|
||||
thipStreamDestroy *hipStreamDestroy;
|
||||
thipEventCreateWithFlags *hipEventCreateWithFlags;
|
||||
thipEventRecord *hipEventRecord;
|
||||
thipEventQuery *hipEventQuery;
|
||||
thipEventSynchronize *hipEventSynchronize;
|
||||
thipEventDestroy *hipEventDestroy;
|
||||
thipEventElapsedTime *hipEventElapsedTime;
|
||||
thipFuncGetAttribute *hipFuncGetAttribute;
|
||||
thipFuncSetCacheConfig *hipFuncSetCacheConfig;
|
||||
thipModuleLaunchKernel *hipModuleLaunchKernel;
|
||||
thipDrvOccupancyMaxActiveBlocksPerMultiprocessor *hipDrvOccupancyMaxActiveBlocksPerMultiprocessor;
|
||||
thipDrvOccupancyMaxActiveBlocksPerMultiprocessorWithFlags *hipDrvOccupancyMaxActiveBlocksPerMultiprocessorWithFlags;
|
||||
thipModuleOccupancyMaxPotentialBlockSize *hipModuleOccupancyMaxPotentialBlockSize;
|
||||
thipTexRefSetArray *hipTexRefSetArray;
|
||||
thipTexRefSetAddress *hipTexRefSetAddress;
|
||||
thipTexRefSetAddress2D *hipTexRefSetAddress2D;
|
||||
thipTexRefSetFormat *hipTexRefSetFormat;
|
||||
thipTexRefSetAddressMode *hipTexRefSetAddressMode;
|
||||
thipTexRefSetFilterMode *hipTexRefSetFilterMode;
|
||||
thipTexRefSetFlags *hipTexRefSetFlags;
|
||||
thipTexRefGetAddress *hipTexRefGetAddress;
|
||||
thipTexRefGetArray *hipTexRefGetArray;
|
||||
thipTexRefGetAddressMode *hipTexRefGetAddressMode;
|
||||
thipTexObjectCreate *hipTexObjectCreate;
|
||||
thipTexObjectDestroy *hipTexObjectDestroy;
|
||||
thipDeviceCanAccessPeer *hipDeviceCanAccessPeer;
|
||||
|
||||
thipCtxEnablePeerAccess *hipCtxEnablePeerAccess;
|
||||
thipCtxDisablePeerAccess *hipCtxDisablePeerAccess;
|
||||
thipDeviceGetP2PAttribute *hipDeviceGetP2PAttribute;
|
||||
thipGraphicsUnregisterResource *hipGraphicsUnregisterResource;
|
||||
thipGraphicsMapResources *hipGraphicsMapResources;
|
||||
thipGraphicsUnmapResources *hipGraphicsUnmapResources;
|
||||
thipGraphicsResourceGetMappedPointer *hipGraphicsResourceGetMappedPointer;
|
||||
|
||||
thipGraphicsGLRegisterBuffer *hipGraphicsGLRegisterBuffer;
|
||||
thipGLGetDevices *hipGLGetDevices;
|
||||
|
||||
thiprtcGetErrorString* hiprtcGetErrorString;
|
||||
thiprtcAddNameExpression* hiprtcAddNameExpression;
|
||||
thiprtcCompileProgram* hiprtcCompileProgram;
|
||||
thiprtcCreateProgram* hiprtcCreateProgram;
|
||||
thiprtcDestroyProgram* hiprtcDestroyProgram;
|
||||
thiprtcGetLoweredName* hiprtcGetLoweredName;
|
||||
thiprtcGetProgramLog* hiprtcGetProgramLog;
|
||||
thiprtcGetProgramLogSize* hiprtcGetProgramLogSize;
|
||||
thiprtcGetCode* hiprtcGetCode;
|
||||
thiprtcGetCodeSize* hiprtcGetCodeSize;
|
||||
|
||||
|
||||
|
||||
static DynamicLibrary dynamic_library_open_find(const char **paths) {
|
||||
int i = 0;
|
||||
while (paths[i] != NULL) {
|
||||
DynamicLibrary lib = dynamic_library_open(paths[i]);
|
||||
if (lib != NULL) {
|
||||
return lib;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Implementation function. */
|
||||
static void hipewHipExit(void) {
|
||||
if (hip_lib != NULL) {
|
||||
/* Ignore errors. */
|
||||
dynamic_library_close(hip_lib);
|
||||
hip_lib = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int hipewHipInit(void) {
|
||||
/* Library paths. */
|
||||
#ifdef _WIN32
|
||||
/* Expected in c:/windows/system or similar, no path needed. */
|
||||
const char *hip_paths[] = {"amdhip64.dll", NULL};
|
||||
#elif defined(__APPLE__)
|
||||
/* Default installation path. */
|
||||
const char *hip_paths[] = {"", NULL};
|
||||
#else
|
||||
const char *hip_paths[] = {"/opt/rocm/hip/lib/libamdhip64.so", NULL};
|
||||
#endif
|
||||
static int initialized = 0;
|
||||
static int result = 0;
|
||||
int error, driver_version;
|
||||
|
||||
if (initialized) {
|
||||
return result;
|
||||
}
|
||||
|
||||
initialized = 1;
|
||||
|
||||
error = atexit(hipewHipExit);
|
||||
if (error) {
|
||||
result = HIPEW_ERROR_ATEXIT_FAILED;
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Load library. */
|
||||
hip_lib = dynamic_library_open_find(hip_paths);
|
||||
|
||||
if (hip_lib == NULL) {
|
||||
result = HIPEW_ERROR_OPEN_FAILED;
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Fetch all function pointers. */
|
||||
HIP_LIBRARY_FIND_CHECKED(hipGetErrorName);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipInit);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipDriverGetVersion);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipGetDevice);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipGetDeviceCount);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipGetDeviceProperties);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipDeviceGetName);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipDeviceGetAttribute);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipDeviceComputeCapability);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipDevicePrimaryCtxRetain);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipDevicePrimaryCtxRelease);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipDevicePrimaryCtxSetFlags);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipDevicePrimaryCtxGetState);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipDevicePrimaryCtxReset);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipCtxCreate);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipCtxDestroy);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipCtxPushCurrent);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipCtxPopCurrent);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipCtxSetCurrent);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipCtxGetCurrent);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipCtxGetDevice);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipCtxGetFlags);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipCtxSynchronize);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipDeviceSynchronize);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipCtxGetCacheConfig);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipCtxSetCacheConfig);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipCtxGetSharedMemConfig);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipCtxSetSharedMemConfig);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipCtxGetApiVersion);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipModuleLoad);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipModuleLoadData);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipModuleLoadDataEx);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipModuleUnload);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipModuleGetFunction);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipModuleGetGlobal);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipModuleGetTexRef);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipMemGetInfo);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipMalloc);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipMemAllocPitch);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipFree);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipMemGetAddressRange);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipHostMalloc);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipHostFree);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipHostGetDevicePointer);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipHostGetFlags);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipMallocManaged);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipDeviceGetByPCIBusId);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipDeviceGetPCIBusId);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipMemcpyPeer);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipMemcpyHtoD);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipMemcpyDtoH);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipMemcpyDtoD);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipMemcpyParam2D);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipDrvMemcpy3D);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipMemcpyHtoDAsync);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipMemcpyDtoHAsync);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipDrvMemcpy2DUnaligned);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipMemcpyParam2DAsync);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipDrvMemcpy3DAsync);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipMemsetD8);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipMemsetD16);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipMemsetD32);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipMemsetD8Async);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipMemsetD16Async);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipMemsetD32Async);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipArrayCreate);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipArrayDestroy);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipArray3DCreate);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipStreamCreateWithFlags);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipStreamCreateWithPriority);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipStreamGetPriority);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipStreamGetFlags);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipStreamWaitEvent);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipStreamAddCallback);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipStreamQuery);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipStreamSynchronize);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipStreamDestroy);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipEventCreateWithFlags);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipEventRecord);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipEventQuery);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipEventSynchronize);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipEventDestroy);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipEventElapsedTime);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipFuncGetAttribute);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipFuncSetCacheConfig);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipModuleLaunchKernel);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipModuleOccupancyMaxPotentialBlockSize);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipTexRefSetArray);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipTexRefSetAddress);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipTexRefSetAddress2D);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipTexRefSetFormat);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipTexRefSetAddressMode);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipTexRefSetFilterMode);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipTexRefSetFlags);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipTexRefGetAddress);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipTexRefGetAddressMode);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipTexObjectCreate);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipTexObjectDestroy);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipDeviceCanAccessPeer);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipCtxEnablePeerAccess);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipCtxDisablePeerAccess);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipDeviceGetP2PAttribute);
|
||||
#ifdef _WIN32
|
||||
HIP_LIBRARY_FIND_CHECKED(hipGraphicsUnregisterResource);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipGraphicsMapResources);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipGraphicsUnmapResources);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipGraphicsResourceGetMappedPointer);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipGraphicsGLRegisterBuffer);
|
||||
HIP_LIBRARY_FIND_CHECKED(hipGLGetDevices);
|
||||
#endif
|
||||
HIP_LIBRARY_FIND_CHECKED(hiprtcGetErrorString);
|
||||
HIP_LIBRARY_FIND_CHECKED(hiprtcAddNameExpression);
|
||||
HIP_LIBRARY_FIND_CHECKED(hiprtcCompileProgram);
|
||||
HIP_LIBRARY_FIND_CHECKED(hiprtcCreateProgram);
|
||||
HIP_LIBRARY_FIND_CHECKED(hiprtcDestroyProgram);
|
||||
HIP_LIBRARY_FIND_CHECKED(hiprtcGetLoweredName);
|
||||
HIP_LIBRARY_FIND_CHECKED(hiprtcGetProgramLog);
|
||||
HIP_LIBRARY_FIND_CHECKED(hiprtcGetProgramLogSize);
|
||||
HIP_LIBRARY_FIND_CHECKED(hiprtcGetCode);
|
||||
HIP_LIBRARY_FIND_CHECKED(hiprtcGetCodeSize);
|
||||
result = HIPEW_SUCCESS;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int hipewInit(hipuint32_t flags) {
|
||||
int result = HIPEW_SUCCESS;
|
||||
|
||||
if (flags & HIPEW_INIT_HIP) {
|
||||
result = hipewHipInit();
|
||||
if (result != HIPEW_SUCCESS) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
const char *hipewErrorString(hipError_t result) {
|
||||
switch (result) {
|
||||
case hipSuccess: return "No errors";
|
||||
case hipErrorInvalidValue: return "Invalid value";
|
||||
case hipErrorOutOfMemory: return "Out of memory";
|
||||
case hipErrorNotInitialized: return "Driver not initialized";
|
||||
case hipErrorDeinitialized: return "Driver deinitialized";
|
||||
case hipErrorProfilerDisabled: return "Profiler disabled";
|
||||
case hipErrorProfilerNotInitialized: return "Profiler not initialized";
|
||||
case hipErrorProfilerAlreadyStarted: return "Profiler already started";
|
||||
case hipErrorProfilerAlreadyStopped: return "Profiler already stopped";
|
||||
case hipErrorNoDevice: return "No HIP-capable device available";
|
||||
case hipErrorInvalidDevice: return "Invalid device";
|
||||
case hipErrorInvalidImage: return "Invalid kernel image";
|
||||
case hipErrorInvalidContext: return "Invalid context";
|
||||
case hipErrorContextAlreadyCurrent: return "Context already current";
|
||||
case hipErrorMapFailed: return "Map failed";
|
||||
case hipErrorUnmapFailed: return "Unmap failed";
|
||||
case hipErrorArrayIsMapped: return "Array is mapped";
|
||||
case hipErrorAlreadyMapped: return "Already mapped";
|
||||
case hipErrorNoBinaryForGpu: return "No binary for GPU";
|
||||
case hipErrorAlreadyAcquired: return "Already acquired";
|
||||
case hipErrorNotMapped: return "Not mapped";
|
||||
case hipErrorNotMappedAsArray: return "Mapped resource not available for access as an array";
|
||||
case hipErrorNotMappedAsPointer: return "Mapped resource not available for access as a pointer";
|
||||
case hipErrorECCNotCorrectable: return "Uncorrectable ECC error detected";
|
||||
case hipErrorUnsupportedLimit: return "hipLimit_t not supported by device";
|
||||
case hipErrorContextAlreadyInUse: return "Context already in use";
|
||||
case hipErrorPeerAccessUnsupported: return "Peer access unsupported";
|
||||
case hipErrorInvalidKernelFile: return "Invalid ptx";
|
||||
case hipErrorInvalidGraphicsContext: return "Invalid graphics context";
|
||||
case hipErrorInvalidSource: return "Invalid source";
|
||||
case hipErrorFileNotFound: return "File not found";
|
||||
case hipErrorSharedObjectSymbolNotFound: return "Link to a shared object failed to resolve";
|
||||
case hipErrorSharedObjectInitFailed: return "Shared object initialization failed";
|
||||
case hipErrorOperatingSystem: return "Operating system";
|
||||
case hipErrorInvalidHandle: return "Invalid handle";
|
||||
case hipErrorNotFound: return "Not found";
|
||||
case hipErrorNotReady: return "HIP not ready";
|
||||
case hipErrorIllegalAddress: return "Illegal address";
|
||||
case hipErrorLaunchOutOfResources: return "Launch exceeded resources";
|
||||
case hipErrorLaunchTimeOut: return "Launch exceeded timeout";
|
||||
case hipErrorPeerAccessAlreadyEnabled: return "Peer access already enabled";
|
||||
case hipErrorPeerAccessNotEnabled: return "Peer access not enabled";
|
||||
case hipErrorSetOnActiveProcess: return "Primary context active";
|
||||
case hipErrorAssert: return "Assert";
|
||||
case hipErrorHostMemoryAlreadyRegistered: return "Host memory already registered";
|
||||
case hipErrorHostMemoryNotRegistered: return "Host memory not registered";
|
||||
case hipErrorLaunchFailure: return "Launch failed";
|
||||
case hipErrorCooperativeLaunchTooLarge: return "Cooperative launch too large";
|
||||
case hipErrorNotSupported: return "Not supported";
|
||||
case hipErrorUnknown: return "Unknown error";
|
||||
default: return "Unknown HIP error value";
|
||||
}
|
||||
}
|
||||
|
||||
static void path_join(const char *path1,
|
||||
const char *path2,
|
||||
int maxlen,
|
||||
char *result) {
|
||||
#if defined(WIN32) || defined(_WIN32)
|
||||
const char separator = '\\';
|
||||
#else
|
||||
const char separator = '/';
|
||||
#endif
|
||||
int n = snprintf(result, maxlen, "%s%c%s", path1, separator, path2);
|
||||
if (n != -1 && n < maxlen) {
|
||||
result[n] = '\0';
|
||||
}
|
||||
else {
|
||||
result[maxlen - 1] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
static int path_exists(const char *path) {
|
||||
struct stat st;
|
||||
if (stat(path, &st)) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char *hipewCompilerPath(void) {
|
||||
#ifdef _WIN32
|
||||
const char *hipPath = getenv("HIP_ROCCLR_HOME");
|
||||
const char *windowsCommand = "perl ";
|
||||
const char *executable = "bin/hipcc";
|
||||
|
||||
static char hipcc[65536];
|
||||
static char finalCommand[65536];
|
||||
if(hipPath) {
|
||||
path_join(hipPath, executable, sizeof(hipcc), hipcc);
|
||||
if(path_exists(hipcc)) {
|
||||
snprintf(finalCommand, sizeof(hipcc), "%s %s", windowsCommand, hipcc);
|
||||
return finalCommand;
|
||||
} else {
|
||||
printf("Could not find hipcc. Make sure HIP_ROCCLR_HOME points to the directory holding /bin/hipcc");
|
||||
}
|
||||
}
|
||||
#else
|
||||
const char *hipPath = "opt/rocm/hip/bin";
|
||||
const char *executable = "hipcc";
|
||||
|
||||
static char hipcc[65536];
|
||||
if(hipPath) {
|
||||
path_join(hipPath, executable, sizeof(hipcc), hipcc);
|
||||
if(path_exists(hipcc)){
|
||||
return hipcc;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
{
|
||||
#ifdef _WIN32
|
||||
FILE *handle = popen("where hipcc", "r");
|
||||
#else
|
||||
FILE *handle = popen("which hipcc", "r");
|
||||
#endif
|
||||
if (handle) {
|
||||
char buffer[4096] = {0};
|
||||
int len = fread(buffer, 1, sizeof(buffer) - 1, handle);
|
||||
buffer[len] = '\0';
|
||||
pclose(handle);
|
||||
if (buffer[0]) {
|
||||
return "hipcc";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int hipewCompilerVersion(void) {
|
||||
const char *path = hipewCompilerPath();
|
||||
const char *marker = "Hip compilation tools, release ";
|
||||
FILE *pipe;
|
||||
int major, minor;
|
||||
char *versionstr;
|
||||
char buf[128];
|
||||
char output[65536] = "\0";
|
||||
char command[65536] = "\0";
|
||||
|
||||
if (path == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* get --version output */
|
||||
strcat(command, "\"");
|
||||
strncat(command, path, sizeof(command) - 1);
|
||||
strncat(command, "\" --version", sizeof(command) - strlen(path) - 1);
|
||||
pipe = popen(command, "r");
|
||||
if (!pipe) {
|
||||
fprintf(stderr, "HIP: failed to run compiler to retrieve version");
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (!feof(pipe)) {
|
||||
if (fgets(buf, sizeof(buf), pipe) != NULL) {
|
||||
strncat(output, buf, sizeof(output) - strlen(output) - 1);
|
||||
}
|
||||
}
|
||||
|
||||
pclose(pipe);
|
||||
return 40;
|
||||
}
|
5
extern/json/README.blender
vendored
5
extern/json/README.blender
vendored
@@ -1,5 +0,0 @@
|
||||
Project: JSON
|
||||
URL: https://github.com/nlohmann/json/
|
||||
License: MIT License
|
||||
Upstream version: 3.10.2
|
||||
Local modifications: None
|
26640
extern/json/include/json.hpp
vendored
26640
extern/json/include/json.hpp
vendored
File diff suppressed because it is too large
Load Diff
2
extern/smaa_areatex/smaa_areatex.cpp
vendored
2
extern/smaa_areatex/smaa_areatex.cpp
vendored
@@ -574,8 +574,6 @@ Dbl2 AreaDiag::area(Dbl2 p1, Dbl2 p2, int left)
|
||||
Dbl2 d = p2 - p1;
|
||||
if (d.x == 0.0)
|
||||
return Dbl2(0.0, 1.0);
|
||||
if (d.y == 0.0)
|
||||
return Dbl2(1.0, 0.0);
|
||||
|
||||
double x1 = (double)(1 + left);
|
||||
double x2 = x1 + 1.0;
|
||||
|
6
extern/tinygltf/README.blender
vendored
6
extern/tinygltf/README.blender
vendored
@@ -1,6 +0,0 @@
|
||||
Project: TinyGLTF
|
||||
URL: https://github.com/syoyo/tinygltf
|
||||
License: MIT
|
||||
Upstream version: 2.5.0, 19a41d20ec0
|
||||
Local modifications:
|
||||
* Silence "enum value not handled in switch" warnings due to JSON dependency.
|
BIN
extern/tinygltf/patches/TinyGLTF.diff
vendored
BIN
extern/tinygltf/patches/TinyGLTF.diff
vendored
Binary file not shown.
7761
extern/tinygltf/tiny_gltf.h
vendored
7761
extern/tinygltf/tiny_gltf.h
vendored
File diff suppressed because it is too large
Load Diff
@@ -247,7 +247,7 @@ if(WITH_CYCLES_OSL)
|
||||
endif()
|
||||
|
||||
if(WITH_CYCLES_DEVICE_OPTIX)
|
||||
find_package(OptiX 7.3.0)
|
||||
find_package(OptiX)
|
||||
|
||||
if(OPTIX_FOUND)
|
||||
add_definitions(-DWITH_OPTIX)
|
||||
@@ -286,14 +286,14 @@ if(WITH_OPENSUBDIV)
|
||||
)
|
||||
endif()
|
||||
|
||||
if(WITH_OPENIMAGEDENOISE)
|
||||
add_definitions(-DWITH_OPENIMAGEDENOISE)
|
||||
add_definitions(-DOIDN_STATIC_LIB)
|
||||
include_directories(
|
||||
SYSTEM
|
||||
${OPENIMAGEDENOISE_INCLUDE_DIRS}
|
||||
)
|
||||
if(WITH_CYCLES_STANDALONE)
|
||||
set(WITH_CYCLES_DEVICE_OPENCL TRUE)
|
||||
set(WITH_CYCLES_DEVICE_CUDA TRUE)
|
||||
# Experimental and unfinished.
|
||||
set(WITH_CYCLES_NETWORK FALSE)
|
||||
endif()
|
||||
# TODO(sergey): Consider removing it, only causes confusion in interface.
|
||||
set(WITH_CYCLES_DEVICE_MULTI TRUE)
|
||||
|
||||
# Logging capabilities using GLog library.
|
||||
if(WITH_CYCLES_LOGGING)
|
||||
@@ -386,15 +386,20 @@ if(WITH_CYCLES_BLENDER)
|
||||
add_subdirectory(blender)
|
||||
endif()
|
||||
|
||||
add_subdirectory(app)
|
||||
if(WITH_CYCLES_NETWORK)
|
||||
add_definitions(-DWITH_NETWORK)
|
||||
endif()
|
||||
|
||||
if(WITH_CYCLES_STANDALONE OR WITH_CYCLES_NETWORK OR WITH_CYCLES_CUBIN_COMPILER)
|
||||
add_subdirectory(app)
|
||||
endif()
|
||||
|
||||
add_subdirectory(bvh)
|
||||
add_subdirectory(device)
|
||||
add_subdirectory(doc)
|
||||
add_subdirectory(graph)
|
||||
add_subdirectory(integrator)
|
||||
add_subdirectory(kernel)
|
||||
add_subdirectory(scene)
|
||||
add_subdirectory(session)
|
||||
add_subdirectory(render)
|
||||
add_subdirectory(subd)
|
||||
add_subdirectory(util)
|
||||
|
||||
|
@@ -25,8 +25,7 @@ set(INC_SYS
|
||||
set(LIBRARIES
|
||||
cycles_device
|
||||
cycles_kernel
|
||||
cycles_scene
|
||||
cycles_session
|
||||
cycles_render
|
||||
cycles_bvh
|
||||
cycles_subd
|
||||
cycles_graph
|
||||
@@ -65,8 +64,6 @@ if(WITH_CYCLES_STANDALONE)
|
||||
cycles_standalone.cpp
|
||||
cycles_xml.cpp
|
||||
cycles_xml.h
|
||||
oiio_output_driver.cpp
|
||||
oiio_output_driver.h
|
||||
)
|
||||
add_executable(cycles ${SRC} ${INC} ${INC_SYS})
|
||||
unset(SRC)
|
||||
@@ -76,7 +73,7 @@ if(WITH_CYCLES_STANDALONE)
|
||||
|
||||
if(APPLE)
|
||||
if(WITH_OPENCOLORIO)
|
||||
set_property(TARGET cycles APPEND_STRING PROPERTY LINK_FLAGS " -framework IOKit -framework Carbon")
|
||||
set_property(TARGET cycles APPEND_STRING PROPERTY LINK_FLAGS " -framework IOKit")
|
||||
endif()
|
||||
if(WITH_OPENIMAGEDENOISE AND "${CMAKE_OSX_ARCHITECTURES}" STREQUAL "arm64")
|
||||
# OpenImageDenoise uses BNNS from the Accelerate framework.
|
||||
@@ -93,6 +90,24 @@ if(WITH_CYCLES_STANDALONE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#####################################################################
|
||||
# Cycles network server executable
|
||||
#####################################################################
|
||||
|
||||
if(WITH_CYCLES_NETWORK)
|
||||
set(SRC
|
||||
cycles_server.cpp
|
||||
)
|
||||
add_executable(cycles_server ${SRC})
|
||||
target_link_libraries(cycles_server ${LIBRARIES})
|
||||
cycles_target_link_libraries(cycles_server)
|
||||
|
||||
if(UNIX AND NOT APPLE)
|
||||
set_target_properties(cycles_server PROPERTIES INSTALL_RPATH $ORIGIN/lib)
|
||||
endif()
|
||||
unset(SRC)
|
||||
endif()
|
||||
|
||||
#####################################################################
|
||||
# Cycles cubin compiler executable
|
||||
#####################################################################
|
||||
|
@@ -18,13 +18,13 @@
|
||||
|
||||
#include "device/device.h"
|
||||
|
||||
#include "util/args.h"
|
||||
#include "util/foreach.h"
|
||||
#include "util/log.h"
|
||||
#include "util/path.h"
|
||||
#include "util/stats.h"
|
||||
#include "util/string.h"
|
||||
#include "util/task.h"
|
||||
#include "util/util_args.h"
|
||||
#include "util/util_foreach.h"
|
||||
#include "util/util_logging.h"
|
||||
#include "util/util_path.h"
|
||||
#include "util/util_stats.h"
|
||||
#include "util/util_string.h"
|
||||
#include "util/util_task.h"
|
||||
|
||||
using namespace ccl;
|
||||
|
||||
|
@@ -17,30 +17,27 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "device/device.h"
|
||||
#include "scene/camera.h"
|
||||
#include "scene/integrator.h"
|
||||
#include "scene/scene.h"
|
||||
#include "session/buffers.h"
|
||||
#include "session/session.h"
|
||||
#include "render/buffers.h"
|
||||
#include "render/camera.h"
|
||||
#include "render/integrator.h"
|
||||
#include "render/scene.h"
|
||||
#include "render/session.h"
|
||||
|
||||
#include "util/args.h"
|
||||
#include "util/foreach.h"
|
||||
#include "util/function.h"
|
||||
#include "util/image.h"
|
||||
#include "util/log.h"
|
||||
#include "util/path.h"
|
||||
#include "util/progress.h"
|
||||
#include "util/string.h"
|
||||
#include "util/time.h"
|
||||
#include "util/transform.h"
|
||||
#include "util/unique_ptr.h"
|
||||
#include "util/version.h"
|
||||
|
||||
#include "app/cycles_xml.h"
|
||||
#include "app/oiio_output_driver.h"
|
||||
#include "util/util_args.h"
|
||||
#include "util/util_foreach.h"
|
||||
#include "util/util_function.h"
|
||||
#include "util/util_image.h"
|
||||
#include "util/util_logging.h"
|
||||
#include "util/util_path.h"
|
||||
#include "util/util_progress.h"
|
||||
#include "util/util_string.h"
|
||||
#include "util/util_time.h"
|
||||
#include "util/util_transform.h"
|
||||
#include "util/util_unique_ptr.h"
|
||||
#include "util/util_version.h"
|
||||
|
||||
#ifdef WITH_CYCLES_STANDALONE_GUI
|
||||
# include "util/view.h"
|
||||
# include "util/util_view.h"
|
||||
#endif
|
||||
|
||||
#include "app/cycles_xml.h"
|
||||
@@ -56,8 +53,7 @@ struct Options {
|
||||
SessionParams session_params;
|
||||
bool quiet;
|
||||
bool show_help, interactive, pause;
|
||||
string output_filepath;
|
||||
string output_pass;
|
||||
string output_path;
|
||||
} options;
|
||||
|
||||
static void session_print(const string &str)
|
||||
@@ -93,6 +89,30 @@ static void session_print_status()
|
||||
session_print(status);
|
||||
}
|
||||
|
||||
static bool write_render(const uchar *pixels, int w, int h, int channels)
|
||||
{
|
||||
string msg = string_printf("Writing image %s", options.output_path.c_str());
|
||||
session_print(msg);
|
||||
|
||||
unique_ptr<ImageOutput> out = unique_ptr<ImageOutput>(ImageOutput::create(options.output_path));
|
||||
if (!out) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ImageSpec spec(w, h, channels, TypeDesc::UINT8);
|
||||
if (!out->open(options.output_path, spec)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* conversion for different top/bottom convention */
|
||||
out->write_image(
|
||||
TypeDesc::UINT8, pixels + (h - 1) * w * channels, AutoStride, -w * channels, AutoStride);
|
||||
|
||||
out->close();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static BufferParams &session_buffer_params()
|
||||
{
|
||||
static BufferParams buffer_params;
|
||||
@@ -106,7 +126,7 @@ static BufferParams &session_buffer_params()
|
||||
|
||||
static void scene_init()
|
||||
{
|
||||
options.scene = options.session->scene;
|
||||
options.scene = new Scene(options.scene_params, options.session->device);
|
||||
|
||||
/* Read XML */
|
||||
xml_read_file(options.scene, options.filepath.c_str());
|
||||
@@ -127,13 +147,8 @@ static void scene_init()
|
||||
|
||||
static void session_init()
|
||||
{
|
||||
options.output_pass = "combined";
|
||||
options.session = new Session(options.session_params, options.scene_params);
|
||||
|
||||
if (!options.output_filepath.empty()) {
|
||||
options.session->set_output_driver(make_unique<OIIOOutputDriver>(
|
||||
options.output_filepath, options.output_pass, session_print));
|
||||
}
|
||||
options.session_params.write_render_cb = write_render;
|
||||
options.session = new Session(options.session_params);
|
||||
|
||||
if (options.session_params.background && !options.quiet)
|
||||
options.session->progress.set_update_callback(function_bind(&session_print_status));
|
||||
@@ -144,13 +159,9 @@ static void session_init()
|
||||
|
||||
/* load scene */
|
||||
scene_init();
|
||||
options.session->scene = options.scene;
|
||||
|
||||
/* add pass for output. */
|
||||
Pass *pass = options.scene->create_node<Pass>();
|
||||
pass->set_name(ustring(options.output_pass.c_str()));
|
||||
pass->set_type(PASS_COMBINED);
|
||||
|
||||
options.session->reset(options.session_params, session_buffer_params());
|
||||
options.session->reset(session_buffer_params(), options.session_params.samples);
|
||||
options.session->start();
|
||||
}
|
||||
|
||||
@@ -212,7 +223,9 @@ static void display_info(Progress &progress)
|
||||
|
||||
static void display()
|
||||
{
|
||||
options.session->draw();
|
||||
static DeviceDrawParams draw_params = DeviceDrawParams();
|
||||
|
||||
options.session->draw(session_buffer_params(), draw_params);
|
||||
|
||||
display_info(options.session->progress);
|
||||
}
|
||||
@@ -242,7 +255,7 @@ static void motion(int x, int y, int button)
|
||||
options.session->scene->camera->need_flags_update = true;
|
||||
options.session->scene->camera->need_device_update = true;
|
||||
|
||||
options.session->reset(options.session_params, session_buffer_params());
|
||||
options.session->reset(session_buffer_params(), options.session_params.samples);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,7 +272,7 @@ static void resize(int width, int height)
|
||||
options.session->scene->camera->need_flags_update = true;
|
||||
options.session->scene->camera->need_device_update = true;
|
||||
|
||||
options.session->reset(options.session_params, session_buffer_params());
|
||||
options.session->reset(session_buffer_params(), options.session_params.samples);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -271,7 +284,7 @@ static void keyboard(unsigned char key)
|
||||
|
||||
/* Reset */
|
||||
else if (key == 'r')
|
||||
options.session->reset(options.session_params, session_buffer_params());
|
||||
options.session->reset(session_buffer_params(), options.session_params.samples);
|
||||
|
||||
/* Cancel */
|
||||
else if (key == 27) // escape
|
||||
@@ -308,7 +321,7 @@ static void keyboard(unsigned char key)
|
||||
options.session->scene->camera->need_flags_update = true;
|
||||
options.session->scene->camera->need_device_update = true;
|
||||
|
||||
options.session->reset(options.session_params, session_buffer_params());
|
||||
options.session->reset(session_buffer_params(), options.session_params.samples);
|
||||
}
|
||||
|
||||
/* Set Max Bounces */
|
||||
@@ -334,7 +347,7 @@ static void keyboard(unsigned char key)
|
||||
|
||||
options.session->scene->integrator->set_max_bounce(bounce);
|
||||
|
||||
options.session->reset(options.session_params, session_buffer_params());
|
||||
options.session->reset(session_buffer_params(), options.session_params.samples);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -349,13 +362,11 @@ static int files_parse(int argc, const char *argv[])
|
||||
|
||||
static void options_parse(int argc, const char **argv)
|
||||
{
|
||||
options.width = 1024;
|
||||
options.height = 512;
|
||||
options.width = 0;
|
||||
options.height = 0;
|
||||
options.filepath = "";
|
||||
options.session = NULL;
|
||||
options.quiet = false;
|
||||
options.session_params.use_auto_tile = false;
|
||||
options.session_params.tile_size = 0;
|
||||
|
||||
/* device names */
|
||||
string device_names = "";
|
||||
@@ -401,7 +412,7 @@ static void options_parse(int argc, const char **argv)
|
||||
&options.session_params.samples,
|
||||
"Number of samples to render",
|
||||
"--output %s",
|
||||
&options.output_filepath,
|
||||
&options.output_path,
|
||||
"File path to write output image",
|
||||
"--threads %d",
|
||||
&options.session_params.threads,
|
||||
@@ -412,9 +423,12 @@ static void options_parse(int argc, const char **argv)
|
||||
"--height %d",
|
||||
&options.height,
|
||||
"Window height in pixel",
|
||||
"--tile-size %d",
|
||||
&options.session_params.tile_size,
|
||||
"Tile size in pixels",
|
||||
"--tile-width %d",
|
||||
&options.session_params.tile_size.x,
|
||||
"Tile width in pixels",
|
||||
"--tile-height %d",
|
||||
&options.session_params.tile_size.y,
|
||||
"Tile height in pixels",
|
||||
"--list-devices",
|
||||
&list,
|
||||
"List information about all available devices",
|
||||
@@ -476,9 +490,8 @@ static void options_parse(int argc, const char **argv)
|
||||
options.session_params.background = true;
|
||||
#endif
|
||||
|
||||
if (options.session_params.tile_size > 0) {
|
||||
options.session_params.use_auto_tile = true;
|
||||
}
|
||||
/* Use progressive rendering */
|
||||
options.session_params.progressive = true;
|
||||
|
||||
/* find matching device */
|
||||
DeviceType device_type = Device::type_from_string(devicename.c_str());
|
||||
@@ -514,6 +527,9 @@ static void options_parse(int argc, const char **argv)
|
||||
fprintf(stderr, "No file path specified\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* For smoother Viewport */
|
||||
options.session_params.start_resolution = 64;
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
@@ -22,27 +22,27 @@
|
||||
|
||||
#include "graph/node_xml.h"
|
||||
|
||||
#include "scene/background.h"
|
||||
#include "scene/camera.h"
|
||||
#include "scene/film.h"
|
||||
#include "scene/integrator.h"
|
||||
#include "scene/light.h"
|
||||
#include "scene/mesh.h"
|
||||
#include "scene/object.h"
|
||||
#include "scene/osl.h"
|
||||
#include "scene/scene.h"
|
||||
#include "scene/shader.h"
|
||||
#include "scene/shader_graph.h"
|
||||
#include "scene/shader_nodes.h"
|
||||
#include "render/background.h"
|
||||
#include "render/camera.h"
|
||||
#include "render/film.h"
|
||||
#include "render/graph.h"
|
||||
#include "render/integrator.h"
|
||||
#include "render/light.h"
|
||||
#include "render/mesh.h"
|
||||
#include "render/nodes.h"
|
||||
#include "render/object.h"
|
||||
#include "render/osl.h"
|
||||
#include "render/scene.h"
|
||||
#include "render/shader.h"
|
||||
|
||||
#include "subd/patch.h"
|
||||
#include "subd/split.h"
|
||||
#include "subd/subd_patch.h"
|
||||
#include "subd/subd_split.h"
|
||||
|
||||
#include "util/foreach.h"
|
||||
#include "util/path.h"
|
||||
#include "util/projection.h"
|
||||
#include "util/transform.h"
|
||||
#include "util/xml.h"
|
||||
#include "util/util_foreach.h"
|
||||
#include "util/util_path.h"
|
||||
#include "util/util_projection.h"
|
||||
#include "util/util_transform.h"
|
||||
#include "util/util_xml.h"
|
||||
|
||||
#include "app/cycles_xml.h"
|
||||
|
||||
@@ -333,7 +333,6 @@ static void xml_read_shader_graph(XMLReadState &state, Shader *shader, xml_node
|
||||
}
|
||||
|
||||
snode = (ShaderNode *)node_type->create(node_type);
|
||||
snode->set_owner(graph);
|
||||
}
|
||||
|
||||
xml_read_node(graph_reader, snode, node);
|
||||
@@ -704,7 +703,7 @@ void xml_read_file(Scene *scene, const char *filepath)
|
||||
|
||||
xml_read_include(state, path_filename(filepath));
|
||||
|
||||
scene->params.bvh_type = BVH_TYPE_STATIC;
|
||||
scene->params.bvh_type = SceneParams::BVH_STATIC;
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
* Copyright 2021 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 "app/oiio_output_driver.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
OIIOOutputDriver::OIIOOutputDriver(const string_view filepath,
|
||||
const string_view pass,
|
||||
LogFunction log)
|
||||
: filepath_(filepath), pass_(pass), log_(log)
|
||||
{
|
||||
}
|
||||
|
||||
OIIOOutputDriver::~OIIOOutputDriver()
|
||||
{
|
||||
}
|
||||
|
||||
void OIIOOutputDriver::write_render_tile(const Tile &tile)
|
||||
{
|
||||
/* Only write the full buffer, no intermediate tiles. */
|
||||
if (!(tile.size == tile.full_size)) {
|
||||
return;
|
||||
}
|
||||
|
||||
log_(string_printf("Writing image %s", filepath_.c_str()));
|
||||
|
||||
unique_ptr<ImageOutput> image_output(ImageOutput::create(filepath_));
|
||||
if (image_output == nullptr) {
|
||||
log_("Failed to create image file");
|
||||
return;
|
||||
}
|
||||
|
||||
const int width = tile.size.x;
|
||||
const int height = tile.size.y;
|
||||
|
||||
ImageSpec spec(width, height, 4, TypeDesc::FLOAT);
|
||||
if (!image_output->open(filepath_, spec)) {
|
||||
log_("Failed to create image file");
|
||||
return;
|
||||
}
|
||||
|
||||
vector<float> pixels(width * height * 4);
|
||||
if (!tile.get_pass_pixels(pass_, 4, pixels.data())) {
|
||||
log_("Failed to read render pass pixels");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Manipulate offset and stride to convert from bottom-up to top-down convention. */
|
||||
image_output->write_image(TypeDesc::FLOAT,
|
||||
pixels.data() + (height - 1) * width * 4,
|
||||
AutoStride,
|
||||
-width * 4 * sizeof(float),
|
||||
AutoStride);
|
||||
image_output->close();
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright 2021 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 "session/output_driver.h"
|
||||
|
||||
#include "util/function.h"
|
||||
#include "util/image.h"
|
||||
#include "util/string.h"
|
||||
#include "util/unique_ptr.h"
|
||||
#include "util/vector.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
class OIIOOutputDriver : public OutputDriver {
|
||||
public:
|
||||
typedef function<void(const string &)> LogFunction;
|
||||
|
||||
OIIOOutputDriver(const string_view filepath, const string_view pass, LogFunction log);
|
||||
virtual ~OIIOOutputDriver();
|
||||
|
||||
void write_render_tile(const Tile &tile) override;
|
||||
|
||||
protected:
|
||||
string filepath_;
|
||||
string pass_;
|
||||
LogFunction log_;
|
||||
};
|
||||
|
||||
CCL_NAMESPACE_END
|
@@ -29,39 +29,35 @@ set(INC_SYS
|
||||
)
|
||||
|
||||
set(SRC
|
||||
camera.cpp
|
||||
device.cpp
|
||||
display_driver.cpp
|
||||
image.cpp
|
||||
geometry.cpp
|
||||
light.cpp
|
||||
mesh.cpp
|
||||
object.cpp
|
||||
object_cull.cpp
|
||||
output_driver.cpp
|
||||
particles.cpp
|
||||
curves.cpp
|
||||
logging.cpp
|
||||
python.cpp
|
||||
session.cpp
|
||||
shader.cpp
|
||||
sync.cpp
|
||||
texture.cpp
|
||||
viewport.cpp
|
||||
volume.cpp
|
||||
blender_camera.cpp
|
||||
blender_device.cpp
|
||||
blender_image.cpp
|
||||
blender_geometry.cpp
|
||||
blender_light.cpp
|
||||
blender_mesh.cpp
|
||||
blender_object.cpp
|
||||
blender_object_cull.cpp
|
||||
blender_particles.cpp
|
||||
blender_curves.cpp
|
||||
blender_logging.cpp
|
||||
blender_python.cpp
|
||||
blender_session.cpp
|
||||
blender_shader.cpp
|
||||
blender_sync.cpp
|
||||
blender_texture.cpp
|
||||
blender_viewport.cpp
|
||||
blender_volume.cpp
|
||||
|
||||
CCL_api.h
|
||||
device.h
|
||||
display_driver.h
|
||||
id_map.h
|
||||
image.h
|
||||
object_cull.h
|
||||
output_driver.h
|
||||
sync.h
|
||||
session.h
|
||||
texture.h
|
||||
util.h
|
||||
viewport.h
|
||||
blender_device.h
|
||||
blender_id_map.h
|
||||
blender_image.h
|
||||
blender_object_cull.h
|
||||
blender_sync.h
|
||||
blender_session.h
|
||||
blender_texture.h
|
||||
blender_util.h
|
||||
blender_viewport.h
|
||||
)
|
||||
|
||||
set(LIB
|
||||
@@ -69,8 +65,7 @@ set(LIB
|
||||
cycles_device
|
||||
cycles_graph
|
||||
cycles_kernel
|
||||
cycles_scene
|
||||
cycles_session
|
||||
cycles_render
|
||||
cycles_subd
|
||||
cycles_util
|
||||
|
||||
@@ -98,9 +93,14 @@ set(ADDON_FILES
|
||||
|
||||
add_definitions(${GL_DEFINITIONS})
|
||||
|
||||
if(WITH_CYCLES_DEVICE_HIP)
|
||||
add_definitions(-DWITH_HIP)
|
||||
if(WITH_CYCLES_DEVICE_OPENCL)
|
||||
add_definitions(-DWITH_OPENCL)
|
||||
endif()
|
||||
|
||||
if(WITH_CYCLES_NETWORK)
|
||||
add_definitions(-DWITH_NETWORK)
|
||||
endif()
|
||||
|
||||
if(WITH_MOD_FLUID)
|
||||
add_definitions(-DWITH_FLUID)
|
||||
endif()
|
||||
|
@@ -58,6 +58,7 @@ class CyclesRender(bpy.types.RenderEngine):
|
||||
bl_use_eevee_viewport = True
|
||||
bl_use_preview = True
|
||||
bl_use_exclude_layers = True
|
||||
bl_use_save_buffers = True
|
||||
bl_use_spherical_stereo = True
|
||||
bl_use_custom_freestyle = True
|
||||
bl_use_alembic_procedural = True
|
||||
@@ -84,12 +85,6 @@ class CyclesRender(bpy.types.RenderEngine):
|
||||
def render(self, depsgraph):
|
||||
engine.render(self, depsgraph)
|
||||
|
||||
def render_frame_finish(self):
|
||||
engine.render_frame_finish(self)
|
||||
|
||||
def draw(self, context, depsgraph):
|
||||
engine.draw(self, depsgraph, context.space_data)
|
||||
|
||||
def bake(self, depsgraph, obj, pass_type, pass_filter, width, height):
|
||||
engine.bake(self, depsgraph, obj, pass_type, pass_filter, width, height)
|
||||
|
||||
@@ -103,7 +98,7 @@ class CyclesRender(bpy.types.RenderEngine):
|
||||
engine.sync(self, depsgraph, context.blend_data)
|
||||
|
||||
def view_draw(self, context, depsgraph):
|
||||
engine.view_draw(self, depsgraph, context.region, context.space_data, context.region_data)
|
||||
engine.draw(self, depsgraph, context.region, context.space_data, context.region_data)
|
||||
|
||||
def update_script_node(self, node):
|
||||
if engine.with_osl():
|
||||
|
@@ -18,17 +18,62 @@
|
||||
from __future__ import annotations
|
||||
|
||||
|
||||
def _is_using_buggy_driver():
|
||||
import gpu
|
||||
# We need to be conservative here because in multi-GPU systems display card
|
||||
# might be quite old, but others one might be just good.
|
||||
#
|
||||
# So We shouldn't disable possible good dedicated cards just because display
|
||||
# card seems weak. And instead we only blacklist configurations which are
|
||||
# proven to cause problems.
|
||||
if gpu.platform.vendor_get() == "ATI Technologies Inc.":
|
||||
import re
|
||||
version = gpu.platform.version_get()
|
||||
if version.endswith("Compatibility Profile Context"):
|
||||
# Old HD 4xxx and 5xxx series drivers did not have driver version
|
||||
# in the version string, but those cards do not quite work and
|
||||
# causing crashes.
|
||||
return True
|
||||
regex = re.compile(".*Compatibility Profile Context ([0-9]+(\\.[0-9]+)+)$")
|
||||
if not regex.match(version):
|
||||
# Skip cards like FireGL
|
||||
return False
|
||||
version = regex.sub("\\1", version).split('.')
|
||||
return int(version[0]) == 8
|
||||
return False
|
||||
|
||||
|
||||
def _workaround_buggy_drivers():
|
||||
if _is_using_buggy_driver():
|
||||
import _cycles
|
||||
if hasattr(_cycles, "opencl_disable"):
|
||||
print("Cycles: OpenGL driver known to be buggy, disabling OpenCL platform.")
|
||||
_cycles.opencl_disable()
|
||||
|
||||
|
||||
def _configure_argument_parser():
|
||||
import argparse
|
||||
# No help because it conflicts with general Python scripts argument parsing
|
||||
parser = argparse.ArgumentParser(description="Cycles Addon argument parser",
|
||||
add_help=False)
|
||||
parser.add_argument("--cycles-resumable-num-chunks",
|
||||
help="Number of chunks to split sample range into",
|
||||
default=None)
|
||||
parser.add_argument("--cycles-resumable-current-chunk",
|
||||
help="Current chunk of samples range to render",
|
||||
default=None)
|
||||
parser.add_argument("--cycles-resumable-start-chunk",
|
||||
help="Start chunk to render",
|
||||
default=None)
|
||||
parser.add_argument("--cycles-resumable-end-chunk",
|
||||
help="End chunk to render",
|
||||
default=None)
|
||||
parser.add_argument("--cycles-print-stats",
|
||||
help="Print rendering statistics to stderr",
|
||||
action='store_true')
|
||||
parser.add_argument("--cycles-device",
|
||||
help="Set the device to use for Cycles, overriding user preferences and the scene setting."
|
||||
"Valid options are 'CPU', 'CUDA', 'OPTIX', or 'HIP'"
|
||||
"Valid options are 'CPU', 'CUDA', 'OPTIX' or 'OPENCL'."
|
||||
"Additionally, you can append '+CPU' to any GPU type for hybrid rendering.",
|
||||
default=None)
|
||||
return parser
|
||||
@@ -44,6 +89,21 @@ def _parse_command_line():
|
||||
parser = _configure_argument_parser()
|
||||
args, _ = parser.parse_known_args(argv[argv.index("--") + 1:])
|
||||
|
||||
if args.cycles_resumable_num_chunks is not None:
|
||||
if args.cycles_resumable_current_chunk is not None:
|
||||
import _cycles
|
||||
_cycles.set_resumable_chunk(
|
||||
int(args.cycles_resumable_num_chunks),
|
||||
int(args.cycles_resumable_current_chunk),
|
||||
)
|
||||
elif args.cycles_resumable_start_chunk is not None and \
|
||||
args.cycles_resumable_end_chunk:
|
||||
import _cycles
|
||||
_cycles.set_resumable_chunk_range(
|
||||
int(args.cycles_resumable_num_chunks),
|
||||
int(args.cycles_resumable_start_chunk),
|
||||
int(args.cycles_resumable_end_chunk),
|
||||
)
|
||||
if args.cycles_print_stats:
|
||||
import _cycles
|
||||
_cycles.enable_print_stats()
|
||||
@@ -58,11 +118,23 @@ def init():
|
||||
import _cycles
|
||||
import os.path
|
||||
|
||||
# Workaround possibly buggy legacy drivers which crashes on the OpenCL
|
||||
# device enumeration.
|
||||
#
|
||||
# This checks are not really correct because they might still fail
|
||||
# in the case of multiple GPUs. However, currently buggy drivers
|
||||
# are really old and likely to be used in single GPU systems only
|
||||
# anyway.
|
||||
#
|
||||
# Can't do it in the background mode, so we hope OpenCL is no enabled
|
||||
# in the user preferences.
|
||||
if not bpy.app.background:
|
||||
_workaround_buggy_drivers()
|
||||
|
||||
path = os.path.dirname(__file__)
|
||||
user_path = os.path.dirname(os.path.abspath(bpy.utils.user_resource('CONFIG', path='')))
|
||||
temp_path = bpy.app.tempdir
|
||||
|
||||
_cycles.init(path, user_path, temp_path, bpy.app.background)
|
||||
_cycles.init(path, user_path, bpy.app.background)
|
||||
_parse_command_line()
|
||||
|
||||
|
||||
@@ -105,25 +177,6 @@ def render(engine, depsgraph):
|
||||
_cycles.render(engine.session, depsgraph.as_pointer())
|
||||
|
||||
|
||||
def render_frame_finish(engine):
|
||||
if not engine.session:
|
||||
return
|
||||
|
||||
import _cycles
|
||||
_cycles.render_frame_finish(engine.session)
|
||||
|
||||
def draw(engine, depsgraph, space_image):
|
||||
if not engine.session:
|
||||
return
|
||||
|
||||
depsgraph_ptr = depsgraph.as_pointer()
|
||||
space_image_ptr = space_image.as_pointer()
|
||||
screen_ptr = space_image.id_data.as_pointer()
|
||||
|
||||
import _cycles
|
||||
_cycles.draw(engine.session, depsgraph_ptr, screen_ptr, space_image_ptr)
|
||||
|
||||
|
||||
def bake(engine, depsgraph, obj, pass_type, pass_filter, width, height):
|
||||
import _cycles
|
||||
session = getattr(engine, "session", None)
|
||||
@@ -151,14 +204,14 @@ def sync(engine, depsgraph, data):
|
||||
_cycles.sync(engine.session, depsgraph.as_pointer())
|
||||
|
||||
|
||||
def view_draw(engine, depsgraph, region, v3d, rv3d):
|
||||
def draw(engine, depsgraph, region, v3d, rv3d):
|
||||
import _cycles
|
||||
depsgraph = depsgraph.as_pointer()
|
||||
v3d = v3d.as_pointer()
|
||||
rv3d = rv3d.as_pointer()
|
||||
|
||||
# draw render image
|
||||
_cycles.view_draw(engine.session, depsgraph, v3d, rv3d)
|
||||
_cycles.draw(engine.session, depsgraph, v3d, rv3d)
|
||||
|
||||
|
||||
def available_devices():
|
||||
@@ -171,6 +224,11 @@ def with_osl():
|
||||
return _cycles.with_osl
|
||||
|
||||
|
||||
def with_network():
|
||||
import _cycles
|
||||
return _cycles.with_network
|
||||
|
||||
|
||||
def system_info():
|
||||
import _cycles
|
||||
return _cycles.system_info()
|
||||
@@ -185,7 +243,6 @@ def list_render_passes(scene, srl):
|
||||
# Data passes.
|
||||
if srl.use_pass_z: yield ("Depth", "Z", 'VALUE')
|
||||
if srl.use_pass_mist: yield ("Mist", "Z", 'VALUE')
|
||||
if srl.use_pass_position: yield ("Position", "XYZ", 'VECTOR')
|
||||
if srl.use_pass_normal: yield ("Normal", "XYZ", 'VECTOR')
|
||||
if srl.use_pass_vector: yield ("Vector", "XYZW", 'VECTOR')
|
||||
if srl.use_pass_uv: yield ("UV", "UVA", 'VECTOR')
|
||||
@@ -208,9 +265,9 @@ def list_render_passes(scene, srl):
|
||||
if srl.use_pass_environment: yield ("Env", "RGB", 'COLOR')
|
||||
if srl.use_pass_shadow: yield ("Shadow", "RGB", 'COLOR')
|
||||
if srl.use_pass_ambient_occlusion: yield ("AO", "RGB", 'COLOR')
|
||||
if crl.use_pass_shadow_catcher: yield ("Shadow Catcher", "RGB", 'COLOR')
|
||||
|
||||
# Debug passes.
|
||||
if crl.pass_debug_render_time: yield ("Debug Render Time", "X", 'VALUE')
|
||||
if crl.pass_debug_sample_count: yield ("Debug Sample Count", "X", 'VALUE')
|
||||
|
||||
# Cryptomatte passes.
|
||||
@@ -226,21 +283,30 @@ def list_render_passes(scene, srl):
|
||||
yield ("CryptoAsset" + '{:02d}'.format(i), "RGBA", 'COLOR')
|
||||
|
||||
# Denoising passes.
|
||||
if scene.cycles.use_denoising and crl.use_denoising:
|
||||
if (scene.cycles.use_denoising and crl.use_denoising) or crl.denoising_store_passes:
|
||||
yield ("Noisy Image", "RGBA", 'COLOR')
|
||||
if crl.use_pass_shadow_catcher:
|
||||
yield ("Noisy Shadow Catcher", "RGBA", 'COLOR')
|
||||
if crl.denoising_store_passes:
|
||||
yield ("Denoising Normal", "XYZ", 'VECTOR')
|
||||
yield ("Denoising Albedo", "RGB", 'COLOR')
|
||||
yield ("Denoising Depth", "Z", 'VALUE')
|
||||
if crl.denoising_store_passes:
|
||||
yield ("Denoising Normal", "XYZ", 'VECTOR')
|
||||
yield ("Denoising Albedo", "RGB", 'COLOR')
|
||||
yield ("Denoising Depth", "Z", 'VALUE')
|
||||
|
||||
if scene.cycles.denoiser == 'NLM':
|
||||
yield ("Denoising Shadowing", "X", 'VALUE')
|
||||
yield ("Denoising Variance", "RGB", 'COLOR')
|
||||
yield ("Denoising Intensity", "X", 'VALUE')
|
||||
|
||||
clean_options = ("denoising_diffuse_direct", "denoising_diffuse_indirect",
|
||||
"denoising_glossy_direct", "denoising_glossy_indirect",
|
||||
"denoising_transmission_direct", "denoising_transmission_indirect")
|
||||
if any(getattr(crl, option) for option in clean_options):
|
||||
yield ("Denoising Clean", "RGB", 'COLOR')
|
||||
|
||||
# Custom AOV passes.
|
||||
for aov in srl.aovs:
|
||||
if aov.type == 'VALUE':
|
||||
yield (aov.name, "X", 'VALUE')
|
||||
else:
|
||||
yield (aov.name, "RGB", 'COLOR')
|
||||
yield (aov.name, "RGBA", 'COLOR')
|
||||
|
||||
|
||||
def register_passes(engine, scene, view_layer):
|
||||
|
@@ -40,10 +40,10 @@ class AddPresetIntegrator(AddPresetBase, Operator):
|
||||
"cycles.transparent_max_bounces",
|
||||
"cycles.caustics_reflective",
|
||||
"cycles.caustics_refractive",
|
||||
"cycles.blur_glossy",
|
||||
"cycles.use_fast_gi",
|
||||
"cycles.ao_bounces",
|
||||
"cycles.ao_bounces_render",
|
||||
"cycles.blur_glossy"
|
||||
"cycles.use_fast_gi"
|
||||
"cycles.ao_bounces"
|
||||
"cycles.ao_bounces_render"
|
||||
]
|
||||
|
||||
preset_subdir = "cycles/integrator"
|
||||
@@ -60,48 +60,32 @@ class AddPresetSampling(AddPresetBase, Operator):
|
||||
]
|
||||
|
||||
preset_values = [
|
||||
"cycles.use_adaptive_sampling",
|
||||
"cycles.samples",
|
||||
"cycles.adaptive_threshold",
|
||||
"cycles.adaptive_min_samples",
|
||||
"cycles.time_limit",
|
||||
"cycles.use_denoising",
|
||||
"cycles.denoiser",
|
||||
"cycles.denoising_input_passes",
|
||||
"cycles.denoising_prefilter",
|
||||
"cycles.preview_samples",
|
||||
"cycles.aa_samples",
|
||||
"cycles.preview_aa_samples",
|
||||
"cycles.diffuse_samples",
|
||||
"cycles.glossy_samples",
|
||||
"cycles.transmission_samples",
|
||||
"cycles.ao_samples",
|
||||
"cycles.mesh_light_samples",
|
||||
"cycles.subsurface_samples",
|
||||
"cycles.volume_samples",
|
||||
"cycles.use_square_samples",
|
||||
"cycles.progressive",
|
||||
"cycles.seed",
|
||||
"cycles.sample_clamp_direct",
|
||||
"cycles.sample_clamp_indirect",
|
||||
"cycles.sample_all_lights_direct",
|
||||
"cycles.sample_all_lights_indirect",
|
||||
]
|
||||
|
||||
preset_subdir = "cycles/sampling"
|
||||
|
||||
|
||||
class AddPresetViewportSampling(AddPresetBase, Operator):
|
||||
'''Add a Viewport Sampling Preset'''
|
||||
bl_idname = "render.cycles_viewport_sampling_preset_add"
|
||||
bl_label = "Add Viewport Sampling Preset"
|
||||
preset_menu = "CYCLES_PT_viewport_sampling_presets"
|
||||
|
||||
preset_defines = [
|
||||
"cycles = bpy.context.scene.cycles"
|
||||
]
|
||||
|
||||
preset_values = [
|
||||
"cycles.use_preview_adaptive_sampling",
|
||||
"cycles.preview_samples",
|
||||
"cycles.preview_adaptive_threshold",
|
||||
"cycles.preview_adaptive_min_samples",
|
||||
"cycles.use_preview_denoising",
|
||||
"cycles.preview_denoiser",
|
||||
"cycles.preview_denoising_input_passes",
|
||||
"cycles.preview_denoising_prefilter",
|
||||
"cycles.preview_denoising_start_sample",
|
||||
]
|
||||
|
||||
preset_subdir = "cycles/viewport_sampling"
|
||||
|
||||
classes = (
|
||||
AddPresetIntegrator,
|
||||
AddPresetSampling,
|
||||
AddPresetViewportSampling,
|
||||
)
|
||||
|
||||
|
||||
|
@@ -39,6 +39,11 @@ enum_devices = (
|
||||
('GPU', "GPU Compute", "Use GPU compute device for rendering, configured in the system tab in the user preferences"),
|
||||
)
|
||||
|
||||
from _cycles import with_network
|
||||
if with_network:
|
||||
enum_devices += (('NETWORK', "Networked Device", "Use networked device for rendering"),)
|
||||
del with_network
|
||||
|
||||
enum_feature_set = (
|
||||
('SUPPORTED', "Supported", "Only use finished and supported features"),
|
||||
('EXPERIMENTAL', "Experimental", "Use experimental and incomplete features that might be broken or change in the future", 'ERROR', 1),
|
||||
@@ -79,6 +84,15 @@ enum_curve_shape = (
|
||||
('THICK', "3D Curves", "Render hair as 3D curve, for accurate results when viewing hair close up"),
|
||||
)
|
||||
|
||||
enum_tile_order = (
|
||||
('CENTER', "Center", "Render from center to the edges"),
|
||||
('RIGHT_TO_LEFT', "Right to Left", "Render from right to left"),
|
||||
('LEFT_TO_RIGHT', "Left to Right", "Render from left to right"),
|
||||
('TOP_TO_BOTTOM', "Top to Bottom", "Render from top to bottom"),
|
||||
('BOTTOM_TO_TOP', "Bottom to Top", "Render from bottom to top"),
|
||||
('HILBERT_SPIRAL', "Hilbert Spiral", "Render in a Hilbert Spiral"),
|
||||
)
|
||||
|
||||
enum_use_layer_samples = (
|
||||
('USE', "Use", "Per render layer number of samples override scene samples"),
|
||||
('BOUNDED', "Bounded", "Bound per render layer number of samples by global samples"),
|
||||
@@ -86,8 +100,14 @@ enum_use_layer_samples = (
|
||||
)
|
||||
|
||||
enum_sampling_pattern = (
|
||||
('SOBOL', "Sobol", "Use Sobol random sampling pattern", 0),
|
||||
('PROGRESSIVE_MULTI_JITTER', "Progressive Multi-Jitter", "Use Progressive Multi-Jitter random sampling pattern", 1),
|
||||
('SOBOL', "Sobol", "Use Sobol random sampling pattern"),
|
||||
('CORRELATED_MUTI_JITTER', "Correlated Multi-Jitter", "Use Correlated Multi-Jitter random sampling pattern"),
|
||||
('PROGRESSIVE_MUTI_JITTER', "Progressive Multi-Jitter", "Use Progressive Multi-Jitter random sampling pattern"),
|
||||
)
|
||||
|
||||
enum_integrator = (
|
||||
('BRANCHED_PATH', "Branched Path Tracing", "Path tracing integrator that branches on the first bounce, giving more control over the number of light and material samples"),
|
||||
('PATH', "Path Tracing", "Pure path tracing integrator"),
|
||||
)
|
||||
|
||||
enum_volume_sampling = (
|
||||
@@ -111,7 +131,7 @@ enum_device_type = (
|
||||
('CPU', "CPU", "CPU", 0),
|
||||
('CUDA', "CUDA", "CUDA", 1),
|
||||
('OPTIX', "OptiX", "OptiX", 3),
|
||||
("HIP", "HIP", "HIP", 4)
|
||||
('OPENCL', "OpenCL", "OpenCL", 2)
|
||||
)
|
||||
|
||||
enum_texture_limit = (
|
||||
@@ -125,50 +145,38 @@ enum_texture_limit = (
|
||||
('8192', "8192", "Limit texture size to 8192 pixels", 7),
|
||||
)
|
||||
|
||||
enum_fast_gi_method = (
|
||||
('REPLACE', "Replace", "Replace global illumination with ambient occlusion after a specified number of bounces"),
|
||||
('ADD', "Add", "Add ambient occlusion to diffuse surfaces"),
|
||||
)
|
||||
|
||||
# NOTE: Identifiers are expected to be an upper case version of identifiers from `Pass::get_type_enum()`
|
||||
enum_view3d_shading_render_pass = (
|
||||
('', "General", ""),
|
||||
|
||||
('COMBINED', "Combined", "Show the Combined Render pass"),
|
||||
('EMISSION', "Emission", "Show the Emission render pass"),
|
||||
('BACKGROUND', "Background", "Show the Background render pass"),
|
||||
('AO', "Ambient Occlusion", "Show the Ambient Occlusion render pass"),
|
||||
('SHADOW', "Shadow", "Show the Shadow render pass"),
|
||||
('SHADOW_CATCHER', "Shadow Catcher", "Show the Shadow Catcher render pass"),
|
||||
('COMBINED', "Combined", "Show the Combined Render pass", 1),
|
||||
('EMISSION', "Emission", "Show the Emission render pass", 33),
|
||||
('BACKGROUND', "Background", "Show the Background render pass", 34),
|
||||
('AO', "Ambient Occlusion", "Show the Ambient Occlusion render pass", 35),
|
||||
|
||||
('', "Light", ""),
|
||||
|
||||
('DIFFUSE_DIRECT', "Diffuse Direct", "Show the Diffuse Direct render pass"),
|
||||
('DIFFUSE_INDIRECT', "Diffuse Indirect", "Show the Diffuse Indirect render pass"),
|
||||
('DIFFUSE_COLOR', "Diffuse Color", "Show the Diffuse Color render pass"),
|
||||
('DIFFUSE_DIRECT', "Diffuse Direct", "Show the Diffuse Direct render pass", 38),
|
||||
('DIFFUSE_INDIRECT', "Diffuse Indirect", "Show the Diffuse Indirect render pass", 39),
|
||||
('DIFFUSE_COLOR', "Diffuse Color", "Show the Diffuse Color render pass", 40),
|
||||
|
||||
('GLOSSY_DIRECT', "Glossy Direct", "Show the Glossy Direct render pass"),
|
||||
('GLOSSY_INDIRECT', "Glossy Indirect", "Show the Glossy Indirect render pass"),
|
||||
('GLOSSY_COLOR', "Glossy Color", "Show the Glossy Color render pass"),
|
||||
('GLOSSY_DIRECT', "Glossy Direct", "Show the Glossy Direct render pass", 41),
|
||||
('GLOSSY_INDIRECT', "Glossy Indirect", "Show the Glossy Indirect render pass", 42),
|
||||
('GLOSSY_COLOR', "Glossy Color", "Show the Glossy Color render pass", 43),
|
||||
|
||||
('', "", ""),
|
||||
|
||||
('TRANSMISSION_DIRECT', "Transmission Direct", "Show the Transmission Direct render pass"),
|
||||
('TRANSMISSION_INDIRECT', "Transmission Indirect", "Show the Transmission Indirect render pass"),
|
||||
('TRANSMISSION_COLOR', "Transmission Color", "Show the Transmission Color render pass"),
|
||||
('TRANSMISSION_DIRECT', "Transmission Direct", "Show the Transmission Direct render pass", 44),
|
||||
('TRANSMISSION_INDIRECT', "Transmission Indirect", "Show the Transmission Indirect render pass", 45),
|
||||
('TRANSMISSION_COLOR', "Transmission Color", "Show the Transmission Color render pass", 46),
|
||||
|
||||
('VOLUME_DIRECT', "Volume Direct", "Show the Volume Direct render pass"),
|
||||
('VOLUME_INDIRECT', "Volume Indirect", "Show the Volume Indirect render pass"),
|
||||
('VOLUME_DIRECT', "Volume Direct", "Show the Volume Direct render pass", 50),
|
||||
('VOLUME_INDIRECT', "Volume Indirect", "Show the Volume Indirect render pass", 51),
|
||||
|
||||
('', "Data", ""),
|
||||
|
||||
('POSITION', "Position", "Show the Position render pass"),
|
||||
('NORMAL', "Normal", "Show the Normal render pass"),
|
||||
('UV', "UV", "Show the UV render pass"),
|
||||
('MIST', "Mist", "Show the Mist render pass"),
|
||||
('DENOISING_ALBEDO', "Denoising Albedo", "Albedo pass used by denoiser"),
|
||||
('DENOISING_NORMAL', "Denoising Normal", "Normal pass used by denoiser"),
|
||||
('SAMPLE_COUNT', "Sample Count", "Per-pixel number of samples"),
|
||||
('NORMAL', "Normal", "Show the Normal render pass", 3),
|
||||
('UV', "UV", "Show the UV render pass", 4),
|
||||
('MIST', "Mist", "Show the Mist render pass", 32),
|
||||
)
|
||||
|
||||
|
||||
@@ -200,23 +208,18 @@ def enum_preview_denoiser(self, context):
|
||||
|
||||
|
||||
def enum_denoiser(self, context):
|
||||
items = []
|
||||
items = [('NLM', "NLM", "Cycles native non-local means denoiser, running on any compute device", 1)]
|
||||
items += enum_optix_denoiser(self, context)
|
||||
items += enum_openimagedenoise_denoiser(self, context)
|
||||
return items
|
||||
|
||||
|
||||
enum_denoising_input_passes = (
|
||||
('RGB', "None", "Don't use utility passes for denoising", 1),
|
||||
('RGB_ALBEDO', "Albedo", "Use albedo pass for denoising", 2),
|
||||
('RGB_ALBEDO_NORMAL', "Albedo and Normal", "Use albedo and normal passes for denoising", 3),
|
||||
('RGB', "Color", "Use only color as input", 1),
|
||||
('RGB_ALBEDO', "Color + Albedo", "Use color and albedo data as input", 2),
|
||||
('RGB_ALBEDO_NORMAL', "Color + Albedo + Normal", "Use color, albedo and normal data as input", 3),
|
||||
)
|
||||
|
||||
enum_denoising_prefilter = (
|
||||
('NONE', "None", "No prefiltering, use when guiding passes are noise-free", 1),
|
||||
('FAST', "Fast", "Denoise color and guiding passes together. Improves quality when guiding passes are noisy using least amount of extra processing time", 2),
|
||||
('ACCURATE', "Accurate", "Prefilter noisy guiding passes before denoising color. Improves quality when guiding passes are noisy using extra processing time", 3),
|
||||
)
|
||||
|
||||
def update_render_passes(self, context):
|
||||
scene = context.scene
|
||||
@@ -249,6 +252,13 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
|
||||
description="Use Open Shading Language (CPU rendering only)",
|
||||
)
|
||||
|
||||
progressive: EnumProperty(
|
||||
name="Integrator",
|
||||
description="Method to sample lights and materials",
|
||||
items=enum_integrator,
|
||||
default='PATH',
|
||||
)
|
||||
|
||||
preview_pause: BoolProperty(
|
||||
name="Pause Preview",
|
||||
description="Pause all viewport preview renders",
|
||||
@@ -258,106 +268,110 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
|
||||
use_denoising: BoolProperty(
|
||||
name="Use Denoising",
|
||||
description="Denoise the rendered image",
|
||||
default=True,
|
||||
default=False,
|
||||
update=update_render_passes,
|
||||
)
|
||||
denoiser: EnumProperty(
|
||||
name="Denoiser",
|
||||
description="Denoise the image with the selected denoiser. "
|
||||
"For denoising the image after rendering",
|
||||
items=enum_denoiser,
|
||||
default=4, # Use integer to avoid error in builds without OpenImageDenoise.
|
||||
update=update_render_passes,
|
||||
)
|
||||
denoising_prefilter: EnumProperty(
|
||||
name="Denoising Prefilter",
|
||||
description="Prefilter noisy guiding (albedo and normal) passes to improve denoising quality when using OpenImageDenoiser",
|
||||
items=enum_denoising_prefilter,
|
||||
default='ACCURATE',
|
||||
)
|
||||
denoising_input_passes: EnumProperty(
|
||||
name="Denoising Input Passes",
|
||||
description="Passes used by the denoiser to distinguish noise from shader and geometry detail",
|
||||
items=enum_denoising_input_passes,
|
||||
default='RGB_ALBEDO_NORMAL',
|
||||
)
|
||||
|
||||
use_preview_denoising: BoolProperty(
|
||||
name="Use Viewport Denoising",
|
||||
description="Denoise the image in the 3D viewport",
|
||||
default=False,
|
||||
)
|
||||
|
||||
denoiser: EnumProperty(
|
||||
name="Denoiser",
|
||||
description="Denoise the image with the selected denoiser. "
|
||||
"For denoising the image after rendering, denoising data render passes "
|
||||
"also adapt to the selected denoiser",
|
||||
items=enum_denoiser,
|
||||
default=1,
|
||||
update=update_render_passes,
|
||||
)
|
||||
preview_denoiser: EnumProperty(
|
||||
name="Viewport Denoiser",
|
||||
description="Denoise the image after each preview update with the selected denoiser",
|
||||
items=enum_preview_denoiser,
|
||||
default=0,
|
||||
)
|
||||
preview_denoising_prefilter: EnumProperty(
|
||||
name="Viewport Denoising Prefilter",
|
||||
description="Prefilter noisy guiding (albedo and normal) passes to improve denoising quality when using OpenImageDenoiser",
|
||||
items=enum_denoising_prefilter,
|
||||
default='FAST',
|
||||
)
|
||||
preview_denoising_input_passes: EnumProperty(
|
||||
name="Viewport Denoising Input Passes",
|
||||
description="Passes used by the denoiser to distinguish noise from shader and geometry detail",
|
||||
items=enum_denoising_input_passes,
|
||||
default='RGB_ALBEDO',
|
||||
)
|
||||
preview_denoising_start_sample: IntProperty(
|
||||
name="Start Denoising",
|
||||
description="Sample to start denoising the preview at",
|
||||
min=0, max=(1 << 24),
|
||||
default=1,
|
||||
|
||||
use_square_samples: BoolProperty(
|
||||
name="Square Samples",
|
||||
description="Square sampling values for easier artist control",
|
||||
default=False,
|
||||
)
|
||||
|
||||
samples: IntProperty(
|
||||
name="Samples",
|
||||
description="Number of samples to render for each pixel",
|
||||
min=1, max=(1 << 24),
|
||||
default=4096,
|
||||
default=128,
|
||||
)
|
||||
preview_samples: IntProperty(
|
||||
name="Viewport Samples",
|
||||
description="Number of samples to render in the viewport, unlimited if 0",
|
||||
min=0, max=(1 << 24),
|
||||
default=1024,
|
||||
default=32,
|
||||
)
|
||||
aa_samples: IntProperty(
|
||||
name="AA Samples",
|
||||
description="Number of antialiasing samples to render for each pixel",
|
||||
min=1, max=2097151,
|
||||
default=128,
|
||||
)
|
||||
preview_aa_samples: IntProperty(
|
||||
name="AA Samples",
|
||||
description="Number of antialiasing samples to render in the viewport, unlimited if 0",
|
||||
min=0, max=2097151,
|
||||
default=32,
|
||||
)
|
||||
|
||||
time_limit: FloatProperty(
|
||||
name="Time Limit",
|
||||
description="Limit the render time (excluding synchronization time)."
|
||||
"Zero disables the limit",
|
||||
min=0.0,
|
||||
default=0.0,
|
||||
step=100.0,
|
||||
unit='TIME_ABSOLUTE',
|
||||
diffuse_samples: IntProperty(
|
||||
name="Diffuse Samples",
|
||||
description="Number of diffuse bounce samples to render for each AA sample",
|
||||
min=1, max=1024,
|
||||
default=1,
|
||||
)
|
||||
glossy_samples: IntProperty(
|
||||
name="Glossy Samples",
|
||||
description="Number of glossy bounce samples to render for each AA sample",
|
||||
min=1, max=1024,
|
||||
default=1,
|
||||
)
|
||||
transmission_samples: IntProperty(
|
||||
name="Transmission Samples",
|
||||
description="Number of transmission bounce samples to render for each AA sample",
|
||||
min=1, max=1024,
|
||||
default=1,
|
||||
)
|
||||
ao_samples: IntProperty(
|
||||
name="Ambient Occlusion Samples",
|
||||
description="Number of ambient occlusion samples to render for each AA sample",
|
||||
min=1, max=1024,
|
||||
default=1,
|
||||
)
|
||||
mesh_light_samples: IntProperty(
|
||||
name="Mesh Light Samples",
|
||||
description="Number of mesh emission light samples to render for each AA sample",
|
||||
min=1, max=1024,
|
||||
default=1,
|
||||
)
|
||||
subsurface_samples: IntProperty(
|
||||
name="Subsurface Samples",
|
||||
description="Number of subsurface scattering samples to render for each AA sample",
|
||||
min=1, max=1024,
|
||||
default=1,
|
||||
)
|
||||
volume_samples: IntProperty(
|
||||
name="Volume Samples",
|
||||
description="Number of volume scattering samples to render for each AA sample",
|
||||
min=1, max=1024,
|
||||
default=1,
|
||||
)
|
||||
|
||||
sampling_pattern: EnumProperty(
|
||||
name="Sampling Pattern",
|
||||
description="Random sampling pattern used by the integrator. When adaptive sampling is enabled, Progressive Multi-Jitter is always used instead of Sobol",
|
||||
description="Random sampling pattern used by the integrator",
|
||||
items=enum_sampling_pattern,
|
||||
default='PROGRESSIVE_MULTI_JITTER',
|
||||
)
|
||||
|
||||
scrambling_distance: FloatProperty(
|
||||
name="Scrambling Distance",
|
||||
default=1.0,
|
||||
min=0.0, max=1.0,
|
||||
description="Lower values give faster rendering with GPU rendering and less noise with all devices at the cost of possible artifacts if set too low. Only works when not using adaptive sampling",
|
||||
)
|
||||
preview_scrambling_distance: BoolProperty(
|
||||
name="Scrambling Distance viewport",
|
||||
default=False,
|
||||
description="Uses the Scrambling Distance value for the viewport. Faster but may flicker",
|
||||
)
|
||||
|
||||
adaptive_scrambling_distance: BoolProperty(
|
||||
name="Adaptive Scrambling Distance",
|
||||
default=False,
|
||||
description="Uses a formula to adapt the scrambling distance strength based on the sample count",
|
||||
default='SOBOL',
|
||||
)
|
||||
|
||||
use_layer_samples: EnumProperty(
|
||||
@@ -367,6 +381,17 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
|
||||
default='USE',
|
||||
)
|
||||
|
||||
sample_all_lights_direct: BoolProperty(
|
||||
name="Sample All Direct Lights",
|
||||
description="Sample all lights (for direct samples), rather than randomly picking one",
|
||||
default=True,
|
||||
)
|
||||
|
||||
sample_all_lights_indirect: BoolProperty(
|
||||
name="Sample All Indirect Lights",
|
||||
description="Sample all lights (for indirect samples), rather than randomly picking one",
|
||||
default=True,
|
||||
)
|
||||
light_sampling_threshold: FloatProperty(
|
||||
name="Light Sampling Threshold",
|
||||
description="Probabilistically terminate light samples when the light contribution is below this threshold (more noise but faster rendering). "
|
||||
@@ -378,39 +403,19 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
|
||||
use_adaptive_sampling: BoolProperty(
|
||||
name="Use Adaptive Sampling",
|
||||
description="Automatically reduce the number of samples per pixel based on estimated noise level",
|
||||
default=True,
|
||||
default=False,
|
||||
)
|
||||
|
||||
adaptive_threshold: FloatProperty(
|
||||
name="Adaptive Sampling Threshold",
|
||||
description="Noise level step to stop sampling at, lower values reduce noise at the cost of render time. Zero for automatic setting based on number of AA samples",
|
||||
min=0.0, max=1.0,
|
||||
soft_min=0.001,
|
||||
default=0.01,
|
||||
default=0.0,
|
||||
precision=4,
|
||||
)
|
||||
adaptive_min_samples: IntProperty(
|
||||
name="Adaptive Min Samples",
|
||||
description="Minimum AA samples for adaptive sampling, to discover noisy features before stopping sampling. Zero for automatic setting based on noise threshold",
|
||||
min=0, max=4096,
|
||||
default=0,
|
||||
)
|
||||
|
||||
use_preview_adaptive_sampling: BoolProperty(
|
||||
name="Use Adaptive Sampling",
|
||||
description="Automatically reduce the number of samples per pixel based on estimated noise level, for viewport renders",
|
||||
default=True,
|
||||
)
|
||||
preview_adaptive_threshold: FloatProperty(
|
||||
name="Adaptive Sampling Threshold",
|
||||
description="Noise level step to stop sampling at, lower values reduce noise at the cost of render time. Zero for automatic setting based on number of AA samples, for viewport renders",
|
||||
min=0.0, max=1.0,
|
||||
soft_min=0.001,
|
||||
default=0.1,
|
||||
precision=4,
|
||||
)
|
||||
preview_adaptive_min_samples: IntProperty(
|
||||
name="Adaptive Min Samples",
|
||||
description="Minimum AA samples for adaptive sampling, to discover noisy features before stopping sampling. Zero for automatic setting based on noise threshold, for viewport renders",
|
||||
description="Minimum AA samples for adaptive sampling, to discover noisy features before stopping sampling. Zero for automatic setting based on number of AA samples",
|
||||
min=0, max=4096,
|
||||
default=0,
|
||||
)
|
||||
@@ -627,6 +632,53 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
|
||||
default=10.0,
|
||||
)
|
||||
|
||||
debug_tile_size: IntProperty(
|
||||
name="Tile Size",
|
||||
description="",
|
||||
min=1, max=4096,
|
||||
default=1024,
|
||||
)
|
||||
|
||||
preview_start_resolution: IntProperty(
|
||||
name="Start Resolution",
|
||||
description="Resolution to start rendering preview at, "
|
||||
"progressively increasing it to the full viewport size",
|
||||
min=8, max=16384,
|
||||
default=64,
|
||||
subtype='PIXEL'
|
||||
)
|
||||
preview_denoising_start_sample: IntProperty(
|
||||
name="Start Denoising",
|
||||
description="Sample to start denoising the preview at",
|
||||
min=0, max=(1 << 24),
|
||||
default=1,
|
||||
)
|
||||
preview_denoising_input_passes: EnumProperty(
|
||||
name="Viewport Input Passes",
|
||||
description="Passes used by the denoiser to distinguish noise from shader and geometry detail",
|
||||
items=enum_denoising_input_passes,
|
||||
default='RGB_ALBEDO',
|
||||
)
|
||||
|
||||
debug_reset_timeout: FloatProperty(
|
||||
name="Reset timeout",
|
||||
description="",
|
||||
min=0.01, max=10.0,
|
||||
default=0.1,
|
||||
)
|
||||
debug_cancel_timeout: FloatProperty(
|
||||
name="Cancel timeout",
|
||||
description="",
|
||||
min=0.01, max=10.0,
|
||||
default=0.1,
|
||||
)
|
||||
debug_text_timeout: FloatProperty(
|
||||
name="Text timeout",
|
||||
description="",
|
||||
min=0.01, max=10.0,
|
||||
default=1.0,
|
||||
)
|
||||
|
||||
debug_bvh_type: EnumProperty(
|
||||
name="Viewport BVH Type",
|
||||
description="Choose between faster updates, or faster render",
|
||||
@@ -649,24 +701,38 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
|
||||
default=0,
|
||||
min=0, max=16,
|
||||
)
|
||||
tile_order: EnumProperty(
|
||||
name="Tile Order",
|
||||
description="Tile order for rendering",
|
||||
items=enum_tile_order,
|
||||
default='HILBERT_SPIRAL',
|
||||
options=set(), # Not animatable!
|
||||
)
|
||||
use_progressive_refine: BoolProperty(
|
||||
name="Progressive Refine",
|
||||
description="Instead of rendering each tile until it is finished, "
|
||||
"refine the whole image progressively "
|
||||
"(this renders somewhat slower, "
|
||||
"but time can be saved by manually stopping the render when the noise is low enough)",
|
||||
default=False,
|
||||
)
|
||||
|
||||
bake_type: EnumProperty(
|
||||
name="Bake Type",
|
||||
default='COMBINED',
|
||||
description="Type of pass to bake",
|
||||
items=(
|
||||
('COMBINED', "Combined", "", 0),
|
||||
('AO', "Ambient Occlusion", "", 1),
|
||||
('SHADOW', "Shadow", "", 2),
|
||||
('POSITION', "Position", "", 11),
|
||||
('NORMAL', "Normal", "", 3),
|
||||
('UV', "UV", "", 4),
|
||||
('ROUGHNESS', "Roughness", "", 5),
|
||||
('EMIT', "Emit", "", 6),
|
||||
('ENVIRONMENT', "Environment", "", 7),
|
||||
('DIFFUSE', "Diffuse", "", 8),
|
||||
('GLOSSY', "Glossy", "", 9),
|
||||
('TRANSMISSION', "Transmission", "", 10),
|
||||
('COMBINED', "Combined", ""),
|
||||
('AO', "Ambient Occlusion", ""),
|
||||
('SHADOW', "Shadow", ""),
|
||||
('NORMAL', "Normal", ""),
|
||||
('UV', "UV", ""),
|
||||
('ROUGHNESS', "Roughness", ""),
|
||||
('EMIT', "Emit", ""),
|
||||
('ENVIRONMENT', "Environment", ""),
|
||||
('DIFFUSE', "Diffuse", ""),
|
||||
('GLOSSY', "Glossy", ""),
|
||||
('TRANSMISSION', "Transmission", ""),
|
||||
),
|
||||
)
|
||||
|
||||
@@ -747,14 +813,6 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
|
||||
description="Approximate diffuse indirect light with background tinted ambient occlusion. This provides fast alternative to full global illumination, for interactive viewport rendering or final renders with reduced quality",
|
||||
default=False,
|
||||
)
|
||||
|
||||
fast_gi_method: EnumProperty(
|
||||
name="Fast GI Method",
|
||||
default='REPLACE',
|
||||
description="Fast GI approximation method",
|
||||
items=enum_fast_gi_method
|
||||
)
|
||||
|
||||
ao_bounces: IntProperty(
|
||||
name="AO Bounces",
|
||||
default=1,
|
||||
@@ -769,18 +827,6 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
|
||||
min=0, max=1024,
|
||||
)
|
||||
|
||||
use_auto_tile: BoolProperty(
|
||||
name="Auto Tiles",
|
||||
description="Automatically render high resolution images in tiles to reduce memory usage, using the specified tile size. Tiles are cached to disk while rendering to save memory",
|
||||
default=True,
|
||||
)
|
||||
tile_size: IntProperty(
|
||||
name="Tile Size",
|
||||
default=2048,
|
||||
description="",
|
||||
min=8, max=16384,
|
||||
)
|
||||
|
||||
# Various fine-tuning debug flags
|
||||
|
||||
def _devices_update_callback(self, context):
|
||||
@@ -798,13 +844,45 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
|
||||
items=enum_bvh_layouts,
|
||||
default='EMBREE',
|
||||
)
|
||||
debug_use_cpu_split_kernel: BoolProperty(name="Split Kernel", default=False)
|
||||
|
||||
debug_use_cuda_adaptive_compile: BoolProperty(name="Adaptive Compile", default=False)
|
||||
debug_use_cuda_split_kernel: BoolProperty(name="Split Kernel", default=False)
|
||||
|
||||
debug_use_optix_debug: BoolProperty(
|
||||
name="OptiX Module Debug",
|
||||
description="Load OptiX module in debug mode: lower logging verbosity level, enable validations, and lower optimization level",
|
||||
default=False
|
||||
debug_optix_cuda_streams: IntProperty(name="CUDA Streams", default=1, min=1)
|
||||
debug_optix_curves_api: BoolProperty(name="Native OptiX Curve Primitive", default=False)
|
||||
|
||||
debug_opencl_kernel_type: EnumProperty(
|
||||
name="OpenCL Kernel Type",
|
||||
default='DEFAULT',
|
||||
items=(
|
||||
('DEFAULT', "Default", ""),
|
||||
('MEGA', "Mega", ""),
|
||||
('SPLIT', "Split", ""),
|
||||
),
|
||||
update=CyclesRenderSettings._devices_update_callback
|
||||
)
|
||||
|
||||
debug_opencl_device_type: EnumProperty(
|
||||
name="OpenCL Device Type",
|
||||
default='ALL',
|
||||
items=(
|
||||
('NONE', "None", ""),
|
||||
('ALL', "All", ""),
|
||||
('DEFAULT', "Default", ""),
|
||||
('CPU', "CPU", ""),
|
||||
('GPU', "GPU", ""),
|
||||
('ACCELERATOR', "Accelerator", ""),
|
||||
),
|
||||
update=CyclesRenderSettings._devices_update_callback
|
||||
)
|
||||
|
||||
debug_use_opencl_debug: BoolProperty(name="Debug OpenCL", default=False)
|
||||
|
||||
debug_opencl_mem_limit: IntProperty(
|
||||
name="Memory limit",
|
||||
default=0,
|
||||
description="Artificial limit on OpenCL memory usage in MB (0 to disable limit)"
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@@ -953,6 +1031,12 @@ class CyclesLightSettings(bpy.types.PropertyGroup):
|
||||
description="Light casts shadows",
|
||||
default=True,
|
||||
)
|
||||
samples: IntProperty(
|
||||
name="Samples",
|
||||
description="Number of light samples to render for each AA sample",
|
||||
min=1, max=10000,
|
||||
default=1,
|
||||
)
|
||||
max_bounces: IntProperty(
|
||||
name="Max Bounces",
|
||||
description="Maximum number of bounces the light will contribute to the render",
|
||||
@@ -1000,6 +1084,12 @@ class CyclesWorldSettings(bpy.types.PropertyGroup):
|
||||
min=4, max=8192,
|
||||
default=1024,
|
||||
)
|
||||
samples: IntProperty(
|
||||
name="Samples",
|
||||
description="Number of light samples to render for each AA sample",
|
||||
min=1, max=10000,
|
||||
default=1,
|
||||
)
|
||||
max_bounces: IntProperty(
|
||||
name="Max Bounces",
|
||||
description="Maximum number of bounces the background light will contribute to the render",
|
||||
@@ -1228,6 +1318,12 @@ class CyclesCurveRenderSettings(bpy.types.PropertyGroup):
|
||||
|
||||
class CyclesRenderLayerSettings(bpy.types.PropertyGroup):
|
||||
|
||||
pass_debug_render_time: BoolProperty(
|
||||
name="Debug Render Time",
|
||||
description="Render time in milliseconds per sample and pixel",
|
||||
default=False,
|
||||
update=update_render_passes,
|
||||
)
|
||||
pass_debug_sample_count: BoolProperty(
|
||||
name="Debug Sample Count",
|
||||
description="Number of samples/camera rays per pixel",
|
||||
@@ -1247,25 +1343,91 @@ class CyclesRenderLayerSettings(bpy.types.PropertyGroup):
|
||||
update=update_render_passes,
|
||||
)
|
||||
|
||||
use_pass_shadow_catcher: BoolProperty(
|
||||
name="Shadow Catcher",
|
||||
description="Pass containing shadows and light which is to be multiplied into backdrop",
|
||||
default=False,
|
||||
update=update_render_passes,
|
||||
)
|
||||
|
||||
use_denoising: BoolProperty(
|
||||
name="Use Denoising",
|
||||
description="Denoise the rendered image",
|
||||
default=True,
|
||||
update=update_render_passes,
|
||||
)
|
||||
denoising_diffuse_direct: BoolProperty(
|
||||
name="Diffuse Direct",
|
||||
description="Denoise the direct diffuse lighting",
|
||||
default=True,
|
||||
)
|
||||
denoising_diffuse_indirect: BoolProperty(
|
||||
name="Diffuse Indirect",
|
||||
description="Denoise the indirect diffuse lighting",
|
||||
default=True,
|
||||
)
|
||||
denoising_glossy_direct: BoolProperty(
|
||||
name="Glossy Direct",
|
||||
description="Denoise the direct glossy lighting",
|
||||
default=True,
|
||||
)
|
||||
denoising_glossy_indirect: BoolProperty(
|
||||
name="Glossy Indirect",
|
||||
description="Denoise the indirect glossy lighting",
|
||||
default=True,
|
||||
)
|
||||
denoising_transmission_direct: BoolProperty(
|
||||
name="Transmission Direct",
|
||||
description="Denoise the direct transmission lighting",
|
||||
default=True,
|
||||
)
|
||||
denoising_transmission_indirect: BoolProperty(
|
||||
name="Transmission Indirect",
|
||||
description="Denoise the indirect transmission lighting",
|
||||
default=True,
|
||||
)
|
||||
denoising_strength: FloatProperty(
|
||||
name="Denoising Strength",
|
||||
description="Controls neighbor pixel weighting for the denoising filter (lower values preserve more detail, but aren't as smooth)",
|
||||
min=0.0, max=1.0,
|
||||
default=0.5,
|
||||
)
|
||||
denoising_feature_strength: FloatProperty(
|
||||
name="Denoising Feature Strength",
|
||||
description="Controls removal of noisy image feature passes (lower values preserve more detail, but aren't as smooth)",
|
||||
min=0.0, max=1.0,
|
||||
default=0.5,
|
||||
)
|
||||
denoising_radius: IntProperty(
|
||||
name="Denoising Radius",
|
||||
description="Size of the image area that's used to denoise a pixel (higher values are smoother, but might lose detail and are slower)",
|
||||
min=1, max=25,
|
||||
default=8,
|
||||
subtype="PIXEL",
|
||||
)
|
||||
denoising_relative_pca: BoolProperty(
|
||||
name="Relative Filter",
|
||||
description="When removing pixels that don't carry information, use a relative threshold instead of an absolute one (can help to reduce artifacts, but might cause detail loss around edges)",
|
||||
default=False,
|
||||
)
|
||||
denoising_store_passes: BoolProperty(
|
||||
name="Store Denoising Passes",
|
||||
description="Store the denoising feature passes and the noisy image. The passes adapt to the denoiser selected for rendering",
|
||||
default=False,
|
||||
update=update_render_passes,
|
||||
)
|
||||
denoising_neighbor_frames: IntProperty(
|
||||
name="Neighbor Frames",
|
||||
description="Number of neighboring frames to use for denoising animations (more frames produce smoother results at the cost of performance)",
|
||||
min=0, max=7,
|
||||
default=0,
|
||||
)
|
||||
|
||||
denoising_optix_input_passes: EnumProperty(
|
||||
name="Input Passes",
|
||||
description="Passes used by the denoiser to distinguish noise from shader and geometry detail",
|
||||
items=enum_denoising_input_passes,
|
||||
default='RGB_ALBEDO',
|
||||
)
|
||||
denoising_openimagedenoise_input_passes: EnumProperty(
|
||||
name="Input Passes",
|
||||
description="Passes used by the denoiser to distinguish noise from shader and geometry detail",
|
||||
items=enum_denoising_input_passes,
|
||||
default='RGB_ALBEDO_NORMAL',
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def register(cls):
|
||||
@@ -1292,16 +1454,14 @@ class CyclesPreferences(bpy.types.AddonPreferences):
|
||||
|
||||
def get_device_types(self, context):
|
||||
import _cycles
|
||||
has_cuda, has_optix, has_hip = _cycles.get_device_types()
|
||||
|
||||
has_cuda, has_optix, has_opencl = _cycles.get_device_types()
|
||||
list = [('NONE', "None", "Don't use compute device", 0)]
|
||||
if has_cuda:
|
||||
list.append(('CUDA', "CUDA", "Use CUDA for GPU acceleration", 1))
|
||||
if has_optix:
|
||||
list.append(('OPTIX', "OptiX", "Use OptiX for GPU acceleration", 3))
|
||||
if has_hip:
|
||||
list.append(('HIP', "HIP", "Use HIP for GPU acceleration", 4))
|
||||
|
||||
if has_opencl:
|
||||
list.append(('OPENCL', "OpenCL", "Use OpenCL for GPU acceleration", 2))
|
||||
return list
|
||||
|
||||
compute_device_type: EnumProperty(
|
||||
@@ -1326,7 +1486,7 @@ class CyclesPreferences(bpy.types.AddonPreferences):
|
||||
|
||||
def update_device_entries(self, device_list):
|
||||
for device in device_list:
|
||||
if not device[1] in {'CUDA', 'OPTIX', 'CPU', 'HIP'}:
|
||||
if not device[1] in {'CUDA', 'OPTIX', 'OPENCL', 'CPU'}:
|
||||
continue
|
||||
# Try to find existing Device entry
|
||||
entry = self.find_existing_device_entry(device)
|
||||
@@ -1360,36 +1520,29 @@ class CyclesPreferences(bpy.types.AddonPreferences):
|
||||
elif entry.type == 'CPU':
|
||||
cpu_devices.append(entry)
|
||||
# Extend all GPU devices with CPU.
|
||||
if len(devices) and compute_device_type != 'CPU':
|
||||
if compute_device_type in {'CUDA', 'OPTIX', 'OPENCL'}:
|
||||
devices.extend(cpu_devices)
|
||||
return devices
|
||||
|
||||
# Refresh device list. This does not happen automatically on Blender
|
||||
# startup due to unstable OpenCL implementations that can cause crashes.
|
||||
def refresh_devices(self):
|
||||
# For backwards compatibility, only returns CUDA and OpenCL but still
|
||||
# refreshes all devices.
|
||||
def get_devices(self, compute_device_type=''):
|
||||
import _cycles
|
||||
# Ensure `self.devices` is not re-allocated when the second call to
|
||||
# get_devices_for_type is made, freeing items from the first list.
|
||||
for device_type in ('CUDA', 'OPTIX', 'HIP'):
|
||||
for device_type in ('CUDA', 'OPTIX', 'OPENCL'):
|
||||
self.update_device_entries(_cycles.available_devices(device_type))
|
||||
|
||||
# Deprecated: use refresh_devices instead.
|
||||
def get_devices(self, compute_device_type=''):
|
||||
self.refresh_devices()
|
||||
return None
|
||||
|
||||
def get_compute_device_type(self):
|
||||
if self.compute_device_type == '':
|
||||
return 'NONE'
|
||||
return self.compute_device_type
|
||||
cuda_devices = self.get_devices_for_type('CUDA')
|
||||
opencl_devices = self.get_devices_for_type('OPENCL')
|
||||
return cuda_devices, opencl_devices
|
||||
|
||||
def get_num_gpu_devices(self):
|
||||
import _cycles
|
||||
compute_device_type = self.get_compute_device_type()
|
||||
device_list = _cycles.available_devices(compute_device_type)
|
||||
device_list = _cycles.available_devices(self.compute_device_type)
|
||||
num = 0
|
||||
for device in device_list:
|
||||
if device[1] != compute_device_type:
|
||||
if device[1] != self.compute_device_type:
|
||||
continue
|
||||
for dev in self.devices:
|
||||
if dev.use and dev.id == device[2]:
|
||||
@@ -1410,19 +1563,8 @@ class CyclesPreferences(bpy.types.AddonPreferences):
|
||||
|
||||
if not found_device:
|
||||
col = box.column(align=True)
|
||||
col.label(text="No compatible GPUs found for Cycles", icon='INFO')
|
||||
|
||||
if device_type == 'CUDA':
|
||||
col.label(text="Requires NVIDIA GPU with compute capability 3.0", icon='BLANK1')
|
||||
elif device_type == 'OPTIX':
|
||||
col.label(text="Requires NVIDIA GPU with compute capability 5.0", icon='BLANK1')
|
||||
col.label(text="and NVIDIA driver version 470 or newer", icon='BLANK1')
|
||||
elif device_type == 'HIP':
|
||||
import sys
|
||||
col.label(text="Requires discrete AMD GPU with RDNA2 architecture", icon='BLANK1')
|
||||
# TODO: provide driver version info.
|
||||
#if sys.platform[:3] == "win":
|
||||
# col.label(text="and AMD driver version ??? or newer", icon='BLANK1')
|
||||
col.label(text="No compatible GPUs found for path tracing", icon='INFO')
|
||||
col.label(text="Cycles will render on the CPU", icon='BLANK1')
|
||||
return
|
||||
|
||||
for device in devices:
|
||||
@@ -1432,16 +1574,15 @@ class CyclesPreferences(bpy.types.AddonPreferences):
|
||||
row = layout.row()
|
||||
row.prop(self, "compute_device_type", expand=True)
|
||||
|
||||
compute_device_type = self.get_compute_device_type()
|
||||
if compute_device_type == 'NONE':
|
||||
if self.compute_device_type == 'NONE':
|
||||
return
|
||||
row = layout.row()
|
||||
devices = self.get_devices_for_type(compute_device_type)
|
||||
self._draw_devices(row, compute_device_type, devices)
|
||||
devices = self.get_devices_for_type(self.compute_device_type)
|
||||
self._draw_devices(row, self.compute_device_type, devices)
|
||||
|
||||
import _cycles
|
||||
has_peer_memory = 0
|
||||
for device in _cycles.available_devices(compute_device_type):
|
||||
for device in _cycles.available_devices(self.compute_device_type):
|
||||
if device[3] and self.find_existing_device_entry(device).use:
|
||||
has_peer_memory += 1
|
||||
if has_peer_memory > 1:
|
||||
@@ -1460,10 +1601,6 @@ class CyclesView3DShadingSettings(bpy.types.PropertyGroup):
|
||||
items=enum_view3d_shading_render_pass,
|
||||
default='COMBINED',
|
||||
)
|
||||
show_active_pixels: BoolProperty(
|
||||
name="Show Active Pixels",
|
||||
description="When using adaptive sampling highlight pixels which are being sampled",
|
||||
)
|
||||
|
||||
|
||||
def register():
|
||||
|
@@ -26,31 +26,21 @@ from bpy.types import Panel
|
||||
from bl_ui.properties_grease_pencil_common import GreasePencilSimplifyPanel
|
||||
from bl_ui.properties_view_layer import ViewLayerCryptomattePanel, ViewLayerAOVPanel
|
||||
|
||||
class CyclesPresetPanel(PresetPanel, Panel):
|
||||
COMPAT_ENGINES = {'CYCLES'}
|
||||
preset_operator = "script.execute_preset"
|
||||
|
||||
@staticmethod
|
||||
def post_cb(context):
|
||||
# Modify an arbitrary built-in scene property to force a depsgraph
|
||||
# update, because add-on properties don't. (see T62325)
|
||||
render = context.scene.render
|
||||
render.filter_size = render.filter_size
|
||||
|
||||
class CYCLES_PT_sampling_presets(CyclesPresetPanel):
|
||||
class CYCLES_PT_sampling_presets(PresetPanel, Panel):
|
||||
bl_label = "Sampling Presets"
|
||||
preset_subdir = "cycles/sampling"
|
||||
preset_operator = "script.execute_preset"
|
||||
preset_add_operator = "render.cycles_sampling_preset_add"
|
||||
COMPAT_ENGINES = {'CYCLES'}
|
||||
|
||||
class CYCLES_PT_viewport_sampling_presets(CyclesPresetPanel):
|
||||
bl_label = "Viewport Sampling Presets"
|
||||
preset_subdir = "cycles/viewport_sampling"
|
||||
preset_add_operator = "render.cycles_viewport_sampling_preset_add"
|
||||
|
||||
class CYCLES_PT_integrator_presets(CyclesPresetPanel):
|
||||
class CYCLES_PT_integrator_presets(PresetPanel, Panel):
|
||||
bl_label = "Integrator Presets"
|
||||
preset_subdir = "cycles/integrator"
|
||||
preset_operator = "script.execute_preset"
|
||||
preset_add_operator = "render.cycles_integrator_preset_add"
|
||||
COMPAT_ENGINES = {'CYCLES'}
|
||||
|
||||
|
||||
class CyclesButtonsPanel:
|
||||
@@ -64,15 +54,6 @@ class CyclesButtonsPanel:
|
||||
return context.engine in cls.COMPAT_ENGINES
|
||||
|
||||
|
||||
class CyclesDebugButtonsPanel(CyclesButtonsPanel):
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
prefs = bpy.context.preferences
|
||||
return (CyclesButtonsPanel.poll(context)
|
||||
and prefs.experimental.use_cycles_debug
|
||||
and prefs.view.show_developer_ui)
|
||||
|
||||
|
||||
# Adapt properties editor panel to display in node editor. We have to
|
||||
# copy the class rather than inherit due to the way bpy registration works.
|
||||
def node_panel(cls):
|
||||
@@ -97,23 +78,30 @@ def use_cpu(context):
|
||||
return (get_device_type(context) == 'NONE' or cscene.device == 'CPU')
|
||||
|
||||
|
||||
def use_opencl(context):
|
||||
cscene = context.scene.cycles
|
||||
|
||||
return (get_device_type(context) == 'OPENCL' and cscene.device == 'GPU')
|
||||
|
||||
|
||||
def use_cuda(context):
|
||||
cscene = context.scene.cycles
|
||||
|
||||
return (get_device_type(context) == 'CUDA' and cscene.device == 'GPU')
|
||||
|
||||
|
||||
def use_hip(context):
|
||||
cscene = context.scene.cycles
|
||||
|
||||
return (get_device_type(context) == 'HIP' and cscene.device == 'GPU')
|
||||
|
||||
def use_optix(context):
|
||||
cscene = context.scene.cycles
|
||||
|
||||
return (get_device_type(context) == 'OPTIX' and cscene.device == 'GPU')
|
||||
|
||||
|
||||
def use_branched_path(context):
|
||||
cscene = context.scene.cycles
|
||||
|
||||
return (cscene.progressive == 'BRANCHED_PATH' and not use_optix(context))
|
||||
|
||||
|
||||
def use_sample_all_lights(context):
|
||||
cscene = context.scene.cycles
|
||||
|
||||
@@ -127,93 +115,55 @@ def show_device_active(context):
|
||||
return context.preferences.addons[__package__].preferences.has_active_device()
|
||||
|
||||
|
||||
def get_effective_preview_denoiser(context):
|
||||
scene = context.scene
|
||||
cscene = scene.cycles
|
||||
def draw_samples_info(layout, context):
|
||||
cscene = context.scene.cycles
|
||||
integrator = cscene.progressive
|
||||
|
||||
if cscene.preview_denoiser != "AUTO":
|
||||
return cscene.preview_denoiser
|
||||
# Calculate sample values
|
||||
if integrator == 'PATH':
|
||||
aa = cscene.samples
|
||||
if cscene.use_square_samples:
|
||||
aa = aa * aa
|
||||
else:
|
||||
aa = cscene.aa_samples
|
||||
d = cscene.diffuse_samples
|
||||
g = cscene.glossy_samples
|
||||
t = cscene.transmission_samples
|
||||
ao = cscene.ao_samples
|
||||
ml = cscene.mesh_light_samples
|
||||
sss = cscene.subsurface_samples
|
||||
vol = cscene.volume_samples
|
||||
|
||||
if context.preferences.addons[__package__].preferences.get_devices_for_type('OPTIX'):
|
||||
return 'OPTIX'
|
||||
|
||||
return 'OIDN'
|
||||
if cscene.use_square_samples:
|
||||
aa = aa * aa
|
||||
d = d * d
|
||||
g = g * g
|
||||
t = t * t
|
||||
ao = ao * ao
|
||||
ml = ml * ml
|
||||
sss = sss * sss
|
||||
vol = vol * vol
|
||||
|
||||
# Draw interface
|
||||
# Do not draw for progressive, when Square Samples are disabled
|
||||
if use_branched_path(context) or (cscene.use_square_samples and integrator == 'PATH'):
|
||||
col = layout.column(align=True)
|
||||
col.scale_y = 0.6
|
||||
col.label(text="Total Samples:")
|
||||
col.separator()
|
||||
if integrator == 'PATH':
|
||||
col.label(text="%s AA" % aa)
|
||||
else:
|
||||
col.label(text="%s AA, %s Diffuse, %s Glossy, %s Transmission" %
|
||||
(aa, d * aa, g * aa, t * aa))
|
||||
col.separator()
|
||||
col.label(text="%s AO, %s Mesh Light, %s Subsurface, %s Volume" %
|
||||
(ao * aa, ml * aa, sss * aa, vol * aa))
|
||||
|
||||
|
||||
class CYCLES_RENDER_PT_sampling(CyclesButtonsPanel, Panel):
|
||||
bl_label = "Sampling"
|
||||
|
||||
def draw(self, context):
|
||||
pass
|
||||
|
||||
|
||||
class CYCLES_RENDER_PT_sampling_viewport(CyclesButtonsPanel, Panel):
|
||||
bl_label = "Viewport"
|
||||
bl_parent_id = "CYCLES_RENDER_PT_sampling"
|
||||
|
||||
def draw_header_preset(self, context):
|
||||
CYCLES_PT_viewport_sampling_presets.draw_panel_header(self.layout)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
scene = context.scene
|
||||
cscene = scene.cycles
|
||||
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
||||
|
||||
heading = layout.column(align=True, heading="Noise Threshold")
|
||||
row = heading.row(align=True)
|
||||
row.prop(cscene, "use_preview_adaptive_sampling", text="")
|
||||
sub = row.row()
|
||||
sub.active = cscene.use_preview_adaptive_sampling
|
||||
sub.prop(cscene, "preview_adaptive_threshold", text="")
|
||||
|
||||
if cscene.use_preview_adaptive_sampling:
|
||||
col = layout.column(align=True)
|
||||
col.prop(cscene, "preview_samples", text=" Max Samples")
|
||||
col.prop(cscene, "preview_adaptive_min_samples", text="Min Samples")
|
||||
else:
|
||||
layout.prop(cscene, "preview_samples", text="Samples")
|
||||
|
||||
|
||||
class CYCLES_RENDER_PT_sampling_viewport_denoise(CyclesButtonsPanel, Panel):
|
||||
bl_label = "Denoise"
|
||||
bl_parent_id = 'CYCLES_RENDER_PT_sampling_viewport'
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
def draw_header(self, context):
|
||||
scene = context.scene
|
||||
cscene = scene.cycles
|
||||
|
||||
self.layout.prop(context.scene.cycles, "use_preview_denoising", text="")
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
||||
|
||||
scene = context.scene
|
||||
cscene = scene.cycles
|
||||
|
||||
col = layout.column()
|
||||
col.active = cscene.use_preview_denoising
|
||||
col.prop(cscene, "preview_denoiser", text="Denoiser")
|
||||
col.prop(cscene, "preview_denoising_input_passes", text="Passes")
|
||||
|
||||
effective_preview_denoiser = get_effective_preview_denoiser(context)
|
||||
if effective_preview_denoiser == 'OPENIMAGEDENOISE':
|
||||
col.prop(cscene, "preview_denoising_prefilter", text="Prefilter")
|
||||
|
||||
col.prop(cscene, "preview_denoising_start_sample", text="Start Sample")
|
||||
|
||||
|
||||
class CYCLES_RENDER_PT_sampling_render(CyclesButtonsPanel, Panel):
|
||||
bl_label = "Render"
|
||||
bl_parent_id = "CYCLES_RENDER_PT_sampling"
|
||||
|
||||
def draw_header_preset(self, context):
|
||||
CYCLES_PT_sampling_presets.draw_panel_header(self.layout)
|
||||
|
||||
@@ -226,32 +176,29 @@ class CYCLES_RENDER_PT_sampling_render(CyclesButtonsPanel, Panel):
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
||||
|
||||
heading = layout.column(align=True, heading="Noise Threshold")
|
||||
row = heading.row(align=True)
|
||||
row.prop(cscene, "use_adaptive_sampling", text="")
|
||||
sub = row.row()
|
||||
sub.active = cscene.use_adaptive_sampling
|
||||
sub.prop(cscene, "adaptive_threshold", text="")
|
||||
if not use_optix(context):
|
||||
layout.prop(cscene, "progressive")
|
||||
|
||||
col = layout.column(align=True)
|
||||
if cscene.use_adaptive_sampling:
|
||||
col.prop(cscene, "samples", text=" Max Samples")
|
||||
col.prop(cscene, "adaptive_min_samples", text="Min Samples")
|
||||
if not use_branched_path(context):
|
||||
col = layout.column(align=True)
|
||||
col.prop(cscene, "samples", text="Render")
|
||||
col.prop(cscene, "preview_samples", text="Viewport")
|
||||
else:
|
||||
col.prop(cscene, "samples", text="Samples")
|
||||
col.prop(cscene, "time_limit")
|
||||
col = layout.column(align=True)
|
||||
col.prop(cscene, "aa_samples", text="Render")
|
||||
col.prop(cscene, "preview_aa_samples", text="Viewport")
|
||||
|
||||
if not use_branched_path(context):
|
||||
draw_samples_info(layout, context)
|
||||
|
||||
|
||||
class CYCLES_RENDER_PT_sampling_render_denoise(CyclesButtonsPanel, Panel):
|
||||
bl_label = "Denoise"
|
||||
bl_parent_id = 'CYCLES_RENDER_PT_sampling_render'
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
class CYCLES_RENDER_PT_sampling_sub_samples(CyclesButtonsPanel, Panel):
|
||||
bl_label = "Sub Samples"
|
||||
bl_parent_id = "CYCLES_RENDER_PT_sampling"
|
||||
|
||||
def draw_header(self, context):
|
||||
scene = context.scene
|
||||
cscene = scene.cycles
|
||||
|
||||
self.layout.prop(context.scene.cycles, "use_denoising", text="")
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return use_branched_path(context)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -261,12 +208,88 @@ class CYCLES_RENDER_PT_sampling_render_denoise(CyclesButtonsPanel, Panel):
|
||||
scene = context.scene
|
||||
cscene = scene.cycles
|
||||
|
||||
col = layout.column()
|
||||
col.active = cscene.use_denoising
|
||||
col.prop(cscene, "denoiser", text="Denoiser")
|
||||
col.prop(cscene, "denoising_input_passes", text="Passes")
|
||||
if cscene.denoiser == 'OPENIMAGEDENOISE':
|
||||
col.prop(cscene, "denoising_prefilter", text="Prefilter")
|
||||
col = layout.column(align=True)
|
||||
col.prop(cscene, "diffuse_samples", text="Diffuse")
|
||||
col.prop(cscene, "glossy_samples", text="Glossy")
|
||||
col.prop(cscene, "transmission_samples", text="Transmission")
|
||||
col.prop(cscene, "ao_samples", text="AO")
|
||||
|
||||
sub = col.row(align=True)
|
||||
sub.active = use_sample_all_lights(context)
|
||||
sub.prop(cscene, "mesh_light_samples", text="Mesh Light")
|
||||
col.prop(cscene, "subsurface_samples", text="Subsurface")
|
||||
col.prop(cscene, "volume_samples", text="Volume")
|
||||
|
||||
draw_samples_info(layout, context)
|
||||
|
||||
|
||||
class CYCLES_RENDER_PT_sampling_adaptive(CyclesButtonsPanel, Panel):
|
||||
bl_label = "Adaptive Sampling"
|
||||
bl_parent_id = "CYCLES_RENDER_PT_sampling"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
def draw_header(self, context):
|
||||
layout = self.layout
|
||||
scene = context.scene
|
||||
cscene = scene.cycles
|
||||
|
||||
layout.prop(cscene, "use_adaptive_sampling", text="")
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
||||
|
||||
scene = context.scene
|
||||
cscene = scene.cycles
|
||||
|
||||
layout.active = cscene.use_adaptive_sampling
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.prop(cscene, "adaptive_threshold", text="Noise Threshold")
|
||||
col.prop(cscene, "adaptive_min_samples", text="Min Samples")
|
||||
|
||||
|
||||
class CYCLES_RENDER_PT_sampling_denoising(CyclesButtonsPanel, Panel):
|
||||
bl_label = "Denoising"
|
||||
bl_parent_id = "CYCLES_RENDER_PT_sampling"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
||||
|
||||
scene = context.scene
|
||||
cscene = scene.cycles
|
||||
|
||||
heading = layout.column(align=True, heading="Render")
|
||||
row = heading.row(align=True)
|
||||
row.prop(cscene, "use_denoising", text="")
|
||||
sub = row.row()
|
||||
|
||||
sub.active = cscene.use_denoising
|
||||
for view_layer in scene.view_layers:
|
||||
if view_layer.cycles.denoising_store_passes:
|
||||
sub.active = True
|
||||
|
||||
sub.prop(cscene, "denoiser", text="")
|
||||
|
||||
layout.separator()
|
||||
|
||||
heading = layout.column(align=False, heading="Viewport")
|
||||
row = heading.row(align=True)
|
||||
row.prop(cscene, "use_preview_denoising", text="")
|
||||
sub = row.row()
|
||||
sub.active = cscene.use_preview_denoising
|
||||
sub.prop(cscene, "preview_denoiser", text="")
|
||||
|
||||
sub = heading.row(align=True)
|
||||
sub.active = cscene.use_preview_denoising
|
||||
sub.prop(cscene, "preview_denoising_start_sample", text="Start Sample")
|
||||
sub = heading.row(align=True)
|
||||
sub.active = cscene.use_preview_denoising
|
||||
sub.prop(cscene, "preview_denoising_input_passes", text="Input Passes")
|
||||
|
||||
|
||||
class CYCLES_RENDER_PT_sampling_advanced(CyclesButtonsPanel, Panel):
|
||||
@@ -287,18 +310,10 @@ class CYCLES_RENDER_PT_sampling_advanced(CyclesButtonsPanel, Panel):
|
||||
row.prop(cscene, "use_animated_seed", text="", icon='TIME')
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.active = not (cscene.use_adaptive_sampling and cscene.use_preview_adaptive_sampling)
|
||||
col.active = not(cscene.use_adaptive_sampling)
|
||||
col.prop(cscene, "sampling_pattern", text="Pattern")
|
||||
|
||||
layout.separator()
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.active = not (cscene.use_adaptive_sampling and cscene.use_preview_adaptive_sampling)
|
||||
col.prop(cscene, "scrambling_distance", text="Scrambling Distance")
|
||||
col.prop(cscene, "adaptive_scrambling_distance", text="Adaptive")
|
||||
sub = col.row(align=True)
|
||||
sub.active = not cscene.use_preview_adaptive_sampling
|
||||
sub.prop(cscene, "preview_scrambling_distance", text="Viewport")
|
||||
layout.prop(cscene, "use_square_samples")
|
||||
|
||||
layout.separator()
|
||||
|
||||
@@ -307,6 +322,11 @@ class CYCLES_RENDER_PT_sampling_advanced(CyclesButtonsPanel, Panel):
|
||||
col.prop(cscene, "min_transparent_bounces")
|
||||
col.prop(cscene, "light_sampling_threshold", text="Light Threshold")
|
||||
|
||||
if cscene.progressive != 'PATH' and use_branched_path(context):
|
||||
col = layout.column(align=True)
|
||||
col.prop(cscene, "sample_all_lights_direct")
|
||||
col.prop(cscene, "sample_all_lights_indirect")
|
||||
|
||||
for view_layer in scene.view_layers:
|
||||
if view_layer.samples > 0:
|
||||
layout.separator()
|
||||
@@ -314,6 +334,62 @@ class CYCLES_RENDER_PT_sampling_advanced(CyclesButtonsPanel, Panel):
|
||||
break
|
||||
|
||||
|
||||
class CYCLES_RENDER_PT_sampling_total(CyclesButtonsPanel, Panel):
|
||||
bl_label = "Total Samples"
|
||||
bl_parent_id = "CYCLES_RENDER_PT_sampling"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
scene = context.scene
|
||||
cscene = scene.cycles
|
||||
|
||||
if cscene.use_square_samples:
|
||||
return True
|
||||
|
||||
return cscene.progressive != 'PATH' and use_branched_path(context)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
cscene = context.scene.cycles
|
||||
integrator = cscene.progressive
|
||||
|
||||
# Calculate sample values
|
||||
if integrator == 'PATH':
|
||||
aa = cscene.samples
|
||||
if cscene.use_square_samples:
|
||||
aa = aa * aa
|
||||
else:
|
||||
aa = cscene.aa_samples
|
||||
d = cscene.diffuse_samples
|
||||
g = cscene.glossy_samples
|
||||
t = cscene.transmission_samples
|
||||
ao = cscene.ao_samples
|
||||
ml = cscene.mesh_light_samples
|
||||
sss = cscene.subsurface_samples
|
||||
vol = cscene.volume_samples
|
||||
|
||||
if cscene.use_square_samples:
|
||||
aa = aa * aa
|
||||
d = d * d
|
||||
g = g * g
|
||||
t = t * t
|
||||
ao = ao * ao
|
||||
ml = ml * ml
|
||||
sss = sss * sss
|
||||
vol = vol * vol
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.scale_y = 0.6
|
||||
if integrator == 'PATH':
|
||||
col.label(text="%s AA" % aa)
|
||||
else:
|
||||
col.label(text="%s AA, %s Diffuse, %s Glossy, %s Transmission" %
|
||||
(aa, d * aa, g * aa, t * aa))
|
||||
col.separator()
|
||||
col.label(text="%s AO, %s Mesh Light, %s Subsurface, %s Volume" %
|
||||
(ao * aa, ml * aa, sss * aa, vol * aa))
|
||||
|
||||
|
||||
class CYCLES_RENDER_PT_subdivision(CyclesButtonsPanel, Panel):
|
||||
bl_label = "Subdivision"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
@@ -472,10 +548,9 @@ class CYCLES_RENDER_PT_light_paths_fast_gi(CyclesButtonsPanel, Panel):
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
||||
|
||||
layout.active = cscene.use_fast_gi
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.prop(cscene, "fast_gi_method", text="Method")
|
||||
col.prop(cscene, "ao_bounces", text="Viewport Bounces")
|
||||
col.prop(cscene, "ao_bounces_render", text="Render Bounces")
|
||||
|
||||
if world:
|
||||
light = world.light_settings
|
||||
@@ -483,11 +558,6 @@ class CYCLES_RENDER_PT_light_paths_fast_gi(CyclesButtonsPanel, Panel):
|
||||
col.prop(light, "ao_factor", text="AO Factor")
|
||||
col.prop(light, "distance", text="AO Distance")
|
||||
|
||||
if cscene.fast_gi_method == 'REPLACE':
|
||||
col = layout.column(align=True)
|
||||
col.prop(cscene, "ao_bounces", text="Viewport Bounces")
|
||||
col.prop(cscene, "ao_bounces_render", text="Render Bounces")
|
||||
|
||||
|
||||
class CYCLES_RENDER_PT_motion_blur(CyclesButtonsPanel, Panel):
|
||||
bl_label = "Motion Blur"
|
||||
@@ -636,8 +706,8 @@ class CYCLES_RENDER_PT_performance_threads(CyclesButtonsPanel, Panel):
|
||||
sub.prop(rd, "threads")
|
||||
|
||||
|
||||
class CYCLES_RENDER_PT_performance_memory(CyclesButtonsPanel, Panel):
|
||||
bl_label = "Memory"
|
||||
class CYCLES_RENDER_PT_performance_tiles(CyclesButtonsPanel, Panel):
|
||||
bl_label = "Tiles"
|
||||
bl_parent_id = "CYCLES_RENDER_PT_performance"
|
||||
|
||||
def draw(self, context):
|
||||
@@ -646,13 +716,19 @@ class CYCLES_RENDER_PT_performance_memory(CyclesButtonsPanel, Panel):
|
||||
layout.use_property_decorate = False
|
||||
|
||||
scene = context.scene
|
||||
rd = scene.render
|
||||
cscene = scene.cycles
|
||||
|
||||
col = layout.column()
|
||||
col.prop(cscene, "use_auto_tile")
|
||||
|
||||
sub = col.column(align=True)
|
||||
sub.prop(rd, "tile_x", text="Tiles X")
|
||||
sub.prop(rd, "tile_y", text="Y")
|
||||
col.prop(cscene, "tile_order", text="Order")
|
||||
|
||||
sub = col.column()
|
||||
sub.active = cscene.use_auto_tile
|
||||
sub.prop(cscene, "tile_size")
|
||||
sub.active = not rd.use_save_buffers and not cscene.use_adaptive_sampling
|
||||
sub.prop(cscene, "use_progressive_refine")
|
||||
|
||||
|
||||
class CYCLES_RENDER_PT_performance_acceleration_structure(CyclesButtonsPanel, Panel):
|
||||
@@ -702,6 +778,7 @@ class CYCLES_RENDER_PT_performance_final_render(CyclesButtonsPanel, Panel):
|
||||
|
||||
col = layout.column()
|
||||
|
||||
col.prop(rd, "use_save_buffers")
|
||||
col.prop(rd, "use_persistent_data", text="Persistent Data")
|
||||
|
||||
|
||||
@@ -720,6 +797,7 @@ class CYCLES_RENDER_PT_performance_viewport(CyclesButtonsPanel, Panel):
|
||||
|
||||
col = layout.column()
|
||||
col.prop(rd, "preview_pixel_size", text="Pixel Size")
|
||||
col.prop(cscene, "preview_start_resolution", text="Start Pixels")
|
||||
|
||||
|
||||
class CYCLES_RENDER_PT_filter(CyclesButtonsPanel, Panel):
|
||||
@@ -740,6 +818,7 @@ class CYCLES_RENDER_PT_filter(CyclesButtonsPanel, Panel):
|
||||
|
||||
col = layout.column(heading="Include")
|
||||
col.prop(view_layer, "use_sky", text="Environment")
|
||||
col.prop(view_layer, "use_ao", text="Ambient Occlusion")
|
||||
col.prop(view_layer, "use_solid", text="Surfaces")
|
||||
col.prop(view_layer, "use_strand", text="Hair")
|
||||
col.prop(view_layer, "use_volumes", text="Volumes")
|
||||
@@ -748,9 +827,6 @@ class CYCLES_RENDER_PT_filter(CyclesButtonsPanel, Panel):
|
||||
sub = col.row()
|
||||
sub.prop(view_layer, "use_motion_blur", text="Motion Blur")
|
||||
sub.active = rd.use_motion_blur
|
||||
sub = col.row()
|
||||
sub.prop(view_layer.cycles, 'use_denoising', text='Denoising')
|
||||
sub.active = scene.cycles.use_denoising
|
||||
|
||||
|
||||
class CYCLES_RENDER_PT_override(CyclesButtonsPanel, Panel):
|
||||
@@ -796,7 +872,6 @@ class CYCLES_RENDER_PT_passes_data(CyclesButtonsPanel, Panel):
|
||||
col.prop(view_layer, "use_pass_combined")
|
||||
col.prop(view_layer, "use_pass_z")
|
||||
col.prop(view_layer, "use_pass_mist")
|
||||
col.prop(view_layer, "use_pass_position")
|
||||
col.prop(view_layer, "use_pass_normal")
|
||||
sub = col.column()
|
||||
sub.active = not rd.use_motion_blur
|
||||
@@ -810,6 +885,7 @@ class CYCLES_RENDER_PT_passes_data(CyclesButtonsPanel, Panel):
|
||||
col.prop(view_layer, "use_pass_material_index")
|
||||
|
||||
col = layout.column(heading="Debug", align=True)
|
||||
col.prop(cycles_view_layer, "pass_debug_render_time", text="Render Time")
|
||||
col.prop(cycles_view_layer, "pass_debug_sample_count", text="Sample Count")
|
||||
|
||||
layout.prop(view_layer, "pass_alpha_threshold")
|
||||
@@ -852,7 +928,6 @@ class CYCLES_RENDER_PT_passes_light(CyclesButtonsPanel, Panel):
|
||||
col.prop(view_layer, "use_pass_environment")
|
||||
col.prop(view_layer, "use_pass_shadow")
|
||||
col.prop(view_layer, "use_pass_ambient_occlusion", text="Ambient Occlusion")
|
||||
col.prop(cycles_view_layer, "use_pass_shadow_catcher")
|
||||
|
||||
|
||||
class CYCLES_RENDER_PT_passes_crypto(CyclesButtonsPanel, ViewLayerCryptomattePanel, Panel):
|
||||
@@ -867,6 +942,70 @@ class CYCLES_RENDER_PT_passes_aov(CyclesButtonsPanel, ViewLayerAOVPanel):
|
||||
bl_parent_id = "CYCLES_RENDER_PT_passes"
|
||||
|
||||
|
||||
class CYCLES_RENDER_PT_denoising(CyclesButtonsPanel, Panel):
|
||||
bl_label = "Denoising"
|
||||
bl_context = "view_layer"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
cscene = context.scene.cycles
|
||||
return CyclesButtonsPanel.poll(context) and cscene.use_denoising
|
||||
|
||||
def draw_header(self, context):
|
||||
scene = context.scene
|
||||
view_layer = context.view_layer
|
||||
cycles_view_layer = view_layer.cycles
|
||||
|
||||
layout = self.layout
|
||||
layout.prop(cycles_view_layer, "use_denoising", text="")
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
||||
|
||||
scene = context.scene
|
||||
view_layer = context.view_layer
|
||||
cycles_view_layer = view_layer.cycles
|
||||
denoiser = scene.cycles.denoiser
|
||||
|
||||
layout.active = denoiser != 'NONE' and cycles_view_layer.use_denoising
|
||||
|
||||
col = layout.column()
|
||||
|
||||
if denoiser == 'OPTIX':
|
||||
col.prop(cycles_view_layer, "denoising_optix_input_passes")
|
||||
return
|
||||
elif denoiser == 'OPENIMAGEDENOISE':
|
||||
col.prop(cycles_view_layer, "denoising_openimagedenoise_input_passes")
|
||||
return
|
||||
|
||||
col.prop(cycles_view_layer, "denoising_radius", text="Radius")
|
||||
|
||||
col = layout.column()
|
||||
col.prop(cycles_view_layer, "denoising_strength", slider=True, text="Strength")
|
||||
col.prop(cycles_view_layer, "denoising_feature_strength", slider=True, text="Feature Strength")
|
||||
col.prop(cycles_view_layer, "denoising_relative_pca")
|
||||
|
||||
layout.separator()
|
||||
|
||||
col = layout.column()
|
||||
col.active = cycles_view_layer.use_denoising or cycles_view_layer.denoising_store_passes
|
||||
|
||||
row = col.row(heading="Diffuse", align=True)
|
||||
row.prop(cycles_view_layer, "denoising_diffuse_direct", text="Direct", toggle=True)
|
||||
row.prop(cycles_view_layer, "denoising_diffuse_indirect", text="Indirect", toggle=True)
|
||||
|
||||
row = col.row(heading="Glossy", align=True)
|
||||
row.prop(cycles_view_layer, "denoising_glossy_direct", text="Direct", toggle=True)
|
||||
row.prop(cycles_view_layer, "denoising_glossy_indirect", text="Indirect", toggle=True)
|
||||
|
||||
row = col.row(heading="Transmission", align=True)
|
||||
row.prop(cycles_view_layer, "denoising_transmission_direct", text="Direct", toggle=True)
|
||||
row.prop(cycles_view_layer, "denoising_transmission_indirect", text="Indirect", toggle=True)
|
||||
|
||||
|
||||
class CYCLES_PT_post_processing(CyclesButtonsPanel, Panel):
|
||||
bl_label = "Post Processing"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
@@ -999,8 +1138,8 @@ class CYCLES_PT_context_material(CyclesButtonsPanel, Panel):
|
||||
row.prop(slot, "link", text="", icon=icon_link, icon_only=True)
|
||||
|
||||
elif mat:
|
||||
layout.template_ID(space, "pin_id")
|
||||
layout.separator()
|
||||
split.template_ID(space, "pin_id")
|
||||
split.separator()
|
||||
|
||||
|
||||
class CYCLES_OBJECT_PT_motion_blur(CyclesButtonsPanel, Panel):
|
||||
@@ -1278,6 +1417,10 @@ class CYCLES_LIGHT_PT_light(CyclesButtonsPanel, Panel):
|
||||
|
||||
if not (light.type == 'AREA' and clamp.is_portal):
|
||||
sub = col.column()
|
||||
if use_branched_path(context):
|
||||
subsub = sub.row(align=True)
|
||||
subsub.active = use_sample_all_lights(context)
|
||||
subsub.prop(clamp, "samples")
|
||||
sub.prop(clamp, "max_bounces")
|
||||
|
||||
sub = col.column(align=True)
|
||||
@@ -1383,6 +1526,34 @@ class CYCLES_WORLD_PT_volume(CyclesButtonsPanel, Panel):
|
||||
panel_node_draw(layout, world, 'OUTPUT_WORLD', 'Volume')
|
||||
|
||||
|
||||
class CYCLES_WORLD_PT_ambient_occlusion(CyclesButtonsPanel, Panel):
|
||||
bl_label = "Ambient Occlusion"
|
||||
bl_context = "world"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return context.world and CyclesButtonsPanel.poll(context)
|
||||
|
||||
def draw_header(self, context):
|
||||
light = context.world.light_settings
|
||||
self.layout.prop(light, "use_ambient_occlusion", text="")
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
||||
|
||||
light = context.world.light_settings
|
||||
scene = context.scene
|
||||
|
||||
col = layout.column()
|
||||
sub = col.column()
|
||||
sub.active = light.use_ambient_occlusion or scene.render.use_simplify
|
||||
sub.prop(light, "ao_factor", text="Factor")
|
||||
col.prop(light, "distance", text="Distance")
|
||||
|
||||
|
||||
class CYCLES_WORLD_PT_mist(CyclesButtonsPanel, Panel):
|
||||
bl_label = "Mist Pass"
|
||||
bl_context = "world"
|
||||
@@ -1479,6 +1650,10 @@ class CYCLES_WORLD_PT_settings_surface(CyclesButtonsPanel, Panel):
|
||||
subsub = sub.row(align=True)
|
||||
subsub.active = cworld.sampling_method == 'MANUAL'
|
||||
subsub.prop(cworld, "sample_map_resolution")
|
||||
if use_branched_path(context):
|
||||
subsub = sub.column(align=True)
|
||||
subsub.active = use_sample_all_lights(context)
|
||||
subsub.prop(cworld, "samples")
|
||||
sub.prop(cworld, "max_bounces")
|
||||
|
||||
|
||||
@@ -1502,7 +1677,8 @@ class CYCLES_WORLD_PT_settings_volume(CyclesButtonsPanel, Panel):
|
||||
col = layout.column()
|
||||
|
||||
sub = col.column()
|
||||
col.prop(cworld, "volume_sampling", text="Sampling")
|
||||
sub.active = use_cpu(context)
|
||||
sub.prop(cworld, "volume_sampling", text="Sampling")
|
||||
col.prop(cworld, "volume_interpolation", text="Interpolation")
|
||||
col.prop(cworld, "homogeneous_volume", text="Homogeneous")
|
||||
sub = col.column()
|
||||
@@ -1641,7 +1817,8 @@ class CYCLES_MATERIAL_PT_settings_volume(CyclesButtonsPanel, Panel):
|
||||
|
||||
col = layout.column()
|
||||
sub = col.column()
|
||||
col.prop(cmat, "volume_sampling", text="Sampling")
|
||||
sub.active = use_cpu(context)
|
||||
sub.prop(cmat, "volume_sampling", text="Sampling")
|
||||
col.prop(cmat, "volume_interpolation", text="Interpolation")
|
||||
col.prop(cmat, "homogeneous_volume", text="Homogeneous")
|
||||
sub = col.column()
|
||||
@@ -1668,6 +1845,9 @@ class CYCLES_RENDER_PT_bake(CyclesButtonsPanel, Panel):
|
||||
cbk = scene.render.bake
|
||||
rd = scene.render
|
||||
|
||||
if use_optix(context):
|
||||
layout.label(text="Baking is performed using CUDA instead of OptiX", icon='INFO')
|
||||
|
||||
if rd.use_bake_multires:
|
||||
layout.operator("object.bake_image", icon='RENDER_STILL')
|
||||
layout.prop(rd, "use_bake_multires")
|
||||
@@ -1725,6 +1905,7 @@ class CYCLES_RENDER_PT_bake_influence(CyclesButtonsPanel, Panel):
|
||||
col.prop(cbk, "use_pass_diffuse")
|
||||
col.prop(cbk, "use_pass_glossy")
|
||||
col.prop(cbk, "use_pass_transmission")
|
||||
col.prop(cbk, "use_pass_ambient_occlusion")
|
||||
col.prop(cbk, "use_pass_emit")
|
||||
|
||||
elif cscene.bake_type in {'DIFFUSE', 'GLOSSY', 'TRANSMISSION'}:
|
||||
@@ -1808,12 +1989,19 @@ class CYCLES_RENDER_PT_bake_output(CyclesButtonsPanel, Panel):
|
||||
layout.prop(cbk, "use_clear", text="Clear Image")
|
||||
|
||||
|
||||
class CYCLES_RENDER_PT_debug(CyclesDebugButtonsPanel, Panel):
|
||||
class CYCLES_RENDER_PT_debug(CyclesButtonsPanel, Panel):
|
||||
bl_label = "Debug"
|
||||
bl_context = "render"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'CYCLES'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
prefs = bpy.context.preferences
|
||||
return (CyclesButtonsPanel.poll(context)
|
||||
and prefs.experimental.use_cycles_debug
|
||||
and prefs.view.show_developer_ui)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
@@ -1830,18 +2018,29 @@ class CYCLES_RENDER_PT_debug(CyclesDebugButtonsPanel, Panel):
|
||||
row.prop(cscene, "debug_use_cpu_avx", toggle=True)
|
||||
row.prop(cscene, "debug_use_cpu_avx2", toggle=True)
|
||||
col.prop(cscene, "debug_bvh_layout")
|
||||
col.prop(cscene, "debug_use_cpu_split_kernel")
|
||||
|
||||
col.separator()
|
||||
|
||||
col = layout.column()
|
||||
col.label(text="CUDA Flags:")
|
||||
col.prop(cscene, "debug_use_cuda_adaptive_compile")
|
||||
col.prop(cscene, "debug_use_cuda_split_kernel")
|
||||
|
||||
col.separator()
|
||||
|
||||
col = layout.column()
|
||||
col.label(text="OptiX Flags:")
|
||||
col.prop(cscene, "debug_use_optix_debug")
|
||||
col.prop(cscene, "debug_optix_cuda_streams")
|
||||
col.prop(cscene, "debug_optix_curves_api")
|
||||
|
||||
col.separator()
|
||||
|
||||
col = layout.column()
|
||||
col.label(text="OpenCL Flags:")
|
||||
col.prop(cscene, "debug_opencl_device_type", text="Device")
|
||||
col.prop(cscene, "debug_use_opencl_debug", text="Debug")
|
||||
col.prop(cscene, "debug_opencl_mem_limit")
|
||||
|
||||
col.separator()
|
||||
|
||||
@@ -1942,22 +2141,20 @@ class CYCLES_RENDER_PT_simplify_culling(CyclesButtonsPanel, Panel):
|
||||
sub.prop(cscene, "distance_cull_margin", text="")
|
||||
|
||||
|
||||
class CyclesShadingButtonsPanel(CyclesButtonsPanel):
|
||||
class CYCLES_VIEW3D_PT_shading_render_pass(Panel):
|
||||
bl_space_type = 'VIEW_3D'
|
||||
bl_region_type = 'HEADER'
|
||||
bl_label = "Render Pass"
|
||||
bl_parent_id = 'VIEW3D_PT_shading'
|
||||
COMPAT_ENGINES = {'CYCLES'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return (
|
||||
CyclesButtonsPanel.poll(context) and
|
||||
context.engine in cls.COMPAT_ENGINES and
|
||||
context.space_data.shading.type == 'RENDERED'
|
||||
)
|
||||
|
||||
|
||||
class CYCLES_VIEW3D_PT_shading_render_pass(CyclesShadingButtonsPanel, Panel):
|
||||
bl_label = "Render Pass"
|
||||
|
||||
def draw(self, context):
|
||||
shading = context.space_data.shading
|
||||
|
||||
@@ -1965,26 +2162,6 @@ class CYCLES_VIEW3D_PT_shading_render_pass(CyclesShadingButtonsPanel, Panel):
|
||||
layout.prop(shading.cycles, "render_pass", text="")
|
||||
|
||||
|
||||
class CYCLES_VIEW3D_PT_shading_debug(CyclesDebugButtonsPanel,
|
||||
CyclesShadingButtonsPanel,
|
||||
Panel):
|
||||
bl_label = "Debug"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return (
|
||||
CyclesDebugButtonsPanel.poll(context) and
|
||||
CyclesShadingButtonsPanel.poll(context)
|
||||
)
|
||||
|
||||
def draw(self, context):
|
||||
shading = context.space_data.shading
|
||||
|
||||
layout = self.layout
|
||||
layout.active = context.scene.cycles.use_preview_adaptive_sampling
|
||||
layout.prop(shading.cycles, "show_active_pixels")
|
||||
|
||||
|
||||
class CYCLES_VIEW3D_PT_shading_lighting(Panel):
|
||||
bl_space_type = 'VIEW_3D'
|
||||
bl_region_type = 'HEADER'
|
||||
@@ -2098,13 +2275,11 @@ def get_panels():
|
||||
|
||||
classes = (
|
||||
CYCLES_PT_sampling_presets,
|
||||
CYCLES_PT_viewport_sampling_presets,
|
||||
CYCLES_PT_integrator_presets,
|
||||
CYCLES_RENDER_PT_sampling,
|
||||
CYCLES_RENDER_PT_sampling_viewport,
|
||||
CYCLES_RENDER_PT_sampling_viewport_denoise,
|
||||
CYCLES_RENDER_PT_sampling_render,
|
||||
CYCLES_RENDER_PT_sampling_render_denoise,
|
||||
CYCLES_RENDER_PT_sampling_sub_samples,
|
||||
CYCLES_RENDER_PT_sampling_adaptive,
|
||||
CYCLES_RENDER_PT_sampling_denoising,
|
||||
CYCLES_RENDER_PT_sampling_advanced,
|
||||
CYCLES_RENDER_PT_light_paths,
|
||||
CYCLES_RENDER_PT_light_paths_max_bounces,
|
||||
@@ -2121,7 +2296,6 @@ classes = (
|
||||
CYCLES_VIEW3D_PT_simplify_greasepencil,
|
||||
CYCLES_VIEW3D_PT_shading_lighting,
|
||||
CYCLES_VIEW3D_PT_shading_render_pass,
|
||||
CYCLES_VIEW3D_PT_shading_debug,
|
||||
CYCLES_RENDER_PT_motion_blur,
|
||||
CYCLES_RENDER_PT_motion_blur_curve,
|
||||
CYCLES_RENDER_PT_film,
|
||||
@@ -2129,7 +2303,7 @@ classes = (
|
||||
CYCLES_RENDER_PT_film_transparency,
|
||||
CYCLES_RENDER_PT_performance,
|
||||
CYCLES_RENDER_PT_performance_threads,
|
||||
CYCLES_RENDER_PT_performance_memory,
|
||||
CYCLES_RENDER_PT_performance_tiles,
|
||||
CYCLES_RENDER_PT_performance_acceleration_structure,
|
||||
CYCLES_RENDER_PT_performance_final_render,
|
||||
CYCLES_RENDER_PT_performance_viewport,
|
||||
@@ -2140,6 +2314,7 @@ classes = (
|
||||
CYCLES_RENDER_PT_passes_aov,
|
||||
CYCLES_RENDER_PT_filter,
|
||||
CYCLES_RENDER_PT_override,
|
||||
CYCLES_RENDER_PT_denoising,
|
||||
CYCLES_PT_post_processing,
|
||||
CYCLES_CAMERA_PT_dof,
|
||||
CYCLES_CAMERA_PT_dof_aperture,
|
||||
@@ -2158,6 +2333,7 @@ classes = (
|
||||
CYCLES_WORLD_PT_preview,
|
||||
CYCLES_WORLD_PT_surface,
|
||||
CYCLES_WORLD_PT_volume,
|
||||
CYCLES_WORLD_PT_ambient_occlusion,
|
||||
CYCLES_WORLD_PT_mist,
|
||||
CYCLES_WORLD_PT_ray_visibility,
|
||||
CYCLES_WORLD_PT_settings,
|
||||
|
@@ -86,7 +86,7 @@ def do_versions(self):
|
||||
# Device might not currently be available so this can fail
|
||||
try:
|
||||
if system.legacy_compute_device_type == 1:
|
||||
prop.compute_device_type = 'NONE' # Was OpenCL
|
||||
prop.compute_device_type = 'OPENCL'
|
||||
elif system.legacy_compute_device_type == 2:
|
||||
prop.compute_device_type = 'CUDA'
|
||||
else:
|
||||
@@ -97,12 +97,6 @@ def do_versions(self):
|
||||
# Init device list for UI
|
||||
prop.get_devices(prop.compute_device_type)
|
||||
|
||||
if bpy.context.preferences.version <= (3, 0, 40):
|
||||
# Disable OpenCL device
|
||||
prop = bpy.context.preferences.addons[__package__].preferences
|
||||
if prop.is_property_set("compute_device_type") and prop['compute_device_type'] == 4:
|
||||
prop.compute_device_type = 'NONE'
|
||||
|
||||
# We don't modify startup file because it assumes to
|
||||
# have all the default values only.
|
||||
if not bpy.data.is_saved:
|
||||
@@ -115,7 +109,7 @@ def do_versions(self):
|
||||
library_versions.setdefault(library.version, []).append(library)
|
||||
|
||||
# Do versioning per library, since they might have different versions.
|
||||
max_need_versioning = (3, 0, 25)
|
||||
max_need_versioning = (2, 93, 7)
|
||||
for version, libraries in library_versions.items():
|
||||
if version > max_need_versioning:
|
||||
continue
|
||||
@@ -172,6 +166,10 @@ def do_versions(self):
|
||||
if not cscene.is_property_set("filter_type"):
|
||||
cscene.pixel_filter_type = 'GAUSSIAN'
|
||||
|
||||
# Tile Order
|
||||
if not cscene.is_property_set("tile_order"):
|
||||
cscene.tile_order = 'CENTER'
|
||||
|
||||
if version <= (2, 76, 10):
|
||||
cscene = scene.cycles
|
||||
if cscene.is_property_set("filter_type"):
|
||||
@@ -188,6 +186,10 @@ def do_versions(self):
|
||||
if version <= (2, 79, 0):
|
||||
cscene = scene.cycles
|
||||
# Default changes
|
||||
if not cscene.is_property_set("aa_samples"):
|
||||
cscene.aa_samples = 4
|
||||
if not cscene.is_property_set("preview_aa_samples"):
|
||||
cscene.preview_aa_samples = 4
|
||||
if not cscene.is_property_set("blur_glossy"):
|
||||
cscene.blur_glossy = 0.0
|
||||
if not cscene.is_property_set("sample_clamp_indirect"):
|
||||
@@ -201,6 +203,7 @@ def do_versions(self):
|
||||
view_layer.use_pass_cryptomatte_material = cview_layer.get("use_pass_crypto_material", False)
|
||||
view_layer.use_pass_cryptomatte_asset = cview_layer.get("use_pass_crypto_asset", False)
|
||||
view_layer.pass_cryptomatte_depth = cview_layer.get("pass_crypto_depth", 6)
|
||||
view_layer.use_pass_cryptomatte_accurate = cview_layer.get("pass_crypto_accurate", True)
|
||||
|
||||
if version <= (2, 93, 7):
|
||||
if scene.render.engine == 'CYCLES':
|
||||
@@ -226,36 +229,6 @@ def do_versions(self):
|
||||
cscene.ao_bounces = 1
|
||||
cscene.ao_bounces_render = 1
|
||||
|
||||
if version <= (3, 0, 25):
|
||||
cscene = scene.cycles
|
||||
|
||||
# Default changes.
|
||||
if not cscene.is_property_set("samples"):
|
||||
cscene.samples = 128
|
||||
if not cscene.is_property_set("preview_samples"):
|
||||
cscene.preview_samples = 32
|
||||
if not cscene.is_property_set("use_adaptive_sampling"):
|
||||
cscene.use_adaptive_sampling = False
|
||||
cscene.use_preview_adaptive_sampling = False
|
||||
if not cscene.is_property_set("use_denoising"):
|
||||
cscene.use_denoising = False
|
||||
if not cscene.is_property_set("use_preview_denoising"):
|
||||
cscene.use_preview_denoising = False
|
||||
if not cscene.is_property_set("sampling_pattern") or \
|
||||
cscene.get('sampling_pattern') >= 2:
|
||||
cscene.sampling_pattern = 'PROGRESSIVE_MULTI_JITTER'
|
||||
|
||||
# Removal of square samples.
|
||||
cscene = scene.cycles
|
||||
use_square_samples = cscene.get("use_square_samples", False)
|
||||
|
||||
if use_square_samples:
|
||||
cscene.samples *= cscene.samples
|
||||
cscene.preview_samples *= cscene.preview_samples
|
||||
for layer in scene.view_layers:
|
||||
layer.samples *= layer.samples
|
||||
cscene["use_square_samples"] = False
|
||||
|
||||
# Lamps
|
||||
for light in bpy.data.lights:
|
||||
if light.library not in libraries:
|
||||
@@ -276,6 +249,10 @@ def do_versions(self):
|
||||
if version <= (2, 76, 9):
|
||||
cworld = world.cycles
|
||||
|
||||
# World MIS Samples
|
||||
if not cworld.is_property_set("samples"):
|
||||
cworld.samples = 4
|
||||
|
||||
# World MIS Resolution
|
||||
if not cworld.is_property_set("sample_map_resolution"):
|
||||
cworld.sample_map_resolution = 256
|
||||
|
@@ -14,13 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "scene/camera.h"
|
||||
#include "scene/scene.h"
|
||||
#include "render/camera.h"
|
||||
#include "render/scene.h"
|
||||
|
||||
#include "blender/sync.h"
|
||||
#include "blender/util.h"
|
||||
#include "blender/blender_sync.h"
|
||||
#include "blender/blender_util.h"
|
||||
|
||||
#include "util/log.h"
|
||||
#include "util/util_logging.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
@@ -80,9 +80,8 @@ struct BlenderCamera {
|
||||
int render_height;
|
||||
|
||||
BoundBox2D border;
|
||||
BoundBox2D viewport_camera_border;
|
||||
BoundBox2D pano_viewplane;
|
||||
float pano_aspectratio;
|
||||
BoundBox2D viewport_camera_border;
|
||||
|
||||
float passepartout_alpha;
|
||||
|
||||
@@ -124,11 +123,10 @@ static void blender_camera_init(BlenderCamera *bcam, BL::RenderSettings &b_rende
|
||||
bcam->motion_position = Camera::MOTION_POSITION_CENTER;
|
||||
bcam->border.right = 1.0f;
|
||||
bcam->border.top = 1.0f;
|
||||
bcam->viewport_camera_border.right = 1.0f;
|
||||
bcam->viewport_camera_border.top = 1.0f;
|
||||
bcam->pano_viewplane.right = 1.0f;
|
||||
bcam->pano_viewplane.top = 1.0f;
|
||||
bcam->pano_aspectratio = 0.0f;
|
||||
bcam->viewport_camera_border.right = 1.0f;
|
||||
bcam->viewport_camera_border.top = 1.0f;
|
||||
bcam->passepartout_alpha = 0.5f;
|
||||
bcam->offscreen_dicing_scale = 1.0f;
|
||||
bcam->matrix = transform_identity();
|
||||
@@ -360,21 +358,9 @@ static void blender_camera_viewplane(BlenderCamera *bcam,
|
||||
}
|
||||
|
||||
if (bcam->type == CAMERA_PANORAMA) {
|
||||
/* Set viewplane for panoramic camera. */
|
||||
/* set viewplane */
|
||||
if (viewplane != NULL) {
|
||||
*viewplane = bcam->pano_viewplane;
|
||||
|
||||
/* Modify viewplane for camera shift. */
|
||||
const float shift_factor = (bcam->pano_aspectratio == 0.0f) ?
|
||||
1.0f :
|
||||
*aspectratio / bcam->pano_aspectratio;
|
||||
const float dx = bcam->shift.x * shift_factor;
|
||||
const float dy = bcam->shift.y * shift_factor;
|
||||
|
||||
viewplane->left += dx;
|
||||
viewplane->right += dx;
|
||||
viewplane->bottom += dy;
|
||||
viewplane->top += dy;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -389,8 +375,8 @@ static void blender_camera_viewplane(BlenderCamera *bcam,
|
||||
*viewplane = (*viewplane) * bcam->zoom;
|
||||
|
||||
/* modify viewplane with camera shift and 3d camera view offset */
|
||||
const float dx = 2.0f * (*aspectratio * bcam->shift.x + bcam->offset.x * xaspect * 2.0f);
|
||||
const float dy = 2.0f * (*aspectratio * bcam->shift.y + bcam->offset.y * yaspect * 2.0f);
|
||||
float dx = 2.0f * (*aspectratio * bcam->shift.x + bcam->offset.x * xaspect * 2.0f);
|
||||
float dy = 2.0f * (*aspectratio * bcam->shift.y + bcam->offset.y * yaspect * 2.0f);
|
||||
|
||||
viewplane->left += dx;
|
||||
viewplane->right += dx;
|
||||
@@ -639,7 +625,7 @@ void BlenderSync::sync_camera_motion(
|
||||
/* TODO(sergey): De-duplicate calculation with camera sync. */
|
||||
float fov = 2.0f * atanf((0.5f * sensor_size) / bcam.lens / aspectratio);
|
||||
if (fov != cam->get_fov()) {
|
||||
VLOG(3) << "Camera " << b_ob.name() << " FOV change detected.";
|
||||
VLOG(1) << "Camera " << b_ob.name() << " FOV change detected.";
|
||||
if (motion_time == 0.0f) {
|
||||
cam->set_fov(fov);
|
||||
}
|
||||
@@ -666,8 +652,7 @@ static void blender_camera_view_subset(BL::RenderEngine &b_engine,
|
||||
int width,
|
||||
int height,
|
||||
BoundBox2D *view_box,
|
||||
BoundBox2D *cam_box,
|
||||
float *view_aspect);
|
||||
BoundBox2D *cam_box);
|
||||
|
||||
static void blender_camera_from_view(BlenderCamera *bcam,
|
||||
BL::RenderEngine &b_engine,
|
||||
@@ -697,7 +682,6 @@ static void blender_camera_from_view(BlenderCamera *bcam,
|
||||
if (!skip_panorama && bcam->type == CAMERA_PANORAMA) {
|
||||
/* in panorama camera view, we map viewplane to camera border */
|
||||
BoundBox2D view_box, cam_box;
|
||||
float view_aspect;
|
||||
|
||||
BL::RenderSettings b_render_settings(b_scene.render());
|
||||
blender_camera_view_subset(b_engine,
|
||||
@@ -709,11 +693,9 @@ static void blender_camera_from_view(BlenderCamera *bcam,
|
||||
width,
|
||||
height,
|
||||
&view_box,
|
||||
&cam_box,
|
||||
&view_aspect);
|
||||
&cam_box);
|
||||
|
||||
bcam->pano_viewplane = view_box.make_relative_to(cam_box);
|
||||
bcam->pano_aspectratio = view_aspect;
|
||||
}
|
||||
else {
|
||||
/* magic zoom formula */
|
||||
@@ -761,18 +743,17 @@ static void blender_camera_view_subset(BL::RenderEngine &b_engine,
|
||||
int width,
|
||||
int height,
|
||||
BoundBox2D *view_box,
|
||||
BoundBox2D *cam_box,
|
||||
float *view_aspect)
|
||||
BoundBox2D *cam_box)
|
||||
{
|
||||
BoundBox2D cam, view;
|
||||
float cam_aspect, sensor_size;
|
||||
float view_aspect, cam_aspect, sensor_size;
|
||||
|
||||
/* Get viewport viewplane. */
|
||||
BlenderCamera view_bcam;
|
||||
blender_camera_init(&view_bcam, b_render);
|
||||
blender_camera_from_view(&view_bcam, b_engine, b_scene, b_v3d, b_rv3d, width, height, true);
|
||||
|
||||
blender_camera_viewplane(&view_bcam, width, height, &view, view_aspect, &sensor_size);
|
||||
blender_camera_viewplane(&view_bcam, width, height, &view, &view_aspect, &sensor_size);
|
||||
|
||||
/* Get camera viewplane. */
|
||||
BlenderCamera cam_bcam;
|
||||
@@ -787,7 +768,7 @@ static void blender_camera_view_subset(BL::RenderEngine &b_engine,
|
||||
&cam_bcam, cam_bcam.full_width, cam_bcam.full_height, &cam, &cam_aspect, &sensor_size);
|
||||
|
||||
/* Return */
|
||||
*view_box = view * (1.0f / *view_aspect);
|
||||
*view_box = view * (1.0f / view_aspect);
|
||||
*cam_box = cam * (1.0f / cam_aspect);
|
||||
}
|
||||
|
||||
@@ -804,18 +785,8 @@ static void blender_camera_border_subset(BL::RenderEngine &b_engine,
|
||||
{
|
||||
/* Determine camera viewport subset. */
|
||||
BoundBox2D view_box, cam_box;
|
||||
float view_aspect;
|
||||
blender_camera_view_subset(b_engine,
|
||||
b_render,
|
||||
b_scene,
|
||||
b_ob,
|
||||
b_v3d,
|
||||
b_rv3d,
|
||||
width,
|
||||
height,
|
||||
&view_box,
|
||||
&cam_box,
|
||||
&view_aspect);
|
||||
blender_camera_view_subset(
|
||||
b_engine, b_render, b_scene, b_ob, b_v3d, b_rv3d, width, height, &view_box, &cam_box);
|
||||
|
||||
/* Determine viewport subset matching given border. */
|
||||
cam_box = cam_box.make_relative_to(view_box);
|
||||
@@ -923,8 +894,12 @@ void BlenderSync::sync_view(BL::SpaceView3D &b_v3d,
|
||||
}
|
||||
}
|
||||
|
||||
BufferParams BlenderSync::get_buffer_params(
|
||||
BL::SpaceView3D &b_v3d, BL::RegionView3D &b_rv3d, Camera *cam, int width, int height)
|
||||
BufferParams BlenderSync::get_buffer_params(BL::SpaceView3D &b_v3d,
|
||||
BL::RegionView3D &b_rv3d,
|
||||
Camera *cam,
|
||||
int width,
|
||||
int height,
|
||||
const bool use_denoiser)
|
||||
{
|
||||
BufferParams params;
|
||||
bool use_border = false;
|
||||
@@ -956,8 +931,10 @@ BufferParams BlenderSync::get_buffer_params(
|
||||
params.height = height;
|
||||
}
|
||||
|
||||
params.window_width = params.width;
|
||||
params.window_height = params.height;
|
||||
PassType display_pass = update_viewport_display_passes(b_v3d, params.passes);
|
||||
|
||||
/* Can only denoise the combined image pass */
|
||||
params.denoising_data_pass = display_pass == PASS_COMBINED && use_denoiser;
|
||||
|
||||
return params;
|
||||
}
|
@@ -14,20 +14,19 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "blender/sync.h"
|
||||
#include "blender/util.h"
|
||||
#include "render/attribute.h"
|
||||
#include "render/camera.h"
|
||||
#include "render/curves.h"
|
||||
#include "render/hair.h"
|
||||
#include "render/object.h"
|
||||
#include "render/scene.h"
|
||||
|
||||
#include "scene/attribute.h"
|
||||
#include "scene/camera.h"
|
||||
#include "scene/curves.h"
|
||||
#include "scene/hair.h"
|
||||
#include "scene/object.h"
|
||||
#include "scene/scene.h"
|
||||
#include "blender/blender_sync.h"
|
||||
#include "blender/blender_util.h"
|
||||
|
||||
#include "util/color.h"
|
||||
#include "util/foreach.h"
|
||||
#include "util/hash.h"
|
||||
#include "util/log.h"
|
||||
#include "util/util_foreach.h"
|
||||
#include "util/util_hash.h"
|
||||
#include "util/util_logging.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
@@ -284,13 +283,10 @@ static void ExportCurveSegments(Scene *scene, Hair *hair, ParticleCurveData *CDa
|
||||
return;
|
||||
|
||||
Attribute *attr_intercept = NULL;
|
||||
Attribute *attr_length = NULL;
|
||||
Attribute *attr_random = NULL;
|
||||
|
||||
if (hair->need_attribute(scene, ATTR_STD_CURVE_INTERCEPT))
|
||||
attr_intercept = hair->attributes.add(ATTR_STD_CURVE_INTERCEPT);
|
||||
if (hair->need_attribute(scene, ATTR_STD_CURVE_LENGTH))
|
||||
attr_length = hair->attributes.add(ATTR_STD_CURVE_LENGTH);
|
||||
if (hair->need_attribute(scene, ATTR_STD_CURVE_RANDOM))
|
||||
attr_random = hair->attributes.add(ATTR_STD_CURVE_RANDOM);
|
||||
|
||||
@@ -304,6 +300,10 @@ static void ExportCurveSegments(Scene *scene, Hair *hair, ParticleCurveData *CDa
|
||||
}
|
||||
}
|
||||
|
||||
if (num_curves > 0) {
|
||||
VLOG(1) << "Exporting curve segments for mesh " << hair->name;
|
||||
}
|
||||
|
||||
hair->reserve_curves(hair->num_curves() + num_curves, hair->get_curve_keys().size() + num_keys);
|
||||
|
||||
num_keys = 0;
|
||||
@@ -336,10 +336,6 @@ static void ExportCurveSegments(Scene *scene, Hair *hair, ParticleCurveData *CDa
|
||||
num_curve_keys++;
|
||||
}
|
||||
|
||||
if (attr_length != NULL) {
|
||||
attr_length->add(CData->curve_length[curve]);
|
||||
}
|
||||
|
||||
if (attr_random != NULL) {
|
||||
attr_random->add(hash_uint2_to_float(num_curves, 0));
|
||||
}
|
||||
@@ -352,7 +348,7 @@ static void ExportCurveSegments(Scene *scene, Hair *hair, ParticleCurveData *CDa
|
||||
|
||||
/* check allocation */
|
||||
if ((hair->get_curve_keys().size() != num_keys) || (hair->num_curves() != num_curves)) {
|
||||
VLOG(1) << "Hair memory allocation failed, clearing data.";
|
||||
VLOG(1) << "Allocation failed, clearing data";
|
||||
hair->clear(true);
|
||||
}
|
||||
}
|
||||
@@ -408,11 +404,16 @@ static void export_hair_motion_validate_attribute(Hair *hair,
|
||||
if (num_motion_keys != num_keys || !have_motion) {
|
||||
/* No motion or hair "topology" changed, remove attributes again. */
|
||||
if (num_motion_keys != num_keys) {
|
||||
VLOG(1) << "Hair topology changed, removing motion attribute.";
|
||||
VLOG(1) << "Hair topology changed, removing attribute.";
|
||||
}
|
||||
else {
|
||||
VLOG(1) << "No motion, removing attribute.";
|
||||
}
|
||||
hair->attributes.remove(ATTR_STD_MOTION_VERTEX_POSITION);
|
||||
}
|
||||
else if (motion_step > 0) {
|
||||
VLOG(1) << "Filling in new motion vertex position for motion_step " << motion_step;
|
||||
|
||||
/* Motion, fill up previous steps that we might have skipped because
|
||||
* they had no motion, but we need them anyway now. */
|
||||
for (int step = 0; step < motion_step; step++) {
|
||||
@@ -428,12 +429,16 @@ static void export_hair_motion_validate_attribute(Hair *hair,
|
||||
|
||||
static void ExportCurveSegmentsMotion(Hair *hair, ParticleCurveData *CData, int motion_step)
|
||||
{
|
||||
VLOG(1) << "Exporting curve motion segments for hair " << hair->name << ", motion step "
|
||||
<< motion_step;
|
||||
|
||||
/* find attribute */
|
||||
Attribute *attr_mP = hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
|
||||
bool new_attribute = false;
|
||||
|
||||
/* add new attribute if it doesn't exist already */
|
||||
if (!attr_mP) {
|
||||
VLOG(1) << "Creating new motion vertex position attribute";
|
||||
attr_mP = hair->attributes.add(ATTR_STD_MOTION_VERTEX_POSITION);
|
||||
new_attribute = true;
|
||||
}
|
||||
@@ -652,15 +657,11 @@ static void export_hair_curves(Scene *scene, Hair *hair, BL::Hair b_hair)
|
||||
|
||||
/* Add requested attributes. */
|
||||
Attribute *attr_intercept = NULL;
|
||||
Attribute *attr_length = NULL;
|
||||
Attribute *attr_random = NULL;
|
||||
|
||||
if (hair->need_attribute(scene, ATTR_STD_CURVE_INTERCEPT)) {
|
||||
attr_intercept = hair->attributes.add(ATTR_STD_CURVE_INTERCEPT);
|
||||
}
|
||||
if (hair->need_attribute(scene, ATTR_STD_CURVE_LENGTH)) {
|
||||
attr_length = hair->attributes.add(ATTR_STD_CURVE_LENGTH);
|
||||
}
|
||||
if (hair->need_attribute(scene, ATTR_STD_CURVE_RANDOM)) {
|
||||
attr_random = hair->attributes.add(ATTR_STD_CURVE_RANDOM);
|
||||
}
|
||||
@@ -669,6 +670,10 @@ static void export_hair_curves(Scene *scene, Hair *hair, BL::Hair b_hair)
|
||||
const int num_keys = b_hair.points.length();
|
||||
const int num_curves = b_hair.curves.length();
|
||||
|
||||
if (num_curves > 0) {
|
||||
VLOG(1) << "Exporting curve segments for hair " << hair->name;
|
||||
}
|
||||
|
||||
hair->reserve_curves(num_curves, num_keys);
|
||||
|
||||
/* Export curves and points. */
|
||||
@@ -709,10 +714,6 @@ static void export_hair_curves(Scene *scene, Hair *hair, BL::Hair b_hair)
|
||||
}
|
||||
}
|
||||
|
||||
if (attr_length) {
|
||||
attr_length->add(length);
|
||||
}
|
||||
|
||||
/* Random number per curve. */
|
||||
if (attr_random != NULL) {
|
||||
attr_random->add(hash_uint2_to_float(b_curve.index(), 0));
|
||||
@@ -726,11 +727,15 @@ static void export_hair_curves(Scene *scene, Hair *hair, BL::Hair b_hair)
|
||||
|
||||
static void export_hair_curves_motion(Hair *hair, BL::Hair b_hair, int motion_step)
|
||||
{
|
||||
VLOG(1) << "Exporting curve motion segments for hair " << hair->name << ", motion step "
|
||||
<< motion_step;
|
||||
|
||||
/* Find or add attribute. */
|
||||
Attribute *attr_mP = hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
|
||||
bool new_attribute = false;
|
||||
|
||||
if (!attr_mP) {
|
||||
VLOG(1) << "Creating new motion vertex position attribute";
|
||||
attr_mP = hair->attributes.add(ATTR_STD_MOTION_VERTEX_POSITION);
|
||||
new_attribute = true;
|
||||
}
|
@@ -14,19 +14,19 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "blender/device.h"
|
||||
#include "blender/session.h"
|
||||
#include "blender/util.h"
|
||||
#include "blender/blender_device.h"
|
||||
#include "blender/blender_session.h"
|
||||
#include "blender/blender_util.h"
|
||||
|
||||
#include "util/foreach.h"
|
||||
#include "util/util_foreach.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
enum ComputeDevice {
|
||||
COMPUTE_DEVICE_CPU = 0,
|
||||
COMPUTE_DEVICE_CUDA = 1,
|
||||
COMPUTE_DEVICE_OPENCL = 2,
|
||||
COMPUTE_DEVICE_OPTIX = 3,
|
||||
COMPUTE_DEVICE_HIP = 4,
|
||||
|
||||
COMPUTE_DEVICE_NUM
|
||||
};
|
||||
@@ -68,6 +68,13 @@ DeviceInfo blender_device_info(BL::Preferences &b_preferences, BL::Scene &b_scen
|
||||
device = Device::get_multi_device(devices, threads, background);
|
||||
}
|
||||
}
|
||||
else if (get_enum(cscene, "device") == 2) {
|
||||
/* Find network device. */
|
||||
vector<DeviceInfo> devices = Device::available_devices(DEVICE_MASK_NETWORK);
|
||||
if (!devices.empty()) {
|
||||
device = devices.front();
|
||||
}
|
||||
}
|
||||
else if (get_enum(cscene, "device") == 1) {
|
||||
/* Test if we are using GPU devices. */
|
||||
ComputeDevice compute_device = (ComputeDevice)get_enum(
|
||||
@@ -82,8 +89,8 @@ DeviceInfo blender_device_info(BL::Preferences &b_preferences, BL::Scene &b_scen
|
||||
else if (compute_device == COMPUTE_DEVICE_OPTIX) {
|
||||
mask |= DEVICE_MASK_OPTIX;
|
||||
}
|
||||
else if (compute_device == COMPUTE_DEVICE_HIP) {
|
||||
mask |= DEVICE_MASK_HIP;
|
||||
else if (compute_device == COMPUTE_DEVICE_OPENCL) {
|
||||
mask |= DEVICE_MASK_OPENCL;
|
||||
}
|
||||
vector<DeviceInfo> devices = Device::available_devices(mask);
|
||||
|
@@ -15,17 +15,17 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "scene/curves.h"
|
||||
#include "scene/hair.h"
|
||||
#include "scene/mesh.h"
|
||||
#include "scene/object.h"
|
||||
#include "scene/volume.h"
|
||||
#include "render/curves.h"
|
||||
#include "render/hair.h"
|
||||
#include "render/mesh.h"
|
||||
#include "render/object.h"
|
||||
#include "render/volume.h"
|
||||
|
||||
#include "blender/sync.h"
|
||||
#include "blender/util.h"
|
||||
#include "blender/blender_sync.h"
|
||||
#include "blender/blender_util.h"
|
||||
|
||||
#include "util/foreach.h"
|
||||
#include "util/task.h"
|
||||
#include "util/util_foreach.h"
|
||||
#include "util/util_task.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
@@ -80,11 +80,7 @@ Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph,
|
||||
{
|
||||
/* Test if we can instance or if the object is modified. */
|
||||
Geometry::Type geom_type = determine_geom_type(b_ob_info, use_particle_hair);
|
||||
BL::ID b_key_id = (b_ob_info.is_real_object_data() &&
|
||||
BKE_object_is_modified(b_ob_info.real_object)) ?
|
||||
b_ob_info.real_object :
|
||||
b_ob_info.object_data;
|
||||
GeometryKey key(b_key_id.ptr.data, geom_type);
|
||||
GeometryKey key(b_ob_info.object_data, geom_type);
|
||||
|
||||
/* Find shader indices. */
|
||||
array<Node *> used_shaders = find_used_shaders(b_ob_info.iter_object);
|
||||
@@ -114,7 +110,7 @@ Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph,
|
||||
}
|
||||
else {
|
||||
/* Test if we need to update existing geometry. */
|
||||
sync = geometry_map.update(geom, b_key_id);
|
||||
sync = geometry_map.update(geom, b_ob_info.object_data);
|
||||
}
|
||||
|
||||
if (!sync) {
|
@@ -19,12 +19,12 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "scene/geometry.h"
|
||||
#include "scene/scene.h"
|
||||
#include "render/geometry.h"
|
||||
#include "render/scene.h"
|
||||
|
||||
#include "util/map.h"
|
||||
#include "util/set.h"
|
||||
#include "util/vector.h"
|
||||
#include "util/util_map.h"
|
||||
#include "util/util_set.h"
|
||||
#include "util/util_vector.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
@@ -16,9 +16,9 @@
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "blender/image.h"
|
||||
#include "blender/session.h"
|
||||
#include "blender/util.h"
|
||||
#include "blender/blender_image.h"
|
||||
#include "blender/blender_session.h"
|
||||
#include "blender/blender_util.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
@@ -19,7 +19,7 @@
|
||||
|
||||
#include "RNA_blender_cpp.h"
|
||||
|
||||
#include "scene/image.h"
|
||||
#include "render/image.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
@@ -16,12 +16,12 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "scene/light.h"
|
||||
#include "render/light.h"
|
||||
|
||||
#include "blender/sync.h"
|
||||
#include "blender/util.h"
|
||||
#include "blender/blender_sync.h"
|
||||
#include "blender/blender_util.h"
|
||||
|
||||
#include "util/hash.h"
|
||||
#include "util/util_hash.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
@@ -125,10 +125,17 @@ void BlenderSync::sync_light(BL::Object &b_parent,
|
||||
light->set_shader(static_cast<Shader *>(used_shaders[0]));
|
||||
|
||||
/* shadow */
|
||||
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
|
||||
PointerRNA clight = RNA_pointer_get(&b_light.ptr, "cycles");
|
||||
light->set_cast_shadow(get_boolean(clight, "cast_shadow"));
|
||||
light->set_use_mis(get_boolean(clight, "use_multiple_importance_sampling"));
|
||||
|
||||
int samples = get_int(clight, "samples");
|
||||
if (get_boolean(cscene, "use_square_samples"))
|
||||
light->set_samples(samples * samples);
|
||||
else
|
||||
light->set_samples(samples);
|
||||
|
||||
light->set_max_bounces(get_int(clight, "max_bounces"));
|
||||
|
||||
if (b_ob_info.real_object != b_ob_info.iter_object) {
|
||||
@@ -148,12 +155,10 @@ void BlenderSync::sync_light(BL::Object &b_parent,
|
||||
|
||||
/* visibility */
|
||||
uint visibility = object_ray_visibility(b_ob_info.real_object);
|
||||
light->set_use_camera((visibility & PATH_RAY_CAMERA) != 0);
|
||||
light->set_use_diffuse((visibility & PATH_RAY_DIFFUSE) != 0);
|
||||
light->set_use_glossy((visibility & PATH_RAY_GLOSSY) != 0);
|
||||
light->set_use_transmission((visibility & PATH_RAY_TRANSMIT) != 0);
|
||||
light->set_use_scatter((visibility & PATH_RAY_VOLUME_SCATTER) != 0);
|
||||
light->set_is_shadow_catcher(b_ob_info.real_object.is_shadow_catcher());
|
||||
|
||||
/* tag */
|
||||
light->tag_update(scene);
|
||||
@@ -164,6 +169,7 @@ void BlenderSync::sync_background_light(BL::SpaceView3D &b_v3d, bool use_portal)
|
||||
BL::World b_world = b_scene.world();
|
||||
|
||||
if (b_world) {
|
||||
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
|
||||
PointerRNA cworld = RNA_pointer_get(&b_world.ptr, "cycles");
|
||||
|
||||
enum SamplingMethod { SAMPLING_NONE = 0, SAMPLING_AUTOMATIC, SAMPLING_MANUAL, SAMPLING_NUM };
|
||||
@@ -191,6 +197,12 @@ void BlenderSync::sync_background_light(BL::SpaceView3D &b_v3d, bool use_portal)
|
||||
/* force enable light again when world is resynced */
|
||||
light->set_is_enabled(true);
|
||||
|
||||
int samples = get_int(cworld, "samples");
|
||||
if (get_boolean(cscene, "use_square_samples"))
|
||||
light->set_samples(samples * samples);
|
||||
else
|
||||
light->set_samples(samples);
|
||||
|
||||
light->tag_update(scene);
|
||||
light_map.set_recalc(b_world);
|
||||
}
|
||||
@@ -199,7 +211,7 @@ void BlenderSync::sync_background_light(BL::SpaceView3D &b_v3d, bool use_portal)
|
||||
|
||||
world_map = b_world.ptr.data;
|
||||
world_recalc = false;
|
||||
viewport_parameters = BlenderViewportParameters(b_v3d, use_developer_ui);
|
||||
viewport_parameters = BlenderViewportParameters(b_v3d);
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
#include "blender/CCL_api.h"
|
||||
#include "util/log.h"
|
||||
#include "util/util_logging.h"
|
||||
|
||||
void CCL_init_logging(const char *argv0)
|
||||
{
|
@@ -14,26 +14,25 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "blender/session.h"
|
||||
#include "blender/sync.h"
|
||||
#include "blender/util.h"
|
||||
#include "render/camera.h"
|
||||
#include "render/colorspace.h"
|
||||
#include "render/mesh.h"
|
||||
#include "render/object.h"
|
||||
#include "render/scene.h"
|
||||
|
||||
#include "scene/camera.h"
|
||||
#include "scene/colorspace.h"
|
||||
#include "scene/mesh.h"
|
||||
#include "scene/object.h"
|
||||
#include "scene/scene.h"
|
||||
#include "blender/blender_session.h"
|
||||
#include "blender/blender_sync.h"
|
||||
#include "blender/blender_util.h"
|
||||
|
||||
#include "subd/patch.h"
|
||||
#include "subd/split.h"
|
||||
#include "subd/subd_patch.h"
|
||||
#include "subd/subd_split.h"
|
||||
|
||||
#include "util/algorithm.h"
|
||||
#include "util/color.h"
|
||||
#include "util/disjoint_set.h"
|
||||
#include "util/foreach.h"
|
||||
#include "util/hash.h"
|
||||
#include "util/log.h"
|
||||
#include "util/math.h"
|
||||
#include "util/util_algorithm.h"
|
||||
#include "util/util_disjoint_set.h"
|
||||
#include "util/util_foreach.h"
|
||||
#include "util/util_hash.h"
|
||||
#include "util/util_logging.h"
|
||||
#include "util/util_math.h"
|
||||
|
||||
#include "mikktspace.h"
|
||||
|
@@ -14,26 +14,26 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "blender/object_cull.h"
|
||||
#include "blender/sync.h"
|
||||
#include "blender/util.h"
|
||||
#include "render/alembic.h"
|
||||
#include "render/camera.h"
|
||||
#include "render/graph.h"
|
||||
#include "render/integrator.h"
|
||||
#include "render/light.h"
|
||||
#include "render/mesh.h"
|
||||
#include "render/nodes.h"
|
||||
#include "render/object.h"
|
||||
#include "render/particles.h"
|
||||
#include "render/scene.h"
|
||||
#include "render/shader.h"
|
||||
|
||||
#include "scene/alembic.h"
|
||||
#include "scene/camera.h"
|
||||
#include "scene/integrator.h"
|
||||
#include "scene/light.h"
|
||||
#include "scene/mesh.h"
|
||||
#include "scene/object.h"
|
||||
#include "scene/particles.h"
|
||||
#include "scene/scene.h"
|
||||
#include "scene/shader.h"
|
||||
#include "scene/shader_graph.h"
|
||||
#include "scene/shader_nodes.h"
|
||||
#include "blender/blender_object_cull.h"
|
||||
#include "blender/blender_sync.h"
|
||||
#include "blender/blender_util.h"
|
||||
|
||||
#include "util/foreach.h"
|
||||
#include "util/hash.h"
|
||||
#include "util/log.h"
|
||||
#include "util/task.h"
|
||||
#include "util/util_foreach.h"
|
||||
#include "util/util_hash.h"
|
||||
#include "util/util_logging.h"
|
||||
#include "util/util_task.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
@@ -104,22 +104,23 @@ void BlenderSync::sync_object_motion_init(BL::Object &b_parent, BL::Object &b_ob
|
||||
array<Transform> motion;
|
||||
object->set_motion(motion);
|
||||
|
||||
Geometry *geom = object->get_geometry();
|
||||
if (!geom) {
|
||||
Scene::MotionType need_motion = scene->need_motion();
|
||||
if (need_motion == Scene::MOTION_NONE || !object->get_geometry()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Geometry *geom = object->get_geometry();
|
||||
|
||||
int motion_steps = 0;
|
||||
bool use_motion_blur = false;
|
||||
|
||||
Scene::MotionType need_motion = scene->need_motion();
|
||||
if (need_motion == Scene::MOTION_BLUR) {
|
||||
motion_steps = object_motion_steps(b_parent, b_ob, Object::MAX_MOTION_STEPS);
|
||||
if (motion_steps && object_use_deform_motion(b_parent, b_ob)) {
|
||||
use_motion_blur = true;
|
||||
}
|
||||
}
|
||||
else if (need_motion != Scene::MOTION_NONE) {
|
||||
else {
|
||||
motion_steps = 3;
|
||||
}
|
||||
|
||||
@@ -161,11 +162,6 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph,
|
||||
if (is_instance) {
|
||||
persistent_id_array = b_instance.persistent_id();
|
||||
persistent_id = persistent_id_array.data;
|
||||
if (!b_ob_info.is_real_object_data()) {
|
||||
/* Remember which object data the geometry is coming from, so that we can sync it when the
|
||||
* object has changed. */
|
||||
instance_geometries_by_object[b_ob_info.real_object.ptr.data].insert(b_ob_info.object_data);
|
||||
}
|
||||
}
|
||||
|
||||
/* light is handled separately */
|
||||
@@ -565,7 +561,6 @@ void BlenderSync::sync_objects(BL::Depsgraph &b_depsgraph,
|
||||
else {
|
||||
geometry_motion_synced.clear();
|
||||
}
|
||||
instance_geometries_by_object.clear();
|
||||
|
||||
/* initialize culling */
|
||||
BlenderObjectCulling culling(scene, b_scene);
|
||||
@@ -573,7 +568,7 @@ void BlenderSync::sync_objects(BL::Depsgraph &b_depsgraph,
|
||||
/* object loop */
|
||||
bool cancel = false;
|
||||
bool use_portal = false;
|
||||
const bool show_lights = BlenderViewportParameters(b_v3d, use_developer_ui).use_scene_lights;
|
||||
const bool show_lights = BlenderViewportParameters(b_v3d).use_scene_lights;
|
||||
|
||||
BL::ViewLayer b_view_layer = b_depsgraph.view_layer_eval();
|
||||
BL::Depsgraph::object_instances_iterator b_instance_iter;
|
@@ -16,10 +16,10 @@
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
#include "scene/camera.h"
|
||||
#include "render/camera.h"
|
||||
|
||||
#include "blender/object_cull.h"
|
||||
#include "blender/util.h"
|
||||
#include "blender/blender_object_cull.h"
|
||||
#include "blender/blender_util.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
@@ -17,8 +17,8 @@
|
||||
#ifndef __BLENDER_OBJECT_CULL_H__
|
||||
#define __BLENDER_OBJECT_CULL_H__
|
||||
|
||||
#include "blender/sync.h"
|
||||
#include "util/types.h"
|
||||
#include "blender/blender_sync.h"
|
||||
#include "util/util_types.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
@@ -14,14 +14,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "scene/particles.h"
|
||||
#include "scene/mesh.h"
|
||||
#include "scene/object.h"
|
||||
#include "render/mesh.h"
|
||||
#include "render/object.h"
|
||||
#include "render/particles.h"
|
||||
|
||||
#include "blender/sync.h"
|
||||
#include "blender/util.h"
|
||||
#include "blender/blender_sync.h"
|
||||
#include "blender/blender_util.h"
|
||||
|
||||
#include "util/foreach.h"
|
||||
#include "util/util_foreach.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
@@ -18,33 +18,37 @@
|
||||
|
||||
#include "blender/CCL_api.h"
|
||||
|
||||
#include "blender/device.h"
|
||||
#include "blender/session.h"
|
||||
#include "blender/sync.h"
|
||||
#include "blender/util.h"
|
||||
#include "blender/blender_device.h"
|
||||
#include "blender/blender_session.h"
|
||||
#include "blender/blender_sync.h"
|
||||
#include "blender/blender_util.h"
|
||||
|
||||
#include "session/denoising.h"
|
||||
#include "session/merge.h"
|
||||
#include "render/denoising.h"
|
||||
#include "render/merge.h"
|
||||
|
||||
#include "util/debug.h"
|
||||
#include "util/foreach.h"
|
||||
#include "util/log.h"
|
||||
#include "util/md5.h"
|
||||
#include "util/opengl.h"
|
||||
#include "util/openimagedenoise.h"
|
||||
#include "util/path.h"
|
||||
#include "util/string.h"
|
||||
#include "util/task.h"
|
||||
#include "util/tbb.h"
|
||||
#include "util/types.h"
|
||||
#include "util/util_debug.h"
|
||||
#include "util/util_foreach.h"
|
||||
#include "util/util_logging.h"
|
||||
#include "util/util_md5.h"
|
||||
#include "util/util_opengl.h"
|
||||
#include "util/util_openimagedenoise.h"
|
||||
#include "util/util_path.h"
|
||||
#include "util/util_string.h"
|
||||
#include "util/util_task.h"
|
||||
#include "util/util_tbb.h"
|
||||
#include "util/util_types.h"
|
||||
|
||||
#ifdef WITH_OSL
|
||||
# include "scene/osl.h"
|
||||
# include "render/osl.h"
|
||||
|
||||
# include <OSL/oslconfig.h>
|
||||
# include <OSL/oslquery.h>
|
||||
#endif
|
||||
|
||||
#ifdef WITH_OPENCL
|
||||
# include "device/device_intern.h"
|
||||
#endif
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
namespace {
|
||||
@@ -68,10 +72,12 @@ PyObject *pyunicode_from_string(const char *str)
|
||||
/* Synchronize debug flags from a given Blender scene.
|
||||
* Return truth when device list needs invalidation.
|
||||
*/
|
||||
static void debug_flags_sync_from_scene(BL::Scene b_scene)
|
||||
bool debug_flags_sync_from_scene(BL::Scene b_scene)
|
||||
{
|
||||
DebugFlagsRef flags = DebugFlags();
|
||||
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
|
||||
/* Backup some settings for comparison. */
|
||||
DebugFlags::OpenCL::DeviceType opencl_device_type = flags.opencl.device_type;
|
||||
/* Synchronize shared flags. */
|
||||
flags.viewport_static_bvh = get_enum(cscene, "debug_bvh_type");
|
||||
/* Synchronize CPU flags. */
|
||||
@@ -81,19 +87,50 @@ static void debug_flags_sync_from_scene(BL::Scene b_scene)
|
||||
flags.cpu.sse3 = get_boolean(cscene, "debug_use_cpu_sse3");
|
||||
flags.cpu.sse2 = get_boolean(cscene, "debug_use_cpu_sse2");
|
||||
flags.cpu.bvh_layout = (BVHLayout)get_enum(cscene, "debug_bvh_layout");
|
||||
flags.cpu.split_kernel = get_boolean(cscene, "debug_use_cpu_split_kernel");
|
||||
/* Synchronize CUDA flags. */
|
||||
flags.cuda.adaptive_compile = get_boolean(cscene, "debug_use_cuda_adaptive_compile");
|
||||
flags.cuda.split_kernel = get_boolean(cscene, "debug_use_cuda_split_kernel");
|
||||
/* Synchronize OptiX flags. */
|
||||
flags.optix.use_debug = get_boolean(cscene, "debug_use_optix_debug");
|
||||
flags.optix.cuda_streams = get_int(cscene, "debug_optix_cuda_streams");
|
||||
flags.optix.curves_api = get_boolean(cscene, "debug_optix_curves_api");
|
||||
/* Synchronize OpenCL device type. */
|
||||
switch (get_enum(cscene, "debug_opencl_device_type")) {
|
||||
case 0:
|
||||
flags.opencl.device_type = DebugFlags::OpenCL::DEVICE_NONE;
|
||||
break;
|
||||
case 1:
|
||||
flags.opencl.device_type = DebugFlags::OpenCL::DEVICE_ALL;
|
||||
break;
|
||||
case 2:
|
||||
flags.opencl.device_type = DebugFlags::OpenCL::DEVICE_DEFAULT;
|
||||
break;
|
||||
case 3:
|
||||
flags.opencl.device_type = DebugFlags::OpenCL::DEVICE_CPU;
|
||||
break;
|
||||
case 4:
|
||||
flags.opencl.device_type = DebugFlags::OpenCL::DEVICE_GPU;
|
||||
break;
|
||||
case 5:
|
||||
flags.opencl.device_type = DebugFlags::OpenCL::DEVICE_ACCELERATOR;
|
||||
break;
|
||||
}
|
||||
/* Synchronize other OpenCL flags. */
|
||||
flags.opencl.debug = get_boolean(cscene, "debug_use_opencl_debug");
|
||||
flags.opencl.mem_limit = ((size_t)get_int(cscene, "debug_opencl_mem_limit")) * 1024 * 1024;
|
||||
return flags.opencl.device_type != opencl_device_type;
|
||||
}
|
||||
|
||||
/* Reset debug flags to default values.
|
||||
* Return truth when device list needs invalidation.
|
||||
*/
|
||||
static void debug_flags_reset()
|
||||
bool debug_flags_reset()
|
||||
{
|
||||
DebugFlagsRef flags = DebugFlags();
|
||||
/* Backup some settings for comparison. */
|
||||
DebugFlags::OpenCL::DeviceType opencl_device_type = flags.opencl.device_type;
|
||||
flags.reset();
|
||||
return flags.opencl.device_type != opencl_device_type;
|
||||
}
|
||||
|
||||
} /* namespace */
|
||||
@@ -138,25 +175,25 @@ static const char *PyC_UnicodeAsByte(PyObject *py_str, PyObject **coerce)
|
||||
|
||||
static PyObject *init_func(PyObject * /*self*/, PyObject *args)
|
||||
{
|
||||
PyObject *path, *user_path, *temp_path;
|
||||
PyObject *path, *user_path;
|
||||
int headless;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "OOOi", &path, &user_path, &temp_path, &headless)) {
|
||||
return nullptr;
|
||||
if (!PyArg_ParseTuple(args, "OOi", &path, &user_path, &headless)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PyObject *path_coerce = nullptr, *user_path_coerce = nullptr, *temp_path_coerce = nullptr;
|
||||
PyObject *path_coerce = NULL, *user_path_coerce = NULL;
|
||||
path_init(PyC_UnicodeAsByte(path, &path_coerce),
|
||||
PyC_UnicodeAsByte(user_path, &user_path_coerce),
|
||||
PyC_UnicodeAsByte(temp_path, &temp_path_coerce));
|
||||
PyC_UnicodeAsByte(user_path, &user_path_coerce));
|
||||
Py_XDECREF(path_coerce);
|
||||
Py_XDECREF(user_path_coerce);
|
||||
Py_XDECREF(temp_path_coerce);
|
||||
|
||||
BlenderSession::headless = headless;
|
||||
|
||||
DebugFlags().running_inside_blender = true;
|
||||
|
||||
VLOG(2) << "Debug flags initialized to:\n" << DebugFlags();
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
@@ -262,50 +299,6 @@ static PyObject *render_func(PyObject * /*self*/, PyObject *args)
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *render_frame_finish_func(PyObject * /*self*/, PyObject *args)
|
||||
{
|
||||
PyObject *pysession;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "O", &pysession)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
BlenderSession *session = (BlenderSession *)PyLong_AsVoidPtr(pysession);
|
||||
|
||||
/* Allow Blender to execute other Python scripts. */
|
||||
python_thread_state_save(&session->python_thread_state);
|
||||
|
||||
session->render_frame_finish();
|
||||
|
||||
python_thread_state_restore(&session->python_thread_state);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *draw_func(PyObject * /*self*/, PyObject *args)
|
||||
{
|
||||
PyObject *py_session, *py_graph, *py_screen, *py_space_image;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "OOOO", &py_session, &py_graph, &py_screen, &py_space_image)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
BlenderSession *session = (BlenderSession *)PyLong_AsVoidPtr(py_session);
|
||||
|
||||
ID *b_screen = (ID *)PyLong_AsVoidPtr(py_screen);
|
||||
|
||||
PointerRNA b_space_image_ptr;
|
||||
RNA_pointer_create(b_screen,
|
||||
&RNA_SpaceImageEditor,
|
||||
pylong_as_voidptr_typesafe(py_space_image),
|
||||
&b_space_image_ptr);
|
||||
BL::SpaceImageEditor b_space_image(b_space_image_ptr);
|
||||
|
||||
session->draw(b_space_image);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
/* pixel_array and result passed as pointers */
|
||||
static PyObject *bake_func(PyObject * /*self*/, PyObject *args)
|
||||
{
|
||||
@@ -343,7 +336,7 @@ static PyObject *bake_func(PyObject * /*self*/, PyObject *args)
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *view_draw_func(PyObject * /*self*/, PyObject *args)
|
||||
static PyObject *draw_func(PyObject * /*self*/, PyObject *args)
|
||||
{
|
||||
PyObject *pysession, *pygraph, *pyv3d, *pyrv3d;
|
||||
|
||||
@@ -357,7 +350,7 @@ static PyObject *view_draw_func(PyObject * /*self*/, PyObject *args)
|
||||
int viewport[4];
|
||||
glGetIntegerv(GL_VIEWPORT, viewport);
|
||||
|
||||
session->view_draw(viewport[2], viewport[3]);
|
||||
session->draw(viewport[2], viewport[3]);
|
||||
}
|
||||
|
||||
Py_RETURN_NONE;
|
||||
@@ -704,6 +697,40 @@ static PyObject *system_info_func(PyObject * /*self*/, PyObject * /*value*/)
|
||||
return pyunicode_from_string(system_info.c_str());
|
||||
}
|
||||
|
||||
#ifdef WITH_OPENCL
|
||||
static PyObject *opencl_disable_func(PyObject * /*self*/, PyObject * /*value*/)
|
||||
{
|
||||
VLOG(2) << "Disabling OpenCL platform.";
|
||||
DebugFlags().opencl.device_type = DebugFlags::OpenCL::DEVICE_NONE;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *opencl_compile_func(PyObject * /*self*/, PyObject *args)
|
||||
{
|
||||
PyObject *sequence = PySequence_Fast(args, "Arguments must be a sequence");
|
||||
if (sequence == NULL) {
|
||||
Py_RETURN_FALSE;
|
||||
}
|
||||
|
||||
vector<string> parameters;
|
||||
for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(sequence); i++) {
|
||||
PyObject *item = PySequence_Fast_GET_ITEM(sequence, i);
|
||||
PyObject *item_as_string = PyObject_Str(item);
|
||||
const char *parameter_string = PyUnicode_AsUTF8(item_as_string);
|
||||
parameters.push_back(parameter_string);
|
||||
Py_DECREF(item_as_string);
|
||||
}
|
||||
Py_DECREF(sequence);
|
||||
|
||||
if (device_opencl_compile_kernel(parameters)) {
|
||||
Py_RETURN_TRUE;
|
||||
}
|
||||
else {
|
||||
Py_RETURN_FALSE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool image_parse_filepaths(PyObject *pyfilepaths, vector<string> &filepaths)
|
||||
{
|
||||
if (PyUnicode_Check(pyfilepaths)) {
|
||||
@@ -735,10 +762,6 @@ static bool image_parse_filepaths(PyObject *pyfilepaths, vector<string> &filepat
|
||||
|
||||
static PyObject *denoise_func(PyObject * /*self*/, PyObject *args, PyObject *keywords)
|
||||
{
|
||||
#if 1
|
||||
(void)args;
|
||||
(void)keywords;
|
||||
#else
|
||||
static const char *keyword_list[] = {
|
||||
"preferences", "scene", "view_layer", "input", "output", "tile_size", "samples", NULL};
|
||||
PyObject *pypreferences, *pyscene, *pyviewlayer;
|
||||
@@ -812,7 +835,7 @@ static PyObject *denoise_func(PyObject * /*self*/, PyObject *args, PyObject *key
|
||||
}
|
||||
|
||||
/* Create denoiser. */
|
||||
DenoiserPipeline denoiser(device);
|
||||
Denoiser denoiser(device);
|
||||
denoiser.params = params;
|
||||
denoiser.input = input;
|
||||
denoiser.output = output;
|
||||
@@ -829,7 +852,6 @@ static PyObject *denoise_func(PyObject * /*self*/, PyObject *args, PyObject *key
|
||||
PyErr_SetString(PyExc_ValueError, denoiser.error.c_str());
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
@@ -881,7 +903,12 @@ static PyObject *debug_flags_update_func(PyObject * /*self*/, PyObject *args)
|
||||
RNA_id_pointer_create((ID *)PyLong_AsVoidPtr(pyscene), &sceneptr);
|
||||
BL::Scene b_scene(sceneptr);
|
||||
|
||||
debug_flags_sync_from_scene(b_scene);
|
||||
if (debug_flags_sync_from_scene(b_scene)) {
|
||||
VLOG(2) << "Tagging device list for update.";
|
||||
Device::tag_update();
|
||||
}
|
||||
|
||||
VLOG(2) << "Debug flags set to:\n" << DebugFlags();
|
||||
|
||||
debug_flags_set = true;
|
||||
|
||||
@@ -890,13 +917,95 @@ static PyObject *debug_flags_update_func(PyObject * /*self*/, PyObject *args)
|
||||
|
||||
static PyObject *debug_flags_reset_func(PyObject * /*self*/, PyObject * /*args*/)
|
||||
{
|
||||
debug_flags_reset();
|
||||
if (debug_flags_reset()) {
|
||||
VLOG(2) << "Tagging device list for update.";
|
||||
Device::tag_update();
|
||||
}
|
||||
if (debug_flags_set) {
|
||||
VLOG(2) << "Debug flags reset to:\n" << DebugFlags();
|
||||
debug_flags_set = false;
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *set_resumable_chunk_func(PyObject * /*self*/, PyObject *args)
|
||||
{
|
||||
int num_resumable_chunks, current_resumable_chunk;
|
||||
if (!PyArg_ParseTuple(args, "ii", &num_resumable_chunks, ¤t_resumable_chunk)) {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
if (num_resumable_chunks <= 0) {
|
||||
fprintf(stderr, "Cycles: Bad value for number of resumable chunks.\n");
|
||||
abort();
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
if (current_resumable_chunk < 1 || current_resumable_chunk > num_resumable_chunks) {
|
||||
fprintf(stderr, "Cycles: Bad value for current resumable chunk number.\n");
|
||||
abort();
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
VLOG(1) << "Initialized resumable render: "
|
||||
<< "num_resumable_chunks=" << num_resumable_chunks << ", "
|
||||
<< "current_resumable_chunk=" << current_resumable_chunk;
|
||||
BlenderSession::num_resumable_chunks = num_resumable_chunks;
|
||||
BlenderSession::current_resumable_chunk = current_resumable_chunk;
|
||||
|
||||
printf("Cycles: Will render chunk %d of %d\n", current_resumable_chunk, num_resumable_chunks);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *set_resumable_chunk_range_func(PyObject * /*self*/, PyObject *args)
|
||||
{
|
||||
int num_chunks, start_chunk, end_chunk;
|
||||
if (!PyArg_ParseTuple(args, "iii", &num_chunks, &start_chunk, &end_chunk)) {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
if (num_chunks <= 0) {
|
||||
fprintf(stderr, "Cycles: Bad value for number of resumable chunks.\n");
|
||||
abort();
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
if (start_chunk < 1 || start_chunk > num_chunks) {
|
||||
fprintf(stderr, "Cycles: Bad value for start chunk number.\n");
|
||||
abort();
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
if (end_chunk < 1 || end_chunk > num_chunks) {
|
||||
fprintf(stderr, "Cycles: Bad value for start chunk number.\n");
|
||||
abort();
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
if (start_chunk > end_chunk) {
|
||||
fprintf(stderr, "Cycles: End chunk should be higher than start one.\n");
|
||||
abort();
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
VLOG(1) << "Initialized resumable render: "
|
||||
<< "num_resumable_chunks=" << num_chunks << ", "
|
||||
<< "start_resumable_chunk=" << start_chunk << "end_resumable_chunk=" << end_chunk;
|
||||
BlenderSession::num_resumable_chunks = num_chunks;
|
||||
BlenderSession::start_resumable_chunk = start_chunk;
|
||||
BlenderSession::end_resumable_chunk = end_chunk;
|
||||
|
||||
printf("Cycles: Will render chunks %d to %d of %d\n", start_chunk, end_chunk, num_chunks);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *clear_resumable_chunk_func(PyObject * /*self*/, PyObject * /*value*/)
|
||||
{
|
||||
VLOG(1) << "Clear resumable render";
|
||||
BlenderSession::num_resumable_chunks = 0;
|
||||
BlenderSession::current_resumable_chunk = 0;
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *enable_print_stats_func(PyObject * /*self*/, PyObject * /*args*/)
|
||||
{
|
||||
BlenderSession::print_render_stats = true;
|
||||
@@ -906,16 +1015,16 @@ static PyObject *enable_print_stats_func(PyObject * /*self*/, PyObject * /*args*
|
||||
static PyObject *get_device_types_func(PyObject * /*self*/, PyObject * /*args*/)
|
||||
{
|
||||
vector<DeviceType> device_types = Device::available_types();
|
||||
bool has_cuda = false, has_optix = false, has_hip = false;
|
||||
bool has_cuda = false, has_optix = false, has_opencl = false;
|
||||
foreach (DeviceType device_type, device_types) {
|
||||
has_cuda |= (device_type == DEVICE_CUDA);
|
||||
has_optix |= (device_type == DEVICE_OPTIX);
|
||||
has_hip |= (device_type == DEVICE_HIP);
|
||||
has_opencl |= (device_type == DEVICE_OPENCL);
|
||||
}
|
||||
PyObject *list = PyTuple_New(3);
|
||||
PyTuple_SET_ITEM(list, 0, PyBool_FromLong(has_cuda));
|
||||
PyTuple_SET_ITEM(list, 1, PyBool_FromLong(has_optix));
|
||||
PyTuple_SET_ITEM(list, 2, PyBool_FromLong(has_hip));
|
||||
PyTuple_SET_ITEM(list, 2, PyBool_FromLong(has_opencl));
|
||||
return list;
|
||||
}
|
||||
|
||||
@@ -935,15 +1044,15 @@ static PyObject *set_device_override_func(PyObject * /*self*/, PyObject *arg)
|
||||
if (override == "CPU") {
|
||||
BlenderSession::device_override = DEVICE_MASK_CPU;
|
||||
}
|
||||
else if (override == "OPENCL") {
|
||||
BlenderSession::device_override = DEVICE_MASK_OPENCL;
|
||||
}
|
||||
else if (override == "CUDA") {
|
||||
BlenderSession::device_override = DEVICE_MASK_CUDA;
|
||||
}
|
||||
else if (override == "OPTIX") {
|
||||
BlenderSession::device_override = DEVICE_MASK_OPTIX;
|
||||
}
|
||||
else if (override == "HIP") {
|
||||
BlenderSession::device_override = DEVICE_MASK_HIP;
|
||||
}
|
||||
else {
|
||||
printf("\nError: %s is not a valid Cycles device.\n", override.c_str());
|
||||
Py_RETURN_FALSE;
|
||||
@@ -963,10 +1072,8 @@ static PyMethodDef methods[] = {
|
||||
{"create", create_func, METH_VARARGS, ""},
|
||||
{"free", free_func, METH_O, ""},
|
||||
{"render", render_func, METH_VARARGS, ""},
|
||||
{"render_frame_finish", render_frame_finish_func, METH_VARARGS, ""},
|
||||
{"draw", draw_func, METH_VARARGS, ""},
|
||||
{"bake", bake_func, METH_VARARGS, ""},
|
||||
{"view_draw", view_draw_func, METH_VARARGS, ""},
|
||||
{"draw", draw_func, METH_VARARGS, ""},
|
||||
{"sync", sync_func, METH_VARARGS, ""},
|
||||
{"reset", reset_func, METH_VARARGS, ""},
|
||||
#ifdef WITH_OSL
|
||||
@@ -975,6 +1082,10 @@ static PyMethodDef methods[] = {
|
||||
#endif
|
||||
{"available_devices", available_devices_func, METH_VARARGS, ""},
|
||||
{"system_info", system_info_func, METH_NOARGS, ""},
|
||||
#ifdef WITH_OPENCL
|
||||
{"opencl_disable", opencl_disable_func, METH_NOARGS, ""},
|
||||
{"opencl_compile", opencl_compile_func, METH_VARARGS, ""},
|
||||
#endif
|
||||
|
||||
/* Standalone denoising */
|
||||
{"denoise", (PyCFunction)denoise_func, METH_VARARGS | METH_KEYWORDS, ""},
|
||||
@@ -987,6 +1098,11 @@ static PyMethodDef methods[] = {
|
||||
/* Statistics. */
|
||||
{"enable_print_stats", enable_print_stats_func, METH_NOARGS, ""},
|
||||
|
||||
/* Resumable render */
|
||||
{"set_resumable_chunk", set_resumable_chunk_func, METH_VARARGS, ""},
|
||||
{"set_resumable_chunk_range", set_resumable_chunk_range_func, METH_VARARGS, ""},
|
||||
{"clear_resumable_chunk", clear_resumable_chunk_func, METH_NOARGS, ""},
|
||||
|
||||
/* Compute Device selection */
|
||||
{"get_device_types", get_device_types_func, METH_VARARGS, ""},
|
||||
{"set_device_override", set_device_override_func, METH_O, ""},
|
||||
@@ -1037,6 +1153,14 @@ void *CCL_python_module_init()
|
||||
PyModule_AddStringConstant(mod, "osl_version_string", "unknown");
|
||||
#endif
|
||||
|
||||
#ifdef WITH_NETWORK
|
||||
PyModule_AddObject(mod, "with_network", Py_True);
|
||||
Py_INCREF(Py_True);
|
||||
#else /* WITH_NETWORK */
|
||||
PyModule_AddObject(mod, "with_network", Py_False);
|
||||
Py_INCREF(Py_False);
|
||||
#endif /* WITH_NETWORK */
|
||||
|
||||
#ifdef WITH_EMBREE
|
||||
PyModule_AddObject(mod, "with_embree", Py_True);
|
||||
Py_INCREF(Py_True);
|
File diff suppressed because it is too large
Load Diff
@@ -17,25 +17,24 @@
|
||||
#ifndef __BLENDER_SESSION_H__
|
||||
#define __BLENDER_SESSION_H__
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "RNA_blender_cpp.h"
|
||||
|
||||
#include "device/device.h"
|
||||
|
||||
#include "scene/bake.h"
|
||||
#include "scene/scene.h"
|
||||
#include "session/session.h"
|
||||
#include "render/bake.h"
|
||||
#include "render/scene.h"
|
||||
#include "render/session.h"
|
||||
|
||||
#include "util/vector.h"
|
||||
#include "util/util_vector.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
class BlenderDisplayDriver;
|
||||
class BlenderSync;
|
||||
class ImageMetaData;
|
||||
class Scene;
|
||||
class Session;
|
||||
class RenderBuffers;
|
||||
class RenderTile;
|
||||
|
||||
class BlenderSession {
|
||||
public:
|
||||
@@ -63,8 +62,6 @@ class BlenderSession {
|
||||
/* offline render */
|
||||
void render(BL::Depsgraph &b_depsgraph);
|
||||
|
||||
void render_frame_finish();
|
||||
|
||||
void bake(BL::Depsgraph &b_depsgrah,
|
||||
BL::Object &b_object,
|
||||
const string &pass_type,
|
||||
@@ -72,16 +69,24 @@ class BlenderSession {
|
||||
const int bake_width,
|
||||
const int bake_height);
|
||||
|
||||
void full_buffer_written(string_view filename);
|
||||
void write_render_result(BL::RenderLayer &b_rlay, RenderTile &rtile);
|
||||
void write_render_tile(RenderTile &rtile);
|
||||
void read_render_tile(RenderTile &rtile);
|
||||
|
||||
/* update functions are used to update display buffer only after sample was rendered
|
||||
* only needed for better visual feedback */
|
||||
void update_render_result(BL::RenderLayer &b_rlay, RenderTile &rtile);
|
||||
void update_render_tile(RenderTile &rtile, bool highlight);
|
||||
|
||||
/* interactive updates */
|
||||
void synchronize(BL::Depsgraph &b_depsgraph);
|
||||
|
||||
/* drawing */
|
||||
void draw(BL::SpaceImageEditor &space_image);
|
||||
void view_draw(int w, int h);
|
||||
bool draw(int w, int h);
|
||||
void tag_redraw();
|
||||
void tag_update();
|
||||
void get_status(string &status, string &substatus);
|
||||
void get_kernel_status(string &kernel_status);
|
||||
void get_progress(float &progress, double &total_time, double &render_time);
|
||||
void test_cancel();
|
||||
void update_status_progress();
|
||||
@@ -99,7 +104,8 @@ class BlenderSession {
|
||||
BL::RenderSettings b_render;
|
||||
BL::Depsgraph b_depsgraph;
|
||||
/* NOTE: Blender's scene might become invalid after call
|
||||
* #free_blender_memory_if_possible(). */
|
||||
* free_blender_memory_if_possible().
|
||||
*/
|
||||
BL::Scene b_scene;
|
||||
BL::SpaceView3D b_v3d;
|
||||
BL::RegionView3D b_rv3d;
|
||||
@@ -117,8 +123,6 @@ class BlenderSession {
|
||||
|
||||
void *python_thread_state;
|
||||
|
||||
bool use_developer_ui;
|
||||
|
||||
/* Global state which is common for all render sessions created from Blender.
|
||||
* Usually denotes command line arguments.
|
||||
*/
|
||||
@@ -130,35 +134,41 @@ class BlenderSession {
|
||||
*/
|
||||
static bool headless;
|
||||
|
||||
/* ** Resumable render ** */
|
||||
|
||||
/* Overall number of chunks in which the sample range is to be divided. */
|
||||
static int num_resumable_chunks;
|
||||
|
||||
/* Current resumable chunk index to render. */
|
||||
static int current_resumable_chunk;
|
||||
|
||||
/* Alternative to single-chunk rendering to render a range of chunks. */
|
||||
static int start_resumable_chunk;
|
||||
static int end_resumable_chunk;
|
||||
|
||||
static bool print_render_stats;
|
||||
|
||||
protected:
|
||||
void stamp_view_layer_metadata(Scene *scene, const string &view_layer_name);
|
||||
|
||||
/* Check whether session error happened.
|
||||
* If so, it is reported to the render engine and true is returned.
|
||||
* Otherwise false is returned. */
|
||||
bool check_and_report_session_error();
|
||||
void do_write_update_render_result(BL::RenderLayer &b_rlay,
|
||||
RenderTile &rtile,
|
||||
bool do_update_only);
|
||||
void do_write_update_render_tile(RenderTile &rtile,
|
||||
bool do_update_only,
|
||||
bool do_read_only,
|
||||
bool highlight);
|
||||
|
||||
void builtin_images_load();
|
||||
|
||||
/* Update tile manager to reflect resumable render settings. */
|
||||
void update_resumable_tile_manager(int num_samples);
|
||||
|
||||
/* Is used after each render layer synchronization is done with the goal
|
||||
* of freeing render engine data which is held from Blender side (for
|
||||
* example, dependency graph).
|
||||
*/
|
||||
void free_blender_memory_if_possible();
|
||||
|
||||
void ensure_display_driver_if_needed();
|
||||
|
||||
struct {
|
||||
thread_mutex mutex;
|
||||
int last_pass_index = -1;
|
||||
} draw_state_;
|
||||
|
||||
/* NOTE: The BlenderSession references the display driver. */
|
||||
BlenderDisplayDriver *display_driver_ = nullptr;
|
||||
|
||||
vector<string> full_buffer_files_;
|
||||
};
|
||||
|
||||
CCL_NAMESPACE_END
|
@@ -14,26 +14,25 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "scene/shader.h"
|
||||
#include "scene/background.h"
|
||||
#include "scene/colorspace.h"
|
||||
#include "scene/integrator.h"
|
||||
#include "scene/light.h"
|
||||
#include "scene/osl.h"
|
||||
#include "scene/scene.h"
|
||||
#include "scene/shader_graph.h"
|
||||
#include "scene/shader_nodes.h"
|
||||
#include "render/background.h"
|
||||
#include "render/colorspace.h"
|
||||
#include "render/graph.h"
|
||||
#include "render/light.h"
|
||||
#include "render/nodes.h"
|
||||
#include "render/osl.h"
|
||||
#include "render/scene.h"
|
||||
#include "render/shader.h"
|
||||
|
||||
#include "blender/image.h"
|
||||
#include "blender/sync.h"
|
||||
#include "blender/texture.h"
|
||||
#include "blender/util.h"
|
||||
#include "blender/blender_image.h"
|
||||
#include "blender/blender_sync.h"
|
||||
#include "blender/blender_texture.h"
|
||||
#include "blender/blender_util.h"
|
||||
|
||||
#include "util/debug.h"
|
||||
#include "util/foreach.h"
|
||||
#include "util/set.h"
|
||||
#include "util/string.h"
|
||||
#include "util/task.h"
|
||||
#include "util/util_debug.h"
|
||||
#include "util/util_foreach.h"
|
||||
#include "util/util_set.h"
|
||||
#include "util/util_string.h"
|
||||
#include "util/util_task.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
@@ -279,7 +278,7 @@ static ShaderNode *add_node(Scene *scene,
|
||||
array<float3> curve_mapping_curves;
|
||||
float min_x, max_x;
|
||||
curvemapping_color_to_array(mapping, curve_mapping_curves, RAMP_TABLE_SIZE, true);
|
||||
curvemapping_minmax(mapping, 4, &min_x, &max_x);
|
||||
curvemapping_minmax(mapping, true, &min_x, &max_x);
|
||||
curves->set_min_x(min_x);
|
||||
curves->set_max_x(max_x);
|
||||
curves->set_curves(curve_mapping_curves);
|
||||
@@ -292,25 +291,12 @@ static ShaderNode *add_node(Scene *scene,
|
||||
array<float3> curve_mapping_curves;
|
||||
float min_x, max_x;
|
||||
curvemapping_color_to_array(mapping, curve_mapping_curves, RAMP_TABLE_SIZE, false);
|
||||
curvemapping_minmax(mapping, 3, &min_x, &max_x);
|
||||
curvemapping_minmax(mapping, false, &min_x, &max_x);
|
||||
curves->set_min_x(min_x);
|
||||
curves->set_max_x(max_x);
|
||||
curves->set_curves(curve_mapping_curves);
|
||||
node = curves;
|
||||
}
|
||||
else if (b_node.is_a(&RNA_ShaderNodeFloatCurve)) {
|
||||
BL::ShaderNodeFloatCurve b_curve_node(b_node);
|
||||
BL::CurveMapping mapping(b_curve_node.mapping());
|
||||
FloatCurveNode *curve = graph->create_node<FloatCurveNode>();
|
||||
array<float> curve_mapping_curve;
|
||||
float min_x, max_x;
|
||||
curvemapping_float_to_array(mapping, curve_mapping_curve, RAMP_TABLE_SIZE);
|
||||
curvemapping_minmax(mapping, 1, &min_x, &max_x);
|
||||
curve->set_min_x(min_x);
|
||||
curve->set_max_x(max_x);
|
||||
curve->set_curve(curve_mapping_curve);
|
||||
node = curve;
|
||||
}
|
||||
else if (b_node.is_a(&RNA_ShaderNodeValToRGB)) {
|
||||
RGBRampNode *ramp = graph->create_node<RGBRampNode>();
|
||||
BL::ShaderNodeValToRGB b_ramp_node(b_node);
|
||||
@@ -489,14 +475,17 @@ static ShaderNode *add_node(Scene *scene,
|
||||
SubsurfaceScatteringNode *subsurface = graph->create_node<SubsurfaceScatteringNode>();
|
||||
|
||||
switch (b_subsurface_node.falloff()) {
|
||||
case BL::ShaderNodeSubsurfaceScattering::falloff_BURLEY:
|
||||
subsurface->set_method(CLOSURE_BSSRDF_BURLEY_ID);
|
||||
case BL::ShaderNodeSubsurfaceScattering::falloff_CUBIC:
|
||||
subsurface->set_falloff(CLOSURE_BSSRDF_CUBIC_ID);
|
||||
break;
|
||||
case BL::ShaderNodeSubsurfaceScattering::falloff_RANDOM_WALK_FIXED_RADIUS:
|
||||
subsurface->set_method(CLOSURE_BSSRDF_RANDOM_WALK_FIXED_RADIUS_ID);
|
||||
case BL::ShaderNodeSubsurfaceScattering::falloff_GAUSSIAN:
|
||||
subsurface->set_falloff(CLOSURE_BSSRDF_GAUSSIAN_ID);
|
||||
break;
|
||||
case BL::ShaderNodeSubsurfaceScattering::falloff_BURLEY:
|
||||
subsurface->set_falloff(CLOSURE_BSSRDF_BURLEY_ID);
|
||||
break;
|
||||
case BL::ShaderNodeSubsurfaceScattering::falloff_RANDOM_WALK:
|
||||
subsurface->set_method(CLOSURE_BSSRDF_RANDOM_WALK_ID);
|
||||
subsurface->set_falloff(CLOSURE_BSSRDF_RANDOM_WALK_ID);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -609,13 +598,10 @@ static ShaderNode *add_node(Scene *scene,
|
||||
}
|
||||
switch (b_principled_node.subsurface_method()) {
|
||||
case BL::ShaderNodeBsdfPrincipled::subsurface_method_BURLEY:
|
||||
principled->set_subsurface_method(CLOSURE_BSSRDF_BURLEY_ID);
|
||||
break;
|
||||
case BL::ShaderNodeBsdfPrincipled::subsurface_method_RANDOM_WALK_FIXED_RADIUS:
|
||||
principled->set_subsurface_method(CLOSURE_BSSRDF_RANDOM_WALK_FIXED_RADIUS_ID);
|
||||
principled->set_subsurface_method(CLOSURE_BSSRDF_PRINCIPLED_ID);
|
||||
break;
|
||||
case BL::ShaderNodeBsdfPrincipled::subsurface_method_RANDOM_WALK:
|
||||
principled->set_subsurface_method(CLOSURE_BSSRDF_RANDOM_WALK_ID);
|
||||
principled->set_subsurface_method(CLOSURE_BSSRDF_PRINCIPLED_RANDOM_WALK_ID);
|
||||
break;
|
||||
}
|
||||
node = principled;
|
||||
@@ -1374,12 +1360,10 @@ void BlenderSync::sync_materials(BL::Depsgraph &b_depsgraph, bool update_all)
|
||||
void BlenderSync::sync_world(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d, bool update_all)
|
||||
{
|
||||
Background *background = scene->background;
|
||||
Integrator *integrator = scene->integrator;
|
||||
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
|
||||
|
||||
BL::World b_world = b_scene.world();
|
||||
|
||||
BlenderViewportParameters new_viewport_parameters(b_v3d, use_developer_ui);
|
||||
BlenderViewportParameters new_viewport_parameters(b_v3d);
|
||||
|
||||
if (world_recalc || update_all || b_world.ptr.data != world_map ||
|
||||
viewport_parameters.shader_modified(new_viewport_parameters)) {
|
||||
@@ -1467,8 +1451,15 @@ void BlenderSync::sync_world(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d,
|
||||
graph->connect(background->output("Background"), out->input("Surface"));
|
||||
}
|
||||
|
||||
/* Visibility */
|
||||
if (b_world) {
|
||||
/* AO */
|
||||
BL::WorldLighting b_light = b_world.light_settings();
|
||||
|
||||
background->set_use_ao(b_light.use_ambient_occlusion());
|
||||
background->set_ao_factor(b_light.ao_factor());
|
||||
background->set_ao_distance(b_light.distance());
|
||||
|
||||
/* visibility */
|
||||
PointerRNA cvisibility = RNA_pointer_get(&b_world.ptr, "cycles_visibility");
|
||||
uint visibility = 0;
|
||||
|
||||
@@ -1480,38 +1471,17 @@ void BlenderSync::sync_world(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d,
|
||||
|
||||
background->set_visibility(visibility);
|
||||
}
|
||||
else {
|
||||
background->set_use_ao(false);
|
||||
background->set_ao_factor(0.0f);
|
||||
background->set_ao_distance(FLT_MAX);
|
||||
}
|
||||
|
||||
shader->set_graph(graph);
|
||||
shader->tag_update(scene);
|
||||
}
|
||||
|
||||
/* Fast GI */
|
||||
if (b_world) {
|
||||
BL::WorldLighting b_light = b_world.light_settings();
|
||||
enum { FAST_GI_METHOD_REPLACE = 0, FAST_GI_METHOD_ADD = 1, FAST_GI_METHOD_NUM };
|
||||
|
||||
const bool use_fast_gi = get_boolean(cscene, "use_fast_gi");
|
||||
if (use_fast_gi) {
|
||||
const int fast_gi_method = get_enum(
|
||||
cscene, "fast_gi_method", FAST_GI_METHOD_NUM, FAST_GI_METHOD_REPLACE);
|
||||
integrator->set_ao_factor((fast_gi_method == FAST_GI_METHOD_REPLACE) ? b_light.ao_factor() :
|
||||
0.0f);
|
||||
integrator->set_ao_additive_factor(
|
||||
(fast_gi_method == FAST_GI_METHOD_ADD) ? b_light.ao_factor() : 0.0f);
|
||||
}
|
||||
else {
|
||||
integrator->set_ao_factor(0.0f);
|
||||
integrator->set_ao_additive_factor(0.0f);
|
||||
}
|
||||
|
||||
integrator->set_ao_distance(b_light.distance());
|
||||
}
|
||||
else {
|
||||
integrator->set_ao_factor(0.0f);
|
||||
integrator->set_ao_additive_factor(0.0f);
|
||||
integrator->set_ao_distance(10.0f);
|
||||
}
|
||||
|
||||
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
|
||||
background->set_transparent(b_scene.render().film_transparent());
|
||||
|
||||
if (background->get_transparent()) {
|
||||
@@ -1526,6 +1496,7 @@ void BlenderSync::sync_world(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d,
|
||||
|
||||
background->set_use_shader(view_layer.use_background_shader ||
|
||||
viewport_parameters.use_custom_shader());
|
||||
background->set_use_ao(background->get_use_ao() && view_layer.use_background_ao);
|
||||
|
||||
background->tag_update(scene);
|
||||
}
|
@@ -14,33 +14,33 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "scene/background.h"
|
||||
#include "scene/camera.h"
|
||||
#include "scene/curves.h"
|
||||
#include "scene/film.h"
|
||||
#include "scene/integrator.h"
|
||||
#include "scene/light.h"
|
||||
#include "scene/mesh.h"
|
||||
#include "scene/object.h"
|
||||
#include "scene/procedural.h"
|
||||
#include "scene/scene.h"
|
||||
#include "scene/shader.h"
|
||||
#include "scene/shader_graph.h"
|
||||
#include "scene/shader_nodes.h"
|
||||
#include "render/background.h"
|
||||
#include "render/camera.h"
|
||||
#include "render/curves.h"
|
||||
#include "render/film.h"
|
||||
#include "render/graph.h"
|
||||
#include "render/integrator.h"
|
||||
#include "render/light.h"
|
||||
#include "render/mesh.h"
|
||||
#include "render/nodes.h"
|
||||
#include "render/object.h"
|
||||
#include "render/procedural.h"
|
||||
#include "render/scene.h"
|
||||
#include "render/shader.h"
|
||||
|
||||
#include "device/device.h"
|
||||
|
||||
#include "blender/device.h"
|
||||
#include "blender/session.h"
|
||||
#include "blender/sync.h"
|
||||
#include "blender/util.h"
|
||||
#include "blender/blender_device.h"
|
||||
#include "blender/blender_session.h"
|
||||
#include "blender/blender_sync.h"
|
||||
#include "blender/blender_util.h"
|
||||
|
||||
#include "util/debug.h"
|
||||
#include "util/foreach.h"
|
||||
#include "util/hash.h"
|
||||
#include "util/log.h"
|
||||
#include "util/opengl.h"
|
||||
#include "util/openimagedenoise.h"
|
||||
#include "util/util_debug.h"
|
||||
#include "util/util_foreach.h"
|
||||
#include "util/util_hash.h"
|
||||
#include "util/util_logging.h"
|
||||
#include "util/util_opengl.h"
|
||||
#include "util/util_openimagedenoise.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
@@ -53,7 +53,6 @@ BlenderSync::BlenderSync(BL::RenderEngine &b_engine,
|
||||
BL::Scene &b_scene,
|
||||
Scene *scene,
|
||||
bool preview,
|
||||
bool use_developer_ui,
|
||||
Progress &progress)
|
||||
: b_engine(b_engine),
|
||||
b_data(b_data),
|
||||
@@ -69,7 +68,6 @@ BlenderSync::BlenderSync(BL::RenderEngine &b_engine,
|
||||
scene(scene),
|
||||
preview(preview),
|
||||
experimental(false),
|
||||
use_developer_ui(use_developer_ui),
|
||||
dicing_rate(1.0f),
|
||||
max_subdivisions(12),
|
||||
progress(progress),
|
||||
@@ -183,15 +181,6 @@ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d
|
||||
(object_subdivision_type(b_ob, preview, experimental) != Mesh::SUBDIVISION_NONE)) {
|
||||
BL::ID key = BKE_object_is_modified(b_ob) ? b_ob : b_ob.data();
|
||||
geometry_map.set_recalc(key);
|
||||
|
||||
/* Sync all contained geometry instances as well when the object changed.. */
|
||||
map<void *, set<BL::ID>>::const_iterator instance_geometries =
|
||||
instance_geometries_by_object.find(b_ob.ptr.data);
|
||||
if (instance_geometries != instance_geometries_by_object.end()) {
|
||||
for (BL::ID geometry : instance_geometries->second) {
|
||||
geometry_map.set_recalc(geometry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (updated_geometry) {
|
||||
@@ -235,7 +224,7 @@ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d
|
||||
}
|
||||
|
||||
if (b_v3d) {
|
||||
BlenderViewportParameters new_viewport_parameters(b_v3d, use_developer_ui);
|
||||
BlenderViewportParameters new_viewport_parameters(b_v3d);
|
||||
|
||||
if (viewport_parameters.shader_modified(new_viewport_parameters)) {
|
||||
world_recalc = true;
|
||||
@@ -262,13 +251,9 @@ void BlenderSync::sync_data(BL::RenderSettings &b_render,
|
||||
|
||||
BL::ViewLayer b_view_layer = b_depsgraph.view_layer_eval();
|
||||
|
||||
/* TODO(sergey): This feels weak to pass view layer to the integrator, and even weaker to have an
|
||||
* implicit check on whether it is a background render or not. What is the nicer thing here? */
|
||||
const bool background = !b_v3d;
|
||||
|
||||
sync_view_layer(b_view_layer);
|
||||
sync_integrator(b_view_layer, background);
|
||||
sync_film(b_view_layer, b_v3d);
|
||||
sync_integrator();
|
||||
sync_film(b_v3d);
|
||||
sync_shaders(b_depsgraph, b_v3d);
|
||||
sync_images();
|
||||
|
||||
@@ -295,7 +280,7 @@ void BlenderSync::sync_data(BL::RenderSettings &b_render,
|
||||
|
||||
/* Integrator */
|
||||
|
||||
void BlenderSync::sync_integrator(BL::ViewLayer &b_view_layer, bool background)
|
||||
void BlenderSync::sync_integrator()
|
||||
{
|
||||
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
|
||||
|
||||
@@ -343,42 +328,58 @@ void BlenderSync::sync_integrator(BL::ViewLayer &b_view_layer, bool background)
|
||||
integrator->set_motion_blur(view_layer.use_motion_blur);
|
||||
}
|
||||
|
||||
integrator->set_method((Integrator::Method)get_enum(
|
||||
cscene, "progressive", Integrator::NUM_METHODS, Integrator::PATH));
|
||||
|
||||
integrator->set_sample_all_lights_direct(get_boolean(cscene, "sample_all_lights_direct"));
|
||||
integrator->set_sample_all_lights_indirect(get_boolean(cscene, "sample_all_lights_indirect"));
|
||||
integrator->set_light_sampling_threshold(get_float(cscene, "light_sampling_threshold"));
|
||||
|
||||
SamplingPattern sampling_pattern = (SamplingPattern)get_enum(
|
||||
cscene, "sampling_pattern", SAMPLING_NUM_PATTERNS, SAMPLING_PATTERN_SOBOL);
|
||||
integrator->set_sampling_pattern(sampling_pattern);
|
||||
|
||||
bool use_adaptive_sampling = false;
|
||||
if (preview) {
|
||||
use_adaptive_sampling = RNA_boolean_get(&cscene, "use_preview_adaptive_sampling");
|
||||
integrator->set_use_adaptive_sampling(use_adaptive_sampling);
|
||||
integrator->set_adaptive_threshold(get_float(cscene, "preview_adaptive_threshold"));
|
||||
integrator->set_adaptive_min_samples(get_int(cscene, "preview_adaptive_min_samples"));
|
||||
int adaptive_min_samples = INT_MAX;
|
||||
|
||||
if (RNA_boolean_get(&cscene, "use_adaptive_sampling")) {
|
||||
sampling_pattern = SAMPLING_PATTERN_PMJ;
|
||||
adaptive_min_samples = get_int(cscene, "adaptive_min_samples");
|
||||
integrator->set_adaptive_threshold(get_float(cscene, "adaptive_threshold"));
|
||||
}
|
||||
else {
|
||||
use_adaptive_sampling = RNA_boolean_get(&cscene, "use_adaptive_sampling");
|
||||
integrator->set_use_adaptive_sampling(use_adaptive_sampling);
|
||||
integrator->set_adaptive_threshold(get_float(cscene, "adaptive_threshold"));
|
||||
integrator->set_adaptive_min_samples(get_int(cscene, "adaptive_min_samples"));
|
||||
integrator->set_adaptive_threshold(0.0f);
|
||||
}
|
||||
|
||||
int samples = get_int(cscene, "samples");
|
||||
float scrambling_distance = get_float(cscene, "scrambling_distance");
|
||||
bool adaptive_scrambling_distance = get_boolean(cscene, "adaptive_scrambling_distance");
|
||||
if (adaptive_scrambling_distance) {
|
||||
scrambling_distance *= 4.0f / sqrtf(samples);
|
||||
integrator->set_sampling_pattern(sampling_pattern);
|
||||
|
||||
int diffuse_samples = get_int(cscene, "diffuse_samples");
|
||||
int glossy_samples = get_int(cscene, "glossy_samples");
|
||||
int transmission_samples = get_int(cscene, "transmission_samples");
|
||||
int ao_samples = get_int(cscene, "ao_samples");
|
||||
int mesh_light_samples = get_int(cscene, "mesh_light_samples");
|
||||
int subsurface_samples = get_int(cscene, "subsurface_samples");
|
||||
int volume_samples = get_int(cscene, "volume_samples");
|
||||
|
||||
if (get_boolean(cscene, "use_square_samples")) {
|
||||
integrator->set_diffuse_samples(diffuse_samples * diffuse_samples);
|
||||
integrator->set_glossy_samples(glossy_samples * glossy_samples);
|
||||
integrator->set_transmission_samples(transmission_samples * transmission_samples);
|
||||
integrator->set_ao_samples(ao_samples * ao_samples);
|
||||
integrator->set_mesh_light_samples(mesh_light_samples * mesh_light_samples);
|
||||
integrator->set_subsurface_samples(subsurface_samples * subsurface_samples);
|
||||
integrator->set_volume_samples(volume_samples * volume_samples);
|
||||
adaptive_min_samples = min(adaptive_min_samples * adaptive_min_samples, INT_MAX);
|
||||
}
|
||||
else {
|
||||
integrator->set_diffuse_samples(diffuse_samples);
|
||||
integrator->set_glossy_samples(glossy_samples);
|
||||
integrator->set_transmission_samples(transmission_samples);
|
||||
integrator->set_ao_samples(ao_samples);
|
||||
integrator->set_mesh_light_samples(mesh_light_samples);
|
||||
integrator->set_subsurface_samples(subsurface_samples);
|
||||
integrator->set_volume_samples(volume_samples);
|
||||
}
|
||||
|
||||
/* only use scrambling distance in the viewport if user wants to and disable with AS */
|
||||
bool preview_scrambling_distance = get_boolean(cscene, "preview_scrambling_distance");
|
||||
if ((preview && !preview_scrambling_distance) || use_adaptive_sampling)
|
||||
scrambling_distance = 1.0f;
|
||||
|
||||
if (scrambling_distance != 1.0f) {
|
||||
VLOG(3) << "Using scrambling distance: " << scrambling_distance;
|
||||
}
|
||||
integrator->set_scrambling_distance(scrambling_distance);
|
||||
integrator->set_adaptive_min_samples(adaptive_min_samples);
|
||||
|
||||
if (get_boolean(cscene, "use_fast_gi")) {
|
||||
if (preview) {
|
||||
@@ -392,38 +393,20 @@ void BlenderSync::sync_integrator(BL::ViewLayer &b_view_layer, bool background)
|
||||
integrator->set_ao_bounces(0);
|
||||
}
|
||||
|
||||
const DenoiseParams denoise_params = get_denoise_params(b_scene, b_view_layer, background);
|
||||
integrator->set_use_denoise(denoise_params.use);
|
||||
|
||||
/* Only update denoiser parameters if the denoiser is actually used. This allows to tweak
|
||||
* denoiser parameters before enabling it without render resetting on every change. The downside
|
||||
* is that the interface and the integrator are technically out of sync. */
|
||||
if (denoise_params.use) {
|
||||
integrator->set_denoiser_type(denoise_params.type);
|
||||
integrator->set_denoise_start_sample(denoise_params.start_sample);
|
||||
integrator->set_use_denoise_pass_albedo(denoise_params.use_pass_albedo);
|
||||
integrator->set_use_denoise_pass_normal(denoise_params.use_pass_normal);
|
||||
integrator->set_denoiser_prefilter(denoise_params.prefilter);
|
||||
}
|
||||
|
||||
/* UPDATE_NONE as we don't want to tag the integrator as modified (this was done by the
|
||||
* set calls above), but we need to make sure that the dependent things are tagged. */
|
||||
/* UPDATE_NONE as we don't want to tag the integrator as modified, just tag dependent things */
|
||||
integrator->tag_update(scene, Integrator::UPDATE_NONE);
|
||||
}
|
||||
|
||||
/* Film */
|
||||
|
||||
void BlenderSync::sync_film(BL::ViewLayer &b_view_layer, BL::SpaceView3D &b_v3d)
|
||||
void BlenderSync::sync_film(BL::SpaceView3D &b_v3d)
|
||||
{
|
||||
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
|
||||
PointerRNA crl = RNA_pointer_get(&b_view_layer.ptr, "cycles");
|
||||
|
||||
Film *film = scene->film;
|
||||
|
||||
if (b_v3d) {
|
||||
const BlenderViewportParameters new_viewport_parameters(b_v3d, use_developer_ui);
|
||||
film->set_display_pass(new_viewport_parameters.display_pass);
|
||||
film->set_show_active_pixels(new_viewport_parameters.show_active_pixels);
|
||||
film->set_display_pass(update_viewport_display_passes(b_v3d, scene->passes));
|
||||
}
|
||||
|
||||
film->set_exposure(get_float(cscene, "film_exposure"));
|
||||
@@ -451,15 +434,6 @@ void BlenderSync::sync_film(BL::ViewLayer &b_view_layer, BL::SpaceView3D &b_v3d)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Blender viewport does not support proper shadow catcher compositing, so force an approximate
|
||||
* mode to improve visual feedback. */
|
||||
if (b_v3d) {
|
||||
film->set_use_approximate_shadow_catcher(true);
|
||||
}
|
||||
else {
|
||||
film->set_use_approximate_shadow_catcher(!get_boolean(crl, "use_pass_shadow_catcher"));
|
||||
}
|
||||
}
|
||||
|
||||
/* Render Layer */
|
||||
@@ -470,6 +444,7 @@ void BlenderSync::sync_view_layer(BL::ViewLayer &b_view_layer)
|
||||
|
||||
/* Filter. */
|
||||
view_layer.use_background_shader = b_view_layer.use_sky();
|
||||
view_layer.use_background_ao = b_view_layer.use_ao();
|
||||
/* Always enable surfaces for baking, otherwise there is nothing to bake to. */
|
||||
view_layer.use_surfaces = b_view_layer.use_solid() || scene->bake_manager->get_baking();
|
||||
view_layer.use_hair = b_view_layer.use_strand();
|
||||
@@ -489,7 +464,10 @@ void BlenderSync::sync_view_layer(BL::ViewLayer &b_view_layer)
|
||||
|
||||
if (use_layer_samples != 2) {
|
||||
int samples = b_view_layer.samples();
|
||||
view_layer.samples = samples;
|
||||
if (get_boolean(cscene, "use_square_samples"))
|
||||
view_layer.samples = samples * samples;
|
||||
else
|
||||
view_layer.samples = samples;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -521,8 +499,7 @@ void BlenderSync::sync_images()
|
||||
}
|
||||
|
||||
/* Passes */
|
||||
|
||||
static PassType get_blender_pass_type(BL::RenderPass &b_pass)
|
||||
PassType BlenderSync::get_pass_type(BL::RenderPass &b_pass)
|
||||
{
|
||||
string name = b_pass.name();
|
||||
#define MAP_PASS(passname, passtype) \
|
||||
@@ -530,15 +507,10 @@ static PassType get_blender_pass_type(BL::RenderPass &b_pass)
|
||||
return passtype; \
|
||||
} \
|
||||
((void)0)
|
||||
|
||||
/* NOTE: Keep in sync with defined names from DNA_scene_types.h */
|
||||
|
||||
MAP_PASS("Combined", PASS_COMBINED);
|
||||
MAP_PASS("Noisy Image", PASS_COMBINED);
|
||||
|
||||
MAP_PASS("Depth", PASS_DEPTH);
|
||||
MAP_PASS("Mist", PASS_MIST);
|
||||
MAP_PASS("Position", PASS_POSITION);
|
||||
MAP_PASS("Normal", PASS_NORMAL);
|
||||
MAP_PASS("IndexOB", PASS_OBJECT_ID);
|
||||
MAP_PASS("UV", PASS_UV);
|
||||
@@ -567,87 +539,118 @@ static PassType get_blender_pass_type(BL::RenderPass &b_pass)
|
||||
MAP_PASS("BakePrimitive", PASS_BAKE_PRIMITIVE);
|
||||
MAP_PASS("BakeDifferential", PASS_BAKE_DIFFERENTIAL);
|
||||
|
||||
MAP_PASS("Denoising Normal", PASS_DENOISING_NORMAL);
|
||||
MAP_PASS("Denoising Albedo", PASS_DENOISING_ALBEDO);
|
||||
MAP_PASS("Denoising Depth", PASS_DENOISING_DEPTH);
|
||||
|
||||
MAP_PASS("Shadow Catcher", PASS_SHADOW_CATCHER);
|
||||
MAP_PASS("Noisy Shadow Catcher", PASS_SHADOW_CATCHER);
|
||||
|
||||
MAP_PASS("Debug Render Time", PASS_RENDER_TIME);
|
||||
MAP_PASS("AdaptiveAuxBuffer", PASS_ADAPTIVE_AUX_BUFFER);
|
||||
MAP_PASS("Debug Sample Count", PASS_SAMPLE_COUNT);
|
||||
|
||||
if (string_startswith(name, cryptomatte_prefix)) {
|
||||
return PASS_CRYPTOMATTE;
|
||||
}
|
||||
|
||||
#undef MAP_PASS
|
||||
|
||||
return PASS_NONE;
|
||||
}
|
||||
|
||||
static Pass *pass_add(Scene *scene,
|
||||
PassType type,
|
||||
const char *name,
|
||||
PassMode mode = PassMode::DENOISED)
|
||||
int BlenderSync::get_denoising_pass(BL::RenderPass &b_pass)
|
||||
{
|
||||
Pass *pass = scene->create_node<Pass>();
|
||||
string name = b_pass.name();
|
||||
|
||||
pass->set_type(type);
|
||||
pass->set_name(ustring(name));
|
||||
pass->set_mode(mode);
|
||||
if (name == "Noisy Image")
|
||||
return DENOISING_PASS_PREFILTERED_COLOR;
|
||||
|
||||
return pass;
|
||||
if (name.substr(0, 10) != "Denoising ") {
|
||||
return -1;
|
||||
}
|
||||
name = name.substr(10);
|
||||
|
||||
#define MAP_PASS(passname, offset) \
|
||||
if (name == passname) { \
|
||||
return offset; \
|
||||
} \
|
||||
((void)0)
|
||||
MAP_PASS("Normal", DENOISING_PASS_PREFILTERED_NORMAL);
|
||||
MAP_PASS("Albedo", DENOISING_PASS_PREFILTERED_ALBEDO);
|
||||
MAP_PASS("Depth", DENOISING_PASS_PREFILTERED_DEPTH);
|
||||
MAP_PASS("Shadowing", DENOISING_PASS_PREFILTERED_SHADOWING);
|
||||
MAP_PASS("Variance", DENOISING_PASS_PREFILTERED_VARIANCE);
|
||||
MAP_PASS("Intensity", DENOISING_PASS_PREFILTERED_INTENSITY);
|
||||
MAP_PASS("Clean", DENOISING_PASS_CLEAN);
|
||||
#undef MAP_PASS
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay, BL::ViewLayer &b_view_layer)
|
||||
vector<Pass> BlenderSync::sync_render_passes(BL::Scene &b_scene,
|
||||
BL::RenderLayer &b_rlay,
|
||||
BL::ViewLayer &b_view_layer,
|
||||
bool adaptive_sampling,
|
||||
const DenoiseParams &denoising)
|
||||
{
|
||||
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
|
||||
vector<Pass> passes;
|
||||
|
||||
/* Delete all existing passes. */
|
||||
set<Pass *> clear_passes(scene->passes.begin(), scene->passes.end());
|
||||
scene->delete_nodes(clear_passes);
|
||||
|
||||
/* Always add combined pass. */
|
||||
pass_add(scene, PASS_COMBINED, "Combined");
|
||||
|
||||
/* Blender built-in data and light passes. */
|
||||
/* loop over passes */
|
||||
for (BL::RenderPass &b_pass : b_rlay.passes) {
|
||||
const PassType pass_type = get_blender_pass_type(b_pass);
|
||||
|
||||
if (pass_type == PASS_NONE) {
|
||||
LOG(ERROR) << "Unknown pass " << b_pass.name();
|
||||
continue;
|
||||
}
|
||||
PassType pass_type = get_pass_type(b_pass);
|
||||
|
||||
if (pass_type == PASS_MOTION &&
|
||||
(b_view_layer.use_motion_blur() && b_scene.render().use_motion_blur())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pass_add(scene, pass_type, b_pass.name().c_str());
|
||||
if (pass_type != PASS_NONE)
|
||||
Pass::add(pass_type, passes, b_pass.name().c_str());
|
||||
}
|
||||
|
||||
PointerRNA crl = RNA_pointer_get(&b_view_layer.ptr, "cycles");
|
||||
|
||||
/* Debug passes. */
|
||||
if (get_boolean(crl, "pass_debug_sample_count")) {
|
||||
b_engine.add_pass("Debug Sample Count", 1, "X", b_view_layer.name().c_str());
|
||||
pass_add(scene, PASS_SAMPLE_COUNT, "Debug Sample Count");
|
||||
int denoising_flags = 0;
|
||||
if (denoising.use || denoising.store_passes) {
|
||||
if (denoising.type == DENOISER_NLM) {
|
||||
#define MAP_OPTION(name, flag) \
|
||||
if (!get_boolean(crl, name)) { \
|
||||
denoising_flags |= flag; \
|
||||
} \
|
||||
((void)0)
|
||||
MAP_OPTION("denoising_diffuse_direct", DENOISING_CLEAN_DIFFUSE_DIR);
|
||||
MAP_OPTION("denoising_diffuse_indirect", DENOISING_CLEAN_DIFFUSE_IND);
|
||||
MAP_OPTION("denoising_glossy_direct", DENOISING_CLEAN_GLOSSY_DIR);
|
||||
MAP_OPTION("denoising_glossy_indirect", DENOISING_CLEAN_GLOSSY_IND);
|
||||
MAP_OPTION("denoising_transmission_direct", DENOISING_CLEAN_TRANSMISSION_DIR);
|
||||
MAP_OPTION("denoising_transmission_indirect", DENOISING_CLEAN_TRANSMISSION_IND);
|
||||
#undef MAP_OPTION
|
||||
}
|
||||
b_engine.add_pass("Noisy Image", 4, "RGBA", b_view_layer.name().c_str());
|
||||
}
|
||||
scene->film->set_denoising_flags(denoising_flags);
|
||||
|
||||
if (denoising.store_passes) {
|
||||
b_engine.add_pass("Denoising Normal", 3, "XYZ", b_view_layer.name().c_str());
|
||||
b_engine.add_pass("Denoising Albedo", 3, "RGB", b_view_layer.name().c_str());
|
||||
b_engine.add_pass("Denoising Depth", 1, "Z", b_view_layer.name().c_str());
|
||||
if (denoising.type == DENOISER_NLM) {
|
||||
b_engine.add_pass("Denoising Shadowing", 1, "X", b_view_layer.name().c_str());
|
||||
b_engine.add_pass("Denoising Variance", 3, "RGB", b_view_layer.name().c_str());
|
||||
b_engine.add_pass("Denoising Intensity", 1, "X", b_view_layer.name().c_str());
|
||||
}
|
||||
|
||||
if (scene->film->get_denoising_flags() & DENOISING_CLEAN_ALL_PASSES) {
|
||||
b_engine.add_pass("Denoising Clean", 3, "RGB", b_view_layer.name().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
/* Cycles specific passes. */
|
||||
if (get_boolean(crl, "pass_debug_render_time")) {
|
||||
b_engine.add_pass("Debug Render Time", 1, "X", b_view_layer.name().c_str());
|
||||
Pass::add(PASS_RENDER_TIME, passes, "Debug Render Time");
|
||||
}
|
||||
if (get_boolean(crl, "pass_debug_sample_count")) {
|
||||
b_engine.add_pass("Debug Sample Count", 1, "X", b_view_layer.name().c_str());
|
||||
Pass::add(PASS_SAMPLE_COUNT, passes, "Debug Sample Count");
|
||||
}
|
||||
if (get_boolean(crl, "use_pass_volume_direct")) {
|
||||
b_engine.add_pass("VolumeDir", 3, "RGB", b_view_layer.name().c_str());
|
||||
pass_add(scene, PASS_VOLUME_DIRECT, "VolumeDir");
|
||||
Pass::add(PASS_VOLUME_DIRECT, passes, "VolumeDir");
|
||||
}
|
||||
if (get_boolean(crl, "use_pass_volume_indirect")) {
|
||||
b_engine.add_pass("VolumeInd", 3, "RGB", b_view_layer.name().c_str());
|
||||
pass_add(scene, PASS_VOLUME_INDIRECT, "VolumeInd");
|
||||
}
|
||||
if (get_boolean(crl, "use_pass_shadow_catcher")) {
|
||||
b_engine.add_pass("Shadow Catcher", 3, "RGB", b_view_layer.name().c_str());
|
||||
pass_add(scene, PASS_SHADOW_CATCHER, "Shadow Catcher");
|
||||
Pass::add(PASS_VOLUME_INDIRECT, passes, "VolumeInd");
|
||||
}
|
||||
|
||||
/* Cryptomatte stores two ID/weight pairs per RGBA layer.
|
||||
@@ -659,7 +662,7 @@ void BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay, BL::ViewLayer &b_v
|
||||
for (int i = 0; i < crypto_depth; i++) {
|
||||
string passname = cryptomatte_prefix + string_printf("Object%02d", i);
|
||||
b_engine.add_pass(passname.c_str(), 4, "RGBA", b_view_layer.name().c_str());
|
||||
pass_add(scene, PASS_CRYPTOMATTE, passname.c_str());
|
||||
Pass::add(PASS_CRYPTOMATTE, passes, passname.c_str());
|
||||
}
|
||||
cryptomatte_passes = (CryptomatteType)(cryptomatte_passes | CRYPT_OBJECT);
|
||||
}
|
||||
@@ -667,7 +670,7 @@ void BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay, BL::ViewLayer &b_v
|
||||
for (int i = 0; i < crypto_depth; i++) {
|
||||
string passname = cryptomatte_prefix + string_printf("Material%02d", i);
|
||||
b_engine.add_pass(passname.c_str(), 4, "RGBA", b_view_layer.name().c_str());
|
||||
pass_add(scene, PASS_CRYPTOMATTE, passname.c_str());
|
||||
Pass::add(PASS_CRYPTOMATTE, passes, passname.c_str());
|
||||
}
|
||||
cryptomatte_passes = (CryptomatteType)(cryptomatte_passes | CRYPT_MATERIAL);
|
||||
}
|
||||
@@ -675,36 +678,22 @@ void BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay, BL::ViewLayer &b_v
|
||||
for (int i = 0; i < crypto_depth; i++) {
|
||||
string passname = cryptomatte_prefix + string_printf("Asset%02d", i);
|
||||
b_engine.add_pass(passname.c_str(), 4, "RGBA", b_view_layer.name().c_str());
|
||||
pass_add(scene, PASS_CRYPTOMATTE, passname.c_str());
|
||||
Pass::add(PASS_CRYPTOMATTE, passes, passname.c_str());
|
||||
}
|
||||
cryptomatte_passes = (CryptomatteType)(cryptomatte_passes | CRYPT_ASSET);
|
||||
}
|
||||
if (b_view_layer.use_pass_cryptomatte_accurate() && cryptomatte_passes != CRYPT_NONE) {
|
||||
cryptomatte_passes = (CryptomatteType)(cryptomatte_passes | CRYPT_ACCURATE);
|
||||
}
|
||||
scene->film->set_cryptomatte_passes(cryptomatte_passes);
|
||||
|
||||
/* Denoising passes. */
|
||||
const bool use_denoising = get_boolean(cscene, "use_denoising") &&
|
||||
get_boolean(crl, "use_denoising");
|
||||
const bool store_denoising_passes = get_boolean(crl, "denoising_store_passes");
|
||||
if (use_denoising) {
|
||||
b_engine.add_pass("Noisy Image", 4, "RGBA", b_view_layer.name().c_str());
|
||||
pass_add(scene, PASS_COMBINED, "Noisy Image", PassMode::NOISY);
|
||||
if (get_boolean(crl, "use_pass_shadow_catcher")) {
|
||||
b_engine.add_pass("Noisy Shadow Catcher", 3, "RGB", b_view_layer.name().c_str());
|
||||
pass_add(scene, PASS_SHADOW_CATCHER, "Noisy Shadow Catcher", PassMode::NOISY);
|
||||
if (adaptive_sampling) {
|
||||
Pass::add(PASS_ADAPTIVE_AUX_BUFFER, passes);
|
||||
if (!get_boolean(crl, "pass_debug_sample_count")) {
|
||||
Pass::add(PASS_SAMPLE_COUNT, passes);
|
||||
}
|
||||
}
|
||||
if (store_denoising_passes) {
|
||||
b_engine.add_pass("Denoising Normal", 3, "XYZ", b_view_layer.name().c_str());
|
||||
pass_add(scene, PASS_DENOISING_NORMAL, "Denoising Normal", PassMode::NOISY);
|
||||
|
||||
b_engine.add_pass("Denoising Albedo", 3, "RGB", b_view_layer.name().c_str());
|
||||
pass_add(scene, PASS_DENOISING_ALBEDO, "Denoising Albedo", PassMode::NOISY);
|
||||
|
||||
b_engine.add_pass("Denoising Depth", 1, "Z", b_view_layer.name().c_str());
|
||||
pass_add(scene, PASS_DENOISING_DEPTH, "Denoising Depth", PassMode::NOISY);
|
||||
}
|
||||
|
||||
/* Custom AOV passes. */
|
||||
BL::ViewLayer::aovs_iterator b_aov_iter;
|
||||
for (b_view_layer.aovs.begin(b_aov_iter); b_aov_iter != b_view_layer.aovs.end(); ++b_aov_iter) {
|
||||
BL::AOV b_aov(*b_aov_iter);
|
||||
@@ -717,15 +706,28 @@ void BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay, BL::ViewLayer &b_v
|
||||
|
||||
if (is_color) {
|
||||
b_engine.add_pass(name.c_str(), 4, "RGBA", b_view_layer.name().c_str());
|
||||
pass_add(scene, PASS_AOV_COLOR, name.c_str());
|
||||
Pass::add(PASS_AOV_COLOR, passes, name.c_str());
|
||||
}
|
||||
else {
|
||||
b_engine.add_pass(name.c_str(), 1, "X", b_view_layer.name().c_str());
|
||||
pass_add(scene, PASS_AOV_VALUE, name.c_str());
|
||||
Pass::add(PASS_AOV_VALUE, passes, name.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
scene->film->set_denoising_data_pass(denoising.use || denoising.store_passes);
|
||||
scene->film->set_denoising_clean_pass(scene->film->get_denoising_flags() &
|
||||
DENOISING_CLEAN_ALL_PASSES);
|
||||
scene->film->set_denoising_prefiltered_pass(denoising.store_passes &&
|
||||
denoising.type == DENOISER_NLM);
|
||||
scene->film->set_pass_alpha_threshold(b_view_layer.pass_alpha_threshold());
|
||||
|
||||
if (!Pass::equals(passes, scene->passes)) {
|
||||
scene->film->tag_passes_update(scene, passes);
|
||||
scene->film->tag_modified();
|
||||
scene->integrator->tag_update(scene, Integrator::UPDATE_ALL);
|
||||
}
|
||||
|
||||
return passes;
|
||||
}
|
||||
|
||||
void BlenderSync::free_data_after_sync(BL::Depsgraph &b_depsgraph)
|
||||
@@ -771,9 +773,9 @@ SceneParams BlenderSync::get_scene_params(BL::Scene &b_scene, bool background)
|
||||
params.shadingsystem = SHADINGSYSTEM_OSL;
|
||||
|
||||
if (background || DebugFlags().viewport_static_bvh)
|
||||
params.bvh_type = BVH_TYPE_STATIC;
|
||||
params.bvh_type = SceneParams::BVH_STATIC;
|
||||
else
|
||||
params.bvh_type = BVH_TYPE_DYNAMIC;
|
||||
params.bvh_type = SceneParams::BVH_DYNAMIC;
|
||||
|
||||
params.use_bvh_spatial_split = RNA_boolean_get(&cscene, "debug_use_spatial_splits");
|
||||
params.use_bvh_unaligned_nodes = RNA_boolean_get(&cscene, "debug_use_hair_bvh");
|
||||
@@ -816,7 +818,8 @@ bool BlenderSync::get_session_pause(BL::Scene &b_scene, bool background)
|
||||
SessionParams BlenderSync::get_session_params(BL::RenderEngine &b_engine,
|
||||
BL::Preferences &b_preferences,
|
||||
BL::Scene &b_scene,
|
||||
bool background)
|
||||
bool background,
|
||||
BL::ViewLayer b_view_layer)
|
||||
{
|
||||
SessionParams params;
|
||||
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
|
||||
@@ -824,8 +827,7 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine &b_engine,
|
||||
/* feature set */
|
||||
params.experimental = (get_enum(cscene, "feature_set") != 0);
|
||||
|
||||
/* Headless and background rendering. */
|
||||
params.headless = BlenderSession::headless;
|
||||
/* Background */
|
||||
params.background = background;
|
||||
|
||||
/* Device */
|
||||
@@ -834,26 +836,111 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine &b_engine,
|
||||
|
||||
/* samples */
|
||||
int samples = get_int(cscene, "samples");
|
||||
int aa_samples = get_int(cscene, "aa_samples");
|
||||
int preview_samples = get_int(cscene, "preview_samples");
|
||||
int preview_aa_samples = get_int(cscene, "preview_aa_samples");
|
||||
|
||||
if (background) {
|
||||
params.samples = samples;
|
||||
if (get_boolean(cscene, "use_square_samples")) {
|
||||
aa_samples = aa_samples * aa_samples;
|
||||
preview_aa_samples = preview_aa_samples * preview_aa_samples;
|
||||
|
||||
samples = samples * samples;
|
||||
preview_samples = preview_samples * preview_samples;
|
||||
}
|
||||
|
||||
if (get_enum(cscene, "progressive") == 0 && params.device.has_branched_path) {
|
||||
if (background) {
|
||||
params.samples = aa_samples;
|
||||
}
|
||||
else {
|
||||
params.samples = preview_aa_samples;
|
||||
if (params.samples == 0)
|
||||
params.samples = INT_MAX;
|
||||
}
|
||||
}
|
||||
else {
|
||||
params.samples = preview_samples;
|
||||
if (params.samples == 0)
|
||||
params.samples = INT_MAX;
|
||||
if (background) {
|
||||
params.samples = samples;
|
||||
}
|
||||
else {
|
||||
params.samples = preview_samples;
|
||||
if (params.samples == 0)
|
||||
params.samples = INT_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
/* Clamp samples. */
|
||||
params.samples = min(params.samples, Integrator::MAX_SAMPLES);
|
||||
|
||||
/* Adaptive sampling. */
|
||||
params.adaptive_sampling = RNA_boolean_get(&cscene, "use_adaptive_sampling");
|
||||
|
||||
/* tiles */
|
||||
const bool is_cpu = (params.device.type == DEVICE_CPU);
|
||||
if (!is_cpu && !background) {
|
||||
/* currently GPU could be much slower than CPU when using tiles,
|
||||
* still need to be investigated, but meanwhile make it possible
|
||||
* to work in viewport smoothly
|
||||
*/
|
||||
int debug_tile_size = get_int(cscene, "debug_tile_size");
|
||||
|
||||
params.tile_size = make_int2(debug_tile_size, debug_tile_size);
|
||||
}
|
||||
else {
|
||||
int tile_x = b_engine.tile_x();
|
||||
int tile_y = b_engine.tile_y();
|
||||
|
||||
params.tile_size = make_int2(tile_x, tile_y);
|
||||
}
|
||||
|
||||
if ((BlenderSession::headless == false) && background) {
|
||||
params.tile_order = (TileOrder)get_enum(cscene, "tile_order");
|
||||
}
|
||||
else {
|
||||
params.tile_order = TILE_BOTTOM_TO_TOP;
|
||||
}
|
||||
|
||||
/* Denoising */
|
||||
params.denoising = get_denoise_params(b_scene, b_view_layer, background);
|
||||
|
||||
if (params.denoising.use) {
|
||||
/* Add additional denoising devices if we are rendering and denoising
|
||||
* with different devices. */
|
||||
params.device.add_denoising_devices(params.denoising.type);
|
||||
|
||||
/* Check if denoiser is supported by device. */
|
||||
if (!(params.device.denoisers & params.denoising.type)) {
|
||||
params.denoising.use = false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Viewport Performance */
|
||||
params.start_resolution = get_int(cscene, "preview_start_resolution");
|
||||
params.pixel_size = b_engine.get_preview_pixel_size(b_scene);
|
||||
|
||||
/* other parameters */
|
||||
params.cancel_timeout = (double)get_float(cscene, "debug_cancel_timeout");
|
||||
params.reset_timeout = (double)get_float(cscene, "debug_reset_timeout");
|
||||
params.text_timeout = (double)get_float(cscene, "debug_text_timeout");
|
||||
|
||||
/* progressive refine */
|
||||
BL::RenderSettings b_r = b_scene.render();
|
||||
params.progressive_refine = b_engine.is_preview() ||
|
||||
get_boolean(cscene, "use_progressive_refine");
|
||||
if (b_r.use_save_buffers() || params.adaptive_sampling)
|
||||
params.progressive_refine = false;
|
||||
|
||||
if (background) {
|
||||
if (params.progressive_refine)
|
||||
params.progressive = true;
|
||||
else
|
||||
params.progressive = false;
|
||||
|
||||
params.start_resolution = INT_MAX;
|
||||
params.pixel_size = 1;
|
||||
}
|
||||
else
|
||||
params.progressive = true;
|
||||
|
||||
/* shading system - scene level needs full refresh */
|
||||
const bool shadingsystem = RNA_boolean_get(&cscene, "shading_system");
|
||||
@@ -863,30 +950,19 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine &b_engine,
|
||||
else if (shadingsystem == 1)
|
||||
params.shadingsystem = SHADINGSYSTEM_OSL;
|
||||
|
||||
/* Time limit. */
|
||||
if (background) {
|
||||
params.time_limit = get_float(cscene, "time_limit");
|
||||
}
|
||||
else {
|
||||
/* For the viewport it kind of makes more sense to think in terms of the noise floor, which is
|
||||
* usually higher than acceptable level for the final frame. */
|
||||
/* TODO: It might be useful to support time limit in the viewport as well, but needs some
|
||||
* extra thoughts and input. */
|
||||
params.time_limit = 0.0;
|
||||
/* Color management. */
|
||||
params.display_buffer_linear = b_engine.support_display_space_shader(b_scene);
|
||||
|
||||
if (b_engine.is_preview()) {
|
||||
/* For preview rendering we're using same timeout as
|
||||
* blender's job update.
|
||||
*/
|
||||
params.progressive_update_timeout = 0.1;
|
||||
}
|
||||
|
||||
/* Profiling. */
|
||||
params.use_profiling = params.device.has_profiling && !b_engine.is_preview() && background &&
|
||||
BlenderSession::print_render_stats;
|
||||
|
||||
if (background) {
|
||||
params.use_auto_tile = RNA_boolean_get(&cscene, "use_auto_tile");
|
||||
params.tile_size = max(get_int(cscene, "tile_size"), 8);
|
||||
}
|
||||
else {
|
||||
params.use_auto_tile = false;
|
||||
}
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
@@ -894,34 +970,33 @@ DenoiseParams BlenderSync::get_denoise_params(BL::Scene &b_scene,
|
||||
BL::ViewLayer &b_view_layer,
|
||||
bool background)
|
||||
{
|
||||
enum DenoiserInput {
|
||||
DENOISER_INPUT_RGB = 1,
|
||||
DENOISER_INPUT_RGB_ALBEDO = 2,
|
||||
DENOISER_INPUT_RGB_ALBEDO_NORMAL = 3,
|
||||
|
||||
DENOISER_INPUT_NUM,
|
||||
};
|
||||
|
||||
DenoiseParams denoising;
|
||||
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
|
||||
|
||||
int input_passes = -1;
|
||||
|
||||
if (background) {
|
||||
/* Final Render Denoising */
|
||||
denoising.use = get_boolean(cscene, "use_denoising");
|
||||
denoising.type = (DenoiserType)get_enum(cscene, "denoiser", DENOISER_NUM, DENOISER_NONE);
|
||||
denoising.prefilter = (DenoiserPrefilter)get_enum(
|
||||
cscene, "denoising_prefilter", DENOISER_PREFILTER_NUM, DENOISER_PREFILTER_NONE);
|
||||
|
||||
input_passes = (DenoiserInput)get_enum(
|
||||
cscene, "denoising_input_passes", DENOISER_INPUT_NUM, DENOISER_INPUT_RGB_ALBEDO_NORMAL);
|
||||
|
||||
if (b_view_layer) {
|
||||
PointerRNA clayer = RNA_pointer_get(&b_view_layer.ptr, "cycles");
|
||||
if (!get_boolean(clayer, "use_denoising")) {
|
||||
denoising.use = false;
|
||||
}
|
||||
|
||||
denoising.radius = get_int(clayer, "denoising_radius");
|
||||
denoising.strength = get_float(clayer, "denoising_strength");
|
||||
denoising.feature_strength = get_float(clayer, "denoising_feature_strength");
|
||||
denoising.relative_pca = get_boolean(clayer, "denoising_relative_pca");
|
||||
|
||||
denoising.input_passes = (DenoiserInput)get_enum(
|
||||
clayer,
|
||||
(denoising.type == DENOISER_OPTIX) ? "denoising_optix_input_passes" :
|
||||
"denoising_openimagedenoise_input_passes",
|
||||
DENOISER_INPUT_NUM,
|
||||
DENOISER_INPUT_RGB_ALBEDO_NORMAL);
|
||||
|
||||
denoising.store_passes = get_boolean(clayer, "denoising_store_passes");
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -929,12 +1004,10 @@ DenoiseParams BlenderSync::get_denoise_params(BL::Scene &b_scene,
|
||||
denoising.use = get_boolean(cscene, "use_preview_denoising");
|
||||
denoising.type = (DenoiserType)get_enum(
|
||||
cscene, "preview_denoiser", DENOISER_NUM, DENOISER_NONE);
|
||||
denoising.prefilter = (DenoiserPrefilter)get_enum(
|
||||
cscene, "preview_denoising_prefilter", DENOISER_PREFILTER_NUM, DENOISER_PREFILTER_FAST);
|
||||
denoising.start_sample = get_int(cscene, "preview_denoising_start_sample");
|
||||
|
||||
input_passes = (DenoiserInput)get_enum(
|
||||
cscene, "preview_denoising_input_passes", DENOISER_INPUT_NUM, DENOISER_INPUT_RGB_ALBEDO);
|
||||
denoising.input_passes = (DenoiserInput)get_enum(
|
||||
cscene, "preview_denoising_input_passes", DENOISER_INPUT_NUM, (int)denoising.input_passes);
|
||||
|
||||
/* Auto select fastest denoiser. */
|
||||
if (denoising.type == DENOISER_NONE) {
|
||||
@@ -950,27 +1023,6 @@ DenoiseParams BlenderSync::get_denoise_params(BL::Scene &b_scene,
|
||||
}
|
||||
}
|
||||
|
||||
switch (input_passes) {
|
||||
case DENOISER_INPUT_RGB:
|
||||
denoising.use_pass_albedo = false;
|
||||
denoising.use_pass_normal = false;
|
||||
break;
|
||||
|
||||
case DENOISER_INPUT_RGB_ALBEDO:
|
||||
denoising.use_pass_albedo = true;
|
||||
denoising.use_pass_normal = false;
|
||||
break;
|
||||
|
||||
case DENOISER_INPUT_RGB_ALBEDO_NORMAL:
|
||||
denoising.use_pass_albedo = true;
|
||||
denoising.use_pass_normal = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG(ERROR) << "Unhandled input passes enum " << input_passes;
|
||||
break;
|
||||
}
|
||||
|
||||
return denoising;
|
||||
}
|
||||
|
@@ -22,17 +22,17 @@
|
||||
#include "RNA_blender_cpp.h"
|
||||
#include "RNA_types.h"
|
||||
|
||||
#include "blender/id_map.h"
|
||||
#include "blender/util.h"
|
||||
#include "blender/viewport.h"
|
||||
#include "blender/blender_id_map.h"
|
||||
#include "blender/blender_util.h"
|
||||
#include "blender/blender_viewport.h"
|
||||
|
||||
#include "scene/scene.h"
|
||||
#include "session/session.h"
|
||||
#include "render/scene.h"
|
||||
#include "render/session.h"
|
||||
|
||||
#include "util/map.h"
|
||||
#include "util/set.h"
|
||||
#include "util/transform.h"
|
||||
#include "util/vector.h"
|
||||
#include "util/util_map.h"
|
||||
#include "util/util_set.h"
|
||||
#include "util/util_transform.h"
|
||||
#include "util/util_vector.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
@@ -60,7 +60,6 @@ class BlenderSync {
|
||||
BL::Scene &b_scene,
|
||||
Scene *scene,
|
||||
bool preview,
|
||||
bool use_developer_ui,
|
||||
Progress &progress);
|
||||
~BlenderSync();
|
||||
|
||||
@@ -76,8 +75,12 @@ class BlenderSync {
|
||||
int height,
|
||||
void **python_thread_state);
|
||||
void sync_view_layer(BL::ViewLayer &b_view_layer);
|
||||
void sync_render_passes(BL::RenderLayer &b_render_layer, BL::ViewLayer &b_view_layer);
|
||||
void sync_integrator(BL::ViewLayer &b_view_layer, bool background);
|
||||
vector<Pass> sync_render_passes(BL::Scene &b_scene,
|
||||
BL::RenderLayer &b_render_layer,
|
||||
BL::ViewLayer &b_view_layer,
|
||||
bool adaptive_sampling,
|
||||
const DenoiseParams &denoising);
|
||||
void sync_integrator();
|
||||
void sync_camera(BL::RenderSettings &b_render,
|
||||
BL::Object &b_override,
|
||||
int width,
|
||||
@@ -95,13 +98,22 @@ class BlenderSync {
|
||||
|
||||
/* get parameters */
|
||||
static SceneParams get_scene_params(BL::Scene &b_scene, bool background);
|
||||
static SessionParams get_session_params(BL::RenderEngine &b_engine,
|
||||
BL::Preferences &b_userpref,
|
||||
BL::Scene &b_scene,
|
||||
bool background);
|
||||
static SessionParams get_session_params(
|
||||
BL::RenderEngine &b_engine,
|
||||
BL::Preferences &b_userpref,
|
||||
BL::Scene &b_scene,
|
||||
bool background,
|
||||
BL::ViewLayer b_view_layer = BL::ViewLayer(PointerRNA_NULL));
|
||||
static bool get_session_pause(BL::Scene &b_scene, bool background);
|
||||
static BufferParams get_buffer_params(
|
||||
BL::SpaceView3D &b_v3d, BL::RegionView3D &b_rv3d, Camera *cam, int width, int height);
|
||||
static BufferParams get_buffer_params(BL::SpaceView3D &b_v3d,
|
||||
BL::RegionView3D &b_rv3d,
|
||||
Camera *cam,
|
||||
int width,
|
||||
int height,
|
||||
const bool use_denoiser);
|
||||
|
||||
static PassType get_pass_type(BL::RenderPass &b_pass);
|
||||
static int get_denoising_pass(BL::RenderPass &b_pass);
|
||||
|
||||
private:
|
||||
static DenoiseParams get_denoise_params(BL::Scene &b_scene,
|
||||
@@ -119,7 +131,7 @@ class BlenderSync {
|
||||
int width,
|
||||
int height,
|
||||
void **python_thread_state);
|
||||
void sync_film(BL::ViewLayer &b_view_layer, BL::SpaceView3D &b_v3d);
|
||||
void sync_film(BL::SpaceView3D &b_v3d);
|
||||
void sync_view();
|
||||
|
||||
/* Shader */
|
||||
@@ -225,8 +237,6 @@ class BlenderSync {
|
||||
set<Geometry *> geometry_synced;
|
||||
set<Geometry *> geometry_motion_synced;
|
||||
set<Geometry *> geometry_motion_attribute_synced;
|
||||
/** Remember which geometries come from which objects to be able to sync them after changes. */
|
||||
map<void *, set<BL::ID>> instance_geometries_by_object;
|
||||
set<float> motion_times;
|
||||
void *world_map;
|
||||
bool world_recalc;
|
||||
@@ -235,7 +245,6 @@ class BlenderSync {
|
||||
Scene *scene;
|
||||
bool preview;
|
||||
bool experimental;
|
||||
bool use_developer_ui;
|
||||
|
||||
float dicing_rate;
|
||||
int max_subdivisions;
|
||||
@@ -244,6 +253,7 @@ class BlenderSync {
|
||||
RenderLayerInfo()
|
||||
: material_override(PointerRNA_NULL),
|
||||
use_background_shader(true),
|
||||
use_background_ao(true),
|
||||
use_surfaces(true),
|
||||
use_hair(true),
|
||||
use_volumes(true),
|
||||
@@ -256,6 +266,7 @@ class BlenderSync {
|
||||
string name;
|
||||
BL::Material material_override;
|
||||
bool use_background_shader;
|
||||
bool use_background_ao;
|
||||
bool use_surfaces;
|
||||
bool use_hair;
|
||||
bool use_volumes;
|
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "blender/texture.h"
|
||||
#include "blender/blender_texture.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
@@ -17,7 +17,7 @@
|
||||
#ifndef __BLENDER_TEXTURE_H__
|
||||
#define __BLENDER_TEXTURE_H__
|
||||
|
||||
#include "blender/sync.h"
|
||||
#include "blender/blender_sync.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
@@ -17,16 +17,16 @@
|
||||
#ifndef __BLENDER_UTIL_H__
|
||||
#define __BLENDER_UTIL_H__
|
||||
|
||||
#include "scene/mesh.h"
|
||||
#include "render/mesh.h"
|
||||
|
||||
#include "util/algorithm.h"
|
||||
#include "util/array.h"
|
||||
#include "util/map.h"
|
||||
#include "util/path.h"
|
||||
#include "util/set.h"
|
||||
#include "util/transform.h"
|
||||
#include "util/types.h"
|
||||
#include "util/vector.h"
|
||||
#include "util/util_algorithm.h"
|
||||
#include "util/util_array.h"
|
||||
#include "util/util_map.h"
|
||||
#include "util/util_path.h"
|
||||
#include "util/util_set.h"
|
||||
#include "util/util_transform.h"
|
||||
#include "util/util_types.h"
|
||||
#include "util/util_vector.h"
|
||||
|
||||
/* Hacks to hook into Blender API
|
||||
* todo: clean this up ... */
|
||||
@@ -90,27 +90,26 @@ static inline BL::Mesh object_to_mesh(BL::BlendData & /*data*/,
|
||||
}
|
||||
#endif
|
||||
|
||||
BL::Mesh mesh = (b_ob_info.object_data.is_a(&RNA_Mesh)) ? BL::Mesh(b_ob_info.object_data) :
|
||||
BL::Mesh(PointerRNA_NULL);
|
||||
BL::Mesh mesh(PointerRNA_NULL);
|
||||
if (b_ob_info.object_data.is_a(&RNA_Mesh)) {
|
||||
/* TODO: calc_undeformed is not used. */
|
||||
mesh = BL::Mesh(b_ob_info.object_data);
|
||||
|
||||
if (b_ob_info.is_real_object_data()) {
|
||||
if (mesh) {
|
||||
/* Make a copy to split faces if we use autosmooth, otherwise not needed.
|
||||
* Also in edit mode do we need to make a copy, to ensure data layers like
|
||||
* UV are not empty. */
|
||||
if (mesh.is_editmode() ||
|
||||
(mesh.use_auto_smooth() && subdivision_type == Mesh::SUBDIVISION_NONE)) {
|
||||
BL::Depsgraph depsgraph(PointerRNA_NULL);
|
||||
mesh = b_ob_info.real_object.to_mesh(false, depsgraph);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Make a copy to split faces if we use autosmooth, otherwise not needed.
|
||||
* Also in edit mode do we need to make a copy, to ensure data layers like
|
||||
* UV are not empty. */
|
||||
if (mesh.is_editmode() ||
|
||||
(mesh.use_auto_smooth() && subdivision_type == Mesh::SUBDIVISION_NONE)) {
|
||||
BL::Depsgraph depsgraph(PointerRNA_NULL);
|
||||
assert(b_ob_info.is_real_object_data());
|
||||
mesh = b_ob_info.real_object.to_mesh(false, depsgraph);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* TODO: what to do about non-mesh geometry instances? */
|
||||
BL::Depsgraph depsgraph(PointerRNA_NULL);
|
||||
if (b_ob_info.is_real_object_data()) {
|
||||
mesh = b_ob_info.real_object.to_mesh(false, depsgraph);
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
@@ -171,11 +170,12 @@ static inline void curvemap_minmax_curve(/*const*/ BL::CurveMap &curve, float *m
|
||||
}
|
||||
|
||||
static inline void curvemapping_minmax(/*const*/ BL::CurveMapping &cumap,
|
||||
int num_curves,
|
||||
bool rgb_curve,
|
||||
float *min_x,
|
||||
float *max_x)
|
||||
{
|
||||
// const int num_curves = cumap.curves.length(); /* Gives linking error so far. */
|
||||
const int num_curves = rgb_curve ? 4 : 3;
|
||||
*min_x = FLT_MAX;
|
||||
*max_x = -FLT_MAX;
|
||||
for (int i = 0; i < num_curves; ++i) {
|
||||
@@ -195,28 +195,6 @@ static inline void curvemapping_to_array(BL::CurveMapping &cumap, array<float> &
|
||||
}
|
||||
}
|
||||
|
||||
static inline void curvemapping_float_to_array(BL::CurveMapping &cumap,
|
||||
array<float> &data,
|
||||
int size)
|
||||
{
|
||||
float min = 0.0f, max = 1.0f;
|
||||
|
||||
curvemapping_minmax(cumap, 1, &min, &max);
|
||||
|
||||
const float range = max - min;
|
||||
|
||||
cumap.update();
|
||||
|
||||
BL::CurveMap map = cumap.curves[0];
|
||||
|
||||
data.resize(size);
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
float t = min + (float)i / (float)(size - 1) * range;
|
||||
data[i] = cumap.evaluate(map, t);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void curvemapping_color_to_array(BL::CurveMapping &cumap,
|
||||
array<float3> &data,
|
||||
int size,
|
||||
@@ -235,8 +213,7 @@ static inline void curvemapping_color_to_array(BL::CurveMapping &cumap,
|
||||
*
|
||||
* There might be some better estimations here tho.
|
||||
*/
|
||||
const int num_curves = rgb_curve ? 4 : 3;
|
||||
curvemapping_minmax(cumap, num_curves, &min_x, &max_x);
|
||||
curvemapping_minmax(cumap, rgb_curve, &min_x, &max_x);
|
||||
|
||||
const float range_x = max_x - min_x;
|
||||
|
@@ -14,12 +14,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "blender/viewport.h"
|
||||
#include "blender/util.h"
|
||||
#include "blender_viewport.h"
|
||||
|
||||
#include "scene/pass.h"
|
||||
|
||||
#include "util/log.h"
|
||||
#include "blender_util.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
@@ -29,12 +26,11 @@ BlenderViewportParameters::BlenderViewportParameters()
|
||||
studiolight_rotate_z(0.0f),
|
||||
studiolight_intensity(1.0f),
|
||||
studiolight_background_alpha(1.0f),
|
||||
display_pass(PASS_COMBINED),
|
||||
show_active_pixels(false)
|
||||
display_pass(PASS_COMBINED)
|
||||
{
|
||||
}
|
||||
|
||||
BlenderViewportParameters::BlenderViewportParameters(BL::SpaceView3D &b_v3d, bool use_developer_ui)
|
||||
BlenderViewportParameters::BlenderViewportParameters(BL::SpaceView3D &b_v3d)
|
||||
: BlenderViewportParameters()
|
||||
{
|
||||
if (!b_v3d) {
|
||||
@@ -59,25 +55,7 @@ BlenderViewportParameters::BlenderViewportParameters(BL::SpaceView3D &b_v3d, boo
|
||||
}
|
||||
|
||||
/* Film. */
|
||||
|
||||
/* Lookup display pass based on the enum identifier.
|
||||
* This is because integer values of python enum are not aligned with the passes definition in
|
||||
* the kernel. */
|
||||
|
||||
display_pass = PASS_COMBINED;
|
||||
|
||||
const string display_pass_identifier = get_enum_identifier(cshading, "render_pass");
|
||||
if (!display_pass_identifier.empty()) {
|
||||
const ustring pass_type_identifier(string_to_lower(display_pass_identifier));
|
||||
const NodeEnum *pass_type_enum = Pass::get_type_enum();
|
||||
if (pass_type_enum->exists(pass_type_identifier)) {
|
||||
display_pass = static_cast<PassType>((*pass_type_enum)[pass_type_identifier]);
|
||||
}
|
||||
}
|
||||
|
||||
if (use_developer_ui) {
|
||||
show_active_pixels = get_boolean(cshading, "show_active_pixels");
|
||||
}
|
||||
display_pass = (PassType)get_enum(cshading, "render_pass", -1, -1);
|
||||
}
|
||||
|
||||
bool BlenderViewportParameters::shader_modified(const BlenderViewportParameters &other) const
|
||||
@@ -91,7 +69,7 @@ bool BlenderViewportParameters::shader_modified(const BlenderViewportParameters
|
||||
|
||||
bool BlenderViewportParameters::film_modified(const BlenderViewportParameters &other) const
|
||||
{
|
||||
return display_pass != other.display_pass || show_active_pixels != other.show_active_pixels;
|
||||
return display_pass != other.display_pass;
|
||||
}
|
||||
|
||||
bool BlenderViewportParameters::modified(const BlenderViewportParameters &other) const
|
||||
@@ -104,4 +82,18 @@ bool BlenderViewportParameters::use_custom_shader() const
|
||||
return !(use_scene_world && use_scene_lights);
|
||||
}
|
||||
|
||||
PassType update_viewport_display_passes(BL::SpaceView3D &b_v3d, vector<Pass> &passes)
|
||||
{
|
||||
if (b_v3d) {
|
||||
const BlenderViewportParameters viewport_parameters(b_v3d);
|
||||
const PassType display_pass = viewport_parameters.display_pass;
|
||||
|
||||
passes.clear();
|
||||
Pass::add(display_pass, passes);
|
||||
|
||||
return display_pass;
|
||||
}
|
||||
return PASS_NONE;
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
@@ -23,7 +23,7 @@
|
||||
#include "RNA_blender_cpp.h"
|
||||
#include "RNA_types.h"
|
||||
|
||||
#include "scene/film.h"
|
||||
#include "render/film.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
@@ -39,10 +39,9 @@ class BlenderViewportParameters {
|
||||
|
||||
/* Film. */
|
||||
PassType display_pass;
|
||||
bool show_active_pixels;
|
||||
|
||||
BlenderViewportParameters();
|
||||
BlenderViewportParameters(BL::SpaceView3D &b_v3d, bool use_developer_ui);
|
||||
explicit BlenderViewportParameters(BL::SpaceView3D &b_v3d);
|
||||
|
||||
/* Check whether any of shading related settings are different from the given parameters. */
|
||||
bool shader_modified(const BlenderViewportParameters &other) const;
|
||||
@@ -58,6 +57,8 @@ class BlenderViewportParameters {
|
||||
bool use_custom_shader() const;
|
||||
};
|
||||
|
||||
PassType update_viewport_display_passes(BL::SpaceView3D &b_v3d, vector<Pass> &passes);
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
#endif
|
@@ -14,14 +14,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "scene/volume.h"
|
||||
#include "scene/colorspace.h"
|
||||
#include "scene/image.h"
|
||||
#include "scene/image_vdb.h"
|
||||
#include "scene/object.h"
|
||||
#include "render/colorspace.h"
|
||||
#include "render/image.h"
|
||||
#include "render/image_vdb.h"
|
||||
#include "render/object.h"
|
||||
#include "render/volume.h"
|
||||
|
||||
#include "blender/sync.h"
|
||||
#include "blender/util.h"
|
||||
#include "blender/blender_sync.h"
|
||||
#include "blender/blender_util.h"
|
||||
|
||||
#ifdef WITH_OPENVDB
|
||||
# include <openvdb/openvdb.h>
|
@@ -1,771 +0,0 @@
|
||||
/*
|
||||
* Copyright 2021 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 "blender/display_driver.h"
|
||||
|
||||
#include "device/device.h"
|
||||
#include "util/log.h"
|
||||
#include "util/opengl.h"
|
||||
|
||||
extern "C" {
|
||||
struct RenderEngine;
|
||||
|
||||
bool RE_engine_has_render_context(struct RenderEngine *engine);
|
||||
void RE_engine_render_context_enable(struct RenderEngine *engine);
|
||||
void RE_engine_render_context_disable(struct RenderEngine *engine);
|
||||
|
||||
bool DRW_opengl_context_release();
|
||||
void DRW_opengl_context_activate(bool drw_state);
|
||||
|
||||
void *WM_opengl_context_create();
|
||||
void WM_opengl_context_activate(void *gl_context);
|
||||
void WM_opengl_context_dispose(void *gl_context);
|
||||
void WM_opengl_context_release(void *context);
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* BlenderDisplayShader.
|
||||
*/
|
||||
|
||||
unique_ptr<BlenderDisplayShader> BlenderDisplayShader::create(BL::RenderEngine &b_engine,
|
||||
BL::Scene &b_scene)
|
||||
{
|
||||
if (b_engine.support_display_space_shader(b_scene)) {
|
||||
return make_unique<BlenderDisplaySpaceShader>(b_engine, b_scene);
|
||||
}
|
||||
|
||||
return make_unique<BlenderFallbackDisplayShader>();
|
||||
}
|
||||
|
||||
int BlenderDisplayShader::get_position_attrib_location()
|
||||
{
|
||||
if (position_attribute_location_ == -1) {
|
||||
const uint shader_program = get_shader_program();
|
||||
position_attribute_location_ = glGetAttribLocation(shader_program, position_attribute_name);
|
||||
}
|
||||
return position_attribute_location_;
|
||||
}
|
||||
|
||||
int BlenderDisplayShader::get_tex_coord_attrib_location()
|
||||
{
|
||||
if (tex_coord_attribute_location_ == -1) {
|
||||
const uint shader_program = get_shader_program();
|
||||
tex_coord_attribute_location_ = glGetAttribLocation(shader_program, tex_coord_attribute_name);
|
||||
}
|
||||
return tex_coord_attribute_location_;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* BlenderFallbackDisplayShader.
|
||||
*/
|
||||
|
||||
/* TODO move shaders to standalone .glsl file. */
|
||||
static const char *FALLBACK_VERTEX_SHADER =
|
||||
"#version 330\n"
|
||||
"uniform vec2 fullscreen;\n"
|
||||
"in vec2 texCoord;\n"
|
||||
"in vec2 pos;\n"
|
||||
"out vec2 texCoord_interp;\n"
|
||||
"\n"
|
||||
"vec2 normalize_coordinates()\n"
|
||||
"{\n"
|
||||
" return (vec2(2.0) * (pos / fullscreen)) - vec2(1.0);\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" gl_Position = vec4(normalize_coordinates(), 0.0, 1.0);\n"
|
||||
" texCoord_interp = texCoord;\n"
|
||||
"}\n\0";
|
||||
|
||||
static const char *FALLBACK_FRAGMENT_SHADER =
|
||||
"#version 330\n"
|
||||
"uniform sampler2D image_texture;\n"
|
||||
"in vec2 texCoord_interp;\n"
|
||||
"out vec4 fragColor;\n"
|
||||
"\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" fragColor = texture(image_texture, texCoord_interp);\n"
|
||||
"}\n\0";
|
||||
|
||||
static void shader_print_errors(const char *task, const char *log, const char *code)
|
||||
{
|
||||
LOG(ERROR) << "Shader: " << task << " error:";
|
||||
LOG(ERROR) << "===== shader string ====";
|
||||
|
||||
stringstream stream(code);
|
||||
string partial;
|
||||
|
||||
int line = 1;
|
||||
while (getline(stream, partial, '\n')) {
|
||||
if (line < 10) {
|
||||
LOG(ERROR) << " " << line << " " << partial;
|
||||
}
|
||||
else {
|
||||
LOG(ERROR) << line << " " << partial;
|
||||
}
|
||||
line++;
|
||||
}
|
||||
LOG(ERROR) << log;
|
||||
}
|
||||
|
||||
static int compile_fallback_shader(void)
|
||||
{
|
||||
const struct Shader {
|
||||
const char *source;
|
||||
const GLenum type;
|
||||
} shaders[2] = {{FALLBACK_VERTEX_SHADER, GL_VERTEX_SHADER},
|
||||
{FALLBACK_FRAGMENT_SHADER, GL_FRAGMENT_SHADER}};
|
||||
|
||||
const GLuint program = glCreateProgram();
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
const GLuint shader = glCreateShader(shaders[i].type);
|
||||
|
||||
string source_str = shaders[i].source;
|
||||
const char *c_str = source_str.c_str();
|
||||
|
||||
glShaderSource(shader, 1, &c_str, NULL);
|
||||
glCompileShader(shader);
|
||||
|
||||
GLint compile_status;
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &compile_status);
|
||||
|
||||
if (!compile_status) {
|
||||
GLchar log[5000];
|
||||
GLsizei length = 0;
|
||||
glGetShaderInfoLog(shader, sizeof(log), &length, log);
|
||||
shader_print_errors("compile", log, c_str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
glAttachShader(program, shader);
|
||||
}
|
||||
|
||||
/* Link output. */
|
||||
glBindFragDataLocation(program, 0, "fragColor");
|
||||
|
||||
/* Link and error check. */
|
||||
glLinkProgram(program);
|
||||
|
||||
/* TODO(sergey): Find a way to nicely de-duplicate the error checking. */
|
||||
GLint link_status;
|
||||
glGetProgramiv(program, GL_LINK_STATUS, &link_status);
|
||||
if (!link_status) {
|
||||
GLchar log[5000];
|
||||
GLsizei length = 0;
|
||||
/* TODO(sergey): Is it really program passed to glGetShaderInfoLog? */
|
||||
glGetShaderInfoLog(program, sizeof(log), &length, log);
|
||||
shader_print_errors("linking", log, FALLBACK_VERTEX_SHADER);
|
||||
shader_print_errors("linking", log, FALLBACK_FRAGMENT_SHADER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return program;
|
||||
}
|
||||
|
||||
void BlenderFallbackDisplayShader::bind(int width, int height)
|
||||
{
|
||||
create_shader_if_needed();
|
||||
|
||||
if (!shader_program_) {
|
||||
return;
|
||||
}
|
||||
|
||||
glUseProgram(shader_program_);
|
||||
glUniform1i(image_texture_location_, 0);
|
||||
glUniform2f(fullscreen_location_, width, height);
|
||||
}
|
||||
|
||||
void BlenderFallbackDisplayShader::unbind()
|
||||
{
|
||||
}
|
||||
|
||||
uint BlenderFallbackDisplayShader::get_shader_program()
|
||||
{
|
||||
return shader_program_;
|
||||
}
|
||||
|
||||
void BlenderFallbackDisplayShader::create_shader_if_needed()
|
||||
{
|
||||
if (shader_program_ || shader_compile_attempted_) {
|
||||
return;
|
||||
}
|
||||
|
||||
shader_compile_attempted_ = true;
|
||||
|
||||
shader_program_ = compile_fallback_shader();
|
||||
if (!shader_program_) {
|
||||
return;
|
||||
}
|
||||
|
||||
glUseProgram(shader_program_);
|
||||
|
||||
image_texture_location_ = glGetUniformLocation(shader_program_, "image_texture");
|
||||
if (image_texture_location_ < 0) {
|
||||
LOG(ERROR) << "Shader doesn't contain the 'image_texture' uniform.";
|
||||
destroy_shader();
|
||||
return;
|
||||
}
|
||||
|
||||
fullscreen_location_ = glGetUniformLocation(shader_program_, "fullscreen");
|
||||
if (fullscreen_location_ < 0) {
|
||||
LOG(ERROR) << "Shader doesn't contain the 'fullscreen' uniform.";
|
||||
destroy_shader();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void BlenderFallbackDisplayShader::destroy_shader()
|
||||
{
|
||||
glDeleteProgram(shader_program_);
|
||||
shader_program_ = 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* BlenderDisplaySpaceShader.
|
||||
*/
|
||||
|
||||
BlenderDisplaySpaceShader::BlenderDisplaySpaceShader(BL::RenderEngine &b_engine,
|
||||
BL::Scene &b_scene)
|
||||
: b_engine_(b_engine), b_scene_(b_scene)
|
||||
{
|
||||
DCHECK(b_engine_.support_display_space_shader(b_scene_));
|
||||
}
|
||||
|
||||
void BlenderDisplaySpaceShader::bind(int /*width*/, int /*height*/)
|
||||
{
|
||||
b_engine_.bind_display_space_shader(b_scene_);
|
||||
}
|
||||
|
||||
void BlenderDisplaySpaceShader::unbind()
|
||||
{
|
||||
b_engine_.unbind_display_space_shader();
|
||||
}
|
||||
|
||||
uint BlenderDisplaySpaceShader::get_shader_program()
|
||||
{
|
||||
if (!shader_program_) {
|
||||
glGetIntegerv(GL_CURRENT_PROGRAM, reinterpret_cast<int *>(&shader_program_));
|
||||
}
|
||||
|
||||
if (!shader_program_) {
|
||||
LOG(ERROR) << "Error retrieving shader program for display space shader.";
|
||||
}
|
||||
|
||||
return shader_program_;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* BlenderDisplayDriver.
|
||||
*/
|
||||
|
||||
BlenderDisplayDriver::BlenderDisplayDriver(BL::RenderEngine &b_engine, BL::Scene &b_scene)
|
||||
: b_engine_(b_engine), display_shader_(BlenderDisplayShader::create(b_engine, b_scene))
|
||||
{
|
||||
/* Create context while on the main thread. */
|
||||
gl_context_create();
|
||||
}
|
||||
|
||||
BlenderDisplayDriver::~BlenderDisplayDriver()
|
||||
{
|
||||
gl_resources_destroy();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Update procedure.
|
||||
*/
|
||||
|
||||
bool BlenderDisplayDriver::update_begin(const Params ¶ms,
|
||||
int texture_width,
|
||||
int texture_height)
|
||||
{
|
||||
/* Note that it's the responsibility of BlenderDisplayDriver to ensure updating and drawing
|
||||
* the texture does not happen at the same time. This is achieved indirectly.
|
||||
*
|
||||
* When enabling the OpenGL context, it uses an internal mutex lock DST.gl_context_lock.
|
||||
* This same lock is also held when do_draw() is called, which together ensure mutual
|
||||
* exclusion.
|
||||
*
|
||||
* This locking is not performed on the Cycles side, because that would cause lock inversion. */
|
||||
if (!gl_context_enable()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (gl_render_sync_) {
|
||||
glWaitSync((GLsync)gl_render_sync_, 0, GL_TIMEOUT_IGNORED);
|
||||
}
|
||||
|
||||
if (!gl_texture_resources_ensure()) {
|
||||
gl_context_disable();
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Update texture dimensions if needed. */
|
||||
if (texture_.width != texture_width || texture_.height != texture_height) {
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, texture_.gl_id);
|
||||
glTexImage2D(
|
||||
GL_TEXTURE_2D, 0, GL_RGBA16F, texture_width, texture_height, 0, GL_RGBA, GL_HALF_FLOAT, 0);
|
||||
texture_.width = texture_width;
|
||||
texture_.height = texture_height;
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
/* Texture did change, and no pixel storage was provided. Tag for an explicit zeroing out to
|
||||
* avoid undefined content. */
|
||||
texture_.need_clear = true;
|
||||
}
|
||||
|
||||
/* Update PBO dimensions if needed.
|
||||
*
|
||||
* NOTE: Allocate the PBO for the the size which will fit the final render resolution (as in,
|
||||
* at a resolution divider 1. This was we don't need to recreate graphics interoperability
|
||||
* objects which are costly and which are tied to the specific underlying buffer size.
|
||||
* The downside of this approach is that when graphics interoperability is not used we are
|
||||
* sending too much data to GPU when resolution divider is not 1. */
|
||||
/* TODO(sergey): Investigate whether keeping the PBO exact size of the texture makes non-interop
|
||||
* mode faster. */
|
||||
const int buffer_width = params.full_size.x;
|
||||
const int buffer_height = params.full_size.y;
|
||||
if (texture_.buffer_width != buffer_width || texture_.buffer_height != buffer_height) {
|
||||
const size_t size_in_bytes = sizeof(half4) * buffer_width * buffer_height;
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, texture_.gl_pbo_id);
|
||||
glBufferData(GL_PIXEL_UNPACK_BUFFER, size_in_bytes, 0, GL_DYNAMIC_DRAW);
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||
|
||||
texture_.buffer_width = buffer_width;
|
||||
texture_.buffer_height = buffer_height;
|
||||
}
|
||||
|
||||
/* New content will be provided to the texture in one way or another, so mark this in a
|
||||
* centralized place. */
|
||||
texture_.need_update = true;
|
||||
|
||||
texture_.params = params;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void BlenderDisplayDriver::update_end()
|
||||
{
|
||||
gl_upload_sync_ = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||
glFlush();
|
||||
|
||||
gl_context_disable();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Texture buffer mapping.
|
||||
*/
|
||||
|
||||
half4 *BlenderDisplayDriver::map_texture_buffer()
|
||||
{
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, texture_.gl_pbo_id);
|
||||
|
||||
half4 *mapped_rgba_pixels = reinterpret_cast<half4 *>(
|
||||
glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY));
|
||||
if (!mapped_rgba_pixels) {
|
||||
LOG(ERROR) << "Error mapping BlenderDisplayDriver pixel buffer object.";
|
||||
}
|
||||
|
||||
if (texture_.need_clear) {
|
||||
const int64_t texture_width = texture_.width;
|
||||
const int64_t texture_height = texture_.height;
|
||||
memset(reinterpret_cast<void *>(mapped_rgba_pixels),
|
||||
0,
|
||||
texture_width * texture_height * sizeof(half4));
|
||||
texture_.need_clear = false;
|
||||
}
|
||||
|
||||
return mapped_rgba_pixels;
|
||||
}
|
||||
|
||||
void BlenderDisplayDriver::unmap_texture_buffer()
|
||||
{
|
||||
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
|
||||
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Graphics interoperability.
|
||||
*/
|
||||
|
||||
BlenderDisplayDriver::GraphicsInterop BlenderDisplayDriver::graphics_interop_get()
|
||||
{
|
||||
GraphicsInterop interop_dst;
|
||||
|
||||
interop_dst.buffer_width = texture_.buffer_width;
|
||||
interop_dst.buffer_height = texture_.buffer_height;
|
||||
interop_dst.opengl_pbo_id = texture_.gl_pbo_id;
|
||||
|
||||
interop_dst.need_clear = texture_.need_clear;
|
||||
texture_.need_clear = false;
|
||||
|
||||
return interop_dst;
|
||||
}
|
||||
|
||||
void BlenderDisplayDriver::graphics_interop_activate()
|
||||
{
|
||||
gl_context_enable();
|
||||
}
|
||||
|
||||
void BlenderDisplayDriver::graphics_interop_deactivate()
|
||||
{
|
||||
gl_context_disable();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
* Drawing.
|
||||
*/
|
||||
|
||||
void BlenderDisplayDriver::clear()
|
||||
{
|
||||
texture_.need_clear = true;
|
||||
}
|
||||
|
||||
void BlenderDisplayDriver::set_zoom(float zoom_x, float zoom_y)
|
||||
{
|
||||
zoom_ = make_float2(zoom_x, zoom_y);
|
||||
}
|
||||
|
||||
void BlenderDisplayDriver::draw(const Params ¶ms)
|
||||
{
|
||||
/* See do_update_begin() for why no locking is required here. */
|
||||
const bool transparent = true; // TODO(sergey): Derive this from Film.
|
||||
|
||||
if (!gl_draw_resources_ensure()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (use_gl_context_) {
|
||||
gl_context_mutex_.lock();
|
||||
}
|
||||
|
||||
if (texture_.need_clear) {
|
||||
/* Texture is requested to be cleared and was not yet cleared.
|
||||
*
|
||||
* Do early return which should be equivalent of drawing all-zero texture.
|
||||
* Watch out for the lock though so that the clear happening during update is properly
|
||||
* synchronized here. */
|
||||
gl_context_mutex_.unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
if (gl_upload_sync_) {
|
||||
glWaitSync((GLsync)gl_upload_sync_, 0, GL_TIMEOUT_IGNORED);
|
||||
}
|
||||
|
||||
if (transparent) {
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
|
||||
display_shader_->bind(params.full_size.x, params.full_size.y);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, texture_.gl_id);
|
||||
|
||||
/* Trick to keep sharp rendering without jagged edges on all GPUs.
|
||||
*
|
||||
* The idea here is to enforce driver to use linear interpolation when the image is not zoomed
|
||||
* in.
|
||||
* For the render result with a resolution divider in effect we always use nearest interpolation.
|
||||
*
|
||||
* Use explicit MIN assignment to make sure the driver does not have an undefined behavior at
|
||||
* the zoom level 1. The MAG filter is always NEAREST. */
|
||||
const float zoomed_width = params.size.x * zoom_.x;
|
||||
const float zoomed_height = params.size.y * zoom_.y;
|
||||
if (texture_.width != params.size.x || texture_.height != params.size.y) {
|
||||
/* Resolution divider is different from 1, force nearest interpolation. */
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
}
|
||||
else if (zoomed_width - params.size.x > 0.5f || zoomed_height - params.size.y > 0.5f) {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
}
|
||||
else {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
}
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_);
|
||||
|
||||
texture_update_if_needed();
|
||||
vertex_buffer_update(params);
|
||||
|
||||
/* TODO(sergey): Does it make sense/possible to cache/reuse the VAO? */
|
||||
GLuint vertex_array_object;
|
||||
glGenVertexArrays(1, &vertex_array_object);
|
||||
glBindVertexArray(vertex_array_object);
|
||||
|
||||
const int texcoord_attribute = display_shader_->get_tex_coord_attrib_location();
|
||||
const int position_attribute = display_shader_->get_position_attrib_location();
|
||||
|
||||
glEnableVertexAttribArray(texcoord_attribute);
|
||||
glEnableVertexAttribArray(position_attribute);
|
||||
|
||||
glVertexAttribPointer(
|
||||
texcoord_attribute, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (const GLvoid *)0);
|
||||
glVertexAttribPointer(position_attribute,
|
||||
2,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
4 * sizeof(float),
|
||||
(const GLvoid *)(sizeof(float) * 2));
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
glDeleteVertexArrays(1, &vertex_array_object);
|
||||
|
||||
display_shader_->unbind();
|
||||
|
||||
if (transparent) {
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
gl_render_sync_ = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||
glFlush();
|
||||
|
||||
if (use_gl_context_) {
|
||||
gl_context_mutex_.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
void BlenderDisplayDriver::gl_context_create()
|
||||
{
|
||||
/* When rendering in viewport there is no render context available via engine.
|
||||
* Check whether own context is to be created here.
|
||||
*
|
||||
* NOTE: If the `b_engine_`'s context is not available, we are expected to be on a main thread
|
||||
* here. */
|
||||
use_gl_context_ = !RE_engine_has_render_context(
|
||||
reinterpret_cast<RenderEngine *>(b_engine_.ptr.data));
|
||||
|
||||
if (use_gl_context_) {
|
||||
const bool drw_state = DRW_opengl_context_release();
|
||||
gl_context_ = WM_opengl_context_create();
|
||||
if (gl_context_) {
|
||||
/* On Windows an old context is restored after creation, and subsequent release of context
|
||||
* generates a Win32 error. Harmless for users, but annoying to have possible misleading
|
||||
* error prints in the console. */
|
||||
#ifndef _WIN32
|
||||
WM_opengl_context_release(gl_context_);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
LOG(ERROR) << "Error creating OpenGL context.";
|
||||
}
|
||||
|
||||
DRW_opengl_context_activate(drw_state);
|
||||
}
|
||||
}
|
||||
|
||||
bool BlenderDisplayDriver::gl_context_enable()
|
||||
{
|
||||
if (use_gl_context_) {
|
||||
if (!gl_context_) {
|
||||
return false;
|
||||
}
|
||||
gl_context_mutex_.lock();
|
||||
WM_opengl_context_activate(gl_context_);
|
||||
return true;
|
||||
}
|
||||
|
||||
RE_engine_render_context_enable(reinterpret_cast<RenderEngine *>(b_engine_.ptr.data));
|
||||
return true;
|
||||
}
|
||||
|
||||
void BlenderDisplayDriver::gl_context_disable()
|
||||
{
|
||||
if (use_gl_context_) {
|
||||
if (gl_context_) {
|
||||
WM_opengl_context_release(gl_context_);
|
||||
gl_context_mutex_.unlock();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
RE_engine_render_context_disable(reinterpret_cast<RenderEngine *>(b_engine_.ptr.data));
|
||||
}
|
||||
|
||||
void BlenderDisplayDriver::gl_context_dispose()
|
||||
{
|
||||
if (gl_context_) {
|
||||
const bool drw_state = DRW_opengl_context_release();
|
||||
|
||||
WM_opengl_context_activate(gl_context_);
|
||||
WM_opengl_context_dispose(gl_context_);
|
||||
|
||||
DRW_opengl_context_activate(drw_state);
|
||||
}
|
||||
}
|
||||
|
||||
bool BlenderDisplayDriver::gl_draw_resources_ensure()
|
||||
{
|
||||
if (!texture_.gl_id) {
|
||||
/* If there is no texture allocated, there is nothing to draw. Inform the draw call that it can
|
||||
* can not continue. Note that this is not an unrecoverable error, so once the texture is known
|
||||
* we will come back here and create all the GPU resources needed for draw. */
|
||||
return false;
|
||||
}
|
||||
|
||||
if (gl_draw_resource_creation_attempted_) {
|
||||
return gl_draw_resources_created_;
|
||||
}
|
||||
gl_draw_resource_creation_attempted_ = true;
|
||||
|
||||
if (!vertex_buffer_) {
|
||||
glGenBuffers(1, &vertex_buffer_);
|
||||
if (!vertex_buffer_) {
|
||||
LOG(ERROR) << "Error creating vertex buffer.";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
gl_draw_resources_created_ = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void BlenderDisplayDriver::gl_resources_destroy()
|
||||
{
|
||||
gl_context_enable();
|
||||
|
||||
if (vertex_buffer_ != 0) {
|
||||
glDeleteBuffers(1, &vertex_buffer_);
|
||||
}
|
||||
|
||||
if (texture_.gl_pbo_id) {
|
||||
glDeleteBuffers(1, &texture_.gl_pbo_id);
|
||||
texture_.gl_pbo_id = 0;
|
||||
}
|
||||
|
||||
if (texture_.gl_id) {
|
||||
glDeleteTextures(1, &texture_.gl_id);
|
||||
texture_.gl_id = 0;
|
||||
}
|
||||
|
||||
gl_context_disable();
|
||||
|
||||
gl_context_dispose();
|
||||
}
|
||||
|
||||
bool BlenderDisplayDriver::gl_texture_resources_ensure()
|
||||
{
|
||||
if (texture_.creation_attempted) {
|
||||
return texture_.is_created;
|
||||
}
|
||||
texture_.creation_attempted = true;
|
||||
|
||||
DCHECK(!texture_.gl_id);
|
||||
DCHECK(!texture_.gl_pbo_id);
|
||||
|
||||
/* Create texture. */
|
||||
glGenTextures(1, &texture_.gl_id);
|
||||
if (!texture_.gl_id) {
|
||||
LOG(ERROR) << "Error creating texture.";
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Configure the texture. */
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, texture_.gl_id);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
/* Create PBO for the texture. */
|
||||
glGenBuffers(1, &texture_.gl_pbo_id);
|
||||
if (!texture_.gl_pbo_id) {
|
||||
LOG(ERROR) << "Error creating texture pixel buffer object.";
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Creation finished with a success. */
|
||||
texture_.is_created = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void BlenderDisplayDriver::texture_update_if_needed()
|
||||
{
|
||||
if (!texture_.need_update) {
|
||||
return;
|
||||
}
|
||||
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, texture_.gl_pbo_id);
|
||||
glTexSubImage2D(
|
||||
GL_TEXTURE_2D, 0, 0, 0, texture_.width, texture_.height, GL_RGBA, GL_HALF_FLOAT, 0);
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||
|
||||
texture_.need_update = false;
|
||||
}
|
||||
|
||||
void BlenderDisplayDriver::vertex_buffer_update(const Params & /*params*/)
|
||||
{
|
||||
/* Draw at the parameters for which the texture has been updated for. This allows to always draw
|
||||
* texture during bordered-rendered camera view without flickering. The validness of the display
|
||||
* parameters for a texture is guaranteed by the initial "clear" state which makes drawing to
|
||||
* have an early output.
|
||||
*
|
||||
* Such approach can cause some extra "jelly" effect during panning, but it is not more jelly
|
||||
* than overlay of selected objects. Also, it's possible to redraw texture at an intersection of
|
||||
* the texture draw parameters and the latest updated draw parameters (although, complexity of
|
||||
* doing it might not worth it. */
|
||||
const int x = texture_.params.full_offset.x;
|
||||
const int y = texture_.params.full_offset.y;
|
||||
|
||||
const int width = texture_.params.size.x;
|
||||
const int height = texture_.params.size.y;
|
||||
|
||||
/* Invalidate old contents - avoids stalling if the buffer is still waiting in queue to be
|
||||
* rendered. */
|
||||
glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(float), NULL, GL_STREAM_DRAW);
|
||||
|
||||
float *vpointer = reinterpret_cast<float *>(glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY));
|
||||
if (!vpointer) {
|
||||
return;
|
||||
}
|
||||
|
||||
vpointer[0] = 0.0f;
|
||||
vpointer[1] = 0.0f;
|
||||
vpointer[2] = x;
|
||||
vpointer[3] = y;
|
||||
|
||||
vpointer[4] = 1.0f;
|
||||
vpointer[5] = 0.0f;
|
||||
vpointer[6] = x + width;
|
||||
vpointer[7] = y;
|
||||
|
||||
vpointer[8] = 1.0f;
|
||||
vpointer[9] = 1.0f;
|
||||
vpointer[10] = x + width;
|
||||
vpointer[11] = y + height;
|
||||
|
||||
vpointer[12] = 0.0f;
|
||||
vpointer[13] = 1.0f;
|
||||
vpointer[14] = x;
|
||||
vpointer[15] = y + height;
|
||||
|
||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
@@ -1,213 +0,0 @@
|
||||
/*
|
||||
* Copyright 2021 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "RNA_blender_cpp.h"
|
||||
|
||||
#include "session/display_driver.h"
|
||||
|
||||
#include "util/thread.h"
|
||||
#include "util/unique_ptr.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
/* Base class of shader used for display driver rendering. */
|
||||
class BlenderDisplayShader {
|
||||
public:
|
||||
static constexpr const char *position_attribute_name = "pos";
|
||||
static constexpr const char *tex_coord_attribute_name = "texCoord";
|
||||
|
||||
/* Create shader implementation suitable for the given render engine and scene configuration. */
|
||||
static unique_ptr<BlenderDisplayShader> create(BL::RenderEngine &b_engine, BL::Scene &b_scene);
|
||||
|
||||
BlenderDisplayShader() = default;
|
||||
virtual ~BlenderDisplayShader() = default;
|
||||
|
||||
virtual void bind(int width, int height) = 0;
|
||||
virtual void unbind() = 0;
|
||||
|
||||
/* Get attribute location for position and texture coordinate respectively.
|
||||
* NOTE: The shader needs to be bound to have access to those. */
|
||||
virtual int get_position_attrib_location();
|
||||
virtual int get_tex_coord_attrib_location();
|
||||
|
||||
protected:
|
||||
/* Get program of this display shader.
|
||||
* NOTE: The shader needs to be bound to have access to this. */
|
||||
virtual uint get_shader_program() = 0;
|
||||
|
||||
/* Cached values of various OpenGL resources. */
|
||||
int position_attribute_location_ = -1;
|
||||
int tex_coord_attribute_location_ = -1;
|
||||
};
|
||||
|
||||
/* Implementation of display rendering shader used in the case when render engine does not support
|
||||
* display space shader. */
|
||||
class BlenderFallbackDisplayShader : public BlenderDisplayShader {
|
||||
public:
|
||||
virtual void bind(int width, int height) override;
|
||||
virtual void unbind() override;
|
||||
|
||||
protected:
|
||||
virtual uint get_shader_program() override;
|
||||
|
||||
void create_shader_if_needed();
|
||||
void destroy_shader();
|
||||
|
||||
uint shader_program_ = 0;
|
||||
int image_texture_location_ = -1;
|
||||
int fullscreen_location_ = -1;
|
||||
|
||||
/* Shader compilation attempted. Which means, that if the shader program is 0 then compilation or
|
||||
* linking has failed. Do not attempt to re-compile the shader. */
|
||||
bool shader_compile_attempted_ = false;
|
||||
};
|
||||
|
||||
class BlenderDisplaySpaceShader : public BlenderDisplayShader {
|
||||
public:
|
||||
BlenderDisplaySpaceShader(BL::RenderEngine &b_engine, BL::Scene &b_scene);
|
||||
|
||||
virtual void bind(int width, int height) override;
|
||||
virtual void unbind() override;
|
||||
|
||||
protected:
|
||||
virtual uint get_shader_program() override;
|
||||
|
||||
BL::RenderEngine b_engine_;
|
||||
BL::Scene &b_scene_;
|
||||
|
||||
/* Cached values of various OpenGL resources. */
|
||||
uint shader_program_ = 0;
|
||||
};
|
||||
|
||||
/* Display driver implementation which is specific for Blender viewport integration. */
|
||||
class BlenderDisplayDriver : public DisplayDriver {
|
||||
public:
|
||||
BlenderDisplayDriver(BL::RenderEngine &b_engine, BL::Scene &b_scene);
|
||||
~BlenderDisplayDriver();
|
||||
|
||||
virtual void graphics_interop_activate() override;
|
||||
virtual void graphics_interop_deactivate() override;
|
||||
|
||||
virtual void clear() override;
|
||||
|
||||
void set_zoom(float zoom_x, float zoom_y);
|
||||
|
||||
protected:
|
||||
virtual bool update_begin(const Params ¶ms, int texture_width, int texture_height) override;
|
||||
virtual void update_end() override;
|
||||
|
||||
virtual half4 *map_texture_buffer() override;
|
||||
virtual void unmap_texture_buffer() override;
|
||||
|
||||
virtual GraphicsInterop graphics_interop_get() override;
|
||||
|
||||
virtual void draw(const Params ¶ms) override;
|
||||
|
||||
/* Helper function which allocates new GPU context. */
|
||||
void gl_context_create();
|
||||
bool gl_context_enable();
|
||||
void gl_context_disable();
|
||||
void gl_context_dispose();
|
||||
|
||||
/* Make sure texture is allocated and its initial configuration is performed. */
|
||||
bool gl_texture_resources_ensure();
|
||||
|
||||
/* Ensure all runtime GPU resources needed for drawing are allocated.
|
||||
* Returns true if all resources needed for drawing are available. */
|
||||
bool gl_draw_resources_ensure();
|
||||
|
||||
/* Destroy all GPU resources which are being used by this object. */
|
||||
void gl_resources_destroy();
|
||||
|
||||
/* Update GPU texture dimensions and content if needed (new pixel data was provided).
|
||||
*
|
||||
* NOTE: The texture needs to be bound. */
|
||||
void texture_update_if_needed();
|
||||
|
||||
/* Update vertex buffer with new coordinates of vertex positions and texture coordinates.
|
||||
* This buffer is used to render texture in the viewport.
|
||||
*
|
||||
* NOTE: The buffer needs to be bound. */
|
||||
void vertex_buffer_update(const Params ¶ms);
|
||||
|
||||
BL::RenderEngine b_engine_;
|
||||
|
||||
/* OpenGL context which is used the render engine doesn't have its own. */
|
||||
void *gl_context_ = nullptr;
|
||||
/* The when Blender RenderEngine side context is not available and the DisplayDriver is to create
|
||||
* its own context. */
|
||||
bool use_gl_context_ = false;
|
||||
/* Mutex used to guard the `gl_context_`. */
|
||||
thread_mutex gl_context_mutex_;
|
||||
|
||||
/* Texture which contains pixels of the render result. */
|
||||
struct {
|
||||
/* Indicates whether texture creation was attempted and succeeded.
|
||||
* Used to avoid multiple attempts of texture creation on GPU issues or GPU context
|
||||
* misconfiguration. */
|
||||
bool creation_attempted = false;
|
||||
bool is_created = false;
|
||||
|
||||
/* OpenGL resource IDs of the texture itself and Pixel Buffer Object (PBO) used to write
|
||||
* pixels to it.
|
||||
*
|
||||
* NOTE: Allocated on the engine's context. */
|
||||
uint gl_id = 0;
|
||||
uint gl_pbo_id = 0;
|
||||
|
||||
/* Is true when new data was written to the PBO, meaning, the texture might need to be resized
|
||||
* and new data is to be uploaded to the GPU. */
|
||||
bool need_update = false;
|
||||
|
||||
/* Content of the texture is to be filled with zeroes. */
|
||||
std::atomic<bool> need_clear = true;
|
||||
|
||||
/* Dimensions of the texture in pixels. */
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
|
||||
/* Dimensions of the underlying PBO. */
|
||||
int buffer_width = 0;
|
||||
int buffer_height = 0;
|
||||
|
||||
/* Display parameters the texture has been updated for. */
|
||||
Params params;
|
||||
} texture_;
|
||||
|
||||
unique_ptr<BlenderDisplayShader> display_shader_;
|
||||
|
||||
/* Special track of whether GPU resources were attempted to be created, to avoid attempts of
|
||||
* their re-creation on failure on every redraw. */
|
||||
bool gl_draw_resource_creation_attempted_ = false;
|
||||
bool gl_draw_resources_created_ = false;
|
||||
|
||||
/* Vertex buffer which hold vertices of a triangle fan which is textures with the texture
|
||||
* holding the render result. */
|
||||
uint vertex_buffer_ = 0;
|
||||
|
||||
void *gl_render_sync_ = nullptr;
|
||||
void *gl_upload_sync_ = nullptr;
|
||||
|
||||
float2 zoom_ = make_float2(1.0f, 1.0f);
|
||||
};
|
||||
|
||||
CCL_NAMESPACE_END
|
@@ -1,126 +0,0 @@
|
||||
/*
|
||||
* Copyright 2021 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 "blender/output_driver.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
BlenderOutputDriver::BlenderOutputDriver(BL::RenderEngine &b_engine) : b_engine_(b_engine)
|
||||
{
|
||||
}
|
||||
|
||||
BlenderOutputDriver::~BlenderOutputDriver()
|
||||
{
|
||||
}
|
||||
|
||||
bool BlenderOutputDriver::read_render_tile(const Tile &tile)
|
||||
{
|
||||
/* Get render result. */
|
||||
BL::RenderResult b_rr = b_engine_.begin_result(tile.offset.x,
|
||||
tile.offset.y,
|
||||
tile.size.x,
|
||||
tile.size.y,
|
||||
tile.layer.c_str(),
|
||||
tile.view.c_str());
|
||||
|
||||
/* Can happen if the intersected rectangle gives 0 width or height. */
|
||||
if (b_rr.ptr.data == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
BL::RenderResult::layers_iterator b_single_rlay;
|
||||
b_rr.layers.begin(b_single_rlay);
|
||||
|
||||
/* layer will be missing if it was disabled in the UI */
|
||||
if (b_single_rlay == b_rr.layers.end()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
BL::RenderLayer b_rlay = *b_single_rlay;
|
||||
|
||||
vector<float> pixels(tile.size.x * tile.size.y * 4);
|
||||
|
||||
/* Copy each pass.
|
||||
* TODO:copy only the required ones for better performance? */
|
||||
for (BL::RenderPass &b_pass : b_rlay.passes) {
|
||||
tile.set_pass_pixels(b_pass.name(), b_pass.channels(), (float *)b_pass.rect());
|
||||
}
|
||||
|
||||
b_engine_.end_result(b_rr, false, false, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BlenderOutputDriver::update_render_tile(const Tile &tile)
|
||||
{
|
||||
/* Use final write for preview renders, otherwise render result wouldn't be be updated
|
||||
* quickly on Blender side. For all other cases we use the display driver. */
|
||||
if (b_engine_.is_preview()) {
|
||||
write_render_tile(tile);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Don't highlight full-frame tile. */
|
||||
if (!(tile.size == tile.full_size)) {
|
||||
b_engine_.tile_highlight_clear_all();
|
||||
b_engine_.tile_highlight_set(tile.offset.x, tile.offset.y, tile.size.x, tile.size.y, true);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void BlenderOutputDriver::write_render_tile(const Tile &tile)
|
||||
{
|
||||
b_engine_.tile_highlight_clear_all();
|
||||
|
||||
/* Get render result. */
|
||||
BL::RenderResult b_rr = b_engine_.begin_result(tile.offset.x,
|
||||
tile.offset.y,
|
||||
tile.size.x,
|
||||
tile.size.y,
|
||||
tile.layer.c_str(),
|
||||
tile.view.c_str());
|
||||
|
||||
/* Can happen if the intersected rectangle gives 0 width or height. */
|
||||
if (b_rr.ptr.data == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
BL::RenderResult::layers_iterator b_single_rlay;
|
||||
b_rr.layers.begin(b_single_rlay);
|
||||
|
||||
/* Layer will be missing if it was disabled in the UI. */
|
||||
if (b_single_rlay == b_rr.layers.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
BL::RenderLayer b_rlay = *b_single_rlay;
|
||||
|
||||
vector<float> pixels(tile.size.x * tile.size.y * 4);
|
||||
|
||||
/* Copy each pass. */
|
||||
for (BL::RenderPass &b_pass : b_rlay.passes) {
|
||||
if (!tile.get_pass_pixels(b_pass.name(), b_pass.channels(), &pixels[0])) {
|
||||
memset(&pixels[0], 0, pixels.size() * sizeof(float));
|
||||
}
|
||||
|
||||
b_pass.rect(&pixels[0]);
|
||||
}
|
||||
|
||||
b_engine_.end_result(b_rr, true, false, true);
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Copyright 2021 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "RNA_blender_cpp.h"
|
||||
|
||||
#include "session/output_driver.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
class BlenderOutputDriver : public OutputDriver {
|
||||
public:
|
||||
explicit BlenderOutputDriver(BL::RenderEngine &b_engine);
|
||||
~BlenderOutputDriver();
|
||||
|
||||
virtual void write_render_tile(const Tile &tile) override;
|
||||
virtual bool update_render_tile(const Tile &tile) override;
|
||||
virtual bool read_render_tile(const Tile &tile) override;
|
||||
|
||||
protected:
|
||||
BL::RenderEngine b_engine_;
|
||||
};
|
||||
|
||||
CCL_NAMESPACE_END
|
@@ -22,34 +22,34 @@ set(INC_SYS
|
||||
set(SRC
|
||||
bvh.cpp
|
||||
bvh2.cpp
|
||||
binning.cpp
|
||||
build.cpp
|
||||
embree.cpp
|
||||
multi.cpp
|
||||
node.cpp
|
||||
optix.cpp
|
||||
sort.cpp
|
||||
split.cpp
|
||||
unaligned.cpp
|
||||
bvh_binning.cpp
|
||||
bvh_build.cpp
|
||||
bvh_embree.cpp
|
||||
bvh_multi.cpp
|
||||
bvh_node.cpp
|
||||
bvh_optix.cpp
|
||||
bvh_sort.cpp
|
||||
bvh_split.cpp
|
||||
bvh_unaligned.cpp
|
||||
)
|
||||
|
||||
set(SRC_HEADERS
|
||||
bvh.h
|
||||
bvh2.h
|
||||
binning.h
|
||||
build.h
|
||||
embree.h
|
||||
multi.h
|
||||
node.h
|
||||
optix.h
|
||||
params.h
|
||||
sort.h
|
||||
split.h
|
||||
unaligned.h
|
||||
bvh_binning.h
|
||||
bvh_build.h
|
||||
bvh_embree.h
|
||||
bvh_multi.h
|
||||
bvh_node.h
|
||||
bvh_optix.h
|
||||
bvh_params.h
|
||||
bvh_sort.h
|
||||
bvh_split.h
|
||||
bvh_unaligned.h
|
||||
)
|
||||
|
||||
set(LIB
|
||||
cycles_scene
|
||||
cycles_render
|
||||
cycles_util
|
||||
)
|
||||
|
||||
|
@@ -18,12 +18,12 @@
|
||||
#include "bvh/bvh.h"
|
||||
|
||||
#include "bvh/bvh2.h"
|
||||
#include "bvh/embree.h"
|
||||
#include "bvh/multi.h"
|
||||
#include "bvh/optix.h"
|
||||
#include "bvh/bvh_embree.h"
|
||||
#include "bvh/bvh_multi.h"
|
||||
#include "bvh/bvh_optix.h"
|
||||
|
||||
#include "util/log.h"
|
||||
#include "util/progress.h"
|
||||
#include "util/util_logging.h"
|
||||
#include "util/util_progress.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
|
@@ -18,10 +18,10 @@
|
||||
#ifndef __BVH_H__
|
||||
#define __BVH_H__
|
||||
|
||||
#include "bvh/params.h"
|
||||
#include "util/array.h"
|
||||
#include "util/types.h"
|
||||
#include "util/vector.h"
|
||||
#include "bvh/bvh_params.h"
|
||||
#include "util/util_array.h"
|
||||
#include "util/util_types.h"
|
||||
#include "util/util_vector.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
@@ -50,9 +50,13 @@ struct PackedBVH {
|
||||
array<int4> leaf_nodes;
|
||||
/* object index to BVH node index mapping for instances */
|
||||
array<int> object_node;
|
||||
/* Mapping from primitive index to index in triangle array. */
|
||||
array<uint> prim_tri_index;
|
||||
/* Continuous storage of triangle vertices. */
|
||||
array<float4> prim_tri_verts;
|
||||
/* primitive type - triangle or strand */
|
||||
array<int> prim_type;
|
||||
/* Visibility visibilities for primitives. */
|
||||
/* visibility visibilitys for primitives */
|
||||
array<uint> prim_visibility;
|
||||
/* mapping from BVH primitive index to true primitive index, as primitives
|
||||
* may be duplicated due to spatial splits. -1 for instances. */
|
||||
|
@@ -17,16 +17,16 @@
|
||||
|
||||
#include "bvh/bvh2.h"
|
||||
|
||||
#include "scene/hair.h"
|
||||
#include "scene/mesh.h"
|
||||
#include "scene/object.h"
|
||||
#include "render/hair.h"
|
||||
#include "render/mesh.h"
|
||||
#include "render/object.h"
|
||||
|
||||
#include "bvh/build.h"
|
||||
#include "bvh/node.h"
|
||||
#include "bvh/unaligned.h"
|
||||
#include "bvh/bvh_build.h"
|
||||
#include "bvh/bvh_node.h"
|
||||
#include "bvh/bvh_unaligned.h"
|
||||
|
||||
#include "util/foreach.h"
|
||||
#include "util/progress.h"
|
||||
#include "util/util_foreach.h"
|
||||
#include "util/util_progress.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
@@ -439,20 +439,61 @@ void BVH2::refit_primitives(int start, int end, BoundBox &bbox, uint &visibility
|
||||
|
||||
/* Triangles */
|
||||
|
||||
void BVH2::pack_triangle(int idx, float4 tri_verts[3])
|
||||
{
|
||||
int tob = pack.prim_object[idx];
|
||||
assert(tob >= 0 && tob < objects.size());
|
||||
const Mesh *mesh = static_cast<const Mesh *>(objects[tob]->get_geometry());
|
||||
|
||||
int tidx = pack.prim_index[idx];
|
||||
Mesh::Triangle t = mesh->get_triangle(tidx);
|
||||
const float3 *vpos = &mesh->verts[0];
|
||||
float3 v0 = vpos[t.v[0]];
|
||||
float3 v1 = vpos[t.v[1]];
|
||||
float3 v2 = vpos[t.v[2]];
|
||||
|
||||
tri_verts[0] = float3_to_float4(v0);
|
||||
tri_verts[1] = float3_to_float4(v1);
|
||||
tri_verts[2] = float3_to_float4(v2);
|
||||
}
|
||||
|
||||
void BVH2::pack_primitives()
|
||||
{
|
||||
const size_t tidx_size = pack.prim_index.size();
|
||||
size_t num_prim_triangles = 0;
|
||||
/* Count number of triangles primitives in BVH. */
|
||||
for (unsigned int i = 0; i < tidx_size; i++) {
|
||||
if ((pack.prim_index[i] != -1)) {
|
||||
if ((pack.prim_type[i] & PRIMITIVE_ALL_TRIANGLE) != 0) {
|
||||
++num_prim_triangles;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Reserve size for arrays. */
|
||||
pack.prim_tri_index.clear();
|
||||
pack.prim_tri_index.resize(tidx_size);
|
||||
pack.prim_tri_verts.clear();
|
||||
pack.prim_tri_verts.resize(num_prim_triangles * 3);
|
||||
pack.prim_visibility.clear();
|
||||
pack.prim_visibility.resize(tidx_size);
|
||||
/* Fill in all the arrays. */
|
||||
size_t prim_triangle_index = 0;
|
||||
for (unsigned int i = 0; i < tidx_size; i++) {
|
||||
if (pack.prim_index[i] != -1) {
|
||||
int tob = pack.prim_object[i];
|
||||
Object *ob = objects[tob];
|
||||
if ((pack.prim_type[i] & PRIMITIVE_ALL_TRIANGLE) != 0) {
|
||||
pack_triangle(i, (float4 *)&pack.prim_tri_verts[3 * prim_triangle_index]);
|
||||
pack.prim_tri_index[i] = 3 * prim_triangle_index;
|
||||
++prim_triangle_index;
|
||||
}
|
||||
else {
|
||||
pack.prim_tri_index[i] = -1;
|
||||
}
|
||||
pack.prim_visibility[i] = ob->visibility_for_tracing();
|
||||
}
|
||||
else {
|
||||
pack.prim_tri_index[i] = -1;
|
||||
pack.prim_visibility[i] = 0;
|
||||
}
|
||||
}
|
||||
@@ -481,8 +522,10 @@ void BVH2::pack_instances(size_t nodes_size, size_t leaf_nodes_size)
|
||||
|
||||
/* reserve */
|
||||
size_t prim_index_size = pack.prim_index.size();
|
||||
size_t prim_tri_verts_size = pack.prim_tri_verts.size();
|
||||
|
||||
size_t pack_prim_index_offset = prim_index_size;
|
||||
size_t pack_prim_tri_verts_offset = prim_tri_verts_size;
|
||||
size_t pack_nodes_offset = nodes_size;
|
||||
size_t pack_leaf_nodes_offset = leaf_nodes_size;
|
||||
size_t object_offset = 0;
|
||||
@@ -492,6 +535,7 @@ void BVH2::pack_instances(size_t nodes_size, size_t leaf_nodes_size)
|
||||
|
||||
if (geom->need_build_bvh(params.bvh_layout)) {
|
||||
prim_index_size += bvh->pack.prim_index.size();
|
||||
prim_tri_verts_size += bvh->pack.prim_tri_verts.size();
|
||||
nodes_size += bvh->pack.nodes.size();
|
||||
leaf_nodes_size += bvh->pack.leaf_nodes.size();
|
||||
}
|
||||
@@ -501,6 +545,8 @@ void BVH2::pack_instances(size_t nodes_size, size_t leaf_nodes_size)
|
||||
pack.prim_type.resize(prim_index_size);
|
||||
pack.prim_object.resize(prim_index_size);
|
||||
pack.prim_visibility.resize(prim_index_size);
|
||||
pack.prim_tri_verts.resize(prim_tri_verts_size);
|
||||
pack.prim_tri_index.resize(prim_index_size);
|
||||
pack.nodes.resize(nodes_size);
|
||||
pack.leaf_nodes.resize(leaf_nodes_size);
|
||||
pack.object_node.resize(objects.size());
|
||||
@@ -513,6 +559,8 @@ void BVH2::pack_instances(size_t nodes_size, size_t leaf_nodes_size)
|
||||
int *pack_prim_type = (pack.prim_type.size()) ? &pack.prim_type[0] : NULL;
|
||||
int *pack_prim_object = (pack.prim_object.size()) ? &pack.prim_object[0] : NULL;
|
||||
uint *pack_prim_visibility = (pack.prim_visibility.size()) ? &pack.prim_visibility[0] : NULL;
|
||||
float4 *pack_prim_tri_verts = (pack.prim_tri_verts.size()) ? &pack.prim_tri_verts[0] : NULL;
|
||||
uint *pack_prim_tri_index = (pack.prim_tri_index.size()) ? &pack.prim_tri_index[0] : NULL;
|
||||
int4 *pack_nodes = (pack.nodes.size()) ? &pack.nodes[0] : NULL;
|
||||
int4 *pack_leaf_nodes = (pack.leaf_nodes.size()) ? &pack.leaf_nodes[0] : NULL;
|
||||
float2 *pack_prim_time = (pack.prim_time.size()) ? &pack.prim_time[0] : NULL;
|
||||
@@ -561,14 +609,18 @@ void BVH2::pack_instances(size_t nodes_size, size_t leaf_nodes_size)
|
||||
int *bvh_prim_index = &bvh->pack.prim_index[0];
|
||||
int *bvh_prim_type = &bvh->pack.prim_type[0];
|
||||
uint *bvh_prim_visibility = &bvh->pack.prim_visibility[0];
|
||||
uint *bvh_prim_tri_index = &bvh->pack.prim_tri_index[0];
|
||||
float2 *bvh_prim_time = bvh->pack.prim_time.size() ? &bvh->pack.prim_time[0] : NULL;
|
||||
|
||||
for (size_t i = 0; i < bvh_prim_index_size; i++) {
|
||||
if (bvh->pack.prim_type[i] & PRIMITIVE_ALL_CURVE) {
|
||||
pack_prim_index[pack_prim_index_offset] = bvh_prim_index[i] + geom_prim_offset;
|
||||
pack_prim_tri_index[pack_prim_index_offset] = -1;
|
||||
}
|
||||
else {
|
||||
pack_prim_index[pack_prim_index_offset] = bvh_prim_index[i] + geom_prim_offset;
|
||||
pack_prim_tri_index[pack_prim_index_offset] = bvh_prim_tri_index[i] +
|
||||
pack_prim_tri_verts_offset;
|
||||
}
|
||||
|
||||
pack_prim_type[pack_prim_index_offset] = bvh_prim_type[i];
|
||||
@@ -581,6 +633,15 @@ void BVH2::pack_instances(size_t nodes_size, size_t leaf_nodes_size)
|
||||
}
|
||||
}
|
||||
|
||||
/* Merge triangle vertices data. */
|
||||
if (bvh->pack.prim_tri_verts.size()) {
|
||||
const size_t prim_tri_size = bvh->pack.prim_tri_verts.size();
|
||||
memcpy(pack_prim_tri_verts + pack_prim_tri_verts_offset,
|
||||
&bvh->pack.prim_tri_verts[0],
|
||||
prim_tri_size * sizeof(float4));
|
||||
pack_prim_tri_verts_offset += prim_tri_size;
|
||||
}
|
||||
|
||||
/* merge nodes */
|
||||
if (bvh->pack.leaf_nodes.size()) {
|
||||
int4 *leaf_nodes_offset = &bvh->pack.leaf_nodes[0];
|
||||
|
@@ -19,10 +19,10 @@
|
||||
#define __BVH2_H__
|
||||
|
||||
#include "bvh/bvh.h"
|
||||
#include "bvh/params.h"
|
||||
#include "bvh/bvh_params.h"
|
||||
|
||||
#include "util/types.h"
|
||||
#include "util/vector.h"
|
||||
#include "util/util_types.h"
|
||||
#include "util/util_vector.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
|
@@ -17,13 +17,13 @@
|
||||
|
||||
//#define __KERNEL_SSE__
|
||||
|
||||
#include "bvh/binning.h"
|
||||
#include "bvh/bvh_binning.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "util/algorithm.h"
|
||||
#include "util/boundbox.h"
|
||||
#include "util/types.h"
|
||||
#include "util/util_algorithm.h"
|
||||
#include "util/util_boundbox.h"
|
||||
#include "util/util_types.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
@@ -18,10 +18,10 @@
|
||||
#ifndef __BVH_BINNING_H__
|
||||
#define __BVH_BINNING_H__
|
||||
|
||||
#include "bvh/params.h"
|
||||
#include "bvh/unaligned.h"
|
||||
#include "bvh/bvh_params.h"
|
||||
#include "bvh/bvh_unaligned.h"
|
||||
|
||||
#include "util/types.h"
|
||||
#include "util/util_types.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
@@ -15,27 +15,27 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "bvh/build.h"
|
||||
#include "bvh/bvh_build.h"
|
||||
|
||||
#include "bvh/binning.h"
|
||||
#include "bvh/node.h"
|
||||
#include "bvh/params.h"
|
||||
#include "bvh/split.h"
|
||||
#include "bvh/bvh_binning.h"
|
||||
#include "bvh/bvh_node.h"
|
||||
#include "bvh/bvh_params.h"
|
||||
#include "bvh_split.h"
|
||||
|
||||
#include "scene/curves.h"
|
||||
#include "scene/hair.h"
|
||||
#include "scene/mesh.h"
|
||||
#include "scene/object.h"
|
||||
#include "scene/scene.h"
|
||||
#include "render/curves.h"
|
||||
#include "render/hair.h"
|
||||
#include "render/mesh.h"
|
||||
#include "render/object.h"
|
||||
#include "render/scene.h"
|
||||
|
||||
#include "util/algorithm.h"
|
||||
#include "util/foreach.h"
|
||||
#include "util/log.h"
|
||||
#include "util/progress.h"
|
||||
#include "util/queue.h"
|
||||
#include "util/simd.h"
|
||||
#include "util/stack_allocator.h"
|
||||
#include "util/time.h"
|
||||
#include "util/util_algorithm.h"
|
||||
#include "util/util_foreach.h"
|
||||
#include "util/util_logging.h"
|
||||
#include "util/util_progress.h"
|
||||
#include "util/util_queue.h"
|
||||
#include "util/util_simd.h"
|
||||
#include "util/util_stack_allocator.h"
|
||||
#include "util/util_time.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
@@ -67,12 +67,8 @@ BVHBuild::~BVHBuild()
|
||||
|
||||
/* Adding References */
|
||||
|
||||
void BVHBuild::add_reference_triangles(BoundBox &root,
|
||||
BoundBox ¢er,
|
||||
Mesh *mesh,
|
||||
int object_index)
|
||||
void BVHBuild::add_reference_triangles(BoundBox &root, BoundBox ¢er, Mesh *mesh, int i)
|
||||
{
|
||||
const PrimitiveType primitive_type = mesh->primitive_type();
|
||||
const Attribute *attr_mP = NULL;
|
||||
if (mesh->has_motion_blur()) {
|
||||
attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
|
||||
@@ -85,7 +81,7 @@ void BVHBuild::add_reference_triangles(BoundBox &root,
|
||||
BoundBox bounds = BoundBox::empty;
|
||||
t.bounds_grow(verts, bounds);
|
||||
if (bounds.valid() && t.valid(verts)) {
|
||||
references.push_back(BVHReference(bounds, j, object_index, primitive_type));
|
||||
references.push_back(BVHReference(bounds, j, i, PRIMITIVE_TRIANGLE));
|
||||
root.grow(bounds);
|
||||
center.grow(bounds.center2());
|
||||
}
|
||||
@@ -105,7 +101,7 @@ void BVHBuild::add_reference_triangles(BoundBox &root,
|
||||
t.bounds_grow(vert_steps + step * num_verts, bounds);
|
||||
}
|
||||
if (bounds.valid()) {
|
||||
references.push_back(BVHReference(bounds, j, object_index, primitive_type));
|
||||
references.push_back(BVHReference(bounds, j, i, PRIMITIVE_MOTION_TRIANGLE));
|
||||
root.grow(bounds);
|
||||
center.grow(bounds.center2());
|
||||
}
|
||||
@@ -144,7 +140,7 @@ void BVHBuild::add_reference_triangles(BoundBox &root,
|
||||
if (bounds.valid()) {
|
||||
const float prev_time = (float)(bvh_step - 1) * num_bvh_steps_inv_1;
|
||||
references.push_back(
|
||||
BVHReference(bounds, j, object_index, primitive_type, prev_time, curr_time));
|
||||
BVHReference(bounds, j, i, PRIMITIVE_MOTION_TRIANGLE, prev_time, curr_time));
|
||||
root.grow(bounds);
|
||||
center.grow(bounds.center2());
|
||||
}
|
||||
@@ -157,14 +153,18 @@ void BVHBuild::add_reference_triangles(BoundBox &root,
|
||||
}
|
||||
}
|
||||
|
||||
void BVHBuild::add_reference_curves(BoundBox &root, BoundBox ¢er, Hair *hair, int object_index)
|
||||
void BVHBuild::add_reference_curves(BoundBox &root, BoundBox ¢er, Hair *hair, int i)
|
||||
{
|
||||
const Attribute *curve_attr_mP = NULL;
|
||||
if (hair->has_motion_blur()) {
|
||||
curve_attr_mP = hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
|
||||
}
|
||||
|
||||
const PrimitiveType primitive_type = hair->primitive_type();
|
||||
const PrimitiveType primitive_type =
|
||||
(curve_attr_mP != NULL) ?
|
||||
((hair->curve_shape == CURVE_RIBBON) ? PRIMITIVE_MOTION_CURVE_RIBBON :
|
||||
PRIMITIVE_MOTION_CURVE_THICK) :
|
||||
((hair->curve_shape == CURVE_RIBBON) ? PRIMITIVE_CURVE_RIBBON : PRIMITIVE_CURVE_THICK);
|
||||
|
||||
const size_t num_curves = hair->num_curves();
|
||||
for (uint j = 0; j < num_curves; j++) {
|
||||
@@ -177,7 +177,7 @@ void BVHBuild::add_reference_curves(BoundBox &root, BoundBox ¢er, Hair *hair
|
||||
curve.bounds_grow(k, &hair->get_curve_keys()[0], curve_radius, bounds);
|
||||
if (bounds.valid()) {
|
||||
int packed_type = PRIMITIVE_PACK_SEGMENT(primitive_type, k);
|
||||
references.push_back(BVHReference(bounds, j, object_index, packed_type));
|
||||
references.push_back(BVHReference(bounds, j, i, packed_type));
|
||||
root.grow(bounds);
|
||||
center.grow(bounds.center2());
|
||||
}
|
||||
@@ -198,7 +198,7 @@ void BVHBuild::add_reference_curves(BoundBox &root, BoundBox ¢er, Hair *hair
|
||||
}
|
||||
if (bounds.valid()) {
|
||||
int packed_type = PRIMITIVE_PACK_SEGMENT(primitive_type, k);
|
||||
references.push_back(BVHReference(bounds, j, object_index, packed_type));
|
||||
references.push_back(BVHReference(bounds, j, i, packed_type));
|
||||
root.grow(bounds);
|
||||
center.grow(bounds.center2());
|
||||
}
|
||||
@@ -254,8 +254,7 @@ void BVHBuild::add_reference_curves(BoundBox &root, BoundBox ¢er, Hair *hair
|
||||
if (bounds.valid()) {
|
||||
const float prev_time = (float)(bvh_step - 1) * num_bvh_steps_inv_1;
|
||||
int packed_type = PRIMITIVE_PACK_SEGMENT(primitive_type, k);
|
||||
references.push_back(
|
||||
BVHReference(bounds, j, object_index, packed_type, prev_time, curr_time));
|
||||
references.push_back(BVHReference(bounds, j, i, packed_type, prev_time, curr_time));
|
||||
root.grow(bounds);
|
||||
center.grow(bounds.center2());
|
||||
}
|
||||
@@ -269,18 +268,15 @@ void BVHBuild::add_reference_curves(BoundBox &root, BoundBox ¢er, Hair *hair
|
||||
}
|
||||
}
|
||||
|
||||
void BVHBuild::add_reference_geometry(BoundBox &root,
|
||||
BoundBox ¢er,
|
||||
Geometry *geom,
|
||||
int object_index)
|
||||
void BVHBuild::add_reference_geometry(BoundBox &root, BoundBox ¢er, Geometry *geom, int i)
|
||||
{
|
||||
if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) {
|
||||
Mesh *mesh = static_cast<Mesh *>(geom);
|
||||
add_reference_triangles(root, center, mesh, object_index);
|
||||
add_reference_triangles(root, center, mesh, i);
|
||||
}
|
||||
else if (geom->geometry_type == Geometry::HAIR) {
|
||||
Hair *hair = static_cast<Hair *>(geom);
|
||||
add_reference_curves(root, center, hair, object_index);
|
||||
add_reference_curves(root, center, hair, i);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -836,18 +832,18 @@ BVHNode *BVHBuild::create_leaf_node(const BVHRange &range, const vector<BVHRefer
|
||||
typedef StackAllocator<256, float2> LeafTimeStackAllocator;
|
||||
typedef StackAllocator<256, BVHReference> LeafReferenceStackAllocator;
|
||||
|
||||
vector<int, LeafStackAllocator> p_type[PRIMITIVE_NUM];
|
||||
vector<int, LeafStackAllocator> p_index[PRIMITIVE_NUM];
|
||||
vector<int, LeafStackAllocator> p_object[PRIMITIVE_NUM];
|
||||
vector<float2, LeafTimeStackAllocator> p_time[PRIMITIVE_NUM];
|
||||
vector<BVHReference, LeafReferenceStackAllocator> p_ref[PRIMITIVE_NUM];
|
||||
vector<int, LeafStackAllocator> p_type[PRIMITIVE_NUM_TOTAL];
|
||||
vector<int, LeafStackAllocator> p_index[PRIMITIVE_NUM_TOTAL];
|
||||
vector<int, LeafStackAllocator> p_object[PRIMITIVE_NUM_TOTAL];
|
||||
vector<float2, LeafTimeStackAllocator> p_time[PRIMITIVE_NUM_TOTAL];
|
||||
vector<BVHReference, LeafReferenceStackAllocator> p_ref[PRIMITIVE_NUM_TOTAL];
|
||||
|
||||
/* TODO(sergey): In theory we should be able to store references. */
|
||||
vector<BVHReference, LeafReferenceStackAllocator> object_references;
|
||||
|
||||
uint visibility[PRIMITIVE_NUM] = {0};
|
||||
uint visibility[PRIMITIVE_NUM_TOTAL] = {0};
|
||||
/* NOTE: Keep initialization in sync with actual number of primitives. */
|
||||
BoundBox bounds[PRIMITIVE_NUM] = {
|
||||
BoundBox bounds[PRIMITIVE_NUM_TOTAL] = {
|
||||
BoundBox::empty, BoundBox::empty, BoundBox::empty, BoundBox::empty};
|
||||
int ob_num = 0;
|
||||
int num_new_prims = 0;
|
||||
@@ -881,7 +877,7 @@ BVHNode *BVHBuild::create_leaf_node(const BVHRange &range, const vector<BVHRefer
|
||||
* TODO(sergey): With some pointer trickery we can write directly to the
|
||||
* destination buffers for the non-spatial split BVH.
|
||||
*/
|
||||
BVHNode *leaves[PRIMITIVE_NUM + 1] = {NULL};
|
||||
BVHNode *leaves[PRIMITIVE_NUM_TOTAL + 1] = {NULL};
|
||||
int num_leaves = 0;
|
||||
size_t start_index = 0;
|
||||
vector<int, LeafStackAllocator> local_prim_type, local_prim_index, local_prim_object;
|
||||
@@ -892,7 +888,7 @@ BVHNode *BVHBuild::create_leaf_node(const BVHRange &range, const vector<BVHRefer
|
||||
if (need_prim_time) {
|
||||
local_prim_time.resize(num_new_prims);
|
||||
}
|
||||
for (int i = 0; i < PRIMITIVE_NUM; ++i) {
|
||||
for (int i = 0; i < PRIMITIVE_NUM_TOTAL; ++i) {
|
||||
int num = (int)p_type[i].size();
|
||||
if (num != 0) {
|
||||
assert(p_type[i].size() == p_index[i].size());
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user