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