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