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