From 716d7394aaaddf09af772cacd363e8daa6fbcc9d Mon Sep 17 00:00:00 2001 From: AndresTraks Date: Sat, 21 Jul 2018 16:56:54 +0300 Subject: [PATCH] Support tex2D swizzle --- BytecodeParser.cs | 99 +++++++++-------- Hlsl/AbsoluteOperation.cs | 1 - Hlsl/AddOperation.cs | 1 - HlslAst.cs => Hlsl/HlslAst.cs | 0 Hlsl/MoveOperation.cs | 1 - Hlsl/MultiplyAddOperation.cs | 1 - Hlsl/MultiplyOperation.cs | 1 - Hlsl/NegateOperation.cs | 1 - Hlsl/Operation.cs | 11 -- Hlsl/OperationType.cs | 13 --- Hlsl/RegisterInputNode.cs | 19 ++++ Hlsl/SubtractOperation.cs | 4 +- Hlsl/TextureLoadOperation.cs | 14 --- Hlsl/TextureLoadOutputNode.cs | 31 ++++++ HlslDecompiler.Tests/CompileShaders.ps1 | 3 +- .../CompiledShaders/ps_tex2d_swizzle.fxc | Bin 0 -> 192 bytes HlslDecompiler.Tests/DecompileTests.cs | 1 + .../HlslDecompiler.Tests.csproj | 9 ++ .../ShaderAssembly/ps_tex2d_swizzle.asm | 5 + .../ShaderSources/ps_tex2d_swizzle.fx | 6 + HlslDecompiler.csproj | 7 +- HlslTreeNode.cs | 15 +-- HlslWriter.cs | 104 ++++++++++-------- IHasComponentIndex.cs | 7 ++ RegisterKey.cs | 39 +++++-- 25 files changed, 231 insertions(+), 162 deletions(-) rename HlslAst.cs => Hlsl/HlslAst.cs (100%) delete mode 100644 Hlsl/OperationType.cs create mode 100644 Hlsl/RegisterInputNode.cs delete mode 100644 Hlsl/TextureLoadOperation.cs create mode 100644 Hlsl/TextureLoadOutputNode.cs create mode 100644 HlslDecompiler.Tests/CompiledShaders/ps_tex2d_swizzle.fxc create mode 100644 HlslDecompiler.Tests/ShaderAssembly/ps_tex2d_swizzle.asm create mode 100644 HlslDecompiler.Tests/ShaderSources/ps_tex2d_swizzle.fx create mode 100644 IHasComponentIndex.cs diff --git a/BytecodeParser.cs b/BytecodeParser.cs index 418bfb4..bab76be 100644 --- a/BytecodeParser.cs +++ b/BytecodeParser.cs @@ -42,11 +42,7 @@ private static Dictionary GetConstantOutputs(ShaderMo RegisterType = RegisterType.Const, ComponentIndex = i }; - var shaderInput = new HlslShaderInput() - { - InputDecl = destinationKey, - ComponentIndex = i - }; + var shaderInput = new RegisterInputNode(destinationKey, i); constantOutputs.Add(destinationKey, shaderInput); } } @@ -58,47 +54,43 @@ private void ParseInstruction(Instruction instruction) { if (instruction.HasDestination) { - IEnumerable destinationKeys = GetDestinationKeys(instruction); - - if (instruction.Opcode == Opcode.Tex) - { - var node1 = new HlslConstant(0); - var node2 = new HlslConstant(1); - var textureLoad = new TextureLoadOperation(node1, node2); - foreach (RegisterKey destinationKey in destinationKeys) - { - _activeOutputs[destinationKey] = textureLoad; - } - } - else + foreach (RegisterKey destinationKey in GetDestinationKeys(instruction)) { - foreach (RegisterKey destinationKey in destinationKeys) - { - HlslTreeNode instructionTree = CreateInstructionTree(instruction, destinationKey); - _activeOutputs[destinationKey] = instructionTree; - } + HlslTreeNode instructionTree = CreateInstructionTree(instruction, destinationKey); + _activeOutputs[destinationKey] = instructionTree; } } } private IEnumerable GetDestinationKeys(Instruction instruction) { - int destIndex = instruction.GetDestinationParamIndex(); - var destRegisterType = instruction.GetParamRegisterType(destIndex); - int destRegisterNumber = instruction.GetParamRegisterNumber(destIndex); - int destMask = instruction.GetDestinationWriteMask(); + int index = instruction.GetDestinationParamIndex(); + RegisterType registerType = instruction.GetParamRegisterType(index); + int registerNumber = instruction.GetParamRegisterNumber(index); - for (int i = 0; i < 4; i++) + if (registerType == RegisterType.Sampler) { - if ((destMask & (1 << i)) == 0) continue; - yield return new RegisterKey() { - RegisterNumber = destRegisterNumber, - RegisterType = destRegisterType, - ComponentIndex = i + RegisterNumber = registerNumber, + RegisterType = RegisterType.Sampler }; } + else + { + int mask = instruction.GetDestinationWriteMask(); + for (int component = 0; component < 4; component++) + { + if ((mask & (1 << component)) == 0) continue; + + yield return new RegisterKey() + { + RegisterNumber = registerNumber, + RegisterType = registerType, + ComponentIndex = component + }; + } + } } private HlslTreeNode CreateInstructionTree(Instruction instruction, RegisterKey destinationKey) @@ -109,11 +101,7 @@ private HlslTreeNode CreateInstructionTree(Instruction instruction, RegisterKey { case Opcode.Dcl: { - var shaderInput = new HlslShaderInput() - { - InputDecl = destinationKey, - ComponentIndex = componentIndex - }; + var shaderInput = new RegisterInputNode(destinationKey, componentIndex); return shaderInput; } case Opcode.Def: @@ -126,7 +114,6 @@ private HlslTreeNode CreateInstructionTree(Instruction instruction, RegisterKey case Opcode.Mad: case Opcode.Mov: case Opcode.Mul: - case Opcode.Tex: { HlslTreeNode[] inputs = GetInputs(instruction, componentIndex); switch (instruction.Opcode) @@ -141,12 +128,12 @@ private HlslTreeNode CreateInstructionTree(Instruction instruction, RegisterKey return new MultiplyOperation(inputs[0], inputs[1]); case Opcode.Mad: return new MultiplyAddOperation(inputs[0], inputs[1], inputs[2]); - case Opcode.Tex: - return new TextureLoadOperation(inputs[0], inputs[1]); default: throw new NotImplementedException(); } } + case Opcode.Tex: + return new TextureLoadOutputNode(GetTextureLoadInputs(instruction), componentIndex); default: throw new NotImplementedException($"{instruction.Opcode} not implemented"); } @@ -159,9 +146,8 @@ private HlslTreeNode[] GetInputs(Instruction instruction, int componentIndex) for (int i = 0; i < numInputs; i++) { int inputParameterIndex = i + 1; - var inputKey = GetParamRegisterKey(instruction, inputParameterIndex, componentIndex); - HlslTreeNode input; - if (_activeOutputs.TryGetValue(inputKey, out input)) + RegisterKey inputKey = GetParamRegisterKey(instruction, inputParameterIndex, componentIndex); + if (_activeOutputs.TryGetValue(inputKey, out HlslTreeNode input)) { var modifier = instruction.GetSourceModifier(inputParameterIndex); input = ApplyModifier(input, modifier); @@ -175,6 +161,31 @@ private HlslTreeNode[] GetInputs(Instruction instruction, int componentIndex) return inputs; } + private IList GetTextureLoadInputs(Instruction instruction) + { + const int TextureCoordsIndex = 1; + const int SamplerIndex = 2; + + var inputs = new List(); + + for (int component = 0; component < 4; component++) + { + RegisterKey textureCoordsKey = GetParamRegisterKey(instruction, TextureCoordsIndex, component); + if (_activeOutputs.TryGetValue(textureCoordsKey, out HlslTreeNode textureCoord)) + { + inputs.Add(textureCoord); + } + } + + RegisterKey samplerKey = GetParamRegisterKey(instruction, SamplerIndex, 0); + if (_activeOutputs.TryGetValue(samplerKey, out HlslTreeNode input)) + { + inputs.Add(input); + } + + return inputs; + } + private static HlslTreeNode ApplyModifier(HlslTreeNode input, SourceModifier modifier) { switch (modifier) diff --git a/Hlsl/AbsoluteOperation.cs b/Hlsl/AbsoluteOperation.cs index cf90577..99907a1 100644 --- a/Hlsl/AbsoluteOperation.cs +++ b/Hlsl/AbsoluteOperation.cs @@ -3,7 +3,6 @@ public class AbsoluteOperation : Operation { public AbsoluteOperation(HlslTreeNode value) - : base(OperationType.Absolute) { AddChild(value); } diff --git a/Hlsl/AddOperation.cs b/Hlsl/AddOperation.cs index 6659e58..81c4acc 100644 --- a/Hlsl/AddOperation.cs +++ b/Hlsl/AddOperation.cs @@ -3,7 +3,6 @@ public class AddOperation : Operation { public AddOperation(HlslTreeNode addend1, HlslTreeNode addend2) - : base(OperationType.Add) { AddChild(addend1); AddChild(addend2); diff --git a/HlslAst.cs b/Hlsl/HlslAst.cs similarity index 100% rename from HlslAst.cs rename to Hlsl/HlslAst.cs diff --git a/Hlsl/MoveOperation.cs b/Hlsl/MoveOperation.cs index fa37458..a85de46 100644 --- a/Hlsl/MoveOperation.cs +++ b/Hlsl/MoveOperation.cs @@ -3,7 +3,6 @@ public class MoveOperation : Operation { public MoveOperation(HlslTreeNode value) - : base(OperationType.Move) { AddChild(value); } diff --git a/Hlsl/MultiplyAddOperation.cs b/Hlsl/MultiplyAddOperation.cs index a980662..1c70723 100644 --- a/Hlsl/MultiplyAddOperation.cs +++ b/Hlsl/MultiplyAddOperation.cs @@ -3,7 +3,6 @@ public class MultiplyAddOperation : Operation { public MultiplyAddOperation(HlslTreeNode factor1, HlslTreeNode factor2, HlslTreeNode addend) - : base(OperationType.MultiplyAdd) { AddChild(factor1); AddChild(factor2); diff --git a/Hlsl/MultiplyOperation.cs b/Hlsl/MultiplyOperation.cs index 9cb6bf3..1bf9ec6 100644 --- a/Hlsl/MultiplyOperation.cs +++ b/Hlsl/MultiplyOperation.cs @@ -3,7 +3,6 @@ public class MultiplyOperation : Operation { public MultiplyOperation(HlslTreeNode factor1, HlslTreeNode factor2) - : base(OperationType.Multiply) { AddChild(factor1); AddChild(factor2); diff --git a/Hlsl/NegateOperation.cs b/Hlsl/NegateOperation.cs index 3606f58..6373be9 100644 --- a/Hlsl/NegateOperation.cs +++ b/Hlsl/NegateOperation.cs @@ -3,7 +3,6 @@ public class NegateOperation : Operation { public NegateOperation(HlslTreeNode value) - : base(OperationType.Negate) { AddChild(value); } diff --git a/Hlsl/Operation.cs b/Hlsl/Operation.cs index a3fb1d4..4e05bfe 100644 --- a/Hlsl/Operation.cs +++ b/Hlsl/Operation.cs @@ -2,16 +2,5 @@ { public class Operation : HlslTreeNode { - public OperationType Type { get; } - - public Operation(OperationType type) - { - Type = type; - } - - public override string ToString() - { - return Type.ToString(); - } } } diff --git a/Hlsl/OperationType.cs b/Hlsl/OperationType.cs deleted file mode 100644 index 37180d2..0000000 --- a/Hlsl/OperationType.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace HlslDecompiler.Hlsl -{ - public enum OperationType - { - Add, - Multiply, - MultiplyAdd, - Subtract, - Absolute, - Move, - Negate - } -} diff --git a/Hlsl/RegisterInputNode.cs b/Hlsl/RegisterInputNode.cs new file mode 100644 index 0000000..de17aa5 --- /dev/null +++ b/Hlsl/RegisterInputNode.cs @@ -0,0 +1,19 @@ +namespace HlslDecompiler.Hlsl +{ + public class RegisterInputNode : HlslTreeNode, IHasComponentIndex + { + public RegisterInputNode(RegisterKey inputDecl, int componentIndex) + { + InputDecl = inputDecl; + ComponentIndex = componentIndex; + } + + public RegisterKey InputDecl { get; } + public int ComponentIndex { get; } + + public override string ToString() + { + return $"{InputDecl} ({ComponentIndex})"; + } + } +} diff --git a/Hlsl/SubtractOperation.cs b/Hlsl/SubtractOperation.cs index e1ffca6..8074ab5 100644 --- a/Hlsl/SubtractOperation.cs +++ b/Hlsl/SubtractOperation.cs @@ -3,10 +3,12 @@ public class SubtractOperation : Operation { public SubtractOperation(HlslTreeNode minuend, HlslConstant subtrahend) - : base(OperationType.Subtract) { AddChild(minuend); AddChild(subtrahend); } + + public HlslTreeNode Minuend => Children[0]; + public HlslTreeNode Subtrahend => Children[1]; } } diff --git a/Hlsl/TextureLoadOperation.cs b/Hlsl/TextureLoadOperation.cs deleted file mode 100644 index 5fd0934..0000000 --- a/Hlsl/TextureLoadOperation.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace HlslDecompiler.Hlsl -{ - public class TextureLoadOperation : HlslTreeNode - { - public TextureLoadOperation(HlslTreeNode textureCoordinates, HlslTreeNode sampler) - { - AddChild(textureCoordinates); - AddChild(sampler); - } - - public HlslTreeNode TextureCoordinates => Children[0]; - public HlslTreeNode Sampler => Children[1]; - } -} diff --git a/Hlsl/TextureLoadOutputNode.cs b/Hlsl/TextureLoadOutputNode.cs new file mode 100644 index 0000000..352e7b9 --- /dev/null +++ b/Hlsl/TextureLoadOutputNode.cs @@ -0,0 +1,31 @@ +using System.Collections.Generic; +using System.Linq; + +namespace HlslDecompiler.Hlsl +{ + public class TextureLoadOutputNode : HlslTreeNode, IHasComponentIndex + { + public TextureLoadOutputNode(IEnumerable inputNodes, int componentIndex) + { + foreach (HlslTreeNode inputNode in inputNodes) + { + AddChild(inputNode); + } + + ComponentIndex = componentIndex; + } + + public IEnumerable TextureCoordinateInputs => Children.Where(c => !IsSamplerInput(c)); + public RegisterInputNode SamplerInput => (RegisterInputNode)Children.Single(IsSamplerInput); + public int ComponentIndex { get; } + + private static bool IsSamplerInput(HlslTreeNode node) + { + if (node is RegisterInputNode registerInput) + { + return registerInput.InputDecl.RegisterType == RegisterType.Sampler; + } + return false; + } + } +} diff --git a/HlslDecompiler.Tests/CompileShaders.ps1 b/HlslDecompiler.Tests/CompileShaders.ps1 index 5b3bd23..c4f21c9 100644 --- a/HlslDecompiler.Tests/CompileShaders.ps1 +++ b/HlslDecompiler.Tests/CompileShaders.ps1 @@ -8,7 +8,8 @@ $shaderSources = @( "ps_multiply_subtract", "ps_absolute_multiply", "ps_negate_absolute", - "ps_tex2d" + "ps_tex2d", + "ps_tex2d_swizzle" ); $fxc_paths = @( diff --git a/HlslDecompiler.Tests/CompiledShaders/ps_tex2d_swizzle.fxc b/HlslDecompiler.Tests/CompiledShaders/ps_tex2d_swizzle.fxc new file mode 100644 index 0000000000000000000000000000000000000000..0a1e09569bc19d9394403b339708b2aec9675de5 GIT binary patch literal 192 zcmZQz{{R2qe+35T5Jx8&1_p*;AZ7rHF#;(Np8?450a6A)%nac&*Z^q|C{D~R$Vn|S zU|79+H46g|P$>vPKtXZ5al8S8Z)S2)esO+UiGoIurh PreserveNewest + + PreserveNewest + PreserveNewest @@ -89,6 +92,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest @@ -98,6 +104,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest diff --git a/HlslDecompiler.Tests/ShaderAssembly/ps_tex2d_swizzle.asm b/HlslDecompiler.Tests/ShaderAssembly/ps_tex2d_swizzle.asm new file mode 100644 index 0000000..888870c --- /dev/null +++ b/HlslDecompiler.Tests/ShaderAssembly/ps_tex2d_swizzle.asm @@ -0,0 +1,5 @@ +ps_3_0 +dcl_texcoord v0.xy +dcl_2d s0 +texld r0, v0, s0 +mov oC0, r0.wzyx diff --git a/HlslDecompiler.Tests/ShaderSources/ps_tex2d_swizzle.fx b/HlslDecompiler.Tests/ShaderSources/ps_tex2d_swizzle.fx new file mode 100644 index 0000000..dd9b1ed --- /dev/null +++ b/HlslDecompiler.Tests/ShaderSources/ps_tex2d_swizzle.fx @@ -0,0 +1,6 @@ +sampler sampler0; + +float4 main(float2 texcoord : TEXCOORD) : COLOR +{ + return tex2D(sampler0, texcoord).wzyx; +} diff --git a/HlslDecompiler.csproj b/HlslDecompiler.csproj index 4aa04f6..a1f2bea 100644 --- a/HlslDecompiler.csproj +++ b/HlslDecompiler.csproj @@ -49,19 +49,20 @@ - + + - + - + diff --git a/HlslTreeNode.cs b/HlslTreeNode.cs index 5d77112..547352d 100644 --- a/HlslTreeNode.cs +++ b/HlslTreeNode.cs @@ -63,8 +63,8 @@ public override int GetHashCode() } public static bool operator ==(HlslConstant x, HlslConstant y) { - if (ReferenceEquals(x, null)) return ReferenceEquals(y, null); - if (ReferenceEquals(y, null)) return false; + if (x is null) return y is null; + if (y is null) return false; return x.Value == y.Value; } public static bool operator !=(HlslConstant x, HlslConstant y) @@ -77,15 +77,4 @@ public override string ToString() return Value.ToString(CultureInfo.InvariantCulture); } } - - public class HlslShaderInput : HlslTreeNode - { - public RegisterKey InputDecl { get; set; } - public int ComponentIndex { get; set; } - - public override string ToString() - { - return $"{InputDecl} ({ComponentIndex})"; - } - } } diff --git a/HlslWriter.cs b/HlslWriter.cs index a6efc11..d43efab 100644 --- a/HlslWriter.cs +++ b/HlslWriter.cs @@ -862,14 +862,14 @@ string GetAstConstant(HlslTreeNode constant) } else { - var shaderInput = constant as HlslShaderInput; - var dcl = shaderInput.InputDecl; + var registerInput = constant as RegisterInputNode; + var dcl = registerInput.InputDecl; var decl = RegisterDeclarations.FirstOrDefault(x => x.RegisterType == dcl.RegisterType && x.RegisterNumber == dcl.RegisterNumber); - return decl.Name + '.' + new[] { 'x', 'y', 'z', 'w' }[shaderInput.ComponentIndex]; + return decl.Name + '.' + new[] { 'x', 'y', 'z', 'w' }[registerInput.ComponentIndex]; } } - public string GetAstSourceSwizzleName(IEnumerable inputs, int registerSize) + public string GetAstSourceSwizzleName(IEnumerable inputs, int registerSize) { string swizzleName = ""; foreach (int swizzle in inputs.Select(i => i.ComponentIndex)) @@ -882,12 +882,9 @@ public string GetAstSourceSwizzleName(IEnumerable inputs, int r return ""; } - foreach (char cc in "xyzw") + if (swizzleName.Distinct().Count() == 1) { - if (swizzleName.All(c => c == cc)) - { - return "." + cc; - } + return "." + swizzleName.First(); } return "." + swizzleName; @@ -903,41 +900,48 @@ private bool CanGroupComponents(HlslTreeNode node1, HlslTreeNode node2) return constant1.Value == constant2.Value; } */ - var input1 = node1 as HlslShaderInput; - var input2 = node2 as HlslShaderInput; - if (input1 != null && input2 != null) + if (node1 is RegisterInputNode input1 && + node2 is RegisterInputNode input2) { return input1.InputDecl.RegisterType == input2.InputDecl.RegisterType && input1.InputDecl.RegisterNumber == input2.InputDecl.RegisterNumber; } - var operation1 = node1 as Operation; - var operation2 = node2 as Operation; - if (operation1 != null && operation2 != null) + if (node1 is Operation operation1 && + node2 is Operation operation2) { - if (operation1.Type == operation2.Type) + if (operation1 is NegateOperation && + operation2 is NegateOperation) { - if (operation1.Type == OperationType.Negate) - { - return true; - } - else if (operation1.Type == OperationType.Multiply) - { - //return operation1.Children.Any(c1 => operation2.Children.Any(c2 => CanGroupComponents(c1, c2))); - return operation1.Children[1].Equals(operation2.Children[1]); - } - else if (operation1.Type == OperationType.Subtract) - { - return operation1.Children[1].Equals(operation2.Children[1]); - } + return true; + } + else if (operation1 is MultiplyOperation multiply1 && + operation2 is MultiplyOperation multiply2) + { + //return operation1.Children.Any(c1 => operation2.Children.Any(c2 => CanGroupComponents(c1, c2))); + return multiply1.Factor2.Equals(multiply2.Factor2); + } + else if (operation1 is SubtractOperation subtract1 && + operation2 is SubtractOperation subtract2) + { + return subtract1.Subtrahend.Equals(subtract2.Subtrahend); } } - var textureLoad1 = node1 as TextureLoadOperation; - var textureLoad2 = node2 as TextureLoadOperation; - if (textureLoad1 != null && textureLoad2 != null) + if (node1 is TextureLoadOutputNode textureLoad1 && + node2 is TextureLoadOutputNode textureLoad2) { - return ReferenceEquals(textureLoad1, textureLoad2); + if (textureLoad1.Children.Count == textureLoad2.Children.Count) + { + for (int i = 0; i < textureLoad1.Children.Count; i++) + { + if (textureLoad1.Children[i].Equals(textureLoad2.Children[i]) == false) + { + return false; + } + } + return true; + } } return false; @@ -989,9 +993,9 @@ void WriteAst(HlslAst ast) if (groups.Count == 1) { IList singleGroup = groups.First(); - if (singleGroup.First() is HlslShaderInput) + if (singleGroup.First() is RegisterInputNode) { - var shaderInputs = singleGroup.Cast(); + var shaderInputs = singleGroup.Cast(); var firstInput = shaderInputs.First(); string swizzle = GetAstSourceSwizzleName(shaderInputs, 4); var decl = RegisterDeclarations.FirstOrDefault(x => @@ -999,9 +1003,12 @@ void WriteAst(HlslAst ast) x.RegisterNumber == firstInput.InputDecl.RegisterNumber); WriteLine($"return {decl.Name}{swizzle};"); } - else if (singleGroup.First() is TextureLoadOperation) + else if (singleGroup.First() is TextureLoadOutputNode) { - WriteLine($"return tex2D(sampler0, texcoord);"); + var shaderInputs = singleGroup.Cast(); + var firstInput = shaderInputs.First(); + string swizzle = GetAstSourceSwizzleName(shaderInputs, 4); + WriteLine($"return tex2D(sampler0, texcoord){swizzle};"); } else { @@ -1026,10 +1033,10 @@ public string Compile(IEnumerable group) return CompileConstant(constant); } - var firstShaderInput = first as HlslShaderInput; + var firstShaderInput = first as RegisterInputNode; if (firstShaderInput != null) { - var shaderInputs = group.Cast(); + var shaderInputs = group.Cast(); var decl = RegisterDeclarations.FirstOrDefault(x => x.RegisterType == firstShaderInput.InputDecl.RegisterType && x.RegisterNumber == firstShaderInput.InputDecl.RegisterNumber); @@ -1040,26 +1047,26 @@ public string Compile(IEnumerable group) var firstOperation = first as Operation; if (firstOperation != null) { - if (firstOperation.Type == OperationType.Absolute) + if (firstOperation is AbsoluteOperation) { return string.Format("abs({0})", Compile(group.Select(g => g.Children[0]))); } - if (firstOperation.Type == OperationType.Negate) + if (firstOperation is NegateOperation) { return string.Format("-{0}", Compile(group.Select(g => g.Children[0]))); } - if (firstOperation.Type == OperationType.Subtract) + if (firstOperation is SubtractOperation) { return string.Format("{0} - {1}", Compile(group.Select(g => g.Children[0])), Compile(group.Select(g => g.Children[1]))); } - if (firstOperation.Type == OperationType.Multiply) + if (firstOperation is MultiplyOperation) { var multiplicand1 = group.Select(g => g.Children[0]); var multiplicand2 = group.Select(g => g.Children[1]); @@ -1077,17 +1084,20 @@ public string Compile(IEnumerable group) } } - var firstTextureLoadOperation = first as TextureLoadOperation; + var firstTextureLoadOperation = first as TextureLoadOutputNode; if (firstTextureLoadOperation != null) { - var textureLoadOperations = group.Cast(); - var textureCoordinates = Compile(textureLoadOperations.Select(ld => ld.TextureCoordinates)); - var samplers = Compile(textureLoadOperations.Select(ld => ld.Sampler)); + /* + var textureLoadOperations = group.Cast(); + var textureCoordinates = Compile(textureLoadOperations.Select(ld => ld.TextureCoordinateInputs)); + var samplers = Compile(textureLoadOperations.Select(ld => ld.SamplerInputs)); //var decl = RegisterDeclarations.FirstOrDefault(x => // x.RegisterType == firstTextureLoadOperation.TextureCoordinates.RegisterType && // x.RegisterNumber == firstTextureLoadOperation.InputDecl.RegisterNumber); //string swizzle = GetAstSourceSwizzleName(textureLoadOperations, GetRegisterFullLength(decl)); return $"tex2D({textureCoordinates}, {samplers})"; + */ + return "tex2D()"; } throw new NotImplementedException(); diff --git a/IHasComponentIndex.cs b/IHasComponentIndex.cs new file mode 100644 index 0000000..4e74dcc --- /dev/null +++ b/IHasComponentIndex.cs @@ -0,0 +1,7 @@ +namespace HlslDecompiler +{ + public interface IHasComponentIndex + { + int ComponentIndex { get; } + } +} diff --git a/RegisterKey.cs b/RegisterKey.cs index 786703c..57f34a0 100644 --- a/RegisterKey.cs +++ b/RegisterKey.cs @@ -1,6 +1,6 @@ namespace HlslDecompiler { - public class RegisterKey + public class RegisterKey : IHasComponentIndex { public int RegisterNumber { get; set; } public RegisterType RegisterType { get; set; } @@ -26,23 +26,44 @@ private string Component } } - public override bool Equals(object obj) + public override bool Equals(object obj) { - var other = obj as RegisterKey; - if (other == null) return false; - return other.RegisterNumber == RegisterNumber && - other.RegisterType == RegisterType && - other.ComponentIndex == ComponentIndex; + if (!(obj is RegisterKey other)) + { + return false; + } + if (other.RegisterNumber == RegisterNumber && + other.RegisterType == RegisterType) + { + if (IsSampler) + { + return true; + } + else + { + return other.ComponentIndex == ComponentIndex; + } + } + return false; } public override int GetHashCode() { - return RegisterNumber.GetHashCode() ^ RegisterType.GetHashCode() ^ ComponentIndex.GetHashCode(); + int hashCode = RegisterNumber.GetHashCode() ^ RegisterType.GetHashCode(); + if (!IsSampler) + { + hashCode ^= ComponentIndex.GetHashCode(); + } + return hashCode; } public override string ToString() { - return $"{RegisterType}{RegisterNumber}.{Component}"; + return IsSampler + ? $"{RegisterType}{RegisterNumber}" + : $"{RegisterType}{RegisterNumber}.{Component}"; } + + private bool IsSampler => RegisterType == RegisterType.Sampler; } }