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