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