Compare commits
1 Commits
temp-keyma
...
template-o
Author | SHA1 | Date | |
---|---|---|---|
753dd8f09a |
@@ -1446,7 +1446,6 @@ elseif(CMAKE_C_COMPILER_ID MATCHES "MSVC")
|
||||
# warning level:
|
||||
"/W3"
|
||||
"/w34062" # switch statement contains 'default' but no 'case' labels
|
||||
"/w34115" # 'type' : named type definition in parentheses
|
||||
"/w34189" # local variable is initialized but not referenced
|
||||
# disable:
|
||||
"/wd4018" # signed/unsigned mismatch
|
||||
|
@@ -25,16 +25,16 @@
|
||||
# Windows and macOS, and install_deps.sh on Linux.
|
||||
#
|
||||
# WINDOWS USAGE:
|
||||
# Don't call this cmake file yourself, use build_deps.cmd
|
||||
# Don't call this cmake file your self, use build_deps.cmd
|
||||
# build_deps 2013 x64 / build_deps 2013 x86
|
||||
# build_deps 2015 x64 / build_deps 2015 x86
|
||||
#
|
||||
# MAC OS X USAGE:
|
||||
# Install with homebrew: brew install cmake autoconf automake libtool yasm nasm
|
||||
# Install with homebrew: brew install autoconf automake libtool yasm nasm
|
||||
# Run "make deps" from main Blender directory
|
||||
#
|
||||
# LINUX USAGE:
|
||||
# Install compiler cmake autoconf automake libtool yasm nasm tcl
|
||||
# Install compiler, cmake, autoconf, automake, libtool, yasm
|
||||
# Run "make deps" from main Blender directory
|
||||
#
|
||||
####################################################################################################
|
||||
|
@@ -129,8 +129,6 @@ harvest(jpg/include jpeg/include "*.h")
|
||||
harvest(jpg/lib jpeg/lib "libjpeg.a")
|
||||
harvest(lame/lib ffmpeg/lib "*.a")
|
||||
harvest(clang/bin llvm/bin "clang-format")
|
||||
harvest(clang/include llvm/include "*")
|
||||
harvest(llvm/include llvm/include "*")
|
||||
harvest(llvm/bin llvm/bin "llvm-config")
|
||||
harvest(llvm/lib llvm/lib "libLLVM*.a")
|
||||
if(APPLE)
|
||||
|
@@ -47,8 +47,7 @@ if(MSVC)
|
||||
set(LLVM_HARVEST_COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/llvm/ ${HARVEST_TARGET}/llvm/ )
|
||||
else()
|
||||
set(LLVM_HARVEST_COMMAND
|
||||
${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/llvm/lib/ ${HARVEST_TARGET}/llvm/debug/lib/ &&
|
||||
${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/llvm/include/ ${HARVEST_TARGET}/llvm/debug/include/
|
||||
${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/llvm/lib/ ${HARVEST_TARGET}/llvm/debug/lib/
|
||||
)
|
||||
endif()
|
||||
ExternalProject_Add_Step(ll after_install
|
||||
|
@@ -18,31 +18,18 @@
|
||||
|
||||
if(BUILD_MODE STREQUAL Release)
|
||||
set(OPENAL_EXTRA_ARGS
|
||||
-DALSOFT_UTILS=OFF
|
||||
-DALSOFT_NO_CONFIG_UTIL=ON
|
||||
-DALSOFT_EXAMPLES=OFF
|
||||
-DALSOFT_TESTS=OFF
|
||||
-DALSOFT_CONFIG=OFF
|
||||
-DALSOFT_HRTF_DEFS=OFF
|
||||
-DALSOFT_INSTALL=ON
|
||||
-DALSOFT_BACKEND_SNDIO=OFF
|
||||
-DALSOFT_UTILS=Off
|
||||
-DALSOFT_NO_CONFIG_UTIL=On
|
||||
-DALSOFT_EXAMPLES=Off
|
||||
-DALSOFT_TESTS=Off
|
||||
-DALSOFT_CONFIG=Off
|
||||
-DALSOFT_HRTF_DEFS=Off
|
||||
-DALSOFT_INSTALL=On
|
||||
-DALSOFT_BACKEND_SNDIO=Off
|
||||
)
|
||||
|
||||
if(UNIX)
|
||||
set(OPENAL_EXTRA_ARGS
|
||||
${OPENAL_EXTRA_ARGS}
|
||||
-DLIBTYPE=STATIC
|
||||
)
|
||||
endif()
|
||||
|
||||
if(UNIX AND NOT APPLE)
|
||||
# Ensure we have backends for playback.
|
||||
set(OPENAL_EXTRA_ARGS
|
||||
${OPENAL_EXTRA_ARGS}
|
||||
-DALSOFT_REQUIRE_ALSA=ON
|
||||
-DALSOFT_REQUIRE_OSS=ON
|
||||
-DALSOFT_REQUIRE_PULSEAUDIO=ON
|
||||
)
|
||||
set(OPENAL_EXTRA_ARGS ${OPENAL_EXTRA_ARGS} -DLIBTYPE=STATIC)
|
||||
endif()
|
||||
|
||||
ExternalProject_Add(external_openal
|
||||
|
@@ -71,7 +71,7 @@ else()
|
||||
endif()
|
||||
|
||||
set(FREETYPE_VERSION 2.9.1)
|
||||
set(FREETYPE_URI http://prdownloads.sourceforge.net/freetype/freetype-${FREETYPE_VERSION}.tar.gz)
|
||||
set(FREETYPE_URI http://download.savannah.gnu.org/releases/freetype/freetype-${FREETYPE_VERSION}.tar.gz)
|
||||
set(FREETYPE_HASH 3adb0e35d3c100c456357345ccfa8056)
|
||||
|
||||
set(GLEW_VERSION 1.13.0)
|
||||
@@ -251,7 +251,7 @@ set(JEMALLOC_URI https://github.com/jemalloc/jemalloc/releases/download/${JEMALL
|
||||
set(JEMALLOC_HASH 507f7b6b882d868730d644510491d18f)
|
||||
|
||||
set(XML2_VERSION 2.9.4)
|
||||
set(XML2_URI http://xmlsoft.org/sources/libxml2-${XML2_VERSION}.tar.gz)
|
||||
set(XML2_URI ftp://xmlsoft.org/libxml2/libxml2-${XML2_VERSION}.tar.gz)
|
||||
set(XML2_HASH ae249165c173b1ff386ee8ad676815f5)
|
||||
|
||||
set(TINYXML_VERSION 2_6_2)
|
||||
@@ -284,7 +284,7 @@ set(BZIP2_URI http://http.debian.net/debian/pool/main/b/bzip2/bzip2_${BZIP2_VERS
|
||||
set(BZIP2_HASH d70a9ccd8bdf47e302d96c69fecd54925f45d9c7b966bb4ef5f56b770960afa7)
|
||||
|
||||
set(FFI_VERSION 3.2.1)
|
||||
set(FFI_URI https://sourceware.org/pub/libffi/libffi-${FFI_VERSION}.tar.gz)
|
||||
set(FFI_URI ftp://sourceware.org/pub/libffi/libffi-${FFI_VERSION}.tar.gz)
|
||||
set(FFI_HASH d06ebb8e1d9a22d19e38d63fdb83954253f39bedc5d46232a05645685722ca37)
|
||||
|
||||
set(LZMA_VERSION 5.2.4)
|
||||
|
@@ -301,8 +301,6 @@ NO_BUILD=false
|
||||
NO_CONFIRM=false
|
||||
USE_CXX11=true
|
||||
|
||||
CLANG_FORMAT_VERSION_MIN="6.0"
|
||||
|
||||
PYTHON_VERSION="3.7.0"
|
||||
PYTHON_VERSION_MIN="3.7"
|
||||
PYTHON_FORCE_BUILD=false
|
||||
@@ -385,6 +383,7 @@ OPENCOLLADA_FORCE_BUILD=false
|
||||
OPENCOLLADA_FORCE_REBUILD=false
|
||||
OPENCOLLADA_SKIP=false
|
||||
|
||||
|
||||
EMBREE_VERSION="3.2.4"
|
||||
EMBREE_FORCE_BUILD=false
|
||||
EMBREE_FORCE_REBUILD=false
|
||||
@@ -2629,7 +2628,7 @@ compile_FFmpeg() {
|
||||
./configure --cc="gcc -Wl,--as-needed" \
|
||||
--extra-ldflags="-pthread -static-libgcc" \
|
||||
--prefix=$_inst --enable-static \
|
||||
--disable-ffplay --disable-doc \
|
||||
--disable-ffplay --disable-ffserver --disable-doc \
|
||||
--enable-gray \
|
||||
--enable-avfilter --disable-vdpau \
|
||||
--disable-bzlib --disable-libgsm --disable-libspeex \
|
||||
@@ -2789,17 +2788,6 @@ install_DEB() {
|
||||
PRINT ""
|
||||
fi
|
||||
|
||||
PRINT ""
|
||||
CLANG_FORMAT="clang-format"
|
||||
check_package_version_ge_DEB $CLANG_FORMAT $CLANG_FORMAT_VERSION_MIN
|
||||
if [ $? -eq 0 ]; then
|
||||
_packages="$_packages $CLANG_FORMAT"
|
||||
else
|
||||
PRINT ""
|
||||
WARNING "clang-format $CLANG_FORMAT_VERSION_MIN or higher not found, this is NOT needed to get Blender compiling..."
|
||||
PRINT ""
|
||||
fi
|
||||
|
||||
if [ "$WITH_JACK" = true ]; then
|
||||
_packages="$_packages libspnav-dev"
|
||||
# Only install jack if jack2 is not already installed!
|
||||
@@ -3451,16 +3439,6 @@ install_RPM() {
|
||||
install_packages_RPM libspnav-devel
|
||||
fi
|
||||
|
||||
PRINT ""
|
||||
CLANG_FORMAT="clang" # Yeah, on fedora/suse clang-format is part of main clang package...
|
||||
check_package_version_ge_RPM $CLANG_FORMAT $CLANG_FORMAT_VERSION_MIN
|
||||
if [ $? -eq 0 ]; then
|
||||
install_packages_RPM $CLANG_FORMAT
|
||||
else
|
||||
PRINT ""
|
||||
WARNING "clang-format $CLANG_FORMAT_VERSION_MIN or higher not found, this is NOT needed to get Blender compiling..."
|
||||
PRINT ""
|
||||
fi
|
||||
|
||||
PRINT ""
|
||||
_do_compile_python=false
|
||||
@@ -3908,18 +3886,6 @@ install_ARCH() {
|
||||
fi
|
||||
|
||||
|
||||
PRINT ""
|
||||
CLANG_FORMAT="clang" # Yeah, on arch clang-format is part of main clang package...
|
||||
check_package_version_ge_ARCH $CLANG_FORMAT $CLANG_FORMAT_VERSION_MIN
|
||||
if [ $? -eq 0 ]; then
|
||||
install_packages_ARCH $CLANG_FORMAT
|
||||
else
|
||||
PRINT ""
|
||||
WARNING "clang-format $CLANG_FORMAT_VERSION_MIN or higher not found, this is NOT needed to get Blender compiling..."
|
||||
PRINT ""
|
||||
fi
|
||||
|
||||
|
||||
PRINT ""
|
||||
_do_compile_python=false
|
||||
if [ "$PYTHON_SKIP" = true ]; then
|
||||
@@ -4558,33 +4524,18 @@ print_info() {
|
||||
PRINT " $_1"
|
||||
_buildargs="$_buildargs $_1"
|
||||
fi
|
||||
if [ -d $INST/blosc ]; then
|
||||
_1="-D BLOSC_ROOT_DIR=$INST/blosc"
|
||||
PRINT " $_1"
|
||||
_buildargs="$_buildargs $_1"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$WITH_OPENCOLLADA" = true ]; then
|
||||
_1="-D WITH_OPENCOLLADA=ON"
|
||||
PRINT " $_1"
|
||||
_buildargs="$_buildargs $_1"
|
||||
if [ -d $INST/opencollada ]; then
|
||||
_1="-D OPENCOLLADA_ROOT_DIR=$INST/opencollada"
|
||||
PRINT " $_1"
|
||||
_buildargs="$_buildargs $_1"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$WITH_EMBREE" = true ]; then
|
||||
_1="-D WITH_CYCLES_EMBREE=ON"
|
||||
PRINT " $_1"
|
||||
_buildargs="$_buildargs $_1"
|
||||
if [ -d $INST/embree ]; then
|
||||
_1="-D EMBREE_ROOT_DIR=$INST/embree"
|
||||
PRINT " $_1"
|
||||
_buildargs="$_buildargs $_1"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$WITH_JACK" = true ]; then
|
||||
|
@@ -54,15 +54,18 @@ if 'cmake' in builder:
|
||||
targets = ['blender']
|
||||
|
||||
chroot_name = None # If not None command will be delegated to that chroot
|
||||
cuda_chroot_name = None # If not None cuda compilationcommand will be delegated to that chroot
|
||||
build_cubins = True # Whether to build Cycles CUDA kernels
|
||||
bits = 64
|
||||
|
||||
# Config file to be used (relative to blender's sources root)
|
||||
cmake_config_file = "build_files/cmake/config/blender_release.cmake"
|
||||
cmake_cuda_config_file = None
|
||||
|
||||
# Set build options.
|
||||
cmake_options = []
|
||||
cmake_extra_options = ['-DCMAKE_BUILD_TYPE:STRING=Release']
|
||||
cuda_cmake_options = []
|
||||
|
||||
if builder.startswith('mac'):
|
||||
# Set up OSX architecture
|
||||
@@ -71,11 +74,26 @@ if 'cmake' in builder:
|
||||
cmake_extra_options.append('-DCMAKE_OSX_DEPLOYMENT_TARGET=10.9')
|
||||
|
||||
elif builder.startswith('win'):
|
||||
if builder.startswith('win64'):
|
||||
cmake_options.extend(['-G', 'Visual Studio 15 2017 Win64'])
|
||||
elif builder.startswith('win32'):
|
||||
bits = 32
|
||||
cmake_options.extend(['-G', 'Visual Studio 15 2017'])
|
||||
if builder.endswith('_vs2017'):
|
||||
if builder.startswith('win64'):
|
||||
cmake_options.extend(['-G', 'Visual Studio 15 2017 Win64'])
|
||||
elif builder.startswith('win32'):
|
||||
bits = 32
|
||||
cmake_options.extend(['-G', 'Visual Studio 15 2017'])
|
||||
elif builder.endswith('_vc2015'):
|
||||
if builder.startswith('win64'):
|
||||
cmake_options.extend(['-G', 'Visual Studio 14 2015 Win64'])
|
||||
elif builder.startswith('win32'):
|
||||
bits = 32
|
||||
cmake_options.extend(['-G', 'Visual Studio 14 2015'])
|
||||
cmake_extra_options.append('-DCUDA_NVCC_FLAGS=--cl-version;2013;' +
|
||||
'--compiler-bindir;C:\\Program Files (x86)\\Microsoft Visual Studio 12.0\\VC\\bin')
|
||||
else:
|
||||
if builder.startswith('win64'):
|
||||
cmake_options.extend(['-G', 'Visual Studio 12 2013 Win64'])
|
||||
elif builder.startswith('win32'):
|
||||
bits = 32
|
||||
cmake_options.extend(['-G', 'Visual Studio 12 2013'])
|
||||
|
||||
elif builder.startswith('linux'):
|
||||
tokens = builder.split("_")
|
||||
@@ -98,14 +116,36 @@ if 'cmake' in builder:
|
||||
cmake_extra_options.extend(["-DCMAKE_C_COMPILER=/usr/bin/gcc-7",
|
||||
"-DCMAKE_CXX_COMPILER=/usr/bin/g++-7"])
|
||||
|
||||
# Workaround to build only sm_7x kernels with CUDA 10, until
|
||||
# older kernels work well with this version.
|
||||
if builder.startswith('win'):
|
||||
cmake_extra_options.append('-DCUDA_VERSION=9.1')
|
||||
cmake_extra_options.append('-DCUDA_TOOLKIT_INCLUDE:PATH=C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v9.1/include')
|
||||
cmake_extra_options.append('-DCUDA_TOOLKIT_ROOT_DIR:PATH=C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v9.1')
|
||||
cmake_extra_options.append('-DCUDA_NVCC_EXECUTABLE:FILEPATH=C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v9.1/bin/nvcc.exe')
|
||||
cmake_extra_options.append('-DCUDA10_NVCC_EXECUTABLE:FILEPATH=C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v10.0/bin/nvcc.exe')
|
||||
cmake_extra_options.append('-DCUDA10_TOOLKIT_ROOT_DIR:PATH=C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v10.0')
|
||||
elif builder.startswith('linux'):
|
||||
cmake_extra_options.append('-DCUDA_VERSION=9.1')
|
||||
cmake_extra_options.append('-DCUDA_TOOLKIT_INCLDUE:PATH=/usr/local/cuda-9.1/include')
|
||||
cmake_extra_options.append('-DCUDA_TOOLKIT_ROOT_DIR:PATH=/usr/local/cuda-9.1')
|
||||
cmake_extra_options.append('-DCUDA_NVCC_EXECUTABLE:FILEPATH=/usr/local/cuda-9.1/bin/nvcc')
|
||||
cmake_extra_options.append('-DCUDA10_NVCC_EXECUTABLE:FILEPATH=/usr/local/cuda-10.0/bin/nvcc')
|
||||
cmake_extra_options.append('-DCUDA10_TOOLKIT_ROOT_DIR:PATH=/usr/local/cuda-10.0')
|
||||
|
||||
cmake_options.append("-C" + os.path.join(blender_dir, cmake_config_file))
|
||||
|
||||
# Prepare CMake options needed to configure cuda binaries compilation, 64bit only.
|
||||
if bits == 64 and build_cubins:
|
||||
cmake_options.append("-DWITH_CYCLES_CUDA_BINARIES=ON")
|
||||
cmake_options.append("-DCUDA_64_BIT_DEVICE_CODE=ON")
|
||||
if bits == 64:
|
||||
cuda_cmake_options.append("-DWITH_CYCLES_CUDA_BINARIES=%s" % ('ON' if build_cubins else 'OFF'))
|
||||
if build_cubins or 'cuda' in targets:
|
||||
cuda_cmake_options.append("-DCUDA_64_BIT_DEVICE_CODE=ON")
|
||||
|
||||
# Only modify common cmake options if cuda doesn't require separate target.
|
||||
if 'cuda' not in targets:
|
||||
cmake_options += cuda_cmake_options
|
||||
else:
|
||||
cmake_options.append("-DWITH_CYCLES_CUDA_BINARIES=OFF")
|
||||
cuda_cmake_options.append("-DWITH_CYCLES_CUDA_BINARIES=OFF")
|
||||
|
||||
cmake_options.append("-DCMAKE_INSTALL_PREFIX=%s" % (install_dir))
|
||||
|
||||
@@ -116,6 +156,10 @@ if 'cmake' in builder:
|
||||
chroot_prefix = ['schroot', '-c', chroot_name, '--']
|
||||
else:
|
||||
chroot_prefix = []
|
||||
if cuda_chroot_name:
|
||||
cuda_chroot_prefix = ['schroot', '-c', cuda_chroot_name, '--']
|
||||
else:
|
||||
cuda_chroot_prefix = chroot_prefix[:]
|
||||
|
||||
# Make sure no garbage remained from the previous run
|
||||
if os.path.isdir(install_dir):
|
||||
@@ -131,6 +175,14 @@ if 'cmake' in builder:
|
||||
target_name = 'install'
|
||||
# Tweaking CMake options to respect the target
|
||||
target_cmake_options = cmake_options[:]
|
||||
if target == 'cuda':
|
||||
target_cmake_options += cuda_cmake_options
|
||||
target_chroot_prefix = cuda_chroot_prefix[:]
|
||||
target_name = 'cycles_kernel_cuda'
|
||||
# If cuda binaries are compiled as a separate target, make sure
|
||||
# other targets don't compile cuda binaries.
|
||||
if 'cuda' in targets and target != 'cuda':
|
||||
target_cmake_options.append("-DWITH_CYCLES_CUDA_BINARIES=OFF")
|
||||
# Do extra git fetch because not all platform/git/buildbot combinations
|
||||
# update the origin remote, causing buildinfo to detect local changes.
|
||||
os.chdir(blender_dir)
|
||||
@@ -167,6 +219,16 @@ if 'cmake' in builder:
|
||||
if retcode != 0:
|
||||
sys.exit(retcode)
|
||||
|
||||
if builder.startswith('linux') and target == 'cuda':
|
||||
blender_h = os.path.join(blender_dir, "source", "blender", "blenkernel", "BKE_blender_version.h")
|
||||
blender_version = int(parse_header_file(blender_h, 'BLENDER_VERSION'))
|
||||
blender_version = "%d.%d" % (blender_version // 100, blender_version % 100)
|
||||
kernels = os.path.join(target_build_dir, 'intern', 'cycles', 'kernel')
|
||||
install_kernels = os.path.join(install_dir, blender_version, 'scripts', 'addons', 'cycles', 'lib')
|
||||
os.mkdir(install_kernels)
|
||||
print("Copying cuda binaries from %s to %s" % (kernels, install_kernels))
|
||||
os.system('cp %s/*.cubin %s' % (kernels, install_kernels))
|
||||
|
||||
else:
|
||||
print("Unknown building system")
|
||||
sys.exit(1)
|
||||
|
@@ -50,9 +50,8 @@ set(WITH_SDL ON CACHE BOOL "" FORCE)
|
||||
set(WITH_X11_XINPUT ON CACHE BOOL "" FORCE)
|
||||
set(WITH_X11_XF86VMODE ON CACHE BOOL "" FORCE)
|
||||
|
||||
set(WITH_MEM_JEMALLOC ON CACHE BOOL "" FORCE)
|
||||
set(WITH_CYCLES_CUDA_BINARIES ON CACHE BOOL "" FORCE)
|
||||
set(WITH_CYCLES_CUBIN_COMPILER OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_MEM_JEMALLOC ON CACHE BOOL "" FORCE)
|
||||
set(WITH_CYCLES_CUDA_BINARIES ON CACHE BOOL "" FORCE)
|
||||
set(CYCLES_CUDA_BINARIES_ARCH sm_30;sm_35;sm_37;sm_50;sm_52;sm_60;sm_61;sm_70;sm_75 CACHE STRING "" FORCE)
|
||||
|
||||
# platform dependent options
|
||||
|
@@ -30,8 +30,3 @@ set(WITH_INTERNATIONAL OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_BULLET OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_OPENVDB OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_ALEMBIC OFF CACHE BOOL "" FORCE)
|
||||
|
||||
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
# jemalloc causes linking error on import, disable.
|
||||
set(WITH_MEM_JEMALLOC OFF CACHE BOOL "" FORCE)
|
||||
endif()
|
||||
|
@@ -86,7 +86,7 @@ if(WIN32)
|
||||
set(CPACK_NSIS_MUI_ICON ${CMAKE_SOURCE_DIR}/release/windows/icons/winblender.ico)
|
||||
set(CPACK_NSIS_COMPRESSOR "/SOLID lzma")
|
||||
|
||||
set(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_SOURCE_DIR}/release/text/GPL3-license.txt)
|
||||
set(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_SOURCE_DIR}/release/text/GPL-license.txt)
|
||||
set(CPACK_WIX_PRODUCT_ICON ${CMAKE_SOURCE_DIR}/release/windows/icons/winblender.ico)
|
||||
set(CPACK_WIX_UPGRADE_GUID "B767E4FD-7DE7-4094-B051-3AE62E13A17A")
|
||||
|
||||
|
@@ -427,7 +427,6 @@ endif()
|
||||
|
||||
if(WITH_LLVM)
|
||||
set(LLVM_ROOT_DIR ${LIBDIR}/llvm CACHE PATH "Path to the LLVM installation")
|
||||
set(LLVM_INCLUDE_DIRS ${LLVM_ROOT_DIR}/$<$<CONFIG:Debug>:Debug>/include CACHE PATH "Path to the LLVM include directory")
|
||||
file(GLOB LLVM_LIBRARY_OPTIMIZED ${LLVM_ROOT_DIR}/lib/*.lib)
|
||||
|
||||
if(EXISTS ${LLVM_ROOT_DIR}/debug/lib)
|
||||
|
@@ -57,6 +57,7 @@
|
||||
|
||||
import struct
|
||||
import sys
|
||||
import getopt # command line arguments handling
|
||||
from string import Template # strings completion
|
||||
|
||||
|
||||
|
@@ -71,7 +71,7 @@
|
||||
* \ingroup audaspace
|
||||
*/
|
||||
/** \defgroup audsrc Audaspace SRC
|
||||
*
|
||||
|
||||
* \ingroup audaspace
|
||||
*/
|
||||
/** \defgroup audffmpeg Audaspace FFMpeg
|
||||
@@ -91,3 +91,4 @@
|
||||
* \ingroup intern GUI
|
||||
* \ref GHOSTPage
|
||||
*/
|
||||
|
||||
|
@@ -6,6 +6,7 @@ Example of using the blf module. For this module to work we
|
||||
need to use the OpenGL wrapper :class:`~bgl` as well.
|
||||
"""
|
||||
# import stand alone modules
|
||||
import bgl
|
||||
import blf
|
||||
import bpy
|
||||
|
||||
|
@@ -15,15 +15,13 @@ class OBJECT_OT_property_example(bpy.types.Operator):
|
||||
bl_label = "Property Example"
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
my_float: bpy.props.FloatProperty(name="Some Floating Point")
|
||||
my_bool: bpy.props.BoolProperty(name="Toggle Option")
|
||||
my_string: bpy.props.StringProperty(name="String Value")
|
||||
my_float = bpy.props.FloatProperty(name="Some Floating Point")
|
||||
my_bool = bpy.props.BoolProperty(name="Toggle Option")
|
||||
my_string = bpy.props.StringProperty(name="String Value")
|
||||
|
||||
def execute(self, context):
|
||||
self.report(
|
||||
{'INFO'}, 'F: %.2f B: %s S: %r' %
|
||||
(self.my_float, self.my_bool, self.my_string)
|
||||
)
|
||||
self.report({'INFO'}, 'F: %.2f B: %s S: %r' %
|
||||
(self.my_float, self.my_bool, self.my_string))
|
||||
print('My float:', self.my_float)
|
||||
print('My bool:', self.my_bool)
|
||||
print('My string:', self.my_string)
|
||||
@@ -55,8 +53,5 @@ bpy.utils.register_class(OBJECT_OT_property_example)
|
||||
bpy.utils.register_class(OBJECT_PT_property_example)
|
||||
|
||||
# Demo call. Be sure to also test in the 3D Viewport.
|
||||
bpy.ops.object.property_example(
|
||||
my_float=47,
|
||||
my_bool=True,
|
||||
my_string="Shouldn't that be 327?",
|
||||
)
|
||||
bpy.ops.object.property_example(my_float=47, my_bool=True,
|
||||
my_string="Shouldn't that be 327?")
|
||||
|
@@ -10,14 +10,15 @@ import bpy
|
||||
|
||||
|
||||
class MaterialSettings(bpy.types.PropertyGroup):
|
||||
my_int: bpy.props.IntProperty()
|
||||
my_float: bpy.props.FloatProperty()
|
||||
my_string: bpy.props.StringProperty()
|
||||
my_int = bpy.props.IntProperty()
|
||||
my_float = bpy.props.FloatProperty()
|
||||
my_string = bpy.props.StringProperty()
|
||||
|
||||
|
||||
bpy.utils.register_class(MaterialSettings)
|
||||
|
||||
bpy.types.Material.my_settings = bpy.props.PointerProperty(type=MaterialSettings)
|
||||
bpy.types.Material.my_settings = \
|
||||
bpy.props.PointerProperty(type=MaterialSettings)
|
||||
|
||||
# test the new settings work
|
||||
material = bpy.data.materials[0]
|
||||
|
@@ -9,17 +9,18 @@ Custom properties can be added to any subclass of an :class:`ID`,
|
||||
import bpy
|
||||
|
||||
|
||||
# Assign a collection.
|
||||
# Assign a collection
|
||||
class SceneSettingItem(bpy.types.PropertyGroup):
|
||||
name: bpy.props.StringProperty(name="Test Property", default="Unknown")
|
||||
value: bpy.props.IntProperty(name="Test Property", default=22)
|
||||
name = bpy.props.StringProperty(name="Test Prop", default="Unknown")
|
||||
value = bpy.props.IntProperty(name="Test Prop", default=22)
|
||||
|
||||
|
||||
bpy.utils.register_class(SceneSettingItem)
|
||||
|
||||
bpy.types.Scene.my_settings = bpy.props.CollectionProperty(type=SceneSettingItem)
|
||||
bpy.types.Scene.my_settings = \
|
||||
bpy.props.CollectionProperty(type=SceneSettingItem)
|
||||
|
||||
# Assume an armature object selected.
|
||||
# Assume an armature object selected
|
||||
print("Adding 2 values!")
|
||||
|
||||
my_item = bpy.context.scene.my_settings.add()
|
||||
|
@@ -12,7 +12,7 @@ like Blender's existing properties.
|
||||
import bpy
|
||||
|
||||
# Assign a custom property to an existing type.
|
||||
bpy.types.Material.custom_float = bpy.props.FloatProperty(name="Test Property")
|
||||
bpy.types.Material.custom_float = bpy.props.FloatProperty(name="Test Prob")
|
||||
|
||||
# Test the property is there.
|
||||
bpy.data.materials[0].custom_float = 5.0
|
||||
|
@@ -22,15 +22,15 @@ class ExampleAddonPreferences(AddonPreferences):
|
||||
# when defining this in a submodule of a python package.
|
||||
bl_idname = __name__
|
||||
|
||||
filepath: StringProperty(
|
||||
filepath = StringProperty(
|
||||
name="Example File Path",
|
||||
subtype='FILE_PATH',
|
||||
)
|
||||
number: IntProperty(
|
||||
number = IntProperty(
|
||||
name="Example Number",
|
||||
default=4,
|
||||
)
|
||||
boolean: BoolProperty(
|
||||
boolean = BoolProperty(
|
||||
name="Example Boolean",
|
||||
default=False,
|
||||
)
|
||||
|
@@ -7,6 +7,7 @@ object, placing it into a view layer, selecting it and making it active.
|
||||
"""
|
||||
|
||||
import bpy
|
||||
from mathutils import Matrix
|
||||
|
||||
view_layer = bpy.context.view_layer
|
||||
|
||||
|
@@ -28,8 +28,8 @@ class SimpleMouseOperator(bpy.types.Operator):
|
||||
bl_idname = "wm.mouse_position"
|
||||
bl_label = "Invoke Mouse Operator"
|
||||
|
||||
x: bpy.props.IntProperty()
|
||||
y: bpy.props.IntProperty()
|
||||
x = bpy.props.IntProperty()
|
||||
y = bpy.props.IntProperty()
|
||||
|
||||
def execute(self, context):
|
||||
# rather than printing, use the report function,
|
||||
|
@@ -21,7 +21,7 @@ class ExportSomeData(bpy.types.Operator):
|
||||
bl_idname = "export.some_data"
|
||||
bl_label = "Export Some Data"
|
||||
|
||||
filepath: bpy.props.StringProperty(subtype="FILE_PATH")
|
||||
filepath = bpy.props.StringProperty(subtype="FILE_PATH")
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
|
@@ -11,15 +11,13 @@ class DialogOperator(bpy.types.Operator):
|
||||
bl_idname = "object.dialog_operator"
|
||||
bl_label = "Simple Dialog Operator"
|
||||
|
||||
my_float: bpy.props.FloatProperty(name="Some Floating Point")
|
||||
my_bool: bpy.props.BoolProperty(name="Toggle Option")
|
||||
my_string: bpy.props.StringProperty(name="String Value")
|
||||
my_float = bpy.props.FloatProperty(name="Some Floating Point")
|
||||
my_bool = bpy.props.BoolProperty(name="Toggle Option")
|
||||
my_string = bpy.props.StringProperty(name="String Value")
|
||||
|
||||
def execute(self, context):
|
||||
message = (
|
||||
"Popup Values: %f, %d, '%s'" %
|
||||
message = "Popup Values: %f, %d, '%s'" % \
|
||||
(self.my_float, self.my_bool, self.my_string)
|
||||
)
|
||||
self.report({'INFO'}, message)
|
||||
return {'FINISHED'}
|
||||
|
||||
@@ -30,5 +28,5 @@ class DialogOperator(bpy.types.Operator):
|
||||
|
||||
bpy.utils.register_class(DialogOperator)
|
||||
|
||||
# Test call.
|
||||
# test call
|
||||
bpy.ops.object.dialog_operator('INVOKE_DEFAULT')
|
||||
|
@@ -16,11 +16,11 @@ class CustomDrawOperator(bpy.types.Operator):
|
||||
bl_idname = "object.custom_draw"
|
||||
bl_label = "Simple Modal Operator"
|
||||
|
||||
filepath: bpy.props.StringProperty(subtype="FILE_PATH")
|
||||
filepath = bpy.props.StringProperty(subtype="FILE_PATH")
|
||||
|
||||
my_float: bpy.props.FloatProperty(name="Float")
|
||||
my_bool: bpy.props.BoolProperty(name="Toggle Option")
|
||||
my_string: bpy.props.StringProperty(name="String Value")
|
||||
my_float = bpy.props.FloatProperty(name="Float")
|
||||
my_bool = bpy.props.BoolProperty(name="Toggle Option")
|
||||
my_string = bpy.props.StringProperty(name="String Value")
|
||||
|
||||
def execute(self, context):
|
||||
print("Test", self)
|
||||
|
@@ -14,7 +14,7 @@ class SearchEnumOperator(bpy.types.Operator):
|
||||
bl_label = "Search Enum Operator"
|
||||
bl_property = "my_search"
|
||||
|
||||
my_search: EnumProperty(
|
||||
my_search = EnumProperty(
|
||||
name="My Search",
|
||||
items=(
|
||||
('FOO', "Foo", ""),
|
||||
|
@@ -28,8 +28,8 @@ import bpy
|
||||
|
||||
|
||||
class MyPropertyGroup(bpy.types.PropertyGroup):
|
||||
custom_1: bpy.props.FloatProperty(name="My Float")
|
||||
custom_2: bpy.props.IntProperty(name="My Int")
|
||||
custom_1 = bpy.props.FloatProperty(name="My Float")
|
||||
custom_2 = bpy.props.IntProperty(name="My Int")
|
||||
|
||||
|
||||
bpy.utils.register_class(MyPropertyGroup)
|
||||
|
@@ -4,218 +4,82 @@ Simple Render Engine
|
||||
"""
|
||||
|
||||
import bpy
|
||||
import bgl
|
||||
|
||||
|
||||
class CustomRenderEngine(bpy.types.RenderEngine):
|
||||
# These three members are used by blender to set up the
|
||||
# RenderEngine; define its internal name, visible name and capabilities.
|
||||
bl_idname = "CUSTOM"
|
||||
bl_label = "Custom"
|
||||
bl_idname = "custom_renderer"
|
||||
bl_label = "Flat Color Renderer"
|
||||
bl_use_preview = True
|
||||
|
||||
# Init is called whenever a new render engine instance is created. Multiple
|
||||
# instances may exist at the same time, for example for a viewport and final
|
||||
# render.
|
||||
def __init__(self):
|
||||
self.scene_data = None
|
||||
self.draw_data = None
|
||||
|
||||
# When the render engine instance is destroy, this is called. Clean up any
|
||||
# render engine data here, for example stopping running render threads.
|
||||
def __del__(self):
|
||||
pass
|
||||
|
||||
# This is the method called by Blender for both final renders (F12) and
|
||||
# small preview for materials, world and lights.
|
||||
def render(self, depsgraph):
|
||||
scene = depsgraph.scene
|
||||
# This is the only method called by blender, in this example
|
||||
# we use it to detect preview rendering and call the implementation
|
||||
# in another method.
|
||||
def render(self, scene):
|
||||
scale = scene.render.resolution_percentage / 100.0
|
||||
self.size_x = int(scene.render.resolution_x * scale)
|
||||
self.size_y = int(scene.render.resolution_y * scale)
|
||||
|
||||
# Fill the render result with a flat color. The framebuffer is
|
||||
# defined as a list of pixels, each pixel itself being a list of
|
||||
# R,G,B,A values.
|
||||
if self.is_preview:
|
||||
color = [0.1, 0.2, 0.1, 1.0]
|
||||
self.render_preview(scene)
|
||||
else:
|
||||
color = [0.2, 0.1, 0.1, 1.0]
|
||||
self.render_scene(scene)
|
||||
|
||||
# In this example, we fill the preview renders with a flat green color.
|
||||
def render_preview(self, scene):
|
||||
pixel_count = self.size_x * self.size_y
|
||||
rect = [color] * pixel_count
|
||||
|
||||
# The framebuffer is defined as a list of pixels, each pixel
|
||||
# itself being a list of R,G,B,A values
|
||||
green_rect = [[0.0, 1.0, 0.0, 1.0]] * pixel_count
|
||||
|
||||
# Here we write the pixel values to the RenderResult
|
||||
result = self.begin_result(0, 0, self.size_x, self.size_y)
|
||||
layer = result.layers[0].passes["Combined"]
|
||||
layer.rect = rect
|
||||
layer.rect = green_rect
|
||||
self.end_result(result)
|
||||
|
||||
# For viewport renders, this method gets called once at the start and
|
||||
# whenever the scene or 3D viewport changes. This method is where data
|
||||
# should be read from Blender in the same thread. Typically a render
|
||||
# thread will be started to do the work while keeping Blender responsive.
|
||||
def view_update(self, context):
|
||||
region = context.region
|
||||
view3d = context.space_data
|
||||
depsgraph = context.depsgraph
|
||||
scene = depsgraph.scene
|
||||
# In this example, we fill the full renders with a flat blue color.
|
||||
def render_scene(self, scene):
|
||||
pixel_count = self.size_x * self.size_y
|
||||
|
||||
# Get viewport dimensions
|
||||
dimensions = region.width, region.height
|
||||
# The framebuffer is defined as a list of pixels, each pixel
|
||||
# itself being a list of R,G,B,A values
|
||||
blue_rect = [[0.0, 0.0, 1.0, 1.0]] * pixel_count
|
||||
|
||||
if not self.scene_data:
|
||||
# First time initialization
|
||||
self.scene_data = []
|
||||
first_time = True
|
||||
# Here we write the pixel values to the RenderResult
|
||||
result = self.begin_result(0, 0, self.size_x, self.size_y)
|
||||
layer = result.layers[0].passes["Combined"]
|
||||
layer.rect = blue_rect
|
||||
self.end_result(result)
|
||||
|
||||
# Loop over all datablocks used in the scene.
|
||||
for datablock in depsgraph.ids:
|
||||
pass
|
||||
else:
|
||||
first_time = False
|
||||
|
||||
# Test which datablocks changed
|
||||
for update in depsgraph.updates:
|
||||
print("Datablock updated: ", update.id.name)
|
||||
|
||||
# Test if any material was added, removed or changed.
|
||||
if depsgraph.id_type_update('MATERIAL'):
|
||||
print("Materials updated")
|
||||
|
||||
# Loop over all object instances in the scene.
|
||||
if first_time or depsgraph.id_type_update('OBJECT'):
|
||||
for instance in depsgraph.object_instances:
|
||||
pass
|
||||
|
||||
# For viewport renders, this method is called whenever Blender redraws
|
||||
# the 3D viewport. The renderer is expected to quickly draw the render
|
||||
# with OpenGL, and not perform other expensive work.
|
||||
# Blender will draw overlays for selection and editing on top of the
|
||||
# rendered image automatically.
|
||||
def view_draw(self, context):
|
||||
region = context.region
|
||||
depsgraph = context.depsgraph
|
||||
scene = depsgraph.scene
|
||||
|
||||
# Get viewport dimensions
|
||||
dimensions = region.width, region.height
|
||||
|
||||
# Bind shader that converts from scene linear to display space,
|
||||
bgl.glEnable(bgl.GL_BLEND)
|
||||
bgl.glBlendFunc(bgl.GL_ONE, bgl.GL_ONE_MINUS_SRC_ALPHA);
|
||||
self.bind_display_space_shader(scene)
|
||||
|
||||
if not self.draw_data or self.draw_data.dimensions != dimensions:
|
||||
self.draw_data = CustomDrawData(dimensions)
|
||||
|
||||
self.draw_data.draw()
|
||||
|
||||
self.unbind_display_space_shader()
|
||||
bgl.glDisable(bgl.GL_BLEND)
|
||||
|
||||
|
||||
class CustomDrawData:
|
||||
def __init__(self, dimensions):
|
||||
# Generate dummy float image buffer
|
||||
self.dimensions = dimensions
|
||||
width, height = dimensions
|
||||
|
||||
pixels = [0.1, 0.2, 0.1, 1.0] * width * height
|
||||
pixels = bgl.Buffer(bgl.GL_FLOAT, width * height * 4, pixels)
|
||||
|
||||
# Generate texture
|
||||
self.texture = bgl.Buffer(bgl.GL_INT, 1)
|
||||
bgl.glGenTextures(1, self.texture)
|
||||
bgl.glActiveTexture(bgl.GL_TEXTURE0)
|
||||
bgl.glBindTexture(bgl.GL_TEXTURE_2D, self.texture[0])
|
||||
bgl.glTexImage2D(bgl.GL_TEXTURE_2D, 0, bgl.GL_RGBA16F, width, height, 0, bgl.GL_RGBA, bgl.GL_FLOAT, pixels)
|
||||
bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MIN_FILTER, bgl.GL_LINEAR)
|
||||
bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MAG_FILTER, bgl.GL_LINEAR)
|
||||
bgl.glBindTexture(bgl.GL_TEXTURE_2D, 0)
|
||||
|
||||
# Bind shader that converts from scene linear to display space,
|
||||
# use the scene's color management settings.
|
||||
shader_program = bgl.Buffer(bgl.GL_INT, 1)
|
||||
bgl.glGetIntegerv(bgl.GL_CURRENT_PROGRAM, shader_program);
|
||||
|
||||
# Generate vertex array
|
||||
self.vertex_array = bgl.Buffer(bgl.GL_INT, 1)
|
||||
bgl.glGenVertexArrays(1, self.vertex_array)
|
||||
bgl.glBindVertexArray(self.vertex_array[0])
|
||||
|
||||
texturecoord_location = bgl.glGetAttribLocation(shader_program[0], "texCoord");
|
||||
position_location = bgl.glGetAttribLocation(shader_program[0], "pos");
|
||||
|
||||
bgl.glEnableVertexAttribArray(texturecoord_location);
|
||||
bgl.glEnableVertexAttribArray(position_location);
|
||||
|
||||
# Generate geometry buffers for drawing textured quad
|
||||
position = [0.0, 0.0, width, 0.0, width, height, 0.0, height]
|
||||
position = bgl.Buffer(bgl.GL_FLOAT, len(position), position)
|
||||
texcoord = [0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0]
|
||||
texcoord = bgl.Buffer(bgl.GL_FLOAT, len(texcoord), texcoord)
|
||||
|
||||
self.vertex_buffer = bgl.Buffer(bgl.GL_INT, 2)
|
||||
|
||||
bgl.glGenBuffers(2, self.vertex_buffer)
|
||||
bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vertex_buffer[0])
|
||||
bgl.glBufferData(bgl.GL_ARRAY_BUFFER, 32, position, bgl.GL_STATIC_DRAW)
|
||||
bgl.glVertexAttribPointer(position_location, 2, bgl.GL_FLOAT, bgl.GL_FALSE, 0, None)
|
||||
|
||||
bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vertex_buffer[1])
|
||||
bgl.glBufferData(bgl.GL_ARRAY_BUFFER, 32, texcoord, bgl.GL_STATIC_DRAW)
|
||||
bgl.glVertexAttribPointer(texturecoord_location, 2, bgl.GL_FLOAT, bgl.GL_FALSE, 0, None)
|
||||
|
||||
bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, 0)
|
||||
bgl.glBindVertexArray(0)
|
||||
|
||||
def __del__(self):
|
||||
bgl.glDeleteBuffers(2, self.vertex_buffer)
|
||||
bgl.glDeleteVertexArrays(1, self.vertex_array)
|
||||
bgl.glBindTexture(bgl.GL_TEXTURE_2D, 0)
|
||||
bgl.glDeleteTextures(1, self.texture)
|
||||
|
||||
def draw(self):
|
||||
bgl.glActiveTexture(bgl.GL_TEXTURE0)
|
||||
bgl.glBindTexture(bgl.GL_TEXTURE_2D, self.texture[0])
|
||||
bgl.glBindVertexArray(self.vertex_array[0])
|
||||
bgl.glDrawArrays(bgl.GL_TRIANGLE_FAN, 0, 4);
|
||||
bgl.glBindVertexArray(0)
|
||||
bgl.glBindTexture(bgl.GL_TEXTURE_2D, 0)
|
||||
|
||||
|
||||
# RenderEngines also need to tell UI Panels that they are compatible with.
|
||||
# We recommend to enable all panels marked as BLENDER_RENDER, and then
|
||||
# exclude any panels that are replaced by custom panels registered by the
|
||||
# render engine, or that are not supported.
|
||||
def get_panels():
|
||||
exclude_panels = {
|
||||
'VIEWLAYER_PT_filter',
|
||||
'VIEWLAYER_PT_layer_passes',
|
||||
}
|
||||
|
||||
panels = []
|
||||
for panel in bpy.types.Panel.__subclasses__():
|
||||
if hasattr(panel, 'COMPAT_ENGINES') and 'BLENDER_RENDER' in panel.COMPAT_ENGINES:
|
||||
if panel.__name__ not in exclude_panels:
|
||||
panels.append(panel)
|
||||
|
||||
return panels
|
||||
|
||||
def register():
|
||||
# Register the RenderEngine
|
||||
bpy.utils.register_class(CustomRenderEngine)
|
||||
|
||||
for panel in get_panels():
|
||||
panel.COMPAT_ENGINES.add('CUSTOM')
|
||||
# RenderEngines also need to tell UI Panels that they are compatible
|
||||
# Otherwise most of the UI will be empty when the engine is selected.
|
||||
# In this example, we need to see the main render image button and
|
||||
# the material preview panel.
|
||||
from bl_ui import (
|
||||
properties_render,
|
||||
properties_material,
|
||||
)
|
||||
properties_render.RENDER_PT_render.COMPAT_ENGINES.add(CustomRenderEngine.bl_idname)
|
||||
properties_material.MATERIAL_PT_preview.COMPAT_ENGINES.add(CustomRenderEngine.bl_idname)
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.utils.unregister_class(CustomRenderEngine)
|
||||
|
||||
for panel in get_panels():
|
||||
if 'CUSTOM' in panel.COMPAT_ENGINES:
|
||||
panel.COMPAT_ENGINES.remove('CUSTOM')
|
||||
from bl_ui import (
|
||||
properties_render,
|
||||
properties_material,
|
||||
)
|
||||
properties_render.RENDER_PT_render.COMPAT_ENGINES.remove(CustomRenderEngine.bl_idname)
|
||||
properties_material.MATERIAL_PT_preview.COMPAT_ENGINES.remove(CustomRenderEngine.bl_idname)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
@@ -15,24 +15,12 @@ class MESH_UL_vgroups_slow(bpy.types.UIList):
|
||||
VGROUP_EMPTY = 1 << 0
|
||||
|
||||
# Custom properties, saved with .blend file.
|
||||
use_filter_empty: bpy.props.BoolProperty(
|
||||
name="Filter Empty",
|
||||
default=False,
|
||||
options=set(),
|
||||
description="Whether to filter empty vertex groups",
|
||||
)
|
||||
use_filter_empty_reverse: bpy.props.BoolProperty(
|
||||
name="Reverse Empty",
|
||||
default=False,
|
||||
options=set(),
|
||||
description="Reverse empty filtering",
|
||||
)
|
||||
use_filter_name_reverse: bpy.props.BoolProperty(
|
||||
name="Reverse Name",
|
||||
default=False,
|
||||
options=set(),
|
||||
description="Reverse name filtering",
|
||||
)
|
||||
use_filter_empty = bpy.props.BoolProperty(name="Filter Empty", default=False, options=set(),
|
||||
description="Whether to filter empty vertex groups")
|
||||
use_filter_empty_reverse = bpy.props.BoolProperty(name="Reverse Empty", default=False, options=set(),
|
||||
description="Reverse empty filtering")
|
||||
use_filter_name_reverse = bpy.props.BoolProperty(name="Reverse Name", default=False, options=set(),
|
||||
description="Reverse name filtering")
|
||||
|
||||
# This allows us to have mutually exclusive options, which are also all disable-able!
|
||||
def _gen_order_update(name1, name2):
|
||||
@@ -40,18 +28,12 @@ class MESH_UL_vgroups_slow(bpy.types.UIList):
|
||||
if (getattr(self, name1)):
|
||||
setattr(self, name2, False)
|
||||
return _u
|
||||
use_order_name: bpy.props.BoolProperty(
|
||||
name="Name", default=False, options=set(),
|
||||
description="Sort groups by their name (case-insensitive)",
|
||||
update=_gen_order_update("use_order_name", "use_order_importance"),
|
||||
)
|
||||
use_order_importance: bpy.props.BoolProperty(
|
||||
name="Importance",
|
||||
default=False,
|
||||
options=set(),
|
||||
description="Sort groups by their average weight in the mesh",
|
||||
update=_gen_order_update("use_order_importance", "use_order_name"),
|
||||
)
|
||||
use_order_name = bpy.props.BoolProperty(name="Name", default=False, options=set(),
|
||||
description="Sort groups by their name (case-insensitive)",
|
||||
update=_gen_order_update("use_order_name", "use_order_importance"))
|
||||
use_order_importance = bpy.props.BoolProperty(name="Importance", default=False, options=set(),
|
||||
description="Sort groups by their average weight in the mesh",
|
||||
update=_gen_order_update("use_order_importance", "use_order_name"))
|
||||
|
||||
# Usual draw item function.
|
||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index, flt_flag):
|
||||
|
@@ -5,32 +5,25 @@ than the bone.
|
||||
"""
|
||||
|
||||
import bpy
|
||||
from bpy.props import (
|
||||
FloatProperty,
|
||||
PointerProperty,
|
||||
)
|
||||
from bpy.props import PointerProperty
|
||||
|
||||
|
||||
# Define a nested property.
|
||||
# define a nested property
|
||||
class MyPropGroup(bpy.types.PropertyGroup):
|
||||
nested: FloatProperty(name="Nested", default=0.0)
|
||||
nested = bpy.props.FloatProperty(name="Nested", default=0.0)
|
||||
|
||||
|
||||
# Register it so its available for all bones.
|
||||
# register it so its available for all bones
|
||||
bpy.utils.register_class(MyPropGroup)
|
||||
bpy.types.Bone.my_prop = PointerProperty(
|
||||
type=MyPropGroup,
|
||||
name="MyProp",
|
||||
)
|
||||
bpy.types.Bone.my_prop = PointerProperty(type=MyPropGroup,
|
||||
name="MyProp")
|
||||
|
||||
# Get a bone.
|
||||
# get a bone
|
||||
obj = bpy.data.objects["Armature"]
|
||||
arm = obj.data
|
||||
|
||||
# Set the keyframe at frame 1.
|
||||
# set the keyframe at frame 1
|
||||
arm.bones["Bone"].my_prop_group.nested = 10
|
||||
arm.keyframe_insert(
|
||||
data_path='bones["Bone"].my_prop.nested',
|
||||
frame=1,
|
||||
group="Nested Group",
|
||||
)
|
||||
arm.keyframe_insert(data_path='bones["Bone"].my_prop.nested',
|
||||
frame=1,
|
||||
group="Nested Group")
|
||||
|
@@ -26,6 +26,58 @@ offers a set of extensive examples, including advanced features.
|
||||
for example.
|
||||
|
||||
|
||||
.. function:: glAccum(op, value):
|
||||
|
||||
Operate on the accumulation buffer.
|
||||
|
||||
.. seealso:: `OpenGL Docs <https://www.opengl.org/sdk/docs/man2/xhtml/glAccum.xml>`__
|
||||
|
||||
:type op: Enumerated constant
|
||||
:arg op: The accumulation buffer operation.
|
||||
:type value: float
|
||||
:arg value: a value used in the accumulation buffer operation.
|
||||
|
||||
|
||||
.. function:: glAlphaFunc(func, ref):
|
||||
|
||||
Specify the alpha test function.
|
||||
|
||||
.. seealso:: `OpenGL Docs <https://www.opengl.org/sdk/docs/man2/xhtml/glAlphaFunc.xml>`__
|
||||
|
||||
:type func: Enumerated constant
|
||||
:arg func: Specifies the alpha comparison function.
|
||||
:type ref: float
|
||||
:arg ref: The reference value that incoming alpha values are compared to.
|
||||
Clamped between 0 and 1.
|
||||
|
||||
|
||||
.. function:: glAreTexturesResident(n, textures, residences):
|
||||
|
||||
Determine if textures are loaded in texture memory
|
||||
|
||||
.. seealso:: `OpenGL Docs <https://www.opengl.org/sdk/docs/man2/xhtml/glAreTexturesResident.xml>`__
|
||||
|
||||
:type n: int
|
||||
:arg n: Specifies the number of textures to be queried.
|
||||
:type textures: :class:`bgl.Buffer` object I{type GL_INT}
|
||||
:arg textures: Specifies an array containing the names of the textures to be queried
|
||||
:type residences: :class:`bgl.Buffer` object I{type GL_INT}(boolean)
|
||||
:arg residences: An array in which the texture residence status in returned.
|
||||
The residence status of a texture named by an element of textures is
|
||||
returned in the corresponding element of residences.
|
||||
|
||||
|
||||
.. function:: glBegin(mode):
|
||||
|
||||
Delimit the vertices of a primitive or a group of like primitives
|
||||
|
||||
.. seealso:: `OpenGL Docs <https://www.opengl.org/sdk/docs/man2/xhtml/glBegin.xml>`__
|
||||
|
||||
:type mode: Enumerated constant
|
||||
:arg mode: Specifies the primitive that will be create from vertices between
|
||||
glBegin and glEnd.
|
||||
|
||||
|
||||
.. function:: glBindTexture(target, texture):
|
||||
|
||||
Bind a named texture to a texturing target
|
||||
@@ -38,6 +90,24 @@ offers a set of extensive examples, including advanced features.
|
||||
:arg texture: Specifies the name of a texture.
|
||||
|
||||
|
||||
.. function:: glBitmap(width, height, xorig, yorig, xmove, ymove, bitmap):
|
||||
|
||||
Draw a bitmap
|
||||
|
||||
.. seealso:: `OpenGL Docs <https://www.opengl.org/sdk/docs/man2/xhtml/glBitmap.xml>`__
|
||||
|
||||
:type width, height: int
|
||||
:arg width, height: Specify the pixel width and height of the bitmap image.
|
||||
:type xorig, yorig: float
|
||||
:arg xorig, yorig: Specify the location of the origin in the bitmap image. The origin is measured
|
||||
from the lower left corner of the bitmap, with right and up being the positive axes.
|
||||
:type xmove, ymove: float
|
||||
:arg xmove, ymove: Specify the x and y offsets to be added to the current raster position after
|
||||
the bitmap is drawn.
|
||||
:type bitmap: :class:`bgl.Buffer` object I{type GL_BYTE}
|
||||
:arg bitmap: Specifies the address of the bitmap image.
|
||||
|
||||
|
||||
.. function:: glBlendFunc(sfactor, dfactor):
|
||||
|
||||
Specify pixel arithmetic
|
||||
@@ -52,6 +122,32 @@ offers a set of extensive examples, including advanced features.
|
||||
blending factors are computed.
|
||||
|
||||
|
||||
.. function:: glCallList(list):
|
||||
|
||||
Execute a display list
|
||||
|
||||
.. seealso:: `OpenGL Docs <https://www.opengl.org/sdk/docs/man2/xhtml/glCallList.xml>`__
|
||||
|
||||
:type list: unsigned int
|
||||
:arg list: Specifies the integer name of the display list to be executed.
|
||||
|
||||
|
||||
.. function:: glCallLists(n, type, lists):
|
||||
|
||||
Execute a list of display lists
|
||||
|
||||
.. seealso:: `OpenGL Docs <https://www.opengl.org/sdk/docs/man2/xhtml/glCallLists.xml>`__
|
||||
|
||||
:type n: int
|
||||
:arg n: Specifies the number of display lists to be executed.
|
||||
:type type: Enumerated constant
|
||||
:arg type: Specifies the type of values in lists.
|
||||
:type lists: :class:`bgl.Buffer` object
|
||||
:arg lists: Specifies the address of an array of name offsets in the display list.
|
||||
The pointer type is void because the offsets can be bytes, shorts, ints, or floats,
|
||||
depending on the value of type.
|
||||
|
||||
|
||||
.. function:: glClear(mask):
|
||||
|
||||
Clear buffers to preset values
|
||||
@@ -62,6 +158,17 @@ offers a set of extensive examples, including advanced features.
|
||||
:arg mask: Bitwise OR of masks that indicate the buffers to be cleared.
|
||||
|
||||
|
||||
.. function:: glClearAccum(red, green, blue, alpha):
|
||||
|
||||
Specify clear values for the accumulation buffer
|
||||
|
||||
.. seealso:: `OpenGL Docs <https://www.opengl.org/sdk/docs/man2/xhtml/glClearAccum.xml>`__
|
||||
|
||||
:type red, green, blue, alpha: float
|
||||
:arg red, green, blue, alpha: Specify the red, green, blue, and alpha values used when the
|
||||
accumulation buffer is cleared. The initial values are all 0.
|
||||
|
||||
|
||||
.. function:: glClearColor(red, green, blue, alpha):
|
||||
|
||||
Specify clear values for the color buffers
|
||||
@@ -84,6 +191,17 @@ offers a set of extensive examples, including advanced features.
|
||||
The initial value is 1.
|
||||
|
||||
|
||||
.. function:: glClearIndex(c):
|
||||
|
||||
Specify the clear value for the color index buffers
|
||||
|
||||
.. seealso:: `OpenGL Docs <https://www.opengl.org/sdk/docs/man2/xhtml/glClearIndex.xml>`__
|
||||
|
||||
:type c: float
|
||||
:arg c: Specifies the index used when the color index buffers are cleared.
|
||||
The initial value is 0.
|
||||
|
||||
|
||||
.. function:: glClearStencil(s):
|
||||
|
||||
Specify the clear value for the stencil buffer
|
||||
@@ -137,7 +255,36 @@ offers a set of extensive examples, including advanced features.
|
||||
color components can be written.
|
||||
|
||||
|
||||
.. function:: glCopyTexImage2D(target, level, internalformat, x, y, width, height, border):
|
||||
.. function:: glColorMaterial(face, mode):
|
||||
|
||||
Cause a material color to track the current color
|
||||
|
||||
.. seealso:: `OpenGL Docs <https://www.opengl.org/sdk/docs/man2/xhtml/glColorMaterial.xml>`__
|
||||
|
||||
:type face: Enumerated constant
|
||||
:arg face: Specifies whether front, back, or both front and back material parameters should
|
||||
track the current color.
|
||||
:type mode: Enumerated constant
|
||||
:arg mode: Specifies which of several material parameters track the current color.
|
||||
|
||||
|
||||
.. function:: glCopyPixels(x, y, width, height, type):
|
||||
|
||||
Copy pixels in the frame buffer
|
||||
|
||||
.. seealso:: `OpenGL Docs <https://www.opengl.org/sdk/docs/man2/xhtml/glCopyPixels.xml>`__
|
||||
|
||||
:type x, y: int
|
||||
:arg x, y: Specify the window coordinates of the lower left corner of the rectangular
|
||||
region of pixels to be copied.
|
||||
:type width, height: int
|
||||
:arg width,height: Specify the dimensions of the rectangular region of pixels to be copied.
|
||||
Both must be non-negative.
|
||||
:type type: Enumerated constant
|
||||
:arg type: Specifies whether color values, depth values, or stencil values are to be copied.
|
||||
|
||||
|
||||
def glCopyTexImage2D(target, level, internalformat, x, y, width, height, border):
|
||||
|
||||
Copy pixels into a 2D texture image
|
||||
|
||||
@@ -176,6 +323,18 @@ offers a set of extensive examples, including advanced features.
|
||||
:arg mode: Specifies whether front- or back-facing facets are candidates for culling.
|
||||
|
||||
|
||||
.. function:: glDeleteLists(list, range):
|
||||
|
||||
Delete a contiguous group of display lists
|
||||
|
||||
.. seealso:: `OpenGL Docs <https://www.opengl.org/sdk/docs/man2/xhtml/glDeleteLists.xml>`__
|
||||
|
||||
:type list: unsigned int
|
||||
:arg list: Specifies the integer name of the first display list to delete
|
||||
:type range: int
|
||||
:arg range: Specifies the number of display lists to delete
|
||||
|
||||
|
||||
.. function:: glDeleteTextures(n, textures):
|
||||
|
||||
Delete named textures
|
||||
@@ -244,6 +403,23 @@ offers a set of extensive examples, including advanced features.
|
||||
:arg mode: Specifies up to four color buffers to be drawn into.
|
||||
|
||||
|
||||
.. function:: glDrawPixels(width, height, format, type, pixels):
|
||||
|
||||
Write a block of pixels to the frame buffer
|
||||
|
||||
.. seealso:: `OpenGL Docs <https://www.opengl.org/sdk/docs/man2/xhtml/glDrawPixels.xml>`__
|
||||
|
||||
:type width, height: int
|
||||
:arg width, height: Specify the dimensions of the pixel rectangle to be
|
||||
written into the frame buffer.
|
||||
:type format: Enumerated constant
|
||||
:arg format: Specifies the format of the pixel data.
|
||||
:type type: Enumerated constant
|
||||
:arg type: Specifies the data type for pixels.
|
||||
:type pixels: :class:`bgl.Buffer` object
|
||||
:arg pixels: Specifies a pointer to the pixel data.
|
||||
|
||||
|
||||
.. function:: glEdgeFlag (flag):
|
||||
|
||||
B{glEdgeFlag, glEdgeFlagv}
|
||||
@@ -266,6 +442,20 @@ offers a set of extensive examples, including advanced features.
|
||||
:arg cap: Specifies a symbolic constant indicating a GL capability.
|
||||
|
||||
|
||||
.. function:: glEnd():
|
||||
|
||||
Delimit the vertices of a primitive or group of like primitives
|
||||
|
||||
.. seealso:: `OpenGL Docs <https://www.opengl.org/sdk/docs/man2/xhtml/glBegin.xml>`__
|
||||
|
||||
|
||||
.. function:: glEndList():
|
||||
|
||||
Create or replace a display list
|
||||
|
||||
.. seealso:: `OpenGL Docs <https://www.opengl.org/sdk/docs/man2/xhtml/glNewList.xml>`__
|
||||
|
||||
|
||||
.. function:: glEvalCoord (u,v):
|
||||
|
||||
B{glEvalCoord1d, glEvalCoord1f, glEvalCoord2d, glEvalCoord2f, glEvalCoord1dv, glEvalCoord1fv,
|
||||
@@ -370,6 +560,33 @@ offers a set of extensive examples, including advanced features.
|
||||
:arg mode: Specifies the orientation of front-facing polygons.
|
||||
|
||||
|
||||
.. function:: glFrustum(left, right, bottom, top, zNear, zFar):
|
||||
|
||||
Multiply the current matrix by a perspective matrix
|
||||
|
||||
.. seealso:: `OpenGL Docs <https://www.opengl.org/sdk/docs/man2/xhtml/glFrustum.xml>`__
|
||||
|
||||
:type left, right: double (float)
|
||||
:arg left, right: Specify the coordinates for the left and right vertical
|
||||
clipping planes.
|
||||
:type top, bottom: double (float)
|
||||
:arg top, bottom: Specify the coordinates for the bottom and top horizontal
|
||||
clipping planes.
|
||||
:type zNear, zFar: double (float)
|
||||
:arg zNear, zFar: Specify the distances to the near and far depth clipping planes.
|
||||
Both distances must be positive.
|
||||
|
||||
|
||||
.. function:: glGenLists(range):
|
||||
|
||||
Generate a contiguous set of empty display lists
|
||||
|
||||
.. seealso:: `OpenGL Docs <https://www.opengl.org/sdk/docs/man2/xhtml/glGenLists.xml>`__
|
||||
|
||||
:type range: int
|
||||
:arg range: Specifies the number of contiguous empty display lists to be generated.
|
||||
|
||||
|
||||
.. function:: glGenTextures(n, textures):
|
||||
|
||||
Generate texture names
|
||||
@@ -396,6 +613,21 @@ offers a set of extensive examples, including advanced features.
|
||||
:arg param: Returns the value or values of the specified parameter.
|
||||
|
||||
|
||||
.. function:: glGetClipPlane(plane, equation):
|
||||
|
||||
Return the coefficients of the specified clipping plane
|
||||
|
||||
.. seealso:: `OpenGL Docs <https://www.opengl.org/sdk/docs/man2/xhtml/glGetClipPlane.xml>`__
|
||||
|
||||
:type plane: Enumerated constant
|
||||
:arg plane: Specifies a clipping plane. The number of clipping planes depends on the
|
||||
implementation, but at least six clipping planes are supported. They are identified by
|
||||
symbolic names of the form GL_CLIP_PLANEi where 0 < i < GL_MAX_CLIP_PLANES.
|
||||
:type equation: :class:`bgl.Buffer` object I{type GL_FLOAT}
|
||||
:arg equation: Returns four float (double)-precision values that are the coefficients of the
|
||||
plane equation of plane in eye coordinates. The initial value is (0, 0, 0, 0).
|
||||
|
||||
|
||||
.. function:: glGetError():
|
||||
|
||||
Return error information
|
||||
@@ -468,6 +700,16 @@ offers a set of extensive examples, including advanced features.
|
||||
:arg values: Returns the pixel map contents.
|
||||
|
||||
|
||||
.. function:: glGetPolygonStipple(mask):
|
||||
|
||||
Return the polygon stipple pattern
|
||||
|
||||
.. seealso:: `OpenGL Docs <https://www.opengl.org/sdk/docs/man2/xhtml/glGetPolygonStipple.xml>`__
|
||||
|
||||
:type mask: :class:`bgl.Buffer` object I{type GL_BYTE}
|
||||
:arg mask: Returns the stipple pattern. The initial value is all 1's.
|
||||
|
||||
|
||||
.. function:: glGetString(name):
|
||||
|
||||
Return a string describing the current GL connection
|
||||
@@ -579,6 +821,38 @@ offers a set of extensive examples, including advanced features.
|
||||
:arg mode: Specifies a symbolic constant indicating the desired behavior.
|
||||
|
||||
|
||||
.. function:: glIndex(c):
|
||||
|
||||
B{glIndexd, glIndexf, glIndexi, glIndexs, glIndexdv, glIndexfv, glIndexiv, glIndexsv}
|
||||
|
||||
Set the current color index
|
||||
|
||||
.. seealso:: `OpenGL Docs <https://www.opengl.org/sdk/docs/man2/xhtml/glIndex.xml>`__
|
||||
|
||||
:type c: :class:`bgl.Buffer` object. Depends on function prototype.
|
||||
:arg c: Specifies a pointer to a one element array that contains the new value for
|
||||
the current color index.
|
||||
|
||||
|
||||
.. function:: glIndexMask(mask):
|
||||
|
||||
Control the writing of individual bits in the color index buffers
|
||||
|
||||
.. seealso:: `OpenGL Docs <https://www.opengl.org/sdk/docs/man2/xhtml/glIndexMask.xml>`__
|
||||
|
||||
:type mask: int
|
||||
:arg mask: Specifies a bit mask to enable and disable the writing of individual bits
|
||||
in the color index buffers.
|
||||
Initially, the mask is all 1's.
|
||||
|
||||
|
||||
.. function:: glInitNames():
|
||||
|
||||
Initialize the name stack
|
||||
|
||||
.. seealso:: `OpenGL Docs <https://www.opengl.org/sdk/docs/man2/xhtml/glInitNames.xml>`__
|
||||
|
||||
|
||||
.. function:: glIsEnabled(cap):
|
||||
|
||||
Test whether a capability is enabled
|
||||
@@ -589,6 +863,16 @@ offers a set of extensive examples, including advanced features.
|
||||
:arg cap: Specifies a constant representing a GL capability.
|
||||
|
||||
|
||||
.. function:: glIsList(list):
|
||||
|
||||
Determine if a name corresponds to a display-list
|
||||
|
||||
.. seealso:: `OpenGL Docs <https://www.opengl.org/sdk/docs/man2/xhtml/glIsList.xml>`__
|
||||
|
||||
:type list: unsigned int
|
||||
:arg list: Specifies a potential display-list name.
|
||||
|
||||
|
||||
.. function:: glIsTexture(texture):
|
||||
|
||||
Determine if a name corresponds to a texture
|
||||
@@ -634,6 +918,23 @@ offers a set of extensive examples, including advanced features.
|
||||
specifies a pointer to the value or values that param will be set to.
|
||||
|
||||
|
||||
.. function:: glLineStipple(factor, pattern):
|
||||
|
||||
Specify the line stipple pattern
|
||||
|
||||
.. seealso:: `OpenGL Docs <https://www.opengl.org/sdk/docs/man2/xhtml/glLineStipple.xml>`__
|
||||
|
||||
:type factor: int
|
||||
:arg factor: Specifies a multiplier for each bit in the line stipple pattern.
|
||||
If factor is 3, for example, each bit in the pattern is used three times before
|
||||
the next bit in the pattern is used. factor is clamped to the range [1, 256] and
|
||||
defaults to 1.
|
||||
:type pattern: unsigned short int
|
||||
:arg pattern: Specifies a 16-bit integer whose bit pattern determines which fragments
|
||||
of a line will be drawn when the line is rasterized. Bit zero is used first; the default
|
||||
pattern is all 1's.
|
||||
|
||||
|
||||
.. function:: glLineWidth(width):
|
||||
|
||||
Specify the width of rasterized lines.
|
||||
@@ -644,6 +945,24 @@ offers a set of extensive examples, including advanced features.
|
||||
:arg width: Specifies the width of rasterized lines. The initial value is 1.
|
||||
|
||||
|
||||
.. function:: glListBase(base):
|
||||
|
||||
Set the display-list base for glCallLists
|
||||
|
||||
.. seealso:: `OpenGL Docs <https://www.opengl.org/sdk/docs/man2/xhtml/glListBase.xml>`__
|
||||
|
||||
:type base: unsigned int
|
||||
:arg base: Specifies an integer offset that will be added to glCallLists
|
||||
offsets to generate display-list names. The initial value is 0.
|
||||
|
||||
|
||||
.. function:: glLoadIdentity():
|
||||
|
||||
Replace the current matrix with the identity matrix
|
||||
|
||||
.. seealso:: `OpenGL Docs <https://www.opengl.org/sdk/docs/man2/xhtml/glLoadIdentity.xml>`__
|
||||
|
||||
|
||||
.. function:: glLoadMatrix (m):
|
||||
|
||||
B{glLoadMatrixd, glLoadMatixf}
|
||||
@@ -657,6 +976,16 @@ offers a set of extensive examples, including advanced features.
|
||||
of a 4x4 column-major matrix.
|
||||
|
||||
|
||||
.. function:: glLoadName(name):
|
||||
|
||||
Load a name onto the name stack.
|
||||
|
||||
.. seealso:: `OpenGL Docs <https://www.opengl.org/sdk/docs/man2/xhtml/glLoadName.xml>`__
|
||||
|
||||
:type name: unsigned int
|
||||
:arg name: Specifies a name that will replace the top value on the name stack.
|
||||
|
||||
|
||||
.. function:: glLogicOp(opcode):
|
||||
|
||||
Specify a logical pixel operation for color index rendering
|
||||
@@ -771,6 +1100,16 @@ offers a set of extensive examples, including advanced features.
|
||||
pname will be set to.
|
||||
|
||||
|
||||
.. function:: glMatrixMode(mode):
|
||||
|
||||
Specify which matrix is the current matrix.
|
||||
|
||||
.. seealso:: `OpenGL Docs <https://www.opengl.org/sdk/docs/man2/xhtml/glMatrixMode.xml>`__
|
||||
|
||||
:type mode: Enumerated constant
|
||||
:arg mode: Specifies which matrix stack is the target for subsequent matrix operations.
|
||||
|
||||
|
||||
.. function:: glMultMatrix (m):
|
||||
|
||||
B{glMultMatrixd, glMultMatrixf}
|
||||
@@ -784,6 +1123,18 @@ offers a set of extensive examples, including advanced features.
|
||||
major matrix.
|
||||
|
||||
|
||||
.. function:: glNewList(list, mode):
|
||||
|
||||
Create or replace a display list
|
||||
|
||||
.. seealso:: `OpenGL Docs <https://www.opengl.org/sdk/docs/man2/xhtml/glNewList.xml>`__
|
||||
|
||||
:type list: unsigned int
|
||||
:arg list: Specifies the display list name
|
||||
:type mode: Enumerated constant
|
||||
:arg mode: Specifies the compilation mode.
|
||||
|
||||
|
||||
.. function:: glNormal3 (nx, ny, nz, v):
|
||||
|
||||
B{Normal3b, Normal3bv, Normal3d, Normal3dv, Normal3f, Normal3fv, Normal3i, Normal3iv,
|
||||
@@ -801,6 +1152,34 @@ offers a set of extensive examples, including advanced features.
|
||||
of the new current normal.
|
||||
|
||||
|
||||
.. function:: glOrtho(left, right, bottom, top, zNear, zFar):
|
||||
|
||||
Multiply the current matrix with an orthographic matrix
|
||||
|
||||
.. seealso:: `OpenGL Docs <https://www.opengl.org/sdk/docs/man2/xhtml/glOrtho.xml>`__
|
||||
|
||||
:type left, right: double (float)
|
||||
:arg left, right: Specify the coordinates for the left and
|
||||
right vertical clipping planes.
|
||||
:type bottom, top: double (float)
|
||||
:arg bottom, top: Specify the coordinates for the bottom and top
|
||||
horizontal clipping planes.
|
||||
:type zNear, zFar: double (float)
|
||||
:arg zNear, zFar: Specify the distances to the nearer and farther
|
||||
depth clipping planes. These values are negative if the plane is to be behind the viewer.
|
||||
|
||||
|
||||
.. function:: glPassThrough(token):
|
||||
|
||||
Place a marker in the feedback buffer
|
||||
|
||||
.. seealso:: `OpenGL Docs <https://www.opengl.org/sdk/docs/man2/xhtml/glPassThrough.xml>`__
|
||||
|
||||
:type token: float
|
||||
:arg token: Specifies a marker value to be placed in the feedback
|
||||
buffer following a GL_PASS_THROUGH_TOKEN.
|
||||
|
||||
|
||||
.. function:: glPixelMap (map, mapsize, values):
|
||||
|
||||
B{glPixelMapfv, glPixelMapuiv, glPixelMapusv}
|
||||
@@ -847,6 +1226,16 @@ offers a set of extensive examples, including advanced features.
|
||||
:arg param: Specifies the value that pname is set to.
|
||||
|
||||
|
||||
.. function:: glPixelZoom(xfactor, yfactor):
|
||||
|
||||
Specify the pixel zoom factors
|
||||
|
||||
.. seealso:: `OpenGL Docs <https://www.opengl.org/sdk/docs/man2/xhtml/glPixelZoom.xml>`__
|
||||
|
||||
:type xfactor, yfactor: float
|
||||
:arg xfactor, yfactor: Specify the x and y zoom factors for pixel write operations.
|
||||
|
||||
|
||||
.. function:: glPointSize(size):
|
||||
|
||||
Specify the diameter of rasterized points
|
||||
@@ -886,6 +1275,98 @@ offers a set of extensive examples, including advanced features.
|
||||
constant depth offset. The initial value is 0.
|
||||
|
||||
|
||||
.. function:: glPolygonStipple(mask):
|
||||
|
||||
Set the polygon stippling pattern
|
||||
|
||||
.. seealso:: `OpenGL Docs <https://www.opengl.org/sdk/docs/man2/xhtml/glPolygonStipple.xml>`__
|
||||
|
||||
:type mask: :class:`bgl.Buffer` object I{type GL_BYTE}
|
||||
:arg mask: Specifies a pointer to a 32x32 stipple pattern that will be unpacked
|
||||
from memory in the same way that glDrawPixels unpacks pixels.
|
||||
|
||||
|
||||
.. function:: glPopAttrib():
|
||||
|
||||
Pop the server attribute stack
|
||||
|
||||
.. seealso:: `OpenGL Docs <https://www.opengl.org/sdk/docs/man2/xhtml/glPopAttrib.xml>`__
|
||||
|
||||
|
||||
.. function:: glPopClientAttrib():
|
||||
|
||||
Pop the client attribute stack
|
||||
|
||||
.. seealso:: `OpenGL Docs <https://www.opengl.org/sdk/docs/man2/xhtml/glPopClientAttrib.xml>`__
|
||||
|
||||
|
||||
.. function:: glPopMatrix():
|
||||
|
||||
Pop the current matrix stack
|
||||
|
||||
.. seealso:: `OpenGL Docs <https://www.opengl.org/sdk/docs/man2/xhtml/glPopMatrix.xml>`__
|
||||
|
||||
|
||||
.. function:: glPopName():
|
||||
|
||||
Pop the name stack
|
||||
|
||||
.. seealso:: `OpenGL Docs <https://www.opengl.org/sdk/docs/man2/xhtml/glPopName.xml>`__
|
||||
|
||||
|
||||
.. function:: glPrioritizeTextures(n, textures, priorities):
|
||||
|
||||
Set texture residence priority
|
||||
|
||||
.. seealso:: `OpenGL Docs <https://www.opengl.org/sdk/docs/man2/xhtml/glPrioritizeTextures.xml>`__
|
||||
|
||||
:type n: int
|
||||
:arg n: Specifies the number of textures to be prioritized.
|
||||
:type textures: :class:`bgl.Buffer` I{type GL_INT}
|
||||
:arg textures: Specifies an array containing the names of the textures to be prioritized.
|
||||
:type priorities: :class:`bgl.Buffer` I{type GL_FLOAT}
|
||||
:arg priorities: Specifies an array containing the texture priorities.
|
||||
A priority given in an element of priorities applies to the texture named
|
||||
by the corresponding element of textures.
|
||||
|
||||
|
||||
.. function:: glPushAttrib(mask):
|
||||
|
||||
Push the server attribute stack
|
||||
|
||||
.. seealso:: `OpenGL Docs <https://www.opengl.org/sdk/docs/man2/xhtml/glPushAttrib.xml>`__
|
||||
|
||||
:type mask: Enumerated constant(s)
|
||||
:arg mask: Specifies a mask that indicates which attributes to save.
|
||||
|
||||
|
||||
.. function:: glPushClientAttrib(mask):
|
||||
|
||||
Push the client attribute stack
|
||||
|
||||
.. seealso:: `OpenGL Docs <https://www.opengl.org/sdk/docs/man2/xhtml/glPushClientAttrib.xml>`__
|
||||
|
||||
:type mask: Enumerated constant(s)
|
||||
:arg mask: Specifies a mask that indicates which attributes to save.
|
||||
|
||||
|
||||
.. function:: glPushMatrix():
|
||||
|
||||
Push the current matrix stack
|
||||
|
||||
.. seealso:: `OpenGL Docs <https://www.opengl.org/sdk/docs/man2/xhtml/glPushMatrix.xml>`__
|
||||
|
||||
|
||||
.. function:: glPushName(name):
|
||||
|
||||
Push the name stack
|
||||
|
||||
.. seealso:: `OpenGL Docs <https://www.opengl.org/sdk/docs/man2/xhtml/glPushName.xml>`__
|
||||
|
||||
:type name: unsigned int
|
||||
:arg name: Specifies a name that will be pushed onto the name stack.
|
||||
|
||||
|
||||
.. function:: glRasterPos (x,y,z,w):
|
||||
|
||||
B{glRasterPos2d, glRasterPos2f, glRasterPos2i, glRasterPos2s, glRasterPos3d,
|
||||
@@ -972,6 +1453,16 @@ offers a set of extensive examples, including advanced features.
|
||||
to the opposite vertex of the rectangle
|
||||
|
||||
|
||||
.. function:: glRenderMode(mode):
|
||||
|
||||
Set rasterization mode
|
||||
|
||||
.. seealso:: `OpenGL Docs <https://www.opengl.org/sdk/docs/man2/xhtml/glRenderMode.xml>`__
|
||||
|
||||
:type mode: Enumerated constant
|
||||
:arg mode: Specifies the rasterization mode.
|
||||
|
||||
|
||||
.. function:: glRotate (angle, x, y, z):
|
||||
|
||||
B{glRotated, glRotatef}
|
||||
@@ -1012,6 +1503,28 @@ offers a set of extensive examples, including advanced features.
|
||||
dimensions of that window.
|
||||
|
||||
|
||||
.. function:: glSelectBuffer(size, buffer):
|
||||
|
||||
Establish a buffer for selection mode values
|
||||
|
||||
.. seealso:: `OpenGL Docs <https://www.opengl.org/sdk/docs/man2/xhtml/glSelectBuffer.xml>`__
|
||||
|
||||
:type size: int
|
||||
:arg size: Specifies the size of buffer
|
||||
:type buffer: :class:`bgl.Buffer` I{type GL_INT}
|
||||
:arg buffer: Returns the selection data
|
||||
|
||||
|
||||
.. function:: glShadeModel(mode):
|
||||
|
||||
Select flat or smooth shading
|
||||
|
||||
.. seealso:: `OpenGL Docs <https://www.opengl.org/sdk/docs/man2/xhtml/glShadeModel.xml>`__
|
||||
|
||||
:type mode: Enumerated constant
|
||||
:arg mode: Specifies a symbolic value representing a shading technique.
|
||||
|
||||
|
||||
.. function:: glStencilFunc(func, ref, mask):
|
||||
|
||||
Set function and reference value for stencil testing
|
||||
@@ -1244,6 +1757,99 @@ offers a set of extensive examples, including advanced features.
|
||||
dimensions of that window.
|
||||
|
||||
|
||||
.. function:: gluPerspective(fovY, aspect, zNear, zFar):
|
||||
|
||||
Set up a perspective projection matrix.
|
||||
|
||||
.. seealso:: https://www.opengl.org/sdk/docs/man2/xhtml/gluPerspective.xml
|
||||
|
||||
:type fovY: double
|
||||
:arg fovY: Specifies the field of view angle, in degrees, in the y direction.
|
||||
:type aspect: double
|
||||
:arg aspect: Specifies the aspect ratio that determines the field of view in the x direction.
|
||||
The aspect ratio is the ratio of x (width) to y (height).
|
||||
:type zNear: double
|
||||
:arg zNear: Specifies the distance from the viewer to the near clipping plane (always positive).
|
||||
:type zFar: double
|
||||
:arg zFar: Specifies the distance from the viewer to the far clipping plane (always positive).
|
||||
|
||||
|
||||
.. function:: gluLookAt(eyex, eyey, eyez, centerx, centery, centerz, upx, upy, upz):
|
||||
|
||||
Define a viewing transformation.
|
||||
|
||||
.. seealso:: https://www.opengl.org/sdk/docs/man2/xhtml/gluLookAt.xml
|
||||
|
||||
:type eyex, eyey, eyez: double
|
||||
:arg eyex, eyey, eyez: Specifies the position of the eye point.
|
||||
:type centerx, centery, centerz: double
|
||||
:arg centerx, centery, centerz: Specifies the position of the reference point.
|
||||
:type upx, upy, upz: double
|
||||
:arg upx, upy, upz: Specifies the direction of the up vector.
|
||||
|
||||
|
||||
.. function:: gluOrtho2D(left, right, bottom, top):
|
||||
|
||||
Define a 2-D orthographic projection matrix.
|
||||
|
||||
.. seealso:: https://www.opengl.org/sdk/docs/man2/xhtml/gluOrtho2D.xml
|
||||
|
||||
:type left, right: double
|
||||
:arg left, right: Specify the coordinates for the left and right vertical clipping planes.
|
||||
:type bottom, top: double
|
||||
:arg bottom, top: Specify the coordinates for the bottom and top horizontal clipping planes.
|
||||
|
||||
|
||||
.. function:: gluPickMatrix(x, y, width, height, viewport):
|
||||
|
||||
Define a picking region.
|
||||
|
||||
.. seealso:: https://www.opengl.org/sdk/docs/man2/xhtml/gluPickMatrix.xml
|
||||
|
||||
:type x, y: double
|
||||
:arg x, y: Specify the center of a picking region in window coordinates.
|
||||
:type width, height: double
|
||||
:arg width, height: Specify the width and height, respectively, of the picking region in window coordinates.
|
||||
:type viewport: :class:`bgl.Buffer` object. [int]
|
||||
:arg viewport: Specifies the current viewport.
|
||||
|
||||
|
||||
.. function:: gluProject(objx, objy, objz, modelMatrix, projMatrix, viewport, winx, winy, winz):
|
||||
|
||||
Map object coordinates to window coordinates.
|
||||
|
||||
.. seealso:: https://www.opengl.org/sdk/docs/man2/xhtml/gluProject.xml
|
||||
|
||||
:type objx, objy, objz: double
|
||||
:arg objx, objy, objz: Specify the object coordinates.
|
||||
:type modelMatrix: :class:`bgl.Buffer` object. [double]
|
||||
:arg modelMatrix: Specifies the current modelview matrix (as from a glGetDoublev call).
|
||||
:type projMatrix: :class:`bgl.Buffer` object. [double]
|
||||
:arg projMatrix: Specifies the current projection matrix (as from a glGetDoublev call).
|
||||
:type viewport: :class:`bgl.Buffer` object. [int]
|
||||
:arg viewport: Specifies the current viewport (as from a glGetIntegerv call).
|
||||
:type winx, winy, winz: :class:`bgl.Buffer` object. [double]
|
||||
:arg winx, winy, winz: Return the computed window coordinates.
|
||||
|
||||
|
||||
.. function:: gluUnProject(winx, winy, winz, modelMatrix, projMatrix, viewport, objx, objy, objz):
|
||||
|
||||
Map object coordinates to window coordinates.
|
||||
|
||||
.. seealso:: https://www.opengl.org/sdk/docs/man2/xhtml/gluUnProject.xml
|
||||
|
||||
:type winx, winy, winz: double
|
||||
:arg winx, winy, winz: Specify the window coordinates to be mapped.
|
||||
:type modelMatrix: :class:`bgl.Buffer` object. [double]
|
||||
:arg modelMatrix: Specifies the current modelview matrix (as from a glGetDoublev call).
|
||||
:type projMatrix: :class:`bgl.Buffer` object. [double]
|
||||
:arg projMatrix: Specifies the current projection matrix (as from a glGetDoublev call).
|
||||
:type viewport: :class:`bgl.Buffer` object. [int]
|
||||
:arg viewport: Specifies the current viewport (as from a glGetIntegerv call).
|
||||
:type objx, objy, objz: :class:`bgl.Buffer` object. [double]
|
||||
:arg objx, objy, objz: Return the computed object coordinates.
|
||||
|
||||
|
||||
.. function:: glUseProgram(program):
|
||||
|
||||
Installs a program object as part of current rendering state
|
||||
|
@@ -633,7 +633,6 @@ Here are some general hints to avoid running into these problems.
|
||||
fetch data from the context each time the script is activated.
|
||||
- Crashes may not happen every time, they may happen more on some configurations/operating-systems.
|
||||
- Be wary of recursive patterns, those are very efficient at hiding the issues described here.
|
||||
- See last sub-section about `Unfortunate Corner Cases`_ for some known breaking exceptions.
|
||||
|
||||
.. note::
|
||||
|
||||
@@ -828,17 +827,6 @@ the next example will still crash.
|
||||
print(vertices) # <- this may crash
|
||||
|
||||
|
||||
Unfortunate Corner Cases
|
||||
------------------------
|
||||
|
||||
Besides all expected cases listed above, there are a few others that should not be
|
||||
an issue but, due to internal implementation details, currently are:
|
||||
|
||||
- ``Object.hide_viewport``, ``Object.hide_select`` and ``Object.hide_render``:
|
||||
Setting any of those booleans will trigger a rebuild of Collection caches, hence breaking
|
||||
any current iteration over ``Collection.all_objects``.
|
||||
|
||||
|
||||
sys.exit
|
||||
========
|
||||
|
||||
|
@@ -1009,8 +1009,7 @@ context_type_map = {
|
||||
"editable_gpencil_strokes": ("GPencilStroke", True),
|
||||
"editable_objects": ("Object", True),
|
||||
"fluid": ("FluidSimulationModifier", False),
|
||||
"gpencil": ("GreasePencil", False),
|
||||
"gpencil_data": ("GreasePencil", False),
|
||||
"gpencil_data": ("GreasePencel", False),
|
||||
"gpencil_data_owner": ("ID", False),
|
||||
"image_paint_object": ("Object", False),
|
||||
"lattice": ("Lattice", False),
|
||||
@@ -1029,7 +1028,6 @@ context_type_map = {
|
||||
"particle_system": ("ParticleSystem", False),
|
||||
"particle_system_editable": ("ParticleSystem", False),
|
||||
"pose_bone": ("PoseBone", False),
|
||||
"pose_object": ("Object", False),
|
||||
"scene": ("Scene", False),
|
||||
"sculpt_object": ("Object", False),
|
||||
"selectable_bases": ("ObjectBase", True),
|
||||
|
4
extern/audaspace/CMakeLists.txt
vendored
4
extern/audaspace/CMakeLists.txt
vendored
@@ -73,8 +73,6 @@ set(SRC
|
||||
src/fx/LoopReader.cpp
|
||||
src/fx/LowpassCalculator.cpp
|
||||
src/fx/Lowpass.cpp
|
||||
src/fx/Modulator.cpp
|
||||
src/fx/ModulatorReader.cpp
|
||||
src/fx/MutableReader.cpp
|
||||
src/fx/MutableSound.cpp
|
||||
src/fx/Pitch.cpp
|
||||
@@ -183,8 +181,6 @@ set(PUBLIC_HDR
|
||||
include/fx/LoopReader.h
|
||||
include/fx/LowpassCalculator.h
|
||||
include/fx/Lowpass.h
|
||||
include/fx/Modulator.h
|
||||
include/fx/ModulatorReader.h
|
||||
include/fx/MutableReader.h
|
||||
include/fx/MutableSound.h
|
||||
include/fx/Pitch.h
|
||||
|
16
extern/audaspace/bindings/C/AUD_Sound.cpp
vendored
16
extern/audaspace/bindings/C/AUD_Sound.cpp
vendored
@@ -32,7 +32,6 @@
|
||||
#include "fx/Limiter.h"
|
||||
#include "fx/Loop.h"
|
||||
#include "fx/Lowpass.h"
|
||||
#include "fx/Modulator.h"
|
||||
#include "fx/Pitch.h"
|
||||
#include "fx/Reverse.h"
|
||||
#include "fx/Sum.h"
|
||||
@@ -466,21 +465,6 @@ AUD_API AUD_Sound* AUD_Sound_lowpass(AUD_Sound* sound, float frequency, float Q)
|
||||
}
|
||||
}
|
||||
|
||||
AUD_API AUD_Sound* AUD_Sound_modulate(AUD_Sound* first, AUD_Sound* second)
|
||||
{
|
||||
assert(first);
|
||||
assert(second);
|
||||
|
||||
try
|
||||
{
|
||||
return new AUD_Sound(new Modulator(*first, *second));
|
||||
}
|
||||
catch(Exception&)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
AUD_API AUD_Sound* AUD_Sound_pitch(AUD_Sound* sound, float factor)
|
||||
{
|
||||
assert(sound);
|
||||
|
8
extern/audaspace/bindings/C/AUD_Sound.h
vendored
8
extern/audaspace/bindings/C/AUD_Sound.h
vendored
@@ -246,14 +246,6 @@ extern AUD_API AUD_Sound* AUD_Sound_loop(AUD_Sound* sound, int count);
|
||||
*/
|
||||
extern AUD_API AUD_Sound* AUD_Sound_lowpass(AUD_Sound* sound, float frequency, float Q);
|
||||
|
||||
/**
|
||||
* Modulates two sound, which means multiplying the sound samples.
|
||||
* \param first The first sound.
|
||||
* \param second The second sound.
|
||||
* \return A handle of the modulated sound.
|
||||
*/
|
||||
extern AUD_API AUD_Sound* AUD_Sound_modulate(AUD_Sound* first, AUD_Sound* second);
|
||||
|
||||
/**
|
||||
* Changes the pitch of a sound.
|
||||
* \param sound The sound to change.
|
||||
|
45
extern/audaspace/bindings/python/PySound.cpp
vendored
45
extern/audaspace/bindings/python/PySound.cpp
vendored
@@ -42,7 +42,6 @@
|
||||
#include "fx/Limiter.h"
|
||||
#include "fx/Loop.h"
|
||||
#include "fx/Lowpass.h"
|
||||
#include "fx/Modulator.h"
|
||||
#include "fx/MutableSound.h"
|
||||
#include "fx/Pitch.h"
|
||||
#include "fx/Reverse.h"
|
||||
@@ -1130,47 +1129,6 @@ Sound_lowpass(Sound* self, PyObject* args)
|
||||
return (PyObject *)parent;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_Sound_modulate_doc,
|
||||
"modulate(sound)\n\n"
|
||||
"Modulates two factories.\n\n"
|
||||
":arg sound: The sound to modulate over the other.\n"
|
||||
":type sound: :class:`Sound`\n"
|
||||
":return: The created :class:`Sound` object.\n"
|
||||
":rtype: :class:`Sound`\n\n"
|
||||
".. note:: The two factories have to have the same specifications "
|
||||
"(channels and samplerate).");
|
||||
|
||||
static PyObject *
|
||||
Sound_modulate(Sound* self, PyObject* object)
|
||||
{
|
||||
PyTypeObject* type = Py_TYPE(self);
|
||||
|
||||
if(!PyObject_TypeCheck(object, type))
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError, "Object is not of type Sound!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Sound* parent = (Sound*)type->tp_alloc(type, 0);
|
||||
Sound* child = (Sound*)object;
|
||||
|
||||
if(parent != nullptr)
|
||||
{
|
||||
try
|
||||
{
|
||||
parent->sound = new std::shared_ptr<ISound>(new Modulator(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound), *reinterpret_cast<std::shared_ptr<ISound>*>(child->sound)));
|
||||
}
|
||||
catch(Exception& e)
|
||||
{
|
||||
Py_DECREF(parent);
|
||||
PyErr_SetString(AUDError, e.what());
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return (PyObject *)parent;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(M_aud_Sound_pitch_doc,
|
||||
"pitch(factor)\n\n"
|
||||
"Changes the pitch of a sound with a specific factor.\n\n"
|
||||
@@ -1833,9 +1791,6 @@ static PyMethodDef Sound_methods[] = {
|
||||
{"lowpass", (PyCFunction)Sound_lowpass, METH_VARARGS,
|
||||
M_aud_Sound_lowpass_doc
|
||||
},
|
||||
{"modulate", (PyCFunction)Sound_modulate, METH_O,
|
||||
M_aud_Sound_modulate_doc
|
||||
},
|
||||
{"pitch", (PyCFunction)Sound_pitch, METH_VARARGS,
|
||||
M_aud_Sound_pitch_doc
|
||||
},
|
||||
|
62
extern/audaspace/include/fx/Modulator.h
vendored
62
extern/audaspace/include/fx/Modulator.h
vendored
@@ -1,62 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright 2009-2016 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 Modulator.h
|
||||
* @ingroup fx
|
||||
* The Modulator class.
|
||||
*/
|
||||
|
||||
#include "ISound.h"
|
||||
|
||||
AUD_NAMESPACE_BEGIN
|
||||
|
||||
/**
|
||||
* This sound plays two other factories, playing them the same time and modulating/multiplying them.
|
||||
* \note Readers from the underlying factories must have the same sample rate
|
||||
* and channel count.
|
||||
*/
|
||||
class AUD_API Modulator : public ISound
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* First played sound.
|
||||
*/
|
||||
std::shared_ptr<ISound> m_sound1;
|
||||
|
||||
/**
|
||||
* Second played sound.
|
||||
*/
|
||||
std::shared_ptr<ISound> m_sound2;
|
||||
|
||||
// delete copy constructor and operator=
|
||||
Modulator(const Modulator&) = delete;
|
||||
Modulator& operator=(const Modulator&) = delete;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a new modulator sound.
|
||||
* \param sound1 The first input sound.
|
||||
* \param sound2 The second input sound.
|
||||
*/
|
||||
Modulator(std::shared_ptr<ISound> sound1, std::shared_ptr<ISound> sound2);
|
||||
|
||||
virtual std::shared_ptr<IReader> createReader();
|
||||
};
|
||||
|
||||
AUD_NAMESPACE_END
|
79
extern/audaspace/include/fx/ModulatorReader.h
vendored
79
extern/audaspace/include/fx/ModulatorReader.h
vendored
@@ -1,79 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright 2009-2016 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 ModulatorReader.h
|
||||
* @ingroup fx
|
||||
* The ModulatorReader class.
|
||||
*/
|
||||
|
||||
#include "IReader.h"
|
||||
#include "util/Buffer.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
AUD_NAMESPACE_BEGIN
|
||||
|
||||
/**
|
||||
* This reader plays two readers with the same specs in parallel multiplying their samples.
|
||||
*/
|
||||
class AUD_API ModulatorReader : public IReader
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* The first reader.
|
||||
*/
|
||||
std::shared_ptr<IReader> m_reader1;
|
||||
|
||||
/**
|
||||
* The second reader.
|
||||
*/
|
||||
std::shared_ptr<IReader> m_reader2;
|
||||
|
||||
/**
|
||||
* Buffer used for mixing.
|
||||
*/
|
||||
Buffer m_buffer;
|
||||
|
||||
// delete copy constructor and operator=
|
||||
ModulatorReader(const ModulatorReader&) = delete;
|
||||
ModulatorReader& operator=(const ModulatorReader&) = delete;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a new modulator reader.
|
||||
* \param reader1 The first reader to read from.
|
||||
* \param reader2 The second reader to read from.
|
||||
* \exception Exception Thrown if the specs from the readers differ.
|
||||
*/
|
||||
ModulatorReader(std::shared_ptr<IReader> reader1, std::shared_ptr<IReader> reader2);
|
||||
|
||||
/**
|
||||
* Destroys the reader.
|
||||
*/
|
||||
virtual ~ModulatorReader();
|
||||
|
||||
virtual bool isSeekable() const;
|
||||
virtual void seek(int position);
|
||||
virtual int getLength() const;
|
||||
virtual int getPosition() const;
|
||||
virtual Specs getSpecs() const;
|
||||
virtual void read(int& length, bool& eos, sample_t* buffer);
|
||||
};
|
||||
|
||||
AUD_NAMESPACE_END
|
@@ -35,12 +35,7 @@ void DeviceManager::registerDevice(std::string name, std::shared_ptr<IDeviceFact
|
||||
|
||||
std::shared_ptr<IDeviceFactory> DeviceManager::getDeviceFactory(std::string name)
|
||||
{
|
||||
auto it = m_factories.find(name);
|
||||
|
||||
if(it == m_factories.end())
|
||||
return nullptr;
|
||||
|
||||
return it->second;
|
||||
return m_factories[name];
|
||||
}
|
||||
|
||||
std::shared_ptr<IDeviceFactory> DeviceManager::getDefaultDeviceFactory()
|
||||
|
35
extern/audaspace/src/fx/Modulator.cpp
vendored
35
extern/audaspace/src/fx/Modulator.cpp
vendored
@@ -1,35 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright 2009-2016 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 "fx/Modulator.h"
|
||||
#include "fx/ModulatorReader.h"
|
||||
|
||||
AUD_NAMESPACE_BEGIN
|
||||
|
||||
Modulator::Modulator(std::shared_ptr<ISound> sound1, std::shared_ptr<ISound> sound2) :
|
||||
m_sound1(sound1), m_sound2(sound2)
|
||||
{
|
||||
}
|
||||
|
||||
std::shared_ptr<IReader> Modulator::createReader()
|
||||
{
|
||||
std::shared_ptr<IReader> reader1 = m_sound1->createReader();
|
||||
std::shared_ptr<IReader> reader2 = m_sound2->createReader();
|
||||
|
||||
return std::shared_ptr<IReader>(new ModulatorReader(reader1, reader2));
|
||||
}
|
||||
|
||||
AUD_NAMESPACE_END
|
95
extern/audaspace/src/fx/ModulatorReader.cpp
vendored
95
extern/audaspace/src/fx/ModulatorReader.cpp
vendored
@@ -1,95 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright 2009-2016 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 "fx/ModulatorReader.h"
|
||||
#include "Exception.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
|
||||
AUD_NAMESPACE_BEGIN
|
||||
|
||||
ModulatorReader::ModulatorReader(std::shared_ptr<IReader> reader1, std::shared_ptr<IReader> reader2) :
|
||||
m_reader1(reader1), m_reader2(reader2)
|
||||
{
|
||||
}
|
||||
|
||||
ModulatorReader::~ModulatorReader()
|
||||
{
|
||||
}
|
||||
|
||||
bool ModulatorReader::isSeekable() const
|
||||
{
|
||||
return m_reader1->isSeekable() && m_reader2->isSeekable();
|
||||
}
|
||||
|
||||
void ModulatorReader::seek(int position)
|
||||
{
|
||||
m_reader1->seek(position);
|
||||
m_reader2->seek(position);
|
||||
}
|
||||
|
||||
int ModulatorReader::getLength() const
|
||||
{
|
||||
int len1 = m_reader1->getLength();
|
||||
int len2 = m_reader2->getLength();
|
||||
if((len1 < 0) || (len2 < 0))
|
||||
return -1;
|
||||
return std::min(len1, len2);
|
||||
}
|
||||
|
||||
int ModulatorReader::getPosition() const
|
||||
{
|
||||
int pos1 = m_reader1->getPosition();
|
||||
int pos2 = m_reader2->getPosition();
|
||||
return std::max(pos1, pos2);
|
||||
}
|
||||
|
||||
Specs ModulatorReader::getSpecs() const
|
||||
{
|
||||
return m_reader1->getSpecs();
|
||||
}
|
||||
|
||||
void ModulatorReader::read(int& length, bool& eos, sample_t* buffer)
|
||||
{
|
||||
Specs specs = m_reader1->getSpecs();
|
||||
Specs s2 = m_reader2->getSpecs();
|
||||
if(!AUD_COMPARE_SPECS(specs, s2))
|
||||
AUD_THROW(StateException, "Two readers with different specifiactions cannot be modulated.");
|
||||
|
||||
int samplesize = AUD_SAMPLE_SIZE(specs);
|
||||
|
||||
m_buffer.assureSize(length * samplesize);
|
||||
|
||||
int len1 = length;
|
||||
m_reader1->read(len1, eos, buffer);
|
||||
|
||||
if(len1 < length)
|
||||
std::memset(buffer + len1 * specs.channels, 0, (length - len1) * samplesize);
|
||||
|
||||
int len2 = length;
|
||||
bool eos2;
|
||||
sample_t* buf = m_buffer.getBuffer();
|
||||
m_reader2->read(len2, eos2, buf);
|
||||
|
||||
for(int i = 0; i < len2 * specs.channels; i++)
|
||||
buffer[i] *= buf[i];
|
||||
|
||||
length = std::max(len1, len2);
|
||||
eos &= eos2;
|
||||
}
|
||||
|
||||
AUD_NAMESPACE_END
|
@@ -66,11 +66,6 @@ static PyMethodDef meth_sound_from_pointer[] = {
|
||||
PyObject *AUD_initPython(void)
|
||||
{
|
||||
PyObject *module = PyInit_aud();
|
||||
if (module == NULL) {
|
||||
printf("Unable to initialise audio\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PyModule_AddObject(module, "_sound_from_pointer", (PyObject *)PyCFunction_New(meth_sound_from_pointer, NULL));
|
||||
PyDict_SetItemString(PyImport_GetModuleDict(), "aud", module);
|
||||
|
||||
|
@@ -301,8 +301,6 @@ if(WITH_CYCLES_CUDA_BINARIES AND (NOT WITH_CYCLES_CUBIN_COMPILER))
|
||||
set(MAX_MSVC 1911)
|
||||
elseif(${CUDA_VERSION} EQUAL "10.0")
|
||||
set(MAX_MSVC 1999)
|
||||
elseif(${CUDA_VERSION} EQUAL "10.1")
|
||||
set(MAX_MSVC 1999)
|
||||
endif()
|
||||
if(NOT MSVC_VERSION LESS ${MAX_MSVC} OR CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
message(STATUS "nvcc not supported for this compiler version, using cycles_cubin_cc instead.")
|
||||
|
@@ -58,8 +58,7 @@ link_directories(${OPENIMAGEIO_LIBPATH}
|
||||
${JPEG_LIBPATH}
|
||||
${ZLIB_LIBPATH}
|
||||
${TIFF_LIBPATH}
|
||||
${OPENEXR_LIBPATH}
|
||||
${OPENJPEG_LIBPATH})
|
||||
${OPENEXR_LIBPATH})
|
||||
|
||||
if(WITH_OPENCOLORIO)
|
||||
link_directories(${OPENCOLORIO_LIBPATH})
|
||||
@@ -95,7 +94,6 @@ macro(cycles_target_link_libraries target)
|
||||
${target}
|
||||
${OPENIMAGEIO_LIBRARIES}
|
||||
${OPENEXR_LIBRARIES}
|
||||
${OPENJPEG_LIBRARIES}
|
||||
${PUGIXML_LIBRARIES}
|
||||
${BOOST_LIBRARIES}
|
||||
${CMAKE_DL_LIBS}
|
||||
@@ -153,7 +151,6 @@ if(WITH_CYCLES_CUBIN_COMPILER)
|
||||
extern_cuew
|
||||
${OPENIMAGEIO_LIBRARIES}
|
||||
${OPENEXR_LIBRARIES}
|
||||
${OPENJPEG_LIBRARIES}
|
||||
${PUGIXML_LIBRARIES}
|
||||
${BOOST_LIBRARIES}
|
||||
${PLATFORM_LINKLIBS}
|
||||
|
@@ -442,7 +442,7 @@ static void xml_read_mesh(const XMLReadState& state, xml_node node)
|
||||
if(xml_read_float_array(UV, node, "UV")) {
|
||||
ustring name = ustring("UVMap");
|
||||
Attribute *attr = mesh->attributes.add(ATTR_STD_UV, name);
|
||||
float2 *fdata = attr->data_float2();
|
||||
float3 *fdata = attr->data_float3();
|
||||
|
||||
/* loop over the triangles */
|
||||
index_offset = 0;
|
||||
@@ -456,9 +456,9 @@ static void xml_read_mesh(const XMLReadState& state, xml_node node)
|
||||
assert(v1*2+1 < (int)UV.size());
|
||||
assert(v2*2+1 < (int)UV.size());
|
||||
|
||||
fdata[0] = make_float2(UV[v0*2], UV[v0*2+1]);
|
||||
fdata[1] = make_float2(UV[v1*2], UV[v1*2+1]);
|
||||
fdata[2] = make_float2(UV[v2*2], UV[v2*2+1]);
|
||||
fdata[0] = make_float3(UV[v0*2], UV[v0*2+1], 0.0);
|
||||
fdata[1] = make_float3(UV[v1*2], UV[v1*2+1], 0.0);
|
||||
fdata[2] = make_float3(UV[v2*2], UV[v2*2+1], 0.0);
|
||||
fdata += 3;
|
||||
}
|
||||
|
||||
@@ -516,6 +516,8 @@ static void xml_read_mesh(const XMLReadState& state, xml_node node)
|
||||
xml_read_float(&sdparams.dicing_rate, node, "dicing_rate");
|
||||
sdparams.dicing_rate = std::max(0.1f, sdparams.dicing_rate);
|
||||
|
||||
state.scene->camera->update(state.scene);
|
||||
sdparams.camera = state.scene->camera;
|
||||
sdparams.objecttoworld = state.tfm;
|
||||
}
|
||||
|
||||
|
@@ -16,6 +16,7 @@
|
||||
|
||||
# XML exporter for generating test files, not intended for end users
|
||||
|
||||
import os
|
||||
import xml.etree.ElementTree as etree
|
||||
import xml.dom.minidom as dom
|
||||
|
||||
|
@@ -124,48 +124,9 @@ class CYCLES_OT_denoise_animation(Operator):
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class CYCLES_OT_merge_images(Operator):
|
||||
"Combine OpenEXR multilayer images rendered with different sample" \
|
||||
"ranges into one image with reduced noise"
|
||||
bl_idname = "cycles.merge_images"
|
||||
bl_label = "Merge Images"
|
||||
|
||||
input_filepath1: StringProperty(
|
||||
name='Input Filepath',
|
||||
description='File path for image to merge',
|
||||
default='',
|
||||
subtype='FILE_PATH')
|
||||
|
||||
input_filepath2: StringProperty(
|
||||
name='Input Filepath',
|
||||
description='File path for image to merge',
|
||||
default='',
|
||||
subtype='FILE_PATH')
|
||||
|
||||
output_filepath: StringProperty(
|
||||
name='Output Filepath',
|
||||
description='File path for merged image',
|
||||
default='',
|
||||
subtype='FILE_PATH')
|
||||
|
||||
def execute(self, context):
|
||||
in_filepaths = [self.input_filepath1, self.input_filepath2]
|
||||
out_filepath = self.output_filepath
|
||||
|
||||
import _cycles
|
||||
try:
|
||||
_cycles.merge(input=in_filepaths, output=out_filepath)
|
||||
except Exception as e:
|
||||
self.report({'ERROR'}, str(e))
|
||||
return {'FINISHED'}
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
classes = (
|
||||
CYCLES_OT_use_shading_nodes,
|
||||
CYCLES_OT_denoise_animation,
|
||||
CYCLES_OT_merge_images
|
||||
CYCLES_OT_denoise_animation
|
||||
)
|
||||
|
||||
def register():
|
||||
|
@@ -192,13 +192,13 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
|
||||
samples: IntProperty(
|
||||
name="Samples",
|
||||
description="Number of samples to render for each pixel",
|
||||
min=1, max=(1 << 24),
|
||||
min=1, max=2147483647,
|
||||
default=128,
|
||||
)
|
||||
preview_samples: IntProperty(
|
||||
name="Preview Samples",
|
||||
description="Number of samples to render in the viewport, unlimited if 0",
|
||||
min=0, max=(1 << 24),
|
||||
min=0, max=2147483647,
|
||||
default=32,
|
||||
)
|
||||
preview_pause: BoolProperty(
|
||||
@@ -722,6 +722,11 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
|
||||
update=_devices_update_callback
|
||||
)
|
||||
|
||||
debug_opencl_kernel_single_program: BoolProperty(
|
||||
name="Single Program",
|
||||
default=False,
|
||||
update=_devices_update_callback,
|
||||
)
|
||||
del _devices_update_callback
|
||||
|
||||
debug_use_opencl_debug: BoolProperty(name="Debug OpenCL", default=False)
|
||||
@@ -1453,11 +1458,10 @@ class CyclesPreferences(bpy.types.AddonPreferences):
|
||||
# Update name in case it changed
|
||||
entry.name = device[0]
|
||||
|
||||
# Gets all devices types by default.
|
||||
def get_devices(self, compute_device_type=''):
|
||||
def get_devices(self):
|
||||
import _cycles
|
||||
# Layout of the device tuples: (Name, Type, Persistent ID)
|
||||
device_list = _cycles.available_devices(compute_device_type)
|
||||
device_list = _cycles.available_devices(self.compute_device_type)
|
||||
# Make sure device entries are up to date and not referenced before
|
||||
# we know we don't add new devices. This way we guarantee to not
|
||||
# hold pointers to a resized array.
|
||||
@@ -1514,7 +1518,7 @@ class CyclesPreferences(bpy.types.AddonPreferences):
|
||||
row = layout.row()
|
||||
row.prop(self, "compute_device_type", expand=True)
|
||||
|
||||
cuda_devices, opencl_devices = self.get_devices(self.compute_device_type)
|
||||
cuda_devices, opencl_devices = self.get_devices()
|
||||
row = layout.row()
|
||||
if self.compute_device_type == 'CUDA':
|
||||
self._draw_devices(row, 'CUDA', cuda_devices)
|
||||
|
@@ -18,12 +18,12 @@
|
||||
|
||||
import bpy
|
||||
from bpy_extras.node_utils import find_node_input
|
||||
from bl_ui.utils import PresetPanel
|
||||
from bl_operators.presets import PresetMenu
|
||||
|
||||
from bpy.types import Panel
|
||||
|
||||
|
||||
class CYCLES_PT_sampling_presets(PresetPanel, Panel):
|
||||
class CYCLES_PT_sampling_presets(PresetMenu):
|
||||
bl_label = "Sampling Presets"
|
||||
preset_subdir = "cycles/sampling"
|
||||
preset_operator = "script.execute_preset"
|
||||
@@ -31,7 +31,7 @@ class CYCLES_PT_sampling_presets(PresetPanel, Panel):
|
||||
COMPAT_ENGINES = {'CYCLES'}
|
||||
|
||||
|
||||
class CYCLES_PT_integrator_presets(PresetPanel, Panel):
|
||||
class CYCLES_PT_integrator_presets(PresetMenu):
|
||||
bl_label = "Integrator Presets"
|
||||
preset_subdir = "cycles/integrator"
|
||||
preset_operator = "script.execute_preset"
|
||||
@@ -50,18 +50,14 @@ class CyclesButtonsPanel:
|
||||
return context.engine in cls.COMPAT_ENGINES
|
||||
|
||||
|
||||
# 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):
|
||||
node_cls = type('NODE_' + cls.__name__, cls.__bases__, dict(cls.__dict__))
|
||||
class CyclesNodeButtonsPanel:
|
||||
bl_space_type = "NODE_EDITOR"
|
||||
bl_region_type = "UI"
|
||||
COMPAT_ENGINES = {'CYCLES'}
|
||||
|
||||
node_cls.bl_space_type = 'NODE_EDITOR'
|
||||
node_cls.bl_region_type = 'UI'
|
||||
node_cls.bl_category = "Node"
|
||||
if hasattr(node_cls, 'bl_parent_id'):
|
||||
node_cls.bl_parent_id = 'NODE_' + node_cls.bl_parent_id
|
||||
|
||||
return node_cls
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return context.engine in cls.COMPAT_ENGINES
|
||||
|
||||
|
||||
def get_device_type(context):
|
||||
@@ -313,7 +309,7 @@ class CYCLES_RENDER_PT_subdivision(CyclesButtonsPanel, Panel):
|
||||
|
||||
@classmethod
|
||||
def poll(self, context):
|
||||
return (context.scene.render.engine == 'CYCLES') and (context.scene.cycles.feature_set == 'EXPERIMENTAL')
|
||||
return context.scene.cycles.feature_set == 'EXPERIMENTAL'
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -1119,7 +1115,7 @@ class CYCLES_PT_context_material(CyclesButtonsPanel, Panel):
|
||||
col.operator("object.material_slot_add", icon='ADD', text="")
|
||||
col.operator("object.material_slot_remove", icon='REMOVE', text="")
|
||||
|
||||
col.menu("MATERIAL_MT_context_menu", icon='DOWNARROW_HLT', text="")
|
||||
col.menu("MATERIAL_MT_specials", icon='DOWNARROW_HLT', text="")
|
||||
|
||||
if is_sortable:
|
||||
col.separator()
|
||||
@@ -1332,16 +1328,13 @@ class CYCLES_LIGHT_PT_light(CyclesButtonsPanel, Panel):
|
||||
|
||||
light = context.light
|
||||
clamp = light.cycles
|
||||
# cscene = context.scene.cycles
|
||||
|
||||
layout.prop(light, "type", expand=True)
|
||||
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
||||
|
||||
if self.bl_space_type == 'PROPERTIES':
|
||||
layout.row().prop(light, "type", expand=True)
|
||||
layout.use_property_split = True
|
||||
else:
|
||||
layout.use_property_split = True
|
||||
layout.row().prop(light, "type")
|
||||
|
||||
col = layout.column()
|
||||
|
||||
if light.type in {'POINT', 'SUN', 'SPOT'}:
|
||||
@@ -1620,8 +1613,7 @@ class CYCLES_MATERIAL_PT_preview(CyclesButtonsPanel, Panel):
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
mat = context.material
|
||||
return mat and (not mat.grease_pencil) and CyclesButtonsPanel.poll(context)
|
||||
return context.material and CyclesButtonsPanel.poll(context)
|
||||
|
||||
def draw(self, context):
|
||||
self.layout.template_preview(context.material)
|
||||
@@ -1633,8 +1625,7 @@ class CYCLES_MATERIAL_PT_surface(CyclesButtonsPanel, Panel):
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
mat = context.material
|
||||
return mat and (not mat.grease_pencil) and CyclesButtonsPanel.poll(context)
|
||||
return context.material and CyclesButtonsPanel.poll(context)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -1652,7 +1643,7 @@ class CYCLES_MATERIAL_PT_volume(CyclesButtonsPanel, Panel):
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
mat = context.material
|
||||
return mat and (not mat.grease_pencil) and mat.node_tree and CyclesButtonsPanel.poll(context)
|
||||
return mat and mat.node_tree and CyclesButtonsPanel.poll(context)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -1670,7 +1661,7 @@ class CYCLES_MATERIAL_PT_displacement(CyclesButtonsPanel, Panel):
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
mat = context.material
|
||||
return mat and (not mat.grease_pencil) and mat.node_tree and CyclesButtonsPanel.poll(context)
|
||||
return mat and mat.node_tree and CyclesButtonsPanel.poll(context)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -1686,8 +1677,7 @@ class CYCLES_MATERIAL_PT_settings(CyclesButtonsPanel, Panel):
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
mat = context.material
|
||||
return mat and (not mat.grease_pencil) and CyclesButtonsPanel.poll(context)
|
||||
return context.material and CyclesButtonsPanel.poll(context)
|
||||
|
||||
@staticmethod
|
||||
def draw_shared(self, mat):
|
||||
@@ -1939,6 +1929,7 @@ class CYCLES_RENDER_PT_debug(CyclesButtonsPanel, Panel):
|
||||
col = layout.column()
|
||||
col.label(text='OpenCL Flags:')
|
||||
col.prop(cscene, "debug_opencl_device_type", text="Device")
|
||||
col.prop(cscene, "debug_opencl_kernel_single_program", text="Single Program")
|
||||
col.prop(cscene, "debug_use_opencl_debug", text="Debug")
|
||||
col.prop(cscene, "debug_opencl_mem_limit")
|
||||
|
||||
@@ -2042,6 +2033,43 @@ class CYCLES_RENDER_PT_simplify_culling(CyclesButtonsPanel, Panel):
|
||||
sub.prop(cscene, "distance_cull_margin", text="Distance")
|
||||
|
||||
|
||||
class CYCLES_NODE_PT_settings(CyclesNodeButtonsPanel, Panel):
|
||||
bl_label = "Settings"
|
||||
bl_category = "Node"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
snode = context.space_data
|
||||
return CyclesNodeButtonsPanel.poll(context) and \
|
||||
snode.tree_type == 'ShaderNodeTree' and snode.id and \
|
||||
snode.id.bl_rna.identifier == 'Material'
|
||||
|
||||
def draw(self, context):
|
||||
material = context.space_data.id
|
||||
CYCLES_MATERIAL_PT_settings.draw_shared(self, material)
|
||||
|
||||
|
||||
class CYCLES_NODE_PT_settings_surface(CyclesNodeButtonsPanel, Panel):
|
||||
bl_label = "Surface"
|
||||
bl_category = "Node"
|
||||
bl_parent_id = "CYCLES_NODE_PT_settings"
|
||||
|
||||
def draw(self, context):
|
||||
material = context.space_data.id
|
||||
CYCLES_MATERIAL_PT_settings_surface.draw_shared(self, material)
|
||||
|
||||
|
||||
class CYCLES_NODE_PT_settings_volume(CyclesNodeButtonsPanel, Panel):
|
||||
bl_label = "Volume"
|
||||
bl_category = "Node"
|
||||
bl_parent_id = "CYCLES_NODE_PT_settings"
|
||||
|
||||
def draw(self, context):
|
||||
material = context.space_data.id
|
||||
CYCLES_MATERIAL_PT_settings_volume.draw_shared(self, context, material)
|
||||
|
||||
|
||||
def draw_device(self, context):
|
||||
scene = context.scene
|
||||
layout = self.layout
|
||||
@@ -2088,8 +2116,6 @@ def get_panels():
|
||||
'DATA_PT_spot',
|
||||
'MATERIAL_PT_context_material',
|
||||
'MATERIAL_PT_preview',
|
||||
'NODE_DATA_PT_light',
|
||||
'NODE_DATA_PT_spot',
|
||||
'VIEWLAYER_PT_filter',
|
||||
'VIEWLAYER_PT_layer_passes',
|
||||
'RENDER_PT_post_processing',
|
||||
@@ -2175,15 +2201,9 @@ classes = (
|
||||
CYCLES_RENDER_PT_bake_selected_to_active,
|
||||
CYCLES_RENDER_PT_bake_output,
|
||||
CYCLES_RENDER_PT_debug,
|
||||
node_panel(CYCLES_MATERIAL_PT_settings),
|
||||
node_panel(CYCLES_MATERIAL_PT_settings_surface),
|
||||
node_panel(CYCLES_MATERIAL_PT_settings_volume),
|
||||
node_panel(CYCLES_WORLD_PT_ray_visibility),
|
||||
node_panel(CYCLES_WORLD_PT_settings),
|
||||
node_panel(CYCLES_WORLD_PT_settings_surface),
|
||||
node_panel(CYCLES_WORLD_PT_settings_volume),
|
||||
node_panel(CYCLES_LIGHT_PT_light),
|
||||
node_panel(CYCLES_LIGHT_PT_spot),
|
||||
CYCLES_NODE_PT_settings,
|
||||
CYCLES_NODE_PT_settings_surface,
|
||||
CYCLES_NODE_PT_settings_volume,
|
||||
)
|
||||
|
||||
|
||||
|
@@ -253,7 +253,7 @@ def do_versions(self):
|
||||
pass
|
||||
|
||||
# Init device list for UI
|
||||
prop.get_devices(prop.compute_device_type)
|
||||
prop.get_devices()
|
||||
|
||||
# We don't modify startup file because it assumes to
|
||||
# have all the default values only.
|
||||
@@ -267,7 +267,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 = (2, 80, 41)
|
||||
max_need_versioning = (2, 79, 6)
|
||||
for version, libraries in library_versions.items():
|
||||
if version > max_need_versioning:
|
||||
continue
|
||||
|
@@ -250,7 +250,7 @@ static bool ObtainCacheParticleUV(Mesh *mesh,
|
||||
BL::Mesh::uv_layers_iterator l;
|
||||
b_mesh->uv_layers.begin(l);
|
||||
|
||||
float2 uv = make_float2(0.0f, 0.0f);
|
||||
float3 uv = make_float3(0.0f, 0.0f, 0.0f);
|
||||
if(b_mesh->uv_layers.length())
|
||||
b_psys.uv_on_emitter(psmd, *b_pa, pa_no, uv_num, &uv.x);
|
||||
CData->curve_uv.push_back_slow(uv);
|
||||
@@ -752,29 +752,45 @@ static void ExportCurveSegmentsMotion(Mesh *mesh, ParticleCurveData *CData, int
|
||||
static void ExportCurveTriangleUV(ParticleCurveData *CData,
|
||||
int vert_offset,
|
||||
int resol,
|
||||
float2 *uvdata)
|
||||
float3 *uvdata)
|
||||
{
|
||||
if(uvdata == NULL)
|
||||
return;
|
||||
|
||||
float time = 0.0f;
|
||||
float prevtime = 0.0f;
|
||||
|
||||
int vertexindex = vert_offset;
|
||||
|
||||
for(int sys = 0; sys < CData->psys_firstcurve.size(); sys++) {
|
||||
for(int curve = CData->psys_firstcurve[sys]; curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys]; curve++) {
|
||||
for(int curvekey = CData->curve_firstkey[curve]; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve] - 1; curvekey++) {
|
||||
const float curve_time = CData->curvekey_time[curvekey];
|
||||
const float curve_length = CData->curve_length[curve];
|
||||
time = (curve_length > 0.0f) ? curve_time / curve_length : 0.0f;
|
||||
|
||||
for(int section = 0; section < resol; section++) {
|
||||
uvdata[vertexindex] = CData->curve_uv[curve];
|
||||
uvdata[vertexindex].z = prevtime;
|
||||
vertexindex++;
|
||||
uvdata[vertexindex] = CData->curve_uv[curve];
|
||||
uvdata[vertexindex].z = time;
|
||||
vertexindex++;
|
||||
uvdata[vertexindex] = CData->curve_uv[curve];
|
||||
uvdata[vertexindex].z = prevtime;
|
||||
vertexindex++;
|
||||
uvdata[vertexindex] = CData->curve_uv[curve];
|
||||
uvdata[vertexindex].z = time;
|
||||
vertexindex++;
|
||||
uvdata[vertexindex] = CData->curve_uv[curve];
|
||||
uvdata[vertexindex].z = prevtime;
|
||||
vertexindex++;
|
||||
uvdata[vertexindex] = CData->curve_uv[curve];
|
||||
uvdata[vertexindex].z = time;
|
||||
vertexindex++;
|
||||
}
|
||||
|
||||
prevtime = time;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1047,9 +1063,9 @@ void BlenderSync::sync_curves(Mesh *mesh,
|
||||
if(active_render)
|
||||
attr_uv = mesh->attributes.add(std, name);
|
||||
else
|
||||
attr_uv = mesh->attributes.add(name, TypeFloat2, ATTR_ELEMENT_CORNER);
|
||||
attr_uv = mesh->attributes.add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CORNER);
|
||||
|
||||
float2 *uv = attr_uv->data_float2();
|
||||
float3 *uv = attr_uv->data_float3();
|
||||
|
||||
ExportCurveTriangleUV(&CData, tri_num * 3, used_res, uv);
|
||||
}
|
||||
@@ -1057,9 +1073,9 @@ void BlenderSync::sync_curves(Mesh *mesh,
|
||||
if(active_render)
|
||||
attr_uv = mesh->curve_attributes.add(std, name);
|
||||
else
|
||||
attr_uv = mesh->curve_attributes.add(name, TypeFloat2, ATTR_ELEMENT_CURVE);
|
||||
attr_uv = mesh->curve_attributes.add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CURVE);
|
||||
|
||||
float2 *uv = attr_uv->data_float2();
|
||||
float3 *uv = attr_uv->data_float3();
|
||||
|
||||
if(uv) {
|
||||
size_t i = 0;
|
||||
|
@@ -66,7 +66,7 @@ struct MikkUserData {
|
||||
else {
|
||||
Attribute *attr_uv = attributes.find(ustring(layer_name));
|
||||
if(attr_uv != NULL) {
|
||||
texface = attr_uv->data_float2();
|
||||
texface = attr_uv->data_float3();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -75,7 +75,7 @@ struct MikkUserData {
|
||||
int num_faces;
|
||||
|
||||
float3 *vertex_normal;
|
||||
float2 *texface;
|
||||
float3 *texface;
|
||||
float3 *orco;
|
||||
float3 orco_loc, orco_size;
|
||||
|
||||
@@ -150,7 +150,7 @@ static void mikk_get_texture_coordinate(const SMikkTSpaceContext *context,
|
||||
const Mesh *mesh = userdata->mesh;
|
||||
if(userdata->texface != NULL) {
|
||||
const int corner_index = mikk_corner_index(mesh, face_num, vert_num);
|
||||
float2 tfuv = userdata->texface[corner_index];
|
||||
float3 tfuv = userdata->texface[corner_index];
|
||||
uv[0] = tfuv.x;
|
||||
uv[1] = tfuv.y;
|
||||
}
|
||||
@@ -430,18 +430,18 @@ static void attr_create_uv_map(Scene *scene,
|
||||
}
|
||||
else {
|
||||
uv_attr = mesh->attributes.add(uv_name,
|
||||
TypeFloat2,
|
||||
TypeDesc::TypePoint,
|
||||
ATTR_ELEMENT_CORNER);
|
||||
}
|
||||
|
||||
BL::Mesh::loop_triangles_iterator t;
|
||||
float2 *fdata = uv_attr->data_float2();
|
||||
float3 *fdata = uv_attr->data_float3();
|
||||
|
||||
for(b_mesh.loop_triangles.begin(t); t != b_mesh.loop_triangles.end(); ++t) {
|
||||
int3 li = get_int3(t->loops());
|
||||
fdata[0] = get_float2(l->data[li[0]].uv());
|
||||
fdata[1] = get_float2(l->data[li[1]].uv());
|
||||
fdata[2] = get_float2(l->data[li[2]].uv());
|
||||
fdata[0] = get_float3(l->data[li[0]].uv());
|
||||
fdata[1] = get_float3(l->data[li[1]].uv());
|
||||
fdata[2] = get_float3(l->data[li[2]].uv());
|
||||
fdata += 3;
|
||||
}
|
||||
}
|
||||
@@ -509,19 +509,19 @@ static void attr_create_subd_uv_map(Scene *scene,
|
||||
if(active_render)
|
||||
uv_attr = mesh->subd_attributes.add(uv_std, uv_name);
|
||||
else
|
||||
uv_attr = mesh->subd_attributes.add(uv_name, TypeFloat2, ATTR_ELEMENT_CORNER);
|
||||
uv_attr = mesh->subd_attributes.add(uv_name, TypeDesc::TypePoint, ATTR_ELEMENT_CORNER);
|
||||
|
||||
if(subdivide_uvs) {
|
||||
uv_attr->flags |= ATTR_SUBDIVIDED;
|
||||
}
|
||||
|
||||
BL::Mesh::polygons_iterator p;
|
||||
float2 *fdata = uv_attr->data_float2();
|
||||
float3 *fdata = uv_attr->data_float3();
|
||||
|
||||
for(b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) {
|
||||
int n = p->loop_total();
|
||||
for(int j = 0; j < n; j++) {
|
||||
*(fdata++) = get_float2(l->data[p->loop_start() + j].uv());
|
||||
*(fdata++) = get_float3(l->data[p->loop_start() + j].uv());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -927,6 +927,8 @@ static void create_subd_mesh(Scene *scene,
|
||||
sdparams.dicing_rate = max(0.1f, RNA_float_get(&cobj, "dicing_rate") * dicing_rate);
|
||||
sdparams.max_level = max_subdivisions;
|
||||
|
||||
scene->dicing_camera->update(scene);
|
||||
sdparams.camera = scene->dicing_camera;
|
||||
sdparams.objecttoworld = get_transform(b_ob.matrix_world());
|
||||
}
|
||||
|
||||
@@ -1037,8 +1039,6 @@ Mesh *BlenderSync::sync_mesh(BL::Depsgraph& b_depsgraph,
|
||||
if(mesh_synced.find(mesh) != mesh_synced.end())
|
||||
return mesh;
|
||||
|
||||
progress.set_sync_status("Synchronizing object", b_ob.name());
|
||||
|
||||
mesh_synced.insert(mesh);
|
||||
|
||||
/* create derived mesh */
|
||||
|
@@ -349,7 +349,7 @@ Object *BlenderSync::sync_object(BL::Depsgraph& b_depsgraph,
|
||||
/* Visibility flags for both parent and child. */
|
||||
PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles");
|
||||
bool use_holdout = get_boolean(cobject, "is_holdout") ||
|
||||
b_parent.holdout_get(PointerRNA_NULL, b_view_layer);
|
||||
b_parent.holdout_get(b_view_layer);
|
||||
uint visibility = object_ray_visibility(b_ob) & PATH_RAY_ALL_VISIBILITY;
|
||||
|
||||
if(b_parent.ptr.data != b_ob.ptr.data) {
|
||||
@@ -364,7 +364,7 @@ Object *BlenderSync::sync_object(BL::Depsgraph& b_depsgraph,
|
||||
#endif
|
||||
|
||||
/* Clear camera visibility for indirect only objects. */
|
||||
bool use_indirect_only = b_parent.indirect_only_get(PointerRNA_NULL, b_view_layer);
|
||||
bool use_indirect_only = b_parent.indirect_only_get(b_view_layer);
|
||||
if(use_indirect_only) {
|
||||
visibility &= ~PATH_RAY_CAMERA;
|
||||
}
|
||||
@@ -544,6 +544,8 @@ void BlenderSync::sync_objects(BL::Depsgraph& b_depsgraph, float motion_time)
|
||||
BL::DepsgraphObjectInstance b_instance = *b_instance_iter;
|
||||
BL::Object b_ob = b_instance.object();
|
||||
|
||||
progress.set_sync_status("Synchronizing object", b_ob.name());
|
||||
|
||||
/* load per-object culling data */
|
||||
culling.init_object(scene, b_ob);
|
||||
|
||||
|
@@ -23,7 +23,6 @@
|
||||
#include "blender/blender_session.h"
|
||||
|
||||
#include "render/denoising.h"
|
||||
#include "render/merge.h"
|
||||
|
||||
#include "util/util_debug.h"
|
||||
#include "util/util_foreach.h"
|
||||
@@ -105,6 +104,7 @@ bool debug_flags_sync_from_scene(BL::Scene b_scene)
|
||||
/* 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;
|
||||
flags.opencl.single_program = get_boolean(cscene, "debug_opencl_kernel_single_program");
|
||||
return flags.opencl.device_type != opencl_device_type;
|
||||
}
|
||||
|
||||
@@ -643,8 +643,9 @@ static PyObject *opencl_compile_func(PyObject * /*self*/, PyObject *args)
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool image_parse_filepaths(PyObject *pyfilepaths, vector<string>& filepaths)
|
||||
static bool denoise_parse_filepaths(PyObject *pyfilepaths, vector<string>& filepaths)
|
||||
{
|
||||
|
||||
if(PyUnicode_Check(pyfilepaths)) {
|
||||
const char *filepath = PyUnicode_AsUTF8(pyfilepaths);
|
||||
filepaths.push_back(filepath);
|
||||
@@ -713,12 +714,12 @@ static PyObject *denoise_func(PyObject * /*self*/, PyObject *args, PyObject *key
|
||||
/* Parse file paths list. */
|
||||
vector<string> input, output;
|
||||
|
||||
if(!image_parse_filepaths(pyinput, input)) {
|
||||
if(!denoise_parse_filepaths(pyinput, input)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(pyoutput) {
|
||||
if(!image_parse_filepaths(pyoutput, output)) {
|
||||
if(!denoise_parse_filepaths(pyoutput, output)) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@@ -757,42 +758,6 @@ static PyObject *denoise_func(PyObject * /*self*/, PyObject *args, PyObject *key
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *merge_func(PyObject * /*self*/, PyObject *args, PyObject *keywords)
|
||||
{
|
||||
static const char *keyword_list[] = {"input", "output", NULL};
|
||||
PyObject *pyinput, *pyoutput = NULL;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, keywords, "OO", (char**)keyword_list, &pyinput, &pyoutput)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Parse input list. */
|
||||
vector<string> input;
|
||||
if(!image_parse_filepaths(pyinput, input)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Parse output string. */
|
||||
if(!PyUnicode_Check(pyoutput)) {
|
||||
PyErr_SetString(PyExc_ValueError, "Output must be a string.");
|
||||
return NULL;
|
||||
}
|
||||
string output = PyUnicode_AsUTF8(pyoutput);
|
||||
|
||||
/* Merge. */
|
||||
ImageMerger merger;
|
||||
merger.input = input;
|
||||
merger.output = output;
|
||||
|
||||
if(!merger.run()) {
|
||||
PyErr_SetString(PyExc_ValueError, merger.error.c_str());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
|
||||
static PyObject *debug_flags_update_func(PyObject * /*self*/, PyObject *args)
|
||||
{
|
||||
PyObject *pyscene;
|
||||
@@ -956,7 +921,6 @@ static PyMethodDef methods[] = {
|
||||
|
||||
/* Standalone denoising */
|
||||
{"denoise", (PyCFunction)denoise_func, METH_VARARGS|METH_KEYWORDS, ""},
|
||||
{"merge", (PyCFunction)merge_func, METH_VARARGS|METH_KEYWORDS, ""},
|
||||
|
||||
/* Debugging routines */
|
||||
{"debug_flags_update", debug_flags_update_func, METH_VARARGS, ""},
|
||||
|
@@ -416,26 +416,16 @@ void BlenderSession::stamp_view_layer_metadata(Scene *scene, const string& view_
|
||||
/* Write cryptomatte metadata. */
|
||||
if(scene->film->cryptomatte_passes & CRYPT_OBJECT) {
|
||||
add_cryptomatte_layer(b_rr, view_layer_name + ".CryptoObject",
|
||||
scene->object_manager->get_cryptomatte_objects(scene));
|
||||
scene->object_manager->get_cryptomatte_objects(scene));
|
||||
}
|
||||
if(scene->film->cryptomatte_passes & CRYPT_MATERIAL) {
|
||||
add_cryptomatte_layer(b_rr, view_layer_name + ".CryptoMaterial",
|
||||
scene->shader_manager->get_cryptomatte_materials(scene));
|
||||
scene->shader_manager->get_cryptomatte_materials(scene));
|
||||
}
|
||||
if(scene->film->cryptomatte_passes & CRYPT_ASSET) {
|
||||
add_cryptomatte_layer(b_rr, view_layer_name + ".CryptoAsset",
|
||||
scene->object_manager->get_cryptomatte_assets(scene));
|
||||
scene->object_manager->get_cryptomatte_assets(scene));
|
||||
}
|
||||
|
||||
/* Store synchronization and bare-render times. */
|
||||
double total_time, render_time;
|
||||
session->progress.get_time(total_time, render_time);
|
||||
b_rr.stamp_data_add_field((prefix + "total_time").c_str(),
|
||||
time_human_readable_from_seconds(total_time).c_str());
|
||||
b_rr.stamp_data_add_field((prefix + "render_time").c_str(),
|
||||
time_human_readable_from_seconds(render_time).c_str());
|
||||
b_rr.stamp_data_add_field((prefix + "synchronization_time").c_str(),
|
||||
time_human_readable_from_seconds(total_time - render_time).c_str());
|
||||
}
|
||||
|
||||
void BlenderSession::render(BL::Depsgraph& b_depsgraph_)
|
||||
@@ -461,7 +451,7 @@ void BlenderSession::render(BL::Depsgraph& b_depsgraph_)
|
||||
b_rlay_name = b_view_layer.name();
|
||||
|
||||
/* add passes */
|
||||
vector<Pass> passes = sync->sync_render_passes(b_rlay, b_view_layer);
|
||||
vector<Pass> passes = sync->sync_render_passes(b_rlay, b_view_layer, session_params);
|
||||
buffer_params.passes = passes;
|
||||
|
||||
PointerRNA crl = RNA_pointer_get(&b_view_layer.ptr, "cycles");
|
||||
@@ -978,11 +968,6 @@ void BlenderSession::get_status(string& status, string& substatus)
|
||||
session->progress.get_status(status, substatus);
|
||||
}
|
||||
|
||||
void BlenderSession::get_kernel_status(string& kernel_status)
|
||||
{
|
||||
session->progress.get_kernel_status(kernel_status);
|
||||
}
|
||||
|
||||
void BlenderSession::get_progress(float& progress, double& total_time, double& render_time)
|
||||
{
|
||||
session->progress.get_time(total_time, render_time);
|
||||
@@ -1001,15 +986,15 @@ void BlenderSession::update_bake_progress()
|
||||
|
||||
void BlenderSession::update_status_progress()
|
||||
{
|
||||
string timestatus, status, substatus, kernel_status;
|
||||
string timestatus, status, substatus;
|
||||
string scene_status = "";
|
||||
float progress;
|
||||
double total_time, remaining_time = 0, render_time;
|
||||
char time_str[128];
|
||||
float mem_used = (float)session->stats.mem_used / 1024.0f / 1024.0f;
|
||||
float mem_peak = (float)session->stats.mem_peak / 1024.0f / 1024.0f;
|
||||
|
||||
get_status(status, substatus);
|
||||
get_kernel_status(kernel_status);
|
||||
get_progress(progress, total_time, render_time);
|
||||
|
||||
if(progress > 0)
|
||||
@@ -1024,7 +1009,8 @@ void BlenderSession::update_status_progress()
|
||||
scene_status += ", " + b_rview_name;
|
||||
|
||||
if(remaining_time > 0) {
|
||||
timestatus += "Remaining:" + time_human_readable_from_seconds(remaining_time) + " | ";
|
||||
BLI_timecode_string_from_time_simple(time_str, sizeof(time_str), remaining_time);
|
||||
timestatus += "Remaining:" + string(time_str) + " | ";
|
||||
}
|
||||
|
||||
timestatus += string_printf("Mem:%.2fM, Peak:%.2fM", (double)mem_used, (double)mem_peak);
|
||||
@@ -1033,8 +1019,6 @@ void BlenderSession::update_status_progress()
|
||||
status = " | " + status;
|
||||
if(substatus.size() > 0)
|
||||
status += " | " + substatus;
|
||||
if(kernel_status.size() > 0)
|
||||
status += " | " + kernel_status;
|
||||
}
|
||||
|
||||
double current_time = time_dt();
|
||||
|
@@ -90,7 +90,6 @@ public:
|
||||
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();
|
||||
|
@@ -1050,18 +1050,13 @@ static void add_nodes(Scene *scene,
|
||||
graph->add(proxy);
|
||||
}
|
||||
}
|
||||
else if(b_node->is_a(&RNA_ShaderNodeGroup) ||
|
||||
b_node->is_a(&RNA_NodeCustomGroup) ||
|
||||
b_node->is_a(&RNA_ShaderNodeCustomGroup)) {
|
||||
else if(b_node->is_a(&RNA_ShaderNodeGroup) || b_node->is_a(&RNA_NodeCustomGroup)) {
|
||||
|
||||
BL::ShaderNodeTree b_group_ntree(PointerRNA_NULL);
|
||||
if(b_node->is_a(&RNA_ShaderNodeGroup))
|
||||
b_group_ntree = BL::ShaderNodeTree(((BL::NodeGroup)(*b_node)).node_tree());
|
||||
else if (b_node->is_a(&RNA_NodeCustomGroup))
|
||||
b_group_ntree = BL::ShaderNodeTree(((BL::NodeCustomGroup)(*b_node)).node_tree());
|
||||
else
|
||||
b_group_ntree = BL::ShaderNodeTree(((BL::ShaderNodeCustomGroup)(*b_node)).node_tree());
|
||||
|
||||
b_group_ntree = BL::ShaderNodeTree(((BL::NodeCustomGroup)(*b_node)).node_tree());
|
||||
ProxyMap group_proxy_input_map, group_proxy_output_map;
|
||||
|
||||
/* Add a proxy node for each socket
|
||||
|
@@ -85,11 +85,10 @@ void BlenderSync::sync_recalc(BL::Depsgraph& b_depsgraph)
|
||||
* so we can do it later on if doing it immediate is not suitable. */
|
||||
|
||||
bool has_updated_objects = b_depsgraph.id_type_updated(BL::DriverTarget::id_type_OBJECT);
|
||||
bool dicing_prop_changed = false;
|
||||
|
||||
if(experimental) {
|
||||
/* Mark all meshes as needing to be exported again if dicing changed. */
|
||||
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
|
||||
bool dicing_prop_changed = false;
|
||||
|
||||
float updated_dicing_rate = preview ? RNA_float_get(&cscene, "preview_dicing_rate")
|
||||
: RNA_float_get(&cscene, "dicing_rate");
|
||||
@@ -105,15 +104,6 @@ void BlenderSync::sync_recalc(BL::Depsgraph& b_depsgraph)
|
||||
max_subdivisions = updated_max_subdivisions;
|
||||
dicing_prop_changed = true;
|
||||
}
|
||||
|
||||
if(dicing_prop_changed) {
|
||||
for(const pair<void*, Mesh*>& iter: mesh_map.key_to_scene_data()) {
|
||||
Mesh *mesh = iter.second;
|
||||
if(mesh->subdivision_type != Mesh::SUBDIVISION_NONE) {
|
||||
mesh_map.set_recalc(iter.first);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Iterate over all IDs in this depsgraph. */
|
||||
@@ -143,7 +133,7 @@ void BlenderSync::sync_recalc(BL::Depsgraph& b_depsgraph)
|
||||
|
||||
if(object_is_mesh(b_ob)) {
|
||||
if(updated_geometry ||
|
||||
(object_subdivision_type(b_ob, preview, experimental) != Mesh::SUBDIVISION_NONE))
|
||||
(dicing_prop_changed && object_subdivision_type(b_ob, preview, experimental) != Mesh::SUBDIVISION_NONE))
|
||||
{
|
||||
BL::ID key = BKE_object_is_modified(b_ob)? b_ob: b_ob.data();
|
||||
mesh_map.set_recalc(key);
|
||||
@@ -514,11 +504,16 @@ int BlenderSync::get_denoising_pass(BL::RenderPass& b_pass)
|
||||
}
|
||||
|
||||
vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer& b_rlay,
|
||||
BL::ViewLayer& b_view_layer)
|
||||
BL::ViewLayer& b_view_layer,
|
||||
const SessionParams &session_params)
|
||||
{
|
||||
vector<Pass> passes;
|
||||
Pass::add(PASS_COMBINED, passes);
|
||||
|
||||
if(!session_params.device.advanced_shading) {
|
||||
return passes;
|
||||
}
|
||||
|
||||
/* loop over passes */
|
||||
BL::RenderLayer::passes_iterator b_pass_iter;
|
||||
|
||||
@@ -774,9 +769,6 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine& b_engine,
|
||||
}
|
||||
}
|
||||
|
||||
/* Clamp samples. */
|
||||
params.samples = min(params.samples, Integrator::MAX_SAMPLES);
|
||||
|
||||
/* tiles */
|
||||
const bool is_cpu = (params.device.type == DEVICE_CPU);
|
||||
if(!is_cpu && !background) {
|
||||
|
@@ -68,7 +68,8 @@ public:
|
||||
void **python_thread_state);
|
||||
void sync_view_layer(BL::SpaceView3D& b_v3d, BL::ViewLayer& b_view_layer);
|
||||
vector<Pass> sync_render_passes(BL::RenderLayer& b_render_layer,
|
||||
BL::ViewLayer& b_view_layer);
|
||||
BL::ViewLayer& b_view_layer,
|
||||
const SessionParams &session_params);
|
||||
void sync_integrator();
|
||||
void sync_camera(BL::RenderSettings& b_render,
|
||||
BL::Object& b_override,
|
||||
|
@@ -32,6 +32,7 @@
|
||||
* todo: clean this up ... */
|
||||
|
||||
extern "C" {
|
||||
size_t BLI_timecode_string_from_time_simple(char *str, size_t maxlen, double time_seconds);
|
||||
void BKE_image_user_frame_calc(void *iuser, int cfra);
|
||||
void BKE_image_user_file_path(void *iuser, void *ima, char *path);
|
||||
unsigned char *BKE_image_get_pixels_for_frame(void *image, int frame);
|
||||
@@ -323,6 +324,46 @@ static inline int4 get_int4(const BL::Array<int, 4>& array)
|
||||
return make_int4(array[0], array[1], array[2], array[3]);
|
||||
}
|
||||
|
||||
static inline uint get_layer(const BL::Array<bool, 20>& array)
|
||||
{
|
||||
uint layer = 0;
|
||||
|
||||
for(uint i = 0; i < 20; i++)
|
||||
if(array[i])
|
||||
layer |= (1 << i);
|
||||
|
||||
return layer;
|
||||
}
|
||||
|
||||
static inline uint get_layer(const BL::Array<bool, 20>& array,
|
||||
const BL::Array<bool, 8>& local_array,
|
||||
bool is_light = false,
|
||||
uint view_layers = (1 << 20) - 1)
|
||||
{
|
||||
uint layer = 0;
|
||||
|
||||
for(uint i = 0; i < 20; i++)
|
||||
if(array[i])
|
||||
layer |= (1 << i);
|
||||
|
||||
if(is_light) {
|
||||
/* Consider light is visible if it was visible without layer
|
||||
* override, which matches behavior of Blender Internal.
|
||||
*/
|
||||
if(layer & view_layers) {
|
||||
for(uint i = 0; i < 8; i++)
|
||||
layer |= (1 << (20+i));
|
||||
}
|
||||
}
|
||||
else {
|
||||
for(uint i = 0; i < 8; i++)
|
||||
if(local_array[i])
|
||||
layer |= (1 << (20+i));
|
||||
}
|
||||
|
||||
return layer;
|
||||
}
|
||||
|
||||
static inline float3 get_float3(PointerRNA& ptr, const char *name)
|
||||
{
|
||||
float3 f;
|
||||
@@ -628,11 +669,6 @@ public:
|
||||
b_recalc.insert(id.ptr.data);
|
||||
}
|
||||
|
||||
void set_recalc(void *id_ptr)
|
||||
{
|
||||
b_recalc.insert(id_ptr);
|
||||
}
|
||||
|
||||
bool has_recalc()
|
||||
{
|
||||
return !(b_recalc.empty());
|
||||
@@ -728,11 +764,6 @@ public:
|
||||
return deleted;
|
||||
}
|
||||
|
||||
const map<K, T*>& key_to_scene_data()
|
||||
{
|
||||
return b_map;
|
||||
}
|
||||
|
||||
protected:
|
||||
vector<T*> *scene_data;
|
||||
map<K, T*> b_map;
|
||||
|
@@ -149,13 +149,6 @@ static void rtc_filter_occluded_func(const RTCFilterFunctionNArguments* args)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Ignore curves. */
|
||||
if(hit->geomID & 1) {
|
||||
/* This tells Embree to continue tracing. */
|
||||
*args->valid = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
/* See triangle_intersect_subsurface() for the native equivalent. */
|
||||
for(int i = min(ctx->max_hits, ctx->ss_isect->num_hits) - 1; i >= 0; --i) {
|
||||
if(ctx->ss_isect->hits[i].t == ray->tfar) {
|
||||
@@ -396,45 +389,6 @@ void BVHEmbree::build(Progress& progress, Stats *stats_)
|
||||
(params.use_spatial_split ? RTC_BUILD_QUALITY_HIGH : RTC_BUILD_QUALITY_MEDIUM);
|
||||
rtcSetSceneBuildQuality(scene, build_quality);
|
||||
|
||||
/* Count triangles and curves first, reserve arrays once. */
|
||||
size_t prim_count = 0;
|
||||
|
||||
foreach(Object *ob, objects) {
|
||||
if (params.top_level) {
|
||||
if (!ob->is_traceable()) {
|
||||
continue;
|
||||
}
|
||||
if (!ob->mesh->is_instanced()) {
|
||||
if(params.primitive_mask & PRIMITIVE_ALL_TRIANGLE) {
|
||||
prim_count += ob->mesh->num_triangles();
|
||||
}
|
||||
if (params.primitive_mask & PRIMITIVE_ALL_CURVE) {
|
||||
for (size_t j = 0; j < ob->mesh->num_curves(); ++j) {
|
||||
prim_count += ob->mesh->get_curve(j).num_segments();
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
++prim_count;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (params.primitive_mask & PRIMITIVE_ALL_TRIANGLE && ob->mesh->num_triangles() > 0) {
|
||||
prim_count += ob->mesh->num_triangles();
|
||||
}
|
||||
if (params.primitive_mask & PRIMITIVE_ALL_CURVE) {
|
||||
for (size_t j = 0; j < ob->mesh->num_curves(); ++j) {
|
||||
prim_count += ob->mesh->get_curve(j).num_segments();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pack.prim_object.reserve(prim_count);
|
||||
pack.prim_type.reserve(prim_count);
|
||||
pack.prim_index.reserve(prim_count);
|
||||
pack.prim_tri_index.reserve(prim_count);
|
||||
|
||||
int i = 0;
|
||||
|
||||
pack.object_node.clear();
|
||||
@@ -576,20 +530,15 @@ void BVHEmbree::add_triangles(Object *ob, int i)
|
||||
|
||||
update_tri_vertex_buffer(geom_id, mesh);
|
||||
|
||||
size_t prim_object_size = pack.prim_object.size();
|
||||
pack.prim_object.resize(prim_object_size + num_triangles);
|
||||
size_t prim_type_size = pack.prim_type.size();
|
||||
pack.prim_type.resize(prim_type_size + num_triangles);
|
||||
size_t prim_index_size = pack.prim_index.size();
|
||||
pack.prim_index.resize(prim_index_size + num_triangles);
|
||||
pack.prim_tri_index.resize(prim_index_size + num_triangles);
|
||||
int prim_type = (num_motion_steps > 1 ? PRIMITIVE_MOTION_TRIANGLE : PRIMITIVE_TRIANGLE);
|
||||
|
||||
pack.prim_object.reserve(pack.prim_object.size() + num_triangles);
|
||||
pack.prim_type.reserve(pack.prim_type.size() + num_triangles);
|
||||
pack.prim_index.reserve(pack.prim_index.size() + num_triangles);
|
||||
pack.prim_tri_index.reserve(pack.prim_index.size() + num_triangles);
|
||||
for(size_t j = 0; j < num_triangles; ++j) {
|
||||
pack.prim_object[prim_object_size + j] = i;
|
||||
pack.prim_type[prim_type_size + j] = prim_type;
|
||||
pack.prim_index[prim_index_size + j] = j;
|
||||
pack.prim_tri_index[prim_index_size + j] = j;
|
||||
pack.prim_object.push_back_reserved(i);
|
||||
pack.prim_type.push_back_reserved(num_motion_steps > 1 ? PRIMITIVE_MOTION_TRIANGLE : PRIMITIVE_TRIANGLE);
|
||||
pack.prim_index.push_back_reserved(j);
|
||||
pack.prim_tri_index.push_back_reserved(j);
|
||||
}
|
||||
|
||||
rtcSetGeometryUserData(geom_id, (void*) prim_offset);
|
||||
@@ -680,7 +629,7 @@ void BVHEmbree::update_curve_vertex_buffer(RTCGeometry geom_id, const Mesh* mesh
|
||||
float4 *rtc_tangents = NULL;
|
||||
if(use_curves) {
|
||||
rtc_tangents = (float4*)rtcSetNewGeometryBuffer(geom_id, RTC_BUFFER_TYPE_TANGENT, t,
|
||||
RTC_FORMAT_FLOAT4, sizeof (float) * 4, num_keys);
|
||||
RTC_FORMAT_FLOAT4, sizeof (float) * 4, num_keys);
|
||||
assert(rtc_tangents);
|
||||
}
|
||||
assert(rtc_verts);
|
||||
@@ -742,14 +691,10 @@ void BVHEmbree::add_curves(Object *ob, int i)
|
||||
}
|
||||
|
||||
/* Make room for Cycles specific data. */
|
||||
size_t prim_object_size = pack.prim_object.size();
|
||||
pack.prim_object.resize(prim_object_size + num_segments);
|
||||
size_t prim_type_size = pack.prim_type.size();
|
||||
pack.prim_type.resize(prim_type_size + num_segments);
|
||||
size_t prim_index_size = pack.prim_index.size();
|
||||
pack.prim_index.resize(prim_index_size + num_segments);
|
||||
size_t prim_tri_index_size = pack.prim_index.size();
|
||||
pack.prim_tri_index.resize(prim_tri_index_size + num_segments);
|
||||
pack.prim_object.reserve(pack.prim_object.size() + num_segments);
|
||||
pack.prim_type.reserve(pack.prim_type.size() + num_segments);
|
||||
pack.prim_index.reserve(pack.prim_index.size() + num_segments);
|
||||
pack.prim_tri_index.reserve(pack.prim_index.size() + num_segments);
|
||||
|
||||
enum RTCGeometryType type = (!use_curves) ? RTC_GEOMETRY_TYPE_FLAT_LINEAR_CURVE :
|
||||
(use_ribbons ? RTC_GEOMETRY_TYPE_FLAT_HERMITE_CURVE :
|
||||
@@ -758,18 +703,18 @@ void BVHEmbree::add_curves(Object *ob, int i)
|
||||
RTCGeometry geom_id = rtcNewGeometry(rtc_shared_device, type);
|
||||
rtcSetGeometryTessellationRate(geom_id, curve_subdivisions);
|
||||
unsigned *rtc_indices = (unsigned*) rtcSetNewGeometryBuffer(geom_id, RTC_BUFFER_TYPE_INDEX, 0,
|
||||
RTC_FORMAT_UINT, sizeof (int), num_segments);
|
||||
RTC_FORMAT_UINT, sizeof (int), num_segments);
|
||||
size_t rtc_index = 0;
|
||||
for(size_t j = 0; j < num_curves; ++j) {
|
||||
Mesh::Curve c = mesh->get_curve(j);
|
||||
for(size_t k = 0; k < c.num_segments(); ++k) {
|
||||
rtc_indices[rtc_index] = c.first_key + k;
|
||||
/* Cycles specific data. */
|
||||
pack.prim_object[prim_object_size + rtc_index] = i;
|
||||
pack.prim_type[prim_type_size + rtc_index] = (PRIMITIVE_PACK_SEGMENT(num_motion_steps > 1 ?
|
||||
PRIMITIVE_MOTION_CURVE : PRIMITIVE_CURVE, k));
|
||||
pack.prim_index[prim_index_size + rtc_index] = j;
|
||||
pack.prim_tri_index[prim_tri_index_size + rtc_index] = rtc_index;
|
||||
pack.prim_object.push_back_reserved(i);
|
||||
pack.prim_type.push_back_reserved(PRIMITIVE_PACK_SEGMENT(num_motion_steps > 1 ?
|
||||
PRIMITIVE_MOTION_CURVE : PRIMITIVE_CURVE, k));
|
||||
pack.prim_index.push_back_reserved(j);
|
||||
pack.prim_tri_index.push_back_reserved(rtc_index);
|
||||
|
||||
++rtc_index;
|
||||
}
|
||||
|
@@ -349,7 +349,6 @@ void Device::draw_pixels(
|
||||
draw_params.unbind_display_space_shader_cb();
|
||||
}
|
||||
|
||||
glDeleteVertexArrays(1, &vertex_array_object);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glDeleteTextures(1, &texid);
|
||||
|
||||
|
@@ -56,14 +56,6 @@ enum DeviceTypeMask {
|
||||
DEVICE_MASK_ALL = ~0
|
||||
};
|
||||
|
||||
enum DeviceKernelStatus {
|
||||
DEVICE_KERNEL_WAITING_FOR_FEATURE_KERNEL = 0,
|
||||
DEVICE_KERNEL_FEATURE_KERNEL_AVAILABLE,
|
||||
DEVICE_KERNEL_USING_FEATURE_KERNEL,
|
||||
DEVICE_KERNEL_FEATURE_KERNEL_INVALID,
|
||||
DEVICE_KERNEL_UNKNOWN,
|
||||
};
|
||||
|
||||
#define DEVICE_MASK(type) (DeviceTypeMask)(1 << type)
|
||||
|
||||
class DeviceInfo {
|
||||
@@ -73,6 +65,7 @@ public:
|
||||
string id; /* used for user preferences, should stay fixed with changing hardware config */
|
||||
int num;
|
||||
bool display_device; /* GPU is used as a display device. */
|
||||
bool advanced_shading; /* Supports full shading system. */
|
||||
bool has_half_images; /* Support half-float textures. */
|
||||
bool has_volume_decoupled; /* Decoupled volume shading. */
|
||||
bool has_osl; /* Support Open Shading Language. */
|
||||
@@ -88,6 +81,7 @@ public:
|
||||
num = 0;
|
||||
cpu_threads = 0;
|
||||
display_device = false;
|
||||
advanced_shading = true;
|
||||
has_half_images = false;
|
||||
has_volume_decoupled = false;
|
||||
has_osl = false;
|
||||
@@ -340,20 +334,6 @@ public:
|
||||
const DeviceRequestedFeatures& /*requested_features*/)
|
||||
{ return true; }
|
||||
|
||||
/* Wait for device to become available to upload data and receive tasks
|
||||
* This method is used by the OpenCL device to load the
|
||||
* optimized kernels or when not (yet) available load the
|
||||
* generic kernels (only during foreground rendering) */
|
||||
virtual bool wait_for_availability(
|
||||
const DeviceRequestedFeatures& /*requested_features*/)
|
||||
{ return true; }
|
||||
/* Check if there are 'better' kernels available to be used
|
||||
* We can switch over to these kernels
|
||||
* This method is used to determine if we can switch the preview kernels
|
||||
* to regular kernels */
|
||||
virtual DeviceKernelStatus get_active_kernel_switch_state()
|
||||
{ return DEVICE_KERNEL_USING_FEATURE_KERNEL; }
|
||||
|
||||
/* tasks */
|
||||
virtual int get_split_task_count(DeviceTask& task) = 0;
|
||||
virtual void task_add(DeviceTask& task) = 0;
|
||||
|
@@ -761,8 +761,8 @@ public:
|
||||
int start_sample = tile.start_sample;
|
||||
int end_sample = tile.start_sample + tile.num_samples;
|
||||
|
||||
/* Needed for Embree. */
|
||||
SIMD_SET_FLUSH_TO_ZERO;
|
||||
_MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON);
|
||||
_MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON);
|
||||
|
||||
for(int sample = start_sample; sample < end_sample; sample++) {
|
||||
if(task.get_cancel() || task_pool.canceled()) {
|
||||
@@ -1123,6 +1123,7 @@ void device_cpu_info(vector<DeviceInfo>& devices)
|
||||
info.description = system_cpu_brand_string();
|
||||
info.id = "CPU";
|
||||
info.num = 0;
|
||||
info.advanced_shading = true;
|
||||
info.has_volume_decoupled = true;
|
||||
info.has_osl = true;
|
||||
info.has_half_images = true;
|
||||
|
@@ -400,9 +400,9 @@ public:
|
||||
major, minor);
|
||||
return false;
|
||||
}
|
||||
else if(cuda_version != 101) {
|
||||
else if(cuda_version != 80) {
|
||||
printf("CUDA version %d.%d detected, build may succeed but only "
|
||||
"CUDA 10.1 is officially supported.\n",
|
||||
"CUDA 8.0 is officially supported.\n",
|
||||
major, minor);
|
||||
}
|
||||
return true;
|
||||
@@ -2532,6 +2532,7 @@ void device_cuda_info(vector<DeviceInfo>& devices)
|
||||
info.description = string(name);
|
||||
info.num = num;
|
||||
|
||||
info.advanced_shading = (major >= 3);
|
||||
info.has_half_images = (major >= 3);
|
||||
info.has_volume_decoupled = false;
|
||||
|
||||
|
@@ -120,38 +120,6 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wait_for_availability(const DeviceRequestedFeatures& requested_features)
|
||||
{
|
||||
foreach(SubDevice& sub, devices)
|
||||
if(!sub.device->wait_for_availability(requested_features))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
DeviceKernelStatus get_active_kernel_switch_state()
|
||||
{
|
||||
DeviceKernelStatus result = DEVICE_KERNEL_USING_FEATURE_KERNEL;
|
||||
|
||||
foreach(SubDevice& sub, devices) {
|
||||
DeviceKernelStatus subresult = sub.device->get_active_kernel_switch_state();
|
||||
switch (subresult) {
|
||||
case DEVICE_KERNEL_WAITING_FOR_FEATURE_KERNEL:
|
||||
result = subresult;
|
||||
break;
|
||||
|
||||
case DEVICE_KERNEL_FEATURE_KERNEL_INVALID:
|
||||
case DEVICE_KERNEL_FEATURE_KERNEL_AVAILABLE:
|
||||
return subresult;
|
||||
|
||||
case DEVICE_KERNEL_USING_FEATURE_KERNEL:
|
||||
case DEVICE_KERNEL_UNKNOWN:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void mem_alloc(device_memory& mem)
|
||||
{
|
||||
device_ptr key = unique_key++;
|
||||
|
@@ -308,6 +308,7 @@ void device_network_info(vector<DeviceInfo>& devices)
|
||||
info.num = 0;
|
||||
|
||||
/* todo: get this info from device */
|
||||
info.advanced_shading = true;
|
||||
info.has_volume_decoupled = false;
|
||||
info.has_osl = false;
|
||||
|
||||
|
@@ -119,6 +119,7 @@ void device_opencl_info(vector<DeviceInfo>& devices)
|
||||
info.num = num_devices;
|
||||
/* We don't know if it's used for display, but assume it is. */
|
||||
info.display_device = true;
|
||||
info.advanced_shading = OpenCLInfo::kernel_use_advanced_shading(platform_name);
|
||||
info.use_split_kernel = true;
|
||||
info.has_volume_decoupled = false;
|
||||
info.id = id;
|
||||
|
@@ -84,6 +84,7 @@ class OpenCLInfo
|
||||
public:
|
||||
static cl_device_type device_type();
|
||||
static bool use_debug();
|
||||
static bool kernel_use_advanced_shading(const string& platform_name);
|
||||
static bool device_supported(const string& platform_name,
|
||||
const cl_device_id device_id);
|
||||
static bool platform_version_check(cl_platform_id platform,
|
||||
@@ -94,6 +95,7 @@ public:
|
||||
cl_device_id device_id);
|
||||
static void get_usable_devices(vector<OpenCLPlatformDevice> *usable_devices,
|
||||
bool force_all = false);
|
||||
static bool use_single_program();
|
||||
|
||||
/* ** Some handy shortcuts to low level cl*GetInfo() functions. ** */
|
||||
|
||||
@@ -260,22 +262,16 @@ class OpenCLDevice : public Device
|
||||
{
|
||||
public:
|
||||
DedicatedTaskPool task_pool;
|
||||
|
||||
/* Task pool for required kernels (base, AO kernels during foreground rendering) */
|
||||
TaskPool load_required_kernel_task_pool;
|
||||
/* Task pool for optional kernels (feature kernels during foreground rendering) */
|
||||
TaskPool load_kernel_task_pool;
|
||||
cl_context cxContext;
|
||||
cl_command_queue cqCommandQueue;
|
||||
cl_platform_id cpPlatform;
|
||||
cl_device_id cdDevice;
|
||||
cl_int ciErr;
|
||||
int device_num;
|
||||
bool use_preview_kernels;
|
||||
|
||||
class OpenCLProgram {
|
||||
public:
|
||||
OpenCLProgram() : loaded(false), needs_compiling(true), program(NULL), device(NULL) {}
|
||||
OpenCLProgram() : loaded(false), program(NULL), device(NULL) {}
|
||||
OpenCLProgram(OpenCLDevice *device,
|
||||
const string& program_name,
|
||||
const string& kernel_name,
|
||||
@@ -284,24 +280,12 @@ public:
|
||||
~OpenCLProgram();
|
||||
|
||||
void add_kernel(ustring name);
|
||||
|
||||
/* Try to load the program from device cache or disk */
|
||||
bool load();
|
||||
/* Compile the kernel (first separate, failback to local) */
|
||||
void compile();
|
||||
/* Create the OpenCL kernels after loading or compiling */
|
||||
void create_kernels();
|
||||
void load();
|
||||
|
||||
bool is_loaded() const { return loaded; }
|
||||
const string& get_log() const { return log; }
|
||||
void report_error();
|
||||
|
||||
/* Wait until this kernel is available to be used
|
||||
* It will return true when the kernel is available.
|
||||
* It will return false when the kernel is not available
|
||||
* or could not be loaded. */
|
||||
bool wait_for_availability();
|
||||
|
||||
cl_kernel operator()();
|
||||
cl_kernel operator()(ustring name);
|
||||
|
||||
@@ -325,8 +309,6 @@ public:
|
||||
void add_error(const string& msg);
|
||||
|
||||
bool loaded;
|
||||
bool needs_compiling;
|
||||
|
||||
cl_program program;
|
||||
OpenCLDevice *device;
|
||||
|
||||
@@ -342,42 +324,26 @@ public:
|
||||
map<ustring, cl_kernel> kernels;
|
||||
};
|
||||
|
||||
/* Container for all types of split programs. */
|
||||
class OpenCLSplitPrograms {
|
||||
public:
|
||||
OpenCLDevice *device;
|
||||
OpenCLProgram program_split;
|
||||
OpenCLProgram program_lamp_emission;
|
||||
OpenCLProgram program_do_volume;
|
||||
OpenCLProgram program_indirect_background;
|
||||
OpenCLProgram program_shader_eval;
|
||||
OpenCLProgram program_holdout_emission_blurring_pathtermination_ao;
|
||||
OpenCLProgram program_subsurface_scatter;
|
||||
OpenCLProgram program_direct_lighting;
|
||||
OpenCLProgram program_shadow_blocked_ao;
|
||||
OpenCLProgram program_shadow_blocked_dl;
|
||||
|
||||
OpenCLSplitPrograms(OpenCLDevice *device);
|
||||
~OpenCLSplitPrograms();
|
||||
|
||||
/* Load the kernels and put the created kernels in the given `programs`
|
||||
* paramter. */
|
||||
void load_kernels(vector<OpenCLProgram*> &programs,
|
||||
const DeviceRequestedFeatures& requested_features,
|
||||
bool is_preview=false);
|
||||
};
|
||||
|
||||
DeviceSplitKernel *split_kernel;
|
||||
|
||||
OpenCLProgram program_split;
|
||||
|
||||
OpenCLProgram program_lamp_emission;
|
||||
OpenCLProgram program_do_volume;
|
||||
OpenCLProgram program_indirect_background;
|
||||
OpenCLProgram program_shader_eval;
|
||||
OpenCLProgram program_holdout_emission_blurring_pathtermination_ao;
|
||||
OpenCLProgram program_subsurface_scatter;
|
||||
OpenCLProgram program_direct_lighting;
|
||||
OpenCLProgram program_shadow_blocked_ao;
|
||||
OpenCLProgram program_shadow_blocked_dl;
|
||||
|
||||
OpenCLProgram base_program;
|
||||
OpenCLProgram bake_program;
|
||||
OpenCLProgram displace_program;
|
||||
OpenCLProgram background_program;
|
||||
OpenCLProgram denoising_program;
|
||||
|
||||
OpenCLSplitPrograms kernel_programs;
|
||||
OpenCLSplitPrograms preview_programs;
|
||||
|
||||
typedef map<string, device_vector<uchar>*> ConstMemMap;
|
||||
typedef map<string, device_ptr> MemMap;
|
||||
|
||||
@@ -393,32 +359,22 @@ public:
|
||||
void opencl_error(const string& message);
|
||||
void opencl_assert_err(cl_int err, const char* where);
|
||||
|
||||
OpenCLDevice(DeviceInfo& info, Stats &stats, Profiler &profiler, bool background);
|
||||
OpenCLDevice(DeviceInfo& info, Stats &stats, Profiler &profiler, bool background_);
|
||||
~OpenCLDevice();
|
||||
|
||||
static void CL_CALLBACK context_notify_callback(const char *err_info,
|
||||
const void * /*private_info*/, size_t /*cb*/, void *user_data);
|
||||
|
||||
bool opencl_version_check();
|
||||
OpenCLSplitPrograms* get_split_programs();
|
||||
|
||||
string device_md5_hash(string kernel_custom_build_options = "");
|
||||
bool load_kernels(const DeviceRequestedFeatures& requested_features);
|
||||
void load_required_kernels(const DeviceRequestedFeatures& requested_features);
|
||||
void load_preview_kernels();
|
||||
|
||||
bool wait_for_availability(const DeviceRequestedFeatures& requested_features);
|
||||
DeviceKernelStatus get_active_kernel_switch_state();
|
||||
|
||||
/* Get the name of the opencl program for the given kernel */
|
||||
const string get_opencl_program_name(const string& kernel_name);
|
||||
const string get_opencl_program_name(bool single_program, const string& kernel_name);
|
||||
/* Get the program file name to compile (*.cl) for the given kernel */
|
||||
const string get_opencl_program_filename(const string& kernel_name);
|
||||
string get_build_options(const DeviceRequestedFeatures& requested_features,
|
||||
const string& opencl_program_name,
|
||||
bool preview_kernel=false);
|
||||
/* Enable the default features to reduce recompilation events */
|
||||
void enable_default_features(DeviceRequestedFeatures& features);
|
||||
const string get_opencl_program_filename(bool single_program, const string& kernel_name);
|
||||
string get_build_options(const DeviceRequestedFeatures& requested_features, const string& opencl_program_name);
|
||||
|
||||
void mem_alloc(device_memory& mem);
|
||||
void mem_copy_to(device_memory& mem);
|
||||
|
@@ -40,13 +40,7 @@ struct texture_slot_t {
|
||||
int slot;
|
||||
};
|
||||
|
||||
static const string NON_SPLIT_KERNELS =
|
||||
"denoising "
|
||||
"base "
|
||||
"background "
|
||||
"displace ";
|
||||
|
||||
static const string SPLIT_BUNDLE_KERNELS =
|
||||
static const string fast_compiled_kernels =
|
||||
"data_init "
|
||||
"path_init "
|
||||
"state_buffer_size "
|
||||
@@ -59,52 +53,37 @@ static const string SPLIT_BUNDLE_KERNELS =
|
||||
"indirect_subsurface "
|
||||
"buffer_update";
|
||||
|
||||
const string OpenCLDevice::get_opencl_program_name(const string& kernel_name)
|
||||
const string OpenCLDevice::get_opencl_program_name(bool single_program, const string& kernel_name)
|
||||
{
|
||||
if (NON_SPLIT_KERNELS.find(kernel_name) != std::string::npos) {
|
||||
return kernel_name;
|
||||
}
|
||||
else if (SPLIT_BUNDLE_KERNELS.find(kernel_name) != std::string::npos) {
|
||||
return "split_bundle";
|
||||
if (single_program) {
|
||||
return "split";
|
||||
}
|
||||
else {
|
||||
return "split_" + kernel_name;
|
||||
if (fast_compiled_kernels.find(kernel_name) != std::string::npos) {
|
||||
return "split_bundle";
|
||||
}
|
||||
else {
|
||||
return "split_" + kernel_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const string OpenCLDevice::get_opencl_program_filename(const string& kernel_name)
|
||||
const string OpenCLDevice::get_opencl_program_filename(bool single_program, const string& kernel_name)
|
||||
{
|
||||
if (kernel_name == "denoising") {
|
||||
return "filter.cl";
|
||||
}
|
||||
else if (SPLIT_BUNDLE_KERNELS.find(kernel_name) != std::string::npos) {
|
||||
return "kernel_split_bundle.cl";
|
||||
if (single_program) {
|
||||
return "kernel_split.cl";
|
||||
}
|
||||
else {
|
||||
return "kernel_" + kernel_name + ".cl";
|
||||
if (fast_compiled_kernels.find(kernel_name) != std::string::npos) {
|
||||
return "kernel_split_bundle.cl";
|
||||
}
|
||||
else {
|
||||
return "kernel_" + kernel_name + ".cl";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Enable features that we always want to compile to reduce recompilation events */
|
||||
void OpenCLDevice::enable_default_features(DeviceRequestedFeatures& features)
|
||||
{
|
||||
features.use_transparent = true;
|
||||
features.use_shadow_tricks = true;
|
||||
features.use_principled = true;
|
||||
features.use_denoising = true;
|
||||
|
||||
if (!background)
|
||||
{
|
||||
features.max_nodes_group = NODE_GROUP_LEVEL_MAX;
|
||||
features.nodes_features = NODE_FEATURE_ALL;
|
||||
features.use_hair = true;
|
||||
features.use_subsurface = true;
|
||||
features.use_camera_motion = false;
|
||||
features.use_object_motion = false;
|
||||
}
|
||||
}
|
||||
|
||||
string OpenCLDevice::get_build_options(const DeviceRequestedFeatures& requested_features, const string& opencl_program_name, bool preview_kernel)
|
||||
string OpenCLDevice::get_build_options(const DeviceRequestedFeatures& requested_features, const string& opencl_program_name)
|
||||
{
|
||||
/* first check for non-split kernel programs */
|
||||
if (opencl_program_name == "base" || opencl_program_name == "denoising") {
|
||||
@@ -112,25 +91,18 @@ string OpenCLDevice::get_build_options(const DeviceRequestedFeatures& requested_
|
||||
}
|
||||
else if (opencl_program_name == "bake") {
|
||||
/* Note: get_build_options for bake is only requested when baking is enabled.
|
||||
* displace and background are always requested.
|
||||
* `__SPLIT_KERNEL__` must not be present in the compile directives for bake */
|
||||
displace and background are always requested.
|
||||
`__SPLIT_KERNEL__` must not be present in the compile directives for bake */
|
||||
DeviceRequestedFeatures features(requested_features);
|
||||
enable_default_features(features);
|
||||
features.use_denoising = false;
|
||||
features.use_object_motion = false;
|
||||
features.use_camera_motion = false;
|
||||
features.use_hair = true;
|
||||
features.use_subsurface = true;
|
||||
features.max_nodes_group = NODE_GROUP_LEVEL_MAX;
|
||||
features.nodes_features = NODE_FEATURE_ALL;
|
||||
features.use_integrator_branched = false;
|
||||
return features.get_build_options();
|
||||
}
|
||||
else if (opencl_program_name == "displace") {
|
||||
/* As displacement does not use any nodes from the Shading group (eg BSDF).
|
||||
* We disable all features that are related to shading. */
|
||||
We disable all features that are related to shading. */
|
||||
DeviceRequestedFeatures features(requested_features);
|
||||
enable_default_features(features);
|
||||
features.use_denoising = false;
|
||||
features.use_object_motion = false;
|
||||
features.use_camera_motion = false;
|
||||
@@ -142,33 +114,27 @@ string OpenCLDevice::get_build_options(const DeviceRequestedFeatures& requested_
|
||||
features.nodes_features &= ~NODE_FEATURE_VOLUME;
|
||||
features.use_denoising = false;
|
||||
features.use_principled = false;
|
||||
features.use_integrator_branched = false;
|
||||
return features.get_build_options();
|
||||
}
|
||||
else if (opencl_program_name == "background") {
|
||||
/* Background uses Background shading
|
||||
* It is save to disable shadow features, subsurface and volumetric. */
|
||||
It is save to disable shadow features, subsurface and volumetric. */
|
||||
DeviceRequestedFeatures features(requested_features);
|
||||
enable_default_features(features);
|
||||
features.use_baking = false;
|
||||
features.use_object_motion = false;
|
||||
features.use_camera_motion = false;
|
||||
features.use_transparent = false;
|
||||
features.use_shadow_tricks = false;
|
||||
features.use_denoising = false;
|
||||
/* NOTE: currently possible to use surface nodes like `Hair Info`, `Bump` node.
|
||||
* Perhaps we should remove them in UI as it does not make any sense when
|
||||
* rendering background. */
|
||||
Perhaps we should remove them in UI as it does not make any sense when
|
||||
rendering background. */
|
||||
features.nodes_features &= ~NODE_FEATURE_VOLUME;
|
||||
features.use_subsurface = false;
|
||||
features.use_volume = false;
|
||||
features.use_shader_raytrace = false;
|
||||
features.use_patch_evaluation = false;
|
||||
features.use_integrator_branched = false;
|
||||
return features.get_build_options();
|
||||
}
|
||||
|
||||
string build_options = "-D__SPLIT_KERNEL__ ";
|
||||
DeviceRequestedFeatures nofeatures;
|
||||
/* Set compute device build option. */
|
||||
cl_device_type device_type;
|
||||
OpenCLInfo::get_device_type(this->cdDevice, &device_type, &this->ciErr);
|
||||
@@ -177,34 +143,28 @@ string OpenCLDevice::get_build_options(const DeviceRequestedFeatures& requested_
|
||||
build_options += "-D__COMPUTE_DEVICE_GPU__ ";
|
||||
}
|
||||
|
||||
DeviceRequestedFeatures nofeatures;
|
||||
enable_default_features(nofeatures);
|
||||
|
||||
/* Add program specific optimized compile directives */
|
||||
if (preview_kernel) {
|
||||
DeviceRequestedFeatures preview_features;
|
||||
preview_features.use_hair = true;
|
||||
build_options += "-D__KERNEL_AO_PREVIEW__ ";
|
||||
build_options += preview_features.get_build_options();
|
||||
if (opencl_program_name == "split_do_volume" && !requested_features.use_volume) {
|
||||
build_options += nofeatures.get_build_options();
|
||||
}
|
||||
else if (opencl_program_name == "split_do_volume" && !requested_features.use_volume) {
|
||||
else if (opencl_program_name == "split_subsurface_scatter" && !requested_features.use_subsurface) {
|
||||
/* When subsurface is off, the kernel updates indexes and does not need any
|
||||
Compile directives */
|
||||
build_options += nofeatures.get_build_options();
|
||||
}
|
||||
else {
|
||||
DeviceRequestedFeatures features(requested_features);
|
||||
enable_default_features(features);
|
||||
|
||||
/* Always turn off baking at this point. Baking is only usefull when building the bake kernel.
|
||||
* this also makes sure that the kernels that are build during baking can be reused
|
||||
* when not doing any baking. */
|
||||
this also makes sure that the kernels that are build during baking can be reused
|
||||
when not doing any baking. */
|
||||
features.use_baking = false;
|
||||
|
||||
/* Do not vary on shaders when program doesn't do any shading.
|
||||
* We have bundled them in a single program. */
|
||||
We have bundled them in a single program. */
|
||||
if (opencl_program_name == "split_bundle") {
|
||||
features.max_nodes_group = 0;
|
||||
features.nodes_features = 0;
|
||||
features.use_shader_raytrace = false;
|
||||
}
|
||||
|
||||
/* No specific settings, just add the regular ones */
|
||||
@@ -214,77 +174,6 @@ string OpenCLDevice::get_build_options(const DeviceRequestedFeatures& requested_
|
||||
return build_options;
|
||||
}
|
||||
|
||||
OpenCLDevice::OpenCLSplitPrograms::OpenCLSplitPrograms(OpenCLDevice *device_)
|
||||
{
|
||||
device = device_;
|
||||
}
|
||||
|
||||
OpenCLDevice::OpenCLSplitPrograms::~OpenCLSplitPrograms()
|
||||
{
|
||||
program_split.release();
|
||||
program_lamp_emission.release();
|
||||
program_do_volume.release();
|
||||
program_indirect_background.release();
|
||||
program_shader_eval.release();
|
||||
program_holdout_emission_blurring_pathtermination_ao.release();
|
||||
program_subsurface_scatter.release();
|
||||
program_direct_lighting.release();
|
||||
program_shadow_blocked_ao.release();
|
||||
program_shadow_blocked_dl.release();
|
||||
}
|
||||
|
||||
void OpenCLDevice::OpenCLSplitPrograms::load_kernels(vector<OpenCLProgram*> &programs, const DeviceRequestedFeatures& requested_features, bool is_preview)
|
||||
{
|
||||
if (!requested_features.use_baking) {
|
||||
#define ADD_SPLIT_KERNEL_BUNDLE_PROGRAM(kernel_name) program_split.add_kernel(ustring("path_trace_"#kernel_name));
|
||||
#define ADD_SPLIT_KERNEL_PROGRAM(kernel_name) \
|
||||
const string program_name_##kernel_name = "split_"#kernel_name; \
|
||||
program_##kernel_name = \
|
||||
OpenCLDevice::OpenCLProgram(device, \
|
||||
program_name_##kernel_name, \
|
||||
"kernel_"#kernel_name".cl", \
|
||||
device->get_build_options(requested_features, program_name_##kernel_name, is_preview)); \
|
||||
program_##kernel_name.add_kernel(ustring("path_trace_"#kernel_name)); \
|
||||
programs.push_back(&program_##kernel_name);
|
||||
|
||||
/* Ordered with most complex kernels first, to reduce overall compile time. */
|
||||
ADD_SPLIT_KERNEL_PROGRAM(subsurface_scatter);
|
||||
if (requested_features.use_volume || is_preview) {
|
||||
ADD_SPLIT_KERNEL_PROGRAM(do_volume);
|
||||
}
|
||||
ADD_SPLIT_KERNEL_PROGRAM(shadow_blocked_dl);
|
||||
ADD_SPLIT_KERNEL_PROGRAM(shadow_blocked_ao);
|
||||
ADD_SPLIT_KERNEL_PROGRAM(holdout_emission_blurring_pathtermination_ao);
|
||||
ADD_SPLIT_KERNEL_PROGRAM(lamp_emission);
|
||||
ADD_SPLIT_KERNEL_PROGRAM(direct_lighting);
|
||||
ADD_SPLIT_KERNEL_PROGRAM(indirect_background);
|
||||
ADD_SPLIT_KERNEL_PROGRAM(shader_eval);
|
||||
|
||||
/* Quick kernels bundled in a single program to reduce overhead of starting
|
||||
* Blender processes. */
|
||||
program_split = OpenCLDevice::OpenCLProgram(device,
|
||||
"split_bundle" ,
|
||||
"kernel_split_bundle.cl",
|
||||
device->get_build_options(requested_features, "split_bundle", is_preview));
|
||||
|
||||
ADD_SPLIT_KERNEL_BUNDLE_PROGRAM(data_init);
|
||||
ADD_SPLIT_KERNEL_BUNDLE_PROGRAM(state_buffer_size);
|
||||
ADD_SPLIT_KERNEL_BUNDLE_PROGRAM(path_init);
|
||||
ADD_SPLIT_KERNEL_BUNDLE_PROGRAM(scene_intersect);
|
||||
ADD_SPLIT_KERNEL_BUNDLE_PROGRAM(queue_enqueue);
|
||||
ADD_SPLIT_KERNEL_BUNDLE_PROGRAM(shader_setup);
|
||||
ADD_SPLIT_KERNEL_BUNDLE_PROGRAM(shader_sort);
|
||||
ADD_SPLIT_KERNEL_BUNDLE_PROGRAM(enqueue_inactive);
|
||||
ADD_SPLIT_KERNEL_BUNDLE_PROGRAM(next_iteration_setup);
|
||||
ADD_SPLIT_KERNEL_BUNDLE_PROGRAM(indirect_subsurface);
|
||||
ADD_SPLIT_KERNEL_BUNDLE_PROGRAM(buffer_update);
|
||||
programs.push_back(&program_split);
|
||||
|
||||
#undef ADD_SPLIT_KERNEL_PROGRAM
|
||||
#undef ADD_SPLIT_KERNEL_BUNDLE_PROGRAM
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
/* Copy dummy KernelGlobals related to OpenCL from kernel_globals.h to
|
||||
@@ -391,14 +280,13 @@ public:
|
||||
{
|
||||
OpenCLSplitKernelFunction* kernel = new OpenCLSplitKernelFunction(device, cached_memory);
|
||||
|
||||
const string program_name = device->get_opencl_program_name(kernel_name);
|
||||
bool single_program = OpenCLInfo::use_single_program();
|
||||
const string program_name = device->get_opencl_program_name(single_program, kernel_name);
|
||||
kernel->program =
|
||||
OpenCLDevice::OpenCLProgram(device,
|
||||
program_name,
|
||||
device->get_opencl_program_filename(kernel_name),
|
||||
device->get_build_options(requested_features,
|
||||
program_name,
|
||||
device->use_preview_kernels));
|
||||
device->get_opencl_program_filename(single_program, kernel_name),
|
||||
device->get_build_options(requested_features, program_name));
|
||||
|
||||
kernel->program.add_kernel(ustring("path_trace_" + kernel_name));
|
||||
kernel->program.load();
|
||||
@@ -418,8 +306,7 @@ public:
|
||||
size_buffer.zero_to_device();
|
||||
|
||||
uint threads = num_threads;
|
||||
OpenCLDevice::OpenCLSplitPrograms *programs = device->get_split_programs();
|
||||
cl_kernel kernel_state_buffer_size = programs->program_split(ustring("path_trace_state_buffer_size"));
|
||||
cl_kernel kernel_state_buffer_size = device->program_split(ustring("path_trace_state_buffer_size"));
|
||||
device->kernel_set_args(kernel_state_buffer_size, 0, kg, data, threads, size_buffer);
|
||||
|
||||
size_t global_size = 64;
|
||||
@@ -469,8 +356,7 @@ public:
|
||||
cl_int start_sample = rtile.start_sample;
|
||||
cl_int end_sample = rtile.start_sample + rtile.num_samples;
|
||||
|
||||
OpenCLDevice::OpenCLSplitPrograms *programs = device->get_split_programs();
|
||||
cl_kernel kernel_data_init = programs->program_split(ustring("path_trace_data_init"));
|
||||
cl_kernel kernel_data_init = device->program_split(ustring("path_trace_data_init"));
|
||||
|
||||
cl_uint start_arg_index =
|
||||
device->kernel_set_args(kernel_data_init,
|
||||
@@ -603,8 +489,6 @@ void OpenCLDevice::opencl_assert_err(cl_int err, const char* where)
|
||||
|
||||
OpenCLDevice::OpenCLDevice(DeviceInfo& info, Stats &stats, Profiler &profiler, bool background)
|
||||
: Device(info, stats, profiler, background),
|
||||
kernel_programs(this),
|
||||
preview_programs(this),
|
||||
memory_manager(this),
|
||||
texture_info(this, "__texture_info", MEM_TEXTURE)
|
||||
{
|
||||
@@ -615,7 +499,6 @@ OpenCLDevice::OpenCLDevice(DeviceInfo& info, Stats &stats, Profiler &profiler, b
|
||||
null_mem = 0;
|
||||
device_initialized = false;
|
||||
textures_need_update = true;
|
||||
use_preview_kernels = !background;
|
||||
|
||||
vector<OpenCLPlatformDevice> usable_devices;
|
||||
OpenCLInfo::get_usable_devices(&usable_devices);
|
||||
@@ -679,16 +562,11 @@ OpenCLDevice::OpenCLDevice(DeviceInfo& info, Stats &stats, Profiler &profiler, b
|
||||
device_initialized = true;
|
||||
|
||||
split_kernel = new OpenCLSplitKernel(this);
|
||||
if (!background) {
|
||||
load_preview_kernels();
|
||||
}
|
||||
}
|
||||
|
||||
OpenCLDevice::~OpenCLDevice()
|
||||
{
|
||||
task_pool.stop();
|
||||
load_required_kernel_task_pool.stop();
|
||||
load_kernel_task_pool.stop();
|
||||
|
||||
memory_manager.free();
|
||||
|
||||
@@ -704,7 +582,7 @@ OpenCLDevice::~OpenCLDevice()
|
||||
bake_program.release();
|
||||
displace_program.release();
|
||||
background_program.release();
|
||||
denoising_program.release();
|
||||
program_split.release();
|
||||
|
||||
if(cqCommandQueue)
|
||||
clReleaseCommandQueue(cqCommandQueue);
|
||||
@@ -771,50 +649,7 @@ bool OpenCLDevice::load_kernels(const DeviceRequestedFeatures& requested_feature
|
||||
if(!opencl_version_check())
|
||||
return false;
|
||||
|
||||
load_required_kernels(requested_features);
|
||||
|
||||
vector<OpenCLProgram*> programs;
|
||||
kernel_programs.load_kernels(programs, requested_features, false);
|
||||
|
||||
if (!requested_features.use_baking && requested_features.use_denoising) {
|
||||
denoising_program = OpenCLProgram(this, "denoising", "filter.cl", get_build_options(requested_features, "denoising"));
|
||||
denoising_program.add_kernel(ustring("filter_divide_shadow"));
|
||||
denoising_program.add_kernel(ustring("filter_get_feature"));
|
||||
denoising_program.add_kernel(ustring("filter_write_feature"));
|
||||
denoising_program.add_kernel(ustring("filter_detect_outliers"));
|
||||
denoising_program.add_kernel(ustring("filter_combine_halves"));
|
||||
denoising_program.add_kernel(ustring("filter_construct_transform"));
|
||||
denoising_program.add_kernel(ustring("filter_nlm_calc_difference"));
|
||||
denoising_program.add_kernel(ustring("filter_nlm_blur"));
|
||||
denoising_program.add_kernel(ustring("filter_nlm_calc_weight"));
|
||||
denoising_program.add_kernel(ustring("filter_nlm_update_output"));
|
||||
denoising_program.add_kernel(ustring("filter_nlm_normalize"));
|
||||
denoising_program.add_kernel(ustring("filter_nlm_construct_gramian"));
|
||||
denoising_program.add_kernel(ustring("filter_finalize"));
|
||||
programs.push_back(&denoising_program);
|
||||
}
|
||||
|
||||
load_required_kernel_task_pool.wait_work();
|
||||
|
||||
/* Parallel compilation of Cycles kernels, this launches multiple
|
||||
* processes to workaround OpenCL frameworks serializing the calls
|
||||
* internally within a single process. */
|
||||
foreach(OpenCLProgram *program, programs) {
|
||||
if (!program->load()) {
|
||||
load_kernel_task_pool.push(function_bind(&OpenCLProgram::compile, program));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void OpenCLDevice::load_required_kernels(const DeviceRequestedFeatures& requested_features)
|
||||
{
|
||||
vector<OpenCLProgram*> programs;
|
||||
base_program = OpenCLProgram(this, "base", "kernel_base.cl", get_build_options(requested_features, "base"));
|
||||
base_program.add_kernel(ustring("convert_to_byte"));
|
||||
base_program.add_kernel(ustring("convert_to_half_float"));
|
||||
base_program.add_kernel(ustring("zero_buffer"));
|
||||
programs.push_back(&base_program);
|
||||
|
||||
if (requested_features.use_true_displacement) {
|
||||
displace_program = OpenCLProgram(this, "displace", "kernel_displace.cl", get_build_options(requested_features, "displace"));
|
||||
@@ -828,89 +663,133 @@ void OpenCLDevice::load_required_kernels(const DeviceRequestedFeatures& requeste
|
||||
programs.push_back(&background_program);
|
||||
}
|
||||
|
||||
bool single_program = OpenCLInfo::use_single_program();
|
||||
|
||||
#define ADD_SPLIT_KERNEL_SINGLE_PROGRAM(kernel_name) program_split.add_kernel(ustring("path_trace_"#kernel_name));
|
||||
#define ADD_SPLIT_KERNEL_SPLIT_PROGRAM(kernel_name) \
|
||||
const string program_name_##kernel_name = "split_"#kernel_name; \
|
||||
program_##kernel_name = \
|
||||
OpenCLDevice::OpenCLProgram(this, \
|
||||
program_name_##kernel_name, \
|
||||
"kernel_"#kernel_name".cl", \
|
||||
get_build_options(requested_features, program_name_##kernel_name)); \
|
||||
program_##kernel_name.add_kernel(ustring("path_trace_"#kernel_name)); \
|
||||
programs.push_back(&program_##kernel_name);
|
||||
|
||||
if (single_program) {
|
||||
program_split = OpenCLDevice::OpenCLProgram(this,
|
||||
"split" ,
|
||||
"kernel_split.cl",
|
||||
get_build_options(requested_features, "split"));
|
||||
|
||||
ADD_SPLIT_KERNEL_SINGLE_PROGRAM(state_buffer_size);
|
||||
ADD_SPLIT_KERNEL_SINGLE_PROGRAM(data_init);
|
||||
ADD_SPLIT_KERNEL_SINGLE_PROGRAM(path_init);
|
||||
ADD_SPLIT_KERNEL_SINGLE_PROGRAM(scene_intersect);
|
||||
ADD_SPLIT_KERNEL_SINGLE_PROGRAM(lamp_emission);
|
||||
ADD_SPLIT_KERNEL_SINGLE_PROGRAM(do_volume);
|
||||
ADD_SPLIT_KERNEL_SINGLE_PROGRAM(queue_enqueue);
|
||||
ADD_SPLIT_KERNEL_SINGLE_PROGRAM(indirect_background);
|
||||
ADD_SPLIT_KERNEL_SINGLE_PROGRAM(shader_setup);
|
||||
ADD_SPLIT_KERNEL_SINGLE_PROGRAM(shader_sort);
|
||||
ADD_SPLIT_KERNEL_SINGLE_PROGRAM(shader_eval);
|
||||
ADD_SPLIT_KERNEL_SINGLE_PROGRAM(holdout_emission_blurring_pathtermination_ao);
|
||||
ADD_SPLIT_KERNEL_SINGLE_PROGRAM(subsurface_scatter);
|
||||
ADD_SPLIT_KERNEL_SINGLE_PROGRAM(direct_lighting);
|
||||
ADD_SPLIT_KERNEL_SINGLE_PROGRAM(shadow_blocked_ao);
|
||||
ADD_SPLIT_KERNEL_SINGLE_PROGRAM(shadow_blocked_dl);
|
||||
ADD_SPLIT_KERNEL_SINGLE_PROGRAM(enqueue_inactive);
|
||||
ADD_SPLIT_KERNEL_SINGLE_PROGRAM(next_iteration_setup);
|
||||
ADD_SPLIT_KERNEL_SINGLE_PROGRAM(indirect_subsurface);
|
||||
ADD_SPLIT_KERNEL_SINGLE_PROGRAM(buffer_update);
|
||||
|
||||
programs.push_back(&program_split);
|
||||
}
|
||||
else {
|
||||
/* Ordered with most complex kernels first, to reduce overall compile time. */
|
||||
ADD_SPLIT_KERNEL_SPLIT_PROGRAM(subsurface_scatter);
|
||||
if (requested_features.use_volume) {
|
||||
ADD_SPLIT_KERNEL_SPLIT_PROGRAM(do_volume);
|
||||
}
|
||||
ADD_SPLIT_KERNEL_SPLIT_PROGRAM(shadow_blocked_dl);
|
||||
ADD_SPLIT_KERNEL_SPLIT_PROGRAM(shadow_blocked_ao);
|
||||
ADD_SPLIT_KERNEL_SPLIT_PROGRAM(holdout_emission_blurring_pathtermination_ao);
|
||||
ADD_SPLIT_KERNEL_SPLIT_PROGRAM(lamp_emission);
|
||||
ADD_SPLIT_KERNEL_SPLIT_PROGRAM(direct_lighting);
|
||||
ADD_SPLIT_KERNEL_SPLIT_PROGRAM(indirect_background);
|
||||
ADD_SPLIT_KERNEL_SPLIT_PROGRAM(shader_eval);
|
||||
|
||||
/* Quick kernels bundled in a single program to reduce overhead of starting
|
||||
* Blender processes. */
|
||||
program_split = OpenCLDevice::OpenCLProgram(this,
|
||||
"split_bundle" ,
|
||||
"kernel_split_bundle.cl",
|
||||
get_build_options(requested_features, "split_bundle"));
|
||||
|
||||
ADD_SPLIT_KERNEL_SINGLE_PROGRAM(data_init);
|
||||
ADD_SPLIT_KERNEL_SINGLE_PROGRAM(state_buffer_size);
|
||||
ADD_SPLIT_KERNEL_SINGLE_PROGRAM(path_init);
|
||||
ADD_SPLIT_KERNEL_SINGLE_PROGRAM(scene_intersect);
|
||||
ADD_SPLIT_KERNEL_SINGLE_PROGRAM(queue_enqueue);
|
||||
ADD_SPLIT_KERNEL_SINGLE_PROGRAM(shader_setup);
|
||||
ADD_SPLIT_KERNEL_SINGLE_PROGRAM(shader_sort);
|
||||
ADD_SPLIT_KERNEL_SINGLE_PROGRAM(enqueue_inactive);
|
||||
ADD_SPLIT_KERNEL_SINGLE_PROGRAM(next_iteration_setup);
|
||||
ADD_SPLIT_KERNEL_SINGLE_PROGRAM(indirect_subsurface);
|
||||
ADD_SPLIT_KERNEL_SINGLE_PROGRAM(buffer_update);
|
||||
programs.push_back(&program_split);
|
||||
}
|
||||
#undef ADD_SPLIT_KERNEL_SPLIT_PROGRAM
|
||||
#undef ADD_SPLIT_KERNEL_SINGLE_PROGRAM
|
||||
|
||||
base_program = OpenCLProgram(this, "base", "kernel_base.cl", get_build_options(requested_features, "base"));
|
||||
base_program.add_kernel(ustring("convert_to_byte"));
|
||||
base_program.add_kernel(ustring("convert_to_half_float"));
|
||||
base_program.add_kernel(ustring("zero_buffer"));
|
||||
programs.push_back(&base_program);
|
||||
|
||||
if (requested_features.use_baking) {
|
||||
bake_program = OpenCLProgram(this, "bake", "kernel_bake.cl", get_build_options(requested_features, "bake"));
|
||||
bake_program.add_kernel(ustring("bake"));
|
||||
programs.push_back(&bake_program);
|
||||
}
|
||||
|
||||
foreach(OpenCLProgram *program, programs) {
|
||||
if (!program->load()) {
|
||||
load_required_kernel_task_pool.push(function_bind(&OpenCLProgram::compile, program));
|
||||
}
|
||||
}
|
||||
}
|
||||
denoising_program = OpenCLProgram(this, "denoising", "filter.cl", get_build_options(requested_features, "denoising"));
|
||||
denoising_program.add_kernel(ustring("filter_divide_shadow"));
|
||||
denoising_program.add_kernel(ustring("filter_get_feature"));
|
||||
denoising_program.add_kernel(ustring("filter_write_feature"));
|
||||
denoising_program.add_kernel(ustring("filter_detect_outliers"));
|
||||
denoising_program.add_kernel(ustring("filter_combine_halves"));
|
||||
denoising_program.add_kernel(ustring("filter_construct_transform"));
|
||||
denoising_program.add_kernel(ustring("filter_nlm_calc_difference"));
|
||||
denoising_program.add_kernel(ustring("filter_nlm_blur"));
|
||||
denoising_program.add_kernel(ustring("filter_nlm_calc_weight"));
|
||||
denoising_program.add_kernel(ustring("filter_nlm_update_output"));
|
||||
denoising_program.add_kernel(ustring("filter_nlm_normalize"));
|
||||
denoising_program.add_kernel(ustring("filter_nlm_construct_gramian"));
|
||||
denoising_program.add_kernel(ustring("filter_finalize"));
|
||||
programs.push_back(&denoising_program);
|
||||
|
||||
void OpenCLDevice::load_preview_kernels()
|
||||
{
|
||||
DeviceRequestedFeatures no_features;
|
||||
vector<OpenCLProgram*> programs;
|
||||
preview_programs.load_kernels(programs, no_features, true);
|
||||
/* Parallel compilation of Cycles kernels, this launches multiple
|
||||
* processes to workaround OpenCL frameworks serializing the calls
|
||||
* internally within a single process. */
|
||||
TaskPool task_pool;
|
||||
foreach(OpenCLProgram *program, programs) {
|
||||
task_pool.push(function_bind(&OpenCLProgram::load, program));
|
||||
}
|
||||
task_pool.wait_work();
|
||||
|
||||
foreach(OpenCLProgram *program, programs) {
|
||||
if (!program->load()) {
|
||||
load_required_kernel_task_pool.push(function_bind(&OpenCLProgram::compile, program));
|
||||
VLOG(2) << program->get_log();
|
||||
if(!program->is_loaded()) {
|
||||
program->report_error();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool OpenCLDevice::wait_for_availability(const DeviceRequestedFeatures& requested_features)
|
||||
{
|
||||
if (background) {
|
||||
load_kernel_task_pool.wait_work();
|
||||
use_preview_kernels = false;
|
||||
}
|
||||
else {
|
||||
/* We use a device setting to determine to load preview kernels or not
|
||||
* Better to check on device level than per kernel as mixing preview and
|
||||
* non-preview kernels does not work due to different data types */
|
||||
if (use_preview_kernels) {
|
||||
use_preview_kernels = !load_kernel_task_pool.finished();
|
||||
}
|
||||
}
|
||||
return split_kernel->load_kernels(requested_features);
|
||||
}
|
||||
|
||||
OpenCLDevice::OpenCLSplitPrograms* OpenCLDevice::get_split_programs()
|
||||
{
|
||||
return use_preview_kernels?&preview_programs:&kernel_programs;
|
||||
}
|
||||
|
||||
DeviceKernelStatus OpenCLDevice::get_active_kernel_switch_state()
|
||||
{
|
||||
/* Do not switch kernels for background renderings
|
||||
* We do foreground rendering but use the preview kernels
|
||||
* Check for the optimized kernels
|
||||
*
|
||||
* This works also the other way around, where we are using
|
||||
* optimized kernels but new ones are being compiled due
|
||||
* to other features that are needed */
|
||||
if (background) {
|
||||
/* The if-statements below would find the same result,
|
||||
* But as the `finished` method uses a mutex we added
|
||||
* this as an early exit */
|
||||
return DEVICE_KERNEL_USING_FEATURE_KERNEL;
|
||||
}
|
||||
|
||||
bool other_kernels_finished = load_kernel_task_pool.finished();
|
||||
if (use_preview_kernels) {
|
||||
if (other_kernels_finished) {
|
||||
return DEVICE_KERNEL_FEATURE_KERNEL_AVAILABLE;
|
||||
}
|
||||
else {
|
||||
return DEVICE_KERNEL_WAITING_FOR_FEATURE_KERNEL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (other_kernels_finished) {
|
||||
return DEVICE_KERNEL_USING_FEATURE_KERNEL;
|
||||
}
|
||||
else {
|
||||
return DEVICE_KERNEL_FEATURE_KERNEL_INVALID;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OpenCLDevice::mem_alloc(device_memory& mem)
|
||||
{
|
||||
if(mem.name) {
|
||||
@@ -1012,7 +891,6 @@ void OpenCLDevice::mem_copy_from(device_memory& mem, int y, int w, int h, int el
|
||||
|
||||
void OpenCLDevice::mem_zero_kernel(device_ptr mem, size_t size)
|
||||
{
|
||||
base_program.wait_for_availability();
|
||||
cl_kernel ckZeroBuffer = base_program(ustring("zero_buffer"));
|
||||
|
||||
size_t global_size[] = {1024, 1024};
|
||||
@@ -1352,13 +1230,13 @@ void OpenCLDevice::thread_run(DeviceTask *task)
|
||||
|
||||
/* Complete kernel execution before release tile. */
|
||||
/* This helps in multi-device render;
|
||||
* The device that reaches the critical-section function
|
||||
* release_tile waits (stalling other devices from entering
|
||||
* release_tile) for all kernels to complete. If device1 (a
|
||||
* slow-render device) reaches release_tile first then it would
|
||||
* stall device2 (a fast-render device) from proceeding to render
|
||||
* next tile.
|
||||
*/
|
||||
* The device that reaches the critical-section function
|
||||
* release_tile waits (stalling other devices from entering
|
||||
* release_tile) for all kernels to complete. If device1 (a
|
||||
* slow-render device) reaches release_tile first then it would
|
||||
* stall device2 (a fast-render device) from proceeding to render
|
||||
* next tile.
|
||||
*/
|
||||
clFinish(cqCommandQueue);
|
||||
}
|
||||
else if(tile.task == RenderTile::DENOISE) {
|
||||
@@ -1840,15 +1718,17 @@ void OpenCLDevice::shader(DeviceTask& task)
|
||||
cl_int d_shader_w = task.shader_w;
|
||||
cl_int d_offset = task.offset;
|
||||
|
||||
OpenCLDevice::OpenCLProgram *program = &background_program;
|
||||
cl_kernel kernel;
|
||||
|
||||
if(task.shader_eval_type >= SHADER_EVAL_BAKE) {
|
||||
program = &bake_program;
|
||||
kernel = bake_program(ustring("bake"));
|
||||
}
|
||||
else if(task.shader_eval_type == SHADER_EVAL_DISPLACE) {
|
||||
program = &displace_program;
|
||||
kernel = displace_program(ustring("displace"));
|
||||
}
|
||||
else {
|
||||
kernel = background_program(ustring("background"));
|
||||
}
|
||||
program->wait_for_availability();
|
||||
cl_kernel kernel = (*program)();
|
||||
|
||||
cl_uint start_arg_index =
|
||||
kernel_set_args(kernel,
|
||||
|
@@ -243,18 +243,6 @@ string OpenCLCache::get_kernel_md5()
|
||||
return self.kernel_md5;
|
||||
}
|
||||
|
||||
static string get_program_source(const string& kernel_file)
|
||||
{
|
||||
string source = "#include \"kernel/kernels/opencl/" + kernel_file + "\"\n";
|
||||
/* We compile kernels consisting of many files. unfortunately OpenCL
|
||||
* kernel caches do not seem to recognize changes in included files.
|
||||
* so we force recompile on changes by adding the md5 hash of all files.
|
||||
*/
|
||||
source = path_source_replace_includes(source, path_get("source"));
|
||||
source += "\n// " + util_md5_string(source) + "\n";
|
||||
return source;
|
||||
}
|
||||
|
||||
OpenCLDevice::OpenCLProgram::OpenCLProgram(OpenCLDevice *device,
|
||||
const string& program_name,
|
||||
const string& kernel_file,
|
||||
@@ -267,7 +255,6 @@ OpenCLDevice::OpenCLProgram::OpenCLProgram(OpenCLDevice *device,
|
||||
use_stdout(use_stdout)
|
||||
{
|
||||
loaded = false;
|
||||
needs_compiling = true;
|
||||
program = NULL;
|
||||
}
|
||||
|
||||
@@ -356,7 +343,13 @@ bool OpenCLDevice::OpenCLProgram::build_kernel(const string *debug_src)
|
||||
|
||||
bool OpenCLDevice::OpenCLProgram::compile_kernel(const string *debug_src)
|
||||
{
|
||||
string source = get_program_source(kernel_file);
|
||||
string source = "#include \"kernel/kernels/opencl/" + kernel_file + "\"\n";
|
||||
/* We compile kernels consisting of many files. unfortunately OpenCL
|
||||
* kernel caches do not seem to recognize changes in included files.
|
||||
* so we force recompile on changes by adding the md5 hash of all files.
|
||||
*/
|
||||
source = path_source_replace_includes(source, path_get("source"));
|
||||
source += "\n// " + util_md5_string(source) + "\n";
|
||||
|
||||
if(debug_src) {
|
||||
path_write_text(*debug_src, source);
|
||||
@@ -480,7 +473,8 @@ bool device_opencl_compile_kernel(const vector<string>& parameters)
|
||||
return false;
|
||||
}
|
||||
|
||||
string source = get_program_source(kernel_file);
|
||||
string source = "#include \"kernel/kernels/opencl/" + kernel_file + "\" // " + path_files_md5_hash(path_get("kernel")) + "\n";
|
||||
source = path_source_replace_includes(source, path_get("source"));
|
||||
size_t source_len = source.size();
|
||||
const char *source_str = source.c_str();
|
||||
cl_program program = clCreateProgramWithSource(context, 1, &source_str, &source_len, &err);
|
||||
@@ -554,55 +548,12 @@ bool OpenCLDevice::OpenCLProgram::save_binary(const string& clbin)
|
||||
return path_write_binary(clbin, binary);
|
||||
}
|
||||
|
||||
bool OpenCLDevice::OpenCLProgram::load()
|
||||
{
|
||||
loaded = false;
|
||||
string device_md5 = device->device_md5_hash(kernel_build_options);
|
||||
|
||||
/* Try to use cached kernel. */
|
||||
thread_scoped_lock cache_locker;
|
||||
ustring cache_key(program_name + device_md5);
|
||||
program = device->load_cached_kernel(cache_key,
|
||||
cache_locker);
|
||||
if (!program) {
|
||||
add_log(string("OpenCL program ") + program_name + " not found in cache.", true);
|
||||
|
||||
/* need to create source to get md5 */
|
||||
string source = get_program_source(kernel_file);
|
||||
|
||||
string basename = "cycles_kernel_" + program_name + "_" + device_md5 + "_" + util_md5_string(source);
|
||||
basename = path_cache_get(path_join("kernels", basename));
|
||||
string clbin = basename + ".clbin";
|
||||
|
||||
/* If binary kernel exists already, try use it. */
|
||||
if(path_exists(clbin) && load_binary(clbin)) {
|
||||
/* Kernel loaded from binary, nothing to do. */
|
||||
add_log(string("Loaded program from ") + clbin + ".", true);
|
||||
|
||||
/* Cache the program. */
|
||||
device->store_cached_kernel(program,
|
||||
cache_key,
|
||||
cache_locker);
|
||||
}
|
||||
else {
|
||||
add_log(string("OpenCL program ") + program_name + " not found on disk.", true);
|
||||
cache_locker.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
if (program) {
|
||||
create_kernels();
|
||||
loaded = true;
|
||||
needs_compiling = false;
|
||||
}
|
||||
|
||||
return loaded;
|
||||
}
|
||||
|
||||
void OpenCLDevice::OpenCLProgram::compile()
|
||||
void OpenCLDevice::OpenCLProgram::load()
|
||||
{
|
||||
assert(device);
|
||||
|
||||
loaded = false;
|
||||
|
||||
string device_md5 = device->device_md5_hash(kernel_build_options);
|
||||
|
||||
/* Try to use cached kernel. */
|
||||
@@ -611,13 +562,12 @@ void OpenCLDevice::OpenCLProgram::compile()
|
||||
program = device->load_cached_kernel(cache_key,
|
||||
cache_locker);
|
||||
|
||||
if (!program)
|
||||
{
|
||||
|
||||
if(!program) {
|
||||
add_log(string("OpenCL program ") + program_name + " not found in cache.", true);
|
||||
|
||||
/* need to create source to get md5 */
|
||||
string source = get_program_source(kernel_file);
|
||||
string source = "#include \"kernel/kernels/opencl/" + kernel_file + "\"\n";
|
||||
source = path_source_replace_includes(source, path_get("source"));
|
||||
|
||||
string basename = "cycles_kernel_" + program_name + "_" + device_md5 + "_" + util_md5_string(source);
|
||||
basename = path_cache_get(path_join("kernels", basename));
|
||||
@@ -632,38 +582,49 @@ void OpenCLDevice::OpenCLProgram::compile()
|
||||
}
|
||||
|
||||
/* If binary kernel exists already, try use it. */
|
||||
if(compile_separate(clbin)) {
|
||||
add_log(string("Built and loaded program from ") + clbin + ".", true);
|
||||
loaded = true;
|
||||
if(path_exists(clbin) && load_binary(clbin)) {
|
||||
/* Kernel loaded from binary, nothing to do. */
|
||||
add_log(string("Loaded program from ") + clbin + ".", true);
|
||||
}
|
||||
else {
|
||||
add_log(string("Separate-process building of ") + clbin + " failed, will fall back to regular building.", true);
|
||||
add_log(string("Kernel file ") + clbin + " either doesn't exist or failed to be loaded by driver.", true);
|
||||
if(!path_exists(clbin)) {
|
||||
if(compile_separate(clbin)) {
|
||||
add_log(string("Built and loaded program from ") + clbin + ".", true);
|
||||
loaded = true;
|
||||
}
|
||||
else {
|
||||
add_log(string("Separate-process building of ") + clbin + " failed, will fall back to regular building.", true);
|
||||
|
||||
/* If does not exist or loading binary failed, compile kernel. */
|
||||
if(!compile_kernel(debug_src)) {
|
||||
needs_compiling = false;
|
||||
return;
|
||||
/* If does not exist or loading binary failed, compile kernel. */
|
||||
if(!compile_kernel(debug_src)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Save binary for reuse. */
|
||||
if(!save_binary(clbin)) {
|
||||
add_log(string("Saving compiled OpenCL kernel to ") + clbin + " failed!", true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Save binary for reuse. */
|
||||
if(!save_binary(clbin)) {
|
||||
add_log(string("Saving compiled OpenCL kernel to ") + clbin + " failed!", true);
|
||||
else {
|
||||
add_log(string("Kernel file ") + clbin + "exists, but failed to be loaded by driver.", true);
|
||||
/* Fall back to compiling. */
|
||||
if(!compile_kernel(debug_src)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Cache the program. */
|
||||
device->store_cached_kernel(program,
|
||||
cache_key,
|
||||
cache_locker);
|
||||
cache_key,
|
||||
cache_locker);
|
||||
}
|
||||
else {
|
||||
add_log(string("Found cached OpenCL program ") + program_name + ".", true);
|
||||
}
|
||||
|
||||
create_kernels();
|
||||
needs_compiling = false;
|
||||
loaded = true;
|
||||
}
|
||||
|
||||
void OpenCLDevice::OpenCLProgram::create_kernels()
|
||||
{
|
||||
for(map<ustring, cl_kernel>::iterator kernel = kernels.begin(); kernel != kernels.end(); ++kernel) {
|
||||
assert(kernel->second == NULL);
|
||||
cl_int ciErr;
|
||||
@@ -674,15 +635,8 @@ void OpenCLDevice::OpenCLProgram::create_kernels()
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool OpenCLDevice::OpenCLProgram::wait_for_availability()
|
||||
{
|
||||
add_log(string("Waiting for availability of ") + program_name + ".", true);
|
||||
while (needs_compiling) {
|
||||
time_sleep(0.1);
|
||||
}
|
||||
return loaded;
|
||||
loaded = true;
|
||||
}
|
||||
|
||||
void OpenCLDevice::OpenCLProgram::report_error()
|
||||
@@ -737,6 +691,28 @@ bool OpenCLInfo::use_debug()
|
||||
return DebugFlags().opencl.debug;
|
||||
}
|
||||
|
||||
bool OpenCLInfo::use_single_program()
|
||||
{
|
||||
return DebugFlags().opencl.single_program;
|
||||
}
|
||||
|
||||
bool OpenCLInfo::kernel_use_advanced_shading(const string& platform)
|
||||
{
|
||||
/* keep this in sync with kernel_types.h! */
|
||||
if(platform == "NVIDIA CUDA")
|
||||
return true;
|
||||
else if(platform == "Apple")
|
||||
return true;
|
||||
else if(platform == "AMD Accelerated Parallel Processing")
|
||||
return true;
|
||||
else if(platform == "Intel(R) OpenCL")
|
||||
return true;
|
||||
/* Make sure officially unsupported OpenCL platforms
|
||||
* does not set up to use advanced shading.
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
|
||||
bool OpenCLInfo::device_supported(const string& platform_name,
|
||||
const cl_device_id device_id)
|
||||
{
|
||||
|
@@ -41,6 +41,7 @@ set(SRC_OPENCL_KERNELS
|
||||
kernels/opencl/kernel_displace.cl
|
||||
kernels/opencl/kernel_background.cl
|
||||
kernels/opencl/kernel_state_buffer_size.cl
|
||||
kernels/opencl/kernel_split.cl
|
||||
kernels/opencl/kernel_split_bundle.cl
|
||||
kernels/opencl/kernel_data_init.cl
|
||||
kernels/opencl/kernel_path_init.cl
|
||||
@@ -346,11 +347,11 @@ if(WITH_CYCLES_CUDA_BINARIES)
|
||||
set(CUDA_VERSION "${CUDA_VERSION_MAJOR}${CUDA_VERSION_MINOR}")
|
||||
|
||||
# warn for other versions
|
||||
if(CUDA_VERSION MATCHES "101")
|
||||
if(CUDA_VERSION MATCHES "90" OR CUDA_VERSION MATCHES "91" OR CUDA_VERSION MATCHES "100")
|
||||
else()
|
||||
message(WARNING
|
||||
"CUDA version ${CUDA_VERSION_MAJOR}.${CUDA_VERSION_MINOR} detected, "
|
||||
"build may succeed but only CUDA 10.1 is officially supported")
|
||||
"build may succeed but only CUDA 9.0, 9.1 and 10.0 are officially supported")
|
||||
endif()
|
||||
|
||||
# build for each arch
|
||||
@@ -400,17 +401,29 @@ if(WITH_CYCLES_CUDA_BINARIES)
|
||||
set(cuda_flags ${cuda_flags} -D __KERNEL_DEBUG__)
|
||||
endif()
|
||||
|
||||
if(WITH_CYCLES_CUBIN_COMPILER)
|
||||
# Workaround to build only sm_7x kernels with CUDA 10, until
|
||||
# older kernels work well with this version.
|
||||
if(DEFINED CUDA10_NVCC_EXECUTABLE AND (${arch} MATCHES "sm_7."))
|
||||
set(with_cubin_compiler OFF)
|
||||
set(cuda_nvcc_executable "${CUDA10_NVCC_EXECUTABLE}")
|
||||
set(cuda_toolkit_root_dir "${CUDA10_TOOLKIT_ROOT_DIR}")
|
||||
else()
|
||||
set(with_cubin_compiler ${WITH_CYCLES_CUBIN_COMPILER})
|
||||
set(cuda_nvcc_executable "${CUDA_NVCC_EXECUTABLE}")
|
||||
set(cuda_toolkit_root_dir "${CUDA_TOOLKIT_ROOT_DIR}")
|
||||
endif()
|
||||
|
||||
if(with_cubin_compiler)
|
||||
string(SUBSTRING ${arch} 3 -1 CUDA_ARCH)
|
||||
|
||||
# Needed to find libnvrtc-builtins.so. Can't do it from inside
|
||||
# cycles_cubin_cc since the env variable is read before main()
|
||||
if(APPLE)
|
||||
set(CUBIN_CC_ENV ${CMAKE_COMMAND}
|
||||
-E env DYLD_LIBRARY_PATH="${CUDA_TOOLKIT_ROOT_DIR}/lib")
|
||||
-E env DYLD_LIBRARY_PATH="${cuda_toolkit_root_dir}/lib")
|
||||
elseif(UNIX)
|
||||
set(CUBIN_CC_ENV ${CMAKE_COMMAND}
|
||||
-E env LD_LIBRARY_PATH="${CUDA_TOOLKIT_ROOT_DIR}/lib64")
|
||||
-E env LD_LIBRARY_PATH="${cuda_toolkit_root_dir}/lib64")
|
||||
endif()
|
||||
|
||||
add_custom_command(
|
||||
@@ -421,12 +434,12 @@ if(WITH_CYCLES_CUDA_BINARIES)
|
||||
-i ${CMAKE_CURRENT_SOURCE_DIR}${cuda_kernel_src}
|
||||
${cuda_flags}
|
||||
-v
|
||||
-cuda-toolkit-dir "${CUDA_TOOLKIT_ROOT_DIR}"
|
||||
-cuda-toolkit-dir "${cuda_toolkit_root_dir}"
|
||||
DEPENDS ${kernel_sources} cycles_cubin_cc)
|
||||
else()
|
||||
add_custom_command(
|
||||
OUTPUT ${cuda_cubin}
|
||||
COMMAND ${CUDA_NVCC_EXECUTABLE}
|
||||
COMMAND ${cuda_nvcc_executable}
|
||||
-arch=${arch}
|
||||
${CUDA_NVCC_FLAGS}
|
||||
--cubin
|
||||
@@ -445,7 +458,7 @@ if(WITH_CYCLES_CUDA_BINARIES)
|
||||
foreach(arch ${CYCLES_CUDA_BINARIES_ARCH})
|
||||
if(${arch} MATCHES "sm_2.")
|
||||
message(STATUS "CUDA binaries for ${arch} are no longer supported, skipped.")
|
||||
elseif(${arch} MATCHES "sm_7." AND ${CUDA_VERSION} LESS 100)
|
||||
elseif(${arch} MATCHES "sm_7." AND (${CUDA_VERSION} LESS 100) AND (NOT DEFINED CUDA10_NVCC_EXECUTABLE))
|
||||
message(STATUS "CUDA binaries for ${arch} require CUDA 10.0+, skipped.")
|
||||
else()
|
||||
# Compile regular kernel
|
||||
|
@@ -253,7 +253,6 @@ ccl_device_intersect bool scene_intersect_local(KernelGlobals *kg,
|
||||
PROFILING_INIT(kg, PROFILING_INTERSECT_LOCAL);
|
||||
|
||||
if(!scene_intersect_valid(&ray)) {
|
||||
local_isect->num_hits = 0;
|
||||
return false;
|
||||
}
|
||||
#ifdef __EMBREE__
|
||||
|
@@ -95,16 +95,14 @@ ccl_device_inline void kernel_filter_finalize(int x, int y,
|
||||
}
|
||||
|
||||
/* The weighted average of pixel colors (essentially, the NLM-filtered image).
|
||||
* In case the solution of the linear model fails due to numerical issues or
|
||||
* returns non-sensical negative values, fall back to this value. */
|
||||
* In case the solution of the linear model fails due to numerical issues,
|
||||
* fall back to this value. */
|
||||
float3 mean_color = XtWY[0]/XtWX[0];
|
||||
|
||||
math_trimatrix_vec3_solve(XtWX, XtWY, (*rank)+1, stride);
|
||||
|
||||
float3 final_color = XtWY[0];
|
||||
if(!isfinite3_safe(final_color) ||
|
||||
(final_color.x < -0.01f || final_color.y < -0.01f || final_color.z < -0.01f))
|
||||
{
|
||||
if(!isfinite3_safe(final_color)) {
|
||||
final_color = mean_color;
|
||||
}
|
||||
|
||||
|
@@ -87,45 +87,6 @@ ccl_device float curve_attribute_float(KernelGlobals *kg, const ShaderData *sd,
|
||||
}
|
||||
}
|
||||
|
||||
ccl_device float2 curve_attribute_float2(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float2 *dx, float2 *dy)
|
||||
{
|
||||
if(desc.element == ATTR_ELEMENT_CURVE) {
|
||||
/* idea: we can't derive any useful differentials here, but for tiled
|
||||
* mipmap image caching it would be useful to avoid reading the highest
|
||||
* detail level always. maybe a derivative based on the hair density
|
||||
* could be computed somehow? */
|
||||
#ifdef __RAY_DIFFERENTIALS__
|
||||
if(dx) *dx = make_float2(0.0f, 0.0f);
|
||||
if(dy) *dy = make_float2(0.0f, 0.0f);
|
||||
#endif
|
||||
|
||||
return kernel_tex_fetch(__attributes_float2, desc.offset + sd->prim);
|
||||
}
|
||||
else if(desc.element == ATTR_ELEMENT_CURVE_KEY || desc.element == ATTR_ELEMENT_CURVE_KEY_MOTION) {
|
||||
float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
|
||||
int k0 = __float_as_int(curvedata.x) + PRIMITIVE_UNPACK_SEGMENT(sd->type);
|
||||
int k1 = k0 + 1;
|
||||
|
||||
float2 f0 = kernel_tex_fetch(__attributes_float2, desc.offset + k0);
|
||||
float2 f1 = kernel_tex_fetch(__attributes_float2, desc.offset + k1);
|
||||
|
||||
#ifdef __RAY_DIFFERENTIALS__
|
||||
if(dx) *dx = sd->du.dx*(f1 - f0);
|
||||
if(dy) *dy = make_float2(0.0f, 0.0f);
|
||||
#endif
|
||||
|
||||
return (1.0f - sd->u)*f0 + sd->u*f1;
|
||||
}
|
||||
else {
|
||||
#ifdef __RAY_DIFFERENTIALS__
|
||||
if(dx) *dx = make_float2(0.0f, 0.0f);
|
||||
if(dy) *dy = make_float2(0.0f, 0.0f);
|
||||
#endif
|
||||
|
||||
return make_float2(0.0f, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
ccl_device float3 curve_attribute_float3(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float3 *dx, float3 *dy)
|
||||
{
|
||||
if(desc.element == ATTR_ELEMENT_CURVE) {
|
||||
|
@@ -284,33 +284,6 @@ ccl_device float patch_eval_float(KernelGlobals *kg, const ShaderData *sd, int o
|
||||
return val;
|
||||
}
|
||||
|
||||
ccl_device float2 patch_eval_float2(KernelGlobals *kg, const ShaderData *sd, int offset,
|
||||
int patch, float u, float v, int channel,
|
||||
float2 *du, float2 *dv)
|
||||
{
|
||||
int indices[PATCH_MAX_CONTROL_VERTS];
|
||||
float weights[PATCH_MAX_CONTROL_VERTS];
|
||||
float weights_du[PATCH_MAX_CONTROL_VERTS];
|
||||
float weights_dv[PATCH_MAX_CONTROL_VERTS];
|
||||
|
||||
int num_control = patch_eval_control_verts(kg, sd->object, patch, u, v, channel,
|
||||
indices, weights, weights_du, weights_dv);
|
||||
|
||||
float2 val = make_float2(0.0f, 0.0f);
|
||||
if(du) *du = make_float2(0.0f, 0.0f);
|
||||
if(dv) *dv = make_float2(0.0f, 0.0f);
|
||||
|
||||
for(int i = 0; i < num_control; i++) {
|
||||
float2 v = kernel_tex_fetch(__attributes_float2, offset + indices[i]);
|
||||
|
||||
val += v * weights[i];
|
||||
if(du) *du += v * weights_du[i];
|
||||
if(dv) *dv += v * weights_dv[i];
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
ccl_device float3 patch_eval_float3(KernelGlobals *kg, const ShaderData *sd, int offset,
|
||||
int patch, float u, float v, int channel,
|
||||
float3 *du, float3 *dv)
|
||||
|
@@ -89,37 +89,6 @@ ccl_device_inline float primitive_volume_attribute_float(KernelGlobals *kg,
|
||||
}
|
||||
#endif
|
||||
|
||||
ccl_device_inline float2 primitive_attribute_float2(KernelGlobals *kg,
|
||||
const ShaderData *sd,
|
||||
const AttributeDescriptor desc,
|
||||
float2 *dx, float2 *dy)
|
||||
{
|
||||
if(sd->type & PRIMITIVE_ALL_TRIANGLE) {
|
||||
if(subd_triangle_patch(kg, sd) == ~0)
|
||||
return triangle_attribute_float2(kg, sd, desc, dx, dy);
|
||||
else
|
||||
return subd_triangle_attribute_float2(kg, sd, desc, dx, dy);
|
||||
}
|
||||
#ifdef __HAIR__
|
||||
else if(sd->type & PRIMITIVE_ALL_CURVE) {
|
||||
return curve_attribute_float2(kg, sd, desc, dx, dy);
|
||||
}
|
||||
#endif
|
||||
#ifdef __VOLUME__
|
||||
else if(sd->object != OBJECT_NONE && desc.element == ATTR_ELEMENT_VOXEL) {
|
||||
kernel_assert(0);
|
||||
if(dx) *dx = make_float2(0.0f, 0.0f);
|
||||
if(dy) *dy = make_float2(0.0f, 0.0f);
|
||||
return make_float2(0.0f, 0.0f);
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
if(dx) *dx = make_float2(0.0f, 0.0f);
|
||||
if(dy) *dy = make_float2(0.0f, 0.0f);
|
||||
return make_float2(0.0f, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
ccl_device_inline float3 primitive_attribute_float3(KernelGlobals *kg,
|
||||
const ShaderData *sd,
|
||||
const AttributeDescriptor desc,
|
||||
@@ -150,29 +119,6 @@ ccl_device_inline float3 primitive_attribute_float3(KernelGlobals *kg,
|
||||
}
|
||||
}
|
||||
|
||||
ccl_device_inline float2 primitive_surface_attribute_float2(KernelGlobals *kg,
|
||||
const ShaderData *sd,
|
||||
const AttributeDescriptor desc,
|
||||
float2 *dx, float2 *dy)
|
||||
{
|
||||
if(sd->type & PRIMITIVE_ALL_TRIANGLE) {
|
||||
if(subd_triangle_patch(kg, sd) == ~0)
|
||||
return triangle_attribute_float2(kg, sd, desc, dx, dy);
|
||||
else
|
||||
return subd_triangle_attribute_float2(kg, sd, desc, dx, dy);
|
||||
}
|
||||
#ifdef __HAIR__
|
||||
else if(sd->type & PRIMITIVE_ALL_CURVE) {
|
||||
return curve_attribute_float2(kg, sd, desc, dx, dy);
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
if(dx) *dx = make_float2(0.0f, 0.0f);
|
||||
if(dy) *dy = make_float2(0.0f, 0.0f);
|
||||
return make_float2(0.0f, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
ccl_device_inline float3 primitive_surface_attribute_float3(KernelGlobals *kg,
|
||||
const ShaderData *sd,
|
||||
const AttributeDescriptor desc,
|
||||
@@ -219,8 +165,9 @@ ccl_device_inline float3 primitive_uv(KernelGlobals *kg, ShaderData *sd)
|
||||
if(desc.offset == ATTR_STD_NOT_FOUND)
|
||||
return make_float3(0.0f, 0.0f, 0.0f);
|
||||
|
||||
float2 uv = primitive_surface_attribute_float2(kg, sd, desc, NULL, NULL);
|
||||
return make_float3(uv.x, uv.y, 1.0f);
|
||||
float3 uv = primitive_surface_attribute_float3(kg, sd, desc, NULL, NULL);
|
||||
uv.z = 1.0f;
|
||||
return uv;
|
||||
}
|
||||
|
||||
/* Ptex coordinates */
|
||||
|
@@ -216,128 +216,6 @@ ccl_device_noinline float subd_triangle_attribute_float(KernelGlobals *kg, const
|
||||
}
|
||||
}
|
||||
|
||||
ccl_device_noinline float2 subd_triangle_attribute_float2(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float2 *dx, float2 *dy)
|
||||
{
|
||||
int patch = subd_triangle_patch(kg, sd);
|
||||
|
||||
#ifdef __PATCH_EVAL__
|
||||
if(desc.flags & ATTR_SUBDIVIDED) {
|
||||
float2 uv[3];
|
||||
subd_triangle_patch_uv(kg, sd, uv);
|
||||
|
||||
float2 dpdu = uv[0] - uv[2];
|
||||
float2 dpdv = uv[1] - uv[2];
|
||||
|
||||
/* p is [s, t] */
|
||||
float2 p = dpdu * sd->u + dpdv * sd->v + uv[2];
|
||||
|
||||
float2 a, dads, dadt;
|
||||
|
||||
a = patch_eval_float2(kg, sd, desc.offset, patch, p.x, p.y, 0, &dads, &dadt);
|
||||
|
||||
#ifdef __RAY_DIFFERENTIALS__
|
||||
if(dx || dy) {
|
||||
float dsdu = dpdu.x;
|
||||
float dtdu = dpdu.y;
|
||||
float dsdv = dpdv.x;
|
||||
float dtdv = dpdv.y;
|
||||
|
||||
if(dx) {
|
||||
float dudx = sd->du.dx;
|
||||
float dvdx = sd->dv.dx;
|
||||
|
||||
float dsdx = dsdu*dudx + dsdv*dvdx;
|
||||
float dtdx = dtdu*dudx + dtdv*dvdx;
|
||||
|
||||
*dx = dads*dsdx + dadt*dtdx;
|
||||
}
|
||||
if(dy) {
|
||||
float dudy = sd->du.dy;
|
||||
float dvdy = sd->dv.dy;
|
||||
|
||||
float dsdy = dsdu*dudy + dsdv*dvdy;
|
||||
float dtdy = dtdu*dudy + dtdv*dvdy;
|
||||
|
||||
*dy = dads*dsdy + dadt*dtdy;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return a;
|
||||
}
|
||||
else
|
||||
#endif /* __PATCH_EVAL__ */
|
||||
if(desc.element == ATTR_ELEMENT_FACE) {
|
||||
if(dx) *dx = make_float2(0.0f, 0.0f);
|
||||
if(dy) *dy = make_float2(0.0f, 0.0f);
|
||||
|
||||
return kernel_tex_fetch(__attributes_float2, desc.offset + subd_triangle_patch_face(kg, patch));
|
||||
}
|
||||
else if(desc.element == ATTR_ELEMENT_VERTEX || desc.element == ATTR_ELEMENT_VERTEX_MOTION) {
|
||||
float2 uv[3];
|
||||
subd_triangle_patch_uv(kg, sd, uv);
|
||||
|
||||
uint4 v = subd_triangle_patch_indices(kg, patch);
|
||||
|
||||
float2 f0 = kernel_tex_fetch(__attributes_float2, desc.offset + v.x);
|
||||
float2 f1 = kernel_tex_fetch(__attributes_float2, desc.offset + v.y);
|
||||
float2 f2 = kernel_tex_fetch(__attributes_float2, desc.offset + v.z);
|
||||
float2 f3 = kernel_tex_fetch(__attributes_float2, desc.offset + v.w);
|
||||
|
||||
if(subd_triangle_patch_num_corners(kg, patch) != 4) {
|
||||
f1 = (f1+f0)*0.5f;
|
||||
f3 = (f3+f0)*0.5f;
|
||||
}
|
||||
|
||||
float2 a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y);
|
||||
float2 b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y);
|
||||
float2 c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
|
||||
|
||||
#ifdef __RAY_DIFFERENTIALS__
|
||||
if(dx) *dx = sd->du.dx*a + sd->dv.dx*b - (sd->du.dx + sd->dv.dx)*c;
|
||||
if(dy) *dy = sd->du.dy*a + sd->dv.dy*b - (sd->du.dy + sd->dv.dy)*c;
|
||||
#endif
|
||||
|
||||
return sd->u*a + sd->v*b + (1.0f - sd->u - sd->v)*c;
|
||||
}
|
||||
else if(desc.element == ATTR_ELEMENT_CORNER) {
|
||||
float2 uv[3];
|
||||
subd_triangle_patch_uv(kg, sd, uv);
|
||||
|
||||
int corners[4];
|
||||
subd_triangle_patch_corners(kg, patch, corners);
|
||||
|
||||
float2 f0, f1, f2, f3;
|
||||
|
||||
f0 = kernel_tex_fetch(__attributes_float2, corners[0] + desc.offset);
|
||||
f1 = kernel_tex_fetch(__attributes_float2, corners[1] + desc.offset);
|
||||
f2 = kernel_tex_fetch(__attributes_float2, corners[2] + desc.offset);
|
||||
f3 = kernel_tex_fetch(__attributes_float2, corners[3] + desc.offset);
|
||||
|
||||
if(subd_triangle_patch_num_corners(kg, patch) != 4) {
|
||||
f1 = (f1+f0)*0.5f;
|
||||
f3 = (f3+f0)*0.5f;
|
||||
}
|
||||
|
||||
float2 a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y);
|
||||
float2 b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y);
|
||||
float2 c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
|
||||
|
||||
#ifdef __RAY_DIFFERENTIALS__
|
||||
if(dx) *dx = sd->du.dx*a + sd->dv.dx*b - (sd->du.dx + sd->dv.dx)*c;
|
||||
if(dy) *dy = sd->du.dy*a + sd->dv.dy*b - (sd->du.dy + sd->dv.dy)*c;
|
||||
#endif
|
||||
|
||||
return sd->u*a + sd->v*b + (1.0f - sd->u - sd->v)*c;
|
||||
}
|
||||
else {
|
||||
if(dx) *dx = make_float2(0.0f, 0.0f);
|
||||
if(dy) *dy = make_float2(0.0f, 0.0f);
|
||||
|
||||
return make_float2(0.0f, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
ccl_device_noinline float3 subd_triangle_attribute_float3(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float3 *dx, float3 *dy)
|
||||
{
|
||||
int patch = subd_triangle_patch(kg, sd);
|
||||
|
@@ -149,53 +149,6 @@ ccl_device float triangle_attribute_float(KernelGlobals *kg, const ShaderData *s
|
||||
}
|
||||
}
|
||||
|
||||
ccl_device float2 triangle_attribute_float2(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float2 *dx, float2 *dy)
|
||||
{
|
||||
if(desc.element == ATTR_ELEMENT_FACE) {
|
||||
if(dx) *dx = make_float2(0.0f, 0.0f);
|
||||
if(dy) *dy = make_float2(0.0f, 0.0f);
|
||||
|
||||
return kernel_tex_fetch(__attributes_float2, desc.offset + sd->prim);
|
||||
}
|
||||
else if(desc.element == ATTR_ELEMENT_VERTEX || desc.element == ATTR_ELEMENT_VERTEX_MOTION) {
|
||||
uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, sd->prim);
|
||||
|
||||
float2 f0 = kernel_tex_fetch(__attributes_float2, desc.offset + tri_vindex.x);
|
||||
float2 f1 = kernel_tex_fetch(__attributes_float2, desc.offset + tri_vindex.y);
|
||||
float2 f2 = kernel_tex_fetch(__attributes_float2, desc.offset + tri_vindex.z);
|
||||
|
||||
#ifdef __RAY_DIFFERENTIALS__
|
||||
if(dx) *dx = sd->du.dx*f0 + sd->dv.dx*f1 - (sd->du.dx + sd->dv.dx)*f2;
|
||||
if(dy) *dy = sd->du.dy*f0 + sd->dv.dy*f1 - (sd->du.dy + sd->dv.dy)*f2;
|
||||
#endif
|
||||
|
||||
return sd->u*f0 + sd->v*f1 + (1.0f - sd->u - sd->v)*f2;
|
||||
}
|
||||
else if(desc.element == ATTR_ELEMENT_CORNER) {
|
||||
int tri = desc.offset + sd->prim*3;
|
||||
float2 f0, f1, f2;
|
||||
|
||||
if(desc.element == ATTR_ELEMENT_CORNER) {
|
||||
f0 = kernel_tex_fetch(__attributes_float2, tri + 0);
|
||||
f1 = kernel_tex_fetch(__attributes_float2, tri + 1);
|
||||
f2 = kernel_tex_fetch(__attributes_float2, tri + 2);
|
||||
}
|
||||
|
||||
#ifdef __RAY_DIFFERENTIALS__
|
||||
if(dx) *dx = sd->du.dx*f0 + sd->dv.dx*f1 - (sd->du.dx + sd->dv.dx)*f2;
|
||||
if(dy) *dy = sd->du.dy*f0 + sd->dv.dy*f1 - (sd->du.dy + sd->dv.dy)*f2;
|
||||
#endif
|
||||
|
||||
return sd->u*f0 + sd->v*f1 + (1.0f - sd->u - sd->v)*f2;
|
||||
}
|
||||
else {
|
||||
if(dx) *dx = make_float2(0.0f, 0.0f);
|
||||
if(dy) *dy = make_float2(0.0f, 0.0f);
|
||||
|
||||
return make_float2(0.0f, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
ccl_device float3 triangle_attribute_float3(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float3 *dx, float3 *dy)
|
||||
{
|
||||
if(desc.element == ATTR_ELEMENT_FACE) {
|
||||
|
@@ -351,7 +351,7 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input,
|
||||
out = make_float3(roughness, roughness, roughness);
|
||||
}
|
||||
else {
|
||||
out = shader_emissive_eval(&sd);
|
||||
out = shader_emissive_eval(kg, &sd);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -475,9 +475,8 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input,
|
||||
shader_setup_from_background(kg, &sd, &ray);
|
||||
|
||||
/* evaluate */
|
||||
int path_flag = 0; /* we can't know which type of BSDF this is for */
|
||||
shader_eval_surface(kg, &sd, &state, path_flag | PATH_RAY_EMISSION);
|
||||
out = shader_background_eval(&sd);
|
||||
int flag = 0; /* we can't know which type of BSDF this is for */
|
||||
out = shader_eval_background(kg, &sd, &state, flag);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -555,9 +554,8 @@ ccl_device void kernel_background_evaluate(KernelGlobals *kg,
|
||||
shader_setup_from_background(kg, &sd, &ray);
|
||||
|
||||
/* evaluate */
|
||||
int path_flag = 0; /* we can't know which type of BSDF this is for */
|
||||
shader_eval_surface(kg, &sd, &state, path_flag | PATH_RAY_EMISSION);
|
||||
float3 color = shader_background_eval(&sd);
|
||||
int flag = 0; /* we can't know which type of BSDF this is for */
|
||||
float3 color = shader_eval_background(kg, &sd, &state, flag);
|
||||
|
||||
/* write output */
|
||||
output[i] += make_float4(color.x, color.y, color.z, 0.0f);
|
||||
|
@@ -125,9 +125,7 @@
|
||||
#define fmodf(x, y) fmod((float)(x), (float)(y))
|
||||
#define sinhf(x) sinh(((float)(x)))
|
||||
|
||||
/* Use native functions with possibly lower precision for performance,
|
||||
* no issues found so far. */
|
||||
#if 1
|
||||
#ifndef __CL_USE_NATIVE__
|
||||
# define sinf(x) native_sin(((float)(x)))
|
||||
# define cosf(x) native_cos(((float)(x)))
|
||||
# define tanf(x) native_tan(((float)(x)))
|
||||
@@ -142,7 +140,7 @@
|
||||
# define expf(x) exp(((float)(x)))
|
||||
# define sqrtf(x) sqrt(((float)(x)))
|
||||
# define logf(x) log(((float)(x)))
|
||||
# define rcp(x) recip(x)
|
||||
# define rcp(x) recip(x))
|
||||
#endif
|
||||
|
||||
/* data lookup defines */
|
||||
|
@@ -29,36 +29,43 @@ ccl_device_noinline float3 direct_emissive_eval(KernelGlobals *kg,
|
||||
/* setup shading at emitter */
|
||||
float3 eval;
|
||||
|
||||
if(shader_constant_emission_eval(kg, ls->shader, &eval)) {
|
||||
int shader_flag = kernel_tex_fetch(__shaders, (ls->shader & SHADER_MASK)).flags;
|
||||
|
||||
#ifdef __BACKGROUND_MIS__
|
||||
if(ls->type == LIGHT_BACKGROUND) {
|
||||
Ray ray;
|
||||
ray.D = ls->D;
|
||||
ray.P = ls->P;
|
||||
ray.t = 1.0f;
|
||||
ray.time = time;
|
||||
ray.dP = differential3_zero();
|
||||
ray.dD = dI;
|
||||
|
||||
shader_setup_from_background(kg, emission_sd, &ray);
|
||||
|
||||
path_state_modify_bounce(state, true);
|
||||
eval = shader_eval_background(kg, emission_sd, state, 0);
|
||||
path_state_modify_bounce(state, false);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if(shader_flag & SD_HAS_CONSTANT_EMISSION)
|
||||
{
|
||||
eval.x = kernel_tex_fetch(__shaders, (ls->shader & SHADER_MASK)).constant_emission[0];
|
||||
eval.y = kernel_tex_fetch(__shaders, (ls->shader & SHADER_MASK)).constant_emission[1];
|
||||
eval.z = kernel_tex_fetch(__shaders, (ls->shader & SHADER_MASK)).constant_emission[2];
|
||||
if((ls->prim != PRIM_NONE) && dot(ls->Ng, I) < 0.0f) {
|
||||
ls->Ng = -ls->Ng;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Setup shader data and call shader_eval_surface once, better
|
||||
* for GPU coherence and compile times. */
|
||||
#ifdef __BACKGROUND_MIS__
|
||||
if(ls->type == LIGHT_BACKGROUND) {
|
||||
Ray ray;
|
||||
ray.D = ls->D;
|
||||
ray.P = ls->P;
|
||||
ray.t = 1.0f;
|
||||
ray.time = time;
|
||||
ray.dP = differential3_zero();
|
||||
ray.dD = dI;
|
||||
else
|
||||
{
|
||||
shader_setup_from_sample(kg, emission_sd,
|
||||
ls->P, ls->Ng, I,
|
||||
ls->shader, ls->object, ls->prim,
|
||||
ls->u, ls->v, t, time, false, ls->lamp);
|
||||
|
||||
shader_setup_from_background(kg, emission_sd, &ray);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
shader_setup_from_sample(kg, emission_sd,
|
||||
ls->P, ls->Ng, I,
|
||||
ls->shader, ls->object, ls->prim,
|
||||
ls->u, ls->v, t, time, false, ls->lamp);
|
||||
|
||||
ls->Ng = emission_sd->Ng;
|
||||
}
|
||||
ls->Ng = emission_sd->Ng;
|
||||
|
||||
/* No proper path flag, we're evaluating this for all closures. that's
|
||||
* weak but we'd have to do multiple evaluations otherwise. */
|
||||
@@ -66,16 +73,8 @@ ccl_device_noinline float3 direct_emissive_eval(KernelGlobals *kg,
|
||||
shader_eval_surface(kg, emission_sd, state, PATH_RAY_EMISSION);
|
||||
path_state_modify_bounce(state, false);
|
||||
|
||||
/* Evaluate closures. */
|
||||
#ifdef __BACKGROUND_MIS__
|
||||
if (ls->type == LIGHT_BACKGROUND) {
|
||||
eval = shader_background_eval(emission_sd);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
eval = shader_emissive_eval(emission_sd);
|
||||
}
|
||||
/* Evaluate emissive closure. */
|
||||
eval = shader_emissive_eval(kg, emission_sd);
|
||||
}
|
||||
|
||||
eval *= ls->eval_fac;
|
||||
@@ -202,7 +201,7 @@ ccl_device_noinline bool direct_emission(KernelGlobals *kg,
|
||||
ccl_device_noinline float3 indirect_primitive_emission(KernelGlobals *kg, ShaderData *sd, float t, int path_flag, float bsdf_pdf)
|
||||
{
|
||||
/* evaluate emissive closure */
|
||||
float3 L = shader_emissive_eval(sd);
|
||||
float3 L = shader_emissive_eval(kg, sd);
|
||||
|
||||
#ifdef __HAIR__
|
||||
if(!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_USE_MIS) && (sd->type & PRIMITIVE_ALL_TRIANGLE))
|
||||
@@ -295,7 +294,7 @@ ccl_device_noinline float3 indirect_background(KernelGlobals *kg,
|
||||
#ifdef __BACKGROUND__
|
||||
int shader = kernel_data.background.surface_shader;
|
||||
|
||||
/* Use visibility flag to skip lights. */
|
||||
/* use visibility flag to skip lights */
|
||||
if(shader & SHADER_EXCLUDE_ANY) {
|
||||
if(((shader & SHADER_EXCLUDE_DIFFUSE) && (state->flag & PATH_RAY_DIFFUSE)) ||
|
||||
((shader & SHADER_EXCLUDE_GLOSSY) &&
|
||||
@@ -306,27 +305,20 @@ ccl_device_noinline float3 indirect_background(KernelGlobals *kg,
|
||||
return make_float3(0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
|
||||
/* Evaluate background shader. */
|
||||
float3 L;
|
||||
if(!shader_constant_emission_eval(kg, shader, &L)) {
|
||||
/* evaluate background closure */
|
||||
# ifdef __SPLIT_KERNEL__
|
||||
Ray priv_ray = *ray;
|
||||
shader_setup_from_background(kg, emission_sd, &priv_ray);
|
||||
Ray priv_ray = *ray;
|
||||
shader_setup_from_background(kg, emission_sd, &priv_ray);
|
||||
# else
|
||||
shader_setup_from_background(kg, emission_sd, ray);
|
||||
shader_setup_from_background(kg, emission_sd, ray);
|
||||
# endif
|
||||
|
||||
path_state_modify_bounce(state, true);
|
||||
shader_eval_surface(kg, emission_sd, state, state->flag | PATH_RAY_EMISSION);
|
||||
path_state_modify_bounce(state, false);
|
||||
path_state_modify_bounce(state, true);
|
||||
float3 L = shader_eval_background(kg, emission_sd, state, state->flag);
|
||||
path_state_modify_bounce(state, false);
|
||||
|
||||
L = shader_background_eval(emission_sd);
|
||||
}
|
||||
|
||||
/* Background MIS weights. */
|
||||
#ifdef __BACKGROUND_MIS__
|
||||
/* Check if background light exists or if we should skip pdf. */
|
||||
/* check if background light exists or if we should skip pdf */
|
||||
int res_x = kernel_data.integrator.pdf_background_res_x;
|
||||
|
||||
if(!(state->flag & PATH_RAY_MIS_SKIP) && res_x) {
|
||||
|
@@ -56,7 +56,7 @@ ccl_device_noinline void shader_setup_from_ray(KernelGlobals *kg,
|
||||
PROFILING_INIT(kg, PROFILING_SHADER_SETUP);
|
||||
|
||||
#ifdef __INSTANCING__
|
||||
sd->object = (isect->object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, isect->prim): isect->object;
|
||||
sd->object = (isect->object == PRIM_NONE)? kernel_tex_fetch(__prim_object, isect->prim): isect->object;
|
||||
#endif
|
||||
sd->lamp = LAMP_NONE;
|
||||
|
||||
@@ -299,10 +299,6 @@ ccl_device_inline void shader_setup_from_sample(KernelGlobals *kg,
|
||||
sd->ob_tfm = lamp_fetch_transform(kg, lamp, false);
|
||||
sd->ob_itfm = lamp_fetch_transform(kg, lamp, true);
|
||||
sd->lamp = lamp;
|
||||
#else
|
||||
}
|
||||
else if(lamp != LAMP_NONE) {
|
||||
sd->lamp = lamp;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -411,7 +407,7 @@ ccl_device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderDat
|
||||
sd->ray_length = 0.0f;
|
||||
|
||||
#ifdef __INSTANCING__
|
||||
sd->object = OBJECT_NONE;
|
||||
sd->object = PRIM_NONE;
|
||||
#endif
|
||||
sd->lamp = LAMP_NONE;
|
||||
sd->prim = PRIM_NONE;
|
||||
@@ -434,9 +430,6 @@ ccl_device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderDat
|
||||
sd->dv = differential_zero();
|
||||
#endif
|
||||
|
||||
/* for NDC coordinates */
|
||||
sd->ray_P = ray->P;
|
||||
|
||||
PROFILING_SHADER(sd->shader);
|
||||
PROFILING_OBJECT(sd->object);
|
||||
}
|
||||
@@ -460,7 +453,7 @@ ccl_device_inline void shader_setup_from_volume(KernelGlobals *kg, ShaderData *s
|
||||
sd->ray_length = 0.0f; /* todo: can we set this to some useful value? */
|
||||
|
||||
# ifdef __INSTANCING__
|
||||
sd->object = OBJECT_NONE; /* todo: fill this for texture coordinates */
|
||||
sd->object = PRIM_NONE; /* todo: fill this for texture coordinates */
|
||||
# endif
|
||||
sd->lamp = LAMP_NONE;
|
||||
sd->prim = PRIM_NONE;
|
||||
@@ -987,40 +980,9 @@ ccl_device float3 shader_bssrdf_sum(ShaderData *sd, float3 *N_, float *texture_b
|
||||
}
|
||||
#endif /* __SUBSURFACE__ */
|
||||
|
||||
/* Constant emission optimization */
|
||||
|
||||
ccl_device bool shader_constant_emission_eval(KernelGlobals *kg, int shader, float3 *eval)
|
||||
{
|
||||
int shader_index = shader & SHADER_MASK;
|
||||
int shader_flag = kernel_tex_fetch(__shaders, shader_index).flags;
|
||||
|
||||
if (shader_flag & SD_HAS_CONSTANT_EMISSION) {
|
||||
*eval = make_float3(
|
||||
kernel_tex_fetch(__shaders, shader_index).constant_emission[0],
|
||||
kernel_tex_fetch(__shaders, shader_index).constant_emission[1],
|
||||
kernel_tex_fetch(__shaders, shader_index).constant_emission[2]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Background */
|
||||
|
||||
ccl_device float3 shader_background_eval(ShaderData *sd)
|
||||
{
|
||||
if(sd->flag & SD_EMISSION) {
|
||||
return sd->closure_emission_background;
|
||||
}
|
||||
else {
|
||||
return make_float3(0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
/* Emission */
|
||||
|
||||
ccl_device float3 shader_emissive_eval(ShaderData *sd)
|
||||
ccl_device float3 shader_emissive_eval(KernelGlobals *kg, ShaderData *sd)
|
||||
{
|
||||
if(sd->flag & SD_EMISSION) {
|
||||
return emissive_simple_eval(sd->Ng, sd->I) * sd->closure_emission_background;
|
||||
@@ -1068,32 +1030,20 @@ ccl_device void shader_eval_surface(KernelGlobals *kg, ShaderData *sd,
|
||||
sd->num_closure_left = max_closures;
|
||||
|
||||
#ifdef __OSL__
|
||||
if(kg->osl) {
|
||||
if (sd->object == OBJECT_NONE) {
|
||||
OSLShader::eval_background(kg, sd, state, path_flag);
|
||||
}
|
||||
else {
|
||||
OSLShader::eval_surface(kg, sd, state, path_flag);
|
||||
}
|
||||
}
|
||||
if(kg->osl)
|
||||
OSLShader::eval_surface(kg, sd, state, path_flag);
|
||||
else
|
||||
#endif
|
||||
{
|
||||
#ifdef __SVM__
|
||||
svm_eval_nodes(kg, sd, state, SHADER_TYPE_SURFACE, path_flag);
|
||||
#else
|
||||
if(sd->object == OBJECT_NONE) {
|
||||
sd->closure_emission_background = make_float3(0.8f, 0.8f, 0.8f);
|
||||
sd->flag |= SD_EMISSION;
|
||||
}
|
||||
else {
|
||||
DiffuseBsdf *bsdf = (DiffuseBsdf*)bsdf_alloc(sd,
|
||||
sizeof(DiffuseBsdf),
|
||||
make_float3(0.8f, 0.8f, 0.8f));
|
||||
if(bsdf != NULL) {
|
||||
bsdf->N = sd->N;
|
||||
sd->flag |= bsdf_diffuse_setup(bsdf);
|
||||
}
|
||||
DiffuseBsdf *bsdf = (DiffuseBsdf*)bsdf_alloc(sd,
|
||||
sizeof(DiffuseBsdf),
|
||||
make_float3(0.8f, 0.8f, 0.8f));
|
||||
if(bsdf != NULL) {
|
||||
bsdf->N = sd->N;
|
||||
sd->flag |= bsdf_diffuse_setup(bsdf);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -1103,6 +1053,36 @@ ccl_device void shader_eval_surface(KernelGlobals *kg, ShaderData *sd,
|
||||
}
|
||||
}
|
||||
|
||||
/* Background Evaluation */
|
||||
|
||||
ccl_device float3 shader_eval_background(KernelGlobals *kg, ShaderData *sd,
|
||||
ccl_addr_space PathState *state, int path_flag)
|
||||
{
|
||||
sd->num_closure = 0;
|
||||
sd->num_closure_left = 0;
|
||||
|
||||
#ifdef __SVM__
|
||||
# ifdef __OSL__
|
||||
if(kg->osl) {
|
||||
OSLShader::eval_background(kg, sd, state, path_flag);
|
||||
}
|
||||
else
|
||||
# endif /* __OSL__ */
|
||||
{
|
||||
svm_eval_nodes(kg, sd, state, SHADER_TYPE_SURFACE, path_flag);
|
||||
}
|
||||
|
||||
if(sd->flag & SD_EMISSION) {
|
||||
return sd->closure_emission_background;
|
||||
}
|
||||
else {
|
||||
return make_float3(0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
#else /* __SVM__ */
|
||||
return make_float3(0.8f, 0.8f, 0.8f);
|
||||
#endif /* __SVM__ */
|
||||
}
|
||||
|
||||
/* Volume */
|
||||
|
||||
#ifdef __VOLUME__
|
||||
|
@@ -56,7 +56,6 @@ KERNEL_TEX(uint, __patches)
|
||||
/* attributes */
|
||||
KERNEL_TEX(uint4, __attributes_map)
|
||||
KERNEL_TEX(float, __attributes_float)
|
||||
KERNEL_TEX(float2, __attributes_float2)
|
||||
KERNEL_TEX(float4, __attributes_float3)
|
||||
KERNEL_TEX(uchar4, __attributes_uchar4)
|
||||
|
||||
|
@@ -83,6 +83,92 @@ CCL_NAMESPACE_BEGIN
|
||||
# define SHADER_SORT_LOCAL_SIZE 1
|
||||
#endif
|
||||
|
||||
|
||||
/* Device capabilities */
|
||||
#ifdef __KERNEL_CPU__
|
||||
# ifdef __KERNEL_SSE2__
|
||||
# define __QBVH__
|
||||
# endif
|
||||
# define __KERNEL_SHADING__
|
||||
# define __KERNEL_ADV_SHADING__
|
||||
# define __BRANCHED_PATH__
|
||||
# ifdef WITH_OSL
|
||||
# define __OSL__
|
||||
# endif
|
||||
# define __PRINCIPLED__
|
||||
# define __SUBSURFACE__
|
||||
# define __CMJ__
|
||||
# define __VOLUME__
|
||||
# define __VOLUME_SCATTER__
|
||||
# define __SHADOW_RECORD_ALL__
|
||||
# define __VOLUME_DECOUPLED__
|
||||
# define __VOLUME_RECORD_ALL__
|
||||
#endif /* __KERNEL_CPU__ */
|
||||
|
||||
#ifdef __KERNEL_CUDA__
|
||||
# define __KERNEL_SHADING__
|
||||
# define __KERNEL_ADV_SHADING__
|
||||
# define __VOLUME__
|
||||
# define __VOLUME_SCATTER__
|
||||
# define __SUBSURFACE__
|
||||
# define __PRINCIPLED__
|
||||
# define __SHADOW_RECORD_ALL__
|
||||
# define __CMJ__
|
||||
# ifndef __SPLIT_KERNEL__
|
||||
# define __BRANCHED_PATH__
|
||||
# endif
|
||||
#endif /* __KERNEL_CUDA__ */
|
||||
|
||||
#ifdef __KERNEL_OPENCL__
|
||||
|
||||
/* keep __KERNEL_ADV_SHADING__ in sync with opencl_kernel_use_advanced_shading! */
|
||||
|
||||
# ifdef __KERNEL_OPENCL_NVIDIA__
|
||||
# define __KERNEL_SHADING__
|
||||
# define __KERNEL_ADV_SHADING__
|
||||
# define __SUBSURFACE__
|
||||
# define __PRINCIPLED__
|
||||
# define __VOLUME__
|
||||
# define __VOLUME_SCATTER__
|
||||
# define __SHADOW_RECORD_ALL__
|
||||
# define __CMJ__
|
||||
# define __BRANCHED_PATH__
|
||||
# endif /* __KERNEL_OPENCL_NVIDIA__ */
|
||||
|
||||
# ifdef __KERNEL_OPENCL_APPLE__
|
||||
# define __KERNEL_SHADING__
|
||||
# define __KERNEL_ADV_SHADING__
|
||||
# define __PRINCIPLED__
|
||||
# define __CMJ__
|
||||
/* TODO(sergey): Currently experimental section is ignored here,
|
||||
* this is because megakernel in device_opencl does not support
|
||||
* custom cflags depending on the scene features.
|
||||
*/
|
||||
# endif /* __KERNEL_OPENCL_APPLE__ */
|
||||
|
||||
# ifdef __KERNEL_OPENCL_AMD__
|
||||
# define __CL_USE_NATIVE__
|
||||
# define __KERNEL_SHADING__
|
||||
# define __KERNEL_ADV_SHADING__
|
||||
# define __SUBSURFACE__
|
||||
# define __PRINCIPLED__
|
||||
# define __VOLUME__
|
||||
# define __VOLUME_SCATTER__
|
||||
# define __SHADOW_RECORD_ALL__
|
||||
# define __CMJ__
|
||||
# define __BRANCHED_PATH__
|
||||
# endif /* __KERNEL_OPENCL_AMD__ */
|
||||
|
||||
# ifdef __KERNEL_OPENCL_INTEL_CPU__
|
||||
# define __CL_USE_NATIVE__
|
||||
# define __KERNEL_SHADING__
|
||||
# define __KERNEL_ADV_SHADING__
|
||||
# define __PRINCIPLED__
|
||||
# define __CMJ__
|
||||
# endif /* __KERNEL_OPENCL_INTEL_CPU__ */
|
||||
|
||||
#endif /* __KERNEL_OPENCL__ */
|
||||
|
||||
/* Kernel features */
|
||||
#define __SOBOL__
|
||||
#define __INSTANCING__
|
||||
@@ -99,55 +185,28 @@ CCL_NAMESPACE_BEGIN
|
||||
#define __SHADOW_TRICKS__
|
||||
#define __DENOISING_FEATURES__
|
||||
#define __SHADER_RAYTRACE__
|
||||
#define __AO__
|
||||
#define __PASSES__
|
||||
#define __HAIR__
|
||||
|
||||
/* Without these we get an AO render, used by OpenCL preview kernel. */
|
||||
#ifndef __KERNEL_AO_PREVIEW__
|
||||
#ifdef __KERNEL_SHADING__
|
||||
# define __SVM__
|
||||
# define __EMISSION__
|
||||
# define __TEXTURES__
|
||||
# define __EXTRA_NODES__
|
||||
# define __HOLDOUT__
|
||||
#endif
|
||||
|
||||
#ifdef __KERNEL_ADV_SHADING__
|
||||
# define __MULTI_CLOSURE__
|
||||
# define __TRANSPARENT_SHADOWS__
|
||||
# define __PASSES__
|
||||
# define __BACKGROUND_MIS__
|
||||
# define __LAMP_MIS__
|
||||
# define __AO__
|
||||
# define __CAMERA_MOTION__
|
||||
# define __OBJECT_MOTION__
|
||||
# define __HAIR__
|
||||
# define __BAKING__
|
||||
# define __PRINCIPLED__
|
||||
# define __SUBSURFACE__
|
||||
# define __VOLUME__
|
||||
# define __VOLUME_SCATTER__
|
||||
# define __CMJ__
|
||||
# define __SHADOW_RECORD_ALL__
|
||||
# define __BRANCHED_PATH__
|
||||
#endif
|
||||
|
||||
/* Device specific features */
|
||||
#ifdef __KERNEL_CPU__
|
||||
# ifdef __KERNEL_SSE2__
|
||||
# define __QBVH__
|
||||
# endif
|
||||
# ifdef WITH_OSL
|
||||
# define __OSL__
|
||||
# endif
|
||||
# define __VOLUME_DECOUPLED__
|
||||
# define __VOLUME_RECORD_ALL__
|
||||
#endif /* __KERNEL_CPU__ */
|
||||
|
||||
#ifdef __KERNEL_CUDA__
|
||||
# ifdef __SPLIT_KERNEL__
|
||||
# undef __BRANCHED_PATH__
|
||||
# endif
|
||||
#endif /* __KERNEL_CUDA__ */
|
||||
|
||||
#ifdef __KERNEL_OPENCL__
|
||||
#endif /* __KERNEL_OPENCL__ */
|
||||
|
||||
/* Scene-based selective features compilation. */
|
||||
#ifdef __NO_CAMERA_MOTION__
|
||||
# undef __CAMERA_MOTION__
|
||||
|
@@ -66,15 +66,9 @@ ccl_device_inline void get_work_pixel(ccl_global const WorkTile *tile,
|
||||
ccl_private uint *y,
|
||||
ccl_private uint *sample)
|
||||
{
|
||||
#ifdef __KERNEL_CUDA__
|
||||
/* Keeping threads for the same pixel together improves performance on CUDA. */
|
||||
uint sample_offset = global_work_index % tile->num_samples;
|
||||
uint pixel_offset = global_work_index / tile->num_samples;
|
||||
#else /* __KERNEL_CUDA__ */
|
||||
uint tile_pixels = tile->w * tile->h;
|
||||
uint sample_offset = global_work_index / tile_pixels;
|
||||
uint pixel_offset = global_work_index - sample_offset * tile_pixels;
|
||||
#endif /* __KERNEL_CUDA__ */
|
||||
uint y_offset = pixel_offset / tile->w;
|
||||
uint x_offset = pixel_offset - y_offset * tile->w;
|
||||
|
||||
|
41
intern/cycles/kernel/kernels/opencl/kernel_split.cl
Normal file
41
intern/cycles/kernel/kernels/opencl/kernel_split.cl
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2011-2017 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 "kernel/kernel_compat_opencl.h" // PRECOMPILED
|
||||
#include "kernel/split/kernel_split_common.h" // PRECOMPILED
|
||||
|
||||
#include "kernel/kernels/opencl/kernel_state_buffer_size.cl"
|
||||
#include "kernel/kernels/opencl/kernel_data_init.cl"
|
||||
#include "kernel/kernels/opencl/kernel_path_init.cl"
|
||||
|
||||
#include "kernel/kernels/opencl/kernel_scene_intersect.cl"
|
||||
#include "kernel/kernels/opencl/kernel_lamp_emission.cl"
|
||||
#include "kernel/kernels/opencl/kernel_do_volume.cl"
|
||||
#include "kernel/kernels/opencl/kernel_indirect_background.cl"
|
||||
#include "kernel/kernels/opencl/kernel_queue_enqueue.cl"
|
||||
#include "kernel/kernels/opencl/kernel_shader_setup.cl"
|
||||
#include "kernel/kernels/opencl/kernel_shader_sort.cl"
|
||||
#include "kernel/kernels/opencl/kernel_shader_eval.cl"
|
||||
#include "kernel/kernels/opencl/kernel_holdout_emission_blurring_pathtermination_ao.cl"
|
||||
#include "kernel/kernels/opencl/kernel_subsurface_scatter.cl"
|
||||
#include "kernel/kernels/opencl/kernel_direct_lighting.cl"
|
||||
#include "kernel/kernels/opencl/kernel_shadow_blocked_ao.cl"
|
||||
#include "kernel/kernels/opencl/kernel_shadow_blocked_dl.cl"
|
||||
#include "kernel/kernels/opencl/kernel_enqueue_inactive.cl"
|
||||
#include "kernel/kernels/opencl/kernel_next_iteration_setup.cl"
|
||||
#include "kernel/kernels/opencl/kernel_indirect_subsurface.cl"
|
||||
#include "kernel/kernels/opencl/kernel_buffer_update.cl"
|
||||
|
@@ -392,44 +392,6 @@ bool OSLRenderServices::get_array_attribute(OSL::ShaderGlobals *sg, bool derivat
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool set_attribute_float2(float2 f[3], TypeDesc type, bool derivatives, void *val)
|
||||
{
|
||||
if(type == TypeDesc::TypePoint || type == TypeDesc::TypeVector ||
|
||||
type == TypeDesc::TypeNormal || type == TypeDesc::TypeColor)
|
||||
{
|
||||
float *fval = (float *)val;
|
||||
|
||||
fval[0] = f[0].x;
|
||||
fval[1] = f[0].y;
|
||||
fval[2] = 0.0f;
|
||||
|
||||
if(derivatives) {
|
||||
fval[3] = f[1].x;
|
||||
fval[4] = f[1].y;
|
||||
fval[5] = 0.0f;
|
||||
|
||||
fval[6] = f[2].x;
|
||||
fval[7] = f[2].y;
|
||||
fval[8] = 0.0f;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else if(type == TypeDesc::TypeFloat) {
|
||||
float *fval = (float *)val;
|
||||
fval[0] = average(f[0]);
|
||||
|
||||
if(derivatives) {
|
||||
fval[1] = average(f[1]);
|
||||
fval[2] = average(f[2]);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool set_attribute_float3(float3 f[3], TypeDesc type, bool derivatives, void *val)
|
||||
{
|
||||
if(type == TypeDesc::TypePoint || type == TypeDesc::TypeVector ||
|
||||
@@ -610,12 +572,6 @@ static bool get_primitive_attribute(KernelGlobals *kg, const ShaderData *sd, con
|
||||
(derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
|
||||
return set_attribute_float3(fval, type, derivatives, val);
|
||||
}
|
||||
else if(attr.type == TypeFloat2) {
|
||||
float2 fval[2];
|
||||
fval[0] = primitive_attribute_float2(kg, sd, attr.desc,
|
||||
(derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
|
||||
return set_attribute_float2(fval, type, derivatives, val);
|
||||
}
|
||||
else if(attr.type == TypeDesc::TypeFloat) {
|
||||
float fval[3];
|
||||
fval[0] = primitive_attribute_float(kg, sd, attr.desc,
|
||||
|
@@ -52,27 +52,18 @@ ccl_device void svm_node_attr(KernelGlobals *kg, ShaderData *sd, float *stack, u
|
||||
AttributeDescriptor desc = svm_node_attr_init(kg, sd, node, &type, &out_offset);
|
||||
|
||||
/* fetch and store attribute */
|
||||
if(desc.type == NODE_ATTR_FLOAT) {
|
||||
if (desc.type == NODE_ATTR_FLOAT) {
|
||||
float f = primitive_attribute_float(kg, sd, desc, NULL, NULL);
|
||||
if(type == NODE_ATTR_FLOAT) {
|
||||
if (type == NODE_ATTR_FLOAT) {
|
||||
stack_store_float(stack, out_offset, f);
|
||||
}
|
||||
else {
|
||||
stack_store_float3(stack, out_offset, make_float3(f, f, f));
|
||||
}
|
||||
}
|
||||
else if(desc.type == NODE_ATTR_FLOAT2) {
|
||||
float2 f = primitive_attribute_float2(kg, sd, desc, NULL, NULL);
|
||||
if(type == NODE_ATTR_FLOAT) {
|
||||
stack_store_float(stack, out_offset, f.x);
|
||||
}
|
||||
else {
|
||||
stack_store_float3(stack, out_offset, make_float3(f.x, f.y, 0.0f));
|
||||
}
|
||||
}
|
||||
else {
|
||||
float3 f = primitive_attribute_float3(kg, sd, desc, NULL, NULL);
|
||||
if(type == NODE_ATTR_FLOAT) {
|
||||
if (type == NODE_ATTR_FLOAT) {
|
||||
stack_store_float(stack, out_offset, average(f));
|
||||
}
|
||||
else {
|
||||
@@ -93,30 +84,20 @@ void svm_node_attr_bump_dx(KernelGlobals *kg, ShaderData *sd, float *stack, uint
|
||||
AttributeDescriptor desc = svm_node_attr_init(kg, sd, node, &type, &out_offset);
|
||||
|
||||
/* fetch and store attribute */
|
||||
if(desc.type == NODE_ATTR_FLOAT) {
|
||||
if (desc.type == NODE_ATTR_FLOAT) {
|
||||
float dx;
|
||||
float f = primitive_surface_attribute_float(kg, sd, desc, &dx, NULL);
|
||||
if(type == NODE_ATTR_FLOAT) {
|
||||
if (type == NODE_ATTR_FLOAT) {
|
||||
stack_store_float(stack, out_offset, f+dx);
|
||||
}
|
||||
else {
|
||||
stack_store_float3(stack, out_offset, make_float3(f+dx, f+dx, f+dx));
|
||||
}
|
||||
}
|
||||
else if(desc.type == NODE_ATTR_FLOAT2) {
|
||||
float2 dx;
|
||||
float2 f = primitive_attribute_float2(kg, sd, desc, &dx, NULL);
|
||||
if (type == NODE_ATTR_FLOAT) {
|
||||
stack_store_float(stack, out_offset, f.x + dx.x);
|
||||
}
|
||||
else {
|
||||
stack_store_float3(stack, out_offset, make_float3(f.x+dx.x, f.y+dx.y, 0.0f));
|
||||
}
|
||||
}
|
||||
else {
|
||||
float3 dx;
|
||||
float3 f = primitive_surface_attribute_float3(kg, sd, desc, &dx, NULL);
|
||||
if(type == NODE_ATTR_FLOAT) {
|
||||
if (type == NODE_ATTR_FLOAT) {
|
||||
stack_store_float(stack, out_offset, average(f+dx));
|
||||
}
|
||||
else {
|
||||
@@ -140,30 +121,20 @@ void svm_node_attr_bump_dy(KernelGlobals *kg,
|
||||
AttributeDescriptor desc = svm_node_attr_init(kg, sd, node, &type, &out_offset);
|
||||
|
||||
/* fetch and store attribute */
|
||||
if(desc.type == NODE_ATTR_FLOAT) {
|
||||
if (desc.type == NODE_ATTR_FLOAT) {
|
||||
float dy;
|
||||
float f = primitive_surface_attribute_float(kg, sd, desc, NULL, &dy);
|
||||
if(type == NODE_ATTR_FLOAT) {
|
||||
if (type == NODE_ATTR_FLOAT) {
|
||||
stack_store_float(stack, out_offset, f+dy);
|
||||
}
|
||||
else {
|
||||
stack_store_float3(stack, out_offset, make_float3(f+dy, f+dy, f+dy));
|
||||
}
|
||||
}
|
||||
else if(desc.type == NODE_ATTR_FLOAT2) {
|
||||
float2 dy;
|
||||
float2 f = primitive_attribute_float2(kg, sd, desc, NULL, &dy);
|
||||
if(type == NODE_ATTR_FLOAT) {
|
||||
stack_store_float(stack, out_offset, f.x + dy.x);
|
||||
}
|
||||
else {
|
||||
stack_store_float3(stack, out_offset, make_float3(f.x+dy.x, f.y+dy.y, 0.0f));
|
||||
}
|
||||
}
|
||||
else {
|
||||
float3 dy;
|
||||
float3 f = primitive_surface_attribute_float3(kg, sd, desc, NULL, &dy);
|
||||
if(type == NODE_ATTR_FLOAT) {
|
||||
if (type == NODE_ATTR_FLOAT) {
|
||||
stack_store_float(stack, out_offset, average(f+dy));
|
||||
}
|
||||
else {
|
||||
|
@@ -146,13 +146,7 @@ ccl_device_noinline float3 svm_bevel(
|
||||
}
|
||||
#endif /* __OBJECT_MOTION__ */
|
||||
|
||||
/* Get geometric normal. */
|
||||
float3 hit_Ng = isect.Ng[hit];
|
||||
int object = (isect.hits[hit].object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, isect.hits[hit].prim): isect.hits[hit].object;
|
||||
int object_flag = kernel_tex_fetch(__object_flag, object);
|
||||
if(object_flag & SD_OBJECT_NEGATIVE_SCALE_APPLIED) {
|
||||
hit_Ng = -hit_Ng;
|
||||
}
|
||||
|
||||
/* Compute smooth normal. */
|
||||
float3 N = hit_Ng;
|
||||
@@ -174,7 +168,7 @@ ccl_device_noinline float3 svm_bevel(
|
||||
}
|
||||
|
||||
/* Transform normals to world space. */
|
||||
if(!(object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
|
||||
if(isect.hits[hit].object != OBJECT_NONE) {
|
||||
object_normal_transform(kg, sd, &N);
|
||||
object_normal_transform(kg, sd, &hit_Ng);
|
||||
}
|
||||
|
@@ -363,15 +363,7 @@ ccl_device void svm_node_tangent(KernelGlobals *kg, ShaderData *sd, float *stack
|
||||
float3 attribute_value;
|
||||
const AttributeDescriptor desc = find_attribute(kg, sd, node.z);
|
||||
if (desc.offset != ATTR_STD_NOT_FOUND) {
|
||||
if(desc.type == NODE_ATTR_FLOAT2) {
|
||||
float2 value = primitive_surface_attribute_float2(kg, sd, desc, NULL, NULL);
|
||||
attribute_value.x = value.x;
|
||||
attribute_value.y = value.y;
|
||||
attribute_value.z = 0.0f;
|
||||
}
|
||||
else {
|
||||
attribute_value = primitive_surface_attribute_float3(kg, sd, desc, NULL, NULL);
|
||||
}
|
||||
attribute_value = primitive_surface_attribute_float3(kg, sd, desc, NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -141,7 +141,6 @@ typedef enum ShaderNodeType {
|
||||
|
||||
typedef enum NodeAttributeType {
|
||||
NODE_ATTR_FLOAT = 0,
|
||||
NODE_ATTR_FLOAT2,
|
||||
NODE_ATTR_FLOAT3,
|
||||
NODE_ATTR_MATRIX
|
||||
} NodeAttributeType;
|
||||
|
@@ -22,7 +22,6 @@ set(SRC
|
||||
image.cpp
|
||||
integrator.cpp
|
||||
light.cpp
|
||||
merge.cpp
|
||||
mesh.cpp
|
||||
mesh_displace.cpp
|
||||
mesh_subdivision.cpp
|
||||
@@ -56,7 +55,6 @@ set(SRC_HEADERS
|
||||
image.h
|
||||
integrator.h
|
||||
light.h
|
||||
merge.h
|
||||
mesh.h
|
||||
nodes.h
|
||||
object.h
|
||||
|
@@ -48,8 +48,7 @@ void Attribute::set(ustring name_, TypeDesc type_, AttributeElement element_)
|
||||
/* string and matrix not supported! */
|
||||
assert(type == TypeDesc::TypeFloat || type == TypeDesc::TypeColor ||
|
||||
type == TypeDesc::TypePoint || type == TypeDesc::TypeVector ||
|
||||
type == TypeDesc::TypeNormal || type == TypeDesc::TypeMatrix ||
|
||||
type == TypeFloat2);
|
||||
type == TypeDesc::TypeNormal || type == TypeDesc::TypeMatrix);
|
||||
}
|
||||
|
||||
void Attribute::resize(Mesh *mesh, AttributePrimitive prim, bool reserve_only)
|
||||
@@ -69,8 +68,6 @@ void Attribute::resize(size_t num_elements)
|
||||
|
||||
void Attribute::add(const float& f)
|
||||
{
|
||||
assert(data_sizeof() == sizeof(float));
|
||||
|
||||
char *data = (char*)&f;
|
||||
size_t size = sizeof(f);
|
||||
|
||||
@@ -80,19 +77,6 @@ void Attribute::add(const float& f)
|
||||
|
||||
void Attribute::add(const uchar4& f)
|
||||
{
|
||||
assert(data_sizeof() == sizeof(uchar4));
|
||||
|
||||
char *data = (char*)&f;
|
||||
size_t size = sizeof(f);
|
||||
|
||||
for(size_t i = 0; i < size; i++)
|
||||
buffer.push_back(data[i]);
|
||||
}
|
||||
|
||||
void Attribute::add(const float2& f)
|
||||
{
|
||||
assert(data_sizeof() == sizeof(float2));
|
||||
|
||||
char *data = (char*)&f;
|
||||
size_t size = sizeof(f);
|
||||
|
||||
@@ -102,8 +86,6 @@ void Attribute::add(const float2& f)
|
||||
|
||||
void Attribute::add(const float3& f)
|
||||
{
|
||||
assert(data_sizeof() == sizeof(float3));
|
||||
|
||||
char *data = (char*)&f;
|
||||
size_t size = sizeof(f);
|
||||
|
||||
@@ -113,8 +95,6 @@ void Attribute::add(const float3& f)
|
||||
|
||||
void Attribute::add(const Transform& f)
|
||||
{
|
||||
assert(data_sizeof() == sizeof(Transform));
|
||||
|
||||
char *data = (char*)&f;
|
||||
size_t size = sizeof(f);
|
||||
|
||||
@@ -124,8 +104,6 @@ void Attribute::add(const Transform& f)
|
||||
|
||||
void Attribute::add(const VoxelAttribute& f)
|
||||
{
|
||||
assert(data_sizeof() == sizeof(VoxelAttribute));
|
||||
|
||||
char *data = (char*)&f;
|
||||
size_t size = sizeof(f);
|
||||
|
||||
@@ -149,8 +127,6 @@ size_t Attribute::data_sizeof() const
|
||||
return sizeof(uchar4);
|
||||
else if(type == TypeDesc::TypeFloat)
|
||||
return sizeof(float);
|
||||
else if(type == TypeFloat2)
|
||||
return sizeof(float2);
|
||||
else if(type == TypeDesc::TypeMatrix)
|
||||
return sizeof(Transform);
|
||||
else
|
||||
@@ -424,7 +400,7 @@ Attribute *AttributeSet::add(AttributeStandard std, ustring name)
|
||||
attr = add(name, TypeDesc::TypeNormal, ATTR_ELEMENT_FACE);
|
||||
break;
|
||||
case ATTR_STD_UV:
|
||||
attr = add(name, TypeFloat2, ATTR_ELEMENT_CORNER);
|
||||
attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CORNER);
|
||||
break;
|
||||
case ATTR_STD_UV_TANGENT:
|
||||
attr = add(name, TypeDesc::TypeVector, ATTR_ELEMENT_CORNER);
|
||||
@@ -475,8 +451,6 @@ Attribute *AttributeSet::add(AttributeStandard std, ustring name)
|
||||
else if(curve_mesh) {
|
||||
switch(std) {
|
||||
case ATTR_STD_UV:
|
||||
attr = add(name, TypeFloat2, ATTR_ELEMENT_CURVE);
|
||||
break;
|
||||
case ATTR_STD_GENERATED:
|
||||
attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CURVE);
|
||||
break;
|
||||
|
@@ -66,86 +66,25 @@ public:
|
||||
size_t element_size(Mesh *mesh, AttributePrimitive prim) const;
|
||||
size_t buffer_size(Mesh *mesh, AttributePrimitive prim) const;
|
||||
|
||||
char *data()
|
||||
{
|
||||
return (buffer.size())? &buffer[0]: NULL;
|
||||
}
|
||||
float2 *data_float2()
|
||||
{
|
||||
assert(data_sizeof() == sizeof(float2));
|
||||
return (float2*)data();
|
||||
}
|
||||
float3 *data_float3()
|
||||
{
|
||||
assert(data_sizeof() == sizeof(float3));
|
||||
return (float3*)data();
|
||||
}
|
||||
float4 *data_float4()
|
||||
{
|
||||
assert(data_sizeof() == sizeof(float4));
|
||||
return (float4*)data();
|
||||
}
|
||||
float *data_float()
|
||||
{
|
||||
assert(data_sizeof() == sizeof(float));
|
||||
return (float*)data();
|
||||
}
|
||||
uchar4 *data_uchar4()
|
||||
{
|
||||
assert(data_sizeof() == sizeof(uchar4));
|
||||
return (uchar4*)data();
|
||||
}
|
||||
Transform *data_transform()
|
||||
{
|
||||
assert(data_sizeof() == sizeof(Transform));
|
||||
return (Transform*)data();
|
||||
}
|
||||
VoxelAttribute *data_voxel()
|
||||
{
|
||||
assert(data_sizeof() == sizeof(VoxelAttribute));
|
||||
return ( VoxelAttribute*)data();
|
||||
}
|
||||
char *data() { return (buffer.size())? &buffer[0]: NULL; };
|
||||
float3 *data_float3() { return (float3*)data(); }
|
||||
float4 *data_float4() { return (float4*)data(); }
|
||||
float *data_float() { return (float*)data(); }
|
||||
uchar4 *data_uchar4() { return (uchar4*)data(); }
|
||||
Transform *data_transform() { return (Transform*)data(); }
|
||||
VoxelAttribute *data_voxel() { return ( VoxelAttribute*)data(); }
|
||||
|
||||
const char *data() const
|
||||
{
|
||||
return (buffer.size())? &buffer[0]: NULL;
|
||||
}
|
||||
const float2 *data_float2() const
|
||||
{
|
||||
assert(data_sizeof() == sizeof(float2));
|
||||
return (const float2*)data();
|
||||
}
|
||||
const float3 *data_float3() const
|
||||
{
|
||||
assert(data_sizeof() == sizeof(float3));
|
||||
return (const float3*)data();
|
||||
}
|
||||
const float4 *data_float4() const
|
||||
{
|
||||
assert(data_sizeof() == sizeof(float4));
|
||||
return (const float4*)data();
|
||||
}
|
||||
const float *data_float() const
|
||||
{
|
||||
assert(data_sizeof() == sizeof(float));
|
||||
return (const float*)data();
|
||||
}
|
||||
const Transform *data_transform() const
|
||||
{
|
||||
assert(data_sizeof() == sizeof(Transform));
|
||||
return (const Transform*)data();
|
||||
}
|
||||
const VoxelAttribute *data_voxel() const
|
||||
{
|
||||
assert(data_sizeof() == sizeof(VoxelAttribute));
|
||||
return (const VoxelAttribute*)data();
|
||||
}
|
||||
const char *data() const { return (buffer.size())? &buffer[0]: NULL; }
|
||||
const float3 *data_float3() const { return (const float3*)data(); }
|
||||
const float4 *data_float4() const { return (const float4*)data(); }
|
||||
const float *data_float() const { return (const float*)data(); }
|
||||
const Transform *data_transform() const { return (const Transform*)data(); }
|
||||
const VoxelAttribute *data_voxel() const { return (const VoxelAttribute*)data(); }
|
||||
|
||||
void zero_data(void* dst);
|
||||
void add_with_weight(void* dst, void* src, float weight);
|
||||
|
||||
void add(const float& f);
|
||||
void add(const float2& f);
|
||||
void add(const float3& f);
|
||||
void add(const uchar4& f);
|
||||
void add(const Transform& f);
|
||||
|
@@ -184,7 +184,6 @@ bool RenderBuffers::get_denoising_pass_rect(int type, float exposure, int sample
|
||||
if(type == DENOISING_PASS_CLEAN) {
|
||||
/* The clean pass isn't changed by prefiltering, so we use the original one there. */
|
||||
offset = type + params.get_denoising_offset();
|
||||
scale /= sample;
|
||||
}
|
||||
else if (type == DENOISING_PASS_PREFILTERED_COLOR && !params.denoising_prefiltered_pass) {
|
||||
/* If we're not saving the prefiltering result, return the original noisy pass. */
|
||||
|
@@ -169,8 +169,6 @@ Camera::Camera()
|
||||
cameratoworld = transform_identity();
|
||||
worldtoraster = projection_identity();
|
||||
|
||||
full_rastertocamera = projection_identity();
|
||||
|
||||
dx = make_float3(0.0f, 0.0f, 0.0f);
|
||||
dy = make_float3(0.0f, 0.0f, 0.0f);
|
||||
|
||||
@@ -253,7 +251,7 @@ void Camera::update(Scene *scene)
|
||||
ProjectionTransform screentocamera = projection_inverse(cameratoscreen);
|
||||
|
||||
rastertocamera = screentocamera * rastertoscreen;
|
||||
full_rastertocamera = screentocamera * full_rastertoscreen;
|
||||
ProjectionTransform full_rastertocamera = screentocamera * full_rastertoscreen;
|
||||
cameratoraster = screentoraster * cameratoscreen;
|
||||
|
||||
cameratoworld = matrix;
|
||||
@@ -629,7 +627,7 @@ float Camera::world_to_raster_size(float3 P)
|
||||
|
||||
if(offscreen_dicing_scale > 1.0f) {
|
||||
float3 p = transform_point(&worldtocamera, P);
|
||||
float3 v = transform_perspective(&full_rastertocamera, make_float3(full_width, full_height, 0.0f));
|
||||
float3 v = transform_perspective(&rastertocamera, make_float3(width, height, 0.0f));
|
||||
|
||||
/* Create point clamped to frustum */
|
||||
float3 c;
|
||||
@@ -646,8 +644,8 @@ float Camera::world_to_raster_size(float3 P)
|
||||
}
|
||||
else if(type == CAMERA_PERSPECTIVE) {
|
||||
/* Calculate as if point is directly ahead of the camera. */
|
||||
float3 raster = make_float3(0.5f*full_width, 0.5f*full_height, 0.0f);
|
||||
float3 Pcamera = transform_perspective(&full_rastertocamera, raster);
|
||||
float3 raster = make_float3(0.5f*width, 0.5f*height, 0.0f);
|
||||
float3 Pcamera = transform_perspective(&rastertocamera, raster);
|
||||
|
||||
/* dDdx */
|
||||
float3 Ddiff = transform_direction(&cameratoworld, Pcamera);
|
||||
@@ -730,21 +728,22 @@ float Camera::world_to_raster_size(float3 P)
|
||||
* point directly ahead seems to produce good enough results. */
|
||||
#if 0
|
||||
float2 dir = direction_to_panorama(&kernel_camera, kernel_camera_motion.data(), normalize(D));
|
||||
float3 raster = transform_perspective(&full_cameratoraster, make_float3(dir.x, dir.y, 0.0f));
|
||||
float3 raster = transform_perspective(&cameratoraster, make_float3(dir.x, dir.y, 0.0f));
|
||||
|
||||
ray.t = 1.0f;
|
||||
camera_sample_panorama(&kernel_camera, kernel_camera_motion.data(), raster.x, raster.y, 0.0f, 0.0f, &ray);
|
||||
if(ray.t == 0.0f) {
|
||||
/* No differentials, just use from directly ahead. */
|
||||
camera_sample_panorama(&kernel_camera, kernel_camera_motion.data(), 0.5f*full_width, 0.5f*full_height, 0.0f, 0.0f, &ray);
|
||||
camera_sample_panorama(&kernel_camera, kernel_camera_motion.data(), 0.5f*width, 0.5f*height, 0.0f, 0.0f, &ray);
|
||||
}
|
||||
#else
|
||||
camera_sample_panorama(&kernel_camera, kernel_camera_motion.data(), 0.5f*full_width, 0.5f*full_height, 0.0f, 0.0f, &ray);
|
||||
camera_sample_panorama(&kernel_camera, kernel_camera_motion.data(), 0.5f*width, 0.5f*height, 0.0f, 0.0f, &ray);
|
||||
#endif
|
||||
|
||||
differential_transfer(&ray.dP, ray.dP, ray.D, ray.dD, ray.D, dist);
|
||||
|
||||
return max(len(ray.dP.dx),len(ray.dP.dy));
|
||||
return max(len(ray.dP.dx) * (float(width)/float(full_width)),
|
||||
len(ray.dP.dy) * (float(height)/float(full_height)));
|
||||
}
|
||||
|
||||
return res;
|
||||
|
@@ -160,8 +160,6 @@ public:
|
||||
ProjectionTransform rastertocamera;
|
||||
ProjectionTransform cameratoraster;
|
||||
|
||||
ProjectionTransform full_rastertocamera;
|
||||
|
||||
float3 dx;
|
||||
float3 dy;
|
||||
|
||||
|
@@ -75,7 +75,7 @@ public:
|
||||
array<int> curve_firstkey;
|
||||
array<int> curve_keynum;
|
||||
array<float> curve_length;
|
||||
array<float2> curve_uv;
|
||||
array<float3> curve_uv;
|
||||
array<float3> curve_vcol;
|
||||
|
||||
array<float3> curvekey_co;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user