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