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