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