diff options
author | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2017-10-24 05:07:24 +0300 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2017-10-24 05:09:48 +0300 |
commit | a1aad1f8d15ecdad4a22c34a3708ba6f8c815079 (patch) | |
tree | 1a94d013095c99156b2b2fa89844e61756d61c01 /intern | |
parent | 070a668d04844610059aaedc80c49e9038fd1779 (diff) |
Fix T53134: denoising with CPU + GPU render leaves some tiles noisy.
Diffstat (limited to 'intern')
-rw-r--r-- | intern/cycles/device/device_multi.cpp | 18 | ||||
-rw-r--r-- | intern/cycles/render/buffers.cpp | 3 | ||||
-rw-r--r-- | intern/cycles/render/buffers.h | 1 |
3 files changed, 17 insertions, 5 deletions
diff --git a/intern/cycles/device/device_multi.cpp b/intern/cycles/device/device_multi.cpp index 0a6dd90c86d..ed2e46965ac 100644 --- a/intern/cycles/device/device_multi.cpp +++ b/intern/cycles/device/device_multi.cpp @@ -248,26 +248,36 @@ public: if(!tiles[i].buffers) { continue; } + /* If the tile was rendered on another device, copy its memory to * to the current device now, for the duration of the denoising task. * Note that this temporarily modifies the RenderBuffers and calls * the device, so this function is not thread safe. */ device_vector<float> &mem = tiles[i].buffers->buffer; if(mem.device != sub_device) { - tiles[i].buffers->copy_from_device(); + /* Only copy from device to host once. This is faster, but + * also required for the case where a CPU thread is denoising + * a tile rendered on the GPU. In that case we have to avoid + * overwriting the buffer being denoised by the CPU thread. */ + if(!tiles[i].buffers->map_neighbor_copied) { + tiles[i].buffers->map_neighbor_copied = true; + mem.copy_from_device(0, mem.data_size, 1); + } Device *original_device = mem.device; device_ptr original_ptr = mem.device_pointer; + size_t original_size = mem.device_size; mem.device = sub_device; mem.device_pointer = 0; + mem.device_size = 0; - sub_device->mem_alloc(mem); - sub_device->mem_copy_to(mem); + mem.copy_to_device(); tiles[i].buffer = mem.device_pointer; mem.device = original_device; mem.device_pointer = original_ptr; + mem.device_size = original_size; } } } @@ -290,7 +300,7 @@ public: /* Copy denoised tile to the host. */ if(i == 4) { - tiles[i].buffers->copy_from_device(); + mem.copy_from_device(0, mem.data_size, 1); } sub_device->mem_free(mem); diff --git a/intern/cycles/render/buffers.cpp b/intern/cycles/render/buffers.cpp index 01f853dda71..23125f66d66 100644 --- a/intern/cycles/render/buffers.cpp +++ b/intern/cycles/render/buffers.cpp @@ -115,7 +115,8 @@ RenderTile::RenderTile() /* Render Buffers */ RenderBuffers::RenderBuffers(Device *device) -: buffer(device, "RenderBuffers", MEM_READ_WRITE) +: buffer(device, "RenderBuffers", MEM_READ_WRITE), + map_neighbor_copied(false) { } diff --git a/intern/cycles/render/buffers.h b/intern/cycles/render/buffers.h index 8563d6674ec..9fa0cdd4e27 100644 --- a/intern/cycles/render/buffers.h +++ b/intern/cycles/render/buffers.h @@ -74,6 +74,7 @@ public: /* float buffer */ device_vector<float> buffer; + bool map_neighbor_copied; explicit RenderBuffers(Device *device); ~RenderBuffers(); |