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