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