1
1

Compare commits

...

5 Commits

Author SHA1 Message Date
5fcc889baa Merge branch 'blender-tiles' of gitorious.org:blender-tiles/blender-tiles into blender-tiles
Conflicts:
	source/blender/blenlib/BLI_compiler_compat.h
	source/blender/compositor/CMakeLists.txt
	source/blender/compositor/intern/COM_ChannelInfo.h
	source/blender/compositor/intern/COM_ExecutionSystem.cpp
	source/blender/compositor/intern/COM_MemoryBuffer.cpp
	source/blender/compositor/intern/COM_OpenCLDevice.cpp
	source/blender/compositor/nodes/COM_SocketProxyNode.cpp
	source/blender/compositor/operations/COM_CompositorOperation.cpp
	source/blender/compositor/operations/COM_ReadBufferOperation.h
	source/blender/compositor/operations/COM_RenderLayersProg.cpp
2014-05-12 21:45:43 +02:00
3b691b54b1 Initialize colors, vectors and values in RenderLayersProg 2014-05-12 20:25:30 +02:00
948703b36d Tiles: synced with master 2014-05-12 20:22:40 +02:00
815c999382 Initialize colors, vectors and values in RenderLayersProg 2014-05-12 18:21:45 +02:00
0563280bff Compositor squashed patch reapplied
Started with the MemoryBufferValue
still a lot needs to be done
stopped at testing the dilate/erode

TILES: did some fixed for value buffer

Determine image format of OpenCL device

TILES: TextureNode fix

TILES: moved buffer sizes to constants for easy access.

TILES: fixed some nodes.
still working on the defocus node

TILES: fixed glare, keying, defocus, normalize, vector curves
2014-04-25 16:32:09 +02:00
53 changed files with 1391 additions and 685 deletions

View File

@@ -74,6 +74,12 @@ set(SRC
intern/COM_MemoryProxy.h
intern/COM_MemoryBuffer.cpp
intern/COM_MemoryBuffer.h
intern/COM_MemoryBufferColor.cpp
intern/COM_MemoryBufferColor.h
intern/COM_MemoryBufferVector.cpp
intern/COM_MemoryBufferVector.h
intern/COM_MemoryBufferValue.cpp
intern/COM_MemoryBufferValue.h
intern/COM_WorkScheduler.cpp
intern/COM_WorkScheduler.h
intern/COM_WorkPackage.cpp
@@ -90,8 +96,6 @@ set(SRC
intern/COM_OpenCLDevice.h
intern/COM_CompositorContext.cpp
intern/COM_CompositorContext.h
intern/COM_ChannelInfo.cpp
intern/COM_ChannelInfo.h
intern/COM_SingleThreadedOperation.cpp
intern/COM_SingleThreadedOperation.h
intern/COM_Debug.cpp

View File

@@ -105,7 +105,9 @@ typedef enum OrderOfChunks {
#define COM_RULE_OF_THIRDS_DIVIDER 100.0f
#define COM_NUMBER_OF_CHANNELS 4
#define COM_NO_CHANNELS_VALUE 1
#define COM_NO_CHANNELS_VECTOR 3
#define COM_NO_CHANNELS_COLOR 4
#define COM_BLUR_BOKEH_PIXELS 512

View File

@@ -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;
}

View File

@@ -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

View File

@@ -372,7 +372,7 @@ MemoryBuffer **ExecutionGroup::getInputBuffersOpenCL(int chunkNumber)
MemoryBuffer *ExecutionGroup::constructConsolidatedMemoryBuffer(MemoryProxy *memoryProxy, rcti *rect)
{
MemoryBuffer *imageBuffer = memoryProxy->getBuffer();
MemoryBuffer *result = new MemoryBuffer(memoryProxy, rect);
MemoryBuffer *result = MemoryBuffer::create(memoryProxy, rect);
result->copyContentFrom(imageBuffer);
return result;
}
@@ -465,7 +465,7 @@ MemoryBuffer *ExecutionGroup::allocateOutputBuffer(int chunkNumber, rcti *rect)
NodeOperation *operation = this->getOutputOperation();
if (operation->isWriteBufferOperation()) {
WriteBufferOperation *writeOperation = (WriteBufferOperation *)operation;
MemoryBuffer *buffer = new MemoryBuffer(writeOperation->getMemoryProxy(), rect);
MemoryBuffer *buffer = MemoryBuffer::create(writeOperation->getMemoryProxy(), rect);
return buffer;
}
return NULL;

View File

@@ -98,7 +98,7 @@ ExecutionSystem::ExecutionSystem(RenderData *rd, Scene *scene, bNodeTree *editin
}
}
// DebugInfo::graphviz(this);
DebugInfo::graphviz(this);
}
ExecutionSystem::~ExecutionSystem()

View File

@@ -27,7 +27,11 @@
using std::min;
using std::max;
unsigned int MemoryBuffer::determineBufferSize()
#include "COM_MemoryBufferColor.h"
#include "COM_MemoryBufferVector.h"
#include "COM_MemoryBufferValue.h"
unsigned int MemoryBuffer::determineBufferSize() const
{
return getWidth() * getHeight();
}
@@ -41,38 +45,109 @@ int MemoryBuffer::getHeight() const
return this->m_rect.ymax - this->m_rect.ymin;
}
MemoryBuffer::MemoryBuffer(MemoryProxy *memoryProxy, unsigned int chunkNumber, rcti *rect)
MemoryBuffer* MemoryBuffer::create(MemoryProxy *memoryProxy, unsigned int chunkNumber, rcti *rect) {
DataType type;
type = memoryProxy->getDataType();
if (type == COM_DT_VALUE) {
return new MemoryBufferValue(memoryProxy, chunkNumber, rect);
}
else if (type == COM_DT_VECTOR) {
return new MemoryBufferVector(memoryProxy, chunkNumber, rect);
}
else {
return new MemoryBufferColor(memoryProxy, chunkNumber, rect);
}
}
MemoryBuffer* MemoryBuffer::create(MemoryProxy *memoryProxy, rcti *rect) {
DataType type;
type = memoryProxy->getDataType();
if (type==COM_DT_VALUE){
return new MemoryBufferValue(memoryProxy, rect);
}
else if (type == COM_DT_VECTOR) {
return new MemoryBufferVector(memoryProxy, rect);
}
else {
return new MemoryBufferColor(memoryProxy, rect);
}
}
MemoryBuffer* MemoryBuffer::create(DataType datatype, rcti *rect) {
if (datatype==COM_DT_VALUE){
return new MemoryBufferValue(datatype, rect);
}
else if (datatype == COM_DT_VECTOR) {
return new MemoryBufferVector(datatype, rect);
}
else {
return new MemoryBufferColor(datatype, rect);
}
}
MemoryBuffer::MemoryBuffer(MemoryProxy *memoryProxy, unsigned int chunkNumber, rcti *rect, unsigned int no_channels)
{
BLI_rcti_init(&this->m_rect, rect->xmin, rect->xmax, rect->ymin, rect->ymax);
this->m_memoryProxy = memoryProxy;
this->m_chunkNumber = chunkNumber;
this->m_buffer = (float *)MEM_mallocN(sizeof(float) * determineBufferSize() * COM_NUMBER_OF_CHANNELS, "COM_MemoryBuffer");
this->m_buffer = (float *)MEM_mallocN(sizeof(float) * determineBufferSize() * no_channels, "COM_MemoryBuffer");
this->m_state = COM_MB_ALLOCATED;
this->m_datatype = COM_DT_COLOR;
this->m_chunkWidth = this->m_rect.xmax - this->m_rect.xmin;
this->m_no_channels = no_channels;
}
MemoryBuffer::MemoryBuffer(MemoryProxy *memoryProxy, rcti *rect)
MemoryBuffer::MemoryBuffer(MemoryProxy *memoryProxy, rcti *rect, unsigned int no_channels)
{
BLI_rcti_init(&this->m_rect, rect->xmin, rect->xmax, rect->ymin, rect->ymax);
this->m_memoryProxy = memoryProxy;
this->m_chunkNumber = -1;
this->m_buffer = (float *)MEM_mallocN(sizeof(float) * determineBufferSize() * COM_NUMBER_OF_CHANNELS, "COM_MemoryBuffer");
this->m_buffer = (float *)MEM_mallocN(sizeof(float) * determineBufferSize() * no_channels, "COM_MemoryBuffer");
this->m_state = COM_MB_TEMPORARILY;
this->m_datatype = COM_DT_COLOR;
this->m_chunkWidth = this->m_rect.xmax - this->m_rect.xmin;
}
MemoryBuffer *MemoryBuffer::duplicate()
{
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));
return result;
}
void MemoryBuffer::clear()
{
memset(this->m_buffer, 0, this->determineBufferSize() * COM_NUMBER_OF_CHANNELS * sizeof(float));
this->m_no_channels = no_channels;
}
MemoryBuffer::MemoryBuffer(DataType datatype, rcti *rect, unsigned int no_channels) {
BLI_rcti_init(&this->m_rect, rect->xmin, rect->xmax, rect->ymin, rect->ymax);
this->m_memoryProxy = NULL;
this->m_chunkNumber = -1;
this->m_buffer = (float *)MEM_mallocN(sizeof(float) * determineBufferSize() * no_channels, "COM_MemoryBuffer");
this->m_state = COM_MB_TEMPORARILY;
this->m_chunkWidth = this->m_rect.xmax - this->m_rect.xmin;
this->m_no_channels = no_channels;
}
void MemoryBuffer::clear()
{
memset(this->m_buffer, 0, this->determineBufferSize() * this->m_no_channels * sizeof(float));
}
void MemoryBuffer::copyContentFrom(MemoryBuffer *otherBuffer)
{
if (!otherBuffer) {
BLI_assert(0);
return;
}
unsigned int otherY;
unsigned int minX = max(this->m_rect.xmin, otherBuffer->m_rect.xmin);
unsigned int maxX = min(this->m_rect.xmax, otherBuffer->m_rect.xmax);
unsigned int minY = max(this->m_rect.ymin, otherBuffer->m_rect.ymin);
unsigned int maxY = min(this->m_rect.ymax, otherBuffer->m_rect.ymax);
int offset;
int otherOffset;
for (otherY = minY; otherY < maxY; otherY++) {
otherOffset = ((otherY - otherBuffer->m_rect.ymin) * otherBuffer->m_chunkWidth + minX - otherBuffer->m_rect.xmin) * this->m_no_channels;
offset = ((otherY - this->m_rect.ymin) * this->m_chunkWidth + minX - this->m_rect.xmin) * this->m_no_channels;
memcpy(&this->m_buffer[offset], &otherBuffer->m_buffer[otherOffset], (maxX - minX) * this->m_no_channels * sizeof(float));
}
}
// TODO: this method needs to be checked! At Mind 2014
float *MemoryBuffer::convertToValueBuffer()
{
const unsigned int size = this->determineBufferSize();
@@ -83,29 +158,16 @@ float *MemoryBuffer::convertToValueBuffer()
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) {
for (i = 0; i < size; i++, fp_dst++, fp_src += COM_NO_CHANNELS_COLOR) {
*fp_dst = *fp_src;
}
return result;
}
float MemoryBuffer::getMaximumValue()
float MemoryBuffer::getMaximumValue() const
{
float result = this->m_buffer[0];
const unsigned int size = this->determineBufferSize();
unsigned int i;
const float *fp_src = this->m_buffer;
for (i = 0; i < size; i++, fp_src += COM_NUMBER_OF_CHANNELS) {
float value = *fp_src;
if (value > result) {
result = value;
}
}
return result;
return 0.0f;
}
float MemoryBuffer::getMaximumValue(rcti *rect)
@@ -116,7 +178,7 @@ float MemoryBuffer::getMaximumValue(rcti *rect)
BLI_rcti_isect(rect, &this->m_rect, &rect_clamp);
if (!BLI_rcti_is_empty(&rect_clamp)) {
MemoryBuffer *temp = new MemoryBuffer(NULL, &rect_clamp);
MemoryBuffer *temp = MemoryBuffer::create(COM_DT_VALUE, &rect_clamp);
temp->copyContentFrom(this);
float result = temp->getMaximumValue();
delete temp;
@@ -136,204 +198,6 @@ MemoryBuffer::~MemoryBuffer()
}
}
void MemoryBuffer::copyContentFrom(MemoryBuffer *otherBuffer)
{
if (!otherBuffer) {
BLI_assert(0);
return;
}
unsigned int otherY;
unsigned int minX = max(this->m_rect.xmin, otherBuffer->m_rect.xmin);
unsigned int maxX = min(this->m_rect.xmax, otherBuffer->m_rect.xmax);
unsigned int minY = max(this->m_rect.ymin, otherBuffer->m_rect.ymin);
unsigned int maxY = min(this->m_rect.ymax, otherBuffer->m_rect.ymax);
int offset;
int otherOffset;
for (otherY = minY; otherY < maxY; otherY++) {
otherOffset = ((otherY - otherBuffer->m_rect.ymin) * otherBuffer->m_chunkWidth + minX - otherBuffer->m_rect.xmin) * COM_NUMBER_OF_CHANNELS;
offset = ((otherY - this->m_rect.ymin) * this->m_chunkWidth + minX - this->m_rect.xmin) * COM_NUMBER_OF_CHANNELS;
memcpy(&this->m_buffer[offset], &otherBuffer->m_buffer[otherOffset], (maxX - minX) * COM_NUMBER_OF_CHANNELS * sizeof(float));
}
}
void MemoryBuffer::writePixel(int x, int y, const float color[4])
{
if (x >= this->m_rect.xmin && x < this->m_rect.xmax &&
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;
copy_v4_v4(&this->m_buffer[offset], color);
}
}
void MemoryBuffer::addPixel(int x, int y, const float color[4])
{
if (x >= this->m_rect.xmin && x < this->m_rect.xmax &&
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;
add_v4_v4(&this->m_buffer[offset], color);
}
}
// table of (exp(ar) - exp(a)) / (1 - exp(a)) for r in range [0, 1] and a = -2
// used instead of actual gaussian, otherwise at high texture magnifications circular artifacts are visible
#define EWA_MAXIDX 255
static const float EWA_WTS[EWA_MAXIDX + 1] = {
1.f, 0.990965f, 0.982f, 0.973105f, 0.96428f, 0.955524f, 0.946836f, 0.938216f, 0.929664f,
0.921178f, 0.912759f, 0.904405f, 0.896117f, 0.887893f, 0.879734f, 0.871638f, 0.863605f,
0.855636f, 0.847728f, 0.839883f, 0.832098f, 0.824375f, 0.816712f, 0.809108f, 0.801564f,
0.794079f, 0.786653f, 0.779284f, 0.771974f, 0.76472f, 0.757523f, 0.750382f, 0.743297f,
0.736267f, 0.729292f, 0.722372f, 0.715505f, 0.708693f, 0.701933f, 0.695227f, 0.688572f,
0.68197f, 0.67542f, 0.66892f, 0.662471f, 0.656073f, 0.649725f, 0.643426f, 0.637176f,
0.630976f, 0.624824f, 0.618719f, 0.612663f, 0.606654f, 0.600691f, 0.594776f, 0.588906f,
0.583083f, 0.577305f, 0.571572f, 0.565883f, 0.56024f, 0.55464f, 0.549084f, 0.543572f,
0.538102f, 0.532676f, 0.527291f, 0.521949f, 0.516649f, 0.511389f, 0.506171f, 0.500994f,
0.495857f, 0.490761f, 0.485704f, 0.480687f, 0.475709f, 0.470769f, 0.465869f, 0.461006f,
0.456182f, 0.451395f, 0.446646f, 0.441934f, 0.437258f, 0.432619f, 0.428017f, 0.42345f,
0.418919f, 0.414424f, 0.409963f, 0.405538f, 0.401147f, 0.39679f, 0.392467f, 0.388178f,
0.383923f, 0.379701f, 0.375511f, 0.371355f, 0.367231f, 0.363139f, 0.359079f, 0.355051f,
0.351055f, 0.347089f, 0.343155f, 0.339251f, 0.335378f, 0.331535f, 0.327722f, 0.323939f,
0.320186f, 0.316461f, 0.312766f, 0.3091f, 0.305462f, 0.301853f, 0.298272f, 0.294719f,
0.291194f, 0.287696f, 0.284226f, 0.280782f, 0.277366f, 0.273976f, 0.270613f, 0.267276f,
0.263965f, 0.26068f, 0.257421f, 0.254187f, 0.250979f, 0.247795f, 0.244636f, 0.241502f,
0.238393f, 0.235308f, 0.232246f, 0.229209f, 0.226196f, 0.223206f, 0.220239f, 0.217296f,
0.214375f, 0.211478f, 0.208603f, 0.20575f, 0.20292f, 0.200112f, 0.197326f, 0.194562f,
0.191819f, 0.189097f, 0.186397f, 0.183718f, 0.18106f, 0.178423f, 0.175806f, 0.17321f,
0.170634f, 0.168078f, 0.165542f, 0.163026f, 0.16053f, 0.158053f, 0.155595f, 0.153157f,
0.150738f, 0.148337f, 0.145955f, 0.143592f, 0.141248f, 0.138921f, 0.136613f, 0.134323f,
0.132051f, 0.129797f, 0.12756f, 0.125341f, 0.123139f, 0.120954f, 0.118786f, 0.116635f,
0.114501f, 0.112384f, 0.110283f, 0.108199f, 0.106131f, 0.104079f, 0.102043f, 0.100023f,
0.0980186f, 0.09603f, 0.094057f, 0.0920994f, 0.0901571f, 0.08823f, 0.0863179f, 0.0844208f,
0.0825384f, 0.0806708f, 0.0788178f, 0.0769792f, 0.0751551f, 0.0733451f, 0.0715493f, 0.0697676f,
0.0679997f, 0.0662457f, 0.0645054f, 0.0627786f, 0.0610654f, 0.0593655f, 0.0576789f, 0.0560055f,
0.0543452f, 0.0526979f, 0.0510634f, 0.0494416f, 0.0478326f, 0.0462361f, 0.0446521f, 0.0430805f,
0.0415211f, 0.039974f, 0.0384389f, 0.0369158f, 0.0354046f, 0.0339052f, 0.0324175f, 0.0309415f,
0.029477f, 0.0280239f, 0.0265822f, 0.0251517f, 0.0237324f, 0.0223242f, 0.020927f, 0.0195408f,
0.0181653f, 0.0168006f, 0.0154466f, 0.0141031f, 0.0127701f, 0.0114476f, 0.0101354f, 0.00883339f,
0.00754159f, 0.00625989f, 0.00498819f, 0.00372644f, 0.00247454f, 0.00123242f, 0.f
};
static void ellipse_bounds(float A, float B, float C, float F, float &xmax, float &ymax)
{
float denom = 4.0f * A * C - B * B;
if (denom > 0.0f && A != 0.0f && C != 0.0f) {
xmax = sqrtf(F) / (2.0f * A) * (sqrtf(F * (4.0f * A - B * B / C)) + B * B * sqrtf(F / (C * denom)));
ymax = sqrtf(F) / (2.0f * C) * (sqrtf(F * (4.0f * C - B * B / A)) + B * B * sqrtf(F / (A * denom)));
}
else {
xmax = 0.0f;
ymax = 0.0f;
}
}
static void ellipse_params(float Ux, float Uy, float Vx, float Vy,
float &A, float &B, float &C, float &F, float &umax, float &vmax)
{
A = Vx * Vx + Vy * Vy;
B = -2.0f * (Ux * Vx + Uy * Vy);
C = Ux * Ux + Uy * Uy;
F = A * C - B * B * 0.25f;
float factor = (F != 0.0f ? (float)(EWA_MAXIDX + 1) / F : 0.0f);
A *= factor;
B *= factor;
C *= factor;
F = (float)(EWA_MAXIDX + 1);
ellipse_bounds(A, B, C, sqrtf(F), umax, vmax);
}
/**
* Filtering method based on
* "Creating raster omnimax images from multiple perspective views using the elliptical weighted average filter"
* by Ned Greene and Paul S. Heckbert (1986)
*/
void MemoryBuffer::readEWA(float result[4], const float uv[2], const float derivatives[2][2], PixelSampler sampler)
{
zero_v4(result);
int width = this->getWidth(), height = this->getHeight();
if (width == 0 || height == 0)
return;
float u = uv[0], v = uv[1];
float Ux = derivatives[0][0], Vx = derivatives[1][0], Uy = derivatives[0][1], Vy = derivatives[1][1];
float A, B, C, F, ue, ve;
ellipse_params(Ux, Uy, Vx, Vy, A, B, C, F, ue, ve);
/* Note: highly eccentric ellipses can lead to large texture space areas to filter!
* This is limited somewhat by the EWA_WTS size in the loop, but a nicer approach
* could be the one found in
* "High Quality Elliptical Texture Filtering on GPU"
* by Pavlos Mavridis and Georgios Papaioannou
* in which the eccentricity of the ellipse is clamped.
*/
int U0 = (int)u;
int V0 = (int)v;
/* pixel offset for interpolation */
float ufac = u - floorf(u), vfac = v - floorf(v);
/* filter size */
int u1 = (int)(u - ue);
int u2 = (int)(u + ue);
int v1 = (int)(v - ve);
int v2 = (int)(v + ve);
/* sane clamping to avoid unnecessarily huge loops */
/* note: if eccentricity gets clamped (see above),
* the ue/ve limits can also be lowered accordingly
*/
if (U0 - u1 > EWA_MAXIDX) u1 = U0 - EWA_MAXIDX;
if (u2 - U0 > EWA_MAXIDX) u2 = U0 + EWA_MAXIDX;
if (V0 - v1 > EWA_MAXIDX) v1 = V0 - EWA_MAXIDX;
if (v2 - V0 > EWA_MAXIDX) v2 = V0 + EWA_MAXIDX;
/* Early output check for cases the whole region is outside of the buffer. */
if ((u2 < m_rect.xmin || u1 >= m_rect.xmax) ||
(v2 < m_rect.ymin || v1 >= m_rect.ymax))
{
zero_v4(result);
return;
}
/* Clamp sampling rectagle to the buffer dimensions. */
u1 = max_ii(u1, m_rect.xmin);
u2 = min_ii(u2, m_rect.xmax);
v1 = max_ii(v1, m_rect.ymin);
v2 = min_ii(v2, m_rect.ymax);
float DDQ = 2.0f * A;
float U = u1 - U0;
float ac1 = A * (2.0f * U + 1.0f);
float ac2 = A * U * U;
float BU = B * U;
float sum = 0.0f;
for (int v = v1; v <= v2; ++v) {
float V = v - V0;
float DQ = ac1 + B * V;
float Q = (C * V + BU) * V + ac2;
for (int u = u1; u <= u2; ++u) {
if (Q < F) {
float tc[4];
const float wt = EWA_WTS[CLAMPIS((int)Q, 0, EWA_MAXIDX)];
switch (sampler) {
case COM_PS_NEAREST: read(tc, u, v); break;
case COM_PS_BILINEAR: readBilinear(tc, (float)u + ufac, (float)v + vfac); break;
case COM_PS_BICUBIC: readBilinear(tc, (float)u + ufac, (float)v + vfac); break; /* XXX no readBicubic method yet */
default: zero_v4(tc); break;
}
madd_v4_v4fl(result, tc, wt);
sum += wt;
}
Q += DQ;
DQ += DDQ;
}
}
mul_v4_fl(result, (sum != 0.0f ? 1.0f / sum : 0.0f));
const int MemoryBuffer::get_no_channels() const {
return this->m_no_channels;
}

View File

@@ -61,57 +61,84 @@ class MemoryProxy;
class MemoryBuffer {
private:
/**
* @brief proxy of the memory (same for all chunks in the same buffer)
* brief refers to the chunknumber within the executiongroup where related to the MemoryProxy
* @see memoryProxy
*/
MemoryProxy *m_memoryProxy;
unsigned int m_chunkNumber;
/**
* @brief the type of buffer COM_DT_VALUE, COM_DT_VECTOR, COM_DT_COLOR
* @brief state of the buffer
*/
DataType m_datatype;
MemoryBufferState m_state;
/**
* @brief the number of channels that form a single pixel in this buffer
*/
unsigned int m_no_channels;
protected:
/**
* @brief width of the chunk
*/
unsigned int m_chunkWidth;
/**
* @brief region of this buffer inside relative to the MemoryProxy
*/
rcti m_rect;
/**
* brief refers to the chunknumber within the executiongroup where related to the MemoryProxy
* @see memoryProxy
* @brief proxy of the memory (same for all chunks in the same buffer)
*/
unsigned int m_chunkNumber;
/**
* @brief width of the chunk
*/
unsigned int m_chunkWidth;
/**
* @brief state of the buffer
*/
MemoryBufferState m_state;
MemoryProxy *m_memoryProxy;
/**
* @brief the actual float buffer/data
*/
float *m_buffer;
public:
/**
* @brief construct new MemoryBuffer for a chunk
*
* @param no_channels Number of channels that must be allocated for every pixel
*/
MemoryBuffer(MemoryProxy *memoryProxy, unsigned int chunkNumber, rcti *rect);
MemoryBuffer(MemoryProxy *memoryProxy, unsigned int chunkNumber, rcti *rect, unsigned int no_channels);
/**
* @brief construct new temporarily MemoryBuffer for an area
*
* @param no_channels Number of channels that must be allocated for every pixel
*/
MemoryBuffer(MemoryProxy *memoryProxy, rcti *rect);
MemoryBuffer(MemoryProxy *memoryProxy, rcti *rect, unsigned int no_channels);
/**
* @brief construct new temporarily MemoryBuffer for an area
*
* @param no_channels Number of channels that must be allocated for every pixel
*/
MemoryBuffer(DataType datatype, rcti *rect, unsigned int no_channels);
public:
/**
* @brief factory method for the constructor, selecting the right subclass
*/
static MemoryBuffer* create(MemoryProxy *memoryProxy, unsigned int chunkNumber, rcti *rect);
/**
* @brief factory method for the constructor, selecting the right subclass, creating a temporarily buffer
*/
static MemoryBuffer* create(MemoryProxy *memoryProxy, rcti *rect);
/**
* @brief factory method for the constructor, selecting the right subclass, creating a temporarily buffer
*/
static MemoryBuffer* create(DataType datatype, rcti *rect);
/**
* @brief destructor
*/
~MemoryBuffer();
virtual ~MemoryBuffer();
/**
* @brief read the ChunkNumber of this MemoryBuffer
@@ -164,89 +191,24 @@ public:
}
}
inline void read(float result[4], int x, int y,
virtual void read(float *result, int x, int y,
MemoryBufferExtend extend_x = COM_MB_CLIP,
MemoryBufferExtend extend_y = COM_MB_CLIP)
{
bool clip_x = (extend_x == COM_MB_CLIP && (x < m_rect.xmin || x >= m_rect.xmax));
bool clip_y = (extend_y == COM_MB_CLIP && (y < m_rect.ymin || y >= m_rect.ymax));
if (clip_x || clip_y) {
/* clip result outside rect is zero */
zero_v4(result);
}
else {
wrap_pixel(x, y, extend_x, extend_y);
const int offset = (this->m_chunkWidth * y + x) * COM_NUMBER_OF_CHANNELS;
copy_v4_v4(result, &this->m_buffer[offset]);
}
}
MemoryBufferExtend extend_y = COM_MB_CLIP) = 0;
inline void readNoCheck(float result[4], int x, int y,
virtual void readNoCheck(float *result, int x, int y,
MemoryBufferExtend extend_x = COM_MB_CLIP,
MemoryBufferExtend extend_y = COM_MB_CLIP)
{
wrap_pixel(x, y, extend_x, extend_y);
const int offset = (this->m_chunkWidth * y + x) * COM_NUMBER_OF_CHANNELS;
MemoryBufferExtend extend_y = COM_MB_CLIP) = 0;
BLI_assert(offset >= 0);
BLI_assert(offset < this->determineBufferSize() * COM_NUMBER_OF_CHANNELS);
BLI_assert(!(extend_x == COM_MB_CLIP && (x < m_rect.xmin || x >= m_rect.xmax)) &&
!(extend_y == COM_MB_CLIP && (y < m_rect.ymin || y >= m_rect.ymax)));
#if 0
/* always true */
BLI_assert((int)(MEM_allocN_len(this->m_buffer) / sizeof(*this->m_buffer)) ==
(int)(this->determineBufferSize() * COM_NUMBER_OF_CHANNELS));
#endif
copy_v4_v4(result, &this->m_buffer[offset]);
}
void writePixel(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,
virtual void writePixel(int x, int y, const float *color) = 0;
virtual void addPixel(int x, int y, const float *color) = 0;
virtual void readBilinear(float *result, float x, float y,
MemoryBufferExtend extend_x = COM_MB_CLIP,
MemoryBufferExtend extend_y = COM_MB_CLIP)
{
int x1 = floor(x);
int y1 = floor(y);
int x2 = x1 + 1;
int y2 = y1 + 1;
wrap_pixel(x1, y1, extend_x, extend_y);
wrap_pixel(x2, y2, extend_x, extend_y);
MemoryBufferExtend extend_y = COM_MB_CLIP) = 0;
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);
virtual void readEWA(float result[4], 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)
@@ -282,13 +244,23 @@ public:
*/
void clear();
MemoryBuffer *duplicate();
virtual MemoryBuffer *duplicate() = 0;
float *convertToValueBuffer();
float getMaximumValue();
virtual float getMaximumValue() const;
float getMaximumValue(rcti *rect);
private:
unsigned int determineBufferSize();
/**
* @brief return the number of channels that form a single pixel.
*
* Value = 1
* Vector= 3
* Color = 4
*/
const int get_no_channels() const;
protected:
unsigned int determineBufferSize() const;
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("COM:MemoryBuffer")

View File

@@ -0,0 +1,291 @@
/*
* Copyright 2014, 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_MemoryBufferColor.h"
#define NUMBER_OF_CHANNELS COM_NO_CHANNELS_COLOR
MemoryBufferColor::MemoryBufferColor(MemoryProxy *memoryProxy, unsigned int chunkNumber, rcti *rect):
MemoryBuffer(memoryProxy, chunkNumber, rect, NUMBER_OF_CHANNELS)
{
}
MemoryBufferColor::MemoryBufferColor(MemoryProxy *memoryProxy, rcti *rect) :
MemoryBuffer(memoryProxy, rect, NUMBER_OF_CHANNELS)
{
}
MemoryBufferColor::MemoryBufferColor(DataType datatype, rcti *rect) :
MemoryBuffer(datatype, rect, NUMBER_OF_CHANNELS) {
}
MemoryBuffer *MemoryBufferColor::duplicate()
{
MemoryBufferColor *result = new MemoryBufferColor(this->m_memoryProxy, &this->m_rect);
memcpy(result->getBuffer(), this->getBuffer(), this->determineBufferSize() * NUMBER_OF_CHANNELS * sizeof(float));
return result;
}
// --- write pixels ---
void MemoryBufferColor::writePixel(int x, int y, const float *color)
{
if (x >= this->m_rect.xmin && x < this->m_rect.xmax &&
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) * NUMBER_OF_CHANNELS;
copy_v4_v4(&this->m_buffer[offset], color);
}
}
void MemoryBufferColor::addPixel(int x, int y, const float *color)
{
if (x >= this->m_rect.xmin && x < this->m_rect.xmax &&
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) * NUMBER_OF_CHANNELS;
add_v4_v4(&this->m_buffer[offset], color);
}
}
// --- SAMPLERS ---
inline void MemoryBufferColor::read(float *result, int x, int y,
MemoryBufferExtend extend_x,
MemoryBufferExtend extend_y)
{
bool clip_x = (extend_x == COM_MB_CLIP && (x < m_rect.xmin || x >= m_rect.xmax));
bool clip_y = (extend_y == COM_MB_CLIP && (y < m_rect.ymin || y >= m_rect.ymax));
if (clip_x || clip_y) {
/* clip result outside rect is zero */
zero_v4(result);
}
else
{
wrap_pixel(x, y, extend_x, extend_y);
const int offset = (this->m_chunkWidth * y + x) * NUMBER_OF_CHANNELS;
copy_v4_v4(result, &this->m_buffer[offset]);
}
}
inline void MemoryBufferColor::readNoCheck(float *result, int x, int y,
MemoryBufferExtend extend_x,
MemoryBufferExtend extend_y)
{
wrap_pixel(x, y, extend_x, extend_y);
const int offset = (this->m_chunkWidth * y + x) * NUMBER_OF_CHANNELS;
BLI_assert(offset >= 0);
BLI_assert(offset < this->determineBufferSize() * NUMBER_OF_CHANNELS);
BLI_assert(!(extend_x == COM_MB_CLIP && (x < m_rect.xmin || x >= m_rect.xmax)) &&
!(extend_y == COM_MB_CLIP && (y < m_rect.ymin || y >= m_rect.ymax)));
copy_v4_v4(result, &this->m_buffer[offset]);
}
inline void MemoryBufferColor::readBilinear(float *result, float x, float y,
MemoryBufferExtend extend_x,
MemoryBufferExtend extend_y)
{
int x1 = floor(x);
int y1 = floor(y);
int x2 = x1 + 1;
int y2 = y1 + 1;
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;
}
// --- EWA Filtering ---
// table of (exp(ar) - exp(a)) / (1 - exp(a)) for r in range [0, 1] and a = -2
// used instead of actual gaussian, otherwise at high texture magnifications circular artifacts are visible
#define EWA_MAXIDX 255
static const float EWA_WTS[EWA_MAXIDX + 1] = {
1.f, 0.990965f, 0.982f, 0.973105f, 0.96428f, 0.955524f, 0.946836f, 0.938216f, 0.929664f,
0.921178f, 0.912759f, 0.904405f, 0.896117f, 0.887893f, 0.879734f, 0.871638f, 0.863605f,
0.855636f, 0.847728f, 0.839883f, 0.832098f, 0.824375f, 0.816712f, 0.809108f, 0.801564f,
0.794079f, 0.786653f, 0.779284f, 0.771974f, 0.76472f, 0.757523f, 0.750382f, 0.743297f,
0.736267f, 0.729292f, 0.722372f, 0.715505f, 0.708693f, 0.701933f, 0.695227f, 0.688572f,
0.68197f, 0.67542f, 0.66892f, 0.662471f, 0.656073f, 0.649725f, 0.643426f, 0.637176f,
0.630976f, 0.624824f, 0.618719f, 0.612663f, 0.606654f, 0.600691f, 0.594776f, 0.588906f,
0.583083f, 0.577305f, 0.571572f, 0.565883f, 0.56024f, 0.55464f, 0.549084f, 0.543572f,
0.538102f, 0.532676f, 0.527291f, 0.521949f, 0.516649f, 0.511389f, 0.506171f, 0.500994f,
0.495857f, 0.490761f, 0.485704f, 0.480687f, 0.475709f, 0.470769f, 0.465869f, 0.461006f,
0.456182f, 0.451395f, 0.446646f, 0.441934f, 0.437258f, 0.432619f, 0.428017f, 0.42345f,
0.418919f, 0.414424f, 0.409963f, 0.405538f, 0.401147f, 0.39679f, 0.392467f, 0.388178f,
0.383923f, 0.379701f, 0.375511f, 0.371355f, 0.367231f, 0.363139f, 0.359079f, 0.355051f,
0.351055f, 0.347089f, 0.343155f, 0.339251f, 0.335378f, 0.331535f, 0.327722f, 0.323939f,
0.320186f, 0.316461f, 0.312766f, 0.3091f, 0.305462f, 0.301853f, 0.298272f, 0.294719f,
0.291194f, 0.287696f, 0.284226f, 0.280782f, 0.277366f, 0.273976f, 0.270613f, 0.267276f,
0.263965f, 0.26068f, 0.257421f, 0.254187f, 0.250979f, 0.247795f, 0.244636f, 0.241502f,
0.238393f, 0.235308f, 0.232246f, 0.229209f, 0.226196f, 0.223206f, 0.220239f, 0.217296f,
0.214375f, 0.211478f, 0.208603f, 0.20575f, 0.20292f, 0.200112f, 0.197326f, 0.194562f,
0.191819f, 0.189097f, 0.186397f, 0.183718f, 0.18106f, 0.178423f, 0.175806f, 0.17321f,
0.170634f, 0.168078f, 0.165542f, 0.163026f, 0.16053f, 0.158053f, 0.155595f, 0.153157f,
0.150738f, 0.148337f, 0.145955f, 0.143592f, 0.141248f, 0.138921f, 0.136613f, 0.134323f,
0.132051f, 0.129797f, 0.12756f, 0.125341f, 0.123139f, 0.120954f, 0.118786f, 0.116635f,
0.114501f, 0.112384f, 0.110283f, 0.108199f, 0.106131f, 0.104079f, 0.102043f, 0.100023f,
0.0980186f, 0.09603f, 0.094057f, 0.0920994f, 0.0901571f, 0.08823f, 0.0863179f, 0.0844208f,
0.0825384f, 0.0806708f, 0.0788178f, 0.0769792f, 0.0751551f, 0.0733451f, 0.0715493f, 0.0697676f,
0.0679997f, 0.0662457f, 0.0645054f, 0.0627786f, 0.0610654f, 0.0593655f, 0.0576789f, 0.0560055f,
0.0543452f, 0.0526979f, 0.0510634f, 0.0494416f, 0.0478326f, 0.0462361f, 0.0446521f, 0.0430805f,
0.0415211f, 0.039974f, 0.0384389f, 0.0369158f, 0.0354046f, 0.0339052f, 0.0324175f, 0.0309415f,
0.029477f, 0.0280239f, 0.0265822f, 0.0251517f, 0.0237324f, 0.0223242f, 0.020927f, 0.0195408f,
0.0181653f, 0.0168006f, 0.0154466f, 0.0141031f, 0.0127701f, 0.0114476f, 0.0101354f, 0.00883339f,
0.00754159f, 0.00625989f, 0.00498819f, 0.00372644f, 0.00247454f, 0.00123242f, 0.f
};
static void ellipse_bounds(float A, float B, float C, float F, float &xmax, float &ymax)
{
float denom = 4.0f * A * C - B * B;
if (denom > 0.0f && A != 0.0f && C != 0.0f) {
xmax = sqrtf(F) / (2.0f * A) * (sqrtf(F * (4.0f * A - B * B / C)) + B * B * sqrtf(F / (C * denom)));
ymax = sqrtf(F) / (2.0f * C) * (sqrtf(F * (4.0f * C - B * B / A)) + B * B * sqrtf(F / (A * denom)));
}
else {
xmax = 0.0f;
ymax = 0.0f;
}
}
static void ellipse_params(float Ux, float Uy, float Vx, float Vy,
float &A, float &B, float &C, float &F, float &umax, float &vmax)
{
A = Vx * Vx + Vy * Vy;
B = -2.0f * (Ux * Vx + Uy * Vy);
C = Ux * Ux + Uy * Uy;
F = A * C - B * B * 0.25f;
float factor = (F != 0.0f ? (float)(EWA_MAXIDX + 1) / F : 0.0f);
A *= factor;
B *= factor;
C *= factor;
F = (float)(EWA_MAXIDX + 1);
ellipse_bounds(A, B, C, sqrtf(F), umax, vmax);
}
/**
* Filtering method based on
* "Creating raster omnimax images from multiple perspective views using the elliptical weighted average filter"
* by Ned Greene and Paul S. Heckbert (1986)
*/
void MemoryBufferColor::readEWA(float result[4], const float uv[2], const float derivatives[2][2], PixelSampler sampler)
{
zero_v4(result);
int width = this->getWidth(), height = this->getHeight();
if (width == 0 || height == 0)
return;
float u = uv[0], v = uv[1];
float Ux = derivatives[0][0], Vx = derivatives[1][0], Uy = derivatives[0][1], Vy = derivatives[1][1];
float A, B, C, F, ue, ve;
ellipse_params(Ux, Uy, Vx, Vy, A, B, C, F, ue, ve);
/* Note: highly eccentric ellipses can lead to large texture space areas to filter!
* This is limited somewhat by the EWA_WTS size in the loop, but a nicer approach
* could be the one found in
* "High Quality Elliptical Texture Filtering on GPU"
* by Pavlos Mavridis and Georgios Papaioannou
* in which the eccentricity of the ellipse is clamped.
*/
int U0 = (int)u;
int V0 = (int)v;
/* pixel offset for interpolation */
float ufac = u - floorf(u), vfac = v - floorf(v);
/* filter size */
int u1 = (int)(u - ue);
int u2 = (int)(u + ue);
int v1 = (int)(v - ve);
int v2 = (int)(v + ve);
/* sane clamping to avoid unnecessarily huge loops */
/* note: if eccentricity gets clamped (see above),
* the ue/ve limits can also be lowered accordingly
*/
if (U0 - u1 > EWA_MAXIDX) u1 = U0 - EWA_MAXIDX;
if (u2 - U0 > EWA_MAXIDX) u2 = U0 + EWA_MAXIDX;
if (V0 - v1 > EWA_MAXIDX) v1 = V0 - EWA_MAXIDX;
if (v2 - V0 > EWA_MAXIDX) v2 = V0 + EWA_MAXIDX;
float DDQ = 2.0f * A;
float U = u1 - U0;
float ac1 = A * (2.0f * U + 1.0f);
float ac2 = A * U * U;
float BU = B * U;
float sum = 0.0f;
for (int v = v1; v <= v2; ++v) {
float V = v - V0;
float DQ = ac1 + B * V;
float Q = (C * V + BU) * V + ac2;
for (int u = u1; u <= u2; ++u) {
if (Q < F) {
float tc[4];
const float wt = EWA_WTS[CLAMPIS((int)Q, 0, EWA_MAXIDX)];
switch (sampler) {
case COM_PS_NEAREST: read(tc, u, v); break;
case COM_PS_BILINEAR: readBilinear(tc, (float)u + ufac, (float)v + vfac); break;
case COM_PS_BICUBIC: readBilinear(tc, (float)u + ufac, (float)v + vfac); break; /* XXX no readBicubic method yet */
default: zero_v4(tc); break;
}
madd_v4_v4fl(result, tc, wt);
sum += wt;
}
Q += DQ;
DQ += DDQ;
}
}
mul_v4_fl(result, (sum != 0.0f ? 1.0f / sum : 0.0f));
}

View File

@@ -0,0 +1,71 @@
/*
* Copyright 2014, 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
*/
class MemoryBufferColor;
#ifndef _COM_MemoryBufferColor_h_
#define _COM_MemoryBufferColor_h_
#include "COM_MemoryBuffer.h"
class MemoryBufferColor: MemoryBuffer
{
protected:
/**
* @brief construct new MemoryBuffer for a chunk
*/
MemoryBufferColor(MemoryProxy *memoryProxy, unsigned int chunkNumber, rcti *rect);
/**
* @brief construct new temporarily MemoryBuffer for an area
*/
MemoryBufferColor(MemoryProxy *memoryProxy, rcti *rect);
MemoryBufferColor(DataType datatype, rcti *rect);
public:
void writePixel(int x, int y, const float *color);
void addPixel(int x, int y, const float *color);
void read(float *result, int x, int y,
MemoryBufferExtend extend_x = COM_MB_CLIP,
MemoryBufferExtend extend_y = COM_MB_CLIP);
void readNoCheck(float *result, int x, int y,
MemoryBufferExtend extend_x = COM_MB_CLIP,
MemoryBufferExtend extend_y = COM_MB_CLIP);
void readBilinear(float *result, float x, float y,
MemoryBufferExtend extend_x = COM_MB_CLIP,
MemoryBufferExtend extend_y = COM_MB_CLIP);
void readEWA(float result[4], const float uv[2], const float derivatives[2][2], PixelSampler sampler);
MemoryBuffer *duplicate();
friend class MemoryBuffer;
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("COM:MemoryBufferColor")
#endif
};
#endif

View File

@@ -0,0 +1,152 @@
/*
* Copyright 2014, 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_MemoryBufferValue.h"
#define NUMBER_OF_CHANNELS COM_NO_CHANNELS_VALUE
MemoryBufferValue::MemoryBufferValue(MemoryProxy *memoryProxy, unsigned int chunkNumber, rcti *rect):
MemoryBuffer(memoryProxy, chunkNumber, rect, NUMBER_OF_CHANNELS)
{
}
MemoryBufferValue::MemoryBufferValue(MemoryProxy *memoryProxy, rcti *rect) :
MemoryBuffer(memoryProxy, rect, NUMBER_OF_CHANNELS)
{
}
MemoryBufferValue::MemoryBufferValue(DataType datatype, rcti *rect) :
MemoryBuffer(datatype, rect, NUMBER_OF_CHANNELS) {
}
MemoryBuffer *MemoryBufferValue::duplicate()
{
MemoryBufferValue *result = new MemoryBufferValue(this->m_memoryProxy, &this->m_rect);
memcpy(result->getBuffer(), this->getBuffer(), this->determineBufferSize() * NUMBER_OF_CHANNELS * sizeof(float));
return result;
}
// --- write pixels ---
void MemoryBufferValue::writePixel(int x, int y, const float *color)
{
if (x >= this->m_rect.xmin && x < this->m_rect.xmax &&
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) * NUMBER_OF_CHANNELS;
copy_v4_v4(&this->m_buffer[offset], color);
}
}
void MemoryBufferValue::addPixel(int x, int y, const float *color)
{
if (x >= this->m_rect.xmin && x < this->m_rect.xmax &&
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) * NUMBER_OF_CHANNELS;
this->m_buffer[offset] = color[0];
}
}
// --- SAMPLERS ---
inline void MemoryBufferValue::read(float *result, int x, int y,
MemoryBufferExtend extend_x,
MemoryBufferExtend extend_y)
{
bool clip_x = (extend_x == COM_MB_CLIP && (x < m_rect.xmin || x >= m_rect.xmax));
bool clip_y = (extend_y == COM_MB_CLIP && (y < m_rect.ymin || y >= m_rect.ymax));
if (clip_x || clip_y) {
/* clip result outside rect is zero */
zero_v4(result);
}
else
{
wrap_pixel(x, y, extend_x, extend_y);
const int offset = (this->m_chunkWidth * y + x) * NUMBER_OF_CHANNELS;
result[0] = this->m_buffer[offset];
}
}
inline void MemoryBufferValue::readNoCheck(float *result, int x, int y,
MemoryBufferExtend extend_x,
MemoryBufferExtend extend_y)
{
wrap_pixel(x, y, extend_x, extend_y);
const int offset = (this->m_chunkWidth * y + x) * NUMBER_OF_CHANNELS;
BLI_assert(offset >= 0);
BLI_assert(offset < this->determineBufferSize() * NUMBER_OF_CHANNELS);
BLI_assert(!(extend_x == COM_MB_CLIP && (x < m_rect.xmin || x >= m_rect.xmax)) &&
!(extend_y == COM_MB_CLIP && (y < m_rect.ymin || y >= m_rect.ymax)));
result[0] = this->m_buffer[offset];
}
inline void MemoryBufferValue::readBilinear(float *result, float x, float y,
MemoryBufferExtend extend_x,
MemoryBufferExtend extend_y)
{
int x1 = floor(x);
int y1 = floor(y);
int x2 = x1 + 1;
int y2 = y1 + 1;
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 value1;
float value2;
float value3;
float value4;
read(&value1, x1, y1);
read(&value2, x1, y2);
read(&value3, x2, y1);
read(&value4, x2, y2);
value1 = value1 * mvaluey + value2 * valuey;
value3 = value3 * mvaluey + value4 * valuey;
result[0] = value1 * mvaluex + value3 * valuex;
}
float MemoryBufferValue::getMaximumValue() const
{
float result = this->m_buffer[0];
const unsigned int size = this->determineBufferSize();
unsigned int i;
const float *fp_src = this->m_buffer;
for (i = 0; i < size; i++, fp_src += NUMBER_OF_CHANNELS) {
float value = *fp_src;
if (value > result) {
result = value;
}
}
return result;
}

View File

@@ -0,0 +1,68 @@
/*
* Copyright 2014, 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
*/
class MemoryBufferValue;
#ifndef _COM_MemoryBufferValue_h_
#define _COM_MemoryBufferValue_h_
#include "COM_MemoryBuffer.h"
class MemoryBufferValue: public MemoryBuffer
{
protected:
/**
* @brief construct new MemoryBuffer for a chunk
*/
MemoryBufferValue(MemoryProxy *memoryProxy, unsigned int chunkNumber, rcti *rect);
/**
* @brief construct new temporarily MemoryBuffer for an area
*/
MemoryBufferValue(MemoryProxy *memoryProxy, rcti *rect);
MemoryBufferValue(DataType datatype, rcti *rect);
public:
void writePixel(int x, int y, const float *color);
void addPixel(int x, int y, const float *color);
void read(float *result, int x, int y,
MemoryBufferExtend extend_x = COM_MB_CLIP,
MemoryBufferExtend extend_y = COM_MB_CLIP);
void readNoCheck(float *result, int x, int y,
MemoryBufferExtend extend_x = COM_MB_CLIP,
MemoryBufferExtend extend_y = COM_MB_CLIP);
void readBilinear(float *result, float x, float y,
MemoryBufferExtend extend_x = COM_MB_CLIP,
MemoryBufferExtend extend_y = COM_MB_CLIP);
float getMaximumValue() const;
MemoryBuffer *duplicate();
friend class MemoryBuffer;
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("COM:MemoryBufferValue")
#endif
};
#endif

View File

@@ -0,0 +1,144 @@
/*
* Copyright 2014, 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_MemoryBufferVector.h"
#define NUMBER_OF_CHANNELS COM_NO_CHANNELS_VECTOR
MemoryBufferVector::MemoryBufferVector(MemoryProxy *memoryProxy, unsigned int chunkNumber, rcti *rect):
MemoryBuffer(memoryProxy, chunkNumber, rect, NUMBER_OF_CHANNELS)
{
}
MemoryBufferVector::MemoryBufferVector(MemoryProxy *memoryProxy, rcti *rect) :
MemoryBuffer(memoryProxy, rect, NUMBER_OF_CHANNELS)
{
}
MemoryBufferVector::MemoryBufferVector(DataType datatype, rcti *rect) :
MemoryBuffer(datatype, rect, NUMBER_OF_CHANNELS) {
}
MemoryBuffer *MemoryBufferVector::duplicate()
{
MemoryBufferVector *result = new MemoryBufferVector(this->m_memoryProxy, &this->m_rect);
memcpy(result->getBuffer(), this->getBuffer(), this->determineBufferSize() * NUMBER_OF_CHANNELS * sizeof(float));
return result;
}
// --- write pixels ---
void MemoryBufferVector::writePixel(int x, int y, const float *color)
{
if (x >= this->m_rect.xmin && x < this->m_rect.xmax &&
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) * NUMBER_OF_CHANNELS;
copy_v4_v4(&this->m_buffer[offset], color);
}
}
void MemoryBufferVector::addPixel(int x, int y, const float *color)
{
if (x >= this->m_rect.xmin && x < this->m_rect.xmax &&
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) * NUMBER_OF_CHANNELS;
add_v4_v4(&this->m_buffer[offset], color);
}
}
// --- SAMPLERS ---
inline void MemoryBufferVector::read(float *result, int x, int y,
MemoryBufferExtend extend_x,
MemoryBufferExtend extend_y)
{
bool clip_x = (extend_x == COM_MB_CLIP && (x < m_rect.xmin || x >= m_rect.xmax));
bool clip_y = (extend_y == COM_MB_CLIP && (y < m_rect.ymin || y >= m_rect.ymax));
if (clip_x || clip_y) {
/* clip result outside rect is zero */
zero_v4(result);
}
else
{
wrap_pixel(x, y, extend_x, extend_y);
const int offset = (this->m_chunkWidth * y + x) * NUMBER_OF_CHANNELS;
copy_v4_v4(result, &this->m_buffer[offset]);
}
}
inline void MemoryBufferVector::readNoCheck(float *result, int x, int y,
MemoryBufferExtend extend_x,
MemoryBufferExtend extend_y)
{
wrap_pixel(x, y, extend_x, extend_y);
const int offset = (this->m_chunkWidth * y + x) * NUMBER_OF_CHANNELS;
BLI_assert(offset >= 0);
BLI_assert(offset < this->determineBufferSize() * NUMBER_OF_CHANNELS);
BLI_assert(!(extend_x == COM_MB_CLIP && (x < m_rect.xmin || x >= m_rect.xmax)) &&
!(extend_y == COM_MB_CLIP && (y < m_rect.ymin || y >= m_rect.ymax)));
copy_v4_v4(result, &this->m_buffer[offset]);
}
inline void MemoryBufferVector::readBilinear(float *result, float x, float y,
MemoryBufferExtend extend_x,
MemoryBufferExtend extend_y)
{
int x1 = floor(x);
int y1 = floor(y);
int x2 = x1 + 1;
int y2 = y1 + 1;
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 vector1[NUMBER_OF_CHANNELS];
float vector2[NUMBER_OF_CHANNELS];
float vector3[NUMBER_OF_CHANNELS];
float vector4[NUMBER_OF_CHANNELS];
read(vector1, x1, y1);
read(vector2, x1, y2);
read(vector3, x2, y1);
read(vector4, x2, y2);
vector1[0] = vector1[0] * mvaluey + vector2[0] * valuey;
vector1[1] = vector1[1] * mvaluey + vector2[1] * valuey;
vector1[2] = vector1[2] * mvaluey + vector2[2] * valuey;
vector3[0] = vector3[0] * mvaluey + vector4[0] * valuey;
vector3[1] = vector3[1] * mvaluey + vector4[1] * valuey;
vector3[2] = vector3[2] * mvaluey + vector4[2] * valuey;
result[0] = vector1[0] * mvaluex + vector3[0] * valuex;
result[1] = vector1[1] * mvaluex + vector3[1] * valuex;
result[2] = vector1[2] * mvaluex + vector3[2] * valuex;
}

View File

@@ -0,0 +1,67 @@
/*
* Copyright 2014, 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
*/
class MemoryBufferVector;
#ifndef _COM_MemoryBufferVector_h_
#define _COM_MemoryBufferVector_h_
#include "COM_MemoryBuffer.h"
class MemoryBufferVector: public MemoryBuffer
{
protected:
/**
* @brief construct new MemoryBuffer for a chunk
*/
MemoryBufferVector(MemoryProxy *memoryProxy, unsigned int chunkNumber, rcti *rect);
/**
* @brief construct new temporarily MemoryBuffer for an area
*/
MemoryBufferVector(MemoryProxy *memoryProxy, rcti *rect);
MemoryBufferVector(DataType datatype, rcti *rect);
public:
void writePixel(int x, int y, const float *color);
void addPixel(int x, int y, const float *color);
void read(float *result, int x, int y,
MemoryBufferExtend extend_x = COM_MB_CLIP,
MemoryBufferExtend extend_y = COM_MB_CLIP);
void readNoCheck(float *result, int x, int y,
MemoryBufferExtend extend_x = COM_MB_CLIP,
MemoryBufferExtend extend_y = COM_MB_CLIP);
void readBilinear(float *result, float x, float y,
MemoryBufferExtend extend_x = COM_MB_CLIP,
MemoryBufferExtend extend_y = COM_MB_CLIP);
MemoryBuffer *duplicate();
friend class MemoryBuffer;
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("COM:MemoryBufferVector")
#endif
};
#endif

View File

@@ -23,10 +23,11 @@
#include "COM_MemoryProxy.h"
MemoryProxy::MemoryProxy()
MemoryProxy::MemoryProxy(DataType type)
{
this->m_writeBufferOperation = NULL;
this->m_executor = NULL;
this->m_datatype = type;
}
void MemoryProxy::allocate(unsigned int width, unsigned int height)
@@ -37,7 +38,7 @@ void MemoryProxy::allocate(unsigned int width, unsigned int height)
result.ymin = 0;
result.ymax = height;
this->m_buffer = new MemoryBuffer(this, 1, &result);
this->m_buffer = MemoryBuffer::create(this, 1, &result);
}
void MemoryProxy::free()

View File

@@ -47,12 +47,7 @@ private:
* @brief reference to the executor. the Execution group that can fill a chunk
*/
ExecutionGroup *m_executor;
/**
* @brief datatype of this MemoryProxy
*/
/* DataType m_datatype; */ /* UNUSED */
/**
* @brief channel information of this buffer
*/
@@ -63,8 +58,13 @@ private:
*/
MemoryBuffer *m_buffer;
/**
* @brief datatype of this MemoryProxy
*/
DataType m_datatype;
public:
MemoryProxy();
MemoryProxy(DataType type);
/**
* @brief set the ExecutionGroup that can be scheduled to calculate a certain chunk.
@@ -104,6 +104,8 @@ public:
*/
inline MemoryBuffer *getBuffer() { return this->m_buffer; }
inline DataType getDataType() { return this->m_datatype; }
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("COM:MemoryProxy")
#endif

View File

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

View File

@@ -24,6 +24,18 @@
#include "COM_WorkScheduler.h"
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)
{
@@ -72,6 +84,21 @@ cl_mem OpenCLDevice::COM_clAttachMemoryBufferToKernelParameter(cl_kernel kernel,
return COM_clAttachMemoryBufferToKernelParameter(kernel, parameterIndex, offsetIndex, cleanup, inputMemoryBuffers, (ReadBufferOperation *)reader);
}
const cl_image_format* OpenCLDevice::determineImageFormat(MemoryBuffer *memoryBuffer)
{
const cl_image_format *imageFormat;
int no_channels = memoryBuffer->get_no_channels();
if (no_channels == 1) {
imageFormat = &IMAGE_FORMAT_VALUE;
} else if (no_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,
list<cl_mem> *cleanup, MemoryBuffer **inputMemoryBuffers,
ReadBufferOperation *reader)
@@ -80,12 +107,9 @@ cl_mem OpenCLDevice::COM_clAttachMemoryBufferToKernelParameter(cl_kernel kernel,
MemoryBuffer *result = reader->getInputMemoryBuffer(inputMemoryBuffers);
const cl_image_format imageFormat = {
CL_RGBA,
CL_FLOAT
};
const cl_image_format *imageFormat = determineImageFormat(result);
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);
if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); }
@@ -192,5 +216,4 @@ cl_kernel OpenCLDevice::COM_clCreateKernel(const char *kernelname, list<cl_kerne
if (clKernelsToCleanUp) clKernelsToCleanUp->push_back(kernel);
}
return kernel;
}

View File

@@ -94,6 +94,13 @@ public:
*/
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_command_queue getQueue() { return this->m_queue; }

View File

@@ -0,0 +1,83 @@
/*
* 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_OutputSocket_h
#define _COM_OutputSocket_h
#include <vector>
#include "COM_Socket.h"
using namespace std;
class SocketConnection;
class Node;
class InputSocket;
class WriteBufferOperation;
//#define COM_ST_INPUT 0
//#define COM_ST_OUTPUT 1
/**
* @brief OutputSocket are sockets that can send data/input
* @ingroup Model
*/
class OutputSocket : public Socket {
private:
vector<SocketConnection *> m_connections;
void removeFirstConnection();
public:
OutputSocket(DataType datatype);
OutputSocket(DataType datatype, int inputSocketDataTypeDeterminatorIndex);
OutputSocket(OutputSocket *from);
void addConnection(SocketConnection *connection);
void removeConnection(SocketConnection *connection);
SocketConnection *getConnection(unsigned int index) { return this->m_connections[index]; }
const int isConnected() const;
int isOutputSocket() const;
/**
* @brief determine the resolution of this socket
* @param resolution the result of this operation
* @param preferredResolution the preferable resolution as no resolution could be determined
*/
void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]);
/**
* @brief determine the actual data type and channel info.
*/
void relinkConnections(OutputSocket *relinkToSocket) { this->relinkConnections(relinkToSocket, false); }
void relinkConnections(OutputSocket *relinkToSocket, bool single);
const int getNumberOfConnections() { return this->m_connections.size(); }
void clearConnections();
/**
* @brief find a connected write buffer operation to this OutputSocket
* @return WriteBufferOperation or NULL
*/
WriteBufferOperation *findAttachedWriteBufferOperation() const;
ChannelInfo *getChannelInfo(const int channelnumber);
private:
};
#endif

View File

@@ -0,0 +1,126 @@
/*
* 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_SocketConnection_h
#define _COM_SocketConnection_h
#include "DNA_node_types.h"
#include "COM_Node.h"
#include "COM_Socket.h"
/**
* @brief An SocketConnection is an connection between an InputSocket and an OutputSocket.
*
* <pre>
* +----------+ To InputSocket +----------+
* | From | SocketConnection \| To Node |
* | Node *====================* |
* | |\ | |
* | | From OutputSocket +----------+
* +----------+
* </pre>
* @ingroup Model
* @see InputSocket
* @see OutputSocket
*/
class SocketConnection {
private:
/**
* @brief Startpoint of the connection
*/
OutputSocket *m_fromSocket;
/**
* @brief Endpoint of the connection
*/
InputSocket *m_toSocket;
/**
* @brief has the resize already been done for this connection
*/
bool m_ignoreResizeCheck;
public:
SocketConnection();
/**
* @brief set the startpoint of the connection
* @param fromsocket
*/
void setFromSocket(OutputSocket *fromsocket);
/**
* @brief get the startpoint of the connection
* @return from OutputSocket
*/
OutputSocket *getFromSocket() const;
/**
* @brief set the endpoint of the connection
* @param tosocket
*/
void setToSocket(InputSocket *tosocket);
/**
* @brief get the endpoint of the connection
* @return to InputSocket
*/
InputSocket *getToSocket() const;
/**
* @brief check if this connection is valid
*/
bool isValid() const;
/**
* @brief return the Node where this connection is connected from
*/
NodeBase *getFromNode() const;
/**
* @brief return the Node where this connection is connected to
*/
NodeBase *getToNode() const;
/**
* @brief set, whether the resize has already been done for this SocketConnection
*/
void setIgnoreResizeCheck(bool check) { this->m_ignoreResizeCheck = check; }
/**
* @brief has the resize already been done for this SocketConnection
*/
bool isIgnoreResizeCheck() const { return this->m_ignoreResizeCheck; }
/**
* @brief does this SocketConnection need resolution conversion
* @note PreviewOperation's will be ignored
* @note Already converted SocketConnection's will be ignored
* @return needs conversion [true:false]
*/
bool needsResolutionConversion() const;
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("COM:SocketConnection")
#endif
};
#endif

View File

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

View File

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

View File

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

View File

@@ -138,7 +138,7 @@ void CompositorOperation::executeRegion(rcti *rect, unsigned int tileNumber)
int y2 = rect->ymax;
int offset = (y1 * this->getWidth() + x1);
int add = (this->getWidth() - (x2 - x1));
int offset4 = offset * COM_NUMBER_OF_CHANNELS;
int offset4 = offset * COM_NO_CHANNELS_COLOR;
int x;
int y;
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);
zbuffer[offset] = color[0];
offset4 += COM_NUMBER_OF_CHANNELS;
offset4 += COM_NO_CHANNELS_COLOR;
offset++;
if (isBreaked()) {
breaked = true;
}
}
offset += add;
offset4 += add * COM_NUMBER_OF_CHANNELS;
offset4 += add * COM_NO_CHANNELS_COLOR;
}
}

View File

@@ -22,7 +22,6 @@
#include "COM_ConvertOperation.h"
ConvertBaseOperation::ConvertBaseOperation()
{
this->m_inputOperation = NULL;
@@ -49,9 +48,9 @@ ConvertValueToColorOperation::ConvertValueToColorOperation() : ConvertBaseOperat
void ConvertValueToColorOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
{
float inputValue[4];
this->m_inputOperation->readSampled(inputValue, x, y, sampler);
output[0] = output[1] = output[2] = inputValue[0];
float value;
this->m_inputOperation->readSampled(&value, x, y, sampler);
output[0] = output[1] = output[2] = value;
output[3] = 1.0f;
}
@@ -98,7 +97,9 @@ ConvertColorToVectorOperation::ConvertColorToVectorOperation() : ConvertBaseOper
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);
}
@@ -112,12 +113,9 @@ ConvertValueToVectorOperation::ConvertValueToVectorOperation() : ConvertBaseOper
void ConvertValueToVectorOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
{
float input[4];
this->m_inputOperation->readSampled(input, x, y, sampler);
output[0] = input[0];
output[1] = input[0];
output[2] = input[0];
output[3] = 0.0f;
float value;
this->m_inputOperation->readSampled(&value, x, y, sampler);
output[0] = output[1] = output[2] = value;
}
@@ -131,7 +129,7 @@ ConvertVectorToColorOperation::ConvertVectorToColorOperation() : ConvertBaseOper
void ConvertVectorToColorOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
{
this->m_inputOperation->readSampled(output, x, y, sampler);
this->m_inputOperation->readSampled(output, x, y, sampler);
output[3] = 1.0f;
}

View File

@@ -82,18 +82,18 @@ void DilateErodeThresholdOperation::executePixel(float output[4], int x, int y,
const int bufferWidth = BLI_rcti_size_x(rect);
int offset;
this->m_inputProgram->read(inputValue, x, y, NULL);
if (inputValue[0] > sw) {
inputBuffer->read(inputValue, x, y);
if (inputValue[0] > sw) {
for (int yi = miny; yi < maxy; yi++) {
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++) {
if (buffer[offset] < sw) {
const float dx = xi - x;
const float dis = dx * dx + dy * dy;
mindist = min(mindist, dis);
}
offset += 4;
offset ++;
}
}
pixelvalue = -sqrtf(mindist);
@@ -101,14 +101,14 @@ void DilateErodeThresholdOperation::executePixel(float output[4], int x, int y,
else {
for (int yi = miny; yi < maxy; yi++) {
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++) {
if (buffer[offset] > sw) {
const float dx = xi - x;
const float dis = dx * dx + dy * dy;
mindist = min(mindist, dis);
}
offset += 4;
offset ++;
}
}
@@ -193,7 +193,7 @@ void DilateDistanceOperation::executePixel(float output[4], int x, int y, void *
const float mindist = distance * distance;
MemoryBuffer *inputBuffer = (MemoryBuffer *)data;
float *buffer = inputBuffer->getBuffer();
float *buffer = inputBuffer->getBuffer();
rcti *rect = inputBuffer->getRect();
const int minx = max(x - this->m_scope, rect->xmin);
const int miny = max(y - this->m_scope, rect->ymin);
@@ -206,17 +206,17 @@ void DilateDistanceOperation::executePixel(float output[4], int x, int y, void *
for (int yi = miny; yi < maxy; yi++) {
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++) {
const float dx = xi - x;
const float dis = dx * dx + dy * dy;
if (dis <= mindist) {
value = max(buffer[offset], value);
}
offset += 4;
offset ++;
}
}
output[0] = value;
output[0] = value;
}
void DilateDistanceOperation::deinitExecution()
@@ -280,14 +280,14 @@ void ErodeDistanceOperation::executePixel(float output[4], int x, int y, void *d
for (int yi = miny; yi < maxy; yi++) {
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++) {
const float dx = xi - x;
const float dis = dx * dx + dy * dy;
if (dis <= mindist) {
value = min(buffer[offset], value);
}
offset += 4;
offset ++;
}
}
output[0] = value;
@@ -383,7 +383,7 @@ void *DilateStepOperation::initializeTileData(rcti *rect)
buf[x] = -MAXFLOAT;
}
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++) {
@@ -510,7 +510,7 @@ void *ErodeStepOperation::initializeTileData(rcti *rect)
buf[x] = MAXFLOAT;
}
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++) {

View File

@@ -129,16 +129,16 @@ void *FastGaussianBlurOperation::initializeTileData(rcti *rect)
this->m_sy = this->m_data.sizey * this->m_size / 2.0f;
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_NO_CHANNELS_COLOR; ++c)
IIR_gauss(copy, this->m_sx, c, 3);
}
else {
if (this->m_sx > 0.0f) {
for (c = 0; c < COM_NUMBER_OF_CHANNELS; ++c)
for (c = 0; c < COM_NO_CHANNELS_COLOR; ++c)
IIR_gauss(copy, this->m_sx, c, 1);
}
if (this->m_sy > 0.0f) {
for (c = 0; c < COM_NUMBER_OF_CHANNELS; ++c)
for (c = 0; c < COM_NO_CHANNELS_COLOR; ++c)
IIR_gauss(copy, this->m_sy, c, 2);
}
}
@@ -170,7 +170,7 @@ void *FastGaussianBlurOperation::initializeTileData(rcti *rect)
dai.ymin = max(dai.ymin, buf_rect->ymin);
dai.ymax = min(dai.ymax, buf_rect->ymax);
MemoryBuffer *tile = new MemoryBuffer(NULL, &dai);
MemoryBuffer *tile = MemoryBuffer::create(COM_DT_COLOR, &dai);
tile->copyContentFrom(buffer);
int c;
@@ -178,16 +178,16 @@ void *FastGaussianBlurOperation::initializeTileData(rcti *rect)
float sy = this->m_data.sizey * this->m_size / 2.0f;
if ((sx == sy) && (sx > 0.f)) {
for (c = 0; c < COM_NUMBER_OF_CHANNELS; ++c)
for (c = 0; c < COM_NO_CHANNELS_COLOR; ++c)
IIR_gauss(tile, sx, c, 3);
}
else {
if (sx > 0.0f) {
for (c = 0; c < COM_NUMBER_OF_CHANNELS; ++c)
for (c = 0; c < COM_NO_CHANNELS_COLOR; ++c)
IIR_gauss(tile, sx, c, 1);
}
if (sy > 0.0f) {
for (c = 0; c < COM_NUMBER_OF_CHANNELS; ++c)
for (c = 0; c < COM_NO_CHANNELS_COLOR; ++c)
IIR_gauss(tile, sy, c, 2);
}
}
@@ -217,6 +217,7 @@ void FastGaussianBlurOperation::IIR_gauss(MemoryBuffer *src, float sigma, unsign
unsigned int x, y, sz;
unsigned int i;
float *buffer = src->getBuffer();
const unsigned int no_channels = src->get_no_channels();
// <0.5 not valid, though can have a possibly useful sort of sharpening effect
if (sigma < 0.5f) return;
@@ -295,31 +296,31 @@ void FastGaussianBlurOperation::IIR_gauss(MemoryBuffer *src, float sigma, unsign
int offset;
for (y = 0; y < src_height; ++y) {
const int yx = y * src_width;
offset = yx * COM_NUMBER_OF_CHANNELS + chan;
offset = yx * no_channels + chan;
for (x = 0; x < src_width; ++x) {
X[x] = buffer[offset];
offset += COM_NUMBER_OF_CHANNELS;
offset += no_channels;
}
YVV(src_width);
offset = yx * COM_NUMBER_OF_CHANNELS + chan;
offset = yx * no_channels + chan;
for (x = 0; x < src_width; ++x) {
buffer[offset] = Y[x];
offset += COM_NUMBER_OF_CHANNELS;
offset += no_channels;
}
}
}
if (xy & 2) { // V
int offset;
const int add = src_width * COM_NUMBER_OF_CHANNELS;
const int add = src_width * no_channels;
for (x = 0; x < src_width; ++x) {
offset = x * COM_NUMBER_OF_CHANNELS + chan;
offset = x * no_channels + chan;
for (y = 0; y < src_height; ++y) {
X[y] = buffer[offset];
offset += add;
}
YVV(src_height);
offset = x * COM_NUMBER_OF_CHANNELS + chan;
offset = x * no_channels + chan;
for (y = 0; y < src_height; ++y) {
buffer[offset] = Y[y];
offset += add;
@@ -395,7 +396,7 @@ void *FastGaussianBlurValueOperation::initializeTileData(rcti *rect)
if (this->m_overlay == FAST_GAUSS_OVERLAY_MIN) {
float *src = newBuf->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_NO_CHANNELS_VALUE, dst += COM_NO_CHANNELS_VALUE) {
if (*src < *dst) {
*dst = *src;
}
@@ -404,15 +405,13 @@ void *FastGaussianBlurValueOperation::initializeTileData(rcti *rect)
else if (this->m_overlay == FAST_GAUSS_OVERLAY_MAX) {
float *src = newBuf->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_NO_CHANNELS_VALUE, dst += COM_NO_CHANNELS_VALUE) {
if (*src > *dst) {
*dst = *src;
}
}
}
// newBuf->
this->m_iirgaus = copy;
}
unlockMutex();

View File

@@ -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' *** */
int step = getStep();
int offsetadd = getOffsetAdd();
int bufferindex = ((xmin - bufferstartx) * 4) + ((ymin - bufferstarty) * 4 * bufferwidth);
int bufferindex = ((xmin - bufferstartx)) + ((ymin - bufferstarty) * bufferwidth);
/* gauss */
float alpha_accum = 0.0f;
float multiplier_accum = 0.0f;
/* 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 */
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;
}
}
bufferindex += offsetadd;
bufferindex += step;
}
/* blend between the max value and gauss blue - gives nice feather */

View File

@@ -108,11 +108,11 @@ void GaussianAlphaYBlurOperation::executePixel(float output[4], int x, int y, vo
float multiplier_accum = 0.0f;
/* 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 */
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;
float value = finv_test(buffer[bufferindex], do_invert);

View File

@@ -293,7 +293,7 @@ void GaussianBlurReferenceOperation::executePixel(float output[4], int x, int y,
int minyr = y - refrady < 0 ? -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_NO_CHANNELS_COLOR * ( (y + minyr) * imgx + x + minxr);
gausstabx = m_maintabs[refradx - 1];
gausstabcentx = gausstabx + refradx;
@@ -301,9 +301,9 @@ void GaussianBlurReferenceOperation::executePixel(float output[4], int x, int y,
gausstabcenty = gausstaby + refrady;
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_NO_CHANNELS_COLOR * imgx) {
src = srcd;
for (j = minxr; j < maxxr; j++, src += COM_NUMBER_OF_CHANNELS) {
for (j = minxr; j < maxxr; j++, src += COM_NO_CHANNELS_COLOR) {
val = gausstabcenty[i] * gausstabcentx[j];
sum += val;

View File

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

View File

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

View File

@@ -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_NO_CHANNELS_COLOR * sizeof(float));
for (n = 1; n < settings->iter && (!breaked); n++) {
for (y = 0; y < gbuf->getHeight() && (!breaked); y++) {
v = ((float)y + 0.5f) / (float)gbuf->getHeight();
@@ -117,9 +117,9 @@ void GlareGhostOperation::generateGlare(float *data, MemoryBuffer *inputTile, No
}
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_NO_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_NO_CHANNELS_COLOR * sizeof(float));
delete gbuf;
delete tbuf1;

View File

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

View File

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

View File

@@ -63,7 +63,7 @@ void KeyingBlurOperation::executePixel(float output[4], int x, int y, void *data
int cx = x + i;
if (cx >= 0 && cx < bufferWidth) {
int bufferIndex = (y * bufferWidth + cx) * 4;
int bufferIndex = (y * bufferWidth + cx);
average += buffer[bufferIndex];
count++;
@@ -75,7 +75,7 @@ void KeyingBlurOperation::executePixel(float output[4], int x, int y, void *data
int cy = y + i;
if (cy >= 0 && cy < bufferHeight) {
int bufferIndex = (cy * bufferWidth + x) * 4;
int bufferIndex = (cy * bufferWidth + x);
average += buffer[bufferIndex];
count++;

View File

@@ -64,7 +64,7 @@ void KeyingClipOperation::executePixel(float output[4], int x, int y, void *data
int i, j, count = 0, totalCount = 0;
float value = buffer[(y * bufferWidth + x) * 4];
float value = buffer[(y * bufferWidth + x)];
bool ok = false;
@@ -76,7 +76,7 @@ void KeyingClipOperation::executePixel(float output[4], int x, int y, void *data
continue;
if (cx >= 0 && cx < bufferWidth && cy >= 0 && cy < bufferHeight) {
int bufferIndex = (cy * bufferWidth + cx) * 4;
int bufferIndex = (cy * bufferWidth + cx);
float currentValue = buffer[bufferIndex];
if (fabsf(currentValue - value) < tolerance) {

View File

@@ -77,17 +77,17 @@ bool MapUVOperation::read_uv(float x, float y, float &r_u, float &r_v, float &r_
float width = m_inputUVProgram->getWidth();
float height = m_inputUVProgram->getHeight();
if (x < 0.0f || x >= width || y < 0.0f || y >= height) {
r_u = 0.0f;
r_u = 0.0f;
r_v = 0.0f;
r_alpha = 0.0f;
return false;
}
else {
float col[4];
m_inputUVProgram->readSampled(col, x, y, COM_PS_BILINEAR);
r_u = col[0] * m_inputColorProgram->getWidth();
r_v = col[1] * m_inputColorProgram->getHeight();
r_alpha = col[2];
float vector[3];
m_inputUVProgram->readSampled(vector, x, y, COM_PS_BILINEAR);
r_u = vector[0] * m_inputColorProgram->getWidth();
r_v = vector[1] * m_inputColorProgram->getHeight();
r_alpha = vector[2];
return true;
}
}

View File

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

View File

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

View File

@@ -24,9 +24,9 @@
#include "COM_WriteBufferOperation.h"
#include "COM_defines.h"
ReadBufferOperation::ReadBufferOperation() : NodeOperation()
ReadBufferOperation::ReadBufferOperation(DataType type) : NodeOperation()
{
this->addOutputSocket(COM_DT_COLOR);
this->addOutputSocket(type);
this->m_single_value = false;
this->m_offset = 0;
this->m_buffer = NULL;

View File

@@ -33,7 +33,7 @@ private:
unsigned int m_offset;
MemoryBuffer *m_buffer;
public:
ReadBufferOperation();
ReadBufferOperation(DataType type);
void setMemoryProxy(MemoryProxy *memoryProxy) { this->m_memoryProxy = memoryProxy; }
MemoryProxy *getMemoryProxy() { return this->m_memoryProxy; }
void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]);

View File

@@ -89,7 +89,6 @@ void RenderLayersBaseProg::doInterpolation(float output[4], float x, float y, Pi
else
zero_v4(output);
break;
}
offset = (iy * width + ix) * this->m_elementsize;
@@ -111,15 +110,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);
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)
@@ -148,7 +138,15 @@ void RenderLayersBaseProg::executePixelSampled(float output[4], float x, float y
#endif
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 {
zero_v4(output);
}
}
else {
doInterpolation(output, ix, iy, sampler);
@@ -210,16 +208,10 @@ void RenderLayersAlphaProg::executePixelSampled(float output[4], float x, float
if (inputBuffer == NULL || ix < 0 || iy < 0 || ix >= (int)this->getWidth() || iy >= (int)this->getHeight() ) {
output[0] = 0.0f;
output[1] = 0.0f;
output[2] = 0.0f;
output[3] = 0.0f;
}
else {
unsigned int offset = (iy * this->getWidth() + ix) * 4;
output[0] = inputBuffer[offset + 3];
output[1] = 0.0f;
output[2] = 0.0f;
output[3] = 0.0f;
}
}
@@ -252,16 +244,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() ) {
output[0] = 0.0f;
output[1] = 0.0f;
output[2] = 0.0f;
output[3] = 0.0f;
}
else {
unsigned int offset = (iy * this->getWidth() + ix);
output[0] = inputBuffer[offset];
output[1] = 0.0f;
output[2] = 0.0f;
output[3] = 0.0f;
}
}

View File

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

View File

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

View File

@@ -137,16 +137,19 @@ void VariableSizeBokehBlurOperation::executePixel(float output[4], int x, int y,
copy_v4_fl(multiplier_accum, 1.0f);
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_NO_CHANNELS_COLOR;
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;
int offsetNy = ny * inputSizeBuffer->getWidth() * COM_NUMBER_OF_CHANNELS;
int offsetNxNy = offsetNy + (minx * COM_NUMBER_OF_CHANNELS);
for (int nx = minx; nx < maxx; nx += QualityStepHelper::getStep()) {
int offsetValueNy = ny * inputSizeBuffer->getWidth();
int offsetValueNxNy = offsetValueNy + (minx);
int offsetColorNxNy = offsetValueNxNy * COM_NO_CHANNELS_COLOR;
for (int nx = minx; nx < maxx; nx += addXStepValue) {
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) {
float dx = nx - x;
if (size > fabsf(dx) && size > fabsf(dy)) {
@@ -154,13 +157,14 @@ void VariableSizeBokehBlurOperation::executePixel(float output[4], int x, int y,
(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)};
inputBokehBuffer->readNoCheck(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);
}
}
}
offsetNxNy += addXStep;
}
offsetColorNxNy += addXStepColor;
offsetValueNxNy += addXStepValue;
}
}
}
@@ -286,7 +290,7 @@ void InverseSearchRadiusOperation::initExecution()
voi *InverseSearchRadiusOperation::initializeTileData(rcti *rect)
{
MemoryBuffer * data = new MemoryBuffer(NULL, rect);
MemoryBuffer * data = MemoryBuffer::(NULL, rect);
float *buffer = data->getBuffer();
int x, y;
int width = this->m_inputRadius->getWidth();

View File

@@ -57,7 +57,7 @@ void VectorBlurOperation::initExecution()
void VectorBlurOperation::executePixel(float output[4], int x, int y, void *data)
{
float *buffer = (float *) data;
int index = (y * this->getWidth() + x) * COM_NUMBER_OF_CHANNELS;
int index = (y * this->getWidth() + x) * COM_NO_CHANNELS_COLOR;
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)
{
float *zbuf = inputZ->convertToValueBuffer();
NodeBlurData blurdata;
blurdata.samples = this->m_settings->samples / QualityStepHelper::getStep();
blurdata.maxspeed = this->m_settings->maxspeed;
blurdata.minspeed = this->m_settings->minspeed;
blurdata.curved = this->m_settings->curved;
blurdata.fac = this->m_settings->fac;
RE_zbuf_accumulate_vecblur(&blurdata, this->getWidth(), this->getHeight(), data, inputImage->getBuffer(), inputSpeed->getBuffer(), zbuf);
MEM_freeN((void *)zbuf);
RE_zbuf_accumulate_vecblur(&blurdata, this->getWidth(), this->getHeight(), data, inputImage->getBuffer(), inputSpeed->getBuffer(), inputZ->getBuffer());
return;
}

View File

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

View File

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

View File

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

View File

@@ -25,10 +25,10 @@
#include <stdio.h>
#include "COM_OpenCLDevice.h"
WriteBufferOperation::WriteBufferOperation() : NodeOperation()
WriteBufferOperation::WriteBufferOperation(DataType type) : NodeOperation()
{
this->addInputSocket(COM_DT_COLOR);
this->m_memoryProxy = new MemoryProxy();
this->addInputSocket(type);
this->m_memoryProxy = new MemoryProxy(type);
this->m_memoryProxy->setWriteBufferOperation(this);
this->m_memoryProxy->setExecutor(NULL);
}
@@ -61,6 +61,7 @@ void WriteBufferOperation::executeRegion(rcti *rect, unsigned int tileNumber)
{
MemoryBuffer *memoryBuffer = this->m_memoryProxy->getBuffer();
float *buffer = memoryBuffer->getBuffer();
const int no_channels = memoryBuffer->get_no_channels();
if (this->m_input->isComplex()) {
void *data = this->m_input->initializeTileData(rect);
int x1 = rect->xmin;
@@ -71,10 +72,10 @@ void WriteBufferOperation::executeRegion(rcti *rect, unsigned int tileNumber)
int y;
bool breaked = false;
for (y = y1; y < y2 && (!breaked); y++) {
int offset4 = (y * memoryBuffer->getWidth() + x1) * COM_NUMBER_OF_CHANNELS;
int offset4 = (y * memoryBuffer->getWidth() + x1) * no_channels;
for (x = x1; x < x2; x++) {
this->m_input->read(&(buffer[offset4]), x, y, data);
offset4 += COM_NUMBER_OF_CHANNELS;
offset4 += no_channels;
}
if (isBreaked()) {
breaked = true;
@@ -96,10 +97,10 @@ void WriteBufferOperation::executeRegion(rcti *rect, unsigned int tileNumber)
int y;
bool breaked = false;
for (y = y1; y < y2 && (!breaked); y++) {
int offset4 = (y * memoryBuffer->getWidth() + x1) * COM_NUMBER_OF_CHANNELS;
int offset4 = (y * memoryBuffer->getWidth() + x1) * no_channels;
for (x = x1; x < x2; x++) {
this->m_input->readSampled(&(buffer[offset4]), x, y, COM_PS_NEAREST);
offset4 += COM_NUMBER_OF_CHANNELS;
offset4 += no_channels;
}
if (isBreaked()) {
breaked = true;
@@ -126,12 +127,9 @@ void WriteBufferOperation::executeOpenCLRegion(OpenCLDevice *device, rcti *rect,
const unsigned int outputBufferWidth = outputBuffer->getWidth();
const unsigned int outputBufferHeight = outputBuffer->getHeight();
const cl_image_format imageFormat = {
CL_RGBA,
CL_FLOAT
};
const cl_image_format *imageFormat = device->determineImageFormat(outputBuffer);
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)); }
// STEP 2

View File

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