// 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 Process() { GL.Finish(); screen.Clear(0); timer.Start(); generatie++; // if (generatie % 2 == 1) { // k_sim.SetArgument(0, patroon); // k_sim.SetArgument(1, volgende); // @Todo: dit ook voor de halo kernels // k_copy.SetArgument(0, patroon); // k_copy.SetArgument(1, volgende); // } // else { // k_sim.SetArgument(0, volgende); // k_sim.SetArgument(1, patroon); // k_copy.SetArgument(0, volgende); // k_copy.SetArgument(1, patroon); // } if (GLInterop) { if (resolution != lastResolution) { image = new OpenCLImage <int>(ocl, resolution.x, resolution.y); lastResolution = resolution; k_sim.SetArgument(3, resolution); } k_sim.SetArgument(5, image); k_sim.LockOpenGLObject(image.texBuffer); k_sim.Execute(werk); k_sim.UnlockOpenGLObject(image.texBuffer); } else { k_sim.SetArgument(5, buffer); k_sim.Execute(werk); buffer.CopyFromDevice(); for (int i = 0; i < buffer.Length; ++i) { screen.pixels[i] = buffer[i]; } } k_copy.Execute(werk_klein); // Kopieer wat zojuist in patroon is geschreven naar de tweede buffer timer.Stop(); Console.Write("\r{0}ms", timer.ElapsedMilliseconds); timer.Reset(); }
public void Tick() { GL.Finish(); // clear the screen screen.Clear( 0 ); // do opencl stuff if (GLInterop) kernel.SetArgument( 0, image ); else kernel.SetArgument( 0, buffer ); kernel.SetArgument( 1, t ); t += 0.1f; // execute kernel long [] workSize = { 512, 512 }; long [] localSize = { 32, 4 }; if (GLInterop) { // INTEROP PATH: // Use OpenCL to fill an OpenGL texture; this will be used in the // Render method to draw a screen filling quad. This is the fastest // option, but interop may not be available on older systems. // lock the OpenGL texture for use by OpenCL kernel.LockOpenGLObject( image.texBuffer ); // execute the kernel kernel.Execute( workSize, localSize ); // unlock the OpenGL texture so it can be used for drawing a quad kernel.UnlockOpenGLObject( image.texBuffer ); } else { // 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, localSize ); // get the data from the device to the host buffer.CopyFromDevice(); // plot pixels using the data on the host for( int y = 0; y < 512; y++ ) for( int x = 0; x < 512; x++ ) { screen.pixels[x + y * screen.width] = buffer[x + y * 512]; } } }
// TICK // Main application entry point: the template calls this function once per frame. public void Tick() { // start timer timer.Restart(); // run the simulation, 1 step GL.Finish(); // clear the screen screen.Clear(0); // do opencl stuff if (!GLInterop) { kernel.SetArgument(0, buffer); // if we have an even generation, we set the "pattern" variable in opencl // to the patternBuffer and "second" to the secondBuffer // if the generation is odd, we set "pattern" to secondBuffer and // "second" to patternBuffer // So every generation these buffers get swapped, so we don't have to // manually swap them every time if (generation % 2 == 0) { kernel.SetArgument(4, patternBuffer); kernel.SetArgument(5, secondBuffer); } else { kernel.SetArgument(4, secondBuffer); kernel.SetArgument(5, patternBuffer); } } kernel.SetArgument(6, xoffset); kernel.SetArgument(7, yoffset); // execute kernel long[] workSize = { amountOfCells }; if (GLInterop) { // INTEROP PATH: // Use OpenCL to fill an OpenGL texture; this will be used in the // Render method to draw a screen filling quad. This is the fastest // option, but interop may not be available on older systems. // lock the OpenGL texture for use by OpenCL kernel.LockOpenGLObject( image.texBuffer ); // execute the kernel kernel.Execute( workSize, null ); // Wait for the kernel to finish kernel.Finish(); // execute the copy kernel copyKernel.Execute(workSize, null); // wait for the copykernel to finish copyKernel.Finish(); // unlock the OpenGL texture so it can be used for drawing a quad kernel.UnlockOpenGLObject( image.texBuffer ); } else { // 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, null ); // get the data from the device to the host buffer.CopyFromDevice(); // plot pixels using the data on the host for (int y = 0; y < screenHeight; y++) { for (int x = 0; x < screenWidth; x++) { int index = x + y * screenWidth; screen.pixels[index] = buffer[index]; } } } // 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(); }