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