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