Example #1
0
        //setup the ID based setters / getters
        public override void AddSetAttribute(IShaderDom shader, Action <CodeStatement> add, Type type)
        {
            //samplers first
            if (type == typeof(Xen.Graphics.State.TextureSamplerState))
            {
                foreach (SharedSampler ss in allSamplers.Values)
                {
                    //assign the sampler, if it matches.
                    CodeExpression uid     = new CodeFieldReferenceExpression(shader.ShaderClassEx, "sid" + ss.Index);
                    CodeExpression sampler = new CodePropertyReferenceExpression(shader.Instance, Common.ToUpper(ss.SamplerDetails.Name));

                    CodeExpression assignIdsMatch =
                        new CodeBinaryOperatorExpression(shader.AttributeAssignId, CodeBinaryOperatorType.IdentityEquality, uid);

                    CodeStatement assignAttribute = new CodeAssignStatement(sampler, shader.AttributeAssignValue);

                    CodeConditionStatement performAssign =
                        new CodeConditionStatement(assignIdsMatch,
                                                   assignAttribute,                                                   //call the assignment code
                                                   new CodeMethodReturnStatement(new CodePrimitiveExpression(true))); //return true, set correctly.

                    add(performAssign);
                }
            }


            if (!typeof(Microsoft.Xna.Framework.Graphics.Texture).IsAssignableFrom(type))
            {
                return;
            }

            //now, all the non-global textures
            for (int i = 0; i < textures.Length; i++)
            {
                TextureAssociation tex = textures[i];

                if ((tex.PsSamplers.Count > 0 || tex.VsSamplers.Count > 0) &&
                    tex.IsGlobal == false)
                {
                    if (Common.GetTextureType(tex.Texture.Type) == type)
                    {
                        //assign
                        CodeExpression uid     = new CodeFieldReferenceExpression(shader.ShaderClassEx, "tid" + i);
                        CodeExpression sampler = new CodePropertyReferenceExpression(shader.Instance, Common.ToUpper(tex.Texture.Name));

                        CodeExpression assignIdsMatch =
                            new CodeBinaryOperatorExpression(shader.AttributeAssignId, CodeBinaryOperatorType.IdentityEquality, uid);

                        CodeStatement assignAttribute = new CodeAssignStatement(sampler, shader.AttributeAssignValue);

                        CodeConditionStatement performAssign =
                            new CodeConditionStatement(assignIdsMatch,
                                                       assignAttribute,                                                   //call the assignment code
                                                       new CodeMethodReturnStatement(new CodePrimitiveExpression(true))); //return true, set correctly.

                        add(performAssign);
                    }
                }
            }
        }
Example #2
0
        public override void AddMembers(IShaderDom shader, Action <CodeTypeMember, string> add, Platform platform)
        {
            if (platform != Platform.Both)
            {
                return;
            }

            //static graphics ID
            CodeMemberField field = new CodeMemberField(typeof(int), gdIndexRef.FieldName);

            field.Attributes = MemberAttributes.Static | MemberAttributes.Final | MemberAttributes.Private;
            add(field, "Static graphics ID");


            //if the class is extendable or extended, state.SetShaders() goes into it's own method
            if (isShaderExtenable || shaderExtendsFrom != null)
            {
                CodeExpression setShaders = new CodeMethodInvokeExpression(
                    ShaderSystemRef, "SetShaders", VertexShaderRef, PixelShaderRef);

                CodeMemberMethod localSetShaders = new CodeMemberMethod();
                localSetShaders.Name = "SetShaders";
                localSetShaders.Parameters.Add(new CodeParameterDeclarationExpression(typeof(IShaderSystem), ShaderSystemRef.ParameterName));
                localSetShaders.Attributes = MemberAttributes.Family;

                //is extended, override
                if (shaderExtendsFrom != null)
                {
                    localSetShaders.Attributes |= MemberAttributes.Override;
                }

                localSetShaders.Statements.Add(setShaders);
                add(localSetShaders, "Local method required for shader extensions");
            }
        }
Example #3
0
 public override void AddReadonlyMembers(IShaderDom shader, Action <CodeTypeMember, string> add, Platform platform)
 {
     if (platform == Platform.Both)
     {
         add(vsInputField, "array storing vertex usages, and element indices");
     }
 }
Example #4
0
        public override void AddConstructor(IShaderDom shader, Action <CodeStatement> add)
        {
            //setup the default values for the masks and samplers

            if (psSamplers.Count > 0)
            {
                //set the PS mask to a big number
                CodeStatement assign = new CodeAssignStatement(new CodeFieldReferenceExpression(shader.Instance, "psm"), new CodePrimitiveExpression(int.MaxValue));
                add(assign);
            }

            if (vsSamplers.Count > 0)
            {
                //set the PS mask to a big number
                CodeStatement assign = new CodeAssignStatement(new CodeFieldReferenceExpression(shader.Instance, "vsm"), new CodePrimitiveExpression(int.MaxValue));
                add(assign);
            }

            //set the samplers to their defaults

            foreach (SharedSampler ss in allSamplers.Values)
            {
                //get the default as an int,
                //then cast it to a sampler state using explicit cast construction
                CodeExpression value = new CodeCastExpression(typeof(Xen.Graphics.State.TextureSamplerState), new CodePrimitiveExpression((int)ss.DefaultState));

                //assign the value
                CodeStatement assign = new CodeAssignStatement(new CodeFieldReferenceExpression(shader.Instance, "ts" + ss.Index), value);
                add(assign);
            }
        }
Example #5
0
        //extract pairs of asmlistings / code registers
        private void ComputeListings(IShaderDom shader)
        {
            List <KeyValuePair <AsmListing, CodeExpression> > listings = new List <KeyValuePair <AsmListing, CodeExpression> >();

            if (asm.VertexShader != null)
            {
                listings.Add(new KeyValuePair <AsmListing, CodeExpression>(asm.VertexShader, shader.VertexShaderRegistersRef));
            }

            if (asm.PixelShader != null)
            {
                listings.Add(new KeyValuePair <AsmListing, CodeExpression>(asm.PixelShader, shader.PixelShaderRegistersRef));
            }

            //preshaders

            if (asm.VertexPreShader != null)
            {
                listings.Add(new KeyValuePair <AsmListing, CodeExpression>(asm.VertexPreShader, shader.VertexPreShaderRegistersRef));
            }

            if (asm.PixelPreShader != null)
            {
                listings.Add(new KeyValuePair <AsmListing, CodeExpression>(asm.PixelPreShader, shader.PixelPreShaderRegistersRef));
            }


            this.listingRegisters = listings.ToArray();
        }
Example #6
0
        private void ProcessConstants(IShaderDom shader)
        {
            RegisterSet registers = asm.CommonRegisters;

            for (int i = 0; i < registers.RegisterCount; i++)
            {
                Register reg = registers.GetRegister(i);
                if (reg.Category == RegisterCategory.Float4 ||
                    reg.Category == RegisterCategory.Boolean)
                {
                    if (reg.Semantic == null)
                    {
                        this.attributeNames.Add(reg.Name);
                    }
                    else
                    {
                        ExtractSemantic(shader, reg);
                    }
                }
                else if (reg.Semantic != null && reg.Category != RegisterCategory.Texture)
                {
                    throw new CompileException(string.Format("Error parsing semantic for '{1} {0}'. Semantic bound types may only be processed as Float4 or Texture registers", reg.Name, reg.Type));
                }
            }
        }
Example #7
0
        //add the member fields
        public override void SetupMembers(IShaderDom shader)
        {
            ComputeListings(shader);

            ProcessConstants(shader);

            for (int i = 0; i < attributeNames.Count; i++)
            {
                //create a field ref for the static that will be created
                //these are used to assign the value using 'SetAttribute'
                CodeFieldReferenceExpression field = new CodeFieldReferenceExpression(shader.ShaderClassEx, string.Format("cid{0}", i));
                this.attributeFields.Add(field);

                //if it's an array, an array object needs to be created too. Create the ref to it now

                field = null;

                Register reg;
                Type     type;            //unused

                if (ExtractRegType(attributeNames[i], out reg, out type) && reg.ArraySize != -1)
                {
                    field = new CodeFieldReferenceExpression(shader.Instance, string.Format("ca{0}", i));
                }

                attributeArrayFields.Add(field);                //may be null.
            }
        }
Example #8
0
        public override void AddStaticGraphicsInit(IShaderDom shader, Action <CodeStatement, string> add)
        {
            //assign the static graphics ID
            CodeStatement assign = new CodeAssignStatement(gdIndexRef, new CodePropertyReferenceExpression(ShaderSystemRef, "DeviceUniqueIndex"));

            add(assign, "set the graphics ID");
        }
Example #9
0
        private void WriteBytes(IShaderDom shader, string name, byte[] data, Action <CodeTypeMember, string> add, CompileDirectives compileDirectives, bool isVS, bool isXbox)
        {
            //the byte array gets run through a simple compression scheme first...

            //generate the local byte array
            CodeMemberField field = new CodeMemberField(typeof(byte[]), name);

            field.Attributes = MemberAttributes.Final | MemberAttributes.Private | MemberAttributes.Static;

            data = ConstantArray.ArrayUtils.SimpleCompress(data);

            //if using the byte pool, then defer creating the array
            if (source.PoolShaderBytes)
            {
                if (isXbox)
                {
                    field.InitExpression = source.BytePoolXbox.AddArray(data);
                }
                else
                {
                    field.InitExpression = source.BytePoolPC.AddArray(data);
                }
            }
            else
            {
                //decompressed in code
                CodeMethodReferenceExpression decompressMethod = new CodeMethodReferenceExpression(new CodeTypeReferenceExpression(typeof(ConstantArray.ArrayUtils)), "SimpleDecompress");
                CodeExpression dataCode = ToArray(data, compileDirectives);

                //assign it inline
                field.InitExpression = new CodeMethodInvokeExpression(decompressMethod, dataCode);
            }

            add(field, string.Format("Static {0} shader byte code ({1})", isVS ? "vertex" : "pixel", isXbox ? "Xbox360" : "Windows"));
        }
Example #10
0
        private void GenerateNameIds(IShaderDom shader, Action <CodeTypeMember, string> add)
        {
            //each texture / sampler needs to be settable by ID

            foreach (SharedSampler ss in allSamplers.Values)
            {
                //create a uid for the sampler

                CodeMemberField field = new CodeMemberField(typeof(int), "sid" + ss.Index);
                field.Attributes = MemberAttributes.Private | MemberAttributes.Family | MemberAttributes.Static;

                add(field, string.Format("Name uid for sampler for '{0} {1}'", Common.ToUpper(ss.SamplerDetails.Type), ss.SamplerDetails.Name));
            }

            //create for each texture
            for (int i = 0; i < textures.Length; i++)
            {
                TextureAssociation tex = textures[i];

                if (tex.PsSamplers.Count > 0 || tex.VsSamplers.Count > 0)
                {
                    //create a uid for the sampler

                    CodeMemberField field = new CodeMemberField(typeof(int), "tid" + i);
                    field.Attributes = MemberAttributes.Private | MemberAttributes.Family | MemberAttributes.Static;

                    add(field, string.Format("Name uid for texture for '{0} {1}'", tex.Texture.Type, tex.Texture.Name));
                }
            }
        }
Example #11
0
        public override void AddWarm(IShaderDom shader, Action <CodeStatement, string> add)
        {
            //return from the method if the device index hasn't changed

            CodeStatement returnCondition =
                new CodeConditionStatement(
                    new CodeBinaryOperatorExpression(GraphicsDeviceUID, CodeBinaryOperatorType.IdentityEquality, new CodePropertyReferenceExpression(ShaderSystemRef, "DeviceUniqueIndex")),
                    new CodeMethodReturnStatement());

            add(returnCondition, "Shader is already warmed");

            //this doesn't happen for extended classes
            if (shader.SourceShader.GetShaderExtension(this.techniqueName) == null)
            {
                add(validateDeviceId, "Setup the shader");
            }
            else
            {
                //however the base class Warm method is called
                CodeExpression baseCall = new CodeMethodInvokeExpression(
                    new CodeBaseReferenceExpression(), "WarmShader", shader.ShaderSystemRef);

                add(shader.ETS(baseCall), null);

                //and assign the g uid
                CodeStatement assign = new CodeAssignStatement(
                    GraphicsDeviceUID, new CodePropertyReferenceExpression(ShaderSystemRef, "DeviceUniqueIndex"));

                add(assign, null);
            }
        }
		public override void AddReadonlyMembers(IShaderDom shader, Action<CodeTypeMember, string> add, Platform platform)
		{
			if (platform != Platform.Both)
				return;
		
			if (vsReg.FloatRegisterCount > 0)
			{
				CodeMemberField field = CreateShaderBufferField(shader, vsReg, shader.VertexShaderRegistersRef.FieldName);

				add(field, "Vertex shader register storage");
			}

			//and the PS

			if (psReg.FloatRegisterCount > 0)
			{
				CodeMemberField field = CreateShaderBufferField(shader, psReg, shader.PixelShaderRegistersRef.FieldName);

				add(field, "Pixel shader register storage");
			}


			//now do the boolean registers
			if (vsReg.BooleanRegisterCount > 0)
			{
				//create the vertex boolean registers
				CodeMemberField field = new CodeMemberField(typeof(bool[]), shader.VertexShaderBooleanRegistersRef.FieldName);
				field.Attributes = MemberAttributes.Private | MemberAttributes.Final;

				add(field, "Vertex shader boolean register storage");
			}
			//now the PS
			if (psReg.BooleanRegisterCount > 0)
			{
				//create the vertex boolean registers
				CodeMemberField field = new CodeMemberField(typeof(bool[]), shader.PixelShaderBooleanRegistersRef.FieldName);
				field.Attributes = MemberAttributes.Private | MemberAttributes.Final;

				add(field, "Pixel shader boolean register storage");
			}

			//blending
			if (vsBlendingReg != null && vsBlendingReg.FloatRegisterCount > 0 && shader.SourceShader.ManualExtensions)
			{
				CodeMemberField field = CreateShaderBufferField(shader, vsBlendingReg, shader.BlendShaderRegistersRef.FieldName);

				add(field, "Blend shader register storage");
			}
			//instancing
			if (vsInstancingReg != null && vsInstancingReg.FloatRegisterCount > 0)
			{
				CodeMemberField field = CreateShaderBufferField(shader, vsInstancingReg, shader.InstancingShaderRegistersRef.FieldName);

				add(field, "Instancing shader register storage");
			}
		}
Example #13
0
        public override void AddMembers(IShaderDom shader, Action <CodeTypeMember, string> add, Platform platform)
        {
            if (platform != Platform.Both)
            {
                return;
            }

            //if samplers are used, a integer is stored which will use bit masking
            //each bit represents if the sampler is dirty

            if (psSamplers.Count > 0)
            {
                //create mask
                CodeMemberField field = new CodeMemberField(typeof(int), "psm");
                field.Attributes = MemberAttributes.Private | MemberAttributes.Final;

                add(field, "Pixel Sampler dirty state bitmask");
            }

            if (vsSamplers.Count > 0)
            {
                //create mask
                CodeMemberField field = new CodeMemberField(typeof(int), "vsm");
                field.Attributes = MemberAttributes.Private | MemberAttributes.Final;

                add(field, "Vertex Sampler dirty state bitmask");
            }

            //add the sampler members
            foreach (SharedSampler ss in allSamplers.Values)
            {
                CodeMemberField field = new CodeMemberField(typeof(Xen.Graphics.State.TextureSamplerState), "ts" + ss.Index);
                field.Attributes = MemberAttributes.Private | MemberAttributes.Family;

                add(field, string.Format("Sampler state for '{0} {1}'", Common.ToUpper(ss.SamplerDetails.Type), ss.SamplerDetails.Name));
            }

            //add the texture members
            for (int i = 0; i < textures.Length; i++)
            {
                TextureAssociation tex = textures[i];
                if (tex.PsSamplers.Count > 0 || tex.VsSamplers.Count > 0)                 //only add if they are used
                {
                    CodeMemberField field = new CodeMemberField(Common.GetTextureType(tex.Texture.Type), "tx" + i);
                    field.Attributes = MemberAttributes.Private | MemberAttributes.Family;

                    add(field, string.Format("Bound texture for '{0} {1}'", tex.Texture.Type, tex.Texture.Name));
                }
            }

            //create the properties for the sampler states
            GenerateProperties(shader, add);

            GenerateNameIds(shader, add);
        }
Example #14
0
        public override void AddMembers(IShaderDom shader, Action <CodeTypeMember, string> add, Platform platform)
        {
            //create static ID's for the registers
            if (platform != Platform.Both)
            {
                return;
            }

            //static id's for named attributes
            for (int i = 0; i < attributeNames.Count; i++)
            {
                //static id of this attribute name
                CodeMemberField field = new CodeMemberField(typeof(int), attributeFields[i].FieldName);
                field.Attributes = MemberAttributes.Static | MemberAttributes.Private | MemberAttributes.Final;

                add(field, string.Format("Name ID for '{0}'", attributeNames[i]));


                CreateConstantSetters(shader, add, attributeNames[i], attributeFields[i], attributeArrayFields[i]);
            }

            //add the semantic change IDs
            foreach (SemanticMapping mapping in semanticMapping)
            {
                for (int i = 0; i < mapping.ChangeRefs.Length; i++)
                {
                    CodeMemberField field = new CodeMemberField(typeof(int), mapping.ChangeRefs[i].FieldName);
                    field.Attributes = MemberAttributes.Private | MemberAttributes.Final;

                    add(field, i != 0 ? null : string.Format("Change ID for Semantic bound attribute '{0}'", mapping.Register.Name));
                }
            }

            //add the global refs and ids


            //add the global change IDs
            foreach (GlobalAttribute global in globals)
            {
                //global ID staics
                CodeMemberField field = new CodeMemberField(typeof(int), global.GlobalIdRef.FieldName);
                field.Attributes = MemberAttributes.Private | MemberAttributes.Final | MemberAttributes.Static;

                add(field, string.Format("TypeID for global attribute '{0} {1}'", global.Register.Type, global.Register.Name));

                for (int i = 0; i < global.ChangeRefs.Length; i++)
                {
                    field            = new CodeMemberField(typeof(int), global.ChangeRefs[i].FieldName);
                    field.Attributes = MemberAttributes.Private | MemberAttributes.Final;

                    add(field, i != 0 ? null : string.Format("Change ID for global attribute '{0} {1}'", global.Register.Type, global.Register.Name));
                }
            }
        }
Example #15
0
        public override void AddWarm(IShaderDom shader, Action <CodeStatement, string> add)
        {
            //dispose the shaders (if the exist)

            CodeBinaryOperatorExpression notNull = new CodeBinaryOperatorExpression(shader.VertexShaderRef, CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression((VertexShader)null));

            //dipose
            CodeConditionStatement disposer = new CodeConditionStatement(notNull,
                                                                         shader.ETS(new CodeMethodInvokeExpression(shader.VertexShaderRef, "Dispose")));

            add(disposer, null);

            //ps
            notNull = new CodeBinaryOperatorExpression(shader.PixelShaderRef, CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression((PixelShader)null));

            //dipose
            disposer = new CodeConditionStatement(notNull,
                                                  shader.ETS(new CodeMethodInvokeExpression(shader.PixelShaderRef, "Dispose")));
            add(disposer, null);


            //and then recreate them using the shader system

            //state.CreateShaders(out ShadowShader.vs, out ShadowShader.ps, ShadowShader.vsb, ShadowShader.psb, 23, 15, 3, 0);


            int vsInstructions = asmTechnique.VertexShader.GetCommandCount() - 1;
            int psInstructions = asmTechnique.PixelShader.GetCommandCount() - 1;

            int vsPreShaderInstructions = 0;
            int psPreShaderInstructions = 0;

            if (asmTechnique.VertexPreShader != null)
            {
                psPreShaderInstructions = asmTechnique.VertexPreShader.GetCommandCount() - 1;
            }
            if (asmTechnique.PixelPreShader != null)
            {
                psPreShaderInstructions = asmTechnique.PixelPreShader.GetCommandCount() - 1;
            }

            CodeExpression create = new CodeMethodInvokeExpression(shader.ShaderSystemRef, "CreateShaders",
                                                                   new CodeDirectionExpression(FieldDirection.Out, shader.VertexShaderRef),
                                                                   new CodeDirectionExpression(FieldDirection.Out, shader.PixelShaderRef),
                                                                   shader.VertexShaderBytesRef,
                                                                   shader.PixelShaderBytesRef,
                                                                   new CodePrimitiveExpression(vsInstructions),
                                                                   new CodePrimitiveExpression(psInstructions),
                                                                   new CodePrimitiveExpression(vsPreShaderInstructions),
                                                                   new CodePrimitiveExpression(psPreShaderInstructions));

            add(shader.ETS(create), "Create the shader instances");
        }
Example #16
0
        public override void AddSetAttribute(IShaderDom shader, Action <CodeStatement> add, Type type)
        {
            List <CodeStatement> statements;

            if (attributeAssignment.TryGetValue(type, out statements))
            {
                foreach (CodeStatement statement in statements)
                {
                    add(statement);
                }
            }
        }
Example #17
0
        public override void AddStaticGraphicsInit(IShaderDom shader, Action <CodeStatement, string> add)
        {
            //initalise the static UIDs

            foreach (SharedSampler ss in allSamplers.Values)
            {
                //set the uid for the sampler

                CodeExpression uid = new CodeFieldReferenceExpression(shader.ShaderClassEx, "sid" + ss.Index);

                CodeExpression call = new CodeMethodInvokeExpression(
                    new CodeMethodReferenceExpression(shader.ShaderSystemRef, "GetNameUniqueID"),
                    new CodePrimitiveExpression(ss.SamplerDetails.Name));

                CodeStatement assign = new CodeAssignStatement(uid, call);

                add(assign, null);
            }

            //and all the textures
            for (int i = 0; i < textures.Length; i++)
            {
                TextureAssociation tex = textures[i];

                if (tex.PsSamplers.Count > 0 || tex.VsSamplers.Count > 0)
                {
                    //set the uid for the sampler

                    CodeExpression uid = new CodeFieldReferenceExpression(shader.ShaderClassEx, "tid" + i);

                    CodeExpression call = new CodeMethodInvokeExpression(
                        new CodeMethodReferenceExpression(shader.ShaderSystemRef, "GetNameUniqueID"),
                        new CodePrimitiveExpression(tex.Texture.Name));

                    if (tex.IsGlobal)
                    {
                        //slightly differnet for globals. Need to call generic getter for the global index
                        call = new CodeMethodInvokeExpression(
                            new CodeMethodReferenceExpression(shader.ShaderSystemRef, "GetGlobalUniqueID", new CodeTypeReference(Common.GetTextureType(tex.Texture.Type))),
                            new CodePrimitiveExpression(tex.Texture.Name));
                    }

                    CodeStatement assign = new CodeAssignStatement(uid, call);

                    add(assign, null);
                }
            }
        }
Example #18
0
        public override void AddChangedCondition(IShaderDom shader, Action <CodeExpression> add)
        {
            if (psSamplers.Count > 0)
            {
                //add the PS sampler mask
                CodeExpression mask = new CodeFieldReferenceExpression(shader.Instance, "psm");
                add(new CodeBinaryOperatorExpression(mask, CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(0)));
            }

            if (vsSamplers.Count > 0)
            {
                //add the VS sampler mask
                CodeExpression mask = new CodeFieldReferenceExpression(shader.Instance, "vsm");
                add(new CodeBinaryOperatorExpression(mask, CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(0)));
            }
        }
Example #19
0
        public override void AddReadonlyMembers(IShaderDom shader, Action <CodeTypeMember, string> add, Platform platform)
        {
            if (platform != Platform.Both)
            {
                return;
            }

            for (int i = 0; i < attributeNames.Count; i++)
            {
                //if it's an array, it needs an array object...

                Register reg;
                Type     dataType;

                if (ExtractRegType(attributeNames[i], out reg, out dataType) && reg.ArraySize != -1)
                {
                    //get the interface type for the field.
                    Type interfaceType = typeof(Xen.Graphics.ShaderSystem.Constants.IArray <float>).GetGenericTypeDefinition();
                    interfaceType = interfaceType.MakeGenericType(dataType);

                    CodeMemberField field = new CodeMemberField(interfaceType, this.attributeArrayFields[i].FieldName);
                    field.Attributes = MemberAttributes.Private | MemberAttributes.Final;

                    add(field, string.Format("Array wrapper for '{0} {1}[{2}]'", reg.Type, attributeNames[i], reg.ArraySize));
                }
            }

            //add the global array IDs (if there are any)
            foreach (GlobalAttribute global in globals)
            {
                for (int i = 0; i < global.ChangeRefs.Length; i++)
                {
                    //if it's an array, also add the array objects
                    if (global.Register.ArraySize != -1)
                    {
                        Type interfaceType = typeof(Xen.Graphics.ShaderSystem.Constants.IArray <float>).GetGenericTypeDefinition();
                        interfaceType = interfaceType.MakeGenericType(global.Type);

                        //arrays are stored differently.. eg as IArray<Matrix>
                        CodeMemberField field = new CodeMemberField(interfaceType, global.ArrayRefs[i].FieldName);
                        field.Attributes = MemberAttributes.Private | MemberAttributes.Final;

                        add(field, i != 0 ? null : string.Format("Array access for global attribute '{0} {1}[{2}]'", global.Register.Type, global.Register.Name, global.Register.ArraySize));
                    }
                }
            }
        }
Example #20
0
 public override void AddChangedCondition(IShaderDom shader, Action <CodeExpression> add)
 {
     if (vsReg.FloatRegisterCount > 0)
     {
         add(new CodeFieldReferenceExpression(shader.VertexShaderRegistersRef, "change"));
     }
     if (psReg.FloatRegisterCount > 0)
     {
         add(new CodeFieldReferenceExpression(shader.PixelShaderRegistersRef, "change"));
     }
     if (vsPreReg != null && vsPreReg.FloatRegisterCount > 0)
     {
         add(new CodeFieldReferenceExpression(shader.VertexPreShaderRegistersRef, "change"));
     }
     if (psPreReg != null && psPreReg.FloatRegisterCount > 0)
     {
         add(new CodeFieldReferenceExpression(shader.PixelPreShaderRegistersRef, "change"));
     }
 }
Example #21
0
        public override void AddMembers(IShaderDom shader, Action <CodeTypeMember, string> add, Platform platform)
        {
            //add pixel and static vertex shaders
            if (platform != Platform.Both)
            {
                return;
            }

            CodeMemberField field = new CodeMemberField(typeof(VertexShader), shader.VertexShaderRef.FieldName);

            field.Attributes = MemberAttributes.Private | MemberAttributes.Final | MemberAttributes.Static;

            add(field, "Static vertex shader instance");

            //ps
            field            = new CodeMemberField(typeof(PixelShader), shader.PixelShaderRef.FieldName);
            field.Attributes = MemberAttributes.Private | MemberAttributes.Final | MemberAttributes.Static;

            add(field, "Static pixel shader instance");
        }
		private void ProcessConstants(IShaderDom shader)
		{
			RegisterSet registers = asm.CommonRegisters;

			for (int i = 0; i < registers.RegisterCount; i++)
			{
				Register reg = registers.GetRegister(i);
				if (reg.Category == RegisterCategory.Float4 ||
					reg.Category == RegisterCategory.Boolean)
				{
					if (reg.Semantic == null)
						this.attributeNames.Add(reg.Name);
					else
						ExtractSemantic(shader, reg);
				}
				else if (reg.Semantic != null && reg.Category != RegisterCategory.Texture && reg.Category != RegisterCategory.Sampler)
				{
					throw new CompileException(string.Format("Error parsing semantic for '{1} {0}'. Semantic bound types may only be processed as Float4, Texture or Sampler registers", reg.Name, reg.Type));
				}
			}
		}
Example #23
0
        public override void AddStaticGraphicsInit(IShaderDom shader, Action <CodeStatement, string> add)
        {
            //initalise the static ID's

            for (int i = 0; i < attributeNames.Count; i++)
            {
                //call state.GetNameUniqueID()

                CodeExpression call = new CodeMethodInvokeExpression(
                    new CodeMethodReferenceExpression(shader.ShaderSystemRef, "GetNameUniqueID"),
                    new CodePrimitiveExpression(attributeNames[i]));

                CodeStatement assign = new CodeAssignStatement(attributeFields[i], call);

                add(assign, null);
            }

            //setup the TypeIDs for global attributes
            //eg:
            //ShadowShaderBlend.g_id0 = state.GetGlobalUniqueID<Microsoft.Xna.Framework.Matrix[]>("shadowMapProjection");

            foreach (GlobalAttribute global in globals)
            {
                //call state.GetGlobalUniqueID()
                Type type = global.Type;
                if (global.Register.ArraySize != -1)
                {
                    type = type.MakeArrayType();
                }

                CodeExpression call = new CodeMethodInvokeExpression(
                    new CodeMethodReferenceExpression(shader.ShaderSystemRef, "GetGlobalUniqueID", new CodeTypeReference(type)),
                    new CodePrimitiveExpression(global.Register.Name));

                CodeStatement assign = new CodeAssignStatement(global.GlobalIdRef, call);

                add(assign, null);
            }
        }
Example #24
0
        public override void AddMembers(IShaderDom shader, Action <CodeTypeMember, string> add, Platform platform)
        {
            if (platform != Platform.Both)
            {
                return;
            }

            //add change values for boolean registers
            if (vsReg.BooleanRegisterCount > 0)
            {
                CodeMemberField field = new CodeMemberField(typeof(bool), shader.VertexShaderBooleanRegistersChangedRef.FieldName);
                field.Attributes = MemberAttributes.Private | MemberAttributes.Final;
                add(field, null);
            }
            //now the PS
            if (psReg.BooleanRegisterCount > 0)
            {
                CodeMemberField field = new CodeMemberField(typeof(bool), shader.PixelShaderBooleanRegistersChangedRef.FieldName);
                field.Attributes = MemberAttributes.Private | MemberAttributes.Final;
                add(field, null);
            }
        }
Example #25
0
        public override void AddBind(IShaderDom shader, Action <CodeStatement, string> add)
        {
            //call the preshaders

            if (vertexPreShader != null)
            {
                CodeExpression call      = new CodeMethodInvokeExpression(shader.Instance, "vspre");
                CodeExpression condition = new CodeBinaryOperatorExpression(new CodeFieldReferenceExpression(shader.VertexPreShaderRegistersRef, "change"), CodeBinaryOperatorType.IdentityEquality, new CodePrimitiveExpression(true));
                CodeStatement  invoke    = new CodeConditionStatement(condition, shader.ETS(call));

                add(invoke, "run the vertex preshader");
            }

            //pixel
            if (pixelPreShader != null)
            {
                CodeExpression call      = new CodeMethodInvokeExpression(shader.Instance, "pspre");
                CodeExpression condition = new CodeBinaryOperatorExpression(new CodeFieldReferenceExpression(shader.PixelPreShaderRegistersRef, "change"), CodeBinaryOperatorType.IdentityEquality, new CodePrimitiveExpression(true));
                CodeStatement  invoke    = new CodeConditionStatement(condition, shader.ETS(call));

                add(invoke, "run the pixel preshader");
            }
        }
Example #26
0
        public override void AddReadonlyMembers(IShaderDom shader, Action <CodeTypeMember, string> add, Platform platform)
        {
            Platform?writePlatform = null;

            if (this.platform == Platform.Both)
            {
                //shader is being built for both PC and xbox
                if (platform != Platform.Both)                 // writing system specific shader
                {
                    writePlatform = platform;
                }
            }
            else
            {
                //shader is being built for just one platform
                writePlatform = this.platform;
            }

            if (writePlatform == null)
            {
                return;
            }

            if (writePlatform.Value == Platform.Windows)
            {
                //write windows
                WriteBytes(shader, shader.VertexShaderBytesRef.FieldName, this.vsBytesPc, add, shader.CompileDirectives, true, false);
                WriteBytes(shader, shader.PixelShaderBytesRef.FieldName, this.psBytesPc, add, shader.CompileDirectives, false, false);
            }
            else
            {
                //write xbox
                WriteBytes(shader, shader.VertexShaderBytesRef.FieldName, this.vsBytesXbox, add, shader.CompileDirectives, true, true);
                WriteBytes(shader, shader.PixelShaderBytesRef.FieldName, this.psBytesXbox, add, shader.CompileDirectives, false, true);
            }
        }
		public virtual void AddStaticGraphicsInit(IShaderDom shader, Action<CodeStatement, string> add)
		{
		}
		public virtual void AddWarm(IShaderDom shader, Action<CodeStatement, string> add)
		{
		}
		//extract pairs of asmlistings / code registers
		private void ComputeListings(IShaderDom shader)
		{
			List<KeyValuePair<AsmListing, CodeExpression>> listings = new List<KeyValuePair<AsmListing, CodeExpression>>();

			if (asm.VertexShader != null)
				listings.Add(new KeyValuePair<AsmListing,CodeExpression>(asm.VertexShader, shader.VertexShaderRegistersRef));
			
			if (asm.PixelShader != null)
				listings.Add(new KeyValuePair<AsmListing,CodeExpression>(asm.PixelShader, shader.PixelShaderRegistersRef));

			if (asm.BlendingShader != null)
				listings.Add(new KeyValuePair<AsmListing, CodeExpression>(asm.BlendingShader, shader.BlendShaderRegistersRef));

			if (asm.InstancingShader != null)
				listings.Add(new KeyValuePair<AsmListing, CodeExpression>(asm.InstancingShader, shader.InstancingShaderRegistersRef));
			
			this.listingRegisters = listings.ToArray();
		}
		public override void AddReadonlyMembers(IShaderDom shader, Action<CodeTypeMember, string> add, Platform platform)
		{
			if (platform != Platform.Both)
				return;
			/*
			for (int i = 0; i < attributeNames.Count; i++)
			{
				//if it's an array, it needs an array object...

				Register reg;
				Type dataType;

				if (ExtractRegType(attributeNames[i], out reg, out dataType) && reg.ArraySize != -1)
				{
					//get the interface type for the field.
					Type interfaceType = typeof(Xen.Graphics.ShaderSystem.Constants.IArray<float>).GetGenericTypeDefinition();
					interfaceType = interfaceType.MakeGenericType(dataType);

					CodeMemberField field = new CodeMemberField(interfaceType, this.attributeArrayFields[i].FieldName);
					field.Attributes = MemberAttributes.Private | MemberAttributes.Final;

					add(field, string.Format("Array wrapper for '{0} {1}[{2}]'", reg.Type, attributeNames[i], reg.ArraySize));
				}
			}

			//add the global array IDs (if there are any)
			foreach (GlobalAttribute global in globals)
			{
				for (int i = 0; i < global.ChangeRefs.Length; i++)
				{
					//if it's an array, also add the array objects
					if (global.Register.ArraySize != -1)
					{
						Type interfaceType = typeof(Xen.Graphics.ShaderSystem.Constants.IArray<float>).GetGenericTypeDefinition();
						interfaceType = interfaceType.MakeGenericType(global.Type);

						//arrays are stored differently.. eg as IArray<Matrix>
						CodeMemberField field = new CodeMemberField(interfaceType, global.ArrayRefs[i].FieldName);
						field.Attributes = MemberAttributes.Private | MemberAttributes.Final;

						add(field, i != 0 ? null : string.Format("Array access for global attribute '{0} {1}[{2}]'", global.Register.Type, global.Register.Name, global.Register.ArraySize));
					}
				}
			}
			*/
		}
		public override void AddChangedCondition(IShaderDom shader, Action<CodeExpression> add)
		{
			if (vsReg.FloatRegisterCount > 0)
				add(shader.VertexShaderRegistersChangedRef);
			if (psReg.FloatRegisterCount > 0)
				add(shader.PixelShaderRegistersChangedRef);
		}
Example #32
0
        public override void AddConstructor(IShaderDom shader, Action <CodeStatement> add)
        {
            //set the semantic change IDs to -1
            foreach (SemanticMapping mapping in semanticMapping)
            {
                for (int i = 0; i < mapping.ChangeRefs.Length; i++)
                {
                    CodeAssignStatement assign = new CodeAssignStatement(mapping.ChangeRefs[i], new CodePrimitiveExpression(-1));

                    add(assign);
                }
            }

            //init the array attributes
            for (int i = 0; i < attributeNames.Count; i++)
            {
                //if it's an array, it needs an array object...

                Register reg;
                Type     dataType;

                if (ExtractRegType(attributeNames[i], out reg, out dataType) && reg.ArraySize != -1)
                {
                    //things get a bit funky here.
                    //if the array is used by more than one register set, it must be wrapped up in a 'DualArray'
                    //so a call to 'SetValue' on the array gets passed to both copies.
                    //This can occur if both the vertex and pixel shader access a constant array, or a preshader, etc.
                    Type dualType = typeof(Xen.Graphics.ShaderSystem.Constants.DualArray <float>).GetGenericTypeDefinition();
                    dualType = dualType.MakeGenericType(dataType);

                    //this.attributeArrayFields[i].FieldName

                    CodeExpression initExpression = null;
                    Type           arrayType      = GetArrayType(reg);

                    foreach (KeyValuePair <AsmListing, CodeExpression> listing in listingRegisters)
                    {
                        Register       sreg;
                        RegisterSet    registers    = listing.Key.RegisterSet;
                        CodeExpression registersRef = listing.Value;

                        if (registers.TryGetRegister(reg.Name, out sreg))
                        {
                            CodeExpression create;

                            create = new CodeObjectCreateExpression(arrayType,
                                                                    registersRef, //vreg
                                                                    new CodePrimitiveExpression(sreg.Index),
                                                                    new CodePrimitiveExpression(sreg.Size));

                            if (initExpression == null)
                            {
                                initExpression = create;
                            }
                            else
                            {
                                //darn. wrap in a dual array.
                                initExpression = new CodeObjectCreateExpression(
                                    dualType,
                                    create, initExpression);
                            }
                        }
                    }

                    CodeAssignStatement assign = new CodeAssignStatement(this.attributeArrayFields[i], initExpression);
                    add(assign);
                }
            }

            //set the global change IDs to -1 (unless it's an array)...
            foreach (GlobalAttribute global in globals)
            {
                int changeRefIndex = 0;
                foreach (KeyValuePair <AsmListing, CodeExpression> listing in listingRegisters)
                {
                    Register       sreg;
                    RegisterSet    registers    = listing.Key.RegisterSet;
                    CodeExpression registersRef = listing.Value;

                    if (registers.TryGetRegister(global.Register.Name, out sreg) && sreg.Category != RegisterCategory.Boolean)
                    {
                        CodeAssignStatement assign = new CodeAssignStatement(global.ChangeRefs[changeRefIndex], new CodePrimitiveExpression(-1));

                        add(assign);


                        //arrays require the array wrapper to be initalised
                        if (global.Register.ArraySize != -1)
                        {
                            //arrays are stored differently.. eg as IArray<Matrix>
                            //eg:
                            //new Xen.Graphics.ShaderSystem.Constants.Matrix4Array(this.vreg, 217, 4);

                            Type arrayType = GetArrayType(global.Register);

                            CodeExpression create;

                            create = new CodeObjectCreateExpression(arrayType,
                                                                    registersRef, //vreg
                                                                    new CodePrimitiveExpression(sreg.Index),
                                                                    new CodePrimitiveExpression(sreg.Size));

                            assign = new CodeAssignStatement(global.ArrayRefs[changeRefIndex], create);
                            add(assign);
                        }

                        changeRefIndex++;
                    }
                }
            }
        }
		public virtual void Setup(IShaderDom shader)
		{
		}
		private void CreateConstantSetters(IShaderDom shader, Action<CodeTypeMember, string> add, string name, CodeExpression assignmentField, CodeExpression assignmentArrayField)
		{
			/*
			 * Something like:

			public void SetInvTargetSize(ref Microsoft.Xna.Framework.Vector2 value)
			{
				this.vreg.SetVector2(130, ref value);
			}

			public Microsoft.Xna.Framework.Vector2 InvTargetSize
			{
				set
				{
					this.SetInvTargetSize(ref value);
				}
			}*/

			Register reg;
			Type dataType;
			bool hasSetMethod;
			int stride;

			if (!ExtractRegType(name, out reg, out dataType, out hasSetMethod, out stride))
				return;

			Type arrayOrSingleType = dataType;

			//right...

			//create the method of the given type.


			//public void SetInvTargetSize(ref Microsoft.Xna.Framework.Vector2 value)
			CodeStatementCollection methodStatements = new CodeStatementCollection();

			CodeParameterDeclarationExpression param = new CodeParameterDeclarationExpression(dataType, "value");
			List<CodeParameterDeclarationExpression> additionalParams = new List<CodeParameterDeclarationExpression>();

			if (reg.ArraySize == -1)
				param.Direction = FieldDirection.Ref;
			else
			{
				arrayOrSingleType = dataType.MakeArrayType();
				param.Type = new CodeTypeReference(arrayOrSingleType);

				//add array params, readIndex, writeIndex, count
				additionalParams.Add(new CodeParameterDeclarationExpression(typeof(uint), "readIndex"));
				additionalParams.Add(new CodeParameterDeclarationExpression(typeof(uint), "writeIndex"));
				additionalParams.Add(new CodeParameterDeclarationExpression(typeof(uint), "count"));
			}

			CodeExpression valueRef = new CodeArgumentReferenceExpression(param.Name);

			//when there isn't a set method, there is just a set property
			if (!hasSetMethod)
				valueRef = new CodePropertySetValueReferenceExpression();

			//create the guts
			//depends on what constants use it...

			//eg:
			//this.vreg.SetVector2(130, ref value);

			Register sreg;

			if (dataType == typeof(bool))
			{
				//special case for booleans, assign the array directly.
				//looks like:
				// 
				// if (preg_bool[index] != value)
				// {
				//  preg_bool[index] = value;
				//  preg_bool_changed = true;
				// }

				foreach (KeyValuePair<AsmListing, CodeExpression> listing in listingRegisters)
				{
					RegisterSet registers = listing.Key.RegisterSet;
					CodeExpression registersRef = listing.Value;

					if (registers.TryGetRegister(name, out sreg))
					{
						if (listing.Key == asm.PixelShader)
						{
							CodeExpression arrayIndex = new CodeArrayIndexerExpression(shader.PixelShaderBooleanRegistersRef, new CodePrimitiveExpression(sreg.Index));

							CodeStatement assign = new CodeAssignStatement(arrayIndex, new CodePropertySetValueReferenceExpression());
							CodeStatement change = new CodeAssignStatement(shader.PixelShaderBooleanRegistersChangedRef, new CodePrimitiveExpression(true));

							CodeStatement condition = new CodeConditionStatement(
								new CodeBinaryOperatorExpression(arrayIndex, CodeBinaryOperatorType.IdentityInequality, new CodePropertySetValueReferenceExpression()),
								new CodeStatement[]{assign, change});

							methodStatements.Add(condition);
						}
						if (listing.Key == asm.VertexShader)
						{
							CodeExpression arrayIndex = new CodeArrayIndexerExpression(shader.VertexShaderBooleanRegistersRef, new CodePrimitiveExpression(sreg.Index));

							CodeStatement assign = new CodeAssignStatement(arrayIndex, new CodePropertySetValueReferenceExpression());
							CodeStatement change = new CodeAssignStatement(shader.VertexShaderBooleanRegistersChangedRef, new CodePrimitiveExpression(true));

							CodeStatement condition = new CodeConditionStatement(
								new CodeBinaryOperatorExpression(arrayIndex, CodeBinaryOperatorType.IdentityInequality, new CodePropertySetValueReferenceExpression()),
								new CodeStatement[] { assign, change });

							methodStatements.Add(condition);
						}
					}
				}
			}
			else
			{
				//some array set methods require temporary values, but should only be created once.
				bool tempValuesCreated = false;

				foreach (KeyValuePair<AsmListing, CodeExpression> listing in listingRegisters)
				{
					RegisterSet registers = listing.Key.RegisterSet;
					CodeExpression registersRef = listing.Value;

					if (registers.TryGetRegister(name, out sreg))
					{
						//Assign the register array data
						AssignRegister(dataType, sreg, reg, listing.Value, valueRef, methodStatements, ref tempValuesCreated);

						//set changed
						CodeExpression changeValue = new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), (registersRef as CodeFieldReferenceExpression).FieldName + "_change");

						methodStatements.Add(new CodeAssignStatement(changeValue, new CodePrimitiveExpression(true)));
					}
				}
			}

			string upperName = Common.ToUpper(name);

			//there is always a setable property
			CodeMemberProperty property = new CodeMemberProperty();
			property.Name = upperName;
			property.Type = param.Type;
			property.Attributes = MemberAttributes.Final | MemberAttributes.Public;
			property.HasSet = true;
			property.HasGet = false;

			//there isn't always a set method
			CodeMemberMethod method = null;

			CodeStatement assignAttribute = null;

			if (hasSetMethod || reg.ArraySize != -1)
			{
				//create the method to set the value
				string methodName = "Set" + upperName;

				method = new CodeMemberMethod();
				method.Name = methodName;
				method.Attributes = MemberAttributes.Final | MemberAttributes.Public;

				method.Parameters.Add(param);
				method.Parameters.AddRange(additionalParams.ToArray());
				method.Statements.AddRange(methodStatements);


				//create a property that calls the Set method

				//is not an array
				CodeMethodInvokeExpression invokeSetter =
					new CodeMethodInvokeExpression(
						shader.Instance, method.Name,
						new CodeDirectionExpression(reg.ArraySize == -1 ? FieldDirection.Ref : FieldDirection.In, new CodePropertySetValueReferenceExpression()));

				if (reg.ArraySize != -1)
				{
					//add method ops (readIndex, writeIndex, count)
					invokeSetter.Parameters.Add(new CodePrimitiveExpression(0));
					invokeSetter.Parameters.Add(new CodePrimitiveExpression(0));
					invokeSetter.Parameters.Add(new CodeCastExpression(typeof(uint), new CodePropertyReferenceExpression(valueRef, "Length")));
				}

				property.SetStatements.Add(invokeSetter);



				//call the method as well for attribute assign
				CodeMethodInvokeExpression assignSetter = 
					new CodeMethodInvokeExpression(
						shader.Instance, method.Name,
						new CodeDirectionExpression(param.Direction, shader.AttributeAssignValue));

				if (reg.ArraySize != -1)
				{
					//add method ops (readIndex, writeIndex, count)
					assignSetter.Parameters.Add(new CodePrimitiveExpression(0));
					assignSetter.Parameters.Add(new CodePrimitiveExpression(0));
					assignSetter.Parameters.Add(new CodeCastExpression(typeof(uint), new CodePropertyReferenceExpression(valueRef, "Length")));
				}

				assignAttribute = shader.ETS(assignSetter);
			}
			else
			{
				//create a property to directly set the value

				property.SetStatements.AddRange(methodStatements);

				//attribute assign sets the property
				assignAttribute = new CodeAssignStatement(
					new CodePropertyReferenceExpression(shader.Instance, property.Name),
						shader.AttributeAssignValue);
			}
			

			if (reg.ArraySize > 0)
			{
				if (method != null)
					add(method, string.Format("Set the shader array value '{0} {1}[{2}]'", reg.Type, reg.Name, reg.ArraySize));
				add(property, string.Format("Set and copy the array data for the shader value '{0} {1}[{2}]'", reg.Type, reg.Name, reg.ArraySize));
			}
			else
			{
				if (method != null)
					add(method, string.Format("Set the shader value '{0} {1}'", reg.Type, reg.Name));
				add(property, string.Format("Assign the shader value '{0} {1}'", reg.Type, reg.Name));
			}

			//create the attribute assignment value statement.

			List<CodeStatement> assignList;
			if (!attributeAssignment.TryGetValue(arrayOrSingleType, out assignList))
			{
				assignList = new List<CodeStatement>();
				attributeAssignment.Add(arrayOrSingleType, assignList);
			}

			//create the statement...
			
			CodeExpression assignIdsMatch =
				new CodeBinaryOperatorExpression(shader.AttributeAssignId,  CodeBinaryOperatorType.IdentityEquality, assignmentField);

			CodeConditionStatement performAssign =
				new CodeConditionStatement(assignIdsMatch,
					assignAttribute, //call the assignment code
					new CodeMethodReturnStatement(new CodePrimitiveExpression(true))); //return true, set correctly.

			assignList.Add(performAssign);
		}
		//add the member fields
		public override void SetupMembers(IShaderDom shader)
		{
			ComputeListings(shader);

			ProcessConstants(shader);

			for (int i = 0; i < attributeNames.Count; i++)
			{
				//create a field ref for the static that will be created
				//these are used to assign the value using 'SetAttribute'
				CodeFieldReferenceExpression field = new CodeFieldReferenceExpression(shader.ShaderClassEx, string.Format("cid{0}",i));
				this.attributeFields.Add(field);

				//if it's an array, an array object needs to be created too. Create the ref to it now

				field = null;

				Register reg;
				Type type;//unused
				
				if (ExtractRegType(attributeNames[i], out reg, out type) && reg.ArraySize != -1)
					field = new CodeFieldReferenceExpression(shader.Instance, string.Format("ca{0}", i));

				attributeArrayFields.Add(field);//may be null.
			}
		}
		public override void AddBindBegin(IShaderDom shader, Action<CodeStatement, string> add)
		{
			CodeExpression devIndex = new CodeFieldReferenceExpression(shader.ShaderSystemRef, "DeviceUniqueIndex");

			//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;

			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)));

			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.

		}
		public override void AddStaticGraphicsInit(IShaderDom shader, Action<CodeStatement, string> add)
		{
			//assign the static graphics ID
			CodeExpression deviceId = new CodePropertyReferenceExpression(ShaderSystemRef, "DeviceUniqueIndex");
			CodeStatement assign = new CodeAssignStatement(gdIndexRef, deviceId);
			add(assign, "set the graphics ID");

			assign = new CodeAssignStatement(new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), "GraphicsID"), deviceId);
			add(assign, null);
		}
		public override void AddMembers(IShaderDom shader, Action<CodeTypeMember, string> add, Platform platform)
		{
			if (platform != Platform.Both)
				return;

			//static graphics ID
			CodeMemberField field = new CodeMemberField(typeof(int),gdIndexRef.FieldName);
			field.Attributes = MemberAttributes.Static | MemberAttributes.Final | MemberAttributes.Private;
			add(field,"Static graphics ID");
		}
		public override void AddConstructor(IShaderDom shader, Action<CodeStatement> add)
		{
			//set the semantic change IDs to -1
			foreach (SemanticMapping mapping in semanticMapping)
			{
				for (int i = 0; i < mapping.ChangeRefs.Length; i++)
				{
					CodeAssignStatement assign = new CodeAssignStatement(mapping.ChangeRefs[i], new CodePrimitiveExpression(-1));

					add(assign);
				}
			}

			//set the global change IDs to -1
			foreach (GlobalAttribute global in globals)
			{
				int changeRefIndex = 0;
				foreach (KeyValuePair<AsmListing, CodeExpression> listing in listingRegisters)
				{
					Register sreg;
					RegisterSet registers = listing.Key.RegisterSet;
					CodeExpression registersRef = listing.Value;

					if (registers.TryGetRegister(global.Register.Name, out sreg) && sreg.Category != RegisterCategory.Boolean)
					{
						CodeAssignStatement assign = new CodeAssignStatement(global.ChangeRefs[changeRefIndex], new CodePrimitiveExpression(-1));

						add(assign);

						changeRefIndex++;
					}
				}
			}
		}
		public virtual void AddStaticConstructor(IShaderDom shader, Action<CodeStatement> add)
		{
		}
		public virtual void AddReadonlyMembers(IShaderDom shader, Action<CodeTypeMember, string> add, Platform platform)
		{
		}
		public override void AddSetAttribute(IShaderDom shader, Action<CodeStatement> add, Type type)
		{
			List<CodeStatement> statements;

			if (attributeAssignment.TryGetValue(type, out statements))
			{
				foreach (CodeStatement statement in statements)
				{
					add(statement);
				}
			}
		}
Example #43
0
        private void CreateConstantSetters(IShaderDom shader, Action <CodeTypeMember, string> add, string name, CodeExpression assignmentField, CodeExpression assignmentArrayField)
        {
            /*
             * Something like:
             *
             * public void SetInvTargetSize(ref Microsoft.Xna.Framework.Vector2 value)
             * {
             *      this.vreg.SetVector2(130, ref value);
             * }
             *
             * public Microsoft.Xna.Framework.Vector2 InvTargetSize
             * {
             *      set
             *      {
             *              this.SetInvTargetSize(ref value);
             *      }
             * }*/

            Register reg;
            Type     dataType;
            bool     hasSetMethod;
            int      stride;

            if (!ExtractRegType(name, out reg, out dataType, out hasSetMethod, out stride))
            {
                return;
            }

            Type arrayOrSingleType = dataType;

            //right...

            //create the method of the given type.


            //public void SetInvTargetSize(ref Microsoft.Xna.Framework.Vector2 value)
            CodeStatementCollection methodStatements = new CodeStatementCollection();

            CodeParameterDeclarationExpression param = new CodeParameterDeclarationExpression(dataType, "value");

            if (reg.ArraySize == -1)
            {
                param.Direction = FieldDirection.Ref;
            }
            else
            {
                arrayOrSingleType = dataType.MakeArrayType();
                param.Type        = new CodeTypeReference(arrayOrSingleType);
            }

            CodeExpression valueRef = new CodeArgumentReferenceExpression(param.Name);

            //when there isn't a set method, there is just a set property
            if (!hasSetMethod)
            {
                valueRef = new CodePropertySetValueReferenceExpression();
            }

            //create the guts
            //depends on what constants use it...

            //eg:
            //this.vreg.SetVector2(130, ref value);

            Register sreg;

            if (dataType == typeof(bool))
            {
                //special case for booleans, assign the array directly.
                //looks like:
                //
                // if (preg_bool[index] != value)
                // {
                //  preg_bool[index] = value;
                //  preg_bool_changed = true;
                // }

                foreach (KeyValuePair <AsmListing, CodeExpression> listing in listingRegisters)
                {
                    RegisterSet    registers    = listing.Key.RegisterSet;
                    CodeExpression registersRef = listing.Value;

                    if (registers.TryGetRegister(name, out sreg))
                    {
                        if (listing.Key == asm.PixelShader)
                        {
                            CodeExpression arrayIndex = new CodeArrayIndexerExpression(shader.PixelShaderBooleanRegistersRef, new CodePrimitiveExpression(sreg.Index));

                            CodeStatement assign = new CodeAssignStatement(arrayIndex, new CodePropertySetValueReferenceExpression());
                            CodeStatement change = new CodeAssignStatement(shader.PixelShaderBooleanRegistersChangedRef, new CodePrimitiveExpression(true));

                            CodeStatement condition = new CodeConditionStatement(
                                new CodeBinaryOperatorExpression(arrayIndex, CodeBinaryOperatorType.IdentityInequality, new CodePropertySetValueReferenceExpression()),
                                new CodeStatement[] { assign, change });

                            methodStatements.Add(condition);
                        }
                        if (listing.Key == asm.VertexShader)
                        {
                            CodeExpression arrayIndex = new CodeArrayIndexerExpression(shader.VertexShaderBooleanRegistersRef, new CodePrimitiveExpression(sreg.Index));

                            CodeStatement assign = new CodeAssignStatement(arrayIndex, new CodePropertySetValueReferenceExpression());
                            CodeStatement change = new CodeAssignStatement(shader.VertexShaderBooleanRegistersChangedRef, new CodePrimitiveExpression(true));

                            CodeStatement condition = new CodeConditionStatement(
                                new CodeBinaryOperatorExpression(arrayIndex, CodeBinaryOperatorType.IdentityInequality, new CodePropertySetValueReferenceExpression()),
                                new CodeStatement[] { assign, change });

                            methodStatements.Add(condition);
                        }
                    }
                }
            }
            else
            {
                string targetName = "Set" + dataType.Name;

                if (dataType == typeof(Matrix))
                {
                    targetName += stride;
                    targetName += "Transpose";
                }

                if (reg.ArraySize == -1)
                {
                    //not an array..

                    foreach (KeyValuePair <AsmListing, CodeExpression> listing in listingRegisters)
                    {
                        RegisterSet    registers    = listing.Key.RegisterSet;
                        CodeExpression registersRef = listing.Value;

                        if (registers.TryGetRegister(name, out sreg))
                        {
                            //set the regiser (eg, may be vertex shader register)
                            CodeExpression methodInvoke =
                                new CodeMethodInvokeExpression(registersRef, targetName,
                                                               new CodePrimitiveExpression(sreg.Index),
                                                               new CodeDirectionExpression(FieldDirection.Ref, valueRef));

                            methodStatements.Add(shader.ETS(methodInvoke));
                        }
                    }
                }
                else
                {
                    //is an array...
                    //simply call SetArray on the array object.
                    CodeExpression methodInvoke =
                        new CodeMethodInvokeExpression(assignmentArrayField, "SetArray",
                                                       valueRef);

                    methodStatements.Add(shader.ETS(methodInvoke));
                }
            }

            string upperName = Common.ToUpper(name);

            //there is always a setable property
            CodeMemberProperty property = new CodeMemberProperty();

            property.Name       = upperName;
            property.Type       = param.Type;
            property.Attributes = MemberAttributes.Final | MemberAttributes.Public;
            property.HasSet     = reg.ArraySize == -1;
            property.HasGet     = reg.ArraySize != -1;

            //there isn't always a set method
            CodeMemberMethod method = null;

            CodeStatement assignAttribute = null;

            if (hasSetMethod || reg.ArraySize != -1)
            {
                //create the method to set the value
                string methodName = "Set" + upperName;

                method            = new CodeMemberMethod();
                method.Name       = methodName;
                method.Attributes = MemberAttributes.Final | MemberAttributes.Public;

                method.Parameters.Add(param);
                method.Statements.AddRange(methodStatements);


                //create a property that calls the Set method if not an array, get method if it is an array

                if (reg.ArraySize == -1)
                {
                    //is not an array
                    CodeExpression invokeSetter =
                        new CodeMethodInvokeExpression(
                            shader.Instance, method.Name,
                            new CodeDirectionExpression(FieldDirection.Ref, new CodePropertySetValueReferenceExpression()));

                    property.SetStatements.Add(invokeSetter);
                }
                else
                {
                    //is an array, return the array object directly.
                    property.GetStatements.Add(new CodeMethodReturnStatement(assignmentArrayField));

                    //set the type of the property to IArray<float>, etc
                    Type interfaceType = typeof(Xen.Graphics.ShaderSystem.Constants.IArray <float>).GetGenericTypeDefinition();
                    interfaceType = interfaceType.MakeGenericType(dataType);

                    property.Type = new CodeTypeReference(interfaceType);
                }



                //call the method as well for attribute assign
                CodeExpression assignSetter =
                    new CodeMethodInvokeExpression(
                        shader.Instance, method.Name,
                        new CodeDirectionExpression(param.Direction, shader.AttributeAssignValue));

                assignAttribute = shader.ETS(assignSetter);
            }
            else
            {
                //create a property to directly set the value

                property.SetStatements.AddRange(methodStatements);

                //attribute assign sets the property
                assignAttribute = new CodeAssignStatement(
                    new CodePropertyReferenceExpression(shader.Instance, property.Name),
                    shader.AttributeAssignValue);
            }


            if (reg.ArraySize > 0)
            {
                if (method != null)
                {
                    add(method, string.Format("Set the shader array value '{0} {1}[{2}]'", reg.Type, reg.Name, reg.ArraySize));
                }
                add(property, string.Format("Get the array for the shader value '{0} {1}[{2}]'", reg.Type, reg.Name, reg.ArraySize));
            }
            else
            {
                if (method != null)
                {
                    add(method, string.Format("Set the shader value '{0} {1}'", reg.Type, reg.Name));
                }
                add(property, string.Format("Assign the shader value '{0} {1}'", reg.Type, reg.Name));
            }

            //create the attribute assignment value statement.

            List <CodeStatement> assignList;

            if (!attributeAssignment.TryGetValue(arrayOrSingleType, out assignList))
            {
                assignList = new List <CodeStatement>();
                attributeAssignment.Add(arrayOrSingleType, assignList);
            }

            //create the statement...

            CodeExpression assignIdsMatch =
                new CodeBinaryOperatorExpression(shader.AttributeAssignId, CodeBinaryOperatorType.IdentityEquality, assignmentField);

            CodeConditionStatement performAssign =
                new CodeConditionStatement(assignIdsMatch,
                                           assignAttribute,                                                   //call the assignment code
                                           new CodeMethodReturnStatement(new CodePrimitiveExpression(true))); //return true, set correctly.

            assignList.Add(performAssign);
        }
Example #44
0
        public override void AddConstructor(IShaderDom shader, Action <CodeStatement> add)
        {
            //setup registers
            if (vsReg.FloatRegisterCount > 0)
            {
                //assign
                CodeExpression create = new CodeObjectCreateExpression(typeof(ConstantArray),
                                                                       new CodePrimitiveExpression(vsReg.FloatRegisterCount)); //create with the number of registers

                add(new CodeAssignStatement(shader.VertexShaderRegistersRef, create));

                //call the set method?
                int            offset;
                CodeExpression initArray = InitaliseConstants(vsReg.FloatRegisterCount, vsDefault, shader.CompileDirectives, out offset);

                if (initArray != null)
                {
                    //the array will be stored statically as a member, so not to leak.
                    string name = "vreg_def";
                    staticArrays.Add(name, initArray);

                    CodeMethodInvokeExpression setCall = new CodeMethodInvokeExpression(shader.VertexShaderRegistersRef, "Set",
                                                                                        new CodePrimitiveExpression(offset), new CodeFieldReferenceExpression(shader.ShaderClassEx, name)); // start from zero
                    add(shader.ETS(setCall));
                }
            }

            //and the PS

            if (psReg.FloatRegisterCount > 0)
            {
                //create the vertex registers
                CodeExpression create = new CodeObjectCreateExpression(typeof(ConstantArray),
                                                                       new CodePrimitiveExpression(psReg.FloatRegisterCount)); //create with the number of registers

                add(new CodeAssignStatement(shader.PixelShaderRegistersRef, create));

                //call the set method?
                int            offset;
                CodeExpression initArray = InitaliseConstants(psReg.FloatRegisterCount, psDefault, shader.CompileDirectives, out offset);

                if (initArray != null)
                {
                    //the array will be stored statically as a member, so not to leak.
                    string name = "preg_def";
                    staticArrays.Add(name, initArray);

                    CodeMethodInvokeExpression setCall = new CodeMethodInvokeExpression(shader.PixelShaderRegistersRef, "Set",
                                                                                        new CodePrimitiveExpression(offset), new CodeFieldReferenceExpression(shader.ShaderClassEx, name));
                    add(shader.ETS(setCall));
                }
            }


            //setup preshader registers
            if (vsPreReg != null && vsPreReg.FloatRegisterCount > 0)
            {
                CodeExpression create = new CodeObjectCreateExpression(typeof(ConstantArray),
                                                                       new CodePrimitiveExpression(vsPreReg.FloatRegisterCount)); //create with the number of registers
                add(new CodeAssignStatement(shader.VertexPreShaderRegistersRef, create));

                //call the set method?
                int            offset;
                CodeExpression initArray = GeneratePreShaderFloatDefaults(this.techniqueData, vsPreReg, vsPreReg.FloatRegisterCount, shader.CompileDirectives, out offset);

                if (initArray != null)
                {
                    string name = "vpreg_def";
                    staticArrays.Add(name, initArray);

                    CodeMethodInvokeExpression setCall = new CodeMethodInvokeExpression(shader.VertexPreShaderRegistersRef, "Set",
                                                                                        new CodePrimitiveExpression(offset), new CodeFieldReferenceExpression(shader.ShaderClassEx, name)); // start from zero
                    add(shader.ETS(setCall));
                }
            }
            //pixel preshader
            if (psPreReg != null && psPreReg.FloatRegisterCount > 0)
            {
                //assign
                CodeExpression create = new CodeObjectCreateExpression(typeof(ConstantArray),
                                                                       new CodePrimitiveExpression(psPreReg.FloatRegisterCount)); //create with the number of registers
                add(new CodeAssignStatement(shader.PixelPreShaderRegistersRef, create));

                //call the set method?
                int            offset;
                CodeExpression initArray = GeneratePreShaderFloatDefaults(this.techniqueData, psPreReg, psPreReg.FloatRegisterCount, shader.CompileDirectives, out offset);

                if (initArray != null)
                {
                    string name = "ppreg_def";
                    staticArrays.Add(name, initArray);

                    CodeMethodInvokeExpression setCall = new CodeMethodInvokeExpression(shader.PixelPreShaderRegistersRef, "Set",
                                                                                        new CodePrimitiveExpression(offset), new CodeFieldReferenceExpression(shader.ShaderClassEx, name)); // start from zero
                    add(shader.ETS(setCall));
                }
            }

            //boolean registers
            if (vsReg.BooleanRegisterCount > 0)
            {
                //assign
                CodeExpression create = new CodeArrayCreateExpression(typeof(bool),
                                                                      new CodePrimitiveExpression(vsReg.BooleanRegisterCount)); //create with the number of registers

                add(new CodeAssignStatement(shader.VertexShaderBooleanRegistersRef, create));
                add(new CodeAssignStatement(shader.VertexShaderBooleanRegistersChangedRef, new CodePrimitiveExpression(true)));

                //if any are default non-zero, assign them.
                if (vsBooleanDefault != null)
                {
                    for (int i = 0; i < this.vsBooleanDefault.Length && i < vsReg.BooleanRegisterCount; i++)
                    {
                        if (this.vsBooleanDefault[i])
                        {
                            add(new CodeAssignStatement(new CodeArrayIndexerExpression(shader.VertexShaderBooleanRegistersRef, new CodePrimitiveExpression(i)), new CodePrimitiveExpression(true)));
                        }
                    }
                }
            }
            //and the PS...
            if (psReg.BooleanRegisterCount > 0)
            {
                //assign
                CodeExpression create = new CodeArrayCreateExpression(typeof(bool),
                                                                      new CodePrimitiveExpression(psReg.BooleanRegisterCount)); //create with the number of registers

                add(new CodeAssignStatement(shader.PixelShaderBooleanRegistersRef, create));
                add(new CodeAssignStatement(shader.PixelShaderBooleanRegistersChangedRef, new CodePrimitiveExpression(true)));

                //if any are default non-zero, assign them.
                if (psBooleanDefault != null)
                {
                    for (int i = 0; i < this.psBooleanDefault.Length && i < psReg.BooleanRegisterCount; i++)
                    {
                        if (this.psBooleanDefault[i])
                        {
                            add(new CodeAssignStatement(new CodeArrayIndexerExpression(shader.PixelShaderBooleanRegistersRef, new CodePrimitiveExpression(i)), new CodePrimitiveExpression(true)));
                        }
                    }
                }
            }
        }
Example #45
0
        public override void AddBind(IShaderDom shader, Action <CodeStatement, string> add)
        {
            //bind the semantics bound attributes
            foreach (SemanticMapping mapping in semanticMapping)
            {
                //eg:
                //state.SetWorldMatrix(this.vreg.Matrix4Transpose(8), ref this.v_8);

                string method    = string.Format("Set{0}{1}", mapping.Type.Mapping, mapping.Type.Type.Name);
                bool   transpose = mapping.Type.Transpose ^ (mapping.Type.Type == typeof(Matrix));

                string registerTypeName = mapping.Type.Type.Name;
                if (mapping.Type.Type == typeof(Matrix))
                {
                    registerTypeName += (int)mapping.Register.Rank;
                }
                if (transpose)
                {
                    registerTypeName += "Transpose";
                }

                //for each register set, see if it uses this mapping

                int changeRefIndex = 0;
                foreach (KeyValuePair <AsmListing, CodeExpression> listing in listingRegisters)
                {
                    Register       sreg;
                    RegisterSet    registers    = listing.Key.RegisterSet;
                    CodeExpression registersRef = listing.Value;

                    if (registers.TryGetRegister(mapping.Register.Name, out sreg))
                    {
                        //it does.. so the constants need setting..
                        //state.SetWorldMatrix(this.vreg.Matrix4Transpose(8), ref this.v_8);

                        CodeExpression changeRef = new CodeDirectionExpression(FieldDirection.Ref, mapping.ChangeRefs[changeRefIndex]);

                        CodeExpression getRegister =                            //this.vreg.Matrix4Transpose(8)
                                                     new CodeMethodInvokeExpression(registersRef, registerTypeName, new CodePrimitiveExpression(sreg.Index));

                        //invoke
                        CodeExpression invokeSet =
                            new CodeMethodInvokeExpression(shader.ShaderSystemRef, method, getRegister, changeRef);

                        add(shader.ETS(invokeSet), changeRefIndex != 0 ? null : string.Format("Set the value for attribute '{0}'", mapping.Register.Name));

                        changeRefIndex++;
                    }
                }
            }

            //bind the shader globals

            foreach (GlobalAttribute global in globals)
            {
                string registerTypeName = global.Type.Name;
                if (global.Type == typeof(Matrix))
                {
                    registerTypeName += (int)global.Register.Rank;
                    registerTypeName += "Transpose";
                }

                int changeRefIndex = 0;
                foreach (KeyValuePair <AsmListing, CodeExpression> listing in listingRegisters)
                {
                    Register       sreg;
                    RegisterSet    registers    = listing.Key.RegisterSet;
                    CodeExpression registersRef = listing.Value;

                    if (registers.TryGetRegister(global.Register.Name, out sreg))
                    {
                        //special case the booleans, as they have different logic to set globally.
                        if (sreg.Category == RegisterCategory.Boolean)
                        {
                            if (global.Register.ArraySize != -1)
                            {
                                throw new CompileException("'GLOBAL' Boolean Arrays are not supported");
                            }

                            //this is a bit of a hack :-/
                            //need to figure out if this is a vertex or pixel boolean constant.
                            if (listing.Key == asm.VertexShader)
                            {
                                add(shader.ETS(
                                        new CodeMethodInvokeExpression(shader.ShaderSystemRef, "SetGlobal", shader.VertexShaderBooleanRegistersRef, new CodePrimitiveExpression(sreg.Index), global.GlobalIdRef, new CodeDirectionExpression(FieldDirection.Ref, shader.VertexShaderBooleanRegistersChangedRef))),
                                    string.Format("Set the value for global 'bool {0}'", global.Register.Name));
                            }
                            if (listing.Key == asm.PixelShader)
                            {
                                add(shader.ETS(
                                        new CodeMethodInvokeExpression(shader.ShaderSystemRef, "SetGlobal", shader.PixelShaderBooleanRegistersRef, new CodePrimitiveExpression(sreg.Index), global.GlobalIdRef, new CodeDirectionExpression(FieldDirection.Ref, shader.PixelShaderBooleanRegistersChangedRef))),
                                    string.Format("Set the value for global 'bool {0}'", global.Register.Name));
                            }
                        }
                        else
                        {
                            //eg:
                            //state.SetGlobal(this.vreg.Matrix4Transpose(8), ShadowShaderBlend.g_id0, ref this.g_0);

                            CodeExpression getRegister =                                //this.vreg.Matrix4Transpose(8)
                                                         new CodeMethodInvokeExpression(registersRef, registerTypeName, new CodePrimitiveExpression(sreg.Index));

                            CodeExpression changeParam = new CodeDirectionExpression(FieldDirection.Ref, global.ChangeRefs[changeRefIndex]);

                            CodeExpression invokeSet;

                            //logic changes for arrays

                            if (global.Register.ArraySize != -1)
                            {
                                invokeSet =
                                    new CodeMethodInvokeExpression(shader.ShaderSystemRef, "SetGlobal", global.ArrayRefs[changeRefIndex], global.GlobalIdRef, changeParam);
                                //state.SetGlobal(this.ga0, ShadowShaderBlend.g_id0, ref this.g_0);
                            }
                            else
                            {
                                //state.SetGlobal(this.vreg.Matrix4Transpose(8), ShadowShaderBlend.g_id0, ref this.g_0);
                                invokeSet =
                                    new CodeMethodInvokeExpression(shader.ShaderSystemRef, "SetGlobal", getRegister, global.GlobalIdRef, changeParam);
                            }

                            add(shader.ETS(invokeSet), changeRefIndex != 0 ? null : string.Format("Set the value for global '{0}'", global.Register.Name));

                            changeRefIndex++;
                        }
                    }
                }
            }
        }
Example #46
0
        public override void AddReadonlyMembers(IShaderDom shader, Action <CodeTypeMember, string> add, Platform platform)
        {
            if (platform != Platform.Both)
            {
                return;
            }

            if (vsReg.FloatRegisterCount > 0)
            {
                //create the vertex registers
                CodeMemberField field = new CodeMemberField(typeof(ConstantArray), shader.VertexShaderRegistersRef.FieldName);
                field.Attributes = MemberAttributes.Private | MemberAttributes.Final;

                add(field, "Vertex shader register storage");
            }

            //and the PS

            if (psReg.FloatRegisterCount > 0)
            {
                //create the pixel registers
                CodeMemberField field = new CodeMemberField(typeof(ConstantArray), shader.PixelShaderRegistersRef.FieldName);
                field.Attributes = MemberAttributes.Private | MemberAttributes.Final;

                add(field, "Pixel shader register storage");
            }

            //now the Preshaders
            if (vsPreReg != null && vsPreReg.FloatRegisterCount > 0)
            {
                //create the vertex preshader registers
                CodeMemberField field = new CodeMemberField(typeof(ConstantArray), shader.VertexPreShaderRegistersRef.FieldName);
                field.Attributes = MemberAttributes.Private | MemberAttributes.Final;
                add(field, "Vertex preshader register storage");
            }

            //and the PS
            if (psPreReg != null && psPreReg.FloatRegisterCount > 0)
            {
                //create the pixel preshader registers
                CodeMemberField field = new CodeMemberField(typeof(ConstantArray), shader.PixelPreShaderRegistersRef.FieldName);
                field.Attributes = MemberAttributes.Private | MemberAttributes.Final;
                add(field, "Pixel preshader register storage");
            }


            //now do the boolean registers
            if (vsReg.BooleanRegisterCount > 0)
            {
                //create the vertex boolean registers
                CodeMemberField field = new CodeMemberField(typeof(bool[]), shader.VertexShaderBooleanRegistersRef.FieldName);
                field.Attributes = MemberAttributes.Private | MemberAttributes.Final;

                add(field, "Vertex shader boolean register storage");
            }
            //now the PS
            if (psReg.BooleanRegisterCount > 0)
            {
                //create the vertex boolean registers
                CodeMemberField field = new CodeMemberField(typeof(bool[]), shader.PixelShaderBooleanRegistersRef.FieldName);
                field.Attributes = MemberAttributes.Private | MemberAttributes.Final;

                add(field, "Pixel shader boolean register storage");
            }


            //add any statics created
            foreach (KeyValuePair <string, CodeExpression> array in staticArrays)
            {
                CodeMemberField field = new CodeMemberField(typeof(float[]), array.Key);
                field.Attributes     = MemberAttributes.Private | MemberAttributes.Final | MemberAttributes.Static;
                field.InitExpression = array.Value;

                add(field, "Register default values");
            }
        }
		public virtual void SetupMembers(IShaderDom shader)
		{
		}
		public override void AddMembers(IShaderDom shader, Action<CodeTypeMember, string> add, Platform platform)
		{
			//create static ID's for the registers
			if (platform != Platform.Both)
				return;

			//static id's for named attributes
			for (int i = 0; i < attributeNames.Count; i++)
			{
				//static id of this attribute name
				CodeMemberField field = new CodeMemberField(typeof(int), attributeFields[i].FieldName);
				field.Attributes = MemberAttributes.Static | MemberAttributes.Private | MemberAttributes.Final;

				add(field, string.Format("Name ID for '{0}'", attributeNames[i]));


				CreateConstantSetters(shader, add, attributeNames[i], attributeFields[i], attributeArrayFields[i]);
			}

			//add the semantic change IDs
			foreach (SemanticMapping mapping in semanticMapping)
			{
				for (int i = 0; i < mapping.ChangeRefs.Length; i++)
				{
					CodeMemberField field = new CodeMemberField(typeof(int), mapping.ChangeRefs[i].FieldName);
					field.Attributes = MemberAttributes.Private | MemberAttributes.Final;

					add(field, i != 0 ? null : string.Format("Change ID for Semantic bound attribute '{0}'", mapping.Register.Name));
				}
			}

			//add the global refs and ids


			//add the global change IDs
			foreach (GlobalAttribute global in globals)
			{
				//global ID staics
				CodeMemberField field = new CodeMemberField(typeof(int), global.GlobalIdRef.FieldName);
				field.Attributes = MemberAttributes.Private | MemberAttributes.Final | MemberAttributes.Static;

				add(field, string.Format("TypeID for global attribute '{0} {1}'", global.Register.Type, global.Register.Name));

				for (int i = 0; i < global.ChangeRefs.Length; i++)
				{
					field = new CodeMemberField(typeof(int), global.ChangeRefs[i].FieldName);
					field.Attributes = MemberAttributes.Private | MemberAttributes.Final;

					add(field, i != 0 ? null : string.Format("Change ID for global attribute '{0} {1}'", global.Register.Type, global.Register.Name));
				}
			}
		}
		public virtual void AddChangedCondition(IShaderDom shader, Action<CodeExpression> add)
		{
		}
		public virtual void AddSetAttribute(IShaderDom shader, Action<CodeStatement> add, Type type)
		{
		}
Example #51
0
        public override void AddBindEnd(IShaderDom shader, Action <CodeStatement, string> add)
        {
            //set the constants
            //eg:

            /*
             *
             * if (((this.vreg.change == true)
             || (ic == true)))
             ||{
             ||     state.SetShaderConstants(this.vreg.array, null);
             ||     this.vreg.change = false;
             ||}
             */

            CodeExpression vreg = new CodePrimitiveExpression(null);
            CodeExpression preg = vreg;

            CodeExpression setConstantsCondition = null;

            if (vsReg.FloatRegisterCount > 0)
            {
                //local variable storing the registers
                CodeVariableDeclarationStatement vregd = new CodeVariableDeclarationStatement(typeof(Vector4[]), "vc");
                vregd.InitExpression = vreg;
                vreg = new CodeVariableReferenceExpression(vregd.Name);
                add(vregd, "Vertex shader registers");

                //assign if changed
                CodeBinaryOperatorExpression assignCondition = new CodeBinaryOperatorExpression(
                    new CodeBinaryOperatorExpression(new CodeFieldReferenceExpression(shader.VertexShaderRegistersRef, "change"), CodeBinaryOperatorType.IdentityEquality, new CodePrimitiveExpression(true)),
                    CodeBinaryOperatorType.BooleanOr,
                    new CodeBinaryOperatorExpression(shader.BindShaderInstanceChange, CodeBinaryOperatorType.IdentityEquality, new CodePrimitiveExpression(true)));

                //assign
                CodeConditionStatement assign = new CodeConditionStatement(assignCondition,
                                                                           new CodeAssignStatement(new CodeVariableReferenceExpression(vregd.Name), new CodeFieldReferenceExpression(shader.VertexShaderRegistersRef, "array")),
                                                                           new CodeAssignStatement(new CodeFieldReferenceExpression(shader.VertexShaderRegistersRef, "change"), new CodePrimitiveExpression(false)));

                add(assign, null);

                setConstantsCondition = new CodeBinaryOperatorExpression(vreg, CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(null));
            }

            //again for PS
            if (psReg.FloatRegisterCount > 0)
            {
                //local variable storing the registers
                CodeVariableDeclarationStatement pregd = new CodeVariableDeclarationStatement(typeof(Vector4[]), "pc");
                pregd.InitExpression = preg;
                preg = new CodeVariableReferenceExpression(pregd.Name);
                add(pregd, "Pixel shader registers");

                //assign if changed
                CodeBinaryOperatorExpression assignCondition = new CodeBinaryOperatorExpression(
                    new CodeBinaryOperatorExpression(new CodeFieldReferenceExpression(shader.PixelShaderRegistersRef, "change"), CodeBinaryOperatorType.IdentityEquality, new CodePrimitiveExpression(true)),
                    CodeBinaryOperatorType.BooleanOr,
                    new CodeBinaryOperatorExpression(shader.BindShaderInstanceChange, CodeBinaryOperatorType.IdentityEquality, new CodePrimitiveExpression(true)));

                //assign
                CodeConditionStatement assign = new CodeConditionStatement(assignCondition,
                                                                           new CodeAssignStatement(new CodeVariableReferenceExpression(pregd.Name), new CodeFieldReferenceExpression(shader.PixelShaderRegistersRef, "array")),
                                                                           new CodeAssignStatement(new CodeFieldReferenceExpression(shader.PixelShaderRegistersRef, "change"), new CodePrimitiveExpression(false)));

                add(assign, null);

                CodeExpression condition = new CodeBinaryOperatorExpression(preg, CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(null));
                if (setConstantsCondition != null)
                {
                    setConstantsCondition = new CodeBinaryOperatorExpression(condition, CodeBinaryOperatorType.BooleanOr, setConstantsCondition);
                }
                else
                {
                    setConstantsCondition = condition;
                }
            }

            if (setConstantsCondition != null)
            {
                //set the shaders
                CodeMethodInvokeExpression invoke = new CodeMethodInvokeExpression(shader.ShaderSystemRef, "SetShaderConstants", vreg, preg);

                //invoke if the constants are not null.

                add(new CodeConditionStatement(setConstantsCondition, shader.ETS(invoke)), null);
            }


            setConstantsCondition = null;

            //set the boolean registers
            if (vsReg.BooleanRegisterCount > 0 ||
                psReg.BooleanRegisterCount > 0)
            {
                CodeExpression vsb = new CodePrimitiveExpression(null);
                CodeExpression psb = new CodePrimitiveExpression(null);

                if (vsReg.BooleanRegisterCount > 0)
                {
                    CodeVariableDeclarationStatement vs_var = new CodeVariableDeclarationStatement(typeof(bool[]), "vcb", new CodePrimitiveExpression(null));
                    add(vs_var, null);
                    vsb = new CodeVariableReferenceExpression(vs_var.Name);
                    CodeConditionStatement changed = new CodeConditionStatement(shader.VertexShaderBooleanRegistersChangedRef,
                                                                                new CodeAssignStatement(vsb, shader.VertexShaderBooleanRegistersRef),
                                                                                new CodeAssignStatement(shader.VertexShaderBooleanRegistersChangedRef, new CodePrimitiveExpression(false)));
                    add(changed, null);
                    setConstantsCondition = new CodeBinaryOperatorExpression(vsb, CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(null));
                }
                if (psReg.BooleanRegisterCount > 0)
                {
                    CodeVariableDeclarationStatement ps_var = new CodeVariableDeclarationStatement(typeof(bool[]), "pcb", new CodePrimitiveExpression(null));
                    add(ps_var, null);
                    psb = new CodeVariableReferenceExpression(ps_var.Name);
                    CodeConditionStatement changed = new CodeConditionStatement(shader.PixelShaderBooleanRegistersChangedRef,
                                                                                new CodeAssignStatement(psb, shader.PixelShaderBooleanRegistersRef),
                                                                                new CodeAssignStatement(shader.PixelShaderBooleanRegistersChangedRef, new CodePrimitiveExpression(false)));
                    add(changed, null);

                    CodeBinaryOperatorExpression condition = new CodeBinaryOperatorExpression(psb, CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(null));
                    if (setConstantsCondition == null)
                    {
                        setConstantsCondition = condition;
                    }
                    else
                    {
                        setConstantsCondition = new CodeBinaryOperatorExpression(setConstantsCondition, CodeBinaryOperatorType.BooleanOr, condition);
                    }
                }
                //invoke the call to set the constants
                //set the shaders
                CodeMethodInvokeExpression invoke = new CodeMethodInvokeExpression(shader.ShaderSystemRef, "SetShaderBooleanConstants", vsb, psb);

                add(new CodeConditionStatement(setConstantsCondition, shader.ETS(invoke)), null);
            }
        }
		public virtual void AddBindFinal(IShaderDom shader, Action<CodeStatement, string> add)
		{
		}
		public override void AddBind(IShaderDom shader, Action<CodeStatement, string> add)
		{
			bool requiresUnused = false;

			//bind the semantics bound attributes
			foreach (SemanticMapping mapping in semanticMapping)
			{
				//eg:
				//state.SetWorldMatrix(this.vreg.Matrix4Transpose(8), ref this.v_8);

				string method = string.Format("Set{0}{1}", mapping.Type.Mapping, mapping.Type.Type.Name);

				if (mapping.Type.IsArray)
					method += "Array";

				//for each register set, see if it uses this mapping

				int changeRefIndex = 0;
				foreach (KeyValuePair<AsmListing, CodeExpression> listing in listingRegisters)
				{
					Register sreg;
					RegisterSet registers = listing.Key.RegisterSet;
					CodeExpression registersRef = listing.Value;

					if (registers.TryGetRegister(mapping.Register.Name, out sreg))
					{
						//it does.. so the constants need setting..
						//changed |= state.SetWorldMatrix(ref this.vreg[8], ref this.vreg[9], ref this.vreg[9], ref unused, ref this.v_8);

						CodeExpression changeRef = Ref(mapping.ChangeRefs[changeRefIndex]);

						CodeExpression getRegisterX =	//this.vreg[8]
							new CodeArrayIndexerExpression(registersRef, new CodePrimitiveExpression(sreg.Index));

						//invoke
						CodeExpression invokeSet = null;

						if (mapping.Type.IsArray)
						{
							invokeSet = new CodeMethodInvokeExpression(shader.ShaderSystemRef, method, registersRef, new CodePrimitiveExpression(sreg.Index), new CodePrimitiveExpression(sreg.Size), changeRef);
						}
						else
						{
							if (mapping.Type.Type == typeof(Matrix))
							{
								int rank = (int)mapping.Register.Rank;
								if (rank != 4 && requiresUnused == false) // an 'unused' variable is required
								{
									//add a temporary. A matrix being set may not use all 4 rows. Need a temp write target
									add(new CodeVariableDeclarationStatement(typeof(Vector4), "unused", new CodeObjectCreateExpression(typeof(Vector4))), null);
									requiresUnused = true;
								}

								//setter takes in X,Y,Z,W registers
								CodeExpression unused = new CodeVariableReferenceExpression("unused");
								CodeExpression Y = rank >= 2 ? new CodeArrayIndexerExpression(registersRef, new CodePrimitiveExpression(sreg.Index + 1)) : unused;
								CodeExpression Z = rank >= 3 ? new CodeArrayIndexerExpression(registersRef, new CodePrimitiveExpression(sreg.Index + 2)) : unused;
								CodeExpression W = rank >= 4 ? new CodeArrayIndexerExpression(registersRef, new CodePrimitiveExpression(sreg.Index + 3)) : unused;

								invokeSet = new CodeMethodInvokeExpression(shader.ShaderSystemRef, method, Ref(getRegisterX), Ref(Y), Ref(Z), Ref(W), changeRef);
							}
							else
								invokeSet = new CodeMethodInvokeExpression(shader.ShaderSystemRef, method, Ref(getRegisterX), changeRef);
						}

						//update the change value appropriately
						CodeExpression changeValue = new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), (registersRef as CodeFieldReferenceExpression).FieldName + "_change");

						//change |= ...;
						CodeStatement assign = new CodeAssignStatement(changeValue, 
							new CodeBinaryOperatorExpression(changeValue, CodeBinaryOperatorType.BitwiseOr,
								invokeSet));

						if (ExtractAssignmentForExtenionBlock(assign, shader, listing.Key))
							continue;

						add(assign, changeRefIndex != 0 ? null : string.Format("Set the value for attribute '{0}'", mapping.Register.Name));

						changeRefIndex++;
					}
				}
			}

			//bind the shader globals

			foreach (GlobalAttribute global in globals)
			{
				string registerTypeName = global.Type.Name;
				if (global.Type == typeof(Matrix))
				{
					registerTypeName += (int)global.Register.Rank;
				}
				
				int changeRefIndex = 0;
				foreach (KeyValuePair<AsmListing, CodeExpression> listing in listingRegisters)
				{
					Register sreg;
					RegisterSet registers = listing.Key.RegisterSet;
					CodeExpression registersRef = listing.Value;

					bool isMatrix = global.Type == typeof(Matrix);

					if (registers.TryGetRegister(global.Register.Name, out sreg))
					{
						//special case the booleans, as they have different logic to set globally.
						if (sreg.Category == RegisterCategory.Boolean)
						{
							if (global.Register.ArraySize != -1)
								throw new CompileException("'GLOBAL' Boolean Arrays are not supported");


							//this is a bit of a hack :-/
							//need to figure out if this is a vertex or pixel boolean constant.
							if (listing.Key == asm.VertexShader)
							{
								CodeExpression setValue = new CodeMethodInvokeExpression(shader.ShaderSystemRef, "SetGlobalBool", shader.VertexShaderBooleanRegistersRef, new CodePrimitiveExpression(sreg.Index), global.GlobalIdRef);

								//update the change flag
								CodeExpression invoke = new CodeBinaryOperatorExpression(
									shader.VertexShaderBooleanRegistersChangedRef, CodeBinaryOperatorType.BitwiseOr,
									setValue);

								add(shader.ETS(invoke),
									string.Format("Set the value for global 'bool {0}'", global.Register.Name));
							}
							if (listing.Key == asm.PixelShader)
							{
								CodeExpression setValue = new CodeMethodInvokeExpression(shader.ShaderSystemRef, "SetGlobalBool", shader.PixelShaderBooleanRegistersRef, new CodePrimitiveExpression(sreg.Index), global.GlobalIdRef);
								
								//update the change flag
								CodeExpression invoke = new CodeBinaryOperatorExpression(
									shader.PixelShaderBooleanRegistersChangedRef, CodeBinaryOperatorType.BitwiseOr,
									setValue);

								add(shader.ETS(invoke),
									string.Format("Set the value for global 'bool {0}'", global.Register.Name));
							}
						}
						else
						{
							//eg:
							//changed |= state.SetGlobalMatrix3(ref this.vreg[8], ref this.vreg[9], ref this.vreg[10], ShadowShaderBlend.g_id0, ref this.g_0);

							CodeExpression getRegisterX =	//this.vreg[8]
								new CodeArrayIndexerExpression(registersRef, new CodePrimitiveExpression(sreg.Index));

							string methodName = "SetGlobal" + global.Type.Name;
							int rank = (int)global.Register.Rank;

							if (isMatrix)
								methodName += rank;

							//eg, SetGlobalMatrix3

							CodeExpression changeRef = Ref(global.ChangeRefs[changeRefIndex]);
							CodeExpression invokeSet;

							//logic changes for arrays

							if (global.Register.ArraySize != -1)
							{
								//SetGlobalMatrix3 for Arrays takes in the array itself as the first arg.
								invokeSet =
									new CodeMethodInvokeExpression(shader.ShaderSystemRef, methodName, registersRef, new CodePrimitiveExpression(global.Register.Index), new CodePrimitiveExpression(global.Register.Size + global.Register.Index), global.GlobalIdRef, changeRef);
								//state.SetGlobal(this.ga0, ShadowShaderBlend.g_id0, ref this.g_0);
							}
							else
							{
								//SetGlobalMatrix3 for non-arays takes a variable number of arguements
								if (isMatrix)
								{
									List<CodeExpression> args = new List<CodeExpression>();
									//add X
									args.Add(Ref(getRegisterX));
									if (rank >= 2) args.Add(Ref(new CodeArrayIndexerExpression(registersRef, new CodePrimitiveExpression(sreg.Index + 1))));
									if (rank >= 3) args.Add(Ref(new CodeArrayIndexerExpression(registersRef, new CodePrimitiveExpression(sreg.Index + 2))));
									if (rank >= 4) args.Add(Ref(new CodeArrayIndexerExpression(registersRef, new CodePrimitiveExpression(sreg.Index + 3))));

									args.Add(global.GlobalIdRef);
									args.Add(changeRef);
									
									invokeSet =
										new CodeMethodInvokeExpression(shader.ShaderSystemRef, methodName, args.ToArray());
								}
								else
									invokeSet =
										new CodeMethodInvokeExpression(shader.ShaderSystemRef, methodName, Ref(getRegisterX), global.GlobalIdRef, changeRef);
							}

								
							//update the change value appropriately
							CodeExpression changeValue = new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), (registersRef as CodeFieldReferenceExpression).FieldName + "_change");

							//change |= ...;
							CodeStatement assign = new CodeAssignStatement(changeValue, 
								new CodeBinaryOperatorExpression(changeValue, CodeBinaryOperatorType.BitwiseOr,
									invokeSet));

							if (ExtractAssignmentForExtenionBlock(assign, shader, listing.Key))
								continue;

							add(assign, changeRefIndex != 0 ? null : string.Format("Set the value for global '{0}'", global.Register.Name));

							changeRefIndex++;
						}
					}
				}
			}
		}
		//pull a semantic bound register
		private void ExtractSemantic(IShaderDom shader, Register reg)
		{
			string semantic = reg.Semantic;

			Type dataType = null;
			switch (reg.Rank)
			{
				case RegisterRank.FloatNx1:
				{
					switch (reg.Type)
					{
						case "float":
						case "float1"://?
							dataType = typeof(Single);
							break;
						case "float2":
							dataType = typeof(Vector2);
							break;
						case "float3":
							dataType = typeof(Vector3);
							break;
						case "float4":
							dataType = typeof(Vector4);
							break;
					}
				}
				break;
				case RegisterRank.FloatNx2:
				case RegisterRank.FloatNx3:
				case RegisterRank.FloatNx4:
					dataType = typeof(Matrix);
				break;
				case RegisterRank.IntNx1:
				case RegisterRank.IntNx2:
				case RegisterRank.IntNx3:
				case RegisterRank.IntNx4:
				{
					//ints are almost always mapped to floats for semantic bound types (EG vertex count)
					//since the register category has been validated to Float4, this is the case here
					switch (reg.Type)
					{
						case "int":
						case "int1"://?
							dataType = typeof(Single);
							break;
						case "int2":
							dataType = typeof(Vector2);
							break;
						case "int3":
							dataType = typeof(Vector3);
							break;
						case "int4":
							dataType = typeof(Vector4);
							break;
					}
				}
				break;
				case RegisterRank.Bool:
				dataType = typeof(Single);
				break;
			}

			if (reg.Category == RegisterCategory.Boolean)
				dataType = typeof(bool);
			

			if (semantic.Length == 6 && semantic.Equals("global", StringComparison.InvariantCultureIgnoreCase))
			{
				//special case global value.

				if (dataType == null)
					throw new CompileException(string.Format("Error parsing semantic for '{0}'. Global values of type '{1}' are not supported.",reg.Name, reg.Type));
				
				GlobalAttribute global = new GlobalAttribute();
				global.Register = reg;
				global.Type = dataType;

				global.GlobalIdRef = new CodeFieldReferenceExpression(shader.ShaderClassEx, string.Format("gid{0}", globals.Count));

				List<CodeFieldReferenceExpression> globalRefs = new List<CodeFieldReferenceExpression>();
				List<CodeFieldReferenceExpression> arrayRefs = new List<CodeFieldReferenceExpression>();

				foreach (KeyValuePair<AsmListing, CodeExpression> listing in listingRegisters)
				{
					Register sreg;
					RegisterSet registers = listing.Key.RegisterSet;
					CodeExpression registersRef = listing.Value;

					if (registers.TryGetRegister(reg.Name, out sreg))
					{
						if (sreg.Category != RegisterCategory.Boolean)
						{
							string refId = string.Format("gc{0}", globalRefCount);
							globalRefs.Add(new CodeFieldReferenceExpression(shader.Instance, refId));
							globalRefCount++;
						}
					}
				}

				global.ChangeRefs = globalRefs.ToArray();

				globals.Add(global);
				return;
			}

			//special case
			bool isBlendMatrices = semantic.Equals("BLENDMATRICES", StringComparison.InvariantCultureIgnoreCase);

			if (reg.ArraySize != -1 && !isBlendMatrices)
			{
				//INVALID. EXTERMINATE.
				throw new CompileException(string.Format("Shader attribute '{0}' is defined as an array and has a semantic '{1}'. Semantics other than 'BLENDMATRICES' and 'GLOBAL' are invalid for Array types.", reg.Name, reg.Semantic));
			}

			bool isTranspose = semantic.Length > 9 && semantic.EndsWith("transpose", StringComparison.InvariantCultureIgnoreCase);

			if (isTranspose)
				semantic = semantic.Substring(0, semantic.Length - 9);

			SemanticType? dataSemanticType = null;

			foreach (SemanticType semanticType in semanticTypes)
			{
				if (semanticType.Type == dataType &&
					semanticType.Mapping.Equals(semantic, StringComparison.InvariantCultureIgnoreCase))
				{
					dataSemanticType = semanticType;
					break;
				}
			}

			if (dataSemanticType == null)
			{
				//INVALID. EXTERMINATE.
				throw new CompileException(string.Format("Shader attribute '{0}' has unrecognised semantic '{1}'.", reg.Name, reg.Semantic));
			}

			//create the mapping...
			SemanticMapping mapping = new SemanticMapping();
			mapping.Register = reg;
			mapping.Type = dataSemanticType.Value;

			//figure out how often this semantic is used..
			List<CodeFieldReferenceExpression> changeRefs = new List<CodeFieldReferenceExpression>();

			foreach (KeyValuePair<AsmListing, CodeExpression> listing in listingRegisters)
			{
				Register sreg;
				RegisterSet registers = listing.Key.RegisterSet;
				CodeExpression registersRef = listing.Value;

				if (registers.TryGetRegister(reg.Name, out sreg))
				{
					string changeId = string.Format("sc{0}", semanticMappingRefCount++);
					changeRefs.Add(new CodeFieldReferenceExpression(shader.Instance, changeId));
				}
			}

			mapping.ChangeRefs = changeRefs.ToArray();

			this.semanticMapping.Add(mapping);
		}
		public override void AddReadonlyMembers(IShaderDom shader, Action<CodeTypeMember, string> add, Platform platform)
		{
			if (platform == Platform.Both)
				add(vsInputField, "array storing vertex usages, and element indices");
		}
		private bool ExtractAssignmentForExtenionBlock(CodeStatement assign, IShaderDom shader, AsmListing asmListing)
		{
			//special case, blending or instancing assignments need to go in an if block.

			if (asmListing == asm.BlendingShader)
			{
				blendExtensionAssignments.Add(assign);
				return true;
			}

			if (asmListing == asm.InstancingShader)
			{
				instancingExtensionAssignments.Add(assign);
				return true;
			}

			return false;
		}
		public override void AddWarm(IShaderDom shader, Action<CodeStatement, string> add)
		{
			//return from the method if the device index hasn't changed

			CodeStatement returnCondition = 
				new CodeConditionStatement(
					new CodeBinaryOperatorExpression(GraphicsDeviceUID, CodeBinaryOperatorType.IdentityEquality, new CodePropertyReferenceExpression(ShaderSystemRef, "DeviceUniqueIndex")),
						new CodeMethodReturnStatement());

			add(returnCondition, "Shader is already warmed");

			add(validateDeviceId, "Setup the shader");
		}
		public CodeStatement GetBlendDirectAssignment(IShaderDom dom)
		{
			foreach (SemanticMapping mapping in semanticMapping)
			{
				if (mapping.Register.Name == ShaderExtensionGenerator.blendMatricesName)
				{
					//call the direct blend matrix setter
					var invokeSet = new CodeMethodInvokeExpression(dom.ShaderSystemRef, "SetBlendMatricesDirect", new CodeFieldReferenceExpression(dom.EffectRef, "vsb_c"), Ref(mapping.ChangeRefs[0]));

					//change |= ...;
					return new CodeAssignStatement(dom.BindShaderInstanceChange,
						new CodeBinaryOperatorExpression(dom.BindShaderInstanceChange, CodeBinaryOperatorType.BitwiseOr,
							invokeSet));
				}
			}
			return null;
		}
		public override void AddBindFinal(IShaderDom shader, Action<CodeStatement, string> add)
		{
			//at the end of the bind, set call SetEffect.
			CodeExpression setShaders = new CodeMethodInvokeExpression(
				ShaderSystemRef, "SetEffect", new CodeThisReferenceExpression(), new CodeDirectionExpression(FieldDirection.Ref, EffectRef), shader.ShaderExtensionMode);

			CodeExpression condition = new CodeBinaryOperatorExpression(shader.BindShaderInstanceChange, CodeBinaryOperatorType.BitwiseOr, shader.ExtensionModeChange);

			add(new CodeConditionStatement(condition, ETS(setShaders)), "Finally, bind the effect");
		}
		public override void AddStaticGraphicsInit(IShaderDom shader, Action<CodeStatement, string> add)
		{
			//initalise the static ID's

			for (int i = 0; i < attributeNames.Count; i++)
			{
				//call state.GetNameUniqueID()

				CodeExpression call = new CodeMethodInvokeExpression(
					new CodeMethodReferenceExpression(shader.ShaderSystemRef, "GetNameUniqueID"),
					new CodePrimitiveExpression(attributeNames[i]));

				CodeStatement assign = new CodeAssignStatement(attributeFields[i], call);

				add(assign, null);
			}

			//setup the TypeIDs for global attributes
			//eg:
			//ShadowShaderBlend.g_id0 = state.GetGlobalUniqueID<Microsoft.Xna.Framework.Matrix[]>("shadowMapProjection");

			foreach (GlobalAttribute global in globals)
			{
				//call state.GetGlobalUniqueID()
				Type type = global.Type;
				if (global.Register.ArraySize != -1)
					type = type.MakeArrayType();
				
				CodeExpression call = new CodeMethodInvokeExpression(
					new CodeMethodReferenceExpression(shader.ShaderSystemRef, "GetGlobalUniqueID", new CodeTypeReference(type)),
					new CodePrimitiveExpression(global.Register.Name));

				CodeStatement assign = new CodeAssignStatement(global.GlobalIdRef, call);

				add(assign, null);
			}
		}