Refactor: Cycles: Replace new/delete by unique_ptr, in simple cases
Pull Request: https://projects.blender.org/blender/blender/pulls/132361
This commit is contained in:
@@ -38,7 +38,7 @@
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
struct Options {
|
||||
Session *session;
|
||||
unique_ptr<Session> session;
|
||||
Scene *scene;
|
||||
string filepath;
|
||||
int width, height;
|
||||
@@ -99,12 +99,12 @@ static BufferParams &session_buffer_params()
|
||||
|
||||
static void scene_init()
|
||||
{
|
||||
options.scene = options.session->scene;
|
||||
options.scene = options.session->scene.get();
|
||||
|
||||
/* Read XML or USD */
|
||||
#ifdef WITH_USD
|
||||
if (!string_endswith(string_to_lower(options.filepath), ".xml")) {
|
||||
HD_CYCLES_NS::HdCyclesFileReader::read(options.session, options.filepath.c_str());
|
||||
HD_CYCLES_NS::HdCyclesFileReader::read(options.session.get(), options.filepath.c_str());
|
||||
}
|
||||
else
|
||||
#endif
|
||||
@@ -129,7 +129,7 @@ static void scene_init()
|
||||
static void session_init()
|
||||
{
|
||||
options.output_pass = "combined";
|
||||
options.session = new Session(options.session_params, options.scene_params);
|
||||
options.session = make_unique<Session>(options.session_params, options.scene_params);
|
||||
|
||||
#ifdef WITH_CYCLES_STANDALONE_GUI
|
||||
if (!options.session_params.background) {
|
||||
@@ -167,8 +167,7 @@ static void session_init()
|
||||
static void session_exit()
|
||||
{
|
||||
if (options.session) {
|
||||
delete options.session;
|
||||
options.session = nullptr;
|
||||
options.session.reset();
|
||||
}
|
||||
|
||||
if (options.session_params.background && !options.quiet) {
|
||||
|
||||
@@ -224,7 +224,7 @@ static void xml_read_shader_graph(XMLReadState &state, Shader *shader, const xml
|
||||
{
|
||||
xml_read_node(state, shader, graph_node);
|
||||
|
||||
ShaderGraph *graph = new ShaderGraph();
|
||||
unique_ptr<ShaderGraph> graph = make_unique<ShaderGraph>();
|
||||
|
||||
/* local state, shader nodes can't link to nodes outside the shader graph */
|
||||
XMLReader graph_reader;
|
||||
@@ -307,7 +307,7 @@ static void xml_read_shader_graph(XMLReadState &state, Shader *shader, const xml
|
||||
|
||||
#ifdef WITH_OSL
|
||||
if (node_name == "osl_shader") {
|
||||
ShaderManager *manager = state.scene->shader_manager;
|
||||
ShaderManager *manager = state.scene->shader_manager.get();
|
||||
|
||||
if (manager->use_osl()) {
|
||||
std::string filepath;
|
||||
@@ -317,7 +317,7 @@ static void xml_read_shader_graph(XMLReadState &state, Shader *shader, const xml
|
||||
filepath = path_join(state.base, filepath);
|
||||
}
|
||||
|
||||
snode = OSLShaderManager::osl_node(graph, manager, filepath, "");
|
||||
snode = OSLShaderManager::osl_node(graph.get(), manager, filepath, "");
|
||||
|
||||
if (!snode) {
|
||||
fprintf(stderr, "Failed to create OSL node from \"%s\".\n", filepath.c_str());
|
||||
@@ -358,7 +358,7 @@ static void xml_read_shader_graph(XMLReadState &state, Shader *shader, const xml
|
||||
}
|
||||
|
||||
snode = (ShaderNode *)node_type->create(node_type);
|
||||
snode->set_owner(graph);
|
||||
snode->set_owner(graph.get());
|
||||
}
|
||||
|
||||
xml_read_node(graph_reader, snode, node);
|
||||
@@ -380,7 +380,7 @@ static void xml_read_shader_graph(XMLReadState &state, Shader *shader, const xml
|
||||
}
|
||||
}
|
||||
|
||||
shader->set_graph(graph);
|
||||
shader->set_graph(std::move(graph));
|
||||
shader->tag_update(state.scene);
|
||||
}
|
||||
|
||||
|
||||
@@ -288,9 +288,9 @@ void BlenderSession::builtin_images_load()
|
||||
* happen is really weak, and likely to break in the future. We should find
|
||||
* a better solution to hand over the data directly to the image manager
|
||||
* instead of through callbacks whose timing is difficult to control. */
|
||||
ImageManager *manager = session->scene->image_manager;
|
||||
Device *device = session->device;
|
||||
manager->device_load_builtin(device, session->scene, session->progress);
|
||||
ImageManager *manager = session->scene->image_manager.get();
|
||||
Device *device = session->device.get();
|
||||
manager->device_load_builtin(device, session->scene.get(), session->progress);
|
||||
}
|
||||
|
||||
string BlenderPointDensityLoader::name() const
|
||||
|
||||
@@ -121,17 +121,17 @@ void BlenderSession::create_session()
|
||||
start_resize_time = 0.0;
|
||||
|
||||
/* create session */
|
||||
session = new Session(session_params, scene_params);
|
||||
session = make_unique<Session>(session_params, scene_params);
|
||||
session->progress.set_update_callback([this] { tag_redraw(); });
|
||||
session->progress.set_cancel_callback([this] { test_cancel(); });
|
||||
session->set_pause(session_pause);
|
||||
|
||||
/* create scene */
|
||||
scene = session->scene;
|
||||
scene = session->scene.get();
|
||||
scene->name = b_scene.name();
|
||||
|
||||
/* create sync */
|
||||
sync = new BlenderSync(
|
||||
sync = make_unique<BlenderSync>(
|
||||
b_engine, b_data, b_scene, scene, !background, use_developer_ui, session->progress);
|
||||
BL::Object b_camera_override(b_engine.camera_override());
|
||||
if (b_v3d) {
|
||||
@@ -222,8 +222,7 @@ void BlenderSession::reset_session(BL::BlendData &b_data, BL::Depsgraph &b_depsg
|
||||
|
||||
if (is_new_session) {
|
||||
/* Sync object should be re-created for new scene. */
|
||||
delete sync;
|
||||
sync = new BlenderSync(
|
||||
sync = make_unique<BlenderSync>(
|
||||
b_engine, b_data, b_scene, scene, !background, use_developer_ui, session->progress);
|
||||
}
|
||||
else {
|
||||
@@ -255,11 +254,8 @@ void BlenderSession::free_session()
|
||||
session->cancel(true);
|
||||
}
|
||||
|
||||
delete sync;
|
||||
sync = nullptr;
|
||||
|
||||
delete session;
|
||||
session = nullptr;
|
||||
sync.reset();
|
||||
session.reset();
|
||||
|
||||
display_driver_ = nullptr;
|
||||
}
|
||||
@@ -491,8 +487,7 @@ void BlenderSession::render_frame_finish()
|
||||
if (!b_render.use_persistent_data()) {
|
||||
/* Free the sync object so that it can properly dereference nodes from the scene graph before
|
||||
* the graph is freed. */
|
||||
delete sync;
|
||||
sync = nullptr;
|
||||
sync.reset();
|
||||
|
||||
session->device_free();
|
||||
}
|
||||
@@ -877,7 +872,7 @@ void BlenderSession::draw(BL::SpaceImageEditor &space_image)
|
||||
return;
|
||||
}
|
||||
|
||||
Scene *scene = session->scene;
|
||||
Scene *scene = session->scene.get();
|
||||
|
||||
const thread_scoped_lock lock(scene->mutex);
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "scene/scene.h"
|
||||
#include "session/session.h"
|
||||
|
||||
#include "util/unique_ptr.h"
|
||||
#include "util/vector.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
@@ -72,9 +73,9 @@ class BlenderSession {
|
||||
void update_bake_progress();
|
||||
|
||||
bool background;
|
||||
Session *session;
|
||||
unique_ptr<Session> session;
|
||||
Scene *scene;
|
||||
BlenderSync *sync;
|
||||
unique_ptr<BlenderSync> sync;
|
||||
double last_redraw_time;
|
||||
|
||||
BL::RenderEngine b_engine;
|
||||
|
||||
@@ -803,7 +803,7 @@ static ShaderNode *add_node(Scene *scene,
|
||||
/* create script node */
|
||||
BL::ShaderNodeScript b_script_node(b_node);
|
||||
|
||||
ShaderManager *manager = scene->shader_manager;
|
||||
ShaderManager *manager = scene->shader_manager.get();
|
||||
const string bytecode_hash = b_script_node.bytecode_hash();
|
||||
|
||||
if (!bytecode_hash.empty()) {
|
||||
@@ -864,18 +864,19 @@ static ShaderNode *add_node(Scene *scene,
|
||||
const int image_frame = image_user_frame_number(b_image_user, b_image, scene_frame);
|
||||
if (b_image_source != BL::Image::source_TILED) {
|
||||
image->handle = scene->image_manager->add_image(
|
||||
new BlenderImageLoader(b_image, image_frame, 0, b_engine.is_preview()),
|
||||
make_unique<BlenderImageLoader>(b_image, image_frame, 0, b_engine.is_preview()),
|
||||
image->image_params());
|
||||
}
|
||||
else {
|
||||
vector<ImageLoader *> loaders;
|
||||
vector<unique_ptr<ImageLoader>> loaders;
|
||||
loaders.reserve(image->get_tiles().size());
|
||||
for (const int tile_number : image->get_tiles()) {
|
||||
loaders.push_back(
|
||||
new BlenderImageLoader(b_image, image_frame, tile_number, b_engine.is_preview()));
|
||||
loaders.push_back(make_unique<BlenderImageLoader>(
|
||||
b_image, image_frame, tile_number, b_engine.is_preview()));
|
||||
}
|
||||
|
||||
image->handle = scene->image_manager->add_image(loaders, image->image_params());
|
||||
image->handle = scene->image_manager->add_image(std::move(loaders),
|
||||
image->image_params());
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -910,7 +911,7 @@ static ShaderNode *add_node(Scene *scene,
|
||||
const int scene_frame = b_scene.frame_current();
|
||||
const int image_frame = image_user_frame_number(b_image_user, b_image, scene_frame);
|
||||
env->handle = scene->image_manager->add_image(
|
||||
new BlenderImageLoader(b_image, image_frame, 0, b_engine.is_preview()),
|
||||
make_unique<BlenderImageLoader>(b_image, image_frame, 0, b_engine.is_preview()),
|
||||
env->image_params());
|
||||
}
|
||||
else {
|
||||
@@ -1075,7 +1076,7 @@ static ShaderNode *add_node(Scene *scene,
|
||||
point_density->set_space((NodeTexVoxelSpace)b_point_density_node.space());
|
||||
point_density->set_interpolation(get_image_interpolation(b_point_density_node));
|
||||
point_density->handle = scene->image_manager->add_image(
|
||||
new BlenderPointDensityLoader(b_depsgraph, b_point_density_node),
|
||||
make_unique<BlenderPointDensityLoader>(b_depsgraph, b_point_density_node),
|
||||
point_density->image_params());
|
||||
|
||||
b_point_density_node.cache_point_density(b_depsgraph);
|
||||
@@ -1575,7 +1576,7 @@ void BlenderSync::sync_materials(BL::Depsgraph &b_depsgraph, bool update_all)
|
||||
if (shader_map.add_or_update(&shader, b_mat) || update_all ||
|
||||
scene_attr_needs_recalc(shader, b_depsgraph))
|
||||
{
|
||||
ShaderGraph *graph = new ShaderGraph();
|
||||
unique_ptr<ShaderGraph> graph = make_unique<ShaderGraph>();
|
||||
|
||||
shader->name = b_mat.name().c_str();
|
||||
shader->set_pass_id(b_mat.pass_index());
|
||||
@@ -1584,7 +1585,7 @@ void BlenderSync::sync_materials(BL::Depsgraph &b_depsgraph, bool update_all)
|
||||
if (b_mat.use_nodes() && b_mat.node_tree()) {
|
||||
BL::ShaderNodeTree b_ntree(b_mat.node_tree());
|
||||
|
||||
add_nodes(scene, b_engine, b_data, b_depsgraph, b_scene, graph, b_ntree);
|
||||
add_nodes(scene, b_engine, b_data, b_depsgraph, b_scene, graph.get(), b_ntree);
|
||||
}
|
||||
else {
|
||||
DiffuseBsdfNode *diffuse = graph->create_node<DiffuseBsdfNode>();
|
||||
@@ -1595,7 +1596,7 @@ void BlenderSync::sync_materials(BL::Depsgraph &b_depsgraph, bool update_all)
|
||||
graph->connect(diffuse->output("BSDF"), out->input("Surface"));
|
||||
}
|
||||
|
||||
resolve_view_layer_attributes(shader, graph, b_depsgraph);
|
||||
resolve_view_layer_attributes(shader, graph.get(), b_depsgraph);
|
||||
|
||||
/* settings */
|
||||
PointerRNA cmat = RNA_pointer_get(&b_mat.ptr, "cycles");
|
||||
@@ -1608,7 +1609,7 @@ void BlenderSync::sync_materials(BL::Depsgraph &b_depsgraph, bool update_all)
|
||||
shader->set_volume_step_rate(get_float(cmat, "volume_step_rate"));
|
||||
shader->set_displacement_method(get_displacement_method(b_mat));
|
||||
|
||||
shader->set_graph(graph);
|
||||
shader->set_graph(std::move(graph));
|
||||
|
||||
/* By simplifying the shader graph as soon as possible, some
|
||||
* redundant shader nodes might be removed which prevents loading
|
||||
@@ -1620,7 +1621,7 @@ void BlenderSync::sync_materials(BL::Depsgraph &b_depsgraph, bool update_all)
|
||||
* right before compiling.
|
||||
*/
|
||||
if (!preview) {
|
||||
pool.push([graph, scene = scene] { graph->simplify(scene); });
|
||||
pool.push([graph = shader->graph.get(), scene = scene] { graph->simplify(scene); });
|
||||
/* NOTE: Update shaders out of the threads since those routines
|
||||
* are accessing and writing to a global context.
|
||||
*/
|
||||
@@ -1660,7 +1661,7 @@ void BlenderSync::sync_world(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d,
|
||||
viewport_parameters.shader_modified(new_viewport_parameters) ||
|
||||
scene_attr_needs_recalc(shader, b_depsgraph))
|
||||
{
|
||||
ShaderGraph *graph = new ShaderGraph();
|
||||
unique_ptr<ShaderGraph> graph = make_unique<ShaderGraph>();
|
||||
|
||||
/* create nodes */
|
||||
if (new_viewport_parameters.use_scene_world && b_world && b_world.use_nodes() &&
|
||||
@@ -1668,7 +1669,7 @@ void BlenderSync::sync_world(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d,
|
||||
{
|
||||
BL::ShaderNodeTree b_ntree(b_world.node_tree());
|
||||
|
||||
add_nodes(scene, b_engine, b_data, b_depsgraph, b_scene, graph, b_ntree);
|
||||
add_nodes(scene, b_engine, b_data, b_depsgraph, b_scene, graph.get(), b_ntree);
|
||||
|
||||
/* volume */
|
||||
PointerRNA cworld = RNA_pointer_get(&b_world.ptr, "cycles");
|
||||
@@ -1758,9 +1759,9 @@ void BlenderSync::sync_world(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d,
|
||||
background->set_visibility(visibility);
|
||||
}
|
||||
|
||||
resolve_view_layer_attributes(shader, graph, b_depsgraph);
|
||||
resolve_view_layer_attributes(shader, graph.get(), b_depsgraph);
|
||||
|
||||
shader->set_graph(graph);
|
||||
shader->set_graph(std::move(graph));
|
||||
shader->tag_update(scene);
|
||||
}
|
||||
|
||||
@@ -1829,7 +1830,7 @@ void BlenderSync::sync_lights(BL::Depsgraph &b_depsgraph, bool update_all)
|
||||
if (shader_map.add_or_update(&shader, b_light) || update_all ||
|
||||
scene_attr_needs_recalc(shader, b_depsgraph))
|
||||
{
|
||||
ShaderGraph *graph = new ShaderGraph();
|
||||
unique_ptr<ShaderGraph> graph = make_unique<ShaderGraph>();
|
||||
|
||||
/* create nodes */
|
||||
if (b_light.use_nodes() && b_light.node_tree()) {
|
||||
@@ -1837,7 +1838,7 @@ void BlenderSync::sync_lights(BL::Depsgraph &b_depsgraph, bool update_all)
|
||||
|
||||
BL::ShaderNodeTree b_ntree(b_light.node_tree());
|
||||
|
||||
add_nodes(scene, b_engine, b_data, b_depsgraph, b_scene, graph, b_ntree);
|
||||
add_nodes(scene, b_engine, b_data, b_depsgraph, b_scene, graph.get(), b_ntree);
|
||||
}
|
||||
else {
|
||||
EmissionNode *emission = graph->create_node<EmissionNode>();
|
||||
@@ -1849,9 +1850,9 @@ void BlenderSync::sync_lights(BL::Depsgraph &b_depsgraph, bool update_all)
|
||||
graph->connect(emission->output("Emission"), out->input("Surface"));
|
||||
}
|
||||
|
||||
resolve_view_layer_attributes(shader, graph, b_depsgraph);
|
||||
resolve_view_layer_attributes(shader, graph.get(), b_depsgraph);
|
||||
|
||||
shader->set_graph(graph);
|
||||
shader->set_graph(std::move(graph));
|
||||
shader->tag_update(scene);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -264,7 +264,7 @@ void BlenderSync::sync_data(BL::RenderSettings &b_render,
|
||||
const DeviceInfo &denoise_device_info)
|
||||
{
|
||||
/* For auto refresh images. */
|
||||
ImageManager *image_manager = scene->image_manager;
|
||||
ImageManager *image_manager = scene->image_manager.get();
|
||||
const int frame = b_scene.frame_current();
|
||||
const bool auto_refresh_update = image_manager->set_animation_frame_update(frame);
|
||||
|
||||
|
||||
@@ -210,11 +210,11 @@ static void sync_smoke_volume(
|
||||
|
||||
Attribute *attr = volume->attributes.add(std);
|
||||
|
||||
ImageLoader *loader = new BlenderSmokeLoader(b_ob_info.real_object, std);
|
||||
unique_ptr<ImageLoader> loader = make_unique<BlenderSmokeLoader>(b_ob_info.real_object, std);
|
||||
ImageParams params;
|
||||
params.frame = frame;
|
||||
|
||||
attr->data_voxel() = scene->image_manager->add_image(loader, params);
|
||||
attr->data_voxel() = scene->image_manager->add_image(std::move(loader), params);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -343,12 +343,12 @@ static void sync_volume_object(BL::BlendData &b_data,
|
||||
volume->attributes.add(std) :
|
||||
volume->attributes.add(name, TypeFloat, ATTR_ELEMENT_VOXEL);
|
||||
|
||||
ImageLoader *loader = new BlenderVolumeLoader(
|
||||
unique_ptr<ImageLoader> loader = make_unique<BlenderVolumeLoader>(
|
||||
b_data, b_volume, name.string(), b_render.precision());
|
||||
ImageParams params;
|
||||
params.frame = b_volume.grids.frame();
|
||||
|
||||
attr->data_voxel() = scene->image_manager->add_image(loader, params, false);
|
||||
attr->data_voxel() = scene->image_manager->add_image(std::move(loader), params, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -473,7 +473,7 @@ void BVHBuild::add_references(BVHRange &root)
|
||||
|
||||
/* Build */
|
||||
|
||||
BVHNode *BVHBuild::run()
|
||||
unique_ptr<BVHNode> BVHBuild::run()
|
||||
{
|
||||
BVHRange root;
|
||||
|
||||
@@ -517,7 +517,7 @@ BVHNode *BVHBuild::run()
|
||||
}
|
||||
|
||||
/* build recursively */
|
||||
BVHNode *rootnode;
|
||||
unique_ptr<BVHNode> rootnode;
|
||||
|
||||
if (params.use_spatial_split) {
|
||||
/* Perform multithreaded spatial split build. */
|
||||
@@ -538,8 +538,7 @@ BVHNode *BVHBuild::run()
|
||||
/* delete if we canceled */
|
||||
if (rootnode) {
|
||||
if (progress.get_cancel()) {
|
||||
rootnode->deleteSubtree();
|
||||
rootnode = nullptr;
|
||||
rootnode.reset();
|
||||
VLOG_WORK << "BVH build canceled.";
|
||||
}
|
||||
else {
|
||||
@@ -601,10 +600,10 @@ void BVHBuild::thread_build_node(InnerNode *inner,
|
||||
}
|
||||
|
||||
/* build nodes */
|
||||
BVHNode *node = build_node(range, level);
|
||||
unique_ptr<BVHNode> node = build_node(range, level);
|
||||
|
||||
/* set child in inner node */
|
||||
inner->children[child] = node;
|
||||
inner->children[child] = std::move(node);
|
||||
|
||||
/* update progress */
|
||||
if (range.size() < THREAD_TASK_SIZE) {
|
||||
@@ -631,10 +630,10 @@ void BVHBuild::thread_build_spatial_split_node(InnerNode *inner,
|
||||
BVHSpatialStorage *local_storage = &spatial_storage.local();
|
||||
|
||||
/* build nodes */
|
||||
BVHNode *node = build_node(range, references, level, local_storage);
|
||||
unique_ptr<BVHNode> node = build_node(range, references, level, local_storage);
|
||||
|
||||
/* set child in inner node */
|
||||
inner->children[child] = node;
|
||||
inner->children[child] = std::move(node);
|
||||
}
|
||||
|
||||
bool BVHBuild::range_within_max_leaf_size(const BVHRange &range,
|
||||
@@ -693,7 +692,7 @@ bool BVHBuild::range_within_max_leaf_size(const BVHRange &range,
|
||||
}
|
||||
|
||||
/* multithreaded binning builder */
|
||||
BVHNode *BVHBuild::build_node(const BVHObjectBinning &range, const int level)
|
||||
unique_ptr<BVHNode> BVHBuild::build_node(const BVHObjectBinning &range, const int level)
|
||||
{
|
||||
const size_t size = range.size();
|
||||
const float leafSAH = params.sah_primitive_cost * range.leafSAH;
|
||||
@@ -756,20 +755,21 @@ BVHNode *BVHBuild::build_node(const BVHObjectBinning &range, const int level)
|
||||
}
|
||||
|
||||
/* Create inner node. */
|
||||
InnerNode *inner;
|
||||
unique_ptr<InnerNode> inner;
|
||||
if (range.size() < THREAD_TASK_SIZE) {
|
||||
/* local build */
|
||||
BVHNode *leftnode = build_node(left, level + 1);
|
||||
BVHNode *rightnode = build_node(right, level + 1);
|
||||
unique_ptr<BVHNode> leftnode = build_node(left, level + 1);
|
||||
unique_ptr<BVHNode> rightnode = build_node(right, level + 1);
|
||||
|
||||
inner = new InnerNode(bounds, leftnode, rightnode);
|
||||
inner = make_unique<InnerNode>(bounds, std::move(leftnode), std::move(rightnode));
|
||||
}
|
||||
else {
|
||||
/* Threaded build */
|
||||
inner = new InnerNode(bounds);
|
||||
inner = make_unique<InnerNode>(bounds);
|
||||
InnerNode *inner_ptr = inner.get();
|
||||
|
||||
task_pool.push([=] { thread_build_node(inner, 0, left, level + 1); });
|
||||
task_pool.push([=] { thread_build_node(inner, 1, right, level + 1); });
|
||||
task_pool.push([=] { thread_build_node(inner_ptr, 0, left, level + 1); });
|
||||
task_pool.push([=] { thread_build_node(inner_ptr, 1, right, level + 1); });
|
||||
}
|
||||
|
||||
if (do_unalinged_split) {
|
||||
@@ -780,10 +780,10 @@ BVHNode *BVHBuild::build_node(const BVHObjectBinning &range, const int level)
|
||||
}
|
||||
|
||||
/* multithreaded spatial split builder */
|
||||
BVHNode *BVHBuild::build_node(const BVHRange &range,
|
||||
vector<BVHReference> &references,
|
||||
const int level,
|
||||
BVHSpatialStorage *storage)
|
||||
unique_ptr<BVHNode> BVHBuild::build_node(const BVHRange &range,
|
||||
vector<BVHReference> &references,
|
||||
const int level,
|
||||
BVHSpatialStorage *storage)
|
||||
{
|
||||
/* Update progress.
|
||||
*
|
||||
@@ -857,7 +857,7 @@ BVHNode *BVHBuild::build_node(const BVHRange &range,
|
||||
}
|
||||
|
||||
/* Create inner node. */
|
||||
InnerNode *inner;
|
||||
unique_ptr<InnerNode> inner;
|
||||
if (range.size() < THREAD_TASK_SIZE) {
|
||||
/* Local build. */
|
||||
|
||||
@@ -866,16 +866,16 @@ BVHNode *BVHBuild::build_node(const BVHRange &range,
|
||||
references.begin() + right.end());
|
||||
right.set_start(0);
|
||||
|
||||
BVHNode *leftnode = build_node(left, references, level + 1, storage);
|
||||
unique_ptr<BVHNode> leftnode = build_node(left, references, level + 1, storage);
|
||||
|
||||
/* Build right node. */
|
||||
BVHNode *rightnode = build_node(right, right_references, level + 1, storage);
|
||||
unique_ptr<BVHNode> rightnode = build_node(right, right_references, level + 1, storage);
|
||||
|
||||
inner = new InnerNode(bounds, leftnode, rightnode);
|
||||
inner = make_unique<InnerNode>(bounds, std::move(leftnode), std::move(rightnode));
|
||||
}
|
||||
else {
|
||||
/* Threaded build. */
|
||||
inner = new InnerNode(bounds);
|
||||
inner = make_unique<InnerNode>(bounds);
|
||||
|
||||
vector<BVHReference> left_references(references.begin() + left.start(),
|
||||
references.begin() + left.end());
|
||||
@@ -883,13 +883,15 @@ BVHNode *BVHBuild::build_node(const BVHRange &range,
|
||||
references.begin() + right.end());
|
||||
right.set_start(0);
|
||||
|
||||
InnerNode *inner_ptr = inner.get();
|
||||
|
||||
/* Create tasks for left and right nodes, using copy for most arguments and
|
||||
* move for reference to avoid memory copies. */
|
||||
task_pool.push([=, refs = std::move(left_references)]() mutable {
|
||||
thread_build_spatial_split_node(inner, 0, left, refs, level + 1);
|
||||
thread_build_spatial_split_node(inner_ptr, 0, left, refs, level + 1);
|
||||
});
|
||||
task_pool.push([=, refs = std::move(right_references)]() mutable {
|
||||
thread_build_spatial_split_node(inner, 1, right, refs, level + 1);
|
||||
thread_build_spatial_split_node(inner_ptr, 1, right, refs, level + 1);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -902,13 +904,13 @@ BVHNode *BVHBuild::build_node(const BVHRange &range,
|
||||
|
||||
/* Create Nodes */
|
||||
|
||||
BVHNode *BVHBuild::create_object_leaf_nodes(const BVHReference *ref,
|
||||
const int start,
|
||||
const int num)
|
||||
unique_ptr<BVHNode> BVHBuild::create_object_leaf_nodes(const BVHReference *ref,
|
||||
const int start,
|
||||
const int num)
|
||||
{
|
||||
if (num == 0) {
|
||||
const BoundBox bounds = BoundBox::empty;
|
||||
return new LeafNode(bounds, 0, 0, 0);
|
||||
return make_unique<LeafNode>(bounds, 0, 0, 0);
|
||||
}
|
||||
if (num == 1) {
|
||||
assert(start < prim_type.size());
|
||||
@@ -920,27 +922,33 @@ BVHNode *BVHBuild::create_object_leaf_nodes(const BVHReference *ref,
|
||||
}
|
||||
|
||||
const uint visibility = objects[ref->prim_object()]->visibility_for_tracing();
|
||||
BVHNode *leaf_node = new LeafNode(ref->bounds(), visibility, start, start + 1);
|
||||
unique_ptr<BVHNode> leaf_node = make_unique<LeafNode>(
|
||||
ref->bounds(), visibility, start, start + 1);
|
||||
leaf_node->time_from = ref->time_from();
|
||||
leaf_node->time_to = ref->time_to();
|
||||
return leaf_node;
|
||||
}
|
||||
|
||||
const int mid = num / 2;
|
||||
BVHNode *leaf0 = create_object_leaf_nodes(ref, start, mid);
|
||||
BVHNode *leaf1 = create_object_leaf_nodes(ref + mid, start + mid, num - mid);
|
||||
unique_ptr<BVHNode> leaf0 = create_object_leaf_nodes(ref, start, mid);
|
||||
unique_ptr<BVHNode> leaf1 = create_object_leaf_nodes(ref + mid, start + mid, num - mid);
|
||||
|
||||
BoundBox bounds = BoundBox::empty;
|
||||
bounds.grow(leaf0->bounds);
|
||||
bounds.grow(leaf1->bounds);
|
||||
|
||||
BVHNode *inner_node = new InnerNode(bounds, leaf0, leaf1);
|
||||
inner_node->time_from = min(leaf0->time_from, leaf1->time_from);
|
||||
inner_node->time_to = max(leaf0->time_to, leaf1->time_to);
|
||||
const float time_from = min(leaf0->time_from, leaf1->time_from);
|
||||
const float time_to = max(leaf0->time_to, leaf1->time_to);
|
||||
|
||||
unique_ptr<BVHNode> inner_node = make_unique<InnerNode>(
|
||||
bounds, std::move(leaf0), std::move(leaf1));
|
||||
inner_node->time_from = time_from;
|
||||
inner_node->time_to = time_to;
|
||||
return inner_node;
|
||||
}
|
||||
|
||||
BVHNode *BVHBuild::create_leaf_node(const BVHRange &range, const vector<BVHReference> &references)
|
||||
unique_ptr<BVHNode> BVHBuild::create_leaf_node(const BVHRange &range,
|
||||
const vector<BVHReference> &references)
|
||||
{
|
||||
/* This is a bit over-allocating here (considering leaf size into account),
|
||||
* but chunk-based re-allocation in vector makes it difficult to use small
|
||||
@@ -1006,7 +1014,7 @@ BVHNode *BVHBuild::create_leaf_node(const BVHRange &range, const vector<BVHRefer
|
||||
* TODO(sergey): With some pointer trickery we can write directly to the
|
||||
* destination buffers for the non-spatial split BVH.
|
||||
*/
|
||||
BVHNode *leaves[PRIMITIVE_NUM + 1] = {nullptr};
|
||||
unique_ptr<BVHNode> leaves[PRIMITIVE_NUM + 1];
|
||||
int num_leaves = 0;
|
||||
size_t start_index = 0;
|
||||
vector<int, LeafStackAllocator> local_prim_type;
|
||||
@@ -1038,7 +1046,8 @@ BVHNode *BVHBuild::create_leaf_node(const BVHRange &range, const vector<BVHRefer
|
||||
alignment_found = unaligned_heuristic.compute_aligned_space(p_ref[i][j], &aligned_space);
|
||||
}
|
||||
}
|
||||
LeafNode *leaf_node = new LeafNode(bounds[i], visibility[i], start_index, start_index + num);
|
||||
unique_ptr<LeafNode> leaf_node = make_unique<LeafNode>(
|
||||
bounds[i], visibility[i], start_index, start_index + num);
|
||||
if (true) {
|
||||
float time_from = 1.0f;
|
||||
float time_to = 0.0f;
|
||||
@@ -1062,7 +1071,7 @@ BVHNode *BVHBuild::create_leaf_node(const BVHRange &range, const vector<BVHRefer
|
||||
/* Set alignment space. */
|
||||
leaf_node->set_aligned_space(aligned_space);
|
||||
}
|
||||
leaves[num_leaves++] = leaf_node;
|
||||
leaves[num_leaves++] = std::move(leaf_node);
|
||||
start_index += num;
|
||||
}
|
||||
}
|
||||
@@ -1139,7 +1148,7 @@ BVHNode *BVHBuild::create_leaf_node(const BVHRange &range, const vector<BVHRefer
|
||||
* index.
|
||||
*/
|
||||
for (int i = 0; i < num_leaves; ++i) {
|
||||
LeafNode *leaf = (LeafNode *)leaves[i];
|
||||
LeafNode *leaf = (LeafNode *)leaves[i].get();
|
||||
leaf->lo += start_index;
|
||||
leaf->hi += start_index;
|
||||
}
|
||||
@@ -1162,27 +1171,31 @@ BVHNode *BVHBuild::create_leaf_node(const BVHRange &range, const vector<BVHRefer
|
||||
* In all the rest cases we'll be creating intermediate inner node with
|
||||
* an appropriate bounding box.
|
||||
*/
|
||||
return leaves[0];
|
||||
return std::move(leaves[0]);
|
||||
}
|
||||
if (num_leaves == 2) {
|
||||
return new InnerNode(range.bounds(), leaves[0], leaves[1]);
|
||||
return make_unique<InnerNode>(range.bounds(), std::move(leaves[0]), std::move(leaves[1]));
|
||||
}
|
||||
if (num_leaves == 3) {
|
||||
const BoundBox inner_bounds = merge(leaves[1]->bounds, leaves[2]->bounds);
|
||||
BVHNode *inner = new InnerNode(inner_bounds, leaves[1], leaves[2]);
|
||||
return new InnerNode(range.bounds(), leaves[0], inner);
|
||||
unique_ptr<BVHNode> inner = make_unique<InnerNode>(
|
||||
inner_bounds, std::move(leaves[1]), std::move(leaves[2]));
|
||||
return make_unique<InnerNode>(range.bounds(), std::move(leaves[0]), std::move(inner));
|
||||
}
|
||||
|
||||
/* Should be doing more branches if more primitive types added. */
|
||||
assert(num_leaves <= 5);
|
||||
const BoundBox inner_bounds_a = merge(leaves[0]->bounds, leaves[1]->bounds);
|
||||
const BoundBox inner_bounds_b = merge(leaves[2]->bounds, leaves[3]->bounds);
|
||||
BVHNode *inner_a = new InnerNode(inner_bounds_a, leaves[0], leaves[1]);
|
||||
BVHNode *inner_b = new InnerNode(inner_bounds_b, leaves[2], leaves[3]);
|
||||
unique_ptr<BVHNode> inner_a = make_unique<InnerNode>(
|
||||
inner_bounds_a, std::move(leaves[0]), std::move(leaves[1]));
|
||||
unique_ptr<BVHNode> inner_b = make_unique<InnerNode>(
|
||||
inner_bounds_b, std::move(leaves[2]), std::move(leaves[3]));
|
||||
const BoundBox inner_bounds_c = merge(inner_a->bounds, inner_b->bounds);
|
||||
BVHNode *inner_c = new InnerNode(inner_bounds_c, inner_a, inner_b);
|
||||
unique_ptr<BVHNode> inner_c = make_unique<InnerNode>(
|
||||
inner_bounds_c, std::move(inner_a), std::move(inner_b));
|
||||
if (num_leaves == 5) {
|
||||
return new InnerNode(range.bounds(), inner_c, leaves[4]);
|
||||
return make_unique<InnerNode>(range.bounds(), std::move(inner_c), std::move(leaves[4]));
|
||||
}
|
||||
return inner_c;
|
||||
|
||||
@@ -1213,7 +1226,7 @@ void BVHBuild::rotate(BVHNode *node, const int max_depth)
|
||||
|
||||
/* rotate all children first */
|
||||
for (size_t c = 0; c < 2; c++) {
|
||||
rotate(parent->children[c], max_depth - 1);
|
||||
rotate(parent->children[c].get(), max_depth - 1);
|
||||
}
|
||||
|
||||
/* compute current area of all children */
|
||||
@@ -1237,7 +1250,7 @@ void BVHBuild::rotate(BVHNode *node, const int max_depth)
|
||||
continue;
|
||||
}
|
||||
|
||||
InnerNode *child = (InnerNode *)parent->children[c];
|
||||
InnerNode *child = (InnerNode *)parent->children[c].get();
|
||||
const BoundBox &other = (c == 0) ? bounds1 : bounds0;
|
||||
|
||||
/* transpose child bounds */
|
||||
@@ -1272,7 +1285,7 @@ void BVHBuild::rotate(BVHNode *node, const int max_depth)
|
||||
assert(best_target != -1);
|
||||
|
||||
/* perform the best found tree rotation */
|
||||
InnerNode *child = (InnerNode *)parent->children[best_child];
|
||||
InnerNode *child = (InnerNode *)parent->children[best_child].get();
|
||||
|
||||
swap(parent->children[best_other], child->children[best_target]);
|
||||
child->bounds = merge(child->children[0]->bounds, child->children[1]->bounds);
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include "util/array.h"
|
||||
#include "util/task.h"
|
||||
#include "util/unique_ptr.h"
|
||||
#include "util/vector.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
@@ -45,7 +46,7 @@ class BVHBuild {
|
||||
Progress &progress);
|
||||
~BVHBuild();
|
||||
|
||||
BVHNode *run();
|
||||
unique_ptr<BVHNode> run();
|
||||
|
||||
protected:
|
||||
friend class BVHMixedSplit;
|
||||
@@ -70,13 +71,16 @@ class BVHBuild {
|
||||
void add_references(BVHRange &root);
|
||||
|
||||
/* Building. */
|
||||
BVHNode *build_node(const BVHRange &range,
|
||||
vector<BVHReference> &references,
|
||||
const int level,
|
||||
BVHSpatialStorage *storage);
|
||||
BVHNode *build_node(const BVHObjectBinning &range, const int level);
|
||||
BVHNode *create_leaf_node(const BVHRange &range, const vector<BVHReference> &references);
|
||||
BVHNode *create_object_leaf_nodes(const BVHReference *ref, const int start, const int num);
|
||||
unique_ptr<BVHNode> build_node(const BVHRange &range,
|
||||
vector<BVHReference> &references,
|
||||
const int level,
|
||||
BVHSpatialStorage *storage);
|
||||
unique_ptr<BVHNode> build_node(const BVHObjectBinning &range, const int level);
|
||||
unique_ptr<BVHNode> create_leaf_node(const BVHRange &range,
|
||||
const vector<BVHReference> &references);
|
||||
unique_ptr<BVHNode> create_object_leaf_nodes(const BVHReference *ref,
|
||||
const int start,
|
||||
const int num);
|
||||
|
||||
bool range_within_max_leaf_size(const BVHRange &range,
|
||||
const vector<BVHReference> &references) const;
|
||||
|
||||
@@ -94,24 +94,24 @@ BVH::BVH(const BVHParams ¶ms_,
|
||||
{
|
||||
}
|
||||
|
||||
BVH *BVH::create(const BVHParams ¶ms,
|
||||
const vector<Geometry *> &geometry,
|
||||
const vector<Object *> &objects,
|
||||
Device *device)
|
||||
unique_ptr<BVH> BVH::create(const BVHParams ¶ms,
|
||||
const vector<Geometry *> &geometry,
|
||||
const vector<Object *> &objects,
|
||||
Device *device)
|
||||
{
|
||||
switch (params.bvh_layout) {
|
||||
case BVH_LAYOUT_BVH2:
|
||||
return new BVH2(params, geometry, objects);
|
||||
return make_unique<BVH2>(params, geometry, objects);
|
||||
case BVH_LAYOUT_EMBREE:
|
||||
case BVH_LAYOUT_EMBREEGPU:
|
||||
#ifdef WITH_EMBREE
|
||||
return new BVHEmbree(params, geometry, objects);
|
||||
return make_unique<BVHEmbree>(params, geometry, objects);
|
||||
#else
|
||||
break;
|
||||
#endif
|
||||
case BVH_LAYOUT_OPTIX:
|
||||
#ifdef WITH_OPTIX
|
||||
return new BVHOptiX(params, geometry, objects, device);
|
||||
return make_unique<BVHOptiX>(params, geometry, objects, device);
|
||||
#else
|
||||
(void)device;
|
||||
break;
|
||||
@@ -125,7 +125,7 @@ BVH *BVH::create(const BVHParams ¶ms,
|
||||
#endif
|
||||
case BVH_LAYOUT_HIPRT:
|
||||
#ifdef WITH_HIPRT
|
||||
return new BVHHIPRT(params, geometry, objects, device);
|
||||
return make_unique<BVHHIPRT>(params, geometry, objects, device);
|
||||
#else
|
||||
(void)device;
|
||||
break;
|
||||
@@ -138,7 +138,7 @@ BVH *BVH::create(const BVHParams ¶ms,
|
||||
case BVH_LAYOUT_MULTI_METAL_EMBREE:
|
||||
case BVH_LAYOUT_MULTI_HIPRT_EMBREE:
|
||||
case BVH_LAYOUT_MULTI_EMBREEGPU_EMBREE:
|
||||
return new BVHMulti(params, geometry, objects);
|
||||
return make_unique<BVHMulti>(params, geometry, objects);
|
||||
case BVH_LAYOUT_NONE:
|
||||
case BVH_LAYOUT_ALL:
|
||||
break;
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "bvh/params.h"
|
||||
#include "util/array.h"
|
||||
#include "util/types.h"
|
||||
#include "util/unique_ptr.h"
|
||||
#include "util/vector.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
@@ -69,10 +70,10 @@ class BVH {
|
||||
vector<Geometry *> geometry;
|
||||
vector<Object *> objects;
|
||||
|
||||
static BVH *create(const BVHParams ¶ms,
|
||||
const vector<Geometry *> &geometry,
|
||||
const vector<Object *> &objects,
|
||||
Device *device);
|
||||
static unique_ptr<BVH> create(const BVHParams ¶ms,
|
||||
const vector<Geometry *> &geometry,
|
||||
const vector<Object *> &objects,
|
||||
Device *device);
|
||||
virtual ~BVH() = default;
|
||||
|
||||
virtual void replace_geometry(const vector<Geometry *> &geometry,
|
||||
|
||||
@@ -48,26 +48,17 @@ void BVH2::build(Progress &progress, Stats * /*unused*/)
|
||||
pack.prim_time,
|
||||
params,
|
||||
progress);
|
||||
BVHNode *bvh2_root = bvh_build.run();
|
||||
unique_ptr<BVHNode> bvh2_root = bvh_build.run();
|
||||
|
||||
if (progress.get_cancel()) {
|
||||
if (bvh2_root != nullptr) {
|
||||
bvh2_root->deleteSubtree();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* BVH builder returns tree in a binary mode (with two children per inner
|
||||
* node. Need to adopt that for a wider BVH implementations. */
|
||||
BVHNode *root = widen_children_nodes(bvh2_root);
|
||||
if (root != bvh2_root) {
|
||||
bvh2_root->deleteSubtree();
|
||||
}
|
||||
const unique_ptr<BVHNode> root = widen_children_nodes(std::move(bvh2_root));
|
||||
|
||||
if (progress.get_cancel()) {
|
||||
if (root != nullptr) {
|
||||
root->deleteSubtree();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -76,16 +67,12 @@ void BVH2::build(Progress &progress, Stats * /*unused*/)
|
||||
pack_primitives();
|
||||
|
||||
if (progress.get_cancel()) {
|
||||
root->deleteSubtree();
|
||||
return;
|
||||
}
|
||||
|
||||
/* pack nodes */
|
||||
progress.set_substatus("Packing BVH nodes");
|
||||
pack_nodes(root);
|
||||
|
||||
/* free build nodes */
|
||||
root->deleteSubtree();
|
||||
pack_nodes(root.get());
|
||||
}
|
||||
|
||||
void BVH2::refit(Progress &progress)
|
||||
@@ -101,9 +88,9 @@ void BVH2::refit(Progress &progress)
|
||||
refit_nodes();
|
||||
}
|
||||
|
||||
BVHNode *BVH2::widen_children_nodes(const BVHNode *root)
|
||||
unique_ptr<BVHNode> BVH2::widen_children_nodes(unique_ptr<BVHNode> &&root)
|
||||
{
|
||||
return const_cast<BVHNode *>(root);
|
||||
return std::move(root);
|
||||
}
|
||||
|
||||
void BVH2::pack_leaf(const BVHStackEntry &e, const LeafNode *leaf)
|
||||
@@ -508,7 +495,7 @@ void BVH2::pack_instances(size_t nodes_size, size_t leaf_nodes_size)
|
||||
size_t object_offset = 0;
|
||||
|
||||
for (Geometry *geom : geometry) {
|
||||
BVH2 *bvh = static_cast<BVH2 *>(geom->bvh);
|
||||
BVH2 *bvh = static_cast<BVH2 *>(geom->bvh.get());
|
||||
|
||||
if (geom->need_build_bvh(params.bvh_layout)) {
|
||||
prim_index_size += bvh->pack.prim_index.size();
|
||||
@@ -564,7 +551,7 @@ void BVH2::pack_instances(size_t nodes_size, size_t leaf_nodes_size)
|
||||
continue;
|
||||
}
|
||||
|
||||
BVH2 *bvh = static_cast<BVH2 *>(geom->bvh);
|
||||
BVH2 *bvh = static_cast<BVH2 *>(geom->bvh.get());
|
||||
|
||||
const int noffset = nodes_offset;
|
||||
const int noffset_leaf = nodes_leaf_offset;
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "bvh/params.h"
|
||||
|
||||
#include "util/types.h"
|
||||
#include "util/unique_ptr.h"
|
||||
#include "util/vector.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
@@ -36,20 +37,18 @@ struct BVHStackEntry {
|
||||
*/
|
||||
class BVH2 : public BVH {
|
||||
public:
|
||||
BVH2(const BVHParams ¶ms,
|
||||
const vector<Geometry *> &geometry,
|
||||
const vector<Object *> &objects);
|
||||
|
||||
void build(Progress &progress, Stats *stats);
|
||||
void refit(Progress &progress);
|
||||
|
||||
PackedBVH pack;
|
||||
|
||||
protected:
|
||||
/* constructor */
|
||||
friend class BVH;
|
||||
BVH2(const BVHParams ¶ms,
|
||||
const vector<Geometry *> &geometry,
|
||||
const vector<Object *> &objects);
|
||||
|
||||
/* Building process. */
|
||||
virtual BVHNode *widen_children_nodes(const BVHNode *root);
|
||||
virtual unique_ptr<BVHNode> widen_children_nodes(unique_ptr<BVHNode> &&root);
|
||||
|
||||
/* pack */
|
||||
void pack_nodes(const BVHNode *root);
|
||||
|
||||
@@ -252,7 +252,7 @@ void BVHEmbree::add_object(Object *ob, const int i)
|
||||
|
||||
void BVHEmbree::add_instance(Object *ob, const int i)
|
||||
{
|
||||
BVHEmbree *instance_bvh = (BVHEmbree *)(ob->get_geometry()->bvh);
|
||||
BVHEmbree *instance_bvh = static_cast<BVHEmbree *>(ob->get_geometry()->bvh.get());
|
||||
assert(instance_bvh != nullptr);
|
||||
|
||||
const size_t num_object_motion_steps = ob->use_motion() ? ob->get_motion().size() : 1;
|
||||
|
||||
@@ -41,8 +41,6 @@ class BVHEmbree : public BVH {
|
||||
|
||||
RTCScene scene;
|
||||
|
||||
protected:
|
||||
friend class BVH;
|
||||
BVHEmbree(const BVHParams ¶ms,
|
||||
const vector<Geometry *> &geometry,
|
||||
const vector<Object *> &objects);
|
||||
|
||||
@@ -41,8 +41,6 @@ class BVHHIPRT : public BVH {
|
||||
device_vector<int> triangle_index;
|
||||
device_vector<float> vertex_data;
|
||||
|
||||
protected:
|
||||
friend class BVH;
|
||||
BVHHIPRT(const BVHParams ¶ms,
|
||||
const vector<Geometry *> &geometry,
|
||||
const vector<Object *> &objects,
|
||||
|
||||
@@ -8,12 +8,14 @@
|
||||
|
||||
# include "bvh/bvh.h"
|
||||
|
||||
# include "util/unique_ptr.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
BVH *bvh_metal_create(const BVHParams ¶ms,
|
||||
const vector<Geometry *> &geometry,
|
||||
const vector<Object *> &objects,
|
||||
Device *device);
|
||||
unique_ptr<BVH> bvh_metal_create(const BVHParams ¶ms,
|
||||
const vector<Geometry *> &geometry,
|
||||
const vector<Object *> &objects,
|
||||
Device *device);
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
|
||||
@@ -6,14 +6,16 @@
|
||||
|
||||
# include "device/metal/bvh.h"
|
||||
|
||||
# include "util/unique_ptr.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
BVH *bvh_metal_create(const BVHParams ¶ms,
|
||||
const vector<Geometry *> &geometry,
|
||||
const vector<Object *> &objects,
|
||||
Device *device)
|
||||
unique_ptr<BVH> bvh_metal_create(const BVHParams ¶ms,
|
||||
const vector<Geometry *> &geometry,
|
||||
const vector<Object *> &objects,
|
||||
Device *device)
|
||||
{
|
||||
return new BVHMetal(params, geometry, objects, device);
|
||||
return make_unique<BVHMetal>(params, geometry, objects, device);
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
@@ -13,17 +13,10 @@ BVHMulti::BVHMulti(const BVHParams ¶ms_,
|
||||
{
|
||||
}
|
||||
|
||||
BVHMulti::~BVHMulti()
|
||||
{
|
||||
for (BVH *bvh : sub_bvhs) {
|
||||
delete bvh;
|
||||
}
|
||||
}
|
||||
|
||||
void BVHMulti::replace_geometry(const vector<Geometry *> &geometry,
|
||||
const vector<Object *> &objects)
|
||||
{
|
||||
for (BVH *bvh : sub_bvhs) {
|
||||
for (unique_ptr<BVH> &bvh : sub_bvhs) {
|
||||
bvh->replace_geometry(geometry, objects);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,19 +7,20 @@
|
||||
#include "bvh/bvh.h"
|
||||
#include "bvh/params.h"
|
||||
|
||||
#include <util/unique_ptr.h>
|
||||
#include <util/vector.h>
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
class BVHMulti : public BVH {
|
||||
public:
|
||||
vector<BVH *> sub_bvhs;
|
||||
vector<unique_ptr<BVH>> sub_bvhs;
|
||||
|
||||
protected:
|
||||
friend class BVH;
|
||||
BVHMulti(const BVHParams ¶ms,
|
||||
const vector<Geometry *> &geometry,
|
||||
const vector<Object *> &objects);
|
||||
~BVHMulti() override;
|
||||
|
||||
protected:
|
||||
void replace_geometry(const vector<Geometry *> &geometry,
|
||||
const vector<Object *> &objects) override;
|
||||
};
|
||||
|
||||
@@ -92,17 +92,6 @@ int BVHNode::getSubtreeSize(BVH_STAT stat) const
|
||||
return cnt;
|
||||
}
|
||||
|
||||
void BVHNode::deleteSubtree()
|
||||
{
|
||||
for (int i = 0; i < num_children(); i++) {
|
||||
if (get_child(i)) {
|
||||
get_child(i)->deleteSubtree();
|
||||
}
|
||||
}
|
||||
|
||||
delete this;
|
||||
}
|
||||
|
||||
float BVHNode::computeSubtreeSAHCost(const BVHParams &p, const float probability) const
|
||||
{
|
||||
float SAH = probability * p.cost(num_children(), num_triangles());
|
||||
@@ -120,8 +109,8 @@ uint BVHNode::update_visibility()
|
||||
{
|
||||
if (!is_leaf() && visibility == 0) {
|
||||
InnerNode *inner = (InnerNode *)this;
|
||||
BVHNode *child0 = inner->children[0];
|
||||
BVHNode *child1 = inner->children[1];
|
||||
BVHNode *child0 = inner->children[0].get();
|
||||
BVHNode *child1 = inner->children[1].get();
|
||||
|
||||
visibility = child0->update_visibility() | child1->update_visibility();
|
||||
}
|
||||
@@ -133,8 +122,8 @@ void BVHNode::update_time()
|
||||
{
|
||||
if (!is_leaf()) {
|
||||
InnerNode *inner = (InnerNode *)this;
|
||||
BVHNode *child0 = inner->children[0];
|
||||
BVHNode *child1 = inner->children[1];
|
||||
BVHNode *child0 = inner->children[0].get();
|
||||
BVHNode *child1 = inner->children[1].get();
|
||||
child0->update_time();
|
||||
child1->update_time();
|
||||
time_from = min(child0->time_from, child1->time_from);
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include "util/boundbox.h"
|
||||
#include "util/types.h"
|
||||
#include "util/unique_ptr.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
@@ -31,10 +32,7 @@ class BVHParams;
|
||||
|
||||
class BVHNode {
|
||||
public:
|
||||
virtual ~BVHNode()
|
||||
{
|
||||
delete aligned_space;
|
||||
}
|
||||
virtual ~BVHNode() = default;
|
||||
|
||||
virtual bool is_leaf() const = 0;
|
||||
virtual int num_children() const = 0;
|
||||
@@ -49,7 +47,7 @@ class BVHNode {
|
||||
{
|
||||
is_unaligned = true;
|
||||
if (this->aligned_space == nullptr) {
|
||||
this->aligned_space = new Transform(aligned_space);
|
||||
this->aligned_space = make_unique<Transform>(aligned_space);
|
||||
}
|
||||
else {
|
||||
*this->aligned_space = aligned_space;
|
||||
@@ -80,7 +78,6 @@ class BVHNode {
|
||||
// Subtree functions
|
||||
int getSubtreeSize(BVH_STAT stat = BVH_STAT_NODE_COUNT) const;
|
||||
float computeSubtreeSAHCost(const BVHParams &p, const float probability = 1.0f) const;
|
||||
void deleteSubtree();
|
||||
|
||||
uint update_visibility();
|
||||
void update_time();
|
||||
@@ -97,7 +94,7 @@ class BVHNode {
|
||||
/* TODO(sergey): Can be stored as 3x3 matrix, but better to have some
|
||||
* utilities and type defines in util_transform first.
|
||||
*/
|
||||
Transform *aligned_space = nullptr;
|
||||
unique_ptr<Transform> aligned_space;
|
||||
|
||||
float time_from = 0.0f, time_to = 1.0f;
|
||||
|
||||
@@ -114,8 +111,7 @@ class BVHNode {
|
||||
{
|
||||
if (other.aligned_space != nullptr) {
|
||||
assert(other.is_unaligned);
|
||||
aligned_space = new Transform();
|
||||
*aligned_space = *other.aligned_space;
|
||||
aligned_space = make_unique<Transform>(*other.aligned_space);
|
||||
}
|
||||
else {
|
||||
assert(!other.is_unaligned);
|
||||
@@ -127,13 +123,9 @@ class InnerNode : public BVHNode {
|
||||
public:
|
||||
static constexpr int kNumMaxChildren = 8;
|
||||
|
||||
InnerNode(const BoundBox &bounds, BVHNode *child0, BVHNode *child1)
|
||||
InnerNode(const BoundBox &bounds, unique_ptr<BVHNode> &&child0, unique_ptr<BVHNode> &&child1)
|
||||
: BVHNode(bounds), num_children_(2)
|
||||
{
|
||||
children[0] = child0;
|
||||
children[1] = child1;
|
||||
reset_unused_children();
|
||||
|
||||
if (child0 && child1) {
|
||||
visibility = child0->visibility | child1->visibility;
|
||||
}
|
||||
@@ -141,30 +133,16 @@ class InnerNode : public BVHNode {
|
||||
/* Happens on build cancel. */
|
||||
visibility = 0;
|
||||
}
|
||||
}
|
||||
|
||||
InnerNode(const BoundBox &bounds, BVHNode **children, const int num_children)
|
||||
: BVHNode(bounds), num_children_(num_children)
|
||||
{
|
||||
visibility = 0;
|
||||
time_from = FLT_MAX;
|
||||
time_to = -FLT_MAX;
|
||||
for (int i = 0; i < num_children; ++i) {
|
||||
assert(children[i] != nullptr);
|
||||
visibility |= children[i]->visibility;
|
||||
this->children[i] = children[i];
|
||||
time_from = min(time_from, children[i]->time_from);
|
||||
time_to = max(time_to, children[i]->time_to);
|
||||
}
|
||||
reset_unused_children();
|
||||
children[0] = std::move(child0);
|
||||
children[1] = std::move(child1);
|
||||
}
|
||||
|
||||
/* NOTE: This function is only used during binary BVH builder, and it's
|
||||
* supposed to be configured to have 2 children which will be filled-in in a
|
||||
* bit. But this is important to have children reset to nullptr. */
|
||||
* bit. */
|
||||
explicit InnerNode(const BoundBox &bounds) : BVHNode(bounds), num_children_(0)
|
||||
{
|
||||
reset_unused_children();
|
||||
visibility = 0;
|
||||
num_children_ = 2;
|
||||
}
|
||||
@@ -180,20 +158,12 @@ class InnerNode : public BVHNode {
|
||||
BVHNode *get_child(const int i) const override
|
||||
{
|
||||
assert(i >= 0 && i < num_children_);
|
||||
return children[i];
|
||||
return children[i].get();
|
||||
}
|
||||
void print(const int depth) const override;
|
||||
|
||||
int num_children_;
|
||||
BVHNode *children[kNumMaxChildren];
|
||||
|
||||
protected:
|
||||
void reset_unused_children()
|
||||
{
|
||||
for (int i = num_children_; i < kNumMaxChildren; ++i) {
|
||||
children[i] = nullptr;
|
||||
}
|
||||
}
|
||||
unique_ptr<BVHNode> children[kNumMaxChildren];
|
||||
};
|
||||
|
||||
class LeafNode : public BVHNode {
|
||||
|
||||
@@ -23,8 +23,6 @@ class BVHOptiX : public BVH {
|
||||
unique_ptr<device_only_memory<char>> as_data;
|
||||
unique_ptr<device_only_memory<char>> motion_transform_data;
|
||||
|
||||
protected:
|
||||
friend class BVH;
|
||||
BVHOptiX(const BVHParams ¶ms,
|
||||
const vector<Geometry *> &geometry,
|
||||
const vector<Object *> &objects,
|
||||
|
||||
@@ -13,9 +13,12 @@
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
Device *device_cpu_create(const DeviceInfo &info, Stats &stats, Profiler &profiler, bool headless)
|
||||
unique_ptr<Device> device_cpu_create(const DeviceInfo &info,
|
||||
Stats &stats,
|
||||
Profiler &profiler,
|
||||
bool headless)
|
||||
{
|
||||
return new CPUDevice(info, stats, profiler, headless);
|
||||
return make_unique<CPUDevice>(info, stats, profiler, headless);
|
||||
}
|
||||
|
||||
void device_cpu_info(vector<DeviceInfo> &devices)
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "util/string.h"
|
||||
#include "util/unique_ptr.h"
|
||||
#include "util/vector.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
@@ -14,7 +15,10 @@ class DeviceInfo;
|
||||
class Profiler;
|
||||
class Stats;
|
||||
|
||||
Device *device_cpu_create(const DeviceInfo &info, Stats &stats, Profiler &profiler, bool headless);
|
||||
unique_ptr<Device> device_cpu_create(const DeviceInfo &info,
|
||||
Stats &stats,
|
||||
Profiler &profiler,
|
||||
bool headless);
|
||||
|
||||
void device_cpu_info(vector<DeviceInfo> &devices);
|
||||
|
||||
|
||||
@@ -62,10 +62,13 @@ bool device_cuda_init()
|
||||
#endif /* WITH_CUDA_DYNLOAD */
|
||||
}
|
||||
|
||||
Device *device_cuda_create(const DeviceInfo &info, Stats &stats, Profiler &profiler, bool headless)
|
||||
unique_ptr<Device> device_cuda_create(const DeviceInfo &info,
|
||||
Stats &stats,
|
||||
Profiler &profiler,
|
||||
bool headless)
|
||||
{
|
||||
#ifdef WITH_CUDA
|
||||
return new CUDADevice(info, stats, profiler, headless);
|
||||
return make_unique<CUDADevice>(info, stats, profiler, headless);
|
||||
#else
|
||||
(void)info;
|
||||
(void)stats;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "util/string.h"
|
||||
#include "util/unique_ptr.h"
|
||||
#include "util/vector.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
@@ -16,10 +17,10 @@ class Stats;
|
||||
|
||||
bool device_cuda_init();
|
||||
|
||||
Device *device_cuda_create(const DeviceInfo &info,
|
||||
Stats &stats,
|
||||
Profiler &profiler,
|
||||
bool headless);
|
||||
unique_ptr<Device> device_cuda_create(const DeviceInfo &info,
|
||||
Stats &stats,
|
||||
Profiler &profiler,
|
||||
bool headless);
|
||||
|
||||
void device_cuda_info(vector<DeviceInfo> &devices);
|
||||
|
||||
|
||||
@@ -62,7 +62,10 @@ void Device::build_bvh(BVH *bvh, Progress &progress, bool refit)
|
||||
}
|
||||
}
|
||||
|
||||
Device *Device::create(const DeviceInfo &info, Stats &stats, Profiler &profiler, bool headless)
|
||||
unique_ptr<Device> Device::create(const DeviceInfo &info,
|
||||
Stats &stats,
|
||||
Profiler &profiler,
|
||||
bool headless)
|
||||
{
|
||||
if (!info.multi_devices.empty()) {
|
||||
/* Always create a multi device when info contains multiple devices.
|
||||
@@ -71,7 +74,7 @@ Device *Device::create(const DeviceInfo &info, Stats &stats, Profiler &profiler,
|
||||
return device_multi_create(info, stats, profiler, headless);
|
||||
}
|
||||
|
||||
Device *device = nullptr;
|
||||
unique_ptr<Device> device;
|
||||
|
||||
switch (info.type) {
|
||||
case DEVICE_CPU:
|
||||
|
||||
@@ -287,7 +287,10 @@ class Device {
|
||||
}
|
||||
|
||||
/* static */
|
||||
static Device *create(const DeviceInfo &info, Stats &stats, Profiler &profiler, bool headless);
|
||||
static unique_ptr<Device> create(const DeviceInfo &info,
|
||||
Stats &stats,
|
||||
Profiler &profiler,
|
||||
bool headless);
|
||||
|
||||
static DeviceType type_from_string(const char *name);
|
||||
static string string_from_type(DeviceType type);
|
||||
|
||||
@@ -42,12 +42,12 @@ class DummyDevice : public Device {
|
||||
void const_copy_to(const char * /*name*/, void * /*host*/, size_t /*size*/) override {}
|
||||
};
|
||||
|
||||
Device *device_dummy_create(const DeviceInfo &info,
|
||||
Stats &stats,
|
||||
Profiler &profiler,
|
||||
bool headless)
|
||||
unique_ptr<Device> device_dummy_create(const DeviceInfo &info,
|
||||
Stats &stats,
|
||||
Profiler &profiler,
|
||||
bool headless)
|
||||
{
|
||||
return new DummyDevice(info, stats, profiler, headless);
|
||||
return make_unique<DummyDevice>(info, stats, profiler, headless);
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "util/unique_ptr.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
class Device;
|
||||
@@ -11,9 +13,9 @@ class DeviceInfo;
|
||||
class Profiler;
|
||||
class Stats;
|
||||
|
||||
Device *device_dummy_create(const DeviceInfo &info,
|
||||
Stats &stats,
|
||||
Profiler &profiler,
|
||||
bool headless);
|
||||
unique_ptr<Device> device_dummy_create(const DeviceInfo &info,
|
||||
Stats &stats,
|
||||
Profiler &profiler,
|
||||
bool headless);
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
@@ -73,18 +73,18 @@ bool device_hip_init()
|
||||
#endif /* WITH_HIP_DYNLOAD */
|
||||
}
|
||||
|
||||
Device *device_hip_create(const DeviceInfo &info,
|
||||
Stats &stats,
|
||||
Profiler &profiler,
|
||||
const bool headless)
|
||||
unique_ptr<Device> device_hip_create(const DeviceInfo &info,
|
||||
Stats &stats,
|
||||
Profiler &profiler,
|
||||
const bool headless)
|
||||
{
|
||||
#ifdef WITH_HIPRT
|
||||
if (info.use_hardware_raytracing) {
|
||||
return new HIPRTDevice(info, stats, profiler, headless);
|
||||
return make_unique<HIPRTDevice>(info, stats, profiler, headless);
|
||||
}
|
||||
return new HIPDevice(info, stats, profiler, headless);
|
||||
return make_unique<HIPDevice>(info, stats, profiler, headless);
|
||||
#elif defined(WITH_HIP)
|
||||
return new HIPDevice(info, stats, profiler, headless);
|
||||
return make_unique<HIPDevice>(info, stats, profiler, headless);
|
||||
#else
|
||||
(void)info;
|
||||
(void)stats;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "util/string.h"
|
||||
#include "util/unique_ptr.h"
|
||||
#include "util/vector.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
@@ -16,7 +17,10 @@ class Stats;
|
||||
|
||||
bool device_hip_init();
|
||||
|
||||
Device *device_hip_create(const DeviceInfo &info, Stats &stats, Profiler &profiler, bool headless);
|
||||
unique_ptr<Device> device_hip_create(const DeviceInfo &info,
|
||||
Stats &stats,
|
||||
Profiler &profiler,
|
||||
bool headless);
|
||||
|
||||
void device_hip_info(vector<DeviceInfo> &devices);
|
||||
|
||||
|
||||
@@ -894,7 +894,7 @@ hiprtScene HIPRTDevice::build_tlas(BVHHIPRT *bvh,
|
||||
Geometry *geom = ob->get_geometry();
|
||||
bool transform_applied = geom->transform_applied;
|
||||
|
||||
BVHHIPRT *current_bvh = static_cast<BVHHIPRT *>(geom->bvh);
|
||||
BVHHIPRT *current_bvh = static_cast<BVHHIPRT *>(geom->bvh.get());
|
||||
bool is_valid_geometry = current_bvh->geom_input.geomType != hiprtInvalidValue;
|
||||
hiprtGeometry hiprt_geom_current = current_bvh->hiprt_geom;
|
||||
|
||||
|
||||
@@ -1101,7 +1101,7 @@ bool BVHMetal::build_TLAS(Progress &progress,
|
||||
for (Object *ob : objects) {
|
||||
/* Skip non-traceable objects */
|
||||
const Geometry *geom = ob->get_geometry();
|
||||
const BVHMetal *blas = static_cast<const BVHMetal *>(geom->bvh);
|
||||
const BVHMetal *blas = static_cast<const BVHMetal *>(geom->bvh.get());
|
||||
if (!blas || !blas->accel_struct || !ob->is_traceable()) {
|
||||
/* Place a degenerate instance, to ensure [[instance_id]] equals ob->get_device_index()
|
||||
* in our intersection functions */
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "util/string.h"
|
||||
#include "util/unique_ptr.h"
|
||||
#include "util/vector.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
@@ -17,10 +18,10 @@ class Stats;
|
||||
bool device_metal_init();
|
||||
void device_metal_exit();
|
||||
|
||||
Device *device_metal_create(const DeviceInfo &info,
|
||||
Stats &stats,
|
||||
Profiler &profiler,
|
||||
bool headless);
|
||||
unique_ptr<Device> device_metal_create(const DeviceInfo &info,
|
||||
Stats &stats,
|
||||
Profiler &profiler,
|
||||
bool headless);
|
||||
|
||||
void device_metal_info(vector<DeviceInfo> &devices);
|
||||
|
||||
|
||||
@@ -20,12 +20,12 @@ CCL_NAMESPACE_BEGIN
|
||||
|
||||
#ifdef WITH_METAL
|
||||
|
||||
Device *device_metal_create(const DeviceInfo &info,
|
||||
Stats &stats,
|
||||
Profiler &profiler,
|
||||
bool headless)
|
||||
unique_ptr<Device> device_metal_create(const DeviceInfo &info,
|
||||
Stats &stats,
|
||||
Profiler &profiler,
|
||||
bool headless)
|
||||
{
|
||||
return new MetalDevice(info, stats, profiler, headless);
|
||||
return make_unique<MetalDevice>(info, stats, profiler, headless);
|
||||
}
|
||||
|
||||
bool device_metal_init()
|
||||
@@ -131,9 +131,9 @@ string device_metal_capabilities()
|
||||
|
||||
#else
|
||||
|
||||
Device *device_metal_create(const DeviceInfo & /*info*/,
|
||||
Stats & /*stats*/,
|
||||
Profiler & /*profiler*/)
|
||||
unique_ptr<Device> device_metal_create(const DeviceInfo & /*info*/,
|
||||
Stats & /*stats*/,
|
||||
Profiler & /*profiler*/)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -708,8 +708,7 @@ MetalDevice::MetalMem *MetalDevice::generic_alloc(device_memory &mem)
|
||||
std::lock_guard<std::recursive_mutex> lock(metal_mem_map_mutex);
|
||||
|
||||
assert(metal_mem_map.count(&mem) == 0); /* assert against double-alloc */
|
||||
MetalMem *mmem = new MetalMem;
|
||||
metal_mem_map[&mem] = std::unique_ptr<MetalMem>(mmem);
|
||||
unique_ptr<MetalMem> mmem = make_unique<MetalMem>();
|
||||
|
||||
mmem->mem = &mem;
|
||||
mmem->mtlBuffer = metal_buffer;
|
||||
@@ -724,7 +723,7 @@ MetalDevice::MetalMem *MetalDevice::generic_alloc(device_memory &mem)
|
||||
|
||||
/* encode device_pointer as (MetalMem*) in order to handle resource relocation and device
|
||||
* pointer recalculation */
|
||||
mem.device_pointer = device_ptr(mmem);
|
||||
mem.device_pointer = device_ptr(mmem.get());
|
||||
|
||||
if (metal_buffer.storageMode == MTLResourceStorageModeShared) {
|
||||
/* Replace host pointer with our host allocation. */
|
||||
@@ -743,12 +742,15 @@ MetalDevice::MetalMem *MetalDevice::generic_alloc(device_memory &mem)
|
||||
mmem->use_UMA = false;
|
||||
}
|
||||
|
||||
MetalMem *mmem_ptr = mmem.get();
|
||||
metal_mem_map[&mem] = std::move(mmem);
|
||||
|
||||
if (max_working_set_exceeded()) {
|
||||
set_error("System is out of GPU memory");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return mmem;
|
||||
return mmem_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1252,10 +1254,10 @@ void MetalDevice::tex_alloc(device_texture &mem)
|
||||
stats.mem_alloc(size);
|
||||
|
||||
std::lock_guard<std::recursive_mutex> lock(metal_mem_map_mutex);
|
||||
MetalMem *mmem = new MetalMem;
|
||||
metal_mem_map[&mem] = std::unique_ptr<MetalMem>(mmem);
|
||||
unique_ptr<MetalMem> mmem = make_unique<MetalMem>();
|
||||
mmem->mem = &mem;
|
||||
mmem->mtlTexture = mtlTexture;
|
||||
metal_mem_map[&mem] = std::move(mmem);
|
||||
|
||||
/* Resize once */
|
||||
const uint slot = mem.slot;
|
||||
|
||||
@@ -130,7 +130,7 @@ struct ShaderCache {
|
||||
|
||||
static bool running;
|
||||
std::condition_variable cond_var;
|
||||
std::deque<MetalKernelPipeline *> request_queue;
|
||||
std::deque<unique_ptr<MetalKernelPipeline>> request_queue;
|
||||
std::vector<std::thread> compile_threads;
|
||||
std::atomic_int incomplete_requests = 0;
|
||||
std::atomic_int incomplete_specialization_requests = 0;
|
||||
@@ -190,7 +190,7 @@ void ShaderCache::compile_thread_func()
|
||||
while (running) {
|
||||
|
||||
/* wait for / acquire next request */
|
||||
MetalKernelPipeline *pipeline;
|
||||
unique_ptr<MetalKernelPipeline> pipeline;
|
||||
{
|
||||
thread_scoped_lock lock(cache_mutex);
|
||||
cond_var.wait(lock, [&] { return !running || !request_queue.empty(); });
|
||||
@@ -198,7 +198,7 @@ void ShaderCache::compile_thread_func()
|
||||
continue;
|
||||
}
|
||||
|
||||
pipeline = request_queue.front();
|
||||
pipeline = std::move(request_queue.front());
|
||||
request_queue.pop_front();
|
||||
}
|
||||
|
||||
@@ -233,7 +233,7 @@ void ShaderCache::compile_thread_func()
|
||||
}
|
||||
}
|
||||
}
|
||||
collection.push_back(unique_ptr<MetalKernelPipeline>(pipeline));
|
||||
collection.push_back(std::move(pipeline));
|
||||
}
|
||||
incomplete_requests--;
|
||||
if (pso_type != PSO_GENERIC) {
|
||||
@@ -334,7 +334,7 @@ void ShaderCache::load_kernel(DeviceKernel device_kernel,
|
||||
incomplete_specialization_requests++;
|
||||
}
|
||||
|
||||
MetalKernelPipeline *pipeline = new MetalKernelPipeline;
|
||||
unique_ptr<MetalKernelPipeline> pipeline = make_unique<MetalKernelPipeline>();
|
||||
|
||||
/* Keep track of the originating device's ID so that we can cancel requests if the device ceases
|
||||
* to be active. */
|
||||
@@ -359,7 +359,7 @@ void ShaderCache::load_kernel(DeviceKernel device_kernel,
|
||||
|
||||
{
|
||||
thread_scoped_lock lock(cache_mutex);
|
||||
request_queue.push_back(pipeline);
|
||||
request_queue.push_back(std::move(pipeline));
|
||||
}
|
||||
cond_var.notify_one();
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ class MultiDevice : public Device {
|
||||
public:
|
||||
struct SubDevice {
|
||||
Stats stats;
|
||||
Device *device;
|
||||
unique_ptr<Device> device;
|
||||
map<device_ptr, device_ptr> ptr_map;
|
||||
int peer_island_index = -1;
|
||||
};
|
||||
@@ -70,7 +70,7 @@ class MultiDevice : public Device {
|
||||
for (SubDevice &peer_sub : devices) {
|
||||
if (peer_sub.peer_island_index < 0 &&
|
||||
peer_sub.device->info.type == sub.device->info.type &&
|
||||
peer_sub.device->check_peer_access(sub.device))
|
||||
peer_sub.device->check_peer_access(sub.device.get()))
|
||||
{
|
||||
peer_sub.peer_island_index = sub.peer_island_index;
|
||||
peer_islands[sub.peer_island_index].push_back(&peer_sub);
|
||||
@@ -79,13 +79,6 @@ class MultiDevice : public Device {
|
||||
}
|
||||
}
|
||||
|
||||
~MultiDevice() override
|
||||
{
|
||||
for (SubDevice &sub : devices) {
|
||||
delete sub.device;
|
||||
}
|
||||
}
|
||||
|
||||
const string &error_message() override
|
||||
{
|
||||
error_msg.clear();
|
||||
@@ -191,10 +184,12 @@ class MultiDevice : public Device {
|
||||
BVHMulti *const bvh_multi = static_cast<BVHMulti *>(bvh);
|
||||
bvh_multi->sub_bvhs.resize(devices.size());
|
||||
|
||||
vector<BVHMulti *> geom_bvhs;
|
||||
/* Temporarily move ownership of BVH on geometry to this vector, to swap
|
||||
* it for each sub device. Need to find a better way to handle this. */
|
||||
vector<unique_ptr<BVH>> geom_bvhs;
|
||||
geom_bvhs.reserve(bvh->geometry.size());
|
||||
for (Geometry *geom : bvh->geometry) {
|
||||
geom_bvhs.push_back(static_cast<BVHMulti *>(geom->bvh));
|
||||
geom_bvhs.push_back(std::move(geom->bvh));
|
||||
}
|
||||
|
||||
/* Broadcast acceleration structure build to all render devices */
|
||||
@@ -202,7 +197,9 @@ class MultiDevice : public Device {
|
||||
for (SubDevice &sub : devices) {
|
||||
/* Change geometry BVH pointers to the sub BVH */
|
||||
for (size_t k = 0; k < bvh->geometry.size(); ++k) {
|
||||
bvh->geometry[k]->bvh = geom_bvhs[k]->sub_bvhs[i];
|
||||
bvh->geometry[k]->bvh.release(); // NOLINT: was not actually the owner
|
||||
bvh->geometry[k]->bvh.reset(
|
||||
static_cast<BVHMulti *>(geom_bvhs[k].get())->sub_bvhs[i].get());
|
||||
}
|
||||
|
||||
if (!bvh_multi->sub_bvhs[i]) {
|
||||
@@ -244,16 +241,18 @@ class MultiDevice : public Device {
|
||||
continue;
|
||||
}
|
||||
|
||||
bvh_multi->sub_bvhs[i] = BVH::create(params, bvh->geometry, bvh->objects, sub.device);
|
||||
bvh_multi->sub_bvhs[i] = BVH::create(
|
||||
params, bvh->geometry, bvh->objects, sub.device.get());
|
||||
}
|
||||
|
||||
sub.device->build_bvh(bvh_multi->sub_bvhs[i], progress, refit);
|
||||
sub.device->build_bvh(bvh_multi->sub_bvhs[i].get(), progress, refit);
|
||||
i++;
|
||||
}
|
||||
|
||||
/* Change geometry BVH pointers back to the multi BVH. */
|
||||
/* Change BVH ownership back to Geometry. */
|
||||
for (size_t k = 0; k < bvh->geometry.size(); ++k) {
|
||||
bvh->geometry[k]->bvh = geom_bvhs[k];
|
||||
bvh->geometry[k]->bvh.release(); // NOLINT: was not actually the owner
|
||||
bvh->geometry[k]->bvh = std::move(geom_bvhs[k]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -270,8 +269,8 @@ class MultiDevice : public Device {
|
||||
bool is_resident(device_ptr key, Device *sub_device) override
|
||||
{
|
||||
for (SubDevice &sub : devices) {
|
||||
if (sub.device == sub_device) {
|
||||
return find_matching_mem_device(key, sub)->device == sub_device;
|
||||
if (sub.device.get() == sub_device) {
|
||||
return find_matching_mem_device(key, sub)->device.get() == sub_device;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -323,7 +322,7 @@ class MultiDevice : public Device {
|
||||
/* The remaining memory types can be distributed across devices */
|
||||
for (const vector<SubDevice *> &island : peer_islands) {
|
||||
SubDevice *owner_sub = find_suitable_mem_device(key, island);
|
||||
mem.device = owner_sub->device;
|
||||
mem.device = owner_sub->device.get();
|
||||
mem.device_pointer = 0;
|
||||
mem.device_size = 0;
|
||||
|
||||
@@ -345,7 +344,7 @@ class MultiDevice : public Device {
|
||||
/* The tile buffers are allocated on each device (see below), so copy to all of them */
|
||||
for (const vector<SubDevice *> &island : peer_islands) {
|
||||
SubDevice *owner_sub = find_suitable_mem_device(existing_key, island);
|
||||
mem.device = owner_sub->device;
|
||||
mem.device = owner_sub->device.get();
|
||||
mem.device_pointer = (existing_key) ? owner_sub->ptr_map[existing_key] : 0;
|
||||
mem.device_size = existing_size;
|
||||
|
||||
@@ -371,14 +370,15 @@ class MultiDevice : public Device {
|
||||
device_memory &mem, const size_t y, size_t w, const size_t h, size_t elem) override
|
||||
{
|
||||
device_ptr key = mem.device_pointer;
|
||||
size_t i = 0, sub_h = h / devices.size();
|
||||
const size_t sub_h = h / devices.size();
|
||||
size_t i = 0;
|
||||
|
||||
for (SubDevice &sub : devices) {
|
||||
size_t sy = y + i * sub_h;
|
||||
size_t sh = (i == (size_t)devices.size() - 1) ? h - sub_h * i : sub_h;
|
||||
|
||||
SubDevice *owner_sub = find_matching_mem_device(key, sub);
|
||||
mem.device = owner_sub->device;
|
||||
mem.device = owner_sub->device.get();
|
||||
mem.device_pointer = owner_sub->ptr_map[key];
|
||||
|
||||
owner_sub->device->mem_copy_from(mem, sy, w, sh, elem);
|
||||
@@ -397,7 +397,7 @@ class MultiDevice : public Device {
|
||||
|
||||
for (const vector<SubDevice *> &island : peer_islands) {
|
||||
SubDevice *owner_sub = find_suitable_mem_device(existing_key, island);
|
||||
mem.device = owner_sub->device;
|
||||
mem.device = owner_sub->device.get();
|
||||
mem.device_pointer = (existing_key) ? owner_sub->ptr_map[existing_key] : 0;
|
||||
mem.device_size = existing_size;
|
||||
|
||||
@@ -418,7 +418,7 @@ class MultiDevice : public Device {
|
||||
/* Free memory that was allocated for all devices (see above) on each device */
|
||||
for (const vector<SubDevice *> &island : peer_islands) {
|
||||
SubDevice *owner_sub = find_matching_mem_device(key, *island.front());
|
||||
mem.device = owner_sub->device;
|
||||
mem.device = owner_sub->device.get();
|
||||
mem.device_pointer = owner_sub->ptr_map[key];
|
||||
mem.device_size = existing_size;
|
||||
|
||||
@@ -453,7 +453,7 @@ class MultiDevice : public Device {
|
||||
int i = 0;
|
||||
|
||||
for (SubDevice &sub : devices) {
|
||||
if (sub.device == sub_device) {
|
||||
if (sub.device.get() == sub_device) {
|
||||
return i;
|
||||
}
|
||||
i++;
|
||||
@@ -470,12 +470,12 @@ class MultiDevice : public Device {
|
||||
}
|
||||
};
|
||||
|
||||
Device *device_multi_create(const DeviceInfo &info,
|
||||
Stats &stats,
|
||||
Profiler &profiler,
|
||||
bool headless)
|
||||
unique_ptr<Device> device_multi_create(const DeviceInfo &info,
|
||||
Stats &stats,
|
||||
Profiler &profiler,
|
||||
bool headless)
|
||||
{
|
||||
return new MultiDevice(info, stats, profiler, headless);
|
||||
return make_unique<MultiDevice>(info, stats, profiler, headless);
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "util/unique_ptr.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
class Device;
|
||||
@@ -11,9 +13,9 @@ class DeviceInfo;
|
||||
class Profiler;
|
||||
class Stats;
|
||||
|
||||
Device *device_multi_create(const DeviceInfo &info,
|
||||
Stats &stats,
|
||||
Profiler &profiler,
|
||||
bool headless);
|
||||
unique_ptr<Device> device_multi_create(const DeviceInfo &info,
|
||||
Stats &stats,
|
||||
Profiler &profiler,
|
||||
bool headless);
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
@@ -75,13 +75,13 @@ bool device_oneapi_init()
|
||||
#endif
|
||||
}
|
||||
|
||||
Device *device_oneapi_create(const DeviceInfo &info,
|
||||
Stats &stats,
|
||||
Profiler &profiler,
|
||||
bool headless)
|
||||
unique_ptr<Device> device_oneapi_create(const DeviceInfo &info,
|
||||
Stats &stats,
|
||||
Profiler &profiler,
|
||||
bool headless)
|
||||
{
|
||||
#ifdef WITH_ONEAPI
|
||||
return new OneapiDevice(info, stats, profiler, headless);
|
||||
return make_unique<OneapiDevice>(info, stats, profiler, headless);
|
||||
#else
|
||||
(void)info;
|
||||
(void)stats;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "util/string.h"
|
||||
#include "util/unique_ptr.h"
|
||||
#include "util/vector.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
@@ -16,10 +17,10 @@ class Stats;
|
||||
|
||||
bool device_oneapi_init();
|
||||
|
||||
Device *device_oneapi_create(const DeviceInfo &info,
|
||||
Stats &stats,
|
||||
Profiler &profiler,
|
||||
bool headless);
|
||||
unique_ptr<Device> device_oneapi_create(const DeviceInfo &info,
|
||||
Stats &stats,
|
||||
Profiler &profiler,
|
||||
bool headless);
|
||||
|
||||
void device_oneapi_info(vector<DeviceInfo> &devices);
|
||||
|
||||
|
||||
@@ -137,9 +137,7 @@ OneapiDevice::~OneapiDevice()
|
||||
usm_free(device_queue_, kg_memory_);
|
||||
usm_free(device_queue_, kg_memory_device_);
|
||||
|
||||
for (ConstMemMap::iterator mt = const_mem_map_.begin(); mt != const_mem_map_.end(); mt++) {
|
||||
delete mt->second;
|
||||
}
|
||||
const_mem_map_.clear();
|
||||
|
||||
if (device_queue_) {
|
||||
free_queue(device_queue_);
|
||||
@@ -548,12 +546,14 @@ void OneapiDevice::const_copy_to(const char *name, void *host, const size_t size
|
||||
device_vector<uchar> *data;
|
||||
|
||||
if (i == const_mem_map_.end()) {
|
||||
data = new device_vector<uchar>(this, name, MEM_READ_ONLY);
|
||||
data->alloc(size);
|
||||
const_mem_map_.insert(ConstMemMap::value_type(name, data));
|
||||
unique_ptr<device_vector<uchar>> data_ptr = make_unique<device_vector<uchar>>(
|
||||
this, name, MEM_READ_ONLY);
|
||||
data_ptr->alloc(size);
|
||||
data = data_ptr.get();
|
||||
const_mem_map_.insert(ConstMemMap::value_type(name, std::move(data)));
|
||||
}
|
||||
else {
|
||||
data = i->second;
|
||||
data = i->second.get();
|
||||
}
|
||||
|
||||
assert(data->memory_size() <= size);
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
# include "kernel/device/oneapi/kernel.h"
|
||||
|
||||
# include "util/map.h"
|
||||
# include "util/unique_ptr.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
@@ -28,7 +29,7 @@ class OneapiDevice : public GPUDevice {
|
||||
vector<RTCScene> all_embree_scenes;
|
||||
# endif
|
||||
# endif
|
||||
using ConstMemMap = map<string, device_vector<uchar> *>;
|
||||
using ConstMemMap = map<string, unique_ptr<device_vector<uchar>>>;
|
||||
ConstMemMap const_mem_map_;
|
||||
void *kg_memory_;
|
||||
void *kg_memory_device_;
|
||||
|
||||
@@ -20,15 +20,10 @@ struct KernelExecutionInfo {
|
||||
/* OneapiDeviceQueue */
|
||||
|
||||
OneapiDeviceQueue::OneapiDeviceQueue(OneapiDevice *device)
|
||||
: DeviceQueue(device), oneapi_device_(device), kernel_context_(nullptr)
|
||||
: DeviceQueue(device), oneapi_device_(device)
|
||||
{
|
||||
}
|
||||
|
||||
OneapiDeviceQueue::~OneapiDeviceQueue()
|
||||
{
|
||||
delete kernel_context_;
|
||||
}
|
||||
|
||||
int OneapiDeviceQueue::num_concurrent_states(const size_t state_size) const
|
||||
{
|
||||
int num_states = 4 * num_concurrent_busy_states(state_size);
|
||||
@@ -60,7 +55,9 @@ void OneapiDeviceQueue::init_execution()
|
||||
void *kg_dptr = oneapi_device_->kernel_globals_device_pointer();
|
||||
assert(device_queue);
|
||||
assert(kg_dptr);
|
||||
kernel_context_ = new KernelContext{device_queue, kg_dptr, 0};
|
||||
kernel_context_ = make_unique<KernelContext>();
|
||||
kernel_context_->queue = device_queue;
|
||||
kernel_context_->kernel_globals = kg_dptr;
|
||||
|
||||
debug_init_execution();
|
||||
}
|
||||
@@ -88,7 +85,7 @@ bool OneapiDeviceQueue::enqueue(DeviceKernel kernel,
|
||||
|
||||
/* Call the oneAPI kernel DLL to launch the requested kernel. */
|
||||
bool is_finished_ok = oneapi_device_->enqueue_kernel(
|
||||
kernel_context_, kernel, kernel_global_size, kernel_local_size, args);
|
||||
kernel_context_.get(), kernel, kernel_global_size, kernel_local_size, args);
|
||||
|
||||
if (is_finished_ok == false) {
|
||||
oneapi_device_->set_error("oneAPI kernel \"" + std::string(device_kernel_as_string(kernel)) +
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
|
||||
# include "kernel/device/oneapi/kernel.h"
|
||||
|
||||
# include "util/unique_ptr.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
class OneapiDevice;
|
||||
@@ -20,7 +22,6 @@ class device_memory;
|
||||
class OneapiDeviceQueue : public DeviceQueue {
|
||||
public:
|
||||
explicit OneapiDeviceQueue(OneapiDevice *device);
|
||||
~OneapiDeviceQueue();
|
||||
|
||||
int num_concurrent_states(const size_t state_size) const override;
|
||||
|
||||
@@ -47,7 +48,7 @@ class OneapiDeviceQueue : public DeviceQueue {
|
||||
|
||||
protected:
|
||||
OneapiDevice *oneapi_device_;
|
||||
KernelContext *kernel_context_;
|
||||
unique_ptr<KernelContext> kernel_context_;
|
||||
};
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
@@ -101,13 +101,13 @@ void device_optix_info(const vector<DeviceInfo> &cuda_devices, vector<DeviceInfo
|
||||
#endif
|
||||
}
|
||||
|
||||
Device *device_optix_create(const DeviceInfo &info,
|
||||
Stats &stats,
|
||||
Profiler &profiler,
|
||||
bool headless)
|
||||
unique_ptr<Device> device_optix_create(const DeviceInfo &info,
|
||||
Stats &stats,
|
||||
Profiler &profiler,
|
||||
bool headless)
|
||||
{
|
||||
#ifdef WITH_OPTIX
|
||||
return new OptiXDevice(info, stats, profiler, headless);
|
||||
return make_unique<OptiXDevice>(info, stats, profiler, headless);
|
||||
#else
|
||||
(void)info;
|
||||
(void)stats;
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "util/unique_ptr.h"
|
||||
#include "util/vector.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
@@ -15,10 +16,10 @@ class Stats;
|
||||
|
||||
bool device_optix_init();
|
||||
|
||||
Device *device_optix_create(const DeviceInfo &info,
|
||||
Stats &stats,
|
||||
Profiler &profiler,
|
||||
bool headless);
|
||||
unique_ptr<Device> device_optix_create(const DeviceInfo &info,
|
||||
Stats &stats,
|
||||
Profiler &profiler,
|
||||
bool headless);
|
||||
|
||||
void device_optix_info(const vector<DeviceInfo> &cuda_devices, vector<DeviceInfo> &devices);
|
||||
|
||||
|
||||
@@ -1584,7 +1584,7 @@ void OptiXDevice::build_bvh(BVH *bvh, Progress &progress, bool refit)
|
||||
continue;
|
||||
}
|
||||
|
||||
BVHOptiX *const blas = static_cast<BVHOptiX *>(ob->get_geometry()->bvh);
|
||||
BVHOptiX *const blas = static_cast<BVHOptiX *>(ob->get_geometry()->bvh.get());
|
||||
OptixTraversableHandle handle = blas->traversable_handle;
|
||||
if (handle == 0) {
|
||||
continue;
|
||||
@@ -1658,15 +1658,16 @@ void OptiXDevice::build_bvh(BVH *bvh, Progress &progress, bool refit)
|
||||
motion_transform_offset += motion_transform_size;
|
||||
|
||||
/* Allocate host side memory for motion transform and fill it with transform data. */
|
||||
OptixSRTMotionTransform &motion_transform = *reinterpret_cast<OptixSRTMotionTransform *>(
|
||||
new uint8_t[motion_transform_size]);
|
||||
motion_transform.child = handle;
|
||||
motion_transform.motionOptions.numKeys = ob->get_motion().size();
|
||||
motion_transform.motionOptions.flags = OPTIX_MOTION_FLAG_NONE;
|
||||
motion_transform.motionOptions.timeBegin = 0.0f;
|
||||
motion_transform.motionOptions.timeEnd = 1.0f;
|
||||
array<uint8_t> motion_transform_storage(motion_transform_size);
|
||||
OptixSRTMotionTransform *motion_transform = reinterpret_cast<OptixSRTMotionTransform *>(
|
||||
motion_transform_storage.data());
|
||||
motion_transform->child = handle;
|
||||
motion_transform->motionOptions.numKeys = ob->get_motion().size();
|
||||
motion_transform->motionOptions.flags = OPTIX_MOTION_FLAG_NONE;
|
||||
motion_transform->motionOptions.timeBegin = 0.0f;
|
||||
motion_transform->motionOptions.timeEnd = 1.0f;
|
||||
|
||||
OptixSRTData *const srt_data = motion_transform.srtData;
|
||||
OptixSRTData *const srt_data = motion_transform->srtData;
|
||||
array<DecomposedTransform> decomp(ob->get_motion().size());
|
||||
transform_motion_decompose(
|
||||
decomp.data(), ob->get_motion().data(), ob->get_motion().size());
|
||||
@@ -1703,8 +1704,9 @@ void OptiXDevice::build_bvh(BVH *bvh, Progress &progress, bool refit)
|
||||
}
|
||||
|
||||
/* Upload motion transform to GPU. */
|
||||
cuMemcpyHtoD(motion_transform_gpu, &motion_transform, motion_transform_size);
|
||||
delete[] reinterpret_cast<uint8_t *>(&motion_transform);
|
||||
cuMemcpyHtoD(motion_transform_gpu, motion_transform, motion_transform_size);
|
||||
motion_transform = nullptr;
|
||||
motion_transform_storage.clear();
|
||||
|
||||
/* Get traversable handle to motion transform. */
|
||||
optixConvertPointerToTraversableHandle(context,
|
||||
|
||||
@@ -79,7 +79,7 @@ void HdCyclesField::Sync(HdSceneDelegate *sceneDelegate,
|
||||
value = sceneDelegate->Get(id, _tokens->fieldName);
|
||||
# endif
|
||||
if (value.IsHolding<TfToken>()) {
|
||||
ImageLoader *const loader = new HdCyclesVolumeLoader(
|
||||
unique_ptr<ImageLoader> loader = make_unique<HdCyclesVolumeLoader>(
|
||||
filename, value.UncheckedGet<TfToken>().GetString());
|
||||
|
||||
const SceneLock lock(renderParam);
|
||||
@@ -87,7 +87,7 @@ void HdCyclesField::Sync(HdSceneDelegate *sceneDelegate,
|
||||
ImageParams params;
|
||||
params.frame = 0.0f;
|
||||
|
||||
_handle = lock.scene->image_manager->add_image(loader, params, false);
|
||||
_handle = lock.scene->image_manager->add_image(std::move(loader), params, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,7 +190,7 @@ void HdCyclesLight::Sync(HdSceneDelegate *sceneDelegate,
|
||||
|
||||
void HdCyclesLight::PopulateShaderGraph(HdSceneDelegate *sceneDelegate)
|
||||
{
|
||||
auto *graph = new ShaderGraph();
|
||||
unique_ptr<ShaderGraph> graph = make_unique<ShaderGraph>();
|
||||
ShaderNode *outputNode = nullptr;
|
||||
|
||||
if (_lightType == HdPrimTypeTokens->domeLight) {
|
||||
@@ -347,7 +347,7 @@ void HdCyclesLight::PopulateShaderGraph(HdSceneDelegate *sceneDelegate)
|
||||
}
|
||||
|
||||
Shader *const shader = _light->get_shader();
|
||||
shader->set_graph(graph);
|
||||
shader->set_graph(std::move(graph));
|
||||
shader->tag_update((Scene *)_light->get_owner());
|
||||
|
||||
shader->has_surface_spatial_varying = hasSpatialVarying;
|
||||
|
||||
@@ -415,7 +415,7 @@ void HdCyclesMaterial::PopulateShaderGraph(const HdMaterialNetwork2 &networkMap)
|
||||
{
|
||||
_nodes.clear();
|
||||
|
||||
auto *graph = new ShaderGraph();
|
||||
unique_ptr<ShaderGraph> graph = make_unique<ShaderGraph>();
|
||||
|
||||
// Iterate all the nodes first and build a complete but unconnected graph with parameters set
|
||||
for (const auto &nodeEntry : networkMap.nodes) {
|
||||
@@ -448,7 +448,7 @@ void HdCyclesMaterial::PopulateShaderGraph(const HdMaterialNetwork2 &networkMap)
|
||||
// If it's a native Cycles' node-type, just do the lookup now.
|
||||
if (const NodeType *nodeType = NodeType::find(cyclesType)) {
|
||||
nodeDesc.node = static_cast<ShaderNode *>(nodeType->create(nodeType));
|
||||
nodeDesc.node->set_owner(graph);
|
||||
nodeDesc.node->set_owner(graph.get());
|
||||
|
||||
graph->add(nodeDesc.node);
|
||||
|
||||
@@ -474,7 +474,7 @@ void HdCyclesMaterial::PopulateShaderGraph(const HdMaterialNetwork2 &networkMap)
|
||||
continue;
|
||||
}
|
||||
|
||||
UpdateConnections(nodeIt->second, nodeEntry.second, nodePath, graph);
|
||||
UpdateConnections(nodeIt->second, nodeEntry.second, nodePath, graph.get());
|
||||
}
|
||||
|
||||
// Finally connect the terminals to the graph output (Surface, Volume, Displacement)
|
||||
@@ -556,7 +556,7 @@ void HdCyclesMaterial::PopulateShaderGraph(const HdMaterialNetwork2 &networkMap)
|
||||
graph->connect(instanceIdNode->output("Fac"), aovNode->input("Value"));
|
||||
}
|
||||
|
||||
_shader->set_graph(graph);
|
||||
_shader->set_graph(std::move(graph));
|
||||
}
|
||||
|
||||
void HdCyclesMaterial::Finalize(HdRenderParam *renderParam)
|
||||
|
||||
@@ -415,7 +415,7 @@ HdAovDescriptor HdCyclesDelegate::GetDefaultAovDescriptor(const TfToken &name) c
|
||||
|
||||
HdRenderSettingDescriptorList HdCyclesDelegate::GetRenderSettingDescriptors() const
|
||||
{
|
||||
Scene *const scene = _renderParam->session->scene;
|
||||
Scene *const scene = _renderParam->session->scene.get();
|
||||
|
||||
HdRenderSettingDescriptorList descriptors;
|
||||
|
||||
@@ -446,7 +446,7 @@ HdRenderSettingDescriptorList HdCyclesDelegate::GetRenderSettingDescriptors() co
|
||||
|
||||
void HdCyclesDelegate::SetRenderSetting(const PXR_NS::TfToken &key, const PXR_NS::VtValue &value)
|
||||
{
|
||||
Scene *const scene = _renderParam->session->scene;
|
||||
Scene *const scene = _renderParam->session->scene.get();
|
||||
Session *const session = _renderParam->session;
|
||||
|
||||
if (key == HdCyclesRenderSettingsTokens->stageMetersPerUnit) {
|
||||
@@ -482,7 +482,7 @@ void HdCyclesDelegate::SetRenderSetting(const PXR_NS::TfToken &key, const PXR_NS
|
||||
|
||||
VtValue HdCyclesDelegate::GetRenderSetting(const TfToken &key) const
|
||||
{
|
||||
Scene *const scene = _renderParam->session->scene;
|
||||
Scene *const scene = _renderParam->session->scene.get();
|
||||
Session *const session = _renderParam->session;
|
||||
|
||||
if (key == HdCyclesRenderSettingsTokens->stageMetersPerUnit) {
|
||||
|
||||
@@ -74,7 +74,7 @@ void HdCyclesRenderPass::ResetConverged()
|
||||
void HdCyclesRenderPass::_Execute(const HdRenderPassStateSharedPtr &renderPassState,
|
||||
const TfTokenVector & /*renderTags*/)
|
||||
{
|
||||
Scene *const scene = _renderParam->session->scene;
|
||||
Scene *const scene = _renderParam->session->scene.get();
|
||||
Session *const session = _renderParam->session;
|
||||
|
||||
if (session->progress.get_cancel()) {
|
||||
|
||||
@@ -28,7 +28,7 @@ const std::unordered_map<TfToken, PassType, TfToken::HashFunctor> kAovToPass = {
|
||||
} // namespace
|
||||
|
||||
SceneLock::SceneLock(const HdRenderParam *renderParam)
|
||||
: scene(static_cast<const HdCyclesSession *>(renderParam)->session->scene),
|
||||
: scene(static_cast<const HdCyclesSession *>(renderParam)->session->scene.get()),
|
||||
sceneLock(scene->mutex)
|
||||
{
|
||||
}
|
||||
@@ -43,11 +43,11 @@ HdCyclesSession::HdCyclesSession(Session *session_, const bool keep_nodes)
|
||||
HdCyclesSession::HdCyclesSession(const SessionParams ¶ms)
|
||||
: session(new Session(params, SceneParams())), keep_nodes(false), _ownCyclesSession(true)
|
||||
{
|
||||
Scene *const scene = session->scene;
|
||||
Scene *const scene = session->scene.get();
|
||||
|
||||
// Create background with ambient light
|
||||
{
|
||||
ShaderGraph *graph = new ShaderGraph();
|
||||
unique_ptr<ShaderGraph> graph = make_unique<ShaderGraph>();
|
||||
|
||||
BackgroundNode *bgNode = graph->create_node<BackgroundNode>();
|
||||
bgNode->set_color(one_float3());
|
||||
@@ -55,13 +55,13 @@ HdCyclesSession::HdCyclesSession(const SessionParams ¶ms)
|
||||
|
||||
graph->connect(bgNode->output("Background"), graph->output()->input("Surface"));
|
||||
|
||||
scene->default_background->set_graph(graph);
|
||||
scene->default_background->set_graph(std::move(graph));
|
||||
scene->default_background->tag_update(scene);
|
||||
}
|
||||
|
||||
// Wire up object color in default surface material
|
||||
{
|
||||
ShaderGraph *graph = new ShaderGraph();
|
||||
unique_ptr<ShaderGraph> graph = make_unique<ShaderGraph>();
|
||||
|
||||
ObjectInfoNode *objectNode = graph->create_node<ObjectInfoNode>();
|
||||
graph->add(objectNode);
|
||||
@@ -85,7 +85,7 @@ HdCyclesSession::HdCyclesSession(const SessionParams ¶ms)
|
||||
|
||||
graph->connect(instanceIdNode->output("Fac"), aovNode->input("Value"));
|
||||
|
||||
scene->default_surface->set_graph(graph);
|
||||
scene->default_surface->set_graph(std::move(graph));
|
||||
scene->default_surface->tag_update(scene);
|
||||
}
|
||||
}
|
||||
@@ -99,7 +99,7 @@ HdCyclesSession::~HdCyclesSession()
|
||||
|
||||
void HdCyclesSession::UpdateScene()
|
||||
{
|
||||
Scene *const scene = session->scene;
|
||||
Scene *const scene = session->scene.get();
|
||||
|
||||
// Update background depending on presence of a background light
|
||||
if (scene->light_manager->need_update()) {
|
||||
@@ -135,7 +135,7 @@ void HdCyclesSession::UpdateScene()
|
||||
|
||||
void HdCyclesSession::SyncAovBindings(const HdRenderPassAovBindingVector &aovBindings)
|
||||
{
|
||||
Scene *const scene = session->scene;
|
||||
Scene *const scene = session->scene.get();
|
||||
|
||||
// Delete all existing passes
|
||||
scene->delete_nodes(set<Pass *>(scene->passes.begin(), scene->passes.end()));
|
||||
|
||||
@@ -43,8 +43,8 @@ PathTrace::PathTrace(Device *device,
|
||||
vector<DeviceInfo> cpu_devices;
|
||||
device_cpu_info(cpu_devices);
|
||||
|
||||
cpu_device_.reset(
|
||||
device_cpu_create(cpu_devices[0], device->stats, device->profiler, device_->headless));
|
||||
cpu_device_ = device_cpu_create(
|
||||
cpu_devices[0], device->stats, device->profiler, device_->headless);
|
||||
}
|
||||
|
||||
/* Create path tracing work in advance, so that it can be reused by incremental sampling as much
|
||||
|
||||
@@ -145,12 +145,12 @@ void PathTraceWorkGPU::alloc_integrator_soa()
|
||||
if ((kernel_features & (feature)) && (integrator_state_gpu_.parent_struct.name == nullptr)) { \
|
||||
string name_str = string_printf("%sintegrator_state_" #parent_struct "_" #name, \
|
||||
shadow ? "shadow_" : ""); \
|
||||
device_only_memory<type> *array = new device_only_memory<type>(device_, name_str.c_str()); \
|
||||
auto array = make_unique<device_only_memory<type>>(device_, name_str.c_str()); \
|
||||
array->alloc_to_device(max_num_paths_); \
|
||||
integrator_state_soa_.emplace_back(array); \
|
||||
memcpy(&integrator_state_gpu_.parent_struct.name, \
|
||||
&array->device_pointer, \
|
||||
sizeof(array->device_pointer)); \
|
||||
integrator_state_soa_.emplace_back(std::move(array)); \
|
||||
}
|
||||
#ifdef __INTEGRATOR_GPU_PACKED_STATE__
|
||||
# define KERNEL_STRUCT_MEMBER_PACKED(parent_struct, type, name, feature) \
|
||||
@@ -174,12 +174,12 @@ void PathTraceWorkGPU::alloc_integrator_soa()
|
||||
{ \
|
||||
string name_str = string_printf( \
|
||||
"%sintegrator_state_" #name "_%d", shadow ? "shadow_" : "", array_index); \
|
||||
device_only_memory<type> *array = new device_only_memory<type>(device_, name_str.c_str()); \
|
||||
auto array = make_unique<device_only_memory<type>>(device_, name_str.c_str()); \
|
||||
array->alloc_to_device(max_num_paths_); \
|
||||
integrator_state_soa_.emplace_back(array); \
|
||||
memcpy(&integrator_state_gpu_.parent_struct[array_index].name, \
|
||||
&array->device_pointer, \
|
||||
sizeof(array->device_pointer)); \
|
||||
integrator_state_soa_.emplace_back(std::move(array)); \
|
||||
}
|
||||
#define KERNEL_STRUCT_END(name) \
|
||||
(void)array_index; \
|
||||
|
||||
@@ -30,11 +30,11 @@ typedef void (*OneAPIErrorCallback)(const char *error, void *user_ptr);
|
||||
|
||||
struct KernelContext {
|
||||
/* Queue, associated with selected device */
|
||||
SyclQueue *queue;
|
||||
SyclQueue *queue = nullptr;
|
||||
/* Pointer to USM device memory with all global/constant allocation on this device */
|
||||
void *kernel_globals;
|
||||
void *kernel_globals = nullptr;
|
||||
/* We needs this additional data for some kernels. */
|
||||
int scene_max_shaders;
|
||||
int scene_max_shaders = 0;
|
||||
};
|
||||
|
||||
/* Use extern C linking so that the symbols can be easily load from the dynamic library at runtime.
|
||||
|
||||
@@ -1146,8 +1146,8 @@ OSL::TextureSystem::TextureHandle *OSLRenderServices::get_texture_handle(OSLUStr
|
||||
if (device_type_ == DEVICE_CPU) {
|
||||
/* For non-OIIO textures, just return a pointer to our own OSLTextureHandle. */
|
||||
if (it != textures.end()) {
|
||||
if (it->second->type != OSLTextureHandle::OIIO) {
|
||||
return reinterpret_cast<OSL::TextureSystem::TextureHandle *>(it->second.get());
|
||||
if (it->second.type != OSLTextureHandle::OIIO) {
|
||||
return (OSL::TextureSystem::TextureHandle *)(&it->second);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1160,34 +1160,36 @@ OSL::TextureSystem::TextureHandle *OSLRenderServices::get_texture_handle(OSLUStr
|
||||
|
||||
/* Insert new OSLTextureHandle if needed. */
|
||||
if (it == textures.end()) {
|
||||
textures.insert(filename, new OSLTextureHandle(OSLTextureHandle::OIIO));
|
||||
textures.insert(filename, OSLTextureHandle(OSLTextureHandle::OIIO));
|
||||
it = textures.find(filename);
|
||||
}
|
||||
|
||||
/* Assign OIIO texture handle and return. */
|
||||
it->second->oiio_handle = handle;
|
||||
return reinterpret_cast<OSL::TextureSystem::TextureHandle *>(it->second.get());
|
||||
/* Assign OIIO texture handle and return.
|
||||
* OIIO::unordered_map_concurrent always returns a const handle even if the underlying
|
||||
* std::unordered_map supports updating values just fine. */
|
||||
const_cast<OSLTextureHandle &>(it->second).oiio_handle = handle;
|
||||
return (OSL::TextureSystem::TextureHandle *)(&it->second);
|
||||
}
|
||||
|
||||
/* Construct GPU texture handle for existing textures. */
|
||||
if (it != textures.end()) {
|
||||
switch (it->second->type) {
|
||||
switch (it->second.type) {
|
||||
case OSLTextureHandle::OIIO:
|
||||
return nullptr;
|
||||
case OSLTextureHandle::SVM:
|
||||
if (!it->second->handle.empty() && it->second->handle.get_manager() != image_manager) {
|
||||
if (!it->second.handle.empty() && it->second.handle.get_manager() != image_manager) {
|
||||
it.clear();
|
||||
break;
|
||||
}
|
||||
return reinterpret_cast<OSL::TextureSystem::TextureHandle *>(OSL_TEXTURE_HANDLE_TYPE_SVM |
|
||||
it->second->svm_slots[0].y);
|
||||
it->second.svm_slots[0].y);
|
||||
case OSLTextureHandle::IES:
|
||||
if (!it->second->handle.empty() && it->second->handle.get_manager() != image_manager) {
|
||||
if (!it->second.handle.empty() && it->second.handle.get_manager() != image_manager) {
|
||||
it.clear();
|
||||
break;
|
||||
}
|
||||
return reinterpret_cast<OSL::TextureSystem::TextureHandle *>(OSL_TEXTURE_HANDLE_TYPE_IES |
|
||||
it->second->svm_slots[0].y);
|
||||
it->second.svm_slots[0].y);
|
||||
case OSLTextureHandle::AO:
|
||||
return reinterpret_cast<OSL::TextureSystem::TextureHandle *>(
|
||||
OSL_TEXTURE_HANDLE_TYPE_AO_OR_BEVEL | 1);
|
||||
@@ -1207,7 +1209,7 @@ OSL::TextureSystem::TextureHandle *OSLRenderServices::get_texture_handle(OSLUStr
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!textures.insert(filename, new OSLTextureHandle(handle))) {
|
||||
if (!textures.insert(filename, OSLTextureHandle(handle))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,10 +22,6 @@
|
||||
|
||||
#include "kernel/osl/compat.h"
|
||||
|
||||
#ifdef WITH_PTEX
|
||||
class PtexCache;
|
||||
#endif
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
class Scene;
|
||||
@@ -47,7 +43,7 @@ struct ThreadKernelGlobalsCPU;
|
||||
* NOTE: The svm_slots array contains a compressed mapping of tile to svm_slot pairs
|
||||
* stored as follows: x:tile_a, y:svm_slot_a, z:tile_b, w:svm_slot_b etc. */
|
||||
|
||||
struct OSLTextureHandle : public OIIO::RefCnt {
|
||||
struct OSLTextureHandle {
|
||||
enum Type { OIIO, SVM, IES, BEVEL, AO };
|
||||
|
||||
OSLTextureHandle(Type type, const vector<int4> &svm_slots) : type(type), svm_slots(svm_slots) {}
|
||||
@@ -69,8 +65,7 @@ struct OSLTextureHandle : public OIIO::RefCnt {
|
||||
ImageHandle handle;
|
||||
};
|
||||
|
||||
using OSLTextureHandleRef = OIIO::intrusive_ptr<OSLTextureHandle>;
|
||||
using OSLTextureHandleMap = OIIO::unordered_map_concurrent<OSLUStringHash, OSLTextureHandleRef>;
|
||||
using OSLTextureHandleMap = OIIO::unordered_map_concurrent<OSLUStringHash, OSLTextureHandle>;
|
||||
|
||||
/* OSL Render Services
|
||||
*
|
||||
|
||||
@@ -473,8 +473,8 @@ bool Film::update_lightgroups(Scene *scene)
|
||||
void Film::update_passes(Scene *scene, bool add_sample_count_pass)
|
||||
{
|
||||
const Background *background = scene->background;
|
||||
const BakeManager *bake_manager = scene->bake_manager;
|
||||
const ObjectManager *object_manager = scene->object_manager;
|
||||
const BakeManager *bake_manager = scene->bake_manager.get();
|
||||
const ObjectManager *object_manager = scene->object_manager.get();
|
||||
Integrator *integrator = scene->integrator;
|
||||
|
||||
if (!is_modified() && !object_manager->need_update() && !integrator->is_modified() &&
|
||||
|
||||
@@ -61,7 +61,6 @@ Geometry::Geometry(const NodeType *node_type, const Type type)
|
||||
has_volume = false;
|
||||
has_surface_bssrdf = false;
|
||||
|
||||
bvh = nullptr;
|
||||
attr_map_offset = 0;
|
||||
prim_offset = 0;
|
||||
}
|
||||
@@ -69,7 +68,6 @@ Geometry::Geometry(const NodeType *node_type, const Type type)
|
||||
Geometry::~Geometry()
|
||||
{
|
||||
dereference_all_used_nodes();
|
||||
delete bvh;
|
||||
}
|
||||
|
||||
void Geometry::clear(bool preserve_shaders)
|
||||
@@ -188,7 +186,7 @@ GeometryManager::~GeometryManager() = default;
|
||||
void GeometryManager::update_osl_globals(Device *device, Scene *scene)
|
||||
{
|
||||
#ifdef WITH_OSL
|
||||
OSLGlobals *og = (OSLGlobals *)device->get_cpu_osl_memory();
|
||||
OSLGlobals *og = device->get_cpu_osl_memory();
|
||||
if (og == nullptr) {
|
||||
/* Can happen when rendering with multiple GPUs, but no CPU (in which case the name maps filled
|
||||
* below are not used anyway) */
|
||||
@@ -503,8 +501,7 @@ void GeometryManager::device_update_preprocess(Device *device, Scene *scene, Pro
|
||||
if (device_update_flags & (DEVICE_MESH_DATA_NEEDS_REALLOC | DEVICE_CURVE_DATA_NEEDS_REALLOC |
|
||||
DEVICE_POINT_DATA_NEEDS_REALLOC))
|
||||
{
|
||||
delete scene->bvh;
|
||||
scene->bvh = nullptr;
|
||||
scene->bvh.reset();
|
||||
|
||||
dscene->bvh_nodes.tag_realloc();
|
||||
dscene->bvh_leaf_nodes.tag_realloc();
|
||||
@@ -609,7 +606,7 @@ void GeometryManager::device_update_displacement_images(Device *device,
|
||||
{
|
||||
progress.set_status("Updating Displacement Images");
|
||||
TaskPool pool;
|
||||
ImageManager *image_manager = scene->image_manager;
|
||||
ImageManager *image_manager = scene->image_manager.get();
|
||||
set<int> bump_images;
|
||||
#ifdef WITH_OSL
|
||||
bool has_osl_node = false;
|
||||
@@ -674,7 +671,7 @@ void GeometryManager::device_update_volume_images(Device *device, Scene *scene,
|
||||
{
|
||||
progress.set_status("Updating Volume Images");
|
||||
TaskPool pool;
|
||||
ImageManager *image_manager = scene->image_manager;
|
||||
ImageManager *image_manager = scene->image_manager.get();
|
||||
set<int> volume_images;
|
||||
|
||||
for (Geometry *geom : scene->geometry) {
|
||||
@@ -1098,7 +1095,7 @@ void GeometryManager::device_free(Device *device, DeviceScene *dscene, bool forc
|
||||
dscene->data.bvh.bvh_layout = BVH_LAYOUT_NONE;
|
||||
|
||||
#ifdef WITH_OSL
|
||||
OSLGlobals *og = (OSLGlobals *)device->get_cpu_osl_memory();
|
||||
OSLGlobals *og = device->get_cpu_osl_memory();
|
||||
|
||||
if (og) {
|
||||
og->object_name_map.clear();
|
||||
|
||||
@@ -99,7 +99,7 @@ class Geometry : public Node {
|
||||
static const uint MAX_MOTION_STEPS = 129;
|
||||
|
||||
/* BVH */
|
||||
BVH *bvh;
|
||||
unique_ptr<BVH> bvh;
|
||||
size_t attr_map_offset;
|
||||
size_t prim_offset;
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ void Geometry::compute_bvh(Device *device,
|
||||
|
||||
bvh->replace_geometry(geometry, objects);
|
||||
|
||||
device->build_bvh(bvh, *progress, true);
|
||||
device->build_bvh(bvh.get(), *progress, true);
|
||||
}
|
||||
else {
|
||||
progress->set_status(msg, "Building BVH");
|
||||
@@ -82,9 +82,8 @@ void Geometry::compute_bvh(Device *device,
|
||||
bparams.bvh_type = params->bvh_type;
|
||||
bparams.curve_subdivisions = params->curve_subdivisions();
|
||||
|
||||
delete bvh;
|
||||
bvh = BVH::create(bparams, geometry, objects, device);
|
||||
MEM_GUARDED_CALL(progress, device->build_bvh, bvh, *progress, false);
|
||||
MEM_GUARDED_CALL(progress, device->build_bvh, bvh.get(), *progress, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,9 +118,10 @@ void GeometryManager::device_update_bvh(Device *device,
|
||||
(bparams.bvh_layout == BVHLayout::BVH_LAYOUT_OPTIX ||
|
||||
bparams.bvh_layout == BVHLayout::BVH_LAYOUT_METAL);
|
||||
|
||||
BVH *bvh = scene->bvh;
|
||||
if (!scene->bvh) {
|
||||
bvh = scene->bvh = BVH::create(bparams, scene->geometry, scene->objects, device);
|
||||
BVH *bvh = scene->bvh.get();
|
||||
if (bvh == nullptr) {
|
||||
scene->bvh = BVH::create(bparams, scene->geometry, scene->objects, device);
|
||||
bvh = scene->bvh.get();
|
||||
}
|
||||
|
||||
device->build_bvh(bvh, progress, can_refit);
|
||||
|
||||
@@ -119,7 +119,7 @@ ImageMetaData ImageHandle::metadata()
|
||||
return ImageMetaData();
|
||||
}
|
||||
|
||||
ImageManager::Image *img = manager->images[tile_slots.front()];
|
||||
ImageManager::Image *img = manager->images[tile_slots.front()].get();
|
||||
manager->load_image_metadata(img);
|
||||
return img->metadata;
|
||||
}
|
||||
@@ -131,7 +131,7 @@ int ImageHandle::svm_slot(const int tile_index) const
|
||||
}
|
||||
|
||||
if (manager->osl_texture_system) {
|
||||
ImageManager::Image *img = manager->images[tile_slots[tile_index]];
|
||||
ImageManager::Image *img = manager->images[tile_slots[tile_index]].get();
|
||||
if (!img->loader->osl_filepath().empty()) {
|
||||
return -1;
|
||||
}
|
||||
@@ -175,8 +175,8 @@ device_texture *ImageHandle::image_memory(const int tile_index) const
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ImageManager::Image *img = manager->images[tile_slots[tile_index]];
|
||||
return img ? img->mem : nullptr;
|
||||
ImageManager::Image *img = manager->images[tile_slots[tile_index]].get();
|
||||
return img ? img->mem.get() : nullptr;
|
||||
}
|
||||
|
||||
VDBImageLoader *ImageHandle::vdb_loader(const int tile_index) const
|
||||
@@ -185,13 +185,13 @@ VDBImageLoader *ImageHandle::vdb_loader(const int tile_index) const
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ImageManager::Image *img = manager->images[tile_slots[tile_index]];
|
||||
ImageManager::Image *img = manager->images[tile_slots[tile_index]].get();
|
||||
|
||||
if (img == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ImageLoader *loader = img->loader;
|
||||
ImageLoader *loader = img->loader.get();
|
||||
|
||||
if (loader == nullptr) {
|
||||
return nullptr;
|
||||
@@ -371,7 +371,7 @@ void ImageManager::load_image_metadata(Image *img)
|
||||
|
||||
ImageHandle ImageManager::add_image(const string &filename, const ImageParams ¶ms)
|
||||
{
|
||||
const size_t slot = add_image_slot(new OIIOImageLoader(filename), params, false);
|
||||
const size_t slot = add_image_slot(make_unique<OIIOImageLoader>(filename), params, false);
|
||||
|
||||
ImageHandle handle;
|
||||
handle.tile_slots.push_back(slot);
|
||||
@@ -398,18 +398,18 @@ ImageHandle ImageManager::add_image(const string &filename,
|
||||
const int v = ((tile - 1001) / 10);
|
||||
string_replace(tile_filename, "<UVTILE>", string_printf("u%d_v%d", u + 1, v + 1));
|
||||
}
|
||||
const size_t slot = add_image_slot(new OIIOImageLoader(tile_filename), params, false);
|
||||
const size_t slot = add_image_slot(make_unique<OIIOImageLoader>(tile_filename), params, false);
|
||||
handle.tile_slots.push_back(slot);
|
||||
}
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
ImageHandle ImageManager::add_image(ImageLoader *loader,
|
||||
ImageHandle ImageManager::add_image(unique_ptr<ImageLoader> &&loader,
|
||||
const ImageParams ¶ms,
|
||||
const bool builtin)
|
||||
{
|
||||
const size_t slot = add_image_slot(loader, params, builtin);
|
||||
const size_t slot = add_image_slot(std::move(loader), params, builtin);
|
||||
|
||||
ImageHandle handle;
|
||||
handle.tile_slots.push_back(slot);
|
||||
@@ -417,12 +417,14 @@ ImageHandle ImageManager::add_image(ImageLoader *loader,
|
||||
return handle;
|
||||
}
|
||||
|
||||
ImageHandle ImageManager::add_image(const vector<ImageLoader *> &loaders,
|
||||
ImageHandle ImageManager::add_image(vector<unique_ptr<ImageLoader>> &&loaders,
|
||||
const ImageParams ¶ms)
|
||||
{
|
||||
ImageHandle handle;
|
||||
for (ImageLoader *loader : loaders) {
|
||||
const size_t slot = add_image_slot(loader, params, true);
|
||||
for (unique_ptr<ImageLoader> &loader : loaders) {
|
||||
unique_ptr<ImageLoader> local_loader;
|
||||
std::swap(loader, local_loader);
|
||||
const size_t slot = add_image_slot(std::move(local_loader), params, true);
|
||||
handle.tile_slots.push_back(slot);
|
||||
}
|
||||
|
||||
@@ -430,21 +432,19 @@ ImageHandle ImageManager::add_image(const vector<ImageLoader *> &loaders,
|
||||
return handle;
|
||||
}
|
||||
|
||||
size_t ImageManager::add_image_slot(ImageLoader *loader,
|
||||
size_t ImageManager::add_image_slot(unique_ptr<ImageLoader> &&loader,
|
||||
const ImageParams ¶ms,
|
||||
const bool builtin)
|
||||
{
|
||||
Image *img;
|
||||
size_t slot;
|
||||
|
||||
const thread_scoped_lock device_lock(images_mutex);
|
||||
|
||||
/* Find existing image. */
|
||||
for (slot = 0; slot < images.size(); slot++) {
|
||||
img = images[slot];
|
||||
if (img && ImageLoader::equals(img->loader, loader) && img->params == params) {
|
||||
Image *img = images[slot].get();
|
||||
if (img && ImageLoader::equals(img->loader.get(), loader.get()) && img->params == params) {
|
||||
img->users++;
|
||||
delete loader;
|
||||
return slot;
|
||||
}
|
||||
}
|
||||
@@ -461,16 +461,16 @@ size_t ImageManager::add_image_slot(ImageLoader *loader,
|
||||
}
|
||||
|
||||
/* Add new image. */
|
||||
img = new Image();
|
||||
unique_ptr<Image> img = make_unique<Image>();
|
||||
img->params = params;
|
||||
img->loader = loader;
|
||||
img->loader = std::move(loader);
|
||||
img->need_metadata = true;
|
||||
img->need_load = !(osl_texture_system && !img->loader->osl_filepath().empty());
|
||||
img->builtin = builtin;
|
||||
img->users = 1;
|
||||
img->mem = nullptr;
|
||||
|
||||
images[slot] = img;
|
||||
images[slot] = std::move(img);
|
||||
|
||||
need_update_ = true;
|
||||
|
||||
@@ -480,7 +480,7 @@ size_t ImageManager::add_image_slot(ImageLoader *loader,
|
||||
void ImageManager::add_image_user(const size_t slot)
|
||||
{
|
||||
const thread_scoped_lock device_lock(images_mutex);
|
||||
Image *image = images[slot];
|
||||
Image *image = images[slot].get();
|
||||
assert(image && image->users >= 1);
|
||||
|
||||
image->users++;
|
||||
@@ -489,7 +489,7 @@ void ImageManager::add_image_user(const size_t slot)
|
||||
void ImageManager::remove_image_user(const size_t slot)
|
||||
{
|
||||
const thread_scoped_lock device_lock(images_mutex);
|
||||
Image *image = images[slot];
|
||||
Image *image = images[slot].get();
|
||||
assert(image && image->users >= 1);
|
||||
|
||||
/* decrement user count */
|
||||
@@ -681,7 +681,7 @@ void ImageManager::device_load_image(Device *device,
|
||||
return;
|
||||
}
|
||||
|
||||
Image *img = images[slot];
|
||||
Image *img = images[slot].get();
|
||||
|
||||
progress.set_status("Updating Images", "Loading " + img->loader->name());
|
||||
|
||||
@@ -696,11 +696,10 @@ void ImageManager::device_load_image(Device *device,
|
||||
/* Free previous texture in slot. */
|
||||
if (img->mem) {
|
||||
const thread_scoped_lock device_lock(device_mutex);
|
||||
delete img->mem;
|
||||
img->mem = nullptr;
|
||||
img->mem.reset();
|
||||
}
|
||||
|
||||
img->mem = new device_texture(
|
||||
img->mem = make_unique<device_texture>(
|
||||
device, img->mem_name.c_str(), slot, type, img->params.interpolation, img->params.extension);
|
||||
img->mem->info.use_transform_3d = img->metadata.use_transform_3d;
|
||||
img->mem->info.transform_3d = img->metadata.transform_3d;
|
||||
@@ -815,7 +814,7 @@ void ImageManager::device_load_image(Device *device,
|
||||
|
||||
void ImageManager::device_free_image(Device * /*unused*/, size_t slot)
|
||||
{
|
||||
Image *img = images[slot];
|
||||
Image *img = images[slot].get();
|
||||
if (img == nullptr) {
|
||||
return;
|
||||
}
|
||||
@@ -831,12 +830,10 @@ void ImageManager::device_free_image(Device * /*unused*/, size_t slot)
|
||||
|
||||
if (img->mem) {
|
||||
const thread_scoped_lock device_lock(device_mutex);
|
||||
delete img->mem;
|
||||
img->mem.reset();
|
||||
}
|
||||
|
||||
delete img->loader;
|
||||
delete img;
|
||||
images[slot] = nullptr;
|
||||
images[slot].reset();
|
||||
}
|
||||
|
||||
void ImageManager::device_update(Device *device, Scene *scene, Progress &progress)
|
||||
@@ -853,7 +850,7 @@ void ImageManager::device_update(Device *device, Scene *scene, Progress &progres
|
||||
|
||||
TaskPool pool;
|
||||
for (size_t slot = 0; slot < images.size(); slot++) {
|
||||
Image *img = images[slot];
|
||||
Image *img = images[slot].get();
|
||||
if (img && img->users == 0) {
|
||||
device_free_image(device, slot);
|
||||
}
|
||||
@@ -874,7 +871,7 @@ void ImageManager::device_update_slot(Device *device,
|
||||
const size_t slot,
|
||||
Progress &progress)
|
||||
{
|
||||
Image *img = images[slot];
|
||||
Image *img = images[slot].get();
|
||||
assert(img != nullptr);
|
||||
|
||||
if (img->users == 0) {
|
||||
@@ -895,7 +892,7 @@ void ImageManager::device_load_builtin(Device *device, Scene *scene, Progress &p
|
||||
|
||||
TaskPool pool;
|
||||
for (size_t slot = 0; slot < images.size(); slot++) {
|
||||
Image *img = images[slot];
|
||||
Image *img = images[slot].get();
|
||||
if (img && img->need_load && img->builtin) {
|
||||
pool.push([this, device, scene, slot, &progress] {
|
||||
device_load_image(device, scene, slot, progress);
|
||||
@@ -909,7 +906,7 @@ void ImageManager::device_load_builtin(Device *device, Scene *scene, Progress &p
|
||||
void ImageManager::device_free_builtin(Device *device)
|
||||
{
|
||||
for (size_t slot = 0; slot < images.size(); slot++) {
|
||||
Image *img = images[slot];
|
||||
Image *img = images[slot].get();
|
||||
if (img && img->builtin) {
|
||||
device_free_image(device, slot);
|
||||
}
|
||||
@@ -926,7 +923,7 @@ void ImageManager::device_free(Device *device)
|
||||
|
||||
void ImageManager::collect_statistics(RenderStats *stats)
|
||||
{
|
||||
for (const Image *image : images) {
|
||||
for (const unique_ptr<Image> &image : images) {
|
||||
if (!image) {
|
||||
/* Image may have been freed due to lack of users. */
|
||||
continue;
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "util/string.h"
|
||||
#include "util/thread.h"
|
||||
#include "util/transform.h"
|
||||
#include "util/unique_ptr.h"
|
||||
#include "util/vector.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
@@ -166,8 +167,10 @@ class ImageManager {
|
||||
ImageHandle add_image(const string &filename,
|
||||
const ImageParams ¶ms,
|
||||
const array<int> &tiles);
|
||||
ImageHandle add_image(ImageLoader *loader, const ImageParams ¶ms, const bool builtin = true);
|
||||
ImageHandle add_image(const vector<ImageLoader *> &loaders, const ImageParams ¶ms);
|
||||
ImageHandle add_image(unique_ptr<ImageLoader> &&loader,
|
||||
const ImageParams ¶ms,
|
||||
const bool builtin = true);
|
||||
ImageHandle add_image(vector<unique_ptr<ImageLoader>> &&loaders, const ImageParams ¶ms);
|
||||
|
||||
void device_update(Device *device, Scene *scene, Progress &progress);
|
||||
void device_update_slot(Device *device, Scene *scene, const size_t slot, Progress &progress);
|
||||
@@ -188,7 +191,7 @@ class ImageManager {
|
||||
struct Image {
|
||||
ImageParams params;
|
||||
ImageMetaData metadata;
|
||||
ImageLoader *loader;
|
||||
unique_ptr<ImageLoader> loader;
|
||||
|
||||
float frame;
|
||||
bool need_metadata;
|
||||
@@ -196,7 +199,7 @@ class ImageManager {
|
||||
bool builtin;
|
||||
|
||||
string mem_name;
|
||||
device_texture *mem;
|
||||
unique_ptr<device_texture> mem;
|
||||
|
||||
int users;
|
||||
thread_mutex mutex;
|
||||
@@ -211,10 +214,12 @@ class ImageManager {
|
||||
thread_mutex images_mutex;
|
||||
int animation_frame;
|
||||
|
||||
vector<Image *> images;
|
||||
vector<unique_ptr<Image>> images;
|
||||
void *osl_texture_system;
|
||||
|
||||
size_t add_image_slot(ImageLoader *loader, const ImageParams ¶ms, const bool builtin);
|
||||
size_t add_image_slot(unique_ptr<ImageLoader> &&loader,
|
||||
const ImageParams ¶ms,
|
||||
const bool builtin);
|
||||
void add_image_user(const size_t slot);
|
||||
void remove_image_user(const size_t slot);
|
||||
|
||||
|
||||
@@ -217,13 +217,6 @@ LightManager::LightManager()
|
||||
last_background_resolution = 0;
|
||||
}
|
||||
|
||||
LightManager::~LightManager()
|
||||
{
|
||||
for (IESSlot *slot : ies_slots) {
|
||||
delete slot;
|
||||
}
|
||||
}
|
||||
|
||||
bool LightManager::has_background_light(Scene *scene)
|
||||
{
|
||||
for (Light *light : scene->lights) {
|
||||
@@ -1534,7 +1527,7 @@ int LightManager::add_ies(const string &content)
|
||||
|
||||
/* If there's no free slot, add one. */
|
||||
if (slot == ies_slots.size()) {
|
||||
ies_slots.push_back(new IESSlot());
|
||||
ies_slots.push_back(make_unique<IESSlot>());
|
||||
}
|
||||
|
||||
ies_slots[slot]->ies.load(content);
|
||||
@@ -1569,7 +1562,7 @@ void LightManager::remove_ies(const int slot)
|
||||
void LightManager::device_update_ies(DeviceScene *dscene)
|
||||
{
|
||||
/* Clear empty slots. */
|
||||
for (IESSlot *slot : ies_slots) {
|
||||
for (const unique_ptr<IESSlot> &slot : ies_slots) {
|
||||
if (slot->users == 0) {
|
||||
slot->hash = 0;
|
||||
slot->ies.clear();
|
||||
@@ -1583,14 +1576,12 @@ void LightManager::device_update_ies(DeviceScene *dscene)
|
||||
/* If the preceding slot has users, we found the new end of the table. */
|
||||
break;
|
||||
}
|
||||
/* The slot will be past the new end of the table, so free it. */
|
||||
delete ies_slots[slot_end - 1];
|
||||
}
|
||||
ies_slots.resize(slot_end);
|
||||
|
||||
if (!ies_slots.empty()) {
|
||||
int packed_size = 0;
|
||||
for (IESSlot *slot : ies_slots) {
|
||||
for (const unique_ptr<IESSlot> &slot : ies_slots) {
|
||||
packed_size += slot->ies.packed_size();
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "util/ies.h"
|
||||
#include "util/thread.h"
|
||||
#include "util/types.h"
|
||||
#include "util/unique_ptr.h"
|
||||
#include "util/vector.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
@@ -117,7 +118,6 @@ class LightManager {
|
||||
bool need_update_background;
|
||||
|
||||
LightManager();
|
||||
~LightManager();
|
||||
|
||||
/* IES texture management */
|
||||
int add_ies(const string &content);
|
||||
@@ -159,7 +159,7 @@ class LightManager {
|
||||
int users;
|
||||
};
|
||||
|
||||
vector<IESSlot *> ies_slots;
|
||||
vector<unique_ptr<IESSlot>> ies_slots;
|
||||
thread_mutex ies_mutex;
|
||||
|
||||
bool last_background_enabled;
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
#include "scene/scene.h"
|
||||
#include "scene/shader_graph.h"
|
||||
|
||||
#include "subd/patch_table.h"
|
||||
#include "subd/split.h"
|
||||
|
||||
#include "util/log.h"
|
||||
@@ -156,14 +155,14 @@ SubdParams *Mesh::get_subd_params()
|
||||
}
|
||||
|
||||
if (!subd_params) {
|
||||
subd_params = new SubdParams(this);
|
||||
subd_params = make_unique<SubdParams>(this);
|
||||
}
|
||||
|
||||
subd_params->dicing_rate = subd_dicing_rate;
|
||||
subd_params->max_level = subd_max_level;
|
||||
subd_params->objecttoworld = subd_objecttoworld;
|
||||
|
||||
return subd_params;
|
||||
return subd_params.get();
|
||||
}
|
||||
|
||||
bool Mesh::need_tesselation()
|
||||
@@ -187,19 +186,10 @@ Mesh::Mesh(const NodeType *node_type, Type geom_type_)
|
||||
num_ngons = 0;
|
||||
|
||||
subdivision_type = SUBDIVISION_NONE;
|
||||
subd_params = nullptr;
|
||||
|
||||
patch_table = nullptr;
|
||||
}
|
||||
|
||||
Mesh::Mesh() : Mesh(get_node_type(), Geometry::MESH) {}
|
||||
|
||||
Mesh::~Mesh()
|
||||
{
|
||||
delete patch_table;
|
||||
delete subd_params;
|
||||
}
|
||||
|
||||
void Mesh::resize_mesh(const int numverts, const int numtris)
|
||||
{
|
||||
verts.resize(numverts);
|
||||
@@ -275,8 +265,7 @@ void Mesh::clear_non_sockets()
|
||||
vert_to_stitching_key_map.clear();
|
||||
vert_stitching_map.clear();
|
||||
|
||||
delete patch_table;
|
||||
patch_table = nullptr;
|
||||
patch_table.reset();
|
||||
}
|
||||
|
||||
void Mesh::clear(bool preserve_shaders, bool preserve_voxel_data)
|
||||
|
||||
@@ -10,12 +10,16 @@
|
||||
#include "scene/geometry.h"
|
||||
#include "scene/shader.h"
|
||||
|
||||
#include "subd/dice.h"
|
||||
#include "subd/patch_table.h"
|
||||
|
||||
#include "util/array.h"
|
||||
#include "util/boundbox.h"
|
||||
#include "util/map.h"
|
||||
#include "util/param.h"
|
||||
#include "util/set.h"
|
||||
#include "util/types.h"
|
||||
#include "util/unique_ptr.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
@@ -31,7 +35,6 @@ class SceneParams;
|
||||
class AttributeRequest;
|
||||
struct SubdParams;
|
||||
class DiagSplit;
|
||||
struct PackedPatchTable;
|
||||
|
||||
/* Mesh */
|
||||
|
||||
@@ -155,7 +158,7 @@ class Mesh : public Geometry {
|
||||
AttributeSet subd_attributes;
|
||||
|
||||
private:
|
||||
PackedPatchTable *patch_table;
|
||||
unique_ptr<PackedPatchTable> patch_table;
|
||||
/* BVH */
|
||||
size_t vert_offset;
|
||||
|
||||
@@ -179,12 +182,11 @@ class Mesh : public Geometry {
|
||||
friend class GeometryManager;
|
||||
friend class ObjectManager;
|
||||
|
||||
SubdParams *subd_params = nullptr;
|
||||
unique_ptr<SubdParams> subd_params;
|
||||
|
||||
public:
|
||||
/* Functions */
|
||||
Mesh();
|
||||
~Mesh() override;
|
||||
|
||||
void resize_mesh(const int numverts, const int numtris);
|
||||
void reserve_mesh(const int numverts, const int numtris);
|
||||
|
||||
@@ -170,20 +170,13 @@ template<> void OsdValue<uchar4>::AddWithWeight(const OsdValue<uchar4> &src, con
|
||||
class OsdData {
|
||||
Mesh *mesh = nullptr;
|
||||
vector<OsdValue<float3>> verts;
|
||||
Far::TopologyRefiner *refiner = nullptr;
|
||||
Far::PatchTable *patch_table = nullptr;
|
||||
Far::PatchMap *patch_map = nullptr;
|
||||
unique_ptr<Far::TopologyRefiner> refiner;
|
||||
unique_ptr<Far::PatchTable> patch_table;
|
||||
unique_ptr<Far::PatchMap> patch_map;
|
||||
|
||||
public:
|
||||
OsdData() = default;
|
||||
|
||||
~OsdData()
|
||||
{
|
||||
delete refiner;
|
||||
delete patch_table;
|
||||
delete patch_map;
|
||||
}
|
||||
|
||||
void build_from_mesh(Mesh *mesh_)
|
||||
{
|
||||
mesh = mesh_;
|
||||
@@ -195,8 +188,8 @@ class OsdData {
|
||||
options.SetVtxBoundaryInterpolation(Sdc::Options::VTX_BOUNDARY_EDGE_ONLY);
|
||||
|
||||
/* create refiner */
|
||||
refiner = Far::TopologyRefinerFactory<Mesh>::Create(
|
||||
*mesh, Far::TopologyRefinerFactory<Mesh>::Options(type, options));
|
||||
refiner.reset(Far::TopologyRefinerFactory<Mesh>::Create(
|
||||
*mesh, Far::TopologyRefinerFactory<Mesh>::Options(type, options)));
|
||||
|
||||
/* adaptive refinement */
|
||||
const int max_isolation = calculate_max_isolation();
|
||||
@@ -206,7 +199,7 @@ class OsdData {
|
||||
Far::PatchTableFactory::Options patch_options;
|
||||
patch_options.endCapType = Far::PatchTableFactory::Options::ENDCAP_GREGORY_BASIS;
|
||||
|
||||
patch_table = Far::PatchTableFactory::Create(*refiner, patch_options);
|
||||
patch_table.reset(Far::PatchTableFactory::Create(*refiner, patch_options));
|
||||
|
||||
/* interpolate verts */
|
||||
const int num_refiner_verts = refiner->GetNumVerticesTotal();
|
||||
@@ -229,7 +222,7 @@ class OsdData {
|
||||
}
|
||||
|
||||
/* create patch map */
|
||||
patch_map = new Far::PatchMap(*patch_table);
|
||||
patch_map = make_unique<Far::PatchMap>(*patch_table);
|
||||
}
|
||||
|
||||
void subdivide_attribute(Attribute &attr)
|
||||
@@ -668,9 +661,8 @@ void Mesh::tessellate(DiagSplit *split)
|
||||
#ifdef WITH_OPENSUBDIV
|
||||
/* pack patch tables */
|
||||
if (need_packed_patch_table) {
|
||||
delete patch_table;
|
||||
patch_table = new PackedPatchTable;
|
||||
patch_table->pack(osd_data.patch_table);
|
||||
patch_table = make_unique<PackedPatchTable>();
|
||||
patch_table->pack(osd_data.patch_table.get());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ int OSLShaderManager::ts_shared_users = 0;
|
||||
thread_mutex OSLShaderManager::ts_shared_mutex;
|
||||
|
||||
OSL::ErrorHandler OSLShaderManager::errhandler;
|
||||
map<int, OSL::ShadingSystem *> OSLShaderManager::ss_shared;
|
||||
map<int, unique_ptr<OSL::ShadingSystem>> OSLShaderManager::ss_shared;
|
||||
int OSLShaderManager::ss_shared_users = 0;
|
||||
thread_mutex OSLShaderManager::ss_shared_mutex;
|
||||
|
||||
@@ -123,7 +123,7 @@ void OSLShaderManager::device_update_specific(Device *device,
|
||||
assert(shader->graph);
|
||||
|
||||
auto compile = [this, scene, shader, background_shader](Device *sub_device) {
|
||||
OSL::ShadingSystem *ss = ss_shared[sub_device->info.type];
|
||||
OSL::ShadingSystem *ss = ss_shared[sub_device->info.type].get();
|
||||
|
||||
OSLCompiler compiler(this, ss, scene);
|
||||
compiler.background = (shader == background_shader);
|
||||
@@ -162,7 +162,7 @@ void OSLShaderManager::device_update_specific(Device *device,
|
||||
/* setup shader engine */
|
||||
device->foreach_device([](Device *sub_device) {
|
||||
OSLGlobals *og = sub_device->get_cpu_osl_memory();
|
||||
OSL::ShadingSystem *ss = ss_shared[sub_device->info.type];
|
||||
OSL::ShadingSystem *ss = ss_shared[sub_device->info.type].get();
|
||||
|
||||
og->ss = ss;
|
||||
og->ts = ts_shared;
|
||||
@@ -181,9 +181,8 @@ void OSLShaderManager::device_update_specific(Device *device,
|
||||
for (const auto &[device_type, ss] : ss_shared) {
|
||||
OSLRenderServices *services = static_cast<OSLRenderServices *>(ss->renderer());
|
||||
|
||||
services->textures.insert(OSLUStringHash("@ao"), new OSLTextureHandle(OSLTextureHandle::AO));
|
||||
services->textures.insert(OSLUStringHash("@bevel"),
|
||||
new OSLTextureHandle(OSLTextureHandle::BEVEL));
|
||||
services->textures.insert(OSLUStringHash("@ao"), OSLTextureHandle(OSLTextureHandle::AO));
|
||||
services->textures.insert(OSLUStringHash("@bevel"), OSLTextureHandle(OSLTextureHandle::BEVEL));
|
||||
}
|
||||
|
||||
device_update_common(device, dscene, scene, progress);
|
||||
@@ -207,7 +206,7 @@ void OSLShaderManager::device_update_specific(Device *device,
|
||||
*
|
||||
* It is used in "OSLRenderServices::get_texture_handle" called during optimization below to
|
||||
* load images for the GPU. */
|
||||
OSLRenderServices::image_manager = scene->image_manager;
|
||||
OSLRenderServices::image_manager = scene->image_manager.get();
|
||||
|
||||
for (const auto &[device_type, ss] : ss_shared) {
|
||||
ss->optimize_all_groups();
|
||||
@@ -247,7 +246,7 @@ void OSLShaderManager::device_free(Device *device, DeviceScene *dscene, Scene *s
|
||||
OSLRenderServices *services = static_cast<OSLRenderServices *>(ss->renderer());
|
||||
|
||||
for (auto it = services->textures.begin(); it != services->textures.end(); ++it) {
|
||||
if (it->second->handle.get_manager() == scene->image_manager) {
|
||||
if (it->second.handle.get_manager() == scene->image_manager.get()) {
|
||||
/* Don't lock again, since the iterator already did so. */
|
||||
services->textures.erase(it->first, false);
|
||||
it.clear();
|
||||
@@ -313,7 +312,8 @@ void OSLShaderManager::shading_system_init()
|
||||
const string shader_path = path_get("shader");
|
||||
# endif
|
||||
|
||||
OSL::ShadingSystem *ss = new OSL::ShadingSystem(services, ts_shared, &errhandler);
|
||||
unique_ptr<OSL::ShadingSystem> ss = make_unique<OSL::ShadingSystem>(
|
||||
services, ts_shared, &errhandler);
|
||||
ss->attribute("lockgeom", 1);
|
||||
ss->attribute("commonspace", "world");
|
||||
ss->attribute("searchpath:shader", shader_path);
|
||||
@@ -373,9 +373,9 @@ void OSLShaderManager::shading_system_init()
|
||||
const int nraytypes = sizeof(raytypes) / sizeof(raytypes[0]);
|
||||
ss->attribute("raytypes", TypeDesc(TypeDesc::STRING, nraytypes), (const void *)raytypes);
|
||||
|
||||
OSLRenderServices::register_closures(ss);
|
||||
OSLRenderServices::register_closures(ss.get());
|
||||
|
||||
ss_shared[device_type] = ss;
|
||||
ss_shared[device_type] = std::move(ss);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -389,11 +389,9 @@ void OSLShaderManager::shading_system_free()
|
||||
|
||||
device_->foreach_device([](Device * /*sub_device*/) {
|
||||
if (--ss_shared_users == 0) {
|
||||
for (const auto &[device_type, ss] : ss_shared) {
|
||||
for (auto &[device_type, ss] : ss_shared) {
|
||||
OSLRenderServices *services = static_cast<OSLRenderServices *>(ss->renderer());
|
||||
|
||||
delete ss;
|
||||
|
||||
ss.reset();
|
||||
util_aligned_delete(services);
|
||||
}
|
||||
|
||||
@@ -424,9 +422,8 @@ bool OSLShaderManager::osl_compile(const string &inputfile, const string &output
|
||||
static thread_mutex osl_compiler_mutex;
|
||||
const thread_scoped_lock lock(osl_compiler_mutex);
|
||||
|
||||
OSL::OSLCompiler *compiler = new OSL::OSLCompiler(&OSL::ErrorHandler::default_handler());
|
||||
const bool ok = compiler->compile(string_view(inputfile), options, string_view(stdosl_path));
|
||||
delete compiler;
|
||||
OSL::OSLCompiler compiler = OSL::OSLCompiler(&OSL::ErrorHandler::default_handler());
|
||||
const bool ok = compiler.compile(string_view(inputfile), options, string_view(stdosl_path));
|
||||
|
||||
return ok;
|
||||
}
|
||||
@@ -718,8 +715,8 @@ void OSLShaderManager::osl_image_slots(Device *device,
|
||||
|
||||
for (OSLRenderServices *services : services_shared) {
|
||||
for (auto it = services->textures.begin(); it != services->textures.end(); ++it) {
|
||||
if (it->second->handle.get_manager() == image_manager) {
|
||||
const int slot = it->second->handle.svm_slot();
|
||||
if (it->second.handle.get_manager() == image_manager) {
|
||||
const int slot = it->second.handle.svm_slot();
|
||||
image_slots.insert(slot);
|
||||
}
|
||||
}
|
||||
@@ -1327,7 +1324,7 @@ OSL::ShaderGroupRef OSLCompiler::compile_type(Shader *shader, ShaderGraph *graph
|
||||
void OSLCompiler::compile(Shader *shader)
|
||||
{
|
||||
if (shader->is_modified()) {
|
||||
ShaderGraph *graph = shader->graph;
|
||||
ShaderGraph *graph = shader->graph.get();
|
||||
ShaderNode *output = (graph) ? graph->output() : nullptr;
|
||||
|
||||
const bool has_bump = (shader->get_displacement_method() != DISPLACE_TRUE) &&
|
||||
@@ -1352,10 +1349,10 @@ void OSLCompiler::compile(Shader *shader)
|
||||
|
||||
/* generate surface shader */
|
||||
if (shader->reference_count() && graph && output->input("Surface")->link) {
|
||||
shader->osl_surface_ref = compile_type(shader, shader->graph, SHADER_TYPE_SURFACE);
|
||||
shader->osl_surface_ref = compile_type(shader, shader->graph.get(), SHADER_TYPE_SURFACE);
|
||||
|
||||
if (has_bump) {
|
||||
shader->osl_surface_bump_ref = compile_type(shader, shader->graph, SHADER_TYPE_BUMP);
|
||||
shader->osl_surface_bump_ref = compile_type(shader, shader->graph.get(), SHADER_TYPE_BUMP);
|
||||
}
|
||||
else {
|
||||
shader->osl_surface_bump_ref = OSL::ShaderGroupRef();
|
||||
@@ -1370,7 +1367,7 @@ void OSLCompiler::compile(Shader *shader)
|
||||
|
||||
/* generate volume shader */
|
||||
if (shader->reference_count() && graph && output->input("Volume")->link) {
|
||||
shader->osl_volume_ref = compile_type(shader, shader->graph, SHADER_TYPE_VOLUME);
|
||||
shader->osl_volume_ref = compile_type(shader, shader->graph.get(), SHADER_TYPE_VOLUME);
|
||||
shader->has_volume = true;
|
||||
}
|
||||
else {
|
||||
@@ -1379,7 +1376,8 @@ void OSLCompiler::compile(Shader *shader)
|
||||
|
||||
/* generate displacement shader */
|
||||
if (shader->reference_count() && graph && output->input("Displacement")->link) {
|
||||
shader->osl_displacement_ref = compile_type(shader, shader->graph, SHADER_TYPE_DISPLACEMENT);
|
||||
shader->osl_displacement_ref = compile_type(
|
||||
shader, shader->graph.get(), SHADER_TYPE_DISPLACEMENT);
|
||||
shader->has_displacement = true;
|
||||
}
|
||||
else {
|
||||
@@ -1395,8 +1393,8 @@ void OSLCompiler::parameter_texture(const char *name, ustring filename, ustring
|
||||
{
|
||||
/* Textured loaded through the OpenImageIO texture cache. For this
|
||||
* case we need to do runtime color space conversion. */
|
||||
OSLTextureHandle *handle = new OSLTextureHandle(OSLTextureHandle::OIIO);
|
||||
handle->processor = ColorSpaceManager::get_processor(colorspace);
|
||||
OSLTextureHandle handle(OSLTextureHandle::OIIO);
|
||||
handle.processor = ColorSpaceManager::get_processor(colorspace);
|
||||
services->textures.insert(OSLUStringHash(filename), handle);
|
||||
parameter(name, filename);
|
||||
}
|
||||
@@ -1409,7 +1407,7 @@ void OSLCompiler::parameter_texture(const char *name, const ImageHandle &handle)
|
||||
* render sessions as the render services are shared. */
|
||||
const ustring filename(string_printf("@svm%d", texture_shared_unique_id++).c_str());
|
||||
services->textures.insert(OSLUStringHash(filename),
|
||||
new OSLTextureHandle(OSLTextureHandle::SVM, handle.get_svm_slots()));
|
||||
OSLTextureHandle(OSLTextureHandle::SVM, handle.get_svm_slots()));
|
||||
parameter(name, filename);
|
||||
}
|
||||
|
||||
@@ -1418,7 +1416,7 @@ void OSLCompiler::parameter_texture_ies(const char *name, const int svm_slot)
|
||||
/* IES light textures stored in SVM. */
|
||||
const ustring filename(string_printf("@svm%d", texture_shared_unique_id++).c_str());
|
||||
services->textures.insert(OSLUStringHash(filename),
|
||||
new OSLTextureHandle(OSLTextureHandle::IES, svm_slot));
|
||||
OSLTextureHandle(OSLTextureHandle::IES, svm_slot));
|
||||
parameter(name, filename);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "util/set.h"
|
||||
#include "util/string.h"
|
||||
#include "util/thread.h"
|
||||
#include "util/unique_ptr.h"
|
||||
|
||||
#include "scene/shader.h"
|
||||
#include "scene/shader_graph.h"
|
||||
@@ -107,7 +108,7 @@ class OSLShaderManager : public ShaderManager {
|
||||
static int ts_shared_users;
|
||||
|
||||
static OSL::ErrorHandler errhandler;
|
||||
static map<int, OSL::ShadingSystem *> ss_shared;
|
||||
static map<int, unique_ptr<OSL::ShadingSystem>> ss_shared;
|
||||
static thread_mutex ss_shared_mutex;
|
||||
static thread_mutex ss_mutex;
|
||||
static int ss_shared_users;
|
||||
|
||||
@@ -37,7 +37,6 @@ CCL_NAMESPACE_BEGIN
|
||||
|
||||
Scene ::Scene(const SceneParams ¶ms_, Device *device)
|
||||
: name("Scene"),
|
||||
bvh(nullptr),
|
||||
default_surface(nullptr),
|
||||
default_volume(nullptr),
|
||||
default_light(nullptr),
|
||||
@@ -57,18 +56,18 @@ Scene ::Scene(const SceneParams ¶ms_, Device *device)
|
||||
shader_manager = ShaderManager::create(
|
||||
device->info.has_osl ? params.shadingsystem : SHADINGSYSTEM_SVM, device);
|
||||
|
||||
light_manager = new LightManager();
|
||||
geometry_manager = new GeometryManager();
|
||||
object_manager = new ObjectManager();
|
||||
image_manager = new ImageManager(device->info);
|
||||
particle_system_manager = new ParticleSystemManager();
|
||||
bake_manager = new BakeManager();
|
||||
procedural_manager = new ProceduralManager();
|
||||
light_manager = make_unique<LightManager>();
|
||||
geometry_manager = make_unique<GeometryManager>();
|
||||
object_manager = make_unique<ObjectManager>();
|
||||
image_manager = make_unique<ImageManager>(device->info);
|
||||
particle_system_manager = make_unique<ParticleSystemManager>();
|
||||
bake_manager = make_unique<BakeManager>();
|
||||
procedural_manager = make_unique<ProceduralManager>();
|
||||
|
||||
/* Create nodes after managers, since create_node() can tag the managers. */
|
||||
camera = create_node<Camera>();
|
||||
dicing_camera = create_node<Camera>();
|
||||
lookup_tables = new LookupTables();
|
||||
lookup_tables = make_unique<LookupTables>();
|
||||
film = create_node<Film>();
|
||||
background = create_node<Background>();
|
||||
integrator = create_node<Integrator>();
|
||||
@@ -84,8 +83,7 @@ Scene::~Scene()
|
||||
|
||||
void Scene::free_memory(bool final)
|
||||
{
|
||||
delete bvh;
|
||||
bvh = nullptr;
|
||||
bvh.reset();
|
||||
|
||||
/* The order of deletion is important to make sure data is freed based on
|
||||
* possible dependencies as the Nodes' reference counts are decremented in the
|
||||
@@ -170,16 +168,16 @@ void Scene::free_memory(bool final)
|
||||
}
|
||||
|
||||
if (final) {
|
||||
delete lookup_tables;
|
||||
delete object_manager;
|
||||
delete geometry_manager;
|
||||
delete shader_manager;
|
||||
delete light_manager;
|
||||
delete particle_system_manager;
|
||||
delete image_manager;
|
||||
delete bake_manager;
|
||||
delete update_stats;
|
||||
delete procedural_manager;
|
||||
lookup_tables.reset();
|
||||
object_manager.reset();
|
||||
geometry_manager.reset();
|
||||
shader_manager.reset();
|
||||
light_manager.reset();
|
||||
particle_system_manager.reset();
|
||||
image_manager.reset();
|
||||
bake_manager.reset();
|
||||
update_stats.reset();
|
||||
procedural_manager.reset();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -472,7 +470,7 @@ void Scene::collect_statistics(RenderStats *stats)
|
||||
void Scene::enable_update_stats()
|
||||
{
|
||||
if (!update_stats) {
|
||||
update_stats = new SceneUpdateStats();
|
||||
update_stats = make_unique<SceneUpdateStats>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -117,10 +117,11 @@ class Scene : public NodeOwner {
|
||||
map<ustring, int> lightgroups;
|
||||
|
||||
/* data */
|
||||
BVH *bvh;
|
||||
unique_ptr<BVH> bvh;
|
||||
unique_ptr<LookupTables> lookup_tables;
|
||||
|
||||
Camera *camera;
|
||||
Camera *dicing_camera;
|
||||
LookupTables *lookup_tables;
|
||||
Film *film;
|
||||
Background *background;
|
||||
Integrator *integrator;
|
||||
@@ -135,14 +136,14 @@ class Scene : public NodeOwner {
|
||||
vector<Procedural *> procedurals;
|
||||
|
||||
/* data managers */
|
||||
ImageManager *image_manager;
|
||||
LightManager *light_manager;
|
||||
ShaderManager *shader_manager;
|
||||
GeometryManager *geometry_manager;
|
||||
ObjectManager *object_manager;
|
||||
ParticleSystemManager *particle_system_manager;
|
||||
BakeManager *bake_manager;
|
||||
ProceduralManager *procedural_manager;
|
||||
unique_ptr<ImageManager> image_manager;
|
||||
unique_ptr<LightManager> light_manager;
|
||||
unique_ptr<ShaderManager> shader_manager;
|
||||
unique_ptr<GeometryManager> geometry_manager;
|
||||
unique_ptr<ObjectManager> object_manager;
|
||||
unique_ptr<ParticleSystemManager> particle_system_manager;
|
||||
unique_ptr<BakeManager> bake_manager;
|
||||
unique_ptr<ProceduralManager> procedural_manager;
|
||||
|
||||
/* default shaders */
|
||||
Shader *default_surface;
|
||||
@@ -162,7 +163,7 @@ class Scene : public NodeOwner {
|
||||
thread_mutex mutex;
|
||||
|
||||
/* scene update statistics */
|
||||
SceneUpdateStats *update_stats;
|
||||
unique_ptr<SceneUpdateStats> update_stats;
|
||||
|
||||
Scene(const SceneParams ¶ms, Device *device);
|
||||
~Scene() override;
|
||||
|
||||
@@ -119,11 +119,6 @@ Shader::Shader() : Node(get_node_type())
|
||||
need_update_displacement = true;
|
||||
}
|
||||
|
||||
Shader::~Shader()
|
||||
{
|
||||
delete graph;
|
||||
}
|
||||
|
||||
static float3 output_estimate_emission(ShaderOutput *output, bool &is_constant)
|
||||
{
|
||||
/* Only supports a few nodes for now, not arbitrary shader graphs. */
|
||||
@@ -280,7 +275,7 @@ void Shader::estimate_emission()
|
||||
}
|
||||
}
|
||||
|
||||
void Shader::set_graph(ShaderGraph *graph_)
|
||||
void Shader::set_graph(unique_ptr<ShaderGraph> &&graph_)
|
||||
{
|
||||
/* do this here already so that we can detect if mesh or object attributes
|
||||
* are needed, since the node attribute callbacks check if their sockets
|
||||
@@ -304,8 +299,7 @@ void Shader::set_graph(ShaderGraph *graph_)
|
||||
}
|
||||
|
||||
/* assign graph */
|
||||
delete graph;
|
||||
graph = graph_;
|
||||
graph = std::move(graph_);
|
||||
|
||||
/* Store info here before graph optimization to make sure that
|
||||
* nodes that get optimized away still count. */
|
||||
@@ -432,21 +426,21 @@ ShaderManager::ShaderManager()
|
||||
|
||||
ShaderManager::~ShaderManager() = default;
|
||||
|
||||
ShaderManager *ShaderManager::create(const int shadingsystem, Device *device)
|
||||
unique_ptr<ShaderManager> ShaderManager::create(const int shadingsystem, Device *device)
|
||||
{
|
||||
ShaderManager *manager;
|
||||
unique_ptr<ShaderManager> manager;
|
||||
|
||||
(void)shadingsystem; /* Ignored when built without OSL. */
|
||||
(void)device;
|
||||
|
||||
#ifdef WITH_OSL
|
||||
if (shadingsystem == SHADINGSYSTEM_OSL) {
|
||||
manager = new OSLShaderManager(device);
|
||||
manager = make_unique<OSLShaderManager>(device);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
manager = new SVMShaderManager();
|
||||
manager = make_unique<SVMShaderManager>();
|
||||
}
|
||||
|
||||
return manager;
|
||||
@@ -661,7 +655,7 @@ void ShaderManager::add_default(Scene *scene)
|
||||
{
|
||||
/* default surface */
|
||||
{
|
||||
ShaderGraph *graph = new ShaderGraph();
|
||||
unique_ptr<ShaderGraph> graph = make_unique<ShaderGraph>();
|
||||
|
||||
DiffuseBsdfNode *diffuse = graph->create_node<DiffuseBsdfNode>();
|
||||
diffuse->set_color(make_float3(0.8f, 0.8f, 0.8f));
|
||||
@@ -671,7 +665,7 @@ void ShaderManager::add_default(Scene *scene)
|
||||
|
||||
Shader *shader = scene->create_node<Shader>();
|
||||
shader->name = "default_surface";
|
||||
shader->set_graph(graph);
|
||||
shader->set_graph(std::move(graph));
|
||||
shader->reference();
|
||||
scene->default_surface = shader;
|
||||
shader->tag_update(scene);
|
||||
@@ -679,7 +673,7 @@ void ShaderManager::add_default(Scene *scene)
|
||||
|
||||
/* default volume */
|
||||
{
|
||||
ShaderGraph *graph = new ShaderGraph();
|
||||
unique_ptr<ShaderGraph> graph = make_unique<ShaderGraph>();
|
||||
|
||||
PrincipledVolumeNode *principled = graph->create_node<PrincipledVolumeNode>();
|
||||
graph->add(principled);
|
||||
@@ -688,7 +682,7 @@ void ShaderManager::add_default(Scene *scene)
|
||||
|
||||
Shader *shader = scene->create_node<Shader>();
|
||||
shader->name = "default_volume";
|
||||
shader->set_graph(graph);
|
||||
shader->set_graph(std::move(graph));
|
||||
scene->default_volume = shader;
|
||||
shader->tag_update(scene);
|
||||
/* No default reference for the volume to avoid compiling volume kernels if there are no
|
||||
@@ -697,7 +691,7 @@ void ShaderManager::add_default(Scene *scene)
|
||||
|
||||
/* default light */
|
||||
{
|
||||
ShaderGraph *graph = new ShaderGraph();
|
||||
unique_ptr<ShaderGraph> graph = make_unique<ShaderGraph>();
|
||||
|
||||
EmissionNode *emission = graph->create_node<EmissionNode>();
|
||||
emission->set_color(make_float3(0.8f, 0.8f, 0.8f));
|
||||
@@ -708,7 +702,7 @@ void ShaderManager::add_default(Scene *scene)
|
||||
|
||||
Shader *shader = scene->create_node<Shader>();
|
||||
shader->name = "default_light";
|
||||
shader->set_graph(graph);
|
||||
shader->set_graph(std::move(graph));
|
||||
shader->reference();
|
||||
scene->default_light = shader;
|
||||
shader->tag_update(scene);
|
||||
@@ -716,11 +710,11 @@ void ShaderManager::add_default(Scene *scene)
|
||||
|
||||
/* default background */
|
||||
{
|
||||
ShaderGraph *graph = new ShaderGraph();
|
||||
unique_ptr<ShaderGraph> graph = make_unique<ShaderGraph>();
|
||||
|
||||
Shader *shader = scene->create_node<Shader>();
|
||||
shader->name = "default_background";
|
||||
shader->set_graph(graph);
|
||||
shader->set_graph(std::move(graph));
|
||||
shader->reference();
|
||||
scene->default_background = shader;
|
||||
shader->tag_update(scene);
|
||||
@@ -728,11 +722,11 @@ void ShaderManager::add_default(Scene *scene)
|
||||
|
||||
/* default empty */
|
||||
{
|
||||
ShaderGraph *graph = new ShaderGraph();
|
||||
unique_ptr<ShaderGraph> graph = make_unique<ShaderGraph>();
|
||||
|
||||
Shader *shader = scene->create_node<Shader>();
|
||||
shader->name = "default_empty";
|
||||
shader->set_graph(graph);
|
||||
shader->set_graph(std::move(graph));
|
||||
shader->reference();
|
||||
scene->default_empty = shader;
|
||||
shader->tag_update(scene);
|
||||
@@ -772,7 +766,7 @@ uint ShaderManager::get_kernel_features(Scene *scene)
|
||||
}
|
||||
|
||||
/* Gather requested features from all the nodes from the graph nodes. */
|
||||
kernel_features |= get_graph_kernel_features(shader->graph);
|
||||
kernel_features |= get_graph_kernel_features(shader->graph.get());
|
||||
ShaderNode *output_node = shader->graph->output();
|
||||
if (output_node->input("Displacement")->link != nullptr) {
|
||||
kernel_features |= KERNEL_FEATURE_NODE_BUMP;
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "util/string.h"
|
||||
#include "util/thread.h"
|
||||
#include "util/types.h"
|
||||
#include "util/unique_ptr.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
@@ -71,7 +72,7 @@ class Shader : public Node {
|
||||
NODE_DECLARE
|
||||
|
||||
/* shader graph */
|
||||
ShaderGraph *graph;
|
||||
unique_ptr<ShaderGraph> graph;
|
||||
|
||||
NODE_SOCKET_API(int, pass_id)
|
||||
|
||||
@@ -135,7 +136,6 @@ class Shader : public Node {
|
||||
#endif
|
||||
|
||||
Shader();
|
||||
~Shader() override;
|
||||
|
||||
/* Estimate emission of this shader based on the shader graph. This works only in very simple
|
||||
* cases. But it helps improve light importance sampling in common cases.
|
||||
@@ -144,7 +144,7 @@ class Shader : public Node {
|
||||
* entirely for a light. */
|
||||
void estimate_emission();
|
||||
|
||||
void set_graph(ShaderGraph *graph);
|
||||
void set_graph(unique_ptr<ShaderGraph> &&graph);
|
||||
void tag_update(Scene *scene);
|
||||
void tag_used(Scene *scene);
|
||||
|
||||
@@ -176,7 +176,7 @@ class ShaderManager {
|
||||
UPDATE_NONE = 0u,
|
||||
};
|
||||
|
||||
static ShaderManager *create(const int shadingsystem, Device *device);
|
||||
static unique_ptr<ShaderManager> create(const int shadingsystem, Device *device);
|
||||
virtual ~ShaderManager();
|
||||
|
||||
virtual void reset(Scene *scene) = 0;
|
||||
|
||||
@@ -331,7 +331,7 @@ void ImageTextureNode::cull_tiles(Scene *scene, ShaderGraph *graph)
|
||||
for (Geometry *geom : scene->geometry) {
|
||||
for (Node *node : geom->get_used_shaders()) {
|
||||
Shader *shader = static_cast<Shader *>(node);
|
||||
if (shader->graph == graph) {
|
||||
if (shader->graph.get() == graph) {
|
||||
geom->get_uv_tiles(attribute, used_tiles);
|
||||
}
|
||||
}
|
||||
@@ -369,7 +369,7 @@ void ImageTextureNode::compile(SVMCompiler &compiler)
|
||||
|
||||
if (handle.empty()) {
|
||||
cull_tiles(compiler.scene, compiler.current_graph);
|
||||
ImageManager *image_manager = compiler.scene->image_manager;
|
||||
ImageManager *image_manager = compiler.scene->image_manager.get();
|
||||
handle = image_manager->add_image(filename.string(), image_params(), tiles);
|
||||
}
|
||||
|
||||
@@ -450,7 +450,7 @@ void ImageTextureNode::compile(OSLCompiler &compiler)
|
||||
tex_mapping.compile(compiler);
|
||||
|
||||
if (handle.empty()) {
|
||||
ImageManager *image_manager = compiler.scene->image_manager;
|
||||
ImageManager *image_manager = compiler.scene->image_manager.get();
|
||||
handle = image_manager->add_image(filename.string(), image_params());
|
||||
}
|
||||
|
||||
@@ -572,7 +572,7 @@ void EnvironmentTextureNode::compile(SVMCompiler &compiler)
|
||||
ShaderOutput *alpha_out = output("Alpha");
|
||||
|
||||
if (handle.empty()) {
|
||||
ImageManager *image_manager = compiler.scene->image_manager;
|
||||
ImageManager *image_manager = compiler.scene->image_manager.get();
|
||||
handle = image_manager->add_image(filename.string(), image_params());
|
||||
}
|
||||
|
||||
@@ -601,7 +601,7 @@ void EnvironmentTextureNode::compile(SVMCompiler &compiler)
|
||||
void EnvironmentTextureNode::compile(OSLCompiler &compiler)
|
||||
{
|
||||
if (handle.empty()) {
|
||||
ImageManager *image_manager = compiler.scene->image_manager;
|
||||
ImageManager *image_manager = compiler.scene->image_manager.get();
|
||||
handle = image_manager->add_image(filename.string(), image_params());
|
||||
}
|
||||
|
||||
@@ -940,16 +940,16 @@ void SkyTextureNode::compile(SVMCompiler &compiler)
|
||||
air_density,
|
||||
dust_density);
|
||||
/* precomputed texture image parameters */
|
||||
ImageManager *image_manager = compiler.scene->image_manager;
|
||||
ImageManager *image_manager = compiler.scene->image_manager.get();
|
||||
ImageParams impar;
|
||||
impar.interpolation = INTERPOLATION_LINEAR;
|
||||
impar.extension = EXTENSION_EXTEND;
|
||||
|
||||
/* precompute sky texture */
|
||||
if (handle.empty()) {
|
||||
SkyLoader *loader = new SkyLoader(
|
||||
unique_ptr<SkyLoader> loader = make_unique<SkyLoader>(
|
||||
sun_elevation, clamped_altitude, air_density, dust_density, ozone_density);
|
||||
handle = image_manager->add_image(loader, impar);
|
||||
handle = image_manager->add_image(std::move(loader), impar);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -1039,16 +1039,16 @@ void SkyTextureNode::compile(OSLCompiler &compiler)
|
||||
air_density,
|
||||
dust_density);
|
||||
/* precomputed texture image parameters */
|
||||
ImageManager *image_manager = compiler.scene->image_manager;
|
||||
ImageManager *image_manager = compiler.scene->image_manager.get();
|
||||
ImageParams impar;
|
||||
impar.interpolation = INTERPOLATION_LINEAR;
|
||||
impar.extension = EXTENSION_EXTEND;
|
||||
|
||||
/* precompute sky texture */
|
||||
if (handle.empty()) {
|
||||
SkyLoader *loader = new SkyLoader(
|
||||
unique_ptr<SkyLoader> loader = make_unique<SkyLoader>(
|
||||
sun_elevation, clamped_altitude, air_density, dust_density, ozone_density);
|
||||
handle = image_manager->add_image(loader, impar);
|
||||
handle = image_manager->add_image(std::move(loader), impar);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -1477,7 +1477,7 @@ void IESLightNode::get_slot()
|
||||
|
||||
void IESLightNode::compile(SVMCompiler &compiler)
|
||||
{
|
||||
light_manager = compiler.scene->light_manager;
|
||||
light_manager = compiler.scene->light_manager.get();
|
||||
get_slot();
|
||||
|
||||
ShaderInput *strength_in = input("Strength");
|
||||
@@ -1499,7 +1499,7 @@ void IESLightNode::compile(SVMCompiler &compiler)
|
||||
|
||||
void IESLightNode::compile(OSLCompiler &compiler)
|
||||
{
|
||||
light_manager = compiler.scene->light_manager;
|
||||
light_manager = compiler.scene->light_manager.get();
|
||||
get_slot();
|
||||
|
||||
tex_mapping.compile(compiler);
|
||||
@@ -1941,7 +1941,7 @@ void PointDensityTextureNode::compile(SVMCompiler &compiler)
|
||||
}
|
||||
|
||||
if (handle.empty()) {
|
||||
ImageManager *image_manager = compiler.scene->image_manager;
|
||||
ImageManager *image_manager = compiler.scene->image_manager.get();
|
||||
handle = image_manager->add_image(filename.string(), image_params());
|
||||
}
|
||||
|
||||
@@ -1992,7 +1992,7 @@ void PointDensityTextureNode::compile(OSLCompiler &compiler)
|
||||
}
|
||||
|
||||
if (handle.empty()) {
|
||||
ImageManager *image_manager = compiler.scene->image_manager;
|
||||
ImageManager *image_manager = compiler.scene->image_manager.get();
|
||||
handle = image_manager->add_image(filename.string(), image_params());
|
||||
}
|
||||
|
||||
|
||||
@@ -911,7 +911,7 @@ void SVMCompiler::compile(Shader *shader,
|
||||
/* generate bump shader */
|
||||
if (has_bump) {
|
||||
const scoped_timer timer((summary != nullptr) ? &summary->time_generate_bump : nullptr);
|
||||
compile_type(shader, shader->graph, SHADER_TYPE_BUMP);
|
||||
compile_type(shader, shader->graph.get(), SHADER_TYPE_BUMP);
|
||||
svm_nodes[index].y = svm_nodes.size();
|
||||
svm_nodes.append(current_svm_nodes);
|
||||
}
|
||||
@@ -919,7 +919,7 @@ void SVMCompiler::compile(Shader *shader,
|
||||
/* generate surface shader */
|
||||
{
|
||||
const scoped_timer timer((summary != nullptr) ? &summary->time_generate_surface : nullptr);
|
||||
compile_type(shader, shader->graph, SHADER_TYPE_SURFACE);
|
||||
compile_type(shader, shader->graph.get(), SHADER_TYPE_SURFACE);
|
||||
/* only set jump offset if there's no bump shader, as the bump shader will fall thru to this
|
||||
* one if it exists */
|
||||
if (!has_bump) {
|
||||
@@ -931,7 +931,7 @@ void SVMCompiler::compile(Shader *shader,
|
||||
/* generate volume shader */
|
||||
{
|
||||
const scoped_timer timer((summary != nullptr) ? &summary->time_generate_volume : nullptr);
|
||||
compile_type(shader, shader->graph, SHADER_TYPE_VOLUME);
|
||||
compile_type(shader, shader->graph.get(), SHADER_TYPE_VOLUME);
|
||||
svm_nodes[index].z = svm_nodes.size();
|
||||
svm_nodes.append(current_svm_nodes);
|
||||
}
|
||||
@@ -940,7 +940,7 @@ void SVMCompiler::compile(Shader *shader,
|
||||
{
|
||||
const scoped_timer timer((summary != nullptr) ? &summary->time_generate_displacement :
|
||||
nullptr);
|
||||
compile_type(shader, shader->graph, SHADER_TYPE_DISPLACEMENT);
|
||||
compile_type(shader, shader->graph.get(), SHADER_TYPE_DISPLACEMENT);
|
||||
svm_nodes[index].w = svm_nodes.size();
|
||||
svm_nodes.append(current_svm_nodes);
|
||||
}
|
||||
|
||||
@@ -626,9 +626,9 @@ static void merge_scalar_grids_for_velocity(const Scene *scene, Volume *volume)
|
||||
|
||||
/* Make an attribute for it. */
|
||||
Attribute *attr = volume->attributes.add(ATTR_STD_VOLUME_VELOCITY);
|
||||
ImageLoader *loader = new VDBImageLoader(vecgrid, "merged_velocity");
|
||||
unique_ptr<ImageLoader> loader = make_unique<VDBImageLoader>(vecgrid, "merged_velocity");
|
||||
const ImageParams params;
|
||||
attr->data_voxel() = scene->image_manager->add_image(loader, params);
|
||||
attr->data_voxel() = scene->image_manager->add_image(std::move(loader), params);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
#include "kernel/types.h"
|
||||
|
||||
#include "util/string.h"
|
||||
#include "util/unique_ptr.h"
|
||||
#include "util/vector.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
|
||||
@@ -614,7 +614,7 @@ DenoiserPipeline::DenoiserPipeline(DeviceInfo &denoiser_device_info, const Denoi
|
||||
device_cpu_info(cpu_devices);
|
||||
cpu_device = device_cpu_create(cpu_devices[0], device->stats, device->profiler, true);
|
||||
|
||||
denoiser = Denoiser::create(device, cpu_device, params);
|
||||
denoiser = Denoiser::create(device.get(), cpu_device.get(), params);
|
||||
if (denoiser) {
|
||||
denoiser->load_kernels(nullptr);
|
||||
}
|
||||
@@ -623,7 +623,7 @@ DenoiserPipeline::DenoiserPipeline(DeviceInfo &denoiser_device_info, const Denoi
|
||||
DenoiserPipeline::~DenoiserPipeline()
|
||||
{
|
||||
denoiser.reset();
|
||||
delete device;
|
||||
device.reset();
|
||||
TaskScheduler::exit();
|
||||
}
|
||||
|
||||
@@ -645,7 +645,7 @@ bool DenoiserPipeline::run()
|
||||
}
|
||||
|
||||
/* Execute task. */
|
||||
DenoiseTask task(device, this, frame);
|
||||
DenoiseTask task(device.get(), this, frame);
|
||||
if (!task.load()) {
|
||||
error = task.error;
|
||||
return false;
|
||||
|
||||
@@ -47,8 +47,8 @@ class DenoiserPipeline {
|
||||
|
||||
Stats stats;
|
||||
Profiler profiler;
|
||||
Device *device;
|
||||
Device *cpu_device;
|
||||
unique_ptr<Device> device;
|
||||
unique_ptr<Device> cpu_device;
|
||||
std::unique_ptr<Denoiser> denoiser;
|
||||
};
|
||||
|
||||
|
||||
@@ -43,22 +43,26 @@ Session::Session(const SessionParams ¶ms_, const SceneParams &scene_params)
|
||||
progress.set_error(device->error_message());
|
||||
}
|
||||
|
||||
scene = new Scene(scene_params, device);
|
||||
scene = make_unique<Scene>(scene_params, device.get());
|
||||
|
||||
if (params.device == params.denoise_device) {
|
||||
denoise_device = device;
|
||||
/* Reuse render device. */
|
||||
}
|
||||
else {
|
||||
denoise_device = Device::create(params.denoise_device, stats, profiler, params_.headless);
|
||||
denoise_device_ = Device::create(params.denoise_device, stats, profiler, params_.headless);
|
||||
|
||||
if (denoise_device->have_error()) {
|
||||
progress.set_error(denoise_device->error_message());
|
||||
if (denoise_device_->have_error()) {
|
||||
progress.set_error(denoise_device_->error_message());
|
||||
}
|
||||
}
|
||||
|
||||
/* Configure path tracer. */
|
||||
path_trace_ = make_unique<PathTrace>(
|
||||
device, denoise_device, scene->film, &scene->dscene, render_scheduler_, tile_manager_);
|
||||
path_trace_ = make_unique<PathTrace>(device.get(),
|
||||
denoise_device(),
|
||||
scene->film,
|
||||
&scene->dscene,
|
||||
render_scheduler_,
|
||||
tile_manager_);
|
||||
path_trace_->set_progress(&progress);
|
||||
path_trace_->progress_update_cb = [&]() { update_status_time(); };
|
||||
|
||||
@@ -70,7 +74,7 @@ Session::Session(const SessionParams ¶ms_, const SceneParams &scene_params)
|
||||
};
|
||||
|
||||
/* Create session thread. */
|
||||
session_thread_ = new thread([this] { thread_run(); });
|
||||
session_thread_ = make_unique<thread>([this] { thread_run(); });
|
||||
}
|
||||
|
||||
Session::~Session()
|
||||
@@ -87,7 +91,7 @@ Session::~Session()
|
||||
|
||||
/* Destroy session thread. */
|
||||
session_thread_->join();
|
||||
delete session_thread_;
|
||||
session_thread_.reset();
|
||||
|
||||
/* Destroy path tracer, before the device. This is needed because destruction might need to
|
||||
* access device for device memory free.
|
||||
@@ -96,11 +100,9 @@ Session::~Session()
|
||||
path_trace_.reset();
|
||||
|
||||
/* Destroy scene and device. */
|
||||
delete scene;
|
||||
if (denoise_device != device) {
|
||||
delete denoise_device;
|
||||
}
|
||||
delete device;
|
||||
scene.reset();
|
||||
denoise_device_.reset();
|
||||
device.reset();
|
||||
|
||||
/* Stop task scheduler. */
|
||||
TaskScheduler::exit();
|
||||
@@ -345,7 +347,7 @@ RenderWork Session::run_update_for_next_iteration()
|
||||
|
||||
/* Update path guiding. */
|
||||
{
|
||||
const GuidingParams guiding_params = scene->integrator->get_guiding_params(device);
|
||||
const GuidingParams guiding_params = scene->integrator->get_guiding_params(device.get());
|
||||
const bool guiding_reset = (guiding_params.use) ? scene->need_reset(false) : false;
|
||||
path_trace_->set_guiding_params(guiding_params, guiding_reset);
|
||||
}
|
||||
@@ -537,11 +539,11 @@ void Session::do_delayed_reset()
|
||||
* tile results. It is safe to use generic update function here which checks for changes since
|
||||
* changes in tile settings re-creates session, which ensures film is fully updated on tile
|
||||
* changes. */
|
||||
scene->film->update_passes(scene, tile_manager_.has_multiple_tiles());
|
||||
scene->film->update_passes(scene.get(), tile_manager_.has_multiple_tiles());
|
||||
|
||||
/* Update for new state of scene and passes. */
|
||||
buffer_params_.update_passes(scene->passes);
|
||||
tile_manager_.update(buffer_params_, scene);
|
||||
tile_manager_.update(buffer_params_, scene.get());
|
||||
|
||||
/* Update temp directory on reset.
|
||||
* This potentially allows to finish the existing rendering with a previously configure
|
||||
@@ -755,7 +757,7 @@ void Session::collect_statistics(RenderStats *render_stats)
|
||||
{
|
||||
scene->collect_statistics(render_stats);
|
||||
if (params.use_profiling && (params.device.type == DEVICE_CPU)) {
|
||||
render_stats->collect_profiling(scene, profiler);
|
||||
render_stats->collect_profiling(scene.get(), profiler);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -107,10 +107,10 @@ class SessionParams {
|
||||
|
||||
class Session {
|
||||
public:
|
||||
Device *device;
|
||||
unique_ptr<Device> device;
|
||||
/* Denoiser device. Could be the same as the path trace device. */
|
||||
Device *denoise_device;
|
||||
Scene *scene;
|
||||
unique_ptr<Device> denoise_device_;
|
||||
unique_ptr<Scene> scene;
|
||||
Progress progress;
|
||||
SessionParams params;
|
||||
Stats stats;
|
||||
@@ -208,10 +208,16 @@ class Session {
|
||||
|
||||
int2 get_effective_tile_size() const;
|
||||
|
||||
/* Get device used for denoising, may be the same as render device. */
|
||||
Device *denoise_device()
|
||||
{
|
||||
return (denoise_device_) ? denoise_device_.get() : device.get();
|
||||
}
|
||||
|
||||
/* Session thread that performs rendering tasks decoupled from the thread
|
||||
* controlling the sessions. The thread is created and destroyed along with
|
||||
* the session. */
|
||||
thread *session_thread_ = nullptr;
|
||||
unique_ptr<thread> session_thread_ = nullptr;
|
||||
thread_condition_variable session_thread_cond_;
|
||||
thread_mutex session_thread_mutex_;
|
||||
enum {
|
||||
|
||||
@@ -157,9 +157,9 @@ class RenderGraph : public testing::Test {
|
||||
Stats stats;
|
||||
Profiler profiler;
|
||||
DeviceInfo device_info;
|
||||
Device *device_cpu;
|
||||
unique_ptr<Device> device_cpu;
|
||||
SceneParams scene_params;
|
||||
Scene *scene;
|
||||
unique_ptr<Scene> scene;
|
||||
ShaderGraph graph;
|
||||
ShaderGraphBuilder builder;
|
||||
|
||||
@@ -175,7 +175,7 @@ class RenderGraph : public testing::Test {
|
||||
ColorSpaceManager::init_fallback_config();
|
||||
|
||||
device_cpu = Device::create(device_info, stats, profiler, true);
|
||||
scene = new Scene(scene_params, device_cpu);
|
||||
scene = make_unique<Scene>(scene_params, device_cpu.get());
|
||||
|
||||
/* Initialize logging after the creation of the essential resources. This way the logging
|
||||
* mock sink does not warn about uninteresting messages which happens prior to the setup of
|
||||
@@ -190,8 +190,8 @@ class RenderGraph : public testing::Test {
|
||||
* not logging by default. */
|
||||
util_logging_verbosity_set(0);
|
||||
|
||||
delete scene;
|
||||
delete device_cpu;
|
||||
scene.reset();
|
||||
device_cpu.reset();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -230,7 +230,7 @@ TEST_F(RenderGraph, deduplicate_deep)
|
||||
.add_connection("Noise2::Color", "Mix::Color2")
|
||||
.output_color("Mix::Color");
|
||||
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
|
||||
EXPECT_EQ(graph.nodes.size(), 5);
|
||||
}
|
||||
@@ -250,7 +250,7 @@ TEST_F(RenderGraph, constant_fold_rgb_to_bw)
|
||||
.set("Color", make_float3(0.8f, 0.8f, 0.8f)))
|
||||
.output_color("RGBToBWNodeNode::Val");
|
||||
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -265,7 +265,7 @@ TEST_F(RenderGraph, constant_fold_emission1)
|
||||
builder.add_node(ShaderNodeBuilder<EmissionNode>(graph, "Emission").set("Color", zero_float3()))
|
||||
.output_closure("Emission::Emission");
|
||||
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
TEST_F(RenderGraph, constant_fold_emission2)
|
||||
@@ -276,7 +276,7 @@ TEST_F(RenderGraph, constant_fold_emission2)
|
||||
builder.add_node(ShaderNodeBuilder<EmissionNode>(graph, "Emission").set("Strength", 0.0f))
|
||||
.output_closure("Emission::Emission");
|
||||
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -292,7 +292,7 @@ TEST_F(RenderGraph, constant_fold_background1)
|
||||
.add_node(ShaderNodeBuilder<BackgroundNode>(graph, "Background").set("Color", zero_float3()))
|
||||
.output_closure("Background::Background");
|
||||
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
TEST_F(RenderGraph, constant_fold_background2)
|
||||
@@ -303,7 +303,7 @@ TEST_F(RenderGraph, constant_fold_background2)
|
||||
builder.add_node(ShaderNodeBuilder<BackgroundNode>(graph, "Background").set("Strength", 0.0f))
|
||||
.output_closure("Background::Background");
|
||||
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -327,7 +327,7 @@ TEST_F(RenderGraph, constant_fold_shader_add)
|
||||
.add_connection("AddClosure2::Closure", "AddClosure3::Closure2")
|
||||
.output_closure("AddClosure3::Closure");
|
||||
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -357,7 +357,7 @@ TEST_F(RenderGraph, constant_fold_shader_mix)
|
||||
.add_connection("MixClosure2::Closure", "MixClosure3::Closure2")
|
||||
.output_closure("MixClosure3::Closure");
|
||||
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -375,7 +375,7 @@ TEST_F(RenderGraph, constant_fold_invert)
|
||||
.set("Color", make_float3(0.2f, 0.5f, 0.8f)))
|
||||
.output_color("Invert::Color");
|
||||
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -392,7 +392,7 @@ TEST_F(RenderGraph, constant_fold_invert_fac_0)
|
||||
.add_connection("Attribute::Color", "Invert::Color")
|
||||
.output_color("Invert::Color");
|
||||
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -410,7 +410,7 @@ TEST_F(RenderGraph, constant_fold_invert_fac_0_const)
|
||||
.set("Color", make_float3(0.2f, 0.5f, 0.8f)))
|
||||
.output_color("Invert::Color");
|
||||
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -431,7 +431,7 @@ TEST_F(RenderGraph, constant_fold_mix_add)
|
||||
.set("Color2", make_float3(0.4f, 0.8f, 0.9f)))
|
||||
.output_color("MixAdd::Color");
|
||||
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -452,7 +452,7 @@ TEST_F(RenderGraph, constant_fold_mix_add_clamp)
|
||||
.set("Color2", make_float3(0.4f, 0.8f, 0.9f)))
|
||||
.output_color("MixAdd::Color");
|
||||
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -474,7 +474,7 @@ TEST_F(RenderGraph, constant_fold_part_mix_dodge_no_fac_0)
|
||||
.add_connection("Attribute2::Color", "Mix::Color2")
|
||||
.output_color("Mix::Color");
|
||||
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -496,7 +496,7 @@ TEST_F(RenderGraph, constant_fold_part_mix_light_no_fac_0)
|
||||
.add_connection("Attribute2::Color", "Mix::Color2")
|
||||
.output_color("Mix::Color");
|
||||
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -518,7 +518,7 @@ TEST_F(RenderGraph, constant_fold_part_mix_burn_no_fac_0)
|
||||
.add_connection("Attribute2::Color", "Mix::Color2")
|
||||
.output_color("Mix::Color");
|
||||
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -540,7 +540,7 @@ TEST_F(RenderGraph, constant_fold_part_mix_blend_clamped_no_fac_0)
|
||||
.add_connection("Attribute2::Color", "Mix::Color2")
|
||||
.output_color("Mix::Color");
|
||||
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -580,7 +580,7 @@ TEST_F(RenderGraph, constant_fold_part_mix_blend)
|
||||
.add_connection("MixBlend2::Color", "MixBlend3::Color2")
|
||||
.output_color("MixBlend3::Color");
|
||||
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -601,7 +601,7 @@ TEST_F(RenderGraph, constant_fold_part_mix_sub_same_fac_bad)
|
||||
.add_connection("Attribute::Color", "Mix::Color2")
|
||||
.output_color("Mix::Color");
|
||||
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -622,7 +622,7 @@ TEST_F(RenderGraph, constant_fold_part_mix_sub_same_fac_1)
|
||||
.add_connection("Attribute::Color", "Mix::Color2")
|
||||
.output_color("Mix::Color");
|
||||
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -698,7 +698,7 @@ TEST_F(RenderGraph, constant_fold_part_mix_add_0)
|
||||
INVALID_INFO_MESSAGE(log, "Folding Out");
|
||||
|
||||
build_mix_partial_test_graph(builder, NODE_MIX_ADD, make_float3(0, 0, 0));
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -715,7 +715,7 @@ TEST_F(RenderGraph, constant_fold_part_mix_sub_0)
|
||||
INVALID_INFO_MESSAGE(log, "Folding Out");
|
||||
|
||||
build_mix_partial_test_graph(builder, NODE_MIX_SUB, make_float3(0, 0, 0));
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -733,7 +733,7 @@ TEST_F(RenderGraph, constant_fold_part_mix_mul_1)
|
||||
INVALID_INFO_MESSAGE(log, "Folding Out");
|
||||
|
||||
build_mix_partial_test_graph(builder, NODE_MIX_MUL, make_float3(1, 1, 1));
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -750,7 +750,7 @@ TEST_F(RenderGraph, constant_fold_part_mix_div_1)
|
||||
INVALID_INFO_MESSAGE(log, "Folding Out");
|
||||
|
||||
build_mix_partial_test_graph(builder, NODE_MIX_DIV, make_float3(1, 1, 1));
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -770,7 +770,7 @@ TEST_F(RenderGraph, constant_fold_part_mix_mul_0)
|
||||
INVALID_INFO_MESSAGE(log, "Folding Out1234");
|
||||
|
||||
build_mix_partial_test_graph(builder, NODE_MIX_MUL, make_float3(0, 0, 0));
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -789,7 +789,7 @@ TEST_F(RenderGraph, constant_fold_part_mix_div_0)
|
||||
INVALID_INFO_MESSAGE(log, "Folding Out1234");
|
||||
|
||||
build_mix_partial_test_graph(builder, NODE_MIX_DIV, make_float3(0, 0, 0));
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -812,7 +812,7 @@ TEST_F(RenderGraph, constant_fold_separate_combine_rgb)
|
||||
.add_connection("SeparateRGB::B", "CombineRGB::B")
|
||||
.output_color("CombineRGB::Image");
|
||||
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -837,7 +837,7 @@ TEST_F(RenderGraph, constant_fold_separate_combine_xyz)
|
||||
.add_connection("SeparateXYZ::Z", "CombineXYZ::Z")
|
||||
.output_color("CombineXYZ::Vector");
|
||||
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -860,7 +860,7 @@ TEST_F(RenderGraph, constant_fold_separate_combine_hsv)
|
||||
.add_connection("SeparateHSV::V", "CombineHSV::V")
|
||||
.output_color("CombineHSV::Color");
|
||||
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -877,7 +877,7 @@ TEST_F(RenderGraph, constant_fold_gamma)
|
||||
.set("Gamma", 1.5f))
|
||||
.output_color("Gamma::Color");
|
||||
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -906,7 +906,7 @@ TEST_F(RenderGraph, constant_fold_gamma_part_0)
|
||||
.add_connection("Gamma_xC::Color", "Out::Color2")
|
||||
.output_color("Out::Color");
|
||||
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -935,7 +935,7 @@ TEST_F(RenderGraph, constant_fold_gamma_part_1)
|
||||
.add_connection("Gamma_xC::Color", "Out::Color2")
|
||||
.output_color("Out::Color");
|
||||
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -953,7 +953,7 @@ TEST_F(RenderGraph, constant_fold_bright_contrast)
|
||||
.set("Contrast", 1.2f))
|
||||
.output_color("BrightContrast::Color");
|
||||
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -968,7 +968,7 @@ TEST_F(RenderGraph, constant_fold_blackbody)
|
||||
.add_node(ShaderNodeBuilder<BlackbodyNode>(graph, "Blackbody").set("Temperature", 1200.0f))
|
||||
.output_color("Blackbody::Color");
|
||||
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/* A Note About The Math Node
|
||||
@@ -994,7 +994,7 @@ TEST_F(RenderGraph, constant_fold_math)
|
||||
.set("Value2", 0.9f))
|
||||
.output_value("Math::Value");
|
||||
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1013,7 +1013,7 @@ TEST_F(RenderGraph, constant_fold_math_clamp)
|
||||
.set("Value2", 0.9f))
|
||||
.output_value("Math::Value");
|
||||
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1059,7 +1059,7 @@ TEST_F(RenderGraph, constant_fold_part_math_add_0)
|
||||
INVALID_INFO_MESSAGE(log, "Folding clamp::");
|
||||
|
||||
build_math_partial_test_graph(builder, NODE_MATH_ADD, 0.0f);
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1074,7 +1074,7 @@ TEST_F(RenderGraph, constant_fold_part_math_sub_0)
|
||||
INVALID_INFO_MESSAGE(log, "Folding clamp::");
|
||||
|
||||
build_math_partial_test_graph(builder, NODE_MATH_SUBTRACT, 0.0f);
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1089,7 +1089,7 @@ TEST_F(RenderGraph, constant_fold_part_math_mul_1)
|
||||
INVALID_INFO_MESSAGE(log, "Folding clamp::");
|
||||
|
||||
build_math_partial_test_graph(builder, NODE_MATH_MULTIPLY, 1.0f);
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1104,7 +1104,7 @@ TEST_F(RenderGraph, constant_fold_part_math_div_1)
|
||||
INVALID_INFO_MESSAGE(log, "Folding clamp::");
|
||||
|
||||
build_math_partial_test_graph(builder, NODE_MATH_DIVIDE, 1.0f);
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1120,7 +1120,7 @@ TEST_F(RenderGraph, constant_fold_part_math_mul_0)
|
||||
CORRECT_INFO_MESSAGE(log, "Discarding closure EmissionNode.");
|
||||
|
||||
build_math_partial_test_graph(builder, NODE_MATH_MULTIPLY, 0.0f);
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1135,7 +1135,7 @@ TEST_F(RenderGraph, constant_fold_part_math_div_0)
|
||||
INVALID_INFO_MESSAGE(log, "Folding clamp::");
|
||||
|
||||
build_math_partial_test_graph(builder, NODE_MATH_DIVIDE, 0.0f);
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1150,7 +1150,7 @@ TEST_F(RenderGraph, constant_fold_part_math_pow_0)
|
||||
INVALID_INFO_MESSAGE(log, "Folding clamp::");
|
||||
|
||||
build_math_partial_test_graph(builder, NODE_MATH_POWER, 0.0f);
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1165,7 +1165,7 @@ TEST_F(RenderGraph, constant_fold_part_math_pow_1)
|
||||
INVALID_INFO_MESSAGE(log, "Folding clamp::");
|
||||
|
||||
build_math_partial_test_graph(builder, NODE_MATH_POWER, 1.0f);
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1183,7 +1183,7 @@ TEST_F(RenderGraph, constant_fold_vector_math)
|
||||
.set("Vector2", make_float3(-1.7f, 0.5f, 0.7f)))
|
||||
.output_color("VectorMath::Vector");
|
||||
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1226,7 +1226,7 @@ TEST_F(RenderGraph, constant_fold_part_vecmath_add_0)
|
||||
INVALID_INFO_MESSAGE(log, "Folding Out::");
|
||||
|
||||
build_vecmath_partial_test_graph(builder, NODE_VECTOR_MATH_ADD, make_float3(0, 0, 0));
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1241,7 +1241,7 @@ TEST_F(RenderGraph, constant_fold_part_vecmath_sub_0)
|
||||
INVALID_INFO_MESSAGE(log, "Folding Out::");
|
||||
|
||||
build_vecmath_partial_test_graph(builder, NODE_VECTOR_MATH_SUBTRACT, make_float3(0, 0, 0));
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1257,7 +1257,7 @@ TEST_F(RenderGraph, constant_fold_part_vecmath_cross_0)
|
||||
CORRECT_INFO_MESSAGE(log, "Discarding closure EmissionNode.");
|
||||
|
||||
build_vecmath_partial_test_graph(builder, NODE_VECTOR_MATH_CROSS_PRODUCT, make_float3(0, 0, 0));
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1273,7 +1273,7 @@ TEST_F(RenderGraph, constant_fold_bump)
|
||||
.add_connection("Geometry1::Normal", "Bump::Normal")
|
||||
.output_color("Bump::Normal");
|
||||
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1286,7 +1286,7 @@ TEST_F(RenderGraph, constant_fold_bump_no_input)
|
||||
|
||||
builder.add_node(ShaderNodeBuilder<BumpNode>(graph, "Bump")).output_color("Bump::Normal");
|
||||
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
template<class T> void init_test_curve(array<T> &buffer, T start, T end, const int steps)
|
||||
@@ -1319,7 +1319,7 @@ TEST_F(RenderGraph, constant_fold_rgb_curves)
|
||||
.set("Color", make_float3(0.3f, 0.5f, 0.7f)))
|
||||
.output_color("Curves::Color");
|
||||
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1343,7 +1343,7 @@ TEST_F(RenderGraph, constant_fold_rgb_curves_fac_0)
|
||||
.add_connection("Attribute::Color", "Curves::Color")
|
||||
.output_color("Curves::Color");
|
||||
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1367,7 +1367,7 @@ TEST_F(RenderGraph, constant_fold_rgb_curves_fac_0_const)
|
||||
.set("Color", make_float3(0.3f, 0.5f, 0.7f)))
|
||||
.output_color("Curves::Color");
|
||||
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1391,7 +1391,7 @@ TEST_F(RenderGraph, constant_fold_vector_curves)
|
||||
.set("Vector", make_float3(0.3f, 0.5f, 0.7f)))
|
||||
.output_color("Curves::Vector");
|
||||
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1415,7 +1415,7 @@ TEST_F(RenderGraph, constant_fold_vector_curves_fac_0)
|
||||
.add_connection("Attribute::Vector", "Curves::Vector")
|
||||
.output_color("Curves::Vector");
|
||||
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1444,7 +1444,7 @@ TEST_F(RenderGraph, constant_fold_rgb_ramp)
|
||||
.add_connection("Ramp::Alpha", "Mix::Color2")
|
||||
.output_color("Mix::Color");
|
||||
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1473,7 +1473,7 @@ TEST_F(RenderGraph, constant_fold_rgb_ramp_flat)
|
||||
.add_connection("Ramp::Alpha", "Mix::Color2")
|
||||
.output_color("Mix::Color");
|
||||
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1493,7 +1493,7 @@ TEST_F(RenderGraph, constant_fold_convert_float_color_float)
|
||||
.add_connection("Attribute::Fac", "Invert::Color")
|
||||
.output_value("Invert::Color");
|
||||
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1515,7 +1515,7 @@ TEST_F(RenderGraph, constant_fold_convert_color_vector_color)
|
||||
.add_connection("Attribute::Color", "VecAdd::Vector1")
|
||||
.output_color("VecAdd::Vector");
|
||||
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1536,7 +1536,7 @@ TEST_F(RenderGraph, constant_fold_convert_color_float_color)
|
||||
.add_connection("Attribute::Color", "MathAdd::Value1")
|
||||
.output_color("MathAdd::Value");
|
||||
|
||||
graph.finalize(scene);
|
||||
graph.finalize(scene.get());
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
Profiler::Profiler() : do_stop_worker(true), worker(nullptr) {}
|
||||
Profiler::Profiler() : do_stop_worker(true) {}
|
||||
|
||||
Profiler::~Profiler()
|
||||
{
|
||||
@@ -76,7 +76,7 @@ void Profiler::start()
|
||||
{
|
||||
assert(worker == nullptr);
|
||||
do_stop_worker = false;
|
||||
worker = new thread([this] { run(); });
|
||||
worker = make_unique<thread>([this] { run(); });
|
||||
}
|
||||
|
||||
void Profiler::stop()
|
||||
@@ -85,8 +85,7 @@ void Profiler::stop()
|
||||
do_stop_worker = true;
|
||||
|
||||
worker->join();
|
||||
delete worker;
|
||||
worker = nullptr;
|
||||
worker.reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <cassert>
|
||||
|
||||
#include "util/thread.h"
|
||||
#include "util/unique_ptr.h"
|
||||
#include "util/vector.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
@@ -104,7 +105,7 @@ class Profiler {
|
||||
vector<uint64_t> object_hits;
|
||||
|
||||
volatile bool do_stop_worker;
|
||||
thread *worker;
|
||||
unique_ptr<thread> worker;
|
||||
|
||||
thread_mutex mutex;
|
||||
vector<ProfilingState *> states;
|
||||
|
||||
@@ -55,7 +55,7 @@ bool TaskPool::canceled()
|
||||
thread_mutex TaskScheduler::mutex;
|
||||
int TaskScheduler::users = 0;
|
||||
int TaskScheduler::active_num_threads = 0;
|
||||
tbb::global_control *TaskScheduler::global_control = nullptr;
|
||||
unique_ptr<tbb::global_control> TaskScheduler::global_control;
|
||||
|
||||
void TaskScheduler::init(const int num_threads)
|
||||
{
|
||||
@@ -69,8 +69,8 @@ void TaskScheduler::init(const int num_threads)
|
||||
if (num_threads > 0) {
|
||||
/* Automatic number of threads. */
|
||||
VLOG_INFO << "Overriding number of TBB threads to " << num_threads << ".";
|
||||
global_control = new tbb::global_control(tbb::global_control::max_allowed_parallelism,
|
||||
num_threads);
|
||||
global_control = make_unique<tbb::global_control>(tbb::global_control::max_allowed_parallelism,
|
||||
num_threads);
|
||||
active_num_threads = num_threads;
|
||||
}
|
||||
else {
|
||||
@@ -83,8 +83,7 @@ void TaskScheduler::exit()
|
||||
const thread_scoped_lock lock(mutex);
|
||||
users--;
|
||||
if (users == 0) {
|
||||
delete global_control;
|
||||
global_control = nullptr;
|
||||
global_control.reset();
|
||||
active_num_threads = 0;
|
||||
}
|
||||
}
|
||||
@@ -108,7 +107,7 @@ DedicatedTaskPool::DedicatedTaskPool()
|
||||
do_exit = false;
|
||||
num = 0;
|
||||
|
||||
worker_thread = new thread([this] { thread_run(); });
|
||||
worker_thread = make_unique<thread>([this] { thread_run(); });
|
||||
}
|
||||
|
||||
DedicatedTaskPool::~DedicatedTaskPool()
|
||||
@@ -119,7 +118,7 @@ DedicatedTaskPool::~DedicatedTaskPool()
|
||||
queue_cond.notify_all();
|
||||
|
||||
worker_thread->join();
|
||||
delete worker_thread;
|
||||
worker_thread.reset();
|
||||
}
|
||||
|
||||
void DedicatedTaskPool::push(TaskRunFunction &&run, bool front)
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "util/string.h"
|
||||
#include "util/tbb.h"
|
||||
#include "util/thread.h"
|
||||
#include "util/unique_ptr.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
@@ -83,7 +84,7 @@ class TaskScheduler {
|
||||
static int active_num_threads;
|
||||
|
||||
#ifdef WITH_TBB_GLOBAL_CONTROL
|
||||
static tbb::global_control *global_control;
|
||||
static unique_ptr<tbb::global_control> global_control;
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -125,7 +126,7 @@ class DedicatedTaskPool {
|
||||
bool do_cancel;
|
||||
bool do_exit;
|
||||
|
||||
thread *worker_thread;
|
||||
unique_ptr<thread> worker_thread;
|
||||
};
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
Reference in New Issue
Block a user