public override void Allocate(int xRes, int yRes) { queue.Finish(); Deallocate(); this.xRes = xRes; this.yRes = yRes; accumBuffer = context.CreateBuffer(MemFlags.ReadWrite, SubPixelByteSize * AALevel * AALevel * xRes * yRes); GL.GenBuffers(1, out glOutputBufferID); GL.BindBuffer(BufferTarget.PixelUnpackBuffer, glOutputBufferID); GL.BufferData(BufferTarget.PixelUnpackBuffer, (IntPtr)(4 * xRes * yRes), IntPtr.Zero, BufferUsageHint.StreamCopy); GL.BindBuffer(BufferTarget.PixelUnpackBuffer, 0); outputBuffer = OpenCL.Buffer.CreateFromGLBuffer(context, MemFlags.ReadWrite, glOutputBufferID); glOutputTexID = GL.GenTexture(); GL.BindTexture(TextureTarget.Texture2D, glOutputTexID); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.GenerateMipmap, 1); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.LinearMipmapLinear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Clamp); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Clamp); GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, xRes, yRes, 0, PixelFormat.Rgba, PixelType.UnsignedByte, IntPtr.Zero); GL.BindTexture(TextureTarget.Texture2D, 0); }
public override void ApplyPalette(Palette palette) { queue.Finish(); if (palette.Width <= 0 || palette.Height <= 0) { throw new ArgumentException("palette may not be empty."); } disposeAndNullify(ref paletteImage); disposeAndNullify(ref paletteBuffer); paletteSize = new Size(palette.Width, palette.Height); if (useLowProfile) { paletteBuffer = context.CreateBuffer(MemFlags.ReadOnly, 4 * palette.Width * palette.Height); uint[] pixels = new uint[palette.Height * palette.Width]; Color col; int i = 0; for (int y = 0; y < palette.Height; y++) { for (int x = 0; x < palette.Width; x++) { col = palette.GetPixel(x, y); pixels[i] = (0xFF000000 | (uint)col.B << 16 | (uint)col.G << 8 | (uint)col.R); i++; } } paletteBuffer.Write(queue, pixels); } else { paletteImage = context.CreateImage2D(MemFlags.ReadOnly, new ImageFormat(ChannelOrder.Rgba, ChannelType.UnormInt8), palette.Width, palette.Height); uint[,] pixels = new uint[palette.Height, palette.Width]; Color col; for (int y = 0; y < palette.Height; y++) { for (int x = 0; x < palette.Width; x++) { col = palette.GetPixel(x, y); pixels[y, x] = (0xFF000000 | (uint)col.B << 16 | (uint)col.G << 8 | (uint)col.R); } } paletteImage.Write(queue, pixels); } }
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(); }