// Computes the simulation via OpenCL void OpenCLTick() { for (int i = 0; i < patternbuffer.Length; i++) patternbuffer[i] = 0; patternbuffer.CopyToDevice(); secondbuffer.CopyToDevice(); // Set openCL arguments kernel.SetArgument(0, patternbuffer); kernel.SetArgument(1, secondbuffer); kernel.SetArgument(2, pw); kernel.SetArgument(3, ph); // Execute kernel long[] workSize = { pw*32,ph }; // NO INTEROP PATH: // Use OpenCL to fill a C# pixel array, encapsulated in an // OpenCLBuffer<int> object (buffer). After filling the buffer, it // is copied to the screen surface, so the template code can show // it in the window. // execute the kernel kernel.Execute(workSize); // get the data from the device to the host patternbuffer.CopyFromDevice(); // swap buffers for (int i = 0; i < pw * ph; i++) second[i] = patternbuffer[i]; }
// SIMULATE // Takes the pattern in array 'second', and applies the rules of Game of Life to produce the next state // in array 'pattern'. At the end, the result is copied back to 'second' for the next generation. void Simulate() { pattern_buffer.CopyToDevice(); second_buffer.CopyToDevice(); // clear destination pattern // for (int i = 0; i < pw * ph; i++) pattern[i] = 0; long[] worksize_empty = { pw *ph }; empty.Execute(worksize_empty); // process all pixels, skipping one pixel boundary uint w = (pw * 32) - 1, h = ph - 1; long[] worksize_process = { w, h }; process.Execute(worksize_process); /* * for (uint y = 1; y < h; y++) * { * for (uint x = 1; x < w; x++) * { * // count active neighbors * uint n = GetBit(x - 1, y - 1) + GetBit(x, y - 1) + GetBit(x + 1, y - 1) + GetBit(x - 1, y) + * GetBit(x + 1, y) + GetBit(x - 1, y + 1) + GetBit(x, y + 1) + GetBit(x + 1, y + 1); * if ((GetBit(x, y) == 1 && n == 2) || n == 3) BitSet(x, y); * } * } */ // swap buffers //for (int i = 0; i < pw * ph; i++) second[i] = pattern[i]; long[] worksize_swap = { pw *ph }; swap.Execute(worksize_swap); pattern_buffer.CopyFromDevice(); second_buffer.CopyFromDevice(); }
public void Init() { timer.Start(); Console.WriteLine("Initialiseren..."); ReadGoLFile(); patroon.CopyToDevice(); //Kopieer het patroon naar de gpu, waar het zal blijven timer.Stop(); Console.WriteLine("Patroon geladen: ({0}x{1}) in {2}s", size.x, size.y, timer.ElapsedMilliseconds * 0.001f); timer.Reset(); resolutionStart = new int2(screen.width, screen.height); resolution = resolutionStart; lastResolution = resolution; k_sim.SetArgument(0, volgende); k_sim.SetArgument(1, patroon); k_sim.SetArgument(2, size_in_ints); k_sim.SetArgument(3, resolution); k_sim.SetArgument(4, offset); k_copy.SetArgument(0, volgende); k_copy.SetArgument(1, patroon); k_copy.SetArgument(2, size_in_ints.x); k_copy.SetArgument(3, size_in_ints.y); }
public void Tick() { // start timer timer.Restart(); // run the simulation, 1 step inBuffer.CopyToDevice(); kernel.Execute(workSize); outBuffer.CopyFromDevice(); for (int i = 0; i < pw * ph; i++) { _in[i] = 0; } // visualize current state, DRAW FUNCTION -> GPU BONUS. screen.Clear(0); for (uint y = 0; y < screen.height / scale; y++) { for (uint x = 0; x < screen.width / scale; x++) { if (GetBit(x + xoffset, y + yoffset) == 1) { if (scale > 1) { for (uint j = 0; ((j + 1) % scale) != 0; j++) { for (uint i = 0; ((i + 1) % scale) != 0; i++) { screen.Plot((x * scale + i), (y * scale + j), 0xffffff); } } } else { screen.Plot(x, y, 0xffffff); } } } } for (uint y = 0; y < ph; y++) { for (uint x = 0; x < pw * 32; x++) { if (GetBit(x, y) == 1) { BitSet(x, y); } } } string text = "Scale: " + scale + "x"; screen.Print(text, 5, 5, 0xffffff); // report performance Console.WriteLine("generation " + generation++ + ": " + timer.ElapsedMilliseconds + "ms"); }
// TICK // Main application entry point: the template calls this function once per frame. public void Tick() { GL.Finish(); // start timer timer.Restart(); //Initiate work sizes long[] workSize = { pw, ph }; long[] workSize2 = { pw *ph }; //Set kernel arguments kernel.SetArgument(5, xoffset); kernel.SetArgument(6, yoffset); resolution = (int)(zoom * 512); long[] workSize3 = { resolution / 32, resolution }; kernel.SetArgument(7, resolution); // run the simulation, 1 step screen.Clear(0); if (GLinterop) { if (resolution != oldResolution) { image = new OpenCLImage <int>(ocl, resolution, resolution); oldResolution = resolution; } //set image as argument imageClearKernel.SetArgument(0, image); imageClearKernel.LockOpenGLObject(image.texBuffer); imageClearKernel.Execute(workSize3); imageClearKernel.UnlockOpenGLObject(image.texBuffer); //lock image object kernel.SetArgument(0, image); kernel.LockOpenGLObject(image.texBuffer); //run kernel kernel.Execute(workSize); //unlock image object kernel.UnlockOpenGLObject(image.texBuffer); secondKernel.Execute(workSize2); } else { kernel.SetArgument(0, buffer); for (int i = 0; i < buffer.Length; i++) { buffer[i] = 0; } buffer.CopyToDevice(); kernel.Execute(workSize); secondKernel.Execute(workSize2); buffer.CopyFromDevice(); for (uint y = 0; y < screen.height; y++) { for (uint x = 0; x < screen.width; x++) { screen.Plot(x, y, buffer[x + y * 512]); } } } // visualize current state // report performance Console.WriteLine("generation " + generation++ + ": " + timer.ElapsedMilliseconds + "ms"); //Console.ReadLine(); }
// minimalistic .rle file reader for Golly files (see http://golly.sourceforge.net) public void Init() { StreamReader sr = new StreamReader("../../data/turing_js_r.rle"); uint state = 0, n = 0, x = 1, y = 1; while (true) { String line = sr.ReadLine(); if (line == null) { break; // end of file } int pos = 0; if (line[pos] == '#') { continue; /* comment line */ } else if (line[pos] == 'x') // header { String[] sub = line.Split(new char[] { '=', ',' }, StringSplitOptions.RemoveEmptyEntries); pw = ((UInt32.Parse(sub[1]) + 33) / 32); ph = UInt32.Parse(sub[3]) + 2; pattern = new OpenCLBuffer <uint>(ocl, (pw * ph)); second = new OpenCLBuffer <uint>(ocl, (pw * ph)); buffer = new OpenCLBuffer <int>(ocl, 512 * 512); kernel.SetArgument(3, pw); kernel.SetArgument(4, ph); } else { while (pos < line.Length) { Char c = line[pos++]; if (state == 0) { if (c < '0' || c > '9') { state = 1; n = Math.Max(n, 1); } else { n = (uint)(n * 10 + (c - '0')); } } if (state == 1) // expect other character { if (c == '$') { y += n; x = 1; } // newline else if (c == 'o') { for (int i = 0; i < n; i++) { BitSet(x++, y); } } else if (c == 'b') { x += n; } state = n = 0; } } } } // swap buffers for (int i = 0; i < pw * ph; i++) { second[i] = pattern[i]; } kernel.SetArgument(1, pattern); kernel.SetArgument(2, second); secondKernel.SetArgument(0, pattern); secondKernel.SetArgument(1, second); second.CopyToDevice(); }