|
|
@@ -38,19 +38,41 @@ namespace ShaderGen
|
|
|
|
|
|
TypeReference returnType = new TypeReference(GetModel(node).GetFullTypeName(node.ReturnType));
|
|
|
|
|
|
- bool isVertexShader, isFragmentShader = false;
|
|
|
- isVertexShader = Utilities.GetMethodAttributes(node, "VertexShader").Any();
|
|
|
+ UInt3 computeGroupCounts = new UInt3();
|
|
|
+ bool isFragmentShader = false, isComputeShader = false;
|
|
|
+ bool isVertexShader = Utilities.GetMethodAttributes(node, "VertexShader").Any();
|
|
|
if (!isVertexShader)
|
|
|
{
|
|
|
isFragmentShader = Utilities.GetMethodAttributes(node, "FragmentShader").Any();
|
|
|
}
|
|
|
+ if (!isVertexShader && !isFragmentShader)
|
|
|
+ {
|
|
|
+ AttributeSyntax computeShaderAttr = Utilities.GetMethodAttributes(node, "ComputeShader").FirstOrDefault();
|
|
|
+ if (computeShaderAttr != null)
|
|
|
+ {
|
|
|
+ isComputeShader = true;
|
|
|
+ computeGroupCounts.X = GetAttributeArgumentUIntValue(computeShaderAttr, 0);
|
|
|
+ computeGroupCounts.Y = GetAttributeArgumentUIntValue(computeShaderAttr, 1);
|
|
|
+ computeGroupCounts.Z = GetAttributeArgumentUIntValue(computeShaderAttr, 2);
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
ShaderFunctionType type = isVertexShader
|
|
|
- ? ShaderFunctionType.VertexEntryPoint : isFragmentShader
|
|
|
- ? ShaderFunctionType.FragmentEntryPoint : ShaderFunctionType.Normal;
|
|
|
+ ? ShaderFunctionType.VertexEntryPoint
|
|
|
+ : isFragmentShader
|
|
|
+ ? ShaderFunctionType.FragmentEntryPoint
|
|
|
+ : isComputeShader
|
|
|
+ ? ShaderFunctionType.ComputeEntryPoint
|
|
|
+ : ShaderFunctionType.Normal;
|
|
|
|
|
|
string nestedTypePrefix = Utilities.GetFullNestedTypePrefix(node, out bool nested);
|
|
|
- ShaderFunction sf = new ShaderFunction(nestedTypePrefix, functionName, returnType, parameters.ToArray(), type);
|
|
|
+ ShaderFunction sf = new ShaderFunction(
|
|
|
+ nestedTypePrefix,
|
|
|
+ functionName,
|
|
|
+ returnType,
|
|
|
+ parameters.ToArray(),
|
|
|
+ type,
|
|
|
+ computeGroupCounts);
|
|
|
ShaderFunctionAndBlockSyntax sfab = new ShaderFunctionAndBlockSyntax(sf, node.Body);
|
|
|
foreach (LanguageBackend b in _backends) { b.AddFunction(_shaderSet.Name, sfab); }
|
|
|
}
|
|
|
@@ -108,12 +130,17 @@ namespace ShaderGen
|
|
|
"Array fields in structs must have a constant size specified by an ArraySizeAttribute.");
|
|
|
}
|
|
|
AttributeSyntax arraySizeAttr = arraySizeAttrs[0];
|
|
|
- return GetAttributeFirstArgumentIntValue(arraySizeAttr);
|
|
|
+ return GetAttributeArgumentIntValue(arraySizeAttr, 0);
|
|
|
}
|
|
|
|
|
|
- private static int GetAttributeFirstArgumentIntValue(AttributeSyntax attr)
|
|
|
+ private static int GetAttributeArgumentIntValue(AttributeSyntax attr, int index)
|
|
|
{
|
|
|
- string fullArg0 = attr.ArgumentList.Arguments[0].ToFullString();
|
|
|
+ if (attr.ArgumentList.Arguments.Count < index + 1)
|
|
|
+ {
|
|
|
+ throw new ShaderGenerationException(
|
|
|
+ "Too few arguments in attribute " + attr.ToFullString() + ". Required + " + (index + 1));
|
|
|
+ }
|
|
|
+ string fullArg0 = attr.ArgumentList.Arguments[index].ToFullString();
|
|
|
if (int.TryParse(fullArg0, out int ret))
|
|
|
{
|
|
|
return ret;
|
|
|
@@ -124,6 +151,24 @@ namespace ShaderGen
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ private static uint GetAttributeArgumentUIntValue(AttributeSyntax attr, int index)
|
|
|
+ {
|
|
|
+ if (attr.ArgumentList.Arguments.Count < index + 1)
|
|
|
+ {
|
|
|
+ throw new ShaderGenerationException(
|
|
|
+ "Too few arguments in attribute " + attr.ToFullString() + ". Required + " + (index + 1));
|
|
|
+ }
|
|
|
+ string fullArg0 = attr.ArgumentList.Arguments[index].ToFullString();
|
|
|
+ if (uint.TryParse(fullArg0, out uint ret))
|
|
|
+ {
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ throw new ShaderGenerationException("Incorrectly formatted attribute: " + attr.ToFullString());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
private static SemanticType GetSemanticType(VariableDeclaratorSyntax vds)
|
|
|
{
|
|
|
AttributeSyntax[] attrs = Utilities.GetMemberAttributes(vds, "VertexSemantic");
|
|
|
@@ -199,18 +244,23 @@ namespace ShaderGen
|
|
|
string resourceName = vds.Identifier.Text;
|
|
|
TypeInfo typeInfo = GetModel(node).GetTypeInfo(node.Type);
|
|
|
string fullTypeName = GetModel(node).GetFullTypeName(node.Type);
|
|
|
- TypeReference tr = new TypeReference(fullTypeName);
|
|
|
+ TypeReference valueType = new TypeReference(fullTypeName);
|
|
|
ShaderResourceKind kind = ClassifyResourceKind(fullTypeName);
|
|
|
|
|
|
+ if (kind == ShaderResourceKind.StructuredBuffer || kind == ShaderResourceKind.RWStructuredBuffer)
|
|
|
+ {
|
|
|
+ valueType = ParseStructuredBufferElementType(vds);
|
|
|
+ }
|
|
|
+
|
|
|
int set = 0; // Default value if not otherwise specified.
|
|
|
if (GetResourceDecl(node, out AttributeSyntax resourceSetDecl))
|
|
|
{
|
|
|
- set = GetAttributeFirstArgumentIntValue(resourceSetDecl);
|
|
|
+ set = GetAttributeArgumentIntValue(resourceSetDecl, 0);
|
|
|
}
|
|
|
|
|
|
int resourceBinding = GetAndIncrementBinding(set);
|
|
|
|
|
|
- ResourceDefinition rd = new ResourceDefinition(resourceName, set, resourceBinding, tr, kind);
|
|
|
+ ResourceDefinition rd = new ResourceDefinition(resourceName, set, resourceBinding, valueType, kind);
|
|
|
if (kind == ShaderResourceKind.Uniform)
|
|
|
{
|
|
|
ValidateResourceType(typeInfo);
|
|
|
@@ -219,6 +269,15 @@ namespace ShaderGen
|
|
|
foreach (LanguageBackend b in _backends) { b.AddResource(_shaderSet.Name, rd); }
|
|
|
}
|
|
|
|
|
|
+ private TypeReference ParseStructuredBufferElementType(VariableDeclaratorSyntax vds)
|
|
|
+ {
|
|
|
+ FieldDeclarationSyntax fieldDecl = (FieldDeclarationSyntax)vds.Parent.Parent;
|
|
|
+ GenericNameSyntax gns = (GenericNameSyntax)fieldDecl.Declaration.Type;
|
|
|
+ TypeSyntax type = gns.TypeArgumentList.Arguments[0];
|
|
|
+ string fullName = Utilities.GetFullTypeName(GetModel(vds), type);
|
|
|
+ return new TypeReference(fullName);
|
|
|
+ }
|
|
|
+
|
|
|
private int GetAndIncrementBinding(int set)
|
|
|
{
|
|
|
if (!_setCounts.TryGetValue(set, out int ret))
|
|
|
@@ -268,6 +327,14 @@ namespace ShaderGen
|
|
|
{
|
|
|
return ShaderResourceKind.Sampler;
|
|
|
}
|
|
|
+ else if (fullTypeName.Contains("ShaderGen.RWStructuredBuffer"))
|
|
|
+ {
|
|
|
+ return ShaderResourceKind.RWStructuredBuffer;
|
|
|
+ }
|
|
|
+ else if (fullTypeName.Contains("ShaderGen.StructuredBuffer"))
|
|
|
+ {
|
|
|
+ return ShaderResourceKind.StructuredBuffer;
|
|
|
+ }
|
|
|
else
|
|
|
{
|
|
|
return ShaderResourceKind.Uniform;
|