Compare commits

..

1 Commits

Author SHA1 Message Date
753dd8f09a First commit to this branch
This branch is supposed to serve as a template and tutorial to
newcomers of the Blender codebase.
2019-03-03 16:46:26 +11:00
1527 changed files with 30693 additions and 51068 deletions

View File

@@ -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

View File

@@ -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
#
####################################################################################################

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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()

View File

@@ -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")

View File

@@ -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)

View File

@@ -57,6 +57,7 @@
import struct
import sys
import getopt # command line arguments handling
from string import Template # strings completion

View File

@@ -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
*/

View File

@@ -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

View File

@@ -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?")

View File

@@ -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]

View File

@@ -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()

View File

@@ -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

View File

@@ -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,
)

View File

@@ -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

View File

@@ -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,

View File

@@ -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):

View File

@@ -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')

View File

@@ -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)

View File

@@ -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", ""),

View File

@@ -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)

View File

@@ -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__":

View File

@@ -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):

View File

@@ -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")

View File

@@ -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

View File

@@ -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
========

View File

@@ -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),

View File

@@ -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

View File

@@ -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);

View File

@@ -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.

View File

@@ -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
},

View File

@@ -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

View File

@@ -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

View File

@@ -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()

View File

@@ -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

View File

@@ -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

View File

@@ -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);

View File

@@ -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.")

View File

@@ -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}

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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():

View File

@@ -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)

View File

@@ -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,
)

View File

@@ -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

View File

@@ -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;

View File

@@ -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 */

View File

@@ -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);

View File

@@ -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, ""},

View File

@@ -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();

View File

@@ -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();

View File

@@ -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

View File

@@ -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) {

View File

@@ -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,

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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++;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);

View File

@@ -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,

View File

@@ -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)
{

View File

@@ -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

View File

@@ -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__

View File

@@ -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;
}

View File

@@ -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) {

View File

@@ -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)

View File

@@ -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 */

View File

@@ -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);

View File

@@ -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) {

View File

@@ -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);

View File

@@ -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 */

View File

@@ -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) {

View File

@@ -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__

View File

@@ -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)

View File

@@ -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__

View File

@@ -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;

View 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"

View File

@@ -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,

View File

@@ -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 {

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -141,7 +141,6 @@ typedef enum ShaderNodeType {
typedef enum NodeAttributeType {
NODE_ATTR_FLOAT = 0,
NODE_ATTR_FLOAT2,
NODE_ATTR_FLOAT3,
NODE_ATTR_MATRIX
} NodeAttributeType;

View File

@@ -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

View File

@@ -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;

View File

@@ -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);

View File

@@ -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. */

View File

@@ -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;

View File

@@ -160,8 +160,6 @@ public:
ProjectionTransform rastertocamera;
ProjectionTransform cameratoraster;
ProjectionTransform full_rastertocamera;
float3 dx;
float3 dy;

View File

@@ -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