Current vvvv alpha and upcoming vvvv beta36 has a new set of nodes that allows you to quickly upload data from VL to the graphics card. We had a WIP forum discussion about it here: VL - Custom Dynamic Buffer
On the VL side the nodes are called ToBufferDescription and we have them for the basic data types that usually hold big chunks of data: Spread, Array, IntPtr and Stream. The vvvv side is rather easy and only has one node called UploadBuffer (DX11.Buffer).
Primitive types work out of the box and don't need any special treatment. Just make sure you define the correct Buffer type in the shader. This works for Integers, Floats, Vectors and so on, everything that is available in the shader as primitive type. Here is an example for Float32:
The only exception is Matrix it needs to be transposed in order to work like a normal transformation input. If you send a large amount of individual matrices to the shader the most efficient way is to do the transpose in the shader directly:
If the same matrix is re-used very often or you don't have access to the shader code simply transpose in VL:
If you want to define your own data types like light information or a custom vertex type in the shader then you need to pack the data accordingly in the buffer description. For this task the ToBufferDescription (Stride) nodes are used. They allow you to make a buffer description out of primitive types like float or even byte and set the stride size of your custom type in bytes so that the shader can read the custom type directly out of the buffer.
Matrix hint: If you define a matrix in a custom type in the shader you can use the row_major modifier to automate the transpose operation.
Performance hint: If you can, design your custom types in a way that the byte count is a multiple of 16, sometimes it makes sense to insert unused floats as padding:
If you are a C# coder you can also define a struct in C# with attribute StructLayout(LayoutKind.Sequential) and the same byte layout, import it in VL and pass that directly into the buffer. Then you don't need the node with version StrideSize because the data type size already matches.
While in the process of doing the dynamic buffer nodes it was easy to add raw buffers. These buffers are from older shader models and can only be filled with bytes. On the shader side however you can also define Custom types. Only difference in HLSL is that you write Buffer<YourType> instead of StructuredBuffer<YourType>.
The node set is basically the same except that the VL part is not generic and only accepts bytes as input. The node names are ToRawBufferDescription in VL and UploadBuffer (DX11.Buffer Raw) in vvvv.
Raw buffers have no advantage except when you have to deal with an older graphics card, driver or shader code.
So now you can start sending your data up to the card and enjoy the speed. As always, if any questions arise hit us up in the forums.
This is really cool and I think I will try to use it in our current project.
Found a really cool Game of Life easteregg inside, much much appreciated.
Was there a reason why you could not implement UploadBuffer (DX11.Buffer) in vl too? I ask because I am interested in the nitty-gritty technical details, why the actual gpu upload was eventually moved out of vl to this (proprietary) vvvv plugin.
Game of Life looks great in VL after all, including easy array swapping. Much recommended reading material I'd say.
could not resist:
I think the reason was that one needs to implement the IDX11ResourceHost interface for it to work. This interface would need to be implemented by the VL hosting layer and forwarded to the VL node itself.
Yes that is right, it would be rather complicated to implement the interfaces, also we wanted to avoid the dependency to vvvv and DirectX in VL.
For custom types in C#, this page says that after importing the type, to "simply pass it directly to the buffer." Which version of the buffer? Spread? I have my types imported into VL but don't see a way to actually pass it into the buffer or turn my type into a spread (and wouldn't doing that force me to set the stride anyway?).
@polyrhythm it means as an Array<YourType> or Spread<YourType>. note that YourType needs to be a struct. if you only have one single element you still have to create a Spread or Array, e.g. with the FromValue node.
anonymous user login