diff options
Diffstat (limited to 'source/blender/compositor/operations/COM_DenoiseOperation.cpp')
-rw-r--r-- | source/blender/compositor/operations/COM_DenoiseOperation.cpp | 111 |
1 files changed, 61 insertions, 50 deletions
diff --git a/source/blender/compositor/operations/COM_DenoiseOperation.cpp b/source/blender/compositor/operations/COM_DenoiseOperation.cpp index ad53ab13def..8235c296c5a 100644 --- a/source/blender/compositor/operations/COM_DenoiseOperation.cpp +++ b/source/blender/compositor/operations/COM_DenoiseOperation.cpp @@ -21,16 +21,19 @@ #include "COM_DenoiseOperation.h" #include "BLI_math.h" +#include "BLI_system.h" #ifdef WITH_OPENIMAGEDENOISE +# include "BLI_threads.h" # include <OpenImageDenoise/oidn.hpp> +static pthread_mutex_t oidn_lock = BLI_MUTEX_INITIALIZER; #endif #include <iostream> DenoiseOperation::DenoiseOperation() : SingleThreadedOperation() { this->addInputSocket(COM_DT_COLOR); - this->addInputSocket(COM_DT_COLOR); this->addInputSocket(COM_DT_VECTOR); + this->addInputSocket(COM_DT_COLOR); this->addOutputSocket(COM_DT_COLOR); this->m_settings = NULL; } @@ -38,23 +41,23 @@ void DenoiseOperation::initExecution() { SingleThreadedOperation::initExecution(); this->m_inputProgramColor = getInputSocketReader(0); - this->m_inputProgramAlbedo = getInputSocketReader(1); - this->m_inputProgramNormal = getInputSocketReader(2); + this->m_inputProgramNormal = getInputSocketReader(1); + this->m_inputProgramAlbedo = getInputSocketReader(2); } void DenoiseOperation::deinitExecution() { this->m_inputProgramColor = NULL; - this->m_inputProgramAlbedo = NULL; this->m_inputProgramNormal = NULL; + this->m_inputProgramAlbedo = NULL; SingleThreadedOperation::deinitExecution(); } MemoryBuffer *DenoiseOperation::createMemoryBuffer(rcti *rect2) { MemoryBuffer *tileColor = (MemoryBuffer *)this->m_inputProgramColor->initializeTileData(rect2); - MemoryBuffer *tileAlbedo = (MemoryBuffer *)this->m_inputProgramAlbedo->initializeTileData(rect2); MemoryBuffer *tileNormal = (MemoryBuffer *)this->m_inputProgramNormal->initializeTileData(rect2); + MemoryBuffer *tileAlbedo = (MemoryBuffer *)this->m_inputProgramAlbedo->initializeTileData(rect2); rcti rect; rect.xmin = 0; rect.ymin = 0; @@ -62,7 +65,7 @@ MemoryBuffer *DenoiseOperation::createMemoryBuffer(rcti *rect2) rect.ymax = getHeight(); MemoryBuffer *result = new MemoryBuffer(COM_DT_COLOR, &rect); float *data = result->getBuffer(); - this->generateDenoise(data, tileColor, tileAlbedo, tileNormal, this->m_settings); + this->generateDenoise(data, tileColor, tileNormal, tileAlbedo, this->m_settings); return result; } @@ -85,8 +88,8 @@ bool DenoiseOperation::determineDependingAreaOfInterest(rcti * /*input*/, void DenoiseOperation::generateDenoise(float *data, MemoryBuffer *inputTileColor, - MemoryBuffer *inputTileAlbedo, MemoryBuffer *inputTileNormal, + MemoryBuffer *inputTileAlbedo, NodeDenoise *settings) { float *inputBufferColor = inputTileColor->getBuffer(); @@ -95,61 +98,69 @@ void DenoiseOperation::generateDenoise(float *data, return; } #ifdef WITH_OPENIMAGEDENOISE - oidn::DeviceRef device = oidn::newDevice(); - device.commit(); + if (BLI_cpu_support_sse41()) { + oidn::DeviceRef device = oidn::newDevice(); + device.commit(); - oidn::FilterRef filter = device.newFilter("RT"); - filter.setImage("color", - inputBufferColor, - oidn::Format::Float3, - inputTileColor->getWidth(), - inputTileColor->getHeight(), - 0, - 4 * sizeof(float)); - if (inputTileAlbedo && inputTileAlbedo->getBuffer()) { - filter.setImage("albedo", - inputTileAlbedo->getBuffer(), + oidn::FilterRef filter = device.newFilter("RT"); + filter.setImage("color", + inputBufferColor, oidn::Format::Float3, - inputTileAlbedo->getWidth(), - inputTileAlbedo->getHeight(), + inputTileColor->getWidth(), + inputTileColor->getHeight(), 0, 4 * sizeof(float)); - } - if (inputTileNormal && inputTileNormal->getBuffer()) { - filter.setImage("normal", - inputTileNormal->getBuffer(), + if (inputTileNormal && inputTileNormal->getBuffer()) { + filter.setImage("normal", + inputTileNormal->getBuffer(), + oidn::Format::Float3, + inputTileNormal->getWidth(), + inputTileNormal->getHeight(), + 0, + 3 * sizeof(float)); + } + if (inputTileAlbedo && inputTileAlbedo->getBuffer()) { + filter.setImage("albedo", + inputTileAlbedo->getBuffer(), + oidn::Format::Float3, + inputTileAlbedo->getWidth(), + inputTileAlbedo->getHeight(), + 0, + 4 * sizeof(float)); + } + filter.setImage("output", + data, oidn::Format::Float3, - inputTileNormal->getWidth(), - inputTileNormal->getHeight(), + inputTileColor->getWidth(), + inputTileColor->getHeight(), 0, - 3 * sizeof(float)); - } - filter.setImage("output", - data, - oidn::Format::Float3, - inputTileColor->getWidth(), - inputTileColor->getHeight(), - 0, - 4 * sizeof(float)); + 4 * sizeof(float)); - BLI_assert(settings); - if (settings) { - filter.set("hdr", settings->hdr); - filter.set("srgb", false); - } + BLI_assert(settings); + if (settings) { + filter.set("hdr", settings->hdr); + filter.set("srgb", false); + } - filter.commit(); - filter.execute(); + filter.commit(); + /* Since it's memory intensive, it's better to run only one instance of OIDN at a time. + * OpenImageDenoise is multithreaded internally and should use all available cores nonetheless. + */ + BLI_mutex_lock(&oidn_lock); + filter.execute(); + BLI_mutex_unlock(&oidn_lock); - /* copy the alpha channel, OpenImageDenoise currently only supports RGB */ - size_t numPixels = inputTileColor->getWidth() * inputTileColor->getHeight(); - for (size_t i = 0; i < numPixels; ++i) { - data[i * 4 + 3] = inputBufferColor[i * 4 + 3]; + /* copy the alpha channel, OpenImageDenoise currently only supports RGB */ + size_t numPixels = inputTileColor->getWidth() * inputTileColor->getHeight(); + for (size_t i = 0; i < numPixels; i++) { + data[i * 4 + 3] = inputBufferColor[i * 4 + 3]; + } + return; } -#else +#endif + /* If built without OIDN or running on an unsupported CPU, just pass through. */ UNUSED_VARS(inputTileAlbedo, inputTileNormal, settings); ::memcpy(data, inputBufferColor, inputTileColor->getWidth() * inputTileColor->getHeight() * sizeof(float) * 4); -#endif } |