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