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