From a76198cb238bef5c08e83b7777c977daa7316c1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Tue, 24 Jul 2018 17:59:46 +0200 Subject: RNA: Remove Unused dof.is_hq_supported and dof.use_high_quality It's not necessary anymore since we assume it's always high quality. --- intern/cycles/blender/addon/ui.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'intern/cycles') diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 3d5ed6b9b44..a1941ce6176 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -883,14 +883,9 @@ class CYCLES_CAMERA_PT_dof_viewport(CyclesButtonsPanel, Panel): cam = context.camera dof_options = cam.gpu_dof - hq_support = dof_options.is_hq_supported sub = flow.column(align=True) - subhq = sub.column() - subhq.active = hq_support - subhq.prop(dof_options, "use_high_quality") sub.prop(dof_options, "fstop") - if dof_options.use_high_quality and hq_support: - sub.prop(dof_options, "blades") + sub.prop(dof_options, "blades") class CYCLES_PT_context_material(CyclesButtonsPanel, Panel): -- cgit v1.2.3 From 41130ecf16b661391915e0ace14ee941045b4a52 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 25 Jul 2018 12:35:27 +0200 Subject: Cleanup: mark missing Cycles view layer override features with TODO. --- intern/cycles/blender/blender_mesh.cpp | 15 +++------------ intern/cycles/blender/blender_object.cpp | 24 ++++++++++++++---------- intern/cycles/blender/blender_session.cpp | 10 ++++------ intern/cycles/blender/blender_sync.cpp | 17 ----------------- intern/cycles/blender/blender_sync.h | 15 ++------------- 5 files changed, 23 insertions(+), 58 deletions(-) (limited to 'intern/cycles') diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp index 08206dd5521..8a6480a9a42 100644 --- a/intern/cycles/blender/blender_mesh.cpp +++ b/intern/cycles/blender/blender_mesh.cpp @@ -1080,27 +1080,18 @@ Mesh *BlenderSync::sync_mesh(BL::Depsgraph& b_depsgraph, /* test if we can instance or if the object is modified */ BL::ID b_ob_data = b_ob.data(); BL::ID key = (BKE_object_is_modified(b_ob))? b_ob_instance: b_ob_data; - BL::Material material_override = view_layer.material_override; /* find shader indices */ vector used_shaders; BL::Object::material_slots_iterator slot; for(b_ob.material_slots.begin(slot); slot != b_ob.material_slots.end(); ++slot) { - if(material_override) { - find_shader(material_override, used_shaders, scene->default_surface); - } - else { - BL::ID b_material(slot->material()); - find_shader(b_material, used_shaders, scene->default_surface); - } + BL::ID b_material(slot->material()); + find_shader(b_material, used_shaders, scene->default_surface); } if(used_shaders.size() == 0) { - if(material_override) - find_shader(material_override, used_shaders, scene->default_surface); - else - used_shaders.push_back(scene->default_surface); + used_shaders.push_back(scene->default_surface); } /* test if we need to sync */ diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index ed01d728931..56365d12bab 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -292,7 +292,6 @@ void BlenderSync::sync_background_light(bool use_portal) Object *BlenderSync::sync_object(BL::Depsgraph& b_depsgraph, BL::DepsgraphObjectInstance& b_instance, - uint layer_flag, float motion_time, bool hide_tris, BlenderObjectCulling& culling, @@ -314,10 +313,13 @@ Object *BlenderSync::sync_object(BL::Depsgraph& b_depsgraph, } /* light is handled separately */ - if(object_is_light(b_ob)) { - /* don't use lights for excluded layers used as mask layer */ - if(!motion && !((layer_flag & view_layer.holdout_layer) && - (layer_flag & view_layer.exclude_layer))) + if(!motion && object_is_light(b_ob)) { + /* TODO: don't use lights for excluded layers used as mask layer, + * when dynamic overrides are back. */ +#if 0 + if(!((layer_flag & view_layer.holdout_layer) && + (layer_flag & view_layer.exclude_layer))) +#endif { sync_light(b_parent, persistent_id, @@ -343,23 +345,26 @@ Object *BlenderSync::sync_object(BL::Depsgraph& b_depsgraph, /* Visibility flags for both parent and child. */ PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles"); - bool use_holdout = (layer_flag & view_layer.holdout_layer) != 0 || - get_boolean(cobject, "is_holdout"); + bool use_holdout = get_boolean(cobject, "is_holdout"); uint visibility = object_ray_visibility(b_ob) & PATH_RAY_ALL_VISIBILITY; if(b_parent.ptr.data != b_ob.ptr.data) { visibility &= object_ray_visibility(b_parent); } - /* Make holdout objects on excluded layer invisible for non-camera rays. */ + /* TODO: make holdout objects on excluded layer invisible for non-camera rays. */ +#if 0 if(use_holdout && (layer_flag & view_layer.exclude_layer)) { visibility &= ~(PATH_RAY_ALL_VISIBILITY - PATH_RAY_CAMERA); } +#endif - /* Hide objects not on render layer from camera rays. */ + /* TODO: hide objects not on render layer from camera rays. */ +#if 0 if(!(layer_flag & view_layer.layer)) { visibility &= ~PATH_RAY_CAMERA; } +#endif /* Don't export completely invisible objects. */ if(visibility == 0) { @@ -605,7 +610,6 @@ void BlenderSync::sync_objects(BL::Depsgraph& b_depsgraph, float motion_time) /* object itself */ sync_object(b_depsgraph, b_instance, - ~(0), /* until we get rid of layers */ motion_time, hide_tris, culling, diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp index cd55155e33b..1a4b26128e3 100644 --- a/intern/cycles/blender/blender_session.cpp +++ b/intern/cycles/blender/blender_session.cpp @@ -461,15 +461,13 @@ void BlenderSession::render(BL::Depsgraph& b_depsgraph_) scene->integrator->tag_update(scene); } - /* Update number of samples per layer. */ - int samples = sync->get_layer_samples(); - bool bound_samples = sync->get_layer_bound_samples(); - int effective_layer_samples; + int effective_layer_samples = session_params.samples; + /* TODO: Update number of samples per layer. */ +#if 0 if(samples != 0 && (!bound_samples || (samples < session_params.samples))) effective_layer_samples = samples; - else - effective_layer_samples = session_params.samples; +#endif /* Update tile manager if we're doing resumable render. */ update_resumable_tile_manager(effective_layer_samples); diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index 3204e0cd3f2..93232fbf98f 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -365,28 +365,11 @@ void BlenderSync::sync_film() void BlenderSync::sync_view_layer(BL::SpaceView3D& /*b_v3d*/, BL::ViewLayer& b_view_layer) { /* render layer */ - uint layer_override = get_layer(b_engine.layer_override()); - uint view_layers = layer_override ? layer_override : get_layer(b_scene.layers()); - view_layer.name = b_view_layer.name(); - - view_layer.holdout_layer = 0; - view_layer.exclude_layer = 0; - - view_layer.view_layer = view_layers & ~view_layer.exclude_layer; - view_layer.view_layer |= view_layer.exclude_layer & view_layer.holdout_layer; - - view_layer.layer = (1 << 20) - 1; - view_layer.layer |= view_layer.holdout_layer; - - view_layer.material_override = PointerRNA_NULL; view_layer.use_background_shader = b_view_layer.use_sky(); view_layer.use_background_ao = b_view_layer.use_ao(); view_layer.use_surfaces = b_view_layer.use_solid(); view_layer.use_hair = b_view_layer.use_strand(); - - view_layer.bound_samples = false; - view_layer.samples = 0; } /* Images */ diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h index 0465f703c51..ba3f5e6428f 100644 --- a/intern/cycles/blender/blender_sync.h +++ b/intern/cycles/blender/blender_sync.h @@ -127,7 +127,6 @@ private: int motion_step = 0); Object *sync_object(BL::Depsgraph& b_depsgraph, BL::DepsgraphObjectInstance& b_instance, - uint layer_flag, float motion_time, bool hide_tris, BlenderObjectCulling& culling, @@ -191,28 +190,18 @@ private: struct RenderLayerInfo { RenderLayerInfo() - : view_layer(0), layer(0), - holdout_layer(0), exclude_layer(0), - material_override(PointerRNA_NULL), - use_background_shader(true), + : use_background_shader(true), use_background_ao(true), use_surfaces(true), - use_hair(true), - samples(0), bound_samples(false) + use_hair(true) {} string name; uint view_layer; - uint layer; /* This can be safely removed from Cycles. */ - uint holdout_layer; /* This can be safely removed from Cycles. */ - uint exclude_layer; /* This can be safely removed from Cycles. */ - BL::Material material_override; /* This can be safely removed from Cycles. */ bool use_background_shader; bool use_background_ao; bool use_surfaces; bool use_hair; - int samples; /* This can be safely removed from Cycles. */ - bool bound_samples; /* This can be safely removed from Cycles. */ } view_layer; Progress &progress; -- cgit v1.2.3 From b0077992d2759b29b536187a226e8382b72261b6 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 25 Jul 2018 12:26:09 +0200 Subject: Cycles: add per layer collection mask/holdout support. In the outliner, right click > view layer > set holdout. This is temporary until we have more general dynamic overrides, but helps Spring production for now. --- intern/cycles/blender/blender_object.cpp | 6 +++++- intern/cycles/blender/blender_sync.h | 3 +-- 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'intern/cycles') diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index 56365d12bab..fd8790c0c79 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -291,6 +291,7 @@ void BlenderSync::sync_background_light(bool use_portal) /* Object */ Object *BlenderSync::sync_object(BL::Depsgraph& b_depsgraph, + BL::ViewLayer& b_view_layer, BL::DepsgraphObjectInstance& b_instance, float motion_time, bool hide_tris, @@ -345,7 +346,8 @@ Object *BlenderSync::sync_object(BL::Depsgraph& b_depsgraph, /* Visibility flags for both parent and child. */ PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles"); - bool use_holdout = get_boolean(cobject, "is_holdout"); + bool use_holdout = get_boolean(cobject, "is_holdout") || + b_ob.holdout_get(b_view_layer); uint visibility = object_ray_visibility(b_ob) & PATH_RAY_ALL_VISIBILITY; if(b_parent.ptr.data != b_ob.ptr.data) { @@ -588,6 +590,7 @@ void BlenderSync::sync_objects(BL::Depsgraph& b_depsgraph, float motion_time) bool cancel = false; bool use_portal = false; + BL::ViewLayer b_view_layer = b_depsgraph.view_layer_eval(); BL::Depsgraph::mode_enum depsgraph_mode = b_depsgraph.mode(); BL::Depsgraph::object_instances_iterator b_instance_iter; @@ -609,6 +612,7 @@ void BlenderSync::sync_objects(BL::Depsgraph& b_depsgraph, float motion_time) if(!object_render_hide(b_ob, true, true, hide_tris, depsgraph_mode)) { /* object itself */ sync_object(b_depsgraph, + b_view_layer, b_instance, motion_time, hide_tris, diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h index ba3f5e6428f..e63ef9e5e47 100644 --- a/intern/cycles/blender/blender_sync.h +++ b/intern/cycles/blender/blender_sync.h @@ -78,8 +78,6 @@ public: void sync_view(BL::SpaceView3D& b_v3d, BL::RegionView3D& b_rv3d, int width, int height); - inline int get_layer_samples() { return view_layer.samples; } - inline int get_layer_bound_samples() { return view_layer.bound_samples; } /* get parameters */ static SceneParams get_scene_params(BL::Scene& b_scene, @@ -126,6 +124,7 @@ private: bool motion, int motion_step = 0); Object *sync_object(BL::Depsgraph& b_depsgraph, + BL::ViewLayer& b_view_layer, BL::DepsgraphObjectInstance& b_instance, float motion_time, bool hide_tris, -- cgit v1.2.3 From 885cda65c90b3f85dc4e72e2e9759aa926a8f07c Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 25 Jul 2018 12:26:09 +0200 Subject: Cycles: add per layer collection indirectly on setting. In the outliner, right click > view layer > set indirect only. This is like clearing camera ray visibility on objects in the collection, and is temporary until we have more general dynamic overrides. --- intern/cycles/blender/blender_object.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'intern/cycles') diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index fd8790c0c79..42e2198779e 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -361,12 +361,11 @@ Object *BlenderSync::sync_object(BL::Depsgraph& b_depsgraph, } #endif - /* TODO: hide objects not on render layer from camera rays. */ -#if 0 - if(!(layer_flag & view_layer.layer)) { + /* Clear camera visibility for indirect only objects. */ + bool use_indirect_only = b_ob.indirect_only_get(b_view_layer); + if(use_indirect_only) { visibility &= ~PATH_RAY_CAMERA; } -#endif /* Don't export completely invisible objects. */ if(visibility == 0) { -- cgit v1.2.3 From 9a40690242dff4153a48c1da0f0f87a71a020e64 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 25 Jul 2018 18:30:26 +0200 Subject: Fix for holdout / indirect only with collection instances. --- intern/cycles/blender/blender_object.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'intern/cycles') diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index 42e2198779e..a1f39d0848f 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -347,7 +347,7 @@ Object *BlenderSync::sync_object(BL::Depsgraph& b_depsgraph, /* Visibility flags for both parent and child. */ PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles"); bool use_holdout = get_boolean(cobject, "is_holdout") || - b_ob.holdout_get(b_view_layer); + b_parent.holdout_get(b_view_layer); uint visibility = object_ray_visibility(b_ob) & PATH_RAY_ALL_VISIBILITY; if(b_parent.ptr.data != b_ob.ptr.data) { @@ -362,7 +362,7 @@ Object *BlenderSync::sync_object(BL::Depsgraph& b_depsgraph, #endif /* Clear camera visibility for indirect only objects. */ - bool use_indirect_only = b_ob.indirect_only_get(b_view_layer); + bool use_indirect_only = b_parent.indirect_only_get(b_view_layer); if(use_indirect_only) { visibility &= ~PATH_RAY_CAMERA; } -- cgit v1.2.3 From 8c9e6c59863077512e7abfa4fdedbbedfd954a87 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 25 Jul 2018 19:15:20 +0200 Subject: Fix crash Cycles rendering with --debug-value 256. --- intern/cycles/blender/addon/engine.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'intern/cycles') diff --git a/intern/cycles/blender/addon/engine.py b/intern/cycles/blender/addon/engine.py index 5c52a8bcce9..60057818e37 100644 --- a/intern/cycles/blender/addon/engine.py +++ b/intern/cycles/blender/addon/engine.py @@ -168,7 +168,7 @@ def reset(engine, data, depsgraph): import bpy if bpy.app.debug_value == 256: - _cycles.debug_flags_update(depsgraph.scene) + _cycles.debug_flags_update(depsgraph.scene.as_pointer()) else: _cycles.debug_flags_reset() -- cgit v1.2.3 From d6e769d32e7939e3bbd1986cdc4abd2b13135eab Mon Sep 17 00:00:00 2001 From: Lukas Stockner Date: Thu, 26 Jul 2018 16:48:15 +0200 Subject: Cycles: Add reflection fix to Bump and Normal Map nodes While changing the shading normal is a great way to add additional detail to a model, there are some problems with it. One of them is that at grazing angles and/or strong changes to the normal, the reflected ray can end up pointing into the actual geometry, which results in a black spot. This patch helps avoid this by automatically reducing the strength of the bump/normal map if the reflected direction would end up too shallow or inside the geometry. Differential Revision: https://developer.blender.org/D2574 --- intern/cycles/kernel/kernel_montecarlo.h | 29 +++++++++++++++++++++++ intern/cycles/kernel/shaders/node_bump.osl | 2 ++ intern/cycles/kernel/shaders/node_normal_map.osl | 2 ++ intern/cycles/kernel/shaders/stdosl.h | 30 ++++++++++++++++++++++++ intern/cycles/kernel/svm/svm_displace.h | 2 ++ intern/cycles/kernel/svm/svm_tex_coord.h | 2 ++ 6 files changed, 67 insertions(+) (limited to 'intern/cycles') diff --git a/intern/cycles/kernel/kernel_montecarlo.h b/intern/cycles/kernel/kernel_montecarlo.h index 49dc1f08cc1..09a3fe8f23d 100644 --- a/intern/cycles/kernel/kernel_montecarlo.h +++ b/intern/cycles/kernel/kernel_montecarlo.h @@ -184,6 +184,35 @@ ccl_device float2 regular_polygon_sample(float corners, float rotation, float u, return make_float2(cr*p.x - sr*p.y, sr*p.x + cr*p.y); } +ccl_device float3 ensure_valid_reflection(float3 Ng, float3 I, float3 N) +{ + float3 R = 2*dot(N, I)*N - I; + if(dot(Ng, R) >= 0.05f) { + return N; + } + + /* Form coordinate system with Ng as the Z axis and N inside the X-Z-plane. + * The X axis is found by normalizing the component of N that's orthogonal to Ng. + * The Y axis isn't actually needed. + */ + float3 X = normalize(N - dot(N, Ng)*Ng); + + /* Calculate N.z and N.x in the local coordinate system. */ + float Iz = dot(I, Ng); + float Ix2 = sqr(dot(I, X)), Iz2 = sqr(Iz); + float Ix2Iz2 = Ix2 + Iz2; + + float a = sqrtf(Ix2*(Ix2Iz2 - sqr(0.05f))); + float b = Iz*0.05f + Ix2Iz2; + float c = (a + b > 0.0f)? (a + b) : (-a + b); + + float Nz = sqrtf(0.5f * c * (1.0f / Ix2Iz2)); + float Nx = sqrtf(1.0f - sqr(Nz)); + + /* Transform back into global coordinates. */ + return Nx*X + Nz*Ng; +} + CCL_NAMESPACE_END #endif /* __KERNEL_MONTECARLO_CL__ */ diff --git a/intern/cycles/kernel/shaders/node_bump.osl b/intern/cycles/kernel/shaders/node_bump.osl index 7f01cf2ca91..a2a4468d5f3 100644 --- a/intern/cycles/kernel/shaders/node_bump.osl +++ b/intern/cycles/kernel/shaders/node_bump.osl @@ -64,5 +64,7 @@ surface node_bump( if (use_object_space) { NormalOut = normalize(transform("object", "world", NormalOut)); } + + NormalOut = ensure_valid_reflection(Ng, I, NormalOut); } diff --git a/intern/cycles/kernel/shaders/node_normal_map.osl b/intern/cycles/kernel/shaders/node_normal_map.osl index 41bcac4fb10..fda6f12a5da 100644 --- a/intern/cycles/kernel/shaders/node_normal_map.osl +++ b/intern/cycles/kernel/shaders/node_normal_map.osl @@ -88,5 +88,7 @@ shader node_normal_map( if (Strength != 1.0) Normal = normalize(NormalIn + (Normal - NormalIn) * max(Strength, 0.0)); + + Normal = ensure_valid_reflection(Ng, I, Normal); } diff --git a/intern/cycles/kernel/shaders/stdosl.h b/intern/cycles/kernel/shaders/stdosl.h index df9c2010872..4a8378796ba 100644 --- a/intern/cycles/kernel/shaders/stdosl.h +++ b/intern/cycles/kernel/shaders/stdosl.h @@ -282,6 +282,36 @@ point rotate (point p, float angle, point a, point b) return transform (M, p-a) + a; } +normal ensure_valid_reflection(normal Ng, vector I, normal N) +{ + float sqr(float x) { return x*x; } + + vector R = 2*dot(N, I)*N - I; + if (dot(Ng, R) >= 0.05) { + return N; + } + + /* Form coordinate system with Ng as the Z axis and N inside the X-Z-plane. + * The X axis is found by normalizing the component of N that's orthogonal to Ng. + * The Y axis isn't actually needed. + */ + vector X = normalize(N - dot(N, Ng)*Ng); + + /* Calculate N.z and N.x in the local coordinate system. */ + float Ix = dot(I, X), Iz = dot(I, Ng); + float Ix2 = sqr(dot(I, X)), Iz2 = sqr(dot(I, Ng)); + float Ix2Iz2 = Ix2 + Iz2; + + float a = sqrt(Ix2*(Ix2Iz2 - sqr(0.05))); + float b = Iz*0.05 + Ix2Iz2; + float c = (a + b > 0.0)? (a + b) : (-a + b); + + float Nz = sqrt(0.5 * c * (1.0 / Ix2Iz2)); + float Nx = sqrt(1.0 - sqr(Nz)); + + /* Transform back into global coordinates. */ + return Nx*X + Nz*Ng; +} // Color functions diff --git a/intern/cycles/kernel/svm/svm_displace.h b/intern/cycles/kernel/svm/svm_displace.h index b85eb9c0458..0f5b3abef87 100644 --- a/intern/cycles/kernel/svm/svm_displace.h +++ b/intern/cycles/kernel/svm/svm_displace.h @@ -75,6 +75,8 @@ ccl_device void svm_node_set_bump(KernelGlobals *kg, ShaderData *sd, float *stac object_normal_transform(kg, sd, &normal_out); } + normal_out = ensure_valid_reflection(sd->Ng, sd->I, normal_out); + stack_store_float3(stack, node.w, normal_out); #endif } diff --git a/intern/cycles/kernel/svm/svm_tex_coord.h b/intern/cycles/kernel/svm/svm_tex_coord.h index 7c207083929..45c38d64763 100644 --- a/intern/cycles/kernel/svm/svm_tex_coord.h +++ b/intern/cycles/kernel/svm/svm_tex_coord.h @@ -345,6 +345,8 @@ ccl_device void svm_node_normal_map(KernelGlobals *kg, ShaderData *sd, float *st N = safe_normalize(sd->N + (N - sd->N)*strength); } + N = ensure_valid_reflection(sd->Ng, sd->I, N); + if(is_zero(N)) { N = sd->N; } -- cgit v1.2.3 From e977fe985f019b7b28c022ffb0ca8fb37f6418ee Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 27 Jul 2018 10:16:30 +0200 Subject: Cycles: Cleanup in image manager, switch statement instead of if-else Allows to catch enumerator values which are missing from being handled. Also use `const char*`, no need to construct string just to throw it away. --- intern/cycles/render/image.cpp | 36 ++++++++++++++++++------------------ intern/cycles/render/image.h | 2 +- 2 files changed, 19 insertions(+), 19 deletions(-) (limited to 'intern/cycles') diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp index 27d6ae78289..854eddac716 100644 --- a/intern/cycles/render/image.cpp +++ b/intern/cycles/render/image.cpp @@ -253,24 +253,23 @@ int ImageManager::flattened_slot_to_type_index(int flat_slot, ImageDataType *typ return flat_slot >> IMAGE_DATA_TYPE_SHIFT; } -string ImageManager::name_from_type(int type) +const char* ImageManager::name_from_type(ImageDataType type) { - if(type == IMAGE_DATA_TYPE_FLOAT4) - return "float4"; - else if(type == IMAGE_DATA_TYPE_FLOAT) - return "float"; - else if(type == IMAGE_DATA_TYPE_BYTE) - return "byte"; - else if(type == IMAGE_DATA_TYPE_HALF4) - return "half4"; - else if(type == IMAGE_DATA_TYPE_HALF) - return "half"; - else if(type == IMAGE_DATA_TYPE_USHORT) - return "ushort"; - else if(type == IMAGE_DATA_TYPE_USHORT4) - return "ushort4"; - else - return "byte4"; + switch(type) { + case IMAGE_DATA_TYPE_FLOAT4: return "float4"; + case IMAGE_DATA_TYPE_BYTE4: return "byte4"; + case IMAGE_DATA_TYPE_HALF4: return "half4"; + case IMAGE_DATA_TYPE_FLOAT: return "float"; + case IMAGE_DATA_TYPE_BYTE: return "byte"; + case IMAGE_DATA_TYPE_HALF: return "half"; + case IMAGE_DATA_TYPE_USHORT4: return "ushort4"; + case IMAGE_DATA_TYPE_USHORT: return "ushort"; + case IMAGE_DATA_NUM_TYPES: + assert(!"System enumerator type, should never be used"); + return ""; + } + assert(!"Unhandled image data type"); + return ""; } static bool image_equals(ImageManager::Image *image, @@ -732,7 +731,8 @@ void ImageManager::device_load_image(Device *device, /* Slot assignment */ int flat_slot = type_index_to_flattened_slot(slot, type); - img->mem_name = string_printf("__tex_image_%s_%03d", name_from_type(type).c_str(), flat_slot); + img->mem_name = string_printf("__tex_image_%s_%03d", + name_from_type(type), flat_slot); /* Free previous texture in slot. */ if(img->mem) { diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h index 5932c24cb74..627ad3ce6aa 100644 --- a/intern/cycles/render/image.h +++ b/intern/cycles/render/image.h @@ -152,7 +152,7 @@ private: int max_flattened_slot(ImageDataType type); int type_index_to_flattened_slot(int slot, ImageDataType type); int flattened_slot_to_type_index(int flat_slot, ImageDataType *type); - string name_from_type(int type); + const char* name_from_type(ImageDataType type); void device_load_image(Device *device, Scene *scene, -- cgit v1.2.3 From de80b928a33bb753bec360e0d4cfeafd0bf23b0c Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 27 Jul 2018 10:22:45 +0200 Subject: Cycles: Cleanup, remove unused function --- intern/cycles/render/image.cpp | 9 --------- intern/cycles/render/image.h | 1 - 2 files changed, 10 deletions(-) (limited to 'intern/cycles') diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp index 854eddac716..b8892a5329d 100644 --- a/intern/cycles/render/image.cpp +++ b/intern/cycles/render/image.cpp @@ -229,15 +229,6 @@ bool ImageManager::get_image_metadata(const string& filename, return true; } -int ImageManager::max_flattened_slot(ImageDataType type) -{ - if(tex_num_images[type] == 0) { - /* No textures for the type, no slots needs allocation. */ - return 0; - } - return type_index_to_flattened_slot(tex_num_images[type], type); -} - /* The lower three bits of a device texture slot number indicate its type. * These functions convert the slot ids from ImageManager "images" ones * to device ones and vice verse. diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h index 627ad3ce6aa..40b8629d549 100644 --- a/intern/cycles/render/image.h +++ b/intern/cycles/render/image.h @@ -149,7 +149,6 @@ private: int texture_limit, device_vector& tex_img); - int max_flattened_slot(ImageDataType type); int type_index_to_flattened_slot(int slot, ImageDataType type); int flattened_slot_to_type_index(int flat_slot, ImageDataType *type); const char* name_from_type(ImageDataType type); -- cgit v1.2.3 From ca359461a803808a832ff603e2d01468a252c90f Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 27 Jul 2018 10:24:03 +0200 Subject: Cycles: Cleanup, move functions outside of class methods There is no reason or justification to have helper functions as class methods: they do not depend on anything in the class itself. There are probably more cases like that. --- intern/cycles/render/image.cpp | 78 ++++++++++++++++++++++-------------------- intern/cycles/render/image.h | 4 --- 2 files changed, 41 insertions(+), 41 deletions(-) (limited to 'intern/cycles') diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp index b8892a5329d..78451658764 100644 --- a/intern/cycles/render/image.cpp +++ b/intern/cycles/render/image.cpp @@ -30,20 +30,58 @@ CCL_NAMESPACE_BEGIN +namespace { + /* Some helpers to silence warning in templated function. */ -static bool isfinite(uchar /*value*/) +bool isfinite(uchar /*value*/) { return true; } -static bool isfinite(half /*value*/) +bool isfinite(half /*value*/) { return true; } -static bool isfinite(uint16_t /*value*/) +bool isfinite(uint16_t /*value*/) { return true; } +/* The lower three bits of a device texture slot number indicate its type. + * These functions convert the slot ids from ImageManager "images" ones + * to device ones and vice verse. + */ +int type_index_to_flattened_slot(int slot, ImageDataType type) +{ + return (slot << IMAGE_DATA_TYPE_SHIFT) | (type); +} + +int flattened_slot_to_type_index(int flat_slot, ImageDataType *type) +{ + *type = (ImageDataType)(flat_slot & IMAGE_DATA_TYPE_MASK); + return flat_slot >> IMAGE_DATA_TYPE_SHIFT; +} + +const char* name_from_type(ImageDataType type) +{ + switch(type) { + case IMAGE_DATA_TYPE_FLOAT4: return "float4"; + case IMAGE_DATA_TYPE_BYTE4: return "byte4"; + case IMAGE_DATA_TYPE_HALF4: return "half4"; + case IMAGE_DATA_TYPE_FLOAT: return "float"; + case IMAGE_DATA_TYPE_BYTE: return "byte"; + case IMAGE_DATA_TYPE_HALF: return "half"; + case IMAGE_DATA_TYPE_USHORT4: return "ushort4"; + case IMAGE_DATA_TYPE_USHORT: return "ushort"; + case IMAGE_DATA_NUM_TYPES: + assert(!"System enumerator type, should never be used"); + return ""; + } + assert(!"Unhandled image data type"); + return ""; +} + +} // namespace + ImageManager::ImageManager(const DeviceInfo& info) { need_update = true; @@ -229,40 +267,6 @@ bool ImageManager::get_image_metadata(const string& filename, return true; } -/* The lower three bits of a device texture slot number indicate its type. - * These functions convert the slot ids from ImageManager "images" ones - * to device ones and vice verse. - */ -int ImageManager::type_index_to_flattened_slot(int slot, ImageDataType type) -{ - return (slot << IMAGE_DATA_TYPE_SHIFT) | (type); -} - -int ImageManager::flattened_slot_to_type_index(int flat_slot, ImageDataType *type) -{ - *type = (ImageDataType)(flat_slot & IMAGE_DATA_TYPE_MASK); - return flat_slot >> IMAGE_DATA_TYPE_SHIFT; -} - -const char* ImageManager::name_from_type(ImageDataType type) -{ - switch(type) { - case IMAGE_DATA_TYPE_FLOAT4: return "float4"; - case IMAGE_DATA_TYPE_BYTE4: return "byte4"; - case IMAGE_DATA_TYPE_HALF4: return "half4"; - case IMAGE_DATA_TYPE_FLOAT: return "float"; - case IMAGE_DATA_TYPE_BYTE: return "byte"; - case IMAGE_DATA_TYPE_HALF: return "half"; - case IMAGE_DATA_TYPE_USHORT4: return "ushort4"; - case IMAGE_DATA_TYPE_USHORT: return "ushort"; - case IMAGE_DATA_NUM_TYPES: - assert(!"System enumerator type, should never be used"); - return ""; - } - assert(!"Unhandled image data type"); - return ""; -} - static bool image_equals(ImageManager::Image *image, const string& filename, void *builtin_data, diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h index 40b8629d549..67af4ba886c 100644 --- a/intern/cycles/render/image.h +++ b/intern/cycles/render/image.h @@ -149,10 +149,6 @@ private: int texture_limit, device_vector& tex_img); - int type_index_to_flattened_slot(int slot, ImageDataType type); - int flattened_slot_to_type_index(int flat_slot, ImageDataType *type); - const char* name_from_type(ImageDataType type); - void device_load_image(Device *device, Scene *scene, ImageDataType type, -- cgit v1.2.3 From 46b85d195cd539d61673a6cf1ffa3704788912ce Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 27 Jul 2018 10:28:06 +0200 Subject: Cycles: Cleanup, line length --- intern/cycles/render/image.cpp | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) (limited to 'intern/cycles') diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp index 78451658764..7f090b7a752 100644 --- a/intern/cycles/render/image.cpp +++ b/intern/cycles/render/image.cpp @@ -171,10 +171,12 @@ bool ImageManager::get_image_metadata(const string& filename, if(metadata.is_float) { metadata.is_linear = true; - metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_FLOAT4 : IMAGE_DATA_TYPE_FLOAT; + metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_FLOAT4 + : IMAGE_DATA_TYPE_FLOAT; } else { - metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_BYTE4 : IMAGE_DATA_TYPE_BYTE; + metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_BYTE4 + : IMAGE_DATA_TYPE_BYTE; } return true; @@ -186,7 +188,8 @@ bool ImageManager::get_image_metadata(const string& filename, return false; } if(path_is_directory(filename)) { - VLOG(1) << "File '" << filename << "' is a directory, can't use as image."; + VLOG(1) << "File '" << filename + << "' is a directory, can't use as image."; return false; } @@ -249,16 +252,20 @@ bool ImageManager::get_image_metadata(const string& filename, metadata.channels = spec.nchannels; if(metadata.is_half) { - metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_HALF4 : IMAGE_DATA_TYPE_HALF; + metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_HALF4 + : IMAGE_DATA_TYPE_HALF; } else if(metadata.is_float) { - metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_FLOAT4 : IMAGE_DATA_TYPE_FLOAT; + metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_FLOAT4 + : IMAGE_DATA_TYPE_FLOAT; } else if(spec.format == TypeDesc::USHORT) { - metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_USHORT4 : IMAGE_DATA_TYPE_USHORT; + metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_USHORT4 + : IMAGE_DATA_TYPE_USHORT; } else { - metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_BYTE4 : IMAGE_DATA_TYPE_BYTE; + metadata.type = (metadata.channels > 1) ? IMAGE_DATA_TYPE_BYTE4 + : IMAGE_DATA_TYPE_BYTE; } in->close(); @@ -338,14 +345,16 @@ int ImageManager::add_image(const string& filename, } /* Count if we're over the limit. - * Very unlikely, since max_num_images is insanely big. But better safe than sorry. */ + * Very unlikely, since max_num_images is insanely big. But better safe + * than sorry. + */ int tex_count = 0; for(int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) { tex_count += tex_num_images[type]; } if(tex_count > max_num_images) { - printf("ImageManager::add_image: Reached image limit (%d), skipping '%s'\n", - max_num_images, filename.c_str()); + printf("ImageManager::add_image: Reached image limit (%d), " + "skipping '%s'\n", max_num_images, filename.c_str()); return -1; } -- cgit v1.2.3 From fcea94489cb181504435868472a74d4887bba947 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 27 Jul 2018 10:28:28 +0200 Subject: Cycles: Cleanup, indentation --- intern/cycles/render/image.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'intern/cycles') diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp index 7f090b7a752..741dfb0717a 100644 --- a/intern/cycles/render/image.cpp +++ b/intern/cycles/render/image.cpp @@ -128,12 +128,12 @@ bool ImageManager::set_animation_frame_update(int frame) device_memory *ImageManager::image_memory(int flat_slot) { - ImageDataType type; - int slot = flattened_slot_to_type_index(flat_slot, &type); + ImageDataType type; + int slot = flattened_slot_to_type_index(flat_slot, &type); - Image *img = images[type][slot]; + Image *img = images[type][slot]; - return img->mem; + return img->mem; } bool ImageManager::get_image_metadata(int flat_slot, -- cgit v1.2.3 From b517b310853cc752ca1bb92b4219b257f5a94e30 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 27 Jul 2018 10:30:10 +0200 Subject: Cycles: Cleanup, spelling --- intern/cycles/render/image.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'intern/cycles') diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h index 67af4ba886c..9a2b373d016 100644 --- a/intern/cycles/render/image.h +++ b/intern/cycles/render/image.h @@ -153,7 +153,7 @@ private: Scene *scene, ImageDataType type, int slot, - Progress *progess); + Progress *progress); void device_free_image(Device *device, ImageDataType type, int slot); -- cgit v1.2.3 From 75c47542d787c91293572b007bbf6787f903522a Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 27 Jul 2018 11:09:10 +0200 Subject: Cycles: Cleanup, indentation --- intern/cycles/render/mesh.cpp | 14 +++++++------- intern/cycles/render/mesh.h | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'intern/cycles') diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp index 7a9d604244d..df408b478b2 100644 --- a/intern/cycles/render/mesh.cpp +++ b/intern/cycles/render/mesh.cpp @@ -2015,8 +2015,8 @@ void MeshManager::device_update_displacement_images(Device *device, } void MeshManager::device_update_volume_images(Device *device, - Scene *scene, - Progress& progress) + Scene *scene, + Progress& progress) { progress.set_status("Updating Volume Images"); TaskPool pool; @@ -2043,11 +2043,11 @@ void MeshManager::device_update_volume_images(Device *device, foreach(int slot, volume_images) { pool.push(function_bind(&ImageManager::device_update_slot, - image_manager, - device, - scene, - slot, - &progress)); + image_manager, + device, + scene, + slot, + &progress)); } pool.wait_work(); } diff --git a/intern/cycles/render/mesh.h b/intern/cycles/render/mesh.h index e7dc1c8e5cf..fc7d0b40273 100644 --- a/intern/cycles/render/mesh.h +++ b/intern/cycles/render/mesh.h @@ -381,8 +381,8 @@ protected: Progress& progress); void device_update_volume_images(Device *device, - Scene *scene, - Progress& progress); + Scene *scene, + Progress& progress); }; CCL_NAMESPACE_END -- cgit v1.2.3 From 67e690f5fcc084fbd949240f2c7733854079efc5 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 27 Jul 2018 11:19:29 +0200 Subject: Cycles: Cleanup, indentation --- intern/cycles/graph/node_type.cpp | 2 +- intern/cycles/graph/node_type.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'intern/cycles') diff --git a/intern/cycles/graph/node_type.cpp b/intern/cycles/graph/node_type.cpp index 671ae2d815a..e045777e969 100644 --- a/intern/cycles/graph/node_type.cpp +++ b/intern/cycles/graph/node_type.cpp @@ -134,7 +134,7 @@ NodeType::~NodeType() void NodeType::register_input(ustring name, ustring ui_name, SocketType::Type type, int struct_offset, const void *default_value, const NodeEnum *enum_values, - const NodeType **node_type, int flags, int extra_flags) + const NodeType **node_type, int flags, int extra_flags) { SocketType socket; socket.name = name; diff --git a/intern/cycles/graph/node_type.h b/intern/cycles/graph/node_type.h index d4e2dbceff6..1d565794b27 100644 --- a/intern/cycles/graph/node_type.h +++ b/intern/cycles/graph/node_type.h @@ -114,9 +114,9 @@ struct NodeType void register_input(ustring name, ustring ui_name, SocketType::Type type, int struct_offset, const void *default_value, - const NodeEnum *enum_values = NULL, - const NodeType **node_type = NULL, - int flags = 0, int extra_flags = 0); + const NodeEnum *enum_values = NULL, + const NodeType **node_type = NULL, + int flags = 0, int extra_flags = 0); void register_output(ustring name, ustring ui_name, SocketType::Type type); const SocketType *find_input(ustring name) const; -- cgit v1.2.3 From 9a080d2ea6065b3686089c156cfa72d29744c953 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 27 Jul 2018 11:34:52 +0200 Subject: Fix T56092: command line arguments after -- beginning with -h don't work. --- intern/cycles/blender/addon/engine.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'intern/cycles') diff --git a/intern/cycles/blender/addon/engine.py b/intern/cycles/blender/addon/engine.py index 08c6a65e5ad..7e06b15afdd 100644 --- a/intern/cycles/blender/addon/engine.py +++ b/intern/cycles/blender/addon/engine.py @@ -52,7 +52,9 @@ def _workaround_buggy_drivers(): def _configure_argument_parser(): import argparse - parser = argparse.ArgumentParser(description="Cycles Addon argument parser") + # No help because it conflicts with general Python scripts argument parsing + parser = argparse.ArgumentParser(description="Cycles Addon argument parser", + add_help=False) parser.add_argument("--cycles-resumable-num-chunks", help="Number of chunks to split sample range into", default=None) -- cgit v1.2.3 From 709b36e43b94678b18fec20a92d7d34f9b5aa78b Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 27 Jul 2018 11:40:44 +0200 Subject: Cycles: Add utility function to query graph node size in bytes --- intern/cycles/graph/node.cpp | 85 +++++++++++++++++++++++++++++++++++++++++--- intern/cycles/graph/node.h | 3 ++ 2 files changed, 84 insertions(+), 4 deletions(-) (limited to 'intern/cycles') diff --git a/intern/cycles/graph/node.cpp b/intern/cycles/graph/node.cpp index 45ffc8d7d6b..5960d9aa7d5 100644 --- a/intern/cycles/graph/node.cpp +++ b/intern/cycles/graph/node.cpp @@ -425,20 +425,22 @@ bool Node::equals(const Node& other) const /* Hash */ +namespace { + template -static void value_hash(const Node *node, const SocketType& socket, MD5Hash& md5) +void value_hash(const Node *node, const SocketType& socket, MD5Hash& md5) { md5.append(((uint8_t*)node) + socket.struct_offset, socket.size()); } -static void float3_hash(const Node *node, const SocketType& socket, MD5Hash& md5) +void float3_hash(const Node *node, const SocketType& socket, MD5Hash& md5) { /* Don't compare 4th element used for padding. */ md5.append(((uint8_t*)node) + socket.struct_offset, sizeof(float) * 3); } template -static void array_hash(const Node *node, const SocketType& socket, MD5Hash& md5) +void array_hash(const Node *node, const SocketType& socket, MD5Hash& md5) { const array& a = *(const array*)(((char*)node) + socket.struct_offset); for (size_t i = 0; i < a.size(); i++) { @@ -446,7 +448,7 @@ static void array_hash(const Node *node, const SocketType& socket, MD5Hash& md5) } } -static void float3_array_hash(const Node *node, const SocketType& socket, MD5Hash& md5) +void float3_array_hash(const Node *node, const SocketType& socket, MD5Hash& md5) { /* Don't compare 4th element used for padding. */ const array& a = *(const array*)(((char*)node) + socket.struct_offset); @@ -455,6 +457,8 @@ static void float3_array_hash(const Node *node, const SocketType& socket, MD5Has } } +} // namespace + void Node::hash(MD5Hash& md5) { md5.append(type->name.string()); @@ -495,4 +499,77 @@ void Node::hash(MD5Hash& md5) } } +namespace { + +template +size_t array_size_in_bytes(const Node *node, const SocketType& socket) +{ + const array& a = *(const array*)(((char*)node) + socket.struct_offset); + return a.size() * sizeof(T); +} + +} // namespace + +size_t Node::get_total_size_in_bytes() const +{ + size_t total_size = 0; + foreach(const SocketType& socket, type->inputs) { + switch(socket.type) { + case SocketType::BOOLEAN: + case SocketType::FLOAT: + case SocketType::INT: + case SocketType::UINT: + case SocketType::COLOR: + case SocketType::VECTOR: + case SocketType::POINT: + case SocketType::NORMAL: + case SocketType::POINT2: + case SocketType::CLOSURE: + case SocketType::STRING: + case SocketType::ENUM: + case SocketType::TRANSFORM: + case SocketType::NODE: + total_size += socket.size(); + break; + + case SocketType::BOOLEAN_ARRAY: + total_size += array_size_in_bytes(this, socket); + break; + case SocketType::FLOAT_ARRAY: + total_size += array_size_in_bytes(this, socket); + break; + case SocketType::INT_ARRAY: + total_size += array_size_in_bytes(this, socket); + break; + case SocketType::COLOR_ARRAY: + total_size += array_size_in_bytes(this, socket); + break; + case SocketType::VECTOR_ARRAY: + total_size += array_size_in_bytes(this, socket); + break; + case SocketType::POINT_ARRAY: + total_size += array_size_in_bytes(this, socket); + break; + case SocketType::NORMAL_ARRAY: + total_size += array_size_in_bytes(this, socket); + break; + case SocketType::POINT2_ARRAY: + total_size += array_size_in_bytes(this, socket); + break; + case SocketType::STRING_ARRAY: + total_size += array_size_in_bytes(this, socket); + break; + case SocketType::TRANSFORM_ARRAY: + total_size += array_size_in_bytes(this, socket); + break; + case SocketType::NODE_ARRAY: + total_size += array_size_in_bytes(this, socket); + break; + + case SocketType::UNDEFINED: break; + } + } + return total_size; +} + CCL_NAMESPACE_END diff --git a/intern/cycles/graph/node.h b/intern/cycles/graph/node.h index a738bfe197e..11695a8631d 100644 --- a/intern/cycles/graph/node.h +++ b/intern/cycles/graph/node.h @@ -92,6 +92,9 @@ struct Node /* compute hash of node and its socket values */ void hash(MD5Hash& md5); + /* Get total size of this node. */ + size_t get_total_size_in_bytes() const; + ustring name; const NodeType *type; }; -- cgit v1.2.3 From 84d47e3685c7ccfeaf2dd41ab64d1b642f157add Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 27 Jul 2018 15:46:13 +0200 Subject: Cycles: Initial implementation of detailed statistics Gathers information about object geometry and textures. Very basic at this moment, but need to start somewhere. Things which needs to be included still: - "Runtime" information, like BVH. While it is not directly controllable by artists, it's still important to know. - Device array sizes. Again, not under artists control, but is added to the overall size. - Memory peak at different synchronization stages. At this point it simply prints info to the stdout after F12 is done, need better control over that too. Reviewers: brecht Differential Revision: https://developer.blender.org/D3566 --- intern/cycles/blender/addon/engine.py | 6 ++ intern/cycles/blender/blender_python.cpp | 9 +++ intern/cycles/blender/blender_session.cpp | 8 ++ intern/cycles/blender/blender_session.h | 2 + intern/cycles/render/CMakeLists.txt | 2 + intern/cycles/render/image.cpp | 12 +++ intern/cycles/render/image.h | 3 + intern/cycles/render/mesh.cpp | 10 +++ intern/cycles/render/mesh.h | 3 + intern/cycles/render/scene.cpp | 6 ++ intern/cycles/render/scene.h | 3 + intern/cycles/render/stats.cpp | 119 ++++++++++++++++++++++++++++++ intern/cycles/render/stats.h | 104 ++++++++++++++++++++++++++ 13 files changed, 287 insertions(+) create mode 100644 intern/cycles/render/stats.cpp create mode 100644 intern/cycles/render/stats.h (limited to 'intern/cycles') diff --git a/intern/cycles/blender/addon/engine.py b/intern/cycles/blender/addon/engine.py index 7e06b15afdd..c30d199ede8 100644 --- a/intern/cycles/blender/addon/engine.py +++ b/intern/cycles/blender/addon/engine.py @@ -67,6 +67,9 @@ def _configure_argument_parser(): parser.add_argument("--cycles-resumable-end-chunk", help="End chunk to render", default=None) + parser.add_argument("--cycles-print-stats", + help="Print rendering statistics to stderr", + action='store_true') return parser @@ -95,6 +98,9 @@ def _parse_command_line(): int(args.cycles_resumable_start_chunk), int(args.cycles_resumable_end_chunk), ) + if args.cycles_print_stats: + import _cycles + _cycles.enable_print_stats() def init(): diff --git a/intern/cycles/blender/blender_python.cpp b/intern/cycles/blender/blender_python.cpp index 3eccecb8850..4b01eb5f2d4 100644 --- a/intern/cycles/blender/blender_python.cpp +++ b/intern/cycles/blender/blender_python.cpp @@ -734,6 +734,12 @@ static PyObject *set_resumable_chunk_range_func(PyObject * /*self*/, PyObject *a Py_RETURN_NONE; } +static PyObject *enable_print_stats_func(PyObject * /*self*/, PyObject * /*args*/) +{ + BlenderSession::print_render_stats = true; + Py_RETURN_NONE; +} + static PyObject *get_device_types_func(PyObject * /*self*/, PyObject * /*args*/) { vector& devices = Device::available_devices(); @@ -772,6 +778,9 @@ static PyMethodDef methods[] = { {"debug_flags_update", debug_flags_update_func, METH_VARARGS, ""}, {"debug_flags_reset", debug_flags_reset_func, METH_NOARGS, ""}, + /* Statistics. */ + {"enable_print_stats", enable_print_stats_func, METH_NOARGS, ""}, + /* Resumable render */ {"set_resumable_chunk", set_resumable_chunk_func, METH_VARARGS, ""}, {"set_resumable_chunk_range", set_resumable_chunk_range_func, METH_VARARGS, ""}, diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp index 00d23b9095e..e11b8e0c70d 100644 --- a/intern/cycles/blender/blender_session.cpp +++ b/intern/cycles/blender/blender_session.cpp @@ -28,6 +28,7 @@ #include "render/scene.h" #include "render/session.h" #include "render/shader.h" +#include "render/stats.h" #include "util/util_color.h" #include "util/util_foreach.h" @@ -48,6 +49,7 @@ int BlenderSession::num_resumable_chunks = 0; int BlenderSession::current_resumable_chunk = 0; int BlenderSession::start_resumable_chunk = 0; int BlenderSession::end_resumable_chunk = 0; +bool BlenderSession::print_render_stats = false; BlenderSession::BlenderSession(BL::RenderEngine& b_engine, BL::UserPreferences& b_userpref, @@ -492,6 +494,12 @@ void BlenderSession::render() /* free result without merging */ end_render_result(b_engine, b_rr, true, true, false); + if(!b_engine.is_preview() && background && print_render_stats) { + RenderStats stats; + session->scene->collect_statistics(&stats); + printf("Render statistics:\n%s\n", stats.full_report().c_str()); + } + if(session->progress.get_cancel()) break; } diff --git a/intern/cycles/blender/blender_session.h b/intern/cycles/blender/blender_session.h index 3804e07cffc..08f5c873bef 100644 --- a/intern/cycles/blender/blender_session.h +++ b/intern/cycles/blender/blender_session.h @@ -143,6 +143,8 @@ public: static int start_resumable_chunk; static int end_resumable_chunk; + static bool print_render_stats; + protected: void do_write_update_render_result(BL::RenderResult& b_rr, BL::RenderLayer& b_rlay, diff --git a/intern/cycles/render/CMakeLists.txt b/intern/cycles/render/CMakeLists.txt index b7248354abd..7d2220f37f9 100644 --- a/intern/cycles/render/CMakeLists.txt +++ b/intern/cycles/render/CMakeLists.txt @@ -33,6 +33,7 @@ set(SRC session.cpp shader.cpp sobol.cpp + stats.cpp svm.cpp tables.cpp tile.cpp @@ -60,6 +61,7 @@ set(SRC_HEADERS session.h shader.h sobol.h + stats.h svm.h tables.h tile.h diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp index 741dfb0717a..e6ef19cc3be 100644 --- a/intern/cycles/render/image.cpp +++ b/intern/cycles/render/image.cpp @@ -17,6 +17,7 @@ #include "device/device.h" #include "render/image.h" #include "render/scene.h" +#include "render/stats.h" #include "util/util_foreach.h" #include "util/util_logging.h" @@ -1042,4 +1043,15 @@ void ImageManager::device_free(Device *device) } } +void ImageManager::collect_statistics(RenderStats *stats) +{ + for(int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) { + foreach(const Image *image, images[type]) { + stats->image.textures.add_entry( + NamedSizeEntry(path_filename(image->filename), + image->mem->memory_size())); + } + } +} + CCL_NAMESPACE_END diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h index 9a2b373d016..d94ebe564e3 100644 --- a/intern/cycles/render/image.h +++ b/intern/cycles/render/image.h @@ -29,6 +29,7 @@ CCL_NAMESPACE_BEGIN class Device; class Progress; +class RenderStats; class Scene; class ImageMetaData { @@ -89,6 +90,8 @@ public: device_memory *image_memory(int flat_slot); + void collect_statistics(RenderStats *stats); + bool need_update; /* NOTE: Here pixels_size is a size of storage, which equals to diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp index df408b478b2..ade575a52d6 100644 --- a/intern/cycles/render/mesh.cpp +++ b/intern/cycles/render/mesh.cpp @@ -27,6 +27,7 @@ #include "render/nodes.h" #include "render/object.h" #include "render/scene.h" +#include "render/stats.h" #include "kernel/osl/osl_globals.h" @@ -2276,6 +2277,15 @@ void MeshManager::tag_update(Scene *scene) scene->object_manager->need_update = true; } +void MeshManager::collect_statistics(const Scene *scene, RenderStats *stats) +{ + foreach(Mesh *mesh, scene->meshes) { + stats->mesh.geometry.add_entry( + NamedSizeEntry(string(mesh->name.c_str()), + mesh->get_total_size_in_bytes())); + } +} + bool Mesh::need_attribute(Scene *scene, AttributeStandard std) { if(std == ATTR_STD_NONE) diff --git a/intern/cycles/render/mesh.h b/intern/cycles/render/mesh.h index fc7d0b40273..444f03a3664 100644 --- a/intern/cycles/render/mesh.h +++ b/intern/cycles/render/mesh.h @@ -38,6 +38,7 @@ class Device; class DeviceScene; class Mesh; class Progress; +class RenderStats; class Scene; class SceneParams; class AttributeRequest; @@ -351,6 +352,8 @@ public: void create_volume_mesh(Scene *scene, Mesh *mesh, Progress &progress); + void collect_statistics(const Scene *scene, RenderStats *stats); + protected: /* Calculate verts/triangles/curves offsets in global arrays. */ void mesh_calc_offset(Scene *scene); diff --git a/intern/cycles/render/scene.cpp b/intern/cycles/render/scene.cpp index 1d65ef65980..9f93fed139c 100644 --- a/intern/cycles/render/scene.cpp +++ b/intern/cycles/render/scene.cpp @@ -379,4 +379,10 @@ void Scene::device_free() free_memory(false); } +void Scene::collect_statistics(RenderStats *stats) +{ + mesh_manager->collect_statistics(this, stats); + image_manager->collect_statistics(stats); +} + CCL_NAMESPACE_END diff --git a/intern/cycles/render/scene.h b/intern/cycles/render/scene.h index 713eba623b1..dd8069537eb 100644 --- a/intern/cycles/render/scene.h +++ b/intern/cycles/render/scene.h @@ -56,6 +56,7 @@ class ShaderManager; class Progress; class BakeManager; class BakeData; +class RenderStats; /* Scene Device Data */ @@ -255,6 +256,8 @@ public: void reset(); void device_free(); + void collect_statistics(RenderStats *stats); + protected: /* Check if some heavy data worth logging was updated. * Mainly used to suppress extra annoying logging. diff --git a/intern/cycles/render/stats.cpp b/intern/cycles/render/stats.cpp new file mode 100644 index 00000000000..101d33fcf65 --- /dev/null +++ b/intern/cycles/render/stats.cpp @@ -0,0 +1,119 @@ +/* + * Copyright 2011-2018 Blender Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "render/stats.h" +#include "util/util_algorithm.h" +#include "util/util_foreach.h" +#include "util/util_string.h" + +CCL_NAMESPACE_BEGIN + +static int kIndentNumSpaces = 2; + +/* Named size entry. */ + +namespace { + +bool namedSizeEntryComparator(const NamedSizeEntry& a, const NamedSizeEntry& b) +{ + /* We sort in descending order. */ + return a.size > b.size; +} + +} // namespace + +NamedSizeEntry::NamedSizeEntry() + : name(""), + size(0) { +} + +NamedSizeEntry::NamedSizeEntry(const string& name, size_t size) + : name(name), + size(size) { +} + +/* Named size statistics. */ + +NamedSizeStats::NamedSizeStats() + : total_size(0) { +} + +void NamedSizeStats::add_entry(const NamedSizeEntry& entry) { + total_size += entry.size; + entries.push_back(entry); +} + +string NamedSizeStats::full_report(int indent_level) +{ + const string indent(indent_level * kIndentNumSpaces, ' '); + const string double_indent = indent + indent; + string result = ""; + result += string_printf("%sTotal memory: %s (%s)\n", + indent.c_str(), + string_human_readable_size(total_size).c_str(), + string_human_readable_number(total_size).c_str()); + sort(entries.begin(), entries.end(), namedSizeEntryComparator); + foreach(const NamedSizeEntry& entry, entries) { + result += string_printf( + "%s%-32s %s (%s)\n", + double_indent.c_str(), + entry.name.c_str(), + string_human_readable_size(entry.size).c_str(), + string_human_readable_number(entry.size).c_str()); + } + return result; +} + +/* Mesh statistics. */ + +MeshStats::MeshStats() { +} + +string MeshStats::full_report(int indent_level) +{ + const string indent(indent_level * kIndentNumSpaces, ' '); + string result = ""; + result += indent + "Geometry:\n" + geometry.full_report(indent_level + 1); + return result; +} + +/* Image statistics. */ + +ImageStats::ImageStats() { +} + +string ImageStats::full_report(int indent_level) +{ + const string indent(indent_level * kIndentNumSpaces, ' '); + string result = ""; + result += indent + "Textures:\n" + textures.full_report(indent_level + 1); + return result; +} + +/* Overall statistics. */ + +RenderStats::RenderStats() { +} + +string RenderStats::full_report() +{ + string result = ""; + result += "Mesh statistics:\n" + mesh.full_report(1); + result += "Image statistics:\n" + image.full_report(1); + return result; +} + +CCL_NAMESPACE_END diff --git a/intern/cycles/render/stats.h b/intern/cycles/render/stats.h new file mode 100644 index 00000000000..72d5f1dd93d --- /dev/null +++ b/intern/cycles/render/stats.h @@ -0,0 +1,104 @@ +/* + * Copyright 2011-2018 Blender Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __RENDER_STATS_H__ +#define __RENDER_STATS_H__ + +#include "util/util_string.h" +#include "util/util_vector.h" + +CCL_NAMESPACE_BEGIN + +/* Named statistics entry, which corresponds to a size. There is no real + * semantic around the units of size, it just should be the same for all + * entries. + * + * This is a generic entry foi all size-related statistics, which helps + * avoiding duplicating code for things like sorting. + */ +class NamedSizeEntry { +public: + NamedSizeEntry(); + NamedSizeEntry(const string& name, size_t size); + + string name; + size_t size; +}; + +/* Container of named size entries. Used, for example, to store per-mesh memory + * usage statistics. But also keeps track of overall memory usage of the + * container. + */ +class NamedSizeStats { +public: + NamedSizeStats(); + + /* Add entry to the statistics. */ + void add_entry(const NamedSizeEntry& entry); + + /* Generate full human-readable report. */ + string full_report(int indent_level = 0); + + /* Total size of all entries. */ + size_t total_size; + + /* NOTE: Is fine to read directly, but for adding use add_entry(), which + * makes sure all accumulating values are properly updated. + */ + vector entries; +}; + +/* Statistics about mesh in the render database. */ +class MeshStats { +public: + MeshStats(); + + /* Generate full human-readable report. */ + string full_report(int indent_level = 0); + + /* Input geometry statistics, this is what is coming as an input to render + * from. say, Blender. This does not include runtime or engine specific + * memory like BVH. + */ + NamedSizeStats geometry; +}; + +/* Statistics about images held in memory. */ +class ImageStats { +public: + ImageStats(); + + /* Generate full human-readable report. */ + string full_report(int indent_level = 0); + + NamedSizeStats textures; +}; + +/* Render process statistics. */ +class RenderStats { +public: + RenderStats(); + + /* Return full report as string. */ + string full_report(); + + MeshStats mesh; + ImageStats image; +}; + +CCL_NAMESPACE_END + +#endif /* __RENDER_STATS_H__ */ -- cgit v1.2.3