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