wined3d: Avoid looking up shaders for shader stages that didn't change.
[wine.git] / dlls / wined3d / state.c
blobb43fda8f2cd09a121b58433d2b2988005dd94481
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 gl_info->gl_ops.gl.p_glDepthFunc(depth_func);
271 checkGLcall("glDepthFunc");
274 void state_ambient(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
276 const struct wined3d_gl_info *gl_info = context->gl_info;
277 float col[4];
279 D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_AMBIENT], col);
280 TRACE("Setting ambient to (%f,%f,%f,%f)\n", col[0], col[1], col[2], col[3]);
281 gl_info->gl_ops.gl.p_glLightModelfv(GL_LIGHT_MODEL_AMBIENT, col);
282 checkGLcall("glLightModel for MODEL_AMBIENT");
285 static void state_blendop_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
287 WARN("Unsupported in local OpenGL implementation: glBlendEquation\n");
290 static GLenum gl_blend_op(enum wined3d_blend_op op)
292 switch (op)
294 case WINED3D_BLEND_OP_ADD:
295 return GL_FUNC_ADD_EXT;
296 case WINED3D_BLEND_OP_SUBTRACT:
297 return GL_FUNC_SUBTRACT_EXT;
298 case WINED3D_BLEND_OP_REVSUBTRACT:
299 return GL_FUNC_REVERSE_SUBTRACT_EXT;
300 case WINED3D_BLEND_OP_MIN:
301 return GL_MIN_EXT;
302 case WINED3D_BLEND_OP_MAX:
303 return GL_MAX_EXT;
304 default:
305 FIXME("Unhandled blend op %#x.\n", op);
306 return GL_NONE;
310 static void state_blendop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
312 const struct wined3d_gl_info *gl_info = context->gl_info;
313 GLenum blend_equation_alpha = GL_FUNC_ADD_EXT;
314 GLenum blend_equation = GL_FUNC_ADD_EXT;
316 /* BLENDOPALPHA requires GL_EXT_blend_equation_separate, so make sure it is around */
317 if (state->render_states[WINED3D_RS_BLENDOPALPHA]
318 && !gl_info->supported[EXT_BLEND_EQUATION_SEPARATE])
320 WARN("Unsupported in local OpenGL implementation: glBlendEquationSeparateEXT\n");
321 return;
324 blend_equation = gl_blend_op(state->render_states[WINED3D_RS_BLENDOP]);
325 blend_equation_alpha = gl_blend_op(state->render_states[WINED3D_RS_BLENDOPALPHA]);
326 TRACE("blend_equation %#x, blend_equation_alpha %#x.\n", blend_equation, blend_equation_alpha);
328 if (state->render_states[WINED3D_RS_SEPARATEALPHABLENDENABLE])
330 GL_EXTCALL(glBlendEquationSeparateEXT(blend_equation, blend_equation_alpha));
331 checkGLcall("glBlendEquationSeparateEXT");
333 else
335 GL_EXTCALL(glBlendEquationEXT(blend_equation));
336 checkGLcall("glBlendEquation");
340 static GLenum gl_blend_factor(enum wined3d_blend factor, const struct wined3d_format *dst_format)
342 switch (factor)
344 case WINED3D_BLEND_ZERO:
345 return GL_ZERO;
346 case WINED3D_BLEND_ONE:
347 return GL_ONE;
348 case WINED3D_BLEND_SRCCOLOR:
349 return GL_SRC_COLOR;
350 case WINED3D_BLEND_INVSRCCOLOR:
351 return GL_ONE_MINUS_SRC_COLOR;
352 case WINED3D_BLEND_SRCALPHA:
353 return GL_SRC_ALPHA;
354 case WINED3D_BLEND_INVSRCALPHA:
355 return GL_ONE_MINUS_SRC_ALPHA;
356 case WINED3D_BLEND_DESTCOLOR:
357 return GL_DST_COLOR;
358 case WINED3D_BLEND_INVDESTCOLOR:
359 return GL_ONE_MINUS_DST_COLOR;
360 /* To compensate for the lack of format switching with backbuffer
361 * offscreen rendering, and with onscreen rendering, we modify the
362 * alpha test parameters for (INV)DESTALPHA if the render target
363 * doesn't support alpha blending. A nonexistent alpha channel
364 * returns 1.0, so WINED3D_BLEND_DESTALPHA becomes GL_ONE, and
365 * WINED3D_BLEND_INVDESTALPHA becomes GL_ZERO. */
366 case WINED3D_BLEND_DESTALPHA:
367 return dst_format->alpha_size ? GL_DST_ALPHA : GL_ONE;
368 case WINED3D_BLEND_INVDESTALPHA:
369 return dst_format->alpha_size ? GL_ONE_MINUS_DST_ALPHA : GL_ZERO;
370 case WINED3D_BLEND_SRCALPHASAT:
371 return GL_SRC_ALPHA_SATURATE;
372 case WINED3D_BLEND_BLENDFACTOR:
373 return GL_CONSTANT_COLOR_EXT;
374 case WINED3D_BLEND_INVBLENDFACTOR:
375 return GL_ONE_MINUS_CONSTANT_COLOR_EXT;
376 default:
377 FIXME("Unhandled blend factor %#x.\n", factor);
378 return GL_NONE;
382 static void state_blend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
384 const struct wined3d_surface *target = state->fb->render_targets[0];
385 const struct wined3d_gl_info *gl_info = context->gl_info;
386 GLenum srcBlend, dstBlend;
387 enum wined3d_blend d3d_blend;
389 /* According to the red book, GL_LINE_SMOOTH needs GL_BLEND with specific
390 * blending parameters to work. */
391 if (state->render_states[WINED3D_RS_ALPHABLENDENABLE]
392 || state->render_states[WINED3D_RS_EDGEANTIALIAS]
393 || state->render_states[WINED3D_RS_ANTIALIASEDLINEENABLE])
395 /* Disable blending in all cases even without pixelshaders.
396 * With blending on we could face a big performance penalty.
397 * The d3d9 visual test confirms the behavior. */
398 if (context->render_offscreen
399 && !(target->resource.format->flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING))
401 gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
402 checkGLcall("glDisable GL_BLEND");
403 return;
405 else
407 gl_info->gl_ops.gl.p_glEnable(GL_BLEND);
408 checkGLcall("glEnable GL_BLEND");
411 else
413 gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
414 checkGLcall("glDisable GL_BLEND");
415 /* Nothing more to do - get out */
416 return;
419 /* WINED3D_BLEND_BOTHSRCALPHA and WINED3D_BLEND_BOTHINVSRCALPHA are legacy
420 * source blending values which are still valid up to d3d9. They should
421 * not occur as dest blend values. */
422 d3d_blend = state->render_states[WINED3D_RS_SRCBLEND];
423 if (d3d_blend == WINED3D_BLEND_BOTHSRCALPHA)
425 srcBlend = GL_SRC_ALPHA;
426 dstBlend = GL_ONE_MINUS_SRC_ALPHA;
428 else if (d3d_blend == WINED3D_BLEND_BOTHINVSRCALPHA)
430 srcBlend = GL_ONE_MINUS_SRC_ALPHA;
431 dstBlend = GL_SRC_ALPHA;
433 else
435 srcBlend = gl_blend_factor(d3d_blend, target->resource.format);
436 dstBlend = gl_blend_factor(state->render_states[WINED3D_RS_DESTBLEND],
437 target->resource.format);
440 if (state->render_states[WINED3D_RS_EDGEANTIALIAS]
441 || state->render_states[WINED3D_RS_ANTIALIASEDLINEENABLE])
443 gl_info->gl_ops.gl.p_glEnable(GL_LINE_SMOOTH);
444 checkGLcall("glEnable(GL_LINE_SMOOTH)");
445 if (srcBlend != GL_SRC_ALPHA)
446 WARN("WINED3D_RS_EDGEANTIALIAS enabled, but unexpected src blending param.\n");
447 if (dstBlend != GL_ONE_MINUS_SRC_ALPHA && dstBlend != GL_ONE)
448 WARN("WINED3D_RS_EDGEANTIALIAS enabled, but unexpected dst blending param.\n");
450 else
452 gl_info->gl_ops.gl.p_glDisable(GL_LINE_SMOOTH);
453 checkGLcall("glDisable(GL_LINE_SMOOTH)");
456 /* Re-apply BLENDOP(ALPHA) because of a possible SEPARATEALPHABLENDENABLE change */
457 if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_BLENDOP)))
458 state_blendop(context, state, STATE_RENDER(WINED3D_RS_BLENDOPALPHA));
460 if (state->render_states[WINED3D_RS_SEPARATEALPHABLENDENABLE])
462 GLenum srcBlendAlpha, dstBlendAlpha;
464 /* Separate alpha blending requires GL_EXT_blend_function_separate, so make sure it is around */
465 if (!context->gl_info->supported[EXT_BLEND_FUNC_SEPARATE])
467 WARN("Unsupported in local OpenGL implementation: glBlendFuncSeparateEXT\n");
468 return;
471 /* WINED3D_BLEND_BOTHSRCALPHA and WINED3D_BLEND_BOTHINVSRCALPHA are legacy
472 * source blending values which are still valid up to d3d9. They should
473 * not occur as dest blend values. */
474 d3d_blend = state->render_states[WINED3D_RS_SRCBLENDALPHA];
475 if (d3d_blend == WINED3D_BLEND_BOTHSRCALPHA)
477 srcBlendAlpha = GL_SRC_ALPHA;
478 dstBlendAlpha = GL_ONE_MINUS_SRC_ALPHA;
480 else if (d3d_blend == WINED3D_BLEND_BOTHINVSRCALPHA)
482 srcBlendAlpha = GL_ONE_MINUS_SRC_ALPHA;
483 dstBlendAlpha = GL_SRC_ALPHA;
485 else
487 srcBlendAlpha = gl_blend_factor(d3d_blend, target->resource.format);
488 dstBlendAlpha = gl_blend_factor(state->render_states[WINED3D_RS_DESTBLENDALPHA],
489 target->resource.format);
492 GL_EXTCALL(glBlendFuncSeparateEXT(srcBlend, dstBlend, srcBlendAlpha, dstBlendAlpha));
493 checkGLcall("glBlendFuncSeparateEXT");
495 else
497 TRACE("glBlendFunc src=%x, dst=%x\n", srcBlend, dstBlend);
498 gl_info->gl_ops.gl.p_glBlendFunc(srcBlend, dstBlend);
499 checkGLcall("glBlendFunc");
502 /* Colorkey fixup for stage 0 alphaop depends on
503 * WINED3D_RS_ALPHABLENDENABLE state, so it may need updating. */
504 if (state->render_states[WINED3D_RS_COLORKEYENABLE])
505 context_apply_state(context, state, STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP));
508 static void state_blendfactor_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
510 WARN("Unsupported in local OpenGL implementation: glBlendColorEXT\n");
513 static void state_blendfactor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
515 const struct wined3d_gl_info *gl_info = context->gl_info;
516 float col[4];
518 TRACE("Setting blend factor to %#x.\n", state->render_states[WINED3D_RS_BLENDFACTOR]);
520 D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_BLENDFACTOR], col);
521 GL_EXTCALL(glBlendColorEXT (col[0],col[1],col[2],col[3]));
522 checkGLcall("glBlendColor");
525 static void state_alpha(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
527 const struct wined3d_gl_info *gl_info = context->gl_info;
528 int glParm = 0;
529 float ref;
530 BOOL enable_ckey = FALSE;
532 TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
534 /* Find out if the texture on the first stage has a ckey set
535 * The alpha state func reads the texture settings, even though alpha and texture are not grouped
536 * together. This is to avoid making a huge alpha+texture+texture stage+ckey block due to the hardly
537 * used WINED3D_RS_COLORKEYENABLE state(which is d3d <= 3 only). The texture function will call alpha
538 * in case it finds some texture+colorkeyenable combination which needs extra care.
540 if (state->textures[0])
542 struct wined3d_surface *surface = surface_from_resource(state->textures[0]->sub_resources[0]);
544 if (surface->CKeyFlags & WINEDDSD_CKSRCBLT)
545 enable_ckey = TRUE;
548 if (enable_ckey || context->last_was_ckey)
549 context_apply_state(context, state, STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP));
550 context->last_was_ckey = enable_ckey;
552 if (state->render_states[WINED3D_RS_ALPHATESTENABLE]
553 || (state->render_states[WINED3D_RS_COLORKEYENABLE] && enable_ckey))
555 gl_info->gl_ops.gl.p_glEnable(GL_ALPHA_TEST);
556 checkGLcall("glEnable GL_ALPHA_TEST");
558 else
560 gl_info->gl_ops.gl.p_glDisable(GL_ALPHA_TEST);
561 checkGLcall("glDisable GL_ALPHA_TEST");
562 /* Alpha test is disabled, don't bother setting the params - it will happen on the next
563 * enable call
565 return;
568 if (state->render_states[WINED3D_RS_COLORKEYENABLE] && enable_ckey)
570 glParm = GL_NOTEQUAL;
571 ref = 0.0f;
573 else
575 ref = ((float)state->render_states[WINED3D_RS_ALPHAREF]) / 255.0f;
576 glParm = gl_compare_func(state->render_states[WINED3D_RS_ALPHAFUNC]);
578 if (glParm)
580 gl_info->gl_ops.gl.p_glAlphaFunc(glParm, ref);
581 checkGLcall("glAlphaFunc");
585 void state_clipping(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
587 const struct wined3d_gl_info *gl_info = context->gl_info;
588 DWORD enable = 0xffffffff;
589 DWORD disable = 0x00000000;
591 if (use_vs(state) && !context->d3d_info->vs_clipping)
593 static BOOL warned;
595 /* The OpenGL spec says that clipping planes are disabled when using
596 * shaders. Direct3D planes aren't, so that is an issue. The MacOS ATI
597 * driver keeps clipping planes activated with shaders in some
598 * conditions I got sick of tracking down. The shader state handler
599 * disables all clip planes because of that - don't do anything here
600 * and keep them disabled. */
601 if (state->render_states[WINED3D_RS_CLIPPLANEENABLE] && !warned++)
602 FIXME("Clipping not supported with vertex shaders\n");
603 return;
606 /* glEnable(GL_CLIP_PLANEx) doesn't apply to (ARB backend) vertex shaders.
607 * The enabled / disabled planes are hardcoded into the shader. Update the
608 * shader to update the enabled clipplanes. In case of fixed function, we
609 * need to update the clipping field from ffp_vertex_settings. */
610 context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_VERTEX;
612 /* TODO: Keep track of previously enabled clipplanes to avoid unnecessary resetting
613 * of already set values
616 /* If enabling / disabling all
617 * TODO: Is this correct? Doesn't D3DRS_CLIPPING disable clipping on the viewport frustrum?
619 if (state->render_states[WINED3D_RS_CLIPPING])
621 enable = state->render_states[WINED3D_RS_CLIPPLANEENABLE];
622 disable = ~state->render_states[WINED3D_RS_CLIPPLANEENABLE];
624 else
626 disable = 0xffffffff;
627 enable = 0x00;
630 if (enable & WINED3DCLIPPLANE0) gl_info->gl_ops.gl.p_glEnable(GL_CLIP_PLANE0);
631 if (enable & WINED3DCLIPPLANE1) gl_info->gl_ops.gl.p_glEnable(GL_CLIP_PLANE1);
632 if (enable & WINED3DCLIPPLANE2) gl_info->gl_ops.gl.p_glEnable(GL_CLIP_PLANE2);
633 if (enable & WINED3DCLIPPLANE3) gl_info->gl_ops.gl.p_glEnable(GL_CLIP_PLANE3);
634 if (enable & WINED3DCLIPPLANE4) gl_info->gl_ops.gl.p_glEnable(GL_CLIP_PLANE4);
635 if (enable & WINED3DCLIPPLANE5) gl_info->gl_ops.gl.p_glEnable(GL_CLIP_PLANE5);
636 checkGLcall("clip plane enable");
638 if (disable & WINED3DCLIPPLANE0) gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE0);
639 if (disable & WINED3DCLIPPLANE1) gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE1);
640 if (disable & WINED3DCLIPPLANE2) gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE2);
641 if (disable & WINED3DCLIPPLANE3) gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE3);
642 if (disable & WINED3DCLIPPLANE4) gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE4);
643 if (disable & WINED3DCLIPPLANE5) gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE5);
644 checkGLcall("clip plane disable");
647 void state_specularenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
649 const struct wined3d_gl_info *gl_info = context->gl_info;
650 /* Originally this used glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR)
651 * and (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR) to swap between enabled/disabled
652 * specular color. This is wrong:
653 * Separate specular color means the specular colour is maintained separately, whereas
654 * single color means it is merged in. However in both cases they are being used to
655 * some extent.
656 * To disable specular color, set it explicitly to black and turn off GL_COLOR_SUM_EXT
657 * NOTE: If not supported don't give FIXMEs the impact is really minimal and very few people are
658 * running 1.4 yet!
661 * If register combiners are enabled, enabling / disabling GL_COLOR_SUM has no effect.
662 * Instead, we need to setup the FinalCombiner properly.
664 * The default setup for the FinalCombiner is:
666 * <variable> <input> <mapping> <usage>
667 * GL_VARIABLE_A_NV GL_FOG, GL_UNSIGNED_IDENTITY_NV GL_ALPHA
668 * GL_VARIABLE_B_NV GL_SPARE0_PLUS_SECONDARY_COLOR_NV GL_UNSIGNED_IDENTITY_NV GL_RGB
669 * GL_VARIABLE_C_NV GL_FOG GL_UNSIGNED_IDENTITY_NV GL_RGB
670 * GL_VARIABLE_D_NV GL_ZERO GL_UNSIGNED_IDENTITY_NV GL_RGB
671 * GL_VARIABLE_E_NV GL_ZERO GL_UNSIGNED_IDENTITY_NV GL_RGB
672 * GL_VARIABLE_F_NV GL_ZERO GL_UNSIGNED_IDENTITY_NV GL_RGB
673 * GL_VARIABLE_G_NV GL_SPARE0_NV GL_UNSIGNED_IDENTITY_NV GL_ALPHA
675 * That's pretty much fine as it is, except for variable B, which needs to take
676 * either GL_SPARE0_PLUS_SECONDARY_COLOR_NV or GL_SPARE0_NV, depending on
677 * whether WINED3D_RS_SPECULARENABLE is enabled or not.
680 TRACE("Setting specular enable state and materials\n");
681 if (state->render_states[WINED3D_RS_SPECULARENABLE])
683 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float *)&state->material.specular);
684 checkGLcall("glMaterialfv");
686 if (state->material.power > gl_info->limits.shininess)
688 /* glMaterialf man page says that the material says that GL_SHININESS must be between 0.0
689 * and 128.0, although in d3d neither -1 nor 129 produce an error. GL_NV_max_light_exponent
690 * allows bigger values. If the extension is supported, gl_info->limits.shininess contains the
691 * value reported by the extension, otherwise 128. For values > gl_info->limits.shininess clamp
692 * them, it should be safe to do so without major visual distortions.
694 WARN("Material power = %.8e, limit %.8e\n", state->material.power, gl_info->limits.shininess);
695 gl_info->gl_ops.gl.p_glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, gl_info->limits.shininess);
697 else
699 gl_info->gl_ops.gl.p_glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, state->material.power);
701 checkGLcall("glMaterialf(GL_SHININESS)");
703 if (gl_info->supported[EXT_SECONDARY_COLOR])
704 gl_info->gl_ops.gl.p_glEnable(GL_COLOR_SUM_EXT);
705 else
706 TRACE("Specular colors cannot be enabled in this version of opengl\n");
707 checkGLcall("glEnable(GL_COLOR_SUM)");
709 if (gl_info->supported[NV_REGISTER_COMBINERS])
711 GL_EXTCALL(glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_SPARE0_PLUS_SECONDARY_COLOR_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB));
712 checkGLcall("glFinalCombinerInputNV()");
714 } else {
715 static const GLfloat black[] = {0.0f, 0.0f, 0.0f, 0.0f};
717 /* for the case of enabled lighting: */
718 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
719 checkGLcall("glMaterialfv");
721 /* for the case of disabled lighting: */
722 if (gl_info->supported[EXT_SECONDARY_COLOR])
723 gl_info->gl_ops.gl.p_glDisable(GL_COLOR_SUM_EXT);
724 else
725 TRACE("Specular colors cannot be disabled in this version of opengl\n");
726 checkGLcall("glDisable(GL_COLOR_SUM)");
728 if (gl_info->supported[NV_REGISTER_COMBINERS])
730 GL_EXTCALL(glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB));
731 checkGLcall("glFinalCombinerInputNV()");
735 TRACE("diffuse {%.8e, %.8e, %.8e, %.8e}\n",
736 state->material.diffuse.r, state->material.diffuse.g,
737 state->material.diffuse.b, state->material.diffuse.a);
738 TRACE("ambient {%.8e, %.8e, %.8e, %.8e}\n",
739 state->material.ambient.r, state->material.ambient.g,
740 state->material.ambient.b, state->material.ambient.a);
741 TRACE("specular {%.8e, %.8e, %.8e, %.8e}\n",
742 state->material.specular.r, state->material.specular.g,
743 state->material.specular.b, state->material.specular.a);
744 TRACE("emissive {%.8e, %.8e, %.8e, %.8e}\n",
745 state->material.emissive.r, state->material.emissive.g,
746 state->material.emissive.b, state->material.emissive.a);
748 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float *)&state->material.ambient);
749 checkGLcall("glMaterialfv(GL_AMBIENT)");
750 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float *)&state->material.diffuse);
751 checkGLcall("glMaterialfv(GL_DIFFUSE)");
752 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float *)&state->material.emissive);
753 checkGLcall("glMaterialfv(GL_EMISSION)");
756 static void state_texfactor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
758 const struct wined3d_gl_info *gl_info = context->gl_info;
759 unsigned int i;
761 /* Note the texture color applies to all textures whereas
762 * GL_TEXTURE_ENV_COLOR applies to active only. */
763 float col[4];
764 D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_TEXTUREFACTOR], col);
766 /* And now the default texture color as well */
767 for (i = 0; i < context->d3d_info->limits.ffp_blend_stages; ++i)
769 /* Note the WINED3D_RS value applies to all textures, but GL has one
770 * per texture, so apply it now ready to be used! */
771 context_active_texture(context, gl_info, i);
773 gl_info->gl_ops.gl.p_glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
774 checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
778 static void renderstate_stencil_twosided(struct wined3d_context *context, GLint face,
779 GLint func, GLint ref, GLuint mask, GLint stencilFail, GLint depthFail, GLint stencilPass)
781 const struct wined3d_gl_info *gl_info = context->gl_info;
783 gl_info->gl_ops.gl.p_glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);
784 checkGLcall("glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT)");
785 GL_EXTCALL(glActiveStencilFaceEXT(face));
786 checkGLcall("glActiveStencilFaceEXT(...)");
787 gl_info->gl_ops.gl.p_glStencilFunc(func, ref, mask);
788 checkGLcall("glStencilFunc(...)");
789 gl_info->gl_ops.gl.p_glStencilOp(stencilFail, depthFail, stencilPass);
790 checkGLcall("glStencilOp(...)");
793 static GLenum gl_stencil_op(enum wined3d_stencil_op op)
795 switch (op)
797 case WINED3D_STENCIL_OP_KEEP:
798 return GL_KEEP;
799 case WINED3D_STENCIL_OP_ZERO:
800 return GL_ZERO;
801 case WINED3D_STENCIL_OP_REPLACE:
802 return GL_REPLACE;
803 case WINED3D_STENCIL_OP_INCR_SAT:
804 return GL_INCR;
805 case WINED3D_STENCIL_OP_DECR_SAT:
806 return GL_DECR;
807 case WINED3D_STENCIL_OP_INVERT:
808 return GL_INVERT;
809 case WINED3D_STENCIL_OP_INCR:
810 return GL_INCR_WRAP_EXT;
811 case WINED3D_STENCIL_OP_DECR:
812 return GL_DECR_WRAP_EXT;
813 default:
814 FIXME("Unrecognized stencil op %#x.\n", op);
815 return GL_KEEP;
819 static void state_stencil(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
821 const struct wined3d_gl_info *gl_info = context->gl_info;
822 DWORD onesided_enable = FALSE;
823 DWORD twosided_enable = FALSE;
824 GLint func = GL_ALWAYS;
825 GLint func_ccw = GL_ALWAYS;
826 GLint ref = 0;
827 GLuint mask = 0;
828 GLint stencilFail = GL_KEEP;
829 GLint depthFail = GL_KEEP;
830 GLint stencilPass = GL_KEEP;
831 GLint stencilFail_ccw = GL_KEEP;
832 GLint depthFail_ccw = GL_KEEP;
833 GLint stencilPass_ccw = GL_KEEP;
835 /* No stencil test without a stencil buffer. */
836 if (!state->fb->depth_stencil)
838 gl_info->gl_ops.gl.p_glDisable(GL_STENCIL_TEST);
839 checkGLcall("glDisable GL_STENCIL_TEST");
840 return;
843 onesided_enable = state->render_states[WINED3D_RS_STENCILENABLE];
844 twosided_enable = state->render_states[WINED3D_RS_TWOSIDEDSTENCILMODE];
845 if (!(func = gl_compare_func(state->render_states[WINED3D_RS_STENCILFUNC])))
846 func = GL_ALWAYS;
847 if (!(func_ccw = gl_compare_func(state->render_states[WINED3D_RS_CCW_STENCILFUNC])))
848 func_ccw = GL_ALWAYS;
849 ref = state->render_states[WINED3D_RS_STENCILREF];
850 mask = state->render_states[WINED3D_RS_STENCILMASK];
851 stencilFail = gl_stencil_op(state->render_states[WINED3D_RS_STENCILFAIL]);
852 depthFail = gl_stencil_op(state->render_states[WINED3D_RS_STENCILZFAIL]);
853 stencilPass = gl_stencil_op(state->render_states[WINED3D_RS_STENCILPASS]);
854 stencilFail_ccw = gl_stencil_op(state->render_states[WINED3D_RS_CCW_STENCILFAIL]);
855 depthFail_ccw = gl_stencil_op(state->render_states[WINED3D_RS_CCW_STENCILZFAIL]);
856 stencilPass_ccw = gl_stencil_op(state->render_states[WINED3D_RS_CCW_STENCILPASS]);
858 TRACE("(onesided %d, twosided %d, ref %x, mask %x, "
859 "GL_FRONT: func: %x, fail %x, zfail %x, zpass %x "
860 "GL_BACK: func: %x, fail %x, zfail %x, zpass %x )\n",
861 onesided_enable, twosided_enable, ref, mask,
862 func, stencilFail, depthFail, stencilPass,
863 func_ccw, stencilFail_ccw, depthFail_ccw, stencilPass_ccw);
865 if (twosided_enable && onesided_enable)
867 gl_info->gl_ops.gl.p_glEnable(GL_STENCIL_TEST);
868 checkGLcall("glEnable GL_STENCIL_TEST");
870 if (gl_info->supported[EXT_STENCIL_TWO_SIDE])
872 /* Apply back first, then front. This function calls glActiveStencilFaceEXT,
873 * which has an effect on the code below too. If we apply the front face
874 * afterwards, we are sure that the active stencil face is set to front,
875 * and other stencil functions which do not use two sided stencil do not have
876 * to set it back
878 renderstate_stencil_twosided(context, GL_BACK,
879 func_ccw, ref, mask, stencilFail_ccw, depthFail_ccw, stencilPass_ccw);
880 renderstate_stencil_twosided(context, GL_FRONT,
881 func, ref, mask, stencilFail, depthFail, stencilPass);
883 else if (gl_info->supported[ATI_SEPARATE_STENCIL])
885 GL_EXTCALL(glStencilFuncSeparateATI(func, func_ccw, ref, mask));
886 checkGLcall("glStencilFuncSeparateATI(...)");
887 GL_EXTCALL(glStencilOpSeparateATI(GL_FRONT, stencilFail, depthFail, stencilPass));
888 checkGLcall("glStencilOpSeparateATI(GL_FRONT, ...)");
889 GL_EXTCALL(glStencilOpSeparateATI(GL_BACK, stencilFail_ccw, depthFail_ccw, stencilPass_ccw));
890 checkGLcall("glStencilOpSeparateATI(GL_BACK, ...)");
891 } else {
892 ERR("Separate (two sided) stencil not supported on this version of opengl. Caps weren't honored?\n");
895 else if(onesided_enable)
897 if (gl_info->supported[EXT_STENCIL_TWO_SIDE])
899 gl_info->gl_ops.gl.p_glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);
900 checkGLcall("glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT)");
903 /* This code disables the ATI extension as well, since the standard stencil functions are equal
904 * to calling the ATI functions with GL_FRONT_AND_BACK as face parameter
906 gl_info->gl_ops.gl.p_glEnable(GL_STENCIL_TEST);
907 checkGLcall("glEnable GL_STENCIL_TEST");
908 gl_info->gl_ops.gl.p_glStencilFunc(func, ref, mask);
909 checkGLcall("glStencilFunc(...)");
910 gl_info->gl_ops.gl.p_glStencilOp(stencilFail, depthFail, stencilPass);
911 checkGLcall("glStencilOp(...)");
913 else
915 gl_info->gl_ops.gl.p_glDisable(GL_STENCIL_TEST);
916 checkGLcall("glDisable GL_STENCIL_TEST");
920 static void state_stencilwrite2s(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
922 DWORD mask = state->fb->depth_stencil ? state->render_states[WINED3D_RS_STENCILWRITEMASK] : 0;
923 const struct wined3d_gl_info *gl_info = context->gl_info;
925 GL_EXTCALL(glActiveStencilFaceEXT(GL_BACK));
926 checkGLcall("glActiveStencilFaceEXT(GL_BACK)");
927 gl_info->gl_ops.gl.p_glStencilMask(mask);
928 checkGLcall("glStencilMask");
929 GL_EXTCALL(glActiveStencilFaceEXT(GL_FRONT));
930 checkGLcall("glActiveStencilFaceEXT(GL_FRONT)");
931 gl_info->gl_ops.gl.p_glStencilMask(mask);
934 static void state_stencilwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
936 DWORD mask = state->fb->depth_stencil ? state->render_states[WINED3D_RS_STENCILWRITEMASK] : 0;
937 const struct wined3d_gl_info *gl_info = context->gl_info;
939 gl_info->gl_ops.gl.p_glStencilMask(mask);
940 checkGLcall("glStencilMask");
943 static void state_fog_vertexpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
945 const struct wined3d_gl_info *gl_info = context->gl_info;
947 TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
949 if (!state->render_states[WINED3D_RS_FOGENABLE])
950 return;
952 /* Table fog on: Never use fog coords, and use per-fragment fog */
953 if (state->render_states[WINED3D_RS_FOGTABLEMODE] != WINED3D_FOG_NONE)
955 gl_info->gl_ops.gl.p_glHint(GL_FOG_HINT, GL_NICEST);
956 if (context->fog_coord)
958 gl_info->gl_ops.gl.p_glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
959 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT)");
960 context->fog_coord = FALSE;
963 /* Range fog is only used with per-vertex fog in d3d */
964 if (gl_info->supported[NV_FOG_DISTANCE])
966 gl_info->gl_ops.gl.p_glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV);
967 checkGLcall("glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV)");
969 return;
972 /* Otherwise use per-vertex fog in any case */
973 gl_info->gl_ops.gl.p_glHint(GL_FOG_HINT, GL_FASTEST);
975 if (state->render_states[WINED3D_RS_FOGVERTEXMODE] == WINED3D_FOG_NONE || context->last_was_rhw)
977 /* No fog at all, or transformed vertices: Use fog coord */
978 if (!context->fog_coord)
980 gl_info->gl_ops.gl.p_glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);
981 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT)");
982 context->fog_coord = TRUE;
985 else
987 /* Otherwise, use the fragment depth */
988 if (context->fog_coord)
990 gl_info->gl_ops.gl.p_glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
991 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT)");
992 context->fog_coord = FALSE;
995 if (state->render_states[WINED3D_RS_RANGEFOGENABLE])
997 if (gl_info->supported[NV_FOG_DISTANCE])
999 gl_info->gl_ops.gl.p_glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_RADIAL_NV);
1000 checkGLcall("glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_RADIAL_NV)");
1002 else
1004 WARN("Range fog enabled, but not supported by this GL implementation.\n");
1007 else if (gl_info->supported[NV_FOG_DISTANCE])
1009 gl_info->gl_ops.gl.p_glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV);
1010 checkGLcall("glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV)");
1015 void state_fogstartend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1017 const struct wined3d_gl_info *gl_info = context->gl_info;
1018 float fogstart, fogend;
1019 union {
1020 DWORD d;
1021 float f;
1022 } tmpvalue;
1024 switch(context->fog_source) {
1025 case FOGSOURCE_VS:
1026 fogstart = 1.0f;
1027 fogend = 0.0f;
1028 break;
1030 case FOGSOURCE_COORD:
1031 fogstart = 255.0f;
1032 fogend = 0.0f;
1033 break;
1035 case FOGSOURCE_FFP:
1036 tmpvalue.d = state->render_states[WINED3D_RS_FOGSTART];
1037 fogstart = tmpvalue.f;
1038 tmpvalue.d = state->render_states[WINED3D_RS_FOGEND];
1039 fogend = tmpvalue.f;
1040 /* Special handling for fogstart == fogend. In d3d with vertex
1041 * fog, everything is fogged. With table fog, everything with
1042 * fog_coord < fog_start is unfogged, and fog_coord > fog_start
1043 * is fogged. Windows drivers disagree when fog_coord == fog_start. */
1044 if (state->render_states[WINED3D_RS_FOGTABLEMODE] == WINED3D_FOG_NONE
1045 && fogstart == fogend)
1047 fogstart = -INFINITY;
1048 fogend = 0.0f;
1050 break;
1052 default:
1053 /* This should not happen.context->fog_source is set in wined3d, not the app.
1054 * Still this is needed to make the compiler happy
1056 ERR("Unexpected fog coordinate source\n");
1057 fogstart = 0.0f;
1058 fogend = 0.0f;
1061 gl_info->gl_ops.gl.p_glFogf(GL_FOG_START, fogstart);
1062 checkGLcall("glFogf(GL_FOG_START, fogstart)");
1063 TRACE("Fog Start == %f\n", fogstart);
1065 gl_info->gl_ops.gl.p_glFogf(GL_FOG_END, fogend);
1066 checkGLcall("glFogf(GL_FOG_END, fogend)");
1067 TRACE("Fog End == %f\n", fogend);
1070 void state_fog_fragpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1072 const struct wined3d_gl_info *gl_info = context->gl_info;
1073 enum fogsource new_source;
1074 DWORD fogstart = state->render_states[WINED3D_RS_FOGSTART];
1075 DWORD fogend = state->render_states[WINED3D_RS_FOGEND];
1077 TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
1079 if (!state->render_states[WINED3D_RS_FOGENABLE])
1081 /* No fog? Disable it, and we're done :-) */
1082 glDisableWINE(GL_FOG);
1083 checkGLcall("glDisable GL_FOG");
1084 return;
1087 /* Fog Rules:
1089 * With fixed function vertex processing, Direct3D knows 2 different fog input sources.
1090 * It can use the Z value of the vertex, or the alpha component of the specular color.
1091 * This depends on the fog vertex, fog table and the vertex declaration. If the Z value
1092 * is used, fogstart, fogend and the equation type are used, otherwise linear fog with
1093 * start = 255, end = 0 is used. Obviously the msdn is not very clear on that.
1095 * FOGTABLEMODE != NONE:
1096 * The Z value is used, with the equation specified, no matter what vertex type.
1098 * FOGTABLEMODE == NONE, FOGVERTEXMODE != NONE, untransformed:
1099 * Per vertex fog is calculated using the specified fog equation and the parameters
1101 * FOGTABLEMODE == NONE, FOGVERTEXMODE != NONE, transformed, OR
1102 * FOGTABLEMODE == NONE, FOGVERTEXMODE == NONE, untransformed:
1103 * Linear fog with start = 255.0, end = 0.0, input comes from the specular color
1106 * Rules for vertex fog with shaders:
1108 * When mixing fixed function functionality with the programmable pipeline, D3D expects
1109 * the fog computation to happen during transformation while openGL expects it to happen
1110 * during rasterization. Also, prior to pixel shader 3.0 D3D handles fog blending after
1111 * the pixel shader while openGL always expects the pixel shader to handle the blending.
1112 * To solve this problem, WineD3D does:
1113 * 1) implement a linear fog equation and fog blending at the end of every pre 3.0 pixel
1114 * shader,
1115 * and 2) disables the fog computation (in either the fixed function or programmable
1116 * rasterizer) if using a vertex program.
1118 * D3D shaders can provide an explicit fog coordinate. This fog coordinate is used with
1119 * D3DRS_FOGTABLEMODE==D3DFOG_NONE. The FOGVERTEXMODE is ignored, d3d always uses linear
1120 * fog with start=1.0 and end=0.0 in this case. This is similar to fog coordinates in
1121 * the specular color, a vertex shader counts as pretransformed geometry in this case.
1122 * There are some GL differences between specular fog coords and vertex shaders though.
1124 * With table fog the vertex shader fog coordinate is ignored.
1126 * If a fogtablemode and a fogvertexmode are specified, table fog is applied (with or
1127 * without shaders).
1130 /* DX 7 sdk: "If both render states(vertex and table fog) are set to valid modes,
1131 * the system will apply only pixel(=table) fog effects."
1133 if (state->render_states[WINED3D_RS_FOGTABLEMODE] == WINED3D_FOG_NONE)
1135 if (use_vs(state))
1137 gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_LINEAR);
1138 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1139 new_source = FOGSOURCE_VS;
1141 else
1143 switch (state->render_states[WINED3D_RS_FOGVERTEXMODE])
1145 /* If processed vertices are used, fall through to the NONE case */
1146 case WINED3D_FOG_EXP:
1147 if (!context->last_was_rhw)
1149 gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_EXP);
1150 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP)");
1151 new_source = FOGSOURCE_FFP;
1152 break;
1154 /* drop through */
1156 case WINED3D_FOG_EXP2:
1157 if (!context->last_was_rhw)
1159 gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_EXP2);
1160 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2)");
1161 new_source = FOGSOURCE_FFP;
1162 break;
1164 /* drop through */
1166 case WINED3D_FOG_LINEAR:
1167 if (!context->last_was_rhw)
1169 gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_LINEAR);
1170 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1171 new_source = FOGSOURCE_FFP;
1172 break;
1174 /* drop through */
1176 case WINED3D_FOG_NONE:
1177 /* Both are none? According to msdn the alpha channel of the specular
1178 * color contains a fog factor. Set it in drawStridedSlow.
1179 * Same happens with Vertexfog on transformed vertices
1181 new_source = FOGSOURCE_COORD;
1182 gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_LINEAR);
1183 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1184 break;
1186 default:
1187 FIXME("Unexpected WINED3D_RS_FOGVERTEXMODE %#x.\n",
1188 state->render_states[WINED3D_RS_FOGVERTEXMODE]);
1189 new_source = FOGSOURCE_FFP; /* Make the compiler happy */
1192 } else {
1193 new_source = FOGSOURCE_FFP;
1195 switch (state->render_states[WINED3D_RS_FOGTABLEMODE])
1197 case WINED3D_FOG_EXP:
1198 gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_EXP);
1199 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP)");
1200 break;
1202 case WINED3D_FOG_EXP2:
1203 gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_EXP2);
1204 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2)");
1205 break;
1207 case WINED3D_FOG_LINEAR:
1208 gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_LINEAR);
1209 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1210 break;
1212 case WINED3D_FOG_NONE: /* Won't happen */
1213 default:
1214 FIXME("Unexpected WINED3D_RS_FOGTABLEMODE %#x.\n",
1215 state->render_states[WINED3D_RS_FOGTABLEMODE]);
1219 glEnableWINE(GL_FOG);
1220 checkGLcall("glEnable GL_FOG");
1221 if (new_source != context->fog_source || fogstart == fogend)
1223 context->fog_source = new_source;
1224 state_fogstartend(context, state, STATE_RENDER(WINED3D_RS_FOGSTART));
1228 void state_fogcolor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1230 const struct wined3d_gl_info *gl_info = context->gl_info;
1231 float col[4];
1233 D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_FOGCOLOR], col);
1234 gl_info->gl_ops.gl.p_glFogfv(GL_FOG_COLOR, &col[0]);
1235 checkGLcall("glFog GL_FOG_COLOR");
1238 void state_fogdensity(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1240 const struct wined3d_gl_info *gl_info = context->gl_info;
1241 union {
1242 DWORD d;
1243 float f;
1244 } tmpvalue;
1246 tmpvalue.d = state->render_states[WINED3D_RS_FOGDENSITY];
1247 gl_info->gl_ops.gl.p_glFogfv(GL_FOG_DENSITY, &tmpvalue.f);
1248 checkGLcall("glFogf(GL_FOG_DENSITY, (float) Value)");
1251 static void state_colormat(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1253 const struct wined3d_device *device = context->swapchain->device;
1254 const struct wined3d_gl_info *gl_info = context->gl_info;
1255 GLenum Parm = 0;
1257 /* Depends on the decoded vertex declaration to read the existence of diffuse data.
1258 * The vertex declaration will call this function if the fixed function pipeline is used.
1261 if(isStateDirty(context, STATE_VDECL)) {
1262 return;
1265 context->num_untracked_materials = 0;
1266 if ((device->stream_info.use_map & (1 << WINED3D_FFP_DIFFUSE))
1267 && state->render_states[WINED3D_RS_COLORVERTEX])
1269 TRACE("diff %d, amb %d, emis %d, spec %d\n",
1270 state->render_states[WINED3D_RS_DIFFUSEMATERIALSOURCE],
1271 state->render_states[WINED3D_RS_AMBIENTMATERIALSOURCE],
1272 state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE],
1273 state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE]);
1275 if (state->render_states[WINED3D_RS_DIFFUSEMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1277 if (state->render_states[WINED3D_RS_AMBIENTMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1278 Parm = GL_AMBIENT_AND_DIFFUSE;
1279 else
1280 Parm = GL_DIFFUSE;
1281 if (state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1283 context->untracked_materials[context->num_untracked_materials] = GL_EMISSION;
1284 context->num_untracked_materials++;
1286 if (state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1288 context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
1289 context->num_untracked_materials++;
1292 else if (state->render_states[WINED3D_RS_AMBIENTMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1294 Parm = GL_AMBIENT;
1295 if (state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1297 context->untracked_materials[context->num_untracked_materials] = GL_EMISSION;
1298 context->num_untracked_materials++;
1300 if (state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1302 context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
1303 context->num_untracked_materials++;
1306 else if (state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1308 Parm = GL_EMISSION;
1309 if (state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1311 context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
1312 context->num_untracked_materials++;
1315 else if (state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1317 Parm = GL_SPECULAR;
1321 /* Nothing changed, return. */
1322 if (Parm == context->tracking_parm) return;
1324 if (!Parm)
1326 gl_info->gl_ops.gl.p_glDisable(GL_COLOR_MATERIAL);
1327 checkGLcall("glDisable GL_COLOR_MATERIAL");
1329 else
1331 gl_info->gl_ops.gl.p_glColorMaterial(GL_FRONT_AND_BACK, Parm);
1332 checkGLcall("glColorMaterial(GL_FRONT_AND_BACK, Parm)");
1333 gl_info->gl_ops.gl.p_glEnable(GL_COLOR_MATERIAL);
1334 checkGLcall("glEnable(GL_COLOR_MATERIAL)");
1337 /* Apparently calls to glMaterialfv are ignored for properties we're
1338 * tracking with glColorMaterial, so apply those here. */
1339 switch (context->tracking_parm)
1341 case GL_AMBIENT_AND_DIFFUSE:
1342 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float *)&state->material.ambient);
1343 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float *)&state->material.diffuse);
1344 checkGLcall("glMaterialfv");
1345 break;
1347 case GL_DIFFUSE:
1348 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float *)&state->material.diffuse);
1349 checkGLcall("glMaterialfv");
1350 break;
1352 case GL_AMBIENT:
1353 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float *)&state->material.ambient);
1354 checkGLcall("glMaterialfv");
1355 break;
1357 case GL_EMISSION:
1358 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float *)&state->material.emissive);
1359 checkGLcall("glMaterialfv");
1360 break;
1362 case GL_SPECULAR:
1363 /* Only change material color if specular is enabled, otherwise it is set to black */
1364 if (state->render_states[WINED3D_RS_SPECULARENABLE])
1366 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float *)&state->material.specular);
1367 checkGLcall("glMaterialfv");
1369 else
1371 static const GLfloat black[] = {0.0f, 0.0f, 0.0f, 0.0f};
1372 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
1373 checkGLcall("glMaterialfv");
1375 break;
1378 context->tracking_parm = Parm;
1381 static void state_linepattern(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1383 const struct wined3d_gl_info *gl_info = context->gl_info;
1384 union
1386 DWORD d;
1387 struct wined3d_line_pattern lp;
1388 } tmppattern;
1389 tmppattern.d = state->render_states[WINED3D_RS_LINEPATTERN];
1391 TRACE("Line pattern: repeat %d bits %x.\n", tmppattern.lp.repeat_factor, tmppattern.lp.line_pattern);
1393 if (tmppattern.lp.repeat_factor)
1395 gl_info->gl_ops.gl.p_glLineStipple(tmppattern.lp.repeat_factor, tmppattern.lp.line_pattern);
1396 checkGLcall("glLineStipple(repeat, linepattern)");
1397 gl_info->gl_ops.gl.p_glEnable(GL_LINE_STIPPLE);
1398 checkGLcall("glEnable(GL_LINE_STIPPLE);");
1400 else
1402 gl_info->gl_ops.gl.p_glDisable(GL_LINE_STIPPLE);
1403 checkGLcall("glDisable(GL_LINE_STIPPLE);");
1407 static void state_normalize(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1409 const struct wined3d_gl_info *gl_info = context->gl_info;
1411 if (isStateDirty(context, STATE_VDECL))
1412 return;
1414 /* Without vertex normals, we set the current normal to 0/0/0 to remove the diffuse factor
1415 * from the opengl lighting equation, as d3d does. Normalization of 0/0/0 can lead to a division
1416 * by zero and is not properly defined in opengl, so avoid it
1418 if (state->render_states[WINED3D_RS_NORMALIZENORMALS]
1419 && (context->swapchain->device->stream_info.use_map & (1 << WINED3D_FFP_NORMAL)))
1421 gl_info->gl_ops.gl.p_glEnable(GL_NORMALIZE);
1422 checkGLcall("glEnable(GL_NORMALIZE);");
1424 else
1426 gl_info->gl_ops.gl.p_glDisable(GL_NORMALIZE);
1427 checkGLcall("glDisable(GL_NORMALIZE);");
1431 void state_psizemin_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1433 union {
1434 DWORD d;
1435 float f;
1436 } tmpvalue;
1438 tmpvalue.d = state->render_states[WINED3D_RS_POINTSIZE_MIN];
1439 if (tmpvalue.f != 1.0f)
1441 FIXME("WINED3D_RS_POINTSIZE_MIN not supported on this opengl, value is %f\n", tmpvalue.f);
1443 tmpvalue.d = state->render_states[WINED3D_RS_POINTSIZE_MAX];
1444 if (tmpvalue.f != 64.0f)
1446 FIXME("WINED3D_RS_POINTSIZE_MAX not supported on this opengl, value is %f\n", tmpvalue.f);
1451 void state_psizemin_ext(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1453 const struct wined3d_gl_info *gl_info = context->gl_info;
1454 union
1456 DWORD d;
1457 float f;
1458 } min, max;
1460 min.d = state->render_states[WINED3D_RS_POINTSIZE_MIN];
1461 max.d = state->render_states[WINED3D_RS_POINTSIZE_MAX];
1463 /* Max point size trumps min point size */
1464 if(min.f > max.f) {
1465 min.f = max.f;
1468 GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MIN_EXT, min.f);
1469 checkGLcall("glPointParameterfEXT(...)");
1470 GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MAX_EXT, max.f);
1471 checkGLcall("glPointParameterfEXT(...)");
1474 void state_psizemin_arb(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1476 const struct wined3d_gl_info *gl_info = context->gl_info;
1477 union
1479 DWORD d;
1480 float f;
1481 } min, max;
1483 min.d = state->render_states[WINED3D_RS_POINTSIZE_MIN];
1484 max.d = state->render_states[WINED3D_RS_POINTSIZE_MAX];
1486 /* Max point size trumps min point size */
1487 if(min.f > max.f) {
1488 min.f = max.f;
1491 GL_EXTCALL(glPointParameterfARB)(GL_POINT_SIZE_MIN_ARB, min.f);
1492 checkGLcall("glPointParameterfARB(...)");
1493 GL_EXTCALL(glPointParameterfARB)(GL_POINT_SIZE_MAX_ARB, max.f);
1494 checkGLcall("glPointParameterfARB(...)");
1497 void state_pscale(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1499 const struct wined3d_gl_info *gl_info = context->gl_info;
1500 /* TODO: Group this with the viewport */
1502 * POINTSCALEENABLE controls how point size value is treated. If set to
1503 * true, the point size is scaled with respect to height of viewport.
1504 * When set to false point size is in pixels.
1507 /* Default values */
1508 GLfloat att[3] = {1.0f, 0.0f, 0.0f};
1509 union {
1510 DWORD d;
1511 float f;
1512 } pointSize, A, B, C;
1514 pointSize.d = state->render_states[WINED3D_RS_POINTSIZE];
1515 A.d = state->render_states[WINED3D_RS_POINTSCALE_A];
1516 B.d = state->render_states[WINED3D_RS_POINTSCALE_B];
1517 C.d = state->render_states[WINED3D_RS_POINTSCALE_C];
1519 if (state->render_states[WINED3D_RS_POINTSCALEENABLE])
1521 DWORD h = state->viewport.height;
1522 GLfloat scaleFactor;
1524 if (pointSize.f < gl_info->limits.pointsize_min)
1526 /* Minimum valid point size for OpenGL is driver specific. For Direct3D it is
1527 * 0.0f. This means that OpenGL will clamp really small point sizes to the
1528 * driver minimum. To correct for this we need to multiply by the scale factor when sizes
1529 * are less than 1.0f. scale_factor = 1.0f / point_size.
1531 scaleFactor = pointSize.f / gl_info->limits.pointsize_min;
1532 /* Clamp the point size, don't rely on the driver to do it. MacOS says min point size
1533 * is 1.0, but then accepts points below that and draws too small points
1535 pointSize.f = gl_info->limits.pointsize_min;
1537 else if(pointSize.f > gl_info->limits.pointsize_max)
1539 /* gl already scales the input to glPointSize,
1540 * d3d scales the result after the point size scale.
1541 * If the point size is bigger than the max size, use the
1542 * scaling to scale it bigger, and set the gl point size to max
1544 scaleFactor = pointSize.f / gl_info->limits.pointsize_max;
1545 TRACE("scale: %f\n", scaleFactor);
1546 pointSize.f = gl_info->limits.pointsize_max;
1547 } else {
1548 scaleFactor = 1.0f;
1550 scaleFactor = powf(h * scaleFactor, 2);
1552 att[0] = A.f / scaleFactor;
1553 att[1] = B.f / scaleFactor;
1554 att[2] = C.f / scaleFactor;
1557 if (gl_info->supported[ARB_POINT_PARAMETERS])
1559 GL_EXTCALL(glPointParameterfvARB)(GL_POINT_DISTANCE_ATTENUATION_ARB, att);
1560 checkGLcall("glPointParameterfvARB(GL_DISTANCE_ATTENUATION_ARB, ...)");
1562 else if (gl_info->supported[EXT_POINT_PARAMETERS])
1564 GL_EXTCALL(glPointParameterfvEXT)(GL_DISTANCE_ATTENUATION_EXT, att);
1565 checkGLcall("glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, ...)");
1567 else if (state->render_states[WINED3D_RS_POINTSCALEENABLE])
1569 WARN("POINT_PARAMETERS not supported in this version of opengl\n");
1572 gl_info->gl_ops.gl.p_glPointSize(pointSize.f);
1573 checkGLcall("glPointSize(...);");
1576 static void state_debug_monitor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1578 WARN("token: %#x.\n", state->render_states[WINED3D_RS_DEBUGMONITORTOKEN]);
1581 static void state_colorwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1583 DWORD mask0 = state->render_states[WINED3D_RS_COLORWRITEENABLE];
1584 DWORD mask1 = state->render_states[WINED3D_RS_COLORWRITEENABLE1];
1585 DWORD mask2 = state->render_states[WINED3D_RS_COLORWRITEENABLE2];
1586 DWORD mask3 = state->render_states[WINED3D_RS_COLORWRITEENABLE3];
1587 const struct wined3d_gl_info *gl_info = context->gl_info;
1589 TRACE("Color mask: r(%d) g(%d) b(%d) a(%d)\n",
1590 mask0 & WINED3DCOLORWRITEENABLE_RED ? 1 : 0,
1591 mask0 & WINED3DCOLORWRITEENABLE_GREEN ? 1 : 0,
1592 mask0 & WINED3DCOLORWRITEENABLE_BLUE ? 1 : 0,
1593 mask0 & WINED3DCOLORWRITEENABLE_ALPHA ? 1 : 0);
1594 gl_info->gl_ops.gl.p_glColorMask(mask0 & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE,
1595 mask0 & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE,
1596 mask0 & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE,
1597 mask0 & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE);
1598 checkGLcall("glColorMask(...)");
1600 if (!((mask1 == mask0 && mask2 == mask0 && mask3 == mask0)
1601 || (mask1 == 0xf && mask2 == 0xf && mask3 == 0xf)))
1603 FIXME("WINED3D_RS_COLORWRITEENABLE/1/2/3, %#x/%#x/%#x/%#x not yet implemented.\n",
1604 mask0, mask1, mask2, mask3);
1605 FIXME("Missing of cap D3DPMISCCAPS_INDEPENDENTWRITEMASKS wasn't honored?\n");
1609 static void set_color_mask(const struct wined3d_gl_info *gl_info, UINT index, DWORD mask)
1611 GL_EXTCALL(glColorMaskIndexedEXT(index,
1612 mask & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE,
1613 mask & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE,
1614 mask & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE,
1615 mask & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE));
1618 static void state_colorwrite0(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1620 set_color_mask(context->gl_info, 0, state->render_states[WINED3D_RS_COLORWRITEENABLE]);
1623 static void state_colorwrite1(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1625 set_color_mask(context->gl_info, 1, state->render_states[WINED3D_RS_COLORWRITEENABLE1]);
1628 static void state_colorwrite2(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1630 set_color_mask(context->gl_info, 2, state->render_states[WINED3D_RS_COLORWRITEENABLE2]);
1633 static void state_colorwrite3(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1635 set_color_mask(context->gl_info, 3, state->render_states[WINED3D_RS_COLORWRITEENABLE3]);
1638 static void state_localviewer(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1640 const struct wined3d_gl_info *gl_info = context->gl_info;
1642 if (state->render_states[WINED3D_RS_LOCALVIEWER])
1644 gl_info->gl_ops.gl.p_glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
1645 checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1)");
1647 else
1649 gl_info->gl_ops.gl.p_glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0);
1650 checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0)");
1654 static void state_lastpixel(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1656 if (state->render_states[WINED3D_RS_LASTPIXEL])
1658 TRACE("Last Pixel Drawing Enabled\n");
1660 else
1662 static BOOL warned;
1663 if (!warned) {
1664 FIXME("Last Pixel Drawing Disabled, not handled yet\n");
1665 warned = TRUE;
1666 } else {
1667 TRACE("Last Pixel Drawing Disabled, not handled yet\n");
1672 void state_pointsprite_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1674 static BOOL warned;
1676 /* TODO: NV_POINT_SPRITE */
1677 if (!warned && state->render_states[WINED3D_RS_POINTSPRITEENABLE])
1679 /* A FIXME, not a WARN because point sprites should be software emulated if not supported by HW */
1680 FIXME("Point sprites not supported\n");
1681 warned = TRUE;
1685 void state_pointsprite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1687 const struct wined3d_gl_info *gl_info = context->gl_info;
1689 if (state->render_states[WINED3D_RS_POINTSPRITEENABLE])
1691 gl_info->gl_ops.gl.p_glEnable(GL_POINT_SPRITE_ARB);
1692 checkGLcall("glEnable(GL_POINT_SPRITE_ARB)");
1694 else
1696 gl_info->gl_ops.gl.p_glDisable(GL_POINT_SPRITE_ARB);
1697 checkGLcall("glDisable(GL_POINT_SPRITE_ARB)");
1701 static void state_wrap(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1703 if (state->render_states[WINED3D_RS_WRAP0]
1704 || state->render_states[WINED3D_RS_WRAP1]
1705 || state->render_states[WINED3D_RS_WRAP2]
1706 || state->render_states[WINED3D_RS_WRAP3]
1707 || state->render_states[WINED3D_RS_WRAP4]
1708 || state->render_states[WINED3D_RS_WRAP5]
1709 || state->render_states[WINED3D_RS_WRAP6]
1710 || state->render_states[WINED3D_RS_WRAP7]
1711 || state->render_states[WINED3D_RS_WRAP8]
1712 || state->render_states[WINED3D_RS_WRAP9]
1713 || state->render_states[WINED3D_RS_WRAP10]
1714 || state->render_states[WINED3D_RS_WRAP11]
1715 || state->render_states[WINED3D_RS_WRAP12]
1716 || state->render_states[WINED3D_RS_WRAP13]
1717 || state->render_states[WINED3D_RS_WRAP14]
1718 || state->render_states[WINED3D_RS_WRAP15])
1719 FIXME("(WINED3D_RS_WRAP0) Texture wrapping not yet supported.\n");
1722 static void state_msaa_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1724 if (state->render_states[WINED3D_RS_MULTISAMPLEANTIALIAS])
1725 WARN("Multisample antialiasing not supported by GL.\n");
1728 static void state_msaa(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1730 const struct wined3d_gl_info *gl_info = context->gl_info;
1732 if (state->render_states[WINED3D_RS_MULTISAMPLEANTIALIAS])
1734 gl_info->gl_ops.gl.p_glEnable(GL_MULTISAMPLE_ARB);
1735 checkGLcall("glEnable(GL_MULTISAMPLE_ARB)");
1737 else
1739 gl_info->gl_ops.gl.p_glDisable(GL_MULTISAMPLE_ARB);
1740 checkGLcall("glDisable(GL_MULTISAMPLE_ARB)");
1744 static void state_scissor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1746 const struct wined3d_gl_info *gl_info = context->gl_info;
1748 if (state->render_states[WINED3D_RS_SCISSORTESTENABLE])
1750 gl_info->gl_ops.gl.p_glEnable(GL_SCISSOR_TEST);
1751 checkGLcall("glEnable(GL_SCISSOR_TEST)");
1753 else
1755 gl_info->gl_ops.gl.p_glDisable(GL_SCISSOR_TEST);
1756 checkGLcall("glDisable(GL_SCISSOR_TEST)");
1760 /* The Direct3D depth bias is specified in normalized depth coordinates. In
1761 * OpenGL the bias is specified in units of "the smallest value that is
1762 * guaranteed to produce a resolvable offset for a given implementation". To
1763 * convert from D3D to GL we need to divide the D3D depth bias by that value.
1764 * There's no practical way to retrieve that value from a given GL
1765 * implementation, but the D3D application has essentially the same problem,
1766 * which makes a guess of the depth buffer format's highest possible value a
1767 * reasonable guess. Note that SLOPESCALEDEPTHBIAS is a scaling factor for the
1768 * depth slope, and doesn't need to be scaled. */
1769 static void state_depthbias(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1771 const struct wined3d_gl_info *gl_info = context->gl_info;
1773 if (state->render_states[WINED3D_RS_SLOPESCALEDEPTHBIAS]
1774 || state->render_states[WINED3D_RS_DEPTHBIAS])
1776 const struct wined3d_surface *depth = state->fb->depth_stencil;
1777 float scale;
1779 union
1781 DWORD d;
1782 float f;
1783 } scale_bias, const_bias;
1785 scale_bias.d = state->render_states[WINED3D_RS_SLOPESCALEDEPTHBIAS];
1786 const_bias.d = state->render_states[WINED3D_RS_DEPTHBIAS];
1788 gl_info->gl_ops.gl.p_glEnable(GL_POLYGON_OFFSET_FILL);
1789 checkGLcall("glEnable(GL_POLYGON_OFFSET_FILL)");
1791 if (context->swapchain->device->wined3d->flags & WINED3D_LEGACY_DEPTH_BIAS)
1793 float bias = -(float)const_bias.d;
1794 gl_info->gl_ops.gl.p_glPolygonOffset(bias, bias);
1795 checkGLcall("glPolygonOffset");
1797 else
1799 if (depth)
1801 const struct wined3d_format *fmt = depth->resource.format;
1802 scale = powf(2, fmt->depth_size) - 1;
1803 TRACE("Depth format %s, using depthbias scale of %.8e.\n",
1804 debug_d3dformat(fmt->id), scale);
1806 else
1808 /* The context manager will reapply this state on a depth stencil change */
1809 TRACE("No depth stencil, using depthbias scale of 0.0.\n");
1810 scale = 0.0f;
1813 gl_info->gl_ops.gl.p_glPolygonOffset(scale_bias.f, const_bias.f * scale);
1814 checkGLcall("glPolygonOffset(...)");
1817 else
1819 gl_info->gl_ops.gl.p_glDisable(GL_POLYGON_OFFSET_FILL);
1820 checkGLcall("glDisable(GL_POLYGON_OFFSET_FILL)");
1824 static void state_zvisible(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1826 if (state->render_states[WINED3D_RS_ZVISIBLE])
1827 FIXME("WINED3D_RS_ZVISIBLE not implemented.\n");
1830 static void state_perspective(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1832 const struct wined3d_gl_info *gl_info = context->gl_info;
1834 if (state->render_states[WINED3D_RS_TEXTUREPERSPECTIVE])
1836 gl_info->gl_ops.gl.p_glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1837 checkGLcall("glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)");
1839 else
1841 gl_info->gl_ops.gl.p_glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
1842 checkGLcall("glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST)");
1846 static void state_stippledalpha(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1848 if (state->render_states[WINED3D_RS_STIPPLEDALPHA])
1849 FIXME("Stippled Alpha not supported yet.\n");
1852 static void state_antialias(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1854 if (state->render_states[WINED3D_RS_ANTIALIAS])
1855 FIXME("Antialias not supported yet.\n");
1858 static void state_multisampmask(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1860 if (state->render_states[WINED3D_RS_MULTISAMPLEMASK] != 0xffffffff)
1861 FIXME("WINED3D_RS_MULTISAMPLEMASK %#x not yet implemented.\n",
1862 state->render_states[WINED3D_RS_MULTISAMPLEMASK]);
1865 static void state_patchedgestyle(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1867 if (state->render_states[WINED3D_RS_PATCHEDGESTYLE] != WINED3D_PATCH_EDGE_DISCRETE)
1868 FIXME("WINED3D_RS_PATCHEDGESTYLE %#x not yet implemented.\n",
1869 state->render_states[WINED3D_RS_PATCHEDGESTYLE]);
1872 static void state_patchsegments(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1874 union {
1875 DWORD d;
1876 float f;
1877 } tmpvalue;
1878 tmpvalue.f = 1.0f;
1880 if (state->render_states[WINED3D_RS_PATCHSEGMENTS] != tmpvalue.d)
1882 static BOOL displayed = FALSE;
1884 tmpvalue.d = state->render_states[WINED3D_RS_PATCHSEGMENTS];
1885 if(!displayed)
1886 FIXME("(WINED3D_RS_PATCHSEGMENTS,%f) not yet implemented\n", tmpvalue.f);
1888 displayed = TRUE;
1892 static void state_positiondegree(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1894 if (state->render_states[WINED3D_RS_POSITIONDEGREE] != WINED3D_DEGREE_CUBIC)
1895 FIXME("WINED3D_RS_POSITIONDEGREE %#x not yet implemented.\n",
1896 state->render_states[WINED3D_RS_POSITIONDEGREE]);
1899 static void state_normaldegree(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1901 if (state->render_states[WINED3D_RS_NORMALDEGREE] != WINED3D_DEGREE_LINEAR)
1902 FIXME("WINED3D_RS_NORMALDEGREE %#x not yet implemented.\n",
1903 state->render_states[WINED3D_RS_NORMALDEGREE]);
1906 static void state_tessellation(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1908 if (state->render_states[WINED3D_RS_ENABLEADAPTIVETESSELLATION])
1909 FIXME("WINED3D_RS_ENABLEADAPTIVETESSELLATION %#x not yet implemented.\n",
1910 state->render_states[WINED3D_RS_ENABLEADAPTIVETESSELLATION]);
1913 static void state_nvdb(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1915 union {
1916 DWORD d;
1917 float f;
1918 } zmin, zmax;
1920 const struct wined3d_gl_info *gl_info = context->gl_info;
1922 if (state->render_states[WINED3D_RS_ADAPTIVETESS_X] == WINED3DFMT_NVDB)
1924 zmin.d = state->render_states[WINED3D_RS_ADAPTIVETESS_Z];
1925 zmax.d = state->render_states[WINED3D_RS_ADAPTIVETESS_W];
1927 /* If zmin is larger than zmax INVALID_VALUE error is generated.
1928 * In d3d9 test is not performed in this case*/
1929 if (zmin.f <= zmax.f)
1931 gl_info->gl_ops.gl.p_glEnable(GL_DEPTH_BOUNDS_TEST_EXT);
1932 checkGLcall("glEnable(GL_DEPTH_BOUNDS_TEST_EXT)");
1933 GL_EXTCALL(glDepthBoundsEXT(zmin.f, zmax.f));
1934 checkGLcall("glDepthBoundsEXT(...)");
1936 else
1938 gl_info->gl_ops.gl.p_glDisable(GL_DEPTH_BOUNDS_TEST_EXT);
1939 checkGLcall("glDisable(GL_DEPTH_BOUNDS_TEST_EXT)");
1942 else
1944 gl_info->gl_ops.gl.p_glDisable(GL_DEPTH_BOUNDS_TEST_EXT);
1945 checkGLcall("glDisable(GL_DEPTH_BOUNDS_TEST_EXT)");
1948 state_tessellation(context, state, STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION));
1951 static void state_wrapu(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1953 if (state->render_states[WINED3D_RS_WRAPU])
1954 FIXME("Render state WINED3D_RS_WRAPU not implemented yet.\n");
1957 static void state_wrapv(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1959 if (state->render_states[WINED3D_RS_WRAPV])
1960 FIXME("Render state WINED3D_RS_WRAPV not implemented yet.\n");
1963 static void state_monoenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1965 if (state->render_states[WINED3D_RS_MONOENABLE])
1966 FIXME("Render state WINED3D_RS_MONOENABLE not implemented yet.\n");
1969 static void state_rop2(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1971 if (state->render_states[WINED3D_RS_ROP2])
1972 FIXME("Render state WINED3D_RS_ROP2 not implemented yet.\n");
1975 static void state_planemask(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1977 if (state->render_states[WINED3D_RS_PLANEMASK])
1978 FIXME("Render state WINED3D_RS_PLANEMASK not implemented yet.\n");
1981 static void state_subpixel(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1983 if (state->render_states[WINED3D_RS_SUBPIXEL])
1984 FIXME("Render state WINED3D_RS_SUBPIXEL not implemented yet.\n");
1987 static void state_subpixelx(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1989 if (state->render_states[WINED3D_RS_SUBPIXELX])
1990 FIXME("Render state WINED3D_RS_SUBPIXELX not implemented yet.\n");
1993 static void state_stippleenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1995 if (state->render_states[WINED3D_RS_STIPPLEENABLE])
1996 FIXME("Render state WINED3D_RS_STIPPLEENABLE not implemented yet.\n");
1999 static void state_mipmaplodbias(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
2001 if (state->render_states[WINED3D_RS_MIPMAPLODBIAS])
2002 FIXME("Render state WINED3D_RS_MIPMAPLODBIAS not implemented yet.\n");
2005 static void state_anisotropy(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
2007 if (state->render_states[WINED3D_RS_ANISOTROPY])
2008 FIXME("Render state WINED3D_RS_ANISOTROPY not implemented yet.\n");
2011 static void state_flushbatch(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
2013 if (state->render_states[WINED3D_RS_FLUSHBATCH])
2014 FIXME("Render state WINED3D_RS_FLUSHBATCH not implemented yet.\n");
2017 static void state_translucentsi(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
2019 if (state->render_states[WINED3D_RS_TRANSLUCENTSORTINDEPENDENT])
2020 FIXME("Render state WINED3D_RS_TRANSLUCENTSORTINDEPENDENT not implemented yet.\n");
2023 static void state_extents(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
2025 if (state->render_states[WINED3D_RS_EXTENTS])
2026 FIXME("Render state WINED3D_RS_EXTENTS not implemented yet.\n");
2029 static void state_ckeyblend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
2031 if (state->render_states[WINED3D_RS_COLORKEYBLENDENABLE])
2032 FIXME("Render state WINED3D_RS_COLORKEYBLENDENABLE not implemented yet.\n");
2035 static void state_swvp(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
2037 if (state->render_states[WINED3D_RS_SOFTWAREVERTEXPROCESSING])
2038 FIXME("Software vertex processing not implemented.\n");
2041 static void get_src_and_opr(DWORD arg, BOOL is_alpha, GLenum* source, GLenum* operand) {
2042 /* The WINED3DTA_ALPHAREPLICATE flag specifies the alpha component of the
2043 * input should be used for all input components. The WINED3DTA_COMPLEMENT
2044 * flag specifies the complement of the input should be used. */
2045 BOOL from_alpha = is_alpha || arg & WINED3DTA_ALPHAREPLICATE;
2046 BOOL complement = arg & WINED3DTA_COMPLEMENT;
2048 /* Calculate the operand */
2049 if (complement) {
2050 if (from_alpha) *operand = GL_ONE_MINUS_SRC_ALPHA;
2051 else *operand = GL_ONE_MINUS_SRC_COLOR;
2052 } else {
2053 if (from_alpha) *operand = GL_SRC_ALPHA;
2054 else *operand = GL_SRC_COLOR;
2057 /* Calculate the source */
2058 switch (arg & WINED3DTA_SELECTMASK) {
2059 case WINED3DTA_CURRENT: *source = GL_PREVIOUS_EXT; break;
2060 case WINED3DTA_DIFFUSE: *source = GL_PRIMARY_COLOR_EXT; break;
2061 case WINED3DTA_TEXTURE: *source = GL_TEXTURE; break;
2062 case WINED3DTA_TFACTOR: *source = GL_CONSTANT_EXT; break;
2063 case WINED3DTA_SPECULAR:
2065 * According to the GL_ARB_texture_env_combine specs, SPECULAR is
2066 * 'Secondary color' and isn't supported until base GL supports it
2067 * There is no concept of temp registers as far as I can tell
2069 FIXME("Unhandled texture arg WINED3DTA_SPECULAR\n");
2070 *source = GL_TEXTURE;
2071 break;
2072 default:
2073 FIXME("Unrecognized texture arg %#x\n", arg);
2074 *source = GL_TEXTURE;
2075 break;
2079 /* Setup the texture operations texture stage states */
2080 static void set_tex_op(const struct wined3d_gl_info *gl_info, const struct wined3d_state *state,
2081 BOOL isAlpha, int Stage, enum wined3d_texture_op op, DWORD arg1, DWORD arg2, DWORD arg3)
2083 GLenum src1, src2, src3;
2084 GLenum opr1, opr2, opr3;
2085 GLenum comb_target;
2086 GLenum src0_target, src1_target, src2_target;
2087 GLenum opr0_target, opr1_target, opr2_target;
2088 GLenum scal_target;
2089 GLenum opr=0, invopr, src3_target, opr3_target;
2090 BOOL Handled = FALSE;
2092 TRACE("Alpha?(%d), Stage:%d Op(%s), a1(%d), a2(%d), a3(%d)\n", isAlpha, Stage, debug_d3dtop(op), arg1, arg2, arg3);
2094 /* This is called by a state handler which has the gl lock held and a context for the thread */
2096 /* Note: Operations usually involve two ars, src0 and src1 and are operations of
2097 the form (a1 <operation> a2). However, some of the more complex operations
2098 take 3 parameters. Instead of the (sensible) addition of a3, Microsoft added
2099 in a third parameter called a0. Therefore these are operations of the form
2100 a0 <operation> a1 <operation> a2, i.e., the new parameter goes to the front.
2102 However, below we treat the new (a0) parameter as src2/opr2, so in the actual
2103 functions below, expect their syntax to differ slightly to those listed in the
2104 manuals, i.e., replace arg1 with arg3, arg2 with arg1 and arg3 with arg2
2105 This affects WINED3DTOP_MULTIPLYADD and WINED3DTOP_LERP */
2107 if (isAlpha)
2109 comb_target = GL_COMBINE_ALPHA;
2110 src0_target = GL_SOURCE0_ALPHA;
2111 src1_target = GL_SOURCE1_ALPHA;
2112 src2_target = GL_SOURCE2_ALPHA;
2113 opr0_target = GL_OPERAND0_ALPHA;
2114 opr1_target = GL_OPERAND1_ALPHA;
2115 opr2_target = GL_OPERAND2_ALPHA;
2116 scal_target = GL_ALPHA_SCALE;
2118 else
2120 comb_target = GL_COMBINE_RGB;
2121 src0_target = GL_SOURCE0_RGB;
2122 src1_target = GL_SOURCE1_RGB;
2123 src2_target = GL_SOURCE2_RGB;
2124 opr0_target = GL_OPERAND0_RGB;
2125 opr1_target = GL_OPERAND1_RGB;
2126 opr2_target = GL_OPERAND2_RGB;
2127 scal_target = GL_RGB_SCALE;
2130 /* If a texture stage references an invalid texture unit the stage just
2131 * passes through the result from the previous stage */
2132 if (is_invalid_op(state, Stage, op, arg1, arg2, arg3))
2134 arg1 = WINED3DTA_CURRENT;
2135 op = WINED3D_TOP_SELECT_ARG1;
2138 if (isAlpha && !state->textures[Stage] && arg1 == WINED3DTA_TEXTURE)
2140 get_src_and_opr(WINED3DTA_DIFFUSE, isAlpha, &src1, &opr1);
2141 } else {
2142 get_src_and_opr(arg1, isAlpha, &src1, &opr1);
2144 get_src_and_opr(arg2, isAlpha, &src2, &opr2);
2145 get_src_and_opr(arg3, isAlpha, &src3, &opr3);
2147 TRACE("ct(%x), 1:(%x,%x), 2:(%x,%x), 3:(%x,%x)\n", comb_target, src1, opr1, src2, opr2, src3, opr3);
2149 Handled = TRUE; /* Assume will be handled */
2151 /* Other texture operations require special extensions: */
2152 if (gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
2154 if (isAlpha) {
2155 opr = GL_SRC_ALPHA;
2156 invopr = GL_ONE_MINUS_SRC_ALPHA;
2157 src3_target = GL_SOURCE3_ALPHA_NV;
2158 opr3_target = GL_OPERAND3_ALPHA_NV;
2159 } else {
2160 opr = GL_SRC_COLOR;
2161 invopr = GL_ONE_MINUS_SRC_COLOR;
2162 src3_target = GL_SOURCE3_RGB_NV;
2163 opr3_target = GL_OPERAND3_RGB_NV;
2165 switch (op)
2167 case WINED3D_TOP_DISABLE: /* Only for alpha */
2168 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2169 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2170 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
2171 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2172 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
2173 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2174 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2175 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2176 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2177 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2178 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2179 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
2180 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2181 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2182 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2183 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2184 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2185 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2186 break;
2188 case WINED3D_TOP_SELECT_ARG1: /* = a1 * 1 + 0 * 0 */
2189 case WINED3D_TOP_SELECT_ARG2: /* = a2 * 1 + 0 * 0 */
2190 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2191 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2192 if (op == WINED3D_TOP_SELECT_ARG1)
2194 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2195 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2196 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2197 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2199 else
2201 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
2202 checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
2203 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
2204 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
2206 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2207 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2208 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2209 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2210 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2211 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
2212 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2213 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2214 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2215 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2216 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2217 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2218 break;
2220 case WINED3D_TOP_MODULATE:
2221 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2222 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2223 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2224 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2225 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2226 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2227 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2228 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2229 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2230 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2231 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2232 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2233 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2234 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2235 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2236 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2237 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2238 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
2239 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2240 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2241 break;
2242 case WINED3D_TOP_MODULATE_2X:
2243 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2244 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2245 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2246 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2247 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2248 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2249 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2250 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2251 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2252 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2253 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2254 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2255 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2256 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2257 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2258 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2259 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2260 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
2261 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2262 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2263 break;
2264 case WINED3D_TOP_MODULATE_4X:
2265 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2266 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2267 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2268 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2269 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2270 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2271 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2272 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2273 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2274 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2275 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2276 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2277 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2278 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2279 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2280 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2281 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2282 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
2283 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
2284 checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
2285 break;
2287 case WINED3D_TOP_ADD:
2288 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2289 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2290 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2291 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2292 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2293 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2294 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2295 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2296 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2297 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2298 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2299 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2300 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2301 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2302 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2303 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2304 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2305 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2306 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2307 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2308 break;
2310 case WINED3D_TOP_ADD_SIGNED:
2311 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED);
2312 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED");
2313 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2314 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2315 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2316 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2317 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2318 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2319 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2320 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2321 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2322 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2323 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2324 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2325 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2326 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2327 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2328 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2329 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2330 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2331 break;
2333 case WINED3D_TOP_ADD_SIGNED_2X:
2334 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED);
2335 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED");
2336 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2337 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2338 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2339 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2340 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2341 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2342 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2343 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2344 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2345 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2346 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2347 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2348 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2349 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2350 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2351 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2352 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2353 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2354 break;
2356 case WINED3D_TOP_ADD_SMOOTH:
2357 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2358 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2359 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2360 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2361 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2362 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2363 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2364 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2365 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2366 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2367 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2368 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2369 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2370 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2371 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
2372 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
2373 switch (opr1) {
2374 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2375 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2376 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2377 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2379 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2380 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2381 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2382 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2383 break;
2385 case WINED3D_TOP_BLEND_DIFFUSE_ALPHA:
2386 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2387 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2388 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2389 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2390 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2391 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2392 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_PRIMARY_COLOR);
2393 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_PRIMARY_COLOR");
2394 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2395 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2396 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2397 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2398 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2399 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2400 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_PRIMARY_COLOR);
2401 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_PRIMARY_COLOR");
2402 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2403 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2404 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2405 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2406 break;
2407 case WINED3D_TOP_BLEND_TEXTURE_ALPHA:
2408 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2409 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2410 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2411 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2412 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2413 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2414 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_TEXTURE);
2415 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_TEXTURE");
2416 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2417 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2418 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2419 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2420 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2421 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2422 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
2423 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
2424 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2425 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2426 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2427 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2428 break;
2429 case WINED3D_TOP_BLEND_FACTOR_ALPHA:
2430 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2431 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2432 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2433 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2434 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2435 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2436 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_CONSTANT);
2437 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_CONSTANT");
2438 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2439 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2440 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2441 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2442 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2443 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2444 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_CONSTANT);
2445 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_CONSTANT");
2446 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2447 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2448 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2449 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2450 break;
2451 case WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM:
2452 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2453 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2454 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2455 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2456 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2457 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2458 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2459 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2460 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2461 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2462 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2463 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2464 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2465 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2466 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
2467 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
2468 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2469 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2470 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2471 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2472 break;
2473 case WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR:
2474 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2475 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2476 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); /* a0 = src1/opr1 */
2477 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2478 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2479 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); /* a1 = 1 (see docs) */
2480 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2481 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2482 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2483 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2484 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); /* a2 = arg2 */
2485 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2486 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2487 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); /* a3 = src1 alpha */
2488 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
2489 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
2490 switch (opr) {
2491 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2492 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2494 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2495 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2496 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2497 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2498 break;
2499 case WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA:
2500 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2501 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2502 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2503 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2504 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2505 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2506 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2507 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2508 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2509 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2510 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
2511 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
2512 switch (opr1) {
2513 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2514 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2516 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2517 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2518 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2519 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2520 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2521 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2522 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2523 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2524 break;
2525 case WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR:
2526 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2527 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2528 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2529 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2530 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2531 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2532 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2533 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2534 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2535 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2536 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2537 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2538 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2539 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2540 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
2541 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
2542 switch (opr1) {
2543 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2544 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2545 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2546 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2548 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2549 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2550 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2551 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2552 break;
2553 case WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA:
2554 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2555 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2556 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2557 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2558 switch (opr1) {
2559 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2560 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2561 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2562 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2564 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2565 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2566 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2567 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2568 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2569 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2570 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
2571 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
2572 switch (opr1) {
2573 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2574 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2576 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2577 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2578 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2579 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2580 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2581 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2582 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2583 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2584 break;
2585 case WINED3D_TOP_MULTIPLY_ADD:
2586 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2587 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2588 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
2589 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2590 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
2591 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2592 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2593 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2594 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2595 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2596 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
2597 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2598 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr1);
2599 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2600 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, src2);
2601 checkGLcall("GL_TEXTURE_ENV, src3_target, src3");
2602 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr2);
2603 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr3");
2604 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2605 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2606 break;
2608 case WINED3D_TOP_BUMPENVMAP:
2609 case WINED3D_TOP_BUMPENVMAP_LUMINANCE:
2610 FIXME("Implement bump environment mapping in GL_NV_texture_env_combine4 path\n");
2611 Handled = FALSE;
2612 break;
2614 default:
2615 Handled = FALSE;
2617 if (Handled)
2619 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
2620 checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV");
2622 return;
2624 } /* GL_NV_texture_env_combine4 */
2626 Handled = TRUE; /* Again, assume handled */
2627 switch (op) {
2628 case WINED3D_TOP_DISABLE: /* Only for alpha */
2629 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
2630 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2631 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
2632 checkGLcall("GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT");
2633 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
2634 checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA");
2635 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2636 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2637 break;
2638 case WINED3D_TOP_SELECT_ARG1:
2639 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
2640 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2641 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2642 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2643 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2644 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2645 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2646 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2647 break;
2648 case WINED3D_TOP_SELECT_ARG2:
2649 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
2650 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2651 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
2652 checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
2653 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
2654 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
2655 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2656 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2657 break;
2658 case WINED3D_TOP_MODULATE:
2659 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2660 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2661 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2662 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2663 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2664 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2665 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2666 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2667 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2668 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2669 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2670 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2671 break;
2672 case WINED3D_TOP_MODULATE_2X:
2673 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2674 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2675 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2676 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2677 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2678 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2679 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2680 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2681 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2682 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2683 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2684 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2685 break;
2686 case WINED3D_TOP_MODULATE_4X:
2687 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2688 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2689 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2690 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2691 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2692 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2693 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2694 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2695 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2696 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2697 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
2698 checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
2699 break;
2700 case WINED3D_TOP_ADD:
2701 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2702 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2703 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2704 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2705 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2706 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2707 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2708 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2709 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2710 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2711 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2712 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2713 break;
2714 case WINED3D_TOP_ADD_SIGNED:
2715 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED);
2716 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED");
2717 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2718 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2719 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2720 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2721 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2722 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2723 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2724 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2725 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2726 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2727 break;
2728 case WINED3D_TOP_ADD_SIGNED_2X:
2729 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED);
2730 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED");
2731 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2732 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2733 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2734 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2735 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2736 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2737 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2738 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2739 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2740 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2741 break;
2742 case WINED3D_TOP_SUBTRACT:
2743 if (gl_info->supported[ARB_TEXTURE_ENV_COMBINE])
2745 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_SUBTRACT);
2746 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_SUBTRACT");
2747 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2748 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2749 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2750 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2751 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2752 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2753 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2754 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2755 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2756 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2757 } else {
2758 FIXME("This version of opengl does not support GL_SUBTRACT\n");
2760 break;
2762 case WINED3D_TOP_BLEND_DIFFUSE_ALPHA:
2763 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
2764 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
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, src2_target, GL_PRIMARY_COLOR);
2774 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PRIMARY_COLOR");
2775 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2776 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2777 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2778 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2779 break;
2780 case WINED3D_TOP_BLEND_TEXTURE_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_TEXTURE);
2792 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_TEXTURE");
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_FACTOR_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_CONSTANT);
2810 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_CONSTANT");
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_CURRENT_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_PREVIOUS);
2828 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PREVIOUS");
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_DOTPRODUCT3:
2835 if (gl_info->supported[ARB_TEXTURE_ENV_DOT3])
2837 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB);
2838 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB");
2840 else if (gl_info->supported[EXT_TEXTURE_ENV_DOT3])
2842 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT);
2843 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT");
2844 } else {
2845 FIXME("This version of opengl does not support GL_DOT3\n");
2847 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2848 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2849 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2850 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2851 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2852 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2853 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2854 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2855 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2856 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2857 break;
2858 case WINED3D_TOP_LERP:
2859 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
2860 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
2861 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2862 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2863 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2864 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2865 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2866 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2867 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2868 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2869 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src3);
2870 checkGLcall("GL_TEXTURE_ENV, src2_target, src3");
2871 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr3);
2872 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr3");
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_ADD_SMOOTH:
2877 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2879 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2880 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2881 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2882 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2883 switch (opr1) {
2884 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2885 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2886 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2887 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2889 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2890 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2891 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2892 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2893 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2894 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2895 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2896 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2897 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2898 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2899 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2900 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2901 } else
2902 Handled = FALSE;
2903 break;
2904 case WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM:
2905 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2907 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2908 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2909 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_TEXTURE);
2910 checkGLcall("GL_TEXTURE_ENV, src0_target, GL_TEXTURE");
2911 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_ALPHA);
2912 checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_APHA");
2913 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2914 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2915 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2916 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2917 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2918 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2919 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2920 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2921 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2922 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2923 } else
2924 Handled = FALSE;
2925 break;
2926 case WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR:
2927 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2929 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2930 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2931 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2932 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2933 switch (opr1) {
2934 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2935 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2936 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2937 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2939 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2940 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2941 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2942 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2943 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2944 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2945 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2946 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2947 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2948 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2949 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2950 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2951 } else
2952 Handled = FALSE;
2953 break;
2954 case WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA:
2955 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2957 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2958 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2959 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2960 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2961 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2962 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2963 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2964 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2965 switch (opr1) {
2966 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2967 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2968 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2969 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2971 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
2972 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
2973 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2974 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2975 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2976 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2977 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2978 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2979 } else
2980 Handled = FALSE;
2981 break;
2982 case WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR:
2983 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2985 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2986 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2987 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2988 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2989 switch (opr1) {
2990 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2991 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2992 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2993 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2995 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2996 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2997 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2998 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2999 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
3000 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
3001 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
3002 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
3003 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
3004 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
3005 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
3006 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
3007 } else
3008 Handled = FALSE;
3009 break;
3010 case WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA:
3011 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
3013 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
3014 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
3015 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
3016 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
3017 switch (opr1) {
3018 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
3019 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
3020 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
3021 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
3023 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
3024 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
3025 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
3026 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
3027 switch (opr1) {
3028 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
3029 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
3030 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
3031 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
3033 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
3034 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
3035 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
3036 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
3037 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
3038 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
3039 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
3040 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
3041 } else
3042 Handled = FALSE;
3043 break;
3044 case WINED3D_TOP_MULTIPLY_ADD:
3045 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
3047 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
3048 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
3049 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
3050 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
3051 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
3052 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
3053 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src3);
3054 checkGLcall("GL_TEXTURE_ENV, src1_target, src3");
3055 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr3);
3056 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr3");
3057 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
3058 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
3059 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
3060 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
3061 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
3062 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
3063 } else
3064 Handled = FALSE;
3065 break;
3066 case WINED3D_TOP_BUMPENVMAP_LUMINANCE:
3067 case WINED3D_TOP_BUMPENVMAP:
3068 if (gl_info->supported[NV_TEXTURE_SHADER2])
3070 /* Technically texture shader support without register combiners is possible, but not expected to occur
3071 * on real world cards, so for now a fixme should be enough
3073 FIXME("Implement bump mapping with GL_NV_texture_shader in non register combiner path\n");
3075 Handled = FALSE;
3076 break;
3078 default:
3079 Handled = FALSE;
3082 if (Handled) {
3083 BOOL combineOK = TRUE;
3084 if (gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
3086 DWORD op2;
3088 if (isAlpha)
3089 op2 = state->texture_states[Stage][WINED3D_TSS_COLOR_OP];
3090 else
3091 op2 = state->texture_states[Stage][WINED3D_TSS_ALPHA_OP];
3093 /* Note: If COMBINE4 in effect can't go back to combine! */
3094 switch (op2)
3096 case WINED3D_TOP_ADD_SMOOTH:
3097 case WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM:
3098 case WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR:
3099 case WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA:
3100 case WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR:
3101 case WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA:
3102 case WINED3D_TOP_MULTIPLY_ADD:
3103 /* Ignore those implemented in both cases */
3104 switch (op)
3106 case WINED3D_TOP_SELECT_ARG1:
3107 case WINED3D_TOP_SELECT_ARG2:
3108 combineOK = FALSE;
3109 Handled = FALSE;
3110 break;
3111 default:
3112 FIXME("Can't use COMBINE4 and COMBINE together, thisop=%s, otherop=%s, isAlpha(%d)\n", debug_d3dtop(op), debug_d3dtop(op2), isAlpha);
3113 return;
3118 if (combineOK)
3120 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
3121 checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE");
3123 return;
3127 /* After all the extensions, if still unhandled, report fixme */
3128 FIXME("Unhandled texture operation %s\n", debug_d3dtop(op));
3132 static void tex_colorop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3134 DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3135 const struct wined3d_device *device = context->swapchain->device;
3136 BOOL tex_used = device->fixed_function_usage_map & (1 << stage);
3137 DWORD mapped_stage = device->texUnitMap[stage];
3138 const struct wined3d_gl_info *gl_info = context->gl_info;
3140 TRACE("Setting color op for stage %d\n", stage);
3142 /* Using a pixel shader? Don't care for anything here, the shader applying does it */
3143 if (use_ps(state)) return;
3145 if (stage != mapped_stage) WARN("Using non 1:1 mapping: %d -> %d!\n", stage, mapped_stage);
3147 if (mapped_stage != WINED3D_UNMAPPED_STAGE)
3149 if (tex_used && mapped_stage >= gl_info->limits.textures)
3151 FIXME("Attempt to enable unsupported stage!\n");
3152 return;
3154 context_active_texture(context, gl_info, mapped_stage);
3157 if (stage >= state->lowest_disabled_stage)
3159 TRACE("Stage disabled\n");
3160 if (mapped_stage != WINED3D_UNMAPPED_STAGE)
3162 /* Disable everything here */
3163 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
3164 checkGLcall("glDisable(GL_TEXTURE_2D)");
3165 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
3166 checkGLcall("glDisable(GL_TEXTURE_3D)");
3167 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3169 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3170 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3172 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3174 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
3175 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3178 /* All done */
3179 return;
3182 /* The sampler will also activate the correct texture dimensions, so no
3183 * need to do it here if the sampler for this stage is dirty. */
3184 if (!isStateDirty(context, STATE_SAMPLER(stage)) && tex_used)
3185 texture_activate_dimensions(state->textures[stage], gl_info);
3187 set_tex_op(gl_info, state, FALSE, stage,
3188 state->texture_states[stage][WINED3D_TSS_COLOR_OP],
3189 state->texture_states[stage][WINED3D_TSS_COLOR_ARG1],
3190 state->texture_states[stage][WINED3D_TSS_COLOR_ARG2],
3191 state->texture_states[stage][WINED3D_TSS_COLOR_ARG0]);
3194 void tex_alphaop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3196 DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3197 const struct wined3d_device *device = context->swapchain->device;
3198 BOOL tex_used = device->fixed_function_usage_map & (1 << stage);
3199 DWORD mapped_stage = device->texUnitMap[stage];
3200 const struct wined3d_gl_info *gl_info = context->gl_info;
3201 DWORD op, arg1, arg2, arg0;
3203 TRACE("Setting alpha op for stage %d\n", stage);
3204 /* Do not care for enabled / disabled stages, just assign the settings. colorop disables / enables required stuff */
3205 if (mapped_stage != WINED3D_UNMAPPED_STAGE)
3207 if (tex_used && mapped_stage >= gl_info->limits.textures)
3209 FIXME("Attempt to enable unsupported stage!\n");
3210 return;
3212 context_active_texture(context, gl_info, mapped_stage);
3215 op = state->texture_states[stage][WINED3D_TSS_ALPHA_OP];
3216 arg1 = state->texture_states[stage][WINED3D_TSS_ALPHA_ARG1];
3217 arg2 = state->texture_states[stage][WINED3D_TSS_ALPHA_ARG2];
3218 arg0 = state->texture_states[stage][WINED3D_TSS_ALPHA_ARG0];
3220 if (state->render_states[WINED3D_RS_COLORKEYENABLE] && !stage && state->textures[0])
3222 struct wined3d_texture *texture = state->textures[0];
3223 GLenum texture_dimensions = texture->target;
3225 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
3227 struct wined3d_surface *surf = surface_from_resource(texture->sub_resources[0]);
3229 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format->alpha_size)
3231 /* Color keying needs to pass alpha values from the texture through to have the alpha test work
3232 * properly. On the other hand applications can still use texture combiners apparently. This code
3233 * takes care that apps cannot remove the texture's alpha channel entirely.
3235 * The fixup is required for Prince of Persia 3D(prison bars), while Moto racer 2 requires
3236 * D3DTOP_MODULATE to work on color keyed surfaces. Aliens vs Predator 1 uses color keyed textures
3237 * and alpha component of diffuse color to draw things like translucent text and perform other
3238 * blending effects.
3240 * Aliens vs Predator 1 relies on diffuse alpha having an effect, so it cannot be ignored. To
3241 * provide the behavior expected by the game, while emulating the colorkey, diffuse alpha must be
3242 * modulated with texture alpha. OTOH, Moto racer 2 at some points sets alphaop/alphaarg to
3243 * SELECTARG/CURRENT, yet puts garbage in diffuse alpha (zeroes). This works on native, because the
3244 * game disables alpha test and alpha blending. Alpha test is overwritten by wine's for purposes of
3245 * color-keying though, so this will lead to missing geometry if texture alpha is modulated (pixels
3246 * fail alpha test). To get around this, ALPHABLENDENABLE state is checked: if the app enables alpha
3247 * blending, it can be expected to provide meaningful values in diffuse alpha, so it should be
3248 * modulated with texture alpha; otherwise, selecting diffuse alpha is ignored in favour of texture
3249 * alpha.
3251 * What to do with multitexturing? So far no app has been found that uses color keying with
3252 * multitexturing */
3253 if (op == WINED3D_TOP_DISABLE)
3255 arg1 = WINED3DTA_TEXTURE;
3256 op = WINED3D_TOP_SELECT_ARG1;
3258 else if (op == WINED3D_TOP_SELECT_ARG1 && arg1 != WINED3DTA_TEXTURE)
3260 if (state->render_states[WINED3D_RS_ALPHABLENDENABLE])
3262 arg2 = WINED3DTA_TEXTURE;
3263 op = WINED3D_TOP_MODULATE;
3265 else arg1 = WINED3DTA_TEXTURE;
3267 else if (op == WINED3D_TOP_SELECT_ARG2 && arg2 != WINED3DTA_TEXTURE)
3269 if (state->render_states[WINED3D_RS_ALPHABLENDENABLE])
3271 arg1 = WINED3DTA_TEXTURE;
3272 op = WINED3D_TOP_MODULATE;
3274 else arg2 = WINED3DTA_TEXTURE;
3280 /* tex_alphaop is shared between the ffp and nvrc because the difference only comes down to
3281 * this if block here, and the other code(color keying, texture unit selection) are the same
3283 TRACE("Setting alpha op for stage %d\n", stage);
3284 if (gl_info->supported[NV_REGISTER_COMBINERS])
3286 set_tex_op_nvrc(gl_info, state, TRUE, stage, op, arg1, arg2, arg0,
3287 mapped_stage, state->texture_states[stage][WINED3D_TSS_RESULT_ARG]);
3289 else
3291 set_tex_op(gl_info, state, TRUE, stage, op, arg1, arg2, arg0);
3295 void transform_texture(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3297 DWORD texUnit = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3298 const struct wined3d_device *device = context->swapchain->device;
3299 const struct wined3d_gl_info *gl_info = context->gl_info;
3300 DWORD mapped_stage = device->texUnitMap[texUnit];
3301 BOOL generated;
3302 int coordIdx;
3304 /* Ignore this when a vertex shader is used, or if the streams aren't sorted out yet */
3305 if (use_vs(state) || isStateDirty(context, STATE_VDECL))
3307 TRACE("Using a vertex shader, or stream sources not sorted out yet, skipping\n");
3308 return;
3311 if (mapped_stage == WINED3D_UNMAPPED_STAGE) return;
3312 if (mapped_stage >= gl_info->limits.textures) return;
3314 context_active_texture(context, gl_info, mapped_stage);
3315 generated = (state->texture_states[texUnit][WINED3D_TSS_TEXCOORD_INDEX] & 0xffff0000) != WINED3DTSS_TCI_PASSTHRU;
3316 coordIdx = min(state->texture_states[texUnit][WINED3D_TSS_TEXCOORD_INDEX & 0x0000ffff], MAX_TEXTURES - 1);
3318 set_texture_matrix(gl_info, &state->transforms[WINED3D_TS_TEXTURE0 + texUnit].u.m[0][0],
3319 state->texture_states[texUnit][WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS],
3320 generated, context->last_was_rhw,
3321 device->stream_info.use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coordIdx))
3322 ? device->stream_info.elements[WINED3D_FFP_TEXCOORD0 + coordIdx].format->id
3323 : WINED3DFMT_UNKNOWN,
3324 device->shader_backend->shader_has_ffp_proj_control(device->shader_priv));
3326 /* The sampler applying function calls us if this changes */
3327 if ((context->lastWasPow2Texture & (1 << texUnit)) && state->textures[texUnit])
3329 if(generated) {
3330 FIXME("Non-power2 texture being used with generated texture coords\n");
3332 /* NP2 texcoord fixup is implemented for pixelshaders so only enable the
3333 fixed-function-pipeline fixup via pow2Matrix when no PS is used. */
3334 if (!use_ps(state))
3336 TRACE("Non power two matrix multiply fixup\n");
3337 gl_info->gl_ops.gl.p_glMultMatrixf(state->textures[texUnit]->pow2_matrix);
3342 static void unload_tex_coords(const struct wined3d_gl_info *gl_info)
3344 unsigned int texture_idx;
3346 for (texture_idx = 0; texture_idx < gl_info->limits.texture_coords; ++texture_idx)
3348 GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + texture_idx));
3349 gl_info->gl_ops.gl.p_glDisableClientState(GL_TEXTURE_COORD_ARRAY);
3353 static void load_tex_coords(const struct wined3d_context *context, const struct wined3d_stream_info *si,
3354 GLuint *curVBO, const struct wined3d_state *state)
3356 const struct wined3d_device *device = context->swapchain->device;
3357 const struct wined3d_gl_info *gl_info = context->gl_info;
3358 unsigned int mapped_stage = 0;
3359 unsigned int textureNo = 0;
3361 for (textureNo = 0; textureNo < context->d3d_info->limits.ffp_blend_stages; ++textureNo)
3363 int coordIdx = state->texture_states[textureNo][WINED3D_TSS_TEXCOORD_INDEX];
3365 mapped_stage = device->texUnitMap[textureNo];
3366 if (mapped_stage == WINED3D_UNMAPPED_STAGE) continue;
3368 if (mapped_stage >= gl_info->limits.texture_coords)
3370 FIXME("Attempted to load unsupported texture coordinate %u\n", mapped_stage);
3371 continue;
3374 if (coordIdx < MAX_TEXTURES && (si->use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coordIdx))))
3376 const struct wined3d_stream_info_element *e = &si->elements[WINED3D_FFP_TEXCOORD0 + coordIdx];
3378 TRACE("Setting up texture %u, idx %d, coordindx %u, data {%#x:%p}.\n",
3379 textureNo, mapped_stage, coordIdx, e->data.buffer_object, e->data.addr);
3381 if (*curVBO != e->data.buffer_object)
3383 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
3384 checkGLcall("glBindBufferARB");
3385 *curVBO = e->data.buffer_object;
3388 GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
3389 checkGLcall("glClientActiveTextureARB");
3391 /* The coords to supply depend completely on the fvf / vertex shader */
3392 gl_info->gl_ops.gl.p_glTexCoordPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
3393 e->data.addr + state->load_base_vertex_index * e->stride);
3394 gl_info->gl_ops.gl.p_glEnableClientState(GL_TEXTURE_COORD_ARRAY);
3396 else
3398 GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + mapped_stage, 0, 0, 0, 1));
3401 if (gl_info->supported[NV_REGISTER_COMBINERS])
3403 /* The number of the mapped stages increases monotonically, so it's fine to use the last used one. */
3404 for (textureNo = mapped_stage + 1; textureNo < gl_info->limits.textures; ++textureNo)
3406 GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, 0, 0, 0, 1));
3410 checkGLcall("loadTexCoords");
3413 static void tex_coordindex(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3415 DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3416 const struct wined3d_device *device = context->swapchain->device;
3417 static const GLfloat s_plane[] = { 1.0f, 0.0f, 0.0f, 0.0f };
3418 static const GLfloat t_plane[] = { 0.0f, 1.0f, 0.0f, 0.0f };
3419 static const GLfloat r_plane[] = { 0.0f, 0.0f, 1.0f, 0.0f };
3420 static const GLfloat q_plane[] = { 0.0f, 0.0f, 0.0f, 1.0f };
3421 const struct wined3d_gl_info *gl_info = context->gl_info;
3422 DWORD mapped_stage = device->texUnitMap[stage];
3424 if (mapped_stage == WINED3D_UNMAPPED_STAGE)
3426 TRACE("No texture unit mapped to stage %d. Skipping texture coordinates.\n", stage);
3427 return;
3430 if (mapped_stage >= gl_info->limits.fragment_samplers)
3432 WARN("stage %u not mapped to a valid texture unit (%u)\n", stage, mapped_stage);
3433 return;
3435 context_active_texture(context, gl_info, mapped_stage);
3437 /* Values 0-7 are indexes into the FVF tex coords - See comments in DrawPrimitive
3439 * FIXME: When using generated texture coordinates, the index value is used to specify the wrapping mode.
3440 * eg. SetTextureStageState( 0, WINED3D_TSS_TEXCOORDINDEX, WINED3D_TSS_TCI_CAMERASPACEPOSITION | 1 );
3441 * means use the vertex position (camera-space) as the input texture coordinates
3442 * for this texture stage, and the wrap mode set in the WINED3D_RS_WRAP1 render
3443 * state. We do not (yet) support the WINED3DRENDERSTATE_WRAPx values, nor tie them up
3444 * to the TEXCOORDINDEX value
3446 switch (state->texture_states[stage][WINED3D_TSS_TEXCOORD_INDEX] & 0xffff0000)
3448 case WINED3DTSS_TCI_PASSTHRU:
3449 /* Use the specified texture coordinates contained within the
3450 * vertex format. This value resolves to zero. */
3451 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_S);
3452 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_T);
3453 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_R);
3454 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_Q);
3455 checkGLcall("WINED3DTSS_TCI_PASSTHRU - Disable texgen.");
3456 break;
3458 case WINED3DTSS_TCI_CAMERASPACEPOSITION:
3459 /* CameraSpacePosition means use the vertex position, transformed to camera space,
3460 * as the input texture coordinates for this stage's texture transformation. This
3461 * equates roughly to EYE_LINEAR */
3463 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
3464 gl_info->gl_ops.gl.p_glPushMatrix();
3465 gl_info->gl_ops.gl.p_glLoadIdentity();
3466 gl_info->gl_ops.gl.p_glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
3467 gl_info->gl_ops.gl.p_glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
3468 gl_info->gl_ops.gl.p_glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
3469 gl_info->gl_ops.gl.p_glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
3470 gl_info->gl_ops.gl.p_glPopMatrix();
3471 checkGLcall("WINED3DTSS_TCI_CAMERASPACEPOSITION - Set eye plane.");
3473 gl_info->gl_ops.gl.p_glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
3474 gl_info->gl_ops.gl.p_glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
3475 gl_info->gl_ops.gl.p_glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
3476 checkGLcall("WINED3DTSS_TCI_CAMERASPACEPOSITION - Set texgen mode.");
3478 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_S);
3479 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_T);
3480 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_R);
3481 checkGLcall("WINED3DTSS_TCI_CAMERASPACEPOSITION - Enable texgen.");
3483 break;
3485 case WINED3DTSS_TCI_CAMERASPACENORMAL:
3486 /* Note that NV_TEXGEN_REFLECTION support is implied when
3487 * ARB_TEXTURE_CUBE_MAP is supported */
3488 if (!gl_info->supported[NV_TEXGEN_REFLECTION])
3490 FIXME("WINED3DTSS_TCI_CAMERASPACENORMAL not supported.\n");
3491 break;
3494 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
3495 gl_info->gl_ops.gl.p_glPushMatrix();
3496 gl_info->gl_ops.gl.p_glLoadIdentity();
3497 gl_info->gl_ops.gl.p_glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
3498 gl_info->gl_ops.gl.p_glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
3499 gl_info->gl_ops.gl.p_glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
3500 gl_info->gl_ops.gl.p_glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
3501 gl_info->gl_ops.gl.p_glPopMatrix();
3502 checkGLcall("WINED3DTSS_TCI_CAMERASPACENORMAL - Set eye plane.");
3504 gl_info->gl_ops.gl.p_glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
3505 gl_info->gl_ops.gl.p_glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
3506 gl_info->gl_ops.gl.p_glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
3507 checkGLcall("WINED3DTSS_TCI_CAMERASPACENORMAL - Set texgen mode.");
3509 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_S);
3510 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_T);
3511 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_R);
3512 checkGLcall("WINED3DTSS_TCI_CAMERASPACENORMAL - Enable texgen.");
3514 break;
3516 case WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR:
3517 /* Note that NV_TEXGEN_REFLECTION support is implied when
3518 * ARB_TEXTURE_CUBE_MAP is supported */
3519 if (!gl_info->supported[NV_TEXGEN_REFLECTION])
3521 FIXME("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR not supported.\n");
3522 break;
3525 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
3526 gl_info->gl_ops.gl.p_glPushMatrix();
3527 gl_info->gl_ops.gl.p_glLoadIdentity();
3528 gl_info->gl_ops.gl.p_glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
3529 gl_info->gl_ops.gl.p_glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
3530 gl_info->gl_ops.gl.p_glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
3531 gl_info->gl_ops.gl.p_glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
3532 gl_info->gl_ops.gl.p_glPopMatrix();
3533 checkGLcall("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Set eye plane.");
3535 gl_info->gl_ops.gl.p_glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
3536 gl_info->gl_ops.gl.p_glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
3537 gl_info->gl_ops.gl.p_glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
3538 checkGLcall("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Set texgen mode.");
3540 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_S);
3541 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_T);
3542 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_R);
3543 checkGLcall("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Enable texgen.");
3545 break;
3547 case WINED3DTSS_TCI_SPHEREMAP:
3548 gl_info->gl_ops.gl.p_glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
3549 gl_info->gl_ops.gl.p_glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
3550 checkGLcall("WINED3DTSS_TCI_SPHEREMAP - Set texgen mode.");
3552 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_S);
3553 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_T);
3554 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_R);
3555 checkGLcall("WINED3DTSS_TCI_SPHEREMAP - Enable texgen.");
3557 break;
3559 default:
3560 FIXME("Unhandled WINED3D_TSS_TEXCOORD_INDEX %#x.\n",
3561 state->texture_states[stage][WINED3D_TSS_TEXCOORD_INDEX]);
3562 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_S);
3563 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_T);
3564 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_R);
3565 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_Q);
3566 checkGLcall("Disable texgen.");
3568 break;
3571 /* Update the texture matrix. */
3572 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + stage)))
3573 transform_texture(context, state, STATE_TEXTURESTAGE(stage, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS));
3575 if (!isStateDirty(context, STATE_VDECL) && context->namedArraysLoaded)
3577 /* Reload the arrays if we are using fixed function arrays to reflect the selected coord input
3578 * source. Call loadTexCoords directly because there is no need to reparse the vertex declaration
3579 * and do all the things linked to it
3580 * TODO: Tidy that up to reload only the arrays of the changed unit
3582 GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
3584 unload_tex_coords(gl_info);
3585 load_tex_coords(context, &device->stream_info, &curVBO, state);
3589 void sampler_texmatrix(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3591 const DWORD sampler = state_id - STATE_SAMPLER(0);
3592 const struct wined3d_texture *texture = state->textures[sampler];
3594 TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
3596 if(!texture) return;
3597 /* The fixed function np2 texture emulation uses the texture matrix to fix up the coordinates
3598 * wined3d_texture_apply_state_changes() multiplies the set matrix with a fixup matrix. Before the
3599 * scaling is reapplied or removed, the texture matrix has to be reapplied
3601 * The mapped stage is already active because the sampler() function below, which is part of the
3602 * misc pipeline
3604 if (sampler < MAX_TEXTURES)
3606 const BOOL texIsPow2 = !(texture->flags & WINED3D_TEXTURE_POW2_MAT_IDENT);
3608 if (texIsPow2 || (context->lastWasPow2Texture & (1 << sampler)))
3610 const struct wined3d_device *device = context->swapchain->device;
3612 if (texIsPow2)
3613 context->lastWasPow2Texture |= 1 << sampler;
3614 else
3615 context->lastWasPow2Texture &= ~(1 << sampler);
3617 transform_texture(context, state,
3618 STATE_TEXTURESTAGE(device->texUnitMap[sampler], WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS));
3623 static void sampler(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3625 const struct wined3d_device *device = context->swapchain->device;
3626 DWORD sampler = state_id - STATE_SAMPLER(0);
3627 DWORD mapped_stage = device->texUnitMap[sampler];
3628 const struct wined3d_gl_info *gl_info = context->gl_info;
3629 union {
3630 float f;
3631 DWORD d;
3632 } tmpvalue;
3634 TRACE("Sampler: %d\n", sampler);
3635 /* Enabling and disabling texture dimensions is done by texture stage state / pixel shader setup, this function
3636 * only has to bind textures and set the per texture states
3639 if (mapped_stage == WINED3D_UNMAPPED_STAGE)
3641 TRACE("No sampler mapped to stage %d. Returning.\n", sampler);
3642 return;
3645 if (mapped_stage >= gl_info->limits.combined_samplers)
3647 return;
3649 context_active_texture(context, gl_info, mapped_stage);
3651 if (state->textures[sampler])
3653 struct wined3d_texture *texture = state->textures[sampler];
3654 BOOL srgb = state->sampler_states[sampler][WINED3D_SAMP_SRGB_TEXTURE];
3656 texture->texture_ops->texture_bind(texture, context, srgb);
3657 wined3d_texture_apply_state_changes(texture, state->sampler_states[sampler], gl_info);
3659 if (gl_info->supported[EXT_TEXTURE_LOD_BIAS])
3661 tmpvalue.d = state->sampler_states[sampler][WINED3D_SAMP_MIPMAP_LOD_BIAS];
3662 gl_info->gl_ops.gl.p_glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT,
3663 GL_TEXTURE_LOD_BIAS_EXT, tmpvalue.f);
3664 checkGLcall("glTexEnvf(GL_TEXTURE_LOD_BIAS_EXT, ...)");
3667 if (!use_ps(state) && sampler < state->lowest_disabled_stage)
3669 if (state->render_states[WINED3D_RS_COLORKEYENABLE] && !sampler)
3671 /* If color keying is enabled update the alpha test, it
3672 * depends on the existence of a color key in stage 0. */
3673 state_alpha(context, state, WINED3D_RS_COLORKEYENABLE);
3677 /* Trigger shader constant reloading (for NP2 texcoord fixup) */
3678 if (!(texture->flags & WINED3D_TEXTURE_POW2_MAT_IDENT))
3679 device->shader_backend->shader_load_np2fixup_constants(device->shader_priv, gl_info, state);
3681 else
3683 if (sampler < state->lowest_disabled_stage)
3685 /* TODO: What should I do with pixel shaders here ??? */
3686 if (state->render_states[WINED3D_RS_COLORKEYENABLE] && !sampler)
3688 /* If color keying is enabled update the alpha test, it
3689 * depends on the existence of a color key in stage 0. */
3690 state_alpha(context, state, WINED3D_RS_COLORKEYENABLE);
3692 } /* Otherwise tex_colorop disables the stage */
3693 context_bind_texture(context, GL_NONE, 0);
3697 void apply_pixelshader(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3699 unsigned int i;
3701 if (use_ps(state))
3703 if (!context->last_was_pshader)
3705 /* Former draw without a pixel shader, some samplers may be
3706 * disabled because of WINED3D_TSS_COLOR_OP = WINED3DTOP_DISABLE
3707 * make sure to enable them. */
3708 for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i)
3710 if (!isStateDirty(context, STATE_SAMPLER(i)))
3711 sampler(context, state, STATE_SAMPLER(i));
3713 context->last_was_pshader = TRUE;
3715 else
3717 /* Otherwise all samplers were activated by the code above in
3718 * earlier draws, or by sampler() if a different texture was
3719 * bound. I don't have to do anything. */
3722 else
3724 /* Disabled the pixel shader - color ops weren't applied while it was
3725 * enabled, so re-apply them. */
3726 for (i = 0; i < context->d3d_info->limits.ffp_blend_stages; ++i)
3728 if (!isStateDirty(context, STATE_TEXTURESTAGE(i, WINED3D_TSS_COLOR_OP)))
3729 context_apply_state(context, state, STATE_TEXTURESTAGE(i, WINED3D_TSS_COLOR_OP));
3731 context->last_was_pshader = FALSE;
3734 context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_PIXEL;
3737 static void state_geometry_shader(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3739 context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_GEOMETRY;
3742 static void shader_bumpenv(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3744 context->constant_update_mask |= WINED3D_SHADER_CONST_PS_BUMP_ENV;
3747 void transform_world(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3749 const struct wined3d_gl_info *gl_info = context->gl_info;
3751 /* This function is called by transform_view below if the view matrix was changed too
3753 * Deliberately no check if the vertex declaration is dirty because the vdecl state
3754 * does not always update the world matrix, only on a switch between transformed
3755 * and untransformed draws. It *may* happen that the world matrix is set 2 times during one
3756 * draw, but that should be rather rare and cheaper in total.
3758 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
3759 checkGLcall("glMatrixMode");
3761 if (context->last_was_rhw)
3763 gl_info->gl_ops.gl.p_glLoadIdentity();
3764 checkGLcall("glLoadIdentity()");
3766 else
3768 gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
3769 checkGLcall("glLoadMatrixf");
3770 gl_info->gl_ops.gl.p_glMultMatrixf(&state->transforms[WINED3D_TS_WORLD_MATRIX(0)].u.m[0][0]);
3771 checkGLcall("glMultMatrixf");
3775 void clipplane(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3777 const struct wined3d_gl_info *gl_info = context->gl_info;
3778 UINT index = state_id - STATE_CLIPPLANE(0);
3779 GLdouble plane[4];
3781 if (isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_VIEW)) || index >= gl_info->limits.clipplanes)
3782 return;
3784 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
3785 gl_info->gl_ops.gl.p_glPushMatrix();
3787 /* Clip Plane settings are affected by the model view in OpenGL, the View transform in direct3d */
3788 if (!use_vs(state))
3789 gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
3790 else
3791 /* With vertex shaders, clip planes are not transformed in Direct3D,
3792 * while in OpenGL they are still transformed by the model view matix. */
3793 gl_info->gl_ops.gl.p_glLoadIdentity();
3795 plane[0] = state->clip_planes[index].x;
3796 plane[1] = state->clip_planes[index].y;
3797 plane[2] = state->clip_planes[index].z;
3798 plane[3] = state->clip_planes[index].w;
3800 TRACE("Clipplane [%.8e, %.8e, %.8e, %.8e]\n",
3801 plane[0], plane[1], plane[2], plane[3]);
3802 gl_info->gl_ops.gl.p_glClipPlane(GL_CLIP_PLANE0 + index, plane);
3803 checkGLcall("glClipPlane");
3805 gl_info->gl_ops.gl.p_glPopMatrix();
3808 static void transform_worldex(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3810 UINT matrix = state_id - STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0));
3811 const struct wined3d_gl_info *gl_info = context->gl_info;
3812 GLenum glMat;
3814 TRACE("Setting world matrix %d\n", matrix);
3816 if (matrix >= gl_info->limits.blends)
3818 WARN("Unsupported blend matrix set\n");
3819 return;
3822 if (isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_VIEW)))
3823 return;
3825 /* GL_MODELVIEW0_ARB: 0x1700
3826 * GL_MODELVIEW1_ARB: 0x850a
3827 * GL_MODELVIEW2_ARB: 0x8722
3828 * GL_MODELVIEW3_ARB: 0x8723
3829 * etc
3830 * GL_MODELVIEW31_ARB: 0x873f
3832 if(matrix == 1) glMat = GL_MODELVIEW1_ARB;
3833 else glMat = GL_MODELVIEW2_ARB - 2 + matrix;
3835 gl_info->gl_ops.gl.p_glMatrixMode(glMat);
3836 checkGLcall("glMatrixMode(glMat)");
3838 /* World matrix 0 is multiplied with the view matrix because d3d uses 3
3839 * matrices while gl uses only 2. To avoid weighting the view matrix
3840 * incorrectly it has to be multiplied into every GL modelview matrix. */
3841 gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
3842 checkGLcall("glLoadMatrixf");
3843 gl_info->gl_ops.gl.p_glMultMatrixf(&state->transforms[WINED3D_TS_WORLD_MATRIX(matrix)].u.m[0][0]);
3844 checkGLcall("glMultMatrixf");
3847 static void state_vertexblend_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3849 enum wined3d_vertex_blend_flags f = state->render_states[WINED3D_RS_VERTEXBLEND];
3850 static unsigned int once;
3852 if (f == WINED3D_VBF_DISABLE)
3853 return;
3855 if (!once++) FIXME("Vertex blend flags %#x not supported.\n", f);
3856 else WARN("Vertex blend flags %#x not supported.\n", f);
3859 static void state_vertexblend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3861 enum wined3d_vertex_blend_flags val = state->render_states[WINED3D_RS_VERTEXBLEND];
3862 struct wined3d_device *device = context->swapchain->device;
3863 const struct wined3d_gl_info *gl_info = context->gl_info;
3864 static unsigned int once;
3866 switch (val)
3868 case WINED3D_VBF_1WEIGHTS:
3869 case WINED3D_VBF_2WEIGHTS:
3870 case WINED3D_VBF_3WEIGHTS:
3871 gl_info->gl_ops.gl.p_glEnable(GL_VERTEX_BLEND_ARB);
3872 checkGLcall("glEnable(GL_VERTEX_BLEND_ARB)");
3874 /* D3D adds one more matrix which has weight (1 - sum(weights)).
3875 * This is enabled at context creation with enabling
3876 * GL_WEIGHT_SUM_UNITY_ARB. */
3877 GL_EXTCALL(glVertexBlendARB(state->render_states[WINED3D_RS_VERTEXBLEND] + 1));
3879 if (!device->vertexBlendUsed)
3881 unsigned int i;
3882 for (i = 1; i < gl_info->limits.blends; ++i)
3884 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(i))))
3885 transform_worldex(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(i)));
3887 device->vertexBlendUsed = TRUE;
3889 break;
3891 case WINED3D_VBF_TWEENING:
3892 case WINED3D_VBF_0WEIGHTS: /* Indexed vertex blending, not supported. */
3893 if (!once++) FIXME("Vertex blend flags %#x not supported.\n", val);
3894 else WARN("Vertex blend flags %#x not supported.\n", val);
3895 /* Fall through. */
3896 case WINED3D_VBF_DISABLE:
3897 gl_info->gl_ops.gl.p_glDisable(GL_VERTEX_BLEND_ARB);
3898 checkGLcall("glDisable(GL_VERTEX_BLEND_ARB)");
3899 break;
3903 void transform_view(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3905 const struct wined3d_gl_info *gl_info = context->gl_info;
3906 const struct wined3d_light_info *light = NULL;
3907 unsigned int k;
3909 /* If we are changing the View matrix, reset the light and clipping planes to the new view
3910 * NOTE: We have to reset the positions even if the light/plane is not currently
3911 * enabled, since the call to enable it will not reset the position.
3912 * NOTE2: Apparently texture transforms do NOT need reapplying
3915 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
3916 checkGLcall("glMatrixMode(GL_MODELVIEW)");
3917 gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
3918 checkGLcall("glLoadMatrixf(...)");
3920 /* Reset lights. TODO: Call light apply func */
3921 for (k = 0; k < gl_info->limits.lights; ++k)
3923 if (!(light = state->lights[k]))
3924 continue;
3925 gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + light->glIndex, GL_POSITION, light->lightPosn);
3926 checkGLcall("glLightfv posn");
3927 gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + light->glIndex, GL_SPOT_DIRECTION, light->lightDirn);
3928 checkGLcall("glLightfv dirn");
3931 /* Reset Clipping Planes */
3932 for (k = 0; k < gl_info->limits.clipplanes; ++k)
3934 if (!isStateDirty(context, STATE_CLIPPLANE(k)))
3935 clipplane(context, state, STATE_CLIPPLANE(k));
3938 if (context->last_was_rhw)
3940 gl_info->gl_ops.gl.p_glLoadIdentity();
3941 checkGLcall("glLoadIdentity()");
3942 /* No need to update the world matrix, the identity is fine */
3943 return;
3946 /* Call the world matrix state, this will apply the combined WORLD + VIEW matrix
3947 * No need to do it here if the state is scheduled for update. */
3948 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0))))
3949 transform_world(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)));
3951 /* Avoid looping over a number of matrices if the app never used the functionality */
3952 if (context->swapchain->device->vertexBlendUsed)
3954 for (k = 1; k < gl_info->limits.blends; ++k)
3956 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(k))))
3957 transform_worldex(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(k)));
3962 void transform_projection(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3964 const struct wined3d_gl_info *gl_info = context->gl_info;
3966 gl_info->gl_ops.gl.p_glMatrixMode(GL_PROJECTION);
3967 checkGLcall("glMatrixMode(GL_PROJECTION)");
3969 /* There are a couple of additional things we have to take into account
3970 * here besides the projection transformation itself:
3971 * - We need to flip along the y-axis in case of offscreen rendering.
3972 * - OpenGL Z range is {-Wc,...,Wc} while D3D Z range is {0,...,Wc}.
3973 * - D3D coordinates refer to pixel centers while GL coordinates refer
3974 * to pixel corners.
3975 * - D3D has a top-left filling convention. We need to maintain this
3976 * even after the y-flip mentioned above.
3977 * In order to handle the last two points, we translate by
3978 * (63.0 / 128.0) / VPw and (63.0 / 128.0) / VPh. This is equivalent to
3979 * translating slightly less than half a pixel. We want the difference to
3980 * be large enough that it doesn't get lost due to rounding inside the
3981 * driver, but small enough to prevent it from interfering with any
3982 * anti-aliasing. */
3984 if (context->last_was_rhw)
3986 /* Transform D3D RHW coordinates to OpenGL clip coordinates. */
3987 double x = state->viewport.x;
3988 double y = state->viewport.y;
3989 double w = state->viewport.width;
3990 double h = state->viewport.height;
3991 double x_scale = 2.0 / w;
3992 double x_offset = ((63.0 / 64.0) - (2.0 * x) - w) / w;
3993 double y_scale = context->render_offscreen ? 2.0 / h : 2.0 / -h;
3994 double y_offset = context->render_offscreen
3995 ? ((63.0 / 64.0) - (2.0 * y) - h) / h
3996 : ((63.0 / 64.0) - (2.0 * y) - h) / -h;
3997 const GLdouble projection[] =
3999 x_scale, 0.0, 0.0, 0.0,
4000 0.0, y_scale, 0.0, 0.0,
4001 0.0, 0.0, 2.0, 0.0,
4002 x_offset, y_offset, -1.0, 1.0,
4005 gl_info->gl_ops.gl.p_glLoadMatrixd(projection);
4006 checkGLcall("glLoadMatrixd");
4008 else
4010 double y_scale = context->render_offscreen ? -1.0 : 1.0;
4011 double x_offset = (63.0 / 64.0) / state->viewport.width;
4012 double y_offset = context->render_offscreen
4013 ? (63.0 / 64.0) / state->viewport.height
4014 : -(63.0 / 64.0) / state->viewport.height;
4015 const GLdouble projection[] =
4017 1.0, 0.0, 0.0, 0.0,
4018 0.0, y_scale, 0.0, 0.0,
4019 0.0, 0.0, 2.0, 0.0,
4020 x_offset, y_offset, -1.0, 1.0,
4023 gl_info->gl_ops.gl.p_glLoadMatrixd(projection);
4024 checkGLcall("glLoadMatrixd");
4026 gl_info->gl_ops.gl.p_glMultMatrixf(&state->transforms[WINED3D_TS_PROJECTION].u.m[0][0]);
4027 checkGLcall("glLoadMatrixf");
4031 /* This should match any arrays loaded in load_vertex_data.
4032 * TODO: Only load / unload arrays if we have to. */
4033 static void unload_vertex_data(const struct wined3d_gl_info *gl_info)
4035 gl_info->gl_ops.gl.p_glDisableClientState(GL_VERTEX_ARRAY);
4036 gl_info->gl_ops.gl.p_glDisableClientState(GL_NORMAL_ARRAY);
4037 gl_info->gl_ops.gl.p_glDisableClientState(GL_COLOR_ARRAY);
4038 if (gl_info->supported[EXT_SECONDARY_COLOR])
4039 gl_info->gl_ops.gl.p_glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
4040 if (gl_info->supported[ARB_VERTEX_BLEND])
4041 gl_info->gl_ops.gl.p_glDisableClientState(GL_WEIGHT_ARRAY_ARB);
4042 unload_tex_coords(gl_info);
4045 static inline void unload_numbered_array(struct wined3d_context *context, int i)
4047 const struct wined3d_gl_info *gl_info = context->gl_info;
4049 GL_EXTCALL(glDisableVertexAttribArrayARB(i));
4050 checkGLcall("glDisableVertexAttribArrayARB(reg)");
4051 if (gl_info->supported[ARB_INSTANCED_ARRAYS])
4052 GL_EXTCALL(glVertexAttribDivisorARB(i, 0));
4054 context->numbered_array_mask &= ~(1 << i);
4057 /* This should match any arrays loaded in loadNumberedArrays
4058 * TODO: Only load / unload arrays if we have to. */
4059 static void unload_numbered_arrays(struct wined3d_context *context)
4061 /* disable any attribs (this is the same for both GLSL and ARB modes) */
4062 int i;
4064 for (i = 0; i < context->gl_info->limits.vertex_attribs; ++i) {
4065 unload_numbered_array(context, i);
4069 static void load_numbered_arrays(struct wined3d_context *context,
4070 const struct wined3d_stream_info *stream_info, const struct wined3d_state *state)
4072 struct wined3d_device *device = context->swapchain->device;
4073 const struct wined3d_gl_info *gl_info = context->gl_info;
4074 GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
4075 int i;
4077 /* Default to no instancing */
4078 device->instance_count = 0;
4080 for (i = 0; i < MAX_ATTRIBS; i++)
4082 const struct wined3d_stream_state *stream;
4084 if (!(stream_info->use_map & (1 << i)))
4086 if (context->numbered_array_mask & (1 << i))
4087 unload_numbered_array(context, i);
4088 if (state->vertex_shader->reg_maps.input_registers & (1 << i))
4089 GL_EXTCALL(glVertexAttrib4fARB(i, 0.0f, 0.0f, 0.0f, 0.0f));
4090 continue;
4093 stream = &state->streams[stream_info->elements[i].stream_idx];
4095 if (stream->flags & WINED3DSTREAMSOURCE_INSTANCEDATA)
4097 if (!device->instance_count)
4098 device->instance_count = state->streams[0].frequency ? state->streams[0].frequency : 1;
4100 if (!gl_info->supported[ARB_INSTANCED_ARRAYS])
4102 /* Unload instanced arrays, they will be loaded using
4103 * immediate mode instead. */
4104 if (context->numbered_array_mask & (1 << i))
4105 unload_numbered_array(context, i);
4106 continue;
4109 GL_EXTCALL(glVertexAttribDivisorARB(i, 1));
4111 else if (gl_info->supported[ARB_INSTANCED_ARRAYS])
4113 GL_EXTCALL(glVertexAttribDivisorARB(i, 0));
4116 TRACE_(d3d_shader)("Loading array %u [VBO=%u]\n", i, stream_info->elements[i].data.buffer_object);
4118 if (stream_info->elements[i].stride)
4120 if (curVBO != stream_info->elements[i].data.buffer_object)
4122 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, stream_info->elements[i].data.buffer_object));
4123 checkGLcall("glBindBufferARB");
4124 curVBO = stream_info->elements[i].data.buffer_object;
4126 /* Use the VBO to find out if a vertex buffer exists, not the vb
4127 * pointer. vb can point to a user pointer data blob. In that case
4128 * curVBO will be 0. If there is a vertex buffer but no vbo we
4129 * won't be load converted attributes anyway. */
4130 GL_EXTCALL(glVertexAttribPointerARB(i, stream_info->elements[i].format->gl_vtx_format,
4131 stream_info->elements[i].format->gl_vtx_type,
4132 stream_info->elements[i].format->gl_normalized,
4133 stream_info->elements[i].stride, stream_info->elements[i].data.addr
4134 + state->load_base_vertex_index * stream_info->elements[i].stride));
4136 if (!(context->numbered_array_mask & (1 << i)))
4138 GL_EXTCALL(glEnableVertexAttribArrayARB(i));
4139 context->numbered_array_mask |= (1 << i);
4142 else
4144 /* Stride = 0 means always the same values.
4145 * glVertexAttribPointerARB doesn't do that. Instead disable the
4146 * pointer and set up the attribute statically. But we have to
4147 * figure out the system memory address. */
4148 const BYTE *ptr = stream_info->elements[i].data.addr;
4149 if (stream_info->elements[i].data.buffer_object)
4151 ptr += (ULONG_PTR)buffer_get_sysmem(stream->buffer, gl_info);
4154 if (context->numbered_array_mask & (1 << i)) unload_numbered_array(context, i);
4156 switch (stream_info->elements[i].format->id)
4158 case WINED3DFMT_R32_FLOAT:
4159 GL_EXTCALL(glVertexAttrib1fvARB(i, (const GLfloat *)ptr));
4160 break;
4161 case WINED3DFMT_R32G32_FLOAT:
4162 GL_EXTCALL(glVertexAttrib2fvARB(i, (const GLfloat *)ptr));
4163 break;
4164 case WINED3DFMT_R32G32B32_FLOAT:
4165 GL_EXTCALL(glVertexAttrib3fvARB(i, (const GLfloat *)ptr));
4166 break;
4167 case WINED3DFMT_R32G32B32A32_FLOAT:
4168 GL_EXTCALL(glVertexAttrib4fvARB(i, (const GLfloat *)ptr));
4169 break;
4171 case WINED3DFMT_R8G8B8A8_UINT:
4172 GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
4173 break;
4174 case WINED3DFMT_B8G8R8A8_UNORM:
4175 if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
4177 const DWORD *src = (const DWORD *)ptr;
4178 DWORD c = *src & 0xff00ff00;
4179 c |= (*src & 0xff0000) >> 16;
4180 c |= (*src & 0xff) << 16;
4181 GL_EXTCALL(glVertexAttrib4NubvARB(i, (GLubyte *)&c));
4182 break;
4184 /* else fallthrough */
4185 case WINED3DFMT_R8G8B8A8_UNORM:
4186 GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
4187 break;
4189 case WINED3DFMT_R16G16_SINT:
4190 GL_EXTCALL(glVertexAttrib4svARB(i, (const GLshort *)ptr));
4191 break;
4192 case WINED3DFMT_R16G16B16A16_SINT:
4193 GL_EXTCALL(glVertexAttrib4svARB(i, (const GLshort *)ptr));
4194 break;
4196 case WINED3DFMT_R16G16_SNORM:
4198 const GLshort s[4] = {((const GLshort *)ptr)[0], ((const GLshort *)ptr)[1], 0, 1};
4199 GL_EXTCALL(glVertexAttrib4NsvARB(i, s));
4200 break;
4202 case WINED3DFMT_R16G16_UNORM:
4204 const GLushort s[4] = {((const GLushort *)ptr)[0], ((const GLushort *)ptr)[1], 0, 1};
4205 GL_EXTCALL(glVertexAttrib4NusvARB(i, s));
4206 break;
4208 case WINED3DFMT_R16G16B16A16_SNORM:
4209 GL_EXTCALL(glVertexAttrib4NsvARB(i, (const GLshort *)ptr));
4210 break;
4211 case WINED3DFMT_R16G16B16A16_UNORM:
4212 GL_EXTCALL(glVertexAttrib4NusvARB(i, (const GLushort *)ptr));
4213 break;
4215 case WINED3DFMT_R10G10B10A2_UINT:
4216 FIXME("Unsure about WINED3DDECLTYPE_UDEC3\n");
4217 /*glVertexAttrib3usvARB(i, (const GLushort *)ptr); Does not exist */
4218 break;
4219 case WINED3DFMT_R10G10B10A2_SNORM:
4220 FIXME("Unsure about WINED3DDECLTYPE_DEC3N\n");
4221 /*glVertexAttrib3NusvARB(i, (const GLushort *)ptr); Does not exist */
4222 break;
4224 case WINED3DFMT_R16G16_FLOAT:
4225 /* Are those 16 bit floats. C doesn't have a 16 bit float type. I could read the single bits and calculate a 4
4226 * byte float according to the IEEE standard
4228 FIXME("Unsupported WINED3DDECLTYPE_FLOAT16_2\n");
4229 break;
4230 case WINED3DFMT_R16G16B16A16_FLOAT:
4231 FIXME("Unsupported WINED3DDECLTYPE_FLOAT16_4\n");
4232 break;
4234 default:
4235 ERR("Unexpected declaration in stride 0 attributes\n");
4236 break;
4241 checkGLcall("Loading numbered arrays");
4244 static void load_vertex_data(const struct wined3d_context *context,
4245 const struct wined3d_stream_info *si, const struct wined3d_state *state)
4247 struct wined3d_device *device = context->swapchain->device;
4248 const struct wined3d_gl_info *gl_info = context->gl_info;
4249 GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
4250 const struct wined3d_stream_info_element *e;
4252 TRACE("Using fast vertex array code\n");
4254 /* This is fixed function pipeline only, and the fixed function pipeline doesn't do instancing */
4255 device->instance_count = 0;
4257 /* Blend Data ---------------------------------------------- */
4258 if ((si->use_map & (1 << WINED3D_FFP_BLENDWEIGHT))
4259 || si->use_map & (1 << WINED3D_FFP_BLENDINDICES))
4261 e = &si->elements[WINED3D_FFP_BLENDWEIGHT];
4263 if (gl_info->supported[ARB_VERTEX_BLEND])
4265 TRACE("Blend %u %p %u\n", e->format->component_count,
4266 e->data.addr + state->load_base_vertex_index * e->stride, e->stride);
4268 gl_info->gl_ops.gl.p_glEnableClientState(GL_WEIGHT_ARRAY_ARB);
4269 checkGLcall("glEnableClientState(GL_WEIGHT_ARRAY_ARB)");
4271 GL_EXTCALL(glVertexBlendARB(e->format->component_count + 1));
4273 if (curVBO != e->data.buffer_object)
4275 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4276 checkGLcall("glBindBufferARB");
4277 curVBO = e->data.buffer_object;
4280 TRACE("glWeightPointerARB(%#x, %#x, %#x, %p);\n",
4281 e->format->gl_vtx_format,
4282 e->format->gl_vtx_type,
4283 e->stride,
4284 e->data.addr + state->load_base_vertex_index * e->stride);
4285 GL_EXTCALL(glWeightPointerARB(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4286 e->data.addr + state->load_base_vertex_index * e->stride));
4288 checkGLcall("glWeightPointerARB");
4290 if (si->use_map & (1 << WINED3D_FFP_BLENDINDICES))
4292 static BOOL warned;
4293 if (!warned)
4295 FIXME("blendMatrixIndices support\n");
4296 warned = TRUE;
4299 } else {
4300 /* TODO: support blends in drawStridedSlow
4301 * No need to write a FIXME here, this is done after the general vertex decl decoding
4303 WARN("unsupported blending in openGl\n");
4306 else
4308 if (gl_info->supported[ARB_VERTEX_BLEND])
4310 static const GLbyte one = 1;
4311 GL_EXTCALL(glWeightbvARB(1, &one));
4312 checkGLcall("glWeightbvARB(gl_info->max_blends, weights)");
4316 /* Point Size ----------------------------------------------*/
4317 if (si->use_map & (1 << WINED3D_FFP_PSIZE))
4319 /* no such functionality in the fixed function GL pipeline */
4320 TRACE("Cannot change ptSize here in openGl\n");
4321 /* TODO: Implement this function in using shaders if they are available */
4324 /* Vertex Pointers -----------------------------------------*/
4325 if (si->use_map & (1 << WINED3D_FFP_POSITION))
4327 e = &si->elements[WINED3D_FFP_POSITION];
4329 if (curVBO != e->data.buffer_object)
4331 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4332 checkGLcall("glBindBufferARB");
4333 curVBO = e->data.buffer_object;
4336 TRACE("glVertexPointer(%#x, %#x, %#x, %p);\n",
4337 e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4338 e->data.addr + state->load_base_vertex_index * e->stride);
4339 gl_info->gl_ops.gl.p_glVertexPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4340 e->data.addr + state->load_base_vertex_index * e->stride);
4341 checkGLcall("glVertexPointer(...)");
4342 gl_info->gl_ops.gl.p_glEnableClientState(GL_VERTEX_ARRAY);
4343 checkGLcall("glEnableClientState(GL_VERTEX_ARRAY)");
4346 /* Normals -------------------------------------------------*/
4347 if (si->use_map & (1 << WINED3D_FFP_NORMAL))
4349 e = &si->elements[WINED3D_FFP_NORMAL];
4351 if (curVBO != e->data.buffer_object)
4353 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4354 checkGLcall("glBindBufferARB");
4355 curVBO = e->data.buffer_object;
4358 TRACE("glNormalPointer(%#x, %#x, %p);\n", e->format->gl_vtx_type, e->stride,
4359 e->data.addr + state->load_base_vertex_index * e->stride);
4360 gl_info->gl_ops.gl.p_glNormalPointer(e->format->gl_vtx_type, e->stride,
4361 e->data.addr + state->load_base_vertex_index * e->stride);
4362 checkGLcall("glNormalPointer(...)");
4363 gl_info->gl_ops.gl.p_glEnableClientState(GL_NORMAL_ARRAY);
4364 checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)");
4367 else
4369 gl_info->gl_ops.gl.p_glNormal3f(0, 0, 0);
4370 checkGLcall("glNormal3f(0, 0, 0)");
4373 /* Diffuse Colour --------------------------------------------*/
4374 if (si->use_map & (1 << WINED3D_FFP_DIFFUSE))
4376 e = &si->elements[WINED3D_FFP_DIFFUSE];
4378 if (curVBO != e->data.buffer_object)
4380 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4381 checkGLcall("glBindBufferARB");
4382 curVBO = e->data.buffer_object;
4385 TRACE("glColorPointer(%#x, %#x %#x, %p);\n",
4386 e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4387 e->data.addr + state->load_base_vertex_index * e->stride);
4388 gl_info->gl_ops.gl.p_glColorPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4389 e->data.addr + state->load_base_vertex_index * e->stride);
4390 checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)");
4391 gl_info->gl_ops.gl.p_glEnableClientState(GL_COLOR_ARRAY);
4392 checkGLcall("glEnableClientState(GL_COLOR_ARRAY)");
4395 else
4397 gl_info->gl_ops.gl.p_glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
4398 checkGLcall("glColor4f(1, 1, 1, 1)");
4401 /* Specular Colour ------------------------------------------*/
4402 if (si->use_map & (1 << WINED3D_FFP_SPECULAR))
4404 TRACE("setting specular colour\n");
4406 e = &si->elements[WINED3D_FFP_SPECULAR];
4408 if (gl_info->supported[EXT_SECONDARY_COLOR])
4410 GLenum type = e->format->gl_vtx_type;
4411 GLint format = e->format->gl_vtx_format;
4413 if (curVBO != e->data.buffer_object)
4415 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4416 checkGLcall("glBindBufferARB");
4417 curVBO = e->data.buffer_object;
4420 if (format != 4 || (gl_info->quirks & WINED3D_QUIRK_ALLOWS_SPECULAR_ALPHA))
4422 /* Usually specular colors only allow 3 components, since they have no alpha. In D3D, the specular alpha
4423 * contains the fog coordinate, which is passed to GL with GL_EXT_fog_coord. However, the fixed function
4424 * vertex pipeline can pass the specular alpha through, and pixel shaders can read it. So it GL accepts
4425 * 4 component secondary colors use it
4427 TRACE("glSecondaryColorPointer(%#x, %#x, %#x, %p);\n", format, type, e->stride,
4428 e->data.addr + state->load_base_vertex_index * e->stride);
4429 GL_EXTCALL(glSecondaryColorPointerEXT(format, type, e->stride,
4430 e->data.addr + state->load_base_vertex_index * e->stride));
4431 checkGLcall("glSecondaryColorPointerEXT(format, type, ...)");
4433 else
4435 switch(type)
4437 case GL_UNSIGNED_BYTE:
4438 TRACE("glSecondaryColorPointer(3, GL_UNSIGNED_BYTE, %#x, %p);\n", e->stride,
4439 e->data.addr + state->load_base_vertex_index * e->stride);
4440 GL_EXTCALL(glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, e->stride,
4441 e->data.addr + state->load_base_vertex_index * e->stride));
4442 checkGLcall("glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, ...)");
4443 break;
4445 default:
4446 FIXME("Add 4 component specular color pointers for type %x\n", type);
4447 /* Make sure that the right color component is dropped */
4448 TRACE("glSecondaryColorPointer(3, %#x, %#x, %p);\n", type, e->stride,
4449 e->data.addr + state->load_base_vertex_index * e->stride);
4450 GL_EXTCALL(glSecondaryColorPointerEXT(3, type, e->stride,
4451 e->data.addr + state->load_base_vertex_index * e->stride));
4452 checkGLcall("glSecondaryColorPointerEXT(3, type, ...)");
4455 gl_info->gl_ops.gl.p_glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
4456 checkGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
4458 else
4460 WARN("Specular colour is not supported in this GL implementation.\n");
4463 else
4465 if (gl_info->supported[EXT_SECONDARY_COLOR])
4467 GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0);
4468 checkGLcall("glSecondaryColor3fEXT(0, 0, 0)");
4470 else
4472 WARN("Specular colour is not supported in this GL implementation.\n");
4476 /* Texture coords -------------------------------------------*/
4477 load_tex_coords(context, si, &curVBO, state);
4480 static void streamsrc(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4482 const struct wined3d_device *device = context->swapchain->device;
4483 BOOL load_numbered = use_vs(state) && !device->useDrawStridedSlow;
4484 BOOL load_named = !use_vs(state) && !device->useDrawStridedSlow;
4486 if (isStateDirty(context, STATE_VDECL)) return;
4487 if (context->numberedArraysLoaded && !load_numbered)
4489 unload_numbered_arrays(context);
4490 context->numberedArraysLoaded = FALSE;
4491 context->numbered_array_mask = 0;
4493 else if (context->namedArraysLoaded)
4495 unload_vertex_data(context->gl_info);
4496 context->namedArraysLoaded = FALSE;
4499 if (load_numbered)
4501 TRACE("Loading numbered arrays\n");
4502 load_numbered_arrays(context, &device->stream_info, state);
4503 context->numberedArraysLoaded = TRUE;
4505 else if (load_named)
4507 TRACE("Loading vertex data\n");
4508 load_vertex_data(context, &device->stream_info, state);
4509 context->namedArraysLoaded = TRUE;
4513 static void vdecl_miscpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4515 if (isStateDirty(context, STATE_STREAMSRC))
4516 return;
4517 streamsrc(context, state, STATE_STREAMSRC);
4520 void vertexdeclaration(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4522 const struct wined3d_device *device = context->swapchain->device;
4523 const struct wined3d_gl_info *gl_info = context->gl_info;
4524 BOOL useVertexShaderFunction = use_vs(state);
4525 BOOL updateFog = FALSE;
4526 BOOL transformed;
4527 BOOL wasrhw = context->last_was_rhw;
4528 unsigned int i;
4530 transformed = device->stream_info.position_transformed;
4531 if (transformed != context->last_was_rhw && !useVertexShaderFunction)
4532 updateFog = TRUE;
4534 context->last_was_rhw = transformed;
4536 /* Don't have to apply the matrices when vertex shaders are used. When
4537 * vshaders are turned off this function will be called again anyway to
4538 * make sure they're properly set. */
4539 if (!useVertexShaderFunction)
4541 /* TODO: Move this mainly to the viewport state and only apply when
4542 * the vp has changed or transformed / untransformed was switched. */
4543 if (wasrhw != context->last_was_rhw
4544 && !isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION))
4545 && !isStateDirty(context, STATE_VIEWPORT))
4546 transform_projection(context, state, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
4547 /* World matrix needs reapplication here only if we're switching between rhw and non-rhw
4548 * mode.
4550 * If a vertex shader is used, the world matrix changed and then vertex shader unbound
4551 * this check will fail and the matrix not applied again. This is OK because a simple
4552 * world matrix change reapplies the matrix - These checks here are only to satisfy the
4553 * needs of the vertex declaration.
4555 * World and view matrix go into the same gl matrix, so only apply them when neither is
4556 * dirty
4558 if (transformed != wasrhw && !isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)))
4559 && !isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_VIEW)))
4560 transform_world(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)));
4561 if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_COLORVERTEX)))
4562 context_apply_state(context, state, STATE_RENDER(WINED3D_RS_COLORVERTEX));
4563 if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_LIGHTING)))
4564 state_lighting(context, state, STATE_RENDER(WINED3D_RS_LIGHTING));
4566 if (context->last_was_vshader)
4568 updateFog = TRUE;
4570 if (!context->d3d_info->vs_clipping
4571 && !isStateDirty(context, STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE)))
4573 state_clipping(context, state, STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE));
4576 for (i = 0; i < gl_info->limits.clipplanes; ++i)
4578 clipplane(context, state, STATE_CLIPPLANE(i));
4581 if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_NORMALIZENORMALS)))
4582 state_normalize(context, state, STATE_RENDER(WINED3D_RS_NORMALIZENORMALS));
4584 else
4586 if(!context->last_was_vshader) {
4587 static BOOL warned = FALSE;
4588 if (!context->d3d_info->vs_clipping)
4590 /* Disable all clip planes to get defined results on all drivers. See comment in the
4591 * state_clipping state handler
4593 for (i = 0; i < gl_info->limits.clipplanes; ++i)
4595 gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE0 + i);
4596 checkGLcall("glDisable(GL_CLIP_PLANE0 + i)");
4599 if (!warned && state->render_states[WINED3D_RS_CLIPPLANEENABLE])
4601 FIXME("Clipping not supported with vertex shaders\n");
4602 warned = TRUE;
4605 if (wasrhw)
4607 /* Apply the transform matrices when switching from rhw
4608 * drawing to vertex shaders. Vertex shaders themselves do
4609 * not need it, but the matrices are not reapplied
4610 * automatically when switching back from vertex shaders to
4611 * fixed function processing. So make sure we leave the fixed
4612 * function vertex processing states back in a sane state
4613 * before switching to shaders. */
4614 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION)))
4615 transform_projection(context, state, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
4616 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0))))
4617 transform_world(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)));
4619 updateFog = TRUE;
4621 /* Vertex shader clipping ignores the view matrix. Update all clipplanes
4622 * (Note: ARB shaders can read the clip planes for clipping emulation even if
4623 * device->vs_clipping is false.
4625 for (i = 0; i < gl_info->limits.clipplanes; ++i)
4627 clipplane(context, state, STATE_CLIPPLANE(i));
4632 context->last_was_vshader = useVertexShaderFunction;
4633 context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_VERTEX;
4635 if (updateFog)
4636 context_apply_state(context, state, STATE_RENDER(WINED3D_RS_FOGVERTEXMODE));
4638 if (!useVertexShaderFunction)
4640 unsigned int i;
4642 for (i = 0; i < MAX_TEXTURES; ++i)
4644 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + i)))
4645 transform_texture(context, state, STATE_TEXTURESTAGE(i, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS));
4648 if (use_ps(state) && state->pixel_shader->reg_maps.shader_version.major == 1
4649 && state->pixel_shader->reg_maps.shader_version.minor <= 3)
4650 context->shader_update_mask |= 1 << WINED3D_SHADER_TYPE_PIXEL;
4653 if (transformed != wasrhw && !isStateDirty(context, STATE_RENDER(WINED3D_RS_ZENABLE)))
4654 state_zenable(context, state, STATE_RENDER(WINED3D_RS_ZENABLE));
4657 static void viewport_miscpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4659 const struct wined3d_surface *target = state->fb->render_targets[0];
4660 const struct wined3d_gl_info *gl_info = context->gl_info;
4661 struct wined3d_viewport vp = state->viewport;
4663 if (vp.width > target->resource.width)
4664 vp.width = target->resource.width;
4665 if (vp.height > target->resource.height)
4666 vp.height = target->resource.height;
4668 gl_info->gl_ops.gl.p_glDepthRange(vp.min_z, vp.max_z);
4669 checkGLcall("glDepthRange");
4670 /* Note: GL requires lower left, DirectX supplies upper left. This is
4671 * reversed when using offscreen rendering. */
4672 if (context->render_offscreen)
4674 gl_info->gl_ops.gl.p_glViewport(vp.x, vp.y, vp.width, vp.height);
4676 else
4678 UINT width, height;
4680 target->get_drawable_size(context, &width, &height);
4681 gl_info->gl_ops.gl.p_glViewport(vp.x, (height - (vp.y + vp.height)),
4682 vp.width, vp.height);
4684 checkGLcall("glViewport");
4687 void viewport_vertexpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4689 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION)))
4690 transform_projection(context, state, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
4691 if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_POINTSCALEENABLE))
4692 && state->render_states[WINED3D_RS_POINTSCALEENABLE])
4693 state_pscale(context, state, STATE_RENDER(WINED3D_RS_POINTSCALEENABLE));
4694 /* Update the position fixup. */
4695 context->constant_update_mask |= WINED3D_SHADER_CONST_VS_POS_FIXUP;
4698 void light(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4700 const struct wined3d_gl_info *gl_info = context->gl_info;
4701 UINT Index = state_id - STATE_ACTIVELIGHT(0);
4702 const struct wined3d_light_info *lightInfo = state->lights[Index];
4704 if (!lightInfo)
4706 gl_info->gl_ops.gl.p_glDisable(GL_LIGHT0 + Index);
4707 checkGLcall("glDisable(GL_LIGHT0 + Index)");
4709 else
4711 float quad_att;
4712 float colRGBA[] = {0.0f, 0.0f, 0.0f, 0.0f};
4714 /* Light settings are affected by the model view in OpenGL, the View transform in direct3d*/
4715 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
4716 gl_info->gl_ops.gl.p_glPushMatrix();
4717 gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
4719 /* Diffuse: */
4720 colRGBA[0] = lightInfo->OriginalParms.diffuse.r;
4721 colRGBA[1] = lightInfo->OriginalParms.diffuse.g;
4722 colRGBA[2] = lightInfo->OriginalParms.diffuse.b;
4723 colRGBA[3] = lightInfo->OriginalParms.diffuse.a;
4724 gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_DIFFUSE, colRGBA);
4725 checkGLcall("glLightfv");
4727 /* Specular */
4728 colRGBA[0] = lightInfo->OriginalParms.specular.r;
4729 colRGBA[1] = lightInfo->OriginalParms.specular.g;
4730 colRGBA[2] = lightInfo->OriginalParms.specular.b;
4731 colRGBA[3] = lightInfo->OriginalParms.specular.a;
4732 gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_SPECULAR, colRGBA);
4733 checkGLcall("glLightfv");
4735 /* Ambient */
4736 colRGBA[0] = lightInfo->OriginalParms.ambient.r;
4737 colRGBA[1] = lightInfo->OriginalParms.ambient.g;
4738 colRGBA[2] = lightInfo->OriginalParms.ambient.b;
4739 colRGBA[3] = lightInfo->OriginalParms.ambient.a;
4740 gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_AMBIENT, colRGBA);
4741 checkGLcall("glLightfv");
4743 if ((lightInfo->OriginalParms.range * lightInfo->OriginalParms.range) >= FLT_MIN)
4744 quad_att = 1.4f / (lightInfo->OriginalParms.range * lightInfo->OriginalParms.range);
4745 else
4746 quad_att = 0.0f; /* 0 or MAX? (0 seems to be ok) */
4748 /* Do not assign attenuation values for lights that do not use them. D3D apps are free to pass any junk,
4749 * but gl drivers use them and may crash due to bad Attenuation values. Need for Speed most wanted sets
4750 * Attenuation0 to NaN and crashes in the gl lib
4753 switch (lightInfo->OriginalParms.type)
4755 case WINED3D_LIGHT_POINT:
4756 /* Position */
4757 gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
4758 checkGLcall("glLightfv");
4759 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
4760 checkGLcall("glLightf");
4761 /* Attenuation - Are these right? guessing... */
4762 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_CONSTANT_ATTENUATION,
4763 lightInfo->OriginalParms.attenuation0);
4764 checkGLcall("glLightf");
4765 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_LINEAR_ATTENUATION,
4766 lightInfo->OriginalParms.attenuation1);
4767 checkGLcall("glLightf");
4768 if (quad_att < lightInfo->OriginalParms.attenuation2)
4769 quad_att = lightInfo->OriginalParms.attenuation2;
4770 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_QUADRATIC_ATTENUATION, quad_att);
4771 checkGLcall("glLightf");
4772 /* FIXME: Range */
4773 break;
4775 case WINED3D_LIGHT_SPOT:
4776 /* Position */
4777 gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
4778 checkGLcall("glLightfv");
4779 /* Direction */
4780 gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_SPOT_DIRECTION, &lightInfo->lightDirn[0]);
4781 checkGLcall("glLightfv");
4782 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, lightInfo->exponent);
4783 checkGLcall("glLightf");
4784 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
4785 checkGLcall("glLightf");
4786 /* Attenuation - Are these right? guessing... */
4787 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_CONSTANT_ATTENUATION,
4788 lightInfo->OriginalParms.attenuation0);
4789 checkGLcall("glLightf");
4790 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_LINEAR_ATTENUATION,
4791 lightInfo->OriginalParms.attenuation1);
4792 checkGLcall("glLightf");
4793 if (quad_att < lightInfo->OriginalParms.attenuation2)
4794 quad_att = lightInfo->OriginalParms.attenuation2;
4795 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_QUADRATIC_ATTENUATION, quad_att);
4796 checkGLcall("glLightf");
4797 /* FIXME: Range */
4798 break;
4800 case WINED3D_LIGHT_DIRECTIONAL:
4801 /* Direction */
4802 /* Note GL uses w position of 0 for direction! */
4803 gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
4804 checkGLcall("glLightfv");
4805 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
4806 checkGLcall("glLightf");
4807 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, 0.0f);
4808 checkGLcall("glLightf");
4809 break;
4811 default:
4812 FIXME("Unrecognized light type %#x.\n", lightInfo->OriginalParms.type);
4815 /* Restore the modelview matrix */
4816 gl_info->gl_ops.gl.p_glPopMatrix();
4818 gl_info->gl_ops.gl.p_glEnable(GL_LIGHT0 + Index);
4819 checkGLcall("glEnable(GL_LIGHT0 + Index)");
4823 static void scissorrect(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4825 const struct wined3d_gl_info *gl_info = context->gl_info;
4826 const RECT *r = &state->scissor_rect;
4828 /* Warning: glScissor uses window coordinates, not viewport coordinates,
4829 * so our viewport correction does not apply. Warning2: Even in windowed
4830 * mode the coords are relative to the window, not the screen. */
4831 TRACE("Setting new scissor rect to %s.\n", wine_dbgstr_rect(r));
4833 if (context->render_offscreen)
4835 gl_info->gl_ops.gl.p_glScissor(r->left, r->top, r->right - r->left, r->bottom - r->top);
4837 else
4839 const struct wined3d_surface *target = state->fb->render_targets[0];
4840 UINT height;
4841 UINT width;
4843 target->get_drawable_size(context, &width, &height);
4844 gl_info->gl_ops.gl.p_glScissor(r->left, height - r->bottom, r->right - r->left, r->bottom - r->top);
4846 checkGLcall("glScissor");
4849 static void indexbuffer(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4851 const struct wined3d_stream_info *stream_info = &context->swapchain->device->stream_info;
4852 const struct wined3d_gl_info *gl_info = context->gl_info;
4854 if (!state->index_buffer || !stream_info->all_vbo)
4856 GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0));
4858 else
4860 struct wined3d_buffer *ib = state->index_buffer;
4861 GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, ib->buffer_object));
4865 static void frontface(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4867 const struct wined3d_gl_info *gl_info = context->gl_info;
4869 if (context->render_offscreen)
4871 gl_info->gl_ops.gl.p_glFrontFace(GL_CCW);
4872 checkGLcall("glFrontFace(GL_CCW)");
4874 else
4876 gl_info->gl_ops.gl.p_glFrontFace(GL_CW);
4877 checkGLcall("glFrontFace(GL_CW)");
4881 static void psorigin_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4883 static BOOL warned;
4885 if (!warned)
4887 WARN("Point sprite coordinate origin switching not supported.\n");
4888 warned = TRUE;
4892 static void psorigin(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4894 const struct wined3d_gl_info *gl_info = context->gl_info;
4895 GLint origin = context->render_offscreen ? GL_LOWER_LEFT : GL_UPPER_LEFT;
4897 if (gl_info->supported[NV_POINT_SPRITE])
4899 GL_EXTCALL(glPointParameteriNV(GL_POINT_SPRITE_COORD_ORIGIN, origin));
4900 checkGLcall("glPointParameteriNV(GL_POINT_SPRITE_COORD_ORIGIN, ...)");
4904 void state_srgbwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4906 const struct wined3d_gl_info *gl_info = context->gl_info;
4907 const struct wined3d_surface *rt = state->fb->render_targets[0];
4909 TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
4911 if (state->render_states[WINED3D_RS_SRGBWRITEENABLE]
4912 && rt->resource.format->flags & WINED3DFMT_FLAG_SRGB_WRITE)
4913 gl_info->gl_ops.gl.p_glEnable(GL_FRAMEBUFFER_SRGB);
4914 else
4915 gl_info->gl_ops.gl.p_glDisable(GL_FRAMEBUFFER_SRGB);
4918 const struct StateEntryTemplate misc_state_template[] = {
4919 { STATE_RENDER(WINED3D_RS_SRCBLEND), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4920 { STATE_RENDER(WINED3D_RS_DESTBLEND), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4921 { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE },
4922 { STATE_RENDER(WINED3D_RS_EDGEANTIALIAS), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4923 { STATE_RENDER(WINED3D_RS_ANTIALIASEDLINEENABLE), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4924 { STATE_RENDER(WINED3D_RS_SEPARATEALPHABLENDENABLE), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4925 { STATE_RENDER(WINED3D_RS_SRCBLENDALPHA), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4926 { STATE_RENDER(WINED3D_RS_DESTBLENDALPHA), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4927 { STATE_RENDER(WINED3D_RS_DESTBLENDALPHA), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4928 { STATE_RENDER(WINED3D_RS_BLENDOPALPHA), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4929 { STATE_STREAMSRC, { STATE_STREAMSRC, streamsrc }, WINED3D_GL_EXT_NONE },
4930 { STATE_VDECL, { STATE_VDECL, vdecl_miscpart }, WINED3D_GL_EXT_NONE },
4931 { STATE_FRONTFACE, { STATE_FRONTFACE, frontface }, WINED3D_GL_EXT_NONE },
4932 { STATE_SCISSORRECT, { STATE_SCISSORRECT, scissorrect }, WINED3D_GL_EXT_NONE },
4933 { STATE_POINTSPRITECOORDORIGIN, { STATE_POINTSPRITECOORDORIGIN, psorigin }, WINED3D_GL_VERSION_2_0 },
4934 { STATE_POINTSPRITECOORDORIGIN, { STATE_POINTSPRITECOORDORIGIN, psorigin_w }, WINED3D_GL_EXT_NONE },
4936 /* TODO: Move shader constant loading to vertex and fragment pipeline respectively, as soon as the pshader and
4937 * vshader loadings are untied from each other
4939 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenv }, WINED3D_GL_EXT_NONE },
4940 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4941 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4942 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4943 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenv }, WINED3D_GL_EXT_NONE },
4944 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4945 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4946 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4947 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenv }, WINED3D_GL_EXT_NONE },
4948 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4949 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4950 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4951 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenv }, WINED3D_GL_EXT_NONE },
4952 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4953 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4954 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4955 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenv }, WINED3D_GL_EXT_NONE },
4956 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4957 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4958 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4959 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenv }, WINED3D_GL_EXT_NONE },
4960 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4961 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4962 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4963 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenv }, WINED3D_GL_EXT_NONE },
4964 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4965 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4966 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4967 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenv }, WINED3D_GL_EXT_NONE },
4968 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4969 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4970 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4971 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE), shader_bumpenv }, WINED3D_GL_EXT_NONE },
4972 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
4973 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE), shader_bumpenv }, WINED3D_GL_EXT_NONE },
4974 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
4975 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE), shader_bumpenv }, WINED3D_GL_EXT_NONE },
4976 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
4977 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE), shader_bumpenv }, WINED3D_GL_EXT_NONE },
4978 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
4979 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE), shader_bumpenv }, WINED3D_GL_EXT_NONE },
4980 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
4981 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE), shader_bumpenv }, WINED3D_GL_EXT_NONE },
4982 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
4983 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE), shader_bumpenv }, WINED3D_GL_EXT_NONE },
4984 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
4985 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), shader_bumpenv }, WINED3D_GL_EXT_NONE },
4986 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
4988 { STATE_VIEWPORT, { STATE_VIEWPORT, viewport_miscpart }, WINED3D_GL_EXT_NONE },
4989 { STATE_INDEXBUFFER, { STATE_INDEXBUFFER, indexbuffer }, ARB_VERTEX_BUFFER_OBJECT },
4990 { STATE_INDEXBUFFER, { STATE_INDEXBUFFER, state_nop }, WINED3D_GL_EXT_NONE },
4991 { STATE_RENDER(WINED3D_RS_ANTIALIAS), { STATE_RENDER(WINED3D_RS_ANTIALIAS), state_antialias }, WINED3D_GL_EXT_NONE },
4992 { STATE_RENDER(WINED3D_RS_TEXTUREPERSPECTIVE), { STATE_RENDER(WINED3D_RS_TEXTUREPERSPECTIVE), state_perspective }, WINED3D_GL_EXT_NONE },
4993 { STATE_RENDER(WINED3D_RS_ZENABLE), { STATE_RENDER(WINED3D_RS_ZENABLE), state_zenable }, WINED3D_GL_EXT_NONE },
4994 { STATE_RENDER(WINED3D_RS_WRAPU), { STATE_RENDER(WINED3D_RS_WRAPU), state_wrapu }, WINED3D_GL_EXT_NONE },
4995 { STATE_RENDER(WINED3D_RS_WRAPV), { STATE_RENDER(WINED3D_RS_WRAPV), state_wrapv }, WINED3D_GL_EXT_NONE },
4996 { STATE_RENDER(WINED3D_RS_FILLMODE), { STATE_RENDER(WINED3D_RS_FILLMODE), state_fillmode }, WINED3D_GL_EXT_NONE },
4997 { STATE_RENDER(WINED3D_RS_SHADEMODE), { STATE_RENDER(WINED3D_RS_SHADEMODE), state_shademode }, WINED3D_GL_EXT_NONE },
4998 { STATE_RENDER(WINED3D_RS_LINEPATTERN), { STATE_RENDER(WINED3D_RS_LINEPATTERN), state_linepattern }, WINED3D_GL_EXT_NONE },
4999 { STATE_RENDER(WINED3D_RS_MONOENABLE), { STATE_RENDER(WINED3D_RS_MONOENABLE), state_monoenable }, WINED3D_GL_EXT_NONE },
5000 { STATE_RENDER(WINED3D_RS_ROP2), { STATE_RENDER(WINED3D_RS_ROP2), state_rop2 }, WINED3D_GL_EXT_NONE },
5001 { STATE_RENDER(WINED3D_RS_PLANEMASK), { STATE_RENDER(WINED3D_RS_PLANEMASK), state_planemask }, WINED3D_GL_EXT_NONE },
5002 { STATE_RENDER(WINED3D_RS_ZWRITEENABLE), { STATE_RENDER(WINED3D_RS_ZWRITEENABLE), state_zwritenable }, WINED3D_GL_EXT_NONE },
5003 { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), state_alpha }, WINED3D_GL_EXT_NONE },
5004 { STATE_RENDER(WINED3D_RS_ALPHAREF), { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE },
5005 { STATE_RENDER(WINED3D_RS_ALPHAFUNC), { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE },
5006 { STATE_RENDER(WINED3D_RS_COLORKEYENABLE), { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE },
5007 { STATE_RENDER(WINED3D_RS_LASTPIXEL), { STATE_RENDER(WINED3D_RS_LASTPIXEL), state_lastpixel }, WINED3D_GL_EXT_NONE },
5008 { STATE_RENDER(WINED3D_RS_CULLMODE), { STATE_RENDER(WINED3D_RS_CULLMODE), state_cullmode }, WINED3D_GL_EXT_NONE },
5009 { STATE_RENDER(WINED3D_RS_ZFUNC), { STATE_RENDER(WINED3D_RS_ZFUNC), state_zfunc }, WINED3D_GL_EXT_NONE },
5010 { STATE_RENDER(WINED3D_RS_DITHERENABLE), { STATE_RENDER(WINED3D_RS_DITHERENABLE), state_ditherenable }, WINED3D_GL_EXT_NONE },
5011 { STATE_RENDER(WINED3D_RS_SUBPIXEL), { STATE_RENDER(WINED3D_RS_SUBPIXEL), state_subpixel }, WINED3D_GL_EXT_NONE },
5012 { STATE_RENDER(WINED3D_RS_SUBPIXELX), { STATE_RENDER(WINED3D_RS_SUBPIXELX), state_subpixelx }, WINED3D_GL_EXT_NONE },
5013 { STATE_RENDER(WINED3D_RS_STIPPLEDALPHA), { STATE_RENDER(WINED3D_RS_STIPPLEDALPHA), state_stippledalpha }, WINED3D_GL_EXT_NONE },
5014 { STATE_RENDER(WINED3D_RS_STIPPLEENABLE), { STATE_RENDER(WINED3D_RS_STIPPLEENABLE), state_stippleenable }, WINED3D_GL_EXT_NONE },
5015 { STATE_RENDER(WINED3D_RS_MIPMAPLODBIAS), { STATE_RENDER(WINED3D_RS_MIPMAPLODBIAS), state_mipmaplodbias }, WINED3D_GL_EXT_NONE },
5016 { STATE_RENDER(WINED3D_RS_ANISOTROPY), { STATE_RENDER(WINED3D_RS_ANISOTROPY), state_anisotropy }, WINED3D_GL_EXT_NONE },
5017 { STATE_RENDER(WINED3D_RS_FLUSHBATCH), { STATE_RENDER(WINED3D_RS_FLUSHBATCH), state_flushbatch }, WINED3D_GL_EXT_NONE },
5018 { STATE_RENDER(WINED3D_RS_TRANSLUCENTSORTINDEPENDENT),{ STATE_RENDER(WINED3D_RS_TRANSLUCENTSORTINDEPENDENT),state_translucentsi }, WINED3D_GL_EXT_NONE },
5019 { STATE_RENDER(WINED3D_RS_STENCILENABLE), { STATE_RENDER(WINED3D_RS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE },
5020 { STATE_RENDER(WINED3D_RS_STENCILFAIL), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5021 { STATE_RENDER(WINED3D_RS_STENCILZFAIL), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5022 { STATE_RENDER(WINED3D_RS_STENCILPASS), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5023 { STATE_RENDER(WINED3D_RS_STENCILFUNC), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5024 { STATE_RENDER(WINED3D_RS_STENCILREF), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5025 { STATE_RENDER(WINED3D_RS_STENCILMASK), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5026 { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), state_stencilwrite2s}, EXT_STENCIL_TWO_SIDE },
5027 { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), state_stencilwrite }, WINED3D_GL_EXT_NONE },
5028 { STATE_RENDER(WINED3D_RS_TWOSIDEDSTENCILMODE), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5029 { STATE_RENDER(WINED3D_RS_CCW_STENCILFAIL), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5030 { STATE_RENDER(WINED3D_RS_CCW_STENCILZFAIL), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5031 { STATE_RENDER(WINED3D_RS_CCW_STENCILPASS), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5032 { STATE_RENDER(WINED3D_RS_CCW_STENCILFUNC), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5033 { STATE_RENDER(WINED3D_RS_WRAP0), { STATE_RENDER(WINED3D_RS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE },
5034 { STATE_RENDER(WINED3D_RS_WRAP1), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5035 { STATE_RENDER(WINED3D_RS_WRAP2), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5036 { STATE_RENDER(WINED3D_RS_WRAP3), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5037 { STATE_RENDER(WINED3D_RS_WRAP4), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5038 { STATE_RENDER(WINED3D_RS_WRAP5), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5039 { STATE_RENDER(WINED3D_RS_WRAP6), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5040 { STATE_RENDER(WINED3D_RS_WRAP7), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5041 { STATE_RENDER(WINED3D_RS_WRAP8), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5042 { STATE_RENDER(WINED3D_RS_WRAP9), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5043 { STATE_RENDER(WINED3D_RS_WRAP10), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5044 { STATE_RENDER(WINED3D_RS_WRAP11), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5045 { STATE_RENDER(WINED3D_RS_WRAP12), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5046 { STATE_RENDER(WINED3D_RS_WRAP13), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5047 { STATE_RENDER(WINED3D_RS_WRAP14), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5048 { STATE_RENDER(WINED3D_RS_WRAP15), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5049 { STATE_RENDER(WINED3D_RS_EXTENTS), { STATE_RENDER(WINED3D_RS_EXTENTS), state_extents }, WINED3D_GL_EXT_NONE },
5050 { STATE_RENDER(WINED3D_RS_COLORKEYBLENDENABLE), { STATE_RENDER(WINED3D_RS_COLORKEYBLENDENABLE), state_ckeyblend }, WINED3D_GL_EXT_NONE },
5051 { STATE_RENDER(WINED3D_RS_SOFTWAREVERTEXPROCESSING), { STATE_RENDER(WINED3D_RS_SOFTWAREVERTEXPROCESSING), state_swvp }, WINED3D_GL_EXT_NONE },
5052 { STATE_RENDER(WINED3D_RS_PATCHEDGESTYLE), { STATE_RENDER(WINED3D_RS_PATCHEDGESTYLE), state_patchedgestyle}, WINED3D_GL_EXT_NONE },
5053 { STATE_RENDER(WINED3D_RS_PATCHSEGMENTS), { STATE_RENDER(WINED3D_RS_PATCHSEGMENTS), state_patchsegments }, WINED3D_GL_EXT_NONE },
5054 { STATE_RENDER(WINED3D_RS_POSITIONDEGREE), { STATE_RENDER(WINED3D_RS_POSITIONDEGREE), state_positiondegree}, WINED3D_GL_EXT_NONE },
5055 { STATE_RENDER(WINED3D_RS_NORMALDEGREE), { STATE_RENDER(WINED3D_RS_NORMALDEGREE), state_normaldegree }, WINED3D_GL_EXT_NONE },
5056 { STATE_RENDER(WINED3D_RS_MINTESSELLATIONLEVEL), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5057 { STATE_RENDER(WINED3D_RS_MAXTESSELLATIONLEVEL), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5058 { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_X), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5059 { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_Y), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5060 { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_Z), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5061 { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_W), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5062 { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),{ STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),state_nvdb }, EXT_DEPTH_BOUNDS_TEST },
5063 { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),{ STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),state_tessellation }, WINED3D_GL_EXT_NONE },
5064 { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), state_msaa }, ARB_MULTISAMPLE },
5065 { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), state_msaa_w }, WINED3D_GL_EXT_NONE },
5066 { STATE_RENDER(WINED3D_RS_MULTISAMPLEMASK), { STATE_RENDER(WINED3D_RS_MULTISAMPLEMASK), state_multisampmask }, WINED3D_GL_EXT_NONE },
5067 { STATE_RENDER(WINED3D_RS_DEBUGMONITORTOKEN), { STATE_RENDER(WINED3D_RS_DEBUGMONITORTOKEN), state_debug_monitor }, WINED3D_GL_EXT_NONE },
5068 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), state_colorwrite0 }, EXT_DRAW_BUFFERS2 },
5069 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), state_colorwrite }, WINED3D_GL_EXT_NONE },
5070 { STATE_RENDER(WINED3D_RS_BLENDOP), { STATE_RENDER(WINED3D_RS_BLENDOP), state_blendop }, EXT_BLEND_MINMAX },
5071 { STATE_RENDER(WINED3D_RS_BLENDOP), { STATE_RENDER(WINED3D_RS_BLENDOP), state_blendop_w }, WINED3D_GL_EXT_NONE },
5072 { STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE), { STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE), state_scissor }, WINED3D_GL_EXT_NONE },
5073 { STATE_RENDER(WINED3D_RS_SLOPESCALEDEPTHBIAS), { STATE_RENDER(WINED3D_RS_DEPTHBIAS), NULL }, WINED3D_GL_EXT_NONE },
5074 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), state_colorwrite1 }, EXT_DRAW_BUFFERS2 },
5075 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5076 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), state_colorwrite2 }, EXT_DRAW_BUFFERS2 },
5077 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5078 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), state_colorwrite3 }, EXT_DRAW_BUFFERS2 },
5079 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5080 { STATE_RENDER(WINED3D_RS_BLENDFACTOR), { STATE_RENDER(WINED3D_RS_BLENDFACTOR), state_blendfactor }, EXT_BLEND_COLOR },
5081 { STATE_RENDER(WINED3D_RS_BLENDFACTOR), { STATE_RENDER(WINED3D_RS_BLENDFACTOR), state_blendfactor_w }, WINED3D_GL_EXT_NONE },
5082 { STATE_RENDER(WINED3D_RS_DEPTHBIAS), { STATE_RENDER(WINED3D_RS_DEPTHBIAS), state_depthbias }, WINED3D_GL_EXT_NONE },
5083 { STATE_RENDER(WINED3D_RS_ZVISIBLE), { STATE_RENDER(WINED3D_RS_ZVISIBLE), state_zvisible }, WINED3D_GL_EXT_NONE },
5084 /* Samplers */
5085 { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler }, WINED3D_GL_EXT_NONE },
5086 { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler }, WINED3D_GL_EXT_NONE },
5087 { STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler }, WINED3D_GL_EXT_NONE },
5088 { STATE_SAMPLER(3), { STATE_SAMPLER(3), sampler }, WINED3D_GL_EXT_NONE },
5089 { STATE_SAMPLER(4), { STATE_SAMPLER(4), sampler }, WINED3D_GL_EXT_NONE },
5090 { STATE_SAMPLER(5), { STATE_SAMPLER(5), sampler }, WINED3D_GL_EXT_NONE },
5091 { STATE_SAMPLER(6), { STATE_SAMPLER(6), sampler }, WINED3D_GL_EXT_NONE },
5092 { STATE_SAMPLER(7), { STATE_SAMPLER(7), sampler }, WINED3D_GL_EXT_NONE },
5093 { STATE_SAMPLER(8), { STATE_SAMPLER(8), sampler }, WINED3D_GL_EXT_NONE },
5094 { STATE_SAMPLER(9), { STATE_SAMPLER(9), sampler }, WINED3D_GL_EXT_NONE },
5095 { STATE_SAMPLER(10), { STATE_SAMPLER(10), sampler }, WINED3D_GL_EXT_NONE },
5096 { STATE_SAMPLER(11), { STATE_SAMPLER(11), sampler }, WINED3D_GL_EXT_NONE },
5097 { STATE_SAMPLER(12), { STATE_SAMPLER(12), sampler }, WINED3D_GL_EXT_NONE },
5098 { STATE_SAMPLER(13), { STATE_SAMPLER(13), sampler }, WINED3D_GL_EXT_NONE },
5099 { STATE_SAMPLER(14), { STATE_SAMPLER(14), sampler }, WINED3D_GL_EXT_NONE },
5100 { STATE_SAMPLER(15), { STATE_SAMPLER(15), sampler }, WINED3D_GL_EXT_NONE },
5101 { STATE_SAMPLER(16), /* Vertex sampler 0 */ { STATE_SAMPLER(16), sampler }, WINED3D_GL_EXT_NONE },
5102 { STATE_SAMPLER(17), /* Vertex sampler 1 */ { STATE_SAMPLER(17), sampler }, WINED3D_GL_EXT_NONE },
5103 { STATE_SAMPLER(18), /* Vertex sampler 2 */ { STATE_SAMPLER(18), sampler }, WINED3D_GL_EXT_NONE },
5104 { STATE_SAMPLER(19), /* Vertex sampler 3 */ { STATE_SAMPLER(19), sampler }, WINED3D_GL_EXT_NONE },
5105 { STATE_BASEVERTEXINDEX, { STATE_BASEVERTEXINDEX, state_nop, }, ARB_DRAW_ELEMENTS_BASE_VERTEX },
5106 { STATE_BASEVERTEXINDEX, { STATE_STREAMSRC, NULL, }, WINED3D_GL_EXT_NONE },
5107 { STATE_FRAMEBUFFER, { STATE_FRAMEBUFFER, context_state_fb }, WINED3D_GL_EXT_NONE },
5108 { STATE_PIXELSHADER, { STATE_PIXELSHADER, context_state_drawbuf},WINED3D_GL_EXT_NONE },
5109 { STATE_GEOMETRY_SHADER, { STATE_GEOMETRY_SHADER, state_geometry_shader}, WINED3D_GL_EXT_NONE },
5110 {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE },
5113 const struct StateEntryTemplate vp_ffp_states[] =
5115 { STATE_VDECL, { STATE_VDECL, vertexdeclaration }, WINED3D_GL_EXT_NONE },
5116 { STATE_VSHADER, { STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
5117 { STATE_MATERIAL, { STATE_RENDER(WINED3D_RS_SPECULARENABLE), NULL }, WINED3D_GL_EXT_NONE },
5118 { STATE_RENDER(WINED3D_RS_SPECULARENABLE), { STATE_RENDER(WINED3D_RS_SPECULARENABLE), state_specularenable}, WINED3D_GL_EXT_NONE },
5119 /* Clip planes */
5120 { STATE_CLIPPLANE(0), { STATE_CLIPPLANE(0), clipplane }, WINED3D_GL_EXT_NONE },
5121 { STATE_CLIPPLANE(1), { STATE_CLIPPLANE(1), clipplane }, WINED3D_GL_EXT_NONE },
5122 { STATE_CLIPPLANE(2), { STATE_CLIPPLANE(2), clipplane }, WINED3D_GL_EXT_NONE },
5123 { STATE_CLIPPLANE(3), { STATE_CLIPPLANE(3), clipplane }, WINED3D_GL_EXT_NONE },
5124 { STATE_CLIPPLANE(4), { STATE_CLIPPLANE(4), clipplane }, WINED3D_GL_EXT_NONE },
5125 { STATE_CLIPPLANE(5), { STATE_CLIPPLANE(5), clipplane }, WINED3D_GL_EXT_NONE },
5126 { STATE_CLIPPLANE(6), { STATE_CLIPPLANE(6), clipplane }, WINED3D_GL_EXT_NONE },
5127 { STATE_CLIPPLANE(7), { STATE_CLIPPLANE(7), clipplane }, WINED3D_GL_EXT_NONE },
5128 { STATE_CLIPPLANE(8), { STATE_CLIPPLANE(8), clipplane }, WINED3D_GL_EXT_NONE },
5129 { STATE_CLIPPLANE(9), { STATE_CLIPPLANE(9), clipplane }, WINED3D_GL_EXT_NONE },
5130 { STATE_CLIPPLANE(10), { STATE_CLIPPLANE(10), clipplane }, WINED3D_GL_EXT_NONE },
5131 { STATE_CLIPPLANE(11), { STATE_CLIPPLANE(11), clipplane }, WINED3D_GL_EXT_NONE },
5132 { STATE_CLIPPLANE(12), { STATE_CLIPPLANE(12), clipplane }, WINED3D_GL_EXT_NONE },
5133 { STATE_CLIPPLANE(13), { STATE_CLIPPLANE(13), clipplane }, WINED3D_GL_EXT_NONE },
5134 { STATE_CLIPPLANE(14), { STATE_CLIPPLANE(14), clipplane }, WINED3D_GL_EXT_NONE },
5135 { STATE_CLIPPLANE(15), { STATE_CLIPPLANE(15), clipplane }, WINED3D_GL_EXT_NONE },
5136 { STATE_CLIPPLANE(16), { STATE_CLIPPLANE(16), clipplane }, WINED3D_GL_EXT_NONE },
5137 { STATE_CLIPPLANE(17), { STATE_CLIPPLANE(17), clipplane }, WINED3D_GL_EXT_NONE },
5138 { STATE_CLIPPLANE(18), { STATE_CLIPPLANE(18), clipplane }, WINED3D_GL_EXT_NONE },
5139 { STATE_CLIPPLANE(19), { STATE_CLIPPLANE(19), clipplane }, WINED3D_GL_EXT_NONE },
5140 { STATE_CLIPPLANE(20), { STATE_CLIPPLANE(20), clipplane }, WINED3D_GL_EXT_NONE },
5141 { STATE_CLIPPLANE(21), { STATE_CLIPPLANE(21), clipplane }, WINED3D_GL_EXT_NONE },
5142 { STATE_CLIPPLANE(22), { STATE_CLIPPLANE(22), clipplane }, WINED3D_GL_EXT_NONE },
5143 { STATE_CLIPPLANE(23), { STATE_CLIPPLANE(23), clipplane }, WINED3D_GL_EXT_NONE },
5144 { STATE_CLIPPLANE(24), { STATE_CLIPPLANE(24), clipplane }, WINED3D_GL_EXT_NONE },
5145 { STATE_CLIPPLANE(25), { STATE_CLIPPLANE(25), clipplane }, WINED3D_GL_EXT_NONE },
5146 { STATE_CLIPPLANE(26), { STATE_CLIPPLANE(26), clipplane }, WINED3D_GL_EXT_NONE },
5147 { STATE_CLIPPLANE(27), { STATE_CLIPPLANE(27), clipplane }, WINED3D_GL_EXT_NONE },
5148 { STATE_CLIPPLANE(28), { STATE_CLIPPLANE(28), clipplane }, WINED3D_GL_EXT_NONE },
5149 { STATE_CLIPPLANE(29), { STATE_CLIPPLANE(29), clipplane }, WINED3D_GL_EXT_NONE },
5150 { STATE_CLIPPLANE(30), { STATE_CLIPPLANE(30), clipplane }, WINED3D_GL_EXT_NONE },
5151 { STATE_CLIPPLANE(31), { STATE_CLIPPLANE(31), clipplane }, WINED3D_GL_EXT_NONE },
5152 /* Lights */
5153 { STATE_LIGHT_TYPE, { STATE_LIGHT_TYPE, state_nop }, WINED3D_GL_EXT_NONE },
5154 { STATE_ACTIVELIGHT(0), { STATE_ACTIVELIGHT(0), light }, WINED3D_GL_EXT_NONE },
5155 { STATE_ACTIVELIGHT(1), { STATE_ACTIVELIGHT(1), light }, WINED3D_GL_EXT_NONE },
5156 { STATE_ACTIVELIGHT(2), { STATE_ACTIVELIGHT(2), light }, WINED3D_GL_EXT_NONE },
5157 { STATE_ACTIVELIGHT(3), { STATE_ACTIVELIGHT(3), light }, WINED3D_GL_EXT_NONE },
5158 { STATE_ACTIVELIGHT(4), { STATE_ACTIVELIGHT(4), light }, WINED3D_GL_EXT_NONE },
5159 { STATE_ACTIVELIGHT(5), { STATE_ACTIVELIGHT(5), light }, WINED3D_GL_EXT_NONE },
5160 { STATE_ACTIVELIGHT(6), { STATE_ACTIVELIGHT(6), light }, WINED3D_GL_EXT_NONE },
5161 { STATE_ACTIVELIGHT(7), { STATE_ACTIVELIGHT(7), light }, WINED3D_GL_EXT_NONE },
5162 /* Viewport */
5163 { STATE_VIEWPORT, { STATE_VIEWPORT, viewport_vertexpart }, WINED3D_GL_EXT_NONE },
5164 /* Transform states follow */
5165 { STATE_TRANSFORM(WINED3D_TS_VIEW), { STATE_TRANSFORM(WINED3D_TS_VIEW), transform_view }, WINED3D_GL_EXT_NONE },
5166 { STATE_TRANSFORM(WINED3D_TS_PROJECTION), { STATE_TRANSFORM(WINED3D_TS_PROJECTION), transform_projection}, WINED3D_GL_EXT_NONE },
5167 { STATE_TRANSFORM(WINED3D_TS_TEXTURE0), { STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5168 { STATE_TRANSFORM(WINED3D_TS_TEXTURE1), { STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5169 { STATE_TRANSFORM(WINED3D_TS_TEXTURE2), { STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5170 { STATE_TRANSFORM(WINED3D_TS_TEXTURE3), { STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5171 { STATE_TRANSFORM(WINED3D_TS_TEXTURE4), { STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5172 { STATE_TRANSFORM(WINED3D_TS_TEXTURE5), { STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5173 { STATE_TRANSFORM(WINED3D_TS_TEXTURE6), { STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5174 { STATE_TRANSFORM(WINED3D_TS_TEXTURE7), { STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5175 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 0)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 0)), transform_world }, WINED3D_GL_EXT_NONE },
5176 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 1)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 1)), transform_worldex }, WINED3D_GL_EXT_NONE },
5177 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 2)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 2)), transform_worldex }, WINED3D_GL_EXT_NONE },
5178 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 3)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 3)), transform_worldex }, WINED3D_GL_EXT_NONE },
5179 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 4)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 4)), transform_worldex }, WINED3D_GL_EXT_NONE },
5180 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 5)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 5)), transform_worldex }, WINED3D_GL_EXT_NONE },
5181 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 6)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 6)), transform_worldex }, WINED3D_GL_EXT_NONE },
5182 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 7)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 7)), transform_worldex }, WINED3D_GL_EXT_NONE },
5183 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 8)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 8)), transform_worldex }, WINED3D_GL_EXT_NONE },
5184 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 9)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 9)), transform_worldex }, WINED3D_GL_EXT_NONE },
5185 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 10)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 10)), transform_worldex }, WINED3D_GL_EXT_NONE },
5186 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 11)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 11)), transform_worldex }, WINED3D_GL_EXT_NONE },
5187 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 12)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 12)), transform_worldex }, WINED3D_GL_EXT_NONE },
5188 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 13)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 13)), transform_worldex }, WINED3D_GL_EXT_NONE },
5189 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 14)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 14)), transform_worldex }, WINED3D_GL_EXT_NONE },
5190 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 15)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 15)), transform_worldex }, WINED3D_GL_EXT_NONE },
5191 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 16)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 16)), transform_worldex }, WINED3D_GL_EXT_NONE },
5192 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 17)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 17)), transform_worldex }, WINED3D_GL_EXT_NONE },
5193 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 18)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 18)), transform_worldex }, WINED3D_GL_EXT_NONE },
5194 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 19)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 19)), transform_worldex }, WINED3D_GL_EXT_NONE },
5195 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 20)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 20)), transform_worldex }, WINED3D_GL_EXT_NONE },
5196 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 21)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 21)), transform_worldex }, WINED3D_GL_EXT_NONE },
5197 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 22)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 22)), transform_worldex }, WINED3D_GL_EXT_NONE },
5198 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 23)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 23)), transform_worldex }, WINED3D_GL_EXT_NONE },
5199 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 24)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 24)), transform_worldex }, WINED3D_GL_EXT_NONE },
5200 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 25)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 25)), transform_worldex }, WINED3D_GL_EXT_NONE },
5201 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 26)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 26)), transform_worldex }, WINED3D_GL_EXT_NONE },
5202 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 27)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 27)), transform_worldex }, WINED3D_GL_EXT_NONE },
5203 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 28)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 28)), transform_worldex }, WINED3D_GL_EXT_NONE },
5204 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 29)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 29)), transform_worldex }, WINED3D_GL_EXT_NONE },
5205 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 30)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 30)), transform_worldex }, WINED3D_GL_EXT_NONE },
5206 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 31)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 31)), transform_worldex }, WINED3D_GL_EXT_NONE },
5207 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 32)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 32)), transform_worldex }, WINED3D_GL_EXT_NONE },
5208 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 33)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 33)), transform_worldex }, WINED3D_GL_EXT_NONE },
5209 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 34)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 34)), transform_worldex }, WINED3D_GL_EXT_NONE },
5210 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 35)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 35)), transform_worldex }, WINED3D_GL_EXT_NONE },
5211 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 36)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 36)), transform_worldex }, WINED3D_GL_EXT_NONE },
5212 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 37)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 37)), transform_worldex }, WINED3D_GL_EXT_NONE },
5213 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 38)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 38)), transform_worldex }, WINED3D_GL_EXT_NONE },
5214 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 39)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 39)), transform_worldex }, WINED3D_GL_EXT_NONE },
5215 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 40)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 40)), transform_worldex }, WINED3D_GL_EXT_NONE },
5216 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 41)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 41)), transform_worldex }, WINED3D_GL_EXT_NONE },
5217 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 42)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 42)), transform_worldex }, WINED3D_GL_EXT_NONE },
5218 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 43)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 43)), transform_worldex }, WINED3D_GL_EXT_NONE },
5219 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 44)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 44)), transform_worldex }, WINED3D_GL_EXT_NONE },
5220 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 45)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 45)), transform_worldex }, WINED3D_GL_EXT_NONE },
5221 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 46)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 46)), transform_worldex }, WINED3D_GL_EXT_NONE },
5222 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 47)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 47)), transform_worldex }, WINED3D_GL_EXT_NONE },
5223 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 48)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 48)), transform_worldex }, WINED3D_GL_EXT_NONE },
5224 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 49)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 49)), transform_worldex }, WINED3D_GL_EXT_NONE },
5225 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 50)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 50)), transform_worldex }, WINED3D_GL_EXT_NONE },
5226 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 51)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 51)), transform_worldex }, WINED3D_GL_EXT_NONE },
5227 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 52)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 52)), transform_worldex }, WINED3D_GL_EXT_NONE },
5228 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 53)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 53)), transform_worldex }, WINED3D_GL_EXT_NONE },
5229 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 54)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 54)), transform_worldex }, WINED3D_GL_EXT_NONE },
5230 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 55)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 55)), transform_worldex }, WINED3D_GL_EXT_NONE },
5231 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 56)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 56)), transform_worldex }, WINED3D_GL_EXT_NONE },
5232 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 57)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 57)), transform_worldex }, WINED3D_GL_EXT_NONE },
5233 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 58)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 58)), transform_worldex }, WINED3D_GL_EXT_NONE },
5234 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 59)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 59)), transform_worldex }, WINED3D_GL_EXT_NONE },
5235 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 60)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 60)), transform_worldex }, WINED3D_GL_EXT_NONE },
5236 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 61)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 61)), transform_worldex }, WINED3D_GL_EXT_NONE },
5237 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 62)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 62)), transform_worldex }, WINED3D_GL_EXT_NONE },
5238 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 63)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 63)), transform_worldex }, WINED3D_GL_EXT_NONE },
5239 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 64)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 64)), transform_worldex }, WINED3D_GL_EXT_NONE },
5240 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 65)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 65)), transform_worldex }, WINED3D_GL_EXT_NONE },
5241 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 66)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 66)), transform_worldex }, WINED3D_GL_EXT_NONE },
5242 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 67)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 67)), transform_worldex }, WINED3D_GL_EXT_NONE },
5243 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 68)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 68)), transform_worldex }, WINED3D_GL_EXT_NONE },
5244 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 69)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 69)), transform_worldex }, WINED3D_GL_EXT_NONE },
5245 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 70)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 70)), transform_worldex }, WINED3D_GL_EXT_NONE },
5246 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 71)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 71)), transform_worldex }, WINED3D_GL_EXT_NONE },
5247 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 72)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 72)), transform_worldex }, WINED3D_GL_EXT_NONE },
5248 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 73)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 73)), transform_worldex }, WINED3D_GL_EXT_NONE },
5249 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 74)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 74)), transform_worldex }, WINED3D_GL_EXT_NONE },
5250 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 75)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 75)), transform_worldex }, WINED3D_GL_EXT_NONE },
5251 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 76)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 76)), transform_worldex }, WINED3D_GL_EXT_NONE },
5252 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 77)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 77)), transform_worldex }, WINED3D_GL_EXT_NONE },
5253 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 78)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 78)), transform_worldex }, WINED3D_GL_EXT_NONE },
5254 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 79)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 79)), transform_worldex }, WINED3D_GL_EXT_NONE },
5255 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 80)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 80)), transform_worldex }, WINED3D_GL_EXT_NONE },
5256 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 81)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 81)), transform_worldex }, WINED3D_GL_EXT_NONE },
5257 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 82)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 82)), transform_worldex }, WINED3D_GL_EXT_NONE },
5258 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 83)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 83)), transform_worldex }, WINED3D_GL_EXT_NONE },
5259 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 84)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 84)), transform_worldex }, WINED3D_GL_EXT_NONE },
5260 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 85)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 85)), transform_worldex }, WINED3D_GL_EXT_NONE },
5261 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 86)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 86)), transform_worldex }, WINED3D_GL_EXT_NONE },
5262 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 87)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 87)), transform_worldex }, WINED3D_GL_EXT_NONE },
5263 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 88)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 88)), transform_worldex }, WINED3D_GL_EXT_NONE },
5264 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 89)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 89)), transform_worldex }, WINED3D_GL_EXT_NONE },
5265 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 90)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 90)), transform_worldex }, WINED3D_GL_EXT_NONE },
5266 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 91)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 91)), transform_worldex }, WINED3D_GL_EXT_NONE },
5267 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 92)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 92)), transform_worldex }, WINED3D_GL_EXT_NONE },
5268 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 93)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 93)), transform_worldex }, WINED3D_GL_EXT_NONE },
5269 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 94)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 94)), transform_worldex }, WINED3D_GL_EXT_NONE },
5270 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 95)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 95)), transform_worldex }, WINED3D_GL_EXT_NONE },
5271 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 96)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 96)), transform_worldex }, WINED3D_GL_EXT_NONE },
5272 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 97)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 97)), transform_worldex }, WINED3D_GL_EXT_NONE },
5273 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 98)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 98)), transform_worldex }, WINED3D_GL_EXT_NONE },
5274 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 99)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 99)), transform_worldex }, WINED3D_GL_EXT_NONE },
5275 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(100)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(100)), transform_worldex }, WINED3D_GL_EXT_NONE },
5276 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(101)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(101)), transform_worldex }, WINED3D_GL_EXT_NONE },
5277 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(102)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(102)), transform_worldex }, WINED3D_GL_EXT_NONE },
5278 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(103)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(103)), transform_worldex }, WINED3D_GL_EXT_NONE },
5279 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(104)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(104)), transform_worldex }, WINED3D_GL_EXT_NONE },
5280 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(105)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(105)), transform_worldex }, WINED3D_GL_EXT_NONE },
5281 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(106)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(106)), transform_worldex }, WINED3D_GL_EXT_NONE },
5282 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(107)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(107)), transform_worldex }, WINED3D_GL_EXT_NONE },
5283 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(108)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(108)), transform_worldex }, WINED3D_GL_EXT_NONE },
5284 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(109)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(109)), transform_worldex }, WINED3D_GL_EXT_NONE },
5285 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(110)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(110)), transform_worldex }, WINED3D_GL_EXT_NONE },
5286 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(111)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(111)), transform_worldex }, WINED3D_GL_EXT_NONE },
5287 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(112)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(112)), transform_worldex }, WINED3D_GL_EXT_NONE },
5288 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(113)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(113)), transform_worldex }, WINED3D_GL_EXT_NONE },
5289 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(114)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(114)), transform_worldex }, WINED3D_GL_EXT_NONE },
5290 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(115)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(115)), transform_worldex }, WINED3D_GL_EXT_NONE },
5291 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(116)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(116)), transform_worldex }, WINED3D_GL_EXT_NONE },
5292 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(117)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(117)), transform_worldex }, WINED3D_GL_EXT_NONE },
5293 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(118)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(118)), transform_worldex }, WINED3D_GL_EXT_NONE },
5294 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(119)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(119)), transform_worldex }, WINED3D_GL_EXT_NONE },
5295 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(120)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(120)), transform_worldex }, WINED3D_GL_EXT_NONE },
5296 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(121)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(121)), transform_worldex }, WINED3D_GL_EXT_NONE },
5297 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(122)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(122)), transform_worldex }, WINED3D_GL_EXT_NONE },
5298 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(123)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(123)), transform_worldex }, WINED3D_GL_EXT_NONE },
5299 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(124)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(124)), transform_worldex }, WINED3D_GL_EXT_NONE },
5300 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(125)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(125)), transform_worldex }, WINED3D_GL_EXT_NONE },
5301 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(126)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(126)), transform_worldex }, WINED3D_GL_EXT_NONE },
5302 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(127)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(127)), transform_worldex }, WINED3D_GL_EXT_NONE },
5303 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(128)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(128)), transform_worldex }, WINED3D_GL_EXT_NONE },
5304 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(129)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(129)), transform_worldex }, WINED3D_GL_EXT_NONE },
5305 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(130)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(130)), transform_worldex }, WINED3D_GL_EXT_NONE },
5306 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(131)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(131)), transform_worldex }, WINED3D_GL_EXT_NONE },
5307 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(132)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(132)), transform_worldex }, WINED3D_GL_EXT_NONE },
5308 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(133)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(133)), transform_worldex }, WINED3D_GL_EXT_NONE },
5309 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(134)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(134)), transform_worldex }, WINED3D_GL_EXT_NONE },
5310 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(135)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(135)), transform_worldex }, WINED3D_GL_EXT_NONE },
5311 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(136)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(136)), transform_worldex }, WINED3D_GL_EXT_NONE },
5312 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(137)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(137)), transform_worldex }, WINED3D_GL_EXT_NONE },
5313 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(138)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(138)), transform_worldex }, WINED3D_GL_EXT_NONE },
5314 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(139)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(139)), transform_worldex }, WINED3D_GL_EXT_NONE },
5315 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(140)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(140)), transform_worldex }, WINED3D_GL_EXT_NONE },
5316 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(141)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(141)), transform_worldex }, WINED3D_GL_EXT_NONE },
5317 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(142)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(142)), transform_worldex }, WINED3D_GL_EXT_NONE },
5318 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(143)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(143)), transform_worldex }, WINED3D_GL_EXT_NONE },
5319 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(144)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(144)), transform_worldex }, WINED3D_GL_EXT_NONE },
5320 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(145)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(145)), transform_worldex }, WINED3D_GL_EXT_NONE },
5321 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(146)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(146)), transform_worldex }, WINED3D_GL_EXT_NONE },
5322 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(147)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(147)), transform_worldex }, WINED3D_GL_EXT_NONE },
5323 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(148)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(148)), transform_worldex }, WINED3D_GL_EXT_NONE },
5324 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(149)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(149)), transform_worldex }, WINED3D_GL_EXT_NONE },
5325 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(150)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(150)), transform_worldex }, WINED3D_GL_EXT_NONE },
5326 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(151)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(151)), transform_worldex }, WINED3D_GL_EXT_NONE },
5327 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(152)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(152)), transform_worldex }, WINED3D_GL_EXT_NONE },
5328 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(153)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(153)), transform_worldex }, WINED3D_GL_EXT_NONE },
5329 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(154)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(154)), transform_worldex }, WINED3D_GL_EXT_NONE },
5330 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(155)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(155)), transform_worldex }, WINED3D_GL_EXT_NONE },
5331 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(156)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(156)), transform_worldex }, WINED3D_GL_EXT_NONE },
5332 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(157)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(157)), transform_worldex }, WINED3D_GL_EXT_NONE },
5333 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(158)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(158)), transform_worldex }, WINED3D_GL_EXT_NONE },
5334 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(159)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(159)), transform_worldex }, WINED3D_GL_EXT_NONE },
5335 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(160)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(160)), transform_worldex }, WINED3D_GL_EXT_NONE },
5336 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(161)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(161)), transform_worldex }, WINED3D_GL_EXT_NONE },
5337 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(162)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(162)), transform_worldex }, WINED3D_GL_EXT_NONE },
5338 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(163)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(163)), transform_worldex }, WINED3D_GL_EXT_NONE },
5339 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(164)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(164)), transform_worldex }, WINED3D_GL_EXT_NONE },
5340 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(165)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(165)), transform_worldex }, WINED3D_GL_EXT_NONE },
5341 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(166)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(166)), transform_worldex }, WINED3D_GL_EXT_NONE },
5342 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(167)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(167)), transform_worldex }, WINED3D_GL_EXT_NONE },
5343 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(168)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(168)), transform_worldex }, WINED3D_GL_EXT_NONE },
5344 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(169)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(169)), transform_worldex }, WINED3D_GL_EXT_NONE },
5345 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(170)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(170)), transform_worldex }, WINED3D_GL_EXT_NONE },
5346 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(171)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(171)), transform_worldex }, WINED3D_GL_EXT_NONE },
5347 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(172)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(172)), transform_worldex }, WINED3D_GL_EXT_NONE },
5348 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(173)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(173)), transform_worldex }, WINED3D_GL_EXT_NONE },
5349 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(174)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(174)), transform_worldex }, WINED3D_GL_EXT_NONE },
5350 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(175)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(175)), transform_worldex }, WINED3D_GL_EXT_NONE },
5351 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(176)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(176)), transform_worldex }, WINED3D_GL_EXT_NONE },
5352 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(177)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(177)), transform_worldex }, WINED3D_GL_EXT_NONE },
5353 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(178)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(178)), transform_worldex }, WINED3D_GL_EXT_NONE },
5354 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(179)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(179)), transform_worldex }, WINED3D_GL_EXT_NONE },
5355 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(180)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(180)), transform_worldex }, WINED3D_GL_EXT_NONE },
5356 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(181)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(181)), transform_worldex }, WINED3D_GL_EXT_NONE },
5357 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(182)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(182)), transform_worldex }, WINED3D_GL_EXT_NONE },
5358 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(183)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(183)), transform_worldex }, WINED3D_GL_EXT_NONE },
5359 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(184)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(184)), transform_worldex }, WINED3D_GL_EXT_NONE },
5360 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(185)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(185)), transform_worldex }, WINED3D_GL_EXT_NONE },
5361 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(186)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(186)), transform_worldex }, WINED3D_GL_EXT_NONE },
5362 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(187)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(187)), transform_worldex }, WINED3D_GL_EXT_NONE },
5363 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(188)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(188)), transform_worldex }, WINED3D_GL_EXT_NONE },
5364 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(189)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(189)), transform_worldex }, WINED3D_GL_EXT_NONE },
5365 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(190)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(190)), transform_worldex }, WINED3D_GL_EXT_NONE },
5366 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(191)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(191)), transform_worldex }, WINED3D_GL_EXT_NONE },
5367 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(192)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(192)), transform_worldex }, WINED3D_GL_EXT_NONE },
5368 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(193)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(193)), transform_worldex }, WINED3D_GL_EXT_NONE },
5369 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(194)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(194)), transform_worldex }, WINED3D_GL_EXT_NONE },
5370 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(195)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(195)), transform_worldex }, WINED3D_GL_EXT_NONE },
5371 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(196)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(196)), transform_worldex }, WINED3D_GL_EXT_NONE },
5372 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(197)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(197)), transform_worldex }, WINED3D_GL_EXT_NONE },
5373 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(198)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(198)), transform_worldex }, WINED3D_GL_EXT_NONE },
5374 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(199)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(199)), transform_worldex }, WINED3D_GL_EXT_NONE },
5375 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(200)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(200)), transform_worldex }, WINED3D_GL_EXT_NONE },
5376 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(201)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(201)), transform_worldex }, WINED3D_GL_EXT_NONE },
5377 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(202)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(202)), transform_worldex }, WINED3D_GL_EXT_NONE },
5378 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(203)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(203)), transform_worldex }, WINED3D_GL_EXT_NONE },
5379 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(204)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(204)), transform_worldex }, WINED3D_GL_EXT_NONE },
5380 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(205)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(205)), transform_worldex }, WINED3D_GL_EXT_NONE },
5381 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(206)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(206)), transform_worldex }, WINED3D_GL_EXT_NONE },
5382 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(207)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(207)), transform_worldex }, WINED3D_GL_EXT_NONE },
5383 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(208)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(208)), transform_worldex }, WINED3D_GL_EXT_NONE },
5384 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(209)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(209)), transform_worldex }, WINED3D_GL_EXT_NONE },
5385 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(210)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(210)), transform_worldex }, WINED3D_GL_EXT_NONE },
5386 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(211)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(211)), transform_worldex }, WINED3D_GL_EXT_NONE },
5387 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(212)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(212)), transform_worldex }, WINED3D_GL_EXT_NONE },
5388 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(213)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(213)), transform_worldex }, WINED3D_GL_EXT_NONE },
5389 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(214)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(214)), transform_worldex }, WINED3D_GL_EXT_NONE },
5390 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(215)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(215)), transform_worldex }, WINED3D_GL_EXT_NONE },
5391 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(216)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(216)), transform_worldex }, WINED3D_GL_EXT_NONE },
5392 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(217)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(217)), transform_worldex }, WINED3D_GL_EXT_NONE },
5393 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(218)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(218)), transform_worldex }, WINED3D_GL_EXT_NONE },
5394 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(219)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(219)), transform_worldex }, WINED3D_GL_EXT_NONE },
5395 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(220)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(220)), transform_worldex }, WINED3D_GL_EXT_NONE },
5396 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(221)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(221)), transform_worldex }, WINED3D_GL_EXT_NONE },
5397 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(222)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(222)), transform_worldex }, WINED3D_GL_EXT_NONE },
5398 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(223)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(223)), transform_worldex }, WINED3D_GL_EXT_NONE },
5399 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(224)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(224)), transform_worldex }, WINED3D_GL_EXT_NONE },
5400 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(225)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(225)), transform_worldex }, WINED3D_GL_EXT_NONE },
5401 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(226)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(226)), transform_worldex }, WINED3D_GL_EXT_NONE },
5402 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(227)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(227)), transform_worldex }, WINED3D_GL_EXT_NONE },
5403 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(228)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(228)), transform_worldex }, WINED3D_GL_EXT_NONE },
5404 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(229)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(229)), transform_worldex }, WINED3D_GL_EXT_NONE },
5405 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(230)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(230)), transform_worldex }, WINED3D_GL_EXT_NONE },
5406 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(231)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(231)), transform_worldex }, WINED3D_GL_EXT_NONE },
5407 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(232)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(232)), transform_worldex }, WINED3D_GL_EXT_NONE },
5408 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(233)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(233)), transform_worldex }, WINED3D_GL_EXT_NONE },
5409 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(234)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(234)), transform_worldex }, WINED3D_GL_EXT_NONE },
5410 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(235)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(235)), transform_worldex }, WINED3D_GL_EXT_NONE },
5411 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(236)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(236)), transform_worldex }, WINED3D_GL_EXT_NONE },
5412 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(237)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(237)), transform_worldex }, WINED3D_GL_EXT_NONE },
5413 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(238)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(238)), transform_worldex }, WINED3D_GL_EXT_NONE },
5414 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(239)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(239)), transform_worldex }, WINED3D_GL_EXT_NONE },
5415 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(240)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(240)), transform_worldex }, WINED3D_GL_EXT_NONE },
5416 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(241)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(241)), transform_worldex }, WINED3D_GL_EXT_NONE },
5417 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(242)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(242)), transform_worldex }, WINED3D_GL_EXT_NONE },
5418 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(243)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(243)), transform_worldex }, WINED3D_GL_EXT_NONE },
5419 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(244)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(244)), transform_worldex }, WINED3D_GL_EXT_NONE },
5420 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(245)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(245)), transform_worldex }, WINED3D_GL_EXT_NONE },
5421 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(246)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(246)), transform_worldex }, WINED3D_GL_EXT_NONE },
5422 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(247)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(247)), transform_worldex }, WINED3D_GL_EXT_NONE },
5423 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(248)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(248)), transform_worldex }, WINED3D_GL_EXT_NONE },
5424 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(249)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(249)), transform_worldex }, WINED3D_GL_EXT_NONE },
5425 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(250)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(250)), transform_worldex }, WINED3D_GL_EXT_NONE },
5426 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(251)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(251)), transform_worldex }, WINED3D_GL_EXT_NONE },
5427 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(252)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(252)), transform_worldex }, WINED3D_GL_EXT_NONE },
5428 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(253)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(253)), transform_worldex }, WINED3D_GL_EXT_NONE },
5429 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(254)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(254)), transform_worldex }, WINED3D_GL_EXT_NONE },
5430 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255)), transform_worldex }, WINED3D_GL_EXT_NONE },
5431 { STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5432 { STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5433 { STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5434 { STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5435 { STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5436 { STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5437 { STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5438 { STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5439 { STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5440 { STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5441 { STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5442 { STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5443 { STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5444 { STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5445 { STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5446 { STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5447 /* Fog */
5448 { STATE_RENDER(WINED3D_RS_FOGENABLE), { STATE_RENDER(WINED3D_RS_FOGENABLE), state_fog_vertexpart}, WINED3D_GL_EXT_NONE },
5449 { STATE_RENDER(WINED3D_RS_FOGTABLEMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5450 { STATE_RENDER(WINED3D_RS_FOGVERTEXMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5451 { STATE_RENDER(WINED3D_RS_RANGEFOGENABLE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5452 { STATE_RENDER(WINED3D_RS_CLIPPING), { STATE_RENDER(WINED3D_RS_CLIPPING), state_clipping }, WINED3D_GL_EXT_NONE },
5453 { STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE), { STATE_RENDER(WINED3D_RS_CLIPPING), NULL }, WINED3D_GL_EXT_NONE },
5454 { STATE_RENDER(WINED3D_RS_LIGHTING), { STATE_RENDER(WINED3D_RS_LIGHTING), state_lighting }, WINED3D_GL_EXT_NONE },
5455 { STATE_RENDER(WINED3D_RS_AMBIENT), { STATE_RENDER(WINED3D_RS_AMBIENT), state_ambient }, WINED3D_GL_EXT_NONE },
5456 { STATE_RENDER(WINED3D_RS_COLORVERTEX), { STATE_RENDER(WINED3D_RS_COLORVERTEX), state_colormat }, WINED3D_GL_EXT_NONE },
5457 { STATE_RENDER(WINED3D_RS_LOCALVIEWER), { STATE_RENDER(WINED3D_RS_LOCALVIEWER), state_localviewer }, WINED3D_GL_EXT_NONE },
5458 { STATE_RENDER(WINED3D_RS_NORMALIZENORMALS), { STATE_RENDER(WINED3D_RS_NORMALIZENORMALS), state_normalize }, WINED3D_GL_EXT_NONE },
5459 { STATE_RENDER(WINED3D_RS_DIFFUSEMATERIALSOURCE), { STATE_RENDER(WINED3D_RS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
5460 { STATE_RENDER(WINED3D_RS_SPECULARMATERIALSOURCE), { STATE_RENDER(WINED3D_RS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
5461 { STATE_RENDER(WINED3D_RS_AMBIENTMATERIALSOURCE), { STATE_RENDER(WINED3D_RS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
5462 { STATE_RENDER(WINED3D_RS_EMISSIVEMATERIALSOURCE), { STATE_RENDER(WINED3D_RS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
5463 { STATE_RENDER(WINED3D_RS_VERTEXBLEND), { STATE_RENDER(WINED3D_RS_VERTEXBLEND), state_vertexblend }, ARB_VERTEX_BLEND },
5464 { STATE_RENDER(WINED3D_RS_VERTEXBLEND), { STATE_RENDER(WINED3D_RS_VERTEXBLEND), state_vertexblend_w }, WINED3D_GL_EXT_NONE },
5465 { STATE_RENDER(WINED3D_RS_POINTSIZE), { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5466 { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), state_psizemin_arb }, ARB_POINT_PARAMETERS },
5467 { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), state_psizemin_ext }, EXT_POINT_PARAMETERS },
5468 { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), state_psizemin_w }, WINED3D_GL_EXT_NONE },
5469 { STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), { STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), state_pointsprite }, ARB_POINT_SPRITE },
5470 { STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), { STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), state_pointsprite_w }, WINED3D_GL_EXT_NONE },
5471 { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), state_pscale }, WINED3D_GL_EXT_NONE },
5472 { STATE_RENDER(WINED3D_RS_POINTSCALE_A), { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5473 { STATE_RENDER(WINED3D_RS_POINTSCALE_B), { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5474 { STATE_RENDER(WINED3D_RS_POINTSCALE_C), { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5475 { STATE_RENDER(WINED3D_RS_POINTSIZE_MAX), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), NULL }, ARB_POINT_PARAMETERS },
5476 { STATE_RENDER(WINED3D_RS_POINTSIZE_MAX), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), NULL }, EXT_POINT_PARAMETERS },
5477 { STATE_RENDER(WINED3D_RS_POINTSIZE_MAX), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), NULL }, WINED3D_GL_EXT_NONE },
5478 { STATE_RENDER(WINED3D_RS_TWEENFACTOR), { STATE_RENDER(WINED3D_RS_VERTEXBLEND), NULL }, WINED3D_GL_EXT_NONE },
5479 { STATE_RENDER(WINED3D_RS_INDEXEDVERTEXBLENDENABLE), { STATE_RENDER(WINED3D_RS_VERTEXBLEND), NULL }, WINED3D_GL_EXT_NONE },
5481 /* Samplers for NP2 texture matrix adjustions. They are not needed if GL_ARB_texture_non_power_of_two is supported,
5482 * so register a NULL state handler in that case to get the vertex part of sampler() skipped(VTF is handled in the misc states.
5483 * otherwise, register sampler_texmatrix, which takes care of updating the texture matrix
5485 { STATE_SAMPLER(0), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5486 { STATE_SAMPLER(0), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5487 { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5488 { STATE_SAMPLER(1), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5489 { STATE_SAMPLER(1), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5490 { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5491 { STATE_SAMPLER(2), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5492 { STATE_SAMPLER(2), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5493 { STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5494 { STATE_SAMPLER(3), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5495 { STATE_SAMPLER(3), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5496 { STATE_SAMPLER(3), { STATE_SAMPLER(3), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5497 { STATE_SAMPLER(4), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5498 { STATE_SAMPLER(4), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5499 { STATE_SAMPLER(4), { STATE_SAMPLER(4), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5500 { STATE_SAMPLER(5), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5501 { STATE_SAMPLER(5), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5502 { STATE_SAMPLER(5), { STATE_SAMPLER(5), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5503 { STATE_SAMPLER(6), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5504 { STATE_SAMPLER(6), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5505 { STATE_SAMPLER(6), { STATE_SAMPLER(6), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5506 { STATE_SAMPLER(7), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5507 { STATE_SAMPLER(7), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5508 { STATE_SAMPLER(7), { STATE_SAMPLER(7), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5509 { STATE_POINT_SIZE_ENABLE, { STATE_POINT_SIZE_ENABLE, state_nop }, WINED3D_GL_EXT_NONE },
5510 {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE },
5513 static const struct StateEntryTemplate ffp_fragmentstate_template[] = {
5514 { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5515 { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5516 { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5517 { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5518 { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5519 { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5520 { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5521 { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5522 { STATE_TEXTURESTAGE(0, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5523 { STATE_TEXTURESTAGE(0, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5524 { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5525 { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5526 { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5527 { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5528 { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5529 { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5530 { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5531 { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5532 { STATE_TEXTURESTAGE(1, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5533 { STATE_TEXTURESTAGE(1, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5534 { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5535 { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5536 { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5537 { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5538 { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5539 { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5540 { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5541 { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5542 { STATE_TEXTURESTAGE(2, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5543 { STATE_TEXTURESTAGE(2, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5544 { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5545 { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5546 { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5547 { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5548 { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5549 { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5550 { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5551 { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5552 { STATE_TEXTURESTAGE(3, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5553 { STATE_TEXTURESTAGE(3, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5554 { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5555 { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5556 { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5557 { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5558 { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5559 { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5560 { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5561 { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5562 { STATE_TEXTURESTAGE(4, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5563 { STATE_TEXTURESTAGE(4, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5564 { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5565 { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5566 { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5567 { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5568 { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5569 { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5570 { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5571 { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5572 { STATE_TEXTURESTAGE(5, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5573 { STATE_TEXTURESTAGE(5, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5574 { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5575 { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5576 { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5577 { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5578 { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5579 { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5580 { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5581 { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5582 { STATE_TEXTURESTAGE(6, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5583 { STATE_TEXTURESTAGE(6, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5584 { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5585 { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5586 { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5587 { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5588 { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5589 { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5590 { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5591 { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5592 { STATE_TEXTURESTAGE(7, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5593 { STATE_TEXTURESTAGE(7, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5594 { STATE_PIXELSHADER, { STATE_PIXELSHADER, apply_pixelshader }, WINED3D_GL_EXT_NONE },
5595 { STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
5596 { STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), { STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), state_texfactor }, WINED3D_GL_EXT_NONE },
5597 { STATE_RENDER(WINED3D_RS_FOGCOLOR), { STATE_RENDER(WINED3D_RS_FOGCOLOR), state_fogcolor }, WINED3D_GL_EXT_NONE },
5598 { STATE_RENDER(WINED3D_RS_FOGDENSITY), { STATE_RENDER(WINED3D_RS_FOGDENSITY), state_fogdensity }, WINED3D_GL_EXT_NONE },
5599 { STATE_RENDER(WINED3D_RS_FOGENABLE), { STATE_RENDER(WINED3D_RS_FOGENABLE), state_fog_fragpart }, WINED3D_GL_EXT_NONE },
5600 { STATE_RENDER(WINED3D_RS_FOGTABLEMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5601 { STATE_RENDER(WINED3D_RS_FOGVERTEXMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5602 { STATE_RENDER(WINED3D_RS_FOGSTART), { STATE_RENDER(WINED3D_RS_FOGSTART), state_fogstartend }, WINED3D_GL_EXT_NONE },
5603 { STATE_RENDER(WINED3D_RS_FOGEND), { STATE_RENDER(WINED3D_RS_FOGSTART), NULL }, WINED3D_GL_EXT_NONE },
5604 { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler_texdim }, WINED3D_GL_EXT_NONE },
5605 { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler_texdim }, WINED3D_GL_EXT_NONE },
5606 { STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler_texdim }, WINED3D_GL_EXT_NONE },
5607 { STATE_SAMPLER(3), { STATE_SAMPLER(3), sampler_texdim }, WINED3D_GL_EXT_NONE },
5608 { STATE_SAMPLER(4), { STATE_SAMPLER(4), sampler_texdim }, WINED3D_GL_EXT_NONE },
5609 { STATE_SAMPLER(5), { STATE_SAMPLER(5), sampler_texdim }, WINED3D_GL_EXT_NONE },
5610 { STATE_SAMPLER(6), { STATE_SAMPLER(6), sampler_texdim }, WINED3D_GL_EXT_NONE },
5611 { STATE_SAMPLER(7), { STATE_SAMPLER(7), sampler_texdim }, WINED3D_GL_EXT_NONE },
5612 {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE },
5615 /* Context activation is done by the caller. */
5616 static void ffp_enable(const struct wined3d_gl_info *gl_info, BOOL enable) {}
5618 static void *ffp_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv)
5620 return shader_priv;
5623 static void ffp_free(struct wined3d_device *device) {}
5625 static void vp_ffp_get_caps(const struct wined3d_gl_info *gl_info, struct wined3d_vertex_caps *caps)
5627 caps->xyzrhw = FALSE;
5628 caps->max_active_lights = gl_info->limits.lights;
5629 caps->max_vertex_blend_matrices = gl_info->limits.blends;
5630 caps->max_vertex_blend_matrix_index = 0;
5631 caps->vertex_processing_caps = WINED3DVTXPCAPS_DIRECTIONALLIGHTS
5632 | WINED3DVTXPCAPS_MATERIALSOURCE7
5633 | WINED3DVTXPCAPS_POSITIONALLIGHTS
5634 | WINED3DVTXPCAPS_LOCALVIEWER
5635 | WINED3DVTXPCAPS_VERTEXFOG
5636 | WINED3DVTXPCAPS_TEXGEN
5637 | WINED3DVTXPCAPS_TEXGEN_SPHEREMAP;
5638 caps->fvf_caps = WINED3DFVFCAPS_PSIZE | 0x0008; /* 8 texture coords */
5639 caps->max_user_clip_planes = gl_info->limits.clipplanes;
5640 caps->raster_caps = 0;
5641 if (gl_info->supported[NV_FOG_DISTANCE])
5642 caps->raster_caps |= WINED3DPRASTERCAPS_FOGRANGE;
5645 const struct wined3d_vertex_pipe_ops ffp_vertex_pipe =
5647 ffp_enable,
5648 vp_ffp_get_caps,
5649 ffp_alloc,
5650 ffp_free,
5651 vp_ffp_states,
5654 static void ffp_fragment_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps)
5656 caps->wined3d_caps = 0;
5657 caps->PrimitiveMiscCaps = 0;
5658 caps->TextureOpCaps = WINED3DTEXOPCAPS_ADD
5659 | WINED3DTEXOPCAPS_ADDSIGNED
5660 | WINED3DTEXOPCAPS_ADDSIGNED2X
5661 | WINED3DTEXOPCAPS_MODULATE
5662 | WINED3DTEXOPCAPS_MODULATE2X
5663 | WINED3DTEXOPCAPS_MODULATE4X
5664 | WINED3DTEXOPCAPS_SELECTARG1
5665 | WINED3DTEXOPCAPS_SELECTARG2
5666 | WINED3DTEXOPCAPS_DISABLE;
5668 if (gl_info->supported[ARB_TEXTURE_ENV_COMBINE]
5669 || gl_info->supported[EXT_TEXTURE_ENV_COMBINE]
5670 || gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
5672 caps->TextureOpCaps |= WINED3DTEXOPCAPS_BLENDDIFFUSEALPHA
5673 | WINED3DTEXOPCAPS_BLENDTEXTUREALPHA
5674 | WINED3DTEXOPCAPS_BLENDFACTORALPHA
5675 | WINED3DTEXOPCAPS_BLENDCURRENTALPHA
5676 | WINED3DTEXOPCAPS_LERP
5677 | WINED3DTEXOPCAPS_SUBTRACT;
5679 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3]
5680 || gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
5682 caps->TextureOpCaps |= WINED3DTEXOPCAPS_ADDSMOOTH
5683 | WINED3DTEXOPCAPS_MULTIPLYADD
5684 | WINED3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR
5685 | WINED3DTEXOPCAPS_MODULATECOLOR_ADDALPHA
5686 | WINED3DTEXOPCAPS_BLENDTEXTUREALPHAPM;
5688 if (gl_info->supported[ARB_TEXTURE_ENV_DOT3])
5689 caps->TextureOpCaps |= WINED3DTEXOPCAPS_DOTPRODUCT3;
5691 caps->MaxTextureBlendStages = gl_info->limits.textures;
5692 caps->MaxSimultaneousTextures = gl_info->limits.textures;
5695 static BOOL ffp_color_fixup_supported(struct color_fixup_desc fixup)
5697 if (TRACE_ON(d3d))
5699 TRACE("Checking support for fixup:\n");
5700 dump_color_fixup_desc(fixup);
5703 /* We only support identity conversions. */
5704 if (is_identity_fixup(fixup))
5706 TRACE("[OK]\n");
5707 return TRUE;
5710 TRACE("[FAILED]\n");
5711 return FALSE;
5714 const struct fragment_pipeline ffp_fragment_pipeline = {
5715 ffp_enable,
5716 ffp_fragment_get_caps,
5717 ffp_alloc,
5718 ffp_free,
5719 ffp_color_fixup_supported,
5720 ffp_fragmentstate_template,
5723 static void none_enable(const struct wined3d_gl_info *gl_info, BOOL enable) {}
5725 static void *none_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv)
5727 return shader_priv;
5730 static void none_free(struct wined3d_device *device) {}
5732 static void vp_none_get_caps(const struct wined3d_gl_info *gl_info, struct wined3d_vertex_caps *caps)
5734 memset(caps, 0, sizeof(*caps));
5737 const struct wined3d_vertex_pipe_ops none_vertex_pipe =
5739 none_enable,
5740 vp_none_get_caps,
5741 none_alloc,
5742 none_free,
5743 NULL,
5746 static void fp_none_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps)
5748 memset(caps, 0, sizeof(*caps));
5751 static BOOL fp_none_color_fixup_supported(struct color_fixup_desc fixup)
5753 return is_identity_fixup(fixup);
5756 const struct fragment_pipeline none_fragment_pipe =
5758 none_enable,
5759 fp_none_get_caps,
5760 none_alloc,
5761 none_free,
5762 fp_none_color_fixup_supported,
5763 NULL,
5766 static unsigned int num_handlers(const APPLYSTATEFUNC *funcs)
5768 unsigned int i;
5769 for(i = 0; funcs[i]; i++);
5770 return i;
5773 static void multistate_apply_2(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
5775 context->swapchain->device->multistate_funcs[state_id][0](context, state, state_id);
5776 context->swapchain->device->multistate_funcs[state_id][1](context, state, state_id);
5779 static void multistate_apply_3(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
5781 context->swapchain->device->multistate_funcs[state_id][0](context, state, state_id);
5782 context->swapchain->device->multistate_funcs[state_id][1](context, state, state_id);
5783 context->swapchain->device->multistate_funcs[state_id][2](context, state, state_id);
5786 static void prune_invalid_states(struct StateEntry *state_table, const struct wined3d_gl_info *gl_info,
5787 const struct wined3d_d3d_info *d3d_info)
5789 unsigned int start, last, i;
5791 start = STATE_TEXTURESTAGE(d3d_info->limits.ffp_blend_stages, 0);
5792 last = STATE_TEXTURESTAGE(MAX_TEXTURES - 1, WINED3D_HIGHEST_TEXTURE_STATE);
5793 for (i = start; i <= last; ++i)
5795 state_table[i].representative = 0;
5796 state_table[i].apply = state_undefined;
5799 start = STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + d3d_info->limits.ffp_blend_stages);
5800 last = STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + MAX_TEXTURES - 1);
5801 for (i = start; i <= last; ++i)
5803 state_table[i].representative = 0;
5804 state_table[i].apply = state_undefined;
5807 start = STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(gl_info->limits.blends));
5808 last = STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255));
5809 for (i = start; i <= last; ++i)
5811 state_table[i].representative = 0;
5812 state_table[i].apply = state_undefined;
5816 static void validate_state_table(struct StateEntry *state_table)
5818 static const struct
5820 DWORD first;
5821 DWORD last;
5823 rs_holes[] =
5825 { 1, 1},
5826 { 3, 3},
5827 { 17, 18},
5828 { 21, 21},
5829 { 42, 45},
5830 { 47, 47},
5831 { 61, 127},
5832 {149, 150},
5833 {169, 169},
5834 {177, 177},
5835 {196, 197},
5836 { 0, 0},
5838 static const DWORD simple_states[] =
5840 STATE_MATERIAL,
5841 STATE_VDECL,
5842 STATE_STREAMSRC,
5843 STATE_INDEXBUFFER,
5844 STATE_VSHADER,
5845 STATE_GEOMETRY_SHADER,
5846 STATE_PIXELSHADER,
5847 STATE_VIEWPORT,
5848 STATE_LIGHT_TYPE,
5849 STATE_SCISSORRECT,
5850 STATE_FRONTFACE,
5851 STATE_POINTSPRITECOORDORIGIN,
5852 STATE_BASEVERTEXINDEX,
5853 STATE_FRAMEBUFFER,
5854 STATE_POINT_SIZE_ENABLE,
5856 unsigned int i, current;
5858 for (i = STATE_RENDER(1), current = 0; i <= STATE_RENDER(WINEHIGHEST_RENDER_STATE); ++i)
5860 if (!rs_holes[current].first || i < STATE_RENDER(rs_holes[current].first))
5862 if (!state_table[i].representative)
5863 ERR("State %s (%#x) should have a representative.\n", debug_d3dstate(i), i);
5865 else if (state_table[i].representative)
5866 ERR("State %s (%#x) shouldn't have a representative.\n", debug_d3dstate(i), i);
5868 if (i == STATE_RENDER(rs_holes[current].last)) ++current;
5871 for (i = 0; i < sizeof(simple_states) / sizeof(*simple_states); ++i)
5873 if (!state_table[simple_states[i]].representative)
5874 ERR("State %s (%#x) should have a representative.\n",
5875 debug_d3dstate(simple_states[i]), simple_states[i]);
5878 for (i = 0; i < STATE_HIGHEST + 1; ++i)
5880 DWORD rep = state_table[i].representative;
5881 if (rep)
5883 if (state_table[rep].representative != rep)
5885 ERR("State %s (%#x) has invalid representative %s (%#x).\n",
5886 debug_d3dstate(i), i, debug_d3dstate(rep), rep);
5887 state_table[i].representative = 0;
5890 if (rep != i)
5892 if (state_table[i].apply)
5893 ERR("State %s (%#x) has both a handler and representative.\n", debug_d3dstate(i), i);
5895 else if (!state_table[i].apply)
5897 ERR("Self representing state %s (%#x) has no handler.\n", debug_d3dstate(i), i);
5903 HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_multistate_funcs,
5904 const struct wined3d_gl_info *gl_info, const struct wined3d_d3d_info *d3d_info,
5905 const struct wined3d_vertex_pipe_ops *vertex, const struct fragment_pipeline *fragment,
5906 const struct StateEntryTemplate *misc)
5908 unsigned int i, type, handlers;
5909 APPLYSTATEFUNC multistate_funcs[STATE_HIGHEST + 1][3];
5910 const struct StateEntryTemplate *cur;
5911 BOOL set[STATE_HIGHEST + 1];
5913 memset(multistate_funcs, 0, sizeof(multistate_funcs));
5915 for(i = 0; i < STATE_HIGHEST + 1; i++) {
5916 StateTable[i].representative = 0;
5917 StateTable[i].apply = state_undefined;
5920 for(type = 0; type < 3; type++) {
5921 /* This switch decides the order in which the states are applied */
5922 switch(type) {
5923 case 0: cur = misc; break;
5924 case 1: cur = fragment->states; break;
5925 case 2: cur = vertex->vp_states; break;
5926 default: cur = NULL; /* Stupid compiler */
5928 if(!cur) continue;
5930 /* GL extension filtering should not prevent multiple handlers being applied from different
5931 * pipeline parts
5933 memset(set, 0, sizeof(set));
5935 for(i = 0; cur[i].state; i++) {
5936 APPLYSTATEFUNC *funcs_array;
5938 /* Only use the first matching state with the available extension from one template.
5939 * e.g.
5940 * {D3DRS_FOOBAR, {D3DRS_FOOBAR, func1}, XYZ_FANCY},
5941 * {D3DRS_FOOBAR, {D3DRS_FOOBAR, func2}, 0 }
5943 * if GL_XYZ_fancy is supported, ignore the 2nd line
5945 if(set[cur[i].state]) continue;
5946 /* Skip state lines depending on unsupported extensions */
5947 if (!gl_info->supported[cur[i].extension]) continue;
5948 set[cur[i].state] = TRUE;
5949 /* In some cases having an extension means that nothing has to be
5950 * done for a state, e.g. if GL_ARB_texture_non_power_of_two is
5951 * supported, the texture coordinate fixup can be ignored. If the
5952 * apply function is used, mark the state set(done above) to prevent
5953 * applying later lines, but do not record anything in the state
5954 * table
5956 if (!cur[i].content.representative) continue;
5958 handlers = num_handlers(multistate_funcs[cur[i].state]);
5959 multistate_funcs[cur[i].state][handlers] = cur[i].content.apply;
5960 switch(handlers) {
5961 case 0:
5962 StateTable[cur[i].state].apply = cur[i].content.apply;
5963 break;
5964 case 1:
5965 StateTable[cur[i].state].apply = multistate_apply_2;
5966 dev_multistate_funcs[cur[i].state] = HeapAlloc(GetProcessHeap(),
5968 sizeof(**dev_multistate_funcs) * 2);
5969 if (!dev_multistate_funcs[cur[i].state]) {
5970 goto out_of_mem;
5973 dev_multistate_funcs[cur[i].state][0] = multistate_funcs[cur[i].state][0];
5974 dev_multistate_funcs[cur[i].state][1] = multistate_funcs[cur[i].state][1];
5975 break;
5976 case 2:
5977 StateTable[cur[i].state].apply = multistate_apply_3;
5978 funcs_array = HeapReAlloc(GetProcessHeap(),
5980 dev_multistate_funcs[cur[i].state],
5981 sizeof(**dev_multistate_funcs) * 3);
5982 if (!funcs_array) {
5983 goto out_of_mem;
5986 dev_multistate_funcs[cur[i].state] = funcs_array;
5987 dev_multistate_funcs[cur[i].state][2] = multistate_funcs[cur[i].state][2];
5988 break;
5989 default:
5990 ERR("Unexpected amount of state handlers for state %u: %u\n",
5991 cur[i].state, handlers + 1);
5994 if (StateTable[cur[i].state].representative
5995 && StateTable[cur[i].state].representative != cur[i].content.representative)
5997 FIXME("State %s (%#x) has different representatives in different pipeline parts.\n",
5998 debug_d3dstate(cur[i].state), cur[i].state);
6000 StateTable[cur[i].state].representative = cur[i].content.representative;
6004 prune_invalid_states(StateTable, gl_info, d3d_info);
6005 validate_state_table(StateTable);
6007 return WINED3D_OK;
6009 out_of_mem:
6010 for (i = 0; i <= STATE_HIGHEST; ++i) {
6011 HeapFree(GetProcessHeap(), 0, dev_multistate_funcs[i]);
6014 memset(dev_multistate_funcs, 0, (STATE_HIGHEST + 1)*sizeof(*dev_multistate_funcs));
6016 return E_OUTOFMEMORY;