A number of considerations contribute to this:
1) The shader backend knows best which shader(s) it needs. GLSL needs
both, arb only one
2) The shader backend may pass some parameters to the compilation
code(e.g. which pixel format fixup to use)
3) The structures used in (2) are different in vs and ps, so a
baseshader::Compile won't work
4) The structures in (2) are wined3d-private structures, so
having a public method in the vtable won't work(its a bad idea
anyway).
Generating the shader ID and parts of the shader prolog and epilog was
done by the common vertexshader.c / pixelshader.c, which is ugly.
This patch doesn't get rid of all the uglyness, somewhen we'll still
have to sort out the relationship of [arb|glsl]_generate_shader and
[arb|glsl]_generate_declarations.
The GL_ARB_vertex_program extension does not define a standard value for
output texture coordinates. This makes problems when using vertex
shaders with fixed function fragment processing because fffp divides the
texture coords by its .w component. This means that gl shaders have to
write to the .w component of texture coords. Direct3D shaders however
do not.
If an attribute has type D3DDECLTYPE_D3DCOLOR, the red and blue channels
are swizzled in the shader. Since the attribute is stored in the vertex
declaration and not the vertex shader, it can change by setting a new
vertex declaration. If this happens, we have to recompile the shader
with the swizzling of that specific attribute turned on or off.
ARB shaders need a swizzle for the RSQ and RCP instructions, while d3d
shaders do not. The DirectX sdk says that the x component is used if
no swizzle is given.
- Replace gl_FragColor with gl_FragData[0] for GLSL pixel shader output.
- Subtract 1 more constant from total GLSL allowed float constants to
accommodate the PROJECTION matrix row that we reference.
- Implement if, else, endif, rep, endrep, break
- Implement ifc, breakc, using undocumented comparison bits in the instruction token
- Fix bug in main loop processing of codes with no dst token
- Fix bug in GLSL output modifier processing of codes with no dst token
- Fix bug in loop implementation (src1 contains the integer data, src0 is aL)
- Add versioning for all the instructions above, and remove
GLSL_REQUIRED thing, which is useless and should be removed from all
opcodes in general.
- move DEF, DEFI, DEFB handling into the register counting pass
- keep track of defined constants as a linked list (because there's a
few of them)
- apply immediate constants after global constants in the constant
loading function
- both types of constants now get loaded with array notation in the
shader (into the same array)
- currently half the shader selection code (GLSL vs ARB) is in
fillGLcaps. The parts that check for software shaders are in
GetDeviceCaps. That placement, will work, but is definitely not optimal.
FillGLcaps should detect support - it should not make decision as to
what's used, because that's not what the purpose of the function is.
GetDeviceCaps should report support as it has already been selected.
Instead, select shader mode in its own function, called in the
appropriate places.
- unifying pixel and vertex shaders into a single selection is a
mistake. A software vertex shader can be coupled with a hardware arb or
glsl pixel shader, or no shader at all. Split them back into two and add
a SHADER_NONE variant.
- drawprim is doing support checks for ARB_PROGRAM, and making shader
decisions based on that - that's wrong, support has already been
checked, and decided upon, and shaders can be implemented via software,
ARB_PROGRAm or GLSL, so that support check isn't valid.
- Store the shader selected mode into the shader itself. Different types
of shaders can be combined, so this is an improvement. In fact, storing
the mode into the settings globally is a mistake as well - it should be
done per device, since different cards have different capabilities.
- Implemented: D3DSIO_SGN, LOOP, ENDLOOP, LOGP, LIT, DST, SINCOS
- Process instruction-based modifiers (function existed, it just
wasn't being called)
- Add loop checking to register maps.
- Renamed "sng" to "sgn" for D3DSIO_SGN - it's not handled anywhere
except for GLSL, so won't matter.
There are a total of 17 instructions without a destination token. Of
those 9 have num_params != 0, which means that we will not process any
of them correctly, because we assume the first token (if present) is a
destination token.
Those are basically all the flow control instructions, which we plan to
support very soon. They have source tokens, and no destination. Add a
flag that marks them up to the ins table. Use this flag in the trace
pass, and generation pass.