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