public void AddCompiledShader(ShaderCompilationTarget target, List <string> dependencyPaths, CompilationResult result)
        {
            string[] defines = new string[target.ShaderMacros.Length];
            for (int i = 0; i < target.ShaderMacros.Length; ++i)
            {
                defines[i] = target.ShaderMacros[i].Name;
            }
            var sourceShader = new SourceShader {
                Name = target.Path + target.Stage.Extension, Defines = defines
            };

            lock (CompiledShaders)
            {
                CompiledShaders[sourceShader] = result;
                TimeStamps[target.Path]       = target.CurrentTimeStamp;

                foreach (var dependency in dependencyPaths)
                {
                    TimeStamps[dependency] = File.GetLastWriteTime(dependency).Ticks;
                }
                if (!Dependencies.TryGetValue(target.Path, out HashSet <string> cacheDependencyPaths))
                {
                    cacheDependencyPaths = new HashSet <string>();
                    Dependencies.Add(target.Path, cacheDependencyPaths);
                }
                foreach (var dependencyPath in dependencyPaths)
                {
                    cacheDependencyPaths.Add(dependencyPath);
                }
            }
        }
Exemplo n.º 2
0
        public ShaderRegisters(SourceShader source, string techniqueName, Platform platform)
        {
            AsmTechnique technique = source.GetAsmTechnique(techniqueName, platform);

            vsReg = technique.VertexShader.RegisterSet;
            psReg = technique.PixelShader.RegisterSet;


            if (technique.VertexPreShader != null)
            {
                vsPreReg = technique.VertexPreShader.RegisterSet;
            }

            if (technique.PixelPreShader != null)
            {
                psPreReg = technique.PixelPreShader.RegisterSet;
            }

            staticArrays = new Dictionary <string, CodeExpression>();

            if (technique.TechniqueExtraData != null)
            {
                this.techniqueData = technique.TechniqueExtraData;

                psDefault = technique.TechniqueExtraData.PixelShaderConstants;
                vsDefault = technique.TechniqueExtraData.VertexShaderConstants;

                psBooleanDefault = technique.TechniqueExtraData.PixelShaderBooleanConstants;
                vsBooleanDefault = technique.TechniqueExtraData.VertexShaderBooleanConstants;
            }
        }
Exemplo n.º 3
0
        public SourceDom(SourceShader shader, string baseNamespace, CodeDomProvider provider)
        {
            this.codeProvider  = provider;
            this.directives    = new CompileDirectives(provider);
            this.source        = shader;
            this.baseNamespace = baseNamespace;

            string namespaceName = baseNamespace;

            if (!shader.UseParentNamespace)
            {
                namespaceName += "." + Common.ToUpper(Path.GetFileNameWithoutExtension(source.FileName));
            }
            this.outputNamespace = namespaceName;

            HlslTechnique[] techniques = shader.GetAllTechniques();

            if (shader.DefinePlatform)
            {
                //create a copy for each platform
                //xbox first

                this.rootPcNamespace   = new CodeNamespace(namespaceName);
                this.rootXboxNamespace = new CodeNamespace(namespaceName);

                for (int i = 0; i < techniques.Length; i++)
                {
                    //build the PC shaders
                    if ((techniques[i].Platform & Platform.Windows) == Platform.Windows)
                    {
                        ShaderDom dom = new ShaderDom(source, techniques[i].Name, Platform.Windows, directives);
                        this.rootPcNamespace.Types.Add(dom.CodeTypeDeclaration);
                    }
                }

                for (int i = 0; i < techniques.Length; i++)
                {
                    //build the xbox shaders
                    if ((techniques[i].Platform & Platform.Xbox) == Platform.Xbox)
                    {
                        ShaderDom dom = new ShaderDom(source, techniques[i].Name, Platform.Xbox, directives);
                        this.rootXboxNamespace.Types.Add(dom.CodeTypeDeclaration);
                    }
                }
            }
            else
            {
                this.rootNamespace = new CodeNamespace(namespaceName);

                for (int i = 0; i < techniques.Length; i++)
                {
                    //build the combined pc / xbox shaders
                    if ((techniques[i].Platform & Platform.Both) == Platform.Both)
                    {
                        ShaderDom dom = new ShaderDom(source, techniques[i].Name, Platform.Both, directives);
                        this.rootNamespace.Types.Add(dom.CodeTypeDeclaration);
                    }
                }
            }
        }
Exemplo n.º 4
0
        public ShaderBytes(SourceShader source, string techniqueName, Platform platform)
        {
            this.source   = source;
            this.platform = platform;

            this.asmTechnique  = source.GetAsmTechnique(techniqueName, platform);
            this.hlslTechnique = source.GetTechnique(techniqueName, platform);
        }
Exemplo n.º 5
0
        public ConstantSetup(SourceShader source, string techniqueName, Platform platform)
        {
            this.source        = source;
            this.techniqueName = techniqueName;

            this.attributeNames       = new List <string>();
            this.attributeFields      = new List <CodeFieldReferenceExpression>();
            this.attributeArrayFields = new List <CodeFieldReferenceExpression>();
            this.attributeAssignment  = new Dictionary <Type, List <CodeStatement> >();
            this.semanticMapping      = new List <SemanticMapping>();
            this.globals = new List <GlobalAttribute>();

            this.asm = source.GetAsmTechnique(techniqueName, platform);

            ComputeAllValidSemantics();
        }
Exemplo n.º 6
0
        public Preshaders(SourceShader source, string techniqueName, Platform platform)
        {
            technique = source.GetAsmTechnique(techniqueName, platform);

            if (technique.PixelPreShader != null)
            {
                pixelPreShaderStatements = new CodeStatementCollection();
                pixelPreShader           = new PreshaderSrc(technique.PixelPreShader, pixelPreShaderStatements);

                technique.PixelShader.RegisterSet.SetMinFloatRegisterCount(pixelPreShader.MaxConstantRegisterAccess);
                technique.PixelShader.RegisterSet.SetMinBooleanRegisterCount(pixelPreShader.MaxBooleanConstantRegisterWrite);
            }

            if (technique.VertexPreShader != null)
            {
                vertexPreShaderStatements = new CodeStatementCollection();
                vertexPreShader           = new PreshaderSrc(technique.VertexPreShader, vertexPreShaderStatements);

                technique.VertexShader.RegisterSet.SetMinFloatRegisterCount(vertexPreShader.MaxConstantRegisterAccess);
                technique.VertexShader.RegisterSet.SetMinBooleanRegisterCount(vertexPreShader.MaxBooleanConstantRegisterWrite);
            }
        }
Exemplo n.º 7
0
        public ShaderTextures(SourceShader source, string techniqueName, Platform platform)
        {
            this.psSamplers  = new List <Register>();
            this.vsSamplers  = new List <Register>();
            this.allSamplers = new Dictionary <string, SharedSampler>();

            AsmTechnique       technique = source.GetAsmTechnique(techniqueName, platform);
            TechniqueExtraData extras    = technique.TechniqueExtraData;

            //pull out the textures that will be used
            textures = new TextureAssociation[extras.TechniqueTextures.Length];
            for (int i = 0; i < extras.TechniqueTextures.Length; i++)
            {
                textures[i] = new TextureAssociation(extras.TechniqueTextures[i]);
            }

            //now do the samplers
            RegisterSet set = technique.PixelShader.RegisterSet;

            //pixel first
            foreach (Register reg in set)
            {
                if (reg.Category == RegisterCategory.Sampler)
                {
                    psSamplers.Add(reg);

                    int textureIndex = extras.PixelSamplerTextureIndex[reg.Index];

                    if (textureIndex == -1)
                    {
                        ThrowSamplerNoTextureException(reg);
                    }

                    textures[textureIndex].PsSamplers.Add(reg.Index);

                    //add the sampler to 'allSamplers'
                    SharedSampler ss = new SharedSampler();
                    ss.PsIndex        = reg.Index;
                    ss.SamplerDetails = reg;
                    ss.Index          = allSamplers.Count;
                    ss.DefaultState   = extras.PixelSamplerStates[reg.Index];
                    allSamplers.Add(reg.Name, ss);
                }
            }

            set = technique.VertexShader.RegisterSet;

            //now vertex
            foreach (Register reg in set)
            {
                if (reg.Category == RegisterCategory.Sampler)
                {
                    vsSamplers.Add(reg);

                    int textureIndex = extras.VertexSamplerTextureIndex[reg.Index];
                    if (textureIndex == -1)
                    {
                        ThrowSamplerNoTextureException(reg);
                    }

                    textures[textureIndex].VsSamplers.Add(reg.Index);

                    //add the sampler to 'allSamplers'
                    SharedSampler ss;
                    if (!allSamplers.TryGetValue(reg.Name, out ss))
                    {
                        ss = new SharedSampler();
                        ss.SamplerDetails = reg;
                        ss.Index          = allSamplers.Count;
                        ss.DefaultState   = extras.VertexSamplerStates[reg.Index];
                        allSamplers.Add(reg.Name, ss);
                    }
                    ss.VsIndex = reg.Index;
                }
            }
        }
        public static bool TryLoad(Stream stream, out ShaderCompilationCache cache)
        {
            using (var reader = new BinaryReader(stream))
            {
                try
                {
                    cache = new ShaderCompilationCache((ShaderFlags)reader.ReadInt32());

                    byte[] data = new byte[16384];

                    var shaderDataCount = reader.ReadInt32();
                    for (int i = 0; i < shaderDataCount; ++i)
                    {
                        var shaderSource = SourceShader.Read(reader);

                        //Read the size in bytes of the content element data itself.
                        int sizeInBytes = reader.ReadInt32();

                        if (data.Length < sizeInBytes)
                        {
                            data = new byte[sizeInBytes];
                        }

                        reader.Read(data, 0, sizeInBytes);

                        ShaderBytecode bytecode;
                        unsafe
                        {
                            fixed(byte *buffer = data)
                            {
                                bytecode = new ShaderBytecode(new IntPtr(buffer), sizeInBytes);
                            }
                        }
                        cache.CompiledShaders.Add(shaderSource, bytecode);
                    }

                    var timeStampCount = reader.ReadInt32();
                    for (int i = 0; i < timeStampCount; ++i)
                    {
                        var shaderSource = reader.ReadString();

                        //Read the time stamp.
                        long timeStamp = reader.ReadInt64();
                        cache.TimeStamps.Add(shaderSource, timeStamp);
                    }

                    var dependenciesCount = reader.ReadInt32();
                    for (int i = 0; i < dependenciesCount; ++i)
                    {
                        var shaderSource          = reader.ReadString();
                        var pathDependenciesCount = reader.ReadInt32();
                        var dependencies          = new HashSet <string>();
                        for (int j = 0; j < pathDependenciesCount; ++j)
                        {
                            dependencies.Add(reader.ReadString());
                        }
                        cache.Dependencies.Add(shaderSource, dependencies);
                    }
                }
                catch
                {
                    cache = null;
                    return(false);
                }
                return(true);
            }
        }
Exemplo n.º 9
0
        public ShaderDom(SourceShader source, string techniqueName, Platform platform, CompileDirectives directives)
        {
            this.domList = new List <DomBase>();
            this.domList.Add(this);

            this.isShaderExtenable = source.GetShaderExtended(techniqueName);
            this.shaderExtendsFrom = source.GetShaderExtension(techniqueName);

            //add custom dom's
            this.domList.Add(new ShaderBytes(source, techniqueName, platform));
            if (shaderExtendsFrom == null)
            {
                this.domList.Add(new ShaderRegisters(source, techniqueName, platform));
                this.domList.Add(new ConstantSetup(source, techniqueName, platform));
                this.domList.Add(new ShaderTextures(source, techniqueName, platform));
                this.domList.Add(new Preshaders(source, techniqueName, platform));
            }

            foreach (DomBase dom in domList)
            {
                dom.Setup(this);
            }

            this.techniqueName = techniqueName;
            this.source        = source;
            this.platform      = platform;


            classDom                = new CodeTypeDeclaration(techniqueName);
            classDom.IsClass        = true;
            classDom.Attributes     = MemberAttributes.Final | MemberAttributes.Public;
            classDom.TypeAttributes = TypeAttributes.Sealed | TypeAttributes.Public | TypeAttributes.Class;


            //provide a useful comment to the class
            GenerateClassComment();


            if (source.GenerateInternalClass)
            {
                classDom.Attributes     = MemberAttributes.Final | MemberAttributes.Assembly;
                classDom.TypeAttributes = TypeAttributes.NestedAssembly | TypeAttributes.Class | TypeAttributes.Sealed;
            }

            if (isShaderExtenable)
            {
                classDom.Attributes     = MemberAttributes.Public;
                classDom.TypeAttributes = TypeAttributes.Public | TypeAttributes.Class;

                if (source.GenerateInternalClass)
                {
                    classDom.Attributes     = MemberAttributes.Assembly;
                    classDom.TypeAttributes = TypeAttributes.NestedAssembly | TypeAttributes.Class;
                }
            }

            classDom.CustomAttributes.Add(new CodeAttributeDeclaration(new CodeTypeReference(typeof(System.Diagnostics.DebuggerStepThroughAttribute))));
            classDom.CustomAttributes.Add(new CodeAttributeDeclaration(new CodeTypeReference(typeof(System.CodeDom.Compiler.GeneratedCodeAttribute)), new CodeAttributeArgument(new CodePrimitiveExpression(GetType().Assembly.ManifestModule.Name)), new CodeAttributeArgument(new CodePrimitiveExpression(GetType().Assembly.ManifestModule.ModuleVersionId.ToString()))));

            if (shaderExtendsFrom != null)
            {
                classDom.BaseTypes.Add(new CodeTypeReference(shaderExtendsFrom));
            }
            else
            {
                classDom.BaseTypes.Add(new CodeTypeReference(typeof(BaseShader)));
            }

            //add custom base types to the shader
            //these are defined in TechniqueExtraData
            AsmTechnique asmTechnique = this.source.GetAsmTechnique(this.techniqueName, this.platform);

            if (asmTechnique.TechniqueExtraData != null && asmTechnique.TechniqueExtraData.ClassBaseTypes != null)
            {
                foreach (string baseTypeName in asmTechnique.TechniqueExtraData.ClassBaseTypes)
                {
                    classDom.BaseTypes.Add(new CodeTypeReference(baseTypeName));
                }
            }


            this.directives = directives;

            SetupMembers(techniqueName);
            foreach (DomBase dom in domList)
            {
                dom.SetupMembers(this);
            }

            if (shaderExtendsFrom == null)
            {
                CreateConstructor();
                CreateStaticGraphicsInitMethod();
                CreateBindMethod();
            }

            if (shaderExtendsFrom != null || isShaderExtenable)
            {
                CreateLocalDeviceIndexProperty();
            }

            CreateWarmShaderMethod();

            if (shaderExtendsFrom == null)
            {
                CreateChangedMethod();
            }

            CreateVertexInputMethods();

            if (shaderExtendsFrom == null)
            {
                CreateShaderConstantHashMethod();
            }


            CodeTypeMemberCollection pcMembers   = new CodeTypeMemberCollection();
            CodeTypeMemberCollection xboxMembers = new CodeTypeMemberCollection();

            foreach (DomBase dom in this.domList)
            {
                dom.AddMembers(this, delegate(CodeTypeMember s, string c) { Comment(s, c); classDom.Members.Add(s); }, Platform.Both);

                if (!source.DefinePlatform)                 // no need for specialization when the platform is constant
                {
                    dom.AddMembers(this, delegate(CodeTypeMember s, string c) { Comment(s, c); pcMembers.Add(s); }, Platform.Windows);
                    dom.AddMembers(this, delegate(CodeTypeMember s, string c) { Comment(s, c); xboxMembers.Add(s); }, Platform.Xbox);
                }
            }


            foreach (DomBase dom in this.domList)
            {
                dom.AddReadonlyMembers(this,
                                       delegate(CodeTypeMember s, string c)
                {
                    CodeTypeMember readonlySnip = directives.CreateReadOnlySnippet();
                    Comment(readonlySnip ?? s, c);
                    if (readonlySnip != null)
                    {
                        classDom.Members.Add(readonlySnip);
                    }
                    classDom.Members.Add(s);
                }, Platform.Both);

                if (!source.DefinePlatform)
                {
                    dom.AddReadonlyMembers(this,
                                           delegate(CodeTypeMember s, string c)
                    {
                        CodeTypeMember readonlySnip = directives.CreateReadOnlySnippet();
                        Comment(readonlySnip ?? s, c);
                        if (readonlySnip != null)
                        {
                            pcMembers.Add(readonlySnip);
                        }
                        pcMembers.Add(s);
                    }, Platform.Windows);

                    dom.AddReadonlyMembers(this,
                                           delegate(CodeTypeMember s, string c)
                    {
                        CodeTypeMember readonlySnip = directives.CreateReadOnlySnippet();
                        Comment(readonlySnip ?? s, c);
                        if (readonlySnip != null)
                        {
                            xboxMembers.Add(readonlySnip);
                        }
                        xboxMembers.Add(s);
                    }, Platform.Xbox);
                }
            }

            if (pcMembers.Count > 0 || xboxMembers.Count > 0)
            {
                //add #if / else blocks

                classDom.Members.Add(directives.IfXboxStatement);

                foreach (CodeTypeMember type in xboxMembers)
                {
                    classDom.Members.Add(type);
                }

                classDom.Members.Add(directives.ElseStatement);

                foreach (CodeTypeMember type in pcMembers)
                {
                    classDom.Members.Add(type);
                }

                classDom.Members.Add(directives.EndifStatement);
            }

            //finally, create the attribute setters

            CreateSetAttributeMethod(typeof(float), "SetAttribute", "attribute");
            CreateSetAttributeMethod(typeof(Vector2), "SetAttribute", "attribute");
            CreateSetAttributeMethod(typeof(Vector3), "SetAttribute", "attribute");
            CreateSetAttributeMethod(typeof(Vector4), "SetAttribute", "attribute");
            CreateSetAttributeMethod(typeof(Matrix), "SetAttribute", "attribute");
            CreateSetAttributeMethod(typeof(bool), "SetAttribute", "attribute");

            CreateSetAttributeMethod(typeof(float[]), "SetAttribute", "attribute");
            CreateSetAttributeMethod(typeof(Vector2[]), "SetAttribute", "attribute");
            CreateSetAttributeMethod(typeof(Vector3[]), "SetAttribute", "attribute");
            CreateSetAttributeMethod(typeof(Vector4[]), "SetAttribute", "attribute");
            CreateSetAttributeMethod(typeof(Matrix[]), "SetAttribute", "attribute");

            CreateSetAttributeMethod(typeof(Xen.Graphics.State.TextureSamplerState), "SetSamplerState", "sampler");
            CreateSetAttributeMethod(typeof(Texture), "SetTexture", "texture");
            CreateSetAttributeMethod(typeof(Texture2D), "SetTexture", "texture");
            CreateSetAttributeMethod(typeof(Texture3D), "SetTexture", "texture");
            CreateSetAttributeMethod(typeof(TextureCube), "SetTexture", "texture");
        }