Thursday, 17 April 2014

After finishing my projects, I finally have time to work on some way long overdue features.

I'm doing a lot of work on my user interface revamp, and also doing a lot of code cleanup since now Windows Phone gives us access (also long overdue) to all nice features like P/Invoke, Direct2d....

This means after a bit of tweaking on SharpDX code base, windows phone is now AnyCpu, which is really great, having x86, x64, ARM and lot of targets to maintain is not pleasing at all.

Also I decided to move on and remove the old DirectX11/DirectX11.1 targets on my toolbox. No more Windows 7 support, I prefer to focus on having a better build for Desktop / RT / Phone instead.

Now after all this I thought it was time to work on another (well overdue as well) feature.

I've always been interested into processing geometry in compute shaders instead of using StreamOut.

This gives some pretty useful advantages:

Write in place : RWStructuredBuffer rocks, no need for ping/pong

Writing Indexed geometry using Geometry Shader is doable, but rather painful.

Much easier to do more advanced post processing

Access to indirect Draw, which means it's much easier to instance generated geometry, StreamOut does not give us access to internal counter, except using a query, eg: not ideal.

Here are my structures:

Code Snippet

privateDX11StructuredBuffer positionbuffer;

privateDX11StructuredBuffer normalsbuffer;

privateDX11StructuredBuffer uvbuffer;

privateDX11StructuredBuffer appendindexbuffer;

privateDX11InstancedIndexedDrawer drawer;

privateDispatchIndirectBuffer vertexIndirectDispatch;

privateDispatchIndirectBuffer indexIndirectDispacth;

Pretty simple, with two things to note:

Position buffer is created with the counter flag

Index Buffer is created with the append flag

Now there are a few bits to consider:

Structured Buffer is not bindable as Vertex Buffer: This is more or less a non issue in my case, since most of my shaders already fetch data from StructuredBuffers using SV_VertexID

StructuredBuffer is not bindable as Index Buffer. This is more annoying, since you need to bind it to the pipeline, no way to fetch. This is quite easy to sort still, as you can just create a standard index buffer (which allow raw view and give it UAV access), then just use a compute shader to copy indices.

So with this setup we are more or less set, you can process per vertex using VertexIndirectDispatcher, process per face using IndexIndirectDispatcher, and since you have access to counter/append, you can also easily emit/remove Geometry.

Now one main issue with this setup, you need to feed your buffers with some initial geometry.

You have a very simple way to do this in DirectX11.1 , but the feature is only supported on ATI.

So instead, let's replace my old monolithic geometry builders by something more flexible