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