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