Compare commits
49 Commits
obj-import
...
blenloader
Author | SHA1 | Date | |
---|---|---|---|
e003c31ca0 | |||
429e85c33a | |||
d2f2f732a5 | |||
7502cdd86f | |||
4e742352ec | |||
f0b75491e9 | |||
d7858eedbf | |||
7a5da6a16c | |||
5a90d35f79 | |||
fb29231e45 | |||
ab673563e8 | |||
bc317808d6 | |||
5961d6565b | |||
acc05a1053 | |||
dc3b6617bb | |||
d912bb9cce | |||
23a071ee6c | |||
d807418a45 | |||
9ad3a3754f | |||
b9a4a3ece5 | |||
f563674d58 | |||
0fa3a00f34 | |||
7ed6e3a5ef | |||
c6e61edb34 | |||
a883e0a30e | |||
cfa101cf46 | |||
520db97acf | |||
6f77056dca | |||
0d444bd3ef | |||
0e52777cf0 | |||
f9e4086b04 | |||
192091903e | |||
681ff0c789 | |||
081311d168 | |||
e41f2c1238 | |||
ac7d45cc19 | |||
eafb864bfe | |||
fb13e40ce1 | |||
ff86d46805 | |||
ecb4c5d8a4 | |||
a0ec12a249 | |||
c3c2ea39b2 | |||
ac8d26974e | |||
d7839734a0 | |||
672372583e | |||
4c95dc5a1b | |||
7adcc0731e | |||
7c08cd508a | |||
a9f39fa197 |
@@ -132,7 +132,9 @@ PenaltyBreakAssignment: 100
|
||||
|
||||
AllowShortFunctionsOnASingleLine: None
|
||||
|
||||
SortIncludes: true
|
||||
# Disable for now since it complicates initial migration tests,
|
||||
# TODO: look into enabling this in the future.
|
||||
SortIncludes: false
|
||||
|
||||
# Don't right align escaped newlines to the right because we have a wide default
|
||||
AlignEscapedNewlines: DontAlign
|
||||
|
@@ -186,7 +186,8 @@ if(APPLE)
|
||||
option(WITH_XR_OPENXR "Enable VR features through the OpenXR specification" OFF)
|
||||
mark_as_advanced(WITH_XR_OPENXR)
|
||||
else()
|
||||
option(WITH_XR_OPENXR "Enable VR features through the OpenXR specification" ON)
|
||||
# Disabled until there's more than just the build system stuff. Should be enabled soon.
|
||||
option(WITH_XR_OPENXR "Enable VR features through the OpenXR specification" OFF)
|
||||
endif()
|
||||
|
||||
# Compositor
|
||||
@@ -319,10 +320,6 @@ mark_as_advanced(WITH_SYSTEM_GLOG)
|
||||
# Freestyle
|
||||
option(WITH_FREESTYLE "Enable Freestyle (advanced edges rendering)" ON)
|
||||
|
||||
# New object types
|
||||
option(WITH_NEW_OBJECT_TYPES "Enable new hair and pointcloud objects (use for development only, don't save in files)" OFF)
|
||||
mark_as_advanced(WITH_NEW_OBJECT_TYPES)
|
||||
|
||||
# Misc
|
||||
if(WIN32)
|
||||
option(WITH_INPUT_IME "Enable Input Method Editor (IME) for complex Asian character input" ON)
|
||||
@@ -684,7 +681,6 @@ if(WITH_GHOST_SDL OR WITH_HEADLESS)
|
||||
set(WITH_X11_ALPHA OFF)
|
||||
set(WITH_GHOST_XDND OFF)
|
||||
set(WITH_INPUT_IME OFF)
|
||||
set(WITH_XR_OPENXR OFF)
|
||||
endif()
|
||||
|
||||
if(WITH_CPU_SSE)
|
||||
|
@@ -162,7 +162,7 @@ harvest(opensubdiv/lib opensubdiv/lib "*.a")
|
||||
harvest(openvdb/include/openvdb openvdb/include/openvdb "*.h")
|
||||
harvest(openvdb/lib openvdb/lib "*.a")
|
||||
harvest(xr_openxr_sdk/include/openxr xr_openxr_sdk/include/openxr "*.h")
|
||||
harvest(xr_openxr_sdk/lib xr_openxr_sdk/lib "*.a")
|
||||
harvest(xr_openxr_sdk/lib xr_openxr_sdk/src/loader "*.a")
|
||||
harvest(osl/bin osl/bin "oslc")
|
||||
harvest(osl/include osl/include "*.h")
|
||||
harvest(osl/lib osl/lib "*.a")
|
||||
|
@@ -29,7 +29,6 @@ if(UNIX AND NOT APPLE)
|
||||
-DBUILD_WITH_WAYLAND_HEADERS=OFF
|
||||
-DBUILD_WITH_XCB_HEADERS=OFF
|
||||
-DBUILD_WITH_XLIB_HEADERS=ON
|
||||
-DCMAKE_CXX_FLAGS=-DDISABLE_STD_FILESYSTEM=1
|
||||
)
|
||||
endif()
|
||||
|
||||
|
@@ -3128,7 +3128,7 @@ compile_XR_OpenXR_SDK() {
|
||||
fi
|
||||
|
||||
# To be changed each time we make edits that would modify the compiled result!
|
||||
xr_openxr_magic=1
|
||||
xr_openxr_magic=0
|
||||
_init_xr_openxr_sdk
|
||||
|
||||
# Clean install if needed!
|
||||
@@ -3186,7 +3186,7 @@ compile_XR_OpenXR_SDK() {
|
||||
cmake_d="$cmake_d -D BUILD_WITH_XCB_HEADERS=OFF"
|
||||
cmake_d="$cmake_d -D BUILD_WITH_XLIB_HEADERS=ON"
|
||||
|
||||
cmake $cmake_d "-DCMAKE_CXX_FLAGS=-DDISABLE_STD_FILESYSTEM=1" ..
|
||||
cmake $cmake_d ..
|
||||
|
||||
make -j$THREADS && make install
|
||||
make clean
|
||||
@@ -5377,7 +5377,7 @@ print_info() {
|
||||
PRINT " $_1"
|
||||
_buildargs="$_buildargs $_1"
|
||||
if [ -d $INST/xr-openxr-sdk ]; then
|
||||
_1="-D XR_OPENXR_SDK_ROOT_DIR=$INST/xr-openxr-sdk"
|
||||
_1="-D XR_OPENXR_ROOT_DIR=$INST/xr-openxr-sdk"
|
||||
PRINT " $_1"
|
||||
_buildargs="$_buildargs $_1"
|
||||
fi
|
||||
|
@@ -98,7 +98,7 @@ class VersionInfo:
|
||||
self.is_development_build = False
|
||||
else:
|
||||
# Development build
|
||||
self.full_version = self.version + self.version_char + '-' + self.hash
|
||||
self.full_version = self.version + '-' + self.hash
|
||||
self.is_development_build = True
|
||||
|
||||
def _parse_header_file(self, filename, define):
|
||||
|
@@ -23,7 +23,7 @@ echo - with_tests ^(enable building unit tests^)
|
||||
echo - nobuildinfo ^(disable buildinfo^)
|
||||
echo - debug ^(Build an unoptimized debuggable build^)
|
||||
echo - packagename [newname] ^(override default cpack package name^)
|
||||
echo - builddir [newdir] ^(override default build folder^)
|
||||
echo - buildir [newdir] ^(override default build folder^)
|
||||
echo - 2017 ^(build with visual studio 2017^)
|
||||
echo - 2017pre ^(build with visual studio 2017 pre-release^)
|
||||
echo - 2017b ^(build with visual studio 2017 Build Tools^)
|
||||
|
7
extern/bullet2/CMakeLists.txt
vendored
7
extern/bullet2/CMakeLists.txt
vendored
@@ -415,11 +415,4 @@ if(CMAKE_COMPILER_IS_GNUCXX)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fpermissive")
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
# bullet is responsible for quite a few silly warnings
|
||||
# suppress all of them. Not great, but they really needed
|
||||
# to sort that out themselves.
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W0")
|
||||
endif()
|
||||
|
||||
blender_add_lib(extern_bullet "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
|
||||
|
5
extern/glog/CMakeLists.txt
vendored
5
extern/glog/CMakeLists.txt
vendored
@@ -77,11 +77,6 @@ if(WIN32)
|
||||
list(APPEND INC
|
||||
src/windows
|
||||
)
|
||||
if(MSVC)
|
||||
# Suppress warning about google::LogMessageFatal::~LogMessageFatal
|
||||
# not returning.
|
||||
add_definitions("/wd4722")
|
||||
endif()
|
||||
else()
|
||||
list(APPEND INC
|
||||
include
|
||||
|
@@ -192,7 +192,7 @@ int cbDisableConstructor(PyObject *self, PyObject *args, PyObject *kwds)
|
||||
return -1;
|
||||
}
|
||||
|
||||
PyMODINIT_FUNC PyInit_manta_main(void)
|
||||
PyMODINIT_FUNC PyInit_Main(void)
|
||||
{
|
||||
MantaEnsureRegistration();
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
@@ -567,7 +567,7 @@ void WrapperRegistry::construct(const string &scriptname, const vector<string> &
|
||||
registerDummyTypes();
|
||||
|
||||
// work around for certain gcc versions, cast to char*
|
||||
PyImport_AppendInittab((char *)gDefaultModuleName.c_str(), PyInit_manta_main);
|
||||
PyImport_AppendInittab((char *)gDefaultModuleName.c_str(), PyInit_Main);
|
||||
}
|
||||
|
||||
inline PyObject *castPy(PyTypeObject *p)
|
||||
|
2
extern/mantaflow/helper/pwrapper/registry.h
vendored
2
extern/mantaflow/helper/pwrapper/registry.h
vendored
@@ -62,7 +62,7 @@ void MantaEnsureRegistration();
|
||||
|
||||
#ifdef BLENDER
|
||||
# ifdef PyMODINIT_FUNC
|
||||
PyMODINIT_FUNC PyInit_manta_main(void);
|
||||
PyMODINIT_FUNC PyInit_Main(void);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
2
extern/mantaflow/helper/util/vectorbase.h
vendored
2
extern/mantaflow/helper/util/vectorbase.h
vendored
@@ -15,7 +15,7 @@
|
||||
#define _VECTORBASE_H
|
||||
|
||||
// get rid of windos min/max defines
|
||||
#if (defined(WIN32) || defined(_WIN32)) && !defined(NOMINMAX)
|
||||
#if defined(WIN32) || defined(_WIN32)
|
||||
# define NOMINMAX
|
||||
#endif
|
||||
|
||||
|
2
extern/mantaflow/preprocessed/gitinfo.h
vendored
2
extern/mantaflow/preprocessed/gitinfo.h
vendored
@@ -1,3 +1,3 @@
|
||||
|
||||
|
||||
#define MANTA_GIT_VERSION "commit 5fbd3d04381b21afce4a593d1fe2d9bc7bef5424"
|
||||
#define MANTA_GIT_VERSION "commit 1d52e96ad602f1974dfee75bef293bc397e4b41b"
|
||||
|
@@ -1171,11 +1171,6 @@ void solvePressureSystem(Grid<Real> &rhs,
|
||||
maxIter = 100;
|
||||
|
||||
pmg = gMapMG[parent];
|
||||
// Release MG from previous step if present (e.g. if previous solve was with MGStatic)
|
||||
if (pmg && preconditioner == PcMGDynamic) {
|
||||
releaseMG(parent);
|
||||
pmg = nullptr;
|
||||
}
|
||||
if (!pmg) {
|
||||
pmg = new GridMg(pressure.getSize());
|
||||
gMapMG[parent] = pmg;
|
||||
|
@@ -37,8 +37,8 @@
|
||||
#endif
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
||||
#include <intrin.h>
|
||||
#include <windows.h>
|
||||
#include <intrin.h>
|
||||
|
||||
#if defined(__clang__)
|
||||
# pragma GCC diagnostic push
|
||||
|
@@ -47,10 +47,10 @@
|
||||
#ifndef __ATOMIC_OPS_UTILS_H__
|
||||
#define __ATOMIC_OPS_UTILS_H__
|
||||
|
||||
#include <limits.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
|
@@ -25,8 +25,8 @@
|
||||
#include "AUD_PyInit.h"
|
||||
|
||||
#include <AUD_Sound.h>
|
||||
#include <python/PyAPI.h>
|
||||
#include <python/PySound.h>
|
||||
#include <python/PyAPI.h>
|
||||
|
||||
extern "C" {
|
||||
extern void *BKE_sound_get_factory(void *sound);
|
||||
|
@@ -18,23 +18,23 @@
|
||||
* \ingroup clog
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
|
||||
/* Disable for small single threaded programs
|
||||
* to avoid having to link with pthreads. */
|
||||
#ifdef WITH_CLOG_PTHREADS
|
||||
# include "atomic_ops.h"
|
||||
# include <pthread.h>
|
||||
# include "atomic_ops.h"
|
||||
#endif
|
||||
|
||||
/* For 'isatty' to check for color. */
|
||||
#if defined(__unix__) || defined(__APPLE__) || defined(__HAIKU__)
|
||||
# include <sys/time.h>
|
||||
# include <unistd.h>
|
||||
# include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
|
@@ -177,11 +177,14 @@ if(CXX_HAS_AVX2)
|
||||
add_definitions(-DWITH_KERNEL_AVX2)
|
||||
endif()
|
||||
|
||||
# LLVM and OSL need to build without RTTI
|
||||
if(WIN32 AND MSVC)
|
||||
set(RTTI_DISABLE_FLAGS "/GR- -DBOOST_NO_RTTI -DBOOST_NO_TYPEID")
|
||||
elseif(CMAKE_COMPILER_IS_GNUCC OR (CMAKE_C_COMPILER_ID MATCHES "Clang"))
|
||||
set(RTTI_DISABLE_FLAGS "-fno-rtti -DBOOST_NO_RTTI -DBOOST_NO_TYPEID")
|
||||
if(WITH_CYCLES_OSL)
|
||||
# LLVM and OSL need to build without RTTI
|
||||
if(WIN32 AND MSVC)
|
||||
set(RTTI_DISABLE_FLAGS "/GR- -DBOOST_NO_RTTI -DBOOST_NO_TYPEID")
|
||||
elseif(CMAKE_COMPILER_IS_GNUCC OR (CMAKE_C_COMPILER_ID MATCHES "Clang"))
|
||||
set(RTTI_DISABLE_FLAGS "-fno-rtti -DBOOST_NO_RTTI -DBOOST_NO_TYPEID")
|
||||
endif()
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${RTTI_DISABLE_FLAGS}")
|
||||
endif()
|
||||
|
||||
# Definitions and Includes
|
||||
@@ -350,6 +353,17 @@ if(WITH_CYCLES_NETWORK)
|
||||
add_definitions(-DWITH_NETWORK)
|
||||
endif()
|
||||
|
||||
if(WITH_OPENCOLORIO)
|
||||
add_definitions(-DWITH_OCIO)
|
||||
include_directories(
|
||||
SYSTEM
|
||||
${OPENCOLORIO_INCLUDE_DIRS}
|
||||
)
|
||||
if(WIN32)
|
||||
add_definitions(-DOpenColorIO_STATIC)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WITH_CYCLES_STANDALONE OR WITH_CYCLES_NETWORK OR WITH_CYCLES_CUBIN_COMPILER)
|
||||
add_subdirectory(app)
|
||||
endif()
|
||||
|
@@ -60,7 +60,6 @@ link_directories(
|
||||
${TIFF_LIBPATH}
|
||||
${OPENEXR_LIBPATH}
|
||||
${OPENJPEG_LIBPATH}
|
||||
${OPENVDB_LIBPATH}
|
||||
)
|
||||
|
||||
if(WITH_OPENCOLORIO)
|
||||
|
@@ -14,8 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
@@ -20,11 +20,11 @@
|
||||
|
||||
#include "util/util_args.h"
|
||||
#include "util/util_foreach.h"
|
||||
#include "util/util_logging.h"
|
||||
#include "util/util_path.h"
|
||||
#include "util/util_stats.h"
|
||||
#include "util/util_string.h"
|
||||
#include "util/util_task.h"
|
||||
#include "util/util_logging.h"
|
||||
|
||||
using namespace ccl;
|
||||
|
||||
|
@@ -16,12 +16,12 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "device/device.h"
|
||||
#include "render/buffers.h"
|
||||
#include "render/camera.h"
|
||||
#include "render/integrator.h"
|
||||
#include "device/device.h"
|
||||
#include "render/scene.h"
|
||||
#include "render/session.h"
|
||||
#include "render/integrator.h"
|
||||
|
||||
#include "util/util_args.h"
|
||||
#include "util/util_foreach.h"
|
||||
|
@@ -16,9 +16,9 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <sstream>
|
||||
|
||||
#include "graph/node_xml.h"
|
||||
|
||||
@@ -32,8 +32,8 @@
|
||||
#include "render/nodes.h"
|
||||
#include "render/object.h"
|
||||
#include "render/osl.h"
|
||||
#include "render/scene.h"
|
||||
#include "render/shader.h"
|
||||
#include "render/scene.h"
|
||||
|
||||
#include "subd/subd_patch.h"
|
||||
#include "subd/subd_split.h"
|
||||
@@ -292,7 +292,7 @@ static void xml_read_shader_graph(XMLReadState &state, Shader *shader, xml_node
|
||||
filepath = path_join(state.base, filepath);
|
||||
}
|
||||
|
||||
snode = OSLShaderManager::osl_node(manager, filepath);
|
||||
snode = ((OSLShaderManager *)manager)->osl_node(filepath);
|
||||
|
||||
if (!snode) {
|
||||
fprintf(stderr, "Failed to create OSL node from \"%s\".\n", filepath.c_str());
|
||||
|
@@ -38,7 +38,6 @@ set(SRC
|
||||
CCL_api.h
|
||||
blender_device.h
|
||||
blender_id_map.h
|
||||
blender_image.h
|
||||
blender_object_cull.h
|
||||
blender_sync.h
|
||||
blender_session.h
|
||||
@@ -92,20 +91,6 @@ if(WITH_MOD_FLUID)
|
||||
add_definitions(-DWITH_FLUID)
|
||||
endif()
|
||||
|
||||
if(WITH_NEW_OBJECT_TYPES)
|
||||
add_definitions(-DWITH_NEW_OBJECT_TYPES)
|
||||
endif()
|
||||
|
||||
if(WITH_OPENVDB)
|
||||
add_definitions(-DWITH_OPENVDB ${OPENVDB_DEFINITIONS})
|
||||
list(APPEND INC_SYS
|
||||
${OPENVDB_INCLUDE_DIRS}
|
||||
)
|
||||
list(APPEND LIB
|
||||
${OPENVDB_LIBRARIES}
|
||||
)
|
||||
endif()
|
||||
|
||||
blender_add_lib(bf_intern_cycles "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
|
||||
|
||||
# avoid link failure with clang 3.4 debug
|
||||
|
@@ -33,7 +33,7 @@ def _is_using_buggy_driver():
|
||||
# in the version string, but those cards do not quite work and
|
||||
# causing crashes.
|
||||
return True
|
||||
regex = re.compile(".*Compatibility Profile Context ([0-9]+(\\.[0-9]+)+)$")
|
||||
regex = re.compile(".*Compatibility Profile Context ([0-9]+(\.[0-9]+)+)$")
|
||||
if not regex.match(version):
|
||||
# Skip cards like FireGL
|
||||
return False
|
||||
|
@@ -361,7 +361,6 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
|
||||
description="Noise level step to stop sampling at, lower values reduce noise the cost of render time. Zero for automatic setting based on number of AA samples",
|
||||
min=0.0, max=1.0,
|
||||
default=0.0,
|
||||
precision=4,
|
||||
)
|
||||
adaptive_min_samples: IntProperty(
|
||||
name="Adaptive Min Samples",
|
||||
@@ -444,20 +443,13 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
|
||||
default=8,
|
||||
)
|
||||
|
||||
volume_step_rate: FloatProperty(
|
||||
name="Step Rate",
|
||||
description="Globally adjust detail for volume rendering, on top of automatically estimated step size. "
|
||||
"Higher values reduce render time, lower values render with more detail",
|
||||
default=1.0,
|
||||
min=0.01, max=100.0, soft_min=0.1, soft_max=10.0, precision=2
|
||||
)
|
||||
|
||||
volume_preview_step_rate: FloatProperty(
|
||||
name="Step Rate",
|
||||
description="Globally adjust detail for volume rendering, on top of automatically estimated step size. "
|
||||
"Higher values reduce render time, lower values render with more detail",
|
||||
default=1.0,
|
||||
min=0.01, max=100.0, soft_min=0.1, soft_max=10.0, precision=2
|
||||
volume_step_size: FloatProperty(
|
||||
name="Step Size",
|
||||
description="Distance between volume shader samples when rendering the volume "
|
||||
"(lower values give more accurate and detailed results, but also increased render time)",
|
||||
default=0.1,
|
||||
min=0.0000001, max=100000.0, soft_min=0.01, soft_max=1.0, precision=4,
|
||||
unit='LENGTH'
|
||||
)
|
||||
|
||||
volume_max_steps: IntProperty(
|
||||
@@ -941,14 +933,6 @@ class CyclesMaterialSettings(bpy.types.PropertyGroup):
|
||||
default='LINEAR',
|
||||
)
|
||||
|
||||
volume_step_rate: FloatProperty(
|
||||
name="Step Rate",
|
||||
description="Scale the distance between volume shader samples when rendering the volume "
|
||||
"(lower values give more accurate and detailed results, but also increased render time)",
|
||||
default=1.0,
|
||||
min=0.001, max=1000.0, soft_min=0.1, soft_max=10.0, precision=4
|
||||
)
|
||||
|
||||
displacement_method: EnumProperty(
|
||||
name="Displacement Method",
|
||||
description="Method to use for the displacement",
|
||||
@@ -1059,13 +1043,6 @@ class CyclesWorldSettings(bpy.types.PropertyGroup):
|
||||
items=enum_volume_interpolation,
|
||||
default='LINEAR',
|
||||
)
|
||||
volume_step_size: FloatProperty(
|
||||
name="Step Size",
|
||||
description="Distance between volume shader samples when rendering the volume "
|
||||
"(lower values give more accurate and detailed results, but also increased render time)",
|
||||
default=1.0,
|
||||
min=0.0000001, max=100000.0, soft_min=0.1, soft_max=100.0, precision=4
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def register(cls):
|
||||
|
@@ -373,7 +373,7 @@ class CYCLES_RENDER_PT_subdivision(CyclesButtonsPanel, Panel):
|
||||
col = layout.column()
|
||||
sub = col.column(align=True)
|
||||
sub.prop(cscene, "dicing_rate", text="Dicing Rate Render")
|
||||
sub.prop(cscene, "preview_dicing_rate", text="Viewport")
|
||||
sub.prop(cscene, "preview_dicing_rate", text="Preview")
|
||||
|
||||
col.separator()
|
||||
|
||||
@@ -428,11 +428,9 @@ class CYCLES_RENDER_PT_volumes(CyclesButtonsPanel, Panel):
|
||||
scene = context.scene
|
||||
cscene = scene.cycles
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.prop(cscene, "volume_step_rate", text="Step Rate Render")
|
||||
col.prop(cscene, "volume_preview_step_rate", text="Viewport")
|
||||
|
||||
layout.prop(cscene, "volume_max_steps", text="Max Steps")
|
||||
col = layout.column()
|
||||
col.prop(cscene, "volume_step_size", text="Step Size")
|
||||
col.prop(cscene, "volume_max_steps", text="Max Steps")
|
||||
|
||||
|
||||
class CYCLES_RENDER_PT_light_paths(CyclesButtonsPanel, Panel):
|
||||
@@ -772,8 +770,6 @@ class CYCLES_RENDER_PT_filter(CyclesButtonsPanel, Panel):
|
||||
col.prop(view_layer, "use_solid", text="Surfaces")
|
||||
col = flow.column()
|
||||
col.prop(view_layer, "use_strand", text="Hair")
|
||||
col = flow.column()
|
||||
col.prop(view_layer, "use_volumes", text="Volumes")
|
||||
if with_freestyle:
|
||||
col = flow.column()
|
||||
col.prop(view_layer, "use_freestyle", text="Freestyle")
|
||||
@@ -1417,6 +1413,8 @@ class CYCLES_LIGHT_PT_light(CyclesButtonsPanel, Panel):
|
||||
light = context.light
|
||||
clamp = light.cycles
|
||||
|
||||
layout.use_property_decorate = False
|
||||
|
||||
if self.bl_space_type == 'PROPERTIES':
|
||||
layout.row().prop(light, "type", expand=True)
|
||||
layout.use_property_split = True
|
||||
@@ -1698,9 +1696,6 @@ class CYCLES_WORLD_PT_settings_volume(CyclesButtonsPanel, Panel):
|
||||
sub.prop(cworld, "volume_sampling", text="Sampling")
|
||||
col.prop(cworld, "volume_interpolation", text="Interpolation")
|
||||
col.prop(cworld, "homogeneous_volume", text="Homogeneous")
|
||||
sub = col.column()
|
||||
sub.active = not cworld.homogeneous_volume
|
||||
sub.prop(cworld, "volume_step_size")
|
||||
|
||||
|
||||
class CYCLES_MATERIAL_PT_preview(CyclesButtonsPanel, Panel):
|
||||
@@ -1832,9 +1827,6 @@ class CYCLES_MATERIAL_PT_settings_volume(CyclesButtonsPanel, Panel):
|
||||
sub.prop(cmat, "volume_sampling", text="Sampling")
|
||||
col.prop(cmat, "volume_interpolation", text="Interpolation")
|
||||
col.prop(cmat, "homogeneous_volume", text="Homogeneous")
|
||||
sub = col.column()
|
||||
sub.active = not cmat.homogeneous_volume
|
||||
sub.prop(cmat, "volume_step_rate")
|
||||
|
||||
def draw(self, context):
|
||||
self.draw_shared(self, context, context.material)
|
||||
|
@@ -595,6 +595,40 @@ static void ExportCurveTriangleGeometry(Mesh *mesh, ParticleCurveData *CData, in
|
||||
/* texture coords still needed */
|
||||
}
|
||||
|
||||
static void export_hair_motion_validate_attribute(Hair *hair,
|
||||
int motion_step,
|
||||
int num_motion_keys,
|
||||
bool have_motion)
|
||||
{
|
||||
Attribute *attr_mP = hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
|
||||
const int num_keys = hair->curve_keys.size();
|
||||
|
||||
if (num_motion_keys != num_keys || !have_motion) {
|
||||
/* No motion or hair "topology" changed, remove attributes again. */
|
||||
if (num_motion_keys != num_keys) {
|
||||
VLOG(1) << "Hair topology changed, removing attribute.";
|
||||
}
|
||||
else {
|
||||
VLOG(1) << "No motion, removing attribute.";
|
||||
}
|
||||
hair->attributes.remove(ATTR_STD_MOTION_VERTEX_POSITION);
|
||||
}
|
||||
else if (motion_step > 0) {
|
||||
VLOG(1) << "Filling in new motion vertex position for motion_step " << motion_step;
|
||||
|
||||
/* Motion, fill up previous steps that we might have skipped because
|
||||
* they had no motion, but we need them anyway now. */
|
||||
for (int step = 0; step < motion_step; step++) {
|
||||
float4 *mP = attr_mP->data_float4() + step * num_keys;
|
||||
|
||||
for (int key = 0; key < num_keys; key++) {
|
||||
mP[key] = float3_to_float4(hair->curve_keys[key]);
|
||||
mP[key].w = hair->curve_radius[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ExportCurveSegments(Scene *scene, Hair *hair, ParticleCurveData *CData)
|
||||
{
|
||||
int num_keys = 0;
|
||||
@@ -714,40 +748,6 @@ static float4 LerpCurveSegmentMotionCV(ParticleCurveData *CData, int sys, int cu
|
||||
return lerp(mP, mP2, remainder);
|
||||
}
|
||||
|
||||
static void export_hair_motion_validate_attribute(Hair *hair,
|
||||
int motion_step,
|
||||
int num_motion_keys,
|
||||
bool have_motion)
|
||||
{
|
||||
Attribute *attr_mP = hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
|
||||
const int num_keys = hair->curve_keys.size();
|
||||
|
||||
if (num_motion_keys != num_keys || !have_motion) {
|
||||
/* No motion or hair "topology" changed, remove attributes again. */
|
||||
if (num_motion_keys != num_keys) {
|
||||
VLOG(1) << "Hair topology changed, removing attribute.";
|
||||
}
|
||||
else {
|
||||
VLOG(1) << "No motion, removing attribute.";
|
||||
}
|
||||
hair->attributes.remove(ATTR_STD_MOTION_VERTEX_POSITION);
|
||||
}
|
||||
else if (motion_step > 0) {
|
||||
VLOG(1) << "Filling in new motion vertex position for motion_step " << motion_step;
|
||||
|
||||
/* Motion, fill up previous steps that we might have skipped because
|
||||
* they had no motion, but we need them anyway now. */
|
||||
for (int step = 0; step < motion_step; step++) {
|
||||
float4 *mP = attr_mP->data_float4() + step * num_keys;
|
||||
|
||||
for (int key = 0; key < num_keys; key++) {
|
||||
mP[key] = float3_to_float4(hair->curve_keys[key]);
|
||||
mP[key].w = hair->curve_radius[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ExportCurveSegmentsMotion(Hair *hair, ParticleCurveData *CData, int motion_step)
|
||||
{
|
||||
VLOG(1) << "Exporting curve motion segments for hair " << hair->name << ", motion step "
|
||||
@@ -817,7 +817,7 @@ static void ExportCurveSegmentsMotion(Hair *hair, ParticleCurveData *CData, int
|
||||
}
|
||||
}
|
||||
|
||||
/* In case of new attribute, we verify if there really was any motion. */
|
||||
/* in case of new attribute, we verify if there really was any motion */
|
||||
if (new_attribute) {
|
||||
export_hair_motion_validate_attribute(hair, motion_step, i, have_motion);
|
||||
}
|
||||
@@ -1154,194 +1154,6 @@ void BlenderSync::sync_particle_hair(
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WITH_NEW_OBJECT_TYPES
|
||||
static float4 hair_point_as_float4(BL::HairPoint b_point)
|
||||
{
|
||||
float4 mP = float3_to_float4(get_float3(b_point.co()));
|
||||
mP.w = b_point.radius();
|
||||
return mP;
|
||||
}
|
||||
|
||||
static float4 interpolate_hair_points(BL::Hair b_hair,
|
||||
const int first_point_index,
|
||||
const int num_points,
|
||||
const float step)
|
||||
{
|
||||
const float curve_t = step * (num_points - 1);
|
||||
const int point_a = clamp((int)curve_t, 0, num_points - 1);
|
||||
const int point_b = min(point_a + 1, num_points - 1);
|
||||
const float t = curve_t - (float)point_a;
|
||||
return lerp(hair_point_as_float4(b_hair.points[first_point_index + point_a]),
|
||||
hair_point_as_float4(b_hair.points[first_point_index + point_b]),
|
||||
t);
|
||||
}
|
||||
|
||||
static void export_hair_curves(Scene *scene, Hair *hair, BL::Hair b_hair)
|
||||
{
|
||||
/* TODO: optimize so we can straight memcpy arrays from Blender? */
|
||||
|
||||
/* Add requested attributes. */
|
||||
Attribute *attr_intercept = NULL;
|
||||
Attribute *attr_random = NULL;
|
||||
|
||||
if (hair->need_attribute(scene, ATTR_STD_CURVE_INTERCEPT)) {
|
||||
attr_intercept = hair->attributes.add(ATTR_STD_CURVE_INTERCEPT);
|
||||
}
|
||||
if (hair->need_attribute(scene, ATTR_STD_CURVE_RANDOM)) {
|
||||
attr_random = hair->attributes.add(ATTR_STD_CURVE_RANDOM);
|
||||
}
|
||||
|
||||
/* Reserve memory. */
|
||||
const int num_keys = b_hair.points.length();
|
||||
const int num_curves = b_hair.curves.length();
|
||||
|
||||
if (num_curves > 0) {
|
||||
VLOG(1) << "Exporting curve segments for hair " << hair->name;
|
||||
}
|
||||
|
||||
hair->reserve_curves(num_curves, num_keys);
|
||||
|
||||
/* Export curves and points. */
|
||||
vector<float> points_length;
|
||||
|
||||
BL::Hair::curves_iterator b_curve_iter;
|
||||
for (b_hair.curves.begin(b_curve_iter); b_curve_iter != b_hair.curves.end(); ++b_curve_iter) {
|
||||
BL::HairCurve b_curve = *b_curve_iter;
|
||||
const int first_point_index = b_curve.first_point_index();
|
||||
const int num_points = b_curve.num_points();
|
||||
|
||||
float3 prev_co = make_float3(0.0f, 0.0f, 0.0f);
|
||||
float length = 0.0f;
|
||||
if (attr_intercept) {
|
||||
points_length.clear();
|
||||
points_length.reserve(num_points);
|
||||
}
|
||||
|
||||
/* Position and radius. */
|
||||
for (int i = 0; i < num_points; i++) {
|
||||
BL::HairPoint b_point = b_hair.points[first_point_index + i];
|
||||
|
||||
const float3 co = get_float3(b_point.co());
|
||||
const float radius = b_point.radius();
|
||||
hair->add_curve_key(co, radius);
|
||||
|
||||
if (attr_intercept) {
|
||||
if (i > 0) {
|
||||
length += len(co - prev_co);
|
||||
points_length.push_back(length);
|
||||
}
|
||||
prev_co = co;
|
||||
}
|
||||
}
|
||||
|
||||
/* Normalized 0..1 attribute along curve. */
|
||||
if (attr_intercept) {
|
||||
for (int i = 0; i < num_points; i++) {
|
||||
attr_intercept->add((length == 0.0f) ? 0.0f : points_length[i] / length);
|
||||
}
|
||||
}
|
||||
|
||||
/* Random number per curve. */
|
||||
if (attr_random != NULL) {
|
||||
attr_random->add(hash_uint2_to_float(b_curve.index(), 0));
|
||||
}
|
||||
|
||||
/* Curve. */
|
||||
const int shader_index = 0;
|
||||
hair->add_curve(first_point_index, shader_index);
|
||||
}
|
||||
}
|
||||
|
||||
static void export_hair_curves_motion(Hair *hair, BL::Hair b_hair, int motion_step)
|
||||
{
|
||||
VLOG(1) << "Exporting curve motion segments for hair " << hair->name << ", motion step "
|
||||
<< motion_step;
|
||||
|
||||
/* Find or add attribute. */
|
||||
Attribute *attr_mP = hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
|
||||
bool new_attribute = false;
|
||||
|
||||
if (!attr_mP) {
|
||||
VLOG(1) << "Creating new motion vertex position attribute";
|
||||
attr_mP = hair->attributes.add(ATTR_STD_MOTION_VERTEX_POSITION);
|
||||
new_attribute = true;
|
||||
}
|
||||
|
||||
/* Export motion keys. */
|
||||
const int num_keys = hair->curve_keys.size();
|
||||
float4 *mP = attr_mP->data_float4() + motion_step * num_keys;
|
||||
bool have_motion = false;
|
||||
int num_motion_keys = 0;
|
||||
int curve_index = 0;
|
||||
|
||||
BL::Hair::curves_iterator b_curve_iter;
|
||||
for (b_hair.curves.begin(b_curve_iter); b_curve_iter != b_hair.curves.end(); ++b_curve_iter) {
|
||||
BL::HairCurve b_curve = *b_curve_iter;
|
||||
const int first_point_index = b_curve.first_point_index();
|
||||
const int num_points = b_curve.num_points();
|
||||
|
||||
Hair::Curve curve = hair->get_curve(curve_index);
|
||||
curve_index++;
|
||||
|
||||
if (num_points == curve.num_keys) {
|
||||
/* Number of keys matches. */
|
||||
for (int i = 0; i < num_points; i++) {
|
||||
int point_index = first_point_index + i;
|
||||
|
||||
if (point_index < num_keys) {
|
||||
mP[num_motion_keys] = hair_point_as_float4(b_hair.points[point_index]);
|
||||
num_motion_keys++;
|
||||
|
||||
if (!have_motion) {
|
||||
/* TODO: use epsilon for comparison? Was needed for particles due to
|
||||
* transform, but ideally should not happen anymore. */
|
||||
float4 curve_key = float3_to_float4(hair->curve_keys[i]);
|
||||
curve_key.w = hair->curve_radius[i];
|
||||
have_motion = !(mP[i] == curve_key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Number of keys has changed. Generate an interpolated version
|
||||
* to preserve motion blur. */
|
||||
const float step_size = curve.num_keys > 1 ? 1.0f / (curve.num_keys - 1) : 0.0f;
|
||||
for (int i = 0; i < curve.num_keys; i++) {
|
||||
const float step = i * step_size;
|
||||
mP[num_motion_keys] = interpolate_hair_points(b_hair, first_point_index, num_points, step);
|
||||
num_motion_keys++;
|
||||
}
|
||||
have_motion = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* In case of new attribute, we verify if there really was any motion. */
|
||||
if (new_attribute) {
|
||||
export_hair_motion_validate_attribute(hair, motion_step, num_motion_keys, have_motion);
|
||||
}
|
||||
}
|
||||
#endif /* WITH_NEW_OBJECT_TYPES */
|
||||
|
||||
/* Hair object. */
|
||||
void BlenderSync::sync_hair(Hair *hair, BL::Object &b_ob, bool motion, int motion_step)
|
||||
{
|
||||
#ifdef WITH_NEW_OBJECT_TYPES
|
||||
/* Convert Blender hair to Cycles curves. */
|
||||
BL::Hair b_hair(b_ob.data());
|
||||
if (motion) {
|
||||
export_hair_curves_motion(hair, b_hair, motion_step);
|
||||
}
|
||||
else {
|
||||
export_hair_curves(scene, hair, b_hair);
|
||||
}
|
||||
#else
|
||||
(void)hair;
|
||||
(void)b_ob;
|
||||
(void)motion;
|
||||
(void)motion_step;
|
||||
#endif /* WITH_NEW_OBJECT_TYPES */
|
||||
}
|
||||
|
||||
void BlenderSync::sync_hair(BL::Depsgraph b_depsgraph,
|
||||
BL::Object b_ob,
|
||||
Geometry *geom,
|
||||
@@ -1367,24 +1179,14 @@ void BlenderSync::sync_hair(BL::Depsgraph b_depsgraph,
|
||||
geom->used_shaders = used_shaders;
|
||||
|
||||
if (view_layer.use_hair && scene->curve_system_manager->use_curves) {
|
||||
#ifdef WITH_NEW_OBJECT_TYPES
|
||||
if (b_ob.type() == BL::Object::type_HAIR) {
|
||||
/* Hair object. */
|
||||
sync_hair(hair, b_ob, false);
|
||||
assert(mesh == NULL);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* Particle hair. */
|
||||
bool need_undeformed = geom->need_attribute(scene, ATTR_STD_GENERATED);
|
||||
BL::Mesh b_mesh = object_to_mesh(
|
||||
b_data, b_ob, b_depsgraph, need_undeformed, Mesh::SUBDIVISION_NONE);
|
||||
/* Particle hair. */
|
||||
bool need_undeformed = geom->need_attribute(scene, ATTR_STD_GENERATED);
|
||||
BL::Mesh b_mesh = object_to_mesh(
|
||||
b_data, b_ob, b_depsgraph, need_undeformed, Mesh::SUBDIVISION_NONE);
|
||||
|
||||
if (b_mesh) {
|
||||
sync_particle_hair(geom, b_mesh, b_ob, false);
|
||||
free_object_to_mesh(b_data, b_ob, b_mesh);
|
||||
}
|
||||
if (b_mesh) {
|
||||
sync_particle_hair(geom, b_mesh, b_ob, false);
|
||||
free_object_to_mesh(b_data, b_ob, b_mesh);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1411,24 +1213,13 @@ void BlenderSync::sync_hair_motion(BL::Depsgraph b_depsgraph,
|
||||
|
||||
/* Export deformed coordinates. */
|
||||
if (ccl::BKE_object_is_deform_modified(b_ob, b_scene, preview)) {
|
||||
#ifdef WITH_NEW_OBJECT_TYPES
|
||||
if (b_ob.type() == BL::Object::type_HAIR) {
|
||||
/* Hair object. */
|
||||
sync_hair(hair, b_ob, true, motion_step);
|
||||
assert(mesh == NULL);
|
||||
/* Particle hair. */
|
||||
BL::Mesh b_mesh = object_to_mesh(b_data, b_ob, b_depsgraph, false, Mesh::SUBDIVISION_NONE);
|
||||
if (b_mesh) {
|
||||
sync_particle_hair(geom, b_mesh, b_ob, true, motion_step);
|
||||
free_object_to_mesh(b_data, b_ob, b_mesh);
|
||||
return;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* Particle hair. */
|
||||
BL::Mesh b_mesh = object_to_mesh(b_data, b_ob, b_depsgraph, false, Mesh::SUBDIVISION_NONE);
|
||||
if (b_mesh) {
|
||||
sync_particle_hair(geom, b_mesh, b_ob, true, motion_step);
|
||||
free_object_to_mesh(b_data, b_ob, b_mesh);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* No deformation on this frame, copy coordinates if other frames did have it. */
|
||||
|
@@ -17,8 +17,6 @@
|
||||
#include "blender/blender_device.h"
|
||||
#include "blender/blender_util.h"
|
||||
|
||||
#include "util/util_foreach.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
enum DenoiserType {
|
||||
|
@@ -18,9 +18,9 @@
|
||||
#define __BLENDER_DEVICE_H__
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
#include "RNA_types.h"
|
||||
#include "RNA_access.h"
|
||||
#include "RNA_blender_cpp.h"
|
||||
#include "RNA_types.h"
|
||||
|
||||
#include "device/device.h"
|
||||
|
||||
|
@@ -23,8 +23,6 @@
|
||||
#include "blender/blender_sync.h"
|
||||
#include "blender/blender_util.h"
|
||||
|
||||
#include "util/util_foreach.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph,
|
||||
@@ -38,19 +36,11 @@ Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph,
|
||||
BL::ID b_key_id = (BKE_object_is_modified(b_ob)) ? b_ob_instance : b_ob_data;
|
||||
GeometryKey key(b_key_id.ptr.data, use_particle_hair);
|
||||
BL::Material material_override = view_layer.material_override;
|
||||
Shader *default_shader = (b_ob.type() == BL::Object::type_VOLUME) ? scene->default_volume :
|
||||
scene->default_surface;
|
||||
#ifdef WITH_NEW_OBJECT_TYPES
|
||||
Geometry::Type geom_type = ((b_ob.type() == BL::Object::type_HAIR || use_particle_hair) &&
|
||||
Shader *default_shader = scene->default_surface;
|
||||
Geometry::Type geom_type = (use_particle_hair &&
|
||||
(scene->curve_system_manager->primitive != CURVE_TRIANGLES)) ?
|
||||
Geometry::HAIR :
|
||||
Geometry::MESH;
|
||||
#else
|
||||
Geometry::Type geom_type = ((use_particle_hair) &&
|
||||
(scene->curve_system_manager->primitive != CURVE_TRIANGLES)) ?
|
||||
Geometry::HAIR :
|
||||
Geometry::MESH;
|
||||
#endif
|
||||
|
||||
/* Find shader indices. */
|
||||
vector<Shader *> used_shaders;
|
||||
@@ -129,14 +119,10 @@ Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph,
|
||||
|
||||
geom->name = ustring(b_ob_data.name().c_str());
|
||||
|
||||
#ifdef WITH_NEW_OBJECT_TYPES
|
||||
if (b_ob.type() == BL::Object::type_HAIR || use_particle_hair) {
|
||||
#else
|
||||
if (use_particle_hair) {
|
||||
#endif
|
||||
sync_hair(b_depsgraph, b_ob, geom, used_shaders);
|
||||
}
|
||||
else if (b_ob.type() == BL::Object::type_VOLUME || object_fluid_gas_domain_find(b_ob)) {
|
||||
else if (object_fluid_gas_domain_find(b_ob)) {
|
||||
Mesh *mesh = static_cast<Mesh *>(geom);
|
||||
sync_volume(b_ob, mesh, used_shaders);
|
||||
}
|
||||
@@ -173,14 +159,10 @@ void BlenderSync::sync_geometry_motion(BL::Depsgraph &b_depsgraph,
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef WITH_NEW_OBJECT_TYPES
|
||||
if (b_ob.type() == BL::Object::type_HAIR || use_particle_hair) {
|
||||
#else
|
||||
if (use_particle_hair) {
|
||||
#endif
|
||||
sync_hair_motion(b_depsgraph, b_ob, geom, motion_step);
|
||||
}
|
||||
else if (b_ob.type() == BL::Object::type_VOLUME || object_fluid_gas_domain_find(b_ob)) {
|
||||
else if (object_fluid_gas_domain_find(b_ob)) {
|
||||
/* No volume motion blur support yet. */
|
||||
}
|
||||
else {
|
||||
|
@@ -14,71 +14,206 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
#include "render/image.h"
|
||||
|
||||
#include "blender/blender_image.h"
|
||||
#include "blender/blender_sync.h"
|
||||
#include "blender/blender_session.h"
|
||||
#include "blender/blender_util.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
/* Packed Images */
|
||||
|
||||
BlenderImageLoader::BlenderImageLoader(BL::Image b_image, int frame)
|
||||
: b_image(b_image), frame(frame), free_cache(!b_image.has_data())
|
||||
/* builtin image file name is actually an image datablock name with
|
||||
* absolute sequence frame number concatenated via '@' character
|
||||
*
|
||||
* this function splits frame from builtin name
|
||||
*/
|
||||
int BlenderSession::builtin_image_frame(const string &builtin_name)
|
||||
{
|
||||
int last = builtin_name.find_last_of('@');
|
||||
return atoi(builtin_name.substr(last + 1, builtin_name.size() - last - 1).c_str());
|
||||
}
|
||||
|
||||
bool BlenderImageLoader::load_metadata(ImageMetaData &metadata)
|
||||
void BlenderSession::builtin_image_info(const string &builtin_name,
|
||||
void *builtin_data,
|
||||
ImageMetaData &metadata)
|
||||
{
|
||||
metadata.width = b_image.size()[0];
|
||||
metadata.height = b_image.size()[1];
|
||||
metadata.depth = 1;
|
||||
metadata.channels = b_image.channels();
|
||||
/* empty image */
|
||||
metadata.width = 1;
|
||||
metadata.height = 1;
|
||||
|
||||
if (b_image.is_float()) {
|
||||
if (metadata.channels == 1) {
|
||||
metadata.type = IMAGE_DATA_TYPE_FLOAT;
|
||||
if (!builtin_data)
|
||||
return;
|
||||
|
||||
/* recover ID pointer */
|
||||
PointerRNA ptr;
|
||||
RNA_id_pointer_create((ID *)builtin_data, &ptr);
|
||||
BL::ID b_id(ptr);
|
||||
|
||||
if (b_id.is_a(&RNA_Image)) {
|
||||
/* image data */
|
||||
BL::Image b_image(b_id);
|
||||
|
||||
metadata.builtin_free_cache = !b_image.has_data();
|
||||
metadata.is_float = b_image.is_float();
|
||||
metadata.width = b_image.size()[0];
|
||||
metadata.height = b_image.size()[1];
|
||||
metadata.depth = 1;
|
||||
metadata.channels = b_image.channels();
|
||||
|
||||
if (metadata.is_float) {
|
||||
/* Float images are already converted on the Blender side,
|
||||
* no need to do anything in Cycles. */
|
||||
metadata.colorspace = u_colorspace_raw;
|
||||
}
|
||||
else if (metadata.channels == 4) {
|
||||
metadata.type = IMAGE_DATA_TYPE_FLOAT4;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
else if (b_id.is_a(&RNA_Object)) {
|
||||
/* smoke volume data */
|
||||
BL::Object b_ob(b_id);
|
||||
BL::FluidDomainSettings b_domain = object_fluid_gas_domain_find(b_ob);
|
||||
|
||||
metadata.is_float = true;
|
||||
metadata.depth = 1;
|
||||
metadata.channels = 1;
|
||||
|
||||
if (!b_domain)
|
||||
return;
|
||||
|
||||
if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_DENSITY) ||
|
||||
builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_FLAME) ||
|
||||
builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_HEAT) ||
|
||||
builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_TEMPERATURE))
|
||||
metadata.channels = 1;
|
||||
else if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_COLOR))
|
||||
metadata.channels = 4;
|
||||
else if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_VELOCITY))
|
||||
metadata.channels = 3;
|
||||
else
|
||||
return;
|
||||
|
||||
int3 resolution = get_int3(b_domain.domain_resolution());
|
||||
int amplify = (b_domain.use_noise()) ? b_domain.noise_scale() : 1;
|
||||
|
||||
/* Velocity and heat data is always low-resolution. */
|
||||
if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_VELOCITY) ||
|
||||
builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_HEAT)) {
|
||||
amplify = 1;
|
||||
}
|
||||
|
||||
/* Float images are already converted on the Blender side,
|
||||
* no need to do anything in Cycles. */
|
||||
metadata.colorspace = u_colorspace_raw;
|
||||
metadata.width = resolution.x * amplify;
|
||||
metadata.height = resolution.y * amplify;
|
||||
metadata.depth = resolution.z * amplify;
|
||||
}
|
||||
else {
|
||||
if (metadata.channels == 1) {
|
||||
metadata.type = IMAGE_DATA_TYPE_BYTE;
|
||||
/* TODO(sergey): Check we're indeed in shader node tree. */
|
||||
PointerRNA ptr;
|
||||
RNA_pointer_create(NULL, &RNA_Node, builtin_data, &ptr);
|
||||
BL::Node b_node(ptr);
|
||||
if (b_node.is_a(&RNA_ShaderNodeTexPointDensity)) {
|
||||
BL::ShaderNodeTexPointDensity b_point_density_node(b_node);
|
||||
metadata.channels = 4;
|
||||
metadata.width = b_point_density_node.resolution();
|
||||
metadata.height = metadata.width;
|
||||
metadata.depth = metadata.width;
|
||||
metadata.is_float = true;
|
||||
}
|
||||
else if (metadata.channels == 4) {
|
||||
metadata.type = IMAGE_DATA_TYPE_BYTE4;
|
||||
}
|
||||
}
|
||||
|
||||
bool BlenderSession::builtin_image_pixels(const string &builtin_name,
|
||||
void *builtin_data,
|
||||
int tile,
|
||||
unsigned char *pixels,
|
||||
const size_t pixels_size,
|
||||
const bool associate_alpha,
|
||||
const bool free_cache)
|
||||
{
|
||||
if (!builtin_data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const int frame = builtin_image_frame(builtin_name);
|
||||
|
||||
PointerRNA ptr;
|
||||
RNA_id_pointer_create((ID *)builtin_data, &ptr);
|
||||
BL::Image b_image(ptr);
|
||||
|
||||
const int width = b_image.size()[0];
|
||||
const int height = b_image.size()[1];
|
||||
const int channels = b_image.channels();
|
||||
|
||||
unsigned char *image_pixels = image_get_pixels_for_frame(b_image, frame, tile);
|
||||
const size_t num_pixels = ((size_t)width) * height;
|
||||
|
||||
if (image_pixels && num_pixels * channels == pixels_size) {
|
||||
memcpy(pixels, image_pixels, pixels_size * sizeof(unsigned char));
|
||||
}
|
||||
else {
|
||||
if (channels == 1) {
|
||||
memset(pixels, 0, pixels_size * sizeof(unsigned char));
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
const size_t num_pixels_safe = pixels_size / channels;
|
||||
unsigned char *cp = pixels;
|
||||
for (size_t i = 0; i < num_pixels_safe; i++, cp += channels) {
|
||||
cp[0] = 255;
|
||||
cp[1] = 0;
|
||||
cp[2] = 255;
|
||||
if (channels == 4) {
|
||||
cp[3] = 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (image_pixels) {
|
||||
MEM_freeN(image_pixels);
|
||||
}
|
||||
|
||||
/* Free image buffers to save memory during render. */
|
||||
if (free_cache) {
|
||||
b_image.buffers_free();
|
||||
}
|
||||
|
||||
if (associate_alpha) {
|
||||
/* Premultiply, byte images are always straight for Blender. */
|
||||
unsigned char *cp = pixels;
|
||||
for (size_t i = 0; i < num_pixels; i++, cp += channels) {
|
||||
cp[0] = (cp[0] * cp[3]) >> 8;
|
||||
cp[1] = (cp[1] * cp[3]) >> 8;
|
||||
cp[2] = (cp[2] * cp[3]) >> 8;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BlenderImageLoader::load_pixels(const ImageMetaData &metadata,
|
||||
void *pixels,
|
||||
const size_t pixels_size,
|
||||
const bool associate_alpha)
|
||||
bool BlenderSession::builtin_image_float_pixels(const string &builtin_name,
|
||||
void *builtin_data,
|
||||
int tile,
|
||||
float *pixels,
|
||||
const size_t pixels_size,
|
||||
const bool,
|
||||
const bool free_cache)
|
||||
{
|
||||
const size_t num_pixels = ((size_t)metadata.width) * metadata.height;
|
||||
const int channels = metadata.channels;
|
||||
const int tile = 0; /* TODO(lukas): Support tiles here? */
|
||||
if (!builtin_data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (b_image.is_float()) {
|
||||
PointerRNA ptr;
|
||||
RNA_id_pointer_create((ID *)builtin_data, &ptr);
|
||||
BL::ID b_id(ptr);
|
||||
|
||||
if (b_id.is_a(&RNA_Image)) {
|
||||
/* image data */
|
||||
BL::Image b_image(b_id);
|
||||
int frame = builtin_image_frame(builtin_name);
|
||||
|
||||
const int width = b_image.size()[0];
|
||||
const int height = b_image.size()[1];
|
||||
const int channels = b_image.channels();
|
||||
|
||||
float *image_pixels;
|
||||
image_pixels = image_get_float_pixels_for_frame(b_image, frame, tile);
|
||||
const size_t num_pixels = ((size_t)width) * height;
|
||||
|
||||
if (image_pixels && num_pixels * channels == pixels_size) {
|
||||
memcpy(pixels, image_pixels, pixels_size * sizeof(float));
|
||||
@@ -89,7 +224,7 @@ bool BlenderImageLoader::load_pixels(const ImageMetaData &metadata,
|
||||
}
|
||||
else {
|
||||
const size_t num_pixels_safe = pixels_size / channels;
|
||||
float *fp = (float *)pixels;
|
||||
float *fp = pixels;
|
||||
for (int i = 0; i < num_pixels_safe; i++, fp += channels) {
|
||||
fp[0] = 1.0f;
|
||||
fp[1] = 0.0f;
|
||||
@@ -104,91 +239,107 @@ bool BlenderImageLoader::load_pixels(const ImageMetaData &metadata,
|
||||
if (image_pixels) {
|
||||
MEM_freeN(image_pixels);
|
||||
}
|
||||
}
|
||||
else {
|
||||
unsigned char *image_pixels = image_get_pixels_for_frame(b_image, frame, tile);
|
||||
|
||||
if (image_pixels && num_pixels * channels == pixels_size) {
|
||||
memcpy(pixels, image_pixels, pixels_size * sizeof(unsigned char));
|
||||
/* Free image buffers to save memory during render. */
|
||||
if (free_cache) {
|
||||
b_image.buffers_free();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (b_id.is_a(&RNA_Object)) {
|
||||
/* smoke volume data */
|
||||
BL::Object b_ob(b_id);
|
||||
BL::FluidDomainSettings b_domain = object_fluid_gas_domain_find(b_ob);
|
||||
|
||||
if (!b_domain) {
|
||||
return false;
|
||||
}
|
||||
#ifdef WITH_FLUID
|
||||
int3 resolution = get_int3(b_domain.domain_resolution());
|
||||
int length, amplify = (b_domain.use_noise()) ? b_domain.noise_scale() : 1;
|
||||
|
||||
/* Velocity and heat data is always low-resolution. */
|
||||
if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_VELOCITY) ||
|
||||
builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_HEAT)) {
|
||||
amplify = 1;
|
||||
}
|
||||
|
||||
const int width = resolution.x * amplify;
|
||||
const int height = resolution.y * amplify;
|
||||
const int depth = resolution.z * amplify;
|
||||
const size_t num_pixels = ((size_t)width) * height * depth;
|
||||
|
||||
if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_DENSITY)) {
|
||||
FluidDomainSettings_density_grid_get_length(&b_domain.ptr, &length);
|
||||
if (length == num_pixels) {
|
||||
FluidDomainSettings_density_grid_get(&b_domain.ptr, pixels);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_FLAME)) {
|
||||
/* this is in range 0..1, and interpreted by the OpenGL smoke viewer
|
||||
* as 1500..3000 K with the first part faded to zero density */
|
||||
FluidDomainSettings_flame_grid_get_length(&b_domain.ptr, &length);
|
||||
if (length == num_pixels) {
|
||||
FluidDomainSettings_flame_grid_get(&b_domain.ptr, pixels);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_COLOR)) {
|
||||
/* the RGB is "premultiplied" by density for better interpolation results */
|
||||
FluidDomainSettings_color_grid_get_length(&b_domain.ptr, &length);
|
||||
if (length == num_pixels * 4) {
|
||||
FluidDomainSettings_color_grid_get(&b_domain.ptr, pixels);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_VELOCITY)) {
|
||||
FluidDomainSettings_velocity_grid_get_length(&b_domain.ptr, &length);
|
||||
if (length == num_pixels * 3) {
|
||||
FluidDomainSettings_velocity_grid_get(&b_domain.ptr, pixels);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_HEAT)) {
|
||||
FluidDomainSettings_heat_grid_get_length(&b_domain.ptr, &length);
|
||||
if (length == num_pixels) {
|
||||
FluidDomainSettings_heat_grid_get(&b_domain.ptr, pixels);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_TEMPERATURE)) {
|
||||
FluidDomainSettings_temperature_grid_get_length(&b_domain.ptr, &length);
|
||||
if (length == num_pixels) {
|
||||
FluidDomainSettings_temperature_grid_get(&b_domain.ptr, pixels);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (channels == 1) {
|
||||
memset(pixels, 0, pixels_size * sizeof(unsigned char));
|
||||
}
|
||||
else {
|
||||
const size_t num_pixels_safe = pixels_size / channels;
|
||||
unsigned char *cp = (unsigned char *)pixels;
|
||||
for (size_t i = 0; i < num_pixels_safe; i++, cp += channels) {
|
||||
cp[0] = 255;
|
||||
cp[1] = 0;
|
||||
cp[2] = 255;
|
||||
if (channels == 4) {
|
||||
cp[3] = 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
fprintf(
|
||||
stderr, "Cycles error: unknown volume attribute %s, skipping\n", builtin_name.c_str());
|
||||
pixels[0] = 0.0f;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (image_pixels) {
|
||||
MEM_freeN(image_pixels);
|
||||
}
|
||||
|
||||
if (associate_alpha) {
|
||||
/* Premultiply, byte images are always straight for Blender. */
|
||||
unsigned char *cp = (unsigned char *)pixels;
|
||||
for (size_t i = 0; i < num_pixels; i++, cp += channels) {
|
||||
cp[0] = (cp[0] * cp[3]) >> 8;
|
||||
cp[1] = (cp[1] * cp[3]) >> 8;
|
||||
cp[2] = (cp[2] * cp[3]) >> 8;
|
||||
}
|
||||
#endif
|
||||
fprintf(stderr, "Cycles error: unexpected smoke volume resolution, skipping\n");
|
||||
}
|
||||
else {
|
||||
/* We originally were passing view_layer here but in reality we need a
|
||||
* a depsgraph to pass to the RE_point_density_minmax() function.
|
||||
*/
|
||||
/* TODO(sergey): Check we're indeed in shader node tree. */
|
||||
PointerRNA ptr;
|
||||
RNA_pointer_create(NULL, &RNA_Node, builtin_data, &ptr);
|
||||
BL::Node b_node(ptr);
|
||||
if (b_node.is_a(&RNA_ShaderNodeTexPointDensity)) {
|
||||
BL::ShaderNodeTexPointDensity b_point_density_node(b_node);
|
||||
int length;
|
||||
b_point_density_node.calc_point_density(b_depsgraph, &length, &pixels);
|
||||
}
|
||||
}
|
||||
|
||||
/* Free image buffers to save memory during render. */
|
||||
if (free_cache) {
|
||||
b_image.buffers_free();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
string BlenderImageLoader::name() const
|
||||
{
|
||||
return BL::Image(b_image).name();
|
||||
}
|
||||
|
||||
bool BlenderImageLoader::equals(const ImageLoader &other) const
|
||||
{
|
||||
const BlenderImageLoader &other_loader = (const BlenderImageLoader &)other;
|
||||
return b_image == other_loader.b_image && frame == other_loader.frame;
|
||||
}
|
||||
|
||||
/* Point Density */
|
||||
|
||||
BlenderPointDensityLoader::BlenderPointDensityLoader(BL::Depsgraph b_depsgraph,
|
||||
BL::ShaderNodeTexPointDensity b_node)
|
||||
: b_depsgraph(b_depsgraph), b_node(b_node)
|
||||
{
|
||||
}
|
||||
|
||||
bool BlenderPointDensityLoader::load_metadata(ImageMetaData &metadata)
|
||||
{
|
||||
metadata.channels = 4;
|
||||
metadata.width = b_node.resolution();
|
||||
metadata.height = metadata.width;
|
||||
metadata.depth = metadata.width;
|
||||
metadata.type = IMAGE_DATA_TYPE_FLOAT4;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BlenderPointDensityLoader::load_pixels(const ImageMetaData &,
|
||||
void *pixels,
|
||||
const size_t,
|
||||
const bool)
|
||||
{
|
||||
int length;
|
||||
b_node.calc_point_density(b_depsgraph, &length, (float **)&pixels);
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void BlenderSession::builtin_images_load()
|
||||
@@ -206,15 +357,4 @@ void BlenderSession::builtin_images_load()
|
||||
manager->device_load_builtin(device, session->scene, session->progress);
|
||||
}
|
||||
|
||||
string BlenderPointDensityLoader::name() const
|
||||
{
|
||||
return BL::ShaderNodeTexPointDensity(b_node).name();
|
||||
}
|
||||
|
||||
bool BlenderPointDensityLoader::equals(const ImageLoader &other) const
|
||||
{
|
||||
const BlenderPointDensityLoader &other_loader = (const BlenderPointDensityLoader &)other;
|
||||
return b_node == other_loader.b_node && b_depsgraph == other_loader.b_depsgraph;
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011-2020 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.
|
||||
*/
|
||||
|
||||
#ifndef __BLENDER_IMAGE_H__
|
||||
#define __BLENDER_IMAGE_H__
|
||||
|
||||
#include "RNA_blender_cpp.h"
|
||||
|
||||
#include "render/image.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
class BlenderImageLoader : public ImageLoader {
|
||||
public:
|
||||
BlenderImageLoader(BL::Image b_image, int frame);
|
||||
|
||||
bool load_metadata(ImageMetaData &metadata) override;
|
||||
bool load_pixels(const ImageMetaData &metadata,
|
||||
void *pixels,
|
||||
const size_t pixels_size,
|
||||
const bool associate_alpha) override;
|
||||
string name() const override;
|
||||
bool equals(const ImageLoader &other) const override;
|
||||
|
||||
BL::Image b_image;
|
||||
int frame;
|
||||
bool free_cache;
|
||||
};
|
||||
|
||||
class BlenderPointDensityLoader : public ImageLoader {
|
||||
public:
|
||||
BlenderPointDensityLoader(BL::Depsgraph depsgraph, BL::ShaderNodeTexPointDensity b_node);
|
||||
|
||||
bool load_metadata(ImageMetaData &metadata) override;
|
||||
bool load_pixels(const ImageMetaData &metadata,
|
||||
void *pixels,
|
||||
const size_t pixels_size,
|
||||
const bool associate_alpha) override;
|
||||
string name() const override;
|
||||
bool equals(const ImageLoader &other) const override;
|
||||
|
||||
BL::Depsgraph b_depsgraph;
|
||||
BL::ShaderNodeTexPointDensity b_node;
|
||||
};
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
#endif /* __BLENDER_IMAGE_H__ */
|
@@ -14,25 +14,25 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "render/camera.h"
|
||||
#include "render/colorspace.h"
|
||||
#include "render/mesh.h"
|
||||
#include "render/object.h"
|
||||
#include "render/scene.h"
|
||||
#include "render/camera.h"
|
||||
|
||||
#include "blender/blender_session.h"
|
||||
#include "blender/blender_sync.h"
|
||||
#include "blender/blender_session.h"
|
||||
#include "blender/blender_util.h"
|
||||
|
||||
#include "subd/subd_patch.h"
|
||||
#include "subd/subd_split.h"
|
||||
|
||||
#include "util/util_algorithm.h"
|
||||
#include "util/util_disjoint_set.h"
|
||||
#include "util/util_foreach.h"
|
||||
#include "util/util_hash.h"
|
||||
#include "util/util_logging.h"
|
||||
#include "util/util_math.h"
|
||||
#include "util/util_disjoint_set.h"
|
||||
|
||||
#include "mikktspace.h"
|
||||
|
||||
|
@@ -15,14 +15,14 @@
|
||||
*/
|
||||
|
||||
#include "render/camera.h"
|
||||
#include "render/graph.h"
|
||||
#include "render/integrator.h"
|
||||
#include "render/graph.h"
|
||||
#include "render/light.h"
|
||||
#include "render/mesh.h"
|
||||
#include "render/nodes.h"
|
||||
#include "render/object.h"
|
||||
#include "render/particles.h"
|
||||
#include "render/scene.h"
|
||||
#include "render/nodes.h"
|
||||
#include "render/particles.h"
|
||||
#include "render/shader.h"
|
||||
|
||||
#include "blender/blender_object_cull.h"
|
||||
@@ -67,20 +67,10 @@ bool BlenderSync::object_is_mesh(BL::Object &b_ob)
|
||||
return false;
|
||||
}
|
||||
|
||||
BL::Object::type_enum type = b_ob.type();
|
||||
|
||||
#ifdef WITH_NEW_OBJECT_TYPES
|
||||
if (type == BL::Object::type_VOLUME || type == BL::Object::type_HAIR) {
|
||||
#else
|
||||
if (type == BL::Object::type_VOLUME) {
|
||||
#endif
|
||||
/* Will be exported attached to mesh. */
|
||||
return true;
|
||||
}
|
||||
else if (type == BL::Object::type_CURVE) {
|
||||
if (b_ob.type() == BL::Object::type_CURVE) {
|
||||
/* Skip exporting curves without faces, overhead can be
|
||||
* significant if there are many for path animation. */
|
||||
BL::Curve b_curve(b_ob_data);
|
||||
BL::Curve b_curve(b_ob.data());
|
||||
|
||||
return (b_curve.bevel_object() || b_curve.extrude() != 0.0f || b_curve.bevel_depth() != 0.0f ||
|
||||
b_curve.dimensions() == BL::Curve::dimensions_2D || b_ob.modifiers.length());
|
||||
|
@@ -19,8 +19,8 @@
|
||||
#include "blender/CCL_api.h"
|
||||
|
||||
#include "blender/blender_device.h"
|
||||
#include "blender/blender_session.h"
|
||||
#include "blender/blender_sync.h"
|
||||
#include "blender/blender_session.h"
|
||||
#include "blender/blender_util.h"
|
||||
|
||||
#include "render/denoising.h"
|
||||
@@ -38,8 +38,8 @@
|
||||
#ifdef WITH_OSL
|
||||
# include "render/osl.h"
|
||||
|
||||
# include <OSL/oslconfig.h>
|
||||
# include <OSL/oslquery.h>
|
||||
# include <OSL/oslconfig.h>
|
||||
#endif
|
||||
|
||||
#ifdef WITH_OPENCL
|
||||
|
@@ -41,8 +41,8 @@
|
||||
#include "util/util_progress.h"
|
||||
#include "util/util_time.h"
|
||||
|
||||
#include "blender/blender_session.h"
|
||||
#include "blender/blender_sync.h"
|
||||
#include "blender/blender_session.h"
|
||||
#include "blender/blender_util.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
@@ -138,6 +138,14 @@ void BlenderSession::create_session()
|
||||
scene = new Scene(scene_params, session->device);
|
||||
scene->name = b_scene.name();
|
||||
|
||||
/* setup callbacks for builtin image support */
|
||||
scene->image_manager->builtin_image_info_cb = function_bind(
|
||||
&BlenderSession::builtin_image_info, this, _1, _2, _3);
|
||||
scene->image_manager->builtin_image_pixels_cb = function_bind(
|
||||
&BlenderSession::builtin_image_pixels, this, _1, _2, _3, _4, _5, _6, _7);
|
||||
scene->image_manager->builtin_image_float_pixels_cb = function_bind(
|
||||
&BlenderSession::builtin_image_float_pixels, this, _1, _2, _3, _4, _5, _6, _7);
|
||||
|
||||
session->scene = scene;
|
||||
|
||||
/* There is no single depsgraph to use for the entire render.
|
||||
|
@@ -157,6 +157,22 @@ class BlenderSession {
|
||||
bool do_update_only);
|
||||
void do_write_update_render_tile(RenderTile &rtile, bool do_update_only, bool highlight);
|
||||
|
||||
int builtin_image_frame(const string &builtin_name);
|
||||
void builtin_image_info(const string &builtin_name, void *builtin_data, ImageMetaData &metadata);
|
||||
bool builtin_image_pixels(const string &builtin_name,
|
||||
void *builtin_data,
|
||||
int tile,
|
||||
unsigned char *pixels,
|
||||
const size_t pixels_size,
|
||||
const bool associate_alpha,
|
||||
const bool free_cache);
|
||||
bool builtin_image_float_pixels(const string &builtin_name,
|
||||
void *builtin_data,
|
||||
int tile,
|
||||
float *pixels,
|
||||
const size_t pixels_size,
|
||||
const bool associate_alpha,
|
||||
const bool free_cache);
|
||||
void builtin_images_load();
|
||||
|
||||
/* Update tile manager to reflect resumable render settings. */
|
||||
|
@@ -23,15 +23,14 @@
|
||||
#include "render/scene.h"
|
||||
#include "render/shader.h"
|
||||
|
||||
#include "blender/blender_image.h"
|
||||
#include "blender/blender_sync.h"
|
||||
#include "blender/blender_texture.h"
|
||||
#include "blender/blender_sync.h"
|
||||
#include "blender/blender_util.h"
|
||||
|
||||
#include "util/util_debug.h"
|
||||
#include "util/util_foreach.h"
|
||||
#include "util/util_set.h"
|
||||
#include "util/util_string.h"
|
||||
#include "util/util_set.h"
|
||||
#include "util/util_task.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
@@ -620,16 +619,16 @@ static ShaderNode *add_node(Scene *scene,
|
||||
/* create script node */
|
||||
BL::ShaderNodeScript b_script_node(b_node);
|
||||
|
||||
ShaderManager *manager = scene->shader_manager;
|
||||
OSLShaderManager *manager = (OSLShaderManager *)scene->shader_manager;
|
||||
string bytecode_hash = b_script_node.bytecode_hash();
|
||||
|
||||
if (!bytecode_hash.empty()) {
|
||||
node = OSLShaderManager::osl_node(manager, "", bytecode_hash, b_script_node.bytecode());
|
||||
node = manager->osl_node("", bytecode_hash, b_script_node.bytecode());
|
||||
}
|
||||
else {
|
||||
string absolute_filepath = blender_absolute_path(
|
||||
b_data, b_ntree, b_script_node.filepath());
|
||||
node = OSLShaderManager::osl_node(manager, absolute_filepath, "");
|
||||
node = manager->osl_node(absolute_filepath, "");
|
||||
}
|
||||
}
|
||||
#else
|
||||
@@ -651,18 +650,6 @@ static ShaderNode *add_node(Scene *scene,
|
||||
get_tex_mapping(&image->tex_mapping, b_texture_mapping);
|
||||
|
||||
if (b_image) {
|
||||
PointerRNA colorspace_ptr = b_image.colorspace_settings().ptr;
|
||||
image->colorspace = get_enum_identifier(colorspace_ptr, "name");
|
||||
|
||||
image->animated = b_image_node.image_user().use_auto_refresh();
|
||||
image->alpha_type = get_image_alpha_type(b_image);
|
||||
|
||||
image->tiles.clear();
|
||||
BL::Image::tiles_iterator b_iter;
|
||||
for (b_image.tiles.begin(b_iter); b_iter != b_image.tiles.end(); ++b_iter) {
|
||||
image->tiles.push_back(b_iter->number());
|
||||
}
|
||||
|
||||
/* builtin images will use callback-based reading because
|
||||
* they could only be loaded correct from blender side
|
||||
*/
|
||||
@@ -679,13 +666,34 @@ static ShaderNode *add_node(Scene *scene,
|
||||
*/
|
||||
int scene_frame = b_scene.frame_current();
|
||||
int image_frame = image_user_frame_number(b_image_user, scene_frame);
|
||||
image->handle = scene->image_manager->add_image(
|
||||
new BlenderImageLoader(b_image, image_frame), image->image_params());
|
||||
image->filename = b_image.name() + "@" + string_printf("%d", image_frame);
|
||||
image->builtin_data = b_image.ptr.data;
|
||||
}
|
||||
else {
|
||||
image->filename = image_user_file_path(
|
||||
b_image_user, b_image, b_scene.frame_current(), true);
|
||||
image->builtin_data = NULL;
|
||||
}
|
||||
|
||||
PointerRNA colorspace_ptr = b_image.colorspace_settings().ptr;
|
||||
image->colorspace = get_enum_identifier(colorspace_ptr, "name");
|
||||
|
||||
image->animated = b_image_node.image_user().use_auto_refresh();
|
||||
image->alpha_type = get_image_alpha_type(b_image);
|
||||
|
||||
image->tiles.clear();
|
||||
BL::Image::tiles_iterator b_iter;
|
||||
for (b_image.tiles.begin(b_iter); b_iter != b_image.tiles.end(); ++b_iter) {
|
||||
image->tiles.push_back(b_iter->number());
|
||||
}
|
||||
|
||||
/* TODO: restore */
|
||||
/* TODO(sergey): Does not work properly when we change builtin type. */
|
||||
#if 0
|
||||
if (b_image.is_updated()) {
|
||||
scene->image_manager->tag_reload_image(image->image_key());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
node = image;
|
||||
}
|
||||
@@ -701,12 +709,6 @@ static ShaderNode *add_node(Scene *scene,
|
||||
get_tex_mapping(&env->tex_mapping, b_texture_mapping);
|
||||
|
||||
if (b_image) {
|
||||
PointerRNA colorspace_ptr = b_image.colorspace_settings().ptr;
|
||||
env->colorspace = get_enum_identifier(colorspace_ptr, "name");
|
||||
|
||||
env->animated = b_env_node.image_user().use_auto_refresh();
|
||||
env->alpha_type = get_image_alpha_type(b_image);
|
||||
|
||||
bool is_builtin = b_image.packed_file() || b_image.source() == BL::Image::source_GENERATED ||
|
||||
b_image.source() == BL::Image::source_MOVIE ||
|
||||
(b_engine.is_preview() && b_image.source() != BL::Image::source_SEQUENCE);
|
||||
@@ -714,13 +716,28 @@ static ShaderNode *add_node(Scene *scene,
|
||||
if (is_builtin) {
|
||||
int scene_frame = b_scene.frame_current();
|
||||
int image_frame = image_user_frame_number(b_image_user, scene_frame);
|
||||
env->handle = scene->image_manager->add_image(new BlenderImageLoader(b_image, image_frame),
|
||||
env->image_params());
|
||||
env->filename = b_image.name() + "@" + string_printf("%d", image_frame);
|
||||
env->builtin_data = b_image.ptr.data;
|
||||
}
|
||||
else {
|
||||
env->filename = image_user_file_path(
|
||||
b_image_user, b_image, b_scene.frame_current(), false);
|
||||
env->builtin_data = NULL;
|
||||
}
|
||||
|
||||
PointerRNA colorspace_ptr = b_image.colorspace_settings().ptr;
|
||||
env->colorspace = get_enum_identifier(colorspace_ptr, "name");
|
||||
|
||||
env->animated = b_env_node.image_user().use_auto_refresh();
|
||||
env->alpha_type = get_image_alpha_type(b_image);
|
||||
|
||||
/* TODO: restore */
|
||||
/* TODO(sergey): Does not work properly when we change builtin type. */
|
||||
#if 0
|
||||
if (b_image.is_updated()) {
|
||||
scene->image_manager->tag_reload_image(env->image_key());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
node = env;
|
||||
}
|
||||
@@ -864,13 +881,18 @@ static ShaderNode *add_node(Scene *scene,
|
||||
else if (b_node.is_a(&RNA_ShaderNodeTexPointDensity)) {
|
||||
BL::ShaderNodeTexPointDensity b_point_density_node(b_node);
|
||||
PointDensityTextureNode *point_density = new PointDensityTextureNode();
|
||||
point_density->filename = b_point_density_node.name();
|
||||
point_density->space = (NodeTexVoxelSpace)b_point_density_node.space();
|
||||
point_density->interpolation = get_image_interpolation(b_point_density_node);
|
||||
point_density->handle = scene->image_manager->add_image(
|
||||
new BlenderPointDensityLoader(b_depsgraph, b_point_density_node),
|
||||
point_density->image_params());
|
||||
point_density->builtin_data = b_point_density_node.ptr.data;
|
||||
point_density->image_manager = scene->image_manager;
|
||||
|
||||
b_point_density_node.cache_point_density(b_depsgraph);
|
||||
/* TODO(sergey): Use more proper update flag. */
|
||||
if (true) {
|
||||
point_density->add_image();
|
||||
b_point_density_node.cache_point_density(b_depsgraph);
|
||||
scene->image_manager->tag_reload_image(point_density->image_key());
|
||||
}
|
||||
node = point_density;
|
||||
|
||||
/* Transformation form world space to texture space.
|
||||
@@ -1260,7 +1282,6 @@ void BlenderSync::sync_materials(BL::Depsgraph &b_depsgraph, bool update_all)
|
||||
shader->heterogeneous_volume = !get_boolean(cmat, "homogeneous_volume");
|
||||
shader->volume_sampling_method = get_volume_sampling(cmat);
|
||||
shader->volume_interpolation_method = get_volume_interpolation(cmat);
|
||||
shader->volume_step_rate = get_float(cmat, "volume_step_rate");
|
||||
shader->displacement_method = get_displacement_method(cmat);
|
||||
|
||||
shader->set_graph(graph);
|
||||
@@ -1325,7 +1346,6 @@ void BlenderSync::sync_world(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d,
|
||||
shader->heterogeneous_volume = !get_boolean(cworld, "homogeneous_volume");
|
||||
shader->volume_sampling_method = get_volume_sampling(cworld);
|
||||
shader->volume_interpolation_method = get_volume_interpolation(cworld);
|
||||
shader->volume_step_rate = get_float(cworld, "volume_step_size");
|
||||
}
|
||||
else if (new_viewport_parameters.use_scene_world && b_world) {
|
||||
BackgroundNode *background = new BackgroundNode();
|
||||
|
@@ -16,7 +16,6 @@
|
||||
|
||||
#include "render/background.h"
|
||||
#include "render/camera.h"
|
||||
#include "render/curves.h"
|
||||
#include "render/film.h"
|
||||
#include "render/graph.h"
|
||||
#include "render/integrator.h"
|
||||
@@ -26,18 +25,19 @@
|
||||
#include "render/object.h"
|
||||
#include "render/scene.h"
|
||||
#include "render/shader.h"
|
||||
#include "render/curves.h"
|
||||
|
||||
#include "device/device.h"
|
||||
|
||||
#include "blender/blender_device.h"
|
||||
#include "blender/blender_session.h"
|
||||
#include "blender/blender_sync.h"
|
||||
#include "blender/blender_session.h"
|
||||
#include "blender/blender_util.h"
|
||||
|
||||
#include "util/util_debug.h"
|
||||
#include "util/util_foreach.h"
|
||||
#include "util/util_hash.h"
|
||||
#include "util/util_opengl.h"
|
||||
#include "util/util_hash.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
@@ -178,11 +178,6 @@ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d
|
||||
world_recalc = true;
|
||||
}
|
||||
}
|
||||
/* Volume */
|
||||
else if (b_id.is_a(&RNA_Volume)) {
|
||||
BL::Volume b_volume(b_id);
|
||||
geometry_map.set_recalc(b_volume);
|
||||
}
|
||||
}
|
||||
|
||||
BlenderViewportParameters new_viewport_parameters(b_v3d);
|
||||
@@ -262,8 +257,7 @@ void BlenderSync::sync_integrator()
|
||||
integrator->transparent_max_bounce = get_int(cscene, "transparent_max_bounces");
|
||||
|
||||
integrator->volume_max_steps = get_int(cscene, "volume_max_steps");
|
||||
integrator->volume_step_rate = (preview) ? get_float(cscene, "volume_preview_step_rate") :
|
||||
get_float(cscene, "volume_step_rate");
|
||||
integrator->volume_step_size = get_float(cscene, "volume_step_size");
|
||||
|
||||
integrator->caustics_reflective = get_boolean(cscene, "caustics_reflective");
|
||||
integrator->caustics_refractive = get_boolean(cscene, "caustics_refractive");
|
||||
@@ -411,7 +405,6 @@ void BlenderSync::sync_view_layer(BL::SpaceView3D & /*b_v3d*/, BL::ViewLayer &b_
|
||||
view_layer.use_background_ao = b_view_layer.use_ao();
|
||||
view_layer.use_surfaces = b_view_layer.use_solid();
|
||||
view_layer.use_hair = b_view_layer.use_strand();
|
||||
view_layer.use_volumes = b_view_layer.use_volumes();
|
||||
|
||||
/* Material override. */
|
||||
view_layer.material_override = b_view_layer.material_override();
|
||||
|
@@ -18,9 +18,9 @@
|
||||
#define __BLENDER_SYNC_H__
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
#include "RNA_types.h"
|
||||
#include "RNA_access.h"
|
||||
#include "RNA_blender_cpp.h"
|
||||
#include "RNA_types.h"
|
||||
|
||||
#include "blender/blender_id_map.h"
|
||||
#include "blender/blender_viewport.h"
|
||||
@@ -157,7 +157,6 @@ class BlenderSync {
|
||||
BL::Object b_ob,
|
||||
Geometry *geom,
|
||||
int motion_step);
|
||||
void sync_hair(Hair *hair, BL::Object &b_ob, bool motion, int motion_step = 0);
|
||||
void sync_particle_hair(
|
||||
Geometry *geom, BL::Mesh &b_mesh, BL::Object &b_ob, bool motion, int motion_step = 0);
|
||||
void sync_curve_settings();
|
||||
@@ -237,7 +236,6 @@ class BlenderSync {
|
||||
use_background_ao(true),
|
||||
use_surfaces(true),
|
||||
use_hair(true),
|
||||
use_volumes(true),
|
||||
samples(0),
|
||||
bound_samples(false)
|
||||
{
|
||||
@@ -249,7 +247,6 @@ class BlenderSync {
|
||||
bool use_background_ao;
|
||||
bool use_surfaces;
|
||||
bool use_hair;
|
||||
bool use_volumes;
|
||||
int samples;
|
||||
bool bound_samples;
|
||||
} view_layer;
|
||||
|
@@ -17,8 +17,8 @@
|
||||
#ifndef __BLENDER_TEXTURE_H__
|
||||
#define __BLENDER_TEXTURE_H__
|
||||
|
||||
#include "blender/blender_sync.h"
|
||||
#include <stdlib.h>
|
||||
#include "blender/blender_sync.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
|
@@ -18,9 +18,9 @@
|
||||
#define __BLENDER_VIEWPORT_H__
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
#include "RNA_types.h"
|
||||
#include "RNA_access.h"
|
||||
#include "RNA_blender_cpp.h"
|
||||
#include "RNA_types.h"
|
||||
|
||||
#include "render/film.h"
|
||||
#include "util/util_param.h"
|
||||
|
@@ -1,3 +1,4 @@
|
||||
|
||||
/*
|
||||
* Copyright 2011-2013 Blender Foundation
|
||||
*
|
||||
@@ -15,177 +16,14 @@
|
||||
*/
|
||||
|
||||
#include "render/colorspace.h"
|
||||
#include "render/image.h"
|
||||
#include "render/image_vdb.h"
|
||||
#include "render/mesh.h"
|
||||
#include "render/object.h"
|
||||
|
||||
#include "blender/blender_sync.h"
|
||||
#include "blender/blender_util.h"
|
||||
|
||||
#ifdef WITH_OPENVDB
|
||||
# include <openvdb/openvdb.h>
|
||||
openvdb::GridBase::ConstPtr BKE_volume_grid_openvdb_for_read(const struct Volume *volume,
|
||||
struct VolumeGrid *grid);
|
||||
#endif
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
/* TODO: verify this is not loading unnecessary attributes. */
|
||||
class BlenderSmokeLoader : public ImageLoader {
|
||||
public:
|
||||
BlenderSmokeLoader(const BL::Object &b_ob, AttributeStandard attribute)
|
||||
: b_ob(b_ob), attribute(attribute)
|
||||
{
|
||||
}
|
||||
|
||||
bool load_metadata(ImageMetaData &metadata) override
|
||||
{
|
||||
BL::FluidDomainSettings b_domain = object_fluid_gas_domain_find(b_ob);
|
||||
|
||||
if (!b_domain) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (attribute == ATTR_STD_VOLUME_DENSITY || attribute == ATTR_STD_VOLUME_FLAME ||
|
||||
attribute == ATTR_STD_VOLUME_HEAT || attribute == ATTR_STD_VOLUME_TEMPERATURE) {
|
||||
metadata.type = IMAGE_DATA_TYPE_FLOAT;
|
||||
metadata.channels = 1;
|
||||
}
|
||||
else if (attribute == ATTR_STD_VOLUME_COLOR) {
|
||||
metadata.type = IMAGE_DATA_TYPE_FLOAT4;
|
||||
metadata.channels = 4;
|
||||
}
|
||||
else if (attribute == ATTR_STD_VOLUME_VELOCITY) {
|
||||
metadata.type = IMAGE_DATA_TYPE_FLOAT4;
|
||||
metadata.channels = 3;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
|
||||
int3 resolution = get_int3(b_domain.domain_resolution());
|
||||
int amplify = (b_domain.use_noise()) ? b_domain.noise_scale() : 1;
|
||||
|
||||
/* Velocity and heat data is always low-resolution. */
|
||||
if (attribute == ATTR_STD_VOLUME_VELOCITY || attribute == ATTR_STD_VOLUME_HEAT) {
|
||||
amplify = 1;
|
||||
}
|
||||
|
||||
metadata.width = resolution.x * amplify;
|
||||
metadata.height = resolution.y * amplify;
|
||||
metadata.depth = resolution.z * amplify;
|
||||
|
||||
/* Create a matrix to transform from object space to mesh texture space.
|
||||
* This does not work with deformations but that can probably only be done
|
||||
* well with a volume grid mapping of coordinates. */
|
||||
BL::Mesh b_mesh(b_ob.data());
|
||||
float3 loc, size;
|
||||
mesh_texture_space(b_mesh, loc, size);
|
||||
metadata.transform_3d = transform_translate(-loc) * transform_scale(size);
|
||||
metadata.use_transform_3d = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool load_pixels(const ImageMetaData &, void *pixels, const size_t, const bool) override
|
||||
{
|
||||
/* smoke volume data */
|
||||
BL::FluidDomainSettings b_domain = object_fluid_gas_domain_find(b_ob);
|
||||
|
||||
if (!b_domain) {
|
||||
return false;
|
||||
}
|
||||
#ifdef WITH_FLUID
|
||||
int3 resolution = get_int3(b_domain.domain_resolution());
|
||||
int length, amplify = (b_domain.use_noise()) ? b_domain.noise_scale() : 1;
|
||||
|
||||
/* Velocity and heat data is always low-resolution. */
|
||||
if (attribute == ATTR_STD_VOLUME_VELOCITY || attribute == ATTR_STD_VOLUME_HEAT) {
|
||||
amplify = 1;
|
||||
}
|
||||
|
||||
const int width = resolution.x * amplify;
|
||||
const int height = resolution.y * amplify;
|
||||
const int depth = resolution.z * amplify;
|
||||
const size_t num_pixels = ((size_t)width) * height * depth;
|
||||
|
||||
float *fpixels = (float *)pixels;
|
||||
|
||||
if (attribute == ATTR_STD_VOLUME_DENSITY) {
|
||||
FluidDomainSettings_density_grid_get_length(&b_domain.ptr, &length);
|
||||
if (length == num_pixels) {
|
||||
FluidDomainSettings_density_grid_get(&b_domain.ptr, fpixels);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (attribute == ATTR_STD_VOLUME_FLAME) {
|
||||
/* this is in range 0..1, and interpreted by the OpenGL smoke viewer
|
||||
* as 1500..3000 K with the first part faded to zero density */
|
||||
FluidDomainSettings_flame_grid_get_length(&b_domain.ptr, &length);
|
||||
if (length == num_pixels) {
|
||||
FluidDomainSettings_flame_grid_get(&b_domain.ptr, fpixels);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (attribute == ATTR_STD_VOLUME_COLOR) {
|
||||
/* the RGB is "premultiplied" by density for better interpolation results */
|
||||
FluidDomainSettings_color_grid_get_length(&b_domain.ptr, &length);
|
||||
if (length == num_pixels * 4) {
|
||||
FluidDomainSettings_color_grid_get(&b_domain.ptr, fpixels);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (attribute == ATTR_STD_VOLUME_VELOCITY) {
|
||||
FluidDomainSettings_velocity_grid_get_length(&b_domain.ptr, &length);
|
||||
if (length == num_pixels * 3) {
|
||||
FluidDomainSettings_velocity_grid_get(&b_domain.ptr, fpixels);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (attribute == ATTR_STD_VOLUME_HEAT) {
|
||||
FluidDomainSettings_heat_grid_get_length(&b_domain.ptr, &length);
|
||||
if (length == num_pixels) {
|
||||
FluidDomainSettings_heat_grid_get(&b_domain.ptr, fpixels);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (attribute == ATTR_STD_VOLUME_TEMPERATURE) {
|
||||
FluidDomainSettings_temperature_grid_get_length(&b_domain.ptr, &length);
|
||||
if (length == num_pixels) {
|
||||
FluidDomainSettings_temperature_grid_get(&b_domain.ptr, fpixels);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
fprintf(stderr,
|
||||
"Cycles error: unknown volume attribute %s, skipping\n",
|
||||
Attribute::standard_name(attribute));
|
||||
fpixels[0] = 0.0f;
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
(void)pixels;
|
||||
#endif
|
||||
fprintf(stderr, "Cycles error: unexpected smoke volume resolution, skipping\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
string name() const override
|
||||
{
|
||||
return Attribute::standard_name(attribute);
|
||||
}
|
||||
|
||||
bool equals(const ImageLoader &other) const override
|
||||
{
|
||||
const BlenderSmokeLoader &other_loader = (const BlenderSmokeLoader &)other;
|
||||
return b_ob == other_loader.b_ob && attribute == other_loader.attribute;
|
||||
}
|
||||
|
||||
BL::Object b_ob;
|
||||
AttributeStandard attribute;
|
||||
};
|
||||
|
||||
static void sync_smoke_volume(Scene *scene, BL::Object &b_ob, Mesh *mesh, float frame)
|
||||
{
|
||||
BL::FluidDomainSettings b_domain = object_fluid_gas_domain_find(b_ob);
|
||||
@@ -193,6 +31,7 @@ static void sync_smoke_volume(Scene *scene, BL::Object &b_ob, Mesh *mesh, float
|
||||
return;
|
||||
}
|
||||
|
||||
ImageManager *image_manager = scene->image_manager;
|
||||
AttributeStandard attributes[] = {ATTR_STD_VOLUME_DENSITY,
|
||||
ATTR_STD_VOLUME_COLOR,
|
||||
ATTR_STD_VOLUME_FLAME,
|
||||
@@ -207,172 +46,47 @@ static void sync_smoke_volume(Scene *scene, BL::Object &b_ob, Mesh *mesh, float
|
||||
continue;
|
||||
}
|
||||
|
||||
mesh->volume_clipping = b_domain.clipping();
|
||||
mesh->volume_isovalue = b_domain.clipping();
|
||||
|
||||
Attribute *attr = mesh->attributes.add(std);
|
||||
VoxelAttribute *volume_data = attr->data_voxel();
|
||||
ImageMetaData metadata;
|
||||
|
||||
ImageLoader *loader = new BlenderSmokeLoader(b_ob, std);
|
||||
ImageParams params;
|
||||
params.frame = frame;
|
||||
ImageKey key;
|
||||
key.filename = Attribute::standard_name(std);
|
||||
key.builtin_data = b_ob.ptr.data;
|
||||
|
||||
attr->data_voxel() = scene->image_manager->add_image(loader, params);
|
||||
}
|
||||
}
|
||||
|
||||
class BlenderVolumeLoader : public VDBImageLoader {
|
||||
public:
|
||||
BlenderVolumeLoader(BL::Volume b_volume, const string &grid_name)
|
||||
: VDBImageLoader(grid_name),
|
||||
b_volume(b_volume),
|
||||
b_volume_grid(PointerRNA_NULL),
|
||||
unload(false)
|
||||
{
|
||||
#ifdef WITH_OPENVDB
|
||||
/* Find grid with matching name. */
|
||||
BL::Volume::grids_iterator b_grid_iter;
|
||||
for (b_volume.grids.begin(b_grid_iter); b_grid_iter != b_volume.grids.end(); ++b_grid_iter) {
|
||||
if (b_grid_iter->name() == grid_name) {
|
||||
b_volume_grid = *b_grid_iter;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
volume_data->manager = image_manager;
|
||||
volume_data->slot = image_manager->add_image(key, frame, metadata);
|
||||
}
|
||||
|
||||
bool load_metadata(ImageMetaData &metadata) override
|
||||
{
|
||||
if (!b_volume_grid) {
|
||||
return false;
|
||||
}
|
||||
/* Create a matrix to transform from object space to mesh texture space.
|
||||
* This does not work with deformations but that can probably only be done
|
||||
* well with a volume grid mapping of coordinates. */
|
||||
if (mesh->need_attribute(scene, ATTR_STD_GENERATED_TRANSFORM)) {
|
||||
Attribute *attr = mesh->attributes.add(ATTR_STD_GENERATED_TRANSFORM);
|
||||
Transform *tfm = attr->data_transform();
|
||||
|
||||
unload = !b_volume_grid.is_loaded();
|
||||
BL::Mesh b_mesh(b_ob.data());
|
||||
float3 loc, size;
|
||||
mesh_texture_space(b_mesh, loc, size);
|
||||
|
||||
#ifdef WITH_OPENVDB
|
||||
Volume *volume = (Volume *)b_volume.ptr.data;
|
||||
VolumeGrid *volume_grid = (VolumeGrid *)b_volume_grid.ptr.data;
|
||||
grid = BKE_volume_grid_openvdb_for_read(volume, volume_grid);
|
||||
#endif
|
||||
|
||||
return VDBImageLoader::load_metadata(metadata);
|
||||
*tfm = transform_translate(-loc) * transform_scale(size);
|
||||
}
|
||||
|
||||
bool load_pixels(const ImageMetaData &metadata,
|
||||
void *pixels,
|
||||
const size_t pixel_size,
|
||||
const bool associate_alpha) override
|
||||
{
|
||||
if (!b_volume_grid) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return VDBImageLoader::load_pixels(metadata, pixels, pixel_size, associate_alpha);
|
||||
}
|
||||
|
||||
bool equals(const ImageLoader &other) const override
|
||||
{
|
||||
/* TODO: detect multiple volume datablocks with the same filepath. */
|
||||
const BlenderVolumeLoader &other_loader = (const BlenderVolumeLoader &)other;
|
||||
return b_volume == other_loader.b_volume && b_volume_grid == other_loader.b_volume_grid;
|
||||
}
|
||||
|
||||
void cleanup() override
|
||||
{
|
||||
VDBImageLoader::cleanup();
|
||||
if (b_volume_grid && unload) {
|
||||
b_volume_grid.unload();
|
||||
}
|
||||
}
|
||||
|
||||
BL::Volume b_volume;
|
||||
BL::VolumeGrid b_volume_grid;
|
||||
bool unload;
|
||||
};
|
||||
|
||||
static void sync_volume_object(BL::BlendData &b_data, BL::Object &b_ob, Scene *scene, Mesh *mesh)
|
||||
{
|
||||
BL::Volume b_volume(b_ob.data());
|
||||
b_volume.grids.load(b_data.ptr.data);
|
||||
|
||||
BL::VolumeRender b_render(b_volume.render());
|
||||
|
||||
mesh->volume_clipping = b_render.clipping();
|
||||
mesh->volume_step_size = b_render.step_size();
|
||||
mesh->volume_object_space = (b_render.space() == BL::VolumeRender::space_OBJECT);
|
||||
|
||||
/* Find grid with matching name. */
|
||||
BL::Volume::grids_iterator b_grid_iter;
|
||||
for (b_volume.grids.begin(b_grid_iter); b_grid_iter != b_volume.grids.end(); ++b_grid_iter) {
|
||||
BL::VolumeGrid b_grid = *b_grid_iter;
|
||||
ustring name = ustring(b_grid.name());
|
||||
AttributeStandard std = ATTR_STD_NONE;
|
||||
|
||||
if (name == Attribute::standard_name(ATTR_STD_VOLUME_DENSITY)) {
|
||||
std = ATTR_STD_VOLUME_DENSITY;
|
||||
}
|
||||
else if (name == Attribute::standard_name(ATTR_STD_VOLUME_COLOR)) {
|
||||
std = ATTR_STD_VOLUME_COLOR;
|
||||
}
|
||||
else if (name == Attribute::standard_name(ATTR_STD_VOLUME_FLAME)) {
|
||||
std = ATTR_STD_VOLUME_FLAME;
|
||||
}
|
||||
else if (name == Attribute::standard_name(ATTR_STD_VOLUME_HEAT)) {
|
||||
std = ATTR_STD_VOLUME_HEAT;
|
||||
}
|
||||
else if (name == Attribute::standard_name(ATTR_STD_VOLUME_TEMPERATURE)) {
|
||||
std = ATTR_STD_VOLUME_TEMPERATURE;
|
||||
}
|
||||
else if (name == Attribute::standard_name(ATTR_STD_VOLUME_VELOCITY)) {
|
||||
std = ATTR_STD_VOLUME_VELOCITY;
|
||||
}
|
||||
|
||||
if ((std != ATTR_STD_NONE && mesh->need_attribute(scene, std)) ||
|
||||
mesh->need_attribute(scene, name)) {
|
||||
Attribute *attr = (std != ATTR_STD_NONE) ?
|
||||
mesh->attributes.add(std) :
|
||||
mesh->attributes.add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_VOXEL);
|
||||
|
||||
ImageLoader *loader = new BlenderVolumeLoader(b_volume, name.string());
|
||||
ImageParams params;
|
||||
params.frame = b_volume.grids.frame();
|
||||
|
||||
attr->data_voxel() = scene->image_manager->add_image(loader, params);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If the voxel attributes change, we need to rebuild the bounding mesh. */
|
||||
static vector<int> get_voxel_image_slots(Mesh *mesh)
|
||||
{
|
||||
vector<int> slots;
|
||||
for (const Attribute &attr : mesh->attributes.attributes) {
|
||||
if (attr.element == ATTR_ELEMENT_VOXEL) {
|
||||
slots.push_back(attr.data_voxel().svm_slot());
|
||||
}
|
||||
}
|
||||
|
||||
return slots;
|
||||
}
|
||||
|
||||
void BlenderSync::sync_volume(BL::Object &b_ob, Mesh *mesh, const vector<Shader *> &used_shaders)
|
||||
{
|
||||
vector<int> old_voxel_slots = get_voxel_image_slots(mesh);
|
||||
bool old_has_voxel_attributes = mesh->has_voxel_attributes();
|
||||
|
||||
mesh->clear();
|
||||
mesh->used_shaders = used_shaders;
|
||||
|
||||
if (view_layer.use_volumes) {
|
||||
if (b_ob.type() == BL::Object::type_VOLUME) {
|
||||
/* Volume object. Create only attributes, bounding mesh will then
|
||||
* be automatically generated later. */
|
||||
sync_volume_object(b_data, b_ob, scene, mesh);
|
||||
}
|
||||
else {
|
||||
/* Smoke domain. */
|
||||
sync_smoke_volume(scene, b_ob, mesh, b_scene.frame_current());
|
||||
}
|
||||
}
|
||||
/* Smoke domain. */
|
||||
sync_smoke_volume(scene, b_ob, mesh, b_scene.frame_current());
|
||||
|
||||
/* Tag update. */
|
||||
bool rebuild = (old_voxel_slots != get_voxel_image_slots(mesh));
|
||||
bool rebuild = (old_has_voxel_attributes != mesh->has_voxel_attributes());
|
||||
mesh->tag_update(scene, rebuild);
|
||||
}
|
||||
|
||||
|
@@ -535,9 +535,8 @@ void BVH::pack_instances(size_t nodes_size, size_t leaf_nodes_size)
|
||||
|
||||
/* Modify offsets into arrays */
|
||||
int4 data = bvh_nodes[i + nsize_bbox];
|
||||
|
||||
int4 data1 = bvh_nodes[i + nsize_bbox - 1];
|
||||
if (use_obvh) {
|
||||
int4 data1 = bvh_nodes[i + nsize_bbox - 1];
|
||||
data.z += (data.z < 0) ? -noffset_leaf : noffset;
|
||||
data.w += (data.w < 0) ? -noffset_leaf : noffset;
|
||||
data.x += (data.x < 0) ? -noffset_leaf : noffset;
|
||||
@@ -546,8 +545,6 @@ void BVH::pack_instances(size_t nodes_size, size_t leaf_nodes_size)
|
||||
data1.w += (data1.w < 0) ? -noffset_leaf : noffset;
|
||||
data1.x += (data1.x < 0) ? -noffset_leaf : noffset;
|
||||
data1.y += (data1.y < 0) ? -noffset_leaf : noffset;
|
||||
pack_nodes[pack_nodes_offset + nsize_bbox] = data;
|
||||
pack_nodes[pack_nodes_offset + nsize_bbox - 1] = data1;
|
||||
}
|
||||
else {
|
||||
data.z += (data.z < 0) ? -noffset_leaf : noffset;
|
||||
@@ -556,7 +553,10 @@ void BVH::pack_instances(size_t nodes_size, size_t leaf_nodes_size)
|
||||
data.x += (data.x < 0) ? -noffset_leaf : noffset;
|
||||
data.y += (data.y < 0) ? -noffset_leaf : noffset;
|
||||
}
|
||||
pack_nodes[pack_nodes_offset + nsize_bbox] = data;
|
||||
}
|
||||
pack_nodes[pack_nodes_offset + nsize_bbox] = data;
|
||||
if (use_obvh) {
|
||||
pack_nodes[pack_nodes_offset + nsize_bbox - 1] = data1;
|
||||
}
|
||||
|
||||
/* Usually this copies nothing, but we better
|
||||
|
@@ -22,20 +22,20 @@
|
||||
#include "bvh/bvh_params.h"
|
||||
#include "bvh_split.h"
|
||||
|
||||
#include "render/curves.h"
|
||||
#include "render/hair.h"
|
||||
#include "render/mesh.h"
|
||||
#include "render/object.h"
|
||||
#include "render/scene.h"
|
||||
#include "render/curves.h"
|
||||
|
||||
#include "util/util_algorithm.h"
|
||||
#include "util/util_foreach.h"
|
||||
#include "util/util_logging.h"
|
||||
#include "util/util_progress.h"
|
||||
#include "util/util_queue.h"
|
||||
#include "util/util_simd.h"
|
||||
#include "util/util_stack_allocator.h"
|
||||
#include "util/util_simd.h"
|
||||
#include "util/util_time.h"
|
||||
#include "util/util_queue.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
|
@@ -35,9 +35,9 @@
|
||||
|
||||
#ifdef WITH_EMBREE
|
||||
|
||||
# include <embree3/rtcore_geometry.h>
|
||||
# include <pmmintrin.h>
|
||||
# include <xmmintrin.h>
|
||||
# include <embree3/rtcore_geometry.h>
|
||||
|
||||
# include "bvh/bvh_embree.h"
|
||||
|
||||
@@ -45,9 +45,9 @@
|
||||
*/
|
||||
# include "kernel/bvh/bvh_embree.h"
|
||||
# include "kernel/kernel_compat_cpu.h"
|
||||
# include "kernel/split/kernel_split_data_types.h"
|
||||
# include "kernel/kernel_globals.h"
|
||||
# include "kernel/kernel_random.h"
|
||||
# include "kernel/split/kernel_split_data_types.h"
|
||||
|
||||
# include "render/hair.h"
|
||||
# include "render/mesh.h"
|
||||
|
@@ -18,11 +18,10 @@
|
||||
#ifdef WITH_OPTIX
|
||||
|
||||
# include "bvh/bvh_optix.h"
|
||||
# include "render/geometry.h"
|
||||
# include "render/hair.h"
|
||||
# include "render/geometry.h"
|
||||
# include "render/mesh.h"
|
||||
# include "render/object.h"
|
||||
# include "util/util_foreach.h"
|
||||
# include "util/util_logging.h"
|
||||
# include "util/util_progress.h"
|
||||
|
||||
|
@@ -155,13 +155,9 @@ class CUDADevice : public Device {
|
||||
|
||||
virtual void const_copy_to(const char *name, void *host, size_t size);
|
||||
|
||||
void global_alloc(device_memory &mem);
|
||||
void tex_alloc(device_memory &mem);
|
||||
|
||||
void global_free(device_memory &mem);
|
||||
|
||||
void tex_alloc(device_texture &mem);
|
||||
|
||||
void tex_free(device_texture &mem);
|
||||
void tex_free(device_memory &mem);
|
||||
|
||||
bool denoising_non_local_means(device_ptr image_ptr,
|
||||
device_ptr guide_ptr,
|
||||
|
@@ -39,8 +39,8 @@
|
||||
# include "util/util_path.h"
|
||||
# include "util/util_string.h"
|
||||
# include "util/util_system.h"
|
||||
# include "util/util_time.h"
|
||||
# include "util/util_types.h"
|
||||
# include "util/util_time.h"
|
||||
# include "util/util_windows.h"
|
||||
|
||||
# include "kernel/split/kernel_split_data_types.h"
|
||||
@@ -185,7 +185,7 @@ void CUDADevice::cuda_error_message(const string &message)
|
||||
}
|
||||
|
||||
CUDADevice::CUDADevice(DeviceInfo &info, Stats &stats, Profiler &profiler, bool background_)
|
||||
: Device(info, stats, profiler, background_), texture_info(this, "__texture_info", MEM_GLOBAL)
|
||||
: Device(info, stats, profiler, background_), texture_info(this, "__texture_info", MEM_TEXTURE)
|
||||
{
|
||||
first_error = true;
|
||||
background = background_;
|
||||
@@ -684,8 +684,7 @@ void CUDADevice::move_textures_to_host(size_t size, bool for_texture)
|
||||
device_memory &mem = *pair.first;
|
||||
CUDAMem *cmem = &pair.second;
|
||||
|
||||
bool is_texture = (mem.type == MEM_TEXTURE || mem.type == MEM_GLOBAL) &&
|
||||
(&mem != &texture_info);
|
||||
bool is_texture = (mem.type == MEM_TEXTURE) && (&mem != &texture_info);
|
||||
bool is_image = is_texture && (mem.data_height > 1);
|
||||
|
||||
/* Can't move this type of memory. */
|
||||
@@ -725,7 +724,8 @@ void CUDADevice::move_textures_to_host(size_t size, bool for_texture)
|
||||
device_ptr prev_pointer = max_mem->device_pointer;
|
||||
size_t prev_size = max_mem->device_size;
|
||||
|
||||
mem_copy_to(*max_mem);
|
||||
tex_free(*max_mem);
|
||||
tex_alloc(*max_mem);
|
||||
size = (max_size >= size) ? 0 : size - max_size;
|
||||
|
||||
max_mem->device_pointer = prev_pointer;
|
||||
@@ -759,7 +759,7 @@ CUDADevice::CUDAMem *CUDADevice::generic_alloc(device_memory &mem, size_t pitch_
|
||||
* If there is not enough room for working memory, we will try to move
|
||||
* textures to host memory, assuming the performance impact would have
|
||||
* been worse for working memory. */
|
||||
bool is_texture = (mem.type == MEM_TEXTURE || mem.type == MEM_GLOBAL) && (&mem != &texture_info);
|
||||
bool is_texture = (mem.type == MEM_TEXTURE) && (&mem != &texture_info);
|
||||
bool is_image = is_texture && (mem.data_height > 1);
|
||||
|
||||
size_t headroom = (is_texture) ? device_texture_headroom : device_working_headroom;
|
||||
@@ -922,9 +922,6 @@ void CUDADevice::mem_alloc(device_memory &mem)
|
||||
else if (mem.type == MEM_TEXTURE) {
|
||||
assert(!"mem_alloc not supported for textures.");
|
||||
}
|
||||
else if (mem.type == MEM_GLOBAL) {
|
||||
assert(!"mem_alloc not supported for global memory.");
|
||||
}
|
||||
else {
|
||||
generic_alloc(mem);
|
||||
}
|
||||
@@ -935,13 +932,9 @@ void CUDADevice::mem_copy_to(device_memory &mem)
|
||||
if (mem.type == MEM_PIXELS) {
|
||||
assert(!"mem_copy_to not supported for pixels.");
|
||||
}
|
||||
else if (mem.type == MEM_GLOBAL) {
|
||||
global_free(mem);
|
||||
global_alloc(mem);
|
||||
}
|
||||
else if (mem.type == MEM_TEXTURE) {
|
||||
tex_free((device_texture &)mem);
|
||||
tex_alloc((device_texture &)mem);
|
||||
tex_free(mem);
|
||||
tex_alloc(mem);
|
||||
}
|
||||
else {
|
||||
if (!mem.device_pointer) {
|
||||
@@ -957,7 +950,7 @@ void CUDADevice::mem_copy_from(device_memory &mem, int y, int w, int h, int elem
|
||||
if (mem.type == MEM_PIXELS && !background) {
|
||||
pixels_copy_from(mem, y, w, h);
|
||||
}
|
||||
else if (mem.type == MEM_TEXTURE || mem.type == MEM_GLOBAL) {
|
||||
else if (mem.type == MEM_TEXTURE) {
|
||||
assert(!"mem_copy_from not supported for textures.");
|
||||
}
|
||||
else if (mem.host_pointer) {
|
||||
@@ -1000,11 +993,8 @@ void CUDADevice::mem_free(device_memory &mem)
|
||||
if (mem.type == MEM_PIXELS && !background) {
|
||||
pixels_free(mem);
|
||||
}
|
||||
else if (mem.type == MEM_GLOBAL) {
|
||||
global_free(mem);
|
||||
}
|
||||
else if (mem.type == MEM_TEXTURE) {
|
||||
tex_free((device_texture &)mem);
|
||||
tex_free(mem);
|
||||
}
|
||||
else {
|
||||
generic_free(mem);
|
||||
@@ -1027,25 +1017,7 @@ void CUDADevice::const_copy_to(const char *name, void *host, size_t size)
|
||||
cuda_assert(cuMemcpyHtoD(mem, host, size));
|
||||
}
|
||||
|
||||
void CUDADevice::global_alloc(device_memory &mem)
|
||||
{
|
||||
CUDAContextScope scope(this);
|
||||
|
||||
generic_alloc(mem);
|
||||
generic_copy_to(mem);
|
||||
|
||||
const_copy_to(mem.name, &mem.device_pointer, sizeof(mem.device_pointer));
|
||||
}
|
||||
|
||||
void CUDADevice::global_free(device_memory &mem)
|
||||
{
|
||||
if (mem.device_pointer) {
|
||||
CUDAContextScope scope(this);
|
||||
generic_free(mem);
|
||||
}
|
||||
}
|
||||
|
||||
void CUDADevice::tex_alloc(device_texture &mem)
|
||||
void CUDADevice::tex_alloc(device_memory &mem)
|
||||
{
|
||||
CUDAContextScope scope(this);
|
||||
|
||||
@@ -1055,7 +1027,7 @@ void CUDADevice::tex_alloc(device_texture &mem)
|
||||
size_t size = mem.memory_size();
|
||||
|
||||
CUaddress_mode address_mode = CU_TR_ADDRESS_MODE_WRAP;
|
||||
switch (mem.info.extension) {
|
||||
switch (mem.extension) {
|
||||
case EXTENSION_REPEAT:
|
||||
address_mode = CU_TR_ADDRESS_MODE_WRAP;
|
||||
break;
|
||||
@@ -1071,13 +1043,22 @@ void CUDADevice::tex_alloc(device_texture &mem)
|
||||
}
|
||||
|
||||
CUfilter_mode filter_mode;
|
||||
if (mem.info.interpolation == INTERPOLATION_CLOSEST) {
|
||||
if (mem.interpolation == INTERPOLATION_CLOSEST) {
|
||||
filter_mode = CU_TR_FILTER_MODE_POINT;
|
||||
}
|
||||
else {
|
||||
filter_mode = CU_TR_FILTER_MODE_LINEAR;
|
||||
}
|
||||
|
||||
/* Data Storage */
|
||||
if (mem.interpolation == INTERPOLATION_NONE) {
|
||||
generic_alloc(mem);
|
||||
generic_copy_to(mem);
|
||||
|
||||
const_copy_to(bind_name.c_str(), &mem.device_pointer, sizeof(mem.device_pointer));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Image Texture Storage */
|
||||
CUarray_format_enum format;
|
||||
switch (mem.data_type) {
|
||||
@@ -1188,6 +1169,15 @@ void CUDADevice::tex_alloc(device_texture &mem)
|
||||
}
|
||||
|
||||
/* Kepler+, bindless textures. */
|
||||
int flat_slot = 0;
|
||||
if (string_startswith(mem.name, "__tex_image")) {
|
||||
int pos = string(mem.name).rfind("_");
|
||||
flat_slot = atoi(mem.name + pos + 1);
|
||||
}
|
||||
else {
|
||||
assert(0);
|
||||
}
|
||||
|
||||
CUDA_RESOURCE_DESC resDesc;
|
||||
memset(&resDesc, 0, sizeof(resDesc));
|
||||
|
||||
@@ -1224,20 +1214,25 @@ void CUDADevice::tex_alloc(device_texture &mem)
|
||||
cuda_assert(cuTexObjectCreate(&cmem->texobject, &resDesc, &texDesc, NULL));
|
||||
|
||||
/* Resize once */
|
||||
const uint slot = mem.slot;
|
||||
if (slot >= texture_info.size()) {
|
||||
if (flat_slot >= texture_info.size()) {
|
||||
/* Allocate some slots in advance, to reduce amount
|
||||
* of re-allocations. */
|
||||
texture_info.resize(slot + 128);
|
||||
texture_info.resize(flat_slot + 128);
|
||||
}
|
||||
|
||||
/* Set Mapping and tag that we need to (re-)upload to device */
|
||||
texture_info[slot] = mem.info;
|
||||
texture_info[slot].data = (uint64_t)cmem->texobject;
|
||||
TextureInfo &info = texture_info[flat_slot];
|
||||
info.data = (uint64_t)cmem->texobject;
|
||||
info.cl_buffer = 0;
|
||||
info.interpolation = mem.interpolation;
|
||||
info.extension = mem.extension;
|
||||
info.width = mem.data_width;
|
||||
info.height = mem.data_height;
|
||||
info.depth = mem.data_depth;
|
||||
need_texture_info = true;
|
||||
}
|
||||
|
||||
void CUDADevice::tex_free(device_texture &mem)
|
||||
void CUDADevice::tex_free(device_memory &mem)
|
||||
{
|
||||
if (mem.device_pointer) {
|
||||
CUDAContextScope scope(this);
|
||||
|
@@ -25,11 +25,11 @@
|
||||
#include "util/util_logging.h"
|
||||
#include "util/util_math.h"
|
||||
#include "util/util_opengl.h"
|
||||
#include "util/util_string.h"
|
||||
#include "util/util_system.h"
|
||||
#include "util/util_time.h"
|
||||
#include "util/util_system.h"
|
||||
#include "util/util_types.h"
|
||||
#include "util/util_vector.h"
|
||||
#include "util/util_string.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
|
@@ -27,8 +27,8 @@
|
||||
#include "util/util_list.h"
|
||||
#include "util/util_stats.h"
|
||||
#include "util/util_string.h"
|
||||
#include "util/util_texture.h"
|
||||
#include "util/util_thread.h"
|
||||
#include "util/util_texture.h"
|
||||
#include "util/util_types.h"
|
||||
#include "util/util_vector.h"
|
||||
|
||||
|
@@ -264,7 +264,7 @@ class CPUDevice : public Device {
|
||||
|
||||
CPUDevice(DeviceInfo &info_, Stats &stats_, Profiler &profiler_, bool background_)
|
||||
: Device(info_, stats_, profiler_, background_),
|
||||
texture_info(this, "__texture_info", MEM_GLOBAL),
|
||||
texture_info(this, "__texture_info", MEM_TEXTURE),
|
||||
#define REGISTER_KERNEL(name) name##_kernel(KERNEL_FUNCTIONS(name))
|
||||
REGISTER_KERNEL(path_trace),
|
||||
REGISTER_KERNEL(convert_to_half_float),
|
||||
@@ -372,9 +372,6 @@ class CPUDevice : public Device {
|
||||
if (mem.type == MEM_TEXTURE) {
|
||||
assert(!"mem_alloc not supported for textures.");
|
||||
}
|
||||
else if (mem.type == MEM_GLOBAL) {
|
||||
assert(!"mem_alloc not supported for global memory.");
|
||||
}
|
||||
else {
|
||||
if (mem.name) {
|
||||
VLOG(1) << "Buffer allocate: " << mem.name << ", "
|
||||
@@ -399,13 +396,9 @@ class CPUDevice : public Device {
|
||||
|
||||
void mem_copy_to(device_memory &mem)
|
||||
{
|
||||
if (mem.type == MEM_GLOBAL) {
|
||||
global_free(mem);
|
||||
global_alloc(mem);
|
||||
}
|
||||
else if (mem.type == MEM_TEXTURE) {
|
||||
tex_free((device_texture &)mem);
|
||||
tex_alloc((device_texture &)mem);
|
||||
if (mem.type == MEM_TEXTURE) {
|
||||
tex_free(mem);
|
||||
tex_alloc(mem);
|
||||
}
|
||||
else if (mem.type == MEM_PIXELS) {
|
||||
assert(!"mem_copy_to not supported for pixels.");
|
||||
@@ -437,11 +430,8 @@ class CPUDevice : public Device {
|
||||
|
||||
void mem_free(device_memory &mem)
|
||||
{
|
||||
if (mem.type == MEM_GLOBAL) {
|
||||
global_free(mem);
|
||||
}
|
||||
else if (mem.type == MEM_TEXTURE) {
|
||||
tex_free((device_texture &)mem);
|
||||
if (mem.type == MEM_TEXTURE) {
|
||||
tex_free(mem);
|
||||
}
|
||||
else if (mem.device_pointer) {
|
||||
if (mem.type == MEM_DEVICE_ONLY) {
|
||||
@@ -463,50 +453,51 @@ class CPUDevice : public Device {
|
||||
kernel_const_copy(&kernel_globals, name, host, size);
|
||||
}
|
||||
|
||||
void global_alloc(device_memory &mem)
|
||||
{
|
||||
VLOG(1) << "Global memory allocate: " << mem.name << ", "
|
||||
<< string_human_readable_number(mem.memory_size()) << " bytes. ("
|
||||
<< string_human_readable_size(mem.memory_size()) << ")";
|
||||
|
||||
kernel_global_memory_copy(&kernel_globals, mem.name, mem.host_pointer, mem.data_size);
|
||||
|
||||
mem.device_pointer = (device_ptr)mem.host_pointer;
|
||||
mem.device_size = mem.memory_size();
|
||||
stats.mem_alloc(mem.device_size);
|
||||
}
|
||||
|
||||
void global_free(device_memory &mem)
|
||||
{
|
||||
if (mem.device_pointer) {
|
||||
mem.device_pointer = 0;
|
||||
stats.mem_free(mem.device_size);
|
||||
mem.device_size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void tex_alloc(device_texture &mem)
|
||||
void tex_alloc(device_memory &mem)
|
||||
{
|
||||
VLOG(1) << "Texture allocate: " << mem.name << ", "
|
||||
<< string_human_readable_number(mem.memory_size()) << " bytes. ("
|
||||
<< string_human_readable_size(mem.memory_size()) << ")";
|
||||
|
||||
if (mem.interpolation == INTERPOLATION_NONE) {
|
||||
/* Data texture. */
|
||||
kernel_tex_copy(&kernel_globals, mem.name, mem.host_pointer, mem.data_size);
|
||||
}
|
||||
else {
|
||||
/* Image Texture. */
|
||||
int flat_slot = 0;
|
||||
if (string_startswith(mem.name, "__tex_image")) {
|
||||
int pos = string(mem.name).rfind("_");
|
||||
flat_slot = atoi(mem.name + pos + 1);
|
||||
}
|
||||
else {
|
||||
assert(0);
|
||||
}
|
||||
|
||||
if (flat_slot >= texture_info.size()) {
|
||||
/* Allocate some slots in advance, to reduce amount
|
||||
* of re-allocations. */
|
||||
texture_info.resize(flat_slot + 128);
|
||||
}
|
||||
|
||||
TextureInfo &info = texture_info[flat_slot];
|
||||
info.data = (uint64_t)mem.host_pointer;
|
||||
info.cl_buffer = 0;
|
||||
info.interpolation = mem.interpolation;
|
||||
info.extension = mem.extension;
|
||||
info.width = mem.data_width;
|
||||
info.height = mem.data_height;
|
||||
info.depth = mem.data_depth;
|
||||
|
||||
need_texture_info = true;
|
||||
}
|
||||
|
||||
mem.device_pointer = (device_ptr)mem.host_pointer;
|
||||
mem.device_size = mem.memory_size();
|
||||
stats.mem_alloc(mem.device_size);
|
||||
|
||||
const uint slot = mem.slot;
|
||||
if (slot >= texture_info.size()) {
|
||||
/* Allocate some slots in advance, to reduce amount of re-allocations. */
|
||||
texture_info.resize(slot + 128);
|
||||
}
|
||||
|
||||
texture_info[slot] = mem.info;
|
||||
texture_info[slot].data = (uint64_t)mem.host_pointer;
|
||||
need_texture_info = true;
|
||||
}
|
||||
|
||||
void tex_free(device_texture &mem)
|
||||
void tex_free(device_memory &mem)
|
||||
{
|
||||
if (mem.device_pointer) {
|
||||
mem.device_pointer = 0;
|
||||
|
@@ -16,9 +16,9 @@
|
||||
|
||||
#ifdef WITH_CUDA
|
||||
|
||||
# include "device/cuda/device_cuda.h"
|
||||
# include "device/device.h"
|
||||
# include "device/device_intern.h"
|
||||
# include "device/cuda/device_cuda.h"
|
||||
|
||||
# include "util/util_logging.h"
|
||||
# include "util/util_string.h"
|
||||
|
@@ -14,8 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "device/device_memory.h"
|
||||
#include "device/device.h"
|
||||
#include "device/device_memory.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
@@ -31,6 +31,8 @@ device_memory::device_memory(Device *device, const char *name, MemoryType type)
|
||||
data_depth(0),
|
||||
type(type),
|
||||
name(name),
|
||||
interpolation(INTERPOLATION_NONE),
|
||||
extension(EXTENSION_REPEAT),
|
||||
device(device),
|
||||
device_pointer(0),
|
||||
host_pointer(0),
|
||||
@@ -74,7 +76,7 @@ void device_memory::host_free()
|
||||
|
||||
void device_memory::device_alloc()
|
||||
{
|
||||
assert(!device_pointer && type != MEM_TEXTURE && type != MEM_GLOBAL);
|
||||
assert(!device_pointer && type != MEM_TEXTURE);
|
||||
device->mem_alloc(*this);
|
||||
}
|
||||
|
||||
@@ -94,7 +96,7 @@ void device_memory::device_copy_to()
|
||||
|
||||
void device_memory::device_copy_from(int y, int w, int h, int elem)
|
||||
{
|
||||
assert(type != MEM_TEXTURE && type != MEM_READ_ONLY && type != MEM_GLOBAL);
|
||||
assert(type != MEM_TEXTURE && type != MEM_READ_ONLY);
|
||||
device->mem_copy_from(*this, y, w, h, elem);
|
||||
}
|
||||
|
||||
@@ -137,93 +139,4 @@ device_sub_ptr::~device_sub_ptr()
|
||||
device->mem_free_sub_ptr(ptr);
|
||||
}
|
||||
|
||||
/* Device Texture */
|
||||
|
||||
device_texture::device_texture(Device *device,
|
||||
const char *name,
|
||||
const uint slot,
|
||||
ImageDataType image_data_type,
|
||||
InterpolationType interpolation,
|
||||
ExtensionType extension)
|
||||
: device_memory(device, name, MEM_TEXTURE), slot(slot)
|
||||
{
|
||||
switch (image_data_type) {
|
||||
case IMAGE_DATA_TYPE_FLOAT4:
|
||||
data_type = TYPE_FLOAT;
|
||||
data_elements = 4;
|
||||
break;
|
||||
case IMAGE_DATA_TYPE_FLOAT:
|
||||
data_type = TYPE_FLOAT;
|
||||
data_elements = 1;
|
||||
break;
|
||||
case IMAGE_DATA_TYPE_BYTE4:
|
||||
data_type = TYPE_UCHAR;
|
||||
data_elements = 4;
|
||||
break;
|
||||
case IMAGE_DATA_TYPE_BYTE:
|
||||
data_type = TYPE_UCHAR;
|
||||
data_elements = 1;
|
||||
break;
|
||||
case IMAGE_DATA_TYPE_HALF4:
|
||||
data_type = TYPE_HALF;
|
||||
data_elements = 4;
|
||||
break;
|
||||
case IMAGE_DATA_TYPE_HALF:
|
||||
data_type = TYPE_HALF;
|
||||
data_elements = 1;
|
||||
break;
|
||||
case IMAGE_DATA_TYPE_USHORT4:
|
||||
data_type = TYPE_UINT16;
|
||||
data_elements = 4;
|
||||
break;
|
||||
case IMAGE_DATA_TYPE_USHORT:
|
||||
data_type = TYPE_UINT16;
|
||||
data_elements = 1;
|
||||
break;
|
||||
case IMAGE_DATA_NUM_TYPES:
|
||||
assert(0);
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&info, 0, sizeof(info));
|
||||
info.data_type = image_data_type;
|
||||
info.interpolation = interpolation;
|
||||
info.extension = extension;
|
||||
}
|
||||
|
||||
device_texture::~device_texture()
|
||||
{
|
||||
device_free();
|
||||
host_free();
|
||||
}
|
||||
|
||||
/* Host memory allocation. */
|
||||
void *device_texture::alloc(const size_t width, const size_t height, const size_t depth)
|
||||
{
|
||||
const size_t new_size = size(width, height, depth);
|
||||
|
||||
if (new_size != data_size) {
|
||||
device_free();
|
||||
host_free();
|
||||
host_pointer = host_alloc(data_elements * datatype_size(data_type) * new_size);
|
||||
assert(device_pointer == 0);
|
||||
}
|
||||
|
||||
data_size = new_size;
|
||||
data_width = width;
|
||||
data_height = height;
|
||||
data_depth = depth;
|
||||
|
||||
info.width = width;
|
||||
info.height = height;
|
||||
info.depth = depth;
|
||||
|
||||
return host_pointer;
|
||||
}
|
||||
|
||||
void device_texture::copy_to_device()
|
||||
{
|
||||
device_copy_to();
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
@@ -23,7 +23,6 @@
|
||||
|
||||
#include "util/util_array.h"
|
||||
#include "util/util_half.h"
|
||||
#include "util/util_string.h"
|
||||
#include "util/util_texture.h"
|
||||
#include "util/util_types.h"
|
||||
#include "util/util_vector.h"
|
||||
@@ -32,14 +31,7 @@ CCL_NAMESPACE_BEGIN
|
||||
|
||||
class Device;
|
||||
|
||||
enum MemoryType {
|
||||
MEM_READ_ONLY,
|
||||
MEM_READ_WRITE,
|
||||
MEM_DEVICE_ONLY,
|
||||
MEM_GLOBAL,
|
||||
MEM_TEXTURE,
|
||||
MEM_PIXELS
|
||||
};
|
||||
enum MemoryType { MEM_READ_ONLY, MEM_READ_WRITE, MEM_DEVICE_ONLY, MEM_TEXTURE, MEM_PIXELS };
|
||||
|
||||
/* Supported Data Types */
|
||||
|
||||
@@ -216,6 +208,8 @@ class device_memory {
|
||||
size_t data_depth;
|
||||
MemoryType type;
|
||||
const char *name;
|
||||
InterpolationType interpolation;
|
||||
ExtensionType extension;
|
||||
|
||||
/* Pointers. */
|
||||
Device *device;
|
||||
@@ -316,7 +310,7 @@ template<typename T> class device_only_memory : public device_memory {
|
||||
* in and copied to the device with copy_to_device(). Or alternatively
|
||||
* allocated and set to zero on the device with zero_to_device().
|
||||
*
|
||||
* When using memory type MEM_GLOBAL, a pointer to this memory will be
|
||||
* When using memory type MEM_TEXTURE, a pointer to this memory will be
|
||||
* automatically attached to kernel globals, using the provided name
|
||||
* matching an entry in kernel_textures.h. */
|
||||
|
||||
@@ -509,33 +503,6 @@ class device_sub_ptr {
|
||||
device_ptr ptr;
|
||||
};
|
||||
|
||||
/* Device Texture
|
||||
*
|
||||
* 2D or 3D image texture memory. */
|
||||
|
||||
class device_texture : public device_memory {
|
||||
public:
|
||||
device_texture(Device *device,
|
||||
const char *name,
|
||||
const uint slot,
|
||||
ImageDataType image_data_type,
|
||||
InterpolationType interpolation,
|
||||
ExtensionType extension);
|
||||
~device_texture();
|
||||
|
||||
void *alloc(const size_t width, const size_t height, const size_t depth = 0);
|
||||
void copy_to_device();
|
||||
|
||||
uint slot;
|
||||
TextureInfo info;
|
||||
|
||||
protected:
|
||||
size_t size(const size_t width, const size_t height, const size_t depth)
|
||||
{
|
||||
return width * ((height == 0) ? 1 : height) * ((depth == 0) ? 1 : depth);
|
||||
}
|
||||
};
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
#endif /* __DEVICE_MEMORY_H__ */
|
||||
|
@@ -14,8 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <sstream>
|
||||
#include <stdlib.h>
|
||||
#include <sstream>
|
||||
|
||||
#include "device/device.h"
|
||||
#include "device/device_intern.h"
|
||||
|
@@ -14,9 +14,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "device/device_network.h"
|
||||
#include "device/device.h"
|
||||
#include "device/device_intern.h"
|
||||
#include "device/device_network.h"
|
||||
|
||||
#include "util/util_foreach.h"
|
||||
#include "util/util_logging.h"
|
||||
|
@@ -19,19 +19,19 @@
|
||||
|
||||
#ifdef WITH_NETWORK
|
||||
|
||||
# include <boost/archive/binary_iarchive.hpp>
|
||||
# include <boost/archive/binary_oarchive.hpp>
|
||||
# include <boost/archive/text_iarchive.hpp>
|
||||
# include <boost/archive/text_oarchive.hpp>
|
||||
# include <boost/archive/binary_iarchive.hpp>
|
||||
# include <boost/archive/binary_oarchive.hpp>
|
||||
# include <boost/array.hpp>
|
||||
# include <boost/asio.hpp>
|
||||
# include <boost/bind.hpp>
|
||||
# include <boost/serialization/vector.hpp>
|
||||
# include <boost/thread.hpp>
|
||||
|
||||
# include <deque>
|
||||
# include <iostream>
|
||||
# include <sstream>
|
||||
# include <deque>
|
||||
|
||||
# include "render/buffers.h"
|
||||
|
||||
|
@@ -16,9 +16,9 @@
|
||||
|
||||
#ifdef WITH_OPENCL
|
||||
|
||||
# include "device/opencl/device_opencl.h"
|
||||
# include "device/device.h"
|
||||
# include "device/device_intern.h"
|
||||
# include "device/opencl/device_opencl.h"
|
||||
|
||||
# include "util/util_foreach.h"
|
||||
# include "util/util_logging.h"
|
||||
|
@@ -17,28 +17,28 @@
|
||||
|
||||
#ifdef WITH_OPTIX
|
||||
|
||||
# include "bvh/bvh.h"
|
||||
# include "device/cuda/device_cuda.h"
|
||||
# include "device/device_denoising.h"
|
||||
# include "device/device_intern.h"
|
||||
# include "render/buffers.h"
|
||||
# include "device/device_denoising.h"
|
||||
# include "bvh/bvh.h"
|
||||
# include "render/scene.h"
|
||||
# include "render/hair.h"
|
||||
# include "render/mesh.h"
|
||||
# include "render/object.h"
|
||||
# include "render/scene.h"
|
||||
# include "util/util_debug.h"
|
||||
# include "util/util_logging.h"
|
||||
# include "render/buffers.h"
|
||||
# include "util/util_md5.h"
|
||||
# include "util/util_path.h"
|
||||
# include "util/util_time.h"
|
||||
# include "util/util_debug.h"
|
||||
# include "util/util_logging.h"
|
||||
|
||||
# ifdef WITH_CUDA_DYNLOAD
|
||||
# include <cuew.h>
|
||||
// Do not use CUDA SDK headers when using CUEW
|
||||
# define OPTIX_DONT_INCLUDE_CUDA
|
||||
# endif
|
||||
# include <optix_function_table_definition.h>
|
||||
# include <optix_stubs.h>
|
||||
# include <optix_function_table_definition.h>
|
||||
|
||||
// TODO(pmours): Disable this once drivers have native support
|
||||
# define OPTIX_DENOISER_NO_PIXEL_STRIDE 1
|
||||
@@ -477,9 +477,9 @@ class OptiXDevice : public CUDADevice {
|
||||
// Calculate maximum trace continuation stack size
|
||||
unsigned int trace_css = stack_size[PG_HITD].cssCH;
|
||||
// This is based on the maximum of closest-hit and any-hit/intersection programs
|
||||
trace_css = std::max(trace_css, stack_size[PG_HITD].cssIS + stack_size[PG_HITD].cssAH);
|
||||
trace_css = std::max(trace_css, stack_size[PG_HITL].cssIS + stack_size[PG_HITL].cssAH);
|
||||
trace_css = std::max(trace_css, stack_size[PG_HITS].cssIS + stack_size[PG_HITS].cssAH);
|
||||
trace_css = max(trace_css, stack_size[PG_HITD].cssIS + stack_size[PG_HITD].cssAH);
|
||||
trace_css = max(trace_css, stack_size[PG_HITL].cssIS + stack_size[PG_HITL].cssAH);
|
||||
trace_css = max(trace_css, stack_size[PG_HITS].cssIS + stack_size[PG_HITS].cssAH);
|
||||
|
||||
OptixPipelineLinkOptions link_options;
|
||||
link_options.maxTraceDepth = 1;
|
||||
@@ -548,9 +548,8 @@ class OptiXDevice : public CUDADevice {
|
||||
&pipelines[PIP_SHADER_EVAL]));
|
||||
|
||||
// Calculate continuation stack size based on the maximum of all ray generation stack sizes
|
||||
const unsigned int css = std::max(stack_size[PG_BAKE].cssRG,
|
||||
std::max(stack_size[PG_DISP].cssRG,
|
||||
stack_size[PG_BACK].cssRG)) +
|
||||
const unsigned int css = max(stack_size[PG_BAKE].cssRG,
|
||||
max(stack_size[PG_DISP].cssRG, stack_size[PG_BACK].cssRG)) +
|
||||
link_options.maxTraceDepth * trace_css;
|
||||
|
||||
check_result_optix_ret(optixPipelineSetStackSize(
|
||||
|
@@ -428,10 +428,8 @@ class OpenCLDevice : public Device {
|
||||
int mem_sub_ptr_alignment();
|
||||
|
||||
void const_copy_to(const char *name, void *host, size_t size);
|
||||
void global_alloc(device_memory &mem);
|
||||
void global_free(device_memory &mem);
|
||||
void tex_alloc(device_texture &mem);
|
||||
void tex_free(device_texture &mem);
|
||||
void tex_alloc(device_memory &mem);
|
||||
void tex_free(device_memory &mem);
|
||||
|
||||
size_t global_size_round_up(int group_size, int global_size);
|
||||
void enqueue_kernel(cl_kernel kernel,
|
||||
|
@@ -613,7 +613,7 @@ OpenCLDevice::OpenCLDevice(DeviceInfo &info, Stats &stats, Profiler &profiler, b
|
||||
kernel_programs(this),
|
||||
preview_programs(this),
|
||||
memory_manager(this),
|
||||
texture_info(this, "__texture_info", MEM_GLOBAL)
|
||||
texture_info(this, "__texture_info", MEM_TEXTURE)
|
||||
{
|
||||
cpPlatform = NULL;
|
||||
cdDevice = NULL;
|
||||
@@ -945,7 +945,7 @@ void OpenCLDevice::mem_alloc(device_memory &mem)
|
||||
cl_mem_flags mem_flag;
|
||||
void *mem_ptr = NULL;
|
||||
|
||||
if (mem.type == MEM_READ_ONLY || mem.type == MEM_TEXTURE || mem.type == MEM_GLOBAL)
|
||||
if (mem.type == MEM_READ_ONLY || mem.type == MEM_TEXTURE)
|
||||
mem_flag = CL_MEM_READ_ONLY;
|
||||
else
|
||||
mem_flag = CL_MEM_READ_WRITE;
|
||||
@@ -969,13 +969,9 @@ void OpenCLDevice::mem_alloc(device_memory &mem)
|
||||
|
||||
void OpenCLDevice::mem_copy_to(device_memory &mem)
|
||||
{
|
||||
if (mem.type == MEM_GLOBAL) {
|
||||
global_free(mem);
|
||||
global_alloc(mem);
|
||||
}
|
||||
else if (mem.type == MEM_TEXTURE) {
|
||||
tex_free((device_texture &)mem);
|
||||
tex_alloc((device_texture &)mem);
|
||||
if (mem.type == MEM_TEXTURE) {
|
||||
tex_free(mem);
|
||||
tex_alloc(mem);
|
||||
}
|
||||
else {
|
||||
if (!mem.device_pointer) {
|
||||
@@ -1081,11 +1077,8 @@ void OpenCLDevice::mem_zero(device_memory &mem)
|
||||
|
||||
void OpenCLDevice::mem_free(device_memory &mem)
|
||||
{
|
||||
if (mem.type == MEM_GLOBAL) {
|
||||
global_free(mem);
|
||||
}
|
||||
else if (mem.type == MEM_TEXTURE) {
|
||||
tex_free((device_texture &)mem);
|
||||
if (mem.type == MEM_TEXTURE) {
|
||||
tex_free(mem);
|
||||
}
|
||||
else {
|
||||
if (mem.device_pointer) {
|
||||
@@ -1108,7 +1101,7 @@ int OpenCLDevice::mem_sub_ptr_alignment()
|
||||
device_ptr OpenCLDevice::mem_alloc_sub_ptr(device_memory &mem, int offset, int size)
|
||||
{
|
||||
cl_mem_flags mem_flag;
|
||||
if (mem.type == MEM_READ_ONLY || mem.type == MEM_TEXTURE || mem.type == MEM_GLOBAL)
|
||||
if (mem.type == MEM_READ_ONLY || mem.type == MEM_TEXTURE)
|
||||
mem_flag = CL_MEM_READ_ONLY;
|
||||
else
|
||||
mem_flag = CL_MEM_READ_WRITE;
|
||||
@@ -1148,9 +1141,9 @@ void OpenCLDevice::const_copy_to(const char *name, void *host, size_t size)
|
||||
data->copy_to_device();
|
||||
}
|
||||
|
||||
void OpenCLDevice::global_alloc(device_memory &mem)
|
||||
void OpenCLDevice::tex_alloc(device_memory &mem)
|
||||
{
|
||||
VLOG(1) << "Global memory allocate: " << mem.name << ", "
|
||||
VLOG(1) << "Texture allocate: " << mem.name << ", "
|
||||
<< string_human_readable_number(mem.memory_size()) << " bytes. ("
|
||||
<< string_human_readable_size(mem.memory_size()) << ")";
|
||||
|
||||
@@ -1162,7 +1155,7 @@ void OpenCLDevice::global_alloc(device_memory &mem)
|
||||
textures_need_update = true;
|
||||
}
|
||||
|
||||
void OpenCLDevice::global_free(device_memory &mem)
|
||||
void OpenCLDevice::tex_free(device_memory &mem)
|
||||
{
|
||||
if (mem.device_pointer) {
|
||||
mem.device_pointer = 0;
|
||||
@@ -1180,25 +1173,6 @@ void OpenCLDevice::global_free(device_memory &mem)
|
||||
}
|
||||
}
|
||||
|
||||
void OpenCLDevice::tex_alloc(device_texture &mem)
|
||||
{
|
||||
VLOG(1) << "Texture allocate: " << mem.name << ", "
|
||||
<< string_human_readable_number(mem.memory_size()) << " bytes. ("
|
||||
<< string_human_readable_size(mem.memory_size()) << ")";
|
||||
|
||||
memory_manager.alloc(mem.name, mem);
|
||||
/* Set the pointer to non-null to keep code that inspects its value from thinking its
|
||||
* unallocated. */
|
||||
mem.device_pointer = 1;
|
||||
textures[mem.name] = &mem;
|
||||
textures_need_update = true;
|
||||
}
|
||||
|
||||
void OpenCLDevice::tex_free(device_texture &mem)
|
||||
{
|
||||
global_free(mem);
|
||||
}
|
||||
|
||||
size_t OpenCLDevice::global_size_round_up(int group_size, int global_size)
|
||||
{
|
||||
int r = global_size % group_size;
|
||||
@@ -1299,10 +1273,10 @@ void OpenCLDevice::flush_texture_buffers()
|
||||
|
||||
foreach (TexturesMap::value_type &tex, textures) {
|
||||
string name = tex.first;
|
||||
device_memory *mem = tex.second;
|
||||
|
||||
if (mem->type == MEM_TEXTURE) {
|
||||
const uint id = ((device_texture *)mem)->slot;
|
||||
if (string_startswith(name, "__tex_image")) {
|
||||
int pos = name.rfind("_");
|
||||
int id = atoi(name.data() + pos + 1);
|
||||
texture_slots.push_back(texture_slot_t(name, num_data_slots + id));
|
||||
num_slots = max(num_slots, num_data_slots + id + 1);
|
||||
}
|
||||
@@ -1315,20 +1289,22 @@ void OpenCLDevice::flush_texture_buffers()
|
||||
|
||||
/* Fill in descriptors */
|
||||
foreach (texture_slot_t &slot, texture_slots) {
|
||||
device_memory *mem = textures[slot.name];
|
||||
TextureInfo &info = texture_info[slot.slot];
|
||||
|
||||
MemoryManager::BufferDescriptor desc = memory_manager.get_descriptor(slot.name);
|
||||
|
||||
if (mem->type == MEM_TEXTURE) {
|
||||
info = ((device_texture *)mem)->info;
|
||||
}
|
||||
else {
|
||||
memset(&info, 0, sizeof(TextureInfo));
|
||||
}
|
||||
|
||||
info.data = desc.offset;
|
||||
info.cl_buffer = desc.device_buffer;
|
||||
|
||||
if (string_startswith(slot.name, "__tex_image")) {
|
||||
device_memory *mem = textures[slot.name];
|
||||
|
||||
info.width = mem->data_width;
|
||||
info.height = mem->data_height;
|
||||
info.depth = mem->data_depth;
|
||||
|
||||
info.interpolation = mem->interpolation;
|
||||
info.extension = mem->extension;
|
||||
}
|
||||
}
|
||||
|
||||
/* Force write of descriptors. */
|
||||
|
@@ -19,8 +19,8 @@
|
||||
#include "device/device.h"
|
||||
|
||||
#include "util/util_map.h"
|
||||
#include "util/util_string.h"
|
||||
#include "util/util_vector.h"
|
||||
#include "util/util_string.h"
|
||||
|
||||
#include "clew.h"
|
||||
|
||||
|
@@ -16,15 +16,15 @@
|
||||
|
||||
#ifdef WITH_OPENCL
|
||||
|
||||
# include "device/device_intern.h"
|
||||
# include "device/opencl/device_opencl.h"
|
||||
# include "device/device_intern.h"
|
||||
|
||||
# include "util/util_debug.h"
|
||||
# include "util/util_logging.h"
|
||||
# include "util/util_md5.h"
|
||||
# include "util/util_path.h"
|
||||
# include "util/util_system.h"
|
||||
# include "util/util_time.h"
|
||||
# include "util/util_system.h"
|
||||
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
|
@@ -320,26 +320,6 @@ ccl_device_inline uint object_patch_map_offset(KernelGlobals *kg, int object)
|
||||
return kernel_tex_fetch(__objects, object).patch_map_offset;
|
||||
}
|
||||
|
||||
/* Volume step size */
|
||||
|
||||
ccl_device_inline float object_volume_density(KernelGlobals *kg, int object)
|
||||
{
|
||||
if (object == OBJECT_NONE) {
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
return kernel_tex_fetch(__objects, object).surface_area;
|
||||
}
|
||||
|
||||
ccl_device_inline float object_volume_step_size(KernelGlobals *kg, int object)
|
||||
{
|
||||
if (object == OBJECT_NONE) {
|
||||
return kernel_data.background.volume_step_size;
|
||||
}
|
||||
|
||||
return kernel_tex_fetch(__object_volume_step, object);
|
||||
}
|
||||
|
||||
/* Pass ID for shader */
|
||||
|
||||
ccl_device int shader_pass_id(KernelGlobals *kg, const ShaderData *sd)
|
||||
|
@@ -51,14 +51,10 @@ ccl_device float volume_attribute_float(KernelGlobals *kg,
|
||||
const ShaderData *sd,
|
||||
const AttributeDescriptor desc)
|
||||
{
|
||||
/* todo: optimize this so we don't have to transform both here and in
|
||||
* kernel_tex_image_interp_3d when possible. Also could optimize for the
|
||||
* common case where transform is translation/scale only. */
|
||||
float3 P = sd->P;
|
||||
object_inverse_position_transform(kg, sd, &P);
|
||||
float3 P = volume_normalized_position(kg, sd, sd->P);
|
||||
InterpolationType interp = (sd->flag & SD_VOLUME_CUBIC) ? INTERPOLATION_CUBIC :
|
||||
INTERPOLATION_NONE;
|
||||
float4 r = kernel_tex_image_interp_3d(kg, desc.offset, P, interp);
|
||||
float4 r = kernel_tex_image_interp_3d(kg, desc.offset, P.x, P.y, P.z, interp);
|
||||
return average(float4_to_float3(r));
|
||||
}
|
||||
|
||||
@@ -66,11 +62,10 @@ ccl_device float3 volume_attribute_float3(KernelGlobals *kg,
|
||||
const ShaderData *sd,
|
||||
const AttributeDescriptor desc)
|
||||
{
|
||||
float3 P = sd->P;
|
||||
object_inverse_position_transform(kg, sd, &P);
|
||||
float3 P = volume_normalized_position(kg, sd, sd->P);
|
||||
InterpolationType interp = (sd->flag & SD_VOLUME_CUBIC) ? INTERPOLATION_CUBIC :
|
||||
INTERPOLATION_NONE;
|
||||
float4 r = kernel_tex_image_interp_3d(kg, desc.offset, P, interp);
|
||||
float4 r = kernel_tex_image_interp_3d(kg, desc.offset, P.x, P.y, P.z, interp);
|
||||
|
||||
if (r.w > 1e-6f && r.w != 1.0f) {
|
||||
/* For RGBA colors, unpremultiply after interpolation. */
|
||||
|
@@ -19,8 +19,8 @@
|
||||
|
||||
/* CPU Kernel Interface */
|
||||
|
||||
#include "kernel/kernel_types.h"
|
||||
#include "util/util_types.h"
|
||||
#include "kernel/kernel_types.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
@@ -38,7 +38,7 @@ void *kernel_osl_memory(KernelGlobals *kg);
|
||||
bool kernel_osl_use(KernelGlobals *kg);
|
||||
|
||||
void kernel_const_copy(KernelGlobals *kg, const char *name, void *host, size_t size);
|
||||
void kernel_global_memory_copy(KernelGlobals *kg, const char *name, void *mem, size_t size);
|
||||
void kernel_tex_copy(KernelGlobals *kg, const char *name, void *mem, size_t size);
|
||||
|
||||
#define KERNEL_ARCH cpu
|
||||
#include "kernel/kernels/cpu/kernel_cpu.h"
|
||||
|
@@ -54,6 +54,12 @@ ccl_device void kernel_adaptive_post_adjust(KernelGlobals *kg,
|
||||
#ifdef __PASSES__
|
||||
int flag = kernel_data.film.pass_flag;
|
||||
|
||||
if (flag & PASSMASK(SHADOW))
|
||||
*(ccl_global float3 *)(buffer + kernel_data.film.pass_shadow) *= sample_multiplier;
|
||||
|
||||
if (flag & PASSMASK(MIST))
|
||||
*(ccl_global float *)(buffer + kernel_data.film.pass_mist) *= sample_multiplier;
|
||||
|
||||
if (flag & PASSMASK(NORMAL))
|
||||
*(ccl_global float3 *)(buffer + kernel_data.film.pass_normal) *= sample_multiplier;
|
||||
|
||||
@@ -68,11 +74,6 @@ ccl_device void kernel_adaptive_post_adjust(KernelGlobals *kg,
|
||||
if (kernel_data.film.use_light_pass) {
|
||||
int light_flag = kernel_data.film.light_pass_flag;
|
||||
|
||||
if (light_flag & PASSMASK(MIST))
|
||||
*(ccl_global float *)(buffer + kernel_data.film.pass_mist) *= sample_multiplier;
|
||||
|
||||
/* Shadow pass omitted on purpose. It has its own scale parameter. */
|
||||
|
||||
if (light_flag & PASSMASK(DIFFUSE_INDIRECT))
|
||||
*(ccl_global float3 *)(buffer + kernel_data.film.pass_diffuse_indirect) *= sample_multiplier;
|
||||
if (light_flag & PASSMASK(GLOSSY_INDIRECT))
|
||||
|
@@ -35,11 +35,11 @@
|
||||
# define __NODES_FEATURES__ NODE_FEATURE_ALL
|
||||
#endif
|
||||
|
||||
#include "util/util_half.h"
|
||||
#include "util/util_math.h"
|
||||
#include "util/util_simd.h"
|
||||
#include "util/util_texture.h"
|
||||
#include "util/util_half.h"
|
||||
#include "util/util_types.h"
|
||||
#include "util/util_texture.h"
|
||||
|
||||
#define ccl_addr_space
|
||||
|
||||
|
@@ -22,8 +22,8 @@
|
||||
#include "kernel/kernel_profiling.h"
|
||||
|
||||
#ifdef __KERNEL_CPU__
|
||||
# include "util/util_map.h"
|
||||
# include "util/util_vector.h"
|
||||
# include "util/util_map.h"
|
||||
#endif
|
||||
|
||||
#ifdef __KERNEL_OPENCL__
|
||||
|
@@ -198,7 +198,7 @@ ccl_device void cmj_sample_2D(int s, int N, int p, float *fx, float *fy)
|
||||
ccl_device float pmj_sample_1D(KernelGlobals *kg, int sample, int rng_hash, int dimension)
|
||||
{
|
||||
/* Fallback to random */
|
||||
if (sample >= NUM_PMJ_SAMPLES) {
|
||||
if (sample > NUM_PMJ_SAMPLES) {
|
||||
int p = rng_hash + dimension;
|
||||
return cmj_randfloat(sample, p);
|
||||
}
|
||||
@@ -211,11 +211,10 @@ ccl_device float pmj_sample_1D(KernelGlobals *kg, int sample, int rng_hash, int
|
||||
ccl_device void pmj_sample_2D(
|
||||
KernelGlobals *kg, int sample, int rng_hash, int dimension, float *fx, float *fy)
|
||||
{
|
||||
if (sample >= NUM_PMJ_SAMPLES) {
|
||||
if (sample > NUM_PMJ_SAMPLES) {
|
||||
int p = rng_hash + dimension;
|
||||
*fx = cmj_randfloat(sample, p);
|
||||
*fy = cmj_randfloat(sample, p + 1);
|
||||
return;
|
||||
}
|
||||
uint tmp_rng = cmj_hash_simple(dimension, rng_hash);
|
||||
int index = ((dimension % NUM_PMJ_PATTERNS) * NUM_PMJ_SAMPLES + sample) * 2;
|
||||
|
@@ -171,19 +171,19 @@ ccl_device_forceinline VolumeIntegrateResult kernel_path_volume(KernelGlobals *k
|
||||
Ray volume_ray = *ray;
|
||||
volume_ray.t = (hit) ? isect->t : FLT_MAX;
|
||||
|
||||
float step_size = volume_stack_step_size(kg, state->volume_stack);
|
||||
bool heterogeneous = volume_stack_is_heterogeneous(kg, state->volume_stack);
|
||||
|
||||
# ifdef __VOLUME_DECOUPLED__
|
||||
int sampling_method = volume_stack_sampling_method(kg, state->volume_stack);
|
||||
bool direct = (state->flag & PATH_RAY_CAMERA) != 0;
|
||||
bool decoupled = kernel_volume_use_decoupled(kg, step_size, direct, sampling_method);
|
||||
bool decoupled = kernel_volume_use_decoupled(kg, heterogeneous, direct, sampling_method);
|
||||
|
||||
if (decoupled) {
|
||||
/* cache steps along volume for repeated sampling */
|
||||
VolumeSegment volume_segment;
|
||||
|
||||
shader_setup_from_volume(kg, sd, &volume_ray);
|
||||
kernel_volume_decoupled_record(kg, state, &volume_ray, sd, &volume_segment, step_size);
|
||||
kernel_volume_decoupled_record(kg, state, &volume_ray, sd, &volume_segment, heterogeneous);
|
||||
|
||||
volume_segment.sampling_method = sampling_method;
|
||||
|
||||
@@ -229,7 +229,7 @@ ccl_device_forceinline VolumeIntegrateResult kernel_path_volume(KernelGlobals *k
|
||||
{
|
||||
/* integrate along volume segment with distance sampling */
|
||||
VolumeIntegrateResult result = kernel_volume_integrate(
|
||||
kg, state, sd, &volume_ray, L, throughput, step_size);
|
||||
kg, state, sd, &volume_ray, L, throughput, heterogeneous);
|
||||
|
||||
# ifdef __VOLUME_SCATTER__
|
||||
if (result == VOLUME_PATH_SCATTERED) {
|
||||
|
@@ -91,7 +91,7 @@ ccl_device_forceinline void kernel_branched_path_volume(KernelGlobals *kg,
|
||||
Ray volume_ray = *ray;
|
||||
volume_ray.t = (hit) ? isect->t : FLT_MAX;
|
||||
|
||||
float step_size = volume_stack_step_size(kg, state->volume_stack);
|
||||
bool heterogeneous = volume_stack_is_heterogeneous(kg, state->volume_stack);
|
||||
|
||||
# ifdef __VOLUME_DECOUPLED__
|
||||
/* decoupled ray marching only supported on CPU */
|
||||
@@ -100,7 +100,7 @@ ccl_device_forceinline void kernel_branched_path_volume(KernelGlobals *kg,
|
||||
VolumeSegment volume_segment;
|
||||
|
||||
shader_setup_from_volume(kg, sd, &volume_ray);
|
||||
kernel_volume_decoupled_record(kg, state, &volume_ray, sd, &volume_segment, step_size);
|
||||
kernel_volume_decoupled_record(kg, state, &volume_ray, sd, &volume_segment, heterogeneous);
|
||||
|
||||
/* direct light sampling */
|
||||
if (volume_segment.closure_flag & SD_SCATTER) {
|
||||
@@ -171,7 +171,7 @@ ccl_device_forceinline void kernel_branched_path_volume(KernelGlobals *kg,
|
||||
path_state_branch(&ps, j, num_samples);
|
||||
|
||||
VolumeIntegrateResult result = kernel_volume_integrate(
|
||||
kg, &ps, sd, &volume_ray, L, &tp, step_size);
|
||||
kg, &ps, sd, &volume_ray, L, &tp, heterogeneous);
|
||||
|
||||
# ifdef __VOLUME_SCATTER__
|
||||
if (result == VOLUME_PATH_SCATTERED) {
|
||||
|
@@ -294,15 +294,12 @@ ccl_device_inline bool sample_is_even(int pattern, int sample)
|
||||
if (pattern == SAMPLING_PATTERN_PMJ) {
|
||||
/* See Section 10.2.1, "Progressive Multi-Jittered Sample Sequences", Christensen et al.
|
||||
* We can use this to get divide sample sequence into two classes for easier variance
|
||||
* estimation. */
|
||||
* estimation. There must be a more elegant way of writing this? */
|
||||
#if defined(__GNUC__) && !defined(__KERNEL_GPU__)
|
||||
return __builtin_popcount(sample & 0xaaaaaaaa) & 1;
|
||||
#elif defined(__NVCC__)
|
||||
return __popc(sample & 0xaaaaaaaa) & 1;
|
||||
#elif defined(__KERNEL_OPENCL__)
|
||||
return popcount(sample & 0xaaaaaaaa) & 1;
|
||||
#else
|
||||
/* TODO(Stefan): popcnt intrinsic for Windows with fallback for older CPUs. */
|
||||
int i = sample & 0xaaaaaaaa;
|
||||
i = i - ((i >> 1) & 0x55555555);
|
||||
i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
|
||||
|
@@ -35,7 +35,6 @@ KERNEL_TEX(KernelObject, __objects)
|
||||
KERNEL_TEX(Transform, __object_motion_pass)
|
||||
KERNEL_TEX(DecomposedTransform, __object_motion)
|
||||
KERNEL_TEX(uint, __object_flag)
|
||||
KERNEL_TEX(float, __object_volume_step)
|
||||
|
||||
/* cameras */
|
||||
KERNEL_TEX(DecomposedTransform, __camera_motion)
|
||||
|
@@ -887,13 +887,13 @@ enum ShaderDataFlag {
|
||||
SD_HAS_DISPLACEMENT = (1 << 26),
|
||||
/* Has constant emission (value stored in __shaders) */
|
||||
SD_HAS_CONSTANT_EMISSION = (1 << 27),
|
||||
/* Needs to access attributes for volume rendering */
|
||||
SD_NEED_VOLUME_ATTRIBUTES = (1 << 28),
|
||||
/* Needs to access attributes */
|
||||
SD_NEED_ATTRIBUTES = (1 << 28),
|
||||
|
||||
SD_SHADER_FLAGS = (SD_USE_MIS | SD_HAS_TRANSPARENT_SHADOW | SD_HAS_VOLUME | SD_HAS_ONLY_VOLUME |
|
||||
SD_HETEROGENEOUS_VOLUME | SD_HAS_BSSRDF_BUMP | SD_VOLUME_EQUIANGULAR |
|
||||
SD_VOLUME_MIS | SD_VOLUME_CUBIC | SD_HAS_BUMP | SD_HAS_DISPLACEMENT |
|
||||
SD_HAS_CONSTANT_EMISSION | SD_NEED_VOLUME_ATTRIBUTES)
|
||||
SD_HAS_CONSTANT_EMISSION | SD_NEED_ATTRIBUTES)
|
||||
};
|
||||
|
||||
/* Object flags. */
|
||||
@@ -1275,7 +1275,6 @@ typedef struct KernelBackground {
|
||||
/* only shader index */
|
||||
int surface_shader;
|
||||
int volume_shader;
|
||||
float volume_step_size;
|
||||
int transparent;
|
||||
float transparent_roughness_squared_threshold;
|
||||
|
||||
@@ -1283,6 +1282,7 @@ typedef struct KernelBackground {
|
||||
float ao_factor;
|
||||
float ao_distance;
|
||||
float ao_bounces_factor;
|
||||
float ao_pad;
|
||||
} KernelBackground;
|
||||
static_assert_align(KernelBackground, 16);
|
||||
|
||||
@@ -1355,7 +1355,7 @@ typedef struct KernelIntegrator {
|
||||
/* volume render */
|
||||
int use_volumes;
|
||||
int volume_max_steps;
|
||||
float volume_step_rate;
|
||||
float volume_step_size;
|
||||
int volume_samples;
|
||||
|
||||
int start_sample;
|
||||
|
@@ -48,8 +48,7 @@ ccl_device_inline bool volume_shader_extinction_sample(KernelGlobals *kg,
|
||||
shader_eval_volume(kg, sd, state, state->volume_stack, PATH_RAY_SHADOW);
|
||||
|
||||
if (sd->flag & SD_EXTINCTION) {
|
||||
const float density = object_volume_density(kg, sd->object);
|
||||
*extinction = sd->closure_transparent_extinction * density;
|
||||
*extinction = sd->closure_transparent_extinction;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
@@ -85,11 +84,6 @@ ccl_device_inline bool volume_shader_sample(KernelGlobals *kg,
|
||||
}
|
||||
}
|
||||
|
||||
const float density = object_volume_density(kg, sd->object);
|
||||
coeff->sigma_s *= density;
|
||||
coeff->sigma_t *= density;
|
||||
coeff->emission *= density;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -107,19 +101,15 @@ ccl_device float kernel_volume_channel_get(float3 value, int channel)
|
||||
|
||||
#ifdef __VOLUME__
|
||||
|
||||
ccl_device float volume_stack_step_size(KernelGlobals *kg, ccl_addr_space VolumeStack *stack)
|
||||
ccl_device bool volume_stack_is_heterogeneous(KernelGlobals *kg, ccl_addr_space VolumeStack *stack)
|
||||
{
|
||||
float step_size = FLT_MAX;
|
||||
|
||||
for (int i = 0; stack[i].shader != SHADER_NONE; i++) {
|
||||
int shader_flag = kernel_tex_fetch(__shaders, (stack[i].shader & SHADER_MASK)).flags;
|
||||
|
||||
bool heterogeneous = false;
|
||||
|
||||
if (shader_flag & SD_HETEROGENEOUS_VOLUME) {
|
||||
heterogeneous = true;
|
||||
return true;
|
||||
}
|
||||
else if (shader_flag & SD_NEED_VOLUME_ATTRIBUTES) {
|
||||
else if (shader_flag & SD_NEED_ATTRIBUTES) {
|
||||
/* We want to render world or objects without any volume grids
|
||||
* as homogeneous, but can only verify this at run-time since other
|
||||
* heterogeneous volume objects may be using the same shader. */
|
||||
@@ -127,19 +117,13 @@ ccl_device float volume_stack_step_size(KernelGlobals *kg, ccl_addr_space Volume
|
||||
if (object != OBJECT_NONE) {
|
||||
int object_flag = kernel_tex_fetch(__object_flag, object);
|
||||
if (object_flag & SD_OBJECT_HAS_VOLUME_ATTRIBUTES) {
|
||||
heterogeneous = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (heterogeneous) {
|
||||
float object_step_size = object_volume_step_size(kg, stack[i].object);
|
||||
object_step_size *= kernel_data.integrator.volume_step_rate;
|
||||
step_size = fminf(object_step_size, step_size);
|
||||
}
|
||||
}
|
||||
|
||||
return step_size;
|
||||
return false;
|
||||
}
|
||||
|
||||
ccl_device int volume_stack_sampling_method(KernelGlobals *kg, VolumeStack *stack)
|
||||
@@ -174,13 +158,12 @@ ccl_device int volume_stack_sampling_method(KernelGlobals *kg, VolumeStack *stac
|
||||
|
||||
ccl_device_inline void kernel_volume_step_init(KernelGlobals *kg,
|
||||
ccl_addr_space PathState *state,
|
||||
const float object_step_size,
|
||||
float t,
|
||||
float *step_size,
|
||||
float *step_offset)
|
||||
{
|
||||
const int max_steps = kernel_data.integrator.volume_max_steps;
|
||||
float step = min(object_step_size, t);
|
||||
float step = min(kernel_data.integrator.volume_step_size, t);
|
||||
|
||||
/* compute exact steps in advance for malloc */
|
||||
if (t > max_steps * step) {
|
||||
@@ -216,8 +199,7 @@ ccl_device void kernel_volume_shadow_heterogeneous(KernelGlobals *kg,
|
||||
ccl_addr_space PathState *state,
|
||||
Ray *ray,
|
||||
ShaderData *sd,
|
||||
float3 *throughput,
|
||||
const float object_step_size)
|
||||
float3 *throughput)
|
||||
{
|
||||
float3 tp = *throughput;
|
||||
const float tp_eps = 1e-6f; /* todo: this is likely not the right value */
|
||||
@@ -225,7 +207,7 @@ ccl_device void kernel_volume_shadow_heterogeneous(KernelGlobals *kg,
|
||||
/* prepare for stepping */
|
||||
int max_steps = kernel_data.integrator.volume_max_steps;
|
||||
float step_offset, step_size;
|
||||
kernel_volume_step_init(kg, state, object_step_size, ray->t, &step_size, &step_offset);
|
||||
kernel_volume_step_init(kg, state, ray->t, &step_size, &step_offset);
|
||||
|
||||
/* compute extinction at the start */
|
||||
float t = 0.0f;
|
||||
@@ -282,9 +264,8 @@ ccl_device_noinline void kernel_volume_shadow(KernelGlobals *kg,
|
||||
{
|
||||
shader_setup_from_volume(kg, shadow_sd, ray);
|
||||
|
||||
float step_size = volume_stack_step_size(kg, state->volume_stack);
|
||||
if (step_size != FLT_MAX)
|
||||
kernel_volume_shadow_heterogeneous(kg, state, ray, shadow_sd, throughput, step_size);
|
||||
if (volume_stack_is_heterogeneous(kg, state->volume_stack))
|
||||
kernel_volume_shadow_heterogeneous(kg, state, ray, shadow_sd, throughput);
|
||||
else
|
||||
kernel_volume_shadow_homogeneous(kg, state, ray, shadow_sd, throughput);
|
||||
}
|
||||
@@ -552,8 +533,7 @@ kernel_volume_integrate_heterogeneous_distance(KernelGlobals *kg,
|
||||
Ray *ray,
|
||||
ShaderData *sd,
|
||||
PathRadiance *L,
|
||||
ccl_addr_space float3 *throughput,
|
||||
const float object_step_size)
|
||||
ccl_addr_space float3 *throughput)
|
||||
{
|
||||
float3 tp = *throughput;
|
||||
const float tp_eps = 1e-6f; /* todo: this is likely not the right value */
|
||||
@@ -561,7 +541,7 @@ kernel_volume_integrate_heterogeneous_distance(KernelGlobals *kg,
|
||||
/* prepare for stepping */
|
||||
int max_steps = kernel_data.integrator.volume_max_steps;
|
||||
float step_offset, step_size;
|
||||
kernel_volume_step_init(kg, state, object_step_size, ray->t, &step_size, &step_offset);
|
||||
kernel_volume_step_init(kg, state, ray->t, &step_size, &step_offset);
|
||||
|
||||
/* compute coefficients at the start */
|
||||
float t = 0.0f;
|
||||
@@ -699,13 +679,12 @@ kernel_volume_integrate(KernelGlobals *kg,
|
||||
Ray *ray,
|
||||
PathRadiance *L,
|
||||
ccl_addr_space float3 *throughput,
|
||||
float step_size)
|
||||
bool heterogeneous)
|
||||
{
|
||||
shader_setup_from_volume(kg, sd, ray);
|
||||
|
||||
if (step_size != FLT_MAX)
|
||||
return kernel_volume_integrate_heterogeneous_distance(
|
||||
kg, state, ray, sd, L, throughput, step_size);
|
||||
if (heterogeneous)
|
||||
return kernel_volume_integrate_heterogeneous_distance(kg, state, ray, sd, L, throughput);
|
||||
else
|
||||
return kernel_volume_integrate_homogeneous(kg, state, ray, sd, L, throughput, true);
|
||||
}
|
||||
@@ -756,7 +735,7 @@ ccl_device void kernel_volume_decoupled_record(KernelGlobals *kg,
|
||||
Ray *ray,
|
||||
ShaderData *sd,
|
||||
VolumeSegment *segment,
|
||||
const float object_step_size)
|
||||
bool heterogeneous)
|
||||
{
|
||||
const float tp_eps = 1e-6f; /* todo: this is likely not the right value */
|
||||
|
||||
@@ -764,9 +743,9 @@ ccl_device void kernel_volume_decoupled_record(KernelGlobals *kg,
|
||||
int max_steps;
|
||||
float step_size, step_offset;
|
||||
|
||||
if (object_step_size != FLT_MAX) {
|
||||
if (heterogeneous) {
|
||||
max_steps = kernel_data.integrator.volume_max_steps;
|
||||
kernel_volume_step_init(kg, state, object_step_size, ray->t, &step_size, &step_offset);
|
||||
kernel_volume_step_init(kg, state, ray->t, &step_size, &step_offset);
|
||||
|
||||
# ifdef __KERNEL_CPU__
|
||||
/* NOTE: For the branched path tracing it's possible to have direct
|
||||
|
@@ -72,7 +72,7 @@ void kernel_const_copy(KernelGlobals *kg, const char *name, void *host, size_t s
|
||||
assert(0);
|
||||
}
|
||||
|
||||
void kernel_global_memory_copy(KernelGlobals *kg, const char *name, void *mem, size_t size)
|
||||
void kernel_tex_copy(KernelGlobals *kg, const char *name, void *mem, size_t size)
|
||||
{
|
||||
if (0) {
|
||||
}
|
||||
|
@@ -474,7 +474,7 @@ ccl_device float4 kernel_tex_image_interp(KernelGlobals *kg, int id, float x, fl
|
||||
{
|
||||
const TextureInfo &info = kernel_tex_fetch(__texture_info, id);
|
||||
|
||||
switch (info.data_type) {
|
||||
switch (kernel_tex_type(id)) {
|
||||
case IMAGE_DATA_TYPE_HALF:
|
||||
return TextureInterpolator<half>::interp(info, x, y);
|
||||
case IMAGE_DATA_TYPE_BYTE:
|
||||
@@ -498,34 +498,28 @@ ccl_device float4 kernel_tex_image_interp(KernelGlobals *kg, int id, float x, fl
|
||||
}
|
||||
}
|
||||
|
||||
ccl_device float4 kernel_tex_image_interp_3d(KernelGlobals *kg,
|
||||
int id,
|
||||
float3 P,
|
||||
InterpolationType interp)
|
||||
ccl_device float4 kernel_tex_image_interp_3d(
|
||||
KernelGlobals *kg, int id, float x, float y, float z, InterpolationType interp)
|
||||
{
|
||||
const TextureInfo &info = kernel_tex_fetch(__texture_info, id);
|
||||
|
||||
if (info.use_transform_3d) {
|
||||
P = transform_point(&info.transform_3d, P);
|
||||
}
|
||||
|
||||
switch (info.data_type) {
|
||||
switch (kernel_tex_type(id)) {
|
||||
case IMAGE_DATA_TYPE_HALF:
|
||||
return TextureInterpolator<half>::interp_3d(info, P.x, P.y, P.z, interp);
|
||||
return TextureInterpolator<half>::interp_3d(info, x, y, z, interp);
|
||||
case IMAGE_DATA_TYPE_BYTE:
|
||||
return TextureInterpolator<uchar>::interp_3d(info, P.x, P.y, P.z, interp);
|
||||
return TextureInterpolator<uchar>::interp_3d(info, x, y, z, interp);
|
||||
case IMAGE_DATA_TYPE_USHORT:
|
||||
return TextureInterpolator<uint16_t>::interp_3d(info, P.x, P.y, P.z, interp);
|
||||
return TextureInterpolator<uint16_t>::interp_3d(info, x, y, z, interp);
|
||||
case IMAGE_DATA_TYPE_FLOAT:
|
||||
return TextureInterpolator<float>::interp_3d(info, P.x, P.y, P.z, interp);
|
||||
return TextureInterpolator<float>::interp_3d(info, x, y, z, interp);
|
||||
case IMAGE_DATA_TYPE_HALF4:
|
||||
return TextureInterpolator<half4>::interp_3d(info, P.x, P.y, P.z, interp);
|
||||
return TextureInterpolator<half4>::interp_3d(info, x, y, z, interp);
|
||||
case IMAGE_DATA_TYPE_BYTE4:
|
||||
return TextureInterpolator<uchar4>::interp_3d(info, P.x, P.y, P.z, interp);
|
||||
return TextureInterpolator<uchar4>::interp_3d(info, x, y, z, interp);
|
||||
case IMAGE_DATA_TYPE_USHORT4:
|
||||
return TextureInterpolator<ushort4>::interp_3d(info, P.x, P.y, P.z, interp);
|
||||
return TextureInterpolator<ushort4>::interp_3d(info, x, y, z, interp);
|
||||
case IMAGE_DATA_TYPE_FLOAT4:
|
||||
return TextureInterpolator<float4>::interp_3d(info, P.x, P.y, P.z, interp);
|
||||
return TextureInterpolator<float4>::interp_3d(info, x, y, z, interp);
|
||||
default:
|
||||
assert(0);
|
||||
return make_float4(
|
||||
|
@@ -124,7 +124,7 @@ ccl_device float4 kernel_tex_image_interp(KernelGlobals *kg, int id, float x, fl
|
||||
CUtexObject tex = (CUtexObject)info.data;
|
||||
|
||||
/* float4, byte4, ushort4 and half4 */
|
||||
const int texture_type = info.data_type;
|
||||
const int texture_type = kernel_tex_type(id);
|
||||
if (texture_type == IMAGE_DATA_TYPE_FLOAT4 || texture_type == IMAGE_DATA_TYPE_BYTE4 ||
|
||||
texture_type == IMAGE_DATA_TYPE_HALF4 || texture_type == IMAGE_DATA_TYPE_USHORT4) {
|
||||
if (info.interpolation == INTERPOLATION_CUBIC) {
|
||||
@@ -149,25 +149,14 @@ ccl_device float4 kernel_tex_image_interp(KernelGlobals *kg, int id, float x, fl
|
||||
}
|
||||
}
|
||||
|
||||
ccl_device float4 kernel_tex_image_interp_3d(KernelGlobals *kg,
|
||||
int id,
|
||||
float3 P,
|
||||
InterpolationType interp)
|
||||
ccl_device float4 kernel_tex_image_interp_3d(
|
||||
KernelGlobals *kg, int id, float x, float y, float z, InterpolationType interp)
|
||||
{
|
||||
const TextureInfo &info = kernel_tex_fetch(__texture_info, id);
|
||||
|
||||
if (info.use_transform_3d) {
|
||||
P = transform_point(&info.transform_3d, P);
|
||||
}
|
||||
|
||||
const float x = P.x;
|
||||
const float y = P.y;
|
||||
const float z = P.z;
|
||||
|
||||
CUtexObject tex = (CUtexObject)info.data;
|
||||
uint interpolation = (interp == INTERPOLATION_NONE) ? info.interpolation : interp;
|
||||
|
||||
const int texture_type = info.data_type;
|
||||
const int texture_type = kernel_tex_type(id);
|
||||
if (texture_type == IMAGE_DATA_TYPE_FLOAT4 || texture_type == IMAGE_DATA_TYPE_BYTE4 ||
|
||||
texture_type == IMAGE_DATA_TYPE_HALF4 || texture_type == IMAGE_DATA_TYPE_USHORT4) {
|
||||
if (interpolation == INTERPOLATION_CUBIC) {
|
||||
|
@@ -47,7 +47,7 @@ ccl_device_inline float4 svm_image_texture_read(KernelGlobals *kg,
|
||||
int id,
|
||||
int offset)
|
||||
{
|
||||
const int texture_type = info->data_type;
|
||||
const int texture_type = kernel_tex_type(id);
|
||||
|
||||
/* Float4 */
|
||||
if (texture_type == IMAGE_DATA_TYPE_FLOAT4) {
|
||||
@@ -202,19 +202,11 @@ ccl_device float4 kernel_tex_image_interp(KernelGlobals *kg, int id, float x, fl
|
||||
}
|
||||
}
|
||||
|
||||
ccl_device float4 kernel_tex_image_interp_3d(KernelGlobals *kg, int id, float3 P, int interp)
|
||||
ccl_device float4
|
||||
kernel_tex_image_interp_3d(KernelGlobals *kg, int id, float x, float y, float z, int interp)
|
||||
{
|
||||
const ccl_global TextureInfo *info = kernel_tex_info(kg, id);
|
||||
|
||||
if (info->use_transform_3d) {
|
||||
Transform tfm = info->transform_3d;
|
||||
P = transform_point(&tfm, P);
|
||||
}
|
||||
|
||||
const float x = P.x;
|
||||
const float y = P.y;
|
||||
const float z = P.z;
|
||||
|
||||
if (info->extension == EXTENSION_CLIP) {
|
||||
if (x < 0.0f || y < 0.0f || z < 0.0f || x > 1.0f || y > 1.0f || z > 1.0f) {
|
||||
return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
@@ -33,9 +33,6 @@ set(LIB
|
||||
${LLVM_LIBRARY}
|
||||
)
|
||||
|
||||
# OSL and LLVM are built without RTTI
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${RTTI_DISABLE_FLAGS}")
|
||||
|
||||
include_directories(${INC})
|
||||
include_directories(SYSTEM ${INC_SYS})
|
||||
|
||||
|
@@ -33,12 +33,12 @@
|
||||
#ifndef __OSL_CLOSURES_H__
|
||||
#define __OSL_CLOSURES_H__
|
||||
|
||||
#include "kernel/kernel_types.h"
|
||||
#include "util/util_types.h"
|
||||
#include "kernel/kernel_types.h"
|
||||
|
||||
#include <OSL/genclosure.h>
|
||||
#include <OSL/oslclosure.h>
|
||||
#include <OSL/oslexec.h>
|
||||
#include <OSL/genclosure.h>
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
|
@@ -27,8 +27,8 @@
|
||||
# include "util/util_map.h"
|
||||
# include "util/util_param.h"
|
||||
# include "util/util_thread.h"
|
||||
# include "util/util_unique_ptr.h"
|
||||
# include "util/util_vector.h"
|
||||
# include "util/util_unique_ptr.h"
|
||||
|
||||
# ifndef WIN32
|
||||
using std::isfinite;
|
||||
|
@@ -1222,8 +1222,8 @@ bool OSLRenderServices::texture3d(ustring filename,
|
||||
ShaderData *sd = (ShaderData *)(sg->renderstate);
|
||||
KernelGlobals *kernel_globals = sd->osl_globals;
|
||||
int slot = handle->svm_slot;
|
||||
float3 P_float3 = make_float3(P.x, P.y, P.z);
|
||||
float4 rgba = kernel_tex_image_interp_3d(kernel_globals, slot, P_float3, INTERPOLATION_NONE);
|
||||
float4 rgba = kernel_tex_image_interp_3d(
|
||||
kernel_globals, slot, P.x, P.y, P.z, INTERPOLATION_NONE);
|
||||
|
||||
result[0] = rgba[0];
|
||||
if (nchannels > 1)
|
||||
|
@@ -25,8 +25,8 @@
|
||||
* attributes.
|
||||
*/
|
||||
|
||||
#include <OSL/oslclosure.h>
|
||||
#include <OSL/oslexec.h>
|
||||
#include <OSL/oslclosure.h>
|
||||
|
||||
#ifdef WITH_PTEX
|
||||
class PtexCache;
|
||||
|
@@ -14,8 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "node_color.h"
|
||||
#include "stdcycles.h"
|
||||
#include "node_color.h"
|
||||
|
||||
vector environment_texture_direction_to_equirectangular(vector dir)
|
||||
{
|
||||
|
@@ -14,8 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "node_fresnel.h"
|
||||
#include "stdcycles.h"
|
||||
#include "node_fresnel.h"
|
||||
|
||||
shader node_fresnel(float IOR = 1.45, normal Normal = N, output float Fac = 0.0)
|
||||
{
|
||||
|
@@ -14,8 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "node_fresnel.h"
|
||||
#include "stdcycles.h"
|
||||
#include "node_fresnel.h"
|
||||
|
||||
shader node_glass_bsdf(color Color = 0.8,
|
||||
string distribution = "sharp",
|
||||
|
@@ -14,8 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "node_fresnel.h"
|
||||
#include "stdcycles.h"
|
||||
#include "node_fresnel.h"
|
||||
|
||||
shader node_glossy_bsdf(color Color = 0.8,
|
||||
string distribution = "GGX",
|
||||
|
@@ -14,8 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "node_color.h"
|
||||
#include "stdcycles.h"
|
||||
#include "node_color.h"
|
||||
|
||||
shader node_hsv(float Hue = 0.5,
|
||||
float Saturation = 1.0,
|
||||
|
@@ -14,8 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "node_color.h"
|
||||
#include "stdcycles.h"
|
||||
#include "node_color.h"
|
||||
|
||||
point texco_remap_square(point co)
|
||||
{
|
||||
|
@@ -14,8 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "node_fresnel.h"
|
||||
#include "stdcycles.h"
|
||||
#include "node_fresnel.h"
|
||||
|
||||
shader node_layer_weight(float Blend = 0.5,
|
||||
normal Normal = N,
|
||||
|
@@ -14,8 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "node_math.h"
|
||||
#include "stdcycles.h"
|
||||
#include "node_math.h"
|
||||
|
||||
/* OSL asin, acos, and pow functions are safe by default. */
|
||||
shader node_math(string type = "add",
|
||||
|
@@ -14,8 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "node_color.h"
|
||||
#include "stdcycles.h"
|
||||
#include "node_color.h"
|
||||
|
||||
color node_mix_blend(float t, color col1, color col2)
|
||||
{
|
||||
|
@@ -14,8 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "node_noise.h"
|
||||
#include "stdcycles.h"
|
||||
#include "node_noise.h"
|
||||
#include "vector2.h"
|
||||
#include "vector4.h"
|
||||
|
||||
|
@@ -14,10 +14,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "node_noise.h"
|
||||
#include "stdcycles.h"
|
||||
#include "vector2.h"
|
||||
#include "vector4.h"
|
||||
#include "node_noise.h"
|
||||
|
||||
#define vector3 point
|
||||
|
||||
|
@@ -14,8 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "node_fresnel.h"
|
||||
#include "stdcycles.h"
|
||||
#include "node_fresnel.h"
|
||||
|
||||
shader node_principled_bsdf(string distribution = "Multiscatter GGX",
|
||||
string subsurface_method = "burley",
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user