Esempio n. 1
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);
        }
Esempio n. 2
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++;
                }
            }
        }
Esempio n. 3
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 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);
        }