Skip to content

Commit

Permalink
Support tex2D swizzle
Browse files Browse the repository at this point in the history
  • Loading branch information
AndresTraks committed Jul 21, 2018
1 parent 04473bf commit 716d739
Show file tree
Hide file tree
Showing 25 changed files with 231 additions and 162 deletions.
99 changes: 55 additions & 44 deletions BytecodeParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,7 @@ private static Dictionary<RegisterKey, HlslTreeNode> 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);
}
}
Expand All @@ -58,47 +54,43 @@ private void ParseInstruction(Instruction instruction)
{
if (instruction.HasDestination)
{
IEnumerable<RegisterKey> 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<RegisterKey> 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)
Expand All @@ -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:
Expand All @@ -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)
Expand All @@ -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");
}
Expand All @@ -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);
Expand All @@ -175,6 +161,31 @@ private HlslTreeNode[] GetInputs(Instruction instruction, int componentIndex)
return inputs;
}

private IList<HlslTreeNode> GetTextureLoadInputs(Instruction instruction)
{
const int TextureCoordsIndex = 1;
const int SamplerIndex = 2;

var inputs = new List<HlslTreeNode>();

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)
Expand Down
1 change: 0 additions & 1 deletion Hlsl/AbsoluteOperation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
public class AbsoluteOperation : Operation
{
public AbsoluteOperation(HlslTreeNode value)
: base(OperationType.Absolute)
{
AddChild(value);
}
Expand Down
1 change: 0 additions & 1 deletion Hlsl/AddOperation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
public class AddOperation : Operation
{
public AddOperation(HlslTreeNode addend1, HlslTreeNode addend2)
: base(OperationType.Add)
{
AddChild(addend1);
AddChild(addend2);
Expand Down
File renamed without changes.
1 change: 0 additions & 1 deletion Hlsl/MoveOperation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
public class MoveOperation : Operation
{
public MoveOperation(HlslTreeNode value)
: base(OperationType.Move)
{
AddChild(value);
}
Expand Down
1 change: 0 additions & 1 deletion Hlsl/MultiplyAddOperation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
public class MultiplyAddOperation : Operation
{
public MultiplyAddOperation(HlslTreeNode factor1, HlslTreeNode factor2, HlslTreeNode addend)
: base(OperationType.MultiplyAdd)
{
AddChild(factor1);
AddChild(factor2);
Expand Down
1 change: 0 additions & 1 deletion Hlsl/MultiplyOperation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
public class MultiplyOperation : Operation
{
public MultiplyOperation(HlslTreeNode factor1, HlslTreeNode factor2)
: base(OperationType.Multiply)
{
AddChild(factor1);
AddChild(factor2);
Expand Down
1 change: 0 additions & 1 deletion Hlsl/NegateOperation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
public class NegateOperation : Operation
{
public NegateOperation(HlslTreeNode value)
: base(OperationType.Negate)
{
AddChild(value);
}
Expand Down
11 changes: 0 additions & 11 deletions Hlsl/Operation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
}
}
13 changes: 0 additions & 13 deletions Hlsl/OperationType.cs

This file was deleted.

19 changes: 19 additions & 0 deletions Hlsl/RegisterInputNode.cs
Original file line number Diff line number Diff line change
@@ -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})";
}
}
}
4 changes: 3 additions & 1 deletion Hlsl/SubtractOperation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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];
}
}
14 changes: 0 additions & 14 deletions Hlsl/TextureLoadOperation.cs

This file was deleted.

31 changes: 31 additions & 0 deletions Hlsl/TextureLoadOutputNode.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System.Collections.Generic;
using System.Linq;

namespace HlslDecompiler.Hlsl
{
public class TextureLoadOutputNode : HlslTreeNode, IHasComponentIndex
{
public TextureLoadOutputNode(IEnumerable<HlslTreeNode> inputNodes, int componentIndex)
{
foreach (HlslTreeNode inputNode in inputNodes)
{
AddChild(inputNode);
}

ComponentIndex = componentIndex;
}

public IEnumerable<HlslTreeNode> 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;
}
}
}
3 changes: 2 additions & 1 deletion HlslDecompiler.Tests/CompileShaders.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ $shaderSources = @(
"ps_multiply_subtract",
"ps_absolute_multiply",
"ps_negate_absolute",
"ps_tex2d"
"ps_tex2d",
"ps_tex2d_swizzle"
);

$fxc_paths = @(
Expand Down
Binary file not shown.
1 change: 1 addition & 0 deletions HlslDecompiler.Tests/DecompileTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public class DecompileTests
[TestCase("ps_absolute_multiply")]
[TestCase("ps_negate_absolute")]
[TestCase("ps_tex2d")]
[TestCase("ps_tex2d_swizzle")]
public void DecompileTest(string baseFilename)
{
string compiledShaderFilename = $"CompiledShaders{Path.DirectorySeparatorChar}{baseFilename}.fxc";
Expand Down
9 changes: 9 additions & 0 deletions HlslDecompiler.Tests/HlslDecompiler.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@
<None Include="CompiledShaders\ps_constant.fxc">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="CompiledShaders\ps_tex2d_swizzle.fxc">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="CompiledShaders\ps_tex2d.fxc">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
Expand Down Expand Up @@ -89,6 +92,9 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="packages.config" />
<Content Include="ShaderAssembly\ps_tex2d_swizzle.asm">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="ShaderSources\ps_negate_absolute.fx">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
Expand All @@ -98,6 +104,9 @@
<Content Include="ShaderSources\ps_tex2d.fx">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="ShaderSources\ps_tex2d_swizzle.fx">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="ShaderAssembly\ps_tex2d.asm">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
Expand Down
5 changes: 5 additions & 0 deletions HlslDecompiler.Tests/ShaderAssembly/ps_tex2d_swizzle.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
ps_3_0
dcl_texcoord v0.xy
dcl_2d s0
texld r0, v0, s0
mov oC0, r0.wzyx
6 changes: 6 additions & 0 deletions HlslDecompiler.Tests/ShaderSources/ps_tex2d_swizzle.fx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
sampler sampler0;

float4 main(float2 texcoord : TEXCOORD) : COLOR
{
return tex2D(sampler0, texcoord).wzyx;
}
Loading

0 comments on commit 716d739

Please sign in to comment.