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