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