Пример #1
0
        // 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];
            // setup scene
            scene = new Scene();
            // setup camera
            camera = new Camera(screen.width, screen.height);
            gpuCamera = new GPUCamera(camera.pos, camera.p1, camera.p2, camera.p3, camera.up, camera.right, screen.width, screen.height, camera.lensSize);

            // initialize max threads
            parallelOptions = new ParallelOptions();
            parallelOptions.MaxDegreeOfParallelism = Environment.ProcessorCount * 2;
            
            // GPU variables
            // pick first platform
            var platform = ComputePlatform.Platforms[gpuPlatform];
            
            // create context with all gpu devices
            if (GLInterop)
            {
                ComputeContextProperty p1 = new ComputeContextProperty(ComputeContextPropertyName.Platform, platform.Handle.Value);
                ComputeContextProperty p2 = new ComputeContextProperty(ComputeContextPropertyName.CL_GL_CONTEXT_KHR, (GraphicsContext.CurrentContext as IGraphicsContextInternal).Context.Handle);
                ComputeContextProperty p3 = new ComputeContextProperty(ComputeContextPropertyName.CL_WGL_HDC_KHR, wglGetCurrentDC());
                ComputeContextPropertyList cpl = new ComputeContextPropertyList(new ComputeContextProperty[] { p1, p2, p3 });
                context = new ComputeContext(ComputeDeviceTypes.Gpu, cpl, null, IntPtr.Zero);
            }
            else
            {
                context = new ComputeContext(ComputeDeviceTypes.Gpu, new ComputeContextPropertyList(platform), null, IntPtr.Zero);
            }

            var streamReader = new StreamReader("../../program.cl");
            string clSource = streamReader.ReadToEnd();
            streamReader.Close();

            // create program with opencl source
            program = new ComputeProgram(context, clSource);

            // compile opencl source
            try
            {
                program.Build(null, null, null, IntPtr.Zero);
            }
            catch
            {
                Console.Write("error in kernel code:\n");
                Console.Write(program.GetBuildLog(context.Devices[0]) + "\n");
            }
            
            // load chosen kernel from program
            kernel = program.CreateKernel("device_function");
            // create some data
            data = new int[screen.width * screen.height];
            // allocate a memory buffer with the message (the int array)
            var flags = ComputeMemoryFlags.WriteOnly | ComputeMemoryFlags.UseHostPointer;
            buffer = new ComputeBuffer<int>(context, flags, data);
            
            kernel.SetMemoryArgument(0, buffer);
            ComputeBuffer<float> skyboxBuffer = new ComputeBuffer<float>(context, flags, Scene.skybox);
            ComputeBuffer<Sphere> sphereBuffer = new ComputeBuffer<Sphere>(context, flags, Scene.sphere);
            ComputeBuffer<Sphere> planeBuffer = new ComputeBuffer<Sphere>(context, flags, Scene.planes);
            kernel.SetMemoryArgument(1, skyboxBuffer);
            kernel.SetValueArgument(2, gpuCamera);
            kernel.SetMemoryArgument(4, sphereBuffer);
            kernel.SetMemoryArgument(5, planeBuffer);
            kernel.SetValueArgument(6, Scene.light);

            // create a command queue with first gpu found
            queue = new ComputeCommandQueue(context, context.Devices[0], 0);
            
            
            ClearAccumulator();
            
            // create a texture to draw to from OpenCL
            if (GLInterop)
            {
                texID = GL.GenTexture();
                GL.BindTexture(TextureTarget.Texture2D, texID);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest);
                GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba32f, 512, 512, 0, OpenTK.Graphics.OpenGL.PixelFormat.Rgb, PixelType.Float, texData);
                flags = ComputeMemoryFlags.WriteOnly;
                texBuffer = ComputeImage2D.CreateFromGLTexture2D(context, flags, (int)TextureTarget.Texture2D, 0, texID);
            }
            

            // initialize dataArray
            int counter = 0;
            for (int y = 0; y < screen.height; y += 12)
            {
                for (int x = 0; x < screen.width; x += 8)
                {
                    //amount.Add(new DataBundle(x, y, 12, 8));
                    dataArray[counter] = new DataBundle(x, y, 8, 12);
                    counter++;
                }
            }
        }
Пример #2
0
        // tick: renders one frame
        public void Tick()
        {
            //float t = 21.5f;
            // 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 (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!
                GL.Finish();
                // clear the screen
                screen.Clear(0);

                // do opencl stuff
                if (GLInterop)
                {
                    kernel.SetMemoryArgument(0, texBuffer);
                }
                else
                {
                    kernel.SetMemoryArgument(0, buffer);
                }
                
                // execute kernel
                //long[] workSize = { screen.width, screen.height };
                long[] localSize = { 8, 12 };
                long [] workSize = { screen.width , screen.height };
                if (GLInterop)
                {
                    List<ComputeMemory> c = new List<ComputeMemory>() { texBuffer };
                    queue.AcquireGLObjects(c, null);
                    queue.Execute(kernel, null, workSize, localSize, null);
                    queue.Finish();
                    queue.ReleaseGLObjects(c, null);
                }
                else
                {
                    camera.Update();
                    gpuCamera = new GPUCamera(camera.pos, camera.p1, camera.p2, camera.p3, camera.up, camera.right, screen.width, screen.height, camera.lensSize);
                    float scale = 1.0f / (float)++spp;
                    kernel.SetValueArgument(2, gpuCamera);
                    kernel.SetValueArgument(3, scale);
                    queue.Execute(kernel, null, workSize, localSize, null);
                    queue.Finish();
                    // fetch results
                    if (!GLInterop)
                    {
                        queue.ReadFromBuffer(buffer, ref data, true, null);

                        // visualize result
                        for (int y = 0; y < screen.height; y++) 
                            for (int x = 0; x < screen.width; x++)
                            {
                                int temp = x + y * screen.width;
                                screen.pixels[temp] = data[temp];
                            }
                    }
                }
            }
            else
            {
                // this is your CPU only path
                float scale = 1.0f / (float)++spp;
                Parallel.For(0, dataArray.Length, parallelOptions, (id) =>
                {
                    for (int j = dataArray[id].y1; j < dataArray[id].y2 && j < screen.height; j++)
                    {
                        for (int i = dataArray[id].x1; i < dataArray[id].x2 && i < screen.width; i++)
                        {
                            // generate primary ray
                            Ray ray = camera.Generate(RTTools.GetRNG(), i, j);
                            // trace path
                            int pixelIdx = i + j * screen.width;
                            accumulator[pixelIdx] += Sample(ray, 0);
                            // 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);
                }
        }