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