예제 #1
0
        public void SetupClContext()
        {
            CanUseDouble = CanUseInterop = false;

            if (clPlatform == null ||
                comboBoxDevice.SelectedIndex >= clPlatform.Devices.Count)
            {
                clDevice  = null;
                clContext = null;
                return;
            }

            try
            {
                clDevice = clPlatform.Devices[comboBoxDevice.SelectedIndex];
                ComputeContextPropertyList properties = new ComputeContextPropertyList(clPlatform);
                IGraphicsContextInternal   ctx        = (IGraphicsContextInternal)GraphicsContext.CurrentContext;
                properties.Add(new ComputeContextProperty(ComputeContextPropertyName.CL_GL_CONTEXT_KHR, ctx.Context.Handle));
                properties.Add(new ComputeContextProperty(ComputeContextPropertyName.CL_WGL_HDC_KHR, OpenGL.wglGetCurrentDC()));
                properties.Add(new ComputeContextProperty(ComputeContextPropertyName.Platform, clPlatform.Handle.Value));
                clContext = new ComputeContext(new ComputeDevice[] { clDevice }, properties, null, IntPtr.Zero);

                // check the double-extension:
                CanUseDouble  = ClInfo.ExtensionCheck(clContext, "cl_khr_fp64");
                CanUseInterop = ClInfo.ExtensionCheck(clContext, "cl_khr_gl_sharing");
                ClInfo.LogCLProperties(clContext, true);
            }
            catch (Exception exc)
            {
                Util.LogFormat("OpenCL error: {0}", exc.Message);
                clDevice  = null;
                clContext = null;
            }

            bool enableDouble = !checkOpenCL.Checked ||
                                CanUseDouble;

            checkDouble.Enabled  = enableDouble;
            checkInterop.Enabled = CanUseInterop;
        }
예제 #2
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;
            }
        }