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