SharpVk icon indicating copy to clipboard operation
SharpVk copied to clipboard

Shanq bindings don't support non-matrix types

Open idg10 opened this issue 3 years ago • 0 comments

The UniformBuffers example in the SharpVk-Samples repo defines this type to enable the application to pass arguments into the shaders:

private struct UniformBufferObject
{
    public mat4 Model;
    public mat4 View;
    public mat4 Proj;
};

This works but if you try to extend it by adding an additional field of type float, it goes wrong. There's no runtime error, but the shader ends up picking up data from the wrong offset within this structure.

This turns out to be because the code in ShanqQueryExecutor that works through all the fields in all the bindings only emits the offset of the field if the field is of a matrix type:

https://github.com/FacticiusVir/SharpVk/blob/1167c3f8ef41f79a92af000d3e31854d3176bd4c/src/SharpVk.Shanq/ShanqQueryExecutor.cs#L137-L150

So if you add, say, a float field, the GPU ends up thinking it needs to look at offset 0.

As a quick hack I just added this else to the if in that loop:

else
{
    file.AddAnnotationStatement(Op.OpMemberDecorate, structureTypeId, fieldIndex, Decoration.Offset, Marshal.OffsetOf(type, field.Name).ToInt32());
}

(or you could just move the relevant line out of the if I suppose, but I was trying to not to spread changes out across too much code).

With that in place, you can now do something like this:

private struct UniformBufferObject
{
    public mat4 Model;
    public mat4 View;
    public mat4 Proj;
    public float Level;
};

and then access this from, e.g. a vertex shader:

from input in shanq.GetInput<Vertex>()
from ubo in shanq.GetBinding<UniformBufferObject>(0)
let transform = ubo.Proj * ubo.View * ubo.Model
select new VertexOutput
{
    Position = transform * new vec4(input.Position, 0, 1),
    Colour = input.Colour * ubo.Level
});

This seems to work. But if there's some reason only matrix types should be used here, then the query exector should probably have an else branch there throwing an exception to say that other types are not supported.

idg10 avatar Feb 17 '21 18:02 idg10