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