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