private ComputeImage2D CreateImageFromBitmap(string file, ComputeContext ctx, ComputeMemoryFlags flags)
        {
            if (!File.Exists(file))
            {
                throw new FileNotFoundException();
            }

            unsafe
            {
                var bitmap = new Bitmap(file);
                if (bitmap.PixelFormat != PixelFormat.Format32bppArgb)
                {
                    throw new ArgumentException("Pixel format not supported.");
                }

                //ComputeImageFormat format = Tools.ConvertImageFormat(bitmap.PixelFormat);
                ComputeImageFormat format     = new ComputeImageFormat(ComputeImageChannelOrder.Rgba, ComputeImageChannelType.UnsignedInt8);
                BitmapData         bitmapData = bitmap.LockBits(new Rectangle(new Point(), bitmap.Size), ImageLockMode.ReadWrite, bitmap.PixelFormat);
                ComputeImage2D     image;
                try
                {
                    image = new ComputeImage2D(ctx, flags, format, bitmapData.Width, bitmapData.Height,
                                               bitmapData.Stride, bitmapData.Scan0);
                    dstBytes = new char[bitmapData.Width * bitmapData.Height * 4];
                }
                finally
                {
                    bitmap.UnlockBits(bitmapData);
                }
                return(image);
            }
        }
Example #2
0
        public OpenCLImage(OpenCLProgram ocl, int width, int height)
        {
            texData         = new T[width * height * 4];
            OpenGLTextureID = GL.GenTexture();
            GL.BindTexture(TextureTarget.Texture2D, OpenGLTextureID);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest);
            Type itemType = typeof(T);

            if (itemType == typeof(int))
            {
                // create an integer texture (RGBA8, 32bit per pixel)
                GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba8, width, height, 0, OpenTK.Graphics.OpenGL.PixelFormat.Rgb, PixelType.Int, texData);
            }
            else if (itemType == typeof(float))
            {
                // create a floating point texture (RGBA32, 128bit per pixel)
                GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba32f, width, height, 0, OpenTK.Graphics.OpenGL.PixelFormat.Rgb, PixelType.Float, texData);
            }
            else
            {
                ocl.FatalError("Unsupported OpenCLImage format");
            }
            texBuffer = ComputeImage2D.CreateFromGLTexture2D(ocl.context, ComputeMemoryFlags.WriteOnly, (int)TextureTarget.Texture2D, 0, OpenGLTextureID);
        }
Example #3
0
        public void LockOpenGLObject(ComputeImage2D image)
        {
            List <ComputeMemory> c = new List <ComputeMemory>()
            {
                image
            };

            queue.AcquireGLObjects(c, null);
        }
Example #4
0
        public Bitmap ProcessImage(Bitmap inImage)
        {
            ComputeImage2D oclInImage  = null;
            ComputeImage2D oclOutImage = null;

            BitmapData inImageData = inImage.LockBits(new Rectangle(0, 0, inImage.Width, inImage.Height),
                                                      ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);

            Bitmap outImage = new Bitmap(inImage.Width, inImage.Height, PixelFormat.Format32bppArgb);

            BitmapData outImageData = outImage.LockBits(new Rectangle(0, 0, outImage.Width, outImage.Height),
                                                        ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);

            try
            {
                oclInImage = new ComputeImage2D(oclContext, ComputeMemoryFlags.ReadOnly |
                                                ComputeMemoryFlags.CopyHostPointer, new ComputeImageFormat(ComputeImageChannelOrder.Bgra,
                                                                                                           ComputeImageChannelType.UNormInt8), inImage.Width, inImage.Height, 0, inImageData.Scan0);

                oclOutImage = new ComputeImage2D(oclContext, ComputeMemoryFlags.WriteOnly |
                                                 ComputeMemoryFlags.CopyHostPointer, new ComputeImageFormat(ComputeImageChannelOrder.Bgra,
                                                                                                            ComputeImageChannelType.UNormInt8), outImage.Width, outImage.Height, 0, outImageData.Scan0);

                oclKernel.SetMemoryArgument(0, oclInImage);
                oclKernel.SetMemoryArgument(1, oclOutImage);

                oclCommandQueue.Execute(oclKernel, new long[] { 0, 0 }, new long[] { oclInImage.Width,
                                                                                     oclInImage.Height }, null, null);

                oclCommandQueue.Finish();

                oclCommandQueue.ReadFromImage(oclOutImage, outImageData.Scan0, true, null);
            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                inImage.UnlockBits(inImageData);
                outImage.UnlockBits(outImageData);

                if (oclInImage != null)
                {
                    oclInImage.Dispose();
                    oclInImage = null;
                }

                if (oclOutImage != null)
                {
                    oclOutImage.Dispose();
                    oclOutImage = null;
                }
            }

            return(outImage);
        }
Example #5
0
        public void UnlockOpenGLObject(ComputeImage2D image)
        {
            queue.Finish();
            List <ComputeMemory> c = new List <ComputeMemory>()
            {
                image
            };

            queue.ReleaseGLObjects(c, null);
        }
        private void setupCanvas()
        {
            Graphics g = Graphics.FromImage(sourceTemplate);

            g.FillRectangle(Brushes.Black, new Rectangle(0, 0, sourceTemplate.Width, sourceTemplate.Height));
            BitmapData bmd = sourceTemplate.LockBits(new Rectangle(0, 0, sourceTemplate.Width, sourceTemplate.Height), ImageLockMode.ReadWrite, sourceTemplate.PixelFormat);

            canvas = new ComputeImage2D(oclc.Context, ComputeMemoryFlags.CopyHostPointer | ComputeMemoryFlags.ReadWrite, new ComputeImageFormat(ComputeImageChannelOrder.Rgba, ComputeImageChannelType.UnsignedInt8), sourceTemplate.Width, sourceTemplate.Height, 0, bmd.Scan0);
            sourceTemplate.UnlockBits(bmd);
        }
Example #7
0
        private static Float2[] GetResultOfFftFromGpu(ComputeImage2D yGpuImage)
        {
            const int length = n * n;
            var       yGpu   = new Float2[length];

            {
                var tmpBuff        = gpu.CreateBuffer(length);
                var imageToBuffKrn = gpu.GetKernel("transpose.cl", "image_to_buffer");
                imageToBuffKrn.SetMemoryArgument(0, yGpuImage);
                imageToBuffKrn.SetMemoryArgument(1, tmpBuff);
                gpu.Exec2D(imageToBuffKrn, n, n, 16, 16);
                gpu.Queue.ReadFromBuffer(tmpBuff, ref yGpu, true, null);
            }
            return(yGpu);
        }
Example #8
0
        public BitmapSource Diffuse()
        {
            CurrImage = NextImage;
            SetMemoryArguments();

            if (WithLocalMem)
            {
                CQ.Execute(DiffuseKernel, null, new long[] { Width, Height }, new long[] { 28, 8 }, null);
            }
            else
            {
                CQ.Execute(DiffuseKernel, null, new long[] { Width, Height }, null, null);
            }

            return(ReadImageDataFromGPUMemory());
        }
Example #9
0
        public void EnqueueGrayscale(
            ComputeDevice device,
            long[] globalWorkSize,
            ComputeImage2D image,
            ComputeBuffer <byte> grayscaleBuffer,
            ICollection <ComputeEventBase> events)
        {
            events ??= new List <ComputeEventBase>();

            var kernel = _computeManager.GetKernel(device, "grayscale_u8");
            var queue  = _computeManager.GetQueue(device);

            kernel.SetMemoryArgument(0, image);
            kernel.SetMemoryArgument(1, grayscaleBuffer);

            queue.Enqueue(kernel, globalWorkSize: globalWorkSize, events: events);
        }
Example #10
0
        private void InitializeImageFieds()
        {
            int ImageVectorSizeInFloats = Width * Height * 4;

            CurrImageVector = new float[ImageVectorSizeInFloats];
            NextImageVector = new float[ImageVectorSizeInFloats];

            unsafe
            {
                fixed(float *imgPtr = CurrImageVector)
                {
                    ComputeImageFormat format = new ComputeImageFormat(ComputeImageChannelOrder.Rgba, ComputeImageChannelType.Float);

                    CurrImage = new ComputeImage2D(Ctx, ComputeMemoryFlags.ReadWrite | ComputeMemoryFlags.CopyHostPointer, format, Width, Height, Width * 4 * sizeof(float), (IntPtr)imgPtr);
                    NextImage = new ComputeImage2D(Ctx, ComputeMemoryFlags.ReadWrite, format, Width, Height, 0, IntPtr.Zero);
                }
            }
        }
Example #11
0
 public void SetArgument(int i, ComputeImage2D v)
 {
     kernel.SetMemoryArgument(i, v);
 }
Example #12
0
        /// <summary>
        /// Prepare OpenCL program, data buffers, etc.
        /// </summary>
        public void PrepareClBuffers(bool dirty = true)
        {
            clDirty = clDirty || dirty;

            if (texName == 0 ||
                !checkOpenCL.Checked)
            {
                DestroyClBuffers();
                return;
            }

            if (!clDirty)
            {
                return;
            }

            DestroyClBuffers();

            if (clContext == null)
            {
                SetupClContext();
            }
            if (clContext == null) // to be sure
            {
                Util.Log("OpenCL error");
                clImage = null;
                clDirty = true;
                return;
            }

            GL.BindTexture(TextureTarget.Texture2D, 0);
            GL.Finish();
            try
            {
                // OpenCL C source:
                string src = ClInfo.ReadSourceFile(CanUseDouble ? "mandel.cl" : "mandelSingle.cl", "090opencl");
                if (string.IsNullOrEmpty(src))
                {
                    return;
                }

                // program & kernel:
                clProgram = new ComputeProgram(clContext, src);
                clProgram.Build(clContext.Devices, null, null, IntPtr.Zero);
                clKernel     = clProgram.CreateKernel((checkDouble.Checked && CanUseDouble) ? "mandelDouble" : "mandelSingle");
                clCommands   = new ComputeCommandQueue(clContext, clContext.Devices[0], ComputeCommandQueueFlags.None);
                globalWidth  = (texWidth + groupSize - 1) & -groupSize;
                globalHeight = (texHeight + groupSize - 1) & -groupSize;

                // buffers:
                // 1. colormap array
                cmap = new ComputeBuffer <byte>(clContext, ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.CopyHostPointer, colormap);

                bool interopOk = checkInterop.Checked;
                if (interopOk)
                {
                    // 2. CL image for OpenGL interop
                    clImage = ComputeImage2D.CreateFromGLTexture2D(clContext, ComputeMemoryFlags.ReadWrite, (int)TextureTarget.Texture2D, 0, texName);
                    if (clImage == null)
                    {
                        Util.Log("OpenCL cannot reference OpenGL texture!");
                        interopOk = false;
                    }
                }

                // 3. CL output array
                result = new ComputeBuffer <byte>(clContext, ComputeMemoryFlags.ReadWrite, texWidth * texHeight * 4);

                // synced..
                clDirty = false;
            }
            catch (Exception exc)
            {
                Util.LogFormat("OpenCL build error: {0}", exc.Message);
                clImage = null;
                clDirty = true;
            }
        }
 public void DetectText(ComputeContext context, ComputeImage2D image, int width, int height)
 {
 }
Example #14
0
        // initialize renderer: takes in command line parameters passed by template code
        public void Init(int rt, bool gpu, int platformIdx)
        {
            // pass command line parameters
            runningTime = rt;
            useGPU = gpu;
            gpuPlatform = platformIdx;
            // initialize accumulator
            accumulator = new Vector3[screen.width * screen.height];
            // setup scene
            scene = new Scene();
            // setup camera
            camera = new Camera(screen.width, screen.height);
            gpuCamera = new GPUCamera(camera.pos, camera.p1, camera.p2, camera.p3, camera.up, camera.right, screen.width, screen.height, camera.lensSize);

            // initialize max threads
            parallelOptions = new ParallelOptions();
            parallelOptions.MaxDegreeOfParallelism = Environment.ProcessorCount * 2;
            
            // GPU variables
            // pick first platform
            var platform = ComputePlatform.Platforms[gpuPlatform];
            
            // create context with all gpu devices
            if (GLInterop)
            {
                ComputeContextProperty p1 = new ComputeContextProperty(ComputeContextPropertyName.Platform, platform.Handle.Value);
                ComputeContextProperty p2 = new ComputeContextProperty(ComputeContextPropertyName.CL_GL_CONTEXT_KHR, (GraphicsContext.CurrentContext as IGraphicsContextInternal).Context.Handle);
                ComputeContextProperty p3 = new ComputeContextProperty(ComputeContextPropertyName.CL_WGL_HDC_KHR, wglGetCurrentDC());
                ComputeContextPropertyList cpl = new ComputeContextPropertyList(new ComputeContextProperty[] { p1, p2, p3 });
                context = new ComputeContext(ComputeDeviceTypes.Gpu, cpl, null, IntPtr.Zero);
            }
            else
            {
                context = new ComputeContext(ComputeDeviceTypes.Gpu, new ComputeContextPropertyList(platform), null, IntPtr.Zero);
            }

            var streamReader = new StreamReader("../../program.cl");
            string clSource = streamReader.ReadToEnd();
            streamReader.Close();

            // create program with opencl source
            program = new ComputeProgram(context, clSource);

            // compile opencl source
            try
            {
                program.Build(null, null, null, IntPtr.Zero);
            }
            catch
            {
                Console.Write("error in kernel code:\n");
                Console.Write(program.GetBuildLog(context.Devices[0]) + "\n");
            }
            
            // load chosen kernel from program
            kernel = program.CreateKernel("device_function");
            // create some data
            data = new int[screen.width * screen.height];
            // allocate a memory buffer with the message (the int array)
            var flags = ComputeMemoryFlags.WriteOnly | ComputeMemoryFlags.UseHostPointer;
            buffer = new ComputeBuffer<int>(context, flags, data);
            
            kernel.SetMemoryArgument(0, buffer);
            ComputeBuffer<float> skyboxBuffer = new ComputeBuffer<float>(context, flags, Scene.skybox);
            ComputeBuffer<Sphere> sphereBuffer = new ComputeBuffer<Sphere>(context, flags, Scene.sphere);
            ComputeBuffer<Sphere> planeBuffer = new ComputeBuffer<Sphere>(context, flags, Scene.planes);
            kernel.SetMemoryArgument(1, skyboxBuffer);
            kernel.SetValueArgument(2, gpuCamera);
            kernel.SetMemoryArgument(4, sphereBuffer);
            kernel.SetMemoryArgument(5, planeBuffer);
            kernel.SetValueArgument(6, Scene.light);

            // create a command queue with first gpu found
            queue = new ComputeCommandQueue(context, context.Devices[0], 0);
            
            
            ClearAccumulator();
            
            // create a texture to draw to from OpenCL
            if (GLInterop)
            {
                texID = GL.GenTexture();
                GL.BindTexture(TextureTarget.Texture2D, texID);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest);
                GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba32f, 512, 512, 0, OpenTK.Graphics.OpenGL.PixelFormat.Rgb, PixelType.Float, texData);
                flags = ComputeMemoryFlags.WriteOnly;
                texBuffer = ComputeImage2D.CreateFromGLTexture2D(context, flags, (int)TextureTarget.Texture2D, 0, texID);
            }
            

            // initialize dataArray
            int counter = 0;
            for (int y = 0; y < screen.height; y += 12)
            {
                for (int x = 0; x < screen.width; x += 8)
                {
                    //amount.Add(new DataBundle(x, y, 12, 8));
                    dataArray[counter] = new DataBundle(x, y, 8, 12);
                    counter++;
                }
            }
        }
        public void UploadToComputingDevice(bool forceUpdate = false)
        {
            if (OpenGlTextureId.HasValue && !forceUpdate)
            {
                return;
            }

            var textureId = OpenGlTextureId ?? GL.GenTexture();

            OpenGlErrorThrower.ThrowIfAny();

            GL.BindTexture(TextureTarget.Texture2D, textureId);
            OpenGlErrorThrower.ThrowIfAny();

            PixelInternalFormat pixelInternalFormat;

            OpenTK.Graphics.OpenGL.PixelFormat pixelFormat;
            PixelType pixelType;

            // TODO: Нужно создавать текстуру заново при изменении размера изображения!

            unsafe
            {
                fixed(byte *p = Data)
                {
                    if (PixelFormat == ImagePixelFormat.Byte)
                    {
                        pixelType = PixelType.UnsignedByte;
                    }
                    else if (PixelFormat == ImagePixelFormat.Float)
                    {
                        pixelType = PixelType.Float;
                    }
                    else
                    {
                        throw new NotSupportedException();
                    }

                    switch ((uint)Format)
                    {
                    case (uint)ImageFormat.Greyscale:
                        pixelInternalFormat = PixelFormat == ImagePixelFormat.Byte ? PixelInternalFormat.R8 : PixelInternalFormat.R32f;
                        pixelFormat         = OpenTK.Graphics.OpenGL.PixelFormat.Red;
                        break;

                    case (uint)ImageFormat.AmplitudePhase:
                    case (uint)ImageFormat.RealImaginative:
                        pixelInternalFormat = PixelFormat == ImagePixelFormat.Byte ? PixelInternalFormat.Rg8 : PixelInternalFormat.Rg32f;
                        pixelFormat         = OpenTK.Graphics.OpenGL.PixelFormat.Rg;
                        break;

                    case (uint)ImageFormat.RGB:
                        pixelInternalFormat = PixelFormat == ImagePixelFormat.Byte ? PixelInternalFormat.Rgb8 : PixelInternalFormat.Rgb32f;
                        pixelFormat         = OpenTK.Graphics.OpenGL.PixelFormat.Bgr;
                        break;

                    case (uint)ImageFormat.RGBA:
                        pixelInternalFormat = PixelFormat == ImagePixelFormat.Byte ? PixelInternalFormat.Rgba8 : PixelInternalFormat.Rgba32f;
                        pixelFormat         = OpenTK.Graphics.OpenGL.PixelFormat.Bgra;
                        break;

                    default:
                        throw new NotSupportedException($"Неподдерживаемая комбинация {nameof(PixelFormat)} = {PixelFormat}, {nameof(Format)} = {Format}.");
                    }
                }
            }

            if (OpenGlTextureId.HasValue)
            {
                GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, Width, Height, pixelFormat, pixelType, Data);
            }
            else
            {
                GL.TexImage2D(TextureTarget.Texture2D, 0, pixelInternalFormat, Width, Height, 0, pixelFormat, pixelType, Data);
            }

            OpenGlErrorThrower.ThrowIfAny();

            GL.GenerateMipmap(GenerateMipmapTarget.Texture2D);

            GL.TexParameterI(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, new[] { (int)TextureMinFilter.Nearest });
            GL.TexParameterI(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, new[] { (int)TextureMagFilter.Nearest });

            OpenGlErrorThrower.ThrowIfAny();
            OpenGlTextureId = textureId;

            var computeContext = Singleton.Get <OpenClApplication>().ComputeContext;

            ComputeBuffer = ComputeImage2D.CreateFromGLTexture2D(computeContext, ComputeMemoryFlags.ReadWrite, (int)TextureTarget.Texture2D, 0, textureId);

            GL.BindTexture(TextureTarget.Texture2D, 0);
        }
Example #16
0
        public static void CLApply2DLUT(ComputeContext context)
        {
            ComputeImageFormat format = new ComputeImageFormat(ComputeImageChannelOrder.Bgra, ComputeImageChannelType.UnsignedInt8);
            var startTime             = LLTools.TimestampMS();

            #region Visible / Temporary Source
            BitmapData     bitmapData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, bmp.PixelFormat);
            ComputeImage2D source0    = new ComputeImage2D(context, ComputeMemoryFlags.ReadWrite | ComputeMemoryFlags.CopyHostPointer, format, bmp.Width, bmp.Height, bitmapData.Stride, bitmapData.Scan0);
            bmp.UnlockBits(bitmapData);
            #endregion
            #region Infrared Source
            bitmapData = irBmp.LockBits(new Rectangle(0, 0, irBmp.Width, irBmp.Height), ImageLockMode.ReadOnly, irBmp.PixelFormat);
            ComputeImage2D source1 = new ComputeImage2D(context, ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.CopyHostPointer, format, irBmp.Width, irBmp.Height, bitmapData.Stride, bitmapData.Scan0);
            irBmp.UnlockBits(bitmapData);
            #endregion
            #region Output
            ComputeImage2D output = new ComputeImage2D(context, ComputeMemoryFlags.ReadWrite | ComputeMemoryFlags.AllocateHostPointer, format, bmp.Width, bmp.Height, 0, IntPtr.Zero);
            #endregion
            #region Variable Initialization
            ComputeEventList    eventList = new ComputeEventList();
            ComputeCommandQueue commands  = new ComputeCommandQueue(context, context.Devices[0], ComputeCommandQueueFlags.None);
            #region Apply Curve
            applyCurveKernel.SetMemoryArgument(0, source0);
            applyCurveKernel.SetMemoryArgument(1, output);
            applyCurveKernel.SetMemoryArgument(2, curveLutBuffer);
            #endregion
            #region Apply LUT 2D
            apply2DLUTKernel.SetMemoryArgument(0, source1);
            apply2DLUTKernel.SetMemoryArgument(1, output);
            apply2DLUTKernel.SetMemoryArgument(2, source0);
            apply2DLUTKernel.SetMemoryArgument(3, lut2DBuffer);
            #endregion
            #region Reprojection
            var latRangeBuff = new ComputeBuffer <float>(context, ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.CopyHostPointer, latRange);
            var lonRangeBuff = new ComputeBuffer <float>(context, ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.CopyHostPointer, lonRange);
            var coverageBuff = new ComputeBuffer <float>(context, ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.CopyHostPointer, coverage);
            var trimBuff     = new ComputeBuffer <float>(context, ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.CopyHostPointer, trim);
            var sizeBuff     = new ComputeBuffer <uint>(context, ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.CopyHostPointer, size);
            reprojectKernel.SetMemoryArgument(0, source0);
            reprojectKernel.SetMemoryArgument(1, output);
            reprojectKernel.SetValueArgument(2, satelliteLongitude);
            reprojectKernel.SetValueArgument(3, coff);
            reprojectKernel.SetValueArgument(4, cfac);
            reprojectKernel.SetValueArgument(5, loff);
            reprojectKernel.SetValueArgument(6, lfac);
            reprojectKernel.SetValueArgument(7, (uint)(fixAspect ? 1 : 0));
            reprojectKernel.SetValueArgument(8, aspectRatio);
            reprojectKernel.SetMemoryArgument(9, latRangeBuff);
            reprojectKernel.SetMemoryArgument(10, lonRangeBuff);
            reprojectKernel.SetMemoryArgument(11, coverageBuff);
            reprojectKernel.SetMemoryArgument(12, trimBuff);
            reprojectKernel.SetMemoryArgument(13, sizeBuff);
            #endregion
            #endregion
            #region Run Pipeline
            UIConsole.Log("Executing curve kernel");
            commands.Execute(applyCurveKernel, null, new long[] { bmp.Width, bmp.Height }, null, eventList);
            UIConsole.Log("Executing LUT2D kernel");
            commands.Execute(apply2DLUTKernel, null, new long[] { bmp.Width, bmp.Height }, null, eventList);
            UIConsole.Log("Executing kernel");
            commands.Execute(reprojectKernel, null, new long[] { bmp.Width, bmp.Height }, null, eventList);
            #endregion
            #region Dump Bitmap
            UIConsole.Log("Dumping bitmap");
            Bitmap     obmp    = new Bitmap(bmp.Width, bmp.Height, bmp.PixelFormat);
            BitmapData bmpData = obmp.LockBits(new Rectangle(0, 0, obmp.Width, obmp.Height), ImageLockMode.ReadWrite, obmp.PixelFormat);
            commands.ReadFromImage(output, bmpData.Scan0, true, null);
            obmp.UnlockBits(bmpData);

            var delta = LLTools.TimestampMS() - startTime;
            UIConsole.Log($"Took {delta} ms to Apply Curve -> Apply Lut2D (FalseColor) -> Reproject");
            UIConsole.Log("Saving bitmap");
            obmp.Save("teste.png");
            UIConsole.Log("Done");
            bmp.Save("original.png");
            #endregion
        }