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