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