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