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