// initialize renderer: takes in command line parameters passed by template code public void Init(int rt, bool gpu, int platformIdx) { // pass command line parameters runningTime = rt; useGPU = gpu; gpuPlatform = platformIdx; // initialize accumulator accumulator = new Vector3[screen.width * screen.height]; ClearAccumulator(); // setup scene scene = new Scene(); // setup camera camera = new Camera(screen.width, screen.height); // Generate randoms Console.Write("Generating randoms....\t"); randoms = new float[1000]; Random r = RTTools.GetRNG(); for (int i = 0; i < 1000; i++) { randoms[i] = (float)r.NextDouble(); } int variable = r.Next(); Console.WriteLine("Done!"); // initialize required opencl things if gpu is used if (useGPU) { StreamReader streamReader = new StreamReader("../../kernel.cl"); string clSource = streamReader.ReadToEnd(); streamReader.Close(); platform = ComputePlatform.Platforms[0]; context = new ComputeContext(ComputeDeviceTypes.Gpu, new ComputeContextPropertyList(platform), null, IntPtr.Zero); queue = new ComputeCommandQueue(context, context.Devices[0], ComputeCommandQueueFlags.None); program = new ComputeProgram(context, clSource); try { program.Build(null, null, null, IntPtr.Zero); kernel = program.CreateKernel("Main"); sceneBuffer = new ComputeBuffer <Vector4>(context, ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.UseHostPointer, scene.toCL()); rndBuffer = new ComputeBuffer <float>(context, ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.UseHostPointer, randoms); cameraBuffer = new ComputeBuffer <Vector3>(context, ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.UseHostPointer, camera.toCL()); outputBuffer = new ComputeBuffer <int>(context, ComputeMemoryFlags.WriteOnly | ComputeMemoryFlags.UseHostPointer, screen.pixels); skydome = new ComputeBuffer <float>(context, ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.UseHostPointer, scene.Skydome); kernel.SetMemoryArgument(0, outputBuffer); kernel.SetValueArgument(1, screen.width); kernel.SetValueArgument(2, screen.height); kernel.SetMemoryArgument(3, sceneBuffer); kernel.SetValueArgument(4, scene.toCL().Length); kernel.SetMemoryArgument(5, skydome); kernel.SetMemoryArgument(6, cameraBuffer); kernel.SetMemoryArgument(7, rndBuffer); } catch (ComputeException e) { Console.WriteLine("Error in kernel code: {0}", program.GetBuildLog(context.Devices[0])); Console.ReadLine(); useGPU = false; } } else { return; } }
bool useGPU = true; // GPU code enabled (from commandline) #endregion Fields #region Methods // initialize renderer: takes in command line parameters passed by template code public void Init( int rt, bool gpu, int platformIdx ) { // pass command line parameters runningTime = rt; useGPU = gpu; gpuPlatform = platformIdx; // initialize accumulator accumulator = new Vector3[screen.width * screen.height]; ClearAccumulator(); // setup scene scene = new Scene(); // setup camera camera = new Camera( screen.width, screen.height ); // Generate randoms Console.Write("Generating randoms....\t"); randoms = new float[1000]; Random r = RTTools.GetRNG(); for (int i = 0; i < 1000; i++) randoms[i] = (float)r.NextDouble(); int variable = r.Next(); Console.WriteLine("Done!"); // initialize required opencl things if gpu is used if (useGPU) { StreamReader streamReader = new StreamReader("../../kernel.cl"); string clSource = streamReader.ReadToEnd(); streamReader.Close(); platform = ComputePlatform.Platforms[0]; context = new ComputeContext(ComputeDeviceTypes.Gpu, new ComputeContextPropertyList(platform), null, IntPtr.Zero); queue = new ComputeCommandQueue(context, context.Devices[0], ComputeCommandQueueFlags.None); program = new ComputeProgram(context, clSource); try { program.Build(null, null, null, IntPtr.Zero); kernel = program.CreateKernel("Main"); sceneBuffer = new ComputeBuffer<Vector4>(context, ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.UseHostPointer, scene.toCL()); rndBuffer = new ComputeBuffer<float>(context, ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.UseHostPointer, randoms); cameraBuffer = new ComputeBuffer<Vector3>(context, ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.UseHostPointer, camera.toCL()); outputBuffer = new ComputeBuffer<int>(context, ComputeMemoryFlags.WriteOnly | ComputeMemoryFlags.UseHostPointer, screen.pixels); skydome = new ComputeBuffer<float>(context, ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.UseHostPointer, scene.Skydome); kernel.SetMemoryArgument(0, outputBuffer); kernel.SetValueArgument(1, screen.width); kernel.SetValueArgument(2, screen.height); kernel.SetMemoryArgument(3, sceneBuffer); kernel.SetValueArgument(4, scene.toCL().Length); kernel.SetMemoryArgument(5, skydome); kernel.SetMemoryArgument(6, cameraBuffer); kernel.SetMemoryArgument(7, rndBuffer); } catch (ComputeException e) { Console.WriteLine("Error in kernel code: {0}", program.GetBuildLog(context.Devices[0])); Console.ReadLine(); useGPU = false; } } else { return; } }
// tick: renders one frame public void Tick() { // initialize timer if (firstFrame) { timer.Reset(); timer.Start(); firstFrame = false; } // handle keys, only when running time set to -1 (infinite) if (runningTime == -1) { if (camera.HandleInput()) { // camera moved; restart ClearAccumulator(); } } // render if (false) // if (useGPU) { // add your CPU + OpenCL path here // mind the gpuPlatform parameter! This allows us to specify the platform on our // test system. // note: it is possible that the automated test tool provides you with a different // platform number than required by your hardware. In that case, you can hardcode // the platform during testing (ignoring gpuPlatform); do not forget to put back // gpuPlatform before submitting! long[] workSize = { screen.width, screen.height }; long[] localSize = { 16, 2 }; queue.Execute(kernel, null, workSize, null, null); queue.Finish(); queue.ReadFromBuffer(outputBuffer, ref screen.pixels, true, null); Console.WriteLine(screen.pixels[0]); Random r = RTTools.GetRNG(); for (int i = 0; i < 1000; i++) { randoms[i] = (float)r.NextDouble(); } rndBuffer = new ComputeBuffer <float>(context, ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.UseHostPointer, randoms); cameraBuffer = new ComputeBuffer <Vector3>(context, ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.UseHostPointer, camera.toCL()); kernel.SetMemoryArgument(6, cameraBuffer); kernel.SetMemoryArgument(7, rndBuffer); } else { // this is your CPU only path float scale = 1.0f / (float)++spp; Parallel.For(0, screen.height, y => { for (int x = 0; x < screen.width; x++) { // generate primary ray Ray ray = camera.Generate(RTTools.GetRNG(), x, y); // trace path int pixelIdx = x + y * screen.width; accumulator[pixelIdx] += Sample(ray, 0, x, y); // plot final color screen.pixels[pixelIdx] = RTTools.Vector3ToIntegerRGB(scale * accumulator[pixelIdx]); } }); } // stop and report when max render time elapsed int elapsedSeconds = (int)(timer.ElapsedMilliseconds / 1000); if (runningTime != -1) { if (elapsedSeconds >= runningTime) { OpenTKApp.Report((int)timer.ElapsedMilliseconds, spp, screen); } } }