wined3d: Fix a capital letter in a parameter name.
[wine] / dlls / wined3d / state.c
1 /*
2  * Direct3D state management
3  *
4  * Copyright 2002 Lionel Ulmer
5  * Copyright 2002-2005 Jason Edmeades
6  * Copyright 2003-2004 Raphael Junqueira
7  * Copyright 2004 Christian Costa
8  * Copyright 2005 Oliver Stieber
9  * Copyright 2006 Henri Verbeet
10  * Copyright 2006-2007 Stefan Dösinger for CodeWeavers
11  *
12  * This library is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU Lesser General Public
14  * License as published by the Free Software Foundation; either
15  * version 2.1 of the License, or (at your option) any later version.
16  *
17  * This library is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20  * Lesser General Public License for more details.
21  *
22  * You should have received a copy of the GNU Lesser General Public
23  * License along with this library; if not, write to the Free Software
24  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25  */
26
27 #include "config.h"
28 #include <stdio.h>
29 #ifdef HAVE_FLOAT_H
30 # include <float.h>
31 #endif
32 #include "wined3d_private.h"
33
34 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
35 WINE_DECLARE_DEBUG_CHANNEL(d3d_shader);
36
37 #define GLINFO_LOCATION ((IWineD3DImpl *)(stateblock->wineD3DDevice->wineD3D))->gl_info
38
39 static void state_nogl(DWORD state, IWineD3DStateBlockImpl *stateblock) {
40     /* Used for states which are not mapped to a gl state as-is, but used somehow different,
41      * e.g as a parameter for drawing, or which are unimplemented in windows d3d
42      */
43     if(STATE_IS_RENDER(state)) {
44         WINED3DRENDERSTATETYPE RenderState = state - STATE_RENDER(0);
45         TRACE("(%s,%d) no direct mapping to gl\n", debug_d3drenderstate(RenderState), stateblock->renderState[RenderState]);
46     } else {
47         /* Shouldn't have an unknown type here */
48         FIXME("%d no direct mapping to gl of state with unknown type\n", state);
49     }
50 }
51
52 static void state_undefined(DWORD state, IWineD3DStateBlockImpl *stateblock) {
53     /* Print a WARN, this allows the stateblock code to loop over all states to generate a display
54      * list without causing confusing terminal output. Deliberately no special debug name here
55      * because its undefined.
56      */
57     WARN("undefined state %d\n", state);
58 }
59
60 static void state_fillmode(DWORD state, IWineD3DStateBlockImpl *stateblock) {
61     D3DFILLMODE Value = stateblock->renderState[WINED3DRS_FILLMODE];
62
63     switch(Value) {
64         case D3DFILL_POINT:
65             glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
66             checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_POINT)");
67             break;
68         case D3DFILL_WIREFRAME:
69             glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
70             checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)");
71             break;
72         case D3DFILL_SOLID:
73             glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
74             checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)");
75             break;
76         default:
77             FIXME("Unrecognized WINED3DRS_FILLMODE value %d\n", Value);
78     }
79 }
80
81 static void state_lighting(DWORD state, IWineD3DStateBlockImpl *stateblock) {
82     BOOL normals;
83
84     /* Lighting is only enabled if Vertex normals are passed by the application,
85      * but lighting does not affect the stream sources, so it is not grouped for performance reasons.
86      * This state reads the decoded vertex decl, so if it is dirty don't do anything. The
87      * vertex declaration appplying function calls this function for updating
88      */
89
90     if(isStateDirty(stateblock->wineD3DDevice, STATE_VDECL)) {
91         return;
92     }
93
94     normals = stateblock->wineD3DDevice->strided_streams.u.s.normal.lpData != NULL ||
95               stateblock->wineD3DDevice->strided_streams.u.s.normal.VBO != 0;
96
97     if (stateblock->renderState[WINED3DRS_LIGHTING] && normals) {
98         glEnable(GL_LIGHTING);
99         checkGLcall("glEnable GL_LIGHTING");
100     } else {
101         glDisable(GL_LIGHTING);
102         checkGLcall("glDisable GL_LIGHTING");
103     }
104 }
105
106 static void state_zenable(DWORD state, IWineD3DStateBlockImpl *stateblock) {
107     switch ((WINED3DZBUFFERTYPE) stateblock->renderState[WINED3DRS_ZENABLE]) {
108         case WINED3DZB_FALSE:
109             glDisable(GL_DEPTH_TEST);
110             checkGLcall("glDisable GL_DEPTH_TEST");
111             break;
112         case WINED3DZB_TRUE:
113             glEnable(GL_DEPTH_TEST);
114             checkGLcall("glEnable GL_DEPTH_TEST");
115             break;
116         case WINED3DZB_USEW:
117             glEnable(GL_DEPTH_TEST);
118             checkGLcall("glEnable GL_DEPTH_TEST");
119             FIXME("W buffer is not well handled\n");
120             break;
121         default:
122             FIXME("Unrecognized D3DZBUFFERTYPE value %d\n", stateblock->renderState[WINED3DRS_ZENABLE]);
123     }
124 }
125
126 static void state_cullmode(DWORD state, IWineD3DStateBlockImpl *stateblock) {
127     /* TODO: Put this into the offscreen / onscreen rendering block due to device->render_offscreen */
128
129     /* If we are culling "back faces with clockwise vertices" then
130        set front faces to be counter clockwise and enable culling
131        of back faces                                               */
132     switch ((WINED3DCULL) stateblock->renderState[WINED3DRS_CULLMODE]) {
133         case WINED3DCULL_NONE:
134             glDisable(GL_CULL_FACE);
135             checkGLcall("glDisable GL_CULL_FACE");
136             break;
137         case WINED3DCULL_CW:
138             glEnable(GL_CULL_FACE);
139             checkGLcall("glEnable GL_CULL_FACE");
140             if (stateblock->wineD3DDevice->render_offscreen) {
141                 glFrontFace(GL_CW);
142                 checkGLcall("glFrontFace GL_CW");
143             } else {
144                 glFrontFace(GL_CCW);
145                 checkGLcall("glFrontFace GL_CCW");
146             }
147             glCullFace(GL_BACK);
148             break;
149         case WINED3DCULL_CCW:
150             glEnable(GL_CULL_FACE);
151             checkGLcall("glEnable GL_CULL_FACE");
152             if (stateblock->wineD3DDevice->render_offscreen) {
153                 glFrontFace(GL_CCW);
154                 checkGLcall("glFrontFace GL_CCW");
155             } else {
156                 glFrontFace(GL_CW);
157                 checkGLcall("glFrontFace GL_CW");
158             }
159             glCullFace(GL_BACK);
160             break;
161         default:
162             FIXME("Unrecognized/Unhandled WINED3DCULL value %d\n", stateblock->renderState[WINED3DRS_CULLMODE]);
163     }
164 }
165
166 static void state_shademode(DWORD state, IWineD3DStateBlockImpl *stateblock) {
167     switch ((WINED3DSHADEMODE) stateblock->renderState[WINED3DRS_SHADEMODE]) {
168         case WINED3DSHADE_FLAT:
169             glShadeModel(GL_FLAT);
170             checkGLcall("glShadeModel(GL_FLAT)");
171             break;
172         case WINED3DSHADE_GOURAUD:
173             glShadeModel(GL_SMOOTH);
174             checkGLcall("glShadeModel(GL_SMOOTH)");
175             break;
176         case WINED3DSHADE_PHONG:
177             FIXME("WINED3DSHADE_PHONG isn't supported\n");
178             break;
179         default:
180             FIXME("Unrecognized/Unhandled WINED3DSHADEMODE value %d\n", stateblock->renderState[WINED3DRS_SHADEMODE]);
181     }
182 }
183
184 static void state_ditherenable(DWORD state, IWineD3DStateBlockImpl *stateblock) {
185     if (stateblock->renderState[WINED3DRS_DITHERENABLE]) {
186         glEnable(GL_DITHER);
187         checkGLcall("glEnable GL_DITHER");
188     } else {
189         glDisable(GL_DITHER);
190         checkGLcall("glDisable GL_DITHER");
191     }
192 }
193
194 static void state_zwritenable(DWORD state, IWineD3DStateBlockImpl *stateblock) {
195     /* TODO: Test if in d3d z writing is enabled even if ZENABLE is off. If yes,
196      * this has to be merged with ZENABLE and ZFUNC
197      */
198     if (stateblock->renderState[WINED3DRS_ZWRITEENABLE]) {
199         glDepthMask(1);
200         checkGLcall("glDepthMask(1)");
201     } else {
202         glDepthMask(0);
203         checkGLcall("glDepthMask(0)");
204     }
205 }
206
207 static void state_zfunc(DWORD state, IWineD3DStateBlockImpl *stateblock) {
208     int glParm = CompareFunc(stateblock->renderState[WINED3DRS_ZFUNC]);
209
210     if(glParm) {
211         glDepthFunc(glParm);
212         checkGLcall("glDepthFunc");
213     }
214 }
215
216 static void state_ambient(DWORD state, IWineD3DStateBlockImpl *stateblock) {
217     float col[4];
218     D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_AMBIENT], col);
219
220     TRACE("Setting ambient to (%f,%f,%f,%f)\n", col[0], col[1], col[2], col[3]);
221     glLightModelfv(GL_LIGHT_MODEL_AMBIENT, col);
222     checkGLcall("glLightModel for MODEL_AMBIENT");
223 }
224
225 static void state_blend(DWORD state, IWineD3DStateBlockImpl *stateblock) {
226     int srcBlend = GL_ZERO;
227     int dstBlend = GL_ZERO;
228
229     /* GL_LINE_SMOOTH needs GL_BLEND to work, according to the red book, and special blending params */
230     if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE]      ||
231         stateblock->renderState[WINED3DRS_EDGEANTIALIAS]         ||
232         stateblock->renderState[WINED3DRS_ANTIALIASEDLINEENABLE]) {
233         glEnable(GL_BLEND);
234         checkGLcall("glEnable GL_BLEND");
235     } else {
236         glDisable(GL_BLEND);
237         checkGLcall("glDisable GL_BLEND");
238         /* Nothing more to do - get out */
239         return;
240     };
241
242     switch (stateblock->renderState[WINED3DRS_SRCBLEND]) {
243         case WINED3DBLEND_ZERO               : srcBlend = GL_ZERO;  break;
244         case WINED3DBLEND_ONE                : srcBlend = GL_ONE;  break;
245         case WINED3DBLEND_SRCCOLOR           : srcBlend = GL_SRC_COLOR;  break;
246         case WINED3DBLEND_INVSRCCOLOR        : srcBlend = GL_ONE_MINUS_SRC_COLOR;  break;
247         case WINED3DBLEND_SRCALPHA           : srcBlend = GL_SRC_ALPHA;  break;
248         case WINED3DBLEND_INVSRCALPHA        : srcBlend = GL_ONE_MINUS_SRC_ALPHA;  break;
249         case WINED3DBLEND_DESTALPHA          : srcBlend = GL_DST_ALPHA;  break;
250         case WINED3DBLEND_INVDESTALPHA       : srcBlend = GL_ONE_MINUS_DST_ALPHA;  break;
251         case WINED3DBLEND_DESTCOLOR          : srcBlend = GL_DST_COLOR;  break;
252         case WINED3DBLEND_INVDESTCOLOR       : srcBlend = GL_ONE_MINUS_DST_COLOR;  break;
253         case WINED3DBLEND_SRCALPHASAT        : srcBlend = GL_SRC_ALPHA_SATURATE;  break;
254
255         case WINED3DBLEND_BOTHSRCALPHA       : srcBlend = GL_SRC_ALPHA;
256             dstBlend = GL_SRC_ALPHA;
257             break;
258
259         case WINED3DBLEND_BOTHINVSRCALPHA    : srcBlend = GL_ONE_MINUS_SRC_ALPHA;
260             dstBlend = GL_ONE_MINUS_SRC_ALPHA;
261             break;
262
263         case WINED3DBLEND_BLENDFACTOR        : srcBlend = GL_CONSTANT_COLOR;   break;
264         case WINED3DBLEND_INVBLENDFACTOR     : srcBlend = GL_ONE_MINUS_CONSTANT_COLOR;  break;
265         default:
266             FIXME("Unrecognized src blend value %d\n", stateblock->renderState[WINED3DRS_SRCBLEND]);
267     }
268
269     switch (stateblock->renderState[WINED3DRS_DESTBLEND]) {
270         case WINED3DBLEND_ZERO               : dstBlend = GL_ZERO;  break;
271         case WINED3DBLEND_ONE                : dstBlend = GL_ONE;  break;
272         case WINED3DBLEND_SRCCOLOR           : dstBlend = GL_SRC_COLOR;  break;
273         case WINED3DBLEND_INVSRCCOLOR        : dstBlend = GL_ONE_MINUS_SRC_COLOR;  break;
274         case WINED3DBLEND_SRCALPHA           : dstBlend = GL_SRC_ALPHA;  break;
275         case WINED3DBLEND_INVSRCALPHA        : dstBlend = GL_ONE_MINUS_SRC_ALPHA;  break;
276         case WINED3DBLEND_DESTALPHA          : dstBlend = GL_DST_ALPHA;  break;
277         case WINED3DBLEND_INVDESTALPHA       : dstBlend = GL_ONE_MINUS_DST_ALPHA;  break;
278         case WINED3DBLEND_DESTCOLOR          : dstBlend = GL_DST_COLOR;  break;
279         case WINED3DBLEND_INVDESTCOLOR       : dstBlend = GL_ONE_MINUS_DST_COLOR;  break;
280         case WINED3DBLEND_SRCALPHASAT        : dstBlend = GL_SRC_ALPHA_SATURATE;  break;
281
282         case WINED3DBLEND_BOTHSRCALPHA       : dstBlend = GL_SRC_ALPHA;
283             srcBlend = GL_SRC_ALPHA;
284             break;
285
286         case WINED3DBLEND_BOTHINVSRCALPHA    : dstBlend = GL_ONE_MINUS_SRC_ALPHA;
287             srcBlend = GL_ONE_MINUS_SRC_ALPHA;
288             break;
289
290         case D3DBLEND_BLENDFACTOR        : dstBlend = GL_CONSTANT_COLOR;   break;
291         case D3DBLEND_INVBLENDFACTOR     : dstBlend = GL_ONE_MINUS_CONSTANT_COLOR;  break;
292         default:
293             FIXME("Unrecognized dst blend value %d\n", stateblock->renderState[WINED3DRS_DESTBLEND]);
294     }
295
296     if(stateblock->renderState[WINED3DRS_EDGEANTIALIAS] ||
297        stateblock->renderState[WINED3DRS_ANTIALIASEDLINEENABLE]) {
298         glEnable(GL_LINE_SMOOTH);
299         checkGLcall("glEnable(GL_LINE_SMOOTH)");
300         if(srcBlend != GL_SRC_ALPHA) {
301             FIXME("WINED3DRS_EDGEANTIALIAS enabled, but incompatible src blending param - what to do?\n");
302             srcBlend = GL_SRC_ALPHA;
303         }
304         if(dstBlend != GL_ONE_MINUS_SRC_ALPHA) {
305             FIXME("WINED3DRS_EDGEANTIALIAS enabled, but incompatible dst blending param - what to do?\n");
306             dstBlend = GL_ONE_MINUS_SRC_ALPHA;
307         }
308     } else {
309         glDisable(GL_LINE_SMOOTH);
310         checkGLcall("glDisable(GL_LINE_SMOOTH)");
311     }
312
313     TRACE("glBlendFunc src=%x, dst=%x\n", srcBlend, dstBlend);
314     glBlendFunc(srcBlend, dstBlend);
315     checkGLcall("glBlendFunc");
316 }
317
318 static void state_blendfactor(DWORD state, IWineD3DStateBlockImpl *stateblock) {
319     float col[4];
320
321     TRACE("Setting BlendFactor to %d\n", stateblock->renderState[WINED3DRS_BLENDFACTOR]);
322     D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_BLENDFACTOR], col);
323     glBlendColor (col[0],col[1],col[2],col[3]);
324     checkGLcall("glBlendColor");
325 }
326
327 static void state_alpha(DWORD state, IWineD3DStateBlockImpl *stateblock) {
328     int glParm = 0;
329     float ref;
330     BOOL enable_ckey = FALSE;
331
332     IWineD3DSurfaceImpl *surf;
333
334     /* Find out if the texture on the first stage has a ckey set
335      * The alpha state func reads the texture settings, even though alpha and texture are not grouped
336      * together. This is to avoid making a huge alpha+texture+texture stage+ckey block due to the hardly
337      * used WINED3DRS_COLORKEYENABLE state(which is d3d <= 3 only). The texture function will call alpha
338      * in case it finds some texture+colorkeyenable combination which needs extra care.
339      */
340     if(stateblock->textures[0]) {
341         surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *)stateblock->textures[0])->surfaces[0];
342         if(surf->CKeyFlags & DDSD_CKSRCBLT) enable_ckey = TRUE;
343     }
344
345     if (stateblock->renderState[WINED3DRS_ALPHATESTENABLE] ||
346         (stateblock->renderState[WINED3DRS_COLORKEYENABLE] && enable_ckey)) {
347         glEnable(GL_ALPHA_TEST);
348         checkGLcall("glEnable GL_ALPHA_TEST");
349     } else {
350         glDisable(GL_ALPHA_TEST);
351         checkGLcall("glDisable GL_ALPHA_TEST");
352         /* Alpha test is disabled, don't bother setting the params - it will happen on the next
353          * enable call
354          */
355         return;
356     }
357
358     if(stateblock->renderState[WINED3DRS_COLORKEYENABLE] && enable_ckey) {
359         glParm = GL_NOTEQUAL;
360         ref = 0.0;
361     } else {
362         ref = ((float) stateblock->renderState[WINED3DRS_ALPHAREF]) / 255.0f;
363         glParm = CompareFunc(stateblock->renderState[WINED3DRS_ALPHAFUNC]);
364     }
365     if(glParm) {
366         glAlphaFunc(glParm, ref);
367         checkGLcall("glAlphaFunc");
368     }
369     /* TODO: Some texture blending operations seem to affect the alpha test */
370 }
371
372 static void state_clipping(DWORD state, IWineD3DStateBlockImpl *stateblock) {
373     DWORD enable  = 0xFFFFFFFF;
374     DWORD disable = 0x00000000;
375
376     /* TODO: Keep track of previously enabled clipplanes to avoid unneccessary resetting
377      * of already set values
378      */
379
380     /* If enabling / disabling all
381      * TODO: Is this correct? Doesn't D3DRS_CLIPPING disable clipping on the viewport frustrum?
382      */
383     if (stateblock->renderState[WINED3DRS_CLIPPING]) {
384         enable  = stateblock->renderState[WINED3DRS_CLIPPLANEENABLE];
385         disable = ~stateblock->renderState[WINED3DRS_CLIPPLANEENABLE];
386     } else {
387         disable = 0xffffffff;
388         enable  = 0x00;
389     }
390
391     if (enable & WINED3DCLIPPLANE0)  { glEnable(GL_CLIP_PLANE0);  checkGLcall("glEnable(clip plane 0)"); }
392     if (enable & WINED3DCLIPPLANE1)  { glEnable(GL_CLIP_PLANE1);  checkGLcall("glEnable(clip plane 1)"); }
393     if (enable & WINED3DCLIPPLANE2)  { glEnable(GL_CLIP_PLANE2);  checkGLcall("glEnable(clip plane 2)"); }
394     if (enable & WINED3DCLIPPLANE3)  { glEnable(GL_CLIP_PLANE3);  checkGLcall("glEnable(clip plane 3)"); }
395     if (enable & WINED3DCLIPPLANE4)  { glEnable(GL_CLIP_PLANE4);  checkGLcall("glEnable(clip plane 4)"); }
396     if (enable & WINED3DCLIPPLANE5)  { glEnable(GL_CLIP_PLANE5);  checkGLcall("glEnable(clip plane 5)"); }
397
398     if (disable & WINED3DCLIPPLANE0) { glDisable(GL_CLIP_PLANE0); checkGLcall("glDisable(clip plane 0)"); }
399     if (disable & WINED3DCLIPPLANE1) { glDisable(GL_CLIP_PLANE1); checkGLcall("glDisable(clip plane 1)"); }
400     if (disable & WINED3DCLIPPLANE2) { glDisable(GL_CLIP_PLANE2); checkGLcall("glDisable(clip plane 2)"); }
401     if (disable & WINED3DCLIPPLANE3) { glDisable(GL_CLIP_PLANE3); checkGLcall("glDisable(clip plane 3)"); }
402     if (disable & WINED3DCLIPPLANE4) { glDisable(GL_CLIP_PLANE4); checkGLcall("glDisable(clip plane 4)"); }
403     if (disable & WINED3DCLIPPLANE5) { glDisable(GL_CLIP_PLANE5); checkGLcall("glDisable(clip plane 5)"); }
404
405     /** update clipping status */
406     if (enable) {
407         stateblock->clip_status.ClipUnion = 0;
408         stateblock->clip_status.ClipIntersection = 0xFFFFFFFF;
409     } else {
410         stateblock->clip_status.ClipUnion = 0;
411         stateblock->clip_status.ClipIntersection = 0;
412     }
413 }
414
415 static void state_blendop(DWORD state, IWineD3DStateBlockImpl *stateblock) {
416     int glParm = GL_FUNC_ADD;
417
418     if(!GL_SUPPORT(EXT_BLEND_MINMAX)) {
419         WARN("Unsupported in local OpenGL implementation: glBlendEquation\n");
420         return;
421     }
422
423     switch ((WINED3DBLENDOP) stateblock->renderState[WINED3DRS_BLENDOP]) {
424         case WINED3DBLENDOP_ADD              : glParm = GL_FUNC_ADD;              break;
425         case WINED3DBLENDOP_SUBTRACT         : glParm = GL_FUNC_SUBTRACT;         break;
426         case WINED3DBLENDOP_REVSUBTRACT      : glParm = GL_FUNC_REVERSE_SUBTRACT; break;
427         case WINED3DBLENDOP_MIN              : glParm = GL_MIN;                   break;
428         case WINED3DBLENDOP_MAX              : glParm = GL_MAX;                   break;
429         default:
430             FIXME("Unrecognized/Unhandled D3DBLENDOP value %d\n", stateblock->renderState[WINED3DRS_BLENDOP]);
431     }
432
433     TRACE("glBlendEquation(%x)\n", glParm);
434     GL_EXTCALL(glBlendEquation(glParm));
435     checkGLcall("glBlendEquation");
436 }
437
438 static void
439 state_specularenable(DWORD state, IWineD3DStateBlockImpl *stateblock) {
440     /* Originally this used glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR)
441      * and (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR) to swap between enabled/disabled
442      * specular color. This is wrong:
443      * Separate specular color means the specular colour is maintained separately, whereas
444      * single color means it is merged in. However in both cases they are being used to
445      * some extent.
446      * To disable specular color, set it explicitly to black and turn off GL_COLOR_SUM_EXT
447      * NOTE: If not supported don't give FIXMEs the impact is really minimal and very few people are
448      * running 1.4 yet!
449      *
450      *
451      * If register combiners are enabled, enabling / disabling GL_COLOR_SUM has no effect.
452      * Instead, we need to setup the FinalCombiner properly.
453      *
454      * The default setup for the FinalCombiner is:
455      *
456      * <variable>       <input>                             <mapping>               <usage>
457      * GL_VARIABLE_A_NV GL_FOG,                             GL_UNSIGNED_IDENTITY_NV GL_ALPHA
458      * GL_VARIABLE_B_NV GL_SPARE0_PLUS_SECONDARY_COLOR_NV   GL_UNSIGNED_IDENTITY_NV GL_RGB
459      * GL_VARIABLE_C_NV GL_FOG                              GL_UNSIGNED_IDENTITY_NV GL_RGB
460      * GL_VARIABLE_D_NV GL_ZERO                             GL_UNSIGNED_IDENTITY_NV GL_RGB
461      * GL_VARIABLE_E_NV GL_ZERO                             GL_UNSIGNED_IDENTITY_NV GL_RGB
462      * GL_VARIABLE_F_NV GL_ZERO                             GL_UNSIGNED_IDENTITY_NV GL_RGB
463      * GL_VARIABLE_G_NV GL_SPARE0_NV                        GL_UNSIGNED_IDENTITY_NV GL_ALPHA
464      *
465      * That's pretty much fine as it is, except for variable B, which needs to take
466      * either GL_SPARE0_PLUS_SECONDARY_COLOR_NV or GL_SPARE0_NV, depending on
467      * whether WINED3DRS_SPECULARENABLE is enabled or not.
468      */
469
470     TRACE("Setting specular enable state\n");
471     /* TODO: Add to the material setting functions */
472     if (stateblock->renderState[WINED3DRS_SPECULARENABLE]) {
473         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float*) &stateblock->material.Specular);
474         checkGLcall("glMaterialfv");
475         if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
476             glEnable(GL_COLOR_SUM_EXT);
477         } else {
478             TRACE("Specular colors cannot be enabled in this version of opengl\n");
479         }
480         checkGLcall("glEnable(GL_COLOR_SUM)");
481
482         if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
483             GL_EXTCALL(glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_SPARE0_PLUS_SECONDARY_COLOR_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB));
484             checkGLcall("glFinalCombinerInputNV()");
485         }
486     } else {
487         float black[4] = {0.0f, 0.0f, 0.0f, 0.0f};
488
489         /* for the case of enabled lighting: */
490         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
491         checkGLcall("glMaterialfv");
492
493         /* for the case of disabled lighting: */
494         if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
495             glDisable(GL_COLOR_SUM_EXT);
496         } else {
497             TRACE("Specular colors cannot be disabled in this version of opengl\n");
498         }
499         checkGLcall("glDisable(GL_COLOR_SUM)");
500
501         if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
502             GL_EXTCALL(glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB));
503             checkGLcall("glFinalCombinerInputNV()");
504         }
505     }
506 }
507
508 static void state_texfactor(DWORD state, IWineD3DStateBlockImpl *stateblock) {
509     unsigned int i;
510
511     /* Note the texture color applies to all textures whereas
512      * GL_TEXTURE_ENV_COLOR applies to active only
513      */
514     float col[4];
515     D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_TEXTUREFACTOR], col);
516
517     if (!GL_SUPPORT(NV_REGISTER_COMBINERS)) {
518         /* And now the default texture color as well */
519         for (i = 0; i < GL_LIMITS(texture_stages); i++) {
520             /* Note the WINED3DRS value applies to all textures, but GL has one
521              * per texture, so apply it now ready to be used!
522              */
523             if (GL_SUPPORT(ARB_MULTITEXTURE)) {
524                 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + i));
525                 checkGLcall("glActiveTextureARB");
526             } else if (i>0) {
527                 FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
528             }
529
530             glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
531             checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
532         }
533     } else {
534         GL_EXTCALL(glCombinerParameterfvNV(GL_CONSTANT_COLOR0_NV, &col[0]));
535     }
536 }
537
538 static void
539 renderstate_stencil_twosided(IWineD3DStateBlockImpl *stateblock, GLint face, GLint func, GLint ref, GLuint mask, GLint stencilFail, GLint depthFail, GLint stencilPass ) {
540 #if 0 /* Don't use OpenGL 2.0 calls for now */
541             if(GL_EXTCALL(glStencilFuncSeparate) && GL_EXTCALL(glStencilOpSeparate)) {
542                 GL_EXTCALL(glStencilFuncSeparate(face, func, ref, mask));
543                 checkGLcall("glStencilFuncSeparate(...)");
544                 GL_EXTCALL(glStencilOpSeparate(face, stencilFail, depthFail, stencilPass));
545                 checkGLcall("glStencilOpSeparate(...)");
546         }
547             else
548 #endif
549     if(GL_SUPPORT(EXT_STENCIL_TWO_SIDE)) {
550         glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);
551         checkGLcall("glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT)");
552         GL_EXTCALL(glActiveStencilFaceEXT(face));
553         checkGLcall("glActiveStencilFaceEXT(...)");
554         glStencilFunc(func, ref, mask);
555         checkGLcall("glStencilFunc(...)");
556         glStencilOp(stencilFail, depthFail, stencilPass);
557         checkGLcall("glStencilOp(...)");
558     } else if(GL_SUPPORT(ATI_SEPARATE_STENCIL)) {
559         GL_EXTCALL(glStencilFuncSeparateATI(face, func, ref, mask));
560         checkGLcall("glStencilFuncSeparateATI(...)");
561         GL_EXTCALL(glStencilOpSeparateATI(face, stencilFail, depthFail, stencilPass));
562         checkGLcall("glStencilOpSeparateATI(...)");
563     } else {
564         ERR("Separate (two sided) stencil not supported on this version of opengl. Caps weren't honored?\n");
565     }
566 }
567
568 static void
569 state_stencil(DWORD state, IWineD3DStateBlockImpl *stateblock) {
570     DWORD onesided_enable = FALSE;
571     DWORD twosided_enable = FALSE;
572     GLint func = GL_ALWAYS;
573     GLint func_ccw = GL_ALWAYS;
574     GLint ref = 0;
575     GLuint mask = 0;
576     GLint stencilFail = GL_KEEP;
577     GLint depthFail = GL_KEEP;
578     GLint stencilPass = GL_KEEP;
579     GLint stencilFail_ccw = GL_KEEP;
580     GLint depthFail_ccw = GL_KEEP;
581     GLint stencilPass_ccw = GL_KEEP;
582
583     if( stateblock->set.renderState[WINED3DRS_STENCILENABLE] )
584         onesided_enable = stateblock->renderState[WINED3DRS_STENCILENABLE];
585     if( stateblock->set.renderState[WINED3DRS_TWOSIDEDSTENCILMODE] )
586         twosided_enable = stateblock->renderState[WINED3DRS_TWOSIDEDSTENCILMODE];
587     if( stateblock->set.renderState[WINED3DRS_STENCILFUNC] )
588         if( !( func = CompareFunc(stateblock->renderState[WINED3DRS_STENCILFUNC]) ) )
589             func = GL_ALWAYS;
590     if( stateblock->set.renderState[WINED3DRS_CCW_STENCILFUNC] )
591         if( !( func_ccw = CompareFunc(stateblock->renderState[WINED3DRS_CCW_STENCILFUNC]) ) )
592             func = GL_ALWAYS;
593     if( stateblock->set.renderState[WINED3DRS_STENCILREF] )
594         ref = stateblock->renderState[WINED3DRS_STENCILREF];
595     if( stateblock->set.renderState[WINED3DRS_STENCILMASK] )
596         mask = stateblock->renderState[WINED3DRS_STENCILMASK];
597     if( stateblock->set.renderState[WINED3DRS_STENCILFAIL] )
598         stencilFail = StencilOp(stateblock->renderState[WINED3DRS_STENCILFAIL]);
599     if( stateblock->set.renderState[WINED3DRS_STENCILZFAIL] )
600         depthFail = StencilOp(stateblock->renderState[WINED3DRS_STENCILZFAIL]);
601     if( stateblock->set.renderState[WINED3DRS_STENCILPASS] )
602         stencilPass = StencilOp(stateblock->renderState[WINED3DRS_STENCILPASS]);
603     if( stateblock->set.renderState[WINED3DRS_CCW_STENCILFAIL] )
604         stencilFail_ccw = StencilOp(stateblock->renderState[WINED3DRS_CCW_STENCILFAIL]);
605     if( stateblock->set.renderState[WINED3DRS_CCW_STENCILZFAIL] )
606         depthFail_ccw = StencilOp(stateblock->renderState[WINED3DRS_CCW_STENCILZFAIL]);
607     if( stateblock->set.renderState[WINED3DRS_CCW_STENCILPASS] )
608         stencilPass_ccw = StencilOp(stateblock->renderState[WINED3DRS_CCW_STENCILPASS]);
609
610     TRACE("(onesided %d, twosided %d, ref %x, mask %x, "
611           "GL_FRONT: func: %x, fail %x, zfail %x, zpass %x "
612           "GL_BACK: func: %x, fail %x, zfail %x, zpass %x )\n",
613     onesided_enable, twosided_enable, ref, mask,
614     func, stencilFail, depthFail, stencilPass,
615     func_ccw, stencilFail_ccw, depthFail_ccw, stencilPass_ccw);
616
617     if (twosided_enable) {
618         renderstate_stencil_twosided(stateblock, GL_FRONT, func, ref, mask, stencilFail, depthFail, stencilPass);
619         renderstate_stencil_twosided(stateblock, GL_BACK, func_ccw, ref, mask, stencilFail_ccw, depthFail_ccw, stencilPass_ccw);
620     } else {
621         if (onesided_enable) {
622             glEnable(GL_STENCIL_TEST);
623             checkGLcall("glEnable GL_STENCIL_TEST");
624             glStencilFunc(func, ref, mask);
625             checkGLcall("glStencilFunc(...)");
626             glStencilOp(stencilFail, depthFail, stencilPass);
627             checkGLcall("glStencilOp(...)");
628         } else {
629             glDisable(GL_STENCIL_TEST);
630             checkGLcall("glDisable GL_STENCIL_TEST");
631         }
632     }
633 }
634
635 static void state_stencilwrite(DWORD state, IWineD3DStateBlockImpl *stateblock) {
636     glStencilMask(stateblock->renderState[WINED3DRS_STENCILWRITEMASK]);
637     checkGLcall("glStencilMask");
638 }
639
640 static void state_fog(DWORD state, IWineD3DStateBlockImpl *stateblock) {
641     /* TODO: Put this into the vertex type block once that is in the state table */
642     BOOL fogenable = stateblock->renderState[WINED3DRS_FOGENABLE];
643     float fogstart, fogend;
644
645     union {
646         DWORD d;
647         float f;
648     } tmpvalue;
649
650     if (!fogenable) {
651         /* No fog? Disable it, and we're done :-) */
652         glDisable(GL_FOG);
653         checkGLcall("glDisable GL_FOG");
654     }
655
656     tmpvalue.d = stateblock->renderState[WINED3DRS_FOGSTART];
657     fogstart = tmpvalue.f;
658     tmpvalue.d = stateblock->renderState[WINED3DRS_FOGEND];
659     fogend = tmpvalue.f;
660
661     /* Activate when vertex shaders are in the state table */
662     if(stateblock->vertexShader && ((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.function &&
663        ((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->usesFog) {
664         glFogi(GL_FOG_MODE, GL_LINEAR);
665         checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
666         fogstart = 1.0;
667         fogend = 0.0;
668         stateblock->wineD3DDevice->last_was_foggy_shader = TRUE;
669     }
670     /* DX 7 sdk: "If both render states(vertex and table fog) are set to valid modes,
671      * the system will apply only pixel(=table) fog effects."
672      */
673     else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == D3DFOG_NONE) {
674         glHint(GL_FOG_HINT, GL_FASTEST);
675         checkGLcall("glHint(GL_FOG_HINT, GL_FASTEST)");
676         stateblock->wineD3DDevice->last_was_foggy_shader = FALSE;
677
678         switch (stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
679             /* Processed vertices have their fog factor stored in the specular value. Fall too the none case.
680              * If we are drawing untransformed vertices atm, d3ddevice_set_ortho will update the fog
681              */
682             case D3DFOG_EXP:  {
683                 if(!stateblock->wineD3DDevice->last_was_rhw) {
684                     glFogi(GL_FOG_MODE, GL_EXP);
685                     checkGLcall("glFogi(GL_FOG_MODE, GL_EXP");
686                     if(GL_SUPPORT(EXT_FOG_COORD)) {
687                         glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
688                         checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
689                     }
690                     break;
691                 }
692             }
693             case D3DFOG_EXP2: {
694                 if(!stateblock->wineD3DDevice->last_was_rhw) {
695                     glFogi(GL_FOG_MODE, GL_EXP2);
696                     checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2");
697                     if(GL_SUPPORT(EXT_FOG_COORD)) {
698                         glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
699                         checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
700                     }
701                     break;
702                 }
703             }
704             case D3DFOG_LINEAR: {
705                 if(!stateblock->wineD3DDevice->last_was_rhw) {
706                     glFogi(GL_FOG_MODE, GL_LINEAR);
707                     checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR");
708                     if(GL_SUPPORT(EXT_FOG_COORD)) {
709                         glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
710                         checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
711                     }
712                     break;
713                 }
714             }
715             case D3DFOG_NONE: {
716                 /* Both are none? According to msdn the alpha channel of the specular
717                  * color contains a fog factor. Set it in drawStridedSlow.
718                  * Same happens with Vertexfog on transformed vertices
719                  */
720                 if(GL_SUPPORT(EXT_FOG_COORD)) {
721                     glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);
722                     checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT)\n");
723                     glFogi(GL_FOG_MODE, GL_LINEAR);
724                     checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
725                     fogstart = 0xff;
726                     fogend = 0x0;
727                 } else {
728                     /* Disable GL fog, handle this in software in drawStridedSlow */
729                     fogenable = FALSE;
730                 }
731                 break;
732             }
733             default: FIXME("Unexpected WINED3DRS_FOGVERTEXMODE %d\n", stateblock->renderState[WINED3DRS_FOGVERTEXMODE]);
734         }
735     } else {
736         glHint(GL_FOG_HINT, GL_NICEST);
737         checkGLcall("glHint(GL_FOG_HINT, GL_NICEST)");
738         stateblock->wineD3DDevice->last_was_foggy_shader = FALSE;
739
740         switch (stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
741             case D3DFOG_EXP:
742                 glFogi(GL_FOG_MODE, GL_EXP);
743                 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP");
744                 if(GL_SUPPORT(EXT_FOG_COORD)) {
745                     glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
746                     checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
747                 }
748                 break;
749
750             case D3DFOG_EXP2:
751                 glFogi(GL_FOG_MODE, GL_EXP2);
752                 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2");
753                 if(GL_SUPPORT(EXT_FOG_COORD)) {
754                     glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
755                     checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
756                 }
757                 break;
758
759             case D3DFOG_LINEAR:
760                 glFogi(GL_FOG_MODE, GL_LINEAR);
761                 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR");
762                 if(GL_SUPPORT(EXT_FOG_COORD)) {
763                     glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
764                     checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
765                 }
766                 break;
767
768             case D3DFOG_NONE:   /* Won't happen */
769             default:
770                 FIXME("Unexpected WINED3DRS_FOGTABLEMODE %d\n", stateblock->renderState[WINED3DRS_FOGTABLEMODE]);
771         }
772     }
773
774     if(fogenable) {
775         glEnable(GL_FOG);
776         checkGLcall("glEnable GL_FOG");
777
778         glFogfv(GL_FOG_START, &fogstart);
779         checkGLcall("glFogf(GL_FOG_START, fogstart");
780         TRACE("Fog Start == %f\n", fogstart);
781
782         glFogfv(GL_FOG_END, &fogend);
783         checkGLcall("glFogf(GL_FOG_END, fogend");
784         TRACE("Fog End == %f\n", fogend);
785     } else {
786         glDisable(GL_FOG);
787         checkGLcall("glDisable GL_FOG");
788     }
789
790     if (GL_SUPPORT(NV_FOG_DISTANCE)) {
791         glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV);
792     }
793 }
794
795 static void state_fogcolor(DWORD state, IWineD3DStateBlockImpl *stateblock) {
796     float col[4];
797     D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_FOGCOLOR], col);
798     /* Set the default alpha blend color */
799     glFogfv(GL_FOG_COLOR, &col[0]);
800     checkGLcall("glFog GL_FOG_COLOR");
801 }
802
803 static void state_fogdensity(DWORD state, IWineD3DStateBlockImpl *stateblock) {
804     union {
805         DWORD d;
806         float f;
807     } tmpvalue;
808     tmpvalue.d = stateblock->renderState[WINED3DRS_FOGDENSITY];
809     glFogfv(GL_FOG_DENSITY, &tmpvalue.f);
810     checkGLcall("glFogf(GL_FOG_DENSITY, (float) Value)");
811 }
812
813 /* TODO: Merge with primitive type + init_materials()!! */
814 static void state_colormat(DWORD state, IWineD3DStateBlockImpl *stateblock) {
815     GLenum Parm = -1;
816     WineDirect3DStridedData *diffuse = &stateblock->wineD3DDevice->strided_streams.u.s.diffuse;
817     BOOL isDiffuseSupplied;
818
819     /* Depends on the decoded vertex declaration to read the existance of diffuse data.
820      * The vertex declaration will call this function if the fixed function pipeline is used.
821      */
822     if(isStateDirty(stateblock->wineD3DDevice, STATE_VDECL)) {
823         return;
824     }
825
826     isDiffuseSupplied = diffuse->lpData || diffuse->VBO;
827
828     if (stateblock->renderState[WINED3DRS_COLORVERTEX]) {
829         TRACE("diff %d, amb %d, emis %d, spec %d\n",
830               stateblock->renderState[WINED3DRS_DIFFUSEMATERIALSOURCE],
831               stateblock->renderState[WINED3DRS_AMBIENTMATERIALSOURCE],
832               stateblock->renderState[WINED3DRS_EMISSIVEMATERIALSOURCE],
833               stateblock->renderState[WINED3DRS_SPECULARMATERIALSOURCE]);
834
835         if (stateblock->renderState[WINED3DRS_DIFFUSEMATERIALSOURCE] == D3DMCS_COLOR1) {
836             if (stateblock->renderState[WINED3DRS_AMBIENTMATERIALSOURCE] == D3DMCS_COLOR1) {
837                 Parm = GL_AMBIENT_AND_DIFFUSE;
838             } else {
839                 Parm = GL_DIFFUSE;
840             }
841         } else if (stateblock->renderState[WINED3DRS_AMBIENTMATERIALSOURCE] == D3DMCS_COLOR1) {
842             Parm = GL_AMBIENT;
843         } else if (stateblock->renderState[WINED3DRS_EMISSIVEMATERIALSOURCE] == D3DMCS_COLOR1) {
844             Parm = GL_EMISSION;
845         } else if (stateblock->renderState[WINED3DRS_SPECULARMATERIALSOURCE] == D3DMCS_COLOR1) {
846             Parm = GL_SPECULAR;
847         }
848     }
849
850     if(Parm == -1 || !isDiffuseSupplied) {
851         glDisable(GL_COLOR_MATERIAL);
852         checkGLcall("glDisable GL_COLOR_MATERIAL");
853     } else {
854         glColorMaterial(GL_FRONT_AND_BACK, Parm);
855         checkGLcall("glColorMaterial(GL_FRONT_AND_BACK, Parm)");
856         glEnable(GL_COLOR_MATERIAL);
857         checkGLcall("glEnable(GL_COLOR_MATERIAL)");
858     }
859 }
860
861 static void state_linepattern(DWORD state, IWineD3DStateBlockImpl *stateblock) {
862     union {
863         DWORD                 d;
864         WINED3DLINEPATTERN    lp;
865     } tmppattern;
866     tmppattern.d = stateblock->renderState[WINED3DRS_LINEPATTERN];
867
868     TRACE("Line pattern: repeat %d bits %x\n", tmppattern.lp.wRepeatFactor, tmppattern.lp.wLinePattern);
869
870     if (tmppattern.lp.wRepeatFactor) {
871         glLineStipple(tmppattern.lp.wRepeatFactor, tmppattern.lp.wLinePattern);
872         checkGLcall("glLineStipple(repeat, linepattern)");
873         glEnable(GL_LINE_STIPPLE);
874         checkGLcall("glEnable(GL_LINE_STIPPLE);");
875     } else {
876         glDisable(GL_LINE_STIPPLE);
877         checkGLcall("glDisable(GL_LINE_STIPPLE);");
878     }
879 }
880
881 static void state_zbias(DWORD state, IWineD3DStateBlockImpl *stateblock) {
882     union {
883         DWORD d;
884         float f;
885     } tmpvalue;
886
887     if (stateblock->renderState[WINED3DRS_ZBIAS]) {
888         tmpvalue.d = stateblock->renderState[WINED3DRS_ZBIAS];
889         TRACE("ZBias value %f\n", tmpvalue.f);
890         glPolygonOffset(0, -tmpvalue.f);
891         checkGLcall("glPolygonOffset(0, -Value)");
892         glEnable(GL_POLYGON_OFFSET_FILL);
893         checkGLcall("glEnable(GL_POLYGON_OFFSET_FILL);");
894         glEnable(GL_POLYGON_OFFSET_LINE);
895         checkGLcall("glEnable(GL_POLYGON_OFFSET_LINE);");
896         glEnable(GL_POLYGON_OFFSET_POINT);
897         checkGLcall("glEnable(GL_POLYGON_OFFSET_POINT);");
898     } else {
899         glDisable(GL_POLYGON_OFFSET_FILL);
900         checkGLcall("glDisable(GL_POLYGON_OFFSET_FILL);");
901         glDisable(GL_POLYGON_OFFSET_LINE);
902         checkGLcall("glDisable(GL_POLYGON_OFFSET_LINE);");
903         glDisable(GL_POLYGON_OFFSET_POINT);
904         checkGLcall("glDisable(GL_POLYGON_OFFSET_POINT);");
905     }
906 }
907
908
909 static void state_normalize(DWORD state, IWineD3DStateBlockImpl *stateblock) {
910     if (stateblock->renderState[WINED3DRS_NORMALIZENORMALS]) {
911         glEnable(GL_NORMALIZE);
912         checkGLcall("glEnable(GL_NORMALIZE);");
913     } else {
914         glDisable(GL_NORMALIZE);
915         checkGLcall("glDisable(GL_NORMALIZE);");
916     }
917 }
918
919 static void state_psize(DWORD state, IWineD3DStateBlockImpl *stateblock) {
920     union {
921         DWORD d;
922         float f;
923     } tmpvalue;
924
925     /* FIXME: check that pointSize isn't outside glGetFloatv( GL_POINT_SIZE_MAX_ARB, &maxSize ); or -ve */
926     tmpvalue.d = stateblock->renderState[WINED3DRS_POINTSIZE];
927     TRACE("Set point size to %f\n", tmpvalue.f);
928     glPointSize(tmpvalue.f);
929     checkGLcall("glPointSize(...);");
930 }
931
932 static void state_psizemin(DWORD state, IWineD3DStateBlockImpl *stateblock) {
933     union {
934         DWORD d;
935         float f;
936     } tmpvalue;
937
938     tmpvalue.d = stateblock->renderState[WINED3DRS_POINTSIZE_MIN];
939     if(GL_SUPPORT(ARB_POINT_PARAMETERS)) {
940         GL_EXTCALL(glPointParameterfARB)(GL_POINT_SIZE_MIN_ARB, tmpvalue.f);
941         checkGLcall("glPointParameterfARB(...");
942     }
943     else if(GL_SUPPORT(EXT_POINT_PARAMETERS)) {
944         GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MIN_EXT, tmpvalue.f);
945         checkGLcall("glPointParameterfEXT(...);");
946     } else if(tmpvalue.f != 1.0) {
947         FIXME("WINED3DRS_POINTSIZE_MIN not supported on this opengl, value is %f\n", tmpvalue.f);
948     }
949 }
950
951 static void state_psizemax(DWORD state, IWineD3DStateBlockImpl *stateblock) {
952     union {
953         DWORD d;
954         float f;
955     } tmpvalue;
956
957     tmpvalue.d = stateblock->renderState[WINED3DRS_POINTSIZE_MAX];
958     if(GL_SUPPORT(ARB_POINT_PARAMETERS)) {
959         GL_EXTCALL(glPointParameterfARB)(GL_POINT_SIZE_MAX_ARB, tmpvalue.f);
960         checkGLcall("glPointParameterfARB(...");
961     }
962     else if(GL_SUPPORT(EXT_POINT_PARAMETERS)) {
963         GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MAX_EXT, tmpvalue.f);
964         checkGLcall("glPointParameterfEXT(...);");
965     } else if(tmpvalue.f != 64.0) {
966         FIXME("WINED3DRS_POINTSIZE_MAX not supported on this opengl, value is %f\n", tmpvalue.f);
967     }
968 }
969
970 static void state_pscale(DWORD state, IWineD3DStateBlockImpl *stateblock) {
971     /* TODO: Group this with the viewport */
972     /*
973      * POINTSCALEENABLE controls how point size value is treated. If set to
974      * true, the point size is scaled with respect to height of viewport.
975      * When set to false point size is in pixels.
976      *
977      * http://msdn.microsoft.com/library/en-us/directx9_c/point_sprites.asp
978      */
979
980     /* Default values */
981     GLfloat att[3] = {1.0f, 0.0f, 0.0f};
982
983     /*
984      * Minimum valid point size for OpenGL is 1.0f. For Direct3D it is 0.0f.
985      * This means that OpenGL will clamp really small point sizes to 1.0f.
986      * To correct for this we need to multiply by the scale factor when sizes
987      * are less than 1.0f. scale_factor =  1.0f / point_size.
988      */
989     GLfloat pointSize = *((float*)&stateblock->renderState[WINED3DRS_POINTSIZE]);
990     if(pointSize > 0.0f) {
991         GLfloat scaleFactor;
992
993         if(pointSize < 1.0f) {
994             scaleFactor = pointSize * pointSize;
995         } else {
996             scaleFactor = 1.0f;
997         }
998
999         if(stateblock->renderState[WINED3DRS_POINTSCALEENABLE]) {
1000             att[0] = *((float*)&stateblock->renderState[WINED3DRS_POINTSCALE_A]) /
1001                     (stateblock->viewport.Height * stateblock->viewport.Height * scaleFactor);
1002             att[1] = *((float*)&stateblock->renderState[WINED3DRS_POINTSCALE_B]) /
1003                     (stateblock->viewport.Height * stateblock->viewport.Height * scaleFactor);
1004             att[2] = *((float*)&stateblock->renderState[WINED3DRS_POINTSCALE_C]) /
1005                     (stateblock->viewport.Height * stateblock->viewport.Height * scaleFactor);
1006         }
1007     }
1008
1009     if(GL_SUPPORT(ARB_POINT_PARAMETERS)) {
1010         GL_EXTCALL(glPointParameterfvARB)(GL_POINT_DISTANCE_ATTENUATION_ARB, att);
1011         checkGLcall("glPointParameterfvARB(GL_DISTANCE_ATTENUATION_ARB, ...");
1012     }
1013     else if(GL_SUPPORT(EXT_POINT_PARAMETERS)) {
1014         GL_EXTCALL(glPointParameterfvEXT)(GL_DISTANCE_ATTENUATION_EXT, att);
1015         checkGLcall("glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, ...");
1016     } else {
1017         TRACE("POINT_PARAMETERS not supported in this version of opengl\n");
1018     }
1019 }
1020
1021 static void state_colorwrite(DWORD state, IWineD3DStateBlockImpl *stateblock) {
1022     DWORD Value = stateblock->renderState[WINED3DRS_COLORWRITEENABLE];
1023
1024     TRACE("Color mask: r(%d) g(%d) b(%d) a(%d)\n",
1025         Value & D3DCOLORWRITEENABLE_RED   ? 1 : 0,
1026         Value & D3DCOLORWRITEENABLE_GREEN ? 1 : 0,
1027         Value & D3DCOLORWRITEENABLE_BLUE  ? 1 : 0,
1028         Value & D3DCOLORWRITEENABLE_ALPHA ? 1 : 0);
1029     glColorMask(Value & D3DCOLORWRITEENABLE_RED   ? GL_TRUE : GL_FALSE,
1030                 Value & D3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE,
1031                 Value & D3DCOLORWRITEENABLE_BLUE  ? GL_TRUE : GL_FALSE,
1032                 Value & D3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE);
1033     checkGLcall("glColorMask(...)");
1034
1035     /* depends on WINED3DRS_COLORWRITEENABLE. */
1036     if(stateblock->renderState[WINED3DRS_COLORWRITEENABLE1] != 0x0000000F ||
1037        stateblock->renderState[WINED3DRS_COLORWRITEENABLE2] != 0x0000000F ||
1038        stateblock->renderState[WINED3DRS_COLORWRITEENABLE3] != 0x0000000F ) {
1039         ERR("(WINED3DRS_COLORWRITEENABLE1/2/3,%d,%d,%d) not yet implemented. Missing of cap D3DPMISCCAPS_INDEPENDENTWRITEMASKS wasn't honored?\n",
1040             stateblock->renderState[WINED3DRS_COLORWRITEENABLE1],
1041             stateblock->renderState[WINED3DRS_COLORWRITEENABLE2],
1042             stateblock->renderState[WINED3DRS_COLORWRITEENABLE3]);
1043     }
1044 }
1045
1046 static void state_localviewer(DWORD state, IWineD3DStateBlockImpl *stateblock) {
1047     if(stateblock->renderState[WINED3DRS_LOCALVIEWER]) {
1048         glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
1049         checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1)");
1050     } else {
1051         glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0);
1052         checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0)");
1053     }
1054 }
1055
1056 static void state_lastpixel(DWORD state, IWineD3DStateBlockImpl *stateblock) {
1057     if(stateblock->renderState[WINED3DRS_LASTPIXEL]) {
1058         TRACE("Last Pixel Drawing Enabled\n");
1059     } else {
1060         FIXME("Last Pixel Drawing Disabled, not handled yet\n");
1061     }
1062 }
1063
1064 static void state_pointsprite(DWORD state, IWineD3DStateBlockImpl *stateblock) {
1065     unsigned int i;
1066     int val;
1067
1068     /* TODO: NV_POINT_SPRITE */
1069     if (!GL_SUPPORT(ARB_POINT_SPRITE)) {
1070         TRACE("Point sprites not supported\n");
1071         return;
1072     }
1073
1074     if (stateblock->renderState[WINED3DRS_POINTSPRITEENABLE]) {
1075         val = GL_TRUE;
1076     } else {
1077         val = GL_FALSE;
1078     }
1079
1080     for (i = 0; i < GL_LIMITS(texture_stages); i++) {
1081         /* Note the WINED3DRS value applies to all textures, but GL has one
1082          * per texture, so apply it now ready to be used!
1083          */
1084         if (GL_SUPPORT(ARB_MULTITEXTURE)) {
1085             GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + i));
1086             checkGLcall("glActiveTextureARB");
1087         } else if (i==1) {
1088             FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
1089             break;
1090         }
1091
1092         glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, val);
1093         checkGLcall((val?"glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE)":
1094                          "glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_FALSE)"));
1095     }
1096 }
1097
1098 static void state_wrap(DWORD state, IWineD3DStateBlockImpl *stateblock) {
1099     /**
1100      http://www.cosc.brocku.ca/Offerings/3P98/course/lectures/texture/
1101      http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/directx9_c/directx/graphics/programmingguide/FixedFunction/Textures/texturewrapping.asp
1102      http://www.gamedev.net/reference/programming/features/rendererdll3/page2.asp
1103      Descussion that ways to turn on WRAPing to solve an opengl conversion problem.
1104      http://www.flipcode.org/cgi-bin/fcmsg.cgi?thread_show=10248
1105
1106      so far as I can tell, wrapping and texture-coordinate generate go hand in hand,
1107      */
1108     TRACE("Stub\n");
1109     if(stateblock->renderState[WINED3DRS_WRAP0] ||
1110        stateblock->renderState[WINED3DRS_WRAP1] ||
1111        stateblock->renderState[WINED3DRS_WRAP2] ||
1112        stateblock->renderState[WINED3DRS_WRAP3] ||
1113        stateblock->renderState[WINED3DRS_WRAP4] ||
1114        stateblock->renderState[WINED3DRS_WRAP5] ||
1115        stateblock->renderState[WINED3DRS_WRAP6] ||
1116        stateblock->renderState[WINED3DRS_WRAP7] ||
1117        stateblock->renderState[WINED3DRS_WRAP8] ||
1118        stateblock->renderState[WINED3DRS_WRAP9] ||
1119        stateblock->renderState[WINED3DRS_WRAP10] ||
1120        stateblock->renderState[WINED3DRS_WRAP11] ||
1121        stateblock->renderState[WINED3DRS_WRAP12] ||
1122        stateblock->renderState[WINED3DRS_WRAP13] ||
1123        stateblock->renderState[WINED3DRS_WRAP14] ||
1124        stateblock->renderState[WINED3DRS_WRAP15] ) {
1125         ERR("(WINED3DRS_WRAP0) Texture wraping not yet supported\n");
1126     }
1127 }
1128
1129 static void state_multisampleaa(DWORD state, IWineD3DStateBlockImpl *stateblock) {
1130     if( GL_SUPPORT(ARB_MULTISAMPLE) ) {
1131         if(stateblock->renderState[WINED3DRS_MULTISAMPLEANTIALIAS]) {
1132             glEnable(GL_MULTISAMPLE_ARB);
1133             checkGLcall("glEnable(GL_MULTISAMPLE_ARB)");
1134         } else {
1135             glDisable(GL_MULTISAMPLE_ARB);
1136             checkGLcall("glDisable(GL_MULTISAMPLE_ARB)");
1137         }
1138     } else {
1139         if(stateblock->renderState[WINED3DRS_MULTISAMPLEANTIALIAS]) {
1140             ERR("Multisample antialiasing not supported by gl\n");
1141         }
1142     }
1143 }
1144
1145 static void state_scissor(DWORD state, IWineD3DStateBlockImpl *stateblock) {
1146     if(stateblock->renderState[WINED3DRS_SCISSORTESTENABLE]) {
1147         glEnable(GL_SCISSOR_TEST);
1148         checkGLcall("glEnable(GL_SCISSOR_TEST)");
1149     } else {
1150         glDisable(GL_SCISSOR_TEST);
1151         checkGLcall("glDisable(GL_SCISSOR_TEST)");
1152     }
1153 }
1154
1155 static void state_depthbias(DWORD state, IWineD3DStateBlockImpl *stateblock) {
1156     union {
1157         DWORD d;
1158         float f;
1159     } tmpvalue;
1160
1161     if(stateblock->renderState[WINED3DRS_SLOPESCALEDEPTHBIAS] ||
1162        stateblock->renderState[WINED3DRS_DEPTHBIAS]) {
1163         tmpvalue.d = stateblock->renderState[WINED3DRS_SLOPESCALEDEPTHBIAS];
1164         glEnable(GL_POLYGON_OFFSET_FILL);
1165         checkGLcall("glEnable(GL_POLYGON_OFFSET_FILL)");
1166         glPolygonOffset(tmpvalue.f, *((float*)&stateblock->renderState[WINED3DRS_DEPTHBIAS]));
1167         checkGLcall("glPolygonOffset(...)");
1168     } else {
1169         glDisable(GL_POLYGON_OFFSET_FILL);
1170         checkGLcall("glDisable(GL_POLYGON_OFFSET_FILL)");
1171     }
1172 }
1173
1174 static void state_perspective(DWORD state, IWineD3DStateBlockImpl *stateblock) {
1175     if (stateblock->renderState[WINED3DRS_TEXTUREPERSPECTIVE]) {
1176         glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1177         checkGLcall("glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)");
1178     } else {
1179         glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
1180         checkGLcall("glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST)");
1181     }
1182 }
1183
1184 static void state_stippledalpha(DWORD state, IWineD3DStateBlockImpl *stateblock) {
1185     TRACE("Stub\n");
1186     if (stateblock->renderState[WINED3DRS_STIPPLEDALPHA])
1187         ERR(" Stippled Alpha not supported yet.\n");
1188 }
1189
1190 static void state_antialias(DWORD state, IWineD3DStateBlockImpl *stateblock) {
1191     TRACE("Stub\n");
1192     if (stateblock->renderState[WINED3DRS_ANTIALIAS])
1193         ERR(" Antialias not supported yet.\n");
1194 }
1195
1196 static void state_multisampmask(DWORD state, IWineD3DStateBlockImpl *stateblock) {
1197     TRACE("Stub\n");
1198     if (stateblock->renderState[WINED3DRS_MULTISAMPLEMASK] != 0xFFFFFFFF)
1199         ERR("(WINED3DRS_MULTISAMPLEMASK,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_MULTISAMPLEMASK]);
1200 }
1201
1202 static void state_patchedgestyle(DWORD state, IWineD3DStateBlockImpl *stateblock) {
1203     TRACE("Stub\n");
1204     if (stateblock->renderState[WINED3DRS_PATCHEDGESTYLE] != D3DPATCHEDGE_DISCRETE)
1205         ERR("(WINED3DRS_PATCHEDGESTYLE,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_PATCHEDGESTYLE]);
1206 }
1207
1208 static void state_patchsegments(DWORD state, IWineD3DStateBlockImpl *stateblock) {
1209     union {
1210         DWORD d;
1211         float f;
1212     } tmpvalue;
1213     tmpvalue.f = 1.0f;
1214
1215     TRACE("Stub\n");
1216     if (stateblock->renderState[WINED3DRS_PATCHSEGMENTS] != tmpvalue.d)
1217         ERR("(WINED3DRS_PATCHSEGMENTS,%d) not yet implemented\n", tmpvalue.d);
1218 }
1219
1220 static void state_positiondegree(DWORD state, IWineD3DStateBlockImpl *stateblock) {
1221     TRACE("Stub\n");
1222     if (stateblock->renderState[WINED3DRS_POSITIONDEGREE] != D3DDEGREE_CUBIC)
1223         ERR("(WINED3DRS_POSITIONDEGREE,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_POSITIONDEGREE]);
1224 }
1225
1226 static void state_normaldegree(DWORD state, IWineD3DStateBlockImpl *stateblock) {
1227     TRACE("Stub\n");
1228     if (stateblock->renderState[WINED3DRS_NORMALDEGREE] != D3DDEGREE_LINEAR)
1229         ERR("(WINED3DRS_NORMALDEGREE,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_NORMALDEGREE]);
1230 }
1231
1232 static void state_tessellation(DWORD state, IWineD3DStateBlockImpl *stateblock) {
1233     TRACE("Stub\n");
1234     if(stateblock->renderState[WINED3DRS_ENABLEADAPTIVETESSELLATION])
1235         FIXME("(WINED3DRS_ENABLEADAPTIVETESSELLATION,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_ENABLEADAPTIVETESSELLATION]);
1236 }
1237
1238
1239 static void state_srgbwrite(DWORD state, IWineD3DStateBlockImpl *stateblock) {
1240     if(stateblock->renderState[WINED3DRS_SRGBWRITEENABLE])
1241         ERR("Render state WINED3DRS_SRGBWRITEENABLE not yet implemented\n");
1242 }
1243
1244 static void state_seperateblend(DWORD state, IWineD3DStateBlockImpl *stateblock) {
1245     TRACE("Stub\n");
1246     if(stateblock->renderState[WINED3DRS_SEPARATEALPHABLENDENABLE])
1247         FIXME("(WINED3DRS_SEPARATEALPHABLENDENABLE,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_SEPARATEALPHABLENDENABLE]);
1248 }
1249
1250 static void state_wrapu(DWORD state, IWineD3DStateBlockImpl *stateblock) {
1251     if(stateblock->renderState[WINED3DRS_WRAPU]) {
1252         FIXME("Render state WINED3DRS_WRAPU not implemented yet\n");
1253     }
1254 }
1255
1256 static void state_wrapv(DWORD state, IWineD3DStateBlockImpl *stateblock) {
1257     if(stateblock->renderState[WINED3DRS_WRAPV]) {
1258         FIXME("Render state WINED3DRS_WRAPV not implemented yet\n");
1259     }
1260 }
1261
1262 static void state_monoenable(DWORD state, IWineD3DStateBlockImpl *stateblock) {
1263     if(stateblock->renderState[WINED3DRS_MONOENABLE]) {
1264         FIXME("Render state WINED3DRS_MONOENABLE not implemented yet\n");
1265     }
1266 }
1267
1268 static void state_rop2(DWORD state, IWineD3DStateBlockImpl *stateblock) {
1269     if(stateblock->renderState[WINED3DRS_ROP2]) {
1270         FIXME("Render state WINED3DRS_ROP2 not implemented yet\n");
1271     }
1272 }
1273
1274 static void state_planemask(DWORD state, IWineD3DStateBlockImpl *stateblock) {
1275     if(stateblock->renderState[WINED3DRS_PLANEMASK]) {
1276         FIXME("Render state WINED3DRS_PLANEMASK not implemented yet\n");
1277     }
1278 }
1279
1280 static void state_subpixel(DWORD state, IWineD3DStateBlockImpl *stateblock) {
1281     if(stateblock->renderState[WINED3DRS_SUBPIXEL]) {
1282         FIXME("Render state WINED3DRS_SUBPIXEL not implemented yet\n");
1283     }
1284 }
1285
1286 static void state_subpixelx(DWORD state, IWineD3DStateBlockImpl *stateblock) {
1287     if(stateblock->renderState[WINED3DRS_SUBPIXELX]) {
1288         FIXME("Render state WINED3DRS_SUBPIXELX not implemented yet\n");
1289     }
1290 }
1291
1292 static void state_stippleenable(DWORD state, IWineD3DStateBlockImpl *stateblock) {
1293     if(stateblock->renderState[WINED3DRS_STIPPLEENABLE]) {
1294         FIXME("Render state WINED3DRS_STIPPLEENABLE not implemented yet\n");
1295     }
1296 }
1297
1298 static void state_bordercolor(DWORD state, IWineD3DStateBlockImpl *stateblock) {
1299     if(stateblock->renderState[WINED3DRS_BORDERCOLOR]) {
1300         FIXME("Render state WINED3DRS_BORDERCOLOR not implemented yet\n");
1301     }
1302 }
1303
1304 static void state_mipmaplodbias(DWORD state, IWineD3DStateBlockImpl *stateblock) {
1305     if(stateblock->renderState[WINED3DRS_MIPMAPLODBIAS]) {
1306         FIXME("Render state WINED3DRS_MIPMAPLODBIAS not implemented yet\n");
1307     }
1308 }
1309
1310 static void state_anisotropy(DWORD state, IWineD3DStateBlockImpl *stateblock) {
1311     if(stateblock->renderState[WINED3DRS_ANISOTROPY]) {
1312         FIXME("Render state WINED3DRS_ANISOTROPY not implemented yet\n");
1313     }
1314 }
1315
1316 static void state_flushbatch(DWORD state, IWineD3DStateBlockImpl *stateblock) {
1317     if(stateblock->renderState[WINED3DRS_FLUSHBATCH]) {
1318         FIXME("Render state WINED3DRS_FLUSHBATCH not implemented yet\n");
1319     }
1320 }
1321
1322 static void state_translucentsi(DWORD state, IWineD3DStateBlockImpl *stateblock) {
1323     if(stateblock->renderState[WINED3DRS_TRANSLUCENTSORTINDEPENDENT]) {
1324         FIXME("Render state WINED3DRS_TRANSLUCENTSORTINDEPENDENT not implemented yet\n");
1325     }
1326 }
1327
1328 static void state_extents(DWORD state, IWineD3DStateBlockImpl *stateblock) {
1329     if(stateblock->renderState[WINED3DRS_EXTENTS]) {
1330         FIXME("Render state WINED3DRS_EXTENTS not implemented yet\n");
1331     }
1332 }
1333
1334 static void state_ckeyblend(DWORD state, IWineD3DStateBlockImpl *stateblock) {
1335     if(stateblock->renderState[WINED3DRS_COLORKEYBLENDENABLE]) {
1336         FIXME("Render state WINED3DRS_COLORKEYBLENDENABLE not implemented yet\n");
1337     }
1338 }
1339
1340 /* Activates the texture dimension according to the bound D3D texture.
1341  * Does not care for the colorop or correct gl texture unit(when using nvrc)
1342  * Requires the caller to activate the correct unit before
1343  */
1344 static void activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock) {
1345     if(stateblock->textures[stage]) {
1346         glDisable(GL_TEXTURE_1D);
1347         checkGLcall("glDisable(GL_TEXTURE_1D)");
1348         switch(stateblock->textureDimensions[stage]) {
1349             case GL_TEXTURE_2D:
1350                 glDisable(GL_TEXTURE_3D);
1351                 checkGLcall("glDisable(GL_TEXTURE_3D)");
1352                 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
1353                 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
1354                 glEnable(GL_TEXTURE_2D);
1355                 checkGLcall("glEnable(GL_TEXTURE_2D)");
1356                 break;
1357             case GL_TEXTURE_3D:
1358                 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
1359                 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
1360                 glDisable(GL_TEXTURE_2D);
1361                 checkGLcall("glDisable(GL_TEXTURE_2D)");
1362                 glEnable(GL_TEXTURE_3D);
1363                 checkGLcall("glEnable(GL_TEXTURE_3D)");
1364                 break;
1365             case GL_TEXTURE_CUBE_MAP_ARB:
1366                 glDisable(GL_TEXTURE_2D);
1367                 checkGLcall("glDisable(GL_TEXTURE_2D)");
1368                 glDisable(GL_TEXTURE_3D);
1369                 checkGLcall("glDisable(GL_TEXTURE_3D)");
1370                 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
1371                 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
1372                 break;
1373         }
1374     } else {
1375         glDisable(GL_TEXTURE_2D);
1376         checkGLcall("glDisable(GL_TEXTURE_2D)");
1377         glDisable(GL_TEXTURE_3D);
1378         checkGLcall("glDisable(GL_TEXTURE_3D)");
1379         glDisable(GL_TEXTURE_CUBE_MAP_ARB);
1380         checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
1381         glEnable(GL_TEXTURE_1D);
1382         checkGLcall("glEnable(GL_TEXTURE_1D)");
1383         /* Binding textures is done by samplers. A dummy texture will be bound */
1384     }
1385 }
1386
1387 static void tex_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock) {
1388     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
1389     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage];
1390
1391     TRACE("Setting color op for stage %d\n", stage);
1392
1393     if (stateblock->pixelShader && stateblock->wineD3DDevice->ps_selected_mode != SHADER_NONE &&
1394         ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.function) {
1395         /* Using a pixel shader? Don't care for anything here, the shader applying does it */
1396         return;
1397     }
1398
1399     if (stage != mapped_stage) WARN("Using non 1:1 mapping: %d -> %d!\n", stage, mapped_stage);
1400
1401     if (mapped_stage != -1) {
1402         if (GL_SUPPORT(ARB_MULTITEXTURE)) {
1403             if (mapped_stage >= GL_LIMITS(sampler_stages)) {
1404                 if (stateblock->textureState[stage][WINED3DTSS_COLOROP] != WINED3DTOP_DISABLE &&
1405                         stateblock->textureState[stage][WINED3DTSS_COLOROP] != 0) {
1406                     FIXME("Attempt to enable unsupported stage!\n");
1407                 }
1408                 return;
1409             }
1410             GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
1411             checkGLcall("glActiveTextureARB");
1412         } else if (stage > 0) {
1413             WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
1414             return;
1415         }
1416     }
1417
1418     if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
1419         if(stateblock->lowest_disabled_stage > 0) {
1420             glEnable(GL_REGISTER_COMBINERS_NV);
1421             GL_EXTCALL(glCombinerParameteriNV(GL_NUM_GENERAL_COMBINERS_NV, stateblock->lowest_disabled_stage));
1422         } else {
1423             glDisable(GL_REGISTER_COMBINERS_NV);
1424         }
1425     }
1426     if(stage >= stateblock->lowest_disabled_stage) {
1427         TRACE("Stage disabled\n");
1428         if (mapped_stage != -1) {
1429             /* Disable everything here */
1430             glDisable(GL_TEXTURE_1D);
1431             checkGLcall("glDisable(GL_TEXTURE_1D)");
1432             glDisable(GL_TEXTURE_2D);
1433             checkGLcall("glDisable(GL_TEXTURE_2D)");
1434             glDisable(GL_TEXTURE_3D);
1435             checkGLcall("glDisable(GL_TEXTURE_3D)");
1436             glDisable(GL_TEXTURE_CUBE_MAP_ARB);
1437             checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
1438         }
1439         /* All done */
1440         return;
1441     }
1442
1443     if (mapped_stage != -1) activate_dimensions(stage, stateblock);
1444
1445     /* Set the texture combiners */
1446     if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
1447         set_tex_op_nvrc((IWineD3DDevice *)stateblock->wineD3DDevice, FALSE, stage,
1448                          stateblock->textureState[stage][WINED3DTSS_COLOROP],
1449                          stateblock->textureState[stage][WINED3DTSS_COLORARG1],
1450                          stateblock->textureState[stage][WINED3DTSS_COLORARG2],
1451                          stateblock->textureState[stage][WINED3DTSS_COLORARG0],
1452                          mapped_stage);
1453     } else {
1454         set_tex_op((IWineD3DDevice *)stateblock->wineD3DDevice, FALSE, stage,
1455                     stateblock->textureState[stage][WINED3DTSS_COLOROP],
1456                     stateblock->textureState[stage][WINED3DTSS_COLORARG1],
1457                     stateblock->textureState[stage][WINED3DTSS_COLORARG2],
1458                     stateblock->textureState[stage][WINED3DTSS_COLORARG0]);
1459     }
1460 }
1461
1462 static void tex_alphaop(DWORD state, IWineD3DStateBlockImpl *stateblock) {
1463     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
1464     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage];
1465
1466     TRACE("Setting alpha op for stage %d\n", stage);
1467     /* Do not care for enabled / disabled stages, just assign the settigns. colorop disables / enables required stuff */
1468     if (mapped_stage != -1) {
1469         if (GL_SUPPORT(ARB_MULTITEXTURE)) {
1470             if (stage >= GL_LIMITS(sampler_stages)) {
1471                 if (stateblock->textureState[stage][WINED3DTSS_COLOROP] != WINED3DTOP_DISABLE &&
1472                         stateblock->textureState[stage][WINED3DTSS_COLOROP] != 0) {
1473                     FIXME("Attempt to enable unsupported stage!\n");
1474                 }
1475                 return;
1476             }
1477             GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
1478             checkGLcall("glActiveTextureARB");
1479         } else if (stage > 0) {
1480             /* We can't do anything here */
1481             WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
1482             return;
1483         }
1484     }
1485
1486     TRACE("Setting alpha op for stage %d\n", stage);
1487     if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
1488         set_tex_op_nvrc((IWineD3DDevice *)stateblock->wineD3DDevice, TRUE, stage,
1489                          stateblock->textureState[stage][WINED3DTSS_ALPHAOP],
1490                          stateblock->textureState[stage][WINED3DTSS_ALPHAARG1],
1491                          stateblock->textureState[stage][WINED3DTSS_ALPHAARG2],
1492                          stateblock->textureState[stage][WINED3DTSS_ALPHAARG0],
1493                          mapped_stage);
1494     } else {
1495         set_tex_op((IWineD3DDevice *)stateblock->wineD3DDevice, TRUE, stage, stateblock->textureState[stage][WINED3DTSS_ALPHAOP],
1496                     stateblock->textureState[stage][WINED3DTSS_ALPHAARG1],
1497                     stateblock->textureState[stage][WINED3DTSS_ALPHAARG2],
1498                     stateblock->textureState[stage][WINED3DTSS_ALPHAARG0]);
1499     }
1500 }
1501
1502 static void transform_texture(DWORD state, IWineD3DStateBlockImpl *stateblock) {
1503     DWORD texUnit = state - STATE_TRANSFORM(WINED3DTS_TEXTURE0);
1504
1505     if (GL_SUPPORT(ARB_MULTITEXTURE)) {
1506         if(texUnit >= GL_LIMITS(sampler_stages)) {
1507             return;
1508         }
1509         GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + stateblock->wineD3DDevice->texUnitMap[texUnit]));
1510         checkGLcall("glActiveTextureARB");
1511     } else if (texUnit > 0) {
1512         /* We can't do anything here */
1513         WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
1514         return;
1515     }
1516
1517     set_texture_matrix((float *)&stateblock->transforms[WINED3DTS_TEXTURE0 + texUnit].u.m[0][0],
1518                         stateblock->textureState[texUnit][WINED3DTSS_TEXTURETRANSFORMFLAGS],
1519                         (stateblock->textureState[texUnit][WINED3DTSS_TEXCOORDINDEX] & 0xFFFF0000) != WINED3DTSS_TCI_PASSTHRU);
1520
1521 }
1522
1523 static void loadVertexData(IWineD3DStateBlockImpl *stateblock, WineDirect3DVertexStridedData *sd);
1524
1525 static void tex_coordindex(DWORD state, IWineD3DStateBlockImpl *stateblock) {
1526     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
1527     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage];
1528
1529     if (mapped_stage == -1) {
1530         TRACE("No texture unit mapped to stage %d. Skipping texture coordinates.\n", stage);
1531         return;
1532     }
1533
1534     if (GL_SUPPORT(ARB_MULTITEXTURE)) {
1535         if(stage >= GL_LIMITS(sampler_stages)) {
1536             return;
1537         }
1538         GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
1539         checkGLcall("glActiveTextureARB");
1540     } else if (stage > 0) {
1541         /* We can't do anything here */
1542         WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
1543         return;
1544     }
1545
1546     /* Values 0-7 are indexes into the FVF tex coords - See comments in DrawPrimitive
1547      *
1548      * FIXME: From MSDN: The WINED3DTSS_TCI_* flags are mutually exclusive. If you include
1549      * one flag, you can still specify an index value, which the system uses to
1550      * determine the texture wrapping mode.
1551      * eg. SetTextureStageState( 0, WINED3DTSS_TEXCOORDINDEX, WINED3DTSS_TCI_CAMERASPACEPOSITION | 1 );
1552      * means use the vertex position (camera-space) as the input texture coordinates
1553      * for this texture stage, and the wrap mode set in the WINED3DRS_WRAP1 render
1554      * state. We do not (yet) support the WINED3DRENDERSTATE_WRAPx values, nor tie them up
1555      * to the TEXCOORDINDEX value
1556      */
1557
1558     /*
1559      * Be careful the value of the mask 0xF0000 come from d3d8types.h infos
1560      */
1561     switch (stateblock->textureState[stage][WINED3DTSS_TEXCOORDINDEX] & 0xFFFF0000) {
1562     case WINED3DTSS_TCI_PASSTHRU:
1563         /*Use the specified texture coordinates contained within the vertex format. This value resolves to zero.*/
1564         glDisable(GL_TEXTURE_GEN_S);
1565         glDisable(GL_TEXTURE_GEN_T);
1566         glDisable(GL_TEXTURE_GEN_R);
1567         glDisable(GL_TEXTURE_GEN_Q);
1568         checkGLcall("glDisable(GL_TEXTURE_GEN_S,T,R,Q)");
1569         break;
1570
1571     case WINED3DTSS_TCI_CAMERASPACEPOSITION:
1572         /* CameraSpacePosition means use the vertex position, transformed to camera space,
1573          * as the input texture coordinates for this stage's texture transformation. This
1574          * equates roughly to EYE_LINEAR
1575          */
1576         {
1577             float s_plane[] = { 1.0, 0.0, 0.0, 0.0 };
1578             float t_plane[] = { 0.0, 1.0, 0.0, 0.0 };
1579             float r_plane[] = { 0.0, 0.0, 1.0, 0.0 };
1580             float q_plane[] = { 0.0, 0.0, 0.0, 1.0 };
1581             TRACE("WINED3DTSS_TCI_CAMERASPACEPOSITION - Set eye plane\n");
1582
1583             glMatrixMode(GL_MODELVIEW);
1584             glPushMatrix();
1585             glLoadIdentity();
1586             glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
1587             glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
1588             glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
1589             glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
1590             glPopMatrix();
1591
1592             TRACE("WINED3DTSS_TCI_CAMERASPACEPOSITION - Set GL_TEXTURE_GEN_x and GL_x, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR\n");
1593             glEnable(GL_TEXTURE_GEN_S);
1594             checkGLcall("glEnable(GL_TEXTURE_GEN_S);");
1595             glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
1596             checkGLcall("glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)");
1597             glEnable(GL_TEXTURE_GEN_T);
1598             checkGLcall("glEnable(GL_TEXTURE_GEN_T);");
1599             glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
1600             checkGLcall("glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)");
1601             glEnable(GL_TEXTURE_GEN_R);
1602             checkGLcall("glEnable(GL_TEXTURE_GEN_R);");
1603             glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
1604             checkGLcall("glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)");
1605         }
1606         break;
1607
1608     case WINED3DTSS_TCI_CAMERASPACENORMAL:
1609         {
1610             if (GL_SUPPORT(NV_TEXGEN_REFLECTION)) {
1611                 float s_plane[] = { 1.0, 0.0, 0.0, 0.0 };
1612                 float t_plane[] = { 0.0, 1.0, 0.0, 0.0 };
1613                 float r_plane[] = { 0.0, 0.0, 1.0, 0.0 };
1614                 float q_plane[] = { 0.0, 0.0, 0.0, 1.0 };
1615                 TRACE("WINED3DTSS_TCI_CAMERASPACENORMAL - Set eye plane\n");
1616
1617                 glMatrixMode(GL_MODELVIEW);
1618                 glPushMatrix();
1619                 glLoadIdentity();
1620                 glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
1621                 glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
1622                 glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
1623                 glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
1624                 glPopMatrix();
1625
1626                 glEnable(GL_TEXTURE_GEN_S);
1627                 checkGLcall("glEnable(GL_TEXTURE_GEN_S);");
1628                 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
1629                 checkGLcall("glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV)");
1630                 glEnable(GL_TEXTURE_GEN_T);
1631                 checkGLcall("glEnable(GL_TEXTURE_GEN_T);");
1632                 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
1633                 checkGLcall("glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV)");
1634                 glEnable(GL_TEXTURE_GEN_R);
1635                 checkGLcall("glEnable(GL_TEXTURE_GEN_R);");
1636                 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
1637                 checkGLcall("glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV)");
1638             }
1639         }
1640         break;
1641
1642     case WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR:
1643         {
1644             if (GL_SUPPORT(NV_TEXGEN_REFLECTION)) {
1645             float s_plane[] = { 1.0, 0.0, 0.0, 0.0 };
1646             float t_plane[] = { 0.0, 1.0, 0.0, 0.0 };
1647             float r_plane[] = { 0.0, 0.0, 1.0, 0.0 };
1648             float q_plane[] = { 0.0, 0.0, 0.0, 1.0 };
1649             TRACE("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Set eye plane\n");
1650
1651             glMatrixMode(GL_MODELVIEW);
1652             glPushMatrix();
1653             glLoadIdentity();
1654             glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
1655             glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
1656             glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
1657             glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
1658             glPopMatrix();
1659
1660             glEnable(GL_TEXTURE_GEN_S);
1661             checkGLcall("glEnable(GL_TEXTURE_GEN_S);");
1662             glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
1663             checkGLcall("glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV)");
1664             glEnable(GL_TEXTURE_GEN_T);
1665             checkGLcall("glEnable(GL_TEXTURE_GEN_T);");
1666             glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
1667             checkGLcall("glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV)");
1668             glEnable(GL_TEXTURE_GEN_R);
1669             checkGLcall("glEnable(GL_TEXTURE_GEN_R);");
1670             glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
1671             checkGLcall("glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV)");
1672             }
1673         }
1674         break;
1675
1676     /* Unhandled types: */
1677     default:
1678         /* Todo: */
1679         /* ? disable GL_TEXTURE_GEN_n ? */
1680         glDisable(GL_TEXTURE_GEN_S);
1681         glDisable(GL_TEXTURE_GEN_T);
1682         glDisable(GL_TEXTURE_GEN_R);
1683         glDisable(GL_TEXTURE_GEN_Q);
1684         FIXME("Unhandled WINED3DTSS_TEXCOORDINDEX %x\n", stateblock->textureState[stage][WINED3DTSS_TEXCOORDINDEX]);
1685         break;
1686     }
1687
1688     /* Update the texture matrix */
1689     if(!isStateDirty(stateblock->wineD3DDevice, STATE_TRANSFORM(WINED3DTS_TEXTURE0 + stage))) {
1690         transform_texture(STATE_TRANSFORM(WINED3DTS_TEXTURE0 + stage), stateblock);
1691     }
1692
1693     if(!isStateDirty(stateblock->wineD3DDevice, STATE_VDECL) && stateblock->wineD3DDevice->namedArraysLoaded) {
1694         /* Reload the arrays if we are using fixed function arrays to reflect the selected coord input
1695          * source. Call loadVertexData directly because there is no need to reparse the vertex declaration
1696          * and do all the things linked to it
1697          * TODO: Tidy that up to reload only the arrays of the changed unit
1698          */
1699         loadVertexData(stateblock, &stateblock->wineD3DDevice->strided_streams);
1700     }
1701 }
1702
1703 static void tex_bumpenvlscale(DWORD state, IWineD3DStateBlockImpl *stateblock) {
1704     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
1705     union {
1706         DWORD d;
1707         float f;
1708     } tmpvalue;
1709
1710     tmpvalue.d = stateblock->textureState[stage][WINED3DTSS_BUMPENVLSCALE];
1711     if(tmpvalue.f != 0.0) {
1712         ERR("WINED3DTSS_BUMPENVLSCALE not supported yet\n");
1713     }
1714 }
1715
1716 static void tex_bumpenvloffset(DWORD state, IWineD3DStateBlockImpl *stateblock) {
1717     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
1718     union {
1719         DWORD d;
1720         float f;
1721     } tmpvalue;
1722
1723     tmpvalue.d = stateblock->textureState[stage][WINED3DTSS_BUMPENVLOFFSET];
1724     if(tmpvalue.f != 0.0) {
1725         ERR("WINED3DTSS_BUMPENVLOFFSET not supported yet\n");
1726     }
1727 }
1728
1729 static void tex_resultarg(DWORD state, IWineD3DStateBlockImpl *stateblock) {
1730     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
1731
1732     if(stage >= GL_LIMITS(texture_stages)) {
1733         return;
1734     }
1735
1736     if(stateblock->textureState[stage][WINED3DTSS_RESULTARG] != D3DTA_CURRENT) {
1737         ERR("WINED3DTSS_RESULTARG not supported yet\n");
1738     }
1739 }
1740
1741 static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock) {
1742     DWORD sampler = state - STATE_SAMPLER(0);
1743     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[sampler];
1744     union {
1745         float f;
1746         DWORD d;
1747     } tmpvalue;
1748
1749     TRACE("Sampler: %d\n", sampler);
1750     /* Enabling and disabling texture dimensions is done by texture stage state / pixel shader setup, this function
1751      * only has to bind textures and set the per texture states
1752      */
1753
1754     if (mapped_stage == -1) {
1755         TRACE("No sampler mapped to stage %d. Returning.\n", sampler);
1756         return;
1757     }
1758
1759     if (GL_SUPPORT(ARB_MULTITEXTURE)) {
1760         if(sampler >= GL_LIMITS(sampler_stages)) {
1761             return;
1762         }
1763         GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
1764         checkGLcall("glActiveTextureARB");
1765     } else if (sampler > 0) {
1766         /* We can't do anything here */
1767         WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
1768         return;
1769     }
1770
1771     if(stateblock->textures[sampler]) {
1772         BOOL texIsPow2 = FALSE;
1773
1774         /* The fixed function np2 texture emulation uses the texture matrix to fix up the coordinates
1775          * IWineD3DBaseTexture::ApplyStateChanges multiplies the set matrix with a fixup matrix. Before the
1776          * scaling is reapplied or removed, the texture matrix has to be reapplied
1777          */
1778         if(wined3d_settings.nonpower2_mode != NP2_NATIVE && sampler < MAX_TEXTURES) {
1779             if(stateblock->textureDimensions[sampler] == GL_TEXTURE_2D) {
1780                 if(((IWineD3DTextureImpl *) stateblock->textures[sampler])->pow2scalingFactorX != 1.0 ||
1781                    ((IWineD3DTextureImpl *) stateblock->textures[sampler])->pow2scalingFactorY != 1.0 ) {
1782                     texIsPow2 = TRUE;
1783                 }
1784             } else if(stateblock->textureDimensions[sampler] == GL_TEXTURE_CUBE_MAP_ARB) {
1785                 if(((IWineD3DCubeTextureImpl *) stateblock->textures[sampler])->pow2scalingFactor != 1.0) {
1786                     texIsPow2 = TRUE;
1787                 }
1788             }
1789
1790             if(texIsPow2 || stateblock->wineD3DDevice->lastWasPow2Texture[sampler]) {
1791                 transform_texture(STATE_TRANSFORM(WINED3DTS_TEXTURE0 + stateblock->wineD3DDevice->texUnitMap[sampler]), stateblock);
1792                 stateblock->wineD3DDevice->lastWasPow2Texture[sampler] = texIsPow2;
1793             }
1794         }
1795
1796         IWineD3DBaseTexture_PreLoad((IWineD3DBaseTexture *) stateblock->textures[sampler]);
1797         IWineD3DBaseTexture_ApplyStateChanges(stateblock->textures[sampler], stateblock->textureState[sampler], stateblock->samplerState[sampler]);
1798
1799         if (GL_SUPPORT(EXT_TEXTURE_LOD_BIAS)) {
1800             tmpvalue.d = stateblock->samplerState[sampler][WINED3DSAMP_MIPMAPLODBIAS];
1801             glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT,
1802                       GL_TEXTURE_LOD_BIAS_EXT,
1803                       tmpvalue.f);
1804             checkGLcall("glTexEnvi GL_TEXTURE_LOD_BIAS_EXT ...");
1805         }
1806
1807         if (stateblock->wineD3DDevice->ps_selected_mode != SHADER_NONE && stateblock->pixelShader &&
1808             ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.function) {
1809             /* Using a pixel shader? Verify the sampler types */
1810
1811             /* Make sure that the texture dimensions are enabled. I don't have to disable the other
1812              * dimensions because the shader knows from which texture type to sample from. For the sake of
1813              * debugging all dimensions could be enabled and a texture with some ugly pink bound to the unused
1814              * dimensions. This should make wrong sampling sources visible :-)
1815              */
1816             glEnable(stateblock->textureDimensions[sampler]);
1817             checkGLcall("glEnable(stateblock->textureDimensions[sampler])");
1818         } else if(sampler < stateblock->lowest_disabled_stage) {
1819             activate_dimensions(sampler, stateblock);
1820
1821             if(stateblock->renderState[WINED3DRS_COLORKEYENABLE] && sampler == 0) {
1822                 /* If color keying is enabled update the alpha test, it depends on the existence
1823                  * of a color key in stage 0
1824                  */
1825                 state_alpha(WINED3DRS_COLORKEYENABLE, stateblock);
1826             }
1827         }
1828     } else if(sampler < GL_LIMITS(texture_stages)) {
1829         if(sampler < stateblock->lowest_disabled_stage) {
1830             /* TODO: Check if the colorop is dirty to do that job
1831              * TODO: What should I do with pixel shaders here ???
1832              */
1833             activate_dimensions(sampler, stateblock);
1834         } /* Otherwise tex_colorop disables the stage */
1835         glBindTexture(GL_TEXTURE_1D, stateblock->wineD3DDevice->dummyTextureName[sampler]);
1836         checkGLcall("glBindTexture(GL_TEXTURE_1D, stateblock->wineD3DDevice->dummyTextureName[sampler])");
1837     }
1838 }
1839
1840 static void shaderconstant(DWORD state, IWineD3DStateBlockImpl *stateblock) {
1841     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
1842
1843     /* Vertex and pixel shader states will call a shader upload, don't do anything as long one of them
1844      * has an update pending
1845      */
1846     if(isStateDirty(device, STATE_VDECL) ||
1847        isStateDirty(device, STATE_PIXELSHADER)) {
1848        return;
1849     }
1850     
1851     device->shader_backend->shader_load_constants((IWineD3DDevice *) device,
1852         stateblock->pixelShader && ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.function,
1853         stateblock->vertexShader && ((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.function);
1854 }
1855
1856 static void pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock) {
1857     int i;
1858
1859     if(stateblock->pixelShader && ((IWineD3DPixelShaderImpl *) stateblock->pixelShader)->baseShader.function != NULL) {
1860         if(!stateblock->wineD3DDevice->last_was_pshader) {
1861             /* Former draw without a pixel shader, some samplers
1862              * may be disabled because of WINED3DTSS_COLOROP = WINED3DTOP_DISABLE
1863              * make sure to enable them
1864              */
1865             for(i=0; i < MAX_SAMPLERS; i++) {
1866                 if(!isStateDirty(stateblock->wineD3DDevice, STATE_SAMPLER(i))) {
1867                     sampler(STATE_SAMPLER(i), stateblock);
1868                 }
1869             }
1870         } else {
1871            /* Otherwise all samplers were activated by the code above in earlier draws, or by sampler()
1872             * if a different texture was bound. I don't have to do anything.
1873             */
1874         }
1875
1876         /* Compile and bind the shader */
1877         IWineD3DPixelShader_CompileShader(stateblock->pixelShader);
1878
1879         if(!isStateDirty(stateblock->wineD3DDevice, StateTable[STATE_VSHADER].representative)) {
1880             stateblock->wineD3DDevice->shader_backend->shader_select(
1881                     (IWineD3DDevice *) stateblock->wineD3DDevice,
1882                     TRUE,
1883                     !stateblock->vertexShader ? FALSE : ((IWineD3DVertexShaderImpl *) stateblock->vertexShader)->baseShader.function != NULL);
1884             
1885             if(!isStateDirty(stateblock->wineD3DDevice, STATE_VERTEXSHADERCONSTANT)) {
1886                 shaderconstant(STATE_VERTEXSHADERCONSTANT, stateblock);
1887             }
1888         }
1889         stateblock->wineD3DDevice->last_was_pshader = TRUE;
1890     } else {
1891         /* Disabled the pixel shader - color ops weren't applied
1892          * while it was enabled, so re-apply them.
1893          */
1894         for(i=0; i < MAX_TEXTURES; i++) {
1895             if(!isStateDirty(stateblock->wineD3DDevice, STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP))) {
1896                 tex_colorop(STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP), stateblock);
1897             }
1898         }
1899         stateblock->wineD3DDevice->last_was_pshader = FALSE;
1900
1901         if(!isStateDirty(stateblock->wineD3DDevice, StateTable[STATE_VSHADER].representative)) {
1902             stateblock->wineD3DDevice->shader_backend->shader_select(
1903                     (IWineD3DDevice *) stateblock->wineD3DDevice,
1904                     FALSE,
1905                     !stateblock->vertexShader ? FALSE : ((IWineD3DVertexShaderImpl *) stateblock->vertexShader)->baseShader.function != NULL);
1906
1907             if(!isStateDirty(stateblock->wineD3DDevice, STATE_VERTEXSHADERCONSTANT)) {
1908                 shaderconstant(STATE_VERTEXSHADERCONSTANT, stateblock);
1909             }
1910         }
1911     }
1912 }
1913
1914 static void transform_world(DWORD state, IWineD3DStateBlockImpl *stateblock) {
1915     /* This function is called by transform_view below if the view matrix was changed too
1916      *
1917      * Deliberately no check if the vertex declaration is dirty because the vdecl state
1918      * does not always update the world matrix, only on a switch between transformed
1919      * and untrannsformed draws. It *may* happen that the world matrix is set 2 times during one
1920      * draw, but that should be rather rare and cheaper in total.
1921      */
1922     glMatrixMode(GL_MODELVIEW);
1923     checkGLcall("glMatrixMode");
1924
1925     if(stateblock->wineD3DDevice->last_was_rhw) {
1926         glLoadIdentity();
1927         checkGLcall("glLoadIdentity()");
1928     } else {
1929         /* In the general case, the view matrix is the identity matrix */
1930         if (stateblock->wineD3DDevice->view_ident) {
1931             glLoadMatrixf((float *) &stateblock->transforms[WINED3DTS_WORLDMATRIX(0)].u.m[0][0]);
1932             checkGLcall("glLoadMatrixf");
1933         } else {
1934             glLoadMatrixf((float *) &stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
1935             checkGLcall("glLoadMatrixf");
1936             glMultMatrixf((float *) &stateblock->transforms[WINED3DTS_WORLDMATRIX(0)].u.m[0][0]);
1937             checkGLcall("glMultMatrixf");
1938         }
1939     }
1940 }
1941
1942 static void transform_view(DWORD state, IWineD3DStateBlockImpl *stateblock) {
1943     unsigned int k;
1944
1945     /* If we are changing the View matrix, reset the light and clipping planes to the new view
1946      * NOTE: We have to reset the positions even if the light/plane is not currently
1947      *       enabled, since the call to enable it will not reset the position.
1948      * NOTE2: Apparently texture transforms do NOT need reapplying
1949      */
1950
1951     PLIGHTINFOEL *lightChain = NULL;
1952
1953     glMatrixMode(GL_MODELVIEW);
1954     checkGLcall("glMatrixMode(GL_MODELVIEW)");
1955     glLoadMatrixf((float *)(float *) &stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
1956     checkGLcall("glLoadMatrixf(...)");
1957
1958     /* Reset lights. TODO: Call light apply func */
1959     lightChain = stateblock->lights;
1960     while (lightChain && lightChain->glIndex != -1) {
1961         glLightfv(GL_LIGHT0 + lightChain->glIndex, GL_POSITION, lightChain->lightPosn);
1962         checkGLcall("glLightfv posn");
1963         glLightfv(GL_LIGHT0 + lightChain->glIndex, GL_SPOT_DIRECTION, lightChain->lightDirn);
1964         checkGLcall("glLightfv dirn");
1965         lightChain = lightChain->next;
1966     }
1967
1968     /* Reset Clipping Planes if clipping is enabled. TODO: Call clipplane apply func */
1969     for (k = 0; k < GL_LIMITS(clipplanes); k++) {
1970         glClipPlane(GL_CLIP_PLANE0 + k, stateblock->clipplane[k]);
1971         checkGLcall("glClipPlane");
1972     }
1973
1974     if(stateblock->wineD3DDevice->last_was_rhw) {
1975         glLoadIdentity();
1976         checkGLcall("glLoadIdentity()");
1977         /* No need to update the world matrix, the identity is fine */
1978         return;
1979     }
1980
1981     /* Call the world matrix state, this will apply the combined WORLD + VIEW matrix
1982      * No need to do it here if the state is scheduled for update.
1983      */
1984     if(!isStateDirty(stateblock->wineD3DDevice, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)))) {
1985         transform_world(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), stateblock);
1986     }
1987 }
1988
1989 static void transform_worldex(DWORD state, IWineD3DStateBlockImpl *stateblock) {
1990     WARN("World matrix 1 - 255 not supported yet\n");
1991 }
1992
1993 static const GLfloat invymat[16] = {
1994     1.0f, 0.0f, 0.0f, 0.0f,
1995     0.0f, -1.0f, 0.0f, 0.0f,
1996     0.0f, 0.0f, 1.0f, 0.0f,
1997     0.0f, 0.0f, 0.0f, 1.0f};
1998
1999 static void transform_projection(DWORD state, IWineD3DStateBlockImpl *stateblock) {
2000     glMatrixMode(GL_PROJECTION);
2001     checkGLcall("glMatrixMode(GL_PROJECTION)");
2002     glLoadIdentity();
2003     checkGLcall("glLoadIdentity");
2004
2005     if(stateblock->wineD3DDevice->last_was_rhw) {
2006         double X, Y, height, width, minZ, maxZ;
2007
2008         X      = stateblock->viewport.X;
2009         Y      = stateblock->viewport.Y;
2010         height = stateblock->viewport.Height;
2011         width  = stateblock->viewport.Width;
2012         minZ   = stateblock->viewport.MinZ;
2013         maxZ   = stateblock->viewport.MaxZ;
2014
2015         if(!stateblock->wineD3DDevice->untransformed) {
2016             /* Transformed vertices are supposed to bypass the whole transform pipeline including
2017              * frustum clipping. This can't be done in opengl, so this code adjusts the Z range to
2018              * suppress depth clipping. This can be done because it is an orthogonal projection and
2019              * the Z coordinate does not affect the size of the primitives
2020              */
2021             TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, -minZ, -maxZ);
2022             glOrtho(X, X + width, Y + height, Y, -minZ, -maxZ);
2023         } else {
2024             /* If the app mixes transformed and untransformed primitives we can't use the coordinate system
2025              * trick above because this would mess up transformed and untransformed Z order. Pass the z position
2026              * unmodified to opengl.
2027              *
2028              * If the app depends on mixed types and disabled clipping we're out of luck without a pipeline
2029              * replacement shader.
2030              */
2031             TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, 1.0, -1.0);
2032             glOrtho(X, X + width, Y + height, Y, 1.0, -1.0);
2033         }
2034         checkGLcall("glOrtho");
2035
2036         /* Window Coord 0 is the middle of the first pixel, so translate by 3/8 pixels */
2037         glTranslatef(0.375, 0.375, 0);
2038         checkGLcall("glTranslatef(0.375, 0.375, 0)");
2039         /* D3D texture coordinates are flipped compared to OpenGL ones, so
2040          * render everything upside down when rendering offscreen. */
2041         if (stateblock->wineD3DDevice->render_offscreen) {
2042             glMultMatrixf(invymat);
2043             checkGLcall("glMultMatrixf(invymat)");
2044         }
2045     } else {
2046         /* The rule is that the window coordinate 0 does not correspond to the
2047             beginning of the first pixel, but the center of the first pixel.
2048             As a consequence if you want to correctly draw one line exactly from
2049             the left to the right end of the viewport (with all matrices set to
2050             be identity), the x coords of both ends of the line would be not
2051             -1 and 1 respectively but (-1-1/viewport_widh) and (1-1/viewport_width)
2052             instead.                                                               */
2053         glTranslatef(0.9 / stateblock->viewport.Width, -0.9 / stateblock->viewport.Height, 0);
2054         checkGLcall("glTranslatef (0.9 / width, -0.9 / height, 0)");
2055
2056         /* D3D texture coordinates are flipped compared to OpenGL ones, so
2057             * render everything upside down when rendering offscreen. */
2058         if (stateblock->wineD3DDevice->render_offscreen) {
2059             glMultMatrixf(invymat);
2060             checkGLcall("glMultMatrixf(invymat)");
2061         }
2062         glMultMatrixf((float *) &stateblock->transforms[WINED3DTS_PROJECTION].u.m[0][0]);
2063         checkGLcall("glLoadMatrixf");
2064     }
2065 }
2066
2067 /* This should match any arrays loaded in loadVertexData.
2068  * stateblock impl is required for GL_SUPPORT
2069  * TODO: Only load / unload arrays if we have to.
2070  */
2071 static inline void unloadVertexData(IWineD3DStateBlockImpl *stateblock) {
2072     int texture_idx;
2073
2074     glDisableClientState(GL_VERTEX_ARRAY);
2075     glDisableClientState(GL_NORMAL_ARRAY);
2076     glDisableClientState(GL_COLOR_ARRAY);
2077     if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
2078         glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
2079     }
2080     for (texture_idx = 0; texture_idx < GL_LIMITS(textures); ++texture_idx) {
2081         GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + texture_idx));
2082         glDisableClientState(GL_TEXTURE_COORD_ARRAY);
2083     }
2084 }
2085
2086 /* This should match any arrays loaded in loadNumberedArrays
2087  * TODO: Only load / unload arrays if we have to.
2088  */
2089 static inline void unloadNumberedArrays(IWineD3DStateBlockImpl *stateblock) {
2090     /* disable any attribs (this is the same for both GLSL and ARB modes) */
2091     GLint maxAttribs;
2092     int i;
2093
2094     /* Leave all the attribs disabled */
2095     glGetIntegerv(GL_MAX_VERTEX_ATTRIBS_ARB, &maxAttribs);
2096     /* MESA does not support it right not */
2097     if (glGetError() != GL_NO_ERROR)
2098         maxAttribs = 16;
2099     for (i = 0; i < maxAttribs; ++i) {
2100         GL_EXTCALL(glDisableVertexAttribArrayARB(i));
2101         checkGLcall("glDisableVertexAttribArrayARB(reg);");
2102     }
2103 }
2104
2105 static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock, WineDirect3DVertexStridedData *strided) {
2106     GLint curVBO = GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT) ? -1 : 0;
2107     int i;
2108
2109     for (i = 0; i < MAX_ATTRIBS; i++) {
2110
2111         if (!strided->u.input[i].lpData && !strided->u.input[i].VBO)
2112             continue;
2113
2114         TRACE_(d3d_shader)("Loading array %u [VBO=%u]\n", i, strided->u.input[i].VBO);
2115
2116         if(curVBO != strided->u.input[i].VBO) {
2117             GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, strided->u.input[i].VBO));
2118             checkGLcall("glBindBufferARB");
2119             curVBO = strided->u.input[i].VBO;
2120         }
2121         GL_EXTCALL(glVertexAttribPointerARB(i,
2122                         WINED3D_ATR_SIZE(strided->u.input[i].dwType),
2123                         WINED3D_ATR_GLTYPE(strided->u.input[i].dwType),
2124                         WINED3D_ATR_NORMALIZED(strided->u.input[i].dwType),
2125                         strided->u.input[i].dwStride,
2126                         strided->u.input[i].lpData + stateblock->loadBaseVertexIndex * strided->u.input[i].dwStride));
2127         GL_EXTCALL(glEnableVertexAttribArrayARB(i));
2128    }
2129 }
2130
2131 /* Used from 2 different functions, and too big to justify making it inlined */
2132 static void loadVertexData(IWineD3DStateBlockImpl *stateblock, WineDirect3DVertexStridedData *sd) {
2133     unsigned int textureNo   = 0;
2134     unsigned int texture_idx = 0;
2135     GLint curVBO = GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT) ? -1 : 0;
2136
2137     TRACE("Using fast vertex array code\n");
2138     /* Blend Data ---------------------------------------------- */
2139     if( (sd->u.s.blendWeights.lpData) || (sd->u.s.blendWeights.VBO) ||
2140         (sd->u.s.blendMatrixIndices.lpData) || (sd->u.s.blendMatrixIndices.VBO) ) {
2141
2142
2143         if (GL_SUPPORT(ARB_VERTEX_BLEND)) {
2144
2145 #if 1
2146             glEnableClientState(GL_WEIGHT_ARRAY_ARB);
2147             checkGLcall("glEnableClientState(GL_WEIGHT_ARRAY_ARB)");
2148 #endif
2149
2150             TRACE("Blend %d %p %d\n", WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType),
2151                 sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride, sd->u.s.blendWeights.dwStride);
2152             /* FIXME("TODO\n");*/
2153             /* Note dwType == float3 or float4 == 2 or 3 */
2154
2155 #if 0
2156             /* with this on, the normals appear to be being modified,
2157                but the vertices aren't being translated as they should be
2158                Maybe the world matrix aren't being setup properly? */
2159             glVertexBlendARB(WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType) + 1);
2160 #endif
2161
2162
2163             VTRACE(("glWeightPointerARB(%d, GL_FLOAT, %d, %p)\n",
2164                 WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType) ,
2165                 sd->u.s.blendWeights.dwStride,
2166                 sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride));
2167
2168             if(curVBO != sd->u.s.blendWeights.VBO) {
2169                 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.blendWeights.VBO));
2170                 checkGLcall("glBindBufferARB");
2171                 curVBO = sd->u.s.blendWeights.VBO;
2172             }
2173
2174             GL_EXTCALL(glWeightPointerARB)(
2175                 WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType),
2176                 WINED3D_ATR_GLTYPE(sd->u.s.blendWeights.dwType),
2177                 sd->u.s.blendWeights.dwStride,
2178                 sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride);
2179
2180             checkGLcall("glWeightPointerARB");
2181
2182             if((sd->u.s.blendMatrixIndices.lpData) || (sd->u.s.blendMatrixIndices.VBO)){
2183                 static BOOL showfixme = TRUE;
2184                 if(showfixme){
2185                     FIXME("blendMatrixIndices support\n");
2186                     showfixme = FALSE;
2187                 }
2188             }
2189
2190         } else if (GL_SUPPORT(EXT_VERTEX_WEIGHTING)) {
2191             /* FIXME("TODO\n");*/
2192 #if 0
2193
2194             GL_EXTCALL(glVertexWeightPointerEXT)(
2195                 WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType),
2196                 WINED3D_ATR_GLTYPE(sd->u.s.blendWeights.dwType),
2197                 sd->u.s.blendWeights.dwStride,
2198                 sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride);
2199             checkGLcall("glVertexWeightPointerEXT(numBlends, ...)");
2200             glEnableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT);
2201             checkGLcall("glEnableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT)");
2202 #endif
2203
2204         } else {
2205             /* TODO: support blends in fixupVertices */
2206             FIXME("unsupported blending in openGl\n");
2207         }
2208     } else {
2209         if (GL_SUPPORT(ARB_VERTEX_BLEND)) {
2210 #if 0    /* TODO: Vertex blending */
2211             glDisable(GL_VERTEX_BLEND_ARB);
2212 #endif
2213             TRACE("ARB_VERTEX_BLEND\n");
2214         } else if (GL_SUPPORT(EXT_VERTEX_WEIGHTING)) {
2215             TRACE(" EXT_VERTEX_WEIGHTING\n");
2216             glDisableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT);
2217             checkGLcall("glDisableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT)");
2218
2219         }
2220     }
2221
2222 #if 0 /* FOG  ----------------------------------------------*/
2223     if (sd->u.s.fog.lpData || sd->u.s.fog.VBO) {
2224         /* TODO: fog*/
2225     if (GL_SUPPORT(EXT_FOG_COORD) {
2226              glEnableClientState(GL_FOG_COORDINATE_EXT);
2227             (GL_EXTCALL)(FogCoordPointerEXT)(
2228                 WINED3D_ATR_GLTYPE(sd->u.s.fog.dwType),
2229                 sd->u.s.fog.dwStride,
2230                 sd->u.s.fog.lpData + stateblock->loadBaseVertexIndex * sd->u.s.fog.dwStride);
2231         } else {
2232             /* don't bother falling back to 'slow' as we don't support software FOG yet. */
2233             /* FIXME: fixme once */
2234             TRACE("Hardware support for FOG is not avaiable, FOG disabled.\n");
2235         }
2236     } else {
2237         if (GL_SUPPRT(EXT_FOR_COORD) {
2238              /* make sure fog is disabled */
2239              glDisableClientState(GL_FOG_COORDINATE_EXT);
2240         }
2241     }
2242 #endif
2243
2244 #if 0 /* tangents  ----------------------------------------------*/
2245     if (sd->u.s.tangent.lpData || sd->u.s.tangent.VBO ||
2246         sd->u.s.binormal.lpData || sd->u.s.binormal.VBO) {
2247         /* TODO: tangents*/
2248         if (GL_SUPPORT(EXT_COORDINATE_FRAME) {
2249             if (sd->u.s.tangent.lpData || sd->u.s.tangent.VBO) {
2250                 glEnable(GL_TANGENT_ARRAY_EXT);
2251                 (GL_EXTCALL)(TangentPointerEXT)(
2252                     WINED3D_ATR_GLTYPE(sd->u.s.tangent.dwType),
2253                     sd->u.s.tangent.dwStride,
2254                     sd->u.s.tangent.lpData + stateblock->loadBaseVertexIndex * sd->u.s.tangent.dwStride);
2255             } else {
2256                     glDisable(GL_TANGENT_ARRAY_EXT);
2257             }
2258             if (sd->u.s.binormal.lpData || sd->u.s.binormal.VBO) {
2259                     glEnable(GL_BINORMAL_ARRAY_EXT);
2260                     (GL_EXTCALL)(BinormalPointerEXT)(
2261                         WINED3D_ATR_GLTYPE(sd->u.s.binormal.dwType),
2262                         sd->u.s.binormal.dwStride,
2263                         sd->u.s.binormal.lpData + stateblock->loadBaseVertexIndex * sd->u.s.binormal.dwStride);
2264             } else{
2265                     glDisable(GL_BINORMAL_ARRAY_EXT);
2266             }
2267
2268         } else {
2269             /* don't bother falling back to 'slow' as we don't support software tangents and binormals yet . */
2270             /* FIXME: fixme once */
2271             TRACE("Hardware support for tangents and binormals is not avaiable, tangents and binormals disabled.\n");
2272         }
2273     } else {
2274         if (GL_SUPPORT(EXT_COORDINATE_FRAME) {
2275              /* make sure fog is disabled */
2276              glDisable(GL_TANGENT_ARRAY_EXT);
2277              glDisable(GL_BINORMAL_ARRAY_EXT);
2278         }
2279     }
2280 #endif
2281
2282     /* Point Size ----------------------------------------------*/
2283     if (sd->u.s.pSize.lpData || sd->u.s.pSize.VBO) {
2284
2285         /* no such functionality in the fixed function GL pipeline */
2286         TRACE("Cannot change ptSize here in openGl\n");
2287         /* TODO: Implement this function in using shaders if they are available */
2288
2289     }
2290
2291     /* Vertex Pointers -----------------------------------------*/
2292     if (sd->u.s.position.lpData != NULL || sd->u.s.position.VBO != 0) {
2293         /* Note dwType == float3 or float4 == 2 or 3 */
2294         VTRACE(("glVertexPointer(%d, GL_FLOAT, %d, %p)\n",
2295                 sd->u.s.position.dwStride,
2296                 sd->u.s.position.dwType + 1,
2297                 sd->u.s.position.lpData));
2298
2299         if(curVBO != sd->u.s.position.VBO) {
2300             GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.position.VBO));
2301             checkGLcall("glBindBufferARB");
2302             curVBO = sd->u.s.position.VBO;
2303         }
2304
2305         /* min(WINED3D_ATR_SIZE(position),3) to Disable RHW mode as 'w' coord
2306            handling for rhw mode should not impact screen position whereas in GL it does.
2307            This may  result in very slightly distored textures in rhw mode, but
2308            a very minimal different. There's always the other option of
2309            fixing the view matrix to prevent w from having any effect
2310
2311            This only applies to user pointer sources, in VBOs the vertices are fixed up
2312          */
2313         if(sd->u.s.position.VBO == 0) {
2314             glVertexPointer(3 /* min(WINED3D_ATR_SIZE(sd->u.s.position.dwType),3) */,
2315                 WINED3D_ATR_GLTYPE(sd->u.s.position.dwType),
2316                 sd->u.s.position.dwStride, sd->u.s.position.lpData + stateblock->loadBaseVertexIndex * sd->u.s.position.dwStride);
2317         } else {
2318             glVertexPointer(
2319                 WINED3D_ATR_SIZE(sd->u.s.position.dwType),
2320                 WINED3D_ATR_GLTYPE(sd->u.s.position.dwType),
2321                 sd->u.s.position.dwStride, sd->u.s.position.lpData + stateblock->loadBaseVertexIndex * sd->u.s.position.dwStride);
2322         }
2323         checkGLcall("glVertexPointer(...)");
2324         glEnableClientState(GL_VERTEX_ARRAY);
2325         checkGLcall("glEnableClientState(GL_VERTEX_ARRAY)");
2326
2327     } else {
2328         glDisableClientState(GL_VERTEX_ARRAY);
2329         checkGLcall("glDisableClientState(GL_VERTEX_ARRAY)");
2330     }
2331
2332     /* Normals -------------------------------------------------*/
2333     if (sd->u.s.normal.lpData || sd->u.s.normal.VBO) {
2334         /* Note dwType == float3 or float4 == 2 or 3 */
2335         VTRACE(("glNormalPointer(GL_FLOAT, %d, %p)\n",
2336                 sd->u.s.normal.dwStride,
2337                 sd->u.s.normal.lpData));
2338         if(curVBO != sd->u.s.normal.VBO) {
2339             GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.normal.VBO));
2340             checkGLcall("glBindBufferARB");
2341             curVBO = sd->u.s.normal.VBO;
2342         }
2343         glNormalPointer(
2344             WINED3D_ATR_GLTYPE(sd->u.s.normal.dwType),
2345             sd->u.s.normal.dwStride,
2346             sd->u.s.normal.lpData + stateblock->loadBaseVertexIndex * sd->u.s.normal.dwStride);
2347         checkGLcall("glNormalPointer(...)");
2348         glEnableClientState(GL_NORMAL_ARRAY);
2349         checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)");
2350
2351     } else {
2352         glDisableClientState(GL_NORMAL_ARRAY);
2353         checkGLcall("glDisableClientState(GL_NORMAL_ARRAY)");
2354         glNormal3f(0, 0, 1);
2355         checkGLcall("glNormal3f(0, 0, 1)");
2356     }
2357
2358     /* Diffuse Colour --------------------------------------------*/
2359     /*  WARNING: Data here MUST be in RGBA format, so cannot      */
2360     /*     go directly into fast mode from app pgm, because       */
2361     /*     directx requires data in BGRA format.                  */
2362     /* currently fixupVertices swizels the format, but this isn't */
2363     /* very practical when using VBOS                             */
2364     /* NOTE: Unless we write a vertex shader to swizel the colour */
2365     /* , or the user doesn't care and wants the speed advantage   */
2366
2367     if (sd->u.s.diffuse.lpData || sd->u.s.diffuse.VBO) {
2368         /* Note dwType == float3 or float4 == 2 or 3 */
2369         VTRACE(("glColorPointer(4, GL_UNSIGNED_BYTE, %d, %p)\n",
2370                 sd->u.s.diffuse.dwStride,
2371                 sd->u.s.diffuse.lpData));
2372
2373         if(curVBO != sd->u.s.diffuse.VBO) {
2374             GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.diffuse.VBO));
2375             checkGLcall("glBindBufferARB");
2376             curVBO = sd->u.s.diffuse.VBO;
2377         }
2378         glColorPointer(4, GL_UNSIGNED_BYTE,
2379                        sd->u.s.diffuse.dwStride,
2380                        sd->u.s.diffuse.lpData + stateblock->loadBaseVertexIndex * sd->u.s.diffuse.dwStride);
2381         checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)");
2382         glEnableClientState(GL_COLOR_ARRAY);
2383         checkGLcall("glEnableClientState(GL_COLOR_ARRAY)");
2384
2385     } else {
2386         glDisableClientState(GL_COLOR_ARRAY);
2387         checkGLcall("glDisableClientState(GL_COLOR_ARRAY)");
2388         glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
2389         checkGLcall("glColor4f(1, 1, 1, 1)");
2390     }
2391
2392     /* Specular Colour ------------------------------------------*/
2393     if (sd->u.s.specular.lpData || sd->u.s.specular.VBO) {
2394         TRACE("setting specular colour\n");
2395         /* Note dwType == float3 or float4 == 2 or 3 */
2396         VTRACE(("glSecondaryColorPointer(4, GL_UNSIGNED_BYTE, %d, %p)\n",
2397                 sd->u.s.specular.dwStride,
2398                 sd->u.s.specular.lpData));
2399         if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
2400             if(curVBO != sd->u.s.specular.VBO) {
2401                 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.specular.VBO));
2402                 checkGLcall("glBindBufferARB");
2403                 curVBO = sd->u.s.specular.VBO;
2404             }
2405             GL_EXTCALL(glSecondaryColorPointerEXT)(4, GL_UNSIGNED_BYTE,
2406                                                    sd->u.s.specular.dwStride,
2407                                                    sd->u.s.specular.lpData + stateblock->loadBaseVertexIndex * sd->u.s.specular.dwStride);
2408             vcheckGLcall("glSecondaryColorPointerEXT(4, GL_UNSIGNED_BYTE, ...)");
2409             glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
2410             vcheckGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
2411         } else {
2412
2413         /* Missing specular color is not critical, no warnings */
2414         VTRACE(("Specular colour is not supported in this GL implementation\n"));
2415         }
2416
2417     } else {
2418         if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
2419
2420             glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
2421             checkGLcall("glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
2422             GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0);
2423             checkGLcall("glSecondaryColor3fEXT(0, 0, 0)");
2424         } else {
2425
2426             /* Missing specular color is not critical, no warnings */
2427             VTRACE(("Specular colour is not supported in this GL implementation\n"));
2428         }
2429     }
2430
2431     /* Texture coords -------------------------------------------*/
2432
2433     for (textureNo = 0, texture_idx = 0; textureNo < GL_LIMITS(texture_stages); ++textureNo) {
2434         /* The code below uses glClientActiveTexture and glMultiTexCoord* which are all part of the GL_ARB_multitexture extension. */
2435         /* Abort if we don't support the extension. */
2436         if (!GL_SUPPORT(ARB_MULTITEXTURE)) {
2437             FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
2438             continue;
2439         }
2440
2441         if (/*!GL_SUPPORT(NV_REGISTER_COMBINERS) || stateblock->textures[textureNo]*/ TRUE) {
2442             /* Select the correct texture stage */
2443             GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + texture_idx));
2444         }
2445
2446         if (stateblock->textures[textureNo] != NULL) {
2447             int coordIdx = stateblock->textureState[textureNo][WINED3DTSS_TEXCOORDINDEX];
2448
2449             if (coordIdx >= MAX_TEXTURES) {
2450                 VTRACE(("tex: %d - Skip tex coords, as being system generated\n", textureNo));
2451                 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
2452                 GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + texture_idx, 0, 0, 0, 1));
2453
2454             } else if (sd->u.s.texCoords[coordIdx].lpData == NULL && sd->u.s.texCoords[coordIdx].VBO == 0) {
2455                 VTRACE(("Bound texture but no texture coordinates supplied, so skipping\n"));
2456                 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
2457                 GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + texture_idx, 0, 0, 0, 1));
2458
2459             } else {
2460                 TRACE("Setting up texture %u, idx %d, cordindx %u, data %p\n",
2461                       textureNo, texture_idx, coordIdx, sd->u.s.texCoords[coordIdx].lpData);
2462                 if(curVBO != sd->u.s.texCoords[coordIdx].VBO) {
2463                     GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.texCoords[coordIdx].VBO));
2464                     checkGLcall("glBindBufferARB");
2465                     curVBO = sd->u.s.texCoords[coordIdx].VBO;
2466                 }
2467                 /* The coords to supply depend completely on the fvf / vertex shader */
2468                 glTexCoordPointer(
2469                     WINED3D_ATR_SIZE(sd->u.s.texCoords[coordIdx].dwType),
2470                     WINED3D_ATR_GLTYPE(sd->u.s.texCoords[coordIdx].dwType),
2471                     sd->u.s.texCoords[coordIdx].dwStride,
2472                     sd->u.s.texCoords[coordIdx].lpData + stateblock->loadBaseVertexIndex * sd->u.s.texCoords[coordIdx].dwStride);
2473                 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
2474             }
2475         } else if (!GL_SUPPORT(NV_REGISTER_COMBINERS)) {
2476             glDisableClientState(GL_TEXTURE_COORD_ARRAY);
2477             GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, 0, 0, 0, 1));
2478         }
2479         if (/*!GL_SUPPORT(NV_REGISTER_COMBINERS) || stateblock->textures[textureNo]*/ TRUE) ++texture_idx;
2480     }
2481     if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
2482         for (textureNo = texture_idx; textureNo < GL_LIMITS(textures); ++textureNo) {
2483             GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + textureNo));
2484             glDisableClientState(GL_TEXTURE_COORD_ARRAY);
2485             GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, 0, 0, 0, 1));
2486         }
2487     }
2488 }
2489
2490 inline void drawPrimitiveTraceDataLocations(
2491     WineDirect3DVertexStridedData *dataLocations) {
2492
2493     /* Dump out what parts we have supplied */
2494     TRACE("Strided Data:\n");
2495     TRACE_STRIDED((dataLocations), position);
2496     TRACE_STRIDED((dataLocations), blendWeights);
2497     TRACE_STRIDED((dataLocations), blendMatrixIndices);
2498     TRACE_STRIDED((dataLocations), normal);
2499     TRACE_STRIDED((dataLocations), pSize);
2500     TRACE_STRIDED((dataLocations), diffuse);
2501     TRACE_STRIDED((dataLocations), specular);
2502     TRACE_STRIDED((dataLocations), texCoords[0]);
2503     TRACE_STRIDED((dataLocations), texCoords[1]);
2504     TRACE_STRIDED((dataLocations), texCoords[2]);
2505     TRACE_STRIDED((dataLocations), texCoords[3]);
2506     TRACE_STRIDED((dataLocations), texCoords[4]);
2507     TRACE_STRIDED((dataLocations), texCoords[5]);
2508     TRACE_STRIDED((dataLocations), texCoords[6]);
2509     TRACE_STRIDED((dataLocations), texCoords[7]);
2510     TRACE_STRIDED((dataLocations), position2);
2511     TRACE_STRIDED((dataLocations), normal2);
2512     TRACE_STRIDED((dataLocations), tangent);
2513     TRACE_STRIDED((dataLocations), binormal);
2514     TRACE_STRIDED((dataLocations), tessFactor);
2515     TRACE_STRIDED((dataLocations), fog);
2516     TRACE_STRIDED((dataLocations), depth);
2517     TRACE_STRIDED((dataLocations), sample);
2518
2519     return;
2520 }
2521
2522 /* Helper for vertexdeclaration() */
2523 static inline void handleStreams(IWineD3DStateBlockImpl *stateblock, BOOL useVertexShaderFunction) {
2524     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
2525     BOOL fixup = FALSE;
2526     WineDirect3DVertexStridedData *dataLocations = &device->strided_streams;
2527
2528     if(device->up_strided) {
2529         /* Note: this is a ddraw fixed-function code path */
2530         TRACE("================ Strided Input ===================\n");
2531         memcpy(dataLocations, device->up_strided, sizeof(*dataLocations));
2532
2533         if(TRACE_ON(d3d)) {
2534             drawPrimitiveTraceDataLocations(dataLocations);
2535         }
2536     } else if (stateblock->vertexDecl || stateblock->vertexShader) {
2537         /* Note: This is a fixed function or shader codepath.
2538          * This means it must handle both types of strided data.
2539          * Shaders must go through here to zero the strided data, even if they
2540          * don't set any declaration at all
2541          */
2542         TRACE("================ Vertex Declaration  ===================\n");
2543         memset(dataLocations, 0, sizeof(*dataLocations));
2544
2545         if (stateblock->vertexDecl != NULL ||
2546             ((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->vertexDeclaration != NULL) {
2547
2548             primitiveDeclarationConvertToStridedData((IWineD3DDevice *) device, useVertexShaderFunction,
2549                 dataLocations, &fixup);
2550         }
2551     } else {
2552         /* Note: This codepath is not reachable from d3d9 (see fvf->decl9 conversion)
2553          * It is reachable through d3d8, but only for fixed-function.
2554          * It will not work properly for shaders.
2555          */
2556         TRACE("================ FVF ===================\n");
2557         memset(dataLocations, 0, sizeof(*dataLocations));
2558         primitiveConvertToStridedData((IWineD3DDevice *) device, dataLocations, &fixup);
2559         if(TRACE_ON(d3d)) {
2560             drawPrimitiveTraceDataLocations(dataLocations);
2561         }
2562      }
2563
2564     /* Unload the old arrays before loading the new ones to get old junk out */
2565     if(device->numberedArraysLoaded) {
2566         unloadNumberedArrays(stateblock);
2567         device->numberedArraysLoaded = FALSE;
2568     }
2569     if(device->namedArraysLoaded) {
2570         unloadVertexData(stateblock);
2571         device->namedArraysLoaded = FALSE;
2572     }
2573
2574     if(useVertexShaderFunction) {
2575         TRACE("Loading numbered arrays\n");
2576         loadNumberedArrays(stateblock, dataLocations);
2577         device->useDrawStridedSlow = FALSE;
2578         device->numberedArraysLoaded = TRUE;
2579     } else if (fixup ||
2580                (dataLocations->u.s.pSize.lpData == NULL &&
2581                 dataLocations->u.s.diffuse.lpData == NULL &&
2582                 dataLocations->u.s.specular.lpData == NULL)) {
2583         /* Load the vertex data using named arrays */
2584         TRACE("Loading vertex data\n");
2585         loadVertexData(stateblock, dataLocations);
2586         device->useDrawStridedSlow = FALSE;
2587         device->namedArraysLoaded = TRUE;
2588     } else {
2589         TRACE("Not loading vertex data\n");
2590         device->useDrawStridedSlow = TRUE;
2591     }
2592
2593 /* Generate some fixme's if unsupported functionality is being used */
2594 #define BUFFER_OR_DATA(_attribute) dataLocations->u.s._attribute.lpData
2595     /* TODO: Either support missing functionality in fixupVertices or by creating a shader to replace the pipeline. */
2596     if (!useVertexShaderFunction && (BUFFER_OR_DATA(blendMatrixIndices) || BUFFER_OR_DATA(blendWeights))) {
2597         FIXME("Blending data is only valid with vertex shaders %p %p\n",dataLocations->u.s.blendWeights.lpData,dataLocations->u.s.blendWeights.lpData);
2598     }
2599     if (!useVertexShaderFunction && (BUFFER_OR_DATA(position2) || BUFFER_OR_DATA(normal2))) {
2600         FIXME("Tweening is only valid with vertex shaders\n");
2601     }
2602     if (!useVertexShaderFunction && (BUFFER_OR_DATA(tangent) || BUFFER_OR_DATA(binormal))) {
2603         FIXME("Tangent and binormal bump mapping is only valid with vertex shaders\n");
2604     }
2605     if (!useVertexShaderFunction && (BUFFER_OR_DATA(tessFactor) || BUFFER_OR_DATA(fog) || BUFFER_OR_DATA(depth) || BUFFER_OR_DATA(sample))) {
2606         FIXME("Extended attributes are only valid with vertex shaders\n");
2607     }
2608 #undef BUFFER_OR_DATA
2609 }
2610
2611 static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock) {
2612     BOOL useVertexShaderFunction = FALSE, updateFog = FALSE;
2613     BOOL transformed;
2614     /* Some stuff is in the device until we have per context tracking */
2615     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
2616     BOOL wasrhw = device->last_was_rhw;
2617
2618     /* Shaders can be implemented using ARB_PROGRAM, GLSL, or software -
2619      * here simply check whether a shader was set, or the user disabled shaders
2620      */
2621     if (device->vs_selected_mode != SHADER_NONE && stateblock->vertexShader &&
2622        ((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.function != NULL) {
2623         useVertexShaderFunction = TRUE;
2624
2625         if(((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->usesFog != device->last_was_foggy_shader) {
2626             updateFog = TRUE;
2627         }
2628     } else if(device->last_was_foggy_shader) {
2629         updateFog = TRUE;
2630     }
2631
2632     handleStreams(stateblock, useVertexShaderFunction);
2633
2634     /* Do I have to use ? TRUE : FALSE ? Or can I rely on 15==15 beeing equal to TRUE(=1)? */
2635     transformed = ((device->strided_streams.u.s.position.lpData != NULL ||
2636                     device->strided_streams.u.s.position.VBO != 0) &&
2637                     device->strided_streams.u.s.position_transformed) ? TRUE : FALSE;
2638
2639     if(transformed != device->last_was_rhw && !useVertexShaderFunction) {
2640         updateFog = TRUE;
2641     }
2642
2643     /* Reapply lighting if it is not sheduled for reapplication already */
2644     if(!isStateDirty(device, STATE_RENDER(WINED3DRS_LIGHTING))) {
2645         state_lighting(STATE_RENDER(WINED3DRS_LIGHTING), stateblock);
2646     }
2647
2648     if (!useVertexShaderFunction && transformed) {
2649         stateblock->wineD3DDevice->last_was_rhw = TRUE;
2650     } else {
2651
2652         /* Untransformed, so relies on the view and projection matrices */
2653         device->last_was_rhw = FALSE;
2654         /* This turns off the Z scale trick to 'disable' viewport frustum clipping in rhw mode*/
2655         device->untransformed = TRUE;
2656
2657         /* Todo for sw shaders: Vertex Shader output is already transformed, so set up identity matrices
2658          * Not needed as long as only hw shaders are supported
2659          */
2660
2661         /* This sets the shader output position correction constants.
2662          * TODO: Move to the viewport state
2663          */
2664         if (useVertexShaderFunction) {
2665             device->posFixup[1] = device->render_offscreen ? -1.0 : 1.0;
2666         }
2667     }
2668
2669     /* Don't have to apply the matrices when vertex shaders are used. When vshaders are turned
2670      * off this function will be called again anyway to make sure they're properly set
2671      */
2672     if(!useVertexShaderFunction) {
2673         /* TODO: Move this mainly to the viewport state and only apply when the vp has changed
2674          * or transformed / untransformed was switched
2675          */
2676        if(wasrhw != device->last_was_rhw &&
2677           !isStateDirty(stateblock->wineD3DDevice, STATE_TRANSFORM(WINED3DTS_PROJECTION)) &&
2678           !isStateDirty(stateblock->wineD3DDevice, STATE_VIEWPORT)) {
2679             transform_projection(STATE_TRANSFORM(WINED3DTS_PROJECTION), stateblock);
2680         }
2681         /* World matrix needs reapplication here only if we're switching between rhw and non-rhw
2682          * mode.
2683          *
2684          * If a vertex shader is used, the world matrix changed and then vertex shader unbound
2685          * this check will fail and the matrix not applied again. This is OK because a simple
2686          * world matrix change reapplies the matrix - These checks here are only to satisfy the
2687          * needs of the vertex declaration.
2688          *
2689          * World and view matrix go into the same gl matrix, so only apply them when neither is
2690          * dirty
2691          */
2692         if(transformed != wasrhw &&
2693            !isStateDirty(stateblock->wineD3DDevice, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0))) &&
2694            !isStateDirty(stateblock->wineD3DDevice, STATE_TRANSFORM(WINED3DTS_VIEW))) {
2695             transform_world(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), stateblock);
2696         }
2697
2698         if(!isStateDirty(stateblock->wineD3DDevice, STATE_RENDER(WINED3DRS_COLORVERTEX))) {
2699             state_colormat(STATE_RENDER(WINED3DRS_COLORVERTEX), stateblock);
2700         }
2701     } else {
2702         /* We compile the shader here because we need the vertex declaration
2703          * in order to determine if we need to do any swizzling for D3DCOLOR
2704          * registers. If the shader is already compiled this call will do nothing. */
2705         IWineD3DVertexShader_CompileShader(stateblock->vertexShader);
2706     }
2707
2708     if(useVertexShaderFunction || device->last_was_vshader) {
2709         BOOL usePixelShaderFunction = device->ps_selected_mode != SHADER_NONE && 
2710                                       stateblock->pixelShader &&
2711                                       ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.function;
2712
2713         /* Vertex and pixel shaders are applied together for now, so let the last dirty state do the
2714          * application
2715          */
2716         if(!isStateDirty(device, STATE_PIXELSHADER)) {
2717             device->shader_backend->shader_select((IWineD3DDevice *) device, usePixelShaderFunction, useVertexShaderFunction);
2718
2719             if(!isStateDirty(stateblock->wineD3DDevice, STATE_VERTEXSHADERCONSTANT) && (useVertexShaderFunction || usePixelShaderFunction)) {
2720                 shaderconstant(STATE_VERTEXSHADERCONSTANT, stateblock);
2721             }
2722         }
2723         device->last_was_vshader = useVertexShaderFunction;
2724     }
2725
2726     if(updateFog) {
2727         state_fog(STATE_RENDER(WINED3DRS_FOGENABLE), stateblock);
2728     }
2729 }
2730
2731 static void viewport(DWORD state, IWineD3DStateBlockImpl *stateblock) {
2732     glDepthRange(stateblock->viewport.MinZ, stateblock->viewport.MaxZ);
2733     checkGLcall("glDepthRange");
2734     /* Note: GL requires lower left, DirectX supplies upper left */
2735     /* TODO: replace usage of renderTarget with context management */
2736     glViewport(stateblock->viewport.X,
2737                (((IWineD3DSurfaceImpl *)stateblock->wineD3DDevice->render_targets[0])->currentDesc.Height - (stateblock->viewport.Y + stateblock->viewport.Height)),
2738                stateblock->viewport.Width, stateblock->viewport.Height);
2739
2740     checkGLcall("glViewport");
2741
2742     stateblock->wineD3DDevice->posFixup[2] = 0.9 / stateblock->viewport.Width;
2743     stateblock->wineD3DDevice->posFixup[3] = -0.9 / stateblock->viewport.Height;
2744     if(!isStateDirty(stateblock->wineD3DDevice, STATE_TRANSFORM(D3DTS_PROJECTION))) {
2745         transform_projection(STATE_TRANSFORM(D3DTS_PROJECTION), stateblock);
2746     }
2747
2748 }
2749
2750 const struct StateEntry StateTable[] =
2751 {
2752       /* State name                                         representative,                                     apply function */
2753     { /* 0,  Undefined                              */      0,                                                  state_undefined     },
2754     { /* 1,  WINED3DRS_TEXTUREHANDLE                */      0 /* Handled in ddraw */,                           state_undefined     },
2755     { /* 2,  WINED3DRS_ANTIALIAS                    */      STATE_RENDER(WINED3DRS_ANTIALIAS),                  state_antialias     },
2756     { /* 3,  WINED3DRS_TEXTUREADDRESS               */      0 /* Handled in ddraw */,                           state_undefined     },
2757     { /* 4,  WINED3DRS_TEXTUREPERSPECTIVE           */      STATE_RENDER(WINED3DRS_TEXTUREPERSPECTIVE),         state_perspective   },
2758     { /* 5,  WINED3DRS_WRAPU                        */      STATE_RENDER(WINED3DRS_WRAPU),                      state_wrapu         },
2759     { /* 6,  WINED3DRS_WRAPV                        */      STATE_RENDER(WINED3DRS_WRAPV),                      state_wrapv         },
2760     { /* 7,  WINED3DRS_ZENABLE                      */      STATE_RENDER(WINED3DRS_ZENABLE),                    state_zenable       },
2761     { /* 8,  WINED3DRS_FILLMODE                     */      STATE_RENDER(WINED3DRS_FILLMODE),                   state_fillmode      },
2762     { /* 9,  WINED3DRS_SHADEMODE                    */      STATE_RENDER(WINED3DRS_SHADEMODE),                  state_shademode     },
2763     { /* 10, WINED3DRS_LINEPATTERN                  */      STATE_RENDER(WINED3DRS_LINEPATTERN),                state_linepattern   },
2764     { /* 11, WINED3DRS_MONOENABLE                   */      STATE_RENDER(WINED3DRS_MONOENABLE),                 state_monoenable    },
2765     { /* 12, WINED3DRS_ROP2                         */      STATE_RENDER(WINED3DRS_ROP2),                       state_rop2          },
2766     { /* 13, WINED3DRS_PLANEMASK                    */      STATE_RENDER(WINED3DRS_PLANEMASK),                  state_planemask     },
2767     { /* 14, WINED3DRS_ZWRITEENABLE                 */      STATE_RENDER(WINED3DRS_ZWRITEENABLE),               state_zwritenable   },
2768     { /* 15, WINED3DRS_ALPHATESTENABLE              */      STATE_RENDER(WINED3DRS_ALPHATESTENABLE),            state_alpha         },
2769     { /* 16, WINED3DRS_LASTPIXEL                    */      STATE_RENDER(WINED3DRS_LASTPIXEL),                  state_lastpixel     },
2770     { /* 17, WINED3DRS_TEXTUREMAG                   */      0 /* Handled in ddraw */,                           state_undefined     },
2771     { /* 18, WINED3DRS_TEXTUREMIN                   */      0 /* Handled in ddraw */,                           state_undefined     },
2772     { /* 19, WINED3DRS_SRCBLEND                     */      STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         },
2773     { /* 20, WINED3DRS_DESTBLEND                    */      STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         },
2774     { /* 21, WINED3DRS_TEXTUREMAPBLEND              */      0 /* Handled in ddraw */,                           state_undefined     },
2775     { /* 22, WINED3DRS_CULLMODE                     */      STATE_RENDER(WINED3DRS_CULLMODE),                   state_cullmode      },
2776     { /* 23, WINED3DRS_ZFUNC                        */      STATE_RENDER(WINED3DRS_ZFUNC),                      state_zfunc         },
2777     { /* 24, WINED3DRS_ALPHAREF                     */      STATE_RENDER(WINED3DRS_ALPHATESTENABLE),            state_alpha         },
2778     { /* 25, WINED3DRS_ALPHAFUNC                    */      STATE_RENDER(WINED3DRS_ALPHATESTENABLE),            state_alpha         },
2779     { /* 26, WINED3DRS_DITHERENABLE                 */      STATE_RENDER(WINED3DRS_DITHERENABLE),               state_ditherenable  },
2780     { /* 27, WINED3DRS_ALPHABLENDENABLE             */      STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         },
2781     { /* 28, WINED3DRS_FOGENABLE                    */      STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog           },
2782     { /* 29, WINED3DRS_SPECULARENABLE               */      STATE_RENDER(WINED3DRS_SPECULARENABLE),             state_specularenable},
2783     { /* 30, WINED3DRS_ZVISIBLE                     */      0 /* Not supported according to the msdn */,        state_nogl          },
2784     { /* 31, WINED3DRS_SUBPIXEL                     */      STATE_RENDER(WINED3DRS_SUBPIXEL),                   state_subpixel      },
2785     { /* 32, WINED3DRS_SUBPIXELX                    */      STATE_RENDER(WINED3DRS_SUBPIXELX),                  state_subpixelx     },
2786     { /* 33, WINED3DRS_STIPPLEDALPHA                */      STATE_RENDER(WINED3DRS_STIPPLEDALPHA),              state_stippledalpha },
2787     { /* 34, WINED3DRS_FOGCOLOR                     */      STATE_RENDER(WINED3DRS_FOGCOLOR),                   state_fogcolor      },
2788     { /* 35, WINED3DRS_FOGTABLEMODE                 */      STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog           },
2789     { /* 36, WINED3DRS_FOGSTART                     */      STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog           },
2790     { /* 37, WINED3DRS_FOGEND                       */      STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog           },
2791     { /* 38, WINED3DRS_FOGDENSITY                   */      STATE_RENDER(WINED3DRS_FOGDENSITY),                 state_fogdensity    },
2792     { /* 39, WINED3DRS_STIPPLEENABLE                */      STATE_RENDER(WINED3DRS_STIPPLEENABLE),              state_stippleenable },
2793     { /* 40, WINED3DRS_EDGEANTIALIAS                */      STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         },
2794     { /* 41, WINED3DRS_COLORKEYENABLE               */      STATE_RENDER(WINED3DRS_ALPHATESTENABLE),            state_alpha         },
2795     { /* 42, undefined                              */      0,                                                  state_undefined     },
2796     { /* 43, WINED3DRS_BORDERCOLOR                  */      STATE_RENDER(WINED3DRS_BORDERCOLOR),                state_bordercolor   },
2797     { /* 44, WINED3DRS_TEXTUREADDRESSU              */      0, /* Handled in ddraw */                           state_undefined     },
2798     { /* 45, WINED3DRS_TEXTUREADDRESSV              */      0, /* Handled in ddraw */                           state_undefined     },
2799     { /* 46, WINED3DRS_MIPMAPLODBIAS                */      STATE_RENDER(WINED3DRS_MIPMAPLODBIAS),              state_mipmaplodbias },
2800     { /* 47, WINED3DRS_ZBIAS                        */      STATE_RENDER(WINED3DRS_ZBIAS),                      state_zbias         },
2801     { /* 48, WINED3DRS_RANGEFOGENABLE               */      0,                                                  state_nogl          },
2802     { /* 49, WINED3DRS_ANISOTROPY                   */      STATE_RENDER(WINED3DRS_ANISOTROPY),                 state_anisotropy    },
2803     { /* 50, WINED3DRS_FLUSHBATCH                   */      STATE_RENDER(WINED3DRS_FLUSHBATCH),                 state_flushbatch    },
2804     { /* 51, WINED3DRS_TRANSLUCENTSORTINDEPENDENT   */      STATE_RENDER(WINED3DRS_TRANSLUCENTSORTINDEPENDENT), state_translucentsi },
2805     { /* 52, WINED3DRS_STENCILENABLE                */      STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       },
2806     { /* 53, WINED3DRS_STENCILFAIL                  */      STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       },
2807     { /* 54, WINED3DRS_STENCILZFAIL                 */      STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       },
2808     { /* 55, WINED3DRS_STENCILPASS                  */      STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       },
2809     { /* 56, WINED3DRS_STENCILFUNC                  */      STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       },
2810     { /* 57, WINED3DRS_STENCILREF                   */      STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       },
2811     { /* 58, WINED3DRS_STENCILMASK                  */      STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       },
2812     { /* 59, WINED3DRS_STENCILWRITEMASK             */      STATE_RENDER(WINED3DRS_STENCILWRITEMASK),           state_stencilwrite  },
2813     { /* 60, WINED3DRS_TEXTUREFACTOR                */      STATE_RENDER(WINED3DRS_TEXTUREFACTOR),              state_texfactor     },
2814     { /* 61, Undefined                              */      0,                                                  state_undefined     },
2815     { /* 62, Undefined                              */      0,                                                  state_undefined     },
2816     { /* 63, Undefined                              */      0,                                                  state_undefined     },
2817     { /* 64, WINED3DRS_STIPPLEPATTERN00             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
2818     { /* 65, WINED3DRS_STIPPLEPATTERN01             */      0 /* Obsolete, should he handled by ddraw */,       state_undefined     },
2819     { /* 66, WINED3DRS_STIPPLEPATTERN02             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
2820     { /* 67, WINED3DRS_STIPPLEPATTERN03             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
2821     { /* 68, WINED3DRS_STIPPLEPATTERN04             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
2822     { /* 69, WINED3DRS_STIPPLEPATTERN05             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
2823     { /* 70, WINED3DRS_STIPPLEPATTERN06             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
2824     { /* 71, WINED3DRS_STIPPLEPATTERN07             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
2825     { /* 72, WINED3DRS_STIPPLEPATTERN08             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
2826     { /* 73, WINED3DRS_STIPPLEPATTERN09             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
2827     { /* 74, WINED3DRS_STIPPLEPATTERN10             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
2828     { /* 75, WINED3DRS_STIPPLEPATTERN11             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
2829     { /* 76, WINED3DRS_STIPPLEPATTERN12             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
2830     { /* 77, WINED3DRS_STIPPLEPATTERN13             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
2831     { /* 78, WINED3DRS_STIPPLEPATTERN14             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
2832     { /* 79, WINED3DRS_STIPPLEPATTERN15             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
2833     { /* 80, WINED3DRS_STIPPLEPATTERN16             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
2834     { /* 81, WINED3DRS_STIPPLEPATTERN17             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
2835     { /* 82, WINED3DRS_STIPPLEPATTERN18             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
2836     { /* 83, WINED3DRS_STIPPLEPATTERN19             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
2837     { /* 84, WINED3DRS_STIPPLEPATTERN20             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
2838     { /* 85, WINED3DRS_STIPPLEPATTERN21             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
2839     { /* 86, WINED3DRS_STIPPLEPATTERN22             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
2840     { /* 87, WINED3DRS_STIPPLEPATTERN23             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
2841     { /* 88, WINED3DRS_STIPPLEPATTERN24             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
2842     { /* 89, WINED3DRS_STIPPLEPATTERN25             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
2843     { /* 90, WINED3DRS_STIPPLEPATTERN26             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
2844     { /* 91, WINED3DRS_STIPPLEPATTERN27             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
2845     { /* 92, WINED3DRS_STIPPLEPATTERN28             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
2846     { /* 93, WINED3DRS_STIPPLEPATTERN29             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
2847     { /* 94, WINED3DRS_STIPPLEPATTERN30             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
2848     { /* 95, WINED3DRS_STIPPLEPATTERN31             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
2849     { /* 96, Undefined                              */      0,                                                  state_undefined     },
2850     { /* 97, Undefined                              */      0,                                                  state_undefined     },
2851     { /* 98, Undefined                              */      0,                                                  state_undefined     },
2852     { /* 99, Undefined                              */      0,                                                  state_undefined     },
2853     { /*100, Undefined                              */      0,                                                  state_undefined     },
2854     { /*101, Undefined                              */      0,                                                  state_undefined     },
2855     { /*102, Undefined                              */      0,                                                  state_undefined     },
2856     { /*103, Undefined                              */      0,                                                  state_undefined     },
2857     { /*104, Undefined                              */      0,                                                  state_undefined     },
2858     { /*105, Undefined                              */      0,                                                  state_undefined     },
2859     { /*106, Undefined                              */      0,                                                  state_undefined     },
2860     { /*107, Undefined                              */      0,                                                  state_undefined     },
2861     { /*108, Undefined                              */      0,                                                  state_undefined     },
2862     { /*109, Undefined                              */      0,                                                  state_undefined     },
2863     { /*110, Undefined                              */      0,                                                  state_undefined     },
2864     { /*111, Undefined                              */      0,                                                  state_undefined     },
2865     { /*112, Undefined                              */      0,                                                  state_undefined     },
2866     { /*113, Undefined                              */      0,                                                  state_undefined     },
2867     { /*114, Undefined                              */      0,                                                  state_undefined     },
2868     { /*115, Undefined                              */      0,                                                  state_undefined     },
2869     { /*116, Undefined                              */      0,                                                  state_undefined     },
2870     { /*117, Undefined                              */      0,                                                  state_undefined     },
2871     { /*118, Undefined                              */      0,                                                  state_undefined     },
2872     { /*119, Undefined                              */      0,                                                  state_undefined     },
2873     { /*120, Undefined                              */      0,                                                  state_undefined     },
2874     { /*121, Undefined                              */      0,                                                  state_undefined     },
2875     { /*122, Undefined                              */      0,                                                  state_undefined     },
2876     { /*123, Undefined                              */      0,                                                  state_undefined     },
2877     { /*124, Undefined                              */      0,                                                  state_undefined     },
2878     { /*125, Undefined                              */      0,                                                  state_undefined     },
2879     { /*126, Undefined                              */      0,                                                  state_undefined     },
2880     { /*127, Undefined                              */      0,                                                  state_undefined     },
2881     /* Big hole ends */
2882     { /*128, WINED3DRS_WRAP0                        */      STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          },
2883     { /*129, WINED3DRS_WRAP1                        */      STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          },
2884     { /*130, WINED3DRS_WRAP2                        */      STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          },
2885     { /*131, WINED3DRS_WRAP3                        */      STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          },
2886     { /*132, WINED3DRS_WRAP4                        */      STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          },
2887     { /*133, WINED3DRS_WRAP5                        */      STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          },
2888     { /*134, WINED3DRS_WRAP6                        */      STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          },
2889     { /*135, WINED3DRS_WRAP7                        */      STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          },
2890     { /*136, WINED3DRS_CLIPPING                     */      STATE_RENDER(WINED3DRS_CLIPPING),                   state_clipping      },
2891     { /*137, WINED3DRS_LIGHTING                     */      STATE_RENDER(WINED3DRS_LIGHTING),                   state_lighting      },
2892     { /*138, WINED3DRS_EXTENTS                      */      STATE_RENDER(WINED3DRS_EXTENTS),                    state_extents       },
2893     { /*139, WINED3DRS_AMBIENT                      */      STATE_RENDER(WINED3DRS_AMBIENT),                    state_ambient       },
2894     { /*140, WINED3DRS_FOGVERTEXMODE                */      STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog           },
2895     { /*141, WINED3DRS_COLORVERTEX                  */      STATE_RENDER(WINED3DRS_COLORVERTEX),                state_colormat      },
2896     { /*142, WINED3DRS_LOCALVIEWER                  */      STATE_RENDER(WINED3DRS_LOCALVIEWER),                state_localviewer   },
2897     { /*143, WINED3DRS_NORMALIZENORMALS             */      STATE_RENDER(WINED3DRS_NORMALIZENORMALS),           state_normalize     },
2898     { /*144, WINED3DRS_COLORKEYBLENDENABLE          */      STATE_RENDER(WINED3DRS_COLORKEYBLENDENABLE),        state_ckeyblend     },
2899     { /*145, WINED3DRS_DIFFUSEMATERIALSOURCE        */      STATE_RENDER(WINED3DRS_COLORVERTEX),                state_colormat      },
2900     { /*146, WINED3DRS_SPECULARMATERIALSOURCE       */      STATE_RENDER(WINED3DRS_COLORVERTEX),                state_colormat      },
2901     { /*147, WINED3DRS_AMBIENTMATERIALSOURCE        */      STATE_RENDER(WINED3DRS_COLORVERTEX),                state_colormat      },
2902     { /*148, WINED3DRS_EMISSIVEMATERIALSOURCE       */      STATE_RENDER(WINED3DRS_COLORVERTEX),                state_colormat      },
2903     { /*149, Undefined                              */      0,                                                  state_undefined     },
2904     { /*150, Undefined                              */      0,                                                  state_undefined     },
2905     { /*151, WINED3DRS_VERTEXBLEND                  */      0,                                                  state_nogl          },
2906     { /*152, WINED3DRS_CLIPPLANEENABLE              */      STATE_RENDER(WINED3DRS_CLIPPING),                   state_clipping      },
2907     { /*153, WINED3DRS_SOFTWAREVERTEXPROCESSING     */      0,                                                  state_nogl          },
2908     { /*154, WINED3DRS_POINTSIZE                    */      STATE_RENDER(WINED3DRS_POINTSIZE),                  state_psize         },
2909     { /*155, WINED3DRS_POINTSIZE_MIN                */      STATE_RENDER(WINED3DRS_POINTSIZE_MIN),              state_psizemin      },
2910     { /*156, WINED3DRS_POINTSPRITEENABLE            */      STATE_RENDER(WINED3DRS_POINTSPRITEENABLE),          state_pointsprite   },
2911     { /*157, WINED3DRS_POINTSCALEENABLE             */      STATE_RENDER(WINED3DRS_POINTSCALEENABLE),           state_pscale        },
2912     { /*158, WINED3DRS_POINTSCALE_A                 */      STATE_RENDER(WINED3DRS_POINTSCALEENABLE),           state_pscale        },
2913     { /*159, WINED3DRS_POINTSCALE_B                 */      STATE_RENDER(WINED3DRS_POINTSCALEENABLE),           state_pscale        },
2914     { /*160, WINED3DRS_POINTSCALE_C                 */      STATE_RENDER(WINED3DRS_POINTSCALEENABLE),           state_pscale        },
2915     { /*161, WINED3DRS_MULTISAMPLEANTIALIAS         */      STATE_RENDER(WINED3DRS_MULTISAMPLEANTIALIAS),       state_multisampleaa },
2916     { /*162, WINED3DRS_MULTISAMPLEMASK              */      STATE_RENDER(WINED3DRS_MULTISAMPLEMASK),            state_multisampmask },
2917     { /*163, WINED3DRS_PATCHEDGESTYLE               */      STATE_RENDER(WINED3DRS_PATCHEDGESTYLE),             state_patchedgestyle},
2918     { /*164, WINED3DRS_PATCHSEGMENTS                */      STATE_RENDER(WINED3DRS_PATCHSEGMENTS),              state_patchsegments },
2919     { /*165, WINED3DRS_DEBUGMONITORTOKEN            */      STATE_RENDER(WINED3DRS_DEBUGMONITORTOKEN),          state_nogl          },
2920     { /*166, WINED3DRS_POINTSIZE_MAX                */      STATE_RENDER(WINED3DRS_POINTSIZE_MAX),              state_psizemax      },
2921     { /*167, WINED3DRS_INDEXEDVERTEXBLENDENABLE     */      0,                                                  state_nogl          },
2922     { /*168, WINED3DRS_COLORWRITEENABLE             */      STATE_RENDER(WINED3DRS_COLORWRITEENABLE),           state_colorwrite    },
2923     { /*169, Undefined                              */      0,                                                  state_undefined     },
2924     { /*170, WINED3DRS_TWEENFACTOR                  */      0,                                                  state_nogl          },
2925     { /*171, WINED3DRS_BLENDOP                      */      STATE_RENDER(WINED3DRS_BLENDOP),                    state_blendop       },
2926     { /*172, WINED3DRS_POSITIONDEGREE               */      STATE_RENDER(WINED3DRS_POSITIONDEGREE),             state_positiondegree},
2927     { /*173, WINED3DRS_NORMALDEGREE                 */      STATE_RENDER(WINED3DRS_NORMALDEGREE),               state_normaldegree  },
2928       /*172, WINED3DRS_POSITIONORDER                */      /* Value assigned to 2 state names */
2929       /*173, WINED3DRS_NORMALORDER                  */      /* Value assigned to 2 state names */
2930     { /*174, WINED3DRS_SCISSORTESTENABLE            */      STATE_RENDER(WINED3DRS_SCISSORTESTENABLE),          state_scissor       },
2931     { /*175, WINED3DRS_SLOPESCALEDEPTHBIAS          */      STATE_RENDER(WINED3DRS_DEPTHBIAS),                  state_depthbias     },
2932     { /*176, WINED3DRS_ANTIALIASEDLINEENABLE        */      STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         },
2933     { /*177, undefined                              */      0,                                                  state_undefined     },
2934     { /*178, WINED3DRS_MINTESSELLATIONLEVEL         */      STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation  },
2935     { /*179, WINED3DRS_MAXTESSELLATIONLEVEL         */      STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation  },
2936     { /*180, WINED3DRS_ADAPTIVETESS_X               */      STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation  },
2937     { /*181, WINED3DRS_ADAPTIVETESS_Y               */      STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation  },
2938     { /*182, WINED3DRS_ADAPTIVETESS_Z               */      STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation  },
2939     { /*183, WINED3DRS_ADAPTIVETESS_W               */      STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation  },
2940     { /*184, WINED3DRS_ENABLEADAPTIVETESSELLATION   */      STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation  },
2941     { /*185, WINED3DRS_TWOSIDEDSTENCILMODE          */      STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       },
2942     { /*186, WINED3DRS_CCW_STENCILFAIL              */      STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       },
2943     { /*187, WINED3DRS_CCW_STENCILZFAIL             */      STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       },
2944     { /*188, WINED3DRS_CCW_STENCILPASS              */      STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       },
2945     { /*189, WINED3DRS_CCW_STENCILFUNC              */      STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       },
2946     { /*190, WINED3DRS_COLORWRITEENABLE1            */      STATE_RENDER(WINED3DRS_COLORWRITEENABLE),           state_colorwrite    },
2947     { /*191, WINED3DRS_COLORWRITEENABLE2            */      STATE_RENDER(WINED3DRS_COLORWRITEENABLE),           state_colorwrite    },
2948     { /*192, WINED3DRS_COLORWRITEENABLE3            */      STATE_RENDER(WINED3DRS_COLORWRITEENABLE),           state_colorwrite    },
2949     { /*193, WINED3DRS_BLENDFACTOR                  */      STATE_RENDER(WINED3DRS_BLENDFACTOR),                state_blendfactor   },
2950     { /*194, WINED3DRS_SRGBWRITEENABLE              */      STATE_RENDER(WINED3DRS_SRGBWRITEENABLE),            state_srgbwrite     },
2951     { /*195, WINED3DRS_DEPTHBIAS                    */      STATE_RENDER(WINED3DRS_DEPTHBIAS),                  state_depthbias     },
2952     { /*196, undefined                              */      0,                                                  state_undefined     },
2953     { /*197, undefined                              */      0,                                                  state_undefined     },
2954     { /*198, WINED3DRS_WRAP8                        */      STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          },
2955     { /*199, WINED3DRS_WRAP9                        */      STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          },
2956     { /*200, WINED3DRS_WRAP10                       */      STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          },
2957     { /*201, WINED3DRS_WRAP11                       */      STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          },
2958     { /*202, WINED3DRS_WRAP12                       */      STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          },
2959     { /*203, WINED3DRS_WRAP13                       */      STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          },
2960     { /*204, WINED3DRS_WRAP14                       */      STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          },
2961     { /*205, WINED3DRS_WRAP15                       */      STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          },
2962     { /*206, WINED3DRS_SEPARATEALPHABLENDENABLE     */      STATE_RENDER(WINED3DRS_SEPARATEALPHABLENDENABLE),   state_seperateblend },
2963     { /*207, WINED3DRS_SRCBLENDALPHA                */      STATE_RENDER(WINED3DRS_SEPARATEALPHABLENDENABLE),   state_seperateblend },
2964     { /*208, WINED3DRS_DESTBLENDALPHA               */      STATE_RENDER(WINED3DRS_SEPARATEALPHABLENDENABLE),   state_seperateblend },
2965     { /*209, WINED3DRS_BLENDOPALPHA                 */      STATE_RENDER(WINED3DRS_SEPARATEALPHABLENDENABLE),   state_seperateblend },
2966     /* Texture stage states */
2967     { /*0, 01, WINED3DTSS_COLOROP                   */      STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          tex_colorop         },
2968     { /*0, 02, WINED3DTSS_COLORARG1                 */      STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          tex_colorop         },
2969     { /*0, 03, WINED3DTSS_COLORARG2                 */      STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          tex_colorop         },
2970     { /*0, 04, WINED3DTSS_ALPHAOP                   */      STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP),          tex_alphaop         },
2971     { /*0, 05, WINED3DTSS_ALPHAARG1                 */      STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP),          tex_alphaop         },
2972     { /*0, 06, WINED3DTSS_ALPHAARG2                 */      STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP),          tex_alphaop         },
2973     { /*0, 07, WINED3DTSS_BUMPENVMAT00              */      STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          tex_colorop         },
2974     { /*0, 08, WINED3DTSS_BUMPENVMAT01              */      STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          tex_colorop         },
2975     { /*0, 09, WINED3DTSS_BUMPENVMAT10              */      STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          tex_colorop         },
2976     { /*0, 10, WINED3DTSS_BUMPENVMAT11              */      STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          tex_colorop         },
2977     { /*0, 11, WINED3DTSS_TEXCOORDINDEX             */      STATE_TEXTURESTAGE(0, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      },
2978     { /*0, 12, WINED3DTSS_ADDRESS                   */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
2979     { /*0, 13, WINED3DTSS_ADDRESSU                  */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
2980     { /*0, 14, WINED3DTSS_ADDRESSV                  */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
2981     { /*0, 15, WINED3DTSS_BORDERCOLOR               */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
2982     { /*0, 16, WINED3DTSS_MAGFILTER                 */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
2983     { /*0, 17, WINED3DTSS_MINFILTER                 */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
2984     { /*0, 18, WINED3DTSS_MIPFILTER                 */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
2985     { /*0, 19, WINED3DTSS_MIPMAPLODBIAS             */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
2986     { /*0, 20, WINED3DTSS_MAXMIPLEVEL               */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
2987     { /*0, 21, WINED3DTSS_MAXANISOTROPY             */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
2988     { /*0, 22, WINED3DTSS_BUMPENVLSCALE             */      STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   },
2989     { /*0, 23, WINED3DTSS_BUMPENVLOFFSET            */      STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLOFFSET),   tex_bumpenvloffset  },
2990     { /*0, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS     */      STATE_TRANSFORM(WINED3DTS_TEXTURE0),                transform_texture   },
2991     { /*0, 25, WINED3DTSS_ADDRESSW                  */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
2992     { /*0, 26, WINED3DTSS_COLORARG0                 */      STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          tex_colorop         },
2993     { /*0, 27, WINED3DTSS_ALPHAARG0                 */      STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP),          tex_alphaop         },
2994     { /*0, 28, WINED3DTSS_RESULTARG                 */      STATE_TEXTURESTAGE(0, WINED3DTSS_RESULTARG),        tex_resultarg       },
2995     { /*0, 29, undefined                            */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
2996     { /*0, 30, undefined                            */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
2997     { /*0, 31, undefined                            */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
2998     { /*0, 32, WINED3DTSS_CONSTANT                  */      0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl          },
2999
3000     { /*1, 01, WINED3DTSS_COLOROP                   */      STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP),          tex_colorop         },
3001     { /*1, 02, WINED3DTSS_COLORARG1                 */      STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP),          tex_colorop         },
3002     { /*1, 03, WINED3DTSS_COLORARG2                 */      STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP),          tex_colorop         },
3003     { /*1, 04, WINED3DTSS_ALPHAOP                   */      STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3004     { /*1, 05, WINED3DTSS_ALPHAARG1                 */      STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3005     { /*1, 06, WINED3DTSS_ALPHAARG2                 */      STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3006     { /*1, 07, WINED3DTSS_BUMPENVMAT00              */      STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP),          tex_colorop         },
3007     { /*1, 08, WINED3DTSS_BUMPENVMAT01              */      STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP),          tex_colorop         },
3008     { /*1, 09, WINED3DTSS_BUMPENVMAT10              */      STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP),          tex_colorop         },
3009     { /*1, 10, WINED3DTSS_BUMPENVMAT11              */      STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP),          tex_colorop         },
3010     { /*1, 11, WINED3DTSS_TEXCOORDINDEX             */      STATE_TEXTURESTAGE(1, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      },
3011     { /*1, 12, WINED3DTSS_ADDRESS                   */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3012     { /*1, 13, WINED3DTSS_ADDRESSU                  */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3013     { /*1, 14, WINED3DTSS_ADDRESSV                  */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3014     { /*1, 15, WINED3DTSS_BORDERCOLOR               */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3015     { /*1, 16, WINED3DTSS_MAGFILTER                 */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3016     { /*1, 17, WINED3DTSS_MINFILTER                 */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3017     { /*1, 18, WINED3DTSS_MIPFILTER                 */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3018     { /*1, 19, WINED3DTSS_MIPMAPLODBIAS             */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3019     { /*1, 20, WINED3DTSS_MAXMIPLEVEL               */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3020     { /*1, 21, WINED3DTSS_MAXANISOTROPY             */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3021     { /*1, 22, WINED3DTSS_BUMPENVLSCALE             */      STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   },
3022     { /*1, 23, WINED3DTSS_BUMPENVLOFFSET            */      STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLOFFSET),   tex_bumpenvloffset  },
3023     { /*1, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS     */      STATE_TRANSFORM(WINED3DTS_TEXTURE1),                transform_texture   },
3024     { /*1, 25, WINED3DTSS_ADDRESSW                  */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3025     { /*1, 26, WINED3DTSS_COLORARG0                 */      STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP),          tex_colorop         },
3026     { /*1, 27, WINED3DTSS_ALPHAARG0                 */      STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3027     { /*1, 28, WINED3DTSS_RESULTARG                 */      STATE_TEXTURESTAGE(1, WINED3DTSS_RESULTARG),        tex_resultarg       },
3028     { /*1, 29, undefined                            */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3029     { /*1, 30, undefined                            */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3030     { /*1, 31, undefined                            */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3031     { /*1, 32, WINED3DTSS_CONSTANT                  */      0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl          },
3032
3033     { /*2, 01, WINED3DTSS_COLOROP                   */      STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP),          tex_colorop         },
3034     { /*2, 02, WINED3DTSS_COLORARG1                 */      STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP),          tex_colorop         },
3035     { /*2, 03, WINED3DTSS_COLORARG2                 */      STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP),          tex_colorop         },
3036     { /*2, 04, WINED3DTSS_ALPHAOP                   */      STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3037     { /*2, 05, WINED3DTSS_ALPHAARG1                 */      STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3038     { /*2, 06, WINED3DTSS_ALPHAARG2                 */      STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3039     { /*2, 07, WINED3DTSS_BUMPENVMAT00              */      STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP),          tex_colorop         },
3040     { /*2, 08, WINED3DTSS_BUMPENVMAT01              */      STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP),          tex_colorop         },
3041     { /*2, 09, WINED3DTSS_BUMPENVMAT10              */      STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP),          tex_colorop         },
3042     { /*2, 10, WINED3DTSS_BUMPENVMAT11              */      STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP),          tex_colorop         },
3043     { /*2, 11, WINED3DTSS_TEXCOORDINDEX             */      STATE_TEXTURESTAGE(2, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      },
3044     { /*2, 12, WINED3DTSS_ADDRESS                   */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3045     { /*2, 13, WINED3DTSS_ADDRESSU                  */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3046     { /*2, 14, WINED3DTSS_ADDRESSV                  */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3047     { /*2, 15, WINED3DTSS_BORDERCOLOR               */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3048     { /*2, 16, WINED3DTSS_MAGFILTER                 */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3049     { /*2, 17, WINED3DTSS_MINFILTER                 */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3050     { /*2, 18, WINED3DTSS_MIPFILTER                 */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3051     { /*2, 19, WINED3DTSS_MIPMAPLODBIAS             */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3052     { /*2, 20, WINED3DTSS_MAXMIPLEVEL               */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3053     { /*2, 21, WINED3DTSS_MAXANISOTROPY             */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3054     { /*2, 22, WINED3DTSS_BUMPENVLSCALE             */      STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   },
3055     { /*2, 23, WINED3DTSS_BUMPENVLOFFSET            */      STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLOFFSET),   tex_bumpenvloffset  },
3056     { /*2, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS     */      STATE_TRANSFORM(WINED3DTS_TEXTURE2),                transform_texture   },
3057     { /*2, 25, WINED3DTSS_ADDRESSW                  */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3058     { /*2, 26, WINED3DTSS_COLORARG0                 */      STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP),          tex_colorop         },
3059     { /*2, 27, WINED3DTSS_ALPHAARG0                 */      STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3060     { /*2, 28, WINED3DTSS_RESULTARG                 */      STATE_TEXTURESTAGE(2, WINED3DTSS_RESULTARG),        tex_resultarg       },
3061     { /*2, 29, undefined                            */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3062     { /*2, 30, undefined                            */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3063     { /*2, 31, undefined                            */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3064     { /*2, 32, WINED3DTSS_CONSTANT                  */      0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl          },
3065
3066     { /*3, 01, WINED3DTSS_COLOROP                   */      STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP),          tex_colorop         },
3067     { /*3, 02, WINED3DTSS_COLORARG1                 */      STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP),          tex_colorop         },
3068     { /*3, 03, WINED3DTSS_COLORARG2                 */      STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP),          tex_colorop         },
3069     { /*3, 04, WINED3DTSS_ALPHAOP                   */      STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3070     { /*3, 05, WINED3DTSS_ALPHAARG1                 */      STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3071     { /*3, 06, WINED3DTSS_ALPHAARG2                 */      STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3072     { /*3, 07, WINED3DTSS_BUMPENVMAT00              */      STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP),          tex_colorop         },
3073     { /*3, 08, WINED3DTSS_BUMPENVMAT01              */      STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP),          tex_colorop         },
3074     { /*3, 09, WINED3DTSS_BUMPENVMAT10              */      STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP),          tex_colorop         },
3075     { /*3, 10, WINED3DTSS_BUMPENVMAT11              */      STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP),          tex_colorop         },
3076     { /*3, 11, WINED3DTSS_TEXCOORDINDEX             */      STATE_TEXTURESTAGE(3, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      },
3077     { /*3, 12, WINED3DTSS_ADDRESS                   */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3078     { /*3, 13, WINED3DTSS_ADDRESSU                  */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3079     { /*3, 14, WINED3DTSS_ADDRESSV                  */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3080     { /*3, 15, WINED3DTSS_BORDERCOLOR               */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3081     { /*3, 16, WINED3DTSS_MAGFILTER                 */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3082     { /*3, 17, WINED3DTSS_MINFILTER                 */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3083     { /*3, 18, WINED3DTSS_MIPFILTER                 */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3084     { /*3, 19, WINED3DTSS_MIPMAPLODBIAS             */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3085     { /*3, 20, WINED3DTSS_MAXMIPLEVEL               */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3086     { /*3, 21, WINED3DTSS_MAXANISOTROPY             */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3087     { /*3, 22, WINED3DTSS_BUMPENVLSCALE             */      STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   },
3088     { /*3, 23, WINED3DTSS_BUMPENVLOFFSET            */      STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLOFFSET),   tex_bumpenvloffset  },
3089     { /*3, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS     */      STATE_TRANSFORM(WINED3DTS_TEXTURE3),                transform_texture   },
3090     { /*3, 25, WINED3DTSS_ADDRESSW                  */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3091     { /*3, 26, WINED3DTSS_COLORARG0                 */      STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP),          tex_colorop         },
3092     { /*3, 27, WINED3DTSS_ALPHAARG0                 */      STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3093     { /*3, 28, WINED3DTSS_RESULTARG                 */      STATE_TEXTURESTAGE(3, WINED3DTSS_RESULTARG),        tex_resultarg       },
3094     { /*3, 29, undefined                            */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3095     { /*3, 30, undefined                            */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3096     { /*3, 31, undefined                            */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3097     { /*3, 32, WINED3DTSS_CONSTANT                  */      0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl          },
3098
3099     { /*4, 01, WINED3DTSS_COLOROP                   */      STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP),          tex_colorop         },
3100     { /*4, 02, WINED3DTSS_COLORARG1                 */      STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP),          tex_colorop         },
3101     { /*4, 03, WINED3DTSS_COLORARG2                 */      STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP),          tex_colorop         },
3102     { /*4, 04, WINED3DTSS_ALPHAOP                   */      STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3103     { /*4, 05, WINED3DTSS_ALPHAARG1                 */      STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3104     { /*4, 06, WINED3DTSS_ALPHAARG2                 */      STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3105     { /*4, 07, WINED3DTSS_BUMPENVMAT00              */      STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP),          state_undefined     },
3106     { /*4, 08, WINED3DTSS_BUMPENVMAT01              */      STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP),          state_undefined     },
3107     { /*4, 09, WINED3DTSS_BUMPENVMAT10              */      STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP),          state_undefined     },
3108     { /*4, 10, WINED3DTSS_BUMPENVMAT11              */      STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP),          state_undefined     },
3109     { /*4, 11, WINED3DTSS_TEXCOORDINDEX             */      STATE_TEXTURESTAGE(4, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      },
3110     { /*4, 12, WINED3DTSS_ADDRESS                   */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3111     { /*4, 13, WINED3DTSS_ADDRESSU                  */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3112     { /*4, 14, WINED3DTSS_ADDRESSV                  */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3113     { /*4, 15, WINED3DTSS_BORDERCOLOR               */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3114     { /*4, 16, WINED3DTSS_MAGFILTER                 */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3115     { /*4, 17, WINED3DTSS_MINFILTER                 */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3116     { /*4, 18, WINED3DTSS_MIPFILTER                 */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3117     { /*4, 19, WINED3DTSS_MIPMAPLODBIAS             */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3118     { /*4, 20, WINED3DTSS_MAXMIPLEVEL               */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3119     { /*4, 21, WINED3DTSS_MAXANISOTROPY             */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3120     { /*4, 22, WINED3DTSS_BUMPENVLSCALE             */      STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   },
3121     { /*4, 23, WINED3DTSS_BUMPENVLOFFSET            */      STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLOFFSET),   tex_bumpenvloffset  },
3122     { /*4, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS     */      STATE_TRANSFORM(WINED3DTS_TEXTURE4),                transform_texture   },
3123     { /*4, 25, WINED3DTSS_ADDRESSW                  */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3124     { /*4, 26, WINED3DTSS_COLORARG0                 */      STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP),          tex_colorop         },
3125     { /*4, 27, WINED3DTSS_ALPHAARG0                 */      STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3126     { /*4, 28, WINED3DTSS_RESULTARG                 */      STATE_TEXTURESTAGE(4, WINED3DTSS_RESULTARG),        tex_resultarg       },
3127     { /*4, 29, undefined                            */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3128     { /*4, 30, undefined                            */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3129     { /*4, 31, undefined                            */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3130     { /*4, 32, WINED3DTSS_CONSTANT                  */      0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl          },
3131
3132     { /*5, 01, WINED3DTSS_COLOROP                   */      STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP),          tex_colorop         },
3133     { /*5, 02, WINED3DTSS_COLORARG1                 */      STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP),          tex_colorop         },
3134     { /*5, 03, WINED3DTSS_COLORARG2                 */      STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP),          tex_colorop         },
3135     { /*5, 04, WINED3DTSS_ALPHAOP                   */      STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3136     { /*5, 05, WINED3DTSS_ALPHAARG1                 */      STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3137     { /*5, 06, WINED3DTSS_ALPHAARG2                 */      STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3138     { /*5, 07, WINED3DTSS_BUMPENVMAT00              */      STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP),          tex_colorop         },
3139     { /*5, 08, WINED3DTSS_BUMPENVMAT01              */      STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP),          tex_colorop         },
3140     { /*5, 09, WINED3DTSS_BUMPENVMAT10              */      STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP),          tex_colorop         },
3141     { /*5, 10, WINED3DTSS_BUMPENVMAT11              */      STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP),          tex_colorop         },
3142     { /*5, 11, WINED3DTSS_TEXCOORDINDEX             */      STATE_TEXTURESTAGE(5, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      },
3143     { /*5, 12, WINED3DTSS_ADDRESS                   */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3144     { /*5, 13, WINED3DTSS_ADDRESSU                  */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3145     { /*5, 14, WINED3DTSS_ADDRESSV                  */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3146     { /*5, 15, WINED3DTSS_BORDERCOLOR               */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3147     { /*5, 16, WINED3DTSS_MAGFILTER                 */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3148     { /*5, 17, WINED3DTSS_MINFILTER                 */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3149     { /*5, 18, WINED3DTSS_MIPFILTER                 */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3150     { /*5, 19, WINED3DTSS_MIPMAPLODBIAS             */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3151     { /*5, 20, WINED3DTSS_MAXMIPLEVEL               */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3152     { /*5, 21, WINED3DTSS_MAXANISOTROPY             */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3153     { /*5, 22, WINED3DTSS_BUMPENVLSCALE             */      STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   },
3154     { /*5, 23, WINED3DTSS_BUMPENVLOFFSET            */      STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLOFFSET),   tex_bumpenvloffset  },
3155     { /*5, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS     */      STATE_TRANSFORM(WINED3DTS_TEXTURE5),                transform_texture   },
3156     { /*5, 25, WINED3DTSS_ADDRESSW                  */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3157     { /*5, 26, WINED3DTSS_COLORARG0                 */      STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP),          tex_colorop         },
3158     { /*5, 27, WINED3DTSS_ALPHAARG0                 */      STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3159     { /*5, 28, WINED3DTSS_RESULTARG                 */      STATE_TEXTURESTAGE(5, WINED3DTSS_RESULTARG),        tex_resultarg       },
3160     { /*5, 29, undefined                            */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3161     { /*5, 30, undefined                            */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3162     { /*5, 31, undefined                            */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3163     { /*5, 32, WINED3DTSS_CONSTANT                  */      0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl          },
3164
3165     { /*6, 01, WINED3DTSS_COLOROP                   */      STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP),          tex_colorop         },
3166     { /*6, 02, WINED3DTSS_COLORARG1                 */      STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP),          tex_colorop         },
3167     { /*6, 03, WINED3DTSS_COLORARG2                 */      STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP),          tex_colorop         },
3168     { /*6, 04, WINED3DTSS_ALPHAOP                   */      STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3169     { /*6, 05, WINED3DTSS_ALPHAARG1                 */      STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3170     { /*6, 06, WINED3DTSS_ALPHAARG2                 */      STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3171     { /*6, 07, WINED3DTSS_BUMPENVMAT00              */      STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP),          tex_colorop         },
3172     { /*6, 08, WINED3DTSS_BUMPENVMAT01              */      STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP),          tex_colorop         },
3173     { /*6, 09, WINED3DTSS_BUMPENVMAT10              */      STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP),          tex_colorop         },
3174     { /*6, 10, WINED3DTSS_BUMPENVMAT11              */      STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP),          tex_colorop         },
3175     { /*6, 11, WINED3DTSS_TEXCOORDINDEX             */      STATE_TEXTURESTAGE(6, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      },
3176     { /*6, 12, WINED3DTSS_ADDRESS                   */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3177     { /*6, 13, WINED3DTSS_ADDRESSU                  */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3178     { /*6, 14, WINED3DTSS_ADDRESSV                  */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3179     { /*6, 15, WINED3DTSS_BORDERCOLOR               */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3180     { /*6, 16, WINED3DTSS_MAGFILTER                 */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3181     { /*6, 17, WINED3DTSS_MINFILTER                 */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3182     { /*6, 18, WINED3DTSS_MIPFILTER                 */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3183     { /*6, 19, WINED3DTSS_MIPMAPLODBIAS             */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3184     { /*6, 20, WINED3DTSS_MAXMIPLEVEL               */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3185     { /*6, 21, WINED3DTSS_MAXANISOTROPY             */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3186     { /*6, 22, WINED3DTSS_BUMPENVLSCALE             */      STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   },
3187     { /*6, 23, WINED3DTSS_BUMPENVLOFFSET            */      STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLOFFSET),   tex_bumpenvloffset  },
3188     { /*6, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS     */      STATE_TRANSFORM(WINED3DTS_TEXTURE6),                transform_texture   },
3189     { /*6, 25, WINED3DTSS_ADDRESSW                  */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3190     { /*6, 26, WINED3DTSS_COLORARG0                 */      STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP),          tex_colorop         },
3191     { /*6, 27, WINED3DTSS_ALPHAARG0                 */      STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3192     { /*6, 28, WINED3DTSS_RESULTARG                 */      STATE_TEXTURESTAGE(6, WINED3DTSS_RESULTARG),        tex_resultarg       },
3193     { /*6, 29, undefined                            */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3194     { /*6, 30, undefined                            */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3195     { /*6, 31, undefined                            */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3196     { /*6, 32, WINED3DTSS_CONSTANT                  */      0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl          },
3197
3198     { /*7, 01, WINED3DTSS_COLOROP                   */      STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP),          tex_colorop         },
3199     { /*7, 02, WINED3DTSS_COLORARG1                 */      STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP),          tex_colorop         },
3200     { /*7, 03, WINED3DTSS_COLORARG2                 */      STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP),          tex_colorop         },
3201     { /*7, 04, WINED3DTSS_ALPHAOP                   */      STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3202     { /*7, 05, WINED3DTSS_ALPHAARG1                 */      STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3203     { /*7, 06, WINED3DTSS_ALPHAARG2                 */      STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3204     { /*7, 07, WINED3DTSS_BUMPENVMAT00              */      STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP),          tex_colorop         },
3205     { /*7, 08, WINED3DTSS_BUMPENVMAT01              */      STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP),          tex_colorop         },
3206     { /*7, 09, WINED3DTSS_BUMPENVMAT10              */      STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP),          tex_colorop         },
3207     { /*7, 10, WINED3DTSS_BUMPENVMAT11              */      STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP),          tex_colorop         },
3208     { /*7, 11, WINED3DTSS_TEXCOORDINDEX             */      STATE_TEXTURESTAGE(7, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      },
3209     { /*7, 12, WINED3DTSS_ADDRESS                   */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3210     { /*7, 13, WINED3DTSS_ADDRESSU                  */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3211     { /*7, 14, WINED3DTSS_ADDRESSV                  */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3212     { /*7, 15, WINED3DTSS_BORDERCOLOR               */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3213     { /*7, 16, WINED3DTSS_MAGFILTER                 */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3214     { /*7, 17, WINED3DTSS_MINFILTER                 */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3215     { /*7, 18, WINED3DTSS_MIPFILTER                 */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3216     { /*7, 19, WINED3DTSS_MIPMAPLODBIAS             */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3217     { /*7, 20, WINED3DTSS_MAXMIPLEVEL               */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3218     { /*7, 21, WINED3DTSS_MAXANISOTROPY             */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3219     { /*7, 22, WINED3DTSS_BUMPENVLSCALE             */      STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   },
3220     { /*7, 23, WINED3DTSS_BUMPENVLOFFSET            */      STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLOFFSET),   tex_bumpenvloffset  },
3221     { /*7, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS     */      STATE_TRANSFORM(WINED3DTS_TEXTURE7),                transform_texture   },
3222     { /*7, 25, WINED3DTSS_ADDRESSW                  */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3223     { /*7, 26, WINED3DTSS_COLORARG0                 */      STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP),          tex_colorop         },
3224     { /*7, 27, WINED3DTSS_ALPHAARG0                 */      STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3225     { /*7, 28, WINED3DTSS_RESULTARG                 */      STATE_TEXTURESTAGE(7, WINED3DTSS_RESULTARG),        tex_resultarg       },
3226     { /*7, 29, undefined                            */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3227     { /*7, 30, undefined                            */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3228     { /*7, 31, undefined                            */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3229     { /*7, 32, WINED3DTSS_CONSTANT                  */      0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl          },
3230     /* Sampler states */
3231     { /* 0, Sampler 0                               */      STATE_SAMPLER(0),                                   sampler             },
3232     { /* 1, Sampler 1                               */      STATE_SAMPLER(1),                                   sampler             },
3233     { /* 2, Sampler 2                               */      STATE_SAMPLER(2),                                   sampler             },
3234     { /* 3, Sampler 3                               */      STATE_SAMPLER(3),                                   sampler             },
3235     { /* 4, Sampler 3                               */      STATE_SAMPLER(4),                                   sampler             },
3236     { /* 5, Sampler 5                               */      STATE_SAMPLER(5),                                   sampler             },
3237     { /* 6, Sampler 6                               */      STATE_SAMPLER(6),                                   sampler             },
3238     { /* 7, Sampler 7                               */      STATE_SAMPLER(7),                                   sampler             },
3239     { /* 8, Sampler 8                               */      STATE_SAMPLER(8),                                   sampler             },
3240     { /* 9, Sampler 9                               */      STATE_SAMPLER(9),                                   sampler             },
3241     { /*10, Sampler 10                              */      STATE_SAMPLER(10),                                  sampler             },
3242     { /*11, Sampler 11                              */      STATE_SAMPLER(11),                                  sampler             },
3243     { /*12, Sampler 12                              */      STATE_SAMPLER(12),                                  sampler             },
3244     { /*13, Sampler 13                              */      STATE_SAMPLER(13),                                  sampler             },
3245     { /*14, Sampler 14                              */      STATE_SAMPLER(14),                                  sampler             },
3246     { /*15, Sampler 15                              */      STATE_SAMPLER(15),                                  sampler             },
3247     /* Pixel shader */
3248     { /*  , Pixel Shader                            */      STATE_PIXELSHADER,                                  pixelshader         },
3249       /* Transform states follow                    */
3250     { /*  1, undefined                              */      0,                                                  state_undefined     },
3251     { /*  2, WINED3DTS_VIEW                         */      STATE_TRANSFORM(WINED3DTS_VIEW),                    transform_view      },
3252     { /*  3, WINED3DTS_PROJECTION                   */      STATE_TRANSFORM(WINED3DTS_PROJECTION),              transform_projection},
3253     { /*  4, undefined                              */      0,                                                  state_undefined     },
3254     { /*  5, undefined                              */      0,                                                  state_undefined     },
3255     { /*  6, undefined                              */      0,                                                  state_undefined     },
3256     { /*  7, undefined                              */      0,                                                  state_undefined     },
3257     { /*  8, undefined                              */      0,                                                  state_undefined     },
3258     { /*  9, undefined                              */      0,                                                  state_undefined     },
3259     { /* 10, undefined                              */      0,                                                  state_undefined     },
3260     { /* 11, undefined                              */      0,                                                  state_undefined     },
3261     { /* 12, undefined                              */      0,                                                  state_undefined     },
3262     { /* 13, undefined                              */      0,                                                  state_undefined     },
3263     { /* 14, undefined                              */      0,                                                  state_undefined     },
3264     { /* 15, undefined                              */      0,                                                  state_undefined     },
3265     { /* 16, WINED3DTS_TEXTURE0                     */      STATE_TRANSFORM(WINED3DTS_TEXTURE0),                transform_texture   },
3266     { /* 17, WINED3DTS_TEXTURE1                     */      STATE_TRANSFORM(WINED3DTS_TEXTURE1),                transform_texture   },
3267     { /* 18, WINED3DTS_TEXTURE2                     */      STATE_TRANSFORM(WINED3DTS_TEXTURE2),                transform_texture   },
3268     { /* 19, WINED3DTS_TEXTURE3                     */      STATE_TRANSFORM(WINED3DTS_TEXTURE3),                transform_texture   },
3269     { /* 20, WINED3DTS_TEXTURE4                     */      STATE_TRANSFORM(WINED3DTS_TEXTURE4),                transform_texture   },
3270     { /* 21, WINED3DTS_TEXTURE5                     */      STATE_TRANSFORM(WINED3DTS_TEXTURE5),                transform_texture   },
3271     { /* 22, WINED3DTS_TEXTURE6                     */      STATE_TRANSFORM(WINED3DTS_TEXTURE6),                transform_texture   },
3272     { /* 23, WINED3DTS_TEXTURE7                     */      STATE_TRANSFORM(WINED3DTS_TEXTURE7),                transform_texture   },
3273       /* A huge gap between TEXTURE7 and WORLDMATRIX(0) :-( But entries are needed to catch then if a broken app sets them */
3274     { /* 24, undefined                              */      0,                                                  state_undefined     },
3275     { /* 25, undefined                              */      0,                                                  state_undefined     },
3276     { /* 26, undefined                              */      0,                                                  state_undefined     },
3277     { /* 27, undefined                              */      0,                                                  state_undefined     },
3278     { /* 28, undefined                              */      0,                                                  state_undefined     },
3279     { /* 29, undefined                              */      0,                                                  state_undefined     },
3280     { /* 30, undefined                              */      0,                                                  state_undefined     },
3281     { /* 31, undefined                              */      0,                                                  state_undefined     },
3282     { /* 32, undefined                              */      0,                                                  state_undefined     },
3283     { /* 33, undefined                              */      0,                                                  state_undefined     },
3284     { /* 34, undefined                              */      0,                                                  state_undefined     },
3285     { /* 35, undefined                              */      0,                                                  state_undefined     },
3286     { /* 36, undefined                              */      0,                                                  state_undefined     },
3287     { /* 37, undefined                              */      0,                                                  state_undefined     },
3288     { /* 38, undefined                              */      0,                                                  state_undefined     },
3289     { /* 39, undefined                              */      0,                                                  state_undefined     },
3290     { /* 40, undefined                              */      0,                                                  state_undefined     },
3291     { /* 41, undefined                              */      0,                                                  state_undefined     },
3292     { /* 42, undefined                              */      0,                                                  state_undefined     },
3293     { /* 43, undefined                              */      0,                                                  state_undefined     },
3294     { /* 44, undefined                              */      0,                                                  state_undefined     },
3295     { /* 45, undefined                              */      0,                                                  state_undefined     },
3296     { /* 46, undefined                              */      0,                                                  state_undefined     },
3297     { /* 47, undefined                              */      0,                                                  state_undefined     },
3298     { /* 48, undefined                              */      0,                                                  state_undefined     },
3299     { /* 49, undefined                              */      0,                                                  state_undefined     },
3300     { /* 50, undefined                              */      0,                                                  state_undefined     },
3301     { /* 51, undefined                              */      0,                                                  state_undefined     },
3302     { /* 52, undefined                              */      0,                                                  state_undefined     },
3303     { /* 53, undefined                              */      0,                                                  state_undefined     },
3304     { /* 54, undefined                              */      0,                                                  state_undefined     },
3305     { /* 55, undefined                              */      0,                                                  state_undefined     },
3306     { /* 56, undefined                              */      0,                                                  state_undefined     },
3307     { /* 57, undefined                              */      0,                                                  state_undefined     },
3308     { /* 58, undefined                              */      0,                                                  state_undefined     },
3309     { /* 59, undefined                              */      0,                                                  state_undefined     },
3310     { /* 60, undefined                              */      0,                                                  state_undefined     },
3311     { /* 61, undefined                              */      0,                                                  state_undefined     },
3312     { /* 62, undefined                              */      0,                                                  state_undefined     },
3313     { /* 63, undefined                              */      0,                                                  state_undefined     },
3314     { /* 64, undefined                              */      0,                                                  state_undefined     },
3315     { /* 65, undefined                              */      0,                                                  state_undefined     },
3316     { /* 66, undefined                              */      0,                                                  state_undefined     },
3317     { /* 67, undefined                              */      0,                                                  state_undefined     },
3318     { /* 68, undefined                              */      0,                                                  state_undefined     },
3319     { /* 69, undefined                              */      0,                                                  state_undefined     },
3320     { /* 70, undefined                              */      0,                                                  state_undefined     },
3321     { /* 71, undefined                              */      0,                                                  state_undefined     },
3322     { /* 72, undefined                              */      0,                                                  state_undefined     },
3323     { /* 73, undefined                              */      0,                                                  state_undefined     },
3324     { /* 74, undefined                              */      0,                                                  state_undefined     },
3325     { /* 75, undefined                              */      0,                                                  state_undefined     },
3326     { /* 76, undefined                              */      0,                                                  state_undefined     },
3327     { /* 77, undefined                              */      0,                                                  state_undefined     },
3328     { /* 78, undefined                              */      0,                                                  state_undefined     },
3329     { /* 79, undefined                              */      0,                                                  state_undefined     },
3330     { /* 80, undefined                              */      0,                                                  state_undefined     },
3331     { /* 81, undefined                              */      0,                                                  state_undefined     },
3332     { /* 82, undefined                              */      0,                                                  state_undefined     },
3333     { /* 83, undefined                              */      0,                                                  state_undefined     },
3334     { /* 84, undefined                              */      0,                                                  state_undefined     },
3335     { /* 85, undefined                              */      0,                                                  state_undefined     },
3336     { /* 86, undefined                              */      0,                                                  state_undefined     },
3337     { /* 87, undefined                              */      0,                                                  state_undefined     },
3338     { /* 88, undefined                              */      0,                                                  state_undefined     },
3339     { /* 89, undefined                              */      0,                                                  state_undefined     },
3340     { /* 90, undefined                              */      0,                                                  state_undefined     },
3341     { /* 91, undefined                              */      0,                                                  state_undefined     },
3342     { /* 92, undefined                              */      0,                                                  state_undefined     },
3343     { /* 93, undefined                              */      0,                                                  state_undefined     },
3344     { /* 94, undefined                              */      0,                                                  state_undefined     },
3345     { /* 95, undefined                              */      0,                                                  state_undefined     },
3346     { /* 96, undefined                              */      0,                                                  state_undefined     },
3347     { /* 97, undefined                              */      0,                                                  state_undefined     },
3348     { /* 98, undefined                              */      0,                                                  state_undefined     },
3349     { /* 99, undefined                              */      0,                                                  state_undefined     },
3350     { /*100, undefined                              */      0,                                                  state_undefined     },
3351     { /*101, undefined                              */      0,                                                  state_undefined     },
3352     { /*102, undefined                              */      0,                                                  state_undefined     },
3353     { /*103, undefined                              */      0,                                                  state_undefined     },
3354     { /*104, undefined                              */      0,                                                  state_undefined     },
3355     { /*105, undefined                              */      0,                                                  state_undefined     },
3356     { /*106, undefined                              */      0,                                                  state_undefined     },
3357     { /*107, undefined                              */      0,                                                  state_undefined     },
3358     { /*108, undefined                              */      0,                                                  state_undefined     },
3359     { /*109, undefined                              */      0,                                                  state_undefined     },
3360     { /*110, undefined                              */      0,                                                  state_undefined     },
3361     { /*111, undefined                              */      0,                                                  state_undefined     },
3362     { /*112, undefined                              */      0,                                                  state_undefined     },
3363     { /*113, undefined                              */      0,                                                  state_undefined     },
3364     { /*114, undefined                              */      0,                                                  state_undefined     },
3365     { /*115, undefined                              */      0,                                                  state_undefined     },
3366     { /*116, undefined                              */      0,                                                  state_undefined     },
3367     { /*117, undefined                              */      0,                                                  state_undefined     },
3368     { /*118, undefined                              */      0,                                                  state_undefined     },
3369     { /*119, undefined                              */      0,                                                  state_undefined     },
3370     { /*120, undefined                              */      0,                                                  state_undefined     },
3371     { /*121, undefined                              */      0,                                                  state_undefined     },
3372     { /*122, undefined                              */      0,                                                  state_undefined     },
3373     { /*123, undefined                              */      0,                                                  state_undefined     },
3374     { /*124, undefined                              */      0,                                                  state_undefined     },
3375     { /*125, undefined                              */      0,                                                  state_undefined     },
3376     { /*126, undefined                              */      0,                                                  state_undefined     },
3377     { /*127, undefined                              */      0,                                                  state_undefined     },
3378     { /*128, undefined                              */      0,                                                  state_undefined     },
3379     { /*129, undefined                              */      0,                                                  state_undefined     },
3380     { /*130, undefined                              */      0,                                                  state_undefined     },
3381     { /*131, undefined                              */      0,                                                  state_undefined     },
3382     { /*132, undefined                              */      0,                                                  state_undefined     },
3383     { /*133, undefined                              */      0,                                                  state_undefined     },
3384     { /*134, undefined                              */      0,                                                  state_undefined     },
3385     { /*135, undefined                              */      0,                                                  state_undefined     },
3386     { /*136, undefined                              */      0,                                                  state_undefined     },
3387     { /*137, undefined                              */      0,                                                  state_undefined     },
3388     { /*138, undefined                              */      0,                                                  state_undefined     },
3389     { /*139, undefined                              */      0,                                                  state_undefined     },
3390     { /*140, undefined                              */      0,                                                  state_undefined     },
3391     { /*141, undefined                              */      0,                                                  state_undefined     },
3392     { /*142, undefined                              */      0,                                                  state_undefined     },
3393     { /*143, undefined                              */      0,                                                  state_undefined     },
3394     { /*144, undefined                              */      0,                                                  state_undefined     },
3395     { /*145, undefined                              */      0,                                                  state_undefined     },
3396     { /*146, undefined                              */      0,                                                  state_undefined     },
3397     { /*147, undefined                              */      0,                                                  state_undefined     },
3398     { /*148, undefined                              */      0,                                                  state_undefined     },
3399     { /*149, undefined                              */      0,                                                  state_undefined     },
3400     { /*150, undefined                              */      0,                                                  state_undefined     },
3401     { /*151, undefined                              */      0,                                                  state_undefined     },
3402     { /*152, undefined                              */      0,                                                  state_undefined     },
3403     { /*153, undefined                              */      0,                                                  state_undefined     },
3404     { /*154, undefined                              */      0,                                                  state_undefined     },
3405     { /*155, undefined                              */      0,                                                  state_undefined     },
3406     { /*156, undefined                              */      0,                                                  state_undefined     },
3407     { /*157, undefined                              */      0,                                                  state_undefined     },
3408     { /*158, undefined                              */      0,                                                  state_undefined     },
3409     { /*159, undefined                              */      0,                                                  state_undefined     },
3410     { /*160, undefined                              */      0,                                                  state_undefined     },
3411     { /*161, undefined                              */      0,                                                  state_undefined     },
3412     { /*162, undefined                              */      0,                                                  state_undefined     },
3413     { /*163, undefined                              */      0,                                                  state_undefined     },
3414     { /*164, undefined                              */      0,                                                  state_undefined     },
3415     { /*165, undefined                              */      0,                                                  state_undefined     },
3416     { /*166, undefined                              */      0,                                                  state_undefined     },
3417     { /*167, undefined                              */      0,                                                  state_undefined     },
3418     { /*168, undefined                              */      0,                                                  state_undefined     },
3419     { /*169, undefined                              */      0,                                                  state_undefined     },
3420     { /*170, undefined                              */      0,                                                  state_undefined     },
3421     { /*171, undefined                              */      0,                                                  state_undefined     },
3422     { /*172, undefined                              */      0,                                                  state_undefined     },
3423     { /*173, undefined                              */      0,                                                  state_undefined     },
3424     { /*174, undefined                              */      0,                                                  state_undefined     },
3425     { /*175, undefined                              */      0,                                                  state_undefined     },
3426     { /*176, undefined                              */      0,                                                  state_undefined     },
3427     { /*177, undefined                              */      0,                                                  state_undefined     },
3428     { /*178, undefined                              */      0,                                                  state_undefined     },
3429     { /*179, undefined                              */      0,                                                  state_undefined     },
3430     { /*180, undefined                              */      0,                                                  state_undefined     },
3431     { /*181, undefined                              */      0,                                                  state_undefined     },
3432     { /*182, undefined                              */      0,                                                  state_undefined     },
3433     { /*183, undefined                              */      0,                                                  state_undefined     },
3434     { /*184, undefined                              */      0,                                                  state_undefined     },
3435     { /*185, undefined                              */      0,                                                  state_undefined     },
3436     { /*186, undefined                              */      0,                                                  state_undefined     },
3437     { /*187, undefined                              */      0,                                                  state_undefined     },
3438     { /*188, undefined                              */      0,                                                  state_undefined     },
3439     { /*189, undefined                              */      0,                                                  state_undefined     },
3440     { /*190, undefined                              */      0,                                                  state_undefined     },
3441     { /*191, undefined                              */      0,                                                  state_undefined     },
3442     { /*192, undefined                              */      0,                                                  state_undefined     },
3443     { /*193, undefined                              */      0,                                                  state_undefined     },
3444     { /*194, undefined                              */      0,                                                  state_undefined     },
3445     { /*195, undefined                              */      0,                                                  state_undefined     },
3446     { /*196, undefined                              */      0,                                                  state_undefined     },
3447     { /*197, undefined                              */      0,                                                  state_undefined     },
3448     { /*198, undefined                              */      0,                                                  state_undefined     },
3449     { /*199, undefined                              */      0,                                                  state_undefined     },
3450     { /*200, undefined                              */      0,                                                  state_undefined     },
3451     { /*201, undefined                              */      0,                                                  state_undefined     },
3452     { /*202, undefined                              */      0,                                                  state_undefined     },
3453     { /*203, undefined                              */      0,                                                  state_undefined     },
3454     { /*204, undefined                              */      0,                                                  state_undefined     },
3455     { /*205, undefined                              */      0,                                                  state_undefined     },
3456     { /*206, undefined                              */      0,                                                  state_undefined     },
3457     { /*207, undefined                              */      0,                                                  state_undefined     },
3458     { /*208, undefined                              */      0,                                                  state_undefined     },
3459     { /*209, undefined                              */      0,                                                  state_undefined     },
3460     { /*210, undefined                              */      0,                                                  state_undefined     },
3461     { /*211, undefined                              */      0,                                                  state_undefined     },
3462     { /*212, undefined                              */      0,                                                  state_undefined     },
3463     { /*213, undefined                              */      0,                                                  state_undefined     },
3464     { /*214, undefined                              */      0,                                                  state_undefined     },
3465     { /*215, undefined                              */      0,                                                  state_undefined     },
3466     { /*216, undefined                              */      0,                                                  state_undefined     },
3467     { /*217, undefined                              */      0,                                                  state_undefined     },
3468     { /*218, undefined                              */      0,                                                  state_undefined     },
3469     { /*219, undefined                              */      0,                                                  state_undefined     },
3470     { /*220, undefined                              */      0,                                                  state_undefined     },
3471     { /*221, undefined                              */      0,                                                  state_undefined     },
3472     { /*222, undefined                              */      0,                                                  state_undefined     },
3473     { /*223, undefined                              */      0,                                                  state_undefined     },
3474     { /*224, undefined                              */      0,                                                  state_undefined     },
3475     { /*225, undefined                              */      0,                                                  state_undefined     },
3476     { /*226, undefined                              */      0,                                                  state_undefined     },
3477     { /*227, undefined                              */      0,                                                  state_undefined     },
3478     { /*228, undefined                              */      0,                                                  state_undefined     },
3479     { /*229, undefined                              */      0,                                                  state_undefined     },
3480     { /*230, undefined                              */      0,                                                  state_undefined     },
3481     { /*231, undefined                              */      0,                                                  state_undefined     },
3482     { /*232, undefined                              */      0,                                                  state_undefined     },
3483     { /*233, undefined                              */      0,                                                  state_undefined     },
3484     { /*234, undefined                              */      0,                                                  state_undefined     },
3485     { /*235, undefined                              */      0,                                                  state_undefined     },
3486     { /*236, undefined                              */      0,                                                  state_undefined     },
3487     { /*237, undefined                              */      0,                                                  state_undefined     },
3488     { /*238, undefined                              */      0,                                                  state_undefined     },
3489     { /*239, undefined                              */      0,                                                  state_undefined     },
3490     { /*240, undefined                              */      0,                                                  state_undefined     },
3491     { /*241, undefined                              */      0,                                                  state_undefined     },
3492     { /*242, undefined                              */      0,                                                  state_undefined     },
3493     { /*243, undefined                              */      0,                                                  state_undefined     },
3494     { /*244, undefined                              */      0,                                                  state_undefined     },
3495     { /*245, undefined                              */      0,                                                  state_undefined     },
3496     { /*246, undefined                              */      0,                                                  state_undefined     },
3497     { /*247, undefined                              */      0,                                                  state_undefined     },
3498     { /*248, undefined                              */      0,                                                  state_undefined     },
3499     { /*249, undefined                              */      0,                                                  state_undefined     },
3500     { /*250, undefined                              */      0,                                                  state_undefined     },
3501     { /*251, undefined                              */      0,                                                  state_undefined     },
3502     { /*252, undefined                              */      0,                                                  state_undefined     },
3503     { /*253, undefined                              */      0,                                                  state_undefined     },
3504     { /*254, undefined                              */      0,                                                  state_undefined     },
3505     { /*255, undefined                              */      0,                                                  state_undefined     },
3506       /* End huge gap */
3507     { /*256, WINED3DTS_WORLDMATRIX(0)               */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)),          transform_world     },
3508     { /*257, WINED3DTS_WORLDMATRIX(1)               */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(1)),          transform_worldex   },
3509     { /*258, WINED3DTS_WORLDMATRIX(2)               */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(2)),          transform_worldex   },
3510     { /*259, WINED3DTS_WORLDMATRIX(3)               */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(3)),          transform_worldex   },
3511     { /*260, WINED3DTS_WORLDMATRIX(4)               */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(4)),          transform_worldex   },
3512     { /*261, WINED3DTS_WORLDMATRIX(5)               */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(5)),          transform_worldex   },
3513     { /*262, WINED3DTS_WORLDMATRIX(6)               */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(6)),          transform_worldex   },
3514     { /*263, WINED3DTS_WORLDMATRIX(7)               */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(7)),          transform_worldex   },
3515     { /*264, WINED3DTS_WORLDMATRIX(8)               */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(8)),          transform_worldex   },
3516     { /*265, WINED3DTS_WORLDMATRIX(9)               */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(9)),          transform_worldex   },
3517     { /*266, WINED3DTS_WORLDMATRIX(10)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(10)),         transform_worldex   },
3518     { /*267, WINED3DTS_WORLDMATRIX(11)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(11)),         transform_worldex   },
3519     { /*268, WINED3DTS_WORLDMATRIX(12)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(12)),         transform_worldex   },
3520     { /*269, WINED3DTS_WORLDMATRIX(13)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(13)),         transform_worldex   },
3521     { /*270, WINED3DTS_WORLDMATRIX(14)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(14)),         transform_worldex   },
3522     { /*271, WINED3DTS_WORLDMATRIX(15)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(15)),         transform_worldex   },
3523     { /*272, WINED3DTS_WORLDMATRIX(16)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(16)),         transform_worldex   },
3524     { /*273, WINED3DTS_WORLDMATRIX(17)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(17)),         transform_worldex   },
3525     { /*274, WINED3DTS_WORLDMATRIX(18)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(18)),         transform_worldex   },
3526     { /*275, WINED3DTS_WORLDMATRIX(19)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(19)),         transform_worldex   },
3527     { /*276, WINED3DTS_WORLDMATRIX(20)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(20)),         transform_worldex   },
3528     { /*277, WINED3DTS_WORLDMATRIX(21)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(21)),         transform_worldex   },
3529     { /*278, WINED3DTS_WORLDMATRIX(22)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(22)),         transform_worldex   },
3530     { /*279, WINED3DTS_WORLDMATRIX(23)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(23)),         transform_worldex   },
3531     { /*280, WINED3DTS_WORLDMATRIX(24)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(24)),         transform_worldex   },
3532     { /*281, WINED3DTS_WORLDMATRIX(25)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(25)),         transform_worldex   },
3533     { /*282, WINED3DTS_WORLDMATRIX(26)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(26)),         transform_worldex   },
3534     { /*283, WINED3DTS_WORLDMATRIX(27)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(27)),         transform_worldex   },
3535     { /*284, WINED3DTS_WORLDMATRIX(28)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(28)),         transform_worldex   },
3536     { /*285, WINED3DTS_WORLDMATRIX(29)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(29)),         transform_worldex   },
3537     { /*286, WINED3DTS_WORLDMATRIX(30)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(30)),         transform_worldex   },
3538     { /*287, WINED3DTS_WORLDMATRIX(31)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(31)),         transform_worldex   },
3539     { /*288, WINED3DTS_WORLDMATRIX(32)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(32)),         transform_worldex   },
3540     { /*289, WINED3DTS_WORLDMATRIX(33)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(33)),         transform_worldex   },
3541     { /*290, WINED3DTS_WORLDMATRIX(34)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(34)),         transform_worldex   },
3542     { /*291, WINED3DTS_WORLDMATRIX(35)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(35)),         transform_worldex   },
3543     { /*292, WINED3DTS_WORLDMATRIX(36)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(36)),         transform_worldex   },
3544     { /*293, WINED3DTS_WORLDMATRIX(37)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(37)),         transform_worldex   },
3545     { /*294, WINED3DTS_WORLDMATRIX(38)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(38)),         transform_worldex   },
3546     { /*295, WINED3DTS_WORLDMATRIX(39)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(39)),         transform_worldex   },
3547     { /*296, WINED3DTS_WORLDMATRIX(40)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(40)),         transform_worldex   },
3548     { /*297, WINED3DTS_WORLDMATRIX(41)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(41)),         transform_worldex   },
3549     { /*298, WINED3DTS_WORLDMATRIX(42)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(42)),         transform_worldex   },
3550     { /*299, WINED3DTS_WORLDMATRIX(43)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(43)),         transform_worldex   },
3551     { /*300, WINED3DTS_WORLDMATRIX(44)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(44)),         transform_worldex   },
3552     { /*301, WINED3DTS_WORLDMATRIX(45)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(45)),         transform_worldex   },
3553     { /*302, WINED3DTS_WORLDMATRIX(46)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(46)),         transform_worldex   },
3554     { /*303, WINED3DTS_WORLDMATRIX(47)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(47)),         transform_worldex   },
3555     { /*304, WINED3DTS_WORLDMATRIX(48)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(48)),         transform_worldex   },
3556     { /*305, WINED3DTS_WORLDMATRIX(49)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(49)),         transform_worldex   },
3557     { /*306, WINED3DTS_WORLDMATRIX(50)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(50)),         transform_worldex   },
3558     { /*307, WINED3DTS_WORLDMATRIX(51)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(51)),         transform_worldex   },
3559     { /*308, WINED3DTS_WORLDMATRIX(52)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(52)),         transform_worldex   },
3560     { /*309, WINED3DTS_WORLDMATRIX(53)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(53)),         transform_worldex   },
3561     { /*310, WINED3DTS_WORLDMATRIX(54)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(54)),         transform_worldex   },
3562     { /*311, WINED3DTS_WORLDMATRIX(55)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(55)),         transform_worldex   },
3563     { /*312, WINED3DTS_WORLDMATRIX(56)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(56)),         transform_worldex   },
3564     { /*313, WINED3DTS_WORLDMATRIX(57)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(57)),         transform_worldex   },
3565     { /*314, WINED3DTS_WORLDMATRIX(58)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(58)),         transform_worldex   },
3566     { /*315, WINED3DTS_WORLDMATRIX(59)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(59)),         transform_worldex   },
3567     { /*316, WINED3DTS_WORLDMATRIX(60)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(60)),         transform_worldex   },
3568     { /*317, WINED3DTS_WORLDMATRIX(61)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(61)),         transform_worldex   },
3569     { /*318, WINED3DTS_WORLDMATRIX(62)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(62)),         transform_worldex   },
3570     { /*319, WINED3DTS_WORLDMATRIX(63)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(63)),         transform_worldex   },
3571     { /*320, WINED3DTS_WORLDMATRIX(64)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(64)),         transform_worldex   },
3572     { /*321, WINED3DTS_WORLDMATRIX(65)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(65)),         transform_worldex   },
3573     { /*322, WINED3DTS_WORLDMATRIX(66)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(66)),         transform_worldex   },
3574     { /*323, WINED3DTS_WORLDMATRIX(67)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(67)),         transform_worldex   },
3575     { /*324, WINED3DTS_WORLDMATRIX(68)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(68)),         transform_worldex   },
3576     { /*325, WINED3DTS_WORLDMATRIX(68)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(69)),         transform_worldex   },
3577     { /*326, WINED3DTS_WORLDMATRIX(70)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(70)),         transform_worldex   },
3578     { /*327, WINED3DTS_WORLDMATRIX(71)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(71)),         transform_worldex   },
3579     { /*328, WINED3DTS_WORLDMATRIX(72)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(72)),         transform_worldex   },
3580     { /*329, WINED3DTS_WORLDMATRIX(73)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(73)),         transform_worldex   },
3581     { /*330, WINED3DTS_WORLDMATRIX(74)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(74)),         transform_worldex   },
3582     { /*331, WINED3DTS_WORLDMATRIX(75)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(75)),         transform_worldex   },
3583     { /*332, WINED3DTS_WORLDMATRIX(76)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(76)),         transform_worldex   },
3584     { /*333, WINED3DTS_WORLDMATRIX(77)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(77)),         transform_worldex   },
3585     { /*334, WINED3DTS_WORLDMATRIX(78)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(78)),         transform_worldex   },
3586     { /*335, WINED3DTS_WORLDMATRIX(79)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(79)),         transform_worldex   },
3587     { /*336, WINED3DTS_WORLDMATRIX(80)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(80)),         transform_worldex   },
3588     { /*337, WINED3DTS_WORLDMATRIX(81)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(81)),         transform_worldex   },
3589     { /*338, WINED3DTS_WORLDMATRIX(82)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(82)),         transform_worldex   },
3590     { /*339, WINED3DTS_WORLDMATRIX(83)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(83)),         transform_worldex   },
3591     { /*340, WINED3DTS_WORLDMATRIX(84)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(84)),         transform_worldex   },
3592     { /*341, WINED3DTS_WORLDMATRIX(85)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(85)),         transform_worldex   },
3593     { /*341, WINED3DTS_WORLDMATRIX(86)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(86)),         transform_worldex   },
3594     { /*343, WINED3DTS_WORLDMATRIX(87)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(87)),         transform_worldex   },
3595     { /*344, WINED3DTS_WORLDMATRIX(88)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(88)),         transform_worldex   },
3596     { /*345, WINED3DTS_WORLDMATRIX(89)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(89)),         transform_worldex   },
3597     { /*346, WINED3DTS_WORLDMATRIX(90)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(90)),         transform_worldex   },
3598     { /*347, WINED3DTS_WORLDMATRIX(91)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(91)),         transform_worldex   },
3599     { /*348, WINED3DTS_WORLDMATRIX(92)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(92)),         transform_worldex   },
3600     { /*349, WINED3DTS_WORLDMATRIX(93)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(93)),         transform_worldex   },
3601     { /*350, WINED3DTS_WORLDMATRIX(94)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(94)),         transform_worldex   },
3602     { /*351, WINED3DTS_WORLDMATRIX(95)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(95)),         transform_worldex   },
3603     { /*352, WINED3DTS_WORLDMATRIX(96)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(96)),         transform_worldex   },
3604     { /*353, WINED3DTS_WORLDMATRIX(97)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(97)),         transform_worldex   },
3605     { /*354, WINED3DTS_WORLDMATRIX(98)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(98)),         transform_worldex   },
3606     { /*355, WINED3DTS_WORLDMATRIX(99)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(99)),         transform_worldex   },
3607     { /*356, WINED3DTS_WORLDMATRIX(100)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(100)),        transform_worldex   },
3608     { /*357, WINED3DTS_WORLDMATRIX(101)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(101)),        transform_worldex   },
3609     { /*358, WINED3DTS_WORLDMATRIX(102)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(102)),        transform_worldex   },
3610     { /*359, WINED3DTS_WORLDMATRIX(103)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(103)),        transform_worldex   },
3611     { /*360, WINED3DTS_WORLDMATRIX(104)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(104)),        transform_worldex   },
3612     { /*361, WINED3DTS_WORLDMATRIX(105)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(105)),        transform_worldex   },
3613     { /*362, WINED3DTS_WORLDMATRIX(106)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(106)),        transform_worldex   },
3614     { /*363, WINED3DTS_WORLDMATRIX(107)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(107)),        transform_worldex   },
3615     { /*364, WINED3DTS_WORLDMATRIX(108)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(108)),        transform_worldex   },
3616     { /*365, WINED3DTS_WORLDMATRIX(109)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(109)),        transform_worldex   },
3617     { /*366, WINED3DTS_WORLDMATRIX(110)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(110)),        transform_worldex   },
3618     { /*367, WINED3DTS_WORLDMATRIX(111)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(111)),        transform_worldex   },
3619     { /*368, WINED3DTS_WORLDMATRIX(112)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(112)),        transform_worldex   },
3620     { /*369, WINED3DTS_WORLDMATRIX(113)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(113)),        transform_worldex   },
3621     { /*370, WINED3DTS_WORLDMATRIX(114)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(114)),        transform_worldex   },
3622     { /*371, WINED3DTS_WORLDMATRIX(115)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(115)),        transform_worldex   },
3623     { /*372, WINED3DTS_WORLDMATRIX(116)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(116)),        transform_worldex   },
3624     { /*373, WINED3DTS_WORLDMATRIX(117)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(117)),        transform_worldex   },
3625     { /*374, WINED3DTS_WORLDMATRIX(118)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(118)),        transform_worldex   },
3626     { /*375, WINED3DTS_WORLDMATRIX(119)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(119)),        transform_worldex   },
3627     { /*376, WINED3DTS_WORLDMATRIX(120)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(120)),        transform_worldex   },
3628     { /*377, WINED3DTS_WORLDMATRIX(121)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(121)),        transform_worldex   },
3629     { /*378, WINED3DTS_WORLDMATRIX(122)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(122)),        transform_worldex   },
3630     { /*379, WINED3DTS_WORLDMATRIX(123)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(123)),        transform_worldex   },
3631     { /*380, WINED3DTS_WORLDMATRIX(124)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(124)),        transform_worldex   },
3632     { /*381, WINED3DTS_WORLDMATRIX(125)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(125)),        transform_worldex   },
3633     { /*382, WINED3DTS_WORLDMATRIX(126)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(126)),        transform_worldex   },
3634     { /*383, WINED3DTS_WORLDMATRIX(127)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(127)),        transform_worldex   },
3635     { /*384, WINED3DTS_WORLDMATRIX(128)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(128)),        transform_worldex   },
3636     { /*385, WINED3DTS_WORLDMATRIX(129)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(129)),        transform_worldex   },
3637     { /*386, WINED3DTS_WORLDMATRIX(130)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(130)),        transform_worldex   },
3638     { /*387, WINED3DTS_WORLDMATRIX(131)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(131)),        transform_worldex   },
3639     { /*388, WINED3DTS_WORLDMATRIX(132)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(132)),        transform_worldex   },
3640     { /*389, WINED3DTS_WORLDMATRIX(133)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(133)),        transform_worldex   },
3641     { /*390, WINED3DTS_WORLDMATRIX(134)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(134)),        transform_worldex   },
3642     { /*391, WINED3DTS_WORLDMATRIX(135)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(135)),        transform_worldex   },
3643     { /*392, WINED3DTS_WORLDMATRIX(136)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(136)),        transform_worldex   },
3644     { /*393, WINED3DTS_WORLDMATRIX(137)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(137)),        transform_worldex   },
3645     { /*394, WINED3DTS_WORLDMATRIX(138)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(138)),        transform_worldex   },
3646     { /*395, WINED3DTS_WORLDMATRIX(139)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(139)),        transform_worldex   },
3647     { /*396, WINED3DTS_WORLDMATRIX(140)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(140)),        transform_worldex   },
3648     { /*397, WINED3DTS_WORLDMATRIX(141)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(141)),        transform_worldex   },
3649     { /*398, WINED3DTS_WORLDMATRIX(142)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(142)),        transform_worldex   },
3650     { /*399, WINED3DTS_WORLDMATRIX(143)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(143)),        transform_worldex   },
3651     { /*400, WINED3DTS_WORLDMATRIX(144)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(144)),        transform_worldex   },
3652     { /*401, WINED3DTS_WORLDMATRIX(145)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(145)),        transform_worldex   },
3653     { /*402, WINED3DTS_WORLDMATRIX(146)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(146)),        transform_worldex   },
3654     { /*403, WINED3DTS_WORLDMATRIX(147)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(147)),        transform_worldex   },
3655     { /*404, WINED3DTS_WORLDMATRIX(148)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(148)),        transform_worldex   },
3656     { /*405, WINED3DTS_WORLDMATRIX(149)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(149)),        transform_worldex   },
3657     { /*406, WINED3DTS_WORLDMATRIX(150)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(150)),        transform_worldex   },
3658     { /*407, WINED3DTS_WORLDMATRIX(151)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(151)),        transform_worldex   },
3659     { /*408, WINED3DTS_WORLDMATRIX(152)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(152)),        transform_worldex   },
3660     { /*409, WINED3DTS_WORLDMATRIX(153)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(153)),        transform_worldex   },
3661     { /*410, WINED3DTS_WORLDMATRIX(154)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(154)),        transform_worldex   },
3662     { /*411, WINED3DTS_WORLDMATRIX(155)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(155)),        transform_worldex   },
3663     { /*412, WINED3DTS_WORLDMATRIX(156)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(156)),        transform_worldex   },
3664     { /*413, WINED3DTS_WORLDMATRIX(157)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(157)),        transform_worldex   },
3665     { /*414, WINED3DTS_WORLDMATRIX(158)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(158)),        transform_worldex   },
3666     { /*415, WINED3DTS_WORLDMATRIX(159)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(159)),        transform_worldex   },
3667     { /*416, WINED3DTS_WORLDMATRIX(160)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(160)),        transform_worldex   },
3668     { /*417, WINED3DTS_WORLDMATRIX(161)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(161)),        transform_worldex   },
3669     { /*418, WINED3DTS_WORLDMATRIX(162)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(162)),        transform_worldex   },
3670     { /*419, WINED3DTS_WORLDMATRIX(163)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(163)),        transform_worldex   },
3671     { /*420, WINED3DTS_WORLDMATRIX(164)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(164)),        transform_worldex   },
3672     { /*421, WINED3DTS_WORLDMATRIX(165)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(165)),        transform_worldex   },
3673     { /*422, WINED3DTS_WORLDMATRIX(166)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(166)),        transform_worldex   },
3674     { /*423, WINED3DTS_WORLDMATRIX(167)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(167)),        transform_worldex   },
3675     { /*424, WINED3DTS_WORLDMATRIX(168)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(168)),        transform_worldex   },
3676     { /*425, WINED3DTS_WORLDMATRIX(168)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(169)),        transform_worldex   },
3677     { /*426, WINED3DTS_WORLDMATRIX(170)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(170)),        transform_worldex   },
3678     { /*427, WINED3DTS_WORLDMATRIX(171)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(171)),        transform_worldex   },
3679     { /*428, WINED3DTS_WORLDMATRIX(172)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(172)),        transform_worldex   },
3680     { /*429, WINED3DTS_WORLDMATRIX(173)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(173)),        transform_worldex   },
3681     { /*430, WINED3DTS_WORLDMATRIX(174)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(174)),        transform_worldex   },
3682     { /*431, WINED3DTS_WORLDMATRIX(175)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(175)),        transform_worldex   },
3683     { /*432, WINED3DTS_WORLDMATRIX(176)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(176)),        transform_worldex   },
3684     { /*433, WINED3DTS_WORLDMATRIX(177)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(177)),        transform_worldex   },
3685     { /*434, WINED3DTS_WORLDMATRIX(178)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(178)),        transform_worldex   },
3686     { /*435, WINED3DTS_WORLDMATRIX(179)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(179)),        transform_worldex   },
3687     { /*436, WINED3DTS_WORLDMATRIX(180)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(180)),        transform_worldex   },
3688     { /*437, WINED3DTS_WORLDMATRIX(181)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(181)),        transform_worldex   },
3689     { /*438, WINED3DTS_WORLDMATRIX(182)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(182)),        transform_worldex   },
3690     { /*439, WINED3DTS_WORLDMATRIX(183)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(183)),        transform_worldex   },
3691     { /*440, WINED3DTS_WORLDMATRIX(184)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(184)),        transform_worldex   },
3692     { /*441, WINED3DTS_WORLDMATRIX(185)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(185)),        transform_worldex   },
3693     { /*441, WINED3DTS_WORLDMATRIX(186)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(186)),        transform_worldex   },
3694     { /*443, WINED3DTS_WORLDMATRIX(187)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(187)),        transform_worldex   },
3695     { /*444, WINED3DTS_WORLDMATRIX(188)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(188)),        transform_worldex   },
3696     { /*445, WINED3DTS_WORLDMATRIX(189)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(189)),        transform_worldex   },
3697     { /*446, WINED3DTS_WORLDMATRIX(190)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(190)),        transform_worldex   },
3698     { /*447, WINED3DTS_WORLDMATRIX(191)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(191)),        transform_worldex   },
3699     { /*448, WINED3DTS_WORLDMATRIX(192)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(192)),        transform_worldex   },
3700     { /*449, WINED3DTS_WORLDMATRIX(193)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(193)),        transform_worldex   },
3701     { /*450, WINED3DTS_WORLDMATRIX(194)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(194)),        transform_worldex   },
3702     { /*451, WINED3DTS_WORLDMATRIX(195)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(195)),        transform_worldex   },
3703     { /*452, WINED3DTS_WORLDMATRIX(196)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(196)),        transform_worldex   },
3704     { /*453, WINED3DTS_WORLDMATRIX(197)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(197)),        transform_worldex   },
3705     { /*454, WINED3DTS_WORLDMATRIX(198)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(198)),        transform_worldex   },
3706     { /*455, WINED3DTS_WORLDMATRIX(199)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(199)),        transform_worldex   },
3707     { /*356, WINED3DTS_WORLDMATRIX(200)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(200)),        transform_worldex   },
3708     { /*457, WINED3DTS_WORLDMATRIX(201)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(201)),        transform_worldex   },
3709     { /*458, WINED3DTS_WORLDMATRIX(202)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(202)),        transform_worldex   },
3710     { /*459, WINED3DTS_WORLDMATRIX(203)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(203)),        transform_worldex   },
3711     { /*460, WINED3DTS_WORLDMATRIX(204)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(204)),        transform_worldex   },
3712     { /*461, WINED3DTS_WORLDMATRIX(205)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(205)),        transform_worldex   },
3713     { /*462, WINED3DTS_WORLDMATRIX(206)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(206)),        transform_worldex   },
3714     { /*463, WINED3DTS_WORLDMATRIX(207)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(207)),        transform_worldex   },
3715     { /*464, WINED3DTS_WORLDMATRIX(208)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(208)),        transform_worldex   },
3716     { /*465, WINED3DTS_WORLDMATRIX(209)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(209)),        transform_worldex   },
3717     { /*466, WINED3DTS_WORLDMATRIX(210)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(210)),        transform_worldex   },
3718     { /*467, WINED3DTS_WORLDMATRIX(211)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(211)),        transform_worldex   },
3719     { /*468, WINED3DTS_WORLDMATRIX(212)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(212)),        transform_worldex   },
3720     { /*469, WINED3DTS_WORLDMATRIX(213)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(213)),        transform_worldex   },
3721     { /*470, WINED3DTS_WORLDMATRIX(214)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(214)),        transform_worldex   },
3722     { /*471, WINED3DTS_WORLDMATRIX(215)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(215)),        transform_worldex   },
3723     { /*472, WINED3DTS_WORLDMATRIX(216)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(216)),        transform_worldex   },
3724     { /*473, WINED3DTS_WORLDMATRIX(217)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(217)),        transform_worldex   },
3725     { /*474, WINED3DTS_WORLDMATRIX(218)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(218)),        transform_worldex   },
3726     { /*475, WINED3DTS_WORLDMATRIX(219)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(219)),        transform_worldex   },
3727     { /*476, WINED3DTS_WORLDMATRIX(220)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(220)),        transform_worldex   },
3728     { /*477, WINED3DTS_WORLDMATRIX(221)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(221)),        transform_worldex   },
3729     { /*478, WINED3DTS_WORLDMATRIX(222)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(222)),        transform_worldex   },
3730     { /*479, WINED3DTS_WORLDMATRIX(223)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(223)),        transform_worldex   },
3731     { /*480, WINED3DTS_WORLDMATRIX(224)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(224)),        transform_worldex   },
3732     { /*481, WINED3DTS_WORLDMATRIX(225)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(225)),        transform_worldex   },
3733     { /*482, WINED3DTS_WORLDMATRIX(226)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(226)),        transform_worldex   },
3734     { /*483, WINED3DTS_WORLDMATRIX(227)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(227)),        transform_worldex   },
3735     { /*484, WINED3DTS_WORLDMATRIX(228)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(228)),        transform_worldex   },
3736     { /*485, WINED3DTS_WORLDMATRIX(229)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(229)),        transform_worldex   },
3737     { /*486, WINED3DTS_WORLDMATRIX(230)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(230)),        transform_worldex   },
3738     { /*487, WINED3DTS_WORLDMATRIX(231)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(231)),        transform_worldex   },
3739     { /*488, WINED3DTS_WORLDMATRIX(232)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(232)),        transform_worldex   },
3740     { /*489, WINED3DTS_WORLDMATRIX(233)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(233)),        transform_worldex   },
3741     { /*490, WINED3DTS_WORLDMATRIX(234)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(234)),        transform_worldex   },
3742     { /*491, WINED3DTS_WORLDMATRIX(235)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(235)),        transform_worldex   },
3743     { /*492, WINED3DTS_WORLDMATRIX(236)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(236)),        transform_worldex   },
3744     { /*493, WINED3DTS_WORLDMATRIX(237)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(237)),        transform_worldex   },
3745     { /*494, WINED3DTS_WORLDMATRIX(238)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(238)),        transform_worldex   },
3746     { /*495, WINED3DTS_WORLDMATRIX(239)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(239)),        transform_worldex   },
3747     { /*496, WINED3DTS_WORLDMATRIX(240)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(240)),        transform_worldex   },
3748     { /*497, WINED3DTS_WORLDMATRIX(241)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(241)),        transform_worldex   },
3749     { /*498, WINED3DTS_WORLDMATRIX(242)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(242)),        transform_worldex   },
3750     { /*499, WINED3DTS_WORLDMATRIX(243)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(243)),        transform_worldex   },
3751     { /*500, WINED3DTS_WORLDMATRIX(244)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(244)),        transform_worldex   },
3752     { /*501, WINED3DTS_WORLDMATRIX(245)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(245)),        transform_worldex   },
3753     { /*502, WINED3DTS_WORLDMATRIX(246)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(246)),        transform_worldex   },
3754     { /*503, WINED3DTS_WORLDMATRIX(247)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(247)),        transform_worldex   },
3755     { /*504, WINED3DTS_WORLDMATRIX(248)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(248)),        transform_worldex   },
3756     { /*505, WINED3DTS_WORLDMATRIX(249)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(249)),        transform_worldex   },
3757     { /*506, WINED3DTS_WORLDMATRIX(250)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(250)),        transform_worldex   },
3758     { /*507, WINED3DTS_WORLDMATRIX(251)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(251)),        transform_worldex   },
3759     { /*508, WINED3DTS_WORLDMATRIX(252)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(252)),        transform_worldex   },
3760     { /*509, WINED3DTS_WORLDMATRIX(253)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(253)),        transform_worldex   },
3761     { /*510, WINED3DTS_WORLDMATRIX(254)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(254)),        transform_worldex   },
3762     { /*511, WINED3DTS_WORLDMATRIX(255)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(255)),        transform_worldex   },
3763       /* Various Vertex states follow */
3764     { /*   , STATE_STREAMSRC                        */      STATE_VDECL,                                        vertexdeclaration   },
3765     { /*   , STATE_VDECL                            */      STATE_VDECL,                                        vertexdeclaration   },
3766     { /*   , STATE_VSHADER                          */      STATE_VDECL,                                        vertexdeclaration   },
3767     { /*   , STATE_VIEWPORT                         */      STATE_VIEWPORT,                                     viewport            },
3768     { /*   , STATE_VERTEXSHADERCONSTANT             */      STATE_VERTEXSHADERCONSTANT,                         shaderconstant      },
3769     { /*   , STATE_PIXELSHADERCONSTANT              */      STATE_VERTEXSHADERCONSTANT,                         shaderconstant      },
3770 };