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