3

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.

Poppolopoppo
  • 103
  • 1
  • 7

1 Answers1

2

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.

mrvux
  • 8,523
  • 1
  • 27
  • 61
  • Thanks for your reply. It seems that the macro preprocessor does not allow the use of reserved characters like '()', or the definition of function-like macro :( I edited my question with a new test. – Poppolopoppo Sep 08 '14 at 18:47
  • Ok, I tried the define within hlsl code (which was working), I'll have a quick check using it in macro def later today. Another way is to use include handlers (using that technique to inject functions a lot actually), I can edit answer with an example if you want. – mrvux Sep 08 '14 at 18:56
  • Yes I would really appreciate an example, actually I am struggling to find the proper way to do that :) – Poppolopoppo Sep 08 '14 at 19:14
  • The define withing HLSL code was probably properly interpreted as a function-like macro, I guess this is why it was correctly expanded on second thought. – Poppolopoppo Sep 08 '14 at 19:21
  • Edited answer with include – mrvux Sep 09 '14 at 09:27