private void Load(ShaderModel shader) { ConstantDeclarations = shader.ParseConstantTable(); 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.Input; break; case RegisterSet.Sampler: registerType = RegisterType.Sampler; break; default: throw new InvalidOperationException(); } if (registerType == RegisterType.Sampler) { // Use declaration from declaration instruction instead continue; } for (int 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.Instructions.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: MethodInputRegisters.Add(registerKey, registerDeclaration); break; case RegisterType.Output: case RegisterType.ColorOut: MethodOutputRegisters.Add(registerKey, registerDeclaration); break; } } 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.Params[1], instruction.Params[2], instruction.Params[3], instruction.Params[4]); _constantIntDefinitions.Add(constantInt); } else if (shader.Type == ShaderType.Pixel) { // Find all assignments to color outputs, because pixel shader outputs are not declared. int destIndex = instruction.GetDestinationParamIndex(); RegisterType registerType = instruction.GetParamRegisterType(destIndex); if (registerType == RegisterType.ColorOut) { int registerNumber = instruction.GetParamRegisterNumber(destIndex); var registerKey = new RegisterKey(registerType, registerNumber); if (MethodOutputRegisters.ContainsKey(registerKey) == false) { var reg = new RegisterDeclaration(registerKey); MethodOutputRegisters[registerKey] = reg; } } } } }
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; } } } } }
private void Load(ShaderModel shader) { ConstantDeclarations = shader.ParseConstantTable(); 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.Input; break; case RegisterSet.Sampler: registerType = RegisterType.Sampler; break; default: throw new InvalidOperationException(); } if (registerType == RegisterType.Sampler) { // Use declaration from declaration instruction instead continue; } for (int r = 0; r < constantDeclaration.RegisterCount; r++) { var registerKey = new RegisterKey(registerType, constantDeclaration.RegisterIndex + r); var registerDeclaration = new RegisterDeclaration(registerKey); _registerDeclarations.Add(registerKey, registerDeclaration); } } if (shader.MajorVersion <= 3) { foreach (D3D9Instruction instruction in shader.Instructions) { if (!instruction.HasDestination) { if (instruction.Opcode == Opcode.Loop) { RegisterKey registerKey = new RegisterKey(RegisterType.Loop, 0); if (!_registerDeclarations.TryGetValue(registerKey, out _)) { var registerDeclaration = new RegisterDeclaration(registerKey); _registerDeclarations.Add(registerKey, registerDeclaration); } } continue; } 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: MethodInputRegisters.Add(registerKey, registerDeclaration); break; case RegisterType.Output: case RegisterType.ColorOut: MethodOutputRegisters.Add(registerKey, registerDeclaration); break; } switch (registerKey.OperandType) { case OperandType.Output: MethodOutputRegisters.Add(registerKey, registerDeclaration); break; } } else if (instruction.Opcode == Opcode.Def) { var constant = new ConstantRegister( 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 ConstantIntRegister(instruction.GetParamRegisterNumber(0), instruction.Params[1], instruction.Params[2], instruction.Params[3], instruction.Params[4]); _constantIntDefinitions.Add(constantInt); } else { int destIndex = instruction.GetDestinationParamIndex(); RegisterType registerType = instruction.GetParamRegisterType(destIndex); // Find assignments to color outputs, since pixel shader outputs are not pre-declared if (registerType == RegisterType.ColorOut) { if (shader.Type == ShaderType.Pixel) { int registerNumber = instruction.GetParamRegisterNumber(destIndex); var registerKey = new RegisterKey(registerType, registerNumber); if (MethodOutputRegisters.ContainsKey(registerKey) == false) { var reg = new RegisterDeclaration(registerKey); MethodOutputRegisters[registerKey] = reg; if (!_registerDeclarations.TryGetValue(registerKey, out _)) { var registerDeclaration = new RegisterDeclaration(registerKey); _registerDeclarations.Add(registerKey, registerDeclaration); } } } } // Find assignments to temporary registers, since they are not pre-declared else if (registerType == RegisterType.Temp) { int registerNumber = instruction.GetParamRegisterNumber(destIndex); RegisterKey registerKey = new RegisterKey(registerType, registerNumber); if (!_registerDeclarations.TryGetValue(registerKey, out _)) { var registerDeclaration = new RegisterDeclaration(registerKey); _registerDeclarations.Add(registerKey, registerDeclaration); } } } } } else { foreach (D3D10Instruction instruction in shader.Instructions) { if (!instruction.HasDestination) { if (instruction.Opcode == D3D10Opcode.Loop) { RegisterKey registerKey = new RegisterKey(RegisterType.Loop, 0); if (!_registerDeclarations.TryGetValue(registerKey, out _)) { var registerDeclaration = new RegisterDeclaration(registerKey); _registerDeclarations.Add(registerKey, registerDeclaration); } } continue; } if (instruction.Opcode == D3D10Opcode.DclOutput) { var registerDeclaration = new RegisterDeclaration(instruction); RegisterKey registerKey = registerDeclaration.RegisterKey; _registerDeclarations.Add(registerKey, registerDeclaration); switch (registerKey.OperandType) { case OperandType.Output: MethodOutputRegisters.Add(registerKey, registerDeclaration); break; } } else if (instruction.Opcode == D3D10Opcode.DclInputPS) { var registerDeclaration = new RegisterDeclaration(instruction); RegisterKey registerKey = registerDeclaration.RegisterKey; _registerDeclarations.Add(registerKey, registerDeclaration); switch (registerKey.OperandType) { case OperandType.Input: MethodInputRegisters.Add(registerKey, registerDeclaration); break; } } else { int destIndex = instruction.GetDestinationParamIndex(); OperandType operandType = instruction.GetOperandType(destIndex); // Find assignments to color outputs, since pixel shader outputs are not pre-declared if (operandType == OperandType.Output) { if (shader.Type == ShaderType.Pixel) { int registerNumber = instruction.GetParamRegisterNumber(destIndex); var registerKey = new RegisterKey(operandType, registerNumber); if (MethodOutputRegisters.ContainsKey(registerKey) == false) { var reg = new RegisterDeclaration(registerKey); MethodOutputRegisters[registerKey] = reg; if (!_registerDeclarations.TryGetValue(registerKey, out _)) { var registerDeclaration = new RegisterDeclaration(registerKey); _registerDeclarations.Add(registerKey, registerDeclaration); } } } } // Find assignments to temporary registers, since they are not pre-declared else if (operandType == OperandType.Temp) { int registerNumber = instruction.GetParamRegisterNumber(destIndex); RegisterKey registerKey = new RegisterKey(operandType, registerNumber); if (!_registerDeclarations.TryGetValue(registerKey, out _)) { var registerDeclaration = new RegisterDeclaration(registerKey); _registerDeclarations.Add(registerKey, registerDeclaration); } } } } } }