protected HashSet <ResourceDefinition> ProcessFunctions(string setName, ShaderFunctionAndMethodDeclarationSyntax entryPoint, out string funcs, out string entry) { HashSet <ResourceDefinition> resourcesUsed = new HashSet <ResourceDefinition>(); StringBuilder sb = new StringBuilder(); foreach (ShaderFunctionAndMethodDeclarationSyntax f in entryPoint.OrderedFunctionList) { if (!f.Function.IsEntryPoint) { MethodProcessResult processResult = VisitShaderMethod(setName, f.Function).VisitFunction(f.MethodDeclaration); foreach (ResourceDefinition rd in processResult.ResourcesUsed) { resourcesUsed.Add(rd); } sb.AppendLine(processResult.FullText); } } funcs = sb.ToString(); MethodProcessResult result = VisitShaderMethod(setName, entryPoint.Function).VisitFunction(entryPoint.MethodDeclaration); foreach (ResourceDefinition rd in result.ResourcesUsed) { resourcesUsed.Add(rd); } entry = result.FullText; return(resourcesUsed); }
internal ShaderModel GetShaderModel(string setName) { BackendContext context = GetContext(setName); foreach (ResourceDefinition rd in context.Resources .Where(rd => rd.ResourceKind == ShaderResourceKind.Uniform || rd.ResourceKind == ShaderResourceKind.RWStructuredBuffer || rd.ResourceKind == ShaderResourceKind.StructuredBuffer)) { ForceTypeDiscovery(setName, rd.ValueType); } // HACK: Discover all field structure types. foreach (StructureDefinition sd in context.Structures.ToArray()) { foreach (FieldDefinition fd in sd.Fields) { ForceTypeDiscovery(setName, fd.Type); } } ResourceDefinition[] vertexResources = null; ResourceDefinition[] fragmentResources = null; ResourceDefinition[] computeResources = null; // HACK: Discover all method input structures. foreach (ShaderFunctionAndBlockSyntax sf in context.Functions.ToArray()) { if (sf.Function.IsEntryPoint) { MethodProcessResult processedFunction = ProcessEntryFunction(setName, sf.Function); if (sf.Function.Type == ShaderFunctionType.VertexEntryPoint) { vertexResources = processedFunction.ResourcesUsed.ToArray(); } else if (sf.Function.Type == ShaderFunctionType.FragmentEntryPoint) { fragmentResources = processedFunction.ResourcesUsed.ToArray(); } else { Debug.Assert(sf.Function.Type == ShaderFunctionType.ComputeEntryPoint); computeResources = processedFunction.ResourcesUsed.ToArray(); } } } return(new ShaderModel( context.Structures.ToArray(), context.Resources.ToArray(), context.Functions.Select(sfabs => sfabs.Function).ToArray(), vertexResources, fragmentResources, computeResources)); }
protected HashSet <ResourceDefinition> ProcessFunctions(string setName, ShaderFunctionAndMethodDeclarationSyntax entryPoint, out string funcs, out string entry) { HashSet <ResourceDefinition> resourcesUsed = new HashSet <ResourceDefinition>(); StringBuilder sb = new StringBuilder(); foreach (ShaderFunctionAndMethodDeclarationSyntax f in entryPoint.OrderedFunctionList) { if (!f.Function.IsEntryPoint) { MethodProcessResult processResult = VisitShaderMethod(setName, f.Function).VisitFunction(f.MethodDeclaration); foreach (ResourceDefinition rd in processResult.ResourcesUsed) { resourcesUsed.Add(rd); } sb.AppendLine(processResult.FullText); foreach (var param in f.Function.Parameters) { resourcesUsed.Add(new ResourceDefinition(param.Name, 0, 0, param.Type, ShaderResourceKind.Local)); } } } funcs = sb.ToString(); MethodProcessResult result = VisitShaderMethod(setName, entryPoint.Function).VisitFunction(entryPoint.MethodDeclaration); foreach (ResourceDefinition rd in result.ResourcesUsed) { resourcesUsed.Add(rd); } var context = GetContext(setName); foreach (var param in entryPoint.Function.Parameters) { var paramResource = new ResourceDefinition(param.Name, 0, 0, param.Type, ShaderResourceKind.Local); resourcesUsed.Add(paramResource); var sd = context.Structures.FirstOrDefault(paramResource.Matches); if (sd != null) { int fieldIndex = 0; foreach (var field in sd.Fields.Where(f => !f.IsBuiltIn)) { resourcesUsed.Add(new ResourceDefinition(field.Name, 0, fieldIndex++, field.Type, ShaderResourceKind.Emit)); } } } entry = result.FullText; return(resourcesUsed); }
internal ShaderModel GetShaderModel(string setName) { BackendContext context = GetContext(setName); foreach (ResourceDefinition rd in context.Resources .Where(rd => rd.ResourceKind == ShaderResourceKind.Uniform || rd.ResourceKind == ShaderResourceKind.RWStructuredBuffer || rd.ResourceKind == ShaderResourceKind.StructuredBuffer || rd.ResourceKind == ShaderResourceKind.BuiltIn)) { ForceTypeDiscovery(setName, rd.ValueType, out var sd); if (sd != null && sd.Fields.Any(f => f.IsBuiltIn)) { rd.ResourceKind = ShaderResourceKind.BuiltIn; } } // HACK: Discover all field structure types. foreach (StructureDefinition sd in context.Structures.ToArray()) { foreach (FieldDefinition fd in sd.Fields) { ForceTypeDiscovery(setName, fd.Type); } } ResourceDefinition[] vertexResources = null; ResourceDefinition[] geometryResources = null; ResourceDefinition[] fragmentResources = null; ResourceDefinition[] computeResources = null; ShaderFunctionAndMethodDeclarationSyntax[] contextFunctions = context.Functions.ToArray(); // Discover all parameter types foreach (ShaderFunctionAndMethodDeclarationSyntax sf in contextFunctions) { foreach (ParameterDefinition funcParam in sf.Function.Parameters) { if (funcParam.Symbol.Type.TypeKind == TypeKind.Struct) { ForceTypeDiscovery(setName, funcParam.Type); } } } foreach (ShaderFunctionAndMethodDeclarationSyntax sf in contextFunctions) { if (sf.Function.IsEntryPoint) { MethodProcessResult processedFunction = ProcessEntryFunction(setName, sf.Function); if (sf.Function.Type == ShaderFunctionType.VertexEntryPoint) { vertexResources = processedFunction.ResourcesUsed.ToArray(); } else if (sf.Function.Type == ShaderFunctionType.GeometryEntryPoint) { geometryResources = processedFunction.ResourcesUsed.ToArray(); } else if (sf.Function.Type == ShaderFunctionType.FragmentEntryPoint) { fragmentResources = processedFunction.ResourcesUsed.ToArray(); } else { Debug.Assert(sf.Function.Type == ShaderFunctionType.ComputeEntryPoint); computeResources = processedFunction.ResourcesUsed.ToArray(); } } } return(new ShaderModel( context.Structures.ToArray(), context.Resources.Where(r => r.ResourceKind <= ShaderResourceKind.AtomicBuffer).ToArray(), context.Functions.Select(sfabs => sfabs.Function).ToArray(), vertexResources, geometryResources, fragmentResources, computeResources)); }