Showing posts with label My Codes. Show all posts
Showing posts with label My Codes. Show all posts

Ph.D thesis: GigaVoxels

I defended my Ph.D thesis on GigaVoxels last July, and the document is now online.

You can download it there:
GigaVoxels: A Voxel-Based Rendering Pipeline For Efficient Exploration Of Large And Detailed Scenes

You can also check my other publications on my Ph.D webpage.


"Interactive Indirect Illumination Using Voxel Cone Tracing" paper (Pacific Graphics 2011)

I am glad to announce that our paper "Interactive Indirect Illumination Using Voxel Cone Tracing" (cf. my previous post http://blog.icare3d.org/2011/06/interactive-indirect-illumination-and.html) has been accepted at Pacific Graphics 2011 !

You can find the authors version of the paper on my research page :
http://www.icare3d.org/research-cat/publications/interactive-indirect-illumination-using-voxel-cone-tracing.html
On my INRIA webpage:

Also, don't forget to attend my talk if you are going to Siggraph 2011 !
Tuesday, 9 August 9:00 am - 10:30 am | West Building, Rooms 109/110

Writing a PhD thesis using FreeMind and LateX : My FreeMind Latex import plug-in

I am currently in the process of writing my PhD thesis, and I discovered that relying on a mind mapping software can in fact revealed very useful especially at the beginning of the process. Indeed, I found mind mapping softwares like FreeMind very useful tools to graphically organize ideas into a hierarchy and that allows you to quickly and very efficiently construct and update the outline of your thesis. 
It is actually easy to export a mindmap from FreeMind into a hierarchy of latex sections, in order to directly get your document structure ready to fill. 
I am actually using this XSLT definition to do so.

The only problem when working like this is that once you have exported your document structure from Freemind into latex, you have made modifications and written some sections into your latex, there is no way to import it back to FreeMind in order to reorganize your document.

To allow this usage, I wrote a small groovy script for FreeMind that read a latex file and build the tree hierarchy out of it. It also imports the content of the sections into the text attribute of the nodes, and this content gets correctly exported by the latex export XSLT.

This script must put into the FreeMind/plugins/script directory, and the following section must be added to the FreeMind/plugins/ScriptingEngine.xml file in order to get the script visible into the Tools menu:

Of course, this code is provided with no warranty, but it should work well :-) 
Have fun !

Old Real-Time GPU Raytracer

I just translated from French to English an old page on my website about a real-time GPU raytracer I developed for fun 4 years ago, during my Master Thesis. It is old school GPGPU in OpenGL and Cg that can run on an NV40 (GeForce 6800). No need for CUDA or a GF110 to do GPU raytracing ! ;-)
The application also features a slow and unoptimized CPU raytracer.

See there: http://www.icare3d.org/myprojects/opengl_projects/raytracer_gpu_full_1.0.html

PS: It is funny to see what was possible at this time, but it was developed quickly and the shader code itself is not a reference !

OpenGL 4.0+ ABuffer V2.0: Linked lists of fragment pages

The main problem with my first ABuffer implementation (cf. my previous post) was that a fixed maximum number of fragments per pixel has to be allocated at initialization time. With this approach, the size of the ABuffer can quickly become very large when the screen resolution and depth complexity of the scene increase.


Using linked lists of fragment pages per pixel

Original basic approach

To try to solve this problem, I implemented a variant of the recent OIT method presented at the GDC2010 by AMD and using per-pixel linked lists. The main difference in my implementation is that fragments are not stored and linked individually but into small pages of fragments (containing 4-6 fragments). Those pages are stored and allocated in a shared pool whose size is changed dynamically depending on the scene demands.
Using pages allows to increase the cache coherency when accessing the fragments, improve the efficiency of concurrent access to the shared pool and decrease the storage cost of the links. This is at the cost of a slight over-allocation of fragments.
The shared pool is composed of a fragment buffer where fragment data is stored, and a link buffer storing links between the pages that are reverse chained. Each pixel of the screen contains the index of the last page it references, as well as a counter with the total number of fragments stored in that pixel (incremented using atomics).
The access to the shared pool is manage through a global page counter, incremented using an atomic operation each time a page is needed by a fragment. The allocation of a page is done by a fragment when it detects that the current page is full, or there is not any page yet for the pixel. This is done inside a critical section to unsure that multiple fragments together in the pipeline and falling into the same pixel will be handled correctly.



ABuffer memory occupancy differences:


Some memory occupancy examples of the fragments storage depending on screen resolution (Basic vs Linked Lists):
  • 512x512:    64MB vs 6.5MB 
  • 768x708:   132.7MB vs 11.7MB
  • 1680x988:  405MB vs 27.42MB

The cost of this huge reduction of the storage need is that the rendering speed decreases compared to the basic approach. Linked lists can be down to half the speed of the basic approach when per-fragment additional costs are low, due to the additional memory access and the increased complexity of the fragment shader (more code, more registers). But this cost seems well amortized when the shading costs per-fragment increase.

Order Independent Transparency (OIT) demo application & source code
New keys:
  • 'x' : Switch between ABuffer Algorithms (V1.0 Basic and V2.0 Linked List)
  • 'n' : Display the number of fragments per pixel.
  • 'g' : Swith between Alpha-Blending and Gelly resolve modes.

UPDATE 28/10/2010: Oscarbg did a port of the demo so that it can run on AMD (mainly removing everything related to shader_load/store), more info there:
http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=285258#Post285258
But sadly still does not work on AMD, so if an AMD guy read that, your help is welcome !
I can't try myself since I don't have any AMD card :-(

    CUDA dynamic template parameters (2/2) : Emulation with metaprogramming

    Following my last post, I will describe how template metaprogramming can be used to "emulate" dynamic kernel template parameters. This approach does not prevent explosion of the amount of generated code at compile time, but provides a simple interface to "transform" runtime variable values into kernel template parameters.

    If you are not familiar with templates metaprogramming, I suggest you to read Andrei Alexandrescu's great book: Modern C++ Design: Generic Programming and Design Patterns Applied. This book comes with a small and simple metaprogramming library called Loki that is just a series of helper headers. My code relies on a few structures from it.

    Code description
    Here is what a kernel call looks like with this mechanism:

    The actual kernel call is encapsulated into a functor (here MyKernelCallFunctor) that is passed, with the runtime variables, to the call function of what I called the KernelCaller. The KernelCaller "transform" the set of runtime variables passed to the call function into a set of compile time parameters passed to the functor in the form of a typelist.
    The functor is in charge making the actual kernel call by extracting the template values from the typelist, and by passing to the __global__ function the arguments previously passed through it's constructor and stored into the structure. It has to be written for each kernel you want to launch:

    The KernelCaller is the core of the mechanism. It operates by recursively adding static values into the typelist by testing the value of the runtime variables. In reallity the compiler will generate code for all the branches and so will instanciate all possible sets of compile time parameters as typelists, the right one being selected at runtime. To ease usage, the runtime variables are passed using a variable argument list and transformed into a vector containing the values.

    The compile time recursion is stopped thanks to the number of arguments passed as a template parameter to the KernelCaller.  :

    Here it is, as is we already have a working mechanism able to deal with arbitrary number of boolean parameters !

    Extending the approach to integer parameters
    The approach as presented here works well for boolean template parameters. If we want to deal with more values than 0/1 per variable, we need to write something like this:

    But this is not very funny to write and not very scalable. So once again we can rely on templates to generate the code for us !
    In this case here is what the KernelCaller::call function looks like:

    And here is the ValueSelector mechanism:


    Loki structures
    Here are the Loki structures we rely on:


    Full source code
    A full running sample code can be downloaded here.

    Have fun, and... sorry for this crazy long post !

    [Update June 21]
    Code updated: There was 2 bugs in the code :
    • Using a reference as first parameter of a vararg is forbiden by C++ and resulted in a crash on 32bits machines -> transformed into a pointer.
    • The MaxArgValue argument to the KernelCaller was not kept by the ValueSelector, resulting in the use of the default value of 10 whatever the user specified so it was very slow to compile even for boolean values.
    I added two #defines to control the sample kernel call: SAMPLE_NUMBER_OF_PARAMS indicating the number of parameters to use and SAMPLE_NUMBER_OF_INTEGER_VALUES indicating the number of values to use for each paramater (2 for boolean parameters).
    I also added a #pragma message in order to follow the recursive compilation. 
    Dependency on cutil_inline.h removed.

    CUDA dynamic template parameters (1/2) : My dream CUDA feature

    One common problem when using templates to parametrize CUDA kernels (cf. my previous post) is to be able to dynamically select the set of template parameters to use for a call, depending on runtime variables. This usually leads to an exploding number of cascaded if/switch and a lot of code copy/paste to instantiate the whole parameters tree for each kernel call.
    This situation is illustrated by the following code for boolean parameters:


    In addition to the pain it is to write, such code results in the compilation of an exploding number of versions of the same kernel, one for each instantiated template configuration.

    Dynamic template parameters with JIT Kernels compilation
    There is a CUDA feature I am dreaming about for a few time now and that would solve both problems: dynamic template parameters. What I mean by this is the ability for a CUDA kernel to accept true C variables (containing runtime values) as integer template parameters. The syntax would simply look like this:


    This feature would be implemented by taking advantage of a C-level JIT (Just In Time) kernel compilation (current CUDA JIT compiler operates at the PTX level). It implies recompiling the kernel at runtime with a new set of template parameters each time a value changed. It requires tracking the last value of each parameters so that recompilation happens only when necessary. To be a bit more efficient, generated code could also be cached in some way so that it can be reused.
    This would change the kernel compilation paradigm to something closer to the OpenCL compiling model, but while keeping the nice CUDA-C syntax provided by nvcc.
    That feature would be very useful, and it would be great if NVIDIA makes CUDA evolves in that direction, or if someone write a JIT CUDA-C compiler that allows that !

    Emulating dynamic templates... with templates !
    While waiting for that feature, dynamic integer template parameters can be partially emulated today... with template metaprogramming ! The idea is to instantiate the whole parameters tree at compile time using templates, and to select the right one at runtime, based on the variables.

    More details coming in the next post !

    Fast and Accurate Single-Pass A-Buffer using OpenGL 4.0+

    One of the first thing I wanted do try on the GF100 was the new NVIDIA extensions that allows random access read/write and atomic operations into global memory and textures, to implement a fast A-Buffer !

    It worked pretty well since it provides something like a 1.5x speedup over the fastest previous approach (at least I know about !), with zero artifact and supporting arbitrary number of layers with a single geometry pass. 


    Sample application sources and Win32 executable:
    Sources+executable+Stanford Dragon model
    Additional models

    Be aware that this will probably only run on a Fermi card (Forceware drivers >=257.15). In particular it requires: EXT_shader_image_load_store, NV_shader_buffer_load, NV_shader_buffer_store, EXT_direct_state_access.
    Application uses freeglut in order to initialize an OpenGL 4.0 context with the core profile.

    Keys: 
    • 'a' Enable/Disable A-Buffer
    • 's' Enable/Disable fragments sorting. Disable= closest fragment kept during resolve.
    • 'g' Swith between Alpha-Blending and Gelly resolve modes.
    • 'c' Enable/Disable alpha correction when in Alpha-Blending mode.
    • 't' Swith between using textures or global memory for A-Buffer storage.
    • '1'-'3' Change mesh (requires the additional models).
    UPDATE: Files updated with a bug fix.

    A-Buffer:
    Basically an A-buffer is a simple list of fragments per pixel [Carpenter 1984]. Previous methods to implement it on DX10 generation hardware required multiple passes to capture an interesting number of fragments per pixel. They where essentially based on depth-peeling, with enhancements allowing to capture more than one layer per geometric pass, like the k-buffer, stencil routed k-buffer. Bucket sort depth peeling allows to capture up to 32 fragments per geometry pass but with only 32 bits per fragment (just a depth) and at the cost of potential collisions. All these techniques were complex and especially limited by the maximum of 8 render targets that were writable by the fragment shader.

    This technique can handle arbitrary number of fragments per pixels in a single pass, with only limitation the available video memory. In this example, I do order independent transparency with fragments storing 4x32bits values containing RGB color components and the depth.

    Technique:
    The idea is very simple: Each fragment is written by the fragment shader at it's position into a pre-allocated 2D texture array (or a global memory region) with a fixed maximum number of layers. The layer to write the fragment into is given by a counter stored per pixel into another 2D texture and incremented using an atomic increment (or addition) operation ( [image]AtomicIncWrap or [image]AtomicAdd). After the rendering pass, the A-Buffer contains an unordered list of fragments per pixel with it's size. To sort these fragments per depth and compose them on the screen, I simply use a single screen filling quad with a fragment shader. This shader copy all the pixel fragments in a local array (probably stored in L1 on Fermi), sort them with a naive bubble sort, and then combine them front-to-back based on transparency.

    Performances:
    To compare performances, this sample also features a standard rasterization mode which renders directly into the color buffer. On the Stanford Dragon example, a GTX480 and 32 layers in the A-Buffer, the technique range between 400-500 FPS, and is only 5-20% more costly than a simple rasterization of the mesh.
    I also compared performances with the k-buffer which code is available online (still be careful, it may not be super optimized). On the GTX480, with the same model and shading (and 16 layers), I can get more than a 2x speedup. Based on that results, I strongly believe that it is also close to 1.5x faster than the bucket sort depth peeling, without it's depth collision problems.


    EDIT: Artifacts in stencil-routed k-buffer came from a bug in DXUT, images removed. Also added a warning about the performances of the k-buffer OpenGL code from Louis Bavoil page.

    EDIT 2: The follow-up of this work using per-pixel linked-lists can also be read there: http://blog.icare3d.org/2010/07/opengl-40-abuffer-v20-linked-lists-of.html

    Copyright © Icare3D
    Designed by Templates Next | Converted into Blogger Templates by Theme Craft