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