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