Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/render')
-rw-r--r--intern/cycles/render/geometry.cpp88
-rw-r--r--intern/cycles/render/geometry.h3
-rw-r--r--intern/cycles/render/hair.cpp35
-rw-r--r--intern/cycles/render/hair.h2
-rw-r--r--intern/cycles/render/image.cpp4
-rw-r--r--intern/cycles/render/mesh.cpp31
-rw-r--r--intern/cycles/render/mesh.h5
-rw-r--r--intern/cycles/render/scene.cpp5
-rw-r--r--intern/cycles/render/scene.h2
-rw-r--r--intern/cycles/render/shader.cpp11
10 files changed, 151 insertions, 35 deletions
diff --git a/intern/cycles/render/geometry.cpp b/intern/cycles/render/geometry.cpp
index 12f4eaf0b79..64b98a91853 100644
--- a/intern/cycles/render/geometry.cpp
+++ b/intern/cycles/render/geometry.cpp
@@ -15,8 +15,7 @@
*/
#include "bvh/bvh.h"
-#include "bvh/bvh_build.h"
-#include "bvh/bvh_embree.h"
+#include "bvh/bvh2.h"
#include "device/device.h"
@@ -41,6 +40,7 @@
#include "util/util_foreach.h"
#include "util/util_logging.h"
#include "util/util_progress.h"
+#include "util/util_task.h"
CCL_NAMESPACE_BEGIN
@@ -162,7 +162,8 @@ int Geometry::motion_step(float time) const
bool Geometry::need_build_bvh(BVHLayout layout) const
{
- return !transform_applied || has_surface_bssrdf || layout == BVH_LAYOUT_OPTIX;
+ return is_instanced() || layout == BVH_LAYOUT_OPTIX || layout == BVH_LAYOUT_MULTI_OPTIX ||
+ layout == BVH_LAYOUT_MULTI_OPTIX_EMBREE;
}
bool Geometry::is_instanced() const
@@ -218,7 +219,7 @@ void Geometry::compute_bvh(
bvh->geometry = geometry;
bvh->objects = objects;
- bvh->refit(*progress);
+ device->build_bvh(bvh, *progress, true);
}
else {
progress->set_status(msg, "Building BVH");
@@ -235,7 +236,7 @@ void Geometry::compute_bvh(
delete bvh;
bvh = BVH::create(bparams, geometry, objects, device);
- MEM_GUARDED_CALL(progress, bvh->build, *progress);
+ MEM_GUARDED_CALL(progress, device->build_bvh, bvh, *progress, false);
}
}
@@ -1162,25 +1163,66 @@ void GeometryManager::device_update_bvh(Device *device,
VLOG(1) << "Using " << bvh_layout_name(bparams.bvh_layout) << " layout.";
- BVH *bvh = BVH::create(bparams, scene->geometry, scene->objects, device);
- bvh->build(progress, &device->stats);
+ delete scene->bvh;
+ BVH *bvh = scene->bvh = BVH::create(bparams, scene->geometry, scene->objects, device);
+ device->build_bvh(bvh, progress, false);
if (progress.get_cancel()) {
-#ifdef WITH_EMBREE
- if (dscene->data.bvh.scene) {
- BVHEmbree::destroy(dscene->data.bvh.scene);
- dscene->data.bvh.scene = NULL;
- }
-#endif
- delete bvh;
return;
}
+ PackedBVH pack;
+ if (bparams.bvh_layout == BVH_LAYOUT_BVH2) {
+ pack = std::move(static_cast<BVH2 *>(bvh)->pack);
+ }
+ else {
+ progress.set_status("Updating Scene BVH", "Packing BVH primitives");
+
+ size_t num_prims = 0;
+ size_t num_tri_verts = 0;
+ foreach (Geometry *geom, scene->geometry) {
+ if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) {
+ Mesh *mesh = static_cast<Mesh *>(geom);
+ num_prims += mesh->num_triangles();
+ num_tri_verts += 3 * mesh->num_triangles();
+ }
+ else if (geom->is_hair()) {
+ Hair *hair = static_cast<Hair *>(geom);
+ num_prims += hair->num_segments();
+ }
+ }
+
+ pack.root_index = -1;
+ pack.prim_tri_index.reserve(num_prims);
+ pack.prim_tri_verts.reserve(num_tri_verts);
+ pack.prim_type.reserve(num_prims);
+ pack.prim_index.reserve(num_prims);
+ pack.prim_object.reserve(num_prims);
+ pack.prim_visibility.reserve(num_prims);
+
+ // Merge visibility flags of all objects and find object index for non-instanced geometry
+ unordered_map<const Geometry *, pair<int, uint>> geometry_to_object_info;
+ geometry_to_object_info.reserve(scene->geometry.size());
+ foreach (Object *ob, scene->objects) {
+ const Geometry *const geom = ob->get_geometry();
+ pair<int, uint> &info = geometry_to_object_info[geom];
+ info.second |= ob->visibility_for_tracing();
+ if (!geom->is_instanced()) {
+ info.first = ob->get_device_index();
+ }
+ }
+
+ // Iterate over scene mesh list instead of objects, since 'optix_prim_offset' was calculated
+ // based on that list, which may be ordered differently from the object list.
+ foreach (Geometry *geom, scene->geometry) {
+ const pair<int, uint> &info = geometry_to_object_info[geom];
+ geom->pack_primitives(pack, info.first, info.second);
+ }
+ }
+
/* copy to device */
progress.set_status("Updating Scene BVH", "Copying BVH to device");
- PackedBVH &pack = bvh->pack;
-
if (pack.nodes.size()) {
dscene->bvh_nodes.steal_data(pack.nodes);
dscene->bvh_nodes.copy_to_device();
@@ -1226,10 +1268,8 @@ void GeometryManager::device_update_bvh(Device *device,
dscene->data.bvh.bvh_layout = bparams.bvh_layout;
dscene->data.bvh.use_bvh_steps = (scene->params.num_bvh_time_steps != 0);
dscene->data.bvh.curve_subdivisions = scene->params.curve_subdivisions();
-
- bvh->copy_to_device(progress, dscene);
-
- delete bvh;
+ /* The scene handle is set in 'CPUDevice::const_copy_to' and 'OptiXDevice::const_copy_to' */
+ dscene->data.bvh.scene = NULL;
}
void GeometryManager::device_update_preprocess(Device *device, Scene *scene, Progress &progress)
@@ -1653,14 +1693,6 @@ void GeometryManager::device_update(Device *device,
void GeometryManager::device_free(Device *device, DeviceScene *dscene)
{
-#ifdef WITH_EMBREE
- if (dscene->data.bvh.scene) {
- if (dscene->data.bvh.bvh_layout == BVH_LAYOUT_EMBREE)
- BVHEmbree::destroy(dscene->data.bvh.scene);
- dscene->data.bvh.scene = NULL;
- }
-#endif
-
dscene->bvh_nodes.free();
dscene->bvh_leaf_nodes.free();
dscene->object_node.free();
diff --git a/intern/cycles/render/geometry.h b/intern/cycles/render/geometry.h
index 1c101540464..d3daf0cc809 100644
--- a/intern/cycles/render/geometry.h
+++ b/intern/cycles/render/geometry.h
@@ -41,6 +41,7 @@ class Scene;
class SceneParams;
class Shader;
class Volume;
+struct PackedBVH;
/* Geometry
*
@@ -124,6 +125,8 @@ class Geometry : public Node {
int n,
int total);
+ virtual void pack_primitives(PackedBVH &pack, int object, uint visibility) = 0;
+
/* Check whether the geometry should have own BVH built separately. Briefly,
* own BVH is needed for geometry, if:
*
diff --git a/intern/cycles/render/hair.cpp b/intern/cycles/render/hair.cpp
index d67bd209142..896e798b6f9 100644
--- a/intern/cycles/render/hair.cpp
+++ b/intern/cycles/render/hair.cpp
@@ -14,8 +14,10 @@
* limitations under the License.
*/
-#include "render/hair.h"
+#include "bvh/bvh.h"
+
#include "render/curves.h"
+#include "render/hair.h"
#include "render/scene.h"
CCL_NAMESPACE_BEGIN
@@ -492,4 +494,35 @@ void Hair::pack_curves(Scene *scene,
}
}
+void Hair::pack_primitives(PackedBVH &pack, int object, uint visibility)
+{
+ if (curve_first_key.empty())
+ return;
+
+ const size_t num_prims = num_segments();
+ pack.prim_tri_index.reserve(pack.prim_tri_index.size() + num_prims);
+ pack.prim_type.reserve(pack.prim_type.size() + num_prims);
+ pack.prim_visibility.reserve(pack.prim_visibility.size() + num_prims);
+ pack.prim_index.reserve(pack.prim_index.size() + num_prims);
+ pack.prim_object.reserve(pack.prim_object.size() + num_prims);
+ // 'pack.prim_time' is unused by Embree and OptiX
+
+ uint type = has_motion_blur() ?
+ ((curve_shape == CURVE_RIBBON) ? PRIMITIVE_MOTION_CURVE_RIBBON :
+ PRIMITIVE_MOTION_CURVE_THICK) :
+ ((curve_shape == CURVE_RIBBON) ? PRIMITIVE_CURVE_RIBBON : PRIMITIVE_CURVE_THICK);
+
+ for (size_t j = 0; j < num_curves(); ++j) {
+ Curve curve = get_curve(j);
+ for (size_t k = 0; k < curve.num_segments(); ++k) {
+ pack.prim_tri_index.push_back_reserved(-1);
+ pack.prim_type.push_back_reserved(PRIMITIVE_PACK_SEGMENT(type, k));
+ pack.prim_visibility.push_back_reserved(visibility);
+ // Each curve segment points back to its curve index
+ pack.prim_index.push_back_reserved(j + prim_offset);
+ pack.prim_object.push_back_reserved(object);
+ }
+ }
+}
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/hair.h b/intern/cycles/render/hair.h
index 32c5b00e879..c7be08d679c 100644
--- a/intern/cycles/render/hair.h
+++ b/intern/cycles/render/hair.h
@@ -145,6 +145,8 @@ class Hair : public Geometry {
/* BVH */
void pack_curves(Scene *scene, float4 *curve_key_co, float4 *curve_data, size_t curvekey_offset);
+
+ void pack_primitives(PackedBVH &pack, int object, uint visibility) override;
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp
index 3e6ff289c85..30858c4f68b 100644
--- a/intern/cycles/render/image.cpp
+++ b/intern/cycles/render/image.cpp
@@ -493,8 +493,8 @@ static bool image_associate_alpha(ImageManager::Image *img)
template<TypeDesc::BASETYPE FileFormat, typename StorageType>
bool ImageManager::file_load_image(Image *img, int texture_limit)
{
- /* we only handle certain number of components */
- if (!(img->metadata.channels >= 1 && img->metadata.channels <= 4)) {
+ /* Ignore empty images. */
+ if (!(img->metadata.channels > 0)) {
return false;
}
diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp
index 43e664a686f..a0afdd3b841 100644
--- a/intern/cycles/render/mesh.cpp
+++ b/intern/cycles/render/mesh.cpp
@@ -805,4 +805,35 @@ void Mesh::pack_patches(uint *patch_data, uint vert_offset, uint face_offset, ui
}
}
+void Mesh::pack_primitives(PackedBVH &pack, int object, uint visibility)
+{
+ if (triangles.empty())
+ return;
+
+ const size_t num_prims = num_triangles();
+ pack.prim_tri_index.reserve(pack.prim_tri_index.size() + num_prims);
+ pack.prim_tri_verts.reserve(pack.prim_tri_verts.size() + num_prims * 3);
+ pack.prim_type.reserve(pack.prim_type.size() + num_prims);
+ pack.prim_visibility.reserve(pack.prim_visibility.size() + num_prims);
+ pack.prim_index.reserve(pack.prim_index.size() + num_prims);
+ pack.prim_object.reserve(pack.prim_object.size() + num_prims);
+ // 'pack.prim_time' is unused by Embree and OptiX
+
+ uint type = has_motion_blur() ? PRIMITIVE_MOTION_TRIANGLE : PRIMITIVE_TRIANGLE;
+
+ for (size_t k = 0; k < num_prims; ++k) {
+ pack.prim_tri_index.push_back_reserved(pack.prim_tri_verts.size());
+
+ const Mesh::Triangle t = get_triangle(k);
+ pack.prim_tri_verts.push_back_reserved(float3_to_float4(verts[t.v[0]]));
+ pack.prim_tri_verts.push_back_reserved(float3_to_float4(verts[t.v[1]]));
+ pack.prim_tri_verts.push_back_reserved(float3_to_float4(verts[t.v[2]]));
+
+ pack.prim_type.push_back_reserved(type);
+ pack.prim_visibility.push_back_reserved(visibility);
+ pack.prim_index.push_back_reserved(k + prim_offset);
+ pack.prim_object.push_back_reserved(object);
+ }
+}
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/mesh.h b/intern/cycles/render/mesh.h
index e2746e560da..b0a16fdfd8f 100644
--- a/intern/cycles/render/mesh.h
+++ b/intern/cycles/render/mesh.h
@@ -184,9 +184,8 @@ class Mesh : public Geometry {
unordered_multimap<int, int>
vert_stitching_map; /* stitching index -> multiple real vert indices */
- friend class BVH;
+ friend class BVH2;
friend class BVHBuild;
- friend class BVHEmbree;
friend class BVHSpatialSplit;
friend class DiagSplit;
friend class EdgeDice;
@@ -233,6 +232,8 @@ class Mesh : public Geometry {
size_t tri_offset);
void pack_patches(uint *patch_data, uint vert_offset, uint face_offset, uint corner_offset);
+ void pack_primitives(PackedBVH &pack, int object, uint visibility) override;
+
void tessellate(DiagSplit *split);
SubdFace get_subd_face(size_t index) const;
diff --git a/intern/cycles/render/scene.cpp b/intern/cycles/render/scene.cpp
index 98c256a43b5..b7720b7aa99 100644
--- a/intern/cycles/render/scene.cpp
+++ b/intern/cycles/render/scene.cpp
@@ -16,6 +16,7 @@
#include <stdlib.h>
+#include "bvh/bvh.h"
#include "device/device.h"
#include "render/background.h"
#include "render/bake.h"
@@ -100,6 +101,7 @@ Scene::Scene(const SceneParams &params_, Device *device)
{
memset((void *)&dscene.data, 0, sizeof(dscene.data));
+ bvh = NULL;
camera = create_node<Camera>();
dicing_camera = create_node<Camera>();
lookup_tables = new LookupTables();
@@ -135,6 +137,9 @@ Scene::~Scene()
void Scene::free_memory(bool final)
{
+ delete bvh;
+ bvh = NULL;
+
foreach (Shader *s, shaders)
delete s;
foreach (Geometry *g, geometry)
diff --git a/intern/cycles/render/scene.h b/intern/cycles/render/scene.h
index 6686327dc49..27e9a131bbd 100644
--- a/intern/cycles/render/scene.h
+++ b/intern/cycles/render/scene.h
@@ -38,6 +38,7 @@ CCL_NAMESPACE_BEGIN
class AttributeRequestSet;
class Background;
+class BVH;
class Camera;
class Device;
class DeviceInfo;
@@ -220,6 +221,7 @@ class Scene : public NodeOwner {
string name;
/* data */
+ BVH *bvh;
Camera *camera;
Camera *dicing_camera;
LookupTables *lookup_tables;
diff --git a/intern/cycles/render/shader.cpp b/intern/cycles/render/shader.cpp
index cf49dedc426..7e06b427e4d 100644
--- a/intern/cycles/render/shader.cpp
+++ b/intern/cycles/render/shader.cpp
@@ -347,8 +347,15 @@ void Shader::tag_update(Scene *scene)
foreach (ShaderNode *node, graph->nodes)
node->attributes(this, &attributes);
- if (has_displacement && displacement_method == DISPLACE_BOTH) {
- attributes.add(ATTR_STD_POSITION_UNDISPLACED);
+ if (has_displacement) {
+ if (displacement_method == DISPLACE_BOTH) {
+ attributes.add(ATTR_STD_POSITION_UNDISPLACED);
+ }
+ if (displacement_method_is_modified()) {
+ need_update_geometry = true;
+ scene->geometry_manager->need_update = true;
+ scene->object_manager->need_flags_update = true;
+ }
}
/* compare if the attributes changed, mesh manager will check