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