Is it possible to define a function-like macro with the const D3D_SHADER_MACRO *pDefines
parameter of D3DCompile()
?
Sadly MSDN is not very specific but implies they can be defined with /D option of fxc.exe.
I tried with this :
const D3D_SHADER_MACRO dx11Defines[] = {
{"SIMPLE_MACRO", "42"},
{"FUNCTION_MACRO(x)", "DoSometing((x).somefield)"},
{nullptr, nullptr},
};
And usage in HLSL :
float test1 = SIMPLE_MACRO;
float test2 = FUNCTION_MACRO(data);
But the compilation failed :
Test.fx(XX,XX-XX): error X3004: undeclared identifier 'FUNCTION_MACRO'
Output of D3DPreprocess()
:
float test1 = 42 ;
float test2 = FUNCTION_MACRO ( data ) ;
[edit]
I tested the following command-line with the same HLSL code :
fxc dtest.fx /Ptest_p.fx /D"SIMPLE_MACRO=42" /D"FUNCTION_MACRO(data)=24"
Which output :
float test1 = 42 ;
float test2 = FUNCTION_MACRO ( data ) ;
[edit]
I finally solved the problem by using ID3DInclude interface, as suggested by @catflier. I generate function-like macro definitions in a temporary buffer when asked for a specific header filename.
I stumbled upon a nice article by Adam Sawicki, that helped me a lot.
Defines with special characters only work when they are defined within hlsl.
so : FUNCTION_MACRO(x) will not be replaced by the preprocessor.
Alternatively you can use Include handlers, so at the beginning of your file you add:
#include <myfunction.fxh>
then in the handler you inject (simple example):
#define FUNCTION_MACRO(data) sin(data)
to build a handler, you can look at this link
It's pretty simple, you implement open method, check if the include name matches yours, and inject the define from there.
On the d3dcompile method you send an instance of your include so the open method gets called.
If you want to keep it simple, you can also just add the define manually at the beginning of the code before to call compile, I just find the include way a bit more flexible in many cases.