Skip to content

Commit

Permalink
#12 Simple uniform buffer binding in Shanq
Browse files Browse the repository at this point in the history
Fixed size bug in MemUtil.WriteToPtr
  • Loading branch information
FacticiusVir committed Oct 19, 2016
1 parent 49a0338 commit e703b8f
Show file tree
Hide file tree
Showing 7 changed files with 145 additions and 75 deletions.
70 changes: 63 additions & 7 deletions SharpVk/SharpVk.Shanq/ShanqExpressionVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -191,31 +191,37 @@ private ResultId VisitMemberAccess(MemberExpression expression)

if (IsVectorType(targetType))
{
var fieldInfo = (FieldInfo)expression.Member;
string name;
Type type;
GetMemberData(expression, out name, out type);

int fieldIndex;

switch (fieldInfo.Name)
switch (name)
{
case "x":
case "r":
fieldIndex = 0;
break;
case "y":
case "g":
fieldIndex = 1;
break;
case "z":
case "b":
fieldIndex = 2;
break;
case "w":
case "a":
fieldIndex = 3;
break;
default:
throw new Exception($"Unsupported field: {fieldInfo.Name}");
throw new Exception($"Unsupported field: {name}");
}

ResultId targetId = this.Visit(expression.Expression);

ResultId typeId = this.Visit(Expression.Constant(fieldInfo.FieldType));
ResultId typeId = this.Visit(Expression.Constant(type));

ResultId accessId = this.file.GetNextResultId();

Expand All @@ -230,6 +236,23 @@ private ResultId VisitMemberAccess(MemberExpression expression)
}
}

private static void GetMemberData(MemberExpression expression, out string name, out Type type)
{
name = expression.Member.Name;

switch (expression.Member.MemberType)
{
case MemberTypes.Field:
type = ((FieldInfo)expression.Member).FieldType;
break;
case MemberTypes.Property:
type = ((PropertyInfo)expression.Member).PropertyType;
break;
default:
throw new NotSupportedException();
}
}

private ResultId GetInputId(FieldInfo fieldInfo)
{
ResultId typeId = this.Visit(Expression.Constant(fieldInfo.FieldType));
Expand All @@ -246,13 +269,17 @@ private ResultId GetInputId(FieldInfo fieldInfo)
}
else
{
ResultId pointerTypeId = this.Visit(Expression.Constant(typeof(UniformPointer<>).MakeGenericType(fieldInfo.FieldType)));

var binding = this.bindingMappings[fieldInfo];

ResultId accessId = this.file.GetNextResultId();

this.file.AddFunctionStatement(accessId, Op.OpAccessChain, pointerTypeId, binding.Item1, this.Visit(Expression.Constant(binding.Item2)));

ResultId resultId = this.file.GetNextResultId();

this.file.AddFunctionStatement(resultId, Op.OpAccessChain, binding.Item1, binding.Item2);
this.file.AddFunctionStatement(resultId, Op.OpLoad, typeId, accessId);

return resultId;
}
Expand Down Expand Up @@ -325,7 +352,16 @@ private ResultId VisitConstant(ConstantExpression expression)
{
Type value = (Type)expression.Value;

if (IsVectorType(value))
if (IsMatrixType(value))
{
Type rowType = GetMatrixRowType(value);
int[] dimensions = GetMatrixDimensions(value);

ResultId rowTypeId = this.Visit(Expression.Constant(rowType));

statement = new SpirvStatement(Op.OpTypeMatrix, rowTypeId, dimensions[0]);
}
else if (IsVectorType(value))
{
Type elementType = GetVectorElementType(value);
int length = GetVectorLength(value);
Expand Down Expand Up @@ -485,6 +521,11 @@ private static Type GetElementType(Type type)
}
}

private static Type GetMatrixRowType(Type value)
{
return value.GetProperty("Row0").PropertyType;
}

private static Type GetVectorElementType(Type value)
{
return value.GetField("x").FieldType;
Expand All @@ -498,13 +539,28 @@ private static int GetVectorLength(Type value)
.Count();
}

private static int[] GetMatrixDimensions(Type value)
{
var identity = value.GetProperty("Identity")
.GetValue(null);

var values = (float[,])value.GetProperty("Values")
.GetValue(identity);

return new[]
{
values.GetLength(0),
values.GetLength(1)
};
}

private static bool IsVectorType(Type type)
{
return type.Assembly == typeof(vec3).Assembly
&& type.Name.Contains("vec");
}

private static bool IsMatrixType(Type type)
public static bool IsMatrixType(Type type)
{
return type.Assembly == typeof(mat4).Assembly
&& type.Name.Contains("mat");
Expand Down
24 changes: 20 additions & 4 deletions SharpVk/SharpVk.Shanq/ShanqQueryExecutor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,18 +102,34 @@ public IEnumerable<T> ExecuteCollection<T>(QueryModel queryModel)
expressionVisitor.AddInputMapping(field, inputVariableId);
}
}
foreach(var type in bindingTypes)

foreach (var type in bindingTypes)
{
ResultId structureTypeId = expressionVisitor.Visit(Expression.Constant(type));
var pointerType = typeof(InputPointer<>).MakeGenericType(type);
ResultId uniformPointerId = expressionVisitor.Visit(Expression.Constant(pointerType));
ResultId uniformVariableId = file.GetNextResultId();

file.AddGlobalStatement(uniformVariableId, Op.OpVariable, uniformPointerId, StorageClass.Uniform);
file.AddAnnotationStatement(Op.OpDecorate, structureTypeId, Decoration.Block);
file.AddAnnotationStatement(Op.OpDecorate, uniformVariableId, Decoration.DescriptorSet, 0);
file.AddAnnotationStatement(Op.OpDecorate, uniformVariableId, Decoration.Binding, 0);

foreach(var field in type.GetFields())
int fieldIndex = 0;

foreach (var field in type.GetFields())
{
expressionVisitor.AddBinding(field, Tuple.Create(uniformVariableId, Marshal.OffsetOf(type, field.Name).ToInt32()));
expressionVisitor.AddBinding(field, Tuple.Create(uniformVariableId, fieldIndex));

if (ShanqExpressionVisitor.IsMatrixType(field.FieldType))
{
//HACK Should adapt to different matrix formats
file.AddAnnotationStatement(Op.OpMemberDecorate, structureTypeId, fieldIndex, Decoration.ColMajor);
file.AddAnnotationStatement(Op.OpMemberDecorate, structureTypeId, fieldIndex, Decoration.Offset, Marshal.OffsetOf(type, field.Name).ToInt32());
file.AddAnnotationStatement(Op.OpMemberDecorate, structureTypeId, fieldIndex, Decoration.MatrixStride, 16);
}

fieldIndex++;
}
}

Expand Down
5 changes: 3 additions & 2 deletions SharpVk/SharpVk/MemUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,15 +76,16 @@ public unsafe static void WriteToPtr<T>(IntPtr dest, T[] value, int startIndex,
{
if (count > 0)
{
uint size = SizeOf<T>() * (uint)value.Length;
int elementSize = (int)SizeOf<T>();
int transferSize = elementSize * value.Length;

void* pointer = dest.ToPointer();

var handle = GCHandle.Alloc(value, GCHandleType.Pinned);

byte* handlePointer = (byte*)handle.AddrOfPinnedObject().ToPointer();

System.Buffer.MemoryCopy(handlePointer + (int)(size * startIndex), pointer, size * count, size * count);
System.Buffer.MemoryCopy(handlePointer + (elementSize * startIndex), pointer, transferSize, transferSize);

handle.Free();
}
Expand Down
55 changes: 20 additions & 35 deletions SharpVk/Test Harness/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,28 +91,12 @@ public static void Main(string[] args)

public void Run()
{
this.BuildShaders();
Console.ReadLine();
return;
this.InitialiseWindow();
this.InitialiseVulkan();
this.MainLoop();
this.TearDown();
}

private void BuildShaders()
{
ShanqShader.Create(ExecutionModel.Vertex,
new MemoryStream(),
shanq => from input in shanq.GetInput<Vertex>()
from ubo in shanq.GetBinding<UniformBufferObject>()
select new VertexOutput
{
Position = new vec4(input.Position.x * ubo.Scale, input.Position.y, 0, 1),
Colour = input.Colour
});
}

private void InitialiseWindow()
{
this.window = new Form
Expand Down Expand Up @@ -284,13 +268,12 @@ private void UpdateUniformBuffer()

UniformBufferObject ubo = new UniformBufferObject
{
//Model = mat4.Rotate((float)Math.Sin(totalTime) * (float)Math.PI, vec3.UnitZ),
//View = mat4.LookAt(new vec3(1), vec3.Zero, vec3.UnitZ),
//Proj = mat4.Perspective((float)Math.PI / 4f, this.swapChainExtent.Width / (float)this.swapChainExtent.Height, 0.1f, 10)
Scale = 1
Model = mat4.Rotate((float)Math.Sin(totalTime) * (float)Math.PI, vec3.UnitZ),
View = mat4.LookAt(new vec3(1), vec3.Zero, vec3.UnitZ),
Proj = mat4.Perspective((float)Math.PI / 4f, this.swapChainExtent.Width / (float)this.swapChainExtent.Height, 0.1f, 10)
};

//ubo.Proj[1, 1] *= -1;
ubo.Proj[1, 1] *= -1;

uint uboSize = MemUtil.SizeOf<UniformBufferObject>();

Expand Down Expand Up @@ -543,7 +526,7 @@ private void CreateDescriptorSetLayout()
{
Binding = 0,
DescriptorType = DescriptorType.UniformBuffer,
StageFlags = ShaderStageFlags.Vertex,
StageFlags = ShaderStageFlags.Vertex | ShaderStageFlags.Fragment,
DescriptorCount = 1
}
}
Expand All @@ -552,20 +535,23 @@ private void CreateDescriptorSetLayout()

private void CreateGraphicsPipeline()
{
int codeSize;
var vertShaderData = LoadShaderData(@".\Shaders\vert.spv", out codeSize);

var vertShader = device.CreateShaderModule(new ShaderModuleCreateInfo
{
Code = vertShaderData,
CodeSize = codeSize
});
var vertShader = ShanqShader.CreateVertexModule(this.device,
shanq => from input in shanq.GetInput<Vertex>()
from ubo in shanq.GetBinding<UniformBufferObject>()
let transform = ubo.Proj * ubo.View * ubo.Model
select new VertexOutput
{
Position = transform * new vec4(input.Position, 0, 1),
Colour = input.Colour
});

var fragShader = ShanqShader.CreateFragmentModule(this.device,
shanq => from input in shanq.GetInput<FragmentInput>()
from ubo in shanq.GetBinding<UniformBufferObject>()
let colour = new vec4(input.Colour, 1)
select new FragmentOutput
{
Colour = new vec4(input.Colour, 1)
Colour = colour
});

var bindingDescription = Vertex.GetBindingDescription();
Expand Down Expand Up @@ -1097,10 +1083,9 @@ private struct FragmentOutput

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

private struct Vertex
Expand Down
6 changes: 4 additions & 2 deletions SharpVk/Test Harness/Shaders/Shader.vert
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
#extension GL_ARB_separate_shader_objects : enable

layout(binding = 0) uniform UniformBufferObject {
float scale;
mat4 model;
mat4 view;
mat4 proj;
} ubo;

layout(location = 0) in vec2 inPosition;
Expand All @@ -15,6 +17,6 @@ out gl_PerVertex {
};

void main() {
gl_Position = vec4(inPosition.x * ubo.scale, inPosition.y * -ubo.scale, 0.0, 1.0);
gl_Position = ubo.proj * ubo.view * ubo.model * vec4(inPosition, 0.0, 1.0);
fragColor = inColor;
}
Loading

0 comments on commit e703b8f

Please sign in to comment.