public static extern CLBuffer CreateFromGLTexture3D( [In] CLContext context, [In] MemoryFlags flags, [In] int target, [In] int mipLevel, [In] int texture, [Out] out CLResultCode error );
public static extern CLBuffer CreateFromGLRenderbuffer( [In] CLContext context, [In] MemoryFlags flags, [In] int renderBuffer, [Out] out CLResultCode error );
public static extern CLEvent CreateEventFromGLsyncKHR( [In] CLContext context, [In] IntPtr sync, [Out] out CLResultCode error );
public static void Add() { CLResultCode error = CLResultCode.Success; CLPlatform[] platforms = new CLPlatform[1]; CL.GetPlatformIds(1, platforms, out _); CLDevice[] devices = new CLDevice[1]; CL.GetDeviceIds(platforms[0], DeviceType.All, 1, devices, out _); CLContext context = CL.CreateContext(IntPtr.Zero, devices, IntPtr.Zero, IntPtr.Zero, out _); CLProgram program = CL.CreateProgramWithSource(context, File.ReadAllText("Kernels/add_arrays.cl"), out error); error = CL.BuildProgram(program, 1, devices, null, IntPtr.Zero, IntPtr.Zero); if (error != CLResultCode.Success) { throw new Exception(error.ToString()); } CLKernel kernel = CL.CreateKernel(program, "add", out error); Span <float> inputA = new float[] { 1, 24, 5, 43, 41, 56 }; Span <float> inputB = new float[] { 72, -323, -1, 43, -41, -26 }; Span <float> output = stackalloc float[inputA.Length]; CLBuffer bufferA = CL.CreateBuffer(context, MemoryFlags.ReadOnly | MemoryFlags.CopyHostPtr, inputA, out _); CLBuffer bufferB = CL.CreateBuffer(context, MemoryFlags.ReadOnly | MemoryFlags.CopyHostPtr, inputB, out _); CLBuffer outputBuffer = CL.CreateBuffer(context, MemoryFlags.WriteOnly, (UIntPtr)(output.Length * sizeof(float)), IntPtr.Zero, out _); //For outputs I wouldn't use that also enqueueing a ReadBuffer is needed regardless //CLBuffer outputBuffer = CL.CreateBuffer(context, MemoryFlags.WriteOnly | MemoryFlags.UseHostPtr, output, out _); CL.SetKernelArg(kernel, 0, bufferA); CL.SetKernelArg(kernel, 1, bufferB); CL.SetKernelArg(kernel, 2, outputBuffer); CLCommandQueue queue = CL.CreateCommandQueueWithProperties(context, devices[0], IntPtr.Zero, out error); CL.EnqueueNDRangeKernel(queue, kernel, 1, null, new[] { (UIntPtr)inputA.Length }, null, 0, null, out _); CL.EnqueueReadBuffer(queue, outputBuffer, true, UIntPtr.Zero, output, null, out _); foreach (float f in output) { Console.WriteLine(f); } CL.ReleaseMemoryObject(bufferA); CL.ReleaseMemoryObject(bufferB); CL.ReleaseMemoryObject(outputBuffer); CL.ReleaseCommandQueue(queue); CL.ReleaseKernel(kernel); CL.ReleaseProgram(program); CL.ReleaseContext(context); }
public static void ConvertToGrayscale(string inputPath) { CLResultCode error = CLResultCode.Success; //Get a platform CLPlatform[] platforms = new CLPlatform[1]; CL.GetPlatformIds(1, platforms, out _); //Get a device CLDevice[] devices = new CLDevice[1]; CL.GetDeviceIds(platforms[0], DeviceType.Gpu, 1, devices, out _); //Create a context CLContext context = CL.CreateContext(IntPtr.Zero, devices, IntPtr.Zero, IntPtr.Zero, out error); if (error != CLResultCode.Success) { throw new Exception("Error on creating a context"); } //Create the program from source CLProgram program = CL.CreateProgramWithSource(context, File.ReadAllText("Kernels/grayscale.cl"), out error); error = CL.BuildProgram(program, 1, devices, null, IntPtr.Zero, IntPtr.Zero); if (error != CLResultCode.Success) { throw new Exception($"Error on building program: {error}"); } //Get the kernel which we will use CLKernel kernel = CL.CreateKernel(program, "grayscale", out error); ImageFormat inputImageFormat = new ImageFormat { ChannelOrder = ChannelOrder.Bgra, ChannelType = ChannelType.UnsignedInteger8 }; Bitmap inputBitmap = new Bitmap(inputPath); BitmapData inputData = inputBitmap.LockBits(new Rectangle(0, 0, inputBitmap.Width, inputBitmap.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); ImageDescription imageDescription = new ImageDescription() { ImageType = MemoryObjectType.Image2D, Width = (UIntPtr)inputBitmap.Width, Height = (UIntPtr)inputBitmap.Height, Depth = (UIntPtr)1 }; CLImage inputImage = CL.CreateImage(context, MemoryFlags.ReadOnly | MemoryFlags.CopyHostPtr, ref inputImageFormat, ref imageDescription, inputData.Scan0, out error); Bitmap outputBitmap = new Bitmap(inputBitmap.Width, inputBitmap.Height, PixelFormat.Format32bppArgb); BitmapData outputData = outputBitmap.LockBits(new Rectangle(0, 0, inputBitmap.Width, inputBitmap.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); CLImage outputImage = CL.CreateImage(context, MemoryFlags.WriteOnly | MemoryFlags.UseHostPtr, ref inputImageFormat, ref imageDescription, outputData.Scan0, out error); CL.SetKernelArg(kernel, 0, rFact); CL.SetKernelArg(kernel, 1, gFact); CL.SetKernelArg(kernel, 2, bFact); CL.SetKernelArg(kernel, 3, inputImage); CL.SetKernelArg(kernel, 4, outputImage); CLCommandQueue queue = CL.CreateCommandQueueWithProperties(context, devices[0], IntPtr.Zero, out error); CL.EnqueueNDRangeKernel(queue, kernel, 2, new UIntPtr[] { UIntPtr.Zero, UIntPtr.Zero, }, new[] { (UIntPtr)inputBitmap.Width, (UIntPtr)inputBitmap.Height, }, null, 0, null, out _); CL.EnqueueReadImage(queue, outputImage, 1, new UIntPtr[] { UIntPtr.Zero, UIntPtr.Zero, }, new UIntPtr[] { (UIntPtr)inputBitmap.Width, (UIntPtr)inputBitmap.Height, (UIntPtr)1, }, UIntPtr.Zero, UIntPtr.Zero, outputData.Scan0, 0, null, out _); outputBitmap.UnlockBits(outputData); outputBitmap.Save("grayscale.png", System.Drawing.Imaging.ImageFormat.Png); //Dispose of all things inputBitmap.Dispose(); outputBitmap.Dispose(); CL.ReleaseMemoryObject(inputImage); CL.ReleaseMemoryObject(outputImage); CL.ReleaseCommandQueue(queue); CL.ReleaseKernel(kernel); CL.ReleaseProgram(program); CL.ReleaseContext(context); }