private TextureLoadOutputNode CreateTextureLoadOutputNode(Instruction 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)); }
private void ParseInstruction(Instruction instruction) { if (instruction.HasDestination) { int destIndex = instruction.GetDestinationParamIndex(); var destRegisterType = instruction.GetParamRegisterType(destIndex); int destRegisterNumber = instruction.GetParamRegisterNumber(destIndex); int destMask = instruction.GetDestinationWriteMask(); for (int i = 0; i < 4; i++) { if ((destMask & (1 << i)) == 0) { continue; } var destinationKey = new RegisterKey() { RegisterNumber = destRegisterNumber, RegisterType = destRegisterType, ComponentIndex = i }; HlslTreeNode instructionTree = CreateInstructionTree(instruction, destinationKey); _activeOutputs.Add(destinationKey, instructionTree); } } }
private static Dictionary <RegisterKey, HlslTreeNode> GetConstantOutputs(ShaderModel shader) { var constantTable = shader.ParseConstantTable(); var constantOutputs = new Dictionary <RegisterKey, HlslTreeNode>(); foreach (var constant in constantTable) { for (int i = 0; i < 4; i++) { var destinationKey = new RegisterKey() { RegisterNumber = constant.RegisterIndex, RegisterType = RegisterType.Const, ComponentIndex = i }; var shaderInput = new HlslShaderInput() { InputDecl = destinationKey, ComponentIndex = i }; constantOutputs.Add(destinationKey, shaderInput); } } return(constantOutputs); }
public override int GetHashCode() { int hashCode = RegisterKey.GetHashCode() ^ ComponentIndex.GetHashCode(); return(hashCode); }
private static RegisterComponentKey GetParamRegisterComponentKey(Instruction 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.ParseConstantTable(); _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 (int 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); } } } } }
private static IEnumerable <RegisterComponentKey> GetDestinationKeys(Instruction instruction) { int index = instruction.GetDestinationParamIndex(); RegisterKey registerKey = instruction.GetParamRegisterKey(index); if (registerKey.Type == RegisterType.Sampler) { yield break; } int mask = instruction.GetDestinationWriteMask(); for (int component = 0; component < 4; component++) { if ((mask & (1 << component)) == 0) { continue; } yield return(new RegisterComponentKey(registerKey, component)); } }
public RegisterDeclaration(RegisterKey registerKey) { RegisterType type = registerKey.Type; if (type != RegisterType.ColorOut && type != RegisterType.Const) { throw new ArgumentException($"Register type {type} requires declaration instruction,", nameof(registerKey)); } RegisterKey = registerKey; switch (registerKey.Number) { case 0: Semantic = "COLOR"; break; default: Semantic = "COLOR" + registerKey.Number; break; } _maskedLength = 4; }
public RegisterComponentKey(RegisterType registerType, int registerNumber, int componentIndex) { RegisterKey = new RegisterKey(registerType, registerNumber); ComponentIndex = componentIndex; }
public RegisterComponentKey(RegisterKey registerKey, int componentIndex) { RegisterKey = registerKey ?? throw new ArgumentNullException(nameof(registerKey)); ComponentIndex = componentIndex; }
private HlslTreeNode CreateInstructionTree(Instruction instruction, RegisterKey destinationKey) { int componentIndex = destinationKey.ComponentIndex; switch (instruction.Opcode) { case Opcode.Dcl: { var shaderInput = new HlslShaderInput() { InputDecl = destinationKey, ComponentIndex = componentIndex }; return(shaderInput); } case Opcode.Def: { var constant = new HlslConstant(instruction.GetParamSingle(componentIndex + 1)); return(constant); } case Opcode.Abs: case Opcode.Add: case Opcode.Mad: case Opcode.Mov: case Opcode.Mul: { int numInputs; switch (instruction.Opcode) { case Opcode.Abs: case Opcode.Mov: numInputs = 1; break; case Opcode.Add: case Opcode.Mul: numInputs = 2; break; case Opcode.Mad: numInputs = 3; break; default: throw new NotImplementedException(); } var operation = new HlslOperation(instruction.Opcode); for (int j = 0; j < numInputs; j++) { var modifier = instruction.GetSourceModifier(j + 1); if (modifier != SourceModifier.None) { // TODO } var inputKey = GetParamRegisterKey(instruction, j + 1, componentIndex); var input = _activeOutputs[inputKey]; operation.AddChild(input); } return(operation); } default: throw new NotImplementedException(); } }