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