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