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