advapi32/tests: Remove duplicate test.
[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 /* Set texture operations up - The following avoids lots of ifdefs in this routine!*/
1844 #if defined (GL_VERSION_1_3)
1845 # define useext(A) A
1846 #elif defined (GL_EXT_texture_env_combine)
1847 # define useext(A) A##_EXT
1848 #elif defined (GL_ARB_texture_env_combine)
1849 # define useext(A) A##_ARB
1850 #endif
1851
1852 static void get_src_and_opr(DWORD arg, BOOL is_alpha, GLenum* source, GLenum* operand) {
1853     /* The WINED3DTA_ALPHAREPLICATE flag specifies the alpha component of the
1854     * input should be used for all input components. The WINED3DTA_COMPLEMENT
1855     * flag specifies the complement of the input should be used. */
1856     BOOL from_alpha = is_alpha || arg & WINED3DTA_ALPHAREPLICATE;
1857     BOOL complement = arg & WINED3DTA_COMPLEMENT;
1858
1859     /* Calculate the operand */
1860     if (complement) {
1861         if (from_alpha) *operand = GL_ONE_MINUS_SRC_ALPHA;
1862         else *operand = GL_ONE_MINUS_SRC_COLOR;
1863     } else {
1864         if (from_alpha) *operand = GL_SRC_ALPHA;
1865         else *operand = GL_SRC_COLOR;
1866     }
1867
1868     /* Calculate the source */
1869     switch (arg & WINED3DTA_SELECTMASK) {
1870         case WINED3DTA_CURRENT: *source = GL_PREVIOUS_EXT; break;
1871         case WINED3DTA_DIFFUSE: *source = GL_PRIMARY_COLOR_EXT; break;
1872         case WINED3DTA_TEXTURE: *source = GL_TEXTURE; break;
1873         case WINED3DTA_TFACTOR: *source = GL_CONSTANT_EXT; break;
1874         case WINED3DTA_SPECULAR:
1875             /*
1876             * According to the GL_ARB_texture_env_combine specs, SPECULAR is
1877             * 'Secondary color' and isn't supported until base GL supports it
1878             * There is no concept of temp registers as far as I can tell
1879             */
1880             FIXME("Unhandled texture arg WINED3DTA_SPECULAR\n");
1881             *source = GL_TEXTURE;
1882             break;
1883         default:
1884             FIXME("Unrecognized texture arg %#x\n", arg);
1885             *source = GL_TEXTURE;
1886             break;
1887     }
1888 }
1889
1890 /* Setup the texture operations texture stage states */
1891 static void set_tex_op(IWineD3DDevice *iface, BOOL isAlpha, int Stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
1892 {
1893     GLenum src1, src2, src3;
1894     GLenum opr1, opr2, opr3;
1895     GLenum comb_target;
1896     GLenum src0_target, src1_target, src2_target;
1897     GLenum opr0_target, opr1_target, opr2_target;
1898     GLenum scal_target;
1899     GLenum opr=0, invopr, src3_target, opr3_target;
1900     BOOL Handled = FALSE;
1901     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
1902     IWineD3DStateBlockImpl *stateblock = This->stateBlock; /* for GLINFO_LOCATION */
1903
1904     TRACE("Alpha?(%d), Stage:%d Op(%s), a1(%d), a2(%d), a3(%d)\n", isAlpha, Stage, debug_d3dtop(op), arg1, arg2, arg3);
1905
1906     /* This is called by a state handler which has the gl lock held and a context for the thread */
1907
1908         /* Note: Operations usually involve two ars, src0 and src1 and are operations of
1909     the form (a1 <operation> a2). However, some of the more complex operations
1910     take 3 parameters. Instead of the (sensible) addition of a3, Microsoft added
1911     in a third parameter called a0. Therefore these are operations of the form
1912     a0 <operation> a1 <operation> a2, i.e., the new parameter goes to the front.
1913
1914     However, below we treat the new (a0) parameter as src2/opr2, so in the actual
1915     functions below, expect their syntax to differ slightly to those listed in the
1916     manuals, i.e., replace arg1 with arg3, arg2 with arg1 and arg3 with arg2
1917     This affects WINED3DTOP_MULTIPLYADD and WINED3DTOP_LERP                     */
1918
1919     if (isAlpha) {
1920         comb_target = useext(GL_COMBINE_ALPHA);
1921         src0_target = useext(GL_SOURCE0_ALPHA);
1922         src1_target = useext(GL_SOURCE1_ALPHA);
1923         src2_target = useext(GL_SOURCE2_ALPHA);
1924         opr0_target = useext(GL_OPERAND0_ALPHA);
1925         opr1_target = useext(GL_OPERAND1_ALPHA);
1926         opr2_target = useext(GL_OPERAND2_ALPHA);
1927         scal_target = GL_ALPHA_SCALE;
1928     }
1929     else {
1930         comb_target = useext(GL_COMBINE_RGB);
1931         src0_target = useext(GL_SOURCE0_RGB);
1932         src1_target = useext(GL_SOURCE1_RGB);
1933         src2_target = useext(GL_SOURCE2_RGB);
1934         opr0_target = useext(GL_OPERAND0_RGB);
1935         opr1_target = useext(GL_OPERAND1_RGB);
1936         opr2_target = useext(GL_OPERAND2_RGB);
1937         scal_target = useext(GL_RGB_SCALE);
1938     }
1939
1940         /* If a texture stage references an invalid texture unit the stage just
1941         * passes through the result from the previous stage */
1942     if (is_invalid_op(This, Stage, op, arg1, arg2, arg3)) {
1943         arg1 = WINED3DTA_CURRENT;
1944         op = WINED3DTOP_SELECTARG1;
1945     }
1946
1947         /* From MSDN (WINED3DTSS_ALPHAARG1) :
1948     The default argument is WINED3DTA_TEXTURE. If no texture is set for this stage,
1949     then the default argument is WINED3DTA_DIFFUSE.
1950     FIXME? If texture added/removed, may need to reset back as well?    */
1951     if (isAlpha && This->stateBlock->textures[Stage] == NULL && arg1 == WINED3DTA_TEXTURE) {
1952         get_src_and_opr(WINED3DTA_DIFFUSE, isAlpha, &src1, &opr1);
1953     } else {
1954         get_src_and_opr(arg1, isAlpha, &src1, &opr1);
1955     }
1956     get_src_and_opr(arg2, isAlpha, &src2, &opr2);
1957     get_src_and_opr(arg3, isAlpha, &src3, &opr3);
1958
1959     TRACE("ct(%x), 1:(%x,%x), 2:(%x,%x), 3:(%x,%x)\n", comb_target, src1, opr1, src2, opr2, src3, opr3);
1960
1961     Handled = TRUE; /* Assume will be handled */
1962
1963     /* Other texture operations require special extensions: */
1964     if (GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
1965         if (isAlpha) {
1966             opr = GL_SRC_ALPHA;
1967             invopr = GL_ONE_MINUS_SRC_ALPHA;
1968             src3_target = GL_SOURCE3_ALPHA_NV;
1969             opr3_target = GL_OPERAND3_ALPHA_NV;
1970         } else {
1971             opr = GL_SRC_COLOR;
1972             invopr = GL_ONE_MINUS_SRC_COLOR;
1973             src3_target = GL_SOURCE3_RGB_NV;
1974             opr3_target = GL_OPERAND3_RGB_NV;
1975         }
1976         switch (op) {
1977             case WINED3DTOP_DISABLE: /* Only for alpha */
1978                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1979                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
1980                 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
1981                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1982                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
1983                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1984                 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1985                 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1986                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1987                 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1988                 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
1989                 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
1990                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1991                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
1992                 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1993                 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1994                 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1995                 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
1996                 break;
1997                 case WINED3DTOP_SELECTARG1:                                          /* = a1 * 1 + 0 * 0 */
1998                 case WINED3DTOP_SELECTARG2:                                          /* = a2 * 1 + 0 * 0 */
1999                     glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2000                     checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2001                     if (op == WINED3DTOP_SELECTARG1) {
2002                         glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2003                         checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2004                         glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2005                         checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2006                     } else {
2007                         glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
2008                         checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
2009                         glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
2010                         checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
2011                     }
2012                     glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2013                     checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2014                     glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2015                     checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2016                     glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2017                     checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
2018                     glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2019                     checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2020                     glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2021                     checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2022                     glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2023                     checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2024                     break;
2025
2026             case WINED3DTOP_MODULATE:
2027                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2028                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2029                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2030                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2031                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2032                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2033                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2034                 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2035                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2036                 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2037                 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2038                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2039                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2040                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2041                 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2042                 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2043                 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2044                 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
2045                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2046                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2047                 break;
2048             case WINED3DTOP_MODULATE2X:
2049                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2050                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2051                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2052                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2053                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2054                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2055                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2056                 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2057                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2058                 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2059                 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2060                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2061                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2062                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2063                 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2064                 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2065                 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2066                 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
2067                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2068                 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2069                 break;
2070             case WINED3DTOP_MODULATE4X:
2071                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2072                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2073                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2074                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2075                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2076                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2077                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2078                 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2079                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2080                 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2081                 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2082                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2083                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2084                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2085                 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2086                 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2087                 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2088                 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
2089                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
2090                 checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
2091                 break;
2092
2093             case WINED3DTOP_ADD:
2094                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2095                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2096                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2097                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2098                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2099                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2100                 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2101                 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2102                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2103                 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2104                 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2105                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2106                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2107                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2108                 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2109                 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2110                 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2111                 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2112                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2113                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2114                 break;
2115
2116             case WINED3DTOP_ADDSIGNED:
2117                 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
2118                 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
2119                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2120                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2121                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2122                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2123                 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2124                 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2125                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2126                 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2127                 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2128                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2129                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2130                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2131                 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2132                 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2133                 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2134                 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2135                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2136                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2137                 break;
2138
2139             case WINED3DTOP_ADDSIGNED2X:
2140                 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
2141                 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
2142                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2143                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2144                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2145                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2146                 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2147                 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2148                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2149                 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2150                 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2151                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2152                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2153                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2154                 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2155                 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2156                 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2157                 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2158                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2159                 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2160                 break;
2161
2162             case WINED3DTOP_ADDSMOOTH:
2163                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2164                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2165                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2166                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2167                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2168                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2169                 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2170                 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2171                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2172                 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2173                 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2174                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2175                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2176                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2177                 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
2178                 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
2179                 switch (opr1) {
2180                     case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2181                     case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2182                     case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2183                     case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2184                 }
2185                 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2186                 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2187                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2188                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2189                 break;
2190
2191             case WINED3DTOP_BLENDDIFFUSEALPHA:
2192                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2193                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2194                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2195                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2196                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2197                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2198                 glTexEnvi(GL_TEXTURE_ENV, src1_target, useext(GL_PRIMARY_COLOR));
2199                 checkGLcall("GL_TEXTURE_ENV, src1_target, useext(GL_PRIMARY_COLOR)");
2200                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2201                 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2202                 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2203                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2204                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2205                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2206                 glTexEnvi(GL_TEXTURE_ENV, src3_target, useext(GL_PRIMARY_COLOR));
2207                 checkGLcall("GL_TEXTURE_ENV, src3_target, useext(GL_PRIMARY_COLOR)");
2208                 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2209                 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2210                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2211                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2212                 break;
2213             case WINED3DTOP_BLENDTEXTUREALPHA:
2214                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2215                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2216                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2217                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2218                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2219                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2220                 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_TEXTURE);
2221                 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_TEXTURE");
2222                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2223                 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2224                 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2225                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2226                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2227                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2228                 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
2229                 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
2230                 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2231                 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2232                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2233                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2234                 break;
2235             case WINED3DTOP_BLENDFACTORALPHA:
2236                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2237                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2238                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2239                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2240                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2241                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2242                 glTexEnvi(GL_TEXTURE_ENV, src1_target, useext(GL_CONSTANT));
2243                 checkGLcall("GL_TEXTURE_ENV, src1_target, useext(GL_CONSTANT)");
2244                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2245                 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2246                 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2247                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2248                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2249                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2250                 glTexEnvi(GL_TEXTURE_ENV, src3_target, useext(GL_CONSTANT));
2251                 checkGLcall("GL_TEXTURE_ENV, src3_target, useext(GL_CONSTANT)");
2252                 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2253                 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2254                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2255                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2256                 break;
2257             case WINED3DTOP_BLENDTEXTUREALPHAPM:
2258                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2259                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2260                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2261                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2262                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2263                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2264                 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2265                 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2266                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2267                 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2268                 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2269                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2270                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2271                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2272                 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
2273                 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
2274                 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2275                 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2276                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2277                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2278                 break;
2279             case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
2280                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2281                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");  /* Add = a0*a1 + a2*a3 */
2282                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);        /*   a0 = src1/opr1    */
2283                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2284                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2285                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");    /*   a1 = 1 (see docs) */
2286                 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2287                 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2288                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2289                 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2290                 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);        /*   a2 = arg2         */
2291                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2292                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2293                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");     /*  a3 = src1 alpha   */
2294                 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
2295                 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
2296                 switch (opr) {
2297                     case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2298                     case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2299                 }
2300                 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2301                 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2302                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2303                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2304                 break;
2305             case WINED3DTOP_MODULATECOLOR_ADDALPHA:
2306                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2307                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2308                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2309                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2310                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2311                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2312                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2313                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2314                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2315                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2316                 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
2317                 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
2318                 switch (opr1) {
2319                     case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2320                     case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2321                 }
2322                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2323                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2324                 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2325                 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2326                 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2327                 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2328                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2329                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2330                 break;
2331             case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
2332                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2333                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2334                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2335                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2336                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2337                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2338                 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2339                 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2340                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2341                 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2342                 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2343                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2344                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2345                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2346                 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
2347                 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
2348                 switch (opr1) {
2349                     case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2350                     case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2351                     case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2352                     case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2353                 }
2354                 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2355                 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2356                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2357                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2358                 break;
2359             case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
2360                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2361                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2362                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2363                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2364                 switch (opr1) {
2365                     case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2366                     case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2367                     case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2368                     case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2369                 }
2370                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2371                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2372                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2373                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2374                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2375                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2376                 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
2377                 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
2378                 switch (opr1) {
2379                     case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2380                     case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2381                 }
2382                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2383                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2384                 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2385                 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2386                 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2387                 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2388                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2389                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2390                 break;
2391             case WINED3DTOP_MULTIPLYADD:
2392                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2393                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2394                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
2395                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2396                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
2397                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2398                 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2399                 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2400                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2401                 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2402                 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
2403                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2404                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr1);
2405                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2406                 glTexEnvi(GL_TEXTURE_ENV, src3_target, src2);
2407                 checkGLcall("GL_TEXTURE_ENV, src3_target, src3");
2408                 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr2);
2409                 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr3");
2410                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2411                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2412                 break;
2413
2414             case WINED3DTOP_BUMPENVMAP:
2415             {
2416             }
2417
2418             case WINED3DTOP_BUMPENVMAPLUMINANCE:
2419                 FIXME("Implement bump environment mapping in GL_NV_texture_env_combine4 path\n");
2420
2421             default:
2422                 Handled = FALSE;
2423         }
2424         if (Handled) {
2425             glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
2426             checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV");
2427
2428             return;
2429         }
2430     } /* GL_NV_texture_env_combine4 */
2431
2432     Handled = TRUE; /* Again, assume handled */
2433     switch (op) {
2434         case WINED3DTOP_DISABLE: /* Only for alpha */
2435             glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
2436             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2437             glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
2438             checkGLcall("GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT");
2439             glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
2440             checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA");
2441             glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2442             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2443             break;
2444         case WINED3DTOP_SELECTARG1:
2445             glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
2446             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2447             glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2448             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2449             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2450             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2451             glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2452             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2453             break;
2454         case WINED3DTOP_SELECTARG2:
2455             glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
2456             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2457             glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
2458             checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
2459             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
2460             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
2461             glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2462             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2463             break;
2464         case WINED3DTOP_MODULATE:
2465             glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2466             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2467             glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2468             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2469             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2470             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2471             glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2472             checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2473             glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2474             checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2475             glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2476             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2477             break;
2478         case WINED3DTOP_MODULATE2X:
2479             glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2480             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2481             glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2482             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2483             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2484             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2485             glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2486             checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2487             glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2488             checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2489             glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2490             checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2491             break;
2492         case WINED3DTOP_MODULATE4X:
2493             glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2494             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2495             glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2496             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2497             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2498             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2499             glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2500             checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2501             glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2502             checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2503             glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
2504             checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
2505             break;
2506         case WINED3DTOP_ADD:
2507             glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2508             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2509             glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2510             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2511             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2512             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2513             glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2514             checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2515             glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2516             checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2517             glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2518             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2519             break;
2520         case WINED3DTOP_ADDSIGNED:
2521             glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
2522             checkGLcall("GL_TEXTURE_ENV, comb_target, useext((GL_ADD_SIGNED)");
2523             glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2524             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2525             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2526             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2527             glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2528             checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2529             glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2530             checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2531             glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2532             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2533             break;
2534         case WINED3DTOP_ADDSIGNED2X:
2535             glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
2536             checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
2537             glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2538             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2539             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2540             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2541             glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2542             checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2543             glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2544             checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2545             glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2546             checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2547             break;
2548         case WINED3DTOP_SUBTRACT:
2549             if (GL_SUPPORT(ARB_TEXTURE_ENV_COMBINE)) {
2550                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_SUBTRACT);
2551                 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_SUBTRACT)");
2552                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2553                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2554                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2555                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2556                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2557                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2558                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2559                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2560                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2561                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2562             } else {
2563                 FIXME("This version of opengl does not support GL_SUBTRACT\n");
2564             }
2565             break;
2566
2567         case WINED3DTOP_BLENDDIFFUSEALPHA:
2568             glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2569             checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2570             glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2571             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2572             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2573             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2574             glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2575             checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2576             glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2577             checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2578             glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PRIMARY_COLOR));
2579             checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PRIMARY_COLOR");
2580             glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2581             checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2582             glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2583             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2584             break;
2585         case WINED3DTOP_BLENDTEXTUREALPHA:
2586             glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2587             checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2588             glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2589             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2590             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2591             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2592             glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2593             checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2594             glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2595             checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2596             glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_TEXTURE);
2597             checkGLcall("GL_TEXTURE_ENV, src2_target, GL_TEXTURE");
2598             glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2599             checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2600             glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2601             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2602             break;
2603         case WINED3DTOP_BLENDFACTORALPHA:
2604             glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2605             checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2606             glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2607             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2608             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2609             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2610             glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2611             checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2612             glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2613             checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2614             glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_CONSTANT));
2615             checkGLcall("GL_TEXTURE_ENV, src2_target, GL_CONSTANT");
2616             glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2617             checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2618             glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2619             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2620             break;
2621         case WINED3DTOP_BLENDCURRENTALPHA:
2622             glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2623             checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2624             glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2625             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2626             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2627             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2628             glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2629             checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2630             glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2631             checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2632             glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PREVIOUS));
2633             checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PREVIOUS");
2634             glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2635             checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2636             glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2637             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2638             break;
2639         case WINED3DTOP_DOTPRODUCT3:
2640             if (GL_SUPPORT(ARB_TEXTURE_ENV_DOT3)) {
2641                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB);
2642                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB");
2643             } else if (GL_SUPPORT(EXT_TEXTURE_ENV_DOT3)) {
2644                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT);
2645                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT");
2646             } else {
2647                 FIXME("This version of opengl does not support GL_DOT3\n");
2648             }
2649             glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2650             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2651             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2652             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2653             glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2654             checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2655             glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2656             checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2657             glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2658             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2659             break;
2660         case WINED3DTOP_LERP:
2661             glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2662             checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2663             glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2664             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2665             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2666             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2667             glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2668             checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2669             glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2670             checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2671             glTexEnvi(GL_TEXTURE_ENV, src2_target, src3);
2672             checkGLcall("GL_TEXTURE_ENV, src2_target, src3");
2673             glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr3);
2674             checkGLcall("GL_TEXTURE_ENV, opr2_target, opr3");
2675             glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2676             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2677             break;
2678         case WINED3DTOP_ADDSMOOTH:
2679             if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2680                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2681                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2682                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2683                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2684                 switch (opr1) {
2685                     case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2686                     case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2687                     case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2688                     case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2689                 }
2690                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2691                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2692                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2693                 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2694                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2695                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2696                 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2697                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2698                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2699                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2700                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2701                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2702             } else
2703                 Handled = FALSE;
2704                 break;
2705         case WINED3DTOP_BLENDTEXTUREALPHAPM:
2706             if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2707                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2708                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2709                 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_TEXTURE);
2710                 checkGLcall("GL_TEXTURE_ENV, src0_target, GL_TEXTURE");
2711                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_ALPHA);
2712                 checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_APHA");
2713                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2714                 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2715                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2716                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2717                 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2718                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2719                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2720                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2721                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2722                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2723             } else
2724                 Handled = FALSE;
2725                 break;
2726         case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
2727             if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2728                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2729                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2730                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2731                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2732                 switch (opr1) {
2733                     case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2734                     case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2735                     case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2736                     case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2737                 }
2738                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2739                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2740                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2741                 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2742                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2743                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2744                 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2745                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2746                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2747                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2748                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2749                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2750             } else
2751                 Handled = FALSE;
2752                 break;
2753         case WINED3DTOP_MODULATECOLOR_ADDALPHA:
2754             if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2755                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2756                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2757                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2758                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2759                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2760                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2761                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2762                 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2763                 switch (opr1) {
2764                     case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2765                     case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2766                     case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2767                     case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2768                 }
2769                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
2770                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
2771                 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2772                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2773                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2774                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2775                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2776                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2777             } else
2778                 Handled = FALSE;
2779                 break;
2780         case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
2781             if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2782                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2783                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2784                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2785                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2786                 switch (opr1) {
2787                     case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2788                     case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2789                     case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2790                     case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2791                 }
2792                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2793                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2794                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2795                 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2796                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2797                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2798                 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2799                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2800                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2801                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2802                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2803                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2804             } else
2805                 Handled = FALSE;
2806                 break;
2807         case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
2808             if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2809                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2810                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2811                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2812                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2813                 switch (opr1) {
2814                     case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2815                     case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2816                     case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2817                     case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2818                 }
2819                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2820                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2821                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2822                 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2823                 switch (opr1) {
2824                     case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2825                     case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2826                     case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2827                     case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2828                 }
2829                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
2830                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
2831                 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2832                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2833                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2834                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2835                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2836                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2837             } else
2838                 Handled = FALSE;
2839                 break;
2840         case WINED3DTOP_MULTIPLYADD:
2841             if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2842                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2843                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2844                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2845                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2846                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2847                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2848                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src3);
2849                 checkGLcall("GL_TEXTURE_ENV, src1_target, src3");
2850                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr3);
2851                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr3");
2852                 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2853                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2854                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2855                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2856                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2857                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2858             } else
2859                 Handled = FALSE;
2860                 break;
2861         case WINED3DTOP_BUMPENVMAPLUMINANCE:
2862             if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
2863                     /* Some apps use BUMPENVMAPLUMINANCE instead of D3DTOP_BUMPENVMAP, although
2864                 * they check for the non-luminance cap flag. Well, give them what they asked
2865                 * for :-)
2866                     */
2867                 WARN("Application uses WINED3DTOP_BUMPENVMAPLUMINANCE\n");
2868             } else {
2869                 Handled = FALSE;
2870                 break;
2871             }
2872             /* Fall through */
2873         case WINED3DTOP_BUMPENVMAP:
2874             if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
2875                 TRACE("Using ati bumpmap on stage %d, target %d\n", Stage, Stage + 1);
2876                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_BUMP_ENVMAP_ATI);
2877                 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_BUMP_ENVMAP_ATI)");
2878                 glTexEnvi(GL_TEXTURE_ENV, GL_BUMP_TARGET_ATI, GL_TEXTURE0_ARB + Stage + 1);
2879                 checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_BUMP_TARGET_ATI, GL_TEXTURE0_ARB + Stage + 1)");
2880                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
2881                 checkGLcall("GL_TEXTURE_ENV, src0_target, src3");
2882                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
2883                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr3");
2884                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2885                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2886                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2887                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2888                 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2889                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2890                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2891                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2892
2893                 Handled = TRUE;
2894                 break;
2895             } else if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
2896                 /* Technically texture shader support without register combiners is possible, but not expected to occur
2897                  * on real world cards, so for now a fixme should be enough
2898                  */
2899                 FIXME("Implement bump mapping with GL_NV_texture_shader in non register combiner path\n");
2900             }
2901         default:
2902             Handled = FALSE;
2903     }
2904
2905     if (Handled) {
2906         BOOL  combineOK = TRUE;
2907         if (GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
2908             DWORD op2;
2909
2910             if (isAlpha) {
2911                 op2 = This->stateBlock->textureState[Stage][WINED3DTSS_COLOROP];
2912             } else {
2913                 op2 = This->stateBlock->textureState[Stage][WINED3DTSS_ALPHAOP];
2914             }
2915
2916             /* Note: If COMBINE4 in effect can't go back to combine! */
2917             switch (op2) {
2918                 case WINED3DTOP_ADDSMOOTH:
2919                 case WINED3DTOP_BLENDTEXTUREALPHAPM:
2920                 case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
2921                 case WINED3DTOP_MODULATECOLOR_ADDALPHA:
2922                 case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
2923                 case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
2924                 case WINED3DTOP_MULTIPLYADD:
2925                     /* Ignore those implemented in both cases */
2926                     switch (op) {
2927                         case WINED3DTOP_SELECTARG1:
2928                         case WINED3DTOP_SELECTARG2:
2929                             combineOK = FALSE;
2930                             Handled   = FALSE;
2931                             break;
2932                         default:
2933                             FIXME("Can't use COMBINE4 and COMBINE together, thisop=%s, otherop=%s, isAlpha(%d)\n", debug_d3dtop(op), debug_d3dtop(op2), isAlpha);
2934                             return;
2935                     }
2936             }
2937         }
2938
2939         if (combineOK) {
2940             glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE));
2941             checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE)");
2942
2943             return;
2944         }
2945     }
2946
2947     /* After all the extensions, if still unhandled, report fixme */
2948     FIXME("Unhandled texture operation %s\n", debug_d3dtop(op));
2949 }
2950
2951
2952 static void tex_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2953     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
2954     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage];
2955     BOOL tex_used = stateblock->wineD3DDevice->fixed_function_usage_map[stage];
2956
2957     TRACE("Setting color op for stage %d\n", stage);
2958
2959     if (stateblock->pixelShader && stateblock->wineD3DDevice->ps_selected_mode != SHADER_NONE &&
2960         ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.function) {
2961         /* Using a pixel shader? Don't care for anything here, the shader applying does it */
2962         return;
2963     }
2964
2965     if (stage != mapped_stage) WARN("Using non 1:1 mapping: %d -> %d!\n", stage, mapped_stage);
2966
2967     if (mapped_stage != -1) {
2968         if (GL_SUPPORT(ARB_MULTITEXTURE)) {
2969             if (tex_used && mapped_stage >= GL_LIMITS(textures)) {
2970                 FIXME("Attempt to enable unsupported stage!\n");
2971                 return;
2972             }
2973             GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
2974             checkGLcall("glActiveTextureARB");
2975         } else if (stage > 0) {
2976             WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
2977             return;
2978         }
2979     }
2980
2981     if(stage >= stateblock->lowest_disabled_stage) {
2982         TRACE("Stage disabled\n");
2983         if (mapped_stage != -1) {
2984             /* Disable everything here */
2985             glDisable(GL_TEXTURE_2D);
2986             checkGLcall("glDisable(GL_TEXTURE_2D)");
2987             glDisable(GL_TEXTURE_3D);
2988             checkGLcall("glDisable(GL_TEXTURE_3D)");
2989             if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2990                 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2991                 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2992             }
2993             if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2994                 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2995                 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2996             }
2997         }
2998         /* All done */
2999         return;
3000     }
3001
3002     /* The sampler will also activate the correct texture dimensions, so no need to do it here
3003      * if the sampler for this stage is dirty
3004      */
3005     if(!isStateDirty(context, STATE_SAMPLER(stage))) {
3006         if (tex_used) texture_activate_dimensions(stage, stateblock, context);
3007     }
3008
3009     set_tex_op((IWineD3DDevice *)stateblock->wineD3DDevice, FALSE, stage,
3010                 stateblock->textureState[stage][WINED3DTSS_COLOROP],
3011                 stateblock->textureState[stage][WINED3DTSS_COLORARG1],
3012                 stateblock->textureState[stage][WINED3DTSS_COLORARG2],
3013                 stateblock->textureState[stage][WINED3DTSS_COLORARG0]);
3014 }
3015
3016 void tex_alphaop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
3017     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
3018     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage];
3019     BOOL tex_used = stateblock->wineD3DDevice->fixed_function_usage_map[stage];
3020     DWORD op, arg1, arg2, arg0;
3021
3022     TRACE("Setting alpha op for stage %d\n", stage);
3023     /* Do not care for enabled / disabled stages, just assign the settings. colorop disables / enables required stuff */
3024     if (mapped_stage != -1) {
3025         if (GL_SUPPORT(ARB_MULTITEXTURE)) {
3026             if (tex_used && mapped_stage >= GL_LIMITS(textures)) {
3027                 FIXME("Attempt to enable unsupported stage!\n");
3028                 return;
3029             }
3030             GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
3031             checkGLcall("glActiveTextureARB");
3032         } else if (stage > 0) {
3033             /* We can't do anything here */
3034             WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
3035             return;
3036         }
3037     }
3038
3039     op = stateblock->textureState[stage][WINED3DTSS_ALPHAOP];
3040     arg1 = stateblock->textureState[stage][WINED3DTSS_ALPHAARG1];
3041     arg2 = stateblock->textureState[stage][WINED3DTSS_ALPHAARG2];
3042     arg0 = stateblock->textureState[stage][WINED3DTSS_ALPHAARG0];
3043
3044     if(stateblock->renderState[WINED3DRS_COLORKEYENABLE] && stage == 0 &&
3045        stateblock->textures[0] &&
3046        (stateblock->textureDimensions[0] == GL_TEXTURE_2D || stateblock->textureDimensions[0] == GL_TEXTURE_RECTANGLE_ARB)) {
3047         IWineD3DSurfaceImpl *surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *) stateblock->textures[0])->surfaces[0];
3048
3049         if(surf->CKeyFlags & WINEDDSD_CKSRCBLT &&
3050            getFormatDescEntry(surf->resource.format, NULL, NULL)->alphaMask == 0x00000000) {
3051
3052             /* Color keying needs to pass alpha values from the texture through to have the alpha test work properly.
3053              * On the other hand applications can still use texture combiners apparently. This code takes care that apps
3054              * cannot remove the texture's alpha channel entirely.
3055              *
3056              * The fixup is required for Prince of Persia 3D(prison bars), while Moto racer 2 requires D3DTOP_MODULATE to work
3057              * on color keyed surfaces. Aliens vs Predator 1 uses color keyed textures and alpha component of diffuse color to
3058              * draw things like translucent text and perform other blending effects.
3059              *
3060              * Aliens vs Predator 1 relies on diffuse alpha having an effect, so it cannot be ignored. To provide the
3061              * behavior expected by the game, while emulating the colorkey, diffuse alpha must be modulated with texture alpha.
3062              * OTOH, Moto racer 2 at some points sets alphaop/alphaarg to SELECTARG/CURRENT, yet puts garbage in diffuse alpha
3063              * (zeroes). This works on native, because the game disables alpha test and alpha blending. Alpha test is overwritten by
3064              * wine's for purposes of color-keying though, so this will lead to missing geometry if texture alpha is modulated
3065              * (pixels fail alpha test). To get around this, ALPHABLENDENABLE state is checked: if the app enables alpha blending,
3066              * it can be expected to provide meaningful values in diffuse alpha, so it should be modulated with texture alpha;
3067              * otherwise, selecting diffuse alpha is ignored in favour of texture alpha.
3068
3069              * What to do with multitexturing? So far no app has been found that uses color keying with multitexturing
3070              */
3071             if(op == WINED3DTOP_DISABLE) {
3072                 arg1 = WINED3DTA_TEXTURE;
3073                 op = WINED3DTOP_SELECTARG1;
3074             }
3075             else if(op == WINED3DTOP_SELECTARG1 && arg1 != WINED3DTA_TEXTURE) {
3076                 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE]) {
3077                     arg2 = WINED3DTA_TEXTURE;
3078                     op = WINED3DTOP_MODULATE;
3079                 }
3080                 else arg1 = WINED3DTA_TEXTURE;
3081             }
3082             else if(op == WINED3DTOP_SELECTARG2 && arg2 != WINED3DTA_TEXTURE) {
3083                 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE]) {
3084                     arg1 = WINED3DTA_TEXTURE;
3085                     op = WINED3DTOP_MODULATE;
3086                 }
3087                 else arg2 = WINED3DTA_TEXTURE;
3088             }
3089         }
3090     }
3091
3092     /* tex_alphaop is shared between the ffp and nvrc because the difference only comes down to
3093      * this if block here, and the other code(color keying, texture unit selection) are the same
3094      */
3095     TRACE("Setting alpha op for stage %d\n", stage);
3096     if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
3097         set_tex_op_nvrc((IWineD3DDevice *)stateblock->wineD3DDevice, TRUE, stage,
3098                          op, arg1, arg2, arg0,
3099                          mapped_stage,
3100                          stateblock->textureState[stage][WINED3DTSS_RESULTARG]);
3101     } else {
3102         set_tex_op((IWineD3DDevice *)stateblock->wineD3DDevice, TRUE, stage,
3103                     op, arg1, arg2, arg0);
3104     }
3105 }
3106
3107 static void transform_texture(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
3108     DWORD texUnit = state - STATE_TRANSFORM(WINED3DTS_TEXTURE0);
3109     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[texUnit];
3110     BOOL generated;
3111     int coordIdx;
3112
3113     /* Ignore this when a vertex shader is used, or if the streams aren't sorted out yet */
3114     if(use_vs(stateblock->wineD3DDevice) ||
3115        isStateDirty(context, STATE_VDECL)) {
3116         TRACE("Using a vertex shader, or stream sources not sorted out yet, skipping\n");
3117         return;
3118     }
3119
3120     if (mapped_stage == -1) return;
3121
3122     if (GL_SUPPORT(ARB_MULTITEXTURE)) {
3123         if(mapped_stage >= GL_LIMITS(textures)) {
3124             return;
3125         }
3126         GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
3127         checkGLcall("glActiveTextureARB");
3128     } else if (mapped_stage > 0) {
3129         /* We can't do anything here */
3130         WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
3131         return;
3132     }
3133     generated = (stateblock->textureState[texUnit][WINED3DTSS_TEXCOORDINDEX] & 0xFFFF0000) != WINED3DTSS_TCI_PASSTHRU;
3134     coordIdx = min(stateblock->textureState[texUnit][WINED3DTSS_TEXCOORDINDEX & 0x0000FFFF], MAX_TEXTURES - 1);
3135
3136     set_texture_matrix(&stateblock->transforms[WINED3DTS_TEXTURE0 + texUnit].u.m[0][0],
3137                         stateblock->textureState[texUnit][WINED3DTSS_TEXTURETRANSFORMFLAGS],
3138                         generated,
3139                         context->last_was_rhw,
3140                         stateblock->wineD3DDevice->strided_streams.u.s.texCoords[coordIdx].dwStride ?
3141                             stateblock->wineD3DDevice->strided_streams.u.s.texCoords[coordIdx].dwType:
3142                             WINED3DDECLTYPE_UNUSED);
3143
3144     /* The sampler applying function calls us if this changes */
3145     if(context->lastWasPow2Texture[texUnit] && stateblock->textures[texUnit]) {
3146         if(generated) {
3147             FIXME("Non-power2 texture being used with generated texture coords\n");
3148         }
3149         TRACE("Non power two matrix multiply fixup\n");
3150         glMultMatrixf(((IWineD3DTextureImpl *) stateblock->textures[texUnit])->baseTexture.pow2Matrix);
3151     }
3152 }
3153
3154 static void unloadTexCoords(IWineD3DStateBlockImpl *stateblock) {
3155     int texture_idx;
3156
3157     for (texture_idx = 0; texture_idx < GL_LIMITS(texture_stages); ++texture_idx) {
3158         GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + texture_idx));
3159         glDisableClientState(GL_TEXTURE_COORD_ARRAY);
3160     }
3161 }
3162
3163 static void loadTexCoords(IWineD3DStateBlockImpl *stateblock, WineDirect3DVertexStridedData *sd, GLint *curVBO) {
3164     UINT *offset = stateblock->streamOffset;
3165     unsigned int mapped_stage = 0;
3166     unsigned int textureNo = 0;
3167
3168     /* The code below uses glClientActiveTexture and glMultiTexCoord* which are all part of the GL_ARB_multitexture extension. */
3169     /* Abort if we don't support the extension. */
3170     if (!GL_SUPPORT(ARB_MULTITEXTURE)) {
3171         FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
3172         return;
3173     }
3174
3175     for (textureNo = 0; textureNo < GL_LIMITS(texture_stages); ++textureNo) {
3176         int coordIdx = stateblock->textureState[textureNo][WINED3DTSS_TEXCOORDINDEX];
3177
3178         mapped_stage = stateblock->wineD3DDevice->texUnitMap[textureNo];
3179         if (mapped_stage == -1) continue;
3180
3181         if (coordIdx < MAX_TEXTURES && (sd->u.s.texCoords[coordIdx].lpData || sd->u.s.texCoords[coordIdx].VBO)) {
3182             TRACE("Setting up texture %u, idx %d, cordindx %u, data %p\n",
3183                     textureNo, mapped_stage, coordIdx, sd->u.s.texCoords[coordIdx].lpData);
3184
3185             if (*curVBO != sd->u.s.texCoords[coordIdx].VBO) {
3186                 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.texCoords[coordIdx].VBO));
3187                 checkGLcall("glBindBufferARB");
3188                 *curVBO = sd->u.s.texCoords[coordIdx].VBO;
3189             }
3190
3191             GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
3192             checkGLcall("glClientActiveTextureARB");
3193
3194             /* The coords to supply depend completely on the fvf / vertex shader */
3195             glTexCoordPointer(
3196                     WINED3D_ATR_SIZE(sd->u.s.texCoords[coordIdx].dwType),
3197                     WINED3D_ATR_GLTYPE(sd->u.s.texCoords[coordIdx].dwType),
3198                     sd->u.s.texCoords[coordIdx].dwStride,
3199                     sd->u.s.texCoords[coordIdx].lpData + stateblock->loadBaseVertexIndex * sd->u.s.texCoords[coordIdx].dwStride + offset[sd->u.s.texCoords[coordIdx].streamNo]);
3200             glEnableClientState(GL_TEXTURE_COORD_ARRAY);
3201         } else {
3202             GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + mapped_stage, 0, 0, 0, 1));
3203         }
3204     }
3205     if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
3206         /* The number of the mapped stages increases monotonically, so it's fine to use the last used one */
3207         for (textureNo = mapped_stage + 1; textureNo < GL_LIMITS(textures); ++textureNo) {
3208             GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, 0, 0, 0, 1));
3209         }
3210     }
3211 }
3212
3213 static void tex_coordindex(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
3214     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
3215     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage];
3216
3217     if (mapped_stage == -1) {
3218         TRACE("No texture unit mapped to stage %d. Skipping texture coordinates.\n", stage);
3219         return;
3220     }
3221
3222     if (GL_SUPPORT(ARB_MULTITEXTURE)) {
3223         if(mapped_stage >= GL_LIMITS(fragment_samplers)) {
3224             return;
3225         }
3226         GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
3227         checkGLcall("glActiveTextureARB");
3228     } else if (stage > 0) {
3229         /* We can't do anything here */
3230         WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
3231         return;
3232     }
3233
3234     /* Values 0-7 are indexes into the FVF tex coords - See comments in DrawPrimitive
3235      *
3236      * FIXME: From MSDN: The WINED3DTSS_TCI_* flags are mutually exclusive. If you include
3237      * one flag, you can still specify an index value, which the system uses to
3238      * determine the texture wrapping mode.
3239      * eg. SetTextureStageState( 0, WINED3DTSS_TEXCOORDINDEX, WINED3DTSS_TCI_CAMERASPACEPOSITION | 1 );
3240      * means use the vertex position (camera-space) as the input texture coordinates
3241      * for this texture stage, and the wrap mode set in the WINED3DRS_WRAP1 render
3242      * state. We do not (yet) support the WINED3DRENDERSTATE_WRAPx values, nor tie them up
3243      * to the TEXCOORDINDEX value
3244      */
3245
3246     /*
3247      * Be careful the value of the mask 0xF0000 come from d3d8types.h infos
3248      */
3249     switch (stateblock->textureState[stage][WINED3DTSS_TEXCOORDINDEX] & 0xFFFF0000) {
3250     case WINED3DTSS_TCI_PASSTHRU:
3251         /*Use the specified texture coordinates contained within the vertex format. This value resolves to zero.*/
3252         glDisable(GL_TEXTURE_GEN_S);
3253         glDisable(GL_TEXTURE_GEN_T);
3254         glDisable(GL_TEXTURE_GEN_R);
3255         glDisable(GL_TEXTURE_GEN_Q);
3256         checkGLcall("glDisable(GL_TEXTURE_GEN_S,T,R,Q)");
3257         break;
3258
3259     case WINED3DTSS_TCI_CAMERASPACEPOSITION:
3260         /* CameraSpacePosition means use the vertex position, transformed to camera space,
3261          * as the input texture coordinates for this stage's texture transformation. This
3262          * equates roughly to EYE_LINEAR
3263          */
3264         {
3265             float s_plane[] = { 1.0, 0.0, 0.0, 0.0 };
3266             float t_plane[] = { 0.0, 1.0, 0.0, 0.0 };
3267             float r_plane[] = { 0.0, 0.0, 1.0, 0.0 };
3268             float q_plane[] = { 0.0, 0.0, 0.0, 1.0 };
3269             TRACE("WINED3DTSS_TCI_CAMERASPACEPOSITION - Set eye plane\n");
3270
3271             glMatrixMode(GL_MODELVIEW);
3272             glPushMatrix();
3273             glLoadIdentity();
3274             glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
3275             glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
3276             glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
3277             glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
3278             glPopMatrix();
3279
3280             TRACE("WINED3DTSS_TCI_CAMERASPACEPOSITION - Set GL_TEXTURE_GEN_x and GL_x, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR\n");
3281             glEnable(GL_TEXTURE_GEN_S);
3282             checkGLcall("glEnable(GL_TEXTURE_GEN_S)");
3283             glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
3284             checkGLcall("glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)");
3285             glEnable(GL_TEXTURE_GEN_T);
3286             checkGLcall("glEnable(GL_TEXTURE_GEN_T)");
3287             glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
3288             checkGLcall("glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)");
3289             glEnable(GL_TEXTURE_GEN_R);
3290             checkGLcall("glEnable(GL_TEXTURE_GEN_R)");
3291             glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
3292             checkGLcall("glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)");
3293         }
3294         break;
3295
3296     case WINED3DTSS_TCI_CAMERASPACENORMAL:
3297         {
3298             if (GL_SUPPORT(NV_TEXGEN_REFLECTION)) {
3299                 float s_plane[] = { 1.0, 0.0, 0.0, 0.0 };
3300                 float t_plane[] = { 0.0, 1.0, 0.0, 0.0 };
3301                 float r_plane[] = { 0.0, 0.0, 1.0, 0.0 };
3302                 float q_plane[] = { 0.0, 0.0, 0.0, 1.0 };
3303                 TRACE("WINED3DTSS_TCI_CAMERASPACENORMAL - Set eye plane\n");
3304
3305                 glMatrixMode(GL_MODELVIEW);
3306                 glPushMatrix();
3307                 glLoadIdentity();
3308                 glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
3309                 glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
3310                 glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
3311                 glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
3312                 glPopMatrix();
3313
3314                 glEnable(GL_TEXTURE_GEN_S);
3315                 checkGLcall("glEnable(GL_TEXTURE_GEN_S)");
3316                 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
3317                 checkGLcall("glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV)");
3318                 glEnable(GL_TEXTURE_GEN_T);
3319                 checkGLcall("glEnable(GL_TEXTURE_GEN_T)");
3320                 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
3321                 checkGLcall("glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV)");
3322                 glEnable(GL_TEXTURE_GEN_R);
3323                 checkGLcall("glEnable(GL_TEXTURE_GEN_R)");
3324                 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
3325                 checkGLcall("glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV)");
3326             }
3327         }
3328         break;
3329
3330     case WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR:
3331         {
3332             if (GL_SUPPORT(NV_TEXGEN_REFLECTION)) {
3333             float s_plane[] = { 1.0, 0.0, 0.0, 0.0 };
3334             float t_plane[] = { 0.0, 1.0, 0.0, 0.0 };
3335             float r_plane[] = { 0.0, 0.0, 1.0, 0.0 };
3336             float q_plane[] = { 0.0, 0.0, 0.0, 1.0 };
3337             TRACE("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Set eye plane\n");
3338
3339             glMatrixMode(GL_MODELVIEW);
3340             glPushMatrix();
3341             glLoadIdentity();
3342             glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
3343             glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
3344             glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
3345             glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
3346             glPopMatrix();
3347
3348             glEnable(GL_TEXTURE_GEN_S);
3349             checkGLcall("glEnable(GL_TEXTURE_GEN_S)");
3350             glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
3351             checkGLcall("glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV)");
3352             glEnable(GL_TEXTURE_GEN_T);
3353             checkGLcall("glEnable(GL_TEXTURE_GEN_T)");
3354             glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
3355             checkGLcall("glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV)");
3356             glEnable(GL_TEXTURE_GEN_R);
3357             checkGLcall("glEnable(GL_TEXTURE_GEN_R)");
3358             glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
3359             checkGLcall("glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV)");
3360             }
3361         }
3362         break;
3363
3364     /* Unhandled types: */
3365     default:
3366         /* Todo: */
3367         /* ? disable GL_TEXTURE_GEN_n ? */
3368         glDisable(GL_TEXTURE_GEN_S);
3369         glDisable(GL_TEXTURE_GEN_T);
3370         glDisable(GL_TEXTURE_GEN_R);
3371         glDisable(GL_TEXTURE_GEN_Q);
3372         FIXME("Unhandled WINED3DTSS_TEXCOORDINDEX %x\n", stateblock->textureState[stage][WINED3DTSS_TEXCOORDINDEX]);
3373         break;
3374     }
3375
3376     /* Update the texture matrix */
3377     if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_TEXTURE0 + stage))) {
3378         transform_texture(STATE_TRANSFORM(WINED3DTS_TEXTURE0 + stage), stateblock, context);
3379     }
3380
3381     if(!isStateDirty(context, STATE_VDECL) && context->namedArraysLoaded) {
3382         /* Reload the arrays if we are using fixed function arrays to reflect the selected coord input
3383          * source. Call loadTexCoords directly because there is no need to reparse the vertex declaration
3384          * and do all the things linked to it
3385          * TODO: Tidy that up to reload only the arrays of the changed unit
3386          */
3387         GLint curVBO = GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT) ? -1 : 0;
3388
3389         unloadTexCoords(stateblock);
3390         loadTexCoords(stateblock, &stateblock->wineD3DDevice->strided_streams, &curVBO);
3391     }
3392 }
3393
3394 static void shaderconstant(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
3395     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
3396
3397     /* Vertex and pixel shader states will call a shader upload, don't do anything as long one of them
3398      * has an update pending
3399      */
3400     if(isStateDirty(context, STATE_VDECL) ||
3401        isStateDirty(context, STATE_PIXELSHADER)) {
3402        return;
3403     }
3404
3405     device->shader_backend->shader_load_constants((IWineD3DDevice *) device, use_ps(device), use_vs(device));
3406 }
3407
3408 static void tex_bumpenvlscale(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
3409     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
3410     union {
3411         DWORD d;
3412         float f;
3413     } tmpvalue;
3414
3415     if(stateblock->pixelShader && stage != 0 &&
3416        ((IWineD3DPixelShaderImpl *) stateblock->pixelShader)->baseShader.reg_maps.luminanceparams[stage]) {
3417         /* The pixel shader has to know the luminance scale. Do a constants update if it
3418          * isn't scheduled anyway
3419          */
3420         if(!isStateDirty(context, STATE_PIXELSHADERCONSTANT) &&
3421            !isStateDirty(context, STATE_PIXELSHADER)) {
3422             shaderconstant(STATE_PIXELSHADERCONSTANT, stateblock, context);
3423         }
3424     }
3425
3426     tmpvalue.d = stateblock->textureState[stage][WINED3DTSS_BUMPENVLSCALE];
3427     if(tmpvalue.f != 0.0) {
3428         FIXME("WINED3DTSS_BUMPENVLSCALE not supported yet\n");
3429     }
3430 }
3431
3432 static void tex_bumpenvloffset(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
3433     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
3434     union {
3435         DWORD d;
3436         float f;
3437     } tmpvalue;
3438
3439     if(stateblock->pixelShader && stage != 0 &&
3440        ((IWineD3DPixelShaderImpl *) stateblock->pixelShader)->baseShader.reg_maps.luminanceparams[stage]) {
3441         /* The pixel shader has to know the luminance offset. Do a constants update if it
3442          * isn't scheduled anyway
3443          */
3444         if(!isStateDirty(context, STATE_PIXELSHADERCONSTANT) &&
3445            !isStateDirty(context, STATE_PIXELSHADER)) {
3446             shaderconstant(STATE_PIXELSHADERCONSTANT, stateblock, context);
3447         }
3448     }
3449
3450     tmpvalue.d = stateblock->textureState[stage][WINED3DTSS_BUMPENVLOFFSET];
3451     if(tmpvalue.f != 0.0) {
3452         FIXME("WINED3DTSS_BUMPENVLOFFSET not supported yet\n");
3453     }
3454 }
3455
3456 static void sampler_texmatrix(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
3457     BOOL texIsPow2 = FALSE;
3458     DWORD sampler = state - STATE_SAMPLER(0);
3459     IWineD3DBaseTexture *texture = stateblock->textures[sampler];
3460
3461     if(!texture) return;
3462     /* The fixed function np2 texture emulation uses the texture matrix to fix up the coordinates
3463      * IWineD3DBaseTexture::ApplyStateChanges multiplies the set matrix with a fixup matrix. Before the
3464      * scaling is reapplied or removed, the texture matrix has to be reapplied
3465      *
3466      * The mapped stage is alrady active because the sampler() function below, which is part of the
3467      * misc pipeline
3468      */
3469     if(sampler < MAX_TEXTURES) {
3470         if(stateblock->textureDimensions[sampler] == GL_TEXTURE_2D ||
3471            stateblock->textureDimensions[sampler] == GL_TEXTURE_RECTANGLE_ARB) {
3472             if(((IWineD3DTextureImpl *)texture)->baseTexture.pow2Matrix[0] != 1.0 ||
3473                ((IWineD3DTextureImpl *)texture)->baseTexture.pow2Matrix[5] != 1.0 ) {
3474                 texIsPow2 = TRUE;
3475             }
3476         } else if(stateblock->textureDimensions[sampler] == GL_TEXTURE_CUBE_MAP_ARB) {
3477             if(((IWineD3DCubeTextureImpl *)texture)->baseTexture.pow2Matrix[0] != 1.0) {
3478                 texIsPow2 = TRUE;
3479             }
3480         }
3481
3482         if(texIsPow2 || context->lastWasPow2Texture[sampler]) {
3483             context->lastWasPow2Texture[sampler] = texIsPow2;
3484             transform_texture(STATE_TRANSFORM(WINED3DTS_TEXTURE0 + stateblock->wineD3DDevice->texUnitMap[sampler]), stateblock, context);
3485         }
3486     }
3487 }
3488
3489 static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
3490     DWORD sampler = state - STATE_SAMPLER(0);
3491     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[sampler];
3492     union {
3493         float f;
3494         DWORD d;
3495     } tmpvalue;
3496
3497     TRACE("Sampler: %d\n", sampler);
3498     /* Enabling and disabling texture dimensions is done by texture stage state / pixel shader setup, this function
3499      * only has to bind textures and set the per texture states
3500      */
3501
3502     if (mapped_stage == -1) {
3503         TRACE("No sampler mapped to stage %d. Returning.\n", sampler);
3504         return;
3505     }
3506
3507     if (GL_SUPPORT(ARB_MULTITEXTURE)) {
3508         if (mapped_stage >= GL_LIMITS(combined_samplers)) {
3509             return;
3510         }
3511         GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
3512         checkGLcall("glActiveTextureARB");
3513     } else if (sampler > 0) {
3514         /* We can't do anything here */
3515         WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
3516         return;
3517     }
3518
3519     if(stateblock->textures[sampler]) {
3520         IWineD3DBaseTexture_PreLoad(stateblock->textures[sampler]);
3521         IWineD3DBaseTexture_ApplyStateChanges(stateblock->textures[sampler], stateblock->textureState[sampler], stateblock->samplerState[sampler]);
3522
3523         if (GL_SUPPORT(EXT_TEXTURE_LOD_BIAS)) {
3524             tmpvalue.d = stateblock->samplerState[sampler][WINED3DSAMP_MIPMAPLODBIAS];
3525             glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT,
3526                       GL_TEXTURE_LOD_BIAS_EXT,
3527                       tmpvalue.f);
3528             checkGLcall("glTexEnvi(GL_TEXTURE_LOD_BIAS_EXT, ...)");
3529         }
3530
3531         if(!use_ps(stateblock->wineD3DDevice) && sampler < stateblock->lowest_disabled_stage) {
3532             if(stateblock->renderState[WINED3DRS_COLORKEYENABLE] && sampler == 0) {
3533                 /* If color keying is enabled update the alpha test, it depends on the existence
3534                  * of a color key in stage 0
3535                  */
3536                 state_alpha(WINED3DRS_COLORKEYENABLE, stateblock, context);
3537             }
3538         }
3539     } else if(mapped_stage < GL_LIMITS(textures)) {
3540         if(sampler < stateblock->lowest_disabled_stage) {
3541             /* TODO: What should I do with pixel shaders here ??? */
3542             if(stateblock->renderState[WINED3DRS_COLORKEYENABLE] && sampler == 0) {
3543                 /* If color keying is enabled update the alpha test, it depends on the existence
3544                 * of a color key in stage 0
3545                 */
3546                 state_alpha(WINED3DRS_COLORKEYENABLE, stateblock, context);
3547             }
3548         } /* Otherwise tex_colorop disables the stage */
3549         glBindTexture(GL_TEXTURE_2D, stateblock->wineD3DDevice->dummyTextureName[sampler]);
3550         checkGLcall("glBindTexture(GL_TEXTURE_2D, stateblock->wineD3DDevice->dummyTextureName[sampler])");
3551     }
3552 }
3553
3554 void apply_pshader_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
3555     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
3556
3557     if (use_ps(device)) {
3558         if(!context->last_was_pshader) {
3559             state_fog(state, stateblock, context);
3560         }
3561         context->last_was_pshader = TRUE;
3562     } else {
3563         if(context->last_was_pshader) {
3564             state_fog(state, stateblock, context);
3565         }
3566         context->last_was_pshader = FALSE;
3567     }
3568 }
3569
3570 void apply_pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
3571     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
3572     BOOL use_pshader = use_ps(device);
3573     BOOL use_vshader = use_vs(device);
3574     int i;
3575
3576     if (use_pshader) {
3577         if(!context->last_was_pshader) {
3578             /* Former draw without a pixel shader, some samplers
3579              * may be disabled because of WINED3DTSS_COLOROP = WINED3DTOP_DISABLE
3580              * make sure to enable them
3581              */
3582             for(i=0; i < MAX_FRAGMENT_SAMPLERS; i++) {
3583                 if(!isStateDirty(context, STATE_SAMPLER(i))) {
3584                     sampler(STATE_SAMPLER(i), stateblock, context);
3585                 }
3586             }
3587         } else {
3588            /* Otherwise all samplers were activated by the code above in earlier draws, or by sampler()
3589             * if a different texture was bound. I don't have to do anything.
3590             */
3591         }
3592
3593         /* Compile and bind the shader */
3594         IWineD3DPixelShader_CompileShader(stateblock->pixelShader);
3595     } else {
3596         /* Disabled the pixel shader - color ops weren't applied
3597          * while it was enabled, so re-apply them.
3598          */
3599         for(i=0; i < MAX_TEXTURES; i++) {
3600             if(!isStateDirty(context, STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP))) {
3601                 device->StateTable[STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP)].apply
3602                         (STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP), stateblock, context);
3603             }
3604         }
3605     }
3606
3607     if(!isStateDirty(context, device->StateTable[STATE_VSHADER].representative)) {
3608         device->shader_backend->shader_select((IWineD3DDevice *)stateblock->wineD3DDevice, use_pshader, use_vshader);
3609
3610         if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && (use_vshader || use_pshader)) {
3611             shaderconstant(STATE_VERTEXSHADERCONSTANT, stateblock, context);
3612         }
3613     }
3614 }
3615
3616 static void shader_bumpenvmat(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
3617     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
3618     if(stateblock->pixelShader && stage != 0 &&
3619        ((IWineD3DPixelShaderImpl *) stateblock->pixelShader)->baseShader.reg_maps.bumpmat[stage]) {
3620         /* The pixel shader has to know the bump env matrix. Do a constants update if it isn't scheduled
3621          * anyway
3622          */
3623         if(!isStateDirty(context, STATE_PIXELSHADERCONSTANT) &&
3624             !isStateDirty(context, STATE_PIXELSHADER)) {
3625             shaderconstant(STATE_PIXELSHADERCONSTANT, stateblock, context);
3626         }
3627     }
3628 }
3629
3630 static void tex_bumpenvmat(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
3631     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
3632     float mat[2][2];
3633
3634     if(stage >= GL_LIMITS(texture_stages)) {
3635         WARN("Bump env matrix of unsupported stage set\n");
3636     } else if(GL_SUPPORT(ARB_MULTITEXTURE)) {
3637         GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + stage));
3638         checkGLcall("GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + stage))");
3639     }
3640     mat[0][0] = *((float *) &stateblock->textureState[stage][WINED3DTSS_BUMPENVMAT00]);
3641     mat[1][0] = *((float *) &stateblock->textureState[stage][WINED3DTSS_BUMPENVMAT01]);
3642     mat[0][1] = *((float *) &stateblock->textureState[stage][WINED3DTSS_BUMPENVMAT10]);
3643     mat[1][1] = *((float *) &stateblock->textureState[stage][WINED3DTSS_BUMPENVMAT11]);
3644     GL_EXTCALL(glTexBumpParameterfvATI(GL_BUMP_ROT_MATRIX_ATI, (float *) mat));
3645     checkGLcall("glTexBumpParameterfvATI");
3646 }
3647
3648 static void transform_world(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
3649     /* This function is called by transform_view below if the view matrix was changed too
3650      *
3651      * Deliberately no check if the vertex declaration is dirty because the vdecl state
3652      * does not always update the world matrix, only on a switch between transformed
3653      * and untransformed draws. It *may* happen that the world matrix is set 2 times during one
3654      * draw, but that should be rather rare and cheaper in total.
3655      */
3656     glMatrixMode(GL_MODELVIEW);
3657     checkGLcall("glMatrixMode");
3658
3659     if(context->last_was_rhw) {
3660         glLoadIdentity();
3661         checkGLcall("glLoadIdentity()");
3662     } else {
3663         /* In the general case, the view matrix is the identity matrix */
3664         if (stateblock->wineD3DDevice->view_ident) {
3665             glLoadMatrixf(&stateblock->transforms[WINED3DTS_WORLDMATRIX(0)].u.m[0][0]);
3666             checkGLcall("glLoadMatrixf");
3667         } else {
3668             glLoadMatrixf(&stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
3669             checkGLcall("glLoadMatrixf");
3670             glMultMatrixf(&stateblock->transforms[WINED3DTS_WORLDMATRIX(0)].u.m[0][0]);
3671             checkGLcall("glMultMatrixf");
3672         }
3673     }
3674 }
3675
3676 static void clipplane(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
3677     UINT index = state - STATE_CLIPPLANE(0);
3678
3679     if(isStateDirty(context, STATE_TRANSFORM(WINED3DTS_VIEW)) || index >= GL_LIMITS(clipplanes)) {
3680         return;
3681     }
3682
3683     /* Clip Plane settings are affected by the model view in OpenGL, the View transform in direct3d */
3684     glMatrixMode(GL_MODELVIEW);
3685     glPushMatrix();
3686     glLoadMatrixf(&stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
3687
3688     TRACE("Clipplane [%f,%f,%f,%f]\n",
3689           stateblock->clipplane[index][0],
3690           stateblock->clipplane[index][1],
3691           stateblock->clipplane[index][2],
3692           stateblock->clipplane[index][3]);
3693     glClipPlane(GL_CLIP_PLANE0 + index, stateblock->clipplane[index]);
3694     checkGLcall("glClipPlane");
3695
3696     glPopMatrix();
3697 }
3698
3699 static void transform_worldex(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
3700     UINT matrix = state - STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0));
3701     GLenum glMat;
3702     TRACE("Setting world matrix %d\n", matrix);
3703
3704     if(matrix >= GL_LIMITS(blends)) {
3705         WARN("Unsupported blend matrix set\n");
3706         return;
3707     } else if(isStateDirty(context, STATE_TRANSFORM(WINED3DTS_VIEW))) {
3708         return;
3709     }
3710
3711     /* GL_MODELVIEW0_ARB:  0x1700
3712      * GL_MODELVIEW1_ARB:  0x0x850a
3713      * GL_MODELVIEW2_ARB:  0x8722
3714      * GL_MODELVIEW3_ARB:  0x8723
3715      * etc
3716      * GL_MODELVIEW31_ARB: 0x873F
3717      */
3718     if(matrix == 1) glMat = GL_MODELVIEW1_ARB;
3719     else glMat = GL_MODELVIEW2_ARB - 2 + matrix;
3720
3721     glMatrixMode(glMat);
3722     checkGLcall("glMatrixMode(glMat)");
3723
3724     /* World matrix 0 is multiplied with the view matrix because d3d uses 3 matrices while gl uses only 2. To avoid
3725      * weighting the view matrix incorrectly it has to be multiplied into every gl modelview matrix
3726      */
3727     if(stateblock->wineD3DDevice->view_ident) {
3728         glLoadMatrixf(&stateblock->transforms[WINED3DTS_WORLDMATRIX(matrix)].u.m[0][0]);
3729         checkGLcall("glLoadMatrixf")
3730     } else {
3731         glLoadMatrixf(&stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
3732         checkGLcall("glLoadMatrixf")
3733         glMultMatrixf(&stateblock->transforms[WINED3DTS_WORLDMATRIX(matrix)].u.m[0][0]);
3734         checkGLcall("glMultMatrixf")
3735     }
3736 }
3737
3738 static void state_vertexblend_w(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
3739     static BOOL once = FALSE;
3740
3741     switch(stateblock->renderState[WINED3DRS_VERTEXBLEND]) {
3742         case WINED3DVBF_1WEIGHTS:
3743         case WINED3DVBF_2WEIGHTS:
3744         case WINED3DVBF_3WEIGHTS:
3745             if(!once) {
3746                 once = TRUE;
3747                 /* TODO: Implement vertex blending in drawStridedSlow */
3748                 FIXME("Vertex blending enabled, but not supported by hardware\n");
3749             }
3750             break;
3751
3752         case WINED3DVBF_TWEENING:
3753             WARN("Tweening not supported yet\n");
3754     }
3755 }
3756
3757 static void state_vertexblend(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
3758     WINED3DVERTEXBLENDFLAGS val = stateblock->renderState[WINED3DRS_VERTEXBLEND];
3759
3760     switch(val) {
3761         case WINED3DVBF_1WEIGHTS:
3762         case WINED3DVBF_2WEIGHTS:
3763         case WINED3DVBF_3WEIGHTS:
3764             glEnable(GL_VERTEX_BLEND_ARB);
3765             checkGLcall("glEnable(GL_VERTEX_BLEND_ARB)");
3766
3767             /* D3D adds one more matrix which has weight (1 - sum(weights)). This is enabled at context
3768              * creation with enabling GL_WEIGHT_SUM_UNITY_ARB.
3769              */
3770             GL_EXTCALL(glVertexBlendARB(stateblock->renderState[WINED3DRS_VERTEXBLEND] + 1));
3771
3772             if(!stateblock->wineD3DDevice->vertexBlendUsed) {
3773                 int i;
3774                 for(i = 1; i < GL_LIMITS(blends); i++) {
3775                     if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(i)))) {
3776                         transform_worldex(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(i)), stateblock, context);
3777                     }
3778                 }
3779                 stateblock->wineD3DDevice->vertexBlendUsed = TRUE;
3780             }
3781             break;
3782
3783         case WINED3DVBF_DISABLE:
3784         case WINED3DVBF_0WEIGHTS: /* for Indexed vertex blending - not supported */
3785             glDisable(GL_VERTEX_BLEND_ARB);
3786             checkGLcall("glDisable(GL_VERTEX_BLEND_ARB)");
3787             break;
3788
3789         case WINED3DVBF_TWEENING:
3790             /* Just set the vertex weight for weight 0, enable vertex blending and hope the app doesn't have
3791              * vertex weights in the vertices?
3792              * For now we don't report that as supported, so a warn should suffice
3793              */
3794             WARN("Tweening not supported yet\n");
3795             break;
3796     }
3797 }
3798
3799 static void transform_view(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
3800     unsigned int k;
3801
3802     /* If we are changing the View matrix, reset the light and clipping planes to the new view
3803      * NOTE: We have to reset the positions even if the light/plane is not currently
3804      *       enabled, since the call to enable it will not reset the position.
3805      * NOTE2: Apparently texture transforms do NOT need reapplying
3806      */
3807
3808     PLIGHTINFOEL *light = NULL;
3809
3810     glMatrixMode(GL_MODELVIEW);
3811     checkGLcall("glMatrixMode(GL_MODELVIEW)");
3812     glLoadMatrixf(&stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
3813     checkGLcall("glLoadMatrixf(...)");
3814
3815     /* Reset lights. TODO: Call light apply func */
3816     for(k = 0; k < stateblock->wineD3DDevice->maxConcurrentLights; k++) {
3817         light = stateblock->activeLights[k];
3818         if(!light) continue;
3819         glLightfv(GL_LIGHT0 + light->glIndex, GL_POSITION, light->lightPosn);
3820         checkGLcall("glLightfv posn");
3821         glLightfv(GL_LIGHT0 + light->glIndex, GL_SPOT_DIRECTION, light->lightDirn);
3822         checkGLcall("glLightfv dirn");
3823     }
3824
3825     /* Reset Clipping Planes  */
3826     for (k = 0; k < GL_LIMITS(clipplanes); k++) {
3827         if(!isStateDirty(context, STATE_CLIPPLANE(k))) {
3828             clipplane(STATE_CLIPPLANE(k), stateblock, context);
3829         }
3830     }
3831
3832     if(context->last_was_rhw) {
3833         glLoadIdentity();
3834         checkGLcall("glLoadIdentity()");
3835         /* No need to update the world matrix, the identity is fine */
3836         return;
3837     }
3838
3839     /* Call the world matrix state, this will apply the combined WORLD + VIEW matrix
3840      * No need to do it here if the state is scheduled for update.
3841      */
3842     if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)))) {
3843         transform_world(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), stateblock, context);
3844     }
3845
3846     /* Avoid looping over a number of matrices if the app never used the functionality */
3847     if(stateblock->wineD3DDevice->vertexBlendUsed) {
3848         for(k = 1; k < GL_LIMITS(blends); k++) {
3849             if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(k)))) {
3850                 transform_worldex(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(k)), stateblock, context);
3851             }
3852         }
3853     }
3854 }
3855
3856 static void transform_projection(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
3857     glMatrixMode(GL_PROJECTION);
3858     checkGLcall("glMatrixMode(GL_PROJECTION)");
3859     glLoadIdentity();
3860     checkGLcall("glLoadIdentity");
3861
3862     if(context->last_was_rhw) {
3863         double X, Y, height, width, minZ, maxZ;
3864
3865         X      = stateblock->viewport.X;
3866         Y      = stateblock->viewport.Y;
3867         height = stateblock->viewport.Height;
3868         width  = stateblock->viewport.Width;
3869         minZ   = stateblock->viewport.MinZ;
3870         maxZ   = stateblock->viewport.MaxZ;
3871
3872         if(!stateblock->wineD3DDevice->untransformed) {
3873             /* Transformed vertices are supposed to bypass the whole transform pipeline including
3874              * frustum clipping. This can't be done in opengl, so this code adjusts the Z range to
3875              * suppress depth clipping. This can be done because it is an orthogonal projection and
3876              * the Z coordinate does not affect the size of the primitives. Half Life 1 and Prince of
3877              * Persia 3D need this.
3878              *
3879              * Note that using minZ and maxZ here doesn't entirely fix the problem, since view frustum
3880              * clipping is still enabled, but it seems to fix it for all apps tested so far. A minor
3881              * problem can be witnessed in half-life 1 engine based games, the weapon is clipped close
3882              * to the viewer.
3883              *
3884              * Also note that this breaks z comparison against z values filled in with clear,
3885              * but no app depending on that and disabled clipping has been found yet. Comparing
3886              * primitives against themselves works, so the Z buffer is still intact for normal hidden
3887              * surface removal.
3888              *
3889              * We could disable clipping entirely by setting the near to infinity and far to -infinity,
3890              * but this would break Z buffer operation. Raising the range to something less than
3891              * infinity would help a bit at the cost of Z precision, but it wouldn't eliminate the
3892              * problem either.
3893              */
3894             TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, -minZ, -maxZ);
3895             if(stateblock->wineD3DDevice->render_offscreen) {
3896                 glOrtho(X, X + width, -Y, -Y - height, -minZ, -maxZ);
3897             } else {
3898                 glOrtho(X, X + width, Y + height, Y, -minZ, -maxZ);
3899             }
3900         } else {
3901             /* If the app mixes transformed and untransformed primitives we can't use the coordinate system
3902              * trick above because this would mess up transformed and untransformed Z order. Pass the z position
3903              * unmodified to opengl.
3904              *
3905              * If the app depends on mixed types and disabled clipping we're out of luck without a pipeline
3906              * replacement shader.
3907              */
3908             TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, 1.0, -1.0);
3909             if(stateblock->wineD3DDevice->render_offscreen) {
3910                 glOrtho(X, X + width, -Y, -Y - height, 0.0, -1.0);
3911             } else {
3912                 glOrtho(X, X + width, Y + height, Y, 0.0, -1.0);
3913             }
3914         }
3915         checkGLcall("glOrtho");
3916
3917         /* Window Coord 0 is the middle of the first pixel, so translate by 1/2 pixels */
3918         glTranslatef(0.5, 0.5, 0);
3919         checkGLcall("glTranslatef(0.5, 0.5, 0)");
3920         /* D3D texture coordinates are flipped compared to OpenGL ones, so
3921          * render everything upside down when rendering offscreen. */
3922         if (stateblock->wineD3DDevice->render_offscreen) {
3923             glScalef(1.0, -1.0, 1.0);
3924             checkGLcall("glScalef");
3925         }
3926     } else {
3927         /* The rule is that the window coordinate 0 does not correspond to the
3928             beginning of the first pixel, but the center of the first pixel.
3929             As a consequence if you want to correctly draw one line exactly from
3930             the left to the right end of the viewport (with all matrices set to
3931             be identity), the x coords of both ends of the line would be not
3932             -1 and 1 respectively but (-1-1/viewport_widh) and (1-1/viewport_width)
3933             instead.
3934
3935             1.0 / Width is used because the coord range goes from -1.0 to 1.0, then we
3936             divide by the Width/Height, so we need the half range(1.0) to translate by
3937             half a pixel.
3938
3939             The other fun is that d3d's output z range after the transformation is [0;1],
3940             but opengl's is [-1;1]. Since the z buffer is in range [0;1] for both, gl
3941             scales [-1;1] to [0;1]. This would mean that we end up in [0.5;1] and loose a lot
3942             of Z buffer precision and the clear values do not match in the z test. Thus scale
3943             [0;1] to [-1;1], so when gl undoes that we utilize the full z range
3944          */
3945         glTranslatef(1.0 / stateblock->viewport.Width, -1.0/ stateblock->viewport.Height, -1.0);
3946         checkGLcall("glTranslatef (1.0 / width, -1.0 / height, -1.0)");
3947         if (stateblock->wineD3DDevice->render_offscreen) {
3948             /* D3D texture coordinates are flipped compared to OpenGL ones, so
3949              * render everything upside down when rendering offscreen. */
3950             glScalef(1.0, -1.0, 2.0);
3951         } else {
3952             glScalef(1.0, 1.0, 2.0);
3953         }
3954         checkGLcall("glScalef");
3955
3956         glMultMatrixf(&stateblock->transforms[WINED3DTS_PROJECTION].u.m[0][0]);
3957         checkGLcall("glLoadMatrixf");
3958     }
3959 }
3960
3961 /* This should match any arrays loaded in loadVertexData.
3962  * stateblock impl is required for GL_SUPPORT
3963  * TODO: Only load / unload arrays if we have to.
3964  */
3965 static inline void unloadVertexData(IWineD3DStateBlockImpl *stateblock) {
3966     glDisableClientState(GL_VERTEX_ARRAY);
3967     glDisableClientState(GL_NORMAL_ARRAY);
3968     glDisableClientState(GL_COLOR_ARRAY);
3969     if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
3970         glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
3971     }
3972     if (GL_SUPPORT(ARB_VERTEX_BLEND)) {
3973         glDisableClientState(GL_WEIGHT_ARRAY_ARB);
3974     }
3975     unloadTexCoords(stateblock);
3976 }
3977
3978 /* This should match any arrays loaded in loadNumberedArrays
3979  * TODO: Only load / unload arrays if we have to.
3980  */
3981 static inline void unloadNumberedArrays(IWineD3DStateBlockImpl *stateblock) {
3982     /* disable any attribs (this is the same for both GLSL and ARB modes) */
3983     GLint maxAttribs = 16;
3984     int i;
3985
3986     /* Leave all the attribs disabled */
3987     glGetIntegerv(GL_MAX_VERTEX_ATTRIBS_ARB, &maxAttribs);
3988     /* MESA does not support it right not */
3989     if (glGetError() != GL_NO_ERROR)
3990         maxAttribs = 16;
3991     for (i = 0; i < maxAttribs; ++i) {
3992         GL_EXTCALL(glDisableVertexAttribArrayARB(i));
3993         checkGLcall("glDisableVertexAttribArrayARB(reg)");
3994         /* Some Windows drivers(NV GF 7) use the latest value that was used when drawing with the now
3995          * deactivated stream disabled, some other drivers(ATI, NV GF 8) set the undefined values to 0x00.
3996          * Let's set them to 0x00 to avoid hitting some undefined aspects of OpenGL. All that is really
3997          * important here is the glDisableVertexAttribArrayARB call above. The test shows that the refrast
3998          * keeps dereferencing the pointers, which would cause crashes in some games like Half Life 2: Episode Two.
3999          */
4000         GL_EXTCALL(glVertexAttrib4NubARB(i, 0, 0, 0, 0));
4001         checkGLcall("glVertexAttrib4NubARB(i, 0, 0, 0, 0)");
4002     }
4003 }
4004
4005 static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock, WineDirect3DVertexStridedData *strided) {
4006     GLint curVBO = GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT) ? -1 : 0;
4007     int i;
4008     UINT *offset = stateblock->streamOffset;
4009     IWineD3DVertexBufferImpl *vb;
4010     DWORD_PTR shift_index;
4011
4012     /* Default to no instancing */
4013     stateblock->wineD3DDevice->instancedDraw = FALSE;
4014
4015     for (i = 0; i < MAX_ATTRIBS; i++) {
4016
4017         if (!strided->u.input[i].lpData && !strided->u.input[i].VBO)
4018             continue;
4019
4020         /* Do not load instance data. It will be specified using glTexCoord by drawprim */
4021         if(stateblock->streamFlags[strided->u.input[i].streamNo] & WINED3DSTREAMSOURCE_INSTANCEDATA) {
4022             GL_EXTCALL(glDisableVertexAttribArrayARB(i));
4023             stateblock->wineD3DDevice->instancedDraw = TRUE;
4024             continue;
4025         }
4026
4027         TRACE_(d3d_shader)("Loading array %u [VBO=%u]\n", i, strided->u.input[i].VBO);
4028
4029         if(strided->u.input[i].dwStride) {
4030             if(curVBO != strided->u.input[i].VBO) {
4031                 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, strided->u.input[i].VBO));
4032                 checkGLcall("glBindBufferARB");
4033                 curVBO = strided->u.input[i].VBO;
4034             }
4035             vb = (IWineD3DVertexBufferImpl *) stateblock->streamSource[strided->u.input[i].streamNo];
4036             /* Use the VBO to find out if a vertex buffer exists, not the vb pointer. vb can point to a
4037              * user pointer data blob. In that case curVBO will be 0. If there is a vertex buffer but no
4038              * vbo we won't be load converted attributes anyway
4039              */
4040             if(curVBO && vb->conv_shift) {
4041                 TRACE("Loading attribute from shifted buffer\n");
4042                 TRACE("Attrib %d has original stride %d, new stride %d\n", i, strided->u.input[i].dwStride, vb->conv_stride);
4043                 TRACE("Original offset %p, additional offset 0x%08x\n",strided->u.input[i].lpData, vb->conv_shift[(DWORD_PTR) strided->u.input[i].lpData]);
4044                 TRACE("Opengl type %x\n", WINED3D_ATR_GLTYPE(strided->u.input[i].dwType));
4045                 shift_index = ((DWORD_PTR) strided->u.input[i].lpData + offset[strided->u.input[i].streamNo]);
4046                 shift_index = shift_index % strided->u.input[i].dwStride;
4047                 GL_EXTCALL(glVertexAttribPointerARB(i,
4048                                 WINED3D_ATR_SIZE(strided->u.input[i].dwType),
4049                                 WINED3D_ATR_GLTYPE(strided->u.input[i].dwType),
4050                                 WINED3D_ATR_NORMALIZED(strided->u.input[i].dwType),
4051                                 vb->conv_stride,
4052
4053                                 strided->u.input[i].lpData + vb->conv_shift[shift_index] +
4054                                 stateblock->loadBaseVertexIndex * strided->u.input[i].dwStride +
4055                                 offset[strided->u.input[i].streamNo]));
4056
4057             } else {
4058                 GL_EXTCALL(glVertexAttribPointerARB(i,
4059                                 WINED3D_ATR_SIZE(strided->u.input[i].dwType),
4060                                 WINED3D_ATR_GLTYPE(strided->u.input[i].dwType),
4061                                 WINED3D_ATR_NORMALIZED(strided->u.input[i].dwType),
4062                                 strided->u.input[i].dwStride,
4063
4064                                 strided->u.input[i].lpData +
4065                                 stateblock->loadBaseVertexIndex * strided->u.input[i].dwStride +
4066                                 offset[strided->u.input[i].streamNo]) );
4067                 }
4068             GL_EXTCALL(glEnableVertexAttribArrayARB(i));
4069         } else {
4070             /* Stride = 0 means always the same values. glVertexAttribPointerARB doesn't do that. Instead disable the pointer and
4071              * set up the attribute statically. But we have to figure out the system memory address.
4072              */
4073             BYTE *ptr = strided->u.input[i].lpData + offset[strided->u.input[i].streamNo];
4074             if(strided->u.input[i].VBO) {
4075                 vb = (IWineD3DVertexBufferImpl *) stateblock->streamSource[strided->u.input[i].streamNo];
4076                 ptr += (long) vb->resource.allocatedMemory;
4077             }
4078             GL_EXTCALL(glDisableVertexAttribArrayARB(i));
4079
4080             switch(strided->u.input[i].dwType) {
4081                 case WINED3DDECLTYPE_FLOAT1:
4082                     GL_EXTCALL(glVertexAttrib1fvARB(i, (float *) ptr));
4083                     break;
4084                 case WINED3DDECLTYPE_FLOAT2:
4085                     GL_EXTCALL(glVertexAttrib2fvARB(i, (float *) ptr));
4086                     break;
4087                 case WINED3DDECLTYPE_FLOAT3:
4088                     GL_EXTCALL(glVertexAttrib3fvARB(i, (float *) ptr));
4089                     break;
4090                 case WINED3DDECLTYPE_FLOAT4:
4091                     GL_EXTCALL(glVertexAttrib4fvARB(i, (float *) ptr));
4092                     break;
4093
4094                 case WINED3DDECLTYPE_UBYTE4:
4095                     GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
4096                     break;
4097                 case WINED3DDECLTYPE_UBYTE4N:
4098                 case WINED3DDECLTYPE_D3DCOLOR:
4099                     GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
4100                     break;
4101
4102                 case WINED3DDECLTYPE_SHORT2:
4103                     GL_EXTCALL(glVertexAttrib4svARB(i, (GLshort *) ptr));
4104                     break;
4105                 case WINED3DDECLTYPE_SHORT4:
4106                     GL_EXTCALL(glVertexAttrib4svARB(i, (GLshort *) ptr));
4107                     break;
4108
4109                 case WINED3DDECLTYPE_SHORT2N:
4110                 {
4111                     GLshort s[4] = {((short *) ptr)[0], ((short *) ptr)[1], 0, 1};
4112                     GL_EXTCALL(glVertexAttrib4NsvARB(i, s));
4113                     break;
4114                 }
4115                 case WINED3DDECLTYPE_USHORT2N:
4116                 {
4117                     GLushort s[4] = {((unsigned short *) ptr)[0], ((unsigned short *) ptr)[1], 0, 1};
4118                     GL_EXTCALL(glVertexAttrib4NusvARB(i, s));
4119                     break;
4120                 }
4121                 case WINED3DDECLTYPE_SHORT4N:
4122                     GL_EXTCALL(glVertexAttrib4NsvARB(i, (GLshort *) ptr));
4123                     break;
4124                 case WINED3DDECLTYPE_USHORT4N:
4125                     GL_EXTCALL(glVertexAttrib4NusvARB(i, (GLushort *) ptr));
4126                     break;
4127
4128                 case WINED3DDECLTYPE_UDEC3:
4129                     FIXME("Unsure about WINED3DDECLTYPE_UDEC3\n");
4130                     /*glVertexAttrib3usvARB(i, (GLushort *) ptr); Does not exist */
4131                     break;
4132                 case WINED3DDECLTYPE_DEC3N:
4133                     FIXME("Unsure about WINED3DDECLTYPE_DEC3N\n");
4134                     /*glVertexAttrib3NusvARB(i, (GLushort *) ptr); Does not exist */
4135                     break;
4136
4137                 case WINED3DDECLTYPE_FLOAT16_2:
4138                     /* Are those 16 bit floats. C doesn't have a 16 bit float type. I could read the single bits and calculate a 4
4139                      * byte float according to the IEEE standard
4140                      */
4141                     FIXME("Unsupported WINED3DDECLTYPE_FLOAT16_2\n");
4142                     break;
4143                 case WINED3DDECLTYPE_FLOAT16_4:
4144                     FIXME("Unsupported WINED3DDECLTYPE_FLOAT16_4\n");
4145                     break;
4146
4147                 case WINED3DDECLTYPE_UNUSED:
4148                 default:
4149                     ERR("Unexpected declaration in stride 0 attributes\n");
4150                     break;
4151
4152             }
4153         }
4154     }
4155     checkGLcall("Loading numbered arrays");
4156 }
4157
4158 /* Used from 2 different functions, and too big to justify making it inlined */
4159 static void loadVertexData(IWineD3DStateBlockImpl *stateblock, WineDirect3DVertexStridedData *sd) {
4160     UINT *offset = stateblock->streamOffset;
4161     GLint curVBO = GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT) ? -1 : 0;
4162
4163     TRACE("Using fast vertex array code\n");
4164
4165     /* This is fixed function pipeline only, and the fixed function pipeline doesn't do instancing */
4166     stateblock->wineD3DDevice->instancedDraw = FALSE;
4167
4168     /* Blend Data ---------------------------------------------- */
4169     if( (sd->u.s.blendWeights.lpData) || (sd->u.s.blendWeights.VBO) ||
4170         (sd->u.s.blendMatrixIndices.lpData) || (sd->u.s.blendMatrixIndices.VBO) ) {
4171
4172         if (GL_SUPPORT(ARB_VERTEX_BLEND)) {
4173             TRACE("Blend %d %p %d\n", WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType),
4174                 sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride, sd->u.s.blendWeights.dwStride + offset[sd->u.s.blendWeights.streamNo]);
4175
4176             glEnableClientState(GL_WEIGHT_ARRAY_ARB);
4177             checkGLcall("glEnableClientState(GL_WEIGHT_ARRAY_ARB)");
4178
4179             GL_EXTCALL(glVertexBlendARB(WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType) + 1));
4180
4181             VTRACE(("glWeightPointerARB(%d, GL_FLOAT, %d, %p)\n",
4182                 WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType) ,
4183                 sd->u.s.blendWeights.dwStride,
4184                 sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride + offset[sd->u.s.blendWeights.streamNo]));
4185
4186             if(curVBO != sd->u.s.blendWeights.VBO) {
4187                 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.blendWeights.VBO));
4188                 checkGLcall("glBindBufferARB");
4189                 curVBO = sd->u.s.blendWeights.VBO;
4190             }
4191
4192             GL_EXTCALL(glWeightPointerARB)(
4193                 WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType),
4194                 WINED3D_ATR_GLTYPE(sd->u.s.blendWeights.dwType),
4195                 sd->u.s.blendWeights.dwStride,
4196                 sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride + offset[sd->u.s.blendWeights.streamNo]);
4197
4198             checkGLcall("glWeightPointerARB");
4199
4200             if((sd->u.s.blendMatrixIndices.lpData) || (sd->u.s.blendMatrixIndices.VBO)){
4201                 static BOOL showfixme = TRUE;
4202                 if(showfixme){
4203                     FIXME("blendMatrixIndices support\n");
4204                     showfixme = FALSE;
4205                 }
4206             }
4207         } else {
4208             /* TODO: support blends in drawStridedSlow
4209              * No need to write a FIXME here, this is done after the general vertex decl decoding
4210              */
4211             WARN("unsupported blending in openGl\n");
4212         }
4213     } else {
4214         if (GL_SUPPORT(ARB_VERTEX_BLEND)) {
4215             static const GLbyte one = 1;
4216             GL_EXTCALL(glWeightbvARB(1, &one));
4217             checkGLcall("glWeightivARB(GL_LIMITS(blends), weights)");
4218         }
4219     }
4220
4221 #if 0 /* FOG  ----------------------------------------------*/
4222     if (sd->u.s.fog.lpData || sd->u.s.fog.VBO) {
4223         /* TODO: fog*/
4224     if (GL_SUPPORT(EXT_FOG_COORD) {
4225              glEnableClientState(GL_FOG_COORDINATE_EXT);
4226             (GL_EXTCALL)(FogCoordPointerEXT)(
4227                 WINED3D_ATR_GLTYPE(sd->u.s.fog.dwType),
4228                 sd->u.s.fog.dwStride,
4229                 sd->u.s.fog.lpData + stateblock->loadBaseVertexIndex * sd->u.s.fog.dwStride);
4230         } else {
4231             /* don't bother falling back to 'slow' as we don't support software FOG yet. */
4232             /* FIXME: fixme once */
4233             TRACE("Hardware support for FOG is not avaiable, FOG disabled.\n");
4234         }
4235     } else {
4236         if (GL_SUPPRT(EXT_FOR_COORD) {
4237              /* make sure fog is disabled */
4238              glDisableClientState(GL_FOG_COORDINATE_EXT);
4239         }
4240     }
4241 #endif
4242
4243     /* Point Size ----------------------------------------------*/
4244     if (sd->u.s.pSize.lpData || sd->u.s.pSize.VBO) {
4245
4246         /* no such functionality in the fixed function GL pipeline */
4247         TRACE("Cannot change ptSize here in openGl\n");
4248         /* TODO: Implement this function in using shaders if they are available */
4249
4250     }
4251
4252     /* Vertex Pointers -----------------------------------------*/
4253     if (sd->u.s.position.lpData != NULL || sd->u.s.position.VBO != 0) {
4254         /* Note dwType == float3 or float4 == 2 or 3 */
4255         VTRACE(("glVertexPointer(%d, GL_FLOAT, %d, %p)\n",
4256                 sd->u.s.position.dwStride,
4257                 sd->u.s.position.dwType + 1,
4258                 sd->u.s.position.lpData));
4259
4260         if(curVBO != sd->u.s.position.VBO) {
4261             GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.position.VBO));
4262             checkGLcall("glBindBufferARB");
4263             curVBO = sd->u.s.position.VBO;
4264         }
4265
4266         /* min(WINED3D_ATR_SIZE(position),3) to Disable RHW mode as 'w' coord
4267            handling for rhw mode should not impact screen position whereas in GL it does.
4268            This may result in very slightly distorted textures in rhw mode.
4269            There's always the other option of fixing the view matrix to
4270            prevent w from having any effect.
4271
4272            This only applies to user pointer sources, in VBOs the vertices are fixed up
4273          */
4274         if(sd->u.s.position.VBO == 0) {
4275             glVertexPointer(3 /* min(WINED3D_ATR_SIZE(sd->u.s.position.dwType),3) */,
4276                 WINED3D_ATR_GLTYPE(sd->u.s.position.dwType),
4277                 sd->u.s.position.dwStride, sd->u.s.position.lpData + stateblock->loadBaseVertexIndex * sd->u.s.position.dwStride + offset[sd->u.s.position.streamNo]);
4278         } else {
4279             glVertexPointer(
4280                 WINED3D_ATR_SIZE(sd->u.s.position.dwType),
4281                 WINED3D_ATR_GLTYPE(sd->u.s.position.dwType),
4282                 sd->u.s.position.dwStride, sd->u.s.position.lpData + stateblock->loadBaseVertexIndex * sd->u.s.position.dwStride + offset[sd->u.s.position.streamNo]);
4283         }
4284         checkGLcall("glVertexPointer(...)");
4285         glEnableClientState(GL_VERTEX_ARRAY);
4286         checkGLcall("glEnableClientState(GL_VERTEX_ARRAY)");
4287     }
4288
4289     /* Normals -------------------------------------------------*/
4290     if (sd->u.s.normal.lpData || sd->u.s.normal.VBO) {
4291         /* Note dwType == float3 or float4 == 2 or 3 */
4292         VTRACE(("glNormalPointer(GL_FLOAT, %d, %p)\n",
4293                 sd->u.s.normal.dwStride,
4294                 sd->u.s.normal.lpData));
4295         if(curVBO != sd->u.s.normal.VBO) {
4296             GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.normal.VBO));
4297             checkGLcall("glBindBufferARB");
4298             curVBO = sd->u.s.normal.VBO;
4299         }
4300         glNormalPointer(
4301             WINED3D_ATR_GLTYPE(sd->u.s.normal.dwType),
4302             sd->u.s.normal.dwStride,
4303             sd->u.s.normal.lpData + stateblock->loadBaseVertexIndex * sd->u.s.normal.dwStride + offset[sd->u.s.normal.streamNo]);
4304         checkGLcall("glNormalPointer(...)");
4305         glEnableClientState(GL_NORMAL_ARRAY);
4306         checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)");
4307
4308     } else {
4309         glNormal3f(0, 0, 0);
4310         checkGLcall("glNormal3f(0, 0, 0)");
4311     }
4312
4313     /* Diffuse Colour --------------------------------------------*/
4314     /*  WARNING: Data here MUST be in RGBA format, so cannot      */
4315     /*     go directly into fast mode from app pgm, because       */
4316     /*     directx requires data in BGRA format.                  */
4317     /* currently fixupVertices swizzles the format, but this isn't*/
4318     /* very practical when using VBOs                             */
4319     /* NOTE: Unless we write a vertex shader to swizzle the colour*/
4320     /* , or the user doesn't care and wants the speed advantage   */
4321
4322     if (sd->u.s.diffuse.lpData || sd->u.s.diffuse.VBO) {
4323         /* Note dwType == float3 or float4 == 2 or 3 */
4324         VTRACE(("glColorPointer(4, GL_UNSIGNED_BYTE, %d, %p)\n",
4325                 sd->u.s.diffuse.dwStride,
4326                 sd->u.s.diffuse.lpData));
4327
4328         if(curVBO != sd->u.s.diffuse.VBO) {
4329             GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.diffuse.VBO));
4330             checkGLcall("glBindBufferARB");
4331             curVBO = sd->u.s.diffuse.VBO;
4332         }
4333
4334         glColorPointer(WINED3D_ATR_SIZE(sd->u.s.diffuse.dwType),
4335                        WINED3D_ATR_GLTYPE(sd->u.s.diffuse.dwType),
4336                        sd->u.s.diffuse.dwStride,
4337                        sd->u.s.diffuse.lpData + stateblock->loadBaseVertexIndex * sd->u.s.diffuse.dwStride + offset[sd->u.s.diffuse.streamNo]);
4338         checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)");
4339         glEnableClientState(GL_COLOR_ARRAY);
4340         checkGLcall("glEnableClientState(GL_COLOR_ARRAY)");
4341
4342     } else {
4343         glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
4344         checkGLcall("glColor4f(1, 1, 1, 1)");
4345     }
4346
4347     /* Specular Colour ------------------------------------------*/
4348     if (sd->u.s.specular.lpData || sd->u.s.specular.VBO) {
4349         TRACE("setting specular colour\n");
4350         /* Note dwType == float3 or float4 == 2 or 3 */
4351         VTRACE(("glSecondaryColorPointer(4, GL_UNSIGNED_BYTE, %d, %p)\n",
4352                 sd->u.s.specular.dwStride,
4353                 sd->u.s.specular.lpData));
4354         if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
4355             if(curVBO != sd->u.s.specular.VBO) {
4356                 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.specular.VBO));
4357                 checkGLcall("glBindBufferARB");
4358                 curVBO = sd->u.s.specular.VBO;
4359             }
4360             GL_EXTCALL(glSecondaryColorPointerEXT)(WINED3D_ATR_SIZE(sd->u.s.specular.dwType),
4361                                                    WINED3D_ATR_GLTYPE(sd->u.s.specular.dwType),
4362                                                    sd->u.s.specular.dwStride,
4363                                                    sd->u.s.specular.lpData + stateblock->loadBaseVertexIndex * sd->u.s.specular.dwStride + offset[sd->u.s.specular.streamNo]);
4364             vcheckGLcall("glSecondaryColorPointerEXT(4, GL_UNSIGNED_BYTE, ...)");
4365             glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
4366             vcheckGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
4367         } else {
4368
4369         /* Missing specular color is not critical, no warnings */
4370         VTRACE(("Specular colour is not supported in this GL implementation\n"));
4371         }
4372
4373     } else {
4374         if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
4375             GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0);
4376             checkGLcall("glSecondaryColor3fEXT(0, 0, 0)");
4377         } else {
4378
4379             /* Missing specular color is not critical, no warnings */
4380             VTRACE(("Specular colour is not supported in this GL implementation\n"));
4381         }
4382     }
4383
4384     /* Texture coords -------------------------------------------*/
4385     loadTexCoords(stateblock, sd, &curVBO);
4386 }
4387
4388 static inline void drawPrimitiveTraceDataLocations(
4389     WineDirect3DVertexStridedData *dataLocations) {
4390
4391     /* Dump out what parts we have supplied */
4392     TRACE("Strided Data:\n");
4393     TRACE_STRIDED((dataLocations), position);
4394     TRACE_STRIDED((dataLocations), blendWeights);
4395     TRACE_STRIDED((dataLocations), blendMatrixIndices);
4396     TRACE_STRIDED((dataLocations), normal);
4397     TRACE_STRIDED((dataLocations), pSize);
4398     TRACE_STRIDED((dataLocations), diffuse);
4399     TRACE_STRIDED((dataLocations), specular);
4400     TRACE_STRIDED((dataLocations), texCoords[0]);
4401     TRACE_STRIDED((dataLocations), texCoords[1]);
4402     TRACE_STRIDED((dataLocations), texCoords[2]);
4403     TRACE_STRIDED((dataLocations), texCoords[3]);
4404     TRACE_STRIDED((dataLocations), texCoords[4]);
4405     TRACE_STRIDED((dataLocations), texCoords[5]);
4406     TRACE_STRIDED((dataLocations), texCoords[6]);
4407     TRACE_STRIDED((dataLocations), texCoords[7]);
4408     TRACE_STRIDED((dataLocations), position2);
4409     TRACE_STRIDED((dataLocations), normal2);
4410     TRACE_STRIDED((dataLocations), tangent);
4411     TRACE_STRIDED((dataLocations), binormal);
4412     TRACE_STRIDED((dataLocations), tessFactor);
4413     TRACE_STRIDED((dataLocations), fog);
4414     TRACE_STRIDED((dataLocations), depth);
4415     TRACE_STRIDED((dataLocations), sample);
4416
4417     return;
4418 }
4419
4420 static void streamsrc(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
4421     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
4422     BOOL fixup = FALSE;
4423     WineDirect3DVertexStridedData *dataLocations = &device->strided_streams;
4424     BOOL useVertexShaderFunction;
4425
4426     if (device->vs_selected_mode != SHADER_NONE && stateblock->vertexShader &&
4427         ((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.function != NULL) {
4428         useVertexShaderFunction = TRUE;
4429     } else {
4430         useVertexShaderFunction = FALSE;
4431     }
4432
4433
4434     if(device->up_strided) {
4435         /* Note: this is a ddraw fixed-function code path */
4436         TRACE("================ Strided Input ===================\n");
4437         memcpy(dataLocations, device->up_strided, sizeof(*dataLocations));
4438
4439         if(TRACE_ON(d3d)) {
4440             drawPrimitiveTraceDataLocations(dataLocations);
4441         }
4442     } else {
4443         /* Note: This is a fixed function or shader codepath.
4444          * This means it must handle both types of strided data.
4445          * Shaders must go through here to zero the strided data, even if they
4446          * don't set any declaration at all
4447          */
4448         TRACE("================ Vertex Declaration  ===================\n");
4449         memset(dataLocations, 0, sizeof(*dataLocations));
4450         primitiveDeclarationConvertToStridedData((IWineD3DDevice *) device,
4451                 useVertexShaderFunction, dataLocations, &fixup);
4452     }
4453
4454     if (dataLocations->u.s.position_transformed) {
4455         useVertexShaderFunction = FALSE;
4456     }
4457
4458     /* Unload the old arrays before loading the new ones to get old junk out */
4459     if(context->numberedArraysLoaded) {
4460         unloadNumberedArrays(stateblock);
4461         context->numberedArraysLoaded = FALSE;
4462     }
4463     if(context->namedArraysLoaded) {
4464         unloadVertexData(stateblock);
4465         context->namedArraysLoaded = FALSE;
4466     }
4467
4468     if(useVertexShaderFunction) {
4469         if(((IWineD3DVertexDeclarationImpl *) stateblock->vertexDecl)->half_float_conv_needed && !fixup) {
4470             TRACE("Using drawStridedSlow with vertex shaders for FLOAT16 conversion\n");
4471             device->useDrawStridedSlow = TRUE;
4472             context->numberedArraysLoaded = FALSE;
4473         } else {
4474             TRACE("Loading numbered arrays\n");
4475             loadNumberedArrays(stateblock, dataLocations);
4476             device->useDrawStridedSlow = FALSE;
4477             context->numberedArraysLoaded = TRUE;
4478         }
4479     } else if (fixup ||
4480                (dataLocations->u.s.pSize.lpData == NULL &&
4481                 dataLocations->u.s.diffuse.lpData == NULL &&
4482                 dataLocations->u.s.specular.lpData == NULL)) {
4483         /* Load the vertex data using named arrays */
4484         TRACE("Loading vertex data\n");
4485         loadVertexData(stateblock, dataLocations);
4486         device->useDrawStridedSlow = FALSE;
4487         context->namedArraysLoaded = TRUE;
4488     } else {
4489         TRACE("Not loading vertex data\n");
4490         device->useDrawStridedSlow = TRUE;
4491     }
4492
4493 /* Generate some fixme's if unsupported functionality is being used */
4494 #define BUFFER_OR_DATA(_attribute) dataLocations->u.s._attribute.lpData
4495     /* TODO: Either support missing functionality in fixupVertices or by creating a shader to replace the pipeline. */
4496     if (!useVertexShaderFunction && (BUFFER_OR_DATA(position2) || BUFFER_OR_DATA(normal2))) {
4497         FIXME("Tweening is only valid with vertex shaders\n");
4498     }
4499     if (!useVertexShaderFunction && BUFFER_OR_DATA(binormal)) {
4500         FIXME("Binormal bump mapping is only valid with vertex shaders\n");
4501     }
4502     if (!useVertexShaderFunction && (BUFFER_OR_DATA(tessFactor) || BUFFER_OR_DATA(fog) || BUFFER_OR_DATA(depth) || BUFFER_OR_DATA(sample))) {
4503         FIXME("Extended attributes are only valid with vertex shaders\n");
4504     }
4505 #undef BUFFER_OR_DATA
4506 }
4507
4508 static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
4509     BOOL useVertexShaderFunction = FALSE, updateFog = FALSE;
4510     BOOL usePixelShaderFunction = stateblock->wineD3DDevice->ps_selected_mode != SHADER_NONE && stateblock->pixelShader
4511             && ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.function;
4512     BOOL transformed;
4513     /* Some stuff is in the device until we have per context tracking */
4514     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
4515     BOOL wasrhw = context->last_was_rhw;
4516
4517     /* Shaders can be implemented using ARB_PROGRAM, GLSL, or software -
4518      * here simply check whether a shader was set, or the user disabled shaders
4519      */
4520     if (use_vs(device)) {
4521         useVertexShaderFunction = TRUE;
4522
4523         if(((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.reg_maps.fog != context->last_was_foggy_shader) {
4524             updateFog = TRUE;
4525         }
4526     } else if(context->last_was_foggy_shader) {
4527         updateFog = TRUE;
4528     }
4529
4530     transformed = device->strided_streams.u.s.position_transformed;
4531     if (transformed) useVertexShaderFunction = FALSE;
4532
4533     if(transformed != context->last_was_rhw && !useVertexShaderFunction) {
4534         updateFog = TRUE;
4535     }
4536
4537     /* Reapply lighting if it is not scheduled for reapplication already */
4538     if(!isStateDirty(context, STATE_RENDER(WINED3DRS_LIGHTING))) {
4539         state_lighting(STATE_RENDER(WINED3DRS_LIGHTING), stateblock, context);
4540     }
4541
4542     if (transformed) {
4543         context->last_was_rhw = TRUE;
4544     } else {
4545
4546         /* Untransformed, so relies on the view and projection matrices */
4547         context->last_was_rhw = FALSE;
4548         /* This turns off the Z scale trick to 'disable' viewport frustum clipping in rhw mode*/
4549         device->untransformed = TRUE;
4550
4551         /* Todo for sw shaders: Vertex Shader output is already transformed, so set up identity matrices
4552          * Not needed as long as only hw shaders are supported
4553          */
4554
4555         /* This sets the shader output position correction constants.
4556          * TODO: Move to the viewport state
4557          */
4558         if (useVertexShaderFunction) {
4559             device->posFixup[1] = device->render_offscreen ? -1.0 : 1.0;
4560             device->posFixup[3] = -device->posFixup[1] / stateblock->viewport.Height;
4561         }
4562     }
4563
4564     /* Don't have to apply the matrices when vertex shaders are used. When vshaders are turned
4565      * off this function will be called again anyway to make sure they're properly set
4566      */
4567     if(!useVertexShaderFunction) {
4568         /* TODO: Move this mainly to the viewport state and only apply when the vp has changed
4569          * or transformed / untransformed was switched
4570          */
4571        if(wasrhw != context->last_was_rhw &&
4572           !isStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION)) &&
4573           !isStateDirty(context, STATE_VIEWPORT)) {
4574             transform_projection(STATE_TRANSFORM(WINED3DTS_PROJECTION), stateblock, context);
4575         }
4576         /* World matrix needs reapplication here only if we're switching between rhw and non-rhw
4577          * mode.
4578          *
4579          * If a vertex shader is used, the world matrix changed and then vertex shader unbound
4580          * this check will fail and the matrix not applied again. This is OK because a simple
4581          * world matrix change reapplies the matrix - These checks here are only to satisfy the
4582          * needs of the vertex declaration.
4583          *
4584          * World and view matrix go into the same gl matrix, so only apply them when neither is
4585          * dirty
4586          */
4587         if(transformed != wasrhw &&
4588            !isStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0))) &&
4589            !isStateDirty(context, STATE_TRANSFORM(WINED3DTS_VIEW))) {
4590             transform_world(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), stateblock, context);
4591         }
4592
4593         if(!isStateDirty(context, STATE_RENDER(WINED3DRS_COLORVERTEX))) {
4594             state_colormat(STATE_RENDER(WINED3DRS_COLORVERTEX), stateblock, context);
4595         }
4596
4597         if(context->last_was_vshader && !isStateDirty(context, STATE_RENDER(WINED3DRS_CLIPPLANEENABLE))) {
4598             state_clipping(STATE_RENDER(WINED3DRS_CLIPPLANEENABLE), stateblock, context);
4599         }
4600         if(!isStateDirty(context, STATE_RENDER(WINED3DRS_NORMALIZENORMALS))) {
4601             state_normalize(STATE_RENDER(WINED3DRS_NORMALIZENORMALS), stateblock, context);
4602         }
4603     } else {
4604         /* We compile the shader here because we need the vertex declaration
4605          * in order to determine if we need to do any swizzling for D3DCOLOR
4606          * registers. If the shader is already compiled this call will do nothing. */
4607         IWineD3DVertexShader_CompileShader(stateblock->vertexShader);
4608
4609         if(!context->last_was_vshader) {
4610             int i;
4611             static BOOL warned = FALSE;
4612             /* Disable all clip planes to get defined results on all drivers. See comment in the
4613              * state_clipping state handler
4614              */
4615             for(i = 0; i < GL_LIMITS(clipplanes); i++) {
4616                 glDisable(GL_CLIP_PLANE0 + i);
4617                 checkGLcall("glDisable(GL_CLIP_PLANE0 + i)");
4618             }
4619
4620             if(!warned && stateblock->renderState[WINED3DRS_CLIPPLANEENABLE]) {
4621                 FIXME("Clipping not supported with vertex shaders\n");
4622                 warned = TRUE;
4623             }
4624             if(wasrhw) {
4625                 /* Apply the transform matrices when switching from rhw drawing to vertex shaders. Vertex
4626                  * shaders themselves do not need it, but the matrices are not reapplied automatically when
4627                  * switching back from vertex shaders to fixed function processing. So make sure we leave the
4628                  * fixed function vertex processing states back in a sane state before switching to shaders
4629                  */
4630                 if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION))) {
4631                     transform_projection(STATE_TRANSFORM(WINED3DTS_PROJECTION), stateblock, context);
4632                 }
4633                 if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)))) {
4634                     transform_world(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), stateblock, context);
4635                 }
4636             }
4637         }
4638     }
4639
4640     /* Vertex and pixel shaders are applied together for now, so let the last dirty state do the
4641      * application
4642      */
4643     if (!isStateDirty(context, STATE_PIXELSHADER)) {
4644         device->shader_backend->shader_select((IWineD3DDevice *)device, usePixelShaderFunction, useVertexShaderFunction);
4645
4646         if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && (useVertexShaderFunction || usePixelShaderFunction)) {
4647             shaderconstant(STATE_VERTEXSHADERCONSTANT, stateblock, context);
4648         }
4649     }
4650
4651     context->last_was_vshader = useVertexShaderFunction;
4652
4653     if(updateFog) {
4654         state_fog(STATE_RENDER(WINED3DRS_FOGENABLE), stateblock, context);
4655     }
4656     if(!useVertexShaderFunction) {
4657         int i;
4658         for(i = 0; i < MAX_TEXTURES; i++) {
4659             if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_TEXTURE0 + i))) {
4660                 transform_texture(STATE_TRANSFORM(WINED3DTS_TEXTURE0 + i), stateblock, context);
4661             }
4662         }
4663     }
4664 }
4665
4666 static void viewport_miscpart(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
4667     UINT width, height;
4668     IWineD3DSurfaceImpl *target;
4669
4670     glDepthRange(stateblock->viewport.MinZ, stateblock->viewport.MaxZ);
4671     checkGLcall("glDepthRange");
4672     /* Note: GL requires lower left, DirectX supplies upper left. This is reversed when using offscreen rendering
4673      */
4674     if(stateblock->wineD3DDevice->render_offscreen) {
4675         glViewport(stateblock->viewport.X,
4676                    stateblock->viewport.Y,
4677                    stateblock->viewport.Width, stateblock->viewport.Height);
4678     } else {
4679         target = (IWineD3DSurfaceImpl *) stateblock->wineD3DDevice->render_targets[0];
4680         target->get_drawable_size(target, &width, &height);
4681
4682         glViewport(stateblock->viewport.X,
4683                    (height - (stateblock->viewport.Y + stateblock->viewport.Height)),
4684                    stateblock->viewport.Width, stateblock->viewport.Height);
4685     }
4686
4687     checkGLcall("glViewport");
4688 }
4689
4690 static void viewport_vertexpart(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
4691     stateblock->wineD3DDevice->posFixup[2] = 1.0 / stateblock->viewport.Width;
4692     stateblock->wineD3DDevice->posFixup[3] = -stateblock->wineD3DDevice->posFixup[1] / stateblock->viewport.Height;
4693     if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION))) {
4694         transform_projection(STATE_TRANSFORM(WINED3DTS_PROJECTION), stateblock, context);
4695     }
4696     if(!isStateDirty(context, STATE_RENDER(WINED3DRS_POINTSCALEENABLE))) {
4697         state_pscale(STATE_RENDER(WINED3DRS_POINTSCALEENABLE), stateblock, context);
4698     }
4699 }
4700
4701 static void light(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
4702     UINT Index = state - STATE_ACTIVELIGHT(0);
4703     PLIGHTINFOEL *lightInfo = stateblock->activeLights[Index];
4704
4705     if(!lightInfo) {
4706         glDisable(GL_LIGHT0 + Index);
4707         checkGLcall("glDisable(GL_LIGHT0 + Index)");
4708     } else {
4709         float quad_att;
4710         float colRGBA[] = {0.0, 0.0, 0.0, 0.0};
4711
4712         /* Light settings are affected by the model view in OpenGL, the View transform in direct3d*/
4713         glMatrixMode(GL_MODELVIEW);
4714         glPushMatrix();
4715         glLoadMatrixf(&stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
4716
4717         /* Diffuse: */
4718         colRGBA[0] = lightInfo->OriginalParms.Diffuse.r;
4719         colRGBA[1] = lightInfo->OriginalParms.Diffuse.g;
4720         colRGBA[2] = lightInfo->OriginalParms.Diffuse.b;
4721         colRGBA[3] = lightInfo->OriginalParms.Diffuse.a;
4722         glLightfv(GL_LIGHT0 + Index, GL_DIFFUSE, colRGBA);
4723         checkGLcall("glLightfv");
4724
4725         /* Specular */
4726         colRGBA[0] = lightInfo->OriginalParms.Specular.r;
4727         colRGBA[1] = lightInfo->OriginalParms.Specular.g;
4728         colRGBA[2] = lightInfo->OriginalParms.Specular.b;
4729         colRGBA[3] = lightInfo->OriginalParms.Specular.a;
4730         glLightfv(GL_LIGHT0 + Index, GL_SPECULAR, colRGBA);
4731         checkGLcall("glLightfv");
4732
4733         /* Ambient */
4734         colRGBA[0] = lightInfo->OriginalParms.Ambient.r;
4735         colRGBA[1] = lightInfo->OriginalParms.Ambient.g;
4736         colRGBA[2] = lightInfo->OriginalParms.Ambient.b;
4737         colRGBA[3] = lightInfo->OriginalParms.Ambient.a;
4738         glLightfv(GL_LIGHT0 + Index, GL_AMBIENT, colRGBA);
4739         checkGLcall("glLightfv");
4740
4741         if ((lightInfo->OriginalParms.Range *lightInfo->OriginalParms.Range) >= FLT_MIN) {
4742             quad_att = 1.4/(lightInfo->OriginalParms.Range *lightInfo->OriginalParms.Range);
4743         } else {
4744             quad_att = 0; /*  0 or  MAX?  (0 seems to be ok) */
4745         }
4746
4747         /* Do not assign attenuation values for lights that do not use them. D3D apps are free to pass any junk,
4748          * but gl drivers use them and may crash due to bad Attenuation values. Need for Speed most wanted sets
4749          * Attenuation0 to NaN and crashes in the gl lib
4750          */
4751
4752         switch (lightInfo->OriginalParms.Type) {
4753             case WINED3DLIGHT_POINT:
4754                 /* Position */
4755                 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
4756                 checkGLcall("glLightfv");
4757                 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
4758                 checkGLcall("glLightf");
4759                 /* Attenuation - Are these right? guessing... */
4760                 glLightf(GL_LIGHT0 + Index, GL_CONSTANT_ATTENUATION,  lightInfo->OriginalParms.Attenuation0);
4761                 checkGLcall("glLightf");
4762                 glLightf(GL_LIGHT0 + Index, GL_LINEAR_ATTENUATION,    lightInfo->OriginalParms.Attenuation1);
4763                 checkGLcall("glLightf");
4764                 if (quad_att < lightInfo->OriginalParms.Attenuation2) quad_att = lightInfo->OriginalParms.Attenuation2;
4765                 glLightf(GL_LIGHT0 + Index, GL_QUADRATIC_ATTENUATION, quad_att);
4766                 checkGLcall("glLightf");
4767                 /* FIXME: Range */
4768                 break;
4769
4770             case WINED3DLIGHT_SPOT:
4771                 /* Position */
4772                 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
4773                 checkGLcall("glLightfv");
4774                 /* Direction */
4775                 glLightfv(GL_LIGHT0 + Index, GL_SPOT_DIRECTION, &lightInfo->lightDirn[0]);
4776                 checkGLcall("glLightfv");
4777                 glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, lightInfo->exponent);
4778                 checkGLcall("glLightf");
4779                 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
4780                 checkGLcall("glLightf");
4781                 /* Attenuation - Are these right? guessing... */
4782                 glLightf(GL_LIGHT0 + Index, GL_CONSTANT_ATTENUATION,  lightInfo->OriginalParms.Attenuation0);
4783                 checkGLcall("glLightf");
4784                 glLightf(GL_LIGHT0 + Index, GL_LINEAR_ATTENUATION,    lightInfo->OriginalParms.Attenuation1);
4785                 checkGLcall("glLightf");
4786                 if (quad_att < lightInfo->OriginalParms.Attenuation2) quad_att = lightInfo->OriginalParms.Attenuation2;
4787                 glLightf(GL_LIGHT0 + Index, GL_QUADRATIC_ATTENUATION, quad_att);
4788                 checkGLcall("glLightf");
4789                 /* FIXME: Range */
4790                 break;
4791
4792             case WINED3DLIGHT_DIRECTIONAL:
4793                 /* Direction */
4794                 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]); /* Note gl uses w position of 0 for direction! */
4795                 checkGLcall("glLightfv");
4796                 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
4797                 checkGLcall("glLightf");
4798                 glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, 0.0f);
4799                 checkGLcall("glLightf");
4800                 break;
4801
4802             default:
4803                 FIXME("Unrecognized light type %d\n", lightInfo->OriginalParms.Type);
4804         }
4805
4806         /* Restore the modelview matrix */
4807         glPopMatrix();
4808
4809         glEnable(GL_LIGHT0 + Index);
4810         checkGLcall("glEnable(GL_LIGHT0 + Index)");
4811     }
4812
4813     return;
4814 }
4815
4816 static void scissorrect(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
4817     RECT *pRect = &stateblock->scissorRect;
4818     UINT height;
4819     UINT width;
4820     IWineD3DSurfaceImpl *target = (IWineD3DSurfaceImpl *) stateblock->wineD3DDevice->render_targets[0];
4821
4822     target->get_drawable_size(target, &width, &height);
4823     /* Warning: glScissor uses window coordinates, not viewport coordinates, so our viewport correction does not apply
4824      * Warning2: Even in windowed mode the coords are relative to the window, not the screen
4825      */
4826     TRACE("(%p) Setting new Scissor Rect to %d:%d-%d:%d\n", stateblock->wineD3DDevice, pRect->left, pRect->bottom - height,
4827           pRect->right - pRect->left, pRect->bottom - pRect->top);
4828
4829     if (stateblock->wineD3DDevice->render_offscreen) {
4830         glScissor(pRect->left, pRect->top, pRect->right - pRect->left, pRect->bottom - pRect->top);
4831     } else {
4832         glScissor(pRect->left, height - pRect->bottom, pRect->right - pRect->left, pRect->bottom - pRect->top);
4833     }
4834     checkGLcall("glScissor");
4835 }
4836
4837 static void indexbuffer(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
4838     if(stateblock->streamIsUP || stateblock->pIndexData == NULL ) {
4839         GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0));
4840     } else {
4841         IWineD3DIndexBufferImpl *ib = (IWineD3DIndexBufferImpl *) stateblock->pIndexData;
4842         GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, ib->vbo));
4843     }
4844 }
4845
4846 static void frontface(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
4847     if(stateblock->wineD3DDevice->render_offscreen) {
4848         glFrontFace(GL_CCW);
4849         checkGLcall("glFrontFace(GL_CCW)");
4850     } else {
4851         glFrontFace(GL_CW);
4852         checkGLcall("glFrontFace(GL_CW)");
4853     }
4854 }
4855
4856 const struct StateEntryTemplate misc_state_template[] = {
4857     { STATE_RENDER(WINED3DRS_SRCBLEND),                   { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         }, 0                               },
4858     { STATE_RENDER(WINED3DRS_DESTBLEND),                  { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         }, 0                               },
4859     { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         }, 0                               },
4860     { STATE_RENDER(WINED3DRS_EDGEANTIALIAS),              { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         }, 0                               },
4861     { STATE_RENDER(WINED3DRS_ANTIALIASEDLINEENABLE),      { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         }, 0                               },
4862     { STATE_RENDER(WINED3DRS_SEPARATEALPHABLENDENABLE),   { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         }, 0                               },
4863     { STATE_RENDER(WINED3DRS_SRCBLENDALPHA),              { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         }, 0                               },
4864     { STATE_RENDER(WINED3DRS_DESTBLENDALPHA),             { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         }, 0                               },
4865     { STATE_RENDER(WINED3DRS_DESTBLENDALPHA),             { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         }, 0                               },
4866     { STATE_RENDER(WINED3DRS_BLENDOPALPHA),               { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         }, 0                               },
4867     { STATE_STREAMSRC,                                    { STATE_VDECL,                                        streamsrc           }, 0                               },
4868     { STATE_VDECL,                                        { STATE_VDECL,                                        streamsrc           }, 0                               },
4869     { STATE_FRONTFACE,                                    { STATE_FRONTFACE,                                    frontface           }, 0                               },
4870     { STATE_SCISSORRECT,                                  { STATE_SCISSORRECT,                                  scissorrect         }, 0                               },
4871     /* TODO: Move shader constant loading to vertex and fragment pipeline repectively, as soon as the pshader and
4872      * vshader loadings are untied from each other
4873      */
4874     { STATE_VERTEXSHADERCONSTANT,                         { STATE_VERTEXSHADERCONSTANT,                         shaderconstant      }, 0                               },
4875     { STATE_PIXELSHADERCONSTANT,                          { STATE_VERTEXSHADERCONSTANT,                         shaderconstant      }, 0                               },
4876     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
4877     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
4878     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
4879     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
4880     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
4881     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
4882     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
4883     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
4884     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
4885     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
4886     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
4887     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
4888     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
4889     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
4890     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
4891     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
4892     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
4893     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
4894     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
4895     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
4896     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
4897     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
4898     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
4899     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
4900     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
4901     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
4902     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
4903     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
4904     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
4905     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
4906     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
4907     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }, 0                               },
4908     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE),    { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   }, 0                               },
4909     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLOFFSET),   { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLOFFSET),   tex_bumpenvloffset  }, 0                               },
4910     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE),    { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   }, 0                               },
4911     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLOFFSET),   { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLOFFSET),   tex_bumpenvloffset  }, 0                               },
4912     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE),    { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   }, 0                               },
4913     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLOFFSET),   { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLOFFSET),   tex_bumpenvloffset  }, 0                               },
4914     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE),    { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   }, 0                               },
4915     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLOFFSET),   { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLOFFSET),   tex_bumpenvloffset  }, 0                               },
4916     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE),    { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   }, 0                               },
4917     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLOFFSET),   { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLOFFSET),   tex_bumpenvloffset  }, 0                               },
4918     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE),    { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   }, 0                               },
4919     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLOFFSET),   { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLOFFSET),   tex_bumpenvloffset  }, 0                               },
4920     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE),    { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   }, 0                               },
4921     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLOFFSET),   { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLOFFSET),   tex_bumpenvloffset  }, 0                               },
4922     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE),    { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   }, 0                               },
4923     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLOFFSET),   { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLOFFSET),   tex_bumpenvloffset  }, 0                               },
4924
4925     { STATE_VIEWPORT,                                     { STATE_VIEWPORT,                                     viewport_miscpart   }, 0                               },
4926     { STATE_INDEXBUFFER,                                  { STATE_INDEXBUFFER,                                  indexbuffer         }, ARB_VERTEX_BUFFER_OBJECT        },
4927     { STATE_RENDER(WINED3DRS_ANTIALIAS),                  { STATE_RENDER(WINED3DRS_ANTIALIAS),                  state_antialias     }, 0                               },
4928     { STATE_RENDER(WINED3DRS_TEXTUREPERSPECTIVE),         { STATE_RENDER(WINED3DRS_TEXTUREPERSPECTIVE),         state_perspective   }, 0                               },
4929     { STATE_RENDER(WINED3DRS_ZENABLE),                    { STATE_RENDER(WINED3DRS_ZENABLE),                    state_zenable       }, 0                               },
4930     { STATE_RENDER(WINED3DRS_WRAPU),                      { STATE_RENDER(WINED3DRS_WRAPU),                      state_wrapu         }, 0                               },
4931     { STATE_RENDER(WINED3DRS_WRAPV),                      { STATE_RENDER(WINED3DRS_WRAPV),                      state_wrapv         }, 0                               },
4932     { STATE_RENDER(WINED3DRS_FILLMODE),                   { STATE_RENDER(WINED3DRS_FILLMODE),                   state_fillmode      }, 0                               },
4933     { STATE_RENDER(WINED3DRS_SHADEMODE),                  { STATE_RENDER(WINED3DRS_SHADEMODE),                  state_shademode     }, 0                               },
4934     { STATE_RENDER(WINED3DRS_LINEPATTERN),                { STATE_RENDER(WINED3DRS_LINEPATTERN),                state_linepattern   }, 0                               },
4935     { STATE_RENDER(WINED3DRS_MONOENABLE),                 { STATE_RENDER(WINED3DRS_MONOENABLE),                 state_monoenable    }, 0                               },
4936     { STATE_RENDER(WINED3DRS_ROP2),                       { STATE_RENDER(WINED3DRS_ROP2),                       state_rop2          }, 0                               },
4937     { STATE_RENDER(WINED3DRS_PLANEMASK),                  { STATE_RENDER(WINED3DRS_PLANEMASK),                  state_planemask     }, 0                               },
4938     { STATE_RENDER(WINED3DRS_ZWRITEENABLE),               { STATE_RENDER(WINED3DRS_ZWRITEENABLE),               state_zwritenable   }, 0                               },
4939     { STATE_RENDER(WINED3DRS_ALPHATESTENABLE),            { STATE_RENDER(WINED3DRS_ALPHATESTENABLE),            state_alpha         }, 0                               },
4940     { STATE_RENDER(WINED3DRS_ALPHAREF),                   { STATE_RENDER(WINED3DRS_ALPHATESTENABLE),            state_alpha         }, 0                               },
4941     { STATE_RENDER(WINED3DRS_ALPHAFUNC),                  { STATE_RENDER(WINED3DRS_ALPHATESTENABLE),            state_alpha         }, 0                               },
4942     { STATE_RENDER(WINED3DRS_COLORKEYENABLE),             { STATE_RENDER(WINED3DRS_ALPHATESTENABLE),            state_alpha         }, 0                               },
4943     { STATE_RENDER(WINED3DRS_LASTPIXEL),                  { STATE_RENDER(WINED3DRS_LASTPIXEL),                  state_lastpixel     }, 0                               },
4944     { STATE_RENDER(WINED3DRS_CULLMODE),                   { STATE_RENDER(WINED3DRS_CULLMODE),                   state_cullmode      }, 0                               },
4945     { STATE_RENDER(WINED3DRS_ZFUNC),                      { STATE_RENDER(WINED3DRS_ZFUNC),                      state_zfunc         }, 0                               },
4946     { STATE_RENDER(WINED3DRS_DITHERENABLE),               { STATE_RENDER(WINED3DRS_DITHERENABLE),               state_ditherenable  }, 0                               },
4947     { STATE_RENDER(WINED3DRS_SUBPIXEL),                   { STATE_RENDER(WINED3DRS_SUBPIXEL),                   state_subpixel      }, 0                               },
4948     { STATE_RENDER(WINED3DRS_SUBPIXELX),                  { STATE_RENDER(WINED3DRS_SUBPIXELX),                  state_subpixelx     }, 0                               },
4949     { STATE_RENDER(WINED3DRS_STIPPLEDALPHA),              { STATE_RENDER(WINED3DRS_STIPPLEDALPHA),              state_stippledalpha }, 0                               },
4950     { STATE_RENDER(WINED3DRS_ZBIAS),                      { STATE_RENDER(WINED3DRS_ZBIAS),                      state_zbias         }, 0                               },
4951     { STATE_RENDER(WINED3DRS_STIPPLEENABLE),              { STATE_RENDER(WINED3DRS_STIPPLEENABLE),              state_stippleenable }, 0                               },
4952     { STATE_RENDER(WINED3DRS_MIPMAPLODBIAS),              { STATE_RENDER(WINED3DRS_MIPMAPLODBIAS),              state_mipmaplodbias }, 0                               },
4953     { STATE_RENDER(WINED3DRS_ANISOTROPY),                 { STATE_RENDER(WINED3DRS_ANISOTROPY),                 state_anisotropy    }, 0                               },
4954     { STATE_RENDER(WINED3DRS_FLUSHBATCH),                 { STATE_RENDER(WINED3DRS_FLUSHBATCH),                 state_flushbatch    }, 0                               },
4955     { STATE_RENDER(WINED3DRS_TRANSLUCENTSORTINDEPENDENT), { STATE_RENDER(WINED3DRS_TRANSLUCENTSORTINDEPENDENT), state_translucentsi }, 0                               },
4956     { STATE_RENDER(WINED3DRS_STENCILENABLE),              { STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       }, 0                               },
4957     { STATE_RENDER(WINED3DRS_STENCILFAIL),                { STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       }, 0                               },
4958     { STATE_RENDER(WINED3DRS_STENCILZFAIL),               { STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       }, 0                               },
4959     { STATE_RENDER(WINED3DRS_STENCILPASS),                { STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       }, 0                               },
4960     { STATE_RENDER(WINED3DRS_STENCILFUNC),                { STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       }, 0                               },
4961     { STATE_RENDER(WINED3DRS_STENCILREF),                 { STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       }, 0                               },
4962     { STATE_RENDER(WINED3DRS_STENCILMASK),                { STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       }, 0                               },
4963     { STATE_RENDER(WINED3DRS_STENCILWRITEMASK),           { STATE_RENDER(WINED3DRS_STENCILWRITEMASK),           state_stencilwrite2s}, EXT_STENCIL_TWO_SIDE            },
4964     { STATE_RENDER(WINED3DRS_STENCILWRITEMASK),           { STATE_RENDER(WINED3DRS_STENCILWRITEMASK),           state_stencilwrite  }, 0                               },
4965     { STATE_RENDER(WINED3DRS_TWOSIDEDSTENCILMODE),        { STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       }, 0                               },
4966     { STATE_RENDER(WINED3DRS_CCW_STENCILFAIL),            { STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       }, 0                               },
4967     { STATE_RENDER(WINED3DRS_CCW_STENCILZFAIL),           { STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       }, 0                               },
4968     { STATE_RENDER(WINED3DRS_CCW_STENCILPASS),            { STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       }, 0                               },
4969     { STATE_RENDER(WINED3DRS_CCW_STENCILFUNC),            { STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       }, 0                               },
4970     { STATE_RENDER(WINED3DRS_WRAP0),                      { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }, 0                               },
4971     { STATE_RENDER(WINED3DRS_WRAP1),                      { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }, 0                               },
4972     { STATE_RENDER(WINED3DRS_WRAP2),                      { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }, 0                               },
4973     { STATE_RENDER(WINED3DRS_WRAP3),                      { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }, 0                               },
4974     { STATE_RENDER(WINED3DRS_WRAP4),                      { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }, 0                               },
4975     { STATE_RENDER(WINED3DRS_WRAP5),                      { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }, 0                               },
4976     { STATE_RENDER(WINED3DRS_WRAP6),                      { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }, 0                               },
4977     { STATE_RENDER(WINED3DRS_WRAP7),                      { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }, 0                               },
4978     { STATE_RENDER(WINED3DRS_WRAP8),                      { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }, 0                               },
4979     { STATE_RENDER(WINED3DRS_WRAP9),                      { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }, 0                               },
4980     { STATE_RENDER(WINED3DRS_WRAP10),                     { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }, 0                               },
4981     { STATE_RENDER(WINED3DRS_WRAP11),                     { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }, 0                               },
4982     { STATE_RENDER(WINED3DRS_WRAP12),                     { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }, 0                               },
4983     { STATE_RENDER(WINED3DRS_WRAP13),                     { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }, 0                               },
4984     { STATE_RENDER(WINED3DRS_WRAP14),                     { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }, 0                               },
4985     { STATE_RENDER(WINED3DRS_WRAP15),                     { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }, 0                               },
4986     { STATE_RENDER(WINED3DRS_EXTENTS),                    { STATE_RENDER(WINED3DRS_EXTENTS),                    state_extents       }, 0                               },
4987     { STATE_RENDER(WINED3DRS_COLORKEYBLENDENABLE),        { STATE_RENDER(WINED3DRS_COLORKEYBLENDENABLE),        state_ckeyblend     }, 0                               },
4988     { STATE_RENDER(WINED3DRS_PATCHEDGESTYLE),             { STATE_RENDER(WINED3DRS_PATCHEDGESTYLE),             state_patchedgestyle}, 0                               },
4989     { STATE_RENDER(WINED3DRS_PATCHSEGMENTS),              { STATE_RENDER(WINED3DRS_PATCHSEGMENTS),              state_patchsegments }, 0                               },
4990     { STATE_RENDER(WINED3DRS_POSITIONDEGREE),             { STATE_RENDER(WINED3DRS_POSITIONDEGREE),             state_positiondegree}, 0                               },
4991     { STATE_RENDER(WINED3DRS_NORMALDEGREE),               { STATE_RENDER(WINED3DRS_NORMALDEGREE),               state_normaldegree  }, 0                               },
4992     { STATE_RENDER(WINED3DRS_MINTESSELLATIONLEVEL),       { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation  }, 0                               },
4993     { STATE_RENDER(WINED3DRS_MAXTESSELLATIONLEVEL),       { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation  }, 0                               },
4994     { STATE_RENDER(WINED3DRS_ADAPTIVETESS_X),             { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation  }, 0                               },
4995     { STATE_RENDER(WINED3DRS_ADAPTIVETESS_Y),             { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation  }, 0                               },
4996     { STATE_RENDER(WINED3DRS_ADAPTIVETESS_Z),             { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation  }, 0                               },
4997     { STATE_RENDER(WINED3DRS_ADAPTIVETESS_W),             { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation  }, 0                               },
4998     { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation  }, 0                               },
4999     { STATE_RENDER(WINED3DRS_MULTISAMPLEANTIALIAS),       { STATE_RENDER(WINED3DRS_MULTISAMPLEANTIALIAS),       state_msaa          }, ARB_MULTISAMPLE                 },
5000     { STATE_RENDER(WINED3DRS_MULTISAMPLEANTIALIAS),       { STATE_RENDER(WINED3DRS_MULTISAMPLEANTIALIAS),       state_msaa_w        }, 0                               },
5001     { STATE_RENDER(WINED3DRS_MULTISAMPLEMASK),            { STATE_RENDER(WINED3DRS_MULTISAMPLEMASK),            state_multisampmask }, 0                               },
5002     { STATE_RENDER(WINED3DRS_COLORWRITEENABLE),           { STATE_RENDER(WINED3DRS_COLORWRITEENABLE),           state_colorwrite    }, 0                               },
5003     { STATE_RENDER(WINED3DRS_BLENDOP),                    { STATE_RENDER(WINED3DRS_BLENDOP),                    state_blendop       }, EXT_BLEND_MINMAX                },
5004     { STATE_RENDER(WINED3DRS_BLENDOP),                    { STATE_RENDER(WINED3DRS_BLENDOP),                    state_blendop_w     }, 0                               },
5005     { STATE_RENDER(WINED3DRS_SCISSORTESTENABLE),          { STATE_RENDER(WINED3DRS_SCISSORTESTENABLE),          state_scissor       }, 0                               },
5006     { STATE_RENDER(WINED3DRS_SLOPESCALEDEPTHBIAS),        { STATE_RENDER(WINED3DRS_DEPTHBIAS),                  state_depthbias     }, 0                               },
5007     { STATE_RENDER(WINED3DRS_COLORWRITEENABLE1),          { STATE_RENDER(WINED3DRS_COLORWRITEENABLE),           state_colorwrite    }, 0                               },
5008     { STATE_RENDER(WINED3DRS_COLORWRITEENABLE2),          { STATE_RENDER(WINED3DRS_COLORWRITEENABLE),           state_colorwrite    }, 0                               },
5009     { STATE_RENDER(WINED3DRS_COLORWRITEENABLE3),          { STATE_RENDER(WINED3DRS_COLORWRITEENABLE),           state_colorwrite    }, 0                               },
5010     { STATE_RENDER(WINED3DRS_BLENDFACTOR),                { STATE_RENDER(WINED3DRS_BLENDFACTOR),                state_blendfactor   }, EXT_BLEND_COLOR                 },
5011     { STATE_RENDER(WINED3DRS_BLENDFACTOR),                { STATE_RENDER(WINED3DRS_BLENDFACTOR),                state_blendfactor_w }, 0                               },
5012     { STATE_RENDER(WINED3DRS_DEPTHBIAS),                  { STATE_RENDER(WINED3DRS_DEPTHBIAS),                  state_depthbias     }, 0                               },
5013     /* Samplers */
5014     { STATE_SAMPLER(0),                                   { STATE_SAMPLER(0),                                   sampler             }, 0                               },
5015     { STATE_SAMPLER(1),                                   { STATE_SAMPLER(1),                                   sampler             }, 0                               },
5016     { STATE_SAMPLER(2),                                   { STATE_SAMPLER(2),                                   sampler             }, 0                               },
5017     { STATE_SAMPLER(3),                                   { STATE_SAMPLER(3),                                   sampler             }, 0                               },
5018     { STATE_SAMPLER(4),                                   { STATE_SAMPLER(4),                                   sampler             }, 0                               },
5019     { STATE_SAMPLER(5),                                   { STATE_SAMPLER(5),                                   sampler             }, 0                               },
5020     { STATE_SAMPLER(6),                                   { STATE_SAMPLER(6),                                   sampler             }, 0                               },
5021     { STATE_SAMPLER(7),                                   { STATE_SAMPLER(7),                                   sampler             }, 0                               },
5022     { STATE_SAMPLER(8),                                   { STATE_SAMPLER(8),                                   sampler             }, 0                               },
5023     { STATE_SAMPLER(9),                                   { STATE_SAMPLER(9),                                   sampler             }, 0                               },
5024     { STATE_SAMPLER(10),                                  { STATE_SAMPLER(10),                                  sampler             }, 0                               },
5025     { STATE_SAMPLER(11),                                  { STATE_SAMPLER(11),                                  sampler             }, 0                               },
5026     { STATE_SAMPLER(12),                                  { STATE_SAMPLER(12),                                  sampler             }, 0                               },
5027     { STATE_SAMPLER(13),                                  { STATE_SAMPLER(13),                                  sampler             }, 0                               },
5028     { STATE_SAMPLER(14),                                  { STATE_SAMPLER(14),                                  sampler             }, 0                               },
5029     { STATE_SAMPLER(15),                                  { STATE_SAMPLER(15),                                  sampler             }, 0                               },
5030     { STATE_SAMPLER(16), /* Vertex sampler 0 */           { STATE_SAMPLER(16),                                  sampler             }, 0                               },
5031     { STATE_SAMPLER(17), /* Vertex sampler 1 */           { STATE_SAMPLER(17),                                  sampler             }, 0                               },
5032     { STATE_SAMPLER(18), /* Vertex sampler 2 */           { STATE_SAMPLER(18),                                  sampler             }, 0                               },
5033     { STATE_SAMPLER(19), /* Vertex sampler 3 */           { STATE_SAMPLER(19),                                  sampler             }, 0                               },
5034     {0 /* Terminate */,                                   { 0,                                                  0                   }, 0                               },
5035 };
5036
5037 const struct StateEntryTemplate ffp_vertexstate_template[] = {
5038     { STATE_VDECL,                                        { STATE_VDECL,                                        vertexdeclaration   }, 0                               },
5039     { STATE_VSHADER,                                      { STATE_VDECL,                                        vertexdeclaration   }, 0                               },
5040     { STATE_MATERIAL,                                     { STATE_RENDER(WINED3DRS_SPECULARENABLE),             state_specularenable}, 0                               },
5041     { STATE_RENDER(WINED3DRS_SPECULARENABLE),             { STATE_RENDER(WINED3DRS_SPECULARENABLE),             state_specularenable}, 0                               },
5042       /* Clip planes */
5043     { STATE_CLIPPLANE(0),                                 { STATE_CLIPPLANE(0),                                 clipplane           }, 0                               },
5044     { STATE_CLIPPLANE(1),                                 { STATE_CLIPPLANE(1),                                 clipplane           }, 0                               },
5045     { STATE_CLIPPLANE(2),                                 { STATE_CLIPPLANE(2),                                 clipplane           }, 0                               },
5046     { STATE_CLIPPLANE(3),                                 { STATE_CLIPPLANE(3),                                 clipplane           }, 0                               },
5047     { STATE_CLIPPLANE(4),                                 { STATE_CLIPPLANE(4),                                 clipplane           }, 0                               },
5048     { STATE_CLIPPLANE(5),                                 { STATE_CLIPPLANE(5),                                 clipplane           }, 0                               },
5049     { STATE_CLIPPLANE(6),                                 { STATE_CLIPPLANE(6),                                 clipplane           }, 0                               },
5050     { STATE_CLIPPLANE(7),                                 { STATE_CLIPPLANE(7),                                 clipplane           }, 0                               },
5051     { STATE_CLIPPLANE(8),                                 { STATE_CLIPPLANE(8),                                 clipplane           }, 0                               },
5052     { STATE_CLIPPLANE(9),                                 { STATE_CLIPPLANE(9),                                 clipplane           }, 0                               },
5053     { STATE_CLIPPLANE(10),                                { STATE_CLIPPLANE(10),                                clipplane           }, 0                               },
5054     { STATE_CLIPPLANE(11),                                { STATE_CLIPPLANE(11),                                clipplane           }, 0                               },
5055     { STATE_CLIPPLANE(12),                                { STATE_CLIPPLANE(12),                                clipplane           }, 0                               },
5056     { STATE_CLIPPLANE(13),                                { STATE_CLIPPLANE(13),                                clipplane           }, 0                               },
5057     { STATE_CLIPPLANE(14),                                { STATE_CLIPPLANE(14),                                clipplane           }, 0                               },
5058     { STATE_CLIPPLANE(15),                                { STATE_CLIPPLANE(15),                                clipplane           }, 0                               },
5059     { STATE_CLIPPLANE(16),                                { STATE_CLIPPLANE(16),                                clipplane           }, 0                               },
5060     { STATE_CLIPPLANE(17),                                { STATE_CLIPPLANE(17),                                clipplane           }, 0                               },
5061     { STATE_CLIPPLANE(18),                                { STATE_CLIPPLANE(18),                                clipplane           }, 0                               },
5062     { STATE_CLIPPLANE(19),                                { STATE_CLIPPLANE(19),                                clipplane           }, 0                               },
5063     { STATE_CLIPPLANE(20),                                { STATE_CLIPPLANE(20),                                clipplane           }, 0                               },
5064     { STATE_CLIPPLANE(21),                                { STATE_CLIPPLANE(21),                                clipplane           }, 0                               },
5065     { STATE_CLIPPLANE(22),                                { STATE_CLIPPLANE(22),                                clipplane           }, 0                               },
5066     { STATE_CLIPPLANE(23),                                { STATE_CLIPPLANE(23),                                clipplane           }, 0                               },
5067     { STATE_CLIPPLANE(24),                                { STATE_CLIPPLANE(24),                                clipplane           }, 0                               },
5068     { STATE_CLIPPLANE(25),                                { STATE_CLIPPLANE(25),                                clipplane           }, 0                               },
5069     { STATE_CLIPPLANE(26),                                { STATE_CLIPPLANE(26),                                clipplane           }, 0                               },
5070     { STATE_CLIPPLANE(27),                                { STATE_CLIPPLANE(27),                                clipplane           }, 0                               },
5071     { STATE_CLIPPLANE(28),                                { STATE_CLIPPLANE(28),                                clipplane           }, 0                               },
5072     { STATE_CLIPPLANE(29),                                { STATE_CLIPPLANE(29),                                clipplane           }, 0                               },
5073     { STATE_CLIPPLANE(30),                                { STATE_CLIPPLANE(30),                                clipplane           }, 0                               },
5074     { STATE_CLIPPLANE(31),                                { STATE_CLIPPLANE(31),                                clipplane           }, 0                               },
5075       /* Lights */
5076     { STATE_ACTIVELIGHT(0),                               { STATE_ACTIVELIGHT(0),                               light               }, 0                               },
5077     { STATE_ACTIVELIGHT(1),                               { STATE_ACTIVELIGHT(1),                               light               }, 0                               },
5078     { STATE_ACTIVELIGHT(2),                               { STATE_ACTIVELIGHT(2),                               light               }, 0                               },
5079     { STATE_ACTIVELIGHT(3),                               { STATE_ACTIVELIGHT(3),                               light               }, 0                               },
5080     { STATE_ACTIVELIGHT(4),                               { STATE_ACTIVELIGHT(4),                               light               }, 0                               },
5081     { STATE_ACTIVELIGHT(5),                               { STATE_ACTIVELIGHT(5),                               light               }, 0                               },
5082     { STATE_ACTIVELIGHT(6),                               { STATE_ACTIVELIGHT(6),                               light               }, 0                               },
5083     { STATE_ACTIVELIGHT(7),                               { STATE_ACTIVELIGHT(7),                               light               }, 0                               },
5084     /* Viewport */
5085     { STATE_VIEWPORT,                                     { STATE_VIEWPORT,                                     viewport_vertexpart }, 0                               },
5086       /* Transform states follow                    */
5087     { STATE_TRANSFORM(WINED3DTS_VIEW),                    { STATE_TRANSFORM(WINED3DTS_VIEW),                    transform_view      }, 0                               },
5088     { STATE_TRANSFORM(WINED3DTS_PROJECTION),              { STATE_TRANSFORM(WINED3DTS_PROJECTION),              transform_projection}, 0                               },
5089     { STATE_TRANSFORM(WINED3DTS_TEXTURE0),                { STATE_TRANSFORM(WINED3DTS_TEXTURE0),                transform_texture   }, 0                               },
5090     { STATE_TRANSFORM(WINED3DTS_TEXTURE1),                { STATE_TRANSFORM(WINED3DTS_TEXTURE1),                transform_texture   }, 0                               },
5091     { STATE_TRANSFORM(WINED3DTS_TEXTURE2),                { STATE_TRANSFORM(WINED3DTS_TEXTURE2),                transform_texture   }, 0                               },
5092     { STATE_TRANSFORM(WINED3DTS_TEXTURE3),                { STATE_TRANSFORM(WINED3DTS_TEXTURE3),                transform_texture   }, 0                               },
5093     { STATE_TRANSFORM(WINED3DTS_TEXTURE4),                { STATE_TRANSFORM(WINED3DTS_TEXTURE4),                transform_texture   }, 0                               },
5094     { STATE_TRANSFORM(WINED3DTS_TEXTURE5),                { STATE_TRANSFORM(WINED3DTS_TEXTURE5),                transform_texture   }, 0                               },
5095     { STATE_TRANSFORM(WINED3DTS_TEXTURE6),                { STATE_TRANSFORM(WINED3DTS_TEXTURE6),                transform_texture   }, 0                               },
5096     { STATE_TRANSFORM(WINED3DTS_TEXTURE7),                { STATE_TRANSFORM(WINED3DTS_TEXTURE7),                transform_texture   }, 0                               },
5097     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  0)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  0)),        transform_world     }, 0                               },
5098     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  1)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  1)),        transform_world     }, 0                               },
5099     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  2)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  2)),        transform_world     }, 0                               },
5100     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  3)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  3)),        transform_world     }, 0                               },
5101     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  4)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  4)),        transform_world     }, 0                               },
5102     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  5)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  5)),        transform_world     }, 0                               },
5103     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  6)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  6)),        transform_world     }, 0                               },
5104     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  7)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  7)),        transform_world     }, 0                               },
5105     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  8)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  8)),        transform_world     }, 0                               },
5106     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  9)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  9)),        transform_world     }, 0                               },
5107     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 10)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 10)),        transform_world     }, 0                               },
5108     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 11)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 11)),        transform_world     }, 0                               },
5109     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 12)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 12)),        transform_world     }, 0                               },
5110     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 13)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 13)),        transform_world     }, 0                               },
5111     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 14)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 14)),        transform_world     }, 0                               },
5112     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 15)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 15)),        transform_world     }, 0                               },
5113     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 16)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 16)),        transform_world     }, 0                               },
5114     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 17)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 17)),        transform_world     }, 0                               },
5115     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 18)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 18)),        transform_world     }, 0                               },
5116     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 19)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 19)),        transform_world     }, 0                               },
5117     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 20)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 20)),        transform_world     }, 0                               },
5118     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 21)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 21)),        transform_world     }, 0                               },
5119     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 22)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 22)),        transform_world     }, 0                               },
5120     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 23)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 23)),        transform_world     }, 0                               },
5121     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 24)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 24)),        transform_world     }, 0                               },
5122     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 25)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 25)),        transform_world     }, 0                               },
5123     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 26)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 26)),        transform_world     }, 0                               },
5124     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 27)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 27)),        transform_world     }, 0                               },
5125     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 28)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 28)),        transform_world     }, 0                               },
5126     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 29)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 29)),        transform_world     }, 0                               },
5127     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 30)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 30)),        transform_world     }, 0                               },
5128     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 31)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 31)),        transform_world     }, 0                               },
5129     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 32)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 32)),        transform_world     }, 0                               },
5130     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 33)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 33)),        transform_world     }, 0                               },
5131     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 34)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 34)),        transform_world     }, 0                               },
5132     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 35)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 35)),        transform_world     }, 0                               },
5133     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 36)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 36)),        transform_world     }, 0                               },
5134     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 37)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 37)),        transform_world     }, 0                               },
5135     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 38)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 38)),        transform_world     }, 0                               },
5136     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 39)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 39)),        transform_world     }, 0                               },
5137     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 40)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 40)),        transform_world     }, 0                               },
5138     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 41)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 41)),        transform_world     }, 0                               },
5139     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 42)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 42)),        transform_world     }, 0                               },
5140     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 43)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 43)),        transform_world     }, 0                               },
5141     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 44)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 44)),        transform_world     }, 0                               },
5142     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 45)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 45)),        transform_world     }, 0                               },
5143     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 46)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 46)),        transform_world     }, 0                               },
5144     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 47)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 47)),        transform_world     }, 0                               },
5145     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 48)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 48)),        transform_world     }, 0                               },
5146     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 49)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 49)),        transform_world     }, 0                               },
5147     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 50)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 50)),        transform_world     }, 0                               },
5148     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 51)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 51)),        transform_world     }, 0                               },
5149     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 52)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 52)),        transform_world     }, 0                               },
5150     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 53)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 53)),        transform_world     }, 0                               },
5151     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 54)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 54)),        transform_world     }, 0                               },
5152     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 55)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 55)),        transform_world     }, 0                               },
5153     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 56)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 56)),        transform_world     }, 0                               },
5154     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 57)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 57)),        transform_world     }, 0                               },
5155     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 58)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 58)),        transform_world     }, 0                               },
5156     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 59)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 59)),        transform_world     }, 0                               },
5157     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 60)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 60)),        transform_world     }, 0                               },
5158     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 61)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 61)),        transform_world     }, 0                               },
5159     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 62)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 62)),        transform_world     }, 0                               },
5160     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 63)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 63)),        transform_world     }, 0                               },
5161     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 64)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 64)),        transform_world     }, 0                               },
5162     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 65)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 65)),        transform_world     }, 0                               },
5163     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 66)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 66)),        transform_world     }, 0                               },
5164     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 67)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 67)),        transform_world     }, 0                               },
5165     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 68)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 68)),        transform_world     }, 0                               },
5166     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 69)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 69)),        transform_world     }, 0                               },
5167     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 70)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 70)),        transform_world     }, 0                               },
5168     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 71)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 71)),        transform_world     }, 0                               },
5169     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 72)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 72)),        transform_world     }, 0                               },
5170     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 73)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 73)),        transform_world     }, 0                               },
5171     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 74)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 74)),        transform_world     }, 0                               },
5172     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 75)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 75)),        transform_world     }, 0                               },
5173     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 76)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 76)),        transform_world     }, 0                               },
5174     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 77)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 77)),        transform_world     }, 0                               },
5175     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 78)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 78)),        transform_world     }, 0                               },
5176     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 79)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 79)),        transform_world     }, 0                               },
5177     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 80)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 80)),        transform_world     }, 0                               },
5178     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 81)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 81)),        transform_world     }, 0                               },
5179     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 82)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 82)),        transform_world     }, 0                               },
5180     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 83)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 83)),        transform_world     }, 0                               },
5181     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 84)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 84)),        transform_world     }, 0                               },
5182     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 85)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 85)),        transform_world     }, 0                               },
5183     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 86)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 86)),        transform_world     }, 0                               },
5184     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 87)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 87)),        transform_world     }, 0                               },
5185     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 88)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 88)),        transform_world     }, 0                               },
5186     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 89)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 89)),        transform_world     }, 0                               },
5187     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 90)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 90)),        transform_world     }, 0                               },
5188     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 91)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 91)),        transform_world     }, 0                               },
5189     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 92)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 92)),        transform_world     }, 0                               },
5190     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 93)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 93)),        transform_world     }, 0                               },
5191     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 94)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 94)),        transform_world     }, 0                               },
5192     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 95)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 95)),        transform_world     }, 0                               },
5193     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 96)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 96)),        transform_world     }, 0                               },
5194     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 97)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 97)),        transform_world     }, 0                               },
5195     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 98)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 98)),        transform_world     }, 0                               },
5196     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 99)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 99)),        transform_world     }, 0                               },
5197     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(100)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(100)),        transform_world     }, 0                               },
5198     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(101)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(101)),        transform_world     }, 0                               },
5199     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(102)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(102)),        transform_world     }, 0                               },
5200     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(103)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(103)),        transform_world     }, 0                               },
5201     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(104)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(104)),        transform_world     }, 0                               },
5202     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(105)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(105)),        transform_world     }, 0                               },
5203     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(106)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(106)),        transform_world     }, 0                               },
5204     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(107)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(107)),        transform_world     }, 0                               },
5205     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(108)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(108)),        transform_world     }, 0                               },
5206     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(109)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(109)),        transform_world     }, 0                               },
5207     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(110)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(110)),        transform_world     }, 0                               },
5208     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(111)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(111)),        transform_world     }, 0                               },
5209     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(112)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(112)),        transform_world     }, 0                               },
5210     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(113)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(113)),        transform_world     }, 0                               },
5211     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(114)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(114)),        transform_world     }, 0                               },
5212     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(115)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(115)),        transform_world     }, 0                               },
5213     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(116)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(116)),        transform_world     }, 0                               },
5214     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(117)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(117)),        transform_world     }, 0                               },
5215     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(118)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(118)),        transform_world     }, 0                               },
5216     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(119)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(119)),        transform_world     }, 0                               },
5217     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(120)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(120)),        transform_world     }, 0                               },
5218     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(121)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(121)),        transform_world     }, 0                               },
5219     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(122)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(122)),        transform_world     }, 0                               },
5220     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(123)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(123)),        transform_world     }, 0                               },
5221     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(124)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(124)),        transform_world     }, 0                               },
5222     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(125)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(125)),        transform_world     }, 0                               },
5223     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(126)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(126)),        transform_world     }, 0                               },
5224     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(127)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(127)),        transform_world     }, 0                               },
5225     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(128)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(128)),        transform_world     }, 0                               },
5226     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(129)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(129)),        transform_world     }, 0                               },
5227     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(130)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(130)),        transform_world     }, 0                               },
5228     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(131)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(131)),        transform_world     }, 0                               },
5229     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(132)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(132)),        transform_world     }, 0                               },
5230     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(133)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(133)),        transform_world     }, 0                               },
5231     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(134)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(134)),        transform_world     }, 0                               },
5232     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(135)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(135)),        transform_world     }, 0                               },
5233     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(136)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(136)),        transform_world     }, 0                               },
5234     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(137)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(137)),        transform_world     }, 0                               },
5235     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(138)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(138)),        transform_world     }, 0                               },
5236     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(139)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(139)),        transform_world     }, 0                               },
5237     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(140)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(140)),        transform_world     }, 0                               },
5238     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(141)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(141)),        transform_world     }, 0                               },
5239     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(142)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(142)),        transform_world     }, 0                               },
5240     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(143)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(143)),        transform_world     }, 0                               },
5241     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(144)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(144)),        transform_world     }, 0                               },
5242     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(145)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(145)),        transform_world     }, 0                               },
5243     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(146)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(146)),        transform_world     }, 0                               },
5244     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(147)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(147)),        transform_world     }, 0                               },
5245     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(148)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(148)),        transform_world     }, 0                               },
5246     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(149)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(149)),        transform_world     }, 0                               },
5247     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(150)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(150)),        transform_world     }, 0                               },
5248     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(151)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(151)),        transform_world     }, 0                               },
5249     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(152)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(152)),        transform_world     }, 0                               },
5250     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(153)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(153)),        transform_world     }, 0                               },
5251     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(154)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(154)),        transform_world     }, 0                               },
5252     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(155)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(155)),        transform_world     }, 0                               },
5253     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(156)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(156)),        transform_world     }, 0                               },
5254     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(157)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(157)),        transform_world     }, 0                               },
5255     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(158)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(158)),        transform_world     }, 0                               },
5256     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(159)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(159)),        transform_world     }, 0                               },
5257     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(160)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(160)),        transform_world     }, 0                               },
5258     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(161)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(161)),        transform_world     }, 0                               },
5259     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(162)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(162)),        transform_world     }, 0                               },
5260     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(163)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(163)),        transform_world     }, 0                               },
5261     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(164)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(164)),        transform_world     }, 0                               },
5262     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(165)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(165)),        transform_world     }, 0                               },
5263     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(166)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(166)),        transform_world     }, 0                               },
5264     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(167)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(167)),        transform_world     }, 0                               },
5265     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(168)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(168)),        transform_world     }, 0                               },
5266     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(169)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(169)),        transform_world     }, 0                               },
5267     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(170)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(170)),        transform_world     }, 0                               },
5268     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(171)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(171)),        transform_world     }, 0                               },
5269     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(172)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(172)),        transform_world     }, 0                               },
5270     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(173)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(173)),        transform_world     }, 0                               },
5271     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(174)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(174)),        transform_world     }, 0                               },
5272     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(175)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(175)),        transform_world     }, 0                               },
5273     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(176)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(176)),        transform_world     }, 0                               },
5274     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(177)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(177)),        transform_world     }, 0                               },
5275     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(178)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(178)),        transform_world     }, 0                               },
5276     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(179)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(179)),        transform_world     }, 0                               },
5277     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(180)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(180)),        transform_world     }, 0                               },
5278     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(181)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(181)),        transform_world     }, 0                               },
5279     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(182)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(182)),        transform_world     }, 0                               },
5280     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(183)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(183)),        transform_world     }, 0                               },
5281     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(184)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(184)),        transform_world     }, 0                               },
5282     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(185)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(185)),        transform_world     }, 0                               },
5283     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(186)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(186)),        transform_world     }, 0                               },
5284     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(187)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(187)),        transform_world     }, 0                               },
5285     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(188)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(188)),        transform_world     }, 0                               },
5286     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(189)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(189)),        transform_world     }, 0                               },
5287     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(190)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(190)),        transform_world     }, 0                               },
5288     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(191)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(191)),        transform_world     }, 0                               },
5289     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(192)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(192)),        transform_world     }, 0                               },
5290     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(193)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(193)),        transform_world     }, 0                               },
5291     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(194)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(194)),        transform_world     }, 0                               },
5292     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(195)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(195)),        transform_world     }, 0                               },
5293     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(196)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(196)),        transform_world     }, 0                               },
5294     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(197)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(197)),        transform_world     }, 0                               },
5295     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(198)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(198)),        transform_world     }, 0                               },
5296     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(199)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(199)),        transform_world     }, 0                               },
5297     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(200)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(200)),        transform_world     }, 0                               },
5298     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(201)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(201)),        transform_world     }, 0                               },
5299     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(202)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(202)),        transform_world     }, 0                               },
5300     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(203)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(203)),        transform_world     }, 0                               },
5301     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(204)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(204)),        transform_world     }, 0                               },
5302     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(205)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(205)),        transform_world     }, 0                               },
5303     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(206)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(206)),        transform_world     }, 0                               },
5304     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(207)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(207)),        transform_world     }, 0                               },
5305     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(208)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(208)),        transform_world     }, 0                               },
5306     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(209)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(209)),        transform_world     }, 0                               },
5307     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(210)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(210)),        transform_world     }, 0                               },
5308     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(211)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(211)),        transform_world     }, 0                               },
5309     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(212)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(212)),        transform_world     }, 0                               },
5310     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(213)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(213)),        transform_world     }, 0                               },
5311     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(214)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(214)),        transform_world     }, 0                               },
5312     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(215)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(215)),        transform_world     }, 0                               },
5313     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(216)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(216)),        transform_world     }, 0                               },
5314     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(217)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(217)),        transform_world     }, 0                               },
5315     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(218)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(218)),        transform_world     }, 0                               },
5316     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(219)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(219)),        transform_world     }, 0                               },
5317     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(220)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(220)),        transform_world     }, 0                               },
5318     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(221)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(221)),        transform_world     }, 0                               },
5319     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(222)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(222)),        transform_world     }, 0                               },
5320     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(223)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(223)),        transform_world     }, 0                               },
5321     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(224)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(224)),        transform_world     }, 0                               },
5322     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(225)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(225)),        transform_world     }, 0                               },
5323     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(226)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(226)),        transform_world     }, 0                               },
5324     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(227)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(227)),        transform_world     }, 0                               },
5325     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(228)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(228)),        transform_world     }, 0                               },
5326     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(229)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(229)),        transform_world     }, 0                               },
5327     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(230)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(230)),        transform_world     }, 0                               },
5328     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(231)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(231)),        transform_world     }, 0                               },
5329     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(232)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(232)),        transform_world     }, 0                               },
5330     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(233)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(233)),        transform_world     }, 0                               },
5331     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(234)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(234)),        transform_world     }, 0                               },
5332     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(235)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(235)),        transform_world     }, 0                               },
5333     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(236)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(236)),        transform_world     }, 0                               },
5334     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(237)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(237)),        transform_world     }, 0                               },
5335     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(238)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(238)),        transform_world     }, 0                               },
5336     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(239)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(239)),        transform_world     }, 0                               },
5337     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(240)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(240)),        transform_world     }, 0                               },
5338     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(241)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(241)),        transform_world     }, 0                               },
5339     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(242)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(242)),        transform_world     }, 0                               },
5340     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(243)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(243)),        transform_world     }, 0                               },
5341     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(244)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(244)),        transform_world     }, 0                               },
5342     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(245)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(245)),        transform_world     }, 0                               },
5343     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(246)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(246)),        transform_world     }, 0                               },
5344     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(247)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(247)),        transform_world     }, 0                               },
5345     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(248)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(248)),        transform_world     }, 0                               },
5346     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(249)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(249)),        transform_world     }, 0                               },
5347     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(250)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(250)),        transform_world     }, 0                               },
5348     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(251)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(251)),        transform_world     }, 0                               },
5349     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(252)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(252)),        transform_world     }, 0                               },
5350     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(253)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(253)),        transform_world     }, 0                               },
5351     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(254)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(254)),        transform_world     }, 0                               },
5352     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(255)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(255)),        transform_world     }, 0                               },
5353     { STATE_TEXTURESTAGE(0,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TRANSFORM(WINED3DTS_TEXTURE0),              transform_texture   }, 0                               },
5354     { STATE_TEXTURESTAGE(1,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TRANSFORM(WINED3DTS_TEXTURE1),              transform_texture   }, 0                               },
5355     { STATE_TEXTURESTAGE(2,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TRANSFORM(WINED3DTS_TEXTURE2),              transform_texture   }, 0                               },
5356     { STATE_TEXTURESTAGE(3,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TRANSFORM(WINED3DTS_TEXTURE3),              transform_texture   }, 0                               },
5357     { STATE_TEXTURESTAGE(4,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TRANSFORM(WINED3DTS_TEXTURE4),              transform_texture   }, 0                               },
5358     { STATE_TEXTURESTAGE(5,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TRANSFORM(WINED3DTS_TEXTURE5),              transform_texture   }, 0                               },
5359     { STATE_TEXTURESTAGE(6,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TRANSFORM(WINED3DTS_TEXTURE6),              transform_texture   }, 0                               },
5360     { STATE_TEXTURESTAGE(7,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TRANSFORM(WINED3DTS_TEXTURE7),              transform_texture   }, 0                               },
5361     { STATE_TEXTURESTAGE(0, WINED3DTSS_TEXCOORDINDEX),    { STATE_TEXTURESTAGE(0, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      }, 0                               },
5362     { STATE_TEXTURESTAGE(1, WINED3DTSS_TEXCOORDINDEX),    { STATE_TEXTURESTAGE(1, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      }, 0                               },
5363     { STATE_TEXTURESTAGE(2, WINED3DTSS_TEXCOORDINDEX),    { STATE_TEXTURESTAGE(2, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      }, 0                               },
5364     { STATE_TEXTURESTAGE(3, WINED3DTSS_TEXCOORDINDEX),    { STATE_TEXTURESTAGE(3, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      }, 0                               },
5365     { STATE_TEXTURESTAGE(4, WINED3DTSS_TEXCOORDINDEX),    { STATE_TEXTURESTAGE(4, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      }, 0                               },
5366     { STATE_TEXTURESTAGE(5, WINED3DTSS_TEXCOORDINDEX),    { STATE_TEXTURESTAGE(5, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      }, 0                               },
5367     { STATE_TEXTURESTAGE(6, WINED3DTSS_TEXCOORDINDEX),    { STATE_TEXTURESTAGE(6, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      }, 0                               },
5368     { STATE_TEXTURESTAGE(7, WINED3DTSS_TEXCOORDINDEX),    { STATE_TEXTURESTAGE(7, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      }, 0                               },
5369       /* Fog */
5370     { STATE_RENDER(WINED3DRS_FOGENABLE),                  { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog           }, 0                               },
5371     { STATE_RENDER(WINED3DRS_FOGTABLEMODE),               { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog           }, 0                               },
5372     { STATE_RENDER(WINED3DRS_FOGSTART),                   { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog           }, 0                               },
5373     { STATE_RENDER(WINED3DRS_FOGEND),                     { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog           }, 0                               },
5374     { STATE_RENDER(WINED3DRS_FOGVERTEXMODE),              { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog           }, 0                               },
5375     { STATE_RENDER(WINED3DRS_FOGCOLOR),                   { STATE_RENDER(WINED3DRS_FOGCOLOR),                   state_fogcolor      }, 0                               },
5376     { STATE_RENDER(WINED3DRS_FOGDENSITY),                 { STATE_RENDER(WINED3DRS_FOGDENSITY),                 state_fogdensity    }, 0                               },
5377     { STATE_RENDER(WINED3DRS_RANGEFOGENABLE),             { STATE_RENDER(WINED3DRS_RANGEFOGENABLE),             state_rangefog      }, NV_FOG_DISTANCE                 },
5378     { STATE_RENDER(WINED3DRS_RANGEFOGENABLE),             { STATE_RENDER(WINED3DRS_RANGEFOGENABLE),             state_rangefog_w    }, 0                               },
5379     { STATE_RENDER(WINED3DRS_CLIPPING),                   { STATE_RENDER(WINED3DRS_CLIPPING),                   state_clipping      }, 0                               },
5380     { STATE_RENDER(WINED3DRS_CLIPPLANEENABLE),            { STATE_RENDER(WINED3DRS_CLIPPING),                   state_clipping      }, 0                               },
5381     { STATE_RENDER(WINED3DRS_LIGHTING),                   { STATE_RENDER(WINED3DRS_LIGHTING),                   state_lighting      }, 0                               },
5382     { STATE_RENDER(WINED3DRS_AMBIENT),                    { STATE_RENDER(WINED3DRS_AMBIENT),                    state_ambient       }, 0                               },
5383     { STATE_RENDER(WINED3DRS_COLORVERTEX),                { STATE_RENDER(WINED3DRS_COLORVERTEX),                state_colormat      }, 0                               },
5384     { STATE_RENDER(WINED3DRS_LOCALVIEWER),                { STATE_RENDER(WINED3DRS_LOCALVIEWER),                state_localviewer   }, 0                               },
5385     { STATE_RENDER(WINED3DRS_NORMALIZENORMALS),           { STATE_RENDER(WINED3DRS_NORMALIZENORMALS),           state_normalize     }, 0                               },
5386     { STATE_RENDER(WINED3DRS_DIFFUSEMATERIALSOURCE),      { STATE_RENDER(WINED3DRS_COLORVERTEX),                state_colormat      }, 0                               },
5387     { STATE_RENDER(WINED3DRS_SPECULARMATERIALSOURCE),     { STATE_RENDER(WINED3DRS_COLORVERTEX),                state_colormat      }, 0                               },
5388     { STATE_RENDER(WINED3DRS_AMBIENTMATERIALSOURCE),      { STATE_RENDER(WINED3DRS_COLORVERTEX),                state_colormat      }, 0                               },
5389     { STATE_RENDER(WINED3DRS_EMISSIVEMATERIALSOURCE),     { STATE_RENDER(WINED3DRS_COLORVERTEX),                state_colormat      }, 0                               },
5390     { STATE_RENDER(WINED3DRS_VERTEXBLEND),                { STATE_RENDER(WINED3DRS_VERTEXBLEND),                state_vertexblend   }, ARB_VERTEX_BLEND                },
5391     { STATE_RENDER(WINED3DRS_VERTEXBLEND),                { STATE_RENDER(WINED3DRS_VERTEXBLEND),                state_vertexblend_w }, 0                               },
5392     { STATE_RENDER(WINED3DRS_POINTSIZE),                  { STATE_RENDER(WINED3DRS_POINTSCALEENABLE),           state_pscale        }, 0                               },
5393     { STATE_RENDER(WINED3DRS_POINTSIZE_MIN),              { STATE_RENDER(WINED3DRS_POINTSIZE_MIN),              state_psizemin_arb  }, ARB_POINT_PARAMETERS            },
5394     { STATE_RENDER(WINED3DRS_POINTSIZE_MIN),              { STATE_RENDER(WINED3DRS_POINTSIZE_MIN),              state_psizemin_ext  }, EXT_POINT_PARAMETERS            },
5395     { STATE_RENDER(WINED3DRS_POINTSIZE_MIN),              { STATE_RENDER(WINED3DRS_POINTSIZE_MIN),              state_psizemin_w    }, 0                               },
5396     { STATE_RENDER(WINED3DRS_POINTSPRITEENABLE),          { STATE_RENDER(WINED3DRS_POINTSPRITEENABLE),          state_pointsprite   }, ARB_POINT_SPRITE                },
5397     { STATE_RENDER(WINED3DRS_POINTSPRITEENABLE),          { STATE_RENDER(WINED3DRS_POINTSPRITEENABLE),          state_pointsprite_w }, 0                               },
5398     { STATE_RENDER(WINED3DRS_POINTSCALEENABLE),           { STATE_RENDER(WINED3DRS_POINTSCALEENABLE),           state_pscale        }, 0                               },
5399     { STATE_RENDER(WINED3DRS_POINTSCALE_A),               { STATE_RENDER(WINED3DRS_POINTSCALEENABLE),           state_pscale        }, 0                               },
5400     { STATE_RENDER(WINED3DRS_POINTSCALE_B),               { STATE_RENDER(WINED3DRS_POINTSCALEENABLE),           state_pscale        }, 0                               },
5401     { STATE_RENDER(WINED3DRS_POINTSCALE_C),               { STATE_RENDER(WINED3DRS_POINTSCALEENABLE),           state_pscale        }, 0                               },
5402     { STATE_RENDER(WINED3DRS_POINTSIZE_MAX),              { STATE_RENDER(WINED3DRS_POINTSIZE_MAX),              state_psizemax_arb  }, ARB_POINT_PARAMETERS            },
5403     { STATE_RENDER(WINED3DRS_POINTSIZE_MAX),              { STATE_RENDER(WINED3DRS_POINTSIZE_MAX),              state_psizemax_ext  }, EXT_POINT_PARAMETERS            },
5404     { STATE_RENDER(WINED3DRS_POINTSIZE_MAX),              { STATE_RENDER(WINED3DRS_POINTSIZE_MAX),              state_psizemax_w    }, 0                               },
5405     /* pixel shaders need a different fog input */
5406     { STATE_PIXELSHADER,                                  { STATE_PIXELSHADER,                                  apply_pshader_fog   }, 0                               },
5407     /* Samplers for NP2 texture matrix adjustions. They are not needed if GL_ARB_texture_non_power_of_two is supported,
5408      * so register a NULL state handler in that case to get the vertex part of sampler() skipped(VTF is handled in the misc states.
5409      * otherwise, register sampler_texmatrix, which takes care of updating the texture matrix
5410      */
5411     { STATE_SAMPLER(0),                                   { 0,                                                  NULL                }, ARB_TEXTURE_NON_POWER_OF_TWO    },
5412     { STATE_SAMPLER(0),                                   { 0,                                                  NULL                }, WINE_NORMALIZED_TEXRECT         },
5413     { STATE_SAMPLER(0),                                   { STATE_SAMPLER(0),                                   sampler_texmatrix   }, 0                               },
5414     { STATE_SAMPLER(1),                                   { 0,                                                  NULL                }, ARB_TEXTURE_NON_POWER_OF_TWO    },
5415     { STATE_SAMPLER(1),                                   { 0,                                                  NULL                }, WINE_NORMALIZED_TEXRECT         },
5416     { STATE_SAMPLER(1),                                   { STATE_SAMPLER(1),                                   sampler_texmatrix   }, 0                               },
5417     { STATE_SAMPLER(2),                                   { 0,                                                  NULL                }, ARB_TEXTURE_NON_POWER_OF_TWO    },
5418     { STATE_SAMPLER(2),                                   { 0,                                                  NULL                }, WINE_NORMALIZED_TEXRECT         },
5419     { STATE_SAMPLER(2),                                   { STATE_SAMPLER(2),                                   sampler_texmatrix   }, 0                               },
5420     { STATE_SAMPLER(3),                                   { 0,                                                  NULL                }, ARB_TEXTURE_NON_POWER_OF_TWO    },
5421     { STATE_SAMPLER(3),                                   { 0,                                                  NULL                }, WINE_NORMALIZED_TEXRECT         },
5422     { STATE_SAMPLER(3),                                   { STATE_SAMPLER(3),                                   sampler_texmatrix   }, 0                               },
5423     { STATE_SAMPLER(4),                                   { 0,                                                  NULL                }, ARB_TEXTURE_NON_POWER_OF_TWO    },
5424     { STATE_SAMPLER(4),                                   { 0,                                                  NULL                }, WINE_NORMALIZED_TEXRECT         },
5425     { STATE_SAMPLER(4),                                   { STATE_SAMPLER(4),                                   sampler_texmatrix   }, 0                               },
5426     { STATE_SAMPLER(5),                                   { 0,                                                  NULL                }, ARB_TEXTURE_NON_POWER_OF_TWO    },
5427     { STATE_SAMPLER(5),                                   { 0,                                                  NULL                }, WINE_NORMALIZED_TEXRECT         },
5428     { STATE_SAMPLER(5),                                   { STATE_SAMPLER(5),                                   sampler_texmatrix   }, 0                               },
5429     { STATE_SAMPLER(6),                                   { 0,                                                  NULL                }, ARB_TEXTURE_NON_POWER_OF_TWO    },
5430     { STATE_SAMPLER(6),                                   { 0,                                                  NULL                }, WINE_NORMALIZED_TEXRECT         },
5431     { STATE_SAMPLER(6),                                   { STATE_SAMPLER(6),                                   sampler_texmatrix   }, 0                               },
5432     { STATE_SAMPLER(7),                                   { 0,                                                  NULL                }, ARB_TEXTURE_NON_POWER_OF_TWO    },
5433     { STATE_SAMPLER(7),                                   { 0,                                                  NULL                }, WINE_NORMALIZED_TEXRECT         },
5434     { STATE_SAMPLER(7),                                   { STATE_SAMPLER(7),                                   sampler_texmatrix   }, 0                               },
5435     {0 /* Terminate */,                                   { 0,                                                  0                   }, 0                               },
5436 };
5437
5438 static const struct StateEntryTemplate ffp_fragmentstate_template[] = {
5439     { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
5440     { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG1),        { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
5441     { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG2),        { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
5442     { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP),          { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
5443     { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG1),        { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
5444     { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG2),        { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
5445     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }, ATI_ENVMAP_BUMPMAP              },
5446     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }, ATI_ENVMAP_BUMPMAP              },
5447     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }, ATI_ENVMAP_BUMPMAP              },
5448     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }, ATI_ENVMAP_BUMPMAP              },
5449     { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG0),        { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
5450     { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG0),        { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
5451     { STATE_TEXTURESTAGE(0, WINED3DTSS_RESULTARG),        { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
5452     { STATE_TEXTURESTAGE(0, WINED3DTSS_CONSTANT),         { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl          }, 0                               },
5453     { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP),          { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
5454     { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG1),        { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
5455     { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG2),        { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
5456     { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP),          { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
5457     { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG1),        { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
5458     { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG2),        { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
5459     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }, ATI_ENVMAP_BUMPMAP              },
5460     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }, ATI_ENVMAP_BUMPMAP              },
5461     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }, ATI_ENVMAP_BUMPMAP              },
5462     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }, ATI_ENVMAP_BUMPMAP              },
5463     { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG0),        { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
5464     { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG0),        { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
5465     { STATE_TEXTURESTAGE(1, WINED3DTSS_RESULTARG),        { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
5466     { STATE_TEXTURESTAGE(1, WINED3DTSS_CONSTANT),         { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl          }, 0                               },
5467     { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP),          { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
5468     { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG1),        { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
5469     { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG2),        { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
5470     { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP),          { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
5471     { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG1),        { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
5472     { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG2),        { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
5473     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }, ATI_ENVMAP_BUMPMAP              },
5474     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }, ATI_ENVMAP_BUMPMAP              },
5475     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }, ATI_ENVMAP_BUMPMAP              },
5476     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }, ATI_ENVMAP_BUMPMAP              },
5477     { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG0),        { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
5478     { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG0),        { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
5479     { STATE_TEXTURESTAGE(2, WINED3DTSS_RESULTARG),        { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
5480     { STATE_TEXTURESTAGE(2, WINED3DTSS_CONSTANT),         { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl          }, 0                               },
5481     { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP),          { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
5482     { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG1),        { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
5483     { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG2),        { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
5484     { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP),          { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
5485     { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG1),        { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
5486     { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG2),        { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
5487     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }, ATI_ENVMAP_BUMPMAP              },
5488     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }, ATI_ENVMAP_BUMPMAP              },
5489     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }, ATI_ENVMAP_BUMPMAP              },
5490     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }, ATI_ENVMAP_BUMPMAP              },
5491     { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG0),        { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
5492     { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG0),        { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
5493     { STATE_TEXTURESTAGE(3, WINED3DTSS_RESULTARG),        { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
5494     { STATE_TEXTURESTAGE(3, WINED3DTSS_CONSTANT),         { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl          }, 0                               },
5495     { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP),          { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
5496     { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG1),        { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
5497     { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG2),        { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
5498     { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP),          { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
5499     { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG1),        { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
5500     { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG2),        { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
5501     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }, ATI_ENVMAP_BUMPMAP              },
5502     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }, ATI_ENVMAP_BUMPMAP              },
5503     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }, ATI_ENVMAP_BUMPMAP              },
5504     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }, ATI_ENVMAP_BUMPMAP              },
5505     { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG0),        { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
5506     { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG0),        { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
5507     { STATE_TEXTURESTAGE(4, WINED3DTSS_RESULTARG),        { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
5508     { STATE_TEXTURESTAGE(4, WINED3DTSS_CONSTANT),         { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl          }, 0                               },
5509     { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP),          { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
5510     { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG1),        { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
5511     { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG2),        { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
5512     { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP),          { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
5513     { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG1),        { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
5514     { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG2),        { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
5515     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }, ATI_ENVMAP_BUMPMAP              },
5516     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }, ATI_ENVMAP_BUMPMAP              },
5517     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }, ATI_ENVMAP_BUMPMAP              },
5518     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }, ATI_ENVMAP_BUMPMAP              },
5519     { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG0),        { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
5520     { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG0),        { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
5521     { STATE_TEXTURESTAGE(5, WINED3DTSS_RESULTARG),        { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
5522     { STATE_TEXTURESTAGE(5, WINED3DTSS_CONSTANT),         { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl          }, 0                               },
5523     { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP),          { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
5524     { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG1),        { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
5525     { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG2),        { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
5526     { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP),          { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
5527     { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG1),        { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
5528     { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG2),        { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
5529     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }, ATI_ENVMAP_BUMPMAP              },
5530     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }, ATI_ENVMAP_BUMPMAP              },
5531     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }, ATI_ENVMAP_BUMPMAP              },
5532     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }, ATI_ENVMAP_BUMPMAP              },
5533     { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG0),        { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
5534     { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG0),        { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
5535     { STATE_TEXTURESTAGE(6, WINED3DTSS_RESULTARG),        { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
5536     { STATE_TEXTURESTAGE(6, WINED3DTSS_CONSTANT),         { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl          }, 0                               },
5537     { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP),          { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
5538     { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG1),        { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
5539     { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG2),        { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
5540     { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP),          { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
5541     { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG1),        { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
5542     { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG2),        { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
5543     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }, ATI_ENVMAP_BUMPMAP              },
5544     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }, ATI_ENVMAP_BUMPMAP              },
5545     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }, ATI_ENVMAP_BUMPMAP              },
5546     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }, ATI_ENVMAP_BUMPMAP              },
5547     { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG0),        { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
5548     { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG0),        { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP),          tex_alphaop         }, 0                               },
5549     { STATE_TEXTURESTAGE(7, WINED3DTSS_RESULTARG),        { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP),          tex_colorop         }, 0                               },
5550     { STATE_TEXTURESTAGE(7, WINED3DTSS_CONSTANT),         { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl          }, 0                               },
5551     { STATE_PIXELSHADER,                                  { STATE_PIXELSHADER,                                  apply_pixelshader   }, 0                               },
5552     { STATE_RENDER(WINED3DRS_SRGBWRITEENABLE),            { STATE_PIXELSHADER,                                  apply_pixelshader   }, 0                               },
5553     { STATE_RENDER(WINED3DRS_BORDERCOLOR),                { STATE_RENDER(WINED3DRS_BORDERCOLOR),                state_bordercolor   }, 0                               },
5554     { STATE_RENDER(WINED3DRS_TEXTUREFACTOR),              { STATE_RENDER(WINED3DRS_TEXTUREFACTOR),              state_texfactor     }, 0                               },
5555     { STATE_SAMPLER(0),                                   { STATE_SAMPLER(0),                                   sampler_texdim      }, 0                               },
5556     { STATE_SAMPLER(1),                                   { STATE_SAMPLER(1),                                   sampler_texdim      }, 0                               },
5557     { STATE_SAMPLER(2),                                   { STATE_SAMPLER(2),                                   sampler_texdim      }, 0                               },
5558     { STATE_SAMPLER(3),                                   { STATE_SAMPLER(3),                                   sampler_texdim      }, 0                               },
5559     { STATE_SAMPLER(4),                                   { STATE_SAMPLER(4),                                   sampler_texdim      }, 0                               },
5560     { STATE_SAMPLER(5),                                   { STATE_SAMPLER(5),                                   sampler_texdim      }, 0                               },
5561     { STATE_SAMPLER(6),                                   { STATE_SAMPLER(6),                                   sampler_texdim      }, 0                               },
5562     { STATE_SAMPLER(7),                                   { STATE_SAMPLER(7),                                   sampler_texdim      }, 0                               },
5563     {0 /* Terminate */,                                   { 0,                                                  0                   }, 0                               },
5564 };
5565 #undef GLINFO_LOCATION
5566
5567 #define GLINFO_LOCATION (*gl_info)
5568 static void ffp_enable(IWineD3DDevice *iface, BOOL enable) { }
5569
5570 static void ffp_fragment_get_caps(WINED3DDEVTYPE devtype, WineD3D_GL_Info *gl_info, struct fragment_caps *pCaps) {
5571     pCaps->TextureOpCaps =  WINED3DTEXOPCAPS_ADD         |
5572                             WINED3DTEXOPCAPS_ADDSIGNED   |
5573                             WINED3DTEXOPCAPS_ADDSIGNED2X |
5574                             WINED3DTEXOPCAPS_MODULATE    |
5575                             WINED3DTEXOPCAPS_MODULATE2X  |
5576                             WINED3DTEXOPCAPS_MODULATE4X  |
5577                             WINED3DTEXOPCAPS_SELECTARG1  |
5578                             WINED3DTEXOPCAPS_SELECTARG2  |
5579                             WINED3DTEXOPCAPS_DISABLE;
5580
5581     if (GL_SUPPORT(ARB_TEXTURE_ENV_COMBINE) ||
5582         GL_SUPPORT(EXT_TEXTURE_ENV_COMBINE) ||
5583         GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
5584         pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_BLENDDIFFUSEALPHA  |
5585                                 WINED3DTEXOPCAPS_BLENDTEXTUREALPHA  |
5586                                 WINED3DTEXOPCAPS_BLENDFACTORALPHA   |
5587                                 WINED3DTEXOPCAPS_BLENDCURRENTALPHA  |
5588                                 WINED3DTEXOPCAPS_LERP               |
5589                                 WINED3DTEXOPCAPS_SUBTRACT;
5590     }
5591     if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3) ||
5592         GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
5593         pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_ADDSMOOTH              |
5594                                 WINED3DTEXOPCAPS_MULTIPLYADD            |
5595                                 WINED3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR |
5596                                 WINED3DTEXOPCAPS_MODULATECOLOR_ADDALPHA |
5597                                 WINED3DTEXOPCAPS_BLENDTEXTUREALPHAPM;
5598     }
5599     if (GL_SUPPORT(ARB_TEXTURE_ENV_DOT3))
5600         pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_DOTPRODUCT3;
5601
5602     if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
5603         pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_BUMPENVMAP;
5604     }
5605
5606     pCaps->MaxTextureBlendStages   = GL_LIMITS(texture_stages);
5607     pCaps->MaxSimultaneousTextures = GL_LIMITS(textures);
5608 }
5609
5610 static HRESULT ffp_fragment_alloc(IWineD3DDevice *iface) { return WINED3D_OK; }
5611 static void ffp_fragment_free(IWineD3DDevice *iface) {}
5612 static BOOL ffp_conv_supported(WINED3DFORMAT fmt) {
5613     TRACE("Checking shader format support for format %s: [FAILED]", debug_d3dformat(fmt));
5614     return FALSE;
5615 }
5616
5617 const struct fragment_pipeline ffp_fragment_pipeline = {
5618     ffp_enable,
5619     ffp_fragment_get_caps,
5620     ffp_fragment_alloc,
5621     ffp_fragment_free,
5622     ffp_conv_supported,
5623     ffp_fragmentstate_template
5624 };
5625
5626 static int num_handlers(APPLYSTATEFUNC *funcs) {
5627     unsigned int i;
5628     for(i = 0; funcs[i]; i++);
5629     return i;
5630 }
5631
5632 static void multistate_apply_2(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
5633     stateblock->wineD3DDevice->multistate_funcs[state][0](state, stateblock, context);
5634     stateblock->wineD3DDevice->multistate_funcs[state][1](state, stateblock, context);
5635 }
5636
5637 static void multistate_apply_3(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
5638     stateblock->wineD3DDevice->multistate_funcs[state][0](state, stateblock, context);
5639     stateblock->wineD3DDevice->multistate_funcs[state][1](state, stateblock, context);
5640     stateblock->wineD3DDevice->multistate_funcs[state][2](state, stateblock, context);
5641 }
5642
5643 void compile_state_table(struct StateEntry *StateTable,
5644                          APPLYSTATEFUNC **dev_multistate_funcs,
5645                          WineD3D_GL_Info *gl_info,
5646                          const struct StateEntryTemplate *vertex,
5647                          const struct fragment_pipeline *fragment,
5648                          const struct StateEntryTemplate *misc) {
5649     unsigned int i, type, handlers;
5650     APPLYSTATEFUNC multistate_funcs[STATE_HIGHEST + 1][3];
5651     const struct StateEntryTemplate *cur;
5652     BOOL set[STATE_HIGHEST + 1];
5653
5654     memset(multistate_funcs, 0, sizeof(multistate_funcs));
5655
5656     for(i = 0; i < STATE_HIGHEST + 1; i++) {
5657         StateTable[i].representative = 0;
5658         StateTable[i].apply = state_undefined;
5659     }
5660
5661     for(type = 0; type < 3; type++) {
5662         /* This switch decides the order in which the states are applied */
5663         switch(type) {
5664             case 0: cur = misc; break;
5665             case 1: cur = fragment->states; break;
5666             case 2: cur = vertex; break;
5667             default: cur = NULL; /* Stupid compiler */
5668         }
5669         if(!cur) continue;
5670
5671         /* GL extension filtering should not prevent multiple handlers being applied from different
5672          * pipeline parts
5673          */
5674         memset(set, 0, sizeof(set));
5675
5676         for(i = 0; cur[i].state; i++) {
5677
5678             /* Only use the first matching state with the available extension from one template.
5679              * e.g.
5680              * {D3DRS_FOOBAR, {D3DRS_FOOBAR, func1}, XYZ_FANCY},
5681              * {D3DRS_FOOBAR, {D3DRS_FOOBAR, func2}, 0        }
5682              *
5683              * if GL_XYZ_fancy is supported, ignore the 2nd line
5684              */
5685             if(set[cur[i].state]) continue;
5686             /* Skip state lines depending on unsupported extensions */
5687             if(cur[i].extension && !GL_SUPPORT(cur[i].extension)) continue;
5688             set[cur[i].state] = TRUE;
5689             /* In some cases having an extension means that nothing has to be
5690              * done for a state, e.g. if GL_ARB_texture_non_power_of_two is
5691              * supported, the texture coordinate fixup can be ignored. If the
5692              * apply function is used, mark the state set(done above) to prevent
5693              * applying later lines, but do not record anything in the state
5694              * table
5695              */
5696             if(!cur[i].content.apply) continue;
5697
5698             handlers = num_handlers(multistate_funcs[cur[i].state]);
5699             multistate_funcs[cur[i].state][handlers] = cur[i].content.apply;
5700             switch(handlers) {
5701                 case 0:
5702                     StateTable[cur[i].state].apply = cur[i].content.apply;
5703                     break;
5704                 case 1:
5705                     StateTable[cur[i].state].apply = multistate_apply_2;
5706                     dev_multistate_funcs[cur[i].state] = HeapAlloc(GetProcessHeap(),
5707                                                                    0,
5708                                                                    sizeof(**dev_multistate_funcs) * 2);
5709                     dev_multistate_funcs[cur[i].state][0] = multistate_funcs[cur[i].state][0];
5710                     dev_multistate_funcs[cur[i].state][1] = multistate_funcs[cur[i].state][1];
5711                     break;
5712                 case 2:
5713                     StateTable[cur[i].state].apply = multistate_apply_3;
5714                     HeapFree(GetProcessHeap(), 0, multistate_funcs[cur[i].state]);
5715                     dev_multistate_funcs[cur[i].state] = HeapAlloc(GetProcessHeap(),
5716                                                                    0,
5717                                                                    sizeof(**dev_multistate_funcs) * 3);
5718                     dev_multistate_funcs[cur[i].state][0] = multistate_funcs[cur[i].state][0];
5719                     dev_multistate_funcs[cur[i].state][1] = multistate_funcs[cur[i].state][1];
5720                     dev_multistate_funcs[cur[i].state][2] = multistate_funcs[cur[i].state][2];
5721                     break;
5722                 default:
5723                     ERR("Unexpected amount of state handlers for state %u: %u\n",
5724                         cur[i].state, handlers + 1);
5725             }
5726
5727             if(StateTable[cur[i].state].representative &&
5728             StateTable[cur[i].state].representative != cur[i].content.representative) {
5729                 FIXME("State %u has different representatives in different pipeline parts\n",
5730                     cur[i].state);
5731             }
5732             StateTable[cur[i].state].representative = cur[i].content.representative;
5733         }
5734     }
5735 }
5736 #undef GLINFO_LOCATION