Hi,
I've a question concerning d3dcompiler, d3d10 and d3dx10 dlls in combination with the shader reflection interfaces.
It seems there are 4 different known interfaces: IID_ID3D10ShaderReflection -> d3d10.dll (D3D10ReflectShader()) IID_ID3D10ShaderReflection1 -> d3dx10_xx.dll (D3DX10ReflectShader()) IID_ID3D11ShaderReflection_42 -> d3dcompiler_(40-42).dll (D3DReflect()) IID_ID3D11ShaderReflection -> d3dcompiler_(43).dll (D3DReflect())
The IID_ID3D11ShaderReflection_42 is just a new name for a IID_ID3D11ShaderReflection interface for version 40-42. In d3dcompiler 43 the interface changed and now has a new IID.
What's the preferred way to implement the different interfaces?
1. Implement a parser which parses the shader (RDEF, STAT), and implement 4 independent interfaces (each in its own dll). Only reuse the parser. 2. Like 1, but all 4 implementations have there own parser, which leads to a lot of duplicated code. But it is the most flexible way. It could easily parse all possible shader blobs (theoretically they could differ from version to version, I have no test for that, yet). 3. Forward all interfaces to d3dcompiler_43.dll and this will contain all interfaces and the parser. This way the codebase is the smallest possible one, but it will offer all interfaces, which isn't what native does. Also all further interfaces would go to d3dcompiler_43.dll. This could get tricky.
Attached is a test program and the output. The programm is compiled with "i686-pc-mingw32-gcc -I./wine/build/include -I./wine/git/include compilertest.c".
The test for D3DReflectCode() doesn't work, so please ignore that part.
Cheers Rico
2010/10/18 Rico Schüller kgbricola@web.de:
What's the preferred way to implement the different interfaces?
- Implement a parser which parses the shader (RDEF, STAT), and implement 4
independent interfaces (each in its own dll). Only reuse the parser. 2. Like 1, but all 4 implementations have there own parser, which leads to a lot of duplicated code. But it is the most flexible way. It could easily parse all possible shader blobs (theoretically they could differ from version to version, I have no test for that, yet). 3. Forward all interfaces to d3dcompiler_43.dll and this will contain all interfaces and the parser. This way the codebase is the smallest possible one, but it will offer all interfaces, which isn't what native does. Also all further interfaces would go to d3dcompiler_43.dll. This could get tricky.
I'm not sure. The problem with 3 is that it will prevent using the native d3dcompiler to work around e.g. the missing HLSL compiler because it doesn't implement ID3D10ShaderReflection etc. Perhaps we don't care in the long term, but at least in the short term that would be a problem. Option 1 would require d3dcompiler to have some private interface or entry point, and you'd still have the same problem as with option 3. Option 2 leads to duplicated code.
There may be an option 4 though, which would be to implement the older interfaces on top of ID3D11ShaderReflection. I.e., you'd use the information you get from the ID3D11ShaderReflection interface to construct constant buffers and variables for the other interfaces, instead of parsing the shader bytecode yourself. It would need some investigation to determine how feasible this option is.
Am 19.10.2010 12:25, schrieb Henri Verbeet:
2010/10/18 Rico Schüllerkgbricola@web.de:
What's the preferred way to implement the different interfaces?
- Implement a parser which parses the shader (RDEF, STAT), and implement 4
independent interfaces (each in its own dll). Only reuse the parser. 2. Like 1, but all 4 implementations have there own parser, which leads to a lot of duplicated code. But it is the most flexible way. It could easily parse all possible shader blobs (theoretically they could differ from version to version, I have no test for that, yet). 3. Forward all interfaces to d3dcompiler_43.dll and this will contain all interfaces and the parser. This way the codebase is the smallest possible one, but it will offer all interfaces, which isn't what native does. Also all further interfaces would go to d3dcompiler_43.dll. This could get tricky.
I'm not sure. The problem with 3 is that it will prevent using the native d3dcompiler to work around e.g. the missing HLSL compiler because it doesn't implement ID3D10ShaderReflection etc. Perhaps we don't care in the long term, but at least in the short term that would be a problem. Option 1 would require d3dcompiler to have some private interface or entry point, and you'd still have the same problem as with option 3. Option 2 leads to duplicated code.
There may be an option 4 though, which would be to implement the older interfaces on top of ID3D11ShaderReflection. I.e., you'd use the information you get from the ID3D11ShaderReflection interface to construct constant buffers and variables for the other interfaces, instead of parsing the shader bytecode yourself. It would need some investigation to determine how feasible this option is.
Yeah option 4 sounds very well. The problem I see with that is if there is a newer interface that adds a new interface function where the values couldn't be quarried by an older one. (I'm not sure if this would happen.) Then we would have to move the code to the newest function.
I guess that older functions/variable will be always there in newer interfaces. But if it is really a showstopper we could move from option 4 to option 3 if that would really be required.
So we start with option 4 and implement the ID3D11ShaderReflection interface in d3dcompiler_43.
Any other opinions?
Cheers Rico