Skip to content

Commit

Permalink
Parse command line options, fix swizzle
Browse files Browse the repository at this point in the history
  • Loading branch information
AndresTraks committed Apr 11, 2021
1 parent 004b918 commit 4066581
Show file tree
Hide file tree
Showing 11 changed files with 117 additions and 48 deletions.
38 changes: 38 additions & 0 deletions CommandLineOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using System;

namespace HlslDecompiler
{
public class CommandLineOptions
{
public string InputFilename { get; }
public bool DoAstAnalysis { get; }

public static CommandLineOptions Parse(string[] args)
{
return new CommandLineOptions(args);
}

private CommandLineOptions(string[] args)
{
foreach (string arg in args)
{
if (arg.StartsWith("--"))
{
string option = arg.Substring(2);
if (option == "ast")
{
DoAstAnalysis = true;
}
else
{
Console.WriteLine("Unknown option: --" + option);
}
}
else
{
InputFilename = arg;
}
}
}
}
}
46 changes: 23 additions & 23 deletions DirectXShaderModel/Instruction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -339,42 +339,42 @@ public byte[] GetSourceSwizzleComponents(int srcIndex)

public string GetSourceSwizzleName(int srcIndex)
{
int swizzleLength;
int destinationMask;
if (Opcode == Opcode.Dp4)
{
swizzleLength = 4;
destinationMask = 15;
}
else if (Opcode == Opcode.Dp3)
{
swizzleLength = 3;
}
else if (HasDestination)
{
swizzleLength = GetDestinationMaskLength();
destinationMask = 7;
}
else
{
swizzleLength = 4;
destinationMask = GetDestinationWriteMask();
}

string swizzleName = "";
byte[] swizzle = GetSourceSwizzleComponents(srcIndex);
for (int i = 0; i < swizzleLength; i++)

string swizzleName = "";
for (int i = 0; i < 4; i++)
{
switch (swizzle[i])
if ((destinationMask & (1 << i)) != 0)
{
case 0:
swizzleName += "x";
break;
case 1:
swizzleName += "y";
break;
case 2:
swizzleName += "z";
break;
case 3:
swizzleName += "w";
break;
switch (swizzle[i])
{
case 0:
swizzleName += "x";
break;
case 1:
swizzleName += "y";
break;
case 2:
swizzleName += "z";
break;
case 3:
swizzleName += "w";
break;
}
}
}
switch (swizzleName)
Expand Down
6 changes: 3 additions & 3 deletions DirectXShaderModel/ShaderModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,19 +62,19 @@ public IList<ConstantDeclaration> ParseConstantTable()
int numConstants = ctabReader.ReadInt32();
long constantInfoPosition = ctabReader.ReadInt32();
ShaderFlags shaderFlags = (ShaderFlags)ctabReader.ReadInt32();
Console.WriteLine("Flags = {0}", shaderFlags);
Console.WriteLine("Flags: {0}", shaderFlags);

long shaderModelPosition = ctabReader.ReadInt32();
//Console.WriteLine("ctabStart = {0}, shaderModelPosition = {1}", ctabStart, shaderModelPosition);


ctabStream.Position = creatorPosition;
string compilerInfo = ReadStringNullTerminated(ctabStream);
Console.WriteLine(compilerInfo);
Console.WriteLine("Compiler: " + compilerInfo);

ctabStream.Position = shaderModelPosition;
string shaderModel = ReadStringNullTerminated(ctabStream);
Console.WriteLine(shaderModel);
Console.WriteLine("Shader model: " + shaderModel);


for (int i = 0; i < numConstants; i++)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ ps_3_0
def c0, 1, 2, 3, 4
dcl_texcoord v0.yzw
dp2add oC0.x, v0.y, v0.z, c0.x
mov oC0.yzw, c0.xyz
mov oC0.yzw, c0.yzw
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ mad oC0, v0.xxxy, c0.xyyx, c0.yyxy
mad oC1, v0.xxxy, c0.yyxx, c0.yxyy
mad oC2, v0.x, c0.yyyx, c0.yxzy
mov oC3.xy, v0.xy
mov oC3.zw, v1.xy
mov oC3.zw, v1.zw
2 changes: 1 addition & 1 deletion HlslDecompiler.Tests/ShaderAssembly/ps_negate_absolute.asm
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ ps_3_0
def c0, 1, 0, 2, 0
dcl_texcoord v0.xz
mov oC0.x, -v0.z_abs
mad oC0.yzw, v0.xxx, c0.xxy, c0.xyx
mad oC0.yzw, v0.xxx, c0.xyy, c0.yxz
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ mad o0, c0.xyxy, v0.xxyy, r0
mul r0.xy, c1.xy, v0.xx_abs
mad o1.xy, c0.xy, v0.yy_abs, r0.xy
add r0.xy, v0.xy, v0.xy
mul r0.yz, r0.yy, c1.xx
mul r0.yz, r0.yy, c1.xy
mad o2.xy, c0.xy, r0.xx, r0.yz
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ dcl_position o0
dcl_position1 o1.xy
dcl_position2 o2.xy
mul r0, c0.xyxy, v0.xyyx
add o0.xz, r0.yy, r0.xy
add o0.xz, r0.yw, r0.xz
mul r0, c1.xyxy, v0.xyyx
add o0.yw, r0.xy, r0.xx
add o0.yw, r0.yw, r0.xz
mul r0.xy, c0.xy, v0.yx_abs
add o1.x, r0.y, r0.x
mul r0.xy, c1.xy, v0.yx_abs
Expand Down
1 change: 1 addition & 0 deletions HlslDecompiler.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="CommandLineOptions.cs" />
<Compile Include="Hlsl\Compiler\ConstantIntRegister.cs" />
<Compile Include="Hlsl\Compiler\ConstantRegister.cs" />
<Compile Include="Hlsl\HlslSimpleWriter.cs" />
Expand Down
29 changes: 13 additions & 16 deletions Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,51 +8,50 @@ class Program
{
static void Main(string[] args)
{
if (args.Length != 1)
var options = CommandLineOptions.Parse(args);
if (options.InputFilename == null)
{
Console.WriteLine("Expected input filename");
return;
}

string inputFilename = args[0];
string baseFilename = Path.GetFileNameWithoutExtension(inputFilename);

// Try to simplify HLSL expressions by doing AST analysis
bool doAstAnalysis = false;
string baseFilename = Path.GetFileNameWithoutExtension(options.InputFilename);

using (var inputStream = File.Open(inputFilename, FileMode.Open, FileAccess.Read))
using (var inputStream = File.Open(options.InputFilename, FileMode.Open, FileAccess.Read))
{
var format = FormatDetector.Detect(inputStream);
switch (format)
{
case ShaderFileFormat.ShaderModel:
ReadShaderModel(baseFilename, inputStream, doAstAnalysis);
ReadShaderModel(baseFilename, inputStream, options.DoAstAnalysis);
break;
case ShaderFileFormat.Rgxa:
ReadRgxa(baseFilename, inputStream, doAstAnalysis);
ReadRgxa(baseFilename, inputStream, options.DoAstAnalysis);
break;
case ShaderFileFormat.Unknown:
Console.WriteLine("Unknown file format!");
break;
}
}

Console.ReadKey();
Console.WriteLine("Finished.");
}

private static void ReadShaderModel(string baseFilename, FileStream inputStream, bool doAstAnalysis)
{
using (var input = new ShaderReader(inputStream, true))
{
Console.WriteLine();
Console.WriteLine("{0}", baseFilename);
ShaderModel shader = input.ReadShader();

AsmWriter writer = new AsmWriter(shader);
writer.Write($"{baseFilename}.asm");
string asmFilename = $"{baseFilename}.asm";
Console.WriteLine("Writing {0}", asmFilename);
writer.Write(asmFilename);

var hlslWriter = CreateHlslWriter(shader, doAstAnalysis);
hlslWriter.Write($"{baseFilename}.fx");
string hlslFilename = $"{baseFilename}.fx";
Console.WriteLine("Writing {0}", hlslFilename);
hlslWriter.Write(hlslFilename);
}
}

Expand Down Expand Up @@ -89,8 +88,6 @@ private static void ReadRgxa(string baseFilename, FileStream inputStream, bool d

var hlslWriter = CreateHlslWriter(shader, doAstAnalysis);
hlslWriter.Write(outFilename + ".fx");

Console.WriteLine();
}
}
}
Expand Down
33 changes: 33 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,35 @@
# HlslDecompiler
Decompiles Shader Model 3.0 shaders into HLSL code

## Usage
`HlslDecompiler [--ast] shader.fxc`

The program will output the assembly listing in shader.asm, e.g.
```
ps_3_0
def c0, 1, 0, 2, 0
dcl_texcoord v0.xz
mov oC0.x, -v0.z_abs
mad oC0.yzw, v0.xxx, c0.xyy, c0.yxz
```
and the decompiled HLSL code in shader.fx:
```
float4 main(float3 texcoord : TEXCOORD) : COLOR
{
float4 o;
o.x = -abs(texcoord.z);
o.yzw = texcoord.xxx * float3(1, 0, 0) + float3(0, 1, 2);
return o;
}
```

With the --ast option, the program will attempt generate more readable HLSL.
It does this by taking the shader bytecode, constructing an abstract syntax tree, simplyfying it and compiling to HLSL:
```
float4 main(float3 texcoord : TEXCOORD) : COLOR
{
return float4(-abs(texcoord.z), texcoord.x, 1, 2);
}
```

0 comments on commit 4066581

Please sign in to comment.