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