예제 #1
0
        public void ImagingTest(string inputImagePath, string outputImagePath)
        {
            ErrorCode error;

            //Load and compile kernel source code.
            string programPath = System.Environment.CurrentDirectory + "/../../imagingtest.cl";  //The path to the source file may vary

            if (!System.IO.File.Exists(programPath))
            {
                Console.WriteLine("Program doesn't exist at path " + programPath);
                return;
            }

            string programSource = System.IO.File.ReadAllText(programPath);

            using (Program program = Cl.CreateProgramWithSource(_context, 1, new[] { programSource }, null, out error))
            {
                CheckErr(error, "Cl.CreateProgramWithSource");

                //Compile kernel source
                error = Cl.BuildProgram(program, 1, new[] { _device }, string.Empty, null, IntPtr.Zero);
                CheckErr(error, "Cl.BuildProgram");

                //Check for any compilation errors
                if (Cl.GetProgramBuildInfo(program, _device, ProgramBuildInfo.Status, out error).CastTo <BuildStatus>()
                    != BuildStatus.Success && 1 == 0)
                {
                    CheckErr(error, "Cl.GetProgramBuildInfo");
                    Console.WriteLine("Cl.GetProgramBuildInfo != Success");
                    Console.WriteLine(Cl.GetProgramBuildInfo(program, _device, ProgramBuildInfo.Log, out error));
                    return;
                }

                //Create the required kernel (entry function)
                Kernel kernel = Cl.CreateKernel(program, "imagingTest", out error);
                CheckErr(error, "Cl.CreateKernel");

                int intPtrSize = 0;
                intPtrSize = Marshal.SizeOf(typeof(IntPtr));

                //Image's RGBA data converted to an unmanaged[] array
                byte[] inputByteArray;
                //OpenCL memory buffer that will keep our image's byte[] data.
                Mem inputImage2DBuffer;

                OpenCL.Net.ImageFormat clImageFormat = new OpenCL.Net.ImageFormat(ChannelOrder.RGBA, ChannelType.Unsigned_Int8);

                int inputImgWidth, inputImgHeight;

                int inputImgBytesSize;

                int inputImgStride;

                //Try loading the input image
                using (FileStream imageFileStream = new FileStream(inputImagePath, FileMode.Open))
                {
                    System.Drawing.Image inputImage = System.Drawing.Image.FromStream(imageFileStream);

                    if (inputImage == null)
                    {
                        Console.WriteLine("Unable to load input image");
                        return;
                    }

                    inputImgWidth  = inputImage.Width;
                    inputImgHeight = inputImage.Height;

                    System.Drawing.Bitmap bmpImage = new System.Drawing.Bitmap(inputImage);

                    //Get raw pixel data of the bitmap
                    //The format should match the format of clImageFormat
                    BitmapData bitmapData = bmpImage.LockBits(new Rectangle(0, 0, bmpImage.Width, bmpImage.Height),
                                                              ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);//inputImage.PixelFormat);

                    inputImgStride    = bitmapData.Stride;
                    inputImgBytesSize = bitmapData.Stride * bitmapData.Height;

                    //Copy the raw bitmap data to an unmanaged byte[] array
                    inputByteArray = new byte[inputImgBytesSize];
                    Marshal.Copy(bitmapData.Scan0, inputByteArray, 0, inputImgBytesSize);

                    //Allocate OpenCL image memory buffer
                    inputImage2DBuffer = (OpenCL.Net.Mem)OpenCL.Net.Cl.CreateImage2D(_context,
                                                                                     OpenCL.Net.MemFlags.CopyHostPtr | OpenCL.Net.MemFlags.ReadOnly, clImageFormat,
                                                                                     (IntPtr)bitmapData.Width, (IntPtr)bitmapData.Height,
                                                                                     (IntPtr)0, inputByteArray, out error);
                    CheckErr(error, "Cl.CreateImage2D input");
                }

                //Unmanaged output image's raw RGBA byte[] array
                byte[] outputByteArray = new byte[inputImgBytesSize];

                //Allocate OpenCL image memory buffer
                OpenCL.Net.Mem outputImage2DBuffer = (OpenCL.Net.Mem)OpenCL.Net.Cl.CreateImage2D(_context, OpenCL.Net.MemFlags.CopyHostPtr | OpenCL.Net.MemFlags.WriteOnly, clImageFormat,
                                                                                                 (IntPtr)inputImgWidth, (IntPtr)inputImgHeight, (IntPtr)0, outputByteArray, out error);

                CheckErr(error, "Cl.CreateImage2D output");

                //Pass the memory buffers to our kernel function
                error  = Cl.SetKernelArg(kernel, 0, (IntPtr)intPtrSize, inputImage2DBuffer);
                error |= Cl.SetKernelArg(kernel, 1, (IntPtr)intPtrSize, outputImage2DBuffer);
                CheckErr(error, "Cl.SetKernelArg");

                //Create a command queue, where all of the commands for execution will be added
                CommandQueue cmdQueue = Cl.CreateCommandQueue(_context, _device, (CommandQueueProperties)0, out error);
                CheckErr(error, "Cl.CreateCommandQueue");

                OpenCL.Net.Event clevent;

                //Copy input image from the host to the GPU.
                IntPtr[] originPtr        = new IntPtr[] { (IntPtr)0, (IntPtr)0, (IntPtr)0 };                          //x, y, z
                IntPtr[] regionPtr        = new IntPtr[] { (IntPtr)inputImgWidth, (IntPtr)inputImgHeight, (IntPtr)1 }; //x, y, z
                IntPtr[] workGroupSizePtr = new IntPtr[] { (IntPtr)inputImgWidth, (IntPtr)inputImgHeight, (IntPtr)1 };
                error = Cl.EnqueueWriteImage(cmdQueue, inputImage2DBuffer, OpenCL.Net.Bool.True, originPtr, regionPtr, (IntPtr)0, (IntPtr)0, inputByteArray, 0, null, out clevent);
                CheckErr(error, "Cl.EnqueueWriteImage");

                //Execute our kernel (OpenCL code)
                //                  CommandQueue q =  new OpenCL.Net.CommandQueue();



                //enqueue nd range kernel

                // error = cmdQueue.EnqueueKernel(cmdQueue, kernel, 2, null, workGroupSizePtr, null, 0, null, out clevent);
                //   OpenCL.Net.Cl.EnqueueNDRangeKernel(
                OpenCL.Net.Cl.EnqueueNDRangeKernel(cmdQueue, kernel, 2, null, workGroupSizePtr, null, 0, null, out clevent);

                CheckErr(error, "Cl.EnqueueNDRangeKernel");

                //Wait for completion of all calculations on the GPU.
                error = Cl.Finish(cmdQueue);
                CheckErr(error, "Cl.Finish");

                //Read the processed image from GPU to raw RGBA data byte[] array
                error = Cl.EnqueueReadImage(cmdQueue, outputImage2DBuffer, OpenCL.Net.Bool.True, originPtr, regionPtr,
                                            (IntPtr)0, (IntPtr)0, outputByteArray, 0, null, out clevent);
                CheckErr(error, "Cl.clEnqueueReadImage");

                //Clean up memory
                Cl.ReleaseKernel(kernel);
                Cl.ReleaseCommandQueue(cmdQueue);

                Cl.ReleaseMemObject(inputImage2DBuffer);
                Cl.ReleaseMemObject(outputImage2DBuffer);

                //Get a pointer to our unmanaged output byte[] array
                GCHandle pinnedOutputArray = GCHandle.Alloc(outputByteArray, GCHandleType.Pinned);
                IntPtr   outputBmpPointer  = pinnedOutputArray.AddrOfPinnedObject();

                //Create a new bitmap with processed data and save it to a file.
                Bitmap outputBitmap = new Bitmap(inputImgWidth, inputImgHeight, inputImgStride, PixelFormat.Format32bppArgb, outputBmpPointer);

                outputBitmap.Save(outputImagePath, System.Drawing.Imaging.ImageFormat.Png);

                pinnedOutputArray.Free();
            }
        }
예제 #2
0
 public MemDebugView(Mem <TElem> mem)
 {
     _mem = mem;
 }
예제 #3
0
 public static ErrorCode SetKernelArg(Kernel kernel, uint argIndex, Mem value)
 {
     return(SetKernelArg(kernel, argIndex, IntPtr.Size, value));
 }
예제 #4
0
 public bool Equals(Mem <T> other)
 {
     return(_handle.ToInt64() == other._handle.ToInt64());
 }
예제 #5
0
 public static InfoBuffer GetImageInfo(Mem image, ImageInfo paramName, out ErrorCode error)
 {
     return(GetInfo(GetImageInfo, image, paramName, out error));
 }