protected override string GenerateFullTextCore(string setName, ShaderFunction function) { Debug.Assert(function.IsEntryPoint); StringBuilder sb = new StringBuilder(); BackendContext setContext = GetContext(setName); ShaderFunctionAndBlockSyntax entryPoint = setContext.Functions.SingleOrDefault( sfabs => sfabs.Function.Name == function.Name); if (entryPoint == null) { throw new ShaderGenerationException("Couldn't find given function: " + function.Name); } ValidateRequiredSemantics(setName, entryPoint.Function, function.Type); StructureDefinition[] orderedStructures = StructureDependencyGraph.GetOrderedStructureList(Compilation, setContext.Structures); foreach (StructureDefinition sd in orderedStructures) { WriteStructure(sb, sd); } FunctionCallGraphDiscoverer fcgd = new FunctionCallGraphDiscoverer( Compilation, new TypeAndMethodName { TypeName = function.DeclaringType, MethodName = function.Name }); fcgd.GenerateFullGraph(); TypeAndMethodName[] orderedFunctionList = fcgd.GetOrderedCallList(); List <ResourceDefinition[]> resourcesBySet = setContext.Resources.GroupBy(rd => rd.Set) .Select(g => g.ToArray()).ToList(); int uniformBinding = 0, textureBinding = 0, samplerBinding = 0, uavBinding = function.ColorOutputCount; int setIndex = 0; foreach (ResourceDefinition[] set in resourcesBySet) { Debug.Assert(set[0].Set == setIndex); setIndex += 1; foreach (ResourceDefinition rd in set) { switch (rd.ResourceKind) { case ShaderResourceKind.Uniform: WriteUniform(sb, rd, uniformBinding++); break; case ShaderResourceKind.Texture2D: WriteTexture2D(sb, rd, textureBinding++); break; case ShaderResourceKind.TextureCube: WriteTextureCube(sb, rd, textureBinding++); break; case ShaderResourceKind.Texture2DMS: WriteTexture2DMS(sb, rd, textureBinding++); break; case ShaderResourceKind.Sampler: WriteSampler(sb, rd, samplerBinding++); break; case ShaderResourceKind.StructuredBuffer: WriteStructuredBuffer(sb, rd, textureBinding++); break; case ShaderResourceKind.RWStructuredBuffer: WriteRWStructuredBuffer(sb, rd, uavBinding++); break; default: throw new ShaderGenerationException("Illegal resource kind: " + rd.ResourceKind); } } } foreach (TypeAndMethodName name in orderedFunctionList) { ShaderFunctionAndBlockSyntax f = setContext.Functions.Single( sfabs => sfabs.Function.DeclaringType == name.TypeName && sfabs.Function.Name == name.MethodName); if (!f.Function.IsEntryPoint) { sb.AppendLine(new HlslMethodVisitor(Compilation, setName, f.Function, this).VisitFunction(f.Block)); } } string result = new HlslMethodVisitor(Compilation, setName, entryPoint.Function, this) .VisitFunction(entryPoint.Block); sb.AppendLine(result); return(sb.ToString()); }
protected override string GenerateFullTextCore(string setName, ShaderFunction function) { BackendContext context = GetContext(setName); StringBuilder sb = new StringBuilder(); ShaderFunctionAndBlockSyntax entryPoint = context.Functions.SingleOrDefault( sfabs => sfabs.Function.Name == function.Name); if (entryPoint == null) { throw new ShaderGenerationException("Couldn't find given function: " + function.Name); } ValidateRequiredSemantics(setName, entryPoint.Function, function.Type); StructureDefinition input = GetRequiredStructureType(setName, entryPoint.Function.Parameters[0].Type); WriteVersionHeader(sb); StructureDefinition[] orderedStructures = StructureDependencyGraph.GetOrderedStructureList(Compilation, context.Structures); foreach (StructureDefinition sd in orderedStructures) { WriteStructure(sb, sd); } foreach (ResourceDefinition rd in context.Resources) { switch (rd.ResourceKind) { case ShaderResourceKind.Uniform: WriteUniform(sb, rd); break; case ShaderResourceKind.Texture2D: WriteTexture2D(sb, rd); break; case ShaderResourceKind.TextureCube: WriteTextureCube(sb, rd); break; case ShaderResourceKind.Sampler: WriteSampler(sb, rd); break; default: throw new ShaderGenerationException("Illegal resource kind: " + rd.ResourceKind); } } FunctionCallGraphDiscoverer fcgd = new FunctionCallGraphDiscoverer( Compilation, new TypeAndMethodName { TypeName = function.DeclaringType, MethodName = function.Name }); fcgd.GenerateFullGraph(); TypeAndMethodName[] orderedFunctionList = fcgd.GetOrderedCallList(); foreach (TypeAndMethodName name in orderedFunctionList) { ShaderFunctionAndBlockSyntax f = context.Functions.Single( sfabs => sfabs.Function.DeclaringType == name.TypeName && sfabs.Function.Name == name.MethodName); if (!f.Function.IsEntryPoint) { sb.AppendLine(new ShaderMethodVisitor(Compilation, setName, f.Function, this).VisitFunction(f.Block)); } } string result = new ShaderMethodVisitor(Compilation, setName, entryPoint.Function, this) .VisitFunction(entryPoint.Block); sb.AppendLine(result); WriteMainFunction(setName, sb, entryPoint.Function); return(sb.ToString()); }
protected override string GenerateFullTextCore(string setName, ShaderFunction function) { Debug.Assert(function.IsEntryPoint); StringBuilder sb = new StringBuilder(); BackendContext setContext = GetContext(setName); ShaderFunctionAndBlockSyntax entryPoint = setContext.Functions.SingleOrDefault( sfabs => sfabs.Function.Name == function.Name); if (entryPoint == null) { throw new ShaderGenerationException("Couldn't find given function: " + function.Name); } ValidateRequiredSemantics(setName, entryPoint.Function, function.Type); StructureDefinition input = GetRequiredStructureType(setName, entryPoint.Function.Parameters[0].Type); if (function.Type == ShaderFunctionType.VertexEntryPoint) { // HLSL vertex outputs needs to have semantics applied to the structure fields. StructureDefinition output = CreateOutputStructure(setName, GetRequiredStructureType(setName, entryPoint.Function.ReturnType)); setContext.Functions.Remove(entryPoint); entryPoint = entryPoint.WithReturnType(new TypeReference(output.Name)); setContext.Functions.Add(entryPoint); } if (function.Type == ShaderFunctionType.FragmentEntryPoint) { // HLSL pixel shader inputs also need these semantics. StructureDefinition modifiedInput = CreateOutputStructure(setName, input); setContext.Functions.Remove(entryPoint); entryPoint = entryPoint.WithParameter(0, new TypeReference(modifiedInput.Name)); setContext.Functions.Add(entryPoint); } StructureDefinition[] orderedStructures = StructureDependencyGraph.GetOrderedStructureList(Compilation, setContext.Structures); foreach (StructureDefinition sd in orderedStructures) { WriteStructure(sb, sd); } foreach (StructureDefinition sd in GetSynthesizedStructures(setName)) { WriteStructure(sb, sd); } FunctionCallGraphDiscoverer fcgd = new FunctionCallGraphDiscoverer( Compilation, new TypeAndMethodName { TypeName = function.DeclaringType, MethodName = function.Name }); fcgd.GenerateFullGraph(); TypeAndMethodName[] orderedFunctionList = fcgd.GetOrderedCallList(); List <ResourceDefinition[]> resourcesBySet = setContext.Resources.GroupBy(rd => rd.Set) .Select(g => g.ToArray()).ToList(); int uniformBinding = 0, textureBinding = 0, samplerBinding = 0; int setIndex = 0; foreach (ResourceDefinition[] set in resourcesBySet) { Debug.Assert(set[0].Set == setIndex); setIndex += 1; foreach (ResourceDefinition rd in set) { switch (rd.ResourceKind) { case ShaderResourceKind.Uniform: WriteUniform(sb, rd, uniformBinding++); break; case ShaderResourceKind.Texture2D: WriteTexture2D(sb, rd, textureBinding++); break; case ShaderResourceKind.TextureCube: WriteTextureCube(sb, rd, textureBinding++); break; case ShaderResourceKind.Sampler: WriteSampler(sb, rd, samplerBinding++); break; default: throw new ShaderGenerationException("Illegal resource kind: " + rd.ResourceKind); } } } foreach (TypeAndMethodName name in orderedFunctionList) { ShaderFunctionAndBlockSyntax f = setContext.Functions.Single( sfabs => sfabs.Function.DeclaringType == name.TypeName && sfabs.Function.Name == name.MethodName); if (!f.Function.IsEntryPoint) { sb.AppendLine(new HlslMethodVisitor(Compilation, setName, f.Function, this).VisitFunction(f.Block)); } } string result = new HlslMethodVisitor(Compilation, setName, entryPoint.Function, this) .VisitFunction(entryPoint.Block); sb.AppendLine(result); return(sb.ToString()); }