private TextureLoadOutputNode CreateTextureLoadOutputNode(InstructionToken instruction, int outputComponent) { const int TextureCoordsIndex = 1; const int SamplerIndex = 2; RegisterKey samplerRegister = instruction.GetParamRegisterKey(SamplerIndex); if (!_samplers.TryGetValue(samplerRegister, out HlslTreeNode samplerInput)) { throw new InvalidOperationException(); } var samplerRegisterInput = (RegisterInputNode)samplerInput; int numSamplerOutputComponents = samplerRegisterInput.SamplerTextureDimension; IList <HlslTreeNode> texCoords = new List <HlslTreeNode>(); for (int component = 0; component < numSamplerOutputComponents; component++) { RegisterComponentKey textureCoordsKey = GetParamRegisterComponentKey(instruction, TextureCoordsIndex, component); HlslTreeNode textureCoord = _activeOutputs[textureCoordsKey]; texCoords.Add(textureCoord); } return(new TextureLoadOutputNode(samplerRegisterInput, texCoords, outputComponent)); }
public uint GetRegisterFullLength(RegisterKey registerKey) { if (registerKey.Type == RegisterType.Const) { var constant = FindConstant(ParameterType.Float, registerKey.Number); return(constant.Columns); } RegisterDeclaration decl = _registerDeclarations[registerKey]; switch (decl.TypeName) { case "float": return(1); case "float2": return(2); case "float3": return(3); case "float4": return(4); default: throw new InvalidOperationException(); } }
public override int GetHashCode() { int hashCode = RegisterKey.GetHashCode() ^ ComponentIndex.GetHashCode(); return(hashCode); }
private static RegisterComponentKey GetParamRegisterComponentKey(InstructionToken instruction, int paramIndex, int component) { RegisterKey registerKey = instruction.GetParamRegisterKey(paramIndex); byte[] swizzle = instruction.GetSourceSwizzleComponents(paramIndex); int componentIndex = swizzle[component]; return(new RegisterComponentKey(registerKey, componentIndex)); }
private void LoadConstantOutputs(ShaderModel shader) { IList <ConstantDeclaration> constantTable = shader.ConstantTable.ConstantDeclarations; _activeOutputs = new Dictionary <RegisterComponentKey, HlslTreeNode>(); _samplers = new Dictionary <RegisterKey, HlslTreeNode>(); foreach (var constant in constantTable) { for (uint r = 0; r < constant.RegisterCount; r++) { var data = constant.GetRegisterTypeByOffset(r); int samplerTextureDimension; switch (data.Type.ParameterType) { case ParameterType.Sampler1D: samplerTextureDimension = 1; goto SamplerCommon; case ParameterType.Sampler2D: samplerTextureDimension = 2; goto SamplerCommon; case ParameterType.Sampler3D: case ParameterType.SamplerCube: samplerTextureDimension = 3; goto SamplerCommon; SamplerCommon: { var registerKey = new RegisterKey(RegisterType.Sampler, constant.RegisterIndex + r); var destinationKey = new RegisterComponentKey(registerKey, 0); var shaderInput = new RegisterInputNode(destinationKey, samplerTextureDimension); _samplers.Add(registerKey, shaderInput); } break; case ParameterType.Float: { var registerKey = new RegisterKey(RegisterType.Const, constant.RegisterIndex + r); for (int i = 0; i < 4; i++) { var destinationKey = new RegisterComponentKey(registerKey, i); var shaderInput = new RegisterInputNode(destinationKey); _activeOutputs.Add(destinationKey, shaderInput); } } break; default: throw new NotImplementedException(); } } } }
private void LoadConstantOutputs(ShaderModel shader) { IList <ConstantDeclaration> constantTable = shader.ConstantTable.ConstantDeclarations; _activeOutputs = new Dictionary <RegisterComponentKey, HlslTreeNode>(); _samplers = new Dictionary <RegisterKey, HlslTreeNode>(); foreach (var constant in constantTable) { if (constant.RegisterSet == RegisterSet.Sampler) { var registerKey = new RegisterKey(RegisterType.Sampler, constant.RegisterIndex); var destinationKey = new RegisterComponentKey(registerKey, 0); int samplerTextureDimension; switch (constant.ParameterType) { case ParameterType.Sampler1D: samplerTextureDimension = 1; break; case ParameterType.Sampler2D: samplerTextureDimension = 2; break; case ParameterType.Sampler3D: case ParameterType.SamplerCube: samplerTextureDimension = 3; break; default: throw new InvalidOperationException(); } var shaderInput = new RegisterInputNode(destinationKey, samplerTextureDimension); _samplers.Add(registerKey, shaderInput); } else { for (uint r = 0; r < constant.RegisterCount; r++) { if (constant.ParameterType != ParameterType.Float) { throw new NotImplementedException(); } var registerKey = new RegisterKey(RegisterType.Const, constant.RegisterIndex + r); for (int i = 0; i < 4; i++) { var destinationKey = new RegisterComponentKey(registerKey, i); var shaderInput = new RegisterInputNode(destinationKey); _activeOutputs.Add(destinationKey, shaderInput); } } } } }
public RegisterDeclaration(RegisterKey registerKey) { RegisterType type = registerKey.Type; _semantic = GuessSemanticByRegisterType(type); RegisterKey = registerKey; if (_semantic != null && RegisterKey.Number != 0) { _semantic += registerKey.Number; } _maskedLength = 4; }
public string GetDestinationName(InstructionToken instruction) { int destIndex = instruction.GetDestinationParamIndex(); RegisterKey registerKey = instruction.GetParamRegisterKey(destIndex); string registerName = GetRegisterName(registerKey); registerName = registerName ?? instruction.GetParamRegisterName(destIndex); var registerLength = GetRegisterFullLength(registerKey); string writeMaskName = instruction.GetDestinationWriteMaskName(registerLength, true); return(string.Format("{0}{1}", registerName, writeMaskName)); }
private static IEnumerable <RegisterComponentKey> GetDestinationKeys(InstructionToken instruction) { int index = instruction.GetDestinationParamIndex(); RegisterKey registerKey = instruction.GetParamRegisterKey(index); if (registerKey.Type == RegisterType.Sampler) { yield break; } ComponentFlags mask = instruction.GetDestinationWriteMask(); for (int component = 0; component < 4; component++) { if ((mask & (ComponentFlags)(1 << component)) == 0) { continue; } yield return(new RegisterComponentKey(registerKey, component)); } }
public uint GetRegisterFullLength(RegisterKey registerKey) { if (registerKey.Type == RegisterType.Const) { var constant = FindConstant(registerKey.Number); var data = constant.GetRegisterTypeByOffset(registerKey.Number - constant.RegisterIndex); if (data.Type.ParameterType != ParameterType.Float) { throw new NotImplementedException(); } if (data.Type.ParameterClass == ParameterClass.MatrixColumns) { return(data.Type.Rows); } return(data.Type.Columns); } RegisterDeclaration decl = _registerDeclarations[registerKey]; switch (decl.TypeName) { case "float": return(1); case "float2": return(2); case "float3": return(3); case "float4": return(4); default: throw new InvalidOperationException(); } }
public RegisterComponentKey(RegisterKey registerKey, int componentIndex) { RegisterKey = registerKey ?? throw new ArgumentNullException(nameof(registerKey)); ComponentIndex = componentIndex; }
public RegisterComponentKey(RegisterType registerType, uint registerNumber, int componentIndex) { RegisterKey = new RegisterKey(registerType, registerNumber); ComponentIndex = componentIndex; }
void WriteTemps() { Dictionary <RegisterKey, int> tempRegisters = new Dictionary <RegisterKey, int>(); foreach (var inst in _shader.Instructions) { foreach (var operand in inst.Operands) { if (operand is DestinationOperand dest) { if (dest.RegisterType == RegisterType.Temp) { var registerKey = new RegisterKey(dest.RegisterType, dest.RegisterNumber); if (!tempRegisters.ContainsKey(registerKey)) { var reg = new RegisterDeclaration(registerKey); _registers._registerDeclarations[registerKey] = reg; tempRegisters[registerKey] = (int)inst.GetDestinationWriteMask(); } else { tempRegisters[registerKey] |= (int)inst.GetDestinationWriteMask(); } } } } } if (tempRegisters.Count == 0) { return; } foreach (IGrouping <int, RegisterKey> group in tempRegisters.GroupBy( kv => kv.Value, kv => kv.Key)) { int writeMask = group.Key; string writeMaskName; switch (writeMask) { case 0x1: writeMaskName = "float"; break; case 0x3: writeMaskName = "float2"; break; case 0x7: writeMaskName = "float3"; break; case 0xF: writeMaskName = "float4"; break; default: // TODO writeMaskName = "float4"; break; //throw new NotImplementedException(); } WriteIndent(); WriteLine("{0} {1};", writeMaskName, string.Join(", ", group)); } }
private void Load(ShaderModel shader) { ConstantDeclarations = shader.ConstantTable.ConstantDeclarations; foreach (var constantDeclaration in ConstantDeclarations) { RegisterType registerType; switch (constantDeclaration.RegisterSet) { case RegisterSet.Bool: registerType = RegisterType.ConstBool; break; case RegisterSet.Float4: registerType = RegisterType.Const; break; case RegisterSet.Int4: registerType = RegisterType.ConstInt; break; case RegisterSet.Sampler: registerType = RegisterType.Sampler; break; default: throw new InvalidOperationException(); } if (registerType == RegisterType.Sampler) { // Use declaration from declaration instruction instead continue; } for (uint r = 0; r < constantDeclaration.RegisterCount; r++) { var registerKey = new RegisterKey(registerType, constantDeclaration.RegisterIndex + r); var registerDeclaration = new RegisterDeclaration(registerKey); _registerDeclarations.Add(registerKey, registerDeclaration); } } foreach (var instruction in shader.Tokens.OfType <InstructionToken>().Where(i => i.HasDestination)) { if (instruction.Opcode == Opcode.Dcl) { var registerDeclaration = new RegisterDeclaration(instruction); RegisterKey registerKey = registerDeclaration.RegisterKey; _registerDeclarations.Add(registerKey, registerDeclaration); switch (registerKey.Type) { case RegisterType.Input: case RegisterType.MiscType: case RegisterType.Texture when shader.Type == ShaderType.Pixel: MethodInputRegisters.Add(registerKey, registerDeclaration); break; case RegisterType.Output: case RegisterType.ColorOut: case RegisterType.AttrOut when shader.MajorVersion == 3 && shader.Type == ShaderType.Vertex: MethodOutputRegisters.Add(registerKey, registerDeclaration); break; case RegisterType.Sampler: case RegisterType.Addr: break; default: throw new Exception($"Unexpected dcl {registerKey.Type}"); } } else if (instruction.Opcode == Opcode.Def) { var constant = new Constant( instruction.GetParamRegisterNumber(0), instruction.GetParamSingle(1), instruction.GetParamSingle(2), instruction.GetParamSingle(3), instruction.GetParamSingle(4)); _constantDefinitions.Add(constant); } else if (instruction.Opcode == Opcode.DefI) { var constantInt = new ConstantInt(instruction.GetParamRegisterNumber(0), instruction.Data[1], instruction.Data[2], instruction.Data[3], instruction.Data[4]); _constantIntDefinitions.Add(constantInt); } else { // Find all assignments to color outputs, because pixel shader outputs are not declared. int destIndex = instruction.GetDestinationParamIndex(); RegisterType registerType = instruction.GetParamRegisterType(destIndex); var registerNumber = instruction.GetParamRegisterNumber(destIndex); var registerKey = new RegisterKey(registerType, registerNumber); if (_registerDeclarations.ContainsKey(registerKey) == false) { var reg = new RegisterDeclaration(registerKey); _registerDeclarations[registerKey] = reg; switch (registerType) { case RegisterType.AttrOut: case RegisterType.ColorOut: case RegisterType.DepthOut: case RegisterType.Output: case RegisterType.RastOut: MethodOutputRegisters[registerKey] = reg; break; } } } } }
public string GetRegisterName(RegisterKey registerKey) { var decl = _registerDeclarations[registerKey]; switch (registerKey.Type) { case RegisterType.Texture: case RegisterType.Input: return((MethodInputRegisters.Count == 1) ? decl.Name : ("i." + decl.Name)); case RegisterType.RastOut: case RegisterType.Output: case RegisterType.AttrOut: case RegisterType.ColorOut: return((MethodOutputRegisters.Count == 1) ? decl.Name : ("o." + decl.Name)); case RegisterType.Const: var constDecl = FindConstant(registerKey.Number); var relativeOffset = registerKey.Number - constDecl.RegisterIndex; var name = constDecl.GetMemberNameByOffset(relativeOffset); var data = constDecl.GetRegisterTypeByOffset(relativeOffset); // sanity check var registersOccupied = data.Type.ParameterClass == ParameterClass.MatrixColumns ? data.Type.Columns : data.Type.Rows; if (registersOccupied == 1 && data.RegisterIndex != registerKey.Number) { throw new InvalidOperationException(); } switch (data.Type.ParameterType) { case ParameterType.Float: if (registersOccupied == 1) { return(name); } var subElement = (registerKey.Number - data.RegisterIndex).ToString(); return(ColumnMajorOrder ? $"transpose({name})[{subElement}]" // subElement = col : $"{name}[{subElement}]"); // subElement = row; default: throw new NotImplementedException(); } case RegisterType.Sampler: ConstantDeclaration samplerDecl = FindConstant(RegisterSet.Sampler, registerKey.Number); if (samplerDecl != null) { var offset = registerKey.Number - samplerDecl.RegisterIndex; return(samplerDecl.GetMemberNameByOffset(offset)); } else { throw new NotImplementedException(); } case RegisterType.MiscType: switch (registerKey.Number) { case 0: return("vFace"); case 1: return("vPos"); default: throw new NotImplementedException(); } case RegisterType.Temp: return(registerKey.ToString()); default: throw new NotImplementedException(); } }
public string GetRegisterName(RegisterKey registerKey) { var decl = _registerDeclarations[registerKey]; switch (registerKey.Type) { case RegisterType.Texture: case RegisterType.Input: return((MethodInputRegisters.Count == 1) ? decl.Name : ("i." + decl.Name)); case RegisterType.RastOut: case RegisterType.Output: case RegisterType.AttrOut: case RegisterType.ColorOut: return((MethodOutputRegisters.Count == 1) ? decl.Name : ("o." + decl.Name)); case RegisterType.Const: var constDecl = FindConstant(ParameterType.Float, registerKey.Number); if (ColumnMajorOrder) { if (constDecl.Rows == 1) { return(constDecl.Name); } string col = (registerKey.Number - constDecl.RegisterIndex).ToString(); return($"transpose({constDecl.Name})[{col}]"); } if (constDecl.Rows == 1) { return(constDecl.Name); } string row = (registerKey.Number - constDecl.RegisterIndex).ToString(); return(constDecl.Name + $"[{row}]"); case RegisterType.Sampler: ConstantDeclaration samplerDecl = FindConstant(RegisterSet.Sampler, registerKey.Number); if (samplerDecl != null) { return(samplerDecl.Name); } else { throw new NotImplementedException(); } case RegisterType.MiscType: switch (registerKey.Number) { case 0: return("vFace"); case 1: return("vPos"); default: throw new NotImplementedException(); } case RegisterType.Temp: return(registerKey.ToString()); default: throw new NotImplementedException(); } }
public string GetSourceName(InstructionToken instruction, int srcIndex) { string sourceRegisterName; RegisterKey registerKey = instruction.GetParamRegisterKey(srcIndex); var registerType = instruction.GetParamRegisterType(srcIndex); switch (registerType) { case RegisterType.Const: case RegisterType.Const2: case RegisterType.Const3: case RegisterType.Const4: case RegisterType.ConstBool: case RegisterType.ConstInt: sourceRegisterName = GetSourceConstantName(instruction, srcIndex); if (sourceRegisterName != null) { return(sourceRegisterName); } ParameterType parameterType; switch (registerType) { case RegisterType.Const: case RegisterType.Const2: case RegisterType.Const3: case RegisterType.Const4: parameterType = ParameterType.Float; break; case RegisterType.ConstBool: parameterType = ParameterType.Bool; break; case RegisterType.ConstInt: parameterType = ParameterType.Int; break; default: throw new NotImplementedException(); } var registerNumber = instruction.GetParamRegisterNumber(srcIndex); ConstantDeclaration decl = FindConstant(registerNumber); if (decl == null) { // Constant register not found in def statements nor the constant table //TODO: return($"Error {registerType}{registerNumber}"); //throw new NotImplementedException(); } var totalOffset = registerNumber - decl.RegisterIndex; var data = decl.GetRegisterTypeByOffset(totalOffset); var offsetFromMember = registerNumber - data.RegisterIndex; sourceRegisterName = decl.GetMemberNameByOffset(totalOffset); if (data.Type.ParameterClass == ParameterClass.MatrixRows) { sourceRegisterName = string.Format("{0}[{1}]", decl.Name, offsetFromMember); } else if (data.Type.ParameterClass == ParameterClass.MatrixColumns) { sourceRegisterName = string.Format("transpose({0})[{1}]", decl.Name, offsetFromMember); } break; default: sourceRegisterName = GetRegisterName(registerKey); break; } sourceRegisterName = sourceRegisterName ?? instruction.GetParamRegisterName(srcIndex); sourceRegisterName += instruction.GetSourceSwizzleName(srcIndex, true); return(ApplyModifier(instruction.GetSourceModifier(srcIndex), sourceRegisterName)); }