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