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