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