FXDIS is a simple Win32 command line tool written in C/C++ with the MIT license forked from the relatively new (and experimental) Mesa "D3D1X" module. This tool can disassemble Shader Model 4/5 binary shaders created by Microsoft's DirectX v10/11 shader compiler. The decoded shader program can be easily accessed, potentially enabling the straightforward creation of low-level automated shader translation tools (for example, from compiled shader model 4/5 programs to GLSL) and simplifying the creation of a D3D 11 to OpenGL translation layer.
The tool can be compiled with Microsoft Visual Studio 2008/2010. This tool is completely standalone, i.e. it does not depend or include any headers from the Windows or DirectX SDK, and it does not rely on the Direct3D/D3DX runtime to function.
This tool surely has bugs, but after a few fixes it appears to be working surprisingly well. A huge thanks to Luca Barbieri ([email protected]), the original author (and copyright holder) of this module. Also thanks to [email protected] for submitting his fixes (currently only checked into SVN).
Currently checked into SVN head only: More testing revealed broken dcl_indexable_temp disassembly, now fixed. Added more elaborate test.hlsl, converted tabs to spaces.
v0.90b [9/15/12] - Added missing fxdis.vcproj file to archive/SVN
v0.90 [9/15/12] - Initial release . Added MSVS project, a few MSVS compile fixes, integer constants literals should be printed correctly, and the disassembly of the various texture resource types is now properly handled. I'm continuing to test and refine this module as time permits.
Make sure the DirectX SDK's bin folder is in your PATH (run the "DirectX SDK Command Prompt" shortcut), then run test.bat. This will run FXC.EXE to compile test.hlsl, a bogus sample shader. This compiler shader's disassembly will be printed twice - the first disassembly is from FXC.EXE, and the second disassembly is created by FXDIS.EXE.
Here's an example disassembly created by FXDIS of test.hlsl (purposely compiled without optimizations in this test):
// DXBC chunk 0: RDEF offset 52 size 532
// Generated by Microsoft (R) HLSL Shader Compiler 10.1
//
//
// Buffer Definitions:
//
// cbuffer cbuf0
// {
//
// float4 cool; // Offset: 0 Size: 16
// int4 zeek; // Offset: 16 Size: 16
// int2 arr[127]; // Offset: 32 Size: 2024
//
// }
//
//
// Resource Bindings:
//
// Name Type Format Dim HLSL Bind Count Flags
// ------------------------------ ---------- ------- ----------- -------------- ------ ------
// samp0 sampler NA unknown s0 1 0
// samp1 sampler NA unknown s1 1 0
// tex0 texture float4 2d t0 1 c
// tex1 texture float4 cube t1 1 c
// tex2 texture float4 3d t2 1 c
// tex3 texture float4 2dMS2 t3 1 c
// tex4 texture float4 2d t4 2 c
// cbuf0 cbuffer NA unknown cb0 1 0
//
// DXBC chunk 1 : ISGN offset 592 size 104
//
// Input signature:
//
// Name Index Mask Register SysValue Format Used
// -------------------- ----- ------ -------- ----------- ------- ------
// TEXCOORD 0 xyzw 0 UNDEFINED float xyzw
// TEXCOORD 1 xyzw 1 UNDEFINED float x
// SV_POSITION 0 xyzw 2 POSITION float x
//
// DXBC chunk 2: OSGN offset 704 size 44
//
// Output signature:
//
// Name Index Mask Register SysValue Format Used
// -------------------- ----- ------ -------- ----------- ------- ------
// SV_TARGET 0 xyzw 0 TARGET float xyzw
//
// DXBC chunk 3: SHDR offset 756 size 5572
// DXBC chunk 4: STAT offset 6336 size 116
// Approximately 225 instruction slots used
ps_4_0
dcl_constantbuffer cb0[129].xyzw, dynamicIndexed
dcl_sampler s0, mode_default
dcl_sampler s1, mode_default
dcl_resource_texture2d t0
dcl_resource_texturecube t1
dcl_resource_texture3d t2
dcl_resource_texture2dms(2) t3
dcl_resource_texture2d t4
dcl_resource_texture2d t5
dcl_input_ps linear v0.xyzw
dcl_input_ps linear centroid v1.x
dcl_input_ps_siv linear noperspective v2.x, position
dcl_output o0.xyzw
dcl_temps 10
dcl_indexableTemp x0[8], 4
dcl_indexableTemp x1[4], 4
dcl_indexableTemp x2[4], 4
ftou r0.x, v2.x
utof r0.x, r0.x
itof r1.xyzw, l(0, 1.4013e-45, 2.8026e-45, 4.2039e-45)
dp4 r0.y, v0.xyzw, r1.xyzw
add r0.x, r0.y, r0.x
add r0.x, r0.x, v1.x
xor r0.y, cb0[1].y, l(2)
itof r0.y, r0.y
add r0.x, r0.y, r0.x
mov r0.y, l(0)
mov r0.z, r0.x
mov r0.w, r0.y
loop
ilt r1.x, r0.w, l(10)
breakc_z r1.x
itof r1.x, r0.w
itof r1.y, r0.w
add r1.y, r1.y, l(1.001)
div r1.y, l(1), r1.y
mul r1.x, r1.y, r1.x
sqrt r1.y, r0.z
add r1.x, r1.y, r1.x
add r1.x, r0.z, r1.x
itof r1.y, l(0)
lt r1.y, r1.x, r1.y
if_nz r1.y
mov r0.z, r1.x
break
endif
iadd r0.w, r0.w, l(1)
mov r0.z, r1.x
endloop
ftoi r0.x, r0.z
ilt r0.y, r0.x, l(0)
if_nz r0.y
xor r0.y, r0.x, l(50)
else
ilt r1.x, l(5), r0.x
if_nz r1.x
and r0.y, r0.x, l(2222)
else
ineg r1.x, cb0[r0.x+2].x
iadd r0.y, r0.x, r1.x
endif
endif
add r0.x, cb0[0].y, cb0[0].x
add r0.x, r0.x, cb0[0].z
add r0.x, r0.x, cb0[0].w
add r0.x, r0.x, r0.z
sample r1.xyzw, l(0.125, 5, 0, 0), t0.xyzw, s0
add r0.x, r0.x, r1.x
sample r1.xyzw, l(0.777, 1234.5, 0, 0), t0.xyzw, s1
add r0.x, r0.x, r1.x
sample r1.xyzw, l(0.125, 5, 1, 0), t1.xyzw, s0
add r0.x, r0.x, r1.x
sample r1.xyzw, l(0.125, 5, 1, 0), t2.xyzw, s0
add r0.x, r0.x, r1.z
ftoi r1.xy, l(0.125, 5, 0, 0)
mov r1.zw, l(0, 0, 0, 0)
ldms r1.xyzw, r1.xyzw, t3.xyzw, l(0)
add r1.x, r0.x, r1.x
itof r0.x, l(1.4013e-45)
div r1.y, r0.x, r1.x
itof r0.x, l(-nan)
sample_b r2.xyzw, r1.xyxx, t0.xyzw, s0, r0.x
add r0.x, r1.x, r2.y
itof r1.xy, l(0, 7.00649e-45, 0, 0)
sample r1.xyzw, r1.xyxx, t4.xyzw, s0
add r0.x, r0.x, r1.z
itof r1.xy, l(0, 7.00649e-45, 0, 0)
sample r1.xyzw, r1.xyxx, t5.xyzw, s0
add r0.x, r0.x, r1.z
itof r0.z, r0.y
mov x1[3].x, r0.z
itof r0.z, r0.y
mov x2[2].x, r0.z
mov x1[2].x, r0.x
mov x2[1].x, r0.x
and r0.y, r0.y, l(556677)
itof r0.z, r0.y
mov x0[0].x, r0.z
itof r0.z, r0.y
mov x2[0].x, r0.z
iadd r0.y, r0.y, l(42)
itof r0.z, r0.y
mov x0[1].x, r0.z
itof r0.z, r0.y
mov x2[3].x, r0.z
ishr r0.y, r0.y, l(76)
itof r0.z, r0.y
mov x1[1].x, r0.z
itof r0.z, r0.y
mov x0[2].x, r0.z
ishl r0.y, r0.y, l(22)
mov r0.y, r0.y
xor r0.z, r0.y, r0.y
utof r1.x, r0.z
mov x0[3].x, r1.x
utof r1.x, r0.z
mov x1[0].x, r1.x
mov r1.x, l(4.2039e-45)
ushr r0.z, r0.z, r1.x
utof r1.x, r0.z
mov x0[4].x, r1.x
mov r1.x, l(2.8026e-45)
ishl r0.z, r0.z, r1.x
utof r1.x, r0.z
mov x0[5].x, r1.x
mov r1.x, cb0[r0.z+2].x
xor r0.z, r0.z, r1.x
utof r1.x, r0.z
mov x0[6].x, r1.x
mov r1.x, l(1.77965e-43)
and r1.x, r0.z, r1.x
mov r1.x, cb0[r1.x+2].x
and r0.z, r0.z, r1.x
utof r1.x, r0.z
mov x0[7].x, r1.x
mov r1.x, l(9.24857e-44)
iadd r1.x, r0.z, r1.x
mov r1.y, l(1.4013e-45)
iadd r1.y, r0.z, r1.y
imul null, r1.x, cb0[r1.y+2].x, cb0[r1.x+2].y
itof r1.x, r1.x
add r1.z, r0.x, r1.x
mov r0.x, x0[7].x
add r0.x, r1.z, r0.x
mov x0[7].x, r0.x
mov r0.x, x0[0].x
itof r0.w, r0.w
add r0.x, r0.x, r0.w
ftoi r0.x, r0.x
and r0.w, r0.x, l(7)
mov r0.w, x0[r0.w].x
itof r0.y, r0.y
add r0.y, r0.w, r0.y
ftoi r0.y, r0.y
and r0.w, r0.y, l(7)
mov r0.w, x1[r0.w].x
itof r0.x, r0.x
add r0.x, r0.w, r0.x
ftoi r0.x, r0.x
and r0.w, r0.y, l(7)
mov r0.w, x2[r0.w].x
itof r0.x, r0.x
add r0.x, r0.w, r0.x
ftoi r0.x, r0.x
mul r2.z, r1.z, l(0.2)
utof r0.w, r0.z
add r2.w, r0.w, l(0.5)
itof r2.x, r0.x
itof r2.y, r0.y
utof r1.w, r0.z
itof r1.x, r0.x
itof r1.y, r0.y
mov r1.z, r1.z
mov r0.x, l(0)
mov r3.yzw, r1.yyzw
mov r3.x, r1.x
mov r0.y, r0.x
loop
ftoi r0.z, r3.x
ilt r0.z, r0.y, r0.z
breakc_z r0.z
mov r0.z, l(0)
mov r4.zw, r3.zzzw
mov r4.x, r3.x
mov r4.y, r3.y
mov r0.w, r0.z
loop
ftoi r5.x, r4.y
ilt r5.x, r0.w, r5.x
breakc_z r5.x
itof r5.x, r0.y
itof r5.y, r0.w
sample_d r5.xyzw, r5.xyxx, t0.xyzw, s0, l(1.5, 1.5, 0, 0), l(4.1, 4.1, 0, 0)
mov r4.x, r4.x
mov r4.y, r4.y
mov r4.zw, r4.zzzw
mov r6.x, l(0)
mov r7.yzw, r4.yyzw
mov r7.x, r4.x
mov r6.y, r6.x
loop
ftoi r6.z, r7.x
ilt r6.z, r6.y, r6.z
breakc_z r6.z
mov r6.z, l(0)
mov r8.zw, r7.zzzw
mov r8.x, r7.x
mov r8.y, r7.y
mov r6.w, r6.z
loop
ftoi r9.x, r8.y
ilt r9.x, r6.w, r9.x
breakc_z r9.x
itof r9.x, r6.y
itof r9.y, r6.w
sample_d r9.xyzw, r9.xyxx, t0.xyzw, s0, l(1.5, 1.5, 0, 0), l(4.1, 4.1, 0, 0)
add r8.xyzw, r9.xyzw, r8.xyzw
iadd r6.w, r6.w, l(1)
endloop
mov r7.zw, r8.zzzw
mov r7.x, r8.x
mov r7.y, r8.y
iadd r6.y, r6.y, l(1)
endloop
add r6.xyzw, r7.xyzw, l(1.1, 2.2, 3.3, 4.4)
add r6.xyzw, r6.xyzw, r7.xyzw
mul r6.xyzw, r6.xyzw, l(55566.2, 55566.2, 55566.2, 55566.2)
mov r6.xyzw, r6.xyzw
add r5.xyzw, r5.xyzw, r6.xyzw
add r4.xyzw, r5.xyzw, r4.xyzw
iadd r0.w, r0.w, l(1)
endloop
mov r3.zw, r4.zzzw
mov r3.x, r4.x
mov r3.y, r4.y
iadd r0.y, r0.y, l(1)
endloop
add r0.xyzw, r3.xyzw, l(1.1, 2.2, 3.3, 4.4)
add r0.xyzw, r0.xyzw, r3.xyzw
mov r0.xyzw, r0.xyzw
add o0.xyzw, r0.xyzw, r2.xyzw
ret