我有一个编译的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着色器文件。或者我忽略了什么?
答案 0 :(得分:5)
不支持从程序集创建着色器。 Shader Model 1.1 - 3.0的旧版DirectX SDK中有旧的DirectX装配工具VSA
和PSA
。它们最后是在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支持,这很可惜)。