Ejemplo n.º 1
0
        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());
        }
Ejemplo n.º 2
0
        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());
        }