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