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