Cycles: add Optix device backend
This uses hardware-accelerated raytracing on NVIDIA RTX graphics cards. It is still currently experimental. Most features are supported, but a few are still missing like baking, branched path tracing and using CPU memory. https://wiki.blender.org/wiki/Reference/Release_Notes/2.81/Cycles#NVIDIA_RTX For building with Optix support, the Optix SDK must be installed. See here for build instructions: https://wiki.blender.org/wiki/Building_Blender/CUDA Differential Revision: https://developer.blender.org/D5363
This commit is contained in:
parent
53932f1f06
commit
a2b52dc571
|
@ -426,6 +426,7 @@ mark_as_advanced(WITH_CYCLES_DEBUG)
|
|||
mark_as_advanced(WITH_CYCLES_NATIVE_ONLY)
|
||||
|
||||
option(WITH_CYCLES_DEVICE_CUDA "Enable Cycles CUDA compute support" ON)
|
||||
option(WITH_CYCLES_DEVICE_OPTIX "Enable Cycles OptiX support" OFF)
|
||||
option(WITH_CYCLES_DEVICE_OPENCL "Enable Cycles OpenCL compute support" ON)
|
||||
option(WITH_CYCLES_NETWORK "Enable Cycles compute over network support (EXPERIMENTAL and unfinished)" OFF)
|
||||
mark_as_advanced(WITH_CYCLES_DEVICE_CUDA)
|
||||
|
|
|
@ -34,6 +34,9 @@ def get_cmake_options(builder):
|
|||
elif builder.platform == 'linux':
|
||||
config_file = "build_files/buildbot/config/blender_linux.cmake"
|
||||
|
||||
optix_sdk_dir = os.path.join(builder.blender_dir, '..', '..', 'NVIDIA-Optix-SDK')
|
||||
options.append('-DOPTIX_ROOT_DIR:PATH=' + optix_sdk_dir)
|
||||
|
||||
options.append("-C" + os.path.join(builder.blender_dir, config_file))
|
||||
options.append("-DCMAKE_INSTALL_PREFIX=%s" % (builder.install_dir))
|
||||
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
# - Find OptiX library
|
||||
# Find the native OptiX includes and library
|
||||
# This module defines
|
||||
# OPTIX_INCLUDE_DIRS, where to find optix.h, Set when
|
||||
# OPTIX_INCLUDE_DIR is found.
|
||||
# OPTIX_ROOT_DIR, The base directory to search for OptiX.
|
||||
# This can also be an environment variable.
|
||||
# OPTIX_FOUND, If false, do not try to use OptiX.
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2019 Blender Foundation.
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
|
||||
# If OPTIX_ROOT_DIR was defined in the environment, use it.
|
||||
IF(NOT OPTIX_ROOT_DIR AND NOT $ENV{OPTIX_ROOT_DIR} STREQUAL "")
|
||||
SET(OPTIX_ROOT_DIR $ENV{OPTIX_ROOT_DIR})
|
||||
ENDIF()
|
||||
|
||||
SET(_optix_SEARCH_DIRS
|
||||
${OPTIX_ROOT_DIR}
|
||||
"$ENV{PROGRAMDATA}/NVIDIA Corporation/OptiX SDK 7.0.0"
|
||||
/usr/local
|
||||
/sw # Fink
|
||||
/opt/local # DarwinPorts
|
||||
)
|
||||
|
||||
FIND_PATH(OPTIX_INCLUDE_DIR
|
||||
NAMES
|
||||
optix.h
|
||||
HINTS
|
||||
${_optix_SEARCH_DIRS}
|
||||
PATH_SUFFIXES
|
||||
include
|
||||
)
|
||||
|
||||
# handle the QUIETLY and REQUIRED arguments and set OPTIX_FOUND to TRUE if
|
||||
# all listed variables are TRUE
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(OptiX DEFAULT_MSG
|
||||
OPTIX_INCLUDE_DIR)
|
||||
|
||||
IF(OPTIX_FOUND)
|
||||
SET(OPTIX_INCLUDE_DIRS ${OPTIX_INCLUDE_DIR})
|
||||
ENDIF(OPTIX_FOUND)
|
||||
|
||||
MARK_AS_ADVANCED(
|
||||
OPTIX_INCLUDE_DIR
|
||||
)
|
||||
|
||||
UNSET(_optix_SEARCH_DIRS)
|
|
@ -17,6 +17,7 @@ set(WITH_CODEC_FFMPEG OFF CACHE BOOL "" FORCE)
|
|||
set(WITH_CODEC_SNDFILE OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_CYCLES OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_CYCLES_OSL OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_CYCLES_DEVICE_OPTIX OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_DRACO OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_FFTW3 OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_LIBMV OFF CACHE BOOL "" FORCE)
|
||||
|
|
|
@ -57,6 +57,7 @@ set(WITH_MEM_JEMALLOC ON CACHE BOOL "" FORCE)
|
|||
set(WITH_CYCLES_CUDA_BINARIES ON CACHE BOOL "" FORCE)
|
||||
set(WITH_CYCLES_CUBIN_COMPILER OFF CACHE BOOL "" FORCE)
|
||||
set(CYCLES_CUDA_BINARIES_ARCH sm_30;sm_35;sm_37;sm_50;sm_52;sm_60;sm_61;sm_70;sm_75 CACHE STRING "" FORCE)
|
||||
set(WITH_CYCLES_DEVICE_OPTIX ON CACHE BOOL "" FORCE)
|
||||
|
||||
# platform dependent options
|
||||
if(UNIX AND NOT APPLE)
|
||||
|
|
|
@ -219,6 +219,24 @@ if(WITH_CYCLES_OSL)
|
|||
)
|
||||
endif()
|
||||
|
||||
if(WITH_CYCLES_DEVICE_OPTIX)
|
||||
find_package(OptiX)
|
||||
|
||||
if(OPTIX_FOUND)
|
||||
add_definitions(-DWITH_OPTIX)
|
||||
include_directories(
|
||||
SYSTEM
|
||||
${OPTIX_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
# Need pre-compiled CUDA binaries in the OptiX device
|
||||
set(WITH_CYCLES_CUDA_BINARIES ON)
|
||||
else()
|
||||
message(STATUS "Optix not found, disabling it from Cycles")
|
||||
set(WITH_CYCLES_DEVICE_OPTIX OFF)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WITH_CYCLES_EMBREE)
|
||||
add_definitions(-DWITH_EMBREE)
|
||||
add_definitions(-DEMBREE_STATIC_LIB)
|
||||
|
|
|
@ -137,6 +137,7 @@ enum_world_mis = (
|
|||
enum_device_type = (
|
||||
('CPU', "CPU", "CPU", 0),
|
||||
('CUDA', "CUDA", "CUDA", 1),
|
||||
('OPTIX', "OptiX", "OptiX", 3),
|
||||
('OPENCL', "OpenCL", "OpenCL", 2)
|
||||
)
|
||||
|
||||
|
@ -740,6 +741,8 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
|
|||
debug_use_cuda_adaptive_compile: BoolProperty(name="Adaptive Compile", default=False)
|
||||
debug_use_cuda_split_kernel: BoolProperty(name="Split Kernel", default=False)
|
||||
|
||||
debug_optix_cuda_streams: IntProperty(name="CUDA Streams", default=1, min=1)
|
||||
|
||||
debug_opencl_kernel_type: EnumProperty(
|
||||
name="OpenCL Kernel Type",
|
||||
default='DEFAULT',
|
||||
|
@ -1400,10 +1403,12 @@ class CyclesPreferences(bpy.types.AddonPreferences):
|
|||
|
||||
def get_device_types(self, context):
|
||||
import _cycles
|
||||
has_cuda, has_opencl = _cycles.get_device_types()
|
||||
has_cuda, has_optix, has_opencl = _cycles.get_device_types()
|
||||
list = [('NONE', "None", "Don't use compute device", 0)]
|
||||
if has_cuda:
|
||||
list.append(('CUDA', "CUDA", "Use CUDA for GPU acceleration", 1))
|
||||
if has_optix:
|
||||
list.append(('OPTIX', "OptiX", "Use OptiX for GPU acceleration", 3))
|
||||
if has_opencl:
|
||||
list.append(('OPENCL', "OpenCL", "Use OpenCL for GPU acceleration", 2))
|
||||
return list
|
||||
|
@ -1424,7 +1429,7 @@ class CyclesPreferences(bpy.types.AddonPreferences):
|
|||
|
||||
def update_device_entries(self, device_list):
|
||||
for device in device_list:
|
||||
if not device[1] in {'CUDA', 'OPENCL', 'CPU'}:
|
||||
if not device[1] in {'CUDA', 'OPTIX', 'OPENCL', 'CPU'}:
|
||||
continue
|
||||
# Try to find existing Device entry
|
||||
entry = self.find_existing_device_entry(device)
|
||||
|
@ -1439,8 +1444,8 @@ class CyclesPreferences(bpy.types.AddonPreferences):
|
|||
# Update name in case it changed
|
||||
entry.name = device[0]
|
||||
|
||||
# Gets all devices types by default.
|
||||
def get_devices(self, compute_device_type=''):
|
||||
# Gets all devices types for a compute device type.
|
||||
def get_devices_for_type(self, compute_device_type):
|
||||
import _cycles
|
||||
# Layout of the device tuples: (Name, Type, Persistent ID)
|
||||
device_list = _cycles.available_devices(compute_device_type)
|
||||
|
@ -1449,20 +1454,23 @@ class CyclesPreferences(bpy.types.AddonPreferences):
|
|||
# hold pointers to a resized array.
|
||||
self.update_device_entries(device_list)
|
||||
# Sort entries into lists
|
||||
cuda_devices = []
|
||||
opencl_devices = []
|
||||
devices = []
|
||||
cpu_devices = []
|
||||
for device in device_list:
|
||||
entry = self.find_existing_device_entry(device)
|
||||
if entry.type == 'CUDA':
|
||||
cuda_devices.append(entry)
|
||||
elif entry.type == 'OPENCL':
|
||||
opencl_devices.append(entry)
|
||||
if entry.type == compute_device_type:
|
||||
devices.append(entry)
|
||||
elif entry.type == 'CPU':
|
||||
cpu_devices.append(entry)
|
||||
# Extend all GPU devices with CPU.
|
||||
cuda_devices.extend(cpu_devices)
|
||||
opencl_devices.extend(cpu_devices)
|
||||
if compute_device_type in ('CUDA', 'OPENCL'):
|
||||
devices.extend(cpu_devices)
|
||||
return devices
|
||||
|
||||
# For backwards compatibility, only has CUDA and OpenCL.
|
||||
def get_devices(self, compute_device_type=''):
|
||||
cuda_devices = self.get_devices_for_type('CUDA')
|
||||
opencl_devices = self.get_devices_for_type('OPENCL')
|
||||
return cuda_devices, opencl_devices
|
||||
|
||||
def get_num_gpu_devices(self):
|
||||
|
@ -1498,16 +1506,24 @@ class CyclesPreferences(bpy.types.AddonPreferences):
|
|||
for device in devices:
|
||||
box.prop(device, "use", text=device.name)
|
||||
|
||||
if device_type == 'OPTIX':
|
||||
col = box.column(align=True)
|
||||
col.label(text="OptiX support is experimental", icon='INFO')
|
||||
col.label(text="Not all Cycles features are supported yet", icon='BLANK1')
|
||||
|
||||
|
||||
def draw_impl(self, layout, context):
|
||||
row = layout.row()
|
||||
row.prop(self, "compute_device_type", expand=True)
|
||||
|
||||
cuda_devices, opencl_devices = self.get_devices(self.compute_device_type)
|
||||
devices = self.get_devices_for_type(self.compute_device_type)
|
||||
row = layout.row()
|
||||
if self.compute_device_type == 'CUDA':
|
||||
self._draw_devices(row, 'CUDA', cuda_devices)
|
||||
self._draw_devices(row, 'CUDA', devices)
|
||||
elif self.compute_device_type == 'OPTIX':
|
||||
self._draw_devices(row, 'OPTIX', devices)
|
||||
elif self.compute_device_type == 'OPENCL':
|
||||
self._draw_devices(row, 'OPENCL', opencl_devices)
|
||||
self._draw_devices(row, 'OPENCL', devices)
|
||||
|
||||
def draw(self, context):
|
||||
self.draw_impl(self.layout, context)
|
||||
|
|
|
@ -88,10 +88,16 @@ def use_cuda(context):
|
|||
return (get_device_type(context) == 'CUDA' and cscene.device == 'GPU')
|
||||
|
||||
|
||||
def use_optix(context):
|
||||
cscene = context.scene.cycles
|
||||
|
||||
return (get_device_type(context) == 'OPTIX' and cscene.device == 'GPU')
|
||||
|
||||
|
||||
def use_branched_path(context):
|
||||
cscene = context.scene.cycles
|
||||
|
||||
return (cscene.progressive == 'BRANCHED_PATH')
|
||||
return (cscene.progressive == 'BRANCHED_PATH' and not use_optix(context))
|
||||
|
||||
|
||||
def use_sample_all_lights(context):
|
||||
|
@ -168,7 +174,8 @@ class CYCLES_RENDER_PT_sampling(CyclesButtonsPanel, Panel):
|
|||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
||||
|
||||
layout.prop(cscene, "progressive")
|
||||
if not use_optix(context):
|
||||
layout.prop(cscene, "progressive")
|
||||
|
||||
if cscene.progressive == 'PATH' or use_branched_path(context) is False:
|
||||
col = layout.column(align=True)
|
||||
|
@ -1763,6 +1770,10 @@ class CYCLES_RENDER_PT_bake(CyclesButtonsPanel, Panel):
|
|||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'CYCLES'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return not use_optix(context)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.use_property_split = True
|
||||
|
@ -1947,7 +1958,13 @@ class CYCLES_RENDER_PT_debug(CyclesButtonsPanel, Panel):
|
|||
col.separator()
|
||||
|
||||
col = layout.column()
|
||||
col.label(text='OpenCL Flags:')
|
||||
col.label(text="OptiX Flags:")
|
||||
col.prop(cscene, "debug_optix_cuda_streams")
|
||||
|
||||
col.separator()
|
||||
|
||||
col = layout.column()
|
||||
col.label(text="OpenCL Flags:")
|
||||
col.prop(cscene, "debug_opencl_device_type", text="Device")
|
||||
col.prop(cscene, "debug_use_opencl_debug", text="Debug")
|
||||
col.prop(cscene, "debug_opencl_mem_limit")
|
||||
|
|
|
@ -61,7 +61,8 @@ DeviceInfo blender_device_info(BL::Preferences &b_preferences, BL::Scene &b_scen
|
|||
COMPUTE_DEVICE_CPU = 0,
|
||||
COMPUTE_DEVICE_CUDA = 1,
|
||||
COMPUTE_DEVICE_OPENCL = 2,
|
||||
COMPUTE_DEVICE_NUM = 3,
|
||||
COMPUTE_DEVICE_OPTIX = 3,
|
||||
COMPUTE_DEVICE_NUM = 4,
|
||||
};
|
||||
|
||||
ComputeDevice compute_device = (ComputeDevice)get_enum(
|
||||
|
@ -73,6 +74,10 @@ DeviceInfo blender_device_info(BL::Preferences &b_preferences, BL::Scene &b_scen
|
|||
if (compute_device == COMPUTE_DEVICE_CUDA) {
|
||||
mask |= DEVICE_MASK_CUDA;
|
||||
}
|
||||
else if (compute_device == COMPUTE_DEVICE_OPTIX) {
|
||||
/* Cannot use CPU and OptiX device at the same time right now, so replace mask. */
|
||||
mask = DEVICE_MASK_OPTIX;
|
||||
}
|
||||
else if (compute_device == COMPUTE_DEVICE_OPENCL) {
|
||||
mask |= DEVICE_MASK_OPENCL;
|
||||
}
|
||||
|
|
|
@ -81,6 +81,8 @@ bool debug_flags_sync_from_scene(BL::Scene b_scene)
|
|||
/* Synchronize CUDA flags. */
|
||||
flags.cuda.adaptive_compile = get_boolean(cscene, "debug_use_cuda_adaptive_compile");
|
||||
flags.cuda.split_kernel = get_boolean(cscene, "debug_use_cuda_split_kernel");
|
||||
/* Synchronize OptiX flags. */
|
||||
flags.optix.cuda_streams = get_int(cscene, "debug_optix_cuda_streams");
|
||||
/* Synchronize OpenCL device type. */
|
||||
switch (get_enum(cscene, "debug_opencl_device_type")) {
|
||||
case 0:
|
||||
|
@ -960,14 +962,16 @@ static PyObject *enable_print_stats_func(PyObject * /*self*/, PyObject * /*args*
|
|||
static PyObject *get_device_types_func(PyObject * /*self*/, PyObject * /*args*/)
|
||||
{
|
||||
vector<DeviceType> device_types = Device::available_types();
|
||||
bool has_cuda = false, has_opencl = false;
|
||||
bool has_cuda = false, has_optix = false, has_opencl = false;
|
||||
foreach (DeviceType device_type, device_types) {
|
||||
has_cuda |= (device_type == DEVICE_CUDA);
|
||||
has_optix |= (device_type == DEVICE_OPTIX);
|
||||
has_opencl |= (device_type == DEVICE_OPENCL);
|
||||
}
|
||||
PyObject *list = PyTuple_New(2);
|
||||
PyObject *list = PyTuple_New(3);
|
||||
PyTuple_SET_ITEM(list, 0, PyBool_FromLong(has_cuda));
|
||||
PyTuple_SET_ITEM(list, 1, PyBool_FromLong(has_opencl));
|
||||
PyTuple_SET_ITEM(list, 1, PyBool_FromLong(has_optix));
|
||||
PyTuple_SET_ITEM(list, 2, PyBool_FromLong(has_opencl));
|
||||
return list;
|
||||
}
|
||||
|
||||
|
|
|
@ -758,7 +758,7 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine &b_engine,
|
|||
preview_samples = preview_samples * preview_samples;
|
||||
}
|
||||
|
||||
if (get_enum(cscene, "progressive") == 0) {
|
||||
if (get_enum(cscene, "progressive") == 0 && (params.device.type != DEVICE_OPTIX)) {
|
||||
if (background) {
|
||||
params.samples = aa_samples;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ set(SRC
|
|||
bvh_build.cpp
|
||||
bvh_embree.cpp
|
||||
bvh_node.cpp
|
||||
bvh_optix.cpp
|
||||
bvh_sort.cpp
|
||||
bvh_split.cpp
|
||||
bvh_unaligned.cpp
|
||||
|
@ -29,6 +30,7 @@ set(SRC_HEADERS
|
|||
bvh_build.h
|
||||
bvh_embree.h
|
||||
bvh_node.h
|
||||
bvh_optix.h
|
||||
bvh_params.h
|
||||
bvh_sort.h
|
||||
bvh_split.h
|
||||
|
|
|
@ -26,6 +26,9 @@
|
|||
#include "bvh/bvh_build.h"
|
||||
#include "bvh/bvh_node.h"
|
||||
|
||||
#ifdef WITH_OPTIX
|
||||
# include "bvh/bvh_optix.h"
|
||||
#endif
|
||||
#ifdef WITH_EMBREE
|
||||
# include "bvh/bvh_embree.h"
|
||||
#endif
|
||||
|
@ -51,6 +54,8 @@ const char *bvh_layout_name(BVHLayout layout)
|
|||
return "NONE";
|
||||
case BVH_LAYOUT_EMBREE:
|
||||
return "EMBREE";
|
||||
case BVH_LAYOUT_OPTIX:
|
||||
return "OPTIX";
|
||||
case BVH_LAYOUT_ALL:
|
||||
return "ALL";
|
||||
}
|
||||
|
@ -115,6 +120,12 @@ BVH *BVH::create(const BVHParams ¶ms,
|
|||
return new BVHEmbree(params, meshes, objects);
|
||||
#else
|
||||
break;
|
||||
#endif
|
||||
case BVH_LAYOUT_OPTIX:
|
||||
#ifdef WITH_OPTIX
|
||||
return new BVHOptiX(params, meshes, objects);
|
||||
#else
|
||||
break;
|
||||
#endif
|
||||
case BVH_LAYOUT_NONE:
|
||||
case BVH_LAYOUT_ALL:
|
||||
|
|
|
@ -0,0 +1,215 @@
|
|||
/*
|
||||
* Copyright 2019, NVIDIA Corporation.
|
||||
* Copyright 2019, Blender Foundation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifdef WITH_OPTIX
|
||||
|
||||
# include "bvh/bvh_optix.h"
|
||||
# include "render/mesh.h"
|
||||
# include "render/object.h"
|
||||
# include "util/util_logging.h"
|
||||
# include "util/util_progress.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
BVHOptiX::BVHOptiX(const BVHParams ¶ms_,
|
||||
const vector<Mesh *> &meshes_,
|
||||
const vector<Object *> &objects_)
|
||||
: BVH(params_, meshes_, objects_)
|
||||
{
|
||||
}
|
||||
|
||||
BVHOptiX::~BVHOptiX()
|
||||
{
|
||||
}
|
||||
|
||||
void BVHOptiX::build(Progress &, Stats *)
|
||||
{
|
||||
if (params.top_level)
|
||||
pack_tlas();
|
||||
else
|
||||
pack_blas();
|
||||
}
|
||||
|
||||
void BVHOptiX::copy_to_device(Progress &progress, DeviceScene *dscene)
|
||||
{
|
||||
progress.set_status("Updating Scene BVH", "Building OptiX acceleration structure");
|
||||
|
||||
Device *const device = dscene->bvh_nodes.device;
|
||||
if (!device->build_optix_bvh(this, dscene->bvh_nodes))
|
||||
progress.set_error("Failed to build OptiX acceleration structure");
|
||||
}
|
||||
|
||||
void BVHOptiX::pack_blas()
|
||||
{
|
||||
// Bottom-level BVH can contain multiple primitive types, so merge them:
|
||||
assert(meshes.size() == 1 && objects.size() == 1); // These are build per-mesh
|
||||
Mesh *const mesh = meshes[0];
|
||||
|
||||
if (params.primitive_mask & PRIMITIVE_ALL_CURVE && mesh->num_curves() > 0) {
|
||||
const size_t num_curves = mesh->num_curves();
|
||||
const size_t num_segments = mesh->num_segments();
|
||||
pack.prim_type.reserve(pack.prim_type.size() + num_segments);
|
||||
pack.prim_index.reserve(pack.prim_index.size() + num_segments);
|
||||
pack.prim_object.reserve(pack.prim_object.size() + num_segments);
|
||||
// 'pack.prim_time' is only used in geom_curve_intersect.h
|
||||
// It is not needed because of OPTIX_MOTION_FLAG_[START|END]_VANISH
|
||||
|
||||
uint type = PRIMITIVE_CURVE;
|
||||
if (mesh->use_motion_blur && mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION))
|
||||
type = PRIMITIVE_MOTION_CURVE;
|
||||
|
||||
for (size_t j = 0; j < num_curves; ++j) {
|
||||
const Mesh::Curve curve = mesh->get_curve(j);
|
||||
for (size_t k = 0; k < curve.num_segments(); ++k) {
|
||||
pack.prim_type.push_back_reserved(PRIMITIVE_PACK_SEGMENT(type, k));
|
||||
// Each curve segment points back to its curve index
|
||||
pack.prim_index.push_back_reserved(j);
|
||||
pack.prim_object.push_back_reserved(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (params.primitive_mask & PRIMITIVE_ALL_TRIANGLE && mesh->num_triangles() > 0) {
|
||||
const size_t num_triangles = mesh->num_triangles();
|
||||
pack.prim_type.reserve(pack.prim_type.size() + num_triangles);
|
||||
pack.prim_index.reserve(pack.prim_index.size() + num_triangles);
|
||||
pack.prim_object.reserve(pack.prim_object.size() + num_triangles);
|
||||
|
||||
uint type = PRIMITIVE_TRIANGLE;
|
||||
if (mesh->use_motion_blur && mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION))
|
||||
type = PRIMITIVE_MOTION_TRIANGLE;
|
||||
|
||||
for (size_t k = 0; k < num_triangles; ++k) {
|
||||
pack.prim_type.push_back_reserved(type);
|
||||
pack.prim_index.push_back_reserved(k);
|
||||
pack.prim_object.push_back_reserved(0);
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize visibility to zero and later update it during top-level build
|
||||
uint prev_visibility = objects[0]->visibility;
|
||||
objects[0]->visibility = 0;
|
||||
|
||||
// Update 'pack.prim_tri_index', 'pack.prim_tri_verts' and 'pack.prim_visibility'
|
||||
pack_primitives();
|
||||
|
||||
// Reset visibility after packing
|
||||
objects[0]->visibility = prev_visibility;
|
||||
}
|
||||
|
||||
void BVHOptiX::pack_tlas()
|
||||
{
|
||||
// Calculate total packed size
|
||||
size_t prim_index_size = 0;
|
||||
size_t prim_tri_verts_size = 0;
|
||||
foreach (Mesh *mesh, meshes) {
|
||||
BVH *const bvh = mesh->bvh;
|
||||
prim_index_size += bvh->pack.prim_index.size();
|
||||
prim_tri_verts_size += bvh->pack.prim_tri_verts.size();
|
||||
}
|
||||
|
||||
if (prim_index_size == 0)
|
||||
return; // Abort right away if this is an empty BVH
|
||||
|
||||
size_t pack_offset = 0;
|
||||
size_t pack_verts_offset = 0;
|
||||
|
||||
pack.prim_type.resize(prim_index_size);
|
||||
int *pack_prim_type = pack.prim_type.data();
|
||||
pack.prim_index.resize(prim_index_size);
|
||||
int *pack_prim_index = pack.prim_index.data();
|
||||
pack.prim_object.resize(prim_index_size);
|
||||
int *pack_prim_object = pack.prim_object.data();
|
||||
pack.prim_visibility.resize(prim_index_size);
|
||||
uint *pack_prim_visibility = pack.prim_visibility.data();
|
||||
pack.prim_tri_index.resize(prim_index_size);
|
||||
uint *pack_prim_tri_index = pack.prim_tri_index.data();
|
||||
pack.prim_tri_verts.resize(prim_tri_verts_size);
|
||||
float4 *pack_prim_tri_verts = pack.prim_tri_verts.data();
|
||||
|
||||
// Top-level BVH should only contain instances, see 'Mesh::need_build_bvh'
|
||||
// Iterate over scene mesh list instead of objects, since the 'prim_offset' is calculated based
|
||||
// on that list, which may be ordered differently from the object list.
|
||||
foreach (Mesh *mesh, meshes) {
|
||||
PackedBVH &bvh_pack = mesh->bvh->pack;
|
||||
int mesh_tri_offset = mesh->tri_offset;
|
||||
int mesh_curve_offset = mesh->curve_offset;
|
||||
|
||||
// Merge primitive, object and triangle indexes
|
||||
if (!bvh_pack.prim_index.empty()) {
|
||||
int *bvh_prim_type = &bvh_pack.prim_type[0];
|
||||
int *bvh_prim_index = &bvh_pack.prim_index[0];
|
||||
uint *bvh_prim_tri_index = &bvh_pack.prim_tri_index[0];
|
||||
uint *bvh_prim_visibility = &bvh_pack.prim_visibility[0];
|
||||
|
||||
for (size_t i = 0; i < bvh_pack.prim_index.size(); i++, pack_offset++) {
|
||||
if (bvh_pack.prim_type[i] & PRIMITIVE_ALL_CURVE) {
|
||||
pack_prim_index[pack_offset] = bvh_prim_index[i] + mesh_curve_offset;
|
||||
pack_prim_tri_index[pack_offset] = -1;
|
||||
}
|
||||
else {
|
||||
pack_prim_index[pack_offset] = bvh_prim_index[i] + mesh_tri_offset;
|
||||
pack_prim_tri_index[pack_offset] = bvh_prim_tri_index[i] + pack_verts_offset;
|
||||
}
|
||||
|
||||
pack_prim_type[pack_offset] = bvh_prim_type[i];
|
||||
pack_prim_object[pack_offset] = 0; // Unused for instanced meshes
|
||||
pack_prim_visibility[pack_offset] = bvh_prim_visibility[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Merge triangle vertex data
|
||||
if (!bvh_pack.prim_tri_verts.empty()) {
|
||||
const size_t prim_tri_size = bvh_pack.prim_tri_verts.size();
|
||||
memcpy(pack_prim_tri_verts + pack_verts_offset,
|
||||
bvh_pack.prim_tri_verts.data(),
|
||||
prim_tri_size * sizeof(float4));
|
||||
pack_verts_offset += prim_tri_size;
|
||||
}
|
||||
}
|
||||
|
||||
// Merge visibility flags of all objects and fix object indices for non-instanced meshes
|
||||
foreach (Object *ob, objects) {
|
||||
Mesh *const mesh = ob->mesh;
|
||||
for (size_t i = 0; i < mesh->num_primitives(); ++i) {
|
||||
if (!ob->mesh->is_instanced()) {
|
||||
assert(pack.prim_object[mesh->prim_offset + i] == 0);
|
||||
pack.prim_object[mesh->prim_offset + i] = ob->get_device_index();
|
||||
}
|
||||
pack.prim_visibility[mesh->prim_offset + i] |= ob->visibility_for_tracing();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BVHOptiX::pack_nodes(const BVHNode *)
|
||||
{
|
||||
}
|
||||
|
||||
void BVHOptiX::refit_nodes()
|
||||
{
|
||||
// TODO(pmours): Implement?
|
||||
VLOG(1) << "Refit is not yet implemented for OptiX BVH.";
|
||||
}
|
||||
|
||||
BVHNode *BVHOptiX::widen_children_nodes(const BVHNode *)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
#endif /* WITH_OPTIX */
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright 2019, NVIDIA Corporation.
|
||||
* Copyright 2019, 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 __BVH_OPTIX_H__
|
||||
#define __BVH_OPTIX_H__
|
||||
|
||||
#ifdef WITH_OPTIX
|
||||
|
||||
# include "bvh/bvh.h"
|
||||
# include "bvh/bvh_params.h"
|
||||
# include "device/device_memory.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
class BVHOptiX : public BVH {
|
||||
friend class BVH;
|
||||
|
||||
public:
|
||||
BVHOptiX(const BVHParams ¶ms, const vector<Mesh *> &meshes, const vector<Object *> &objects);
|
||||
virtual ~BVHOptiX();
|
||||
|
||||
virtual void build(Progress &progress, Stats *) override;
|
||||
virtual void copy_to_device(Progress &progress, DeviceScene *dscene) override;
|
||||
|
||||
private:
|
||||
void pack_blas();
|
||||
void pack_tlas();
|
||||
|
||||
virtual void pack_nodes(const BVHNode *) override;
|
||||
virtual void refit_nodes() override;
|
||||
|
||||
virtual BVHNode *widen_children_nodes(const BVHNode *) override;
|
||||
};
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
#endif /* WITH_OPTIX */
|
||||
|
||||
#endif /* __BVH_OPTIX_H__ */
|
|
@ -29,6 +29,7 @@ set(SRC
|
|||
device_memory.cpp
|
||||
device_multi.cpp
|
||||
device_opencl.cpp
|
||||
device_optix.cpp
|
||||
device_split_kernel.cpp
|
||||
device_task.cpp
|
||||
)
|
||||
|
@ -85,6 +86,9 @@ endif()
|
|||
if(WITH_CYCLES_DEVICE_CUDA)
|
||||
add_definitions(-DWITH_CUDA)
|
||||
endif()
|
||||
if(WITH_CYCLES_DEVICE_OPTIX)
|
||||
add_definitions(-DWITH_OPTIX)
|
||||
endif()
|
||||
if(WITH_CYCLES_DEVICE_MULTI)
|
||||
add_definitions(-DWITH_MULTI)
|
||||
endif()
|
||||
|
|
|
@ -38,6 +38,7 @@ bool Device::need_devices_update = true;
|
|||
thread_mutex Device::device_mutex;
|
||||
vector<DeviceInfo> Device::opencl_devices;
|
||||
vector<DeviceInfo> Device::cuda_devices;
|
||||
vector<DeviceInfo> Device::optix_devices;
|
||||
vector<DeviceInfo> Device::cpu_devices;
|
||||
vector<DeviceInfo> Device::network_devices;
|
||||
uint Device::devices_initialized_mask = 0;
|
||||
|
@ -379,6 +380,14 @@ Device *Device::create(DeviceInfo &info, Stats &stats, Profiler &profiler, bool
|
|||
device = NULL;
|
||||
break;
|
||||
#endif
|
||||
#ifdef WITH_OPTIX
|
||||
case DEVICE_OPTIX:
|
||||
if (device_optix_init())
|
||||
device = device_optix_create(info, stats, profiler, background);
|
||||
else
|
||||
device = NULL;
|
||||
break;
|
||||
#endif
|
||||
#ifdef WITH_MULTI
|
||||
case DEVICE_MULTI:
|
||||
device = device_multi_create(info, stats, profiler, background);
|
||||
|
@ -410,6 +419,8 @@ DeviceType Device::type_from_string(const char *name)
|
|||
return DEVICE_CPU;
|
||||
else if (strcmp(name, "CUDA") == 0)
|
||||
return DEVICE_CUDA;
|
||||
else if (strcmp(name, "OPTIX") == 0)
|
||||
return DEVICE_OPTIX;
|
||||
else if (strcmp(name, "OPENCL") == 0)
|
||||
return DEVICE_OPENCL;
|
||||
else if (strcmp(name, "NETWORK") == 0)
|
||||
|
@ -426,6 +437,8 @@ string Device::string_from_type(DeviceType type)
|
|||
return "CPU";
|
||||
else if (type == DEVICE_CUDA)
|
||||
return "CUDA";
|
||||
else if (type == DEVICE_OPTIX)
|
||||
return "OPTIX";
|
||||
else if (type == DEVICE_OPENCL)
|
||||
return "OPENCL";
|
||||
else if (type == DEVICE_NETWORK)
|
||||
|
@ -443,6 +456,9 @@ vector<DeviceType> Device::available_types()
|
|||
#ifdef WITH_CUDA
|
||||
types.push_back(DEVICE_CUDA);
|
||||
#endif
|
||||
#ifdef WITH_OPTIX
|
||||
types.push_back(DEVICE_OPTIX);
|
||||
#endif
|
||||
#ifdef WITH_OPENCL
|
||||
types.push_back(DEVICE_OPENCL);
|
||||
#endif
|
||||
|
@ -488,6 +504,20 @@ vector<DeviceInfo> Device::available_devices(uint mask)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef WITH_OPTIX
|
||||
if (mask & DEVICE_MASK_OPTIX) {
|
||||
if (!(devices_initialized_mask & DEVICE_MASK_OPTIX)) {
|
||||
if (device_optix_init()) {
|
||||
device_optix_info(optix_devices);
|
||||
}
|
||||
devices_initialized_mask |= DEVICE_MASK_OPTIX;
|
||||
}
|
||||
foreach (DeviceInfo &info, optix_devices) {
|
||||
devices.push_back(info);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mask & DEVICE_MASK_CPU) {
|
||||
if (!(devices_initialized_mask & DEVICE_MASK_CPU)) {
|
||||
device_cpu_info(cpu_devices);
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
class BVH;
|
||||
class Progress;
|
||||
class RenderTile;
|
||||
|
||||
|
@ -45,13 +46,15 @@ enum DeviceType {
|
|||
DEVICE_OPENCL,
|
||||
DEVICE_CUDA,
|
||||
DEVICE_NETWORK,
|
||||
DEVICE_MULTI
|
||||
DEVICE_MULTI,
|
||||
DEVICE_OPTIX,
|
||||
};
|
||||
|
||||
enum DeviceTypeMask {
|
||||
DEVICE_MASK_CPU = (1 << DEVICE_CPU),
|
||||
DEVICE_MASK_OPENCL = (1 << DEVICE_OPENCL),
|
||||
DEVICE_MASK_CUDA = (1 << DEVICE_CUDA),
|
||||
DEVICE_MASK_OPTIX = (1 << DEVICE_OPTIX),
|
||||
DEVICE_MASK_NETWORK = (1 << DEVICE_NETWORK),
|
||||
DEVICE_MASK_ALL = ~0
|
||||
};
|
||||
|
@ -380,7 +383,11 @@ class Device {
|
|||
}
|
||||
|
||||
/* tasks */
|
||||
virtual int get_split_task_count(DeviceTask &task) = 0;
|
||||
virtual int get_split_task_count(DeviceTask &)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
virtual void task_add(DeviceTask &task) = 0;
|
||||
virtual void task_wait() = 0;
|
||||
virtual void task_cancel() = 0;
|
||||
|
@ -399,6 +406,12 @@ class Device {
|
|||
bool transparent,
|
||||
const DeviceDrawParams &draw_params);
|
||||
|
||||
/* acceleration structure building */
|
||||
virtual bool build_optix_bvh(BVH *, device_memory &)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef WITH_NETWORK
|
||||
/* networking */
|
||||
void server_run();
|
||||
|
@ -456,6 +469,7 @@ class Device {
|
|||
static bool need_types_update, need_devices_update;
|
||||
static thread_mutex device_mutex;
|
||||
static vector<DeviceInfo> cuda_devices;
|
||||
static vector<DeviceInfo> optix_devices;
|
||||
static vector<DeviceInfo> opencl_devices;
|
||||
static vector<DeviceInfo> cpu_devices;
|
||||
static vector<DeviceInfo> network_devices;
|
||||
|
|
|
@ -2263,11 +2263,6 @@ class CUDADevice : public Device {
|
|||
}
|
||||
};
|
||||
|
||||
int get_split_task_count(DeviceTask & /*task*/)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
void task_add(DeviceTask &task)
|
||||
{
|
||||
CUDAContextScope scope(this);
|
||||
|
|
|
@ -27,6 +27,9 @@ Device *device_opencl_create(DeviceInfo &info, Stats &stats, Profiler &profiler,
|
|||
bool device_opencl_compile_kernel(const vector<string> ¶meters);
|
||||
bool device_cuda_init();
|
||||
Device *device_cuda_create(DeviceInfo &info, Stats &stats, Profiler &profiler, bool background);
|
||||
bool device_optix_init();
|
||||
Device *device_optix_create(DeviceInfo &info, Stats &stats, Profiler &profiler, bool background);
|
||||
|
||||
Device *device_network_create(DeviceInfo &info,
|
||||
Stats &stats,
|
||||
Profiler &profiler,
|
||||
|
@ -36,6 +39,7 @@ Device *device_multi_create(DeviceInfo &info, Stats &stats, Profiler &profiler,
|
|||
void device_cpu_info(vector<DeviceInfo> &devices);
|
||||
void device_opencl_info(vector<DeviceInfo> &devices);
|
||||
void device_cuda_info(vector<DeviceInfo> &devices);
|
||||
void device_optix_info(vector<DeviceInfo> &devices);
|
||||
void device_network_info(vector<DeviceInfo> &devices);
|
||||
|
||||
string device_cpu_capabilities();
|
||||
|
|
|
@ -153,6 +153,24 @@ class MultiDevice : public Device {
|
|||
return result;
|
||||
}
|
||||
|
||||
bool build_optix_bvh(BVH *bvh, device_memory &mem)
|
||||
{
|
||||
device_ptr key = unique_key++;
|
||||
|
||||
// Broadcast acceleration structure build to all devices
|
||||
foreach (SubDevice &sub, devices) {
|
||||
mem.device = sub.device;
|
||||
if (!sub.device->build_optix_bvh(bvh, mem))
|
||||
return false;
|
||||
sub.ptr_map[key] = mem.device_pointer;
|
||||
}
|
||||
|
||||
mem.device = this;
|
||||
mem.device_pointer = key;
|
||||
stats.mem_alloc(mem.device_size);
|
||||
return true;
|
||||
}
|
||||
|
||||
void mem_alloc(device_memory &mem)
|
||||
{
|
||||
device_ptr key = unique_key++;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -64,6 +64,10 @@ set(SRC_OPENCL_KERNELS
|
|||
kernels/opencl/filter.cl
|
||||
)
|
||||
|
||||
set(SRC_OPTIX_KERNELS
|
||||
kernels/optix/kernel_optix.cu
|
||||
)
|
||||
|
||||
set(SRC_BVH_HEADERS
|
||||
bvh/bvh.h
|
||||
bvh/bvh_nodes.h
|
||||
|
@ -95,6 +99,7 @@ set(SRC_HEADERS
|
|||
kernel_color.h
|
||||
kernel_compat_cpu.h
|
||||
kernel_compat_cuda.h
|
||||
kernel_compat_optix.h
|
||||
kernel_compat_opencl.h
|
||||
kernel_differential.h
|
||||
kernel_emission.h
|
||||
|
@ -140,6 +145,9 @@ set(SRC_KERNELS_CUDA_HEADERS
|
|||
kernels/cuda/kernel_cuda_image.h
|
||||
)
|
||||
|
||||
set(SRC_KERNELS_OPTIX_HEADERS
|
||||
)
|
||||
|
||||
set(SRC_KERNELS_OPENCL_HEADERS
|
||||
kernels/opencl/kernel_split_function.h
|
||||
kernels/opencl/kernel_opencl_image.h
|
||||
|
@ -168,7 +176,7 @@ set(SRC_CLOSURE_HEADERS
|
|||
closure/volume.h
|
||||
closure/bsdf_principled_diffuse.h
|
||||
closure/bsdf_principled_sheen.h
|
||||
closure/bsdf_hair_principled.h
|
||||
closure/bsdf_hair_principled.h
|
||||
)
|
||||
|
||||
set(SRC_SVM_HEADERS
|
||||
|
@ -476,6 +484,53 @@ if(WITH_CYCLES_CUDA_BINARIES)
|
|||
cycles_set_solution_folder(cycles_kernel_cuda)
|
||||
endif()
|
||||
|
||||
# OptiX PTX modules
|
||||
|
||||
if(WITH_CYCLES_DEVICE_OPTIX)
|
||||
foreach(input ${SRC_OPTIX_KERNELS})
|
||||
get_filename_component(input_we ${input} NAME_WE)
|
||||
|
||||
set(output "${CMAKE_CURRENT_BINARY_DIR}/${input_we}.ptx")
|
||||
set(cuda_flags
|
||||
-I "${OPTIX_INCLUDE_DIR}"
|
||||
-I "${CMAKE_CURRENT_SOURCE_DIR}/.."
|
||||
-I "${CMAKE_CURRENT_SOURCE_DIR}/kernels/cuda"
|
||||
-arch=sm_30
|
||||
--use_fast_math
|
||||
-o ${output})
|
||||
|
||||
if(WITH_CYCLES_DEBUG)
|
||||
set(cuda_flags ${cuda_flags}
|
||||
-D __KERNEL_DEBUG__)
|
||||
endif()
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT
|
||||
${output}
|
||||
DEPENDS
|
||||
${input}
|
||||
${SRC_HEADERS}
|
||||
${SRC_KERNELS_CUDA_HEADERS}
|
||||
${SRC_KERNELS_OPTIX_HEADERS}
|
||||
${SRC_BVH_HEADERS}
|
||||
${SRC_SVM_HEADERS}
|
||||
${SRC_GEOM_HEADERS}
|
||||
${SRC_CLOSURE_HEADERS}
|
||||
${SRC_UTIL_HEADERS}
|
||||
COMMAND
|
||||
${CUDA_NVCC_EXECUTABLE} --ptx ${cuda_flags} ${input}
|
||||
WORKING_DIRECTORY
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
|
||||
list(APPEND optix_ptx ${output})
|
||||
|
||||
delayed_install("${CMAKE_CURRENT_BINARY_DIR}" "${output}" ${CYCLES_INSTALL_PATH}/lib)
|
||||
endforeach()
|
||||
|
||||
add_custom_target(cycles_kernel_optix ALL DEPENDS ${optix_ptx})
|
||||
cycles_set_solution_folder(cycles_kernel_optix)
|
||||
endif()
|
||||
|
||||
# OSL module
|
||||
|
||||
if(WITH_CYCLES_OSL)
|
||||
|
@ -535,10 +590,12 @@ endif()
|
|||
cycles_add_library(cycles_kernel "${LIB}"
|
||||
${SRC_CPU_KERNELS}
|
||||
${SRC_CUDA_KERNELS}
|
||||
${SRC_OPTIX_KERNELS}
|
||||
${SRC_OPENCL_KERNELS}
|
||||
${SRC_HEADERS}
|
||||
${SRC_KERNELS_CPU_HEADERS}
|
||||
${SRC_KERNELS_CUDA_HEADERS}
|
||||
${SRC_KERNELS_OPTIX_HEADERS}
|
||||
${SRC_KERNELS_OPENCL_HEADERS}
|
||||
${SRC_BVH_HEADERS}
|
||||
${SRC_CLOSURE_HEADERS}
|
||||
|
@ -548,9 +605,24 @@ cycles_add_library(cycles_kernel "${LIB}"
|
|||
${SRC_SPLIT_HEADERS}
|
||||
)
|
||||
|
||||
source_group("bvh" FILES ${SRC_BVH_HEADERS})
|
||||
source_group("closure" FILES ${SRC_CLOSURE_HEADERS})
|
||||
source_group("filter" FILES ${SRC_FILTER_HEADERS})
|
||||
source_group("geom" FILES ${SRC_GEOM_HEADERS})
|
||||
source_group("kernel" FILES ${SRC_HEADERS})
|
||||
source_group("kernel\\split" FILES ${SRC_SPLIT_HEADERS})
|
||||
source_group("kernels\\cpu" FILES ${SRC_CPU_KERNELS} ${SRC_KERNELS_CPU_HEADERS})
|
||||
source_group("kernels\\cuda" FILES ${SRC_CUDA_KERNELS} ${SRC_KERNELS_CUDA_HEADERS})
|
||||
source_group("kernels\\opencl" FILES ${SRC_OPENCL_KERNELS} ${SRC_KERNELS_OPENCL_HEADERS})
|
||||
source_group("kernels\\optix" FILES ${SRC_OPTIX_KERNELS} ${SRC_KERNELS_OPTIX_HEADERS})
|
||||
source_group("svm" FILES ${SRC_SVM_HEADERS})
|
||||
|
||||
if(WITH_CYCLES_CUDA)
|
||||
add_dependencies(cycles_kernel cycles_kernel_cuda)
|
||||
endif()
|
||||
if(WITH_CYCLES_DEVICE_OPTIX)
|
||||
add_dependencies(cycles_kernel cycles_kernel_optix)
|
||||
endif()
|
||||
|
||||
# OpenCL kernel
|
||||
|
||||
|
@ -564,9 +636,11 @@ endif()
|
|||
|
||||
delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "${SRC_OPENCL_KERNELS}" ${CYCLES_INSTALL_PATH}/source/kernel/kernels/opencl)
|
||||
delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "${SRC_CUDA_KERNELS}" ${CYCLES_INSTALL_PATH}/source/kernel/kernels/cuda)
|
||||
delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "${SRC_OPTIX_KERNELS}" ${CYCLES_INSTALL_PATH}/source/kernel/kernels/optix)
|
||||
delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "${SRC_HEADERS}" ${CYCLES_INSTALL_PATH}/source/kernel)
|
||||
delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "${SRC_KERNELS_OPENCL_HEADERS}" ${CYCLES_INSTALL_PATH}/source/kernel/kernels/opencl)
|
||||
delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "${SRC_KERNELS_CUDA_HEADERS}" ${CYCLES_INSTALL_PATH}/source/kernel/kernels/cuda)
|
||||
delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "${SRC_KERNELS_OPTIX_HEADERS}" ${CYCLES_INSTALL_PATH}/source/kernel/kernels/optix)
|
||||
delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "${SRC_BVH_HEADERS}" ${CYCLES_INSTALL_PATH}/source/kernel/bvh)
|
||||
delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "${SRC_CLOSURE_HEADERS}" ${CYCLES_INSTALL_PATH}/source/kernel/closure)
|
||||
delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "${SRC_FILTER_HEADERS}" ${CYCLES_INSTALL_PATH}/source/kernel/filter)
|
||||
|
|
|
@ -1139,9 +1139,9 @@ int Mesh::motion_step(float time) const
|
|||
return -1;
|
||||
}
|
||||
|
||||
bool Mesh::need_build_bvh(BVHLayout) const
|
||||
bool Mesh::need_build_bvh(BVHLayout layout) const
|
||||
{
|
||||
return !transform_applied || has_surface_bssrdf;
|
||||
return !transform_applied || has_surface_bssrdf || layout == BVH_LAYOUT_OPTIX;
|
||||
}
|
||||
|
||||
bool Mesh::is_instanced() const
|
||||
|
|
|
@ -86,6 +86,16 @@ void DebugFlags::CUDA::reset()
|
|||
split_kernel = false;
|
||||
}
|
||||
|
||||
DebugFlags::OptiX::OptiX()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
void DebugFlags::OptiX::reset()
|
||||
{
|
||||
cuda_streams = 1;
|
||||
}
|
||||
|
||||
DebugFlags::OpenCL::OpenCL() : device_type(DebugFlags::OpenCL::DEVICE_ALL), debug(false)
|
||||
{
|
||||
reset();
|
||||
|
@ -130,6 +140,7 @@ void DebugFlags::reset()
|
|||
viewport_static_bvh = false;
|
||||
cpu.reset();
|
||||
cuda.reset();
|
||||
optix.reset();
|
||||
opencl.reset();
|
||||
}
|
||||
|
||||
|
@ -145,7 +156,10 @@ std::ostream &operator<<(std::ostream &os, DebugFlagsConstRef debug_flags)
|
|||
<< " Split : " << string_from_bool(debug_flags.cpu.split_kernel) << "\n";
|
||||
|
||||
os << "CUDA flags:\n"
|
||||
<< " Adaptive Compile: " << string_from_bool(debug_flags.cuda.adaptive_compile) << "\n";
|
||||
<< " Adaptive Compile : " << string_from_bool(debug_flags.cuda.adaptive_compile) << "\n";
|
||||
|
||||
os << "OptiX flags:\n"
|
||||
<< " CUDA streams : " << debug_flags.optix.cuda_streams << "\n";
|
||||
|
||||
const char *opencl_device_type;
|
||||
switch (debug_flags.opencl.device_type) {
|
||||
|
|
|
@ -99,6 +99,17 @@ class DebugFlags {
|
|||
bool split_kernel;
|
||||
};
|
||||
|
||||
/* Descriptor of OptiX feature-set to be used. */
|
||||
struct OptiX {
|
||||
OptiX();
|
||||
|
||||
/* Reset flags to their defaults. */
|
||||
void reset();
|
||||
|
||||
/* Number of CUDA streams to launch kernels concurrently from. */
|
||||
int cuda_streams;
|
||||
};
|
||||
|
||||
/* Descriptor of OpenCL feature-set to be used. */
|
||||
struct OpenCL {
|
||||
OpenCL();
|
||||
|
@ -165,6 +176,9 @@ class DebugFlags {
|
|||
/* Requested CUDA flags. */
|
||||
CUDA cuda;
|
||||
|
||||
/* Requested OptiX flags. */
|
||||
OptiX optix;
|
||||
|
||||
/* Requested OpenCL flags. */
|
||||
OpenCL opencl;
|
||||
|
||||
|
|
Loading…
Reference in New Issue