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