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