如何将asm着色器编译为fxo文件?

时间:2018-04-27 09:29:26

标签: assembly directx shader direct3d hlsl

我有一个编译的fxo着色器,我正在尝试稍微编辑(只是调整一些常量)。

使用fxdis(https://code.google.com/archive/p/fxdis-d3d1x/)我可以反汇编这个着色器,这是输出:

#ifndef FOO
#define FOO

template<int T>
struct foo;

template<>
struct foo<1>
{ static int const value; };

template<>
int const foo<1>::value = 1;

#endif

我理解程序集并可以编辑它。问题是,我目前不知道如何将其编译回fxo文件。看来Windows SDK中的fxc.exe不接受asm着色器文件。或者我忽略了什么?

2 个答案:

答案 0 :(得分:5)

不支持从程序集创建着色器。 Shader Model 1.1 - 3.0的旧版DirectX SDK中有旧的DirectX装配工具VSAPSA。它们最后是在DirectX SDK(2008年11月)中发布的,远远早于end-of-life DirectX SDK (June 2010)

除了Shader Model 4.x和5.x之外,DirectX Runtime不会接受未使用正确哈希签名的着色器blob,因此着色器blob的二进制编辑将无法加载。只有官方HLSL编译器才能为DirectX 10.x或DirectX 11生成有效的着色器blob。

支持Diassembler输出,并在MSDN上记录着色器汇编语言,以便于优化HLSL着色器,调试HLSL编译器本身,以及帮助人们调试应用程序中的着色器。

  

对于DirectX 12和新的Shader Model 6.x工具,请参阅GitHub

答案 1 :(得分:2)

从程序集创建字节码不受官方支持,但有关于操作码和文件格式的资源。

这应该是一个很好的入门链接:parsing bytecode

通过更改操作数重建字节码是一项非常繁琐的任务,但在您的情况下,如果您只需要更改一些常量,则可以使用解析信息直接替换常量二进制值(在您的情况下,您不需要重建块作为替换常量不会添加/删除新指令。)

在您的场景中,您需要进入SHDR块(着色器块),首先找到包含您要修改的常量的操作数,例如:

add r2.y, -r1.y, l(1)

并将l(1)的二进制值修改为l(想要你想要)

Windows Driver Kit中有操作数的描述(文件是d3d11TokenizedProgramFormat.hpp)

您还需要修改在dxbc中生成的哈希/校验和,否则调用

device->CreateXShader 

会失败。

校验和描述为here

当然这不是正式的和支持的,所以可能有点容易出错。

正如Chuck所提到的,dx12还有一个新的基于llvm的开源编译器,它可以使这些操作更容易,但它有点超出你的范围,因为你想要修改的着色器已经是dxbc(并且似乎在那里)没有计划获得dx11 dxil支持,这很可惜)。