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