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