示例#1
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;
            }
        }
示例#2
0
        private void GenerateClassComment()
        {
            AsmTechnique technique = this.source.GetAsmTechnique(this.techniqueName, this.platform);

            //generate a comment for the class, detailing the shaders
            string vspre_comment = "";
            string pspre_comment = "";

            if (technique.VertexPreShader != null)
            {
                vspre_comment = string.Format("</para><para>Vertex Preshader: approximately {0} instruction slots used, {1} {2}", technique.VertexPreShader.GetCommandCount(), technique.VertexPreShader.RegisterSet.FloatRegisterCount, technique.VertexPreShader.RegisterSet.FloatRegisterCount == 1 ? "register" : "registers");
            }
            if (technique.PixelPreShader != null)
            {
                pspre_comment = string.Format("</para><para>Pixel Preshader: approximately {0} instruction slots used, {1} {2}", technique.PixelPreShader.GetCommandCount(), technique.PixelPreShader.RegisterSet.FloatRegisterCount, technique.PixelPreShader.RegisterSet.FloatRegisterCount == 1 ? "register" : "registers");
            }

            //comment the class
            string comment = string.Format(
                @"<para>Technique '{0}' generated from file '{1}'</para><para>Vertex Shader: {2}, {3} {4}{5}</para><para>Pixel Shader: {6}, {7} {8}{9}</para>",
                this.techniqueName,
                System.IO.Path.GetFileName(this.source.FileName),
                technique.VertexShaderComment,
                technique.VertexShader.RegisterSet.FloatRegisterCount,
                technique.VertexShader.RegisterSet.FloatRegisterCount == 1 ? "register" : "registers",
                vspre_comment,
                technique.PixelShaderComment,
                technique.PixelShader.RegisterSet.FloatRegisterCount,
                technique.PixelShader.RegisterSet.FloatRegisterCount == 1 ? "register" : "registers",
                pspre_comment);

            Comment(classDom, comment);
        }
示例#3
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);
        }
示例#4
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();
        }
示例#5
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);
            }
        }
示例#6
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;
                }
            }
        }
示例#7
0
        public override void AddBindBegin(IShaderDom shader, Action <CodeStatement, string> add)
        {
            //create the shader change bools..
            CodeStatement typeChange = new CodeVariableDeclarationStatement(typeof(bool), bindShaderChange.VariableName, new CodePrimitiveExpression(false));

            add(typeChange, "Shader type changed?");
            CodeStatement instanceChange = new CodeVariableDeclarationStatement(typeof(bool), bindInstanceChange.VariableName, new CodePrimitiveExpression(false));

            add(instanceChange, "Shader instance changed?");

            //call the Bind method in the shader system

            //int devIndex = state.Begin(this, 2, 0, out tc, out ic);

            CodeVariableReferenceExpression devIndex = new CodeVariableReferenceExpression("devIndex");

            AsmTechnique technique = source.GetAsmTechnique(techniqueName, Platform);

            int maxPixelSamplers  = MaxSamplers(technique.PixelShader.RegisterSet);
            int maxVertexSamplers = MaxSamplers(technique.VertexShader.RegisterSet);

            CodeMethodInvokeExpression beginInvoke = new CodeMethodInvokeExpression(
                new CodeMethodReferenceExpression(ShaderSystemRef, "Begin"),
                Instance,
                new CodePrimitiveExpression(maxPixelSamplers),
                new CodePrimitiveExpression(maxVertexSamplers),
                new CodeDirectionExpression(FieldDirection.Out, BindShaderTypeChange),
                new CodeDirectionExpression(FieldDirection.Out, BindShaderInstanceChange));

            CodeStatement callBegin = new CodeVariableDeclarationStatement(typeof(int), devIndex.VariableName, beginInvoke);

            add(callBegin, "About to start the bind");

            //if the devIndex has changed, call Warm() and set both bools to true

            //if extending in some way, then don't compare the devIndex to the class static, compare it to the virtual g uid
            CodeExpression classDevIndex = GraphicsDeviceUID;

            if (isShaderExtenable)
            {
                classDevIndex = new CodePropertyReferenceExpression(Instance, "lgd");
            }

            CodeExpression devChanged = new CodeBinaryOperatorExpression(devIndex, CodeBinaryOperatorType.IdentityInequality, classDevIndex);

            CodeStatement checkChanged =
                new CodeConditionStatement(devChanged,
                                           ETS(new CodeMethodInvokeExpression(Instance, "WarmShader", ShaderSystemRef)), // Call warm
                                           new CodeAssignStatement(BindShaderInstanceChange, new CodePrimitiveExpression(true)),
                                           new CodeAssignStatement(BindShaderTypeChange, new CodePrimitiveExpression(true)));

            add(checkChanged, "if the device changed, call Warm()");

            //bind the shaders if tc is true (type has changed)
            //and that 'owner' is true (owns the shaders)

            //if (((tc && this.owner)
            //            == true))
            //{
            //    state.SetShaders(ShadowShader.vs, ShadowShader.ps);
            //}

            //for classes that are either extendable or extended from another shader,
            //then the SetShaders call is put into a virtual method that is overridden.

            CodeBinaryOperatorExpression bindShaders = new CodeBinaryOperatorExpression(
                new CodeBinaryOperatorExpression(BindShaderTypeChange, CodeBinaryOperatorType.IdentityEquality, new CodePrimitiveExpression(true)),
                CodeBinaryOperatorType.BooleanAnd,
                new CodeBinaryOperatorExpression(new CodeFieldReferenceExpression(Instance, "owner"), CodeBinaryOperatorType.IdentityEquality, new CodePrimitiveExpression(true)));

            CodeExpression setShaders = new CodeMethodInvokeExpression(
                ShaderSystemRef, "SetShaders", VertexShaderRef, PixelShaderRef);


            //if extendable, the call goes into a local 'SetShaders' method
            if (isShaderExtenable)
            {
                setShaders = new CodeMethodInvokeExpression(Instance, "SetShaders", ShaderSystemRef);
            }

            CodeStatement exp = new CodeConditionStatement(
                bindShaders, ETS(setShaders));

            if (shaderExtendsFrom == null)
            {
                add(exp, "If the type has changed, and this class owns it's shaders, then bind the shaders");
            }
        }
示例#8
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");
        }