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