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