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