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