Cycles: Add per-tile render time debug pass
authorLukas Stockner <lukas.stockner@freenet.de>
Fri, 17 Nov 2017 13:23:48 +0000 (14:23 +0100)
committerLukas Stockner <lukas.stockner@freenet.de>
Fri, 17 Nov 2017 15:40:24 +0000 (16:40 +0100)
Reviewers: sergey, brecht

Differential Revision: https://developer.blender.org/D2920

12 files changed:
intern/cycles/blender/addon/engine.py
intern/cycles/blender/addon/properties.py
intern/cycles/blender/addon/ui.py
intern/cycles/blender/blender_sync.cpp
intern/cycles/device/device_cpu.cpp
intern/cycles/device/device_cuda.cpp
intern/cycles/device/opencl/opencl_mega.cpp
intern/cycles/device/opencl/opencl_split.cpp
intern/cycles/kernel/kernel_types.h
intern/cycles/render/buffers.cpp
intern/cycles/render/buffers.h
intern/cycles/render/film.cpp

index bc71a1b2fd7da3d14d0c91700e48e1cbdcc469c7..1f97eff9bd0f308777298e0162f4b4201676aaa2 100644 (file)
@@ -234,6 +234,7 @@ def register_passes(engine, scene, srl):
     if srl.use_pass_environment:           engine.register_pass(scene, srl, "Env",           3, "RGB",  'COLOR')
 
     crl = srl.cycles
+    if crl.pass_debug_render_time:             engine.register_pass(scene, srl, "Debug Render Time",             1, "X",   'VALUE')
     if crl.pass_debug_bvh_traversed_nodes:     engine.register_pass(scene, srl, "Debug BVH Traversed Nodes",     1, "X",   'VALUE')
     if crl.pass_debug_bvh_traversed_instances: engine.register_pass(scene, srl, "Debug BVH Traversed Instances", 1, "X",   'VALUE')
     if crl.pass_debug_bvh_intersections:       engine.register_pass(scene, srl, "Debug BVH Intersections",       1, "X",   'VALUE')
index e20e0b757c187505f9ba0920e459315136871e95..e5084138a9c21cc0e847e8711320d14e75171fa3 100644 (file)
@@ -1189,6 +1189,12 @@ class CyclesRenderLayerSettings(bpy.types.PropertyGroup):
                 default=False,
                 update=update_render_passes,
                 )
+        cls.pass_debug_render_time = BoolProperty(
+                name="Debug Render Time",
+                description="Render time in milliseconds per sample and pixel",
+                default=False,
+                update=update_render_passes,
+                )
         cls.use_pass_volume_direct = BoolProperty(
                 name="Volume Direct",
                 description="Deliver direct volumetric scattering pass",
index ff36e2a82d82f17e8ec66ee5ed01ef29d4113bf3..03ca1ab6c7facb465984f30f86e9174b6c60af00 100644 (file)
@@ -541,8 +541,9 @@ class CYCLES_RENDER_PT_layer_passes(CyclesButtonsPanel, Panel):
             sub.active = crl.use_denoising
             sub.prop(crl, "denoising_store_passes", text="Denoising")
 
+        col = layout.column()
+        col.prop(crl, "pass_debug_render_time")
         if _cycles.with_cycles_debug:
-            col = layout.column()
             col.prop(crl, "pass_debug_bvh_traversed_nodes")
             col.prop(crl, "pass_debug_bvh_traversed_instances")
             col.prop(crl, "pass_debug_bvh_intersections")
index dbc559e749ef943f0b229eda8d18aa11b9c93693..e24ed31b92685dedc381ee194fe75f37570e4f70 100644 (file)
@@ -520,6 +520,7 @@ PassType BlenderSync::get_pass_type(BL::RenderPass& b_pass)
        MAP_PASS("Debug BVH Intersections", PASS_BVH_INTERSECTIONS);
        MAP_PASS("Debug Ray Bounces", PASS_RAY_BOUNCES);
 #endif
+       MAP_PASS("Debug Render Time", PASS_RENDER_TIME);
 #undef MAP_PASS
 
        return PASS_NONE;
@@ -606,6 +607,10 @@ array<Pass> BlenderSync::sync_render_passes(BL::RenderLayer& b_rlay,
                Pass::add(PASS_RAY_BOUNCES, passes);
        }
 #endif
+       if(get_boolean(crp, "pass_debug_render_time")) {
+               b_engine.add_pass("Debug Render Time", 1, "X", b_srlay.name().c_str());
+               Pass::add(PASS_RENDER_TIME, passes);
+       }
        if(get_boolean(crp, "use_pass_volume_direct")) {
                b_engine.add_pass("VolumeDir", 3, "RGB", b_srlay.name().c_str());
                Pass::add(PASS_VOLUME_DIRECT, passes);
index ce02a5a932e4f0047fd6148749a182aa7932f230..999b9230d295be8f1dece574547a8708b47e943d 100644 (file)
@@ -689,6 +689,8 @@ public:
 
        void path_trace(DeviceTask &task, RenderTile &tile, KernelGlobals *kg)
        {
+               scoped_timer timer(&tile.buffers->render_time);
+
                float *render_buffer = (float*)tile.buffer;
                int start_sample = tile.start_sample;
                int end_sample = tile.start_sample + tile.num_samples;
index 305e5e9f1af3d245a730473388408b64fa9ea6d3..d8d787ba706b768662bf1df86bd749286bb24d22 100644 (file)
@@ -1436,6 +1436,8 @@ public:
 
        void path_trace(DeviceTask& task, RenderTile& rtile, device_vector<WorkTile>& work_tiles)
        {
+               scoped_timer timer(&rtile.buffers->render_time);
+
                if(have_error())
                        return;
 
index 575ab73330ec2ec14ee95bcca15eb9c35a45bb41..ef39cfb5f7dbb25f4e48e53d0e80e59460379195 100644 (file)
@@ -59,6 +59,8 @@ public:
 
        void path_trace(RenderTile& rtile, int sample)
        {
+               scoped_timer timer(&rtile.buffers->render_time);
+
                /* Cast arguments to cl types. */
                cl_mem d_data = CL_MEM_PTR(const_mem_map["__data"]->device_pointer);
                cl_mem d_buffer = CL_MEM_PTR(rtile.buffer);
index 1073cfa6bf6a8c282447427265e118e4593d62c4..2d819080674c8d08306bbef0964b2eae6f5b4ee1 100644 (file)
@@ -138,6 +138,8 @@ public:
                        while(task->acquire_tile(this, tile)) {
                                if(tile.task == RenderTile::PATH_TRACE) {
                                        assert(tile.task == RenderTile::PATH_TRACE);
+                                       scoped_timer timer(&tile.buffers->render_time);
+
                                        split_kernel->path_trace(task,
                                                                 tile,
                                                                 kgbuffer,
index b6a9cf5f28580cd6d71d8572fbfa82a5d1f4840c..c4a9b3f4aa35fe2cf21396b295a38d9521a0aa0e 100644 (file)
@@ -393,6 +393,7 @@ typedef enum PassType {
        PASS_BVH_INTERSECTIONS,
        PASS_RAY_BOUNCES,
 #endif
+       PASS_RENDER_TIME,
        PASS_CATEGORY_MAIN_END = 31,
 
        PASS_MIST = 32,
index ac675dc7b398203ead03607a8890cada39d6dea8..2fa297371f4b0890bf1ed9d2bd32bd81694e341b 100644 (file)
@@ -116,7 +116,7 @@ RenderTile::RenderTile()
 
 RenderBuffers::RenderBuffers(Device *device)
 : buffer(device, "RenderBuffers", MEM_READ_WRITE),
-  map_neighbor_copied(false)
+  map_neighbor_copied(false), render_time(0.0f)
 {
 }
 
@@ -264,6 +264,12 @@ bool RenderBuffers::get_pass_rect(PassType type, float exposure, int sample, int
                                }
                        }
 #endif
+                       else if(type == PASS_RENDER_TIME) {
+                               float val = (float) (1000.0 * render_time/(params.width * params.height * sample));
+                               for(int i = 0; i < size; i++, pixels++) {
+                                       pixels[0] = val;
+                               }
+                       }
                        else {
                                for(int i = 0; i < size; i++, in += pass_stride, pixels++) {
                                        float f = *in;
index 9fa0cdd4e27bac20b1102ba583f912437c6c5ff7..028bfb83735d549062449de8e21f5bf2f768d055 100644 (file)
@@ -75,6 +75,7 @@ public:
        /* float buffer */
        device_vector<float> buffer;
        bool map_neighbor_copied;
+       double render_time;
 
        explicit RenderBuffers(Device *device);
        ~RenderBuffers();
index 82fea67f001f672bf806c1fb759be90e202441c2..6c8c929c2f991610344aef7f8b60bd8cf73660a6 100644 (file)
@@ -116,6 +116,10 @@ void Pass::add(PassType type, array<Pass>& passes)
                        pass.exposure = false;
                        break;
 #endif
+               case PASS_RENDER_TIME:
+                       /* This pass is handled entirely on the host side. */
+                       pass.components = 0;
+                       break;
 
                case PASS_DIFFUSE_COLOR:
                case PASS_GLOSSY_COLOR:
@@ -428,6 +432,8 @@ void Film::device_update(Device *device, DeviceScene *dscene, Scene *scene)
                                kfilm->pass_ray_bounces = kfilm->pass_stride;
                                break;
 #endif
+                       case PASS_RENDER_TIME:
+                               break;
 
                        default:
                                assert(false);