Refactoring of tiles opencl implementation:
[blender.git] / source / blender / compositor / operations / COM_WriteBufferOperation.cpp
index 498add2fc870396af21288c318216eed3bbfa259..356ba452185023ea627943361ad78aff12940efb 100644 (file)
 #include "COM_WriteBufferOperation.h"
 #include "COM_defines.h"
 #include <stdio.h>
+#include "COM_OpenCLDevice.h"
 
-WriteBufferOperation::WriteBufferOperation() :NodeOperation()
+WriteBufferOperation::WriteBufferOperation() : NodeOperation()
 {
        this->addInputSocket(COM_DT_COLOR);
        this->memoryProxy = new MemoryProxy();
        this->memoryProxy->setWriteBufferOperation(this);
        this->memoryProxy->setExecutor(NULL);
-       this->tree = NULL;
 }
 WriteBufferOperation::~WriteBufferOperation()
 {
@@ -57,7 +57,7 @@ void WriteBufferOperation::deinitExecution()
        this->memoryProxy->free();
 }
 
-void WriteBufferOperation::executeRegion(rcti *rect, unsigned int tileNumber, MemoryBuffer** memoryBuffers)
+void WriteBufferOperation::executeRegion(rcti *rect, unsigned int tileNumber, MemoryBuffer **memoryBuffers)
 {
        //MemoryBuffer *memoryBuffer = MemoryManager::getMemoryBuffer(this->getMemoryProxy(), tileNumber);
        MemoryBuffer *memoryBuffer = this->memoryProxy->getBuffer();
@@ -71,14 +71,14 @@ void WriteBufferOperation::executeRegion(rcti *rect, unsigned int tileNumber, Me
                int x;
                int y;
                bool breaked = false;
-               for (y = y1 ; y < y2 && (!breaked) ; y++) {
-                       int offset4 = (y*memoryBuffer->getWidth()+x1)*COM_NUMBER_OF_CHANNELS;
-                       for (x = x1 ; x < x2; x++) {
+               for (y = y1; y < y2 && (!breaked); y++) {
+                       int offset4 = (y * memoryBuffer->getWidth() + x1) * COM_NUMBER_OF_CHANNELS;
+                       for (x = x1; x < x2; x++) {
                                input->read(&(buffer[offset4]), x, y, memoryBuffers, data);
-                               offset4 +=COM_NUMBER_OF_CHANNELS;
+                               offset4 += COM_NUMBER_OF_CHANNELS;
 
                        }
-                       if (tree->test_break && tree->test_break(tree->tbh)) {
+                       if (isBreaked()) {
                                breaked = true;
                        }
 
@@ -97,13 +97,13 @@ void WriteBufferOperation::executeRegion(rcti *rect, unsigned int tileNumber, Me
                int x;
                int y;
                bool breaked = false;
-               for (y = y1 ; y < y2 && (!breaked) ; y++) {
-                       int offset4 = (y*memoryBuffer->getWidth()+x1)*COM_NUMBER_OF_CHANNELS;
-                       for (x = x1 ; x < x2 ; x++) {
+               for (y = y1; y < y2 && (!breaked); y++) {
+                       int offset4 = (y * memoryBuffer->getWidth() + x1) * COM_NUMBER_OF_CHANNELS;
+                       for (x = x1; x < x2; x++) {
                                input->read(&(buffer[offset4]), x, y, COM_PS_NEAREST, memoryBuffers);
-                               offset4 +=COM_NUMBER_OF_CHANNELS;
+                               offset4 += COM_NUMBER_OF_CHANNELS;
                        }
-                       if (tree->test_break && tree->test_break(tree->tbh)) {
+                       if (isBreaked()) {
                                breaked = true;
                        }
                }
@@ -111,10 +111,9 @@ void WriteBufferOperation::executeRegion(rcti *rect, unsigned int tileNumber, Me
        memoryBuffer->setCreatedState();
 }
 
-void WriteBufferOperation::executeOpenCLRegion(cl_context context, cl_program program, cl_command_queue queue, rcti *rect, unsigned int chunkNumber, MemoryBuffer** inputMemoryBuffers)
+void WriteBufferOperation::executeOpenCLRegion(OpenCLDevice* device, rcti *rect, unsigned int chunkNumber, MemoryBuffer **inputMemoryBuffers, MemoryBuffer *outputBuffer)
 {
-       MemoryBuffer *outputMemoryBuffer = this->getMemoryProxy()->getBuffer();// @todo wrong implementation needs revision
-       float *outputFloatBuffer = outputMemoryBuffer->getBuffer();
+       float *outputFloatBuffer = outputBuffer->getBuffer();
        cl_int error;
        /*
         * 1. create cl_mem from outputbuffer
@@ -125,47 +124,61 @@ void WriteBufferOperation::executeOpenCLRegion(cl_context context, cl_program pr
         * note: list of cl_mem will be filled by 2, and needs to be cleaned up by 4
         */
        // STEP 1
-       const unsigned int outputBufferWidth = outputMemoryBuffer->getWidth();
-       const unsigned int outputBufferHeight = outputMemoryBuffer->getHeight();
+       const unsigned int outputBufferWidth = outputBuffer->getWidth();
+       const unsigned int outputBufferHeight = outputBuffer->getHeight();
 
        const cl_image_format imageFormat = {
                CL_RGBA,
                CL_FLOAT
        };
 
-       cl_mem clOutputBuffer = clCreateImage2D(context, 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));  }
+       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
-       list<cl_mem> * clMemToCleanUp = new list<cl_mem>();
+       list<cl_mem> *clMemToCleanUp = new list<cl_mem>();
        clMemToCleanUp->push_back(clOutputBuffer);
        list<cl_kernel> *clKernelsToCleanUp = new list<cl_kernel>();
 
-       this->input->executeOpenCL(context, program, queue, outputMemoryBuffer, clOutputBuffer, inputMemoryBuffers, clMemToCleanUp, clKernelsToCleanUp);
+       this->input->executeOpenCL(device, outputBuffer, clOutputBuffer, inputMemoryBuffers, clMemToCleanUp, clKernelsToCleanUp);
 
        // STEP 3
 
-       size_t origin[3] = {0,0,0};
-       size_t region[3] = {outputBufferWidth,outputBufferHeight,1};
+       size_t origin[3] = {0, 0, 0};
+       size_t region[3] = {outputBufferWidth, outputBufferHeight, 1};
 
-       error = clEnqueueBarrier(queue);
-       if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error));  }
-       error = clEnqueueReadImage(queue, clOutputBuffer, CL_TRUE, origin, region, 0, 0, outputFloatBuffer, 0, NULL, NULL);
-       if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error));  }
+//     clFlush(queue);
+//     clFinish(queue);
+
+       error = clEnqueueBarrier(device->getQueue());
+       if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error));  }
+       error = clEnqueueReadImage(device->getQueue(), clOutputBuffer, CL_TRUE, origin, region, 0, 0, outputFloatBuffer, 0, NULL, NULL);
+       if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error));  }
+       
+       this->getMemoryProxy()->getBuffer()->copyContentFrom(outputBuffer);
+       
        // STEP 4
 
-       while (clMemToCleanUp->size()>0) {
+       
+       while (clMemToCleanUp->size() > 0) {
                cl_mem mem = clMemToCleanUp->front();
                error = clReleaseMemObject(mem);
-               if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error));  }
+               if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error));  }
                clMemToCleanUp->pop_front();
        }
 
-       while (clKernelsToCleanUp->size()>0) {
+       while (clKernelsToCleanUp->size() > 0) {
                cl_kernel kernel = clKernelsToCleanUp->front();
                error = clReleaseKernel(kernel);
-               if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error));  }
+               if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error));  }
                clKernelsToCleanUp->pop_front();
        }
        delete clKernelsToCleanUp;
 }
+
+void WriteBufferOperation::readResolutionFromInputSocket()
+{
+       NodeOperation *inputOperation = this->getInputOperation(0);
+       this->setWidth(inputOperation->getWidth());
+       this->setHeight(inputOperation->getHeight());
+}