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 'source/blender/compositor/operations/COM_DenoiseOperation.cpp')
-rw-r--r--source/blender/compositor/operations/COM_DenoiseOperation.cpp111
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
}