Direct3D shader compiler infrastructure

Stefan Dösinger stefandoesinger at
Sun Mar 30 18:08:09 CDT 2008


So, I am getting serious about a shader compiler and related things now, and 
I've made a design proposal.

First of all, let us collect a few things we want regarding shader handling:
-> D3DXCompileShader & Friends
-> D3DXAssembleShader & Friends
-> D3DXDisassembleShader & Friends
-> A way to deal with d3d9 and d3d10 shader language differences

All these items are related in some way, so I am proposing the following 
design of a shader library:

The core part of the library is a wine internal shader language representing 
D3D assembler shaders. Shaders in this language can be created from D3D 
Bytecode("SlDisassembleShader"), D3D ASM("SlAssembleShader") and from 
HLSL("SlCompileShader"). From the intermediate language, D3D bytecode can be 
generated in various versions(SlGenBytecode), as well as D3D Text 
asm(SlGenAsm). Unlike regular D3D asm languages, this language does not have 
a version token, it is a superset of all asm language versions. It does have 
a pixel / vertex / geometry shader flag though.

The motivation behind an intermediate language is to avoid writing many 
different code generators, which is a big part of the HLSL compiler. We also 
need a WineD3D intermediate language to share our shader generator between 
d3d9 and d3d10, and use it for both kinds of shaders. The requirements for 
both intermediate asm languages are the same. This motivates making the 
language the same to reuse code.

With those functions, the D3DX functions are pretty streightforward:
bytecode = SlGenBytecode(SlAssembleShader(char *asm_text));

bytecode = SlGenBytecode(SlCompileShader(char *hlsl_text));

asm_text = SlGenAsm(SlDisassembleShader(DWORD *bytecode));

WineD3D can be changed to use this shader language as shader input. In this 
case, d3d8, d3d9 and d3d10 run their shader bytecode through 
SlDisassembleShader, and pass the returned pointer to WineD3D. This in turn 
calls SlCopyShader to make a copy it owns, and d3d8/9/10 free their copy 
using SlDestroyShader.

With WineD3D working on the same language, we have to share the language 
definition between the shader library and WineD3D, or put the shader compiler 
into WineD3D as well. I do not like the 2nd way, as it puts things together 
that don't have to be in one lib, and wastes runtime memory. A 3rd way I have 
to consider was a SlReadShader() function with callbacks which takes over the 
current role of shader_generate_main() in WineD3D. I am not quite convinced 
by this either.

Attached are a few files for reference:
shaderlib.gif: A diagram explaining the roles of the languages(No, it is not 
UML 2.0)
uses.gif: Illustrating various uses of the shader library
shader-lang: A very early pseudocode definition of the language

The intermediate asm language follows the same principles as D3D bytecode. A 
shader contains any number of instructions, each instruction has one 
destination register and any number of source registers. The instructions 
have an opcode, writemask, modifiers. A register has a type, an index, 
information about relative addressing, source modifiers, and a swizzle.

Appart of the instructions, the shader contains a header with informations 
about the shader. Declarations, input/output semantics, special registers 
used, etc. This replaces the shader_get_registers_used() pass in WineD3D. It 
is done by the shader library, and it also generates the declarations for 1.x 
pixel shaders. (We still have to find out which texture type to read from in 

-------------- next part --------------
A non-text attachment was scrubbed...
Name: shaderlib.gif
Type: image/gif
Size: 19677 bytes
Desc: not available
Url : 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: shader-lang
Type: text/x-csrc
Size: 812 bytes
Desc: not available
Url : 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: uses.gif
Type: image/gif
Size: 15819 bytes
Desc: not available
Url : 

More information about the wine-devel mailing list