d3drm: Implement IDirect3DRMMesh_GetGroupColor.
[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 = -1.0f / 0.0f;
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)) unload_numbered_array(context, i);
4086             continue;
4087         }
4088
4089         stream = &state->streams[stream_info->elements[i].stream_idx];
4090
4091         /* Do not load instance data. It will be specified using glTexCoord by drawprim */
4092         if (stream->flags & WINED3DSTREAMSOURCE_INSTANCEDATA)
4093         {
4094             if (context->numbered_array_mask & (1 << i)) unload_numbered_array(context, i);
4095             device->instancedDraw = TRUE;
4096             continue;
4097         }
4098
4099         TRACE_(d3d_shader)("Loading array %u [VBO=%u]\n", i, stream_info->elements[i].data.buffer_object);
4100
4101         if (stream_info->elements[i].stride)
4102         {
4103             if (curVBO != stream_info->elements[i].data.buffer_object)
4104             {
4105                 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, stream_info->elements[i].data.buffer_object));
4106                 checkGLcall("glBindBufferARB");
4107                 curVBO = stream_info->elements[i].data.buffer_object;
4108             }
4109             /* Use the VBO to find out if a vertex buffer exists, not the vb
4110              * pointer. vb can point to a user pointer data blob. In that case
4111              * curVBO will be 0. If there is a vertex buffer but no vbo we
4112              * won't be load converted attributes anyway. */
4113             GL_EXTCALL(glVertexAttribPointerARB(i, stream_info->elements[i].format->gl_vtx_format,
4114                     stream_info->elements[i].format->gl_vtx_type,
4115                     stream_info->elements[i].format->gl_normalized,
4116                     stream_info->elements[i].stride, stream_info->elements[i].data.addr
4117                     + state->load_base_vertex_index * stream_info->elements[i].stride));
4118
4119             if (!(context->numbered_array_mask & (1 << i)))
4120             {
4121                 GL_EXTCALL(glEnableVertexAttribArrayARB(i));
4122                 context->numbered_array_mask |= (1 << i);
4123             }
4124         }
4125         else
4126         {
4127             /* Stride = 0 means always the same values.
4128              * glVertexAttribPointerARB doesn't do that. Instead disable the
4129              * pointer and set up the attribute statically. But we have to
4130              * figure out the system memory address. */
4131             const BYTE *ptr = stream_info->elements[i].data.addr;
4132             if (stream_info->elements[i].data.buffer_object)
4133             {
4134                 ptr += (ULONG_PTR)buffer_get_sysmem(stream->buffer, gl_info);
4135             }
4136
4137             if (context->numbered_array_mask & (1 << i)) unload_numbered_array(context, i);
4138
4139             switch (stream_info->elements[i].format->id)
4140             {
4141                 case WINED3DFMT_R32_FLOAT:
4142                     GL_EXTCALL(glVertexAttrib1fvARB(i, (const GLfloat *)ptr));
4143                     break;
4144                 case WINED3DFMT_R32G32_FLOAT:
4145                     GL_EXTCALL(glVertexAttrib2fvARB(i, (const GLfloat *)ptr));
4146                     break;
4147                 case WINED3DFMT_R32G32B32_FLOAT:
4148                     GL_EXTCALL(glVertexAttrib3fvARB(i, (const GLfloat *)ptr));
4149                     break;
4150                 case WINED3DFMT_R32G32B32A32_FLOAT:
4151                     GL_EXTCALL(glVertexAttrib4fvARB(i, (const GLfloat *)ptr));
4152                     break;
4153
4154                 case WINED3DFMT_R8G8B8A8_UINT:
4155                     GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
4156                     break;
4157                 case WINED3DFMT_B8G8R8A8_UNORM:
4158                     if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
4159                     {
4160                         const DWORD *src = (const DWORD *)ptr;
4161                         DWORD c = *src & 0xff00ff00;
4162                         c |= (*src & 0xff0000) >> 16;
4163                         c |= (*src & 0xff) << 16;
4164                         GL_EXTCALL(glVertexAttrib4NubvARB(i, (GLubyte *)&c));
4165                         break;
4166                     }
4167                     /* else fallthrough */
4168                 case WINED3DFMT_R8G8B8A8_UNORM:
4169                     GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
4170                     break;
4171
4172                 case WINED3DFMT_R16G16_SINT:
4173                     GL_EXTCALL(glVertexAttrib4svARB(i, (const GLshort *)ptr));
4174                     break;
4175                 case WINED3DFMT_R16G16B16A16_SINT:
4176                     GL_EXTCALL(glVertexAttrib4svARB(i, (const GLshort *)ptr));
4177                     break;
4178
4179                 case WINED3DFMT_R16G16_SNORM:
4180                 {
4181                     const GLshort s[4] = {((const GLshort *)ptr)[0], ((const GLshort *)ptr)[1], 0, 1};
4182                     GL_EXTCALL(glVertexAttrib4NsvARB(i, s));
4183                     break;
4184                 }
4185                 case WINED3DFMT_R16G16_UNORM:
4186                 {
4187                     const GLushort s[4] = {((const GLushort *)ptr)[0], ((const GLushort *)ptr)[1], 0, 1};
4188                     GL_EXTCALL(glVertexAttrib4NusvARB(i, s));
4189                     break;
4190                 }
4191                 case WINED3DFMT_R16G16B16A16_SNORM:
4192                     GL_EXTCALL(glVertexAttrib4NsvARB(i, (const GLshort *)ptr));
4193                     break;
4194                 case WINED3DFMT_R16G16B16A16_UNORM:
4195                     GL_EXTCALL(glVertexAttrib4NusvARB(i, (const GLushort *)ptr));
4196                     break;
4197
4198                 case WINED3DFMT_R10G10B10A2_UINT:
4199                     FIXME("Unsure about WINED3DDECLTYPE_UDEC3\n");
4200                     /*glVertexAttrib3usvARB(i, (const GLushort *)ptr); Does not exist */
4201                     break;
4202                 case WINED3DFMT_R10G10B10A2_SNORM:
4203                     FIXME("Unsure about WINED3DDECLTYPE_DEC3N\n");
4204                     /*glVertexAttrib3NusvARB(i, (const GLushort *)ptr); Does not exist */
4205                     break;
4206
4207                 case WINED3DFMT_R16G16_FLOAT:
4208                     /* Are those 16 bit floats. C doesn't have a 16 bit float type. I could read the single bits and calculate a 4
4209                      * byte float according to the IEEE standard
4210                      */
4211                     FIXME("Unsupported WINED3DDECLTYPE_FLOAT16_2\n");
4212                     break;
4213                 case WINED3DFMT_R16G16B16A16_FLOAT:
4214                     FIXME("Unsupported WINED3DDECLTYPE_FLOAT16_4\n");
4215                     break;
4216
4217                 default:
4218                     ERR("Unexpected declaration in stride 0 attributes\n");
4219                     break;
4220
4221             }
4222         }
4223     }
4224     checkGLcall("Loading numbered arrays");
4225 }
4226
4227 static void load_vertex_data(const struct wined3d_context *context,
4228         const struct wined3d_stream_info *si, const struct wined3d_state *state)
4229 {
4230     struct wined3d_device *device = context->swapchain->device;
4231     const struct wined3d_gl_info *gl_info = context->gl_info;
4232     GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
4233     const struct wined3d_stream_info_element *e;
4234
4235     TRACE("Using fast vertex array code\n");
4236
4237     /* This is fixed function pipeline only, and the fixed function pipeline doesn't do instancing */
4238     device->instancedDraw = FALSE;
4239
4240     /* Blend Data ---------------------------------------------- */
4241     if ((si->use_map & (1 << WINED3D_FFP_BLENDWEIGHT))
4242             || si->use_map & (1 << WINED3D_FFP_BLENDINDICES))
4243     {
4244         e = &si->elements[WINED3D_FFP_BLENDWEIGHT];
4245
4246         if (gl_info->supported[ARB_VERTEX_BLEND])
4247         {
4248             TRACE("Blend %u %p %u\n", e->format->component_count,
4249                     e->data.addr + state->load_base_vertex_index * e->stride, e->stride);
4250
4251             glEnableClientState(GL_WEIGHT_ARRAY_ARB);
4252             checkGLcall("glEnableClientState(GL_WEIGHT_ARRAY_ARB)");
4253
4254             GL_EXTCALL(glVertexBlendARB(e->format->component_count + 1));
4255
4256             if (curVBO != e->data.buffer_object)
4257             {
4258                 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4259                 checkGLcall("glBindBufferARB");
4260                 curVBO = e->data.buffer_object;
4261             }
4262
4263             TRACE("glWeightPointerARB(%#x, %#x, %#x, %p);\n",
4264                     e->format->gl_vtx_format,
4265                     e->format->gl_vtx_type,
4266                     e->stride,
4267                     e->data.addr + state->load_base_vertex_index * e->stride);
4268             GL_EXTCALL(glWeightPointerARB(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4269                     e->data.addr + state->load_base_vertex_index * e->stride));
4270
4271             checkGLcall("glWeightPointerARB");
4272
4273             if (si->use_map & (1 << WINED3D_FFP_BLENDINDICES))
4274             {
4275                 static BOOL warned;
4276                 if (!warned)
4277                 {
4278                     FIXME("blendMatrixIndices support\n");
4279                     warned = TRUE;
4280                 }
4281             }
4282         } else {
4283             /* TODO: support blends in drawStridedSlow
4284              * No need to write a FIXME here, this is done after the general vertex decl decoding
4285              */
4286             WARN("unsupported blending in openGl\n");
4287         }
4288     }
4289     else
4290     {
4291         if (gl_info->supported[ARB_VERTEX_BLEND])
4292         {
4293             static const GLbyte one = 1;
4294             GL_EXTCALL(glWeightbvARB(1, &one));
4295             checkGLcall("glWeightbvARB(gl_info->max_blends, weights)");
4296         }
4297     }
4298
4299     /* Point Size ----------------------------------------------*/
4300     if (si->use_map & (1 << WINED3D_FFP_PSIZE))
4301     {
4302         /* no such functionality in the fixed function GL pipeline */
4303         TRACE("Cannot change ptSize here in openGl\n");
4304         /* TODO: Implement this function in using shaders if they are available */
4305     }
4306
4307     /* Vertex Pointers -----------------------------------------*/
4308     if (si->use_map & (1 << WINED3D_FFP_POSITION))
4309     {
4310         e = &si->elements[WINED3D_FFP_POSITION];
4311
4312         if (curVBO != e->data.buffer_object)
4313         {
4314             GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4315             checkGLcall("glBindBufferARB");
4316             curVBO = e->data.buffer_object;
4317         }
4318
4319         TRACE("glVertexPointer(%#x, %#x, %#x, %p);\n",
4320                 e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4321                 e->data.addr + state->load_base_vertex_index * e->stride);
4322         glVertexPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4323                 e->data.addr + state->load_base_vertex_index * e->stride);
4324         checkGLcall("glVertexPointer(...)");
4325         glEnableClientState(GL_VERTEX_ARRAY);
4326         checkGLcall("glEnableClientState(GL_VERTEX_ARRAY)");
4327     }
4328
4329     /* Normals -------------------------------------------------*/
4330     if (si->use_map & (1 << WINED3D_FFP_NORMAL))
4331     {
4332         e = &si->elements[WINED3D_FFP_NORMAL];
4333
4334         if (curVBO != e->data.buffer_object)
4335         {
4336             GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4337             checkGLcall("glBindBufferARB");
4338             curVBO = e->data.buffer_object;
4339         }
4340
4341         TRACE("glNormalPointer(%#x, %#x, %p);\n", e->format->gl_vtx_type, e->stride,
4342                 e->data.addr + state->load_base_vertex_index * e->stride);
4343         glNormalPointer(e->format->gl_vtx_type, e->stride,
4344                 e->data.addr + state->load_base_vertex_index * e->stride);
4345         checkGLcall("glNormalPointer(...)");
4346         glEnableClientState(GL_NORMAL_ARRAY);
4347         checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)");
4348
4349     } else {
4350         glNormal3f(0, 0, 0);
4351         checkGLcall("glNormal3f(0, 0, 0)");
4352     }
4353
4354     /* Diffuse Colour --------------------------------------------*/
4355     if (si->use_map & (1 << WINED3D_FFP_DIFFUSE))
4356     {
4357         e = &si->elements[WINED3D_FFP_DIFFUSE];
4358
4359         if (curVBO != e->data.buffer_object)
4360         {
4361             GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4362             checkGLcall("glBindBufferARB");
4363             curVBO = e->data.buffer_object;
4364         }
4365
4366         TRACE("glColorPointer(%#x, %#x %#x, %p);\n",
4367                 e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4368                 e->data.addr + state->load_base_vertex_index * e->stride);
4369         glColorPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4370                 e->data.addr + state->load_base_vertex_index * e->stride);
4371         checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)");
4372         glEnableClientState(GL_COLOR_ARRAY);
4373         checkGLcall("glEnableClientState(GL_COLOR_ARRAY)");
4374
4375     } else {
4376         glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
4377         checkGLcall("glColor4f(1, 1, 1, 1)");
4378     }
4379
4380     /* Specular Colour ------------------------------------------*/
4381     if (si->use_map & (1 << WINED3D_FFP_SPECULAR))
4382     {
4383         TRACE("setting specular colour\n");
4384
4385         e = &si->elements[WINED3D_FFP_SPECULAR];
4386
4387         if (gl_info->supported[EXT_SECONDARY_COLOR])
4388         {
4389             GLenum type = e->format->gl_vtx_type;
4390             GLint format = e->format->gl_vtx_format;
4391
4392             if (curVBO != e->data.buffer_object)
4393             {
4394                 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4395                 checkGLcall("glBindBufferARB");
4396                 curVBO = e->data.buffer_object;
4397             }
4398
4399             if (format != 4 || (gl_info->quirks & WINED3D_QUIRK_ALLOWS_SPECULAR_ALPHA))
4400             {
4401                 /* Usually specular colors only allow 3 components, since they have no alpha. In D3D, the specular alpha
4402                  * contains the fog coordinate, which is passed to GL with GL_EXT_fog_coord. However, the fixed function
4403                  * vertex pipeline can pass the specular alpha through, and pixel shaders can read it. So it GL accepts
4404                  * 4 component secondary colors use it
4405                  */
4406                 TRACE("glSecondaryColorPointer(%#x, %#x, %#x, %p);\n", format, type, e->stride,
4407                         e->data.addr + state->load_base_vertex_index * e->stride);
4408                 GL_EXTCALL(glSecondaryColorPointerEXT(format, type, e->stride,
4409                         e->data.addr + state->load_base_vertex_index * e->stride));
4410                 checkGLcall("glSecondaryColorPointerEXT(format, type, ...)");
4411             }
4412             else
4413             {
4414                 switch(type)
4415                 {
4416                     case GL_UNSIGNED_BYTE:
4417                         TRACE("glSecondaryColorPointer(3, GL_UNSIGNED_BYTE, %#x, %p);\n", e->stride,
4418                                 e->data.addr + state->load_base_vertex_index * e->stride);
4419                         GL_EXTCALL(glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, e->stride,
4420                                 e->data.addr + state->load_base_vertex_index * e->stride));
4421                         checkGLcall("glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, ...)");
4422                         break;
4423
4424                     default:
4425                         FIXME("Add 4 component specular color pointers for type %x\n", type);
4426                         /* Make sure that the right color component is dropped */
4427                         TRACE("glSecondaryColorPointer(3, %#x, %#x, %p);\n", type, e->stride,
4428                                 e->data.addr + state->load_base_vertex_index * e->stride);
4429                         GL_EXTCALL(glSecondaryColorPointerEXT(3, type, e->stride,
4430                                 e->data.addr + state->load_base_vertex_index * e->stride));
4431                         checkGLcall("glSecondaryColorPointerEXT(3, type, ...)");
4432                 }
4433             }
4434             glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
4435             checkGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
4436         }
4437         else
4438         {
4439             WARN("Specular colour is not supported in this GL implementation.\n");
4440         }
4441     }
4442     else
4443     {
4444         if (gl_info->supported[EXT_SECONDARY_COLOR])
4445         {
4446             GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0);
4447             checkGLcall("glSecondaryColor3fEXT(0, 0, 0)");
4448         }
4449         else
4450         {
4451             WARN("Specular colour is not supported in this GL implementation.\n");
4452         }
4453     }
4454
4455     /* Texture coords -------------------------------------------*/
4456     load_tex_coords(context, si, &curVBO, state);
4457 }
4458
4459 static void streamsrc(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4460 {
4461     const struct wined3d_device *device = context->swapchain->device;
4462     BOOL load_numbered = use_vs(state) && !device->useDrawStridedSlow;
4463     BOOL load_named = !use_vs(state) && !device->useDrawStridedSlow;
4464
4465     if (isStateDirty(context, STATE_VDECL)) return;
4466     if (context->numberedArraysLoaded && !load_numbered)
4467     {
4468         unload_numbered_arrays(context);
4469         context->numberedArraysLoaded = FALSE;
4470         context->numbered_array_mask = 0;
4471     }
4472     else if (context->namedArraysLoaded)
4473     {
4474         unload_vertex_data(context->gl_info);
4475         context->namedArraysLoaded = FALSE;
4476     }
4477
4478     if (load_numbered)
4479     {
4480         TRACE("Loading numbered arrays\n");
4481         load_numbered_arrays(context, &device->strided_streams, state);
4482         context->numberedArraysLoaded = TRUE;
4483     }
4484     else if (load_named)
4485     {
4486         TRACE("Loading vertex data\n");
4487         load_vertex_data(context, &device->strided_streams, state);
4488         context->namedArraysLoaded = TRUE;
4489     }
4490 }
4491
4492 static void vdecl_miscpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4493 {
4494     if (isStateDirty(context, STATE_STREAMSRC))
4495         return;
4496     streamsrc(context, state, STATE_STREAMSRC);
4497 }
4498
4499 static void vertexdeclaration(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4500 {
4501     const struct wined3d_device *device = context->swapchain->device;
4502     const struct wined3d_gl_info *gl_info = context->gl_info;
4503     BOOL useVertexShaderFunction = use_vs(state);
4504     BOOL usePixelShaderFunction = use_ps(state);
4505     BOOL updateFog = FALSE;
4506     BOOL transformed;
4507     BOOL wasrhw = context->last_was_rhw;
4508     unsigned int i;
4509
4510     transformed = device->strided_streams.position_transformed;
4511     if (transformed != context->last_was_rhw && !useVertexShaderFunction)
4512         updateFog = TRUE;
4513
4514     context->last_was_rhw = transformed;
4515
4516     /* Don't have to apply the matrices when vertex shaders are used. When
4517      * vshaders are turned off this function will be called again anyway to
4518      * make sure they're properly set. */
4519     if (!useVertexShaderFunction)
4520     {
4521         /* TODO: Move this mainly to the viewport state and only apply when
4522          * the vp has changed or transformed / untransformed was switched. */
4523         if (wasrhw != context->last_was_rhw
4524                 && !isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION))
4525                 && !isStateDirty(context, STATE_VIEWPORT))
4526             transform_projection(context, state, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
4527         /* World matrix needs reapplication here only if we're switching between rhw and non-rhw
4528          * mode.
4529          *
4530          * If a vertex shader is used, the world matrix changed and then vertex shader unbound
4531          * this check will fail and the matrix not applied again. This is OK because a simple
4532          * world matrix change reapplies the matrix - These checks here are only to satisfy the
4533          * needs of the vertex declaration.
4534          *
4535          * World and view matrix go into the same gl matrix, so only apply them when neither is
4536          * dirty
4537          */
4538         if (transformed != wasrhw && !isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)))
4539                 && !isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_VIEW)))
4540             transform_world(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)));
4541         if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_COLORVERTEX)))
4542             state_colormat(context, state, STATE_RENDER(WINED3D_RS_COLORVERTEX));
4543         if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_LIGHTING)))
4544             state_lighting(context, state, STATE_RENDER(WINED3D_RS_LIGHTING));
4545
4546         if (context->last_was_vshader)
4547         {
4548             updateFog = TRUE;
4549
4550             if (!device->vs_clipping && !isStateDirty(context, STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE)))
4551                 state_clipping(context, state, STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE));
4552
4553             for (i = 0; i < gl_info->limits.clipplanes; ++i)
4554             {
4555                 clipplane(context, state, STATE_CLIPPLANE(i));
4556             }
4557         }
4558         if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_NORMALIZENORMALS)))
4559             state_normalize(context, state, STATE_RENDER(WINED3D_RS_NORMALIZENORMALS));
4560     }
4561     else
4562     {
4563         if(!context->last_was_vshader) {
4564             static BOOL warned = FALSE;
4565             if(!device->vs_clipping) {
4566                 /* Disable all clip planes to get defined results on all drivers. See comment in the
4567                  * state_clipping state handler
4568                  */
4569                 for (i = 0; i < gl_info->limits.clipplanes; ++i)
4570                 {
4571                     glDisable(GL_CLIP_PLANE0 + i);
4572                     checkGLcall("glDisable(GL_CLIP_PLANE0 + i)");
4573                 }
4574
4575                 if (!warned && state->render_states[WINED3D_RS_CLIPPLANEENABLE])
4576                 {
4577                     FIXME("Clipping not supported with vertex shaders\n");
4578                     warned = TRUE;
4579                 }
4580             }
4581             if (wasrhw)
4582             {
4583                 /* Apply the transform matrices when switching from rhw
4584                  * drawing to vertex shaders. Vertex shaders themselves do
4585                  * not need it, but the matrices are not reapplied
4586                  * automatically when switching back from vertex shaders to
4587                  * fixed function processing. So make sure we leave the fixed
4588                  * function vertex processing states back in a sane state
4589                  * before switching to shaders. */
4590                 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION)))
4591                     transform_projection(context, state, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
4592                 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0))))
4593                     transform_world(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)));
4594             }
4595             updateFog = TRUE;
4596
4597             /* Vertex shader clipping ignores the view matrix. Update all clipplanes
4598              * (Note: ARB shaders can read the clip planes for clipping emulation even if
4599              * device->vs_clipping is false.
4600              */
4601             for (i = 0; i < gl_info->limits.clipplanes; ++i)
4602             {
4603                 clipplane(context, state, STATE_CLIPPLANE(i));
4604             }
4605         }
4606     }
4607
4608     /* Vertex and pixel shaders are applied together, so let the last dirty
4609      * state do the application. */
4610     if (!isStateDirty(context, STATE_PIXELSHADER))
4611     {
4612         device->shader_backend->shader_select(context, usePixelShaderFunction, useVertexShaderFunction);
4613
4614         if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT)
4615                 && (useVertexShaderFunction || usePixelShaderFunction))
4616             shaderconstant(context, state, STATE_VERTEXSHADERCONSTANT);
4617     }
4618
4619     context->last_was_vshader = useVertexShaderFunction;
4620
4621     if (updateFog)
4622         context_apply_state(context, state, STATE_RENDER(WINED3D_RS_FOGVERTEXMODE));
4623
4624     if (!useVertexShaderFunction)
4625     {
4626         unsigned int i;
4627
4628         for (i = 0; i < MAX_TEXTURES; ++i)
4629         {
4630             if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + i)))
4631                 transform_texture(context, state, STATE_TEXTURESTAGE(i, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS));
4632         }
4633     }
4634
4635     if (transformed != wasrhw && !isStateDirty(context, STATE_RENDER(WINED3D_RS_ZENABLE)))
4636         state_zenable(context, state, STATE_RENDER(WINED3D_RS_ZENABLE));
4637 }
4638
4639 static void viewport_miscpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4640 {
4641     const struct wined3d_surface *target = state->fb->render_targets[0];
4642     struct wined3d_viewport vp = state->viewport;
4643
4644     if (vp.width > target->resource.width)
4645         vp.width = target->resource.width;
4646     if (vp.height > target->resource.height)
4647         vp.height = target->resource.height;
4648
4649     glDepthRange(vp.min_z, vp.max_z);
4650     checkGLcall("glDepthRange");
4651     /* Note: GL requires lower left, DirectX supplies upper left. This is
4652      * reversed when using offscreen rendering. */
4653     if (context->render_offscreen)
4654     {
4655         glViewport(vp.x, vp.y, vp.width, vp.height);
4656     }
4657     else
4658     {
4659         UINT width, height;
4660
4661         target->get_drawable_size(context, &width, &height);
4662         glViewport(vp.x, (height - (vp.y + vp.height)),
4663                 vp.width, vp.height);
4664     }
4665
4666     checkGLcall("glViewport");
4667 }
4668
4669 static void viewport_vertexpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4670 {
4671     if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION)))
4672         transform_projection(context, state, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
4673     if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_POINTSCALEENABLE)))
4674         state_pscale(context, state, STATE_RENDER(WINED3D_RS_POINTSCALEENABLE));
4675     /* Update the position fixup. */
4676     if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT))
4677         shaderconstant(context, state, STATE_VERTEXSHADERCONSTANT);
4678 }
4679
4680 static void light(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4681 {
4682     UINT Index = state_id - STATE_ACTIVELIGHT(0);
4683     const struct wined3d_light_info *lightInfo = state->lights[Index];
4684
4685     if (!lightInfo)
4686     {
4687         glDisable(GL_LIGHT0 + Index);
4688         checkGLcall("glDisable(GL_LIGHT0 + Index)");
4689     }
4690     else
4691     {
4692         float quad_att;
4693         float colRGBA[] = {0.0f, 0.0f, 0.0f, 0.0f};
4694
4695         /* Light settings are affected by the model view in OpenGL, the View transform in direct3d*/
4696         glMatrixMode(GL_MODELVIEW);
4697         glPushMatrix();
4698         glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
4699
4700         /* Diffuse: */
4701         colRGBA[0] = lightInfo->OriginalParms.diffuse.r;
4702         colRGBA[1] = lightInfo->OriginalParms.diffuse.g;
4703         colRGBA[2] = lightInfo->OriginalParms.diffuse.b;
4704         colRGBA[3] = lightInfo->OriginalParms.diffuse.a;
4705         glLightfv(GL_LIGHT0 + Index, GL_DIFFUSE, colRGBA);
4706         checkGLcall("glLightfv");
4707
4708         /* Specular */
4709         colRGBA[0] = lightInfo->OriginalParms.specular.r;
4710         colRGBA[1] = lightInfo->OriginalParms.specular.g;
4711         colRGBA[2] = lightInfo->OriginalParms.specular.b;
4712         colRGBA[3] = lightInfo->OriginalParms.specular.a;
4713         glLightfv(GL_LIGHT0 + Index, GL_SPECULAR, colRGBA);
4714         checkGLcall("glLightfv");
4715
4716         /* Ambient */
4717         colRGBA[0] = lightInfo->OriginalParms.ambient.r;
4718         colRGBA[1] = lightInfo->OriginalParms.ambient.g;
4719         colRGBA[2] = lightInfo->OriginalParms.ambient.b;
4720         colRGBA[3] = lightInfo->OriginalParms.ambient.a;
4721         glLightfv(GL_LIGHT0 + Index, GL_AMBIENT, colRGBA);
4722         checkGLcall("glLightfv");
4723
4724         if ((lightInfo->OriginalParms.range * lightInfo->OriginalParms.range) >= FLT_MIN)
4725             quad_att = 1.4f / (lightInfo->OriginalParms.range * lightInfo->OriginalParms.range);
4726         else
4727             quad_att = 0.0f; /*  0 or  MAX?  (0 seems to be ok) */
4728
4729         /* Do not assign attenuation values for lights that do not use them. D3D apps are free to pass any junk,
4730          * but gl drivers use them and may crash due to bad Attenuation values. Need for Speed most wanted sets
4731          * Attenuation0 to NaN and crashes in the gl lib
4732          */
4733
4734         switch (lightInfo->OriginalParms.type)
4735         {
4736             case WINED3D_LIGHT_POINT:
4737                 /* Position */
4738                 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
4739                 checkGLcall("glLightfv");
4740                 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
4741                 checkGLcall("glLightf");
4742                 /* Attenuation - Are these right? guessing... */
4743                 glLightf(GL_LIGHT0 + Index, GL_CONSTANT_ATTENUATION, lightInfo->OriginalParms.attenuation0);
4744                 checkGLcall("glLightf");
4745                 glLightf(GL_LIGHT0 + Index, GL_LINEAR_ATTENUATION, lightInfo->OriginalParms.attenuation1);
4746                 checkGLcall("glLightf");
4747                 if (quad_att < lightInfo->OriginalParms.attenuation2)
4748                     quad_att = lightInfo->OriginalParms.attenuation2;
4749                 glLightf(GL_LIGHT0 + Index, GL_QUADRATIC_ATTENUATION, quad_att);
4750                 checkGLcall("glLightf");
4751                 /* FIXME: Range */
4752                 break;
4753
4754             case WINED3D_LIGHT_SPOT:
4755                 /* Position */
4756                 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
4757                 checkGLcall("glLightfv");
4758                 /* Direction */
4759                 glLightfv(GL_LIGHT0 + Index, GL_SPOT_DIRECTION, &lightInfo->lightDirn[0]);
4760                 checkGLcall("glLightfv");
4761                 glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, lightInfo->exponent);
4762                 checkGLcall("glLightf");
4763                 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
4764                 checkGLcall("glLightf");
4765                 /* Attenuation - Are these right? guessing... */
4766                 glLightf(GL_LIGHT0 + Index, GL_CONSTANT_ATTENUATION, lightInfo->OriginalParms.attenuation0);
4767                 checkGLcall("glLightf");
4768                 glLightf(GL_LIGHT0 + Index, GL_LINEAR_ATTENUATION, lightInfo->OriginalParms.attenuation1);
4769                 checkGLcall("glLightf");
4770                 if (quad_att < lightInfo->OriginalParms.attenuation2)
4771                     quad_att = lightInfo->OriginalParms.attenuation2;
4772                 glLightf(GL_LIGHT0 + Index, GL_QUADRATIC_ATTENUATION, quad_att);
4773                 checkGLcall("glLightf");
4774                 /* FIXME: Range */
4775                 break;
4776
4777             case WINED3D_LIGHT_DIRECTIONAL:
4778                 /* Direction */
4779                 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]); /* Note gl uses w position of 0 for direction! */
4780                 checkGLcall("glLightfv");
4781                 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
4782                 checkGLcall("glLightf");
4783                 glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, 0.0f);
4784                 checkGLcall("glLightf");
4785                 break;
4786
4787             default:
4788                 FIXME("Unrecognized light type %#x.\n", lightInfo->OriginalParms.type);
4789         }
4790
4791         /* Restore the modelview matrix */
4792         glPopMatrix();
4793
4794         glEnable(GL_LIGHT0 + Index);
4795         checkGLcall("glEnable(GL_LIGHT0 + Index)");
4796     }
4797 }
4798
4799 static void scissorrect(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4800 {
4801     const RECT *r = &state->scissor_rect;
4802
4803     /* Warning: glScissor uses window coordinates, not viewport coordinates,
4804      * so our viewport correction does not apply. Warning2: Even in windowed
4805      * mode the coords are relative to the window, not the screen. */
4806     TRACE("Setting new scissor rect to %s.\n", wine_dbgstr_rect(r));
4807
4808     if (context->render_offscreen)
4809     {
4810         glScissor(r->left, r->top, r->right - r->left, r->bottom - r->top);
4811     }
4812     else
4813     {
4814         const struct wined3d_surface *target = state->fb->render_targets[0];
4815         UINT height;
4816         UINT width;
4817
4818         target->get_drawable_size(context, &width, &height);
4819         glScissor(r->left, height - r->bottom, r->right - r->left, r->bottom - r->top);
4820     }
4821     checkGLcall("glScissor");
4822 }
4823
4824 static void indexbuffer(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4825 {
4826     const struct wined3d_stream_info *stream_info = &context->swapchain->device->strided_streams;
4827     const struct wined3d_gl_info *gl_info = context->gl_info;
4828
4829     if (state->user_stream || !state->index_buffer || !stream_info->all_vbo)
4830     {
4831         GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0));
4832     }
4833     else
4834     {
4835         struct wined3d_buffer *ib = state->index_buffer;
4836         GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, ib->buffer_object));
4837     }
4838 }
4839
4840 static void frontface(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4841 {
4842     if (context->render_offscreen)
4843     {
4844         glFrontFace(GL_CCW);
4845         checkGLcall("glFrontFace(GL_CCW)");
4846     } else {
4847         glFrontFace(GL_CW);
4848         checkGLcall("glFrontFace(GL_CW)");
4849     }
4850 }
4851
4852 static void psorigin_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4853 {
4854     static BOOL warned;
4855
4856     if (!warned)
4857     {
4858         WARN("Point sprite coordinate origin switching not supported.\n");
4859         warned = TRUE;
4860     }
4861 }
4862
4863 static void psorigin(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4864 {
4865     const struct wined3d_gl_info *gl_info = context->gl_info;
4866     GLint origin = context->render_offscreen ? GL_LOWER_LEFT : GL_UPPER_LEFT;
4867
4868     if (glPointParameteri)
4869     {
4870         glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, origin);
4871         checkGLcall("glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, ...)");
4872     }
4873     else if (gl_info->supported[NV_POINT_SPRITE])
4874     {
4875         GL_EXTCALL(glPointParameteriNV(GL_POINT_SPRITE_COORD_ORIGIN, origin));
4876         checkGLcall("glPointParameteriNV(GL_POINT_SPRITE_COORD_ORIGIN, ...)");
4877     }
4878 }
4879
4880 const struct StateEntryTemplate misc_state_template[] = {
4881     { STATE_RENDER(WINED3D_RS_SRCBLEND),                  { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
4882     { STATE_RENDER(WINED3D_RS_DESTBLEND),                 { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
4883     { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE),          { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE),          state_blend         }, WINED3D_GL_EXT_NONE             },
4884     { STATE_RENDER(WINED3D_RS_EDGEANTIALIAS),             { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
4885     { STATE_RENDER(WINED3D_RS_ANTIALIASEDLINEENABLE),     { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
4886     { STATE_RENDER(WINED3D_RS_SEPARATEALPHABLENDENABLE),  { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
4887     { STATE_RENDER(WINED3D_RS_SRCBLENDALPHA),             { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
4888     { STATE_RENDER(WINED3D_RS_DESTBLENDALPHA),            { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
4889     { STATE_RENDER(WINED3D_RS_DESTBLENDALPHA),            { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
4890     { STATE_RENDER(WINED3D_RS_BLENDOPALPHA),              { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
4891     { STATE_STREAMSRC,                                    { STATE_STREAMSRC,                                    streamsrc           }, WINED3D_GL_EXT_NONE             },
4892     { STATE_VDECL,                                        { STATE_VDECL,                                        vdecl_miscpart      }, WINED3D_GL_EXT_NONE             },
4893     { STATE_FRONTFACE,                                    { STATE_FRONTFACE,                                    frontface           }, WINED3D_GL_EXT_NONE             },
4894     { STATE_SCISSORRECT,                                  { STATE_SCISSORRECT,                                  scissorrect         }, WINED3D_GL_EXT_NONE             },
4895     { STATE_POINTSPRITECOORDORIGIN,                       { STATE_POINTSPRITECOORDORIGIN,                       psorigin            }, WINED3D_GL_VERSION_2_0          },
4896     { STATE_POINTSPRITECOORDORIGIN,                       { STATE_POINTSPRITECOORDORIGIN,                       psorigin_w          }, WINED3D_GL_EXT_NONE             },
4897
4898     /* TODO: Move shader constant loading to vertex and fragment pipeline respectively, as soon as the pshader and
4899      * vshader loadings are untied from each other
4900      */
4901     { STATE_VERTEXSHADERCONSTANT,                         { STATE_VERTEXSHADERCONSTANT,                         shaderconstant      }, WINED3D_GL_EXT_NONE             },
4902     { STATE_PIXELSHADERCONSTANT,                          { STATE_VERTEXSHADERCONSTANT,                         NULL                }, WINED3D_GL_EXT_NONE             },
4903     { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00),   { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00),   shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
4904     { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT01),   { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
4905     { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT10),   { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
4906     { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT11),   { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
4907     { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00),   { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00),   shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
4908     { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT01),   { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
4909     { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT10),   { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
4910     { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT11),   { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
4911     { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00),   { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00),   shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
4912     { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT01),   { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
4913     { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT10),   { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
4914     { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT11),   { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
4915     { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00),   { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00),   shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
4916     { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT01),   { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
4917     { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT10),   { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
4918     { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT11),   { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
4919     { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00),   { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00),   shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
4920     { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT01),   { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
4921     { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT10),   { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
4922     { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT11),   { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
4923     { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00),   { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00),   shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
4924     { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT01),   { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
4925     { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT10),   { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
4926     { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT11),   { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
4927     { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00),   { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00),   shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
4928     { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT01),   { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
4929     { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT10),   { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
4930     { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT11),   { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
4931     { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00),   { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00),   shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
4932     { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT01),   { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
4933     { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT10),   { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
4934     { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT11),   { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
4935     { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE),  { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE),  tex_bumpenvlscale   }, WINED3D_GL_EXT_NONE             },
4936     { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE),  NULL                }, WINED3D_GL_EXT_NONE             },
4937     { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE),  { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE),  tex_bumpenvlscale   }, WINED3D_GL_EXT_NONE             },
4938     { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE),  NULL                }, WINED3D_GL_EXT_NONE             },
4939     { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE),  { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE),  tex_bumpenvlscale   }, WINED3D_GL_EXT_NONE             },
4940     { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE),  NULL                }, WINED3D_GL_EXT_NONE             },
4941     { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE),  { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE),  tex_bumpenvlscale   }, WINED3D_GL_EXT_NONE             },
4942     { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE),  NULL                }, WINED3D_GL_EXT_NONE             },
4943     { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE),  { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE),  tex_bumpenvlscale   }, WINED3D_GL_EXT_NONE             },
4944     { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE),  NULL                }, WINED3D_GL_EXT_NONE             },
4945     { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE),  { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE),  tex_bumpenvlscale   }, WINED3D_GL_EXT_NONE             },
4946     { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE),  NULL                }, WINED3D_GL_EXT_NONE             },
4947     { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE),  { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE),  tex_bumpenvlscale   }, WINED3D_GL_EXT_NONE             },
4948     { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE),  NULL                }, WINED3D_GL_EXT_NONE             },
4949     { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE),  { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE),  tex_bumpenvlscale   }, WINED3D_GL_EXT_NONE             },
4950     { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE),  NULL                }, WINED3D_GL_EXT_NONE             },
4951
4952     { STATE_VIEWPORT,                                     { STATE_VIEWPORT,                                     viewport_miscpart   }, WINED3D_GL_EXT_NONE             },
4953     { STATE_INDEXBUFFER,                                  { STATE_INDEXBUFFER,                                  indexbuffer         }, ARB_VERTEX_BUFFER_OBJECT        },
4954     { STATE_INDEXBUFFER,                                  { STATE_INDEXBUFFER,                                  state_nop           }, WINED3D_GL_EXT_NONE             },
4955     { STATE_RENDER(WINED3D_RS_ANTIALIAS),                 { STATE_RENDER(WINED3D_RS_ANTIALIAS),                 state_antialias     }, WINED3D_GL_EXT_NONE             },
4956     { STATE_RENDER(WINED3D_RS_TEXTUREPERSPECTIVE),        { STATE_RENDER(WINED3D_RS_TEXTUREPERSPECTIVE),        state_perspective   }, WINED3D_GL_EXT_NONE             },
4957     { STATE_RENDER(WINED3D_RS_ZENABLE),                   { STATE_RENDER(WINED3D_RS_ZENABLE),                   state_zenable       }, WINED3D_GL_EXT_NONE             },
4958     { STATE_RENDER(WINED3D_RS_WRAPU),                     { STATE_RENDER(WINED3D_RS_WRAPU),                     state_wrapu         }, WINED3D_GL_EXT_NONE             },
4959     { STATE_RENDER(WINED3D_RS_WRAPV),                     { STATE_RENDER(WINED3D_RS_WRAPV),                     state_wrapv         }, WINED3D_GL_EXT_NONE             },
4960     { STATE_RENDER(WINED3D_RS_FILLMODE),                  { STATE_RENDER(WINED3D_RS_FILLMODE),                  state_fillmode      }, WINED3D_GL_EXT_NONE             },
4961     { STATE_RENDER(WINED3D_RS_SHADEMODE),                 { STATE_RENDER(WINED3D_RS_SHADEMODE),                 state_shademode     }, WINED3D_GL_EXT_NONE             },
4962     { STATE_RENDER(WINED3D_RS_LINEPATTERN),               { STATE_RENDER(WINED3D_RS_LINEPATTERN),               state_linepattern   }, WINED3D_GL_EXT_NONE             },
4963     { STATE_RENDER(WINED3D_RS_MONOENABLE),                { STATE_RENDER(WINED3D_RS_MONOENABLE),                state_monoenable    }, WINED3D_GL_EXT_NONE             },
4964     { STATE_RENDER(WINED3D_RS_ROP2),                      { STATE_RENDER(WINED3D_RS_ROP2),                      state_rop2          }, WINED3D_GL_EXT_NONE             },
4965     { STATE_RENDER(WINED3D_RS_PLANEMASK),                 { STATE_RENDER(WINED3D_RS_PLANEMASK),                 state_planemask     }, WINED3D_GL_EXT_NONE             },
4966     { STATE_RENDER(WINED3D_RS_ZWRITEENABLE),              { STATE_RENDER(WINED3D_RS_ZWRITEENABLE),              state_zwritenable   }, WINED3D_GL_EXT_NONE             },
4967     { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE),           { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE),           state_alpha         }, WINED3D_GL_EXT_NONE             },
4968     { STATE_RENDER(WINED3D_RS_ALPHAREF),                  { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE),           NULL                }, WINED3D_GL_EXT_NONE             },
4969     { STATE_RENDER(WINED3D_RS_ALPHAFUNC),                 { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE),           NULL                }, WINED3D_GL_EXT_NONE             },
4970     { STATE_RENDER(WINED3D_RS_COLORKEYENABLE),            { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE),           NULL                }, WINED3D_GL_EXT_NONE             },
4971     { STATE_RENDER(WINED3D_RS_LASTPIXEL),                 { STATE_RENDER(WINED3D_RS_LASTPIXEL),                 state_lastpixel     }, WINED3D_GL_EXT_NONE             },
4972     { STATE_RENDER(WINED3D_RS_CULLMODE),                  { STATE_RENDER(WINED3D_RS_CULLMODE),                  state_cullmode      }, WINED3D_GL_EXT_NONE             },
4973     { STATE_RENDER(WINED3D_RS_ZFUNC),                     { STATE_RENDER(WINED3D_RS_ZFUNC),                     state_zfunc         }, WINED3D_GL_EXT_NONE             },
4974     { STATE_RENDER(WINED3D_RS_DITHERENABLE),              { STATE_RENDER(WINED3D_RS_DITHERENABLE),              state_ditherenable  }, WINED3D_GL_EXT_NONE             },
4975     { STATE_RENDER(WINED3D_RS_SUBPIXEL),                  { STATE_RENDER(WINED3D_RS_SUBPIXEL),                  state_subpixel      }, WINED3D_GL_EXT_NONE             },
4976     { STATE_RENDER(WINED3D_RS_SUBPIXELX),                 { STATE_RENDER(WINED3D_RS_SUBPIXELX),                 state_subpixelx     }, WINED3D_GL_EXT_NONE             },
4977     { STATE_RENDER(WINED3D_RS_STIPPLEDALPHA),             { STATE_RENDER(WINED3D_RS_STIPPLEDALPHA),             state_stippledalpha }, WINED3D_GL_EXT_NONE             },
4978     { STATE_RENDER(WINED3D_RS_STIPPLEENABLE),             { STATE_RENDER(WINED3D_RS_STIPPLEENABLE),             state_stippleenable }, WINED3D_GL_EXT_NONE             },
4979     { STATE_RENDER(WINED3D_RS_MIPMAPLODBIAS),             { STATE_RENDER(WINED3D_RS_MIPMAPLODBIAS),             state_mipmaplodbias }, WINED3D_GL_EXT_NONE             },
4980     { STATE_RENDER(WINED3D_RS_ANISOTROPY),                { STATE_RENDER(WINED3D_RS_ANISOTROPY),                state_anisotropy    }, WINED3D_GL_EXT_NONE             },
4981     { STATE_RENDER(WINED3D_RS_FLUSHBATCH),                { STATE_RENDER(WINED3D_RS_FLUSHBATCH),                state_flushbatch    }, WINED3D_GL_EXT_NONE             },
4982     { STATE_RENDER(WINED3D_RS_TRANSLUCENTSORTINDEPENDENT),{ STATE_RENDER(WINED3D_RS_TRANSLUCENTSORTINDEPENDENT),state_translucentsi }, WINED3D_GL_EXT_NONE             },
4983     { STATE_RENDER(WINED3D_RS_STENCILENABLE),             { STATE_RENDER(WINED3D_RS_STENCILENABLE),             state_stencil       }, WINED3D_GL_EXT_NONE             },
4984     { STATE_RENDER(WINED3D_RS_STENCILFAIL),               { STATE_RENDER(WINED3D_RS_STENCILENABLE),             NULL                }, WINED3D_GL_EXT_NONE             },
4985     { STATE_RENDER(WINED3D_RS_STENCILZFAIL),              { STATE_RENDER(WINED3D_RS_STENCILENABLE),             NULL                }, WINED3D_GL_EXT_NONE             },
4986     { STATE_RENDER(WINED3D_RS_STENCILPASS),               { STATE_RENDER(WINED3D_RS_STENCILENABLE),             NULL                }, WINED3D_GL_EXT_NONE             },
4987     { STATE_RENDER(WINED3D_RS_STENCILFUNC),               { STATE_RENDER(WINED3D_RS_STENCILENABLE),             NULL                }, WINED3D_GL_EXT_NONE             },
4988     { STATE_RENDER(WINED3D_RS_STENCILREF),                { STATE_RENDER(WINED3D_RS_STENCILENABLE),             NULL                }, WINED3D_GL_EXT_NONE             },
4989     { STATE_RENDER(WINED3D_RS_STENCILMASK),               { STATE_RENDER(WINED3D_RS_STENCILENABLE),             NULL                }, WINED3D_GL_EXT_NONE             },
4990     { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK),          { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK),          state_stencilwrite2s}, EXT_STENCIL_TWO_SIDE            },
4991     { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK),          { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK),          state_stencilwrite  }, WINED3D_GL_EXT_NONE             },
4992     { STATE_RENDER(WINED3D_RS_TWOSIDEDSTENCILMODE),       { STATE_RENDER(WINED3D_RS_STENCILENABLE),             NULL                }, WINED3D_GL_EXT_NONE             },
4993     { STATE_RENDER(WINED3D_RS_CCW_STENCILFAIL),           { STATE_RENDER(WINED3D_RS_STENCILENABLE),             NULL                }, WINED3D_GL_EXT_NONE             },
4994     { STATE_RENDER(WINED3D_RS_CCW_STENCILZFAIL),          { STATE_RENDER(WINED3D_RS_STENCILENABLE),             NULL                }, WINED3D_GL_EXT_NONE             },
4995     { STATE_RENDER(WINED3D_RS_CCW_STENCILPASS),           { STATE_RENDER(WINED3D_RS_STENCILENABLE),             NULL                }, WINED3D_GL_EXT_NONE             },
4996     { STATE_RENDER(WINED3D_RS_CCW_STENCILFUNC),           { STATE_RENDER(WINED3D_RS_STENCILENABLE),             NULL                }, WINED3D_GL_EXT_NONE             },
4997     { STATE_RENDER(WINED3D_RS_WRAP0),                     { STATE_RENDER(WINED3D_RS_WRAP0),                     state_wrap          }, WINED3D_GL_EXT_NONE             },
4998     { STATE_RENDER(WINED3D_RS_WRAP1),                     { STATE_RENDER(WINED3D_RS_WRAP0),                     NULL                }, WINED3D_GL_EXT_NONE             },
4999     { STATE_RENDER(WINED3D_RS_WRAP2),                     { STATE_RENDER(WINED3D_RS_WRAP0),                     NULL                }, WINED3D_GL_EXT_NONE             },
5000     { STATE_RENDER(WINED3D_RS_WRAP3),                     { STATE_RENDER(WINED3D_RS_WRAP0),                     NULL                }, WINED3D_GL_EXT_NONE             },
5001     { STATE_RENDER(WINED3D_RS_WRAP4),                     { STATE_RENDER(WINED3D_RS_WRAP0),                     NULL                }, WINED3D_GL_EXT_NONE             },
5002     { STATE_RENDER(WINED3D_RS_WRAP5),                     { STATE_RENDER(WINED3D_RS_WRAP0),                     NULL                }, WINED3D_GL_EXT_NONE             },
5003     { STATE_RENDER(WINED3D_RS_WRAP6),                     { STATE_RENDER(WINED3D_RS_WRAP0),                     NULL                }, WINED3D_GL_EXT_NONE             },
5004     { STATE_RENDER(WINED3D_RS_WRAP7),                     { STATE_RENDER(WINED3D_RS_WRAP0),                     NULL                }, WINED3D_GL_EXT_NONE             },
5005     { STATE_RENDER(WINED3D_RS_WRAP8),                     { STATE_RENDER(WINED3D_RS_WRAP0),                     NULL                }, WINED3D_GL_EXT_NONE             },
5006     { STATE_RENDER(WINED3D_RS_WRAP9),                     { STATE_RENDER(WINED3D_RS_WRAP0),                     NULL                }, WINED3D_GL_EXT_NONE             },
5007     { STATE_RENDER(WINED3D_RS_WRAP10),                    { STATE_RENDER(WINED3D_RS_WRAP0),                     NULL                }, WINED3D_GL_EXT_NONE             },
5008     { STATE_RENDER(WINED3D_RS_WRAP11),                    { STATE_RENDER(WINED3D_RS_WRAP0),                     NULL                }, WINED3D_GL_EXT_NONE             },
5009     { STATE_RENDER(WINED3D_RS_WRAP12),                    { STATE_RENDER(WINED3D_RS_WRAP0),                     NULL                }, WINED3D_GL_EXT_NONE             },
5010     { STATE_RENDER(WINED3D_RS_WRAP13),                    { STATE_RENDER(WINED3D_RS_WRAP0),                     NULL                }, WINED3D_GL_EXT_NONE             },
5011     { STATE_RENDER(WINED3D_RS_WRAP14),                    { STATE_RENDER(WINED3D_RS_WRAP0),                     NULL                }, WINED3D_GL_EXT_NONE             },
5012     { STATE_RENDER(WINED3D_RS_WRAP15),                    { STATE_RENDER(WINED3D_RS_WRAP0),                     NULL                }, WINED3D_GL_EXT_NONE             },
5013     { STATE_RENDER(WINED3D_RS_EXTENTS),                   { STATE_RENDER(WINED3D_RS_EXTENTS),                   state_extents       }, WINED3D_GL_EXT_NONE             },
5014     { STATE_RENDER(WINED3D_RS_COLORKEYBLENDENABLE),       { STATE_RENDER(WINED3D_RS_COLORKEYBLENDENABLE),       state_ckeyblend     }, WINED3D_GL_EXT_NONE             },
5015     { STATE_RENDER(WINED3D_RS_SOFTWAREVERTEXPROCESSING),  { STATE_RENDER(WINED3D_RS_SOFTWAREVERTEXPROCESSING),  state_swvp          }, WINED3D_GL_EXT_NONE             },
5016     { STATE_RENDER(WINED3D_RS_PATCHEDGESTYLE),            { STATE_RENDER(WINED3D_RS_PATCHEDGESTYLE),            state_patchedgestyle}, WINED3D_GL_EXT_NONE             },
5017     { STATE_RENDER(WINED3D_RS_PATCHSEGMENTS),             { STATE_RENDER(WINED3D_RS_PATCHSEGMENTS),             state_patchsegments }, WINED3D_GL_EXT_NONE             },
5018     { STATE_RENDER(WINED3D_RS_POSITIONDEGREE),            { STATE_RENDER(WINED3D_RS_POSITIONDEGREE),            state_positiondegree}, WINED3D_GL_EXT_NONE             },
5019     { STATE_RENDER(WINED3D_RS_NORMALDEGREE),              { STATE_RENDER(WINED3D_RS_NORMALDEGREE),              state_normaldegree  }, WINED3D_GL_EXT_NONE             },
5020     { STATE_RENDER(WINED3D_RS_MINTESSELLATIONLEVEL),      { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL                }, WINED3D_GL_EXT_NONE             },
5021     { STATE_RENDER(WINED3D_RS_MAXTESSELLATIONLEVEL),      { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL                }, WINED3D_GL_EXT_NONE             },
5022     { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_X),            { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL                }, WINED3D_GL_EXT_NONE             },
5023     { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_Y),            { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL                }, WINED3D_GL_EXT_NONE             },
5024     { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_Z),            { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL                }, WINED3D_GL_EXT_NONE             },
5025     { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_W),            { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL                }, WINED3D_GL_EXT_NONE             },
5026     { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),{ STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),state_nvdb          }, EXT_DEPTH_BOUNDS_TEST           },
5027     { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),{ STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),state_tessellation  }, WINED3D_GL_EXT_NONE             },
5028     { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS),      { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS),      state_msaa          }, ARB_MULTISAMPLE                 },
5029     { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS),      { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS),      state_msaa_w        }, WINED3D_GL_EXT_NONE             },
5030     { STATE_RENDER(WINED3D_RS_MULTISAMPLEMASK),           { STATE_RENDER(WINED3D_RS_MULTISAMPLEMASK),           state_multisampmask }, WINED3D_GL_EXT_NONE             },
5031     { STATE_RENDER(WINED3D_RS_DEBUGMONITORTOKEN),         { STATE_RENDER(WINED3D_RS_DEBUGMONITORTOKEN),         state_debug_monitor }, WINED3D_GL_EXT_NONE             },
5032     { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE),          { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE),          state_colorwrite0   }, EXT_DRAW_BUFFERS2               },
5033     { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE),          { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE),          state_colorwrite    }, WINED3D_GL_EXT_NONE             },
5034     { STATE_RENDER(WINED3D_RS_BLENDOP),                   { STATE_RENDER(WINED3D_RS_BLENDOP),                   state_blendop       }, EXT_BLEND_MINMAX                },
5035     { STATE_RENDER(WINED3D_RS_BLENDOP),                   { STATE_RENDER(WINED3D_RS_BLENDOP),                   state_blendop_w     }, WINED3D_GL_EXT_NONE             },
5036     { STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE),         { STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE),         state_scissor       }, WINED3D_GL_EXT_NONE             },
5037     { STATE_RENDER(WINED3D_RS_SLOPESCALEDEPTHBIAS),       { STATE_RENDER(WINED3D_RS_DEPTHBIAS),                 NULL                }, WINED3D_GL_EXT_NONE             },
5038     { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1),         { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1),         state_colorwrite1   }, EXT_DRAW_BUFFERS2               },
5039     { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1),         { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
5040     { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2),         { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2),         state_colorwrite2   }, EXT_DRAW_BUFFERS2               },
5041     { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2),         { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
5042     { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3),         { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3),         state_colorwrite3   }, EXT_DRAW_BUFFERS2               },
5043     { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3),         { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
5044     { STATE_RENDER(WINED3D_RS_BLENDFACTOR),               { STATE_RENDER(WINED3D_RS_BLENDFACTOR),               state_blendfactor   }, EXT_BLEND_COLOR                 },
5045     { STATE_RENDER(WINED3D_RS_BLENDFACTOR),               { STATE_RENDER(WINED3D_RS_BLENDFACTOR),               state_blendfactor_w }, WINED3D_GL_EXT_NONE             },
5046     { STATE_RENDER(WINED3D_RS_DEPTHBIAS),                 { STATE_RENDER(WINED3D_RS_DEPTHBIAS),                 state_depthbias     }, WINED3D_GL_EXT_NONE             },
5047     { STATE_RENDER(WINED3D_RS_ZVISIBLE),                  { STATE_RENDER(WINED3D_RS_ZVISIBLE),                  state_zvisible      }, WINED3D_GL_EXT_NONE             },
5048     /* Samplers */
5049     { STATE_SAMPLER(0),                                   { STATE_SAMPLER(0),                                   sampler             }, WINED3D_GL_EXT_NONE             },
5050     { STATE_SAMPLER(1),                                   { STATE_SAMPLER(1),                                   sampler             }, WINED3D_GL_EXT_NONE             },
5051     { STATE_SAMPLER(2),                                   { STATE_SAMPLER(2),                                   sampler             }, WINED3D_GL_EXT_NONE             },
5052     { STATE_SAMPLER(3),                                   { STATE_SAMPLER(3),                                   sampler             }, WINED3D_GL_EXT_NONE             },
5053     { STATE_SAMPLER(4),                                   { STATE_SAMPLER(4),                                   sampler             }, WINED3D_GL_EXT_NONE             },
5054     { STATE_SAMPLER(5),                                   { STATE_SAMPLER(5),                                   sampler             }, WINED3D_GL_EXT_NONE             },
5055     { STATE_SAMPLER(6),                                   { STATE_SAMPLER(6),                                   sampler             }, WINED3D_GL_EXT_NONE             },
5056     { STATE_SAMPLER(7),                                   { STATE_SAMPLER(7),                                   sampler             }, WINED3D_GL_EXT_NONE             },
5057     { STATE_SAMPLER(8),                                   { STATE_SAMPLER(8),                                   sampler             }, WINED3D_GL_EXT_NONE             },
5058     { STATE_SAMPLER(9),                                   { STATE_SAMPLER(9),                                   sampler             }, WINED3D_GL_EXT_NONE             },
5059     { STATE_SAMPLER(10),                                  { STATE_SAMPLER(10),                                  sampler             }, WINED3D_GL_EXT_NONE             },
5060     { STATE_SAMPLER(11),                                  { STATE_SAMPLER(11),                                  sampler             }, WINED3D_GL_EXT_NONE             },
5061     { STATE_SAMPLER(12),                                  { STATE_SAMPLER(12),                                  sampler             }, WINED3D_GL_EXT_NONE             },
5062     { STATE_SAMPLER(13),                                  { STATE_SAMPLER(13),                                  sampler             }, WINED3D_GL_EXT_NONE             },
5063     { STATE_SAMPLER(14),                                  { STATE_SAMPLER(14),                                  sampler             }, WINED3D_GL_EXT_NONE             },
5064     { STATE_SAMPLER(15),                                  { STATE_SAMPLER(15),                                  sampler             }, WINED3D_GL_EXT_NONE             },
5065     { STATE_SAMPLER(16), /* Vertex sampler 0 */           { STATE_SAMPLER(16),                                  sampler             }, WINED3D_GL_EXT_NONE             },
5066     { STATE_SAMPLER(17), /* Vertex sampler 1 */           { STATE_SAMPLER(17),                                  sampler             }, WINED3D_GL_EXT_NONE             },
5067     { STATE_SAMPLER(18), /* Vertex sampler 2 */           { STATE_SAMPLER(18),                                  sampler             }, WINED3D_GL_EXT_NONE             },
5068     { STATE_SAMPLER(19), /* Vertex sampler 3 */           { STATE_SAMPLER(19),                                  sampler             }, WINED3D_GL_EXT_NONE             },
5069     { STATE_BASEVERTEXINDEX,                              { STATE_BASEVERTEXINDEX,                              state_nop,          }, ARB_DRAW_ELEMENTS_BASE_VERTEX   },
5070     { STATE_BASEVERTEXINDEX,                              { STATE_STREAMSRC,                                    NULL,               }, WINED3D_GL_EXT_NONE             },
5071     { STATE_FRAMEBUFFER,                                  { STATE_FRAMEBUFFER,                                  context_state_fb    }, WINED3D_GL_EXT_NONE             },
5072     { STATE_PIXELSHADER,                                  { STATE_PIXELSHADER,                                  context_state_drawbuf},WINED3D_GL_EXT_NONE             },
5073     {0 /* Terminate */,                                   { 0,                                                  0                   }, WINED3D_GL_EXT_NONE             },
5074 };
5075
5076 const struct StateEntryTemplate ffp_vertexstate_template[] = {
5077     { STATE_VDECL,                                        { STATE_VDECL,                                        vertexdeclaration   }, WINED3D_GL_EXT_NONE             },
5078     { STATE_VSHADER,                                      { STATE_VDECL,                                        NULL                }, WINED3D_GL_EXT_NONE             },
5079     { STATE_MATERIAL,                                     { STATE_RENDER(WINED3D_RS_SPECULARENABLE),            NULL                }, WINED3D_GL_EXT_NONE             },
5080     { STATE_RENDER(WINED3D_RS_SPECULARENABLE),            { STATE_RENDER(WINED3D_RS_SPECULARENABLE),            state_specularenable}, WINED3D_GL_EXT_NONE             },
5081       /* Clip planes */
5082     { STATE_CLIPPLANE(0),                                 { STATE_CLIPPLANE(0),                                 clipplane           }, WINED3D_GL_EXT_NONE             },
5083     { STATE_CLIPPLANE(1),                                 { STATE_CLIPPLANE(1),                                 clipplane           }, WINED3D_GL_EXT_NONE             },
5084     { STATE_CLIPPLANE(2),                                 { STATE_CLIPPLANE(2),                                 clipplane           }, WINED3D_GL_EXT_NONE             },
5085     { STATE_CLIPPLANE(3),                                 { STATE_CLIPPLANE(3),                                 clipplane           }, WINED3D_GL_EXT_NONE             },
5086     { STATE_CLIPPLANE(4),                                 { STATE_CLIPPLANE(4),                                 clipplane           }, WINED3D_GL_EXT_NONE             },
5087     { STATE_CLIPPLANE(5),                                 { STATE_CLIPPLANE(5),                                 clipplane           }, WINED3D_GL_EXT_NONE             },
5088     { STATE_CLIPPLANE(6),                                 { STATE_CLIPPLANE(6),                                 clipplane           }, WINED3D_GL_EXT_NONE             },
5089     { STATE_CLIPPLANE(7),                                 { STATE_CLIPPLANE(7),                                 clipplane           }, WINED3D_GL_EXT_NONE             },
5090     { STATE_CLIPPLANE(8),                                 { STATE_CLIPPLANE(8),                                 clipplane           }, WINED3D_GL_EXT_NONE             },
5091     { STATE_CLIPPLANE(9),                                 { STATE_CLIPPLANE(9),                                 clipplane           }, WINED3D_GL_EXT_NONE             },
5092     { STATE_CLIPPLANE(10),                                { STATE_CLIPPLANE(10),                                clipplane           }, WINED3D_GL_EXT_NONE             },
5093     { STATE_CLIPPLANE(11),                                { STATE_CLIPPLANE(11),                                clipplane           }, WINED3D_GL_EXT_NONE             },
5094     { STATE_CLIPPLANE(12),                                { STATE_CLIPPLANE(12),                                clipplane           }, WINED3D_GL_EXT_NONE             },
5095     { STATE_CLIPPLANE(13),                                { STATE_CLIPPLANE(13),                                clipplane           }, WINED3D_GL_EXT_NONE             },
5096     { STATE_CLIPPLANE(14),                                { STATE_CLIPPLANE(14),                                clipplane           }, WINED3D_GL_EXT_NONE             },
5097     { STATE_CLIPPLANE(15),                                { STATE_CLIPPLANE(15),                                clipplane           }, WINED3D_GL_EXT_NONE             },
5098     { STATE_CLIPPLANE(16),                                { STATE_CLIPPLANE(16),                                clipplane           }, WINED3D_GL_EXT_NONE             },
5099     { STATE_CLIPPLANE(17),                                { STATE_CLIPPLANE(17),                                clipplane           }, WINED3D_GL_EXT_NONE             },
5100     { STATE_CLIPPLANE(18),                                { STATE_CLIPPLANE(18),                                clipplane           }, WINED3D_GL_EXT_NONE             },
5101     { STATE_CLIPPLANE(19),                                { STATE_CLIPPLANE(19),                                clipplane           }, WINED3D_GL_EXT_NONE             },
5102     { STATE_CLIPPLANE(20),                                { STATE_CLIPPLANE(20),                                clipplane           }, WINED3D_GL_EXT_NONE             },
5103     { STATE_CLIPPLANE(21),                                { STATE_CLIPPLANE(21),                                clipplane           }, WINED3D_GL_EXT_NONE             },
5104     { STATE_CLIPPLANE(22),                                { STATE_CLIPPLANE(22),                                clipplane           }, WINED3D_GL_EXT_NONE             },
5105     { STATE_CLIPPLANE(23),                                { STATE_CLIPPLANE(23),                                clipplane           }, WINED3D_GL_EXT_NONE             },
5106     { STATE_CLIPPLANE(24),                                { STATE_CLIPPLANE(24),                                clipplane           }, WINED3D_GL_EXT_NONE             },
5107     { STATE_CLIPPLANE(25),                                { STATE_CLIPPLANE(25),                                clipplane           }, WINED3D_GL_EXT_NONE             },
5108     { STATE_CLIPPLANE(26),                                { STATE_CLIPPLANE(26),                                clipplane           }, WINED3D_GL_EXT_NONE             },
5109     { STATE_CLIPPLANE(27),                                { STATE_CLIPPLANE(27),                                clipplane           }, WINED3D_GL_EXT_NONE             },
5110     { STATE_CLIPPLANE(28),                                { STATE_CLIPPLANE(28),                                clipplane           }, WINED3D_GL_EXT_NONE             },
5111     { STATE_CLIPPLANE(29),                                { STATE_CLIPPLANE(29),                                clipplane           }, WINED3D_GL_EXT_NONE             },
5112     { STATE_CLIPPLANE(30),                                { STATE_CLIPPLANE(30),                                clipplane           }, WINED3D_GL_EXT_NONE             },
5113     { STATE_CLIPPLANE(31),                                { STATE_CLIPPLANE(31),                                clipplane           }, WINED3D_GL_EXT_NONE             },
5114       /* Lights */
5115     { STATE_ACTIVELIGHT(0),                               { STATE_ACTIVELIGHT(0),                               light               }, WINED3D_GL_EXT_NONE             },
5116     { STATE_ACTIVELIGHT(1),                               { STATE_ACTIVELIGHT(1),                               light               }, WINED3D_GL_EXT_NONE             },
5117     { STATE_ACTIVELIGHT(2),                               { STATE_ACTIVELIGHT(2),                               light               }, WINED3D_GL_EXT_NONE             },
5118     { STATE_ACTIVELIGHT(3),                               { STATE_ACTIVELIGHT(3),                               light               }, WINED3D_GL_EXT_NONE             },
5119     { STATE_ACTIVELIGHT(4),                               { STATE_ACTIVELIGHT(4),                               light               }, WINED3D_GL_EXT_NONE             },
5120     { STATE_ACTIVELIGHT(5),                               { STATE_ACTIVELIGHT(5),                               light               }, WINED3D_GL_EXT_NONE             },
5121     { STATE_ACTIVELIGHT(6),                               { STATE_ACTIVELIGHT(6),                               light               }, WINED3D_GL_EXT_NONE             },
5122     { STATE_ACTIVELIGHT(7),                               { STATE_ACTIVELIGHT(7),                               light               }, WINED3D_GL_EXT_NONE             },
5123     /* Viewport */
5124     { STATE_VIEWPORT,                                     { STATE_VIEWPORT,                                     viewport_vertexpart }, WINED3D_GL_EXT_NONE             },
5125       /* Transform states follow                    */
5126     { STATE_TRANSFORM(WINED3D_TS_VIEW),                   { STATE_TRANSFORM(WINED3D_TS_VIEW),                   transform_view      }, WINED3D_GL_EXT_NONE             },
5127     { STATE_TRANSFORM(WINED3D_TS_PROJECTION),             { STATE_TRANSFORM(WINED3D_TS_PROJECTION),             transform_projection}, WINED3D_GL_EXT_NONE             },
5128     { STATE_TRANSFORM(WINED3D_TS_TEXTURE0),               { STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL            }, WINED3D_GL_EXT_NONE             },
5129     { STATE_TRANSFORM(WINED3D_TS_TEXTURE1),               { STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL            }, WINED3D_GL_EXT_NONE             },
5130     { STATE_TRANSFORM(WINED3D_TS_TEXTURE2),               { STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL            }, WINED3D_GL_EXT_NONE             },
5131     { STATE_TRANSFORM(WINED3D_TS_TEXTURE3),               { STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL            }, WINED3D_GL_EXT_NONE             },
5132     { STATE_TRANSFORM(WINED3D_TS_TEXTURE4),               { STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL            }, WINED3D_GL_EXT_NONE             },
5133     { STATE_TRANSFORM(WINED3D_TS_TEXTURE5),               { STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL            }, WINED3D_GL_EXT_NONE             },
5134     { STATE_TRANSFORM(WINED3D_TS_TEXTURE6),               { STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL            }, WINED3D_GL_EXT_NONE             },
5135     { STATE_TRANSFORM(WINED3D_TS_TEXTURE7),               { STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL            }, WINED3D_GL_EXT_NONE             },
5136     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  0)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  0)),      transform_world     }, WINED3D_GL_EXT_NONE             },
5137     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  1)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  1)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5138     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  2)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  2)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5139     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  3)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  3)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5140     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  4)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  4)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5141     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  5)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  5)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5142     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  6)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  6)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5143     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  7)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  7)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5144     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  8)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  8)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5145     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  9)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  9)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5146     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 10)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 10)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5147     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 11)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 11)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5148     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 12)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 12)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5149     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 13)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 13)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5150     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 14)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 14)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5151     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 15)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 15)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5152     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 16)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 16)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5153     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 17)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 17)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5154     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 18)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 18)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5155     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 19)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 19)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5156     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 20)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 20)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5157     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 21)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 21)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5158     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 22)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 22)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5159     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 23)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 23)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5160     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 24)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 24)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5161     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 25)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 25)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5162     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 26)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 26)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5163     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 27)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 27)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5164     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 28)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 28)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5165     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 29)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 29)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5166     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 30)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 30)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5167     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 31)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 31)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5168     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 32)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 32)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5169     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 33)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 33)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5170     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 34)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 34)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5171     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 35)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 35)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5172     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 36)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 36)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5173     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 37)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 37)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5174     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 38)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 38)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5175     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 39)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 39)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5176     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 40)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 40)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5177     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 41)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 41)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5178     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 42)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 42)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5179     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 43)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 43)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5180     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 44)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 44)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5181     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 45)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 45)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5182     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 46)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 46)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5183     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 47)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 47)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5184     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 48)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 48)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5185     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 49)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 49)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5186     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 50)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 50)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5187     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 51)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 51)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5188     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 52)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 52)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5189     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 53)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 53)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5190     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 54)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 54)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5191     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 55)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 55)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5192     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 56)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 56)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5193     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 57)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 57)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5194     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 58)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 58)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5195     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 59)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 59)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5196     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 60)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 60)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5197     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 61)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 61)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5198     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 62)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 62)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5199     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 63)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 63)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5200     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 64)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 64)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5201     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 65)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 65)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5202     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 66)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 66)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5203     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 67)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 67)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5204     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 68)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 68)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5205     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 69)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 69)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5206     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 70)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 70)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5207     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 71)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 71)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5208     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 72)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 72)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5209     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 73)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 73)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5210     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 74)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 74)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5211     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 75)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 75)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5212     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 76)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 76)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5213     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 77)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 77)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5214     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 78)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 78)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5215     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 79)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 79)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5216     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 80)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 80)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5217     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 81)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 81)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5218     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 82)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 82)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5219     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 83)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 83)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5220     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 84)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 84)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5221     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 85)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 85)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5222     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 86)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 86)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5223     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 87)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 87)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5224     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 88)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 88)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5225     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 89)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 89)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5226     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 90)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 90)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5227     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 91)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 91)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5228     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 92)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 92)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5229     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 93)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 93)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5230     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 94)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 94)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5231     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 95)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 95)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5232     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 96)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 96)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5233     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 97)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 97)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5234     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 98)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 98)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5235     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 99)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 99)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5236     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(100)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(100)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5237     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(101)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(101)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5238     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(102)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(102)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5239     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(103)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(103)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5240     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(104)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(104)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5241     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(105)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(105)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5242     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(106)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(106)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5243     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(107)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(107)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5244     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(108)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(108)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5245     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(109)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(109)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5246     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(110)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(110)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5247     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(111)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(111)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5248     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(112)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(112)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5249     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(113)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(113)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5250     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(114)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(114)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5251     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(115)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(115)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5252     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(116)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(116)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5253     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(117)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(117)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5254     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(118)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(118)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5255     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(119)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(119)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5256     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(120)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(120)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5257     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(121)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(121)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5258     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(122)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(122)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5259     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(123)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(123)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5260     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(124)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(124)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5261     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(125)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(125)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5262     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(126)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(126)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5263     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(127)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(127)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5264     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(128)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(128)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5265     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(129)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(129)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5266     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(130)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(130)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5267     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(131)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(131)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5268     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(132)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(132)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5269     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(133)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(133)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5270     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(134)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(134)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5271     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(135)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(135)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5272     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(136)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(136)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5273     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(137)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(137)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5274     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(138)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(138)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5275     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(139)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(139)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5276     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(140)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(140)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5277     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(141)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(141)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5278     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(142)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(142)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5279     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(143)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(143)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5280     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(144)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(144)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5281     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(145)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(145)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5282     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(146)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(146)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5283     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(147)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(147)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5284     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(148)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(148)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5285     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(149)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(149)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5286     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(150)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(150)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5287     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(151)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(151)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5288     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(152)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(152)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5289     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(153)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(153)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5290     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(154)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(154)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5291     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(155)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(155)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5292     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(156)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(156)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5293     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(157)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(157)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5294     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(158)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(158)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5295     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(159)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(159)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5296     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(160)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(160)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5297     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(161)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(161)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5298     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(162)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(162)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5299     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(163)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(163)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5300     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(164)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(164)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5301     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(165)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(165)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5302     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(166)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(166)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5303     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(167)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(167)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5304     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(168)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(168)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5305     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(169)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(169)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5306     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(170)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(170)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5307     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(171)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(171)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5308     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(172)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(172)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5309     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(173)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(173)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5310     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(174)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(174)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5311     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(175)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(175)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5312     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(176)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(176)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5313     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(177)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(177)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5314     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(178)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(178)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5315     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(179)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(179)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5316     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(180)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(180)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5317     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(181)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(181)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5318     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(182)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(182)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5319     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(183)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(183)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5320     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(184)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(184)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5321     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(185)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(185)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5322     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(186)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(186)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5323     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(187)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(187)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5324     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(188)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(188)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5325     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(189)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(189)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5326     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(190)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(190)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5327     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(191)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(191)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5328     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(192)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(192)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5329     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(193)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(193)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5330     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(194)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(194)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5331     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(195)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(195)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5332     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(196)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(196)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5333     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(197)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(197)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5334     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(198)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(198)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5335     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(199)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(199)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5336     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(200)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(200)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5337     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(201)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(201)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5338     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(202)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(202)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5339     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(203)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(203)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5340     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(204)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(204)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5341     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(205)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(205)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5342     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(206)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(206)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5343     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(207)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(207)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5344     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(208)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(208)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5345     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(209)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(209)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5346     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(210)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(210)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5347     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(211)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(211)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5348     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(212)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(212)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5349     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(213)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(213)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5350     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(214)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(214)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5351     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(215)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(215)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5352     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(216)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(216)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5353     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(217)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(217)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5354     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(218)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(218)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5355     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(219)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(219)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5356     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(220)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(220)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5357     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(221)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(221)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5358     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(222)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(222)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5359     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(223)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(223)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5360     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(224)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(224)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5361     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(225)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(225)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5362     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(226)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(226)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5363     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(227)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(227)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5364     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(228)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(228)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5365     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(229)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(229)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5366     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(230)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(230)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5367     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(231)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(231)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5368     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(232)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(232)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5369     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(233)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(233)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5370     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(234)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(234)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5371     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(235)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(235)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5372     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(236)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(236)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5373     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(237)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(237)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5374     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(238)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(238)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5375     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(239)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(239)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5376     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(240)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(240)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5377     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(241)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(241)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5378     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(242)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(242)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5379     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(243)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(243)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5380     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(244)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(244)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5381     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(245)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(245)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5382     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(246)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(246)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5383     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(247)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(247)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5384     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(248)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(248)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5385     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(249)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(249)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5386     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(250)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(250)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5387     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(251)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(251)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5388     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(252)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(252)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5389     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(253)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(253)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5390     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(254)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(254)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5391     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5392     { STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture   }, WINED3D_GL_EXT_NONE             },
5393     { STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture   }, WINED3D_GL_EXT_NONE             },
5394     { STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture   }, WINED3D_GL_EXT_NONE             },
5395     { STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture   }, WINED3D_GL_EXT_NONE             },
5396     { STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture   }, WINED3D_GL_EXT_NONE             },
5397     { STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture   }, WINED3D_GL_EXT_NONE             },
5398     { STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture   }, WINED3D_GL_EXT_NONE             },
5399     { STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture   }, WINED3D_GL_EXT_NONE             },
5400     { STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXCOORD_INDEX),  { STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXCOORD_INDEX),  tex_coordindex      }, WINED3D_GL_EXT_NONE             },
5401     { STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXCOORD_INDEX),  { STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXCOORD_INDEX),  tex_coordindex      }, WINED3D_GL_EXT_NONE             },
5402     { STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXCOORD_INDEX),  { STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXCOORD_INDEX),  tex_coordindex      }, WINED3D_GL_EXT_NONE             },
5403     { STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXCOORD_INDEX),  { STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXCOORD_INDEX),  tex_coordindex      }, WINED3D_GL_EXT_NONE             },
5404     { STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXCOORD_INDEX),  { STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXCOORD_INDEX),  tex_coordindex      }, WINED3D_GL_EXT_NONE             },
5405     { STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXCOORD_INDEX),  { STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXCOORD_INDEX),  tex_coordindex      }, WINED3D_GL_EXT_NONE             },
5406     { STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXCOORD_INDEX),  { STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXCOORD_INDEX),  tex_coordindex      }, WINED3D_GL_EXT_NONE             },
5407     { STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXCOORD_INDEX),  { STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXCOORD_INDEX),  tex_coordindex      }, WINED3D_GL_EXT_NONE             },
5408       /* Fog */
5409     { STATE_RENDER(WINED3D_RS_FOGENABLE),                 { STATE_RENDER(WINED3D_RS_FOGENABLE),                 state_fog_vertexpart}, WINED3D_GL_EXT_NONE             },
5410     { STATE_RENDER(WINED3D_RS_FOGTABLEMODE),              { STATE_RENDER(WINED3D_RS_FOGENABLE),                 NULL                }, WINED3D_GL_EXT_NONE             },
5411     { STATE_RENDER(WINED3D_RS_FOGVERTEXMODE),             { STATE_RENDER(WINED3D_RS_FOGENABLE),                 NULL                }, WINED3D_GL_EXT_NONE             },
5412     { STATE_RENDER(WINED3D_RS_RANGEFOGENABLE),            { STATE_RENDER(WINED3D_RS_FOGENABLE),                 NULL                }, WINED3D_GL_EXT_NONE             },
5413     { STATE_RENDER(WINED3D_RS_CLIPPING),                  { STATE_RENDER(WINED3D_RS_CLIPPING),                  state_clipping      }, WINED3D_GL_EXT_NONE             },
5414     { STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE),           { STATE_RENDER(WINED3D_RS_CLIPPING),                  NULL                }, WINED3D_GL_EXT_NONE             },
5415     { STATE_RENDER(WINED3D_RS_LIGHTING),                  { STATE_RENDER(WINED3D_RS_LIGHTING),                  state_lighting      }, WINED3D_GL_EXT_NONE             },
5416     { STATE_RENDER(WINED3D_RS_AMBIENT),                   { STATE_RENDER(WINED3D_RS_AMBIENT),                   state_ambient       }, WINED3D_GL_EXT_NONE             },
5417     { STATE_RENDER(WINED3D_RS_COLORVERTEX),               { STATE_RENDER(WINED3D_RS_COLORVERTEX),               state_colormat      }, WINED3D_GL_EXT_NONE             },
5418     { STATE_RENDER(WINED3D_RS_LOCALVIEWER),               { STATE_RENDER(WINED3D_RS_LOCALVIEWER),               state_localviewer   }, WINED3D_GL_EXT_NONE             },
5419     { STATE_RENDER(WINED3D_RS_NORMALIZENORMALS),          { STATE_RENDER(WINED3D_RS_NORMALIZENORMALS),          state_normalize     }, WINED3D_GL_EXT_NONE             },
5420     { STATE_RENDER(WINED3D_RS_DIFFUSEMATERIALSOURCE),     { STATE_RENDER(WINED3D_RS_COLORVERTEX),               NULL                }, WINED3D_GL_EXT_NONE             },
5421     { STATE_RENDER(WINED3D_RS_SPECULARMATERIALSOURCE),    { STATE_RENDER(WINED3D_RS_COLORVERTEX),               NULL                }, WINED3D_GL_EXT_NONE             },
5422     { STATE_RENDER(WINED3D_RS_AMBIENTMATERIALSOURCE),     { STATE_RENDER(WINED3D_RS_COLORVERTEX),               NULL                }, WINED3D_GL_EXT_NONE             },
5423     { STATE_RENDER(WINED3D_RS_EMISSIVEMATERIALSOURCE),    { STATE_RENDER(WINED3D_RS_COLORVERTEX),               NULL                }, WINED3D_GL_EXT_NONE             },
5424     { STATE_RENDER(WINED3D_RS_VERTEXBLEND),               { STATE_RENDER(WINED3D_RS_VERTEXBLEND),               state_vertexblend   }, ARB_VERTEX_BLEND                },
5425     { STATE_RENDER(WINED3D_RS_VERTEXBLEND),               { STATE_RENDER(WINED3D_RS_VERTEXBLEND),               state_vertexblend_w }, WINED3D_GL_EXT_NONE             },
5426     { STATE_RENDER(WINED3D_RS_POINTSIZE),                 { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
5427     { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN),             { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN),             state_psizemin_arb  }, ARB_POINT_PARAMETERS            },
5428     { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN),             { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN),             state_psizemin_ext  }, EXT_POINT_PARAMETERS            },
5429     { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN),             { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN),             state_psizemin_w    }, WINED3D_GL_EXT_NONE             },
5430     { STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE),         { STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE),         state_pointsprite   }, ARB_POINT_SPRITE                },
5431     { STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE),         { STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE),         state_pointsprite_w }, WINED3D_GL_EXT_NONE             },
5432     { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE),          { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE),          state_pscale        }, WINED3D_GL_EXT_NONE             },
5433     { STATE_RENDER(WINED3D_RS_POINTSCALE_A),              { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
5434     { STATE_RENDER(WINED3D_RS_POINTSCALE_B),              { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
5435     { STATE_RENDER(WINED3D_RS_POINTSCALE_C),              { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
5436     { STATE_RENDER(WINED3D_RS_POINTSIZE_MAX),             { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN),             NULL                }, ARB_POINT_PARAMETERS            },
5437     { STATE_RENDER(WINED3D_RS_POINTSIZE_MAX),             { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN),             NULL                }, EXT_POINT_PARAMETERS            },
5438     { STATE_RENDER(WINED3D_RS_POINTSIZE_MAX),             { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN),             NULL                }, WINED3D_GL_EXT_NONE             },
5439     { STATE_RENDER(WINED3D_RS_TWEENFACTOR),               { STATE_RENDER(WINED3D_RS_VERTEXBLEND),               NULL                }, WINED3D_GL_EXT_NONE             },
5440     { STATE_RENDER(WINED3D_RS_INDEXEDVERTEXBLENDENABLE),  { STATE_RENDER(WINED3D_RS_VERTEXBLEND),               NULL                }, WINED3D_GL_EXT_NONE             },
5441
5442     /* Samplers for NP2 texture matrix adjustions. They are not needed if GL_ARB_texture_non_power_of_two is supported,
5443      * so register a NULL state handler in that case to get the vertex part of sampler() skipped(VTF is handled in the misc states.
5444      * otherwise, register sampler_texmatrix, which takes care of updating the texture matrix
5445      */
5446     { STATE_SAMPLER(0),                                   { 0,                                                  NULL                }, ARB_TEXTURE_NON_POWER_OF_TWO    },
5447     { STATE_SAMPLER(0),                                   { 0,                                                  NULL                }, WINED3D_GL_NORMALIZED_TEXRECT   },
5448     { STATE_SAMPLER(0),                                   { STATE_SAMPLER(0),                                   sampler_texmatrix   }, WINED3D_GL_EXT_NONE             },
5449     { STATE_SAMPLER(1),                                   { 0,                                                  NULL                }, ARB_TEXTURE_NON_POWER_OF_TWO    },
5450     { STATE_SAMPLER(1),                                   { 0,                                                  NULL                }, WINED3D_GL_NORMALIZED_TEXRECT   },
5451     { STATE_SAMPLER(1),                                   { STATE_SAMPLER(1),                                   sampler_texmatrix   }, WINED3D_GL_EXT_NONE             },
5452     { STATE_SAMPLER(2),                                   { 0,                                                  NULL                }, ARB_TEXTURE_NON_POWER_OF_TWO    },
5453     { STATE_SAMPLER(2),                                   { 0,                                                  NULL                }, WINED3D_GL_NORMALIZED_TEXRECT   },
5454     { STATE_SAMPLER(2),                                   { STATE_SAMPLER(2),                                   sampler_texmatrix   }, WINED3D_GL_EXT_NONE             },
5455     { STATE_SAMPLER(3),                                   { 0,                                                  NULL                }, ARB_TEXTURE_NON_POWER_OF_TWO    },
5456     { STATE_SAMPLER(3),                                   { 0,                                                  NULL                }, WINED3D_GL_NORMALIZED_TEXRECT   },
5457     { STATE_SAMPLER(3),                                   { STATE_SAMPLER(3),                                   sampler_texmatrix   }, WINED3D_GL_EXT_NONE             },
5458     { STATE_SAMPLER(4),                                   { 0,                                                  NULL                }, ARB_TEXTURE_NON_POWER_OF_TWO    },
5459     { STATE_SAMPLER(4),                                   { 0,                                                  NULL                }, WINED3D_GL_NORMALIZED_TEXRECT   },
5460     { STATE_SAMPLER(4),                                   { STATE_SAMPLER(4),                                   sampler_texmatrix   }, WINED3D_GL_EXT_NONE             },
5461     { STATE_SAMPLER(5),                                   { 0,                                                  NULL                }, ARB_TEXTURE_NON_POWER_OF_TWO    },
5462     { STATE_SAMPLER(5),                                   { 0,                                                  NULL                }, WINED3D_GL_NORMALIZED_TEXRECT   },
5463     { STATE_SAMPLER(5),                                   { STATE_SAMPLER(5),                                   sampler_texmatrix   }, WINED3D_GL_EXT_NONE             },
5464     { STATE_SAMPLER(6),                                   { 0,                                                  NULL                }, ARB_TEXTURE_NON_POWER_OF_TWO    },
5465     { STATE_SAMPLER(6),                                   { 0,                                                  NULL                }, WINED3D_GL_NORMALIZED_TEXRECT   },
5466     { STATE_SAMPLER(6),                                   { STATE_SAMPLER(6),                                   sampler_texmatrix   }, WINED3D_GL_EXT_NONE             },
5467     { STATE_SAMPLER(7),                                   { 0,                                                  NULL                }, ARB_TEXTURE_NON_POWER_OF_TWO    },
5468     { STATE_SAMPLER(7),                                   { 0,                                                  NULL                }, WINED3D_GL_NORMALIZED_TEXRECT   },
5469     { STATE_SAMPLER(7),                                   { STATE_SAMPLER(7),                                   sampler_texmatrix   }, WINED3D_GL_EXT_NONE             },
5470     {0 /* Terminate */,                                   { 0,                                                  0                   }, WINED3D_GL_EXT_NONE             },
5471 };
5472
5473 static const struct StateEntryTemplate ffp_fragmentstate_template[] = {
5474     { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP),        { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP),        tex_colorop         }, WINED3D_GL_EXT_NONE             },
5475     { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG1),      { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5476     { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG2),      { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5477     { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP),        { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP),        tex_alphaop         }, WINED3D_GL_EXT_NONE             },
5478     { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG1),      { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5479     { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG2),      { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5480     { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG0),      { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5481     { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG0),      { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5482     { STATE_TEXTURESTAGE(0, WINED3D_TSS_RESULT_ARG),      { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5483     { STATE_TEXTURESTAGE(0, WINED3D_TSS_CONSTANT),        { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL                }, WINED3D_GL_EXT_NONE             },
5484     { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP),        { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP),        tex_colorop         }, WINED3D_GL_EXT_NONE             },
5485     { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG1),      { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5486     { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG2),      { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5487     { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP),        { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP),        tex_alphaop         }, WINED3D_GL_EXT_NONE             },
5488     { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG1),      { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5489     { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG2),      { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5490     { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG0),      { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5491     { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG0),      { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5492     { STATE_TEXTURESTAGE(1, WINED3D_TSS_RESULT_ARG),      { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5493     { STATE_TEXTURESTAGE(1, WINED3D_TSS_CONSTANT),        { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL                }, WINED3D_GL_EXT_NONE             },
5494     { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP),        { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP),        tex_colorop         }, WINED3D_GL_EXT_NONE             },
5495     { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG1),      { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5496     { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG2),      { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5497     { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP),        { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP),        tex_alphaop         }, WINED3D_GL_EXT_NONE             },
5498     { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG1),      { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5499     { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG2),      { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5500     { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG0),      { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5501     { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG0),      { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5502     { STATE_TEXTURESTAGE(2, WINED3D_TSS_RESULT_ARG),      { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5503     { STATE_TEXTURESTAGE(2, WINED3D_TSS_CONSTANT),        { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL                }, WINED3D_GL_EXT_NONE             },
5504     { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP),        { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP),        tex_colorop         }, WINED3D_GL_EXT_NONE             },
5505     { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG1),      { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5506     { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG2),      { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5507     { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP),        { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP),        tex_alphaop         }, WINED3D_GL_EXT_NONE             },
5508     { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG1),      { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5509     { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG2),      { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5510     { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG0),      { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5511     { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG0),      { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5512     { STATE_TEXTURESTAGE(3, WINED3D_TSS_RESULT_ARG),      { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5513     { STATE_TEXTURESTAGE(3, WINED3D_TSS_CONSTANT),        { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL                }, WINED3D_GL_EXT_NONE             },
5514     { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP),        { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP),        tex_colorop         }, WINED3D_GL_EXT_NONE             },
5515     { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG1),      { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5516     { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG2),      { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5517     { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP),        { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP),        tex_alphaop         }, WINED3D_GL_EXT_NONE             },
5518     { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG1),      { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5519     { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG2),      { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5520     { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG0),      { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5521     { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG0),      { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5522     { STATE_TEXTURESTAGE(4, WINED3D_TSS_RESULT_ARG),      { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5523     { STATE_TEXTURESTAGE(4, WINED3D_TSS_CONSTANT),        { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL                }, WINED3D_GL_EXT_NONE             },
5524     { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP),        { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP),        tex_colorop         }, WINED3D_GL_EXT_NONE             },
5525     { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG1),      { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5526     { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG2),      { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5527     { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP),        { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP),        tex_alphaop         }, WINED3D_GL_EXT_NONE             },
5528     { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG1),      { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5529     { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG2),      { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5530     { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG0),      { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5531     { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG0),      { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5532     { STATE_TEXTURESTAGE(5, WINED3D_TSS_RESULT_ARG),      { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5533     { STATE_TEXTURESTAGE(5, WINED3D_TSS_CONSTANT),        { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL                }, WINED3D_GL_EXT_NONE             },
5534     { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP),        { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP),        tex_colorop         }, WINED3D_GL_EXT_NONE             },
5535     { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG1),      { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5536     { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG2),      { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5537     { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP),        { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP),        tex_alphaop         }, WINED3D_GL_EXT_NONE             },
5538     { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG1),      { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5539     { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG2),      { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5540     { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG0),      { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5541     { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG0),      { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5542     { STATE_TEXTURESTAGE(6, WINED3D_TSS_RESULT_ARG),      { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5543     { STATE_TEXTURESTAGE(6, WINED3D_TSS_CONSTANT),        { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL                }, WINED3D_GL_EXT_NONE             },
5544     { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP),        { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP),        tex_colorop         }, WINED3D_GL_EXT_NONE             },
5545     { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG1),      { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5546     { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG2),      { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5547     { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP),        { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP),        tex_alphaop         }, WINED3D_GL_EXT_NONE             },
5548     { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG1),      { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5549     { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG2),      { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5550     { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG0),      { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5551     { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG0),      { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5552     { STATE_TEXTURESTAGE(7, WINED3D_TSS_RESULT_ARG),      { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5553     { STATE_TEXTURESTAGE(7, WINED3D_TSS_CONSTANT),        { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL                }, WINED3D_GL_EXT_NONE             },
5554     { STATE_PIXELSHADER,                                  { STATE_PIXELSHADER,                                  apply_pixelshader   }, WINED3D_GL_EXT_NONE             },
5555     { STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE),           { STATE_PIXELSHADER,                                  NULL                }, WINED3D_GL_EXT_NONE             },
5556     { STATE_RENDER(WINED3D_RS_TEXTUREFACTOR),             { STATE_RENDER(WINED3D_RS_TEXTUREFACTOR),             state_texfactor     }, WINED3D_GL_EXT_NONE             },
5557     { STATE_RENDER(WINED3D_RS_FOGCOLOR),                  { STATE_RENDER(WINED3D_RS_FOGCOLOR),                  state_fogcolor      }, WINED3D_GL_EXT_NONE             },
5558     { STATE_RENDER(WINED3D_RS_FOGDENSITY),                { STATE_RENDER(WINED3D_RS_FOGDENSITY),                state_fogdensity    }, WINED3D_GL_EXT_NONE             },
5559     { STATE_RENDER(WINED3D_RS_FOGENABLE),                 { STATE_RENDER(WINED3D_RS_FOGENABLE),                 state_fog_fragpart  }, WINED3D_GL_EXT_NONE             },
5560     { STATE_RENDER(WINED3D_RS_FOGTABLEMODE),              { STATE_RENDER(WINED3D_RS_FOGENABLE),                 NULL                }, WINED3D_GL_EXT_NONE             },
5561     { STATE_RENDER(WINED3D_RS_FOGVERTEXMODE),             { STATE_RENDER(WINED3D_RS_FOGENABLE),                 NULL                }, WINED3D_GL_EXT_NONE             },
5562     { STATE_RENDER(WINED3D_RS_FOGSTART),                  { STATE_RENDER(WINED3D_RS_FOGSTART),                  state_fogstartend   }, WINED3D_GL_EXT_NONE             },
5563     { STATE_RENDER(WINED3D_RS_FOGEND),                    { STATE_RENDER(WINED3D_RS_FOGSTART),                  NULL                }, WINED3D_GL_EXT_NONE             },
5564     { STATE_SAMPLER(0),                                   { STATE_SAMPLER(0),                                   sampler_texdim      }, WINED3D_GL_EXT_NONE             },
5565     { STATE_SAMPLER(1),                                   { STATE_SAMPLER(1),                                   sampler_texdim      }, WINED3D_GL_EXT_NONE             },
5566     { STATE_SAMPLER(2),                                   { STATE_SAMPLER(2),                                   sampler_texdim      }, WINED3D_GL_EXT_NONE             },
5567     { STATE_SAMPLER(3),                                   { STATE_SAMPLER(3),                                   sampler_texdim      }, WINED3D_GL_EXT_NONE             },
5568     { STATE_SAMPLER(4),                                   { STATE_SAMPLER(4),                                   sampler_texdim      }, WINED3D_GL_EXT_NONE             },
5569     { STATE_SAMPLER(5),                                   { STATE_SAMPLER(5),                                   sampler_texdim      }, WINED3D_GL_EXT_NONE             },
5570     { STATE_SAMPLER(6),                                   { STATE_SAMPLER(6),                                   sampler_texdim      }, WINED3D_GL_EXT_NONE             },
5571     { STATE_SAMPLER(7),                                   { STATE_SAMPLER(7),                                   sampler_texdim      }, WINED3D_GL_EXT_NONE             },
5572     {0 /* Terminate */,                                   { 0,                                                  0                   }, WINED3D_GL_EXT_NONE             },
5573 };
5574
5575 /* Context activation and GL locking are done by the caller. */
5576 static void ffp_enable(BOOL enable) {}
5577
5578 static void ffp_fragment_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps)
5579 {
5580     caps->PrimitiveMiscCaps = 0;
5581     caps->TextureOpCaps = WINED3DTEXOPCAPS_ADD
5582             | WINED3DTEXOPCAPS_ADDSIGNED
5583             | WINED3DTEXOPCAPS_ADDSIGNED2X
5584             | WINED3DTEXOPCAPS_MODULATE
5585             | WINED3DTEXOPCAPS_MODULATE2X
5586             | WINED3DTEXOPCAPS_MODULATE4X
5587             | WINED3DTEXOPCAPS_SELECTARG1
5588             | WINED3DTEXOPCAPS_SELECTARG2
5589             | WINED3DTEXOPCAPS_DISABLE;
5590
5591     if (gl_info->supported[ARB_TEXTURE_ENV_COMBINE]
5592             || gl_info->supported[EXT_TEXTURE_ENV_COMBINE]
5593             || gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
5594     {
5595         caps->TextureOpCaps |= WINED3DTEXOPCAPS_BLENDDIFFUSEALPHA
5596                 | WINED3DTEXOPCAPS_BLENDTEXTUREALPHA
5597                 | WINED3DTEXOPCAPS_BLENDFACTORALPHA
5598                 | WINED3DTEXOPCAPS_BLENDCURRENTALPHA
5599                 | WINED3DTEXOPCAPS_LERP
5600                 | WINED3DTEXOPCAPS_SUBTRACT;
5601     }
5602     if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3]
5603             || gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
5604     {
5605         caps->TextureOpCaps |= WINED3DTEXOPCAPS_ADDSMOOTH
5606                 | WINED3DTEXOPCAPS_MULTIPLYADD
5607                 | WINED3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR
5608                 | WINED3DTEXOPCAPS_MODULATECOLOR_ADDALPHA
5609                 | WINED3DTEXOPCAPS_BLENDTEXTUREALPHAPM;
5610     }
5611     if (gl_info->supported[ARB_TEXTURE_ENV_DOT3])
5612         caps->TextureOpCaps |= WINED3DTEXOPCAPS_DOTPRODUCT3;
5613
5614     caps->MaxTextureBlendStages = gl_info->limits.textures;
5615     caps->MaxSimultaneousTextures = gl_info->limits.textures;
5616 }
5617
5618 static HRESULT ffp_fragment_alloc(struct wined3d_device *device) { return WINED3D_OK; }
5619 static void ffp_fragment_free(struct wined3d_device *device) {}
5620 static BOOL ffp_color_fixup_supported(struct color_fixup_desc fixup)
5621 {
5622     if (TRACE_ON(d3d))
5623     {
5624         TRACE("Checking support for fixup:\n");
5625         dump_color_fixup_desc(fixup);
5626     }
5627
5628     /* We only support identity conversions. */
5629     if (is_identity_fixup(fixup))
5630     {
5631         TRACE("[OK]\n");
5632         return TRUE;
5633     }
5634
5635     TRACE("[FAILED]\n");
5636     return FALSE;
5637 }
5638
5639 const struct fragment_pipeline ffp_fragment_pipeline = {
5640     ffp_enable,
5641     ffp_fragment_get_caps,
5642     ffp_fragment_alloc,
5643     ffp_fragment_free,
5644     ffp_color_fixup_supported,
5645     ffp_fragmentstate_template,
5646     FALSE /* we cannot disable projected textures. The vertex pipe has to do it */
5647 };
5648
5649 static unsigned int num_handlers(const APPLYSTATEFUNC *funcs)
5650 {
5651     unsigned int i;
5652     for(i = 0; funcs[i]; i++);
5653     return i;
5654 }
5655
5656 static void multistate_apply_2(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
5657 {
5658     context->swapchain->device->multistate_funcs[state_id][0](context, state, state_id);
5659     context->swapchain->device->multistate_funcs[state_id][1](context, state, state_id);
5660 }
5661
5662 static void multistate_apply_3(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
5663 {
5664     context->swapchain->device->multistate_funcs[state_id][0](context, state, state_id);
5665     context->swapchain->device->multistate_funcs[state_id][1](context, state, state_id);
5666     context->swapchain->device->multistate_funcs[state_id][2](context, state, state_id);
5667 }
5668
5669 static void prune_invalid_states(struct StateEntry *state_table, const struct wined3d_gl_info *gl_info)
5670 {
5671     unsigned int start, last, i;
5672
5673     start = STATE_TEXTURESTAGE(gl_info->limits.texture_stages, 0);
5674     last = STATE_TEXTURESTAGE(MAX_TEXTURES - 1, WINED3D_HIGHEST_TEXTURE_STATE);
5675     for (i = start; i <= last; ++i)
5676     {
5677         state_table[i].representative = 0;
5678         state_table[i].apply = state_undefined;
5679     }
5680
5681     start = STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + gl_info->limits.texture_stages);
5682     last = STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + MAX_TEXTURES - 1);
5683     for (i = start; i <= last; ++i)
5684     {
5685         state_table[i].representative = 0;
5686         state_table[i].apply = state_undefined;
5687     }
5688
5689     start = STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(gl_info->limits.blends));
5690     last = STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255));
5691     for (i = start; i <= last; ++i)
5692     {
5693         state_table[i].representative = 0;
5694         state_table[i].apply = state_undefined;
5695     }
5696 }
5697
5698 static void validate_state_table(struct StateEntry *state_table)
5699 {
5700     static const struct
5701     {
5702         DWORD first;
5703         DWORD last;
5704     }
5705     rs_holes[] =
5706     {
5707         {  1,   1},
5708         {  3,   3},
5709         { 17,  18},
5710         { 21,  21},
5711         { 42,  45},
5712         { 47,  47},
5713         { 61, 127},
5714         {149, 150},
5715         {169, 169},
5716         {177, 177},
5717         {196, 197},
5718         {  0,   0},
5719     };
5720     static const DWORD simple_states[] =
5721     {
5722         STATE_MATERIAL,
5723         STATE_VDECL,
5724         STATE_STREAMSRC,
5725         STATE_INDEXBUFFER,
5726         STATE_VERTEXSHADERCONSTANT,
5727         STATE_PIXELSHADERCONSTANT,
5728         STATE_VSHADER,
5729         STATE_PIXELSHADER,
5730         STATE_VIEWPORT,
5731         STATE_SCISSORRECT,
5732         STATE_FRONTFACE,
5733         STATE_POINTSPRITECOORDORIGIN,
5734         STATE_BASEVERTEXINDEX,
5735         STATE_FRAMEBUFFER
5736     };
5737     unsigned int i, current;
5738
5739     for (i = STATE_RENDER(1), current = 0; i <= STATE_RENDER(WINEHIGHEST_RENDER_STATE); ++i)
5740     {
5741         if (!rs_holes[current].first || i < STATE_RENDER(rs_holes[current].first))
5742         {
5743             if (!state_table[i].representative)
5744                 ERR("State %s (%#x) should have a representative.\n", debug_d3dstate(i), i);
5745         }
5746         else if (state_table[i].representative)
5747             ERR("State %s (%#x) shouldn't have a representative.\n", debug_d3dstate(i), i);
5748
5749         if (i == STATE_RENDER(rs_holes[current].last)) ++current;
5750     }
5751
5752     for (i = 0; i < sizeof(simple_states) / sizeof(*simple_states); ++i)
5753     {
5754         if (!state_table[simple_states[i]].representative)
5755             ERR("State %s (%#x) should have a representative.\n",
5756                     debug_d3dstate(simple_states[i]), simple_states[i]);
5757     }
5758
5759     for (i = 0; i < STATE_HIGHEST + 1; ++i)
5760     {
5761         DWORD rep = state_table[i].representative;
5762         if (rep)
5763         {
5764             if (state_table[rep].representative != rep)
5765             {
5766                 ERR("State %s (%#x) has invalid representative %s (%#x).\n",
5767                         debug_d3dstate(i), i, debug_d3dstate(rep), rep);
5768                 state_table[i].representative = 0;
5769             }
5770
5771             if (rep != i)
5772             {
5773                 if (state_table[i].apply)
5774                     ERR("State %s (%#x) has both a handler and representative.\n", debug_d3dstate(i), i);
5775             }
5776             else if (!state_table[i].apply)
5777             {
5778                 ERR("Self representing state %s (%#x) has no handler.\n", debug_d3dstate(i), i);
5779             }
5780         }
5781     }
5782 }
5783
5784 HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_multistate_funcs,
5785         const struct wined3d_gl_info *gl_info, const struct StateEntryTemplate *vertex,
5786         const struct fragment_pipeline *fragment, const struct StateEntryTemplate *misc)
5787 {
5788     unsigned int i, type, handlers;
5789     APPLYSTATEFUNC multistate_funcs[STATE_HIGHEST + 1][3];
5790     const struct StateEntryTemplate *cur;
5791     BOOL set[STATE_HIGHEST + 1];
5792
5793     memset(multistate_funcs, 0, sizeof(multistate_funcs));
5794
5795     for(i = 0; i < STATE_HIGHEST + 1; i++) {
5796         StateTable[i].representative = 0;
5797         StateTable[i].apply = state_undefined;
5798     }
5799
5800     for(type = 0; type < 3; type++) {
5801         /* This switch decides the order in which the states are applied */
5802         switch(type) {
5803             case 0: cur = misc; break;
5804             case 1: cur = fragment->states; break;
5805             case 2: cur = vertex; break;
5806             default: cur = NULL; /* Stupid compiler */
5807         }
5808         if(!cur) continue;
5809
5810         /* GL extension filtering should not prevent multiple handlers being applied from different
5811          * pipeline parts
5812          */
5813         memset(set, 0, sizeof(set));
5814
5815         for(i = 0; cur[i].state; i++) {
5816             APPLYSTATEFUNC *funcs_array;
5817
5818             /* Only use the first matching state with the available extension from one template.
5819              * e.g.
5820              * {D3DRS_FOOBAR, {D3DRS_FOOBAR, func1}, XYZ_FANCY},
5821              * {D3DRS_FOOBAR, {D3DRS_FOOBAR, func2}, 0        }
5822              *
5823              * if GL_XYZ_fancy is supported, ignore the 2nd line
5824              */
5825             if(set[cur[i].state]) continue;
5826             /* Skip state lines depending on unsupported extensions */
5827             if (!gl_info->supported[cur[i].extension]) continue;
5828             set[cur[i].state] = TRUE;
5829             /* In some cases having an extension means that nothing has to be
5830              * done for a state, e.g. if GL_ARB_texture_non_power_of_two is
5831              * supported, the texture coordinate fixup can be ignored. If the
5832              * apply function is used, mark the state set(done above) to prevent
5833              * applying later lines, but do not record anything in the state
5834              * table
5835              */
5836             if (!cur[i].content.representative) continue;
5837
5838             handlers = num_handlers(multistate_funcs[cur[i].state]);
5839             multistate_funcs[cur[i].state][handlers] = cur[i].content.apply;
5840             switch(handlers) {
5841                 case 0:
5842                     StateTable[cur[i].state].apply = cur[i].content.apply;
5843                     break;
5844                 case 1:
5845                     StateTable[cur[i].state].apply = multistate_apply_2;
5846                     dev_multistate_funcs[cur[i].state] = HeapAlloc(GetProcessHeap(),
5847                                                                    0,
5848                                                                    sizeof(**dev_multistate_funcs) * 2);
5849                     if (!dev_multistate_funcs[cur[i].state]) {
5850                         goto out_of_mem;
5851                     }
5852
5853                     dev_multistate_funcs[cur[i].state][0] = multistate_funcs[cur[i].state][0];
5854                     dev_multistate_funcs[cur[i].state][1] = multistate_funcs[cur[i].state][1];
5855                     break;
5856                 case 2:
5857                     StateTable[cur[i].state].apply = multistate_apply_3;
5858                     funcs_array = HeapReAlloc(GetProcessHeap(),
5859                                               0,
5860                                               dev_multistate_funcs[cur[i].state],
5861                                               sizeof(**dev_multistate_funcs) * 3);
5862                     if (!funcs_array) {
5863                         goto out_of_mem;
5864                     }
5865
5866                     dev_multistate_funcs[cur[i].state] = funcs_array;
5867                     dev_multistate_funcs[cur[i].state][2] = multistate_funcs[cur[i].state][2];
5868                     break;
5869                 default:
5870                     ERR("Unexpected amount of state handlers for state %u: %u\n",
5871                         cur[i].state, handlers + 1);
5872             }
5873
5874             if(StateTable[cur[i].state].representative &&
5875             StateTable[cur[i].state].representative != cur[i].content.representative) {
5876                 FIXME("State %u has different representatives in different pipeline parts\n",
5877                     cur[i].state);
5878             }
5879             StateTable[cur[i].state].representative = cur[i].content.representative;
5880         }
5881     }
5882
5883     prune_invalid_states(StateTable, gl_info);
5884     validate_state_table(StateTable);
5885
5886     return WINED3D_OK;
5887
5888 out_of_mem:
5889     for (i = 0; i <= STATE_HIGHEST; ++i) {
5890         HeapFree(GetProcessHeap(), 0, dev_multistate_funcs[i]);
5891     }
5892
5893     memset(dev_multistate_funcs, 0, (STATE_HIGHEST + 1)*sizeof(*dev_multistate_funcs));
5894
5895     return E_OUTOFMEMORY;
5896 }