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