wintrust: Use a helper function to get a signer's cert info from a message.
[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-2007 Stefan Dösinger for CodeWeavers
11  *
12  * This library is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU Lesser General Public
14  * License as published by the Free Software Foundation; either
15  * version 2.1 of the License, or (at your option) any later version.
16  *
17  * This library is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20  * Lesser General Public License for more details.
21  *
22  * You should have received a copy of the GNU Lesser General Public
23  * License along with this library; if not, write to the Free Software
24  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25  */
26
27 #include "config.h"
28 #include <stdio.h>
29 #ifdef HAVE_FLOAT_H
30 # include <float.h>
31 #endif
32 #include "wined3d_private.h"
33
34 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
35 WINE_DECLARE_DEBUG_CHANNEL(d3d_shader);
36
37 #define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
38
39 static void state_nogl(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
40     /* Used for states which are not mapped to a gl state as-is, but used somehow different,
41      * e.g as a parameter for drawing, or which are unimplemented in windows d3d
42      */
43     if(STATE_IS_RENDER(state)) {
44         WINED3DRENDERSTATETYPE RenderState = state - STATE_RENDER(0);
45         TRACE("(%s,%d) no direct mapping to gl\n", debug_d3drenderstate(RenderState), stateblock->renderState[RenderState]);
46     } else {
47         /* Shouldn't have an unknown type here */
48         FIXME("%d no direct mapping to gl of state with unknown type\n", state);
49     }
50 }
51
52 static void state_undefined(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
53     /* Print a WARN, this allows the stateblock code to loop over all states to generate a display
54      * list without causing confusing terminal output. Deliberately no special debug name here
55      * because its undefined.
56      */
57     WARN("undefined state %d\n", state);
58 }
59
60 static void state_fillmode(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
61     WINED3DFILLMODE Value = stateblock->renderState[WINED3DRS_FILLMODE];
62
63     switch(Value) {
64         case WINED3DFILL_POINT:
65             glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
66             checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_POINT)");
67             break;
68         case WINED3DFILL_WIREFRAME:
69             glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
70             checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)");
71             break;
72         case WINED3DFILL_SOLID:
73             glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
74             checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)");
75             break;
76         default:
77             FIXME("Unrecognized WINED3DRS_FILLMODE value %d\n", Value);
78     }
79 }
80
81 static void state_lighting(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
82     BOOL transformed;
83
84     /* Lighting is not enabled if transformed vertices are drawn
85      * but lighting does not affect the stream sources, so it is not grouped for performance reasons.
86      * This state reads the decoded vertex decl, so if it is dirty don't do anything. The
87      * vertex declaration appplying function calls this function for updating
88      */
89
90     if(isStateDirty(context, STATE_VDECL)) {
91         return;
92     }
93
94     transformed = ((stateblock->wineD3DDevice->strided_streams.u.s.position.lpData != NULL ||
95                     stateblock->wineD3DDevice->strided_streams.u.s.position.VBO != 0) &&
96                     stateblock->wineD3DDevice->strided_streams.u.s.position_transformed) ? TRUE : FALSE;
97
98     if (stateblock->renderState[WINED3DRS_LIGHTING] && !transformed) {
99         glEnable(GL_LIGHTING);
100         checkGLcall("glEnable GL_LIGHTING");
101     } else {
102         glDisable(GL_LIGHTING);
103         checkGLcall("glDisable GL_LIGHTING");
104     }
105 }
106
107 static void state_zenable(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
108     /* No z test without depth stencil buffers */
109     if(stateblock->wineD3DDevice->stencilBufferTarget == NULL) {
110         glDisable(GL_DEPTH_TEST); /* This also disables z writing in gl */
111         checkGLcall("glDisable GL_DEPTH_TEST");
112         return;
113     }
114
115     switch ((WINED3DZBUFFERTYPE) stateblock->renderState[WINED3DRS_ZENABLE]) {
116         case WINED3DZB_FALSE:
117             glDisable(GL_DEPTH_TEST);
118             checkGLcall("glDisable GL_DEPTH_TEST");
119             break;
120         case WINED3DZB_TRUE:
121             glEnable(GL_DEPTH_TEST);
122             checkGLcall("glEnable GL_DEPTH_TEST");
123             break;
124         case WINED3DZB_USEW:
125             glEnable(GL_DEPTH_TEST);
126             checkGLcall("glEnable GL_DEPTH_TEST");
127             FIXME("W buffer is not well handled\n");
128             break;
129         default:
130             FIXME("Unrecognized D3DZBUFFERTYPE value %d\n", stateblock->renderState[WINED3DRS_ZENABLE]);
131     }
132 }
133
134 static void state_cullmode(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
135     /* TODO: Put this into the offscreen / onscreen rendering block due to device->render_offscreen */
136
137     /* If we are culling "back faces with clockwise vertices" then
138        set front faces to be counter clockwise and enable culling
139        of back faces                                               */
140     switch ((WINED3DCULL) stateblock->renderState[WINED3DRS_CULLMODE]) {
141         case WINED3DCULL_NONE:
142             glDisable(GL_CULL_FACE);
143             checkGLcall("glDisable GL_CULL_FACE");
144             break;
145         case WINED3DCULL_CW:
146             glEnable(GL_CULL_FACE);
147             checkGLcall("glEnable GL_CULL_FACE");
148             if (stateblock->wineD3DDevice->render_offscreen) {
149                 glFrontFace(GL_CW);
150                 checkGLcall("glFrontFace GL_CW");
151             } else {
152                 glFrontFace(GL_CCW);
153                 checkGLcall("glFrontFace GL_CCW");
154             }
155             glCullFace(GL_BACK);
156             break;
157         case WINED3DCULL_CCW:
158             glEnable(GL_CULL_FACE);
159             checkGLcall("glEnable GL_CULL_FACE");
160             if (stateblock->wineD3DDevice->render_offscreen) {
161                 glFrontFace(GL_CCW);
162                 checkGLcall("glFrontFace GL_CCW");
163             } else {
164                 glFrontFace(GL_CW);
165                 checkGLcall("glFrontFace GL_CW");
166             }
167             glCullFace(GL_BACK);
168             break;
169         default:
170             FIXME("Unrecognized/Unhandled WINED3DCULL value %d\n", stateblock->renderState[WINED3DRS_CULLMODE]);
171     }
172 }
173
174 static void state_shademode(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
175     switch ((WINED3DSHADEMODE) stateblock->renderState[WINED3DRS_SHADEMODE]) {
176         case WINED3DSHADE_FLAT:
177             glShadeModel(GL_FLAT);
178             checkGLcall("glShadeModel(GL_FLAT)");
179             break;
180         case WINED3DSHADE_GOURAUD:
181             glShadeModel(GL_SMOOTH);
182             checkGLcall("glShadeModel(GL_SMOOTH)");
183             break;
184         case WINED3DSHADE_PHONG:
185             FIXME("WINED3DSHADE_PHONG isn't supported\n");
186             break;
187         default:
188             FIXME("Unrecognized/Unhandled WINED3DSHADEMODE value %d\n", stateblock->renderState[WINED3DRS_SHADEMODE]);
189     }
190 }
191
192 static void state_ditherenable(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
193     if (stateblock->renderState[WINED3DRS_DITHERENABLE]) {
194         glEnable(GL_DITHER);
195         checkGLcall("glEnable GL_DITHER");
196     } else {
197         glDisable(GL_DITHER);
198         checkGLcall("glDisable GL_DITHER");
199     }
200 }
201
202 static void state_zwritenable(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
203     /* TODO: Test if in d3d z writing is enabled even if ZENABLE is off. If yes,
204      * this has to be merged with ZENABLE and ZFUNC
205      */
206     if (stateblock->renderState[WINED3DRS_ZWRITEENABLE]) {
207         glDepthMask(1);
208         checkGLcall("glDepthMask(1)");
209     } else {
210         glDepthMask(0);
211         checkGLcall("glDepthMask(0)");
212     }
213 }
214
215 static void state_zfunc(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
216     int glParm = CompareFunc(stateblock->renderState[WINED3DRS_ZFUNC]);
217
218     if(glParm) {
219         glDepthFunc(glParm);
220         checkGLcall("glDepthFunc");
221     }
222 }
223
224 static void state_ambient(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
225     float col[4];
226     D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_AMBIENT], col);
227
228     TRACE("Setting ambient to (%f,%f,%f,%f)\n", col[0], col[1], col[2], col[3]);
229     glLightModelfv(GL_LIGHT_MODEL_AMBIENT, col);
230     checkGLcall("glLightModel for MODEL_AMBIENT");
231 }
232
233 static void state_blend(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
234     int srcBlend = GL_ZERO;
235     int dstBlend = GL_ZERO;
236
237     /* GL_LINE_SMOOTH needs GL_BLEND to work, according to the red book, and special blending params */
238     if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE]      ||
239         stateblock->renderState[WINED3DRS_EDGEANTIALIAS]         ||
240         stateblock->renderState[WINED3DRS_ANTIALIASEDLINEENABLE]) {
241         glEnable(GL_BLEND);
242         checkGLcall("glEnable GL_BLEND");
243     } else {
244         glDisable(GL_BLEND);
245         checkGLcall("glDisable GL_BLEND");
246         /* Nothing more to do - get out */
247         return;
248     };
249
250     switch (stateblock->renderState[WINED3DRS_DESTBLEND]) {
251         case WINED3DBLEND_ZERO               : dstBlend = GL_ZERO;  break;
252         case WINED3DBLEND_ONE                : dstBlend = GL_ONE;  break;
253         case WINED3DBLEND_SRCCOLOR           : dstBlend = GL_SRC_COLOR;  break;
254         case WINED3DBLEND_INVSRCCOLOR        : dstBlend = GL_ONE_MINUS_SRC_COLOR;  break;
255         case WINED3DBLEND_SRCALPHA           : dstBlend = GL_SRC_ALPHA;  break;
256         case WINED3DBLEND_INVSRCALPHA        : dstBlend = GL_ONE_MINUS_SRC_ALPHA;  break;
257         case WINED3DBLEND_DESTALPHA          : dstBlend = GL_DST_ALPHA;  break;
258         case WINED3DBLEND_INVDESTALPHA       : dstBlend = GL_ONE_MINUS_DST_ALPHA;  break;
259         case WINED3DBLEND_DESTCOLOR          : dstBlend = GL_DST_COLOR;  break;
260         case WINED3DBLEND_INVDESTCOLOR       : dstBlend = GL_ONE_MINUS_DST_COLOR;  break;
261
262         case WINED3DBLEND_SRCALPHASAT        :
263             dstBlend = GL_SRC_ALPHA_SATURATE;
264             WARN("Application uses SRCALPHASAT as dest blend factor, expect problems\n");
265             break;
266
267         /* WINED3DBLEND_BOTHSRCALPHA and WINED3DBLEND_BOTHINVSRCALPHA are legacy source blending
268          * values which are still valid up to d3d9. They should not occur as dest blend values
269          */
270         case WINED3DBLEND_BOTHSRCALPHA       : dstBlend = GL_SRC_ALPHA;
271             srcBlend = GL_SRC_ALPHA;
272             FIXME("WINED3DRS_DESTBLEND = WINED3DBLEND_BOTHSRCALPHA, what to do?\n");
273             break;
274
275         case WINED3DBLEND_BOTHINVSRCALPHA    : dstBlend = GL_ONE_MINUS_SRC_ALPHA;
276             srcBlend = GL_ONE_MINUS_SRC_ALPHA;
277             FIXME("WINED3DRS_DESTBLEND = WINED3DBLEND_BOTHINVSRCALPHA, what to do?\n");
278             break;
279
280         case WINED3DBLEND_BLENDFACTOR        : dstBlend = GL_CONSTANT_COLOR;   break;
281         case WINED3DBLEND_INVBLENDFACTOR     : dstBlend = GL_ONE_MINUS_CONSTANT_COLOR;  break;
282         default:
283             FIXME("Unrecognized dst blend value %d\n", stateblock->renderState[WINED3DRS_DESTBLEND]);
284     }
285
286     switch (stateblock->renderState[WINED3DRS_SRCBLEND]) {
287         case WINED3DBLEND_ZERO               : srcBlend = GL_ZERO;  break;
288         case WINED3DBLEND_ONE                : srcBlend = GL_ONE;  break;
289         case WINED3DBLEND_SRCCOLOR           : srcBlend = GL_SRC_COLOR;  break;
290         case WINED3DBLEND_INVSRCCOLOR        : srcBlend = GL_ONE_MINUS_SRC_COLOR;  break;
291         case WINED3DBLEND_SRCALPHA           : srcBlend = GL_SRC_ALPHA;  break;
292         case WINED3DBLEND_INVSRCALPHA        : srcBlend = GL_ONE_MINUS_SRC_ALPHA;  break;
293         case WINED3DBLEND_DESTALPHA          : srcBlend = GL_DST_ALPHA;  break;
294         case WINED3DBLEND_INVDESTALPHA       : srcBlend = GL_ONE_MINUS_DST_ALPHA;  break;
295         case WINED3DBLEND_DESTCOLOR          : srcBlend = GL_DST_COLOR;  break;
296         case WINED3DBLEND_INVDESTCOLOR       : srcBlend = GL_ONE_MINUS_DST_COLOR;  break;
297         case WINED3DBLEND_SRCALPHASAT        : srcBlend = GL_SRC_ALPHA_SATURATE;  break;
298
299         case WINED3DBLEND_BOTHSRCALPHA       : srcBlend = GL_SRC_ALPHA;
300             dstBlend = GL_ONE_MINUS_SRC_ALPHA;
301             break;
302
303         case WINED3DBLEND_BOTHINVSRCALPHA    : srcBlend = GL_ONE_MINUS_SRC_ALPHA;
304             dstBlend = GL_SRC_ALPHA;
305             break;
306
307         case WINED3DBLEND_BLENDFACTOR        : srcBlend = GL_CONSTANT_COLOR;   break;
308         case WINED3DBLEND_INVBLENDFACTOR     : srcBlend = GL_ONE_MINUS_CONSTANT_COLOR;  break;
309         default:
310             FIXME("Unrecognized src blend value %d\n", stateblock->renderState[WINED3DRS_SRCBLEND]);
311     }
312
313
314     if(stateblock->renderState[WINED3DRS_EDGEANTIALIAS] ||
315        stateblock->renderState[WINED3DRS_ANTIALIASEDLINEENABLE]) {
316         glEnable(GL_LINE_SMOOTH);
317         checkGLcall("glEnable(GL_LINE_SMOOTH)");
318         if(srcBlend != GL_SRC_ALPHA) {
319             WARN("WINED3DRS_EDGEANTIALIAS enabled, but unexpected src blending param\n");
320         }
321         if(dstBlend != GL_ONE_MINUS_SRC_ALPHA && dstBlend != GL_ONE) {
322             WARN("WINED3DRS_EDGEANTIALIAS enabled, but unexpected dst blending param\n");
323         }
324     } else {
325         glDisable(GL_LINE_SMOOTH);
326         checkGLcall("glDisable(GL_LINE_SMOOTH)");
327     }
328
329     TRACE("glBlendFunc src=%x, dst=%x\n", srcBlend, dstBlend);
330     glBlendFunc(srcBlend, dstBlend);
331     checkGLcall("glBlendFunc");
332 }
333
334 static void state_blendfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
335     float col[4];
336
337     TRACE("Setting BlendFactor to %d\n", stateblock->renderState[WINED3DRS_BLENDFACTOR]);
338     D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_BLENDFACTOR], col);
339     GL_EXTCALL(glBlendColor (col[0],col[1],col[2],col[3]));
340     checkGLcall("glBlendColor");
341 }
342
343 static void state_alpha(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
344     int glParm = 0;
345     float ref;
346     BOOL enable_ckey = FALSE;
347
348     IWineD3DSurfaceImpl *surf;
349
350     /* Find out if the texture on the first stage has a ckey set
351      * The alpha state func reads the texture settings, even though alpha and texture are not grouped
352      * together. This is to avoid making a huge alpha+texture+texture stage+ckey block due to the hardly
353      * used WINED3DRS_COLORKEYENABLE state(which is d3d <= 3 only). The texture function will call alpha
354      * in case it finds some texture+colorkeyenable combination which needs extra care.
355      */
356     if(stateblock->textures[0] && stateblock->textureDimensions[0] == GL_TEXTURE_2D) {
357         surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *)stateblock->textures[0])->surfaces[0];
358
359         if(surf->CKeyFlags & WINEDDSD_CKSRCBLT) {
360             const StaticPixelFormatDesc *fmt = getFormatDescEntry(surf->resource.format, NULL, NULL);
361             /* The surface conversion does not do color keying conversion for surfaces that have an alpha
362              * channel on their own. Likewise, the alpha test shouldn't be set up for color keying if the
363              * surface has alpha bits
364              */
365             if(fmt->alphaMask == 0x00000000) {
366                 enable_ckey = TRUE;
367             }
368         }
369     }
370
371     if(enable_ckey || context->last_was_ckey) {
372         StateTable[STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP)].apply(STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), stateblock, context);
373     }
374     context->last_was_ckey = enable_ckey;
375
376     if (stateblock->renderState[WINED3DRS_ALPHATESTENABLE] ||
377         (stateblock->renderState[WINED3DRS_COLORKEYENABLE] && enable_ckey)) {
378         glEnable(GL_ALPHA_TEST);
379         checkGLcall("glEnable GL_ALPHA_TEST");
380     } else {
381         glDisable(GL_ALPHA_TEST);
382         checkGLcall("glDisable GL_ALPHA_TEST");
383         /* Alpha test is disabled, don't bother setting the params - it will happen on the next
384          * enable call
385          */
386         return;
387     }
388
389     if(stateblock->renderState[WINED3DRS_COLORKEYENABLE] && enable_ckey) {
390         glParm = GL_NOTEQUAL;
391         ref = 0.0;
392     } else {
393         ref = ((float) stateblock->renderState[WINED3DRS_ALPHAREF]) / 255.0f;
394         glParm = CompareFunc(stateblock->renderState[WINED3DRS_ALPHAFUNC]);
395     }
396     if(glParm) {
397         glAlphaFunc(glParm, ref);
398         checkGLcall("glAlphaFunc");
399     }
400 }
401
402 static void state_clipping(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
403     DWORD enable  = 0xFFFFFFFF;
404     DWORD disable = 0x00000000;
405
406     if (use_vs(stateblock->wineD3DDevice)) {
407         /* The spec says that opengl clipping planes are disabled when using shaders. Direct3D planes aren't,
408          * so that is an issue. The MacOS ATI driver keeps clipping planes activated with shaders in some
409          * contitions I got sick of tracking down. The shader state handler disables all clip planes because
410          * of that - don't do anything here and keep them disabled
411          */
412         if(stateblock->renderState[WINED3DRS_CLIPPLANEENABLE]) {
413             static BOOL warned = FALSE;
414             if(!warned) {
415                 FIXME("Clipping not supported with vertex shaders\n");
416                 warned = TRUE;
417             }
418         }
419         return;
420     }
421
422     /* TODO: Keep track of previously enabled clipplanes to avoid unnecessary resetting
423      * of already set values
424      */
425
426     /* If enabling / disabling all
427      * TODO: Is this correct? Doesn't D3DRS_CLIPPING disable clipping on the viewport frustrum?
428      */
429     if (stateblock->renderState[WINED3DRS_CLIPPING]) {
430         enable  = stateblock->renderState[WINED3DRS_CLIPPLANEENABLE];
431         disable = ~stateblock->renderState[WINED3DRS_CLIPPLANEENABLE];
432     } else {
433         disable = 0xffffffff;
434         enable  = 0x00;
435     }
436
437     if (enable & WINED3DCLIPPLANE0)  { glEnable(GL_CLIP_PLANE0);  checkGLcall("glEnable(clip plane 0)"); }
438     if (enable & WINED3DCLIPPLANE1)  { glEnable(GL_CLIP_PLANE1);  checkGLcall("glEnable(clip plane 1)"); }
439     if (enable & WINED3DCLIPPLANE2)  { glEnable(GL_CLIP_PLANE2);  checkGLcall("glEnable(clip plane 2)"); }
440     if (enable & WINED3DCLIPPLANE3)  { glEnable(GL_CLIP_PLANE3);  checkGLcall("glEnable(clip plane 3)"); }
441     if (enable & WINED3DCLIPPLANE4)  { glEnable(GL_CLIP_PLANE4);  checkGLcall("glEnable(clip plane 4)"); }
442     if (enable & WINED3DCLIPPLANE5)  { glEnable(GL_CLIP_PLANE5);  checkGLcall("glEnable(clip plane 5)"); }
443
444     if (disable & WINED3DCLIPPLANE0) { glDisable(GL_CLIP_PLANE0); checkGLcall("glDisable(clip plane 0)"); }
445     if (disable & WINED3DCLIPPLANE1) { glDisable(GL_CLIP_PLANE1); checkGLcall("glDisable(clip plane 1)"); }
446     if (disable & WINED3DCLIPPLANE2) { glDisable(GL_CLIP_PLANE2); checkGLcall("glDisable(clip plane 2)"); }
447     if (disable & WINED3DCLIPPLANE3) { glDisable(GL_CLIP_PLANE3); checkGLcall("glDisable(clip plane 3)"); }
448     if (disable & WINED3DCLIPPLANE4) { glDisable(GL_CLIP_PLANE4); checkGLcall("glDisable(clip plane 4)"); }
449     if (disable & WINED3DCLIPPLANE5) { glDisable(GL_CLIP_PLANE5); checkGLcall("glDisable(clip plane 5)"); }
450
451     /** update clipping status */
452     if (enable) {
453         stateblock->clip_status.ClipUnion = 0;
454         stateblock->clip_status.ClipIntersection = 0xFFFFFFFF;
455     } else {
456         stateblock->clip_status.ClipUnion = 0;
457         stateblock->clip_status.ClipIntersection = 0;
458     }
459 }
460
461 static void state_blendop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
462     int glParm = GL_FUNC_ADD;
463
464     if(!GL_SUPPORT(EXT_BLEND_MINMAX)) {
465         WARN("Unsupported in local OpenGL implementation: glBlendEquation\n");
466         return;
467     }
468
469     switch ((WINED3DBLENDOP) stateblock->renderState[WINED3DRS_BLENDOP]) {
470         case WINED3DBLENDOP_ADD              : glParm = GL_FUNC_ADD;              break;
471         case WINED3DBLENDOP_SUBTRACT         : glParm = GL_FUNC_SUBTRACT;         break;
472         case WINED3DBLENDOP_REVSUBTRACT      : glParm = GL_FUNC_REVERSE_SUBTRACT; break;
473         case WINED3DBLENDOP_MIN              : glParm = GL_MIN;                   break;
474         case WINED3DBLENDOP_MAX              : glParm = GL_MAX;                   break;
475         default:
476             FIXME("Unrecognized/Unhandled D3DBLENDOP value %d\n", stateblock->renderState[WINED3DRS_BLENDOP]);
477     }
478
479     TRACE("glBlendEquation(%x)\n", glParm);
480     GL_EXTCALL(glBlendEquation(glParm));
481     checkGLcall("glBlendEquation");
482 }
483
484 static void
485 state_specularenable(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
486     /* Originally this used glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR)
487      * and (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR) to swap between enabled/disabled
488      * specular color. This is wrong:
489      * Separate specular color means the specular colour is maintained separately, whereas
490      * single color means it is merged in. However in both cases they are being used to
491      * some extent.
492      * To disable specular color, set it explicitly to black and turn off GL_COLOR_SUM_EXT
493      * NOTE: If not supported don't give FIXMEs the impact is really minimal and very few people are
494      * running 1.4 yet!
495      *
496      *
497      * If register combiners are enabled, enabling / disabling GL_COLOR_SUM has no effect.
498      * Instead, we need to setup the FinalCombiner properly.
499      *
500      * The default setup for the FinalCombiner is:
501      *
502      * <variable>       <input>                             <mapping>               <usage>
503      * GL_VARIABLE_A_NV GL_FOG,                             GL_UNSIGNED_IDENTITY_NV GL_ALPHA
504      * GL_VARIABLE_B_NV GL_SPARE0_PLUS_SECONDARY_COLOR_NV   GL_UNSIGNED_IDENTITY_NV GL_RGB
505      * GL_VARIABLE_C_NV GL_FOG                              GL_UNSIGNED_IDENTITY_NV GL_RGB
506      * GL_VARIABLE_D_NV GL_ZERO                             GL_UNSIGNED_IDENTITY_NV GL_RGB
507      * GL_VARIABLE_E_NV GL_ZERO                             GL_UNSIGNED_IDENTITY_NV GL_RGB
508      * GL_VARIABLE_F_NV GL_ZERO                             GL_UNSIGNED_IDENTITY_NV GL_RGB
509      * GL_VARIABLE_G_NV GL_SPARE0_NV                        GL_UNSIGNED_IDENTITY_NV GL_ALPHA
510      *
511      * That's pretty much fine as it is, except for variable B, which needs to take
512      * either GL_SPARE0_PLUS_SECONDARY_COLOR_NV or GL_SPARE0_NV, depending on
513      * whether WINED3DRS_SPECULARENABLE is enabled or not.
514      */
515
516     TRACE("Setting specular enable state and materials\n");
517     if (stateblock->renderState[WINED3DRS_SPECULARENABLE]) {
518         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float*) &stateblock->material.Specular);
519         checkGLcall("glMaterialfv");
520
521         if(stateblock->material.Power > 128.0) {
522             /* glMaterialf man page says that the material says that GL_SHININESS must be between 0.0
523              * and 128.0, although in d3d neither -1 nor 129 produce an error. For values > 128 clamp
524              * them, since 128 results in a hardly visible specular highlight, so it should be safe to
525              * to clamp to 128
526              */
527             WARN("Material power > 128\n");
528             glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 128.0);
529         } else {
530             glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, stateblock->material.Power);
531         }
532         checkGLcall("glMaterialf(GL_SHININESS");
533
534         if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
535             glEnable(GL_COLOR_SUM_EXT);
536         } else {
537             TRACE("Specular colors cannot be enabled in this version of opengl\n");
538         }
539         checkGLcall("glEnable(GL_COLOR_SUM)");
540
541         if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
542             GL_EXTCALL(glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_SPARE0_PLUS_SECONDARY_COLOR_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB));
543             checkGLcall("glFinalCombinerInputNV()");
544         }
545     } else {
546         float black[4] = {0.0f, 0.0f, 0.0f, 0.0f};
547
548         /* for the case of enabled lighting: */
549         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
550         checkGLcall("glMaterialfv");
551
552         /* for the case of disabled lighting: */
553         if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
554             glDisable(GL_COLOR_SUM_EXT);
555         } else {
556             TRACE("Specular colors cannot be disabled in this version of opengl\n");
557         }
558         checkGLcall("glDisable(GL_COLOR_SUM)");
559
560         if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
561             GL_EXTCALL(glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB));
562             checkGLcall("glFinalCombinerInputNV()");
563         }
564     }
565
566     TRACE("(%p) : Diffuse (%f,%f,%f,%f)\n", stateblock->wineD3DDevice, stateblock->material.Diffuse.r, stateblock->material.Diffuse.g,
567           stateblock->material.Diffuse.b, stateblock->material.Diffuse.a);
568     TRACE("(%p) : Ambient (%f,%f,%f,%f)\n", stateblock->wineD3DDevice, stateblock->material.Ambient.r, stateblock->material.Ambient.g,
569           stateblock->material.Ambient.b, stateblock->material.Ambient.a);
570     TRACE("(%p) : Specular (%f,%f,%f,%f)\n", stateblock->wineD3DDevice, stateblock->material.Specular.r, stateblock->material.Specular.g,
571           stateblock->material.Specular.b, stateblock->material.Specular.a);
572     TRACE("(%p) : Emissive (%f,%f,%f,%f)\n", stateblock->wineD3DDevice, stateblock->material.Emissive.r, stateblock->material.Emissive.g,
573           stateblock->material.Emissive.b, stateblock->material.Emissive.a);
574
575     glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float*) &stateblock->material.Ambient);
576     checkGLcall("glMaterialfv(GL_AMBIENT)");
577     glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float*) &stateblock->material.Diffuse);
578     checkGLcall("glMaterialfv(GL_DIFFUSE)");
579     glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float*) &stateblock->material.Emissive);
580     checkGLcall("glMaterialfv(GL_EMISSION)");
581 }
582
583 static void state_texfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
584     unsigned int i;
585
586     /* Note the texture color applies to all textures whereas
587      * GL_TEXTURE_ENV_COLOR applies to active only
588      */
589     float col[4];
590     D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_TEXTUREFACTOR], col);
591
592     if (!GL_SUPPORT(NV_REGISTER_COMBINERS)) {
593         /* And now the default texture color as well */
594         for (i = 0; i < GL_LIMITS(texture_stages); i++) {
595             /* Note the WINED3DRS value applies to all textures, but GL has one
596              * per texture, so apply it now ready to be used!
597              */
598             if (GL_SUPPORT(ARB_MULTITEXTURE)) {
599                 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + i));
600                 checkGLcall("glActiveTextureARB");
601             } else if (i>0) {
602                 FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
603             }
604
605             glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
606             checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
607         }
608     } else {
609         GL_EXTCALL(glCombinerParameterfvNV(GL_CONSTANT_COLOR0_NV, &col[0]));
610     }
611 }
612
613 static void
614 renderstate_stencil_twosided(IWineD3DStateBlockImpl *stateblock, GLint face, GLint func, GLint ref, GLuint mask, GLint stencilFail, GLint depthFail, GLint stencilPass ) {
615 #if 0 /* Don't use OpenGL 2.0 calls for now */
616             if(GL_EXTCALL(glStencilFuncSeparate) && GL_EXTCALL(glStencilOpSeparate)) {
617                 GL_EXTCALL(glStencilFuncSeparate(face, func, ref, mask));
618                 checkGLcall("glStencilFuncSeparate(...)");
619                 GL_EXTCALL(glStencilOpSeparate(face, stencilFail, depthFail, stencilPass));
620                 checkGLcall("glStencilOpSeparate(...)");
621         }
622             else
623 #endif
624     if(GL_SUPPORT(EXT_STENCIL_TWO_SIDE)) {
625         glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);
626         checkGLcall("glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT)");
627         GL_EXTCALL(glActiveStencilFaceEXT(face));
628         checkGLcall("glActiveStencilFaceEXT(...)");
629         glStencilFunc(func, ref, mask);
630         checkGLcall("glStencilFunc(...)");
631         glStencilOp(stencilFail, depthFail, stencilPass);
632         checkGLcall("glStencilOp(...)");
633     } else if(GL_SUPPORT(ATI_SEPARATE_STENCIL)) {
634         GL_EXTCALL(glStencilFuncSeparateATI(face, func, ref, mask));
635         checkGLcall("glStencilFuncSeparateATI(...)");
636         GL_EXTCALL(glStencilOpSeparateATI(face, stencilFail, depthFail, stencilPass));
637         checkGLcall("glStencilOpSeparateATI(...)");
638     } else {
639         ERR("Separate (two sided) stencil not supported on this version of opengl. Caps weren't honored?\n");
640     }
641 }
642
643 static void
644 state_stencil(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
645     DWORD onesided_enable = FALSE;
646     DWORD twosided_enable = FALSE;
647     GLint func = GL_ALWAYS;
648     GLint func_ccw = GL_ALWAYS;
649     GLint ref = 0;
650     GLuint mask = 0;
651     GLint stencilFail = GL_KEEP;
652     GLint depthFail = GL_KEEP;
653     GLint stencilPass = GL_KEEP;
654     GLint stencilFail_ccw = GL_KEEP;
655     GLint depthFail_ccw = GL_KEEP;
656     GLint stencilPass_ccw = GL_KEEP;
657
658     /* No stencil test without a stencil buffer */
659     if(stateblock->wineD3DDevice->stencilBufferTarget == NULL) {
660         glDisable(GL_STENCIL_TEST);
661         checkGLcall("glDisable GL_STENCIL_TEST");
662         return;
663     }
664
665     onesided_enable = stateblock->renderState[WINED3DRS_STENCILENABLE];
666     twosided_enable = stateblock->renderState[WINED3DRS_TWOSIDEDSTENCILMODE];
667     if( !( func = CompareFunc(stateblock->renderState[WINED3DRS_STENCILFUNC]) ) )
668         func = GL_ALWAYS;
669     if( !( func_ccw = CompareFunc(stateblock->renderState[WINED3DRS_CCW_STENCILFUNC]) ) )
670         func = GL_ALWAYS;
671     ref = stateblock->renderState[WINED3DRS_STENCILREF];
672     mask = stateblock->renderState[WINED3DRS_STENCILMASK];
673     stencilFail = StencilOp(stateblock->renderState[WINED3DRS_STENCILFAIL]);
674     depthFail = StencilOp(stateblock->renderState[WINED3DRS_STENCILZFAIL]);
675     stencilPass = StencilOp(stateblock->renderState[WINED3DRS_STENCILPASS]);
676     stencilFail_ccw = StencilOp(stateblock->renderState[WINED3DRS_CCW_STENCILFAIL]);
677     depthFail_ccw = StencilOp(stateblock->renderState[WINED3DRS_CCW_STENCILZFAIL]);
678     stencilPass_ccw = StencilOp(stateblock->renderState[WINED3DRS_CCW_STENCILPASS]);
679
680     TRACE("(onesided %d, twosided %d, ref %x, mask %x, "
681           "GL_FRONT: func: %x, fail %x, zfail %x, zpass %x "
682           "GL_BACK: func: %x, fail %x, zfail %x, zpass %x )\n",
683     onesided_enable, twosided_enable, ref, mask,
684     func, stencilFail, depthFail, stencilPass,
685     func_ccw, stencilFail_ccw, depthFail_ccw, stencilPass_ccw);
686
687     if (twosided_enable) {
688         renderstate_stencil_twosided(stateblock, GL_FRONT, func, ref, mask, stencilFail, depthFail, stencilPass);
689         renderstate_stencil_twosided(stateblock, GL_BACK, func_ccw, ref, mask, stencilFail_ccw, depthFail_ccw, stencilPass_ccw);
690     } else {
691         if (onesided_enable) {
692             glEnable(GL_STENCIL_TEST);
693             checkGLcall("glEnable GL_STENCIL_TEST");
694             glStencilFunc(func, ref, mask);
695             checkGLcall("glStencilFunc(...)");
696             glStencilOp(stencilFail, depthFail, stencilPass);
697             checkGLcall("glStencilOp(...)");
698         } else {
699             glDisable(GL_STENCIL_TEST);
700             checkGLcall("glDisable GL_STENCIL_TEST");
701         }
702     }
703 }
704
705 static void state_stencilwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
706     if(stateblock->wineD3DDevice->stencilBufferTarget) {
707         glStencilMask(stateblock->renderState[WINED3DRS_STENCILWRITEMASK]);
708     } else {
709         glStencilMask(0);
710     }
711     checkGLcall("glStencilMask");
712 }
713
714 static void state_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
715     /* TODO: Put this into the vertex type block once that is in the state table */
716     BOOL fogenable = stateblock->renderState[WINED3DRS_FOGENABLE];
717     BOOL is_ps3 = use_ps(stateblock->wineD3DDevice)
718                   && ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.hex_version >= WINED3DPS_VERSION(3,0);
719     float fogstart, fogend;
720
721     union {
722         DWORD d;
723         float f;
724     } tmpvalue;
725
726     if (!fogenable) {
727         /* No fog? Disable it, and we're done :-) */
728         glDisable(GL_FOG);
729         checkGLcall("glDisable GL_FOG");
730         if( use_ps(stateblock->wineD3DDevice)
731                 && ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.hex_version < WINED3DPS_VERSION(3,0) ) {
732             /* disable fog in the pixel shader
733              * NOTE: For pixel shader, GL_FOG_START and GL_FOG_END don't hold fog start s and end e but
734              * -1/(e-s) and e/(e-s) respectively.
735              */
736             glFogf(GL_FOG_START, 0.0f);
737             checkGLcall("glFogf(GL_FOG_START, fogstart");
738             glFogf(GL_FOG_END, 1.0f);
739             checkGLcall("glFogf(GL_FOG_END, fogend");
740         }
741         return;
742     }
743
744     tmpvalue.d = stateblock->renderState[WINED3DRS_FOGSTART];
745     fogstart = tmpvalue.f;
746     tmpvalue.d = stateblock->renderState[WINED3DRS_FOGEND];
747     fogend = tmpvalue.f;
748
749     /* Fog Rules:
750      *
751      * With fixed function vertex processing, Direct3D knows 2 different fog input sources.
752      * It can use the Z value of the vertex, or the alpha component of the specular color.
753      * This depends on the fog vertex, fog table and the vertex declaration. If the Z value
754      * is used, fogstart, fogend and the equation type are used, otherwise linear fog with
755      * start = 255, end = 0 is used. Obviously the msdn is not very clear on that.
756      *
757      * FOGTABLEMODE != NONE:
758      *  The Z value is used, with the equation specified, no matter what vertex type.
759      *
760      * FOGTABLEMODE == NONE, FOGVERTEXMODE != NONE, untransformed:
761      *  Per vertex fog is calculated using the specified fog equation and the parameters
762      *
763      * FOGTABLEMODE == NONE, FOGVERTEXMODE != NONE, transformed, OR
764      * FOGTABLEMODE == NONE, FOGVERTEXMODE == NONE, untransformed:
765      *  Linear fog with start = 255.0, end = 0.0, input comes from the specular color
766      *
767      *
768      * Rules for vertex fog with shaders:
769      *
770      * When mixing fixed function functionality with the programmable pipeline, D3D expects
771      * the fog computation to happen during transformation while openGL expects it to happen
772      * during rasterization. Also, prior to pixel shader 3.0 D3D handles fog blending after
773      * the pixel shader while openGL always expects the pixel shader to handle the blending.
774      * To solve this problem, WineD3D does:
775      * 1) implement a linear fog equation and fog blending at the end of every pre 3.0 pixel
776      * shader,
777      * and 2) disables the fog computation (in either the fixed function or programmable
778      * rasterizer) if using a vertex program.
779      *
780      *
781      * If a fogtablemode and a fogvertexmode are specified, table fog is applied (with or
782      * without shaders).
783      */
784
785     if( is_ps3 ) {
786         if( !use_vs(stateblock->wineD3DDevice)
787                 && stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE ) {
788             FIXME("Implement vertex fog for pixel shader >= 3.0 and fixed function pipeline\n");
789         }
790     }
791
792     if (use_vs(stateblock->wineD3DDevice)
793             && ((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.reg_maps.fog) {
794         if( stateblock->renderState[WINED3DRS_FOGTABLEMODE] != WINED3DFOG_NONE ) {
795             if(!is_ps3) FIXME("Implement table fog for foggy vertex shader\n");
796             /* Disable fog */
797             fogenable = FALSE;
798         } else {
799             /* Set fog computation in the rasterizer to pass through the value (just blend it) */
800             glFogi(GL_FOG_MODE, GL_LINEAR);
801             checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
802             fogstart = 1.0;
803             fogend = 0.0;
804         }
805
806         if(GL_SUPPORT(EXT_FOG_COORD) && context->fog_coord) {
807             glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
808             checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
809             context->fog_coord = FALSE;
810         }
811         context->last_was_foggy_shader = TRUE;
812     }
813     else if( use_ps(stateblock->wineD3DDevice) ) {
814         /* NOTE: For pixel shader, GL_FOG_START and GL_FOG_END don't hold fog start s and end e but
815          * -1/(e-s) and e/(e-s) respectively to simplify fog computation in the shader.
816          */
817         WINED3DFOGMODE mode;
818         context->last_was_foggy_shader = FALSE;
819
820         /* If both fogmodes are set use the table fog mode */
821         if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE)
822             mode = stateblock->renderState[WINED3DRS_FOGVERTEXMODE];
823         else
824             mode = stateblock->renderState[WINED3DRS_FOGTABLEMODE];
825
826         switch (mode) {
827             case WINED3DFOG_EXP:
828             case WINED3DFOG_EXP2:
829                 if(!is_ps3) FIXME("Implement non linear fog for pixel shader < 3.0\n");
830                 /* Disable fog */
831                 fogenable = FALSE;
832                 break;
833
834             case WINED3DFOG_LINEAR:
835                 fogstart = -1.0f/(fogend-fogstart);
836                 fogend *= -fogstart;
837                 break;
838
839             case WINED3DFOG_NONE:
840                 if(!is_ps3) FIXME("Implement software vertex fog for pixel shader < 3.0\n");
841                 /* Disable fog */
842                 fogenable = FALSE;
843                 break;
844             default: FIXME("Unexpected WINED3DRS_FOGVERTEXMODE %d\n", stateblock->renderState[WINED3DRS_FOGVERTEXMODE]);
845         }
846
847         if(GL_SUPPORT(EXT_FOG_COORD) && context->fog_coord) {
848             glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
849             checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
850             context->fog_coord = FALSE;
851         }
852     }
853     /* DX 7 sdk: "If both render states(vertex and table fog) are set to valid modes,
854      * the system will apply only pixel(=table) fog effects."
855      */
856     else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
857         glHint(GL_FOG_HINT, GL_FASTEST);
858         checkGLcall("glHint(GL_FOG_HINT, GL_FASTEST)");
859         context->last_was_foggy_shader = FALSE;
860
861         switch (stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
862             /* If processed vertices are used, fall through to the NONE case */
863             case WINED3DFOG_EXP:  {
864                 if(!context->last_was_rhw) {
865                     glFogi(GL_FOG_MODE, GL_EXP);
866                     checkGLcall("glFogi(GL_FOG_MODE, GL_EXP");
867                     if(GL_SUPPORT(EXT_FOG_COORD) && context->fog_coord) {
868                         glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
869                         checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
870                         context->fog_coord = FALSE;
871                     }
872                     break;
873                 }
874             }
875             case WINED3DFOG_EXP2: {
876                 if(!context->last_was_rhw) {
877                     glFogi(GL_FOG_MODE, GL_EXP2);
878                     checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2");
879                     if(GL_SUPPORT(EXT_FOG_COORD) && context->fog_coord) {
880                         glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
881                         checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
882                         context->fog_coord = FALSE;
883                     }
884                     break;
885                 }
886             }
887             case WINED3DFOG_LINEAR: {
888                 if(!context->last_was_rhw) {
889                     glFogi(GL_FOG_MODE, GL_LINEAR);
890                     checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR");
891                     if(GL_SUPPORT(EXT_FOG_COORD) && context->fog_coord) {
892                         glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
893                         checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
894                         context->fog_coord = FALSE;
895                     }
896                     break;
897                 }
898             }
899             case WINED3DFOG_NONE: {
900                 /* Both are none? According to msdn the alpha channel of the specular
901                  * color contains a fog factor. Set it in drawStridedSlow.
902                  * Same happens with Vertexfog on transformed vertices
903                  */
904                 if(GL_SUPPORT(EXT_FOG_COORD)) {
905                     if(context->fog_coord == FALSE) {
906                         glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);
907                         checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT)\n");
908                         context->fog_coord = TRUE;
909                     }
910                     glFogi(GL_FOG_MODE, GL_LINEAR);
911                     checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
912                     fogstart = 0xff;
913                     fogend = 0x0;
914                 } else {
915                     /* Disable GL fog, handle this in software in drawStridedSlow */
916                     fogenable = FALSE;
917                 }
918                 break;
919             }
920             default: FIXME("Unexpected WINED3DRS_FOGVERTEXMODE %d\n", stateblock->renderState[WINED3DRS_FOGVERTEXMODE]);
921         }
922     } else {
923         glHint(GL_FOG_HINT, GL_NICEST);
924         checkGLcall("glHint(GL_FOG_HINT, GL_NICEST)");
925         context->last_was_foggy_shader = FALSE;
926
927         switch (stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
928             case WINED3DFOG_EXP:
929                 glFogi(GL_FOG_MODE, GL_EXP);
930                 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP");
931                 if(GL_SUPPORT(EXT_FOG_COORD) && context->fog_coord) {
932                     glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
933                     checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
934                     context->fog_coord = FALSE;
935                 }
936                 break;
937
938             case WINED3DFOG_EXP2:
939                 glFogi(GL_FOG_MODE, GL_EXP2);
940                 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2");
941                 if(GL_SUPPORT(EXT_FOG_COORD) && context->fog_coord) {
942                     glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
943                     checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
944                     context->fog_coord = FALSE;
945                 }
946                 break;
947
948             case WINED3DFOG_LINEAR:
949                 glFogi(GL_FOG_MODE, GL_LINEAR);
950                 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR");
951                 if(GL_SUPPORT(EXT_FOG_COORD) && context->fog_coord) {
952                     glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
953                     checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
954                     context->fog_coord = FALSE;
955                 }
956                 break;
957
958             case WINED3DFOG_NONE:   /* Won't happen */
959             default:
960                 FIXME("Unexpected WINED3DRS_FOGTABLEMODE %d\n", stateblock->renderState[WINED3DRS_FOGTABLEMODE]);
961         }
962     }
963
964     if(fogenable) {
965         glEnable(GL_FOG);
966         checkGLcall("glEnable GL_FOG");
967
968         if(fogstart != fogend)
969         {
970             glFogfv(GL_FOG_START, &fogstart);
971             checkGLcall("glFogf(GL_FOG_START, fogstart");
972             TRACE("Fog Start == %f\n", fogstart);
973
974             glFogfv(GL_FOG_END, &fogend);
975             checkGLcall("glFogf(GL_FOG_END, fogend");
976             TRACE("Fog End == %f\n", fogend);
977         }
978         else
979         {
980             glFogf(GL_FOG_START, -1.0 / 0.0);
981             checkGLcall("glFogf(GL_FOG_START, fogstart");
982             TRACE("Fog Start == %f\n", fogstart);
983
984             glFogf(GL_FOG_END, 0.0);
985             checkGLcall("glFogf(GL_FOG_END, fogend");
986             TRACE("Fog End == %f\n", fogend);
987         }
988     } else {
989         glDisable(GL_FOG);
990         checkGLcall("glDisable GL_FOG");
991         if( use_ps(stateblock->wineD3DDevice) ) {
992             /* disable fog in the pixel shader
993              * NOTE: For pixel shader, GL_FOG_START and GL_FOG_END don't hold fog start s and end e but
994              * -1/(e-s) and e/(e-s) respectively.
995              */
996             glFogf(GL_FOG_START, 0.0f);
997             checkGLcall("glFogf(GL_FOG_START, fogstart");
998             glFogf(GL_FOG_END, 1.0f);
999             checkGLcall("glFogf(GL_FOG_END, fogend");
1000         }
1001     }
1002 }
1003
1004 static void state_rangefog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1005     if(stateblock->renderState[WINED3DRS_RANGEFOGENABLE]) {
1006         if (GL_SUPPORT(NV_FOG_DISTANCE)) {
1007             glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_RADIAL_NV);
1008             checkGLcall("glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_RADIAL_NV)");
1009         } else {
1010             WARN("Range fog enabled, but not supported by this opengl implementation\n");
1011         }
1012     } else {
1013         if (GL_SUPPORT(NV_FOG_DISTANCE)) {
1014             glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV);
1015             checkGLcall("glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV)");
1016         }
1017     }
1018 }
1019
1020 static void state_fogcolor(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1021     float col[4];
1022     D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_FOGCOLOR], col);
1023     glFogfv(GL_FOG_COLOR, &col[0]);
1024     checkGLcall("glFog GL_FOG_COLOR");
1025 }
1026
1027 static void state_fogdensity(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1028     union {
1029         DWORD d;
1030         float f;
1031     } tmpvalue;
1032     tmpvalue.d = stateblock->renderState[WINED3DRS_FOGDENSITY];
1033     glFogfv(GL_FOG_DENSITY, &tmpvalue.f);
1034     checkGLcall("glFogf(GL_FOG_DENSITY, (float) Value)");
1035 }
1036
1037 /* TODO: Merge with primitive type + init_materials()!! */
1038 static void state_colormat(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1039     IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *)stateblock->wineD3DDevice;
1040     GLenum Parm = 0;
1041     WineDirect3DStridedData *diffuse = &device->strided_streams.u.s.diffuse;
1042     BOOL isDiffuseSupplied;
1043
1044     /* Depends on the decoded vertex declaration to read the existence of diffuse data.
1045      * The vertex declaration will call this function if the fixed function pipeline is used.
1046      */
1047
1048     if(isStateDirty(context, STATE_VDECL)) {
1049         return;
1050     }
1051
1052     isDiffuseSupplied = diffuse->lpData || diffuse->VBO;
1053
1054     context->num_untracked_materials = 0;
1055     if (isDiffuseSupplied && stateblock->renderState[WINED3DRS_COLORVERTEX]) {
1056         TRACE("diff %d, amb %d, emis %d, spec %d\n",
1057               stateblock->renderState[WINED3DRS_DIFFUSEMATERIALSOURCE],
1058               stateblock->renderState[WINED3DRS_AMBIENTMATERIALSOURCE],
1059               stateblock->renderState[WINED3DRS_EMISSIVEMATERIALSOURCE],
1060               stateblock->renderState[WINED3DRS_SPECULARMATERIALSOURCE]);
1061
1062         if (stateblock->renderState[WINED3DRS_DIFFUSEMATERIALSOURCE] == WINED3DMCS_COLOR1) {
1063             if (stateblock->renderState[WINED3DRS_AMBIENTMATERIALSOURCE] == WINED3DMCS_COLOR1) {
1064                 Parm = GL_AMBIENT_AND_DIFFUSE;
1065             } else {
1066                 Parm = GL_DIFFUSE;
1067             }
1068             if(stateblock->renderState[WINED3DRS_EMISSIVEMATERIALSOURCE] == WINED3DMCS_COLOR1) {
1069                 context->untracked_materials[context->num_untracked_materials] = GL_EMISSION;
1070                 context->num_untracked_materials++;
1071             }
1072             if(stateblock->renderState[WINED3DRS_SPECULARMATERIALSOURCE] == WINED3DMCS_COLOR1) {
1073                 context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
1074                 context->num_untracked_materials++;
1075             }
1076         } else if (stateblock->renderState[WINED3DRS_AMBIENTMATERIALSOURCE] == WINED3DMCS_COLOR1) {
1077             Parm = GL_AMBIENT;
1078             if(stateblock->renderState[WINED3DRS_EMISSIVEMATERIALSOURCE] == WINED3DMCS_COLOR1) {
1079                 context->untracked_materials[context->num_untracked_materials] = GL_EMISSION;
1080                 context->num_untracked_materials++;
1081             }
1082             if(stateblock->renderState[WINED3DRS_SPECULARMATERIALSOURCE] == WINED3DMCS_COLOR1) {
1083                 context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
1084                 context->num_untracked_materials++;
1085             }
1086         } else if (stateblock->renderState[WINED3DRS_EMISSIVEMATERIALSOURCE] == WINED3DMCS_COLOR1) {
1087             Parm = GL_EMISSION;
1088             if(stateblock->renderState[WINED3DRS_SPECULARMATERIALSOURCE] == WINED3DMCS_COLOR1) {
1089                 context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
1090                 context->num_untracked_materials++;
1091             }
1092         } else if (stateblock->renderState[WINED3DRS_SPECULARMATERIALSOURCE] == WINED3DMCS_COLOR1) {
1093             Parm = GL_SPECULAR;
1094         }
1095     }
1096
1097     /* Nothing changed, return. */
1098     if (Parm == context->tracking_parm) return;
1099
1100     if(!Parm) {
1101         glDisable(GL_COLOR_MATERIAL);
1102         checkGLcall("glDisable GL_COLOR_MATERIAL");
1103     } else {
1104         glColorMaterial(GL_FRONT_AND_BACK, Parm);
1105         checkGLcall("glColorMaterial(GL_FRONT_AND_BACK, Parm)");
1106         glEnable(GL_COLOR_MATERIAL);
1107         checkGLcall("glEnable(GL_COLOR_MATERIAL)");
1108     }
1109
1110     /* Apparently calls to glMaterialfv are ignored for properties we're
1111      * tracking with glColorMaterial, so apply those here. */
1112     switch (context->tracking_parm) {
1113         case GL_AMBIENT_AND_DIFFUSE:
1114             glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float*)&device->updateStateBlock->material.Ambient);
1115             glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float*)&device->updateStateBlock->material.Diffuse);
1116             checkGLcall("glMaterialfv");
1117             break;
1118
1119         case GL_DIFFUSE:
1120             glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float*)&device->updateStateBlock->material.Diffuse);
1121             checkGLcall("glMaterialfv");
1122             break;
1123
1124         case GL_AMBIENT:
1125             glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float*)&device->updateStateBlock->material.Ambient);
1126             checkGLcall("glMaterialfv");
1127             break;
1128
1129         case GL_EMISSION:
1130             glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float*)&device->updateStateBlock->material.Emissive);
1131             checkGLcall("glMaterialfv");
1132             break;
1133
1134         case GL_SPECULAR:
1135             /* Only change material color if specular is enabled, otherwise it is set to black */
1136             if (device->stateBlock->renderState[WINED3DRS_SPECULARENABLE]) {
1137                 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float*)&device->updateStateBlock->material.Specular);
1138                 checkGLcall("glMaterialfv");
1139             } else {
1140                 float black[4] = {0.0f, 0.0f, 0.0f, 0.0f};
1141                 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
1142                 checkGLcall("glMaterialfv");
1143             }
1144             break;
1145     }
1146
1147     context->tracking_parm = Parm;
1148 }
1149
1150 static void state_linepattern(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1151     union {
1152         DWORD                 d;
1153         WINED3DLINEPATTERN    lp;
1154     } tmppattern;
1155     tmppattern.d = stateblock->renderState[WINED3DRS_LINEPATTERN];
1156
1157     TRACE("Line pattern: repeat %d bits %x\n", tmppattern.lp.wRepeatFactor, tmppattern.lp.wLinePattern);
1158
1159     if (tmppattern.lp.wRepeatFactor) {
1160         glLineStipple(tmppattern.lp.wRepeatFactor, tmppattern.lp.wLinePattern);
1161         checkGLcall("glLineStipple(repeat, linepattern)");
1162         glEnable(GL_LINE_STIPPLE);
1163         checkGLcall("glEnable(GL_LINE_STIPPLE);");
1164     } else {
1165         glDisable(GL_LINE_STIPPLE);
1166         checkGLcall("glDisable(GL_LINE_STIPPLE);");
1167     }
1168 }
1169
1170 static void state_zbias(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1171     union {
1172         DWORD d;
1173         float f;
1174     } tmpvalue;
1175
1176     if (stateblock->renderState[WINED3DRS_ZBIAS]) {
1177         tmpvalue.d = stateblock->renderState[WINED3DRS_ZBIAS];
1178         TRACE("ZBias value %f\n", tmpvalue.f);
1179         glPolygonOffset(0, -tmpvalue.f);
1180         checkGLcall("glPolygonOffset(0, -Value)");
1181         glEnable(GL_POLYGON_OFFSET_FILL);
1182         checkGLcall("glEnable(GL_POLYGON_OFFSET_FILL);");
1183         glEnable(GL_POLYGON_OFFSET_LINE);
1184         checkGLcall("glEnable(GL_POLYGON_OFFSET_LINE);");
1185         glEnable(GL_POLYGON_OFFSET_POINT);
1186         checkGLcall("glEnable(GL_POLYGON_OFFSET_POINT);");
1187     } else {
1188         glDisable(GL_POLYGON_OFFSET_FILL);
1189         checkGLcall("glDisable(GL_POLYGON_OFFSET_FILL);");
1190         glDisable(GL_POLYGON_OFFSET_LINE);
1191         checkGLcall("glDisable(GL_POLYGON_OFFSET_LINE);");
1192         glDisable(GL_POLYGON_OFFSET_POINT);
1193         checkGLcall("glDisable(GL_POLYGON_OFFSET_POINT);");
1194     }
1195 }
1196
1197
1198 static void state_normalize(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1199     if (stateblock->renderState[WINED3DRS_NORMALIZENORMALS]) {
1200         glEnable(GL_NORMALIZE);
1201         checkGLcall("glEnable(GL_NORMALIZE);");
1202     } else {
1203         glDisable(GL_NORMALIZE);
1204         checkGLcall("glDisable(GL_NORMALIZE);");
1205     }
1206 }
1207
1208 static void state_psize(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1209     union {
1210         DWORD d;
1211         float f;
1212     } tmpvalue;
1213
1214     /* FIXME: check that pointSize isn't outside glGetFloatv( GL_POINT_SIZE_MAX_ARB, &maxSize ); or -ve */
1215     tmpvalue.d = stateblock->renderState[WINED3DRS_POINTSIZE];
1216     TRACE("Set point size to %f\n", tmpvalue.f);
1217     glPointSize(tmpvalue.f);
1218     checkGLcall("glPointSize(...);");
1219 }
1220
1221 static void state_psizemin(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1222     union {
1223         DWORD d;
1224         float f;
1225     } tmpvalue;
1226
1227     tmpvalue.d = stateblock->renderState[WINED3DRS_POINTSIZE_MIN];
1228     if(GL_SUPPORT(ARB_POINT_PARAMETERS)) {
1229         GL_EXTCALL(glPointParameterfARB)(GL_POINT_SIZE_MIN_ARB, tmpvalue.f);
1230         checkGLcall("glPointParameterfARB(...");
1231     }
1232     else if(GL_SUPPORT(EXT_POINT_PARAMETERS)) {
1233         GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MIN_EXT, tmpvalue.f);
1234         checkGLcall("glPointParameterfEXT(...);");
1235     } else if(tmpvalue.f != 1.0) {
1236         FIXME("WINED3DRS_POINTSIZE_MIN not supported on this opengl, value is %f\n", tmpvalue.f);
1237     }
1238 }
1239
1240 static void state_psizemax(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1241     union {
1242         DWORD d;
1243         float f;
1244     } tmpvalue;
1245
1246     tmpvalue.d = stateblock->renderState[WINED3DRS_POINTSIZE_MAX];
1247     if(GL_SUPPORT(ARB_POINT_PARAMETERS)) {
1248         GL_EXTCALL(glPointParameterfARB)(GL_POINT_SIZE_MAX_ARB, tmpvalue.f);
1249         checkGLcall("glPointParameterfARB(...");
1250     }
1251     else if(GL_SUPPORT(EXT_POINT_PARAMETERS)) {
1252         GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MAX_EXT, tmpvalue.f);
1253         checkGLcall("glPointParameterfEXT(...);");
1254     } else if(tmpvalue.f != 64.0) {
1255         FIXME("WINED3DRS_POINTSIZE_MAX not supported on this opengl, value is %f\n", tmpvalue.f);
1256     }
1257 }
1258
1259 static void state_pscale(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1260     /* TODO: Group this with the viewport */
1261     /*
1262      * POINTSCALEENABLE controls how point size value is treated. If set to
1263      * true, the point size is scaled with respect to height of viewport.
1264      * When set to false point size is in pixels.
1265      *
1266      * http://msdn.microsoft.com/library/en-us/directx9_c/point_sprites.asp
1267      */
1268
1269     /* Default values */
1270     GLfloat att[3] = {1.0f, 0.0f, 0.0f};
1271
1272     /*
1273      * Minimum valid point size for OpenGL is 1.0f. For Direct3D it is 0.0f.
1274      * This means that OpenGL will clamp really small point sizes to 1.0f.
1275      * To correct for this we need to multiply by the scale factor when sizes
1276      * are less than 1.0f. scale_factor =  1.0f / point_size.
1277      */
1278     GLfloat pointSize = *((float*)&stateblock->renderState[WINED3DRS_POINTSIZE]);
1279     if(pointSize > 0.0f) {
1280         GLfloat scaleFactor;
1281
1282         if(pointSize < 1.0f) {
1283             scaleFactor = pointSize * pointSize;
1284         } else {
1285             scaleFactor = 1.0f;
1286         }
1287
1288         if(stateblock->renderState[WINED3DRS_POINTSCALEENABLE]) {
1289             att[0] = *((float*)&stateblock->renderState[WINED3DRS_POINTSCALE_A]) /
1290                     (stateblock->viewport.Height * stateblock->viewport.Height * scaleFactor);
1291             att[1] = *((float*)&stateblock->renderState[WINED3DRS_POINTSCALE_B]) /
1292                     (stateblock->viewport.Height * stateblock->viewport.Height * scaleFactor);
1293             att[2] = *((float*)&stateblock->renderState[WINED3DRS_POINTSCALE_C]) /
1294                     (stateblock->viewport.Height * stateblock->viewport.Height * scaleFactor);
1295         }
1296     }
1297
1298     if(GL_SUPPORT(ARB_POINT_PARAMETERS)) {
1299         GL_EXTCALL(glPointParameterfvARB)(GL_POINT_DISTANCE_ATTENUATION_ARB, att);
1300         checkGLcall("glPointParameterfvARB(GL_DISTANCE_ATTENUATION_ARB, ...");
1301     }
1302     else if(GL_SUPPORT(EXT_POINT_PARAMETERS)) {
1303         GL_EXTCALL(glPointParameterfvEXT)(GL_DISTANCE_ATTENUATION_EXT, att);
1304         checkGLcall("glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, ...");
1305     } else {
1306         TRACE("POINT_PARAMETERS not supported in this version of opengl\n");
1307     }
1308 }
1309
1310 static void state_colorwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1311     DWORD Value = stateblock->renderState[WINED3DRS_COLORWRITEENABLE];
1312
1313     TRACE("Color mask: r(%d) g(%d) b(%d) a(%d)\n",
1314         Value & WINED3DCOLORWRITEENABLE_RED   ? 1 : 0,
1315         Value & WINED3DCOLORWRITEENABLE_GREEN ? 1 : 0,
1316         Value & WINED3DCOLORWRITEENABLE_BLUE  ? 1 : 0,
1317         Value & WINED3DCOLORWRITEENABLE_ALPHA ? 1 : 0);
1318     glColorMask(Value & WINED3DCOLORWRITEENABLE_RED   ? GL_TRUE : GL_FALSE,
1319                 Value & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE,
1320                 Value & WINED3DCOLORWRITEENABLE_BLUE  ? GL_TRUE : GL_FALSE,
1321                 Value & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE);
1322     checkGLcall("glColorMask(...)");
1323
1324     /* depends on WINED3DRS_COLORWRITEENABLE. */
1325     if(stateblock->renderState[WINED3DRS_COLORWRITEENABLE1] != 0x0000000F ||
1326        stateblock->renderState[WINED3DRS_COLORWRITEENABLE2] != 0x0000000F ||
1327        stateblock->renderState[WINED3DRS_COLORWRITEENABLE3] != 0x0000000F ) {
1328         ERR("(WINED3DRS_COLORWRITEENABLE1/2/3,%d,%d,%d) not yet implemented. Missing of cap D3DPMISCCAPS_INDEPENDENTWRITEMASKS wasn't honored?\n",
1329             stateblock->renderState[WINED3DRS_COLORWRITEENABLE1],
1330             stateblock->renderState[WINED3DRS_COLORWRITEENABLE2],
1331             stateblock->renderState[WINED3DRS_COLORWRITEENABLE3]);
1332     }
1333 }
1334
1335 static void state_localviewer(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1336     if(stateblock->renderState[WINED3DRS_LOCALVIEWER]) {
1337         glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
1338         checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1)");
1339     } else {
1340         glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0);
1341         checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0)");
1342     }
1343 }
1344
1345 static void state_lastpixel(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1346     if(stateblock->renderState[WINED3DRS_LASTPIXEL]) {
1347         TRACE("Last Pixel Drawing Enabled\n");
1348     } else {
1349         static BOOL first = TRUE;
1350         if(first) {
1351             FIXME("Last Pixel Drawing Disabled, not handled yet\n");
1352             first = FALSE;
1353         } else {
1354             TRACE("Last Pixel Drawing Disabled, not handled yet\n");
1355         }
1356     }
1357 }
1358
1359 static void state_pointsprite(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1360     /* TODO: NV_POINT_SPRITE */
1361     if (!GL_SUPPORT(ARB_POINT_SPRITE)) {
1362         TRACE("Point sprites not supported\n");
1363         return;
1364     }
1365
1366     if (stateblock->renderState[WINED3DRS_POINTSPRITEENABLE]) {
1367         glEnable(GL_POINT_SPRITE_ARB);
1368         checkGLcall("glEnable(GL_POINT_SPRITE_ARB)\n");
1369     } else {
1370         glDisable(GL_POINT_SPRITE_ARB);
1371         checkGLcall("glDisable(GL_POINT_SPRITE_ARB)\n");
1372     }
1373 }
1374
1375 static void state_wrap(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1376     /**
1377      http://www.cosc.brocku.ca/Offerings/3P98/course/lectures/texture/
1378      http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/directx9_c/directx/graphics/programmingguide/FixedFunction/Textures/texturewrapping.asp
1379      http://www.gamedev.net/reference/programming/features/rendererdll3/page2.asp
1380      Descussion that ways to turn on WRAPing to solve an opengl conversion problem.
1381      http://www.flipcode.org/cgi-bin/fcmsg.cgi?thread_show=10248
1382
1383      so far as I can tell, wrapping and texture-coordinate generate go hand in hand,
1384      */
1385     TRACE("Stub\n");
1386     if(stateblock->renderState[WINED3DRS_WRAP0] ||
1387        stateblock->renderState[WINED3DRS_WRAP1] ||
1388        stateblock->renderState[WINED3DRS_WRAP2] ||
1389        stateblock->renderState[WINED3DRS_WRAP3] ||
1390        stateblock->renderState[WINED3DRS_WRAP4] ||
1391        stateblock->renderState[WINED3DRS_WRAP5] ||
1392        stateblock->renderState[WINED3DRS_WRAP6] ||
1393        stateblock->renderState[WINED3DRS_WRAP7] ||
1394        stateblock->renderState[WINED3DRS_WRAP8] ||
1395        stateblock->renderState[WINED3DRS_WRAP9] ||
1396        stateblock->renderState[WINED3DRS_WRAP10] ||
1397        stateblock->renderState[WINED3DRS_WRAP11] ||
1398        stateblock->renderState[WINED3DRS_WRAP12] ||
1399        stateblock->renderState[WINED3DRS_WRAP13] ||
1400        stateblock->renderState[WINED3DRS_WRAP14] ||
1401        stateblock->renderState[WINED3DRS_WRAP15] ) {
1402         FIXME("(WINED3DRS_WRAP0) Texture wraping not yet supported\n");
1403     }
1404 }
1405
1406 static void state_multisampleaa(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1407     if( GL_SUPPORT(ARB_MULTISAMPLE) ) {
1408         if(stateblock->renderState[WINED3DRS_MULTISAMPLEANTIALIAS]) {
1409             glEnable(GL_MULTISAMPLE_ARB);
1410             checkGLcall("glEnable(GL_MULTISAMPLE_ARB)");
1411         } else {
1412             glDisable(GL_MULTISAMPLE_ARB);
1413             checkGLcall("glDisable(GL_MULTISAMPLE_ARB)");
1414         }
1415     } else {
1416         if(stateblock->renderState[WINED3DRS_MULTISAMPLEANTIALIAS]) {
1417             WARN("Multisample antialiasing not supported by gl\n");
1418         }
1419     }
1420 }
1421
1422 static void state_scissor(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1423     if(stateblock->renderState[WINED3DRS_SCISSORTESTENABLE]) {
1424         glEnable(GL_SCISSOR_TEST);
1425         checkGLcall("glEnable(GL_SCISSOR_TEST)");
1426     } else {
1427         glDisable(GL_SCISSOR_TEST);
1428         checkGLcall("glDisable(GL_SCISSOR_TEST)");
1429     }
1430 }
1431
1432 static void state_depthbias(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1433     union {
1434         DWORD d;
1435         float f;
1436     } tmpvalue;
1437
1438     if(stateblock->renderState[WINED3DRS_SLOPESCALEDEPTHBIAS] ||
1439        stateblock->renderState[WINED3DRS_DEPTHBIAS]) {
1440         tmpvalue.d = stateblock->renderState[WINED3DRS_SLOPESCALEDEPTHBIAS];
1441         glEnable(GL_POLYGON_OFFSET_FILL);
1442         checkGLcall("glEnable(GL_POLYGON_OFFSET_FILL)");
1443         glPolygonOffset(tmpvalue.f, *((float*)&stateblock->renderState[WINED3DRS_DEPTHBIAS]));
1444         checkGLcall("glPolygonOffset(...)");
1445     } else {
1446         glDisable(GL_POLYGON_OFFSET_FILL);
1447         checkGLcall("glDisable(GL_POLYGON_OFFSET_FILL)");
1448     }
1449 }
1450
1451 static void state_perspective(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1452     if (stateblock->renderState[WINED3DRS_TEXTUREPERSPECTIVE]) {
1453         glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1454         checkGLcall("glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)");
1455     } else {
1456         glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
1457         checkGLcall("glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST)");
1458     }
1459 }
1460
1461 static void state_stippledalpha(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1462     TRACE("Stub\n");
1463     if (stateblock->renderState[WINED3DRS_STIPPLEDALPHA])
1464         FIXME(" Stippled Alpha not supported yet.\n");
1465 }
1466
1467 static void state_antialias(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1468     TRACE("Stub\n");
1469     if (stateblock->renderState[WINED3DRS_ANTIALIAS])
1470         FIXME(" Antialias not supported yet.\n");
1471 }
1472
1473 static void state_multisampmask(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1474     TRACE("Stub\n");
1475     if (stateblock->renderState[WINED3DRS_MULTISAMPLEMASK] != 0xFFFFFFFF)
1476         FIXME("(WINED3DRS_MULTISAMPLEMASK,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_MULTISAMPLEMASK]);
1477 }
1478
1479 static void state_patchedgestyle(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1480     TRACE("Stub\n");
1481     if (stateblock->renderState[WINED3DRS_PATCHEDGESTYLE] != WINED3DPATCHEDGE_DISCRETE)
1482         FIXME("(WINED3DRS_PATCHEDGESTYLE,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_PATCHEDGESTYLE]);
1483 }
1484
1485 static void state_patchsegments(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1486     union {
1487         DWORD d;
1488         float f;
1489     } tmpvalue;
1490     tmpvalue.f = 1.0f;
1491
1492     TRACE("Stub\n");
1493     if (stateblock->renderState[WINED3DRS_PATCHSEGMENTS] != tmpvalue.d)
1494     {
1495         static BOOL displayed = FALSE;
1496
1497         tmpvalue.d = stateblock->renderState[WINED3DRS_PATCHSEGMENTS];
1498         if(!displayed)
1499             FIXME("(WINED3DRS_PATCHSEGMENTS,%f) not yet implemented\n", tmpvalue.f);
1500
1501         displayed = TRUE;
1502     }
1503 }
1504
1505 static void state_positiondegree(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1506     TRACE("Stub\n");
1507     if (stateblock->renderState[WINED3DRS_POSITIONDEGREE] != WINED3DDEGREE_CUBIC)
1508         FIXME("(WINED3DRS_POSITIONDEGREE,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_POSITIONDEGREE]);
1509 }
1510
1511 static void state_normaldegree(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1512     TRACE("Stub\n");
1513     if (stateblock->renderState[WINED3DRS_NORMALDEGREE] != WINED3DDEGREE_LINEAR)
1514         FIXME("(WINED3DRS_NORMALDEGREE,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_NORMALDEGREE]);
1515 }
1516
1517 static void state_tessellation(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1518     TRACE("Stub\n");
1519     if(stateblock->renderState[WINED3DRS_ENABLEADAPTIVETESSELLATION])
1520         FIXME("(WINED3DRS_ENABLEADAPTIVETESSELLATION,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_ENABLEADAPTIVETESSELLATION]);
1521 }
1522
1523
1524 static void state_srgbwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1525     if(stateblock->renderState[WINED3DRS_SRGBWRITEENABLE])
1526         FIXME("Render state WINED3DRS_SRGBWRITEENABLE not yet implemented\n");
1527 }
1528
1529 static void state_separateblend(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1530     TRACE("Stub\n");
1531     if(stateblock->renderState[WINED3DRS_SEPARATEALPHABLENDENABLE])
1532         FIXME("(WINED3DRS_SEPARATEALPHABLENDENABLE,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_SEPARATEALPHABLENDENABLE]);
1533 }
1534
1535 static void state_wrapu(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1536     if(stateblock->renderState[WINED3DRS_WRAPU]) {
1537         FIXME("Render state WINED3DRS_WRAPU not implemented yet\n");
1538     }
1539 }
1540
1541 static void state_wrapv(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1542     if(stateblock->renderState[WINED3DRS_WRAPV]) {
1543         FIXME("Render state WINED3DRS_WRAPV not implemented yet\n");
1544     }
1545 }
1546
1547 static void state_monoenable(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1548     if(stateblock->renderState[WINED3DRS_MONOENABLE]) {
1549         FIXME("Render state WINED3DRS_MONOENABLE not implemented yet\n");
1550     }
1551 }
1552
1553 static void state_rop2(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1554     if(stateblock->renderState[WINED3DRS_ROP2]) {
1555         FIXME("Render state WINED3DRS_ROP2 not implemented yet\n");
1556     }
1557 }
1558
1559 static void state_planemask(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1560     if(stateblock->renderState[WINED3DRS_PLANEMASK]) {
1561         FIXME("Render state WINED3DRS_PLANEMASK not implemented yet\n");
1562     }
1563 }
1564
1565 static void state_subpixel(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1566     if(stateblock->renderState[WINED3DRS_SUBPIXEL]) {
1567         FIXME("Render state WINED3DRS_SUBPIXEL not implemented yet\n");
1568     }
1569 }
1570
1571 static void state_subpixelx(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1572     if(stateblock->renderState[WINED3DRS_SUBPIXELX]) {
1573         FIXME("Render state WINED3DRS_SUBPIXELX not implemented yet\n");
1574     }
1575 }
1576
1577 static void state_stippleenable(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1578     if(stateblock->renderState[WINED3DRS_STIPPLEENABLE]) {
1579         FIXME("Render state WINED3DRS_STIPPLEENABLE not implemented yet\n");
1580     }
1581 }
1582
1583 static void state_bordercolor(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1584     if(stateblock->renderState[WINED3DRS_BORDERCOLOR]) {
1585         FIXME("Render state WINED3DRS_BORDERCOLOR not implemented yet\n");
1586     }
1587 }
1588
1589 static void state_mipmaplodbias(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1590     if(stateblock->renderState[WINED3DRS_MIPMAPLODBIAS]) {
1591         FIXME("Render state WINED3DRS_MIPMAPLODBIAS not implemented yet\n");
1592     }
1593 }
1594
1595 static void state_anisotropy(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1596     if(stateblock->renderState[WINED3DRS_ANISOTROPY]) {
1597         FIXME("Render state WINED3DRS_ANISOTROPY not implemented yet\n");
1598     }
1599 }
1600
1601 static void state_flushbatch(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1602     if(stateblock->renderState[WINED3DRS_FLUSHBATCH]) {
1603         FIXME("Render state WINED3DRS_FLUSHBATCH not implemented yet\n");
1604     }
1605 }
1606
1607 static void state_translucentsi(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1608     if(stateblock->renderState[WINED3DRS_TRANSLUCENTSORTINDEPENDENT]) {
1609         FIXME("Render state WINED3DRS_TRANSLUCENTSORTINDEPENDENT not implemented yet\n");
1610     }
1611 }
1612
1613 static void state_extents(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1614     if(stateblock->renderState[WINED3DRS_EXTENTS]) {
1615         FIXME("Render state WINED3DRS_EXTENTS not implemented yet\n");
1616     }
1617 }
1618
1619 static void state_ckeyblend(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1620     if(stateblock->renderState[WINED3DRS_COLORKEYBLENDENABLE]) {
1621         FIXME("Render state WINED3DRS_COLORKEYBLENDENABLE not implemented yet\n");
1622     }
1623 }
1624
1625 /* Activates the texture dimension according to the bound D3D texture.
1626  * Does not care for the colorop or correct gl texture unit(when using nvrc)
1627  * Requires the caller to activate the correct unit before
1628  */
1629 static void activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1630     BOOL bumpmap = FALSE;
1631
1632     if(stage > 0 && (stateblock->textureState[stage - 1][WINED3DTSS_COLOROP] == WINED3DTOP_BUMPENVMAPLUMINANCE ||
1633                      stateblock->textureState[stage - 1][WINED3DTSS_COLOROP] == WINED3DTOP_BUMPENVMAP)) {
1634         bumpmap = TRUE;
1635         context->texShaderBumpMap |= (1 << stage);
1636     } else {
1637         context->texShaderBumpMap &= ~(1 << stage);
1638     }
1639
1640     if(stateblock->textures[stage]) {
1641         switch(stateblock->textureDimensions[stage]) {
1642             case GL_TEXTURE_2D:
1643                 if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
1644                     glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, bumpmap ? GL_OFFSET_TEXTURE_2D_NV : GL_TEXTURE_2D);
1645                 } else {
1646                     glDisable(GL_TEXTURE_3D);
1647                     checkGLcall("glDisable(GL_TEXTURE_3D)");
1648                     if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
1649                         glDisable(GL_TEXTURE_CUBE_MAP_ARB);
1650                         checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
1651                     }
1652                     glEnable(GL_TEXTURE_2D);
1653                     checkGLcall("glEnable(GL_TEXTURE_2D)");
1654                 }
1655                 break;
1656             case GL_TEXTURE_3D:
1657                 if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
1658                     glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_3D);
1659                 } else {
1660                     if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
1661                         glDisable(GL_TEXTURE_CUBE_MAP_ARB);
1662                         checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
1663                     }
1664                     glDisable(GL_TEXTURE_2D);
1665                     checkGLcall("glDisable(GL_TEXTURE_2D)");
1666                     glEnable(GL_TEXTURE_3D);
1667                     checkGLcall("glEnable(GL_TEXTURE_3D)");
1668                 }
1669                 break;
1670             case GL_TEXTURE_CUBE_MAP_ARB:
1671                 if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
1672                     glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_CUBE_MAP_ARB);
1673                 } else {
1674                     glDisable(GL_TEXTURE_2D);
1675                     checkGLcall("glDisable(GL_TEXTURE_2D)");
1676                     glDisable(GL_TEXTURE_3D);
1677                     checkGLcall("glDisable(GL_TEXTURE_3D)");
1678                     glEnable(GL_TEXTURE_CUBE_MAP_ARB);
1679                     checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
1680                 }
1681               break;
1682         }
1683     } else {
1684         if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
1685             glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_NONE);
1686         } else {
1687             glEnable(GL_TEXTURE_2D);
1688             checkGLcall("glEnable(GL_TEXTURE_2D)");
1689             glDisable(GL_TEXTURE_3D);
1690             checkGLcall("glDisable(GL_TEXTURE_3D)");
1691             if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
1692                 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
1693                 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
1694             }
1695             /* Binding textures is done by samplers. A dummy texture will be bound */
1696         }
1697     }
1698 }
1699
1700 static void tex_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1701     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
1702     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage];
1703     BOOL tex_used = stateblock->wineD3DDevice->fixed_function_usage_map[stage];
1704
1705     TRACE("Setting color op for stage %d\n", stage);
1706
1707     if (stateblock->pixelShader && stateblock->wineD3DDevice->ps_selected_mode != SHADER_NONE &&
1708         ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.function) {
1709         /* Using a pixel shader? Don't care for anything here, the shader applying does it */
1710         return;
1711     }
1712
1713     if (stage != mapped_stage) WARN("Using non 1:1 mapping: %d -> %d!\n", stage, mapped_stage);
1714
1715     if (mapped_stage != -1) {
1716         if (GL_SUPPORT(ARB_MULTITEXTURE)) {
1717             if (tex_used && mapped_stage >= GL_LIMITS(textures)) {
1718                 FIXME("Attempt to enable unsupported stage!\n");
1719                 return;
1720             }
1721             GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
1722             checkGLcall("glActiveTextureARB");
1723         } else if (stage > 0) {
1724             WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
1725             return;
1726         }
1727     }
1728
1729     if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
1730         if(stateblock->lowest_disabled_stage > 0) {
1731             glEnable(GL_REGISTER_COMBINERS_NV);
1732             GL_EXTCALL(glCombinerParameteriNV(GL_NUM_GENERAL_COMBINERS_NV, stateblock->lowest_disabled_stage));
1733         } else {
1734             glDisable(GL_REGISTER_COMBINERS_NV);
1735         }
1736     }
1737     if(stage >= stateblock->lowest_disabled_stage) {
1738         TRACE("Stage disabled\n");
1739         if (mapped_stage != -1) {
1740             /* Disable everything here */
1741             glDisable(GL_TEXTURE_2D);
1742             checkGLcall("glDisable(GL_TEXTURE_2D)");
1743             glDisable(GL_TEXTURE_3D);
1744             checkGLcall("glDisable(GL_TEXTURE_3D)");
1745             if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
1746                 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
1747                 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
1748             }
1749             if(GL_SUPPORT(NV_TEXTURE_SHADER2) && mapped_stage < GL_LIMITS(textures)) {
1750                 glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_NONE);
1751             }
1752         }
1753         /* All done */
1754         return;
1755     }
1756
1757     /* The sampler will also activate the correct texture dimensions, so no need to do it here
1758      * if the sampler for this stage is dirty
1759      */
1760     if(!isStateDirty(context, STATE_SAMPLER(stage))) {
1761         if (tex_used) activate_dimensions(stage, stateblock, context);
1762     }
1763
1764     /* Set the texture combiners */
1765     if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
1766         set_tex_op_nvrc((IWineD3DDevice *)stateblock->wineD3DDevice, FALSE, stage,
1767                          stateblock->textureState[stage][WINED3DTSS_COLOROP],
1768                          stateblock->textureState[stage][WINED3DTSS_COLORARG1],
1769                          stateblock->textureState[stage][WINED3DTSS_COLORARG2],
1770                          stateblock->textureState[stage][WINED3DTSS_COLORARG0],
1771                          mapped_stage);
1772
1773         /* In register combiners bump mapping is done in the stage AFTER the one that has the bump map operation set,
1774          * thus the texture shader may have to be updated
1775          */
1776         if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
1777             BOOL usesBump = (stateblock->textureState[stage][WINED3DTSS_COLOROP] == WINED3DTOP_BUMPENVMAPLUMINANCE ||
1778                              stateblock->textureState[stage][WINED3DTSS_COLOROP] == WINED3DTOP_BUMPENVMAP) ? TRUE : FALSE;
1779             BOOL usedBump = (context->texShaderBumpMap & 1 << (stage + 1)) ? TRUE : FALSE;
1780             if(usesBump != usedBump) {
1781                 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage + 1));
1782                 checkGLcall("glActiveTextureARB");
1783                 activate_dimensions(stage + 1, stateblock, context);
1784                 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
1785                 checkGLcall("glActiveTextureARB");
1786             }
1787         }
1788     } else {
1789         set_tex_op((IWineD3DDevice *)stateblock->wineD3DDevice, FALSE, stage,
1790                     stateblock->textureState[stage][WINED3DTSS_COLOROP],
1791                     stateblock->textureState[stage][WINED3DTSS_COLORARG1],
1792                     stateblock->textureState[stage][WINED3DTSS_COLORARG2],
1793                     stateblock->textureState[stage][WINED3DTSS_COLORARG0]);
1794     }
1795 }
1796
1797 static void tex_alphaop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1798     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
1799     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage];
1800     BOOL tex_used = stateblock->wineD3DDevice->fixed_function_usage_map[stage];
1801     DWORD op, arg1, arg2, arg0;
1802
1803     TRACE("Setting alpha op for stage %d\n", stage);
1804     /* Do not care for enabled / disabled stages, just assign the settigns. colorop disables / enables required stuff */
1805     if (mapped_stage != -1) {
1806         if (GL_SUPPORT(ARB_MULTITEXTURE)) {
1807             if (tex_used && mapped_stage >= GL_LIMITS(textures)) {
1808                 FIXME("Attempt to enable unsupported stage!\n");
1809                 return;
1810             }
1811             GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
1812             checkGLcall("glActiveTextureARB");
1813         } else if (stage > 0) {
1814             /* We can't do anything here */
1815             WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
1816             return;
1817         }
1818     }
1819
1820     op = stateblock->textureState[stage][WINED3DTSS_ALPHAOP];
1821     arg1 = stateblock->textureState[stage][WINED3DTSS_ALPHAARG1];
1822     arg2 = stateblock->textureState[stage][WINED3DTSS_ALPHAARG2];
1823     arg0 = stateblock->textureState[stage][WINED3DTSS_ALPHAARG0];
1824
1825     if(stateblock->renderState[WINED3DRS_COLORKEYENABLE] && stage == 0 &&
1826        stateblock->textures[0] && stateblock->textureDimensions[0] == GL_TEXTURE_2D) {
1827         IWineD3DSurfaceImpl *surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *) stateblock->textures[0])->surfaces[0];
1828
1829         if(surf->CKeyFlags & WINEDDSD_CKSRCBLT &&
1830            getFormatDescEntry(surf->resource.format, NULL, NULL)->alphaMask == 0x00000000) {
1831
1832             /* Color keying needs to pass alpha values from the texture through to have the alpha test work properly.
1833              * On the other hand applications can still use texture combiners apparently. This code takes care that apps
1834              * cannot remove the texture's alpha channel entirely.
1835              *
1836              * The fixup is required for Prince of Persia 3D(prison bars), while Moto racer 2 requires D3DTOP_MODULATE to work
1837              * on color keyed surfaces.
1838              *
1839              * What to do with multitexturing? So far no app has been found that uses color keying with multitexturing
1840              */
1841             if(op == WINED3DTOP_DISABLE) op = WINED3DTOP_SELECTARG1;
1842             if(op == WINED3DTOP_SELECTARG1) arg1 = WINED3DTA_TEXTURE;
1843             else if(op == WINED3DTOP_SELECTARG2) arg2 = WINED3DTA_TEXTURE;
1844         }
1845     }
1846
1847     TRACE("Setting alpha op for stage %d\n", stage);
1848     if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
1849         set_tex_op_nvrc((IWineD3DDevice *)stateblock->wineD3DDevice, TRUE, stage,
1850                          op, arg1, arg2, arg0,
1851                          mapped_stage);
1852     } else {
1853         set_tex_op((IWineD3DDevice *)stateblock->wineD3DDevice, TRUE, stage,
1854                     op, arg1, arg2, arg0);
1855     }
1856 }
1857
1858 static void transform_texture(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1859     DWORD texUnit = state - STATE_TRANSFORM(WINED3DTS_TEXTURE0);
1860     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[texUnit];
1861
1862     /* Ignore this when a vertex shader is used, or if the streams aren't sorted out yet */
1863     if(stateblock->vertexShader ||
1864        isStateDirty(context, STATE_VDECL)) {
1865         TRACE("Using a vertex shader, or stream sources not sorted out yet, skipping\n");
1866         return;
1867     }
1868
1869     if (mapped_stage < 0) return;
1870
1871     if (GL_SUPPORT(ARB_MULTITEXTURE)) {
1872         if(mapped_stage >= GL_LIMITS(textures)) {
1873             return;
1874         }
1875         GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
1876         checkGLcall("glActiveTextureARB");
1877     } else if (mapped_stage > 0) {
1878         /* We can't do anything here */
1879         WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
1880         return;
1881     }
1882
1883     set_texture_matrix((float *)&stateblock->transforms[WINED3DTS_TEXTURE0 + texUnit].u.m[0][0],
1884                         stateblock->textureState[texUnit][WINED3DTSS_TEXTURETRANSFORMFLAGS],
1885                         (stateblock->textureState[texUnit][WINED3DTSS_TEXCOORDINDEX] & 0xFFFF0000) != WINED3DTSS_TCI_PASSTHRU,
1886                         context->last_was_rhw,
1887                         stateblock->wineD3DDevice->strided_streams.u.s.texCoords[texUnit].dwStride ?
1888                             stateblock->wineD3DDevice->strided_streams.u.s.texCoords[texUnit].dwType:
1889                             WINED3DDECLTYPE_UNUSED);
1890
1891 }
1892
1893 static void unloadTexCoords(IWineD3DStateBlockImpl *stateblock) {
1894     int texture_idx;
1895
1896     for (texture_idx = 0; texture_idx < GL_LIMITS(texture_stages); ++texture_idx) {
1897         GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + texture_idx));
1898         glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1899     }
1900 }
1901
1902 static void loadTexCoords(IWineD3DStateBlockImpl *stateblock, WineDirect3DVertexStridedData *sd, GLint *curVBO) {
1903     UINT *offset = stateblock->streamOffset;
1904     unsigned int mapped_stage = 0;
1905     unsigned int textureNo = 0;
1906
1907     /* The code below uses glClientActiveTexture and glMultiTexCoord* which are all part of the GL_ARB_multitexture extension. */
1908     /* Abort if we don't support the extension. */
1909     if (!GL_SUPPORT(ARB_MULTITEXTURE)) {
1910         FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
1911         return;
1912     }
1913
1914     for (textureNo = 0; textureNo < GL_LIMITS(texture_stages); ++textureNo) {
1915         int coordIdx = stateblock->textureState[textureNo][WINED3DTSS_TEXCOORDINDEX];
1916
1917         mapped_stage = stateblock->wineD3DDevice->texUnitMap[textureNo];
1918         if (mapped_stage == -1) continue;
1919
1920         if (coordIdx < MAX_TEXTURES && (sd->u.s.texCoords[coordIdx].lpData || sd->u.s.texCoords[coordIdx].VBO)) {
1921             TRACE("Setting up texture %u, idx %d, cordindx %u, data %p\n",
1922                     textureNo, mapped_stage, coordIdx, sd->u.s.texCoords[coordIdx].lpData);
1923
1924             if (*curVBO != sd->u.s.texCoords[coordIdx].VBO) {
1925                 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.texCoords[coordIdx].VBO));
1926                 checkGLcall("glBindBufferARB");
1927                 *curVBO = sd->u.s.texCoords[coordIdx].VBO;
1928             }
1929
1930             GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
1931             checkGLcall("glClientActiveTextureARB");
1932
1933             /* The coords to supply depend completely on the fvf / vertex shader */
1934             glTexCoordPointer(
1935                     WINED3D_ATR_SIZE(sd->u.s.texCoords[coordIdx].dwType),
1936                     WINED3D_ATR_GLTYPE(sd->u.s.texCoords[coordIdx].dwType),
1937                     sd->u.s.texCoords[coordIdx].dwStride,
1938                     sd->u.s.texCoords[coordIdx].lpData + stateblock->loadBaseVertexIndex * sd->u.s.texCoords[coordIdx].dwStride + offset[sd->u.s.texCoords[coordIdx].streamNo]);
1939             glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1940         } else {
1941             GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + mapped_stage, 0, 0, 0, 1));
1942         }
1943     }
1944     if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
1945         /* The number of the mapped stages increases monotonically, so it's fine to use the last used one */
1946         for (textureNo = mapped_stage + 1; textureNo < GL_LIMITS(textures); ++textureNo) {
1947             GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, 0, 0, 0, 1));
1948         }
1949     }
1950 }
1951
1952 static void tex_coordindex(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1953     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
1954     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage];
1955
1956     if (mapped_stage == -1) {
1957         TRACE("No texture unit mapped to stage %d. Skipping texture coordinates.\n", stage);
1958         return;
1959     }
1960
1961     if (GL_SUPPORT(ARB_MULTITEXTURE)) {
1962         if(mapped_stage >= GL_LIMITS(fragment_samplers)) {
1963             return;
1964         }
1965         GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
1966         checkGLcall("glActiveTextureARB");
1967     } else if (stage > 0) {
1968         /* We can't do anything here */
1969         WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
1970         return;
1971     }
1972
1973     /* Values 0-7 are indexes into the FVF tex coords - See comments in DrawPrimitive
1974      *
1975      * FIXME: From MSDN: The WINED3DTSS_TCI_* flags are mutually exclusive. If you include
1976      * one flag, you can still specify an index value, which the system uses to
1977      * determine the texture wrapping mode.
1978      * eg. SetTextureStageState( 0, WINED3DTSS_TEXCOORDINDEX, WINED3DTSS_TCI_CAMERASPACEPOSITION | 1 );
1979      * means use the vertex position (camera-space) as the input texture coordinates
1980      * for this texture stage, and the wrap mode set in the WINED3DRS_WRAP1 render
1981      * state. We do not (yet) support the WINED3DRENDERSTATE_WRAPx values, nor tie them up
1982      * to the TEXCOORDINDEX value
1983      */
1984
1985     /*
1986      * Be careful the value of the mask 0xF0000 come from d3d8types.h infos
1987      */
1988     switch (stateblock->textureState[stage][WINED3DTSS_TEXCOORDINDEX] & 0xFFFF0000) {
1989     case WINED3DTSS_TCI_PASSTHRU:
1990         /*Use the specified texture coordinates contained within the vertex format. This value resolves to zero.*/
1991         glDisable(GL_TEXTURE_GEN_S);
1992         glDisable(GL_TEXTURE_GEN_T);
1993         glDisable(GL_TEXTURE_GEN_R);
1994         glDisable(GL_TEXTURE_GEN_Q);
1995         checkGLcall("glDisable(GL_TEXTURE_GEN_S,T,R,Q)");
1996         break;
1997
1998     case WINED3DTSS_TCI_CAMERASPACEPOSITION:
1999         /* CameraSpacePosition means use the vertex position, transformed to camera space,
2000          * as the input texture coordinates for this stage's texture transformation. This
2001          * equates roughly to EYE_LINEAR
2002          */
2003         {
2004             float s_plane[] = { 1.0, 0.0, 0.0, 0.0 };
2005             float t_plane[] = { 0.0, 1.0, 0.0, 0.0 };
2006             float r_plane[] = { 0.0, 0.0, 1.0, 0.0 };
2007             float q_plane[] = { 0.0, 0.0, 0.0, 1.0 };
2008             TRACE("WINED3DTSS_TCI_CAMERASPACEPOSITION - Set eye plane\n");
2009
2010             glMatrixMode(GL_MODELVIEW);
2011             glPushMatrix();
2012             glLoadIdentity();
2013             glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
2014             glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
2015             glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
2016             glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
2017             glPopMatrix();
2018
2019             TRACE("WINED3DTSS_TCI_CAMERASPACEPOSITION - Set GL_TEXTURE_GEN_x and GL_x, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR\n");
2020             glEnable(GL_TEXTURE_GEN_S);
2021             checkGLcall("glEnable(GL_TEXTURE_GEN_S);");
2022             glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
2023             checkGLcall("glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)");
2024             glEnable(GL_TEXTURE_GEN_T);
2025             checkGLcall("glEnable(GL_TEXTURE_GEN_T);");
2026             glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
2027             checkGLcall("glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)");
2028             glEnable(GL_TEXTURE_GEN_R);
2029             checkGLcall("glEnable(GL_TEXTURE_GEN_R);");
2030             glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
2031             checkGLcall("glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)");
2032         }
2033         break;
2034
2035     case WINED3DTSS_TCI_CAMERASPACENORMAL:
2036         {
2037             if (GL_SUPPORT(NV_TEXGEN_REFLECTION)) {
2038                 float s_plane[] = { 1.0, 0.0, 0.0, 0.0 };
2039                 float t_plane[] = { 0.0, 1.0, 0.0, 0.0 };
2040                 float r_plane[] = { 0.0, 0.0, 1.0, 0.0 };
2041                 float q_plane[] = { 0.0, 0.0, 0.0, 1.0 };
2042                 TRACE("WINED3DTSS_TCI_CAMERASPACENORMAL - Set eye plane\n");
2043
2044                 glMatrixMode(GL_MODELVIEW);
2045                 glPushMatrix();
2046                 glLoadIdentity();
2047                 glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
2048                 glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
2049                 glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
2050                 glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
2051                 glPopMatrix();
2052
2053                 glEnable(GL_TEXTURE_GEN_S);
2054                 checkGLcall("glEnable(GL_TEXTURE_GEN_S);");
2055                 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
2056                 checkGLcall("glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV)");
2057                 glEnable(GL_TEXTURE_GEN_T);
2058                 checkGLcall("glEnable(GL_TEXTURE_GEN_T);");
2059                 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
2060                 checkGLcall("glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV)");
2061                 glEnable(GL_TEXTURE_GEN_R);
2062                 checkGLcall("glEnable(GL_TEXTURE_GEN_R);");
2063                 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
2064                 checkGLcall("glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV)");
2065             }
2066         }
2067         break;
2068
2069     case WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR:
2070         {
2071             if (GL_SUPPORT(NV_TEXGEN_REFLECTION)) {
2072             float s_plane[] = { 1.0, 0.0, 0.0, 0.0 };
2073             float t_plane[] = { 0.0, 1.0, 0.0, 0.0 };
2074             float r_plane[] = { 0.0, 0.0, 1.0, 0.0 };
2075             float q_plane[] = { 0.0, 0.0, 0.0, 1.0 };
2076             TRACE("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Set eye plane\n");
2077
2078             glMatrixMode(GL_MODELVIEW);
2079             glPushMatrix();
2080             glLoadIdentity();
2081             glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
2082             glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
2083             glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
2084             glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
2085             glPopMatrix();
2086
2087             glEnable(GL_TEXTURE_GEN_S);
2088             checkGLcall("glEnable(GL_TEXTURE_GEN_S);");
2089             glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
2090             checkGLcall("glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV)");
2091             glEnable(GL_TEXTURE_GEN_T);
2092             checkGLcall("glEnable(GL_TEXTURE_GEN_T);");
2093             glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
2094             checkGLcall("glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV)");
2095             glEnable(GL_TEXTURE_GEN_R);
2096             checkGLcall("glEnable(GL_TEXTURE_GEN_R);");
2097             glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
2098             checkGLcall("glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV)");
2099             }
2100         }
2101         break;
2102
2103     /* Unhandled types: */
2104     default:
2105         /* Todo: */
2106         /* ? disable GL_TEXTURE_GEN_n ? */
2107         glDisable(GL_TEXTURE_GEN_S);
2108         glDisable(GL_TEXTURE_GEN_T);
2109         glDisable(GL_TEXTURE_GEN_R);
2110         glDisable(GL_TEXTURE_GEN_Q);
2111         FIXME("Unhandled WINED3DTSS_TEXCOORDINDEX %x\n", stateblock->textureState[stage][WINED3DTSS_TEXCOORDINDEX]);
2112         break;
2113     }
2114
2115     /* Update the texture matrix */
2116     if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_TEXTURE0 + stage))) {
2117         transform_texture(STATE_TRANSFORM(WINED3DTS_TEXTURE0 + stage), stateblock, context);
2118     }
2119
2120     if(!isStateDirty(context, STATE_VDECL) && context->namedArraysLoaded) {
2121         /* Reload the arrays if we are using fixed function arrays to reflect the selected coord input
2122          * source. Call loadTexCoords directly because there is no need to reparse the vertex declaration
2123          * and do all the things linked to it
2124          * TODO: Tidy that up to reload only the arrays of the changed unit
2125          */
2126         GLint curVBO = GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT) ? -1 : 0;
2127
2128         unloadTexCoords(stateblock);
2129         loadTexCoords(stateblock, &stateblock->wineD3DDevice->strided_streams, &curVBO);
2130     }
2131 }
2132
2133 static void tex_bumpenvlscale(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2134     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
2135     union {
2136         DWORD d;
2137         float f;
2138     } tmpvalue;
2139
2140     tmpvalue.d = stateblock->textureState[stage][WINED3DTSS_BUMPENVLSCALE];
2141     if(tmpvalue.f != 0.0) {
2142         FIXME("WINED3DTSS_BUMPENVLSCALE not supported yet\n");
2143     }
2144 }
2145
2146 static void tex_bumpenvloffset(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2147     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
2148     union {
2149         DWORD d;
2150         float f;
2151     } tmpvalue;
2152
2153     tmpvalue.d = stateblock->textureState[stage][WINED3DTSS_BUMPENVLOFFSET];
2154     if(tmpvalue.f != 0.0) {
2155         FIXME("WINED3DTSS_BUMPENVLOFFSET not supported yet\n");
2156     }
2157 }
2158
2159 static void tex_resultarg(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2160     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
2161
2162     if(stage >= GL_LIMITS(texture_stages)) {
2163         return;
2164     }
2165
2166     if(stateblock->textureState[stage][WINED3DTSS_RESULTARG] != WINED3DTA_CURRENT) {
2167         FIXME("WINED3DTSS_RESULTARG not supported yet\n");
2168     }
2169 }
2170
2171 static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2172     DWORD sampler = state - STATE_SAMPLER(0);
2173     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[sampler];
2174     union {
2175         float f;
2176         DWORD d;
2177     } tmpvalue;
2178
2179     TRACE("Sampler: %d\n", sampler);
2180     /* Enabling and disabling texture dimensions is done by texture stage state / pixel shader setup, this function
2181      * only has to bind textures and set the per texture states
2182      */
2183
2184     if (mapped_stage == -1) {
2185         TRACE("No sampler mapped to stage %d. Returning.\n", sampler);
2186         return;
2187     }
2188
2189     if (GL_SUPPORT(ARB_MULTITEXTURE)) {
2190         if (mapped_stage >= GL_LIMITS(combined_samplers)) {
2191             return;
2192         }
2193         GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
2194         checkGLcall("glActiveTextureARB");
2195     } else if (sampler > 0) {
2196         /* We can't do anything here */
2197         WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
2198         return;
2199     }
2200
2201     if(stateblock->textures[sampler]) {
2202         BOOL texIsPow2 = FALSE;
2203
2204         /* The fixed function np2 texture emulation uses the texture matrix to fix up the coordinates
2205          * IWineD3DBaseTexture::ApplyStateChanges multiplies the set matrix with a fixup matrix. Before the
2206          * scaling is reapplied or removed, the texture matrix has to be reapplied
2207          */
2208         if(!GL_SUPPORT(ARB_TEXTURE_NON_POWER_OF_TWO) && sampler < MAX_TEXTURES) {
2209             if(stateblock->textureDimensions[sampler] == GL_TEXTURE_2D) {
2210                 if(((IWineD3DTextureImpl *) stateblock->textures[sampler])->pow2scalingFactorX != 1.0 ||
2211                    ((IWineD3DTextureImpl *) stateblock->textures[sampler])->pow2scalingFactorY != 1.0 ) {
2212                     texIsPow2 = TRUE;
2213                 }
2214             } else if(stateblock->textureDimensions[sampler] == GL_TEXTURE_CUBE_MAP_ARB) {
2215                 if(((IWineD3DCubeTextureImpl *) stateblock->textures[sampler])->pow2scalingFactor != 1.0) {
2216                     texIsPow2 = TRUE;
2217                 }
2218             }
2219
2220             if(texIsPow2 || context->lastWasPow2Texture[sampler]) {
2221                 transform_texture(STATE_TRANSFORM(WINED3DTS_TEXTURE0 + stateblock->wineD3DDevice->texUnitMap[sampler]), stateblock, context);
2222                 context->lastWasPow2Texture[sampler] = texIsPow2;
2223             }
2224         }
2225
2226         IWineD3DBaseTexture_PreLoad((IWineD3DBaseTexture *) stateblock->textures[sampler]);
2227         IWineD3DBaseTexture_ApplyStateChanges(stateblock->textures[sampler], stateblock->textureState[sampler], stateblock->samplerState[sampler]);
2228
2229         if (GL_SUPPORT(EXT_TEXTURE_LOD_BIAS)) {
2230             tmpvalue.d = stateblock->samplerState[sampler][WINED3DSAMP_MIPMAPLODBIAS];
2231             glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT,
2232                       GL_TEXTURE_LOD_BIAS_EXT,
2233                       tmpvalue.f);
2234             checkGLcall("glTexEnvi GL_TEXTURE_LOD_BIAS_EXT ...");
2235         }
2236
2237         if (stateblock->wineD3DDevice->ps_selected_mode != SHADER_NONE && stateblock->pixelShader &&
2238             ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.function) {
2239             /* Using a pixel shader? Verify the sampler types */
2240
2241             /* Make sure that the texture dimensions are enabled. I don't have to disable the other
2242              * dimensions because the shader knows from which texture type to sample from. For the sake of
2243              * debugging all dimensions could be enabled and a texture with some ugly pink bound to the unused
2244              * dimensions. This should make wrong sampling sources visible :-)
2245              */
2246             glEnable(stateblock->textureDimensions[sampler]);
2247             checkGLcall("glEnable(stateblock->textureDimensions[sampler])");
2248         } else if(sampler < stateblock->lowest_disabled_stage) {
2249             if(!isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) {
2250                 activate_dimensions(sampler, stateblock, context);
2251             }
2252
2253             if(stateblock->renderState[WINED3DRS_COLORKEYENABLE] && sampler == 0) {
2254                 /* If color keying is enabled update the alpha test, it depends on the existence
2255                  * of a color key in stage 0
2256                  */
2257                 state_alpha(WINED3DRS_COLORKEYENABLE, stateblock, context);
2258             }
2259         }
2260     } else if(sampler < GL_LIMITS(texture_stages)) {
2261         if(sampler < stateblock->lowest_disabled_stage) {
2262             /* TODO: What should I do with pixel shaders here ??? */
2263             if(!isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) {
2264                 activate_dimensions(sampler, stateblock, context);
2265             }
2266         } /* Otherwise tex_colorop disables the stage */
2267         glBindTexture(GL_TEXTURE_2D, stateblock->wineD3DDevice->dummyTextureName[sampler]);
2268         checkGLcall("glBindTexture(GL_TEXTURE_2D, stateblock->wineD3DDevice->dummyTextureName[sampler])");
2269     }
2270 }
2271
2272 static void shaderconstant(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2273     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
2274
2275     /* Vertex and pixel shader states will call a shader upload, don't do anything as long one of them
2276      * has an update pending
2277      */
2278     if(isStateDirty(context, STATE_VDECL) ||
2279        isStateDirty(context, STATE_PIXELSHADER)) {
2280        return;
2281     }
2282     
2283     device->shader_backend->shader_load_constants((IWineD3DDevice *) device, use_ps(device), use_vs(device));
2284 }
2285
2286 static void pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2287     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
2288     BOOL use_pshader = use_ps(device);
2289     BOOL use_vshader = use_vs(device);
2290     BOOL update_fog = FALSE;
2291     int i;
2292
2293     if (use_pshader) {
2294         if(!context->last_was_pshader) {
2295             /* Former draw without a pixel shader, some samplers
2296              * may be disabled because of WINED3DTSS_COLOROP = WINED3DTOP_DISABLE
2297              * make sure to enable them
2298              */
2299             for(i=0; i < MAX_FRAGMENT_SAMPLERS; i++) {
2300                 if(!isStateDirty(context, STATE_SAMPLER(i))) {
2301                     sampler(STATE_SAMPLER(i), stateblock, context);
2302                 }
2303             }
2304             update_fog = TRUE;
2305         } else {
2306            /* Otherwise all samplers were activated by the code above in earlier draws, or by sampler()
2307             * if a different texture was bound. I don't have to do anything.
2308             */
2309         }
2310
2311         /* Compile and bind the shader */
2312         IWineD3DPixelShader_CompileShader(stateblock->pixelShader);
2313     } else {
2314         /* Disabled the pixel shader - color ops weren't applied
2315          * while it was enabled, so re-apply them.
2316          */
2317         for(i=0; i < MAX_TEXTURES; i++) {
2318             if(!isStateDirty(context, STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP))) {
2319                 tex_colorop(STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP), stateblock, context);
2320             }
2321         }
2322         if(context->last_was_pshader)
2323             update_fog = TRUE;
2324     }
2325
2326     if(!isStateDirty(context, StateTable[STATE_VSHADER].representative)) {
2327         device->shader_backend->shader_select((IWineD3DDevice *)stateblock->wineD3DDevice, use_pshader, use_vshader);
2328
2329         if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && (use_vshader || use_pshader)) {
2330             shaderconstant(STATE_VERTEXSHADERCONSTANT, stateblock, context);
2331         }
2332     }
2333
2334     if(update_fog)
2335         state_fog(state, stateblock, context);
2336
2337     context->last_was_pshader = use_pshader;
2338 }
2339
2340 static void tex_bumpenvmat(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2341     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
2342
2343     if(stateblock->pixelShader && stage != 0 &&
2344        ((IWineD3DPixelShaderImpl *) stateblock->pixelShader)->needsbumpmat == stage) {
2345         /* The pixel shader has to know the bump env matrix. Do a constants update if it isn't scheduled
2346          * anyway
2347          */
2348         if(!isStateDirty(context, STATE_PIXELSHADERCONSTANT) &&
2349            !isStateDirty(context, STATE_PIXELSHADER)) {
2350             shaderconstant(STATE_PIXELSHADERCONSTANT, stateblock, context);
2351         }
2352     }
2353
2354     if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
2355         if(stage >= GL_LIMITS(texture_stages)) {
2356             WARN("Bump env matrix of unsupported stage set\n");
2357         } else if(GL_SUPPORT(ARB_MULTITEXTURE)) {
2358             GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + stage));
2359             checkGLcall("GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + stage))");
2360         }
2361         GL_EXTCALL(glTexBumpParameterfvATI(GL_BUMP_ROT_MATRIX_ATI,
2362                    (float *) &(stateblock->textureState[stage][WINED3DTSS_BUMPENVMAT00])));
2363         checkGLcall("glTexBumpParameterfvATI");
2364     }
2365     if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
2366         /* Direct3D sets the matrix in the stage reading the perturbation map. The result is used to
2367          * offset the destination stage(always stage + 1 in d3d). In GL_NV_texture_shader, the bump
2368          * map offseting is done in the stage reading the bump mapped texture, and the perturbation
2369          * map is read from a specified source stage(always stage - 1 for d3d). Thus set the matrix
2370          * for stage + 1. Keep the nvrc tex unit mapping in mind too
2371          */
2372         DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage + 1];
2373
2374         if(mapped_stage < GL_LIMITS(textures)) {
2375             GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
2376             checkGLcall("GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage))");
2377
2378             glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_MATRIX_NV,
2379                       (float *) &(stateblock->textureState[stage][WINED3DTSS_BUMPENVMAT00]));
2380             checkGLcall("glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_MATRIX_NV, mat)\n");
2381         }
2382     }
2383 }
2384
2385 static void transform_world(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2386     /* This function is called by transform_view below if the view matrix was changed too
2387      *
2388      * Deliberately no check if the vertex declaration is dirty because the vdecl state
2389      * does not always update the world matrix, only on a switch between transformed
2390      * and untrannsformed draws. It *may* happen that the world matrix is set 2 times during one
2391      * draw, but that should be rather rare and cheaper in total.
2392      */
2393     glMatrixMode(GL_MODELVIEW);
2394     checkGLcall("glMatrixMode");
2395
2396     if(context->last_was_rhw) {
2397         glLoadIdentity();
2398         checkGLcall("glLoadIdentity()");
2399     } else {
2400         /* In the general case, the view matrix is the identity matrix */
2401         if (stateblock->wineD3DDevice->view_ident) {
2402             glLoadMatrixf((float *) &stateblock->transforms[WINED3DTS_WORLDMATRIX(0)].u.m[0][0]);
2403             checkGLcall("glLoadMatrixf");
2404         } else {
2405             glLoadMatrixf((float *) &stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
2406             checkGLcall("glLoadMatrixf");
2407             glMultMatrixf((float *) &stateblock->transforms[WINED3DTS_WORLDMATRIX(0)].u.m[0][0]);
2408             checkGLcall("glMultMatrixf");
2409         }
2410     }
2411 }
2412
2413 static void clipplane(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2414     UINT index = state - STATE_CLIPPLANE(0);
2415
2416     if(isStateDirty(context, STATE_TRANSFORM(WINED3DTS_VIEW)) || index >= GL_LIMITS(clipplanes)) {
2417         return;
2418     }
2419
2420     /* Clip Plane settings are affected by the model view in OpenGL, the View transform in direct3d */
2421     glMatrixMode(GL_MODELVIEW);
2422     glPushMatrix();
2423     glLoadMatrixf((float *) &stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
2424
2425     TRACE("Clipplane [%f,%f,%f,%f]\n",
2426           stateblock->clipplane[index][0],
2427           stateblock->clipplane[index][1],
2428           stateblock->clipplane[index][2],
2429           stateblock->clipplane[index][3]);
2430     glClipPlane(GL_CLIP_PLANE0 + index, stateblock->clipplane[index]);
2431     checkGLcall("glClipPlane");
2432
2433     glPopMatrix();
2434 }
2435
2436 static void transform_worldex(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2437     UINT matrix = state - STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0));
2438     GLenum glMat;
2439     TRACE("Setting world matrix %d\n", matrix);
2440
2441     if(matrix >= GL_LIMITS(blends)) {
2442         WARN("Unsupported blend matrix set\n");
2443         return;
2444     } else if(isStateDirty(context, STATE_TRANSFORM(WINED3DTS_VIEW))) {
2445         return;
2446     }
2447
2448     /* GL_MODELVIEW0_ARB:  0x1700
2449      * GL_MODELVIEW1_ARB:  0x0x850a
2450      * GL_MODELVIEW2_ARB:  0x8722
2451      * GL_MODELVIEW3_ARB:  0x8723
2452      * etc
2453      * GL_MODELVIEW31_ARB: 0x873F
2454      */
2455     if(matrix == 1) glMat = GL_MODELVIEW1_ARB;
2456     else glMat = GL_MODELVIEW2_ARB - 2 + matrix;
2457
2458     glMatrixMode(glMat);
2459     checkGLcall("glMatrixMode(glMat)");
2460
2461     /* World matrix 0 is multiplied with the view matrix because d3d uses 3 matrices while gl uses only 2. To avoid
2462      * weighting the view matrix incorrectly it has to be multiplied into every gl modelview matrix
2463      */
2464     if(stateblock->wineD3DDevice->view_ident) {
2465         glLoadMatrixf(&stateblock->transforms[WINED3DTS_WORLDMATRIX(matrix)].u.m[0][0]);
2466         checkGLcall("glLoadMatrixf")
2467     } else {
2468         glLoadMatrixf(&stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
2469         checkGLcall("glLoadMatrixf")
2470         glMultMatrixf(&stateblock->transforms[WINED3DTS_WORLDMATRIX(matrix)].u.m[0][0]);
2471         checkGLcall("glMultMatrixf")
2472     }
2473 }
2474
2475 static void state_vertexblend(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2476     WINED3DVERTEXBLENDFLAGS val = stateblock->renderState[WINED3DRS_VERTEXBLEND];
2477
2478     switch(val) {
2479         case WINED3DVBF_1WEIGHTS:
2480         case WINED3DVBF_2WEIGHTS:
2481         case WINED3DVBF_3WEIGHTS:
2482             if(GL_SUPPORT(ARB_VERTEX_BLEND)) {
2483                 glEnable(GL_VERTEX_BLEND_ARB);
2484                 checkGLcall("glEnable(GL_VERTEX_BLEND_ARB)");
2485
2486                 /* D3D adds one more matrix which has weight (1 - sum(weights)). This is enabled at context
2487                  * creation with enabling GL_WEIGHT_SUM_UNITY_ARB.
2488                  */
2489                 GL_EXTCALL(glVertexBlendARB(stateblock->renderState[WINED3DRS_VERTEXBLEND] + 1));
2490
2491                 if(!stateblock->wineD3DDevice->vertexBlendUsed) {
2492                     int i;
2493                     for(i = 1; i < GL_LIMITS(blends); i++) {
2494                         if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(i)))) {
2495                             transform_worldex(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(i)), stateblock, context);
2496                         }
2497                     }
2498                     stateblock->wineD3DDevice->vertexBlendUsed = TRUE;
2499                 }
2500             } else {
2501                 /* TODO: Implement vertex blending in drawStridedSlow */
2502                 FIXME("Vertex blending enabled, but not supported by hardware\n");
2503             }
2504             break;
2505
2506         case WINED3DVBF_DISABLE:
2507         case WINED3DVBF_0WEIGHTS: /* for Indexed vertex blending - not supported */
2508             if(GL_SUPPORT(ARB_VERTEX_BLEND)) {
2509                 glDisable(GL_VERTEX_BLEND_ARB);
2510                 checkGLcall("glDisable(GL_VERTEX_BLEND_ARB)");
2511             } else {
2512                 TRACE("Vertex blending disabled\n");
2513             }
2514             break;
2515
2516         case WINED3DVBF_TWEENING:
2517             /* Just set the vertex weight for weight 0, enable vertex blending and hope the app doesn't have
2518              * vertex weights in the vertices?
2519              * For now we don't report that as supported, so a warn should suffice
2520              */
2521             WARN("Tweening not supported yet\n");
2522             break;
2523     }
2524 }
2525
2526 static void transform_view(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2527     unsigned int k;
2528
2529     /* If we are changing the View matrix, reset the light and clipping planes to the new view
2530      * NOTE: We have to reset the positions even if the light/plane is not currently
2531      *       enabled, since the call to enable it will not reset the position.
2532      * NOTE2: Apparently texture transforms do NOT need reapplying
2533      */
2534
2535     PLIGHTINFOEL *light = NULL;
2536
2537     glMatrixMode(GL_MODELVIEW);
2538     checkGLcall("glMatrixMode(GL_MODELVIEW)");
2539     glLoadMatrixf((float *)(float *) &stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
2540     checkGLcall("glLoadMatrixf(...)");
2541
2542     /* Reset lights. TODO: Call light apply func */
2543     for(k = 0; k < stateblock->wineD3DDevice->maxConcurrentLights; k++) {
2544         light = stateblock->activeLights[k];
2545         if(!light) continue;
2546         glLightfv(GL_LIGHT0 + light->glIndex, GL_POSITION, light->lightPosn);
2547         checkGLcall("glLightfv posn");
2548         glLightfv(GL_LIGHT0 + light->glIndex, GL_SPOT_DIRECTION, light->lightDirn);
2549         checkGLcall("glLightfv dirn");
2550     }
2551
2552     /* Reset Clipping Planes  */
2553     for (k = 0; k < GL_LIMITS(clipplanes); k++) {
2554         if(!isStateDirty(context, STATE_CLIPPLANE(k))) {
2555             clipplane(STATE_CLIPPLANE(k), stateblock, context);
2556         }
2557     }
2558
2559     if(context->last_was_rhw) {
2560         glLoadIdentity();
2561         checkGLcall("glLoadIdentity()");
2562         /* No need to update the world matrix, the identity is fine */
2563         return;
2564     }
2565
2566     /* Call the world matrix state, this will apply the combined WORLD + VIEW matrix
2567      * No need to do it here if the state is scheduled for update.
2568      */
2569     if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)))) {
2570         transform_world(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), stateblock, context);
2571     }
2572
2573     /* Avoid looping over a number of matrices if the app never used the functionality */
2574     if(stateblock->wineD3DDevice->vertexBlendUsed) {
2575         for(k = 1; k < GL_LIMITS(blends); k++) {
2576             if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(k)))) {
2577                 transform_worldex(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(k)), stateblock, context);
2578             }
2579         }
2580     }
2581 }
2582
2583 static const GLfloat invymat[16] = {
2584     1.0f, 0.0f, 0.0f, 0.0f,
2585     0.0f, -1.0f, 0.0f, 0.0f,
2586     0.0f, 0.0f, 1.0f, 0.0f,
2587     0.0f, 0.0f, 0.0f, 1.0f};
2588
2589 static void transform_projection(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2590     glMatrixMode(GL_PROJECTION);
2591     checkGLcall("glMatrixMode(GL_PROJECTION)");
2592     glLoadIdentity();
2593     checkGLcall("glLoadIdentity");
2594
2595     if(context->last_was_rhw) {
2596         double X, Y, height, width, minZ, maxZ;
2597
2598         X      = stateblock->viewport.X;
2599         Y      = stateblock->viewport.Y;
2600         height = stateblock->viewport.Height;
2601         width  = stateblock->viewport.Width;
2602         minZ   = stateblock->viewport.MinZ;
2603         maxZ   = stateblock->viewport.MaxZ;
2604
2605         if(!stateblock->wineD3DDevice->untransformed) {
2606             /* Transformed vertices are supposed to bypass the whole transform pipeline including
2607              * frustum clipping. This can't be done in opengl, so this code adjusts the Z range to
2608              * suppress depth clipping. This can be done because it is an orthogonal projection and
2609              * the Z coordinate does not affect the size of the primitives
2610              */
2611             TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, -minZ, -maxZ);
2612             if(stateblock->wineD3DDevice->render_offscreen) {
2613                 glOrtho(X, X + width, -Y, -Y - height, -minZ, -maxZ);
2614             } else {
2615                 glOrtho(X, X + width, Y + height, Y, -minZ, -maxZ);
2616             }
2617         } else {
2618             /* If the app mixes transformed and untransformed primitives we can't use the coordinate system
2619              * trick above because this would mess up transformed and untransformed Z order. Pass the z position
2620              * unmodified to opengl.
2621              *
2622              * If the app depends on mixed types and disabled clipping we're out of luck without a pipeline
2623              * replacement shader.
2624              */
2625             TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, 1.0, -1.0);
2626             if(stateblock->wineD3DDevice->render_offscreen) {
2627                 glOrtho(X, X + width, -Y, -Y - height, 1.0, -1.0);
2628             } else {
2629                 glOrtho(X, X + width, Y + height, Y, 1.0, -1.0);
2630             }
2631         }
2632         checkGLcall("glOrtho");
2633
2634         /* Window Coord 0 is the middle of the first pixel, so translate by 1/2 pixels */
2635         glTranslatef(0.5, 0.5, 0);
2636         checkGLcall("glTranslatef(0.5, 0.5, 0)");
2637         /* D3D texture coordinates are flipped compared to OpenGL ones, so
2638          * render everything upside down when rendering offscreen. */
2639         if (stateblock->wineD3DDevice->render_offscreen) {
2640             glMultMatrixf(invymat);
2641             checkGLcall("glMultMatrixf(invymat)");
2642         }
2643     } else {
2644         /* The rule is that the window coordinate 0 does not correspond to the
2645             beginning of the first pixel, but the center of the first pixel.
2646             As a consequence if you want to correctly draw one line exactly from
2647             the left to the right end of the viewport (with all matrices set to
2648             be identity), the x coords of both ends of the line would be not
2649             -1 and 1 respectively but (-1-1/viewport_widh) and (1-1/viewport_width)
2650             instead.
2651
2652             1.0 / Width is used because the coord range goes from -1.0 to 1.0, then we
2653             divide by the Width/Height, so we need the half range(1.0) to translate by
2654             half a pixel.
2655          */
2656         glTranslatef(1.0 / stateblock->viewport.Width, -1.0/ stateblock->viewport.Height, 0);
2657         checkGLcall("glTranslatef (1.0 / width, -1.0 / height, 0)");
2658
2659         /* D3D texture coordinates are flipped compared to OpenGL ones, so
2660             * render everything upside down when rendering offscreen. */
2661         if (stateblock->wineD3DDevice->render_offscreen) {
2662             glMultMatrixf(invymat);
2663             checkGLcall("glMultMatrixf(invymat)");
2664         }
2665         glMultMatrixf((float *) &stateblock->transforms[WINED3DTS_PROJECTION].u.m[0][0]);
2666         checkGLcall("glLoadMatrixf");
2667     }
2668 }
2669
2670 /* This should match any arrays loaded in loadVertexData.
2671  * stateblock impl is required for GL_SUPPORT
2672  * TODO: Only load / unload arrays if we have to.
2673  */
2674 static inline void unloadVertexData(IWineD3DStateBlockImpl *stateblock) {
2675     glDisableClientState(GL_VERTEX_ARRAY);
2676     glDisableClientState(GL_NORMAL_ARRAY);
2677     glDisableClientState(GL_COLOR_ARRAY);
2678     if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
2679         glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
2680     }
2681     if (GL_SUPPORT(ARB_VERTEX_BLEND)) {
2682         glDisableClientState(GL_WEIGHT_ARRAY_ARB);
2683     } else if (GL_SUPPORT(EXT_VERTEX_WEIGHTING)) {
2684         glDisableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT);
2685     }
2686     unloadTexCoords(stateblock);
2687 }
2688
2689 /* This should match any arrays loaded in loadNumberedArrays
2690  * TODO: Only load / unload arrays if we have to.
2691  */
2692 static inline void unloadNumberedArrays(IWineD3DStateBlockImpl *stateblock) {
2693     /* disable any attribs (this is the same for both GLSL and ARB modes) */
2694     GLint maxAttribs;
2695     int i;
2696
2697     /* Leave all the attribs disabled */
2698     glGetIntegerv(GL_MAX_VERTEX_ATTRIBS_ARB, &maxAttribs);
2699     /* MESA does not support it right not */
2700     if (glGetError() != GL_NO_ERROR)
2701         maxAttribs = 16;
2702     for (i = 0; i < maxAttribs; ++i) {
2703         GL_EXTCALL(glDisableVertexAttribArrayARB(i));
2704         checkGLcall("glDisableVertexAttribArrayARB(reg);");
2705     }
2706 }
2707
2708 static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock, WineDirect3DVertexStridedData *strided) {
2709     GLint curVBO = GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT) ? -1 : 0;
2710     int i;
2711     UINT *offset = stateblock->streamOffset;
2712
2713     /* Default to no instancing */
2714     stateblock->wineD3DDevice->instancedDraw = FALSE;
2715
2716     for (i = 0; i < MAX_ATTRIBS; i++) {
2717
2718         if (!strided->u.input[i].lpData && !strided->u.input[i].VBO)
2719             continue;
2720
2721         /* Do not load instance data. It will be specified using glTexCoord by drawprim */
2722         if(stateblock->streamFlags[strided->u.input[i].streamNo] & WINED3DSTREAMSOURCE_INSTANCEDATA) {
2723             GL_EXTCALL(glDisableVertexAttribArrayARB(i));
2724             stateblock->wineD3DDevice->instancedDraw = TRUE;
2725             continue;
2726         }
2727
2728         TRACE_(d3d_shader)("Loading array %u [VBO=%u]\n", i, strided->u.input[i].VBO);
2729
2730         if(strided->u.input[i].dwStride) {
2731             if(curVBO != strided->u.input[i].VBO) {
2732                 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, strided->u.input[i].VBO));
2733                 checkGLcall("glBindBufferARB");
2734                 curVBO = strided->u.input[i].VBO;
2735             }
2736             GL_EXTCALL(glVertexAttribPointerARB(i,
2737                             WINED3D_ATR_SIZE(strided->u.input[i].dwType),
2738                             WINED3D_ATR_GLTYPE(strided->u.input[i].dwType),
2739                             WINED3D_ATR_NORMALIZED(strided->u.input[i].dwType),
2740                             strided->u.input[i].dwStride,
2741                             strided->u.input[i].lpData + stateblock->loadBaseVertexIndex * strided->u.input[i].dwStride + offset[strided->u.input[i].streamNo]) );
2742             GL_EXTCALL(glEnableVertexAttribArrayARB(i));
2743         } else {
2744             /* Stride = 0 means always the same values. glVertexAttribPointerARB doesn't do that. Instead disable the pointer and
2745              * set up the attribute statically. But we have to figure out the system memory address.
2746              */
2747             BYTE *ptr = strided->u.input[i].lpData + offset[strided->u.input[i].streamNo];
2748             if(strided->u.input[i].VBO) {
2749                 IWineD3DVertexBufferImpl *vb = (IWineD3DVertexBufferImpl *) stateblock->streamSource[strided->u.input[i].streamNo];
2750                 ptr += (long) vb->resource.allocatedMemory;
2751             }
2752             GL_EXTCALL(glDisableVertexAttribArrayARB(i));
2753
2754             switch(strided->u.input[i].dwType) {
2755                 case WINED3DDECLTYPE_FLOAT1:
2756                     GL_EXTCALL(glVertexAttrib1fvARB(i, (float *) ptr));
2757                     break;
2758                 case WINED3DDECLTYPE_FLOAT2:
2759                     GL_EXTCALL(glVertexAttrib2fvARB(i, (float *) ptr));
2760                     break;
2761                 case WINED3DDECLTYPE_FLOAT3:
2762                     GL_EXTCALL(glVertexAttrib3fvARB(i, (float *) ptr));
2763                     break;
2764                 case WINED3DDECLTYPE_FLOAT4:
2765                     GL_EXTCALL(glVertexAttrib4fvARB(i, (float *) ptr));
2766                     break;
2767
2768                 case WINED3DDECLTYPE_UBYTE4:
2769                     GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
2770                     break;
2771                 case WINED3DDECLTYPE_UBYTE4N:
2772                 case WINED3DDECLTYPE_D3DCOLOR:
2773                     GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
2774                     break;
2775
2776                 case WINED3DDECLTYPE_SHORT2:
2777                     GL_EXTCALL(glVertexAttrib4svARB(i, (GLshort *) ptr));
2778                     break;
2779                 case WINED3DDECLTYPE_SHORT4:
2780                     GL_EXTCALL(glVertexAttrib4svARB(i, (GLshort *) ptr));
2781                     break;
2782
2783                 case WINED3DDECLTYPE_SHORT2N:
2784                 {
2785                     GLshort s[4] = {((short *) ptr)[0], ((short *) ptr)[1], 0, 1};
2786                     GL_EXTCALL(glVertexAttrib4NsvARB(i, s));
2787                     break;
2788                 }
2789                 case WINED3DDECLTYPE_USHORT2N:
2790                 {
2791                     GLushort s[4] = {((unsigned short *) ptr)[0], ((unsigned short *) ptr)[1], 0, 1};
2792                     GL_EXTCALL(glVertexAttrib4NusvARB(i, s));
2793                     break;
2794                 }
2795                 case WINED3DDECLTYPE_SHORT4N:
2796                     GL_EXTCALL(glVertexAttrib4NsvARB(i, (GLshort *) ptr));
2797                     break;
2798                 case WINED3DDECLTYPE_USHORT4N:
2799                     GL_EXTCALL(glVertexAttrib4NusvARB(i, (GLushort *) ptr));
2800                     break;
2801
2802                 case WINED3DDECLTYPE_UDEC3:
2803                     FIXME("Unsure about WINED3DDECLTYPE_UDEC3\n");
2804                     /*glVertexAttrib3usvARB(i, (GLushort *) ptr); Does not exist */
2805                     break;
2806                 case WINED3DDECLTYPE_DEC3N:
2807                     FIXME("Unsure about WINED3DDECLTYPE_DEC3N\n");
2808                     /*glVertexAttrib3NusvARB(i, (GLushort *) ptr); Does not exist */
2809                     break;
2810
2811                 case WINED3DDECLTYPE_FLOAT16_2:
2812                     /* Are those 16 bit floats. C doesn't have a 16 bit float type. I could read the single bits and calculate a 4
2813                      * byte float according to the IEEE standard
2814                      */
2815                     FIXME("Unsupported WINED3DDECLTYPE_FLOAT16_2\n");
2816                     break;
2817                 case WINED3DDECLTYPE_FLOAT16_4:
2818                     FIXME("Unsupported WINED3DDECLTYPE_FLOAT16_4\n");
2819                     break;
2820
2821                 case WINED3DDECLTYPE_UNUSED:
2822                 default:
2823                     ERR("Unexpected declaration in stride 0 attributes\n");
2824                     break;
2825
2826             }
2827         }
2828     }
2829 }
2830
2831 /* Used from 2 different functions, and too big to justify making it inlined */
2832 static void loadVertexData(IWineD3DStateBlockImpl *stateblock, WineDirect3DVertexStridedData *sd) {
2833     UINT *offset = stateblock->streamOffset;
2834     GLint curVBO = GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT) ? -1 : 0;
2835
2836     TRACE("Using fast vertex array code\n");
2837
2838     /* This is fixed function pipeline only, and the fixed function pipeline doesn't do instancing */
2839     stateblock->wineD3DDevice->instancedDraw = FALSE;
2840
2841     /* Blend Data ---------------------------------------------- */
2842     if( (sd->u.s.blendWeights.lpData) || (sd->u.s.blendWeights.VBO) ||
2843         (sd->u.s.blendMatrixIndices.lpData) || (sd->u.s.blendMatrixIndices.VBO) ) {
2844
2845         if (GL_SUPPORT(ARB_VERTEX_BLEND)) {
2846             TRACE("Blend %d %p %d\n", WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType),
2847                 sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride, sd->u.s.blendWeights.dwStride + offset[sd->u.s.blendWeights.streamNo]);
2848
2849             glEnableClientState(GL_WEIGHT_ARRAY_ARB);
2850             checkGLcall("glEnableClientState(GL_WEIGHT_ARRAY_ARB)");
2851
2852             GL_EXTCALL(glVertexBlendARB(WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType) + 1));
2853
2854             VTRACE(("glWeightPointerARB(%d, GL_FLOAT, %d, %p)\n",
2855                 WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType) ,
2856                 sd->u.s.blendWeights.dwStride,
2857                 sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride + offset[sd->u.s.blendWeights.streamNo]));
2858
2859             if(curVBO != sd->u.s.blendWeights.VBO) {
2860                 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.blendWeights.VBO));
2861                 checkGLcall("glBindBufferARB");
2862                 curVBO = sd->u.s.blendWeights.VBO;
2863             }
2864
2865             GL_EXTCALL(glWeightPointerARB)(
2866                 WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType),
2867                 WINED3D_ATR_GLTYPE(sd->u.s.blendWeights.dwType),
2868                 sd->u.s.blendWeights.dwStride,
2869                 sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride + offset[sd->u.s.blendWeights.streamNo]);
2870
2871             checkGLcall("glWeightPointerARB");
2872
2873             if((sd->u.s.blendMatrixIndices.lpData) || (sd->u.s.blendMatrixIndices.VBO)){
2874                 static BOOL showfixme = TRUE;
2875                 if(showfixme){
2876                     FIXME("blendMatrixIndices support\n");
2877                     showfixme = FALSE;
2878                 }
2879             }
2880         } else if (GL_SUPPORT(EXT_VERTEX_WEIGHTING)) {
2881             /* FIXME("TODO\n");*/
2882 #if 0
2883
2884             GL_EXTCALL(glVertexWeightPointerEXT)(
2885                 WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType),
2886                 WINED3D_ATR_GLTYPE(sd->u.s.blendWeights.dwType),
2887                 sd->u.s.blendWeights.dwStride,
2888                 sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride);
2889             checkGLcall("glVertexWeightPointerEXT(numBlends, ...)");
2890             glEnableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT);
2891             checkGLcall("glEnableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT)");
2892 #endif
2893
2894         } else {
2895             /* TODO: support blends in drawStridedSlow
2896              * No need to write a FIXME here, this is done after the general vertex decl decoding
2897              */
2898             WARN("unsupported blending in openGl\n");
2899         }
2900     } else {
2901         if (GL_SUPPORT(ARB_VERTEX_BLEND)) {
2902             static const GLbyte one = 1;
2903             GL_EXTCALL(glWeightbvARB(1, &one));
2904             checkGLcall("glWeightivARB(GL_LIMITS(blends), weights)");
2905         }
2906     }
2907
2908 #if 0 /* FOG  ----------------------------------------------*/
2909     if (sd->u.s.fog.lpData || sd->u.s.fog.VBO) {
2910         /* TODO: fog*/
2911     if (GL_SUPPORT(EXT_FOG_COORD) {
2912              glEnableClientState(GL_FOG_COORDINATE_EXT);
2913             (GL_EXTCALL)(FogCoordPointerEXT)(
2914                 WINED3D_ATR_GLTYPE(sd->u.s.fog.dwType),
2915                 sd->u.s.fog.dwStride,
2916                 sd->u.s.fog.lpData + stateblock->loadBaseVertexIndex * sd->u.s.fog.dwStride);
2917         } else {
2918             /* don't bother falling back to 'slow' as we don't support software FOG yet. */
2919             /* FIXME: fixme once */
2920             TRACE("Hardware support for FOG is not avaiable, FOG disabled.\n");
2921         }
2922     } else {
2923         if (GL_SUPPRT(EXT_FOR_COORD) {
2924              /* make sure fog is disabled */
2925              glDisableClientState(GL_FOG_COORDINATE_EXT);
2926         }
2927     }
2928 #endif
2929
2930 #if 0 /* tangents  ----------------------------------------------*/
2931     if (sd->u.s.tangent.lpData || sd->u.s.tangent.VBO ||
2932         sd->u.s.binormal.lpData || sd->u.s.binormal.VBO) {
2933         /* TODO: tangents*/
2934         if (GL_SUPPORT(EXT_COORDINATE_FRAME) {
2935             if (sd->u.s.tangent.lpData || sd->u.s.tangent.VBO) {
2936                 glEnable(GL_TANGENT_ARRAY_EXT);
2937                 (GL_EXTCALL)(TangentPointerEXT)(
2938                     WINED3D_ATR_GLTYPE(sd->u.s.tangent.dwType),
2939                     sd->u.s.tangent.dwStride,
2940                     sd->u.s.tangent.lpData + stateblock->loadBaseVertexIndex * sd->u.s.tangent.dwStride);
2941             } else {
2942                     glDisable(GL_TANGENT_ARRAY_EXT);
2943             }
2944             if (sd->u.s.binormal.lpData || sd->u.s.binormal.VBO) {
2945                     glEnable(GL_BINORMAL_ARRAY_EXT);
2946                     (GL_EXTCALL)(BinormalPointerEXT)(
2947                         WINED3D_ATR_GLTYPE(sd->u.s.binormal.dwType),
2948                         sd->u.s.binormal.dwStride,
2949                         sd->u.s.binormal.lpData + stateblock->loadBaseVertexIndex * sd->u.s.binormal.dwStride);
2950             } else{
2951                     glDisable(GL_BINORMAL_ARRAY_EXT);
2952             }
2953
2954         } else {
2955             /* don't bother falling back to 'slow' as we don't support software tangents and binormals yet . */
2956             /* FIXME: fixme once */
2957             TRACE("Hardware support for tangents and binormals is not avaiable, tangents and binormals disabled.\n");
2958         }
2959     } else {
2960         if (GL_SUPPORT(EXT_COORDINATE_FRAME) {
2961              /* make sure fog is disabled */
2962              glDisable(GL_TANGENT_ARRAY_EXT);
2963              glDisable(GL_BINORMAL_ARRAY_EXT);
2964         }
2965     }
2966 #endif
2967
2968     /* Point Size ----------------------------------------------*/
2969     if (sd->u.s.pSize.lpData || sd->u.s.pSize.VBO) {
2970
2971         /* no such functionality in the fixed function GL pipeline */
2972         TRACE("Cannot change ptSize here in openGl\n");
2973         /* TODO: Implement this function in using shaders if they are available */
2974
2975     }
2976
2977     /* Vertex Pointers -----------------------------------------*/
2978     if (sd->u.s.position.lpData != NULL || sd->u.s.position.VBO != 0) {
2979         /* Note dwType == float3 or float4 == 2 or 3 */
2980         VTRACE(("glVertexPointer(%d, GL_FLOAT, %d, %p)\n",
2981                 sd->u.s.position.dwStride,
2982                 sd->u.s.position.dwType + 1,
2983                 sd->u.s.position.lpData));
2984
2985         if(curVBO != sd->u.s.position.VBO) {
2986             GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.position.VBO));
2987             checkGLcall("glBindBufferARB");
2988             curVBO = sd->u.s.position.VBO;
2989         }
2990
2991         /* min(WINED3D_ATR_SIZE(position),3) to Disable RHW mode as 'w' coord
2992            handling for rhw mode should not impact screen position whereas in GL it does.
2993            This may  result in very slightly distored textures in rhw mode, but
2994            a very minimal different. There's always the other option of
2995            fixing the view matrix to prevent w from having any effect
2996
2997            This only applies to user pointer sources, in VBOs the vertices are fixed up
2998          */
2999         if(sd->u.s.position.VBO == 0) {
3000             glVertexPointer(3 /* min(WINED3D_ATR_SIZE(sd->u.s.position.dwType),3) */,
3001                 WINED3D_ATR_GLTYPE(sd->u.s.position.dwType),
3002                 sd->u.s.position.dwStride, sd->u.s.position.lpData + stateblock->loadBaseVertexIndex * sd->u.s.position.dwStride + offset[sd->u.s.position.streamNo]);
3003         } else {
3004             glVertexPointer(
3005                 WINED3D_ATR_SIZE(sd->u.s.position.dwType),
3006                 WINED3D_ATR_GLTYPE(sd->u.s.position.dwType),
3007                 sd->u.s.position.dwStride, sd->u.s.position.lpData + stateblock->loadBaseVertexIndex * sd->u.s.position.dwStride + offset[sd->u.s.position.streamNo]);
3008         }
3009         checkGLcall("glVertexPointer(...)");
3010         glEnableClientState(GL_VERTEX_ARRAY);
3011         checkGLcall("glEnableClientState(GL_VERTEX_ARRAY)");
3012     }
3013
3014     /* Normals -------------------------------------------------*/
3015     if (sd->u.s.normal.lpData || sd->u.s.normal.VBO) {
3016         /* Note dwType == float3 or float4 == 2 or 3 */
3017         VTRACE(("glNormalPointer(GL_FLOAT, %d, %p)\n",
3018                 sd->u.s.normal.dwStride,
3019                 sd->u.s.normal.lpData));
3020         if(curVBO != sd->u.s.normal.VBO) {
3021             GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.normal.VBO));
3022             checkGLcall("glBindBufferARB");
3023             curVBO = sd->u.s.normal.VBO;
3024         }
3025         glNormalPointer(
3026             WINED3D_ATR_GLTYPE(sd->u.s.normal.dwType),
3027             sd->u.s.normal.dwStride,
3028             sd->u.s.normal.lpData + stateblock->loadBaseVertexIndex * sd->u.s.normal.dwStride + offset[sd->u.s.normal.streamNo]);
3029         checkGLcall("glNormalPointer(...)");
3030         glEnableClientState(GL_NORMAL_ARRAY);
3031         checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)");
3032
3033     } else {
3034         glNormal3f(0, 0, 1);
3035         checkGLcall("glNormal3f(0, 0, 1)");
3036     }
3037
3038     /* Diffuse Colour --------------------------------------------*/
3039     /*  WARNING: Data here MUST be in RGBA format, so cannot      */
3040     /*     go directly into fast mode from app pgm, because       */
3041     /*     directx requires data in BGRA format.                  */
3042     /* currently fixupVertices swizels the format, but this isn't */
3043     /* very practical when using VBOS                             */
3044     /* NOTE: Unless we write a vertex shader to swizel the colour */
3045     /* , or the user doesn't care and wants the speed advantage   */
3046
3047     if (sd->u.s.diffuse.lpData || sd->u.s.diffuse.VBO) {
3048         /* Note dwType == float3 or float4 == 2 or 3 */
3049         VTRACE(("glColorPointer(4, GL_UNSIGNED_BYTE, %d, %p)\n",
3050                 sd->u.s.diffuse.dwStride,
3051                 sd->u.s.diffuse.lpData));
3052
3053         if(curVBO != sd->u.s.diffuse.VBO) {
3054             GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.diffuse.VBO));
3055             checkGLcall("glBindBufferARB");
3056             curVBO = sd->u.s.diffuse.VBO;
3057         }
3058         glColorPointer(4, GL_UNSIGNED_BYTE,
3059                        sd->u.s.diffuse.dwStride,
3060                        sd->u.s.diffuse.lpData + stateblock->loadBaseVertexIndex * sd->u.s.diffuse.dwStride + offset[sd->u.s.diffuse.streamNo]);
3061         checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)");
3062         glEnableClientState(GL_COLOR_ARRAY);
3063         checkGLcall("glEnableClientState(GL_COLOR_ARRAY)");
3064
3065     } else {
3066         glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
3067         checkGLcall("glColor4f(1, 1, 1, 1)");
3068     }
3069
3070     /* Specular Colour ------------------------------------------*/
3071     if (sd->u.s.specular.lpData || sd->u.s.specular.VBO) {
3072         TRACE("setting specular colour\n");
3073         /* Note dwType == float3 or float4 == 2 or 3 */
3074         VTRACE(("glSecondaryColorPointer(4, GL_UNSIGNED_BYTE, %d, %p)\n",
3075                 sd->u.s.specular.dwStride,
3076                 sd->u.s.specular.lpData));
3077         if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
3078             if(curVBO != sd->u.s.specular.VBO) {
3079                 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.specular.VBO));
3080                 checkGLcall("glBindBufferARB");
3081                 curVBO = sd->u.s.specular.VBO;
3082             }
3083             GL_EXTCALL(glSecondaryColorPointerEXT)(4, GL_UNSIGNED_BYTE,
3084                                                    sd->u.s.specular.dwStride,
3085                                                    sd->u.s.specular.lpData + stateblock->loadBaseVertexIndex * sd->u.s.specular.dwStride + offset[sd->u.s.specular.streamNo]);
3086             vcheckGLcall("glSecondaryColorPointerEXT(4, GL_UNSIGNED_BYTE, ...)");
3087             glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
3088             vcheckGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
3089         } else {
3090
3091         /* Missing specular color is not critical, no warnings */
3092         VTRACE(("Specular colour is not supported in this GL implementation\n"));
3093         }
3094
3095     } else {
3096         if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
3097             GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0);
3098             checkGLcall("glSecondaryColor3fEXT(0, 0, 0)");
3099         } else {
3100
3101             /* Missing specular color is not critical, no warnings */
3102             VTRACE(("Specular colour is not supported in this GL implementation\n"));
3103         }
3104     }
3105
3106     /* Texture coords -------------------------------------------*/
3107     loadTexCoords(stateblock, sd, &curVBO);
3108 }
3109
3110 static inline void drawPrimitiveTraceDataLocations(
3111     WineDirect3DVertexStridedData *dataLocations) {
3112
3113     /* Dump out what parts we have supplied */
3114     TRACE("Strided Data:\n");
3115     TRACE_STRIDED((dataLocations), position);
3116     TRACE_STRIDED((dataLocations), blendWeights);
3117     TRACE_STRIDED((dataLocations), blendMatrixIndices);
3118     TRACE_STRIDED((dataLocations), normal);
3119     TRACE_STRIDED((dataLocations), pSize);
3120     TRACE_STRIDED((dataLocations), diffuse);
3121     TRACE_STRIDED((dataLocations), specular);
3122     TRACE_STRIDED((dataLocations), texCoords[0]);
3123     TRACE_STRIDED((dataLocations), texCoords[1]);
3124     TRACE_STRIDED((dataLocations), texCoords[2]);
3125     TRACE_STRIDED((dataLocations), texCoords[3]);
3126     TRACE_STRIDED((dataLocations), texCoords[4]);
3127     TRACE_STRIDED((dataLocations), texCoords[5]);
3128     TRACE_STRIDED((dataLocations), texCoords[6]);
3129     TRACE_STRIDED((dataLocations), texCoords[7]);
3130     TRACE_STRIDED((dataLocations), position2);
3131     TRACE_STRIDED((dataLocations), normal2);
3132     TRACE_STRIDED((dataLocations), tangent);
3133     TRACE_STRIDED((dataLocations), binormal);
3134     TRACE_STRIDED((dataLocations), tessFactor);
3135     TRACE_STRIDED((dataLocations), fog);
3136     TRACE_STRIDED((dataLocations), depth);
3137     TRACE_STRIDED((dataLocations), sample);
3138
3139     return;
3140 }
3141
3142 /* Helper for vertexdeclaration() */
3143 static inline void handleStreams(IWineD3DStateBlockImpl *stateblock, BOOL useVertexShaderFunction, WineD3DContext *context) {
3144     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
3145     BOOL fixup = FALSE;
3146     WineDirect3DVertexStridedData *dataLocations = &device->strided_streams;
3147
3148     if(device->up_strided) {
3149         /* Note: this is a ddraw fixed-function code path */
3150         TRACE("================ Strided Input ===================\n");
3151         memcpy(dataLocations, device->up_strided, sizeof(*dataLocations));
3152
3153         if(TRACE_ON(d3d)) {
3154             drawPrimitiveTraceDataLocations(dataLocations);
3155         }
3156     } else {
3157         /* Note: This is a fixed function or shader codepath.
3158          * This means it must handle both types of strided data.
3159          * Shaders must go through here to zero the strided data, even if they
3160          * don't set any declaration at all
3161          */
3162         TRACE("================ Vertex Declaration  ===================\n");
3163         memset(dataLocations, 0, sizeof(*dataLocations));
3164         primitiveDeclarationConvertToStridedData((IWineD3DDevice *) device,
3165                 useVertexShaderFunction, dataLocations, &fixup);
3166     }
3167
3168     if (dataLocations->u.s.position_transformed) {
3169         useVertexShaderFunction = FALSE;
3170     }
3171
3172     /* Unload the old arrays before loading the new ones to get old junk out */
3173     if(context->numberedArraysLoaded) {
3174         unloadNumberedArrays(stateblock);
3175         context->numberedArraysLoaded = FALSE;
3176     }
3177     if(context->namedArraysLoaded) {
3178         unloadVertexData(stateblock);
3179         context->namedArraysLoaded = FALSE;
3180     }
3181
3182     if(useVertexShaderFunction) {
3183         TRACE("Loading numbered arrays\n");
3184         loadNumberedArrays(stateblock, dataLocations);
3185         device->useDrawStridedSlow = FALSE;
3186         context->numberedArraysLoaded = TRUE;
3187     } else if (fixup ||
3188                (dataLocations->u.s.pSize.lpData == NULL &&
3189                 dataLocations->u.s.diffuse.lpData == NULL &&
3190                 dataLocations->u.s.specular.lpData == NULL)) {
3191         /* Load the vertex data using named arrays */
3192         TRACE("Loading vertex data\n");
3193         loadVertexData(stateblock, dataLocations);
3194         device->useDrawStridedSlow = FALSE;
3195         context->namedArraysLoaded = TRUE;
3196     } else {
3197         TRACE("Not loading vertex data\n");
3198         device->useDrawStridedSlow = TRUE;
3199     }
3200
3201 /* Generate some fixme's if unsupported functionality is being used */
3202 #define BUFFER_OR_DATA(_attribute) dataLocations->u.s._attribute.lpData
3203     /* TODO: Either support missing functionality in fixupVertices or by creating a shader to replace the pipeline. */
3204     if (!useVertexShaderFunction && (BUFFER_OR_DATA(position2) || BUFFER_OR_DATA(normal2))) {
3205         FIXME("Tweening is only valid with vertex shaders\n");
3206     }
3207     if (!useVertexShaderFunction && (BUFFER_OR_DATA(tangent) || BUFFER_OR_DATA(binormal))) {
3208         FIXME("Tangent and binormal bump mapping is only valid with vertex shaders\n");
3209     }
3210     if (!useVertexShaderFunction && (BUFFER_OR_DATA(tessFactor) || BUFFER_OR_DATA(fog) || BUFFER_OR_DATA(depth) || BUFFER_OR_DATA(sample))) {
3211         FIXME("Extended attributes are only valid with vertex shaders\n");
3212     }
3213 #undef BUFFER_OR_DATA
3214 }
3215
3216 static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
3217     BOOL useVertexShaderFunction = FALSE, updateFog = FALSE;
3218     BOOL usePixelShaderFunction = stateblock->wineD3DDevice->ps_selected_mode != SHADER_NONE && stateblock->pixelShader
3219             && ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.function;
3220     BOOL transformed;
3221     /* Some stuff is in the device until we have per context tracking */
3222     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
3223     BOOL wasrhw = context->last_was_rhw;
3224
3225     /* Shaders can be implemented using ARB_PROGRAM, GLSL, or software -
3226      * here simply check whether a shader was set, or the user disabled shaders
3227      */
3228     if (device->vs_selected_mode != SHADER_NONE && stateblock->vertexShader &&
3229        ((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.function != NULL) {
3230         useVertexShaderFunction = TRUE;
3231
3232         if(((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.reg_maps.fog != context->last_was_foggy_shader) {
3233             updateFog = TRUE;
3234         }
3235     } else if(context->last_was_foggy_shader) {
3236         updateFog = TRUE;
3237     }
3238
3239     handleStreams(stateblock, useVertexShaderFunction, context);
3240
3241     transformed = device->strided_streams.u.s.position_transformed;
3242     if (transformed) useVertexShaderFunction = FALSE;
3243
3244     if(transformed != context->last_was_rhw && !useVertexShaderFunction) {
3245         updateFog = TRUE;
3246     }
3247
3248     /* Reapply lighting if it is not scheduled for reapplication already */
3249     if(!isStateDirty(context, STATE_RENDER(WINED3DRS_LIGHTING))) {
3250         state_lighting(STATE_RENDER(WINED3DRS_LIGHTING), stateblock, context);
3251     }
3252
3253     if (transformed) {
3254         context->last_was_rhw = TRUE;
3255     } else {
3256
3257         /* Untransformed, so relies on the view and projection matrices */
3258         context->last_was_rhw = FALSE;
3259         /* This turns off the Z scale trick to 'disable' viewport frustum clipping in rhw mode*/
3260         device->untransformed = TRUE;
3261
3262         /* Todo for sw shaders: Vertex Shader output is already transformed, so set up identity matrices
3263          * Not needed as long as only hw shaders are supported
3264          */
3265
3266         /* This sets the shader output position correction constants.
3267          * TODO: Move to the viewport state
3268          */
3269         if (useVertexShaderFunction) {
3270             device->posFixup[1] = device->render_offscreen ? -1.0 : 1.0;
3271         }
3272     }
3273
3274     /* Don't have to apply the matrices when vertex shaders are used. When vshaders are turned
3275      * off this function will be called again anyway to make sure they're properly set
3276      */
3277     if(!useVertexShaderFunction) {
3278         /* TODO: Move this mainly to the viewport state and only apply when the vp has changed
3279          * or transformed / untransformed was switched
3280          */
3281        if(wasrhw != context->last_was_rhw &&
3282           !isStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION)) &&
3283           !isStateDirty(context, STATE_VIEWPORT)) {
3284             transform_projection(STATE_TRANSFORM(WINED3DTS_PROJECTION), stateblock, context);
3285         }
3286         /* World matrix needs reapplication here only if we're switching between rhw and non-rhw
3287          * mode.
3288          *
3289          * If a vertex shader is used, the world matrix changed and then vertex shader unbound
3290          * this check will fail and the matrix not applied again. This is OK because a simple
3291          * world matrix change reapplies the matrix - These checks here are only to satisfy the
3292          * needs of the vertex declaration.
3293          *
3294          * World and view matrix go into the same gl matrix, so only apply them when neither is
3295          * dirty
3296          */
3297         if(transformed != wasrhw &&
3298            !isStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0))) &&
3299            !isStateDirty(context, STATE_TRANSFORM(WINED3DTS_VIEW))) {
3300             transform_world(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), stateblock, context);
3301         }
3302
3303         if(!isStateDirty(context, STATE_RENDER(WINED3DRS_COLORVERTEX))) {
3304             state_colormat(STATE_RENDER(WINED3DRS_COLORVERTEX), stateblock, context);
3305         }
3306
3307         if(context->last_was_vshader && !isStateDirty(context, STATE_RENDER(WINED3DRS_CLIPPLANEENABLE))) {
3308             state_clipping(STATE_RENDER(WINED3DRS_CLIPPLANEENABLE), stateblock, context);
3309         }
3310     } else {
3311         /* We compile the shader here because we need the vertex declaration
3312          * in order to determine if we need to do any swizzling for D3DCOLOR
3313          * registers. If the shader is already compiled this call will do nothing. */
3314         IWineD3DVertexShader_CompileShader(stateblock->vertexShader);
3315
3316         if(!context->last_was_vshader) {
3317             int i;
3318             static BOOL warned = FALSE;
3319             /* Disable all clip planes to get defined results on all drivers. See comment in the
3320              * state_clipping state handler
3321              */
3322             for(i = 0; i < GL_LIMITS(clipplanes); i++) {
3323                 glDisable(GL_CLIP_PLANE0 + i);
3324                 checkGLcall("glDisable(GL_CLIP_PLANE0 + i)");
3325             }
3326
3327             if(!warned && stateblock->renderState[WINED3DRS_CLIPPLANEENABLE]) {
3328                 FIXME("Clipping not supported with vertex shaders\n");
3329                 warned = TRUE;
3330             }
3331         }
3332     }
3333
3334     /* Vertex and pixel shaders are applied together for now, so let the last dirty state do the
3335      * application
3336      */
3337     if (!isStateDirty(context, STATE_PIXELSHADER)) {
3338         device->shader_backend->shader_select((IWineD3DDevice *)device, usePixelShaderFunction, useVertexShaderFunction);
3339
3340         if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && (useVertexShaderFunction || usePixelShaderFunction)) {
3341             shaderconstant(STATE_VERTEXSHADERCONSTANT, stateblock, context);
3342         }
3343     }
3344
3345     context->last_was_vshader = useVertexShaderFunction;
3346
3347     if(updateFog) {
3348         state_fog(STATE_RENDER(WINED3DRS_FOGENABLE), stateblock, context);
3349     }
3350     if(!useVertexShaderFunction) {
3351         int i;
3352         for(i = 0; i < MAX_TEXTURES; i++) {
3353             if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_TEXTURE0 + i))) {
3354                 transform_texture(STATE_TRANSFORM(WINED3DTS_TEXTURE0 + i), stateblock, context);
3355             }
3356         }
3357     }
3358 }
3359
3360 static void viewport(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
3361     glDepthRange(stateblock->viewport.MinZ, stateblock->viewport.MaxZ);
3362     checkGLcall("glDepthRange");
3363     /* Note: GL requires lower left, DirectX supplies upper left. This is reversed when using offscreen rendering
3364      */
3365     if(stateblock->wineD3DDevice->render_offscreen) {
3366         glViewport(stateblock->viewport.X,
3367                    stateblock->viewport.Y,
3368                    stateblock->viewport.Width, stateblock->viewport.Height);
3369     } else {
3370         glViewport(stateblock->viewport.X,
3371                    (((IWineD3DSurfaceImpl *)stateblock->wineD3DDevice->render_targets[0])->currentDesc.Height - (stateblock->viewport.Y + stateblock->viewport.Height)),
3372                    stateblock->viewport.Width, stateblock->viewport.Height);
3373     }
3374
3375     checkGLcall("glViewport");
3376
3377     stateblock->wineD3DDevice->posFixup[2] = 1.0 / stateblock->viewport.Width;
3378     stateblock->wineD3DDevice->posFixup[3] = -1.0 / stateblock->viewport.Height;
3379     if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION))) {
3380         transform_projection(STATE_TRANSFORM(WINED3DTS_PROJECTION), stateblock, context);
3381     }
3382
3383 }
3384
3385 static void light(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
3386     UINT Index = state - STATE_ACTIVELIGHT(0);
3387     PLIGHTINFOEL *lightInfo = stateblock->activeLights[Index];
3388
3389     if(!lightInfo) {
3390         glDisable(GL_LIGHT0 + Index);
3391         checkGLcall("glDisable(GL_LIGHT0 + Index)");
3392     } else {
3393         float quad_att;
3394         float colRGBA[] = {0.0, 0.0, 0.0, 0.0};
3395
3396         /* Light settings are affected by the model view in OpenGL, the View transform in direct3d*/
3397         glMatrixMode(GL_MODELVIEW);
3398         glPushMatrix();
3399         glLoadMatrixf((float *)&stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
3400
3401         /* Diffuse: */
3402         colRGBA[0] = lightInfo->OriginalParms.Diffuse.r;
3403         colRGBA[1] = lightInfo->OriginalParms.Diffuse.g;
3404         colRGBA[2] = lightInfo->OriginalParms.Diffuse.b;
3405         colRGBA[3] = lightInfo->OriginalParms.Diffuse.a;
3406         glLightfv(GL_LIGHT0 + Index, GL_DIFFUSE, colRGBA);
3407         checkGLcall("glLightfv");
3408
3409         /* Specular */
3410         colRGBA[0] = lightInfo->OriginalParms.Specular.r;
3411         colRGBA[1] = lightInfo->OriginalParms.Specular.g;
3412         colRGBA[2] = lightInfo->OriginalParms.Specular.b;
3413         colRGBA[3] = lightInfo->OriginalParms.Specular.a;
3414         glLightfv(GL_LIGHT0 + Index, GL_SPECULAR, colRGBA);
3415         checkGLcall("glLightfv");
3416
3417         /* Ambient */
3418         colRGBA[0] = lightInfo->OriginalParms.Ambient.r;
3419         colRGBA[1] = lightInfo->OriginalParms.Ambient.g;
3420         colRGBA[2] = lightInfo->OriginalParms.Ambient.b;
3421         colRGBA[3] = lightInfo->OriginalParms.Ambient.a;
3422         glLightfv(GL_LIGHT0 + Index, GL_AMBIENT, colRGBA);
3423         checkGLcall("glLightfv");
3424
3425         if ((lightInfo->OriginalParms.Range *lightInfo->OriginalParms.Range) >= FLT_MIN) {
3426             quad_att = 1.4/(lightInfo->OriginalParms.Range *lightInfo->OriginalParms.Range);
3427         } else {
3428             quad_att = 0; /*  0 or  MAX?  (0 seems to be ok) */
3429         }
3430
3431         /* Do not assign attenuation values for lights that do not use them. D3D apps are free to pass any junk,
3432          * but gl drivers use them and may crash due to bad Attenuation values. Need for Speed most wanted sets
3433          * Attenuation0 to NaN and crashes in the gl lib
3434          */
3435
3436         switch (lightInfo->OriginalParms.Type) {
3437             case WINED3DLIGHT_POINT:
3438                 /* Position */
3439                 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
3440                 checkGLcall("glLightfv");
3441                 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
3442                 checkGLcall("glLightf");
3443                 /* Attenuation - Are these right? guessing... */
3444                 glLightf(GL_LIGHT0 + Index, GL_CONSTANT_ATTENUATION,  lightInfo->OriginalParms.Attenuation0);
3445                 checkGLcall("glLightf");
3446                 glLightf(GL_LIGHT0 + Index, GL_LINEAR_ATTENUATION,    lightInfo->OriginalParms.Attenuation1);
3447                 checkGLcall("glLightf");
3448                 if (quad_att < lightInfo->OriginalParms.Attenuation2) quad_att = lightInfo->OriginalParms.Attenuation2;
3449                 glLightf(GL_LIGHT0 + Index, GL_QUADRATIC_ATTENUATION, quad_att);
3450                 checkGLcall("glLightf");
3451                 /* FIXME: Range */
3452                 break;
3453
3454             case WINED3DLIGHT_SPOT:
3455                 /* Position */
3456                 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
3457                 checkGLcall("glLightfv");
3458                 /* Direction */
3459                 glLightfv(GL_LIGHT0 + Index, GL_SPOT_DIRECTION, &lightInfo->lightDirn[0]);
3460                 checkGLcall("glLightfv");
3461                 glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, lightInfo->exponent);
3462                 checkGLcall("glLightf");
3463                 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
3464                 checkGLcall("glLightf");
3465                 /* Attenuation - Are these right? guessing... */
3466                 glLightf(GL_LIGHT0 + Index, GL_CONSTANT_ATTENUATION,  lightInfo->OriginalParms.Attenuation0);
3467                 checkGLcall("glLightf");
3468                 glLightf(GL_LIGHT0 + Index, GL_LINEAR_ATTENUATION,    lightInfo->OriginalParms.Attenuation1);
3469                 checkGLcall("glLightf");
3470                 if (quad_att < lightInfo->OriginalParms.Attenuation2) quad_att = lightInfo->OriginalParms.Attenuation2;
3471                 glLightf(GL_LIGHT0 + Index, GL_QUADRATIC_ATTENUATION, quad_att);
3472                 checkGLcall("glLightf");
3473                 /* FIXME: Range */
3474                 break;
3475
3476             case WINED3DLIGHT_DIRECTIONAL:
3477                 /* Direction */
3478                 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]); /* Note gl uses w position of 0 for direction! */
3479                 checkGLcall("glLightfv");
3480                 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
3481                 checkGLcall("glLightf");
3482                 glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, 0.0f);
3483                 checkGLcall("glLightf");
3484                 break;
3485
3486             default:
3487                 FIXME("Unrecognized light type %d\n", lightInfo->OriginalParms.Type);
3488         }
3489
3490         /* Restore the modelview matrix */
3491         glPopMatrix();
3492
3493         glEnable(GL_LIGHT0 + Index);
3494         checkGLcall("glEnable(GL_LIGHT0 + Index)");
3495     }
3496
3497     return;
3498 }
3499
3500 static void scissorrect(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
3501     IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *) stateblock->wineD3DDevice->swapchains[0];
3502     RECT *pRect = &stateblock->scissorRect;
3503     RECT windowRect;
3504     UINT winHeight;
3505
3506     GetClientRect(swapchain->win_handle, &windowRect);
3507     /* Warning: glScissor uses window coordinates, not viewport coordinates, so our viewport correction does not apply
3508      * Warning2: Even in windowed mode the coords are relative to the window, not the screen
3509      */
3510     winHeight = windowRect.bottom - windowRect.top;
3511     TRACE("(%p) Setting new Scissor Rect to %d:%d-%d:%d\n", stateblock->wineD3DDevice, pRect->left, pRect->bottom - winHeight,
3512           pRect->right - pRect->left, pRect->bottom - pRect->top);
3513
3514     if (stateblock->wineD3DDevice->render_offscreen) {
3515         glScissor(pRect->left, pRect->top, pRect->right - pRect->left, pRect->bottom - pRect->top);
3516     } else {
3517         glScissor(pRect->left, winHeight - pRect->bottom, pRect->right - pRect->left, pRect->bottom - pRect->top);
3518     }
3519     checkGLcall("glScissor");
3520 }
3521
3522 static void indexbuffer(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
3523     if(GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT)) {
3524         if(stateblock->streamIsUP || stateblock->pIndexData == NULL ) {
3525             GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0));
3526         } else {
3527             IWineD3DIndexBufferImpl *ib = (IWineD3DIndexBufferImpl *) stateblock->pIndexData;
3528             GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, ib->vbo));
3529         }
3530     }
3531 }
3532
3533 const struct StateEntry StateTable[] =
3534 {
3535       /* State name                                         representative,                                     apply function */
3536     { /* 0,  Undefined                              */      0,                                                  state_undefined     },
3537     { /* 1,  WINED3DRS_TEXTUREHANDLE                */      0 /* Handled in ddraw */,                           state_undefined     },
3538     { /* 2,  WINED3DRS_ANTIALIAS                    */      STATE_RENDER(WINED3DRS_ANTIALIAS),                  state_antialias     },
3539     { /* 3,  WINED3DRS_TEXTUREADDRESS               */      0 /* Handled in ddraw */,                           state_undefined     },
3540     { /* 4,  WINED3DRS_TEXTUREPERSPECTIVE           */      STATE_RENDER(WINED3DRS_TEXTUREPERSPECTIVE),         state_perspective   },
3541     { /* 5,  WINED3DRS_WRAPU                        */      STATE_RENDER(WINED3DRS_WRAPU),                      state_wrapu         },
3542     { /* 6,  WINED3DRS_WRAPV                        */      STATE_RENDER(WINED3DRS_WRAPV),                      state_wrapv         },
3543     { /* 7,  WINED3DRS_ZENABLE                      */      STATE_RENDER(WINED3DRS_ZENABLE),                    state_zenable       },
3544     { /* 8,  WINED3DRS_FILLMODE                     */      STATE_RENDER(WINED3DRS_FILLMODE),                   state_fillmode      },
3545     { /* 9,  WINED3DRS_SHADEMODE                    */      STATE_RENDER(WINED3DRS_SHADEMODE),                  state_shademode     },
3546     { /* 10, WINED3DRS_LINEPATTERN                  */      STATE_RENDER(WINED3DRS_LINEPATTERN),                state_linepattern   },
3547     { /* 11, WINED3DRS_MONOENABLE                   */      STATE_RENDER(WINED3DRS_MONOENABLE),                 state_monoenable    },
3548     { /* 12, WINED3DRS_ROP2                         */      STATE_RENDER(WINED3DRS_ROP2),                       state_rop2          },
3549     { /* 13, WINED3DRS_PLANEMASK                    */      STATE_RENDER(WINED3DRS_PLANEMASK),                  state_planemask     },
3550     { /* 14, WINED3DRS_ZWRITEENABLE                 */      STATE_RENDER(WINED3DRS_ZWRITEENABLE),               state_zwritenable   },
3551     { /* 15, WINED3DRS_ALPHATESTENABLE              */      STATE_RENDER(WINED3DRS_ALPHATESTENABLE),            state_alpha         },
3552     { /* 16, WINED3DRS_LASTPIXEL                    */      STATE_RENDER(WINED3DRS_LASTPIXEL),                  state_lastpixel     },
3553     { /* 17, WINED3DRS_TEXTUREMAG                   */      0 /* Handled in ddraw */,                           state_undefined     },
3554     { /* 18, WINED3DRS_TEXTUREMIN                   */      0 /* Handled in ddraw */,                           state_undefined     },
3555     { /* 19, WINED3DRS_SRCBLEND                     */      STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         },
3556     { /* 20, WINED3DRS_DESTBLEND                    */      STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         },
3557     { /* 21, WINED3DRS_TEXTUREMAPBLEND              */      0 /* Handled in ddraw */,                           state_undefined     },
3558     { /* 22, WINED3DRS_CULLMODE                     */      STATE_RENDER(WINED3DRS_CULLMODE),                   state_cullmode      },
3559     { /* 23, WINED3DRS_ZFUNC                        */      STATE_RENDER(WINED3DRS_ZFUNC),                      state_zfunc         },
3560     { /* 24, WINED3DRS_ALPHAREF                     */      STATE_RENDER(WINED3DRS_ALPHATESTENABLE),            state_alpha         },
3561     { /* 25, WINED3DRS_ALPHAFUNC                    */      STATE_RENDER(WINED3DRS_ALPHATESTENABLE),            state_alpha         },
3562     { /* 26, WINED3DRS_DITHERENABLE                 */      STATE_RENDER(WINED3DRS_DITHERENABLE),               state_ditherenable  },
3563     { /* 27, WINED3DRS_ALPHABLENDENABLE             */      STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         },
3564     { /* 28, WINED3DRS_FOGENABLE                    */      STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog           },
3565     { /* 29, WINED3DRS_SPECULARENABLE               */      STATE_RENDER(WINED3DRS_SPECULARENABLE),             state_specularenable},
3566     { /* 30, WINED3DRS_ZVISIBLE                     */      0 /* Not supported according to the msdn */,        state_nogl          },
3567     { /* 31, WINED3DRS_SUBPIXEL                     */      STATE_RENDER(WINED3DRS_SUBPIXEL),                   state_subpixel      },
3568     { /* 32, WINED3DRS_SUBPIXELX                    */      STATE_RENDER(WINED3DRS_SUBPIXELX),                  state_subpixelx     },
3569     { /* 33, WINED3DRS_STIPPLEDALPHA                */      STATE_RENDER(WINED3DRS_STIPPLEDALPHA),              state_stippledalpha },
3570     { /* 34, WINED3DRS_FOGCOLOR                     */      STATE_RENDER(WINED3DRS_FOGCOLOR),                   state_fogcolor      },
3571     { /* 35, WINED3DRS_FOGTABLEMODE                 */      STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog           },
3572     { /* 36, WINED3DRS_FOGSTART                     */      STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog           },
3573     { /* 37, WINED3DRS_FOGEND                       */      STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog           },
3574     { /* 38, WINED3DRS_FOGDENSITY                   */      STATE_RENDER(WINED3DRS_FOGDENSITY),                 state_fogdensity    },
3575     { /* 39, WINED3DRS_STIPPLEENABLE                */      STATE_RENDER(WINED3DRS_STIPPLEENABLE),              state_stippleenable },
3576     { /* 40, WINED3DRS_EDGEANTIALIAS                */      STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         },
3577     { /* 41, WINED3DRS_COLORKEYENABLE               */      STATE_RENDER(WINED3DRS_ALPHATESTENABLE),            state_alpha         },
3578     { /* 42, undefined                              */      0,                                                  state_undefined     },
3579     { /* 43, WINED3DRS_BORDERCOLOR                  */      STATE_RENDER(WINED3DRS_BORDERCOLOR),                state_bordercolor   },
3580     { /* 44, WINED3DRS_TEXTUREADDRESSU              */      0, /* Handled in ddraw */                           state_undefined     },
3581     { /* 45, WINED3DRS_TEXTUREADDRESSV              */      0, /* Handled in ddraw */                           state_undefined     },
3582     { /* 46, WINED3DRS_MIPMAPLODBIAS                */      STATE_RENDER(WINED3DRS_MIPMAPLODBIAS),              state_mipmaplodbias },
3583     { /* 47, WINED3DRS_ZBIAS                        */      STATE_RENDER(WINED3DRS_ZBIAS),                      state_zbias         },
3584     { /* 48, WINED3DRS_RANGEFOGENABLE               */      STATE_RENDER(WINED3DRS_RANGEFOGENABLE),             state_rangefog      },
3585     { /* 49, WINED3DRS_ANISOTROPY                   */      STATE_RENDER(WINED3DRS_ANISOTROPY),                 state_anisotropy    },
3586     { /* 50, WINED3DRS_FLUSHBATCH                   */      STATE_RENDER(WINED3DRS_FLUSHBATCH),                 state_flushbatch    },
3587     { /* 51, WINED3DRS_TRANSLUCENTSORTINDEPENDENT   */      STATE_RENDER(WINED3DRS_TRANSLUCENTSORTINDEPENDENT), state_translucentsi },
3588     { /* 52, WINED3DRS_STENCILENABLE                */      STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       },
3589     { /* 53, WINED3DRS_STENCILFAIL                  */      STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       },
3590     { /* 54, WINED3DRS_STENCILZFAIL                 */      STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       },
3591     { /* 55, WINED3DRS_STENCILPASS                  */      STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       },
3592     { /* 56, WINED3DRS_STENCILFUNC                  */      STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       },
3593     { /* 57, WINED3DRS_STENCILREF                   */      STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       },
3594     { /* 58, WINED3DRS_STENCILMASK                  */      STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       },
3595     { /* 59, WINED3DRS_STENCILWRITEMASK             */      STATE_RENDER(WINED3DRS_STENCILWRITEMASK),           state_stencilwrite  },
3596     { /* 60, WINED3DRS_TEXTUREFACTOR                */      STATE_RENDER(WINED3DRS_TEXTUREFACTOR),              state_texfactor     },
3597     { /* 61, Undefined                              */      0,                                                  state_undefined     },
3598     { /* 62, Undefined                              */      0,                                                  state_undefined     },
3599     { /* 63, Undefined                              */      0,                                                  state_undefined     },
3600     { /* 64, WINED3DRS_STIPPLEPATTERN00             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
3601     { /* 65, WINED3DRS_STIPPLEPATTERN01             */      0 /* Obsolete, should he handled by ddraw */,       state_undefined     },
3602     { /* 66, WINED3DRS_STIPPLEPATTERN02             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
3603     { /* 67, WINED3DRS_STIPPLEPATTERN03             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
3604     { /* 68, WINED3DRS_STIPPLEPATTERN04             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
3605     { /* 69, WINED3DRS_STIPPLEPATTERN05             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
3606     { /* 70, WINED3DRS_STIPPLEPATTERN06             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
3607     { /* 71, WINED3DRS_STIPPLEPATTERN07             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
3608     { /* 72, WINED3DRS_STIPPLEPATTERN08             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
3609     { /* 73, WINED3DRS_STIPPLEPATTERN09             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
3610     { /* 74, WINED3DRS_STIPPLEPATTERN10             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
3611     { /* 75, WINED3DRS_STIPPLEPATTERN11             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
3612     { /* 76, WINED3DRS_STIPPLEPATTERN12             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
3613     { /* 77, WINED3DRS_STIPPLEPATTERN13             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
3614     { /* 78, WINED3DRS_STIPPLEPATTERN14             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
3615     { /* 79, WINED3DRS_STIPPLEPATTERN15             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
3616     { /* 80, WINED3DRS_STIPPLEPATTERN16             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
3617     { /* 81, WINED3DRS_STIPPLEPATTERN17             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
3618     { /* 82, WINED3DRS_STIPPLEPATTERN18             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
3619     { /* 83, WINED3DRS_STIPPLEPATTERN19             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
3620     { /* 84, WINED3DRS_STIPPLEPATTERN20             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
3621     { /* 85, WINED3DRS_STIPPLEPATTERN21             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
3622     { /* 86, WINED3DRS_STIPPLEPATTERN22             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
3623     { /* 87, WINED3DRS_STIPPLEPATTERN23             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
3624     { /* 88, WINED3DRS_STIPPLEPATTERN24             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
3625     { /* 89, WINED3DRS_STIPPLEPATTERN25             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
3626     { /* 90, WINED3DRS_STIPPLEPATTERN26             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
3627     { /* 91, WINED3DRS_STIPPLEPATTERN27             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
3628     { /* 92, WINED3DRS_STIPPLEPATTERN28             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
3629     { /* 93, WINED3DRS_STIPPLEPATTERN29             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
3630     { /* 94, WINED3DRS_STIPPLEPATTERN30             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
3631     { /* 95, WINED3DRS_STIPPLEPATTERN31             */      0 /* Obsolete, should be handled by ddraw */,       state_undefined     },
3632     { /* 96, Undefined                              */      0,                                                  state_undefined     },
3633     { /* 97, Undefined                              */      0,                                                  state_undefined     },
3634     { /* 98, Undefined                              */      0,                                                  state_undefined     },
3635     { /* 99, Undefined                              */      0,                                                  state_undefined     },
3636     { /*100, Undefined                              */      0,                                                  state_undefined     },
3637     { /*101, Undefined                              */      0,                                                  state_undefined     },
3638     { /*102, Undefined                              */      0,                                                  state_undefined     },
3639     { /*103, Undefined                              */      0,                                                  state_undefined     },
3640     { /*104, Undefined                              */      0,                                                  state_undefined     },
3641     { /*105, Undefined                              */      0,                                                  state_undefined     },
3642     { /*106, Undefined                              */      0,                                                  state_undefined     },
3643     { /*107, Undefined                              */      0,                                                  state_undefined     },
3644     { /*108, Undefined                              */      0,                                                  state_undefined     },
3645     { /*109, Undefined                              */      0,                                                  state_undefined     },
3646     { /*110, Undefined                              */      0,                                                  state_undefined     },
3647     { /*111, Undefined                              */      0,                                                  state_undefined     },
3648     { /*112, Undefined                              */      0,                                                  state_undefined     },
3649     { /*113, Undefined                              */      0,                                                  state_undefined     },
3650     { /*114, Undefined                              */      0,                                                  state_undefined     },
3651     { /*115, Undefined                              */      0,                                                  state_undefined     },
3652     { /*116, Undefined                              */      0,                                                  state_undefined     },
3653     { /*117, Undefined                              */      0,                                                  state_undefined     },
3654     { /*118, Undefined                              */      0,                                                  state_undefined     },
3655     { /*119, Undefined                              */      0,                                                  state_undefined     },
3656     { /*120, Undefined                              */      0,                                                  state_undefined     },
3657     { /*121, Undefined                              */      0,                                                  state_undefined     },
3658     { /*122, Undefined                              */      0,                                                  state_undefined     },
3659     { /*123, Undefined                              */      0,                                                  state_undefined     },
3660     { /*124, Undefined                              */      0,                                                  state_undefined     },
3661     { /*125, Undefined                              */      0,                                                  state_undefined     },
3662     { /*126, Undefined                              */      0,                                                  state_undefined     },
3663     { /*127, Undefined                              */      0,                                                  state_undefined     },
3664     /* Big hole ends */
3665     { /*128, WINED3DRS_WRAP0                        */      STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          },
3666     { /*129, WINED3DRS_WRAP1                        */      STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          },
3667     { /*130, WINED3DRS_WRAP2                        */      STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          },
3668     { /*131, WINED3DRS_WRAP3                        */      STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          },
3669     { /*132, WINED3DRS_WRAP4                        */      STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          },
3670     { /*133, WINED3DRS_WRAP5                        */      STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          },
3671     { /*134, WINED3DRS_WRAP6                        */      STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          },
3672     { /*135, WINED3DRS_WRAP7                        */      STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          },
3673     { /*136, WINED3DRS_CLIPPING                     */      STATE_RENDER(WINED3DRS_CLIPPING),                   state_clipping      },
3674     { /*137, WINED3DRS_LIGHTING                     */      STATE_RENDER(WINED3DRS_LIGHTING),                   state_lighting      },
3675     { /*138, WINED3DRS_EXTENTS                      */      STATE_RENDER(WINED3DRS_EXTENTS),                    state_extents       },
3676     { /*139, WINED3DRS_AMBIENT                      */      STATE_RENDER(WINED3DRS_AMBIENT),                    state_ambient       },
3677     { /*140, WINED3DRS_FOGVERTEXMODE                */      STATE_RENDER(WINED3DRS_FOGENABLE),                  state_fog           },
3678     { /*141, WINED3DRS_COLORVERTEX                  */      STATE_RENDER(WINED3DRS_COLORVERTEX),                state_colormat      },
3679     { /*142, WINED3DRS_LOCALVIEWER                  */      STATE_RENDER(WINED3DRS_LOCALVIEWER),                state_localviewer   },
3680     { /*143, WINED3DRS_NORMALIZENORMALS             */      STATE_RENDER(WINED3DRS_NORMALIZENORMALS),           state_normalize     },
3681     { /*144, WINED3DRS_COLORKEYBLENDENABLE          */      STATE_RENDER(WINED3DRS_COLORKEYBLENDENABLE),        state_ckeyblend     },
3682     { /*145, WINED3DRS_DIFFUSEMATERIALSOURCE        */      STATE_RENDER(WINED3DRS_COLORVERTEX),                state_colormat      },
3683     { /*146, WINED3DRS_SPECULARMATERIALSOURCE       */      STATE_RENDER(WINED3DRS_COLORVERTEX),                state_colormat      },
3684     { /*147, WINED3DRS_AMBIENTMATERIALSOURCE        */      STATE_RENDER(WINED3DRS_COLORVERTEX),                state_colormat      },
3685     { /*148, WINED3DRS_EMISSIVEMATERIALSOURCE       */      STATE_RENDER(WINED3DRS_COLORVERTEX),                state_colormat      },
3686     { /*149, Undefined                              */      0,                                                  state_undefined     },
3687     { /*150, Undefined                              */      0,                                                  state_undefined     },
3688     { /*151, WINED3DRS_VERTEXBLEND                  */      STATE_RENDER(WINED3DRS_VERTEXBLEND),                state_vertexblend   },
3689     { /*152, WINED3DRS_CLIPPLANEENABLE              */      STATE_RENDER(WINED3DRS_CLIPPING),                   state_clipping      },
3690     { /*153, WINED3DRS_SOFTWAREVERTEXPROCESSING     */      0,                                                  state_nogl          },
3691     { /*154, WINED3DRS_POINTSIZE                    */      STATE_RENDER(WINED3DRS_POINTSIZE),                  state_psize         },
3692     { /*155, WINED3DRS_POINTSIZE_MIN                */      STATE_RENDER(WINED3DRS_POINTSIZE_MIN),              state_psizemin      },
3693     { /*156, WINED3DRS_POINTSPRITEENABLE            */      STATE_RENDER(WINED3DRS_POINTSPRITEENABLE),          state_pointsprite   },
3694     { /*157, WINED3DRS_POINTSCALEENABLE             */      STATE_RENDER(WINED3DRS_POINTSCALEENABLE),           state_pscale        },
3695     { /*158, WINED3DRS_POINTSCALE_A                 */      STATE_RENDER(WINED3DRS_POINTSCALEENABLE),           state_pscale        },
3696     { /*159, WINED3DRS_POINTSCALE_B                 */      STATE_RENDER(WINED3DRS_POINTSCALEENABLE),           state_pscale        },
3697     { /*160, WINED3DRS_POINTSCALE_C                 */      STATE_RENDER(WINED3DRS_POINTSCALEENABLE),           state_pscale        },
3698     { /*161, WINED3DRS_MULTISAMPLEANTIALIAS         */      STATE_RENDER(WINED3DRS_MULTISAMPLEANTIALIAS),       state_multisampleaa },
3699     { /*162, WINED3DRS_MULTISAMPLEMASK              */      STATE_RENDER(WINED3DRS_MULTISAMPLEMASK),            state_multisampmask },
3700     { /*163, WINED3DRS_PATCHEDGESTYLE               */      STATE_RENDER(WINED3DRS_PATCHEDGESTYLE),             state_patchedgestyle},
3701     { /*164, WINED3DRS_PATCHSEGMENTS                */      STATE_RENDER(WINED3DRS_PATCHSEGMENTS),              state_patchsegments },
3702     { /*165, WINED3DRS_DEBUGMONITORTOKEN            */      STATE_RENDER(WINED3DRS_DEBUGMONITORTOKEN),          state_nogl          },
3703     { /*166, WINED3DRS_POINTSIZE_MAX                */      STATE_RENDER(WINED3DRS_POINTSIZE_MAX),              state_psizemax      },
3704     { /*167, WINED3DRS_INDEXEDVERTEXBLENDENABLE     */      0,                                                  state_nogl          },
3705     { /*168, WINED3DRS_COLORWRITEENABLE             */      STATE_RENDER(WINED3DRS_COLORWRITEENABLE),           state_colorwrite    },
3706     { /*169, Undefined                              */      0,                                                  state_undefined     },
3707     { /*170, WINED3DRS_TWEENFACTOR                  */      0,                                                  state_nogl          },
3708     { /*171, WINED3DRS_BLENDOP                      */      STATE_RENDER(WINED3DRS_BLENDOP),                    state_blendop       },
3709     { /*172, WINED3DRS_POSITIONDEGREE               */      STATE_RENDER(WINED3DRS_POSITIONDEGREE),             state_positiondegree},
3710     { /*173, WINED3DRS_NORMALDEGREE                 */      STATE_RENDER(WINED3DRS_NORMALDEGREE),               state_normaldegree  },
3711       /*172, WINED3DRS_POSITIONORDER                */      /* Value assigned to 2 state names */
3712       /*173, WINED3DRS_NORMALORDER                  */      /* Value assigned to 2 state names */
3713     { /*174, WINED3DRS_SCISSORTESTENABLE            */      STATE_RENDER(WINED3DRS_SCISSORTESTENABLE),          state_scissor       },
3714     { /*175, WINED3DRS_SLOPESCALEDEPTHBIAS          */      STATE_RENDER(WINED3DRS_DEPTHBIAS),                  state_depthbias     },
3715     { /*176, WINED3DRS_ANTIALIASEDLINEENABLE        */      STATE_RENDER(WINED3DRS_ALPHABLENDENABLE),           state_blend         },
3716     { /*177, undefined                              */      0,                                                  state_undefined     },
3717     { /*178, WINED3DRS_MINTESSELLATIONLEVEL         */      STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation  },
3718     { /*179, WINED3DRS_MAXTESSELLATIONLEVEL         */      STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation  },
3719     { /*180, WINED3DRS_ADAPTIVETESS_X               */      STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation  },
3720     { /*181, WINED3DRS_ADAPTIVETESS_Y               */      STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation  },
3721     { /*182, WINED3DRS_ADAPTIVETESS_Z               */      STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation  },
3722     { /*183, WINED3DRS_ADAPTIVETESS_W               */      STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation  },
3723     { /*184, WINED3DRS_ENABLEADAPTIVETESSELLATION   */      STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation  },
3724     { /*185, WINED3DRS_TWOSIDEDSTENCILMODE          */      STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       },
3725     { /*186, WINED3DRS_CCW_STENCILFAIL              */      STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       },
3726     { /*187, WINED3DRS_CCW_STENCILZFAIL             */      STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       },
3727     { /*188, WINED3DRS_CCW_STENCILPASS              */      STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       },
3728     { /*189, WINED3DRS_CCW_STENCILFUNC              */      STATE_RENDER(WINED3DRS_STENCILENABLE),              state_stencil       },
3729     { /*190, WINED3DRS_COLORWRITEENABLE1            */      STATE_RENDER(WINED3DRS_COLORWRITEENABLE),           state_colorwrite    },
3730     { /*191, WINED3DRS_COLORWRITEENABLE2            */      STATE_RENDER(WINED3DRS_COLORWRITEENABLE),           state_colorwrite    },
3731     { /*192, WINED3DRS_COLORWRITEENABLE3            */      STATE_RENDER(WINED3DRS_COLORWRITEENABLE),           state_colorwrite    },
3732     { /*193, WINED3DRS_BLENDFACTOR                  */      STATE_RENDER(WINED3DRS_BLENDFACTOR),                state_blendfactor   },
3733     { /*194, WINED3DRS_SRGBWRITEENABLE              */      STATE_RENDER(WINED3DRS_SRGBWRITEENABLE),            state_srgbwrite     },
3734     { /*195, WINED3DRS_DEPTHBIAS                    */      STATE_RENDER(WINED3DRS_DEPTHBIAS),                  state_depthbias     },
3735     { /*196, undefined                              */      0,                                                  state_undefined     },
3736     { /*197, undefined                              */      0,                                                  state_undefined     },
3737     { /*198, WINED3DRS_WRAP8                        */      STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          },
3738     { /*199, WINED3DRS_WRAP9                        */      STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          },
3739     { /*200, WINED3DRS_WRAP10                       */      STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          },
3740     { /*201, WINED3DRS_WRAP11                       */      STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          },
3741     { /*202, WINED3DRS_WRAP12                       */      STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          },
3742     { /*203, WINED3DRS_WRAP13                       */      STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          },
3743     { /*204, WINED3DRS_WRAP14                       */      STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          },
3744     { /*205, WINED3DRS_WRAP15                       */      STATE_RENDER(WINED3DRS_WRAP0),                      state_wrap          },
3745     { /*206, WINED3DRS_SEPARATEALPHABLENDENABLE     */      STATE_RENDER(WINED3DRS_SEPARATEALPHABLENDENABLE),   state_separateblend },
3746     { /*207, WINED3DRS_SRCBLENDALPHA                */      STATE_RENDER(WINED3DRS_SEPARATEALPHABLENDENABLE),   state_separateblend },
3747     { /*208, WINED3DRS_DESTBLENDALPHA               */      STATE_RENDER(WINED3DRS_SEPARATEALPHABLENDENABLE),   state_separateblend },
3748     { /*209, WINED3DRS_BLENDOPALPHA                 */      STATE_RENDER(WINED3DRS_SEPARATEALPHABLENDENABLE),   state_separateblend },
3749     /* Texture stage states */
3750     { /*0, 01, WINED3DTSS_COLOROP                   */      STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          tex_colorop         },
3751     { /*0, 02, WINED3DTSS_COLORARG1                 */      STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          tex_colorop         },
3752     { /*0, 03, WINED3DTSS_COLORARG2                 */      STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          tex_colorop         },
3753     { /*0, 04, WINED3DTSS_ALPHAOP                   */      STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3754     { /*0, 05, WINED3DTSS_ALPHAARG1                 */      STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3755     { /*0, 06, WINED3DTSS_ALPHAARG2                 */      STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3756     { /*0, 07, WINED3DTSS_BUMPENVMAT00              */      STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      },
3757     { /*0, 08, WINED3DTSS_BUMPENVMAT01              */      STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      },
3758     { /*0, 09, WINED3DTSS_BUMPENVMAT10              */      STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      },
3759     { /*0, 10, WINED3DTSS_BUMPENVMAT11              */      STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      },
3760     { /*0, 11, WINED3DTSS_TEXCOORDINDEX             */      STATE_TEXTURESTAGE(0, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      },
3761     { /*0, 12, WINED3DTSS_ADDRESS                   */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3762     { /*0, 13, WINED3DTSS_ADDRESSU                  */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3763     { /*0, 14, WINED3DTSS_ADDRESSV                  */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3764     { /*0, 15, WINED3DTSS_BORDERCOLOR               */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3765     { /*0, 16, WINED3DTSS_MAGFILTER                 */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3766     { /*0, 17, WINED3DTSS_MINFILTER                 */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3767     { /*0, 18, WINED3DTSS_MIPFILTER                 */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3768     { /*0, 19, WINED3DTSS_MIPMAPLODBIAS             */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3769     { /*0, 20, WINED3DTSS_MAXMIPLEVEL               */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3770     { /*0, 21, WINED3DTSS_MAXANISOTROPY             */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3771     { /*0, 22, WINED3DTSS_BUMPENVLSCALE             */      STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   },
3772     { /*0, 23, WINED3DTSS_BUMPENVLOFFSET            */      STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLOFFSET),   tex_bumpenvloffset  },
3773     { /*0, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS     */      STATE_TRANSFORM(WINED3DTS_TEXTURE0),                transform_texture   },
3774     { /*0, 25, WINED3DTSS_ADDRESSW                  */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3775     { /*0, 26, WINED3DTSS_COLORARG0                 */      STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP),          tex_colorop         },
3776     { /*0, 27, WINED3DTSS_ALPHAARG0                 */      STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3777     { /*0, 28, WINED3DTSS_RESULTARG                 */      STATE_TEXTURESTAGE(0, WINED3DTSS_RESULTARG),        tex_resultarg       },
3778     { /*0, 29, undefined                            */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3779     { /*0, 30, undefined                            */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3780     { /*0, 31, undefined                            */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3781     { /*0, 32, WINED3DTSS_CONSTANT                  */      0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl          },
3782
3783     { /*1, 01, WINED3DTSS_COLOROP                   */      STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP),          tex_colorop         },
3784     { /*1, 02, WINED3DTSS_COLORARG1                 */      STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP),          tex_colorop         },
3785     { /*1, 03, WINED3DTSS_COLORARG2                 */      STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP),          tex_colorop         },
3786     { /*1, 04, WINED3DTSS_ALPHAOP                   */      STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3787     { /*1, 05, WINED3DTSS_ALPHAARG1                 */      STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3788     { /*1, 06, WINED3DTSS_ALPHAARG2                 */      STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3789     { /*1, 07, WINED3DTSS_BUMPENVMAT00              */      STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      },
3790     { /*1, 08, WINED3DTSS_BUMPENVMAT01              */      STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      },
3791     { /*1, 09, WINED3DTSS_BUMPENVMAT10              */      STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      },
3792     { /*1, 10, WINED3DTSS_BUMPENVMAT11              */      STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      },
3793     { /*1, 11, WINED3DTSS_TEXCOORDINDEX             */      STATE_TEXTURESTAGE(1, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      },
3794     { /*1, 12, WINED3DTSS_ADDRESS                   */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3795     { /*1, 13, WINED3DTSS_ADDRESSU                  */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3796     { /*1, 14, WINED3DTSS_ADDRESSV                  */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3797     { /*1, 15, WINED3DTSS_BORDERCOLOR               */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3798     { /*1, 16, WINED3DTSS_MAGFILTER                 */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3799     { /*1, 17, WINED3DTSS_MINFILTER                 */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3800     { /*1, 18, WINED3DTSS_MIPFILTER                 */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3801     { /*1, 19, WINED3DTSS_MIPMAPLODBIAS             */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3802     { /*1, 20, WINED3DTSS_MAXMIPLEVEL               */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3803     { /*1, 21, WINED3DTSS_MAXANISOTROPY             */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3804     { /*1, 22, WINED3DTSS_BUMPENVLSCALE             */      STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   },
3805     { /*1, 23, WINED3DTSS_BUMPENVLOFFSET            */      STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLOFFSET),   tex_bumpenvloffset  },
3806     { /*1, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS     */      STATE_TRANSFORM(WINED3DTS_TEXTURE1),                transform_texture   },
3807     { /*1, 25, WINED3DTSS_ADDRESSW                  */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3808     { /*1, 26, WINED3DTSS_COLORARG0                 */      STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP),          tex_colorop         },
3809     { /*1, 27, WINED3DTSS_ALPHAARG0                 */      STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3810     { /*1, 28, WINED3DTSS_RESULTARG                 */      STATE_TEXTURESTAGE(1, WINED3DTSS_RESULTARG),        tex_resultarg       },
3811     { /*1, 29, undefined                            */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3812     { /*1, 30, undefined                            */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3813     { /*1, 31, undefined                            */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3814     { /*1, 32, WINED3DTSS_CONSTANT                  */      0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl          },
3815
3816     { /*2, 01, WINED3DTSS_COLOROP                   */      STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP),          tex_colorop         },
3817     { /*2, 02, WINED3DTSS_COLORARG1                 */      STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP),          tex_colorop         },
3818     { /*2, 03, WINED3DTSS_COLORARG2                 */      STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP),          tex_colorop         },
3819     { /*2, 04, WINED3DTSS_ALPHAOP                   */      STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3820     { /*2, 05, WINED3DTSS_ALPHAARG1                 */      STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3821     { /*2, 06, WINED3DTSS_ALPHAARG2                 */      STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3822     { /*2, 07, WINED3DTSS_BUMPENVMAT00              */      STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      },
3823     { /*2, 08, WINED3DTSS_BUMPENVMAT01              */      STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      },
3824     { /*2, 09, WINED3DTSS_BUMPENVMAT10              */      STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      },
3825     { /*2, 10, WINED3DTSS_BUMPENVMAT11              */      STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      },
3826     { /*2, 11, WINED3DTSS_TEXCOORDINDEX             */      STATE_TEXTURESTAGE(2, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      },
3827     { /*2, 12, WINED3DTSS_ADDRESS                   */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3828     { /*2, 13, WINED3DTSS_ADDRESSU                  */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3829     { /*2, 14, WINED3DTSS_ADDRESSV                  */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3830     { /*2, 15, WINED3DTSS_BORDERCOLOR               */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3831     { /*2, 16, WINED3DTSS_MAGFILTER                 */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3832     { /*2, 17, WINED3DTSS_MINFILTER                 */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3833     { /*2, 18, WINED3DTSS_MIPFILTER                 */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3834     { /*2, 19, WINED3DTSS_MIPMAPLODBIAS             */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3835     { /*2, 20, WINED3DTSS_MAXMIPLEVEL               */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3836     { /*2, 21, WINED3DTSS_MAXANISOTROPY             */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3837     { /*2, 22, WINED3DTSS_BUMPENVLSCALE             */      STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   },
3838     { /*2, 23, WINED3DTSS_BUMPENVLOFFSET            */      STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLOFFSET),   tex_bumpenvloffset  },
3839     { /*2, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS     */      STATE_TRANSFORM(WINED3DTS_TEXTURE2),                transform_texture   },
3840     { /*2, 25, WINED3DTSS_ADDRESSW                  */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3841     { /*2, 26, WINED3DTSS_COLORARG0                 */      STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP),          tex_colorop         },
3842     { /*2, 27, WINED3DTSS_ALPHAARG0                 */      STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3843     { /*2, 28, WINED3DTSS_RESULTARG                 */      STATE_TEXTURESTAGE(2, WINED3DTSS_RESULTARG),        tex_resultarg       },
3844     { /*2, 29, undefined                            */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3845     { /*2, 30, undefined                            */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3846     { /*2, 31, undefined                            */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3847     { /*2, 32, WINED3DTSS_CONSTANT                  */      0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl          },
3848
3849     { /*3, 01, WINED3DTSS_COLOROP                   */      STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP),          tex_colorop         },
3850     { /*3, 02, WINED3DTSS_COLORARG1                 */      STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP),          tex_colorop         },
3851     { /*3, 03, WINED3DTSS_COLORARG2                 */      STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP),          tex_colorop         },
3852     { /*3, 04, WINED3DTSS_ALPHAOP                   */      STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3853     { /*3, 05, WINED3DTSS_ALPHAARG1                 */      STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3854     { /*3, 06, WINED3DTSS_ALPHAARG2                 */      STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3855     { /*3, 07, WINED3DTSS_BUMPENVMAT00              */      STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      },
3856     { /*3, 08, WINED3DTSS_BUMPENVMAT01              */      STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      },
3857     { /*3, 09, WINED3DTSS_BUMPENVMAT10              */      STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      },
3858     { /*3, 10, WINED3DTSS_BUMPENVMAT11              */      STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      },
3859     { /*3, 11, WINED3DTSS_TEXCOORDINDEX             */      STATE_TEXTURESTAGE(3, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      },
3860     { /*3, 12, WINED3DTSS_ADDRESS                   */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3861     { /*3, 13, WINED3DTSS_ADDRESSU                  */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3862     { /*3, 14, WINED3DTSS_ADDRESSV                  */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3863     { /*3, 15, WINED3DTSS_BORDERCOLOR               */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3864     { /*3, 16, WINED3DTSS_MAGFILTER                 */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3865     { /*3, 17, WINED3DTSS_MINFILTER                 */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3866     { /*3, 18, WINED3DTSS_MIPFILTER                 */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3867     { /*3, 19, WINED3DTSS_MIPMAPLODBIAS             */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3868     { /*3, 20, WINED3DTSS_MAXMIPLEVEL               */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3869     { /*3, 21, WINED3DTSS_MAXANISOTROPY             */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3870     { /*3, 22, WINED3DTSS_BUMPENVLSCALE             */      STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   },
3871     { /*3, 23, WINED3DTSS_BUMPENVLOFFSET            */      STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLOFFSET),   tex_bumpenvloffset  },
3872     { /*3, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS     */      STATE_TRANSFORM(WINED3DTS_TEXTURE3),                transform_texture   },
3873     { /*3, 25, WINED3DTSS_ADDRESSW                  */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3874     { /*3, 26, WINED3DTSS_COLORARG0                 */      STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP),          tex_colorop         },
3875     { /*3, 27, WINED3DTSS_ALPHAARG0                 */      STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3876     { /*3, 28, WINED3DTSS_RESULTARG                 */      STATE_TEXTURESTAGE(3, WINED3DTSS_RESULTARG),        tex_resultarg       },
3877     { /*3, 29, undefined                            */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3878     { /*3, 30, undefined                            */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3879     { /*3, 31, undefined                            */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3880     { /*3, 32, WINED3DTSS_CONSTANT                  */      0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl          },
3881
3882     { /*4, 01, WINED3DTSS_COLOROP                   */      STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP),          tex_colorop         },
3883     { /*4, 02, WINED3DTSS_COLORARG1                 */      STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP),          tex_colorop         },
3884     { /*4, 03, WINED3DTSS_COLORARG2                 */      STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP),          tex_colorop         },
3885     { /*4, 04, WINED3DTSS_ALPHAOP                   */      STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3886     { /*4, 05, WINED3DTSS_ALPHAARG1                 */      STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3887     { /*4, 06, WINED3DTSS_ALPHAARG2                 */      STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3888     { /*4, 07, WINED3DTSS_BUMPENVMAT00              */      STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      },
3889     { /*4, 08, WINED3DTSS_BUMPENVMAT01              */      STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      },
3890     { /*4, 09, WINED3DTSS_BUMPENVMAT10              */      STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      },
3891     { /*4, 10, WINED3DTSS_BUMPENVMAT11              */      STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      },
3892     { /*4, 11, WINED3DTSS_TEXCOORDINDEX             */      STATE_TEXTURESTAGE(4, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      },
3893     { /*4, 12, WINED3DTSS_ADDRESS                   */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3894     { /*4, 13, WINED3DTSS_ADDRESSU                  */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3895     { /*4, 14, WINED3DTSS_ADDRESSV                  */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3896     { /*4, 15, WINED3DTSS_BORDERCOLOR               */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3897     { /*4, 16, WINED3DTSS_MAGFILTER                 */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3898     { /*4, 17, WINED3DTSS_MINFILTER                 */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3899     { /*4, 18, WINED3DTSS_MIPFILTER                 */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3900     { /*4, 19, WINED3DTSS_MIPMAPLODBIAS             */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3901     { /*4, 20, WINED3DTSS_MAXMIPLEVEL               */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3902     { /*4, 21, WINED3DTSS_MAXANISOTROPY             */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3903     { /*4, 22, WINED3DTSS_BUMPENVLSCALE             */      STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   },
3904     { /*4, 23, WINED3DTSS_BUMPENVLOFFSET            */      STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLOFFSET),   tex_bumpenvloffset  },
3905     { /*4, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS     */      STATE_TRANSFORM(WINED3DTS_TEXTURE4),                transform_texture   },
3906     { /*4, 25, WINED3DTSS_ADDRESSW                  */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3907     { /*4, 26, WINED3DTSS_COLORARG0                 */      STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP),          tex_colorop         },
3908     { /*4, 27, WINED3DTSS_ALPHAARG0                 */      STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3909     { /*4, 28, WINED3DTSS_RESULTARG                 */      STATE_TEXTURESTAGE(4, WINED3DTSS_RESULTARG),        tex_resultarg       },
3910     { /*4, 29, undefined                            */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3911     { /*4, 30, undefined                            */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3912     { /*4, 31, undefined                            */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3913     { /*4, 32, WINED3DTSS_CONSTANT                  */      0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl          },
3914
3915     { /*5, 01, WINED3DTSS_COLOROP                   */      STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP),          tex_colorop         },
3916     { /*5, 02, WINED3DTSS_COLORARG1                 */      STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP),          tex_colorop         },
3917     { /*5, 03, WINED3DTSS_COLORARG2                 */      STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP),          tex_colorop         },
3918     { /*5, 04, WINED3DTSS_ALPHAOP                   */      STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3919     { /*5, 05, WINED3DTSS_ALPHAARG1                 */      STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3920     { /*5, 06, WINED3DTSS_ALPHAARG2                 */      STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3921     { /*5, 07, WINED3DTSS_BUMPENVMAT00              */      STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      },
3922     { /*5, 08, WINED3DTSS_BUMPENVMAT01              */      STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      },
3923     { /*5, 09, WINED3DTSS_BUMPENVMAT10              */      STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      },
3924     { /*5, 10, WINED3DTSS_BUMPENVMAT11              */      STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      },
3925     { /*5, 11, WINED3DTSS_TEXCOORDINDEX             */      STATE_TEXTURESTAGE(5, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      },
3926     { /*5, 12, WINED3DTSS_ADDRESS                   */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3927     { /*5, 13, WINED3DTSS_ADDRESSU                  */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3928     { /*5, 14, WINED3DTSS_ADDRESSV                  */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3929     { /*5, 15, WINED3DTSS_BORDERCOLOR               */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3930     { /*5, 16, WINED3DTSS_MAGFILTER                 */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3931     { /*5, 17, WINED3DTSS_MINFILTER                 */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3932     { /*5, 18, WINED3DTSS_MIPFILTER                 */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3933     { /*5, 19, WINED3DTSS_MIPMAPLODBIAS             */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3934     { /*5, 20, WINED3DTSS_MAXMIPLEVEL               */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3935     { /*5, 21, WINED3DTSS_MAXANISOTROPY             */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3936     { /*5, 22, WINED3DTSS_BUMPENVLSCALE             */      STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   },
3937     { /*5, 23, WINED3DTSS_BUMPENVLOFFSET            */      STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLOFFSET),   tex_bumpenvloffset  },
3938     { /*5, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS     */      STATE_TRANSFORM(WINED3DTS_TEXTURE5),                transform_texture   },
3939     { /*5, 25, WINED3DTSS_ADDRESSW                  */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3940     { /*5, 26, WINED3DTSS_COLORARG0                 */      STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP),          tex_colorop         },
3941     { /*5, 27, WINED3DTSS_ALPHAARG0                 */      STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3942     { /*5, 28, WINED3DTSS_RESULTARG                 */      STATE_TEXTURESTAGE(5, WINED3DTSS_RESULTARG),        tex_resultarg       },
3943     { /*5, 29, undefined                            */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3944     { /*5, 30, undefined                            */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3945     { /*5, 31, undefined                            */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3946     { /*5, 32, WINED3DTSS_CONSTANT                  */      0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl          },
3947
3948     { /*6, 01, WINED3DTSS_COLOROP                   */      STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP),          tex_colorop         },
3949     { /*6, 02, WINED3DTSS_COLORARG1                 */      STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP),          tex_colorop         },
3950     { /*6, 03, WINED3DTSS_COLORARG2                 */      STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP),          tex_colorop         },
3951     { /*6, 04, WINED3DTSS_ALPHAOP                   */      STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3952     { /*6, 05, WINED3DTSS_ALPHAARG1                 */      STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3953     { /*6, 06, WINED3DTSS_ALPHAARG2                 */      STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3954     { /*6, 07, WINED3DTSS_BUMPENVMAT00              */      STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      },
3955     { /*6, 08, WINED3DTSS_BUMPENVMAT01              */      STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      },
3956     { /*6, 09, WINED3DTSS_BUMPENVMAT10              */      STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      },
3957     { /*6, 10, WINED3DTSS_BUMPENVMAT11              */      STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      },
3958     { /*6, 11, WINED3DTSS_TEXCOORDINDEX             */      STATE_TEXTURESTAGE(6, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      },
3959     { /*6, 12, WINED3DTSS_ADDRESS                   */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3960     { /*6, 13, WINED3DTSS_ADDRESSU                  */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3961     { /*6, 14, WINED3DTSS_ADDRESSV                  */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3962     { /*6, 15, WINED3DTSS_BORDERCOLOR               */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3963     { /*6, 16, WINED3DTSS_MAGFILTER                 */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3964     { /*6, 17, WINED3DTSS_MINFILTER                 */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3965     { /*6, 18, WINED3DTSS_MIPFILTER                 */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3966     { /*6, 19, WINED3DTSS_MIPMAPLODBIAS             */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3967     { /*6, 20, WINED3DTSS_MAXMIPLEVEL               */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3968     { /*6, 21, WINED3DTSS_MAXANISOTROPY             */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3969     { /*6, 22, WINED3DTSS_BUMPENVLSCALE             */      STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   },
3970     { /*6, 23, WINED3DTSS_BUMPENVLOFFSET            */      STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLOFFSET),   tex_bumpenvloffset  },
3971     { /*6, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS     */      STATE_TRANSFORM(WINED3DTS_TEXTURE6),                transform_texture   },
3972     { /*6, 25, WINED3DTSS_ADDRESSW                  */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3973     { /*6, 26, WINED3DTSS_COLORARG0                 */      STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP),          tex_colorop         },
3974     { /*6, 27, WINED3DTSS_ALPHAARG0                 */      STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3975     { /*6, 28, WINED3DTSS_RESULTARG                 */      STATE_TEXTURESTAGE(6, WINED3DTSS_RESULTARG),        tex_resultarg       },
3976     { /*6, 29, undefined                            */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3977     { /*6, 30, undefined                            */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3978     { /*6, 31, undefined                            */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3979     { /*6, 32, WINED3DTSS_CONSTANT                  */      0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl          },
3980
3981     { /*7, 01, WINED3DTSS_COLOROP                   */      STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP),          tex_colorop         },
3982     { /*7, 02, WINED3DTSS_COLORARG1                 */      STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP),          tex_colorop         },
3983     { /*7, 03, WINED3DTSS_COLORARG2                 */      STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP),          tex_colorop         },
3984     { /*7, 04, WINED3DTSS_ALPHAOP                   */      STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3985     { /*7, 05, WINED3DTSS_ALPHAARG1                 */      STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3986     { /*7, 06, WINED3DTSS_ALPHAARG2                 */      STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP),          tex_alphaop         },
3987     { /*7, 07, WINED3DTSS_BUMPENVMAT00              */      STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      },
3988     { /*7, 08, WINED3DTSS_BUMPENVMAT01              */      STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      },
3989     { /*7, 09, WINED3DTSS_BUMPENVMAT10              */      STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      },
3990     { /*7, 10, WINED3DTSS_BUMPENVMAT11              */      STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00),     tex_bumpenvmat      },
3991     { /*7, 11, WINED3DTSS_TEXCOORDINDEX             */      STATE_TEXTURESTAGE(7, WINED3DTSS_TEXCOORDINDEX),    tex_coordindex      },
3992     { /*7, 12, WINED3DTSS_ADDRESS                   */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3993     { /*7, 13, WINED3DTSS_ADDRESSU                  */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3994     { /*7, 14, WINED3DTSS_ADDRESSV                  */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3995     { /*7, 15, WINED3DTSS_BORDERCOLOR               */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3996     { /*7, 16, WINED3DTSS_MAGFILTER                 */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3997     { /*7, 17, WINED3DTSS_MINFILTER                 */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3998     { /*7, 18, WINED3DTSS_MIPFILTER                 */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
3999     { /*7, 19, WINED3DTSS_MIPMAPLODBIAS             */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
4000     { /*7, 20, WINED3DTSS_MAXMIPLEVEL               */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
4001     { /*7, 21, WINED3DTSS_MAXANISOTROPY             */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
4002     { /*7, 22, WINED3DTSS_BUMPENVLSCALE             */      STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE),    tex_bumpenvlscale   },
4003     { /*7, 23, WINED3DTSS_BUMPENVLOFFSET            */      STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLOFFSET),   tex_bumpenvloffset  },
4004     { /*7, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS     */      STATE_TRANSFORM(WINED3DTS_TEXTURE7),                transform_texture   },
4005     { /*7, 25, WINED3DTSS_ADDRESSW                  */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
4006     { /*7, 26, WINED3DTSS_COLORARG0                 */      STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP),          tex_colorop         },
4007     { /*7, 27, WINED3DTSS_ALPHAARG0                 */      STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP),          tex_alphaop         },
4008     { /*7, 28, WINED3DTSS_RESULTARG                 */      STATE_TEXTURESTAGE(7, WINED3DTSS_RESULTARG),        tex_resultarg       },
4009     { /*7, 29, undefined                            */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
4010     { /*7, 30, undefined                            */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
4011     { /*7, 31, undefined                            */      0 /* -> sampler state in ddraw / d3d8 */,           state_undefined     },
4012     { /*7, 32, WINED3DTSS_CONSTANT                  */      0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl          },
4013     /* Sampler states */
4014     { /* 0, Sampler 0                               */      STATE_SAMPLER(0),                                   sampler             },
4015     { /* 1, Sampler 1                               */      STATE_SAMPLER(1),                                   sampler             },
4016     { /* 2, Sampler 2                               */      STATE_SAMPLER(2),                                   sampler             },
4017     { /* 3, Sampler 3                               */      STATE_SAMPLER(3),                                   sampler             },
4018     { /* 4, Sampler 3                               */      STATE_SAMPLER(4),                                   sampler             },
4019     { /* 5, Sampler 5                               */      STATE_SAMPLER(5),                                   sampler             },
4020     { /* 6, Sampler 6                               */      STATE_SAMPLER(6),                                   sampler             },
4021     { /* 7, Sampler 7                               */      STATE_SAMPLER(7),                                   sampler             },
4022     { /* 8, Sampler 8                               */      STATE_SAMPLER(8),                                   sampler             },
4023     { /* 9, Sampler 9                               */      STATE_SAMPLER(9),                                   sampler             },
4024     { /*10, Sampler 10                              */      STATE_SAMPLER(10),                                  sampler             },
4025     { /*11, Sampler 11                              */      STATE_SAMPLER(11),                                  sampler             },
4026     { /*12, Sampler 12                              */      STATE_SAMPLER(12),                                  sampler             },
4027     { /*13, Sampler 13                              */      STATE_SAMPLER(13),                                  sampler             },
4028     { /*14, Sampler 14                              */      STATE_SAMPLER(14),                                  sampler             },
4029     { /*15, Sampler 15                              */      STATE_SAMPLER(15),                                  sampler             },
4030     { /*16, Vertex sampler 0                        */      STATE_SAMPLER(16),                                  sampler             },
4031     { /*17, Vertex sampler 1                        */      STATE_SAMPLER(17),                                  sampler             },
4032     { /*18, Vertex sampler 2                        */      STATE_SAMPLER(18),                                  sampler             },
4033     { /*19, Vertex sampler 3                        */      STATE_SAMPLER(19),                                  sampler             },
4034     /* Pixel shader */
4035     { /*  , Pixel Shader                            */      STATE_PIXELSHADER,                                  pixelshader         },
4036       /* Transform states follow                    */
4037     { /*  1, undefined                              */      0,                                                  state_undefined     },
4038     { /*  2, WINED3DTS_VIEW                         */      STATE_TRANSFORM(WINED3DTS_VIEW),                    transform_view      },
4039     { /*  3, WINED3DTS_PROJECTION                   */      STATE_TRANSFORM(WINED3DTS_PROJECTION),              transform_projection},
4040     { /*  4, undefined                              */      0,                                                  state_undefined     },
4041     { /*  5, undefined                              */      0,                                                  state_undefined     },
4042     { /*  6, undefined                              */      0,                                                  state_undefined     },
4043     { /*  7, undefined                              */      0,                                                  state_undefined     },
4044     { /*  8, undefined                              */      0,                                                  state_undefined     },
4045     { /*  9, undefined                              */      0,                                                  state_undefined     },
4046     { /* 10, undefined                              */      0,                                                  state_undefined     },
4047     { /* 11, undefined                              */      0,                                                  state_undefined     },
4048     { /* 12, undefined                              */      0,                                                  state_undefined     },
4049     { /* 13, undefined                              */      0,                                                  state_undefined     },
4050     { /* 14, undefined                              */      0,                                                  state_undefined     },
4051     { /* 15, undefined                              */      0,                                                  state_undefined     },
4052     { /* 16, WINED3DTS_TEXTURE0                     */      STATE_TRANSFORM(WINED3DTS_TEXTURE0),                transform_texture   },
4053     { /* 17, WINED3DTS_TEXTURE1                     */      STATE_TRANSFORM(WINED3DTS_TEXTURE1),                transform_texture   },
4054     { /* 18, WINED3DTS_TEXTURE2                     */      STATE_TRANSFORM(WINED3DTS_TEXTURE2),                transform_texture   },
4055     { /* 19, WINED3DTS_TEXTURE3                     */      STATE_TRANSFORM(WINED3DTS_TEXTURE3),                transform_texture   },
4056     { /* 20, WINED3DTS_TEXTURE4                     */      STATE_TRANSFORM(WINED3DTS_TEXTURE4),                transform_texture   },
4057     { /* 21, WINED3DTS_TEXTURE5                     */      STATE_TRANSFORM(WINED3DTS_TEXTURE5),                transform_texture   },
4058     { /* 22, WINED3DTS_TEXTURE6                     */      STATE_TRANSFORM(WINED3DTS_TEXTURE6),                transform_texture   },
4059     { /* 23, WINED3DTS_TEXTURE7                     */      STATE_TRANSFORM(WINED3DTS_TEXTURE7),                transform_texture   },
4060       /* A huge gap between TEXTURE7 and WORLDMATRIX(0) :-( But entries are needed to catch then if a broken app sets them */
4061     { /* 24, undefined                              */      0,                                                  state_undefined     },
4062     { /* 25, undefined                              */      0,                                                  state_undefined     },
4063     { /* 26, undefined                              */      0,                                                  state_undefined     },
4064     { /* 27, undefined                              */      0,                                                  state_undefined     },
4065     { /* 28, undefined                              */      0,                                                  state_undefined     },
4066     { /* 29, undefined                              */      0,                                                  state_undefined     },
4067     { /* 30, undefined                              */      0,                                                  state_undefined     },
4068     { /* 31, undefined                              */      0,                                                  state_undefined     },
4069     { /* 32, undefined                              */      0,                                                  state_undefined     },
4070     { /* 33, undefined                              */      0,                                                  state_undefined     },
4071     { /* 34, undefined                              */      0,                                                  state_undefined     },
4072     { /* 35, undefined                              */      0,                                                  state_undefined     },
4073     { /* 36, undefined                              */      0,                                                  state_undefined     },
4074     { /* 37, undefined                              */      0,                                                  state_undefined     },
4075     { /* 38, undefined                              */      0,                                                  state_undefined     },
4076     { /* 39, undefined                              */      0,                                                  state_undefined     },
4077     { /* 40, undefined                              */      0,                                                  state_undefined     },
4078     { /* 41, undefined                              */      0,                                                  state_undefined     },
4079     { /* 42, undefined                              */      0,                                                  state_undefined     },
4080     { /* 43, undefined                              */      0,                                                  state_undefined     },
4081     { /* 44, undefined                              */      0,                                                  state_undefined     },
4082     { /* 45, undefined                              */      0,                                                  state_undefined     },
4083     { /* 46, undefined                              */      0,                                                  state_undefined     },
4084     { /* 47, undefined                              */      0,                                                  state_undefined     },
4085     { /* 48, undefined                              */      0,                                                  state_undefined     },
4086     { /* 49, undefined                              */      0,                                                  state_undefined     },
4087     { /* 50, undefined                              */      0,                                                  state_undefined     },
4088     { /* 51, undefined                              */      0,                                                  state_undefined     },
4089     { /* 52, undefined                              */      0,                                                  state_undefined     },
4090     { /* 53, undefined                              */      0,                                                  state_undefined     },
4091     { /* 54, undefined                              */      0,                                                  state_undefined     },
4092     { /* 55, undefined                              */      0,                                                  state_undefined     },
4093     { /* 56, undefined                              */      0,                                                  state_undefined     },
4094     { /* 57, undefined                              */      0,                                                  state_undefined     },
4095     { /* 58, undefined                              */      0,                                                  state_undefined     },
4096     { /* 59, undefined                              */      0,                                                  state_undefined     },
4097     { /* 60, undefined                              */      0,                                                  state_undefined     },
4098     { /* 61, undefined                              */      0,                                                  state_undefined     },
4099     { /* 62, undefined                              */      0,                                                  state_undefined     },
4100     { /* 63, undefined                              */      0,                                                  state_undefined     },
4101     { /* 64, undefined                              */      0,                                                  state_undefined     },
4102     { /* 65, undefined                              */      0,                                                  state_undefined     },
4103     { /* 66, undefined                              */      0,                                                  state_undefined     },
4104     { /* 67, undefined                              */      0,                                                  state_undefined     },
4105     { /* 68, undefined                              */      0,                                                  state_undefined     },
4106     { /* 69, undefined                              */      0,                                                  state_undefined     },
4107     { /* 70, undefined                              */      0,                                                  state_undefined     },
4108     { /* 71, undefined                              */      0,                                                  state_undefined     },
4109     { /* 72, undefined                              */      0,                                                  state_undefined     },
4110     { /* 73, undefined                              */      0,                                                  state_undefined     },
4111     { /* 74, undefined                              */      0,                                                  state_undefined     },
4112     { /* 75, undefined                              */      0,                                                  state_undefined     },
4113     { /* 76, undefined                              */      0,                                                  state_undefined     },
4114     { /* 77, undefined                              */      0,                                                  state_undefined     },
4115     { /* 78, undefined                              */      0,                                                  state_undefined     },
4116     { /* 79, undefined                              */      0,                                                  state_undefined     },
4117     { /* 80, undefined                              */      0,                                                  state_undefined     },
4118     { /* 81, undefined                              */      0,                                                  state_undefined     },
4119     { /* 82, undefined                              */      0,                                                  state_undefined     },
4120     { /* 83, undefined                              */      0,                                                  state_undefined     },
4121     { /* 84, undefined                              */      0,                                                  state_undefined     },
4122     { /* 85, undefined                              */      0,                                                  state_undefined     },
4123     { /* 86, undefined                              */      0,                                                  state_undefined     },
4124     { /* 87, undefined                              */      0,                                                  state_undefined     },
4125     { /* 88, undefined                              */      0,                                                  state_undefined     },
4126     { /* 89, undefined                              */      0,                                                  state_undefined     },
4127     { /* 90, undefined                              */      0,                                                  state_undefined     },
4128     { /* 91, undefined                              */      0,                                                  state_undefined     },
4129     { /* 92, undefined                              */      0,                                                  state_undefined     },
4130     { /* 93, undefined                              */      0,                                                  state_undefined     },
4131     { /* 94, undefined                              */      0,                                                  state_undefined     },
4132     { /* 95, undefined                              */      0,                                                  state_undefined     },
4133     { /* 96, undefined                              */      0,                                                  state_undefined     },
4134     { /* 97, undefined                              */      0,                                                  state_undefined     },
4135     { /* 98, undefined                              */      0,                                                  state_undefined     },
4136     { /* 99, undefined                              */      0,                                                  state_undefined     },
4137     { /*100, undefined                              */      0,                                                  state_undefined     },
4138     { /*101, undefined                              */      0,                                                  state_undefined     },
4139     { /*102, undefined                              */      0,                                                  state_undefined     },
4140     { /*103, undefined                              */      0,                                                  state_undefined     },
4141     { /*104, undefined                              */      0,                                                  state_undefined     },
4142     { /*105, undefined                              */      0,                                                  state_undefined     },
4143     { /*106, undefined                              */      0,                                                  state_undefined     },
4144     { /*107, undefined                              */      0,                                                  state_undefined     },
4145     { /*108, undefined                              */      0,                                                  state_undefined     },
4146     { /*109, undefined                              */      0,                                                  state_undefined     },
4147     { /*110, undefined                              */      0,                                                  state_undefined     },
4148     { /*111, undefined                              */      0,                                                  state_undefined     },
4149     { /*112, undefined                              */      0,                                                  state_undefined     },
4150     { /*113, undefined                              */      0,                                                  state_undefined     },
4151     { /*114, undefined                              */      0,                                                  state_undefined     },
4152     { /*115, undefined                              */      0,                                                  state_undefined     },
4153     { /*116, undefined                              */      0,                                                  state_undefined     },
4154     { /*117, undefined                              */      0,                                                  state_undefined     },
4155     { /*118, undefined                              */      0,                                                  state_undefined     },
4156     { /*119, undefined                              */      0,                                                  state_undefined     },
4157     { /*120, undefined                              */      0,                                                  state_undefined     },
4158     { /*121, undefined                              */      0,                                                  state_undefined     },
4159     { /*122, undefined                              */      0,                                                  state_undefined     },
4160     { /*123, undefined                              */      0,                                                  state_undefined     },
4161     { /*124, undefined                              */      0,                                                  state_undefined     },
4162     { /*125, undefined                              */      0,                                                  state_undefined     },
4163     { /*126, undefined                              */      0,                                                  state_undefined     },
4164     { /*127, undefined                              */      0,                                                  state_undefined     },
4165     { /*128, undefined                              */      0,                                                  state_undefined     },
4166     { /*129, undefined                              */      0,                                                  state_undefined     },
4167     { /*130, undefined                              */      0,                                                  state_undefined     },
4168     { /*131, undefined                              */      0,                                                  state_undefined     },
4169     { /*132, undefined                              */      0,                                                  state_undefined     },
4170     { /*133, undefined                              */      0,                                                  state_undefined     },
4171     { /*134, undefined                              */      0,                                                  state_undefined     },
4172     { /*135, undefined                              */      0,                                                  state_undefined     },
4173     { /*136, undefined                              */      0,                                                  state_undefined     },
4174     { /*137, undefined                              */      0,                                                  state_undefined     },
4175     { /*138, undefined                              */      0,                                                  state_undefined     },
4176     { /*139, undefined                              */      0,                                                  state_undefined     },
4177     { /*140, undefined                              */      0,                                                  state_undefined     },
4178     { /*141, undefined                              */      0,                                                  state_undefined     },
4179     { /*142, undefined                              */      0,                                                  state_undefined     },
4180     { /*143, undefined                              */      0,                                                  state_undefined     },
4181     { /*144, undefined                              */      0,                                                  state_undefined     },
4182     { /*145, undefined                              */      0,                                                  state_undefined     },
4183     { /*146, undefined                              */      0,                                                  state_undefined     },
4184     { /*147, undefined                              */      0,                                                  state_undefined     },
4185     { /*148, undefined                              */      0,                                                  state_undefined     },
4186     { /*149, undefined                              */      0,                                                  state_undefined     },
4187     { /*150, undefined                              */      0,                                                  state_undefined     },
4188     { /*151, undefined                              */      0,                                                  state_undefined     },
4189     { /*152, undefined                              */      0,                                                  state_undefined     },
4190     { /*153, undefined                              */      0,                                                  state_undefined     },
4191     { /*154, undefined                              */      0,                                                  state_undefined     },
4192     { /*155, undefined                              */      0,                                                  state_undefined     },
4193     { /*156, undefined                              */      0,                                                  state_undefined     },
4194     { /*157, undefined                              */      0,                                                  state_undefined     },
4195     { /*158, undefined                              */      0,                                                  state_undefined     },
4196     { /*159, undefined                              */      0,                                                  state_undefined     },
4197     { /*160, undefined                              */      0,                                                  state_undefined     },
4198     { /*161, undefined                              */      0,                                                  state_undefined     },
4199     { /*162, undefined                              */      0,                                                  state_undefined     },
4200     { /*163, undefined                              */      0,                                                  state_undefined     },
4201     { /*164, undefined                              */      0,                                                  state_undefined     },
4202     { /*165, undefined                              */      0,                                                  state_undefined     },
4203     { /*166, undefined                              */      0,                                                  state_undefined     },
4204     { /*167, undefined                              */      0,                                                  state_undefined     },
4205     { /*168, undefined                              */      0,                                                  state_undefined     },
4206     { /*169, undefined                              */      0,                                                  state_undefined     },
4207     { /*170, undefined                              */      0,                                                  state_undefined     },
4208     { /*171, undefined                              */      0,                                                  state_undefined     },
4209     { /*172, undefined                              */      0,                                                  state_undefined     },
4210     { /*173, undefined                              */      0,                                                  state_undefined     },
4211     { /*174, undefined                              */      0,                                                  state_undefined     },
4212     { /*175, undefined                              */      0,                                                  state_undefined     },
4213     { /*176, undefined                              */      0,                                                  state_undefined     },
4214     { /*177, undefined                              */      0,                                                  state_undefined     },
4215     { /*178, undefined                              */      0,                                                  state_undefined     },
4216     { /*179, undefined                              */      0,                                                  state_undefined     },
4217     { /*180, undefined                              */      0,                                                  state_undefined     },
4218     { /*181, undefined                              */      0,                                                  state_undefined     },
4219     { /*182, undefined                              */      0,                                                  state_undefined     },
4220     { /*183, undefined                              */      0,                                                  state_undefined     },
4221     { /*184, undefined                              */      0,                                                  state_undefined     },
4222     { /*185, undefined                              */      0,                                                  state_undefined     },
4223     { /*186, undefined                              */      0,                                                  state_undefined     },
4224     { /*187, undefined                              */      0,                                                  state_undefined     },
4225     { /*188, undefined                              */      0,                                                  state_undefined     },
4226     { /*189, undefined                              */      0,                                                  state_undefined     },
4227     { /*190, undefined                              */      0,                                                  state_undefined     },
4228     { /*191, undefined                              */      0,                                                  state_undefined     },
4229     { /*192, undefined                              */      0,                                                  state_undefined     },
4230     { /*193, undefined                              */      0,                                                  state_undefined     },
4231     { /*194, undefined                              */      0,                                                  state_undefined     },
4232     { /*195, undefined                              */      0,                                                  state_undefined     },
4233     { /*196, undefined                              */      0,                                                  state_undefined     },
4234     { /*197, undefined                              */      0,                                                  state_undefined     },
4235     { /*198, undefined                              */      0,                                                  state_undefined     },
4236     { /*199, undefined                              */      0,                                                  state_undefined     },
4237     { /*200, undefined                              */      0,                                                  state_undefined     },
4238     { /*201, undefined                              */      0,                                                  state_undefined     },
4239     { /*202, undefined                              */      0,                                                  state_undefined     },
4240     { /*203, undefined                              */      0,                                                  state_undefined     },
4241     { /*204, undefined                              */      0,                                                  state_undefined     },
4242     { /*205, undefined                              */      0,                                                  state_undefined     },
4243     { /*206, undefined                              */      0,                                                  state_undefined     },
4244     { /*207, undefined                              */      0,                                                  state_undefined     },
4245     { /*208, undefined                              */      0,                                                  state_undefined     },
4246     { /*209, undefined                              */      0,                                                  state_undefined     },
4247     { /*210, undefined                              */      0,                                                  state_undefined     },
4248     { /*211, undefined                              */      0,                                                  state_undefined     },
4249     { /*212, undefined                              */      0,                                                  state_undefined     },
4250     { /*213, undefined                              */      0,                                                  state_undefined     },
4251     { /*214, undefined                              */      0,                                                  state_undefined     },
4252     { /*215, undefined                              */      0,                                                  state_undefined     },
4253     { /*216, undefined                              */      0,                                                  state_undefined     },
4254     { /*217, undefined                              */      0,                                                  state_undefined     },
4255     { /*218, undefined                              */      0,                                                  state_undefined     },
4256     { /*219, undefined                              */      0,                                                  state_undefined     },
4257     { /*220, undefined                              */      0,                                                  state_undefined     },
4258     { /*221, undefined                              */      0,                                                  state_undefined     },
4259     { /*222, undefined                              */      0,                                                  state_undefined     },
4260     { /*223, undefined                              */      0,                                                  state_undefined     },
4261     { /*224, undefined                              */      0,                                                  state_undefined     },
4262     { /*225, undefined                              */      0,                                                  state_undefined     },
4263     { /*226, undefined                              */      0,                                                  state_undefined     },
4264     { /*227, undefined                              */      0,                                                  state_undefined     },
4265     { /*228, undefined                              */      0,                                                  state_undefined     },
4266     { /*229, undefined                              */      0,                                                  state_undefined     },
4267     { /*230, undefined                              */      0,                                                  state_undefined     },
4268     { /*231, undefined                              */      0,                                                  state_undefined     },
4269     { /*232, undefined                              */      0,                                                  state_undefined     },
4270     { /*233, undefined                              */      0,                                                  state_undefined     },
4271     { /*234, undefined                              */      0,                                                  state_undefined     },
4272     { /*235, undefined                              */      0,                                                  state_undefined     },
4273     { /*236, undefined                              */      0,                                                  state_undefined     },
4274     { /*237, undefined                              */      0,                                                  state_undefined     },
4275     { /*238, undefined                              */      0,                                                  state_undefined     },
4276     { /*239, undefined                              */      0,                                                  state_undefined     },
4277     { /*240, undefined                              */      0,                                                  state_undefined     },
4278     { /*241, undefined                              */      0,                                                  state_undefined     },
4279     { /*242, undefined                              */      0,                                                  state_undefined     },
4280     { /*243, undefined                              */      0,                                                  state_undefined     },
4281     { /*244, undefined                              */      0,                                                  state_undefined     },
4282     { /*245, undefined                              */      0,                                                  state_undefined     },
4283     { /*246, undefined                              */      0,                                                  state_undefined     },
4284     { /*247, undefined                              */      0,                                                  state_undefined     },
4285     { /*248, undefined                              */      0,                                                  state_undefined     },
4286     { /*249, undefined                              */      0,                                                  state_undefined     },
4287     { /*250, undefined                              */      0,                                                  state_undefined     },
4288     { /*251, undefined                              */      0,                                                  state_undefined     },
4289     { /*252, undefined                              */      0,                                                  state_undefined     },
4290     { /*253, undefined                              */      0,                                                  state_undefined     },
4291     { /*254, undefined                              */      0,                                                  state_undefined     },
4292     { /*255, undefined                              */      0,                                                  state_undefined     },
4293       /* End huge gap */
4294     { /*256, WINED3DTS_WORLDMATRIX(0)               */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)),          transform_world     },
4295     { /*257, WINED3DTS_WORLDMATRIX(1)               */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(1)),          transform_worldex   },
4296     { /*258, WINED3DTS_WORLDMATRIX(2)               */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(2)),          transform_worldex   },
4297     { /*259, WINED3DTS_WORLDMATRIX(3)               */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(3)),          transform_worldex   },
4298     { /*260, WINED3DTS_WORLDMATRIX(4)               */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(4)),          transform_worldex   },
4299     { /*261, WINED3DTS_WORLDMATRIX(5)               */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(5)),          transform_worldex   },
4300     { /*262, WINED3DTS_WORLDMATRIX(6)               */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(6)),          transform_worldex   },
4301     { /*263, WINED3DTS_WORLDMATRIX(7)               */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(7)),          transform_worldex   },
4302     { /*264, WINED3DTS_WORLDMATRIX(8)               */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(8)),          transform_worldex   },
4303     { /*265, WINED3DTS_WORLDMATRIX(9)               */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(9)),          transform_worldex   },
4304     { /*266, WINED3DTS_WORLDMATRIX(10)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(10)),         transform_worldex   },
4305     { /*267, WINED3DTS_WORLDMATRIX(11)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(11)),         transform_worldex   },
4306     { /*268, WINED3DTS_WORLDMATRIX(12)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(12)),         transform_worldex   },
4307     { /*269, WINED3DTS_WORLDMATRIX(13)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(13)),         transform_worldex   },
4308     { /*270, WINED3DTS_WORLDMATRIX(14)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(14)),         transform_worldex   },
4309     { /*271, WINED3DTS_WORLDMATRIX(15)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(15)),         transform_worldex   },
4310     { /*272, WINED3DTS_WORLDMATRIX(16)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(16)),         transform_worldex   },
4311     { /*273, WINED3DTS_WORLDMATRIX(17)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(17)),         transform_worldex   },
4312     { /*274, WINED3DTS_WORLDMATRIX(18)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(18)),         transform_worldex   },
4313     { /*275, WINED3DTS_WORLDMATRIX(19)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(19)),         transform_worldex   },
4314     { /*276, WINED3DTS_WORLDMATRIX(20)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(20)),         transform_worldex   },
4315     { /*277, WINED3DTS_WORLDMATRIX(21)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(21)),         transform_worldex   },
4316     { /*278, WINED3DTS_WORLDMATRIX(22)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(22)),         transform_worldex   },
4317     { /*279, WINED3DTS_WORLDMATRIX(23)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(23)),         transform_worldex   },
4318     { /*280, WINED3DTS_WORLDMATRIX(24)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(24)),         transform_worldex   },
4319     { /*281, WINED3DTS_WORLDMATRIX(25)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(25)),         transform_worldex   },
4320     { /*282, WINED3DTS_WORLDMATRIX(26)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(26)),         transform_worldex   },
4321     { /*283, WINED3DTS_WORLDMATRIX(27)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(27)),         transform_worldex   },
4322     { /*284, WINED3DTS_WORLDMATRIX(28)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(28)),         transform_worldex   },
4323     { /*285, WINED3DTS_WORLDMATRIX(29)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(29)),         transform_worldex   },
4324     { /*286, WINED3DTS_WORLDMATRIX(30)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(30)),         transform_worldex   },
4325     { /*287, WINED3DTS_WORLDMATRIX(31)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(31)),         transform_worldex   },
4326     { /*288, WINED3DTS_WORLDMATRIX(32)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(32)),         transform_worldex   },
4327     { /*289, WINED3DTS_WORLDMATRIX(33)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(33)),         transform_worldex   },
4328     { /*290, WINED3DTS_WORLDMATRIX(34)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(34)),         transform_worldex   },
4329     { /*291, WINED3DTS_WORLDMATRIX(35)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(35)),         transform_worldex   },
4330     { /*292, WINED3DTS_WORLDMATRIX(36)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(36)),         transform_worldex   },
4331     { /*293, WINED3DTS_WORLDMATRIX(37)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(37)),         transform_worldex   },
4332     { /*294, WINED3DTS_WORLDMATRIX(38)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(38)),         transform_worldex   },
4333     { /*295, WINED3DTS_WORLDMATRIX(39)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(39)),         transform_worldex   },
4334     { /*296, WINED3DTS_WORLDMATRIX(40)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(40)),         transform_worldex   },
4335     { /*297, WINED3DTS_WORLDMATRIX(41)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(41)),         transform_worldex   },
4336     { /*298, WINED3DTS_WORLDMATRIX(42)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(42)),         transform_worldex   },
4337     { /*299, WINED3DTS_WORLDMATRIX(43)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(43)),         transform_worldex   },
4338     { /*300, WINED3DTS_WORLDMATRIX(44)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(44)),         transform_worldex   },
4339     { /*301, WINED3DTS_WORLDMATRIX(45)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(45)),         transform_worldex   },
4340     { /*302, WINED3DTS_WORLDMATRIX(46)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(46)),         transform_worldex   },
4341     { /*303, WINED3DTS_WORLDMATRIX(47)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(47)),         transform_worldex   },
4342     { /*304, WINED3DTS_WORLDMATRIX(48)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(48)),         transform_worldex   },
4343     { /*305, WINED3DTS_WORLDMATRIX(49)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(49)),         transform_worldex   },
4344     { /*306, WINED3DTS_WORLDMATRIX(50)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(50)),         transform_worldex   },
4345     { /*307, WINED3DTS_WORLDMATRIX(51)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(51)),         transform_worldex   },
4346     { /*308, WINED3DTS_WORLDMATRIX(52)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(52)),         transform_worldex   },
4347     { /*309, WINED3DTS_WORLDMATRIX(53)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(53)),         transform_worldex   },
4348     { /*310, WINED3DTS_WORLDMATRIX(54)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(54)),         transform_worldex   },
4349     { /*311, WINED3DTS_WORLDMATRIX(55)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(55)),         transform_worldex   },
4350     { /*312, WINED3DTS_WORLDMATRIX(56)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(56)),         transform_worldex   },
4351     { /*313, WINED3DTS_WORLDMATRIX(57)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(57)),         transform_worldex   },
4352     { /*314, WINED3DTS_WORLDMATRIX(58)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(58)),         transform_worldex   },
4353     { /*315, WINED3DTS_WORLDMATRIX(59)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(59)),         transform_worldex   },
4354     { /*316, WINED3DTS_WORLDMATRIX(60)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(60)),         transform_worldex   },
4355     { /*317, WINED3DTS_WORLDMATRIX(61)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(61)),         transform_worldex   },
4356     { /*318, WINED3DTS_WORLDMATRIX(62)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(62)),         transform_worldex   },
4357     { /*319, WINED3DTS_WORLDMATRIX(63)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(63)),         transform_worldex   },
4358     { /*320, WINED3DTS_WORLDMATRIX(64)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(64)),         transform_worldex   },
4359     { /*321, WINED3DTS_WORLDMATRIX(65)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(65)),         transform_worldex   },
4360     { /*322, WINED3DTS_WORLDMATRIX(66)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(66)),         transform_worldex   },
4361     { /*323, WINED3DTS_WORLDMATRIX(67)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(67)),         transform_worldex   },
4362     { /*324, WINED3DTS_WORLDMATRIX(68)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(68)),         transform_worldex   },
4363     { /*325, WINED3DTS_WORLDMATRIX(68)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(69)),         transform_worldex   },
4364     { /*326, WINED3DTS_WORLDMATRIX(70)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(70)),         transform_worldex   },
4365     { /*327, WINED3DTS_WORLDMATRIX(71)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(71)),         transform_worldex   },
4366     { /*328, WINED3DTS_WORLDMATRIX(72)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(72)),         transform_worldex   },
4367     { /*329, WINED3DTS_WORLDMATRIX(73)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(73)),         transform_worldex   },
4368     { /*330, WINED3DTS_WORLDMATRIX(74)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(74)),         transform_worldex   },
4369     { /*331, WINED3DTS_WORLDMATRIX(75)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(75)),         transform_worldex   },
4370     { /*332, WINED3DTS_WORLDMATRIX(76)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(76)),         transform_worldex   },
4371     { /*333, WINED3DTS_WORLDMATRIX(77)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(77)),         transform_worldex   },
4372     { /*334, WINED3DTS_WORLDMATRIX(78)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(78)),         transform_worldex   },
4373     { /*335, WINED3DTS_WORLDMATRIX(79)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(79)),         transform_worldex   },
4374     { /*336, WINED3DTS_WORLDMATRIX(80)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(80)),         transform_worldex   },
4375     { /*337, WINED3DTS_WORLDMATRIX(81)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(81)),         transform_worldex   },
4376     { /*338, WINED3DTS_WORLDMATRIX(82)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(82)),         transform_worldex   },
4377     { /*339, WINED3DTS_WORLDMATRIX(83)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(83)),         transform_worldex   },
4378     { /*340, WINED3DTS_WORLDMATRIX(84)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(84)),         transform_worldex   },
4379     { /*341, WINED3DTS_WORLDMATRIX(85)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(85)),         transform_worldex   },
4380     { /*341, WINED3DTS_WORLDMATRIX(86)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(86)),         transform_worldex   },
4381     { /*343, WINED3DTS_WORLDMATRIX(87)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(87)),         transform_worldex   },
4382     { /*344, WINED3DTS_WORLDMATRIX(88)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(88)),         transform_worldex   },
4383     { /*345, WINED3DTS_WORLDMATRIX(89)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(89)),         transform_worldex   },
4384     { /*346, WINED3DTS_WORLDMATRIX(90)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(90)),         transform_worldex   },
4385     { /*347, WINED3DTS_WORLDMATRIX(91)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(91)),         transform_worldex   },
4386     { /*348, WINED3DTS_WORLDMATRIX(92)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(92)),         transform_worldex   },
4387     { /*349, WINED3DTS_WORLDMATRIX(93)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(93)),         transform_worldex   },
4388     { /*350, WINED3DTS_WORLDMATRIX(94)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(94)),         transform_worldex   },
4389     { /*351, WINED3DTS_WORLDMATRIX(95)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(95)),         transform_worldex   },
4390     { /*352, WINED3DTS_WORLDMATRIX(96)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(96)),         transform_worldex   },
4391     { /*353, WINED3DTS_WORLDMATRIX(97)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(97)),         transform_worldex   },
4392     { /*354, WINED3DTS_WORLDMATRIX(98)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(98)),         transform_worldex   },
4393     { /*355, WINED3DTS_WORLDMATRIX(99)              */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(99)),         transform_worldex   },
4394     { /*356, WINED3DTS_WORLDMATRIX(100)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(100)),        transform_worldex   },
4395     { /*357, WINED3DTS_WORLDMATRIX(101)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(101)),        transform_worldex   },
4396     { /*358, WINED3DTS_WORLDMATRIX(102)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(102)),        transform_worldex   },
4397     { /*359, WINED3DTS_WORLDMATRIX(103)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(103)),        transform_worldex   },
4398     { /*360, WINED3DTS_WORLDMATRIX(104)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(104)),        transform_worldex   },
4399     { /*361, WINED3DTS_WORLDMATRIX(105)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(105)),        transform_worldex   },
4400     { /*362, WINED3DTS_WORLDMATRIX(106)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(106)),        transform_worldex   },
4401     { /*363, WINED3DTS_WORLDMATRIX(107)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(107)),        transform_worldex   },
4402     { /*364, WINED3DTS_WORLDMATRIX(108)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(108)),        transform_worldex   },
4403     { /*365, WINED3DTS_WORLDMATRIX(109)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(109)),        transform_worldex   },
4404     { /*366, WINED3DTS_WORLDMATRIX(110)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(110)),        transform_worldex   },
4405     { /*367, WINED3DTS_WORLDMATRIX(111)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(111)),        transform_worldex   },
4406     { /*368, WINED3DTS_WORLDMATRIX(112)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(112)),        transform_worldex   },
4407     { /*369, WINED3DTS_WORLDMATRIX(113)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(113)),        transform_worldex   },
4408     { /*370, WINED3DTS_WORLDMATRIX(114)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(114)),        transform_worldex   },
4409     { /*371, WINED3DTS_WORLDMATRIX(115)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(115)),        transform_worldex   },
4410     { /*372, WINED3DTS_WORLDMATRIX(116)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(116)),        transform_worldex   },
4411     { /*373, WINED3DTS_WORLDMATRIX(117)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(117)),        transform_worldex   },
4412     { /*374, WINED3DTS_WORLDMATRIX(118)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(118)),        transform_worldex   },
4413     { /*375, WINED3DTS_WORLDMATRIX(119)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(119)),        transform_worldex   },
4414     { /*376, WINED3DTS_WORLDMATRIX(120)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(120)),        transform_worldex   },
4415     { /*377, WINED3DTS_WORLDMATRIX(121)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(121)),        transform_worldex   },
4416     { /*378, WINED3DTS_WORLDMATRIX(122)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(122)),        transform_worldex   },
4417     { /*379, WINED3DTS_WORLDMATRIX(123)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(123)),        transform_worldex   },
4418     { /*380, WINED3DTS_WORLDMATRIX(124)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(124)),        transform_worldex   },
4419     { /*381, WINED3DTS_WORLDMATRIX(125)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(125)),        transform_worldex   },
4420     { /*382, WINED3DTS_WORLDMATRIX(126)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(126)),        transform_worldex   },
4421     { /*383, WINED3DTS_WORLDMATRIX(127)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(127)),        transform_worldex   },
4422     { /*384, WINED3DTS_WORLDMATRIX(128)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(128)),        transform_worldex   },
4423     { /*385, WINED3DTS_WORLDMATRIX(129)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(129)),        transform_worldex   },
4424     { /*386, WINED3DTS_WORLDMATRIX(130)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(130)),        transform_worldex   },
4425     { /*387, WINED3DTS_WORLDMATRIX(131)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(131)),        transform_worldex   },
4426     { /*388, WINED3DTS_WORLDMATRIX(132)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(132)),        transform_worldex   },
4427     { /*389, WINED3DTS_WORLDMATRIX(133)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(133)),        transform_worldex   },
4428     { /*390, WINED3DTS_WORLDMATRIX(134)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(134)),        transform_worldex   },
4429     { /*391, WINED3DTS_WORLDMATRIX(135)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(135)),        transform_worldex   },
4430     { /*392, WINED3DTS_WORLDMATRIX(136)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(136)),        transform_worldex   },
4431     { /*393, WINED3DTS_WORLDMATRIX(137)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(137)),        transform_worldex   },
4432     { /*394, WINED3DTS_WORLDMATRIX(138)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(138)),        transform_worldex   },
4433     { /*395, WINED3DTS_WORLDMATRIX(139)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(139)),        transform_worldex   },
4434     { /*396, WINED3DTS_WORLDMATRIX(140)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(140)),        transform_worldex   },
4435     { /*397, WINED3DTS_WORLDMATRIX(141)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(141)),        transform_worldex   },
4436     { /*398, WINED3DTS_WORLDMATRIX(142)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(142)),        transform_worldex   },
4437     { /*399, WINED3DTS_WORLDMATRIX(143)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(143)),        transform_worldex   },
4438     { /*400, WINED3DTS_WORLDMATRIX(144)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(144)),        transform_worldex   },
4439     { /*401, WINED3DTS_WORLDMATRIX(145)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(145)),        transform_worldex   },
4440     { /*402, WINED3DTS_WORLDMATRIX(146)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(146)),        transform_worldex   },
4441     { /*403, WINED3DTS_WORLDMATRIX(147)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(147)),        transform_worldex   },
4442     { /*404, WINED3DTS_WORLDMATRIX(148)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(148)),        transform_worldex   },
4443     { /*405, WINED3DTS_WORLDMATRIX(149)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(149)),        transform_worldex   },
4444     { /*406, WINED3DTS_WORLDMATRIX(150)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(150)),        transform_worldex   },
4445     { /*407, WINED3DTS_WORLDMATRIX(151)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(151)),        transform_worldex   },
4446     { /*408, WINED3DTS_WORLDMATRIX(152)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(152)),        transform_worldex   },
4447     { /*409, WINED3DTS_WORLDMATRIX(153)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(153)),        transform_worldex   },
4448     { /*410, WINED3DTS_WORLDMATRIX(154)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(154)),        transform_worldex   },
4449     { /*411, WINED3DTS_WORLDMATRIX(155)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(155)),        transform_worldex   },
4450     { /*412, WINED3DTS_WORLDMATRIX(156)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(156)),        transform_worldex   },
4451     { /*413, WINED3DTS_WORLDMATRIX(157)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(157)),        transform_worldex   },
4452     { /*414, WINED3DTS_WORLDMATRIX(158)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(158)),        transform_worldex   },
4453     { /*415, WINED3DTS_WORLDMATRIX(159)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(159)),        transform_worldex   },
4454     { /*416, WINED3DTS_WORLDMATRIX(160)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(160)),        transform_worldex   },
4455     { /*417, WINED3DTS_WORLDMATRIX(161)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(161)),        transform_worldex   },
4456     { /*418, WINED3DTS_WORLDMATRIX(162)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(162)),        transform_worldex   },
4457     { /*419, WINED3DTS_WORLDMATRIX(163)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(163)),        transform_worldex   },
4458     { /*420, WINED3DTS_WORLDMATRIX(164)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(164)),        transform_worldex   },
4459     { /*421, WINED3DTS_WORLDMATRIX(165)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(165)),        transform_worldex   },
4460     { /*422, WINED3DTS_WORLDMATRIX(166)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(166)),        transform_worldex   },
4461     { /*423, WINED3DTS_WORLDMATRIX(167)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(167)),        transform_worldex   },
4462     { /*424, WINED3DTS_WORLDMATRIX(168)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(168)),        transform_worldex   },
4463     { /*425, WINED3DTS_WORLDMATRIX(168)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(169)),        transform_worldex   },
4464     { /*426, WINED3DTS_WORLDMATRIX(170)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(170)),        transform_worldex   },
4465     { /*427, WINED3DTS_WORLDMATRIX(171)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(171)),        transform_worldex   },
4466     { /*428, WINED3DTS_WORLDMATRIX(172)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(172)),        transform_worldex   },
4467     { /*429, WINED3DTS_WORLDMATRIX(173)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(173)),        transform_worldex   },
4468     { /*430, WINED3DTS_WORLDMATRIX(174)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(174)),        transform_worldex   },
4469     { /*431, WINED3DTS_WORLDMATRIX(175)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(175)),        transform_worldex   },
4470     { /*432, WINED3DTS_WORLDMATRIX(176)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(176)),        transform_worldex   },
4471     { /*433, WINED3DTS_WORLDMATRIX(177)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(177)),        transform_worldex   },
4472     { /*434, WINED3DTS_WORLDMATRIX(178)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(178)),        transform_worldex   },
4473     { /*435, WINED3DTS_WORLDMATRIX(179)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(179)),        transform_worldex   },
4474     { /*436, WINED3DTS_WORLDMATRIX(180)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(180)),        transform_worldex   },
4475     { /*437, WINED3DTS_WORLDMATRIX(181)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(181)),        transform_worldex   },
4476     { /*438, WINED3DTS_WORLDMATRIX(182)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(182)),        transform_worldex   },
4477     { /*439, WINED3DTS_WORLDMATRIX(183)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(183)),        transform_worldex   },
4478     { /*440, WINED3DTS_WORLDMATRIX(184)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(184)),        transform_worldex   },
4479     { /*441, WINED3DTS_WORLDMATRIX(185)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(185)),        transform_worldex   },
4480     { /*441, WINED3DTS_WORLDMATRIX(186)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(186)),        transform_worldex   },
4481     { /*443, WINED3DTS_WORLDMATRIX(187)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(187)),        transform_worldex   },
4482     { /*444, WINED3DTS_WORLDMATRIX(188)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(188)),        transform_worldex   },
4483     { /*445, WINED3DTS_WORLDMATRIX(189)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(189)),        transform_worldex   },
4484     { /*446, WINED3DTS_WORLDMATRIX(190)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(190)),        transform_worldex   },
4485     { /*447, WINED3DTS_WORLDMATRIX(191)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(191)),        transform_worldex   },
4486     { /*448, WINED3DTS_WORLDMATRIX(192)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(192)),        transform_worldex   },
4487     { /*449, WINED3DTS_WORLDMATRIX(193)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(193)),        transform_worldex   },
4488     { /*450, WINED3DTS_WORLDMATRIX(194)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(194)),        transform_worldex   },
4489     { /*451, WINED3DTS_WORLDMATRIX(195)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(195)),        transform_worldex   },
4490     { /*452, WINED3DTS_WORLDMATRIX(196)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(196)),        transform_worldex   },
4491     { /*453, WINED3DTS_WORLDMATRIX(197)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(197)),        transform_worldex   },
4492     { /*454, WINED3DTS_WORLDMATRIX(198)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(198)),        transform_worldex   },
4493     { /*455, WINED3DTS_WORLDMATRIX(199)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(199)),        transform_worldex   },
4494     { /*356, WINED3DTS_WORLDMATRIX(200)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(200)),        transform_worldex   },
4495     { /*457, WINED3DTS_WORLDMATRIX(201)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(201)),        transform_worldex   },
4496     { /*458, WINED3DTS_WORLDMATRIX(202)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(202)),        transform_worldex   },
4497     { /*459, WINED3DTS_WORLDMATRIX(203)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(203)),        transform_worldex   },
4498     { /*460, WINED3DTS_WORLDMATRIX(204)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(204)),        transform_worldex   },
4499     { /*461, WINED3DTS_WORLDMATRIX(205)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(205)),        transform_worldex   },
4500     { /*462, WINED3DTS_WORLDMATRIX(206)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(206)),        transform_worldex   },
4501     { /*463, WINED3DTS_WORLDMATRIX(207)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(207)),        transform_worldex   },
4502     { /*464, WINED3DTS_WORLDMATRIX(208)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(208)),        transform_worldex   },
4503     { /*465, WINED3DTS_WORLDMATRIX(209)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(209)),        transform_worldex   },
4504     { /*466, WINED3DTS_WORLDMATRIX(210)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(210)),        transform_worldex   },
4505     { /*467, WINED3DTS_WORLDMATRIX(211)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(211)),        transform_worldex   },
4506     { /*468, WINED3DTS_WORLDMATRIX(212)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(212)),        transform_worldex   },
4507     { /*469, WINED3DTS_WORLDMATRIX(213)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(213)),        transform_worldex   },
4508     { /*470, WINED3DTS_WORLDMATRIX(214)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(214)),        transform_worldex   },
4509     { /*471, WINED3DTS_WORLDMATRIX(215)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(215)),        transform_worldex   },
4510     { /*472, WINED3DTS_WORLDMATRIX(216)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(216)),        transform_worldex   },
4511     { /*473, WINED3DTS_WORLDMATRIX(217)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(217)),        transform_worldex   },
4512     { /*474, WINED3DTS_WORLDMATRIX(218)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(218)),        transform_worldex   },
4513     { /*475, WINED3DTS_WORLDMATRIX(219)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(219)),        transform_worldex   },
4514     { /*476, WINED3DTS_WORLDMATRIX(220)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(220)),        transform_worldex   },
4515     { /*477, WINED3DTS_WORLDMATRIX(221)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(221)),        transform_worldex   },
4516     { /*478, WINED3DTS_WORLDMATRIX(222)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(222)),        transform_worldex   },
4517     { /*479, WINED3DTS_WORLDMATRIX(223)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(223)),        transform_worldex   },
4518     { /*480, WINED3DTS_WORLDMATRIX(224)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(224)),        transform_worldex   },
4519     { /*481, WINED3DTS_WORLDMATRIX(225)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(225)),        transform_worldex   },
4520     { /*482, WINED3DTS_WORLDMATRIX(226)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(226)),        transform_worldex   },
4521     { /*483, WINED3DTS_WORLDMATRIX(227)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(227)),        transform_worldex   },
4522     { /*484, WINED3DTS_WORLDMATRIX(228)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(228)),        transform_worldex   },
4523     { /*485, WINED3DTS_WORLDMATRIX(229)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(229)),        transform_worldex   },
4524     { /*486, WINED3DTS_WORLDMATRIX(230)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(230)),        transform_worldex   },
4525     { /*487, WINED3DTS_WORLDMATRIX(231)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(231)),        transform_worldex   },
4526     { /*488, WINED3DTS_WORLDMATRIX(232)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(232)),        transform_worldex   },
4527     { /*489, WINED3DTS_WORLDMATRIX(233)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(233)),        transform_worldex   },
4528     { /*490, WINED3DTS_WORLDMATRIX(234)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(234)),        transform_worldex   },
4529     { /*491, WINED3DTS_WORLDMATRIX(235)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(235)),        transform_worldex   },
4530     { /*492, WINED3DTS_WORLDMATRIX(236)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(236)),        transform_worldex   },
4531     { /*493, WINED3DTS_WORLDMATRIX(237)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(237)),        transform_worldex   },
4532     { /*494, WINED3DTS_WORLDMATRIX(238)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(238)),        transform_worldex   },
4533     { /*495, WINED3DTS_WORLDMATRIX(239)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(239)),        transform_worldex   },
4534     { /*496, WINED3DTS_WORLDMATRIX(240)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(240)),        transform_worldex   },
4535     { /*497, WINED3DTS_WORLDMATRIX(241)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(241)),        transform_worldex   },
4536     { /*498, WINED3DTS_WORLDMATRIX(242)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(242)),        transform_worldex   },
4537     { /*499, WINED3DTS_WORLDMATRIX(243)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(243)),        transform_worldex   },
4538     { /*500, WINED3DTS_WORLDMATRIX(244)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(244)),        transform_worldex   },
4539     { /*501, WINED3DTS_WORLDMATRIX(245)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(245)),        transform_worldex   },
4540     { /*502, WINED3DTS_WORLDMATRIX(246)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(246)),        transform_worldex   },
4541     { /*503, WINED3DTS_WORLDMATRIX(247)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(247)),        transform_worldex   },
4542     { /*504, WINED3DTS_WORLDMATRIX(248)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(248)),        transform_worldex   },
4543     { /*505, WINED3DTS_WORLDMATRIX(249)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(249)),        transform_worldex   },
4544     { /*506, WINED3DTS_WORLDMATRIX(250)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(250)),        transform_worldex   },
4545     { /*507, WINED3DTS_WORLDMATRIX(251)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(251)),        transform_worldex   },
4546     { /*508, WINED3DTS_WORLDMATRIX(252)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(252)),        transform_worldex   },
4547     { /*509, WINED3DTS_WORLDMATRIX(253)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(253)),        transform_worldex   },
4548     { /*510, WINED3DTS_WORLDMATRIX(254)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(254)),        transform_worldex   },
4549     { /*511, WINED3DTS_WORLDMATRIX(255)             */      STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(255)),        transform_worldex   },
4550       /* Various Vertex states follow */
4551     { /*   , STATE_STREAMSRC                        */      STATE_VDECL,                                        vertexdeclaration   },
4552     { /*   , STATE_INDEXBUFFER                      */      STATE_INDEXBUFFER,                                  indexbuffer         },
4553     { /*   , STATE_VDECL                            */      STATE_VDECL,                                        vertexdeclaration   },
4554     { /*   , STATE_VSHADER                          */      STATE_VDECL,                                        vertexdeclaration   },
4555     { /*   , STATE_VIEWPORT                         */      STATE_VIEWPORT,                                     viewport            },
4556     { /*   , STATE_VERTEXSHADERCONSTANT             */      STATE_VERTEXSHADERCONSTANT,                         shaderconstant      },
4557     { /*   , STATE_PIXELSHADERCONSTANT              */      STATE_VERTEXSHADERCONSTANT,                         shaderconstant      },
4558       /* Lights */
4559     { /*   , STATE_ACTIVELIGHT(0)                   */      STATE_ACTIVELIGHT(0),                               light               },
4560     { /*   , STATE_ACTIVELIGHT(1)                   */      STATE_ACTIVELIGHT(1),                               light               },
4561     { /*   , STATE_ACTIVELIGHT(2)                   */      STATE_ACTIVELIGHT(2),                               light               },
4562     { /*   , STATE_ACTIVELIGHT(3)                   */      STATE_ACTIVELIGHT(3),                               light               },
4563     { /*   , STATE_ACTIVELIGHT(4)                   */      STATE_ACTIVELIGHT(4),                               light               },
4564     { /*   , STATE_ACTIVELIGHT(5)                   */      STATE_ACTIVELIGHT(5),                               light               },
4565     { /*   , STATE_ACTIVELIGHT(6)                   */      STATE_ACTIVELIGHT(6),                               light               },
4566     { /*   , STATE_ACTIVELIGHT(7)                   */      STATE_ACTIVELIGHT(7),                               light               },
4567
4568     { /* Scissor rect                               */      STATE_SCISSORRECT,                                  scissorrect         },
4569       /* Clip planes */
4570     { /* STATE_CLIPPLANE(0)                         */      STATE_CLIPPLANE(0),                                 clipplane           },
4571     { /* STATE_CLIPPLANE(1)                         */      STATE_CLIPPLANE(1),                                 clipplane           },
4572     { /* STATE_CLIPPLANE(2)                         */      STATE_CLIPPLANE(2),                                 clipplane           },
4573     { /* STATE_CLIPPLANE(3)                         */      STATE_CLIPPLANE(3),                                 clipplane           },
4574     { /* STATE_CLIPPLANE(4)                         */      STATE_CLIPPLANE(4),                                 clipplane           },
4575     { /* STATE_CLIPPLANE(5)                         */      STATE_CLIPPLANE(5),                                 clipplane           },
4576     { /* STATE_CLIPPLANE(6)                         */      STATE_CLIPPLANE(6),                                 clipplane           },
4577     { /* STATE_CLIPPLANE(7)                         */      STATE_CLIPPLANE(7),                                 clipplane           },
4578     { /* STATE_CLIPPLANE(8)                         */      STATE_CLIPPLANE(8),                                 clipplane           },
4579     { /* STATE_CLIPPLANE(9)                         */      STATE_CLIPPLANE(9),                                 clipplane           },
4580     { /* STATE_CLIPPLANE(10)                        */      STATE_CLIPPLANE(10),                                clipplane           },
4581     { /* STATE_CLIPPLANE(11)                        */      STATE_CLIPPLANE(11),                                clipplane           },
4582     { /* STATE_CLIPPLANE(12)                        */      STATE_CLIPPLANE(12),                                clipplane           },
4583     { /* STATE_CLIPPLANE(13)                        */      STATE_CLIPPLANE(13),                                clipplane           },
4584     { /* STATE_CLIPPLANE(14)                        */      STATE_CLIPPLANE(14),                                clipplane           },
4585     { /* STATE_CLIPPLANE(15)                        */      STATE_CLIPPLANE(15),                                clipplane           },
4586     { /* STATE_CLIPPLANE(16)                        */      STATE_CLIPPLANE(16),                                clipplane           },
4587     { /* STATE_CLIPPLANE(17)                        */      STATE_CLIPPLANE(17),                                clipplane           },
4588     { /* STATE_CLIPPLANE(18)                        */      STATE_CLIPPLANE(18),                                clipplane           },
4589     { /* STATE_CLIPPLANE(19)                        */      STATE_CLIPPLANE(19),                                clipplane           },
4590     { /* STATE_CLIPPLANE(20)                        */      STATE_CLIPPLANE(20),                                clipplane           },
4591     { /* STATE_CLIPPLANE(21)                        */      STATE_CLIPPLANE(21),                                clipplane           },
4592     { /* STATE_CLIPPLANE(22)                        */      STATE_CLIPPLANE(22),                                clipplane           },
4593     { /* STATE_CLIPPLANE(23)                        */      STATE_CLIPPLANE(23),                                clipplane           },
4594     { /* STATE_CLIPPLANE(24)                        */      STATE_CLIPPLANE(24),                                clipplane           },
4595     { /* STATE_CLIPPLANE(25)                        */      STATE_CLIPPLANE(25),                                clipplane           },
4596     { /* STATE_CLIPPLANE(26)                        */      STATE_CLIPPLANE(26),                                clipplane           },
4597     { /* STATE_CLIPPLANE(27)                        */      STATE_CLIPPLANE(27),                                clipplane           },
4598     { /* STATE_CLIPPLANE(28)                        */      STATE_CLIPPLANE(28),                                clipplane           },
4599     { /* STATE_CLIPPLANE(29)                        */      STATE_CLIPPLANE(29),                                clipplane           },
4600     { /* STATE_CLIPPLANE(30)                        */      STATE_CLIPPLANE(30),                                clipplane           },
4601     { /* STATE_CLIPPLANE(31)                        */      STATE_CLIPPLANE(31),                                clipplane           },
4602
4603     { /* STATE_MATERIAL                             */      STATE_RENDER(WINED3DRS_SPECULARENABLE),             state_specularenable},
4604 };