internal OpenCLFractalEngine(OpenTK.Graphics.IGraphicsContext graphicsContext, Platform platform, Device device) { if (graphicsContext == null || !(graphicsContext is OpenTK.Graphics.IGraphicsContextInternal)) { throw new ArgumentException("Invalid graphics context for OpenCLFractalEngine.", "graphicsContext"); } if (platform == null) { throw new ArgumentException("Invalid platform for OpenCLFractalEngine", "platform"); } if (device == null) { throw new ArgumentException("Invalid device for OpenCLFractalEngine", "device"); } this.platform = platform; this.device = device; useLowProfile = !device.ImageSupport; IntPtr curDC = wglGetCurrentDC(); OpenTK.Graphics.IGraphicsContextInternal gCtx = (OpenTK.Graphics.IGraphicsContextInternal)graphicsContext; context = OpenCL.Context.Create(new Device[] { device }, new ContextParam(ContextProperties.Platform, platform), new ContextParam(ContextProperties.GlContext, gCtx.Context.Handle), new ContextParam(ContextProperties.WglHdc, curDC)); iterBlockCount = Util.Clamp((int)device.MaxComputeUnits * 2, 2, 64); string source = null; if (useLowProfile) { source = Kernels.KernelResources.kernels_low_cl; } else { source = Kernels.KernelResources.kernels_cl; } string opts = ""; try{ program = OpenCL.Program.CreateFromSource(context, new string[] { source }); program.Build(new Device[] { device }, opts); } catch (OpenCLCallFailedException ex) { if (ex.ErrorCode == OpenCL.ErrorCode.BuildProgramFailure) { ex.Data.Add("build_log", program.GetBuildLog(device)); } throw ex; } initIteratorsKernel = Kernel.Create(program, "init_iterators_kernel"); resetIteratorsKernel = Kernel.Create(program, "reset_iterators_kernel"); iterateKernel = Kernel.Create(program, "iterate_kernel"); updateStatsKernel = Kernel.Create(program, "update_stats_kernel"); resetOutputKernel = Kernel.Create(program, "reset_output_kernel"); updateOutputKernel = Kernel.Create(program, "update_output_kernel"); glOutputBufferID = 0; queue = CommandQueue.Create(context, device, CommandQueueFlags.ProfilingEnable); fractalBuffer = context.CreateBuffer(MemFlags.ReadOnly, Marshal.SizeOf(typeof(NativeFractal))); branchBuffer = context.CreateBuffer(MemFlags.ReadOnly, Marshal.SizeOf(typeof(NativeBranch)) * NativeFractal.MaxBranches); variWeightBuffer = context.CreateBuffer(MemFlags.ReadOnly, 4 * NativeFractal.MaxBranches * NativeFractal.MaxVariations); iterPosStateBuffer = context.CreateBuffer(MemFlags.ReadWrite, (8 * IteratorCount)); iterColorStateBuffer = context.CreateBuffer(MemFlags.ReadWrite, (8 * IteratorCount)); iterStatBuffer = context.CreateBuffer(MemFlags.ReadWrite, Marshal.SizeOf(typeof(NativeIterStatEntry)) * IteratorCount); globalStatBuffer = context.CreateBuffer(MemFlags.ReadWrite, Marshal.SizeOf(typeof(NativeGlobalStatEntry))); entropyXBuffer = context.CreateBuffer(MemFlags.ReadWrite, (16 * IteratorCount)); entropyCBuffer = context.CreateBuffer(MemFlags.ReadWrite, (4 * IteratorCount)); entropySeedBuffer = context.CreateBuffer(MemFlags.ReadWrite, (4 * IteratorCount)); uint[] seeds = new uint[IteratorCount]; for (int i = 0; i < IteratorCount; i++) { seeds[i] = (uint)rand.Next(65536); } entropySeedBuffer.Write(queue, seeds); paletteSize = new Size(0, 0); paletteImage = null; paletteBuffer = null; if (!useLowProfile) { paletteSampler = Sampler.Create(context, true, AddressingMode.ClampToEdge, FilterMode.Linear); } initIteratorsKernel.SetArgs(entropyXBuffer, entropyCBuffer, entropySeedBuffer); Event initEvt; initIteratorsKernel.EnqueueLaunch(queue, IteratorCount, IterGroupSize, null, out initEvt); initEvt.Wait(); disposeAndNullify(ref initEvt); queue.Finish(); }