D627: Memory usage optimization for the compositor.

The compostor used a fixed size of 4 floats to hold pixel data. this
patch will select size of a pixel based on its type.
It uses 1 float for Value, 3 float for vector and 4 floats for color
data types.

When benchmarking on shots (opening shot of caminandes) we get a
reduction of memory of 30% and a tiny speedup as less data
transformations needs to take place (but these are negligable.

More information of the patch can be found on
https://developer.blender.org/D627 and
http://wiki.blender.org/index.php/Dev:Ref/Proposals/Compositor2014_p1.1_TD

Developers: jbakker & mdewanchand
Thanks for Sergey for his indept review.
This commit is contained in:
Jeroen Bakker 2015-01-19 18:13:26 +01:00
parent a8fa291b8c
commit 35d3b6316b
48 changed files with 364 additions and 442 deletions

@ -90,8 +90,6 @@ set(SRC
intern/COM_OpenCLDevice.h intern/COM_OpenCLDevice.h
intern/COM_CompositorContext.cpp intern/COM_CompositorContext.cpp
intern/COM_CompositorContext.h intern/COM_CompositorContext.h
intern/COM_ChannelInfo.cpp
intern/COM_ChannelInfo.h
intern/COM_SingleThreadedOperation.cpp intern/COM_SingleThreadedOperation.cpp
intern/COM_SingleThreadedOperation.h intern/COM_SingleThreadedOperation.h
intern/COM_Debug.cpp intern/COM_Debug.cpp

@ -105,7 +105,9 @@ typedef enum OrderOfChunks {
#define COM_RULE_OF_THIRDS_DIVIDER 100.0f #define COM_RULE_OF_THIRDS_DIVIDER 100.0f
#define COM_NUMBER_OF_CHANNELS 4 #define COM_NUM_CHANNELS_VALUE 1
#define COM_NUM_CHANNELS_VECTOR 3
#define COM_NUM_CHANNELS_COLOR 4
#define COM_BLUR_BOKEH_PIXELS 512 #define COM_BLUR_BOKEH_PIXELS 512

@ -1,35 +0,0 @@
/*
* Copyright 2011, Blender Foundation.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#include "COM_ChannelInfo.h"
#include "COM_defines.h"
#include <stdio.h>
/**
* @brief create new ChannelInfo instance and sets the defaults.
*/
ChannelInfo::ChannelInfo()
{
this->m_number = 0;
this->m_premultiplied = true;
this->m_type = COM_CT_UNUSED;
}

@ -1,121 +0,0 @@
/*
* Copyright 2011, Blender Foundation.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#ifndef _COM_ChannelInfo_h
#define _COM_ChannelInfo_h
#include <vector>
#include "BKE_text.h"
#include <string>
#include "DNA_node_types.h"
#include "BLI_rect.h"
using namespace std;
/**
* @brief List of possible channel types
* @ingroup Model
*/
typedef enum ChannelType {
COM_CT_ColorComponent /** @brief this channel is contains color information. Specific used is determined by channelnumber, and in the future color space */,
COM_CT_Alpha /** @brief this channel is contains transparency value */,
COM_CT_Value /** @brief this channel is contains a value */,
COM_CT_X /** @brief this channel is contains a X value */,
COM_CT_Y /** @brief this channel is contains a Y value */,
COM_CT_Z /** @brief this channel is contains a Z value */,
COM_CT_W /** @brief this channel is contains a W value */,
COM_CT_UNUSED /** @brief this channel is unused */
} ChannelType;
/**
* @brief ChannelInfo holds information about a channel.
*
* Channels are transported from node to node via a NodeLink.
* ChannelInfo holds specific setting of these channels in order that the to-node of the link
* Can handle specific logic per channel setting.
*
* @note currently this is not used, but a future place to implement color spacing and other things.
* @ingroup Model
*/
class ChannelInfo {
private:
/**
* @brief the channel number, in the link. [0-3]
*/
int m_number;
/**
* @brief type of channel
*/
ChannelType m_type;
/**
* @brieg Is this value in this channel premultiplied with its alpha
* @note only valid if type = ColorComponent;
*/
bool m_premultiplied;
// /**
// * Color space of this value.
// * only valid when type = ColorComponent;
// */
// string colorspacename;
public:
/**
* @brief creates a new ChannelInfo and set default values
*/
ChannelInfo();
/**
* @brief set the index of this channel in the NodeLink
*/
void setNumber(const int number) { this->m_number = number; }
/**
* @brief get the index of this channel in the NodeLink
*/
const int getNumber() const { return this->m_number; }
/**
* @brief set the type of channel
*/
void setType(const ChannelType type) { this->m_type = type; }
/**
* @brief get the type of channel
*/
const ChannelType getType() const { return this->m_type; }
/**
* @brief set the premultiplicatioin of this channel
*/
void setPremultiplied(const bool premultiplied) { this->m_premultiplied = premultiplied; }
/**
* @brief is this channel premultiplied
*/
const bool isPremultiplied() const { return this->m_premultiplied; }
};
#endif

@ -137,11 +137,15 @@ void ExecutionSystem::execute()
} }
unsigned int index; unsigned int index;
// First allocale all write buffer
for (index = 0; index < this->m_operations.size(); index++) { for (index = 0; index < this->m_operations.size(); index++) {
NodeOperation *operation = this->m_operations[index]; NodeOperation *operation = this->m_operations[index];
operation->setbNodeTree(this->m_context.getbNodeTree()); if (operation->isWriteBufferOperation()) {
operation->initExecution(); operation->setbNodeTree(this->m_context.getbNodeTree());
operation->initExecution();
}
} }
// Connect read buffers to their write buffers
for (index = 0; index < this->m_operations.size(); index++) { for (index = 0; index < this->m_operations.size(); index++) {
NodeOperation *operation = this->m_operations[index]; NodeOperation *operation = this->m_operations[index];
if (operation->isReadBufferOperation()) { if (operation->isReadBufferOperation()) {
@ -149,6 +153,14 @@ void ExecutionSystem::execute()
readOperation->updateMemoryBuffer(); readOperation->updateMemoryBuffer();
} }
} }
// initialize other operations
for (index = 0; index < this->m_operations.size(); index++) {
NodeOperation *operation = this->m_operations[index];
if (!operation->isWriteBufferOperation()) {
operation->setbNodeTree(this->m_context.getbNodeTree());
operation->initExecution();
}
}
for (index = 0; index < this->m_groups.size(); index++) { for (index = 0; index < this->m_groups.size(); index++) {
ExecutionGroup *executionGroup = this->m_groups[index]; ExecutionGroup *executionGroup = this->m_groups[index];
executionGroup->setChunksize(this->m_context.getChunksize()); executionGroup->setChunksize(this->m_context.getChunksize());

@ -27,6 +27,18 @@
using std::min; using std::min;
using std::max; using std::max;
static unsigned int determine_num_channels(DataType datatype) {
switch (datatype) {
case COM_DT_VALUE:
return COM_NUM_CHANNELS_VALUE;
case COM_DT_VECTOR:
return COM_NUM_CHANNELS_VECTOR;
case COM_DT_COLOR:
default:
return COM_NUM_CHANNELS_COLOR;
}
}
unsigned int MemoryBuffer::determineBufferSize() unsigned int MemoryBuffer::determineBufferSize()
{ {
return getWidth() * getHeight(); return getWidth() * getHeight();
@ -34,61 +46,62 @@ unsigned int MemoryBuffer::determineBufferSize()
int MemoryBuffer::getWidth() const int MemoryBuffer::getWidth() const
{ {
return this->m_rect.xmax - this->m_rect.xmin; return this->m_width;
} }
int MemoryBuffer::getHeight() const int MemoryBuffer::getHeight() const
{ {
return this->m_rect.ymax - this->m_rect.ymin; return this->m_height;
} }
MemoryBuffer::MemoryBuffer(MemoryProxy *memoryProxy, unsigned int chunkNumber, rcti *rect) MemoryBuffer::MemoryBuffer(MemoryProxy *memoryProxy, unsigned int chunkNumber, rcti *rect)
{ {
BLI_rcti_init(&this->m_rect, rect->xmin, rect->xmax, rect->ymin, rect->ymax); BLI_rcti_init(&this->m_rect, rect->xmin, rect->xmax, rect->ymin, rect->ymax);
this->m_width = BLI_rcti_size_x(&this->m_rect);
this->m_height = BLI_rcti_size_y(&this->m_rect);
this->m_memoryProxy = memoryProxy; this->m_memoryProxy = memoryProxy;
this->m_chunkNumber = chunkNumber; this->m_chunkNumber = chunkNumber;
this->m_buffer = (float *)MEM_mallocN_aligned(sizeof(float) * determineBufferSize() * COM_NUMBER_OF_CHANNELS, 16, "COM_MemoryBuffer"); this->m_num_channels = determine_num_channels(memoryProxy->getDataType());
this->m_buffer = (float *)MEM_mallocN_aligned(sizeof(float) * determineBufferSize() * this->m_num_channels, 16, "COM_MemoryBuffer");
this->m_state = COM_MB_ALLOCATED; this->m_state = COM_MB_ALLOCATED;
this->m_datatype = COM_DT_COLOR; this->m_datatype = memoryProxy->getDataType();;
this->m_chunkWidth = this->m_rect.xmax - this->m_rect.xmin;
} }
MemoryBuffer::MemoryBuffer(MemoryProxy *memoryProxy, rcti *rect) MemoryBuffer::MemoryBuffer(MemoryProxy *memoryProxy, rcti *rect)
{ {
BLI_rcti_init(&this->m_rect, rect->xmin, rect->xmax, rect->ymin, rect->ymax); BLI_rcti_init(&this->m_rect, rect->xmin, rect->xmax, rect->ymin, rect->ymax);
this->m_width = BLI_rcti_size_x(&this->m_rect);
this->m_height = BLI_rcti_size_y(&this->m_rect);
this->m_memoryProxy = memoryProxy; this->m_memoryProxy = memoryProxy;
this->m_chunkNumber = -1; this->m_chunkNumber = -1;
this->m_buffer = (float *)MEM_mallocN_aligned(sizeof(float) * determineBufferSize() * COM_NUMBER_OF_CHANNELS, 16, "COM_MemoryBuffer"); this->m_num_channels = determine_num_channels(memoryProxy->getDataType());
this->m_buffer = (float *)MEM_mallocN_aligned(sizeof(float) * determineBufferSize() * this->m_num_channels, 16, "COM_MemoryBuffer");
this->m_state = COM_MB_TEMPORARILY; this->m_state = COM_MB_TEMPORARILY;
this->m_datatype = COM_DT_COLOR; this->m_datatype = memoryProxy->getDataType();
this->m_chunkWidth = this->m_rect.xmax - this->m_rect.xmin; }
MemoryBuffer::MemoryBuffer(DataType dataType, rcti *rect)
{
BLI_rcti_init(&this->m_rect, rect->xmin, rect->xmax, rect->ymin, rect->ymax);
this->m_width = BLI_rcti_size_x(&this->m_rect);
this->m_height = BLI_rcti_size_y(&this->m_rect);
this->m_height = this->m_rect.ymax - this->m_rect.ymin;
this->m_memoryProxy = NULL;
this->m_chunkNumber = -1;
this->m_num_channels = determine_num_channels(dataType);
this->m_buffer = (float *)MEM_mallocN_aligned(sizeof(float) * determineBufferSize() * this->m_num_channels, 16, "COM_MemoryBuffer");
this->m_state = COM_MB_TEMPORARILY;
this->m_datatype = dataType;
} }
MemoryBuffer *MemoryBuffer::duplicate() MemoryBuffer *MemoryBuffer::duplicate()
{ {
MemoryBuffer *result = new MemoryBuffer(this->m_memoryProxy, &this->m_rect); MemoryBuffer *result = new MemoryBuffer(this->m_memoryProxy, &this->m_rect);
memcpy(result->m_buffer, this->m_buffer, this->determineBufferSize() * COM_NUMBER_OF_CHANNELS * sizeof(float)); memcpy(result->m_buffer, this->m_buffer, this->determineBufferSize() * this->m_num_channels * sizeof(float));
return result; return result;
} }
void MemoryBuffer::clear() void MemoryBuffer::clear()
{ {
memset(this->m_buffer, 0, this->determineBufferSize() * COM_NUMBER_OF_CHANNELS * sizeof(float)); memset(this->m_buffer, 0, this->determineBufferSize() * this->m_num_channels * sizeof(float));
} }
float *MemoryBuffer::convertToValueBuffer()
{
const unsigned int size = this->determineBufferSize();
unsigned int i;
float *result = (float *)MEM_mallocN(sizeof(float) * size, __func__);
const float *fp_src = this->m_buffer;
float *fp_dst = result;
for (i = 0; i < size; i++, fp_dst++, fp_src += COM_NUMBER_OF_CHANNELS) {
*fp_dst = *fp_src;
}
return result;
}
float MemoryBuffer::getMaximumValue() float MemoryBuffer::getMaximumValue()
{ {
@ -98,7 +111,7 @@ float MemoryBuffer::getMaximumValue()
const float *fp_src = this->m_buffer; const float *fp_src = this->m_buffer;
for (i = 0; i < size; i++, fp_src += COM_NUMBER_OF_CHANNELS) { for (i = 0; i < size; i++, fp_src += this->m_num_channels) {
float value = *fp_src; float value = *fp_src;
if (value > result) { if (value > result) {
result = value; result = value;
@ -116,7 +129,7 @@ float MemoryBuffer::getMaximumValue(rcti *rect)
BLI_rcti_isect(rect, &this->m_rect, &rect_clamp); BLI_rcti_isect(rect, &this->m_rect, &rect_clamp);
if (!BLI_rcti_is_empty(&rect_clamp)) { if (!BLI_rcti_is_empty(&rect_clamp)) {
MemoryBuffer *temp = new MemoryBuffer(NULL, &rect_clamp); MemoryBuffer *temp = new MemoryBuffer(this->m_datatype, &rect_clamp);
temp->copyContentFrom(this); temp->copyContentFrom(this);
float result = temp->getMaximumValue(); float result = temp->getMaximumValue();
delete temp; delete temp;
@ -152,9 +165,9 @@ void MemoryBuffer::copyContentFrom(MemoryBuffer *otherBuffer)
for (otherY = minY; otherY < maxY; otherY++) { for (otherY = minY; otherY < maxY; otherY++) {
otherOffset = ((otherY - otherBuffer->m_rect.ymin) * otherBuffer->m_chunkWidth + minX - otherBuffer->m_rect.xmin) * COM_NUMBER_OF_CHANNELS; otherOffset = ((otherY - otherBuffer->m_rect.ymin) * otherBuffer->m_width + minX - otherBuffer->m_rect.xmin) * this->m_num_channels;
offset = ((otherY - this->m_rect.ymin) * this->m_chunkWidth + minX - this->m_rect.xmin) * COM_NUMBER_OF_CHANNELS; offset = ((otherY - this->m_rect.ymin) * this->m_width + minX - this->m_rect.xmin) * this->m_num_channels;
memcpy(&this->m_buffer[offset], &otherBuffer->m_buffer[otherOffset], (maxX - minX) * COM_NUMBER_OF_CHANNELS * sizeof(float)); memcpy(&this->m_buffer[offset], &otherBuffer->m_buffer[otherOffset], (maxX - minX) * this->m_num_channels * sizeof(float));
} }
} }
@ -163,9 +176,8 @@ void MemoryBuffer::writePixel(int x, int y, const float color[4])
if (x >= this->m_rect.xmin && x < this->m_rect.xmax && if (x >= this->m_rect.xmin && x < this->m_rect.xmax &&
y >= this->m_rect.ymin && y < this->m_rect.ymax) y >= this->m_rect.ymin && y < this->m_rect.ymax)
{ {
const int offset = (this->m_chunkWidth * (y - this->m_rect.ymin) + x - this->m_rect.xmin) * COM_NUMBER_OF_CHANNELS; const int offset = (this->m_width * (y - this->m_rect.ymin) + x - this->m_rect.xmin) * this->m_num_channels;
copy_v4_v4(&this->m_buffer[offset], color); memcpy(&this->m_buffer[offset], color, sizeof(float)*this->m_num_channels); }
}
} }
void MemoryBuffer::addPixel(int x, int y, const float color[4]) void MemoryBuffer::addPixel(int x, int y, const float color[4])
@ -173,8 +185,12 @@ void MemoryBuffer::addPixel(int x, int y, const float color[4])
if (x >= this->m_rect.xmin && x < this->m_rect.xmax && if (x >= this->m_rect.xmin && x < this->m_rect.xmax &&
y >= this->m_rect.ymin && y < this->m_rect.ymax) y >= this->m_rect.ymin && y < this->m_rect.ymax)
{ {
const int offset = (this->m_chunkWidth * (y - this->m_rect.ymin) + x - this->m_rect.xmin) * COM_NUMBER_OF_CHANNELS; const int offset = (this->m_width * (y - this->m_rect.ymin) + x - this->m_rect.xmin) * this->m_num_channels;
add_v4_v4(&this->m_buffer[offset], color); float *dst = &this->m_buffer[offset];
const float *src = color;
for (int i = 0; i < this->m_num_channels ; i++, dst++, src++) {
*dst += *src;
}
} }
} }
@ -208,8 +224,9 @@ static void read_ewa_pixel_sampled(void *userdata, int x, int y, float result[4]
} }
} }
void MemoryBuffer::readEWA(float result[4], const float uv[2], const float derivatives[2][2], PixelSampler sampler) void MemoryBuffer::readEWA(float *result, const float uv[2], const float derivatives[2][2], PixelSampler sampler)
{ {
BLI_assert(this->m_datatype==COM_DT_COLOR);
ReadEWAData data; ReadEWAData data;
data.buffer = this; data.buffer = this;
data.sampler = sampler; data.sampler = sampler;

@ -82,11 +82,6 @@ private:
*/ */
unsigned int m_chunkNumber; unsigned int m_chunkNumber;
/**
* @brief width of the chunk
*/
unsigned int m_chunkWidth;
/** /**
* @brief state of the buffer * @brief state of the buffer
*/ */
@ -97,6 +92,15 @@ private:
*/ */
float *m_buffer; float *m_buffer;
/**
* @brief the number of channels of a single value in the buffer.
* For value buffers this is 1, vector 3 and color 4
*/
unsigned int m_num_channels;
int m_width;
int m_height;
public: public:
/** /**
* @brief construct new MemoryBuffer for a chunk * @brief construct new MemoryBuffer for a chunk
@ -108,6 +112,11 @@ public:
*/ */
MemoryBuffer(MemoryProxy *memoryProxy, rcti *rect); MemoryBuffer(MemoryProxy *memoryProxy, rcti *rect);
/**
* @brief construct new temporarily MemoryBuffer for an area
*/
MemoryBuffer(DataType datatype, rcti *rect);
/** /**
* @brief destructor * @brief destructor
*/ */
@ -118,6 +127,8 @@ public:
*/ */
unsigned int getChunkNumber() { return this->m_chunkNumber; } unsigned int getChunkNumber() { return this->m_chunkNumber; }
unsigned int get_num_channels() { return this->m_num_channels; }
/** /**
* @brief get the data of this MemoryBuffer * @brief get the data of this MemoryBuffer
* @note buffer should already be available in memory * @note buffer should already be available in memory
@ -134,8 +145,8 @@ public:
inline void wrap_pixel(int &x, int &y, MemoryBufferExtend extend_x, MemoryBufferExtend extend_y) inline void wrap_pixel(int &x, int &y, MemoryBufferExtend extend_x, MemoryBufferExtend extend_y)
{ {
int w = m_rect.xmax - m_rect.xmin; int w = this->m_width;
int h = m_rect.ymax - m_rect.ymin; int h = this->m_height;
x = x - m_rect.xmin; x = x - m_rect.xmin;
y = y - m_rect.ymin; y = y - m_rect.ymin;
@ -164,7 +175,39 @@ public:
} }
} }
inline void read(float result[4], int x, int y, inline void wrap_pixel(float &x, float &y, MemoryBufferExtend extend_x, MemoryBufferExtend extend_y)
{
float w = (float)this->m_width;
float h = (float)this->m_height;
x = x - m_rect.xmin;
y = y - m_rect.ymin;
switch (extend_x) {
case COM_MB_CLIP:
break;
case COM_MB_EXTEND:
if (x < 0) x = 0.0f;
if (x >= w) x = w;
break;
case COM_MB_REPEAT:
x = fmodf(x, w);
break;
}
switch (extend_y) {
case COM_MB_CLIP:
break;
case COM_MB_EXTEND:
if (y < 0) y = 0.0f;
if (y >= h) y = h;
break;
case COM_MB_REPEAT:
y = fmodf(y, h);
break;
}
}
inline void read(float *result, int x, int y,
MemoryBufferExtend extend_x = COM_MB_CLIP, MemoryBufferExtend extend_x = COM_MB_CLIP,
MemoryBufferExtend extend_y = COM_MB_CLIP) MemoryBufferExtend extend_y = COM_MB_CLIP)
{ {
@ -172,81 +215,54 @@ public:
bool clip_y = (extend_y == COM_MB_CLIP && (y < m_rect.ymin || y >= m_rect.ymax)); bool clip_y = (extend_y == COM_MB_CLIP && (y < m_rect.ymin || y >= m_rect.ymax));
if (clip_x || clip_y) { if (clip_x || clip_y) {
/* clip result outside rect is zero */ /* clip result outside rect is zero */
zero_v4(result); memset(result, 0, this->m_num_channels*sizeof(float));
} }
else { else {
wrap_pixel(x, y, extend_x, extend_y); int u = x;
const int offset = (this->m_chunkWidth * y + x) * COM_NUMBER_OF_CHANNELS; int v = y;
copy_v4_v4(result, &this->m_buffer[offset]); this->wrap_pixel(u, v, extend_x, extend_y);
const int offset = (this->m_width * y + x) * this->m_num_channels;
float* buffer = &this->m_buffer[offset];
memcpy(result, buffer, sizeof(float)*this->m_num_channels);
} }
} }
inline void readNoCheck(float result[4], int x, int y, inline void readNoCheck(float *result, int x, int y,
MemoryBufferExtend extend_x = COM_MB_CLIP, MemoryBufferExtend extend_x = COM_MB_CLIP,
MemoryBufferExtend extend_y = COM_MB_CLIP) MemoryBufferExtend extend_y = COM_MB_CLIP)
{ {
wrap_pixel(x, y, extend_x, extend_y); int u = x;
const int offset = (this->m_chunkWidth * y + x) * COM_NUMBER_OF_CHANNELS; int v = y;
this->wrap_pixel(u, v, extend_x, extend_y);
const int offset = (this->m_width * v + u) * this->m_num_channels;
BLI_assert(offset >= 0); BLI_assert(offset >= 0);
BLI_assert(offset < this->determineBufferSize() * COM_NUMBER_OF_CHANNELS); BLI_assert(offset < this->determineBufferSize() * this->m_num_channels);
BLI_assert(!(extend_x == COM_MB_CLIP && (x < m_rect.xmin || x >= m_rect.xmax)) && BLI_assert(!(extend_x == COM_MB_CLIP && (u < m_rect.xmin || u >= m_rect.xmax)) &&
!(extend_y == COM_MB_CLIP && (y < m_rect.ymin || y >= m_rect.ymax))); !(extend_y == COM_MB_CLIP && (v < m_rect.ymin || v >= m_rect.ymax)));
#if 0 #if 0
/* always true */ /* always true */
BLI_assert((int)(MEM_allocN_len(this->m_buffer) / sizeof(*this->m_buffer)) == BLI_assert((int)(MEM_allocN_len(this->m_buffer) / sizeof(*this->m_buffer)) ==
(int)(this->determineBufferSize() * COM_NUMBER_OF_CHANNELS)); (int)(this->determineBufferSize() * COM_NUMBER_OF_CHANNELS));
#endif #endif
float* buffer = &this->m_buffer[offset];
copy_v4_v4(result, &this->m_buffer[offset]); memcpy(result, buffer, sizeof(float)*this->m_num_channels);
} }
void writePixel(int x, int y, const float color[4]); void writePixel(int x, int y, const float color[4]);
void addPixel(int x, int y, const float color[4]); void addPixel(int x, int y, const float color[4]);
inline void readBilinear(float result[4], float x, float y, inline void readBilinear(float *result, float x, float y,
MemoryBufferExtend extend_x = COM_MB_CLIP, MemoryBufferExtend extend_x = COM_MB_CLIP,
MemoryBufferExtend extend_y = COM_MB_CLIP) MemoryBufferExtend extend_y = COM_MB_CLIP)
{ {
int x1 = floor(x); float u = x;
int y1 = floor(y); float v = y;
int x2 = x1 + 1; this->wrap_pixel(u, v, extend_x, extend_y);
int y2 = y1 + 1; BLI_bilinear_interpolation_fl(this->m_buffer, result, this->m_width, this->m_height, this->m_num_channels, u, v);
wrap_pixel(x1, y1, extend_x, extend_y);
wrap_pixel(x2, y2, extend_x, extend_y);
float valuex = x - x1;
float valuey = y - y1;
float mvaluex = 1.0f - valuex;
float mvaluey = 1.0f - valuey;
float color1[4];
float color2[4];
float color3[4];
float color4[4];
read(color1, x1, y1);
read(color2, x1, y2);
read(color3, x2, y1);
read(color4, x2, y2);
color1[0] = color1[0] * mvaluey + color2[0] * valuey;
color1[1] = color1[1] * mvaluey + color2[1] * valuey;
color1[2] = color1[2] * mvaluey + color2[2] * valuey;
color1[3] = color1[3] * mvaluey + color2[3] * valuey;
color3[0] = color3[0] * mvaluey + color4[0] * valuey;
color3[1] = color3[1] * mvaluey + color4[1] * valuey;
color3[2] = color3[2] * mvaluey + color4[2] * valuey;
color3[3] = color3[3] * mvaluey + color4[3] * valuey;
result[0] = color1[0] * mvaluex + color3[0] * valuex;
result[1] = color1[1] * mvaluex + color3[1] * valuex;
result[2] = color1[2] * mvaluex + color3[2] * valuex;
result[3] = color1[3] * mvaluex + color3[3] * valuex;
} }
void readEWA(float result[4], const float uv[2], const float derivatives[2][2], PixelSampler sampler); void readEWA(float *result, const float uv[2], const float derivatives[2][2], PixelSampler sampler);
/** /**
* @brief is this MemoryBuffer a temporarily buffer (based on an area, not on a chunk) * @brief is this MemoryBuffer a temporarily buffer (based on an area, not on a chunk)
@ -284,7 +300,6 @@ public:
MemoryBuffer *duplicate(); MemoryBuffer *duplicate();
float *convertToValueBuffer();
float getMaximumValue(); float getMaximumValue();
float getMaximumValue(rcti *rect); float getMaximumValue(rcti *rect);
private: private:

@ -23,10 +23,11 @@
#include "COM_MemoryProxy.h" #include "COM_MemoryProxy.h"
MemoryProxy::MemoryProxy() MemoryProxy::MemoryProxy(DataType datatype)
{ {
this->m_writeBufferOperation = NULL; this->m_writeBufferOperation = NULL;
this->m_executor = NULL; this->m_executor = NULL;
this->m_datatype = datatype;
} }
void MemoryProxy::allocate(unsigned int width, unsigned int height) void MemoryProxy::allocate(unsigned int width, unsigned int height)

@ -63,8 +63,13 @@ private:
*/ */
MemoryBuffer *m_buffer; MemoryBuffer *m_buffer;
/**
* @brief datatype of this MemoryProxy
*/
DataType m_datatype;
public: public:
MemoryProxy(); MemoryProxy(DataType type);
/** /**
* @brief set the ExecutionGroup that can be scheduled to calculate a certain chunk. * @brief set the ExecutionGroup that can be scheduled to calculate a certain chunk.
@ -104,6 +109,8 @@ public:
*/ */
inline MemoryBuffer *getBuffer() { return this->m_buffer; } inline MemoryBuffer *getBuffer() { return this->m_buffer; }
inline DataType getDataType() { return this->m_datatype; }
#ifdef WITH_CXX_GUARDEDALLOC #ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("COM:MemoryProxy") MEM_CXX_CLASS_ALLOC_FUNCS("COM:MemoryProxy")
#endif #endif

@ -476,7 +476,7 @@ void NodeOperationBuilder::add_input_buffers(NodeOperation *operation, NodeOpera
/* check of other end already has write operation, otherwise add a new one */ /* check of other end already has write operation, otherwise add a new one */
WriteBufferOperation *writeoperation = find_attached_write_buffer_operation(output); WriteBufferOperation *writeoperation = find_attached_write_buffer_operation(output);
if (!writeoperation) { if (!writeoperation) {
writeoperation = new WriteBufferOperation(); writeoperation = new WriteBufferOperation(output->getDataType());
writeoperation->setbNodeTree(m_context->getbNodeTree()); writeoperation->setbNodeTree(m_context->getbNodeTree());
addOperation(writeoperation); addOperation(writeoperation);
@ -486,7 +486,7 @@ void NodeOperationBuilder::add_input_buffers(NodeOperation *operation, NodeOpera
} }
/* add readbuffer op for the input */ /* add readbuffer op for the input */
ReadBufferOperation *readoperation = new ReadBufferOperation(); ReadBufferOperation *readoperation = new ReadBufferOperation(output->getDataType());
readoperation->setMemoryProxy(writeoperation->getMemoryProxy()); readoperation->setMemoryProxy(writeoperation->getMemoryProxy());
this->addOperation(readoperation); this->addOperation(readoperation);
@ -519,7 +519,7 @@ void NodeOperationBuilder::add_output_buffers(NodeOperation *operation, NodeOper
/* if no write buffer operation exists yet, create a new one */ /* if no write buffer operation exists yet, create a new one */
if (!writeOperation) { if (!writeOperation) {
writeOperation = new WriteBufferOperation(); writeOperation = new WriteBufferOperation(operation->getOutputSocket()->getDataType());
writeOperation->setbNodeTree(m_context->getbNodeTree()); writeOperation->setbNodeTree(m_context->getbNodeTree());
addOperation(writeOperation); addOperation(writeOperation);
@ -534,7 +534,7 @@ void NodeOperationBuilder::add_output_buffers(NodeOperation *operation, NodeOper
if (&target->getOperation() == writeOperation) if (&target->getOperation() == writeOperation)
continue; /* skip existing write op links */ continue; /* skip existing write op links */
ReadBufferOperation *readoperation = new ReadBufferOperation(); ReadBufferOperation *readoperation = new ReadBufferOperation(operation->getOutputSocket()->getDataType());
readoperation->setMemoryProxy(writeOperation->getMemoryProxy()); readoperation->setMemoryProxy(writeOperation->getMemoryProxy());
addOperation(readoperation); addOperation(readoperation);

@ -24,6 +24,18 @@
#include "COM_WorkScheduler.h" #include "COM_WorkScheduler.h"
typedef enum COM_VendorID {NVIDIA = 0x10DE, AMD = 0x1002} COM_VendorID; typedef enum COM_VendorID {NVIDIA = 0x10DE, AMD = 0x1002} COM_VendorID;
const cl_image_format IMAGE_FORMAT_COLOR = {
CL_RGBA,
CL_FLOAT
};
const cl_image_format IMAGE_FORMAT_VECTOR = {
CL_RGB,
CL_FLOAT
};
const cl_image_format IMAGE_FORMAT_VALUE = {
CL_R,
CL_FLOAT
};
OpenCLDevice::OpenCLDevice(cl_context context, cl_device_id device, cl_program program, cl_int vendorId) OpenCLDevice::OpenCLDevice(cl_context context, cl_device_id device, cl_program program, cl_int vendorId)
{ {
@ -72,6 +84,21 @@ cl_mem OpenCLDevice::COM_clAttachMemoryBufferToKernelParameter(cl_kernel kernel,
return COM_clAttachMemoryBufferToKernelParameter(kernel, parameterIndex, offsetIndex, cleanup, inputMemoryBuffers, (ReadBufferOperation *)reader); return COM_clAttachMemoryBufferToKernelParameter(kernel, parameterIndex, offsetIndex, cleanup, inputMemoryBuffers, (ReadBufferOperation *)reader);
} }
const cl_image_format* OpenCLDevice::determineImageFormat(MemoryBuffer *memoryBuffer)
{
const cl_image_format *imageFormat;
int num_channels = memoryBuffer->get_num_channels();
if (num_channels == 1) {
imageFormat = &IMAGE_FORMAT_VALUE;
} else if (num_channels == 3) {
imageFormat = &IMAGE_FORMAT_VECTOR;
} else {
imageFormat = &IMAGE_FORMAT_COLOR;
}
return imageFormat;
}
cl_mem OpenCLDevice::COM_clAttachMemoryBufferToKernelParameter(cl_kernel kernel, int parameterIndex, int offsetIndex, cl_mem OpenCLDevice::COM_clAttachMemoryBufferToKernelParameter(cl_kernel kernel, int parameterIndex, int offsetIndex,
list<cl_mem> *cleanup, MemoryBuffer **inputMemoryBuffers, list<cl_mem> *cleanup, MemoryBuffer **inputMemoryBuffers,
ReadBufferOperation *reader) ReadBufferOperation *reader)
@ -80,12 +107,9 @@ cl_mem OpenCLDevice::COM_clAttachMemoryBufferToKernelParameter(cl_kernel kernel,
MemoryBuffer *result = reader->getInputMemoryBuffer(inputMemoryBuffers); MemoryBuffer *result = reader->getInputMemoryBuffer(inputMemoryBuffers);
const cl_image_format imageFormat = { const cl_image_format *imageFormat = determineImageFormat(result);
CL_RGBA,
CL_FLOAT
};
cl_mem clBuffer = clCreateImage2D(this->m_context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, &imageFormat, result->getWidth(), cl_mem clBuffer = clCreateImage2D(this->m_context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, imageFormat, result->getWidth(),
result->getHeight(), 0, result->getBuffer(), &error); result->getHeight(), 0, result->getBuffer(), &error);
if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); }

@ -94,6 +94,12 @@ public:
*/ */
void execute(WorkPackage *work); void execute(WorkPackage *work);
/**
* @brief determine an image format
* @param memorybuffer
*/
static const cl_image_format* determineImageFormat(MemoryBuffer *memoryBuffer);
cl_context getContext() { return this->m_context; } cl_context getContext() { return this->m_context; }
cl_command_queue getQueue() { return this->m_queue; } cl_command_queue getQueue() { return this->m_queue; }

@ -196,7 +196,7 @@ void WorkScheduler::schedule(ExecutionGroup *group, int chunkNumber)
BLI_thread_queue_push(g_cpuqueue, package); BLI_thread_queue_push(g_cpuqueue, package);
} }
#else #else
BLI_thread_queue_push(cpuqueue, package); BLI_thread_queue_push(g_cpuqueue, package);
#endif #endif
#endif #endif
} }

@ -73,8 +73,9 @@ void SocketBufferNode::convertToOperations(NodeConverter &converter, const Compo
NodeOutput *output = this->getOutputSocket(0); NodeOutput *output = this->getOutputSocket(0);
NodeInput *input = this->getInputSocket(0); NodeInput *input = this->getInputSocket(0);
WriteBufferOperation *writeOperation = new WriteBufferOperation(); DataType datatype = output->getDataType();
ReadBufferOperation *readOperation = new ReadBufferOperation(); WriteBufferOperation *writeOperation = new WriteBufferOperation(datatype);
ReadBufferOperation *readOperation = new ReadBufferOperation(datatype);
readOperation->setMemoryProxy(writeOperation->getMemoryProxy()); readOperation->setMemoryProxy(writeOperation->getMemoryProxy());
converter.addOperation(writeOperation); converter.addOperation(writeOperation);
converter.addOperation(readOperation); converter.addOperation(readOperation);

@ -57,8 +57,8 @@ void TranslateNode::convertToOperations(NodeConverter &converter, const Composit
converter.mapOutputSocket(outputSocket, operation->getOutputSocket(0)); converter.mapOutputSocket(outputSocket, operation->getOutputSocket(0));
if (data->wrap_axis) { if (data->wrap_axis) {
WriteBufferOperation *writeOperation = new WriteBufferOperation(); WriteBufferOperation *writeOperation = new WriteBufferOperation(COM_DT_COLOR);
WrapOperation *wrapOperation = new WrapOperation(); WrapOperation *wrapOperation = new WrapOperation(COM_DT_COLOR);
wrapOperation->setMemoryProxy(writeOperation->getMemoryProxy()); wrapOperation->setMemoryProxy(writeOperation->getMemoryProxy());
wrapOperation->setWrapping(data->wrap_axis); wrapOperation->setWrapping(data->wrap_axis);

@ -95,7 +95,7 @@ void *AntiAliasOperation::initializeTileData(rcti *rect)
float *input = tile->getBuffer(); float *input = tile->getBuffer();
char *valuebuffer = (char *)MEM_mallocN(sizeof(char) * size, __func__); char *valuebuffer = (char *)MEM_mallocN(sizeof(char) * size, __func__);
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
float in = input[i * COM_NUMBER_OF_CHANNELS]; float in = input[i];
valuebuffer[i] = FTOCHAR(in); valuebuffer[i] = FTOCHAR(in);
} }
antialias_tagbuf(tile->getWidth(), tile->getHeight(), valuebuffer); antialias_tagbuf(tile->getWidth(), tile->getHeight(), valuebuffer);

@ -110,11 +110,11 @@ void BokehBlurOperation::executePixel(float output[4], int x, int y, void *data)
int step = getStep(); int step = getStep();
int offsetadd = getOffsetAdd(); int offsetadd = getOffsetAdd() * COM_NUM_CHANNELS_COLOR;
float m = this->m_bokehDimension / pixelSize; float m = this->m_bokehDimension / pixelSize;
for (int ny = miny; ny < maxy; ny += step) { for (int ny = miny; ny < maxy; ny += step) {
int bufferindex = ((minx - bufferstartx) * 4) + ((ny - bufferstarty) * 4 * bufferwidth); int bufferindex = ((minx - bufferstartx) * COM_NUM_CHANNELS_COLOR) + ((ny - bufferstarty) * COM_NUM_CHANNELS_COLOR * bufferwidth);
for (int nx = minx; nx < maxx; nx += step) { for (int nx = minx; nx < maxx; nx += step) {
float u = this->m_bokehMidX - (nx - x) * m; float u = this->m_bokehMidX - (nx - x) * m;
float v = this->m_bokehMidY - (ny - y) * m; float v = this->m_bokehMidY - (ny - y) * m;

@ -138,7 +138,7 @@ void CompositorOperation::executeRegion(rcti *rect, unsigned int tileNumber)
int y2 = rect->ymax; int y2 = rect->ymax;
int offset = (y1 * this->getWidth() + x1); int offset = (y1 * this->getWidth() + x1);
int add = (this->getWidth() - (x2 - x1)); int add = (this->getWidth() - (x2 - x1));
int offset4 = offset * COM_NUMBER_OF_CHANNELS; int offset4 = offset * COM_NUM_CHANNELS_COLOR;
int x; int x;
int y; int y;
bool breaked = false; bool breaked = false;
@ -196,14 +196,14 @@ void CompositorOperation::executeRegion(rcti *rect, unsigned int tileNumber)
this->m_depthInput->readSampled(color, input_x, input_y, COM_PS_NEAREST); this->m_depthInput->readSampled(color, input_x, input_y, COM_PS_NEAREST);
zbuffer[offset] = color[0]; zbuffer[offset] = color[0];
offset4 += COM_NUMBER_OF_CHANNELS; offset4 += COM_NUM_CHANNELS_COLOR;
offset++; offset++;
if (isBreaked()) { if (isBreaked()) {
breaked = true; breaked = true;
} }
} }
offset += add; offset += add;
offset4 += add * COM_NUMBER_OF_CHANNELS; offset4 += add * COM_NUM_CHANNELS_COLOR;
} }
} }

@ -49,9 +49,9 @@ ConvertValueToColorOperation::ConvertValueToColorOperation() : ConvertBaseOperat
void ConvertValueToColorOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) void ConvertValueToColorOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
{ {
float inputValue[4]; float value;
this->m_inputOperation->readSampled(inputValue, x, y, sampler); this->m_inputOperation->readSampled(&value, x, y, sampler);
output[0] = output[1] = output[2] = inputValue[0]; output[0] = output[1] = output[2] = value;
output[3] = 1.0f; output[3] = 1.0f;
} }
@ -98,8 +98,9 @@ ConvertColorToVectorOperation::ConvertColorToVectorOperation() : ConvertBaseOper
void ConvertColorToVectorOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) void ConvertColorToVectorOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
{ {
this->m_inputOperation->readSampled(output, x, y, sampler); float color[4];
} this->m_inputOperation->readSampled(color, x, y, sampler);
copy_v3_v3(output, color);}
/* ******** Value to Vector ******** */ /* ******** Value to Vector ******** */
@ -112,12 +113,9 @@ ConvertValueToVectorOperation::ConvertValueToVectorOperation() : ConvertBaseOper
void ConvertValueToVectorOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) void ConvertValueToVectorOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
{ {
float input[4]; float value;
this->m_inputOperation->readSampled(input, x, y, sampler); this->m_inputOperation->readSampled(&value, x, y, sampler);
output[0] = input[0]; output[0] = output[1] = output[2] = value;
output[1] = input[0];
output[2] = input[0];
output[3] = 0.0f;
} }

@ -72,7 +72,7 @@ void DilateErodeThresholdOperation::executePixel(float output[4], int x, int y,
const float inset = this->m_inset; const float inset = this->m_inset;
float mindist = rd * 2; float mindist = rd * 2;
MemoryBuffer *inputBuffer = (MemoryBuffer *)data; MemoryBuffer *inputBuffer = (MemoryBuffer*)data;
float *buffer = inputBuffer->getBuffer(); float *buffer = inputBuffer->getBuffer();
rcti *rect = inputBuffer->getRect(); rcti *rect = inputBuffer->getRect();
const int minx = max(x - this->m_scope, rect->xmin); const int minx = max(x - this->m_scope, rect->xmin);
@ -82,18 +82,18 @@ void DilateErodeThresholdOperation::executePixel(float output[4], int x, int y,
const int bufferWidth = BLI_rcti_size_x(rect); const int bufferWidth = BLI_rcti_size_x(rect);
int offset; int offset;
this->m_inputProgram->read(inputValue, x, y, NULL); inputBuffer->read(inputValue, x, y);
if (inputValue[0] > sw) { if (inputValue[0] > sw) {
for (int yi = miny; yi < maxy; yi++) { for (int yi = miny; yi < maxy; yi++) {
const float dy = yi - y; const float dy = yi - y;
offset = ((yi - rect->ymin) * bufferWidth + (minx - rect->xmin)) * 4; offset = ((yi - rect->ymin) * bufferWidth + (minx - rect->xmin));
for (int xi = minx; xi < maxx; xi++) { for (int xi = minx; xi < maxx; xi++) {
if (buffer[offset] < sw) { if (buffer[offset] < sw) {
const float dx = xi - x; const float dx = xi - x;
const float dis = dx * dx + dy * dy; const float dis = dx * dx + dy * dy;
mindist = min(mindist, dis); mindist = min(mindist, dis);
} }
offset += 4; offset ++;
} }
} }
pixelvalue = -sqrtf(mindist); pixelvalue = -sqrtf(mindist);
@ -101,15 +101,14 @@ void DilateErodeThresholdOperation::executePixel(float output[4], int x, int y,
else { else {
for (int yi = miny; yi < maxy; yi++) { for (int yi = miny; yi < maxy; yi++) {
const float dy = yi - y; const float dy = yi - y;
offset = ((yi - rect->ymin) * bufferWidth + (minx - rect->xmin)) * 4; offset = ((yi - rect->ymin) * bufferWidth + (minx - rect->xmin));
for (int xi = minx; xi < maxx; xi++) { for (int xi = minx; xi < maxx; xi++) {
if (buffer[offset] > sw) { if (buffer[offset] > sw) {
const float dx = xi - x; const float dx = xi - x;
const float dis = dx * dx + dy * dy; const float dis = dx * dx + dy * dy;
mindist = min(mindist, dis); mindist = min(mindist, dis);
} }
offset += 4; offset ++;
} }
} }
pixelvalue = sqrtf(mindist); pixelvalue = sqrtf(mindist);
@ -206,14 +205,14 @@ void DilateDistanceOperation::executePixel(float output[4], int x, int y, void *
for (int yi = miny; yi < maxy; yi++) { for (int yi = miny; yi < maxy; yi++) {
const float dy = yi - y; const float dy = yi - y;
offset = ((yi - rect->ymin) * bufferWidth + (minx - rect->xmin)) * 4; offset = ((yi - rect->ymin) * bufferWidth + (minx - rect->xmin));
for (int xi = minx; xi < maxx; xi++) { for (int xi = minx; xi < maxx; xi++) {
const float dx = xi - x; const float dx = xi - x;
const float dis = dx * dx + dy * dy; const float dis = dx * dx + dy * dy;
if (dis <= mindist) { if (dis <= mindist) {
value = max(buffer[offset], value); value = max(buffer[offset], value);
} }
offset += 4; offset ++;
} }
} }
output[0] = value; output[0] = value;
@ -280,14 +279,14 @@ void ErodeDistanceOperation::executePixel(float output[4], int x, int y, void *d
for (int yi = miny; yi < maxy; yi++) { for (int yi = miny; yi < maxy; yi++) {
const float dy = yi - y; const float dy = yi - y;
offset = ((yi - rect->ymin) * bufferWidth + (minx - rect->xmin)) * 4; offset = ((yi - rect->ymin) * bufferWidth + (minx - rect->xmin));
for (int xi = minx; xi < maxx; xi++) { for (int xi = minx; xi < maxx; xi++) {
const float dx = xi - x; const float dx = xi - x;
const float dis = dx * dx + dy * dy; const float dis = dx * dx + dy * dy;
if (dis <= mindist) { if (dis <= mindist) {
value = min(buffer[offset], value); value = min(buffer[offset], value);
} }
offset += 4; offset ++;
} }
} }
output[0] = value; output[0] = value;
@ -383,7 +382,7 @@ void *DilateStepOperation::initializeTileData(rcti *rect)
buf[x] = -FLT_MAX; buf[x] = -FLT_MAX;
} }
for (x = xmin; x < xmax; ++x) { for (x = xmin; x < xmax; ++x) {
buf[x - rect->xmin + window - 1] = buffer[4 * (y * width + x)]; buf[x - rect->xmin + window - 1] = buffer[(y * width + x)];
} }
for (i = 0; i < (bwidth + 3 * half_window) / window; i++) { for (i = 0; i < (bwidth + 3 * half_window) / window; i++) {
@ -510,7 +509,7 @@ void *ErodeStepOperation::initializeTileData(rcti *rect)
buf[x] = FLT_MAX; buf[x] = FLT_MAX;
} }
for (x = xmin; x < xmax; ++x) { for (x = xmin; x < xmax; ++x) {
buf[x - rect->xmin + window - 1] = buffer[4 * (y * width + x)]; buf[x - rect->xmin + window - 1] = buffer[(y * width + x)];
} }
for (i = 0; i < (bwidth + 3 * half_window) / window; i++) { for (i = 0; i < (bwidth + 3 * half_window) / window; i++) {

@ -1270,11 +1270,9 @@ void *DoubleEdgeMaskOperation::initializeTileData(rcti *rect)
MemoryBuffer *innerMask = (MemoryBuffer *)this->m_inputInnerMask->initializeTileData(rect); MemoryBuffer *innerMask = (MemoryBuffer *)this->m_inputInnerMask->initializeTileData(rect);
MemoryBuffer *outerMask = (MemoryBuffer *)this->m_inputOuterMask->initializeTileData(rect); MemoryBuffer *outerMask = (MemoryBuffer *)this->m_inputOuterMask->initializeTileData(rect);
float *data = (float *)MEM_mallocN(sizeof(float) * this->getWidth() * this->getHeight(), __func__); float *data = (float *)MEM_mallocN(sizeof(float) * this->getWidth() * this->getHeight(), __func__);
float *imask = innerMask->convertToValueBuffer(); float *imask = innerMask->getBuffer();
float *omask = outerMask->convertToValueBuffer(); float *omask = outerMask->getBuffer();
doDoubleEdgeMask(imask, omask, data); doDoubleEdgeMask(imask, omask, data);
MEM_freeN(imask);
MEM_freeN(omask);
this->m_cachedInstance = data; this->m_cachedInstance = data;
} }
unlockMutex(); unlockMutex();

@ -92,16 +92,16 @@ void *FastGaussianBlurOperation::initializeTileData(rcti *rect)
this->m_sy = this->m_data.sizey * this->m_size / 2.0f; this->m_sy = this->m_data.sizey * this->m_size / 2.0f;
if ((this->m_sx == this->m_sy) && (this->m_sx > 0.f)) { if ((this->m_sx == this->m_sy) && (this->m_sx > 0.f)) {
for (c = 0; c < COM_NUMBER_OF_CHANNELS; ++c) for (c = 0; c < COM_NUM_CHANNELS_COLOR; ++c)
IIR_gauss(copy, this->m_sx, c, 3); IIR_gauss(copy, this->m_sx, c, 3);
} }
else { else {
if (this->m_sx > 0.0f) { if (this->m_sx > 0.0f) {
for (c = 0; c < COM_NUMBER_OF_CHANNELS; ++c) for (c = 0; c < COM_NUM_CHANNELS_COLOR; ++c)
IIR_gauss(copy, this->m_sx, c, 1); IIR_gauss(copy, this->m_sx, c, 1);
} }
if (this->m_sy > 0.0f) { if (this->m_sy > 0.0f) {
for (c = 0; c < COM_NUMBER_OF_CHANNELS; ++c) for (c = 0; c < COM_NUM_CHANNELS_COLOR; ++c)
IIR_gauss(copy, this->m_sy, c, 2); IIR_gauss(copy, this->m_sy, c, 2);
} }
} }
@ -120,6 +120,7 @@ void FastGaussianBlurOperation::IIR_gauss(MemoryBuffer *src, float sigma, unsign
unsigned int x, y, sz; unsigned int x, y, sz;
unsigned int i; unsigned int i;
float *buffer = src->getBuffer(); float *buffer = src->getBuffer();
const unsigned int num_channels = src->get_num_channels();
// <0.5 not valid, though can have a possibly useful sort of sharpening effect // <0.5 not valid, though can have a possibly useful sort of sharpening effect
if (sigma < 0.5f) return; if (sigma < 0.5f) return;
@ -198,31 +199,31 @@ void FastGaussianBlurOperation::IIR_gauss(MemoryBuffer *src, float sigma, unsign
int offset; int offset;
for (y = 0; y < src_height; ++y) { for (y = 0; y < src_height; ++y) {
const int yx = y * src_width; const int yx = y * src_width;
offset = yx * COM_NUMBER_OF_CHANNELS + chan; offset = yx * num_channels + chan;
for (x = 0; x < src_width; ++x) { for (x = 0; x < src_width; ++x) {
X[x] = buffer[offset]; X[x] = buffer[offset];
offset += COM_NUMBER_OF_CHANNELS; offset += num_channels;
} }
YVV(src_width); YVV(src_width);
offset = yx * COM_NUMBER_OF_CHANNELS + chan; offset = yx * num_channels + chan;
for (x = 0; x < src_width; ++x) { for (x = 0; x < src_width; ++x) {
buffer[offset] = Y[x]; buffer[offset] = Y[x];
offset += COM_NUMBER_OF_CHANNELS; offset += num_channels;
} }
} }
} }
if (xy & 2) { // V if (xy & 2) { // V
int offset; int offset;
const int add = src_width * COM_NUMBER_OF_CHANNELS; const int add = src_width * num_channels;
for (x = 0; x < src_width; ++x) { for (x = 0; x < src_width; ++x) {
offset = x * COM_NUMBER_OF_CHANNELS + chan; offset = x * num_channels + chan;
for (y = 0; y < src_height; ++y) { for (y = 0; y < src_height; ++y) {
X[y] = buffer[offset]; X[y] = buffer[offset];
offset += add; offset += add;
} }
YVV(src_height); YVV(src_height);
offset = x * COM_NUMBER_OF_CHANNELS + chan; offset = x * num_channels + chan;
for (y = 0; y < src_height; ++y) { for (y = 0; y < src_height; ++y) {
buffer[offset] = Y[y]; buffer[offset] = Y[y];
offset += add; offset += add;
@ -298,7 +299,7 @@ void *FastGaussianBlurValueOperation::initializeTileData(rcti *rect)
if (this->m_overlay == FAST_GAUSS_OVERLAY_MIN) { if (this->m_overlay == FAST_GAUSS_OVERLAY_MIN) {
float *src = newBuf->getBuffer(); float *src = newBuf->getBuffer();
float *dst = copy->getBuffer(); float *dst = copy->getBuffer();
for (int i = copy->getWidth() * copy->getHeight(); i != 0; i--, src += COM_NUMBER_OF_CHANNELS, dst += COM_NUMBER_OF_CHANNELS) { for (int i = copy->getWidth() * copy->getHeight(); i != 0; i--, src += COM_NUM_CHANNELS_VALUE, dst += COM_NUM_CHANNELS_VALUE) {
if (*src < *dst) { if (*src < *dst) {
*dst = *src; *dst = *src;
} }
@ -307,7 +308,7 @@ void *FastGaussianBlurValueOperation::initializeTileData(rcti *rect)
else if (this->m_overlay == FAST_GAUSS_OVERLAY_MAX) { else if (this->m_overlay == FAST_GAUSS_OVERLAY_MAX) {
float *src = newBuf->getBuffer(); float *src = newBuf->getBuffer();
float *dst = copy->getBuffer(); float *dst = copy->getBuffer();
for (int i = copy->getWidth() * copy->getHeight(); i != 0; i--, src += COM_NUMBER_OF_CHANNELS, dst += COM_NUMBER_OF_CHANNELS) { for (int i = copy->getWidth() * copy->getHeight(); i != 0; i--, src += COM_NUM_CHANNELS_VALUE, dst += COM_NUM_CHANNELS_VALUE) {
if (*src > *dst) { if (*src > *dst) {
*dst = *src; *dst = *src;
} }

@ -102,15 +102,14 @@ void GaussianAlphaXBlurOperation::executePixel(float output[4], int x, int y, vo
/* *** this is the main part which is different to 'GaussianXBlurOperation' *** */ /* *** this is the main part which is different to 'GaussianXBlurOperation' *** */
int step = getStep(); int step = getStep();
int offsetadd = getOffsetAdd(); int bufferindex = ((xmin - bufferstartx)) + ((ymin - bufferstarty) * bufferwidth);
int bufferindex = ((xmin - bufferstartx) * 4) + ((ymin - bufferstarty) * 4 * bufferwidth);
/* gauss */ /* gauss */
float alpha_accum = 0.0f; float alpha_accum = 0.0f;
float multiplier_accum = 0.0f; float multiplier_accum = 0.0f;
/* dilate */ /* dilate */
float value_max = finv_test(buffer[(x * 4) + (y * 4 * bufferwidth)], do_invert); /* init with the current color to avoid unneeded lookups */ float value_max = finv_test(buffer[(x) + (y * bufferwidth)], do_invert); /* init with the current color to avoid unneeded lookups */
float distfacinv_max = 1.0f; /* 0 to 1 */ float distfacinv_max = 1.0f; /* 0 to 1 */
for (int nx = xmin; nx < xmax; nx += step) { for (int nx = xmin; nx < xmax; nx += step) {
@ -134,7 +133,7 @@ void GaussianAlphaXBlurOperation::executePixel(float output[4], int x, int y, vo
distfacinv_max = multiplier; distfacinv_max = multiplier;
} }
} }
bufferindex += offsetadd; bufferindex += step;
} }
/* blend between the max value and gauss blue - gives nice feather */ /* blend between the max value and gauss blue - gives nice feather */

@ -108,11 +108,11 @@ void GaussianAlphaYBlurOperation::executePixel(float output[4], int x, int y, vo
float multiplier_accum = 0.0f; float multiplier_accum = 0.0f;
/* dilate */ /* dilate */
float value_max = finv_test(buffer[(x * 4) + (y * 4 * bufferwidth)], do_invert); /* init with the current color to avoid unneeded lookups */ float value_max = finv_test(buffer[(x) + (y * bufferwidth)], do_invert); /* init with the current color to avoid unneeded lookups */
float distfacinv_max = 1.0f; /* 0 to 1 */ float distfacinv_max = 1.0f; /* 0 to 1 */
for (int ny = ymin; ny < ymax; ny += step) { for (int ny = ymin; ny < ymax; ny += step) {
int bufferindex = ((xmin - bufferstartx) * 4) + ((ny - bufferstarty) * 4 * bufferwidth); int bufferindex = ((xmin - bufferstartx)) + ((ny - bufferstarty) * bufferwidth);
const int index = (ny - y) + this->m_filtersize; const int index = (ny - y) + this->m_filtersize;
float value = finv_test(buffer[bufferindex], do_invert); float value = finv_test(buffer[bufferindex], do_invert);

@ -296,7 +296,7 @@ void GaussianBlurReferenceOperation::executePixel(float output[4], int x, int y,
int minyr = y - refrady < 0 ? -y : -refrady; int minyr = y - refrady < 0 ? -y : -refrady;
int maxyr = y + refrady > imgy ? imgy - y : refrady; int maxyr = y + refrady > imgy ? imgy - y : refrady;
float *srcd = buffer + COM_NUMBER_OF_CHANNELS * ( (y + minyr) * imgx + x + minxr); float *srcd = buffer + COM_NUM_CHANNELS_COLOR * ( (y + minyr) * imgx + x + minxr);
gausstabx = m_maintabs[refradx - 1]; gausstabx = m_maintabs[refradx - 1];
gausstabcentx = gausstabx + refradx; gausstabcentx = gausstabx + refradx;
@ -304,9 +304,9 @@ void GaussianBlurReferenceOperation::executePixel(float output[4], int x, int y,
gausstabcenty = gausstaby + refrady; gausstabcenty = gausstaby + refrady;
sum = gval = rval = bval = aval = 0.0f; sum = gval = rval = bval = aval = 0.0f;
for (i = minyr; i < maxyr; i++, srcd += COM_NUMBER_OF_CHANNELS * imgx) { for (i = minyr; i < maxyr; i++, srcd += COM_NUM_CHANNELS_COLOR * imgx) {
src = srcd; src = srcd;
for (j = minxr; j < maxxr; j++, src += COM_NUMBER_OF_CHANNELS) { for (j = minxr; j < maxxr; j++, src += COM_NUM_CHANNELS_COLOR) {
val = gausstabcenty[i] * gausstabcentx[j]; val = gausstabcenty[i] * gausstabcentx[j];
sum += val; sum += val;

@ -49,7 +49,7 @@ MemoryBuffer *GlareBaseOperation::createMemoryBuffer(rcti *rect2)
rect.ymin = 0; rect.ymin = 0;
rect.xmax = getWidth(); rect.xmax = getWidth();
rect.ymax = getHeight(); rect.ymax = getHeight();
MemoryBuffer *result = new MemoryBuffer(NULL, &rect); MemoryBuffer *result = new MemoryBuffer(COM_DT_COLOR, &rect);
float *data = result->getBuffer(); float *data = result->getBuffer();
this->generateGlare(data, tile, this->m_settings); this->generateGlare(data, tile, this->m_settings);
return result; return result;

@ -259,8 +259,8 @@ static void convolve(float *dst, MemoryBuffer *in1, MemoryBuffer *in2)
float *kernelBuffer = in2->getBuffer(); float *kernelBuffer = in2->getBuffer();
float *imageBuffer = in1->getBuffer(); float *imageBuffer = in1->getBuffer();
MemoryBuffer *rdst = new MemoryBuffer(NULL, in1->getRect()); MemoryBuffer *rdst = new MemoryBuffer(COM_DT_COLOR, in1->getRect());
memset(rdst->getBuffer(), 0, rdst->getWidth() * rdst->getHeight() * COM_NUMBER_OF_CHANNELS * sizeof(float)); memset(rdst->getBuffer(), 0, rdst->getWidth() * rdst->getHeight() * COM_NUM_CHANNELS_COLOR * sizeof(float));
// convolution result width & height // convolution result width & height
w2 = 2 * kernelWidth - 1; w2 = 2 * kernelWidth - 1;
@ -276,7 +276,7 @@ static void convolve(float *dst, MemoryBuffer *in1, MemoryBuffer *in2)
// normalize convolutor // normalize convolutor
wt[0] = wt[1] = wt[2] = 0.f; wt[0] = wt[1] = wt[2] = 0.f;
for (y = 0; y < kernelHeight; y++) { for (y = 0; y < kernelHeight; y++) {
colp = (fRGB *)&kernelBuffer[y * kernelWidth * COM_NUMBER_OF_CHANNELS]; colp = (fRGB *)&kernelBuffer[y * kernelWidth * COM_NUM_CHANNELS_COLOR];
for (x = 0; x < kernelWidth; x++) for (x = 0; x < kernelWidth; x++)
add_v3_v3(wt, colp[x]); add_v3_v3(wt, colp[x]);
} }
@ -284,7 +284,7 @@ static void convolve(float *dst, MemoryBuffer *in1, MemoryBuffer *in2)
if (wt[1] != 0.f) wt[1] = 1.f / wt[1]; if (wt[1] != 0.f) wt[1] = 1.f / wt[1];
if (wt[2] != 0.f) wt[2] = 1.f / wt[2]; if (wt[2] != 0.f) wt[2] = 1.f / wt[2];
for (y = 0; y < kernelHeight; y++) { for (y = 0; y < kernelHeight; y++) {
colp = (fRGB *)&kernelBuffer[y * kernelWidth * COM_NUMBER_OF_CHANNELS]; colp = (fRGB *)&kernelBuffer[y * kernelWidth * COM_NUM_CHANNELS_COLOR];
for (x = 0; x < kernelWidth; x++) for (x = 0; x < kernelWidth; x++)
mul_v3_v3(colp[x], wt); mul_v3_v3(colp[x], wt);
} }
@ -313,7 +313,7 @@ static void convolve(float *dst, MemoryBuffer *in1, MemoryBuffer *in2)
// in2, channel ch -> data1 // in2, channel ch -> data1
for (y = 0; y < kernelHeight; y++) { for (y = 0; y < kernelHeight; y++) {
fp = &data1ch[y * w2]; fp = &data1ch[y * w2];
colp = (fRGB *)&kernelBuffer[y * kernelWidth * COM_NUMBER_OF_CHANNELS]; colp = (fRGB *)&kernelBuffer[y * kernelWidth * COM_NUM_CHANNELS_COLOR];
for (x = 0; x < kernelWidth; x++) for (x = 0; x < kernelWidth; x++)
fp[x] = colp[x][ch]; fp[x] = colp[x][ch];
} }
@ -325,7 +325,7 @@ static void convolve(float *dst, MemoryBuffer *in1, MemoryBuffer *in2)
int yy = ybl * ybsz + y; int yy = ybl * ybsz + y;
if (yy >= imageHeight) continue; if (yy >= imageHeight) continue;
fp = &data2[y * w2]; fp = &data2[y * w2];
colp = (fRGB *)&imageBuffer[yy * imageWidth * COM_NUMBER_OF_CHANNELS]; colp = (fRGB *)&imageBuffer[yy * imageWidth * COM_NUM_CHANNELS_COLOR];
for (x = 0; x < xbsz; x++) { for (x = 0; x < xbsz; x++) {
int xx = xbl * xbsz + x; int xx = xbl * xbsz + x;
if (xx >= imageWidth) continue; if (xx >= imageWidth) continue;
@ -349,7 +349,7 @@ static void convolve(float *dst, MemoryBuffer *in1, MemoryBuffer *in2)
const int yy = ybl * ybsz + y - hh; const int yy = ybl * ybsz + y - hh;
if ((yy < 0) || (yy >= imageHeight)) continue; if ((yy < 0) || (yy >= imageHeight)) continue;
fp = &data2[y * w2]; fp = &data2[y * w2];
colp = (fRGB *)&rdst->getBuffer()[yy * imageWidth * COM_NUMBER_OF_CHANNELS]; colp = (fRGB *)&rdst->getBuffer()[yy * imageWidth * COM_NUM_CHANNELS_COLOR];
for (x = 0; x < (int)w2; x++) { for (x = 0; x < (int)w2; x++) {
const int xx = xbl * xbsz + x - hw; const int xx = xbl * xbsz + x - hw;
if ((xx < 0) || (xx >= imageWidth)) continue; if ((xx < 0) || (xx >= imageWidth)) continue;
@ -364,7 +364,7 @@ static void convolve(float *dst, MemoryBuffer *in1, MemoryBuffer *in2)
MEM_freeN(data2); MEM_freeN(data2);
MEM_freeN(data1); MEM_freeN(data1);
memcpy(dst, rdst->getBuffer(), sizeof(float) * imageWidth * imageHeight * COM_NUMBER_OF_CHANNELS); memcpy(dst, rdst->getBuffer(), sizeof(float) * imageWidth * imageHeight * COM_NUM_CHANNELS_COLOR);
delete(rdst); delete(rdst);
} }
@ -381,7 +381,7 @@ void GlareFogGlowOperation::generateGlare(float *data, MemoryBuffer *inputTile,
// make the convolution kernel // make the convolution kernel
rcti kernelRect; rcti kernelRect;
BLI_rcti_init(&kernelRect, 0, sz, 0, sz); BLI_rcti_init(&kernelRect, 0, sz, 0, sz);
ckrn = new MemoryBuffer(NULL, &kernelRect); ckrn = new MemoryBuffer(COM_DT_COLOR, &kernelRect);
scale = 0.25f * sqrtf((float)(sz * sz)); scale = 0.25f * sqrtf((float)(sz * sz));

@ -97,7 +97,7 @@ void GlareGhostOperation::generateGlare(float *data, MemoryBuffer *inputTile, No
} }
memset(tbuf1->getBuffer(), 0, tbuf1->getWidth() * tbuf1->getHeight() * COM_NUMBER_OF_CHANNELS * sizeof(float)); memset(tbuf1->getBuffer(), 0, tbuf1->getWidth() * tbuf1->getHeight() * COM_NUM_CHANNELS_COLOR * sizeof(float));
for (n = 1; n < settings->iter && (!breaked); n++) { for (n = 1; n < settings->iter && (!breaked); n++) {
for (y = 0; y < gbuf->getHeight() && (!breaked); y++) { for (y = 0; y < gbuf->getHeight() && (!breaked); y++) {
v = ((float)y + 0.5f) / (float)gbuf->getHeight(); v = ((float)y + 0.5f) / (float)gbuf->getHeight();
@ -117,9 +117,9 @@ void GlareGhostOperation::generateGlare(float *data, MemoryBuffer *inputTile, No
} }
if (isBreaked()) breaked = true; if (isBreaked()) breaked = true;
} }
memcpy(gbuf->getBuffer(), tbuf1->getBuffer(), tbuf1->getWidth() * tbuf1->getHeight() * COM_NUMBER_OF_CHANNELS * sizeof(float)); memcpy(gbuf->getBuffer(), tbuf1->getBuffer(), tbuf1->getWidth() * tbuf1->getHeight() * COM_NUM_CHANNELS_COLOR * sizeof(float));
} }
memcpy(data, gbuf->getBuffer(), gbuf->getWidth() * gbuf->getHeight() * COM_NUMBER_OF_CHANNELS * sizeof(float)); memcpy(data, gbuf->getBuffer(), gbuf->getWidth() * gbuf->getHeight() * COM_NUM_CHANNELS_COLOR * sizeof(float));
delete gbuf; delete gbuf;
delete tbuf1; delete tbuf1;

@ -36,7 +36,7 @@ void GlareStreaksOperation::generateGlare(float *data, MemoryBuffer *inputTile,
bool breaked = false; bool breaked = false;
MemoryBuffer *tsrc = inputTile->duplicate(); MemoryBuffer *tsrc = inputTile->duplicate();
MemoryBuffer *tdst = new MemoryBuffer(NULL, inputTile->getRect()); MemoryBuffer *tdst = new MemoryBuffer(COM_DT_COLOR, inputTile->getRect());
tdst->clear(); tdst->clear();
memset(data, 0, size4 * sizeof(float)); memset(data, 0, size4 * sizeof(float));

@ -83,8 +83,8 @@ float *InpaintSimpleOperation::get_pixel(int x, int y)
ASSERT_XY_RANGE(x, y); ASSERT_XY_RANGE(x, y);
return &this->m_cached_buffer[ return &this->m_cached_buffer[
y * width * COM_NUMBER_OF_CHANNELS + y * width * COM_NUM_CHANNELS_COLOR +
x * COM_NUMBER_OF_CHANNELS]; x * COM_NUM_CHANNELS_COLOR];
} }
int InpaintSimpleOperation::mdist(int x, int y) int InpaintSimpleOperation::mdist(int x, int y)

@ -58,7 +58,7 @@ void KeyingBlurOperation::executePixel(float output[4], int x, int y, void *data
const int start = max(0, x - this->m_size + 1), const int start = max(0, x - this->m_size + 1),
end = min(bufferWidth, x + this->m_size); end = min(bufferWidth, x + this->m_size);
for (int cx = start; cx < end; ++cx) { for (int cx = start; cx < end; ++cx) {
int bufferIndex = (y * bufferWidth + cx) * 4; int bufferIndex = (y * bufferWidth + cx);
average += buffer[bufferIndex]; average += buffer[bufferIndex];
count++; count++;
} }
@ -67,7 +67,7 @@ void KeyingBlurOperation::executePixel(float output[4], int x, int y, void *data
const int start = max(0, y - this->m_size + 1), const int start = max(0, y - this->m_size + 1),
end = min(inputBuffer->getHeight(), y + this->m_size); end = min(inputBuffer->getHeight(), y + this->m_size);
for (int cy = start; cy < end; ++cy) { for (int cy = start; cy < end; ++cy) {
int bufferIndex = (cy * bufferWidth + x) * 4; int bufferIndex = (cy * bufferWidth + x);
average += buffer[bufferIndex]; average += buffer[bufferIndex];
count++; count++;
} }

@ -62,7 +62,7 @@ void KeyingClipOperation::executePixel(float output[4], int x, int y, void *data
int bufferWidth = inputBuffer->getWidth(); int bufferWidth = inputBuffer->getWidth();
int bufferHeight = inputBuffer->getHeight(); int bufferHeight = inputBuffer->getHeight();
float value = buffer[(y * bufferWidth + x) * 4]; float value = buffer[(y * bufferWidth + x)];
bool ok = false; bool ok = false;
int start_x = max_ff(0, x - delta + 1), int start_x = max_ff(0, x - delta + 1),
@ -83,7 +83,7 @@ void KeyingClipOperation::executePixel(float output[4], int x, int y, void *data
continue; continue;
} }
int bufferIndex = (cy * bufferWidth + cx) * 4; int bufferIndex = (cy * bufferWidth + cx);
float currentValue = buffer[bufferIndex]; float currentValue = buffer[bufferIndex];
if (fabsf(currentValue - value) < tolerance) { if (fabsf(currentValue - value) < tolerance) {

@ -83,11 +83,11 @@ bool MapUVOperation::read_uv(float x, float y, float &r_u, float &r_v, float &r_
return false; return false;
} }
else { else {
float col[4]; float vector[3];
m_inputUVProgram->readSampled(col, x, y, COM_PS_BILINEAR); m_inputUVProgram->readSampled(vector, x, y, COM_PS_BILINEAR);
r_u = col[0] * m_inputColorProgram->getWidth(); r_u = vector[0] * m_inputColorProgram->getWidth();
r_v = col[1] * m_inputColorProgram->getHeight(); r_v = vector[1] * m_inputColorProgram->getHeight();
r_alpha = col[2]; r_alpha = vector[2];
return true; return true;
} }
} }

@ -104,7 +104,7 @@ void *NormalizeOperation::initializeTileData(rcti *rect)
if ((value < minv) && (value >= -BLENDER_ZMAX)) { if ((value < minv) && (value >= -BLENDER_ZMAX)) {
minv = value; minv = value;
} }
bc += 4; bc ++;
} }
minmult->x = minv; minmult->x = minv;

@ -37,15 +37,15 @@ void QualityStepHelper::initExecution(QualityHelper helper)
case COM_QUALITY_HIGH: case COM_QUALITY_HIGH:
default: default:
this->m_step = 1; this->m_step = 1;
this->m_offsetadd = 4; this->m_offsetadd = 1;
break; break;
case COM_QUALITY_MEDIUM: case COM_QUALITY_MEDIUM:
this->m_step = 2; this->m_step = 2;
this->m_offsetadd = 8; this->m_offsetadd = 2;
break; break;
case COM_QUALITY_LOW: case COM_QUALITY_LOW:
this->m_step = 3; this->m_step = 3;
this->m_offsetadd = 12; this->m_offsetadd = 3;
break; break;
} }
break; break;

@ -24,9 +24,9 @@
#include "COM_WriteBufferOperation.h" #include "COM_WriteBufferOperation.h"
#include "COM_defines.h" #include "COM_defines.h"
ReadBufferOperation::ReadBufferOperation() : NodeOperation() ReadBufferOperation::ReadBufferOperation(DataType datatype) : NodeOperation()
{ {
this->addOutputSocket(COM_DT_COLOR); this->addOutputSocket(datatype);
this->m_single_value = false; this->m_single_value = false;
this->m_offset = 0; this->m_offset = 0;
this->m_buffer = NULL; this->m_buffer = NULL;
@ -58,11 +58,20 @@ void ReadBufferOperation::executePixelSampled(float output[4], float x, float y,
/* write buffer has a single value stored at (0,0) */ /* write buffer has a single value stored at (0,0) */
m_buffer->read(output, 0, 0); m_buffer->read(output, 0, 0);
} }
else if (sampler == COM_PS_NEAREST) {
m_buffer->read(output, x, y);
}
else { else {
m_buffer->readBilinear(output, x, y); switch (sampler) {
case COM_PS_NEAREST:
m_buffer->read(output, x, y);
break;
case COM_PS_BILINEAR:
default:
m_buffer->readBilinear(output, x, y);
break;
case COM_PS_BICUBIC:
m_buffer->readBilinear(output, x, y);
break;
}
} }
} }

@ -25,6 +25,7 @@
#include "COM_NodeOperation.h" #include "COM_NodeOperation.h"
#include "COM_MemoryProxy.h" #include "COM_MemoryProxy.h"
#include "COM_MemoryBuffer.h"
class ReadBufferOperation : public NodeOperation { class ReadBufferOperation : public NodeOperation {
private: private:
@ -33,7 +34,7 @@ private:
unsigned int m_offset; unsigned int m_offset;
MemoryBuffer *m_buffer; MemoryBuffer *m_buffer;
public: public:
ReadBufferOperation(); ReadBufferOperation(DataType datetype);
void setMemoryProxy(MemoryProxy *memoryProxy) { this->m_memoryProxy = memoryProxy; } void setMemoryProxy(MemoryProxy *memoryProxy) { this->m_memoryProxy = memoryProxy; }
MemoryProxy *getMemoryProxy() { return this->m_memoryProxy; } MemoryProxy *getMemoryProxy() { return this->m_memoryProxy; }
void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]); void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]);

@ -111,15 +111,6 @@ void RenderLayersBaseProg::doInterpolation(float output[4], float x, float y, Pi
BLI_bicubic_interpolation_fl(this->m_inputBuffer, output, width, height, this->m_elementsize, x, y); BLI_bicubic_interpolation_fl(this->m_inputBuffer, output, width, height, this->m_elementsize, x, y);
break; break;
} }
if (this->m_elementsize == 1) {
output[1] = 0.0f;
output[2] = 0.0f;
output[3] = 0.0f;
}
else if (this->m_elementsize == 3) {
output[3] = 1.0f;
}
} }
void RenderLayersBaseProg::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) void RenderLayersBaseProg::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
@ -145,7 +136,16 @@ void RenderLayersBaseProg::executePixelSampled(float output[4], float x, float y
#endif #endif
if (this->m_inputBuffer == NULL) { if (this->m_inputBuffer == NULL) {
zero_v4(output); int elemsize = this->m_elementsize;
if (elemsize == 1) {
output[0] = 0.0f;
}
else if (elemsize == 3) {
zero_v3(output);
} else {
BLI_assert(elemsize == 4);
zero_v4(output);
}
} }
else { else {
doInterpolation(output, x, y, sampler); doInterpolation(output, x, y, sampler);
@ -204,15 +204,12 @@ void RenderLayersAlphaProg::executePixelSampled(float output[4], float x, float
float *inputBuffer = this->getInputBuffer(); float *inputBuffer = this->getInputBuffer();
if (inputBuffer == NULL) { if (inputBuffer == NULL) {
zero_v4(output); output[0] = 0.0f;
} }
else { else {
float temp[4]; float temp[4];
doInterpolation(temp, x, y, sampler); doInterpolation(temp, x, y, sampler);
output[0] = temp[3]; output[0] = temp[3];
output[1] = 0.0f;
output[2] = 0.0f;
output[3] = 0.0f;
} }
} }
@ -227,7 +224,7 @@ RenderLayersColorOperation::RenderLayersColorOperation() : RenderLayersBaseProg(
RenderLayersCyclesOperation::RenderLayersCyclesOperation(int pass) : RenderLayersBaseProg(pass, 3) RenderLayersCyclesOperation::RenderLayersCyclesOperation(int pass) : RenderLayersBaseProg(pass, 3)
{ {
this->addOutputSocket(COM_DT_COLOR); this->addOutputSocket(COM_DT_VECTOR);
} }
/* ******** Render Layers Depth Operation ******** */ /* ******** Render Layers Depth Operation ******** */
@ -245,16 +242,10 @@ void RenderLayersDepthProg::executePixelSampled(float output[4], float x, float
if (inputBuffer == NULL || ix < 0 || iy < 0 || ix >= (int)this->getWidth() || iy >= (int)this->getHeight() ) { if (inputBuffer == NULL || ix < 0 || iy < 0 || ix >= (int)this->getWidth() || iy >= (int)this->getHeight() ) {
output[0] = 0.0f; output[0] = 0.0f;
output[1] = 0.0f;
output[2] = 0.0f;
output[3] = 0.0f;
} }
else { else {
unsigned int offset = (iy * this->getWidth() + ix); unsigned int offset = (iy * this->getWidth() + ix);
output[0] = inputBuffer[offset]; output[0] = inputBuffer[offset];
output[1] = 0.0f;
output[2] = 0.0f;
output[3] = 0.0f;
} }
} }
@ -262,21 +253,21 @@ void RenderLayersDepthProg::executePixelSampled(float output[4], float x, float
RenderLayersDiffuseOperation::RenderLayersDiffuseOperation() : RenderLayersBaseProg(SCE_PASS_DIFFUSE, 3) RenderLayersDiffuseOperation::RenderLayersDiffuseOperation() : RenderLayersBaseProg(SCE_PASS_DIFFUSE, 3)
{ {
this->addOutputSocket(COM_DT_COLOR); this->addOutputSocket(COM_DT_VECTOR);
} }
/* ******** Render Layers Emit Operation ******** */ /* ******** Render Layers Emit Operation ******** */
RenderLayersEmitOperation::RenderLayersEmitOperation() : RenderLayersBaseProg(SCE_PASS_EMIT, 3) RenderLayersEmitOperation::RenderLayersEmitOperation() : RenderLayersBaseProg(SCE_PASS_EMIT, 3)
{ {
this->addOutputSocket(COM_DT_COLOR); this->addOutputSocket(COM_DT_VECTOR);
} }
/* ******** Render Layers Environment Operation ******** */ /* ******** Render Layers Environment Operation ******** */
RenderLayersEnvironmentOperation::RenderLayersEnvironmentOperation() : RenderLayersBaseProg(SCE_PASS_ENVIRONMENT, 3) RenderLayersEnvironmentOperation::RenderLayersEnvironmentOperation() : RenderLayersBaseProg(SCE_PASS_ENVIRONMENT, 3)
{ {
this->addOutputSocket(COM_DT_COLOR); this->addOutputSocket(COM_DT_VECTOR);
} }
/* ******** Render Layers Image Operation ******** */ /* ******** Render Layers Image Operation ******** */
@ -290,7 +281,7 @@ RenderLayersColorProg::RenderLayersColorProg() : RenderLayersBaseProg(SCE_PASS_C
RenderLayersIndirectOperation::RenderLayersIndirectOperation() : RenderLayersBaseProg(SCE_PASS_INDIRECT, 3) RenderLayersIndirectOperation::RenderLayersIndirectOperation() : RenderLayersBaseProg(SCE_PASS_INDIRECT, 3)
{ {
this->addOutputSocket(COM_DT_COLOR); this->addOutputSocket(COM_DT_VECTOR);
} }
/* ******** Render Layers Material Index Operation ******** */ /* ******** Render Layers Material Index Operation ******** */
@ -325,28 +316,28 @@ RenderLayersObjectIndexOperation::RenderLayersObjectIndexOperation() : RenderLay
RenderLayersReflectionOperation::RenderLayersReflectionOperation() : RenderLayersBaseProg(SCE_PASS_REFLECT, 3) RenderLayersReflectionOperation::RenderLayersReflectionOperation() : RenderLayersBaseProg(SCE_PASS_REFLECT, 3)
{ {
this->addOutputSocket(COM_DT_COLOR); this->addOutputSocket(COM_DT_VECTOR);
} }
/* ******** Render Layers Refraction Operation ******** */ /* ******** Render Layers Refraction Operation ******** */
RenderLayersRefractionOperation::RenderLayersRefractionOperation() : RenderLayersBaseProg(SCE_PASS_REFRACT, 3) RenderLayersRefractionOperation::RenderLayersRefractionOperation() : RenderLayersBaseProg(SCE_PASS_REFRACT, 3)
{ {
this->addOutputSocket(COM_DT_COLOR); this->addOutputSocket(COM_DT_VECTOR);
} }
/* ******** Render Layers Shadow Operation ******** */ /* ******** Render Layers Shadow Operation ******** */
RenderLayersShadowOperation::RenderLayersShadowOperation() : RenderLayersBaseProg(SCE_PASS_SHADOW, 3) RenderLayersShadowOperation::RenderLayersShadowOperation() : RenderLayersBaseProg(SCE_PASS_SHADOW, 3)
{ {
this->addOutputSocket(COM_DT_COLOR); this->addOutputSocket(COM_DT_VECTOR);
} }
/* ******** Render Layers Specular Operation ******** */ /* ******** Render Layers Specular Operation ******** */
RenderLayersSpecularOperation::RenderLayersSpecularOperation() : RenderLayersBaseProg(SCE_PASS_SPEC, 3) RenderLayersSpecularOperation::RenderLayersSpecularOperation() : RenderLayersBaseProg(SCE_PASS_SPEC, 3)
{ {
this->addOutputSocket(COM_DT_COLOR); this->addOutputSocket(COM_DT_VECTOR);
} }
/* ******** Render Layers Speed Operation ******** */ /* ******** Render Layers Speed Operation ******** */

@ -33,7 +33,6 @@ void SetVectorOperation::executePixelSampled(float output[4], float x, float y,
output[0] = this->m_x; output[0] = this->m_x;
output[1] = this->m_y; output[1] = this->m_y;
output[2] = this->m_z; output[2] = this->m_z;
output[3] = this->m_w;
} }
void SetVectorOperation::determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]) void SetVectorOperation::determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2])

@ -135,7 +135,7 @@ struct BufferLineAccumulator {
falloff_factor = dist_max > dist_min ? dr / (float)(dist_max - dist_min) : 0.0f; falloff_factor = dist_max > dist_min ? dr / (float)(dist_max - dist_min) : 0.0f;
float *iter = input->getBuffer() + COM_NUMBER_OF_CHANNELS * (x + input->getWidth() * y); float *iter = input->getBuffer() + COM_NUM_CHANNELS_COLOR * (x + input->getWidth() * y);
return iter; return iter;
} }
@ -159,7 +159,7 @@ struct BufferLineAccumulator {
zero_v4(output); zero_v4(output);
if ((int)(co[0] - source[0]) == 0 && (int)(co[1] - source[1]) == 0) { if ((int)(co[0] - source[0]) == 0 && (int)(co[1] - source[1]) == 0) {
copy_v4_v4(output, input->getBuffer() + COM_NUMBER_OF_CHANNELS * ((int)source[0] + input->getWidth() * (int)source[1])); copy_v4_v4(output, input->getBuffer() + COM_NUM_CHANNELS_COLOR * ((int)source[0] + input->getWidth() * (int)source[1]));
return; return;
} }
@ -198,7 +198,7 @@ struct BufferLineAccumulator {
/* decrement u */ /* decrement u */
x -= fxu; x -= fxu;
y -= fyu; y -= fyu;
buffer -= (fxu + fyu * buffer_width) * COM_NUMBER_OF_CHANNELS; buffer -= (fxu + fyu * buffer_width) * COM_NUM_CHANNELS_COLOR;
/* decrement v (in steps of dv < 1) */ /* decrement v (in steps of dv < 1) */
v_local -= dv; v_local -= dv;
@ -207,7 +207,7 @@ struct BufferLineAccumulator {
x -= fxv; x -= fxv;
y -= fyv; y -= fyv;
buffer -= (fxv + fyv * buffer_width) * COM_NUMBER_OF_CHANNELS; buffer -= (fxv + fyv * buffer_width) * COM_NUM_CHANNELS_COLOR;
} }
} }

@ -77,12 +77,9 @@ void TextureBaseOperation::determineResolution(unsigned int resolution[2], unsig
void TextureAlphaOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) void TextureAlphaOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
{ {
TextureBaseOperation::executePixelSampled(output, x, y, sampler); float color[4];
output[0] = output[3]; TextureBaseOperation::executePixelSampled(color, x, y, sampler);
output[1] = 0.0f; output[0] = color[3];}
output[2] = 0.0f;
output[3] = 0.0f;
}
void TextureBaseOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler) void TextureBaseOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
{ {
@ -124,18 +121,23 @@ MemoryBuffer *TextureBaseOperation::createMemoryBuffer(rcti *rect2)
{ {
int height = getHeight(); int height = getHeight();
int width = getWidth(); int width = getWidth();
DataType datatype = this->getOutputSocket()->getDataType();
int add = 4;
if (datatype == COM_DT_VALUE) {
add = 1;
}
rcti rect; rcti rect;
rect.xmin = 0; rect.xmin = 0;
rect.ymin = 0; rect.ymin = 0;
rect.xmax = width; rect.xmax = width;
rect.ymax = height; rect.ymax = height;
MemoryBuffer *result = new MemoryBuffer(NULL, &rect); MemoryBuffer *result = new MemoryBuffer(datatype, &rect);
float *data = result->getBuffer(); float *data = result->getBuffer();
for (int y = 0; y < height; y++) { for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++, data += 4) { for (int x = 0; x < width; x++, data += add) {
this->executePixelSampled(data, x, y, COM_PS_NEAREST); this->executePixelSampled(data, x, y, COM_PS_NEAREST);
} }
} }

@ -137,30 +137,33 @@ void VariableSizeBokehBlurOperation::executePixel(float output[4], int x, int y,
copy_v4_fl(multiplier_accum, 1.0f); copy_v4_fl(multiplier_accum, 1.0f);
float size_center = tempSize[0] * scalar; float size_center = tempSize[0] * scalar;
const int addXStep = QualityStepHelper::getStep() * COM_NUMBER_OF_CHANNELS; const int addXStepValue = QualityStepHelper::getStep();
const int addYStepValue = addXStepValue;
const int addXStepColor = addXStepValue * COM_NUM_CHANNELS_COLOR;
if (size_center > this->m_threshold) { if (size_center > this->m_threshold) {
for (int ny = miny; ny < maxy; ny += QualityStepHelper::getStep()) { for (int ny = miny; ny < maxy; ny += addYStepValue) {
float dy = ny - y; float dy = ny - y;
int offsetNy = ny * inputSizeBuffer->getWidth() * COM_NUMBER_OF_CHANNELS; int offsetValueNy = ny * inputSizeBuffer->getWidth();
int offsetNxNy = offsetNy + (minx * COM_NUMBER_OF_CHANNELS); int offsetValueNxNy = offsetValueNy + (minx);
for (int nx = minx; nx < maxx; nx += QualityStepHelper::getStep()) { int offsetColorNxNy = offsetValueNxNy * COM_NUM_CHANNELS_COLOR;
for (int nx = minx; nx < maxx; nx += addXStepValue) {
if (nx != x || ny != y) { if (nx != x || ny != y) {
float size = min(inputSizeFloatBuffer[offsetNxNy] * scalar, size_center); float size = min(inputSizeFloatBuffer[offsetValueNxNy] * scalar, size_center);
if (size > this->m_threshold) { if (size > this->m_threshold) {
float dx = nx - x; float dx = nx - x;
if (size > fabsf(dx) && size > fabsf(dy)) { if (size > fabsf(dx) && size > fabsf(dy)) {
float uv[2] = { float uv[2] = {
(float)(COM_BLUR_BOKEH_PIXELS / 2) + (dx / size) * (float)((COM_BLUR_BOKEH_PIXELS / 2) - 1), (float)(COM_BLUR_BOKEH_PIXELS / 2) + (dx / size) * (float)((COM_BLUR_BOKEH_PIXELS / 2) - 1),
(float)(COM_BLUR_BOKEH_PIXELS / 2) + (dy / size) * (float)((COM_BLUR_BOKEH_PIXELS / 2) - 1)}; (float)(COM_BLUR_BOKEH_PIXELS / 2) + (dy / size) * (float)((COM_BLUR_BOKEH_PIXELS / 2) - 1)};
inputBokehBuffer->readNoCheck(bokeh, uv[0], uv[1]); inputBokehBuffer->read(bokeh, uv[0], uv[1]);
madd_v4_v4v4(color_accum, bokeh, &inputProgramFloatBuffer[offsetNxNy]); madd_v4_v4v4(color_accum, bokeh, &inputProgramFloatBuffer[offsetColorNxNy]);
add_v4_v4(multiplier_accum, bokeh); add_v4_v4(multiplier_accum, bokeh);
} }
} }
} }
offsetNxNy += addXStep; offsetColorNxNy += addXStepColor;
} offsetValueNxNy += addXStepValue; }
} }
} }

@ -57,7 +57,7 @@ void VectorBlurOperation::initExecution()
void VectorBlurOperation::executePixel(float output[4], int x, int y, void *data) void VectorBlurOperation::executePixel(float output[4], int x, int y, void *data)
{ {
float *buffer = (float *) data; float *buffer = (float *) data;
int index = (y * this->getWidth() + x) * COM_NUMBER_OF_CHANNELS; int index = (y * this->getWidth() + x) * COM_NUM_CHANNELS_COLOR;
copy_v4_v4(output, &buffer[index]); copy_v4_v4(output, &buffer[index]);
} }
@ -108,14 +108,12 @@ bool VectorBlurOperation::determineDependingAreaOfInterest(rcti *input, ReadBuff
void VectorBlurOperation::generateVectorBlur(float *data, MemoryBuffer *inputImage, MemoryBuffer *inputSpeed, MemoryBuffer *inputZ) void VectorBlurOperation::generateVectorBlur(float *data, MemoryBuffer *inputImage, MemoryBuffer *inputSpeed, MemoryBuffer *inputZ)
{ {
float *zbuf = inputZ->convertToValueBuffer();
NodeBlurData blurdata; NodeBlurData blurdata;
blurdata.samples = this->m_settings->samples / QualityStepHelper::getStep(); blurdata.samples = this->m_settings->samples / QualityStepHelper::getStep();
blurdata.maxspeed = this->m_settings->maxspeed; blurdata.maxspeed = this->m_settings->maxspeed;
blurdata.minspeed = this->m_settings->minspeed; blurdata.minspeed = this->m_settings->minspeed;
blurdata.curved = this->m_settings->curved; blurdata.curved = this->m_settings->curved;
blurdata.fac = this->m_settings->fac; blurdata.fac = this->m_settings->fac;
RE_zbuf_accumulate_vecblur(&blurdata, this->getWidth(), this->getHeight(), data, inputImage->getBuffer(), inputSpeed->getBuffer(), zbuf); RE_zbuf_accumulate_vecblur(&blurdata, this->getWidth(), this->getHeight(), data, inputImage->getBuffer(), inputSpeed->getBuffer(), inputZ->getBuffer());
MEM_freeN((void *)zbuf);
return; return;
} }

@ -51,7 +51,6 @@ void VectorCurveOperation::executePixelSampled(float output[4], float x, float y
this->m_inputProgram->readSampled(input, x, y, sampler); this->m_inputProgram->readSampled(input, x, y, sampler);
curvemapping_evaluate_premulRGBF(this->m_curveMapping, output, input); curvemapping_evaluate_premulRGBF(this->m_curveMapping, output, input);
output[3] = input[3];
} }
void VectorCurveOperation::deinitExecution() void VectorCurveOperation::deinitExecution()

@ -23,7 +23,7 @@
#include "COM_WrapOperation.h" #include "COM_WrapOperation.h"
WrapOperation::WrapOperation() : ReadBufferOperation() WrapOperation::WrapOperation(DataType datatype) : ReadBufferOperation(datatype)
{ {
this->m_wrappingType = CMP_NODE_WRAP_NONE; this->m_wrappingType = CMP_NODE_WRAP_NONE;
} }

@ -29,7 +29,7 @@ class WrapOperation : public ReadBufferOperation {
private: private:
int m_wrappingType; int m_wrappingType;
public: public:
WrapOperation(); WrapOperation(DataType datetype);
bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output);
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);

@ -25,10 +25,10 @@
#include <stdio.h> #include <stdio.h>
#include "COM_OpenCLDevice.h" #include "COM_OpenCLDevice.h"
WriteBufferOperation::WriteBufferOperation() : NodeOperation() WriteBufferOperation::WriteBufferOperation(DataType datatype) : NodeOperation()
{ {
this->addInputSocket(COM_DT_COLOR); this->addInputSocket(datatype);
this->m_memoryProxy = new MemoryProxy(); this->m_memoryProxy = new MemoryProxy(datatype);
this->m_memoryProxy->setWriteBufferOperation(this); this->m_memoryProxy->setWriteBufferOperation(this);
this->m_memoryProxy->setExecutor(NULL); this->m_memoryProxy->setExecutor(NULL);
} }
@ -61,6 +61,7 @@ void WriteBufferOperation::executeRegion(rcti *rect, unsigned int tileNumber)
{ {
MemoryBuffer *memoryBuffer = this->m_memoryProxy->getBuffer(); MemoryBuffer *memoryBuffer = this->m_memoryProxy->getBuffer();
float *buffer = memoryBuffer->getBuffer(); float *buffer = memoryBuffer->getBuffer();
const int num_channels = memoryBuffer->get_num_channels();
if (this->m_input->isComplex()) { if (this->m_input->isComplex()) {
void *data = this->m_input->initializeTileData(rect); void *data = this->m_input->initializeTileData(rect);
int x1 = rect->xmin; int x1 = rect->xmin;
@ -71,10 +72,10 @@ void WriteBufferOperation::executeRegion(rcti *rect, unsigned int tileNumber)
int y; int y;
bool breaked = false; bool breaked = false;
for (y = y1; y < y2 && (!breaked); y++) { for (y = y1; y < y2 && (!breaked); y++) {
int offset4 = (y * memoryBuffer->getWidth() + x1) * COM_NUMBER_OF_CHANNELS; int offset4 = (y * memoryBuffer->getWidth() + x1) * num_channels;
for (x = x1; x < x2; x++) { for (x = x1; x < x2; x++) {
this->m_input->read(&(buffer[offset4]), x, y, data); this->m_input->read(&(buffer[offset4]), x, y, data);
offset4 += COM_NUMBER_OF_CHANNELS; offset4 += num_channels;
} }
if (isBreaked()) { if (isBreaked()) {
breaked = true; breaked = true;
@ -96,10 +97,10 @@ void WriteBufferOperation::executeRegion(rcti *rect, unsigned int tileNumber)
int y; int y;
bool breaked = false; bool breaked = false;
for (y = y1; y < y2 && (!breaked); y++) { for (y = y1; y < y2 && (!breaked); y++) {
int offset4 = (y * memoryBuffer->getWidth() + x1) * COM_NUMBER_OF_CHANNELS; int offset4 = (y * memoryBuffer->getWidth() + x1) * num_channels;
for (x = x1; x < x2; x++) { for (x = x1; x < x2; x++) {
this->m_input->readSampled(&(buffer[offset4]), x, y, COM_PS_NEAREST); this->m_input->readSampled(&(buffer[offset4]), x, y, COM_PS_NEAREST);
offset4 += COM_NUMBER_OF_CHANNELS; offset4 += num_channels;
} }
if (isBreaked()) { if (isBreaked()) {
breaked = true; breaked = true;
@ -126,12 +127,9 @@ void WriteBufferOperation::executeOpenCLRegion(OpenCLDevice *device, rcti *rect,
const unsigned int outputBufferWidth = outputBuffer->getWidth(); const unsigned int outputBufferWidth = outputBuffer->getWidth();
const unsigned int outputBufferHeight = outputBuffer->getHeight(); const unsigned int outputBufferHeight = outputBuffer->getHeight();
const cl_image_format imageFormat = { const cl_image_format *imageFormat = device->determineImageFormat(outputBuffer);
CL_RGBA,
CL_FLOAT
};
cl_mem clOutputBuffer = clCreateImage2D(device->getContext(), CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR, &imageFormat, outputBufferWidth, outputBufferHeight, 0, outputFloatBuffer, &error); cl_mem clOutputBuffer = clCreateImage2D(device->getContext(), CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR, imageFormat, outputBufferWidth, outputBufferHeight, 0, outputFloatBuffer, &error);
if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); }
// STEP 2 // STEP 2

@ -35,7 +35,7 @@ class WriteBufferOperation : public NodeOperation {
bool m_single_value; /* single value stored in buffer */ bool m_single_value; /* single value stored in buffer */
NodeOperation *m_input; NodeOperation *m_input;
public: public:
WriteBufferOperation(); WriteBufferOperation(DataType datatype);
~WriteBufferOperation(); ~WriteBufferOperation();
MemoryProxy *getMemoryProxy() { return this->m_memoryProxy; } MemoryProxy *getMemoryProxy() { return this->m_memoryProxy; }
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);