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