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