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