uxtheme: Remove unused variable.
[wine] / dlls / wined3d / state.c
1 /*
2  * Direct3D state management
3  *
4  * Copyright 2002 Lionel Ulmer
5  * Copyright 2002-2005 Jason Edmeades
6  * Copyright 2003-2004 Raphael Junqueira
7  * Copyright 2004 Christian Costa
8  * Copyright 2005 Oliver Stieber
9  * Copyright 2006 Henri Verbeet
10  * Copyright 2006-2008 Stefan Dösinger for CodeWeavers
11  * Copyright 2009-2011 Henri Verbeet for CodeWeavers
12  *
13  * This library is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU Lesser General Public
15  * License as published by the Free Software Foundation; either
16  * version 2.1 of the License, or (at your option) any later version.
17  *
18  * This library is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21  * Lesser General Public License for more details.
22  *
23  * You should have received a copy of the GNU Lesser General Public
24  * License along with this library; if not, write to the Free Software
25  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
26  */
27
28 #include "config.h"
29 #include "wine/port.h"
30
31 #include <stdio.h>
32 #ifdef HAVE_FLOAT_H
33 # include <float.h>
34 #endif
35
36 #include "wined3d_private.h"
37
38 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
39 WINE_DECLARE_DEBUG_CHANNEL(d3d_shader);
40
41 /* GL locking for state handlers is done by the caller. */
42
43 static void state_undefined(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
44 {
45     ERR("Undefined state.\n");
46 }
47
48 static void state_nop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
49 {
50     TRACE("%s: nop in current pipe config.\n", debug_d3dstate(state_id));
51 }
52
53 static void state_fillmode(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
54 {
55     enum wined3d_fill_mode mode = state->render_states[WINED3D_RS_FILLMODE];
56     const struct wined3d_gl_info *gl_info = context->gl_info;
57
58     switch (mode)
59     {
60         case WINED3D_FILL_POINT:
61             gl_info->gl_ops.gl.p_glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
62             checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_POINT)");
63             break;
64         case WINED3D_FILL_WIREFRAME:
65             gl_info->gl_ops.gl.p_glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
66             checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)");
67             break;
68         case WINED3D_FILL_SOLID:
69             gl_info->gl_ops.gl.p_glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
70             checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)");
71             break;
72         default:
73             FIXME("Unrecognized fill mode %#x.\n", mode);
74     }
75 }
76
77 static void state_lighting(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
78 {
79     const struct wined3d_gl_info *gl_info = context->gl_info;
80
81     /* Lighting is not enabled if transformed vertices are drawn, but lighting
82      * does not affect the stream sources, so it is not grouped for
83      * performance reasons. This state reads the decoded vertex declaration,
84      * so if it is dirty don't do anything. The vertex declaration applying
85      * function calls this function for updating. */
86     if (isStateDirty(context, STATE_VDECL))
87         return;
88
89     if (state->render_states[WINED3D_RS_LIGHTING]
90             && !context->swapchain->device->strided_streams.position_transformed)
91     {
92         gl_info->gl_ops.gl.p_glEnable(GL_LIGHTING);
93         checkGLcall("glEnable GL_LIGHTING");
94     }
95     else
96     {
97         gl_info->gl_ops.gl.p_glDisable(GL_LIGHTING);
98         checkGLcall("glDisable GL_LIGHTING");
99     }
100 }
101
102 static void state_zenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
103 {
104     enum wined3d_depth_buffer_type zenable = state->render_states[WINED3D_RS_ZENABLE];
105     const struct wined3d_gl_info *gl_info = context->gl_info;
106     static UINT once;
107
108     /* No z test without depth stencil buffers */
109     if (!state->fb->depth_stencil)
110     {
111         TRACE("No Z buffer - disabling depth test\n");
112         zenable = WINED3D_ZB_FALSE;
113     }
114
115     switch (zenable)
116     {
117         case WINED3D_ZB_FALSE:
118             gl_info->gl_ops.gl.p_glDisable(GL_DEPTH_TEST);
119             checkGLcall("glDisable GL_DEPTH_TEST");
120             break;
121         case WINED3D_ZB_TRUE:
122             gl_info->gl_ops.gl.p_glEnable(GL_DEPTH_TEST);
123             checkGLcall("glEnable GL_DEPTH_TEST");
124             break;
125         case WINED3D_ZB_USEW:
126             gl_info->gl_ops.gl.p_glEnable(GL_DEPTH_TEST);
127             checkGLcall("glEnable GL_DEPTH_TEST");
128             FIXME("W buffer is not well handled\n");
129             break;
130         default:
131             FIXME("Unrecognized depth buffer type %#x.\n", zenable);
132             break;
133     }
134
135     if (context->gl_info->supported[ARB_DEPTH_CLAMP])
136     {
137         if (!zenable && context->swapchain->device->strided_streams.position_transformed)
138         {
139             gl_info->gl_ops.gl.p_glEnable(GL_DEPTH_CLAMP);
140             checkGLcall("glEnable(GL_DEPTH_CLAMP)");
141         }
142         else
143         {
144             gl_info->gl_ops.gl.p_glDisable(GL_DEPTH_CLAMP);
145             checkGLcall("glDisable(GL_DEPTH_CLAMP)");
146         }
147     }
148     else if (!zenable && !once++)
149         FIXME("Z buffer disabled, but ARB_depth_clamp isn't supported.\n");
150 }
151
152 static void state_cullmode(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
153 {
154     const struct wined3d_gl_info *gl_info = context->gl_info;
155
156     /* glFrontFace() is set in context.c at context init and on an
157      * offscreen / onscreen rendering switch. */
158     switch (state->render_states[WINED3D_RS_CULLMODE])
159     {
160         case WINED3D_CULL_NONE:
161             gl_info->gl_ops.gl.p_glDisable(GL_CULL_FACE);
162             checkGLcall("glDisable GL_CULL_FACE");
163             break;
164         case WINED3D_CULL_CW:
165             gl_info->gl_ops.gl.p_glEnable(GL_CULL_FACE);
166             checkGLcall("glEnable GL_CULL_FACE");
167             gl_info->gl_ops.gl.p_glCullFace(GL_FRONT);
168             checkGLcall("glCullFace(GL_FRONT)");
169             break;
170         case WINED3D_CULL_CCW:
171             gl_info->gl_ops.gl.p_glEnable(GL_CULL_FACE);
172             checkGLcall("glEnable GL_CULL_FACE");
173             gl_info->gl_ops.gl.p_glCullFace(GL_BACK);
174             checkGLcall("glCullFace(GL_BACK)");
175             break;
176         default:
177             FIXME("Unrecognized cull mode %#x.\n",
178                     state->render_states[WINED3D_RS_CULLMODE]);
179     }
180 }
181
182 static void state_shademode(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
183 {
184     const struct wined3d_gl_info *gl_info = context->gl_info;
185
186     switch (state->render_states[WINED3D_RS_SHADEMODE])
187     {
188         case WINED3D_SHADE_FLAT:
189             gl_info->gl_ops.gl.p_glShadeModel(GL_FLAT);
190             checkGLcall("glShadeModel(GL_FLAT)");
191             break;
192         case WINED3D_SHADE_GOURAUD:
193             gl_info->gl_ops.gl.p_glShadeModel(GL_SMOOTH);
194             checkGLcall("glShadeModel(GL_SMOOTH)");
195             break;
196         case WINED3D_SHADE_PHONG:
197             FIXME("WINED3D_SHADE_PHONG isn't supported.\n");
198             break;
199         default:
200             FIXME("Unrecognized shade mode %#x.\n",
201                     state->render_states[WINED3D_RS_SHADEMODE]);
202     }
203 }
204
205 static void state_ditherenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
206 {
207     const struct wined3d_gl_info *gl_info = context->gl_info;
208
209     if (state->render_states[WINED3D_RS_DITHERENABLE])
210     {
211         gl_info->gl_ops.gl.p_glEnable(GL_DITHER);
212         checkGLcall("glEnable GL_DITHER");
213     }
214     else
215     {
216         gl_info->gl_ops.gl.p_glDisable(GL_DITHER);
217         checkGLcall("glDisable GL_DITHER");
218     }
219 }
220
221 static void state_zwritenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
222 {
223     const struct wined3d_gl_info *gl_info = context->gl_info;
224
225     if (state->render_states[WINED3D_RS_ZWRITEENABLE])
226     {
227         gl_info->gl_ops.gl.p_glDepthMask(1);
228         checkGLcall("glDepthMask(1)");
229     }
230     else
231     {
232         gl_info->gl_ops.gl.p_glDepthMask(0);
233         checkGLcall("glDepthMask(0)");
234     }
235 }
236
237 static GLenum gl_compare_func(enum wined3d_cmp_func f)
238 {
239     switch (f)
240     {
241         case WINED3D_CMP_NEVER:
242             return GL_NEVER;
243         case WINED3D_CMP_LESS:
244             return GL_LESS;
245         case WINED3D_CMP_EQUAL:
246             return GL_EQUAL;
247         case WINED3D_CMP_LESSEQUAL:
248             return GL_LEQUAL;
249         case WINED3D_CMP_GREATER:
250             return GL_GREATER;
251         case WINED3D_CMP_NOTEQUAL:
252             return GL_NOTEQUAL;
253         case WINED3D_CMP_GREATEREQUAL:
254             return GL_GEQUAL;
255         case WINED3D_CMP_ALWAYS:
256             return GL_ALWAYS;
257         default:
258             FIXME("Unrecognized compare function %#x.\n", f);
259             return GL_NONE;
260     }
261 }
262
263 static void state_zfunc(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
264 {
265     GLenum depth_func = gl_compare_func(state->render_states[WINED3D_RS_ZFUNC]);
266     const struct wined3d_gl_info *gl_info = context->gl_info;
267
268     if (!depth_func) return;
269
270     if (depth_func == GL_EQUAL || depth_func == GL_NOTEQUAL)
271     {
272         static BOOL once;
273         /* There are a few issues with this: First, our inability to
274          * select a proper Z depth, most of the time we're stuck with
275          * D24S8, even if the app selects D32 or D16. There seem to be
276          * some other precision problems which have to be debugged to
277          * make NOTEQUAL and EQUAL work properly. */
278         if (!once)
279         {
280             once = TRUE;
281             FIXME("D3DCMP_NOTEQUAL and D3DCMP_EQUAL do not work correctly yet.\n");
282         }
283     }
284
285     gl_info->gl_ops.gl.p_glDepthFunc(depth_func);
286     checkGLcall("glDepthFunc");
287 }
288
289 static void state_ambient(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
290 {
291     const struct wined3d_gl_info *gl_info = context->gl_info;
292     float col[4];
293
294     D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_AMBIENT], col);
295     TRACE("Setting ambient to (%f,%f,%f,%f)\n", col[0], col[1], col[2], col[3]);
296     gl_info->gl_ops.gl.p_glLightModelfv(GL_LIGHT_MODEL_AMBIENT, col);
297     checkGLcall("glLightModel for MODEL_AMBIENT");
298 }
299
300 static void state_blendop_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
301 {
302     WARN("Unsupported in local OpenGL implementation: glBlendEquation\n");
303 }
304
305 static GLenum gl_blend_op(enum wined3d_blend_op op)
306 {
307     switch (op)
308     {
309         case WINED3D_BLEND_OP_ADD:
310             return GL_FUNC_ADD_EXT;
311         case WINED3D_BLEND_OP_SUBTRACT:
312             return GL_FUNC_SUBTRACT_EXT;
313         case WINED3D_BLEND_OP_REVSUBTRACT:
314             return GL_FUNC_REVERSE_SUBTRACT_EXT;
315         case WINED3D_BLEND_OP_MIN:
316             return GL_MIN_EXT;
317         case WINED3D_BLEND_OP_MAX:
318             return GL_MAX_EXT;
319         default:
320             FIXME("Unhandled blend op %#x.\n", op);
321             return GL_NONE;
322     }
323 }
324
325 static void state_blendop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
326 {
327     const struct wined3d_gl_info *gl_info = context->gl_info;
328     GLenum blend_equation_alpha = GL_FUNC_ADD_EXT;
329     GLenum blend_equation = GL_FUNC_ADD_EXT;
330
331     /* BLENDOPALPHA requires GL_EXT_blend_equation_separate, so make sure it is around */
332     if (state->render_states[WINED3D_RS_BLENDOPALPHA]
333             && !gl_info->supported[EXT_BLEND_EQUATION_SEPARATE])
334     {
335         WARN("Unsupported in local OpenGL implementation: glBlendEquationSeparateEXT\n");
336         return;
337     }
338
339     blend_equation = gl_blend_op(state->render_states[WINED3D_RS_BLENDOP]);
340     blend_equation_alpha = gl_blend_op(state->render_states[WINED3D_RS_BLENDOPALPHA]);
341     TRACE("blend_equation %#x, blend_equation_alpha %#x.\n", blend_equation, blend_equation_alpha);
342
343     if (state->render_states[WINED3D_RS_SEPARATEALPHABLENDENABLE])
344     {
345         GL_EXTCALL(glBlendEquationSeparateEXT(blend_equation, blend_equation_alpha));
346         checkGLcall("glBlendEquationSeparateEXT");
347     }
348     else
349     {
350         GL_EXTCALL(glBlendEquationEXT(blend_equation));
351         checkGLcall("glBlendEquation");
352     }
353 }
354
355 static GLenum gl_blend_factor(enum wined3d_blend factor, const struct wined3d_format *dst_format)
356 {
357     switch (factor)
358     {
359         case WINED3D_BLEND_ZERO:
360             return GL_ZERO;
361         case WINED3D_BLEND_ONE:
362             return GL_ONE;
363         case WINED3D_BLEND_SRCCOLOR:
364             return GL_SRC_COLOR;
365         case WINED3D_BLEND_INVSRCCOLOR:
366             return GL_ONE_MINUS_SRC_COLOR;
367         case WINED3D_BLEND_SRCALPHA:
368             return GL_SRC_ALPHA;
369         case WINED3D_BLEND_INVSRCALPHA:
370             return GL_ONE_MINUS_SRC_ALPHA;
371         case WINED3D_BLEND_DESTCOLOR:
372             return GL_DST_COLOR;
373         case WINED3D_BLEND_INVDESTCOLOR:
374             return GL_ONE_MINUS_DST_COLOR;
375         /* To compensate for the lack of format switching with backbuffer
376          * offscreen rendering, and with onscreen rendering, we modify the
377          * alpha test parameters for (INV)DESTALPHA if the render target
378          * doesn't support alpha blending. A nonexistent alpha channel
379          * returns 1.0, so WINED3D_BLEND_DESTALPHA becomes GL_ONE, and
380          * WINED3D_BLEND_INVDESTALPHA becomes GL_ZERO. */
381         case WINED3D_BLEND_DESTALPHA:
382             return dst_format->alpha_size ? GL_DST_ALPHA : GL_ONE;
383         case WINED3D_BLEND_INVDESTALPHA:
384             return dst_format->alpha_size ? GL_ONE_MINUS_DST_ALPHA : GL_ZERO;
385         case WINED3D_BLEND_SRCALPHASAT:
386             return GL_SRC_ALPHA_SATURATE;
387         case WINED3D_BLEND_BLENDFACTOR:
388             return GL_CONSTANT_COLOR_EXT;
389         case WINED3D_BLEND_INVBLENDFACTOR:
390             return GL_ONE_MINUS_CONSTANT_COLOR_EXT;
391         default:
392             FIXME("Unhandled blend factor %#x.\n", factor);
393             return GL_NONE;
394     }
395 }
396
397 static void state_blend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
398 {
399     const struct wined3d_surface *target = state->fb->render_targets[0];
400     const struct wined3d_gl_info *gl_info = context->gl_info;
401     GLenum srcBlend, dstBlend;
402     enum wined3d_blend d3d_blend;
403
404     /* According to the red book, GL_LINE_SMOOTH needs GL_BLEND with specific
405      * blending parameters to work. */
406     if (state->render_states[WINED3D_RS_ALPHABLENDENABLE]
407             || state->render_states[WINED3D_RS_EDGEANTIALIAS]
408             || state->render_states[WINED3D_RS_ANTIALIASEDLINEENABLE])
409     {
410         /* Disable blending in all cases even without pixelshaders.
411          * With blending on we could face a big performance penalty.
412          * The d3d9 visual test confirms the behavior. */
413         if (context->render_offscreen
414                 && !(target->resource.format->flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING))
415         {
416             gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
417             checkGLcall("glDisable GL_BLEND");
418             return;
419         }
420         else
421         {
422             gl_info->gl_ops.gl.p_glEnable(GL_BLEND);
423             checkGLcall("glEnable GL_BLEND");
424         }
425     }
426     else
427     {
428         gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
429         checkGLcall("glDisable GL_BLEND");
430         /* Nothing more to do - get out */
431         return;
432     };
433
434     /* WINED3D_BLEND_BOTHSRCALPHA and WINED3D_BLEND_BOTHINVSRCALPHA are legacy
435      * source blending values which are still valid up to d3d9. They should
436      * not occur as dest blend values. */
437     d3d_blend = state->render_states[WINED3D_RS_SRCBLEND];
438     if (d3d_blend == WINED3D_BLEND_BOTHSRCALPHA)
439     {
440         srcBlend = GL_SRC_ALPHA;
441         dstBlend = GL_ONE_MINUS_SRC_ALPHA;
442     }
443     else if (d3d_blend == WINED3D_BLEND_BOTHINVSRCALPHA)
444     {
445         srcBlend = GL_ONE_MINUS_SRC_ALPHA;
446         dstBlend = GL_SRC_ALPHA;
447     }
448     else
449     {
450         srcBlend = gl_blend_factor(d3d_blend, target->resource.format);
451         dstBlend = gl_blend_factor(state->render_states[WINED3D_RS_DESTBLEND],
452                 target->resource.format);
453     }
454
455     if (state->render_states[WINED3D_RS_EDGEANTIALIAS]
456             || state->render_states[WINED3D_RS_ANTIALIASEDLINEENABLE])
457     {
458         gl_info->gl_ops.gl.p_glEnable(GL_LINE_SMOOTH);
459         checkGLcall("glEnable(GL_LINE_SMOOTH)");
460         if (srcBlend != GL_SRC_ALPHA)
461             WARN("WINED3D_RS_EDGEANTIALIAS enabled, but unexpected src blending param.\n");
462         if (dstBlend != GL_ONE_MINUS_SRC_ALPHA && dstBlend != GL_ONE)
463             WARN("WINED3D_RS_EDGEANTIALIAS enabled, but unexpected dst blending param.\n");
464     }
465     else
466     {
467         gl_info->gl_ops.gl.p_glDisable(GL_LINE_SMOOTH);
468         checkGLcall("glDisable(GL_LINE_SMOOTH)");
469     }
470
471     /* Re-apply BLENDOP(ALPHA) because of a possible SEPARATEALPHABLENDENABLE change */
472     if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_BLENDOP)))
473         state_blendop(context, state, STATE_RENDER(WINED3D_RS_BLENDOPALPHA));
474
475     if (state->render_states[WINED3D_RS_SEPARATEALPHABLENDENABLE])
476     {
477         GLenum srcBlendAlpha, dstBlendAlpha;
478
479         /* Separate alpha blending requires GL_EXT_blend_function_separate, so make sure it is around */
480         if (!context->gl_info->supported[EXT_BLEND_FUNC_SEPARATE])
481         {
482             WARN("Unsupported in local OpenGL implementation: glBlendFuncSeparateEXT\n");
483             return;
484         }
485
486         /* WINED3D_BLEND_BOTHSRCALPHA and WINED3D_BLEND_BOTHINVSRCALPHA are legacy
487          * source blending values which are still valid up to d3d9. They should
488          * not occur as dest blend values. */
489         d3d_blend = state->render_states[WINED3D_RS_SRCBLENDALPHA];
490         if (d3d_blend == WINED3D_BLEND_BOTHSRCALPHA)
491         {
492             srcBlendAlpha = GL_SRC_ALPHA;
493             dstBlendAlpha = GL_ONE_MINUS_SRC_ALPHA;
494         }
495         else if (d3d_blend == WINED3D_BLEND_BOTHINVSRCALPHA)
496         {
497             srcBlendAlpha = GL_ONE_MINUS_SRC_ALPHA;
498             dstBlendAlpha = GL_SRC_ALPHA;
499         }
500         else
501         {
502             srcBlendAlpha = gl_blend_factor(d3d_blend, target->resource.format);
503             dstBlendAlpha = gl_blend_factor(state->render_states[WINED3D_RS_DESTBLENDALPHA],
504                     target->resource.format);
505         }
506
507         GL_EXTCALL(glBlendFuncSeparateEXT(srcBlend, dstBlend, srcBlendAlpha, dstBlendAlpha));
508         checkGLcall("glBlendFuncSeparateEXT");
509     }
510     else
511     {
512         TRACE("glBlendFunc src=%x, dst=%x\n", srcBlend, dstBlend);
513         gl_info->gl_ops.gl.p_glBlendFunc(srcBlend, dstBlend);
514         checkGLcall("glBlendFunc");
515     }
516
517     /* Colorkey fixup for stage 0 alphaop depends on
518      * WINED3D_RS_ALPHABLENDENABLE state, so it may need updating. */
519     if (state->render_states[WINED3D_RS_COLORKEYENABLE])
520         context_apply_state(context, state, STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP));
521 }
522
523 static void state_blendfactor_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
524 {
525     WARN("Unsupported in local OpenGL implementation: glBlendColorEXT\n");
526 }
527
528 static void state_blendfactor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
529 {
530     const struct wined3d_gl_info *gl_info = context->gl_info;
531     float col[4];
532
533     TRACE("Setting blend factor to %#x.\n", state->render_states[WINED3D_RS_BLENDFACTOR]);
534
535     D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_BLENDFACTOR], col);
536     GL_EXTCALL(glBlendColorEXT (col[0],col[1],col[2],col[3]));
537     checkGLcall("glBlendColor");
538 }
539
540 static void state_alpha(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
541 {
542     const struct wined3d_gl_info *gl_info = context->gl_info;
543     int glParm = 0;
544     float ref;
545     BOOL enable_ckey = FALSE;
546
547     TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
548
549     /* Find out if the texture on the first stage has a ckey set
550      * The alpha state func reads the texture settings, even though alpha and texture are not grouped
551      * together. This is to avoid making a huge alpha+texture+texture stage+ckey block due to the hardly
552      * used WINED3D_RS_COLORKEYENABLE state(which is d3d <= 3 only). The texture function will call alpha
553      * in case it finds some texture+colorkeyenable combination which needs extra care.
554      */
555     if (state->textures[0])
556     {
557         struct wined3d_surface *surface = surface_from_resource(state->textures[0]->sub_resources[0]);
558
559         if (surface->CKeyFlags & WINEDDSD_CKSRCBLT)
560             enable_ckey = TRUE;
561     }
562
563     if (enable_ckey || context->last_was_ckey)
564         context_apply_state(context, state, STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP));
565     context->last_was_ckey = enable_ckey;
566
567     if (state->render_states[WINED3D_RS_ALPHATESTENABLE]
568             || (state->render_states[WINED3D_RS_COLORKEYENABLE] && enable_ckey))
569     {
570         gl_info->gl_ops.gl.p_glEnable(GL_ALPHA_TEST);
571         checkGLcall("glEnable GL_ALPHA_TEST");
572     }
573     else
574     {
575         gl_info->gl_ops.gl.p_glDisable(GL_ALPHA_TEST);
576         checkGLcall("glDisable GL_ALPHA_TEST");
577         /* Alpha test is disabled, don't bother setting the params - it will happen on the next
578          * enable call
579          */
580         return;
581     }
582
583     if (state->render_states[WINED3D_RS_COLORKEYENABLE] && enable_ckey)
584     {
585         glParm = GL_NOTEQUAL;
586         ref = 0.0f;
587     }
588     else
589     {
590         ref = ((float)state->render_states[WINED3D_RS_ALPHAREF]) / 255.0f;
591         glParm = gl_compare_func(state->render_states[WINED3D_RS_ALPHAFUNC]);
592     }
593     if (glParm)
594     {
595         gl_info->gl_ops.gl.p_glAlphaFunc(glParm, ref);
596         checkGLcall("glAlphaFunc");
597     }
598 }
599
600 static void shaderconstant(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
601 {
602     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->strided_streams.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->strided_streams.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
2632             default:
2633                 Handled = FALSE;
2634         }
2635         if (Handled)
2636         {
2637             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
2638             checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV");
2639
2640             return;
2641         }
2642     } /* GL_NV_texture_env_combine4 */
2643
2644     Handled = TRUE; /* Again, assume handled */
2645     switch (op) {
2646         case WINED3D_TOP_DISABLE: /* Only for alpha */
2647             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
2648             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2649             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
2650             checkGLcall("GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT");
2651             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
2652             checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA");
2653             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2654             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2655             break;
2656         case WINED3D_TOP_SELECT_ARG1:
2657             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
2658             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2659             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2660             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2661             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2662             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2663             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2664             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2665             break;
2666         case WINED3D_TOP_SELECT_ARG2:
2667             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
2668             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2669             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
2670             checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
2671             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
2672             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
2673             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2674             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2675             break;
2676         case WINED3D_TOP_MODULATE:
2677             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2678             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2679             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2680             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2681             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2682             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2683             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2684             checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2685             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2686             checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2687             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2688             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2689             break;
2690         case WINED3D_TOP_MODULATE_2X:
2691             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2692             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2693             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2694             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2695             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2696             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2697             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2698             checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2699             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2700             checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2701             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2702             checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2703             break;
2704         case WINED3D_TOP_MODULATE_4X:
2705             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2706             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2707             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2708             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2709             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2710             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2711             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2712             checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2713             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2714             checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2715             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
2716             checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
2717             break;
2718         case WINED3D_TOP_ADD:
2719             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2720             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2721             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2722             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2723             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2724             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2725             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2726             checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2727             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2728             checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2729             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2730             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2731             break;
2732         case WINED3D_TOP_ADD_SIGNED:
2733             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED);
2734             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED");
2735             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2736             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2737             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2738             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2739             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2740             checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2741             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2742             checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2743             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2744             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2745             break;
2746         case WINED3D_TOP_ADD_SIGNED_2X:
2747             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED);
2748             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED");
2749             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2750             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2751             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2752             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2753             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2754             checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2755             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2756             checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2757             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2758             checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2759             break;
2760         case WINED3D_TOP_SUBTRACT:
2761             if (gl_info->supported[ARB_TEXTURE_ENV_COMBINE])
2762             {
2763                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_SUBTRACT);
2764                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_SUBTRACT");
2765                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2766                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2767                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2768                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2769                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2770                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2771                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2772                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2773                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2774                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2775             } else {
2776                 FIXME("This version of opengl does not support GL_SUBTRACT\n");
2777             }
2778             break;
2779
2780         case WINED3D_TOP_BLEND_DIFFUSE_ALPHA:
2781             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
2782             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
2783             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2784             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2785             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2786             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2787             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2788             checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2789             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2790             checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2791             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_PRIMARY_COLOR);
2792             checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PRIMARY_COLOR");
2793             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2794             checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2795             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2796             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2797             break;
2798         case WINED3D_TOP_BLEND_TEXTURE_ALPHA:
2799             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
2800             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
2801             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2802             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2803             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2804             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2805             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2806             checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2807             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2808             checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2809             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_TEXTURE);
2810             checkGLcall("GL_TEXTURE_ENV, src2_target, GL_TEXTURE");
2811             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2812             checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2813             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2814             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2815             break;
2816         case WINED3D_TOP_BLEND_FACTOR_ALPHA:
2817             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
2818             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
2819             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2820             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2821             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2822             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2823             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2824             checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2825             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2826             checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2827             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_CONSTANT);
2828             checkGLcall("GL_TEXTURE_ENV, src2_target, GL_CONSTANT");
2829             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2830             checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2831             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2832             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2833             break;
2834         case WINED3D_TOP_BLEND_CURRENT_ALPHA:
2835             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
2836             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
2837             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2838             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2839             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2840             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2841             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2842             checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2843             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2844             checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2845             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_PREVIOUS);
2846             checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PREVIOUS");
2847             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2848             checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2849             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2850             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2851             break;
2852         case WINED3D_TOP_DOTPRODUCT3:
2853             if (gl_info->supported[ARB_TEXTURE_ENV_DOT3])
2854             {
2855                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB);
2856                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB");
2857             }
2858             else if (gl_info->supported[EXT_TEXTURE_ENV_DOT3])
2859             {
2860                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT);
2861                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT");
2862             } else {
2863                 FIXME("This version of opengl does not support GL_DOT3\n");
2864             }
2865             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2866             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2867             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2868             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2869             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2870             checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2871             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2872             checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2873             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2874             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2875             break;
2876         case WINED3D_TOP_LERP:
2877             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
2878             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
2879             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2880             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2881             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2882             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2883             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2884             checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2885             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2886             checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2887             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src3);
2888             checkGLcall("GL_TEXTURE_ENV, src2_target, src3");
2889             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr3);
2890             checkGLcall("GL_TEXTURE_ENV, opr2_target, opr3");
2891             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2892             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2893             break;
2894         case WINED3D_TOP_ADD_SMOOTH:
2895             if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2896             {
2897                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2898                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2899                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2900                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2901                 switch (opr1) {
2902                     case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2903                     case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2904                     case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2905                     case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2906                 }
2907                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2908                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2909                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2910                 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2911                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2912                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2913                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2914                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2915                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2916                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2917                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2918                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2919             } else
2920                 Handled = FALSE;
2921                 break;
2922         case WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM:
2923             if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2924             {
2925                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2926                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2927                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_TEXTURE);
2928                 checkGLcall("GL_TEXTURE_ENV, src0_target, GL_TEXTURE");
2929                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_ALPHA);
2930                 checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_APHA");
2931                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2932                 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2933                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2934                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2935                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2936                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2937                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2938                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2939                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2940                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2941             } else
2942                 Handled = FALSE;
2943                 break;
2944         case WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR:
2945             if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2946             {
2947                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2948                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2949                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2950                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2951                 switch (opr1) {
2952                     case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2953                     case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2954                     case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2955                     case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2956                 }
2957                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2958                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2959                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2960                 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2961                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2962                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2963                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2964                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2965                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2966                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2967                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2968                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2969             } else
2970                 Handled = FALSE;
2971                 break;
2972         case WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA:
2973             if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2974             {
2975                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2976                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2977                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2978                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2979                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2980                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2981                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2982                 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2983                 switch (opr1) {
2984                     case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2985                     case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2986                     case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2987                     case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2988                 }
2989                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
2990                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
2991                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2992                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2993                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2994                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2995                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2996                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2997             } else
2998                 Handled = FALSE;
2999                 break;
3000         case WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR:
3001             if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
3002             {
3003                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
3004                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
3005                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
3006                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
3007                 switch (opr1) {
3008                     case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
3009                     case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
3010                     case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
3011                     case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
3012                 }
3013                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
3014                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
3015                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
3016                 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
3017                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
3018                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
3019                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
3020                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
3021                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
3022                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
3023                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
3024                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
3025             } else
3026                 Handled = FALSE;
3027                 break;
3028         case WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA:
3029             if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
3030             {
3031                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
3032                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
3033                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
3034                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
3035                 switch (opr1) {
3036                     case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
3037                     case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
3038                     case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
3039                     case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
3040                 }
3041                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
3042                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
3043                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
3044                 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
3045                 switch (opr1) {
3046                     case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
3047                     case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
3048                     case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
3049                     case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
3050                 }
3051                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
3052                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
3053                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
3054                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
3055                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
3056                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
3057                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
3058                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
3059             } else
3060                 Handled = FALSE;
3061                 break;
3062         case WINED3D_TOP_MULTIPLY_ADD:
3063             if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
3064             {
3065                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
3066                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
3067                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
3068                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
3069                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
3070                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
3071                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src3);
3072                 checkGLcall("GL_TEXTURE_ENV, src1_target, src3");
3073                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr3);
3074                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr3");
3075                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
3076                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
3077                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
3078                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
3079                 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
3080                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
3081             } else
3082                 Handled = FALSE;
3083                 break;
3084         case WINED3D_TOP_BUMPENVMAP_LUMINANCE:
3085         case WINED3D_TOP_BUMPENVMAP:
3086             if (gl_info->supported[NV_TEXTURE_SHADER2])
3087             {
3088                 /* Technically texture shader support without register combiners is possible, but not expected to occur
3089                  * on real world cards, so for now a fixme should be enough
3090                  */
3091                 FIXME("Implement bump mapping with GL_NV_texture_shader in non register combiner path\n");
3092             }
3093         default:
3094             Handled = FALSE;
3095     }
3096
3097     if (Handled) {
3098         BOOL  combineOK = TRUE;
3099         if (gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
3100         {
3101             DWORD op2;
3102
3103             if (isAlpha)
3104                 op2 = state->texture_states[Stage][WINED3D_TSS_COLOR_OP];
3105             else
3106                 op2 = state->texture_states[Stage][WINED3D_TSS_ALPHA_OP];
3107
3108             /* Note: If COMBINE4 in effect can't go back to combine! */
3109             switch (op2)
3110             {
3111                 case WINED3D_TOP_ADD_SMOOTH:
3112                 case WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM:
3113                 case WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR:
3114                 case WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA:
3115                 case WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR:
3116                 case WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA:
3117                 case WINED3D_TOP_MULTIPLY_ADD:
3118                     /* Ignore those implemented in both cases */
3119                     switch (op)
3120                     {
3121                         case WINED3D_TOP_SELECT_ARG1:
3122                         case WINED3D_TOP_SELECT_ARG2:
3123                             combineOK = FALSE;
3124                             Handled   = FALSE;
3125                             break;
3126                         default:
3127                             FIXME("Can't use COMBINE4 and COMBINE together, thisop=%s, otherop=%s, isAlpha(%d)\n", debug_d3dtop(op), debug_d3dtop(op2), isAlpha);
3128                             return;
3129                     }
3130             }
3131         }
3132
3133         if (combineOK)
3134         {
3135             gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
3136             checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE");
3137
3138             return;
3139         }
3140     }
3141
3142     /* After all the extensions, if still unhandled, report fixme */
3143     FIXME("Unhandled texture operation %s\n", debug_d3dtop(op));
3144 }
3145
3146
3147 static void tex_colorop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3148 {
3149     DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3150     const struct wined3d_device *device = context->swapchain->device;
3151     BOOL tex_used = device->fixed_function_usage_map & (1 << stage);
3152     DWORD mapped_stage = device->texUnitMap[stage];
3153     const struct wined3d_gl_info *gl_info = context->gl_info;
3154
3155     TRACE("Setting color op for stage %d\n", stage);
3156
3157     /* Using a pixel shader? Don't care for anything here, the shader applying does it */
3158     if (use_ps(state)) return;
3159
3160     if (stage != mapped_stage) WARN("Using non 1:1 mapping: %d -> %d!\n", stage, mapped_stage);
3161
3162     if (mapped_stage != WINED3D_UNMAPPED_STAGE)
3163     {
3164         if (tex_used && mapped_stage >= gl_info->limits.textures)
3165         {
3166             FIXME("Attempt to enable unsupported stage!\n");
3167             return;
3168         }
3169         context_active_texture(context, gl_info, mapped_stage);
3170     }
3171
3172     if (stage >= state->lowest_disabled_stage)
3173     {
3174         TRACE("Stage disabled\n");
3175         if (mapped_stage != WINED3D_UNMAPPED_STAGE)
3176         {
3177             /* Disable everything here */
3178             gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
3179             checkGLcall("glDisable(GL_TEXTURE_2D)");
3180             gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
3181             checkGLcall("glDisable(GL_TEXTURE_3D)");
3182             if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3183             {
3184                 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3185                 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3186             }
3187             if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3188             {
3189                 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
3190                 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3191             }
3192         }
3193         /* All done */
3194         return;
3195     }
3196
3197     /* The sampler will also activate the correct texture dimensions, so no
3198      * need to do it here if the sampler for this stage is dirty. */
3199     if (!isStateDirty(context, STATE_SAMPLER(stage)) && tex_used)
3200         texture_activate_dimensions(state->textures[stage], gl_info);
3201
3202     set_tex_op(gl_info, state, FALSE, stage,
3203             state->texture_states[stage][WINED3D_TSS_COLOR_OP],
3204             state->texture_states[stage][WINED3D_TSS_COLOR_ARG1],
3205             state->texture_states[stage][WINED3D_TSS_COLOR_ARG2],
3206             state->texture_states[stage][WINED3D_TSS_COLOR_ARG0]);
3207 }
3208
3209 void tex_alphaop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3210 {
3211     DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3212     const struct wined3d_device *device = context->swapchain->device;
3213     BOOL tex_used = device->fixed_function_usage_map & (1 << stage);
3214     DWORD mapped_stage = device->texUnitMap[stage];
3215     const struct wined3d_gl_info *gl_info = context->gl_info;
3216     DWORD op, arg1, arg2, arg0;
3217
3218     TRACE("Setting alpha op for stage %d\n", stage);
3219     /* Do not care for enabled / disabled stages, just assign the settings. colorop disables / enables required stuff */
3220     if (mapped_stage != WINED3D_UNMAPPED_STAGE)
3221     {
3222         if (tex_used && mapped_stage >= gl_info->limits.textures)
3223         {
3224             FIXME("Attempt to enable unsupported stage!\n");
3225             return;
3226         }
3227         context_active_texture(context, gl_info, mapped_stage);
3228     }
3229
3230     op = state->texture_states[stage][WINED3D_TSS_ALPHA_OP];
3231     arg1 = state->texture_states[stage][WINED3D_TSS_ALPHA_ARG1];
3232     arg2 = state->texture_states[stage][WINED3D_TSS_ALPHA_ARG2];
3233     arg0 = state->texture_states[stage][WINED3D_TSS_ALPHA_ARG0];
3234
3235     if (state->render_states[WINED3D_RS_COLORKEYENABLE] && !stage && state->textures[0])
3236     {
3237         struct wined3d_texture *texture = state->textures[0];
3238         GLenum texture_dimensions = texture->target;
3239
3240         if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
3241         {
3242             struct wined3d_surface *surf = surface_from_resource(texture->sub_resources[0]);
3243
3244             if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format->alpha_size)
3245             {
3246                 /* Color keying needs to pass alpha values from the texture through to have the alpha test work
3247                  * properly. On the other hand applications can still use texture combiners apparently. This code
3248                  * takes care that apps cannot remove the texture's alpha channel entirely.
3249                  *
3250                  * The fixup is required for Prince of Persia 3D(prison bars), while Moto racer 2 requires
3251                  * D3DTOP_MODULATE to work on color keyed surfaces. Aliens vs Predator 1 uses color keyed textures
3252                  * and alpha component of diffuse color to draw things like translucent text and perform other
3253                  * blending effects.
3254                  *
3255                  * Aliens vs Predator 1 relies on diffuse alpha having an effect, so it cannot be ignored. To
3256                  * provide the behavior expected by the game, while emulating the colorkey, diffuse alpha must be
3257                  * modulated with texture alpha. OTOH, Moto racer 2 at some points sets alphaop/alphaarg to
3258                  * SELECTARG/CURRENT, yet puts garbage in diffuse alpha (zeroes). This works on native, because the
3259                  * game disables alpha test and alpha blending. Alpha test is overwritten by wine's for purposes of
3260                  * color-keying though, so this will lead to missing geometry if texture alpha is modulated (pixels
3261                  * fail alpha test). To get around this, ALPHABLENDENABLE state is checked: if the app enables alpha
3262                  * blending, it can be expected to provide meaningful values in diffuse alpha, so it should be
3263                  * modulated with texture alpha; otherwise, selecting diffuse alpha is ignored in favour of texture
3264                  * alpha.
3265                  *
3266                  * What to do with multitexturing? So far no app has been found that uses color keying with
3267                  * multitexturing */
3268                 if (op == WINED3D_TOP_DISABLE)
3269                 {
3270                     arg1 = WINED3DTA_TEXTURE;
3271                     op = WINED3D_TOP_SELECT_ARG1;
3272                 }
3273                 else if (op == WINED3D_TOP_SELECT_ARG1 && arg1 != WINED3DTA_TEXTURE)
3274                 {
3275                     if (state->render_states[WINED3D_RS_ALPHABLENDENABLE])
3276                     {
3277                         arg2 = WINED3DTA_TEXTURE;
3278                         op = WINED3D_TOP_MODULATE;
3279                     }
3280                     else arg1 = WINED3DTA_TEXTURE;
3281                 }
3282                 else if (op == WINED3D_TOP_SELECT_ARG2 && arg2 != WINED3DTA_TEXTURE)
3283                 {
3284                     if (state->render_states[WINED3D_RS_ALPHABLENDENABLE])
3285                     {
3286                         arg1 = WINED3DTA_TEXTURE;
3287                         op = WINED3D_TOP_MODULATE;
3288                     }
3289                     else arg2 = WINED3DTA_TEXTURE;
3290                 }
3291             }
3292         }
3293     }
3294
3295     /* tex_alphaop is shared between the ffp and nvrc because the difference only comes down to
3296      * this if block here, and the other code(color keying, texture unit selection) are the same
3297      */
3298     TRACE("Setting alpha op for stage %d\n", stage);
3299     if (gl_info->supported[NV_REGISTER_COMBINERS])
3300     {
3301         set_tex_op_nvrc(gl_info, state, TRUE, stage, op, arg1, arg2, arg0,
3302                 mapped_stage, state->texture_states[stage][WINED3D_TSS_RESULT_ARG]);
3303     }
3304     else
3305     {
3306         set_tex_op(gl_info, state, TRUE, stage, op, arg1, arg2, arg0);
3307     }
3308 }
3309
3310 static void transform_texture(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3311 {
3312     DWORD texUnit = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3313     const struct wined3d_device *device = context->swapchain->device;
3314     const struct wined3d_gl_info *gl_info = context->gl_info;
3315     DWORD mapped_stage = device->texUnitMap[texUnit];
3316     BOOL generated;
3317     int coordIdx;
3318
3319     /* Ignore this when a vertex shader is used, or if the streams aren't sorted out yet */
3320     if (use_vs(state) || isStateDirty(context, STATE_VDECL))
3321     {
3322         TRACE("Using a vertex shader, or stream sources not sorted out yet, skipping\n");
3323         return;
3324     }
3325
3326     if (mapped_stage == WINED3D_UNMAPPED_STAGE) return;
3327     if (mapped_stage >= gl_info->limits.textures) return;
3328
3329     context_active_texture(context, gl_info, mapped_stage);
3330     generated = (state->texture_states[texUnit][WINED3D_TSS_TEXCOORD_INDEX] & 0xffff0000) != WINED3DTSS_TCI_PASSTHRU;
3331     coordIdx = min(state->texture_states[texUnit][WINED3D_TSS_TEXCOORD_INDEX & 0x0000ffff], MAX_TEXTURES - 1);
3332
3333     set_texture_matrix(gl_info, &state->transforms[WINED3D_TS_TEXTURE0 + texUnit].u.m[0][0],
3334             state->texture_states[texUnit][WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS],
3335             generated, context->last_was_rhw,
3336             device->strided_streams.use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coordIdx))
3337             ? device->strided_streams.elements[WINED3D_FFP_TEXCOORD0 + coordIdx].format->id
3338             : WINED3DFMT_UNKNOWN,
3339             device->shader_backend->shader_has_ffp_proj_control(device->shader_priv));
3340
3341     /* The sampler applying function calls us if this changes */
3342     if ((context->lastWasPow2Texture & (1 << texUnit)) && state->textures[texUnit])
3343     {
3344         if(generated) {
3345             FIXME("Non-power2 texture being used with generated texture coords\n");
3346         }
3347         /* NP2 texcoord fixup is implemented for pixelshaders so only enable the
3348            fixed-function-pipeline fixup via pow2Matrix when no PS is used. */
3349         if (!use_ps(state))
3350         {
3351             TRACE("Non power two matrix multiply fixup\n");
3352             gl_info->gl_ops.gl.p_glMultMatrixf(state->textures[texUnit]->pow2_matrix);
3353         }
3354     }
3355 }
3356
3357 static void unload_tex_coords(const struct wined3d_gl_info *gl_info)
3358 {
3359     unsigned int texture_idx;
3360
3361     for (texture_idx = 0; texture_idx < gl_info->limits.texture_coords; ++texture_idx)
3362     {
3363         GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + texture_idx));
3364         gl_info->gl_ops.gl.p_glDisableClientState(GL_TEXTURE_COORD_ARRAY);
3365     }
3366 }
3367
3368 static void load_tex_coords(const struct wined3d_context *context, const struct wined3d_stream_info *si,
3369         GLuint *curVBO, const struct wined3d_state *state)
3370 {
3371     const struct wined3d_device *device = context->swapchain->device;
3372     const struct wined3d_gl_info *gl_info = context->gl_info;
3373     unsigned int mapped_stage = 0;
3374     unsigned int textureNo = 0;
3375
3376     for (textureNo = 0; textureNo < gl_info->limits.texture_stages; ++textureNo)
3377     {
3378         int coordIdx = state->texture_states[textureNo][WINED3D_TSS_TEXCOORD_INDEX];
3379
3380         mapped_stage = device->texUnitMap[textureNo];
3381         if (mapped_stage == WINED3D_UNMAPPED_STAGE) continue;
3382
3383         if (mapped_stage >= gl_info->limits.texture_coords)
3384         {
3385             FIXME("Attempted to load unsupported texture coordinate %u\n", mapped_stage);
3386             continue;
3387         }
3388
3389         if (coordIdx < MAX_TEXTURES && (si->use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coordIdx))))
3390         {
3391             const struct wined3d_stream_info_element *e = &si->elements[WINED3D_FFP_TEXCOORD0 + coordIdx];
3392
3393             TRACE("Setting up texture %u, idx %d, coordindx %u, data {%#x:%p}.\n",
3394                     textureNo, mapped_stage, coordIdx, e->data.buffer_object, e->data.addr);
3395
3396             if (*curVBO != e->data.buffer_object)
3397             {
3398                 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
3399                 checkGLcall("glBindBufferARB");
3400                 *curVBO = e->data.buffer_object;
3401             }
3402
3403             GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
3404             checkGLcall("glClientActiveTextureARB");
3405
3406             /* The coords to supply depend completely on the fvf / vertex shader */
3407             gl_info->gl_ops.gl.p_glTexCoordPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
3408                     e->data.addr + state->load_base_vertex_index * e->stride);
3409             gl_info->gl_ops.gl.p_glEnableClientState(GL_TEXTURE_COORD_ARRAY);
3410         }
3411         else
3412         {
3413             GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + mapped_stage, 0, 0, 0, 1));
3414         }
3415     }
3416     if (gl_info->supported[NV_REGISTER_COMBINERS])
3417     {
3418         /* The number of the mapped stages increases monotonically, so it's fine to use the last used one. */
3419         for (textureNo = mapped_stage + 1; textureNo < gl_info->limits.textures; ++textureNo)
3420         {
3421             GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, 0, 0, 0, 1));
3422         }
3423     }
3424
3425     checkGLcall("loadTexCoords");
3426 }
3427
3428 static void tex_coordindex(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3429 {
3430     DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3431     const struct wined3d_device *device = context->swapchain->device;
3432     static const GLfloat s_plane[] = { 1.0f, 0.0f, 0.0f, 0.0f };
3433     static const GLfloat t_plane[] = { 0.0f, 1.0f, 0.0f, 0.0f };
3434     static const GLfloat r_plane[] = { 0.0f, 0.0f, 1.0f, 0.0f };
3435     static const GLfloat q_plane[] = { 0.0f, 0.0f, 0.0f, 1.0f };
3436     const struct wined3d_gl_info *gl_info = context->gl_info;
3437     DWORD mapped_stage = device->texUnitMap[stage];
3438
3439     if (mapped_stage == WINED3D_UNMAPPED_STAGE)
3440     {
3441         TRACE("No texture unit mapped to stage %d. Skipping texture coordinates.\n", stage);
3442         return;
3443     }
3444
3445     if (mapped_stage >= gl_info->limits.fragment_samplers)
3446     {
3447         WARN("stage %u not mapped to a valid texture unit (%u)\n", stage, mapped_stage);
3448         return;
3449     }
3450     context_active_texture(context, gl_info, mapped_stage);
3451
3452     /* Values 0-7 are indexes into the FVF tex coords - See comments in DrawPrimitive
3453      *
3454      * FIXME: When using generated texture coordinates, the index value is used to specify the wrapping mode.
3455      * eg. SetTextureStageState( 0, WINED3D_TSS_TEXCOORDINDEX, WINED3D_TSS_TCI_CAMERASPACEPOSITION | 1 );
3456      * means use the vertex position (camera-space) as the input texture coordinates
3457      * for this texture stage, and the wrap mode set in the WINED3D_RS_WRAP1 render
3458      * state. We do not (yet) support the WINED3DRENDERSTATE_WRAPx values, nor tie them up
3459      * to the TEXCOORDINDEX value
3460      */
3461     switch (state->texture_states[stage][WINED3D_TSS_TEXCOORD_INDEX] & 0xffff0000)
3462     {
3463         case WINED3DTSS_TCI_PASSTHRU:
3464             /* Use the specified texture coordinates contained within the
3465              * vertex format. This value resolves to zero. */
3466             gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_S);
3467             gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_T);
3468             gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_R);
3469             gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_Q);
3470             checkGLcall("WINED3DTSS_TCI_PASSTHRU - Disable texgen.");
3471             break;
3472
3473         case WINED3DTSS_TCI_CAMERASPACEPOSITION:
3474             /* CameraSpacePosition means use the vertex position, transformed to camera space,
3475              * as the input texture coordinates for this stage's texture transformation. This
3476              * equates roughly to EYE_LINEAR */
3477
3478             gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
3479             gl_info->gl_ops.gl.p_glPushMatrix();
3480             gl_info->gl_ops.gl.p_glLoadIdentity();
3481             gl_info->gl_ops.gl.p_glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
3482             gl_info->gl_ops.gl.p_glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
3483             gl_info->gl_ops.gl.p_glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
3484             gl_info->gl_ops.gl.p_glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
3485             gl_info->gl_ops.gl.p_glPopMatrix();
3486             checkGLcall("WINED3DTSS_TCI_CAMERASPACEPOSITION - Set eye plane.");
3487
3488             gl_info->gl_ops.gl.p_glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
3489             gl_info->gl_ops.gl.p_glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
3490             gl_info->gl_ops.gl.p_glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
3491             checkGLcall("WINED3DTSS_TCI_CAMERASPACEPOSITION - Set texgen mode.");
3492
3493             gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_S);
3494             gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_T);
3495             gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_R);
3496             checkGLcall("WINED3DTSS_TCI_CAMERASPACEPOSITION - Enable texgen.");
3497
3498             break;
3499
3500         case WINED3DTSS_TCI_CAMERASPACENORMAL:
3501             /* Note that NV_TEXGEN_REFLECTION support is implied when
3502              * ARB_TEXTURE_CUBE_MAP is supported */
3503             if (!gl_info->supported[NV_TEXGEN_REFLECTION])
3504             {
3505                 FIXME("WINED3DTSS_TCI_CAMERASPACENORMAL not supported.\n");
3506                 break;
3507             }
3508
3509             gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
3510             gl_info->gl_ops.gl.p_glPushMatrix();
3511             gl_info->gl_ops.gl.p_glLoadIdentity();
3512             gl_info->gl_ops.gl.p_glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
3513             gl_info->gl_ops.gl.p_glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
3514             gl_info->gl_ops.gl.p_glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
3515             gl_info->gl_ops.gl.p_glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
3516             gl_info->gl_ops.gl.p_glPopMatrix();
3517             checkGLcall("WINED3DTSS_TCI_CAMERASPACENORMAL - Set eye plane.");
3518
3519             gl_info->gl_ops.gl.p_glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
3520             gl_info->gl_ops.gl.p_glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
3521             gl_info->gl_ops.gl.p_glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
3522             checkGLcall("WINED3DTSS_TCI_CAMERASPACENORMAL - Set texgen mode.");
3523
3524             gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_S);
3525             gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_T);
3526             gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_R);
3527             checkGLcall("WINED3DTSS_TCI_CAMERASPACENORMAL - Enable texgen.");
3528
3529             break;
3530
3531         case WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR:
3532             /* Note that NV_TEXGEN_REFLECTION support is implied when
3533              * ARB_TEXTURE_CUBE_MAP is supported */
3534             if (!gl_info->supported[NV_TEXGEN_REFLECTION])
3535             {
3536                 FIXME("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR not supported.\n");
3537                 break;
3538             }
3539
3540             gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
3541             gl_info->gl_ops.gl.p_glPushMatrix();
3542             gl_info->gl_ops.gl.p_glLoadIdentity();
3543             gl_info->gl_ops.gl.p_glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
3544             gl_info->gl_ops.gl.p_glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
3545             gl_info->gl_ops.gl.p_glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
3546             gl_info->gl_ops.gl.p_glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
3547             gl_info->gl_ops.gl.p_glPopMatrix();
3548             checkGLcall("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Set eye plane.");
3549
3550             gl_info->gl_ops.gl.p_glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
3551             gl_info->gl_ops.gl.p_glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
3552             gl_info->gl_ops.gl.p_glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
3553             checkGLcall("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Set texgen mode.");
3554
3555             gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_S);
3556             gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_T);
3557             gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_R);
3558             checkGLcall("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Enable texgen.");
3559
3560             break;
3561
3562         case WINED3DTSS_TCI_SPHEREMAP:
3563             gl_info->gl_ops.gl.p_glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
3564             gl_info->gl_ops.gl.p_glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
3565             checkGLcall("WINED3DTSS_TCI_SPHEREMAP - Set texgen mode.");
3566
3567             gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_S);
3568             gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_T);
3569             gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_R);
3570             checkGLcall("WINED3DTSS_TCI_SPHEREMAP - Enable texgen.");
3571
3572             break;
3573
3574         default:
3575             FIXME("Unhandled WINED3D_TSS_TEXCOORD_INDEX %#x.\n",
3576                     state->texture_states[stage][WINED3D_TSS_TEXCOORD_INDEX]);
3577             gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_S);
3578             gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_T);
3579             gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_R);
3580             gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_Q);
3581             checkGLcall("Disable texgen.");
3582
3583             break;
3584     }
3585
3586     /* Update the texture matrix. */
3587     if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + stage)))
3588         transform_texture(context, state, STATE_TEXTURESTAGE(stage, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS));
3589
3590     if (!isStateDirty(context, STATE_VDECL) && context->namedArraysLoaded)
3591     {
3592         /* Reload the arrays if we are using fixed function arrays to reflect the selected coord input
3593          * source. Call loadTexCoords directly because there is no need to reparse the vertex declaration
3594          * and do all the things linked to it
3595          * TODO: Tidy that up to reload only the arrays of the changed unit
3596          */
3597         GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
3598
3599         unload_tex_coords(gl_info);
3600         load_tex_coords(context, &device->strided_streams, &curVBO, state);
3601     }
3602 }
3603
3604 static void tex_bumpenvlscale(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3605 {
3606     DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3607     const struct wined3d_shader *ps = state->pixel_shader;
3608
3609     /* The pixel shader has to know the luminance scale. Do a constants update. */
3610     if (ps && stage && (ps->reg_maps.luminanceparams & (1 << stage)))
3611         context->load_constants = 1;
3612 }
3613
3614 static void sampler_texmatrix(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3615 {
3616     const DWORD sampler = state_id - STATE_SAMPLER(0);
3617     const struct wined3d_texture *texture = state->textures[sampler];
3618
3619     TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
3620
3621     if(!texture) return;
3622     /* The fixed function np2 texture emulation uses the texture matrix to fix up the coordinates
3623      * wined3d_texture_apply_state_changes() multiplies the set matrix with a fixup matrix. Before the
3624      * scaling is reapplied or removed, the texture matrix has to be reapplied
3625      *
3626      * The mapped stage is already active because the sampler() function below, which is part of the
3627      * misc pipeline
3628      */
3629     if (sampler < MAX_TEXTURES)
3630     {
3631         const BOOL texIsPow2 = !(texture->flags & WINED3D_TEXTURE_POW2_MAT_IDENT);
3632
3633         if (texIsPow2 || (context->lastWasPow2Texture & (1 << sampler)))
3634         {
3635             const struct wined3d_device *device = context->swapchain->device;
3636
3637             if (texIsPow2)
3638                 context->lastWasPow2Texture |= 1 << sampler;
3639             else
3640                 context->lastWasPow2Texture &= ~(1 << sampler);
3641
3642             transform_texture(context, state,
3643                     STATE_TEXTURESTAGE(device->texUnitMap[sampler], WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS));
3644         }
3645     }
3646 }
3647
3648 static void sampler(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3649 {
3650     const struct wined3d_device *device = context->swapchain->device;
3651     DWORD sampler = state_id - STATE_SAMPLER(0);
3652     DWORD mapped_stage = device->texUnitMap[sampler];
3653     const struct wined3d_gl_info *gl_info = context->gl_info;
3654     union {
3655         float f;
3656         DWORD d;
3657     } tmpvalue;
3658
3659     TRACE("Sampler: %d\n", sampler);
3660     /* Enabling and disabling texture dimensions is done by texture stage state / pixel shader setup, this function
3661      * only has to bind textures and set the per texture states
3662      */
3663
3664     if (mapped_stage == WINED3D_UNMAPPED_STAGE)
3665     {
3666         TRACE("No sampler mapped to stage %d. Returning.\n", sampler);
3667         return;
3668     }
3669
3670     if (mapped_stage >= gl_info->limits.combined_samplers)
3671     {
3672         return;
3673     }
3674     context_active_texture(context, gl_info, mapped_stage);
3675
3676     if (state->textures[sampler])
3677     {
3678         struct wined3d_texture *texture = state->textures[sampler];
3679         BOOL srgb = state->sampler_states[sampler][WINED3D_SAMP_SRGB_TEXTURE];
3680
3681         texture->texture_ops->texture_bind(texture, context, srgb);
3682         wined3d_texture_apply_state_changes(texture, state->sampler_states[sampler], gl_info);
3683
3684         if (gl_info->supported[EXT_TEXTURE_LOD_BIAS])
3685         {
3686             tmpvalue.d = state->sampler_states[sampler][WINED3D_SAMP_MIPMAP_LOD_BIAS];
3687             gl_info->gl_ops.gl.p_glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT,
3688                       GL_TEXTURE_LOD_BIAS_EXT, tmpvalue.f);
3689             checkGLcall("glTexEnvf(GL_TEXTURE_LOD_BIAS_EXT, ...)");
3690         }
3691
3692         if (!use_ps(state) && sampler < state->lowest_disabled_stage)
3693         {
3694             if (state->render_states[WINED3D_RS_COLORKEYENABLE] && !sampler)
3695             {
3696                 /* If color keying is enabled update the alpha test, it
3697                  * depends on the existence of a color key in stage 0. */
3698                 state_alpha(context, state, WINED3D_RS_COLORKEYENABLE);
3699             }
3700         }
3701
3702         /* Trigger shader constant reloading (for NP2 texcoord fixup) */
3703         if (!(texture->flags & WINED3D_TEXTURE_POW2_MAT_IDENT))
3704             device->shader_backend->shader_load_np2fixup_constants(device->shader_priv, gl_info, state);
3705     }
3706     else
3707     {
3708         if (sampler < state->lowest_disabled_stage)
3709         {
3710             /* TODO: What should I do with pixel shaders here ??? */
3711             if (state->render_states[WINED3D_RS_COLORKEYENABLE] && !sampler)
3712             {
3713                 /* If color keying is enabled update the alpha test, it
3714                  * depends on the existence of a color key in stage 0. */
3715                 state_alpha(context, state, WINED3D_RS_COLORKEYENABLE);
3716             }
3717         } /* Otherwise tex_colorop disables the stage */
3718         context_bind_texture(context, GL_NONE, 0);
3719     }
3720 }
3721
3722 void apply_pixelshader(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3723 {
3724     unsigned int i;
3725
3726     if (use_ps(state))
3727     {
3728         if (!context->last_was_pshader)
3729         {
3730             /* Former draw without a pixel shader, some samplers may be
3731              * disabled because of WINED3D_TSS_COLOR_OP = WINED3DTOP_DISABLE
3732              * make sure to enable them. */
3733             for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i)
3734             {
3735                 if (!isStateDirty(context, STATE_SAMPLER(i)))
3736                     sampler(context, state, STATE_SAMPLER(i));
3737             }
3738             context->last_was_pshader = TRUE;
3739         }
3740         else
3741         {
3742             /* Otherwise all samplers were activated by the code above in
3743              * earlier draws, or by sampler() if a different texture was
3744              * bound. I don't have to do anything. */
3745         }
3746     }
3747     else
3748     {
3749         /* Disabled the pixel shader - color ops weren't applied while it was
3750          * enabled, so re-apply them. */
3751         for (i = 0; i < context->gl_info->limits.texture_stages; ++i)
3752         {
3753             if (!isStateDirty(context, STATE_TEXTURESTAGE(i, WINED3D_TSS_COLOR_OP)))
3754                 context_apply_state(context, state, STATE_TEXTURESTAGE(i, WINED3D_TSS_COLOR_OP));
3755         }
3756         context->last_was_pshader = FALSE;
3757     }
3758
3759     context->select_shader = 1;
3760     context->load_constants = 1;
3761 }
3762
3763 static void state_geometry_shader(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3764 {
3765     context->select_shader = 1;
3766 }
3767
3768 static void shader_bumpenvmat(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3769 {
3770     DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3771     const struct wined3d_shader *ps = state->pixel_shader;
3772
3773     /* The pixel shader has to know the bump env matrix. Do a constants update. */
3774     if (ps && stage && (ps->reg_maps.bumpmat & (1 << stage)))
3775         context->load_constants = 1;
3776 }
3777
3778 static void transform_world(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3779 {
3780     const struct wined3d_gl_info *gl_info = context->gl_info;
3781
3782     /* This function is called by transform_view below if the view matrix was changed too
3783      *
3784      * Deliberately no check if the vertex declaration is dirty because the vdecl state
3785      * does not always update the world matrix, only on a switch between transformed
3786      * and untransformed draws. It *may* happen that the world matrix is set 2 times during one
3787      * draw, but that should be rather rare and cheaper in total.
3788      */
3789     gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
3790     checkGLcall("glMatrixMode");
3791
3792     if (context->last_was_rhw)
3793     {
3794         gl_info->gl_ops.gl.p_glLoadIdentity();
3795         checkGLcall("glLoadIdentity()");
3796     }
3797     else
3798     {
3799         /* In the general case, the view matrix is the identity matrix */
3800         if (context->swapchain->device->view_ident)
3801         {
3802             gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_WORLD_MATRIX(0)].u.m[0][0]);
3803             checkGLcall("glLoadMatrixf");
3804         }
3805         else
3806         {
3807             gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
3808             checkGLcall("glLoadMatrixf");
3809             gl_info->gl_ops.gl.p_glMultMatrixf(&state->transforms[WINED3D_TS_WORLD_MATRIX(0)].u.m[0][0]);
3810             checkGLcall("glMultMatrixf");
3811         }
3812     }
3813 }
3814
3815 static void clipplane(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3816 {
3817     const struct wined3d_gl_info *gl_info = context->gl_info;
3818     UINT index = state_id - STATE_CLIPPLANE(0);
3819     GLdouble plane[4];
3820
3821     if (isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_VIEW)) || index >= gl_info->limits.clipplanes)
3822         return;
3823
3824     gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
3825     gl_info->gl_ops.gl.p_glPushMatrix();
3826
3827     /* Clip Plane settings are affected by the model view in OpenGL, the View transform in direct3d */
3828     if (!use_vs(state))
3829         gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
3830     else
3831         /* With vertex shaders, clip planes are not transformed in Direct3D,
3832          * while in OpenGL they are still transformed by the model view matix. */
3833         gl_info->gl_ops.gl.p_glLoadIdentity();
3834
3835     plane[0] = state->clip_planes[index].x;
3836     plane[1] = state->clip_planes[index].y;
3837     plane[2] = state->clip_planes[index].z;
3838     plane[3] = state->clip_planes[index].w;
3839
3840     TRACE("Clipplane [%.8e, %.8e, %.8e, %.8e]\n",
3841             plane[0], plane[1], plane[2], plane[3]);
3842     gl_info->gl_ops.gl.p_glClipPlane(GL_CLIP_PLANE0 + index, plane);
3843     checkGLcall("glClipPlane");
3844
3845     gl_info->gl_ops.gl.p_glPopMatrix();
3846 }
3847
3848 static void transform_worldex(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3849 {
3850     UINT matrix = state_id - STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0));
3851     const struct wined3d_gl_info *gl_info = context->gl_info;
3852     GLenum glMat;
3853
3854     TRACE("Setting world matrix %d\n", matrix);
3855
3856     if (matrix >= gl_info->limits.blends)
3857     {
3858         WARN("Unsupported blend matrix set\n");
3859         return;
3860     }
3861
3862     if (isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_VIEW)))
3863         return;
3864
3865     /* GL_MODELVIEW0_ARB:  0x1700
3866      * GL_MODELVIEW1_ARB:  0x850a
3867      * GL_MODELVIEW2_ARB:  0x8722
3868      * GL_MODELVIEW3_ARB:  0x8723
3869      * etc
3870      * GL_MODELVIEW31_ARB: 0x873f
3871      */
3872     if(matrix == 1) glMat = GL_MODELVIEW1_ARB;
3873     else glMat = GL_MODELVIEW2_ARB - 2 + matrix;
3874
3875     gl_info->gl_ops.gl.p_glMatrixMode(glMat);
3876     checkGLcall("glMatrixMode(glMat)");
3877
3878     /* World matrix 0 is multiplied with the view matrix because d3d uses 3
3879      * matrices while gl uses only 2. To avoid weighting the view matrix
3880      * incorrectly it has to be multiplied into every GL modelview matrix. */
3881     if (context->swapchain->device->view_ident)
3882     {
3883         gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_WORLD_MATRIX(matrix)].u.m[0][0]);
3884         checkGLcall("glLoadMatrixf");
3885     }
3886     else
3887     {
3888         gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
3889         checkGLcall("glLoadMatrixf");
3890         gl_info->gl_ops.gl.p_glMultMatrixf(&state->transforms[WINED3D_TS_WORLD_MATRIX(matrix)].u.m[0][0]);
3891         checkGLcall("glMultMatrixf");
3892     }
3893 }
3894
3895 static void state_vertexblend_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3896 {
3897     enum wined3d_vertex_blend_flags f = state->render_states[WINED3D_RS_VERTEXBLEND];
3898     static unsigned int once;
3899
3900     if (f == WINED3D_VBF_DISABLE)
3901         return;
3902
3903     if (!once++) FIXME("Vertex blend flags %#x not supported.\n", f);
3904     else WARN("Vertex blend flags %#x not supported.\n", f);
3905 }
3906
3907 static void state_vertexblend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3908 {
3909     enum wined3d_vertex_blend_flags val = state->render_states[WINED3D_RS_VERTEXBLEND];
3910     struct wined3d_device *device = context->swapchain->device;
3911     const struct wined3d_gl_info *gl_info = context->gl_info;
3912     static unsigned int once;
3913
3914     switch (val)
3915     {
3916         case WINED3D_VBF_1WEIGHTS:
3917         case WINED3D_VBF_2WEIGHTS:
3918         case WINED3D_VBF_3WEIGHTS:
3919             gl_info->gl_ops.gl.p_glEnable(GL_VERTEX_BLEND_ARB);
3920             checkGLcall("glEnable(GL_VERTEX_BLEND_ARB)");
3921
3922             /* D3D adds one more matrix which has weight (1 - sum(weights)).
3923              * This is enabled at context creation with enabling
3924              * GL_WEIGHT_SUM_UNITY_ARB. */
3925             GL_EXTCALL(glVertexBlendARB(state->render_states[WINED3D_RS_VERTEXBLEND] + 1));
3926
3927             if (!device->vertexBlendUsed)
3928             {
3929                 unsigned int i;
3930                 for (i = 1; i < gl_info->limits.blends; ++i)
3931                 {
3932                     if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(i))))
3933                         transform_worldex(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(i)));
3934                 }
3935                 device->vertexBlendUsed = TRUE;
3936             }
3937             break;
3938
3939         case WINED3D_VBF_TWEENING:
3940         case WINED3D_VBF_0WEIGHTS: /* Indexed vertex blending, not supported. */
3941             if (!once++) FIXME("Vertex blend flags %#x not supported.\n", val);
3942             else WARN("Vertex blend flags %#x not supported.\n", val);
3943             /* Fall through. */
3944         case WINED3D_VBF_DISABLE:
3945             gl_info->gl_ops.gl.p_glDisable(GL_VERTEX_BLEND_ARB);
3946             checkGLcall("glDisable(GL_VERTEX_BLEND_ARB)");
3947             break;
3948     }
3949 }
3950
3951 static void transform_view(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3952 {
3953     const struct wined3d_gl_info *gl_info = context->gl_info;
3954     const struct wined3d_light_info *light = NULL;
3955     unsigned int k;
3956
3957     /* If we are changing the View matrix, reset the light and clipping planes to the new view
3958      * NOTE: We have to reset the positions even if the light/plane is not currently
3959      *       enabled, since the call to enable it will not reset the position.
3960      * NOTE2: Apparently texture transforms do NOT need reapplying
3961      */
3962
3963     gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
3964     checkGLcall("glMatrixMode(GL_MODELVIEW)");
3965     gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
3966     checkGLcall("glLoadMatrixf(...)");
3967
3968     /* Reset lights. TODO: Call light apply func */
3969     for (k = 0; k < gl_info->limits.lights; ++k)
3970     {
3971         if (!(light = state->lights[k]))
3972             continue;
3973         gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + light->glIndex, GL_POSITION, light->lightPosn);
3974         checkGLcall("glLightfv posn");
3975         gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + light->glIndex, GL_SPOT_DIRECTION, light->lightDirn);
3976         checkGLcall("glLightfv dirn");
3977     }
3978
3979     /* Reset Clipping Planes  */
3980     for (k = 0; k < gl_info->limits.clipplanes; ++k)
3981     {
3982         if (!isStateDirty(context, STATE_CLIPPLANE(k)))
3983             clipplane(context, state, STATE_CLIPPLANE(k));
3984     }
3985
3986     if (context->last_was_rhw)
3987     {
3988         gl_info->gl_ops.gl.p_glLoadIdentity();
3989         checkGLcall("glLoadIdentity()");
3990         /* No need to update the world matrix, the identity is fine */
3991         return;
3992     }
3993
3994     /* Call the world matrix state, this will apply the combined WORLD + VIEW matrix
3995      * No need to do it here if the state is scheduled for update. */
3996     if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0))))
3997         transform_world(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)));
3998
3999     /* Avoid looping over a number of matrices if the app never used the functionality */
4000     if (context->swapchain->device->vertexBlendUsed)
4001     {
4002         for (k = 1; k < gl_info->limits.blends; ++k)
4003         {
4004             if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(k))))
4005                 transform_worldex(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(k)));
4006         }
4007     }
4008 }
4009
4010 static void transform_projection(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4011 {
4012     const struct wined3d_gl_info *gl_info = context->gl_info;
4013
4014     gl_info->gl_ops.gl.p_glMatrixMode(GL_PROJECTION);
4015     checkGLcall("glMatrixMode(GL_PROJECTION)");
4016
4017     /* There are a couple of additional things we have to take into account
4018      * here besides the projection transformation itself:
4019      *   - We need to flip along the y-axis in case of offscreen rendering.
4020      *   - OpenGL Z range is {-Wc,...,Wc} while D3D Z range is {0,...,Wc}.
4021      *   - D3D coordinates refer to pixel centers while GL coordinates refer
4022      *     to pixel corners.
4023      *   - D3D has a top-left filling convention. We need to maintain this
4024      *     even after the y-flip mentioned above.
4025      * In order to handle the last two points, we translate by
4026      * (63.0 / 128.0) / VPw and (63.0 / 128.0) / VPh. This is equivalent to
4027      * translating slightly less than half a pixel. We want the difference to
4028      * be large enough that it doesn't get lost due to rounding inside the
4029      * driver, but small enough to prevent it from interfering with any
4030      * anti-aliasing. */
4031
4032     if (context->last_was_rhw)
4033     {
4034         /* Transform D3D RHW coordinates to OpenGL clip coordinates. */
4035         double x = state->viewport.x;
4036         double y = state->viewport.y;
4037         double w = state->viewport.width;
4038         double h = state->viewport.height;
4039         double x_scale = 2.0 / w;
4040         double x_offset = ((63.0 / 64.0) - (2.0 * x) - w) / w;
4041         double y_scale = context->render_offscreen ? 2.0 / h : 2.0 / -h;
4042         double y_offset = context->render_offscreen
4043                 ? ((63.0 / 64.0) - (2.0 * y) - h) / h
4044                 : ((63.0 / 64.0) - (2.0 * y) - h) / -h;
4045         const GLdouble projection[] =
4046         {
4047              x_scale,      0.0,  0.0, 0.0,
4048                  0.0,  y_scale,  0.0, 0.0,
4049                  0.0,      0.0,  2.0, 0.0,
4050             x_offset, y_offset, -1.0, 1.0,
4051         };
4052
4053         gl_info->gl_ops.gl.p_glLoadMatrixd(projection);
4054         checkGLcall("glLoadMatrixd");
4055     }
4056     else
4057     {
4058         double y_scale = context->render_offscreen ? -1.0 : 1.0;
4059         double x_offset = (63.0 / 64.0) / state->viewport.width;
4060         double y_offset = context->render_offscreen
4061                 ? (63.0 / 64.0) / state->viewport.height
4062                 : -(63.0 / 64.0) / state->viewport.height;
4063         const GLdouble projection[] =
4064         {
4065                  1.0,      0.0,  0.0, 0.0,
4066                  0.0,  y_scale,  0.0, 0.0,
4067                  0.0,      0.0,  2.0, 0.0,
4068             x_offset, y_offset, -1.0, 1.0,
4069         };
4070
4071         gl_info->gl_ops.gl.p_glLoadMatrixd(projection);
4072         checkGLcall("glLoadMatrixd");
4073
4074         gl_info->gl_ops.gl.p_glMultMatrixf(&state->transforms[WINED3D_TS_PROJECTION].u.m[0][0]);
4075         checkGLcall("glLoadMatrixf");
4076     }
4077 }
4078
4079 /* This should match any arrays loaded in load_vertex_data.
4080  * TODO: Only load / unload arrays if we have to. */
4081 static void unload_vertex_data(const struct wined3d_gl_info *gl_info)
4082 {
4083     gl_info->gl_ops.gl.p_glDisableClientState(GL_VERTEX_ARRAY);
4084     gl_info->gl_ops.gl.p_glDisableClientState(GL_NORMAL_ARRAY);
4085     gl_info->gl_ops.gl.p_glDisableClientState(GL_COLOR_ARRAY);
4086     if (gl_info->supported[EXT_SECONDARY_COLOR])
4087         gl_info->gl_ops.gl.p_glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
4088     if (gl_info->supported[ARB_VERTEX_BLEND])
4089         gl_info->gl_ops.gl.p_glDisableClientState(GL_WEIGHT_ARRAY_ARB);
4090     unload_tex_coords(gl_info);
4091 }
4092
4093 static inline void unload_numbered_array(struct wined3d_context *context, int i)
4094 {
4095     const struct wined3d_gl_info *gl_info = context->gl_info;
4096
4097     GL_EXTCALL(glDisableVertexAttribArrayARB(i));
4098     checkGLcall("glDisableVertexAttribArrayARB(reg)");
4099
4100     context->numbered_array_mask &= ~(1 << i);
4101 }
4102
4103 /* This should match any arrays loaded in loadNumberedArrays
4104  * TODO: Only load / unload arrays if we have to. */
4105 static void unload_numbered_arrays(struct wined3d_context *context)
4106 {
4107     /* disable any attribs (this is the same for both GLSL and ARB modes) */
4108     int i;
4109
4110     for (i = 0; i < context->gl_info->limits.vertex_attribs; ++i) {
4111         unload_numbered_array(context, i);
4112     }
4113 }
4114
4115 static void load_numbered_arrays(struct wined3d_context *context,
4116         const struct wined3d_stream_info *stream_info, const struct wined3d_state *state)
4117 {
4118     struct wined3d_device *device = context->swapchain->device;
4119     const struct wined3d_gl_info *gl_info = context->gl_info;
4120     GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
4121     int i;
4122
4123     /* Default to no instancing */
4124     device->instancedDraw = FALSE;
4125
4126     for (i = 0; i < MAX_ATTRIBS; i++)
4127     {
4128         const struct wined3d_stream_state *stream;
4129
4130         if (!(stream_info->use_map & (1 << i)))
4131         {
4132             if (context->numbered_array_mask & (1 << i))
4133                 unload_numbered_array(context, i);
4134             if (state->vertex_shader->reg_maps.input_registers & (1 << i))
4135                 GL_EXTCALL(glVertexAttrib4fARB(i, 0.0f, 0.0f, 0.0f, 0.0f));
4136             continue;
4137         }
4138
4139         stream = &state->streams[stream_info->elements[i].stream_idx];
4140
4141         /* Do not load instance data. It will be specified using glTexCoord by drawprim */
4142         if (stream->flags & WINED3DSTREAMSOURCE_INSTANCEDATA)
4143         {
4144             if (context->numbered_array_mask & (1 << i)) unload_numbered_array(context, i);
4145             device->instancedDraw = TRUE;
4146             continue;
4147         }
4148
4149         TRACE_(d3d_shader)("Loading array %u [VBO=%u]\n", i, stream_info->elements[i].data.buffer_object);
4150
4151         if (stream_info->elements[i].stride)
4152         {
4153             if (curVBO != stream_info->elements[i].data.buffer_object)
4154             {
4155                 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, stream_info->elements[i].data.buffer_object));
4156                 checkGLcall("glBindBufferARB");
4157                 curVBO = stream_info->elements[i].data.buffer_object;
4158             }
4159             /* Use the VBO to find out if a vertex buffer exists, not the vb
4160              * pointer. vb can point to a user pointer data blob. In that case
4161              * curVBO will be 0. If there is a vertex buffer but no vbo we
4162              * won't be load converted attributes anyway. */
4163             GL_EXTCALL(glVertexAttribPointerARB(i, stream_info->elements[i].format->gl_vtx_format,
4164                     stream_info->elements[i].format->gl_vtx_type,
4165                     stream_info->elements[i].format->gl_normalized,
4166                     stream_info->elements[i].stride, stream_info->elements[i].data.addr
4167                     + state->load_base_vertex_index * stream_info->elements[i].stride));
4168
4169             if (!(context->numbered_array_mask & (1 << i)))
4170             {
4171                 GL_EXTCALL(glEnableVertexAttribArrayARB(i));
4172                 context->numbered_array_mask |= (1 << i);
4173             }
4174         }
4175         else
4176         {
4177             /* Stride = 0 means always the same values.
4178              * glVertexAttribPointerARB doesn't do that. Instead disable the
4179              * pointer and set up the attribute statically. But we have to
4180              * figure out the system memory address. */
4181             const BYTE *ptr = stream_info->elements[i].data.addr;
4182             if (stream_info->elements[i].data.buffer_object)
4183             {
4184                 ptr += (ULONG_PTR)buffer_get_sysmem(stream->buffer, gl_info);
4185             }
4186
4187             if (context->numbered_array_mask & (1 << i)) unload_numbered_array(context, i);
4188
4189             switch (stream_info->elements[i].format->id)
4190             {
4191                 case WINED3DFMT_R32_FLOAT:
4192                     GL_EXTCALL(glVertexAttrib1fvARB(i, (const GLfloat *)ptr));
4193                     break;
4194                 case WINED3DFMT_R32G32_FLOAT:
4195                     GL_EXTCALL(glVertexAttrib2fvARB(i, (const GLfloat *)ptr));
4196                     break;
4197                 case WINED3DFMT_R32G32B32_FLOAT:
4198                     GL_EXTCALL(glVertexAttrib3fvARB(i, (const GLfloat *)ptr));
4199                     break;
4200                 case WINED3DFMT_R32G32B32A32_FLOAT:
4201                     GL_EXTCALL(glVertexAttrib4fvARB(i, (const GLfloat *)ptr));
4202                     break;
4203
4204                 case WINED3DFMT_R8G8B8A8_UINT:
4205                     GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
4206                     break;
4207                 case WINED3DFMT_B8G8R8A8_UNORM:
4208                     if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
4209                     {
4210                         const DWORD *src = (const DWORD *)ptr;
4211                         DWORD c = *src & 0xff00ff00;
4212                         c |= (*src & 0xff0000) >> 16;
4213                         c |= (*src & 0xff) << 16;
4214                         GL_EXTCALL(glVertexAttrib4NubvARB(i, (GLubyte *)&c));
4215                         break;
4216                     }
4217                     /* else fallthrough */
4218                 case WINED3DFMT_R8G8B8A8_UNORM:
4219                     GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
4220                     break;
4221
4222                 case WINED3DFMT_R16G16_SINT:
4223                     GL_EXTCALL(glVertexAttrib4svARB(i, (const GLshort *)ptr));
4224                     break;
4225                 case WINED3DFMT_R16G16B16A16_SINT:
4226                     GL_EXTCALL(glVertexAttrib4svARB(i, (const GLshort *)ptr));
4227                     break;
4228
4229                 case WINED3DFMT_R16G16_SNORM:
4230                 {
4231                     const GLshort s[4] = {((const GLshort *)ptr)[0], ((const GLshort *)ptr)[1], 0, 1};
4232                     GL_EXTCALL(glVertexAttrib4NsvARB(i, s));
4233                     break;
4234                 }
4235                 case WINED3DFMT_R16G16_UNORM:
4236                 {
4237                     const GLushort s[4] = {((const GLushort *)ptr)[0], ((const GLushort *)ptr)[1], 0, 1};
4238                     GL_EXTCALL(glVertexAttrib4NusvARB(i, s));
4239                     break;
4240                 }
4241                 case WINED3DFMT_R16G16B16A16_SNORM:
4242                     GL_EXTCALL(glVertexAttrib4NsvARB(i, (const GLshort *)ptr));
4243                     break;
4244                 case WINED3DFMT_R16G16B16A16_UNORM:
4245                     GL_EXTCALL(glVertexAttrib4NusvARB(i, (const GLushort *)ptr));
4246                     break;
4247
4248                 case WINED3DFMT_R10G10B10A2_UINT:
4249                     FIXME("Unsure about WINED3DDECLTYPE_UDEC3\n");
4250                     /*glVertexAttrib3usvARB(i, (const GLushort *)ptr); Does not exist */
4251                     break;
4252                 case WINED3DFMT_R10G10B10A2_SNORM:
4253                     FIXME("Unsure about WINED3DDECLTYPE_DEC3N\n");
4254                     /*glVertexAttrib3NusvARB(i, (const GLushort *)ptr); Does not exist */
4255                     break;
4256
4257                 case WINED3DFMT_R16G16_FLOAT:
4258                     /* Are those 16 bit floats. C doesn't have a 16 bit float type. I could read the single bits and calculate a 4
4259                      * byte float according to the IEEE standard
4260                      */
4261                     FIXME("Unsupported WINED3DDECLTYPE_FLOAT16_2\n");
4262                     break;
4263                 case WINED3DFMT_R16G16B16A16_FLOAT:
4264                     FIXME("Unsupported WINED3DDECLTYPE_FLOAT16_4\n");
4265                     break;
4266
4267                 default:
4268                     ERR("Unexpected declaration in stride 0 attributes\n");
4269                     break;
4270
4271             }
4272         }
4273     }
4274     checkGLcall("Loading numbered arrays");
4275 }
4276
4277 static void load_vertex_data(const struct wined3d_context *context,
4278         const struct wined3d_stream_info *si, const struct wined3d_state *state)
4279 {
4280     struct wined3d_device *device = context->swapchain->device;
4281     const struct wined3d_gl_info *gl_info = context->gl_info;
4282     GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
4283     const struct wined3d_stream_info_element *e;
4284
4285     TRACE("Using fast vertex array code\n");
4286
4287     /* This is fixed function pipeline only, and the fixed function pipeline doesn't do instancing */
4288     device->instancedDraw = FALSE;
4289
4290     /* Blend Data ---------------------------------------------- */
4291     if ((si->use_map & (1 << WINED3D_FFP_BLENDWEIGHT))
4292             || si->use_map & (1 << WINED3D_FFP_BLENDINDICES))
4293     {
4294         e = &si->elements[WINED3D_FFP_BLENDWEIGHT];
4295
4296         if (gl_info->supported[ARB_VERTEX_BLEND])
4297         {
4298             TRACE("Blend %u %p %u\n", e->format->component_count,
4299                     e->data.addr + state->load_base_vertex_index * e->stride, e->stride);
4300
4301             gl_info->gl_ops.gl.p_glEnableClientState(GL_WEIGHT_ARRAY_ARB);
4302             checkGLcall("glEnableClientState(GL_WEIGHT_ARRAY_ARB)");
4303
4304             GL_EXTCALL(glVertexBlendARB(e->format->component_count + 1));
4305
4306             if (curVBO != e->data.buffer_object)
4307             {
4308                 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4309                 checkGLcall("glBindBufferARB");
4310                 curVBO = e->data.buffer_object;
4311             }
4312
4313             TRACE("glWeightPointerARB(%#x, %#x, %#x, %p);\n",
4314                     e->format->gl_vtx_format,
4315                     e->format->gl_vtx_type,
4316                     e->stride,
4317                     e->data.addr + state->load_base_vertex_index * e->stride);
4318             GL_EXTCALL(glWeightPointerARB(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4319                     e->data.addr + state->load_base_vertex_index * e->stride));
4320
4321             checkGLcall("glWeightPointerARB");
4322
4323             if (si->use_map & (1 << WINED3D_FFP_BLENDINDICES))
4324             {
4325                 static BOOL warned;
4326                 if (!warned)
4327                 {
4328                     FIXME("blendMatrixIndices support\n");
4329                     warned = TRUE;
4330                 }
4331             }
4332         } else {
4333             /* TODO: support blends in drawStridedSlow
4334              * No need to write a FIXME here, this is done after the general vertex decl decoding
4335              */
4336             WARN("unsupported blending in openGl\n");
4337         }
4338     }
4339     else
4340     {
4341         if (gl_info->supported[ARB_VERTEX_BLEND])
4342         {
4343             static const GLbyte one = 1;
4344             GL_EXTCALL(glWeightbvARB(1, &one));
4345             checkGLcall("glWeightbvARB(gl_info->max_blends, weights)");
4346         }
4347     }
4348
4349     /* Point Size ----------------------------------------------*/
4350     if (si->use_map & (1 << WINED3D_FFP_PSIZE))
4351     {
4352         /* no such functionality in the fixed function GL pipeline */
4353         TRACE("Cannot change ptSize here in openGl\n");
4354         /* TODO: Implement this function in using shaders if they are available */
4355     }
4356
4357     /* Vertex Pointers -----------------------------------------*/
4358     if (si->use_map & (1 << WINED3D_FFP_POSITION))
4359     {
4360         e = &si->elements[WINED3D_FFP_POSITION];
4361
4362         if (curVBO != e->data.buffer_object)
4363         {
4364             GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4365             checkGLcall("glBindBufferARB");
4366             curVBO = e->data.buffer_object;
4367         }
4368
4369         TRACE("glVertexPointer(%#x, %#x, %#x, %p);\n",
4370                 e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4371                 e->data.addr + state->load_base_vertex_index * e->stride);
4372         gl_info->gl_ops.gl.p_glVertexPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4373                 e->data.addr + state->load_base_vertex_index * e->stride);
4374         checkGLcall("glVertexPointer(...)");
4375         gl_info->gl_ops.gl.p_glEnableClientState(GL_VERTEX_ARRAY);
4376         checkGLcall("glEnableClientState(GL_VERTEX_ARRAY)");
4377     }
4378
4379     /* Normals -------------------------------------------------*/
4380     if (si->use_map & (1 << WINED3D_FFP_NORMAL))
4381     {
4382         e = &si->elements[WINED3D_FFP_NORMAL];
4383
4384         if (curVBO != e->data.buffer_object)
4385         {
4386             GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4387             checkGLcall("glBindBufferARB");
4388             curVBO = e->data.buffer_object;
4389         }
4390
4391         TRACE("glNormalPointer(%#x, %#x, %p);\n", e->format->gl_vtx_type, e->stride,
4392                 e->data.addr + state->load_base_vertex_index * e->stride);
4393         gl_info->gl_ops.gl.p_glNormalPointer(e->format->gl_vtx_type, e->stride,
4394                 e->data.addr + state->load_base_vertex_index * e->stride);
4395         checkGLcall("glNormalPointer(...)");
4396         gl_info->gl_ops.gl.p_glEnableClientState(GL_NORMAL_ARRAY);
4397         checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)");
4398
4399     }
4400     else
4401     {
4402         gl_info->gl_ops.gl.p_glNormal3f(0, 0, 0);
4403         checkGLcall("glNormal3f(0, 0, 0)");
4404     }
4405
4406     /* Diffuse Colour --------------------------------------------*/
4407     if (si->use_map & (1 << WINED3D_FFP_DIFFUSE))
4408     {
4409         e = &si->elements[WINED3D_FFP_DIFFUSE];
4410
4411         if (curVBO != e->data.buffer_object)
4412         {
4413             GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4414             checkGLcall("glBindBufferARB");
4415             curVBO = e->data.buffer_object;
4416         }
4417
4418         TRACE("glColorPointer(%#x, %#x %#x, %p);\n",
4419                 e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4420                 e->data.addr + state->load_base_vertex_index * e->stride);
4421         gl_info->gl_ops.gl.p_glColorPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4422                 e->data.addr + state->load_base_vertex_index * e->stride);
4423         checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)");
4424         gl_info->gl_ops.gl.p_glEnableClientState(GL_COLOR_ARRAY);
4425         checkGLcall("glEnableClientState(GL_COLOR_ARRAY)");
4426
4427     }
4428     else
4429     {
4430         gl_info->gl_ops.gl.p_glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
4431         checkGLcall("glColor4f(1, 1, 1, 1)");
4432     }
4433
4434     /* Specular Colour ------------------------------------------*/
4435     if (si->use_map & (1 << WINED3D_FFP_SPECULAR))
4436     {
4437         TRACE("setting specular colour\n");
4438
4439         e = &si->elements[WINED3D_FFP_SPECULAR];
4440
4441         if (gl_info->supported[EXT_SECONDARY_COLOR])
4442         {
4443             GLenum type = e->format->gl_vtx_type;
4444             GLint format = e->format->gl_vtx_format;
4445
4446             if (curVBO != e->data.buffer_object)
4447             {
4448                 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4449                 checkGLcall("glBindBufferARB");
4450                 curVBO = e->data.buffer_object;
4451             }
4452
4453             if (format != 4 || (gl_info->quirks & WINED3D_QUIRK_ALLOWS_SPECULAR_ALPHA))
4454             {
4455                 /* Usually specular colors only allow 3 components, since they have no alpha. In D3D, the specular alpha
4456                  * contains the fog coordinate, which is passed to GL with GL_EXT_fog_coord. However, the fixed function
4457                  * vertex pipeline can pass the specular alpha through, and pixel shaders can read it. So it GL accepts
4458                  * 4 component secondary colors use it
4459                  */
4460                 TRACE("glSecondaryColorPointer(%#x, %#x, %#x, %p);\n", format, type, e->stride,
4461                         e->data.addr + state->load_base_vertex_index * e->stride);
4462                 GL_EXTCALL(glSecondaryColorPointerEXT(format, type, e->stride,
4463                         e->data.addr + state->load_base_vertex_index * e->stride));
4464                 checkGLcall("glSecondaryColorPointerEXT(format, type, ...)");
4465             }
4466             else
4467             {
4468                 switch(type)
4469                 {
4470                     case GL_UNSIGNED_BYTE:
4471                         TRACE("glSecondaryColorPointer(3, GL_UNSIGNED_BYTE, %#x, %p);\n", e->stride,
4472                                 e->data.addr + state->load_base_vertex_index * e->stride);
4473                         GL_EXTCALL(glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, e->stride,
4474                                 e->data.addr + state->load_base_vertex_index * e->stride));
4475                         checkGLcall("glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, ...)");
4476                         break;
4477
4478                     default:
4479                         FIXME("Add 4 component specular color pointers for type %x\n", type);
4480                         /* Make sure that the right color component is dropped */
4481                         TRACE("glSecondaryColorPointer(3, %#x, %#x, %p);\n", type, e->stride,
4482                                 e->data.addr + state->load_base_vertex_index * e->stride);
4483                         GL_EXTCALL(glSecondaryColorPointerEXT(3, type, e->stride,
4484                                 e->data.addr + state->load_base_vertex_index * e->stride));
4485                         checkGLcall("glSecondaryColorPointerEXT(3, type, ...)");
4486                 }
4487             }
4488             gl_info->gl_ops.gl.p_glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
4489             checkGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
4490         }
4491         else
4492         {
4493             WARN("Specular colour is not supported in this GL implementation.\n");
4494         }
4495     }
4496     else
4497     {
4498         if (gl_info->supported[EXT_SECONDARY_COLOR])
4499         {
4500             GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0);
4501             checkGLcall("glSecondaryColor3fEXT(0, 0, 0)");
4502         }
4503         else
4504         {
4505             WARN("Specular colour is not supported in this GL implementation.\n");
4506         }
4507     }
4508
4509     /* Texture coords -------------------------------------------*/
4510     load_tex_coords(context, si, &curVBO, state);
4511 }
4512
4513 static void streamsrc(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4514 {
4515     const struct wined3d_device *device = context->swapchain->device;
4516     BOOL load_numbered = use_vs(state) && !device->useDrawStridedSlow;
4517     BOOL load_named = !use_vs(state) && !device->useDrawStridedSlow;
4518
4519     if (isStateDirty(context, STATE_VDECL)) return;
4520     if (context->numberedArraysLoaded && !load_numbered)
4521     {
4522         unload_numbered_arrays(context);
4523         context->numberedArraysLoaded = FALSE;
4524         context->numbered_array_mask = 0;
4525     }
4526     else if (context->namedArraysLoaded)
4527     {
4528         unload_vertex_data(context->gl_info);
4529         context->namedArraysLoaded = FALSE;
4530     }
4531
4532     if (load_numbered)
4533     {
4534         TRACE("Loading numbered arrays\n");
4535         load_numbered_arrays(context, &device->strided_streams, state);
4536         context->numberedArraysLoaded = TRUE;
4537     }
4538     else if (load_named)
4539     {
4540         TRACE("Loading vertex data\n");
4541         load_vertex_data(context, &device->strided_streams, state);
4542         context->namedArraysLoaded = TRUE;
4543     }
4544 }
4545
4546 static void vdecl_miscpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4547 {
4548     if (isStateDirty(context, STATE_STREAMSRC))
4549         return;
4550     streamsrc(context, state, STATE_STREAMSRC);
4551 }
4552
4553 static void vertexdeclaration(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4554 {
4555     const struct wined3d_device *device = context->swapchain->device;
4556     const struct wined3d_gl_info *gl_info = context->gl_info;
4557     BOOL useVertexShaderFunction = use_vs(state);
4558     BOOL updateFog = FALSE;
4559     BOOL transformed;
4560     BOOL wasrhw = context->last_was_rhw;
4561     unsigned int i;
4562
4563     transformed = device->strided_streams.position_transformed;
4564     if (transformed != context->last_was_rhw && !useVertexShaderFunction)
4565         updateFog = TRUE;
4566
4567     context->last_was_rhw = transformed;
4568
4569     /* Don't have to apply the matrices when vertex shaders are used. When
4570      * vshaders are turned off this function will be called again anyway to
4571      * make sure they're properly set. */
4572     if (!useVertexShaderFunction)
4573     {
4574         /* TODO: Move this mainly to the viewport state and only apply when
4575          * the vp has changed or transformed / untransformed was switched. */
4576         if (wasrhw != context->last_was_rhw
4577                 && !isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION))
4578                 && !isStateDirty(context, STATE_VIEWPORT))
4579             transform_projection(context, state, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
4580         /* World matrix needs reapplication here only if we're switching between rhw and non-rhw
4581          * mode.
4582          *
4583          * If a vertex shader is used, the world matrix changed and then vertex shader unbound
4584          * this check will fail and the matrix not applied again. This is OK because a simple
4585          * world matrix change reapplies the matrix - These checks here are only to satisfy the
4586          * needs of the vertex declaration.
4587          *
4588          * World and view matrix go into the same gl matrix, so only apply them when neither is
4589          * dirty
4590          */
4591         if (transformed != wasrhw && !isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)))
4592                 && !isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_VIEW)))
4593             transform_world(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)));
4594         if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_COLORVERTEX)))
4595             state_colormat(context, state, STATE_RENDER(WINED3D_RS_COLORVERTEX));
4596         if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_LIGHTING)))
4597             state_lighting(context, state, STATE_RENDER(WINED3D_RS_LIGHTING));
4598
4599         if (context->last_was_vshader)
4600         {
4601             updateFog = TRUE;
4602
4603             if (!device->vs_clipping && !isStateDirty(context, STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE)))
4604                 state_clipping(context, state, STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE));
4605
4606             for (i = 0; i < gl_info->limits.clipplanes; ++i)
4607             {
4608                 clipplane(context, state, STATE_CLIPPLANE(i));
4609             }
4610         }
4611         if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_NORMALIZENORMALS)))
4612             state_normalize(context, state, STATE_RENDER(WINED3D_RS_NORMALIZENORMALS));
4613     }
4614     else
4615     {
4616         if(!context->last_was_vshader) {
4617             static BOOL warned = FALSE;
4618             if(!device->vs_clipping) {
4619                 /* Disable all clip planes to get defined results on all drivers. See comment in the
4620                  * state_clipping state handler
4621                  */
4622                 for (i = 0; i < gl_info->limits.clipplanes; ++i)
4623                 {
4624                     gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE0 + i);
4625                     checkGLcall("glDisable(GL_CLIP_PLANE0 + i)");
4626                 }
4627
4628                 if (!warned && state->render_states[WINED3D_RS_CLIPPLANEENABLE])
4629                 {
4630                     FIXME("Clipping not supported with vertex shaders\n");
4631                     warned = TRUE;
4632                 }
4633             }
4634             if (wasrhw)
4635             {
4636                 /* Apply the transform matrices when switching from rhw
4637                  * drawing to vertex shaders. Vertex shaders themselves do
4638                  * not need it, but the matrices are not reapplied
4639                  * automatically when switching back from vertex shaders to
4640                  * fixed function processing. So make sure we leave the fixed
4641                  * function vertex processing states back in a sane state
4642                  * before switching to shaders. */
4643                 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION)))
4644                     transform_projection(context, state, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
4645                 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0))))
4646                     transform_world(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)));
4647             }
4648             updateFog = TRUE;
4649
4650             /* Vertex shader clipping ignores the view matrix. Update all clipplanes
4651              * (Note: ARB shaders can read the clip planes for clipping emulation even if
4652              * device->vs_clipping is false.
4653              */
4654             for (i = 0; i < gl_info->limits.clipplanes; ++i)
4655             {
4656                 clipplane(context, state, STATE_CLIPPLANE(i));
4657             }
4658         }
4659     }
4660
4661     context->last_was_vshader = useVertexShaderFunction;
4662     context->select_shader = 1;
4663     context->load_constants = 1;
4664
4665     if (updateFog)
4666         context_apply_state(context, state, STATE_RENDER(WINED3D_RS_FOGVERTEXMODE));
4667
4668     if (!useVertexShaderFunction)
4669     {
4670         unsigned int i;
4671
4672         for (i = 0; i < MAX_TEXTURES; ++i)
4673         {
4674             if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + i)))
4675                 transform_texture(context, state, STATE_TEXTURESTAGE(i, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS));
4676         }
4677     }
4678
4679     if (transformed != wasrhw && !isStateDirty(context, STATE_RENDER(WINED3D_RS_ZENABLE)))
4680         state_zenable(context, state, STATE_RENDER(WINED3D_RS_ZENABLE));
4681 }
4682
4683 static void viewport_miscpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4684 {
4685     const struct wined3d_surface *target = state->fb->render_targets[0];
4686     const struct wined3d_gl_info *gl_info = context->gl_info;
4687     struct wined3d_viewport vp = state->viewport;
4688
4689     if (vp.width > target->resource.width)
4690         vp.width = target->resource.width;
4691     if (vp.height > target->resource.height)
4692         vp.height = target->resource.height;
4693
4694     gl_info->gl_ops.gl.p_glDepthRange(vp.min_z, vp.max_z);
4695     checkGLcall("glDepthRange");
4696     /* Note: GL requires lower left, DirectX supplies upper left. This is
4697      * reversed when using offscreen rendering. */
4698     if (context->render_offscreen)
4699     {
4700         gl_info->gl_ops.gl.p_glViewport(vp.x, vp.y, vp.width, vp.height);
4701     }
4702     else
4703     {
4704         UINT width, height;
4705
4706         target->get_drawable_size(context, &width, &height);
4707         gl_info->gl_ops.gl.p_glViewport(vp.x, (height - (vp.y + vp.height)),
4708                 vp.width, vp.height);
4709     }
4710
4711     checkGLcall("glViewport");
4712 }
4713
4714 static void viewport_vertexpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4715 {
4716     if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION)))
4717         transform_projection(context, state, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
4718     if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_POINTSCALEENABLE)))
4719         state_pscale(context, state, STATE_RENDER(WINED3D_RS_POINTSCALEENABLE));
4720     /* Update the position fixup. */
4721     context->load_constants = 1;
4722 }
4723
4724 static void light(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4725 {
4726     const struct wined3d_gl_info *gl_info = context->gl_info;
4727     UINT Index = state_id - STATE_ACTIVELIGHT(0);
4728     const struct wined3d_light_info *lightInfo = state->lights[Index];
4729
4730     if (!lightInfo)
4731     {
4732         gl_info->gl_ops.gl.p_glDisable(GL_LIGHT0 + Index);
4733         checkGLcall("glDisable(GL_LIGHT0 + Index)");
4734     }
4735     else
4736     {
4737         float quad_att;
4738         float colRGBA[] = {0.0f, 0.0f, 0.0f, 0.0f};
4739
4740         /* Light settings are affected by the model view in OpenGL, the View transform in direct3d*/
4741         gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
4742         gl_info->gl_ops.gl.p_glPushMatrix();
4743         gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
4744
4745         /* Diffuse: */
4746         colRGBA[0] = lightInfo->OriginalParms.diffuse.r;
4747         colRGBA[1] = lightInfo->OriginalParms.diffuse.g;
4748         colRGBA[2] = lightInfo->OriginalParms.diffuse.b;
4749         colRGBA[3] = lightInfo->OriginalParms.diffuse.a;
4750         gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_DIFFUSE, colRGBA);
4751         checkGLcall("glLightfv");
4752
4753         /* Specular */
4754         colRGBA[0] = lightInfo->OriginalParms.specular.r;
4755         colRGBA[1] = lightInfo->OriginalParms.specular.g;
4756         colRGBA[2] = lightInfo->OriginalParms.specular.b;
4757         colRGBA[3] = lightInfo->OriginalParms.specular.a;
4758         gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_SPECULAR, colRGBA);
4759         checkGLcall("glLightfv");
4760
4761         /* Ambient */
4762         colRGBA[0] = lightInfo->OriginalParms.ambient.r;
4763         colRGBA[1] = lightInfo->OriginalParms.ambient.g;
4764         colRGBA[2] = lightInfo->OriginalParms.ambient.b;
4765         colRGBA[3] = lightInfo->OriginalParms.ambient.a;
4766         gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_AMBIENT, colRGBA);
4767         checkGLcall("glLightfv");
4768
4769         if ((lightInfo->OriginalParms.range * lightInfo->OriginalParms.range) >= FLT_MIN)
4770             quad_att = 1.4f / (lightInfo->OriginalParms.range * lightInfo->OriginalParms.range);
4771         else
4772             quad_att = 0.0f; /*  0 or  MAX?  (0 seems to be ok) */
4773
4774         /* Do not assign attenuation values for lights that do not use them. D3D apps are free to pass any junk,
4775          * but gl drivers use them and may crash due to bad Attenuation values. Need for Speed most wanted sets
4776          * Attenuation0 to NaN and crashes in the gl lib
4777          */
4778
4779         switch (lightInfo->OriginalParms.type)
4780         {
4781             case WINED3D_LIGHT_POINT:
4782                 /* Position */
4783                 gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
4784                 checkGLcall("glLightfv");
4785                 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
4786                 checkGLcall("glLightf");
4787                 /* Attenuation - Are these right? guessing... */
4788                 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_CONSTANT_ATTENUATION,
4789                         lightInfo->OriginalParms.attenuation0);
4790                 checkGLcall("glLightf");
4791                 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_LINEAR_ATTENUATION,
4792                         lightInfo->OriginalParms.attenuation1);
4793                 checkGLcall("glLightf");
4794                 if (quad_att < lightInfo->OriginalParms.attenuation2)
4795                     quad_att = lightInfo->OriginalParms.attenuation2;
4796                 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_QUADRATIC_ATTENUATION, quad_att);
4797                 checkGLcall("glLightf");
4798                 /* FIXME: Range */
4799                 break;
4800
4801             case WINED3D_LIGHT_SPOT:
4802                 /* Position */
4803                 gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
4804                 checkGLcall("glLightfv");
4805                 /* Direction */
4806                 gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_SPOT_DIRECTION, &lightInfo->lightDirn[0]);
4807                 checkGLcall("glLightfv");
4808                 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, lightInfo->exponent);
4809                 checkGLcall("glLightf");
4810                 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
4811                 checkGLcall("glLightf");
4812                 /* Attenuation - Are these right? guessing... */
4813                 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_CONSTANT_ATTENUATION,
4814                         lightInfo->OriginalParms.attenuation0);
4815                 checkGLcall("glLightf");
4816                 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_LINEAR_ATTENUATION,
4817                         lightInfo->OriginalParms.attenuation1);
4818                 checkGLcall("glLightf");
4819                 if (quad_att < lightInfo->OriginalParms.attenuation2)
4820                     quad_att = lightInfo->OriginalParms.attenuation2;
4821                 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_QUADRATIC_ATTENUATION, quad_att);
4822                 checkGLcall("glLightf");
4823                 /* FIXME: Range */
4824                 break;
4825
4826             case WINED3D_LIGHT_DIRECTIONAL:
4827                 /* Direction */
4828                 /* Note GL uses w position of 0 for direction! */
4829                 gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
4830                 checkGLcall("glLightfv");
4831                 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
4832                 checkGLcall("glLightf");
4833                 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, 0.0f);
4834                 checkGLcall("glLightf");
4835                 break;
4836
4837             default:
4838                 FIXME("Unrecognized light type %#x.\n", lightInfo->OriginalParms.type);
4839         }
4840
4841         /* Restore the modelview matrix */
4842         gl_info->gl_ops.gl.p_glPopMatrix();
4843
4844         gl_info->gl_ops.gl.p_glEnable(GL_LIGHT0 + Index);
4845         checkGLcall("glEnable(GL_LIGHT0 + Index)");
4846     }
4847 }
4848
4849 static void scissorrect(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4850 {
4851     const struct wined3d_gl_info *gl_info = context->gl_info;
4852     const RECT *r = &state->scissor_rect;
4853
4854     /* Warning: glScissor uses window coordinates, not viewport coordinates,
4855      * so our viewport correction does not apply. Warning2: Even in windowed
4856      * mode the coords are relative to the window, not the screen. */
4857     TRACE("Setting new scissor rect to %s.\n", wine_dbgstr_rect(r));
4858
4859     if (context->render_offscreen)
4860     {
4861         gl_info->gl_ops.gl.p_glScissor(r->left, r->top, r->right - r->left, r->bottom - r->top);
4862     }
4863     else
4864     {
4865         const struct wined3d_surface *target = state->fb->render_targets[0];
4866         UINT height;
4867         UINT width;
4868
4869         target->get_drawable_size(context, &width, &height);
4870         gl_info->gl_ops.gl.p_glScissor(r->left, height - r->bottom, r->right - r->left, r->bottom - r->top);
4871     }
4872     checkGLcall("glScissor");
4873 }
4874
4875 static void indexbuffer(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4876 {
4877     const struct wined3d_stream_info *stream_info = &context->swapchain->device->strided_streams;
4878     const struct wined3d_gl_info *gl_info = context->gl_info;
4879
4880     if (state->user_stream || !state->index_buffer || !stream_info->all_vbo)
4881     {
4882         GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0));
4883     }
4884     else
4885     {
4886         struct wined3d_buffer *ib = state->index_buffer;
4887         GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, ib->buffer_object));
4888     }
4889 }
4890
4891 static void frontface(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4892 {
4893     const struct wined3d_gl_info *gl_info = context->gl_info;
4894
4895     if (context->render_offscreen)
4896     {
4897         gl_info->gl_ops.gl.p_glFrontFace(GL_CCW);
4898         checkGLcall("glFrontFace(GL_CCW)");
4899     }
4900     else
4901     {
4902         gl_info->gl_ops.gl.p_glFrontFace(GL_CW);
4903         checkGLcall("glFrontFace(GL_CW)");
4904     }
4905 }
4906
4907 static void psorigin_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4908 {
4909     static BOOL warned;
4910
4911     if (!warned)
4912     {
4913         WARN("Point sprite coordinate origin switching not supported.\n");
4914         warned = TRUE;
4915     }
4916 }
4917
4918 static void psorigin(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4919 {
4920     const struct wined3d_gl_info *gl_info = context->gl_info;
4921     GLint origin = context->render_offscreen ? GL_LOWER_LEFT : GL_UPPER_LEFT;
4922
4923     if (gl_info->supported[NV_POINT_SPRITE])
4924     {
4925         GL_EXTCALL(glPointParameteriNV(GL_POINT_SPRITE_COORD_ORIGIN, origin));
4926         checkGLcall("glPointParameteriNV(GL_POINT_SPRITE_COORD_ORIGIN, ...)");
4927     }
4928 }
4929
4930 void state_srgbwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4931 {
4932     const struct wined3d_gl_info *gl_info = context->gl_info;
4933     const struct wined3d_surface *rt = state->fb->render_targets[0];
4934
4935     TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
4936
4937     if (state->render_states[WINED3D_RS_SRGBWRITEENABLE]
4938             && rt->resource.format->flags & WINED3DFMT_FLAG_SRGB_WRITE)
4939         gl_info->gl_ops.gl.p_glEnable(GL_FRAMEBUFFER_SRGB);
4940     else
4941         gl_info->gl_ops.gl.p_glDisable(GL_FRAMEBUFFER_SRGB);
4942 }
4943
4944 const struct StateEntryTemplate misc_state_template[] = {
4945     { STATE_RENDER(WINED3D_RS_SRCBLEND),                  { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
4946     { STATE_RENDER(WINED3D_RS_DESTBLEND),                 { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
4947     { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE),          { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE),          state_blend         }, WINED3D_GL_EXT_NONE             },
4948     { STATE_RENDER(WINED3D_RS_EDGEANTIALIAS),             { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
4949     { STATE_RENDER(WINED3D_RS_ANTIALIASEDLINEENABLE),     { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
4950     { STATE_RENDER(WINED3D_RS_SEPARATEALPHABLENDENABLE),  { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
4951     { STATE_RENDER(WINED3D_RS_SRCBLENDALPHA),             { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
4952     { STATE_RENDER(WINED3D_RS_DESTBLENDALPHA),            { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
4953     { STATE_RENDER(WINED3D_RS_DESTBLENDALPHA),            { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
4954     { STATE_RENDER(WINED3D_RS_BLENDOPALPHA),              { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
4955     { STATE_STREAMSRC,                                    { STATE_STREAMSRC,                                    streamsrc           }, WINED3D_GL_EXT_NONE             },
4956     { STATE_VDECL,                                        { STATE_VDECL,                                        vdecl_miscpart      }, WINED3D_GL_EXT_NONE             },
4957     { STATE_FRONTFACE,                                    { STATE_FRONTFACE,                                    frontface           }, WINED3D_GL_EXT_NONE             },
4958     { STATE_SCISSORRECT,                                  { STATE_SCISSORRECT,                                  scissorrect         }, WINED3D_GL_EXT_NONE             },
4959     { STATE_POINTSPRITECOORDORIGIN,                       { STATE_POINTSPRITECOORDORIGIN,                       psorigin            }, WINED3D_GL_VERSION_2_0          },
4960     { STATE_POINTSPRITECOORDORIGIN,                       { STATE_POINTSPRITECOORDORIGIN,                       psorigin_w          }, WINED3D_GL_EXT_NONE             },
4961
4962     /* TODO: Move shader constant loading to vertex and fragment pipeline respectively, as soon as the pshader and
4963      * vshader loadings are untied from each other
4964      */
4965     { STATE_VERTEXSHADERCONSTANT,                         { STATE_VERTEXSHADERCONSTANT,                         shaderconstant      }, WINED3D_GL_EXT_NONE             },
4966     { STATE_PIXELSHADERCONSTANT,                          { STATE_VERTEXSHADERCONSTANT,                         NULL                }, WINED3D_GL_EXT_NONE             },
4967     { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00),   { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00),   shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
4968     { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT01),   { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
4969     { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT10),   { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
4970     { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT11),   { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
4971     { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00),   { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00),   shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
4972     { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT01),   { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
4973     { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT10),   { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
4974     { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT11),   { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
4975     { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00),   { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00),   shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
4976     { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT01),   { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
4977     { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT10),   { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
4978     { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT11),   { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
4979     { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00),   { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00),   shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
4980     { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT01),   { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
4981     { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT10),   { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
4982     { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT11),   { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
4983     { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00),   { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00),   shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
4984     { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT01),   { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
4985     { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT10),   { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
4986     { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT11),   { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
4987     { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00),   { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00),   shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
4988     { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT01),   { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
4989     { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT10),   { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
4990     { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT11),   { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
4991     { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00),   { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00),   shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
4992     { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT01),   { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
4993     { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT10),   { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
4994     { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT11),   { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
4995     { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00),   { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00),   shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
4996     { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT01),   { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
4997     { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT10),   { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
4998     { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT11),   { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
4999     { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE),  { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE),  tex_bumpenvlscale   }, WINED3D_GL_EXT_NONE             },
5000     { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE),  NULL                }, WINED3D_GL_EXT_NONE             },
5001     { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE),  { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE),  tex_bumpenvlscale   }, WINED3D_GL_EXT_NONE             },
5002     { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE),  NULL                }, WINED3D_GL_EXT_NONE             },
5003     { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE),  { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE),  tex_bumpenvlscale   }, WINED3D_GL_EXT_NONE             },
5004     { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE),  NULL                }, WINED3D_GL_EXT_NONE             },
5005     { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE),  { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE),  tex_bumpenvlscale   }, WINED3D_GL_EXT_NONE             },
5006     { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE),  NULL                }, WINED3D_GL_EXT_NONE             },
5007     { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE),  { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE),  tex_bumpenvlscale   }, WINED3D_GL_EXT_NONE             },
5008     { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE),  NULL                }, WINED3D_GL_EXT_NONE             },
5009     { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE),  { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE),  tex_bumpenvlscale   }, WINED3D_GL_EXT_NONE             },
5010     { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE),  NULL                }, WINED3D_GL_EXT_NONE             },
5011     { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE),  { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE),  tex_bumpenvlscale   }, WINED3D_GL_EXT_NONE             },
5012     { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE),  NULL                }, WINED3D_GL_EXT_NONE             },
5013     { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE),  { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE),  tex_bumpenvlscale   }, WINED3D_GL_EXT_NONE             },
5014     { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE),  NULL                }, WINED3D_GL_EXT_NONE             },
5015
5016     { STATE_VIEWPORT,                                     { STATE_VIEWPORT,                                     viewport_miscpart   }, WINED3D_GL_EXT_NONE             },
5017     { STATE_INDEXBUFFER,                                  { STATE_INDEXBUFFER,                                  indexbuffer         }, ARB_VERTEX_BUFFER_OBJECT        },
5018     { STATE_INDEXBUFFER,                                  { STATE_INDEXBUFFER,                                  state_nop           }, WINED3D_GL_EXT_NONE             },
5019     { STATE_RENDER(WINED3D_RS_ANTIALIAS),                 { STATE_RENDER(WINED3D_RS_ANTIALIAS),                 state_antialias     }, WINED3D_GL_EXT_NONE             },
5020     { STATE_RENDER(WINED3D_RS_TEXTUREPERSPECTIVE),        { STATE_RENDER(WINED3D_RS_TEXTUREPERSPECTIVE),        state_perspective   }, WINED3D_GL_EXT_NONE             },
5021     { STATE_RENDER(WINED3D_RS_ZENABLE),                   { STATE_RENDER(WINED3D_RS_ZENABLE),                   state_zenable       }, WINED3D_GL_EXT_NONE             },
5022     { STATE_RENDER(WINED3D_RS_WRAPU),                     { STATE_RENDER(WINED3D_RS_WRAPU),                     state_wrapu         }, WINED3D_GL_EXT_NONE             },
5023     { STATE_RENDER(WINED3D_RS_WRAPV),                     { STATE_RENDER(WINED3D_RS_WRAPV),                     state_wrapv         }, WINED3D_GL_EXT_NONE             },
5024     { STATE_RENDER(WINED3D_RS_FILLMODE),                  { STATE_RENDER(WINED3D_RS_FILLMODE),                  state_fillmode      }, WINED3D_GL_EXT_NONE             },
5025     { STATE_RENDER(WINED3D_RS_SHADEMODE),                 { STATE_RENDER(WINED3D_RS_SHADEMODE),                 state_shademode     }, WINED3D_GL_EXT_NONE             },
5026     { STATE_RENDER(WINED3D_RS_LINEPATTERN),               { STATE_RENDER(WINED3D_RS_LINEPATTERN),               state_linepattern   }, WINED3D_GL_EXT_NONE             },
5027     { STATE_RENDER(WINED3D_RS_MONOENABLE),                { STATE_RENDER(WINED3D_RS_MONOENABLE),                state_monoenable    }, WINED3D_GL_EXT_NONE             },
5028     { STATE_RENDER(WINED3D_RS_ROP2),                      { STATE_RENDER(WINED3D_RS_ROP2),                      state_rop2          }, WINED3D_GL_EXT_NONE             },
5029     { STATE_RENDER(WINED3D_RS_PLANEMASK),                 { STATE_RENDER(WINED3D_RS_PLANEMASK),                 state_planemask     }, WINED3D_GL_EXT_NONE             },
5030     { STATE_RENDER(WINED3D_RS_ZWRITEENABLE),              { STATE_RENDER(WINED3D_RS_ZWRITEENABLE),              state_zwritenable   }, WINED3D_GL_EXT_NONE             },
5031     { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE),           { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE),           state_alpha         }, WINED3D_GL_EXT_NONE             },
5032     { STATE_RENDER(WINED3D_RS_ALPHAREF),                  { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE),           NULL                }, WINED3D_GL_EXT_NONE             },
5033     { STATE_RENDER(WINED3D_RS_ALPHAFUNC),                 { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE),           NULL                }, WINED3D_GL_EXT_NONE             },
5034     { STATE_RENDER(WINED3D_RS_COLORKEYENABLE),            { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE),           NULL                }, WINED3D_GL_EXT_NONE             },
5035     { STATE_RENDER(WINED3D_RS_LASTPIXEL),                 { STATE_RENDER(WINED3D_RS_LASTPIXEL),                 state_lastpixel     }, WINED3D_GL_EXT_NONE             },
5036     { STATE_RENDER(WINED3D_RS_CULLMODE),                  { STATE_RENDER(WINED3D_RS_CULLMODE),                  state_cullmode      }, WINED3D_GL_EXT_NONE             },
5037     { STATE_RENDER(WINED3D_RS_ZFUNC),                     { STATE_RENDER(WINED3D_RS_ZFUNC),                     state_zfunc         }, WINED3D_GL_EXT_NONE             },
5038     { STATE_RENDER(WINED3D_RS_DITHERENABLE),              { STATE_RENDER(WINED3D_RS_DITHERENABLE),              state_ditherenable  }, WINED3D_GL_EXT_NONE             },
5039     { STATE_RENDER(WINED3D_RS_SUBPIXEL),                  { STATE_RENDER(WINED3D_RS_SUBPIXEL),                  state_subpixel      }, WINED3D_GL_EXT_NONE             },
5040     { STATE_RENDER(WINED3D_RS_SUBPIXELX),                 { STATE_RENDER(WINED3D_RS_SUBPIXELX),                 state_subpixelx     }, WINED3D_GL_EXT_NONE             },
5041     { STATE_RENDER(WINED3D_RS_STIPPLEDALPHA),             { STATE_RENDER(WINED3D_RS_STIPPLEDALPHA),             state_stippledalpha }, WINED3D_GL_EXT_NONE             },
5042     { STATE_RENDER(WINED3D_RS_STIPPLEENABLE),             { STATE_RENDER(WINED3D_RS_STIPPLEENABLE),             state_stippleenable }, WINED3D_GL_EXT_NONE             },
5043     { STATE_RENDER(WINED3D_RS_MIPMAPLODBIAS),             { STATE_RENDER(WINED3D_RS_MIPMAPLODBIAS),             state_mipmaplodbias }, WINED3D_GL_EXT_NONE             },
5044     { STATE_RENDER(WINED3D_RS_ANISOTROPY),                { STATE_RENDER(WINED3D_RS_ANISOTROPY),                state_anisotropy    }, WINED3D_GL_EXT_NONE             },
5045     { STATE_RENDER(WINED3D_RS_FLUSHBATCH),                { STATE_RENDER(WINED3D_RS_FLUSHBATCH),                state_flushbatch    }, WINED3D_GL_EXT_NONE             },
5046     { STATE_RENDER(WINED3D_RS_TRANSLUCENTSORTINDEPENDENT),{ STATE_RENDER(WINED3D_RS_TRANSLUCENTSORTINDEPENDENT),state_translucentsi }, WINED3D_GL_EXT_NONE             },
5047     { STATE_RENDER(WINED3D_RS_STENCILENABLE),             { STATE_RENDER(WINED3D_RS_STENCILENABLE),             state_stencil       }, WINED3D_GL_EXT_NONE             },
5048     { STATE_RENDER(WINED3D_RS_STENCILFAIL),               { STATE_RENDER(WINED3D_RS_STENCILENABLE),             NULL                }, WINED3D_GL_EXT_NONE             },
5049     { STATE_RENDER(WINED3D_RS_STENCILZFAIL),              { STATE_RENDER(WINED3D_RS_STENCILENABLE),             NULL                }, WINED3D_GL_EXT_NONE             },
5050     { STATE_RENDER(WINED3D_RS_STENCILPASS),               { STATE_RENDER(WINED3D_RS_STENCILENABLE),             NULL                }, WINED3D_GL_EXT_NONE             },
5051     { STATE_RENDER(WINED3D_RS_STENCILFUNC),               { STATE_RENDER(WINED3D_RS_STENCILENABLE),             NULL                }, WINED3D_GL_EXT_NONE             },
5052     { STATE_RENDER(WINED3D_RS_STENCILREF),                { STATE_RENDER(WINED3D_RS_STENCILENABLE),             NULL                }, WINED3D_GL_EXT_NONE             },
5053     { STATE_RENDER(WINED3D_RS_STENCILMASK),               { STATE_RENDER(WINED3D_RS_STENCILENABLE),             NULL                }, WINED3D_GL_EXT_NONE             },
5054     { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK),          { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK),          state_stencilwrite2s}, EXT_STENCIL_TWO_SIDE            },
5055     { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK),          { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK),          state_stencilwrite  }, WINED3D_GL_EXT_NONE             },
5056     { STATE_RENDER(WINED3D_RS_TWOSIDEDSTENCILMODE),       { STATE_RENDER(WINED3D_RS_STENCILENABLE),             NULL                }, WINED3D_GL_EXT_NONE             },
5057     { STATE_RENDER(WINED3D_RS_CCW_STENCILFAIL),           { STATE_RENDER(WINED3D_RS_STENCILENABLE),             NULL                }, WINED3D_GL_EXT_NONE             },
5058     { STATE_RENDER(WINED3D_RS_CCW_STENCILZFAIL),          { STATE_RENDER(WINED3D_RS_STENCILENABLE),             NULL                }, WINED3D_GL_EXT_NONE             },
5059     { STATE_RENDER(WINED3D_RS_CCW_STENCILPASS),           { STATE_RENDER(WINED3D_RS_STENCILENABLE),             NULL                }, WINED3D_GL_EXT_NONE             },
5060     { STATE_RENDER(WINED3D_RS_CCW_STENCILFUNC),           { STATE_RENDER(WINED3D_RS_STENCILENABLE),             NULL                }, WINED3D_GL_EXT_NONE             },
5061     { STATE_RENDER(WINED3D_RS_WRAP0),                     { STATE_RENDER(WINED3D_RS_WRAP0),                     state_wrap          }, WINED3D_GL_EXT_NONE             },
5062     { STATE_RENDER(WINED3D_RS_WRAP1),                     { STATE_RENDER(WINED3D_RS_WRAP0),                     NULL                }, WINED3D_GL_EXT_NONE             },
5063     { STATE_RENDER(WINED3D_RS_WRAP2),                     { STATE_RENDER(WINED3D_RS_WRAP0),                     NULL                }, WINED3D_GL_EXT_NONE             },
5064     { STATE_RENDER(WINED3D_RS_WRAP3),                     { STATE_RENDER(WINED3D_RS_WRAP0),                     NULL                }, WINED3D_GL_EXT_NONE             },
5065     { STATE_RENDER(WINED3D_RS_WRAP4),                     { STATE_RENDER(WINED3D_RS_WRAP0),                     NULL                }, WINED3D_GL_EXT_NONE             },
5066     { STATE_RENDER(WINED3D_RS_WRAP5),                     { STATE_RENDER(WINED3D_RS_WRAP0),                     NULL                }, WINED3D_GL_EXT_NONE             },
5067     { STATE_RENDER(WINED3D_RS_WRAP6),                     { STATE_RENDER(WINED3D_RS_WRAP0),                     NULL                }, WINED3D_GL_EXT_NONE             },
5068     { STATE_RENDER(WINED3D_RS_WRAP7),                     { STATE_RENDER(WINED3D_RS_WRAP0),                     NULL                }, WINED3D_GL_EXT_NONE             },
5069     { STATE_RENDER(WINED3D_RS_WRAP8),                     { STATE_RENDER(WINED3D_RS_WRAP0),                     NULL                }, WINED3D_GL_EXT_NONE             },
5070     { STATE_RENDER(WINED3D_RS_WRAP9),                     { STATE_RENDER(WINED3D_RS_WRAP0),                     NULL                }, WINED3D_GL_EXT_NONE             },
5071     { STATE_RENDER(WINED3D_RS_WRAP10),                    { STATE_RENDER(WINED3D_RS_WRAP0),                     NULL                }, WINED3D_GL_EXT_NONE             },
5072     { STATE_RENDER(WINED3D_RS_WRAP11),                    { STATE_RENDER(WINED3D_RS_WRAP0),                     NULL                }, WINED3D_GL_EXT_NONE             },
5073     { STATE_RENDER(WINED3D_RS_WRAP12),                    { STATE_RENDER(WINED3D_RS_WRAP0),                     NULL                }, WINED3D_GL_EXT_NONE             },
5074     { STATE_RENDER(WINED3D_RS_WRAP13),                    { STATE_RENDER(WINED3D_RS_WRAP0),                     NULL                }, WINED3D_GL_EXT_NONE             },
5075     { STATE_RENDER(WINED3D_RS_WRAP14),                    { STATE_RENDER(WINED3D_RS_WRAP0),                     NULL                }, WINED3D_GL_EXT_NONE             },
5076     { STATE_RENDER(WINED3D_RS_WRAP15),                    { STATE_RENDER(WINED3D_RS_WRAP0),                     NULL                }, WINED3D_GL_EXT_NONE             },
5077     { STATE_RENDER(WINED3D_RS_EXTENTS),                   { STATE_RENDER(WINED3D_RS_EXTENTS),                   state_extents       }, WINED3D_GL_EXT_NONE             },
5078     { STATE_RENDER(WINED3D_RS_COLORKEYBLENDENABLE),       { STATE_RENDER(WINED3D_RS_COLORKEYBLENDENABLE),       state_ckeyblend     }, WINED3D_GL_EXT_NONE             },
5079     { STATE_RENDER(WINED3D_RS_SOFTWAREVERTEXPROCESSING),  { STATE_RENDER(WINED3D_RS_SOFTWAREVERTEXPROCESSING),  state_swvp          }, WINED3D_GL_EXT_NONE             },
5080     { STATE_RENDER(WINED3D_RS_PATCHEDGESTYLE),            { STATE_RENDER(WINED3D_RS_PATCHEDGESTYLE),            state_patchedgestyle}, WINED3D_GL_EXT_NONE             },
5081     { STATE_RENDER(WINED3D_RS_PATCHSEGMENTS),             { STATE_RENDER(WINED3D_RS_PATCHSEGMENTS),             state_patchsegments }, WINED3D_GL_EXT_NONE             },
5082     { STATE_RENDER(WINED3D_RS_POSITIONDEGREE),            { STATE_RENDER(WINED3D_RS_POSITIONDEGREE),            state_positiondegree}, WINED3D_GL_EXT_NONE             },
5083     { STATE_RENDER(WINED3D_RS_NORMALDEGREE),              { STATE_RENDER(WINED3D_RS_NORMALDEGREE),              state_normaldegree  }, WINED3D_GL_EXT_NONE             },
5084     { STATE_RENDER(WINED3D_RS_MINTESSELLATIONLEVEL),      { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL                }, WINED3D_GL_EXT_NONE             },
5085     { STATE_RENDER(WINED3D_RS_MAXTESSELLATIONLEVEL),      { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL                }, WINED3D_GL_EXT_NONE             },
5086     { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_X),            { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL                }, WINED3D_GL_EXT_NONE             },
5087     { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_Y),            { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL                }, WINED3D_GL_EXT_NONE             },
5088     { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_Z),            { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL                }, WINED3D_GL_EXT_NONE             },
5089     { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_W),            { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL                }, WINED3D_GL_EXT_NONE             },
5090     { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),{ STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),state_nvdb          }, EXT_DEPTH_BOUNDS_TEST           },
5091     { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),{ STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),state_tessellation  }, WINED3D_GL_EXT_NONE             },
5092     { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS),      { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS),      state_msaa          }, ARB_MULTISAMPLE                 },
5093     { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS),      { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS),      state_msaa_w        }, WINED3D_GL_EXT_NONE             },
5094     { STATE_RENDER(WINED3D_RS_MULTISAMPLEMASK),           { STATE_RENDER(WINED3D_RS_MULTISAMPLEMASK),           state_multisampmask }, WINED3D_GL_EXT_NONE             },
5095     { STATE_RENDER(WINED3D_RS_DEBUGMONITORTOKEN),         { STATE_RENDER(WINED3D_RS_DEBUGMONITORTOKEN),         state_debug_monitor }, WINED3D_GL_EXT_NONE             },
5096     { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE),          { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE),          state_colorwrite0   }, EXT_DRAW_BUFFERS2               },
5097     { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE),          { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE),          state_colorwrite    }, WINED3D_GL_EXT_NONE             },
5098     { STATE_RENDER(WINED3D_RS_BLENDOP),                   { STATE_RENDER(WINED3D_RS_BLENDOP),                   state_blendop       }, EXT_BLEND_MINMAX                },
5099     { STATE_RENDER(WINED3D_RS_BLENDOP),                   { STATE_RENDER(WINED3D_RS_BLENDOP),                   state_blendop_w     }, WINED3D_GL_EXT_NONE             },
5100     { STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE),         { STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE),         state_scissor       }, WINED3D_GL_EXT_NONE             },
5101     { STATE_RENDER(WINED3D_RS_SLOPESCALEDEPTHBIAS),       { STATE_RENDER(WINED3D_RS_DEPTHBIAS),                 NULL                }, WINED3D_GL_EXT_NONE             },
5102     { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1),         { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1),         state_colorwrite1   }, EXT_DRAW_BUFFERS2               },
5103     { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1),         { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
5104     { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2),         { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2),         state_colorwrite2   }, EXT_DRAW_BUFFERS2               },
5105     { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2),         { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
5106     { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3),         { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3),         state_colorwrite3   }, EXT_DRAW_BUFFERS2               },
5107     { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3),         { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
5108     { STATE_RENDER(WINED3D_RS_BLENDFACTOR),               { STATE_RENDER(WINED3D_RS_BLENDFACTOR),               state_blendfactor   }, EXT_BLEND_COLOR                 },
5109     { STATE_RENDER(WINED3D_RS_BLENDFACTOR),               { STATE_RENDER(WINED3D_RS_BLENDFACTOR),               state_blendfactor_w }, WINED3D_GL_EXT_NONE             },
5110     { STATE_RENDER(WINED3D_RS_DEPTHBIAS),                 { STATE_RENDER(WINED3D_RS_DEPTHBIAS),                 state_depthbias     }, WINED3D_GL_EXT_NONE             },
5111     { STATE_RENDER(WINED3D_RS_ZVISIBLE),                  { STATE_RENDER(WINED3D_RS_ZVISIBLE),                  state_zvisible      }, WINED3D_GL_EXT_NONE             },
5112     /* Samplers */
5113     { STATE_SAMPLER(0),                                   { STATE_SAMPLER(0),                                   sampler             }, WINED3D_GL_EXT_NONE             },
5114     { STATE_SAMPLER(1),                                   { STATE_SAMPLER(1),                                   sampler             }, WINED3D_GL_EXT_NONE             },
5115     { STATE_SAMPLER(2),                                   { STATE_SAMPLER(2),                                   sampler             }, WINED3D_GL_EXT_NONE             },
5116     { STATE_SAMPLER(3),                                   { STATE_SAMPLER(3),                                   sampler             }, WINED3D_GL_EXT_NONE             },
5117     { STATE_SAMPLER(4),                                   { STATE_SAMPLER(4),                                   sampler             }, WINED3D_GL_EXT_NONE             },
5118     { STATE_SAMPLER(5),                                   { STATE_SAMPLER(5),                                   sampler             }, WINED3D_GL_EXT_NONE             },
5119     { STATE_SAMPLER(6),                                   { STATE_SAMPLER(6),                                   sampler             }, WINED3D_GL_EXT_NONE             },
5120     { STATE_SAMPLER(7),                                   { STATE_SAMPLER(7),                                   sampler             }, WINED3D_GL_EXT_NONE             },
5121     { STATE_SAMPLER(8),                                   { STATE_SAMPLER(8),                                   sampler             }, WINED3D_GL_EXT_NONE             },
5122     { STATE_SAMPLER(9),                                   { STATE_SAMPLER(9),                                   sampler             }, WINED3D_GL_EXT_NONE             },
5123     { STATE_SAMPLER(10),                                  { STATE_SAMPLER(10),                                  sampler             }, WINED3D_GL_EXT_NONE             },
5124     { STATE_SAMPLER(11),                                  { STATE_SAMPLER(11),                                  sampler             }, WINED3D_GL_EXT_NONE             },
5125     { STATE_SAMPLER(12),                                  { STATE_SAMPLER(12),                                  sampler             }, WINED3D_GL_EXT_NONE             },
5126     { STATE_SAMPLER(13),                                  { STATE_SAMPLER(13),                                  sampler             }, WINED3D_GL_EXT_NONE             },
5127     { STATE_SAMPLER(14),                                  { STATE_SAMPLER(14),                                  sampler             }, WINED3D_GL_EXT_NONE             },
5128     { STATE_SAMPLER(15),                                  { STATE_SAMPLER(15),                                  sampler             }, WINED3D_GL_EXT_NONE             },
5129     { STATE_SAMPLER(16), /* Vertex sampler 0 */           { STATE_SAMPLER(16),                                  sampler             }, WINED3D_GL_EXT_NONE             },
5130     { STATE_SAMPLER(17), /* Vertex sampler 1 */           { STATE_SAMPLER(17),                                  sampler             }, WINED3D_GL_EXT_NONE             },
5131     { STATE_SAMPLER(18), /* Vertex sampler 2 */           { STATE_SAMPLER(18),                                  sampler             }, WINED3D_GL_EXT_NONE             },
5132     { STATE_SAMPLER(19), /* Vertex sampler 3 */           { STATE_SAMPLER(19),                                  sampler             }, WINED3D_GL_EXT_NONE             },
5133     { STATE_BASEVERTEXINDEX,                              { STATE_BASEVERTEXINDEX,                              state_nop,          }, ARB_DRAW_ELEMENTS_BASE_VERTEX   },
5134     { STATE_BASEVERTEXINDEX,                              { STATE_STREAMSRC,                                    NULL,               }, WINED3D_GL_EXT_NONE             },
5135     { STATE_FRAMEBUFFER,                                  { STATE_FRAMEBUFFER,                                  context_state_fb    }, WINED3D_GL_EXT_NONE             },
5136     { STATE_PIXELSHADER,                                  { STATE_PIXELSHADER,                                  context_state_drawbuf},WINED3D_GL_EXT_NONE             },
5137     { STATE_GEOMETRY_SHADER,                              { STATE_GEOMETRY_SHADER,                              state_geometry_shader}, WINED3D_GL_EXT_NONE             },
5138     {0 /* Terminate */,                                   { 0,                                                  0                   }, WINED3D_GL_EXT_NONE             },
5139 };
5140
5141 const struct StateEntryTemplate ffp_vertexstate_template[] = {
5142     { STATE_VDECL,                                        { STATE_VDECL,                                        vertexdeclaration   }, WINED3D_GL_EXT_NONE             },
5143     { STATE_VSHADER,                                      { STATE_VDECL,                                        NULL                }, WINED3D_GL_EXT_NONE             },
5144     { STATE_MATERIAL,                                     { STATE_RENDER(WINED3D_RS_SPECULARENABLE),            NULL                }, WINED3D_GL_EXT_NONE             },
5145     { STATE_RENDER(WINED3D_RS_SPECULARENABLE),            { STATE_RENDER(WINED3D_RS_SPECULARENABLE),            state_specularenable}, WINED3D_GL_EXT_NONE             },
5146       /* Clip planes */
5147     { STATE_CLIPPLANE(0),                                 { STATE_CLIPPLANE(0),                                 clipplane           }, WINED3D_GL_EXT_NONE             },
5148     { STATE_CLIPPLANE(1),                                 { STATE_CLIPPLANE(1),                                 clipplane           }, WINED3D_GL_EXT_NONE             },
5149     { STATE_CLIPPLANE(2),                                 { STATE_CLIPPLANE(2),                                 clipplane           }, WINED3D_GL_EXT_NONE             },
5150     { STATE_CLIPPLANE(3),                                 { STATE_CLIPPLANE(3),                                 clipplane           }, WINED3D_GL_EXT_NONE             },
5151     { STATE_CLIPPLANE(4),                                 { STATE_CLIPPLANE(4),                                 clipplane           }, WINED3D_GL_EXT_NONE             },
5152     { STATE_CLIPPLANE(5),                                 { STATE_CLIPPLANE(5),                                 clipplane           }, WINED3D_GL_EXT_NONE             },
5153     { STATE_CLIPPLANE(6),                                 { STATE_CLIPPLANE(6),                                 clipplane           }, WINED3D_GL_EXT_NONE             },
5154     { STATE_CLIPPLANE(7),                                 { STATE_CLIPPLANE(7),                                 clipplane           }, WINED3D_GL_EXT_NONE             },
5155     { STATE_CLIPPLANE(8),                                 { STATE_CLIPPLANE(8),                                 clipplane           }, WINED3D_GL_EXT_NONE             },
5156     { STATE_CLIPPLANE(9),                                 { STATE_CLIPPLANE(9),                                 clipplane           }, WINED3D_GL_EXT_NONE             },
5157     { STATE_CLIPPLANE(10),                                { STATE_CLIPPLANE(10),                                clipplane           }, WINED3D_GL_EXT_NONE             },
5158     { STATE_CLIPPLANE(11),                                { STATE_CLIPPLANE(11),                                clipplane           }, WINED3D_GL_EXT_NONE             },
5159     { STATE_CLIPPLANE(12),                                { STATE_CLIPPLANE(12),                                clipplane           }, WINED3D_GL_EXT_NONE             },
5160     { STATE_CLIPPLANE(13),                                { STATE_CLIPPLANE(13),                                clipplane           }, WINED3D_GL_EXT_NONE             },
5161     { STATE_CLIPPLANE(14),                                { STATE_CLIPPLANE(14),                                clipplane           }, WINED3D_GL_EXT_NONE             },
5162     { STATE_CLIPPLANE(15),                                { STATE_CLIPPLANE(15),                                clipplane           }, WINED3D_GL_EXT_NONE             },
5163     { STATE_CLIPPLANE(16),                                { STATE_CLIPPLANE(16),                                clipplane           }, WINED3D_GL_EXT_NONE             },
5164     { STATE_CLIPPLANE(17),                                { STATE_CLIPPLANE(17),                                clipplane           }, WINED3D_GL_EXT_NONE             },
5165     { STATE_CLIPPLANE(18),                                { STATE_CLIPPLANE(18),                                clipplane           }, WINED3D_GL_EXT_NONE             },
5166     { STATE_CLIPPLANE(19),                                { STATE_CLIPPLANE(19),                                clipplane           }, WINED3D_GL_EXT_NONE             },
5167     { STATE_CLIPPLANE(20),                                { STATE_CLIPPLANE(20),                                clipplane           }, WINED3D_GL_EXT_NONE             },
5168     { STATE_CLIPPLANE(21),                                { STATE_CLIPPLANE(21),                                clipplane           }, WINED3D_GL_EXT_NONE             },
5169     { STATE_CLIPPLANE(22),                                { STATE_CLIPPLANE(22),                                clipplane           }, WINED3D_GL_EXT_NONE             },
5170     { STATE_CLIPPLANE(23),                                { STATE_CLIPPLANE(23),                                clipplane           }, WINED3D_GL_EXT_NONE             },
5171     { STATE_CLIPPLANE(24),                                { STATE_CLIPPLANE(24),                                clipplane           }, WINED3D_GL_EXT_NONE             },
5172     { STATE_CLIPPLANE(25),                                { STATE_CLIPPLANE(25),                                clipplane           }, WINED3D_GL_EXT_NONE             },
5173     { STATE_CLIPPLANE(26),                                { STATE_CLIPPLANE(26),                                clipplane           }, WINED3D_GL_EXT_NONE             },
5174     { STATE_CLIPPLANE(27),                                { STATE_CLIPPLANE(27),                                clipplane           }, WINED3D_GL_EXT_NONE             },
5175     { STATE_CLIPPLANE(28),                                { STATE_CLIPPLANE(28),                                clipplane           }, WINED3D_GL_EXT_NONE             },
5176     { STATE_CLIPPLANE(29),                                { STATE_CLIPPLANE(29),                                clipplane           }, WINED3D_GL_EXT_NONE             },
5177     { STATE_CLIPPLANE(30),                                { STATE_CLIPPLANE(30),                                clipplane           }, WINED3D_GL_EXT_NONE             },
5178     { STATE_CLIPPLANE(31),                                { STATE_CLIPPLANE(31),                                clipplane           }, WINED3D_GL_EXT_NONE             },
5179       /* Lights */
5180     { STATE_ACTIVELIGHT(0),                               { STATE_ACTIVELIGHT(0),                               light               }, WINED3D_GL_EXT_NONE             },
5181     { STATE_ACTIVELIGHT(1),                               { STATE_ACTIVELIGHT(1),                               light               }, WINED3D_GL_EXT_NONE             },
5182     { STATE_ACTIVELIGHT(2),                               { STATE_ACTIVELIGHT(2),                               light               }, WINED3D_GL_EXT_NONE             },
5183     { STATE_ACTIVELIGHT(3),                               { STATE_ACTIVELIGHT(3),                               light               }, WINED3D_GL_EXT_NONE             },
5184     { STATE_ACTIVELIGHT(4),                               { STATE_ACTIVELIGHT(4),                               light               }, WINED3D_GL_EXT_NONE             },
5185     { STATE_ACTIVELIGHT(5),                               { STATE_ACTIVELIGHT(5),                               light               }, WINED3D_GL_EXT_NONE             },
5186     { STATE_ACTIVELIGHT(6),                               { STATE_ACTIVELIGHT(6),                               light               }, WINED3D_GL_EXT_NONE             },
5187     { STATE_ACTIVELIGHT(7),                               { STATE_ACTIVELIGHT(7),                               light               }, WINED3D_GL_EXT_NONE             },
5188     /* Viewport */
5189     { STATE_VIEWPORT,                                     { STATE_VIEWPORT,                                     viewport_vertexpart }, WINED3D_GL_EXT_NONE             },
5190       /* Transform states follow                    */
5191     { STATE_TRANSFORM(WINED3D_TS_VIEW),                   { STATE_TRANSFORM(WINED3D_TS_VIEW),                   transform_view      }, WINED3D_GL_EXT_NONE             },
5192     { STATE_TRANSFORM(WINED3D_TS_PROJECTION),             { STATE_TRANSFORM(WINED3D_TS_PROJECTION),             transform_projection}, WINED3D_GL_EXT_NONE             },
5193     { STATE_TRANSFORM(WINED3D_TS_TEXTURE0),               { STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL            }, WINED3D_GL_EXT_NONE             },
5194     { STATE_TRANSFORM(WINED3D_TS_TEXTURE1),               { STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL            }, WINED3D_GL_EXT_NONE             },
5195     { STATE_TRANSFORM(WINED3D_TS_TEXTURE2),               { STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL            }, WINED3D_GL_EXT_NONE             },
5196     { STATE_TRANSFORM(WINED3D_TS_TEXTURE3),               { STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL            }, WINED3D_GL_EXT_NONE             },
5197     { STATE_TRANSFORM(WINED3D_TS_TEXTURE4),               { STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL            }, WINED3D_GL_EXT_NONE             },
5198     { STATE_TRANSFORM(WINED3D_TS_TEXTURE5),               { STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL            }, WINED3D_GL_EXT_NONE             },
5199     { STATE_TRANSFORM(WINED3D_TS_TEXTURE6),               { STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL            }, WINED3D_GL_EXT_NONE             },
5200     { STATE_TRANSFORM(WINED3D_TS_TEXTURE7),               { STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL            }, WINED3D_GL_EXT_NONE             },
5201     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  0)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  0)),      transform_world     }, WINED3D_GL_EXT_NONE             },
5202     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  1)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  1)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5203     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  2)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  2)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5204     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  3)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  3)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5205     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  4)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  4)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5206     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  5)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  5)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5207     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  6)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  6)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5208     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  7)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  7)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5209     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  8)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  8)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5210     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  9)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  9)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5211     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 10)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 10)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5212     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 11)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 11)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5213     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 12)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 12)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5214     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 13)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 13)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5215     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 14)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 14)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5216     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 15)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 15)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5217     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 16)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 16)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5218     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 17)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 17)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5219     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 18)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 18)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5220     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 19)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 19)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5221     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 20)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 20)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5222     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 21)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 21)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5223     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 22)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 22)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5224     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 23)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 23)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5225     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 24)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 24)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5226     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 25)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 25)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5227     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 26)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 26)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5228     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 27)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 27)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5229     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 28)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 28)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5230     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 29)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 29)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5231     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 30)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 30)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5232     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 31)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 31)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5233     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 32)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 32)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5234     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 33)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 33)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5235     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 34)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 34)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5236     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 35)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 35)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5237     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 36)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 36)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5238     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 37)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 37)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5239     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 38)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 38)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5240     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 39)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 39)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5241     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 40)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 40)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5242     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 41)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 41)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5243     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 42)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 42)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5244     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 43)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 43)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5245     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 44)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 44)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5246     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 45)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 45)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5247     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 46)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 46)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5248     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 47)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 47)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5249     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 48)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 48)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5250     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 49)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 49)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5251     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 50)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 50)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5252     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 51)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 51)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5253     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 52)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 52)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5254     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 53)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 53)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5255     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 54)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 54)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5256     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 55)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 55)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5257     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 56)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 56)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5258     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 57)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 57)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5259     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 58)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 58)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5260     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 59)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 59)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5261     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 60)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 60)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5262     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 61)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 61)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5263     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 62)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 62)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5264     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 63)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 63)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5265     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 64)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 64)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5266     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 65)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 65)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5267     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 66)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 66)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5268     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 67)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 67)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5269     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 68)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 68)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5270     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 69)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 69)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5271     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 70)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 70)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5272     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 71)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 71)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5273     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 72)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 72)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5274     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 73)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 73)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5275     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 74)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 74)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5276     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 75)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 75)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5277     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 76)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 76)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5278     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 77)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 77)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5279     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 78)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 78)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5280     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 79)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 79)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5281     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 80)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 80)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5282     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 81)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 81)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5283     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 82)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 82)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5284     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 83)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 83)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5285     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 84)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 84)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5286     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 85)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 85)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5287     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 86)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 86)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5288     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 87)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 87)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5289     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 88)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 88)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5290     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 89)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 89)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5291     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 90)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 90)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5292     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 91)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 91)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5293     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 92)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 92)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5294     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 93)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 93)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5295     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 94)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 94)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5296     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 95)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 95)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5297     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 96)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 96)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5298     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 97)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 97)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5299     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 98)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 98)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5300     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 99)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 99)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5301     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(100)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(100)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5302     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(101)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(101)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5303     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(102)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(102)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5304     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(103)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(103)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5305     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(104)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(104)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5306     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(105)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(105)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5307     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(106)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(106)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5308     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(107)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(107)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5309     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(108)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(108)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5310     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(109)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(109)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5311     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(110)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(110)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5312     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(111)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(111)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5313     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(112)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(112)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5314     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(113)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(113)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5315     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(114)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(114)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5316     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(115)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(115)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5317     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(116)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(116)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5318     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(117)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(117)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5319     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(118)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(118)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5320     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(119)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(119)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5321     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(120)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(120)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5322     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(121)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(121)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5323     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(122)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(122)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5324     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(123)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(123)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5325     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(124)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(124)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5326     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(125)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(125)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5327     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(126)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(126)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5328     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(127)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(127)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5329     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(128)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(128)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5330     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(129)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(129)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5331     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(130)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(130)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5332     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(131)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(131)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5333     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(132)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(132)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5334     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(133)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(133)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5335     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(134)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(134)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5336     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(135)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(135)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5337     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(136)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(136)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5338     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(137)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(137)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5339     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(138)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(138)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5340     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(139)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(139)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5341     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(140)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(140)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5342     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(141)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(141)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5343     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(142)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(142)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5344     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(143)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(143)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5345     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(144)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(144)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5346     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(145)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(145)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5347     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(146)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(146)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5348     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(147)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(147)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5349     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(148)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(148)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5350     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(149)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(149)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5351     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(150)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(150)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5352     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(151)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(151)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5353     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(152)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(152)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5354     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(153)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(153)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5355     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(154)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(154)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5356     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(155)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(155)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5357     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(156)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(156)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5358     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(157)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(157)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5359     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(158)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(158)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5360     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(159)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(159)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5361     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(160)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(160)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5362     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(161)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(161)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5363     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(162)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(162)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5364     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(163)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(163)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5365     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(164)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(164)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5366     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(165)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(165)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5367     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(166)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(166)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5368     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(167)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(167)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5369     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(168)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(168)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5370     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(169)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(169)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5371     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(170)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(170)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5372     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(171)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(171)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5373     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(172)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(172)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5374     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(173)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(173)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5375     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(174)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(174)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5376     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(175)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(175)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5377     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(176)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(176)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5378     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(177)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(177)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5379     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(178)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(178)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5380     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(179)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(179)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5381     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(180)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(180)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5382     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(181)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(181)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5383     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(182)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(182)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5384     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(183)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(183)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5385     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(184)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(184)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5386     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(185)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(185)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5387     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(186)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(186)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5388     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(187)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(187)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5389     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(188)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(188)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5390     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(189)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(189)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5391     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(190)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(190)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5392     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(191)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(191)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5393     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(192)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(192)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5394     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(193)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(193)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5395     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(194)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(194)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5396     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(195)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(195)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5397     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(196)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(196)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5398     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(197)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(197)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5399     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(198)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(198)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5400     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(199)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(199)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5401     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(200)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(200)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5402     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(201)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(201)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5403     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(202)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(202)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5404     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(203)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(203)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5405     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(204)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(204)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5406     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(205)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(205)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5407     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(206)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(206)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5408     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(207)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(207)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5409     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(208)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(208)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5410     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(209)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(209)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5411     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(210)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(210)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5412     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(211)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(211)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5413     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(212)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(212)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5414     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(213)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(213)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5415     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(214)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(214)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5416     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(215)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(215)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5417     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(216)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(216)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5418     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(217)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(217)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5419     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(218)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(218)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5420     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(219)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(219)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5421     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(220)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(220)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5422     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(221)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(221)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5423     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(222)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(222)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5424     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(223)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(223)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5425     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(224)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(224)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5426     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(225)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(225)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5427     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(226)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(226)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5428     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(227)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(227)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5429     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(228)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(228)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5430     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(229)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(229)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5431     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(230)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(230)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5432     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(231)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(231)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5433     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(232)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(232)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5434     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(233)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(233)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5435     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(234)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(234)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5436     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(235)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(235)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5437     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(236)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(236)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5438     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(237)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(237)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5439     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(238)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(238)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5440     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(239)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(239)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5441     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(240)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(240)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5442     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(241)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(241)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5443     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(242)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(242)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5444     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(243)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(243)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5445     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(244)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(244)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5446     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(245)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(245)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5447     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(246)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(246)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5448     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(247)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(247)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5449     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(248)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(248)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5450     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(249)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(249)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5451     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(250)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(250)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5452     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(251)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(251)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5453     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(252)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(252)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5454     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(253)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(253)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5455     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(254)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(254)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5456     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
5457     { STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture   }, WINED3D_GL_EXT_NONE             },
5458     { STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture   }, WINED3D_GL_EXT_NONE             },
5459     { STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture   }, WINED3D_GL_EXT_NONE             },
5460     { STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture   }, WINED3D_GL_EXT_NONE             },
5461     { STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture   }, WINED3D_GL_EXT_NONE             },
5462     { STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture   }, WINED3D_GL_EXT_NONE             },
5463     { STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture   }, WINED3D_GL_EXT_NONE             },
5464     { STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture   }, WINED3D_GL_EXT_NONE             },
5465     { STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXCOORD_INDEX),  { STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXCOORD_INDEX),  tex_coordindex      }, WINED3D_GL_EXT_NONE             },
5466     { STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXCOORD_INDEX),  { STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXCOORD_INDEX),  tex_coordindex      }, WINED3D_GL_EXT_NONE             },
5467     { STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXCOORD_INDEX),  { STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXCOORD_INDEX),  tex_coordindex      }, WINED3D_GL_EXT_NONE             },
5468     { STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXCOORD_INDEX),  { STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXCOORD_INDEX),  tex_coordindex      }, WINED3D_GL_EXT_NONE             },
5469     { STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXCOORD_INDEX),  { STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXCOORD_INDEX),  tex_coordindex      }, WINED3D_GL_EXT_NONE             },
5470     { STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXCOORD_INDEX),  { STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXCOORD_INDEX),  tex_coordindex      }, WINED3D_GL_EXT_NONE             },
5471     { STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXCOORD_INDEX),  { STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXCOORD_INDEX),  tex_coordindex      }, WINED3D_GL_EXT_NONE             },
5472     { STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXCOORD_INDEX),  { STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXCOORD_INDEX),  tex_coordindex      }, WINED3D_GL_EXT_NONE             },
5473       /* Fog */
5474     { STATE_RENDER(WINED3D_RS_FOGENABLE),                 { STATE_RENDER(WINED3D_RS_FOGENABLE),                 state_fog_vertexpart}, WINED3D_GL_EXT_NONE             },
5475     { STATE_RENDER(WINED3D_RS_FOGTABLEMODE),              { STATE_RENDER(WINED3D_RS_FOGENABLE),                 NULL                }, WINED3D_GL_EXT_NONE             },
5476     { STATE_RENDER(WINED3D_RS_FOGVERTEXMODE),             { STATE_RENDER(WINED3D_RS_FOGENABLE),                 NULL                }, WINED3D_GL_EXT_NONE             },
5477     { STATE_RENDER(WINED3D_RS_RANGEFOGENABLE),            { STATE_RENDER(WINED3D_RS_FOGENABLE),                 NULL                }, WINED3D_GL_EXT_NONE             },
5478     { STATE_RENDER(WINED3D_RS_CLIPPING),                  { STATE_RENDER(WINED3D_RS_CLIPPING),                  state_clipping      }, WINED3D_GL_EXT_NONE             },
5479     { STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE),           { STATE_RENDER(WINED3D_RS_CLIPPING),                  NULL                }, WINED3D_GL_EXT_NONE             },
5480     { STATE_RENDER(WINED3D_RS_LIGHTING),                  { STATE_RENDER(WINED3D_RS_LIGHTING),                  state_lighting      }, WINED3D_GL_EXT_NONE             },
5481     { STATE_RENDER(WINED3D_RS_AMBIENT),                   { STATE_RENDER(WINED3D_RS_AMBIENT),                   state_ambient       }, WINED3D_GL_EXT_NONE             },
5482     { STATE_RENDER(WINED3D_RS_COLORVERTEX),               { STATE_RENDER(WINED3D_RS_COLORVERTEX),               state_colormat      }, WINED3D_GL_EXT_NONE             },
5483     { STATE_RENDER(WINED3D_RS_LOCALVIEWER),               { STATE_RENDER(WINED3D_RS_LOCALVIEWER),               state_localviewer   }, WINED3D_GL_EXT_NONE             },
5484     { STATE_RENDER(WINED3D_RS_NORMALIZENORMALS),          { STATE_RENDER(WINED3D_RS_NORMALIZENORMALS),          state_normalize     }, WINED3D_GL_EXT_NONE             },
5485     { STATE_RENDER(WINED3D_RS_DIFFUSEMATERIALSOURCE),     { STATE_RENDER(WINED3D_RS_COLORVERTEX),               NULL                }, WINED3D_GL_EXT_NONE             },
5486     { STATE_RENDER(WINED3D_RS_SPECULARMATERIALSOURCE),    { STATE_RENDER(WINED3D_RS_COLORVERTEX),               NULL                }, WINED3D_GL_EXT_NONE             },
5487     { STATE_RENDER(WINED3D_RS_AMBIENTMATERIALSOURCE),     { STATE_RENDER(WINED3D_RS_COLORVERTEX),               NULL                }, WINED3D_GL_EXT_NONE             },
5488     { STATE_RENDER(WINED3D_RS_EMISSIVEMATERIALSOURCE),    { STATE_RENDER(WINED3D_RS_COLORVERTEX),               NULL                }, WINED3D_GL_EXT_NONE             },
5489     { STATE_RENDER(WINED3D_RS_VERTEXBLEND),               { STATE_RENDER(WINED3D_RS_VERTEXBLEND),               state_vertexblend   }, ARB_VERTEX_BLEND                },
5490     { STATE_RENDER(WINED3D_RS_VERTEXBLEND),               { STATE_RENDER(WINED3D_RS_VERTEXBLEND),               state_vertexblend_w }, WINED3D_GL_EXT_NONE             },
5491     { STATE_RENDER(WINED3D_RS_POINTSIZE),                 { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
5492     { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN),             { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN),             state_psizemin_arb  }, ARB_POINT_PARAMETERS            },
5493     { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN),             { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN),             state_psizemin_ext  }, EXT_POINT_PARAMETERS            },
5494     { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN),             { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN),             state_psizemin_w    }, WINED3D_GL_EXT_NONE             },
5495     { STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE),         { STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE),         state_pointsprite   }, ARB_POINT_SPRITE                },
5496     { STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE),         { STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE),         state_pointsprite_w }, WINED3D_GL_EXT_NONE             },
5497     { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE),          { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE),          state_pscale        }, WINED3D_GL_EXT_NONE             },
5498     { STATE_RENDER(WINED3D_RS_POINTSCALE_A),              { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
5499     { STATE_RENDER(WINED3D_RS_POINTSCALE_B),              { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
5500     { STATE_RENDER(WINED3D_RS_POINTSCALE_C),              { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
5501     { STATE_RENDER(WINED3D_RS_POINTSIZE_MAX),             { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN),             NULL                }, ARB_POINT_PARAMETERS            },
5502     { STATE_RENDER(WINED3D_RS_POINTSIZE_MAX),             { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN),             NULL                }, EXT_POINT_PARAMETERS            },
5503     { STATE_RENDER(WINED3D_RS_POINTSIZE_MAX),             { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN),             NULL                }, WINED3D_GL_EXT_NONE             },
5504     { STATE_RENDER(WINED3D_RS_TWEENFACTOR),               { STATE_RENDER(WINED3D_RS_VERTEXBLEND),               NULL                }, WINED3D_GL_EXT_NONE             },
5505     { STATE_RENDER(WINED3D_RS_INDEXEDVERTEXBLENDENABLE),  { STATE_RENDER(WINED3D_RS_VERTEXBLEND),               NULL                }, WINED3D_GL_EXT_NONE             },
5506
5507     /* Samplers for NP2 texture matrix adjustions. They are not needed if GL_ARB_texture_non_power_of_two is supported,
5508      * so register a NULL state handler in that case to get the vertex part of sampler() skipped(VTF is handled in the misc states.
5509      * otherwise, register sampler_texmatrix, which takes care of updating the texture matrix
5510      */
5511     { STATE_SAMPLER(0),                                   { 0,                                                  NULL                }, ARB_TEXTURE_NON_POWER_OF_TWO    },
5512     { STATE_SAMPLER(0),                                   { 0,                                                  NULL                }, WINED3D_GL_NORMALIZED_TEXRECT   },
5513     { STATE_SAMPLER(0),                                   { STATE_SAMPLER(0),                                   sampler_texmatrix   }, WINED3D_GL_EXT_NONE             },
5514     { STATE_SAMPLER(1),                                   { 0,                                                  NULL                }, ARB_TEXTURE_NON_POWER_OF_TWO    },
5515     { STATE_SAMPLER(1),                                   { 0,                                                  NULL                }, WINED3D_GL_NORMALIZED_TEXRECT   },
5516     { STATE_SAMPLER(1),                                   { STATE_SAMPLER(1),                                   sampler_texmatrix   }, WINED3D_GL_EXT_NONE             },
5517     { STATE_SAMPLER(2),                                   { 0,                                                  NULL                }, ARB_TEXTURE_NON_POWER_OF_TWO    },
5518     { STATE_SAMPLER(2),                                   { 0,                                                  NULL                }, WINED3D_GL_NORMALIZED_TEXRECT   },
5519     { STATE_SAMPLER(2),                                   { STATE_SAMPLER(2),                                   sampler_texmatrix   }, WINED3D_GL_EXT_NONE             },
5520     { STATE_SAMPLER(3),                                   { 0,                                                  NULL                }, ARB_TEXTURE_NON_POWER_OF_TWO    },
5521     { STATE_SAMPLER(3),                                   { 0,                                                  NULL                }, WINED3D_GL_NORMALIZED_TEXRECT   },
5522     { STATE_SAMPLER(3),                                   { STATE_SAMPLER(3),                                   sampler_texmatrix   }, WINED3D_GL_EXT_NONE             },
5523     { STATE_SAMPLER(4),                                   { 0,                                                  NULL                }, ARB_TEXTURE_NON_POWER_OF_TWO    },
5524     { STATE_SAMPLER(4),                                   { 0,                                                  NULL                }, WINED3D_GL_NORMALIZED_TEXRECT   },
5525     { STATE_SAMPLER(4),                                   { STATE_SAMPLER(4),                                   sampler_texmatrix   }, WINED3D_GL_EXT_NONE             },
5526     { STATE_SAMPLER(5),                                   { 0,                                                  NULL                }, ARB_TEXTURE_NON_POWER_OF_TWO    },
5527     { STATE_SAMPLER(5),                                   { 0,                                                  NULL                }, WINED3D_GL_NORMALIZED_TEXRECT   },
5528     { STATE_SAMPLER(5),                                   { STATE_SAMPLER(5),                                   sampler_texmatrix   }, WINED3D_GL_EXT_NONE             },
5529     { STATE_SAMPLER(6),                                   { 0,                                                  NULL                }, ARB_TEXTURE_NON_POWER_OF_TWO    },
5530     { STATE_SAMPLER(6),                                   { 0,                                                  NULL                }, WINED3D_GL_NORMALIZED_TEXRECT   },
5531     { STATE_SAMPLER(6),                                   { STATE_SAMPLER(6),                                   sampler_texmatrix   }, WINED3D_GL_EXT_NONE             },
5532     { STATE_SAMPLER(7),                                   { 0,                                                  NULL                }, ARB_TEXTURE_NON_POWER_OF_TWO    },
5533     { STATE_SAMPLER(7),                                   { 0,                                                  NULL                }, WINED3D_GL_NORMALIZED_TEXRECT   },
5534     { STATE_SAMPLER(7),                                   { STATE_SAMPLER(7),                                   sampler_texmatrix   }, WINED3D_GL_EXT_NONE             },
5535     {0 /* Terminate */,                                   { 0,                                                  0                   }, WINED3D_GL_EXT_NONE             },
5536 };
5537
5538 static const struct StateEntryTemplate ffp_fragmentstate_template[] = {
5539     { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP),        { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP),        tex_colorop         }, WINED3D_GL_EXT_NONE             },
5540     { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG1),      { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5541     { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG2),      { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5542     { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP),        { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP),        tex_alphaop         }, WINED3D_GL_EXT_NONE             },
5543     { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG1),      { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5544     { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG2),      { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5545     { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG0),      { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5546     { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG0),      { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5547     { STATE_TEXTURESTAGE(0, WINED3D_TSS_RESULT_ARG),      { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5548     { STATE_TEXTURESTAGE(0, WINED3D_TSS_CONSTANT),        { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL                }, WINED3D_GL_EXT_NONE             },
5549     { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP),        { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP),        tex_colorop         }, WINED3D_GL_EXT_NONE             },
5550     { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG1),      { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5551     { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG2),      { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5552     { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP),        { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP),        tex_alphaop         }, WINED3D_GL_EXT_NONE             },
5553     { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG1),      { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5554     { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG2),      { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5555     { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG0),      { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5556     { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG0),      { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5557     { STATE_TEXTURESTAGE(1, WINED3D_TSS_RESULT_ARG),      { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5558     { STATE_TEXTURESTAGE(1, WINED3D_TSS_CONSTANT),        { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL                }, WINED3D_GL_EXT_NONE             },
5559     { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP),        { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP),        tex_colorop         }, WINED3D_GL_EXT_NONE             },
5560     { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG1),      { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5561     { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG2),      { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5562     { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP),        { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP),        tex_alphaop         }, WINED3D_GL_EXT_NONE             },
5563     { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG1),      { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5564     { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG2),      { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5565     { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG0),      { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5566     { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG0),      { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5567     { STATE_TEXTURESTAGE(2, WINED3D_TSS_RESULT_ARG),      { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5568     { STATE_TEXTURESTAGE(2, WINED3D_TSS_CONSTANT),        { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL                }, WINED3D_GL_EXT_NONE             },
5569     { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP),        { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP),        tex_colorop         }, WINED3D_GL_EXT_NONE             },
5570     { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG1),      { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5571     { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG2),      { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5572     { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP),        { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP),        tex_alphaop         }, WINED3D_GL_EXT_NONE             },
5573     { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG1),      { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5574     { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG2),      { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5575     { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG0),      { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5576     { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG0),      { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5577     { STATE_TEXTURESTAGE(3, WINED3D_TSS_RESULT_ARG),      { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5578     { STATE_TEXTURESTAGE(3, WINED3D_TSS_CONSTANT),        { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL                }, WINED3D_GL_EXT_NONE             },
5579     { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP),        { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP),        tex_colorop         }, WINED3D_GL_EXT_NONE             },
5580     { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG1),      { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5581     { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG2),      { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5582     { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP),        { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP),        tex_alphaop         }, WINED3D_GL_EXT_NONE             },
5583     { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG1),      { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5584     { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG2),      { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5585     { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG0),      { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5586     { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG0),      { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5587     { STATE_TEXTURESTAGE(4, WINED3D_TSS_RESULT_ARG),      { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5588     { STATE_TEXTURESTAGE(4, WINED3D_TSS_CONSTANT),        { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL                }, WINED3D_GL_EXT_NONE             },
5589     { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP),        { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP),        tex_colorop         }, WINED3D_GL_EXT_NONE             },
5590     { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG1),      { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5591     { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG2),      { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5592     { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP),        { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP),        tex_alphaop         }, WINED3D_GL_EXT_NONE             },
5593     { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG1),      { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5594     { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG2),      { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5595     { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG0),      { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5596     { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG0),      { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5597     { STATE_TEXTURESTAGE(5, WINED3D_TSS_RESULT_ARG),      { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5598     { STATE_TEXTURESTAGE(5, WINED3D_TSS_CONSTANT),        { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL                }, WINED3D_GL_EXT_NONE             },
5599     { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP),        { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP),        tex_colorop         }, WINED3D_GL_EXT_NONE             },
5600     { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG1),      { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5601     { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG2),      { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5602     { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP),        { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP),        tex_alphaop         }, WINED3D_GL_EXT_NONE             },
5603     { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG1),      { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5604     { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG2),      { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5605     { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG0),      { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5606     { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG0),      { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5607     { STATE_TEXTURESTAGE(6, WINED3D_TSS_RESULT_ARG),      { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5608     { STATE_TEXTURESTAGE(6, WINED3D_TSS_CONSTANT),        { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL                }, WINED3D_GL_EXT_NONE             },
5609     { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP),        { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP),        tex_colorop         }, WINED3D_GL_EXT_NONE             },
5610     { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG1),      { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5611     { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG2),      { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5612     { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP),        { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP),        tex_alphaop         }, WINED3D_GL_EXT_NONE             },
5613     { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG1),      { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5614     { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG2),      { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5615     { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG0),      { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5616     { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG0),      { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5617     { STATE_TEXTURESTAGE(7, WINED3D_TSS_RESULT_ARG),      { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
5618     { STATE_TEXTURESTAGE(7, WINED3D_TSS_CONSTANT),        { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL                }, WINED3D_GL_EXT_NONE             },
5619     { STATE_PIXELSHADER,                                  { STATE_PIXELSHADER,                                  apply_pixelshader   }, WINED3D_GL_EXT_NONE             },
5620     { STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE),           { STATE_PIXELSHADER,                                  NULL                }, WINED3D_GL_EXT_NONE             },
5621     { STATE_RENDER(WINED3D_RS_TEXTUREFACTOR),             { STATE_RENDER(WINED3D_RS_TEXTUREFACTOR),             state_texfactor     }, WINED3D_GL_EXT_NONE             },
5622     { STATE_RENDER(WINED3D_RS_FOGCOLOR),                  { STATE_RENDER(WINED3D_RS_FOGCOLOR),                  state_fogcolor      }, WINED3D_GL_EXT_NONE             },
5623     { STATE_RENDER(WINED3D_RS_FOGDENSITY),                { STATE_RENDER(WINED3D_RS_FOGDENSITY),                state_fogdensity    }, WINED3D_GL_EXT_NONE             },
5624     { STATE_RENDER(WINED3D_RS_FOGENABLE),                 { STATE_RENDER(WINED3D_RS_FOGENABLE),                 state_fog_fragpart  }, WINED3D_GL_EXT_NONE             },
5625     { STATE_RENDER(WINED3D_RS_FOGTABLEMODE),              { STATE_RENDER(WINED3D_RS_FOGENABLE),                 NULL                }, WINED3D_GL_EXT_NONE             },
5626     { STATE_RENDER(WINED3D_RS_FOGVERTEXMODE),             { STATE_RENDER(WINED3D_RS_FOGENABLE),                 NULL                }, WINED3D_GL_EXT_NONE             },
5627     { STATE_RENDER(WINED3D_RS_FOGSTART),                  { STATE_RENDER(WINED3D_RS_FOGSTART),                  state_fogstartend   }, WINED3D_GL_EXT_NONE             },
5628     { STATE_RENDER(WINED3D_RS_FOGEND),                    { STATE_RENDER(WINED3D_RS_FOGSTART),                  NULL                }, WINED3D_GL_EXT_NONE             },
5629     { STATE_SAMPLER(0),                                   { STATE_SAMPLER(0),                                   sampler_texdim      }, WINED3D_GL_EXT_NONE             },
5630     { STATE_SAMPLER(1),                                   { STATE_SAMPLER(1),                                   sampler_texdim      }, WINED3D_GL_EXT_NONE             },
5631     { STATE_SAMPLER(2),                                   { STATE_SAMPLER(2),                                   sampler_texdim      }, WINED3D_GL_EXT_NONE             },
5632     { STATE_SAMPLER(3),                                   { STATE_SAMPLER(3),                                   sampler_texdim      }, WINED3D_GL_EXT_NONE             },
5633     { STATE_SAMPLER(4),                                   { STATE_SAMPLER(4),                                   sampler_texdim      }, WINED3D_GL_EXT_NONE             },
5634     { STATE_SAMPLER(5),                                   { STATE_SAMPLER(5),                                   sampler_texdim      }, WINED3D_GL_EXT_NONE             },
5635     { STATE_SAMPLER(6),                                   { STATE_SAMPLER(6),                                   sampler_texdim      }, WINED3D_GL_EXT_NONE             },
5636     { STATE_SAMPLER(7),                                   { STATE_SAMPLER(7),                                   sampler_texdim      }, WINED3D_GL_EXT_NONE             },
5637     {0 /* Terminate */,                                   { 0,                                                  0                   }, WINED3D_GL_EXT_NONE             },
5638 };
5639
5640 /* Context activation and GL locking are done by the caller. */
5641 static void ffp_enable(const struct wined3d_gl_info *gl_info, BOOL enable) {}
5642
5643 static void ffp_fragment_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps)
5644 {
5645     caps->PrimitiveMiscCaps = 0;
5646     caps->TextureOpCaps = WINED3DTEXOPCAPS_ADD
5647             | WINED3DTEXOPCAPS_ADDSIGNED
5648             | WINED3DTEXOPCAPS_ADDSIGNED2X
5649             | WINED3DTEXOPCAPS_MODULATE
5650             | WINED3DTEXOPCAPS_MODULATE2X
5651             | WINED3DTEXOPCAPS_MODULATE4X
5652             | WINED3DTEXOPCAPS_SELECTARG1
5653             | WINED3DTEXOPCAPS_SELECTARG2
5654             | WINED3DTEXOPCAPS_DISABLE;
5655
5656     if (gl_info->supported[ARB_TEXTURE_ENV_COMBINE]
5657             || gl_info->supported[EXT_TEXTURE_ENV_COMBINE]
5658             || gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
5659     {
5660         caps->TextureOpCaps |= WINED3DTEXOPCAPS_BLENDDIFFUSEALPHA
5661                 | WINED3DTEXOPCAPS_BLENDTEXTUREALPHA
5662                 | WINED3DTEXOPCAPS_BLENDFACTORALPHA
5663                 | WINED3DTEXOPCAPS_BLENDCURRENTALPHA
5664                 | WINED3DTEXOPCAPS_LERP
5665                 | WINED3DTEXOPCAPS_SUBTRACT;
5666     }
5667     if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3]
5668             || gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
5669     {
5670         caps->TextureOpCaps |= WINED3DTEXOPCAPS_ADDSMOOTH
5671                 | WINED3DTEXOPCAPS_MULTIPLYADD
5672                 | WINED3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR
5673                 | WINED3DTEXOPCAPS_MODULATECOLOR_ADDALPHA
5674                 | WINED3DTEXOPCAPS_BLENDTEXTUREALPHAPM;
5675     }
5676     if (gl_info->supported[ARB_TEXTURE_ENV_DOT3])
5677         caps->TextureOpCaps |= WINED3DTEXOPCAPS_DOTPRODUCT3;
5678
5679     caps->MaxTextureBlendStages = gl_info->limits.textures;
5680     caps->MaxSimultaneousTextures = gl_info->limits.textures;
5681 }
5682
5683 static void *ffp_fragment_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv)
5684 {
5685     return shader_priv;
5686 }
5687
5688 static void ffp_fragment_free(struct wined3d_device *device) {}
5689 static BOOL ffp_color_fixup_supported(struct color_fixup_desc fixup)
5690 {
5691     if (TRACE_ON(d3d))
5692     {
5693         TRACE("Checking support for fixup:\n");
5694         dump_color_fixup_desc(fixup);
5695     }
5696
5697     /* We only support identity conversions. */
5698     if (is_identity_fixup(fixup))
5699     {
5700         TRACE("[OK]\n");
5701         return TRUE;
5702     }
5703
5704     TRACE("[FAILED]\n");
5705     return FALSE;
5706 }
5707
5708 const struct fragment_pipeline ffp_fragment_pipeline = {
5709     ffp_enable,
5710     ffp_fragment_get_caps,
5711     ffp_fragment_alloc,
5712     ffp_fragment_free,
5713     ffp_color_fixup_supported,
5714     ffp_fragmentstate_template,
5715     FALSE /* we cannot disable projected textures. The vertex pipe has to do it */
5716 };
5717
5718 static unsigned int num_handlers(const APPLYSTATEFUNC *funcs)
5719 {
5720     unsigned int i;
5721     for(i = 0; funcs[i]; i++);
5722     return i;
5723 }
5724
5725 static void multistate_apply_2(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
5726 {
5727     context->swapchain->device->multistate_funcs[state_id][0](context, state, state_id);
5728     context->swapchain->device->multistate_funcs[state_id][1](context, state, state_id);
5729 }
5730
5731 static void multistate_apply_3(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
5732 {
5733     context->swapchain->device->multistate_funcs[state_id][0](context, state, state_id);
5734     context->swapchain->device->multistate_funcs[state_id][1](context, state, state_id);
5735     context->swapchain->device->multistate_funcs[state_id][2](context, state, state_id);
5736 }
5737
5738 static void prune_invalid_states(struct StateEntry *state_table, const struct wined3d_gl_info *gl_info)
5739 {
5740     unsigned int start, last, i;
5741
5742     start = STATE_TEXTURESTAGE(gl_info->limits.texture_stages, 0);
5743     last = STATE_TEXTURESTAGE(MAX_TEXTURES - 1, WINED3D_HIGHEST_TEXTURE_STATE);
5744     for (i = start; i <= last; ++i)
5745     {
5746         state_table[i].representative = 0;
5747         state_table[i].apply = state_undefined;
5748     }
5749
5750     start = STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + gl_info->limits.texture_stages);
5751     last = STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + MAX_TEXTURES - 1);
5752     for (i = start; i <= last; ++i)
5753     {
5754         state_table[i].representative = 0;
5755         state_table[i].apply = state_undefined;
5756     }
5757
5758     start = STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(gl_info->limits.blends));
5759     last = STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255));
5760     for (i = start; i <= last; ++i)
5761     {
5762         state_table[i].representative = 0;
5763         state_table[i].apply = state_undefined;
5764     }
5765 }
5766
5767 static void validate_state_table(struct StateEntry *state_table)
5768 {
5769     static const struct
5770     {
5771         DWORD first;
5772         DWORD last;
5773     }
5774     rs_holes[] =
5775     {
5776         {  1,   1},
5777         {  3,   3},
5778         { 17,  18},
5779         { 21,  21},
5780         { 42,  45},
5781         { 47,  47},
5782         { 61, 127},
5783         {149, 150},
5784         {169, 169},
5785         {177, 177},
5786         {196, 197},
5787         {  0,   0},
5788     };
5789     static const DWORD simple_states[] =
5790     {
5791         STATE_MATERIAL,
5792         STATE_VDECL,
5793         STATE_STREAMSRC,
5794         STATE_INDEXBUFFER,
5795         STATE_VERTEXSHADERCONSTANT,
5796         STATE_PIXELSHADERCONSTANT,
5797         STATE_VSHADER,
5798         STATE_GEOMETRY_SHADER,
5799         STATE_PIXELSHADER,
5800         STATE_VIEWPORT,
5801         STATE_SCISSORRECT,
5802         STATE_FRONTFACE,
5803         STATE_POINTSPRITECOORDORIGIN,
5804         STATE_BASEVERTEXINDEX,
5805         STATE_FRAMEBUFFER
5806     };
5807     unsigned int i, current;
5808
5809     for (i = STATE_RENDER(1), current = 0; i <= STATE_RENDER(WINEHIGHEST_RENDER_STATE); ++i)
5810     {
5811         if (!rs_holes[current].first || i < STATE_RENDER(rs_holes[current].first))
5812         {
5813             if (!state_table[i].representative)
5814                 ERR("State %s (%#x) should have a representative.\n", debug_d3dstate(i), i);
5815         }
5816         else if (state_table[i].representative)
5817             ERR("State %s (%#x) shouldn't have a representative.\n", debug_d3dstate(i), i);
5818
5819         if (i == STATE_RENDER(rs_holes[current].last)) ++current;
5820     }
5821
5822     for (i = 0; i < sizeof(simple_states) / sizeof(*simple_states); ++i)
5823     {
5824         if (!state_table[simple_states[i]].representative)
5825             ERR("State %s (%#x) should have a representative.\n",
5826                     debug_d3dstate(simple_states[i]), simple_states[i]);
5827     }
5828
5829     for (i = 0; i < STATE_HIGHEST + 1; ++i)
5830     {
5831         DWORD rep = state_table[i].representative;
5832         if (rep)
5833         {
5834             if (state_table[rep].representative != rep)
5835             {
5836                 ERR("State %s (%#x) has invalid representative %s (%#x).\n",
5837                         debug_d3dstate(i), i, debug_d3dstate(rep), rep);
5838                 state_table[i].representative = 0;
5839             }
5840
5841             if (rep != i)
5842             {
5843                 if (state_table[i].apply)
5844                     ERR("State %s (%#x) has both a handler and representative.\n", debug_d3dstate(i), i);
5845             }
5846             else if (!state_table[i].apply)
5847             {
5848                 ERR("Self representing state %s (%#x) has no handler.\n", debug_d3dstate(i), i);
5849             }
5850         }
5851     }
5852 }
5853
5854 HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_multistate_funcs,
5855         const struct wined3d_gl_info *gl_info, const struct StateEntryTemplate *vertex,
5856         const struct fragment_pipeline *fragment, const struct StateEntryTemplate *misc)
5857 {
5858     unsigned int i, type, handlers;
5859     APPLYSTATEFUNC multistate_funcs[STATE_HIGHEST + 1][3];
5860     const struct StateEntryTemplate *cur;
5861     BOOL set[STATE_HIGHEST + 1];
5862
5863     memset(multistate_funcs, 0, sizeof(multistate_funcs));
5864
5865     for(i = 0; i < STATE_HIGHEST + 1; i++) {
5866         StateTable[i].representative = 0;
5867         StateTable[i].apply = state_undefined;
5868     }
5869
5870     for(type = 0; type < 3; type++) {
5871         /* This switch decides the order in which the states are applied */
5872         switch(type) {
5873             case 0: cur = misc; break;
5874             case 1: cur = fragment->states; break;
5875             case 2: cur = vertex; break;
5876             default: cur = NULL; /* Stupid compiler */
5877         }
5878         if(!cur) continue;
5879
5880         /* GL extension filtering should not prevent multiple handlers being applied from different
5881          * pipeline parts
5882          */
5883         memset(set, 0, sizeof(set));
5884
5885         for(i = 0; cur[i].state; i++) {
5886             APPLYSTATEFUNC *funcs_array;
5887
5888             /* Only use the first matching state with the available extension from one template.
5889              * e.g.
5890              * {D3DRS_FOOBAR, {D3DRS_FOOBAR, func1}, XYZ_FANCY},
5891              * {D3DRS_FOOBAR, {D3DRS_FOOBAR, func2}, 0        }
5892              *
5893              * if GL_XYZ_fancy is supported, ignore the 2nd line
5894              */
5895             if(set[cur[i].state]) continue;
5896             /* Skip state lines depending on unsupported extensions */
5897             if (!gl_info->supported[cur[i].extension]) continue;
5898             set[cur[i].state] = TRUE;
5899             /* In some cases having an extension means that nothing has to be
5900              * done for a state, e.g. if GL_ARB_texture_non_power_of_two is
5901              * supported, the texture coordinate fixup can be ignored. If the
5902              * apply function is used, mark the state set(done above) to prevent
5903              * applying later lines, but do not record anything in the state
5904              * table
5905              */
5906             if (!cur[i].content.representative) continue;
5907
5908             handlers = num_handlers(multistate_funcs[cur[i].state]);
5909             multistate_funcs[cur[i].state][handlers] = cur[i].content.apply;
5910             switch(handlers) {
5911                 case 0:
5912                     StateTable[cur[i].state].apply = cur[i].content.apply;
5913                     break;
5914                 case 1:
5915                     StateTable[cur[i].state].apply = multistate_apply_2;
5916                     dev_multistate_funcs[cur[i].state] = HeapAlloc(GetProcessHeap(),
5917                                                                    0,
5918                                                                    sizeof(**dev_multistate_funcs) * 2);
5919                     if (!dev_multistate_funcs[cur[i].state]) {
5920                         goto out_of_mem;
5921                     }
5922
5923                     dev_multistate_funcs[cur[i].state][0] = multistate_funcs[cur[i].state][0];
5924                     dev_multistate_funcs[cur[i].state][1] = multistate_funcs[cur[i].state][1];
5925                     break;
5926                 case 2:
5927                     StateTable[cur[i].state].apply = multistate_apply_3;
5928                     funcs_array = HeapReAlloc(GetProcessHeap(),
5929                                               0,
5930                                               dev_multistate_funcs[cur[i].state],
5931                                               sizeof(**dev_multistate_funcs) * 3);
5932                     if (!funcs_array) {
5933                         goto out_of_mem;
5934                     }
5935
5936                     dev_multistate_funcs[cur[i].state] = funcs_array;
5937                     dev_multistate_funcs[cur[i].state][2] = multistate_funcs[cur[i].state][2];
5938                     break;
5939                 default:
5940                     ERR("Unexpected amount of state handlers for state %u: %u\n",
5941                         cur[i].state, handlers + 1);
5942             }
5943
5944             if(StateTable[cur[i].state].representative &&
5945             StateTable[cur[i].state].representative != cur[i].content.representative) {
5946                 FIXME("State %u has different representatives in different pipeline parts\n",
5947                     cur[i].state);
5948             }
5949             StateTable[cur[i].state].representative = cur[i].content.representative;
5950         }
5951     }
5952
5953     prune_invalid_states(StateTable, gl_info);
5954     validate_state_table(StateTable);
5955
5956     return WINED3D_OK;
5957
5958 out_of_mem:
5959     for (i = 0; i <= STATE_HIGHEST; ++i) {
5960         HeapFree(GetProcessHeap(), 0, dev_multistate_funcs[i]);
5961     }
5962
5963     memset(dev_multistate_funcs, 0, (STATE_HIGHEST + 1)*sizeof(*dev_multistate_funcs));
5964
5965     return E_OUTOFMEMORY;
5966 }