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