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