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