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