예제 #1
0
        //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));

                            if (reg.ArraySize != -1)
                            {
                                refId = string.Format("ga{0}", globalRefCount);
                                arrayRefs.Add(new CodeFieldReferenceExpression(shader.Instance, refId));
                            }
                            globalRefCount++;
                        }
                    }
                }

                global.ChangeRefs = globalRefs.ToArray();
                global.ArrayRefs  = arrayRefs.ToArray();

                globals.Add(global);
                return;
            }

            if (reg.ArraySize != -1)
            {
                //INVALID. EXTERMINATE.
                throw new CompileException(string.Format("Shader attribute '{0}' is defined as an array and has a semantic '{1}'. Semantics other than '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.Transpose == isTranspose &&
                    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);
        }
		//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);
		}