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