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