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