wined3d: Store the texture in a local variable in sampler_texmatrix().
[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 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(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
455     float col[4];
456
457     if(!GL_SUPPORT(EXT_BLEND_COLOR)) {
458         WARN("Unsupported in local OpenGL implementation: glBlendColorEXT\n");
459         return;
460     }
461
462     TRACE("Setting BlendFactor to %d\n", stateblock->renderState[WINED3DRS_BLENDFACTOR]);
463     D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_BLENDFACTOR], col);
464     GL_EXTCALL(glBlendColorEXT (col[0],col[1],col[2],col[3]));
465     checkGLcall("glBlendColor");
466 }
467
468 static void state_alpha(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
469     int glParm = 0;
470     float ref;
471     BOOL enable_ckey = FALSE;
472
473     IWineD3DSurfaceImpl *surf;
474
475     /* Find out if the texture on the first stage has a ckey set
476      * The alpha state func reads the texture settings, even though alpha and texture are not grouped
477      * together. This is to avoid making a huge alpha+texture+texture stage+ckey block due to the hardly
478      * used WINED3DRS_COLORKEYENABLE state(which is d3d <= 3 only). The texture function will call alpha
479      * in case it finds some texture+colorkeyenable combination which needs extra care.
480      */
481     if(stateblock->textures[0] && (
482        stateblock->textureDimensions[0] == GL_TEXTURE_2D ||
483        stateblock->textureDimensions[0] == GL_TEXTURE_RECTANGLE_ARB)) {
484         surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *)stateblock->textures[0])->surfaces[0];
485
486         if(surf->CKeyFlags & WINEDDSD_CKSRCBLT) {
487             const StaticPixelFormatDesc *fmt = getFormatDescEntry(surf->resource.format, NULL, NULL);
488             /* The surface conversion does not do color keying conversion for surfaces that have an alpha
489              * channel on their own. Likewise, the alpha test shouldn't be set up for color keying if the
490              * surface has alpha bits
491              */
492             if(fmt->alphaMask == 0x00000000) {
493                 enable_ckey = TRUE;
494             }
495         }
496     }
497
498     if(enable_ckey || context->last_was_ckey) {
499         const struct StateEntry *StateTable = stateblock->wineD3DDevice->StateTable;
500         StateTable[STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP)].apply(STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), stateblock, context);
501     }
502     context->last_was_ckey = enable_ckey;
503
504     if (stateblock->renderState[WINED3DRS_ALPHATESTENABLE] ||
505         (stateblock->renderState[WINED3DRS_COLORKEYENABLE] && enable_ckey)) {
506         glEnable(GL_ALPHA_TEST);
507         checkGLcall("glEnable GL_ALPHA_TEST");
508     } else {
509         glDisable(GL_ALPHA_TEST);
510         checkGLcall("glDisable GL_ALPHA_TEST");
511         /* Alpha test is disabled, don't bother setting the params - it will happen on the next
512          * enable call
513          */
514         return;
515     }
516
517     if(stateblock->renderState[WINED3DRS_COLORKEYENABLE] && enable_ckey) {
518         glParm = GL_NOTEQUAL;
519         ref = 0.0;
520     } else {
521         ref = ((float) stateblock->renderState[WINED3DRS_ALPHAREF]) / 255.0f;
522         glParm = CompareFunc(stateblock->renderState[WINED3DRS_ALPHAFUNC]);
523     }
524     if(glParm) {
525         glAlphaFunc(glParm, ref);
526         checkGLcall("glAlphaFunc");
527     }
528 }
529
530 static void state_clipping(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
531     DWORD enable  = 0xFFFFFFFF;
532     DWORD disable = 0x00000000;
533
534     if (use_vs(stateblock->wineD3DDevice)) {
535         /* The spec says that opengl clipping planes are disabled when using shaders. Direct3D planes aren't,
536          * so that is an issue. The MacOS ATI driver keeps clipping planes activated with shaders in some
537          * conditions I got sick of tracking down. The shader state handler disables all clip planes because
538          * of that - don't do anything here and keep them disabled
539          */
540         if(stateblock->renderState[WINED3DRS_CLIPPLANEENABLE]) {
541             static BOOL warned = FALSE;
542             if(!warned) {
543                 FIXME("Clipping not supported with vertex shaders\n");
544                 warned = TRUE;
545             }
546         }
547         return;
548     }
549
550     /* TODO: Keep track of previously enabled clipplanes to avoid unnecessary resetting
551      * of already set values
552      */
553
554     /* If enabling / disabling all
555      * TODO: Is this correct? Doesn't D3DRS_CLIPPING disable clipping on the viewport frustrum?
556      */
557     if (stateblock->renderState[WINED3DRS_CLIPPING]) {
558         enable  = stateblock->renderState[WINED3DRS_CLIPPLANEENABLE];
559         disable = ~stateblock->renderState[WINED3DRS_CLIPPLANEENABLE];
560         if(GL_SUPPORT(NV_DEPTH_CLAMP)) {
561             glDisable(GL_DEPTH_CLAMP_NV);
562             checkGLcall("glDisable(GL_DEPTH_CLAMP_NV)");
563         }
564     } else {
565         disable = 0xffffffff;
566         enable  = 0x00;
567         if(GL_SUPPORT(NV_DEPTH_CLAMP)) {
568             glEnable(GL_DEPTH_CLAMP_NV);
569             checkGLcall("glEnable(GL_DEPTH_CLAMP_NV)");
570         }
571     }
572
573     if (enable & WINED3DCLIPPLANE0)  { glEnable(GL_CLIP_PLANE0);  checkGLcall("glEnable(clip plane 0)"); }
574     if (enable & WINED3DCLIPPLANE1)  { glEnable(GL_CLIP_PLANE1);  checkGLcall("glEnable(clip plane 1)"); }
575     if (enable & WINED3DCLIPPLANE2)  { glEnable(GL_CLIP_PLANE2);  checkGLcall("glEnable(clip plane 2)"); }
576     if (enable & WINED3DCLIPPLANE3)  { glEnable(GL_CLIP_PLANE3);  checkGLcall("glEnable(clip plane 3)"); }
577     if (enable & WINED3DCLIPPLANE4)  { glEnable(GL_CLIP_PLANE4);  checkGLcall("glEnable(clip plane 4)"); }
578     if (enable & WINED3DCLIPPLANE5)  { glEnable(GL_CLIP_PLANE5);  checkGLcall("glEnable(clip plane 5)"); }
579
580     if (disable & WINED3DCLIPPLANE0) { glDisable(GL_CLIP_PLANE0); checkGLcall("glDisable(clip plane 0)"); }
581     if (disable & WINED3DCLIPPLANE1) { glDisable(GL_CLIP_PLANE1); checkGLcall("glDisable(clip plane 1)"); }
582     if (disable & WINED3DCLIPPLANE2) { glDisable(GL_CLIP_PLANE2); checkGLcall("glDisable(clip plane 2)"); }
583     if (disable & WINED3DCLIPPLANE3) { glDisable(GL_CLIP_PLANE3); checkGLcall("glDisable(clip plane 3)"); }
584     if (disable & WINED3DCLIPPLANE4) { glDisable(GL_CLIP_PLANE4); checkGLcall("glDisable(clip plane 4)"); }
585     if (disable & WINED3DCLIPPLANE5) { glDisable(GL_CLIP_PLANE5); checkGLcall("glDisable(clip plane 5)"); }
586
587     /** update clipping status */
588     if (enable) {
589         stateblock->clip_status.ClipUnion = 0;
590         stateblock->clip_status.ClipIntersection = 0xFFFFFFFF;
591     } else {
592         stateblock->clip_status.ClipUnion = 0;
593         stateblock->clip_status.ClipIntersection = 0;
594     }
595 }
596
597 static void state_blendop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
598     int blendEquation = GL_FUNC_ADD;
599     int blendEquationAlpha = GL_FUNC_ADD;
600
601     if(!GL_SUPPORT(EXT_BLEND_MINMAX)) {
602         WARN("Unsupported in local OpenGL implementation: glBlendEquation\n");
603         return;
604     }
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         float black[4] = {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_stencilwrite(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     if(GL_SUPPORT(EXT_STENCIL_TWO_SIDE)) {
881         GL_EXTCALL(glActiveStencilFaceEXT(GL_BACK));
882         checkGLcall("glActiveStencilFaceEXT(GL_BACK)");
883         glStencilMask(mask);
884         checkGLcall("glStencilMask");
885         GL_EXTCALL(glActiveStencilFaceEXT(GL_FRONT));
886         checkGLcall("glActiveStencilFaceEXT(GL_FRONT)");
887         glStencilMask(mask);
888     } else {
889         glStencilMask(mask);
890     }
891     checkGLcall("glStencilMask");
892 }
893
894 static void state_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
895     BOOL fogenable = stateblock->renderState[WINED3DRS_FOGENABLE];
896     BOOL is_ps3 = use_ps(stateblock->wineD3DDevice)
897                   && ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.hex_version >= WINED3DPS_VERSION(3,0);
898     float fogstart, fogend;
899
900     union {
901         DWORD d;
902         float f;
903     } tmpvalue;
904
905     if (!fogenable) {
906         /* No fog? Disable it, and we're done :-) */
907         glDisable(GL_FOG);
908         checkGLcall("glDisable GL_FOG");
909         if( use_ps(stateblock->wineD3DDevice)
910                 && ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.hex_version < WINED3DPS_VERSION(3,0) ) {
911             /* disable fog in the pixel shader
912              * NOTE: For pixel shader, GL_FOG_START and GL_FOG_END don't hold fog start s and end e but
913              * -1/(e-s) and e/(e-s) respectively.
914              */
915             glFogf(GL_FOG_START, 0.0f);
916             checkGLcall("glFogf(GL_FOG_START, fogstart)");
917             glFogf(GL_FOG_END, 1.0f);
918             checkGLcall("glFogf(GL_FOG_END, fogend)");
919         }
920         return;
921     }
922
923     tmpvalue.d = stateblock->renderState[WINED3DRS_FOGSTART];
924     fogstart = tmpvalue.f;
925     tmpvalue.d = stateblock->renderState[WINED3DRS_FOGEND];
926     fogend = tmpvalue.f;
927
928     /* Fog Rules:
929      *
930      * With fixed function vertex processing, Direct3D knows 2 different fog input sources.
931      * It can use the Z value of the vertex, or the alpha component of the specular color.
932      * This depends on the fog vertex, fog table and the vertex declaration. If the Z value
933      * is used, fogstart, fogend and the equation type are used, otherwise linear fog with
934      * start = 255, end = 0 is used. Obviously the msdn is not very clear on that.
935      *
936      * FOGTABLEMODE != NONE:
937      *  The Z value is used, with the equation specified, no matter what vertex type.
938      *
939      * FOGTABLEMODE == NONE, FOGVERTEXMODE != NONE, untransformed:
940      *  Per vertex fog is calculated using the specified fog equation and the parameters
941      *
942      * FOGTABLEMODE == NONE, FOGVERTEXMODE != NONE, transformed, OR
943      * FOGTABLEMODE == NONE, FOGVERTEXMODE == NONE, untransformed:
944      *  Linear fog with start = 255.0, end = 0.0, input comes from the specular color
945      *
946      *
947      * Rules for vertex fog with shaders:
948      *
949      * When mixing fixed function functionality with the programmable pipeline, D3D expects
950      * the fog computation to happen during transformation while openGL expects it to happen
951      * during rasterization. Also, prior to pixel shader 3.0 D3D handles fog blending after
952      * the pixel shader while openGL always expects the pixel shader to handle the blending.
953      * To solve this problem, WineD3D does:
954      * 1) implement a linear fog equation and fog blending at the end of every pre 3.0 pixel
955      * shader,
956      * and 2) disables the fog computation (in either the fixed function or programmable
957      * rasterizer) if using a vertex program.
958      *
959      *
960      * If a fogtablemode and a fogvertexmode are specified, table fog is applied (with or
961      * without shaders).
962      */
963
964     if( is_ps3 ) {
965         if( !use_vs(stateblock->wineD3DDevice)
966                 && stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE ) {
967             FIXME("Implement vertex fog for pixel shader >= 3.0 and fixed function pipeline\n");
968         }
969     }
970
971     if (use_vs(stateblock->wineD3DDevice)
972             && ((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.reg_maps.fog) {
973         if( stateblock->renderState[WINED3DRS_FOGTABLEMODE] != WINED3DFOG_NONE ) {
974             if(!is_ps3) FIXME("Implement table fog for foggy vertex shader\n");
975             /* Disable fog */
976             fogenable = FALSE;
977         } else {
978             /* Set fog computation in the rasterizer to pass through the value (just blend it) */
979             glFogi(GL_FOG_MODE, GL_LINEAR);
980             checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
981             fogstart = 1.0;
982             fogend = 0.0;
983         }
984
985         if(GL_SUPPORT(EXT_FOG_COORD) && context->fog_coord) {
986             glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
987             checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT)");
988             context->fog_coord = FALSE;
989         }
990         context->last_was_foggy_shader = TRUE;
991     }
992     else if( use_ps(stateblock->wineD3DDevice) ) {
993         /* NOTE: For pixel shader, GL_FOG_START and GL_FOG_END don't hold fog start s and end e but
994          * -1/(e-s) and e/(e-s) respectively to simplify fog computation in the shader.
995          */
996         WINED3DFOGMODE mode;
997         context->last_was_foggy_shader = FALSE;
998
999         /* If both fogmodes are set use the table fog mode */
1000         if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE)
1001             mode = stateblock->renderState[WINED3DRS_FOGVERTEXMODE];
1002         else
1003             mode = stateblock->renderState[WINED3DRS_FOGTABLEMODE];
1004
1005         switch (mode) {
1006             case WINED3DFOG_EXP:
1007             case WINED3DFOG_EXP2:
1008                 if(!is_ps3) FIXME("Implement non linear fog for pixel shader < 3.0\n");
1009                 /* Disable fog */
1010                 fogenable = FALSE;
1011                 break;
1012
1013             case WINED3DFOG_LINEAR:
1014                 fogstart = -1.0f/(fogend-fogstart);
1015                 fogend *= -fogstart;
1016                 break;
1017
1018             case WINED3DFOG_NONE:
1019                 if(!is_ps3) FIXME("Implement software vertex fog for pixel shader < 3.0\n");
1020                 /* Disable fog */
1021                 fogenable = FALSE;
1022                 break;
1023             default: FIXME("Unexpected WINED3DRS_FOGVERTEXMODE %d\n", stateblock->renderState[WINED3DRS_FOGVERTEXMODE]);
1024         }
1025
1026         if(GL_SUPPORT(EXT_FOG_COORD) && context->fog_coord) {
1027             glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
1028             checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT)");
1029             context->fog_coord = FALSE;
1030         }
1031     }
1032     /* DX 7 sdk: "If both render states(vertex and table fog) are set to valid modes,
1033      * the system will apply only pixel(=table) fog effects."
1034      */
1035     else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
1036         glHint(GL_FOG_HINT, GL_FASTEST);
1037         checkGLcall("glHint(GL_FOG_HINT, GL_FASTEST)");
1038         context->last_was_foggy_shader = FALSE;
1039
1040         switch (stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
1041             /* If processed vertices are used, fall through to the NONE case */
1042             case WINED3DFOG_EXP:  {
1043                 if(!context->last_was_rhw) {
1044                     glFogi(GL_FOG_MODE, GL_EXP);
1045                     checkGLcall("glFogi(GL_FOG_MODE, GL_EXP)");
1046                     if(GL_SUPPORT(EXT_FOG_COORD) && context->fog_coord) {
1047                         glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
1048                         checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT)");
1049                         context->fog_coord = FALSE;
1050                     }
1051                     break;
1052                 }
1053             }
1054             case WINED3DFOG_EXP2: {
1055                 if(!context->last_was_rhw) {
1056                     glFogi(GL_FOG_MODE, GL_EXP2);
1057                     checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2)");
1058                     if(GL_SUPPORT(EXT_FOG_COORD) && context->fog_coord) {
1059                         glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
1060                         checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT)");
1061                         context->fog_coord = FALSE;
1062                     }
1063                     break;
1064                 }
1065             }
1066             case WINED3DFOG_LINEAR: {
1067                 if(!context->last_was_rhw) {
1068                     glFogi(GL_FOG_MODE, GL_LINEAR);
1069                     checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1070                     if(GL_SUPPORT(EXT_FOG_COORD) && context->fog_coord) {
1071                         glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
1072                         checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT)");
1073                         context->fog_coord = FALSE;
1074                     }
1075                     break;
1076                 }
1077             }
1078             case WINED3DFOG_NONE: {
1079                 /* Both are none? According to msdn the alpha channel of the specular
1080                  * color contains a fog factor. Set it in drawStridedSlow.
1081                  * Same happens with Vertexfog on transformed vertices
1082                  */
1083                 if(GL_SUPPORT(EXT_FOG_COORD)) {
1084                     if(context->fog_coord == FALSE) {
1085                         glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);
1086                         checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT)");
1087                         context->fog_coord = TRUE;
1088                     }
1089                     glFogi(GL_FOG_MODE, GL_LINEAR);
1090                     checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1091                     fogstart = 0xff;
1092                     fogend = 0x0;
1093                 } else {
1094                     /* Disable GL fog, handle this in software in drawStridedSlow */
1095                     fogenable = FALSE;
1096                 }
1097                 break;
1098             }
1099             default: FIXME("Unexpected WINED3DRS_FOGVERTEXMODE %d\n", stateblock->renderState[WINED3DRS_FOGVERTEXMODE]);
1100         }
1101     } else {
1102         glHint(GL_FOG_HINT, GL_NICEST);
1103         checkGLcall("glHint(GL_FOG_HINT, GL_NICEST)");
1104         context->last_was_foggy_shader = FALSE;
1105
1106         switch (stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
1107             case WINED3DFOG_EXP:
1108                 glFogi(GL_FOG_MODE, GL_EXP);
1109                 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP)");
1110                 if(GL_SUPPORT(EXT_FOG_COORD) && context->fog_coord) {
1111                     glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
1112                     checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT)");
1113                     context->fog_coord = FALSE;
1114                 }
1115                 break;
1116
1117             case WINED3DFOG_EXP2:
1118                 glFogi(GL_FOG_MODE, GL_EXP2);
1119                 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2)");
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_LINEAR:
1128                 glFogi(GL_FOG_MODE, GL_LINEAR);
1129                 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
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_NONE:   /* Won't happen */
1138             default:
1139                 FIXME("Unexpected WINED3DRS_FOGTABLEMODE %d\n", stateblock->renderState[WINED3DRS_FOGTABLEMODE]);
1140         }
1141     }
1142
1143     if(fogenable) {
1144         glEnable(GL_FOG);
1145         checkGLcall("glEnable GL_FOG");
1146
1147         if(fogstart != fogend)
1148         {
1149             glFogfv(GL_FOG_START, &fogstart);
1150             checkGLcall("glFogf(GL_FOG_START, fogstart)");
1151             TRACE("Fog Start == %f\n", fogstart);
1152
1153             glFogfv(GL_FOG_END, &fogend);
1154             checkGLcall("glFogf(GL_FOG_END, fogend)");
1155             TRACE("Fog End == %f\n", fogend);
1156         }
1157         else
1158         {
1159             glFogf(GL_FOG_START, -1.0 / 0.0);
1160             checkGLcall("glFogf(GL_FOG_START, fogstart)");
1161             TRACE("Fog Start == %f\n", fogstart);
1162
1163             glFogf(GL_FOG_END, 0.0);
1164             checkGLcall("glFogf(GL_FOG_END, fogend)");
1165             TRACE("Fog End == %f\n", fogend);
1166         }
1167     } else {
1168         glDisable(GL_FOG);
1169         checkGLcall("glDisable GL_FOG");
1170         if( use_ps(stateblock->wineD3DDevice) ) {
1171             /* disable fog in the pixel shader
1172              * NOTE: For pixel shader, GL_FOG_START and GL_FOG_END don't hold fog start s and end e but
1173              * -1/(e-s) and e/(e-s) respectively.
1174              */
1175             glFogf(GL_FOG_START, 0.0f);
1176             checkGLcall("glFogf(GL_FOG_START, fogstart)");
1177             glFogf(GL_FOG_END, 1.0f);
1178             checkGLcall("glFogf(GL_FOG_END, fogend)");
1179         }
1180     }
1181 }
1182
1183 static void state_rangefog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1184     if(stateblock->renderState[WINED3DRS_RANGEFOGENABLE]) {
1185         if (GL_SUPPORT(NV_FOG_DISTANCE)) {
1186             glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_RADIAL_NV);
1187             checkGLcall("glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_RADIAL_NV)");
1188         } else {
1189             WARN("Range fog enabled, but not supported by this opengl implementation\n");
1190         }
1191     } else {
1192         if (GL_SUPPORT(NV_FOG_DISTANCE)) {
1193             glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV);
1194             checkGLcall("glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV)");
1195         }
1196     }
1197 }
1198
1199 static void state_fogcolor(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1200     float col[4];
1201     D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_FOGCOLOR], col);
1202     glFogfv(GL_FOG_COLOR, &col[0]);
1203     checkGLcall("glFog GL_FOG_COLOR");
1204 }
1205
1206 static void state_fogdensity(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1207     union {
1208         DWORD d;
1209         float f;
1210     } tmpvalue;
1211     tmpvalue.d = stateblock->renderState[WINED3DRS_FOGDENSITY];
1212     glFogfv(GL_FOG_DENSITY, &tmpvalue.f);
1213     checkGLcall("glFogf(GL_FOG_DENSITY, (float) Value)");
1214 }
1215
1216 /* TODO: Merge with primitive type + init_materials()!! */
1217 static void state_colormat(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1218     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
1219     GLenum Parm = 0;
1220     WineDirect3DStridedData *diffuse = &device->strided_streams.u.s.diffuse;
1221     BOOL isDiffuseSupplied;
1222
1223     /* Depends on the decoded vertex declaration to read the existence of diffuse data.
1224      * The vertex declaration will call this function if the fixed function pipeline is used.
1225      */
1226
1227     if(isStateDirty(context, STATE_VDECL)) {
1228         return;
1229     }
1230
1231     isDiffuseSupplied = diffuse->lpData || diffuse->VBO;
1232
1233     context->num_untracked_materials = 0;
1234     if (isDiffuseSupplied && stateblock->renderState[WINED3DRS_COLORVERTEX]) {
1235         TRACE("diff %d, amb %d, emis %d, spec %d\n",
1236               stateblock->renderState[WINED3DRS_DIFFUSEMATERIALSOURCE],
1237               stateblock->renderState[WINED3DRS_AMBIENTMATERIALSOURCE],
1238               stateblock->renderState[WINED3DRS_EMISSIVEMATERIALSOURCE],
1239               stateblock->renderState[WINED3DRS_SPECULARMATERIALSOURCE]);
1240
1241         if (stateblock->renderState[WINED3DRS_DIFFUSEMATERIALSOURCE] == WINED3DMCS_COLOR1) {
1242             if (stateblock->renderState[WINED3DRS_AMBIENTMATERIALSOURCE] == WINED3DMCS_COLOR1) {
1243                 Parm = GL_AMBIENT_AND_DIFFUSE;
1244             } else {
1245                 Parm = GL_DIFFUSE;
1246             }
1247             if(stateblock->renderState[WINED3DRS_EMISSIVEMATERIALSOURCE] == WINED3DMCS_COLOR1) {
1248                 context->untracked_materials[context->num_untracked_materials] = GL_EMISSION;
1249                 context->num_untracked_materials++;
1250             }
1251             if(stateblock->renderState[WINED3DRS_SPECULARMATERIALSOURCE] == WINED3DMCS_COLOR1) {
1252                 context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
1253                 context->num_untracked_materials++;
1254             }
1255         } else if (stateblock->renderState[WINED3DRS_AMBIENTMATERIALSOURCE] == WINED3DMCS_COLOR1) {
1256             Parm = GL_AMBIENT;
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_EMISSIVEMATERIALSOURCE] == WINED3DMCS_COLOR1) {
1266             Parm = GL_EMISSION;
1267             if(stateblock->renderState[WINED3DRS_SPECULARMATERIALSOURCE] == WINED3DMCS_COLOR1) {
1268                 context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
1269                 context->num_untracked_materials++;
1270             }
1271         } else if (stateblock->renderState[WINED3DRS_SPECULARMATERIALSOURCE] == WINED3DMCS_COLOR1) {
1272             Parm = GL_SPECULAR;
1273         }
1274     }
1275
1276     /* Nothing changed, return. */
1277     if (Parm == context->tracking_parm) return;
1278
1279     if(!Parm) {
1280         glDisable(GL_COLOR_MATERIAL);
1281         checkGLcall("glDisable GL_COLOR_MATERIAL");
1282     } else {
1283         glColorMaterial(GL_FRONT_AND_BACK, Parm);
1284         checkGLcall("glColorMaterial(GL_FRONT_AND_BACK, Parm)");
1285         glEnable(GL_COLOR_MATERIAL);
1286         checkGLcall("glEnable(GL_COLOR_MATERIAL)");
1287     }
1288
1289     /* Apparently calls to glMaterialfv are ignored for properties we're
1290      * tracking with glColorMaterial, so apply those here. */
1291     switch (context->tracking_parm) {
1292         case GL_AMBIENT_AND_DIFFUSE:
1293             glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float*)&device->updateStateBlock->material.Ambient);
1294             glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float*)&device->updateStateBlock->material.Diffuse);
1295             checkGLcall("glMaterialfv");
1296             break;
1297
1298         case GL_DIFFUSE:
1299             glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float*)&device->updateStateBlock->material.Diffuse);
1300             checkGLcall("glMaterialfv");
1301             break;
1302
1303         case GL_AMBIENT:
1304             glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float*)&device->updateStateBlock->material.Ambient);
1305             checkGLcall("glMaterialfv");
1306             break;
1307
1308         case GL_EMISSION:
1309             glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float*)&device->updateStateBlock->material.Emissive);
1310             checkGLcall("glMaterialfv");
1311             break;
1312
1313         case GL_SPECULAR:
1314             /* Only change material color if specular is enabled, otherwise it is set to black */
1315             if (device->stateBlock->renderState[WINED3DRS_SPECULARENABLE]) {
1316                 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float*)&device->updateStateBlock->material.Specular);
1317                 checkGLcall("glMaterialfv");
1318             } else {
1319                 float black[4] = {0.0f, 0.0f, 0.0f, 0.0f};
1320                 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
1321                 checkGLcall("glMaterialfv");
1322             }
1323             break;
1324     }
1325
1326     context->tracking_parm = Parm;
1327 }
1328
1329 static void state_linepattern(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1330     union {
1331         DWORD                 d;
1332         WINED3DLINEPATTERN    lp;
1333     } tmppattern;
1334     tmppattern.d = stateblock->renderState[WINED3DRS_LINEPATTERN];
1335
1336     TRACE("Line pattern: repeat %d bits %x\n", tmppattern.lp.wRepeatFactor, tmppattern.lp.wLinePattern);
1337
1338     if (tmppattern.lp.wRepeatFactor) {
1339         glLineStipple(tmppattern.lp.wRepeatFactor, tmppattern.lp.wLinePattern);
1340         checkGLcall("glLineStipple(repeat, linepattern)");
1341         glEnable(GL_LINE_STIPPLE);
1342         checkGLcall("glEnable(GL_LINE_STIPPLE);");
1343     } else {
1344         glDisable(GL_LINE_STIPPLE);
1345         checkGLcall("glDisable(GL_LINE_STIPPLE);");
1346     }
1347 }
1348
1349 static void state_zbias(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1350     union {
1351         DWORD d;
1352         float f;
1353     } tmpvalue;
1354
1355     if (stateblock->renderState[WINED3DRS_ZBIAS]) {
1356         tmpvalue.d = stateblock->renderState[WINED3DRS_ZBIAS];
1357         TRACE("ZBias value %f\n", tmpvalue.f);
1358         glPolygonOffset(0, -tmpvalue.f);
1359         checkGLcall("glPolygonOffset(0, -Value)");
1360         glEnable(GL_POLYGON_OFFSET_FILL);
1361         checkGLcall("glEnable(GL_POLYGON_OFFSET_FILL);");
1362         glEnable(GL_POLYGON_OFFSET_LINE);
1363         checkGLcall("glEnable(GL_POLYGON_OFFSET_LINE);");
1364         glEnable(GL_POLYGON_OFFSET_POINT);
1365         checkGLcall("glEnable(GL_POLYGON_OFFSET_POINT);");
1366     } else {
1367         glDisable(GL_POLYGON_OFFSET_FILL);
1368         checkGLcall("glDisable(GL_POLYGON_OFFSET_FILL);");
1369         glDisable(GL_POLYGON_OFFSET_LINE);
1370         checkGLcall("glDisable(GL_POLYGON_OFFSET_LINE);");
1371         glDisable(GL_POLYGON_OFFSET_POINT);
1372         checkGLcall("glDisable(GL_POLYGON_OFFSET_POINT);");
1373     }
1374 }
1375
1376
1377 static void state_normalize(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1378     if(isStateDirty(context, STATE_VDECL)) {
1379         return;
1380     }
1381     /* Without vertex normals, we set the current normal to 0/0/0 to remove the diffuse factor
1382      * from the opengl lighting equation, as d3d does. Normalization of 0/0/0 can lead to a division
1383      * by zero and is not properly defined in opengl, so avoid it
1384      */
1385     if (stateblock->renderState[WINED3DRS_NORMALIZENORMALS] && (
1386         stateblock->wineD3DDevice->strided_streams.u.s.normal.lpData ||
1387         stateblock->wineD3DDevice->strided_streams.u.s.normal.VBO)) {
1388         glEnable(GL_NORMALIZE);
1389         checkGLcall("glEnable(GL_NORMALIZE);");
1390     } else {
1391         glDisable(GL_NORMALIZE);
1392         checkGLcall("glDisable(GL_NORMALIZE);");
1393     }
1394 }
1395
1396 static void state_psizemin(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1397     union {
1398         DWORD d;
1399         float f;
1400     } tmpvalue;
1401
1402     tmpvalue.d = stateblock->renderState[WINED3DRS_POINTSIZE_MIN];
1403     if(GL_SUPPORT(ARB_POINT_PARAMETERS)) {
1404         GL_EXTCALL(glPointParameterfARB)(GL_POINT_SIZE_MIN_ARB, tmpvalue.f);
1405         checkGLcall("glPointParameterfARB(...)");
1406     }
1407     else if(GL_SUPPORT(EXT_POINT_PARAMETERS)) {
1408         GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MIN_EXT, tmpvalue.f);
1409         checkGLcall("glPointParameterfEXT(...)");
1410     } else if(tmpvalue.f != 1.0) {
1411         FIXME("WINED3DRS_POINTSIZE_MIN not supported on this opengl, value is %f\n", tmpvalue.f);
1412     }
1413 }
1414
1415 static void state_psizemax(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1416     union {
1417         DWORD d;
1418         float f;
1419     } tmpvalue;
1420
1421     tmpvalue.d = stateblock->renderState[WINED3DRS_POINTSIZE_MAX];
1422     if(GL_SUPPORT(ARB_POINT_PARAMETERS)) {
1423         GL_EXTCALL(glPointParameterfARB)(GL_POINT_SIZE_MAX_ARB, tmpvalue.f);
1424         checkGLcall("glPointParameterfARB(...)");
1425     }
1426     else if(GL_SUPPORT(EXT_POINT_PARAMETERS)) {
1427         GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MAX_EXT, tmpvalue.f);
1428         checkGLcall("glPointParameterfEXT(...)");
1429     } else if(tmpvalue.f != 64.0) {
1430         FIXME("WINED3DRS_POINTSIZE_MAX not supported on this opengl, value is %f\n", tmpvalue.f);
1431     }
1432 }
1433
1434 static void state_pscale(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1435     /* TODO: Group this with the viewport */
1436     /*
1437      * POINTSCALEENABLE controls how point size value is treated. If set to
1438      * true, the point size is scaled with respect to height of viewport.
1439      * When set to false point size is in pixels.
1440      */
1441
1442     /* Default values */
1443     GLfloat att[3] = {1.0f, 0.0f, 0.0f};
1444     union {
1445         DWORD d;
1446         float f;
1447     } pointSize, A, B, C;
1448
1449     pointSize.d = stateblock->renderState[WINED3DRS_POINTSIZE];
1450     A.d = stateblock->renderState[WINED3DRS_POINTSCALE_A];
1451     B.d = stateblock->renderState[WINED3DRS_POINTSCALE_B];
1452     C.d = stateblock->renderState[WINED3DRS_POINTSCALE_C];
1453
1454     if(stateblock->renderState[WINED3DRS_POINTSCALEENABLE]) {
1455         GLfloat scaleFactor;
1456         float h = stateblock->viewport.Height;
1457
1458         if(pointSize.f < GL_LIMITS(pointsizemin)) {
1459             /*
1460              * Minimum valid point size for OpenGL is driver specific. For Direct3D it is
1461              * 0.0f. This means that OpenGL will clamp really small point sizes to the
1462              * driver minimum. To correct for this we need to multiply by the scale factor when sizes
1463              * are less than 1.0f. scale_factor =  1.0f / point_size.
1464              */
1465             scaleFactor = pointSize.f / GL_LIMITS(pointsizemin);
1466             /* Clamp the point size, don't rely on the driver to do it. MacOS says min point size
1467              * is 1.0, but then accepts points below that and draws too small points
1468              */
1469             pointSize.f = GL_LIMITS(pointsizemin);
1470         } else if(pointSize.f > GL_LIMITS(pointsize)) {
1471             /* gl already scales the input to glPointSize,
1472              * d3d scales the result after the point size scale.
1473              * If the point size is bigger than the max size, use the
1474              * scaling to scale it bigger, and set the gl point size to max
1475              */
1476             scaleFactor = pointSize.f / GL_LIMITS(pointsize);
1477             TRACE("scale: %f\n", scaleFactor);
1478             pointSize.f = GL_LIMITS(pointsize);
1479         } else {
1480             scaleFactor = 1.0f;
1481         }
1482         scaleFactor = pow(h * scaleFactor, 2);
1483
1484         att[0] = A.f / scaleFactor;
1485         att[1] = B.f / scaleFactor;
1486         att[2] = C.f / scaleFactor;
1487     }
1488
1489     if(GL_SUPPORT(ARB_POINT_PARAMETERS)) {
1490         GL_EXTCALL(glPointParameterfvARB)(GL_POINT_DISTANCE_ATTENUATION_ARB, att);
1491         checkGLcall("glPointParameterfvARB(GL_DISTANCE_ATTENUATION_ARB, ...)");
1492     }
1493     else if(GL_SUPPORT(EXT_POINT_PARAMETERS)) {
1494         GL_EXTCALL(glPointParameterfvEXT)(GL_DISTANCE_ATTENUATION_EXT, att);
1495         checkGLcall("glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, ...)");
1496     } else if(stateblock->renderState[WINED3DRS_POINTSCALEENABLE]) {
1497         WARN("POINT_PARAMETERS not supported in this version of opengl\n");
1498     }
1499
1500     glPointSize(pointSize.f);
1501     checkGLcall("glPointSize(...);");
1502 }
1503
1504 static void state_colorwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1505     DWORD Value = stateblock->renderState[WINED3DRS_COLORWRITEENABLE];
1506
1507     TRACE("Color mask: r(%d) g(%d) b(%d) a(%d)\n",
1508         Value & WINED3DCOLORWRITEENABLE_RED   ? 1 : 0,
1509         Value & WINED3DCOLORWRITEENABLE_GREEN ? 1 : 0,
1510         Value & WINED3DCOLORWRITEENABLE_BLUE  ? 1 : 0,
1511         Value & WINED3DCOLORWRITEENABLE_ALPHA ? 1 : 0);
1512     glColorMask(Value & WINED3DCOLORWRITEENABLE_RED   ? GL_TRUE : GL_FALSE,
1513                 Value & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE,
1514                 Value & WINED3DCOLORWRITEENABLE_BLUE  ? GL_TRUE : GL_FALSE,
1515                 Value & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE);
1516     checkGLcall("glColorMask(...)");
1517
1518     /* depends on WINED3DRS_COLORWRITEENABLE. */
1519     if(stateblock->renderState[WINED3DRS_COLORWRITEENABLE1] != 0x0000000F ||
1520        stateblock->renderState[WINED3DRS_COLORWRITEENABLE2] != 0x0000000F ||
1521        stateblock->renderState[WINED3DRS_COLORWRITEENABLE3] != 0x0000000F ) {
1522         ERR("(WINED3DRS_COLORWRITEENABLE1/2/3,%d,%d,%d) not yet implemented. Missing of cap D3DPMISCCAPS_INDEPENDENTWRITEMASKS wasn't honored?\n",
1523             stateblock->renderState[WINED3DRS_COLORWRITEENABLE1],
1524             stateblock->renderState[WINED3DRS_COLORWRITEENABLE2],
1525             stateblock->renderState[WINED3DRS_COLORWRITEENABLE3]);
1526     }
1527 }
1528
1529 static void state_localviewer(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1530     if(stateblock->renderState[WINED3DRS_LOCALVIEWER]) {
1531         glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
1532         checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1)");
1533     } else {
1534         glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0);
1535         checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0)");
1536     }
1537 }
1538
1539 static void state_lastpixel(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1540     if(stateblock->renderState[WINED3DRS_LASTPIXEL]) {
1541         TRACE("Last Pixel Drawing Enabled\n");
1542     } else {
1543         static BOOL first = TRUE;
1544         if(first) {
1545             FIXME("Last Pixel Drawing Disabled, not handled yet\n");
1546             first = FALSE;
1547         } else {
1548             TRACE("Last Pixel Drawing Disabled, not handled yet\n");
1549         }
1550     }
1551 }
1552
1553 static void state_pointsprite(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1554     /* TODO: NV_POINT_SPRITE */
1555     if (!GL_SUPPORT(ARB_POINT_SPRITE)) {
1556         TRACE("Point sprites not supported\n");
1557         return;
1558     }
1559
1560     if (stateblock->renderState[WINED3DRS_POINTSPRITEENABLE]) {
1561         glEnable(GL_POINT_SPRITE_ARB);
1562         checkGLcall("glEnable(GL_POINT_SPRITE_ARB)");
1563     } else {
1564         glDisable(GL_POINT_SPRITE_ARB);
1565         checkGLcall("glDisable(GL_POINT_SPRITE_ARB)");
1566     }
1567 }
1568
1569 static void state_wrap(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1570     /**
1571      http://www.cosc.brocku.ca/Offerings/3P98/course/lectures/texture/
1572      http://www.gamedev.net/reference/programming/features/rendererdll3/page2.asp
1573      Discussion on the ways to turn on WRAPing to solve an OpenGL conversion problem.
1574      http://www.flipcode.org/cgi-bin/fcmsg.cgi?thread_show=10248
1575
1576      so far as I can tell, wrapping and texture-coordinate generate go hand in hand,
1577      */
1578     TRACE("Stub\n");
1579     if(stateblock->renderState[WINED3DRS_WRAP0] ||
1580        stateblock->renderState[WINED3DRS_WRAP1] ||
1581        stateblock->renderState[WINED3DRS_WRAP2] ||
1582        stateblock->renderState[WINED3DRS_WRAP3] ||
1583        stateblock->renderState[WINED3DRS_WRAP4] ||
1584        stateblock->renderState[WINED3DRS_WRAP5] ||
1585        stateblock->renderState[WINED3DRS_WRAP6] ||
1586        stateblock->renderState[WINED3DRS_WRAP7] ||
1587        stateblock->renderState[WINED3DRS_WRAP8] ||
1588        stateblock->renderState[WINED3DRS_WRAP9] ||
1589        stateblock->renderState[WINED3DRS_WRAP10] ||
1590        stateblock->renderState[WINED3DRS_WRAP11] ||
1591        stateblock->renderState[WINED3DRS_WRAP12] ||
1592        stateblock->renderState[WINED3DRS_WRAP13] ||
1593        stateblock->renderState[WINED3DRS_WRAP14] ||
1594        stateblock->renderState[WINED3DRS_WRAP15] ) {
1595         FIXME("(WINED3DRS_WRAP0) Texture wraping not yet supported\n");
1596     }
1597 }
1598
1599 static void state_multisampleaa(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1600     if( GL_SUPPORT(ARB_MULTISAMPLE) ) {
1601         if(stateblock->renderState[WINED3DRS_MULTISAMPLEANTIALIAS]) {
1602             glEnable(GL_MULTISAMPLE_ARB);
1603             checkGLcall("glEnable(GL_MULTISAMPLE_ARB)");
1604         } else {
1605             glDisable(GL_MULTISAMPLE_ARB);
1606             checkGLcall("glDisable(GL_MULTISAMPLE_ARB)");
1607         }
1608     } else {
1609         if(stateblock->renderState[WINED3DRS_MULTISAMPLEANTIALIAS]) {
1610             WARN("Multisample antialiasing not supported by gl\n");
1611         }
1612     }
1613 }
1614
1615 static void state_scissor(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1616     if(stateblock->renderState[WINED3DRS_SCISSORTESTENABLE]) {
1617         glEnable(GL_SCISSOR_TEST);
1618         checkGLcall("glEnable(GL_SCISSOR_TEST)");
1619     } else {
1620         glDisable(GL_SCISSOR_TEST);
1621         checkGLcall("glDisable(GL_SCISSOR_TEST)");
1622     }
1623 }
1624
1625 static void state_depthbias(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1626     union {
1627         DWORD d;
1628         float f;
1629     } tmpvalue;
1630
1631     if(stateblock->renderState[WINED3DRS_SLOPESCALEDEPTHBIAS] ||
1632        stateblock->renderState[WINED3DRS_DEPTHBIAS]) {
1633         tmpvalue.d = stateblock->renderState[WINED3DRS_SLOPESCALEDEPTHBIAS];
1634         glEnable(GL_POLYGON_OFFSET_FILL);
1635         checkGLcall("glEnable(GL_POLYGON_OFFSET_FILL)");
1636         glPolygonOffset(tmpvalue.f, *((float*)&stateblock->renderState[WINED3DRS_DEPTHBIAS]));
1637         checkGLcall("glPolygonOffset(...)");
1638     } else {
1639         glDisable(GL_POLYGON_OFFSET_FILL);
1640         checkGLcall("glDisable(GL_POLYGON_OFFSET_FILL)");
1641     }
1642 }
1643
1644 static void state_perspective(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1645     if (stateblock->renderState[WINED3DRS_TEXTUREPERSPECTIVE]) {
1646         glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1647         checkGLcall("glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)");
1648     } else {
1649         glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
1650         checkGLcall("glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST)");
1651     }
1652 }
1653
1654 static void state_stippledalpha(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1655     TRACE("Stub\n");
1656     if (stateblock->renderState[WINED3DRS_STIPPLEDALPHA])
1657         FIXME(" Stippled Alpha not supported yet.\n");
1658 }
1659
1660 static void state_antialias(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1661     TRACE("Stub\n");
1662     if (stateblock->renderState[WINED3DRS_ANTIALIAS])
1663         FIXME(" Antialias not supported yet.\n");
1664 }
1665
1666 static void state_multisampmask(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1667     TRACE("Stub\n");
1668     if (stateblock->renderState[WINED3DRS_MULTISAMPLEMASK] != 0xFFFFFFFF)
1669         FIXME("(WINED3DRS_MULTISAMPLEMASK,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_MULTISAMPLEMASK]);
1670 }
1671
1672 static void state_patchedgestyle(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1673     TRACE("Stub\n");
1674     if (stateblock->renderState[WINED3DRS_PATCHEDGESTYLE] != WINED3DPATCHEDGE_DISCRETE)
1675         FIXME("(WINED3DRS_PATCHEDGESTYLE,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_PATCHEDGESTYLE]);
1676 }
1677
1678 static void state_patchsegments(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1679     union {
1680         DWORD d;
1681         float f;
1682     } tmpvalue;
1683     tmpvalue.f = 1.0f;
1684
1685     TRACE("Stub\n");
1686     if (stateblock->renderState[WINED3DRS_PATCHSEGMENTS] != tmpvalue.d)
1687     {
1688         static BOOL displayed = FALSE;
1689
1690         tmpvalue.d = stateblock->renderState[WINED3DRS_PATCHSEGMENTS];
1691         if(!displayed)
1692             FIXME("(WINED3DRS_PATCHSEGMENTS,%f) not yet implemented\n", tmpvalue.f);
1693
1694         displayed = TRUE;
1695     }
1696 }
1697
1698 static void state_positiondegree(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1699     TRACE("Stub\n");
1700     if (stateblock->renderState[WINED3DRS_POSITIONDEGREE] != WINED3DDEGREE_CUBIC)
1701         FIXME("(WINED3DRS_POSITIONDEGREE,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_POSITIONDEGREE]);
1702 }
1703
1704 static void state_normaldegree(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1705     TRACE("Stub\n");
1706     if (stateblock->renderState[WINED3DRS_NORMALDEGREE] != WINED3DDEGREE_LINEAR)
1707         FIXME("(WINED3DRS_NORMALDEGREE,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_NORMALDEGREE]);
1708 }
1709
1710 static void state_tessellation(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1711     TRACE("Stub\n");
1712     if(stateblock->renderState[WINED3DRS_ENABLEADAPTIVETESSELLATION])
1713         FIXME("(WINED3DRS_ENABLEADAPTIVETESSELLATION,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_ENABLEADAPTIVETESSELLATION]);
1714 }
1715
1716 static void state_wrapu(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1717     if(stateblock->renderState[WINED3DRS_WRAPU]) {
1718         FIXME("Render state WINED3DRS_WRAPU not implemented yet\n");
1719     }
1720 }
1721
1722 static void state_wrapv(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1723     if(stateblock->renderState[WINED3DRS_WRAPV]) {
1724         FIXME("Render state WINED3DRS_WRAPV not implemented yet\n");
1725     }
1726 }
1727
1728 static void state_monoenable(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1729     if(stateblock->renderState[WINED3DRS_MONOENABLE]) {
1730         FIXME("Render state WINED3DRS_MONOENABLE not implemented yet\n");
1731     }
1732 }
1733
1734 static void state_rop2(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1735     if(stateblock->renderState[WINED3DRS_ROP2]) {
1736         FIXME("Render state WINED3DRS_ROP2 not implemented yet\n");
1737     }
1738 }
1739
1740 static void state_planemask(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1741     if(stateblock->renderState[WINED3DRS_PLANEMASK]) {
1742         FIXME("Render state WINED3DRS_PLANEMASK not implemented yet\n");
1743     }
1744 }
1745
1746 static void state_subpixel(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1747     if(stateblock->renderState[WINED3DRS_SUBPIXEL]) {
1748         FIXME("Render state WINED3DRS_SUBPIXEL not implemented yet\n");
1749     }
1750 }
1751
1752 static void state_subpixelx(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1753     if(stateblock->renderState[WINED3DRS_SUBPIXELX]) {
1754         FIXME("Render state WINED3DRS_SUBPIXELX not implemented yet\n");
1755     }
1756 }
1757
1758 static void state_stippleenable(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1759     if(stateblock->renderState[WINED3DRS_STIPPLEENABLE]) {
1760         FIXME("Render state WINED3DRS_STIPPLEENABLE not implemented yet\n");
1761     }
1762 }
1763
1764 static void state_bordercolor(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1765     if(stateblock->renderState[WINED3DRS_BORDERCOLOR]) {
1766         FIXME("Render state WINED3DRS_BORDERCOLOR not implemented yet\n");
1767     }
1768 }
1769
1770 static void state_mipmaplodbias(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1771     if(stateblock->renderState[WINED3DRS_MIPMAPLODBIAS]) {
1772         FIXME("Render state WINED3DRS_MIPMAPLODBIAS not implemented yet\n");
1773     }
1774 }
1775
1776 static void state_anisotropy(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1777     if(stateblock->renderState[WINED3DRS_ANISOTROPY]) {
1778         FIXME("Render state WINED3DRS_ANISOTROPY not implemented yet\n");
1779     }
1780 }
1781
1782 static void state_flushbatch(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1783     if(stateblock->renderState[WINED3DRS_FLUSHBATCH]) {
1784         FIXME("Render state WINED3DRS_FLUSHBATCH not implemented yet\n");
1785     }
1786 }
1787
1788 static void state_translucentsi(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1789     if(stateblock->renderState[WINED3DRS_TRANSLUCENTSORTINDEPENDENT]) {
1790         FIXME("Render state WINED3DRS_TRANSLUCENTSORTINDEPENDENT not implemented yet\n");
1791     }
1792 }
1793
1794 static void state_extents(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1795     if(stateblock->renderState[WINED3DRS_EXTENTS]) {
1796         FIXME("Render state WINED3DRS_EXTENTS not implemented yet\n");
1797     }
1798 }
1799
1800 static void state_ckeyblend(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1801     if(stateblock->renderState[WINED3DRS_COLORKEYBLENDENABLE]) {
1802         FIXME("Render state WINED3DRS_COLORKEYBLENDENABLE not implemented yet\n");
1803     }
1804 }
1805
1806 static void tex_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1807     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
1808     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage];
1809     BOOL tex_used = stateblock->wineD3DDevice->fixed_function_usage_map[stage];
1810
1811     TRACE("Setting color op for stage %d\n", stage);
1812
1813     if (stateblock->pixelShader && stateblock->wineD3DDevice->ps_selected_mode != SHADER_NONE &&
1814         ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.function) {
1815         /* Using a pixel shader? Don't care for anything here, the shader applying does it */
1816         return;
1817     }
1818
1819     if (stage != mapped_stage) WARN("Using non 1:1 mapping: %d -> %d!\n", stage, mapped_stage);
1820
1821     if (mapped_stage != -1) {
1822         if (GL_SUPPORT(ARB_MULTITEXTURE)) {
1823             if (tex_used && mapped_stage >= GL_LIMITS(textures)) {
1824                 FIXME("Attempt to enable unsupported stage!\n");
1825                 return;
1826             }
1827             GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
1828             checkGLcall("glActiveTextureARB");
1829         } else if (stage > 0) {
1830             WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
1831             return;
1832         }
1833     }
1834
1835     if(stage >= stateblock->lowest_disabled_stage) {
1836         TRACE("Stage disabled\n");
1837         if (mapped_stage != -1) {
1838             /* Disable everything here */
1839             glDisable(GL_TEXTURE_2D);
1840             checkGLcall("glDisable(GL_TEXTURE_2D)");
1841             glDisable(GL_TEXTURE_3D);
1842             checkGLcall("glDisable(GL_TEXTURE_3D)");
1843             if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
1844                 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
1845                 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
1846             }
1847             if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
1848                 glDisable(GL_TEXTURE_RECTANGLE_ARB);
1849                 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
1850             }
1851         }
1852         /* All done */
1853         return;
1854     }
1855
1856     /* The sampler will also activate the correct texture dimensions, so no need to do it here
1857      * if the sampler for this stage is dirty
1858      */
1859     if(!isStateDirty(context, STATE_SAMPLER(stage))) {
1860         if (tex_used) texture_activate_dimensions(stage, stateblock, context);
1861     }
1862
1863     set_tex_op((IWineD3DDevice *)stateblock->wineD3DDevice, FALSE, stage,
1864                 stateblock->textureState[stage][WINED3DTSS_COLOROP],
1865                 stateblock->textureState[stage][WINED3DTSS_COLORARG1],
1866                 stateblock->textureState[stage][WINED3DTSS_COLORARG2],
1867                 stateblock->textureState[stage][WINED3DTSS_COLORARG0]);
1868 }
1869
1870 void tex_alphaop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1871     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
1872     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage];
1873     BOOL tex_used = stateblock->wineD3DDevice->fixed_function_usage_map[stage];
1874     DWORD op, arg1, arg2, arg0;
1875
1876     TRACE("Setting alpha op for stage %d\n", stage);
1877     /* Do not care for enabled / disabled stages, just assign the settings. colorop disables / enables required stuff */
1878     if (mapped_stage != -1) {
1879         if (GL_SUPPORT(ARB_MULTITEXTURE)) {
1880             if (tex_used && mapped_stage >= GL_LIMITS(textures)) {
1881                 FIXME("Attempt to enable unsupported stage!\n");
1882                 return;
1883             }
1884             GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
1885             checkGLcall("glActiveTextureARB");
1886         } else if (stage > 0) {
1887             /* We can't do anything here */
1888             WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
1889             return;
1890         }
1891     }
1892
1893     op = stateblock->textureState[stage][WINED3DTSS_ALPHAOP];
1894     arg1 = stateblock->textureState[stage][WINED3DTSS_ALPHAARG1];
1895     arg2 = stateblock->textureState[stage][WINED3DTSS_ALPHAARG2];
1896     arg0 = stateblock->textureState[stage][WINED3DTSS_ALPHAARG0];
1897
1898     if(stateblock->renderState[WINED3DRS_COLORKEYENABLE] && stage == 0 &&
1899        stateblock->textures[0] &&
1900        (stateblock->textureDimensions[0] == GL_TEXTURE_2D || stateblock->textureDimensions[0] == GL_TEXTURE_RECTANGLE_ARB)) {
1901         IWineD3DSurfaceImpl *surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *) stateblock->textures[0])->surfaces[0];
1902
1903         if(surf->CKeyFlags & WINEDDSD_CKSRCBLT &&
1904            getFormatDescEntry(surf->resource.format, NULL, NULL)->alphaMask == 0x00000000) {
1905
1906             /* Color keying needs to pass alpha values from the texture through to have the alpha test work properly.
1907              * On the other hand applications can still use texture combiners apparently. This code takes care that apps
1908              * cannot remove the texture's alpha channel entirely.
1909              *
1910              * The fixup is required for Prince of Persia 3D(prison bars), while Moto racer 2 requires D3DTOP_MODULATE to work
1911              * on color keyed surfaces. Aliens vs Predator 1 uses color keyed textures and alpha component of diffuse color to
1912              * draw things like translucent text and perform other blending effects.
1913              *
1914              * Aliens vs Predator 1 relies on diffuse alpha having an effect, so it cannot be ignored. To provide the
1915              * behavior expected by the game, while emulating the colorkey, diffuse alpha must be modulated with texture alpha.
1916              * OTOH, Moto racer 2 at some points sets alphaop/alphaarg to SELECTARG/CURRENT, yet puts garbage in diffuse alpha
1917              * (zeroes). This works on native, because the game disables alpha test and alpha blending. Alpha test is overwritten by
1918              * wine's for purposes of color-keying though, so this will lead to missing geometry if texture alpha is modulated
1919              * (pixels fail alpha test). To get around this, ALPHABLENDENABLE state is checked: if the app enables alpha blending,
1920              * it can be expected to provide meaningful values in diffuse alpha, so it should be modulated with texture alpha;
1921              * otherwise, selecting diffuse alpha is ignored in favour of texture alpha.
1922
1923              * What to do with multitexturing? So far no app has been found that uses color keying with multitexturing
1924              */
1925             if(op == WINED3DTOP_DISABLE) {
1926                 arg1 = WINED3DTA_TEXTURE;
1927                 op = WINED3DTOP_SELECTARG1;
1928             }
1929             else if(op == WINED3DTOP_SELECTARG1 && arg1 != WINED3DTA_TEXTURE) {
1930                 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE]) {
1931                     arg2 = WINED3DTA_TEXTURE;
1932                     op = WINED3DTOP_MODULATE;
1933                 }
1934                 else arg1 = WINED3DTA_TEXTURE;
1935             }
1936             else if(op == WINED3DTOP_SELECTARG2 && arg2 != WINED3DTA_TEXTURE) {
1937                 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE]) {
1938                     arg1 = WINED3DTA_TEXTURE;
1939                     op = WINED3DTOP_MODULATE;
1940                 }
1941                 else arg2 = WINED3DTA_TEXTURE;
1942             }
1943         }
1944     }
1945
1946     /* tex_alphaop is shared between the ffp and nvrc because the difference only comes down to
1947      * this if block here, and the other code(color keying, texture unit selection) are the same
1948      */
1949     TRACE("Setting alpha op for stage %d\n", stage);
1950     if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
1951         set_tex_op_nvrc((IWineD3DDevice *)stateblock->wineD3DDevice, TRUE, stage,
1952                          op, arg1, arg2, arg0,
1953                          mapped_stage,
1954                          stateblock->textureState[stage][WINED3DTSS_RESULTARG]);
1955     } else {
1956         set_tex_op((IWineD3DDevice *)stateblock->wineD3DDevice, TRUE, stage,
1957                     op, arg1, arg2, arg0);
1958     }
1959 }
1960
1961 static void transform_texture(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1962     DWORD texUnit = state - STATE_TRANSFORM(WINED3DTS_TEXTURE0);
1963     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[texUnit];
1964     BOOL generated;
1965
1966     /* Ignore this when a vertex shader is used, or if the streams aren't sorted out yet */
1967     if(use_vs(stateblock->wineD3DDevice) ||
1968        isStateDirty(context, STATE_VDECL)) {
1969         TRACE("Using a vertex shader, or stream sources not sorted out yet, skipping\n");
1970         return;
1971     }
1972
1973     if (mapped_stage == -1) return;
1974
1975     if (GL_SUPPORT(ARB_MULTITEXTURE)) {
1976         if(mapped_stage >= GL_LIMITS(textures)) {
1977             return;
1978         }
1979         GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
1980         checkGLcall("glActiveTextureARB");
1981     } else if (mapped_stage > 0) {
1982         /* We can't do anything here */
1983         WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
1984         return;
1985     }
1986     generated = (stateblock->textureState[texUnit][WINED3DTSS_TEXCOORDINDEX] & 0xFFFF0000) != WINED3DTSS_TCI_PASSTHRU;
1987
1988     set_texture_matrix(&stateblock->transforms[WINED3DTS_TEXTURE0 + texUnit].u.m[0][0],
1989                         stateblock->textureState[texUnit][WINED3DTSS_TEXTURETRANSFORMFLAGS],
1990                         generated,
1991                         context->last_was_rhw,
1992                         stateblock->wineD3DDevice->strided_streams.u.s.texCoords[texUnit].dwStride ?
1993                             stateblock->wineD3DDevice->strided_streams.u.s.texCoords[texUnit].dwType:
1994                             WINED3DDECLTYPE_UNUSED);
1995
1996     /* The sampler applying function calls us if this changes */
1997     if(context->lastWasPow2Texture[texUnit] && stateblock->textures[texUnit]) {
1998         if(generated) {
1999             FIXME("Non-power2 texture being used with generated texture coords\n");
2000         }
2001         TRACE("Non power two matrix multiply fixup\n");
2002         glMultMatrixf(((IWineD3DTextureImpl *) stateblock->textures[texUnit])->baseTexture.pow2Matrix);
2003     }
2004 }
2005
2006 static void unloadTexCoords(IWineD3DStateBlockImpl *stateblock) {
2007     int texture_idx;
2008
2009     for (texture_idx = 0; texture_idx < GL_LIMITS(texture_stages); ++texture_idx) {
2010         GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + texture_idx));
2011         glDisableClientState(GL_TEXTURE_COORD_ARRAY);
2012     }
2013 }
2014
2015 static void loadTexCoords(IWineD3DStateBlockImpl *stateblock, WineDirect3DVertexStridedData *sd, GLint *curVBO) {
2016     UINT *offset = stateblock->streamOffset;
2017     unsigned int mapped_stage = 0;
2018     unsigned int textureNo = 0;
2019
2020     /* The code below uses glClientActiveTexture and glMultiTexCoord* which are all part of the GL_ARB_multitexture extension. */
2021     /* Abort if we don't support the extension. */
2022     if (!GL_SUPPORT(ARB_MULTITEXTURE)) {
2023         FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
2024         return;
2025     }
2026
2027     for (textureNo = 0; textureNo < GL_LIMITS(texture_stages); ++textureNo) {
2028         int coordIdx = stateblock->textureState[textureNo][WINED3DTSS_TEXCOORDINDEX];
2029
2030         mapped_stage = stateblock->wineD3DDevice->texUnitMap[textureNo];
2031         if (mapped_stage == -1) continue;
2032
2033         if (coordIdx < MAX_TEXTURES && (sd->u.s.texCoords[coordIdx].lpData || sd->u.s.texCoords[coordIdx].VBO)) {
2034             TRACE("Setting up texture %u, idx %d, cordindx %u, data %p\n",
2035                     textureNo, mapped_stage, coordIdx, sd->u.s.texCoords[coordIdx].lpData);
2036
2037             if (*curVBO != sd->u.s.texCoords[coordIdx].VBO) {
2038                 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.texCoords[coordIdx].VBO));
2039                 checkGLcall("glBindBufferARB");
2040                 *curVBO = sd->u.s.texCoords[coordIdx].VBO;
2041             }
2042
2043             GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
2044             checkGLcall("glClientActiveTextureARB");
2045
2046             /* The coords to supply depend completely on the fvf / vertex shader */
2047             glTexCoordPointer(
2048                     WINED3D_ATR_SIZE(sd->u.s.texCoords[coordIdx].dwType),
2049                     WINED3D_ATR_GLTYPE(sd->u.s.texCoords[coordIdx].dwType),
2050                     sd->u.s.texCoords[coordIdx].dwStride,
2051                     sd->u.s.texCoords[coordIdx].lpData + stateblock->loadBaseVertexIndex * sd->u.s.texCoords[coordIdx].dwStride + offset[sd->u.s.texCoords[coordIdx].streamNo]);
2052             glEnableClientState(GL_TEXTURE_COORD_ARRAY);
2053         } else {
2054             GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + mapped_stage, 0, 0, 0, 1));
2055         }
2056     }
2057     if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
2058         /* The number of the mapped stages increases monotonically, so it's fine to use the last used one */
2059         for (textureNo = mapped_stage + 1; textureNo < GL_LIMITS(textures); ++textureNo) {
2060             GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, 0, 0, 0, 1));
2061         }
2062     }
2063 }
2064
2065 static void tex_coordindex(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2066     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
2067     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage];
2068
2069     if (mapped_stage == -1) {
2070         TRACE("No texture unit mapped to stage %d. Skipping texture coordinates.\n", stage);
2071         return;
2072     }
2073
2074     if (GL_SUPPORT(ARB_MULTITEXTURE)) {
2075         if(mapped_stage >= GL_LIMITS(fragment_samplers)) {
2076             return;
2077         }
2078         GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
2079         checkGLcall("glActiveTextureARB");
2080     } else if (stage > 0) {
2081         /* We can't do anything here */
2082         WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
2083         return;
2084     }
2085
2086     /* Values 0-7 are indexes into the FVF tex coords - See comments in DrawPrimitive
2087      *
2088      * FIXME: From MSDN: The WINED3DTSS_TCI_* flags are mutually exclusive. If you include
2089      * one flag, you can still specify an index value, which the system uses to
2090      * determine the texture wrapping mode.
2091      * eg. SetTextureStageState( 0, WINED3DTSS_TEXCOORDINDEX, WINED3DTSS_TCI_CAMERASPACEPOSITION | 1 );
2092      * means use the vertex position (camera-space) as the input texture coordinates
2093      * for this texture stage, and the wrap mode set in the WINED3DRS_WRAP1 render
2094      * state. We do not (yet) support the WINED3DRENDERSTATE_WRAPx values, nor tie them up
2095      * to the TEXCOORDINDEX value
2096      */
2097
2098     /*
2099      * Be careful the value of the mask 0xF0000 come from d3d8types.h infos
2100      */
2101     switch (stateblock->textureState[stage][WINED3DTSS_TEXCOORDINDEX] & 0xFFFF0000) {
2102     case WINED3DTSS_TCI_PASSTHRU:
2103         /*Use the specified texture coordinates contained within the vertex format. This value resolves to zero.*/
2104         glDisable(GL_TEXTURE_GEN_S);
2105         glDisable(GL_TEXTURE_GEN_T);
2106         glDisable(GL_TEXTURE_GEN_R);
2107         glDisable(GL_TEXTURE_GEN_Q);
2108         checkGLcall("glDisable(GL_TEXTURE_GEN_S,T,R,Q)");
2109         break;
2110
2111     case WINED3DTSS_TCI_CAMERASPACEPOSITION:
2112         /* CameraSpacePosition means use the vertex position, transformed to camera space,
2113          * as the input texture coordinates for this stage's texture transformation. This
2114          * equates roughly to EYE_LINEAR
2115          */
2116         {
2117             float s_plane[] = { 1.0, 0.0, 0.0, 0.0 };
2118             float t_plane[] = { 0.0, 1.0, 0.0, 0.0 };
2119             float r_plane[] = { 0.0, 0.0, 1.0, 0.0 };
2120             float q_plane[] = { 0.0, 0.0, 0.0, 1.0 };
2121             TRACE("WINED3DTSS_TCI_CAMERASPACEPOSITION - Set eye plane\n");
2122
2123             glMatrixMode(GL_MODELVIEW);
2124             glPushMatrix();
2125             glLoadIdentity();
2126             glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
2127             glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
2128             glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
2129             glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
2130             glPopMatrix();
2131
2132             TRACE("WINED3DTSS_TCI_CAMERASPACEPOSITION - Set GL_TEXTURE_GEN_x and GL_x, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR\n");
2133             glEnable(GL_TEXTURE_GEN_S);
2134             checkGLcall("glEnable(GL_TEXTURE_GEN_S)");
2135             glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
2136             checkGLcall("glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)");
2137             glEnable(GL_TEXTURE_GEN_T);
2138             checkGLcall("glEnable(GL_TEXTURE_GEN_T)");
2139             glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
2140             checkGLcall("glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)");
2141             glEnable(GL_TEXTURE_GEN_R);
2142             checkGLcall("glEnable(GL_TEXTURE_GEN_R)");
2143             glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
2144             checkGLcall("glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)");
2145         }
2146         break;
2147
2148     case WINED3DTSS_TCI_CAMERASPACENORMAL:
2149         {
2150             if (GL_SUPPORT(NV_TEXGEN_REFLECTION)) {
2151                 float s_plane[] = { 1.0, 0.0, 0.0, 0.0 };
2152                 float t_plane[] = { 0.0, 1.0, 0.0, 0.0 };
2153                 float r_plane[] = { 0.0, 0.0, 1.0, 0.0 };
2154                 float q_plane[] = { 0.0, 0.0, 0.0, 1.0 };
2155                 TRACE("WINED3DTSS_TCI_CAMERASPACENORMAL - Set eye plane\n");
2156
2157                 glMatrixMode(GL_MODELVIEW);
2158                 glPushMatrix();
2159                 glLoadIdentity();
2160                 glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
2161                 glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
2162                 glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
2163                 glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
2164                 glPopMatrix();
2165
2166                 glEnable(GL_TEXTURE_GEN_S);
2167                 checkGLcall("glEnable(GL_TEXTURE_GEN_S)");
2168                 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
2169                 checkGLcall("glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV)");
2170                 glEnable(GL_TEXTURE_GEN_T);
2171                 checkGLcall("glEnable(GL_TEXTURE_GEN_T)");
2172                 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
2173                 checkGLcall("glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV)");
2174                 glEnable(GL_TEXTURE_GEN_R);
2175                 checkGLcall("glEnable(GL_TEXTURE_GEN_R)");
2176                 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
2177                 checkGLcall("glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV)");
2178             }
2179         }
2180         break;
2181
2182     case WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR:
2183         {
2184             if (GL_SUPPORT(NV_TEXGEN_REFLECTION)) {
2185             float s_plane[] = { 1.0, 0.0, 0.0, 0.0 };
2186             float t_plane[] = { 0.0, 1.0, 0.0, 0.0 };
2187             float r_plane[] = { 0.0, 0.0, 1.0, 0.0 };
2188             float q_plane[] = { 0.0, 0.0, 0.0, 1.0 };
2189             TRACE("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Set eye plane\n");
2190
2191             glMatrixMode(GL_MODELVIEW);
2192             glPushMatrix();
2193             glLoadIdentity();
2194             glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
2195             glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
2196             glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
2197             glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
2198             glPopMatrix();
2199
2200             glEnable(GL_TEXTURE_GEN_S);
2201             checkGLcall("glEnable(GL_TEXTURE_GEN_S)");
2202             glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
2203             checkGLcall("glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV)");
2204             glEnable(GL_TEXTURE_GEN_T);
2205             checkGLcall("glEnable(GL_TEXTURE_GEN_T)");
2206             glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
2207             checkGLcall("glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV)");
2208             glEnable(GL_TEXTURE_GEN_R);
2209             checkGLcall("glEnable(GL_TEXTURE_GEN_R)");
2210             glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
2211             checkGLcall("glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV)");
2212             }
2213         }
2214         break;
2215
2216     /* Unhandled types: */
2217     default:
2218         /* Todo: */
2219         /* ? disable GL_TEXTURE_GEN_n ? */
2220         glDisable(GL_TEXTURE_GEN_S);
2221         glDisable(GL_TEXTURE_GEN_T);
2222         glDisable(GL_TEXTURE_GEN_R);
2223         glDisable(GL_TEXTURE_GEN_Q);
2224         FIXME("Unhandled WINED3DTSS_TEXCOORDINDEX %x\n", stateblock->textureState[stage][WINED3DTSS_TEXCOORDINDEX]);
2225         break;
2226     }
2227
2228     /* Update the texture matrix */
2229     if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_TEXTURE0 + stage))) {
2230         transform_texture(STATE_TRANSFORM(WINED3DTS_TEXTURE0 + stage), stateblock, context);
2231     }
2232
2233     if(!isStateDirty(context, STATE_VDECL) && context->namedArraysLoaded) {
2234         /* Reload the arrays if we are using fixed function arrays to reflect the selected coord input
2235          * source. Call loadTexCoords directly because there is no need to reparse the vertex declaration
2236          * and do all the things linked to it
2237          * TODO: Tidy that up to reload only the arrays of the changed unit
2238          */
2239         GLint curVBO = GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT) ? -1 : 0;
2240
2241         unloadTexCoords(stateblock);
2242         loadTexCoords(stateblock, &stateblock->wineD3DDevice->strided_streams, &curVBO);
2243     }
2244 }
2245
2246 static void shaderconstant(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2247     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
2248
2249     /* Vertex and pixel shader states will call a shader upload, don't do anything as long one of them
2250      * has an update pending
2251      */
2252     if(isStateDirty(context, STATE_VDECL) ||
2253        isStateDirty(context, STATE_PIXELSHADER)) {
2254        return;
2255     }
2256
2257     device->shader_backend->shader_load_constants((IWineD3DDevice *) device, use_ps(device), use_vs(device));
2258 }
2259
2260 static void tex_bumpenvlscale(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2261     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
2262     union {
2263         DWORD d;
2264         float f;
2265     } tmpvalue;
2266
2267     if(stateblock->pixelShader && stage != 0 &&
2268        ((IWineD3DPixelShaderImpl *) stateblock->pixelShader)->baseShader.reg_maps.luminanceparams[stage]) {
2269         /* The pixel shader has to know the luminance scale. Do a constants update if it
2270          * isn't scheduled anyway
2271          */
2272         if(!isStateDirty(context, STATE_PIXELSHADERCONSTANT) &&
2273            !isStateDirty(context, STATE_PIXELSHADER)) {
2274             shaderconstant(STATE_PIXELSHADERCONSTANT, stateblock, context);
2275         }
2276     }
2277
2278     tmpvalue.d = stateblock->textureState[stage][WINED3DTSS_BUMPENVLSCALE];
2279     if(tmpvalue.f != 0.0) {
2280         FIXME("WINED3DTSS_BUMPENVLSCALE not supported yet\n");
2281     }
2282 }
2283
2284 static void tex_bumpenvloffset(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2285     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
2286     union {
2287         DWORD d;
2288         float f;
2289     } tmpvalue;
2290
2291     if(stateblock->pixelShader && stage != 0 &&
2292        ((IWineD3DPixelShaderImpl *) stateblock->pixelShader)->baseShader.reg_maps.luminanceparams[stage]) {
2293         /* The pixel shader has to know the luminance offset. Do a constants update if it
2294          * isn't scheduled anyway
2295          */
2296         if(!isStateDirty(context, STATE_PIXELSHADERCONSTANT) &&
2297            !isStateDirty(context, STATE_PIXELSHADER)) {
2298             shaderconstant(STATE_PIXELSHADERCONSTANT, stateblock, context);
2299         }
2300     }
2301
2302     tmpvalue.d = stateblock->textureState[stage][WINED3DTSS_BUMPENVLOFFSET];
2303     if(tmpvalue.f != 0.0) {
2304         FIXME("WINED3DTSS_BUMPENVLOFFSET not supported yet\n");
2305     }
2306 }
2307
2308 static void sampler_texmatrix(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2309     BOOL texIsPow2 = FALSE;
2310     DWORD sampler = state - STATE_SAMPLER(0);
2311     IWineD3DBaseTexture *texture = stateblock->textures[sampler];
2312
2313     if(!texture) return;
2314     /* The fixed function np2 texture emulation uses the texture matrix to fix up the coordinates
2315      * IWineD3DBaseTexture::ApplyStateChanges multiplies the set matrix with a fixup matrix. Before the
2316      * scaling is reapplied or removed, the texture matrix has to be reapplied
2317      *
2318      * The mapped stage is alrady active because the sampler() function below, which is part of the
2319      * misc pipeline
2320      */
2321     if(!GL_SUPPORT(ARB_TEXTURE_NON_POWER_OF_TWO) && sampler < MAX_TEXTURES) {
2322         if(stateblock->textureDimensions[sampler] == GL_TEXTURE_2D ||
2323            stateblock->textureDimensions[sampler] == GL_TEXTURE_RECTANGLE_ARB) {
2324             if(((IWineD3DTextureImpl *)texture)->baseTexture.pow2Matrix[0] != 1.0 ||
2325                ((IWineD3DTextureImpl *)texture)->baseTexture.pow2Matrix[5] != 1.0 ) {
2326                 texIsPow2 = TRUE;
2327             }
2328         } else if(stateblock->textureDimensions[sampler] == GL_TEXTURE_CUBE_MAP_ARB) {
2329             if(((IWineD3DCubeTextureImpl *)texture)->baseTexture.pow2Matrix[0] != 1.0) {
2330                 texIsPow2 = TRUE;
2331             }
2332         }
2333
2334         if(texIsPow2 || context->lastWasPow2Texture[sampler]) {
2335             context->lastWasPow2Texture[sampler] = texIsPow2;
2336             transform_texture(STATE_TRANSFORM(WINED3DTS_TEXTURE0 + stateblock->wineD3DDevice->texUnitMap[sampler]), stateblock, context);
2337         }
2338     }
2339 }
2340
2341 static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2342     DWORD sampler = state - STATE_SAMPLER(0);
2343     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[sampler];
2344     union {
2345         float f;
2346         DWORD d;
2347     } tmpvalue;
2348
2349     TRACE("Sampler: %d\n", sampler);
2350     /* Enabling and disabling texture dimensions is done by texture stage state / pixel shader setup, this function
2351      * only has to bind textures and set the per texture states
2352      */
2353
2354     if (mapped_stage == -1) {
2355         TRACE("No sampler mapped to stage %d. Returning.\n", sampler);
2356         return;
2357     }
2358
2359     if (GL_SUPPORT(ARB_MULTITEXTURE)) {
2360         if (mapped_stage >= GL_LIMITS(combined_samplers)) {
2361             return;
2362         }
2363         GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
2364         checkGLcall("glActiveTextureARB");
2365     } else if (sampler > 0) {
2366         /* We can't do anything here */
2367         WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
2368         return;
2369     }
2370
2371     if(stateblock->textures[sampler]) {
2372         IWineD3DBaseTexture_PreLoad(stateblock->textures[sampler]);
2373         IWineD3DBaseTexture_ApplyStateChanges(stateblock->textures[sampler], stateblock->textureState[sampler], stateblock->samplerState[sampler]);
2374
2375         if (GL_SUPPORT(EXT_TEXTURE_LOD_BIAS)) {
2376             tmpvalue.d = stateblock->samplerState[sampler][WINED3DSAMP_MIPMAPLODBIAS];
2377             glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT,
2378                       GL_TEXTURE_LOD_BIAS_EXT,
2379                       tmpvalue.f);
2380             checkGLcall("glTexEnvi(GL_TEXTURE_LOD_BIAS_EXT, ...)");
2381         }
2382
2383         if (stateblock->wineD3DDevice->ps_selected_mode != SHADER_NONE && stateblock->pixelShader &&
2384             ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.function) {
2385             /* Using a pixel shader? Verify the sampler types */
2386
2387             /* Make sure that the texture dimensions are enabled. I don't have to disable the other
2388              * dimensions because the shader knows from which texture type to sample from. For the sake of
2389              * debugging all dimensions could be enabled and a texture with some ugly pink bound to the unused
2390              * dimensions. This should make wrong sampling sources visible :-)
2391              */
2392             glEnable(stateblock->textureDimensions[sampler]);
2393             checkGLcall("glEnable(stateblock->textureDimensions[sampler])");
2394         } else if(sampler < stateblock->lowest_disabled_stage) {
2395             if(stateblock->renderState[WINED3DRS_COLORKEYENABLE] && sampler == 0) {
2396                 /* If color keying is enabled update the alpha test, it depends on the existence
2397                  * of a color key in stage 0
2398                  */
2399                 state_alpha(WINED3DRS_COLORKEYENABLE, stateblock, context);
2400             }
2401         }
2402     } else if(mapped_stage < GL_LIMITS(textures)) {
2403         if(sampler < stateblock->lowest_disabled_stage) {
2404             /* TODO: What should I do with pixel shaders here ??? */
2405             if(stateblock->renderState[WINED3DRS_COLORKEYENABLE] && sampler == 0) {
2406                 /* If color keying is enabled update the alpha test, it depends on the existence
2407                 * of a color key in stage 0
2408                 */
2409                 state_alpha(WINED3DRS_COLORKEYENABLE, stateblock, context);
2410             }
2411         } /* Otherwise tex_colorop disables the stage */
2412         glBindTexture(GL_TEXTURE_2D, stateblock->wineD3DDevice->dummyTextureName[sampler]);
2413         checkGLcall("glBindTexture(GL_TEXTURE_2D, stateblock->wineD3DDevice->dummyTextureName[sampler])");
2414     }
2415 }
2416
2417 void apply_pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2418     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
2419     BOOL use_pshader = use_ps(device);
2420     BOOL use_vshader = use_vs(device);
2421     BOOL update_fog = FALSE;
2422     int i;
2423
2424     if (use_pshader) {
2425         if(!context->last_was_pshader) {
2426             /* Former draw without a pixel shader, some samplers
2427              * may be disabled because of WINED3DTSS_COLOROP = WINED3DTOP_DISABLE
2428              * make sure to enable them
2429              */
2430             for(i=0; i < MAX_FRAGMENT_SAMPLERS; i++) {
2431                 if(!isStateDirty(context, STATE_SAMPLER(i))) {
2432                     sampler(STATE_SAMPLER(i), stateblock, context);
2433                 }
2434             }
2435             update_fog = TRUE;
2436         } else {
2437            /* Otherwise all samplers were activated by the code above in earlier draws, or by sampler()
2438             * if a different texture was bound. I don't have to do anything.
2439             */
2440         }
2441
2442         /* Compile and bind the shader */
2443         IWineD3DPixelShader_CompileShader(stateblock->pixelShader);
2444     } else {
2445         /* Disabled the pixel shader - color ops weren't applied
2446          * while it was enabled, so re-apply them.
2447          */
2448         for(i=0; i < MAX_TEXTURES; i++) {
2449             if(!isStateDirty(context, STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP))) {
2450                 device->StateTable[STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP)].apply
2451                         (STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP), stateblock, context);
2452             }
2453         }
2454         if(context->last_was_pshader)
2455             update_fog = TRUE;
2456     }
2457
2458     if(!isStateDirty(context, device->StateTable[STATE_VSHADER].representative)) {
2459         device->shader_backend->shader_select((IWineD3DDevice *)stateblock->wineD3DDevice, use_pshader, use_vshader);
2460
2461         if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && (use_vshader || use_pshader)) {
2462             shaderconstant(STATE_VERTEXSHADERCONSTANT, stateblock, context);
2463         }
2464     }
2465
2466     if(update_fog)
2467         state_fog(state, stateblock, context);
2468
2469     context->last_was_pshader = use_pshader;
2470 }
2471
2472 static void shader_bumpenvmat(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2473     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
2474     if(stateblock->pixelShader && stage != 0 &&
2475        ((IWineD3DPixelShaderImpl *) stateblock->pixelShader)->baseShader.reg_maps.bumpmat[stage]) {
2476         /* The pixel shader has to know the bump env matrix. Do a constants update if it isn't scheduled
2477          * anyway
2478          */
2479         if(!isStateDirty(context, STATE_PIXELSHADERCONSTANT) &&
2480             !isStateDirty(context, STATE_PIXELSHADER)) {
2481             shaderconstant(STATE_PIXELSHADERCONSTANT, stateblock, context);
2482             }
2483     }
2484 }
2485
2486 static void tex_bumpenvmat(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2487     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
2488     float mat[2][2];
2489     if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
2490         if(stage >= GL_LIMITS(texture_stages)) {
2491             WARN("Bump env matrix of unsupported stage set\n");
2492         } else if(GL_SUPPORT(ARB_MULTITEXTURE)) {
2493             GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + stage));
2494             checkGLcall("GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + stage))");
2495         }
2496         mat[0][0] = *((float *) &stateblock->textureState[stage][WINED3DTSS_BUMPENVMAT00]);
2497         mat[1][0] = *((float *) &stateblock->textureState[stage][WINED3DTSS_BUMPENVMAT01]);
2498         mat[0][1] = *((float *) &stateblock->textureState[stage][WINED3DTSS_BUMPENVMAT10]);
2499         mat[1][1] = *((float *) &stateblock->textureState[stage][WINED3DTSS_BUMPENVMAT11]);
2500         GL_EXTCALL(glTexBumpParameterfvATI(GL_BUMP_ROT_MATRIX_ATI, (float *) mat));
2501         checkGLcall("glTexBumpParameterfvATI");
2502     }
2503 }
2504
2505 static void transform_world(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2506     /* This function is called by transform_view below if the view matrix was changed too
2507      *
2508      * Deliberately no check if the vertex declaration is dirty because the vdecl state
2509      * does not always update the world matrix, only on a switch between transformed
2510      * and untransformed draws. It *may* happen that the world matrix is set 2 times during one
2511      * draw, but that should be rather rare and cheaper in total.
2512      */
2513     glMatrixMode(GL_MODELVIEW);
2514     checkGLcall("glMatrixMode");
2515
2516     if(context->last_was_rhw) {
2517         glLoadIdentity();
2518         checkGLcall("glLoadIdentity()");
2519     } else {
2520         /* In the general case, the view matrix is the identity matrix */
2521         if (stateblock->wineD3DDevice->view_ident) {
2522             glLoadMatrixf(&stateblock->transforms[WINED3DTS_WORLDMATRIX(0)].u.m[0][0]);
2523             checkGLcall("glLoadMatrixf");
2524         } else {
2525             glLoadMatrixf(&stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
2526             checkGLcall("glLoadMatrixf");
2527             glMultMatrixf(&stateblock->transforms[WINED3DTS_WORLDMATRIX(0)].u.m[0][0]);
2528             checkGLcall("glMultMatrixf");
2529         }
2530     }
2531 }
2532
2533 static void clipplane(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2534     UINT index = state - STATE_CLIPPLANE(0);
2535
2536     if(isStateDirty(context, STATE_TRANSFORM(WINED3DTS_VIEW)) || index >= GL_LIMITS(clipplanes)) {
2537         return;
2538     }
2539
2540     /* Clip Plane settings are affected by the model view in OpenGL, the View transform in direct3d */
2541     glMatrixMode(GL_MODELVIEW);
2542     glPushMatrix();
2543     glLoadMatrixf(&stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
2544
2545     TRACE("Clipplane [%f,%f,%f,%f]\n",
2546           stateblock->clipplane[index][0],
2547           stateblock->clipplane[index][1],
2548           stateblock->clipplane[index][2],
2549           stateblock->clipplane[index][3]);
2550     glClipPlane(GL_CLIP_PLANE0 + index, stateblock->clipplane[index]);
2551     checkGLcall("glClipPlane");
2552
2553     glPopMatrix();
2554 }
2555
2556 static void transform_worldex(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2557     UINT matrix = state - STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0));
2558     GLenum glMat;
2559     TRACE("Setting world matrix %d\n", matrix);
2560
2561     if(matrix >= GL_LIMITS(blends)) {
2562         WARN("Unsupported blend matrix set\n");
2563         return;
2564     } else if(isStateDirty(context, STATE_TRANSFORM(WINED3DTS_VIEW))) {
2565         return;
2566     }
2567
2568     /* GL_MODELVIEW0_ARB:  0x1700
2569      * GL_MODELVIEW1_ARB:  0x0x850a
2570      * GL_MODELVIEW2_ARB:  0x8722
2571      * GL_MODELVIEW3_ARB:  0x8723
2572      * etc
2573      * GL_MODELVIEW31_ARB: 0x873F
2574      */
2575     if(matrix == 1) glMat = GL_MODELVIEW1_ARB;
2576     else glMat = GL_MODELVIEW2_ARB - 2 + matrix;
2577
2578     glMatrixMode(glMat);
2579     checkGLcall("glMatrixMode(glMat)");
2580
2581     /* World matrix 0 is multiplied with the view matrix because d3d uses 3 matrices while gl uses only 2. To avoid
2582      * weighting the view matrix incorrectly it has to be multiplied into every gl modelview matrix
2583      */
2584     if(stateblock->wineD3DDevice->view_ident) {
2585         glLoadMatrixf(&stateblock->transforms[WINED3DTS_WORLDMATRIX(matrix)].u.m[0][0]);
2586         checkGLcall("glLoadMatrixf")
2587     } else {
2588         glLoadMatrixf(&stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
2589         checkGLcall("glLoadMatrixf")
2590         glMultMatrixf(&stateblock->transforms[WINED3DTS_WORLDMATRIX(matrix)].u.m[0][0]);
2591         checkGLcall("glMultMatrixf")
2592     }
2593 }
2594
2595 static void state_vertexblend(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2596     WINED3DVERTEXBLENDFLAGS val = stateblock->renderState[WINED3DRS_VERTEXBLEND];
2597
2598     switch(val) {
2599         case WINED3DVBF_1WEIGHTS:
2600         case WINED3DVBF_2WEIGHTS:
2601         case WINED3DVBF_3WEIGHTS:
2602             if(GL_SUPPORT(ARB_VERTEX_BLEND)) {
2603                 glEnable(GL_VERTEX_BLEND_ARB);
2604                 checkGLcall("glEnable(GL_VERTEX_BLEND_ARB)");
2605
2606                 /* D3D adds one more matrix which has weight (1 - sum(weights)). This is enabled at context
2607                  * creation with enabling GL_WEIGHT_SUM_UNITY_ARB.
2608                  */
2609                 GL_EXTCALL(glVertexBlendARB(stateblock->renderState[WINED3DRS_VERTEXBLEND] + 1));
2610
2611                 if(!stateblock->wineD3DDevice->vertexBlendUsed) {
2612                     int i;
2613                     for(i = 1; i < GL_LIMITS(blends); i++) {
2614                         if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(i)))) {
2615                             transform_worldex(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(i)), stateblock, context);
2616                         }
2617                     }
2618                     stateblock->wineD3DDevice->vertexBlendUsed = TRUE;
2619                 }
2620             } else {
2621                 static BOOL once = FALSE;
2622                 if(!once) {
2623                     once = TRUE;
2624                     /* TODO: Implement vertex blending in drawStridedSlow */
2625                     FIXME("Vertex blending enabled, but not supported by hardware\n");
2626                 }
2627             }
2628             break;
2629
2630         case WINED3DVBF_DISABLE:
2631         case WINED3DVBF_0WEIGHTS: /* for Indexed vertex blending - not supported */
2632             if(GL_SUPPORT(ARB_VERTEX_BLEND)) {
2633                 glDisable(GL_VERTEX_BLEND_ARB);
2634                 checkGLcall("glDisable(GL_VERTEX_BLEND_ARB)");
2635             } else {
2636                 TRACE("Vertex blending disabled\n");
2637             }
2638             break;
2639
2640         case WINED3DVBF_TWEENING:
2641             /* Just set the vertex weight for weight 0, enable vertex blending and hope the app doesn't have
2642              * vertex weights in the vertices?
2643              * For now we don't report that as supported, so a warn should suffice
2644              */
2645             WARN("Tweening not supported yet\n");
2646             break;
2647     }
2648 }
2649
2650 static void transform_view(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2651     unsigned int k;
2652
2653     /* If we are changing the View matrix, reset the light and clipping planes to the new view
2654      * NOTE: We have to reset the positions even if the light/plane is not currently
2655      *       enabled, since the call to enable it will not reset the position.
2656      * NOTE2: Apparently texture transforms do NOT need reapplying
2657      */
2658
2659     PLIGHTINFOEL *light = NULL;
2660
2661     glMatrixMode(GL_MODELVIEW);
2662     checkGLcall("glMatrixMode(GL_MODELVIEW)");
2663     glLoadMatrixf(&stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
2664     checkGLcall("glLoadMatrixf(...)");
2665
2666     /* Reset lights. TODO: Call light apply func */
2667     for(k = 0; k < stateblock->wineD3DDevice->maxConcurrentLights; k++) {
2668         light = stateblock->activeLights[k];
2669         if(!light) continue;
2670         glLightfv(GL_LIGHT0 + light->glIndex, GL_POSITION, light->lightPosn);
2671         checkGLcall("glLightfv posn");
2672         glLightfv(GL_LIGHT0 + light->glIndex, GL_SPOT_DIRECTION, light->lightDirn);
2673         checkGLcall("glLightfv dirn");
2674     }
2675
2676     /* Reset Clipping Planes  */
2677     for (k = 0; k < GL_LIMITS(clipplanes); k++) {
2678         if(!isStateDirty(context, STATE_CLIPPLANE(k))) {
2679             clipplane(STATE_CLIPPLANE(k), stateblock, context);
2680         }
2681     }
2682
2683     if(context->last_was_rhw) {
2684         glLoadIdentity();
2685         checkGLcall("glLoadIdentity()");
2686         /* No need to update the world matrix, the identity is fine */
2687         return;
2688     }
2689
2690     /* Call the world matrix state, this will apply the combined WORLD + VIEW matrix
2691      * No need to do it here if the state is scheduled for update.
2692      */
2693     if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)))) {
2694         transform_world(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), stateblock, context);
2695     }
2696
2697     /* Avoid looping over a number of matrices if the app never used the functionality */
2698     if(stateblock->wineD3DDevice->vertexBlendUsed) {
2699         for(k = 1; k < GL_LIMITS(blends); k++) {
2700             if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(k)))) {
2701                 transform_worldex(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(k)), stateblock, context);
2702             }
2703         }
2704     }
2705 }
2706
2707 static void transform_projection(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2708     glMatrixMode(GL_PROJECTION);
2709     checkGLcall("glMatrixMode(GL_PROJECTION)");
2710     glLoadIdentity();
2711     checkGLcall("glLoadIdentity");
2712
2713     if(context->last_was_rhw) {
2714         double X, Y, height, width, minZ, maxZ;
2715
2716         X      = stateblock->viewport.X;
2717         Y      = stateblock->viewport.Y;
2718         height = stateblock->viewport.Height;
2719         width  = stateblock->viewport.Width;
2720         minZ   = stateblock->viewport.MinZ;
2721         maxZ   = stateblock->viewport.MaxZ;
2722
2723         if(!stateblock->wineD3DDevice->untransformed) {
2724             /* Transformed vertices are supposed to bypass the whole transform pipeline including
2725              * frustum clipping. This can't be done in opengl, so this code adjusts the Z range to
2726              * suppress depth clipping. This can be done because it is an orthogonal projection and
2727              * the Z coordinate does not affect the size of the primitives. Half Life 1 and Prince of
2728              * Persia 3D need this.
2729              *
2730              * Note that using minZ and maxZ here doesn't entirely fix the problem, since view frustum
2731              * clipping is still enabled, but it seems to fix it for all apps tested so far. A minor
2732              * problem can be witnessed in half-life 1 engine based games, the weapon is clipped close
2733              * to the viewer.
2734              *
2735              * Also note that this breaks z comparison against z values filled in with clear,
2736              * but no app depending on that and disabled clipping has been found yet. Comparing
2737              * primitives against themselves works, so the Z buffer is still intact for normal hidden
2738              * surface removal.
2739              *
2740              * We could disable clipping entirely by setting the near to infinity and far to -infinity,
2741              * but this would break Z buffer operation. Raising the range to something less than
2742              * infinity would help a bit at the cost of Z precision, but it wouldn't eliminate the
2743              * problem either.
2744              */
2745             TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, -minZ, -maxZ);
2746             if(stateblock->wineD3DDevice->render_offscreen) {
2747                 glOrtho(X, X + width, -Y, -Y - height, -minZ, -maxZ);
2748             } else {
2749                 glOrtho(X, X + width, Y + height, Y, -minZ, -maxZ);
2750             }
2751         } else {
2752             /* If the app mixes transformed and untransformed primitives we can't use the coordinate system
2753              * trick above because this would mess up transformed and untransformed Z order. Pass the z position
2754              * unmodified to opengl.
2755              *
2756              * If the app depends on mixed types and disabled clipping we're out of luck without a pipeline
2757              * replacement shader.
2758              */
2759             TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, 1.0, -1.0);
2760             if(stateblock->wineD3DDevice->render_offscreen) {
2761                 glOrtho(X, X + width, -Y, -Y - height, 0.0, -1.0);
2762             } else {
2763                 glOrtho(X, X + width, Y + height, Y, 0.0, -1.0);
2764             }
2765         }
2766         checkGLcall("glOrtho");
2767
2768         /* Window Coord 0 is the middle of the first pixel, so translate by 1/2 pixels */
2769         glTranslatef(0.5, 0.5, 0);
2770         checkGLcall("glTranslatef(0.5, 0.5, 0)");
2771         /* D3D texture coordinates are flipped compared to OpenGL ones, so
2772          * render everything upside down when rendering offscreen. */
2773         if (stateblock->wineD3DDevice->render_offscreen) {
2774             glScalef(1.0, -1.0, 1.0);
2775             checkGLcall("glScalef");
2776         }
2777     } else {
2778         /* The rule is that the window coordinate 0 does not correspond to the
2779             beginning of the first pixel, but the center of the first pixel.
2780             As a consequence if you want to correctly draw one line exactly from
2781             the left to the right end of the viewport (with all matrices set to
2782             be identity), the x coords of both ends of the line would be not
2783             -1 and 1 respectively but (-1-1/viewport_widh) and (1-1/viewport_width)
2784             instead.
2785
2786             1.0 / Width is used because the coord range goes from -1.0 to 1.0, then we
2787             divide by the Width/Height, so we need the half range(1.0) to translate by
2788             half a pixel.
2789
2790             The other fun is that d3d's output z range after the transformation is [0;1],
2791             but opengl's is [-1;1]. Since the z buffer is in range [0;1] for both, gl
2792             scales [-1;1] to [0;1]. This would mean that we end up in [0.5;1] and loose a lot
2793             of Z buffer precision and the clear values do not match in the z test. Thus scale
2794             [0;1] to [-1;1], so when gl undoes that we utilize the full z range
2795          */
2796         glTranslatef(1.0 / stateblock->viewport.Width, -1.0/ stateblock->viewport.Height, -1.0);
2797         checkGLcall("glTranslatef (1.0 / width, -1.0 / height, -1.0)");
2798         if (stateblock->wineD3DDevice->render_offscreen) {
2799             /* D3D texture coordinates are flipped compared to OpenGL ones, so
2800              * render everything upside down when rendering offscreen. */
2801             glScalef(1.0, -1.0, 2.0);
2802         } else {
2803             glScalef(1.0, 1.0, 2.0);
2804         }
2805         checkGLcall("glScalef");
2806
2807         glMultMatrixf(&stateblock->transforms[WINED3DTS_PROJECTION].u.m[0][0]);
2808         checkGLcall("glLoadMatrixf");
2809     }
2810 }
2811
2812 /* This should match any arrays loaded in loadVertexData.
2813  * stateblock impl is required for GL_SUPPORT
2814  * TODO: Only load / unload arrays if we have to.
2815  */
2816 static inline void unloadVertexData(IWineD3DStateBlockImpl *stateblock) {
2817     glDisableClientState(GL_VERTEX_ARRAY);
2818     glDisableClientState(GL_NORMAL_ARRAY);
2819     glDisableClientState(GL_COLOR_ARRAY);
2820     if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
2821         glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
2822     }
2823     if (GL_SUPPORT(ARB_VERTEX_BLEND)) {
2824         glDisableClientState(GL_WEIGHT_ARRAY_ARB);
2825     } else if (GL_SUPPORT(EXT_VERTEX_WEIGHTING)) {
2826         glDisableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT);
2827     }
2828     unloadTexCoords(stateblock);
2829 }
2830
2831 /* This should match any arrays loaded in loadNumberedArrays
2832  * TODO: Only load / unload arrays if we have to.
2833  */
2834 static inline void unloadNumberedArrays(IWineD3DStateBlockImpl *stateblock) {
2835     /* disable any attribs (this is the same for both GLSL and ARB modes) */
2836     GLint maxAttribs = 16;
2837     int i;
2838
2839     /* Leave all the attribs disabled */
2840     glGetIntegerv(GL_MAX_VERTEX_ATTRIBS_ARB, &maxAttribs);
2841     /* MESA does not support it right not */
2842     if (glGetError() != GL_NO_ERROR)
2843         maxAttribs = 16;
2844     for (i = 0; i < maxAttribs; ++i) {
2845         GL_EXTCALL(glDisableVertexAttribArrayARB(i));
2846         checkGLcall("glDisableVertexAttribArrayARB(reg)");
2847         /* Some Windows drivers(NV GF 7) use the latest value that was used when drawing with the now
2848          * deactivated stream disabled, some other drivers(ATI, NV GF 8) set the undefined values to 0x00.
2849          * Let's set them to 0x00 to avoid hitting some undefined aspects of OpenGL. All that is really
2850          * important here is the glDisableVertexAttribArrayARB call above. The test shows that the refrast
2851          * keeps dereferencing the pointers, which would cause crashes in some games like Half Life 2: Episode Two.
2852          */
2853         GL_EXTCALL(glVertexAttrib4NubARB(i, 0, 0, 0, 0));
2854         checkGLcall("glVertexAttrib4NubARB(i, 0, 0, 0, 0)");
2855     }
2856 }
2857
2858 static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock, WineDirect3DVertexStridedData *strided) {
2859     GLint curVBO = GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT) ? -1 : 0;
2860     int i;
2861     UINT *offset = stateblock->streamOffset;
2862     IWineD3DVertexBufferImpl *vb;
2863     DWORD_PTR shift_index;
2864
2865     /* Default to no instancing */
2866     stateblock->wineD3DDevice->instancedDraw = FALSE;
2867
2868     for (i = 0; i < MAX_ATTRIBS; i++) {
2869
2870         if (!strided->u.input[i].lpData && !strided->u.input[i].VBO)
2871             continue;
2872
2873         /* Do not load instance data. It will be specified using glTexCoord by drawprim */
2874         if(stateblock->streamFlags[strided->u.input[i].streamNo] & WINED3DSTREAMSOURCE_INSTANCEDATA) {
2875             GL_EXTCALL(glDisableVertexAttribArrayARB(i));
2876             stateblock->wineD3DDevice->instancedDraw = TRUE;
2877             continue;
2878         }
2879
2880         TRACE_(d3d_shader)("Loading array %u [VBO=%u]\n", i, strided->u.input[i].VBO);
2881
2882         if(strided->u.input[i].dwStride) {
2883             if(curVBO != strided->u.input[i].VBO) {
2884                 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, strided->u.input[i].VBO));
2885                 checkGLcall("glBindBufferARB");
2886                 curVBO = strided->u.input[i].VBO;
2887             }
2888             vb = (IWineD3DVertexBufferImpl *) stateblock->streamSource[strided->u.input[i].streamNo];
2889             /* Use the VBO to find out if a vertex buffer exists, not the vb pointer. vb can point to a
2890              * user pointer data blob. In that case curVBO will be 0. If there is a vertex buffer but no
2891              * vbo we won't be load converted attributes anyway
2892              */
2893             if(curVBO && vb->conv_shift) {
2894                 TRACE("Loading attribute from shifted buffer\n");
2895                 TRACE("Attrib %d has original stride %d, new stride %d\n", i, strided->u.input[i].dwStride, vb->conv_stride);
2896                 TRACE("Original offset %p, additional offset 0x%08x\n",strided->u.input[i].lpData, vb->conv_shift[(DWORD_PTR) strided->u.input[i].lpData]);
2897                 TRACE("Opengl type %x\n", WINED3D_ATR_GLTYPE(strided->u.input[i].dwType));
2898                 shift_index = ((DWORD_PTR) strided->u.input[i].lpData + offset[strided->u.input[i].streamNo]);
2899                 shift_index = shift_index % strided->u.input[i].dwStride;
2900                 GL_EXTCALL(glVertexAttribPointerARB(i,
2901                                 WINED3D_ATR_SIZE(strided->u.input[i].dwType),
2902                                 WINED3D_ATR_GLTYPE(strided->u.input[i].dwType),
2903                                 WINED3D_ATR_NORMALIZED(strided->u.input[i].dwType),
2904                                 vb->conv_stride,
2905
2906                                 strided->u.input[i].lpData + vb->conv_shift[shift_index] +
2907                                 stateblock->loadBaseVertexIndex * strided->u.input[i].dwStride +
2908                                 offset[strided->u.input[i].streamNo]));
2909
2910             } else {
2911                 GL_EXTCALL(glVertexAttribPointerARB(i,
2912                                 WINED3D_ATR_SIZE(strided->u.input[i].dwType),
2913                                 WINED3D_ATR_GLTYPE(strided->u.input[i].dwType),
2914                                 WINED3D_ATR_NORMALIZED(strided->u.input[i].dwType),
2915                                 strided->u.input[i].dwStride,
2916
2917                                 strided->u.input[i].lpData +
2918                                 stateblock->loadBaseVertexIndex * strided->u.input[i].dwStride +
2919                                 offset[strided->u.input[i].streamNo]) );
2920                 }
2921             GL_EXTCALL(glEnableVertexAttribArrayARB(i));
2922         } else {
2923             /* Stride = 0 means always the same values. glVertexAttribPointerARB doesn't do that. Instead disable the pointer and
2924              * set up the attribute statically. But we have to figure out the system memory address.
2925              */
2926             BYTE *ptr = strided->u.input[i].lpData + offset[strided->u.input[i].streamNo];
2927             if(strided->u.input[i].VBO) {
2928                 vb = (IWineD3DVertexBufferImpl *) stateblock->streamSource[strided->u.input[i].streamNo];
2929                 ptr += (long) vb->resource.allocatedMemory;
2930             }
2931             GL_EXTCALL(glDisableVertexAttribArrayARB(i));
2932
2933             switch(strided->u.input[i].dwType) {
2934                 case WINED3DDECLTYPE_FLOAT1:
2935                     GL_EXTCALL(glVertexAttrib1fvARB(i, (float *) ptr));
2936                     break;
2937                 case WINED3DDECLTYPE_FLOAT2:
2938                     GL_EXTCALL(glVertexAttrib2fvARB(i, (float *) ptr));
2939                     break;
2940                 case WINED3DDECLTYPE_FLOAT3:
2941                     GL_EXTCALL(glVertexAttrib3fvARB(i, (float *) ptr));
2942                     break;
2943                 case WINED3DDECLTYPE_FLOAT4:
2944                     GL_EXTCALL(glVertexAttrib4fvARB(i, (float *) ptr));
2945                     break;
2946
2947                 case WINED3DDECLTYPE_UBYTE4:
2948                     GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
2949                     break;
2950                 case WINED3DDECLTYPE_UBYTE4N:
2951                 case WINED3DDECLTYPE_D3DCOLOR:
2952                     GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
2953                     break;
2954
2955                 case WINED3DDECLTYPE_SHORT2:
2956                     GL_EXTCALL(glVertexAttrib4svARB(i, (GLshort *) ptr));
2957                     break;
2958                 case WINED3DDECLTYPE_SHORT4:
2959                     GL_EXTCALL(glVertexAttrib4svARB(i, (GLshort *) ptr));
2960                     break;
2961
2962                 case WINED3DDECLTYPE_SHORT2N:
2963                 {
2964                     GLshort s[4] = {((short *) ptr)[0], ((short *) ptr)[1], 0, 1};
2965                     GL_EXTCALL(glVertexAttrib4NsvARB(i, s));
2966                     break;
2967                 }
2968                 case WINED3DDECLTYPE_USHORT2N:
2969                 {
2970                     GLushort s[4] = {((unsigned short *) ptr)[0], ((unsigned short *) ptr)[1], 0, 1};
2971                     GL_EXTCALL(glVertexAttrib4NusvARB(i, s));
2972                     break;
2973                 }
2974                 case WINED3DDECLTYPE_SHORT4N:
2975                     GL_EXTCALL(glVertexAttrib4NsvARB(i, (GLshort *) ptr));
2976                     break;
2977                 case WINED3DDECLTYPE_USHORT4N:
2978                     GL_EXTCALL(glVertexAttrib4NusvARB(i, (GLushort *) ptr));
2979                     break;
2980
2981                 case WINED3DDECLTYPE_UDEC3:
2982                     FIXME("Unsure about WINED3DDECLTYPE_UDEC3\n");
2983                     /*glVertexAttrib3usvARB(i, (GLushort *) ptr); Does not exist */
2984                     break;
2985                 case WINED3DDECLTYPE_DEC3N:
2986                     FIXME("Unsure about WINED3DDECLTYPE_DEC3N\n");
2987                     /*glVertexAttrib3NusvARB(i, (GLushort *) ptr); Does not exist */
2988                     break;
2989
2990                 case WINED3DDECLTYPE_FLOAT16_2:
2991                     /* Are those 16 bit floats. C doesn't have a 16 bit float type. I could read the single bits and calculate a 4
2992                      * byte float according to the IEEE standard
2993                      */
2994                     FIXME("Unsupported WINED3DDECLTYPE_FLOAT16_2\n");
2995                     break;
2996                 case WINED3DDECLTYPE_FLOAT16_4:
2997                     FIXME("Unsupported WINED3DDECLTYPE_FLOAT16_4\n");
2998                     break;
2999
3000                 case WINED3DDECLTYPE_UNUSED:
3001                 default:
3002                     ERR("Unexpected declaration in stride 0 attributes\n");
3003                     break;
3004
3005             }
3006         }
3007     }
3008     checkGLcall("Loading numbered arrays");
3009 }
3010
3011 /* Used from 2 different functions, and too big to justify making it inlined */
3012 static void loadVertexData(IWineD3DStateBlockImpl *stateblock, WineDirect3DVertexStridedData *sd) {
3013     UINT *offset = stateblock->streamOffset;
3014     GLint curVBO = GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT) ? -1 : 0;
3015
3016     TRACE("Using fast vertex array code\n");
3017
3018     /* This is fixed function pipeline only, and the fixed function pipeline doesn't do instancing */
3019     stateblock->wineD3DDevice->instancedDraw = FALSE;
3020
3021     /* Blend Data ---------------------------------------------- */
3022     if( (sd->u.s.blendWeights.lpData) || (sd->u.s.blendWeights.VBO) ||
3023         (sd->u.s.blendMatrixIndices.lpData) || (sd->u.s.blendMatrixIndices.VBO) ) {
3024
3025         if (GL_SUPPORT(ARB_VERTEX_BLEND)) {
3026             TRACE("Blend %d %p %d\n", WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType),
3027                 sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride, sd->u.s.blendWeights.dwStride + offset[sd->u.s.blendWeights.streamNo]);
3028
3029             glEnableClientState(GL_WEIGHT_ARRAY_ARB);
3030             checkGLcall("glEnableClientState(GL_WEIGHT_ARRAY_ARB)");
3031
3032             GL_EXTCALL(glVertexBlendARB(WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType) + 1));
3033
3034             VTRACE(("glWeightPointerARB(%d, GL_FLOAT, %d, %p)\n",
3035                 WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType) ,
3036                 sd->u.s.blendWeights.dwStride,
3037                 sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride + offset[sd->u.s.blendWeights.streamNo]));
3038
3039             if(curVBO != sd->u.s.blendWeights.VBO) {
3040                 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.blendWeights.VBO));
3041                 checkGLcall("glBindBufferARB");
3042                 curVBO = sd->u.s.blendWeights.VBO;
3043             }
3044
3045             GL_EXTCALL(glWeightPointerARB)(
3046                 WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType),
3047                 WINED3D_ATR_GLTYPE(sd->u.s.blendWeights.dwType),
3048                 sd->u.s.blendWeights.dwStride,
3049                 sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride + offset[sd->u.s.blendWeights.streamNo]);
3050
3051             checkGLcall("glWeightPointerARB");
3052
3053             if((sd->u.s.blendMatrixIndices.lpData) || (sd->u.s.blendMatrixIndices.VBO)){
3054                 static BOOL showfixme = TRUE;
3055                 if(showfixme){
3056                     FIXME("blendMatrixIndices support\n");
3057                     showfixme = FALSE;
3058                 }
3059             }
3060         } else if (GL_SUPPORT(EXT_VERTEX_WEIGHTING)) {
3061             /* FIXME("TODO\n");*/
3062 #if 0
3063
3064             GL_EXTCALL(glVertexWeightPointerEXT)(
3065                 WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType),
3066                 WINED3D_ATR_GLTYPE(sd->u.s.blendWeights.dwType),
3067                 sd->u.s.blendWeights.dwStride,
3068                 sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride);
3069             checkGLcall("glVertexWeightPointerEXT(numBlends, ...)");
3070             glEnableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT);
3071             checkGLcall("glEnableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT)");
3072 #endif
3073
3074         } else {
3075             /* TODO: support blends in drawStridedSlow
3076              * No need to write a FIXME here, this is done after the general vertex decl decoding
3077              */
3078             WARN("unsupported blending in openGl\n");
3079         }
3080     } else {
3081         if (GL_SUPPORT(ARB_VERTEX_BLEND)) {
3082             static const GLbyte one = 1;
3083             GL_EXTCALL(glWeightbvARB(1, &one));
3084             checkGLcall("glWeightivARB(GL_LIMITS(blends), weights)");
3085         }
3086     }
3087
3088 #if 0 /* FOG  ----------------------------------------------*/
3089     if (sd->u.s.fog.lpData || sd->u.s.fog.VBO) {
3090         /* TODO: fog*/
3091     if (GL_SUPPORT(EXT_FOG_COORD) {
3092              glEnableClientState(GL_FOG_COORDINATE_EXT);
3093             (GL_EXTCALL)(FogCoordPointerEXT)(
3094                 WINED3D_ATR_GLTYPE(sd->u.s.fog.dwType),
3095                 sd->u.s.fog.dwStride,
3096                 sd->u.s.fog.lpData + stateblock->loadBaseVertexIndex * sd->u.s.fog.dwStride);
3097         } else {
3098             /* don't bother falling back to 'slow' as we don't support software FOG yet. */
3099             /* FIXME: fixme once */
3100             TRACE("Hardware support for FOG is not avaiable, FOG disabled.\n");
3101         }
3102     } else {
3103         if (GL_SUPPRT(EXT_FOR_COORD) {
3104              /* make sure fog is disabled */
3105              glDisableClientState(GL_FOG_COORDINATE_EXT);
3106         }
3107     }
3108 #endif
3109
3110 #if 0 /* tangents  ----------------------------------------------*/
3111     if (sd->u.s.tangent.lpData || sd->u.s.tangent.VBO ||
3112         sd->u.s.binormal.lpData || sd->u.s.binormal.VBO) {
3113         /* TODO: tangents*/
3114         if (GL_SUPPORT(EXT_COORDINATE_FRAME) {
3115             if (sd->u.s.tangent.lpData || sd->u.s.tangent.VBO) {
3116                 glEnable(GL_TANGENT_ARRAY_EXT);
3117                 (GL_EXTCALL)(TangentPointerEXT)(
3118                     WINED3D_ATR_GLTYPE(sd->u.s.tangent.dwType),
3119                     sd->u.s.tangent.dwStride,
3120                     sd->u.s.tangent.lpData + stateblock->loadBaseVertexIndex * sd->u.s.tangent.dwStride);
3121             } else {
3122                     glDisable(GL_TANGENT_ARRAY_EXT);
3123             }
3124             if (sd->u.s.binormal.lpData || sd->u.s.binormal.VBO) {
3125                     glEnable(GL_BINORMAL_ARRAY_EXT);
3126                     (GL_EXTCALL)(BinormalPointerEXT)(
3127                         WINED3D_ATR_GLTYPE(sd->u.s.binormal.dwType),
3128                         sd->u.s.binormal.dwStride,
3129                         sd->u.s.binormal.lpData + stateblock->loadBaseVertexIndex * sd->u.s.binormal.dwStride);
3130             } else{
3131                     glDisable(GL_BINORMAL_ARRAY_EXT);
3132             }
3133
3134         } else {
3135             /* don't bother falling back to 'slow' as we don't support software tangents and binormals yet . */
3136             /* FIXME: fixme once */
3137             TRACE("Hardware support for tangents and binormals is not avaiable, tangents and binormals disabled.\n");
3138         }
3139     } else {
3140         if (GL_SUPPORT(EXT_COORDINATE_FRAME) {
3141              /* make sure fog is disabled */
3142              glDisable(GL_TANGENT_ARRAY_EXT);
3143              glDisable(GL_BINORMAL_ARRAY_EXT);
3144         }
3145     }
3146 #endif
3147
3148     /* Point Size ----------------------------------------------*/
3149     if (sd->u.s.pSize.lpData || sd->u.s.pSize.VBO) {
3150
3151         /* no such functionality in the fixed function GL pipeline */
3152         TRACE("Cannot change ptSize here in openGl\n");
3153         /* TODO: Implement this function in using shaders if they are available */
3154
3155     }
3156
3157     /* Vertex Pointers -----------------------------------------*/
3158     if (sd->u.s.position.lpData != NULL || sd->u.s.position.VBO != 0) {
3159         /* Note dwType == float3 or float4 == 2 or 3 */
3160         VTRACE(("glVertexPointer(%d, GL_FLOAT, %d, %p)\n",
3161                 sd->u.s.position.dwStride,
3162                 sd->u.s.position.dwType + 1,
3163                 sd->u.s.position.lpData));
3164
3165         if(curVBO != sd->u.s.position.VBO) {
3166             GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.position.VBO));
3167             checkGLcall("glBindBufferARB");
3168             curVBO = sd->u.s.position.VBO;
3169         }
3170
3171         /* min(WINED3D_ATR_SIZE(position),3) to Disable RHW mode as 'w' coord
3172            handling for rhw mode should not impact screen position whereas in GL it does.
3173            This may result in very slightly distorted textures in rhw mode.
3174            There's always the other option of fixing the view matrix to
3175            prevent w from having any effect.
3176
3177            This only applies to user pointer sources, in VBOs the vertices are fixed up
3178          */
3179         if(sd->u.s.position.VBO == 0) {
3180             glVertexPointer(3 /* min(WINED3D_ATR_SIZE(sd->u.s.position.dwType),3) */,
3181                 WINED3D_ATR_GLTYPE(sd->u.s.position.dwType),
3182                 sd->u.s.position.dwStride, sd->u.s.position.lpData + stateblock->loadBaseVertexIndex * sd->u.s.position.dwStride + offset[sd->u.s.position.streamNo]);
3183         } else {
3184             glVertexPointer(
3185                 WINED3D_ATR_SIZE(sd->u.s.position.dwType),
3186                 WINED3D_ATR_GLTYPE(sd->u.s.position.dwType),
3187                 sd->u.s.position.dwStride, sd->u.s.position.lpData + stateblock->loadBaseVertexIndex * sd->u.s.position.dwStride + offset[sd->u.s.position.streamNo]);
3188         }
3189         checkGLcall("glVertexPointer(...)");
3190         glEnableClientState(GL_VERTEX_ARRAY);
3191         checkGLcall("glEnableClientState(GL_VERTEX_ARRAY)");
3192     }
3193
3194     /* Normals -------------------------------------------------*/
3195     if (sd->u.s.normal.lpData || sd->u.s.normal.VBO) {
3196         /* Note dwType == float3 or float4 == 2 or 3 */
3197         VTRACE(("glNormalPointer(GL_FLOAT, %d, %p)\n",
3198                 sd->u.s.normal.dwStride,
3199                 sd->u.s.normal.lpData));
3200         if(curVBO != sd->u.s.normal.VBO) {
3201             GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.normal.VBO));
3202             checkGLcall("glBindBufferARB");
3203             curVBO = sd->u.s.normal.VBO;
3204         }
3205         glNormalPointer(
3206             WINED3D_ATR_GLTYPE(sd->u.s.normal.dwType),
3207             sd->u.s.normal.dwStride,
3208             sd->u.s.normal.lpData + stateblock->loadBaseVertexIndex * sd->u.s.normal.dwStride + offset[sd->u.s.normal.streamNo]);
3209         checkGLcall("glNormalPointer(...)");
3210         glEnableClientState(GL_NORMAL_ARRAY);
3211         checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)");
3212
3213     } else {
3214         glNormal3f(0, 0, 0);
3215         checkGLcall("glNormal3f(0, 0, 0)");
3216     }
3217
3218     /* Diffuse Colour --------------------------------------------*/
3219     /*  WARNING: Data here MUST be in RGBA format, so cannot      */
3220     /*     go directly into fast mode from app pgm, because       */
3221     /*     directx requires data in BGRA format.                  */
3222     /* currently fixupVertices swizzles the format, but this isn't*/
3223     /* very practical when using VBOs                             */
3224     /* NOTE: Unless we write a vertex shader to swizzle the colour*/
3225     /* , or the user doesn't care and wants the speed advantage   */
3226
3227     if (sd->u.s.diffuse.lpData || sd->u.s.diffuse.VBO) {
3228         /* Note dwType == float3 or float4 == 2 or 3 */
3229         VTRACE(("glColorPointer(4, GL_UNSIGNED_BYTE, %d, %p)\n",
3230                 sd->u.s.diffuse.dwStride,
3231                 sd->u.s.diffuse.lpData));
3232
3233         if(curVBO != sd->u.s.diffuse.VBO) {
3234             GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.diffuse.VBO));
3235             checkGLcall("glBindBufferARB");
3236             curVBO = sd->u.s.diffuse.VBO;
3237         }
3238
3239         glColorPointer(WINED3D_ATR_SIZE(sd->u.s.diffuse.dwType),
3240                        WINED3D_ATR_GLTYPE(sd->u.s.diffuse.dwType),
3241                        sd->u.s.diffuse.dwStride,
3242                        sd->u.s.diffuse.lpData + stateblock->loadBaseVertexIndex * sd->u.s.diffuse.dwStride + offset[sd->u.s.diffuse.streamNo]);
3243         checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)");
3244         glEnableClientState(GL_COLOR_ARRAY);
3245         checkGLcall("glEnableClientState(GL_COLOR_ARRAY)");
3246
3247     } else {
3248         glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
3249         checkGLcall("glColor4f(1, 1, 1, 1)");
3250     }
3251
3252     /* Specular Colour ------------------------------------------*/
3253     if (sd->u.s.specular.lpData || sd->u.s.specular.VBO) {
3254         TRACE("setting specular colour\n");
3255         /* Note dwType == float3 or float4 == 2 or 3 */
3256         VTRACE(("glSecondaryColorPointer(4, GL_UNSIGNED_BYTE, %d, %p)\n",
3257                 sd->u.s.specular.dwStride,
3258                 sd->u.s.specular.lpData));
3259         if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
3260             if(curVBO != sd->u.s.specular.VBO) {
3261                 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.specular.VBO));
3262                 checkGLcall("glBindBufferARB");
3263                 curVBO = sd->u.s.specular.VBO;
3264             }
3265             GL_EXTCALL(glSecondaryColorPointerEXT)(WINED3D_ATR_SIZE(sd->u.s.specular.dwType),
3266                                                    WINED3D_ATR_GLTYPE(sd->u.s.specular.dwType),
3267                                                    sd->u.s.specular.dwStride,
3268                                                    sd->u.s.specular.lpData + stateblock->loadBaseVertexIndex * sd->u.s.specular.dwStride + offset[sd->u.s.specular.streamNo]);
3269             vcheckGLcall("glSecondaryColorPointerEXT(4, GL_UNSIGNED_BYTE, ...)");
3270             glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
3271             vcheckGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
3272         } else {
3273
3274         /* Missing specular color is not critical, no warnings */
3275         VTRACE(("Specular colour is not supported in this GL implementation\n"));
3276         }
3277
3278     } else {
3279         if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
3280             GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0);
3281             checkGLcall("glSecondaryColor3fEXT(0, 0, 0)");
3282         } else {
3283
3284             /* Missing specular color is not critical, no warnings */
3285             VTRACE(("Specular colour is not supported in this GL implementation\n"));
3286         }
3287     }
3288
3289     /* Texture coords -------------------------------------------*/
3290     loadTexCoords(stateblock, sd, &curVBO);
3291 }
3292
3293 static inline void drawPrimitiveTraceDataLocations(
3294     WineDirect3DVertexStridedData *dataLocations) {
3295
3296     /* Dump out what parts we have supplied */
3297     TRACE("Strided Data:\n");
3298     TRACE_STRIDED((dataLocations), position);
3299     TRACE_STRIDED((dataLocations), blendWeights);
3300     TRACE_STRIDED((dataLocations), blendMatrixIndices);
3301     TRACE_STRIDED((dataLocations), normal);
3302     TRACE_STRIDED((dataLocations), pSize);
3303     TRACE_STRIDED((dataLocations), diffuse);
3304     TRACE_STRIDED((dataLocations), specular);
3305     TRACE_STRIDED((dataLocations), texCoords[0]);
3306     TRACE_STRIDED((dataLocations), texCoords[1]);
3307     TRACE_STRIDED((dataLocations), texCoords[2]);
3308     TRACE_STRIDED((dataLocations), texCoords[3]);
3309     TRACE_STRIDED((dataLocations), texCoords[4]);
3310     TRACE_STRIDED((dataLocations), texCoords[5]);
3311     TRACE_STRIDED((dataLocations), texCoords[6]);
3312     TRACE_STRIDED((dataLocations), texCoords[7]);
3313     TRACE_STRIDED((dataLocations), position2);
3314     TRACE_STRIDED((dataLocations), normal2);
3315     TRACE_STRIDED((dataLocations), tangent);
3316     TRACE_STRIDED((dataLocations), binormal);
3317     TRACE_STRIDED((dataLocations), tessFactor);
3318     TRACE_STRIDED((dataLocations), fog);
3319     TRACE_STRIDED((dataLocations), depth);
3320     TRACE_STRIDED((dataLocations), sample);
3321
3322     return;
3323 }
3324
3325 static void streamsrc(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
3326     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
3327     BOOL fixup = FALSE;
3328     WineDirect3DVertexStridedData *dataLocations = &device->strided_streams;
3329     BOOL useVertexShaderFunction;
3330
3331     if (device->vs_selected_mode != SHADER_NONE && stateblock->vertexShader &&
3332         ((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.function != NULL) {
3333         useVertexShaderFunction = TRUE;
3334     } else {
3335         useVertexShaderFunction = FALSE;
3336     }
3337
3338
3339     if(device->up_strided) {
3340         /* Note: this is a ddraw fixed-function code path */
3341         TRACE("================ Strided Input ===================\n");
3342         memcpy(dataLocations, device->up_strided, sizeof(*dataLocations));
3343
3344         if(TRACE_ON(d3d)) {
3345             drawPrimitiveTraceDataLocations(dataLocations);
3346         }
3347     } else {
3348         /* Note: This is a fixed function or shader codepath.
3349          * This means it must handle both types of strided data.
3350          * Shaders must go through here to zero the strided data, even if they
3351          * don't set any declaration at all
3352          */
3353         TRACE("================ Vertex Declaration  ===================\n");
3354         memset(dataLocations, 0, sizeof(*dataLocations));
3355         primitiveDeclarationConvertToStridedData((IWineD3DDevice *) device,
3356                 useVertexShaderFunction, dataLocations, &fixup);
3357     }
3358
3359     if (dataLocations->u.s.position_transformed) {
3360         useVertexShaderFunction = FALSE;
3361     }
3362
3363     /* Unload the old arrays before loading the new ones to get old junk out */
3364     if(context->numberedArraysLoaded) {
3365         unloadNumberedArrays(stateblock);
3366         context->numberedArraysLoaded = FALSE;
3367     }
3368     if(context->namedArraysLoaded) {
3369         unloadVertexData(stateblock);
3370         context->namedArraysLoaded = FALSE;
3371     }
3372
3373     if(useVertexShaderFunction) {
3374         if(((IWineD3DVertexDeclarationImpl *) stateblock->vertexDecl)->half_float_conv_needed && !fixup) {
3375             TRACE("Using drawStridedSlow with vertex shaders for FLOAT16 conversion\n");
3376             device->useDrawStridedSlow = TRUE;
3377             context->numberedArraysLoaded = FALSE;
3378         } else {
3379             TRACE("Loading numbered arrays\n");
3380             loadNumberedArrays(stateblock, dataLocations);
3381             device->useDrawStridedSlow = FALSE;
3382             context->numberedArraysLoaded = TRUE;
3383         }
3384     } else if (fixup ||
3385                (dataLocations->u.s.pSize.lpData == NULL &&
3386                 dataLocations->u.s.diffuse.lpData == NULL &&
3387                 dataLocations->u.s.specular.lpData == NULL)) {
3388         /* Load the vertex data using named arrays */
3389         TRACE("Loading vertex data\n");
3390         loadVertexData(stateblock, dataLocations);
3391         device->useDrawStridedSlow = FALSE;
3392         context->namedArraysLoaded = TRUE;
3393     } else {
3394         TRACE("Not loading vertex data\n");
3395         device->useDrawStridedSlow = TRUE;
3396     }
3397
3398 /* Generate some fixme's if unsupported functionality is being used */
3399 #define BUFFER_OR_DATA(_attribute) dataLocations->u.s._attribute.lpData
3400     /* TODO: Either support missing functionality in fixupVertices or by creating a shader to replace the pipeline. */
3401     if (!useVertexShaderFunction && (BUFFER_OR_DATA(position2) || BUFFER_OR_DATA(normal2))) {
3402         FIXME("Tweening is only valid with vertex shaders\n");
3403     }
3404     if (!useVertexShaderFunction && (BUFFER_OR_DATA(tangent) || BUFFER_OR_DATA(binormal))) {
3405         FIXME("Tangent and binormal bump mapping is only valid with vertex shaders\n");
3406     }
3407     if (!useVertexShaderFunction && (BUFFER_OR_DATA(tessFactor) || BUFFER_OR_DATA(fog) || BUFFER_OR_DATA(depth) || BUFFER_OR_DATA(sample))) {
3408         FIXME("Extended attributes are only valid with vertex shaders\n");
3409     }
3410 #undef BUFFER_OR_DATA
3411 }
3412
3413 static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
3414     BOOL useVertexShaderFunction = FALSE, updateFog = FALSE;
3415     BOOL usePixelShaderFunction = stateblock->wineD3DDevice->ps_selected_mode != SHADER_NONE && stateblock->pixelShader
3416             && ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.function;
3417     BOOL transformed;
3418     /* Some stuff is in the device until we have per context tracking */
3419     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
3420     BOOL wasrhw = context->last_was_rhw;
3421
3422     /* Shaders can be implemented using ARB_PROGRAM, GLSL, or software -
3423      * here simply check whether a shader was set, or the user disabled shaders
3424      */
3425     if (use_vs(device)) {
3426         useVertexShaderFunction = TRUE;
3427
3428         if(((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.reg_maps.fog != context->last_was_foggy_shader) {
3429             updateFog = TRUE;
3430         }
3431     } else if(context->last_was_foggy_shader) {
3432         updateFog = TRUE;
3433     }
3434
3435     transformed = device->strided_streams.u.s.position_transformed;
3436     if (transformed) useVertexShaderFunction = FALSE;
3437
3438     if(transformed != context->last_was_rhw && !useVertexShaderFunction) {
3439         updateFog = TRUE;
3440     }
3441
3442     /* Reapply lighting if it is not scheduled for reapplication already */
3443     if(!isStateDirty(context, STATE_RENDER(WINED3DRS_LIGHTING))) {
3444         state_lighting(STATE_RENDER(WINED3DRS_LIGHTING), stateblock, context);
3445     }
3446
3447     if (transformed) {
3448         context->last_was_rhw = TRUE;
3449     } else {
3450
3451         /* Untransformed, so relies on the view and projection matrices */
3452         context->last_was_rhw = FALSE;
3453         /* This turns off the Z scale trick to 'disable' viewport frustum clipping in rhw mode*/
3454         device->untransformed = TRUE;
3455
3456         /* Todo for sw shaders: Vertex Shader output is already transformed, so set up identity matrices
3457          * Not needed as long as only hw shaders are supported
3458          */
3459
3460         /* This sets the shader output position correction constants.
3461          * TODO: Move to the viewport state
3462          */
3463         if (useVertexShaderFunction) {
3464             device->posFixup[1] = device->render_offscreen ? -1.0 : 1.0;
3465             device->posFixup[3] = -device->posFixup[1] / stateblock->viewport.Height;
3466         }
3467     }
3468
3469     /* Don't have to apply the matrices when vertex shaders are used. When vshaders are turned
3470      * off this function will be called again anyway to make sure they're properly set
3471      */
3472     if(!useVertexShaderFunction) {
3473         /* TODO: Move this mainly to the viewport state and only apply when the vp has changed
3474          * or transformed / untransformed was switched
3475          */
3476        if(wasrhw != context->last_was_rhw &&
3477           !isStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION)) &&
3478           !isStateDirty(context, STATE_VIEWPORT)) {
3479             transform_projection(STATE_TRANSFORM(WINED3DTS_PROJECTION), stateblock, context);
3480         }
3481         /* World matrix needs reapplication here only if we're switching between rhw and non-rhw
3482          * mode.
3483          *
3484          * If a vertex shader is used, the world matrix changed and then vertex shader unbound
3485          * this check will fail and the matrix not applied again. This is OK because a simple
3486          * world matrix change reapplies the matrix - These checks here are only to satisfy the
3487          * needs of the vertex declaration.
3488          *
3489          * World and view matrix go into the same gl matrix, so only apply them when neither is
3490          * dirty
3491          */
3492         if(transformed != wasrhw &&
3493            !isStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0))) &&
3494            !isStateDirty(context, STATE_TRANSFORM(WINED3DTS_VIEW))) {
3495             transform_world(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), stateblock, context);
3496         }
3497
3498         if(!isStateDirty(context, STATE_RENDER(WINED3DRS_COLORVERTEX))) {
3499             state_colormat(STATE_RENDER(WINED3DRS_COLORVERTEX), stateblock, context);
3500         }
3501
3502         if(context->last_was_vshader && !isStateDirty(context, STATE_RENDER(WINED3DRS_CLIPPLANEENABLE))) {
3503             state_clipping(STATE_RENDER(WINED3DRS_CLIPPLANEENABLE), stateblock, context);
3504         }
3505         if(!isStateDirty(context, STATE_RENDER(WINED3DRS_NORMALIZENORMALS))) {
3506             state_normalize(STATE_RENDER(WINED3DRS_NORMALIZENORMALS), stateblock, context);
3507         }
3508     } else {
3509         /* We compile the shader here because we need the vertex declaration
3510          * in order to determine if we need to do any swizzling for D3DCOLOR
3511          * registers. If the shader is already compiled this call will do nothing. */
3512         IWineD3DVertexShader_CompileShader(stateblock->vertexShader);
3513
3514         if(!context->last_was_vshader) {
3515             int i;
3516             static BOOL warned = FALSE;
3517             /* Disable all clip planes to get defined results on all drivers. See comment in the
3518              * state_clipping state handler
3519              */
3520             for(i = 0; i < GL_LIMITS(clipplanes); i++) {
3521                 glDisable(GL_CLIP_PLANE0 + i);
3522                 checkGLcall("glDisable(GL_CLIP_PLANE0 + i)");
3523             }
3524
3525             if(!warned && stateblock->renderState[WINED3DRS_CLIPPLANEENABLE]) {
3526                 FIXME("Clipping not supported with vertex shaders\n");
3527                 warned = TRUE;
3528             }
3529             if(wasrhw) {
3530                 /* Apply the transform matrices when switching from rhw drawing to vertex shaders. Vertex
3531                  * shaders themselves do not need it, but the matrices are not reapplied automatically when
3532                  * switching back from vertex shaders to fixed function processing. So make sure we leave the
3533                  * fixed function vertex processing states back in a sane state before switching to shaders
3534                  */
3535                 if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION))) {
3536                     transform_projection(STATE_TRANSFORM(WINED3DTS_PROJECTION), stateblock, context);
3537                 }
3538                 if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)))) {
3539                     transform_world(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), stateblock, context);
3540                 }
3541             }
3542         }
3543     }
3544
3545     /* Vertex and pixel shaders are applied together for now, so let the last dirty state do the
3546      * application
3547      */
3548     if (!isStateDirty(context, STATE_PIXELSHADER)) {
3549         device->shader_backend->shader_select((IWineD3DDevice *)device, usePixelShaderFunction, useVertexShaderFunction);
3550
3551         if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && (useVertexShaderFunction || usePixelShaderFunction)) {
3552             shaderconstant(STATE_VERTEXSHADERCONSTANT, stateblock, context);
3553         }
3554     }
3555
3556     context->last_was_vshader = useVertexShaderFunction;
3557
3558     if(updateFog) {
3559         state_fog(STATE_RENDER(WINED3DRS_FOGENABLE), stateblock, context);
3560     }
3561     if(!useVertexShaderFunction) {
3562         int i;
3563         for(i = 0; i < MAX_TEXTURES; i++) {
3564             if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_TEXTURE0 + i))) {
3565                 transform_texture(STATE_TRANSFORM(WINED3DTS_TEXTURE0 + i), stateblock, context);
3566             }
3567         }
3568     }
3569 }
3570
3571 static void viewport_miscpart(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
3572     UINT width, height;
3573     IWineD3DSurfaceImpl *target;
3574
3575     glDepthRange(stateblock->viewport.MinZ, stateblock->viewport.MaxZ);
3576     checkGLcall("glDepthRange");
3577     /* Note: GL requires lower left, DirectX supplies upper left. This is reversed when using offscreen rendering
3578      */
3579     if(stateblock->wineD3DDevice->render_offscreen) {
3580         glViewport(stateblock->viewport.X,
3581                    stateblock->viewport.Y,
3582                    stateblock->viewport.Width, stateblock->viewport.Height);
3583     } else {
3584         target = (IWineD3DSurfaceImpl *) stateblock->wineD3DDevice->render_targets[0];
3585         target->get_drawable_size(target, &width, &height);
3586
3587         glViewport(stateblock->viewport.X,
3588                    (height - (stateblock->viewport.Y + stateblock->viewport.Height)),
3589                    stateblock->viewport.Width, stateblock->viewport.Height);
3590     }
3591
3592     checkGLcall("glViewport");
3593 }
3594
3595 static void viewport_vertexpart(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
3596     stateblock->wineD3DDevice->posFixup[2] = 1.0 / stateblock->viewport.Width;
3597     stateblock->wineD3DDevice->posFixup[3] = -stateblock->wineD3DDevice->posFixup[1] / stateblock->viewport.Height;
3598     if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION))) {
3599         transform_projection(STATE_TRANSFORM(WINED3DTS_PROJECTION), stateblock, context);
3600     }
3601     if(!isStateDirty(context, STATE_RENDER(WINED3DRS_POINTSCALEENABLE))) {
3602         state_pscale(STATE_RENDER(WINED3DRS_POINTSCALEENABLE), stateblock, context);
3603     }
3604 }
3605
3606 static void light(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
3607     UINT Index = state - STATE_ACTIVELIGHT(0);
3608     PLIGHTINFOEL *lightInfo = stateblock->activeLights[Index];
3609
3610     if(!lightInfo) {
3611         glDisable(GL_LIGHT0 + Index);
3612         checkGLcall("glDisable(GL_LIGHT0 + Index)");
3613     } else {
3614         float quad_att;
3615         float colRGBA[] = {0.0, 0.0, 0.0, 0.0};
3616
3617         /* Light settings are affected by the model view in OpenGL, the View transform in direct3d*/
3618         glMatrixMode(GL_MODELVIEW);
3619         glPushMatrix();
3620         glLoadMatrixf(&stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
3621
3622         /* Diffuse: */
3623         colRGBA[0] = lightInfo->OriginalParms.Diffuse.r;
3624         colRGBA[1] = lightInfo->OriginalParms.Diffuse.g;
3625         colRGBA[2] = lightInfo->OriginalParms.Diffuse.b;
3626         colRGBA[3] = lightInfo->OriginalParms.Diffuse.a;
3627         glLightfv(GL_LIGHT0 + Index, GL_DIFFUSE, colRGBA);
3628         checkGLcall("glLightfv");
3629
3630         /* Specular */
3631         colRGBA[0] = lightInfo->OriginalParms.Specular.r;
3632         colRGBA[1] = lightInfo->OriginalParms.Specular.g;
3633         colRGBA[2] = lightInfo->OriginalParms.Specular.b;
3634         colRGBA[3] = lightInfo->OriginalParms.Specular.a;
3635         glLightfv(GL_LIGHT0 + Index, GL_SPECULAR, colRGBA);
3636         checkGLcall("glLightfv");
3637
3638         /* Ambient */
3639         colRGBA[0] = lightInfo->OriginalParms.Ambient.r;
3640         colRGBA[1] = lightInfo->OriginalParms.Ambient.g;
3641         colRGBA[2] = lightInfo->OriginalParms.Ambient.b;
3642         colRGBA[3] = lightInfo->OriginalParms.Ambient.a;
3643         glLightfv(GL_LIGHT0 + Index, GL_AMBIENT, colRGBA);
3644         checkGLcall("glLightfv");
3645
3646         if ((lightInfo->OriginalParms.Range *lightInfo->OriginalParms.Range) >= FLT_MIN) {
3647             quad_att = 1.4/(lightInfo->OriginalParms.Range *lightInfo->OriginalParms.Range);
3648         } else {
3649             quad_att = 0; /*  0 or  MAX?  (0 seems to be ok) */
3650         }
3651
3652         /* Do not assign attenuation values for lights that do not use them. D3D apps are free to pass any junk,
3653          * but gl drivers use them and may crash due to bad Attenuation values. Need for Speed most wanted sets
3654          * Attenuation0 to NaN and crashes in the gl lib
3655          */
3656
3657         switch (lightInfo->OriginalParms.Type) {
3658             case WINED3DLIGHT_POINT:
3659                 /* Position */
3660                 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
3661                 checkGLcall("glLightfv");
3662                 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
3663                 checkGLcall("glLightf");
3664                 /* Attenuation - Are these right? guessing... */
3665                 glLightf(GL_LIGHT0 + Index, GL_CONSTANT_ATTENUATION,  lightInfo->OriginalParms.Attenuation0);
3666                 checkGLcall("glLightf");
3667                 glLightf(GL_LIGHT0 + Index, GL_LINEAR_ATTENUATION,    lightInfo->OriginalParms.Attenuation1);
3668                 checkGLcall("glLightf");
3669                 if (quad_att < lightInfo->OriginalParms.Attenuation2) quad_att = lightInfo->OriginalParms.Attenuation2;
3670                 glLightf(GL_LIGHT0 + Index, GL_QUADRATIC_ATTENUATION, quad_att);
3671                 checkGLcall("glLightf");
3672                 /* FIXME: Range */
3673                 break;
3674
3675             case WINED3DLIGHT_SPOT:
3676                 /* Position */
3677                 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
3678                 checkGLcall("glLightfv");
3679                 /* Direction */
3680                 glLightfv(GL_LIGHT0 + Index, GL_SPOT_DIRECTION, &lightInfo->lightDirn[0]);
3681                 checkGLcall("glLightfv");
3682                 glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, lightInfo->exponent);
3683                 checkGLcall("glLightf");
3684                 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
3685                 checkGLcall("glLightf");
3686                 /* Attenuation - Are these right? guessing... */
3687                 glLightf(GL_LIGHT0 + Index, GL_CONSTANT_ATTENUATION,  lightInfo->OriginalParms.Attenuation0);
3688                 checkGLcall("glLightf");
3689                 glLightf(GL_LIGHT0 + Index, GL_LINEAR_ATTENUATION,    lightInfo->OriginalParms.Attenuation1);
3690                 checkGLcall("glLightf");
3691                 if (quad_att < lightInfo->OriginalParms.Attenuation2) quad_att = lightInfo->OriginalParms.Attenuation2;
3692                 glLightf(GL_LIGHT0 + Index, GL_QUADRATIC_ATTENUATION, quad_att);
3693                 checkGLcall("glLightf");
3694                 /* FIXME: Range */
3695                 break;
3696
3697             case WINED3DLIGHT_DIRECTIONAL:
3698                 /* Direction */
3699                 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]); /* Note gl uses w position of 0 for direction! */
3700                 checkGLcall("glLightfv");
3701                 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
3702                 checkGLcall("glLightf");
3703                 glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, 0.0f);
3704                 checkGLcall("glLightf");
3705                 break;
3706
3707             default:
3708                 FIXME("Unrecognized light type %d\n", lightInfo->OriginalParms.Type);
3709         }
3710
3711         /* Restore the modelview matrix */
3712         glPopMatrix();
3713
3714         glEnable(GL_LIGHT0 + Index);
3715         checkGLcall("glEnable(GL_LIGHT0 + Index)");
3716     }
3717
3718     return;
3719 }
3720
3721 static void scissorrect(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
3722     RECT *pRect = &stateblock->scissorRect;
3723     UINT height;
3724     UINT width;
3725     IWineD3DSurfaceImpl *target = (IWineD3DSurfaceImpl *) stateblock->wineD3DDevice->render_targets[0];
3726
3727     target->get_drawable_size(target, &width, &height);
3728     /* Warning: glScissor uses window coordinates, not viewport coordinates, so our viewport correction does not apply
3729      * Warning2: Even in windowed mode the coords are relative to the window, not the screen
3730      */
3731     TRACE("(%p) Setting new Scissor Rect to %d:%d-%d:%d\n", stateblock->wineD3DDevice, pRect->left, pRect->bottom - height,
3732           pRect->right - pRect->left, pRect->bottom - pRect->top);
3733
3734     if (stateblock->wineD3DDevice->render_offscreen) {
3735         glScissor(pRect->left, pRect->top, pRect->right - pRect->left, pRect->bottom - pRect->top);
3736     } else {
3737         glScissor(pRect->left, height - pRect->bottom, pRect->right - pRect->left, pRect->bottom - pRect->top);
3738     }
3739     checkGLcall("glScissor");
3740 }
3741
3742 static void indexbuffer(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
3743     if(GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT)) {
3744         if(stateblock->streamIsUP || stateblock->pIndexData == NULL ) {
3745             GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0));
3746         } else {
3747             IWineD3DIndexBufferImpl *ib = (IWineD3DIndexBufferImpl *) stateblock->pIndexData;
3748             GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, ib->vbo));
3749         }
3750     }
3751 }
3752
3753 static void frontface(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
3754     if(stateblock->wineD3DDevice->render_offscreen) {
3755         glFrontFace(GL_CCW);
3756         checkGLcall("glFrontFace(GL_CCW)");
3757     } else {
3758         glFrontFace(GL_CW);
3759         checkGLcall("glFrontFace(GL_CW)");
3760     }
3761 }
3762
3763 const struct StateEntryTemplate misc_state_template[] = {
3764     { STATE_RENDER(WINED3DRS_SRCBLEND),                   { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         }},
3765     { STATE_RENDER(WINED3DRS_DESTBLEND),                  { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         }},
3766     { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         }},
3767     { STATE_RENDER(WINED3DRS_EDGEANTIALIAS),              { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         }},
3768     { STATE_RENDER(WINED3DRS_ANTIALIASEDLINEENABLE),      { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         }},
3769     { STATE_RENDER(WINED3DRS_SEPARATEALPHABLENDENABLE),   { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         }},
3770     { STATE_RENDER(WINED3DRS_SRCBLENDALPHA),              { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         }},
3771     { STATE_RENDER(WINED3DRS_DESTBLENDALPHA),             { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         }},
3772     { STATE_RENDER(WINED3DRS_DESTBLENDALPHA),             { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         }},
3773     { STATE_RENDER(WINED3DRS_BLENDOPALPHA),               { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         }},
3774     { STATE_STREAMSRC,                                    { STATE_VDECL,                                        streamsrc           }},
3775     { STATE_VDECL,                                        { STATE_VDECL,                                        streamsrc           }},
3776     { STATE_FRONTFACE,                                    { STATE_FRONTFACE,                                    frontface           }},
3777     { STATE_SCISSORRECT,                                  { STATE_SCISSORRECT,                                  scissorrect         }},
3778     /* TODO: Move shader constant loading to vertex and fragment pipeline repectively, as soon as the pshader and
3779      * vshader loadings are untied from each other
3780      */
3781     { STATE_VERTEXSHADERCONSTANT,                         { STATE_VERTEXSHADERCONSTANT,                         shaderconstant      }},
3782     { STATE_PIXELSHADERCONSTANT,                          { STATE_VERTEXSHADERCONSTANT,                         shaderconstant      }},
3783     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }},
3784     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }},
3785     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }},
3786     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }},
3787     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }},
3788     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }},
3789     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }},
3790     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }},
3791     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }},
3792     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }},
3793     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }},
3794     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }},
3795     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }},
3796     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }},
3797     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }},
3798     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }},
3799     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }},
3800     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }},
3801     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }},
3802     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }},
3803     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }},
3804     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }},
3805     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }},
3806     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }},
3807     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }},
3808     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }},
3809     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }},
3810     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }},
3811     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }},
3812     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }},
3813     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }},
3814     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   }},
3815     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE),    { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   }},
3816     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLOFFSET),   { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLOFFSET),   tex_bumpenvloffset  }},
3817     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE),    { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   }},
3818     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLOFFSET),   { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLOFFSET),   tex_bumpenvloffset  }},
3819     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE),    { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   }},
3820     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLOFFSET),   { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLOFFSET),   tex_bumpenvloffset  }},
3821     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE),    { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   }},
3822     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLOFFSET),   { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLOFFSET),   tex_bumpenvloffset  }},
3823     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE),    { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   }},
3824     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLOFFSET),   { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLOFFSET),   tex_bumpenvloffset  }},
3825     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE),    { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   }},
3826     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLOFFSET),   { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLOFFSET),   tex_bumpenvloffset  }},
3827     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE),    { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   }},
3828     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLOFFSET),   { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLOFFSET),   tex_bumpenvloffset  }},
3829     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE),    { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   }},
3830     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLOFFSET),   { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLOFFSET),   tex_bumpenvloffset  }},
3831
3832     { STATE_VIEWPORT,                                     { STATE_VIEWPORT,                                     viewport_miscpart   }},
3833     { STATE_INDEXBUFFER,                                  { STATE_INDEXBUFFER,                                  indexbuffer         }},
3834     { STATE_RENDER(WINED3DRS_ANTIALIAS),                  { STATE_RENDER(WINED3DRS_ANTIALIAS),                  state_antialias     }},
3835     { STATE_RENDER(WINED3DRS_TEXTUREPERSPECTIVE),         { STATE_RENDER(WINED3DRS_TEXTUREPERSPECTIVE),         state_perspective   }},
3836     { STATE_RENDER(WINED3DRS_ZENABLE),                    { STATE_RENDER(WINED3DRS_ZENABLE),                    state_zenable       }},
3837     { STATE_RENDER(WINED3DRS_WRAPU),                      { STATE_RENDER(WINED3DRS_WRAPU),                      state_wrapu         }},
3838     { STATE_RENDER(WINED3DRS_WRAPV),                      { STATE_RENDER(WINED3DRS_WRAPV),                      state_wrapv         }},
3839     { STATE_RENDER(WINED3DRS_FILLMODE),                   { STATE_RENDER(WINED3DRS_FILLMODE),                   state_fillmode      }},
3840     { STATE_RENDER(WINED3DRS_SHADEMODE),                  { STATE_RENDER(WINED3DRS_SHADEMODE),                  state_shademode     }},
3841     { STATE_RENDER(WINED3DRS_LINEPATTERN),                { STATE_RENDER(WINED3DRS_LINEPATTERN),                state_linepattern   }},
3842     { STATE_RENDER(WINED3DRS_MONOENABLE),                 { STATE_RENDER(WINED3DRS_MONOENABLE),                 state_monoenable    }},
3843     { STATE_RENDER(WINED3DRS_ROP2),                       { STATE_RENDER(WINED3DRS_ROP2),                       state_rop2          }},
3844     { STATE_RENDER(WINED3DRS_PLANEMASK),                  { STATE_RENDER(WINED3DRS_PLANEMASK),                  state_planemask     }},
3845     { STATE_RENDER(WINED3DRS_ZWRITEENABLE),               { STATE_RENDER(WINED3DRS_ZWRITEENABLE),               state_zwritenable   }},
3846     { STATE_RENDER(WINED3DRS_ALPHATESTENABLE),            { STATE_RENDER(WINED3DRS_ALPHATESTENABLE),            state_alpha         }},
3847     { STATE_RENDER(WINED3DRS_ALPHAREF),                   { STATE_RENDER(WINED3DRS_ALPHATESTENABLE),            state_alpha         }},
3848     { STATE_RENDER(WINED3DRS_ALPHAFUNC),                  { STATE_RENDER(WINED3DRS_ALPHATESTENABLE),            state_alpha         }},
3849     { STATE_RENDER(WINED3DRS_COLORKEYENABLE),             { STATE_RENDER(WINED3DRS_ALPHATESTENABLE),            state_alpha         }},
3850     { STATE_RENDER(WINED3DRS_LASTPIXEL),                  { STATE_RENDER(WINED3DRS_LASTPIXEL),                  state_lastpixel     }},
3851     { STATE_RENDER(WINED3DRS_CULLMODE),                   { STATE_RENDER(WINED3DRS_CULLMODE),                   state_cullmode      }},
3852     { STATE_RENDER(WINED3DRS_ZFUNC),                      { STATE_RENDER(WINED3DRS_ZFUNC),                      state_zfunc         }},
3853     { STATE_RENDER(WINED3DRS_DITHERENABLE),               { STATE_RENDER(WINED3DRS_DITHERENABLE),               state_ditherenable  }},
3854     { STATE_RENDER(WINED3DRS_SUBPIXEL),                   { STATE_RENDER(WINED3DRS_SUBPIXEL),                   state_subpixel      }},
3855     { STATE_RENDER(WINED3DRS_SUBPIXELX),                  { STATE_RENDER(WINED3DRS_SUBPIXELX),                  state_subpixelx     }},
3856     { STATE_RENDER(WINED3DRS_STIPPLEDALPHA),              { STATE_RENDER(WINED3DRS_STIPPLEDALPHA),              state_stippledalpha }},
3857     { STATE_RENDER(WINED3DRS_ZBIAS),                      { STATE_RENDER(WINED3DRS_ZBIAS),                      state_zbias         }},
3858     { STATE_RENDER(WINED3DRS_STIPPLEENABLE),              { STATE_RENDER(WINED3DRS_STIPPLEENABLE),              state_stippleenable }},
3859     { STATE_RENDER(WINED3DRS_MIPMAPLODBIAS),              { STATE_RENDER(WINED3DRS_MIPMAPLODBIAS),              state_mipmaplodbias }},
3860     { STATE_RENDER(WINED3DRS_ANISOTROPY),                 { STATE_RENDER(WINED3DRS_ANISOTROPY),                 state_anisotropy    }},
3861     { STATE_RENDER(WINED3DRS_FLUSHBATCH),                 { STATE_RENDER(WINED3DRS_FLUSHBATCH),                 state_flushbatch    }},
3862     { STATE_RENDER(WINED3DRS_TRANSLUCENTSORTINDEPENDENT), { STATE_RENDER(WINED3DRS_TRANSLUCENTSORTINDEPENDENT), state_translucentsi }},
3863     { STATE_RENDER(WINED3DRS_STENCILENABLE),              { STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       }},
3864     { STATE_RENDER(WINED3DRS_STENCILFAIL),                { STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       }},
3865     { STATE_RENDER(WINED3DRS_STENCILZFAIL),               { STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       }},
3866     { STATE_RENDER(WINED3DRS_STENCILPASS),                { STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       }},
3867     { STATE_RENDER(WINED3DRS_STENCILFUNC),                { STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       }},
3868     { STATE_RENDER(WINED3DRS_STENCILREF),                 { STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       }},
3869     { STATE_RENDER(WINED3DRS_STENCILMASK),                { STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       }},
3870     { STATE_RENDER(WINED3DRS_STENCILWRITEMASK),           { STATE_RENDER(WINED3DRS_STENCILWRITEMASK),           state_stencilwrite  }},
3871     { STATE_RENDER(WINED3DRS_TWOSIDEDSTENCILMODE),        { STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       }},
3872     { STATE_RENDER(WINED3DRS_CCW_STENCILFAIL),            { STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       }},
3873     { STATE_RENDER(WINED3DRS_CCW_STENCILZFAIL),           { STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       }},
3874     { STATE_RENDER(WINED3DRS_CCW_STENCILPASS),            { STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       }},
3875     { STATE_RENDER(WINED3DRS_CCW_STENCILFUNC),            { STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       }},
3876     { STATE_RENDER(WINED3DRS_WRAP0),                      { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }},
3877     { STATE_RENDER(WINED3DRS_WRAP1),                      { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }},
3878     { STATE_RENDER(WINED3DRS_WRAP2),                      { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }},
3879     { STATE_RENDER(WINED3DRS_WRAP3),                      { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }},
3880     { STATE_RENDER(WINED3DRS_WRAP4),                      { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }},
3881     { STATE_RENDER(WINED3DRS_WRAP5),                      { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }},
3882     { STATE_RENDER(WINED3DRS_WRAP6),                      { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }},
3883     { STATE_RENDER(WINED3DRS_WRAP7),                      { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }},
3884     { STATE_RENDER(WINED3DRS_WRAP8),                      { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }},
3885     { STATE_RENDER(WINED3DRS_WRAP9),                      { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }},
3886     { STATE_RENDER(WINED3DRS_WRAP10),                     { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }},
3887     { STATE_RENDER(WINED3DRS_WRAP11),                     { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }},
3888     { STATE_RENDER(WINED3DRS_WRAP12),                     { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }},
3889     { STATE_RENDER(WINED3DRS_WRAP13),                     { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }},
3890     { STATE_RENDER(WINED3DRS_WRAP14),                     { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }},
3891     { STATE_RENDER(WINED3DRS_WRAP15),                     { STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          }},
3892     { STATE_RENDER(WINED3DRS_EXTENTS),                    { STATE_RENDER(WINED3DRS_EXTENTS),                    state_extents       }},
3893     { STATE_RENDER(WINED3DRS_COLORKEYBLENDENABLE),        { STATE_RENDER(WINED3DRS_COLORKEYBLENDENABLE),        state_ckeyblend     }},
3894     { STATE_RENDER(WINED3DRS_PATCHEDGESTYLE),             { STATE_RENDER(WINED3DRS_PATCHEDGESTYLE),             state_patchedgestyle}},
3895     { STATE_RENDER(WINED3DRS_PATCHSEGMENTS),              { STATE_RENDER(WINED3DRS_PATCHSEGMENTS),              state_patchsegments }},
3896     { STATE_RENDER(WINED3DRS_POSITIONDEGREE),             { STATE_RENDER(WINED3DRS_POSITIONDEGREE),             state_positiondegree}},
3897     { STATE_RENDER(WINED3DRS_NORMALDEGREE),               { STATE_RENDER(WINED3DRS_NORMALDEGREE),               state_normaldegree  }},
3898     { STATE_RENDER(WINED3DRS_MINTESSELLATIONLEVEL),       { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation  }},
3899     { STATE_RENDER(WINED3DRS_MAXTESSELLATIONLEVEL),       { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation  }},
3900     { STATE_RENDER(WINED3DRS_ADAPTIVETESS_X),             { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation  }},
3901     { STATE_RENDER(WINED3DRS_ADAPTIVETESS_Y),             { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation  }},
3902     { STATE_RENDER(WINED3DRS_ADAPTIVETESS_Z),             { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation  }},
3903     { STATE_RENDER(WINED3DRS_ADAPTIVETESS_W),             { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation  }},
3904     { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation  }},
3905     { STATE_RENDER(WINED3DRS_MULTISAMPLEANTIALIAS),       { STATE_RENDER(WINED3DRS_MULTISAMPLEANTIALIAS),       state_multisampleaa }},
3906     { STATE_RENDER(WINED3DRS_MULTISAMPLEMASK),            { STATE_RENDER(WINED3DRS_MULTISAMPLEMASK),            state_multisampmask }},
3907     { STATE_RENDER(WINED3DRS_COLORWRITEENABLE),           { STATE_RENDER(WINED3DRS_COLORWRITEENABLE),           state_colorwrite    }},
3908     { STATE_RENDER(WINED3DRS_BLENDOP),                    { STATE_RENDER(WINED3DRS_BLENDOP),                    state_blendop       }},
3909     { STATE_RENDER(WINED3DRS_SCISSORTESTENABLE),          { STATE_RENDER(WINED3DRS_SCISSORTESTENABLE),          state_scissor       }},
3910     { STATE_RENDER(WINED3DRS_SLOPESCALEDEPTHBIAS),        { STATE_RENDER(WINED3DRS_DEPTHBIAS),                  state_depthbias     }},
3911     { STATE_RENDER(WINED3DRS_COLORWRITEENABLE1),          { STATE_RENDER(WINED3DRS_COLORWRITEENABLE),           state_colorwrite    }},
3912     { STATE_RENDER(WINED3DRS_COLORWRITEENABLE2),          { STATE_RENDER(WINED3DRS_COLORWRITEENABLE),           state_colorwrite    }},
3913     { STATE_RENDER(WINED3DRS_COLORWRITEENABLE3),          { STATE_RENDER(WINED3DRS_COLORWRITEENABLE),           state_colorwrite    }},
3914     { STATE_RENDER(WINED3DRS_BLENDFACTOR),                { STATE_RENDER(WINED3DRS_BLENDFACTOR),                state_blendfactor   }},
3915     { STATE_RENDER(WINED3DRS_DEPTHBIAS),                  { STATE_RENDER(WINED3DRS_DEPTHBIAS),                  state_depthbias     }},
3916     /* Samplers */
3917     { STATE_SAMPLER(0),                                   { STATE_SAMPLER(0),                                   sampler             }},
3918     { STATE_SAMPLER(1),                                   { STATE_SAMPLER(1),                                   sampler             }},
3919     { STATE_SAMPLER(2),                                   { STATE_SAMPLER(2),                                   sampler             }},
3920     { STATE_SAMPLER(3),                                   { STATE_SAMPLER(3),                                   sampler             }},
3921     { STATE_SAMPLER(4),                                   { STATE_SAMPLER(4),                                   sampler             }},
3922     { STATE_SAMPLER(5),                                   { STATE_SAMPLER(5),                                   sampler             }},
3923     { STATE_SAMPLER(6),                                   { STATE_SAMPLER(6),                                   sampler             }},
3924     { STATE_SAMPLER(7),                                   { STATE_SAMPLER(7),                                   sampler             }},
3925     { STATE_SAMPLER(8),                                   { STATE_SAMPLER(8),                                   sampler             }},
3926     { STATE_SAMPLER(9),                                   { STATE_SAMPLER(9),                                   sampler             }},
3927     { STATE_SAMPLER(10),                                  { STATE_SAMPLER(10),                                  sampler             }},
3928     { STATE_SAMPLER(11),                                  { STATE_SAMPLER(11),                                  sampler             }},
3929     { STATE_SAMPLER(12),                                  { STATE_SAMPLER(12),                                  sampler             }},
3930     { STATE_SAMPLER(13),                                  { STATE_SAMPLER(13),                                  sampler             }},
3931     { STATE_SAMPLER(14),                                  { STATE_SAMPLER(14),                                  sampler             }},
3932     { STATE_SAMPLER(15),                                  { STATE_SAMPLER(15),                                  sampler             }},
3933     { STATE_SAMPLER(16), /* Vertex sampler 0 */           { STATE_SAMPLER(16),                                  sampler             }},
3934     { STATE_SAMPLER(17), /* Vertex sampler 1 */           { STATE_SAMPLER(17),                                  sampler             }},
3935     { STATE_SAMPLER(18), /* Vertex sampler 2 */           { STATE_SAMPLER(18),                                  sampler             }},
3936     { STATE_SAMPLER(19), /* Vertex sampler 3 */           { STATE_SAMPLER(19),                                  sampler             }},
3937     {0 /* Terminate */,                                   { 0,                                                  0                   }},
3938 };
3939
3940 const struct StateEntryTemplate ffp_vertexstate_template[] = {
3941     { STATE_VDECL,                                        { STATE_VDECL,                                        vertexdeclaration   }},
3942     { STATE_VSHADER,                                      { STATE_VDECL,                                        vertexdeclaration   }},
3943     { STATE_MATERIAL,                                     { STATE_RENDER(WINED3DRS_SPECULARENABLE),             state_specularenable}},
3944     { STATE_RENDER(WINED3DRS_SPECULARENABLE),             { STATE_RENDER(WINED3DRS_SPECULARENABLE),             state_specularenable}},
3945       /* Clip planes */
3946     { STATE_CLIPPLANE(0),                                 { STATE_CLIPPLANE(0),                                 clipplane           }},
3947     { STATE_CLIPPLANE(1),                                 { STATE_CLIPPLANE(1),                                 clipplane           }},
3948     { STATE_CLIPPLANE(2),                                 { STATE_CLIPPLANE(2),                                 clipplane           }},
3949     { STATE_CLIPPLANE(3),                                 { STATE_CLIPPLANE(3),                                 clipplane           }},
3950     { STATE_CLIPPLANE(4),                                 { STATE_CLIPPLANE(4),                                 clipplane           }},
3951     { STATE_CLIPPLANE(5),                                 { STATE_CLIPPLANE(5),                                 clipplane           }},
3952     { STATE_CLIPPLANE(6),                                 { STATE_CLIPPLANE(6),                                 clipplane           }},
3953     { STATE_CLIPPLANE(7),                                 { STATE_CLIPPLANE(7),                                 clipplane           }},
3954     { STATE_CLIPPLANE(8),                                 { STATE_CLIPPLANE(8),                                 clipplane           }},
3955     { STATE_CLIPPLANE(9),                                 { STATE_CLIPPLANE(9),                                 clipplane           }},
3956     { STATE_CLIPPLANE(10),                                { STATE_CLIPPLANE(10),                                clipplane           }},
3957     { STATE_CLIPPLANE(11),                                { STATE_CLIPPLANE(11),                                clipplane           }},
3958     { STATE_CLIPPLANE(12),                                { STATE_CLIPPLANE(12),                                clipplane           }},
3959     { STATE_CLIPPLANE(13),                                { STATE_CLIPPLANE(13),                                clipplane           }},
3960     { STATE_CLIPPLANE(14),                                { STATE_CLIPPLANE(14),                                clipplane           }},
3961     { STATE_CLIPPLANE(15),                                { STATE_CLIPPLANE(15),                                clipplane           }},
3962     { STATE_CLIPPLANE(16),                                { STATE_CLIPPLANE(16),                                clipplane           }},
3963     { STATE_CLIPPLANE(17),                                { STATE_CLIPPLANE(17),                                clipplane           }},
3964     { STATE_CLIPPLANE(18),                                { STATE_CLIPPLANE(18),                                clipplane           }},
3965     { STATE_CLIPPLANE(19),                                { STATE_CLIPPLANE(19),                                clipplane           }},
3966     { STATE_CLIPPLANE(20),                                { STATE_CLIPPLANE(20),                                clipplane           }},
3967     { STATE_CLIPPLANE(21),                                { STATE_CLIPPLANE(21),                                clipplane           }},
3968     { STATE_CLIPPLANE(22),                                { STATE_CLIPPLANE(22),                                clipplane           }},
3969     { STATE_CLIPPLANE(23),                                { STATE_CLIPPLANE(23),                                clipplane           }},
3970     { STATE_CLIPPLANE(24),                                { STATE_CLIPPLANE(24),                                clipplane           }},
3971     { STATE_CLIPPLANE(25),                                { STATE_CLIPPLANE(25),                                clipplane           }},
3972     { STATE_CLIPPLANE(26),                                { STATE_CLIPPLANE(26),                                clipplane           }},
3973     { STATE_CLIPPLANE(27),                                { STATE_CLIPPLANE(27),                                clipplane           }},
3974     { STATE_CLIPPLANE(28),                                { STATE_CLIPPLANE(28),                                clipplane           }},
3975     { STATE_CLIPPLANE(29),                                { STATE_CLIPPLANE(29),                                clipplane           }},
3976     { STATE_CLIPPLANE(30),                                { STATE_CLIPPLANE(30),                                clipplane           }},
3977     { STATE_CLIPPLANE(31),                                { STATE_CLIPPLANE(31),                                clipplane           }},
3978       /* Lights */
3979     { STATE_ACTIVELIGHT(0),                               { STATE_ACTIVELIGHT(0),                               light               }},
3980     { STATE_ACTIVELIGHT(1),                               { STATE_ACTIVELIGHT(1),                               light               }},
3981     { STATE_ACTIVELIGHT(2),                               { STATE_ACTIVELIGHT(2),                               light               }},
3982     { STATE_ACTIVELIGHT(3),                               { STATE_ACTIVELIGHT(3),                               light               }},
3983     { STATE_ACTIVELIGHT(4),                               { STATE_ACTIVELIGHT(4),                               light               }},
3984     { STATE_ACTIVELIGHT(5),                               { STATE_ACTIVELIGHT(5),                               light               }},
3985     { STATE_ACTIVELIGHT(6),                               { STATE_ACTIVELIGHT(6),                               light               }},
3986     { STATE_ACTIVELIGHT(7),                               { STATE_ACTIVELIGHT(7),                               light               }},
3987     /* Viewport */
3988     { STATE_VIEWPORT,                                     { STATE_VIEWPORT,                                     viewport_vertexpart }},
3989       /* Transform states follow                    */
3990     { STATE_TRANSFORM(WINED3DTS_VIEW),                    { STATE_TRANSFORM(WINED3DTS_VIEW),                    transform_view      }},
3991     { STATE_TRANSFORM(WINED3DTS_PROJECTION),              { STATE_TRANSFORM(WINED3DTS_PROJECTION),              transform_projection}},
3992     { STATE_TRANSFORM(WINED3DTS_TEXTURE0),                { STATE_TRANSFORM(WINED3DTS_TEXTURE0),                transform_texture   }},
3993     { STATE_TRANSFORM(WINED3DTS_TEXTURE1),                { STATE_TRANSFORM(WINED3DTS_TEXTURE1),                transform_texture   }},
3994     { STATE_TRANSFORM(WINED3DTS_TEXTURE2),                { STATE_TRANSFORM(WINED3DTS_TEXTURE2),                transform_texture   }},
3995     { STATE_TRANSFORM(WINED3DTS_TEXTURE3),                { STATE_TRANSFORM(WINED3DTS_TEXTURE3),                transform_texture   }},
3996     { STATE_TRANSFORM(WINED3DTS_TEXTURE4),                { STATE_TRANSFORM(WINED3DTS_TEXTURE4),                transform_texture   }},
3997     { STATE_TRANSFORM(WINED3DTS_TEXTURE5),                { STATE_TRANSFORM(WINED3DTS_TEXTURE5),                transform_texture   }},
3998     { STATE_TRANSFORM(WINED3DTS_TEXTURE6),                { STATE_TRANSFORM(WINED3DTS_TEXTURE6),                transform_texture   }},
3999     { STATE_TRANSFORM(WINED3DTS_TEXTURE7),                { STATE_TRANSFORM(WINED3DTS_TEXTURE7),                transform_texture   }},
4000     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  0)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  0)),        transform_world     }},
4001     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  1)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  1)),        transform_world     }},
4002     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  2)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  2)),        transform_world     }},
4003     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  3)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  3)),        transform_world     }},
4004     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  4)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  4)),        transform_world     }},
4005     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  5)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  5)),        transform_world     }},
4006     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  6)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  6)),        transform_world     }},
4007     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  7)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  7)),        transform_world     }},
4008     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  8)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  8)),        transform_world     }},
4009     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  9)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(  9)),        transform_world     }},
4010     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 10)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 10)),        transform_world     }},
4011     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 11)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 11)),        transform_world     }},
4012     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 12)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 12)),        transform_world     }},
4013     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 13)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 13)),        transform_world     }},
4014     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 14)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 14)),        transform_world     }},
4015     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 15)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 15)),        transform_world     }},
4016     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 16)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 16)),        transform_world     }},
4017     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 17)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 17)),        transform_world     }},
4018     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 18)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 18)),        transform_world     }},
4019     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 19)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 19)),        transform_world     }},
4020     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 20)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 20)),        transform_world     }},
4021     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 21)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 21)),        transform_world     }},
4022     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 22)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 22)),        transform_world     }},
4023     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 23)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 23)),        transform_world     }},
4024     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 24)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 24)),        transform_world     }},
4025     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 25)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 25)),        transform_world     }},
4026     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 26)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 26)),        transform_world     }},
4027     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 27)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 27)),        transform_world     }},
4028     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 28)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 28)),        transform_world     }},
4029     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 29)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 29)),        transform_world     }},
4030     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 30)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 30)),        transform_world     }},
4031     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 31)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 31)),        transform_world     }},
4032     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 32)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 32)),        transform_world     }},
4033     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 33)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 33)),        transform_world     }},
4034     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 34)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 34)),        transform_world     }},
4035     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 35)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 35)),        transform_world     }},
4036     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 36)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 36)),        transform_world     }},
4037     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 37)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 37)),        transform_world     }},
4038     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 38)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 38)),        transform_world     }},
4039     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 39)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 39)),        transform_world     }},
4040     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 40)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 40)),        transform_world     }},
4041     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 41)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 41)),        transform_world     }},
4042     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 42)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 42)),        transform_world     }},
4043     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 43)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 43)),        transform_world     }},
4044     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 44)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 44)),        transform_world     }},
4045     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 45)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 45)),        transform_world     }},
4046     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 46)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 46)),        transform_world     }},
4047     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 47)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 47)),        transform_world     }},
4048     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 48)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 48)),        transform_world     }},
4049     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 49)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 49)),        transform_world     }},
4050     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 50)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 50)),        transform_world     }},
4051     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 51)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 51)),        transform_world     }},
4052     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 52)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 52)),        transform_world     }},
4053     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 53)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 53)),        transform_world     }},
4054     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 54)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 54)),        transform_world     }},
4055     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 55)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 55)),        transform_world     }},
4056     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 56)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 56)),        transform_world     }},
4057     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 57)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 57)),        transform_world     }},
4058     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 58)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 58)),        transform_world     }},
4059     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 59)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 59)),        transform_world     }},
4060     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 60)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 60)),        transform_world     }},
4061     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 61)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 61)),        transform_world     }},
4062     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 62)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 62)),        transform_world     }},
4063     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 63)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 63)),        transform_world     }},
4064     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 64)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 64)),        transform_world     }},
4065     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 65)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 65)),        transform_world     }},
4066     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 66)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 66)),        transform_world     }},
4067     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 67)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 67)),        transform_world     }},
4068     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 68)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 68)),        transform_world     }},
4069     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 69)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 69)),        transform_world     }},
4070     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 70)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 70)),        transform_world     }},
4071     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 71)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 71)),        transform_world     }},
4072     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 72)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 72)),        transform_world     }},
4073     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 73)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 73)),        transform_world     }},
4074     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 74)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 74)),        transform_world     }},
4075     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 75)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 75)),        transform_world     }},
4076     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 76)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 76)),        transform_world     }},
4077     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 77)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 77)),        transform_world     }},
4078     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 78)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 78)),        transform_world     }},
4079     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 79)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 79)),        transform_world     }},
4080     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 80)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 80)),        transform_world     }},
4081     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 81)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 81)),        transform_world     }},
4082     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 82)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 82)),        transform_world     }},
4083     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 83)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 83)),        transform_world     }},
4084     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 84)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 84)),        transform_world     }},
4085     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 85)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 85)),        transform_world     }},
4086     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 86)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 86)),        transform_world     }},
4087     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 87)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 87)),        transform_world     }},
4088     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 88)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 88)),        transform_world     }},
4089     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 89)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 89)),        transform_world     }},
4090     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 90)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 90)),        transform_world     }},
4091     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 91)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 91)),        transform_world     }},
4092     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 92)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 92)),        transform_world     }},
4093     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 93)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 93)),        transform_world     }},
4094     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 94)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 94)),        transform_world     }},
4095     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 95)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 95)),        transform_world     }},
4096     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 96)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 96)),        transform_world     }},
4097     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 97)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 97)),        transform_world     }},
4098     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 98)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 98)),        transform_world     }},
4099     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 99)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 99)),        transform_world     }},
4100     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(100)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(100)),        transform_world     }},
4101     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(101)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(101)),        transform_world     }},
4102     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(102)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(102)),        transform_world     }},
4103     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(103)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(103)),        transform_world     }},
4104     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(104)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(104)),        transform_world     }},
4105     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(105)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(105)),        transform_world     }},
4106     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(106)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(106)),        transform_world     }},
4107     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(107)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(107)),        transform_world     }},
4108     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(108)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(108)),        transform_world     }},
4109     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(109)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(109)),        transform_world     }},
4110     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(110)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(110)),        transform_world     }},
4111     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(111)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(111)),        transform_world     }},
4112     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(112)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(112)),        transform_world     }},
4113     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(113)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(113)),        transform_world     }},
4114     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(114)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(114)),        transform_world     }},
4115     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(115)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(115)),        transform_world     }},
4116     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(116)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(116)),        transform_world     }},
4117     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(117)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(117)),        transform_world     }},
4118     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(118)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(118)),        transform_world     }},
4119     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(119)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(119)),        transform_world     }},
4120     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(120)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(120)),        transform_world     }},
4121     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(121)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(121)),        transform_world     }},
4122     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(122)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(122)),        transform_world     }},
4123     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(123)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(123)),        transform_world     }},
4124     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(124)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(124)),        transform_world     }},
4125     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(125)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(125)),        transform_world     }},
4126     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(126)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(126)),        transform_world     }},
4127     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(127)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(127)),        transform_world     }},
4128     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(128)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(128)),        transform_world     }},
4129     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(129)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(129)),        transform_world     }},
4130     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(130)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(130)),        transform_world     }},
4131     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(131)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(131)),        transform_world     }},
4132     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(132)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(132)),        transform_world     }},
4133     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(133)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(133)),        transform_world     }},
4134     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(134)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(134)),        transform_world     }},
4135     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(135)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(135)),        transform_world     }},
4136     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(136)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(136)),        transform_world     }},
4137     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(137)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(137)),        transform_world     }},
4138     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(138)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(138)),        transform_world     }},
4139     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(139)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(139)),        transform_world     }},
4140     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(140)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(140)),        transform_world     }},
4141     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(141)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(141)),        transform_world     }},
4142     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(142)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(142)),        transform_world     }},
4143     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(143)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(143)),        transform_world     }},
4144     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(144)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(144)),        transform_world     }},
4145     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(145)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(145)),        transform_world     }},
4146     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(146)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(146)),        transform_world     }},
4147     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(147)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(147)),        transform_world     }},
4148     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(148)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(148)),        transform_world     }},
4149     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(149)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(149)),        transform_world     }},
4150     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(150)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(150)),        transform_world     }},
4151     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(151)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(151)),        transform_world     }},
4152     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(152)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(152)),        transform_world     }},
4153     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(153)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(153)),        transform_world     }},
4154     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(154)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(154)),        transform_world     }},
4155     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(155)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(155)),        transform_world     }},
4156     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(156)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(156)),        transform_world     }},
4157     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(157)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(157)),        transform_world     }},
4158     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(158)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(158)),        transform_world     }},
4159     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(159)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(159)),        transform_world     }},
4160     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(160)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(160)),        transform_world     }},
4161     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(161)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(161)),        transform_world     }},
4162     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(162)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(162)),        transform_world     }},
4163     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(163)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(163)),        transform_world     }},
4164     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(164)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(164)),        transform_world     }},
4165     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(165)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(165)),        transform_world     }},
4166     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(166)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(166)),        transform_world     }},
4167     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(167)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(167)),        transform_world     }},
4168     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(168)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(168)),        transform_world     }},
4169     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(169)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(169)),        transform_world     }},
4170     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(170)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(170)),        transform_world     }},
4171     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(171)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(171)),        transform_world     }},
4172     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(172)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(172)),        transform_world     }},
4173     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(173)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(173)),        transform_world     }},
4174     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(174)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(174)),        transform_world     }},
4175     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(175)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(175)),        transform_world     }},
4176     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(176)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(176)),        transform_world     }},
4177     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(177)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(177)),        transform_world     }},
4178     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(178)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(178)),        transform_world     }},
4179     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(179)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(179)),        transform_world     }},
4180     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(180)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(180)),        transform_world     }},
4181     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(181)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(181)),        transform_world     }},
4182     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(182)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(182)),        transform_world     }},
4183     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(183)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(183)),        transform_world     }},
4184     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(184)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(184)),        transform_world     }},
4185     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(185)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(185)),        transform_world     }},
4186     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(186)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(186)),        transform_world     }},
4187     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(187)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(187)),        transform_world     }},
4188     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(188)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(188)),        transform_world     }},
4189     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(189)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(189)),        transform_world     }},
4190     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(190)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(190)),        transform_world     }},
4191     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(191)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(191)),        transform_world     }},
4192     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(192)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(192)),        transform_world     }},
4193     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(193)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(193)),        transform_world     }},
4194     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(194)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(194)),        transform_world     }},
4195     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(195)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(195)),        transform_world     }},
4196     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(196)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(196)),        transform_world     }},
4197     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(197)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(197)),        transform_world     }},
4198     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(198)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(198)),        transform_world     }},
4199     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(199)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(199)),        transform_world     }},
4200     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(200)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(200)),        transform_world     }},
4201     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(201)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(201)),        transform_world     }},
4202     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(202)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(202)),        transform_world     }},
4203     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(203)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(203)),        transform_world     }},
4204     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(204)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(204)),        transform_world     }},
4205     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(205)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(205)),        transform_world     }},
4206     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(206)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(206)),        transform_world     }},
4207     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(207)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(207)),        transform_world     }},
4208     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(208)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(208)),        transform_world     }},
4209     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(209)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(209)),        transform_world     }},
4210     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(210)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(210)),        transform_world     }},
4211     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(211)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(211)),        transform_world     }},
4212     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(212)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(212)),        transform_world     }},
4213     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(213)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(213)),        transform_world     }},
4214     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(214)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(214)),        transform_world     }},
4215     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(215)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(215)),        transform_world     }},
4216     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(216)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(216)),        transform_world     }},
4217     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(217)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(217)),        transform_world     }},
4218     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(218)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(218)),        transform_world     }},
4219     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(219)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(219)),        transform_world     }},
4220     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(220)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(220)),        transform_world     }},
4221     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(221)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(221)),        transform_world     }},
4222     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(222)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(222)),        transform_world     }},
4223     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(223)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(223)),        transform_world     }},
4224     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(224)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(224)),        transform_world     }},
4225     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(225)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(225)),        transform_world     }},
4226     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(226)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(226)),        transform_world     }},
4227     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(227)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(227)),        transform_world     }},
4228     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(228)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(228)),        transform_world     }},
4229     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(229)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(229)),        transform_world     }},
4230     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(230)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(230)),        transform_world     }},
4231     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(231)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(231)),        transform_world     }},
4232     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(232)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(232)),        transform_world     }},
4233     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(233)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(233)),        transform_world     }},
4234     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(234)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(234)),        transform_world     }},
4235     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(235)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(235)),        transform_world     }},
4236     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(236)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(236)),        transform_world     }},
4237     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(237)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(237)),        transform_world     }},
4238     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(238)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(238)),        transform_world     }},
4239     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(239)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(239)),        transform_world     }},
4240     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(240)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(240)),        transform_world     }},
4241     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(241)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(241)),        transform_world     }},
4242     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(242)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(242)),        transform_world     }},
4243     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(243)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(243)),        transform_world     }},
4244     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(244)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(244)),        transform_world     }},
4245     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(245)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(245)),        transform_world     }},
4246     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(246)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(246)),        transform_world     }},
4247     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(247)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(247)),        transform_world     }},
4248     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(248)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(248)),        transform_world     }},
4249     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(249)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(249)),        transform_world     }},
4250     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(250)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(250)),        transform_world     }},
4251     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(251)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(251)),        transform_world     }},
4252     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(252)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(252)),        transform_world     }},
4253     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(253)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(253)),        transform_world     }},
4254     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(254)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(254)),        transform_world     }},
4255     { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(255)),        { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(255)),        transform_world     }},
4256     { STATE_TEXTURESTAGE(0,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TRANSFORM(WINED3DTS_TEXTURE0),              transform_texture   }},
4257     { STATE_TEXTURESTAGE(1,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TRANSFORM(WINED3DTS_TEXTURE1),              transform_texture   }},
4258     { STATE_TEXTURESTAGE(2,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TRANSFORM(WINED3DTS_TEXTURE2),              transform_texture   }},
4259     { STATE_TEXTURESTAGE(3,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TRANSFORM(WINED3DTS_TEXTURE3),              transform_texture   }},
4260     { STATE_TEXTURESTAGE(4,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TRANSFORM(WINED3DTS_TEXTURE4),              transform_texture   }},
4261     { STATE_TEXTURESTAGE(5,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TRANSFORM(WINED3DTS_TEXTURE5),              transform_texture   }},
4262     { STATE_TEXTURESTAGE(6,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TRANSFORM(WINED3DTS_TEXTURE6),              transform_texture   }},
4263     { STATE_TEXTURESTAGE(7,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TRANSFORM(WINED3DTS_TEXTURE7),              transform_texture   }},
4264     { STATE_TEXTURESTAGE(0, WINED3DTSS_TEXCOORDINDEX),    { STATE_TEXTURESTAGE(0, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      }},
4265     { STATE_TEXTURESTAGE(1, WINED3DTSS_TEXCOORDINDEX),    { STATE_TEXTURESTAGE(1, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      }},
4266     { STATE_TEXTURESTAGE(2, WINED3DTSS_TEXCOORDINDEX),    { STATE_TEXTURESTAGE(2, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      }},
4267     { STATE_TEXTURESTAGE(3, WINED3DTSS_TEXCOORDINDEX),    { STATE_TEXTURESTAGE(3, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      }},
4268     { STATE_TEXTURESTAGE(4, WINED3DTSS_TEXCOORDINDEX),    { STATE_TEXTURESTAGE(4, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      }},
4269     { STATE_TEXTURESTAGE(5, WINED3DTSS_TEXCOORDINDEX),    { STATE_TEXTURESTAGE(5, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      }},
4270     { STATE_TEXTURESTAGE(6, WINED3DTSS_TEXCOORDINDEX),    { STATE_TEXTURESTAGE(6, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      }},
4271     { STATE_TEXTURESTAGE(7, WINED3DTSS_TEXCOORDINDEX),    { STATE_TEXTURESTAGE(7, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      }},
4272       /* Fog */
4273     { STATE_RENDER(WINED3DRS_FOGENABLE),                  { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog           }},
4274     { STATE_RENDER(WINED3DRS_FOGTABLEMODE),               { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog           }},
4275     { STATE_RENDER(WINED3DRS_FOGSTART),                   { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog           }},
4276     { STATE_RENDER(WINED3DRS_FOGEND),                     { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog           }},
4277     { STATE_RENDER(WINED3DRS_FOGVERTEXMODE),              { STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog           }},
4278     { STATE_RENDER(WINED3DRS_FOGCOLOR),                   { STATE_RENDER(WINED3DRS_FOGCOLOR),                   state_fogcolor      }},
4279     { STATE_RENDER(WINED3DRS_FOGDENSITY),                 { STATE_RENDER(WINED3DRS_FOGDENSITY),                 state_fogdensity    }},
4280     { STATE_RENDER(WINED3DRS_RANGEFOGENABLE),             { STATE_RENDER(WINED3DRS_RANGEFOGENABLE),             state_rangefog      }},
4281     { STATE_RENDER(WINED3DRS_CLIPPING),                   { STATE_RENDER(WINED3DRS_CLIPPING),                   state_clipping      }},
4282     { STATE_RENDER(WINED3DRS_CLIPPLANEENABLE),            { STATE_RENDER(WINED3DRS_CLIPPING),                   state_clipping      }},
4283     { STATE_RENDER(WINED3DRS_LIGHTING),                   { STATE_RENDER(WINED3DRS_LIGHTING),                   state_lighting      }},
4284     { STATE_RENDER(WINED3DRS_AMBIENT),                    { STATE_RENDER(WINED3DRS_AMBIENT),                    state_ambient       }},
4285     { STATE_RENDER(WINED3DRS_COLORVERTEX),                { STATE_RENDER(WINED3DRS_COLORVERTEX),                state_colormat      }},
4286     { STATE_RENDER(WINED3DRS_LOCALVIEWER),                { STATE_RENDER(WINED3DRS_LOCALVIEWER),                state_localviewer   }},
4287     { STATE_RENDER(WINED3DRS_NORMALIZENORMALS),           { STATE_RENDER(WINED3DRS_NORMALIZENORMALS),           state_normalize     }},
4288     { STATE_RENDER(WINED3DRS_DIFFUSEMATERIALSOURCE),      { STATE_RENDER(WINED3DRS_COLORVERTEX),                state_colormat      }},
4289     { STATE_RENDER(WINED3DRS_SPECULARMATERIALSOURCE),     { STATE_RENDER(WINED3DRS_COLORVERTEX),                state_colormat      }},
4290     { STATE_RENDER(WINED3DRS_AMBIENTMATERIALSOURCE),      { STATE_RENDER(WINED3DRS_COLORVERTEX),                state_colormat      }},
4291     { STATE_RENDER(WINED3DRS_EMISSIVEMATERIALSOURCE),     { STATE_RENDER(WINED3DRS_COLORVERTEX),                state_colormat      }},
4292     { STATE_RENDER(WINED3DRS_VERTEXBLEND),                { STATE_RENDER(WINED3DRS_VERTEXBLEND),                state_vertexblend   }},
4293     { STATE_RENDER(WINED3DRS_POINTSIZE),                  { STATE_RENDER(WINED3DRS_POINTSCALEENABLE),           state_pscale        }},
4294     { STATE_RENDER(WINED3DRS_POINTSIZE_MIN),              { STATE_RENDER(WINED3DRS_POINTSIZE_MIN),              state_psizemin      }},
4295     { STATE_RENDER(WINED3DRS_POINTSPRITEENABLE),          { STATE_RENDER(WINED3DRS_POINTSPRITEENABLE),          state_pointsprite   }},
4296     { STATE_RENDER(WINED3DRS_POINTSCALEENABLE),           { STATE_RENDER(WINED3DRS_POINTSCALEENABLE),           state_pscale        }},
4297     { STATE_RENDER(WINED3DRS_POINTSCALE_A),               { STATE_RENDER(WINED3DRS_POINTSCALEENABLE),           state_pscale        }},
4298     { STATE_RENDER(WINED3DRS_POINTSCALE_B),               { STATE_RENDER(WINED3DRS_POINTSCALEENABLE),           state_pscale        }},
4299     { STATE_RENDER(WINED3DRS_POINTSCALE_C),               { STATE_RENDER(WINED3DRS_POINTSCALEENABLE),           state_pscale        }},
4300     { STATE_RENDER(WINED3DRS_POINTSIZE_MAX),              { STATE_RENDER(WINED3DRS_POINTSIZE_MAX),              state_psizemax      }},
4301     /* Samplers for NP2 texture matrix adjustions */
4302     { STATE_SAMPLER(0),                                   { STATE_SAMPLER(0),                                   sampler_texmatrix   }},
4303     { STATE_SAMPLER(1),                                   { STATE_SAMPLER(1),                                   sampler_texmatrix   }},
4304     { STATE_SAMPLER(2),                                   { STATE_SAMPLER(2),                                   sampler_texmatrix   }},
4305     { STATE_SAMPLER(3),                                   { STATE_SAMPLER(3),                                   sampler_texmatrix   }},
4306     { STATE_SAMPLER(4),                                   { STATE_SAMPLER(4),                                   sampler_texmatrix   }},
4307     { STATE_SAMPLER(5),                                   { STATE_SAMPLER(5),                                   sampler_texmatrix   }},
4308     { STATE_SAMPLER(6),                                   { STATE_SAMPLER(6),                                   sampler_texmatrix   }},
4309     { STATE_SAMPLER(7),                                   { STATE_SAMPLER(7),                                   sampler_texmatrix   }},
4310     {0 /* Terminate */,                                   { 0,                                                  0                   }},
4311 };
4312
4313 static const struct StateEntryTemplate ffp_fragmentstate_template[] = {
4314     { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          tex_colorop         }},
4315     { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG1),        { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          tex_colorop         }},
4316     { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG2),        { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          tex_colorop         }},
4317     { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP),          { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP),          tex_alphaop         }},
4318     { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG1),        { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP),          tex_alphaop         }},
4319     { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG2),        { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP),          tex_alphaop         }},
4320     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }},
4321     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }},
4322     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }},
4323     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }},
4324     { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG0),        { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          tex_colorop         }},
4325     { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG0),        { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP),          tex_alphaop         }},
4326     { STATE_TEXTURESTAGE(0, WINED3DTSS_RESULTARG),        { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          tex_colorop         }},
4327     { STATE_TEXTURESTAGE(0, WINED3DTSS_CONSTANT),         { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl          }},
4328     { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP),          { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP),          tex_colorop         }},
4329     { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG1),        { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP),          tex_colorop         }},
4330     { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG2),        { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP),          tex_colorop         }},
4331     { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP),          { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP),          tex_alphaop         }},
4332     { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG1),        { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP),          tex_alphaop         }},
4333     { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG2),        { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP),          tex_alphaop         }},
4334     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }},
4335     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }},
4336     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }},
4337     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }},
4338     { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG0),        { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP),          tex_colorop         }},
4339     { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG0),        { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP),          tex_alphaop         }},
4340     { STATE_TEXTURESTAGE(1, WINED3DTSS_RESULTARG),        { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP),          tex_colorop         }},
4341     { STATE_TEXTURESTAGE(1, WINED3DTSS_CONSTANT),         { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl          }},
4342     { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP),          { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP),          tex_colorop         }},
4343     { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG1),        { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP),          tex_colorop         }},
4344     { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG2),        { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP),          tex_colorop         }},
4345     { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP),          { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP),          tex_alphaop         }},
4346     { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG1),        { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP),          tex_alphaop         }},
4347     { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG2),        { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP),          tex_alphaop         }},
4348     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }},
4349     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }},
4350     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }},
4351     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }},
4352     { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG0),        { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP),          tex_colorop         }},
4353     { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG0),        { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP),          tex_alphaop         }},
4354     { STATE_TEXTURESTAGE(2, WINED3DTSS_RESULTARG),        { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP),          tex_colorop         }},
4355     { STATE_TEXTURESTAGE(2, WINED3DTSS_CONSTANT),         { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl          }},
4356     { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP),          { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP),          tex_colorop         }},
4357     { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG1),        { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP),          tex_colorop         }},
4358     { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG2),        { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP),          tex_colorop         }},
4359     { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP),          { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP),          tex_alphaop         }},
4360     { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG1),        { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP),          tex_alphaop         }},
4361     { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG2),        { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP),          tex_alphaop         }},
4362     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }},
4363     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }},
4364     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }},
4365     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }},
4366     { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG0),        { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP),          tex_colorop         }},
4367     { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG0),        { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP),          tex_alphaop         }},
4368     { STATE_TEXTURESTAGE(3, WINED3DTSS_RESULTARG),        { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP),          tex_colorop         }},
4369     { STATE_TEXTURESTAGE(3, WINED3DTSS_CONSTANT),         { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl          }},
4370     { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP),          { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP),          tex_colorop         }},
4371     { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG1),        { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP),          tex_colorop         }},
4372     { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG2),        { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP),          tex_colorop         }},
4373     { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP),          { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP),          tex_alphaop         }},
4374     { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG1),        { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP),          tex_alphaop         }},
4375     { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG2),        { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP),          tex_alphaop         }},
4376     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }},
4377     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }},
4378     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }},
4379     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }},
4380     { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG0),        { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP),          tex_colorop         }},
4381     { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG0),        { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP),          tex_alphaop         }},
4382     { STATE_TEXTURESTAGE(4, WINED3DTSS_RESULTARG),        { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP),          tex_colorop         }},
4383     { STATE_TEXTURESTAGE(4, WINED3DTSS_CONSTANT),         { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl          }},
4384     { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP),          { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP),          tex_colorop         }},
4385     { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG1),        { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP),          tex_colorop         }},
4386     { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG2),        { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP),          tex_colorop         }},
4387     { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP),          { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP),          tex_alphaop         }},
4388     { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG1),        { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP),          tex_alphaop         }},
4389     { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG2),        { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP),          tex_alphaop         }},
4390     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }},
4391     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }},
4392     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }},
4393     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }},
4394     { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG0),        { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP),          tex_colorop         }},
4395     { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG0),        { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP),          tex_alphaop         }},
4396     { STATE_TEXTURESTAGE(5, WINED3DTSS_RESULTARG),        { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP),          tex_colorop         }},
4397     { STATE_TEXTURESTAGE(5, WINED3DTSS_CONSTANT),         { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl          }},
4398     { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP),          { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP),          tex_colorop         }},
4399     { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG1),        { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP),          tex_colorop         }},
4400     { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG2),        { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP),          tex_colorop         }},
4401     { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP),          { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP),          tex_alphaop         }},
4402     { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG1),        { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP),          tex_alphaop         }},
4403     { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG2),        { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP),          tex_alphaop         }},
4404     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }},
4405     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }},
4406     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }},
4407     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }},
4408     { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG0),        { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP),          tex_colorop         }},
4409     { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG0),        { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP),          tex_alphaop         }},
4410     { STATE_TEXTURESTAGE(6, WINED3DTSS_RESULTARG),        { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP),          tex_colorop         }},
4411     { STATE_TEXTURESTAGE(6, WINED3DTSS_CONSTANT),         { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl          }},
4412     { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP),          { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP),          tex_colorop         }},
4413     { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG1),        { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP),          tex_colorop         }},
4414     { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG2),        { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP),          tex_colorop         }},
4415     { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP),          { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP),          tex_alphaop         }},
4416     { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG1),        { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP),          tex_alphaop         }},
4417     { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG2),        { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP),          tex_alphaop         }},
4418     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }},
4419     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT01),     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }},
4420     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT10),     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }},
4421     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT11),     { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      }},
4422     { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG0),        { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP),          tex_colorop         }},
4423     { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG0),        { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP),          tex_alphaop         }},
4424     { STATE_TEXTURESTAGE(7, WINED3DTSS_RESULTARG),        { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP),          tex_colorop         }},
4425     { STATE_TEXTURESTAGE(7, WINED3DTSS_CONSTANT),         { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl          }},
4426     { STATE_PIXELSHADER,                                  { STATE_PIXELSHADER,                                  apply_pixelshader   }},
4427     { STATE_RENDER(WINED3DRS_SRGBWRITEENABLE),            { STATE_PIXELSHADER,                                  apply_pixelshader   }},
4428     { STATE_RENDER(WINED3DRS_BORDERCOLOR),                { STATE_RENDER(WINED3DRS_BORDERCOLOR),                state_bordercolor   }},
4429     { STATE_RENDER(WINED3DRS_TEXTUREFACTOR),              { STATE_RENDER(WINED3DRS_TEXTUREFACTOR),              state_texfactor     }},
4430     { STATE_SAMPLER(0),                                   { STATE_SAMPLER(0),                                   sampler_texdim      }},
4431     { STATE_SAMPLER(1),                                   { STATE_SAMPLER(1),                                   sampler_texdim      }},
4432     { STATE_SAMPLER(2),                                   { STATE_SAMPLER(2),                                   sampler_texdim      }},
4433     { STATE_SAMPLER(3),                                   { STATE_SAMPLER(3),                                   sampler_texdim      }},
4434     { STATE_SAMPLER(4),                                   { STATE_SAMPLER(4),                                   sampler_texdim      }},
4435     { STATE_SAMPLER(5),                                   { STATE_SAMPLER(5),                                   sampler_texdim      }},
4436     { STATE_SAMPLER(6),                                   { STATE_SAMPLER(6),                                   sampler_texdim      }},
4437     { STATE_SAMPLER(7),                                   { STATE_SAMPLER(7),                                   sampler_texdim      }},
4438     {0 /* Terminate */,                                   { 0,                                                  0                   }},
4439 };
4440 #undef GLINFO_LOCATION
4441
4442 #define GLINFO_LOCATION (*gl_info)
4443 static void ffp_enable(IWineD3DDevice *iface, BOOL enable) { }
4444
4445 static void ffp_fragment_get_caps(WINED3DDEVTYPE devtype, WineD3D_GL_Info *gl_info, struct fragment_caps *pCaps) {
4446     pCaps->TextureOpCaps =  WINED3DTEXOPCAPS_ADD         |
4447                             WINED3DTEXOPCAPS_ADDSIGNED   |
4448                             WINED3DTEXOPCAPS_ADDSIGNED2X |
4449                             WINED3DTEXOPCAPS_MODULATE    |
4450                             WINED3DTEXOPCAPS_MODULATE2X  |
4451                             WINED3DTEXOPCAPS_MODULATE4X  |
4452                             WINED3DTEXOPCAPS_SELECTARG1  |
4453                             WINED3DTEXOPCAPS_SELECTARG2  |
4454                             WINED3DTEXOPCAPS_DISABLE;
4455
4456     if (GL_SUPPORT(ARB_TEXTURE_ENV_COMBINE) ||
4457         GL_SUPPORT(EXT_TEXTURE_ENV_COMBINE) ||
4458         GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
4459         pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_BLENDDIFFUSEALPHA  |
4460                                 WINED3DTEXOPCAPS_BLENDTEXTUREALPHA  |
4461                                 WINED3DTEXOPCAPS_BLENDFACTORALPHA   |
4462                                 WINED3DTEXOPCAPS_BLENDCURRENTALPHA  |
4463                                 WINED3DTEXOPCAPS_LERP               |
4464                                 WINED3DTEXOPCAPS_SUBTRACT;
4465     }
4466     if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3) ||
4467         GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
4468         pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_ADDSMOOTH              |
4469                                 WINED3DTEXOPCAPS_MULTIPLYADD            |
4470                                 WINED3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR |
4471                                 WINED3DTEXOPCAPS_MODULATECOLOR_ADDALPHA |
4472                                 WINED3DTEXOPCAPS_BLENDTEXTUREALPHAPM;
4473     }
4474     if (GL_SUPPORT(ARB_TEXTURE_ENV_DOT3))
4475         pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_DOTPRODUCT3;
4476
4477     if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
4478         pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_BUMPENVMAP;
4479     }
4480
4481     pCaps->MaxTextureBlendStages   = GL_LIMITS(texture_stages);
4482     pCaps->MaxSimultaneousTextures = GL_LIMITS(textures);
4483 }
4484
4485 static HRESULT ffp_fragment_alloc(IWineD3DDevice *iface) { return WINED3D_OK; }
4486 static void ffp_fragment_free(IWineD3DDevice *iface) {}
4487
4488 #undef GLINFO_LOCATION
4489
4490 const struct fragment_pipeline ffp_fragment_pipeline = {
4491     ffp_enable,
4492     ffp_fragment_get_caps,
4493     ffp_fragment_alloc,
4494     ffp_fragment_free,
4495     ffp_fragmentstate_template
4496 };
4497
4498 static int num_handlers(APPLYSTATEFUNC *funcs) {
4499     unsigned int i;
4500     for(i = 0; funcs[i]; i++);
4501     return i;
4502 }
4503
4504 static void multistate_apply_2(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
4505     stateblock->wineD3DDevice->multistate_funcs[state][0](state, stateblock, context);
4506     stateblock->wineD3DDevice->multistate_funcs[state][1](state, stateblock, context);
4507 }
4508
4509 static void multistate_apply_3(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
4510     stateblock->wineD3DDevice->multistate_funcs[state][0](state, stateblock, context);
4511     stateblock->wineD3DDevice->multistate_funcs[state][1](state, stateblock, context);
4512     stateblock->wineD3DDevice->multistate_funcs[state][2](state, stateblock, context);
4513 }
4514
4515 void compile_state_table(struct StateEntry *StateTable,
4516                          APPLYSTATEFUNC **dev_multistate_funcs,
4517                          const struct StateEntryTemplate *vertex,
4518                          const struct fragment_pipeline *fragment,
4519                          const struct StateEntryTemplate *misc) {
4520     unsigned int i, type, handlers;
4521     APPLYSTATEFUNC multistate_funcs[STATE_HIGHEST + 1][3];
4522     const struct StateEntryTemplate *cur;
4523
4524     memset(multistate_funcs, 0, sizeof(multistate_funcs));
4525
4526     for(i = 0; i < STATE_HIGHEST + 1; i++) {
4527         StateTable[i].representative = 0;
4528         StateTable[i].apply = state_undefined;
4529     }
4530
4531     for(type = 0; type < 3; type++) {
4532         /* This switch decides the order in which the states are applied */
4533         switch(type) {
4534             case 0: cur = misc; break;
4535             case 1: cur = fragment->states; break;
4536             case 2: cur = vertex; break;
4537             default: cur = NULL; /* Stupid compiler */
4538         }
4539         if(!cur) continue;
4540
4541         for(i = 0; cur[i].state; i++) {
4542             handlers = num_handlers(multistate_funcs[cur[i].state]);
4543             multistate_funcs[cur[i].state][handlers] = cur[i].content.apply;
4544             switch(handlers) {
4545                 case 0:
4546                     StateTable[cur[i].state].apply = cur[i].content.apply;
4547                     break;
4548                 case 1:
4549                     StateTable[cur[i].state].apply = multistate_apply_2;
4550                     dev_multistate_funcs[cur[i].state] = HeapAlloc(GetProcessHeap(),
4551                                                                    0,
4552                                                                    sizeof(**dev_multistate_funcs) * 2);
4553                     dev_multistate_funcs[cur[i].state][0] = multistate_funcs[cur[i].state][0];
4554                     dev_multistate_funcs[cur[i].state][1] = multistate_funcs[cur[i].state][1];
4555                     break;
4556                 case 2:
4557                     StateTable[cur[i].state].apply = multistate_apply_3;
4558                     HeapFree(GetProcessHeap(), 0, multistate_funcs[cur[i].state]);
4559                     dev_multistate_funcs[cur[i].state] = HeapAlloc(GetProcessHeap(),
4560                                                                    0,
4561                                                                    sizeof(**dev_multistate_funcs) * 3);
4562                     dev_multistate_funcs[cur[i].state][0] = multistate_funcs[cur[i].state][0];
4563                     dev_multistate_funcs[cur[i].state][1] = multistate_funcs[cur[i].state][1];
4564                     dev_multistate_funcs[cur[i].state][2] = multistate_funcs[cur[i].state][2];
4565                     break;
4566                 default:
4567                     ERR("Unexpected amount of state handlers for state %u: %u\n",
4568                         cur[i].state, handlers + 1);
4569             }
4570
4571             if(StateTable[cur[i].state].representative &&
4572             StateTable[cur[i].state].representative != cur[i].content.representative) {
4573                 FIXME("State %u has different representatives in different pipeline parts\n",
4574                     cur[i].state);
4575             }
4576             StateTable[cur[i].state].representative = cur[i].content.representative;
4577         }
4578     }
4579 }