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